diff --git a/src/com/projectkorra/ProjectKorra/BendingManager.java b/src/com/projectkorra/ProjectKorra/BendingManager.java index 624565a9..11b44647 100644 --- a/src/com/projectkorra/ProjectKorra/BendingManager.java +++ b/src/com/projectkorra/ProjectKorra/BendingManager.java @@ -38,6 +38,7 @@ import com.projectkorra.ProjectKorra.firebending.FireBlast; import com.projectkorra.ProjectKorra.firebending.FireBurst; import com.projectkorra.ProjectKorra.firebending.FireJet; import com.projectkorra.ProjectKorra.firebending.FirePassive; +import com.projectkorra.ProjectKorra.firebending.FireShield; import com.projectkorra.ProjectKorra.firebending.FireStream; import com.projectkorra.ProjectKorra.firebending.Fireball; import com.projectkorra.ProjectKorra.firebending.Illumination; @@ -111,6 +112,7 @@ public class BendingManager implements Runnable { Fireball.progressAll(); HealingWaters.heal(Bukkit.getServer()); FireBurst.progressAll(); + FireShield.progressAll(); for (Player p : RapidPunch.instance.keySet()) RapidPunch.instance.get(p).startPunch(p); diff --git a/src/com/projectkorra/ProjectKorra/ConfigManager.java b/src/com/projectkorra/ProjectKorra/ConfigManager.java index 455c0782..9b961004 100644 --- a/src/com/projectkorra/ProjectKorra/ConfigManager.java +++ b/src/com/projectkorra/ProjectKorra/ConfigManager.java @@ -361,17 +361,25 @@ public class ConfigManager { + "To use, press and hold sneak to charge your burst. " + "Once charged, you can either release sneak to launch a cone-shaped burst " + "of flames in front of you, or click to release the burst in a sphere around you. "); + config.addDefault("Abilities.Fire.FireJet.Enabled", true); config.addDefault("Abilities.Fire.FireJet.Description", "This ability is used for a limited burst of flight for firebenders. Clicking with this " + "ability selected will launch you in the direction you're looking, granting you " + "controlled flight for a short time. This ability can be used mid-air to prevent falling " + "to your death, but on the ground it can only be used if standing on a block that's " + "ignitable (e.g. not snow or water)."); - config.addDefault("Abilities.Fire.FireJet.Speed", 0.7); config.addDefault("Abilities.Fire.FireJet.Duration", 1500); config.addDefault("Abilities.Fire.FireJet.Cooldown", 6000); + config.addDefault("Abilities.Fire.FireShield.Enabled", true); + config.addDefault("Abilities.Fire.FireShield.Description", "FireShield is a basic defensive ability. " + + "Clicking with this ability selected will create a " + + "small disc of fire in front of you, which will block most " + + "attacks and bending. Alternatively, pressing and holding " + + "sneak creates a very small shield of fire, blocking most attacks. " + + "Creatures that contact this fire are ignited."); + config.addDefault("Abilities.Fire.HeatControl.Enabled", true); config.addDefault("Abilities.Fire.HeatControl.Description", "While this ability is selected, the firebender becomes impervious " + "to fire damage and cannot be ignited. " diff --git a/src/com/projectkorra/ProjectKorra/PKListener.java b/src/com/projectkorra/ProjectKorra/PKListener.java index 08f17c2a..48609746 100644 --- a/src/com/projectkorra/ProjectKorra/PKListener.java +++ b/src/com/projectkorra/ProjectKorra/PKListener.java @@ -84,6 +84,7 @@ import com.projectkorra.ProjectKorra.firebending.Extinguish; import com.projectkorra.ProjectKorra.firebending.FireBlast; import com.projectkorra.ProjectKorra.firebending.FireBurst; import com.projectkorra.ProjectKorra.firebending.FireJet; +import com.projectkorra.ProjectKorra.firebending.FireShield; import com.projectkorra.ProjectKorra.firebending.FireStream; import com.projectkorra.ProjectKorra.firebending.Fireball; import com.projectkorra.ProjectKorra.firebending.Illumination; @@ -308,6 +309,9 @@ public class PKListener implements Listener { if (abil.equalsIgnoreCase("FireBurst")) { new FireBurst(player); } + if (abil.equalsIgnoreCase("FireShield")) { + FireShield.shield(player); + } } } } @@ -581,6 +585,9 @@ public class PKListener implements Listener { if (abil.equalsIgnoreCase("FireBurst")) { FireBurst.coneBurst(player); } + if (abil.equalsIgnoreCase("FireShield")) { + new FireShield(player); + } } if (Methods.isChiAbility(abil)) { diff --git a/src/com/projectkorra/ProjectKorra/firebending/FireShield.java b/src/com/projectkorra/ProjectKorra/firebending/FireShield.java new file mode 100644 index 00000000..33ab13bb --- /dev/null +++ b/src/com/projectkorra/ProjectKorra/firebending/FireShield.java @@ -0,0 +1,207 @@ +package com.projectkorra.ProjectKorra.firebending; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import com.projectkorra.ProjectKorra.Methods; +import com.projectkorra.ProjectKorra.ProjectKorra; +import com.projectkorra.ProjectKorra.earthbending.EarthBlast; +import com.projectkorra.ProjectKorra.waterbending.WaterManipulation; + +public class FireShield { + + private static ConcurrentHashMap instances = new ConcurrentHashMap(); + private static Map cooldowns = new HashMap(); + + private static long interval = 100; + private static double radius = 3; + private static double discradius = 1.5; + private static long duration = 1000; + private static boolean ignite = true; + + private Player player; + private long time; + private long starttime; + private boolean shield = false; + + public FireShield(Player player) { + this(player, false); + } + + public FireShield(Player player, boolean shield) { + this.player = player; + this.shield = shield; + if (instances.containsKey(player)) + return; + if (cooldowns.containsKey(player.getName())) { + if (cooldowns.get(player.getName()) + ProjectKorra.plugin.getConfig().getLong("Properties.GlobalCooldown") >= System.currentTimeMillis()) { + return; + } else { + cooldowns.remove(player.getName()); + } + } + + if (!player.getEyeLocation().getBlock().isLiquid()) { + time = System.currentTimeMillis(); + starttime = time; + instances.put(player, this); + if (!shield) + cooldowns.put(player.getName(), System.currentTimeMillis()); + } + } + + public static void shield(Player player) { + new FireShield(player, true); + } + + private void remove() { + instances.remove(player); + } + + private void progress() { + if (((!player.isSneaking()) && shield) + || !Methods.canBend(player.getName(), "FireShield")) { + remove(); + return; + } + + if (!player.isOnline() || player.isDead()) { + remove(); + return; + } + + if (System.currentTimeMillis() > starttime + duration && !shield) { + remove(); + return; + } + + if (System.currentTimeMillis() > time + interval) { + time = System.currentTimeMillis(); + + if (shield) { + + ArrayList blocks = new ArrayList(); + Location location = player.getEyeLocation().clone(); + + for (double theta = 0; theta < 180; theta += 20) { + for (double phi = 0; phi < 360; phi += 20) { + double rphi = Math.toRadians(phi); + double rtheta = Math.toRadians(theta); + Block block = location + .clone() + .add(radius * Math.cos(rphi) * Math.sin(rtheta), + radius * Math.cos(rtheta), + radius * Math.sin(rphi) + * Math.sin(rtheta)).getBlock(); + if (!blocks.contains(block) && !Methods.isSolid(block) + && !block.isLiquid()) + blocks.add(block); + } + } + + for (Block block : blocks) { +// if (!Methods.isRegionProtectedFromBuild(player, +// Abilities.FireShield, block.getLocation())) + block.getWorld().playEffect(block.getLocation(), + Effect.MOBSPAWNER_FLAMES, 0, 20); + } + + for (Entity entity : Methods.getEntitiesAroundPoint(location, + radius)) { +// if (Methods.isRegionProtectedFromBuild(player, +// Abilities.FireShield, entity.getLocation())) +// continue; + if (player.getEntityId() != entity.getEntityId() && ignite) { + entity.setFireTicks(120); + new Enflamed(entity, player); + } + } + + FireBlast.removeFireBlastsAroundPoint(location, radius); + // WaterManipulation.removeAroundPoint(location, radius); + // EarthBlast.removeAroundPoint(location, radius); + // FireStream.removeAroundPoint(location, radius); + + } else { + + ArrayList blocks = new ArrayList(); + Location location = player.getEyeLocation().clone(); + Vector direction = location.getDirection(); + location = location.clone().add(direction.multiply(radius)); + +// if (Methods.isRegionProtectedFromBuild(player, +// Abilities.FireShield, location)) { +// remove(); +// return; +// } + + for (double theta = 0; theta < 360; theta += 20) { + Vector vector = Methods.getOrthogonalVector(direction, theta, + discradius); + + Block block = location.clone().add(vector).getBlock(); + if (!blocks.contains(block) && !Methods.isSolid(block) + && !block.isLiquid()) + blocks.add(block); + + } + + for (Block block : blocks) { +// if (!Methods.isRegionProtectedFromBuild(player, +// Abilities.FireShield, block.getLocation())) + block.getWorld().playEffect(block.getLocation(), + Effect.MOBSPAWNER_FLAMES, 0, 20); + } + + for (Entity entity : Methods.getEntitiesAroundPoint(location, + discradius)) { +// if (Methods.isRegionProtectedFromBuild(player, +// Abilities.FireShield, entity.getLocation())) +// continue; + if (player.getEntityId() != entity.getEntityId() && ignite) { + entity.setFireTicks(120); + if (!(entity instanceof LivingEntity)) { + entity.remove(); + } + } + } + + FireBlast.removeFireBlastsAroundPoint(location, discradius); + WaterManipulation.removeAroundPoint(location, discradius); + EarthBlast.removeAroundPoint(location, discradius); + FireStream.removeAroundPoint(location, discradius); + + } + + } + } + + public static void progressAll() { + for (Player player : instances.keySet()) + instances.get(player).progress(); + } + + public static String getDescription() { + return "FireShield is a basic defensive ability. " + + "Clicking with this ability selected will create a " + + "small disc of fire in front of you, which will block most " + + "attacks and bending. Alternatively, pressing and holding " + + "sneak creates a very small shield of fire, blocking most attacks. " + + "Creatures that contact this fire are ignited."; + } + + public static void removeAll() { + instances.clear(); + + } +} diff --git a/src/config.yml b/src/config.yml index f71c71fb..8f95d261 100644 --- a/src/config.yml +++ b/src/config.yml @@ -255,6 +255,9 @@ Abilities: Speed: 0.7 Duration: 1500 Cooldown: 6000 + FireShield: + Enabled: true + Description: "FireShield is a basic defensive ability. Clicking with this ability selected will create a small disc of fire in front of you, which will block most attacks and bending. Alternatively, pressing and holding sneak creates a very small shield of fire, blocking most attacks. Creatures that contact this fire are ignited." HeatControl: Enabled: true Description: "While this ability is selected, the firebender becomes impervious to fire damage and cannot be ignited. If the user left-clicks with this ability, the targeted area will be extinguished, although it will leave any creature burning engulfed in flames. This ability can also cool lava. If this ability is used while targeting ice or snow, it will instead melt blocks in that area. Finally, sneaking with this ability will cook any food in your hand."