Tornado and AirBlast

This commit is contained in:
MistPhizzle 2014-06-24 18:39:33 -04:00
parent cafea60f7c
commit ead0c812d1
9 changed files with 677 additions and 10 deletions

View file

@ -4,7 +4,5 @@
<classpathentry kind="lib" path="C:/Users/Shawn/Documents/LocalServer/BukkitForPlugins.jar"/>
<classpathentry kind="lib" path="C:/Users/Shawn/Documents/Bending Plugins/TagAPI.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="C:/Users/Shawn/Documents/LocalServer/plugins/ProjectKorra/Abilities/RaiseEarth.jar"/>
<classpathentry kind="lib" path="C:/Users/Shawn/Documents/LocalServer/plugins/ProjectKorra/Abilities/Surge.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -12,7 +12,9 @@ import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import com.projectkorra.ProjectKorra.Ability.AvatarState;
import com.projectkorra.ProjectKorra.airbending.AirBlast;
import com.projectkorra.ProjectKorra.airbending.AirPassive;
import com.projectkorra.ProjectKorra.airbending.Tornado;
import com.projectkorra.ProjectKorra.chiblocking.ChiPassive;
import com.projectkorra.ProjectKorra.earthbending.EarthPassive;
import com.projectkorra.ProjectKorra.firebending.FirePassive;
@ -48,6 +50,7 @@ public class BendingManager implements Runnable {
ProjectKorra.time_step = interval;
AvatarState.manageAvatarStates();
AirBlast.progressAll();
AirPassive.handlePassive(Bukkit.getServer());
ChiPassive.handlePassive();
WaterPassive.handlePassive();
@ -55,6 +58,9 @@ public class BendingManager implements Runnable {
EarthPassive.revertSands();
Plantbending.regrow();
handleDayNight();
for (int ID: Tornado.instances.keySet()) {
Tornado.progress(ID);
}
for (int id: FireStream.instances.keySet()) {
FireStream.progress(id);

View file

@ -2,6 +2,8 @@ package com.projectkorra.ProjectKorra;
import java.util.ArrayList;
import org.bukkit.configuration.file.FileConfiguration;
public class ConfigManager {
static ProjectKorra plugin;
@ -12,7 +14,9 @@ public class ConfigManager {
}
public static void configCheck() {
FileConfiguration config = ProjectKorra.plugin.getConfig();
ArrayList<String> earthbendable = new ArrayList<String>();
earthbendable.add("STONE");
earthbendable.add("COAL_ORE");
@ -56,6 +60,35 @@ public class ConfigManager {
plugin.getConfig().addDefault("Abilities.Air.Passive.Speed", 2);
plugin.getConfig().addDefault("Abilities.Air.Passive.Jump", 3);
config.addDefault("Abilities.Air.AirBlast.Enabled", true);
config.addDefault("Abilities.Air.AirBlast.Description", "AirBlast is the most fundamental bending technique of an airbender."
+ " To use, simply left-click in a direction. A gust of wind will be"
+ " created at your fingertips, launching anything in its path harmlessly back."
+ " A gust of air can extinguish fires on the ground or on a player, can cool lava, and "
+ "can flip levers and activate buttons. Additionally, tapping sneak will change the "
+ "origin of your next AirBlast to your targeted location.");
config.addDefault("Abilities.Air.AirBlast.Speed", 25);
config.addDefault("Abilities.Air.AirBlast.Range", 20);
config.addDefault("Abilities.Air.AirBlast.Radius", 2);
config.addDefault("Abilities.Air.AirBlast.Push", 3.5);
plugin.getConfig().addDefault("Abilities.Air.Tornado.Enabled", true);
plugin.getConfig().addDefault("Abilities.Air.Tornado.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 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's looking. Skilled airbenders can scale anything "
+ "with this ability.");
config.addDefault("Abilities.Air.Tornado.Radius", 10);
config.addDefault("Abilities.Air.Tornado.Height", 25);
config.addDefault("Abilities.Air.Tornado.Range", 25);
config.addDefault("Abilities.Air.Tornado.MobPushFactor", 1);
config.addDefault("Abilities.Air.Tornado.PlayerPushFactor", 1);
plugin.getConfig().addDefault("Abilities.Water.Passive.SwimSpeedFactor", 0.7);
plugin.getConfig().addDefault("Abilities.Water.Plantbending.RegrowTime", 180000);

View file

@ -7,6 +7,7 @@ import org.bukkit.GameMode;
import org.bukkit.entity.Player;
import com.projectkorra.ProjectKorra.Ability.AvatarState;
import com.projectkorra.ProjectKorra.airbending.Tornado;
public class Flight {

View file

@ -346,7 +346,7 @@ public class Methods {
/*
* TODO : Checks for WaterManip and other abilities.
*/
if (isWater(block) && blocki.getData() == full) {
sources++;
}
@ -572,12 +572,11 @@ public class Methods {
if (block.getType() == Material.SANDSTONE
&& info.getType() == Material.SAND)
block.setType(Material.SAND);
if (isAbilityInstalled("RaiseEarth", "orion304")) {
if (EarthColumn.blockInAllAffectedBlocks(block))
EarthColumn.revertBlock(block);
if (EarthColumn.blockInAllAffectedBlocks(block))
EarthColumn.revertBlock(block);
EarthColumn.resetBlock(block);
EarthColumn.resetBlock(block);
}
movedearth.remove(block);
}
}

View file

@ -24,9 +24,12 @@ import org.bukkit.event.player.PlayerAnimationEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerToggleFlightEvent;
import org.bukkit.event.player.PlayerToggleSneakEvent;
import org.kitteh.tag.AsyncPlayerReceiveNameTagEvent;
import com.projectkorra.ProjectKorra.Ability.AvatarState;
import com.projectkorra.ProjectKorra.airbending.AirBlast;
import com.projectkorra.ProjectKorra.airbending.Tornado;
import com.projectkorra.ProjectKorra.chiblocking.ChiPassive;
import com.projectkorra.ProjectKorra.earthbending.EarthPassive;
import com.projectkorra.ProjectKorra.firebending.Enflamed;
@ -82,6 +85,35 @@ public class PKListener implements Listener {
BendingPlayer.players.remove(e.getPlayer().getName());
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onPlayerSneak(PlayerToggleSneakEvent event) {
Player player = event.getPlayer();
if (Paralyze.isParaylzed(player) || Bloodbending.isBloodbended(player)) {
event.setCancelled(true);
}
AirScooter.check(player);
String abil = Methods.getBoundAbility(player);
if (abil == null) {
return;
}
if (!player.isSneaking() && Methods.canBend(player.getName(), abil)) {
if (Methods.isAirAbility(abil)) {
if (Methods.isWeapon(player.getItemInHand().getType()) && !plugin.getConfig().getBoolean("Properties.Air.CanBendWithWeapons")) {
return;
}
if (abil == "Tornado") {
new Tornado(player);
}
if (abil == "AirBlast") {
AirBlast.setOrigin(player);
}
}
}
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onPlayerSwing(PlayerAnimationEvent event) {
Player player = event.getPlayer();
@ -96,12 +128,20 @@ public class PKListener implements Listener {
if (abil == "AvatarState") {
new AvatarState(player);
}
if (Methods.isAirAbility(abil)) {
if (Methods.isWeapon(player.getItemInHand().getType()) && !plugin.getConfig().getBoolean("Properties.Air.CanBendWithWeapons")) {
return;
}
if (abil == "AirBlast") {
new AirBlast(player);
}
}
}
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onPlayerToggleFlight(PlayerToggleFlightEvent event) {
Player p = event.getPlayer();
if (Tornado.getplayers().contains(p) || Bloodbending.isBloodbended(p)
if (Tornado.getPlayers().contains(p) || Bloodbending.isBloodbended(p)
|| FireJet.getPlayers().contains(p)
|| AvatarState.getPlayers().contains(p)) {
event.setCancelled(p.getGameMode() != GameMode.CREATIVE);

View file

@ -0,0 +1,358 @@
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.Material;
import org.bukkit.block.Block;
import org.bukkit.configuration.file.FileConfiguration;
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;
public class AirBlast {
public static ConcurrentHashMap<Integer, AirBlast> instances = new ConcurrentHashMap<Integer, AirBlast>();
private static ConcurrentHashMap<Player, Location> origins = new ConcurrentHashMap<Player, Location>();
public static ConcurrentHashMap<String, Long> cooldowns = new ConcurrentHashMap<String, Long>();
// private static ConcurrentHashMap<Player, Long> timers = new
// ConcurrentHashMap<Player, Long>();
// static final long soonesttime = Methods.timeinterval;
private static int ID = Integer.MIN_VALUE;
static final int maxticks = 10000;
static FileConfiguration config = ProjectKorra.plugin.getConfig();
public static double speed = config.getDouble("Abilities.Air.AirBlast.Speed");
public static double defaultrange = config.getDouble("Abilities.Air.AirBlast.Range");
public static double affectingradius = config.getDouble("Abilities.Air.AirBlast.Radius");
public static double defaultpushfactor = config.getDouble("Abilities.Air.AirBlast.Push");
private static double originselectrange = 10;
static final double maxspeed = 1. / defaultpushfactor;
// public static long interval = 2000;
public static byte full = 0x0;
private Location location;
private Location origin;
private Vector direction;
private Player player;
private int id;
private double speedfactor;
private double range = defaultrange;
private double pushfactor = defaultpushfactor;
private boolean otherorigin = false;
private int ticks = 0;
private ArrayList<Block> affectedlevers = new ArrayList<Block>();
private ArrayList<Entity> affectedentities = new ArrayList<Entity>();
private AirBurst source = null;
// private long time;
public AirBlast(Player player) {
// if (timers.containsKey(player)) {
// if (System.currentTimeMillis() < timers.get(player) + soonesttime) {
// return;
// }
// }
if (cooldowns.containsKey(player.getName())) {
if (cooldowns.get(player.getName()) + config.getLong("Properties.GlobalCooldown") >= System.currentTimeMillis()) {
return;
} else {
cooldowns.remove(player.getName());
}
}
if (player.getEyeLocation().getBlock().isLiquid()) {
return;
}
// timers.put(player, System.currentTimeMillis());
this.player = player;
if (origins.containsKey(player)) {
otherorigin = true;
origin = origins.get(player);
origins.remove(player);
Entity entity = Methods.getTargetedEntity(player, range, new ArrayList<Entity>());
if (entity != null) {
direction = Methods.getDirection(origin, entity.getLocation())
.normalize();
} else {
direction = Methods.getDirection(origin,
Methods.getTargetedLocation(player, range)).normalize();
}
} else {
origin = player.getEyeLocation();
direction = player.getEyeLocation().getDirection().normalize();
}
location = origin.clone();
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());
}
public AirBlast(Location location, Vector direction, Player player,
double factorpush, AirBurst burst) {
if (location.getBlock().isLiquid()) {
return;
}
source = burst;
this.player = player;
origin = location.clone();
this.direction = direction.clone();
this.location = location.clone();
id = ID;
pushfactor *= factorpush;
instances.put(id, this);
if (ID == Integer.MAX_VALUE)
ID = Integer.MIN_VALUE;
ID++;
}
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.AirBlast,
// 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.AirBlast,
// 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.AirBlast) {
// new AirBlast(player);
// }
Block block = location.getBlock();
for (Block testblock : Methods.getBlocksAroundPoint(location,
affectingradius)) {
if (testblock.getType() == Material.FIRE) {
testblock.setType(Material.AIR);
testblock.getWorld().playEffect(testblock.getLocation(),
Effect.EXTINGUISH, 0);
}
if (((block.getType() == Material.LEVER) || (block.getType() == Material.STONE_BUTTON))
&& !affectedlevers.contains(block)) {
// BlockState state = block.getState();
// Lever lever = (Lever) (state.getData());
// lever.setPowered(!lever.isPowered());
// state.setData(lever);
// state.update(true, true);
//
// Block relative = block.getRelative(((Attachable) block
// .getState().getData()).getFacing(), -1);
// relative.getState().update(true, true);
//
// for (Block block2 : Methods.getBlocksAroundPoint(
// relative.getLocation(), 2))
// block2.getState().update(true, true);
affectedlevers.add(block);
}
}
if ((Methods.isSolid(block) || block.isLiquid())
&& !affectedlevers.contains(block)) {
if (block.getType() == Material.LAVA
|| block.getType() == Material.STATIONARY_LAVA) {
if (block.getData() == full) {
block.setType(Material.OBSIDIAN);
} else {
block.setType(Material.COBBLESTONE);
}
}
instances.remove(id);
return false;
}
// Methods.verbose(location.distance(origin));
if (location.distance(origin) > range) {
// Methods.verbose(id);
instances.remove(id);
return false;
}
for (Entity entity : Methods.getEntitiesAroundPoint(location,
affectingradius)) {
// if (source == null) {
// if (affectedentities.contains(entity))
// continue;
// } else {
// if (source.isAffectedEntity(entity))
// continue;
// }
affect(entity);
}
advanceLocation();
return true;
}
private void advanceLocation() {
location.getWorld().playEffect(location, Effect.SMOKE, 4, (int) range);
location = location.add(direction.clone().multiply(speedfactor));
}
private void affect(Entity entity) {
// if (source == null)
// affectedentities.add(entity);
// else
// source.addAffectedEntity(entity);
boolean isUser = entity.getEntityId() == player.getEntityId();
if (!isUser || otherorigin) {
Vector velocity = entity.getVelocity();
// double mag = Math.abs(velocity.getY());
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 && !isUser) {
if (push.getY() < 0)
push.setY(-max);
else
push.setY(max);
}
factor *= 1 - location.distance(origin) / (2 * range);
if (isUser
&& Methods.isSolid(player.getLocation().add(0, -.5, 0)
.getBlock())) {
factor *= .5;
}
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));
}
// velocity =
// velocity.clone().add(direction.clone().multiply(factor));
// 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);
// }
// }
//
// velocity.multiply(1 - location.distance(origin) / (2 * range));
//
// if (entity instanceof Player)
// velocity.multiply(2);
entity.setVelocity(velocity);
entity.setFallDistance(0);
if (!isUser && entity instanceof Player) {
new Flight((Player) entity, player);
}
if (entity.getFireTicks() > 0)
entity.getWorld().playEffect(entity.getLocation(),
Effect.EXTINGUISH, 0);
entity.setFireTicks(0);
}
}
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("AirBlast") || !Methods.canBend(player.getName(), "AirBlast")) {
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 void removeAll() {
for (int id : instances.keySet()) {
instances.remove(id);
}
}
}

View file

@ -0,0 +1,214 @@
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.Material;
import org.bukkit.configuration.file.FileConfiguration;
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;
public class Tornado {
public static ConcurrentHashMap<Integer, Tornado> instances = new ConcurrentHashMap<Integer, Tornado>();
static FileConfiguration config = ProjectKorra.plugin.getConfig();
private static double maxradius = config.getDouble("Abilities.Air.Tornado.Radius");
private static double maxheight = config.getDouble("Abilities.Air.Tornado.Height");
private static double range = config.getDouble("Abilities.Air.Tornado.Range");
private static int numberOfStreams = (int) (.3 * (double) maxheight);
private static double NPCpushfactor = config.getDouble("Abilities.Air.Tornado.MobPushFactor");
private static double PCpushfactor = config.getDouble("Abilities.Air.Tornado.PlayerPushFactor");
// private static double speed = .75;
private double height = 2;
private double radius = height / maxheight * maxradius;
// private static double speedfactor = 1000 * speed
// * (Bending.time_step / 1000.);
private static double speedfactor = 1;
private ConcurrentHashMap<Integer, Integer> angles = new ConcurrentHashMap<Integer, Integer>();
private Location origin;
private Player player;
// private boolean canfly;
public Tornado(Player player) {
this.player = player;
// canfly = player.getAllowFlight();
// player.setAllowFlight(true);
origin = player.getTargetBlock(null, (int) range).getLocation();
origin.setY(origin.getY() - 1. / 10. * height);
int angle = 0;
for (int i = 0; i <= maxheight; i += (int) maxheight / numberOfStreams) {
angles.put(i, angle);
angle += 90;
if (angle == 360)
angle = 0;
}
new Flight(player);
player.setAllowFlight(true);
instances.put(player.getEntityId(), this);
}
public boolean progress() {
if (player.isDead() || !player.isOnline()) {
// player.setAllowFlight(canfly);
instances.remove(player.getEntityId());
return false;
}
if (!Methods.canBend(player.getName(), "Tornado")
|| player.getEyeLocation().getBlock().isLiquid()) {
// player.setAllowFlight(canfly);
instances.remove(player.getEntityId());
return false;
}
String abil = Methods.getBoundAbility(player);
if (abil == null) {
instances.remove(player.getEntityId());
return false;
}
if (!abil.equalsIgnoreCase("Tornado") || !player.isSneaking()) {
instances.remove(player.getEntityId());
return false;
}
// if (Methods
// .isRegionProtectedFromBuild(player, Abilities.AirBlast, origin)) {
// instances.remove(player.getEntityId());
// return false;
// }
rotateTornado();
return true;
}
private void rotateTornado() {
origin = player.getTargetBlock(null, (int) range).getLocation();
double timefactor = height / maxheight;
radius = timefactor * maxradius;
if (origin.getBlock().getType() != Material.AIR) {
origin.setY(origin.getY() - 1. / 10. * height);
for (Entity entity : Methods.getEntitiesAroundPoint(origin, height)) {
// if (Methods.isRegionProtectedFromBuild(player,
// Abilities.AirBlast, entity.getLocation()))
// continue;
double y = entity.getLocation().getY();
double factor;
if (y > origin.getY() && y < origin.getY() + height) {
factor = (y - origin.getY()) / height;
Location testloc = new Location(origin.getWorld(),
origin.getX(), y, origin.getZ());
if (testloc.distance(entity.getLocation()) < radius
* factor) {
double x, z, vx, vz, mag;
double angle = 100;
double vy = 0.7 * NPCpushfactor;
angle = Math.toRadians(angle);
x = entity.getLocation().getX() - origin.getX();
z = entity.getLocation().getZ() - origin.getZ();
mag = Math.sqrt(x * x + z * z);
vx = (x * Math.cos(angle) - z * Math.sin(angle)) / mag;
vz = (x * Math.sin(angle) + z * Math.cos(angle)) / mag;
if (entity instanceof Player) {
vy = 0.05 * PCpushfactor;
}
if (entity.getEntityId() == player.getEntityId()) {
Vector direction = player.getEyeLocation()
.getDirection().clone().normalize();
vx = direction.getX();
vz = direction.getZ();
Location playerloc = player.getLocation();
double py = playerloc.getY();
double oy = origin.getY();
double dy = py - oy;
if (dy >= height * .95) {
vy = 0;
} else if (dy >= height * .85) {
vy = 6.0 * (.95 - dy / height);
} else {
vy = .6;
}
}
Vector velocity = entity.getVelocity();
velocity.setX(vx);
velocity.setZ(vz);
velocity.setY(vy);
velocity.multiply(timefactor);
entity.setVelocity(velocity);
entity.setFallDistance(0);
if (entity instanceof Player) {
new Flight((Player) entity);
}
}
}
}
for (int i : angles.keySet()) {
double x, y, z;
double angle = (double) angles.get(i);
angle = Math.toRadians(angle);
double factor;
y = origin.getY() + timefactor * (double) i;
factor = (double) i / height;
x = origin.getX() + timefactor * factor * radius
* Math.cos(angle);
z = origin.getZ() + timefactor * factor * radius
* Math.sin(angle);
Location effect = new Location(origin.getWorld(), x, y, z);
// if (!Methods.isRegionProtectedFromBuild(player,
// Abilities.AirBlast, effect))
origin.getWorld().playEffect(effect, Effect.SMOKE, 4,
(int) AirBlast.defaultrange);
angles.put(i, angles.get(i) + 25 * (int) speedfactor);
}
}
if (height < maxheight) {
height += 1;
}
if (height > maxheight) {
height = maxheight;
}
}
public static boolean progress(int ID) {
return instances.get(ID).progress();
}
public static ArrayList<Player> getPlayers() {
ArrayList<Player> players = new ArrayList<Player>();
for (int id : instances.keySet()) {
players.add(instances.get(id).player);
}
return players;
}
}

View file

@ -36,11 +36,29 @@ Properties:
Chi:
CanBendWithWeapons: false
Abilities:
AvatarState:
Enabled: true
Description: "The signature ability of the Avatar, this is a toggle. Click to activate to become nearly unstoppable. While in the Avatar State, the user takes severely reduced damage from all sources, regenreates health rapidly, and is granted extreme speed. Nearly all abilities are incredibly amplified in this state. Additionally, AirShield and FireJet become toggle-able abilities and last until you deactivate them or the Avatar State. Click again with the Avatar State selected to deactivate it."
Air:
Passive:
Factor: 0.3
Speed: 2
Jump: 3
AirBlast:
Enabled: true
Description: "AirBlast is the most fundamental bending technique of an airbender. To use, simply left-click in a direction. A gust of wind will be created at your fingertips, launching anything in its path harmlessly back. A gust of air can extinguish fires on the ground or on a player, can cool lava, and can flip levers and activate buttons. Additionally, tapping sneak will change the original of your next AirBlast to your targeted location."
Speed: 25
Range: 20
Radius: 2
Push: 3.5
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."
Radius: 10
Height: 25
Range: 25
MobPushFactor: 1
PlayerPushFactor: 1
Water:
Passive:
SwimSpeedFactor: 0.7