Compare commits

..

No commits in common. "8718ca091875f0c1e658d86cc14ca5e51b42f206" and "e5077b40c53272cb77707762580beb16285eebf4" have entirely different histories.

27 changed files with 129 additions and 363 deletions

View File

@ -31,8 +31,6 @@ dependencies {
implementation("com.fasterxml.jackson.core:jackson-databind:2.15.2") implementation("com.fasterxml.jackson.core:jackson-databind:2.15.2")
implementation("com.fasterxml.jackson.core:jackson-annotations:2.15.2") implementation("com.fasterxml.jackson.core:jackson-annotations:2.15.2")
// End JSON config dependencies // End JSON config dependencies
// WorldBorderAPI
compileOnly("com.github.yannicklamprecht:worldborderapi:1.210.0:dev")
} }
tasks.test { tasks.test {

View File

@ -5,10 +5,6 @@ dependencyResolutionManagement {
mavenLocal() mavenLocal()
mavenCentral() mavenCentral()
maven("https://repo.destro.xyz/snapshots") // Altitude - Galaxy 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) repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
} }

View File

@ -11,19 +11,15 @@ import com.alttd.ctf.events.SnowballEvent;
import com.alttd.ctf.flag.Flag; import com.alttd.ctf.flag.Flag;
import com.alttd.ctf.flag.FlagTryCaptureEvent; import com.alttd.ctf.flag.FlagTryCaptureEvent;
import com.alttd.ctf.game.GameManager; 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.gui.GUIListener;
import com.alttd.ctf.json_config.JacksonConfig; import com.alttd.ctf.json_config.JacksonConfig;
import com.alttd.ctf.json_config.JsonConfigManager; import com.alttd.ctf.json_config.JsonConfigManager;
import com.alttd.ctf.team.Team; import com.alttd.ctf.team.Team;
import com.github.yannicklamprecht.worldborder.api.WorldBorderApi;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.GameRule; import org.bukkit.GameRule;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import java.io.File; import java.io.File;
@ -39,27 +35,24 @@ public class Main extends JavaPlugin {
@Override @Override
public void onEnable() { public void onEnable() {
GUIInventory.setMain(this); // sorry
ClassSelectionGUI.setMain(this); // sorry
Package pkg = Main.class.getPackage(); Package pkg = Main.class.getPackage();
String version = pkg.getImplementationVersion(); String version = pkg.getImplementationVersion();
log.info("Plugin enabled, version {}", version); log.info("Plugin enabled, version {}", version);
reloadConfigs(); reloadConfigs();
WorldBorderApi worldBorderApi = worldBorder(); this.gameManager = new GameManager();
this.gameManager = new GameManager(worldBorderApi);
registerTeams(); //Skipped in reloadConfig if gameManager is not created yet registerTeams(); //Skipped in reloadConfig if gameManager is not created yet
flag = new Flag(this, gameManager); flag = new Flag(this, gameManager);
new CommandManager(this, gameManager, flag, worldBorderApi); CommandManager commandManager = new CommandManager(this, gameManager, flag);
//Ensuring immediate respawn is on in all worlds //Ensuring immediate respawn is on in all worlds
log.info("Enabling immediate respawn for {}.", GameConfig.FLAG.world); log.info("Enabling immediate respawn for {}.", Config.FLAG.world);
World world = Bukkit.getWorld(GameConfig.FLAG.world); World world = Bukkit.getWorld(Config.FLAG.world);
if (world != null) { if (world != null) {
world.setGameRule(GameRule.DO_IMMEDIATE_RESPAWN, true); world.setGameRule(GameRule.DO_IMMEDIATE_RESPAWN, true);
} else { } else {
log.error("No valid flag world defined, unable to modify game rules"); log.error("No valid flag world defined, unable to modify game rules");
} }
registerEvents(flag, worldBorderApi); registerEvents(flag);
} }
public void reloadConfigs() { public void reloadConfigs() {
@ -71,23 +64,12 @@ public class Main extends JavaPlugin {
} }
} }
private WorldBorderApi worldBorder() { private void registerEvents(Flag flag) {
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(); PluginManager pluginManager = getServer().getPluginManager();
//TODO add event for player joining and clear their inv
pluginManager.registerEvents(new SnowballEvent(gameManager), this); pluginManager.registerEvents(new SnowballEvent(gameManager), this);
pluginManager.registerEvents(new FlagTryCaptureEvent(flag), this); pluginManager.registerEvents(new FlagTryCaptureEvent(flag), this);
pluginManager.registerEvents(new OnPlayerDeath(gameManager, worldBorderApi, this), this); pluginManager.registerEvents(new OnPlayerDeath(gameManager), this);
pluginManager.registerEvents(new InventoryItemInteractionEvent(), this); pluginManager.registerEvents(new InventoryItemInteractionEvent(), this);
pluginManager.registerEvents(new OnPlayerJoin(gameManager, flag), this); pluginManager.registerEvents(new OnPlayerJoin(gameManager, flag), this);
pluginManager.registerEvents(new GUIListener(), this); pluginManager.registerEvents(new GUIListener(), this);

View File

@ -5,7 +5,6 @@ import com.alttd.ctf.commands.subcommands.*;
import com.alttd.ctf.config.Messages; import com.alttd.ctf.config.Messages;
import com.alttd.ctf.flag.Flag; import com.alttd.ctf.flag.Flag;
import com.alttd.ctf.game.GameManager; import com.alttd.ctf.game.GameManager;
import com.github.yannicklamprecht.worldborder.api.WorldBorderApi;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
@ -23,7 +22,7 @@ import java.util.stream.Collectors;
public class CommandManager implements CommandExecutor, TabExecutor { public class CommandManager implements CommandExecutor, TabExecutor {
private final List<SubCommand> subCommands; private final List<SubCommand> subCommands;
public CommandManager(Main main, GameManager gameManager, Flag flag, WorldBorderApi worldBorderApi) { public CommandManager(Main main, GameManager gameManager, Flag flag) {
PluginCommand command = main.getCommand("ctf"); PluginCommand command = main.getCommand("ctf");
if (command == null) { if (command == null) {
subCommands = null; subCommands = null;
@ -37,7 +36,7 @@ public class CommandManager implements CommandExecutor, TabExecutor {
new ChangeTeam(gameManager), new ChangeTeam(gameManager),
new Start(gameManager, flag), new Start(gameManager, flag),
new CreateTeam(main, gameManager), new CreateTeam(main, gameManager),
new SelectClass(gameManager, worldBorderApi), new SelectClass(gameManager),
new Reload(main) new Reload(main)
); );
} }

View File

@ -75,7 +75,7 @@ public class CreateTeam extends SubCommand {
int highestId = gameManager.getMaxTeamId(); int highestId = gameManager.getMaxTeamId();
Team team = new Team(MiniMessage.miniMessage().deserialize(String.format("<color:%s>%s</color>", color, name)), Team team = new Team(MiniMessage.miniMessage().deserialize(String.format("<color:%s>%s</color>", color, name)),
highestId + 1, player.getLocation(), player.getLocation(), player.getLocation(), teamColor); highestId + 1, player.getLocation(), player.getLocation(), teamColor);
return consumer.apply(team); return consumer.apply(team);
} }

View File

@ -5,13 +5,15 @@ import com.alttd.ctf.config.Messages;
import com.alttd.ctf.game.GameManager; import com.alttd.ctf.game.GameManager;
import com.alttd.ctf.game.GamePhase; import com.alttd.ctf.game.GamePhase;
import com.alttd.ctf.game_class.GameClass; import com.alttd.ctf.game_class.GameClass;
import com.alttd.ctf.game_class.GameClassRetrieval; 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.gui.ClassSelectionGUI; import com.alttd.ctf.gui.ClassSelectionGUI;
import com.alttd.ctf.team.TeamPlayer; import com.alttd.ctf.team.TeamPlayer;
import com.github.yannicklamprecht.worldborder.api.WorldBorderApi;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@ -20,12 +22,15 @@ public class SelectClass extends SubCommand {
private final GameManager gameManager; private final GameManager gameManager;
private final HashMap<Integer, List<GameClass>> gameClasses; private final HashMap<Integer, List<GameClass>> gameClasses;
private final WorldBorderApi worldBorderApi;
public SelectClass(GameManager gameManager, WorldBorderApi worldBorderApi) { public SelectClass(GameManager gameManager) {
this.gameManager = gameManager; this.gameManager = gameManager;
this.worldBorderApi = worldBorderApi; this.gameClasses = new HashMap<>();
gameClasses = GameClassRetrieval.getGameClassesForAllTeams(gameManager); 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()));
});
} }
@Override @Override
@ -50,7 +55,7 @@ public class SelectClass extends SubCommand {
commandSender.sendRichMessage("<red>You have to be near your spawn to change classes.</red>"); commandSender.sendRichMessage("<red>You have to be near your spawn to change classes.</red>");
return 0; return 0;
} }
new ClassSelectionGUI(gameClasses.get(teamPlayer.getTeam().getId()), teamPlayer, worldBorderApi, gamePhase) new ClassSelectionGUI(gameClasses.get(teamPlayer.getTeam().getId()), teamPlayer)
.open(player); .open(player);
return 0; return 0;
} }

