Compare commits
12 Commits
e5077b40c5
...
8718ca0918
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8718ca0918 | ||
|
|
728e8b7486 | ||
|
|
74cf3589c0 | ||
|
|
d7432c9b89 | ||
|
|
7ed4c20d29 | ||
|
|
33578027d3 | ||
|
|
a52efb9dbb | ||
|
|
72dc1af903 | ||
|
|
e93580bea9 | ||
|
|
53de0fe217 | ||
|
|
b8afe209bc | ||
|
|
be7b508667 |
|
|
@ -31,6 +31,8 @@ dependencies {
|
|||
implementation("com.fasterxml.jackson.core:jackson-databind:2.15.2")
|
||||
implementation("com.fasterxml.jackson.core:jackson-annotations:2.15.2")
|
||||
// End JSON config dependencies
|
||||
// WorldBorderAPI
|
||||
compileOnly("com.github.yannicklamprecht:worldborderapi:1.210.0:dev")
|
||||
}
|
||||
|
||||
tasks.test {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@ dependencyResolutionManagement {
|
|||
mavenLocal()
|
||||
mavenCentral()
|
||||
maven("https://repo.destro.xyz/snapshots") // Altitude - Galaxy
|
||||
maven { // WorldBorderAPI
|
||||
name = "eldonexus"
|
||||
url = uri("https://eldonexus.de/repository/maven-releases/")
|
||||
}
|
||||
}
|
||||
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,15 +11,19 @@ import com.alttd.ctf.events.SnowballEvent;
|
|||
import com.alttd.ctf.flag.Flag;
|
||||
import com.alttd.ctf.flag.FlagTryCaptureEvent;
|
||||
import com.alttd.ctf.game.GameManager;
|
||||
import com.alttd.ctf.gui.ClassSelectionGUI;
|
||||
import com.alttd.ctf.gui.GUIInventory;
|
||||
import com.alttd.ctf.gui.GUIListener;
|
||||
import com.alttd.ctf.json_config.JacksonConfig;
|
||||
import com.alttd.ctf.json_config.JsonConfigManager;
|
||||
import com.alttd.ctf.team.Team;
|
||||
import com.github.yannicklamprecht.worldborder.api.WorldBorderApi;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameRule;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.File;
|
||||
|
|
@ -35,24 +39,27 @@ public class Main extends JavaPlugin {
|
|||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
GUIInventory.setMain(this); // sorry
|
||||
ClassSelectionGUI.setMain(this); // sorry
|
||||
Package pkg = Main.class.getPackage();
|
||||
String version = pkg.getImplementationVersion();
|
||||
log.info("Plugin enabled, version {}", version);
|
||||
|
||||
reloadConfigs();
|
||||
this.gameManager = new GameManager();
|
||||
WorldBorderApi worldBorderApi = worldBorder();
|
||||
this.gameManager = new GameManager(worldBorderApi);
|
||||
registerTeams(); //Skipped in reloadConfig if gameManager is not created yet
|
||||
flag = new Flag(this, gameManager);
|
||||
CommandManager commandManager = new CommandManager(this, gameManager, flag);
|
||||
new CommandManager(this, gameManager, flag, worldBorderApi);
|
||||
//Ensuring immediate respawn is on in all worlds
|
||||
log.info("Enabling immediate respawn for {}.", Config.FLAG.world);
|
||||
World world = Bukkit.getWorld(Config.FLAG.world);
|
||||
log.info("Enabling immediate respawn for {}.", GameConfig.FLAG.world);
|
||||
World world = Bukkit.getWorld(GameConfig.FLAG.world);
|
||||
if (world != null) {
|
||||
world.setGameRule(GameRule.DO_IMMEDIATE_RESPAWN, true);
|
||||
} else {
|
||||
log.error("No valid flag world defined, unable to modify game rules");
|
||||
}
|
||||
registerEvents(flag);
|
||||
registerEvents(flag, worldBorderApi);
|
||||
}
|
||||
|
||||
public void reloadConfigs() {
|
||||
|
|
@ -64,12 +71,23 @@ public class Main extends JavaPlugin {
|
|||
}
|
||||
}
|
||||
|
||||
private void registerEvents(Flag flag) {
|
||||
private WorldBorderApi worldBorder() {
|
||||
RegisteredServiceProvider<WorldBorderApi> worldBorderApiRegisteredServiceProvider = getServer().getServicesManager().getRegistration(WorldBorderApi.class);
|
||||
|
||||
if (worldBorderApiRegisteredServiceProvider == null) {
|
||||
log.error("WorldBorder API not found, disabling plugin");
|
||||
getServer().getPluginManager().disablePlugin(this);
|
||||
return null;
|
||||
}
|
||||
|
||||
return worldBorderApiRegisteredServiceProvider.getProvider();
|
||||
}
|
||||
|
||||
private void registerEvents(Flag flag, WorldBorderApi worldBorderApi) {
|
||||
PluginManager pluginManager = getServer().getPluginManager();
|
||||
//TODO add event for player joining and clear their inv
|
||||
pluginManager.registerEvents(new SnowballEvent(gameManager), this);
|
||||
pluginManager.registerEvents(new FlagTryCaptureEvent(flag), this);
|
||||
pluginManager.registerEvents(new OnPlayerDeath(gameManager), this);
|
||||
pluginManager.registerEvents(new OnPlayerDeath(gameManager, worldBorderApi, this), this);
|
||||
pluginManager.registerEvents(new InventoryItemInteractionEvent(), this);
|
||||
pluginManager.registerEvents(new OnPlayerJoin(gameManager, flag), this);
|
||||
pluginManager.registerEvents(new GUIListener(), this);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import com.alttd.ctf.commands.subcommands.*;
|
|||
import com.alttd.ctf.config.Messages;
|
||||
import com.alttd.ctf.flag.Flag;
|
||||
import com.alttd.ctf.game.GameManager;
|
||||
import com.github.yannicklamprecht.worldborder.api.WorldBorderApi;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||
|
|
@ -22,7 +23,7 @@ import java.util.stream.Collectors;
|
|||
public class CommandManager implements CommandExecutor, TabExecutor {
|
||||
private final List<SubCommand> subCommands;
|
||||
|
||||
public CommandManager(Main main, GameManager gameManager, Flag flag) {
|
||||
public CommandManager(Main main, GameManager gameManager, Flag flag, WorldBorderApi worldBorderApi) {
|
||||
PluginCommand command = main.getCommand("ctf");
|
||||
if (command == null) {
|
||||
subCommands = null;
|
||||
|
|
@ -36,7 +37,7 @@ public class CommandManager implements CommandExecutor, TabExecutor {
|
|||
new ChangeTeam(gameManager),
|
||||
new Start(gameManager, flag),
|
||||
new CreateTeam(main, gameManager),
|
||||
new SelectClass(gameManager),
|
||||
new SelectClass(gameManager, worldBorderApi),
|
||||
new Reload(main)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ public class CreateTeam extends SubCommand {
|
|||
|
||||
int highestId = gameManager.getMaxTeamId();
|
||||
Team team = new Team(MiniMessage.miniMessage().deserialize(String.format("<color:%s>%s</color>", color, name)),
|
||||
highestId + 1, player.getLocation(), player.getLocation(), teamColor);
|
||||
highestId + 1, player.getLocation(), player.getLocation(), player.getLocation(), teamColor);
|
||||
|
||||
return consumer.apply(team);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,15 +5,13 @@ import com.alttd.ctf.config.Messages;
|
|||
import com.alttd.ctf.game.GameManager;
|
||||
import com.alttd.ctf.game.GamePhase;
|
||||
import com.alttd.ctf.game_class.GameClass;
|
||||
import com.alttd.ctf.game_class.creation.EngineerCreator;
|
||||
import com.alttd.ctf.game_class.creation.FighterCreator;
|
||||
import com.alttd.ctf.game_class.creation.TankCreator;
|
||||
import com.alttd.ctf.game_class.GameClassRetrieval;
|
||||
import com.alttd.ctf.gui.ClassSelectionGUI;
|
||||
import com.alttd.ctf.team.TeamPlayer;
|
||||
import com.github.yannicklamprecht.worldborder.api.WorldBorderApi;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
|
@ -22,15 +20,12 @@ public class SelectClass extends SubCommand {
|
|||
|
||||
private final GameManager gameManager;
|
||||
private final HashMap<Integer, List<GameClass>> gameClasses;
|
||||
private final WorldBorderApi worldBorderApi;
|
||||
|
||||
public SelectClass(GameManager gameManager) {
|
||||
public SelectClass(GameManager gameManager, WorldBorderApi worldBorderApi) {
|
||||
this.gameManager = gameManager;
|
||||
this.gameClasses = new HashMap<>();
|
||||
gameManager.getTeams().forEach(team -> {
|
||||
gameClasses.computeIfAbsent(team.getId(), teamId -> new ArrayList<>()).add(FighterCreator.createFighter(team.getColor()));
|
||||
gameClasses.computeIfAbsent(team.getId(), teamId -> new ArrayList<>()).add(TankCreator.createTank(team.getColor()));
|
||||
gameClasses.computeIfAbsent(team.getId(), teamId -> new ArrayList<>()).add(EngineerCreator.createEngineer(team.getColor()));
|
||||
});
|
||||
this.worldBorderApi = worldBorderApi;
|
||||
gameClasses = GameClassRetrieval.getGameClassesForAllTeams(gameManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -55,7 +50,7 @@ public class SelectClass extends SubCommand {
|
|||
commandSender.sendRichMessage("<red>You have to be near your spawn to change classes.</red>");
|
||||
return 0;
|
||||
}
|
||||
new ClassSelectionGUI(gameClasses.get(teamPlayer.getTeam().getId()), teamPlayer)
|
||||
new ClassSelectionGUI(gameClasses.get(teamPlayer.getTeam().getId()), teamPlayer, worldBorderApi, gamePhase)
|
||||
.open(player);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,21 +41,4 @@ public class Config extends AbstractConfig{
|
|||
}
|
||||
}
|
||||
|
||||
public static class FLAG {
|
||||
private static final String prefix = "flag.";
|
||||
|
||||
public static String world = "world";
|
||||
public static double x = 0;
|
||||
public static double y = 0;
|
||||
public static double z = 0;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static void load() {
|
||||
world = config.getString(prefix, "world", world);
|
||||
x = config.getDouble(prefix, "x", x);
|
||||
y = config.getDouble(prefix, "y", y);
|
||||
z = config.getDouble(prefix, "z", z);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import java.time.Duration;
|
|||
import java.util.HashMap;
|
||||
|
||||
@Slf4j
|
||||
public class GameConfig extends AbstractConfig{
|
||||
public class GameConfig extends AbstractConfig {
|
||||
|
||||
static GameConfig config;
|
||||
|
||||
|
|
@ -45,4 +45,67 @@ public class GameConfig extends AbstractConfig{
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static class WORLD_BORDER {
|
||||
private static final String prefix = "world-border.";
|
||||
|
||||
public static final double DEFAULT_SIZE = 140;
|
||||
private static final HashMap<GamePhase, WorldBorderSettings> GAME_PHASE_WORLD_BORDER = new HashMap<>();
|
||||
|
||||
public static HashMap<GamePhase, WorldBorderSettings> getGAME_PHASE_WORLD_BORDER() {
|
||||
return new HashMap<>(GAME_PHASE_WORLD_BORDER);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static void load() {
|
||||
GAME_PHASE_WORLD_BORDER.clear();
|
||||
for (GamePhase phase : GamePhase.values()) {
|
||||
String stringType = config.getString(prefix, phase.name().toLowerCase() + ".type", WorldBorderType.PLAYER.name());
|
||||
double size = config.getDouble(prefix, phase.name().toLowerCase() + ".size", 10);
|
||||
|
||||
WorldBorderType worldBorderType;
|
||||
try {
|
||||
worldBorderType = WorldBorderType.valueOf(stringType);
|
||||
} catch (IllegalArgumentException e) {
|
||||
log.error("Invalid world border type [{}] in game phase world border config", stringType);
|
||||
continue;
|
||||
}
|
||||
GAME_PHASE_WORLD_BORDER.put(phase, new WorldBorderSettings(worldBorderType, size));
|
||||
log.debug("Set {} phase world border type to {} blocks", phase.name(), size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class FLAG {
|
||||
private static final String prefix = "flag.";
|
||||
|
||||
public static String world = "world";
|
||||
public static double x = 0;
|
||||
public static double y = 0;
|
||||
public static double z = 0;
|
||||
public static double CAPTURE_RADIUS = 7;
|
||||
public static int WINNING_SCORE = 50;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static void load() {
|
||||
world = config.getString(prefix, "world", world);
|
||||
x = config.getDouble(prefix, "x", x);
|
||||
y = config.getDouble(prefix, "y", y);
|
||||
z = config.getDouble(prefix, "z", z);
|
||||
CAPTURE_RADIUS = config.getDouble(prefix, "capture-radius", CAPTURE_RADIUS);
|
||||
WINNING_SCORE = config.getInt(prefix, "winning-score", WINNING_SCORE);
|
||||
}
|
||||
}
|
||||
|
||||
public static class RESPAWN {
|
||||
private static final String prefix = "respawn.";
|
||||
|
||||
public static int TIME = 10;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static void load() {
|
||||
TIME = config.getInt(prefix, "time", TIME);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ public class Messages extends AbstractConfig {
|
|||
static Messages config;
|
||||
|
||||
Messages(Main main) {
|
||||
super(main, "config.yml");
|
||||
super(main, "messages.yml");
|
||||
}
|
||||
|
||||
public static void reload(Main main) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
package com.alttd.ctf.config;
|
||||
|
||||
public record WorldBorderSettings(WorldBorderType type, double size) {
|
||||
}
|
||||
6
src/main/java/com/alttd/ctf/config/WorldBorderType.java
Normal file
6
src/main/java/com/alttd/ctf/config/WorldBorderType.java
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
package com.alttd.ctf.config;
|
||||
|
||||
public enum WorldBorderType {
|
||||
FLAG,
|
||||
PLAYER
|
||||
}
|
||||
|
|
@ -1,7 +1,14 @@
|
|||
package com.alttd.ctf.events;
|
||||
|
||||
import com.alttd.ctf.Main;
|
||||
import com.alttd.ctf.config.Config;
|
||||
import com.alttd.ctf.config.GameConfig;
|
||||
import com.alttd.ctf.game.GameManager;
|
||||
import com.alttd.ctf.game.GamePhase;
|
||||
import com.alttd.ctf.team.TeamPlayer;
|
||||
import com.github.yannicklamprecht.worldborder.api.WorldBorderApi;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
|
|
@ -10,12 +17,17 @@ import org.bukkit.event.player.PlayerRespawnEvent;
|
|||
|
||||
import java.util.Optional;
|
||||
|
||||
@Slf4j
|
||||
public class OnPlayerDeath implements Listener {
|
||||
|
||||
private final GameManager gameManager;
|
||||
private final WorldBorderApi worldBorderApi;
|
||||
private final Main main;
|
||||
|
||||
public OnPlayerDeath(GameManager gameManager) {
|
||||
public OnPlayerDeath(GameManager gameManager, WorldBorderApi worldBorderApi, Main main) {
|
||||
this.gameManager = gameManager;
|
||||
this.worldBorderApi = worldBorderApi;
|
||||
this.main = main;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
|
@ -33,13 +45,18 @@ public class OnPlayerDeath implements Listener {
|
|||
@EventHandler
|
||||
public void onPlayerRespawn(PlayerRespawnEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
Optional<GamePhase> gamePhase = gameManager.getGamePhase();
|
||||
if (gamePhase.isEmpty()) {
|
||||
log.warn("Player {} died while the game wasn't running", player.getName());
|
||||
return;
|
||||
}
|
||||
Optional<TeamPlayer> optionalTeamPlayer = gameManager.getTeamPlayer(player.getUniqueId());
|
||||
if (optionalTeamPlayer.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
TeamPlayer teamPlayer = optionalTeamPlayer.get();
|
||||
event.setRespawnLocation(teamPlayer.getTeam().getSpawnLocation());
|
||||
teamPlayer.getGameClass().apply(teamPlayer);
|
||||
event.setRespawnLocation(player.getWorld().getSpawnLocation());
|
||||
Bukkit.getScheduler().runTaskLater(main, () -> teamPlayer.getGameClass().apply(teamPlayer, worldBorderApi, gamePhase.get(), true), GameConfig.RESPAWN.TIME * 20L);//10 x 20 ticks aka 10 seconds
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
package com.alttd.ctf.flag;
|
||||
|
||||
import com.alttd.ctf.Main;
|
||||
import com.alttd.ctf.config.Config;
|
||||
import com.alttd.ctf.config.GameConfig;
|
||||
import com.alttd.ctf.game.GameManager;
|
||||
import com.alttd.ctf.team.Team;
|
||||
import com.alttd.ctf.team.TeamColor;
|
||||
import com.alttd.ctf.team.TeamPlayer;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||
|
|
@ -20,31 +20,37 @@ import org.bukkit.boss.KeyedBossBar;
|
|||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.EquipmentSlot;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
public class Flag implements Runnable {
|
||||
|
||||
private final HashMap<Integer, Integer> teamFlagPointCount = new HashMap<>();
|
||||
private final ItemStack flagItem = new ItemStack(Material.CYAN_BANNER);
|
||||
private final ItemStack flagItem = new ItemStack(Material.BLACK_BANNER);
|
||||
private final BossBar bossBar = createBossBar();
|
||||
private final HashMap<Integer, Integer> wins = new HashMap<>();
|
||||
private int lastWinningTeamId = -1;
|
||||
private Location flagLocation;
|
||||
@Getter
|
||||
private final Location flagLocation;
|
||||
private Team winningTeam;
|
||||
private Player flagCarrier;
|
||||
|
||||
private final Main main;
|
||||
private final GameManager gameManager;
|
||||
|
||||
public Flag(Main main, GameManager gameManager) {
|
||||
this.main = main;
|
||||
this.gameManager = gameManager;
|
||||
World world = Bukkit.getWorld(GameConfig.FLAG.world);
|
||||
if (world == null) {
|
||||
throw new IllegalStateException(String.format("Tried to spawn flag in world [%s] that doesn't exist", GameConfig.FLAG.world));
|
||||
}
|
||||
this.flagLocation = new Location(world, GameConfig.FLAG.x, GameConfig.FLAG.y, GameConfig.FLAG.z);
|
||||
}
|
||||
|
||||
private BossBar createBossBar() {
|
||||
NamespacedKey namespacedKey = NamespacedKey.fromString("ctf_flag", main);
|
||||
if (namespacedKey == null) {
|
||||
|
|
@ -60,10 +66,6 @@ public class Flag implements Runnable {
|
|||
return captureProgress;
|
||||
}
|
||||
|
||||
protected Location getFlagLocation() {
|
||||
return flagLocation;
|
||||
}
|
||||
|
||||
public void addPlayer(Player player) {
|
||||
bossBar.addPlayer(player);
|
||||
}
|
||||
|
|
@ -85,13 +87,6 @@ public class Flag implements Runnable {
|
|||
}
|
||||
|
||||
public void spawnFlag() {
|
||||
//TODO disable flag capture for a minute or so, and maybe have it slowly drop down?
|
||||
World world = Bukkit.getWorld(Config.FLAG.world);
|
||||
if (world == null) {
|
||||
throw new IllegalStateException(String.format("Tried to spawn flag in world [%s] that doesn't exist", Config.FLAG.world));
|
||||
}
|
||||
this.flagLocation = new Location(world, Config.FLAG.x, Config.FLAG.y, Config.FLAG.z);
|
||||
//Place block on main thread
|
||||
Bukkit.getScheduler().runTask(main, () -> flagLocation.getBlock().setType(flagItem.getType()));
|
||||
}
|
||||
|
||||
|
|
@ -126,18 +121,18 @@ public class Flag implements Runnable {
|
|||
private void spawnParticlesOnSquareBorder(World world, Location center) {
|
||||
double size = 10;
|
||||
double step = 0.2;
|
||||
center.add(0, 0.5, 0);
|
||||
Location finalCenter = center.clone().add(0, 0.5, 0);
|
||||
Bukkit.getScheduler().runTask(main, () -> {
|
||||
// Top and Bottom (Z varies, X constant)
|
||||
for (double z = -size; z <= size; z += step) {
|
||||
world.spawnParticle(Particle.FLAME, center.getX() + size, center.getY(), center.getZ() + z, 1, 0, 0, 0, 0);
|
||||
world.spawnParticle(Particle.FLAME, center.getX() - size, center.getY(), center.getZ() + z, 1, 0, 0, 0, 0);
|
||||
world.spawnParticle(Particle.FLAME, finalCenter.getX() + size, finalCenter.getY(), finalCenter.getZ() + z, 1, 0, 0, 0, 0);
|
||||
world.spawnParticle(Particle.FLAME, finalCenter.getX() - size, finalCenter.getY(), finalCenter.getZ() + z, 1, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
// Left and Right (X varies, Z constant)
|
||||
for (double x = -size; x <= size; x += step) {
|
||||
world.spawnParticle(Particle.FLAME, center.getX() + x, center.getY(), center.getZ() + size, 1, 0, 0, 0, 0);
|
||||
world.spawnParticle(Particle.FLAME, center.getX() + x, center.getY(), center.getZ() - size, 1, 0, 0, 0, 0);
|
||||
world.spawnParticle(Particle.FLAME, finalCenter.getX() + x, finalCenter.getY(), finalCenter.getZ() + size, 1, 0, 0, 0, 0);
|
||||
world.spawnParticle(Particle.FLAME, finalCenter.getX() + x, finalCenter.getY(), finalCenter.getZ() - size, 1, 0, 0, 0, 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -160,8 +155,8 @@ public class Flag implements Runnable {
|
|||
spawnFlag();
|
||||
return;
|
||||
}
|
||||
double distance = winningTeam.getSpawnLocation().distance(flagCarrier.getLocation());
|
||||
if (distance > 5) {
|
||||
double distance = winningTeam.getFlagTurnInLocation().distance(flagCarrier.getLocation());
|
||||
if (distance > 2) {
|
||||
Location location = flagCarrier.getLocation();
|
||||
location.setY(location.getY() + 1);
|
||||
particleTrail.add(location);
|
||||
|
|
@ -194,7 +189,7 @@ public class Flag implements Runnable {
|
|||
if (max.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
if (max.get().getValue() < 100) {
|
||||
if (max.get().getValue() < GameConfig.FLAG.WINNING_SCORE) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return gameManager.getTeam(max.get().getKey());
|
||||
|
|
@ -209,7 +204,7 @@ public class Flag implements Runnable {
|
|||
private CompletableFuture<Boolean> updateScoreBasedOnNearbyPlayers() {
|
||||
CompletableFuture<Boolean> future = new CompletableFuture<>();
|
||||
Bukkit.getScheduler().runTask(main, () -> {
|
||||
Collection<Player> nearbyPlayers = flagLocation.getNearbyPlayers(10);
|
||||
Collection<Player> nearbyPlayers = flagLocation.getNearbyPlayers(GameConfig.FLAG.CAPTURE_RADIUS);
|
||||
Bukkit.getScheduler().runTaskAsynchronously(main, () -> {
|
||||
boolean result = updateScoreBasedOnNearbyPlayers(nearbyPlayers);
|
||||
future.complete(result);
|
||||
|
|
@ -288,7 +283,7 @@ public class Flag implements Runnable {
|
|||
bossBar.setTitle(String.format("Team %s is capturing the flag", PlainTextComponentSerializer.plainText().serialize(team.get().getName())));
|
||||
lastWinningTeamId = highestKey;
|
||||
}
|
||||
bossBar.setProgress(Math.min(100, teamFlagPointCount.get(highestKey)) / 100.0);
|
||||
bossBar.setProgress(Math.min(GameConfig.FLAG.WINNING_SCORE, teamFlagPointCount.get(highestKey)) / (double) GameConfig.FLAG.WINNING_SCORE);
|
||||
bossBar.setVisible(teamFlagPointCount.get(highestKey) > 0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import com.alttd.ctf.game.phases.GatheringPhase;
|
|||
import com.alttd.ctf.game_class.creation.FighterCreator;
|
||||
import com.alttd.ctf.team.Team;
|
||||
import com.alttd.ctf.team.TeamPlayer;
|
||||
import com.github.yannicklamprecht.worldborder.api.WorldBorderApi;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
|
@ -24,10 +25,10 @@ public class GameManager {
|
|||
private RunningGame runningGame;
|
||||
private final HashMap<Integer, Team> teams = new HashMap<>();
|
||||
|
||||
public GameManager() {
|
||||
public GameManager(WorldBorderApi worldBorderApi) {
|
||||
phases = new HashMap<>();
|
||||
phases.put(GamePhase.CLASS_SELECTION, new ClassSelectionPhase(this, (FighterCreator::createFighter)));
|
||||
phases.put(GamePhase.GATHERING, new GatheringPhase());
|
||||
phases.put(GamePhase.CLASS_SELECTION, new ClassSelectionPhase(this, FighterCreator::createFighter, worldBorderApi));
|
||||
phases.put(GamePhase.GATHERING, new GatheringPhase(this, worldBorderApi));
|
||||
phases.put(GamePhase.COMBAT, new CombatPhase());
|
||||
phases.put(GamePhase.ENDED, new EndedPhase());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,5 +6,5 @@ public interface GamePhaseExecutor {
|
|||
|
||||
void start(Flag flag);
|
||||
|
||||
void end();
|
||||
void end(GamePhase nextGamePhase);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,26 +33,31 @@ public class RunningGame implements Runnable {
|
|||
|
||||
@Override
|
||||
public void run() {
|
||||
GamePhase nextPhase = GamePhase.values().length < currentPhase.ordinal() ? null : GamePhase.values()[currentPhase.ordinal() + 1];
|
||||
if (phaseStartTime == null) {
|
||||
phaseStartTime = Instant.now();
|
||||
nextPhaseActions(null, currentPhase, nextPhase);
|
||||
}
|
||||
try {
|
||||
GamePhase nextPhase = GamePhase.values().length < currentPhase.ordinal() ? null : GamePhase.values()[currentPhase.ordinal() + 1];
|
||||
if (phaseStartTime == null) {
|
||||
phaseStartTime = Instant.now();
|
||||
nextPhaseActions(null, currentPhase, nextPhase);
|
||||
}
|
||||
|
||||
if (Duration.between(phaseStartTime, Instant.now()).compareTo(phaseDurations.get(currentPhase)) >= 0) {
|
||||
GamePhase previousPhase = currentPhase;
|
||||
currentPhase = GamePhase.values()[currentPhase.ordinal() + 1];
|
||||
nextPhaseActions(previousPhase, currentPhase, nextPhase);
|
||||
phaseStartTime = Instant.now();
|
||||
} else if (nextPhase != null) {
|
||||
broadcastNextPhaseStartTime(currentPhase, nextPhase);
|
||||
if (Duration.between(phaseStartTime, Instant.now()).compareTo(phaseDurations.get(currentPhase)) >= 0) {
|
||||
GamePhase previousPhase = currentPhase;
|
||||
currentPhase = GamePhase.values()[currentPhase.ordinal() + 1];
|
||||
nextPhaseActions(previousPhase, currentPhase, nextPhase);
|
||||
phaseStartTime = Instant.now();
|
||||
} else if (nextPhase != null) {
|
||||
broadcastNextPhaseStartTime(currentPhase, nextPhase);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Unexpected error in running game", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void nextPhaseActions(@Nullable GamePhase previousPhase, @NotNull GamePhase phase, @Nullable GamePhase nextPhase) {
|
||||
//TODO command to go to next phase
|
||||
if (previousPhase != null) {
|
||||
gameManager.getPhaseExecutor(previousPhase).end();
|
||||
gameManager.getPhaseExecutor(previousPhase).end(phase);
|
||||
}
|
||||
gameManager.getPhaseExecutor(phase).start(flag);
|
||||
if (nextPhase != null) {
|
||||
|
|
|
|||
|
|
@ -1,17 +1,24 @@
|
|||
package com.alttd.ctf.game.phases;
|
||||
|
||||
import com.alttd.ctf.config.GameConfig;
|
||||
import com.alttd.ctf.flag.Flag;
|
||||
import com.alttd.ctf.game.GameManager;
|
||||
import com.alttd.ctf.game.GamePhase;
|
||||
import com.alttd.ctf.game.GamePhaseExecutor;
|
||||
import com.alttd.ctf.game_class.GameClass;
|
||||
import com.alttd.ctf.team.Team;
|
||||
import com.alttd.ctf.team.TeamColor;
|
||||
import com.alttd.ctf.team.TeamPlayer;
|
||||
import com.alttd.ctf.util.CircularIterator;
|
||||
import com.github.yannicklamprecht.worldborder.api.IWorldBorder;
|
||||
import com.github.yannicklamprecht.worldborder.api.Position;
|
||||
import com.github.yannicklamprecht.worldborder.api.WorldBorderApi;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Optional;
|
||||
|
|
@ -21,24 +28,32 @@ public class ClassSelectionPhase implements GamePhaseExecutor {
|
|||
|
||||
private final GameManager gameManager;
|
||||
private final DefaultClassCreator defaultClassCreator;
|
||||
private final WorldBorderApi worldBorderApi;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface DefaultClassCreator {
|
||||
@NotNull GameClass apply(TeamColor teamColor);
|
||||
}
|
||||
|
||||
public ClassSelectionPhase(@NotNull GameManager gameManager, DefaultClassCreator defaultClassCreator) {
|
||||
public ClassSelectionPhase(@NotNull GameManager gameManager, DefaultClassCreator defaultClassCreator,
|
||||
@NotNull WorldBorderApi worldBorderApi) {
|
||||
this.gameManager = gameManager;
|
||||
this.defaultClassCreator = defaultClassCreator;
|
||||
this.worldBorderApi = worldBorderApi;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Flag flag) {
|
||||
teleportPlayersToStartingZone();
|
||||
Bukkit.broadcast(MiniMessage.miniMessage().deserialize("<green>Select your class</green>"));
|
||||
Location flagLocation = flag.getFlagLocation();
|
||||
IWorldBorder worldBorder = worldBorderApi.getWorldBorder(flagLocation.getWorld());
|
||||
worldBorder.setCenter(Position.of(flagLocation));
|
||||
worldBorder.setSize(GameConfig.WORLD_BORDER.DEFAULT_SIZE);
|
||||
|
||||
Bukkit.broadcast(MiniMessage.miniMessage().deserialize("<green>Select your class with <gold>/ctf selectclass</gold></green>"));
|
||||
CircularIterator<Team> teamCircularIterator = new CircularIterator<>(gameManager.getTeams());
|
||||
if (teamCircularIterator.hasNext()) {
|
||||
Bukkit.getOnlinePlayers().stream()
|
||||
.filter(player -> !player.hasPermission("ctf.bypass"))
|
||||
.filter(player -> gameManager.getTeamPlayer(player.getUniqueId()).isEmpty())
|
||||
.forEach(player -> {
|
||||
Team team = teamCircularIterator.next();
|
||||
|
|
@ -48,34 +63,41 @@ public class ClassSelectionPhase implements GamePhaseExecutor {
|
|||
} else {
|
||||
log.warn("No teams to add players to");
|
||||
}
|
||||
//TODO let players select classes
|
||||
// They should always be able to do this when in their starting zone
|
||||
// They should be locked into their starting zone until the next phase starts
|
||||
// That phase should handle opening the zone
|
||||
teleportPlayersToStartingZone();
|
||||
}
|
||||
|
||||
private void teleportPlayersToStartingZone() {
|
||||
Bukkit.getOnlinePlayers().forEach(player -> {
|
||||
Optional<Team> team = gameManager.getTeam(player.getUniqueId());
|
||||
if (team.isEmpty()) {
|
||||
Optional<TeamPlayer> teamPlayer = gameManager.getTeamPlayer(player.getUniqueId());
|
||||
if (teamPlayer.isEmpty()) {
|
||||
log.warn("{} is not a team player when teleporting to starting zone", player.getName());
|
||||
return;
|
||||
}
|
||||
Location spawnLocation = team.get().getSpawnLocation();
|
||||
player.teleportAsync(spawnLocation);
|
||||
Optional<GamePhase> gamePhase = gameManager.getGamePhase();
|
||||
if (gamePhase.isEmpty()) {
|
||||
log.warn("Game phase is empty when teleporting to starting zone");
|
||||
return;
|
||||
}
|
||||
teamPlayer.get().respawn(player, worldBorderApi, gamePhase.get());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end() {
|
||||
public void end(GamePhase nextPhase) {
|
||||
gameManager.getTeams().forEach(team -> {
|
||||
GameClass defaultClass = defaultClassCreator.apply(team.getColor());
|
||||
team.getPlayers().forEach(player -> {
|
||||
if (player.getGameClass() != null) {
|
||||
team.getPlayers().forEach(teamPlayer -> {
|
||||
Player player = Bukkit.getPlayer(teamPlayer.getUuid());
|
||||
if (player == null || !player.isOnline()) {
|
||||
log.debug("Tried to reset world border for offline player");
|
||||
return;
|
||||
}
|
||||
defaultClass.apply(player);
|
||||
teamPlayer.resetWorldBorder(player, worldBorderApi, nextPhase, team.getWorldBorderCenter());
|
||||
if (teamPlayer.getGameClass() != null) {
|
||||
return;
|
||||
}
|
||||
defaultClass.apply(teamPlayer, worldBorderApi, nextPhase, false);
|
||||
});
|
||||
});
|
||||
//TODO expand world border so ppl can gather things but not get near the flag yet
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.alttd.ctf.game.phases;
|
||||
|
||||
import com.alttd.ctf.flag.Flag;
|
||||
import com.alttd.ctf.game.GamePhase;
|
||||
import com.alttd.ctf.game.GamePhaseExecutor;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import org.bukkit.Bukkit;
|
||||
|
|
@ -28,7 +29,7 @@ public class CombatPhase implements GamePhaseExecutor {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void end() {
|
||||
public void end(GamePhase ignored) {
|
||||
executorService.shutdown();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
package com.alttd.ctf.game.phases;
|
||||
|
||||
import com.alttd.ctf.config.Config;
|
||||
import com.alttd.ctf.config.GameConfig;
|
||||
import com.alttd.ctf.flag.Flag;
|
||||
import com.alttd.ctf.game.GamePhase;
|
||||
import com.alttd.ctf.game.GamePhaseExecutor;
|
||||
import com.alttd.ctf.team.Team;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
|
@ -31,7 +32,7 @@ public class EndedPhase implements GamePhaseExecutor {
|
|||
HashMap<Team, Integer> wins = flag.getWins();
|
||||
Bukkit.broadcast(Component.join(JoinConfiguration.separator(Component.newline()), getWinnerMessages(wins)));
|
||||
new Thread(() -> {
|
||||
World world = Bukkit.getWorld(Config.FLAG.world);
|
||||
World world = Bukkit.getWorld(GameConfig.FLAG.world);
|
||||
if (world == null) {
|
||||
log.error("Invalid flag world defined");
|
||||
return;
|
||||
|
|
@ -101,7 +102,7 @@ public class EndedPhase implements GamePhaseExecutor {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void end() {
|
||||
public void end(GamePhase ignored) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,45 @@
|
|||
package com.alttd.ctf.game.phases;
|
||||
|
||||
import com.alttd.ctf.flag.Flag;
|
||||
import com.alttd.ctf.game.GameManager;
|
||||
import com.alttd.ctf.game.GamePhase;
|
||||
import com.alttd.ctf.game.GamePhaseExecutor;
|
||||
import com.alttd.ctf.game_class.GameClass;
|
||||
import com.github.yannicklamprecht.worldborder.api.WorldBorderApi;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
@Slf4j
|
||||
public class GatheringPhase implements GamePhaseExecutor {
|
||||
|
||||
private final GameManager gameManager;
|
||||
private final WorldBorderApi worldBorderApi;
|
||||
private Flag flag;
|
||||
|
||||
public GatheringPhase(GameManager gameManager, WorldBorderApi worldBorderApi) {
|
||||
this.gameManager = gameManager;
|
||||
this.worldBorderApi = worldBorderApi;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Flag flag) {
|
||||
this.flag = flag;
|
||||
Bukkit.broadcast(MiniMessage.miniMessage().deserialize("<green>Gather materials and prepare for combat!</green>"));
|
||||
//TODO give everyone haste or something so they can mine faster till this game phase ends
|
||||
// Let them store things at base during this phase, after only one class can do this?
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end() {
|
||||
//TODO Remove team area barrier
|
||||
public void end(GamePhase nextPhase) {
|
||||
if (flag == null) {
|
||||
log.error("Unable to update world border due to missing Flag");
|
||||
return;
|
||||
}
|
||||
gameManager.getTeams().forEach(team -> {
|
||||
team.getPlayers().forEach(player -> {
|
||||
player.resetWorldBorder(Bukkit.getPlayer(player.getUuid()), worldBorderApi, nextPhase, flag.getFlagLocation());
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
package com.alttd.ctf.game_class;
|
||||
|
||||
import com.alttd.ctf.game.GamePhase;
|
||||
import com.alttd.ctf.team.TeamColor;
|
||||
import com.alttd.ctf.team.TeamPlayer;
|
||||
import com.github.yannicklamprecht.worldborder.api.WorldBorderApi;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
|
@ -68,7 +70,7 @@ public abstract class GameClass {
|
|||
displayItem.setItemMeta(itemMeta);
|
||||
}
|
||||
|
||||
public void apply(TeamPlayer teamPlayer) {
|
||||
public void apply(TeamPlayer teamPlayer, WorldBorderApi worldBorderApi, GamePhase gamePhase, boolean teleport) {
|
||||
Player player = Bukkit.getPlayer(teamPlayer.getUuid());
|
||||
if (player == null || !player.isOnline()) {
|
||||
log.warn("Tried to give class to offline player {}", player == null ? teamPlayer.getUuid() : player.getName());
|
||||
|
|
@ -91,7 +93,7 @@ public abstract class GameClass {
|
|||
player.updateInventory();
|
||||
teamPlayer.setGameClass(this);
|
||||
player.sendRichMessage("You selected the <class_name> class", Placeholder.component("class_name", className));
|
||||
player.teleportAsync(teamPlayer.getTeam().getSpawnLocation());
|
||||
teamPlayer.respawn(player, worldBorderApi, gamePhase, teleport);
|
||||
}
|
||||
|
||||
private void setArmor(Player player, int r, int g, int b) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
package com.alttd.ctf.game_class;
|
||||
|
||||
import com.alttd.ctf.game.GameManager;
|
||||
import com.alttd.ctf.game_class.creation.EngineerCreator;
|
||||
import com.alttd.ctf.game_class.creation.FighterCreator;
|
||||
import com.alttd.ctf.game_class.creation.TankCreator;
|
||||
import com.alttd.ctf.team.Team;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class GameClassRetrieval {
|
||||
|
||||
public static HashMap<Integer, List<GameClass>> getGameClassesForAllTeams(GameManager gameManager) {
|
||||
final HashMap<Integer, List<GameClass>> gameClasses = new HashMap<>();
|
||||
gameManager.getTeams().forEach(team -> {
|
||||
gameClasses.put(team.getId(), getGameClassesForTeam(team));
|
||||
});
|
||||
return gameClasses;
|
||||
}
|
||||
|
||||
public static List<GameClass> getGameClassesForTeam(Team team) {
|
||||
final List<GameClass> gameClasses = new ArrayList<>();
|
||||
gameClasses.add(FighterCreator.createFighter(team.getColor()));
|
||||
gameClasses.add(TankCreator.createTank(team.getColor()));
|
||||
gameClasses.add(EngineerCreator.createEngineer(team.getColor()));
|
||||
return gameClasses;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,8 +1,13 @@
|
|||
package com.alttd.ctf.gui;
|
||||
|
||||
import com.alttd.ctf.Main;
|
||||
import com.alttd.ctf.game.GamePhase;
|
||||
import com.alttd.ctf.game_class.GameClass;
|
||||
import com.alttd.ctf.team.TeamPlayer;
|
||||
import com.github.yannicklamprecht.worldborder.api.WorldBorderApi;
|
||||
import lombok.Setter;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
|
@ -11,17 +16,21 @@ import java.util.List;
|
|||
|
||||
public class ClassSelectionGUI extends GUIInventory {
|
||||
|
||||
public ClassSelectionGUI(@NotNull List<GameClass> gameClasses, @NotNull TeamPlayer teamPlayer) {
|
||||
@Setter
|
||||
private static Main main;
|
||||
|
||||
public ClassSelectionGUI(@NotNull List<GameClass> gameClasses, @NotNull TeamPlayer teamPlayer,
|
||||
@NotNull WorldBorderApi worldBorderApi, @NotNull GamePhase gamePhase) {
|
||||
super(InventoryType.CHEST, teamPlayer.getTeam().getName().append(MiniMessage.miniMessage().deserialize(" - class selection")));
|
||||
createClassSelection(gameClasses, teamPlayer);
|
||||
createClassSelection(gameClasses, teamPlayer, worldBorderApi, gamePhase);
|
||||
}
|
||||
|
||||
private void createClassSelection(@NotNull List<GameClass> gameClasses, @NotNull TeamPlayer teamPlayer) {
|
||||
private void createClassSelection(@NotNull List<GameClass> gameClasses, @NotNull TeamPlayer teamPlayer, @NotNull WorldBorderApi worldBorderApi, @NotNull GamePhase gamePhase) {
|
||||
int pos = (9 + (9 - gameClasses.size()) / 2);
|
||||
for (GameClass gameClass : gameClasses) {
|
||||
setItem(pos++, gameClass.getDisplayItem(), player -> {
|
||||
gameClass.apply(teamPlayer);
|
||||
player.closeInventory(InventoryCloseEvent.Reason.PLUGIN);
|
||||
gameClass.apply(teamPlayer, worldBorderApi, gamePhase, true);
|
||||
Bukkit.getScheduler().runTask(main, () -> player.closeInventory(InventoryCloseEvent.Reason.PLUGIN));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,22 @@
|
|||
package com.alttd.ctf.gui;
|
||||
|
||||
import com.alttd.ctf.Main;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.Merchant;
|
||||
import org.bukkit.inventory.MerchantInventory;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public abstract class GUIInventory implements GUI {
|
||||
|
||||
@Setter
|
||||
private static Main main;
|
||||
|
||||
@Getter
|
||||
protected final Inventory inventory;
|
||||
protected final HashMap<Integer, GUIAction> guiActions;
|
||||
|
|
@ -35,7 +38,7 @@ public abstract class GUIInventory implements GUI {
|
|||
}
|
||||
|
||||
public void open(Player player) {
|
||||
player.openInventory(inventory);
|
||||
Bukkit.getScheduler().runTask(main, () -> player.openInventory(inventory));
|
||||
GUIByUUID.put(player.getUniqueId(), this);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,11 @@ public class Team {
|
|||
@JsonProperty("worldBorderCenter")
|
||||
@NotNull
|
||||
@Getter
|
||||
private Location worldBorderCenter; //TODO https://github.com/yannicklamprecht/WorldBorderAPI/blob/main/how-to-use.md
|
||||
private Location worldBorderCenter; // https://github.com/yannicklamprecht/WorldBorderAPI/blob/main/how-to-use.md
|
||||
@JsonProperty("flagTurnInLocation")
|
||||
@NotNull
|
||||
@Getter
|
||||
private Location flagTurnInLocation;
|
||||
@JsonProperty("teamColor")
|
||||
@NotNull
|
||||
@Getter
|
||||
|
|
|
|||
|
|
@ -1,12 +1,23 @@
|
|||
package com.alttd.ctf.team;
|
||||
|
||||
import com.alttd.ctf.config.GameConfig;
|
||||
import com.alttd.ctf.config.WorldBorderSettings;
|
||||
import com.alttd.ctf.config.WorldBorderType;
|
||||
import com.alttd.ctf.game.GamePhase;
|
||||
import com.alttd.ctf.game_class.GameClass;
|
||||
import com.alttd.ctf.game_class.GameClassRetrieval;
|
||||
import com.alttd.ctf.gui.ClassSelectionGUI;
|
||||
import com.github.yannicklamprecht.worldborder.api.WorldBorderApi;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
|
||||
@Slf4j
|
||||
@Getter
|
||||
public class TeamPlayer {
|
||||
|
||||
|
|
@ -20,6 +31,37 @@ public class TeamPlayer {
|
|||
this.team = team;
|
||||
}
|
||||
|
||||
public void respawn(@NotNull Player player, @NotNull WorldBorderApi worldBorderApi, @NotNull GamePhase gamePhase) {
|
||||
respawn(player, worldBorderApi, gamePhase, true);
|
||||
}
|
||||
|
||||
public void respawn(Player player, WorldBorderApi worldBorderApi, GamePhase gamePhase, boolean teleport) {
|
||||
Location spawnLocation = team.getSpawnLocation();
|
||||
Location worldBorderCenter = team.getWorldBorderCenter();
|
||||
|
||||
List<GameClass> gameClasses = GameClassRetrieval.getGameClassesForTeam(team);
|
||||
new ClassSelectionGUI(gameClasses, this, worldBorderApi, GamePhase.CLASS_SELECTION).open(player);
|
||||
|
||||
if (!teleport) {
|
||||
resetWorldBorder(player, worldBorderApi, gamePhase, worldBorderCenter);
|
||||
return;
|
||||
}
|
||||
player.teleportAsync(spawnLocation).thenAcceptAsync(unused ->
|
||||
resetWorldBorder(player, worldBorderApi, gamePhase, worldBorderCenter));
|
||||
}
|
||||
|
||||
public void resetWorldBorder(Player player, WorldBorderApi worldBorderApi, GamePhase gamePhase, Location worldBorderCenter) {
|
||||
WorldBorderSettings worldBorderSettings = GameConfig.WORLD_BORDER.getGAME_PHASE_WORLD_BORDER().get(gamePhase);
|
||||
if (worldBorderSettings == null) {
|
||||
throw new IllegalStateException("All phases need to have world border settings");
|
||||
}
|
||||
if (worldBorderSettings.type().equals(WorldBorderType.FLAG)) {
|
||||
worldBorderApi.resetWorldBorderToGlobal(player);
|
||||
return;
|
||||
}
|
||||
worldBorderApi.setBorder(player, worldBorderSettings.size(), worldBorderCenter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
#Sat Feb 08 00:30:51 CET 2025
|
||||
buildNumber=11
|
||||
#Sat Feb 08 21:57:04 CET 2025
|
||||
buildNumber=30
|
||||
version=0.1
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user