Add new seeker/hider protection configuration options.

To use these new protection features, these options must be
manually added to the arenas.yml file and restart the server.

These settings should be fairly self-explanatory:

arena1:
  ==: BlockHuntArena
  seekersCanHurtSeekers: false
  hidersCanHurtSeekers: false
  hidersCanHurtHiders: false
  seekersTakeFallDamage: false
  hidersTakeFallDamage: false
This commit is contained in:
addstar 2015-05-16 19:53:38 +10:00
parent b353589963
commit 1e38bd6b29
7 changed files with 182 additions and 98 deletions

View File

@ -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<ItemStack> 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<ItemStack> 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<ItemStack> disguiseBlocks, LocationSerializable lobbyWarp, LocationSerializable hidersWarp, LocationSerializable seekersWarp, LocationSerializable spawnWarp,
List<String> seekersWinCommands, List<String> hidersWinCommands, List<String> allowedCommands, int seekersTokenWin, int hidersTokenWin, int killTokens,
List<Player> playersInArena, ArenaState gameState, int timer, List<Player> 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<ItemStack>) M.g(map, "disguiseBlocks", new ArrayList<ItemStack>()),
(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<ItemStack>) M.g(map, "disguiseBlocks", new ArrayList<ItemStack>()),(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<String>) M.g(map, "seekersWinCommands", new ArrayList<String>()),
(ArrayList<String>) M.g(map, "hidersWinCommands", new ArrayList<String>()), (ArrayList<String>) M.g(map, "allowedCommands", new ArrayList<String>()),
(Integer) M.g(map, "seekersTokenWin", 10), (Integer) M.g(map, "hidersTokenWin", 50), (Integer) M.g(map, "killTokens", 8), new ArrayList<Player>(),

View File

@ -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<ItemStack>(), 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<ItemStack>(), null, null, null,
null, new ArrayList<String>(), new ArrayList<String>(), new ArrayList<String>(), 10, 50, 8, new ArrayList<Player>(), ArenaState.WAITING,
0, new ArrayList<Player>(), Bukkit.getScoreboardManager().getNewScoreboard());
W.arenas.getFile().set(args[1], arena);

View File

@ -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);

View File

@ -15,46 +15,97 @@ 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());
}
// 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 (player != null) {
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);
} 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);
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());
// The damage is allowed, so lets handle it!
player.getWorld().playSound(player.getLocation(), Sound.HURT_FLESH, 1, 1);
if (event.getDamage() >= player.getHealth()) {
player.setHealth(20);
event.setCancelled(true);
System.out.println("[DEBUG] EntityDamageByEntity: isCancelled = " + event.isCancelled() + "(handling fake damage)");
DisguiseAPI.undisguiseToAll(player);
W.pBlock.remove(player);
@ -82,7 +133,7 @@ public class OnEntityDamageByEntityEvent implements Listener {
MessageM.sendFMessage(player, ConfigC.normal_addedToken, "amount-" + (int) addingTokens);
arena.seekers.add(player);
ArenaHandler.sendFMessage(arena, ConfigC.normal_ingameHiderDied, "playername-" + player.getName(), "killer-" + damagername);
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)) {
@ -112,26 +163,12 @@ public class OnEntityDamageByEntityEvent implements Listener {
player.setGameMode(GameMode.SURVIVAL);
player.setWalkSpeed(0.3F);
// Fix for client not showing players after
// they join
// 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
otherplayer.showPlayer(player); // Make new player visible to others
if (player.canSee(otherplayer))
player.showPlayer(otherplayer); // Make
// other
// players
// visible
// to
// new
// player
}
}
player.showPlayer(otherplayer); // Make other players visible to new player
}
}
}

View File

@ -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,15 +16,47 @@ 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)) {
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;
}
}
}

View File

@ -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();

View File

@ -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) {