From 3c0424db516afa105a9b339ef49ab0866d59cb83 Mon Sep 17 00:00:00 2001 From: Benford Whitaker Date: Sat, 18 Jul 2020 21:23:36 -0400 Subject: [PATCH] Fix TempArmor Dupe (#1065) ## Additions * Adds new methods to GeneralMethods involving armor Material checks. ## Fixes * Fixes TempArmor duping glitches --- .../projectkorra/GeneralMethods.java | 122 ++++++++++++++++++ .../projectkorra/projectkorra/PKListener.java | 50 ++++--- .../projectkorra/earthbending/EarthGrab.java | 30 ++--- .../earthbending/metal/MetalClips.java | 24 ++-- .../projectkorra/util/TempArmor.java | 28 +++- 5 files changed, 208 insertions(+), 46 deletions(-) diff --git a/src/com/projectkorra/projectkorra/GeneralMethods.java b/src/com/projectkorra/projectkorra/GeneralMethods.java index 990ed418..075fdce6 100644 --- a/src/com/projectkorra/projectkorra/GeneralMethods.java +++ b/src/com/projectkorra/projectkorra/GeneralMethods.java @@ -317,6 +317,10 @@ public class GeneralMethods { final boolean c = xyzsolid[1] && xyzsolid[2]; return (a || b || c || (a && b)); } + + public static int compareArmor(Material first, Material second) { + return getArmorTier(first) - getArmorTier(second); + } /** * Creates a {@link BendingPlayer} with the data from the database. This @@ -696,6 +700,81 @@ public class GeneralMethods { e.printStackTrace(); } } + + public static int getArmorTier(Material mat) { + switch (mat) { + case NETHERITE_HELMET: + case NETHERITE_CHESTPLATE: + case NETHERITE_LEGGINGS: + case NETHERITE_BOOTS: + return 7; + case DIAMOND_HELMET: + case DIAMOND_CHESTPLATE: + case DIAMOND_LEGGINGS: + case DIAMOND_BOOTS: + return 6; + case TURTLE_HELMET: + return 5; + case IRON_HELMET: + case IRON_CHESTPLATE: + case IRON_LEGGINGS: + case IRON_BOOTS: + return 4; + case CHAINMAIL_HELMET: + case CHAINMAIL_CHESTPLATE: + case CHAINMAIL_LEGGINGS: + case CHAINMAIL_BOOTS: + return 3; + case GOLDEN_HELMET: + case GOLDEN_CHESTPLATE: + case GOLDEN_LEGGINGS: + case GOLDEN_BOOTS: + return 2; + case LEATHER_HELMET: + case LEATHER_CHESTPLATE: + case LEATHER_LEGGINGS: + case LEATHER_BOOTS: + return 1; + default: + return 0; + } + } + + public static int getArmorIndex(Material mat) { + switch (mat) { + case NETHERITE_HELMET: + case DIAMOND_HELMET: + case TURTLE_HELMET: + case IRON_HELMET: + case CHAINMAIL_HELMET: + case GOLDEN_HELMET: + case LEATHER_HELMET: + return 3; + case NETHERITE_CHESTPLATE: + case DIAMOND_CHESTPLATE: + case IRON_CHESTPLATE: + case CHAINMAIL_CHESTPLATE: + case GOLDEN_CHESTPLATE: + case LEATHER_CHESTPLATE: + return 2; + case NETHERITE_LEGGINGS: + case DIAMOND_LEGGINGS: + case IRON_LEGGINGS: + case CHAINMAIL_LEGGINGS: + case GOLDEN_LEGGINGS: + case LEATHER_LEGGINGS: + return 1; + case NETHERITE_BOOTS: + case DIAMOND_BOOTS: + case IRON_BOOTS: + case CHAINMAIL_BOOTS: + case GOLDEN_BOOTS: + case LEATHER_BOOTS: + return 0; + default: + return -1; + } + } /** * This gets the BlockFace in the specified dimension of a certain value @@ -1340,6 +1419,39 @@ public class GeneralMethods { public static boolean hasSpirits() { return Bukkit.getServer().getPluginManager().getPlugin("ProjectKorraSpirits") != null; } + + public static boolean isArmor(Material mat) { + switch (mat) { + case NETHERITE_HELMET: + case NETHERITE_CHESTPLATE: + case NETHERITE_LEGGINGS: + case NETHERITE_BOOTS: + case DIAMOND_HELMET: + case DIAMOND_CHESTPLATE: + case DIAMOND_LEGGINGS: + case DIAMOND_BOOTS: + case TURTLE_HELMET: + case IRON_HELMET: + case IRON_CHESTPLATE: + case IRON_LEGGINGS: + case IRON_BOOTS: + case CHAINMAIL_HELMET: + case CHAINMAIL_CHESTPLATE: + case CHAINMAIL_LEGGINGS: + case CHAINMAIL_BOOTS: + case GOLDEN_HELMET: + case GOLDEN_CHESTPLATE: + case GOLDEN_LEGGINGS: + case GOLDEN_BOOTS: + case LEATHER_HELMET: + case LEATHER_CHESTPLATE: + case LEATHER_LEGGINGS: + case LEATHER_BOOTS: + return true; + default: + return false; + } + } public static boolean isAdjacentToThreeOrMoreSources(final Block block) { return isAdjacentToThreeOrMoreSources(block, false); @@ -1637,6 +1749,16 @@ public class GeneralMethods { } return false; } + + public static boolean isSameArmor(Material a, Material b) { + int ai = getArmorIndex(a), bi = getArmorIndex(b); + + if (ai == -1 || bi == -1) { + return false; + } + + return ai == bi; + } public static boolean isSolid(final Block block) { return isSolid(block.getType()); diff --git a/src/com/projectkorra/projectkorra/PKListener.java b/src/com/projectkorra/projectkorra/PKListener.java index b041bd22..d2e4326e 100644 --- a/src/com/projectkorra/projectkorra/PKListener.java +++ b/src/com/projectkorra/projectkorra/PKListener.java @@ -7,8 +7,6 @@ import java.util.List; import java.util.Map; import java.util.UUID; -import co.aikar.timings.lib.MCTiming; - import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.GameMode; @@ -19,6 +17,7 @@ import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; +import org.bukkit.entity.Item; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -191,6 +190,8 @@ import com.projectkorra.projectkorra.waterbending.multiabilities.WaterArms; import com.projectkorra.projectkorra.waterbending.passive.FastSwim; import com.projectkorra.projectkorra.waterbending.passive.HydroSink; +import co.aikar.timings.lib.MCTiming; + public class PKListener implements Listener { ProjectKorra plugin; @@ -548,21 +549,13 @@ public class PKListener implements Listener { @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onEntityDeath(final EntityDeathEvent event) { if (TempArmor.hasTempArmor(event.getEntity())) { - final TempArmor armor = TempArmor.getVisibleTempArmor(event.getEntity()); - - if (armor != null) { - final List newDrops = armor.filterArmor(event.getDrops()); - event.getDrops().clear(); - event.getDrops().addAll(newDrops); + for (final TempArmor tarmor : TempArmor.getTempArmorList(event.getEntity())) { + tarmor.revert(event.getDrops()); } if (MetalClips.isControlled(event.getEntity())) { event.getDrops().add(new ItemStack(Material.IRON_INGOT, MetalClips.getTargetToAbility().get(event.getEntity()).getMetalClipsCount())); } - - for (final TempArmor tarmor : TempArmor.getTempArmorList(event.getEntity())) { - tarmor.revert(); - } } final CoreAbility[] cookingFireCombos = { CoreAbility.getAbility("JetBlast"), CoreAbility.getAbility("FireWheel"), CoreAbility.getAbility("FireSpin"), CoreAbility.getAbility("FireKick") }; @@ -716,7 +709,7 @@ public class PKListener implements Listener { if (entity instanceof LivingEntity && TempArmor.hasTempArmor((LivingEntity) entity)) { for (final TempArmor armor : TempArmor.getTempArmorList((LivingEntity) entity)) { - armor.revert(); + armor.revert(null); } } @@ -1015,7 +1008,7 @@ public class PKListener implements Listener { if (event.getKeepInventory()) { if (TempArmor.hasTempArmor(event.getEntity())) { for (final TempArmor armor : TempArmor.getTempArmorList(event.getEntity())) { - armor.revert(); + armor.revert(event.getDrops()); } } } else { @@ -1370,7 +1363,7 @@ public class PKListener implements Listener { if (TempArmor.hasTempArmor(player)) { for (final TempArmor armor : TempArmor.getTempArmorList(player)) { - armor.revert(); + armor.revert(null); } } @@ -1895,6 +1888,33 @@ public class PKListener implements Listener { event.setCancelled(true); } } + + if (event.isCancelled()) { + return; + } + + if (event.getEntity() instanceof LivingEntity) { + LivingEntity lent = (LivingEntity) event.getEntity(); + + if (TempArmor.hasTempArmor(lent)) { + TempArmor armor = TempArmor.getVisibleTempArmor(lent); + ItemStack is = event.getItem().getItemStack(); + int index = GeneralMethods.getArmorIndex(is.getType()); + + if (index == -1) { + return; + } + + event.setCancelled(true); + ItemStack prev = armor.getOldArmor()[index]; + + if (GeneralMethods.compareArmor(is.getType(), prev.getType()) > 0) { + event.getEntity().getWorld().dropItemNaturally(event.getEntity().getLocation(), prev); + armor.getOldArmor()[index] = is; + event.getItem().remove(); + } + } + } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) diff --git a/src/com/projectkorra/projectkorra/earthbending/EarthGrab.java b/src/com/projectkorra/projectkorra/earthbending/EarthGrab.java index d9f3c97c..6a861982 100644 --- a/src/com/projectkorra/projectkorra/earthbending/EarthGrab.java +++ b/src/com/projectkorra/projectkorra/earthbending/EarthGrab.java @@ -203,20 +203,20 @@ public class EarthGrab extends EarthAbility { this.mHandler = new MovementHandler(this.target, this); this.mHandler.stop(Element.EARTH.getColor() + "* Trapped *"); -// if (this.target instanceof Player || this.target instanceof Zombie || this.target instanceof Skeleton) { -// final ItemStack legs = new ItemStack(Material.LEATHER_LEGGINGS); -// final LeatherArmorMeta legmeta = (LeatherArmorMeta) legs.getItemMeta(); -// legmeta.setColor(Color.fromRGB(EarthArmor.getColor(m))); -// legs.setItemMeta(legmeta); -// -// final ItemStack feet = new ItemStack(Material.LEATHER_BOOTS); -// final LeatherArmorMeta footmeta = (LeatherArmorMeta) feet.getItemMeta(); -// footmeta.setColor(Color.fromRGB(EarthArmor.getColor(m))); -// feet.setItemMeta(footmeta); -// -// final ItemStack[] pieces = { (this.target.getEquipment().getArmorContents()[0] == null || this.target.getEquipment().getArmorContents()[0].getType() == Material.AIR) ? feet : null, (this.target.getEquipment().getArmorContents()[1] == null || this.target.getEquipment().getArmorContents()[1].getType() == Material.AIR) ? legs : null, null, null }; -// this.armor = new TempArmor(this.target, 36000000L, this, pieces); -// } + if (this.target instanceof Player || this.target instanceof Zombie || this.target instanceof Skeleton) { + final ItemStack legs = new ItemStack(Material.LEATHER_LEGGINGS); + final LeatherArmorMeta legmeta = (LeatherArmorMeta) legs.getItemMeta(); + legmeta.setColor(Color.fromRGB(EarthArmor.getColor(m))); + legs.setItemMeta(legmeta); + + final ItemStack feet = new ItemStack(Material.LEATHER_BOOTS); + final LeatherArmorMeta footmeta = (LeatherArmorMeta) feet.getItemMeta(); + footmeta.setColor(Color.fromRGB(EarthArmor.getColor(m))); + feet.setItemMeta(footmeta); + + final ItemStack[] pieces = { (this.target.getEquipment().getArmorContents()[0] == null || this.target.getEquipment().getArmorContents()[0].getType() == Material.AIR) ? feet : null, (this.target.getEquipment().getArmorContents()[1] == null || this.target.getEquipment().getArmorContents()[1].getType() == Material.AIR) ? legs : null, null, null }; + this.armor = new TempArmor(this.target, 36000000L, this, pieces); + } playEarthbendingSound(this.target.getLocation()); this.initiated = true; @@ -330,7 +330,7 @@ public class EarthGrab extends EarthAbility { if (System.currentTimeMillis() >= this.lastHit + this.interval) { this.trapHP -= 1; this.lastHit = System.currentTimeMillis(); - ParticleEffect.BLOCK_CRACK.display(this.target.getLocation().clone().add(0, 1, 0), 17, 0.1, 0.5, 0.1, this.target.getLocation().getBlock().getRelative(BlockFace.DOWN).getBlockData()); + ParticleEffect.BLOCK_CRACK.display(this.target.getLocation().clone().add(0, 1, 0), 7, 0.06, 0.3, 0.06, this.target.getLocation().getBlock().getRelative(BlockFace.DOWN).getBlockData()); playEarthbendingSound(this.target.getLocation()); } } diff --git a/src/com/projectkorra/projectkorra/earthbending/metal/MetalClips.java b/src/com/projectkorra/projectkorra/earthbending/metal/MetalClips.java index d535e137..3dde48e6 100644 --- a/src/com/projectkorra/projectkorra/earthbending/metal/MetalClips.java +++ b/src/com/projectkorra/projectkorra/earthbending/metal/MetalClips.java @@ -172,29 +172,25 @@ public class MetalClips extends MetalAbility { this.metalClipsCount = (this.metalClipsCount < 4) ? this.metalClipsCount + 1 : 4; - for (final TempArmor armor : TempArmor.getTempArmorList(this.targetEntity)) { - armor.revert(); - } - if (this.targetEntity instanceof Player) { final Player target = (Player) this.targetEntity; final ItemStack[] metalArmor = new ItemStack[4]; - metalArmor[2] = (this.metalClipsCount >= 1) ? new ItemStack(Material.IRON_CHESTPLATE) : new ItemStack(Material.AIR); - metalArmor[0] = (this.metalClipsCount >= 2) ? new ItemStack(Material.IRON_BOOTS) : new ItemStack(Material.AIR); - metalArmor[1] = (this.metalClipsCount >= 3) ? new ItemStack(Material.IRON_LEGGINGS) : new ItemStack(Material.AIR); - metalArmor[3] = (this.metalClipsCount >= 4) ? new ItemStack(Material.IRON_HELMET) : new ItemStack(Material.AIR); + metalArmor[2] = (this.metalClipsCount >= 1) ? new ItemStack(Material.IRON_CHESTPLATE) : null; + metalArmor[0] = (this.metalClipsCount >= 2) ? new ItemStack(Material.IRON_BOOTS) : null; + metalArmor[1] = (this.metalClipsCount >= 3) ? new ItemStack(Material.IRON_LEGGINGS) : null; + metalArmor[3] = (this.metalClipsCount >= 4) ? new ItemStack(Material.IRON_HELMET) : null; ENTITY_CLIPS_COUNT.put(target, this.metalClipsCount); new TempArmor(target, this, metalArmor); } else { final ItemStack[] metalarmor = new ItemStack[4]; - metalarmor[2] = (this.metalClipsCount >= 1) ? new ItemStack(Material.IRON_CHESTPLATE) : new ItemStack(Material.AIR); - metalarmor[0] = (this.metalClipsCount >= 2) ? new ItemStack(Material.IRON_BOOTS) : new ItemStack(Material.AIR); - metalarmor[1] = (this.metalClipsCount >= 3) ? new ItemStack(Material.IRON_LEGGINGS) : new ItemStack(Material.AIR); - metalarmor[3] = (this.metalClipsCount >= 4) ? new ItemStack(Material.IRON_HELMET) : new ItemStack(Material.AIR); + metalarmor[2] = (this.metalClipsCount >= 1) ? new ItemStack(Material.IRON_CHESTPLATE) : null; + metalarmor[0] = (this.metalClipsCount >= 2) ? new ItemStack(Material.IRON_BOOTS) : null; + metalarmor[1] = (this.metalClipsCount >= 3) ? new ItemStack(Material.IRON_LEGGINGS) : null; + metalarmor[3] = (this.metalClipsCount >= 4) ? new ItemStack(Material.IRON_HELMET) : null; ENTITY_CLIPS_COUNT.put(this.targetEntity, this.metalClipsCount); new TempArmor(this.targetEntity, this, metalarmor); @@ -208,7 +204,9 @@ public class MetalClips extends MetalAbility { return; } - TempArmor.getVisibleTempArmor(this.targetEntity).revert(); + for (final TempArmor tarmor : TempArmor.getTempArmorList(targetEntity)) { + tarmor.revert(); + } this.dropIngots(this.targetEntity.getLocation()); this.isBeingWorn = false; } diff --git a/src/com/projectkorra/projectkorra/util/TempArmor.java b/src/com/projectkorra/projectkorra/util/TempArmor.java index beae12cb..f016d668 100644 --- a/src/com/projectkorra/projectkorra/util/TempArmor.java +++ b/src/com/projectkorra/projectkorra/util/TempArmor.java @@ -197,14 +197,20 @@ public class TempArmor { this.removeAbilOnForceRevert = bool; } + public void revert() { + revert(null); + } + /** * Destroys the TempArmor instance and removes it from the display queue. *
*
* Will also restore the player's armor to the state it was before any * TempArmor instance was started, if the display queue is empty. + * + * @param drops A list of drops to filter temporary armor from when reverting, null if n/a */ - public void revert() { + public void revert(List drops) { final PriorityQueue queue = INSTANCES.get(this.entity); if (queue.contains(this)) { @@ -218,8 +224,24 @@ public class TempArmor { queue.remove(this); } } + + if (drops != null) { + for (ItemStack is : newArmor) { + if (is != null) { + drops.remove(is); + } + } + } if (queue.isEmpty()) { + if (drops != null) { + for (ItemStack is : ORIGINAL.get(this.entity)) { + if (is != null) { + drops.add(is); + } + } + } + this.entity.getEquipment().setArmorContents(ORIGINAL.get(this.entity)); INSTANCES.remove(this.entity); ORIGINAL.remove(this.entity); @@ -236,7 +258,7 @@ public class TempArmor { while (!queue.isEmpty()) { final TempArmor tarmor = queue.peek(); if (System.currentTimeMillis() >= tarmor.getStartTime() + tarmor.getDuration()) { - tarmor.revert(); + tarmor.revert(null); } else { break; } @@ -252,7 +274,7 @@ public class TempArmor { for (final LivingEntity entity : INSTANCES.keySet()) { while (!INSTANCES.get(entity).isEmpty()) { final TempArmor armor = INSTANCES.get(entity).poll(); - armor.revert(); + armor.revert(null); } } }