diff --git a/src/nl/Steffion/BlockHunt/Arena.java b/src/nl/Steffion/BlockHunt/Arena.java index a0250df..6ce6a83 100644 --- a/src/nl/Steffion/BlockHunt/Arena.java +++ b/src/nl/Steffion/BlockHunt/Arena.java @@ -28,7 +28,11 @@ public class Arena implements ConfigurationSerializable { public int gameTime; public int timeUntilHidersSword; public int blockAnnouncerTime; - public boolean seekerProtection; + public boolean seekersCanHurtSeekers; + public boolean hidersCanHurtSeekers; + public boolean hidersCanHurtHiders; + public boolean seekersTakeFallDamage; + public boolean hidersTakeFallDamage; public ArrayList disguiseBlocks; public LocationSerializable lobbyWarp; public LocationSerializable hidersWarp; @@ -48,8 +52,9 @@ public class Arena implements ConfigurationSerializable { public Scoreboard scoreboard; public Arena(String arenaName, LocationSerializable pos1, LocationSerializable pos2, int maxPlayers, int minPlayers, int amountSeekersOnStart, - int timeInLobbyUntilStart, int waitingTimeSeeker, int gameTime, int timeUntilHidersSword, int blockAnnouncerTime, boolean seekerProtection, ArrayList disguiseBlocks, - LocationSerializable lobbyWarp, LocationSerializable hidersWarp, LocationSerializable seekersWarp, LocationSerializable spawnWarp, + int timeInLobbyUntilStart, int waitingTimeSeeker, int gameTime, int timeUntilHidersSword, int blockAnnouncerTime, + boolean seekersCanHurtSeekers, boolean hidersCanHurtSeekers, boolean hidersCanHurtHiders, boolean seekersTakeFallDamage, boolean hidersTakeFallDamage, + ArrayList disguiseBlocks, LocationSerializable lobbyWarp, LocationSerializable hidersWarp, LocationSerializable seekersWarp, LocationSerializable spawnWarp, List seekersWinCommands, List hidersWinCommands, List allowedCommands, int seekersTokenWin, int hidersTokenWin, int killTokens, List playersInArena, ArenaState gameState, int timer, List seekers, Scoreboard scoreboard) { this.arenaName = arenaName; @@ -137,9 +142,9 @@ public class Arena implements ConfigurationSerializable { LocationSerializable loc = new LocationSerializable(Bukkit.getWorld("world"), 0, 0, 0, 0, 0); return new Arena((String) M.g(map, "arenaName", "UNKNOWN_NAME"), (LocationSerializable) M.g(map, "pos1", loc), (LocationSerializable) M.g(map, "pos2", loc), (Integer) M.g(map, "maxPlayers", 12), (Integer) M.g(map, "minPlayers", 3), (Integer) M.g(map, "amountSeekersOnStart", 1), (Integer) M.g(map, "timeInLobbyUntilStart", 90), - (Integer) M.g(map, "waitingTimeSeeker", 20), (Integer) M.g(map, "gameTime", 200), (Integer) M.g(map, "timeUntilHidersSword", 30), - (Integer) M.g(map, "blockAnnouncerTime", 45), (Boolean) M.g(map, "seekerProtection", false),(ArrayList) M.g(map, "disguiseBlocks", new ArrayList()), - (LocationSerializable) M.g(map, "lobbyWarp", loc), (LocationSerializable) M.g(map, "hidersWarp", loc), (LocationSerializable) M.g(map, "seekersWarp", loc), + (Integer) M.g(map, "waitingTimeSeeker", 20), (Integer) M.g(map, "gameTime", 200), (Integer) M.g(map, "timeUntilHidersSword", 30),(Integer) M.g(map, "blockAnnouncerTime", 45), + (Boolean) M.g(map, "seekersCanHurtSeekers", false),(Boolean) M.g(map, "hidersCanHurtSeekers", false),(Boolean) M.g(map, "hidersCanHurtHiders", false),(Boolean) M.g(map, "seekersTakeFallDamage", false),(Boolean) M.g(map, "hidersTakeFallDamage", false), + (ArrayList) M.g(map, "disguiseBlocks", new ArrayList()),(LocationSerializable) M.g(map, "lobbyWarp", loc), (LocationSerializable) M.g(map, "hidersWarp", loc), (LocationSerializable) M.g(map, "seekersWarp", loc), (LocationSerializable) M.g(map, "spawnWarp", loc), (ArrayList) M.g(map, "seekersWinCommands", new ArrayList()), (ArrayList) M.g(map, "hidersWinCommands", new ArrayList()), (ArrayList) M.g(map, "allowedCommands", new ArrayList()), (Integer) M.g(map, "seekersTokenWin", 10), (Integer) M.g(map, "hidersTokenWin", 50), (Integer) M.g(map, "killTokens", 8), new ArrayList(), diff --git a/src/nl/Steffion/BlockHunt/Commands/CMDcreate.java b/src/nl/Steffion/BlockHunt/Commands/CMDcreate.java index cc0dc10..0393fc6 100644 --- a/src/nl/Steffion/BlockHunt/Commands/CMDcreate.java +++ b/src/nl/Steffion/BlockHunt/Commands/CMDcreate.java @@ -25,7 +25,7 @@ public class CMDcreate extends DefaultCMD { } else { if (W.pos1.get(player) != null && W.pos2.get(player) != null) { if (W.pos1.get(player).getWorld().equals(W.pos2.get(player).getWorld())) { - Arena arena = new Arena(args[1], W.pos1.get(player), W.pos2.get(player), 12, 3, 1, 50, 20, 300, 30, 45, false, new ArrayList(), null, null, null, + Arena arena = new Arena(args[1], W.pos1.get(player), W.pos2.get(player), 12, 3, 1, 50, 20, 300, 30, 45, false, false, false, false, false, new ArrayList(), null, null, null, null, new ArrayList(), new ArrayList(), new ArrayList(), 10, 50, 8, new ArrayList(), ArenaState.WAITING, 0, new ArrayList(), Bukkit.getScoreboardManager().getNewScoreboard()); W.arenas.getFile().set(args[1], arena); diff --git a/src/nl/Steffion/BlockHunt/Listeners/OnBlockPlaceEvent.java b/src/nl/Steffion/BlockHunt/Listeners/OnBlockPlaceEvent.java index 5c72484..20814bf 100644 --- a/src/nl/Steffion/BlockHunt/Listeners/OnBlockPlaceEvent.java +++ b/src/nl/Steffion/BlockHunt/Listeners/OnBlockPlaceEvent.java @@ -1,6 +1,7 @@ package nl.Steffion.BlockHunt.Listeners; import nl.Steffion.BlockHunt.Arena; +import nl.Steffion.BlockHunt.ArenaHandler; import nl.Steffion.BlockHunt.W; import org.bukkit.entity.Player; @@ -13,8 +14,10 @@ public class OnBlockPlaceEvent implements Listener { @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onBlockPlaceEvent(BlockPlaceEvent event) { - Player player = event.getPlayer(); + // Early exit if no one is in any arena + if (ArenaHandler.noPlayersInArenas()) return; + Player player = event.getPlayer(); for (Arena arena : W.arenaList) { if (arena.playersInArena.contains(player)) { event.setCancelled(true); diff --git a/src/nl/Steffion/BlockHunt/Listeners/OnEntityDamageByEntityEvent.java b/src/nl/Steffion/BlockHunt/Listeners/OnEntityDamageByEntityEvent.java index fe42ac8..6e036d1 100644 --- a/src/nl/Steffion/BlockHunt/Listeners/OnEntityDamageByEntityEvent.java +++ b/src/nl/Steffion/BlockHunt/Listeners/OnEntityDamageByEntityEvent.java @@ -15,123 +15,160 @@ import nl.Steffion.BlockHunt.Managers.MessageM; import org.apache.commons.lang.StringUtils; import org.bukkit.GameMode; import org.bukkit.Sound; +import org.bukkit.entity.Arrow; 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.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.projectiles.ProjectileSource; public class OnEntityDamageByEntityEvent implements Listener { @SuppressWarnings("deprecation") @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onEntityDamageByEntityEvent(EntityDamageByEntityEvent event) { - Player player = null; - if (event.getEntity() instanceof Player) { - player = (Player) event.getEntity(); + if (!(event.getEntity() instanceof Player) || event.getEntity() == null) { + // We only care about player damage + return; } + // Early exit if no one is in any arena + if (ArenaHandler.noPlayersInArenas()) return; + + Player player = (Player) event.getEntity(); Player damager = null; - String damagername = "unknown"; if (event.getDamager() instanceof Player) { damager = (Player) event.getDamager(); - damagername = damager.getName(); + System.out.println("[DEBUG] EntityDamageByEntity: Player = " + player.getName() + " / Damager = " + damager.getName() + " / Cause = " + event.getCause()); + } else { + if ((event.getCause() == DamageCause.PROJECTILE) && (event.getDamager() instanceof Arrow)) { + // If damage was caused by an arrow, find out who shot the arrow + Arrow arrow = (Arrow) event.getDamager(); + ProjectileSource shooter = arrow.getShooter(); + if (shooter instanceof Player) { + damager = (Player) shooter; + } + } + System.out.println("[DEBUG] EntityDamageByEntity: Player = " + player.getName() + " / Damager = " + event.getDamager() + " / Cause = " + event.getCause()); } - if (player != null) { - for (Arena arena : W.arenaList) { - if (arena.playersInArena.contains(player)) { - if (arena.gameState == ArenaState.WAITING || arena.gameState == ArenaState.STARTING) { - event.setCancelled(true); - } else { - if (arena.seekers.contains(player)) { - event.setCancelled(true); - } else if (arena.seekerProtection && arena.playersInArena.contains(player) && arena.playersInArena.contains(event.getDamager()) - && !arena.seekers.contains(event.getDamager()) && !arena.seekers.contains(player)) { - event.setCancelled(true); - } else { - player.getWorld().playSound(player.getLocation(), Sound.HURT_FLESH, 1, 1); + // Always block all damage not dealt by a player + if (damager == null || !(damager instanceof Player)) { + event.setCancelled(true); + System.out.println("[DEBUG] EntityDamageByEntity: isCancelled = " + event.isCancelled()); + return; + } - if (event.getDamage() >= player.getHealth()) { - player.setHealth(20); + for (Arena arena : W.arenaList) { + if (arena.playersInArena.contains(player)) { + if (arena.gameState == ArenaState.WAITING || arena.gameState == ArenaState.STARTING) { + // Always cancel damage when players are waiting + event.setCancelled(true); + System.out.println("[DEBUG] EntityDamageByEntity: isCancelled = " + event.isCancelled()); + return; + } else { + // Seeker receiving damage + if (arena.seekers.contains(player)) { + if (arena.seekers.contains(damager)) { + // Seeker damaged by seeker + if (!arena.seekersCanHurtSeekers) { event.setCancelled(true); + System.out.println("[DEBUG] EntityDamageByEntity: isCancelled = " + event.isCancelled()); + return; + } + } else { + // Seeker damaged by hider + if (!arena.hidersCanHurtSeekers) { + event.setCancelled(true); + System.out.println("[DEBUG] EntityDamageByEntity: isCancelled = " + event.isCancelled()); + return; + } + } + event.setCancelled(true); + System.out.println("[DEBUG] EntityDamageByEntity: isCancelled = " + event.isCancelled()); + return; + } else { + // Hider damaged by hider + if (!arena.hidersCanHurtHiders && !arena.seekers.contains(damager)) { + event.setCancelled(true); + System.out.println("[DEBUG] EntityDamageByEntity: isCancelled = " + event.isCancelled()); + return; + } + } + System.out.println("[DEBUG] EntityDamageByEntity: isCancelled = " + event.isCancelled()); - DisguiseAPI.undisguiseToAll(player); - W.pBlock.remove(player); + // The damage is allowed, so lets handle it! + player.getWorld().playSound(player.getLocation(), Sound.HURT_FLESH, 1, 1); - if (!arena.seekers.contains(player)) { - if (W.shop.getFile().get(damager.getName() + ".tokens") == null) { - W.shop.getFile().set(damager.getName() + ".tokens", 0); - W.shop.save(); - } - int damagerTokens = W.shop.getFile().getInt(damager.getName() + ".tokens"); - W.shop.getFile().set(damager.getName() + ".tokens", damagerTokens + arena.killTokens); - W.shop.save(); + if (event.getDamage() >= player.getHealth()) { + player.setHealth(20); + event.setCancelled(true); + System.out.println("[DEBUG] EntityDamageByEntity: isCancelled = " + event.isCancelled() + "(handling fake damage)"); - MessageM.sendFMessage(damager, ConfigC.normal_addedToken, "amount-" + arena.killTokens); + DisguiseAPI.undisguiseToAll(player); + W.pBlock.remove(player); - if (W.shop.getFile().get(player.getName() + ".tokens") == null) { - W.shop.getFile().set(player.getName() + ".tokens", 0); - W.shop.save(); - } - int playerTokens = W.shop.getFile().getInt(player.getName() + ".tokens"); - float addingTokens = ((float) arena.hidersTokenWin - (((float) arena.timer / (float) arena.gameTime) * (float) arena.hidersTokenWin)); - W.shop.getFile().set(player.getName() + ".tokens", playerTokens + (int) addingTokens); - W.shop.save(); + if (!arena.seekers.contains(player)) { + if (W.shop.getFile().get(damager.getName() + ".tokens") == null) { + W.shop.getFile().set(damager.getName() + ".tokens", 0); + W.shop.save(); + } + int damagerTokens = W.shop.getFile().getInt(damager.getName() + ".tokens"); + W.shop.getFile().set(damager.getName() + ".tokens", damagerTokens + arena.killTokens); + W.shop.save(); - MessageM.sendFMessage(player, ConfigC.normal_addedToken, "amount-" + (int) addingTokens); + MessageM.sendFMessage(damager, ConfigC.normal_addedToken, "amount-" + arena.killTokens); - arena.seekers.add(player); - ArenaHandler.sendFMessage(arena, ConfigC.normal_ingameHiderDied, "playername-" + player.getName(), "killer-" + damagername); + if (W.shop.getFile().get(player.getName() + ".tokens") == null) { + W.shop.getFile().set(player.getName() + ".tokens", 0); + W.shop.save(); + } + int playerTokens = W.shop.getFile().getInt(player.getName() + ".tokens"); + float addingTokens = ((float) arena.hidersTokenWin - (((float) arena.timer / (float) arena.gameTime) * (float) arena.hidersTokenWin)); + W.shop.getFile().set(player.getName() + ".tokens", playerTokens + (int) addingTokens); + W.shop.save(); - int hidercount = (arena.playersInArena.size() - arena.seekers.size()); - if ((hidercount <= 3) && (hidercount > 0)) { - List hiders = new ArrayList(); - for (Player p : arena.playersInArena) { - if (!arena.seekers.contains(p)) { - hiders.add(p.getName()); - } - } - Collections.sort(hiders); + MessageM.sendFMessage(player, ConfigC.normal_addedToken, "amount-" + (int) addingTokens); - ArenaHandler.sendFMessage(arena, ConfigC.normal_ingameHidersLeft, "left-" + StringUtils.join(hiders.toArray(), ", ")); - } else { - ArenaHandler.sendFMessage(arena, ConfigC.normal_ingameHidersLeft, "left-" + hidercount); + arena.seekers.add(player); + ArenaHandler.sendFMessage(arena, ConfigC.normal_ingameHiderDied, "playername-" + player.getDisplayName(), "killer-" + damager.getDisplayName()); + + int hidercount = (arena.playersInArena.size() - arena.seekers.size()); + if ((hidercount <= 3) && (hidercount > 0)) { + List hiders = new ArrayList(); + for (Player p : arena.playersInArena) { + if (!arena.seekers.contains(p)) { + hiders.add(p.getName()); } } + Collections.sort(hiders); - player.getInventory().clear(); - player.updateInventory(); + ArenaHandler.sendFMessage(arena, ConfigC.normal_ingameHidersLeft, "left-" + StringUtils.join(hiders.toArray(), ", ")); + } else { + ArenaHandler.sendFMessage(arena, ConfigC.normal_ingameHidersLeft, "left-" + hidercount); + } + } - if (arena.seekers.size() >= arena.playersInArena.size()) { - ArenaHandler.seekersWin(arena); - } else { - DisguiseAPI.undisguiseToAll(player); - W.seekertime.put(player, arena.waitingTimeSeeker); - player.teleport(arena.seekersWarp); - player.setGameMode(GameMode.SURVIVAL); - player.setWalkSpeed(0.3F); + player.getInventory().clear(); + player.updateInventory(); - // Fix for client not showing players after - // they join - for (Player otherplayer : arena.playersInArena) { - if (otherplayer.canSee(player)) - otherplayer.showPlayer(player); // Make - // new - // player - // visible - // to - // others - if (player.canSee(otherplayer)) - player.showPlayer(otherplayer); // Make - // other - // players - // visible - // to - // new - // player - } - } + if (arena.seekers.size() >= arena.playersInArena.size()) { + ArenaHandler.seekersWin(arena); + } else { + DisguiseAPI.undisguiseToAll(player); + W.seekertime.put(player, arena.waitingTimeSeeker); + player.teleport(arena.seekersWarp); + player.setGameMode(GameMode.SURVIVAL); + player.setWalkSpeed(0.3F); + + // Fix for client not showing players after they join + for (Player otherplayer : arena.playersInArena) { + if (otherplayer.canSee(player)) + otherplayer.showPlayer(player); // Make new player visible to others + if (player.canSee(otherplayer)) + player.showPlayer(otherplayer); // Make other players visible to new player } } } diff --git a/src/nl/Steffion/BlockHunt/Listeners/OnEntityDamageEvent.java b/src/nl/Steffion/BlockHunt/Listeners/OnEntityDamageEvent.java index 2d5e892..aaecd46 100644 --- a/src/nl/Steffion/BlockHunt/Listeners/OnEntityDamageEvent.java +++ b/src/nl/Steffion/BlockHunt/Listeners/OnEntityDamageEvent.java @@ -1,6 +1,7 @@ package nl.Steffion.BlockHunt.Listeners; import nl.Steffion.BlockHunt.Arena; +import nl.Steffion.BlockHunt.ArenaHandler; import nl.Steffion.BlockHunt.W; import org.bukkit.entity.Entity; @@ -15,17 +16,49 @@ public class OnEntityDamageEvent implements Listener { @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onEntityDamageEvent(EntityDamageEvent event) { - Entity ent = event.getEntity(); + // Early exit if no one is in any arena + if (ArenaHandler.noPlayersInArenas()) return; + Entity ent = event.getEntity(); if (ent instanceof Player) { Player player = (Player) event.getEntity(); for (Arena arena : W.arenaList) { if (arena.playersInArena.contains(player)) { - if (!event.getCause().equals(DamageCause.ENTITY_ATTACK)) { - event.setCancelled(true); + DamageCause cause = event.getCause(); + System.out.println("[DEBUG] EntityDamage: Player = " + player.getName() + " / Cause = " + cause); + switch (cause) { + case ENTITY_ATTACK: + // Do nothing about damage from an entity + // Any entity damage that makes it to here was already allowed by the EntityDamageByEntity event + break; + case FALL: + // Should we prevent the fall damage? + if (arena.seekers.contains(player)) { + if (!arena.seekersTakeFallDamage) { + // Prevent seeker fall damage (if configured) + event.setCancelled(true); + System.out.println("[DEBUG] EntityDamage: isCancelled = " + event.isCancelled()); + return; + } + } else { + if (!arena.hidersTakeFallDamage) { + // Prevent hider fall damage (if configured) + event.setCancelled(true); + System.out.println("[DEBUG] EntityDamage: isCancelled = " + event.isCancelled()); + return; + } + } + break; + default: + // Cancel all non-entity damage for all players (lava, drowning, fire, etc) + event.setCancelled(true); + System.out.println("[DEBUG] EntityDamage: isCancelled = " + event.isCancelled()); + break; } + System.out.println("[DEBUG] EntityDamage: isCancelled = " + event.isCancelled()); + return; } } } } -} +} \ No newline at end of file diff --git a/src/nl/Steffion/BlockHunt/Listeners/OnPlayerCommandPreprocessEvent.java b/src/nl/Steffion/BlockHunt/Listeners/OnPlayerCommandPreprocessEvent.java index 85b00b6..014d076 100644 --- a/src/nl/Steffion/BlockHunt/Listeners/OnPlayerCommandPreprocessEvent.java +++ b/src/nl/Steffion/BlockHunt/Listeners/OnPlayerCommandPreprocessEvent.java @@ -1,6 +1,7 @@ package nl.Steffion.BlockHunt.Listeners; import nl.Steffion.BlockHunt.Arena; +import nl.Steffion.BlockHunt.ArenaHandler; import nl.Steffion.BlockHunt.ConfigC; import nl.Steffion.BlockHunt.PermissionsC.Permissions; import nl.Steffion.BlockHunt.W; @@ -17,8 +18,10 @@ public class OnPlayerCommandPreprocessEvent implements Listener { @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void onPlayerCommandPreprocessEvent(PlayerCommandPreprocessEvent event) { - Player player = event.getPlayer(); + // Early exit if no one is in any arena + if (ArenaHandler.noPlayersInArenas()) return; + Player player = event.getPlayer(); for (Arena arena : W.arenaList) { if (arena.playersInArena.contains(player)) { String m = event.getMessage(); diff --git a/src/nl/Steffion/BlockHunt/Listeners/OnPlayerMoveEvent.java b/src/nl/Steffion/BlockHunt/Listeners/OnPlayerMoveEvent.java index cdddddc..78415de 100644 --- a/src/nl/Steffion/BlockHunt/Listeners/OnPlayerMoveEvent.java +++ b/src/nl/Steffion/BlockHunt/Listeners/OnPlayerMoveEvent.java @@ -1,6 +1,7 @@ package nl.Steffion.BlockHunt.Listeners; import nl.Steffion.BlockHunt.Arena; +import nl.Steffion.BlockHunt.ArenaHandler; import nl.Steffion.BlockHunt.Arena.ArenaState; import nl.Steffion.BlockHunt.W; @@ -17,8 +18,10 @@ public class OnPlayerMoveEvent implements Listener { @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPlayerMoveEvent(PlayerMoveEvent event) { - Player player = event.getPlayer(); + // Early exit if no one is in any arena + if (ArenaHandler.noPlayersInArenas()) return; + Player player = event.getPlayer(); for (Arena arena : W.arenaList) { if (arena.playersInArena.contains(player)) { if (arena.gameState == ArenaState.INGAME) {