diff --git a/src/de/steamwar/towerrun/config/WorldConfig.java b/src/de/steamwar/towerrun/config/WorldConfig.java index 9372cb5..3c71f4f 100644 --- a/src/de/steamwar/towerrun/config/WorldConfig.java +++ b/src/de/steamwar/towerrun/config/WorldConfig.java @@ -20,6 +20,7 @@ package de.steamwar.towerrun.config; import de.steamwar.towerrun.TowerRun; +import de.steamwar.towerrun.winconditions.WinCondition; import lombok.Getter; import lombok.experimental.UtilityClass; import org.bukkit.Bukkit; @@ -29,6 +30,7 @@ import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.util.Vector; import java.io.File; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -42,6 +44,7 @@ public class WorldConfig { public static final int ESCAPE_HEIGHT; public static final Location MIN_TOWER; public static final Location MAX_TOWER; + public static final List ACTIVE_WINCONDITIONS; private static Location parseLocation(ConfigurationSection section) { Location loc = new Location( @@ -116,6 +119,8 @@ public class WorldConfig { } LAVA_Y = tower.getInt("lavaY"); + ACTIVE_WINCONDITIONS = tower.getStringList("winconditions"); + WinCondition.WINCONDITIONS.stream().filter(winCondition -> ACTIVE_WINCONDITIONS.contains(winCondition.getName())).forEach(WinCondition::enable); } @Getter diff --git a/src/de/steamwar/towerrun/game/TowerRunGame.java b/src/de/steamwar/towerrun/game/TowerRunGame.java index 96df21f..572c168 100644 --- a/src/de/steamwar/towerrun/game/TowerRunGame.java +++ b/src/de/steamwar/towerrun/game/TowerRunGame.java @@ -26,22 +26,24 @@ import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.util.Vector; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; public class TowerRunGame { - private static final List playersAlive = new ArrayList<>(); - private static final List playersEscaped = new ArrayList<>(); + public static final List PLAYERS_ALIVE = new ArrayList<>(); + public static final List PLAYERS_ESCAPED = new ArrayList<>(); public static boolean isAlive(TowerRunPlayer player) { - return playersAlive.contains(player); + return PLAYERS_ALIVE.contains(player); } public static void start() { if (GameState.getCurrentState() == GameStates.LOBBY) { - playersAlive.addAll(TowerRunPlayer.getAll()); - playersAlive.forEach(TowerRunPlayer::reset); + PLAYERS_ALIVE.addAll(TowerRunPlayer.getAll()); + PLAYERS_ALIVE.forEach(TowerRunPlayer::reset); GameState.nextState(); generateLava(); Bukkit.broadcastMessage("§aDas Spiel beginnt!"); @@ -58,41 +60,26 @@ public class TowerRunGame { 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); + Vector pos = new Vector(x, 0, z); + if (Arrays.stream(WorldConfig.REGIONS).anyMatch(region -> region.contains(pos))) { + 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); + PLAYERS_ALIVE.remove(towerRunPlayer); + PLAYERS_ESCAPED.remove(towerRunPlayer); } public static void win(TowerRunPlayer tPlayer) { Bukkit.getOnlinePlayers().forEach(player -> player.setGameMode(GameMode.SPECTATOR)); - playersAlive.clear(); + PLAYERS_ALIVE.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/listener/IngameListener.java b/src/de/steamwar/towerrun/listener/IngameListener.java index 6871b49..94a4d5e 100644 --- a/src/de/steamwar/towerrun/listener/IngameListener.java +++ b/src/de/steamwar/towerrun/listener/IngameListener.java @@ -20,9 +20,6 @@ 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; @@ -30,16 +27,12 @@ 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 { @@ -54,19 +47,6 @@ public class IngameListener extends GameStateBukkitListener { 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 diff --git a/src/de/steamwar/towerrun/winconditions/FirstOutsideWincondition.java b/src/de/steamwar/towerrun/winconditions/FirstOutsideWincondition.java new file mode 100644 index 0000000..f2d753f --- /dev/null +++ b/src/de/steamwar/towerrun/winconditions/FirstOutsideWincondition.java @@ -0,0 +1,35 @@ +/* + * 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.winconditions; + +import de.steamwar.towerrun.game.TowerRunGame; +import de.steamwar.towerrun.game.TowerRunPlayer; +import org.bukkit.entity.Player; + +public class FirstOutsideWincondition extends OutsideWincondition { + public FirstOutsideWincondition() { + super("FIRST_OUTSIDE"); + } + + @Override + public void onPlayerOutside(Player player) { + TowerRunGame.win(TowerRunPlayer.get(player)); + } +} diff --git a/src/de/steamwar/towerrun/winconditions/LastOutsideWincondition.java b/src/de/steamwar/towerrun/winconditions/LastOutsideWincondition.java new file mode 100644 index 0000000..71e7a4d --- /dev/null +++ b/src/de/steamwar/towerrun/winconditions/LastOutsideWincondition.java @@ -0,0 +1,48 @@ +/* + * 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.winconditions; + +import de.steamwar.towerrun.game.TowerRunGame; +import de.steamwar.towerrun.game.TowerRunPlayer; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.PlayerDeathEvent; + +public class LastOutsideWincondition extends OutsideWincondition{ + public LastOutsideWincondition() { + super("LAST_OUTSIDE"); + } + + @Override + public void onPlayerOutside(Player player) { + TowerRunPlayer towerRunPlayer = TowerRunPlayer.get(player); + outside(towerRunPlayer); + if (TowerRunGame.PLAYERS_ALIVE.isEmpty()) { + TowerRunGame.win(towerRunPlayer); + } + } + + @EventHandler + public void onPlayerDeath(PlayerDeathEvent event) { + if(TowerRunGame.PLAYERS_ALIVE.isEmpty()) { + TowerRunGame.win(TowerRunGame.PLAYERS_ESCAPED.get(TowerRunGame.PLAYERS_ESCAPED.size() - 1)); + } + } +} diff --git a/src/de/steamwar/towerrun/winconditions/LastRemainingWincondition.java b/src/de/steamwar/towerrun/winconditions/LastRemainingWincondition.java new file mode 100644 index 0000000..9957b95 --- /dev/null +++ b/src/de/steamwar/towerrun/winconditions/LastRemainingWincondition.java @@ -0,0 +1,45 @@ +/* + * 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.winconditions; + +import de.steamwar.towerrun.config.WorldConfig; +import de.steamwar.towerrun.game.TowerRunGame; +import de.steamwar.towerrun.game.TowerRunPlayer; +import org.bukkit.GameMode; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.PlayerDeathEvent; + +public class LastRemainingWincondition extends WinCondition { + + public LastRemainingWincondition() { + super("LAST_REMAINING"); + } + + @EventHandler + public void onPlayerDeath(PlayerDeathEvent event) { + TowerRunPlayer tPlayer = TowerRunPlayer.get(event.getEntity()); + TowerRunGame.PLAYERS_ALIVE.remove(tPlayer); + tPlayer.player().teleport(WorldConfig.SPAWN); + tPlayer.player().setGameMode(GameMode.SPECTATOR); + if (TowerRunGame.PLAYERS_ALIVE.size() == 1 && TowerRunGame.PLAYERS_ESCAPED.isEmpty()) { + TowerRunGame.win(TowerRunGame.PLAYERS_ALIVE.get(0)); + } + } +} diff --git a/src/de/steamwar/towerrun/winconditions/OutsideWincondition.java b/src/de/steamwar/towerrun/winconditions/OutsideWincondition.java new file mode 100644 index 0000000..9f105d2 --- /dev/null +++ b/src/de/steamwar/towerrun/winconditions/OutsideWincondition.java @@ -0,0 +1,65 @@ +/* + * 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.winconditions; + +import de.steamwar.towerrun.config.WorldConfig; +import de.steamwar.towerrun.game.TowerRunGame; +import de.steamwar.towerrun.game.TowerRunPlayer; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerMoveEvent; + +import java.util.Arrays; + +public abstract class OutsideWincondition extends WinCondition { + + protected OutsideWincondition(String name) { + super(name); + } + + public abstract void onPlayerOutside(Player player); + + @EventHandler + public void onPlayerMove(PlayerMoveEvent event) { + if (event.getTo().getY() > WorldConfig.ESCAPE_HEIGHT) { + return; + } + TowerRunPlayer tPlayer = TowerRunPlayer.get(event.getPlayer()); + if (!TowerRunGame.isAlive(tPlayer)) { + return; + } + + if (Arrays.stream(WorldConfig.REGIONS).anyMatch(region -> region.contains(event.getTo().toVector()))) { + return; + } + + if (event.getPlayer().getLocation().add(0, -0.1, 0).getBlock().getType() == Material.AIR) { + return; + } + + onPlayerOutside(event.getPlayer()); + } + + protected void outside(TowerRunPlayer towerRunPlayer) { + TowerRunGame.PLAYERS_ESCAPED.add(towerRunPlayer); + TowerRunGame.PLAYERS_ALIVE.remove(towerRunPlayer); + } +} diff --git a/src/de/steamwar/towerrun/winconditions/WinCondition.java b/src/de/steamwar/towerrun/winconditions/WinCondition.java new file mode 100644 index 0000000..aceca1d --- /dev/null +++ b/src/de/steamwar/towerrun/winconditions/WinCondition.java @@ -0,0 +1,61 @@ +/* + * 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.winconditions; + +import de.steamwar.towerrun.state.GameStateBukkitListener; +import de.steamwar.towerrun.state.GameStates; +import lombok.Getter; +import lombok.Setter; + +import java.util.*; + +@Getter +public abstract class WinCondition extends GameStateBukkitListener { + + public static final List WINCONDITIONS = new ArrayList<>(); + static { + WINCONDITIONS.add(new LastRemainingWincondition()); + WINCONDITIONS.add(new LastOutsideWincondition()); + WINCONDITIONS.add(new FirstOutsideWincondition()); + } + + private final String name; + @Setter + private boolean active = false; + + protected WinCondition(String name) { + super(EnumSet.of(GameStates.INGAME)); + this.name = name; + } + + @Override + public void enable() { + if (active) { + super.enable(); + } + } + + @Override + public void disable() { + if (active) { + super.disable(); + } + } +}