mirror of
https://github.com/TotalFreedomMC/TF-ProjectKorra.git
synced 2025-02-11 03:30:10 +00:00
IceSpike
This commit is contained in:
parent
358e9f4d71
commit
62e54864ae
8 changed files with 933 additions and 1 deletions
|
@ -31,6 +31,8 @@ import com.projectkorra.ProjectKorra.firebending.FireStream;
|
|||
import com.projectkorra.ProjectKorra.firebending.Illumination;
|
||||
import com.projectkorra.ProjectKorra.waterbending.Bloodbending;
|
||||
import com.projectkorra.ProjectKorra.waterbending.FreezeMelt;
|
||||
import com.projectkorra.ProjectKorra.waterbending.IceSpike;
|
||||
import com.projectkorra.ProjectKorra.waterbending.IceSpike2;
|
||||
import com.projectkorra.ProjectKorra.waterbending.OctopusForm;
|
||||
import com.projectkorra.ProjectKorra.waterbending.Plantbending;
|
||||
import com.projectkorra.ProjectKorra.waterbending.Torrent;
|
||||
|
@ -129,6 +131,12 @@ public class BendingManager implements Runnable {
|
|||
Wave.progress(ID);
|
||||
}
|
||||
|
||||
for (int ID : IceSpike.instances.keySet()) {
|
||||
IceSpike.instances.get(ID).progress();
|
||||
}
|
||||
|
||||
IceSpike2.progressAll();
|
||||
|
||||
FireStream.dissipateAll();
|
||||
} catch (Exception e) {
|
||||
Methods.stopBending();
|
||||
|
|
|
@ -17,6 +17,7 @@ public class BendingPlayer {
|
|||
HashMap<Integer, String> abilities;
|
||||
boolean permaRemoved;
|
||||
boolean isToggled;
|
||||
private long slowTime = 0;
|
||||
|
||||
public BendingPlayer(UUID uuid, String player, ArrayList<Element> elements, HashMap<Integer, String> abilities, boolean permaRemoved) {
|
||||
this.uuid = uuid;
|
||||
|
@ -61,4 +62,12 @@ public class BendingPlayer {
|
|||
this.elements.clear();
|
||||
this.elements.add(e);
|
||||
}
|
||||
|
||||
public boolean canBeSlowed() {
|
||||
return (System.currentTimeMillis() > slowTime);
|
||||
}
|
||||
|
||||
public void slow(long cooldown) {
|
||||
slowTime = System.currentTimeMillis() + cooldown;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,6 +130,19 @@ public class ConfigManager {
|
|||
config.addDefault("Abilities.Water.Bloodbending.ThrowFactor", 2);
|
||||
config.addDefault("Abilities.Water.Bloodbending.Range", 10);
|
||||
|
||||
config.addDefault("Abilities.Water.IceSpike.Enabled", true);
|
||||
config.addDefault("Abilities.Water.IceSpike.Description", "This ability has many functions. Clicking while targetting ice, or an entity over some ice, "
|
||||
+ "will raise a spike of ice up, damaging and slowing the target. Tapping sneak (shift) while"
|
||||
+ " selecting a water source will select that source that can then be fired with a click. Firing"
|
||||
+ " this will launch a spike of ice at your target, dealing a bit of damage and slowing the target. "
|
||||
+ "If you sneak (shift) while not selecting a source, many ice spikes will erupt from around you, "
|
||||
+ "damaging and slowing those targets.");
|
||||
config.addDefault("Abilities.Water.IceSpike.Cooldown", 2000);
|
||||
config.addDefault("Abilities.Water.IceSpike.Damage", 2);
|
||||
config.addDefault("Abilities.Water.IceSpike.Range", 20);
|
||||
config.addDefault("Abilities.Water.IceSpike.ThrowingMult", 0.7);
|
||||
config.addDefault("Abilities.Water.IceSpike.Height", 6);
|
||||
|
||||
config.addDefault("Abilities.Water.OctopusForm.Enabled", true);
|
||||
config.addDefault("Abilities.Water.OctopusForm.Description", "This ability allows the waterbender to manipulate a large quantity of water into a form resembling that of an octopus. "
|
||||
+ "To use, click to select a water source. Then, hold sneak to channel this ability. "
|
||||
|
|
|
@ -65,6 +65,7 @@ import com.projectkorra.ProjectKorra.firebending.FireStream;
|
|||
import com.projectkorra.ProjectKorra.firebending.Illumination;
|
||||
import com.projectkorra.ProjectKorra.waterbending.Bloodbending;
|
||||
import com.projectkorra.ProjectKorra.waterbending.FreezeMelt;
|
||||
import com.projectkorra.ProjectKorra.waterbending.IceSpike2;
|
||||
import com.projectkorra.ProjectKorra.waterbending.Melt;
|
||||
import com.projectkorra.ProjectKorra.waterbending.OctopusForm;
|
||||
import com.projectkorra.ProjectKorra.waterbending.Torrent;
|
||||
|
@ -181,6 +182,9 @@ public class PKListener implements Listener {
|
|||
if (abil.equalsIgnoreCase("Bloodbending")) {
|
||||
new Bloodbending(player);
|
||||
}
|
||||
if (abil.equalsIgnoreCase("IceSpike")) {
|
||||
new IceSpike2(player);
|
||||
}
|
||||
if (abil.equalsIgnoreCase("OctopusForm")) {
|
||||
OctopusForm.form(player);
|
||||
}
|
||||
|
@ -365,6 +369,9 @@ public class PKListener implements Listener {
|
|||
if (abil.equalsIgnoreCase("Bloodbending")) {
|
||||
Bloodbending.launch(player);
|
||||
}
|
||||
if (abil.equalsIgnoreCase("IceSpike")) {
|
||||
IceSpike2.activate(player);
|
||||
}
|
||||
if (abil.equalsIgnoreCase("OctopusForm")) {
|
||||
new OctopusForm(player);
|
||||
}
|
||||
|
|
301
src/com/projectkorra/ProjectKorra/waterbending/IceSpike.java
Normal file
301
src/com/projectkorra/ProjectKorra/waterbending/IceSpike.java
Normal file
|
@ -0,0 +1,301 @@
|
|||
package com.projectkorra.ProjectKorra.waterbending;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Entity;
|
||||
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 com.projectkorra.ProjectKorra.BendingPlayer;
|
||||
import com.projectkorra.ProjectKorra.Methods;
|
||||
import com.projectkorra.ProjectKorra.ProjectKorra;
|
||||
import com.projectkorra.ProjectKorra.TempPotionEffect;
|
||||
|
||||
public class IceSpike {
|
||||
|
||||
public static ConcurrentHashMap<Integer, IceSpike> instances = new ConcurrentHashMap<Integer, IceSpike>();
|
||||
public ConcurrentHashMap<Player, Long> removeTimers = new ConcurrentHashMap<Player, Long>();
|
||||
public static Map<String, Long> cooldowns = new HashMap<String, Long>();
|
||||
public static final int standardheight = ProjectKorra.plugin.getConfig().getInt("Abilities.Water.IceSpike.Height");
|
||||
public static long removeTimer = 500;
|
||||
|
||||
private static ConcurrentHashMap<Block, Block> alreadydoneblocks = new ConcurrentHashMap<Block, Block>();
|
||||
private static ConcurrentHashMap<Block, Integer> baseblocks = new ConcurrentHashMap<Block, Integer>();
|
||||
|
||||
private static int ID = Integer.MIN_VALUE;
|
||||
|
||||
private static double range = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.IceSpike.Range");
|
||||
public static long cooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Water.IceSpike.Cooldown");
|
||||
private static double speed = 25;
|
||||
private static final Vector direction = new Vector(0, 1, 0);
|
||||
|
||||
private static long interval = (long) (1000. / speed);
|
||||
|
||||
private Location origin;
|
||||
private Location location;
|
||||
private Block block;
|
||||
private Player player;
|
||||
private int progress = 0;
|
||||
private double damage = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.IceSpike.Damage");
|
||||
int id;
|
||||
private long time;
|
||||
int height = 2;
|
||||
private Vector thrown = new Vector(0, ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.IceSpike.ThrowingMult"), 0);
|
||||
private ConcurrentHashMap<Block, Block> affectedblocks = new ConcurrentHashMap<Block, Block>();
|
||||
private List<LivingEntity> damaged = new ArrayList<LivingEntity>();
|
||||
|
||||
public IceSpike(Player player) {
|
||||
if (cooldowns.containsKey(player))
|
||||
if (cooldowns.get(player) + cooldown >= System.currentTimeMillis())
|
||||
return;
|
||||
try {
|
||||
this.player = player;
|
||||
|
||||
double lowestdistance = range + 1;
|
||||
Entity closestentity = null;
|
||||
for (Entity entity : Methods.getEntitiesAroundPoint(
|
||||
player.getLocation(), range)) {
|
||||
if (Methods.getDistanceFromLine(player.getLocation()
|
||||
.getDirection(), player.getLocation(), entity
|
||||
.getLocation()) <= 2
|
||||
&& (entity instanceof LivingEntity)
|
||||
&& (entity.getEntityId() != player.getEntityId())) {
|
||||
double distance = player.getLocation().distance(
|
||||
entity.getLocation());
|
||||
if (distance < lowestdistance) {
|
||||
closestentity = entity;
|
||||
lowestdistance = distance;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (closestentity != null) {
|
||||
Block temptestingblock = closestentity.getLocation().getBlock()
|
||||
.getRelative(BlockFace.DOWN, 1);
|
||||
// if (temptestingblock.getType() == Material.ICE){
|
||||
this.block = temptestingblock;
|
||||
// }
|
||||
} else {
|
||||
this.block = player.getTargetBlock(null, (int) range);
|
||||
}
|
||||
origin = block.getLocation();
|
||||
location = origin.clone();
|
||||
|
||||
} catch (IllegalStateException e) {
|
||||
return;
|
||||
}
|
||||
|
||||
loadAffectedBlocks();
|
||||
|
||||
if (height != 0) {
|
||||
if (canInstantiate()) {
|
||||
id = ID;
|
||||
instances.put(id, this);
|
||||
if (ID >= Integer.MAX_VALUE) {
|
||||
ID = Integer.MIN_VALUE;
|
||||
}
|
||||
ID++;
|
||||
time = System.currentTimeMillis() - interval;
|
||||
cooldowns.put(player.getName(), System.currentTimeMillis());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IceSpike(Player player, Location origin, int damage,
|
||||
Vector throwing, long aoecooldown) {
|
||||
this.cooldown = aoecooldown;
|
||||
this.player = player;
|
||||
this.origin = origin;
|
||||
location = origin.clone();
|
||||
block = location.getBlock();
|
||||
this.damage = damage;
|
||||
this.thrown = throwing;
|
||||
|
||||
loadAffectedBlocks();
|
||||
|
||||
if (block.getType() == Material.ICE) {
|
||||
if (canInstantiate()) {
|
||||
id = ID;
|
||||
instances.put(id, this);
|
||||
if (ID >= Integer.MAX_VALUE) {
|
||||
ID = Integer.MIN_VALUE;
|
||||
}
|
||||
ID++;
|
||||
time = System.currentTimeMillis() - interval;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadAffectedBlocks() {
|
||||
affectedblocks.clear();
|
||||
Block thisblock;
|
||||
for (int i = 1; i <= height; i++) {
|
||||
thisblock = block.getWorld().getBlockAt(
|
||||
location.clone().add(direction.clone().multiply(i)));
|
||||
affectedblocks.put(thisblock, thisblock);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean blockInAffectedBlocks(Block block) {
|
||||
if (affectedblocks.containsKey(block)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean blockInAllAffectedBlocks(Block block) {
|
||||
for (int ID : instances.keySet()) {
|
||||
if (instances.get(ID).blockInAffectedBlocks(block))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void revertBlock(Block block) {
|
||||
for (int ID : instances.keySet()) {
|
||||
if (instances.get(ID).blockInAffectedBlocks(block)) {
|
||||
instances.get(ID).affectedblocks.remove(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canInstantiate() {
|
||||
if (block.getType() != Material.ICE)
|
||||
return false;
|
||||
for (Block block : affectedblocks.keySet()) {
|
||||
if (blockInAllAffectedBlocks(block)
|
||||
|| alreadydoneblocks.containsKey(block)
|
||||
|| block.getType() != Material.AIR
|
||||
|| (block.getX() == player.getEyeLocation().getBlock()
|
||||
.getX() && block.getZ() == player.getEyeLocation()
|
||||
.getBlock().getZ())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean progress() {
|
||||
if (System.currentTimeMillis() - time >= interval) {
|
||||
time = System.currentTimeMillis();
|
||||
if (progress < height) {
|
||||
moveEarth();
|
||||
removeTimers.put(player, System.currentTimeMillis());
|
||||
} else {
|
||||
if (removeTimers.get(player) + removeTimer <= System
|
||||
.currentTimeMillis()) {
|
||||
baseblocks.put(
|
||||
location.clone()
|
||||
.add(direction.clone().multiply(
|
||||
-1 * (height))).getBlock(),
|
||||
(height - 1));
|
||||
if (!revertblocks()) {
|
||||
instances.remove(id);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean moveEarth() {
|
||||
progress++;
|
||||
Block affectedblock = location.clone().add(direction).getBlock();
|
||||
location = location.add(direction);
|
||||
// if (Methods.isRegionProtectedFromBuild(player, Abilities.IceSpike,
|
||||
// location))
|
||||
// return false;
|
||||
for (Entity en : Methods.getEntitiesAroundPoint(location, 1.4)) {
|
||||
if (en instanceof LivingEntity && en != player
|
||||
&& !damaged.contains(((LivingEntity) en))) {
|
||||
LivingEntity le = (LivingEntity) en;
|
||||
affect(le);
|
||||
// le.setVelocity(thrown);
|
||||
// le.damage(damage);
|
||||
// damaged.add(le);
|
||||
// Methods.verbose(damage + " Hp:" + le.getHealth());
|
||||
}
|
||||
}
|
||||
affectedblock.setType(Material.ICE);
|
||||
loadAffectedBlocks();
|
||||
|
||||
if (location.distance(origin) >= height) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void affect(LivingEntity entity) {
|
||||
entity.setVelocity(thrown);
|
||||
entity.damage(damage);
|
||||
damaged.add(entity);
|
||||
long slowCooldown = IceSpike2.slowCooldown;
|
||||
int mod = 2;
|
||||
if (entity instanceof Player) {
|
||||
BendingPlayer bPlayer = Methods.getBendingPlayer(player.getName());
|
||||
if (bPlayer.canBeSlowed()) {
|
||||
PotionEffect effect = new PotionEffect(PotionEffectType.SLOW,
|
||||
70, mod);
|
||||
new TempPotionEffect(entity, effect);
|
||||
bPlayer.slow(slowCooldown);
|
||||
}
|
||||
} else {
|
||||
PotionEffect effect = new PotionEffect(PotionEffectType.SLOW, 70,
|
||||
mod);
|
||||
new TempPotionEffect(entity, effect);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static boolean blockIsBase(Block block) {
|
||||
if (baseblocks.containsKey(block)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void removeBlockBase(Block block) {
|
||||
if (baseblocks.containsKey(block)) {
|
||||
baseblocks.remove(block);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void removeAll() {
|
||||
for (int ID : instances.keySet()) {
|
||||
instances.remove(ID);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean revertblocks() {
|
||||
Vector direction = new Vector(0, -1, 0);
|
||||
location.getBlock().setType(Material.AIR);// .clone().add(direction).getBlock().setType(Material.AIR);
|
||||
location.add(direction);
|
||||
if (blockIsBase(location.getBlock()))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static String getDescription() {
|
||||
return "This ability has many functions. Clicking while targetting ice, or an entity over some ice, "
|
||||
+ "will raise a spike of ice up, damaging and slowing the target. Tapping sneak (shift) while"
|
||||
+ " selecting a water source will select that source that can then be fired with a click. Firing"
|
||||
+ " this will launch a spike of ice at your target, dealing a bit of damage and slowing the target. "
|
||||
+ "If you sneak (shift) while not selecting a source, many ice spikes will erupt from around you, "
|
||||
+ "damaging and slowing those targets.";
|
||||
}
|
||||
|
||||
}
|
447
src/com/projectkorra/ProjectKorra/waterbending/IceSpike2.java
Normal file
447
src/com/projectkorra/ProjectKorra/waterbending/IceSpike2.java
Normal file
|
@ -0,0 +1,447 @@
|
|||
package com.projectkorra.ProjectKorra.waterbending;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Entity;
|
||||
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 com.projectkorra.ProjectKorra.BendingPlayer;
|
||||
import com.projectkorra.ProjectKorra.Methods;
|
||||
import com.projectkorra.ProjectKorra.TempBlock;
|
||||
import com.projectkorra.ProjectKorra.TempPotionEffect;
|
||||
|
||||
public class IceSpike2 {
|
||||
|
||||
private static ConcurrentHashMap<Integer, IceSpike2> instances = new ConcurrentHashMap<Integer, IceSpike2>();
|
||||
|
||||
private static double defaultrange = 20;
|
||||
private static int defaultdamage = 1;
|
||||
private static int defaultmod = 2;
|
||||
private static int ID = Integer.MIN_VALUE;
|
||||
static long slowCooldown = 5000;
|
||||
|
||||
private static final long interval = 20;
|
||||
private static final byte data = 0;
|
||||
private static final double affectingradius = 2;
|
||||
private static final double deflectrange = 3;
|
||||
|
||||
private Player player;
|
||||
private int id;
|
||||
private double range;
|
||||
private boolean plantbending = false;
|
||||
private Block sourceblock;
|
||||
private TempBlock source;
|
||||
private boolean prepared = false;
|
||||
private boolean settingup = false;
|
||||
private boolean progressing = false;
|
||||
private long time;
|
||||
|
||||
private Location location;
|
||||
private Location firstdestination;
|
||||
private Location destination;
|
||||
|
||||
public IceSpike2(Player player) {
|
||||
block(player);
|
||||
if (Methods.canPlantbend(player))
|
||||
plantbending = true;
|
||||
range = Methods.waterbendingNightAugment(defaultrange, player.getWorld());
|
||||
this.player = player;
|
||||
Block sourceblock = Methods.getWaterSourceBlock(player, range,
|
||||
plantbending);
|
||||
|
||||
if (sourceblock == null) {
|
||||
new SpikeField(player);
|
||||
} else {
|
||||
prepare(sourceblock);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void prepare(Block block) {
|
||||
for (IceSpike2 ice : getInstances(player)) {
|
||||
if (ice.prepared) {
|
||||
ice.cancel();
|
||||
}
|
||||
}
|
||||
sourceblock = block;
|
||||
location = sourceblock.getLocation();
|
||||
prepared = true;
|
||||
createInstance();
|
||||
}
|
||||
|
||||
private void createInstance() {
|
||||
id = ID++;
|
||||
instances.put(id, this);
|
||||
if (ID >= Integer.MAX_VALUE) {
|
||||
ID = Integer.MIN_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
private static ArrayList<IceSpike2> getInstances(Player player) {
|
||||
ArrayList<IceSpike2> list = new ArrayList<IceSpike2>();
|
||||
for (int id : instances.keySet()) {
|
||||
IceSpike2 ice = instances.get(id);
|
||||
if (ice.player.equals(player)) {
|
||||
list.add(ice);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public static void activate(Player player) {
|
||||
redirect(player);
|
||||
boolean activate = false;
|
||||
|
||||
if (IceSpike.cooldowns.containsKey(player.getName())) {
|
||||
if (IceSpike.cooldowns.get(player.getName()) + IceSpike.cooldown >= System.currentTimeMillis()) {
|
||||
return;
|
||||
} else {
|
||||
IceSpike.cooldowns.remove(player.getName());
|
||||
}
|
||||
}
|
||||
|
||||
for (IceSpike2 ice : getInstances(player)) {
|
||||
if (ice.prepared) {
|
||||
ice.throwIce();
|
||||
activate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!activate) {
|
||||
IceSpike spike = new IceSpike(player);
|
||||
if (spike.id == 0) {
|
||||
waterBottle(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void waterBottle(Player player) {
|
||||
if (WaterReturn.hasWaterBottle(player)) {
|
||||
Location eyeloc = player.getEyeLocation();
|
||||
Block block = eyeloc.add(eyeloc.getDirection().normalize())
|
||||
.getBlock();
|
||||
if (Methods.isTransparentToEarthbending(player, block)
|
||||
&& Methods.isTransparentToEarthbending(player,
|
||||
eyeloc.getBlock())) {
|
||||
|
||||
LivingEntity target = (LivingEntity) Methods.getTargetedEntity(
|
||||
player, defaultrange, new ArrayList<Entity>());
|
||||
Location destination;
|
||||
if (target == null) {
|
||||
destination = Methods.getTargetedLocation(player,
|
||||
defaultrange, Methods.transparentToEarthbending);
|
||||
} else {
|
||||
destination = Methods.getPointOnLine(player.getEyeLocation(),
|
||||
target.getEyeLocation(), defaultrange);
|
||||
}
|
||||
|
||||
if (destination.distance(block.getLocation()) < 1)
|
||||
return;
|
||||
|
||||
block.setType(Material.WATER);
|
||||
block.setData((byte) 0x0);
|
||||
IceSpike2 ice = new IceSpike2(player);
|
||||
ice.throwIce();
|
||||
|
||||
if (ice.progressing) {
|
||||
WaterReturn.emptyWaterBottle(player);
|
||||
} else {
|
||||
block.setType(Material.AIR);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void throwIce() {
|
||||
if (!prepared)
|
||||
return;
|
||||
LivingEntity target = (LivingEntity) Methods.getTargetedEntity(player,
|
||||
range, new ArrayList<Entity>());
|
||||
if (target == null) {
|
||||
destination = Methods.getTargetedLocation(player, range,
|
||||
Methods.transparentToEarthbending);
|
||||
} else {
|
||||
destination = target.getEyeLocation();
|
||||
}
|
||||
|
||||
location = sourceblock.getLocation();
|
||||
if (destination.distance(location) < 1)
|
||||
return;
|
||||
firstdestination = location.clone();
|
||||
if (destination.getY() - location.getY() > 2) {
|
||||
firstdestination.setY(destination.getY() - 1);
|
||||
} else {
|
||||
firstdestination.add(0, 2, 0);
|
||||
}
|
||||
destination = Methods
|
||||
.getPointOnLine(firstdestination, destination, range);
|
||||
progressing = true;
|
||||
settingup = true;
|
||||
prepared = false;
|
||||
|
||||
if (Methods.isPlant(sourceblock)) {
|
||||
new Plantbending(sourceblock);
|
||||
sourceblock.setType(Material.AIR);
|
||||
} else if (!Methods.isAdjacentToThreeOrMoreSources(sourceblock)) {
|
||||
sourceblock.setType(Material.AIR);
|
||||
}
|
||||
|
||||
source = new TempBlock(sourceblock, Material.ICE, data);
|
||||
}
|
||||
|
||||
public static void progressAll() {
|
||||
for (int id : instances.keySet()) {
|
||||
instances.get(id).progress();
|
||||
}
|
||||
}
|
||||
|
||||
private void progress() {
|
||||
if (player.isDead() || !player.isOnline()
|
||||
|| !Methods.canBend(player.getName(), "IceSpike")) {
|
||||
cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!player.getWorld().equals(location.getWorld())) {
|
||||
cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
if (player.getEyeLocation().distance(location) >= range) {
|
||||
if (progressing) {
|
||||
cancel();
|
||||
returnWater();
|
||||
} else {
|
||||
cancel();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ((Methods.getBoundAbility(player) == null || !Methods.getBoundAbility(player).equalsIgnoreCase("IceSpike")) && prepared) {
|
||||
cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
if (System.currentTimeMillis() < time + interval)
|
||||
return;
|
||||
|
||||
time = System.currentTimeMillis();
|
||||
|
||||
if (progressing) {
|
||||
|
||||
Vector direction;
|
||||
|
||||
if (location.getBlockY() == firstdestination.getBlockY())
|
||||
settingup = false;
|
||||
|
||||
if (location.distance(destination) <= 2) {
|
||||
cancel();
|
||||
returnWater();
|
||||
return;
|
||||
}
|
||||
|
||||
if (settingup) {
|
||||
direction = Methods.getDirection(location, firstdestination)
|
||||
.normalize();
|
||||
} else {
|
||||
direction = Methods.getDirection(location, destination)
|
||||
.normalize();
|
||||
}
|
||||
|
||||
location.add(direction);
|
||||
|
||||
Block block = location.getBlock();
|
||||
|
||||
if (block.equals(sourceblock))
|
||||
return;
|
||||
|
||||
source.revertBlock();
|
||||
source = null;
|
||||
|
||||
if (Methods.isTransparentToEarthbending(player, block)
|
||||
&& !block.isLiquid()) {
|
||||
Methods.breakBlock(block);
|
||||
} else if (!Methods.isWater(block)) {
|
||||
cancel();
|
||||
returnWater();
|
||||
return;
|
||||
}
|
||||
|
||||
// if (Methods.isRegionProtectedFromBuild(player, Abilities.IceSpike,
|
||||
// location)) {
|
||||
// cancel();
|
||||
// returnWater();
|
||||
// return;
|
||||
// }
|
||||
|
||||
for (Entity entity : Methods.getEntitiesAroundPoint(location,
|
||||
affectingradius)) {
|
||||
if (entity.getEntityId() != player.getEntityId()
|
||||
&& entity instanceof LivingEntity) {
|
||||
affect((LivingEntity) entity);
|
||||
progressing = false;
|
||||
returnWater();
|
||||
}
|
||||
}
|
||||
|
||||
if (!progressing) {
|
||||
cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
sourceblock = block;
|
||||
source = new TempBlock(sourceblock, Material.ICE, data);
|
||||
|
||||
} else if (prepared) {
|
||||
Methods.playFocusWaterEffect(sourceblock);
|
||||
}
|
||||
}
|
||||
|
||||
private void affect(LivingEntity entity) {
|
||||
int mod = (int) Methods.waterbendingNightAugment(defaultmod,
|
||||
player.getWorld());
|
||||
int damage = (int) Methods.waterbendingNightAugment(defaultdamage,
|
||||
player.getWorld());
|
||||
if (entity instanceof Player) {
|
||||
BendingPlayer bPlayer = Methods.getBendingPlayer(player.getName());
|
||||
if (bPlayer.canBeSlowed()) {
|
||||
PotionEffect effect = new PotionEffect(PotionEffectType.SLOW,
|
||||
70, mod);
|
||||
new TempPotionEffect(entity, effect);
|
||||
bPlayer.slow(slowCooldown);
|
||||
entity.damage(damage, player);
|
||||
}
|
||||
} else {
|
||||
PotionEffect effect = new PotionEffect(PotionEffectType.SLOW, 70,
|
||||
mod);
|
||||
new TempPotionEffect(entity, effect);
|
||||
entity.damage(damage, player);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void redirect(Player player) {
|
||||
|
||||
for (int id : instances.keySet()) {
|
||||
IceSpike2 ice = instances.get(id);
|
||||
|
||||
if (!ice.progressing)
|
||||
continue;
|
||||
|
||||
if (!ice.location.getWorld().equals(player.getWorld()))
|
||||
continue;
|
||||
|
||||
if (ice.player.equals(player)) {
|
||||
Location location;
|
||||
Entity target = Methods.getTargetedEntity(player, defaultrange, new ArrayList<Entity>());
|
||||
if (target == null) {
|
||||
location = Methods.getTargetedLocation(player, defaultrange);
|
||||
} else {
|
||||
location = ((LivingEntity) target).getEyeLocation();
|
||||
}
|
||||
location = Methods.getPointOnLine(ice.location, location,
|
||||
defaultrange * 2);
|
||||
ice.redirect(location, player);
|
||||
}
|
||||
|
||||
Location location = player.getEyeLocation();
|
||||
Vector vector = location.getDirection();
|
||||
Location mloc = ice.location;
|
||||
// if (Methods.isRegionProtectedFromBuild(player, Abilities.IceSpike,
|
||||
// mloc))
|
||||
// continue;
|
||||
if (mloc.distance(location) <= defaultrange
|
||||
&& Methods.getDistanceFromLine(vector, location, ice.location) < deflectrange
|
||||
&& mloc.distance(location.clone().add(vector)) < mloc
|
||||
.distance(location.clone().add(
|
||||
vector.clone().multiply(-1)))) {
|
||||
Location loc;
|
||||
Entity target = Methods.getTargetedEntity(player, defaultrange, new ArrayList<Entity>());
|
||||
if (target == null) {
|
||||
loc = Methods.getTargetedLocation(player, defaultrange);
|
||||
} else {
|
||||
loc = ((LivingEntity) target).getEyeLocation();
|
||||
}
|
||||
loc = Methods.getPointOnLine(ice.location, loc, defaultrange * 2);
|
||||
ice.redirect(loc, player);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static void block(Player player) {
|
||||
for (int id : instances.keySet()) {
|
||||
IceSpike2 ice = instances.get(id);
|
||||
|
||||
if (ice.player.equals(player))
|
||||
continue;
|
||||
|
||||
if (!ice.location.getWorld().equals(player.getWorld()))
|
||||
continue;
|
||||
|
||||
if (!ice.progressing)
|
||||
continue;
|
||||
|
||||
// if (Methods.isRegionProtectedFromBuild(player, Abilities.IceSpike,
|
||||
// ice.location))
|
||||
// continue;
|
||||
|
||||
Location location = player.getEyeLocation();
|
||||
Vector vector = location.getDirection();
|
||||
Location mloc = ice.location;
|
||||
if (mloc.distance(location) <= defaultrange
|
||||
&& Methods.getDistanceFromLine(vector, location, ice.location) < deflectrange
|
||||
&& mloc.distance(location.clone().add(vector)) < mloc
|
||||
.distance(location.clone().add(
|
||||
vector.clone().multiply(-1)))) {
|
||||
ice.cancel();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void redirect(Location destination, Player player) {
|
||||
this.destination = destination;
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
private void cancel() {
|
||||
if (progressing) {
|
||||
if (source != null)
|
||||
source.revertBlock();
|
||||
progressing = false;
|
||||
}
|
||||
|
||||
instances.remove(id);
|
||||
}
|
||||
|
||||
private void returnWater() {
|
||||
new WaterReturn(player, sourceblock);
|
||||
}
|
||||
|
||||
public static void removeAll() {
|
||||
for (int id : instances.keySet()) {
|
||||
instances.get(id).cancel();
|
||||
}
|
||||
|
||||
instances.clear();
|
||||
}
|
||||
|
||||
public static boolean isBending(Player player) {
|
||||
for (int id : instances.keySet()) {
|
||||
if (instances.get(id).player.equals(player))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
139
src/com/projectkorra/ProjectKorra/waterbending/SpikeField.java
Normal file
139
src/com/projectkorra/ProjectKorra/waterbending/SpikeField.java
Normal file
|
@ -0,0 +1,139 @@
|
|||
package com.projectkorra.ProjectKorra.waterbending;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import com.projectkorra.ProjectKorra.Methods;
|
||||
import com.projectkorra.ProjectKorra.ProjectKorra;
|
||||
|
||||
public class SpikeField {
|
||||
|
||||
private static int radius = 6;
|
||||
public static int numofspikes = ((radius * 2) * (radius * 2)) / 16;
|
||||
private static long cooldown = ProjectKorra.plugin.getConfig().getLong("Abilities.Water.IceSpike.Cooldown");
|
||||
public static Map<Player, Long> cooldowns = new HashMap<Player, Long>();
|
||||
|
||||
Random ran = new Random();
|
||||
private int damage = 2;
|
||||
private Vector thrown = new Vector(0, 1, 0);
|
||||
|
||||
public SpikeField(Player p) {
|
||||
if (cooldowns.containsKey(p))
|
||||
if (cooldowns.get(p) + cooldown >= System.currentTimeMillis())
|
||||
return;
|
||||
// Tools.verbose("Trying to create IceField" + numofspikes);
|
||||
int locX = p.getLocation().getBlockX();
|
||||
int locY = p.getLocation().getBlockY();
|
||||
int locZ = p.getLocation().getBlockZ();
|
||||
List<Block> iceblocks = new ArrayList<Block>();
|
||||
for (int x = -(radius - 1); x <= (radius - 1); x++) {
|
||||
for (int z = -(radius - 1); z <= (radius - 1); z++) {
|
||||
for (int y = -1; y <= 1; y++) {
|
||||
Block testblock = p.getWorld().getBlockAt(locX + x,
|
||||
locY + y, locZ + z);
|
||||
if (testblock.getType() == Material.ICE
|
||||
&& testblock.getRelative(BlockFace.UP).getType() == Material.AIR
|
||||
&& !(testblock.getX() == p.getEyeLocation()
|
||||
.getBlock().getX() && testblock.getZ() == p
|
||||
.getEyeLocation().getBlock().getZ())) {
|
||||
iceblocks.add(testblock);
|
||||
// /Tools.verbose("X: " + testblock.getLocation().getX()
|
||||
// + " Y: " + testblock.getLocation().getY() + " Z: " +
|
||||
// testblock.getLocation().getZ());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<Entity> entities = Methods.getEntitiesAroundPoint(p.getLocation(),
|
||||
radius);
|
||||
|
||||
for (int i = 0; i < numofspikes; i++) {
|
||||
if (iceblocks.isEmpty())
|
||||
return;
|
||||
|
||||
Entity target = null;
|
||||
Block targetblock = null;
|
||||
for (Entity entity : entities) {
|
||||
if (entity instanceof LivingEntity
|
||||
&& entity.getEntityId() != p.getEntityId()) {
|
||||
for (Block block : iceblocks) {
|
||||
if (block.getX() == entity.getLocation().getBlockX()
|
||||
&& block.getZ() == entity.getLocation()
|
||||
.getBlockZ()) {
|
||||
target = entity;
|
||||
targetblock = block;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (target != null) {
|
||||
entities.remove(target);
|
||||
} else {
|
||||
targetblock = iceblocks.get(ran.nextInt(iceblocks.size()));
|
||||
}
|
||||
|
||||
// Tools.verbose("X: " + targetblock.getLocation().getX() + " Y: " +
|
||||
// targetblock.getLocation().getY() + " Z: " +
|
||||
// targetblock.getLocation().getZ());
|
||||
if (targetblock.getRelative(BlockFace.UP).getType() != Material.ICE) {
|
||||
new IceSpike(p, targetblock.getLocation(), damage, thrown, cooldown);
|
||||
IceSpike.cooldowns.put(p.getName(), System.currentTimeMillis());
|
||||
iceblocks.remove(targetblock);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// for (int i = 0; i < (numofspikes / 2); i++){
|
||||
// int blockX = ran.nextInt(radius) + 1;
|
||||
// int blockZ = ran.nextInt((radius * 2) + 1) - radius;
|
||||
// Block b = p.getLocation().getWorld().getBlockAt(locX + blockX, locY - 1, locZ
|
||||
// - blockZ);
|
||||
// if (b.getType() == Material.ICE){
|
||||
// new IceSpike(p, b.getLocation(), 2);
|
||||
// } else {
|
||||
// for (i = 0; i <= heigth; i++) {
|
||||
// b = b.getRelative(BlockFace.DOWN);
|
||||
// if (b.getType() == Material.ICE){
|
||||
// new IceSpike(p, b.getLocation(), 2);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// for (int i = 0; i < (numofspikes / 2); i++){
|
||||
// int blockX = ran.nextInt(radius) + 1;
|
||||
// int blockZ = ran.nextInt((radius * 2) + 1) - radius;
|
||||
// Block b = p.getLocation().getWorld().getBlockAt(locX - blockX, locY - 1, locZ
|
||||
// - blockZ);
|
||||
// if (b.getType() == Material.ICE) {
|
||||
// new IceSpike(p, b.getLocation(), 2);
|
||||
// } else {
|
||||
// for (i = 0; i <= heigth; i++) {
|
||||
// b = b.getRelative(BlockFace.DOWN);
|
||||
// if (b.getType() == Material.ICE){
|
||||
// new IceSpike(p, b.getLocation(), 2);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
|
@ -82,6 +82,14 @@ Abilities:
|
|||
Description: "This ability was made illegal for a reason. With this ability selected, sneak while targeting something and you will bloodbend that target. Bloodbent targets cannot move, bend, or attack. You are free to control their actions by looking elsewhere - they will be forced to move in that direciton. Additionally, clicking while bloodbending will launch that target off in the direction you're looking. People who are capable of bloodbending are immune to technique, and you are immune to theirs.";
|
||||
ThrowFactor: 2
|
||||
Range: 10
|
||||
IceSpike:
|
||||
Enabled: true
|
||||
Description: "This ability has many functions. Clicking while targetting ice, or an entity over some ice, will raise a spike of ice up, damaging and slowing the target. Tapping sneak (default: shift) while selecting a water source will select that source that can be fired with a click. Firing this will launch a spike of ice at your target, dealing a bit of damage and slowing the target. If you sneak (shift) will not selecting a source, many ice spikes will erupt from around you, damaging and slowing those targets."
|
||||
Cooldown: 2000
|
||||
Damage: 2
|
||||
Range: 20
|
||||
ThrowingMult: 0.7
|
||||
Height: 6
|
||||
OctopusForm:
|
||||
Enabled: true
|
||||
Description: "This ability allows the waterbender to manipulate a large quantity of water into a form resembling that of an octopus. To use, click to select a water source. Then, hold sneak to channel this ability. While channleing, the water will form itself around you and has a chance to block incoming attacks. Additionally, you can click while channeling to attack things near you, dealing damage and knocking the target back. Releasing shift at any time will dissipate the form."
|
||||
|
|
Loading…
Reference in a new issue