From 99c1ea8eb34093f27c37d315e2bc447f93998287 Mon Sep 17 00:00:00 2001 From: Tyler Murphy Date: Fri, 13 May 2022 23:11:35 -0400 Subject: [PATCH] better spectator flight and teleporting --- .../hideAndSeek/configuration/Config.java | 70 +++++++++--------- .../tylermurphy/hideAndSeek/game/Game.java | 2 +- .../game/listener/ChatHandler.java | 8 -- .../game/listener/DamageHandler.java | 4 +- .../game/listener/InteractHandler.java | 73 ++++++++++++++++++- .../game/listener/MovementHandler.java | 35 ++++++++- .../game/listener/PlayerHandler.java | 13 ---- .../hideAndSeek/game/util/PlayerUtil.java | 2 + src/main/resources/config.yml | 18 +++++ .../resources/lang/localization_de-DE.yml | 2 + .../resources/lang/localization_en-US.yml | 2 + 11 files changed, 164 insertions(+), 65 deletions(-) diff --git a/src/main/java/net/tylermurphy/hideAndSeek/configuration/Config.java b/src/main/java/net/tylermurphy/hideAndSeek/configuration/Config.java index afd1729..9fdaaa6 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/configuration/Config.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/configuration/Config.java @@ -31,6 +31,7 @@ import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collections; @@ -105,7 +106,9 @@ public class Config { seekerPingLevel2, seekerPingLevel3, lobbyItemLeavePosition, - lobbyItemStartPosition; + lobbyItemStartPosition, + flightToggleItemPosition, + teleportItemPosition; public static float seekerPingLeadingVolume, @@ -137,7 +140,9 @@ public class Config { public static ItemStack lobbyLeaveItem, lobbyStartItem, - glowPowerupItem; + glowPowerupItem, + flightToggleItem, + teleportItem; public static XSound ringingSound, @@ -218,14 +223,7 @@ public class Config { glowStackable = config.getBoolean("glow.stackable"); glowEnabled = config.getBoolean("glow.enabled") && Version.atLeast("1.9"); if (glowEnabled) { - ConfigurationSection item = new YamlConfiguration().createSection("temp"); - item.set("name", ChatColor.translateAlternateColorCodes('&',config.getString("glow.name"))); - item.set("material", config.getString("glow.material")); - List lore = config.getStringList("glow.lore"); - if (lore != null && !lore.isEmpty()) item.set("lore", lore); - ItemStack temp = null; - try{ temp = XItemStack.deserialize(item); } catch(Exception ignored) {} - glowPowerupItem = temp; + glowPowerupItem = createItemStack("glow"); } //Lobby @@ -302,38 +300,21 @@ public class Config { //Lobby Items if (config.getBoolean("lobbyItems.leave.enabled")) { - ConfigurationSection item = new YamlConfiguration().createSection("temp"); - item.set("name", ChatColor.translateAlternateColorCodes('&',config.getString("lobbyItems.leave.name"))); - item.set("material", config.getString("lobbyItems.leave.material")); - if (Version.atLeast("1.14")) { - if (config.contains("lobbyItems.leave.model-data") && config.getInt("lobbyItems.leave.model-data") != 0) { - item.set("model-data", config.getInt("lobbyItems.leave.model-data")); - } - } - List lore = config.getStringList("lobbyItems.leave.lore"); - if (lore != null && !lore.isEmpty()) item.set("lore", lore); - ItemStack temp = null; - try{ temp = XItemStack.deserialize(item); } catch(Exception ignored) {} - lobbyLeaveItem = temp; + lobbyLeaveItem = createItemStack("lobbyItems.leave"); lobbyItemLeavePosition = config.getInt("lobbyItems.leave.position"); } if (config.getBoolean("lobbyItems.start.enabled")) { - ConfigurationSection item = new YamlConfiguration().createSection("temp"); - item.set("name", ChatColor.translateAlternateColorCodes('&',config.getString("lobbyItems.start.name"))); - item.set("material", config.getString("lobbyItems.start.material")); - List lore = config.getStringList("lobbyItems.start.lore"); - if (lore != null && !lore.isEmpty()) item.set("lore", lore); - ItemStack temp = null; - try{ temp = XItemStack.deserialize(item); } catch(Exception ignored) {} - lobbyStartItem = temp; + lobbyStartItem = createItemStack("lobbyItems.start"); lobbyItemStartAdmin = config.getBoolean("lobbyItems.start.adminOnly"); lobbyItemStartPosition = config.getInt("lobbyItems.start.position"); - if (Version.atLeast("1.14")) { - if (config.contains("lobbyItems.start.model-data") && config.getInt("lobbyItems.start.model-data") != 0) { - item.set("model-data", config.getInt("lobbyItems.start.model-data")); - } - } } + + //Spectator Items + flightToggleItem = createItemStack("spectatorItems.flight"); + flightToggleItemPosition = config.getInt("spectatorItems.flight.position"); + + teleportItem = createItemStack("spectatorItems.teleport"); + teleportItemPosition = config.getInt("spectatorItems.teleport.position"); } public static void addToConfig(String path, Object value) { @@ -343,5 +324,22 @@ public class Config { public static void saveConfig() { config.saveConfig(); } + + @Nullable + private static ItemStack createItemStack(String path){ + ConfigurationSection item = new YamlConfiguration().createSection("temp"); + item.set("name", ChatColor.translateAlternateColorCodes('&',config.getString(path+".name"))); + item.set("material", config.getString(path+".material")); + if (Version.atLeast("1.14")) { + if (config.contains(path+".model-data") && config.getInt(path+".model-data") != 0) { + item.set("model-data", config.getInt(path+".model-data")); + } + } + List lore = config.getStringList(path+".lore"); + if (lore != null && !lore.isEmpty()) item.set("lore", lore); + ItemStack temp = null; + try{ temp = XItemStack.deserialize(item); } catch(Exception ignored) {} + return temp; + } } \ 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 e33e503..15341c0 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/game/Game.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/game/Game.java @@ -265,7 +265,6 @@ public class Game { } startingTimer--; } - checkWinConditions(); } @@ -308,6 +307,7 @@ public class Game { if (tauntEnabled) taunt.update(); if (glowEnabled) glow.update(); } + board.getSpectators().forEach(spectator -> spectator.setFlying(spectator.getAllowFlight())); checkWinConditions(); } diff --git a/src/main/java/net/tylermurphy/hideAndSeek/game/listener/ChatHandler.java b/src/main/java/net/tylermurphy/hideAndSeek/game/listener/ChatHandler.java index 07014b7..27a6235 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/game/listener/ChatHandler.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/game/listener/ChatHandler.java @@ -11,14 +11,6 @@ public class ChatHandler implements Listener { @EventHandler(priority = EventPriority.HIGHEST) public void onChat(AsyncPlayerChatEvent event) { - if (event.getMessage().equals("fly")) { - event.getPlayer().setAllowFlight(true); - event.getPlayer().setFlying(true); - } - if (event.getMessage().equals("no fly")) { - event.getPlayer().setAllowFlight(false); - event.getPlayer().setFlying(false); - } if (Main.getInstance().getBoard().isSeeker(event.getPlayer())) { event.setCancelled(true); Main.getInstance().getBoard().getSpectators().forEach(spectator -> spectator.sendMessage(ChatColor.GRAY + "[SPECTATOR] " + event.getPlayer().getName() + ": " + event.getMessage())); 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 aabbd92..ee63cc2 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/game/listener/DamageHandler.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/game/listener/DamageHandler.java @@ -34,8 +34,6 @@ public class DamageHandler implements Listener { // Define variables Player player = (Player) event.getEntity(); Player attacker = null; - // If player pvp is enabled, and player doesn't die, we do not care - if (pvpEnabled && player.getHealth() - event.getFinalDamage() >= 0.5) { return; } // If no spawn position, we won't be able to manage their death :o if (spawnPosition == null) { return; } // If there is an attacker, find them @@ -84,6 +82,8 @@ public class DamageHandler implements Listener { event.setCancelled(true); return; } + // Check if player dies (pvp mode) + if(pvpEnabled && player.getHealth() - event.getFinalDamage() >= 0.5) return; // Handle death event event.setCancelled(true); // Play death effect diff --git a/src/main/java/net/tylermurphy/hideAndSeek/game/listener/InteractHandler.java b/src/main/java/net/tylermurphy/hideAndSeek/game/listener/InteractHandler.java index bd2c7fe..7fe924f 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/game/listener/InteractHandler.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/game/listener/InteractHandler.java @@ -1,15 +1,23 @@ package net.tylermurphy.hideAndSeek.game.listener; import com.cryptomorin.xseries.XMaterial; +import com.cryptomorin.xseries.messages.ActionBar; import net.tylermurphy.hideAndSeek.Main; import net.tylermurphy.hideAndSeek.game.util.Status; +import org.bukkit.ChatColor; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.Action; +import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SkullMeta; + +import java.util.ArrayList; +import java.util.List; import static net.tylermurphy.hideAndSeek.configuration.Config.*; import static net.tylermurphy.hideAndSeek.configuration.Config.glowPowerupItem; @@ -30,15 +38,17 @@ public class InteractHandler implements Listener { onPlayerInteractLobby(temp, event); if (Main.getInstance().getGame().getStatus() == Status.PLAYING) onPlayerInteractGame(temp, event); + if (Main.getInstance().getBoard().isSpectator(event.getPlayer())) + onSpectatorInteract(temp, event); } private void onPlayerInteractLobby(ItemStack temp, PlayerInteractEvent event) { - if (temp.getItemMeta().getDisplayName().equalsIgnoreCase(lobbyLeaveItem.getItemMeta().getDisplayName()) && temp.getType() == lobbyLeaveItem.getType()) { + if (temp.isSimilar(lobbyLeaveItem)) { event.setCancelled(true); Main.getInstance().getGame().leave(event.getPlayer()); } - if (temp.getItemMeta().getDisplayName().equalsIgnoreCase(lobbyStartItem.getItemMeta().getDisplayName()) && temp.getType() == lobbyStartItem.getType() && event.getPlayer().hasPermission("hideandseek.start")) { + if (temp.isSimilar(lobbyStartItem) && event.getPlayer().hasPermission("hideandseek.start")) { event.setCancelled(true); if (Main.getInstance().getGame().isNotSetup()) { event.getPlayer().sendMessage(errorPrefix + message("GAME_SETUP")); @@ -57,7 +67,7 @@ public class InteractHandler implements Listener { } private void onPlayerInteractGame(ItemStack temp, PlayerInteractEvent event) { - if (temp.getItemMeta().getDisplayName().equalsIgnoreCase(glowPowerupItem.getItemMeta().getDisplayName()) && temp.getType() == glowPowerupItem.getType()) { + if (temp.isSimilar(glowPowerupItem)) { if (!glowEnabled) return; Player player = event.getPlayer(); if (Main.getInstance().getBoard().isHider(player)) { @@ -70,4 +80,61 @@ public class InteractHandler implements Listener { } } + private void onSpectatorInteract(ItemStack temp, PlayerInteractEvent event){ + if(temp.isSimilar(flightToggleItem)){ + boolean isFlying = event.getPlayer().getAllowFlight(); + event.getPlayer().setAllowFlight(!isFlying); + event.getPlayer().setFlying(!isFlying); + ActionBar.clearActionBar(event.getPlayer()); + if(!isFlying){ + ActionBar.sendActionBar(event.getPlayer(), message("FLYING_ENABLED").toString()); + } else { + ActionBar.sendActionBar(event.getPlayer(), message("FLYING_DISABLED").toString()); + } + return; + } + if(temp.isSimilar(teleportItem)){ + int amount = Main.getInstance().getBoard().getHiders().size() + Main.getInstance().getBoard().getSeekers().size(); + Inventory teleportMenu = Main.getInstance().getServer().createInventory(null, 9*(((amount-1)/9)+1), ChatColor.stripColor(teleportItem.getItemMeta().getDisplayName())); + List hider_lore = new ArrayList<>(); hider_lore.add(message("HIDER_TEAM_NAME").toString()); + Main.getInstance().getBoard().getHiders().forEach(hider -> { + teleportMenu.addItem(getSkull(hider, hider_lore)); + }); + List seeker_lore = new ArrayList<>(); seeker_lore.add(message("SEEKER_TEAM_NAME").toString()); + Main.getInstance().getBoard().getSeekers().forEach(seeker -> { + teleportMenu.addItem(getSkull(seeker, seeker_lore)); + }); + event.getPlayer().openInventory(teleportMenu); + } + } + + private ItemStack getSkull(Player player, List lore){ + assert XMaterial.PLAYER_HEAD.parseMaterial() != null; + ItemStack playerhead = new ItemStack(XMaterial.PLAYER_HEAD.parseMaterial(), 1); + SkullMeta playerheadmeta = (SkullMeta) playerhead.getItemMeta(); + playerheadmeta.setOwner(player.getName()); + playerheadmeta.setDisplayName(player.getName()); + playerheadmeta.setLore(lore); + playerhead.setItemMeta(playerheadmeta); + return playerhead; + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onInventoryClick(InventoryClickEvent event) { + if (event.getWhoClicked() instanceof Player) { + Player player = (Player) event.getWhoClicked(); + if (Main.getInstance().getBoard().contains(player) && Main.getInstance().getGame().getStatus() == Status.STANDBY) { + event.setCancelled(true); + } + if (Main.getInstance().getBoard().isSpectator(player) && event.getCurrentItem().getType() == XMaterial.PLAYER_HEAD.parseMaterial()) { + event.setCancelled(true); + player.closeInventory(); + String name = event.getCurrentItem().getItemMeta().getDisplayName(); + Player clicked = Main.getInstance().getServer().getPlayer(name); + if(clicked == null) return; + player.teleport(clicked); + } + } + } + } diff --git a/src/main/java/net/tylermurphy/hideAndSeek/game/listener/MovementHandler.java b/src/main/java/net/tylermurphy/hideAndSeek/game/listener/MovementHandler.java index 10872ad..aafc529 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/game/listener/MovementHandler.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/game/listener/MovementHandler.java @@ -1,23 +1,54 @@ package net.tylermurphy.hideAndSeek.game.listener; +import com.comphenix.protocol.PacketType; +import com.google.common.collect.Sets; import net.tylermurphy.hideAndSeek.Main; +import org.bukkit.Material; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerMoveEvent; +import java.util.Set; +import java.util.UUID; + import static net.tylermurphy.hideAndSeek.configuration.Config.*; import static net.tylermurphy.hideAndSeek.configuration.Config.saveMaxZ; public class MovementHandler implements Listener { + private final Set prevPlayersOnGround = Sets.newHashSet(); + @EventHandler(priority = EventPriority.HIGHEST) public void onMove(PlayerMoveEvent event) { + if (event.getTo() == null || event.getTo().getWorld() == null) return; + + checkJumping(event); + checkBounds(event); + } + + private void checkJumping(PlayerMoveEvent event){ + if (!Main.getInstance().getBoard().isSpectator(event.getPlayer())) return; + if (event.getPlayer().getVelocity().getY() > 0) { + if (event.getPlayer().getLocation().getBlock().getType() != Material.LADDER && prevPlayersOnGround.contains(event.getPlayer().getUniqueId())) { + if (!event.getPlayer().isOnGround()) { + // JUMPING :o + if(event.getPlayer().getAllowFlight()) event.getPlayer().setFlying(true); + } + } + } + if (event.getPlayer().isOnGround()) { + prevPlayersOnGround.add(event.getPlayer().getUniqueId()); + } else { + prevPlayersOnGround.remove(event.getPlayer().getUniqueId()); + } + } + + private void checkBounds(PlayerMoveEvent event){ if (!Main.getInstance().getBoard().contains(event.getPlayer())) return; if (!event.getPlayer().getWorld().getName().equals(Main.getInstance().getGame().getGameWorld())) return; - if (event.getPlayer().hasPermission("hideandseek.leavebounds")) return; - if (event.getTo() == null || event.getTo().getWorld() == null) return; if (!event.getTo().getWorld().getName().equals(Main.getInstance().getGame().getGameWorld())) return; + if (event.getPlayer().hasPermission("hideandseek.leavebounds")) return; if (event.getTo().getBlockX() < saveMinX || event.getTo().getBlockX() > saveMaxX || event.getTo().getBlockZ() < saveMinZ || event.getTo().getBlockZ() > saveMaxZ) { event.setCancelled(true); } diff --git a/src/main/java/net/tylermurphy/hideAndSeek/game/listener/PlayerHandler.java b/src/main/java/net/tylermurphy/hideAndSeek/game/listener/PlayerHandler.java index b63d982..d8790fd 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/game/listener/PlayerHandler.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/game/listener/PlayerHandler.java @@ -1,15 +1,12 @@ package net.tylermurphy.hideAndSeek.game.listener; import net.tylermurphy.hideAndSeek.Main; -import net.tylermurphy.hideAndSeek.game.Game; -import net.tylermurphy.hideAndSeek.game.util.Status; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityRegainHealthEvent; import org.bukkit.event.entity.FoodLevelChangeEvent; -import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.player.PlayerDropItemEvent; public class PlayerHandler implements Listener { @@ -32,16 +29,6 @@ public class PlayerHandler implements Listener { } } - @EventHandler(priority = EventPriority.HIGHEST) - public void onInventoryClick(InventoryClickEvent event) { - if (event.getWhoClicked() instanceof Player) { - Player player = (Player) event.getWhoClicked(); - if (Main.getInstance().getBoard().contains(player) && Main.getInstance().getGame().getStatus() == Status.STANDBY) { - event.setCancelled(true); - } - } - } - @EventHandler(priority = EventPriority.HIGHEST) public void onItemDrop(PlayerDropItemEvent event) { if (Main.getInstance().getBoard().contains(event.getPlayer())) { diff --git a/src/main/java/net/tylermurphy/hideAndSeek/game/util/PlayerUtil.java b/src/main/java/net/tylermurphy/hideAndSeek/game/util/PlayerUtil.java index 61d2b0e..59c7b73 100644 --- a/src/main/java/net/tylermurphy/hideAndSeek/game/util/PlayerUtil.java +++ b/src/main/java/net/tylermurphy/hideAndSeek/game/util/PlayerUtil.java @@ -43,6 +43,8 @@ public class PlayerUtil { 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); }); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 75658b6..c509200 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -130,6 +130,7 @@ glow: name: "Glow Powerup" lore: [ "Throw to make all seekers glow", "Last 30s, all hiders can see it", "Time stacks on multi use" ] material: SNOWBALL + model-data: 0 # The message prefixes displayed before messages. The message contents themselves # can be changed in localization.yml. @@ -182,6 +183,23 @@ lobbyItems: enabled: true adminOnly: true +# Below are the two items given to you when you join the game as a spectator. One toggles flight mode, and the other +# opens a gui to teleport to other players! Just like the lobby items, you can customize the material, name, lore, +# and position of the item. You can also change the model data if your server is running 1.14 or above. +spectatorItems: + flight: + material: FEATHER + name: "&bToggle Flight" + lore: [ "Turns flying on and off" ] + position: 3 + model-data: 0 + teleport: + material: COMPASS + name: "&bTeleport to Others" + lore: [ "Allows you to teleport to all other players in game" ] + position: 5 + model-data: 0 + # As a hider, the closer a seeker gets to you, the louder and faster a pining noise will play. # There are 3 separate distances (in blocks) you can set to the 3 different levels for the noise. # The higher the level, the closer the seeker. diff --git a/src/main/resources/lang/localization_de-DE.yml b/src/main/resources/lang/localization_de-DE.yml index fec12ba..84ada18 100644 --- a/src/main/resources/lang/localization_de-DE.yml +++ b/src/main/resources/lang/localization_de-DE.yml @@ -70,6 +70,8 @@ Localization: NO_GAME_INFO: "Keine Informationen zum Gameplay für diesen Spieler vorhanden." INFORMATION_FOR: "Gewinninformationen für {PLAYER}:" BLOCKED_COMMAND: "Command blocked by Kenshin's Hide And Seek" + FLYING_ENABLED: "Fliegen aktiviert" + FLYING_DISABLED: "Fliegen deaktiviert" # DO NOT EDIT IT OR IT MAY BREAK OR RESET FILE version: 3 diff --git a/src/main/resources/lang/localization_en-US.yml b/src/main/resources/lang/localization_en-US.yml index 1115fc4..07d547b 100644 --- a/src/main/resources/lang/localization_en-US.yml +++ b/src/main/resources/lang/localization_en-US.yml @@ -71,6 +71,8 @@ Localization: NO_GAME_INFO: "Player has no gameplay information." INFORMATION_FOR: "Win information for {PLAYER}:" BLOCKED_COMMAND: "Command blocked by Hide And Seek plugin." + FLYING_ENABLED: "&l&bFlying Enabled" + FLYING_DISABLED: "&l&bFlying Disabled" # DO NOT EDIT IT OR IT MAY BREAK OR RESET FILE version: 3