From a299b167de1c86d8d06399fb2395b7569659be20 Mon Sep 17 00:00:00 2001 From: Torrie Fischer Date: Sat, 28 May 2022 19:28:03 +0200 Subject: [PATCH] Fix sidebars, implement vault api, coin pickups, and player respawning --- TODO.md | 8 +- pom.xml | 6 + .../java/gg/malloc/defense/GameEconomy.java | 198 ++++++++++++++++++ .../gg/malloc/defense/GameEventHandler.java | 27 +++ src/main/java/gg/malloc/defense/Plugin.java | 12 ++ .../defense/commands/LeaveGameCommand.java | 1 + .../gg/malloc/defense/engine/GameRunner.java | 63 +++++- .../gg/malloc/defense/engine/GameState.java | 46 ++++ .../malloc/defense/engine/PlayerManager.java | 49 ++++- .../gg/malloc/defense/model/Progress.java | 3 + .../java/gg/malloc/defense/model/State.java | 6 + .../java/gg/malloc/defense/ui/BossBars.java | 22 ++ .../java/gg/malloc/defense/ui/Sidebar.java | 23 +- .../java/gg/malloc/defense/ui/Sidebars.java | 2 +- src/main/resources/plugin.yml | 2 +- 15 files changed, 446 insertions(+), 22 deletions(-) create mode 100644 src/main/java/gg/malloc/defense/GameEconomy.java diff --git a/TODO.md b/TODO.md index c800b56..f1b89c3 100644 --- a/TODO.md +++ b/TODO.md @@ -21,7 +21,7 @@ [X] Never hungry [X] Mobs don't drop bomb items [ ] Execute commands on game/wave end -[ ] Player Respawning +[X] Player Respawning # QOL @@ -33,7 +33,7 @@ [ ] Leave game when leaving game world [ ] Bomb and target glow different colors [ ] Play sound once bomb is close to / at target -[ ] Expose coins under vault API +[X] Expose coins under vault API [ ] Animations framework # Malloc beta map @@ -60,7 +60,7 @@ [ ] Post-Round summary in chat [X] Clickable join links in /list [X] Sidebar -[ ] Coin pickup messages in action bar +[X] Coin pickup status in sidebar [ ] Target catches on fire more it is lit [ ] Colored titles [ ] Clickable /leave action @@ -123,7 +123,7 @@ [X] Restore health+hunger on respawn/game start [ ] /restart games [ ] Instancing -[ ] Respawn during games +[X] Respawn during games [ ] Player revival items [X] Clear inventory on join/leave diff --git a/pom.xml b/pom.xml index 6372dd8..633f0ba 100644 --- a/pom.xml +++ b/pom.xml @@ -43,6 +43,12 @@ 2.9.2 provided + + com.github.MilkBowl + VaultAPI + 1.7 + provided + diff --git a/src/main/java/gg/malloc/defense/GameEconomy.java b/src/main/java/gg/malloc/defense/GameEconomy.java new file mode 100644 index 0000000..5e5cf16 --- /dev/null +++ b/src/main/java/gg/malloc/defense/GameEconomy.java @@ -0,0 +1,198 @@ +package gg.malloc.defense; + +import net.milkbowl.vault.economy.AbstractEconomy; +import net.milkbowl.vault.economy.Economy; +import net.milkbowl.vault.economy.EconomyResponse; +import net.milkbowl.vault.economy.EconomyResponse.ResponseType; + +import org.bukkit.plugin.ServicesManager; +import org.bukkit.plugin.ServicePriority; +import org.bukkit.entity.Player; +import org.bukkit.OfflinePlayer; + +import gg.malloc.defense.engine.GameRunner; + +import java.util.List; +import java.util.ArrayList; + +public class GameEconomy extends AbstractEconomy { + + Plugin m_plugin; + + public GameEconomy(Plugin plugin) { + m_plugin = plugin; + } + + public void register() { + ServicesManager manager = m_plugin.getServer().getServicesManager(); + manager.register(Economy.class, this, m_plugin, ServicePriority.Highest); + } + + @Override + public EconomyResponse withdrawPlayer(String playerName, double amount) { + GameRunner runner = m_plugin.getRunnerForPlayer(playerName); + if (runner != null) { + Player p = m_plugin.getServer().getPlayer(playerName); + if (!has(playerName, amount)) { + int newBalance = runner.getState().getPlayerBalance(p); + return new EconomyResponse(amount, newBalance, ResponseType.FAILURE, "Not enough money!"); + } else { + runner.spendMoney(p, (int)Math.floor(amount)); + int newBalance = runner.getState().getPlayerBalance(p); + return new EconomyResponse(amount, newBalance, ResponseType.SUCCESS, ""); + } + } else { + return new EconomyResponse(0, 0, ResponseType.FAILURE, "Not in a game!"); + } + } + + @Override + public EconomyResponse depositPlayer(String playerName, double amount) { + GameRunner runner = m_plugin.getRunnerForPlayer(playerName); + if (runner != null) { + Player p = m_plugin.getServer().getPlayer(playerName); + runner.spendMoney(p, -(int)Math.floor(amount)); + int newBalance = runner.getState().getPlayerBalance(p); + return new EconomyResponse(amount, newBalance, ResponseType.SUCCESS, ""); + } else { + return new EconomyResponse(0, 0, ResponseType.FAILURE, "Not in a game!"); + } + } + + @Override + public double getBalance(String playerName) { + GameRunner runner = m_plugin.getRunnerForPlayer(playerName); + if (runner != null) { + Player p = m_plugin.getServer().getPlayer(playerName); + return runner.getState().getPlayerBalance(p); + } else { + return 0.0; + } + } + + @Override + public double getBalance(String playerName, String worldName) { + return getBalance(playerName); + } + @Override + public boolean isEnabled() { + return true; + } + + @Override + public String getName() { + return "Malloc Defense"; + } + + @Override + public boolean hasBankSupport() { + return false; + } + + @Override + public int fractionalDigits() { + return 0; + } + + @Override + public String format(double amount) { + return amount + " grist"; + } + + @Override + public String currencyNamePlural() { + return "Grist"; + } + + @Override + public String currencyNameSingular() { + return "Grist"; + } + + @Override + public boolean hasAccount(String playerName) { + return true; + } + + @Override + public boolean hasAccount(String playerName, String worldName) { + return hasAccount(playerName); + } + + @Override + public boolean has(String playerName, double amount) { + return getBalance(playerName) >= amount; + } + + @Override + public boolean has(String playerName, String worldName, double amount) { + return has(playerName, amount); + } + + @Override + public EconomyResponse withdrawPlayer(String playerName, String worldName, double amount) { + return withdrawPlayer(playerName, amount); + } + + @Override + public EconomyResponse depositPlayer(String playerName, String worldName, double amount) { + return depositPlayer(playerName, amount); + } + + private static final EconomyResponse NO_IMPL_RESPONSE = new EconomyResponse(0, 0, ResponseType.NOT_IMPLEMENTED, "Not implemented."); + + @Override + public EconomyResponse createBank(String name, String player) { + return NO_IMPL_RESPONSE; + } + + @Override + public EconomyResponse deleteBank(String name) { + return NO_IMPL_RESPONSE; + } + + @Override + public EconomyResponse bankBalance(String name) { + return NO_IMPL_RESPONSE; + } + + @Override + public EconomyResponse bankHas(String name, double amount) { + return NO_IMPL_RESPONSE; + } + + @Override + public EconomyResponse bankWithdraw(String name, double amount) { + return NO_IMPL_RESPONSE; + } + + @Override + public EconomyResponse bankDeposit(String name, double amount) { + return NO_IMPL_RESPONSE; + } + + @Override + public EconomyResponse isBankOwner(String name, String player) { + return NO_IMPL_RESPONSE; + } + + @Override + public EconomyResponse isBankMember(String name, String player) { + return NO_IMPL_RESPONSE; + } + + @Override + public boolean createPlayerAccount(String name) { + return true; + } + + @Override + public boolean createPlayerAccount(String name, String worldName) { + return true; + } + + @Override + public List getBanks() { + return new ArrayList(); + } +} diff --git a/src/main/java/gg/malloc/defense/GameEventHandler.java b/src/main/java/gg/malloc/defense/GameEventHandler.java index 0d1baec..ef621dd 100644 --- a/src/main/java/gg/malloc/defense/GameEventHandler.java +++ b/src/main/java/gg/malloc/defense/GameEventHandler.java @@ -14,10 +14,16 @@ import org.bukkit.event.entity.EntityCombustEvent; import org.bukkit.event.entity.EntityTargetEvent; import org.bukkit.event.entity.FoodLevelChangeEvent; import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; import org.bukkit.event.world.LootGenerateEvent; +import org.bukkit.Sound; +import org.bukkit.SoundCategory; import org.bukkit.inventory.ItemStack; import org.bukkit.entity.Player; +import de.tr7zw.nbtapi.NBTItem; +import de.tr7zw.nbtapi.NBTCompound; + public class GameEventHandler implements Listener { Collection m_runners; @@ -78,4 +84,25 @@ public class GameEventHandler implements Listener { public void onFoodLevelChange(FoodLevelChangeEvent evt) { evt.setCancelled(true); } + + @EventHandler + public void onItemPickup(PlayerPickupItemEvent evt) { + NBTItem nbt = new NBTItem(evt.getItem().getItemStack()); + if (nbt.hasKey("malloc")) { + NBTCompound mallocData = nbt.getCompound("malloc"); + if (mallocData.hasKey("coinValue")) { + evt.setCancelled(true); + Player player = evt.getPlayer(); + int coinValue = mallocData.getInteger("coinValue") * evt.getItem().getItemStack().getAmount(); + player.getWorld().playSound(evt.getPlayer(), Sound.BLOCK_CHAIN_PLACE, SoundCategory.PLAYERS, (float)1.0, (float)1.0); + evt.getItem().remove(); + for(GameRunner runner : m_runners) { + if (runner.getPlayers().contains(player)) { + runner.depositCoins(coinValue); + return; + } + } + } + } + } } diff --git a/src/main/java/gg/malloc/defense/Plugin.java b/src/main/java/gg/malloc/defense/Plugin.java index 6277363..ec9d446 100644 --- a/src/main/java/gg/malloc/defense/Plugin.java +++ b/src/main/java/gg/malloc/defense/Plugin.java @@ -48,6 +48,7 @@ public class Plugin extends JavaPlugin { HashMap m_runningGames = new HashMap<>(); HashMap m_playerGames = new HashMap<>(); GameEventHandler m_handler = new GameEventHandler(); + GameEconomy m_economy = new GameEconomy(this); public Collection arenaNames() { return m_arenas.keySet(); @@ -75,6 +76,9 @@ public class Plugin extends JavaPlugin { getServer().getPluginManager().registerEvents(new PlayerQuitHandler(), this); getServer().getPluginManager().registerEvents(m_handler, this); + + getLogger().info("Registering economy"); + m_economy.register(); } public void onDisable() { @@ -159,6 +163,14 @@ public class Plugin extends JavaPlugin { p.teleport(lobby.getSpawnLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); } + public GameRunner getRunnerForPlayer(String playerName) { + return getRunnerForPlayer(getServer().getPlayer(playerName)); + } + + public void removePlayerFromGames(Player player) { + m_playerGames.get(player).removePlayer(player); + } + public GameRunner getRunnerForPlayer(Player p) { GameRunner ret = null; if (m_playerGames.containsKey(p)) { diff --git a/src/main/java/gg/malloc/defense/commands/LeaveGameCommand.java b/src/main/java/gg/malloc/defense/commands/LeaveGameCommand.java index 9ba2b12..413411a 100644 --- a/src/main/java/gg/malloc/defense/commands/LeaveGameCommand.java +++ b/src/main/java/gg/malloc/defense/commands/LeaveGameCommand.java @@ -26,6 +26,7 @@ public class LeaveGameCommand implements CommandExecutor { return true; } runner.removePlayer(player); + m_plugin.removePlayerFromGames(player); m_plugin.returnPlayerToLobby(player); } else { sender.sendMessage("Only players may use this command."); diff --git a/src/main/java/gg/malloc/defense/engine/GameRunner.java b/src/main/java/gg/malloc/defense/engine/GameRunner.java index 1b2956e..dfe39e8 100644 --- a/src/main/java/gg/malloc/defense/engine/GameRunner.java +++ b/src/main/java/gg/malloc/defense/engine/GameRunner.java @@ -66,6 +66,7 @@ public class GameRunner { TickTask m_lobbyReturnTask; TickTask m_bombSmokeTask; TickTask m_bombCrackleTask; + TickTask m_playerRespawnTask; BossBars m_bars; Sidebars m_sidebars; @@ -94,6 +95,10 @@ public class GameRunner { validateGameRule(GameRule.SPECTATORS_GENERATE_CHUNKS, false); } + public GameState getState() { + return m_state; + } + public GameRunner(Plugin plugin, Game game, Arena arena, World world) { m_plugin = plugin; m_game = game; @@ -120,6 +125,19 @@ public class GameRunner { } }, 80); + m_playerRespawnTask = new TickTask(m_plugin, () -> { + m_players.tickRespawnCounters(); + for (Player p : m_players.getPlayers()) { + if (m_players.readyToRespawn(p)) { + if (m_players.requestTransition(p, PlayerManager.State.Playing)) { + sendRespawnTitle(p); + p.teleport(m_world.getSpawnLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN); + } + } + } + m_bars.update(); + }, 20); + m_countdownTask = new TickTask(m_plugin, () -> { if (m_warmupCountdown == 0) { requestTransition(Stage.Playing); @@ -176,6 +194,16 @@ public class GameRunner { m_mobs.handleEntityRetarget(evt); } + public void spendMoney(Player p, int amount) { + m_players.addPlayerExpenses(p, amount); + m_sidebars.update(); + } + + public void depositCoins(int amount) { + m_state.addPickedUpCoins(amount); + m_sidebars.update(); + } + public void handleEntityDamage(EntityDamageEvent evt) { m_mobs.handleEntityDamage(evt); if (m_mobs.bombWasHit() && !m_bombFuse.isExploded()) { @@ -229,6 +257,8 @@ public class GameRunner { m_fuseTask.stop(); m_countdownTask.stop(); m_lobbyReturnTask.stop(); + m_playerRespawnTask.stop(); + m_state.resetBalances(); return true; } @@ -253,6 +283,7 @@ public class GameRunner { .create(); broadcastMessage(message); m_mobs.clear(); + m_playerRespawnTask.start(); return true; } @@ -288,6 +319,7 @@ public class GameRunner { m_warmupCountdown = 10; m_bars.setCountdownProgress(1.0); m_countdownTask.start(); + m_playerRespawnTask.start(); return true; } @@ -302,6 +334,7 @@ public class GameRunner { } m_countdownTask.stop(); m_fuseTask.start(); + m_playerRespawnTask.start(); spawnNextBatch(); return true; } @@ -311,7 +344,7 @@ public class GameRunner { m_lobbyReturnTask.start(); m_countdownTask.stop(); m_fuseTask.stop(); - //m_mobs.clear(); + m_playerRespawnTask.stop(); return true; } @@ -330,7 +363,8 @@ public class GameRunner { private void handlePlayerDeath(Player player) { if (m_players.requestTransition(player, PlayerManager.State.Dead)) { m_world.strikeLightningEffect(player.getLocation()); - if (!m_players.isAnyoneAlive()) { + //if (!m_players.isAnyoneAlive()) { + if (false) { BaseComponent[] message = new ComponentBuilder() .append("Everyone is ").color(ChatColor.LIGHT_PURPLE) .append("DEAD").color(ChatColor.RED).bold(true) @@ -339,6 +373,14 @@ public class GameRunner { broadcastMessage(message); requestTransition(Stage.GameOver); } else { + BaseComponent[] message = new ComponentBuilder() + .append(player.getName()) + .append(" has ").color(ChatColor.LIGHT_PURPLE) + .append("DIED!").color(ChatColor.RED).bold(true) + .append(" :(").color(ChatColor.LIGHT_PURPLE) + .create(); + broadcastMessage(message); + sendDeathTitle(player); m_log.info("Remaining players " + m_players.remainingPlayers()); } } @@ -347,12 +389,15 @@ public class GameRunner { public void handleEntityDeath(Entity entity) { boolean wasCarrier = m_mobs.isBombCarrier(entity); if (m_mobs.killMob(entity)) { + int COIN_STACK_SIZE = 5; int coinsToDrop = 60; while(coinsToDrop > 0) { - int droppedCoins = Math.min(coinsToDrop, 5); + int droppedCoins = Math.min(coinsToDrop, COIN_STACK_SIZE); ItemStack coins = Items.makeCoins(); coins.setAmount(droppedCoins); - coinsToDrop -= 64; + coinsToDrop -= droppedCoins; + m_state.addDroppedCoins(droppedCoins); + m_sidebars.update(); m_world.dropItem(entity.getLocation(), coins); } m_bars.update(); @@ -433,6 +478,14 @@ public class GameRunner { return false; } + void sendDeathTitle(Player p) { + p.sendTitle(ChatColor.RED.toString() + "You died!", "Wait to respawn..."); + } + + void sendRespawnTitle(Player p) { + p.sendTitle(ChatColor.AQUA.toString() + "Respawn", ""); + } + void sendStageTitle(Player p) { switch(m_stage) { case Warmup: @@ -451,6 +504,7 @@ public class GameRunner { return; } p.getInventory().clear(); + m_sidebars.addPlayer(p); m_players.addPlayer(p); m_bars.addPlayer(p); if (m_stage == Stage.Idle || m_stage == Stage.Warmup) { @@ -471,6 +525,7 @@ public class GameRunner { public void removePlayer(Player p) { p.getInventory().clear(); + m_sidebars.removePlayer(p); m_bars.removePlayer(p); m_players.removePlayer(p); if (m_players.isEmpty()) { diff --git a/src/main/java/gg/malloc/defense/engine/GameState.java b/src/main/java/gg/malloc/defense/engine/GameState.java index 44d2108..1d2759d 100644 --- a/src/main/java/gg/malloc/defense/engine/GameState.java +++ b/src/main/java/gg/malloc/defense/engine/GameState.java @@ -4,6 +4,8 @@ import gg.malloc.defense.model.Game; import gg.malloc.defense.model.Progress; import gg.malloc.defense.model.State; +import org.bukkit.entity.Player; + public class GameState implements State { GameRunner m_runner; WaveManager m_waves; @@ -12,6 +14,9 @@ public class GameState implements State { BombFuse m_fuse; PlayerManager m_players; + int m_coinsDropped; + int m_coinsPickedUp; + public GameState(GameRunner runner, WaveManager waves, Game game, MobManager mobs, BombFuse fuse, PlayerManager players) { m_runner = runner; m_waves = waves; @@ -19,6 +24,47 @@ public class GameState implements State { m_mobs = mobs; m_fuse = fuse; m_players = players; + m_coinsDropped = 0; + m_coinsPickedUp = 0; + } + + public int getRemainingCoins() { + return coinsDropped() - coinsPickedUp(); + } + + public int coinsDropped() { + return m_coinsDropped; + } + + public int coinsPickedUp() { + return m_coinsPickedUp; + } + + int INITIAL_BALANCE = 1500; + + public int getPlayerBalance(Player p) { + return coinsPickedUp() - m_players.getPlayerExpenses(p) + INITIAL_BALANCE; + } + + public void addDroppedCoins(int v) { + m_coinsDropped += v; + } + + public void addPickedUpCoins(int v) { + m_coinsPickedUp += v; + } + + public void resetBalances() { + m_coinsDropped = 0; + m_coinsPickedUp = 0; + } + + public Progress playerRespawnProgress(Player p) { + return m_players.getRespawnProgress(p); + } + + public Progress coinProgress() { + return new StaticProgress(m_coinsPickedUp, m_coinsDropped); } public GameRunner.Stage getStage() { diff --git a/src/main/java/gg/malloc/defense/engine/PlayerManager.java b/src/main/java/gg/malloc/defense/engine/PlayerManager.java index f58404c..90f6d9e 100644 --- a/src/main/java/gg/malloc/defense/engine/PlayerManager.java +++ b/src/main/java/gg/malloc/defense/engine/PlayerManager.java @@ -16,6 +16,8 @@ import java.util.Collection; public class PlayerManager { HashMap m_playerStates = new HashMap<>(); HashMap m_playerReadyStates = new HashMap<>(); + HashMap m_playerExpenses = new HashMap<>(); + HashMap m_respawnCounters = new HashMap<>(); public enum State { Idle, @@ -68,22 +70,22 @@ public class PlayerManager { // Respawn player public boolean enterPlaying(Player player) { - //m_log.fine("Respawning player " + player); player.setGameMode(Bukkit.getDefaultGameMode()); healPlayer(player); return true; } public boolean enterDead(Player player) { - //m_log.info("Player has died in game" + player); player.setGameMode(GameMode.SPECTATOR); + m_respawnCounters.put(player, 15); return true; } public void addPlayer(Player player) { - //m_log.info("Adding player " + player); m_playerStates.put(player, State.Idle); m_playerReadyStates.put(player, false); + m_playerExpenses.put(player, 0); + m_respawnCounters.put(player, 0); } public boolean isReady(Player player) { @@ -111,14 +113,53 @@ public class PlayerManager { } } return true; + + } + + public Progress getRespawnProgress(Player player) { + return new StaticProgress(m_respawnCounters.get(player), 15); + } + + public int getRespawnCounter(Player player) { + if (m_respawnCounters.containsKey(player)) { + return m_respawnCounters.get(player); + } else { + return 0; + } + } + + public void tickRespawnCounters() { + for(Player p : m_respawnCounters.keySet()) { + if (m_respawnCounters.get(p) > 0) { + m_respawnCounters.put(p, m_respawnCounters.get(p) - 1); + } + } + } + + public boolean readyToRespawn(Player player) { + return m_respawnCounters.get(player) == 0 && m_playerStates.get(player) == State.Dead; + } + + public void addPlayerExpenses(Player player, int amount) { + if (m_playerExpenses.containsKey(player)) { + m_playerExpenses.put(player, m_playerExpenses.get(player) + amount); + } + } + + public int getPlayerExpenses(Player player) { + if (m_playerExpenses.containsKey(player)) { + return m_playerExpenses.get(player); + } + return 0; } public boolean removePlayer(Player player) { - //m_log.info("Removing player " + player); healPlayer(player); requestTransition(player, State.Idle); m_playerStates.remove(player); m_playerReadyStates.remove(player); + m_playerExpenses.remove(player); + m_respawnCounters.remove(player); return true; } diff --git a/src/main/java/gg/malloc/defense/model/Progress.java b/src/main/java/gg/malloc/defense/model/Progress.java index 1879621..311dc90 100644 --- a/src/main/java/gg/malloc/defense/model/Progress.java +++ b/src/main/java/gg/malloc/defense/model/Progress.java @@ -4,6 +4,9 @@ public interface Progress { int value(); int maximum(); + default int remaining() { + return maximum() - value(); + } default double toDouble() { return Math.min(maximum(), Math.max(0.0, value())) / maximum(); } diff --git a/src/main/java/gg/malloc/defense/model/State.java b/src/main/java/gg/malloc/defense/model/State.java index 648196a..5540969 100644 --- a/src/main/java/gg/malloc/defense/model/State.java +++ b/src/main/java/gg/malloc/defense/model/State.java @@ -2,6 +2,8 @@ package gg.malloc.defense.model; import gg.malloc.defense.engine.GameRunner; +import org.bukkit.entity.Player; + public interface State { GameRunner.Stage getStage(); @@ -9,4 +11,8 @@ public interface State { Progress waveProgress(); Progress mobProgress(); Progress playerReadyProgress(); + Progress coinProgress(); + + Progress playerRespawnProgress(Player p); + int getPlayerBalance(Player p); } diff --git a/src/main/java/gg/malloc/defense/ui/BossBars.java b/src/main/java/gg/malloc/defense/ui/BossBars.java index cacba7e..ceffa59 100644 --- a/src/main/java/gg/malloc/defense/ui/BossBars.java +++ b/src/main/java/gg/malloc/defense/ui/BossBars.java @@ -2,6 +2,9 @@ package gg.malloc.defense.ui; import gg.malloc.defense.model.Game; import gg.malloc.defense.model.State; +import gg.malloc.defense.model.Progress; + +import java.util.HashMap; import org.bukkit.boss.BossBar; import org.bukkit.boss.BarStyle; @@ -13,6 +16,7 @@ public class BossBars { BossBar m_gameBar = Bukkit.createBossBar("Malloc Defense", BarColor.PURPLE, BarStyle.SOLID); BossBar m_waveBar = Bukkit.createBossBar("Malloc Defense", BarColor.PURPLE, BarStyle.SOLID); BossBar m_bombBar = Bukkit.createBossBar("Bomb Fuse", BarColor.RED, BarStyle.SOLID); + HashMap m_respawnBars = new HashMap<>(); State m_gameState; @@ -33,12 +37,20 @@ public class BossBars { m_gameBar.addPlayer(p); m_waveBar.addPlayer(p); m_bombBar.addPlayer(p); + BossBar respawnBar = Bukkit.createBossBar("Respawn", BarColor.BLUE, BarStyle.SOLID); + respawnBar.addPlayer(p); + respawnBar.setVisible(false); + m_respawnBars.put(p, respawnBar); } public void removePlayer(Player p) { m_gameBar.removePlayer(p); m_waveBar.removePlayer(p); m_bombBar.removePlayer(p); + if (m_respawnBars.containsKey(p)) { + m_respawnBars.get(p).removePlayer(p); + m_respawnBars.remove(p); + } } public void update() { @@ -100,5 +112,15 @@ public class BossBars { m_bombBar.setVisible(false); break; } + for (Player p : m_respawnBars.keySet()) { + Progress respawnProgress = m_gameState.playerRespawnProgress(p); + if (respawnProgress.value() > 0) { + m_respawnBars.get(p).setVisible(true); + m_respawnBars.get(p).setProgress(respawnProgress.toDouble()); + m_respawnBars.get(p).setTitle("Respawning in " + respawnProgress.value()); + } else { + m_respawnBars.get(p).setVisible(false); + } + } } } diff --git a/src/main/java/gg/malloc/defense/ui/Sidebar.java b/src/main/java/gg/malloc/defense/ui/Sidebar.java index cae37a9..542b68f 100644 --- a/src/main/java/gg/malloc/defense/ui/Sidebar.java +++ b/src/main/java/gg/malloc/defense/ui/Sidebar.java @@ -12,6 +12,7 @@ import org.bukkit.scoreboard.DisplaySlot; import org.bukkit.scoreboard.Score; import org.bukkit.scoreboard.Team; import org.bukkit.scoreboard.Objective; +import org.bukkit.entity.Player; public class Sidebar { Scoreboard m_scoreboard; @@ -19,12 +20,14 @@ public class Sidebar { ArrayList m_rowKeys; HashMap m_rows; ArrayList m_teams; + Player m_player; int m_size; State m_state; - public Sidebar(State state, Scoreboard scoreboard) { + public Sidebar(State state, Scoreboard scoreboard, Player player) { m_state = state; + m_player = player; m_scoreboard = scoreboard; m_objective = m_scoreboard.registerNewObjective("text", "dummy", ChatColor.LIGHT_PURPLE + "" + ChatColor.BOLD + "Malloc Defense"); m_objective.setDisplaySlot(DisplaySlot.SIDEBAR); @@ -34,6 +37,7 @@ public class Sidebar { m_rowKeys.add(ChatColor.BLACK + "" + ChatColor.WHITE); m_rowKeys.add(ChatColor.GOLD+ "" + ChatColor.WHITE); m_rowKeys.add(ChatColor.WHITE+ "" + ChatColor.WHITE); + m_rowKeys.add(ChatColor.BLACK+ "" + ChatColor.BLACK); for(String key : m_rowKeys) { Team team = m_scoreboard.registerNewTeam(key); team.addEntry(key); @@ -50,20 +54,23 @@ public class Sidebar { case Warmup: m_rows.put(0, ChatColor.LIGHT_PURPLE + "Wave " + m_state.waveProgress().value() + " / " + m_state.waveProgress().maximum()); m_rows.put(1, ChatColor.AQUA + "Get ready!"); - m_rows.put(2, ChatColor.AQUA + "Balance: "); - m_size = 3; + m_rows.put(2, ChatColor.AQUA + "Balance: " + m_state.getPlayerBalance(m_player)); + m_rows.put(3, ChatColor.AQUA + "Coins remaining: " + m_state.coinProgress().remaining()); + m_size = 4; break; case Countdown: m_rows.put(0, ChatColor.LIGHT_PURPLE + "Wave " + m_state.waveProgress().value() + " / " + m_state.waveProgress().maximum()); m_rows.put(1, ChatColor.GOLD + "Wave incoming!"); - m_rows.put(2, ChatColor.AQUA + "Balance: "); - m_size = 3; + m_rows.put(2, ChatColor.AQUA + "Balance: " + m_state.getPlayerBalance(m_player)); + m_rows.put(3, ChatColor.AQUA + "Coins remaining: " + m_state.coinProgress().remaining()); + m_size = 4; break; case Playing: m_rows.put(0, ChatColor.LIGHT_PURPLE + "Wave " + m_state.waveProgress().value() + " / " + m_state.waveProgress().maximum()); - m_rows.put(1, ChatColor.GREEN + "Mobs remaining: " + (m_state.mobProgress().maximum() - m_state.mobProgress().value())); - m_rows.put(2, ChatColor.AQUA + "Balance: "); - m_size = 3; + m_rows.put(1, ChatColor.GREEN + "Mobs remaining: " + m_state.mobProgress().remaining()); + m_rows.put(2, ChatColor.AQUA + "Balance: " + m_state.getPlayerBalance(m_player)); + m_rows.put(3, ChatColor.AQUA + "Coins remaining: " + m_state.coinProgress().remaining()); + m_size = 4; break; case GameOver: m_rows.put(0, ChatColor.RED + "Game over!"); diff --git a/src/main/java/gg/malloc/defense/ui/Sidebars.java b/src/main/java/gg/malloc/defense/ui/Sidebars.java index 524bfca..b1006b9 100644 --- a/src/main/java/gg/malloc/defense/ui/Sidebars.java +++ b/src/main/java/gg/malloc/defense/ui/Sidebars.java @@ -18,7 +18,7 @@ public class Sidebars { } public void addPlayer(Player player) { - m_sidebars.put(player, new Sidebar(m_state, m_scoreboards.getNewScoreboard())); + m_sidebars.put(player, new Sidebar(m_state, m_scoreboards.getNewScoreboard(), player)); player.setScoreboard(m_sidebars.get(player).getScoreboard()); } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 2e34a08..ec36aa9 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -2,7 +2,7 @@ name: Malloc-Defense version: 1.0 api-version: 1.18 main: gg.malloc.defense.Plugin -depend: [] +depend: [Vault] commands: ready: description: Mark yourself as ready for the next wave