reorganize engine bits into engine package, same with commands, reimplement player state as FSM
This commit is contained in:
		
							
								
								
									
										350
									
								
								src/main/java/gg/malloc/defense/engine/GameRunner.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										350
									
								
								src/main/java/gg/malloc/defense/engine/GameRunner.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,350 @@
 | 
			
		||||
package gg.malloc.defense.engine;
 | 
			
		||||
 | 
			
		||||
import gg.malloc.defense.model.Game;
 | 
			
		||||
import gg.malloc.defense.model.Arena;
 | 
			
		||||
import gg.malloc.defense.model.Spawner;
 | 
			
		||||
import gg.malloc.defense.model.Wave;
 | 
			
		||||
 | 
			
		||||
import gg.malloc.defense.Plugin;
 | 
			
		||||
 | 
			
		||||
import java.util.logging.Logger;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.World;
 | 
			
		||||
import org.bukkit.boss.BarColor;
 | 
			
		||||
import org.bukkit.boss.BarStyle;
 | 
			
		||||
import org.bukkit.boss.BossBar;
 | 
			
		||||
import org.bukkit.event.player.PlayerTeleportEvent;
 | 
			
		||||
import org.bukkit.event.entity.EntityDamageEvent;
 | 
			
		||||
import org.bukkit.entity.Entity;
 | 
			
		||||
import org.bukkit.entity.LivingEntity;
 | 
			
		||||
import org.bukkit.entity.EntityType;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.scheduler.BukkitTask;
 | 
			
		||||
 | 
			
		||||
public class GameRunner {
 | 
			
		||||
  Arena m_arena;
 | 
			
		||||
  Game m_game;
 | 
			
		||||
  Stage m_stage;
 | 
			
		||||
  Plugin m_plugin;
 | 
			
		||||
 | 
			
		||||
  BossBar m_gameBar = Bukkit.createBossBar("Malloc Defense", BarColor.PURPLE, BarStyle.SOLID);
 | 
			
		||||
  BossBar m_waveBar = Bukkit.createBossBar("Malloc Defense", BarColor.PURPLE, BarStyle.SOLID);
 | 
			
		||||
  BukkitTask m_countdownTask;
 | 
			
		||||
 | 
			
		||||
  MobManager m_mobs;
 | 
			
		||||
  WaveManager m_waves;
 | 
			
		||||
  PlayerManager m_players;
 | 
			
		||||
 | 
			
		||||
  Logger m_log;
 | 
			
		||||
 | 
			
		||||
  public enum Stage {
 | 
			
		||||
    Idle,
 | 
			
		||||
    Warmup,
 | 
			
		||||
    Playing,
 | 
			
