package com.projectkorra.projectkorra.earthbending; import java.util.List; import org.bukkit.Color; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.LeatherArmorMeta; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; import com.projectkorra.projectkorra.GeneralMethods; import com.projectkorra.projectkorra.ProjectKorra; import com.projectkorra.projectkorra.ability.EarthAbility; import com.projectkorra.projectkorra.ability.ElementalAbility; import com.projectkorra.projectkorra.attribute.Attribute; import com.projectkorra.projectkorra.command.Commands; import com.projectkorra.projectkorra.util.ParticleEffect; import com.projectkorra.projectkorra.util.TempArmor; import com.projectkorra.projectkorra.util.TempBlock; public class EarthArmor extends EarthAbility { private boolean formed; private Material headMaterial; private Material legsMaterial; @Attribute(Attribute.COOLDOWN) private long cooldown; private long interval; @Attribute(Attribute.DURATION) private long maxDuration; @Attribute(Attribute.SELECT_RANGE) private double selectRange; private Block headBlock; private Block legsBlock; private Location headBlockLocation; private Location legsBlockLocation; private boolean active; private PotionEffect oldAbsorbtion = null; private double goldHearts; @Attribute("GoldHearts") private int maxGoldHearts; private TempArmor armor; public EarthArmor(final Player player) { super(player); if (hasAbility(player, EarthArmor.class) || !this.canBend()) { return; } this.formed = false; this.active = true; this.interval = 2000; this.goldHearts = 0; this.cooldown = getConfig().getLong("Abilities.Earth.EarthArmor.Cooldown"); this.maxDuration = getConfig().getLong("Abilities.Earth.EarthArmor.MaxDuration"); this.selectRange = getConfig().getDouble("Abilities.Earth.EarthArmor.SelectRange"); this.maxGoldHearts = getConfig().getInt("Abilities.Earth.EarthArmor.GoldHearts"); if (this.bPlayer.isAvatarState()) { this.cooldown = getConfig().getLong("Abilities.Avatar.AvatarState.Earth.EarthArmor.Cooldown"); this.maxGoldHearts = getConfig().getInt("Abilities.Avatar.AvatarState.Earth.EarthArmor.GoldHearts"); } this.headBlock = this.getTargetEarthBlock((int) this.selectRange); if (!GeneralMethods.isRegionProtectedFromBuild(this, this.headBlock.getLocation()) && this.getEarthbendableBlocksLength(this.headBlock, new Vector(0, -1, 0), 2) >= 2) { this.legsBlock = this.headBlock.getRelative(BlockFace.DOWN); this.headMaterial = this.headBlock.getType(); this.legsMaterial = this.legsBlock.getType(); this.headBlockLocation = this.headBlock.getLocation(); this.legsBlockLocation = this.legsBlock.getLocation(); final Block oldHeadBlock = this.headBlock; final Block oldLegsBlock = this.legsBlock; if (!this.moveBlocks()) { return; } if ((TempBlock.isTempBlock(oldHeadBlock) && !isBendableEarthTempBlock(oldHeadBlock)) || (TempBlock.isTempBlock(oldLegsBlock) && !isBendableEarthTempBlock(oldLegsBlock))) { return; } if (isEarthRevertOn()) { addTempAirBlock(oldHeadBlock); addTempAirBlock(oldLegsBlock); } else { GeneralMethods.removeBlock(oldHeadBlock); GeneralMethods.removeBlock(oldLegsBlock); } playEarthbendingSound(this.headBlock.getLocation()); this.start(); } } private void formArmor() { if (TempBlock.isTempBlock(this.headBlock)) { TempBlock.revertBlock(this.headBlock, Material.AIR); } if (TempBlock.isTempBlock(this.legsBlock)) { TempBlock.revertBlock(this.legsBlock, Material.AIR); } final ItemStack head = new ItemStack(Material.LEATHER_HELMET, 1); final ItemStack chestplate = new ItemStack(Material.LEATHER_CHESTPLATE, 1); final ItemStack leggings = new ItemStack(Material.LEATHER_LEGGINGS, 1); final ItemStack boots = new ItemStack(Material.LEATHER_BOOTS, 1); final LeatherArmorMeta metaHead = (LeatherArmorMeta) head.getItemMeta(); final LeatherArmorMeta metaChest = (LeatherArmorMeta) chestplate.getItemMeta(); final LeatherArmorMeta metaLegs = (LeatherArmorMeta) leggings.getItemMeta(); final LeatherArmorMeta metaBottom = (LeatherArmorMeta) boots.getItemMeta(); metaHead.setColor(Color.fromRGB(getColor(this.headMaterial))); metaChest.setColor(Color.fromRGB(getColor(this.headMaterial))); metaLegs.setColor(Color.fromRGB(getColor(this.legsMaterial))); metaBottom.setColor(Color.fromRGB(getColor(this.legsMaterial))); head.setItemMeta(metaHead); chestplate.setItemMeta(metaChest); leggings.setItemMeta(metaLegs); boots.setItemMeta(metaBottom); final ItemStack armors[] = { boots, leggings, chestplate, head }; this.armor = new TempArmor(this.player, 72000000L, this, armors); // Duration of 2 hours. this.armor.setRemovesAbilityOnForceRevert(true); this.formed = true; for (final PotionEffect effect : this.player.getActivePotionEffects()) { if (effect.getType() == PotionEffectType.ABSORPTION) { this.oldAbsorbtion = effect; this.player.removePotionEffect(PotionEffectType.ABSORPTION); break; } } final int level = this.maxGoldHearts / 2 - 1 + (this.maxGoldHearts % 2); this.player.addPotionEffect(new PotionEffect(PotionEffectType.ABSORPTION, Integer.MAX_VALUE, level, true, false)); this.goldHearts = this.maxGoldHearts * 2; this.player.setAbsorptionAmount(this.goldHearts); } private boolean inPosition() { return this.headBlock.equals(this.player.getEyeLocation().getBlock()) && this.legsBlock.equals(this.player.getLocation().getBlock()); } private boolean moveBlocks() { if (!this.player.getWorld().equals(this.headBlock.getWorld())) { this.remove(); return false; } final Location headLocation = this.player.getEyeLocation(); final Location legsLocation = this.player.getLocation(); Vector headDirection = headLocation.toVector().subtract(this.headBlockLocation.toVector()).normalize().multiply(.5); Block newHeadBlock = this.headBlock; Block newLegsBlock = this.legsBlock; final int yDiff = this.player.getEyeLocation().getBlockY() - this.headBlock.getY(); if (yDiff != 0) { final Block checkBlock = yDiff > 0 ? this.headBlock.getRelative(BlockFace.UP) : this.legsBlock.getRelative(BlockFace.DOWN); if (this.isTransparent(checkBlock) && !checkBlock.isLiquid()) { GeneralMethods.breakBlock(checkBlock); // Destroy any minor blocks that are in the way. headDirection = new Vector(0, yDiff > 0 ? 0.5 : -0.5, 0); } } if (!headLocation.getBlock().equals(this.headBlock)) { this.headBlockLocation = this.headBlockLocation.clone().add(headDirection); newHeadBlock = this.headBlockLocation.getBlock(); } if (!legsLocation.getBlock().equals(this.legsBlock)) { this.legsBlockLocation = this.headBlockLocation.clone().add(0, -1, 0); newLegsBlock = newHeadBlock.getRelative(BlockFace.DOWN); } if (this.isTransparent(newHeadBlock) && !newHeadBlock.isLiquid()) { GeneralMethods.breakBlock(newHeadBlock); } else if (!this.isEarthbendable(newHeadBlock) && !newHeadBlock.isLiquid() && !ElementalAbility.isAir(newHeadBlock.getType())) { ParticleEffect.BLOCK_CRACK.display(newHeadBlock.getLocation(), 8, 0.5, 0.5, 0.5, newHeadBlock.getBlockData()); this.remove(); return false; } if (this.isTransparent(newLegsBlock) && !newLegsBlock.isLiquid()) { GeneralMethods.breakBlock(newLegsBlock); } else if (!this.isEarthbendable(newLegsBlock) && !newLegsBlock.isLiquid() && !ElementalAbility.isAir(newLegsBlock.getType())) { newLegsBlock.getLocation().getWorld().playSound(newLegsBlock.getLocation(), Sound.BLOCK_GRASS_BREAK, 1, 1); ParticleEffect.BLOCK_CRACK.display(newHeadBlock.getLocation(), 8, 0.5, 0.5, 0.5, newLegsBlock.getBlockData()); this.remove(); return false; } if (this.headBlock.getLocation().distanceSquared(this.player.getEyeLocation()) > this.selectRange * this.selectRange) { this.remove(); return false; } if (!newHeadBlock.equals(this.headBlock)) { new TempBlock(newHeadBlock, this.headMaterial); if (TempBlock.isTempBlock(this.headBlock)) { TempBlock.revertBlock(this.headBlock, Material.AIR); } } if (!newLegsBlock.equals(this.legsBlock)) { new TempBlock(newLegsBlock, this.legsMaterial); if (TempBlock.isTempBlock(this.legsBlock)) { TempBlock.revertBlock(this.legsBlock, Material.AIR); } } this.headBlock = newHeadBlock; this.legsBlock = newLegsBlock; return true; } @Override public void progress() { if (!this.canBend()) { this.remove(); return; } if (System.currentTimeMillis() - this.getStartTime() > this.maxDuration) { this.player.getLocation().getWorld().playSound(this.player.getLocation(), Sound.BLOCK_STONE_BREAK, 2, 1); this.player.getLocation().getWorld().playSound(this.player.getLocation(), Sound.BLOCK_STONE_BREAK, 2, 1); this.player.getLocation().getWorld().playSound(this.player.getLocation(), Sound.BLOCK_STONE_BREAK, 2, 1); ParticleEffect.BLOCK_CRACK.display(this.player.getEyeLocation(), 8, 0.1, 0.1, 0.1, this.headMaterial.createBlockData()); ParticleEffect.BLOCK_CRACK.display(this.player.getLocation(), 8, 0.1F, 0.1F, 0.1F, this.legsMaterial.createBlockData()); this.bPlayer.addCooldown(this); this.remove(); return; } if (this.formed) { if (!this.player.hasPotionEffect(PotionEffectType.ABSORPTION)) { this.player.addPotionEffect(new PotionEffect(PotionEffectType.ABSORPTION, Integer.MAX_VALUE, 1, true, false)); this.player.setAbsorptionAmount(this.goldHearts); } if (!this.active) { this.bPlayer.addCooldown(this); this.remove(); return; } this.player.setFireTicks(0); } else { if (!this.moveBlocks()) { return; } if (this.inPosition()) { this.formArmor(); } } } @Override public void remove() { super.remove(); if (isEarthRevertOn()) { if (TempBlock.isTempBlock(this.headBlock)) { TempBlock.revertBlock(this.headBlock, Material.AIR); } if (TempBlock.isTempBlock(this.legsBlock)) { TempBlock.revertBlock(this.legsBlock, Material.AIR); } } else { this.headBlock.breakNaturally(); this.legsBlock.breakNaturally(); } if (TempArmor.getTempArmorList(this.player).contains(this.armor)) { this.armor.revert(); } this.player.removePotionEffect(PotionEffectType.ABSORPTION); if (this.oldAbsorbtion != null) { this.player.addPotionEffect(this.oldAbsorbtion); } } public void updateAbsorbtion() { final EarthArmor abil = this; new BukkitRunnable() { @Override public void run() { abil.goldHearts = EarthArmor.this.player.getAbsorptionAmount(); if (abil.formed && abil.goldHearts < 0.9F) { abil.bPlayer.addCooldown(abil); abil.player.getLocation().getWorld().playSound(abil.player.getLocation(), Sound.BLOCK_STONE_BREAK, 2, 1); abil.player.getLocation().getWorld().playSound(abil.player.getLocation(), Sound.BLOCK_STONE_BREAK, 2, 1); abil.player.getLocation().getWorld().playSound(abil.player.getLocation(), Sound.BLOCK_STONE_BREAK, 2, 1); ParticleEffect.BLOCK_CRACK.display(abil.player.getEyeLocation(), 8, 0.1, 0.1, 0.1, abil.headMaterial.createBlockData()); ParticleEffect.BLOCK_CRACK.display(abil.player.getLocation(), 8, 0.1F, 0.1F, 0.1F, abil.legsMaterial.createBlockData()); abil.remove(); } } }.runTaskLater(ProjectKorra.plugin, 1L); } public static int getColor(final Material material) { return getColor(material, (byte) 0x0); } /** Returns the color for the specified material. */ public static int getColor(final Material material, final byte damage) { if (material == Material.DIRT) { return 0xa86e45; // Default dirt brown. } if (material == Material.GRASS) { return 0xa86e45; // Default dirt brown. } if (material == Material.MYCELIUM) { return 0xa86e45; // Default dirt brown. } if (material == Material.GRASS_BLOCK) { return 0xa86e45; } if (material == Material.CLAY) { return 0xBAC2D1; // Dull gray-brown. } if (material == Material.STONE || material == Material.STONE_BRICKS) { return 0x9e9e9e; // Gray. } if (material == Material.GRANITE || material == Material.POLISHED_GRANITE) { return 0xc69489; // Pink. } if (material == Material.DIORITE || material == Material.POLISHED_DIORITE) { return 0xe3e3e5; // White. } if (material == Material.ANDESITE || material == Material.POLISHED_ANDESITE) { return 0xa3a3a3; // Gray. } if (material == Material.COBBLESTONE) { return 0x6B6B6B; // Dark Gray. } if (material == Material.SAND) { return 0xffffaf; // Sand yellow. } if (material == Material.RED_SAND) { return 0xb85f25; // Sand orange. } if (material == Material.SANDSTONE) { return 0xffffaf; // Sand. } if (material == Material.RED_SANDSTONE) { return 0xbc5a1a; // Red sandstone. } if (material == Material.GRAVEL) { return 0xaaa49e; // Dark Gray. } if (material == Material.GOLD_ORE) { return 0xa2a38f; // Gray-yellow. } if (material == Material.GOLD_BLOCK) { return 0xF1F103; // Gold - Could be a tiny bit darker. } if (material == Material.IRON_ORE) { return 0xa39d91; // Gray-brown. } if (material == Material.IRON_BLOCK) { return 0xf4f4f4; // Silver/Gray. } if (material == Material.COAL_ORE) { return 0x7c7c7c; // Stone gray. } if (material == Material.LAPIS_ORE) { return 0x9198a3; // Gray-azure. } if (material == Material.LAPIS_BLOCK) { return 0x0060BA; // Dark blue. } if (material == Material.DIAMOND_ORE) { return 0xa8bebf; // Gray-cyan. } if (material == Material.NETHERRACK) { return 0x9b3131; // Pinkish-red. } if (material == Material.NETHER_QUARTZ_ORE) { return 0xb75656; // Pinkish-red. } if (material == Material.QUARTZ_BLOCK) { return 0xfff4f4; // White. } if (material == Material.WHITE_TERRACOTTA) { return 0xCFAFA0; // White Stained Clay. } if (material == Material.ORANGE_TERRACOTTA) { return 0xA75329; // Orange. } if (material == Material.MAGENTA_TERRACOTTA) { return 0x95596E; // Magenta. } if (material == Material.LIGHT_BLUE_TERRACOTTA) { return 0x736E8A; // Light blue. } if (material == Material.YELLOW_TERRACOTTA) { return 0xBA8825; // Yellow. } if (material == Material.LIME_TERRACOTTA) { return 0x6B7736; // Lime. } if (material == Material.PINK_TERRACOTTA) { return 0xA24D4F; // Pink. } if (material == Material.GRAY_TERRACOTTA) { return 0x3A2923; // Gray. } if (material == Material.LIGHT_GRAY_TERRACOTTA) { return 0x876A61; // Light Gray. } if (material == Material.CYAN_TERRACOTTA) { return 0x575B5B; // Cyan. } if (material == Material.PURPLE_TERRACOTTA) { return 0x734453; // Purple. } if (material == Material.BLUE_TERRACOTTA) { return 0x493A5A; // Blue. } if (material == Material.BROWN_TERRACOTTA) { return 0x4C3223; // Brown. } if (material == Material.GREEN_TERRACOTTA) { return 0x4B522A; // Green. } if (material == Material.RED_TERRACOTTA) { return 0x8D3B2E; // Red. } if (material == Material.BLACK_TERRACOTTA) { return 0x251610; // Black. } return 0x9e9e9e; // Stone. } public void click() { if (!this.player.isSneaking()) { return; } this.player.getLocation().getWorld().playSound(this.player.getLocation(), Sound.BLOCK_STONE_BREAK, 2, 1); this.player.getLocation().getWorld().playSound(this.player.getLocation(), Sound.BLOCK_STONE_BREAK, 2, 1); this.player.getLocation().getWorld().playSound(this.player.getLocation(), Sound.BLOCK_STONE_BREAK, 2, 1); ParticleEffect.BLOCK_CRACK.display(this.player.getEyeLocation(), 8, 0.1, 0.1, 0.1, this.headMaterial.createBlockData()); ParticleEffect.BLOCK_CRACK.display(this.player.getLocation(), 8, 0.1F, 0.1F, 0.1F, this.legsMaterial.createBlockData()); this.bPlayer.addCooldown(this); this.remove(); } private boolean canBend() { final List disabledWorlds = getConfig().getStringList("Properties.DisabledWorlds"); final Location playerLoc = this.player.getLocation(); if (!this.player.isOnline() || this.player.isDead()) { return false; } else if (this.bPlayer.isOnCooldown("EarthArmor")) { return false; } else if (!this.bPlayer.canBind(this)) { return false; } else if (this.getPlayer() != null && this.getLocation() != null && !this.getLocation().getWorld().equals(this.player.getWorld())) { return false; } else if (disabledWorlds != null && disabledWorlds.contains(this.player.getWorld().getName())) { return false; } else if (Commands.isToggledForAll || !this.bPlayer.isToggled() || !this.bPlayer.isElementToggled(this.getElement())) { return false; } else if (this.player.getGameMode() == GameMode.SPECTATOR) { return false; } if (GeneralMethods.isRegionProtectedFromBuild(this.player, this.getName(), playerLoc)) { return false; } return true; } @Override public String getName() { return "EarthArmor"; } @Override public Location getLocation() { return this.headBlockLocation; } @Override public long getCooldown() { return this.cooldown; } @Override public boolean isSneakAbility() { return this.player != null; } @Override public boolean isHarmlessAbility() { return false; } public boolean isFormed() { return this.formed; } public void setFormed(final boolean formed) { this.formed = formed; } public Material getHeadMaterial() { return this.headMaterial; } public void setHeadMaterial(final Material material) { this.headMaterial = material; } public Material getLegsMaterial() { return this.legsMaterial; } public void setLegsMaterial(final Material material) { this.legsMaterial = material; } public double getSelectRange() { return this.selectRange; } public void setSelectRange(final double selectRange) { this.selectRange = selectRange; } public long getInterval() { return this.interval; } public void setInterval(final long interval) { this.interval = interval; } public Block getHeadBlock() { return this.headBlock; } public void setHeadBlock(final Block headBlock) { this.headBlock = headBlock; } public Block getLegsBlock() { return this.legsBlock; } public void setLegsBlock(final Block legsBlock) { this.legsBlock = legsBlock; } public Location getHeadBlockLocation() { return this.headBlockLocation; } public void setHeadBlockLocation(final Location headBlockLocation) { this.headBlockLocation = headBlockLocation; } public Location getLegsBlockLocation() { return this.legsBlockLocation; } public void setLegsBlockLocation(final Location legsBlockLocation) { this.legsBlockLocation = legsBlockLocation; } public void setCooldown(final long cooldown) { this.cooldown = cooldown; } public double getGoldHearts() { return this.goldHearts; } public int getMaxGoldHearts() { return this.maxGoldHearts; } public void setGoldHearts(final double goldHearts) { this.goldHearts = goldHearts; } public void setMaxGoldHearts(final int maxGoldHearts) { this.maxGoldHearts = maxGoldHearts; } }