From 9e98351923f79232c878cc789fcbd22b4282c70a Mon Sep 17 00:00:00 2001 From: bm01 Date: Sat, 28 Apr 2012 06:14:19 +0200 Subject: [PATCH] Capped bleeding ticks for monsters, moved players bleeding to BleedTimer --- .../nossr50/datatypes/PlayerProfile.java | 27 ---- .../nossr50/listeners/EntityListener.java | 12 +- .../nossr50/listeners/PlayerListener.java | 7 +- src/main/java/com/gmail/nossr50/mcMMO.java | 2 +- .../gmail/nossr50/runnables/BleedTimer.java | 136 +++++++++++------- .../java/com/gmail/nossr50/skills/Swords.java | 18 +-- .../java/com/gmail/nossr50/skills/Taming.java | 10 +- .../java/com/gmail/nossr50/util/Combat.java | 133 ++++++++--------- 8 files changed, 163 insertions(+), 182 deletions(-) diff --git a/src/main/java/com/gmail/nossr50/datatypes/PlayerProfile.java b/src/main/java/com/gmail/nossr50/datatypes/PlayerProfile.java index d548edfc9..239fc51ae 100644 --- a/src/main/java/com/gmail/nossr50/datatypes/PlayerProfile.java +++ b/src/main/java/com/gmail/nossr50/datatypes/PlayerProfile.java @@ -19,8 +19,6 @@ import com.gmail.nossr50.mcMMO; public class PlayerProfile { - final static int MAX_BLEED_TICKS = 10; - /* HUD */ private HUDType hud; private int xpbarinc = 0; @@ -52,7 +50,6 @@ public class PlayerProfile { /* mySQL STUFF */ private int lastlogin = 0; private int userid = 0; - private int bleedticks = 0; HashMap skills = new HashMap(); //Skills and Levels HashMap skillsXp = new HashMap(); //Skills and XP @@ -608,30 +605,6 @@ public class PlayerProfile { partyChatMode = !partyChatMode; } - /* - * Bleed Stuff - */ - - public void decreaseBleedTicks() { - bleedticks--; - } - - public int getBleedTicks() { - return bleedticks; - } - - public void resetBleedTicks() { - bleedticks = 0; - } - - public void addBleedTicks(int newvalue){ - bleedticks += newvalue; - - if (bleedticks > MAX_BLEED_TICKS) { - bleedticks = MAX_BLEED_TICKS; - } - } - /* * Exploit Prevention */ diff --git a/src/main/java/com/gmail/nossr50/listeners/EntityListener.java b/src/main/java/com/gmail/nossr50/listeners/EntityListener.java index b99925a57..7fe6a9902 100644 --- a/src/main/java/com/gmail/nossr50/listeners/EntityListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/EntityListener.java @@ -143,17 +143,13 @@ public class EntityListener implements Listener { */ @EventHandler (priority = EventPriority.MONITOR) public void onEntityDeath(EntityDeathEvent event) { - LivingEntity x = event.getEntity(); - x.setFireTicks(0); + LivingEntity entity = event.getEntity(); + entity.setFireTicks(0); /* Remove bleed track */ - BleedTimer.remove(x); + BleedTimer.remove(entity); - Archery.arrowRetrievalCheck(x, plugin); - - if (x instanceof Player) { - Users.getProfile((Player)x).resetBleedTicks(); - } + Archery.arrowRetrievalCheck(entity, plugin); } /** diff --git a/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java b/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java index c8e16eca9..9aed76ea0 100644 --- a/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java @@ -27,6 +27,7 @@ import org.bukkit.inventory.ItemStack; import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.commands.general.XprateCommand; import com.gmail.nossr50.config.Config; +import com.gmail.nossr50.runnables.BleedTimer; import com.gmail.nossr50.runnables.RemoveProfileFromMemoryTask; import com.gmail.nossr50.spout.SpoutStuff; import com.gmail.nossr50.datatypes.AbilityType; @@ -43,7 +44,6 @@ import com.gmail.nossr50.skills.Repair; import com.gmail.nossr50.skills.Skills; import com.gmail.nossr50.skills.Taming; import com.gmail.nossr50.util.BlockChecks; -import com.gmail.nossr50.util.Combat; import com.gmail.nossr50.util.Item; import com.gmail.nossr50.util.ItemChecks; import com.gmail.nossr50.util.Permissions; @@ -140,7 +140,6 @@ public class PlayerListener implements Listener { @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onPlayerQuit(PlayerQuitEvent event) { Player player = event.getPlayer(); - PlayerProfile PP = Users.getProfile(player); /* GARBAGE COLLECTION */ @@ -150,9 +149,7 @@ public class PlayerListener implements Listener { } //Bleed it out - if(PP.getBleedTicks() > 0) { - Combat.dealDamage(player, PP.getBleedTicks() * 2); - } + BleedTimer.bleedOut(player); //Schedule PlayerProfile removal 2 minutes after quitting plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new RemoveProfileFromMemoryTask(player.getName()), 2400); diff --git a/src/main/java/com/gmail/nossr50/mcMMO.java b/src/main/java/com/gmail/nossr50/mcMMO.java index 029e5f4b6..4f760b42d 100644 --- a/src/main/java/com/gmail/nossr50/mcMMO.java +++ b/src/main/java/com/gmail/nossr50/mcMMO.java @@ -114,7 +114,7 @@ public class mcMMO extends JavaPlugin { //Regen & Cooldown timer (Runs every second) scheduler.scheduleSyncRepeatingTask(this, new SkillMonitor(this), 0, 20); //Bleed timer (Runs every two seconds) - scheduler.scheduleSyncRepeatingTask(this, new BleedTimer(this), 0, 40); + scheduler.scheduleSyncRepeatingTask(this, new BleedTimer(), 0, 40); registerCommands(); diff --git a/src/main/java/com/gmail/nossr50/runnables/BleedTimer.java b/src/main/java/com/gmail/nossr50/runnables/BleedTimer.java index b4c46e9c1..109149243 100644 --- a/src/main/java/com/gmail/nossr50/runnables/BleedTimer.java +++ b/src/main/java/com/gmail/nossr50/runnables/BleedTimer.java @@ -1,45 +1,51 @@ package com.gmail.nossr50.runnables; -import java.util.HashSet; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import com.gmail.nossr50.mcMMO; -import com.gmail.nossr50.datatypes.PlayerProfile; import com.gmail.nossr50.locale.LocaleLoader; import com.gmail.nossr50.util.Combat; -import com.gmail.nossr50.util.Users; public class BleedTimer implements Runnable { - private final mcMMO plugin; - - private static HashSet bleedList = new HashSet(); - private static HashSet bleedAddList = new HashSet(); - private static HashSet bleedRemoveList = new HashSet(); + private final static int MAX_BLEED_TICKS = 10; + + private static Map bleedList = new HashMap(); + private static Map bleedAddList = new HashMap(); + private static List bleedRemoveList = new ArrayList(); private static boolean lock = false; - public BleedTimer(final mcMMO plugin) { - this.plugin = plugin; - } - @Override public void run() { updateBleedList(); + bleedSimulate(); + } - // Player bleed simulation - for (Player player : plugin.getServer().getOnlinePlayers()) { - if (player == null) { - continue; + private void bleedSimulate() { + lock = true; + + for (Entry entry : bleedList.entrySet()) { + LivingEntity entity = entry.getKey(); + + if (entry.getValue() <= 0 || entity.isDead() || entity == null) { + remove(entity); + break; } - PlayerProfile PP = Users.getProfile(player); - if (PP == null) { - continue; - } + // Player bleed simulation + if (entity instanceof Player) { + Player player = (Player) entity; - if (PP.getBleedTicks() >= 1) { + if (!player.isOnline()) { + continue; + } //Never kill with Bleeding if (player.getHealth() - 2 < 0) { @@ -51,29 +57,16 @@ public class BleedTimer implements Runnable { Combat.dealDamage(player, 2); } - PP.decreaseBleedTicks(); + entry.setValue(entry.getValue() - 1); - if (PP.getBleedTicks() == 0) { + if (entry.getValue() <= 0) { player.sendMessage(LocaleLoader.getString("Swords.Combat.Bleeding.Stopped")); } } - } - - // Non-player bleed simulation - bleedSimulate(); - } - - private void bleedSimulate() { - lock = true; - - // Bleed monsters/animals - for (LivingEntity entity : bleedList) { - if ((entity == null || entity.isDead())) { - remove(entity); - continue; - } + // Bleed monsters/animals else { Combat.dealDamage(entity, 2); + entry.setValue(entry.getValue() - 1); } } @@ -83,17 +76,29 @@ public class BleedTimer implements Runnable { private void updateBleedList() { if (lock) { - plugin.getLogger().warning("mcBleedTimer attempted to update the bleedList but the list was locked!"); + mcMMO.p.getLogger().warning("mcBleedTimer attempted to update the bleedList but the list was locked!"); } else { - bleedList.removeAll(bleedRemoveList); + bleedList.keySet().removeAll(bleedRemoveList); bleedRemoveList.clear(); - bleedList.addAll(bleedAddList); + bleedList.putAll(bleedAddList); bleedAddList.clear(); } } + /** + * Instantly Bleed out a LivingEntity + * + * @param entity LivingEntity to bleed out + */ + public static void bleedOut(LivingEntity entity) { + if (bleedList.containsKey(entity)) { + Combat.dealDamage(entity, bleedList.get(entity) * 2); + bleedList.remove(entity); + } + } + /** * Remove a LivingEntity from the bleedList if it is in it * @@ -106,7 +111,7 @@ public class BleedTimer implements Runnable { } } else { - if (bleedList.contains(entity)) { + if (bleedList.containsKey(entity)) { bleedList.remove(entity); } } @@ -117,15 +122,50 @@ public class BleedTimer implements Runnable { * * @param entity LivingEntity to add */ - public static void add(LivingEntity entity) { + public static void add(LivingEntity entity, int ticks) { + int newTicks = ticks; + if (lock) { - if (!bleedAddList.contains(entity)) { - bleedAddList.add(entity); + if (bleedAddList.containsKey(entity)) { + newTicks += bleedAddList.get(entity); + + if (newTicks > MAX_BLEED_TICKS) { + newTicks = MAX_BLEED_TICKS; + } + + bleedAddList.put(entity, newTicks); + } + else { + if (newTicks > MAX_BLEED_TICKS) { + newTicks = MAX_BLEED_TICKS; + } + + bleedAddList.put(entity, newTicks); } } else { - if (!bleedList.contains(entity)){ - bleedList.add(entity); + if (bleedList.containsKey(entity)) { + newTicks += bleedList.get(entity); + + if (newTicks > MAX_BLEED_TICKS) { + newTicks = MAX_BLEED_TICKS; + } + + bleedList.put(entity, newTicks); + + // Need to find a better way to ensure that the entity stays in bleedList + // when some ticks are added but already marked for removal. + // Suggestion: Why not use Iterator.remove() and drop the lock boolean? + if (bleedRemoveList.contains(entity)) { + bleedRemoveList.remove(entity); + } + } + else { + if (newTicks > MAX_BLEED_TICKS) { + newTicks = MAX_BLEED_TICKS; + } + + bleedList.put(entity, newTicks); } } } @@ -137,6 +177,6 @@ public class BleedTimer implements Runnable { * @return true if in the list, false if not */ public static boolean contains(LivingEntity entity) { - return (bleedList.contains(entity) || bleedAddList.contains(entity)); + return (bleedList.containsKey(entity) || bleedAddList.containsKey(entity)); } } diff --git a/src/main/java/com/gmail/nossr50/skills/Swords.java b/src/main/java/com/gmail/nossr50/skills/Swords.java index 4c2797b75..6f89f012e 100644 --- a/src/main/java/com/gmail/nossr50/skills/Swords.java +++ b/src/main/java/com/gmail/nossr50/skills/Swords.java @@ -57,22 +57,16 @@ public class Swords { int skillCheck = Misc.skillCheck(skillLevel, MAX_BONUS_LEVEL); if (random.nextInt(1000) <= skillCheck && !entity.isDead()) { - if (entity instanceof Player) { - Player target = (Player) entity; - int bleedTicks; + int bleedTicks = 0; - if (skillLevel >= 750) { - bleedTicks = 3; - } - else { - bleedTicks = 2; - } - - Users.getProfile(target).addBleedTicks(bleedTicks); + if (skillLevel >= 750) { + bleedTicks = 3; } else { - BleedTimer.add(entity); + bleedTicks = 2; } + + BleedTimer.add(entity, bleedTicks); attacker.sendMessage(LocaleLoader.getString("Swords.Combat.Bleeding")); } } diff --git a/src/main/java/com/gmail/nossr50/skills/Taming.java b/src/main/java/com/gmail/nossr50/skills/Taming.java index 245d19698..c89a97200 100644 --- a/src/main/java/com/gmail/nossr50/skills/Taming.java +++ b/src/main/java/com/gmail/nossr50/skills/Taming.java @@ -92,14 +92,10 @@ public class Taming { event.setDamage(event.getDamage() * GORE_MULTIPLIER); if (entity instanceof Player) { - Player target = (Player) entity; + ((Player) entity).sendMessage(LocaleLoader.getString("Combat.StruckByGore")); + } - target.sendMessage(LocaleLoader.getString("Combat.StruckByGore")); - Users.getProfile(target).addBleedTicks(2); - } - else { - BleedTimer.add((LivingEntity) entity); - } + BleedTimer.add((LivingEntity) entity, 2); master.sendMessage(LocaleLoader.getString("Combat.Gore")); } diff --git a/src/main/java/com/gmail/nossr50/util/Combat.java b/src/main/java/com/gmail/nossr50/util/Combat.java index c1aee2e71..faeba2b36 100644 --- a/src/main/java/com/gmail/nossr50/util/Combat.java +++ b/src/main/java/com/gmail/nossr50/util/Combat.java @@ -62,12 +62,13 @@ public class Combat { combatAbilityChecks(attacker); if (ItemChecks.isSword(itemInHand) && Permissions.getInstance().swords(attacker)) { - if (!BleedTimer.contains(target) && Permissions.getInstance().swordsBleed(attacker)) { + if (Permissions.getInstance().swordsBleed(attacker)) { Swords.bleedCheck(attacker, target, plugin); } if (PPa.getAbilityMode(AbilityType.SERRATED_STRIKES) && Permissions.getInstance().serratedStrikes(attacker)) { - applyAbilityAoE(attacker, target, event.getDamage(), plugin, SkillType.SWORDS); + applyAbilityAoE(attacker, target, event.getDamage() / 4, plugin, SkillType.SWORDS); + BleedTimer.add(target, 5); } startGainXp(attacker, PPa, target, SkillType.SWORDS, plugin); @@ -86,7 +87,7 @@ public class Combat { } if (PPa.getAbilityMode(AbilityType.SKULL_SPLIITER) && Permissions.getInstance().skullSplitter(attacker)) { - applyAbilityAoE(attacker, target, event.getDamage(), plugin, SkillType.AXES); + applyAbilityAoE(attacker, target, event.getDamage() / 2, plugin, SkillType.AXES); } startGainXp(attacker, PPa, target, SkillType.AXES, plugin); @@ -139,9 +140,6 @@ public class Combat { case ARROW: archeryCheck((EntityDamageByEntityEvent) event, plugin); break; - - default: - break; } if (targetType.equals(EntityType.PLAYER)) { @@ -297,89 +295,76 @@ public class Combat { */ private static void applyAbilityAoE(Player attacker, LivingEntity target, int damage, mcMMO plugin, SkillType type) { int numberOfTargets = Misc.getTier(attacker.getItemInHand()); //The higher the weapon tier, the more targets you hit - int damageAmount = 0; - - if (type.equals(SkillType.AXES)) { - damageAmount = damage / 2; - } - else if (type.equals(SkillType.SWORDS)) { - damageAmount = damage / 4; - } + int damageAmount = damage; if (damageAmount < 1) { damageAmount = 1; } for (Entity entity : target.getNearbyEntities(2.5, 2.5, 2.5)) { - EntityType entityType = entity.getType(); - - if (entityType.equals(EntityType.WOLF)) { - Wolf wolf = (Wolf) entity; - AnimalTamer tamer = wolf.getOwner(); + if (!(entity instanceof LivingEntity)) { + continue; + } + + if (numberOfTargets <= 0) { + break; + } + + switch (entity.getType()) { + case WOLF: + AnimalTamer tamer = ((Wolf) entity).getOwner(); if (tamer instanceof Player) { - Player owner = (Player) tamer; - - if (owner.equals(attacker) || Party.getInstance().inSameParty(attacker, owner)) { + if (tamer.equals(attacker) || Party.getInstance().inSameParty(attacker, (Player) tamer)) { continue; } } + + break; + case PLAYER: + Player defender = (Player) entity; + + if (!target.getWorld().getPVP()) { + continue; + } + + if (defender.getName().equals(attacker.getName())) { + continue; + } + + if (Party.getInstance().inSameParty(attacker, defender)) { + continue; + } + + PlayerProfile playerProfile = Users.getProfile((Player) entity); + + if (playerProfile.getGodMode()) { + continue; + } + + break; } - - if (entity instanceof LivingEntity && numberOfTargets >= 1) { - if (entityType.equals(EntityType.PLAYER)) { - Player defender = (Player) entity; - PlayerProfile PP = Users.getProfile(defender); - - //Reasons why the target shouldn't be hit - if (PP.getGodMode()) { - continue; - } - - if (defender.getName().equals(attacker.getName())) { //Is this even possible? - continue; - } - - if (Party.getInstance().inSameParty(attacker, defender)) { - continue; - } - - if (defender.isDead()) { - continue; - } - - //Apply effect to players only if PVP is enabled - if (target.getWorld().getPVP()) { - String message = ""; - - if (type.equals(SkillType.AXES)) { - message = LocaleLoader.getString("Axes.Combat.Cleave.Struck"); - } - else if (type.equals(SkillType.SWORDS)) { - message = LocaleLoader.getString("Swords.Combat.SS.Struck"); - } - - dealDamage(defender, damageAmount, attacker); - defender.sendMessage(message); - - if (type.equals(SkillType.SWORDS)) { - PP.addBleedTicks(5); - } - - numberOfTargets--; - } + + + switch (type) { + case SWORDS: + if (entity instanceof Player) { + ((Player) entity).sendMessage(LocaleLoader.getString("Swords.Combat.SS.Struck")); } - else { - LivingEntity livingEntity = (LivingEntity) entity; - - if (type.equals(SkillType.SWORDS)) { - BleedTimer.add(livingEntity); - } - - dealDamage(livingEntity, damageAmount, attacker); - numberOfTargets--; + + BleedTimer.add((LivingEntity) entity, 5); + + break; + case AXES: + if (entity instanceof Player) { + ((Player) entity).sendMessage(LocaleLoader.getString("Axes.Combat.Cleave.Struck")); } + + break; } + + dealDamage((LivingEntity) entity, damageAmount, attacker); + numberOfTargets--; } }