Merge pull request 'tower-generator' (#6) from tower-generator into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful

Reviewed-on: #6
Dieser Commit ist enthalten in:
YoyoNow 2023-09-23 21:29:05 +02:00
Commit 52d2da88dd
19 geänderte Dateien mit 728 neuen und 59 gelöschten Zeilen

Datei anzeigen

@ -15,11 +15,11 @@ tower:
doors: doors:
1: 1:
x: 138 x: 138
y: 229 y: 228
z: 858 z: 858
2: 2:
x: 137 x: 137
y: 229 y: 228
z: 858 z: 858
lavaY: 255 lavaY: 255
laveSpace: 7 laveSpace: 7
@ -32,7 +32,7 @@ tower:
minX: 93 minX: 93
maxX: 167 maxX: 167
minZ: 813 minZ: 813
maxZ: 863 maxZ: 883
winconditions: winconditions:
- LAST_REMAINING - LAST_REMAINING

154
configs/steamtower.yml Normale Datei
Datei anzeigen

@ -0,0 +1,154 @@
tower:
regions:
1:
minX: 0
maxX: 69
minZ: 0
maxZ: 79
2:
minX: 54
maxX: 74
minZ: 63
maxZ: 84
escapeHeight: 1
spawn:
x: 66
y: 12
z: 71
yaw: 180.0
pitch: 0.0
doors: []
keys: []
lavaY: 62
laveSpace: 8
meltingBlocks:
SPRUCE_TRAPDOOR: 10
SMOOTH_STONE: 120
SMOOTH_STONE_SLAB: 60
STONE_BRICK_SLAB: 60
ANDESITE: 120
ANDESITE_SLAB: 60
ANDESITE_WALL: 45
JUKEBOX: 10
IRON_BLOCK: 240
IRON_DOOR: 60
IRON_TRAPDOOR: 60
QUARTZ_SLAB: 30
QUARTZ_STAIRS: 30
SMOOTH_RED_SANDSTONE_STAIRS: 30
SMOOTH_RED_SANDSTONE_SLAB: 30
END_STONE: 240
REDSTONE_LAMP: 30
GLASS: 30
GLASS_PANE: 3
TINTED_GLASS: 30
WHITE_STAINED_GLASS: 30
WHITE_STAINED_GLASS_PANE: 3
ORANGE_STAINED_GLASS: 30
ORANGE_STAINED_GLASS_PANE: 3
MAGENTA_STAINED_GLASS: 30
MAGENTA_STAINED_GLASS_PANE: 3
LIGHT_BLUE_STAINED_GLASS: 30
LIGHT_BLUE_STAINED_GLASS_PANE: 3
YELLOW_STAINED_GLASS: 30
YELLOW_STAINED_GLASS_PANE: 3
LIME_STAINED_GLASS: 30
LIME_STAINED_GLASS_PANE: 3
PINK_STAINED_GLASS: 30
PINK_STAINED_GLASS_PANE: 3
GRAY_STAINED_GLASS: 30
GRAY_STAINED_GLASS_PANE: 3
LIGHT_GRAY_STAINED_GLASS: 30
LIGHT_GRAY_STAINED_GLASS_PANE: 3
CYAN_STAINED_GLASS: 30
CYAN_STAINED_GLASS_PANE: 3
PURPLE_STAINED_GLASS: 30
PURPLE_STAINED_GLASS_PANE: 3
BLUE_STAINED_GLASS: 30
BLUE_STAINED_GLASS_PANE: 3
BROWN_STAINED_GLASS: 30
BROWN_STAINED_GLASS_PANE: 3
GREEN_STAINED_GLASS: 30
GREEN_STAINED_GLASS_PANE: 3
RED_STAINED_GLASS: 30
RED_STAINED_GLASS_PANE: 3
BLACK_STAINED_GLASS: 30
BLACK_STAINED_GLASS_PANE: 3
towerGenerator:
x: 0
y: 12
z: 0
minHeight: 190
maxHeight: 240
schematicType: steamtower
fillRegions:
1:
minX: 31
minZ: 29
maxX: 38
maxZ: 34
percentage: 0.25
material: MANGROVE_ROOTS
2:
minX: 31
minZ: 46
maxX: 38
maxZ: 51
percentage: 0.25
material: MANGROVE_ROOTS
minNoBombFloors: 2
maxNoBombFloors: 7
minBombs: 20
maxBombs: 60
tntChance: 0.3
tntRegions:
1:
minX: 3
minZ: 3
maxX: 30
maxZ: 77
2:
minX: 40
minZ: 3
maxX: 67
maxZ: 77
3:
minX: 30
minZ: 3
maxX: 40
maxZ: 28
4:
minX: 30
minZ: 52
maxX: 40
maxZ: 77
keyChance: 0.8
minNoKeyFloors: 2
maxNoKeyFloors: 7
doorBlocks:
1:
x: 36
dy: 1
z: 32
2:
x: 36
dy: 1
z: 33
3:
x: 33
dy: 1
z: 46
4:
x: 33
dy: 1
z: 47
minX: -28
maxX: 98
minZ: -27
maxZ: 107
winconditions:
- LAST_REMAINING
- LAST_OUTSIDE

Datei anzeigen

@ -31,5 +31,6 @@ KEY_NAME=
KEY_FOUND=§a{0} §7found a key§8! KEY_FOUND=§a{0} §7found a key§8!
GAME_TIE=§aThe game ended in a tie§8! GAME_TIE=§aThe game ended in a tie§8!
GAME_TIME=§a{0}:{1} GAME_TIME=§a{0}:{1}
CATCH_UP_WARNING=§4!! §cYou should catch up §4!!
COMMAND_START=§aThe game will start soon§8! COMMAND_START=§aThe game will start soon§8!

Datei anzeigen

@ -30,4 +30,6 @@ GAME_TIE=
KEY_NAME=§eSchlüssel KEY_NAME=§eSchlüssel
KEY_FOUND=§a{0} §7hat einen Schlüssel gefunden§8! KEY_FOUND=§a{0} §7hat einen Schlüssel gefunden§8!
CATCH_UP_WARNING=§4!! §cDu solltest aufholen §4!!
COMMAND_START=§7Das Spiel startet bald§8! COMMAND_START=§7Das Spiel startet bald§8!

Datei anzeigen

@ -21,9 +21,12 @@ package de.steamwar.towerrun;
import de.steamwar.message.Message; import de.steamwar.message.Message;
import de.steamwar.towerrun.commands.StartCommand; import de.steamwar.towerrun.commands.StartCommand;
import de.steamwar.towerrun.config.WorldConfig;
import de.steamwar.towerrun.countdowns.EndCountdown; import de.steamwar.towerrun.countdowns.EndCountdown;
import de.steamwar.towerrun.countdowns.GameCountdown; import de.steamwar.towerrun.countdowns.GameCountdown;
import de.steamwar.towerrun.countdowns.LobbyCountdown; import de.steamwar.towerrun.countdowns.LobbyCountdown;
import de.steamwar.towerrun.game.TowerRunGame;
import de.steamwar.towerrun.generator.TowerGenerator;
import de.steamwar.towerrun.listener.GlobalListener; import de.steamwar.towerrun.listener.GlobalListener;
import de.steamwar.towerrun.listener.IngameListener; import de.steamwar.towerrun.listener.IngameListener;
import de.steamwar.towerrun.listener.LobbyListener; import de.steamwar.towerrun.listener.LobbyListener;
@ -50,6 +53,9 @@ public class TowerRun extends JavaPlugin {
@Getter @Getter
private static Message message; private static Message message;
@Getter
private static TowerGenerator towerGenerator = null;
@Getter @Getter
private static GameCountdown gameCountdown; private static GameCountdown gameCountdown;
@ -59,6 +65,10 @@ public class TowerRun extends JavaPlugin {
instance = this; instance = this;
message = new Message("TowerRun", getClassLoader()); message = new Message("TowerRun", getClassLoader());
if (WorldConfig.TOWER_GENERATOR_CONFIG != null) {
towerGenerator = new TowerGenerator(WorldConfig.TOWER_GENERATOR_CONFIG);
}
new LobbyListener(); new LobbyListener();
new IngameListener(); new IngameListener();
new GlobalListener(); new GlobalListener();
@ -68,5 +78,7 @@ public class TowerRun extends JavaPlugin {
new EndCountdown(lobbyCountdown); new EndCountdown(lobbyCountdown);
new StartCommand(lobbyCountdown); new StartCommand(lobbyCountdown);
gameCountdown = new GameCountdown(); gameCountdown = new GameCountdown();
TowerRunGame.reset();
} }
} }

