forked from SteamWar/SteamWar
199 lines
7.4 KiB
Java
199 lines
7.4 KiB
Java
/*
|
|
* 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.sql.SteamwarUser;
|
|
import de.steamwar.towerrun.TowerRun;
|
|
import de.steamwar.towerrun.config.Config;
|
|
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 isEscaped(TowerRunPlayer player) {
|
|
return PLAYERS_ESCAPED.contains(player);
|
|
}
|
|
|
|
public static boolean isAlive(TowerRunPlayer player) {
|
|
return PLAYERS_ALIVE.contains(player);
|
|
}
|
|
|
|
public static void prepareTowerOrStart() {
|
|
if (GameState.getCurrentState() == GameStates.WAITING) {
|
|
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.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();
|
|
|
|
if (Config.event()) {
|
|
Config.EVENT_FIGHT.setErgebnis(3);
|
|
}
|
|
}
|
|
|
|
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();
|
|
|
|
if (Config.event()) {
|
|
Config.EVENT_FIGHT.setErgebnis(SteamwarUser.get(tPlayer.player().getUniqueId()).getTeam() == Config.EVENT_TEAM_BLUE_ID ? 1 : 2);
|
|
}
|
|
}
|
|
|
|
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);
|
|
PLAYERS_ALIVE.add(TowerRunPlayer.get(player));
|
|
});
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|