package com.projectkorra.projectkorra.earthbending.metal; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.entity.Entity; import org.bukkit.entity.Item; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.entity.Skeleton; import org.bukkit.entity.Zombie; import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; import com.projectkorra.projectkorra.GeneralMethods; import com.projectkorra.projectkorra.ability.CoreAbility; import com.projectkorra.projectkorra.ability.MetalAbility; import com.projectkorra.projectkorra.util.DamageHandler; import com.projectkorra.projectkorra.util.TempArmor; public class MetalClips extends MetalAbility { private static final Map ENTITY_CLIPS_COUNT = new ConcurrentHashMap<>(); private static final Map TARGET_TO_ABILITY = new ConcurrentHashMap<>(); private static final Material[] METAL_ITEMS = { Material.IRON_INGOT, Material.IRON_HELMET, Material.IRON_CHESTPLATE, Material.IRON_LEGGINGS, Material.IRON_BOOTS, Material.IRON_BLOCK, Material.IRON_AXE, Material.IRON_PICKAXE, Material.IRON_SWORD, Material.IRON_HOE, Material.IRON_SPADE, Material.IRON_DOOR }; private boolean isBeingWorn; private boolean isControlling; private boolean canThrow; private boolean isMagnetized; private boolean canUse4Clips; private boolean canLoot; private boolean hasSnuck; private int metalClipsCount; private int abilityType; private int armorTime; private int magnetRange; private long armorStartTime; private long cooldown; private long shootCooldown; private long crushCooldown; private long magnetCooldown; private double magnetPower; private double range; private double crushDamage; private double damage; private LivingEntity targetEntity; //private ItemStack[] oldArmor; private List trackedIngots; public MetalClips(Player player, int abilityType) { super(player); if (hasAbility(player, MetalClips.class)) { return; } this.abilityType = abilityType; this.canLoot = player.hasPermission("bending.ability.MetalClips.loot"); this.canUse4Clips = player.hasPermission("bending.ability.MetalClips.4clips"); this.armorTime = getConfig().getInt("Abilities.Earth.MetalClips.Duration"); this.range = getConfig().getDouble("Abilities.Earth.MetalClips.Range"); this.cooldown = getConfig().getLong("Abilities.Earth.MetalClips.Cooldown"); this.shootCooldown = 600; this.crushCooldown = getConfig().getLong("Abilities.Earth.MetalClips.CrushCooldown"); this.magnetCooldown = getConfig().getLong("Abilities.Earth.MetalClips.MagnetCooldown"); this.magnetRange = getConfig().getInt("Abilities.Earth.MetalClips.MagnetRange"); this.magnetPower = getConfig().getDouble("Abilities.Earth.MetalClips.MagnetPower"); this.crushDamage = getConfig().getDouble("Abilities.Earth.MetalClips.CrushDamage"); this.damage = getConfig().getDouble("Abilities.Earth.MetalClips.Damage"); this.canThrow = (getConfig().getBoolean("Abilities.Earth.MetalClips.ThrowEnabled") && player.hasPermission("bending.ability.metalclips.throw")); this.trackedIngots = new ArrayList<>(); if (bPlayer.isAvatarState()) { cooldown = getConfig().getLong("Abilities.Avatar.AvatarState.Earth.MetalClips.Cooldown"); range = getConfig().getDouble("Abilities.Avatar.AvatarState.Earth.MetalClips.Range"); crushDamage = getConfig().getLong("Abilities.Avatar.AvatarState.Earth.MetalClips.CrushDamage"); } if (abilityType == 0) { if (!bPlayer.canBend(this)) { return; } if (!player.getInventory().containsAtLeast(new ItemStack(Material.IRON_INGOT), 1)) { return; } shootMetal(); } else if (abilityType == 1) { if (bPlayer.isOnCooldown("MetalClips Magnet")) { return; } isMagnetized = true; } start(); } /* * public static ItemStack getOriginalHelmet(LivingEntity ent) { MetalClips * clips = TARGET_TO_ABILITY.get(ent); if (clips != null) { return * clips.oldArmor[3]; } return null; } * * public static ItemStack getOriginalChestplate(LivingEntity ent) { * MetalClips clips = TARGET_TO_ABILITY.get(ent); if (clips != null) { * return clips.oldArmor[2]; } return null; } * * public static ItemStack getOriginalLeggings(LivingEntity ent) { * MetalClips clips = TARGET_TO_ABILITY.get(ent); if (clips != null) { * return clips.oldArmor[1]; } return null; } * * public static ItemStack getOriginalBoots(LivingEntity ent) { MetalClips * clips = TARGET_TO_ABILITY.get(ent); if (clips != null) { return * clips.oldArmor[0]; } return null; } * * public static ItemStack[] getOriginalArmor(LivingEntity ent) { MetalClips * clips = TARGET_TO_ABILITY.get(ent); if (clips != null) { return * clips.oldArmor; } return null; } */ public void shootMetal() { if (bPlayer.isOnCooldown("MetalClips Shoot")) { return; } bPlayer.addCooldown("MetalClips Shoot", shootCooldown); ItemStack is = new ItemStack(Material.IRON_INGOT, 1); if (!player.getInventory().containsAtLeast(is, 1)) { return; } Item item = player.getWorld().dropItemNaturally(player.getLocation().add(0, 1, 0), is); Vector vector; Entity targetedEntity = GeneralMethods.getTargetedEntity(player, range, new ArrayList()); if (targetedEntity != null) { vector = GeneralMethods.getDirection(player.getLocation(), targetedEntity.getLocation()); } else { vector = GeneralMethods.getDirection(player.getLocation(), GeneralMethods.getTargetedLocation(player, range)); } item.setVelocity(vector.normalize().add(new Vector(0, 0.1, 0).multiply(1.2))); trackedIngots.add(item); player.getInventory().removeItem(is); } public void formArmor() { if (metalClipsCount >= 4) { return; } else if (metalClipsCount == 3 && !canUse4Clips) { return; } else if (targetEntity != null && GeneralMethods.isRegionProtectedFromBuild(this, targetEntity.getLocation())) { return; } metalClipsCount = (metalClipsCount < 4) ? metalClipsCount + 1 : 4; if (targetEntity instanceof Player) { Player target = (Player) targetEntity; ItemStack[] metalArmor = new ItemStack[4]; metalArmor[2] = (metalClipsCount >= 1) ? new ItemStack(Material.IRON_CHESTPLATE) : new ItemStack(Material.AIR); metalArmor[0] = (metalClipsCount >= 2) ? new ItemStack(Material.IRON_BOOTS) : new ItemStack(Material.AIR); metalArmor[1] = (metalClipsCount >= 3) ? new ItemStack(Material.IRON_LEGGINGS) : new ItemStack(Material.AIR); metalArmor[3] = (metalClipsCount >= 4) ? new ItemStack(Material.IRON_HELMET) : new ItemStack(Material.AIR); ENTITY_CLIPS_COUNT.put(target, metalClipsCount); TempArmor armor = TempArmor.getTempArmor(target); if (armor != null) armor.revert(); new TempArmor(target, this, metalArmor); } else { ItemStack[] metalarmor = new ItemStack[4]; metalarmor[2] = (metalClipsCount >= 1) ? new ItemStack(Material.IRON_CHESTPLATE) : new ItemStack(Material.AIR); metalarmor[0] = (metalClipsCount >= 2) ? new ItemStack(Material.IRON_BOOTS) : new ItemStack(Material.AIR); metalarmor[1] = (metalClipsCount >= 3) ? new ItemStack(Material.IRON_LEGGINGS) : new ItemStack(Material.AIR); metalarmor[3] = (metalClipsCount >= 4) ? new ItemStack(Material.IRON_HELMET) : new ItemStack(Material.AIR); ENTITY_CLIPS_COUNT.put(targetEntity, metalClipsCount); TempArmor armor = TempArmor.getTempArmor(targetEntity); if (armor != null) armor.revert(); new TempArmor(targetEntity, this, metalarmor); } armorStartTime = System.currentTimeMillis(); isBeingWorn = true; } public void resetArmor() { if (!isMagnetized) { bPlayer.addCooldown(this); } if (targetEntity == null || !TempArmor.hasTempArmor(targetEntity) || targetEntity.isDead()) { return; } TempArmor.getTempArmor(targetEntity).revert(); dropIngots(targetEntity.getLocation()); isBeingWorn = false; } public void launch() { if (!canThrow) { return; } if (targetEntity == null) { return; } Location location = player.getLocation(); double dx, dy, dz; Location target = targetEntity.getLocation().clone(); dx = target.getX() - location.getX(); dy = target.getY() - location.getY(); dz = target.getZ() - location.getZ(); Vector vector = new Vector(dx, dy, dz); vector.normalize(); targetEntity.setVelocity(vector.multiply(metalClipsCount / 2).normalize()); remove(); } public void crush() { if (bPlayer.isOnCooldown("MetalClips Crush")) { return; } bPlayer.addCooldown("MetalClips Crush", crushCooldown); DamageHandler.damageEntity(targetEntity, player, crushDamage, this); } @Override public void progress() { if (!bPlayer.canBendIgnoreCooldowns(this)) { remove(); return; } if (targetEntity != null) { if ((targetEntity instanceof Player && !((Player) targetEntity).isOnline()) || targetEntity.isDead()) { remove(); return; } } if (player.isSneaking()) { hasSnuck = true; } if (!player.isSneaking()) { if (isMagnetized) { bPlayer.addCooldown("MetalClips Magnet", magnetCooldown); remove(); return; } isControlling = false; isMagnetized = false; if (metalClipsCount < 4 && hasSnuck && abilityType == 0) { launch(); } } if (isMagnetized) { if (GeneralMethods.getEntitiesAroundPoint(player.getLocation(), magnetRange).size() == 0) { remove(); return; } for (Entity entity : GeneralMethods.getEntitiesAroundPoint(player.getLocation(), magnetRange)) { Vector vector = GeneralMethods.getDirection(entity.getLocation(), player.getLocation()); ItemStack itemInHand = player.getInventory().getItemInMainHand(); if (entity instanceof Player && canLoot && itemInHand.getType() == Material.IRON_INGOT && (itemInHand.hasItemMeta() && itemInHand.getItemMeta().getDisplayName().equalsIgnoreCase("Magnet"))) { Player targetPlayer = (Player) entity; if (targetPlayer.getEntityId() == player.getEntityId()) { continue; } ItemStack[] inventory = targetPlayer.getInventory().getContents(); for (ItemStack is : inventory) { if (is == null) { continue; } if (Arrays.asList(METAL_ITEMS).contains(is.getType())) { targetPlayer.getWorld().dropItem(targetPlayer.getLocation(), is); is.setType(Material.AIR); is.setAmount(0); } } targetPlayer.getInventory().setContents(inventory); ItemStack[] armor = targetPlayer.getInventory().getArmorContents(); for (ItemStack is : armor) { if (Arrays.asList(METAL_ITEMS).contains(is.getType())) { targetPlayer.getWorld().dropItem(targetPlayer.getLocation(), is); is.setType(Material.AIR); } } targetPlayer.getInventory().setArmorContents(armor); if (Arrays.asList(METAL_ITEMS).contains(targetPlayer.getInventory().getItemInMainHand().getType())) { targetPlayer.getWorld().dropItem(targetPlayer.getLocation(), targetPlayer.getEquipment().getItemInMainHand()); targetPlayer.getEquipment().setItemInMainHand(new ItemStack(Material.AIR, 1)); } } if ((entity instanceof Zombie || entity instanceof Skeleton) && canLoot && itemInHand.getType() == Material.IRON_INGOT && itemInHand.getItemMeta().getDisplayName().equalsIgnoreCase("Magnet")) { LivingEntity livingEntity = (LivingEntity) entity; ItemStack[] armor = livingEntity.getEquipment().getArmorContents(); for (ItemStack istack : armor) { if (Arrays.asList(METAL_ITEMS).contains(istack.getType())) { livingEntity.getWorld().dropItem(livingEntity.getLocation(), istack); istack.setType(Material.AIR); } } livingEntity.getEquipment().setArmorContents(armor); if (Arrays.asList(METAL_ITEMS).contains(livingEntity.getEquipment().getItemInMainHand().getType())) { livingEntity.getWorld().dropItem(livingEntity.getLocation(), livingEntity.getEquipment().getItemInMainHand()); livingEntity.getEquipment().setItemInMainHand(new ItemStack(Material.AIR, 1)); } } if (entity instanceof Item) { Item iron = (Item) entity; if (Arrays.asList(METAL_ITEMS).contains(iron.getItemStack().getType())) { iron.setVelocity(vector.normalize().multiply(magnetPower).add(new Vector(0, 0.2, 0))); } } } } if (isBeingWorn && System.currentTimeMillis() > armorStartTime + armorTime) { remove(); return; } if (isControlling && player.isSneaking()) { if (metalClipsCount == 1) { Location oldLocation = targetEntity.getLocation(); Location loc = oldLocation; if (player.getWorld().equals(oldLocation.getWorld())) { loc = GeneralMethods.getTargetedLocation(player, (int) player.getLocation().distance(oldLocation)); } double distance = 0; if (loc.getWorld().equals(oldLocation.getWorld())) { distance = loc.distance(oldLocation); } Vector vector = GeneralMethods.getDirection(targetEntity.getLocation(), player.getLocation()); if (distance > 0.5) { targetEntity.setVelocity(vector.normalize().multiply(0.2)); } } if (metalClipsCount == 2) { Location oldLocation = targetEntity.getLocation(); Location loc = oldLocation; if (player.getWorld().equals(oldLocation.getWorld())) { loc = GeneralMethods.getTargetedLocation(player, (int) player.getLocation().distance(oldLocation)); } double distance = 0; if (loc.getWorld().equals(oldLocation.getWorld())) { distance = loc.distance(oldLocation); } Vector vector = GeneralMethods.getDirection(targetEntity.getLocation(), GeneralMethods.getTargetedLocation(player, 10)); if (distance > 1.2) { targetEntity.setVelocity(vector.normalize().multiply(0.2)); } } if (metalClipsCount >= 3) { Location oldLocation = targetEntity.getLocation(); Location loc = oldLocation; if (player.getWorld().equals(oldLocation.getWorld())) { loc = GeneralMethods.getTargetedLocation(player, (int) player.getLocation().distance(oldLocation)); } double distance = 0; if (loc.getWorld().equals(oldLocation.getWorld())) { distance = loc.distance(oldLocation); } Vector vector = GeneralMethods.getDirection(oldLocation, GeneralMethods.getTargetedLocation(player, 10)); if (distance > 1.2) { targetEntity.setVelocity(vector.normalize().multiply(.5)); } else { targetEntity.setVelocity(new Vector(0, 0, 0)); } targetEntity.setFallDistance(0); } } for (int i = trackedIngots.size() - 1; i >= 0; i--) { Item ii = trackedIngots.get(i); if (ii.isOnGround()) { trackedIngots.remove(i); continue; } if (ii.getItemStack().getType() == Material.IRON_INGOT) { if (GeneralMethods.getEntitiesAroundPoint(ii.getLocation(), 2).size() == 0) { remove(); return; } for (Entity e : GeneralMethods.getEntitiesAroundPoint(ii.getLocation(), 2)) { if (e instanceof LivingEntity && e.getEntityId() != player.getEntityId()) { if ((e instanceof Player || e instanceof Zombie || e instanceof Skeleton)) { if (targetEntity == null) { targetEntity = (LivingEntity) e; TARGET_TO_ABILITY.put(targetEntity, this); formArmor(); } else if (targetEntity == e) { formArmor(); } else { dropIngots(e.getLocation()); TARGET_TO_ABILITY.get(targetEntity).remove(); } } else { DamageHandler.damageEntity(e, player, damage, this); dropIngots(e.getLocation(), ii.getItemStack().getAmount()); remove(); } ii.remove(); break; } } } } removeDeadIngots(); } public void dropIngots(Location loc) { dropIngots(loc, metalClipsCount == 0 ? 1 : metalClipsCount); } public void dropIngots(Location loc, int amount) { Item i = player.getWorld().dropItem(loc, new ItemStack(Material.IRON_INGOT, amount)); i.setPickupDelay(61); } public void removeDeadIngots() { for (int i = 0; i < trackedIngots.size(); i++) { Item ii = trackedIngots.get(i); if (ii.isDead()) { trackedIngots.remove(ii); } } } @Override public void remove() { super.remove(); resetArmor(); trackedIngots.clear(); metalClipsCount = 0; if (targetEntity != null) { ENTITY_CLIPS_COUNT.remove(targetEntity); TARGET_TO_ABILITY.remove(targetEntity); } } public static boolean isControlled(LivingEntity player) { return TARGET_TO_ABILITY.containsKey(player); } public static boolean isControllingEntity(Player player) { MetalClips clips = getAbility(player, MetalClips.class); return clips != null && player.isSneaking() && clips.targetEntity != null; } public static Map getEntityClipsCount() { return ENTITY_CLIPS_COUNT; } public static Map getTargetToAbility() { return TARGET_TO_ABILITY; } public static boolean removeControlledEnitity(LivingEntity entity) { if (entity == null) return false; for (MetalClips metalclips : CoreAbility.getAbilities(MetalClips.class)) { if (metalclips.targetEntity == entity) { metalclips.remove(); return true; } } return false; } @Override public String getName() { return "MetalClips"; } @Override public Location getLocation() { if (targetEntity != null) { return targetEntity.getLocation(); } else if (player != null) { return player.getLocation(); } return null; } @Override public long getCooldown() { return cooldown; } public long getShootCooldown() { return shootCooldown; } public long getCrushCooldown() { return crushCooldown; } @Override public boolean isSneakAbility() { return true; } @Override public boolean isHarmlessAbility() { return false; } public boolean isBeingWorn() { return isBeingWorn; } public void setBeingWorn(boolean isBeingWorn) { this.isBeingWorn = isBeingWorn; } public boolean isControlling() { return isControlling; } public void setControlling(boolean isControlling) { this.isControlling = isControlling; } public boolean isCanThrow() { return canThrow; } public void setCanThrow(boolean canThrow) { this.canThrow = canThrow; } public boolean isMagnetized() { return isMagnetized; } public void setMagnetized(boolean isMagnetized) { this.isMagnetized = isMagnetized; } public boolean isCanUse4Clips() { return canUse4Clips; } public void setCanUse4Clips(boolean canUse4Clips) { this.canUse4Clips = canUse4Clips; } public boolean isCanLoot() { return canLoot; } public void setCanLoot(boolean canLoot) { this.canLoot = canLoot; } public int getMetalClipsCount() { return metalClipsCount; } public void setMetalClipsCount(int metalClipsCount) { this.metalClipsCount = metalClipsCount; } public int getAbilityType() { return abilityType; } public void setAbilityType(int abilityType) { this.abilityType = abilityType; } public int getArmorTime() { return armorTime; } public void setArmorTime(int armorTime) { this.armorTime = armorTime; } public double getCrushDamage() { return crushDamage; } public void setCrushDamage(double crushDamage) { this.crushDamage = crushDamage; } public int getMagnetRange() { return magnetRange; } public void setMagnetRange(int magnetRange) { this.magnetRange = magnetRange; } public long getArmorStartTime() { return armorStartTime; } public void setArmorStartTime(long armorStartTime) { this.armorStartTime = armorStartTime; } public double getMagnetPower() { return magnetPower; } public void setMagnetPower(double magnetPower) { this.magnetPower = magnetPower; } public double getRange() { return range; } public void setRange(double range) { this.range = range; } public LivingEntity getTargetEntity() { return targetEntity; } public void setTargetEntity(LivingEntity targetEntity) { this.targetEntity = targetEntity; } public List getTrackedIngots() { return trackedIngots; } public void setCooldown(long cooldown) { this.cooldown = cooldown; } }