Integrate WorldBorderAPI and enhance game phase functionality
Added WorldBorderAPI dependency to manage player boundaries dynamically during game phases. Updated game phases, respawn mechanics, and class selection to utilize the WorldBorderAPI. Reworked related components to improve boundary handling, ensuring consistent gameplay flow and preparation for future enhancements.
This commit is contained in:
parent
e5077b40c5
commit
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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,11 +15,13 @@ 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;
|
||||
|
|
@ -40,10 +42,11 @@ public class Main extends JavaPlugin {
|
|||
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);
|
||||
|
|
@ -52,7 +55,7 @@ public class Main extends JavaPlugin {
|
|||
} else {
|
||||
log.error("No valid flag world defined, unable to modify game rules");
|
||||
}
|
||||
registerEvents(flag);
|
||||
registerEvents(flag, worldBorderApi);
|
||||
}
|
||||
|
||||
public void reloadConfigs() {
|
||||
|
|
@ -64,12 +67,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);
|
||||
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)
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ 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.team.TeamPlayer;
|
||||
import com.github.yannicklamprecht.worldborder.api.WorldBorderApi;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
|
|
@ -22,9 +23,11 @@ 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.worldBorderApi = worldBorderApi;
|
||||
this.gameClasses = new HashMap<>();
|
||||
gameManager.getTeams().forEach(team -> {
|
||||
gameClasses.computeIfAbsent(team.getId(), teamId -> new ArrayList<>()).add(FighterCreator.createFighter(team.getColor()));
|
||||
|
|
@ -55,7 +58,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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
package com.alttd.ctf.events;
|
||||
|
||||
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.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
|
|
@ -10,12 +13,15 @@ import org.bukkit.event.player.PlayerRespawnEvent;
|
|||
|
||||
import java.util.Optional;
|
||||
|
||||
@Slf4j
|
||||
public class OnPlayerDeath implements Listener {
|
||||
|
||||
private final GameManager gameManager;
|
||||
private final WorldBorderApi worldBorderApi;
|
||||
|
||||
public OnPlayerDeath(GameManager gameManager) {
|
||||
public OnPlayerDeath(GameManager gameManager, WorldBorderApi worldBorderApi) {
|
||||
this.gameManager = gameManager;
|
||||
this.worldBorderApi = worldBorderApi;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
|
@ -33,13 +39,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);
|
||||
teamPlayer.getGameClass().apply(teamPlayer, worldBorderApi, gamePhase.get(), false);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ 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.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
|
|
@ -30,7 +31,6 @@ 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<>();
|
||||
|
|
@ -38,13 +38,24 @@ public class Flag implements Runnable {
|
|||
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(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);
|
||||
}
|
||||
|
||||
private BossBar createBossBar() {
|
||||
NamespacedKey namespacedKey = NamespacedKey.fromString("ctf_flag", main);
|
||||
if (namespacedKey == null) {
|
||||
|
|
@ -60,10 +71,6 @@ public class Flag implements Runnable {
|
|||
return captureProgress;
|
||||
}
|
||||
|
||||
protected Location getFlagLocation() {
|
||||
return flagLocation;
|
||||
}
|
||||
|
||||
public void addPlayer(Player player) {
|
||||
bossBar.addPlayer(player);
|
||||
}
|
||||
|
|
@ -85,13 +92,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 +126,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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,14 +6,16 @@ import net.kyori.adventure.text.minimessage.MiniMessage;
|
|||
|
||||
@Getter
|
||||
public enum GamePhase {
|
||||
CLASS_SELECTION(MiniMessage.miniMessage().deserialize("<green>Class selection phase</green>")),
|
||||
GATHERING(MiniMessage.miniMessage().deserialize("<green>Gathering phase</green>")),
|
||||
COMBAT(MiniMessage.miniMessage().deserialize("<green>Combat phase</green>")),
|
||||
ENDED(MiniMessage.miniMessage().deserialize("<green>Game end phase</green>"));
|
||||
CLASS_SELECTION(MiniMessage.miniMessage().deserialize("<green>Class selection phase</green>"), 25),
|
||||
GATHERING(MiniMessage.miniMessage().deserialize("<green>Gathering phase</green>"), 50),
|
||||
COMBAT(MiniMessage.miniMessage().deserialize("<green>Combat phase</green>"), 0),
|
||||
ENDED(MiniMessage.miniMessage().deserialize("<green>Game end phase</green>"), 0);
|
||||
|
||||
private final Component displayName;
|
||||
private final double worldBorderSize;
|
||||
|
||||
GamePhase(Component displayName) {
|
||||
GamePhase(Component displayName, double worldBorderSize) {
|
||||
this.displayName = displayName;
|
||||
this.worldBorderSize = worldBorderSize;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,5 +6,5 @@ public interface GamePhaseExecutor {
|
|||
|
||||
void start(Flag flag);
|
||||
|
||||
void end();
|
||||
void end(GamePhase nextGamePhase);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ public class RunningGame implements Runnable {
|
|||
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) {
|
||||
|
|
|
|||
|
|
@ -2,16 +2,18 @@ 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.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.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.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Optional;
|
||||
|
|
@ -21,20 +23,22 @@ 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>"));
|
||||
CircularIterator<Team> teamCircularIterator = new CircularIterator<>(gameManager.getTeams());
|
||||
if (teamCircularIterator.hasNext()) {
|
||||
|
|
@ -48,34 +52,36 @@ 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 -> {
|
||||
player.resetWorldBorder(Bukkit.getPlayer(player.getUuid()), worldBorderApi, nextPhase, team.getWorldBorderCenter());
|
||||
if (player.getGameClass() != null) {
|
||||
return;
|
||||
}
|
||||
defaultClass.apply(player);
|
||||
defaultClass.apply(player, 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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.alttd.ctf.game.phases;
|
|||
|
||||
import com.alttd.ctf.config.Config;
|
||||
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;
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
package com.alttd.ctf.gui;
|
||||
|
||||
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 net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
|
|
@ -11,16 +13,17 @@ import java.util.List;
|
|||
|
||||
public class ClassSelectionGUI extends GUIInventory {
|
||||
|
||||
public ClassSelectionGUI(@NotNull List<GameClass> gameClasses, @NotNull TeamPlayer teamPlayer) {
|
||||
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);
|
||||
gameClass.apply(teamPlayer, worldBorderApi, gamePhase, true);
|
||||
player.closeInventory(InventoryCloseEvent.Reason.PLUGIN);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ 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("teamColor")
|
||||
@NotNull
|
||||
@Getter
|
||||
|
|
|
|||
|
|
@ -1,12 +1,21 @@
|
|||
package com.alttd.ctf.team;
|
||||
|
||||
import com.alttd.ctf.game.GamePhase;
|
||||
import com.alttd.ctf.game_class.GameClass;
|
||||
import com.github.yannicklamprecht.worldborder.api.IWorldBorder;
|
||||
import com.github.yannicklamprecht.worldborder.api.Position;
|
||||
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;
|
||||
|
||||
@Slf4j
|
||||
@Getter
|
||||
public class TeamPlayer {
|
||||
|
||||
|
|
@ -20,6 +29,35 @@ 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();
|
||||
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) {
|
||||
log.info("Resetting world border for {}", player.getName());
|
||||
double worldBorderSize = gamePhase.getWorldBorderSize();
|
||||
log.info("Resetting world border to {} for {}", worldBorderSize, player.getName());
|
||||
IWorldBorder worldBorder = worldBorderApi.getWorldBorder(player);
|
||||
if (worldBorderSize <= 0) {
|
||||
log.info("Resetting world border to global for {}", player.getName());
|
||||
worldBorderApi.resetWorldBorderToGlobal(player);
|
||||
return;
|
||||
}
|
||||
log.info("Resetting world border to {} for {}", worldBorderCenter.toString(), player.getName());
|
||||
worldBorderApi.setBorder(player, worldBorderSize, 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 20:41:32 CET 2025
|
||||
buildNumber=18
|
||||
version=0.1
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user