From 44bf1c361fe78136d08d4eb57608bfd515746b59 Mon Sep 17 00:00:00 2001 From: MistPhizzle Date: Tue, 24 Jun 2014 21:18:44 -0400 Subject: [PATCH] AirSpout --- .../ProjectKorra/BendingManager.java | 2 + .../ProjectKorra/ConfigManager.java | 8 + src/com/projectkorra/ProjectKorra/Flight.java | 1 + .../projectkorra/ProjectKorra/PKListener.java | 23 +++ .../ProjectKorra/airbending/AirSpout.java | 188 ++++++++++++++++++ src/config.yml | 4 + 6 files changed, 226 insertions(+) create mode 100644 src/com/projectkorra/ProjectKorra/airbending/AirSpout.java diff --git a/src/com/projectkorra/ProjectKorra/BendingManager.java b/src/com/projectkorra/ProjectKorra/BendingManager.java index b8d45abc..b8a9a4e6 100644 --- a/src/com/projectkorra/ProjectKorra/BendingManager.java +++ b/src/com/projectkorra/ProjectKorra/BendingManager.java @@ -16,6 +16,7 @@ import com.projectkorra.ProjectKorra.airbending.AirBlast; import com.projectkorra.ProjectKorra.airbending.AirBurst; import com.projectkorra.ProjectKorra.airbending.AirPassive; import com.projectkorra.ProjectKorra.airbending.AirScooter; +import com.projectkorra.ProjectKorra.airbending.AirSpout; import com.projectkorra.ProjectKorra.airbending.Tornado; import com.projectkorra.ProjectKorra.chiblocking.ChiPassive; import com.projectkorra.ProjectKorra.earthbending.EarthPassive; @@ -67,6 +68,7 @@ public class BendingManager implements Runnable { Bloodbending.progressAll(); FireJet.progressAll(); AirScooter.progressAll(); + AirSpout.spoutAll(); for (int ID: Tornado.instances.keySet()) { Tornado.progress(ID); diff --git a/src/com/projectkorra/ProjectKorra/ConfigManager.java b/src/com/projectkorra/ProjectKorra/ConfigManager.java index 5433900e..cc0d04f3 100644 --- a/src/com/projectkorra/ProjectKorra/ConfigManager.java +++ b/src/com/projectkorra/ProjectKorra/ConfigManager.java @@ -100,6 +100,14 @@ public class ConfigManager { + "fall out of the vortex, it will take him to a maximum height and move him in " + "the general direction he's looking. Skilled airbenders can scale anything " + "with this ability."); + + config.addDefault("Abilities.Air.AirSpout.Enabled", true); + config.addDefault("Abilities.Air.AirSpout.Description", "This ability gives the airbender limited sustained levitation. It is a " + + "toggle - click to activate and form a whirling spout of air " + + "beneath you, lifting you up. You can bend other abilities while using AirSpout. " + + "Click again to deactivate this ability."); + config.addDefault("Abilities.Air.AirSpout.Height", 20); + config.addDefault("Abilities.Air.Tornado.Radius", 10); config.addDefault("Abilities.Air.Tornado.Height", 25); config.addDefault("Abilities.Air.Tornado.Range", 25); diff --git a/src/com/projectkorra/ProjectKorra/Flight.java b/src/com/projectkorra/ProjectKorra/Flight.java index 4dee471e..1c3e0813 100644 --- a/src/com/projectkorra/ProjectKorra/Flight.java +++ b/src/com/projectkorra/ProjectKorra/Flight.java @@ -8,6 +8,7 @@ import org.bukkit.entity.Player; import com.projectkorra.ProjectKorra.Ability.AvatarState; import com.projectkorra.ProjectKorra.airbending.AirScooter; +import com.projectkorra.ProjectKorra.airbending.AirSpout; import com.projectkorra.ProjectKorra.airbending.Tornado; import com.projectkorra.ProjectKorra.firebending.FireJet; import com.projectkorra.ProjectKorra.waterbending.Bloodbending; diff --git a/src/com/projectkorra/ProjectKorra/PKListener.java b/src/com/projectkorra/ProjectKorra/PKListener.java index b10c5f5f..c721fad6 100644 --- a/src/com/projectkorra/ProjectKorra/PKListener.java +++ b/src/com/projectkorra/ProjectKorra/PKListener.java @@ -45,6 +45,7 @@ import com.projectkorra.ProjectKorra.Ability.AvatarState; import com.projectkorra.ProjectKorra.airbending.AirBlast; import com.projectkorra.ProjectKorra.airbending.AirBurst; import com.projectkorra.ProjectKorra.airbending.AirScooter; +import com.projectkorra.ProjectKorra.airbending.AirSpout; import com.projectkorra.ProjectKorra.airbending.Tornado; import com.projectkorra.ProjectKorra.chiblocking.ChiPassive; import com.projectkorra.ProjectKorra.chiblocking.Paralyze; @@ -170,6 +171,25 @@ public class PKListener implements Listener { event.setCancelled(true); return; } + + if (WaterSpout.instances.containsKey(event.getPlayer()) || AirSpout.getPlayers().contains(event.getPlayer())) { + Vector vel = new Vector(); + vel.setX(event.getTo().getX() - event.getFrom().getX()); + vel.setY(event.getTo().getY() - event.getFrom().getY()); + vel.setZ(event.getTo().getZ() - event.getFrom().getZ()); + // You now know the old velocity. Set to match recommended velocity + double currspeed = vel.length(); + double maxspeed = .15; + if (currspeed > maxspeed) { + // only if moving set a factor + // double recspeed = 0.6; + // vel = vel.ultiply(recspeed * currspeed); + vel = vel.normalize().multiply(maxspeed); + // apply the new velocity (MAY REQUIRE A SCHEDULED TASK + // INSTEAD!) + event.getPlayer().setVelocity(vel); + } + } if (Bloodbending.isBloodbended(player)) { double distance1, distance2; @@ -277,6 +297,9 @@ public class PKListener implements Listener { if (abil.equalsIgnoreCase("AirScooter")) { new AirScooter(player); } + if (abil.equalsIgnoreCase("AirSpout")) { + new AirSpout(player); + } } if (Methods.isWaterAbility(abil)) { if (Methods.isWeapon(player.getItemInHand().getType()) && !plugin.getConfig().getBoolean("Properties.Water.CanBendWithWeapons")) { diff --git a/src/com/projectkorra/ProjectKorra/airbending/AirSpout.java b/src/com/projectkorra/ProjectKorra/airbending/AirSpout.java new file mode 100644 index 00000000..7d177d94 --- /dev/null +++ b/src/com/projectkorra/ProjectKorra/airbending/AirSpout.java @@ -0,0 +1,188 @@ +package com.projectkorra.ProjectKorra.airbending; + +import java.util.ArrayList; +import java.util.concurrent.ConcurrentHashMap; + +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Player; + +import com.projectkorra.ProjectKorra.Flight; +import com.projectkorra.ProjectKorra.Methods; +import com.projectkorra.ProjectKorra.ProjectKorra; + +public class AirSpout { + + private static ConcurrentHashMap instances = new ConcurrentHashMap(); + + private static final double height = ProjectKorra.plugin.getConfig().getDouble("Abilities.Air.AirSpout.Height"); + private static final long interval = 100; + + private Player player; + private long time; + private int angle = 0; + + public AirSpout(Player player) { +// BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player); +// +// if (bPlayer.isOnCooldown(Abilities.AirSpout)) +// return; + + if (instances.containsKey(player)) { + instances.get(player).remove(); + return; + } + this.player = player; + time = System.currentTimeMillis(); + new Flight(player); + instances.put(player, this); +// bPlayer.cooldown(Abilities.AirSpout); + spout(); + } + + public static void spoutAll() { + for (Player player : instances.keySet()) { + instances.get(player).spout(); + } + } + + public static ArrayList getPlayers() { + ArrayList players = new ArrayList(); + players.addAll(instances.keySet()); + return players; + } + + private void spout() { + if (!Methods.canBend(player.getName(), "AirSpout") +// || !Methods.hasAbility(player, Abilities.AirSpout) + || player.getEyeLocation().getBlock().isLiquid() + || Methods.isSolid(player.getEyeLocation().getBlock()) + || player.isDead() || !player.isOnline()) { + remove(); + return; + } + player.setFallDistance(0); + player.setSprinting(false); + Block block = getGround(); + if (block != null) { + double dy = player.getLocation().getY() - block.getY(); + if (dy > height) { + removeFlight(); + } else { + allowFlight(); + } + rotateAirColumn(block); + } else { + remove(); + } + } + + private void allowFlight() { + player.setAllowFlight(true); + player.setFlying(true); + // flight speed too + } + + private void removeFlight() { + player.setAllowFlight(false); + player.setFlying(false); + // player.setAllowFlight(player.getGameMode() == GameMode.CREATIVE); + // flight speed too + } + + private Block getGround() { + Block standingblock = player.getLocation().getBlock(); + for (int i = 0; i <= height + 5; i++) { + Block block = standingblock.getRelative(BlockFace.DOWN, i); + if (Methods.isSolid(block) || block.isLiquid()) { + return block; + } + } + return null; + } + + private void rotateAirColumn(Block block) { + + if (System.currentTimeMillis() >= time + interval) { + time = System.currentTimeMillis(); + + Location location = block.getLocation(); + Location playerloc = player.getLocation(); + location = new Location(location.getWorld(), playerloc.getX(), + location.getY(), playerloc.getZ()); + + double dy = playerloc.getY() - block.getY(); + if (dy > height) + dy = height; + Integer[] directions = { 0, 1, 2, 3, 5, 6, 7, 8 }; + int index = angle; + + angle++; + if (angle >= directions.length) + angle = 0; + for (int i = 1; i <= dy; i++) { + + index += 1; + if (index >= directions.length) + index = 0; + + Location effectloc2 = new Location(location.getWorld(), + location.getX(), block.getY() + i, location.getZ()); + + location.getWorld().playEffect(effectloc2, Effect.SMOKE, + (int) directions[index], (int) height + 5); + + // Methods.verbose(directions[index]); + + // location.getWorld().playEffect(effectloc2, Effect.SMOKE, 0, + // (int) height + 5); + // location.getWorld().playEffect(effectloc2, Effect.SMOKE, 1, + // (int) height + 5); + // location.getWorld().playEffect(effectloc2, Effect.SMOKE, 2, + // (int) height + 5); + // location.getWorld().playEffect(effectloc2, Effect.SMOKE, 3, + // (int) height + 5); + // location.getWorld().playEffect(effectloc2, Effect.SMOKE, 5, + // (int) height + 5); + // location.getWorld().playEffect(effectloc2, Effect.SMOKE, 6, + // (int) height + 5); + // location.getWorld().playEffect(effectloc2, Effect.SMOKE, 7, + // (int) height + 5); + // location.getWorld().playEffect(effectloc2, Effect.SMOKE, 8, + // (int) height + 5); + } + } + } + + public static void removeSpouts(Location loc0, double radius, + Player sourceplayer) { + for (Player player : instances.keySet()) { + if (!player.equals(sourceplayer)) { + Location loc1 = player.getLocation().getBlock().getLocation(); + loc0 = loc0.getBlock().getLocation(); + double dx = loc1.getX() - loc0.getX(); + double dy = loc1.getY() - loc0.getY(); + double dz = loc1.getZ() - loc0.getZ(); + + double distance = Math.sqrt(dx * dx + dz * dz); + + if (distance <= radius && dy > 0 && dy < height) + instances.get(player).remove(); + } + } + } + + private void remove() { + removeFlight(); + instances.remove(player); + } + + public static void removeAll() { + for (Player player : instances.keySet()) { + instances.get(player).remove(); + } + } + +} \ No newline at end of file diff --git a/src/config.yml b/src/config.yml index 0f3e3d09..5f73870e 100644 --- a/src/config.yml +++ b/src/config.yml @@ -58,6 +58,10 @@ Abilities: Enabled: true Description: "AirScooter is a fast means of transportation. To use, sprint, jump then click with this ability selected. YOu will hop on a scooter of air and be propelled forward in the direction you're looking (you don't need to press anything). This ability can be used to levitate above liquids, but it cannot go up steep slopes. Any other actions will deactivate this ability." Speed: 0.675 + AirSpout: + Enabled: true + Description: "This ability gives the airbender limited sustained levitation. It is a toggle - click to activate and form a whirling spout of air beneath you, lifting you up. You can bend other abilities while using AirSpout. Click again to deactivate this ability." + Height: 20 Tornado: Enabled: true Description: "To use, simply sneak (default: shift). This will create a swirling vortex at the targeted lcoation. Any creature or object caught in the vortex will be launched up and out in some random direction. If another player gets caught in the vortex, the launching effect is minimal. Tornado can also be used to transport the user. If the user gets caught in his/her own tornado, his/her movements are much more manageable. Provided the user doesn't fall out of the vortex, it will take him to a maximum height and move him in the general direction he/she is looking. Skilled airbenders can scale anything with this ability."