Compare commits
No commits in common. "8718ca091875f0c1e658d86cc14ca5e51b42f206" and "e5077b40c53272cb77707762580beb16285eebf4" have entirely different histories.
8718ca0918
...
e5077b40c5
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
package com.alttd.ctf.config;
|
|
||||||
|
|
||||||
public record WorldBorderSettings(WorldBorderType type, double size) {
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
package com.alttd.ctf.config;
|
|
||||||
|
|
||||||
public enum WorldBorderType {
|
|
||||||
FLAG,
|
|
||||||
PLAYER
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,5 +6,5 @@ public interface GamePhaseExecutor {
|
||||||
|
|
||||||
void start(Flag flag);
|
void start(Flag flag);
|
||||||
|
|
||||||
void end(GamePhase nextGamePhase);
|
void end();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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() {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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());
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user