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