View File

@ -41,4 +41,21 @@ 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);
}
}
} }

View File

@ -8,7 +8,7 @@ import java.time.Duration;
import java.util.HashMap; import java.util.HashMap;
@Slf4j @Slf4j
public class GameConfig extends AbstractConfig { public class GameConfig extends AbstractConfig{
static GameConfig config; static GameConfig config;
@ -45,67 +45,4 @@ 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);
}
}
} }

View File

@ -8,7 +8,7 @@ public class Messages extends AbstractConfig {
static Messages config; static Messages config;
Messages(Main main) { Messages(Main main) {
super(main, "messages.yml"); super(main, "config.yml");
} }
public static void reload(Main main) { public static void reload(Main main) {

View File

@ -1,4 +0,0 @@
package com.alttd.ctf.config;
public record WorldBorderSettings(WorldBorderType type, double size) {
}

View File

@ -1,6 +0,0 @@
package com.alttd.ctf.config;
public enum WorldBorderType {
FLAG,
PLAYER
}

View File

@ -1,14 +1,7 @@
package com.alttd.ctf.events; 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.GameManager;
import com.alttd.ctf.game.GamePhase;
import com.alttd.ctf.team.TeamPlayer; 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.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
@ -17,17 +10,12 @@ import org.bukkit.event.player.PlayerRespawnEvent;
import java.util.Optional; import java.util.Optional;
@Slf4j
public class OnPlayerDeath implements Listener { public class OnPlayerDeath implements Listener {
private final GameManager gameManager; private final GameManager gameManager;
private final WorldBorderApi worldBorderApi;
private final Main main;
public OnPlayerDeath(GameManager gameManager, WorldBorderApi worldBorderApi, Main main) { public OnPlayerDeath(GameManager gameManager) {
this.gameManager = gameManager; this.gameManager = gameManager;
this.worldBorderApi = worldBorderApi;
this.main = main;
} }
@EventHandler @EventHandler
@ -45,18 +33,13 @@ public class OnPlayerDeath implements Listener {
@EventHandler @EventHandler
public void onPlayerRespawn(PlayerRespawnEvent event) { public void onPlayerRespawn(PlayerRespawnEvent event) {
Player player = event.getPlayer(); 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()); Optional<TeamPlayer> optionalTeamPlayer = gameManager.getTeamPlayer(player.getUniqueId());
if (optionalTeamPlayer.isEmpty()) { if (optionalTeamPlayer.isEmpty()) {
return; return;
} }
TeamPlayer teamPlayer = optionalTeamPlayer.get(); TeamPlayer teamPlayer = optionalTeamPlayer.get();
event.setRespawnLocation(player.getWorld().getSpawnLocation()); event.setRespawnLocation(teamPlayer.getTeam().getSpawnLocation());
Bukkit.getScheduler().runTaskLater(main, () -> teamPlayer.getGameClass().apply(teamPlayer, worldBorderApi, gamePhase.get(), true), GameConfig.RESPAWN.TIME * 20L);//10 x 20 ticks aka 10 seconds teamPlayer.getGameClass().apply(teamPlayer);
} }
} }

View File

@ -1,12 +1,12 @@
package com.alttd.ctf.flag; package com.alttd.ctf.flag;
import com.alttd.ctf.Main; import com.alttd.ctf.Main;
import com.alttd.ctf.config.GameConfig; import com.alttd.ctf.config.Config;
import com.alttd.ctf.game.GameManager; import com.alttd.ctf.game.GameManager;
import com.alttd.ctf.team.Team; import com.alttd.ctf.team.Team;
import com.alttd.ctf.team.TeamColor; import com.alttd.ctf.team.TeamColor;
import com.alttd.ctf.team.TeamPlayer; import com.alttd.ctf.team.TeamPlayer;
import lombok.Getter; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
@ -20,37 +20,31 @@ import org.bukkit.boss.KeyedBossBar;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scheduler.BukkitScheduler;
import java.util.*; import java.util.*;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Future;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Slf4j @Slf4j
@RequiredArgsConstructor
public class Flag implements Runnable { public class Flag implements Runnable {
private final HashMap<Integer, Integer> teamFlagPointCount = new HashMap<>(); private final HashMap<Integer, Integer> teamFlagPointCount = new HashMap<>();
private final ItemStack flagItem = new ItemStack(Material.BLACK_BANNER); private final ItemStack flagItem = new ItemStack(Material.CYAN_BANNER);
private final BossBar bossBar = createBossBar(); private final BossBar bossBar = createBossBar();
private final HashMap<Integer, Integer> wins = new HashMap<>(); private final HashMap<Integer, Integer> wins = new HashMap<>();
private int lastWinningTeamId = -1; private int lastWinningTeamId = -1;
@Getter private Location flagLocation;
private final Location flagLocation;
private Team winningTeam; private Team winningTeam;
private Player flagCarrier; private Player flagCarrier;
private final Main main; private final Main main;
private final GameManager gameManager; 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() { private BossBar createBossBar() {
NamespacedKey namespacedKey = NamespacedKey.fromString("ctf_flag", main); NamespacedKey namespacedKey = NamespacedKey.fromString("ctf_flag", main);
if (namespacedKey == null) { if (namespacedKey == null) {
@ -66,6 +60,10 @@ public class Flag implements Runnable {
return captureProgress; return captureProgress;
} }
protected Location getFlagLocation() {
return flagLocation;
}
public void addPlayer(Player player) { public void addPlayer(Player player) {
bossBar.addPlayer(player); bossBar.addPlayer(player);
} }
@ -87,6 +85,13 @@ public class Flag implements Runnable {
} }
public void spawnFlag() { 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())); Bukkit.getScheduler().runTask(main, () -> flagLocation.getBlock().setType(flagItem.getType()));
} }
@ -121,18 +126,18 @@ public class Flag implements Runnable {
private void spawnParticlesOnSquareBorder(World world, Location center) { private void spawnParticlesOnSquareBorder(World world, Location center) {
double size = 10; double size = 10;
double step = 0.2; double step = 0.2;
Location finalCenter = center.clone().add(0, 0.5, 0); center.add(0, 0.5, 0);
Bukkit.getScheduler().runTask(main, () -> { Bukkit.getScheduler().runTask(main, () -> {
// Top and Bottom (Z varies, X constant) // Top and Bottom (Z varies, X constant)
for (double z = -size; z <= size; z += step) { for (double z = -size; z <= size; z += step) {
world.spawnParticle(Particle.FLAME, finalCenter.getX() + size, finalCenter.getY(), finalCenter.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, center.getX() - size, center.getY(), center.getZ() + z, 1, 0, 0, 0, 0);
} }
// Left and Right (X varies, Z constant) // Left and Right (X varies, Z constant)
for (double x = -size; x <= size; x += step) { for (double x = -size; x <= size; x += step) {
world.spawnParticle(Particle.FLAME, finalCenter.getX() + x, finalCenter.getY(), finalCenter.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, center.getX() + x, center.getY(), center.getZ() - size, 1, 0, 0, 0, 0);
} }
}); });
} }
@ -155,8 +160,8 @@ public class Flag implements Runnable {
spawnFlag(); spawnFlag();
return; return;
} }
double distance = winningTeam.getFlagTurnInLocation().distance(flagCarrier.getLocation()); double distance = winningTeam.getSpawnLocation().distance(flagCarrier.getLocation());
if (distance > 2) { if (distance > 5) {
Location location = flagCarrier.getLocation(); Location location = flagCarrier.getLocation();
location.setY(location.getY() + 1); location.setY(location.getY() + 1);
particleTrail.add(location); particleTrail.add(location);
@ -189,7 +194,7 @@ public class Flag implements Runnable {
if (max.isEmpty()) { if (max.isEmpty()) {
return Optional.empty(); return Optional.empty();
} }
if (max.get().getValue() < GameConfig.FLAG.WINNING_SCORE) { if (max.get().getValue() < 100) {
return Optional.empty(); return Optional.empty();
} }
return gameManager.getTeam(max.get().getKey()); return gameManager.getTeam(max.get().getKey());
@ -204,7 +209,7 @@ public class Flag implements Runnable {
private CompletableFuture<Boolean> updateScoreBasedOnNearbyPlayers() { private CompletableFuture<Boolean> updateScoreBasedOnNearbyPlayers() {
CompletableFuture<Boolean> future = new CompletableFuture<>(); CompletableFuture<Boolean> future = new CompletableFuture<>();
Bukkit.getScheduler().runTask(main, () -> { Bukkit.getScheduler().runTask(main, () -> {
Collection<Player> nearbyPlayers = flagLocation.getNearbyPlayers(GameConfig.FLAG.CAPTURE_RADIUS); Collection<Player> nearbyPlayers = flagLocation.getNearbyPlayers(10);
Bukkit.getScheduler().runTaskAsynchronously(main, () -> { Bukkit.getScheduler().runTaskAsynchronously(main, () -> {
boolean result = updateScoreBasedOnNearbyPlayers(nearbyPlayers); boolean result = updateScoreBasedOnNearbyPlayers(nearbyPlayers);
future.complete(result); future.complete(result);
@ -283,7 +288,7 @@ public class Flag implements Runnable {
bossBar.setTitle(String.format("Team %s is capturing the flag", PlainTextComponentSerializer.plainText().serialize(team.get().getName()))); bossBar.setTitle(String.format("Team %s is capturing the flag", PlainTextComponentSerializer.plainText().serialize(team.get().getName())));
lastWinningTeamId = highestKey; lastWinningTeamId = highestKey;
} }
bossBar.setProgress(Math.min(GameConfig.FLAG.WINNING_SCORE, teamFlagPointCount.get(highestKey)) / (double) GameConfig.FLAG.WINNING_SCORE); bossBar.setProgress(Math.min(100, teamFlagPointCount.get(highestKey)) / 100.0);
bossBar.setVisible(teamFlagPointCount.get(highestKey) > 0); bossBar.setVisible(teamFlagPointCount.get(highestKey) > 0);
} }

View File

@ -8,7 +8,6 @@ import com.alttd.ctf.game.phases.GatheringPhase;
import com.alttd.ctf.game_class.creation.FighterCreator; import com.alttd.ctf.game_class.creation.FighterCreator;
import com.alttd.ctf.team.Team; import com.alttd.ctf.team.Team;
import com.alttd.ctf.team.TeamPlayer; import com.alttd.ctf.team.TeamPlayer;
import com.github.yannicklamprecht.worldborder.api.WorldBorderApi;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -25,10 +24,10 @@ public class GameManager {
private RunningGame runningGame; private RunningGame runningGame;
private final HashMap<Integer, Team> teams = new HashMap<>(); private final HashMap<Integer, Team> teams = new HashMap<>();
public GameManager(WorldBorderApi worldBorderApi) { public GameManager() {
phases = new HashMap<>(); phases = new HashMap<>();
phases.put(GamePhase.CLASS_SELECTION, new ClassSelectionPhase(this, FighterCreator::createFighter, worldBorderApi)); phases.put(GamePhase.CLASS_SELECTION, new ClassSelectionPhase(this, (FighterCreator::createFighter)));
phases.put(GamePhase.GATHERING, new GatheringPhase(this, worldBorderApi)); phases.put(GamePhase.GATHERING, new GatheringPhase());
phases.put(GamePhase.COMBAT, new CombatPhase()); phases.put(GamePhase.COMBAT, new CombatPhase());
phases.put(GamePhase.ENDED, new EndedPhase()); phases.put(GamePhase.ENDED, new EndedPhase());
} }

View File

@ -6,5 +6,5 @@ public interface GamePhaseExecutor {
void start(Flag flag); void start(Flag flag);
void end(GamePhase nextGamePhase); void end();
} }

View File

@ -33,31 +33,26 @@ public class RunningGame implements Runnable {
@Override @Override
public void run() { public void run() {
try { GamePhase nextPhase = GamePhase.values().length < currentPhase.ordinal() ? null : GamePhase.values()[currentPhase.ordinal() + 1];
GamePhase nextPhase = GamePhase.values().length < currentPhase.ordinal() ? null : GamePhase.values()[currentPhase.ordinal() + 1]; if (phaseStartTime == null) {
if (phaseStartTime == null) { phaseStartTime = Instant.now();
phaseStartTime = Instant.now(); nextPhaseActions(null, currentPhase, nextPhase);
nextPhaseActions(null, currentPhase, nextPhase); }
}
if (Duration.between(phaseStartTime, Instant.now()).compareTo(phaseDurations.get(currentPhase)) >= 0) { if (Duration.between(phaseStartTime, Instant.now()).compareTo(phaseDurations.get(currentPhase)) >= 0) {
GamePhase previousPhase = currentPhase; GamePhase previousPhase = currentPhase;
currentPhase = GamePhase.values()[currentPhase.ordinal() + 1]; currentPhase = GamePhase.values()[currentPhase.ordinal() + 1];
nextPhaseActions(previousPhase, currentPhase, nextPhase); nextPhaseActions(previousPhase, currentPhase, nextPhase);
phaseStartTime = Instant.now(); phaseStartTime = Instant.now();
} else if (nextPhase != null) { } else if (nextPhase != null) {
broadcastNextPhaseStartTime(currentPhase, nextPhase); 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) { private void nextPhaseActions(@Nullable GamePhase previousPhase, @NotNull GamePhase phase, @Nullable GamePhase nextPhase) {
//TODO command to go to next phase //TODO command to go to next phase
if (previousPhase != null) { if (previousPhase != null) {
gameManager.getPhaseExecutor(previousPhase).end(phase); gameManager.getPhaseExecutor(previousPhase).end();
} }
gameManager.getPhaseExecutor(phase).start(flag); gameManager.getPhaseExecutor(phase).start(flag);
if (nextPhase != null) { if (nextPhase != null) {

View File

@ -1,24 +1,17 @@
package com.alttd.ctf.game.phases; package com.alttd.ctf.game.phases;
import com.alttd.ctf.config.GameConfig;
import com.alttd.ctf.flag.Flag; import com.alttd.ctf.flag.Flag;
import com.alttd.ctf.game.GameManager; import com.alttd.ctf.game.GameManager;
import com.alttd.ctf.game.GamePhase;
import com.alttd.ctf.game.GamePhaseExecutor; import com.alttd.ctf.game.GamePhaseExecutor;
import com.alttd.ctf.game_class.GameClass; import com.alttd.ctf.game_class.GameClass;
import com.alttd.ctf.team.Team; import com.alttd.ctf.team.Team;
import com.alttd.ctf.team.TeamColor; import com.alttd.ctf.team.TeamColor;
import com.alttd.ctf.team.TeamPlayer;
import com.alttd.ctf.util.CircularIterator; 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 lombok.extern.slf4j.Slf4j;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Optional; import java.util.Optional;
@ -28,32 +21,24 @@ public class ClassSelectionPhase implements GamePhaseExecutor {
private final GameManager gameManager; private final GameManager gameManager;
private final DefaultClassCreator defaultClassCreator; private final DefaultClassCreator defaultClassCreator;
private final WorldBorderApi worldBorderApi;
@FunctionalInterface @FunctionalInterface
public interface DefaultClassCreator { public interface DefaultClassCreator {
@NotNull GameClass apply(TeamColor teamColor); @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.gameManager = gameManager;
this.defaultClassCreator = defaultClassCreator; this.defaultClassCreator = defaultClassCreator;
this.worldBorderApi = worldBorderApi;
} }
@Override @Override
public void start(Flag flag) { public void start(Flag flag) {
Location flagLocation = flag.getFlagLocation(); teleportPlayersToStartingZone();
IWorldBorder worldBorder = worldBorderApi.getWorldBorder(flagLocation.getWorld()); Bukkit.broadcast(MiniMessage.miniMessage().deserialize("<green>Select your class</green>"));
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()); CircularIterator<Team> teamCircularIterator = new CircularIterator<>(gameManager.getTeams());
if (teamCircularIterator.hasNext()) { if (teamCircularIterator.hasNext()) {
Bukkit.getOnlinePlayers().stream() Bukkit.getOnlinePlayers().stream()
.filter(player -> !player.hasPermission("ctf.bypass"))
.filter(player -> gameManager.getTeamPlayer(player.getUniqueId()).isEmpty()) .filter(player -> gameManager.getTeamPlayer(player.getUniqueId()).isEmpty())
.forEach(player -> { .forEach(player -> {
Team team = teamCircularIterator.next(); Team team = teamCircularIterator.next();
@ -63,41 +48,34 @@ public class ClassSelectionPhase implements GamePhaseExecutor {
} else { } else {
log.warn("No teams to add players to"); log.warn("No teams to add players to");
} }
teleportPlayersToStartingZone(); //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
} }
private void teleportPlayersToStartingZone() { private void teleportPlayersToStartingZone() {
Bukkit.getOnlinePlayers().forEach(player -> { Bukkit.getOnlinePlayers().forEach(player -> {
Optional<TeamPlayer> teamPlayer = gameManager.getTeamPlayer(player.getUniqueId()); Optional<Team> team = gameManager.getTeam(player.getUniqueId());
if (teamPlayer.isEmpty()) { if (team.isEmpty()) {
log.warn("{} is not a team player when teleporting to starting zone", player.getName());
return; return;
} }
Optional<GamePhase> gamePhase = gameManager.getGamePhase(); Location spawnLocation = team.get().getSpawnLocation();
if (gamePhase.isEmpty()) { player.teleportAsync(spawnLocation);
log.warn("Game phase is empty when teleporting to starting zone");
return;
}
teamPlayer.get().respawn(player, worldBorderApi, gamePhase.get());
}); });
} }
@Override @Override
public void end(GamePhase nextPhase) { public void end() {
gameManager.getTeams().forEach(team -> { gameManager.getTeams().forEach(team -> {
GameClass defaultClass = defaultClassCreator.apply(team.getColor()); GameClass defaultClass = defaultClassCreator.apply(team.getColor());
team.getPlayers().forEach(teamPlayer -> { team.getPlayers().forEach(player -> {
Player player = Bukkit.getPlayer(teamPlayer.getUuid()); if (player.getGameClass() != null) {
if (player == null || !player.isOnline()) {
log.debug("Tried to reset world border for offline player");
return; return;
} }
teamPlayer.resetWorldBorder(player, worldBorderApi, nextPhase, team.getWorldBorderCenter()); defaultClass.apply(player);
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
} }
} }

View File

@ -1,7 +1,6 @@
package com.alttd.ctf.game.phases; package com.alttd.ctf.game.phases;
import com.alttd.ctf.flag.Flag; import com.alttd.ctf.flag.Flag;
import com.alttd.ctf.game.GamePhase;
import com.alttd.ctf.game.GamePhaseExecutor; import com.alttd.ctf.game.GamePhaseExecutor;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -29,7 +28,7 @@ public class CombatPhase implements GamePhaseExecutor {
} }
@Override @Override
public void end(GamePhase ignored) { public void end() {
executorService.shutdown(); executorService.shutdown();
} }
} }

View File

@ -1,8 +1,7 @@
package com.alttd.ctf.game.phases; package com.alttd.ctf.game.phases;
import com.alttd.ctf.config.GameConfig; import com.alttd.ctf.config.Config;
import com.alttd.ctf.flag.Flag; import com.alttd.ctf.flag.Flag;
import com.alttd.ctf.game.GamePhase;
import com.alttd.ctf.game.GamePhaseExecutor; import com.alttd.ctf.game.GamePhaseExecutor;
import com.alttd.ctf.team.Team; import com.alttd.ctf.team.Team;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -32,7 +31,7 @@ public class EndedPhase implements GamePhaseExecutor {
HashMap<Team, Integer> wins = flag.getWins(); HashMap<Team, Integer> wins = flag.getWins();
Bukkit.broadcast(Component.join(JoinConfiguration.separator(Component.newline()), getWinnerMessages(wins))); Bukkit.broadcast(Component.join(JoinConfiguration.separator(Component.newline()), getWinnerMessages(wins)));
new Thread(() -> { new Thread(() -> {
World world = Bukkit.getWorld(GameConfig.FLAG.world); World world = Bukkit.getWorld(Config.FLAG.world);
if (world == null) { if (world == null) {
log.error("Invalid flag world defined"); log.error("Invalid flag world defined");
return; return;
@ -102,7 +101,7 @@ public class EndedPhase implements GamePhaseExecutor {
} }
@Override @Override
public void end(GamePhase ignored) { public void end() {
} }
} }

View File

@ -1,45 +1,20 @@
package com.alttd.ctf.game.phases; package com.alttd.ctf.game.phases;
import com.alttd.ctf.flag.Flag; 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.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 net.kyori.adventure.text.minimessage.MiniMessage;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@Slf4j
public class GatheringPhase implements GamePhaseExecutor { 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 @Override
public void start(Flag flag) { public void start(Flag flag) {
this.flag = flag;
Bukkit.broadcast(MiniMessage.miniMessage().deserialize("<green>Gather materials and prepare for combat!</green>")); 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 //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? // Let them store things at base during this phase, after only one class can do this?
} }
@Override @Override
public void end(GamePhase nextPhase) { public void end() {
if (flag == null) { //TODO Remove team area barrier
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());
});
});
} }
} }

View File

@ -1,9 +1,7 @@
package com.alttd.ctf.game_class; package com.alttd.ctf.game_class;
import com.alttd.ctf.game.GamePhase;
import com.alttd.ctf.team.TeamColor; import com.alttd.ctf.team.TeamColor;
import com.alttd.ctf.team.TeamPlayer; import com.alttd.ctf.team.TeamPlayer;
import com.github.yannicklamprecht.worldborder.api.WorldBorderApi;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@ -70,7 +68,7 @@ public abstract class GameClass {
displayItem.setItemMeta(itemMeta); displayItem.setItemMeta(itemMeta);
} }
public void apply(TeamPlayer teamPlayer, WorldBorderApi worldBorderApi, GamePhase gamePhase, boolean teleport) { public void apply(TeamPlayer teamPlayer) {
Player player = Bukkit.getPlayer(teamPlayer.getUuid()); Player player = Bukkit.getPlayer(teamPlayer.getUuid());
if (player == null || !player.isOnline()) { if (player == null || !player.isOnline()) {
log.warn("Tried to give class to offline player {}", player == null ? teamPlayer.getUuid() : player.getName()); log.warn("Tried to give class to offline player {}", player == null ? teamPlayer.getUuid() : player.getName());
@ -93,7 +91,7 @@ public abstract class GameClass {
player.updateInventory(); player.updateInventory();
teamPlayer.setGameClass(this); teamPlayer.setGameClass(this);
player.sendRichMessage("You selected the <class_name> class", Placeholder.component("class_name", className)); player.sendRichMessage("You selected the <class_name> class", Placeholder.component("class_name", className));
teamPlayer.respawn(player, worldBorderApi, gamePhase, teleport); player.teleportAsync(teamPlayer.getTeam().getSpawnLocation());
} }
private void setArmor(Player player, int r, int g, int b) { private void setArmor(Player player, int r, int g, int b) {

View File

@ -1,31 +0,0 @@
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;
}
}

View File

@ -1,13 +1,8 @@
package com.alttd.ctf.gui; 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.game_class.GameClass;
import com.alttd.ctf.team.TeamPlayer; import com.alttd.ctf.team.TeamPlayer;
import com.github.yannicklamprecht.worldborder.api.WorldBorderApi;
import lombok.Setter;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
import org.bukkit.Bukkit;
import org.bukkit.event.inventory.InventoryCloseEvent; import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.inventory.InventoryType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -16,21 +11,17 @@ import java.util.List;
public class ClassSelectionGUI extends GUIInventory { public class ClassSelectionGUI extends GUIInventory {
@Setter public ClassSelectionGUI(@NotNull List<GameClass> gameClasses, @NotNull TeamPlayer teamPlayer) {
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"))); super(InventoryType.CHEST, teamPlayer.getTeam().getName().append(MiniMessage.miniMessage().deserialize(" - class selection")));
createClassSelection(gameClasses, teamPlayer, worldBorderApi, gamePhase); createClassSelection(gameClasses, teamPlayer);
} }
private void createClassSelection(@NotNull List<GameClass> gameClasses, @NotNull TeamPlayer teamPlayer, @NotNull WorldBorderApi worldBorderApi, @NotNull GamePhase gamePhase) { private void createClassSelection(@NotNull List<GameClass> gameClasses, @NotNull TeamPlayer teamPlayer) {
int pos = (9 + (9 - gameClasses.size()) / 2); int pos = (9 + (9 - gameClasses.size()) / 2);
for (GameClass gameClass : gameClasses) { for (GameClass gameClass : gameClasses) {
setItem(pos++, gameClass.getDisplayItem(), player -> { setItem(pos++, gameClass.getDisplayItem(), player -> {
gameClass.apply(teamPlayer, worldBorderApi, gamePhase, true); gameClass.apply(teamPlayer);
Bukkit.getScheduler().runTask(main, () -> player.closeInventory(InventoryCloseEvent.Reason.PLUGIN)); player.closeInventory(InventoryCloseEvent.Reason.PLUGIN);
}); });
} }
} }

View File

@ -1,22 +1,19 @@
package com.alttd.ctf.gui; package com.alttd.ctf.gui;
import com.alttd.ctf.Main;
import lombok.Getter; import lombok.Getter;
import lombok.Setter;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Merchant;
import org.bukkit.inventory.MerchantInventory;
import java.util.HashMap; import java.util.HashMap;
public abstract class GUIInventory implements GUI { public abstract class GUIInventory implements GUI {
@Setter
private static Main main;
@Getter @Getter
protected final Inventory inventory; protected final Inventory inventory;
protected final HashMap<Integer, GUIAction> guiActions; protected final HashMap<Integer, GUIAction> guiActions;
@ -38,7 +35,7 @@ public abstract class GUIInventory implements GUI {
} }
public void open(Player player) { public void open(Player player) {
Bukkit.getScheduler().runTask(main, () -> player.openInventory(inventory)); player.openInventory(inventory);
GUIByUUID.put(player.getUniqueId(), this); GUIByUUID.put(player.getUniqueId(), this);
} }

View File

@ -33,11 +33,7 @@ public class Team {
@JsonProperty("worldBorderCenter") @JsonProperty("worldBorderCenter")
@NotNull @NotNull
@Getter @Getter
private Location worldBorderCenter; // https://github.com/yannicklamprecht/WorldBorderAPI/blob/main/how-to-use.md private Location worldBorderCenter; //TODO https://github.com/yannicklamprecht/WorldBorderAPI/blob/main/how-to-use.md
@JsonProperty("flagTurnInLocation")
@NotNull
@Getter
private Location flagTurnInLocation;
@JsonProperty("teamColor") @JsonProperty("teamColor")
@NotNull @NotNull
@Getter @Getter

View File

@ -1,23 +1,12 @@
package com.alttd.ctf.team; 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.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.Getter;
import lombok.Setter; 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.*; import java.util.Objects;
import java.util.UUID;
@Slf4j
@Getter @Getter
public class TeamPlayer { public class TeamPlayer {
@ -31,37 +20,6 @@ public class TeamPlayer {
this.team = team; 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 @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) { if (this == obj) {

View File

@ -1,3 +1,3 @@
#Sat Feb 08 21:57:04 CET 2025 #Sat Feb 08 00:30:51 CET 2025
buildNumber=30 buildNumber=11
version=0.1 version=0.1