diff --git a/pom.xml b/pom.xml
index 0ce1bf7..7022d61 100644
--- a/pom.xml
+++ b/pom.xml
@@ -67,11 +67,20 @@
+ ${project.build.directory}/dependency-reduced-pom.xml
xyz.twovb.toolbox
${project.groupId}.${project.artifactId}.toolbox
+
+ com.github.stefvanschie.inventoryframework
+ ${project.groupId}.${project.artifactId}.inventoryframework
+
+
+ net.megavex.scoreboardlibrary
+ ${project.groupId}.${project.artifactId}.scoreboardlibrary
+
@@ -159,7 +168,30 @@
commons-io
2.16.1
-
+
+ com.github.stefvanschie.inventoryframework
+ IF
+ 0.10.15
+
+
+ net.megavex
+ scoreboard-library-api
+ 2.1.10
+
+
+ net.megavex
+ scoreboard-library-implementation
+ 2.1.10
+ runtime
+
+
+ net.megavex
+ scoreboard-library-modern
+ 2.1.10
+ runtime
+
+
+
diff --git a/src/main/java/xyz/twovb/sgm/SGM.java b/src/main/java/xyz/twovb/sgm/SGM.java
index c07d7d6..efa2116 100644
--- a/src/main/java/xyz/twovb/sgm/SGM.java
+++ b/src/main/java/xyz/twovb/sgm/SGM.java
@@ -1,8 +1,17 @@
package xyz.twovb.sgm;
+
+/*
+ * Created by 2vb - 5/7/2024
+ */
+
import dev.rollczi.litecommands.bukkit.LiteBukkitMessages;
import dev.rollczi.litecommands.bukkit.LiteCommandsBukkit;
import lombok.Getter;
+import net.megavex.scoreboardlibrary.api.ScoreboardLibrary;
+import net.megavex.scoreboardlibrary.api.exception.NoPacketAdapterAvailableException;
+import net.megavex.scoreboardlibrary.api.noop.NoopScoreboardLibrary;
+import net.megavex.scoreboardlibrary.api.team.TeamManager;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
@@ -40,6 +49,10 @@ public final class SGM extends JavaPlugin {
@Getter
private LevelManager levelManager;
+ @Getter
+ private ScoreboardLibrary scoreboardLibrary;
+ @Getter
+ private TeamManager teamManager;
@Override
public void onEnable() {
@@ -55,12 +68,32 @@ public final class SGM extends JavaPlugin {
BuildInfo.load(Objects.requireNonNull(this.getTextResource("build-info.yml")));
} catch (IOException | InvalidConfigurationException ignored) {
}
+ loadScoreboard();
+ loadGuis();
registerCommands();
registerGames();
registerPlaceholders();
levelManager.loadLevels();
}
+ private void loadScoreboard() {
+ try {
+ scoreboardLibrary = ScoreboardLibrary.loadScoreboardLibrary(this);
+ } catch (NoPacketAdapterAvailableException e) {
+ // If no packet adapter was found, you can fallback to the no-op implementation:
+ scoreboardLibrary = new NoopScoreboardLibrary();
+ this.getCLogger().error("No scoreboard packet adapter found.");
+ }
+ }
+
+ private void loadGuis() {
+ saveResource("guis/initgame.xml", false);
+ saveResource("guis/mapgui.xml", false);
+ saveResource("guis/teampicker.xml", false);
+ saveResource("guis/activegames.xml", false);
+ saveResource("guis/joingame.xml", false);
+ }
+
private void registerPlaceholders() {
PlaceholderManager pm = new PlaceholderManager();
pm.registerPlaceholder("%commit.id%", BuildInfo.getString("commit.id"));
diff --git a/src/main/java/xyz/twovb/sgm/commands/impl/GameCommand.java b/src/main/java/xyz/twovb/sgm/commands/impl/GameCommand.java
index d9a9b60..d303336 100644
--- a/src/main/java/xyz/twovb/sgm/commands/impl/GameCommand.java
+++ b/src/main/java/xyz/twovb/sgm/commands/impl/GameCommand.java
@@ -1,5 +1,16 @@
package xyz.twovb.sgm.commands.impl;
+
+
+/*
+ * Created by 2vb - 5/7/2024
+ */
+
+
+/*
+ * Created by 2vb - 5/7/2024
+ */
+
/*
* Created by 2vb - 2/7/2024
*/
@@ -13,11 +24,13 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import xyz.twovb.sgm.SGM;
import xyz.twovb.sgm.games.Minigame;
-import xyz.twovb.sgm.games.impl.TestGame;
-import xyz.twovb.sgm.games.impl.capturethebrick.CTB;
+import xyz.twovb.sgm.games.impl.capturethebrick.guis.TeamGui;
+import xyz.twovb.sgm.guis.InitGameGui;
+import xyz.twovb.sgm.guis.JoinGameGui;
import xyz.twovb.toolbox.api.CustomPlayer;
import xyz.twovb.toolbox.utils.ChatUtils;
+import java.util.Optional;
import java.util.UUID;
@Command(name = "game")
@@ -40,9 +53,10 @@ public class GameCommand {
@Execute(name = "init")
@Permission("sgm.games.init")
- void init(@Context Player player, @Arg("name") String name) {
+ void init(@Context Player player, @Arg("name") Optional map) {
CustomPlayer cPlayer = new CustomPlayer(player);
- SGM.getInstance().getGameManager().initGame(new CTB(), player, name);
+ new InitGameGui().getGui().show(player);
+// SGM.getInstance().getGameManager().initGame(new CTB(), player, name);
}
@Execute(name = "start")
@@ -53,6 +67,19 @@ public class GameCommand {
game.start();
}
+ @Execute(name = "team join")
+ @Permission("sgm.games.team")
+ void teamJoin(@Context Player player, @Arg("player") Optional target) {
+// String name = LevelName.orElse(UUID.randomUUID().toString());
+ Player targetPlayer = target.orElse(player);
+ new TeamGui(targetPlayer).getGui().show(player);
+ }
+
+ @Execute(name = "testjoin")
+ void testjoin(@Context Player player) {
+ new JoinGameGui().getGui().show(player);
+ }
+
@Execute(name = "join")
void join(@Context Player player, @Arg("id") String id) {
CustomPlayer cPlayer = new CustomPlayer(player);
diff --git a/src/main/java/xyz/twovb/sgm/games/GameManager.java b/src/main/java/xyz/twovb/sgm/games/GameManager.java
index e5643b8..f68771c 100644
--- a/src/main/java/xyz/twovb/sgm/games/GameManager.java
+++ b/src/main/java/xyz/twovb/sgm/games/GameManager.java
@@ -1,5 +1,10 @@
package xyz.twovb.sgm.games;
+
+/*
+ * Created by 2vb - 5/7/2024
+ */
+
/*
* Created by 2vb - 4/6/2024
*/
@@ -11,8 +16,8 @@ import xyz.twovb.sgm.SGM;
import xyz.twovb.toolbox.managers.PlaceholderManager;
import xyz.twovb.toolbox.utils.ChatUtils;
-import java.io.File;
import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
@@ -25,19 +30,12 @@ public class GameManager {
@Getter
private final ArrayList registeredGames = new ArrayList();
+ private final Map> gameMappings = new HashMap<>();
+
public static Minigame findGame(UUID gameId) {
return activeGames.get(gameId);
}
- public Minigame findGame(Player player) {
- for (Minigame game : activeGames.values()) {
- if (game.getPlayers().contains(player)) {
- return game;
- }
- }
- return null;
- }
-
public static boolean isInGame(Player player) {
for (Minigame game : activeGames.values()) {
if (game.getPlayers().contains(player)) {
@@ -47,16 +45,37 @@ public class GameManager {
return false;
}
- public void initGame(Minigame game, CommandSender owner, String level) {
+ public Minigame findGame(Player player) {
+ for (Minigame game : activeGames.values()) {
+ if (game.getPlayers().contains(player)) {
+ return game;
+ }
+ }
+ return null;
+ }
+
+ public void initGame(String internalName, CommandSender owner, String level) {
try {
+ Minigame game = createGameInstance(internalName);
game.init(owner, level);
- } catch (IOException e) {
+ activeGames.put(game.getGameId(), game);
+ } catch (InstantiationException | IllegalAccessException | IOException | NoSuchMethodException |
+ InvocationTargetException e) {
SGM.getInstance().getCLogger().error(e.getMessage());
owner.sendMessage(ChatUtils.translate(PlaceholderManager.setPlaceholders(SGM.getInstance().getMessages().getString("sgm.game.cant-start"), owner)));
}
- activeGames.put(game.getGameId(), game);
}
+// public void initGame(Minigame game, CommandSender owner, String level) {
+// try {
+// game.init(owner, level);
+// } catch (IOException e) {
+// SGM.getInstance().getCLogger().error(e.getMessage());
+// owner.sendMessage(ChatUtils.translate(PlaceholderManager.setPlaceholders(SGM.getInstance().getMessages().getString("sgm.game.cant-start"), owner)));
+// }
+// activeGames.put(game.getGameId(), game);
+// }
+
public void addPlayerToGame(Player player, UUID gameId) {
Minigame game = findGame(gameId);
if (game.getState() == Minigame.GameState.READY && !game.getPlayers().contains(player) && !isInGame(player)) {
@@ -69,17 +88,28 @@ public class GameManager {
game.removePlayer(player);
}
+ public Minigame createGameInstance(String internalName) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
+ Class extends Minigame> gameClass = gameMappings.get(internalName);
+ if (gameClass != null) {
+ return gameClass.getDeclaredConstructor().newInstance();
+ } else {
+ throw new IllegalArgumentException("No game registered with internal name: " + internalName);
+ }
+ }
+
public void registerGame(Minigame game) {
String intName = game.getName().toLowerCase();
try {
SGM.getInstance().getConfigManager().loadConfig("games/" + intName + "/options.yml");
registeredGames.add(intName);
+ gameMappings.put(intName, game.getClass());
SGM.getInstance().getCLogger().log("Registered game " + game.getName());
- } catch(IllegalArgumentException error) {
+ } catch (IllegalArgumentException error) {
String errMsg = error.getMessage();
if (errMsg.contains("The embedded resource") && errMsg.contains("cannot be found")) {
SGM.getInstance().getCLogger().log(game.getName() + "'s game options are nowhere to be found. Please ensure this is intended behaviour.");
registeredGames.add(intName);
+ gameMappings.put(intName, game.getClass());
} else {
SGM.getInstance().getCLogger().error("Failed to register game " + game.getName() + ". Reason: " + errMsg);
}
diff --git a/src/main/java/xyz/twovb/sgm/games/Minigame.java b/src/main/java/xyz/twovb/sgm/games/Minigame.java
index 3359636..a03b945 100644
--- a/src/main/java/xyz/twovb/sgm/games/Minigame.java
+++ b/src/main/java/xyz/twovb/sgm/games/Minigame.java
@@ -1,5 +1,10 @@
package xyz.twovb.sgm.games;
+
+/*
+ * Created by 2vb - 5/7/2024
+ */
+
/*
* Created by 2vb - 4/6/2024
*/
@@ -9,7 +14,6 @@ import org.bukkit.NamespacedKey;
import org.bukkit.World;
import org.bukkit.WorldCreator;
import org.bukkit.command.CommandSender;
-import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import xyz.twovb.sgm.SGM;
@@ -43,6 +47,8 @@ public interface Minigame extends Listener {
GameState getState();
+ World getWorld();
+
default void sendMessageToAllPlayers(String message) {
for (Player player : getPlayers()) {
CustomPlayer cPlayer = new CustomPlayer(player);
diff --git a/src/main/java/xyz/twovb/sgm/games/impl/TestGame.java b/src/main/java/xyz/twovb/sgm/games/impl/TestGame.java
index b1f47bf..235f062 100644
--- a/src/main/java/xyz/twovb/sgm/games/impl/TestGame.java
+++ b/src/main/java/xyz/twovb/sgm/games/impl/TestGame.java
@@ -1,5 +1,10 @@
package xyz.twovb.sgm.games.impl;
+
+/*
+ * Created by 2vb - 5/7/2024
+ */
+
/*
* Created by 2vb - 26/6/2024
*/
@@ -117,6 +122,12 @@ public class TestGame implements Minigame {
return state;
}
+
+ @Override
+ public World getWorld() {
+ return gameWorld;
+ }
+
@Override
public void onTick() {
if (state == GameState.STARTED && players.size() <= 1) {
diff --git a/src/main/java/xyz/twovb/sgm/games/impl/capturethebrick/CTB.java b/src/main/java/xyz/twovb/sgm/games/impl/capturethebrick/CTB.java
index cf4db34..35013ff 100644
--- a/src/main/java/xyz/twovb/sgm/games/impl/capturethebrick/CTB.java
+++ b/src/main/java/xyz/twovb/sgm/games/impl/capturethebrick/CTB.java
@@ -1,9 +1,31 @@
package xyz.twovb.sgm.games.impl.capturethebrick;
+
+
/*
- * Created by 2vb - 3/7/2024
+ * Created by 2vb - 5/7/2024
*/
+
+/*
+ * Created by 2vb - 5/7/2024
+ */
+
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.NamedTextColor;
+import net.kyori.adventure.text.format.Style;
+import net.kyori.adventure.text.format.TextDecoration;
+import net.kyori.adventure.text.minimessage.MiniMessage;
+import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
+import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
+import net.megavex.scoreboardlibrary.api.sidebar.Sidebar;
+import net.megavex.scoreboardlibrary.api.sidebar.component.ComponentSidebarLayout;
+import net.megavex.scoreboardlibrary.api.sidebar.component.SidebarComponent;
+import net.megavex.scoreboardlibrary.api.sidebar.component.animation.CollectionSidebarAnimation;
+import net.megavex.scoreboardlibrary.api.sidebar.component.animation.SidebarAnimation;
+import net.megavex.scoreboardlibrary.api.team.ScoreboardTeam;
+import net.megavex.scoreboardlibrary.api.team.TeamDisplay;
+import net.megavex.scoreboardlibrary.api.team.TeamManager;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
@@ -11,16 +33,21 @@ import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.PlayerDeathEvent;
+import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerQuitEvent;
+import org.bukkit.scheduler.BukkitTask;
+import org.jetbrains.annotations.NotNull;
import xyz.twovb.sgm.SGM;
import xyz.twovb.sgm.games.GameManager;
import xyz.twovb.sgm.games.Minigame;
import xyz.twovb.sgm.levels.LevelManager;
+import xyz.twovb.toolbox.utils.ChatUtils;
import java.io.File;
import java.io.IOException;
@@ -35,18 +62,33 @@ public class CTB implements Minigame {
private final ArrayList blueBrickSpawns = new ArrayList();
private final ArrayList redSpawnArea = new ArrayList();
private final ArrayList blueSpawnArea = new ArrayList();
+ private final FileConfiguration messages;
private World gameWorld;
private GameState state;
private int bricks;
private int territoryLevel;
private int boundsLevel;
private Location spawnLoc;
+ private TeamManager teamManager;
+ private ScoreboardTeam redTeam;
+ private ScoreboardTeam blueTeam;
+ private Sidebar sb;
+ private SidebarAnimation titleAnimation;
+ // private @NotNull SidebarComponent title;
+ private ComponentSidebarLayout layout;
+
+ private int taskId;
+
+// private List redTeam = new ArrayList();
+// private List blueTeam = new ArrayList();
+// private Sidebar sb;
public CTB() {
this.uuid = UUID.randomUUID();
this.state = GameState.PRESTART;
this.players = new ArrayList<>();
+ this.messages = SGM.getInstance().getConfigManager().loadConfig("games/" + name.toLowerCase() + "/messages.yml");
}
public void init(CommandSender owner, String world) throws IOException {
@@ -54,14 +96,65 @@ public class CTB implements Minigame {
gameWorld = createGameWorld(world, uuid);
gameWorld.setAutoSave(false);
if (applyOptions(world)) {
+ teamManager = SGM.getInstance().getScoreboardLibrary().createTeamManager();
+ this.redTeam = teamManager.createIfAbsent("red_team");
+ this.blueTeam = teamManager.createIfAbsent("blue_team");
Bukkit.getPluginManager().registerEvents(this, SGM.getInstance());
+
+ setupTeamDisplay(redTeam, "Red Team", NamedTextColor.RED);
+ setupTeamDisplay(blueTeam, "Blue Team", NamedTextColor.BLUE);
+
+ this.sb = SGM.getInstance().getScoreboardLibrary().createSidebar();
+ this.titleAnimation = createGradientAnimation(Component.text("Capture The Brick", Style.style(TextDecoration.BOLD)));
+ var title = SidebarComponent.animatedLine(titleAnimation);
+
+ SidebarComponent gameInfo = SidebarComponent.builder().addDynamicLine(() -> Component.text("Players Alive: " + getAlivePlayersCount(), NamedTextColor.YELLOW)).addDynamicLine(() -> Component.text("Red Team: " + getTeamSize(redTeam), NamedTextColor.RED)).addDynamicLine(() -> Component.text("Blue Team: " + getTeamSize(blueTeam), NamedTextColor.BLUE)).addDynamicLine(() -> Component.text("Bricks Remaining: " + bricks, NamedTextColor.GREEN)).build();
+
+ this.layout = new ComponentSidebarLayout(title, gameInfo);
+ layout.apply(sb);
+
+// buildScoreboard();
+ // Ready
state = GameState.READY;
- owner.sendMessage("A new " + name + " instance with ID " + uuid + " has been created and is now ready!");
+ owner.sendMessage(ChatUtils.translate(messages.getString("system.game.ready").replace("%game%", name)));
} else {
- owner.sendMessage("a");
-// owner.sendMessage(ChatUtils.translate(SGM.getInstance().getMessages().getString("sgm.game.cant-start")));
+ owner.sendMessage(ChatUtils.translate(messages.getString("system.game.failed").replace("%cause%", "to load options.")));
+ this.stop();
+ }
+ }
+
+ private void setupTeamDisplay(ScoreboardTeam team, String displayName, NamedTextColor color) {
+ TeamDisplay display = team.defaultDisplay();
+ display.displayName(Component.text(displayName));
+ display.playerColor(color);
+ }
+
+// private void buildScoreboard() {
+// titleAnimation = createGradientAnimation(Component.text("Capture The Brick", Style.style(TextDecoration.BOLD)));
+// title = SidebarComponent.animatedLine(titleAnimation);
+// SidebarComponent lines = SidebarComponent.builder().addDynamicLine(() -> Component.text("Red Team: " + redTeam.teamManager().players().size(), NamedTextColor.RED)).addDynamicLine(() -> Component.text("Blue Team: " + blueTeam.teamManager().players().size(), NamedTextColor.BLUE)).addDynamicLine(() -> Component.text("Bricks Remaining: " + bricks, NamedTextColor.GREEN)).build();
+// layout = new ComponentSidebarLayout(title, lines);
+// layout.apply(sb);
+// }
+
+ private @NotNull SidebarAnimation createGradientAnimation(@NotNull Component text) {
+ float step = 1f / 8f;
+ TagResolver.Single textPlaceholder = Placeholder.component("text", text);
+ List frames = new ArrayList<>((int) (2f / step));
+ float phase = -1f;
+
+ SGM.getInstance().getCLogger().log("Creating gradient animation");
+
+ while (phase <= 1) {
+ String gradientTag = String.format("", phase);
+ Component frame = MiniMessage.miniMessage().deserialize(gradientTag + "", textPlaceholder);
+ frames.add(frame);
+ SGM.getInstance().getCLogger().log("Phase: " + phase + ", Tag: " + gradientTag);
+ phase += step;
}
+ SGM.getInstance().getCLogger().log("Total frames: " + frames.size());
+ return new CollectionSidebarAnimation<>(frames);
}
private Location parseString(String string) {
@@ -146,8 +239,9 @@ public class CTB implements Minigame {
sendMessageToAllPlayers("The game has started!");
for (Player player : players) {
player.teleport(this.spawnLoc);
+ sb.addPlayer(player);
}
- for (int i = 0; i < bricks; i++) {
+ for (int i = 0; i <= bricks; i++) {
for (Location brickLoc : redBrickSpawns) {
placeBrick(brickLoc, "red");
}
@@ -155,10 +249,35 @@ public class CTB implements Minigame {
placeBrick(brickLoc, "blue");
}
}
- Bukkit.getScheduler().runTaskTimer(SGM.getInstance(), this::onTick, 0L, 1L);
+ BukkitTask task = Bukkit.getScheduler().runTaskTimer(SGM.getInstance(), this::onTick, 0L, 1L);
+ this.taskId = task.getTaskId();
}
}
+ public void addPlayerToTeam(Player player, boolean isRedTeam) {
+ //TODO: make this shit fuckin better bor
+ if (isRedTeam) {
+ redTeam.defaultDisplay().addEntry(player.getName());
+ } else {
+ blueTeam.defaultDisplay().addEntry(player.getName());
+ }
+ teamManager.addPlayer(player);
+ }
+
+ public void removePlayerFromTeams(Player player) {
+ redTeam.defaultDisplay().removeEntry(player.getName());
+ blueTeam.defaultDisplay().removeEntry(player.getName());
+ teamManager.removePlayer(player);
+ }
+
+ public int getAlivePlayersCount() {
+ return (int) players.stream().filter(Player::isOnline).count();
+ }
+
+ public int getTeamSize(ScoreboardTeam team) {
+ return team.defaultDisplay().entries().size();
+ }
+
private void placeBrick(Location location, String team) {
Block brick = location.getBlock();
if (Objects.equals(team, "red")) {
@@ -172,6 +291,7 @@ public class CTB implements Minigame {
@Override
public void stop() {
+ // TODO: make it wait before unloading world
// Stop game logic
state = GameState.ENDING;
Player winner;
@@ -186,18 +306,28 @@ public class CTB implements Minigame {
player.teleport(Bukkit.getServer().getWorlds().get(0).getSpawnLocation());
}
Bukkit.unloadWorld(gameWorld, false);
+ if (teamManager != null) {
+ teamManager.close();
+ }
+ if (sb != null) {
+ sb.close();
+ }
+ Bukkit.getScheduler().cancelTask(this.taskId);
}
@Override
public void addPlayer(Player player) {
players.add(player);
+// sb.addPlayer(player);
player.teleport(this.spawnLoc);
- sendMessageToAllPlayers(player.getName() + " has joined the game!");
+ sendMessageToAllPlayers(messages.getString("system.player.join").replace("%player%", player.getName()));
}
@Override
public void removePlayer(Player player) {
players.remove(player);
+ sb.removePlayer(player);
+ sendMessageToAllPlayers(messages.getString("system.player.left").replace("%player%", player.getName()));
}
@EventHandler
@@ -208,6 +338,14 @@ public class CTB implements Minigame {
}
}
+ @EventHandler
+ void onWorldChange(PlayerChangedWorldEvent event) {
+ Player player = event.getPlayer();
+ if (players.contains(player)) {
+ removePlayer(event.getPlayer());
+ }
+ }
+
@EventHandler
void onPlayerDeath(PlayerDeathEvent event) {
Player player = event.getPlayer();
@@ -238,21 +376,26 @@ public class CTB implements Minigame {
return state;
}
-// @EventHandler
-// void onPlayerMove(PlayerMoveEvent event) {
-// Player player = event.getPlayer();
-// CustomPlayer cPlayer = new CustomPlayer(player);
-// cPlayer.sendMessage("move");
-// if (event.getFrom().getX() != event.getTo().getX() || event.getFrom().getZ() != event.getTo().getZ()) {
-// cPlayer.sendMessage("move full block");
-// }
-// }
+ @Override
+ public World getWorld() {
+ return gameWorld;
+ }
@Override
public void onTick() {
+ for (Player player : gameWorld.getPlayers()) {
+ if (!players.contains(player)) {
+ sendMessageToAllPlayers(player.getName() + " IS A IMPOSTER");
+ }
+ }
if (state == GameState.STARTED && players.size() <= 1) {
this.stop();
}
+ try {
+ titleAnimation.nextFrame();
+ layout.apply(sb);
+ } catch (IllegalStateException ignored) {
+ }
}
}
\ No newline at end of file
diff --git a/src/main/java/xyz/twovb/sgm/games/impl/capturethebrick/guis/TeamGui.java b/src/main/java/xyz/twovb/sgm/games/impl/capturethebrick/guis/TeamGui.java
new file mode 100644
index 0000000..faedbc7
--- /dev/null
+++ b/src/main/java/xyz/twovb/sgm/games/impl/capturethebrick/guis/TeamGui.java
@@ -0,0 +1,63 @@
+package xyz.twovb.sgm.games.impl.capturethebrick.guis;
+
+
+/*
+ * Created by 2vb - 5/7/2024
+ */
+
+import com.github.stefvanschie.inventoryframework.gui.type.ChestGui;
+import lombok.Getter;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.inventory.ItemStack;
+import xyz.twovb.sgm.SGM;
+import xyz.twovb.sgm.games.impl.capturethebrick.CTB;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.util.logging.Level;
+
+public class TeamGui {
+ @Getter
+ private final ChestGui gui;
+
+ private Player target;
+
+ public TeamGui(Player player) {
+ ChestGui loadedGui = null;
+ try {
+ File guiFile = new File(SGM.getInstance().getDataFolder(), "guis/teampicker.xml");
+ if (guiFile.exists()) {
+ byte[] fileContent = Files.readAllBytes(guiFile.toPath());
+ InputStream inputStream = new ByteArrayInputStream(fileContent);
+ loadedGui = ChestGui.load(this, inputStream);
+ } else {
+ SGM.getInstance().getLogger().log(Level.WARNING, "Could not find teampicker.xml file.");
+ }
+ } catch (Exception e) {
+ SGM.getInstance().getLogger().log(Level.SEVERE, "Error loading teampicker.xml", e);
+ }
+ gui = loadedGui;
+ target = player;
+ }
+
+ public void globalClick(InventoryClickEvent event) {
+ event.setCancelled(true);
+ }
+
+ public void pickTeam(InventoryClickEvent event) {
+ Player player = (Player) event.getWhoClicked();
+ ItemStack clickedItem = event.getCurrentItem();
+ CTB game = (CTB) SGM.getInstance().getGameManager().findGame(player);
+ if (clickedItem.getType().equals(Material.RED_WOOL)) {
+ game.addPlayerToTeam(target, true);
+ game.sendMessageToAllPlayers(target.getName() + " RED");
+ } else if (clickedItem.getType().equals(Material.BLUE_WOOL)) {
+ game.addPlayerToTeam(target, false);
+ game.sendMessageToAllPlayers(target.getName() + " BLUE");
+ }
+ }
+}
diff --git a/src/main/java/xyz/twovb/sgm/guis/ActiveGamesGui.java b/src/main/java/xyz/twovb/sgm/guis/ActiveGamesGui.java
new file mode 100644
index 0000000..55d4502
--- /dev/null
+++ b/src/main/java/xyz/twovb/sgm/guis/ActiveGamesGui.java
@@ -0,0 +1,110 @@
+package xyz.twovb.sgm.guis;
+
+/*
+ * Created by 2vb - 5/7/2024
+ */
+
+/*
+ * Created by 2vb - 5/7/2024
+ */
+
+import com.github.stefvanschie.inventoryframework.gui.GuiItem;
+import com.github.stefvanschie.inventoryframework.gui.type.ChestGui;
+import com.github.stefvanschie.inventoryframework.pane.OutlinePane;
+import lombok.Getter;
+import net.kyori.adventure.text.Component;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+import xyz.twovb.sgm.SGM;
+import xyz.twovb.sgm.games.GameManager;
+import xyz.twovb.sgm.games.Minigame;
+import xyz.twovb.toolbox.utils.ChatUtils;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+
+public class ActiveGamesGui {
+
+ @Getter
+ private final ChestGui gui;
+
+ private final String game;
+ private OutlinePane mapPane;
+
+ public ActiveGamesGui(String game) {
+ this.game = game;
+ ChestGui loadedGui = null;
+ try {
+ File guiFile = new File(SGM.getInstance().getDataFolder(), "guis/activegames.xml");
+ if (guiFile.exists()) {
+ byte[] fileContent = Files.readAllBytes(guiFile.toPath());
+ InputStream inputStream = new ByteArrayInputStream(fileContent);
+ loadedGui = ChestGui.load(this, inputStream);
+ mapPane = new OutlinePane(1, 1, 7, 1); // Define your pane layout
+ loadedGui.addPane(mapPane);
+ addMaps();
+ } else {
+ SGM.getInstance().getLogger().log(Level.WARNING, "Could not find activegames.xml file.");
+ }
+ } catch (Exception e) {
+ SGM.getInstance().getLogger().log(Level.SEVERE, "Error loading activegames.xml", e);
+ }
+ gui = loadedGui;
+ }
+
+ public void globalClick(InventoryClickEvent event) {
+ event.setCancelled(true);
+ }
+
+ public void addMaps() {
+ for (Minigame game : GameManager.getActiveGames().values()) {
+// SGM.getInstance().getCLogger().log(game.getName());
+// SGM.getInstance().getCLogger().log(this.game);
+ Material itemType;
+ switch (game.getState()) {
+ case PRESTART:
+// mapItem.setType(Material.YELLOW_WOOL);
+ itemType = Material.YELLOW_WOOL;
+ break;
+ case READY:
+// mapItem.setType(Material.LIME_WOOL);
+ itemType = Material.LIME_WOOL;
+ break;
+ case STARTED:
+ case ENDING:
+ default:
+// mapItem.setType(Material.RED_WOOL);
+ itemType = Material.RED_WOOL;
+ break;
+ }
+ ItemStack joinItem = new ItemStack(itemType);
+ ItemMeta meta = joinItem.getItemMeta();
+ meta.displayName(ChatUtils.translate(game.getName()));
+ List lore = new ArrayList();
+ lore.add(0, ChatUtils.translate("&r&7" + game.getGameId().toString()));
+ if (!game.getPlayers().isEmpty()) {
+ lore.add(ChatUtils.translate("&r&7Players:"));
+ for (Player player : game.getPlayers()) {
+ lore.add(ChatUtils.translate("&r&a" + player.getName()));
+ }
+ }
+ meta.lore(lore);
+ joinItem.setItemMeta(meta);
+ mapPane.addItem(new GuiItem(joinItem, event -> {
+ Player player = (Player) event.getWhoClicked();
+ if (game.getState() == Minigame.GameState.READY) {
+ SGM.getInstance().getGameManager().addPlayerToGame(player, game.getGameId());
+ }
+ player.closeInventory();
+ }));
+ }
+ }
+}
diff --git a/src/main/java/xyz/twovb/sgm/guis/InitGameGui.java b/src/main/java/xyz/twovb/sgm/guis/InitGameGui.java
new file mode 100644
index 0000000..460389e
--- /dev/null
+++ b/src/main/java/xyz/twovb/sgm/guis/InitGameGui.java
@@ -0,0 +1,55 @@
+package xyz.twovb.sgm.guis;
+/*
+ * Created by 2vb - 4/7/2024
+ */
+
+import com.github.stefvanschie.inventoryframework.gui.type.ChestGui;
+import lombok.Getter;
+import org.bukkit.entity.Player;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import xyz.twovb.sgm.SGM;
+import xyz.twovb.sgm.games.impl.capturethebrick.CTB;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.util.logging.Level;
+
+public class InitGameGui {
+
+ @Getter
+ private final ChestGui gui;
+
+ public InitGameGui() {
+ ChestGui loadedGui = null;
+ try {
+ File guiFile = new File(SGM.getInstance().getDataFolder(), "guis/initgame.xml");
+ if (guiFile.exists()) {
+ byte[] fileContent = Files.readAllBytes(guiFile.toPath());
+ InputStream inputStream = new ByteArrayInputStream(fileContent);
+ loadedGui = ChestGui.load(this, inputStream);
+ } else {
+ SGM.getInstance().getLogger().log(Level.WARNING, "Could not find initgame.xml file.");
+ }
+ } catch (Exception e) {
+ SGM.getInstance().getLogger().log(Level.SEVERE, "Error loading initgame.xml", e);
+ }
+ gui = loadedGui;
+ }
+
+ public void globalClick(InventoryClickEvent event) {
+ event.setCancelled(true);
+ }
+
+ public void initGame(InventoryClickEvent event) {
+ Player player = (Player) event.getWhoClicked();
+ String itemName = event.getCurrentItem().getItemMeta().getDisplayName().replaceAll("\\W+", "");
+ player.closeInventory();
+ if (SGM.getInstance().getGameManager().getRegisteredGames().contains(itemName.toLowerCase())) {
+ new MapGui(itemName.toLowerCase()).getGui().show(player);
+ } else {
+ player.sendMessage("Please check xml");
+ }
+ }
+}
diff --git a/src/main/java/xyz/twovb/sgm/guis/JoinGameGui.java b/src/main/java/xyz/twovb/sgm/guis/JoinGameGui.java
new file mode 100644
index 0000000..1a5ef6b
--- /dev/null
+++ b/src/main/java/xyz/twovb/sgm/guis/JoinGameGui.java
@@ -0,0 +1,59 @@
+package xyz.twovb.sgm.guis;
+
+/*
+ * Created by 2vb - 5/7/2024
+ */
+
+/*
+ * Created by 2vb - 5/7/2024
+ */
+
+import com.github.stefvanschie.inventoryframework.gui.type.ChestGui;
+import lombok.Getter;
+import org.bukkit.entity.Player;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import xyz.twovb.sgm.SGM;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.util.logging.Level;
+
+public class JoinGameGui {
+
+ @Getter
+ private final ChestGui gui;
+
+ public JoinGameGui() {
+ ChestGui loadedGui = null;
+ try {
+ File guiFile = new File(SGM.getInstance().getDataFolder(), "guis/joingame.xml");
+ if (guiFile.exists()) {
+ byte[] fileContent = Files.readAllBytes(guiFile.toPath());
+ InputStream inputStream = new ByteArrayInputStream(fileContent);
+ loadedGui = ChestGui.load(this, inputStream);
+ } else {
+ SGM.getInstance().getLogger().log(Level.WARNING, "Could not find joingame.xml file.");
+ }
+ } catch (Exception e) {
+ SGM.getInstance().getLogger().log(Level.SEVERE, "Error loading joingame.xml", e);
+ }
+ gui = loadedGui;
+ }
+
+ public void globalClick(InventoryClickEvent event) {
+ event.setCancelled(true);
+ }
+
+ public void joinGame(InventoryClickEvent event) {
+ Player player = (Player) event.getWhoClicked();
+ String itemName = event.getCurrentItem().getItemMeta().getDisplayName().replaceAll("\\W+", "");
+ player.closeInventory();
+ if (SGM.getInstance().getGameManager().getRegisteredGames().contains(itemName.toLowerCase())) {
+ new ActiveGamesGui(itemName).getGui().show(player);
+ } else {
+ player.sendMessage("Please check xml");
+ }
+ }
+}
diff --git a/src/main/java/xyz/twovb/sgm/guis/MapGui.java b/src/main/java/xyz/twovb/sgm/guis/MapGui.java
new file mode 100644
index 0000000..ca58d86
--- /dev/null
+++ b/src/main/java/xyz/twovb/sgm/guis/MapGui.java
@@ -0,0 +1,82 @@
+package xyz.twovb.sgm.guis;
+
+
+/*
+ * Created by 2vb - 5/7/2024
+ */
+
+import com.github.stefvanschie.inventoryframework.gui.GuiItem;
+import com.github.stefvanschie.inventoryframework.gui.type.ChestGui;
+import com.github.stefvanschie.inventoryframework.pane.OutlinePane;
+import lombok.Getter;
+import org.bukkit.Material;
+import org.bukkit.entity.Player;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+import xyz.twovb.sgm.SGM;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.util.List;
+import java.util.logging.Level;
+
+public class MapGui {
+
+ @Getter
+ private final ChestGui gui;
+
+ private final String game;
+ private OutlinePane mapPane;
+
+ public MapGui(String game) {
+ this.game = game;
+ ChestGui loadedGui = null;
+ try {
+ File guiFile = new File(SGM.getInstance().getDataFolder(), "guis/mapgui.xml");
+ if (guiFile.exists()) {
+ byte[] fileContent = Files.readAllBytes(guiFile.toPath());
+ InputStream inputStream = new ByteArrayInputStream(fileContent);
+ loadedGui = ChestGui.load(this, inputStream);
+ mapPane = new OutlinePane(1, 1, 7, 1); // Define your pane layout
+ loadedGui.addPane(mapPane);
+ addMaps();
+ } else {
+ SGM.getInstance().getLogger().log(Level.WARNING, "Could not find mapgui.xml file.");
+ }
+ } catch (Exception e) {
+ SGM.getInstance().getLogger().log(Level.SEVERE, "Error loading mapgui.xml", e);
+ }
+ gui = loadedGui;
+ }
+
+ public void globalClick(InventoryClickEvent event) {
+ event.setCancelled(true);
+ }
+
+ public void addMaps() {
+ List enabledMaps = SGM.getInstance().getLevelManager().enabledMaps.get(this.game);
+ if (enabledMaps != null) {
+ for (String mapName : enabledMaps) {
+ // Create button for each map
+ ItemStack mapItem = new ItemStack(Material.MAP);
+ ItemMeta mapMeta = mapItem.getItemMeta();
+ mapMeta.setDisplayName(mapName);
+ mapItem.setItemMeta(mapMeta);
+
+ mapPane.addItem(new GuiItem(mapItem, event -> {
+ // Handle click event if needed
+ // Example: navigate to the map or show map details
+ Player player = (Player) event.getWhoClicked();
+ SGM.getInstance().getGameManager().initGame(this.game, player, mapName);
+ player.closeInventory();
+// player.sendMessage("Clicked on map: " + mapName);
+ }));
+ }
+ } else {
+ SGM.getInstance().getLogger().log(Level.WARNING, "No maps found for game: " + game);
+ }
+ }
+}
diff --git a/src/main/java/xyz/twovb/sgm/levels/LevelManager.java b/src/main/java/xyz/twovb/sgm/levels/LevelManager.java
index 33d39b3..e60893c 100644
--- a/src/main/java/xyz/twovb/sgm/levels/LevelManager.java
+++ b/src/main/java/xyz/twovb/sgm/levels/LevelManager.java
@@ -1,5 +1,16 @@
package xyz.twovb.sgm.levels;
+
+
+/*
+ * Created by 2vb - 5/7/2024
+ */
+
+
+/*
+ * Created by 2vb - 5/7/2024
+ */
+
/*
* Created by 2vb - 4/6/2024
*/
@@ -108,6 +119,7 @@ public class LevelManager {
File yamlFile = new File(path, "sgm.yml");
try (FileWriter writer = new FileWriter(yamlFile)) {
yaml.dump(data, writer);
+ this.cancel();
} catch (IOException e) {
SGM.getInstance().getCLogger().error("Error writing data file: " + e.getMessage());
}
@@ -130,10 +142,20 @@ public class LevelManager {
// This is probably gonna be funny later
player.teleport(Bukkit.getServer().getWorlds().get(0).getSpawnLocation());
}
+ // TODO: make better
if (!Bukkit.isTickingWorlds() && Bukkit.getServer().unloadWorld(world, true)) {
if (mapDir.exists()) {
FileUtils.deleteDirectory(mapDir);
}
+ File configFile = new File(levelDir + "/sgm.yml");
+ YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
+ String gameIntName = config.getString("game");
+ if (SGM.getInstance().getGameManager().getRegisteredGames().contains(gameIntName)) {
+ List maps = enabledMaps.get(gameIntName);
+ if (!maps.contains(name)) {
+ enabledMaps.get(gameIntName).add(name);
+ }
+ }
FileUtils.copyDirectory(levelDir, mapDir);
FileUtils.delete(new File(mapDir + "/uid.dat"));
loadWorld(name, LevelType.LEVEL);
@@ -170,8 +192,6 @@ public class LevelManager {
block.setType(Material.STONE);
}
}
-// Block block = location.subtract(0, 2, 0).getBlock();
-// block.setType(Material.STONE);
world.setSpawnLocation(location);
world.setSpawnFlags(false, false);
world.setGameRule(GameRule.KEEP_INVENTORY, true);
@@ -190,6 +210,7 @@ public class LevelManager {
// Load levels from levelPath
loadWorldDir(levelPath, LevelType.LEVEL);
+ loadWorldDir(mapPath, LevelType.MAP);
}
private void loadWorldDir(String path, LevelType levelType) {
@@ -208,8 +229,10 @@ public class LevelManager {
if (enabledMaps.containsKey(game) && levelType == LevelType.MAP) {
enabledMaps.get(game).add(name);
}
- // Load the world if sgm.yml exists
- loadWorld(file.getName(), levelType);
+ if (levelType == LevelType.LEVEL) {
+ // Load the world if sgm.yml exists
+ loadWorld(file.getName(), levelType);
+ }
} else {
SGM.getInstance().getCLogger().log("Skipping directory " + file.getName() + ": sgm.yml not found.");
}
diff --git a/src/main/resources/games/capturethebrick/messages.yml b/src/main/resources/games/capturethebrick/messages.yml
new file mode 100644
index 0000000..0a60f14
--- /dev/null
+++ b/src/main/resources/games/capturethebrick/messages.yml
@@ -0,0 +1,7 @@
+system:
+ game:
+ ready: "&7A new %game% game has started and can now be joined!"
+ failed: "&7%game% failed %cause%"
+ player:
+ join: "&7%player% has joined the game!"
+ left: "&7%player% has left the game."
diff --git a/src/main/resources/guis/activegames.xml b/src/main/resources/guis/activegames.xml
new file mode 100644
index 0000000..2c3d4f7
--- /dev/null
+++ b/src/main/resources/guis/activegames.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/guis/initgame.xml b/src/main/resources/guis/initgame.xml
new file mode 100644
index 0000000..f6ff7ed
--- /dev/null
+++ b/src/main/resources/guis/initgame.xml
@@ -0,0 +1,19 @@
+
+
+
+
+ -
+
+
+
+
+ -
+ Capture The Brick
+
+ -
+ TestGame
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/guis/joingame.xml b/src/main/resources/guis/joingame.xml
new file mode 100644
index 0000000..2332b4a
--- /dev/null
+++ b/src/main/resources/guis/joingame.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+ -
+
+
+
+
+ -
+ Capture The Brick
+
+ -
+ TestGame
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/guis/mapgui.xml b/src/main/resources/guis/mapgui.xml
new file mode 100644
index 0000000..8374ed4
--- /dev/null
+++ b/src/main/resources/guis/mapgui.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/guis/teampicker.xml b/src/main/resources/guis/teampicker.xml
new file mode 100644
index 0000000..dbb4207
--- /dev/null
+++ b/src/main/resources/guis/teampicker.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+ -
+ Red Team
+
+ -
+ Blue Team
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/messages.yml b/src/main/resources/messages.yml
index 5c8ec1c..e4375e9 100644
--- a/src/main/resources/messages.yml
+++ b/src/main/resources/messages.yml
@@ -16,8 +16,6 @@ sgm:
cant-start: "&7Game couldn't be started!"
cant-join: "&7Could not join this game!"
started: "&7Game has started!"
- joined: "&7%player% has joined the game!"
- left: "&7%player% has left the game."
win: "&7Congratulations to %winner% for winning!"
level:
new: "&7A level with the name %level% has been created."