From 7561fd8ffb765564591861c3b351d0bc7b644ddf Mon Sep 17 00:00:00 2001 From: cmastudios Date: Fri, 13 Jun 2014 23:28:08 -0500 Subject: [PATCH] Moved death message handling to warzone class The more interesting change I made here was the removal of the so-called 're-killing' statements - e.g. setting the health of really dead players to 0 to ensure they are dead. Who knows, it might affect #796 and #778, because I have zero idea what is causing them. --- .../main/java/com/tommytony/war/Warzone.java | 118 +++++++++++++- .../war/event/WarEntityListener.java | 153 +++--------------- 2 files changed, 133 insertions(+), 138 deletions(-) diff --git a/war/src/main/java/com/tommytony/war/Warzone.java b/war/src/main/java/com/tommytony/war/Warzone.java index 4f258a8..b1025b8 100644 --- a/war/src/main/java/com/tommytony/war/Warzone.java +++ b/war/src/main/java/com/tommytony/war/Warzone.java @@ -12,12 +12,11 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Random; import java.util.logging.Level; import net.milkbowl.vault.economy.EconomyResponse; -import com.tommytony.war.mapper.VolumeMapper; -import com.tommytony.war.mapper.ZoneVolumeMapper; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; @@ -29,9 +28,15 @@ import org.bukkit.OfflinePlayer; import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; +import org.bukkit.entity.Arrow; import org.bukkit.entity.Entity; import org.bukkit.entity.Item; import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.inventory.InventoryView; @@ -62,6 +67,8 @@ import com.tommytony.war.job.LoadoutResetJob; import com.tommytony.war.job.LogKillsDeathsJob; import com.tommytony.war.job.LogKillsDeathsJob.KillsDeathsRecord; import com.tommytony.war.mapper.LoadoutYmlMapper; +import com.tommytony.war.mapper.VolumeMapper; +import com.tommytony.war.mapper.ZoneVolumeMapper; import com.tommytony.war.spout.SpoutDisplayer; import com.tommytony.war.structure.Bomb; import com.tommytony.war.structure.Cake; @@ -981,6 +988,112 @@ public class Warzone { this.broadcast("join.broadcast", player.getName(), team.getKind().getFormattedName()); return true; } + + private void dropItems(Location location, ItemStack[] items) { + for (ItemStack item : items) { + if (item == null || item.getType() == Material.AIR) { + continue; + } + location.getWorld().dropItem(location, item); + } + } + + private Random killSeed = new Random(); + + /** + * Send death messages and process other records before passing off the + * death to the {@link #handleDeath(Player)} method. + * @param attacker Player who killed the defender + * @param defender Player who was killed + * @param damager Entity who caused the damage. Usually an arrow. Used for + * specific death messages. Can be null. + */ + public void handleKill(Player attacker, Player defender, Entity damager) { + Team attackerTeam = this.getPlayerTeam(attacker.getName()); + Team defenderTeam = this.getPlayerTeam(defender.getName()); + if (this.getWarzoneConfig().getBoolean(WarzoneConfig.DEATHMESSAGES)) { + String attackerString = attackerTeam.getKind().getColor() + attacker.getName(); + String defenderString = defenderTeam.getKind().getColor() + defender.getName(); + Material killerWeapon = attacker.getItemInHand().getType(); + String weaponString = killerWeapon.toString(); + if (attacker.getItemInHand().hasItemMeta() && attacker.getItemInHand().getItemMeta().hasDisplayName()) { + weaponString = attacker.getItemInHand().getItemMeta().getDisplayName() + ChatColor.WHITE; + } + if (killerWeapon == Material.AIR) { + weaponString = War.war.getString("pvp.kill.weapon.hand"); + } else if (killerWeapon == Material.BOW || damager instanceof Arrow) { + int rand = killSeed.nextInt(3); + if (rand == 0) { + weaponString = War.war.getString("pvp.kill.weapon.bow"); + } else { + weaponString = War.war.getString("pvp.kill.weapon.aim"); + } + } else if (damager instanceof Projectile) { + weaponString = War.war.getString("pvp.kill.weapon.aim"); + } + String adjectiveString = War.war.getDeadlyAdjectives().isEmpty() ? "" : War.war.getDeadlyAdjectives().get(this.killSeed.nextInt(War.war.getDeadlyAdjectives().size())); + String verbString = War.war.getKillerVerbs().isEmpty() ? "" : War.war.getKillerVerbs().get(this.killSeed.nextInt(War.war.getKillerVerbs().size())); + this.broadcast("pvp.kill.format", attackerString + ChatColor.WHITE, adjectiveString, + weaponString.toLowerCase().replace('_', ' '), verbString, defenderString); + } + this.addKillCount(attacker.getName(), 1); + this.addKillDeathRecord(attacker, 1, 0); + this.addKillDeathRecord(defender, 0, 1); + if (attackerTeam.getTeamConfig().resolveBoolean(TeamConfig.XPKILLMETER)) { + attacker.setLevel(this.getKillCount(attacker.getName())); + } + if (attackerTeam.getTeamConfig().resolveBoolean(TeamConfig.KILLSTREAK)) { + War.war.getKillstreakReward().rewardPlayer(attacker, this.getKillCount(attacker.getName())); + } + if (this.getScoreboard() != null && this.getScoreboardType() == ScoreboardType.TOPKILLS) { + Objective obj = this.getScoreboard().getObjective("Top kills"); + obj.getScore(attacker).setScore(this.getKillCount(attacker.getName())); + } + if (defenderTeam.getTeamConfig().resolveBoolean(TeamConfig.INVENTORYDROP)) { + dropItems(defender.getLocation(), defender.getInventory().getContents()); + dropItems(defender.getLocation(), defender.getInventory().getArmorContents()); + } + this.handleDeath(defender); + } + + /** + * Handle death messages before passing to {@link #handleDeath(Player)} + * for post-processing. It's like + * {@link #handleKill(Player, Player, Entity)}, but only for suicides. + * @param player Player who killed himself + */ + public void handleSuicide(Player player) { + if (this.getWarzoneConfig().getBoolean(WarzoneConfig.DEATHMESSAGES)) { + String defenderString = this.getPlayerTeam(player.getName()).getKind().getColor() + player.getName() + ChatColor.WHITE; + this.broadcast("pvp.kill.self", defenderString); + } + this.handleDeath(player); + } + + /** + * Handle a player killed naturally (like by a dispenser or explosion). + * @param player Player killed + * @param event Event causing damage + */ + public void handleNaturalKill(Player player, EntityDamageEvent event) { + if (this.getWarzoneConfig().getBoolean(WarzoneConfig.DEATHMESSAGES)) { + String defenderString = this.getPlayerTeam(player.getName()).getKind().getColor() + player.getName() + ChatColor.WHITE; + if (event instanceof EntityDamageByEntityEvent + && ((EntityDamageByEntityEvent) event).getDamager() instanceof TNTPrimed) { + this.broadcast("pvp.death.explosion", defenderString + ChatColor.WHITE); + } else if (event.getCause() == DamageCause.FIRE || event.getCause() == DamageCause.FIRE_TICK + || event.getCause() == DamageCause.LAVA || event.getCause() == DamageCause.LIGHTNING) { + this.broadcast("pvp.death.fire", defenderString); + } else if (event.getCause() == DamageCause.DROWNING) { + this.broadcast("pvp.death.drown", defenderString); + } else if (event.getCause() == DamageCause.FALL) { + this.broadcast("pvp.death.fall", defenderString); + } else { + this.broadcast("pvp.death.other", defenderString); + } + } + this.handleDeath(player); + } /** * Cleanup after a player who has died. This decrements the team's @@ -994,7 +1107,6 @@ public class Warzone { Validate.notNull(playerTeam, "Can't find team for dead player " + player.getName()); if (this.getWarzoneConfig().getBoolean(WarzoneConfig.REALDEATHS)) { this.getReallyDeadFighters().add(player.getName()); - player.setHealth(0D); } else { this.respawnPlayer(playerTeam, player); } diff --git a/war/src/main/java/com/tommytony/war/event/WarEntityListener.java b/war/src/main/java/com/tommytony/war/event/WarEntityListener.java index 7768be4..6992872 100644 --- a/war/src/main/java/com/tommytony/war/event/WarEntityListener.java +++ b/war/src/main/java/com/tommytony/war/event/WarEntityListener.java @@ -2,14 +2,13 @@ package com.tommytony.war.event; import java.util.ArrayList; import java.util.List; -import java.util.Random; +import java.util.logging.Level; import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockState; -import org.bukkit.entity.Arrow; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; @@ -20,34 +19,27 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.entity.CreatureSpawnEvent; -import org.bukkit.event.entity.EntityCombustEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDamageEvent; -import org.bukkit.event.entity.EntityDamageEvent.DamageCause; -import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.entity.EntityExplodeEvent; import org.bukkit.event.entity.EntityRegainHealthEvent; import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; import org.bukkit.event.entity.ExplosionPrimeEvent; import org.bukkit.event.entity.FoodLevelChangeEvent; +import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.entity.ProjectileHitEvent; import org.bukkit.event.entity.ProjectileLaunchEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.metadata.FixedMetadataValue; -import org.bukkit.scoreboard.Objective; import org.bukkit.util.Vector; -import org.getspout.spoutapi.SpoutManager; -import org.getspout.spoutapi.player.SpoutPlayer; import com.tommytony.war.Team; import com.tommytony.war.War; import com.tommytony.war.Warzone; -import com.tommytony.war.config.ScoreboardType; import com.tommytony.war.config.TeamConfig; import com.tommytony.war.config.WarConfig; import com.tommytony.war.config.WarzoneConfig; import com.tommytony.war.job.DeferredBlockResetsJob; -import com.tommytony.war.spout.SpoutDisplayer; import com.tommytony.war.structure.Bomb; import com.tommytony.war.utility.LoadoutSelection; @@ -59,17 +51,6 @@ import com.tommytony.war.utility.LoadoutSelection; */ public class WarEntityListener implements Listener { - private final Random killSeed = new Random(); - - private void dropItems(Location location, ItemStack[] items) { - for (ItemStack item : items) { - if (item == null || item.getType() == Material.AIR) { - continue; - } - location.getWorld().dropItem(location, item); - } - } - /** * Handles PVP-Damage * @@ -131,72 +112,20 @@ public class WarEntityListener implements Listener { // Detect death, prevent it and respawn the player if (event.getDamage() >= d.getHealth()) { if (defenderWarzone.getReallyDeadFighters().contains(d.getName())) { - // don't re-kill a dead person - if (d.getHealth() != 0) { - d.setHealth(0); - } - + // don't re-kill a dead person return; } - - if (attackerWarzone.getWarzoneConfig().getBoolean(WarzoneConfig.DEATHMESSAGES)) { - String attackerString = attackerTeam.getKind().getColor() + a.getName(); - String defenderString = defenderTeam.getKind().getColor() + d.getName(); - if (attacker.getEntityId() != defender.getEntityId()) { - Material killerWeapon = a.getItemInHand().getType(); - String weaponString = killerWeapon.toString(); - if (a.getItemInHand().hasItemMeta() && a.getItemInHand().getItemMeta().hasDisplayName()) { - weaponString = a.getItemInHand().getItemMeta().getDisplayName() + ChatColor.WHITE; - } - if (killerWeapon == Material.AIR) { - weaponString = War.war.getString("pvp.kill.weapon.hand"); - } else if (killerWeapon == Material.BOW || event.getDamager() instanceof Arrow) { - int rand = killSeed.nextInt(3); - if (rand == 0) { - weaponString = War.war.getString("pvp.kill.weapon.bow"); - } else { - weaponString = War.war.getString("pvp.kill.weapon.aim"); - } - } else if (event.getDamager() instanceof Projectile) { - weaponString = War.war.getString("pvp.kill.weapon.aim"); - } - String adjectiveString = War.war.getDeadlyAdjectives().isEmpty() ? "" : War.war.getDeadlyAdjectives().get(this.killSeed.nextInt(War.war.getDeadlyAdjectives().size())); - String verbString = War.war.getKillerVerbs().isEmpty() ? "" : War.war.getKillerVerbs().get(this.killSeed.nextInt(War.war.getKillerVerbs().size())); - defenderWarzone.broadcast("pvp.kill.format", attackerString + ChatColor.WHITE, adjectiveString, - weaponString.toLowerCase().replace('_', ' '), verbString, defenderString); - } else { - defenderWarzone.broadcast("pvp.kill.self", defenderString + ChatColor.WHITE); - } - } - if (attacker.getEntityId() != defender.getEntityId()) { - defenderWarzone.addKillCount(a.getName(), 1); - defenderWarzone.addKillDeathRecord(a, 1, 0); - defenderWarzone.addKillDeathRecord(d, 0, 1); - if (attackerTeam.getTeamConfig().resolveBoolean(TeamConfig.XPKILLMETER)) { - a.setLevel(defenderWarzone.getKillCount(a.getName())); - } - if (attackerTeam.getTeamConfig().resolveBoolean(TeamConfig.KILLSTREAK)) { - War.war.getKillstreakReward().rewardPlayer(a, defenderWarzone.getKillCount(a.getName())); - } - if (defenderWarzone.getScoreboard() != null && - defenderWarzone.getScoreboardType() == ScoreboardType.TOPKILLS) { - Objective obj = attackerWarzone.getScoreboard().getObjective("Top kills"); - obj.getScore(a).setScore(defenderWarzone.getKillCount(a.getName())); - } - if (defenderTeam.getTeamConfig().resolveBoolean(TeamConfig.INVENTORYDROP)) { - dropItems(d.getLocation(), d.getInventory().getContents()); - dropItems(d.getLocation(), d.getInventory().getArmorContents()); - } - } WarPlayerDeathEvent event1 = new WarPlayerDeathEvent(defenderWarzone, d, a, event.getCause()); War.war.getServer().getPluginManager().callEvent(event1); - defenderWarzone.handleDeath(d); if (!defenderWarzone.getWarzoneConfig().getBoolean(WarzoneConfig.REALDEATHS)) { // fast respawn, don't really die event.setCancelled(true); - return; } - + if (d == a) { + defenderWarzone.handleSuicide(d); + } else { + defenderWarzone.handleKill(a, d, event.getDamager()); + } } else if (defenderWarzone.isBombThief(d.getName()) && d.getLocation().distance(a.getLocation()) < 2) { // Close combat, close enough to detonate Bomb bomb = defenderWarzone.getBombForThief(d.getName()); @@ -223,24 +152,11 @@ public class WarEntityListener implements Listener { // Notify everyone for (Team t : defenderWarzone.getTeams()) { - if (War.war.isSpoutServer()) { - for (Player p : t.getPlayers()) { - SpoutPlayer sp = SpoutManager.getPlayer(p); - if (sp.isSpoutCraftEnabled()) { - sp.sendNotification( - SpoutDisplayer.cleanForNotification(attackerTeam.getKind().getColor() + a.getName() + ChatColor.YELLOW + " made "), - SpoutDisplayer.cleanForNotification(defenderTeam.getKind().getColor() + d.getName() + ChatColor.YELLOW + " blow up!"), - Material.TNT, - (short)0, - 10000); - } - } - } - + t.sendAchievement(attackerTeam.getKind().getColor() + a.getName() + ChatColor.YELLOW + " made ", + defenderTeam.getKind().getColor() + d.getName() + ChatColor.YELLOW + " blow up!", new ItemStack(Material.TNT), 10000); t.teamcast("pvp.kill.bomb", attackerTeam.getKind().getColor() + a.getName() + ChatColor.WHITE, defenderTeam.getKind().getColor() + d.getName() + ChatColor.WHITE); } - } } else if (attackerTeam != null && defenderTeam != null && attackerTeam == defenderTeam && attackerWarzone == defenderWarzone && attacker.getEntityId() != defender.getEntityId()) { // same team, but not same person @@ -286,30 +202,16 @@ public class WarEntityListener implements Listener { } if (defenderWarzone.getReallyDeadFighters().contains(d.getName())) { // don't re-kill a dead person - if (d.getHealth() != 0) { - d.setHealth(0); - } - return; } - if (defenderWarzone.getWarzoneConfig().getBoolean(WarzoneConfig.DEATHMESSAGES)) { - String defenderString = Team.getTeamByPlayerName(d.getName()).getKind().getColor() + d.getName(); - if (event.getDamager() instanceof TNTPrimed) { - defenderWarzone.broadcast("pvp.death.explosion", defenderString + ChatColor.WHITE); - } else { - defenderWarzone.broadcast("pvp.death.other", defenderString + ChatColor.WHITE); - } - } WarPlayerDeathEvent event1 = new WarPlayerDeathEvent(defenderWarzone, d, null, event.getCause()); War.war.getServer().getPluginManager().callEvent(event1); - defenderWarzone.handleDeath(d); - if (!defenderWarzone.getWarzoneConfig().getBoolean(WarzoneConfig.REALDEATHS)) { // fast respawn, don't really die event.setCancelled(true); - return; } + defenderWarzone.handleNaturalKill(d, event); } } } @@ -432,36 +334,18 @@ public class WarEntityListener implements Listener { event.setCancelled(true); } else if (event.getDamage() >= player.getHealth()) { if (zone.getReallyDeadFighters().contains(player.getName())) { - // don't re-count the death points of an already dead person, make sure they are dead though - // (reason for this is that onEntityDamage sometimes fires more than once for one death) - if (player.getHealth() != 0) { - player.setHealth(0); - } + // don't re-count the death points of an already dead person return; } // Detect death, prevent it and respawn the player - if (zone.getWarzoneConfig().getBoolean(WarzoneConfig.DEATHMESSAGES)) { - String playerName = Team.getTeamByPlayerName(player.getName()).getKind().getColor() + player.getName() + ChatColor.WHITE; - if (event.getCause() == DamageCause.FIRE || event.getCause() == DamageCause.FIRE_TICK - || event.getCause() == DamageCause.LAVA || event.getCause() == DamageCause.LIGHTNING) { - zone.broadcast("pvp.death.fire", playerName); - } else if (event.getCause() == DamageCause.DROWNING) { - zone.broadcast("pvp.death.drown", playerName); - } else if (event.getCause() == DamageCause.FALL) { - zone.broadcast("pvp.death.fall", playerName); - } else { - zone.broadcast("pvp.death.other", playerName); - } - } WarPlayerDeathEvent event1 = new WarPlayerDeathEvent(zone, player, null, event.getCause()); War.war.getServer().getPluginManager().callEvent(event1); - zone.handleDeath(player); - if (!zone.getWarzoneConfig().getBoolean(WarzoneConfig.REALDEATHS)) { // fast respawn, don't really die event.setCancelled(true); } + zone.handleNaturalKill(player, event); } } } @@ -565,12 +449,8 @@ public class WarEntityListener implements Listener { } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void onEntityDeath(final EntityDeathEvent event) { - if (!War.war.isLoaded() || !(event.getEntity() instanceof Player)) { - return; - } - - Player player = (Player) event.getEntity(); + public void onPlayerDeath(final PlayerDeathEvent event) { + Player player = event.getEntity(); Warzone zone = Warzone.getZoneByPlayerName(player.getName()); if (zone != null) { event.getDrops().clear(); @@ -581,6 +461,9 @@ public class WarEntityListener implements Listener { if (zone.getWarzoneConfig().getBoolean(WarzoneConfig.DEATHMESSAGES)) { zone.broadcast("pvp.death.other", team.getKind().getColor() + player.getName()); } + War.war.getLogger().log(Level.WARNING, "We missed the death of player {0} - something went wrong.", player.getName()); + } else { + event.setDeathMessage(""); } } }