Implement first pass at config loading, /join, /leave commands, tab completion (broken)
This commit is contained in:
parent
75debe1905
commit
a4b110773e
39
TODO.md
39
TODO.md
@ -8,12 +8,18 @@
|
||||
|
||||
# Malloc Beta
|
||||
|
||||
[ ] Join games
|
||||
[ ] Leave games
|
||||
[ ] One arena config
|
||||
[X] One arena config
|
||||
[ ] Config reload
|
||||
[X] Leave games
|
||||
[X] Join games
|
||||
[ ] Lobby with instructions
|
||||
[ ] Drop back to lobby on game over
|
||||
[ ] Grist drops
|
||||
[ ] Item shoppes
|
||||
|
||||
# Scaled waves
|
||||
|
||||
[ ] Limit ranged mobs and Ravagers to non-bomb-carrier state
|
||||
[ ] Weaker mobs, more of them
|
||||
[ ] Mob categories
|
||||
[ ] Spawnpoint categories
|
||||
@ -24,9 +30,16 @@
|
||||
[X] Mob count boss bar
|
||||
[X] Stage titles
|
||||
[X] EXPLOSIONS
|
||||
[ ] Target catches on fire more it is lit
|
||||
[X] Bomb model
|
||||
[ ] Pretty bomb model
|
||||
[ ] "Player $X is ready" message in chat
|
||||
[ ] Colored titles
|
||||
[ ] Clickable join links in /list
|
||||
[ ] Clickable /leave action
|
||||
[ ] Clickable /ready in chat
|
||||
[ ] Countdown while in warmup
|
||||
[ ] Countdown shrinks w/ every /ready player
|
||||
[ ] Target catches on fire more it is lit
|
||||
[ ] Sidebar
|
||||
[ ] List of mobs in next wave
|
||||
|
||||
@ -37,13 +50,16 @@
|
||||
[ ] Plan stats
|
||||
[ ] /invite friends to games
|
||||
[ ] /voterestart
|
||||
[ ] Medals/awards/scoreboards
|
||||
|
||||
# Mechanics
|
||||
|
||||
[ ] Coin drops
|
||||
[X] Mob tracking should prioritize bomb
|
||||
[X] Mobs recover dropped bombs
|
||||
[X] Bomb carriers are slower
|
||||
[ ] Coin drops
|
||||
[ ] Mob categories
|
||||
[ ] Mobs split between bomb and player priorities
|
||||
[ ] Bonus coins for complete coin pickup
|
||||
[ ] Infinite weapons + armor
|
||||
[ ] Ammo/health spawns
|
||||
@ -56,26 +72,29 @@
|
||||
[X] Batch overlap
|
||||
[ ] Scripted batch overlap/timings
|
||||
[ ] Scripted spawn locations
|
||||
[ ] Scripted waypoint paths
|
||||
[ ] Bosses
|
||||
|
||||
# Mapping
|
||||
|
||||
[ ] Load arenas from config file
|
||||
[X] Load arenas from config file
|
||||
[ ] Live map editing
|
||||
|
||||
# Game lifecycle
|
||||
|
||||
[ ] /list arenas and games
|
||||
[ ] /start a game on an arena
|
||||
[ ] /join games
|
||||
[X] /list arenas and games
|
||||
[X] /join games
|
||||
[X] /ready
|
||||
[ ] /leave games
|
||||
[X] /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
|
||||
[ ] Restore health+hunger on respawn/game start
|
||||
[ ] Respawn during games
|
||||
[ ] Player revival items
|
||||
|
||||
# Powerups
|
||||
|
||||
|
@ -1,41 +1,27 @@
|
||||
package gg.malloc.defense;
|
||||
|
||||
import gg.malloc.defense.model.Arena;
|
||||
import gg.malloc.defense.model.Spawnpoint;
|
||||
import gg.malloc.defense.model.Waypoint;
|
||||
|
||||
import org.bukkit.World;
|
||||
|
||||
public class MemoryArena implements Arena {
|
||||
|
||||
Spawnpoint[] m_spawnpoints;
|
||||
Spawnpoint m_bombTarget;
|
||||
World m_world;
|
||||
String m_name;
|
||||
Waypoint[] m_spawnpoints;
|
||||
Waypoint m_bombTarget;
|
||||
|
||||
public MemoryArena(String name, World world, Spawnpoint[] spawnpoints, Spawnpoint bombTarget) {
|
||||
m_world = world;
|
||||
public MemoryArena(Waypoint[] spawnpoints, Waypoint bombTarget) {
|
||||
m_spawnpoints = spawnpoints;
|
||||
m_name = name;
|
||||
m_bombTarget = bombTarget;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return m_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spawnpoint[] spawnpoints() {
|
||||
public Waypoint[] spawnpoints() {
|
||||
return m_spawnpoints;
|
||||
}
|
||||
|
||||
@Override
|
||||
public World getWorld() {
|
||||
return m_world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spawnpoint bombTarget() {
|
||||
public Waypoint bombTarget() {
|
||||
return m_bombTarget;
|
||||
}
|
||||
}
|
||||
|
@ -5,17 +5,27 @@ import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldCreator;
|
||||
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.EventHandler;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
|
||||
import gg.malloc.defense.model.Arena;
|
||||
import gg.malloc.defense.model.Spawnpoint;
|
||||
import gg.malloc.defense.model.Waypoint;
|
||||
import gg.malloc.defense.model.Game;
|
||||
|
||||
import gg.malloc.defense.games.LinearGame;
|
||||
@ -26,32 +36,40 @@ import gg.malloc.defense.engine.GameRunner;
|
||||
import gg.malloc.defense.commands.AddPlayerCommand;
|
||||
import gg.malloc.defense.commands.SetStageCommand;
|
||||
import gg.malloc.defense.commands.PlayerReadyCommand;
|
||||
import gg.malloc.defense.commands.ListGamesCommand;
|
||||
import gg.malloc.defense.commands.JoinGameCommand;
|
||||
import gg.malloc.defense.commands.LeaveGameCommand;
|
||||
|
||||
public class Plugin extends JavaPlugin {
|
||||
ArrayList<Arena> m_arenas = new ArrayList<>();
|
||||
HashMap<String, Arena> m_arenas = new HashMap<>();
|
||||
ArrayList<Game> m_games = new ArrayList<>();
|
||||
HashMap<World, GameRunner> m_runningGames = new HashMap<>();
|
||||
HashMap<String, GameRunner> m_runningGames = new HashMap<>();
|
||||
HashMap<Player, GameRunner> m_playerGames = new HashMap<>();
|
||||
|
||||
private class TestSpawn implements Spawnpoint {
|
||||
Location m_location;
|
||||
|
||||
public TestSpawn(Location location) {
|
||||
m_location = location;
|
||||
public Collection<String> arenaNames() {
|
||||
return m_arenas.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getLocation() {
|
||||
return m_location;
|
||||
private class TestSpawn implements Waypoint {
|
||||
double m_x;
|
||||
double m_y;
|
||||
double m_z;
|
||||
String m_name;
|
||||
|
||||
public TestSpawn(double x, double y, double z) {
|
||||
m_x = x;
|
||||
m_y = y;
|
||||
m_z = z;
|
||||
m_name = "(" + x + "," + y + "," + z + ")";
|
||||
}
|
||||
|
||||
public double getX() { return m_x; }
|
||||
public double getY() { return m_y; }
|
||||
public double getZ() { return m_z; }
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Mob Spawner";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return "mob-spawner";
|
||||
return m_name;
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,23 +81,107 @@ public class Plugin extends JavaPlugin {
|
||||
public void onEnable() {
|
||||
getLogger().info("Malloc Defense registered");
|
||||
getLogger().setLevel(Level.FINEST);
|
||||
setupDemoGame();
|
||||
getCommand("setstage").setExecutor(new SetStageCommand(this));
|
||||
getCommand("addplayer").setExecutor(new AddPlayerCommand(this));
|
||||
getCommand("debuginfo").setExecutor(new DebuginfoCommand(this));
|
||||
//setupDemoGame();
|
||||
m_games.add(new ScaledWaves());
|
||||
loadArenas();
|
||||
getCommand("join").setExecutor(new JoinGameCommand(this));
|
||||
getCommand("leave").setExecutor(new LeaveGameCommand(this));
|
||||
getCommand("ready").setExecutor(new PlayerReadyCommand(this));
|
||||
getCommand("list").setExecutor(new ListGamesCommand(this));
|
||||
|
||||
getCommand("addplayer").setExecutor(new AddPlayerCommand(this));
|
||||
getCommand("setstage").setExecutor(new SetStageCommand(this));
|
||||
getCommand("debuginfo").setExecutor(new DebuginfoCommand(this));
|
||||
|
||||
getServer().getPluginManager().registerEvents(new PlayerQuitHandler(), this);
|
||||
}
|
||||
|
||||
public GameRunner getRunnerForWorld(World world) {
|
||||
void loadArenas() {
|
||||
getLogger().info("Loading arenas...");
|
||||
saveDefaultConfig();
|
||||
ConfigurationSection pluginConfig = getConfig();
|
||||
ConfigurationSection mapList = pluginConfig.getConfigurationSection("maps");
|
||||
|
||||
for(String mapName : mapList.getKeys(false)) {
|
||||
getLogger().info("Loading arena: " + mapName);
|
||||
ConfigurationSection mapConfig = mapList.getConfigurationSection(mapName);
|
||||
List<Map<?, ?>> spawnpointList = mapConfig.getMapList("spawnpoints");
|
||||
ArrayList<Waypoint> spawnpoints = new ArrayList<>();
|
||||
|
||||
for(Map<?, ?> spawnerObj : spawnpointList) {
|
||||
Map<String, Double> thisSpawner = (Map<String, Double>)spawnerObj;
|
||||
double x = thisSpawner.get("x");
|
||||
double y = thisSpawner.get("y");
|
||||
double z = thisSpawner.get("z");
|
||||
spawnpoints.add(new TestSpawn(x, y, z));
|
||||
}
|
||||
|
||||
ConfigurationSection targetConfig = mapConfig.getConfigurationSection("target");
|
||||
double x = targetConfig.getDouble("x");
|
||||
double y = targetConfig.getDouble("y");
|
||||
double z = targetConfig.getDouble("z");
|
||||
Waypoint bombTarget = new TestSpawn(x, y, z);
|
||||
Waypoint[] spawnArray = new Waypoint[spawnpoints.size()];
|
||||
spawnpoints.toArray(spawnArray);
|
||||
Arena arena = new MemoryArena(spawnArray, bombTarget);
|
||||
m_arenas.put(mapName, arena);
|
||||
}
|
||||
}
|
||||
|
||||
/*GameRunner getRunnerForWorld(World world) {
|
||||
GameRunner ret;
|
||||
if (m_runningGames.containsKey(world)) {
|
||||
ret = m_runningGames.get(world);
|
||||
} else {
|
||||
ret = new GameRunner(this, m_games.get(0), m_arenas.get(0));
|
||||
} else if (m_arenas.containsKey(world)) {
|
||||
ret = new GameRunner(this, m_games.get(0), m_arenas.get(world.getName()), world);
|
||||
m_runningGames.put(world, ret);
|
||||
getServer().getPluginManager().registerEvents(new GameEventHandler(ret), this);
|
||||
}
|
||||
return ret;
|
||||
}*/
|
||||
|
||||
public boolean hasRunnerForArenaName(String arenaName) {
|
||||
return m_runningGames.containsKey(arenaName);
|
||||
}
|
||||
|
||||
public void addPlayerToArena(String arenaName, Player player) {
|
||||
GameRunner runner = getRunnerForArenaName(arenaName);
|
||||
runner.addPlayer(player);
|
||||
m_playerGames.put(player, runner);
|
||||
}
|
||||
|
||||
class PlayerQuitHandler implements Listener {
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent evt) {
|
||||
m_playerGames.remove(evt.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
public GameRunner getRunnerForArenaName(String arenaName) {
|
||||
GameRunner ret = null;
|
||||
if (m_runningGames.containsKey(arenaName)) {
|
||||
ret = m_runningGames.get(arenaName);
|
||||
} else if (m_arenas.containsKey(arenaName)) {
|
||||
getLogger().info("Loading game world " + arenaName);
|
||||
World gameWorld = getServer().getWorld(arenaName);
|
||||
if (gameWorld == null) {
|
||||
getLogger().info("Creating game world " + arenaName);
|
||||
gameWorld = new WorldCreator(arenaName).generateStructures(false).createWorld();
|
||||
}
|
||||
ret = new GameRunner(this, m_games.get(0), m_arenas.get(arenaName), gameWorld);
|
||||
getServer().getPluginManager().registerEvents(new GameEventHandler(ret), this);
|
||||
m_runningGames.put(arenaName, ret);
|
||||
getLogger().info("Game ready for " + arenaName);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public GameRunner getRunnerForPlayer(Player p) {
|
||||
GameRunner ret = null;
|
||||
if (m_playerGames.containsKey(p)) {
|
||||
ret = m_playerGames.get(p);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void setupDemoGame() {
|
||||
@ -88,12 +190,11 @@ public class Plugin extends JavaPlugin {
|
||||
if (testWorld == null) {
|
||||
testWorld = new WorldCreator("quarry").generateStructures(false).createWorld();
|
||||
}
|
||||
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());
|
||||
Waypoint[] spawnpoints = new Waypoint[3];
|
||||
spawnpoints[0] = new TestSpawn(-15, 80, -46);
|
||||
spawnpoints[1] = new TestSpawn(-1, 80, -45);
|
||||
spawnpoints[2] = new TestSpawn(12, 81, -42);
|
||||
Waypoint bombTarget = new TestSpawn(-20, 80, 31);
|
||||
m_arenas.put("quarry", new MemoryArena(spawnpoints, bombTarget));
|
||||
}
|
||||
}
|
||||
|
@ -18,8 +18,12 @@ public class AddPlayerCommand implements CommandExecutor {
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String s, String[] args) {
|
||||
String worldName = args[0];
|
||||
GameRunner runner = m_plugin.getRunnerForWorld(m_plugin.getServer().getWorld(worldName));
|
||||
String arenaName = args[0];
|
||||
GameRunner runner = m_plugin.getRunnerForArenaName(arenaName);
|
||||
if (runner == null) {
|
||||
sender.sendMessage("No such arena '" + arenaName + "'");
|
||||
return true;
|
||||
}
|
||||
Player player = m_plugin.getServer().getPlayer(args[1]);
|
||||
runner.addPlayer(player);
|
||||
return true;
|
||||
|
@ -0,0 +1,56 @@
|
||||
package gg.malloc.defense.commands;
|
||||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import gg.malloc.defense.engine.GameRunner;
|
||||
|
||||
import gg.malloc.defense.Plugin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class JoinGameCommand implements TabExecutor {
|
||||
Plugin m_plugin;
|
||||
|
||||
public JoinGameCommand(Plugin plugin) {
|
||||
m_plugin = plugin;
|
||||
}
|
||||
|
||||
public List<String> onTabComplete(CommandSender sender, Command command, String label, String[] args) {
|
||||
ArrayList<String> ret = new ArrayList<>();
|
||||
if (args.length == 1) {
|
||||
String proposal = args[0].toLowerCase();
|
||||
for(String arena : m_plugin.arenaNames()) {
|
||||
if (proposal.startsWith(arena.toLowerCase())) {
|
||||
ret.add(arena);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String s, String[] args) {
|
||||
if (args.length != 1) {
|
||||
sender.sendMessage("Usage: join <game>");
|
||||
return true;
|
||||
}
|
||||
if (sender instanceof Player) {
|
||||
Player player = (Player)sender;
|
||||
String arenaName = args[0];
|
||||
sender.sendMessage("Joining arena '" + arenaName + "'...");
|
||||
GameRunner runner = m_plugin.getRunnerForArenaName(arenaName);
|
||||
if (runner == null) {
|
||||
sender.sendMessage("No such arena '" + arenaName + "'");
|
||||
return true;
|
||||
}
|
||||
m_plugin.addPlayerToArena(arenaName, player);
|
||||
} else {
|
||||
sender.sendMessage("Only players may use htis command.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
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 LeaveGameCommand implements CommandExecutor {
|
||||
Plugin m_plugin;
|
||||
|
||||
public LeaveGameCommand(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.getRunnerForPlayer(player);
|
||||
if (runner == null) {
|
||||
sender.sendMessage("You ae not currently in a game.");
|
||||
return true;
|
||||
}
|
||||
runner.removePlayer(player);
|
||||
} else {
|
||||
sender.sendMessage("Only players may use htis command.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
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 ListGamesCommand implements CommandExecutor {
|
||||
Plugin m_plugin;
|
||||
|
||||
public ListGamesCommand(Plugin plugin) {
|
||||
m_plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String s, String[] args) {
|
||||
sender.sendMessage("Available games:");
|
||||
for(String arenaName : m_plugin.arenaNames()) {
|
||||
String arenaDescription = arenaName + ": ";
|
||||
if (m_plugin.hasRunnerForArenaName(arenaName)) {
|
||||
GameRunner runner = m_plugin.getRunnerForArenaName(arenaName);
|
||||
arenaDescription += runner.getStage().toString();
|
||||
} else {
|
||||
arenaDescription += "Loadable";
|
||||
}
|
||||
sender.sendMessage(arenaDescription);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -20,9 +20,12 @@ public class PlayerReadyCommand implements CommandExecutor {
|
||||
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);
|
||||
GameRunner runner = m_plugin.getRunnerForPlayer(player);
|
||||
if (runner != null) {
|
||||
runner.togglePlayerReady(player);
|
||||
} else {
|
||||
sender.sendMessage("You are not part of any game.");
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
sender.sendMessage("You must be a player to use this command.");
|
||||
|
@ -1,25 +1,56 @@
|
||||
package gg.malloc.defense.commands;
|
||||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
import org.bukkit.World;
|
||||
|
||||
import gg.malloc.defense.engine.GameRunner;
|
||||
|
||||
import gg.malloc.defense.Plugin;
|
||||
|
||||
public class SetStageCommand implements CommandExecutor {
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SetStageCommand implements TabExecutor {
|
||||
Plugin m_plugin;
|
||||
|
||||
public SetStageCommand(Plugin plugin) {
|
||||
m_plugin = plugin;
|
||||
}
|
||||
|
||||
public List<String> onTabComplete(CommandSender sender, Command command, String label, String[] args) {
|
||||
ArrayList<String> ret = new ArrayList<>();
|
||||
if (args.length == 1) {
|
||||
String proposal = args[0];
|
||||
for(String arena : m_plugin.arenaNames()) {
|
||||
if (proposal.startsWith(arena)) {
|
||||
ret.add(arena);
|
||||
}
|
||||
}
|
||||
} else if (args.length == 2) {
|
||||
String proposal = args[1].toLowerCase();
|
||||
GameRunner.Stage stages[] = GameRunner.Stage.Idle.getDeclaringClass().getEnumConstants();
|
||||
for(GameRunner.Stage stage : stages) {
|
||||
if (proposal.startsWith(stage.toString().toLowerCase())) {
|
||||
ret.add(stage.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String s, String[] args) {
|
||||
World world = m_plugin.getServer().getWorld(args[1]);
|
||||
GameRunner runner = m_plugin.getRunnerForWorld(world);
|
||||
if (args.length != 2) {
|
||||
sender.sendMessage("Usage: setstage <stage> <arena>");
|
||||
return true;
|
||||
}
|
||||
GameRunner runner = m_plugin.getRunnerForArenaName(args[1]);
|
||||
if (runner == null) {
|
||||
sender.sendMessage("Unknown arena " + args[1]);
|
||||
return true;
|
||||
}
|
||||
String stateName = args[0].toLowerCase();
|
||||
boolean ret = false;
|
||||
GameRunner.Stage decodedStage = null;
|
||||
|
@ -3,6 +3,7 @@ package gg.malloc.defense.engine;
|
||||
import gg.malloc.defense.model.Arena;
|
||||
import gg.malloc.defense.model.Game;
|
||||
import gg.malloc.defense.model.Spawner;
|
||||
import gg.malloc.defense.model.Waypoint;
|
||||
|
||||
import gg.malloc.defense.ui.BombCarrier;
|
||||
import gg.malloc.defense.ui.BossBars;
|
||||
@ -60,9 +61,16 @@ public class GameRunner {
|
||||
|
||||
BossBars m_bars;
|
||||
|
||||
public GameRunner(Plugin plugin, Game game, Arena arena) {
|
||||
World m_world;
|
||||
|
||||
Location getLocation(Waypoint waypoint) {
|
||||
return new Location(m_world, waypoint.getX(), waypoint.getY(), waypoint.getZ());
|
||||
}
|
||||
|
||||
public GameRunner(Plugin plugin, Game game, Arena arena, World world) {
|
||||
m_plugin = plugin;
|
||||
m_game = game;
|
||||
m_world = world;
|
||||
m_arena = arena;
|
||||
m_stage = Stage.Idle;
|
||||
m_mobs = new MobManager();
|
||||
@ -92,13 +100,13 @@ public class GameRunner {
|
||||
}, 20);
|
||||
|
||||
m_bombSmokeTask = new TickTask(m_plugin, () -> {
|
||||
Location targetLoc = m_arena.bombTarget().getLocation();
|
||||
m_arena.getWorld().spawnParticle(Particle.SMOKE_LARGE, targetLoc, 35, 4, 2, 4);
|
||||
m_arena.getWorld().spawnParticle(Particle.SMALL_FLAME, targetLoc, 30, 3, 2, 3);
|
||||
Location targetLoc = getLocation(m_arena.bombTarget());
|
||||
m_world.spawnParticle(Particle.SMOKE_LARGE, targetLoc, 35, 4, 2, 4);
|
||||
m_world.spawnParticle(Particle.SMALL_FLAME, targetLoc, 30, 3, 2, 3);
|
||||
}, 5);
|
||||
m_bombCrackleTask = new TickTask(m_plugin, () -> {
|
||||
Location targetLoc = m_arena.bombTarget().getLocation();
|
||||
m_arena.getWorld().playSound(targetLoc, Sound.BLOCK_CAMPFIRE_CRACKLE, SoundCategory.NEUTRAL, 1.0f, 1.0f);
|
||||
Location targetLoc = getLocation(m_arena.bombTarget());
|
||||
m_world.playSound(targetLoc, Sound.BLOCK_CAMPFIRE_CRACKLE, SoundCategory.NEUTRAL, 1.0f, 1.0f);
|
||||
}, 35);
|
||||
}
|
||||
|
||||
@ -115,12 +123,12 @@ public class GameRunner {
|
||||
m_log.info("Target attacked!");
|
||||
entityEvt.getDamager().setGlowing(true);
|
||||
m_bombFuse.tickLit();
|
||||
m_arena.getWorld().playSound(m_arena.bombTarget().getLocation(), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 1.5f, 0.9f);
|
||||
m_world.playSound(getLocation(m_arena.bombTarget()), Sound.ENTITY_ZOMBIE_ATTACK_IRON_DOOR, 1.5f, 0.9f);
|
||||
m_bars.update();
|
||||
if (m_bombFuse.isExploded()) {
|
||||
m_arena.getWorld().strikeLightningEffect(m_arena.bombTarget().getLocation());
|
||||
m_arena.getWorld().playSound(m_arena.bombTarget().getLocation(), Sound.ENTITY_GENERIC_EXPLODE, SoundCategory.NEUTRAL, 1.3f, 1.0f);
|
||||
m_arena.getWorld().spawnParticle(Particle.EXPLOSION_HUGE, m_arena.bombTarget().getLocation(), 8, 5, 2, 5);
|
||||
m_world.strikeLightningEffect(getLocation(m_arena.bombTarget()));
|
||||
m_world.playSound(getLocation(m_arena.bombTarget()), Sound.ENTITY_GENERIC_EXPLODE, SoundCategory.NEUTRAL, 1.3f, 1.0f);
|
||||
m_world.spawnParticle(Particle.EXPLOSION_HUGE, getLocation(m_arena.bombTarget()), 8, 5, 2, 5);
|
||||
requestTransition(Stage.GameOver);
|
||||
m_bombSmokeTask.start();
|
||||
m_bombCrackleTask.start();
|
||||
@ -150,7 +158,7 @@ public class GameRunner {
|
||||
m_waves.next();
|
||||
for(Player p : m_players.getPlayers()) {
|
||||
if (m_players.requestTransition(p, PlayerManager.State.Playing)) {
|
||||
p.teleport(m_arena.getWorld().getSpawnLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN);
|
||||
p.teleport(m_world.getSpawnLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN);
|
||||
}
|
||||
m_players.setReady(p, false);
|
||||
}
|
||||
@ -179,11 +187,11 @@ public class GameRunner {
|
||||
|
||||
private boolean enterPlaying() {
|
||||
m_log.info("Starting wave " + m_waves.currentWaveNum());
|
||||
m_mobs.spawnTarget(m_arena.bombTarget().getLocation());
|
||||
m_mobs.spawnTarget(getLocation(m_arena.bombTarget()));
|
||||
// TODO: Set helmet with custom model data
|
||||
for(Player p : m_players.getPlayers()) {
|
||||
if (m_players.requestTransition(p, PlayerManager.State.Playing)) {
|
||||
p.teleport(m_arena.getWorld().getSpawnLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN);
|
||||
p.teleport(m_world.getSpawnLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN);
|
||||
}
|
||||
}
|
||||
m_countdownTask.stop();
|
||||
@ -211,14 +219,14 @@ public class GameRunner {
|
||||
|
||||
private void spawnNextBatch() {
|
||||
broadcastMessage("Spawning batch " + m_waves.currentBatchNum());
|
||||
Spawner spawner = new GameSpawner(m_arena, m_mobs, m_players);
|
||||
Spawner spawner = new GameSpawner(m_world, m_arena, m_mobs, m_players);
|
||||
m_waves.currentWave().spawnBatch(spawner, m_waves.currentBatchNum());
|
||||
m_bars.update();
|
||||
}
|
||||
|
||||
private void handlePlayerDeath(Player player) {
|
||||
if (m_players.requestTransition(player, PlayerManager.State.Dead)) {
|
||||
m_arena.getWorld().strikeLightningEffect(player.getLocation());
|
||||
m_world.strikeLightningEffect(player.getLocation());
|
||||
if (!m_players.isAnyoneAlive()) {
|
||||
broadcastMessage("Everyone is dead :(");
|
||||
requestTransition(Stage.GameOver);
|
||||
@ -273,7 +281,7 @@ public class GameRunner {
|
||||
private boolean validateTransition(Stage from, Stage to) {
|
||||
switch(from) {
|
||||
case Idle:
|
||||
return to == Stage.Warmup;
|
||||
return !m_players.isEmpty() && to == Stage.Warmup;
|
||||
case Warmup:
|
||||
return to == Stage.Playing || to == Stage.Idle || to == Stage.Countdown ;
|
||||
case Countdown:
|
||||
@ -309,7 +317,7 @@ public class GameRunner {
|
||||
m_bars.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);
|
||||
p.teleport(m_world.getSpawnLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN);
|
||||
}
|
||||
broadcastMessage(p.getName() + " has joined the game");
|
||||
if (m_stage == Stage.Idle) {
|
||||
@ -337,8 +345,7 @@ public class GameRunner {
|
||||
}
|
||||
|
||||
void broadcastMessage(String string) {
|
||||
World world = m_arena.getWorld();
|
||||
for(Player p : world.getPlayers()) {
|
||||
for(Player p : m_world.getPlayers()) {
|
||||
p.sendMessage(string);
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,15 @@
|
||||
package gg.malloc.defense.engine;
|
||||
|
||||
import gg.malloc.defense.model.Spawner;
|
||||
import gg.malloc.defense.model.Spawnpoint;
|
||||
import gg.malloc.defense.model.Waypoint;
|
||||
import gg.malloc.defense.model.Arena;
|
||||
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Mob;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.inventory.EntityEquipment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
@ -20,8 +22,10 @@ public class GameSpawner implements Spawner {
|
||||
MobManager m_manager;
|
||||
PlayerManager m_players;
|
||||
int m_spawnIdx = 0;
|
||||
World m_world;
|
||||
|
||||
public GameSpawner(Arena arena, MobManager manager, PlayerManager players) {
|
||||
public GameSpawner(World world, Arena arena, MobManager manager, PlayerManager players) {
|
||||
m_world = world;
|
||||
m_arena = arena;
|
||||
m_manager = manager;
|
||||
m_players = players;
|
||||
@ -38,10 +42,12 @@ public class GameSpawner implements Spawner {
|
||||
|
||||
@Override
|
||||
public LivingEntity spawnMob(EntityType type) {
|
||||
Spawnpoint[] spawnpoints = m_arena.spawnpoints();
|
||||
Waypoint[] 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);
|
||||
Waypoint thisSpawner = spawnpoints[m_spawnIdx];
|
||||
Location loc = new Location(m_world, thisSpawner.getX(), thisSpawner.getY(), thisSpawner.getZ());
|
||||
Entity newMob = m_world.spawnEntity(loc, type);
|
||||
LivingEntity livingMob = (LivingEntity)newMob;
|
||||
livingMob.setRemoveWhenFarAway(false);
|
||||
m_manager.addEntity(livingMob);
|
||||
|
@ -3,8 +3,6 @@ package gg.malloc.defense.model;
|
||||
import org.bukkit.World;
|
||||
|
||||
public interface Arena {
|
||||
World getWorld();
|
||||
String name();
|
||||
Spawnpoint[] spawnpoints();
|
||||
Spawnpoint bombTarget();
|
||||
Waypoint[] spawnpoints();
|
||||
Waypoint bombTarget();
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
package gg.malloc.defense.model;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
||||
public interface Game {
|
||||
int getWaveCount();
|
||||
Wave getWave(int waveNumber);
|
||||
default void onMobDamaged(Entity entity) {}
|
||||
}
|
||||
|
@ -1,9 +0,0 @@
|
||||
package gg.malloc.defense.model;
|
||||
|
||||
import org.bukkit.Location;
|
||||
|
||||
public interface Spawnpoint {
|
||||
Location getLocation();
|
||||
String getName();
|
||||
String getID();
|
||||
}
|
8
src/main/java/gg/malloc/defense/model/Waypoint.java
Normal file
8
src/main/java/gg/malloc/defense/model/Waypoint.java
Normal file
@ -0,0 +1,8 @@
|
||||
package gg.malloc.defense.model;
|
||||
|
||||
public interface Waypoint {
|
||||
double getX();
|
||||
double getY();
|
||||
double getZ();
|
||||
String getName();
|
||||
}
|
16
src/main/resources/config.yml
Normal file
16
src/main/resources/config.yml
Normal file
@ -0,0 +1,16 @@
|
||||
maps:
|
||||
quarry:
|
||||
target:
|
||||
x: -20.0
|
||||
y: 80.0
|
||||
z: 31.0
|
||||
spawnpoints:
|
||||
- x: -15.0
|
||||
y: 80.0
|
||||
z: -46.0
|
||||
- x: -1.0
|
||||
y: 80.0
|
||||
z: -45.0
|
||||
- x: 12.0
|
||||
y: 81.0
|
||||
z: -42.0
|
@ -4,11 +4,17 @@ api-version: 1.18
|
||||
main: gg.malloc.defense.Plugin
|
||||
depend: []
|
||||
commands:
|
||||
ready:
|
||||
description: Mark yourself as ready for the next wave
|
||||
list:
|
||||
description: List games
|
||||
join:
|
||||
description: Join a game
|
||||
leave:
|
||||
description: Leave a game
|
||||
setstage:
|
||||
description: Sets a game stage
|
||||
addplayer:
|
||||
description: Adds a player to a game
|
||||
debuginfo:
|
||||
description: Unknowable powers
|
||||
ready:
|
||||
description: Mark yourself as ready for the next wave
|
||||
|
Loading…
Reference in New Issue
Block a user