From 66608e53d5e6d43878f5552fc3b686b2312e9624 Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Fri, 11 Aug 2023 16:52:19 +0200 Subject: [PATCH] Initial MVP --- src/de/steamwar/towerrun/Config.java | 88 ----------- src/de/steamwar/towerrun/TowerRun.java | 29 +++- src/de/steamwar/towerrun/config/Config.java | 54 +++++++ .../steamwar/towerrun/config/WorldConfig.java | 146 ++++++++++++++++++ .../towerrun/countdowns/EndCountdown.java | 57 +++++++ .../towerrun/countdowns/LobbyCountdown.java | 68 ++++++++ .../steamwar/towerrun/game/TowerRunGame.java | 98 ++++++++++++ .../towerrun/game/TowerRunPlayer.java | 49 ++++++ .../towerrun/listener/GlobalListener.java | 49 ++++++ .../towerrun/listener/IngameListener.java | 103 ++++++++++++ .../towerrun/listener/LobbyListener.java | 72 +++++++++ .../towerrun/listener/NotLobbyListener.java | 39 +++++ src/de/steamwar/towerrun/state/GameState.java | 53 +++++++ .../state/GameStateBukkitListener.java | 44 ++++++ .../towerrun/state/GameStateListener.java | 29 ++++ .../state/GameStateToggleListener.java | 47 ++++++ .../steamwar/towerrun/state/GameStates.java | 33 ++++ 17 files changed, 969 insertions(+), 89 deletions(-) delete mode 100644 src/de/steamwar/towerrun/Config.java create mode 100644 src/de/steamwar/towerrun/config/Config.java create mode 100644 src/de/steamwar/towerrun/config/WorldConfig.java create mode 100644 src/de/steamwar/towerrun/countdowns/EndCountdown.java create mode 100644 src/de/steamwar/towerrun/countdowns/LobbyCountdown.java create mode 100644 src/de/steamwar/towerrun/game/TowerRunGame.java create mode 100644 src/de/steamwar/towerrun/game/TowerRunPlayer.java create mode 100644 src/de/steamwar/towerrun/listener/GlobalListener.java create mode 100644 src/de/steamwar/towerrun/listener/IngameListener.java create mode 100644 src/de/steamwar/towerrun/listener/LobbyListener.java create mode 100644 src/de/steamwar/towerrun/listener/NotLobbyListener.java create mode 100644 src/de/steamwar/towerrun/state/GameState.java create mode 100644 src/de/steamwar/towerrun/state/GameStateBukkitListener.java create mode 100644 src/de/steamwar/towerrun/state/GameStateListener.java create mode 100644 src/de/steamwar/towerrun/state/GameStateToggleListener.java create mode 100644 src/de/steamwar/towerrun/state/GameStates.java diff --git a/src/de/steamwar/towerrun/Config.java b/src/de/steamwar/towerrun/Config.java deleted file mode 100644 index e822baa..0000000 --- a/src/de/steamwar/towerrun/Config.java +++ /dev/null @@ -1,88 +0,0 @@ -package de.steamwar.towerrun; - -import lombok.Getter; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.logging.Level; - -public class Config { - - private Config() { - } - - public static final World world = Bukkit.getWorlds().get(0); - - public static final int TOWER_MIN_X; - public static final int TOWER_FLOOR_Y; - public static final int TOWER_MIN_Z; - - public static final int TOWER_MIN_HEIGHT; - public static final int TOWER_MAX_HEIGHT; - - public static final List TOWER_GENERATORS = new ArrayList<>(); - - public static final List TOWER_DOORS = new ArrayList<>(); - - static { - File worldConfigFile = new File(world.getWorldFolder(), "config.yml"); - if (!worldConfigFile.exists()) { - Bukkit.getLogger().log(Level.SEVERE, "Weltconfig fehlt!"); - Bukkit.shutdown(); - } - FileConfiguration worldconfig = YamlConfiguration.loadConfiguration(worldConfigFile); - - ConfigurationSection tower = worldconfig.getConfigurationSection("tower"); - TOWER_MIN_X = tower.getInt("minX"); - TOWER_FLOOR_Y = tower.getInt("floorY"); - TOWER_MIN_Z = tower.getInt("minZ"); - - TOWER_MIN_HEIGHT = tower.getInt("minHeight"); - TOWER_MAX_HEIGHT = tower.getInt("maxHeight"); - - for (String key : tower.getConfigurationSection("generators").getKeys(false)) { - TOWER_GENERATORS.add(new Generator(tower.getConfigurationSection("generators." + key))); - } - - for (String key : tower.getConfigurationSection("doors").getKeys(false)) { - TOWER_DOORS.add(new Door(tower.getConfigurationSection("doors." + key))); - } - } - - @Getter - public static final class Generator { - public final int minX; - public final int maxX; - public final int minZ; - public final int maxZ; - public final Material type; - - private Generator(ConfigurationSection generator) { - minX = generator.getInt("minX"); - maxX = generator.getInt("maxX"); - minZ = generator.getInt("minZ"); - maxZ = generator.getInt("maxZ"); - type = Material.valueOf(generator.getString("type")); - } - } - - @Getter - public static final class Door { - public final int x; - public final int offsetY; - public final int z; - - private Door(ConfigurationSection door) { - x = door.getInt("x"); - offsetY = door.getInt("offsetY"); - z = door.getInt("z"); - } - } -} diff --git a/src/de/steamwar/towerrun/TowerRun.java b/src/de/steamwar/towerrun/TowerRun.java index 69ed0db..9f93eb9 100644 --- a/src/de/steamwar/towerrun/TowerRun.java +++ b/src/de/steamwar/towerrun/TowerRun.java @@ -19,17 +19,44 @@ package de.steamwar.towerrun; +import de.steamwar.message.Message; +import de.steamwar.towerrun.countdowns.EndCountdown; +import de.steamwar.towerrun.countdowns.LobbyCountdown; +import de.steamwar.towerrun.listener.GlobalListener; +import de.steamwar.towerrun.listener.IngameListener; +import de.steamwar.towerrun.listener.LobbyListener; +import de.steamwar.towerrun.listener.NotLobbyListener; +import lombok.Getter; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.annotation.dependency.Dependency; import org.bukkit.plugin.java.annotation.plugin.Description; import org.bukkit.plugin.java.annotation.plugin.Plugin; import org.bukkit.plugin.java.annotation.plugin.author.Author; -@Plugin(name = "TowerRun", version = "1.0") +@Plugin(name = "TowerRun", version = "0.0.1") @Dependency(value = "SpigotCore") @Dependency(value = "WorldEdit") @Author(value = "YoyoNow") @Author(value = "Chaoscaot") @Description(value = "SteamWar TowerRun Plugin") public class TowerRun extends JavaPlugin { + + @Getter + private static TowerRun instance; + @Getter + private static Message message; + + @Override + public void onEnable() { + instance = this; + message = new Message("TowerRun", getClassLoader()); + + new LobbyListener(); + new IngameListener(); + new GlobalListener(); + new LobbyListener(); + new NotLobbyListener(); + new LobbyCountdown(); + new EndCountdown(); + } } diff --git a/src/de/steamwar/towerrun/config/Config.java b/src/de/steamwar/towerrun/config/Config.java new file mode 100644 index 0000000..bbd3138 --- /dev/null +++ b/src/de/steamwar/towerrun/config/Config.java @@ -0,0 +1,54 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.towerrun.config; + +import de.steamwar.towerrun.TowerRun; +import lombok.experimental.UtilityClass; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; +import java.util.EnumSet; +import java.util.Set; +import java.util.stream.Collectors; + +@UtilityClass +public class Config { + public static final int MIN_PLAYERS; + public static final int LOBBY_TIMER; + public static final Set DESTROYABLE_BLOCKS; + + static { + File configFile = new File(TowerRun.getInstance().getDataFolder(), "config.yml"); + if (!configFile.exists()) { + TowerRun.getInstance().getLogger().severe("Config not found!"); + Bukkit.shutdown(); + } + + ConfigurationSection config = YamlConfiguration.loadConfiguration(configFile); + + MIN_PLAYERS = config.getInt("minPlayers"); + LOBBY_TIMER = config.getInt("lobbyTimer"); + DESTROYABLE_BLOCKS = EnumSet.copyOf(config.getStringList("destroyable").stream().map(Material::valueOf).collect(Collectors.toSet())); + } + +} diff --git a/src/de/steamwar/towerrun/config/WorldConfig.java b/src/de/steamwar/towerrun/config/WorldConfig.java new file mode 100644 index 0000000..9372cb5 --- /dev/null +++ b/src/de/steamwar/towerrun/config/WorldConfig.java @@ -0,0 +1,146 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.towerrun.config; + +import de.steamwar.towerrun.TowerRun; +import lombok.Getter; +import lombok.experimental.UtilityClass; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.util.Vector; + +import java.io.File; +import java.util.List; +import java.util.Map; + +@UtilityClass +public class WorldConfig { + + public static final Region[] REGIONS; + public static final Location[] DOORS; + public static final int LAVA_Y; + public static final Location SPAWN; + public static final int ESCAPE_HEIGHT; + public static final Location MIN_TOWER; + public static final Location MAX_TOWER; + + private static Location parseLocation(ConfigurationSection section) { + Location loc = new Location( + Bukkit.getWorlds().get(0), + section.getDouble("x"), + section.getDouble("y"), + section.getDouble("z") + ); + if (section.contains("yaw")) { + loc.setYaw((float) section.getDouble("yaw")); + } + if (section.contains("pitch")) { + loc.setPitch((float) section.getDouble("pitch")); + } + return loc; + } + + static { + File configFile = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "config.yml"); + if (!configFile.exists()) { + TowerRun.getInstance().getLogger().severe("World config not found!"); + Bukkit.shutdown(); + } + + ConfigurationSection config = YamlConfiguration.loadConfiguration(configFile); + System.out.println(configFile.getAbsolutePath()); + System.out.println(config.getKeys(false)); + ConfigurationSection tower = config.getConfigurationSection("tower"); + + List regions = tower.getConfigurationSection("regions").getKeys(false).stream() + .map(tower.getConfigurationSection("regions")::getConfigurationSection) + .toList(); + REGIONS = new Region[regions.size()]; + for (int i = 0; i < regions.size(); i++) { + REGIONS[i] = new Region(regions.get(i)); + } + + if (REGIONS.length == 1) { + MIN_TOWER = REGIONS[0].min; + MAX_TOWER = REGIONS[0].max; + } else { + MIN_TOWER = new Location( + Bukkit.getWorlds().get(0), + Math.min(REGIONS[0].min.getX(), REGIONS[1].min.getX()), + 0, + Math.min(REGIONS[0].min.getZ(), REGIONS[1].min.getZ()) + ); + MAX_TOWER = new Location( + Bukkit.getWorlds().get(0), + Math.max(REGIONS[0].max.getX(), REGIONS[1].max.getX()), + 255, + Math.max(REGIONS[0].max.getZ(), REGIONS[1].max.getZ()) + ); + if (REGIONS.length > 2) { + for (int i = 2; i < REGIONS.length; i++) { + MIN_TOWER.setX(Math.min(MIN_TOWER.getX(), REGIONS[i].min.getX())); + MIN_TOWER.setZ(Math.min(MIN_TOWER.getZ(), REGIONS[i].min.getZ())); + MAX_TOWER.setX(Math.max(MAX_TOWER.getX(), REGIONS[i].max.getX())); + MAX_TOWER.setZ(Math.max(MAX_TOWER.getZ(), REGIONS[i].max.getZ())); + } + } + } + + ESCAPE_HEIGHT = tower.getInt("escapeHeight"); + SPAWN = parseLocation(tower.getConfigurationSection("spawn")); + List doors = tower.getConfigurationSection("doors").getKeys(false).stream() + .map(tower.getConfigurationSection("doors")::getConfigurationSection) + .toList(); + DOORS = new Location[doors.size()]; + for (int i = 0; i < doors.size(); i++) { + DOORS[i] = parseLocation(doors.get(i)); + } + + LAVA_Y = tower.getInt("lavaY"); + } + + @Getter + public static final class Region { + public final Location min; + public final Location max; + + public Region(ConfigurationSection section) { + min = new Location( + Bukkit.getWorlds().get(0), + section.getDouble("minX"), + 0, + section.getDouble("minZ") + ); + max = new Location( + Bukkit.getWorlds().get(0), + section.getDouble("maxX"), + 255, + section.getDouble("maxZ") + ); + } + + public boolean contains(Vector vector) { + return vector.getX() >= min.getX() && vector.getX() <= max.getX() + && vector.getZ() >= min.getZ() && vector.getZ() <= max.getZ(); + } + } +} diff --git a/src/de/steamwar/towerrun/countdowns/EndCountdown.java b/src/de/steamwar/towerrun/countdowns/EndCountdown.java new file mode 100644 index 0000000..653f8ac --- /dev/null +++ b/src/de/steamwar/towerrun/countdowns/EndCountdown.java @@ -0,0 +1,57 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.towerrun.countdowns; + +import de.steamwar.towerrun.TowerRun; +import de.steamwar.towerrun.state.GameStateToggleListener; +import de.steamwar.towerrun.state.GameStates; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.Bukkit; +import org.bukkit.scheduler.BukkitTask; + +import java.util.EnumSet; + +public class EndCountdown extends GameStateToggleListener { + + private BukkitTask task; + private int time = 10; + public EndCountdown() { + super(EnumSet.of(GameStates.ENDING)); + } + + private void timer() { + if (time == 0) { + Bukkit.shutdown(); + } + Bukkit.getOnlinePlayers().forEach(player -> player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText("§cServer wird in " + time + " Sekunden heruntergefahren..."))); + time--; + } + + @Override + public void enable() { + task = Bukkit.getScheduler().runTaskTimer(TowerRun.getInstance(), this::timer, 0, 20); + } + + @Override + public void disable() { + task.cancel(); + } +} diff --git a/src/de/steamwar/towerrun/countdowns/LobbyCountdown.java b/src/de/steamwar/towerrun/countdowns/LobbyCountdown.java new file mode 100644 index 0000000..d0e7b21 --- /dev/null +++ b/src/de/steamwar/towerrun/countdowns/LobbyCountdown.java @@ -0,0 +1,68 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.towerrun.countdowns; + +import de.steamwar.towerrun.TowerRun; +import de.steamwar.towerrun.config.Config; +import de.steamwar.towerrun.game.TowerRunGame; +import de.steamwar.towerrun.state.GameStateToggleListener; +import de.steamwar.towerrun.state.GameStates; +import net.md_5.bungee.api.ChatMessageType; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.Bukkit; +import org.bukkit.scheduler.BukkitTask; + +import java.util.EnumSet; + +public class LobbyCountdown extends GameStateToggleListener { + + private BukkitTask task; + private int timer = Config.LOBBY_TIMER; + + public LobbyCountdown() { + super(EnumSet.of(GameStates.LOBBY)); + } + + private void timer() { + if (Bukkit.getOnlinePlayers().size() >= Config.MIN_PLAYERS) { + Bukkit.getOnlinePlayers().forEach(player -> player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText("§aStartet: " + timer))); + timer--; + if (timer < 10) { + Bukkit.getOnlinePlayers().forEach(player -> player.playSound(player.getLocation(), "note.pling", 1, 1)); + } + if (timer == 0) { + TowerRunGame.start(); + } + } else { + timer = Config.LOBBY_TIMER; + Bukkit.getOnlinePlayers().forEach(player -> player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText("§cEs wird noch auf Spieler gewartet..."))); + } + } + + @Override + public void enable() { + task = Bukkit.getScheduler().runTaskTimer(TowerRun.getInstance(), this::timer, 0, 20); + } + + @Override + public void disable() { + task.cancel(); + } +} diff --git a/src/de/steamwar/towerrun/game/TowerRunGame.java b/src/de/steamwar/towerrun/game/TowerRunGame.java new file mode 100644 index 0000000..96df21f --- /dev/null +++ b/src/de/steamwar/towerrun/game/TowerRunGame.java @@ -0,0 +1,98 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.towerrun.game; + +import de.steamwar.towerrun.config.WorldConfig; +import de.steamwar.towerrun.state.GameState; +import de.steamwar.towerrun.state.GameStates; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; + +import java.util.ArrayList; +import java.util.List; + +public class TowerRunGame { + private static final List playersAlive = new ArrayList<>(); + private static final List playersEscaped = new ArrayList<>(); + + public static boolean isAlive(TowerRunPlayer player) { + return playersAlive.contains(player); + } + + public static void start() { + if (GameState.getCurrentState() == GameStates.LOBBY) { + playersAlive.addAll(TowerRunPlayer.getAll()); + playersAlive.forEach(TowerRunPlayer::reset); + GameState.nextState(); + generateLava(); + Bukkit.broadcastMessage("§aDas Spiel beginnt!"); + + for (Location door : WorldConfig.DOORS) { + door.getBlock().setType(Material.AIR); + door.add(0, 1, 0).getBlock().setType(Material.AIR); + } + } else { + throw new IllegalStateException("Game is already running!"); + } + } + + private static void generateLava() { + for (int x = WorldConfig.MIN_TOWER.getBlockX(); x < WorldConfig.MAX_TOWER.getBlockX(); x += 7) { + for (int z = WorldConfig.MIN_TOWER.getBlockZ(); z < WorldConfig.MAX_TOWER.getBlockZ(); z += 7) { + WorldConfig.MIN_TOWER.getWorld().getBlockAt(x, WorldConfig.LAVA_Y, z).setType(Material.LAVA, true); + WorldConfig.MIN_TOWER.getWorld().getBlockAt(x, WorldConfig.LAVA_Y - 1, z).setType(Material.BEDROCK, true); + } + } + } + + public static void remove(TowerRunPlayer towerRunPlayer) { + death(towerRunPlayer); + } + + public static void win(TowerRunPlayer tPlayer) { + Bukkit.getOnlinePlayers().forEach(player -> player.setGameMode(GameMode.SPECTATOR)); + playersAlive.clear(); + tPlayer.player().teleport(WorldConfig.SPAWN); + tPlayer.player().setGameMode(GameMode.SPECTATOR); + Bukkit.broadcastMessage("§a" + tPlayer.player().getName() + " hat das Spiel gewonnen!"); + GameState.nextState(); + } + + public static void death(TowerRunPlayer tPlayer) { + playersAlive.remove(tPlayer); + tPlayer.player().teleport(WorldConfig.SPAWN); + tPlayer.player().setGameMode(GameMode.SPECTATOR); + if(playersAlive.size() == 1 && playersEscaped.isEmpty()) { + win(playersAlive.get(0)); + } else if(playersAlive.isEmpty() && !playersEscaped.isEmpty()) { + win(playersEscaped.get(playersEscaped.size() -1)); + } + } + + public static void escape(TowerRunPlayer towerRunPlayer) { + playersEscaped.add(towerRunPlayer); + playersAlive.remove(towerRunPlayer); + if (playersAlive.isEmpty()) { + win(towerRunPlayer); + } + } +} diff --git a/src/de/steamwar/towerrun/game/TowerRunPlayer.java b/src/de/steamwar/towerrun/game/TowerRunPlayer.java new file mode 100644 index 0000000..87347d8 --- /dev/null +++ b/src/de/steamwar/towerrun/game/TowerRunPlayer.java @@ -0,0 +1,49 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.towerrun.game; + +import de.steamwar.towerrun.config.WorldConfig; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +public record TowerRunPlayer(Player player) { + private static final Map players = new HashMap<>(); + + public static TowerRunPlayer get(Player player) { + return players.computeIfAbsent(player, TowerRunPlayer::new); + } + + public static void remove(Player player) { + players.remove(player); + } + + public static Collection getAll() { + return players.values(); + } + + public void reset() { + player.teleport(WorldConfig.SPAWN); + player.setVelocity(new Vector(0, 0, 0)); + } +} diff --git a/src/de/steamwar/towerrun/listener/GlobalListener.java b/src/de/steamwar/towerrun/listener/GlobalListener.java new file mode 100644 index 0000000..edf0dba --- /dev/null +++ b/src/de/steamwar/towerrun/listener/GlobalListener.java @@ -0,0 +1,49 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.towerrun.listener; + +import de.steamwar.towerrun.game.TowerRunGame; +import de.steamwar.towerrun.game.TowerRunPlayer; +import de.steamwar.towerrun.state.GameStateBukkitListener; +import de.steamwar.towerrun.state.GameStates; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +import java.util.EnumSet; + +public class GlobalListener extends GameStateBukkitListener { + public GlobalListener() { + super(EnumSet.allOf(GameStates.class)); + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + TowerRunPlayer.get(event.getPlayer()); + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + if (TowerRunGame.isAlive(TowerRunPlayer.get(event.getPlayer()))) { + TowerRunGame.remove(TowerRunPlayer.get(event.getPlayer())); + } + TowerRunPlayer.remove(event.getPlayer()); + } +} diff --git a/src/de/steamwar/towerrun/listener/IngameListener.java b/src/de/steamwar/towerrun/listener/IngameListener.java new file mode 100644 index 0000000..6871b49 --- /dev/null +++ b/src/de/steamwar/towerrun/listener/IngameListener.java @@ -0,0 +1,103 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.towerrun.listener; + +import de.steamwar.towerrun.config.Config; +import de.steamwar.towerrun.config.WorldConfig; +import de.steamwar.towerrun.game.TowerRunGame; +import de.steamwar.towerrun.game.TowerRunPlayer; +import de.steamwar.towerrun.state.GameStateBukkitListener; +import de.steamwar.towerrun.state.GameStates; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.EntityType; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.ItemSpawnEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerMoveEvent; + +import java.util.Arrays; +import java.util.EnumSet; + +public class IngameListener extends GameStateBukkitListener { + public IngameListener() { + super(EnumSet.of(GameStates.INGAME)); + } + + @EventHandler + public void onPlayerDeath(PlayerDeathEvent event) { + event.setDeathMessage(null); + Bukkit.getOnlinePlayers().forEach(player -> { + player.sendTitle("§c" + event.getEntity().getName() + " ist gestorben!", "", 10, 70, 20); + player.playSound(player.getLocation(), Sound.ENTITY_WITHER_DEATH, 1, 1); + }); + TowerRunPlayer tPlayer = TowerRunPlayer.get(event.getEntity()); + if (TowerRunGame.isAlive(tPlayer)) { + TowerRunGame.death(tPlayer); + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void onPlayerMove(PlayerMoveEvent event) { + if (event.getTo().getY() < WorldConfig.ESCAPE_HEIGHT && TowerRunGame.isAlive(TowerRunPlayer.get(event.getPlayer()))) { + if (Arrays.stream(WorldConfig.REGIONS).noneMatch(region -> region.contains(event.getTo().toVector())) && event.getPlayer().getLocation().add(0, -0.1, 0).getBlock().getType() != Material.AIR) { + TowerRunGame.escape(TowerRunPlayer.get(event.getPlayer())); + } + } + } + + @EventHandler + public void onBlockBreak(BlockBreakEvent event) { + event.setDropItems(false); + if (!Config.DESTROYABLE_BLOCKS.contains(event.getBlock().getType())) { + event.setCancelled(true); + } + } + + @EventHandler + public void onBlockPlace(BlockPlaceEvent event) { + if (event.getBlockPlaced().getType() == Material.LEVER) { + event.setCancelled(true); + if (event.getBlockAgainst().getType() == Material.IRON_DOOR) { + event.getBlockPlaced().breakNaturally(); + event.getBlockAgainst().breakNaturally(); + event.getItemInHand().setType(Material.AIR); + } + } + } + + @EventHandler + public void onItemSpawn(ItemSpawnEvent event) { + event.setCancelled(true); + } + + @EventHandler + public void onEntityDamageByEntity(EntityDamageByEntityEvent event) { + if(event.getDamager().getType() == EntityType.PLAYER) { + event.setCancelled(true); + } + } +} diff --git a/src/de/steamwar/towerrun/listener/LobbyListener.java b/src/de/steamwar/towerrun/listener/LobbyListener.java new file mode 100644 index 0000000..470b198 --- /dev/null +++ b/src/de/steamwar/towerrun/listener/LobbyListener.java @@ -0,0 +1,72 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.towerrun.listener; + +import de.steamwar.towerrun.config.WorldConfig; +import de.steamwar.towerrun.state.GameStateBukkitListener; +import de.steamwar.towerrun.state.GameStates; +import org.bukkit.GameMode; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerMoveEvent; + +import java.util.EnumSet; + +public class LobbyListener extends GameStateBukkitListener { + public LobbyListener() { + super(EnumSet.of(GameStates.LOBBY)); + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + Player player = event.getPlayer(); + player.teleport(WorldConfig.SPAWN); + player.setGameMode(GameMode.SURVIVAL); + } + + @EventHandler + public void onPlayerMove(PlayerMoveEvent event) { + if(event.getTo().getY() < WorldConfig.SPAWN.getY() - 10) { + event.getPlayer().teleport(WorldConfig.SPAWN); + } + } + + @EventHandler + public void onPlayerInteract(PlayerInteractEvent event) { + event.setCancelled(true); + } + + @EventHandler + public void onBlockBreak(BlockBreakEvent event) { + event.setCancelled(true); + } + + @EventHandler + public void onEntityDamage(EntityDamageEvent event) { + if (event.getEntityType() == EntityType.PLAYER) { + event.setCancelled(true); + } + } +} diff --git a/src/de/steamwar/towerrun/listener/NotLobbyListener.java b/src/de/steamwar/towerrun/listener/NotLobbyListener.java new file mode 100644 index 0000000..ffd5b38 --- /dev/null +++ b/src/de/steamwar/towerrun/listener/NotLobbyListener.java @@ -0,0 +1,39 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.towerrun.listener; + +import de.steamwar.towerrun.state.GameStateBukkitListener; +import de.steamwar.towerrun.state.GameStates; +import org.bukkit.GameMode; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerJoinEvent; + +import java.util.EnumSet; + +public class NotLobbyListener extends GameStateBukkitListener { + public NotLobbyListener() { + super(EnumSet.complementOf(EnumSet.of(GameStates.LOBBY))); + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + event.getPlayer().setGameMode(GameMode.SPECTATOR); + } +} diff --git a/src/de/steamwar/towerrun/state/GameState.java b/src/de/steamwar/towerrun/state/GameState.java new file mode 100644 index 0000000..120b6a8 --- /dev/null +++ b/src/de/steamwar/towerrun/state/GameState.java @@ -0,0 +1,53 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.towerrun.state; + +import lombok.Getter; +import lombok.experimental.UtilityClass; + +import java.util.ArrayList; +import java.util.List; + +@UtilityClass +public class GameState { + @Getter + private static GameStates currentState = GameStates.LOBBY; + private static final List gameStateListeners = new ArrayList<>(); + + public static void addGameStateListener(GameStateListener gameStateListener) { + gameStateListeners.add(gameStateListener); + } + + public static void nextState() { + final GameStates oldState = currentState; + currentState = currentState.getNextState(); + gameStateChanges(oldState, currentState); + } + + static void setState(final GameStates newState) { + final GameStates oldState = currentState; + currentState = newState; + gameStateChanges(oldState, currentState); + } + + private static void gameStateChanges(GameStates oldState, GameStates newState) { + gameStateListeners.forEach(gameStateListener -> gameStateListener.onGameStateChange(oldState, newState)); + } +} diff --git a/src/de/steamwar/towerrun/state/GameStateBukkitListener.java b/src/de/steamwar/towerrun/state/GameStateBukkitListener.java new file mode 100644 index 0000000..bd259f6 --- /dev/null +++ b/src/de/steamwar/towerrun/state/GameStateBukkitListener.java @@ -0,0 +1,44 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.towerrun.state; + +import de.steamwar.towerrun.TowerRun; +import org.bukkit.Bukkit; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; + +import java.util.EnumSet; + +public abstract class GameStateBukkitListener extends GameStateToggleListener implements Listener { + + protected GameStateBukkitListener(EnumSet enabledStates) { + super(enabledStates); + } + + @Override + public void enable() { + Bukkit.getPluginManager().registerEvents(this, TowerRun.getInstance()); + } + + @Override + public void disable() { + HandlerList.unregisterAll(this); + } +} diff --git a/src/de/steamwar/towerrun/state/GameStateListener.java b/src/de/steamwar/towerrun/state/GameStateListener.java new file mode 100644 index 0000000..d4dcd63 --- /dev/null +++ b/src/de/steamwar/towerrun/state/GameStateListener.java @@ -0,0 +1,29 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.towerrun.state; + +public abstract class GameStateListener { + + protected GameStateListener() { + GameState.addGameStateListener(this); + } + + public abstract void onGameStateChange(GameStates oldState, GameStates newState); +} diff --git a/src/de/steamwar/towerrun/state/GameStateToggleListener.java b/src/de/steamwar/towerrun/state/GameStateToggleListener.java new file mode 100644 index 0000000..85aa0f1 --- /dev/null +++ b/src/de/steamwar/towerrun/state/GameStateToggleListener.java @@ -0,0 +1,47 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.towerrun.state; + +import java.util.EnumSet; + +public abstract class GameStateToggleListener extends GameStateListener { + + private final EnumSet enabledStates; + + protected GameStateToggleListener(EnumSet enabledStates) { + super(); + this.enabledStates = enabledStates; + if(enabledStates.contains(GameState.getCurrentState())) { + enable(); + } + } + + public abstract void enable(); + public abstract void disable(); + + @Override + public void onGameStateChange(GameStates oldState, GameStates newState) { + if (enabledStates.contains(newState) && !enabledStates.contains(oldState)) { + enable(); + } else if (!enabledStates.contains(newState) && enabledStates.contains(oldState)) { + disable(); + } + } +} diff --git a/src/de/steamwar/towerrun/state/GameStates.java b/src/de/steamwar/towerrun/state/GameStates.java new file mode 100644 index 0000000..3c838a3 --- /dev/null +++ b/src/de/steamwar/towerrun/state/GameStates.java @@ -0,0 +1,33 @@ +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2023 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package de.steamwar.towerrun.state; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public enum GameStates { + ENDING(null), + INGAME(ENDING), + LOBBY(INGAME); + + private final GameStates nextState; +}