AirSuction

This commit is contained in:
MistPhizzle 2014-06-26 19:26:48 -04:00
parent d07e5af788
commit 03d961c6cc
5 changed files with 337 additions and 0 deletions

View file

@ -19,6 +19,7 @@ import com.projectkorra.ProjectKorra.airbending.AirPassive;
import com.projectkorra.ProjectKorra.airbending.AirScooter; import com.projectkorra.ProjectKorra.airbending.AirScooter;
import com.projectkorra.ProjectKorra.airbending.AirShield; import com.projectkorra.ProjectKorra.airbending.AirShield;
import com.projectkorra.ProjectKorra.airbending.AirSpout; import com.projectkorra.ProjectKorra.airbending.AirSpout;
import com.projectkorra.ProjectKorra.airbending.AirSuction;
import com.projectkorra.ProjectKorra.airbending.Tornado; import com.projectkorra.ProjectKorra.airbending.Tornado;
import com.projectkorra.ProjectKorra.chiblocking.ChiPassive; import com.projectkorra.ProjectKorra.chiblocking.ChiPassive;
import com.projectkorra.ProjectKorra.earthbending.Catapult; import com.projectkorra.ProjectKorra.earthbending.Catapult;
@ -99,6 +100,7 @@ public class BendingManager implements Runnable {
Torrent.progressAll(); Torrent.progressAll();
TorrentBurst.progressAll(); TorrentBurst.progressAll();
FireBlast.progressAll(); FireBlast.progressAll();
AirSuction.progressAll();
Fireball.progressAll(); Fireball.progressAll();
for (int ID: Tornado.instances.keySet()) { for (int ID: Tornado.instances.keySet()) {
Tornado.progress(ID); Tornado.progress(ID);

View file

@ -121,6 +121,13 @@ public class ConfigManager {
+ "Click again to deactivate this ability."); + "Click again to deactivate this ability.");
config.addDefault("Abilities.Air.AirSpout.Height", 20); config.addDefault("Abilities.Air.AirSpout.Height", 20);
config.addDefault("Abilities.Air.AirSuction.Enabled", true);
config.addDefault("Abilities.Air.AirSuction.Description", "To use, simply left-click in a direction. A gust of wind will originate as far as it can in that direction and flow towards you, sucking anything in its path harmlessly with it. Skilled benders can use this technique to pull items from precarious locations. Additionally, tapping sneak will change the origin of your next AirSuction to your targeted location.");
config.addDefault("Abilities.Air.AirSuction.Speed", 25);
config.addDefault("Abilities.Air.AirSuction.Range", 20);
config.addDefault("Abilities.Air.AirSuction.Radius", 2);
config.addDefault("Abilities.Air.AirSuction.Push", 3.5);
config.addDefault("Abilities.Air.Tornado.Radius", 10); config.addDefault("Abilities.Air.Tornado.Radius", 10);
config.addDefault("Abilities.Air.Tornado.Height", 25); config.addDefault("Abilities.Air.Tornado.Height", 25);
config.addDefault("Abilities.Air.Tornado.Range", 25); config.addDefault("Abilities.Air.Tornado.Range", 25);

View file

@ -49,6 +49,7 @@ import com.projectkorra.ProjectKorra.airbending.AirBurst;
import com.projectkorra.ProjectKorra.airbending.AirScooter; import com.projectkorra.ProjectKorra.airbending.AirScooter;
import com.projectkorra.ProjectKorra.airbending.AirShield; import com.projectkorra.ProjectKorra.airbending.AirShield;
import com.projectkorra.ProjectKorra.airbending.AirSpout; import com.projectkorra.ProjectKorra.airbending.AirSpout;
import com.projectkorra.ProjectKorra.airbending.AirSuction;
import com.projectkorra.ProjectKorra.airbending.Tornado; import com.projectkorra.ProjectKorra.airbending.Tornado;
import com.projectkorra.ProjectKorra.chiblocking.ChiPassive; import com.projectkorra.ProjectKorra.chiblocking.ChiPassive;
import com.projectkorra.ProjectKorra.chiblocking.Paralyze; import com.projectkorra.ProjectKorra.chiblocking.Paralyze;
@ -183,6 +184,9 @@ public class PKListener implements Listener {
if (abil.equalsIgnoreCase("AirBurst")) { if (abil.equalsIgnoreCase("AirBurst")) {
new AirBurst(player); new AirBurst(player);
} }
if (abil.equalsIgnoreCase("AirSuction")) {
AirSuction.setOrigin(player);
}
} }
if (Methods.isWaterAbility(abil)) { if (Methods.isWaterAbility(abil)) {
@ -410,6 +414,9 @@ public class PKListener implements Listener {
if (abil.equalsIgnoreCase("AirBlast")) { if (abil.equalsIgnoreCase("AirBlast")) {
new AirBlast(player); new AirBlast(player);
} }
if (abil.equalsIgnoreCase("AirSuction")) {
new AirSuction(player);
}
if (abil.equalsIgnoreCase("AirBurst")) { if (abil.equalsIgnoreCase("AirBurst")) {
AirBurst.coneBurst(player); AirBurst.coneBurst(player);
} }

View file

@ -0,0 +1,318 @@
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.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import com.projectkorra.ProjectKorra.Flight;
import com.projectkorra.ProjectKorra.Methods;
import com.projectkorra.ProjectKorra.ProjectKorra;
import com.projectkorra.ProjectKorra.Ability.AvatarState;
import com.projectkorra.ProjectKorra.waterbending.WaterSpout;
public class AirSuction {
public static ConcurrentHashMap<Integer, AirSuction> instances = new ConcurrentHashMap<Integer, AirSuction>();
private static ConcurrentHashMap<Player, Location> origins = new ConcurrentHashMap<Player, Location>();
private static ConcurrentHashMap<String, Long> cooldowns = new ConcurrentHashMap<String, Long>();
// private static ConcurrentHashMap<Player, Long> timers = new
// ConcurrentHashMap<Player, Long>();
static final long soonesttime = ProjectKorra.plugin.getConfig().getLong("Properties.GlobalCooldown");
private static int ID = Integer.MIN_VALUE;
private static final int maxticks = AirBlast.maxticks;
static final double maxspeed = AirBlast.maxspeed;
private static double speed = ProjectKorra.plugin.getConfig().getDouble("Abilities.Air.AirSuction.Speed");
private static double range = ProjectKorra.plugin.getConfig().getDouble("Abilities.Air.AirSuction.Range");
private static double affectingradius = ProjectKorra.plugin.getConfig().getDouble("Abilities.Air.AirSuction.Radius");
private static double pushfactor = ProjectKorra.plugin.getConfig().getDouble("Abilities.Air.AirSuction.Push");
private static double originselectrange = 10;
// private static long interval = AirBlast.interval;
private Location location;
private Location origin;
private Vector direction;
private Player player;
private boolean otherorigin = false;
private int id;
private int ticks = 0;
// private long time;
private double speedfactor;
private ArrayList<Entity> affectedentities = new ArrayList<Entity>();
public AirSuction(Player player) {
// if (timers.containsKey(player)) {
// if (System.currentTimeMillis() < timers.get(player) + soonesttime) {
// return;
// }
// }
if (cooldowns.containsKey(player.getName())) {
if (cooldowns.get(player.getName()) + soonesttime >= System.currentTimeMillis()) {
return;
} else {
cooldowns.remove(player.getName());
}
}
if (player.getEyeLocation().getBlock().isLiquid()) {
return;
}
if (AirSpout.getPlayers().contains(player)
|| WaterSpout.getPlayers().contains(player))
return;
// timers.put(player, System.currentTimeMillis());
this.player = player;
if (origins.containsKey(player)) {
origin = origins.get(player);
otherorigin = true;
origins.remove(player);
} else {
origin = player.getEyeLocation();
}
// if (origins.containsKey(player)) {
// origin = origins.get(player);
// otherorigin = true;
// location = Methods.getTargetedLocation(player, range);
// origins.remove(player);
// Entity entity = Methods.getTargettedEntity(player, range);
// if (entity != null) {
// direction = Methods.getDirection(entity.getLocation(), origin)
// .normalize();
// location = origin.clone().add(
// direction.clone().multiply(-range));
// } else {
// direction = Methods.getDirection(location, origin).normalize();
// }
//
// } else {
location = Methods.getTargetedLocation(player, range, Methods.nonOpaque);
direction = Methods.getDirection(location, origin).normalize();
Entity entity = Methods.getTargetedEntity(player, range, new ArrayList<Entity>());
if (entity != null) {
direction = Methods.getDirection(entity.getLocation(), origin)
.normalize();
location = getLocation(origin, direction.clone().multiply(-1));
// location =
// origin.clone().add(direction.clone().multiply(-range));
}
// }
id = ID;
instances.put(id, this);
cooldowns.put(player.getName(), System.currentTimeMillis());
if (ID == Integer.MAX_VALUE)
ID = Integer.MIN_VALUE;
ID++;
// time = System.currentTimeMillis();
// timers.put(player, System.currentTimeMillis());
}
private Location getLocation(Location origin, Vector direction) {
Location location = origin.clone();
for (double i = 1; i <= range; i++) {
location = origin.clone().add(direction.clone().multiply(i));
if (!Methods.isTransparentToEarthbending(player, location.getBlock())) {
return origin.clone().add(direction.clone().multiply(i - 1));
}
}
return location;
}
public static void setOrigin(Player player) {
Location location = Methods.getTargetedLocation(player,
originselectrange, Methods.nonOpaque);
if (location.getBlock().isLiquid()
|| Methods.isSolid(location.getBlock()))
return;
//
// if (Methods.isRegionProtectedFromBuild(player, Abilities.AirSuction,
// location))
// return;
if (origins.containsKey(player)) {
origins.replace(player, location);
} else {
origins.put(player, location);
}
}
public boolean progress() {
if (player.isDead() || !player.isOnline()) {
instances.remove(id);
return false;
}
// if (Methods.isRegionProtectedFromBuild(player, Abilities.AirSuction,
// location)) {
// instances.remove(id);
// return false;
// }
speedfactor = speed * (ProjectKorra.time_step / 1000.);
ticks++;
if (ticks > maxticks) {
instances.remove(id);
return false;
}
// if (player.isSneaking()
// && Methods.getBendingAbility(player) == Abilities.AirSuction) {
// new AirSuction(player);
// }
if ((location.distance(origin) > range)
|| (location.distance(origin) <= 1)) {
instances.remove(id);
return false;
}
for (Entity entity : Methods.getEntitiesAroundPoint(location,
affectingradius)) {
// if (affectedentities.contains(entity))
// continue;
// affectedentities.add(entity);
if (entity.getEntityId() != player.getEntityId() || otherorigin) {
// Vector velocity = entity.getVelocity();
// double mag = Math.abs(velocity.getY());
// double max = maxspeed;
// if (AvatarState.isAvatarState(player)) {
// max = AvatarState.getValue(maxspeed);
// velocity = velocity.clone().add(
// direction.clone().multiply(
// AvatarState.getValue(pushfactor)));
// double newmag = Math.abs(velocity.getY());
// if (newmag > mag) {
// if (mag > max) {
// velocity = velocity.clone().multiply(mag / newmag);
// } else if (newmag > max) {
// velocity = velocity.clone().multiply(max / newmag);
// }
// }
// } else {
// velocity = velocity.clone().add(
// direction.clone().multiply(pushfactor));
// double newmag = Math.abs(velocity.getY());
// if (newmag > mag) {
// if (mag > max) {
// velocity = velocity.clone().multiply(mag / newmag);
// } else if (newmag > max) {
// velocity = velocity.clone().multiply(max / newmag);
// }
// }
// }
// if (entity instanceof Player)
// velocity.multiply(2);
// entity.setVelocity(velocity);
// entity.setFallDistance(0);
Vector velocity = entity.getVelocity();
double max = maxspeed;
double factor = pushfactor;
if (AvatarState.isAvatarState(player)) {
max = AvatarState.getValue(maxspeed);
factor = AvatarState.getValue(factor);
}
Vector push = direction.clone();
if (Math.abs(push.getY()) > max
&& entity.getEntityId() != player.getEntityId()) {
if (push.getY() < 0)
push.setY(-max);
else
push.setY(max);
}
factor *= 1 - location.distance(origin) / (2 * range);
double comp = velocity.dot(push.clone().normalize());
if (comp > factor) {
velocity.multiply(.5);
velocity.add(push
.clone()
.normalize()
.multiply(
velocity.clone().dot(
push.clone().normalize())));
} else if (comp + factor * .5 > factor) {
velocity.add(push.clone().multiply(factor - comp));
} else {
velocity.add(push.clone().multiply(factor * .5));
}
entity.setVelocity(velocity);
entity.setFallDistance(0);
if (entity.getEntityId() != player.getEntityId()
&& entity instanceof Player) {
new Flight((Player) entity, player);
}
if (entity.getFireTicks() > 0)
entity.getWorld().playEffect(entity.getLocation(),
Effect.EXTINGUISH, 0);
entity.setFireTicks(0);
}
}
advanceLocation();
return true;
}
private void advanceLocation() {
location.getWorld().playEffect(location, Effect.SMOKE, 4,
(int) AirBlast.defaultrange);
location = location.add(direction.clone().multiply(speedfactor));
}
public static void progressAll() {
for (int id : instances.keySet())
instances.get(id).progress();
for (Player player : origins.keySet()) {
playOriginEffect(player);
}
}
private static void playOriginEffect(Player player) {
if (!origins.containsKey(player))
return;
Location origin = origins.get(player);
if (!origin.getWorld().equals(player.getWorld())) {
origins.remove(player);
return;
}
if (Methods.getBoundAbility(player) == null) {
origins.remove(player);
return;
}
if (!Methods.getBoundAbility(player).equalsIgnoreCase("AirSuction") || !Methods.canBend(player.getName(), "AirSuction")) {
origins.remove(player);
return;
}
if (origin.distance(player.getEyeLocation()) > originselectrange) {
origins.remove(player);
return;
}
origin.getWorld().playEffect(origin, Effect.SMOKE, 4,
(int) originselectrange);
}
public static String getDescription() {
return "To use, simply left-click in a direction. "
+ "A gust of wind will originate as far as it can in that direction"
+ " and flow towards you, sucking anything in its path harmlessly with it."
+ " Skilled benders can use this technique to pull items from precarious locations. "
+ "Additionally, tapping sneak will change the origin of your next "
+ "AirSuction to your targeted location.";
}
}

View file

@ -70,6 +70,9 @@ Abilities:
Enabled: true 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." 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 Height: 20
AirSuction:
Enabled: true
Description: "To use, simply left-click in a direction. A gust of wind will originate as far as it can in that direction and flow towards you, sucking anything in its path harmlessly with it. Skilled benders can use this technique to pull items from precarious locations. Additionally, tapping sneak will change the origin of your next AirSuction to your targeted location."
Tornado: Tornado:
Enabled: true Enabled: true
Description: "To use, simply sneak (default: shift). This will create a swirling vortex at the targeted location. 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." Description: "To use, simply sneak (default: shift). This will create a swirling vortex at the targeted location. 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."