diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..bb5e6bd --- /dev/null +++ b/.classpath @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/.gradle/8.14.1/checksums/checksums.lock b/.gradle/8.14.1/checksums/checksums.lock deleted file mode 100644 index 3226b96..0000000 Binary files a/.gradle/8.14.1/checksums/checksums.lock and /dev/null differ diff --git a/.gradle/8.14.1/checksums/md5-checksums.bin b/.gradle/8.14.1/checksums/md5-checksums.bin deleted file mode 100644 index e39ec97..0000000 Binary files a/.gradle/8.14.1/checksums/md5-checksums.bin and /dev/null differ diff --git a/.gradle/8.14.1/checksums/sha1-checksums.bin b/.gradle/8.14.1/checksums/sha1-checksums.bin deleted file mode 100644 index 50dda50..0000000 Binary files a/.gradle/8.14.1/checksums/sha1-checksums.bin and /dev/null differ diff --git a/.gradle/8.14.1/executionHistory/executionHistory.lock b/.gradle/8.14.1/executionHistory/executionHistory.lock deleted file mode 100644 index 7dd3d95..0000000 Binary files a/.gradle/8.14.1/executionHistory/executionHistory.lock and /dev/null differ diff --git a/.gradle/8.14.1/fileChanges/last-build.bin b/.gradle/8.14.1/fileChanges/last-build.bin deleted file mode 100644 index f76dd23..0000000 Binary files a/.gradle/8.14.1/fileChanges/last-build.bin and /dev/null differ diff --git a/.gradle/8.14.1/fileHashes/fileHashes.lock b/.gradle/8.14.1/fileHashes/fileHashes.lock deleted file mode 100644 index 12a7b4b..0000000 Binary files a/.gradle/8.14.1/fileHashes/fileHashes.lock and /dev/null differ diff --git a/.gradle/8.14.1/gc.properties b/.gradle/8.14.1/gc.properties deleted file mode 100644 index e69de29..0000000 diff --git a/.gradle/8.8/checksums/checksums.lock b/.gradle/8.8/checksums/checksums.lock deleted file mode 100644 index 074a6a0..0000000 Binary files a/.gradle/8.8/checksums/checksums.lock and /dev/null differ diff --git a/.gradle/8.8/checksums/md5-checksums.bin b/.gradle/8.8/checksums/md5-checksums.bin deleted file mode 100644 index 9770ed1..0000000 Binary files a/.gradle/8.8/checksums/md5-checksums.bin and /dev/null differ diff --git a/.gradle/8.8/checksums/sha1-checksums.bin b/.gradle/8.8/checksums/sha1-checksums.bin deleted file mode 100644 index 96f0b2d..0000000 Binary files a/.gradle/8.8/checksums/sha1-checksums.bin and /dev/null differ diff --git a/.gradle/8.8/dependencies-accessors/gc.properties b/.gradle/8.8/dependencies-accessors/gc.properties deleted file mode 100644 index e69de29..0000000 diff --git a/.gradle/8.8/executionHistory/executionHistory.lock b/.gradle/8.8/executionHistory/executionHistory.lock deleted file mode 100644 index 3405bea..0000000 Binary files a/.gradle/8.8/executionHistory/executionHistory.lock and /dev/null differ diff --git a/.gradle/8.8/fileChanges/last-build.bin b/.gradle/8.8/fileChanges/last-build.bin deleted file mode 100644 index f76dd23..0000000 Binary files a/.gradle/8.8/fileChanges/last-build.bin and /dev/null differ diff --git a/.gradle/8.8/fileHashes/fileHashes.bin b/.gradle/8.8/fileHashes/fileHashes.bin deleted file mode 100644 index c371daf..0000000 Binary files a/.gradle/8.8/fileHashes/fileHashes.bin and /dev/null differ diff --git a/.gradle/8.8/fileHashes/fileHashes.lock b/.gradle/8.8/fileHashes/fileHashes.lock deleted file mode 100644 index f8a0d47..0000000 Binary files a/.gradle/8.8/fileHashes/fileHashes.lock and /dev/null differ diff --git a/.gradle/8.8/gc.properties b/.gradle/8.8/gc.properties deleted file mode 100644 index e69de29..0000000 diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock index 35e1805..b657368 100644 Binary files a/.gradle/buildOutputCleanup/buildOutputCleanup.lock and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/.gradle/buildOutputCleanup/cache.properties b/.gradle/buildOutputCleanup/cache.properties deleted file mode 100644 index 528a962..0000000 --- a/.gradle/buildOutputCleanup/cache.properties +++ /dev/null @@ -1,2 +0,0 @@ -#Sat Jun 21 03:09:22 MSK 2025 -gradle.version=8.14.1 diff --git a/.idea/hotswap_agent.xml b/.idea/hotswap_agent.xml new file mode 100644 index 0000000..88fa3d9 --- /dev/null +++ b/.idea/hotswap_agent.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/modules/BlockAndSeek.iml b/.idea/modules/BlockAndSeek.iml new file mode 100644 index 0000000..c72e27f --- /dev/null +++ b/.idea/modules/BlockAndSeek.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.project b/.project new file mode 100644 index 0000000..3fa369c --- /dev/null +++ b/.project @@ -0,0 +1,34 @@ + + + BlockAndSeek + Project BlockAndSeek created by Buildship. + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.buildship.core.gradleprojectnature + + + + 1750464766576 + + 30 + + org.eclipse.core.resources.regexFilterMatcher + node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ + + + + diff --git a/src/main/java/hdvtdev/blockAndSeek/BlockAndSeek.java b/src/main/java/hdvtdev/blockAndSeek/BlockAndSeek.java index bd6eab2..54478eb 100644 --- a/src/main/java/hdvtdev/blockAndSeek/BlockAndSeek.java +++ b/src/main/java/hdvtdev/blockAndSeek/BlockAndSeek.java @@ -1,5 +1,6 @@ package hdvtdev.blockAndSeek; +import hdvtdev.blockAndSeek.eventListeners.DefaultEventListener; import hdvtdev.blockAndSeek.eventListeners.EventListener; import hdvtdev.blockAndSeek.eventListeners.ForceControlEventListener; import hdvtdev.blockAndSeek.managers.ConfigManager; @@ -66,15 +67,12 @@ public class BlockAndSeek extends JavaPlugin { getLogger().severe("Failed to save some .yml configs!"); } - - getLogger().warning(ConfigManager.getConfig().toString()); - PluginCommand command = Objects.requireNonNull(getCommand("blockandseek")); command.setExecutor(new CommandListener()); PluginManager manager = getServer().getPluginManager(); - if (ConfigManager.getConfig().forceControl()) manager.registerEvents(new ForceControlEventListener(), this); - manager.registerEvents(new EventListener(), this); + manager.registerEvents(ConfigManager.getConfig().forceControl() ? new ForceControlEventListener() : new EventListener(), this); + manager.registerEvents(new DefaultEventListener(), this); } diff --git a/src/main/java/hdvtdev/blockAndSeek/BlockAndSeekGame.java b/src/main/java/hdvtdev/blockAndSeek/BlockAndSeekGame.java index 534a836..227b703 100644 --- a/src/main/java/hdvtdev/blockAndSeek/BlockAndSeekGame.java +++ b/src/main/java/hdvtdev/blockAndSeek/BlockAndSeekGame.java @@ -14,10 +14,7 @@ import org.bukkit.persistence.PersistentDataType; import org.bukkit.scheduler.BukkitRunnable; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; @@ -113,6 +110,10 @@ public class BlockAndSeekGame { return players.values().stream().filter(type -> type == PlayerType.HIDER).count(); } + private long getSeekersCount() { + return players.values().stream().filter(type -> type == PlayerType.SEEKER).count(); + } + private List getSeekers() { return players.entrySet().stream().filter(entry -> entry.getValue() == PlayerType.SEEKER).map(Map.Entry::getKey).toList(); } @@ -136,7 +137,7 @@ public class BlockAndSeekGame { PlayerInventory inventory = hider.getInventory(); inventory.clear(); inventory.addItem(Localization.translateItem(hider, ItemManager.getFreezeItem())); - RouletteCreator.createRoulette(hider, null, true, map.getBlocks()); + new RouletteCreator(hider, map.getBlocks()); } } @@ -154,6 +155,7 @@ public class BlockAndSeekGame { if (defaultInventory) ItemManager.defaultInventory(player); player.setGlowing(false); player.setInvulnerable(false); + Utils.setLevelWithBar(player, 0); player.setVisibleByDefault(true); player.setGameMode(GameMode.SURVIVAL); player.teleport(serverLobby); @@ -163,23 +165,31 @@ public class BlockAndSeekGame { } private void preEnd() { + for (Player player : players.keySet()) { + player.setInvulnerable(true); + } for (Player hider : getHiders()) { hider.getInventory().clear(); FreezeManager.unfreezeIfFrozen(hider); hider.setGlowing(true); - hider.setInvulnerable(true); } } public void selectRandomSeekers(int count) { - ArrayList playerList = new ArrayList<>(players.keySet()); - Collections.shuffle(playerList); - List seekers = playerList.subList(0, Math.min(count, playerList.size())); - for (Player seeker : seekers) { + ArrayList rawSeekers = new ArrayList<>(); + Set playerSet = players.keySet(); + for (Player player : playerSet) { + if (!GamesManager.triggerSeekerImmune(player)) rawSeekers.add(player); + } + Collections.shuffle(rawSeekers); + + for (Player seeker : rawSeekers.subList(0, Math.min(count, playerSet.size()))) { players.put(seeker, PlayerType.SEEKER); ItemManager.setSeekerSet(seeker); + Utils.setLevelWithBar(seeker, 100); seeker.setInvulnerable(false); seeker.getPersistentDataContainer().set(Keys.SEEKER, PersistentDataType.BOOLEAN, true); + GamesManager.addSeekerImmune(seeker); } } @@ -235,7 +245,10 @@ public class BlockAndSeekGame { } } + if (getSeekersCount() == 0) duration = 0; + if (duration == 0) { + preEnd(); if (getHidersCount() == 1) { Localization.sendTitle( diff --git a/src/main/java/hdvtdev/blockAndSeek/CommandListener.java b/src/main/java/hdvtdev/blockAndSeek/CommandListener.java index 9012737..33edc39 100644 --- a/src/main/java/hdvtdev/blockAndSeek/CommandListener.java +++ b/src/main/java/hdvtdev/blockAndSeek/CommandListener.java @@ -76,10 +76,22 @@ public class CommandListener implements TabExecutor { DisguiseAPI.disguiseToAll(player, new MiscDisguise(DisguiseType.FALLING_BLOCK, new ItemStack(material))); } } - + + case "damage" -> { + if (sender instanceof Player player && args.length == 2) { + player.damage(Double.parseDouble(args[1])); + } + } + + case "health" -> { + if (sender instanceof Player player && args.length == 2) { + player.setHealth(Double.parseDouble(args[1])); + } + } + case "new" -> { if (sender instanceof Player player) { - RouletteCreator.newCreateRoulette(player, List.of( + new RouletteCreator(player, List.of( new BlockAndSeekMap.Block(new ItemStack(Material.STONE), 10), new BlockAndSeekMap.Block(new ItemStack(Material.DIRT), 10), new BlockAndSeekMap.Block(new ItemStack(Material.LANTERN), 10), diff --git a/src/main/java/hdvtdev/blockAndSeek/Utils.java b/src/main/java/hdvtdev/blockAndSeek/Utils.java new file mode 100644 index 0000000..91319ba --- /dev/null +++ b/src/main/java/hdvtdev/blockAndSeek/Utils.java @@ -0,0 +1,35 @@ +package hdvtdev.blockAndSeek; + +import hdvtdev.blockAndSeek.managers.FreezeManager; +import me.libraryaddict.disguise.DisguiseAPI; +import me.libraryaddict.disguise.disguisetypes.DisguiseType; +import me.libraryaddict.disguise.disguisetypes.MiscDisguise; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public final class Utils { + + private Utils() { + } + + public static void setLevelWithBar(Player p, int level) { + p.setLevel(level); + p.setExp(0.9998f * ((float) level / 100)); + } + + public static boolean isInOneTeam(Player p1, Player p2) { + var c1 = p1.getPersistentDataContainer(); + var c2 = p2.getPersistentDataContainer(); + return (c1.has(Keys.HIDER) && c2.has(Keys.HIDER)) || (c1.has(Keys.SEEKER) && c2.has(Keys.SEEKER)); + } + + public static boolean playerInGame(Player player) { + return player.getPersistentDataContainer().has(Keys.GAME); + } + + public static void firstDisguise(Player player, ItemStack prop) { + DisguiseAPI.disguiseToAll(player, new MiscDisguise(DisguiseType.FALLING_BLOCK, prop)); + FreezeManager.addPlayerDisguise(player, prop.getType().createBlockData()); + } + +} diff --git a/src/main/java/hdvtdev/blockAndSeek/eventListeners/DefaultEventListener.java b/src/main/java/hdvtdev/blockAndSeek/eventListeners/DefaultEventListener.java new file mode 100644 index 0000000..df9d59f --- /dev/null +++ b/src/main/java/hdvtdev/blockAndSeek/eventListeners/DefaultEventListener.java @@ -0,0 +1,269 @@ +package hdvtdev.blockAndSeek.eventListeners; + +import hdvtdev.blockAndSeek.BlockAndSeek; +import hdvtdev.blockAndSeek.Keys; +import hdvtdev.blockAndSeek.Utils; +import hdvtdev.blockAndSeek.managers.FreezeManager; +import hdvtdev.blockAndSeek.managers.GamesManager; +import hdvtdev.blockAndSeek.managers.GuiManager; +import hdvtdev.blockAndSeek.roulette.RouletteCreator; +import org.bukkit.Bukkit; +import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockDamageEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDismountEvent; +import org.bukkit.event.entity.EntityRegainHealthEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; +import org.bukkit.scheduler.BukkitScheduler; +import org.bukkit.scheduler.BukkitTask; + +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import static hdvtdev.blockAndSeek.Utils.isInOneTeam; +import static hdvtdev.blockAndSeek.Utils.playerInGame; + +public class DefaultEventListener implements Listener { + + private static final BukkitScheduler scheduler = Bukkit.getScheduler(); + private static final Set coolDown = ConcurrentHashMap.newKeySet(); + + @Deprecated(forRemoval = true) + private static final ConcurrentHashMap tasks = new ConcurrentHashMap<>(); + + @Deprecated(forRemoval = true) + public static void createTask(Player player, BukkitTask bukkitTask) { + tasks.put(player, bukkitTask); + } + + @Deprecated(forRemoval = true) + public static void stopTask(Player player) { + BukkitTask task = tasks.remove(player); + task.cancel(); + } + + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + Player player = event.getPlayer(); + if (player.getVehicle() instanceof ArmorStand armorStand) { + PersistentDataContainer armorStandContainer = armorStand.getPersistentDataContainer(); + if (armorStandContainer.has(Keys.FROZEN_PLAYER)) { + armorStandContainer.remove(Keys.FROZEN_PLAYER); + armorStand.remove(); + } + } + } + + @EventHandler + public void onBlockDamage(BlockDamageEvent event) { + Player player = event.getPlayer(); + if (player.getPersistentDataContainer().has(Keys.SEEKER)) { + if (FreezeManager.unfreeze(event.getBlock().getBlockData())) { + event.setCancelled(true); + } else { + player.damage(2); + Utils.setLevelWithBar(player, (int) Math.round(player.getHealth() * 5)); + } + } + } + + @EventHandler + public void onRightClick(PlayerInteractEvent event) { + if (event.getHand() != EquipmentSlot.HAND) return; + Action action = event.getAction(); + Player player = event.getPlayer(); + if (action.isRightClick() && !coolDown.contains(player)) { + + + ItemStack itemInHand = player.getInventory().getItemInMainHand(); + ItemMeta meta = itemInHand.getItemMeta(); + + if (meta != null) { + PersistentDataContainer itemData = meta.getPersistentDataContainer(); + if (itemData.has(Keys.FREEZE_ITEM) && playerInGame(player)) { + coolDown.add(player); + scheduler.runTaskLater(BlockAndSeek.getInstance(), () -> coolDown.remove(player), 3L); + FreezeManager.freeze(player); + event.setCancelled(true); + } else if (itemData.has(Keys.MENU_ITEM)) { + GuiManager.Menu.open(player); + event.setCancelled(true); + } else if (itemData.has(Keys.LEAVE_ITEM)) { + String game = player.getPersistentDataContainer().get(Keys.GAME, PersistentDataType.STRING); + GamesManager.get(game).removePlayer(player); + event.setCancelled(true); + } + } + + + } + + } + + @EventHandler + public void onEntityDismount(EntityDismountEvent event) { + Player player = (Player) event.getEntity(); + if (event.getDismounted() instanceof ArmorStand armorStand && armorStand.getPersistentDataContainer().has(Keys.FROZEN_PLAYER)) { + FreezeManager.freeze(player); + } + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + Player player = event.getPlayer(); + PersistentDataContainer container = player.getPersistentDataContainer(); + + String arena = container.get(Keys.GAME, PersistentDataType.STRING); + if (arena != null) { + GamesManager.get(arena).removePlayer(player); + FreezeManager.removePlayerDisguise(player); + } + } + + @EventHandler + public void onPlayerDeath(PlayerDeathEvent event) { + Player player = event.getPlayer(); + String game = player.getPersistentDataContainer().get(Keys.GAME, PersistentDataType.STRING); + if (game != null) { + event.deathMessage(null); + event.setDroppedExp(0); + event.getDrops().clear(); + scheduler.runTask(BlockAndSeek.getInstance(), () -> GamesManager.get(game).setSpectator(player, player.getKiller())); + //without scheduler strange things are happening idk + } + } + + @EventHandler + public void onInventoryClose(InventoryCloseEvent event) { + + Player player = (Player) event.getPlayer(); + InventoryHolder holder = event.getInventory().getHolder(); + + + if (holder instanceof RouletteCreator rouletteCreator) { + if (rouletteCreator.isClosedByPlayer()) { + RouletteCreator.Task task = rouletteCreator.getTask(); + + if (!task.rouletteTask().isCancelled()) { + task.cancelBoth(); + Utils.firstDisguise(player, rouletteCreator.randomPropItem()); + } else Utils.firstDisguise(player, rouletteCreator.randomMidPropItem()); //FIXME THIS FUCKING LINE AAAA + + } else Utils.firstDisguise(player, rouletteCreator.randomMidPropItem()); + } + + + } + + @EventHandler + public void onInventoryClick(InventoryClickEvent event) { + Player player = (Player) event.getWhoClicked(); + Inventory inventory = event.getClickedInventory(); + + + if (inventory != null) { + + InventoryHolder holder = inventory.getHolder(); + int slot = event.getSlot(); + ItemStack item = inventory.getItem(slot); + + if (holder instanceof RouletteCreator rouletteCreator) { + RouletteCreator.Task task = rouletteCreator.getTask(); + + if (task.rouletteTask().isCancelled()) { + if (slot == 21 || slot == 23 || slot == 25) { + task.autoCloseTask().cancel(); + Utils.firstDisguise(player, inventory.getItem(slot)); + rouletteCreator.closeInventoryByPlayer(); + } + event.setCancelled(true); + return; + } else { + if (slot == 36) { + task.rouletteTask().cancel(); + Utils.firstDisguise(player, rouletteCreator.randomPropItem()); + rouletteCreator.closeInventory(); + event.setCancelled(true); + return; + } + } + + + } + + + if (item != null) { + ItemMeta meta = item.getItemMeta(); + if (meta != null) { + PersistentDataContainer itemData = meta.getPersistentDataContainer(); + + if (itemData.has(Keys.GAME_PAGE)) { + GuiManager.Menu.Games.open(player); + event.setCancelled(true); + } else if (itemData.has(Keys.GAME)) { + String game = itemData.get(Keys.GAME, PersistentDataType.STRING); + if (game != null) { + GamesManager.get(game).addPlayer(player); + event.setCancelled(true); + } + } + } + } + + } + + //TODO MOVE TO EVENT LISTENER + if (player.getPersistentDataContainer().has(Keys.GAME)) { + event.setCancelled(true); + } + + + } + + @EventHandler + public void onRegainHealth(EntityRegainHealthEvent event) { + if (event.getEntity() instanceof Player player) { + if (player.getPersistentDataContainer().has(Keys.SEEKER)) { + event.setCancelled(true); + } + } + } + + + @EventHandler + public void onPlayerDamage(EntityDamageByEntityEvent event) { + if (event.getDamager() instanceof Player damager && event.getEntity() instanceof Player victim) { + if (isInOneTeam(damager, victim)) { + event.setCancelled(true); + } else if (victim.getPersistentDataContainer().has(Keys.SEEKER)) { + event.setDamage(0); + } else if (damager.getPersistentDataContainer().has(Keys.SEEKER)) { + double maxHealth = 20.0; + double currentHealth = damager.getHealth(); + if (currentHealth < maxHealth) { + double newHealth = Math.min(currentHealth + event.getDamage(), maxHealth); + damager.setHealth(newHealth); + Utils.setLevelWithBar(damager, (int) Math.round(damager.getHealth() * 5)); + } + } + } + } + +} diff --git a/src/main/java/hdvtdev/blockAndSeek/eventListeners/EventListener.java b/src/main/java/hdvtdev/blockAndSeek/eventListeners/EventListener.java index fa5345d..3040b8c 100644 --- a/src/main/java/hdvtdev/blockAndSeek/eventListeners/EventListener.java +++ b/src/main/java/hdvtdev/blockAndSeek/eventListeners/EventListener.java @@ -1,176 +1,30 @@ package hdvtdev.blockAndSeek.eventListeners; - -import hdvtdev.blockAndSeek.BlockAndSeek; import hdvtdev.blockAndSeek.Keys; -import hdvtdev.blockAndSeek.managers.FreezeManager; -import hdvtdev.blockAndSeek.managers.GamesManager; -import hdvtdev.blockAndSeek.managers.GuiManager; -import hdvtdev.blockAndSeek.managers.ItemManager; -import me.libraryaddict.disguise.DisguiseAPI; -import me.libraryaddict.disguise.disguisetypes.DisguiseType; -import me.libraryaddict.disguise.disguisetypes.MiscDisguise; -import org.bukkit.Bukkit; -import org.bukkit.entity.ArmorStand; +import hdvtdev.blockAndSeek.Utils; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; -import org.bukkit.event.block.Action; import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.event.block.BlockDamageEvent; import org.bukkit.event.block.BlockPlaceEvent; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.entity.EntityDismountEvent; import org.bukkit.event.entity.FoodLevelChangeEvent; -import org.bukkit.event.entity.PlayerDeathEvent; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryCloseEvent; import org.bukkit.event.player.PlayerDropItemEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.inventory.EquipmentSlot; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.persistence.PersistentDataContainer; -import org.bukkit.persistence.PersistentDataType; -import org.bukkit.scheduler.BukkitScheduler; -import org.bukkit.scheduler.BukkitTask; - -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - public class EventListener implements Listener { - private static final BukkitScheduler scheduler = Bukkit.getScheduler(); - - private static final Set coolDown = ConcurrentHashMap.newKeySet(); - - private static final ConcurrentHashMap tasks = new ConcurrentHashMap<>(); - private static final ConcurrentHashMap soundCoolDown = new ConcurrentHashMap<>(); - - private static final ItemStack menuItem = ItemManager.getMenuItem(); - - public static void createTask(Player player, BukkitTask bukkitTask) { - tasks.put(player, bukkitTask); - } - - public static void stopTask(Player player) { - BukkitTask task = tasks.remove(player); - task.cancel(); - } - - private static boolean playerInGame(Player player) { - return player.getPersistentDataContainer().has(Keys.GAME); - } - - private static boolean isInOneTeam(Player p1, Player p2) { - var c1 = p1.getPersistentDataContainer(); - var c2 = p2.getPersistentDataContainer(); - return (c1.has(Keys.HIDER) && c2.has(Keys.HIDER)) || (c1.has(Keys.SEEKER) && c2.has(Keys.SEEKER)); - } - @EventHandler public void onDrop(PlayerDropItemEvent event) { if (event.getPlayer().getPersistentDataContainer().has(Keys.GAME)) event.setCancelled(true); } - @EventHandler - public void onBlockDamage(BlockDamageEvent event) { - if (event.getPlayer().getPersistentDataContainer().has(Keys.SEEKER)) { - if (FreezeManager.unfreeze(event.getBlock().getBlockData())) event.setCancelled(true); - } - } - - @EventHandler - public void onPlayerJoin(PlayerJoinEvent event) { - Player player = event.getPlayer(); - if (player.getVehicle() instanceof ArmorStand armorStand) { - PersistentDataContainer armorStandContainer = armorStand.getPersistentDataContainer(); - if (armorStandContainer.has(Keys.FROZEN_PLAYER)) { - armorStandContainer.remove(Keys.FROZEN_PLAYER); - armorStand.remove(); - } - } - } - - @EventHandler - public void onPlayerQuit(PlayerQuitEvent event) { - Player player = event.getPlayer(); - PersistentDataContainer container = player.getPersistentDataContainer(); - - String arena = container.get(Keys.GAME, PersistentDataType.STRING); - if (arena != null) { - GamesManager.get(arena).removePlayer(player); - FreezeManager.removePlayerDisguise(player); - } - } - - @EventHandler - public void onPlayerDeath(PlayerDeathEvent event) { - Player player = event.getPlayer(); - String game = player.getPersistentDataContainer().get(Keys.GAME, PersistentDataType.STRING); - if (game != null) { - event.deathMessage(null); - event.setDroppedExp(0); - event.getDrops().clear(); - scheduler.runTask(BlockAndSeek.getInstance(), () -> GamesManager.get(game).setSpectator(player, player.getKiller())); - //without scheduler strange things are happening idk - } - } - - @EventHandler - public void onEntityDismount(EntityDismountEvent event) { - Player player = (Player) event.getEntity(); - if (event.getDismounted() instanceof ArmorStand armorStand && armorStand.getPersistentDataContainer().has(Keys.FROZEN_PLAYER)) { - FreezeManager.freeze(player); - } - } - @EventHandler public void onFoodLevelChange(FoodLevelChangeEvent event) { - if (event.getEntity() instanceof Player player && playerInGame(player)) { + if (event.getEntity() instanceof Player player && Utils.playerInGame(player)) { event.setCancelled(true); event.getEntity().setFoodLevel(20); } } - - @EventHandler - public void onRightClick(PlayerInteractEvent event) { - if (event.getHand() != EquipmentSlot.HAND) return; - Action action = event.getAction(); - Player player = event.getPlayer(); - if (action.isRightClick() && !coolDown.contains(player)) { - - - ItemStack itemInHand = player.getInventory().getItemInMainHand(); - ItemMeta meta = itemInHand.getItemMeta(); - - if (meta != null) { - PersistentDataContainer itemData = meta.getPersistentDataContainer(); - if (itemData.has(Keys.FREEZE_ITEM) && playerInGame(player)) { - coolDown.add(player); - scheduler.runTaskLater(BlockAndSeek.getInstance(), () -> coolDown.remove(player), 3L); - FreezeManager.freeze(player); - event.setCancelled(true); - } else if (itemData.has(Keys.MENU_ITEM)) { - GuiManager.Menu.open(player); - event.setCancelled(true); - } else if (itemData.has(Keys.LEAVE_ITEM)) { - String game = player.getPersistentDataContainer().get(Keys.GAME, PersistentDataType.STRING); - GamesManager.get(game).removePlayer(player); - event.setCancelled(true); - } - } - - - } - - } - @EventHandler public void onBlockPlacement(BlockPlaceEvent event) { if (event.getPlayer().getPersistentDataContainer().has(Keys.GAME)) event.setCancelled(true); @@ -181,85 +35,5 @@ public class EventListener implements Listener { if (event.getPlayer().getPersistentDataContainer().has(Keys.GAME)) event.setCancelled(true); } - @EventHandler - public void onPlayerDamage(EntityDamageByEntityEvent event) { - if (event.getDamager() instanceof Player damager && event.getEntity() instanceof Player victim) { - if (isInOneTeam(damager, victim)) { - event.setCancelled(true); - } - } - } - - @EventHandler - public void onInventoryClick(InventoryClickEvent event) { - Player player = (Player) event.getWhoClicked(); - Inventory inventory = event.getClickedInventory(); - - - if (inventory != null) { - - ItemStack item = inventory.getItem(event.getSlot()); - - - if (item != null) { - ItemMeta meta = item.getItemMeta(); - if (meta != null) { - PersistentDataContainer itemData = meta.getPersistentDataContainer(); - - if (itemData.has(Keys.GAME_PAGE)) { - GuiManager.Menu.Games.open(player); - event.setCancelled(true); - } else if (itemData.has(Keys.GAME)) { - String game = itemData.get(Keys.GAME, PersistentDataType.STRING); - if (game != null) { - GamesManager.get(game).addPlayer(player); - event.setCancelled(true); - } - } - } - } - - } - - if (player.getPersistentDataContainer().has(Keys.GAME)) { - event.setCancelled(true); - } - - if (player.hasMetadata("RollingMenu")) { - event.setCancelled(true); - int slot = event.getSlot(); - if (slot == 21 || slot == 23 || slot == 25) { - if (!tasks.containsKey(player)) { - ItemStack prop = event.getInventory().getItem(slot); - FreezeManager.addPlayerDisguise(player, prop.getType().createBlockData()); - MiscDisguise miscDisguise = new MiscDisguise(DisguiseType.FALLING_BLOCK, prop); - DisguiseAPI.disguiseToAll(player, miscDisguise); - player.closeInventory(InventoryCloseEvent.Reason.UNKNOWN); - } - } - } - - - } - - @EventHandler - public void onInventoryClose(InventoryCloseEvent event) { - - Player player = (Player) event.getPlayer(); - if (player.hasMetadata("RollingMenu")) { - if (!tasks.containsKey(player)) { - player.removeMetadata("RollingMenu", BlockAndSeek.getInstance()); - if (!event.getReason().equals(InventoryCloseEvent.Reason.UNKNOWN)) { - ItemStack prop = event.getInventory().getItem(21); - FreezeManager.addPlayerDisguise(player, prop.getType().createBlockData()); - MiscDisguise miscDisguise = new MiscDisguise(DisguiseType.FALLING_BLOCK, prop); - DisguiseAPI.disguiseToAll(player, miscDisguise); - } - } else { - Bukkit.getScheduler().runTaskLater(BlockAndSeek.getInstance(), () -> player.openInventory(event.getInventory()), 0L); - } - - } - } } diff --git a/src/main/java/hdvtdev/blockAndSeek/managers/FreezeManager.java b/src/main/java/hdvtdev/blockAndSeek/managers/FreezeManager.java index b6f0ec6..3302709 100644 --- a/src/main/java/hdvtdev/blockAndSeek/managers/FreezeManager.java +++ b/src/main/java/hdvtdev/blockAndSeek/managers/FreezeManager.java @@ -56,7 +56,7 @@ public class FreezeManager { location.getWorld().setBlockData(blockLocation, data.blockData); player.getPersistentDataContainer().remove(Keys.FROZEN_PLAYER); - + player.setFreezeTicks(0); data.armorStand.remove(); player.setInvulnerable(false); @@ -110,6 +110,8 @@ public class FreezeManager { DisguiseAPI.disguiseToAll(player, hideDisguise); + player.setFreezeTicks(40); + frozenPlayers.put(player, new FreezeData(armorStand, blockData, disguise)); } else return false; diff --git a/src/main/java/hdvtdev/blockAndSeek/managers/GamesManager.java b/src/main/java/hdvtdev/blockAndSeek/managers/GamesManager.java index bfc4c3d..2ce45a7 100644 --- a/src/main/java/hdvtdev/blockAndSeek/managers/GamesManager.java +++ b/src/main/java/hdvtdev/blockAndSeek/managers/GamesManager.java @@ -3,13 +3,9 @@ package hdvtdev.blockAndSeek.managers; import hdvtdev.blockAndSeek.BlockAndSeek; import hdvtdev.blockAndSeek.BlockAndSeekGame; import hdvtdev.blockAndSeek.BlockAndSeekMap; -import hdvtdev.blockAndSeek.Localization; import org.bukkit.Bukkit; import org.bukkit.WorldCreator; -import org.bukkit.scoreboard.Criteria; -import org.bukkit.scoreboard.DisplaySlot; -import org.bukkit.scoreboard.Objective; -import org.bukkit.scoreboard.Scoreboard; +import org.bukkit.entity.Player; import java.io.File; import java.util.Set; @@ -18,9 +14,14 @@ import java.util.concurrent.ConcurrentHashMap; public class GamesManager { private static final ConcurrentHashMap games = new ConcurrentHashMap<>(); + private static final Set seekerImmune = ConcurrentHashMap.newKeySet(); - public static boolean isExist(String name) { - return games.containsKey(name); + public static boolean triggerSeekerImmune(Player player) { + return seekerImmune.remove(player); + } + + public static void addSeekerImmune(Player player) { + seekerImmune.add(player); } public static Set getAvailableGames() { @@ -51,33 +52,4 @@ public class GamesManager { return games.get(name); } - private static Scoreboard updateScoreboard(Scoreboard scoreboard, int players, int maxPlayers) { - Objective objective = scoreboard.getObjective(DisplaySlot.SIDEBAR); - for (String o : scoreboard.getEntries()) { - scoreboard.resetScores(o); - } - - - objective.getScore(" ").setScore(3); - objective.getScore(Localization.getComponent("game-players-count", "{players}", String.valueOf(players), "{max-players}", String.valueOf(maxPlayers)).toString()).setScore(2); - objective.getScore(" ").setScore(1); - objective.getScore(Localization.getComponent("wait-time-left", "{time}", String.valueOf(30)).toString()).setScore(0); - - return scoreboard; - } - - private static Scoreboard newLobbyScoreboard(String name, int players, int maxPlayers) { - Scoreboard scoreboard = Bukkit.getScoreboardManager().getNewScoreboard(); - Objective objective = scoreboard.registerNewObjective(name, Criteria.DUMMY, Localization.getComponent(" game-title", "{title}", name)); - objective.setDisplaySlot(DisplaySlot.SIDEBAR); - - objective.getScore(" ").setScore(3); - objective.getScore(Localization.getComponent("game-players-count", "{players}", String.valueOf(players), "{max-players}", String.valueOf(maxPlayers)).toString()).setScore(2); - objective.getScore(" ").setScore(1); - objective.getScore(Localization.getComponent("wait-time-left", "{time}", String.valueOf(30)).toString()).setScore(0); - - - return scoreboard; - } - } diff --git a/src/main/java/hdvtdev/blockAndSeek/managers/ItemManager.java b/src/main/java/hdvtdev/blockAndSeek/managers/ItemManager.java index 99b4d79..2fb6783 100644 --- a/src/main/java/hdvtdev/blockAndSeek/managers/ItemManager.java +++ b/src/main/java/hdvtdev/blockAndSeek/managers/ItemManager.java @@ -94,6 +94,7 @@ public class ItemManager { meta.setColor(Color.RED); meta.setUnbreakable(true); meta.addEnchant(Enchantment.PROTECTION_ENVIRONMENTAL, 10, true); + meta.addEnchant(Enchantment.THORNS, 3, true); meta.displayName(Component.text("seeker-armor")); return meta; diff --git a/src/main/java/hdvtdev/blockAndSeek/roulette/RouletteCreator.java b/src/main/java/hdvtdev/blockAndSeek/roulette/RouletteCreator.java index 123cda9..ee88f4c 100644 --- a/src/main/java/hdvtdev/blockAndSeek/roulette/RouletteCreator.java +++ b/src/main/java/hdvtdev/blockAndSeek/roulette/RouletteCreator.java @@ -2,35 +2,74 @@ package hdvtdev.blockAndSeek.roulette; import hdvtdev.blockAndSeek.BlockAndSeek; import hdvtdev.blockAndSeek.BlockAndSeekMap; -import hdvtdev.blockAndSeek.eventListeners.EventListener; -import me.libraryaddict.disguise.DisguiseAPI; -import me.libraryaddict.disguise.disguisetypes.DisguiseType; -import me.libraryaddict.disguise.disguisetypes.MiscDisguise; -import net.kyori.adventure.text.Component; +import hdvtdev.blockAndSeek.Localization; import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.entity.Player; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryHolder; -import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; import java.util.List; +import java.util.Random; -public class RouletteCreator implements InventoryHolder { +public final class RouletteCreator implements InventoryHolder { - public static void newCreateRoulette(Player player, List blocks) { - final Inventory gui = Bukkit.createInventory(null, 45); - new BukkitRunnable() { + private static final int[] slots = {3, 5, 7, 12, 14, 16, 21, 23, 25, 30, 32, 34, 39, 41, 43}; + private static final int[] midSlots = {21, 23, 25}; + private static final Random random = new Random(); + private final Inventory roulette; + private Task task; + private volatile boolean closedByPlayer = true; + + public RouletteCreator(@NotNull Player player, List blocks) { + roulette = Bukkit.createInventory(this, 45, Localization.getComponent(player, "roulette-title")); + this.createUnoptimizedRoulette(roulette, player, blocks); + } + + public @NotNull Task getTask() { + return task; + } + + public boolean isClosedByPlayer() { + return closedByPlayer; + } + + @Override + public @NotNull Inventory getInventory() { + return roulette; + } + + public void closeInventory() { + closedByPlayer = false; + roulette.close(); + } + + public void closeInventoryByPlayer() { + closedByPlayer = true; + roulette.close(); + } + + public ItemStack randomPropItem() { + return roulette.getItem(slots[random.nextInt(0, 15)]); + } + + public ItemStack randomMidPropItem() { + return roulette.getItem(midSlots[random.nextInt(0, 3)]); + } + + @ApiStatus.Experimental + private void createUnoptimizedRoulette(Inventory gui, Player player, List blocks) { + + BukkitTask rouletteTask = new BukkitRunnable() { - int i = 0; final RouletteGenerator rouletteGenerator = new RouletteGenerator(blocks); final List> rows = List.of( @@ -39,57 +78,58 @@ public class RouletteCreator implements InventoryHolder { new RouletteList<>(rouletteGenerator.getRandomRow(15)) ); - final List items = List.of( - new ItemStack[]{ - rows.getFirst().next(), - rows.getFirst().next(), - rows.getFirst().next(), - rows.getFirst().next(), - rows.getFirst().next() - }, - new ItemStack[]{ - rows.get(1).next(), - rows.get(1).next(), - rows.get(1).next(), - rows.get(1).next(), - rows.get(1).next() - }, - new ItemStack[]{ - rows.get(2).next(), - rows.get(2).next(), - rows.get(2).next(), - rows.get(2).next(), - rows.get(2).next() + final List items; + + { + List rawItems = new ArrayList<>(); + for (int j = 0; j < 3; j++) { + ItemStack[] itemStacks = new ItemStack[5]; + for (int l = 0; l < 5; l++) { + itemStacks[l] = rows.get(j).next(); } - ); + rawItems.add(j, itemStacks); + } + items = rawItems; + } - private volatile boolean finished = false; - private long startTime = System.currentTimeMillis(); - private long lastActionTime = startTime; - private long nextDelay = 0; + final long startTime = System.currentTimeMillis(); + double currentSpeed = 0; + int i = 0; - private final long baseDelay = 30; - private final long maxDelay = 450; - private final double k = 0.2; @Override public void run() { - if (finished) this.cancel(); - long now = System.currentTimeMillis(); - long elapsedSeconds = (now - startTime) / 1000; - if (elapsedSeconds >= 10) { - finished = true; - return; + double elapsed = (now - startTime) / 1000.0; + + if (elapsed >= 9.5) { + this.cancel(); } + double speed; + if (elapsed < 3.0) speed = 1.0; + else if (elapsed < 3.5) speed = 0.8; + else if (elapsed < 4.0) speed = 0.6; + else if (elapsed < 4.5) speed = 0.5; + else if (elapsed < 5.0) speed = 0.4; + else if (elapsed < 5.5) speed = 0.33; + else if (elapsed < 6.0) speed = 0.28; + else if (elapsed < 6.5) speed = 0.25; + else if (elapsed < 7.0) speed = 0.22; + else if (elapsed < 7.5) speed = 0.2; + else if (elapsed < 8.0) speed = 0.12; + else speed = 0.05; - nextDelay = (long) (baseDelay + (maxDelay - baseDelay) * (1 - Math.exp(-k * elapsedSeconds))); + task(speed); - if (now - lastActionTime >= nextDelay) { - i++; + i++; + } + + private void task(double speed) { + if (currentSpeed >= 1) { + currentSpeed = 0; for (int j = 0; j < 5; j++) { gui.setItem(3 + j * 9, items.getFirst()[j]); gui.setItem(5 + j * 9, items.get(1)[j]); @@ -107,136 +147,24 @@ public class RouletteCreator implements InventoryHolder { items.getFirst()[0] = rows.getFirst().next(); items.get(1)[0] = rows.get(1).next(); items.get(2)[0] = rows.get(2).next(); - lastActionTime = now; - } - - i++; + } else currentSpeed += speed; } + }.runTaskTimer(BlockAndSeek.getInstance(), 0, 1); - }.runTaskTimer(BlockAndSeek.getInstance(), 0, 4); + + task = new Task(rouletteTask, Bukkit.getScheduler().runTaskLater(BlockAndSeek.getInstance(), this::closeInventory, 300)); player.openInventory(gui); } - @Deprecated - public static void createRoulette(Player player, Inventory inventory, boolean openInventory, List blocks) { - - Inventory gui = inventory == null ? new RouletteCreator().getInventory() : inventory; - - - EventListener.createTask(player, new BukkitRunnable() { - - int i = 0; - final RouletteGenerator rouletteGenerator = new RouletteGenerator(blocks); - - final List> rows = List.of( - new RouletteList<>(rouletteGenerator.getRandomRow(15)), - new RouletteList<>(rouletteGenerator.getRandomRow(15)), - new RouletteList<>(rouletteGenerator.getRandomRow(15)) - ); - - final List items = List.of( - new ItemStack[]{ - rows.getFirst().next(), - rows.getFirst().next(), - rows.getFirst().next(), - rows.getFirst().next(), - rows.getFirst().next() - }, - new ItemStack[]{ - rows.get(1).next(), - rows.get(1).next(), - rows.get(1).next(), - rows.get(1).next(), - rows.get(1).next() - - }, - new ItemStack[]{ - rows.get(2).next(), - rows.get(2).next(), - rows.get(2).next(), - rows.get(2).next(), - rows.get(2).next() - } - ); - - @Override - public void run() { - - for (int j = 0; j < 5; j++) { - gui.setItem(3 + j * 9, items.getFirst()[j]); - gui.setItem(5 + j * 9, items.get(1)[j]); - gui.setItem(7 + j * 9, items.get(2)[j]); - } - - player.playSound(player.getLocation(), Sound.UI_BUTTON_CLICK, 0.5f, 2f); - - - if (i == 30) { - player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 0.5f, 0.5f); - EventListener.stopTask(player); - } - - for (int j = 4; j >= 1; j--) { - items.getFirst()[j] = items.getFirst()[j - 1]; - items.get(1)[j] = items.get(1)[j - 1]; - items.get(2)[j] = items.get(2)[j - 1]; - } - - - items.getFirst()[0] = rows.getFirst().next(); - items.get(1)[0] = rows.get(1).next(); - items.get(2)[0] = rows.get(2).next(); - - i++; - } - - - }.runTaskTimer(BlockAndSeek.getInstance(), 0, 3L)); - - new BukkitRunnable() { - - @Override - public void run() { - - Inventory inventory = player.getOpenInventory().getTopInventory(); - - if (inventory.getHolder() instanceof RouletteCreator) { - inventory.close(); - MiscDisguise miscDisguise = new MiscDisguise(DisguiseType.FALLING_BLOCK, inventory.getItem(21)); - DisguiseAPI.disguiseToAll(player, miscDisguise); - } - - } - - - }.runTaskLater(BlockAndSeek.getInstance(), 300L); - - if (openInventory) { - player.openInventory(gui); - player.setMetadata("RollingMenu", new FixedMetadataValue(BlockAndSeek.getInstance(), "RollingMenu")); + public record Task(BukkitTask rouletteTask, BukkitTask autoCloseTask) { + public void cancelBoth() { + rouletteTask.cancel(); + autoCloseTask.cancel(); } - - } - @Override - public @NotNull Inventory getInventory() { - - Inventory gui = Bukkit.createInventory(this, 45, Component.text("РулетОЧКА")); - - ItemStack filler = new ItemStack(Material.BLUE_STAINED_GLASS_PANE); - ItemMeta fillerMeta = filler.getItemMeta(); - fillerMeta.displayName(Component.text("")); - fillerMeta.lore(null); - fillerMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); - filler.setItemMeta(fillerMeta); - for (int i = 0; i < 45; i++) { - gui.setItem(i, filler); - } - return gui; - } } diff --git a/src/main/resources/localization.yml b/src/main/resources/localization.yml index fd2b31b..c175e11 100644 --- a/src/main/resources/localization.yml +++ b/src/main/resources/localization.yml @@ -36,3 +36,5 @@ en-US: game-player-count: "{players} of {max-players} players" leave-item: "Leave game" + roulette-title: "Props Roulette" +