|
|
|
|
@@ -10,14 +10,18 @@ import gg.malloc.defense.Plugin;
|
|
|
|
|
import java.util.logging.Logger;
|
|
|
|
|
|
|
|
|
|
import org.bukkit.Bukkit;
|
|
|
|
|
import org.bukkit.Sound;
|
|
|
|
|
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.EntityTargetEvent;
|
|
|
|
|
import org.bukkit.event.entity.EntityDamageEvent;
|
|
|
|
|
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
|
|
|
|
import org.bukkit.entity.Entity;
|
|
|
|
|
import org.bukkit.entity.LivingEntity;
|
|
|
|
|
import org.bukkit.entity.ArmorStand;
|
|
|
|
|
import org.bukkit.entity.EntityType;
|
|
|
|
|
import org.bukkit.entity.Player;
|
|
|
|
|
import org.bukkit.scheduler.BukkitTask;
|
|
|
|
|
@@ -30,17 +34,23 @@ public class GameRunner {
|
|
|
|
|
|
|
|
|
|
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 HP", BarColor.RED, BarStyle.SOLID);
|
|
|
|
|
|
|
|
|
|
BukkitTask m_countdownTask;
|
|
|
|
|
|
|
|
|
|
MobManager m_mobs;
|
|
|
|
|
WaveManager m_waves;
|
|
|
|
|
PlayerManager m_players;
|
|
|
|
|
|
|
|
|
|
LivingEntity m_bombTarget = null;
|
|
|
|
|
int m_bombHP = 100;
|
|
|
|
|
|
|
|
|
|
Logger m_log;
|
|
|
|
|
|
|
|
|
|
public enum Stage {
|
|
|
|
|
Idle,
|
|
|
|
|
Warmup,
|
|
|
|
|
Countdown,
|
|
|
|
|
Playing,
|
|
|
|
|
GameOver
|
|
|
|
|
}
|
|
|
|
|
@@ -104,6 +114,7 @@ public class GameRunner {
|
|
|
|
|
m_stage = Stage.Idle;
|
|
|
|
|
m_gameBar.setVisible(true);
|
|
|
|
|
m_waveBar.setVisible(false);
|
|
|
|
|
m_bombBar.setVisible(false);
|
|
|
|
|
m_mobs = new MobManager(m_game);
|
|
|
|
|
m_waves = new WaveManager(m_game);
|
|
|
|
|
m_players = new PlayerManager();
|
|
|
|
|
@@ -112,8 +123,30 @@ public class GameRunner {
|
|
|
|
|
|
|
|
|
|
int m_warmupCountdown = 0;
|
|
|
|
|
|
|
|
|
|
public void handleEntityRetargeting(EntityTargetEvent evt) {
|
|
|
|
|
if (m_mobs.contains(evt.getEntity()) && evt.getReason() == EntityTargetEvent.TargetReason.FORGOT_TARGET) {
|
|
|
|
|
evt.setTarget(m_bombTarget);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void handleEntityDamage(EntityDamageEvent evt) {
|
|
|
|
|
m_mobs.handleEntityDamage(evt);
|
|
|
|
|
if (evt.getEntity() == m_bombTarget && evt instanceof EntityDamageByEntityEvent) {
|
|
|
|
|
EntityDamageByEntityEvent entityEvt = (EntityDamageByEntityEvent)evt;
|
|
|
|
|
if (m_mobs.contains(entityEvt.getDamager())) {
|
|
|
|
|
entityEvt.getDamager().setGlowing(true);
|
|
|
|
|
m_bombHP -= 1;
|
|
|
|
|
broadcastMessage("The bomb has been struck!");
|
|
|
|
|
m_arena.getWorld().playSound(m_bombTarget.getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 1.5f, 0.9f);
|
|
|
|
|
updateMobBars();
|
|
|
|
|
if (m_bombHP <= 0) {
|
|
|
|
|
m_arena.getWorld().strikeLightningEffect(m_bombTarget.getLocation());
|
|
|
|
|
requestTransition(Stage.GameOver);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
evt.setCancelled(true);
|
|
|
|
|
} else {
|
|
|
|
|
m_mobs.handleEntityDamage(evt);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void countdownTick() {
|
|
|
|
|
@@ -130,9 +163,14 @@ public class GameRunner {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean enterIdle() {
|
|
|
|
|
m_bombHP = 100;
|
|
|
|
|
m_waves.reset();
|
|
|
|
|
m_mobs.clear();
|
|
|
|
|
m_players.requestTransitionForAll(PlayerManager.State.Idle);
|
|
|
|
|
if (m_bombTarget != null) {
|
|
|
|
|
m_bombTarget.remove();
|
|
|
|
|
m_bombTarget = null;
|
|
|
|
|
}
|
|
|
|
|
if (m_countdownTask != null) {
|
|
|
|
|
m_countdownTask.cancel();
|
|
|
|
|
m_countdownTask = null;
|
|
|
|
|
@@ -142,25 +180,54 @@ public class GameRunner {
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
m_players.setReady(p, false);
|
|
|
|
|
}
|
|
|
|
|
broadcastTitle("Warmup", "Prepare yourself for wave " + m_waves.currentWaveNum());
|
|
|
|
|
m_mobs.clear();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void togglePlayerReady(Player p) {
|
|
|
|
|
setPlayerReady(p, !m_players.isReady(p));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setPlayerReady(Player p, boolean isReady) {
|
|
|
|
|
m_players.setReady(p, isReady);
|
|
|
|
|
if (m_players.isEveryoneReady()) {
|
|
|
|
|
requestTransition(Stage.Countdown);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean enterCountdown() {
|
|
|
|
|
m_warmupCountdown = 10;
|
|
|
|
|
countdownTick();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean enterPlaying() {
|
|
|
|
|
m_log.info("Starting wave " + m_waves.currentWaveNum());
|
|
|
|
|
if (m_bombTarget == null) {
|
|
|
|
|
m_bombTarget = (LivingEntity)m_arena.getWorld().spawnEntity(m_arena.bombTarget().getLocation(), EntityType.ARMOR_STAND);
|
|
|
|
|
}
|
|
|
|
|
ArmorStand bombStand = (ArmorStand)m_bombTarget;
|
|
|
|
|
bombStand.setCustomName("Bomb Target");
|
|
|
|
|
bombStand.setVisible(true);
|
|
|
|
|
bombStand.setCustomNameVisible(true);
|
|
|
|
|
bombStand.setGlowing(true);
|
|
|
|
|
for(Player p : m_players.getPlayers()) {
|
|
|
|
|
if (m_players.requestTransition(p, PlayerManager.State.Playing)) {
|
|
|
|
|
p.teleport(m_arena.getWorld().getSpawnLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
spawnNextBatch();
|
|
|
|
|
broadcastTitle("Wave " + m_waves.currentWaveNum());
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private boolean enterGameOver() {
|
|
|
|
|
broadcastTitle("Game Over!");
|
|
|
|
|
if (m_countdownTask != null) {
|
|
|
|
|
@@ -179,18 +246,30 @@ public class GameRunner {
|
|
|
|
|
switch(m_stage) {
|
|
|
|
|
case Idle:
|
|
|
|
|
m_gameBar.setProgress(1.0);
|
|
|
|
|
m_gameBar.setTitle("Waiting for playres...");
|
|
|
|
|
m_gameBar.setTitle("Waiting for players...");
|
|
|
|
|
m_gameBar.setColor(BarColor.PURPLE);
|
|
|
|
|
m_waveBar.setVisible(false);
|
|
|
|
|
m_bombBar.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.BLUE);
|
|
|
|
|
m_waveBar.setTitle("Warmup - Waiting for players to get ready...");
|
|
|
|
|
m_waveBar.setProgress(m_players.readyProgress());
|
|
|
|
|
m_bombBar.setVisible(false);
|
|
|
|
|
break;
|
|
|
|
|
case Countdown:
|
|
|
|
|
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.setTitle("Wave starting!");
|
|
|
|
|
m_waveBar.setProgress((double)m_warmupCountdown / (double)10);
|
|
|
|
|
m_bombBar.setVisible(false);
|
|
|
|
|
break;
|
|
|
|
|
case Playing:
|
|
|
|
|
m_gameBar.setProgress(m_waves.progress());
|
|
|
|
|
@@ -204,19 +283,22 @@ public class GameRunner {
|
|
|
|
|
} else {
|
|
|
|
|
m_waveBar.setVisible(false);
|
|
|
|
|
}
|
|
|
|
|
m_bombBar.setVisible(true);
|
|
|
|
|
m_bombBar.setProgress((double)m_bombHP / (double)100);
|
|
|
|
|
break;
|
|
|
|
|
case GameOver:
|
|
|
|
|
m_gameBar.setColor(BarColor.RED);
|
|
|
|
|
m_gameBar.setProgress(1.0);
|
|
|
|
|
m_gameBar.setTitle("Game Over!");
|
|
|
|
|
m_waveBar.setVisible(false);
|
|
|
|
|
m_bombBar.setVisible(false);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void spawnNextBatch() {
|
|
|
|
|
broadcastMessage("Spawning batch " + m_waves.currentBatchNum());
|
|
|
|
|
Spawner spawner = new GameSpawner(m_arena, m_mobs);
|
|
|
|
|
Spawner spawner = new GameSpawner(m_arena, m_mobs, m_players, m_bombTarget);
|
|
|
|
|
m_waves.currentWave().spawnBatch(spawner, m_waves.currentBatchNum());
|
|
|
|
|
updateMobBars();
|
|
|
|
|
}
|
|
|
|
|
@@ -265,6 +347,8 @@ public class GameRunner {
|
|
|
|
|
return enterIdle();
|
|
|
|
|
case Warmup:
|
|
|
|
|
return enterWarmup();
|
|
|
|
|
case Countdown:
|
|
|
|
|
return enterCountdown();
|
|
|
|
|
case Playing:
|
|
|
|
|
return enterPlaying();
|
|
|
|
|
case GameOver:
|
|
|
|
|
@@ -278,7 +362,9 @@ public class GameRunner {
|
|
|
|
|
case Idle:
|
|
|
|
|
return to == Stage.Warmup;
|
|
|
|
|
case Warmup:
|
|
|
|
|
return to == Stage.Playing || to == Stage.Idle || to == Stage.GameOver;
|
|
|
|
|
return to == Stage.Playing || to == Stage.Idle || to == Stage.Countdown ;
|
|
|
|
|
case Countdown:
|
|
|
|
|
return to == Stage.Playing || to == Stage.Idle || to == Stage.Warmup;
|
|
|
|
|
case Playing:
|
|
|
|
|
return to == Stage.Warmup || to == Stage.GameOver || to == Stage.Idle;
|
|
|
|
|
case GameOver:
|
|
|
|
|
@@ -306,6 +392,7 @@ public class GameRunner {
|
|
|
|
|
m_players.addPlayer(p);
|
|
|
|
|
m_gameBar.addPlayer(p);
|
|
|
|
|
m_waveBar.addPlayer(p);
|
|
|
|
|
m_bombBar.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);
|
|
|
|
|
@@ -346,5 +433,4 @@ public class GameRunner {
|
|
|
|
|
void registerSpawnedMob(Entity entity) {
|
|
|
|
|
m_mobs.addEntity(entity);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|