Datei anzeigen

@ -37,8 +37,10 @@ public class StartCommand extends SWCommand {
@Register @Register
public void command(@Validator Player player) { public void command(@Validator Player player) {
countdown.setOverride(true); if (countdown.getTime() > 10) {
countdown.setTime(10); countdown.setOverride(true);
countdown.setTime(10);
}
TowerRun.getMessage().send("COMMAND_START", player); TowerRun.getMessage().send("COMMAND_START", player);
} }

Datei anzeigen

@ -19,6 +19,7 @@
package de.steamwar.towerrun.config; package de.steamwar.towerrun.config;
import de.steamwar.sql.SchematicType;
import de.steamwar.towerrun.TowerRun; import de.steamwar.towerrun.TowerRun;
import de.steamwar.towerrun.winconditions.FirstOutsideWincondition; import de.steamwar.towerrun.winconditions.FirstOutsideWincondition;
import de.steamwar.towerrun.winconditions.LastOutsideWincondition; import de.steamwar.towerrun.winconditions.LastOutsideWincondition;
@ -28,13 +29,13 @@ import lombok.Getter;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.*;
import java.util.List;
@UtilityClass @UtilityClass
public class WorldConfig { public class WorldConfig {
@ -53,8 +54,11 @@ public class WorldConfig {
public static final int MAP_MIN_Z; public static final int MAP_MIN_Z;
public static final int MAP_MAX_X; public static final int MAP_MAX_X;
public static final int MAP_MAX_Z; public static final int MAP_MAX_Z;
public static final Map<Material, Integer> MELTING_TIMES;
public static final TowerGeneratorConfig TOWER_GENERATOR_CONFIG;
public static final List<WinCondition> WINCONDITIONS = new ArrayList<>(); public static final List<WinCondition> WINCONDITIONS = new ArrayList<>();
static { static {
WINCONDITIONS.add(new LastRemainingWincondition()); WINCONDITIONS.add(new LastRemainingWincondition());
WINCONDITIONS.add(new LastOutsideWincondition()); WINCONDITIONS.add(new LastOutsideWincondition());
@ -62,7 +66,7 @@ public class WorldConfig {
} }
private static Location parseLocation(ConfigurationSection section) { private static Location parseLocation(ConfigurationSection section) {
Location loc = new Location( Location loc = new Location(
Bukkit.getWorlds().get(0), Bukkit.getWorlds().get(0),
section.getDouble("x"), section.getDouble("x"),
section.getDouble("y"), section.getDouble("y"),
@ -123,20 +127,30 @@ public class WorldConfig {
ESCAPE_HEIGHT = tower.getInt("escapeHeight"); ESCAPE_HEIGHT = tower.getInt("escapeHeight");
SPAWN = parseLocation(tower.getConfigurationSection("spawn")); SPAWN = parseLocation(tower.getConfigurationSection("spawn"));
List<ConfigurationSection> doors = tower.getConfigurationSection("doors").getKeys(false).stream() ConfigurationSection doorSection = tower.getConfigurationSection("doors");
.map(tower.getConfigurationSection("doors")::getConfigurationSection) if (doorSection != null) {
.toList(); List<ConfigurationSection> doors = doorSection.getKeys(false).stream()
DOORS = new Location[doors.size()]; .map(tower.getConfigurationSection("doors")::getConfigurationSection)
for (int i = 0; i < doors.size(); i++) { .toList();
DOORS[i] = parseLocation(doors.get(i)); DOORS = new Location[doors.size()];
for (int i = 0; i < doors.size(); i++) {
DOORS[i] = parseLocation(doors.get(i));
}
} else {
DOORS = new Location[0];
} }
List<ConfigurationSection> keys = tower.getConfigurationSection("keys").getKeys(false).stream() ConfigurationSection keysSection = tower.getConfigurationSection("keys");
.map(tower.getConfigurationSection("keys")::getConfigurationSection) if (keysSection != null) {
.toList(); List<ConfigurationSection> keys = keysSection.getKeys(false).stream()
KEYS = new Location[keys.size()]; .map(tower.getConfigurationSection("keys")::getConfigurationSection)
for (int i = 0; i < keys.size(); i++) { .toList();
KEYS[i] = parseLocation(keys.get(i)); KEYS = new Location[keys.size()];
for (int i = 0; i < keys.size(); i++) {
KEYS[i] = parseLocation(keys.get(i));
}
} else {
KEYS = new Location[0];
} }
LAVA_Y = tower.getInt("lavaY"); LAVA_Y = tower.getInt("lavaY");
@ -147,8 +161,26 @@ public class WorldConfig {
MAP_MAX_X = config.getInt("maxX"); MAP_MAX_X = config.getInt("maxX");
MAP_MAX_Z = config.getInt("maxZ"); MAP_MAX_Z = config.getInt("maxZ");
ConfigurationSection meltingBlocksSection = tower.getConfigurationSection("meltingBlocks");
if (meltingBlocksSection != null) {
Map<Material, Integer> meltingTimes = new HashMap<>();
meltingBlocksSection.getKeys(false).forEach(s -> {
meltingTimes.put(Material.valueOf(s), meltingBlocksSection.getInt(s));
});
MELTING_TIMES = Collections.unmodifiableMap(meltingTimes);
} else {
MELTING_TIMES = Collections.emptyMap();
}
ACTIVE_WINCONDITIONS = config.getStringList("winconditions"); ACTIVE_WINCONDITIONS = config.getStringList("winconditions");
WINCONDITIONS.stream().filter(winCondition -> ACTIVE_WINCONDITIONS.contains(winCondition.getName())).forEach(winCondition -> winCondition.setActive(true)); WINCONDITIONS.stream().filter(winCondition -> ACTIVE_WINCONDITIONS.contains(winCondition.getName())).forEach(winCondition -> winCondition.setActive(true));
ConfigurationSection towerGeneratorSection = config.getConfigurationSection("towerGenerator");
if (towerGeneratorSection == null) {
TOWER_GENERATOR_CONFIG = null;
} else {
TOWER_GENERATOR_CONFIG = new TowerGeneratorConfig(towerGeneratorSection);
}
} }
@Getter @Getter
@ -176,4 +208,116 @@ public class WorldConfig {
&& vector.getZ() >= min.getZ() && vector.getZ() <= max.getZ(); && vector.getZ() >= min.getZ() && vector.getZ() <= max.getZ();
} }
} }
@Getter
public static final class TowerGeneratorConfig {
public final int x;
public final int y;
public final int z;
public final int minHeight;
public final int maxHeight;
public final int minNoBombFloors;
public final int maxNoBombFloors;
public final double tntChance;
public final int minBombs;
public final int maxBombs;
public final double keyChance;
public final int minNoKeyFloors;
public final int maxNoKeyFloors;
public final SchematicType schematicType;
public final TowerGeneratorFillRegion[] fillRegions;
public final Region[] tntRegions;
public final TowerGeneratorDoorBlock[] doorBlocks;
public TowerGeneratorConfig(ConfigurationSection section) {
x = section.getInt("x");
y = section.getInt("y");
z = section.getInt("z");
minHeight = section.getInt("minHeight");
maxHeight = section.getInt("maxHeight");
minNoBombFloors = section.getInt("minNoBombFloors");
maxNoBombFloors = section.getInt("maxNoBombFloors");
minBombs = section.getInt("minBombs");
maxBombs = section.getInt("maxBombs");
tntChance = section.getDouble("tntChance");
keyChance = section.getDouble("keyChance");
minNoKeyFloors = section.getInt("minNoKeyFloors");
maxNoKeyFloors = section.getInt("maxNoKeyFloors");
schematicType = SchematicType.fromDB(section.getString("schematicType"));
ConfigurationSection fillRegionsSection = section.getConfigurationSection("fillRegions");
if (fillRegionsSection != null) {
List<ConfigurationSection> fillRegions = fillRegionsSection.getKeys(false).stream()
.map(fillRegionsSection::getConfigurationSection)
.toList();
this.fillRegions = new TowerGeneratorFillRegion[fillRegions.size()];
for (int i = 0; i < fillRegions.size(); i++) {
this.fillRegions[i] = new TowerGeneratorFillRegion(fillRegions.get(i));
}
} else {
fillRegions = new TowerGeneratorFillRegion[0];
}
ConfigurationSection tntRegionsSection = section.getConfigurationSection("tntRegions");
if (tntRegionsSection != null) {
List<ConfigurationSection> tntRegions = tntRegionsSection.getKeys(false).stream()
.map(tntRegionsSection::getConfigurationSection)
.toList();
this.tntRegions = new Region[tntRegions.size()];
for (int i = 0; i < tntRegions.size(); i++) {
this.tntRegions[i] = new Region(tntRegions.get(i));
}
} else {
tntRegions = new Region[0];
}
ConfigurationSection doorBlocksSection = section.getConfigurationSection("doorBlocks");
if (doorBlocksSection != null) {
List<ConfigurationSection> doorBlocks = doorBlocksSection.getKeys(false).stream()
.map(doorBlocksSection::getConfigurationSection)
.toList();
this.doorBlocks = new TowerGeneratorDoorBlock[doorBlocks.size()];
for (int i = 0; i < doorBlocks.size(); i++) {
this.doorBlocks[i] = new TowerGeneratorDoorBlock(doorBlocks.get(i));
}
} else {
doorBlocks = new TowerGeneratorDoorBlock[0];
}
}
}
@Getter
public static final class TowerGeneratorFillRegion {
private final int minX;
private final int minZ;
private final int maxX;
private final int maxZ;
private final double percentage;
private final Material material;
public TowerGeneratorFillRegion(ConfigurationSection section) {
minX = section.getInt("minX");
minZ = section.getInt("minZ");
maxX = section.getInt("maxX");
maxZ = section.getInt("maxZ");
percentage = section.getDouble("percentage");
material = Material.valueOf(section.getString("material"));
}
}
@Getter
public static final class TowerGeneratorDoorBlock {
private final int x;
private final int dy;
private final int z;
public TowerGeneratorDoorBlock(ConfigurationSection section) {
x = section.getInt("x");
dy = section.getInt("dy");
z = section.getInt("z");
}
}
} }

Datei anzeigen

@ -22,6 +22,7 @@ package de.steamwar.towerrun.countdowns;
import de.steamwar.towerrun.TowerRun; import de.steamwar.towerrun.TowerRun;
import de.steamwar.towerrun.state.GameStateToggleListener; import de.steamwar.towerrun.state.GameStateToggleListener;
import de.steamwar.towerrun.state.GameStates; import de.steamwar.towerrun.state.GameStates;
import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.scheduler.BukkitTask; import org.bukkit.scheduler.BukkitTask;
@ -31,6 +32,7 @@ import java.util.EnumSet;
public abstract class Countdown extends GameStateToggleListener { public abstract class Countdown extends GameStateToggleListener {
@Setter @Setter
@Getter
protected int time = defaultTime(); protected int time = defaultTime();
protected BukkitTask task; protected BukkitTask task;
@ -38,9 +40,13 @@ public abstract class Countdown extends GameStateToggleListener {
super(enabledStates); super(enabledStates);
} }
int defaultTime() {return 0;} int defaultTime() {
return 0;
}
void timerEnd() {} void timerEnd() {}
boolean timerShouldCancel() {return true;} boolean timerShouldCancel() {
return true;
}
void run() {} void run() {}
void timerStart() {} void timerStart() {}
void timerReset() {} void timerReset() {}

Datei anzeigen

@ -32,7 +32,7 @@ public class EndCountdown extends Countdown {
private final LobbyCountdown lobbyCountdown; private final LobbyCountdown lobbyCountdown;
private static boolean RESETS = Objects.requireNonNull(Bukkit.getWorlds().get(0).getWorldFolder().list((dir, name) -> name.equals("backup"))).length > 0; private static final boolean RESETS = Objects.requireNonNull(Bukkit.getWorlds().get(0).getWorldFolder().list((dir, name) -> name.equals("backup"))).length > 0;
public EndCountdown(LobbyCountdown lobbyCountdown) { public EndCountdown(LobbyCountdown lobbyCountdown) {
super(EnumSet.of(GameStates.ENDING)); super(EnumSet.of(GameStates.ENDING));

Datei anzeigen

@ -47,7 +47,7 @@ public class LobbyCountdown extends Countdown {
@Override @Override
void timerEnd() { void timerEnd() {
TowerRunGame.start(); TowerRunGame.prepareTowerOrStart();
override = false; override = false;
} }

Datei anzeigen

@ -48,10 +48,27 @@ public class TowerRunGame {
return PLAYERS_ALIVE.contains(player); return PLAYERS_ALIVE.contains(player);
} }
public static void start() { public static void prepareTowerOrStart() {
if (GameState.getCurrentState() == GameStates.LOBBY) { if (GameState.getCurrentState() == GameStates.LOBBY) {
GameState.nextState();
if (TowerRun.getTowerGenerator() == null) {
start();
return;
}
TowerRun.getTowerGenerator().generate();
} else {
throw new IllegalStateException("Game is already running!");
}
}
public static void start() {
if (GameState.getCurrentState() == GameStates.GENERATING_TOWER) {
PLAYERS_ALIVE.addAll(TowerRunPlayer.getAll()); PLAYERS_ALIVE.addAll(TowerRunPlayer.getAll());
PLAYERS_ALIVE.forEach(TowerRunPlayer::reset); PLAYERS_ALIVE.forEach(p -> {
p.reset();
p.player().setGameMode(GameMode.SURVIVAL);
});
GameState.nextState(); GameState.nextState();
generateLava(); generateLava();
TowerRun.getMessage().broadcast("GAME_START"); TowerRun.getMessage().broadcast("GAME_START");
@ -70,8 +87,12 @@ public class TowerRunGame {
for (int z = WorldConfig.MIN_TOWER.getBlockZ(); z < WorldConfig.MAX_TOWER.getBlockZ(); z += WorldConfig.LAVE_SPACE) { for (int z = WorldConfig.MIN_TOWER.getBlockZ(); z < WorldConfig.MAX_TOWER.getBlockZ(); z += WorldConfig.LAVE_SPACE) {
Vector pos = new Vector(x, 0, z); Vector pos = new Vector(x, 0, z);
if (Arrays.stream(WorldConfig.REGIONS).anyMatch(region -> region.contains(pos))) { if (Arrays.stream(WorldConfig.REGIONS).anyMatch(region -> region.contains(pos))) {
WorldConfig.MIN_TOWER.getWorld().getBlockAt(x, WorldConfig.LAVA_Y, z).setType(Material.LAVA, true); int offset = WorldConfig.LAVA_Y;
WorldConfig.MIN_TOWER.getWorld().getBlockAt(x, WorldConfig.LAVA_Y - 1, z).setType(Material.BEDROCK, true); if (TowerRun.getTowerGenerator() != null) {
offset += TowerRun.getTowerGenerator().getHeight();
}
WorldConfig.MIN_TOWER.getWorld().getBlockAt(x, offset, z).setType(Material.LAVA, true);
WorldConfig.MIN_TOWER.getWorld().getBlockAt(x, offset - 1, z).setType(Material.BEDROCK, true);
} }
} }
} }
@ -107,38 +128,42 @@ public class TowerRunGame {
resetWorld(); resetWorld();
GameState.reset(); GameState.reset();
Bukkit.getOnlinePlayers().forEach(player -> { Bukkit.getOnlinePlayers().forEach(player -> {
player.setGameMode(GameMode.SURVIVAL); if (TowerRun.getTowerGenerator() != null) {
player.setGameMode(GameMode.SPECTATOR);
} else {
player.setGameMode(GameMode.SURVIVAL);
}
player.teleport(WorldConfig.SPAWN); player.teleport(WorldConfig.SPAWN);
}); });
} }
private static double posToChunk(int pos){ private static double posToChunk(int pos) {
return pos / 16.0; return pos / 16.0;
} }
private static int getMinChunkX(){ private static int getMinChunkX() {
return (int) Math.floor(posToChunk(WorldConfig.MAP_MIN_X)); return (int) Math.floor(posToChunk(WorldConfig.MAP_MIN_X));
} }
private static int getMaxChunkX(){ private static int getMaxChunkX() {
return (int) Math.ceil(posToChunk(WorldConfig.MAP_MAX_X)); return (int) Math.ceil(posToChunk(WorldConfig.MAP_MAX_X));
} }
private static int getMinChunkZ(){ private static int getMinChunkZ() {
return (int) Math.floor(posToChunk(WorldConfig.MAP_MIN_Z)); return (int) Math.floor(posToChunk(WorldConfig.MAP_MIN_Z));
} }
private static int getMaxChunkZ(){ private static int getMaxChunkZ() {
return (int) Math.ceil(posToChunk(WorldConfig.MAP_MAX_Z)); return (int) Math.ceil(posToChunk(WorldConfig.MAP_MAX_Z));
} }
private static void forEachChunk(ObjIntConsumer<Integer> executor) { private static void forEachChunk(ObjIntConsumer<Integer> executor) {
for(int x = getMinChunkX(); x <= getMaxChunkX(); x++) for (int x = getMinChunkX(); x <= getMaxChunkX(); x++)
for(int z = getMinChunkZ(); z <= getMaxChunkZ(); z++) for (int z = getMinChunkZ(); z <= getMaxChunkZ(); z++)
executor.accept(x, z); executor.accept(x, z);
} }
private static void resetWorld(){ private static void resetWorld() {
world.getEntities().stream().filter(entity -> entity.getType() != EntityType.PLAYER).forEach(Entity::remove); world.getEntities().stream().filter(entity -> entity.getType() != EntityType.PLAYER).forEach(Entity::remove);
World backup = new WorldCreator(world.getName() + "/backup").createWorld(); World backup = new WorldCreator(world.getName() + "/backup").createWorld();
@ -153,7 +178,7 @@ public class TowerRunGame {
System.arraycopy(backupChunk.d(), 0, chunk.d(), 0, chunk.d().length); System.arraycopy(backupChunk.d(), 0, chunk.d(), 0, chunk.d().length);
for(Player p : Bukkit.getOnlinePlayers()) for (Player p : Bukkit.getOnlinePlayers())
CraftbukkitWrapper.impl.sendChunk(p, x, z); CraftbukkitWrapper.impl.sendChunk(p, x, z);
} }
} }

Datei anzeigen

@ -19,6 +19,7 @@
package de.steamwar.towerrun.game; package de.steamwar.towerrun.game;
import de.steamwar.towerrun.TowerRun;
import de.steamwar.towerrun.config.WorldConfig; import de.steamwar.towerrun.config.WorldConfig;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
@ -43,7 +44,14 @@ public record TowerRunPlayer(Player player) {
} }
public void reset() { public void reset() {
player.teleport(WorldConfig.SPAWN); player.getInventory().clear();
player.updateInventory();
player.setHealth(20);
if (TowerRun.getTowerGenerator() != null) {
player.teleport(TowerRun.getTowerGenerator().getSpawn());
} else {
player.teleport(WorldConfig.SPAWN);
}
player.setVelocity(new Vector(0, 0, 0)); player.setVelocity(new Vector(0, 0, 0));
} }

Datei anzeigen

@ -0,0 +1,206 @@
package de.steamwar.towerrun.generator;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardReader;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.session.ClipboardHolder;
import de.steamwar.sql.SchematicData;
import de.steamwar.sql.SchematicNode;
import de.steamwar.towerrun.TowerRun;
import de.steamwar.towerrun.config.WorldConfig;
import de.steamwar.towerrun.game.TowerRunGame;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.*;
import org.bukkit.block.data.Bisected;
import org.bukkit.block.data.type.Door;
import org.bukkit.scheduler.BukkitRunnable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Random;
public class TowerGenerator {
private static final Random random = new Random();
private final WorldConfig.TowerGeneratorConfig config;
private final List<SchematicNode> allSchematics;
private final Clipboard roof;
@Getter
private int height;
@Getter
private Location spawn;
@Getter
private List<Location> keys = new ArrayList<>();
public TowerGenerator(WorldConfig.TowerGeneratorConfig config) {
File file = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "Roof.schem");
if (!file.exists()) {
Bukkit.shutdown();
throw new SecurityException("TowerRun schematic not found");
}
roof = loadSchematic(file);
this.config = config;
allSchematics = SchematicNode.getAllSchematicsOfType(config.schematicType);
spawn = WorldConfig.SPAWN;
}
private Clipboard loadSchematic(File file) {
Clipboard clipboard;
try (ClipboardReader reader = Objects.requireNonNull(ClipboardFormats.findByFile(file)).getReader(new FileInputStream(file))) {
clipboard = reader.read();
} catch (NullPointerException | IOException e) {
Bukkit.shutdown();
throw new SecurityException("TowerRun schematic not found", e);
}
return clipboard;
}
public void generate() {
new BukkitRunnable() {
int height = random.nextInt(config.maxHeight - config.minHeight) + config.minHeight;
int y = TowerGenerator.this.config.y;
int noBombFloors;
int noKeyFloors;
{
noBombFloors = random.nextInt(config.maxNoBombFloors - config.minNoBombFloors) + config.minNoBombFloors;
noKeyFloors = random.nextInt(config.maxNoKeyFloors - config.minNoKeyFloors) + config.minNoKeyFloors;
keys.clear();
}
@Override
public void run() {
if (height > 0) {
SchematicNode schematicNode = allSchematics.get(random.nextInt(allSchematics.size()));
SchematicData schematicData = new SchematicData(schematicNode);
int currentY;
int width;
int depth;
try {
Clipboard clipboard = schematicData.load();
try (EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(new BukkitWorld(Bukkit.getWorlds().get(0)), -1)) {
ClipboardHolder ch = new ClipboardHolder(clipboard);
Operations.completeBlindly(ch.createPaste(e).to(BlockVector3.at(config.x, y, config.z)).build());
}
width = clipboard.getDimensions().getX();
depth = clipboard.getDimensions().getZ();
currentY = y;
y += clipboard.getDimensions().getY();
height -= clipboard.getDimensions().getY();
TowerGenerator.this.height += clipboard.getDimensions().getY();
} catch (IOException e) {
allSchematics.remove(schematicNode);
return;
}
spawn = WorldConfig.SPAWN.clone().add(0, y, 0);
List<Container> chestBlocks = new ArrayList<>();
for (int x = config.x; x < config.x + width; x++) {
for (int z = config.z; z < config.z + depth; z++) {
for (int y = currentY; y < this.y; y++) {
Block block = Bukkit.getWorlds().get(0).getBlockAt(x, y, z);
BlockState blockState = block.getState();
if (blockState instanceof Chest) {
chestBlocks.add((Container) blockState);
}
}
}
}
noBombFloors--;
if (noBombFloors < 0 && random.nextDouble() < config.tntChance) {
noBombFloors = random.nextInt(config.maxNoBombFloors - config.minNoBombFloors) + config.minNoBombFloors;
int bombCount = random.nextInt(config.maxBombs - config.minBombs) + config.minBombs;
for (int i = 0; i < bombCount; i++) {
WorldConfig.Region region = config.tntRegions[random.nextInt(config.tntRegions.length)];
int x = random.nextInt(region.max.getBlockX() - region.min.getBlockX()) + region.min.getBlockX();
int z = random.nextInt(region.max.getBlockZ() - region.min.getBlockZ()) + region.min.getBlockZ();
int y = currentY + 1;
Bukkit.getWorlds().get(0).getBlockAt(x, y, z).setType(Material.TNT, true);
}
}
noKeyFloors--;
if (!chestBlocks.isEmpty() && noKeyFloors < 0 && random.nextDouble() < config.keyChance) {
noKeyFloors = random.nextInt(config.maxNoKeyFloors - config.minNoKeyFloors) + config.minNoKeyFloors;
Container container = chestBlocks.get(random.nextInt(chestBlocks.size()));
keys.add(container.getLocation());
for (WorldConfig.TowerGeneratorDoorBlock doorBlock : config.doorBlocks) {
int x = doorBlock.getX();
int y = currentY + doorBlock.getDy();
int z = doorBlock.getZ();
Block block = Bukkit.getWorlds().get(0).getBlockAt(x, y, z);
for (int i = 0; i < 5; i++) {
if (block.getType().isAir()) {
block.setType(Material.IRON_BLOCK, false);
block = block.getRelative(0, 1, 0);
} else {
break;
}
}
Bukkit.getScheduler().runTaskLater(TowerRun.getInstance(), () -> {
Block door = Bukkit.getWorlds().get(0).getBlockAt(x, y, z);
door.setType(Material.IRON_DOOR, false);
door = door.getRelative(0, 1, 0);
door.setType(Material.IRON_DOOR, false);
}, 10);
Bukkit.getScheduler().runTaskLater(TowerRun.getInstance(), () -> {
Block door = Bukkit.getWorlds().get(0).getBlockAt(x, y, z);
Door doorState = (Door) door.getBlockData();
doorState.setFacing(BlockFace.EAST);
door.setBlockData(doorState, false);
door = door.getRelative(0, 1, 0);
doorState = (Door) door.getBlockData();
doorState.setFacing(BlockFace.EAST);
doorState.setHalf(Bisected.Half.TOP);
door.setBlockData(doorState, false);
}, 20);
}
}
for (WorldConfig.TowerGeneratorFillRegion fillRegion : config.fillRegions) {
for (int x = fillRegion.getMinX(); x < fillRegion.getMaxX(); x++) {
for (int z = fillRegion.getMinZ(); z < fillRegion.getMaxZ(); z++) {
for (int y = currentY; y < this.y; y++) {
Block block = Bukkit.getWorlds().get(0).getBlockAt(x, y, z);
if (!block.getType().isAir()) {
continue;
}
if (random.nextDouble() < fillRegion.getPercentage()) {
block.setType(fillRegion.getMaterial(), true);
}
}
}
}
}
} else {
cancel();
try (EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(new BukkitWorld(Bukkit.getWorlds().get(0)), -1)) {
ClipboardHolder ch = new ClipboardHolder(roof);
Operations.completeBlindly(ch.createPaste(e).to(BlockVector3.at(config.x, y, config.z)).build());
}
TowerRunGame.start();
}
}
}.runTaskTimer(TowerRun.getInstance(), 0, 10);
}
}

Datei anzeigen

@ -23,34 +23,104 @@ import de.steamwar.inventory.SWItem;
import de.steamwar.towerrun.TowerRun; import de.steamwar.towerrun.TowerRun;
import de.steamwar.towerrun.config.Config; import de.steamwar.towerrun.config.Config;
import de.steamwar.towerrun.config.WorldConfig; import de.steamwar.towerrun.config.WorldConfig;
import de.steamwar.towerrun.game.TowerRunGame;
import de.steamwar.towerrun.state.GameStateBukkitListener; import de.steamwar.towerrun.state.GameStateBukkitListener;
import de.steamwar.towerrun.state.GameStates; import de.steamwar.towerrun.state.GameStates;
import org.bukkit.Bukkit; import org.bukkit.*;
import org.bukkit.Material; import org.bukkit.block.Block;
import org.bukkit.Sound;
import org.bukkit.entity.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.block.Action; import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPhysicsEvent;
import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityRegainHealthEvent; import org.bukkit.event.entity.EntityRegainHealthEvent;
import org.bukkit.event.entity.ItemSpawnEvent; import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerRespawnEvent; import org.bukkit.scheduler.BukkitRunnable;
import java.util.Arrays; import java.util.*;
import java.util.EnumSet; import java.util.function.Function;
import java.util.stream.Stream;
public class IngameListener extends GameStateBukkitListener { public class IngameListener extends GameStateBukkitListener {
private int time = 0;
private final Map<Integer, List<Block>> blocksToMelt = new HashMap<>();
private BukkitRunnable blocksToMeltRunnable;
private BukkitRunnable antiCampRunnable;
public IngameListener() { public IngameListener() {
super(EnumSet.of(GameStates.INGAME)); super(EnumSet.of(GameStates.INGAME));
} }
@Override
public void enable() {
super.enable();
blocksToMeltRunnable = new BukkitRunnable() {
@Override
public void run() {
List<Block> blocks = blocksToMelt.get(time);
time++;
if (blocks == null) {
return;
}
blocks.forEach(block -> {
if (!WorldConfig.MELTING_TIMES.containsKey(block.getType())) return;
block.setType(Material.AIR);
block.getWorld().playSound(block.getLocation(), Sound.BLOCK_FIRE_EXTINGUISH, 0.1F, 1);
});
}
};
blocksToMeltRunnable.runTaskTimer(TowerRun.getInstance(), 0, 1);
antiCampRunnable = new BukkitRunnable() {
@Override
public void run() {
double minY = TowerRunGame.PLAYERS_ALIVE.stream()
.map(p -> p.player().getLocation().getY())
.min(Comparator.comparing(Function.identity()))
.orElse(0.0);
TowerRunGame.PLAYERS_ALIVE.forEach(towerRunPlayer -> {
if (towerRunPlayer.player().getLocation().getY() - minY > 20) {
towerRunPlayer.player().sendTitle("§a", TowerRun.getMessage().parse("CATCH_UP_WARNING", towerRunPlayer.player()), 5, 30, 5);
}
if (towerRunPlayer.player().getLocation().getY() - minY > 30) {
towerRunPlayer.player().damage(1.0);
}
});
}
};
antiCampRunnable.runTaskTimer(TowerRun.getInstance(), 100, 100);
}
@Override
public void disable() {
super.disable();
blocksToMeltRunnable.cancel();
blocksToMeltRunnable = null;
blocksToMelt.clear();
time = 0;
antiCampRunnable.cancel();
antiCampRunnable = null;
}
@EventHandler @EventHandler
public void onPlayerDeath(PlayerDeathEvent event) { public void onPlayerDeath(PlayerDeathEvent event) {
event.setDeathMessage(null); event.setDeathMessage(null);
Bukkit.getScheduler().runTaskLater(TowerRun.getInstance(), () -> {
if (TowerRun.getTowerGenerator() != null) {
event.getEntity().teleport(TowerRun.getTowerGenerator().getSpawn());
} else {
event.getEntity().teleport(WorldConfig.SPAWN);
}
}, 5
);
event.getEntity().setGameMode(GameMode.SPECTATOR);
Bukkit.getOnlinePlayers().forEach(player -> { Bukkit.getOnlinePlayers().forEach(player -> {
player.sendTitle("", TowerRun.getMessage().parse("PLAYER_DIED", player, event.getEntity().getPlayer().getName()), 10, 70, 20); player.sendTitle("", TowerRun.getMessage().parse("PLAYER_DIED", player, event.getEntity().getPlayer().getName()), 10, 70, 20);
player.playSound(player.getLocation(), Sound.ENTITY_WITHER_DEATH, 1, 1); player.playSound(player.getLocation(), Sound.ENTITY_WITHER_DEATH, 1, 1);
@ -85,13 +155,17 @@ public class IngameListener extends GameStateBukkitListener {
@EventHandler @EventHandler
public void onEntityDamageByEntity(EntityDamageByEntityEvent event) { public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
if(event.getDamager().getType() == EntityType.PLAYER) { if (event.getDamager().getType() == EntityType.PLAYER) {
event.setCancelled(true); event.setCancelled(true);
} }
} }
@EventHandler @EventHandler
public void onPlayerInteract(PlayerInteractEvent event) { public void onPlayerInteract(PlayerInteractEvent event) {
if (event.getPlayer().getGameMode() != GameMode.SURVIVAL) {
return;
}
if (event.getAction() != Action.RIGHT_CLICK_BLOCK || !event.hasBlock()) { if (event.getAction() != Action.RIGHT_CLICK_BLOCK || !event.hasBlock()) {
return; return;
} }
@ -100,20 +174,39 @@ public class IngameListener extends GameStateBukkitListener {
return; return;
} }
if (Arrays.stream(WorldConfig.KEYS).noneMatch(location -> location.equals(event.getClickedBlock().getLocation()))) { Stream<Location> locations = TowerRun.getTowerGenerator() == null ? Arrays.stream(WorldConfig.KEYS) : TowerRun.getTowerGenerator().getKeys().stream();
if (locations.noneMatch(location -> location.equals(event.getClickedBlock().getLocation()))) {
event.getClickedBlock().setType(Material.AIR);
return; return;
} }
event.getPlayer().getInventory().addItem(new SWItem(Material.LEVER, TowerRun.getMessage().parse("KEY_NAME", event.getPlayer())).getItemStack()); event.getPlayer().getInventory().addItem(new SWItem(Material.LEVER, TowerRun.getMessage().parse("KEY_NAME", event.getPlayer())).getItemStack());
event.getClickedBlock().setType(Material.AIR); event.getClickedBlock().setType(Material.ENDER_CHEST);
event.getPlayer().playSound(event.getPlayer().getLocation(), Sound.BLOCK_ENDER_CHEST_OPEN, 1, 1); event.getPlayer().playSound(event.getPlayer().getLocation(), Sound.BLOCK_ENDER_CHEST_OPEN, 1, 1);
TowerRun.getMessage().broadcast("KEY_FOUND", event.getPlayer().getName()); TowerRun.getMessage().broadcast("KEY_FOUND", event.getPlayer().getName());
} }
@EventHandler @EventHandler
public void onPlayerRespawn(PlayerRespawnEvent event) { public void onBlockPhysics(BlockPhysicsEvent event) {
event.setRespawnLocation(WorldConfig.SPAWN); if (event.getSourceBlock().getType() != Material.LAVA) {
return;
}
Block block = event.getSourceBlock();
shouldMelt(block.getRelative(0, 1, 0));
shouldMelt(block.getRelative(0, -1, 0));
shouldMelt(block.getRelative(1, 0, 0));
shouldMelt(block.getRelative(-1, 0, 0));
shouldMelt(block.getRelative(0, 0, 1));
shouldMelt(block.getRelative(0, 0, -1));
}
private void shouldMelt(Block block) {
int meltingTime = WorldConfig.MELTING_TIMES.getOrDefault(block.getType(), -1);
if (meltingTime == -1) {
return;
}
blocksToMelt.computeIfAbsent(time + meltingTime * 20, integer -> new ArrayList<>()).add(block);
} }
@EventHandler @EventHandler

Datei anzeigen

@ -19,6 +19,7 @@
package de.steamwar.towerrun.listener; package de.steamwar.towerrun.listener;
import de.steamwar.towerrun.TowerRun;
import de.steamwar.towerrun.config.WorldConfig; import de.steamwar.towerrun.config.WorldConfig;
import de.steamwar.towerrun.state.GameStateBukkitListener; import de.steamwar.towerrun.state.GameStateBukkitListener;
import de.steamwar.towerrun.state.GameStates; import de.steamwar.towerrun.state.GameStates;
@ -42,13 +43,21 @@ public class LobbyListener extends GameStateBukkitListener {
@EventHandler @EventHandler
public void onPlayerJoin(PlayerJoinEvent event) { public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer(); Player player = event.getPlayer();
player.teleport(WorldConfig.SPAWN); if (TowerRun.getTowerGenerator() != null) {
player.setGameMode(GameMode.SURVIVAL); player.teleport(TowerRun.getTowerGenerator().getSpawn());
player.setGameMode(GameMode.SPECTATOR);
} else {
player.teleport(WorldConfig.SPAWN);
player.setGameMode(GameMode.SURVIVAL);
}
} }
@EventHandler @EventHandler
public void onPlayerMove(PlayerMoveEvent event) { public void onPlayerMove(PlayerMoveEvent event) {
if(event.getTo().getY() < WorldConfig.SPAWN.getY() - 10) { if (TowerRun.getTowerGenerator() != null) {
return;
}
if (event.getTo().getY() < WorldConfig.SPAWN.getY() - 10) {
event.getPlayer().teleport(WorldConfig.SPAWN); event.getPlayer().teleport(WorldConfig.SPAWN);
} }
} }

Datei anzeigen

@ -19,6 +19,7 @@
package de.steamwar.towerrun.listener; package de.steamwar.towerrun.listener;
import de.steamwar.towerrun.TowerRun;
import de.steamwar.towerrun.config.WorldConfig; import de.steamwar.towerrun.config.WorldConfig;
import de.steamwar.towerrun.state.GameStateBukkitListener; import de.steamwar.towerrun.state.GameStateBukkitListener;
import de.steamwar.towerrun.state.GameStates; import de.steamwar.towerrun.state.GameStates;
@ -36,6 +37,10 @@ public class NotLobbyListener extends GameStateBukkitListener {
@EventHandler @EventHandler
public void onPlayerJoin(PlayerJoinEvent event) { public void onPlayerJoin(PlayerJoinEvent event) {
event.getPlayer().setGameMode(GameMode.SPECTATOR); event.getPlayer().setGameMode(GameMode.SPECTATOR);
event.getPlayer().teleport(WorldConfig.SPAWN); if (TowerRun.getTowerGenerator() != null) {
event.getPlayer().teleport(TowerRun.getTowerGenerator().getSpawn());
} else {
event.getPlayer().teleport(WorldConfig.SPAWN);
}
} }
} }

Datei anzeigen

@ -28,12 +28,13 @@ public abstract class GameStateToggleListener extends GameStateListener {
protected GameStateToggleListener(EnumSet<GameStates> enabledStates) { protected GameStateToggleListener(EnumSet<GameStates> enabledStates) {
super(); super();
this.enabledStates = enabledStates; this.enabledStates = enabledStates;
if(enabledStates.contains(GameState.getCurrentState())) { if (enabledStates.contains(GameState.getCurrentState())) {
enable(); enable();
} }
} }
public abstract void enable(); public abstract void enable();
public abstract void disable(); public abstract void disable();
@Override @Override

Datei anzeigen

@ -27,7 +27,8 @@ import lombok.Getter;
public enum GameStates { public enum GameStates {
ENDING(null), ENDING(null),
INGAME(ENDING), INGAME(ENDING),
LOBBY(INGAME); GENERATING_TOWER(INGAME),
LOBBY(GENERATING_TOWER);
private final GameStates nextState; private final GameStates nextState;
} }

Datei anzeigen

@ -26,7 +26,7 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.entity.PlayerDeathEvent;
public class LastOutsideWincondition extends OutsideWincondition{ public class LastOutsideWincondition extends OutsideWincondition {
public LastOutsideWincondition() { public LastOutsideWincondition() {
super("LAST_OUTSIDE"); super("LAST_OUTSIDE");
} }
@ -42,8 +42,8 @@ public class LastOutsideWincondition extends OutsideWincondition{
@EventHandler(priority = EventPriority.LOW) @EventHandler(priority = EventPriority.LOW)
public void onPlayerDeath(PlayerDeathEvent event) { public void onPlayerDeath(PlayerDeathEvent event) {
if(TowerRunGame.PLAYERS_ALIVE.isEmpty()) { if (TowerRunGame.PLAYERS_ALIVE.isEmpty()) {
if(TowerRunGame.PLAYERS_ESCAPED.isEmpty()) { if (TowerRunGame.PLAYERS_ESCAPED.isEmpty()) {
TowerRunGame.tie(); TowerRunGame.tie();
return; return;
} }