mirror of
https://github.com/TotalFreedomMC/TF-ProjectKorra.git
synced 2025-02-11 11:40:40 +00:00
Merge branch 'master' of https://github.com/ProjectKorra/ProjectKorra
Conflicts: src/com/projectkorra/ProjectKorra/Methods.java src/com/projectkorra/ProjectKorra/firebending/Lightning.java
This commit is contained in:
commit
d63db2e235
15 changed files with 1083 additions and 416 deletions
Binary file not shown.
|
@ -223,9 +223,24 @@ public class ConfigManager {
|
|||
|
||||
config.addDefault("Abilities.Air.Suffocate.Enabled", true);
|
||||
config.addDefault("Abilities.Air.Suffocate.Description", "This ability is one of the most dangerous abilities an Airbender possesses. To use, simply look at an entity and hold shift. The entity will begin taking damage as you extract the air from their lungs. Any bender caught in this sphere will only be able to use basic moves, such as AirSwipe, WaterManipulation, FireBlast, or EarthBlast. An entity can be knocked out of the sphere by certain bending arts, and your attention will be disrupted if you are hit by bending.");
|
||||
config.addDefault("Abilities.Air.Suffocate.ChargeTime", 1000);
|
||||
config.addDefault("Abilities.Air.Suffocate.Cooldown", 0);
|
||||
config.addDefault("Abilities.Air.Suffocate.Range", 15);
|
||||
config.addDefault("Abilities.Air.Suffocate.Damage", 2);
|
||||
config.addDefault("Abilities.Air.Suffocate.DamageInitialDelay", 2);
|
||||
config.addDefault("Abilities.Air.Suffocate.DamageInterval", 1);
|
||||
config.addDefault("Abilities.Air.Suffocate.SlowPotency", 1);
|
||||
config.addDefault("Abilities.Air.Suffocate.SlowDelay", 0.5);
|
||||
config.addDefault("Abilities.Air.Suffocate.SlowInterval", 1.25);
|
||||
config.addDefault("Abilities.Air.Suffocate.BlindPotentcy", 30);
|
||||
config.addDefault("Abilities.Air.Suffocate.BlindDelay", 2);
|
||||
config.addDefault("Abilities.Air.Suffocate.BlindInterval", 1.5);
|
||||
config.addDefault("Abilities.Air.Suffocate.CanBeUsedOnUndeadMobs", true);
|
||||
config.addDefault("Abilities.Air.Suffocate.Range", 5);
|
||||
config.addDefault("Abilities.Air.Suffocate.Damage", 0.5);
|
||||
config.addDefault("Abilities.Air.Suffocate.RequireConstantAim", true);
|
||||
config.addDefault("Abilities.Air.Suffocate.RequireConstantAimRadius", 5);
|
||||
config.addDefault("Abilities.Air.Suffocate.AnimationRadius", 2.0);
|
||||
config.addDefault("Abilities.Air.Suffocate.AnimationParticleAmount", 2);
|
||||
config.addDefault("Abilities.Air.Suffocate.AnimationSpeed", 1.0);
|
||||
|
||||
config.addDefault("Abilities.Air.Tornado.Radius", 10);
|
||||
config.addDefault("Abilities.Air.Tornado.Height", 25);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.projectkorra.ProjectKorra;
|
||||
|
||||
|
||||
import com.griefcraft.lwc.LWC;
|
||||
import com.griefcraft.lwc.LWCPlugin;
|
||||
import com.griefcraft.model.Protection;
|
||||
|
@ -1379,15 +1380,22 @@ public class Methods {
|
|||
|
||||
ConcurrentHashMap<Block, BlockCacheElement> blockMap = blockProtectionCache.get(player.getName());
|
||||
Block block = loc.getBlock();
|
||||
if(blockMap.containsKey(block))
|
||||
return blockMap.get(block).isAllowed();
|
||||
if(blockMap.containsKey(block)) {
|
||||
BlockCacheElement elem = blockMap.get(block);
|
||||
|
||||
// both abilities must be equal to each other to use the cache
|
||||
if((ability == null && elem.getAbility() == null)
|
||||
|| (ability != null && elem.getAbility() != null && elem.getAbility().equals(ability))) {
|
||||
return elem.isAllowed();
|
||||
}
|
||||
}
|
||||
|
||||
boolean value = isRegionProtectedFromBuildPostCache(player, ability, loc);
|
||||
blockMap.put(block, new BlockCacheElement(player, block, value, System.currentTimeMillis()));
|
||||
blockMap.put(block, new BlockCacheElement(player, block, ability, value, System.currentTimeMillis()));
|
||||
return value;
|
||||
}
|
||||
|
||||
private static boolean isRegionProtectedFromBuildPostCache(Player player, String ability, Location loc) {
|
||||
public static boolean isRegionProtectedFromBuildPostCache(Player player, String ability, Location loc) {
|
||||
|
||||
boolean allowharmless = plugin.getConfig().getBoolean("Properties.RegionProtection.AllowHarmlessAbilities");
|
||||
boolean respectWorldGuard = plugin.getConfig().getBoolean("Properties.RegionProtection.RespectWorldGuard");
|
||||
|
@ -1445,7 +1453,7 @@ public class Methods {
|
|||
if (explode.contains(ability)) {
|
||||
if (wg.getGlobalStateManager().get(location.getWorld()).blockTNTExplosions)
|
||||
return true;
|
||||
if (wg.getRegionContainer().createQuery().testBuild(location, player, DefaultFlag.TNT))
|
||||
if (!wg.getRegionContainer().createQuery().testBuild(location, player, DefaultFlag.TNT))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -2586,19 +2594,21 @@ public class Methods {
|
|||
if(!canBend(player.getName(), "Flight")) return false;
|
||||
if(!getBoundAbility(player).equalsIgnoreCase("Flight")) return false;
|
||||
if(isRegionProtectedFromBuild(player, "Flight", player.getLocation())) return false;
|
||||
if(player.getLocation().subtract(0, 1, 0).getBlock().getType() != Material.AIR) return false;
|
||||
if(player.getLocation().subtract(0, 0.5, 0).getBlock().getType() != Material.AIR) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static class BlockCacheElement {
|
||||
private Player player;
|
||||
private Block block;
|
||||
private String ability;
|
||||
private boolean allowed;
|
||||
private long time;
|
||||
|
||||
public BlockCacheElement(Player player, Block block, boolean allowed, long time) {
|
||||
public BlockCacheElement(Player player, Block block, String ability, boolean allowed, long time) {
|
||||
this.player = player;
|
||||
this.block = block;
|
||||
this.ability = ability;
|
||||
this.allowed = allowed;
|
||||
this.time = time;
|
||||
}
|
||||
|
@ -2635,6 +2645,14 @@ public class Methods {
|
|||
this.allowed = allowed;
|
||||
}
|
||||
|
||||
public String getAbility() {
|
||||
return ability;
|
||||
}
|
||||
|
||||
public void setAbility(String ability) {
|
||||
this.ability = ability;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void startCacheCleaner(final double period) {
|
||||
|
@ -2654,5 +2672,22 @@ public class Methods {
|
|||
}.runTaskTimer(ProjectKorra.plugin, 0, (long) (period / 20));
|
||||
}
|
||||
|
||||
/** Checks if an entity is Undead **/
|
||||
public static boolean isUndead(Entity entity) {
|
||||
if (entity == null) return false;
|
||||
if (entity.getType() == EntityType.ZOMBIE
|
||||
|| entity.getType() == EntityType.BLAZE
|
||||
|| entity.getType() == EntityType.GIANT
|
||||
|| entity.getType() == EntityType.IRON_GOLEM
|
||||
|| entity.getType() == EntityType.MAGMA_CUBE
|
||||
|| entity.getType() == EntityType.PIG_ZOMBIE
|
||||
|| entity.getType() == EntityType.SKELETON
|
||||
|| entity.getType() == EntityType.SLIME
|
||||
|| entity.getType() == EntityType.SNOWMAN
|
||||
|| entity.getType() == EntityType.ZOMBIE) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1145,6 +1145,10 @@ public class PKListener implements Listener {
|
|||
e.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if(entity instanceof Player) {
|
||||
Suffocate.remove((Player) entity);
|
||||
}
|
||||
|
||||
Entity en = e.getEntity();
|
||||
if (en instanceof Player) {
|
||||
|
|
|
@ -13,6 +13,7 @@ import org.bukkit.util.Vector;
|
|||
import com.projectkorra.ProjectKorra.BendingPlayer;
|
||||
import com.projectkorra.ProjectKorra.ComboManager.ClickType;
|
||||
import com.projectkorra.ProjectKorra.Commands;
|
||||
import com.projectkorra.ProjectKorra.Element;
|
||||
import com.projectkorra.ProjectKorra.Flight;
|
||||
import com.projectkorra.ProjectKorra.Methods;
|
||||
import com.projectkorra.ProjectKorra.ProjectKorra;
|
||||
|
@ -99,11 +100,13 @@ public class AirCombo {
|
|||
public AirCombo(Player player, String ability) {
|
||||
if (!enabled || !player.hasPermission("bending.ability.AirCombo"))
|
||||
return;
|
||||
if (Methods.isRegionProtectedFromBuild(player, "AirBlast",
|
||||
player.getLocation()))
|
||||
if(!Methods.getBendingPlayer(player.getName()).hasElement(Element.Air))
|
||||
return;
|
||||
if (Commands.isToggledForAll)
|
||||
return;
|
||||
if (Methods.isRegionProtectedFromBuild(player, "AirBlast",
|
||||
player.getLocation()))
|
||||
return;
|
||||
if (!Methods.getBendingPlayer(player.getName()).isToggled())
|
||||
return;
|
||||
time = System.currentTimeMillis();
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
package com.projectkorra.ProjectKorra.airbending;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import com.projectkorra.ProjectKorra.Flight;
|
||||
import com.projectkorra.ProjectKorra.Methods;
|
||||
|
||||
public class FlightAbility {
|
||||
|
@ -13,15 +15,13 @@ public class FlightAbility {
|
|||
private static ConcurrentHashMap<String, Integer> hits = new ConcurrentHashMap<String, Integer>();
|
||||
private static ConcurrentHashMap<String, Boolean> hovering = new ConcurrentHashMap<String, Boolean>();
|
||||
private Player p;
|
||||
|
||||
private Flight flight;
|
||||
|
||||
public FlightAbility(Player player) {
|
||||
if(!Methods.canFly(player, true, false)) return;
|
||||
|
||||
if(!Methods.canFly(player, true, false))
|
||||
return;
|
||||
player.setAllowFlight(true);
|
||||
|
||||
player.setVelocity(player.getEyeLocation().getDirection().normalize());
|
||||
|
||||
instances.put(player.getName(), this);
|
||||
p = player;
|
||||
}
|
||||
|
@ -32,9 +32,18 @@ public class FlightAbility {
|
|||
return;
|
||||
}
|
||||
|
||||
p.setAllowFlight(true);
|
||||
if(flight == null)
|
||||
flight = new Flight(p);
|
||||
|
||||
if(isHovering(p)) {
|
||||
Vector vec = p.getVelocity().clone();
|
||||
vec.setY(0);
|
||||
p.setVelocity(vec);
|
||||
}
|
||||
else {
|
||||
p.setVelocity(p.getEyeLocation().getDirection().normalize());
|
||||
}
|
||||
|
||||
p.setVelocity(p.getEyeLocation().getDirection().normalize());
|
||||
}
|
||||
|
||||
public static void addHit(Player player) {
|
||||
|
@ -51,11 +60,7 @@ public class FlightAbility {
|
|||
}
|
||||
|
||||
public static boolean isHovering(Player player) {
|
||||
String playername = player.getName();
|
||||
|
||||
if(hovering.containsKey(playername) && hovering.get(playername)) return true;
|
||||
if(hovering.containsKey(playername) && hovering.get(playername)) return false; //Shouldn't happen
|
||||
return false;
|
||||
return hovering.containsKey(player.getName());
|
||||
}
|
||||
|
||||
public static void setHovering(Player player, boolean bool) {
|
||||
|
@ -64,13 +69,11 @@ public class FlightAbility {
|
|||
if(bool) {
|
||||
if(!hovering.containsKey(playername)) {
|
||||
hovering.put(playername, true);
|
||||
player.setFlying(true);
|
||||
player.setVelocity(new Vector(0, 0 ,0));
|
||||
player.setVelocity(new Vector(0, 0, 0));
|
||||
}
|
||||
}else{
|
||||
if(hovering.containsKey(playername)) {
|
||||
hovering.remove(playername);
|
||||
player.setFlying(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -81,30 +84,24 @@ public class FlightAbility {
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void remove() {
|
||||
String name = p.getName();
|
||||
instances.remove(name);
|
||||
hits.remove(name);
|
||||
hovering.remove(name);
|
||||
flight.revert();
|
||||
}
|
||||
|
||||
public static void remove(Player player) {
|
||||
if(instances.containsKey(player.getName())) {
|
||||
instances.remove(player.getName());
|
||||
if(hits.containsKey(player.getName())) {
|
||||
hits.remove(player.getName());
|
||||
}
|
||||
if(hovering.containsKey(player.getName())) {
|
||||
hovering.remove(player.getName());
|
||||
}
|
||||
if((!(player.getGameMode().getValue() == 1))) {
|
||||
if(!(player.getGameMode().getValue() == 1)) {
|
||||
player.setAllowFlight(false);
|
||||
}
|
||||
}
|
||||
if((!(player.getGameMode().getValue() == 3))) {
|
||||
if(!(player.getGameMode().getValue() == 1)) {
|
||||
player.setAllowFlight(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(instances.containsKey(player.getName()))
|
||||
instances.get(player.getName()).remove();
|
||||
}
|
||||
|
||||
public static void removeAll() {
|
||||
Iterator<String> it = instances.keySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
instances.get(it.next()).remove();
|
||||
}
|
||||
instances.clear();
|
||||
hits.clear();
|
||||
hovering.clear();
|
||||
|
|
|
@ -1,220 +1,682 @@
|
|||
package com.projectkorra.ProjectKorra.airbending;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Creature;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import com.projectkorra.ProjectKorra.Commands;
|
||||
import com.projectkorra.ProjectKorra.BendingPlayer;
|
||||
import com.projectkorra.ProjectKorra.Methods;
|
||||
import com.projectkorra.ProjectKorra.ProjectKorra;
|
||||
import com.projectkorra.ProjectKorra.TempPotionEffect;
|
||||
import com.projectkorra.ProjectKorra.Ability.AvatarState;
|
||||
import com.projectkorra.ProjectKorra.Utilities.ParticleEffect;
|
||||
|
||||
/**
|
||||
* Suffocate
|
||||
*
|
||||
* Suffocate is an air ability that causes entities to be surrounded by
|
||||
* a sphere air that causes constant damage after a configurable delay.
|
||||
* Suffocate also causes Blinding and Slowing affects to entities depending
|
||||
* on how the ability is configured. While in AvatarState this ability can
|
||||
* be used on multiple entities within a large radius.
|
||||
* If the user is damaged while performing this ability then the ability is removed.
|
||||
*/
|
||||
public class Suffocate {
|
||||
|
||||
public static ConcurrentHashMap<Player, Suffocate> instances = new ConcurrentHashMap<Player, Suffocate>();
|
||||
|
||||
private static boolean canBeUsedOnUndead = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Air.Suffocate.CanBeUsedOnUndeadMobs");
|
||||
private int range = ProjectKorra.plugin.getConfig().getInt("Abilities.Air.Suffocate.Range");
|
||||
private double damage = ProjectKorra.plugin.getConfig().getDouble("Abilities.Air.Suffocate.Damage");
|
||||
|
||||
private Map<Entity, Location> targets = new HashMap<Entity, Location>();
|
||||
public static enum SpiralType {
|
||||
HORIZONTAL1, HORIZONTAL2, VERTICAL1, VERTICAL2, DIAGONAL1, DIAGONAL2
|
||||
};
|
||||
|
||||
private static ConcurrentHashMap<Player, Suffocate> instances = new ConcurrentHashMap<Player, Suffocate>();
|
||||
|
||||
private static FileConfiguration config = ProjectKorra.plugin.getConfig();
|
||||
private static final boolean CAN_SUFFOCATE_UNDEAD = config.getBoolean("Abilities.Air.Suffocate.CanBeUsedOnUndeadMobs");
|
||||
private static final boolean REQUIRE_CONSTANT_AIM = config.getBoolean("Abilities.Air.Suffocate.RequireConstantAim");
|
||||
private static final double ANIM_RADIUS = config.getDouble("Abilities.Air.Suffocate.AnimationRadius");
|
||||
private static final int ANIM_PARTICLE_AMOUNT = config.getInt("Abilities.Air.Suffocate.AnimationParticleAmount");
|
||||
private static final double ANIM_SPEED = config.getDouble("Abilities.Air.Suffocate.AnimationSpeed");
|
||||
|
||||
private static final long CHARGE_TIME = config.getLong("Abilities.Air.Suffocate.ChargeTime");
|
||||
private static final long COOLDOWN = config.getLong("Abilities.Air.Suffocate.Cooldown");
|
||||
private static final double RANGE = config.getDouble("Abilities.Air.Suffocate.Range");
|
||||
private static double AIM_RADIUS = config.getDouble("Abilities.Air.Suffocate.RequireConstantAimRadius");
|
||||
private static double DAMAGE = config.getDouble("Abilities.Air.Suffocate.Damage");
|
||||
private static double DAMAGE_INITIAL_DELAY = config.getDouble("Abilities.Air.Suffocate.DamageInitialDelay");
|
||||
private static double DAMAGE_INTERVAL = config.getDouble("Abilities.Air.Suffocate.DamageInterval");
|
||||
private static int SLOW = config.getInt("Abilities.Air.Suffocate.SlowPotency");
|
||||
private static double SLOW_INTERVAL = config.getDouble("Abilities.Air.Suffocate.SlowInterval");
|
||||
private static double SLOW_DELAY = config.getDouble("Abilities.Air.Suffocate.SlowDelay");
|
||||
private static int BLIND = config.getInt("Abilities.Air.Suffocate.BlindPotentcy");
|
||||
private static double BLIND_DELAY = config.getDouble("Abilities.Air.Suffocate.BlindDelay");
|
||||
private static double BLIND_INTERVAL = config.getDouble("Abilities.Air.Suffocate.BlindInterval");
|
||||
|
||||
private Player player;
|
||||
private BendingPlayer bplayer;
|
||||
private boolean started = false;
|
||||
private long time;
|
||||
private long warmup = 2000;
|
||||
|
||||
private PotionEffect slow = new PotionEffect(PotionEffectType.SLOW, 60, 1);
|
||||
private PotionEffect nausea = new PotionEffect(PotionEffectType.SLOW, 60, 1);
|
||||
|
||||
private ArrayList<BukkitRunnable> tasks;
|
||||
private ArrayList<LivingEntity> targets;
|
||||
private boolean reqConstantAim;
|
||||
private boolean canSuffUndead;
|
||||
private long chargeTime, cooldown;
|
||||
private int particleScale;
|
||||
private double range, radius;
|
||||
private double speedFactor;
|
||||
private double aimRadius;
|
||||
private double damage, damageDelay, damageRepeat;
|
||||
private double slow, slowRepeat, slowDelay;
|
||||
private double blind, blindDelay, blindRepeat;
|
||||
|
||||
public Suffocate(Player player) {
|
||||
if (instances.containsKey(player)) {
|
||||
remove(player);
|
||||
return;
|
||||
}
|
||||
|
||||
if (AvatarState.isAvatarState(player)) {
|
||||
range = AvatarState.getValue(range);
|
||||
for (Entity entity: Methods.getEntitiesAroundPoint(player.getLocation(), range)) {
|
||||
if (entity instanceof LivingEntity && entity.getEntityId() != player.getEntityId()) {
|
||||
targets.put(entity, entity.getLocation());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Entity en = Methods.getTargetedEntity(player, range, new ArrayList<Entity>());
|
||||
if (en != null && en instanceof LivingEntity && en.getEntityId() != player.getEntityId()) {
|
||||
targets.put(en, en.getLocation());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
this.player = player;
|
||||
instances.put(player, this);
|
||||
bplayer = Methods.getBendingPlayer(player.getName());
|
||||
targets = new ArrayList<LivingEntity>();
|
||||
tasks = new ArrayList<BukkitRunnable>();
|
||||
time = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
private void progress() {
|
||||
if (!player.isSneaking()) {
|
||||
remove(player);
|
||||
|
||||
reqConstantAim = REQUIRE_CONSTANT_AIM;
|
||||
canSuffUndead = CAN_SUFFOCATE_UNDEAD;
|
||||
chargeTime = CHARGE_TIME;
|
||||
cooldown = COOLDOWN;
|
||||
particleScale = ANIM_PARTICLE_AMOUNT;
|
||||
range = RANGE;
|
||||
radius = ANIM_RADIUS;
|
||||
speedFactor = ANIM_SPEED;
|
||||
aimRadius = AIM_RADIUS;
|
||||
damage = DAMAGE;
|
||||
damageDelay = DAMAGE_INITIAL_DELAY;
|
||||
damageRepeat = DAMAGE_INTERVAL;
|
||||
slow = SLOW;
|
||||
slowRepeat = SLOW_INTERVAL;
|
||||
slowDelay = SLOW_DELAY;
|
||||
blind = BLIND;
|
||||
blindDelay = BLIND_DELAY;
|
||||
blindRepeat = BLIND_INTERVAL;
|
||||
|
||||
if(instances.containsKey(player))
|
||||
return;
|
||||
|
||||
if(AvatarState.isAvatarState(player)) {
|
||||
cooldown = 0;
|
||||
chargeTime = 0;
|
||||
reqConstantAim = false;
|
||||
damage = AvatarState.getValue(damage);
|
||||
range *= 2;
|
||||
slow = AvatarState.getValue(slow);
|
||||
slowRepeat = AvatarState.getValue(slowRepeat);
|
||||
blind = AvatarState.getValue(blind);
|
||||
blindRepeat = AvatarState.getValue(blindRepeat);
|
||||
}
|
||||
|
||||
if (player.isDead()) {
|
||||
remove(player);
|
||||
return;
|
||||
if(particleScale < 1)
|
||||
particleScale = 1;
|
||||
else if(particleScale > 2)
|
||||
particleScale = 2;
|
||||
|
||||
if(AvatarState.isAvatarState(player)) {
|
||||
for(Entity ent : Methods.getEntitiesAroundPoint(player.getLocation(), range))
|
||||
if(ent instanceof LivingEntity && !ent.equals(player))
|
||||
targets.add((LivingEntity) ent);
|
||||
}
|
||||
|
||||
if (!Methods.canBend(player.getName(), "Suffocate")) {
|
||||
remove(player);
|
||||
return;
|
||||
else {
|
||||
Entity ent = Methods.getTargetedEntity(player, range, new ArrayList<Entity>());
|
||||
if(ent != null && ent instanceof LivingEntity)
|
||||
targets.add((LivingEntity) ent);
|
||||
}
|
||||
|
||||
if (Methods.getBoundAbility(player) == null || !Methods.getBoundAbility(player).equalsIgnoreCase("Suffocate")) {
|
||||
remove(player);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
for (Entity entity: targets.keySet()) {
|
||||
if (!targets.keySet().iterator().hasNext()) {
|
||||
remove(player);
|
||||
return;
|
||||
}
|
||||
if (targets.isEmpty()) {
|
||||
remove(player);
|
||||
return;
|
||||
}
|
||||
if (isUndead(entity) && !canBeUsedOnUndead) {
|
||||
breakSuffocate(entity);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entity.getLocation().getBlock() != null && Methods.isWater(entity.getLocation().getBlock())) {
|
||||
breakSuffocate(entity);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Methods.isRegionProtectedFromBuild(player, "Suffocate", entity.getLocation())) {
|
||||
remove(player);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entity.getLocation().distance(player.getLocation()) >= range) {
|
||||
breakSuffocate(entity);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Methods.isObstructed(player.getLocation(), entity.getLocation())) {
|
||||
breakSuffocate(entity);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entity instanceof Player) {
|
||||
if (Commands.invincible.contains(((Player) entity).getName())) {
|
||||
breakSuffocate(entity);
|
||||
continue;
|
||||
}
|
||||
if (AvatarState.isAvatarState((Player) entity)) {
|
||||
breakSuffocate(entity);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (entity.isDead()) {
|
||||
breakSuffocate(entity);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entity instanceof Creature) {
|
||||
((Creature) entity).setTarget(player);
|
||||
}
|
||||
|
||||
for(Location airsphere : Methods.getCircle(entity.getLocation(), 3, 3, false, true, 0)) {
|
||||
Methods.playAirbendingParticles(airsphere, 1);
|
||||
if (Methods.rand.nextInt(4) == 0) {
|
||||
Methods.playAirbendingSound(airsphere);
|
||||
}
|
||||
}
|
||||
entity.setFallDistance(0);
|
||||
new TempPotionEffect((LivingEntity) entity, slow);
|
||||
new TempPotionEffect((LivingEntity) entity, nausea);
|
||||
if (System.currentTimeMillis() >= time + warmup) {
|
||||
Methods.damageEntity(player, entity, damage);
|
||||
entity.setVelocity(new Vector(0, 0, 0));
|
||||
|
||||
if(!canSuffUndead) {
|
||||
for(int i = 0; i < targets.size(); i++) {
|
||||
LivingEntity target = targets.get(i);
|
||||
if(Methods.isUndead(target)) {
|
||||
targets.remove(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
} catch (ConcurrentModificationException e) {
|
||||
}
|
||||
|
||||
if(targets.size() == 0)
|
||||
return;
|
||||
else if(bplayer.isOnCooldown("suffocate"))
|
||||
return;
|
||||
bplayer.addCooldown("suffocate", cooldown);
|
||||
instances.put(player,this);
|
||||
}
|
||||
|
||||
/** Progresses this instance of Suffocate by 1 tick. **/
|
||||
public void progress() {
|
||||
if(targets.size() == 0) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
if (player.isDead() || !player.isOnline()) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
String ability = Methods.getBoundAbility(player);
|
||||
if(ability == null
|
||||
|| !ability.equalsIgnoreCase("Suffocate")
|
||||
|| !Methods.canBend(player.getName(), "Suffocate")) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
for(int i = 0; i < targets.size(); i++) {
|
||||
LivingEntity target = targets.get(i);
|
||||
if(target.isDead()
|
||||
|| !target.getWorld().equals(player.getWorld())
|
||||
|| target.getLocation().distance(player.getEyeLocation()) > range) {
|
||||
breakSuffocateLocal(target);
|
||||
i--;
|
||||
}
|
||||
else if(target instanceof Player) {
|
||||
Player targPlayer = (Player)target;
|
||||
if(!targPlayer.isOnline()) {
|
||||
breakSuffocateLocal(target);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(targets.size() == 0) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
|
||||
if(reqConstantAim) {
|
||||
double dist = player.getEyeLocation().distance(targets.get(0).getEyeLocation());
|
||||
Location targetLoc = player.getEyeLocation().clone().add
|
||||
(player.getEyeLocation().getDirection().normalize().multiply(dist));
|
||||
List<Entity> ents = Methods.getEntitiesAroundPoint(targetLoc, aimRadius);
|
||||
|
||||
for(int i = 0; i < targets.size(); i++) {
|
||||
LivingEntity target = targets.get(i);
|
||||
if(!ents.contains(target)) {
|
||||
breakSuffocateLocal(target);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
if(targets.size() == 0) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(System.currentTimeMillis() - time < chargeTime) {
|
||||
return;
|
||||
}
|
||||
else if(!started) {
|
||||
started = true;
|
||||
final Player fplayer = player;
|
||||
for(LivingEntity targ : targets) {
|
||||
final LivingEntity target = targ;
|
||||
BukkitRunnable br1 = new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Methods.damageEntity(fplayer, target, damage);
|
||||
}
|
||||
};
|
||||
BukkitRunnable br2 = new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
target.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, (int) (slowRepeat * 20), (int) slow));
|
||||
}
|
||||
};
|
||||
BukkitRunnable br3 = new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
target.addPotionEffect(new PotionEffect(PotionEffectType.BLINDNESS, (int) (blindRepeat * 20), (int) blind));
|
||||
}
|
||||
};
|
||||
|
||||
tasks.add(br1);
|
||||
tasks.add(br2);
|
||||
tasks.add(br3);
|
||||
br1.runTaskTimer(ProjectKorra.plugin, (long) (damageDelay * 20), (long) (damageRepeat * 20));
|
||||
br2.runTaskTimer(ProjectKorra.plugin, (long) (slowDelay * 20), (long) (slowRepeat * 20 / 0.25));
|
||||
br3.runTaskTimer(ProjectKorra.plugin, (long) (blindDelay * 20), (long) (blindRepeat * 20));
|
||||
}
|
||||
}
|
||||
|
||||
animate();
|
||||
if(!player.isSneaking()) {
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Animates this instance of the Suffocate ability.
|
||||
* Depending on the specific time (dt) the ability will create
|
||||
* a different set of SuffocationSpirals.
|
||||
*/
|
||||
public void animate() {
|
||||
long curTime = System.currentTimeMillis();
|
||||
long dt = curTime - time - chargeTime;
|
||||
int steps = 8 * particleScale;
|
||||
long delay = 2 / particleScale;
|
||||
long t1 = (long) (1500 * speedFactor);
|
||||
long t2 = (long) (2500 * speedFactor);
|
||||
long t3 = (long) (5000 * speedFactor);
|
||||
long t4 = (long) (6000 * speedFactor);
|
||||
for(LivingEntity lent : targets) {
|
||||
final LivingEntity target = lent;
|
||||
if(dt < t1) {
|
||||
new SuffocateSpiral(target, steps, radius, delay, 0, 0.25 - (0.25 * (double)dt / (double)t1), 0, SpiralType.HORIZONTAL1);
|
||||
new SuffocateSpiral(target, steps, radius, delay, 0, 0.25 - (0.25 * (double)dt / (double)t1), 0, SpiralType.HORIZONTAL2);
|
||||
}
|
||||
else if(dt < t2) {
|
||||
new SuffocateSpiral(target, steps, radius, delay, 0, 0, 0, SpiralType.HORIZONTAL1);
|
||||
new SuffocateSpiral(target, steps * 2, radius, delay, 0, 0, 0, SpiralType.VERTICAL1);
|
||||
new SuffocateSpiral(target, steps * 2, radius, delay, 0, 0, 0, SpiralType.VERTICAL2);
|
||||
}
|
||||
else if(dt < t3) {
|
||||
new SuffocateSpiral(target, steps, radius, delay, 0, 0, 0, SpiralType.HORIZONTAL1);
|
||||
new SuffocateSpiral(target, steps, radius, delay, 0, 0, 0, SpiralType.VERTICAL1);
|
||||
new SuffocateSpiral(target, steps, radius, delay, 0, 0, 0, SpiralType.VERTICAL2);
|
||||
}
|
||||
else if(dt < t4) {
|
||||
new SuffocateSpiral(target, steps, radius - Math.min(radius * 3 / 4, (radius * 3.0 / 4 * ((double)(dt - t3) / (double)(t4 - t3)))), delay, 0, 0, 0, SpiralType.HORIZONTAL1);
|
||||
new SuffocateSpiral(target, steps, radius - Math.min(radius * 3 / 4, (radius * 3.0 / 4 * ((double)(dt - t3) / (double)(t4 - t3)))), delay, 0, 0, 0, SpiralType.VERTICAL1);
|
||||
new SuffocateSpiral(target, steps, radius - Math.min(radius * 3 / 4, (radius * 3.0 / 4 * ((double)(dt - t3) / (double)(t4 - t3)))), delay, 0, 0, 0, SpiralType.VERTICAL2);
|
||||
}
|
||||
else {
|
||||
new SuffocateSpiral(target, steps, radius - (radius * 3.0 / 4.0), delay, 0, 0, 0, SpiralType.HORIZONTAL1);
|
||||
new SuffocateSpiral(target, steps, radius - (radius * 3.0 / 4.0), delay, 0, 0, 0, SpiralType.VERTICAL1);
|
||||
new SuffocateSpiral(target, steps, radius - (radius * 3.0 / 4.0), delay, 0, 0, 0, SpiralType.VERTICAL2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** **
|
||||
* Animates a Spiral of air particles around a location or a targetted entity.
|
||||
* The direction of the spiral is determined by SpiralType, and each type
|
||||
* is calculated independently from one another.
|
||||
*/
|
||||
public class SuffocateSpiral extends BukkitRunnable {
|
||||
private Location startLoc;
|
||||
private Location loc;
|
||||
private LivingEntity target;
|
||||
private int totalSteps;
|
||||
private double radius;
|
||||
private double dx, dy, dz;
|
||||
private SpiralType type;
|
||||
private int i;
|
||||
|
||||
/**
|
||||
* @param startLoc: initial location
|
||||
* @param totalSteps: amount of times it will be animated
|
||||
* @param radius: the radius of the spiral
|
||||
* @param interval: the speed of the animation
|
||||
* @param dx: x offset
|
||||
* @param dy: y offset
|
||||
* @param dz: z offset
|
||||
* @param type: spiral animation direction
|
||||
*/
|
||||
public SuffocateSpiral(Location startLoc, int totalSteps, double radius,
|
||||
long interval, double dx, double dy, double dz, SpiralType type) {
|
||||
this.startLoc = startLoc;
|
||||
this.totalSteps = totalSteps;
|
||||
this.radius = radius;
|
||||
this.dx = dx;
|
||||
this.dy = dy;
|
||||
this.dz = dz;
|
||||
this.type = type;
|
||||
|
||||
loc = startLoc.clone();
|
||||
i = 0;
|
||||
this.runTaskTimer(ProjectKorra.plugin, 0L, interval);
|
||||
tasks.add(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param lent: the entity to animate the spiral around
|
||||
* @param totalSteps: amount of times it will be animated
|
||||
* @param radius: the radius of the spiral
|
||||
* @param interval: the speed of the animation
|
||||
* @param dx: x offset
|
||||
* @param dy: y offset
|
||||
* @param dz: z offset
|
||||
* @param type: spiral animation direction
|
||||
*/
|
||||
public SuffocateSpiral(LivingEntity lent, int totalSteps, double radius,
|
||||
long interval, double dx, double dy, double dz, SpiralType type) {
|
||||
this.target = lent;
|
||||
this.totalSteps = totalSteps;
|
||||
this.radius = radius;
|
||||
this.dx = dx;
|
||||
this.dy = dy;
|
||||
this.dz = dz;
|
||||
this.type = type;
|
||||
|
||||
loc = target.getEyeLocation();
|
||||
i = 0;
|
||||
this.runTaskTimer(ProjectKorra.plugin, 0L, interval);
|
||||
tasks.add(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the initial animation, and removes
|
||||
* itself when it is finished.
|
||||
*/
|
||||
public void run() {
|
||||
Location tempLoc;
|
||||
if(target != null) {
|
||||
tempLoc = target.getEyeLocation();
|
||||
tempLoc.setY(tempLoc.getY() - 0.5);
|
||||
}
|
||||
else
|
||||
tempLoc = startLoc.clone();
|
||||
|
||||
if(type == SpiralType.HORIZONTAL1) {
|
||||
loc.setX(tempLoc.getX() + radius * Math.cos(Math.toRadians((double)i / (double)totalSteps * 360)));
|
||||
loc.setY(tempLoc.getY() + dy * i);
|
||||
loc.setZ(tempLoc.getZ() + radius * Math.sin(Math.toRadians((double)i / (double)totalSteps * 360)));
|
||||
}
|
||||
else if(type == SpiralType.HORIZONTAL2) {
|
||||
loc.setX(tempLoc.getX() + radius * -Math.cos(Math.toRadians((double)i / (double)totalSteps * 360)));
|
||||
loc.setY(tempLoc.getY() + dy * i);
|
||||
loc.setZ(tempLoc.getZ() + radius * -Math.sin(Math.toRadians((double)i / (double)totalSteps * 360)));
|
||||
}
|
||||
else if(type == SpiralType.VERTICAL1) {
|
||||
loc.setX(tempLoc.getX() + radius * Math.sin(Math.toRadians((double)i / (double)totalSteps * 360)));
|
||||
loc.setY(tempLoc.getY() + radius * Math.cos(Math.toRadians((double)i / (double)totalSteps * 360)));
|
||||
loc.setZ(tempLoc.getZ() + dz * i);
|
||||
}
|
||||
else if(type == SpiralType.VERTICAL2) {
|
||||
loc.setX(tempLoc.getX() + dx * i);
|
||||
loc.setY(tempLoc.getY() + radius * Math.sin(Math.toRadians((double)i / (double)totalSteps * 360)));
|
||||
loc.setZ(tempLoc.getZ() + radius * Math.cos(Math.toRadians((double)i / (double)totalSteps * 360)));
|
||||
}
|
||||
else if(type == SpiralType.DIAGONAL1) {
|
||||
loc.setX(tempLoc.getX() + radius * Math.cos(Math.toRadians((double)i / (double)totalSteps * 360)));
|
||||
loc.setY(tempLoc.getY() + radius * Math.sin(Math.toRadians((double)i / (double)totalSteps * 360)));
|
||||
loc.setZ(tempLoc.getZ() + radius * -Math.cos(Math.toRadians((double)i / (double)totalSteps * 360)));
|
||||
}
|
||||
else if(type == SpiralType.DIAGONAL2) {
|
||||
loc.setX(tempLoc.getX() + radius * Math.cos(Math.toRadians((double)i / (double)totalSteps * 360)));
|
||||
loc.setY(tempLoc.getY() + radius * Math.sin(Math.toRadians((double)i / (double)totalSteps * 360)));
|
||||
loc.setZ(tempLoc.getZ() + radius * Math.cos(Math.toRadians((double)i / (double)totalSteps * 360)));
|
||||
}
|
||||
|
||||
Methods.getAirbendingParticles().display(loc, (float) 0, (float) 0, (float) 0, 0, 1);
|
||||
if(i == totalSteps + 1)
|
||||
this.cancel();
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/** Progresses every instance of Suffocate by 1 tick **/
|
||||
public static void progressAll() {
|
||||
for (Player player : instances.keySet()) {
|
||||
instances.get(player).progress();
|
||||
for(Suffocate suff : instances.values())
|
||||
suff.progress();
|
||||
}
|
||||
|
||||
/** Removes this instance of the ability **/
|
||||
public void remove() {
|
||||
instances.remove(player);
|
||||
for(int i = 0; i < tasks.size(); i++) {
|
||||
tasks.get(i).cancel();
|
||||
tasks.remove(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Removes all instances of Suffocate at loc within the radius threshold.
|
||||
* The location of a Suffocate is defined at the benders location, not
|
||||
* the location of the entities being suffocated.
|
||||
* @param causer: the player causing this instance to be removed
|
||||
* **/
|
||||
public static boolean removeAtLocation(Player causer, Location loc, double radius) {
|
||||
Iterator<Player> it = instances.keySet().iterator();
|
||||
while(it.hasNext()) {
|
||||
Player key = it.next();
|
||||
Suffocate val = instances.get(key);
|
||||
|
||||
if (causer == null || !key.equals(causer)) {
|
||||
Location playerLoc = val.getPlayer().getLocation();
|
||||
if(playerLoc.getWorld().equals(loc.getWorld()) && playerLoc.distance(loc) <= radius) {
|
||||
it.remove();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Removes an instance of Suffocate if player is the one suffocating entities **/
|
||||
public static void remove(Player player) {
|
||||
if (instances.containsKey(player)) {
|
||||
instances.remove(player);
|
||||
if (instances.containsKey(player))
|
||||
instances.get(player).remove();
|
||||
}
|
||||
|
||||
/** Removes every instance of Suffocate **/
|
||||
public static void removeAll() {
|
||||
Enumeration<Player> keys = instances.keys();
|
||||
while(keys.hasMoreElements()) {
|
||||
instances.get(keys.nextElement()).remove();
|
||||
}
|
||||
}
|
||||
|
||||
public static void breakSuffocate(Entity entity) {
|
||||
for (Player player : instances.keySet()) {
|
||||
if (instances.get(player).targets.containsKey(entity)) {
|
||||
instances.get(player).targets.remove(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isBreathbent(Entity entity) {
|
||||
for (Player player : instances.keySet()) {
|
||||
if (instances.get(player).targets.containsKey(entity)) {
|
||||
if (System.currentTimeMillis() >= instances.get(player).time + instances.get(player).warmup) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isUndead(Entity entity) {
|
||||
if (entity == null) return false;
|
||||
if (entity.getType() == EntityType.ZOMBIE
|
||||
|| entity.getType() == EntityType.BLAZE
|
||||
|| entity.getType() == EntityType.GIANT
|
||||
|| entity.getType() == EntityType.IRON_GOLEM
|
||||
|| entity.getType() == EntityType.MAGMA_CUBE
|
||||
|| entity.getType() == EntityType.PIG_ZOMBIE
|
||||
|| entity.getType() == EntityType.SKELETON
|
||||
|| entity.getType() == EntityType.SLIME
|
||||
|| entity.getType() == EntityType.SNOWMAN
|
||||
|| entity.getType() == EntityType.ZOMBIE) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/** Determines if a player is Suffocating entities **/
|
||||
public static boolean isChannelingSphere(Player player){
|
||||
if(instances.containsKey(player)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void removeAll() {
|
||||
instances.clear();
|
||||
|
||||
/** Stops an entity from being suffocated **/
|
||||
public void breakSuffocateLocal(Entity entity) {
|
||||
if (targets.contains(entity))
|
||||
targets.remove(entity);
|
||||
}
|
||||
|
||||
/** Stops an entity from being suffocated **/
|
||||
public static void breakSuffocate(Entity entity) {
|
||||
for (Player player : instances.keySet()) {
|
||||
if (instances.get(player).targets.contains(entity)) {
|
||||
instances.get(player).breakSuffocateLocal(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Checks if an entity is being suffocated **/
|
||||
public static boolean isBreathbent(Entity entity) {
|
||||
for (Player player : instances.keySet()) {
|
||||
if (instances.get(player).targets.contains(entity)) {
|
||||
return instances.get(player).started;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
public static ConcurrentHashMap<Player, Suffocate> getInstances() {
|
||||
return instances;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public boolean isStarted() {
|
||||
return started;
|
||||
}
|
||||
|
||||
public void setStarted(boolean started) {
|
||||
this.started = started;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(long time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public ArrayList<BukkitRunnable> getTasks() {
|
||||
return tasks;
|
||||
}
|
||||
|
||||
public void setTasks(ArrayList<BukkitRunnable> tasks) {
|
||||
this.tasks = tasks;
|
||||
}
|
||||
|
||||
public ArrayList<LivingEntity> getTargets() {
|
||||
return targets;
|
||||
}
|
||||
|
||||
public void setTargets(ArrayList<LivingEntity> targets) {
|
||||
this.targets = targets;
|
||||
}
|
||||
|
||||
public boolean isReqConstantAim() {
|
||||
return reqConstantAim;
|
||||
}
|
||||
|
||||
public void setReqConstantAim(boolean reqConstantAim) {
|
||||
this.reqConstantAim = reqConstantAim;
|
||||
}
|
||||
|
||||
public boolean isCanSuffUndead() {
|
||||
return canSuffUndead;
|
||||
}
|
||||
|
||||
public void setCanSuffUndead(boolean canSuffUndead) {
|
||||
this.canSuffUndead = canSuffUndead;
|
||||
}
|
||||
|
||||
public long getChargeTime() {
|
||||
return chargeTime;
|
||||
}
|
||||
|
||||
public void setChargeTime(long chargeTime) {
|
||||
this.chargeTime = chargeTime;
|
||||
}
|
||||
|
||||
public long getCooldown() {
|
||||
return cooldown;
|
||||
}
|
||||
|
||||
public void setCooldown(long cooldown) {
|
||||
this.cooldown = cooldown;
|
||||
}
|
||||
|
||||
public int getParticleScale() {
|
||||
return particleScale;
|
||||
}
|
||||
|
||||
public void setParticleScale(int particleScale) {
|
||||
this.particleScale = particleScale;
|
||||
}
|
||||
|
||||
public double getRange() {
|
||||
return range;
|
||||
}
|
||||
|
||||
public void setRange(double range) {
|
||||
this.range = range;
|
||||
}
|
||||
|
||||
public double getRadius() {
|
||||
return radius;
|
||||
}
|
||||
|
||||
public void setRadius(double radius) {
|
||||
this.radius = radius;
|
||||
}
|
||||
|
||||
public double getSpeedFactor() {
|
||||
return speedFactor;
|
||||
}
|
||||
|
||||
public void setSpeedFactor(double speedFactor) {
|
||||
this.speedFactor = speedFactor;
|
||||
}
|
||||
|
||||
public double getAimRadius() {
|
||||
return aimRadius;
|
||||
}
|
||||
|
||||
public void setAimRadius(double aimRadius) {
|
||||
this.aimRadius = aimRadius;
|
||||
}
|
||||
|
||||
public double getDamage() {
|
||||
return damage;
|
||||
}
|
||||
|
||||
public void setDamage(double damage) {
|
||||
this.damage = damage;
|
||||
}
|
||||
|
||||
public double getDamageDelay() {
|
||||
return damageDelay;
|
||||
}
|
||||
|
||||
public void setDamageDelay(double damageDelay) {
|
||||
this.damageDelay = damageDelay;
|
||||
}
|
||||
|
||||
public double getDamageRepeat() {
|
||||
return damageRepeat;
|
||||
}
|
||||
|
||||
public void setDamageRepeat(double damageRepeat) {
|
||||
this.damageRepeat = damageRepeat;
|
||||
}
|
||||
|
||||
public double getSlow() {
|
||||
return slow;
|
||||
}
|
||||
|
||||
public void setSlow(double slow) {
|
||||
this.slow = slow;
|
||||
}
|
||||
|
||||
public double getslowRepeat() {
|
||||
return slowRepeat;
|
||||
}
|
||||
|
||||
public void setslowRepeat(double slowRepeat) {
|
||||
this.slowRepeat = slowRepeat;
|
||||
}
|
||||
|
||||
public double getSlowDelay() {
|
||||
return slowDelay;
|
||||
}
|
||||
|
||||
public void setSlowDelay(double slowDelay) {
|
||||
this.slowDelay = slowDelay;
|
||||
}
|
||||
|
||||
public double getBlind() {
|
||||
return blind;
|
||||
}
|
||||
|
||||
public void setBlind(double blind) {
|
||||
this.blind = blind;
|
||||
}
|
||||
|
||||
public double getBlindDelay() {
|
||||
return blindDelay;
|
||||
}
|
||||
|
||||
public void setBlindDelay(double blindDelay) {
|
||||
this.blindDelay = blindDelay;
|
||||
}
|
||||
|
||||
public double getBlindRepeat() {
|
||||
return blindRepeat;
|
||||
}
|
||||
|
||||
public void setBlindRepeat(double blindRepeat) {
|
||||
this.blindRepeat = blindRepeat;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,11 +15,11 @@ public class ChiblockingManager implements Runnable {
|
|||
|
||||
@Override
|
||||
public void run() {
|
||||
ChiPassive.handlePassive();
|
||||
WarriorStance.progressAll();
|
||||
AcrobatStance.progressAll();
|
||||
for(Player player : Bukkit.getOnlinePlayers()) {
|
||||
ChiPassive.handlePassive();
|
||||
Smokescreen.removeFromHashMap(player);
|
||||
WarriorStance.progressAll();
|
||||
AcrobatStance.progressAll();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -546,9 +546,12 @@ public class EarthSmash {
|
|||
|
||||
for(EarthSmash smash : instances) {
|
||||
//Check to see if the player is standing on top of the smash.
|
||||
if(smash.state == State.LIFTED)
|
||||
if(smash.loc.clone().add(0,2,0).distanceSquared(player.getLocation()) <= Math.pow(FLIGHT_DETECTION_RADIUS, 2))
|
||||
if(smash.state == State.LIFTED) {
|
||||
if(smash.loc.getWorld().equals(player.getWorld())
|
||||
&& smash.loc.clone().add(0,2,0).distanceSquared(player.getLocation()) <= Math.pow(FLIGHT_DETECTION_RADIUS, 2)) {
|
||||
return smash;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -27,22 +27,38 @@ public class Extraction {
|
|||
}
|
||||
if (!Methods.isRegionProtectedFromBuild(player, "Extraction", block.getLocation())) {
|
||||
if (Methods.canMetalbend(player) && Methods.canBend(player.getName(), "Extraction")) {
|
||||
Material type = null;
|
||||
|
||||
switch(block.getType()) {
|
||||
case IRON_ORE:
|
||||
block.setType(Material.STONE);
|
||||
player.getWorld().dropItem(player.getLocation(), new ItemStack(Material.IRON_INGOT, getAmount()));
|
||||
type = Material.STONE;
|
||||
break;
|
||||
case GOLD_ORE:
|
||||
block.setType(Material.STONE);
|
||||
player.getWorld().dropItem(player.getLocation(), new ItemStack(Material.GOLD_INGOT, getAmount()));
|
||||
type = Material.STONE;
|
||||
break;
|
||||
case QUARTZ_ORE:
|
||||
block.setType(Material.NETHERRACK);
|
||||
player.getWorld().dropItem(player.getLocation(), new ItemStack(Material.QUARTZ, getAmount()));
|
||||
type = Material.NETHERRACK;
|
||||
break;
|
||||
default:
|
||||
break; // shouldn't happen.
|
||||
}
|
||||
|
||||
if(type != null) {
|
||||
/* Update the block from Methods.movedearth to Stone otherwise
|
||||
* players can use RaiseEarth > Extraction > Collapse
|
||||
* to dupe the material from the block.
|
||||
* */
|
||||
if(Methods.movedearth.containsKey(block)) {
|
||||
Methods.movedearth.remove(block);
|
||||
}
|
||||
}
|
||||
|
||||
Methods.playMetalbendingSound(block.getLocation());
|
||||
bPlayer.addCooldown("Extraction", cooldown);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
package com.projectkorra.ProjectKorra.firebending;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.projectkorra.ProjectKorra.Ability.AvatarState;
|
||||
import com.projectkorra.ProjectKorra.*;
|
||||
import com.projectkorra.ProjectKorra.ComboManager.ClickType;
|
||||
import com.projectkorra.ProjectKorra.Utilities.ParticleEffect;
|
||||
import com.projectkorra.ProjectKorra.chiblocking.Paralyze;
|
||||
import com.projectkorra.ProjectKorra.waterbending.Bloodbending;
|
||||
import org.bukkit.Effect;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
|
@ -15,15 +18,8 @@ import org.bukkit.entity.Player;
|
|||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import com.projectkorra.ProjectKorra.BendingPlayer;
|
||||
import com.projectkorra.ProjectKorra.ComboManager.ClickType;
|
||||
import com.projectkorra.ProjectKorra.Commands;
|
||||
import com.projectkorra.ProjectKorra.Methods;
|
||||
import com.projectkorra.ProjectKorra.ProjectKorra;
|
||||
import com.projectkorra.ProjectKorra.Ability.AvatarState;
|
||||
import com.projectkorra.ProjectKorra.Utilities.ParticleEffect;
|
||||
import com.projectkorra.ProjectKorra.chiblocking.Paralyze;
|
||||
import com.projectkorra.ProjectKorra.waterbending.Bloodbending;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class FireCombo {
|
||||
public static final List<String> abilitiesToBlock = new ArrayList<String>() {
|
||||
|
@ -103,11 +99,13 @@ public class FireCombo {
|
|||
// Dont' call Methods.canBind directly, it doesn't let you combo as fast
|
||||
if (!enabled || !player.hasPermission("bending.ability.FireCombo"))
|
||||
return;
|
||||
if (Methods.isRegionProtectedFromBuild(player, "Blaze",
|
||||
player.getLocation()))
|
||||
if(!Methods.getBendingPlayer(player.getName()).hasElement(Element.Fire))
|
||||
return;
|
||||
if (Commands.isToggledForAll)
|
||||
return;
|
||||
if (Methods.isRegionProtectedFromBuild(player, "Blaze",
|
||||
player.getLocation()))
|
||||
return;
|
||||
if (!Methods.getBendingPlayer(player.getName()).isToggled())
|
||||
return;
|
||||
time = System.currentTimeMillis();
|
||||
|
|
|
@ -20,11 +20,13 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class Lightning {
|
||||
public static enum State {
|
||||
public class Lightning
|
||||
{
|
||||
public static enum State
|
||||
{
|
||||
START, STRIKE, MAINBOLT
|
||||
}
|
||||
|
||||
|
||||
public static ArrayList<Lightning> instances = new ArrayList<Lightning>();
|
||||
public static boolean SELF_HIT_WATER = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Fire.Lightning.SelfHitWater");
|
||||
public static boolean SELF_HIT_CLOSE = ProjectKorra.plugin.getConfig().getBoolean("Abilities.Fire.Lightning.SelfHitClose");
|
||||
|
@ -42,8 +44,8 @@ public class Lightning {
|
|||
public static int WATER_ARCS = (int) ProjectKorra.plugin.getConfig().getDouble("Abilities.Fire.Lightning.WaterArcs");
|
||||
public static long CHARGETIME = (long) ProjectKorra.plugin.getConfig().getDouble("Abilities.Fire.Lightning.ChargeTime");
|
||||
public static long COOLDOWN = (long) ProjectKorra.plugin.getConfig().getDouble("Abilities.Fire.Lightning.Cooldown");
|
||||
|
||||
private static final int POINT_GENERATION = 5;
|
||||
|
||||
private static final int POINT_GENERATION = 5;
|
||||
|
||||
private Player player;
|
||||
private BendingPlayer bplayer;
|
||||
|
@ -58,7 +60,8 @@ public class Lightning {
|
|||
private ArrayList<BukkitRunnable> tasks = new ArrayList<BukkitRunnable>();
|
||||
private HashMap<Block, Boolean> isTransparentCache = new HashMap<Block, Boolean>();
|
||||
|
||||
public Lightning(Player player) {
|
||||
public Lightning(Player player)
|
||||
{
|
||||
this.player = player;
|
||||
bplayer = Methods.getBendingPlayer(player.getName());
|
||||
charged = false;
|
||||
|
@ -76,8 +79,9 @@ public class Lightning {
|
|||
stunDuration = Methods.getFirebendingDayAugment(STUN_DURATION, player.getWorld());
|
||||
chargeTime = CHARGETIME;
|
||||
cooldown = COOLDOWN;
|
||||
|
||||
if(AvatarState.isAvatarState(player)) {
|
||||
|
||||
if (AvatarState.isAvatarState(player))
|
||||
{
|
||||
//range = AvatarState.getValue(range);
|
||||
chargeTime = 0;
|
||||
cooldown = 0;
|
||||
|
@ -90,65 +94,78 @@ public class Lightning {
|
|||
stunChance = AvatarState.getValue(stunChance);
|
||||
//stunDuration = AvatarState.getValue(stunDuration);
|
||||
}
|
||||
else if(BendingManager.events.containsKey(player.getWorld())) {
|
||||
if (BendingManager.events.get(player.getWorld()).equalsIgnoreCase("SozinsComet")) {
|
||||
else if (BendingManager.events.containsKey(player.getWorld()))
|
||||
{
|
||||
if (BendingManager.events.get(player.getWorld()).equalsIgnoreCase("SozinsComet"))
|
||||
{
|
||||
chargeTime = 0;
|
||||
cooldown = 0;
|
||||
}
|
||||
}
|
||||
instances.add(this);
|
||||
}
|
||||
|
||||
public void displayChargedParticles(){
|
||||
Location l = player.getEyeLocation().add(player.getEyeLocation().getDirection().normalize().multiply(1));
|
||||
|
||||
public void displayChargedParticles()
|
||||
{
|
||||
Location l = player.getEyeLocation().add(player.getEyeLocation().getDirection().normalize().multiply(1));
|
||||
l.setX(l.getX() + Math.random() * (0.1 - -0.1));
|
||||
l.setY(l.getY() + Math.random() * (0.1 - -0.1));
|
||||
l.setZ(l.getZ() + Math.random() * (0.1 - -0.1));
|
||||
|
||||
|
||||
ParticleEffect.RED_DUST.display((float) 0, (float) 255, (float) 255, 0.1F, 0, l, 256D);
|
||||
}
|
||||
|
||||
private void progress() {
|
||||
if (player.isDead() || !player.isOnline()) {
|
||||
|
||||
private void progress()
|
||||
{
|
||||
if (player.isDead() || !player.isOnline())
|
||||
{
|
||||
removeWithTasks();
|
||||
return;
|
||||
}
|
||||
else if (Methods.getBoundAbility(player) == null || !Methods.getBoundAbility(player).equalsIgnoreCase("Lightning")) {
|
||||
else if (Methods.getBoundAbility(player) == null || !Methods.getBoundAbility(player).equalsIgnoreCase("Lightning"))
|
||||
{
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
if(state == State.START) {
|
||||
if(bplayer.isOnCooldown("Lightning")) {
|
||||
if (state == State.START)
|
||||
{
|
||||
if (bplayer.isOnCooldown("Lightning"))
|
||||
{
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
if (System.currentTimeMillis() - time > chargeTime)
|
||||
charged = true;
|
||||
if(charged) {
|
||||
if(player.isSneaking()) {
|
||||
if (charged)
|
||||
{
|
||||
if (player.isSneaking())
|
||||
{
|
||||
Location loc = player.getEyeLocation().add(player.getEyeLocation()
|
||||
.getDirection().normalize().multiply(1.2));
|
||||
loc.add(0, 0.3, 0);
|
||||
displayChargedParticles();
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
state = State.MAINBOLT;
|
||||
bplayer.addCooldown("Lightning", (long) cooldown);
|
||||
Entity target = Methods.getTargetedEntity(player, range, new ArrayList<Entity>());
|
||||
origin = player.getEyeLocation();
|
||||
if(target != null)
|
||||
if (target != null)
|
||||
destination = target.getLocation();
|
||||
else
|
||||
destination = player.getEyeLocation().add(
|
||||
player.getEyeLocation().getDirection().normalize().multiply(range));
|
||||
}
|
||||
}
|
||||
else if(!player.isSneaking()) {
|
||||
else if (!player.isSneaking())
|
||||
{
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(state == State.MAINBOLT) {
|
||||
else if (state == State.MAINBOLT)
|
||||
{
|
||||
Arc mainArc = new Arc(origin, destination);
|
||||
mainArc.generatePoints(POINT_GENERATION);
|
||||
arcs.add(mainArc);
|
||||
|
@ -156,72 +173,86 @@ public class Lightning {
|
|||
arcs.addAll(subArcs);
|
||||
state = State.STRIKE;
|
||||
}
|
||||
else if(state == State.STRIKE) {
|
||||
for(int i = 0; i < arcs.size(); i++) {
|
||||
else if (state == State.STRIKE)
|
||||
{
|
||||
for (int i = 0; i < arcs.size(); i++)
|
||||
{
|
||||
Arc arc = arcs.get(i);
|
||||
for(int j = 0; j < arc.getAnimLocs().size() - 1; j++) {
|
||||
for (int j = 0; j < arc.getAnimLocs().size() - 1; j++)
|
||||
{
|
||||
final Location iterLoc = arc.getAnimLocs().get(j).getLoc().clone();
|
||||
final Location dest = arc.getAnimLocs().get(j + 1).getLoc().clone();
|
||||
if(SELF_HIT_CLOSE
|
||||
&& player.getLocation().distance(iterLoc) < 3
|
||||
if (SELF_HIT_CLOSE
|
||||
&& player.getLocation().distance(iterLoc) < 3
|
||||
&& !isTransparent(player, iterLoc.getBlock())
|
||||
&& !affectedEntities.contains(player)) {
|
||||
affectedEntities.add(player);
|
||||
electrocute(player);
|
||||
}
|
||||
|
||||
while(iterLoc.distance(dest) > 0.15) {
|
||||
&& !affectedEntities.contains(player))
|
||||
{
|
||||
affectedEntities.add(player);
|
||||
electrocute(player);
|
||||
}
|
||||
|
||||
while (iterLoc.distance(dest) > 0.15)
|
||||
{
|
||||
BukkitRunnable task = new LightningParticle(arc, iterLoc.clone());
|
||||
double timer = arc.getAnimLocs().get(j).getAnimCounter() / 2;
|
||||
task.runTaskTimer(ProjectKorra.plugin, (long) timer, 1);
|
||||
tasks.add(task);
|
||||
tasks.add(task);
|
||||
iterLoc.add(Methods.getDirection(iterLoc, dest).normalize().multiply(0.15));
|
||||
}
|
||||
}
|
||||
arcs.remove(i);
|
||||
i--;
|
||||
}
|
||||
if(tasks.size() == 0) {
|
||||
if (tasks.size() == 0)
|
||||
{
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isTransparent(Player player, Block block) {
|
||||
if(isTransparentCache.containsKey(block))
|
||||
|
||||
public boolean isTransparent(Player player, Block block)
|
||||
{
|
||||
if (isTransparentCache.containsKey(block))
|
||||
return isTransparentCache.get(block);
|
||||
|
||||
|
||||
boolean value = false;
|
||||
if (Arrays.asList(Methods.transparentToEarthbending).contains(block.getTypeId())) {
|
||||
if(Methods.isRegionProtectedFromBuild(player, "Lightning", block.getLocation()))
|
||||
if (Arrays.asList(Methods.transparentToEarthbending).contains(block.getTypeId()))
|
||||
{
|
||||
if (Methods.isRegionProtectedFromBuild(player, "Lightning", block.getLocation()))
|
||||
value = false;
|
||||
else if(isIce(block.getLocation()))
|
||||
else if (isIce(block.getLocation()))
|
||||
value = ARC_ON_ICE;
|
||||
else
|
||||
value = true;
|
||||
}
|
||||
else
|
||||
else
|
||||
value = false;
|
||||
isTransparentCache.put(block, new Boolean(value));
|
||||
return value;
|
||||
return value;
|
||||
}
|
||||
|
||||
public void electrocute(LivingEntity lent) {
|
||||
|
||||
public void electrocute(LivingEntity lent)
|
||||
{
|
||||
lent.getWorld().playSound(lent.getLocation(), Sound.CREEPER_HISS, 1, 0);
|
||||
player.getWorld().playSound(player.getLocation(), Sound.CREEPER_HISS, 1, 0);
|
||||
Methods.damageEntity(player, lent, damage);
|
||||
if(Math.random() < stunChance) {
|
||||
if (Math.random() < stunChance)
|
||||
{
|
||||
final Location lentLoc = lent.getLocation();
|
||||
final LivingEntity flent = lent;
|
||||
new BukkitRunnable() {
|
||||
new BukkitRunnable()
|
||||
{
|
||||
int count = 0;
|
||||
public void run() {
|
||||
if(flent.isDead() || (flent instanceof Player && !((Player) flent).isOnline())) {
|
||||
|
||||
public void run()
|
||||
{
|
||||
if (flent.isDead() || (flent instanceof Player && !((Player) flent).isOnline()))
|
||||
{
|
||||
cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Location tempLoc = lentLoc.clone();
|
||||
Vector tempVel = flent.getVelocity();
|
||||
tempVel.setY(Math.min(0, tempVel.getY()));
|
||||
|
@ -229,73 +260,87 @@ public class Lightning {
|
|||
flent.teleport(tempLoc);
|
||||
flent.setVelocity(tempVel);
|
||||
count++;
|
||||
if(count > stunDuration)
|
||||
if (count > stunDuration)
|
||||
cancel();
|
||||
}
|
||||
}.runTaskTimer(ProjectKorra.plugin, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeWithTasks() {
|
||||
for(int i = 0; i < tasks.size(); i++) {
|
||||
public void removeWithTasks()
|
||||
{
|
||||
for (int i = 0; i < tasks.size(); i++)
|
||||
{
|
||||
tasks.get(i).cancel();
|
||||
i--;
|
||||
}
|
||||
remove();
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
|
||||
public void remove()
|
||||
{
|
||||
instances.remove(this);
|
||||
}
|
||||
|
||||
public static void removeAll() {
|
||||
for (int i = 0; i < instances.size(); i++) {
|
||||
|
||||
public static void removeAll()
|
||||
{
|
||||
for (int i = 0; i < instances.size(); i++)
|
||||
{
|
||||
instances.get(i).remove();
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
public static void progressAll() {
|
||||
public static void progressAll()
|
||||
{
|
||||
for (int i = 0; i < instances.size(); i++)
|
||||
instances.get(i).progress();
|
||||
}
|
||||
|
||||
public static Lightning getLightning(Player player) {
|
||||
for(Lightning light : instances) {
|
||||
if(light.player == player)
|
||||
|
||||
public static Lightning getLightning(Player player)
|
||||
{
|
||||
for (Lightning light : instances)
|
||||
{
|
||||
if (light.player == player)
|
||||
return light;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean isIce(Location loc) {
|
||||
|
||||
public static boolean isIce(Location loc)
|
||||
{
|
||||
Material mat = loc.getBlock().getType();
|
||||
return mat == Material.ICE || mat == Material.PACKED_ICE;
|
||||
}
|
||||
|
||||
public static boolean isWater(Location loc) {
|
||||
public static boolean isWater(Location loc)
|
||||
{
|
||||
Material mat = loc.getBlock().getType();
|
||||
return mat == Material.WATER || mat == Material.STATIONARY_WATER;
|
||||
}
|
||||
|
||||
public static boolean isWaterOrIce(Location loc) {
|
||||
|
||||
public static boolean isWaterOrIce(Location loc)
|
||||
{
|
||||
return isIce(loc) || isWater(loc);
|
||||
}
|
||||
|
||||
public static String getDescription() {
|
||||
|
||||
public static String getDescription()
|
||||
{
|
||||
return "Hold sneak while selecting this ability to charge up a lightning strike. Once "
|
||||
+ "charged, release sneak to discharge the lightning to the targetted location.";
|
||||
}
|
||||
|
||||
public class Arc {
|
||||
|
||||
public class Arc
|
||||
{
|
||||
private ArrayList<Location> points;
|
||||
private ArrayList<AnimLocation> animLocs;
|
||||
private ArrayList<LightningParticle> particles;
|
||||
private ArrayList<Arc> subArcs;
|
||||
private Vector direction;
|
||||
private int animCounter;
|
||||
|
||||
public Arc(Location startPoint, Location endPoint) {
|
||||
|
||||
public Arc(Location startPoint, Location endPoint)
|
||||
{
|
||||
points = new ArrayList<Location>();
|
||||
points.add(startPoint.clone());
|
||||
points.add(endPoint.clone());
|
||||
|
@ -305,10 +350,13 @@ public class Lightning {
|
|||
animLocs = new ArrayList<AnimLocation>();
|
||||
animCounter = 0;
|
||||
}
|
||||
|
||||
public void generatePoints(int times) {
|
||||
for(int i = 0; i < times; i++) {
|
||||
for(int j = 0; j < points.size() - 1; j += 2) {
|
||||
|
||||
public void generatePoints(int times)
|
||||
{
|
||||
for (int i = 0; i < times; i++)
|
||||
{
|
||||
for (int j = 0; j < points.size() - 1; j += 2)
|
||||
{
|
||||
Location loc1 = points.get(j);
|
||||
Location loc2 = points.get(j + 1);
|
||||
double adjac = loc1.distance(loc2) / 2;
|
||||
|
@ -322,16 +370,20 @@ public class Lightning {
|
|||
points.add(j + 1, newLoc);
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < points.size(); i++) {
|
||||
for (int i = 0; i < points.size(); i++)
|
||||
{
|
||||
animLocs.add(new AnimLocation(points.get(i), animCounter));
|
||||
animCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<Arc> generateArcs(double chance, double range) {
|
||||
|
||||
public ArrayList<Arc> generateArcs(double chance, double range)
|
||||
{
|
||||
ArrayList<Arc> arcs = new ArrayList<Arc>();
|
||||
for(int i = 0; i < animLocs.size(); i++) {
|
||||
if(Math.random() < chance) {
|
||||
for (int i = 0; i < animLocs.size(); i++)
|
||||
{
|
||||
if (Math.random() < chance)
|
||||
{
|
||||
Location loc = animLocs.get(i).getLoc();
|
||||
double angle = (Math.random() - 0.5) * MAX_ARC_ANGLE * 2;
|
||||
Vector dir = Methods.rotateXZ(direction.clone(), angle);
|
||||
|
@ -347,118 +399,145 @@ public class Lightning {
|
|||
}
|
||||
return arcs;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
for(int i = 0; i < particles.size(); i++) {
|
||||
|
||||
public void cancel()
|
||||
{
|
||||
for (int i = 0; i < particles.size(); i++)
|
||||
{
|
||||
particles.get(i).cancel();
|
||||
}
|
||||
|
||||
for(Arc subArc : subArcs) {
|
||||
|
||||
for (Arc subArc : subArcs)
|
||||
{
|
||||
subArc.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
public ArrayList<Location> getPoints() {
|
||||
public ArrayList<Location> getPoints()
|
||||
{
|
||||
return points;
|
||||
}
|
||||
|
||||
public void setPoints(ArrayList<Location> points) {
|
||||
public void setPoints(ArrayList<Location> points)
|
||||
{
|
||||
this.points = points;
|
||||
}
|
||||
|
||||
public Vector getDirection() {
|
||||
public Vector getDirection()
|
||||
{
|
||||
return direction;
|
||||
}
|
||||
|
||||
public void setDirection(Vector direction) {
|
||||
public void setDirection(Vector direction)
|
||||
{
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
public int getAnimCounter() {
|
||||
public int getAnimCounter()
|
||||
{
|
||||
return animCounter;
|
||||
}
|
||||
|
||||
public void setAnimCounter(int animCounter) {
|
||||
public void setAnimCounter(int animCounter)
|
||||
{
|
||||
this.animCounter = animCounter;
|
||||
}
|
||||
|
||||
public ArrayList<AnimLocation> getAnimLocs() {
|
||||
public ArrayList<AnimLocation> getAnimLocs()
|
||||
{
|
||||
return animLocs;
|
||||
}
|
||||
|
||||
public void setAnimLocs(ArrayList<AnimLocation> animLocs) {
|
||||
public void setAnimLocs(ArrayList<AnimLocation> animLocs)
|
||||
{
|
||||
this.animLocs = animLocs;
|
||||
}
|
||||
|
||||
public ArrayList<LightningParticle> getParticles() {
|
||||
public ArrayList<LightningParticle> getParticles()
|
||||
{
|
||||
return particles;
|
||||
}
|
||||
|
||||
public void setParticles(ArrayList<LightningParticle> particles) {
|
||||
public void setParticles(ArrayList<LightningParticle> particles)
|
||||
{
|
||||
this.particles = particles;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class AnimLocation {
|
||||
|
||||
public class AnimLocation
|
||||
{
|
||||
private Location loc;
|
||||
private int animCounter;
|
||||
|
||||
public AnimLocation(Location loc, int animCounter) {
|
||||
|
||||
public AnimLocation(Location loc, int animCounter)
|
||||
{
|
||||
this.loc = loc;
|
||||
this.animCounter = animCounter;
|
||||
}
|
||||
|
||||
public Location getLoc() {
|
||||
public Location getLoc()
|
||||
{
|
||||
return loc;
|
||||
}
|
||||
|
||||
public void setLoc(Location loc) {
|
||||
public void setLoc(Location loc)
|
||||
{
|
||||
this.loc = loc;
|
||||
}
|
||||
|
||||
public int getAnimCounter() {
|
||||
public int getAnimCounter()
|
||||
{
|
||||
return animCounter;
|
||||
}
|
||||
|
||||
public void setAnimCounter(int animCounter) {
|
||||
public void setAnimCounter(int animCounter)
|
||||
{
|
||||
this.animCounter = animCounter;
|
||||
}
|
||||
}
|
||||
|
||||
public class LightningParticle extends BukkitRunnable {
|
||||
}
|
||||
|
||||
public class LightningParticle extends BukkitRunnable
|
||||
{
|
||||
private Arc arc;
|
||||
private Location loc;
|
||||
private int count = 0;
|
||||
|
||||
public LightningParticle(Arc arc, Location loc) {
|
||||
|
||||
public LightningParticle(Arc arc, Location loc)
|
||||
{
|
||||
this.arc = arc;
|
||||
this.loc = loc;
|
||||
arc.particles.add(this);
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
|
||||
public void cancel()
|
||||
{
|
||||
super.cancel();
|
||||
tasks.remove(this);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
|
||||
public void run()
|
||||
{
|
||||
ParticleEffect.RED_DUST.display((float) 0, (float) 255, (float) 255, 0.1F, 0, loc, 256D);
|
||||
count++;
|
||||
if(count > 5)
|
||||
if (count > 5)
|
||||
this.cancel();
|
||||
else if(count == 1) {
|
||||
if(!isTransparent(player, loc.getBlock())) {
|
||||
else if (count == 1)
|
||||
{
|
||||
if (!isTransparent(player, loc.getBlock()))
|
||||
{
|
||||
arc.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Handle Water electrocution
|
||||
if(!hitWater && (isWater(loc) || (ARC_ON_ICE && isIce(loc)))) {
|
||||
if (!hitWater && (isWater(loc) || (ARC_ON_ICE && isIce(loc))))
|
||||
{
|
||||
hitWater = true;
|
||||
if(isIce(loc))
|
||||
if (isIce(loc))
|
||||
hitIce = true;
|
||||
for(int i = 0; i < WATER_ARCS; i++) {
|
||||
for (int i = 0; i < WATER_ARCS; i++)
|
||||
{
|
||||
Location origin = loc.clone();
|
||||
origin.add(new Vector((Math.random() - 0.5) * 2, 0, (Math.random() - 0.5) * 2));
|
||||
destination = origin.clone().add(
|
||||
|
@ -468,38 +547,45 @@ public class Lightning {
|
|||
arcs.add(newArc);
|
||||
}
|
||||
}
|
||||
|
||||
for(Entity entity : Methods.getEntitiesAroundPoint(loc, 2.5)) {
|
||||
|
||||
for (Entity entity : Methods.getEntitiesAroundPoint(loc, 2.5))
|
||||
{
|
||||
/*
|
||||
* If the player is in water we will electrocute them only if they are standing in water.
|
||||
* If the lightning hit ice we can electrocute them all the time.
|
||||
*/
|
||||
if(entity.equals(player)
|
||||
if (entity.equals(player)
|
||||
&& !(SELF_HIT_WATER && hitWater && isWater(player.getLocation()))
|
||||
&& !(SELF_HIT_WATER && hitIce))
|
||||
continue;
|
||||
|
||||
if(entity instanceof LivingEntity && !affectedEntities.contains(entity)) {
|
||||
|
||||
if (entity instanceof LivingEntity && !affectedEntities.contains(entity))
|
||||
{
|
||||
affectedEntities.add(entity);
|
||||
LivingEntity lent = (LivingEntity) entity;
|
||||
if(lent instanceof Player) {
|
||||
LivingEntity lent = (LivingEntity) entity;
|
||||
if (lent instanceof Player)
|
||||
{
|
||||
lent.getWorld().playSound(lent.getLocation(), Sound.CREEPER_HISS, 1, 0);
|
||||
player.getWorld().playSound(player.getLocation(), Sound.CREEPER_HISS, 1, 0);
|
||||
Player p = (Player) lent;
|
||||
Lightning light = getLightning(p);
|
||||
if(light != null && light.state == State.START) {
|
||||
if (light != null && light.state == State.START)
|
||||
{
|
||||
light.charged = true;
|
||||
remove();
|
||||
return;
|
||||
}
|
||||
}
|
||||
electrocute(lent);
|
||||
|
||||
|
||||
// Handle Chain Lightning
|
||||
if(chainArcs >= 1 && Math.random() <= chainArcChance) {
|
||||
if (chainArcs >= 1 && Math.random() <= chainArcChance)
|
||||
{
|
||||
chainArcs--;
|
||||
for(Entity ent : Methods.getEntitiesAroundPoint(lent.getLocation(), chainRange)) {
|
||||
if(!ent.equals(player) && !ent.equals(lent) && ent instanceof LivingEntity && !affectedEntities.contains(ent)) {
|
||||
for (Entity ent : Methods.getEntitiesAroundPoint(lent.getLocation(), chainRange))
|
||||
{
|
||||
if (!ent.equals(player) && !ent.equals(lent) && ent instanceof LivingEntity && !affectedEntities.contains(ent))
|
||||
{
|
||||
origin = lent.getLocation().add(0, 1, 0);
|
||||
destination = ent.getLocation().add(0, 1, 0);
|
||||
Arc newArc = new Arc(origin, destination);
|
||||
|
@ -516,125 +602,155 @@ public class Lightning {
|
|||
}
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
public Player getPlayer()
|
||||
{
|
||||
return player;
|
||||
}
|
||||
|
||||
public void setPlayer(Player player) {
|
||||
public void setPlayer(Player player)
|
||||
{
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public double getRange() {
|
||||
public double getRange()
|
||||
{
|
||||
return range;
|
||||
}
|
||||
|
||||
public void setRange(double range) {
|
||||
public void setRange(double range)
|
||||
{
|
||||
this.range = range;
|
||||
}
|
||||
|
||||
public double getChargeTime() {
|
||||
public double getChargeTime()
|
||||
{
|
||||
return chargeTime;
|
||||
}
|
||||
|
||||
public void setChargeTime(double chargeTime) {
|
||||
public void setChargeTime(double chargeTime)
|
||||
{
|
||||
this.chargeTime = chargeTime;
|
||||
}
|
||||
|
||||
public double getCooldown() {
|
||||
public double getCooldown()
|
||||
{
|
||||
return cooldown;
|
||||
}
|
||||
|
||||
public void setCooldown(double cooldown) {
|
||||
public void setCooldown(double cooldown)
|
||||
{
|
||||
this.cooldown = cooldown;
|
||||
if(player != null)
|
||||
if (player != null)
|
||||
bplayer.addCooldown("Lightning", (long) cooldown);
|
||||
}
|
||||
|
||||
public double getSubArcChance() {
|
||||
public double getSubArcChance()
|
||||
{
|
||||
return subArcChance;
|
||||
}
|
||||
|
||||
public void setSubArcChance(double subArcChance) {
|
||||
public void setSubArcChance(double subArcChance)
|
||||
{
|
||||
this.subArcChance = subArcChance;
|
||||
}
|
||||
|
||||
public double getDamage() {
|
||||
public double getDamage()
|
||||
{
|
||||
return damage;
|
||||
}
|
||||
|
||||
public void setDamage(double damage) {
|
||||
public void setDamage(double damage)
|
||||
{
|
||||
this.damage = damage;
|
||||
}
|
||||
|
||||
public double getChainArcs() {
|
||||
public double getChainArcs()
|
||||
{
|
||||
return chainArcs;
|
||||
}
|
||||
|
||||
public void setChainArcs(double chainArcs) {
|
||||
public void setChainArcs(double chainArcs)
|
||||
{
|
||||
this.chainArcs = chainArcs;
|
||||
}
|
||||
|
||||
public double getChainRange() {
|
||||
public double getChainRange()
|
||||
{
|
||||
return chainRange;
|
||||
}
|
||||
|
||||
public void setChainRange(double chainRange) {
|
||||
public void setChainRange(double chainRange)
|
||||
{
|
||||
this.chainRange = chainRange;
|
||||
}
|
||||
|
||||
public double getWaterRange() {
|
||||
public double getWaterRange()
|
||||
{
|
||||
return waterRange;
|
||||
}
|
||||
|
||||
public void setWaterRange(double waterRange) {
|
||||
public void setWaterRange(double waterRange)
|
||||
{
|
||||
this.waterRange = waterRange;
|
||||
}
|
||||
|
||||
public double getChainArcChance() {
|
||||
public double getChainArcChance()
|
||||
{
|
||||
return chainArcChance;
|
||||
}
|
||||
|
||||
public void setChainArcChance(double chainArcChance) {
|
||||
public void setChainArcChance(double chainArcChance)
|
||||
{
|
||||
this.chainArcChance = chainArcChance;
|
||||
}
|
||||
|
||||
public double getStunChance() {
|
||||
public double getStunChance()
|
||||
{
|
||||
return stunChance;
|
||||
}
|
||||
|
||||
public void setStunChance(double stunChance) {
|
||||
public void setStunChance(double stunChance)
|
||||
{
|
||||
this.stunChance = stunChance;
|
||||
}
|
||||
|
||||
public double getStunDuration() {
|
||||
public double getStunDuration()
|
||||
{
|
||||
return stunDuration;
|
||||
}
|
||||
|
||||
public void setStunDuration(double stunDuration) {
|
||||
public void setStunDuration(double stunDuration)
|
||||
{
|
||||
this.stunDuration = stunDuration;
|
||||
}
|
||||
|
||||
public boolean isCharged() {
|
||||
public boolean isCharged()
|
||||
{
|
||||
return charged;
|
||||
}
|
||||
|
||||
public void setCharged(boolean charged) {
|
||||
public void setCharged(boolean charged)
|
||||
{
|
||||
this.charged = charged;
|
||||
}
|
||||
|
||||
public boolean isHitWater() {
|
||||
public boolean isHitWater()
|
||||
{
|
||||
return hitWater;
|
||||
}
|
||||
|
||||
public void setHitWater(boolean hitWater) {
|
||||
public void setHitWater(boolean hitWater)
|
||||
{
|
||||
this.hitWater = hitWater;
|
||||
}
|
||||
|
||||
public boolean isHitIce() {
|
||||
public boolean isHitIce()
|
||||
{
|
||||
return hitIce;
|
||||
}
|
||||
|
||||
public void setHitIce(boolean hitIce) {
|
||||
public void setHitIce(boolean hitIce)
|
||||
{
|
||||
this.hitIce = hitIce;
|
||||
}
|
||||
}
|
|
@ -15,6 +15,7 @@ import org.bukkit.util.Vector;
|
|||
|
||||
import com.projectkorra.ProjectKorra.BendingPlayer;
|
||||
import com.projectkorra.ProjectKorra.Commands;
|
||||
import com.projectkorra.ProjectKorra.Element;
|
||||
import com.projectkorra.ProjectKorra.Methods;
|
||||
import com.projectkorra.ProjectKorra.ProjectKorra;
|
||||
import com.projectkorra.ProjectKorra.TempBlock;
|
||||
|
@ -81,11 +82,13 @@ public class WaterCombo {
|
|||
public WaterCombo(Player player, String ability) {
|
||||
if (!enabled || !player.hasPermission("bending.ability.WaterCombo"))
|
||||
return;
|
||||
if (Methods.isRegionProtectedFromBuild(player, "WaterManipulation",
|
||||
player.getLocation()))
|
||||
if(!Methods.getBendingPlayer(player.getName()).hasElement(Element.Water))
|
||||
return;
|
||||
if (Commands.isToggledForAll)
|
||||
return;
|
||||
if (Methods.isRegionProtectedFromBuild(player, "WaterManipulation",
|
||||
player.getLocation()))
|
||||
return;
|
||||
if (!Methods.getBendingPlayer(player.getName()).isToggled())
|
||||
return;
|
||||
time = System.currentTimeMillis();
|
||||
|
|
|
@ -161,9 +161,24 @@ Abilities:
|
|||
Suffocate:
|
||||
Enabled: true
|
||||
Description: "This ability is one of the most dangerous abilities an Airbender possesses. To use, simply look at an entity and hold shift. The entity will begin taking damage as you extract the air from their lungs. Any bender caught in this sphere will only be able to use basic moves, such as AirSwipe, WaterManipulation, FireBlast, or EarthBlast. An entity can be knocked out of the sphere by certain bending arts, and your attention will be disrupted if you are hit by bending."
|
||||
Range: 15
|
||||
Damage: 2
|
||||
ChargeTime: 1000
|
||||
Cooldown: 0
|
||||
DamageInitialDelay: 2
|
||||
DamageInterval: 1
|
||||
SlowPotency: 1
|
||||
SlowDelay: 0.5
|
||||
SlowInterval: 1.25
|
||||
BlindPotentcy: 30
|
||||
BlindDelay: 2
|
||||
BlindInterval: 1.5
|
||||
CanBeUsedOnUndeadMobs: true
|
||||
Range: 5
|
||||
Damage: 0.5
|
||||
RequireConstantAim: true
|
||||
RequireConstantAimRadius: 5
|
||||
AnimationRadius: 2.0
|
||||
AnimationParticleAmount: 2
|
||||
AnimationSpeed: 1.0
|
||||
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."
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
name: ProjectKorra
|
||||
author: ProjectKorra
|
||||
version: 1.6.0 BETA 12
|
||||
version: 1.6.0 BETA 13
|
||||
main: com.projectkorra.ProjectKorra.ProjectKorra
|
||||
softdepend: [PreciousStones, WorldGuard, WorldEdit, Factions, MassiveCore, GriefPrevention, Towny, NoCheatPlus, LWC]
|
||||
commands:
|
||||
|
|
Loading…
Reference in a new issue