Implement /ready and basic objective mechanics
This commit is contained in:
parent
a078f74b4b
commit
2f63695ee9
86
TODO.md
86
TODO.md
@ -1,30 +1,78 @@
|
|||||||
# TODO
|
# Objective
|
||||||
|
|
||||||
|
[X] Mobs spawn in waves
|
||||||
|
[X] Mobs move towards goal
|
||||||
|
[ ] Mobs carry bomb to goal
|
||||||
|
[X] Mobs arm bomb
|
||||||
|
[X] Bomb explodes
|
||||||
|
|
||||||
|
# UX
|
||||||
|
|
||||||
|
[X] Wave boss bar
|
||||||
|
[X] Mob count boss bar
|
||||||
|
[X] Stage titles
|
||||||
|
[ ] EXPLOSIONS
|
||||||
|
[ ] Colored titles
|
||||||
|
[ ] Clickable /ready in chat
|
||||||
|
[ ] Sidebar
|
||||||
|
|
||||||
|
# Social
|
||||||
|
|
||||||
|
[ ] Automatic VC groups for games
|
||||||
|
[ ] DiscordSRV
|
||||||
|
[ ] Plan stats
|
||||||
|
[ ] /invite friends to games
|
||||||
|
[ ] /voterestart
|
||||||
|
|
||||||
|
# Mechanics
|
||||||
|
|
||||||
[ ] Coin drops
|
[ ] Coin drops
|
||||||
[ ] Basic setup commands
|
[ ] Mob tracking should prioritize bomb
|
||||||
[ ] Config file
|
[ ] Mobs recover dropped bombs
|
||||||
[ ] Spectator mode
|
[ ] Bomb carriers are slower
|
||||||
[ ] Commands/tools to start warmup countdown/mark 'ready'
|
[ ] Bonus coins for complete coin pickup
|
||||||
[ ] Upgrades
|
[ ] Infinite weapons + armor
|
||||||
[ ] Plan stats
|
[ ] Ammo/health spawns
|
||||||
[ ] Live map editing
|
|
||||||
[ ] Instancing
|
|
||||||
[ ] DiscordSRV
|
|
||||||
[ ] Voice Chat
|
|
||||||
[ ] Player readiness starts countdown
|
|
||||||
|
|
||||||
# Scripted waves
|
# Scripted waves
|
||||||
|
|
||||||
|
[X] Spawn in batches
|
||||||
|
[X] Randomized spawn locations
|
||||||
|
[X] Weighted distributions
|
||||||
|
[X] Batch overlap
|
||||||
|
[ ] Scripted batch overlap/timings
|
||||||
|
[ ] Scripted spawn locations
|
||||||
[ ] Bosses
|
[ ] Bosses
|
||||||
[ ] Batch overlap/timing
|
|
||||||
|
# Mapping
|
||||||
|
|
||||||
|
[ ] Load arenas from config file
|
||||||
|
[ ] Live map editing
|
||||||
|
|
||||||
# Game lifecycle
|
# Game lifecycle
|
||||||
|
|
||||||
[ ] Return to lobby
|
[ ] /list arenas and games
|
||||||
[ ] Join game via sign/commands/something
|
[ ] /start a game on an arena
|
||||||
[ ] Bonus coins for complete coin pickup
|
[ ] /join games
|
||||||
|
[X] /ready
|
||||||
|
[ ] /leave games
|
||||||
|
[ ] /restart games
|
||||||
|
[X] Spectator mode on death
|
||||||
|
[X] Player readiness starts countdown
|
||||||
|
[ ] Game is automatically closed some time after game over
|
||||||
|
[ ] Return to lobby on leave/close
|
||||||
|
[ ] Instancing
|
||||||
|
|
||||||
# Cleanup
|
# Powerups
|
||||||
|
|
||||||
[ ] Generic countdown mechanic
|
[ ] Coin pickup range
|
||||||
[ ]
|
[ ] Coin boost
|
||||||
|
[ ] Knockback on weapons
|
||||||
|
[ ] Damage boost
|
||||||
|
[ ] Speed boost
|
||||||
|
[ ] Health boost
|
||||||
|
[ ] Repair barriers
|
||||||
|
|
||||||
|
# Fantasy
|
||||||
|
|
||||||
|
[ ] Totems/turrets/stationary weapons
|
||||||
|
@ -7,6 +7,7 @@ import org.bukkit.event.Listener;
|
|||||||
import org.bukkit.event.entity.EntityDeathEvent;
|
import org.bukkit.event.entity.EntityDeathEvent;
|
||||||
import org.bukkit.event.entity.EntityDamageEvent;
|
import org.bukkit.event.entity.EntityDamageEvent;
|
||||||
import org.bukkit.event.entity.EntityCombustEvent;
|
import org.bukkit.event.entity.EntityCombustEvent;
|
||||||
|
import org.bukkit.event.entity.EntityTargetEvent;
|
||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
@ -32,6 +33,11 @@ public class GameEventHandler implements Listener {
|
|||||||
evt.setCancelled(true);
|
evt.setCancelled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onEntityTarget(EntityTargetEvent evt) {
|
||||||
|
m_runner.handleEntityRetargeting(evt);
|
||||||
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onEntityDamage(EntityDamageEvent evt) {
|
public void onEntityDamage(EntityDamageEvent evt) {
|
||||||
if (evt.getEntity() instanceof Player) {
|
if (evt.getEntity() instanceof Player) {
|
||||||
|
@ -8,13 +8,15 @@ import org.bukkit.World;
|
|||||||
public class MemoryArena implements Arena {
|
public class MemoryArena implements Arena {
|
||||||
|
|
||||||
Spawnpoint[] m_spawnpoints;
|
Spawnpoint[] m_spawnpoints;
|
||||||
|
Spawnpoint m_bombTarget;
|
||||||
World m_world;
|
World m_world;
|
||||||
String m_name;
|
String m_name;
|
||||||
|
|
||||||
public MemoryArena(String name, World world, Spawnpoint[] spawnpoints) {
|
public MemoryArena(String name, World world, Spawnpoint[] spawnpoints, Spawnpoint bombTarget) {
|
||||||
m_world = world;
|
m_world = world;
|
||||||
m_spawnpoints = spawnpoints;
|
m_spawnpoints = spawnpoints;
|
||||||
m_name = name;
|
m_name = name;
|
||||||
|
m_bombTarget = bombTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -31,4 +33,9 @@ public class MemoryArena implements Arena {
|
|||||||
public World getWorld() {
|
public World getWorld() {
|
||||||
return m_world;
|
return m_world;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Spawnpoint bombTarget() {
|
||||||
|
return m_bombTarget;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import org.bukkit.Location;
|
|||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.WorldCreator;
|
||||||
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
@ -24,6 +25,7 @@ import gg.malloc.defense.engine.GameRunner;
|
|||||||
|
|
||||||
import gg.malloc.defense.commands.AddPlayerCommand;
|
import gg.malloc.defense.commands.AddPlayerCommand;
|
||||||
import gg.malloc.defense.commands.SetStageCommand;
|
import gg.malloc.defense.commands.SetStageCommand;
|
||||||
|
import gg.malloc.defense.commands.PlayerReadyCommand;
|
||||||
|
|
||||||
public class Plugin extends JavaPlugin {
|
public class Plugin extends JavaPlugin {
|
||||||
ArrayList<Arena> m_arenas = new ArrayList<>();
|
ArrayList<Arena> m_arenas = new ArrayList<>();
|
||||||
@ -65,6 +67,7 @@ public class Plugin extends JavaPlugin {
|
|||||||
getCommand("setstage").setExecutor(new SetStageCommand(this));
|
getCommand("setstage").setExecutor(new SetStageCommand(this));
|
||||||
getCommand("addplayer").setExecutor(new AddPlayerCommand(this));
|
getCommand("addplayer").setExecutor(new AddPlayerCommand(this));
|
||||||
getCommand("debuginfo").setExecutor(new DebuginfoCommand(this));
|
getCommand("debuginfo").setExecutor(new DebuginfoCommand(this));
|
||||||
|
getCommand("ready").setExecutor(new PlayerReadyCommand(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameRunner getRunnerForWorld(World world) {
|
public GameRunner getRunnerForWorld(World world) {
|
||||||
@ -81,14 +84,16 @@ public class Plugin extends JavaPlugin {
|
|||||||
|
|
||||||
void setupDemoGame() {
|
void setupDemoGame() {
|
||||||
getLogger().info("Setting up demo data'");
|
getLogger().info("Setting up demo data'");
|
||||||
World testWorld = getServer().getWorld("world");
|
World testWorld = getServer().getWorld("quarry");
|
||||||
Spawnpoint[] spawnpoints = new Spawnpoint[4];
|
if (testWorld == null) {
|
||||||
Location spawnCenter = testWorld.getSpawnLocation();
|
testWorld = new WorldCreator("quarry").generateStructures(false).createWorld();
|
||||||
for(int i = 0; i < 4; i++) {
|
|
||||||
Location spawnLocation = spawnCenter.add(Math.random() * 3, 0, Math.random() * 3);
|
|
||||||
spawnpoints[i] = new TestSpawn(spawnLocation);
|
|
||||||
}
|
}
|
||||||
m_arenas.add(new MemoryArena("Test Arena", testWorld, spawnpoints));
|
Spawnpoint[] spawnpoints = new Spawnpoint[3];
|
||||||
|
spawnpoints[0] = new TestSpawn(new Location(testWorld, -15, 80, -46));
|
||||||
|
spawnpoints[1] = new TestSpawn(new Location(testWorld, -1, 80, -45));
|
||||||
|
spawnpoints[2] = new TestSpawn(new Location(testWorld, 12, 81, -42));
|
||||||
|
Spawnpoint bombTarget = new TestSpawn(new Location(testWorld, -20, 80, 31));
|
||||||
|
m_arenas.add(new MemoryArena("Test Arena", testWorld, spawnpoints, bombTarget));
|
||||||
m_games.add(new ScaledWaves());
|
m_games.add(new ScaledWaves());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
package gg.malloc.defense.commands;
|
||||||
|
|
||||||
|
import org.bukkit.command.Command;
|
||||||
|
import org.bukkit.command.CommandExecutor;
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import gg.malloc.defense.engine.GameRunner;
|
||||||
|
|
||||||
|
import gg.malloc.defense.Plugin;
|
||||||
|
|
||||||
|
public class PlayerReadyCommand implements CommandExecutor {
|
||||||
|
Plugin m_plugin;
|
||||||
|
|
||||||
|
public PlayerReadyCommand(Plugin plugin) {
|
||||||
|
m_plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onCommand(CommandSender sender, Command command, String s, String[] args) {
|
||||||
|
if (sender instanceof Player) {
|
||||||
|
Player player = (Player)sender;
|
||||||
|
GameRunner runner = m_plugin.getRunnerForWorld(player.getLocation().getWorld());
|
||||||
|
runner.addPlayer(player);
|
||||||
|
runner.togglePlayerReady(player);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
sender.sendMessage("You must be a player to use this command.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -10,14 +10,18 @@ import gg.malloc.defense.Plugin;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Sound;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.boss.BarColor;
|
import org.bukkit.boss.BarColor;
|
||||||
import org.bukkit.boss.BarStyle;
|
import org.bukkit.boss.BarStyle;
|
||||||
import org.bukkit.boss.BossBar;
|
import org.bukkit.boss.BossBar;
|
||||||
import org.bukkit.event.player.PlayerTeleportEvent;
|
import org.bukkit.event.player.PlayerTeleportEvent;
|
||||||
|
import org.bukkit.event.entity.EntityTargetEvent;
|
||||||
import org.bukkit.event.entity.EntityDamageEvent;
|
import org.bukkit.event.entity.EntityDamageEvent;
|
||||||
|
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.LivingEntity;
|
import org.bukkit.entity.LivingEntity;
|
||||||
|
import org.bukkit.entity.ArmorStand;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
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_gameBar = Bukkit.createBossBar("Malloc Defense", BarColor.PURPLE, BarStyle.SOLID);
|
||||||
BossBar m_waveBar = 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;
|
BukkitTask m_countdownTask;
|
||||||
|
|
||||||
MobManager m_mobs;
|
MobManager m_mobs;
|
||||||
WaveManager m_waves;
|
WaveManager m_waves;
|
||||||
PlayerManager m_players;
|
PlayerManager m_players;
|
||||||
|
|
||||||
|
LivingEntity m_bombTarget = null;
|
||||||
|
int m_bombHP = 100;
|
||||||
|
|
||||||
Logger m_log;
|
Logger m_log;
|
||||||
|
|
||||||
public enum Stage {
|
public enum Stage {
|
||||||
Idle,
|
Idle,
|
||||||
Warmup,
|
Warmup,
|
||||||
|
Countdown,
|
||||||
Playing,
|
Playing,
|
||||||
GameOver
|
GameOver
|
||||||
}
|
}
|
||||||
@ -104,6 +114,7 @@ public class GameRunner {
|
|||||||
m_stage = Stage.Idle;
|
m_stage = Stage.Idle;
|
||||||
m_gameBar.setVisible(true);
|
m_gameBar.setVisible(true);
|
||||||
m_waveBar.setVisible(false);
|
m_waveBar.setVisible(false);
|
||||||
|
m_bombBar.setVisible(false);
|
||||||
m_mobs = new MobManager(m_game);
|
m_mobs = new MobManager(m_game);
|
||||||
m_waves = new WaveManager(m_game);
|
m_waves = new WaveManager(m_game);
|
||||||
m_players = new PlayerManager();
|
m_players = new PlayerManager();
|
||||||
@ -112,8 +123,30 @@ public class GameRunner {
|
|||||||
|
|
||||||
int m_warmupCountdown = 0;
|
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) {
|
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() {
|
private void countdownTick() {
|
||||||
@ -130,9 +163,14 @@ public class GameRunner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean enterIdle() {
|
private boolean enterIdle() {
|
||||||
|
m_bombHP = 100;
|
||||||
m_waves.reset();
|
m_waves.reset();
|
||||||
m_mobs.clear();
|
m_mobs.clear();
|
||||||
m_players.requestTransitionForAll(PlayerManager.State.Idle);
|
m_players.requestTransitionForAll(PlayerManager.State.Idle);
|
||||||
|
if (m_bombTarget != null) {
|
||||||
|
m_bombTarget.remove();
|
||||||
|
m_bombTarget = null;
|
||||||
|
}
|
||||||
if (m_countdownTask != null) {
|
if (m_countdownTask != null) {
|
||||||
m_countdownTask.cancel();
|
m_countdownTask.cancel();
|
||||||
m_countdownTask = null;
|
m_countdownTask = null;
|
||||||
@ -142,20 +180,49 @@ public class GameRunner {
|
|||||||
|
|
||||||
private boolean enterWarmup() {
|
private boolean enterWarmup() {
|
||||||
m_waves.next();
|
m_waves.next();
|
||||||
m_warmupCountdown = 10;
|
|
||||||
for(Player p : m_players.getPlayers()) {
|
for(Player p : m_players.getPlayers()) {
|
||||||
if (m_players.requestTransition(p, PlayerManager.State.Playing)) {
|
if (m_players.requestTransition(p, PlayerManager.State.Playing)) {
|
||||||
p.teleport(m_arena.getWorld().getSpawnLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN);
|
p.teleport(m_arena.getWorld().getSpawnLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN);
|
||||||
}
|
}
|
||||||
|
m_players.setReady(p, false);
|
||||||
}
|
}
|
||||||
broadcastTitle("Warmup", "Prepare yourself for wave " + m_waves.currentWaveNum());
|
broadcastTitle("Warmup", "Prepare yourself for wave " + m_waves.currentWaveNum());
|
||||||
m_mobs.clear();
|
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();
|
countdownTick();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean enterPlaying() {
|
private boolean enterPlaying() {
|
||||||
m_log.info("Starting wave " + m_waves.currentWaveNum());
|
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();
|
spawnNextBatch();
|
||||||
broadcastTitle("Wave " + m_waves.currentWaveNum());
|
broadcastTitle("Wave " + m_waves.currentWaveNum());
|
||||||
return true;
|
return true;
|
||||||
@ -179,18 +246,30 @@ public class GameRunner {
|
|||||||
switch(m_stage) {
|
switch(m_stage) {
|
||||||
case Idle:
|
case Idle:
|
||||||
m_gameBar.setProgress(1.0);
|
m_gameBar.setProgress(1.0);
|
||||||
m_gameBar.setTitle("Waiting for playres...");
|
m_gameBar.setTitle("Waiting for players...");
|
||||||
m_gameBar.setColor(BarColor.PURPLE);
|
m_gameBar.setColor(BarColor.PURPLE);
|
||||||
m_waveBar.setVisible(false);
|
m_waveBar.setVisible(false);
|
||||||
|
m_bombBar.setVisible(false);
|
||||||
break;
|
break;
|
||||||
case Warmup:
|
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.setProgress(m_waves.progress());
|
||||||
m_gameBar.setTitle("Wave " + m_waves.currentWaveNum() + " / " + m_game.getWaveCount());
|
m_gameBar.setTitle("Wave " + m_waves.currentWaveNum() + " / " + m_game.getWaveCount());
|
||||||
m_gameBar.setColor(BarColor.PURPLE);
|
m_gameBar.setColor(BarColor.PURPLE);
|
||||||
m_waveBar.setVisible(true);
|
m_waveBar.setVisible(true);
|
||||||
m_waveBar.setColor(BarColor.YELLOW);
|
m_waveBar.setColor(BarColor.YELLOW);
|
||||||
m_waveBar.setTitle("Warmup");
|
m_waveBar.setTitle("Wave starting!");
|
||||||
m_waveBar.setProgress((double)m_warmupCountdown / (double)10);
|
m_waveBar.setProgress((double)m_warmupCountdown / (double)10);
|
||||||
|
m_bombBar.setVisible(false);
|
||||||
break;
|
break;
|
||||||
case Playing:
|
case Playing:
|
||||||
m_gameBar.setProgress(m_waves.progress());
|
m_gameBar.setProgress(m_waves.progress());
|
||||||
@ -204,19 +283,22 @@ public class GameRunner {
|
|||||||
} else {
|
} else {
|
||||||
m_waveBar.setVisible(false);
|
m_waveBar.setVisible(false);
|
||||||
}
|
}
|
||||||
|
m_bombBar.setVisible(true);
|
||||||
|
m_bombBar.setProgress((double)m_bombHP / (double)100);
|
||||||
break;
|
break;
|
||||||
case GameOver:
|
case GameOver:
|
||||||
m_gameBar.setColor(BarColor.RED);
|
m_gameBar.setColor(BarColor.RED);
|
||||||
m_gameBar.setProgress(1.0);
|
m_gameBar.setProgress(1.0);
|
||||||
m_gameBar.setTitle("Game Over!");
|
m_gameBar.setTitle("Game Over!");
|
||||||
m_waveBar.setVisible(false);
|
m_waveBar.setVisible(false);
|
||||||
|
m_bombBar.setVisible(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void spawnNextBatch() {
|
private void spawnNextBatch() {
|
||||||
broadcastMessage("Spawning batch " + m_waves.currentBatchNum());
|
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());
|
m_waves.currentWave().spawnBatch(spawner, m_waves.currentBatchNum());
|
||||||
updateMobBars();
|
updateMobBars();
|
||||||
}
|
}
|
||||||
@ -265,6 +347,8 @@ public class GameRunner {
|
|||||||
return enterIdle();
|
return enterIdle();
|
||||||
case Warmup:
|
case Warmup:
|
||||||
return enterWarmup();
|
return enterWarmup();
|
||||||
|
case Countdown:
|
||||||
|
return enterCountdown();
|
||||||
case Playing:
|
case Playing:
|
||||||
return enterPlaying();
|
return enterPlaying();
|
||||||
case GameOver:
|
case GameOver:
|
||||||
@ -278,7 +362,9 @@ public class GameRunner {
|
|||||||
case Idle:
|
case Idle:
|
||||||
return to == Stage.Warmup;
|
return to == Stage.Warmup;
|
||||||
case 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:
|
case Playing:
|
||||||
return to == Stage.Warmup || to == Stage.GameOver || to == Stage.Idle;
|
return to == Stage.Warmup || to == Stage.GameOver || to == Stage.Idle;
|
||||||
case GameOver:
|
case GameOver:
|
||||||
@ -306,6 +392,7 @@ public class GameRunner {
|
|||||||
m_players.addPlayer(p);
|
m_players.addPlayer(p);
|
||||||
m_gameBar.addPlayer(p);
|
m_gameBar.addPlayer(p);
|
||||||
m_waveBar.addPlayer(p);
|
m_waveBar.addPlayer(p);
|
||||||
|
m_bombBar.addPlayer(p);
|
||||||
if (m_stage == Stage.Idle || m_stage == Stage.Warmup) {
|
if (m_stage == Stage.Idle || m_stage == Stage.Warmup) {
|
||||||
if (m_players.requestTransition(p, PlayerManager.State.Playing)) {
|
if (m_players.requestTransition(p, PlayerManager.State.Playing)) {
|
||||||
p.teleport(m_arena.getWorld().getSpawnLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN);
|
p.teleport(m_arena.getWorld().getSpawnLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN);
|
||||||
@ -346,5 +433,4 @@ public class GameRunner {
|
|||||||
void registerSpawnedMob(Entity entity) {
|
void registerSpawnedMob(Entity entity) {
|
||||||
m_mobs.addEntity(entity);
|
m_mobs.addEntity(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,15 +7,20 @@ import gg.malloc.defense.model.Arena;
|
|||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.LivingEntity;
|
import org.bukkit.entity.LivingEntity;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.entity.Mob;
|
||||||
|
|
||||||
public class GameSpawner implements Spawner {
|
public class GameSpawner implements Spawner {
|
||||||
Arena m_arena;
|
Arena m_arena;
|
||||||
MobManager m_manager;
|
MobManager m_manager;
|
||||||
|
PlayerManager m_players;
|
||||||
|
LivingEntity m_bombTarget;
|
||||||
int m_spawnIdx = 0;
|
int m_spawnIdx = 0;
|
||||||
|
|
||||||
public GameSpawner(Arena arena, MobManager manager) {
|
public GameSpawner(Arena arena, MobManager manager, PlayerManager players, LivingEntity bombTarget) {
|
||||||
m_arena = arena;
|
m_arena = arena;
|
||||||
m_manager = manager;
|
m_manager = manager;
|
||||||
|
m_players = players;
|
||||||
|
m_bombTarget = bombTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -28,6 +33,7 @@ public class GameSpawner implements Spawner {
|
|||||||
livingMob.setRemoveWhenFarAway(false);
|
livingMob.setRemoveWhenFarAway(false);
|
||||||
m_manager.addEntity(newMob);
|
m_manager.addEntity(newMob);
|
||||||
m_spawnIdx += 1;
|
m_spawnIdx += 1;
|
||||||
|
((Mob)newMob).setTarget(m_bombTarget);
|
||||||
return newMob;
|
return newMob;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,10 @@ public class MobManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean contains(Entity entity) {
|
||||||
|
return m_livingMobs.contains(entity);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean killMob(Entity entity) {
|
public boolean killMob(Entity entity) {
|
||||||
if (m_livingMobs.contains(entity)) {
|
if (m_livingMobs.contains(entity)) {
|
||||||
m_killedMobs += 1;
|
m_killedMobs += 1;
|
||||||
|
@ -11,6 +11,7 @@ import java.util.Collection;
|
|||||||
|
|
||||||
public class PlayerManager {
|
public class PlayerManager {
|
||||||
HashMap<Player, State> m_playerStates = new HashMap<>();
|
HashMap<Player, State> m_playerStates = new HashMap<>();
|
||||||
|
HashMap<Player, Boolean> m_playerReadyStates = new HashMap<>();
|
||||||
|
|
||||||
public enum State {
|
public enum State {
|
||||||
Idle,
|
Idle,
|
||||||
@ -70,6 +71,34 @@ public class PlayerManager {
|
|||||||
public void addPlayer(Player player) {
|
public void addPlayer(Player player) {
|
||||||
//m_log.info("Adding player " + player);
|
//m_log.info("Adding player " + player);
|
||||||
m_playerStates.put(player, State.Idle);
|
m_playerStates.put(player, State.Idle);
|
||||||
|
m_playerReadyStates.put(player, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReady(Player player) {
|
||||||
|
return m_playerReadyStates.get(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setReady(Player player, boolean ready) {
|
||||||
|
m_playerReadyStates.put(player, ready);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double readyProgress() {
|
||||||
|
int readyNum = 0;
|
||||||
|
for(boolean b : m_playerReadyStates.values()) {
|
||||||
|
if (b) {
|
||||||
|
readyNum += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (double)readyNum / (double)m_playerReadyStates.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEveryoneReady() {
|
||||||
|
for(boolean b : m_playerReadyStates.values()) {
|
||||||
|
if (!b) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean removePlayer(Player player) {
|
public boolean removePlayer(Player player) {
|
||||||
|
@ -6,4 +6,5 @@ public interface Arena {
|
|||||||
World getWorld();
|
World getWorld();
|
||||||
String name();
|
String name();
|
||||||
Spawnpoint[] spawnpoints();
|
Spawnpoint[] spawnpoints();
|
||||||
|
Spawnpoint bombTarget();
|
||||||
}
|
}
|
||||||
|
@ -10,3 +10,5 @@ commands:
|
|||||||
description: Adds a player to a game
|
description: Adds a player to a game
|
||||||
debuginfo:
|
debuginfo:
|
||||||
description: Unknowable powers
|
description: Unknowable powers
|
||||||
|
ready:
|
||||||
|
description: Mark yourself as ready for the next wave
|
||||||
|
Loading…
Reference in New Issue
Block a user