diff --git a/.project b/.project new file mode 100644 index 0000000..12a14d4 --- /dev/null +++ b/.project @@ -0,0 +1,34 @@ + + + KenshinsHideAndSeek + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + + + 1690577727676 + + 30 + + org.eclipse.core.resources.regexFilterMatcher + node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ + + + + diff --git a/pom.xml b/pom.xml index 0515362..23eec91 100644 --- a/pom.xml +++ b/pom.xml @@ -1,7 +1,7 @@ 4.0.0 net.tylermurphy KenshinsHideAndSeek - 1.7.4 + 1.7.5 Hide and Seek Plugin diff --git a/src/main/java/net/tylermurphy/hideAndSeek/command/Start.java b/src/main/java/net/tylermurphy/hideAndSeek/command/Start.java index 5184933..83665a0 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/command/Start.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/command/Start.java @@ -7,6 +7,7 @@ import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -33,19 +34,21 @@ public class Start implements ICommand { sender.sendMessage(errorPrefix + message("START_MIN_PLAYERS").addAmount(minPlayers)); return; } - String seekerName; + if (args.length < 1) { Main.getInstance().getGame().start(); return; - } else { - seekerName = args[0]; - } - Player seeker = Bukkit.getPlayer(seekerName); - if (seeker == null || !Main.getInstance().getBoard().contains(seeker)) { - sender.sendMessage(errorPrefix + message("START_INVALID_NAME").addPlayer(seekerName)); - return; - } - Main.getInstance().getGame().start(seeker); + }; + + List initialSeekers = new ArrayList<>(args.length); + for (int i = 0; i < args.length; i++) { + Player seeker = Bukkit.getPlayer(args[i]); + if (seeker == null || !Main.getInstance().getBoard().contains(seeker) || initialSeekers.contains(seeker)) { + sender.sendMessage(errorPrefix + message("START_INVALID_NAME").addPlayer(args[i])); + return; + } + } + Main.getInstance().getGame().start(initialSeekers); } public String getLabel() { @@ -53,18 +56,15 @@ public class Start implements ICommand { } public String getUsage() { - return "<*player>"; + return "<*seekers...>"; } public String getDescription() { - return "Starts the game either with a random seeker or chosen one"; + return "Starts the game either with a random set of seekers or a chosen list"; } public List autoComplete(@NotNull String parameter, @NotNull String typed) { - if(parameter.equals("player")) { - return Main.getInstance().getBoard().getPlayers().stream().map(Player::getName).collect(Collectors.toList()); - } - return null; + return Main.getInstance().getBoard().getPlayers().stream().map(Player::getName).collect(Collectors.toList()); } } diff --git a/src/main/java/net/tylermurphy/hideAndSeek/command/util/CommandGroup.java b/src/main/java/net/tylermurphy/hideAndSeek/command/util/CommandGroup.java index 9bfdd0e..907f031 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/command/util/CommandGroup.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/command/util/CommandGroup.java @@ -51,7 +51,7 @@ public class CommandGroup { if (data == null) { player.sendMessage( - String.format("%s%sKenshin's Hide and Seek %s(%s1.7.4%s)\n", ChatColor.AQUA, ChatColor.BOLD, ChatColor.GRAY, ChatColor.WHITE, ChatColor.GRAY) + + String.format("%s%sKenshin's Hide and Seek %s(%s1.7.5%s)\n", ChatColor.AQUA, ChatColor.BOLD, ChatColor.GRAY, ChatColor.WHITE, ChatColor.GRAY) + String.format("%sAuthor: %s[KenshinEto]\n", ChatColor.GRAY, ChatColor.WHITE) + String.format("%sHelp Command: %s/hs %shelp", ChatColor.GRAY, ChatColor.AQUA, ChatColor.WHITE) ); diff --git a/src/main/java/net/tylermurphy/hideAndSeek/configuration/Config.java b/src/main/java/net/tylermurphy/hideAndSeek/configuration/Config.java index 9fc7009..67fc4bf 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/configuration/Config.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/configuration/Config.java @@ -62,8 +62,11 @@ public class Config { allowNaturalCauses, saveInventory, delayedRespawn, + dontRewardQuit, spawnPatch, dropItems, + respawnAsSpectator, + waitTillNoneLeft, regenHealth; public static int @@ -82,6 +85,7 @@ public class Config { lobbyItemStartPosition, flightToggleItemPosition, teleportItemPosition, + startingSeekerCount, delayedRespawnDelay; public static float @@ -154,7 +158,9 @@ public class Config { } //Lobby - minPlayers = Math.max(2, config.getInt("minPlayers")); + startingSeekerCount = Math.max(1, config.getInt("startingSeekerCount")); + waitTillNoneLeft = config.getBoolean("waitTillNoneLeft"); + minPlayers = Math.max(1 + startingSeekerCount + (waitTillNoneLeft ? 0 : 1), config.getInt("minPlayers")); countdown = Math.max(10, config.getInt("lobby.countdown")); changeCountdown = Math.max(minPlayers, config.getInt("lobby.changeCountdown")); lobbyMin = Math.max(minPlayers, config.getInt("lobby.min")); @@ -188,6 +194,9 @@ public class Config { placeholderError = config.getString("placeholder.incorrect"); placeholderNoData = config.getString("placeholder.noData"); saveInventory = config.getBoolean("saveInventory"); + respawnAsSpectator = config.getBoolean("respawnAsSpectator"); + dontRewardQuit = config.getBoolean("dontRewardQuit"); + try { countdownDisplay = CountdownDisplay.valueOf(config.getString("hideCountdownDisplay")); } catch (IllegalArgumentException e) { @@ -271,4 +280,4 @@ public class Config { return temp; } -} \ No newline at end of file +} diff --git a/src/main/java/net/tylermurphy/hideAndSeek/database/GameDataTable.java b/src/main/java/net/tylermurphy/hideAndSeek/database/GameDataTable.java index 87378f9..d5fe7e6 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/database/GameDataTable.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/database/GameDataTable.java @@ -79,7 +79,6 @@ public class GameDataTable { rs.getInt("seeker_deaths") ); rs.close(); - connection.close(); CACHE.put(uuid, info); return info; } @@ -111,7 +110,6 @@ public class GameDataTable { rs.getInt("seeker_deaths") ); rs.close(); - connection.close(); CACHE.put(uuid, info); return info; } @@ -145,7 +143,6 @@ public class GameDataTable { infoList.add(info); } rs.close(); - connection.close(); return infoList; } catch (SQLException e) { Main.getInstance().getLogger().severe("SQL Error: " + e.getMessage()); @@ -190,8 +187,8 @@ public class GameDataTable { database.encodeUUID(info.getUniqueId()), info.getHiderWins() + (winners.contains(uuid) && type == WinType.HIDER_WIN ? 1 : 0), info.getSeekerWins() + (winners.contains(uuid) && type == WinType.SEEKER_WIN ? 1 : 0), - info.getHiderGames() + (board.isHider(uuid) || (board.isSeeker(uuid) && !board.getFirstSeeker().getUniqueId().equals(uuid)) ? 1 : 0), - info.getSeekerGames() + (board.getFirstSeeker().getUniqueId().equals(uuid) ? 1 : 0), + info.getHiderGames() + (board.isHider(uuid) || (board.isSeeker(uuid) && winners.contains(uuid)) ? 1 : 0), + info.getSeekerGames() + (board.isSeeker(uuid) && winners.contains(uuid) ? 1 : 0), info.getHiderKills() + hider_kills.getOrDefault(uuid, 0), info.getSeekerKills() + seeker_kills.getOrDefault(uuid, 0), info.getHiderDeaths() + hider_deaths.getOrDefault(uuid, 0), diff --git a/src/main/java/net/tylermurphy/hideAndSeek/database/connections/MySQLConnection.java b/src/main/java/net/tylermurphy/hideAndSeek/database/connections/MySQLConnection.java index e237e71..20e7c8e 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/database/connections/MySQLConnection.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/database/connections/MySQLConnection.java @@ -25,7 +25,6 @@ import net.tylermurphy.hideAndSeek.Main; import java.sql.Connection; import java.sql.SQLException; -import java.sql.Statement; import static net.tylermurphy.hideAndSeek.configuration.Config.*; diff --git a/src/main/java/net/tylermurphy/hideAndSeek/database/connections/SQLiteConnection.java b/src/main/java/net/tylermurphy/hideAndSeek/database/connections/SQLiteConnection.java index 1a03106..bbf330b 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/database/connections/SQLiteConnection.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/database/connections/SQLiteConnection.java @@ -52,7 +52,7 @@ public class SQLiteConnection implements DatabaseConnection { public Connection connect() { Connection conn = null; try { - String url = "jdbc:sqlite:"+databaseFile; + String url = "jdbc:sqlite:"+databaseFile.getPath(); conn = DriverManager.getConnection(url, config.toProperties()); } catch (SQLException e) { Main.getInstance().getLogger().severe(e.getMessage()); diff --git a/src/main/java/net/tylermurphy/hideAndSeek/game/Board.java b/src/main/java/net/tylermurphy/hideAndSeek/game/Board.java index 2050f33..4c56453 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/game/Board.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/game/Board.java @@ -25,7 +25,7 @@ public class Board { SPECTATOR, } - private UUID initialSeeker = null; + private List initialSeekers = null; private final Map Players = new HashMap<>(); private final Map customBoards = new HashMap<>(); private final Map hider_kills = new HashMap<>(), seeker_kills = new HashMap<>(), hider_deaths = new HashMap<>(), seeker_deaths = new HashMap<>(); @@ -104,9 +104,15 @@ public class Board { .collect(Collectors.toList()); } - public Player getFirstSeeker() { - if(initialSeeker == null) return null; - return Bukkit.getPlayer(initialSeeker); + public void setInitialSeekers(List seekers) { + initialSeekers = seekers; + } + + public List getInitialSeekers() { + if(initialSeekers == null) return null; + return initialSeekers.stream().map(u -> { + return Bukkit.getPlayer(u); + }).collect(Collectors.toList()); } public Player getPlayer(UUID uuid) { @@ -121,9 +127,6 @@ public class Board { } public void addSeeker(Player player) { - if(initialSeeker == null) { - initialSeeker = player.getUniqueId(); - } Players.put(player.getUniqueId(), Type.SEEKER); } @@ -347,7 +350,7 @@ public class Board { public void cleanup() { Players.clear();; - initialSeeker = null; + initialSeekers = null; customBoards.clear(); } @@ -487,4 +490,4 @@ class Line { this.message = message; } -} \ No newline at end of file +} diff --git a/src/main/java/net/tylermurphy/hideAndSeek/game/Game.java b/src/main/java/net/tylermurphy/hideAndSeek/game/Game.java index 41df9b8..e8b39d1 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/game/Game.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/game/Game.java @@ -97,22 +97,28 @@ public class Game { } public void start() { - Player seeker; - try { - int rand = (int) (Math.random() * board.getPlayers().size()); - seeker = board.getPlayers().get(rand); - } catch (Exception e){ - Main.getInstance().getLogger().warning("Failed to select random seeker."); - return; - } - start(seeker); + List seekers = new ArrayList<>(startingSeekerCount); + List pool = board.getPlayers(); + for (int i = 0; i < startingSeekerCount; i++) { + try { + int rand = new Random().nextInt(0, pool.size()-1); + seekers.add(pool.remove(rand)); + } catch (Exception e){ + Main.getInstance().getLogger().warning("Failed to select random seeker."); + return; + } + } + start(seekers); } - public void start(Player seeker) { + public void start(List seekers) { if (mapSaveEnabled) currentMap.getWorldLoader().rollback(); board.reload(); - board.addSeeker(seeker); - PlayerLoader.loadSeeker(seeker, currentMap); + board.setInitialSeekers(seekers.stream().map(Player::getUniqueId).collect(Collectors.toList())); + seekers.forEach(seeker -> { + board.addSeeker(seeker); + PlayerLoader.loadSeeker(seeker, currentMap); + }); board.getPlayers().forEach(player -> { if(board.isSeeker(player)) return; board.addHider(player); @@ -133,7 +139,12 @@ public class Game { Main.getInstance().getDatabase().getGameData().addWins(board, players, winners, board.getHiderKills(), board.getHiderDeaths(), board.getSeekerKills(), board.getSeekerDeaths(), type); } else if (type == WinType.SEEKER_WIN) { List winners = new ArrayList<>(); - winners.add(board.getFirstSeeker().getUniqueId()); + board.getInitialSeekers().forEach(p -> { + winners.add(p.getUniqueId()); + }); + if (!waitTillNoneLeft && board.getHiders().size() == 1) { + winners.add(board.getHiders().get(0).getUniqueId()); + } Main.getInstance().getDatabase().getGameData().addWins(board, players, winners, board.getHiderKills(), board.getHiderDeaths(), board.getSeekerKills(), board.getSeekerDeaths(), type); } Bukkit.getScheduler().scheduleSyncDelayedTask(Main.getInstance(), this::end, 5*20); @@ -351,8 +362,9 @@ public class Game { } private void checkWinConditions() { - if (board.sizeHider() < 1) { - if (hiderLeft) { + int hiderCount = board.sizeHider(); + if (hiderCount < 1 || (!waitTillNoneLeft && hiderCount < 2)) { + if (hiderLeft && dontRewardQuit) { if (announceMessagesToNonPlayers) Bukkit.broadcastMessage(gameOverPrefix + message("GAME_GAMEOVER_HIDERS_QUIT")); else broadcastMessage(gameOverPrefix + message("GAME_GAMEOVER_HIDERS_QUIT")); stop(WinType.NONE); @@ -364,7 +376,7 @@ public class Game { } else if (board.sizeSeeker() < 1) { if (announceMessagesToNonPlayers) Bukkit.broadcastMessage(abortPrefix + message("GAME_GAMEOVER_SEEKERS_QUIT")); else broadcastMessage(abortPrefix + message("GAME_GAMEOVER_SEEKERS_QUIT")); - stop(WinType.NONE); + stop(dontRewardQuit ? WinType.NONE : WinType.HIDER_WIN); } else if (gameTimer < 1) { if (announceMessagesToNonPlayers) Bukkit.broadcastMessage(gameOverPrefix + message("GAME_GAMEOVER_TIME")); else broadcastMessage(gameOverPrefix + message("GAME_GAMEOVER_TIME")); @@ -373,4 +385,4 @@ public class Game { hiderLeft = false; } -} \ No newline at end of file +} diff --git a/src/main/java/net/tylermurphy/hideAndSeek/game/PlayerLoader.java b/src/main/java/net/tylermurphy/hideAndSeek/game/PlayerLoader.java index 4ee1f5c..e424024 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/game/PlayerLoader.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/game/PlayerLoader.java @@ -67,6 +67,17 @@ public class PlayerLoader { Titles.sendTitle(player, 10, 70, 20, ChatColor.GRAY + "" + ChatColor.BOLD + "SPECTATING", ChatColor.WHITE + message("SPECTATOR_SUBTITLE").toString()); } + public static void loadDeadHiderSpectator(Player player, Map map) { + map.getGameSpawn().teleport(player); + loadPlayer(player); + player.setAllowFlight(true); + player.setFlying(true); + player.setFallDistance(0.0F); + player.getInventory().setItem(flightToggleItemPosition, flightToggleItem); + player.getInventory().setItem(teleportItemPosition, teleportItem); + Main.getInstance().getBoard().getPlayers().forEach(otherPlayer -> otherPlayer.hidePlayer(player)); + } + public static void resetPlayer(Player player, Board board){ if(board.isSpectator(player)) return; loadPlayer(player); diff --git a/src/main/java/net/tylermurphy/hideAndSeek/game/listener/DamageHandler.java b/src/main/java/net/tylermurphy/hideAndSeek/game/listener/DamageHandler.java index 37537d6..7f3f22e 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/game/listener/DamageHandler.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/game/listener/DamageHandler.java @@ -94,7 +94,7 @@ public class DamageHandler implements Listener { // Reveal player if they are disguised Main.getInstance().getDisguiser().reveal(player); // Teleport player to seeker spawn - if(delayedRespawn){ + if(delayedRespawn && !respawnAsSpectator){ game.getCurrentMap().getGameSeekerLobby().teleport(player); player.sendMessage(messagePrefix + message("RESPAWN_NOTICE").addAmount(delayedRespawnDelay)); Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(Main.getInstance(), () -> { @@ -117,10 +117,14 @@ public class DamageHandler implements Listener { } else { game.broadcastMessage(message("GAME_PLAYER_FOUND_BY").addPlayer(player).addPlayer(attacker).toString()); } - board.addSeeker(player); + if (respawnAsSpectator) { + board.addSpectator(player); + PlayerLoader.loadDeadHiderSpectator(player, game.getCurrentMap()); + } else { + board.addSeeker(player); + PlayerLoader.resetPlayer(player, board); + } } - //Reload player - PlayerLoader.resetPlayer(player, board); board.reloadBoardTeams(); } diff --git a/src/main/java/net/tylermurphy/hideAndSeek/util/PAPIExpansion.java b/src/main/java/net/tylermurphy/hideAndSeek/util/PAPIExpansion.java index 8e4078e..54c2f02 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/util/PAPIExpansion.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/util/PAPIExpansion.java @@ -28,7 +28,7 @@ public class PAPIExpansion extends PlaceholderExpansion { @Override public @NotNull String getVersion() { - return "1.4.3"; + return "1.7.5"; } @Override diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 5316402..1642b82 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -48,6 +48,24 @@ permissionsRequired: true # default: 2 minPlayers: 2 +# Amount of initial seekers when game starts +# default: 1 +startingSeekerCount: 1 + +# By default, when a HIDER dies they will join the SEEKER team. If enabled they will instead become a spectator +# default: false +respawnAsSpectator: false + +# If enabled, the game will go until no hiders are left. If the timer runs out all hiders left will be marked as winning. +# If disabled the game wll go until there is only one hider left. If the timer runs out, all hiders left win, if t here is one +# hider left, all inital seekers win along with the last hider. +waitTillNoneLeft: true + +# By default, if the last hider or seeker quits the game, a win type of NONE is given, which doesnt mark anyone as winning. This can be +# used as a way to prevent players form quitting in a loop to get someone else points. +# default: true +dontRewardQuit: true + # This plugin by default functions as not tag to catch Hiders, but to pvp. All players are given weapons, # and seekers slightly better weapons (this can be changed in items.yml). If you want, you can disable this # entire pvp functionality, and make Hiders get found on a single hit. Hiders would also not be able to fight @@ -304,4 +322,4 @@ exit: x: 0 y: 0 z: 0 - world: "world" \ No newline at end of file + world: "world" diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index dc8cab1..777c1ba 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: KenshinsHideAndSeek main: net.tylermurphy.hideAndSeek.Main -version: 1.7.4 +version: 1.7.5 author: KenshinEto load: STARTUP api-version: 1.13