mirror of
https://github.com/TotalFreedomMC/TF-ProjectKorra.git
synced 2025-02-11 03:30:10 +00:00
AirSuction
This commit is contained in:
parent
d07e5af788
commit
03d961c6cc
5 changed files with 337 additions and 0 deletions
|
@ -19,6 +19,7 @@ import com.projectkorra.ProjectKorra.airbending.AirPassive;
|
|||
import com.projectkorra.ProjectKorra.airbending.AirScooter;
|
||||
import com.projectkorra.ProjectKorra.airbending.AirShield;
|
||||
import com.projectkorra.ProjectKorra.airbending.AirSpout;
|
||||
import com.projectkorra.ProjectKorra.airbending.AirSuction;
|
||||
import com.projectkorra.ProjectKorra.airbending.Tornado;
|
||||
import com.projectkorra.ProjectKorra.chiblocking.ChiPassive;
|
||||
import com.projectkorra.ProjectKorra.earthbending.Catapult;
|
||||
|
@ -99,6 +100,7 @@ public class BendingManager implements Runnable {
|
|||
Torrent.progressAll();
|
||||
TorrentBurst.progressAll();
|
||||
FireBlast.progressAll();
|
||||
AirSuction.progressAll();
|
||||
Fireball.progressAll();
|
||||
for (int ID: Tornado.instances.keySet()) {
|
||||
Tornado.progress(ID);
|
||||
|
|
|
@ -121,6 +121,13 @@ public class ConfigManager {
|
|||
+ "Click again to deactivate this ability.");
|
||||
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.Height", 25);
|
||||
config.addDefault("Abilities.Air.Tornado.Range", 25);
|
||||
|
|
|
@ -49,6 +49,7 @@ import com.projectkorra.ProjectKorra.airbending.AirBurst;
|
|||
import com.projectkorra.ProjectKorra.airbending.AirScooter;
|
||||
import com.projectkorra.ProjectKorra.airbending.AirShield;
|
||||
import com.projectkorra.ProjectKorra.airbending.AirSpout;
|
||||
import com.projectkorra.ProjectKorra.airbending.AirSuction;
|
||||
import com.projectkorra.ProjectKorra.airbending.Tornado;
|
||||
import com.projectkorra.ProjectKorra.chiblocking.ChiPassive;
|
||||
import com.projectkorra.ProjectKorra.chiblocking.Paralyze;
|
||||
|
@ -183,6 +184,9 @@ public class PKListener implements Listener {
|
|||
if (abil.equalsIgnoreCase("AirBurst")) {
|
||||
new AirBurst(player);
|
||||
}
|
||||
if (abil.equalsIgnoreCase("AirSuction")) {
|
||||
AirSuction.setOrigin(player);
|
||||
}
|
||||
}
|
||||
|
||||
if (Methods.isWaterAbility(abil)) {
|
||||
|
@ -410,6 +414,9 @@ public class PKListener implements Listener {
|
|||
if (abil.equalsIgnoreCase("AirBlast")) {
|
||||
new AirBlast(player);
|
||||
}
|
||||
if (abil.equalsIgnoreCase("AirSuction")) {
|
||||
new AirSuction(player);
|
||||
}
|
||||
if (abil.equalsIgnoreCase("AirBurst")) {
|
||||
AirBurst.coneBurst(player);
|
||||
}
|
||||
|
|
318
src/com/projectkorra/ProjectKorra/airbending/AirSuction.java
Normal file
318
src/com/projectkorra/ProjectKorra/airbending/AirSuction.java
Normal 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.";
|
||||
}
|
||||
|
||||
}
|
|
@ -70,6 +70,9 @@ Abilities:
|
|||
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
|
||||
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:
|
||||
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."
|
||||
|
|
Loading…
Reference in a new issue