From 09575f8e9b4eae95dd8ef00337fe39ec2ad1d092 Mon Sep 17 00:00:00 2001 From: jedk1 Date: Sun, 31 May 2015 15:19:50 +0100 Subject: [PATCH] Started Recode on WaterArms. --- .../ProjectKorra/waterbending/WaterArms.java | 556 ++++++++++++++++++ .../waterbending/WaterArmsWhip.java | 432 ++++++++++++++ 2 files changed, 988 insertions(+) create mode 100644 src/com/projectkorra/ProjectKorra/waterbending/WaterArms.java create mode 100644 src/com/projectkorra/ProjectKorra/waterbending/WaterArmsWhip.java diff --git a/src/com/projectkorra/ProjectKorra/waterbending/WaterArms.java b/src/com/projectkorra/ProjectKorra/waterbending/WaterArms.java new file mode 100644 index 00000000..f7531abe --- /dev/null +++ b/src/com/projectkorra/ProjectKorra/waterbending/WaterArms.java @@ -0,0 +1,556 @@ +package com.projectkorra.ProjectKorra.waterbending; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Entity; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; + +import com.projectkorra.ProjectKorra.GeneralMethods; +import com.projectkorra.ProjectKorra.MultiAbilityManager; +import com.projectkorra.ProjectKorra.ProjectKorra; +import com.projectkorra.ProjectKorra.TempBlock; +import com.projectkorra.ProjectKorra.Utilities.ParticleEffect; +import com.projectkorra.ProjectKorra.earthbending.EarthMethods; +import com.projectkorra.ProjectKorra.firebending.FireMethods; +import com.projectkorra.ProjectKorra.firebending.Lightning; +import com.projectkorra.ProjectKorra.waterbending.WaterArmsWhip.Whip; + +public class WaterArms{ + + /** + * Arm Enum value for deciding which arm is being used. + */ + public enum Arm { + Right, Left; + } + + private static FileConfiguration config = ProjectKorra.plugin.getConfig(); + + public static ConcurrentHashMap instances = new ConcurrentHashMap(); + public static ConcurrentHashMap revert = new ConcurrentHashMap(); + public static ConcurrentHashMap falling = new ConcurrentHashMap(); + + private static Integer[] unbreakable = {7, 8, 9, 10, 11, 49, 54, 90, 119, 120, 130, 146}; + + private Player player; + private World world; + + private Arm activeArm = Arm.Right; + + private boolean cooldownLeft; + private boolean cooldownRight; + private boolean fullSource = true; + + private boolean leftArmConsumed = false; + private boolean rightArmConsumed = false; + + private int lengthReduction = 0; + + private int initLength = config.getInt("Abilities.Water.WaterArms.Arms.InitialLength"); + private int sourceGrabRange = config.getInt("Abilities.Water.WaterArms.Arms.SourceGrabRange"); + private int maxPunches = config.getInt("Abilities.Water.WaterArms.Arms.MaxAttacks"); + private int maxIceBlasts = config.getInt("Abilities.Water.WaterArms.Arms.MaxIceShots"); + private int maxUses = config.getInt("Abilities.Water.WaterArms.Arms.MaxAlternateUsage"); + private long cooldown = config.getLong("Abilities.Water.WaterArms.Arms.cooldown"); + private boolean canUsePlantSource = config.getBoolean("Abilities.Water.WaterArms.Arms.AllowPlantSource"); + + private boolean lightningEnabled = config.getBoolean("Abilities.Water.WaterArms.Arms.Lightning.Enabled"); + private double lightningDamage = config.getDouble("Abilities.Water.WaterArms.Arms.Lightning.Damage"); + private boolean lightningKill = config.getBoolean("Abilities.Water.WaterArms.Arms.Lightning.KillUser"); + + private static double blockDamage = config.getDouble("Abilities.Water.WaterArms.WhipMode.Pull.BlockDamage"); + private static boolean pullBlocksDamageUser = config.getBoolean("Abilities.Water.WaterArms.WhipMode.Pull.BlockDamageUser"); + + private int selectedSlot = 0; + private int freezeSlot = 4; + + private long lastClickTime; + + public WaterArms(Player player){ + if(instances.containsKey(player)){ + if(player.isSneaking()){ + instances.get(player).prepareCancel(); + }else{ + switch(player.getInventory().getHeldItemSlot()){ + case 0: + new WaterArmsWhip(player, Whip.Pull); + break; + case 1: + new WaterArmsWhip(player, Whip.Punch); + break; + case 2: + new WaterArmsWhip(player, Whip.Grapple); + break; + case 3: + new WaterArmsWhip(player, Whip.Grab); + break; + case 4: + //new WaterArmsIce(player); + break; + case 5: + //new WaterArmsSpear(player); + break; + default: + break; + } + } + return; + } + this.player = player; + if(canUse(player) && prepare()){ + world = player.getWorld(); + instances.put(player, this); + MultiAbilityManager.bindMultiAbility(player, "WaterArms"); + if(ChatColor.stripColor(GeneralMethods.getBoundAbility(player)) == null){ + remove(); + return; + } + } + } + + private boolean canUse(Player player){ + if(GeneralMethods.getBoundAbility(player) == null) + return false; + if(!GeneralMethods.canBend(player.getName(), "WaterArms")) + return false; + if(GeneralMethods.isRegionProtectedFromBuild(player, "WaterArms", player.getLocation())) + return false; + if(GeneralMethods.getBendingPlayer(player.getName()).isOnCooldown("WaterArms")) + return false; + if(GeneralMethods.getBoundAbility(player).equalsIgnoreCase("WaterArms")) + return true; + return false; + } + + private boolean prepare(){ + Block sourceblock = WaterMethods.getWaterSourceBlock(player, sourceGrabRange, canUsePlantSource); + if(sourceblock != null){ + if(WaterMethods.isPlant(sourceblock)){ + fullSource = false; + } + ParticleEffect.LARGE_SMOKE.display(WaterMethods.getWaterSourceBlock(player, sourceGrabRange, canUsePlantSource).getLocation().clone().add(0.5,0.5,0.5), 0, 0, 0, 0F, 4); + return true; + }else if(WaterReturn.hasWaterBottle(player)){ + WaterReturn.emptyWaterBottle(player); + fullSource = false; + return true; + } + return false; + } + + private void progress(){ + if (!instances.containsKey(player)){ + return; + } + if(player.isDead() || !player.isOnline() || world != player.getWorld()){ + remove(); + return; + } + if(!GeneralMethods.getBendingPlayer(player.getName()).isToggled()){ + remove(); + return; + } + if(!MultiAbilityManager.hasMultiAbilityBound(player, "WaterArms")){ + remove(); + return; + } + if(maxPunches == 0 || maxUses == 0 || maxIceBlasts == 0 || (leftArmConsumed && rightArmConsumed)){ + remove(); + return; + } + + selectedSlot = player.getInventory().getHeldItemSlot(); + displayRightArm(); + displayLeftArm(); + + if(lightningEnabled) + checkIfZapped(); + } + + private boolean canPlaceBlock(Block block){ + if(!EarthMethods.isTransparentToEarthbending(player, block) && !(WaterMethods.isWater(block) && TempBlock.isTempBlock(block))) + return false; + return true; + } + + /** + * Displays the right arm. + * Returns false if the arm cannot be fully displayed. + * @return + */ + public boolean displayRightArm(){ + if(rightArmConsumed) + return false; + + Location r1 = GeneralMethods.getRightSide(player.getLocation(), 1).add(0, 1.5, 0); + if(!canPlaceBlock(r1.getBlock())) + return false; + + if(!(getRightHandPos().getBlock().getLocation().equals(r1.getBlock().getLocation()))){ + new TempBlock(r1.getBlock(), Material.STATIONARY_WATER, (byte) 5); + revert.put(r1.getBlock(), 0L); + } + + Location r2 = GeneralMethods.getRightSide(player.getLocation(), 2).add(0, 1.5, 0); + if(!canPlaceBlock(r2.getBlock())) + return false; + + new TempBlock(r2.getBlock(), Material.STATIONARY_WATER, (byte) 0); + revert.put(r2.getBlock(), 0L); + + for(int j = 0; j <= initLength; j++){ + Location r3 = r2.clone().toVector().add(player.getLocation().clone().getDirection().multiply(j)).toLocation(player.getWorld()); + if(!canPlaceBlock(r3.getBlock())){ + if(selectedSlot == freezeSlot && r3.getBlock().getType().equals(Material.ICE)) + continue; + return false; + } + + if(j >= 1 && selectedSlot == freezeSlot){ + new TempBlock(r3.getBlock(), Material.ICE, (byte) 0); + revert.put(r3.getBlock(), 0L); + }else{ + new TempBlock(r3.getBlock(), Material.STATIONARY_WATER, (byte) 0); + revert.put(r3.getBlock(), 0L); + } + } + + return true; + } + + /** + * Displays the left arm. + * Returns false if the arm cannot be fully displayed. + * @return + */ + public boolean displayLeftArm(){ + if(leftArmConsumed) + return false; + + Location l1 = GeneralMethods.getLeftSide(player.getLocation(), 1).add(0, 1.5, 0); + if(!canPlaceBlock(l1.getBlock())) + return false; + + if(!(getLeftHandPos().getBlock().getLocation().equals(l1.getBlock().getLocation()))){ + new TempBlock(l1.getBlock(), Material.STATIONARY_WATER, (byte) 5); + revert.put(l1.getBlock(), 0L); + } + + Location l2 = GeneralMethods.getLeftSide(player.getLocation(), 2).add(0, 1.5, 0); + if(!canPlaceBlock(l2.getBlock())) + return false; + + new TempBlock(l2.getBlock(), Material.STATIONARY_WATER, (byte) 0); + revert.put(l2.getBlock(), 0L); + + for(int j = 0; j <= initLength; j++){ + Location l3 = l2.clone().toVector().add(player.getLocation().clone().getDirection().multiply(j)).toLocation(player.getWorld()); + if(!canPlaceBlock(l3.getBlock())){ + if(selectedSlot == freezeSlot && l3.getBlock().getType().equals(Material.ICE)) + continue; + return false; + } + + if(j >= 1 && selectedSlot == freezeSlot){ + new TempBlock(l3.getBlock(), Material.ICE, (byte) 0); + revert.put(l3.getBlock(), 0L); + }else{ + new TempBlock(l3.getBlock(), Material.STATIONARY_WATER, (byte) 0); + revert.put(l3.getBlock(), 0L); + } + } + + return true; + } + + /** + * Calculate roughly where the player's right hand is. + * @return + */ + private Location getRightHandPos(){ + return GeneralMethods.getRightSide(player.getLocation(), .34).add(0, 1.5, 0); + } + + /** + * Calculate roughly where the player's left hand is. + * @return + */ + private Location getLeftHandPos(){ + return GeneralMethods.getLeftSide(player.getLocation(), .34).add(0, 1.5, 0); + } + + /** + * Returns the location of the tip of the right arm, assuming it is fully extended. + * Use the displayRightArm() check to see if it is fully extended. + * @return + */ + public Location getRightArmEnd(){ + Location r1 = GeneralMethods.getRightSide(player.getLocation(), 2).add(0, 1.5, 0); + return r1.clone().add(player.getLocation().getDirection().normalize().multiply(initLength)); + } + + /** + * Returns the location of the tip of the left arm assuming it is fully extended. + * Use the displayLeftArm() check to see if it is fully extended. + * @return + */ + public Location getLeftArmEnd(){ + Location l1 = GeneralMethods.getLeftSide(player.getLocation(), 2).add(0, 1.5, 0); + return l1.clone().add(player.getLocation().getDirection().normalize().multiply(initLength)); + } + + private static void progressRevert(boolean ignoreTime){ + for(Block block : revert.keySet()){ + long time = revert.get(block); + if(System.currentTimeMillis() > time || ignoreTime){ + if(TempBlock.isTempBlock(block)) + TempBlock.revertBlock(block, Material.AIR); + revert.remove(block); + } + } + } + + private static void trackEntities(boolean remove){ + for(FallingBlock fallingBlock : falling.keySet()){ + if(remove){ + fallingBlock.remove(); + falling.remove(fallingBlock); + } + + if(!fallingBlock.isDead()){ + for(Entity entity : GeneralMethods.getEntitiesAroundPoint(fallingBlock.getLocation(), 2.0)){ + if(entity instanceof LivingEntity){ + if(!pullBlocksDamageUser && entity.getEntityId() == falling.get(fallingBlock).getEntityId()) + continue; + GeneralMethods.damageEntity(falling.get(fallingBlock), entity, blockDamage); + fallingBlock.remove(); + falling.remove(fallingBlock); + } + } + } + } + } + + private void checkIfZapped(){ + for (int i = 0; i < Lightning.instances.size(); i++){ + Lightning l = Lightning.instances.get(i); + for(Lightning.Arc arc : l.getArcs()){ + for(Block arm : revert.keySet()){ + for(Location loc : arc.getPoints()){ + if(arm.getLocation().getWorld() == loc.getWorld() && loc.distance(arm.getLocation()) <= 2.5){ + for(Location l1 : getOffsetLocations(4, arm.getLocation(), 1.25)) + FireMethods.playLightningbendingParticle(l1); + if(lightningKill) + GeneralMethods.damageEntity(Lightning.instances.get(i).getPlayer(), player, 60D); + else + GeneralMethods.damageEntity(Lightning.instances.get(i).getPlayer(), player, lightningDamage); + } + } + } + } + } + } + + private static List getOffsetLocations(int amount, Location location, double offset){ + List locations = new ArrayList(); + for(int i = 0; i < amount; i++) + locations.add(location.clone().add((float) (Math.random()*offset), (float) (Math.random()*offset), (float) (Math.random()*offset))); + return locations; + } + + public static void remove(Player player){ + if(instances.containsKey(player)) + instances.get(player).remove(); + } + + public void remove(){ + MultiAbilityManager.unbindMultiAbility(player); + if(player.isOnline()) + GeneralMethods.getBendingPlayer(player.getName()).addCooldown("WaterArms", cooldown); + instances.remove(player); + } + + public void prepareCancel(){ + if(System.currentTimeMillis() < lastClickTime + 500L){ + remove(); + }else{ + lastClickTime = System.currentTimeMillis(); + } + } + + public static void progressAll(){ + progressRevert(false); + trackEntities(false); + for(Player p : instances.keySet()) + instances.get(p).progress(); + WaterArmsWhip.progressAll(); + } + + public static void removeAll(){ + progressRevert(true); + trackEntities(true); + revert.clear(); + falling.clear(); + instances.clear(); + WaterArmsWhip.removeAll(); + } + + + @SuppressWarnings("deprecation") + public static boolean isUnbreakable(Block block) { + if (Arrays.asList(unbreakable).contains(block.getTypeId())) return true; + return false; + } + + /** + * Returns the active arm of the player. + * @return + */ + public Arm getActiveArm(){ + return activeArm; + } + + /** + * Switches the active arm of a player. + */ + public void switchActiveArm(){ + if(activeArm.equals(Arm.Right)) + activeArm = Arm.Left; + else + activeArm = Arm.Right; + } + + /** + * Switches to the most suitable arm for the player. + * @return + */ + public Arm switchPreferredArm(){ + switchActiveArm(); + if(activeArm.equals(Arm.Left)){ + if(!displayLeftArm()){ + switchActiveArm(); + } + } + if(activeArm.equals(Arm.Right)){ + if(!displayRightArm()){ + switchActiveArm(); + } + } + return getActiveArm(); + } + + public boolean canDisplayCurrentArm(){ + switch(activeArm){ + case Left: + return displayLeftArm(); + case Right: + return displayRightArm(); + default: + return false; + } + } + + public Player getPlayer(){ + return player; + } + + public Boolean isFullSource(){ + return fullSource; + } + + public Integer getLengthReduction(){ + return lengthReduction; + } + + public void setLengthReduction(int lengthReduction){ + this.lengthReduction = lengthReduction; + } + + public Integer getMaxPunches(){ + return maxPunches; + } + + public void setMaxPunches(int maxPunches){ + this.maxPunches = maxPunches; + } + + public Integer getMaxUses(){ + return maxUses; + } + + public void setMaxUses(int maxUses){ + this.maxUses = maxUses; + } + + public Integer getMaxIceBlasts(){ + return maxIceBlasts; + } + + public void setMaxIceBlasts(int maxIceBlasts){ + this.maxIceBlasts = maxIceBlasts; + } + + public boolean canLightningDamage(){ + return lightningEnabled; + } + + public void setCanLightningDamage(boolean lightningEnabled){ + this.lightningEnabled = lightningEnabled; + } + + public double getLightningDamage(){ + return lightningDamage; + } + + public void setLightningDamage(double lightningDamage){ + this.lightningDamage = lightningDamage; + } + + public boolean isLeftArmCooldown(){ + return cooldownLeft; + } + + public void setLeftArmCooldown(boolean cooldown){ + this.cooldownLeft = cooldown; + } + + public boolean isRightArmCooldown(){ + return cooldownRight; + } + + public void setRightArmCooldown(boolean cooldown){ + this.cooldownRight = cooldown; + } + + public void setActiveArmCooldown(boolean cooldown){ + switch(activeArm){ + case Left: + setLeftArmCooldown(cooldown); + return; + case Right: + setRightArmCooldown(cooldown); + return; + default: + break; + } + } + + public long getCooldown() { + return cooldown; + } + + public void setCooldown(long cooldown) { + this.cooldown = cooldown; + } +} \ No newline at end of file diff --git a/src/com/projectkorra/ProjectKorra/waterbending/WaterArmsWhip.java b/src/com/projectkorra/ProjectKorra/waterbending/WaterArmsWhip.java new file mode 100644 index 00000000..6598db3c --- /dev/null +++ b/src/com/projectkorra/ProjectKorra/waterbending/WaterArmsWhip.java @@ -0,0 +1,432 @@ +package com.projectkorra.ProjectKorra.waterbending; + +import java.util.ArrayList; +import java.util.concurrent.ConcurrentHashMap; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Creature; +import org.bukkit.entity.Entity; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import com.projectkorra.ProjectKorra.BendingManager; +import com.projectkorra.ProjectKorra.BendingPlayer; +import com.projectkorra.ProjectKorra.Commands; +import com.projectkorra.ProjectKorra.GeneralMethods; +import com.projectkorra.ProjectKorra.MultiAbilityManager; +import com.projectkorra.ProjectKorra.ProjectKorra; +import com.projectkorra.ProjectKorra.TempBlock; +import com.projectkorra.ProjectKorra.earthbending.EarthMethods; +import com.projectkorra.ProjectKorra.waterbending.WaterArms.Arm; +import com.projectkorra.rpg.WorldEvents; + +public class WaterArmsWhip{ + + /** + * Whip Enum value for deciding what ability should be executed. + */ + public enum Whip { + Pull, Punch, Grapple, Grab; + } + + private static FileConfiguration config = ProjectKorra.plugin.getConfig(); + + public static ConcurrentHashMap instances = new ConcurrentHashMap(); + public static ArrayList grabbedEntities = new ArrayList(); + + private Player player; + private WaterArms waterArms; + + private int whipLength = config.getInt("Abilities.Water.WaterArms.WhipMode.MaxLength"); + private int whipLengthWeak = config.getInt("Abilities.Water.WaterArms.WhipMode.MaxLengthWeak"); + + private int whipLengthNight = config.getInt("Abilities.Water.WaterArms.WhipMode.NightAugments.MaxLength.Normal"); + private int whipLengthFullMoon = config.getInt("Abilities.Water.WaterArms.WhipMode.NightAugments.MaxLength.FullMoon"); + + private int initLength = config.getInt("Abilities.Water.WaterArms.Arms.InitialLength"); + private double damage = config.getDouble("Abilities.Water.WaterArms.WhipMode.Punch.PunchDamage"); + private boolean pullBlocks = config.getBoolean("Abilities.Water.WaterArms.WhipMode.Pull.PullBlocks"); + private long pullBlocksRevertDelay = config.getLong("Abilities.Water.WaterArms.WhipMode.Pull.BlockRevertDelay"); + private boolean grappleRespectRegions = config.getBoolean("Abilities.Water.WaterArms.WhipMode.Grapple.RespectRegions"); + private boolean usageCooldownEnabled = config.getBoolean("Abilities.Water.WaterArms.Arms.Cooldowns.UsageCooldownEnabled"); + private long usageCooldown = config.getLong("Abilities.Water.WaterArms.Arms.Cooldowns.UsageCooldown"); + + private int activeLength = initLength; + private int whipSpeed = 2; + private boolean reverting = false; + private boolean damaged = false; + private boolean grappled = false; + private boolean grabbed = false; + private LivingEntity grabbedEntity; + private Location end; + private Arm arm; + private Whip ability; + + private int id; + private static int ID = Integer.MIN_VALUE; + + public WaterArmsWhip(Player player, Whip m){ + this.player = player; + ability = m; + getNightAugments(); + createInstance(); + } + + private void getNightAugments(){ + World world = player.getWorld(); + if(WaterMethods.isNight(world)){ + if(GeneralMethods.hasRPG()){ + if(BendingManager.events.get(world).equalsIgnoreCase(WorldEvents.LunarEclipse.toString())){ + whipLength = whipLengthFullMoon; + }else if (BendingManager.events.get(world).equalsIgnoreCase("FullMoon")){ + whipLength = whipLengthFullMoon; + }else{ + whipLength = whipLengthNight; + } + }else{ + if(WaterMethods.isFullMoon(world)){ + whipLength = whipLengthFullMoon; + }else{ + whipLength = whipLengthNight; + } + } + } + } + + private void createInstance(){ + if(WaterArms.instances.containsKey(player)){ + waterArms = WaterArms.instances.get(player); + waterArms.switchPreferredArm(); + arm = waterArms.getActiveArm(); + BendingPlayer bPlayer = GeneralMethods.getBendingPlayer(player.getName()); + if(arm.equals(Arm.Left)){ + if(waterArms.isLeftArmCooldown() || bPlayer.isOnCooldown("WaterArms_LEFT")){ + return; + }else{ + if(usageCooldownEnabled) + bPlayer.addCooldown("WaterArms_LEFT", usageCooldown); + waterArms.setLeftArmCooldown(true); + } + } + if(arm.equals(Arm.Right)){ + if(waterArms.isRightArmCooldown() || bPlayer.isOnCooldown("WaterArms_RIGHT")){ + return; + }else{ + if(usageCooldownEnabled) + bPlayer.addCooldown("WaterArms_RIGHT", usageCooldown); + waterArms.setRightArmCooldown(true); + } + } + }else{ + return; + } + if(!waterArms.isFullSource()){ + whipLength = whipLengthWeak; + } + id = ID; + instances.put(id, this); + if (ID == Integer.MAX_VALUE) + ID = Integer.MIN_VALUE; + ID++; + } + + private void progress(){ + if(!WaterArms.instances.containsKey(player)){ + remove(); + return; + } + if(player.isDead() || !player.isOnline()){ + remove(); + return; + } + if(!MultiAbilityManager.hasMultiAbilityBound(player, "WaterArms")){ + remove(); + return; + } + + if(activeLength < whipLength && !reverting){ + activeLength+=whipSpeed; + }else if(activeLength > initLength){ + if(!grabbed){ + activeLength-=whipSpeed; + } + }else{ + remove(); + return; + } + + if(activeLength == whipLength && !grabbed){ + reverting = true; + } + + if(arm.equals(Arm.Left)){ + useLeftArm(); + }else{ + useRightArm(); + } + dragEntity(end); + grapplePlayer(end); + } + + //START OF RECODE + + private boolean canPlaceBlock(Block block){ + if(!EarthMethods.isTransparentToEarthbending(player, block) && !(WaterMethods.isWater(block) && TempBlock.isTempBlock(block))){ + return false; + } + return true; + } + + private void useLeftArm(){ + if(waterArms.displayLeftArm()){ + Location l1 = waterArms.getLeftArmEnd().clone(); + Vector dir = player.getLocation().getDirection(); + for(int i = 1; i <= activeLength; i++){ + Location l2 = l1.clone().add(dir.normalize().multiply(i)); + + if(!canPlaceBlock(l2.getBlock())){ + if(!l2.getBlock().getType().equals(Material.BARRIER)){ + grappled = true; + } + reverting = true; + break; + } + + new TempBlock(l2.getBlock(), Material.STATIONARY_WATER, (byte) 0); + WaterArms.revert.put(l2.getBlock(), 0L); + + if(i == activeLength){ + Location l3 = GeneralMethods.getRightSide(l2, 1); + end = l3.clone(); + if(canPlaceBlock(l3.getBlock())){ + new TempBlock(l3.getBlock(), Material.STATIONARY_WATER, (byte) 3); + WaterArms.revert.put(l3.getBlock(), 0L); + checkLocation(l3); + }else{ + if(!l3.getBlock().getType().equals(Material.BARRIER)){ + grappled = true; + } + reverting = true; + } + } + } + } + } + + private void useRightArm(){ + if(waterArms.displayLeftArm()){ + Location l1 = waterArms.getRightArmEnd().clone(); + Vector dir = player.getLocation().getDirection(); + for(int i = 1; i <= activeLength; i++){ + Location l2 = l1.clone().add(dir.normalize().multiply(i)); + + if(!canPlaceBlock(l2.getBlock())){ + if(!l2.getBlock().getType().equals(Material.BARRIER)){ + grappled = true; + } + reverting = true; + break; + } + + new TempBlock(l2.getBlock(), Material.STATIONARY_WATER, (byte) 0); + WaterArms.revert.put(l2.getBlock(), 0L); + + if(i == activeLength){ + Location l3 = GeneralMethods.getLeftSide(l2, 1); + end = l3.clone(); + if(canPlaceBlock(l3.getBlock())){ + new TempBlock(l3.getBlock(), Material.STATIONARY_WATER, (byte) 3); + WaterArms.revert.put(l3.getBlock(), 0L); + checkLocation(l3); + }else{ + if(!l3.getBlock().getType().equals(Material.BARRIER)){ + grappled = true; + } + reverting = true; + } + } + } + } + } + + private void checkLocation(Location location){ + Location endOfArm = waterArms.getLeftArmEnd().clone(); + switch(ability){ + case Pull: + for(Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 2)){ + if(entity instanceof Player && Commands.invincible.contains(((Player) entity).getName())){ + continue; + } + Vector vector = endOfArm.toVector().subtract(entity.getLocation().toVector()); + entity.setVelocity(vector.multiply(0.15)); + } + break; + case Punch: + for(Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 2)){ + if(entity instanceof Player && Commands.invincible.contains(((Player) entity).getName())){ + continue; + } + Vector vector = entity.getLocation().toVector().subtract(endOfArm.toVector()); + entity.setVelocity(vector.multiply(0.15)); + if(entity instanceof LivingEntity){ + if(entity.getEntityId() != player.getEntityId()){ + damaged = true; + GeneralMethods.damageEntity(player, entity, damage); + } + } + } + break; + case Grapple: + grapplePlayer(end); + break; + case Grab: + if(grabbedEntity == null){ + for(Entity entity : GeneralMethods.getEntitiesAroundPoint(location, 2)){ + if(entity instanceof LivingEntity && entity.getEntityId() != player.getEntityId() && !grabbedEntities.contains(entity)){ + System.out.println("Grabbed Entity!"); + grabbedEntities.add((LivingEntity) entity); + grabbedEntity = (LivingEntity) entity; + grabbed = true; + reverting = true; + waterArms.setActiveArmCooldown(true); + break; + } + } + } + break; + default: + break; + } + } + + private void dragEntity(Location location){ + if(grabbedEntity != null){ + if(!waterArms.canDisplayCurrentArm() || grabbedEntity.isDead()){ + grabbed = false; + grabbedEntities.remove(grabbedEntity); + return; + } + Location newlocation = grabbedEntity.getLocation(); + 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) { + grabbedEntity.setVelocity(vector.normalize().multiply(1)); + } else { + grabbedEntity.setVelocity(new Vector(0, 0, 0)); + } + grabbedEntity.setFallDistance(0); + if (grabbedEntity instanceof Creature) { + ((Creature) grabbedEntity).setTarget(null); + } + } + } + + private void grapplePlayer(Location location){ + if(reverting && grappled && player != null && end != null && ability.equals(Whip.Grapple)){ + Vector vector = player.getLocation().toVector().subtract(location.toVector()); + player.setVelocity(vector.multiply(-0.25)); + player.setFallDistance(0); + } + } + + //END OF RECODE + + @SuppressWarnings("deprecation") + private void spawnFallingBlock(Location location, Location armbase){ + Block block = location.getBlock(); + Material mat = block.getType(); + byte data = block.getData(); + if(!GeneralMethods.isRegionProtectedFromBuild(player, "WaterArms", location)){ + Location spawnLoc = location.clone().toVector().subtract(player.getLocation().clone().getDirection().multiply(1)).toLocation(player.getWorld()); + + new TempBlock(block, Material.AIR, (byte) 0); + WaterArms.revert.put(block, System.currentTimeMillis() + pullBlocksRevertDelay); + + if(!WaterArms.isUnbreakable(spawnLoc.getBlock())){ + new TempBlock(spawnLoc.getBlock(), Material.AIR, (byte) 0); + WaterArms.revert.put(spawnLoc.getBlock(), System.currentTimeMillis() + pullBlocksRevertDelay); + }else{ + return; + } + + FallingBlock fBlock = player.getWorld().spawnFallingBlock(spawnLoc.clone(), mat, data); + fBlock.setDropItem(false); + Vector from = fBlock.getLocation().toVector(); + Vector to = armbase.clone().toVector(); + Vector vector = to.subtract(from); + fBlock.setVelocity(vector.multiply(0.15)); + WaterArms.falling.put(fBlock, player); + } + } + + private boolean canModifyBlock(Block block, Location toLoc){ + if(!EarthMethods.isTransparentToEarthbending(player, block) && !WaterMethods.isWater(block)){ + if(GeneralMethods.isRegionProtectedFromBuild(player, "WaterArms", block.getLocation())){ + if(!grappleRespectRegions() && block.getType().isSolid() && !EarthMethods.isTransparentToEarthbending(player, block)) + grappled = true; + reverting = true; + return true; + } + if(EarthMethods.isTransparentToEarthbending(player, block)){ + if(!block.getType().equals(Material.BARRIER)){ + grappled = true; + } + reverting = true; + return true; + } + if(!(TempBlock.isTempBlock(block) && TempBlock.get(block).equals(Material.AIR))){ + if(!block.isLiquid() && block.getType().isSolid() && ability.equals(Whip.Pull) && pullBlocks && player.hasPermission("bending.ability.WaterArms.PullBlocks")){ + if(!EarthMethods.isTransparentToEarthbending(player, block)) + spawnFallingBlock(block.getLocation(), toLoc); + } + grappled = true; + reverting = true; + return true; + } + } + return false; + } + + private boolean grappleRespectRegions(){ + if(!grappleRespectRegions) + if(!ability.equals(Whip.Grapple)) + return true; + else + return false; + else + return true; + } + + private void remove(){ + if(WaterArms.instances.containsKey(player)){ + if(arm.equals(Arm.Left)){ + waterArms.setLeftArmCooldown(false); + }else{ + waterArms.setRightArmCooldown(false); + } + if(damaged) + waterArms.setMaxPunches(waterArms.getMaxPunches() - 1); + waterArms.setMaxUses(waterArms.getMaxUses() - 1); + } + instances.remove(id); + } + + public static void progressAll(){ + for(int ID : instances.keySet()) + instances.get(ID).progress(); + } + + public static void removeAll(){ + instances.clear(); + } +} \ No newline at end of file