		||||
    GameOver
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  class WaveManager {
 | 
			
		||||
    int m_currentWaveNum = 0;
 | 
			
		||||
    int m_currentBatch = 0;
 | 
			
		||||
    Wave m_currentWave = null;
 | 
			
		||||
    Game m_game;
 | 
			
		||||
 | 
			
		||||
    WaveManager(Game game) {
 | 
			
		||||
      m_game = game;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void reset() {
 | 
			
		||||
      m_currentWaveNum = 0;
 | 
			
		||||
      m_currentBatch = 0;
 | 
			
		||||
      m_currentWave = null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Wave currentWave() {
 | 
			
		||||
      return m_currentWave;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int currentWaveNum() {
 | 
			
		||||
      return m_currentWaveNum;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int currentBatchNum() {
 | 
			
		||||
      return m_currentBatch;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    double progress() {
 | 
			
		||||
      return (double)m_currentWaveNum / (double)m_game.getWaveCount();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    boolean isLastWave() {
 | 
			
		||||
      return m_currentWaveNum >= m_game.getWaveCount();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    boolean isLastBatch() {
 | 
			
		||||
      return m_currentBatch >= m_currentWave.batchCount();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void nextBatch() {
 | 
			
		||||
      m_currentBatch += 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void next() {
 | 
			
		||||
      m_currentWaveNum += 1;
 | 
			
		||||
      m_currentBatch = 0;
 | 
			
		||||
      m_currentWave = m_game.getWave(m_currentWaveNum);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  public GameRunner(Plugin plugin, Game game, Arena arena) {
 | 
			
		||||
    m_plugin = plugin;
 | 
			
		||||
    m_game = game;
 | 
			
		||||
    m_arena = arena;
 | 
			
		||||
    m_stage = Stage.Idle;
 | 
			
		||||
    m_gameBar.setVisible(true);
 | 
			
		||||
    m_waveBar.setVisible(false);
 | 
			
		||||
    m_mobs = new MobManager(m_game);
 | 
			
		||||
    m_waves = new WaveManager(m_game);
 | 
			
		||||
    m_players = new PlayerManager();
 | 
			
		||||
    m_log = m_plugin.getLogger();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  int m_warmupCountdown = 0;
 | 
			
		||||
 | 
			
		||||
  public void handleEntityDamage(EntityDamageEvent evt) {
 | 
			
		||||
    m_mobs.handleEntityDamage(evt);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private void countdownTick() {
 | 
			
		||||
    if (m_warmupCountdown == 0) {
 | 
			
		||||
      requestTransition(Stage.Playing);
 | 
			
		||||
    } else {
 | 
			
		||||
      updateMobBars();
 | 
			
		||||
      broadcastMessage("Starting game in " + m_warmupCountdown);
 | 
			
		||||
      m_warmupCountdown--;
 | 
			
		||||
      m_countdownTask = m_plugin.getServer().getScheduler().runTaskLater(m_plugin, () -> {
 | 
			
		||||
        countdownTick();
 | 
			
		||||
      }, 20);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private boolean enterIdle() {
 | 
			
		||||
    m_waves.reset();
 | 
			
		||||
    m_mobs.clear();
 | 
			
		||||
    m_players.requestTransitionForAll(PlayerManager.State.Idle);
 | 
			
		||||
    if (m_countdownTask != null) {
 | 
			
		||||
      m_countdownTask.cancel();
 | 
			
		||||
      m_countdownTask = null;
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private boolean enterWarmup() {
 | 
			
		||||
    m_waves.next();
 | 
			
		||||
    m_warmupCountdown = 10;
 | 
			
		||||
    for(Player p : m_players.getPlayers()) {
 | 
			
		||||
        if (m_players.requestTransition(p, PlayerManager.State.Playing)) {
 | 
			
		||||
          p.teleport(m_arena.getWorld().getSpawnLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    broadcastTitle("Warmup", "Prepare yourself for wave " + m_waves.currentWaveNum());
 | 
			
		||||
    m_mobs.clear();
 | 
			
		||||
    countdownTick();
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private boolean enterPlaying() {
 | 
			
		||||
    m_log.info("Starting wave " + m_waves.currentWaveNum());
 | 
			
		||||
    spawnNextBatch();
 | 
			
		||||
    broadcastTitle("Wave " + m_waves.currentWaveNum());
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private boolean enterGameOver() {
 | 
			
		||||
    broadcastTitle("Game Over!");
 | 
			
		||||
    if (m_countdownTask != null) {
 | 
			
		||||
      m_countdownTask.cancel();
 | 
			
		||||
      m_countdownTask = null;
 | 
			
		||||
    }
 | 
			
		||||
    m_mobs.clear();
 | 
			
		||||
    for(Player p : m_players.getPlayers()) {
 | 
			
		||||
      removePlayer(p);
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private void updateMobBars() {
 | 
			
		||||
    m_gameBar.setVisible(true);
 | 
			
		||||
    switch(m_stage) {
 | 
			
		||||
      case Idle:
 | 
			
		||||
        m_gameBar.setProgress(1.0);
 | 
			
		||||
        m_gameBar.setTitle("Waiting for playres...");
 | 
			
		||||
        m_gameBar.setColor(BarColor.PURPLE);
 | 
			
		||||
        m_waveBar.setVisible(false);
 | 
			
		||||
        break;
 | 
			
		||||
      case Warmup:
 | 
			
		||||
        m_gameBar.setProgress(m_waves.progress());
 | 
			
		||||
        m_gameBar.setTitle("Wave " + m_waves.currentWaveNum() + " / " + m_game.getWaveCount());
 | 
			
		||||
        m_gameBar.setColor(BarColor.PURPLE);
 | 
			
		||||
        m_waveBar.setVisible(true);
 | 
			
		||||
        m_waveBar.setColor(BarColor.YELLOW);
 | 
			
		||||
        m_waveBar.setTitle("Warmup");
 | 
			
		||||
        m_waveBar.setProgress((double)m_warmupCountdown / (double)10);
 | 
			
		||||
        break;
 | 
			
		||||
      case Playing:
 | 
			
		||||
        m_gameBar.setProgress(m_waves.progress());
 | 
			
		||||
        m_gameBar.setTitle("Wave " + m_waves.currentWaveNum() + " / " + m_game.getWaveCount());
 | 
			
		||||
        m_gameBar.setColor(BarColor.PURPLE);
 | 
			
		||||
        if (m_mobs.createdMobs() > 0) {
 | 
			
		||||
          m_waveBar.setVisible(true);
 | 
			
		||||
          m_waveBar.setColor(BarColor.GREEN);
 | 
			
		||||
          m_waveBar.setTitle("Mobs remaining: " + m_mobs.remainingMobs());
 | 
			
		||||
          m_waveBar.setProgress(m_mobs.progress());
 | 
			
		||||
        } else {
 | 
			
		||||
          m_waveBar.setVisible(false);
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
      case GameOver:
 | 
			
		||||
        m_gameBar.setColor(BarColor.RED);
 | 
			
		||||
        m_gameBar.setProgress(1.0);
 | 
			
		||||
        m_gameBar.setTitle("Game Over!");
 | 
			
		||||
        m_waveBar.setVisible(false);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private void spawnNextBatch() {
 | 
			
		||||
    broadcastMessage("Spawning batch " + m_waves.currentBatchNum());
 | 
			
		||||
    Spawner spawner = new GameSpawner(m_arena, m_mobs);
 | 
			
		||||
    m_waves.currentWave().spawnBatch(spawner, m_waves.currentBatchNum());
 | 
			
		||||
    updateMobBars();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void handlePlayerDeath(Player player) {
 | 
			
		||||
    if (m_players.requestTransition(player, PlayerManager.State.Dead)) {
 | 
			
		||||
      m_arena.getWorld().strikeLightningEffect(player.getLocation());
 | 
			
		||||
      if (!m_players.isAnyoneAlive()) {
 | 
			
		||||
        broadcastMessage("Everyone is dead :(");
 | 
			
		||||
        requestTransition(Stage.GameOver);
 | 
			
		||||
      } else {
 | 
			
		||||
        m_log.info("Remaining players " + m_players.remainingPlayers());
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void handleEntityDeath(Entity entity) {
 | 
			
		||||
    if (m_mobs.killMob(entity)) {
 | 
			
		||||
      broadcastMessage("Killed game entity " + entity);
 | 
			
		||||
      updateMobBars();
 | 
			
		||||
      if (m_mobs.remainingMobs() <= 3) {
 | 
			
		||||
        m_log.info("Starting next batch!");
 | 
			
		||||
        if (m_waves.isLastBatch()) {
 | 
			
		||||
          if (m_waves.isLastWave()) {
 | 
			
		||||
            requestTransition(Stage.GameOver);
 | 
			
		||||
          } else if (m_mobs.empty()) {
 | 
			
		||||
            requestTransition(Stage.Warmup);
 | 
			
		||||
          }
 | 
			
		||||
        } else {
 | 
			
		||||
          m_waves.nextBatch();
 | 
			
		||||
          spawnNextBatch();
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        m_log.fine("Living mobs remaining: " + m_mobs.remainingMobs());
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private boolean attemptTransition(Stage stage) {
 | 
			
		||||
    if (m_stage == stage) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    m_log.info("Game state: " + stage);
 | 
			
		||||
    switch(stage) {
 | 
			
		||||
      case Idle:
 | 
			
		||||
        return enterIdle();
 | 
			
		||||
      case Warmup:
 | 
			
		||||
        return enterWarmup();
 | 
			
		||||
      case Playing:
 | 
			
		||||
        return enterPlaying();
 | 
			
		||||
      case GameOver:
 | 
			
		||||
        return enterGameOver();
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  private boolean validateTransition(Stage from, Stage to) {
 | 
			
		||||
    switch(from) {
 | 
			
		||||
      case Idle:
 | 
			
		||||
        return to == Stage.Warmup;
 | 
			
		||||
      case Warmup:
 | 
			
		||||
        return to == Stage.Playing || to == Stage.Idle || to == Stage.GameOver;
 | 
			
		||||
      case Playing:
 | 
			
		||||
        return to == Stage.Warmup || to == Stage.GameOver || to == Stage.Idle;
 | 
			
		||||
      case GameOver:
 | 
			
		||||
        return to == Stage.Idle;
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean requestTransition(Stage stage) {
 | 
			
		||||
    if (!validateTransition(m_stage, stage)) {
 | 
			
		||||
      m_log.warning("Attemped illegal transition: " + m_stage + " -> " + stage);
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    if (attemptTransition(stage)) {
 | 
			
		||||
      m_log.info("Game transition: " + m_stage + " -> " + stage);
 | 
			
		||||
      m_stage = stage;
 | 
			
		||||
      updateMobBars();
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
    m_log.severe("Failed to complete transition: " + m_stage + " -> " + stage);
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void addPlayer(Player p) {
 | 
			
		||||
    m_players.addPlayer(p);
 | 
			
		||||
    m_gameBar.addPlayer(p);
 | 
			
		||||
    m_waveBar.addPlayer(p);
 | 
			
		||||
    if (m_stage == Stage.Idle || m_stage == Stage.Warmup) {
 | 
			
		||||
      if (m_players.requestTransition(p, PlayerManager.State.Playing)) {
 | 
			
		||||
        p.teleport(m_arena.getWorld().getSpawnLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN);
 | 
			
		||||
      }
 | 
			
		||||
      broadcastMessage(p.getName() + " has joined the game");
 | 
			
		||||
      if (m_stage == Stage.Idle) {
 | 
			
		||||
        requestTransition(Stage.Warmup);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void removePlayer(Player p) {
 | 
			
		||||
    m_gameBar.removePlayer(p);
 | 
			
		||||
    m_waveBar.removePlayer(p);
 | 
			
		||||
    m_players.removePlayer(p);
 | 
			
		||||
    if (m_players.isEmpty()) {
 | 
			
		||||
      requestTransition(Stage.Idle);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void broadcastTitle(String title) {
 | 
			
		||||
    broadcastTitle(title, "");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void broadcastTitle(String title, String subtitle) {
 | 
			
		||||
    for(Player p : m_players.getPlayers()) {
 | 
			
		||||
      p.sendTitle(title, subtitle, 10, 70, 20);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void broadcastMessage(String string) {
 | 
			
		||||
    World world = m_arena.getWorld();
 | 
			
		||||
    for(Player p : world.getPlayers()) {
 | 
			
		||||
      p.sendMessage(string);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void registerSpawnedMob(Entity entity) {
 | 
			
		||||
    m_mobs.addEntity(entity);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										33
									
								
								src/main/java/gg/malloc/defense/engine/GameSpawner.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/main/java/gg/malloc/defense/engine/GameSpawner.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
package gg.malloc.defense.engine;
 | 
			
		||||
 | 
			
		||||
import gg.malloc.defense.model.Spawner;
 | 
			
		||||
import gg.malloc.defense.model.Spawnpoint;
 | 
			
		||||
import gg.malloc.defense.model.Arena;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.entity.Entity;
 | 
			
		||||
import org.bukkit.entity.LivingEntity;
 | 
			
		||||
import org.bukkit.entity.EntityType;
 | 
			
		||||
 | 
			
		||||
public class GameSpawner implements Spawner {
 | 
			
		||||
  Arena m_arena;
 | 
			
		||||
  MobManager m_manager;
 | 
			
		||||
  int m_spawnIdx = 0;
 | 
			
		||||
 | 
			
		||||
  public GameSpawner(Arena arena, MobManager manager) {
 | 
			
		||||
    m_arena = arena;
 | 
			
		||||
    m_manager = manager;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Override
 | 
			
		||||
  public Entity spawnMob(EntityType type) {
 | 
			
		||||
    Spawnpoint[] spawnpoints = m_arena.spawnpoints();
 | 
			
		||||
    m_spawnIdx %= spawnpoints.length;
 | 
			
		||||
    //m_log.fine("Spawning " + type + " at " + spawnpoints[m_spawnIdx]);
 | 
			
		||||
    Entity newMob = m_arena.getWorld().spawnEntity(spawnpoints[m_spawnIdx].getLocation(), type);
 | 
			
		||||
    LivingEntity livingMob = (LivingEntity)newMob;
 | 
			
		||||
    livingMob.setRemoveWhenFarAway(false);
 | 
			
		||||
    m_manager.addEntity(newMob);
 | 
			
		||||
    m_spawnIdx += 1;
 | 
			
		||||
    return newMob;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										7
									
								
								src/main/java/gg/malloc/defense/engine/GameStage.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/main/java/gg/malloc/defense/engine/GameStage.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
package gg.malloc.defense.engine;
 | 
			
		||||
 | 
			
		||||
public interface GameStage {
 | 
			
		||||
  String name();
 | 
			
		||||
  default void onEnter() {}
 | 
			
		||||
  default void onExit() {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										72
									
								
								src/main/java/gg/malloc/defense/engine/MobManager.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/main/java/gg/malloc/defense/engine/MobManager.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
			
		||||
package gg.malloc.defense.engine;
 | 
			
		||||
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.entity.Entity;
 | 
			
		||||
import org.bukkit.event.entity.EntityDamageEvent;
 | 
			
		||||
 | 
			
		||||
import gg.malloc.defense.model.Game;
 | 
			
		||||
 | 
			
		||||
public class MobManager {
 | 
			
		||||
  HashSet<Entity> m_livingMobs = new HashSet<>();
 | 
			
		||||
  int m_createdMobs = 0;
 | 
			
		||||
  int m_killedMobs = 0;
 | 
			
		||||
 | 
			
		||||
  Game m_game;
 | 
			
		||||
 | 
			
		||||
  MobManager(Game game) {
 | 
			
		||||
    m_game = game;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void handleEntityDamage(EntityDamageEvent evt) {
 | 
			
		||||
    Entity entity = evt.getEntity();
 | 
			
		||||
    //m_log.info("Damage " + entity);
 | 
			
		||||
    //m_log.info("Living Mobs " + m_livingMobs);
 | 
			
		||||
    if (m_livingMobs.contains(entity)) {
 | 
			
		||||
      m_game.onMobDamaged(entity);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean killMob(Entity entity) {
 | 
			
		||||
    if (m_livingMobs.contains(entity)) {
 | 
			
		||||
      m_killedMobs += 1;
 | 
			
		||||
      return m_livingMobs.remove(entity);
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void clear() {
 | 
			
		||||
    for(Entity e : m_livingMobs) {
 | 
			
		||||
      e.remove();
 | 
			
		||||
    }
 | 
			
		||||
    m_livingMobs.clear();
 | 
			
		||||
    m_createdMobs = 0;
 | 
			
		||||
    m_killedMobs = 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public int createdMobs() {
 | 
			
		||||
    return m_createdMobs;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public int killedMobs() {
 | 
			
		||||
    return m_killedMobs;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public int remainingMobs() {
 | 
			
		||||
    return m_createdMobs - m_killedMobs;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public double progress() {
 | 
			
		||||
    return (double)m_killedMobs / (double)m_createdMobs;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void addEntity(Entity entity) {
 | 
			
		||||
    //m_log.fine("Registered new mob " + entity); 
 | 
			
		||||
    m_livingMobs.add(entity);
 | 
			
		||||
    m_createdMobs += 1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean empty() {
 | 
			
		||||
    return m_livingMobs.size() == 0;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										113
									
								
								src/main/java/gg/malloc/defense/engine/PlayerManager.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								src/main/java/gg/malloc/defense/engine/PlayerManager.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,113 @@
 | 
			
		||||
package gg.malloc.defense.engine;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.GameMode;
 | 
			
		||||
import org.bukkit.attribute.Attribute;
 | 
			
		||||
import org.bukkit.event.player.PlayerTeleportEvent;
 | 
			
		||||
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
 | 
			
		||||
public class PlayerManager {
 | 
			
		||||
  HashMap<Player, State> m_playerStates = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
  public enum State {
 | 
			
		||||
    Idle,
 | 
			
		||||
    Playing,
 | 
			
		||||
    Dead
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean requestTransitionForAll(State toState) {
 | 
			
		||||
    boolean allSuccess = true;
 | 
			
		||||
    for (Player p : getPlayers()) {
 | 
			
		||||
      allSuccess = allSuccess && requestTransition(p, toState);
 | 
			
		||||
    }
 | 
			
		||||
    return allSuccess;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean requestTransition(Player player, State toState) {
 | 
			
		||||
    State currentState = m_playerStates.get(player);
 | 
			
		||||
    if (currentState == toState) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    boolean ret = false;
 | 
			
		||||
    switch(toState) {
 | 
			
		||||
      case Idle:
 | 
			
		||||
        ret = enterIdle(player);break;
 | 
			
		||||
      case Playing:
 | 
			
		||||
        ret = enterPlaying(player);break;
 | 
			
		||||
      case Dead:
 | 
			
		||||
        ret = enterDead(player);break;
 | 
			
		||||
    }
 | 
			
		||||
    if (ret) {
 | 
			
		||||
      m_playerStates.put(player, toState);
 | 
			
		||||
    }
 | 
			
		||||
    return ret;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean enterIdle(Player player) {
 | 
			
		||||
    // Reset player to non-game state, return control back to Minecraft
 | 
			
		||||
    player.setGameMode(Bukkit.getDefaultGameMode());
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Respawn player
 | 
			
		||||
  public boolean enterPlaying(Player player) {
 | 
			
		||||
    //m_log.fine("Respawning player " + player);
 | 
			
		||||
    player.setGameMode(Bukkit.getDefaultGameMode());
 | 
			
		||||
    player.setHealth(player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue());
 | 
			
		||||
    player.setFoodLevel(10);
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean enterDead(Player player) {
 | 
			
		||||
    //m_log.info("Player has died in game" + player);
 | 
			
		||||
    player.setGameMode(GameMode.SPECTATOR);
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public void addPlayer(Player player) {
 | 
			
		||||
    //m_log.info("Adding player " + player); 
 | 
			
		||||
    m_playerStates.put(player, State.Idle);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean removePlayer(Player player) {
 | 
			
		||||
    //m_log.info("Removing player " + player); 
 | 
			
		||||
    requestTransition(player, State.Idle);
 | 
			
		||||
    m_playerStates.remove(player);
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean isEmpty() {
 | 
			
		||||
    return m_playerStates.size() == 0;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean isAlive(Player player) {
 | 
			
		||||
    return m_playerStates.get(player) == State.Playing;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public boolean isAnyoneAlive() {
 | 
			
		||||
    for(Player p : m_playerStates.keySet()) {
 | 
			
		||||
      if (m_playerStates.get(p) == State.Playing) {
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public int remainingPlayers() {
 | 
			
		||||
    int aliveCount = 0;
 | 
			
		||||
    for(State s : m_playerStates.values()) {
 | 
			
		||||
      if (s == State.Playing) {
 | 
			
		||||
        aliveCount += 1;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return aliveCount;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Collection<Player> getPlayers() {
 | 
			
		||||
    return m_playerStates.keySet();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user