forked from SteamWar/SteamWar
Add TowerRun module
This commit is contained in:
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* This file is a part of the SteamWar software.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2024 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("java")
|
||||||
|
id("base")
|
||||||
|
|
||||||
|
id("com.github.johnrengelman.shadow")
|
||||||
|
}
|
||||||
|
|
||||||
|
group = "de.steamwar"
|
||||||
|
version = ""
|
||||||
|
|
||||||
|
tasks.compileJava {
|
||||||
|
options.encoding = "UTF-8"
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.build {
|
||||||
|
finalizedBy(tasks.shadowJar)
|
||||||
|
}
|
||||||
|
|
||||||
|
java {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_17
|
||||||
|
targetCompatibility = JavaVersion.VERSION_17
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main {
|
||||||
|
java {
|
||||||
|
srcDirs("src/")
|
||||||
|
}
|
||||||
|
resources {
|
||||||
|
srcDirs("src/")
|
||||||
|
exclude("**/*.java", "**/*.kt")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnly("org.projectlombok:lombok:1.18.32")
|
||||||
|
annotationProcessor("org.projectlombok:lombok:1.18.32")
|
||||||
|
compileOnly("org.spigotmc:plugin-annotations:1.2.3-SNAPSHOT")
|
||||||
|
annotationProcessor("org.spigotmc:plugin-annotations:1.2.3-SNAPSHOT")
|
||||||
|
|
||||||
|
compileOnly(project(":SpigotCore"))
|
||||||
|
|
||||||
|
compileOnly("de.steamwar:spigot:1.19")
|
||||||
|
compileOnly("de.steamwar:worldedit:1.15")
|
||||||
|
|
||||||
|
compileOnly("org.spigotmc:spigot-api:1.19-R0.1-SNAPSHOT")
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#
|
||||||
|
# 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 <https://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
PREFIX=§eTowerRun§8»§r
|
||||||
|
|
||||||
|
PLAYER_DIED=§c{0} §7died§8!
|
||||||
|
PLAYER_ESCAPE=§a{0} §7escaped§8!
|
||||||
|
GAME_START=§aThe game has started§8!
|
||||||
|
GAME_WIN=§a{0} §7has won the game§8!
|
||||||
|
GAME_STARTING=§7Starting: §e{0}s§8!
|
||||||
|
GAME_WAITING=§7Waiting for players§8...
|
||||||
|
SERVER_STOPPING=§cThe server stops in §e{0}s§8!
|
||||||
|
SERVER_RESET=§cThe server will be reset in §e{0}s§8!
|
||||||
|
KEY_NAME=§eKey
|
||||||
|
KEY_FOUND=§a{0} §7found a key§8!
|
||||||
|
GAME_TIE=§aThe game ended in a tie§8!
|
||||||
|
GAME_TIME=§a{0}:{1}
|
||||||
|
CATCH_UP_WARNING=§4!! §cYou should catch up §4!!
|
||||||
|
|
||||||
|
COMMAND_START=§aThe game will start soon§8!
|
||||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
|
||||||
|
PLAYER_DIED=§c{0} §7ist gestorben§8!
|
||||||
|
PLAYER_ESCAPE=§a{0} §7ist entkommen§8!
|
||||||
|
GAME_START=§aDas Spiel beginnt§8!
|
||||||
|
GAME_WIN=§a{0} §7hat das Spiel gewonnen§8!
|
||||||
|
GAME_STARTING=§7Das Spiel startet in §e{0}s§8!
|
||||||
|
GAME_WAITING=§7Warte auf weitere Spieler§8...
|
||||||
|
SERVER_STOPPING=§cDer Server stoppt in §e{0}s§8!
|
||||||
|
SERVER_RESET=§cDer Server wird in §e{0}s §czurückgesetzt§8!
|
||||||
|
GAME_TIE=§7Keiner hat gewonnen§8!
|
||||||
|
|
||||||
|
KEY_NAME=§eSchlüssel
|
||||||
|
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!
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.towerrun;
|
||||||
|
|
||||||
|
import de.steamwar.message.Message;
|
||||||
|
import de.steamwar.towerrun.commands.StartCommand;
|
||||||
|
import de.steamwar.towerrun.config.WorldConfig;
|
||||||
|
import de.steamwar.towerrun.countdowns.EndCountdown;
|
||||||
|
import de.steamwar.towerrun.countdowns.GameCountdown;
|
||||||
|
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.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.ApiVersion;
|
||||||
|
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.0")
|
||||||
|
@Dependency("SpigotCore")
|
||||||
|
@Author("YoyoNow")
|
||||||
|
@Author("Chaoscaot")
|
||||||
|
@Description("SteamWar TowerRun Plugin")
|
||||||
|
@ApiVersion(ApiVersion.Target.v1_19)
|
||||||
|
public class TowerRun extends JavaPlugin {
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static TowerRun instance;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static Message message;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static TowerGenerator towerGenerator = null;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private static GameCountdown gameCountdown;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
instance = this;
|
||||||
|
message = new Message("TowerRun", getClassLoader());
|
||||||
|
|
||||||
|
if (WorldConfig.TOWER_GENERATOR_CONFIG != null) {
|
||||||
|
towerGenerator = new TowerGenerator(WorldConfig.TOWER_GENERATOR_CONFIG);
|
||||||
|
}
|
||||||
|
|
||||||
|
new LobbyListener();
|
||||||
|
new IngameListener();
|
||||||
|
new GlobalListener();
|
||||||
|
new LobbyListener();
|
||||||
|
new NotLobbyListener();
|
||||||
|
final LobbyCountdown lobbyCountdown = new LobbyCountdown();
|
||||||
|
new EndCountdown(lobbyCountdown);
|
||||||
|
new StartCommand(lobbyCountdown);
|
||||||
|
gameCountdown = new GameCountdown();
|
||||||
|
|
||||||
|
TowerRunGame.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.towerrun.commands;
|
||||||
|
|
||||||
|
import de.steamwar.command.SWCommand;
|
||||||
|
import de.steamwar.command.TypeValidator;
|
||||||
|
import de.steamwar.sql.SteamwarUser;
|
||||||
|
import de.steamwar.sql.UserGroup;
|
||||||
|
import de.steamwar.towerrun.TowerRun;
|
||||||
|
import de.steamwar.towerrun.countdowns.LobbyCountdown;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
public class StartCommand extends SWCommand {
|
||||||
|
private final LobbyCountdown countdown;
|
||||||
|
|
||||||
|
public StartCommand(LobbyCountdown countdown) {
|
||||||
|
super("start", "skip");
|
||||||
|
this.countdown = countdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Register
|
||||||
|
public void command(@Validator Player player) {
|
||||||
|
if (countdown.getTime() > 10) {
|
||||||
|
countdown.setOverride(true);
|
||||||
|
countdown.setTime(10);
|
||||||
|
}
|
||||||
|
TowerRun.getMessage().send("COMMAND_START", player);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ClassValidator(value = Player.class, local = true)
|
||||||
|
public TypeValidator<Player> playerValidator() {
|
||||||
|
return (commandSender, player, messageSender) -> SteamwarUser.get(player.getUniqueId()).getUserGroup() != UserGroup.Member;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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<Material> DESTROYABLE_BLOCKS;
|
||||||
|
public static final int GAME_TIMER;
|
||||||
|
public static final int GAME_ESCAPE_TIMER;
|
||||||
|
|
||||||
|
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");
|
||||||
|
GAME_TIMER = config.getInt("gameTimer", 20 * 60);
|
||||||
|
GAME_ESCAPE_TIMER = config.getInt("gameEscapeTimer", 60);
|
||||||
|
DESTROYABLE_BLOCKS = EnumSet.copyOf(config.getStringList("destroyable").stream().map(Material::valueOf).collect(Collectors.toSet()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,323 @@
|
|||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.towerrun.config;
|
||||||
|
|
||||||
|
import de.steamwar.sql.SchematicType;
|
||||||
|
import de.steamwar.towerrun.TowerRun;
|
||||||
|
import de.steamwar.towerrun.winconditions.FirstOutsideWincondition;
|
||||||
|
import de.steamwar.towerrun.winconditions.LastOutsideWincondition;
|
||||||
|
import de.steamwar.towerrun.winconditions.LastRemainingWincondition;
|
||||||
|
import de.steamwar.towerrun.winconditions.WinCondition;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@UtilityClass
|
||||||
|
public class WorldConfig {
|
||||||
|
|
||||||
|
public static final Region[] REGIONS;
|
||||||
|
public static final Location[] DOORS;
|
||||||
|
public static final Location[] KEYS;
|
||||||
|
public static final int LAVA_Y;
|
||||||
|
public static final int LAVE_SPACE;
|
||||||
|
public static final Location SPAWN;
|
||||||
|
public static final int ESCAPE_HEIGHT;
|
||||||
|
public static final Location MIN_TOWER;
|
||||||
|
public static final Location MAX_TOWER;
|
||||||
|
public static final List<String> ACTIVE_WINCONDITIONS;
|
||||||
|
public static final int MAP_MIN_X;
|
||||||
|
public static final int MAP_MIN_Z;
|
||||||
|
public static final int MAP_MAX_X;
|
||||||
|
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<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
WINCONDITIONS.add(new LastRemainingWincondition());
|
||||||
|
WINCONDITIONS.add(new LastOutsideWincondition());
|
||||||
|
WINCONDITIONS.add(new FirstOutsideWincondition());
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
ConfigurationSection tower = config.getConfigurationSection("tower");
|
||||||
|
|
||||||
|
List<ConfigurationSection> 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"));
|
||||||
|
ConfigurationSection doorSection = tower.getConfigurationSection("doors");
|
||||||
|
if (doorSection != null) {
|
||||||
|
List<ConfigurationSection> doors = doorSection.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));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
DOORS = new Location[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigurationSection keysSection = tower.getConfigurationSection("keys");
|
||||||
|
if (keysSection != null) {
|
||||||
|
List<ConfigurationSection> keys = keysSection.getKeys(false).stream()
|
||||||
|
.map(tower.getConfigurationSection("keys")::getConfigurationSection)
|
||||||
|
.toList();
|
||||||
|
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");
|
||||||
|
LAVE_SPACE = tower.getInt("laveSpace");
|
||||||
|
|
||||||
|
MAP_MIN_X = config.getInt("minX");
|
||||||
|
MAP_MIN_Z = config.getInt("minZ");
|
||||||
|
MAP_MAX_X = config.getInt("maxX");
|
||||||
|
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");
|
||||||
|
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
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.towerrun.countdowns;
|
||||||
|
|
||||||
|
import de.steamwar.towerrun.TowerRun;
|
||||||
|
import de.steamwar.towerrun.state.GameStateToggleListener;
|
||||||
|
import de.steamwar.towerrun.state.GameStates;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.scheduler.BukkitTask;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
|
||||||
|
public abstract class Countdown extends GameStateToggleListener {
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
|
protected int time = defaultTime();
|
||||||
|
protected BukkitTask task;
|
||||||
|
|
||||||
|
protected Countdown(EnumSet<GameStates> enabledStates) {
|
||||||
|
super(enabledStates);
|
||||||
|
}
|
||||||
|
|
||||||
|
int defaultTime() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
void timerEnd() {}
|
||||||
|
boolean timerShouldCancel() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
void run() {}
|
||||||
|
void timerStart() {}
|
||||||
|
void timerReset() {}
|
||||||
|
|
||||||
|
private void timer() {
|
||||||
|
if (timerShouldCancel()) {
|
||||||
|
time = defaultTime();
|
||||||
|
timerReset();
|
||||||
|
} else {
|
||||||
|
if (time == defaultTime()) {
|
||||||
|
timerStart();
|
||||||
|
}
|
||||||
|
if (time == 0) {
|
||||||
|
timerEnd();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
run();
|
||||||
|
time--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enable() {
|
||||||
|
task = Bukkit.getScheduler().runTaskTimer(TowerRun.getInstance(), this::timer, 0, 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disable() {
|
||||||
|
task.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.towerrun.countdowns;
|
||||||
|
|
||||||
|
import de.steamwar.towerrun.TowerRun;
|
||||||
|
import de.steamwar.towerrun.game.TowerRunGame;
|
||||||
|
import de.steamwar.towerrun.state.GameStates;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class EndCountdown extends Countdown {
|
||||||
|
|
||||||
|
private final LobbyCountdown lobbyCountdown;
|
||||||
|
|
||||||
|
private static final boolean RESETS = Objects.requireNonNull(Bukkit.getWorlds().get(0).getWorldFolder().list((dir, name) -> name.equals("backup"))).length > 0;
|
||||||
|
|
||||||
|
public EndCountdown(LobbyCountdown lobbyCountdown) {
|
||||||
|
super(EnumSet.of(GameStates.ENDING));
|
||||||
|
this.lobbyCountdown = lobbyCountdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
int defaultTime() {
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void timerEnd() {
|
||||||
|
Bukkit.getOnlinePlayers().forEach(player -> player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_PLING, 1, 1));
|
||||||
|
if (RESETS) {
|
||||||
|
TowerRunGame.reset();
|
||||||
|
lobbyCountdown.setTime(lobbyCountdown.defaultTime());
|
||||||
|
} else {
|
||||||
|
Bukkit.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean timerShouldCancel() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void run() {
|
||||||
|
TowerRun.getMessage().broadcastActionbar(RESETS ? "SERVER_RESET" : "SERVER_STOPPING", time);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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.GameStates;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
|
||||||
|
public class GameCountdown extends Countdown {
|
||||||
|
|
||||||
|
public GameCountdown() {
|
||||||
|
super(EnumSet.of(GameStates.INGAME));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
int defaultTime() {
|
||||||
|
return Config.GAME_TIMER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void timerEnd() {
|
||||||
|
if (TowerRunGame.PLAYERS_ESCAPED.isEmpty()) {
|
||||||
|
TowerRunGame.tie();
|
||||||
|
} else {
|
||||||
|
TowerRunGame.win(TowerRunGame.PLAYERS_ESCAPED.get(TowerRunGame.PLAYERS_ESCAPED.size() - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean timerShouldCancel() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void run() {
|
||||||
|
int timeMinutes = Math.floorDiv(time, 60);
|
||||||
|
int timeSeconds = time % 60;
|
||||||
|
|
||||||
|
TowerRun.getMessage().broadcastActionbar("GAME_TIME", String.format("%02d", timeMinutes), String.format("%02d", timeSeconds));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disable() {
|
||||||
|
super.disable();
|
||||||
|
setTime(defaultTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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.GameStates;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Sound;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public class LobbyCountdown extends Countdown {
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
private boolean override = false;
|
||||||
|
|
||||||
|
public LobbyCountdown() {
|
||||||
|
super(EnumSet.of(GameStates.LOBBY));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
int defaultTime() {
|
||||||
|
return Config.LOBBY_TIMER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void timerEnd() {
|
||||||
|
TowerRunGame.prepareTowerOrStart();
|
||||||
|
override = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean timerShouldCancel() {
|
||||||
|
return !override && Bukkit.getOnlinePlayers().size() < Config.MIN_PLAYERS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void run() {
|
||||||
|
TowerRun.getMessage().broadcastActionbar("GAME_STARTING", time);
|
||||||
|
if (time < 10) {
|
||||||
|
Bukkit.getOnlinePlayers().forEach(player -> player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_PLING, 1, 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void timerReset() {
|
||||||
|
TowerRun.getMessage().broadcastActionbar("GAME_WAITING");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,184 @@
|
|||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.towerrun.game;
|
||||||
|
|
||||||
|
import de.steamwar.core.CraftbukkitWrapper;
|
||||||
|
import de.steamwar.towerrun.TowerRun;
|
||||||
|
import de.steamwar.towerrun.config.WorldConfig;
|
||||||
|
import de.steamwar.towerrun.state.GameState;
|
||||||
|
import de.steamwar.towerrun.state.GameStates;
|
||||||
|
import lombok.experimental.UtilityClass;
|
||||||
|
import net.minecraft.world.level.chunk.Chunk;
|
||||||
|
import org.bukkit.*;
|
||||||
|
import org.bukkit.craftbukkit.v1_19_R2.CraftWorld;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.ObjIntConsumer;
|
||||||
|
|
||||||
|
@UtilityClass
|
||||||
|
public class TowerRunGame {
|
||||||
|
public static final List<TowerRunPlayer> PLAYERS_ALIVE = new ArrayList<>();
|
||||||
|
public static final List<TowerRunPlayer> PLAYERS_ESCAPED = new ArrayList<>();
|
||||||
|
private static final World world = Bukkit.getWorlds().get(0);
|
||||||
|
|
||||||
|
public static boolean isAlive(TowerRunPlayer player) {
|
||||||
|
return PLAYERS_ALIVE.contains(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void prepareTowerOrStart() {
|
||||||
|
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.forEach(p -> {
|
||||||
|
p.reset();
|
||||||
|
p.player().setGameMode(GameMode.SURVIVAL);
|
||||||
|
});
|
||||||
|
GameState.nextState();
|
||||||
|
generateLava();
|
||||||
|
TowerRun.getMessage().broadcast("GAME_START");
|
||||||
|
|
||||||
|
for (Location door : WorldConfig.DOORS) {
|
||||||
|
door.getBlock().setType(Material.AIR);
|
||||||
|
door.clone().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 += 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);
|
||||||
|
if (Arrays.stream(WorldConfig.REGIONS).anyMatch(region -> region.contains(pos))) {
|
||||||
|
int offset = WorldConfig.LAVA_Y;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void remove(TowerRunPlayer towerRunPlayer) {
|
||||||
|
PLAYERS_ALIVE.remove(towerRunPlayer);
|
||||||
|
PLAYERS_ESCAPED.remove(towerRunPlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void tie() {
|
||||||
|
Bukkit.getOnlinePlayers().forEach(player -> player.setGameMode(GameMode.SPECTATOR));
|
||||||
|
PLAYERS_ALIVE.clear();
|
||||||
|
Bukkit.getOnlinePlayers().forEach(player -> player.sendTitle(TowerRun.getMessage().parse("GAME_TIE", player), "", 10, 70, 20));
|
||||||
|
GameState.nextState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void win(TowerRunPlayer tPlayer) {
|
||||||
|
Bukkit.getOnlinePlayers().forEach(player -> player.setGameMode(GameMode.SPECTATOR));
|
||||||
|
PLAYERS_ALIVE.clear();
|
||||||
|
tPlayer.player().setGameMode(GameMode.SPECTATOR);
|
||||||
|
TowerRun.getMessage().broadcast("GAME_WIN", tPlayer.player().getName());
|
||||||
|
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||||
|
player.sendTitle(TowerRun.getMessage().parse("GAME_WIN", player, tPlayer.player().getName()), "", 10, 70, 20);
|
||||||
|
player.playSound(player.getLocation(), Sound.ENTITY_ENDER_DRAGON_DEATH, 1, 1);
|
||||||
|
});
|
||||||
|
GameState.nextState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void reset() {
|
||||||
|
PLAYERS_ALIVE.clear();
|
||||||
|
PLAYERS_ESCAPED.clear();
|
||||||
|
resetWorld();
|
||||||
|
GameState.reset();
|
||||||
|
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||||
|
if (TowerRun.getTowerGenerator() != null) {
|
||||||
|
player.setGameMode(GameMode.SPECTATOR);
|
||||||
|
} else {
|
||||||
|
player.setGameMode(GameMode.SURVIVAL);
|
||||||
|
}
|
||||||
|
player.teleport(WorldConfig.SPAWN);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double posToChunk(int pos) {
|
||||||
|
return pos / 16.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getMinChunkX() {
|
||||||
|
return (int) Math.floor(posToChunk(WorldConfig.MAP_MIN_X));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getMaxChunkX() {
|
||||||
|
return (int) Math.ceil(posToChunk(WorldConfig.MAP_MAX_X));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getMinChunkZ() {
|
||||||
|
return (int) Math.floor(posToChunk(WorldConfig.MAP_MIN_Z));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getMaxChunkZ() {
|
||||||
|
return (int) Math.ceil(posToChunk(WorldConfig.MAP_MAX_Z));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void forEachChunk(ObjIntConsumer<Integer> executor) {
|
||||||
|
for (int x = getMinChunkX(); x <= getMaxChunkX(); x++)
|
||||||
|
for (int z = getMinChunkZ(); z <= getMaxChunkZ(); z++)
|
||||||
|
executor.accept(x, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void resetWorld() {
|
||||||
|
world.getEntities().stream().filter(entity -> entity.getType() != EntityType.PLAYER).forEach(Entity::remove);
|
||||||
|
|
||||||
|
World backup = new WorldCreator(world.getName() + "/backup").createWorld();
|
||||||
|
assert backup != null;
|
||||||
|
forEachChunk((x, z) -> resetChunk(backup, x, z));
|
||||||
|
Bukkit.unloadWorld(backup, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void resetChunk(World backup, int x, int z) {
|
||||||
|
Chunk chunk = ((CraftWorld) world).getHandle().d(x, z);
|
||||||
|
Chunk backupChunk = ((CraftWorld) backup).getHandle().d(x, z);
|
||||||
|
|
||||||
|
System.arraycopy(backupChunk.d(), 0, chunk.d(), 0, chunk.d().length);
|
||||||
|
|
||||||
|
for (Player p : Bukkit.getOnlinePlayers())
|
||||||
|
CraftbukkitWrapper.impl.sendChunk(p, x, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.towerrun.game;
|
||||||
|
|
||||||
|
import de.steamwar.towerrun.TowerRun;
|
||||||
|
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<Player, TowerRunPlayer> 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<TowerRunPlayer> getAll() {
|
||||||
|
return players.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "TowerRunPlayer{" +
|
||||||
|
"player=" + player.getName() +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,207 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
{
|
||||||
|
TowerGenerator.this.height = 0;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.towerrun.listener;
|
||||||
|
|
||||||
|
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.Location;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
|
import org.bukkit.event.player.PlayerMoveEvent;
|
||||||
|
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());
|
||||||
|
|
||||||
|
if(Bukkit.getOnlinePlayers().isEmpty() || (Bukkit.getOnlinePlayers().size() == 1 && Bukkit.getOnlinePlayers().stream().allMatch(player -> player == event.getPlayer()))) {
|
||||||
|
Bukkit.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerMove(PlayerMoveEvent event) {
|
||||||
|
Location to = event.getTo();
|
||||||
|
if (to.getX() > WorldConfig.MAP_MIN_X && to.getX() < WorldConfig.MAP_MAX_X && to.getZ() > WorldConfig.MAP_MIN_Z && to.getZ() < WorldConfig.MAP_MAX_Z && to.getY() > WorldConfig.ESCAPE_HEIGHT - 20) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,215 @@
|
|||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.towerrun.listener;
|
||||||
|
|
||||||
|
import de.steamwar.inventory.SWItem;
|
||||||
|
import de.steamwar.towerrun.TowerRun;
|
||||||
|
import de.steamwar.towerrun.config.Config;
|
||||||
|
import de.steamwar.towerrun.config.WorldConfig;
|
||||||
|
import de.steamwar.towerrun.game.TowerRunGame;
|
||||||
|
import de.steamwar.towerrun.state.GameStateBukkitListener;
|
||||||
|
import de.steamwar.towerrun.state.GameStates;
|
||||||
|
import org.bukkit.*;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.block.Action;
|
||||||
|
import org.bukkit.event.block.BlockBreakEvent;
|
||||||
|
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||||
|
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||||
|
import org.bukkit.event.entity.EntityRegainHealthEvent;
|
||||||
|
import org.bukkit.event.entity.ItemSpawnEvent;
|
||||||
|
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||||
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
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() {
|
||||||
|
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
|
||||||
|
public void onPlayerDeath(PlayerDeathEvent event) {
|
||||||
|
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 -> {
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onBlockBreak(BlockBreakEvent event) {
|
||||||
|
event.setDropItems(false);
|
||||||
|
if (!Config.DESTROYABLE_BLOCKS.contains(event.getBlock().getType())) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onKeyUse(PlayerInteractEvent event) {
|
||||||
|
if (!event.hasItem()) return;
|
||||||
|
if (event.getItem().getType() != Material.LEVER) return;
|
||||||
|
event.setCancelled(true);
|
||||||
|
if (!event.hasBlock()) return;
|
||||||
|
if (event.getClickedBlock().getType() != Material.IRON_DOOR) return;
|
||||||
|
event.getPlayer().getInventory().setItemInMainHand(null);
|
||||||
|
event.getClickedBlock().breakNaturally();
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onItemSpawn(ItemSpawnEvent event) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
|
||||||
|
if (event.getDamager().getType() == EntityType.PLAYER) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerInteract(PlayerInteractEvent event) {
|
||||||
|
if (event.getPlayer().getGameMode() != GameMode.SURVIVAL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.getAction() != Action.RIGHT_CLICK_BLOCK || !event.hasBlock()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.getClickedBlock().getType() != Material.CHEST) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.getPlayer().getInventory().addItem(new SWItem(Material.LEVER, TowerRun.getMessage().parse("KEY_NAME", event.getPlayer())).getItemStack());
|
||||||
|
|
||||||
|
event.getClickedBlock().setType(Material.ENDER_CHEST);
|
||||||
|
event.getPlayer().playSound(event.getPlayer().getLocation(), Sound.BLOCK_ENDER_CHEST_OPEN, 1, 1);
|
||||||
|
TowerRun.getMessage().broadcast("KEY_FOUND", event.getPlayer().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onBlockPhysics(BlockPhysicsEvent event) {
|
||||||
|
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
|
||||||
|
public void onEntityRegainHealth(EntityRegainHealthEvent event) {
|
||||||
|
if (event.getEntityType() == EntityType.PLAYER) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.towerrun.listener;
|
||||||
|
|
||||||
|
import de.steamwar.towerrun.TowerRun;
|
||||||
|
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();
|
||||||
|
if (TowerRun.getTowerGenerator() != null) {
|
||||||
|
player.teleport(TowerRun.getTowerGenerator().getSpawn());
|
||||||
|
player.setGameMode(GameMode.SPECTATOR);
|
||||||
|
} else {
|
||||||
|
player.teleport(WorldConfig.SPAWN);
|
||||||
|
player.setGameMode(GameMode.SURVIVAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerMove(PlayerMoveEvent event) {
|
||||||
|
if (TowerRun.getTowerGenerator() != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.towerrun.listener;
|
||||||
|
|
||||||
|
import de.steamwar.towerrun.TowerRun;
|
||||||
|
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.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);
|
||||||
|
if (TowerRun.getTowerGenerator() != null) {
|
||||||
|
event.getPlayer().teleport(TowerRun.getTowerGenerator().getSpawn());
|
||||||
|
} else {
|
||||||
|
event.getPlayer().teleport(WorldConfig.SPAWN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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<GameStateListener> 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void reset() {
|
||||||
|
final GameStates oldState = currentState;
|
||||||
|
currentState = GameStates.LOBBY;
|
||||||
|
gameStateChanges(oldState, currentState);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void gameStateChanges(GameStates oldState, GameStates newState) {
|
||||||
|
gameStateListeners.forEach(gameStateListener -> gameStateListener.onGameStateChange(oldState, newState));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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<GameStates> enabledStates) {
|
||||||
|
super(enabledStates);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enable() {
|
||||||
|
Bukkit.getPluginManager().registerEvents(this, TowerRun.getInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disable() {
|
||||||
|
HandlerList.unregisterAll(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.towerrun.state;
|
||||||
|
|
||||||
|
public abstract class GameStateListener {
|
||||||
|
|
||||||
|
protected GameStateListener() {
|
||||||
|
GameState.addGameStateListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void onGameStateChange(GameStates oldState, GameStates newState);
|
||||||
|
}
|
||||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.towerrun.state;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
|
||||||
|
public abstract class GameStateToggleListener extends GameStateListener {
|
||||||
|
|
||||||
|
private final EnumSet<GameStates> enabledStates;
|
||||||
|
|
||||||
|
protected GameStateToggleListener(EnumSet<GameStates> 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.towerrun.state;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public enum GameStates {
|
||||||
|
ENDING(null),
|
||||||
|
INGAME(ENDING),
|
||||||
|
GENERATING_TOWER(INGAME),
|
||||||
|
LOBBY(GENERATING_TOWER);
|
||||||
|
|
||||||
|
private final GameStates nextState;
|
||||||
|
}
|
||||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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.EventPriority;
|
||||||
|
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(priority = EventPriority.LOW)
|
||||||
|
public void onPlayerDeath(PlayerDeathEvent event) {
|
||||||
|
if (TowerRunGame.PLAYERS_ALIVE.isEmpty()) {
|
||||||
|
if (TowerRunGame.PLAYERS_ESCAPED.isEmpty()) {
|
||||||
|
TowerRunGame.tie();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
TowerRunGame.win(TowerRunGame.PLAYERS_ESCAPED.get(TowerRunGame.PLAYERS_ESCAPED.size() - 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.towerrun.winconditions;
|
||||||
|
|
||||||
|
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.EventPriority;
|
||||||
|
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||||
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
|
||||||
|
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);
|
||||||
|
TowerRunGame.PLAYERS_ESCAPED.remove(tPlayer);
|
||||||
|
tPlayer.player().setGameMode(GameMode.SPECTATOR);
|
||||||
|
if (TowerRunGame.PLAYERS_ALIVE.size() == 1 && TowerRunGame.PLAYERS_ESCAPED.isEmpty()) {
|
||||||
|
TowerRunGame.win(TowerRunGame.PLAYERS_ALIVE.get(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.LOW)
|
||||||
|
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||||
|
TowerRunPlayer tPlayer = TowerRunPlayer.get(event.getPlayer());
|
||||||
|
if (TowerRunGame.isAlive(tPlayer)) {
|
||||||
|
TowerRunGame.PLAYERS_ALIVE.remove(tPlayer);
|
||||||
|
TowerRunGame.PLAYERS_ESCAPED.remove(tPlayer);
|
||||||
|
if (TowerRunGame.PLAYERS_ALIVE.size() == 1 && TowerRunGame.PLAYERS_ESCAPED.isEmpty()) {
|
||||||
|
TowerRunGame.win(TowerRunGame.PLAYERS_ALIVE.get(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
* 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package de.steamwar.towerrun.winconditions;
|
||||||
|
|
||||||
|
import de.steamwar.towerrun.TowerRun;
|
||||||
|
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 org.bukkit.GameMode;
|
||||||
|
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.getTo().getY() - event.getFrom().getY() != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
onPlayerOutside(event.getPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void outside(TowerRunPlayer towerRunPlayer) {
|
||||||
|
TowerRunGame.PLAYERS_ESCAPED.add(towerRunPlayer);
|
||||||
|
TowerRunGame.PLAYERS_ALIVE.remove(towerRunPlayer);
|
||||||
|
towerRunPlayer.player().setGameMode(GameMode.SPECTATOR);
|
||||||
|
TowerRun.getMessage().broadcast("PLAYER_ESCAPE", towerRunPlayer.player().getName());
|
||||||
|
if (TowerRunGame.PLAYERS_ESCAPED.size() == 1) {
|
||||||
|
TowerRun.getGameCountdown().setTime(Config.GAME_ESCAPE_TIMER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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 {
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-1
@@ -27,6 +27,7 @@ include("LobbySystem_2")
|
|||||||
include("MissileWars")
|
include("MissileWars")
|
||||||
|
|
||||||
include("SpigotCore")
|
include("SpigotCore")
|
||||||
|
include("SpigotCore:CRIUDummy")
|
||||||
include("SpigotCore:SpigotCore_8")
|
include("SpigotCore:SpigotCore_8")
|
||||||
include("SpigotCore:SpigotCore_9")
|
include("SpigotCore:SpigotCore_9")
|
||||||
include("SpigotCore:SpigotCore_10")
|
include("SpigotCore:SpigotCore_10")
|
||||||
@@ -38,6 +39,7 @@ include("SpigotCore:SpigotCore_19")
|
|||||||
include("SpigotCore:SpigotCore_20")
|
include("SpigotCore:SpigotCore_20")
|
||||||
include("SpigotCore:SpigotCore_Main")
|
include("SpigotCore:SpigotCore_Main")
|
||||||
|
|
||||||
|
include("TowerRun")
|
||||||
|
|
||||||
include("VelocityCore")
|
include("VelocityCore")
|
||||||
include("VelocityCore:Persistent")
|
include("VelocityCore:Persistent")
|
||||||
include("SpigotCore:CRIUDummy")
|
|
||||||
|
|||||||
Reference in New Issue
Block a user