From edada84fa2c45082a831b12eba1ae20e50dae20d Mon Sep 17 00:00:00 2001 From: MistPhizzle Date: Thu, 26 Jun 2014 22:15:28 -0400 Subject: [PATCH] EarthArmor --- .../ProjectKorra/BendingManager.java | 4 + .../ProjectKorra/ConfigManager.java | 7 + .../projectkorra/ProjectKorra/Methods.java | 8 + .../projectkorra/ProjectKorra/PKListener.java | 58 +++- .../ProjectKorra/earthbending/EarthArmor.java | 275 ++++++++++++++++++ src/config.yml | 7 + 6 files changed, 354 insertions(+), 5 deletions(-) create mode 100644 src/com/projectkorra/ProjectKorra/earthbending/EarthArmor.java diff --git a/src/com/projectkorra/ProjectKorra/BendingManager.java b/src/com/projectkorra/ProjectKorra/BendingManager.java index acf8daec..2e10a15e 100644 --- a/src/com/projectkorra/ProjectKorra/BendingManager.java +++ b/src/com/projectkorra/ProjectKorra/BendingManager.java @@ -25,6 +25,7 @@ import com.projectkorra.ProjectKorra.airbending.Tornado; import com.projectkorra.ProjectKorra.chiblocking.ChiPassive; import com.projectkorra.ProjectKorra.earthbending.Catapult; import com.projectkorra.ProjectKorra.earthbending.CompactColumn; +import com.projectkorra.ProjectKorra.earthbending.EarthArmor; import com.projectkorra.ProjectKorra.earthbending.EarthBlast; import com.projectkorra.ProjectKorra.earthbending.EarthColumn; import com.projectkorra.ProjectKorra.earthbending.EarthPassive; @@ -105,6 +106,9 @@ public class BendingManager implements Runnable { AirSuction.progressAll(); Fireball.progressAll(); HealingWaters.heal(Bukkit.getServer()); + for (Player player : EarthArmor.instances.keySet()) { + EarthArmor.moveArmor(player); + } for (int ID: AirSwipe.instances.keySet()) { AirSwipe.progress(ID); } diff --git a/src/com/projectkorra/ProjectKorra/ConfigManager.java b/src/com/projectkorra/ProjectKorra/ConfigManager.java index 4663311a..a5c5d7a1 100644 --- a/src/com/projectkorra/ProjectKorra/ConfigManager.java +++ b/src/com/projectkorra/ProjectKorra/ConfigManager.java @@ -41,6 +41,7 @@ public class ConfigManager { plugin.getConfig().addDefault("Properties.Water.CanBendWithWeapons", true); plugin.getConfig().addDefault("Properties.Water.NightFactor", 1.5); + config.addDefault("Properties.Earth.RevertEarthbending", true); plugin.getConfig().addDefault("Properties.Earth.CanBendWithWeapons", true); plugin.getConfig().addDefault("Properties.Earth.EarthbendableBlocks", earthbendable); @@ -250,6 +251,12 @@ public class ConfigManager { config.addDefault("Abilities.Earth.Collapse.Radius", 7); config.addDefault("Abilities.Earth.Collapse.Speed", 8); + config.addDefault("Abilities.Earth.EarthArmor.Enabled", true); + config.addDefault("Abilities.Earth.EarthArmor.Description", "This ability encases the earthbender in temporary armor. To use, click on a block that is earthbendable. If there is another block under it that is earthbendable, the block will fly to you and grant you temporary armor and damage reduction. This ability has a long cooldown."); + config.addDefault("Abilities.Earth.EarthArmor.Duration", 10000); + config.addDefault("Abilities.Earth.EarthArmor.Strength", 2); + config.addDefault("Abilities.Earth.EarthArmor.Duration", 17500); + config.addDefault("Abilities.Earth.EarthBlast.Enabled", true); config.addDefault("Abilities.Earth.EarthBlast.Description", "To use, place your cursor over an earthbendable object (dirt, rock, ores, etc) " + "and tap sneak (default: shift). The object will temporarily turn to stone, " diff --git a/src/com/projectkorra/ProjectKorra/Methods.java b/src/com/projectkorra/ProjectKorra/Methods.java index 69bc2a47..23408e7e 100644 --- a/src/com/projectkorra/ProjectKorra/Methods.java +++ b/src/com/projectkorra/ProjectKorra/Methods.java @@ -589,6 +589,14 @@ public class Methods { return adjacent; } + public static void removeBlock(Block block) { + if (isAdjacentToThreeOrMoreSources(block)) { + block.setType(Material.WATER); + block.setData((byte) 0x0); + } else { + block.setType(Material.AIR); + } + } public static void playFocusWaterEffect(Block block) { diff --git a/src/com/projectkorra/ProjectKorra/PKListener.java b/src/com/projectkorra/ProjectKorra/PKListener.java index 01c23ed1..ee6e727b 100644 --- a/src/com/projectkorra/ProjectKorra/PKListener.java +++ b/src/com/projectkorra/ProjectKorra/PKListener.java @@ -1,5 +1,6 @@ package com.projectkorra.ProjectKorra; +import java.util.ArrayList; import java.util.List; import org.bukkit.ChatColor; @@ -30,8 +31,11 @@ import org.bukkit.event.entity.EntityShootBowEvent; import org.bukkit.event.entity.EntityTargetEvent; import org.bukkit.event.entity.EntityTargetLivingEntityEvent; import org.bukkit.event.entity.EntityTeleportEvent; +import org.bukkit.event.entity.PlayerDeathEvent; import org.bukkit.event.entity.ProjectileLaunchEvent; import org.bukkit.event.entity.SlimeSplitEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryType.SlotType; import org.bukkit.event.player.PlayerAnimationEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerJoinEvent; @@ -39,6 +43,8 @@ import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerToggleFlightEvent; import org.bukkit.event.player.PlayerToggleSneakEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffectType; import org.bukkit.util.Vector; import org.kitteh.tag.AsyncPlayerReceiveNameTagEvent; @@ -57,6 +63,7 @@ import com.projectkorra.ProjectKorra.chiblocking.Paralyze; import com.projectkorra.ProjectKorra.earthbending.Catapult; import com.projectkorra.ProjectKorra.earthbending.Collapse; import com.projectkorra.ProjectKorra.earthbending.CompactColumn; +import com.projectkorra.ProjectKorra.earthbending.EarthArmor; import com.projectkorra.ProjectKorra.earthbending.EarthBlast; import com.projectkorra.ProjectKorra.earthbending.EarthColumn; import com.projectkorra.ProjectKorra.earthbending.EarthPassive; @@ -146,9 +153,14 @@ public class PKListener implements Listener { } @EventHandler - public void onPlayerQuit(PlayerQuitEvent e) { - Methods.saveBendingPlayer(e.getPlayer().getName()); - BendingPlayer.players.remove(e.getPlayer().getName()); + public void onPlayerQuit(PlayerQuitEvent event) { + Methods.saveBendingPlayer(event.getPlayer().getName()); + BendingPlayer.players.remove(event.getPlayer().getName()); + if (EarthArmor.instances.containsKey(event.getPlayer())) { + EarthArmor.removeEffect(event.getPlayer()); + event.getPlayer().removePotionEffect( + PotionEffectType.DAMAGE_RESISTANCE); + } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) @@ -167,11 +179,11 @@ public class PKListener implements Listener { } if (!player.isSneaking() && Methods.canBend(player.getName(), abil)) { - + if (abil.equalsIgnoreCase("AirShield")) { new AirShield(player); } - + if (Methods.isAirAbility(abil)) { if (Methods.isWeapon(player.getItemInHand().getType()) && !plugin.getConfig().getBoolean("Properties.Air.CanBendWithWeapons")) { return; @@ -486,6 +498,9 @@ public class PKListener implements Listener { if (abil.equalsIgnoreCase("Shockwave")) { Shockwave.coneShockwave(player); } + if (abil.equalsIgnoreCase("EarthArmor")) { + new EarthArmor(player); + } } if (Methods.isFireAbility(abil)) { if (Methods.isWeapon(player.getItemInHand().getType()) && !plugin.getConfig().getBoolean("Properties.Fire.CanBendWithWeapons")) { @@ -507,6 +522,39 @@ public class PKListener implements Listener { } } } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onInventoryClick(InventoryClickEvent event) { + if (event.getSlotType() == SlotType.ARMOR + && !EarthArmor.canRemoveArmor((Player) event.getWhoClicked())) + event.setCancelled(true); + } + + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onPlayerDeath(PlayerDeathEvent event) { + if (EarthArmor.instances.containsKey(event.getEntity())) { + List drops = event.getDrops(); + List newdrops = new ArrayList(); + for (int i = 0; i < drops.size(); i++) { + if (!(drops.get(i).getType() == Material.LEATHER_BOOTS + || drops.get(i).getType() == Material.LEATHER_CHESTPLATE + || drops.get(i).getType() == Material.LEATHER_HELMET + || drops.get(i).getType() == Material.LEATHER_LEGGINGS || drops + .get(i).getType() == Material.AIR)) + newdrops.add((drops.get(i))); + } + if (EarthArmor.instances.get(event.getEntity()).oldarmor != null) { + for (ItemStack is : EarthArmor.instances.get(event.getEntity()).oldarmor) { + if (!(is.getType() == Material.AIR)) + newdrops.add(is); + } + } + event.getDrops().clear(); + event.getDrops().addAll(newdrops); + EarthArmor.removeEffect(event.getEntity()); + } + } + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onPlayerToggleFlight(PlayerToggleFlightEvent event) { Player p = event.getPlayer(); diff --git a/src/com/projectkorra/ProjectKorra/earthbending/EarthArmor.java b/src/com/projectkorra/ProjectKorra/earthbending/EarthArmor.java new file mode 100644 index 00000000..57fd1734 --- /dev/null +++ b/src/com/projectkorra/ProjectKorra/earthbending/EarthArmor.java @@ -0,0 +1,275 @@ +package com.projectkorra.ProjectKorra.earthbending; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.util.Vector; + +import com.projectkorra.ProjectKorra.Methods; +import com.projectkorra.ProjectKorra.ProjectKorra; +import com.projectkorra.ProjectKorra.TempBlock; +import com.projectkorra.ProjectKorra.TempPotionEffect; + +public class EarthArmor { + + private static long duration = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.EarthArmor.Duration"); + private static int strength = ProjectKorra.plugin.getConfig().getInt("Abilities.Earth.EarthArmor.Strength"); + private static long cooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Earth.EarthArmor.Cooldown"); + private static int range = 7; + + private Player player; + private Block headblock, legsblock; + private Location headblocklocation, legsblocklocation; + private Material headtype, legstype; + private byte headdata, legsdata; + private long time, starttime; + private boolean formed = false; + private boolean complete = false; + public ItemStack[] oldarmor; + + private static long interval = 2000; + public static ConcurrentHashMap instances = new ConcurrentHashMap(); + public static Map cooldowns = new ConcurrentHashMap(); + + public EarthArmor(Player player) { + if (instances.containsKey(player)) { + return; + } + + if (cooldowns.containsKey(player.getName())) { + if (cooldowns.get(player.getName()) + cooldown >= System.currentTimeMillis()) { + return; + } else { + cooldowns.remove(player.getName()); + } + } + + this.player = player; + headblock = player.getTargetBlock(Methods.getTransparentEarthbending(), + range); + if (Methods.getEarthbendableBlocksLength(player, headblock, new Vector(0, + -1, 0), 2) >= 2) { + legsblock = headblock.getRelative(BlockFace.DOWN); + headtype = headblock.getType(); + legstype = legsblock.getType(); + headdata = headblock.getData(); + legsdata = legsblock.getData(); + headblocklocation = headblock.getLocation(); + legsblocklocation = legsblock.getLocation(); + Block oldheadblock, oldlegsblock; + oldheadblock = headblock; + oldlegsblock = legsblock; + if (!moveBlocks()) + return; + if (ProjectKorra.plugin.getConfig().getBoolean("Properties.Earth.RevertEarthbending")) { + Methods.addTempAirBlock(oldheadblock); + Methods.addTempAirBlock(oldlegsblock); + } else { + Methods.removeBlock(oldheadblock); + Methods.removeBlock(oldlegsblock); + } + instances.put(player, this); + } + } + + private boolean moveBlocks() { + if (player.getWorld() != headblock.getWorld()) { + cancel(); + return false; + } + + Location headlocation = player.getEyeLocation(); + Location legslocation = player.getLocation(); + Vector headdirection = headlocation.toVector() + .subtract(headblocklocation.toVector()).normalize() + .multiply(.5); + Vector legsdirection = legslocation.toVector() + .subtract(legsblocklocation.toVector()).normalize() + .multiply(.5); + + Block newheadblock = headblock; + Block newlegsblock = legsblock; + + if (!headlocation.getBlock().equals(headblock)) { + headblocklocation = headblocklocation.clone().add(headdirection); + newheadblock = headblocklocation.getBlock(); + } + if (!legslocation.getBlock().equals(legsblock)) { + legsblocklocation = legsblocklocation.clone().add(legsdirection); + newlegsblock = legsblocklocation.getBlock(); + } + + if (Methods.isTransparentToEarthbending(player, newheadblock) + && !newheadblock.isLiquid()) { + Methods.breakBlock(newheadblock); + } else if (!Methods.isEarthbendable(player, newheadblock) + && !newheadblock.isLiquid() + && newheadblock.getType() != Material.AIR) { + cancel(); + return false; + } + + if (Methods.isTransparentToEarthbending(player, newlegsblock) + && !newlegsblock.isLiquid()) { + Methods.breakBlock(newlegsblock); + } else if (!Methods.isEarthbendable(player, newlegsblock) + && !newlegsblock.isLiquid() + && newlegsblock.getType() != Material.AIR) { + cancel(); + return false; + } + + // if ((!Methods.isEarthbendable(player, newlegsblock) + // && !newlegsblock.isLiquid() && newlegsblock.getType() != + // Material.AIR) + // || (!Methods.isEarthbendable(player, newheadblock) + // && !newheadblock.isLiquid() && newheadblock.getType() != + // Material.AIR)) { + // cancel(); + // return false; + // } + + if (headblock.getLocation().distance(player.getEyeLocation()) > range + || legsblock.getLocation().distance(player.getLocation()) > range) { + cancel(); + return false; + } + + if (!newheadblock.equals(headblock)) { + new TempBlock(newheadblock, headtype, headdata); + if (TempBlock.isTempBlock(headblock)) + TempBlock.revertBlock(headblock, Material.AIR); + } + + if (!newlegsblock.equals(legsblock)) { + new TempBlock(newlegsblock, legstype, legsdata); + if (TempBlock.isTempBlock(legsblock)) + TempBlock.revertBlock(legsblock, Material.AIR); + } + + headblock = newheadblock; + legsblock = newlegsblock; + + return true; + } + + private void cancel() { + if (ProjectKorra.plugin.getConfig().getBoolean("Properties.Earth.RevertEarthbending")) { + if (TempBlock.isTempBlock(headblock)) + TempBlock.revertBlock(headblock, Material.AIR); + if (TempBlock.isTempBlock(legsblock)) + TempBlock.revertBlock(legsblock, Material.AIR); + } else { + headblock.breakNaturally(); + legsblock.breakNaturally(); + } + if (instances.containsKey(player)) + instances.remove(player); + } + + private boolean inPosition() { + if (headblock.equals(player.getEyeLocation().getBlock()) + && legsblock.equals(player.getLocation().getBlock())) { + return true; + } + return false; + } + + private void formArmor() { + if (TempBlock.isTempBlock(headblock)) + TempBlock.revertBlock(headblock, Material.AIR); + if (TempBlock.isTempBlock(legsblock)) + TempBlock.revertBlock(legsblock, Material.AIR); + + oldarmor = player.getInventory().getArmorContents(); + ItemStack armors[] = { new ItemStack(Material.LEATHER_BOOTS, 1), + new ItemStack(Material.LEATHER_LEGGINGS, 1), + new ItemStack(Material.LEATHER_CHESTPLATE, 1), + new ItemStack(Material.LEATHER_HELMET, 1) }; + player.getInventory().setArmorContents(armors); + PotionEffect resistance = new PotionEffect( + PotionEffectType.DAMAGE_RESISTANCE, (int) duration / 50, + strength - 1); + new TempPotionEffect(player, resistance); + // player.addPotionEffect(new PotionEffect( + // PotionEffectType.DAMAGE_RESISTANCE, (int) duration / 50, + // strength - 1)); + formed = true; + starttime = System.currentTimeMillis(); + } + + public static void moveArmor(Player player) { + if (!instances.containsKey(player)) + return; + EarthArmor eartharmor = instances.get(player); + + if (player.isDead() || !player.isOnline()) { + eartharmor.cancel(); + eartharmor.removeEffect(); + return; + } + + if (eartharmor.formed) { + if (System.currentTimeMillis() > eartharmor.starttime + duration + && !eartharmor.complete) { + eartharmor.complete = true; + eartharmor.removeEffect(); + return; + } + if (System.currentTimeMillis() > eartharmor.starttime + cooldown) { + instances.remove(player); + return; + } + } else if (System.currentTimeMillis() > eartharmor.time + interval) { + if (!eartharmor.moveBlocks()) + return; + + if (eartharmor.inPosition()) { + eartharmor.formArmor(); + } + } + + } + + private void removeEffect() { + player.getInventory().setArmorContents(oldarmor); + // player.removePotionEffect(PotionEffectType.DAMAGE_RESISTANCE); + // instances.remove(player); + } + + public static void removeEffect(Player player) { + if (!instances.containsKey(player)) + return; + instances.get(player).removeEffect(); + } + + public static void removeAll() { + for (Player player : instances.keySet()) { + EarthArmor eartharmor = instances.get(player); + eartharmor.cancel(); + eartharmor.removeEffect(); + } + } + + public static String getDescription() { + return "This ability encases the earthbender in temporary armor. To use, click on a block that is earthbendable. If there is another block under" + + " it that is earthbendable, the block will fly to you and grant you temporary armor and damage reduction. This ability has a long cooldown."; + } + + public static boolean canRemoveArmor(Player player) { + if (instances.containsKey(player)) { + EarthArmor eartharmor = instances.get(player); + if (System.currentTimeMillis() < eartharmor.starttime + duration) + return false; + } + return true; + } +} \ No newline at end of file diff --git a/src/config.yml b/src/config.yml index 44431089..f45e733f 100644 --- a/src/config.yml +++ b/src/config.yml @@ -15,6 +15,7 @@ Properties: CanBendWithWeapons: false NightFactor: 1.5 Earth: + RevertEarthbending: true CanBendWithWeapons: true EarthbendableBlocks: - STONE @@ -168,6 +169,12 @@ Abilities: Range: 20 Radius: 7 Speed: 8 + EarthArmor: + Enabled: true + Description: "This ability encases the earthbender in temporary armor. To use, click on a block that is earthbendable. If there is another block under it that is earthbendable, the block will fly to you and grant you temporary armor and damage reduction. This ability has a long cooldown." + Duration: 10000 + Strength: 2 + Cooldown: 17500 EarthBlast: Enabled: true Description: "To use, place your cursor over an earthbendable object and tap sneak (default: shift). The object will temporarily turn to stone, indicating that you have it focused as the source for your ability. After you have selected an origin (you no longer need to be sneaking), simply left-click in any direction and you will see your object launch off in that direction, smashing into any creature in its path. If you look towards a creature when you use this ability, it will target that creature. A collision from Earth Blast both knocks the target back and deals some damage. You cannot have multiple of these abilities flying at the same time."