diff --git a/src/de/steamwar/lobby/LobbySystem.java b/src/de/steamwar/lobby/LobbySystem.java index 3fce387..596590b 100644 --- a/src/de/steamwar/lobby/LobbySystem.java +++ b/src/de/steamwar/lobby/LobbySystem.java @@ -24,6 +24,7 @@ import de.steamwar.lobby.command.FlyCommand; import de.steamwar.lobby.command.HologramCommand; import de.steamwar.lobby.command.ModifyCommand; import de.steamwar.lobby.command.PortalCommand; +import de.steamwar.lobby.games.GamesCommand; import de.steamwar.lobby.jumpandrun.JumpAndRun; import de.steamwar.lobby.jumpandrun.JumpAndRunCommand; import de.steamwar.lobby.listener.*; @@ -82,6 +83,7 @@ public class LobbySystem extends JavaPlugin { new AlphaWall(l -> l.getZ() > 892, AlphaWall.REFLECT_Z); new AlphaWall(l -> l.getZ() < 1794, AlphaWall.REFLECT_Z); new LobbyPacketHandler().register(); + new GamesCommand(); } @Override diff --git a/src/de/steamwar/lobby/LobbySystem.properties b/src/de/steamwar/lobby/LobbySystem.properties index 5fdfe48..109eb0f 100644 --- a/src/de/steamwar/lobby/LobbySystem.properties +++ b/src/de/steamwar/lobby/LobbySystem.properties @@ -135,6 +135,16 @@ JUMP_AND_RUN_PERSONAL_BEST = §aNice! You beat your personal best by {0} JUMP_AND_RUN_PERSONAL_BEST_TIME = §aPersonal best in {0} JUMP_AND_RUN_PERSONAL_BEST_NO_TIME = §cNo personal best +# Games +GAMES_TICTACTOE = TicTacToe +GAMES_NO_SELF = §cYou can\'t play against yourself +GAMES_CHALLENGED_BY = §e{0} §7challenged you to a game of §e{1} +GAMES_CHALLENGED_BY_HOVER = §7Click to accept +GAMES_WON = §6{0} has won! +GAMES_DRAW = §6Draw! +GAMES_TURN = {0}\'s turn +GAMES_LEFT = §7{0} left the game + # Easter Egg Hunt DIFFICULTY_EASY = §aEasy DIFFICULTY_MEDIUM = §eMedium diff --git a/src/de/steamwar/lobby/LobbySystem_de.properties b/src/de/steamwar/lobby/LobbySystem_de.properties index 450779d..76fb6ea 100644 --- a/src/de/steamwar/lobby/LobbySystem_de.properties +++ b/src/de/steamwar/lobby/LobbySystem_de.properties @@ -126,6 +126,16 @@ JUMP_AND_RUN_PERSONAL_BEST = §aNice! Du hast deinen Rekord um {0} verbessert! JUMP_AND_RUN_PERSONAL_BEST_TIME = §aDein Rekord ist {0} JUMP_AND_RUN_PERSONAL_BEST_NO_TIME = §cDu hast noch keinen Rekord +# Games +GAMES_TICTACTOE = TicTacToe +GAMES_NO_SELF = §cDu kannst dich nicht selbst herausfordern! +GAMES_CHALLENGED_BY = §e{0} §7hat dich zu einem Spiel §e{1}§7 herausgefordert! +GAMES_CHALLENGED_BY_HOVER = §7Klicke hier, um das Spiel zu bestätigen +GAMES_WON = §6{0} hat das Spiel gewonnen! +GAMES_DRAW = §6Unentschieden! +GAMES_TURN = {0} ist dran +GAMES_LEFT = §7{0} hat das Spiel verlassen + # Easter Egg Hunt DIFFICULTY_EASY = §aLeicht DIFFICULTY_MEDIUM = §eMedium diff --git a/src/de/steamwar/lobby/games/GamesCommand.java b/src/de/steamwar/lobby/games/GamesCommand.java new file mode 100644 index 0000000..c6e597d --- /dev/null +++ b/src/de/steamwar/lobby/games/GamesCommand.java @@ -0,0 +1,38 @@ +package de.steamwar.lobby.games; + +import de.steamwar.command.SWCommand; +import de.steamwar.lobby.LobbySystem; +import net.md_5.bungee.api.chat.ClickEvent; +import org.bukkit.entity.Player; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class GamesCommand extends SWCommand { + + private final Map> CHALLENGES = new HashMap<>(); + + public GamesCommand() { + super("games"); + } + + @Register("tictactoe") + public void tictactoe(Player player, Player target) { + if(player == target) { + LobbySystem.getMessage().send("GAMES_NO_SELF", player); + return; + } + + if(CHALLENGES.containsKey(player) && CHALLENGES.get(player).contains(target)) { + new TicTacToe(player, target).updateBoard(); + CHALLENGES.remove(player); + CHALLENGES.remove(target); + return; + } + + CHALLENGES.computeIfAbsent(target, k -> new ArrayList<>()).add(player); + LobbySystem.getMessage().send("GAMES_CHALLENGED_BY", target, LobbySystem.getMessage().parse("GAMES_CHALLENGED_BY_HOVER", target), new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/games tictactoe " + player.getName()), player.getName(), LobbySystem.getMessage().parse("GAMES_TICTACTOE", target)); + } +} diff --git a/src/de/steamwar/lobby/games/TicTacToe.java b/src/de/steamwar/lobby/games/TicTacToe.java new file mode 100644 index 0000000..ecf847a --- /dev/null +++ b/src/de/steamwar/lobby/games/TicTacToe.java @@ -0,0 +1,153 @@ +package de.steamwar.lobby.games; + +import de.steamwar.inventory.SWInventory; +import de.steamwar.inventory.SWItem; +import de.steamwar.lobby.LobbySystem; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.HandlerList; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.player.PlayerQuitEvent; + +import java.util.Random; + +public class TicTacToe implements Listener { + + private static final Random random = new Random(); + + private static final int[][] WINNING_COMBINATIONS = { + {0, 1, 2}, + {3, 4, 5}, + {6, 7, 8}, + {0, 3, 6}, + {1, 4, 7}, + {2, 5, 8}, + {0, 4, 8}, + {2, 4, 6} + }; + + private final Player player1; + private final Player player2; + private Player turn; + + private final int[] board = new int[9]; + + private int turns = 0; + + private boolean running = true; + + public TicTacToe(Player player1, Player player2) { + this.player1 = player1; + this.player2 = player2; + this.turn = random.nextBoolean() ? player1 : player2; + Bukkit.getPluginManager().registerEvents(this, LobbySystem.getPlugin()); + } + + public void updateBoard() { + for (int[] winningCombination : WINNING_COMBINATIONS) { + if(board[winningCombination[0]] == board[winningCombination[1]] && + board[winningCombination[1]] == board[winningCombination[2]] && + board[winningCombination[0]] != 0) { + win(turn, winningCombination); + return; + } + } + + if(turns++ == 9) { + draw(); + return; + } + + turn = turn == player1 ? player2 : player1; + showBoard(player1); + showBoard(player2); + } + + private void win(Player player, int[] winningCombination) { + running = false; + SWInventory inventory = createCurrentBoard(player1, LobbySystem.getMessage().parse("GAMES_WON", player1, player.getName())); + SWInventory inventory2 = createCurrentBoard(player2, LobbySystem.getMessage().parse("GAMES_WON", player2, player.getName())); + for (int j : winningCombination) { + inventory.setItem(j, new SWItem(Material.LIME_WOOL, "§" + j + "§a" + (board[j] == 1 ? "X" : "O"))); + inventory2.setItem(j, new SWItem(Material.LIME_WOOL, "§" + j + "§a" + (board[j] == 1 ? "X" : "O"))); + } + remake(inventory, inventory2); + inventory.open(); + inventory2.open(); + } + + private void draw() { + running = false; + SWInventory inventory = createCurrentBoard(player1, LobbySystem.getMessage().parse("GAMES_DRAW", player1)); + SWInventory inventory2 = createCurrentBoard(player2, LobbySystem.getMessage().parse("GAMES_DRAW", player2)); + remake(inventory, inventory2); + inventory.open(); + inventory2.open(); + } + + private void remake(SWInventory inventory, SWInventory inventory2) { + for (int i = 0; i < board.length; i++) { + inventory.setCallback(i, clickType -> player1.performCommand("games tictactoe " + player2.getName())); + inventory2.setCallback(i, clickType -> player2.performCommand("games tictactoe " + player1.getName())); + } + } + + private void end() { + running = false; + HandlerList.unregisterAll(this); + } + + private void showBoard(Player player) { + SWInventory inventory = createCurrentBoard(player, LobbySystem.getMessage().parse("GAMES_TURN", player, turn.getName())); + inventory.addCloseRunnable(() -> { + Bukkit.getScheduler().runTaskLater(LobbySystem.getPlugin(), () -> { + if(player.getOpenInventory().getTopInventory().getType() != InventoryType.DROPPER && running) { + player1.closeInventory(); + player2.closeInventory(); + LobbySystem.getMessage().send("GAMES_LEFT", player1, player.getName()); + LobbySystem.getMessage().send("GAMES_LEFT", player2, player.getName()); + end(); + } + }, 1); + }); + inventory.open(); + } + + private SWInventory createCurrentBoard(Player player, String title) { + SWInventory inventory = new SWInventory(player, () -> Bukkit.createInventory(null, InventoryType.DROPPER, title)); + for (int i = 0; i < board.length; i++) { + if(board[i] == 0) { + int finalI = i; + inventory.setItem(i, new SWItem(Material.LIGHT_GRAY_WOOL, "§" + i, clickType -> makeMove(player, finalI))); + } else { + inventory.setItem(i, new SWItem(board[i] == 1 ? Material.RED_WOOL : Material.BLUE_WOOL, "§" + i + "§" + (board[i] == 1? "c" : "3") + (board[i] == 1 ? "X" : "O"))); + } + } + return inventory; + } + + private void makeMove(Player player, int i) { + if(player != turn) { + return; + } + + if(board[i] != 0) { + return; + } + + board[i] = player == player1 ? 1 : 2; + updateBoard(); + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + if(event.getPlayer() == player1 || event.getPlayer() == player2) { + player1.closeInventory(); + player2.closeInventory(); + end(); + } + } +}