From 80d2b64dd3ed2a1a0c67ab67cda59766f298b3d5 Mon Sep 17 00:00:00 2001 From: StrangeOne101 Date: Thu, 7 Jul 2016 10:16:05 +1200 Subject: [PATCH] Bloodbending + Other fixes (#513) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • Fixed binds being removed when non-ops relog • Fixed Lavaflow destroying plants and flowers • Fixed Bloodbending being spammed • Fixed Bloodbending being able to bloodbending grouped players • Fixed Bloodbending in the AvatarState from going haywire • Fixed Bloodbending having no default cooldown • Fixed PK Side Plugins (Items, Probending) from showing up in the wrong place in the debug file --- .../projectkorra/GeneralMethods.java | 5 +- .../projectkorra/projectkorra/PKListener.java | 10 +- .../projectkorra/ability/CoreAbility.java | 2 +- .../configuration/ConfigManager.java | 12 +- .../projectkorra/earthbending/LavaFlow.java | 32 +++-- .../waterbending/Bloodbending.java | 117 +++++++++--------- .../waterbending/PlantRegrowth.java | 12 ++ 7 files changed, 116 insertions(+), 74 deletions(-) diff --git a/src/com/projectkorra/projectkorra/GeneralMethods.java b/src/com/projectkorra/projectkorra/GeneralMethods.java index 17c61987..2fa5cc1b 100644 --- a/src/com/projectkorra/projectkorra/GeneralMethods.java +++ b/src/com/projectkorra/projectkorra/GeneralMethods.java @@ -1510,8 +1510,11 @@ public class GeneralMethods { writeToDebug(""); writeToDebug("Plugins Hooking Into ProjectKorra (Core)"); writeToDebug("===================="); + + String[] pkPlugins = new String[] {"projectkorrarpg", "projectkorraitems", "projectkorraspirits", "probending"}; for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) { - if (plugin.getDescription().getDepend() != null && plugin.getDescription().getDepend().contains("ProjectKorra")) { + if (plugin.getDescription().getDepend() != null && plugin.getDescription().getDepend().contains("ProjectKorra") + && !Arrays.asList(pkPlugins).contains(plugin.getName().toLowerCase())) { writeToDebug(plugin.getDescription().getName() + " v" + plugin.getDescription().getVersion()); } } diff --git a/src/com/projectkorra/projectkorra/PKListener.java b/src/com/projectkorra/projectkorra/PKListener.java index bfc5c546..af01541f 100644 --- a/src/com/projectkorra/projectkorra/PKListener.java +++ b/src/com/projectkorra/projectkorra/PKListener.java @@ -1029,11 +1029,17 @@ public class PKListener implements Listener { @EventHandler public void onPlayerJoin(PlayerJoinEvent event) { - Player player = event.getPlayer(); + final Player player = event.getPlayer(); JUMPS.put(player, player.getStatistic(Statistic.JUMP)); GeneralMethods.createBendingPlayer(player.getUniqueId(), player.getName()); - GeneralMethods.removeUnusableAbilities(player.getName()); + Bukkit.getScheduler().runTaskLater(ProjectKorra.plugin, new Runnable() { + + @Override + public void run() { + GeneralMethods.removeUnusableAbilities(player.getName()); + } + }, 5); } @EventHandler diff --git a/src/com/projectkorra/projectkorra/ability/CoreAbility.java b/src/com/projectkorra/projectkorra/ability/CoreAbility.java index d3f8ae58..3efde921 100644 --- a/src/com/projectkorra/projectkorra/ability/CoreAbility.java +++ b/src/com/projectkorra/projectkorra/ability/CoreAbility.java @@ -598,7 +598,7 @@ public abstract class CoreAbility implements Ability { } sb.append("Class->UUID's in memory: " + playerCounter + "\n"); - sb.append("Abilities in memory\n"); + sb.append("Abilities in memory:\n"); for (String className : classCounter.keySet()) { sb.append(className + ": " + classCounter.get(className) + "\n"); } diff --git a/src/com/projectkorra/projectkorra/configuration/ConfigManager.java b/src/com/projectkorra/projectkorra/configuration/ConfigManager.java index b0d45403..e6220a1f 100644 --- a/src/com/projectkorra/projectkorra/configuration/ConfigManager.java +++ b/src/com/projectkorra/projectkorra/configuration/ConfigManager.java @@ -212,7 +212,7 @@ public class ConfigManager { config.addDefault("Abilities.Avatar.AvatarState.Description", "The signature ability of the Avatar, this is a toggle. Click to activate to become " + "nearly unstoppable. While in the Avatar State, the user takes severely reduced damage from " + "all sources, regenerates health rapidly, and is granted extreme speed. Nearly all abilities " + "are incredibly amplified in this state. Additionally, AirShield and FireJet become toggle-able " + "abilities and last until you deactivate them or the Avatar State. Click again with the Avatar " + "State selected to deactivate it."); - config.addDefault("Commands.Help.Elements.Air", "Air is the element of freedom. Airbenders are natural pacifists and great explorers. There is nothing stopping them from scaling the tallest of mountains and walls easily. They specialize in redirection, from blasting things away with gusts of winds, to forming a shield around them to prevent damage. Easy to get across flat terrains, such as oceans, there is practically no terrain off limits to Airbenders. They lack much raw damage output, but make up for it with with their ridiculous amounts of utility and speed.\nAirbenders can chain their abilities into combos, type /b help AirCombos for more information."); + config.addDefault("Abilities.Air.Description", "Air is the element of freedom. Airbenders are natural pacifists and great explorers. There is nothing stopping them from scaling the tallest of mountains and walls easily. They specialize in redirection, from blasting things away with gusts of winds, to forming a shield around them to prevent damage. Easy to get across flat terrains, such as oceans, there is practically no terrain off limits to Airbenders. They lack much raw damage output, but make up for it with with their ridiculous amounts of utility and speed.\nAirbenders can chain their abilities into combos, type /b help AirCombos for more information."); config.addDefault("Abilities.Air.AirBlast.Description", "AirBlast is the most fundamental bending technique of an airbender." + " To use, simply left-click in a direction. A gust of wind will be" + " created at your fingertips, launching anything in its path harmlessly back." + " A gust of air can extinguish fires on the ground or on a player, can cool lava, and " + "can flip levers and activate buttons. Additionally, tapping sneak will change the " + "origin of your next AirBlast to your targeted location."); config.addDefault("Abilities.Air.AirBlast.DeathMessage", "{victim} was flung by {attacker}'s {ability}"); config.addDefault("Abilities.Air.AirBlast.HorizontalVelocityDeath","{victim} experienced kinetic damage by {attacker}'s {ability}"); @@ -236,7 +236,7 @@ public class ConfigManager { config.addDefault("Abilities.Air.Combo.AirSweep.Description", "Sweep the air in front of you hitting multiple enemies, causing moderate damage and a large knockback. The radius and direction of AirSweep is controlled by moving your mouse in a sweeping motion. For example, if you want to AirSweep upward, then move your mouse upward right after you left click AirBurst"); config.addDefault("Abilities.Air.Combo.AirSweep.DeathMessage", "{victim} was swept away by {attacker}'s {ability}"); - config.addDefault("Commands.Help.Elements.Water", "Water is the element of change. Waterbending focuses on using your opponents own force against them. Using redirection and various dodging tactics, you can be made practically untouchable by an opponent. Waterbending provides agility, along with strong offensive skills while in or near water.\nWaterbenders can chain their abilities into combos, type /b help WaterCombos for more information."); + config.addDefault("Abilities.Water.Description", "Water is the element of change. Waterbending focuses on using your opponents own force against them. Using redirection and various dodging tactics, you can be made practically untouchable by an opponent. Waterbending provides agility, along with strong offensive skills while in or near water.\nWaterbenders can chain their abilities into combos, type /b help WaterCombos for more information."); config.addDefault("Abilities.Water.Bloodbending.Description", "This ability was made illegal for a reason. With this ability selected, sneak while " + "targetting something and you will bloodbend that target. Bloodbent targets cannot move, " + "bend or attack. You are free to control their actions by looking elsewhere - they will " + "be forced to move in that direction. Additionally, clicking while bloodbending will " + "launch that target off in the direction you're looking. " + "People who are capable of bloodbending are immune to your technique, and you are immune to theirs."); config.addDefault("Abilities.Water.Bloodbending.DeathMessage", "{victim} was destroyed by {attacker}'s {ability}"); config.addDefault("Abilities.Water.Bloodbending.HorizontalVelocityDeath","{victim} experienced kinetic damage by {attacker}'s {ability}"); @@ -266,7 +266,7 @@ public class ConfigManager { config.addDefault("Abilities.Water.Combo.IceWave.Description", "PhaseChange your WaterWave into an IceWave that freezes and damages enemies."); config.addDefault("Abilities.Water.Combo.IceWave.DeathMessage", "{victim} was frozen solid by {attacker}'s {ability}"); - config.addDefault("Commands.Help.Elements.Earth", "Earth is the element of substance. Earthbenders share many of the same fundamental techniques as Waterbenders, but their domain is quite different and more readily accessible. Earthbenders dominate the ground and subterranean, having abilities to pull columns of rock straight up from the earth or drill their way through the mountain. They can also launch themselves through the air using pillars of rock, and will not hurt themselves assuming they land on something they can bend. The more skilled Earthbenders can even bend metal."); + config.addDefault("Abilities.Earth.Description", "Earth is the element of substance. Earthbenders share many of the same fundamental techniques as Waterbenders, but their domain is quite different and more readily accessible. Earthbenders dominate the ground and subterranean, having abilities to pull columns of rock straight up from the earth or drill their way through the mountain. They can also launch themselves through the air using pillars of rock, and will not hurt themselves assuming they land on something they can bend. The more skilled Earthbenders can even bend metal."); config.addDefault("Abilities.Earth.Catapult.Description", "To use, left-click while looking in the direction you want to be launched. " + "A pillar of earth will jut up from under you and launch you in that direction - " + "if and only if there is enough earth behind where you're looking to launch you. " + "Skillful use of this ability takes much time and work, and it does result in the " + "death of certain gung-ho earthbenders. If you plan to use this ability, be sure " + "you've read about your passive ability you innately have as an earthbender."); config.addDefault("Abilities.Earth.Collapse.Description", " To use, simply left-click on an earthbendable block. " + "That block and the earthbendable blocks above it will be shoved " + "back into the earth below them, if they can. " + "This ability does have the capacity to trap something inside of it, " + "although it is incredibly difficult to do so. " + "Additionally, press sneak with this ability to affect an area around your targetted location - " + "all earth that can be moved downwards will be moved downwards. " + "This ability is especially risky or deadly in caves, depending on the " + "earthbender's goal and technique."); config.addDefault("Abilities.Earth.Collapse.DeathMessage", "{victim} was suffocated by {attacker}'s {ability}"); @@ -288,7 +288,7 @@ public class ConfigManager { config.addDefault("Abilities.Earth.SandSpout.Description", "SandSpout is a core move for travelling, evasion, and mobility for sandbenders. To use, simply left click while over sand or sandstone, and a column of sand will form at your feet, enabling you to levitate. Any mobs or players that touch your column will receive damage and be blinded. Beware, as the spout will stop working when no longer over sand!"); config.addDefault("Abilities.Earth.Tremorsense.Description", "This is a pure utility ability for earthbenders. If you are in an area of low-light and are standing on top of an earthbendable block, this ability will automatically turn that block into glowstone, visible *only by you*. If you lose contact with a bendable block, the light will go out as you have lost contact with the earth and cannot 'see' until you can touch earth again. Additionally, if you click with this ability selected, smoke will appear above nearby earth with pockets of air beneath them."); - config.addDefault("Commands.Help.Elements.Fire", "Fire is the element of power. Firebenders focus on destruction and incineration. Their abilities are pretty straight forward: set things on fire. They do have a bit of utility however, being able to make themselves un-ignitable, extinguish large areas, cook food in their hands, extinguish large areas, small bursts of flight, and then comes the abilities to shoot fire from your hands.\nFirebenders can chain their abilities into combos, type /b help FireCombos for more information."); + config.addDefault("Abilities.Fire.Description", "Fire is the element of power. Firebenders focus on destruction and incineration. Their abilities are pretty straight forward: set things on fire. They do have a bit of utility however, being able to make themselves un-ignitable, extinguish large areas, cook food in their hands, extinguish large areas, small bursts of flight, and then comes the abilities to shoot fire from your hands.\nFirebenders can chain their abilities into combos, type /b help FireCombos for more information."); config.addDefault("Abilities.Fire.Blaze.Description", "To use, simply left-click in any direction. An arc of fire will flow from your location, igniting anything in its path. Additionally, tap sneak to engulf the area around you in roaring flames."); config.addDefault("Abilities.Fire.Blaze.DeathMessage", "{victim} was burned alive by {attacker}'s {ability}"); config.addDefault("Abilities.Fire.Combustion.Description", "Combustion is a powerful ability only known by a few skilled Firebenders. It allows the bender to Firebend with their mind, concentrating energy to create a powerful blast. To use, simply tap sneak (Default: Shift) to launch the blast. This technique is highly destructive and very effective, it also comes with a long cooldown."); @@ -316,7 +316,7 @@ public class ConfigManager { config.addDefault("Abilities.Fire.Combo.FireWheel.Description", "A high-speed wheel of fire that travels along the ground for long distances dealing high damage."); config.addDefault("Abilities.Fire.Combo.FireWheel.DeathMessage", "{victim} was incinerated by {attacker}'s {ability}"); - config.addDefault("Commands.Help.Elements.Chi", "Chiblockers focus on bare handed combat, utilizing their agility and speed to stop any bender right in their path. Although they lack the ability to bend any of the other elements, they are great in combat, and a serious threat to any bender. Chiblocking was first shown to be used by Ty Lee in Avatar: The Last Airbender, then later by members of the Equalists in The Legend of Korra.\nChiblockers can chain their abilities into combos, type /b help ChiCombos for more information."); + config.addDefault("Abilities.Chi.Description", "Chiblockers focus on bare handed combat, utilizing their agility and speed to stop any bender right in their path. Although they lack the ability to bend any of the other elements, they are great in combat, and a serious threat to any bender. Chiblocking was first shown to be used by Ty Lee in Avatar: The Last Airbender, then later by members of the Equalists in The Legend of Korra.\nChiblockers can chain their abilities into combos, type /b help ChiCombos for more information."); config.addDefault("Abilities.Chi.AcrobatStance.Description", "AcrobatStance gives a Chiblocker a higher probability of blocking a Bender's Chi while granting them a Speed and Jump Boost. It also increases the rate at which the hunger bar depletes. To use, simply left click. Left clicking again will de-activate the stance."); config.addDefault("Abilities.Chi.HighJump.Description", "To use this ability, simply click. You will jump quite high. This ability has a short cooldown."); config.addDefault("Abilities.Chi.Paralyze.Description", "Paralyzes the target, making them unable to do anything for a short " + "period of time. This ability has a long cooldown."); @@ -601,7 +601,7 @@ public class ConfigManager { config.addDefault("Abilities.Water.Bloodbending.ThrowFactor", 2); config.addDefault("Abilities.Water.Bloodbending.Range", 10); config.addDefault("Abilities.Water.Bloodbending.HoldTime", 0); - config.addDefault("Abilities.Water.Bloodbending.Cooldown", 0); + config.addDefault("Abilities.Water.Bloodbending.Cooldown", 3000); config.addDefault("Abilities.Water.Bloodbending.CanOnlyBeUsedDuringFullMoon", true); config.addDefault("Abilities.Water.Bloodbending.CanBloodbendOtherBloodbenders", false); diff --git a/src/com/projectkorra/projectkorra/earthbending/LavaFlow.java b/src/com/projectkorra/projectkorra/earthbending/LavaFlow.java index 02a63ce9..61f72fd9 100644 --- a/src/com/projectkorra/projectkorra/earthbending/LavaFlow.java +++ b/src/com/projectkorra/projectkorra/earthbending/LavaFlow.java @@ -30,7 +30,8 @@ public class LavaFlow extends LavaAbility { private static final Map TEMP_LAVA_BLOCKS = new ConcurrentHashMap<>(); private static final Map TEMP_LAND_BLOCKS = new ConcurrentHashMap<>(); - + private static final Map TEMP_AIR_BLOCKS = new ConcurrentHashMap<>(); + private boolean removing; private boolean makeLava; private boolean clickIsFinished; @@ -231,17 +232,14 @@ public class LavaFlow extends LavaAbility { Block lower = block.getRelative(BlockFace.DOWN); if (isPlant(lower)) { Block lower2 = lower.getRelative(BlockFace.DOWN); - if (!isEarth(lower2) && !isSand(lower2) && !isMetal(lower2)) { + if (!(isEarth(lower2) || isSand(lower2) || isMetal(lower2))) { continue; } - block.breakNaturally(); - lower.breakNaturally(); createLava(lower2); } else { - if (!isEarth(lower) && !isSand(lower) && !isMetal(lower)) { + if (!(isEarth(lower) || isSand(lower) || isMetal(lower))) { continue; } - block.breakNaturally(); createLava(lower); } } else { @@ -342,13 +340,11 @@ public class LavaFlow extends LavaAbility { continue; } tempBlock.breakNaturally(); - lower.breakNaturally(); createLava(lower2); } else { if (!isEarth(lower) && !isSand(lower) && !isMetal(lower)) { continue; } - tempBlock.breakNaturally(); createLava(lower); } } else { @@ -388,6 +384,22 @@ public class LavaFlow extends LavaAbility { */ public void createLava(Block block) { if (isEarth(block) || isSand(block) || isMetal(block)) { + if (isPlant(block.getRelative(BlockFace.UP))) { + Block above = block.getRelative(BlockFace.UP); + Block above2 = above.getRelative(BlockFace.UP); + if (isPlant(above2) && above2.getType() == Material.DOUBLE_PLANT) { + TempBlock tb = new TempBlock(above, Material.AIR, (byte) 0); + TEMP_AIR_BLOCKS.put(above, tb); + affectedBlocks.add(tb); + TempBlock tb2 = new TempBlock(above2, Material.AIR, (byte) 0); + TEMP_AIR_BLOCKS.put(above2, tb2); + affectedBlocks.add(tb2); + } else if (!isPlant(above2)) { + TempBlock tb = new TempBlock(above, Material.AIR, (byte) 0); + TEMP_AIR_BLOCKS.put(above, tb); + affectedBlocks.add(tb); + } else return; + } TempBlock tblock = new TempBlock(block, Material.STATIONARY_LAVA, (byte) 0); TEMP_LAVA_BLOCKS.put(block, tblock); affectedBlocks.add(tblock); @@ -461,6 +473,10 @@ public class LavaFlow extends LavaAbility { affectedBlocks.remove(tblock); TEMP_LAND_BLOCKS.remove(tblock); } + if (TEMP_AIR_BLOCKS.values().contains(tblock)) { + affectedBlocks.remove(tblock); + TEMP_AIR_BLOCKS.remove(tblock); + } } for (BukkitRunnable task : tasks) { diff --git a/src/com/projectkorra/projectkorra/waterbending/Bloodbending.java b/src/com/projectkorra/projectkorra/waterbending/Bloodbending.java index 6990febc..3d9a2474 100644 --- a/src/com/projectkorra/projectkorra/waterbending/Bloodbending.java +++ b/src/com/projectkorra/projectkorra/waterbending/Bloodbending.java @@ -25,8 +25,8 @@ import com.projectkorra.projectkorra.util.TempPotionEffect; public class Bloodbending extends BloodAbility { - private static final Map TARGETED_ENTITIES = new ConcurrentHashMap(); - + private static final Map TARGETED_ENTITIES = new ConcurrentHashMap(); + private boolean canOnlyBeUsedAtNight; private boolean canBeUsedOnUndeadMobs; private boolean onlyUsableDuringMoon; @@ -82,7 +82,7 @@ public class Bloodbending extends BloodAbility { } DamageHandler.damageEntity(entity, 0, this); AirAbility.breakBreathbendingHold(entity); - TARGETED_ENTITIES.put(entity, entity.getLocation().clone()); + TARGETED_ENTITIES.put(entity, player); } } } else { @@ -94,6 +94,11 @@ public class Bloodbending extends BloodAbility { entities = GeneralMethods.getEntitiesAroundPoint(location, 1.7); if (entities.contains(player)) entities.remove(player); + for (Entity e : entities) { + if (!(e instanceof LivingEntity)) { + entities.remove(e); + } + } if (entities != null && !entities.isEmpty() && !entities.contains(player)) { break; } @@ -123,11 +128,7 @@ public class Bloodbending extends BloodAbility { DamageHandler.damageEntity(target, 0, this); HorizontalVelocityTracker.remove(target); AirAbility.breakBreathbendingHold(target); - TARGETED_ENTITIES.put(target, target.getLocation().clone()); - } - - if (TARGETED_ENTITIES.size() > 0) { - bPlayer.addCooldown(this); + TARGETED_ENTITIES.put(target, player); } this.time = System.currentTimeMillis(); @@ -151,6 +152,7 @@ public class Bloodbending extends BloodAbility { new HorizontalVelocityTracker(entity, player, 200, this); } remove(); + bPlayer.addCooldown(this); } @Override @@ -158,12 +160,10 @@ public class Bloodbending extends BloodAbility { PotionEffect effect = new PotionEffect(PotionEffectType.SLOW, 60, 1); if (!player.isSneaking()) { - TARGETED_ENTITIES.remove(target); remove(); return; } else if (holdTime > 0 && System.currentTimeMillis() - this.time > holdTime) { remove(); - TARGETED_ENTITIES.remove(target); return; } @@ -176,25 +176,24 @@ public class Bloodbending extends BloodAbility { } if (onlyUsableDuringMoon && !isFullMoon(player.getWorld()) && !bPlayer.canBloodbendAtAnytime()) { - TARGETED_ENTITIES.remove(target); remove(); return; } else if (canOnlyBeUsedAtNight && !isNight(player.getWorld()) && !bPlayer.canBloodbendAtAnytime()) { - TARGETED_ENTITIES.remove(target); remove(); return; } else if (!bPlayer.canBendIgnoreCooldowns(this)) { - TARGETED_ENTITIES.remove(target); remove(); return; } - if (bPlayer.isAvatarState()) { + if (bPlayer.isAvatarState()) { ArrayList entities = new ArrayList<>(); for (Entity entity : GeneralMethods.getEntitiesAroundPoint(player.getLocation(), range)) { if (GeneralMethods.isRegionProtectedFromBuild(this, entity.getLocation())) { continue; + } else if (!(entity instanceof LivingEntity)) { + continue; } else if (entity instanceof Player) { BendingPlayer targetBPlayer = BendingPlayer.getBendingPlayer((Player) entity); if (targetBPlayer != null) { @@ -207,30 +206,16 @@ public class Bloodbending extends BloodAbility { entities.add(entity); if (!TARGETED_ENTITIES.containsKey(entity) && entity instanceof LivingEntity) { DamageHandler.damageEntity(entity, 0, this); - TARGETED_ENTITIES.put(entity, entity.getLocation().clone()); + TARGETED_ENTITIES.put(entity, player); } + + if (player.getWorld() != entity.getLocation().getWorld()) { + TARGETED_ENTITIES.remove(entity); + continue; + } if (entity instanceof LivingEntity) { - Location newLocation = entity.getLocation(); - if (player.getWorld() != newLocation.getWorld()) { - TARGETED_ENTITIES.remove(entity); - continue; - } - - Location location = TARGETED_ENTITIES.get(entity); - double distance = location.distance(newLocation); - double dx, dy, dz; - dx = location.getX() - newLocation.getX(); - dy = location.getY() - newLocation.getY(); - dz = location.getZ() - newLocation.getZ(); - Vector vector = new Vector(dx, dy, dz); - - if (distance > .5) { - entity.setVelocity(vector.normalize().multiply(.5)); - } else { - entity.setVelocity(new Vector(0, 0, 0)); - } - + entity.setVelocity(new Vector(0, 0, 0)); new TempPotionEffect((LivingEntity) entity, effect); entity.setFallDistance(0); if (entity instanceof Creature) { @@ -241,11 +226,15 @@ public class Bloodbending extends BloodAbility { } for (Entity entity : TARGETED_ENTITIES.keySet()) { - if (!entities.contains(entity)) { + if (!entities.contains(entity) && TARGETED_ENTITIES.get(entity) == player) { TARGETED_ENTITIES.remove(entity); } } } else { + if (TARGETED_ENTITIES.get(target) != player) { + remove(); + return; + } for (Entity entity : TARGETED_ENTITIES.keySet()) { if (entity instanceof Player) { BendingPlayer targetBPlayer = BendingPlayer.getBendingPlayer((Player) entity); @@ -260,29 +249,45 @@ public class Bloodbending extends BloodAbility { TARGETED_ENTITIES.remove(entity); continue; } + } + + Location location = GeneralMethods.getTargetedLocation(player, 6, getTransparentMaterial()); + double distance = location.distance(target.getLocation()); + double dx, dy, dz; + dx = location.getX() - target.getLocation().getX(); + dy = location.getY() - target.getLocation().getY(); + dz = location.getZ() - target.getLocation().getZ(); + Vector vector = new Vector(dx, dy, dz); - Location location = GeneralMethods.getTargetedLocation(player, 6, getTransparentMaterial()); - double distance = location.distance(newLocation); - double dx, dy, dz; - dx = location.getX() - newLocation.getX(); - dy = location.getY() - newLocation.getY(); - dz = location.getZ() - newLocation.getZ(); - Vector vector = new Vector(dx, dy, dz); + if (distance > .5) { + target.setVelocity(vector.normalize().multiply(.5)); + } else { + target.setVelocity(new Vector(0, 0, 0)); + } - if (distance > .5) { - entity.setVelocity(vector.normalize().multiply(.5)); - } else { - entity.setVelocity(new Vector(0, 0, 0)); - } - - new TempPotionEffect((LivingEntity) entity, effect); - entity.setFallDistance(0); - if (entity instanceof Creature) { - ((Creature) entity).setTarget(null); - } - AirAbility.breakBreathbendingHold(entity); + new TempPotionEffect((LivingEntity) target, effect); + target.setFallDistance(0); + if (target instanceof Creature) { + ((Creature) target).setTarget(null); + } + AirAbility.breakBreathbendingHold(target); + } + } + + @Override + public void remove() { + if (!bPlayer.isAvatarState() && target != null) { + if (System.currentTimeMillis() < this.startTime + 1200) { + bPlayer.addCooldown(this); //Prevents spamming } } + for (Entity e : TARGETED_ENTITIES.keySet()) { + if (TARGETED_ENTITIES.get(e) == player) { + TARGETED_ENTITIES.remove(e); + } + } + + super.remove(); } public static boolean isBloodbent(Entity entity) { @@ -290,7 +295,7 @@ public class Bloodbending extends BloodAbility { } public static Location getBloodbendingLocation(Entity entity) { - return entity != null ? TARGETED_ENTITIES.get(entity) : null; + return entity != null ? TARGETED_ENTITIES.get(entity).getLocation() : null; } @Override diff --git a/src/com/projectkorra/projectkorra/waterbending/PlantRegrowth.java b/src/com/projectkorra/projectkorra/waterbending/PlantRegrowth.java index 22933f7e..4ed428f8 100644 --- a/src/com/projectkorra/projectkorra/waterbending/PlantRegrowth.java +++ b/src/com/projectkorra/projectkorra/waterbending/PlantRegrowth.java @@ -6,6 +6,7 @@ import com.projectkorra.projectkorra.ability.PlantAbility; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; import org.bukkit.entity.Player; public class PlantRegrowth extends PlantAbility { @@ -25,6 +26,12 @@ public class PlantRegrowth extends PlantAbility { this.block = block; this.type = block.getType(); this.data = block.getData(); + + if (block.getType() == Material.DOUBLE_PLANT && block.getRelative(BlockFace.DOWN).getType() == Material.DOUBLE_PLANT) { + this.block = block.getRelative(BlockFace.DOWN); + this.data = (byte) (block.getData() - 8); + } + time = System.currentTimeMillis() + regrowTime / 2 + (long) (Math.random() * (double) regrowTime) / 2; start(); } @@ -37,6 +44,11 @@ public class PlantRegrowth extends PlantAbility { if (block.getType() == Material.AIR) { block.setType(type); block.setData(data); + if (type == Material.DOUBLE_PLANT) { + block.getRelative(BlockFace.UP).setType(Material.DOUBLE_PLANT); + block.getRelative(BlockFace.UP).setData((byte) (data + 8)); + } + } else { GeneralMethods.dropItems(block, GeneralMethods.getDrops(block, type, data, null)); }