WaterManipulation

This commit is contained in:
MistPhizzle 2014-06-25 13:08:36 -04:00
parent 8c60f64623
commit bd1f83f2cf
8 changed files with 967 additions and 95 deletions

View file

@ -30,6 +30,7 @@ import com.projectkorra.ProjectKorra.firebending.FireStream;
import com.projectkorra.ProjectKorra.waterbending.Bloodbending; import com.projectkorra.ProjectKorra.waterbending.Bloodbending;
import com.projectkorra.ProjectKorra.waterbending.FreezeMelt; import com.projectkorra.ProjectKorra.waterbending.FreezeMelt;
import com.projectkorra.ProjectKorra.waterbending.Plantbending; import com.projectkorra.ProjectKorra.waterbending.Plantbending;
import com.projectkorra.ProjectKorra.waterbending.WaterManipulation;
import com.projectkorra.ProjectKorra.waterbending.WaterPassive; import com.projectkorra.ProjectKorra.waterbending.WaterPassive;
import com.projectkorra.ProjectKorra.waterbending.WaterSpout; import com.projectkorra.ProjectKorra.waterbending.WaterSpout;
@ -104,6 +105,10 @@ public class BendingManager implements Runnable {
CompactColumn.progress(ID); CompactColumn.progress(ID);
} }
for (int ID: WaterManipulation.instances.keySet()) {
WaterManipulation.progress(ID);
}
FireStream.dissipateAll(); FireStream.dissipateAll();
} catch (Exception e) { } catch (Exception e) {
Methods.stopBending(); Methods.stopBending();

View file

@ -37,6 +37,7 @@ import com.projectkorra.ProjectKorra.earthbending.EarthColumn;
import com.projectkorra.ProjectKorra.earthbending.EarthPassive; import com.projectkorra.ProjectKorra.earthbending.EarthPassive;
import com.projectkorra.ProjectKorra.waterbending.FreezeMelt; import com.projectkorra.ProjectKorra.waterbending.FreezeMelt;
import com.projectkorra.ProjectKorra.waterbending.WaterCore; import com.projectkorra.ProjectKorra.waterbending.WaterCore;
import com.projectkorra.ProjectKorra.waterbending.WaterManipulation;
public class Methods { public class Methods {

View file

@ -65,6 +65,7 @@ import com.projectkorra.ProjectKorra.waterbending.Bloodbending;
import com.projectkorra.ProjectKorra.waterbending.FreezeMelt; import com.projectkorra.ProjectKorra.waterbending.FreezeMelt;
import com.projectkorra.ProjectKorra.waterbending.Melt; import com.projectkorra.ProjectKorra.waterbending.Melt;
import com.projectkorra.ProjectKorra.waterbending.WaterCore; import com.projectkorra.ProjectKorra.waterbending.WaterCore;
import com.projectkorra.ProjectKorra.waterbending.WaterManipulation;
import com.projectkorra.ProjectKorra.waterbending.WaterPassive; import com.projectkorra.ProjectKorra.waterbending.WaterPassive;
import com.projectkorra.ProjectKorra.waterbending.WaterSpout; import com.projectkorra.ProjectKorra.waterbending.WaterSpout;
@ -98,10 +99,14 @@ public class PKListener implements Listener {
Block toblock = event.getToBlock(); Block toblock = event.getToBlock();
Block fromblock = event.getBlock(); Block fromblock = event.getBlock();
if (Methods.isWater(fromblock)) { if (Methods.isWater(fromblock)) {
event.setCancelled(!AirBubble.canFlowTo(toblock));
if (!event.isCancelled()) { if (!event.isCancelled()) {
if (Methods.isAdjacentToFrozenBlock(toblock) || Methods.isAdjacentToFrozenBlock(fromblock)) { event.setCancelled(!WaterManipulation.canFlowFromTo(fromblock,
event.setCancelled(true); toblock));
} }
if (!event.isCancelled()) {
if (Illumination.blocks.containsKey(toblock))
toblock.setType(Material.AIR);
} }
} }
} }
@ -175,6 +180,9 @@ public class PKListener implements Listener {
if (abil.equalsIgnoreCase("PhaseChange")) { if (abil.equalsIgnoreCase("PhaseChange")) {
new Melt(player); new Melt(player);
} }
if (abil.equalsIgnoreCase("WaterManipulation")) {
new WaterManipulation(player);
}
} }
if (Methods.isEarthAbility(abil)) { if (Methods.isEarthAbility(abil)) {
@ -350,6 +358,9 @@ public class PKListener implements Listener {
if (abil.equalsIgnoreCase("WaterSpout")) { if (abil.equalsIgnoreCase("WaterSpout")) {
new WaterSpout(player); new WaterSpout(player);
} }
if (abil.equalsIgnoreCase("WaterManipulation")) {
WaterManipulation.moveWater(player);
}
} }
if (Methods.isEarthAbility(abil)) { if (Methods.isEarthAbility(abil)) {
@ -586,17 +597,21 @@ public class PKListener implements Listener {
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onBlockPhysics(BlockPhysicsEvent event) { public void onBlockPhysics(BlockPhysicsEvent event) {
Block block = event.getBlock(); Block block = event.getBlock();
if (TempBlock.isTempBlock(block) || TempBlock.isTouchingTempBlock(block)) { event.setCancelled(!WaterManipulation.canPhysicsChange(block));
event.setCancelled(true); if (!event.isCancelled())
} event.setCancelled(Illumination.blocks.containsKey(block));
if (!event.isCancelled())
event.setCancelled(Methods.tempnophysics.contains(block));
} }
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onBlockForm(BlockFormEvent event) { public void onBlockForm(BlockFormEvent event) {
if (!WaterCore.canPhysicsChange(event.getBlock())) if (TempBlock.isTempBlock(event.getBlock()))
event.setCancelled(true);
if (!WaterManipulation.canPhysicsChange(event.getBlock()))
event.setCancelled(true); event.setCancelled(true);
} }
public void onNameTag(AsyncPlayerReceiveNameTagEvent e) { public void onNameTag(AsyncPlayerReceiveNameTagEvent e) {
List<Element> elements = Methods.getBendingPlayer(e.getNamedPlayer().getName()).getElements(); List<Element> elements = Methods.getBendingPlayer(e.getNamedPlayer().getName()).getElements();
if (elements.size() > 1) if (elements.size() > 1)

View file

@ -50,9 +50,9 @@ public class FreezeMelt {
} }
private static boolean isFreezable(Player player, Block block) { private static boolean isFreezable(Player player, Block block) {
if (Methods.isRegionProtectedFromBuild(player, Abilities.PhaseChange, // if (Methods.isRegionProtectedFromBuild(player, Abilities.PhaseChange,
block.getLocation())) // block.getLocation()))
return false; // return false;
if (block.getType() == Material.WATER if (block.getType() == Material.WATER
|| block.getType() == Material.STATIONARY_WATER) || block.getType() == Material.STATIONARY_WATER)
if (WaterManipulation.canPhysicsChange(block) if (WaterManipulation.canPhysicsChange(block)

View file

@ -1,84 +0,0 @@
package com.projectkorra.ProjectKorra.waterbending;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.Material;
import org.bukkit.block.Block;
import com.projectkorra.ProjectKorra.Methods;
import com.projectkorra.ProjectKorra.TempBlock;
public class WaterCore {
public static ConcurrentHashMap<Block, Byte> frozenblocks = new ConcurrentHashMap<Block, Byte>();
public static ConcurrentHashMap<Block, Block> waterSpoutAffectedBlocks = new ConcurrentHashMap<Block, Block>();
public static ConcurrentHashMap<Block, Block> waterManipulationAffectedBlocks = new ConcurrentHashMap<Block, Block>();
// public static void removeSpouts(Location loc0, double radius,
// Player sourceplayer) {
// if (!Methods.isAbilityInstalled("WaterSpout", "orion304")) return;
// for (Player player : WaterSpoutAbility.instances.keySet()) {
// if (!player.equals(sourceplayer)) {
// Location loc1 = player.getLocation().getBlock().getLocation();
// loc0 = loc0.getBlock().getLocation();
// double dx = loc1.getX() - loc0.getX();
// double dy = loc1.getY() - loc0.getY();
// double dz = loc1.getZ() - loc0.getZ();
//
// double distance = Math.sqrt(dx * dx + dz * dz);
//
// if (distance <= radius && dy > 0 && dy < WaterSpoutAbility.defaultheight)
// WaterSpoutAbility.instances.get(player).remove();
// }
// }
// }
public static void thaw(Block block) {
if (frozenblocks.containsKey(block)) {
byte data = frozenblocks.get(block);
frozenblocks.remove(block);
block.setType(Material.WATER);
block.setData(data);
}
}
public static boolean canFlowFromTo(Block from, Block to) {
if (WaterCore.waterManipulationAffectedBlocks.containsKey(to) || WaterCore.waterManipulationAffectedBlocks.containsKey(from)) {
return false;
}
if (WaterCore.waterSpoutAffectedBlocks.containsKey(to) || WaterCore.waterSpoutAffectedBlocks.containsKey(from)) {
return false;
}
if (TempBlock.isTempBlock(to) || TempBlock.isTempBlock(from)) {
return false;
}
if (Methods.isAdjacentToFrozenBlock(to)
|| Methods.isAdjacentToFrozenBlock(from)) {
return false;
}
return true;
}
public static boolean canPhysicsChange(Block block) {
if (waterManipulationAffectedBlocks.containsKey(block))
return false;
if (Methods.isAbilityInstalled("WaterSpout", "orion304")) {
if (waterSpoutAffectedBlocks.containsKey(block))
return false;
}
// if (Methods.isAbilityInstalled("Surge", "orion304")) {
// if (waterWallAffectedBlocks.containsKey(block))
// return false;
// if (waterwallblocks.containsKey(block))
// return false;
//// if (WaveAbility.isBlockWave(block))
//// return false;
// }
if (TempBlock.isTempBlock(block))
return false;
if (TempBlock.isTouchingTempBlock(block))
return false;
return true;
}
}

View file

@ -0,0 +1,707 @@
package com.projectkorra.ProjectKorra.waterbending;
import java.util.HashSet;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.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;
import com.projectkorra.ProjectKorra.TempBlock;
import com.projectkorra.ProjectKorra.Ability.AvatarState;
public class WaterManipulation {
public static ConcurrentHashMap<Integer, WaterManipulation> instances = new ConcurrentHashMap<Integer, WaterManipulation>();
public static ConcurrentHashMap<Block, Block> affectedblocks = new ConcurrentHashMap<Block, Block>();
public static ConcurrentHashMap<Player, Integer> prepared = new ConcurrentHashMap<Player, Integer>();
private static int ID = Integer.MIN_VALUE;
private static final byte full = 0x0;
// private static final byte half = 0x4;
static double range = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.WaterManipulation.Range");
private static double pushfactor = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.WaterManipulation.Push");
private static double defaultdamage = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.WaterManipulation.Damage");
private static double speed = ProjectKorra.plugin.getConfig().getDouble("Abilities.Water.WaterManipulation.Speed");
private static final double deflectrange = 3;
// private static double speed = 1.5;
private static HashSet<Byte> water = new HashSet<Byte>();
private static long interval = (long) (1000. / speed);
Player player;
private int id;
private Location location = null;
private Block sourceblock = null;
private TempBlock trail, trail2;
private boolean progressing = false;
private Location firstdestination = null;
private Location targetdestination = null;
private Vector firstdirection = null;
private Vector targetdirection = null;
private boolean falling = false;
private boolean settingup = false;
// private boolean targetting = false;
private final boolean displacing = false;
private long time;
private double damage = defaultdamage;
private int displrange;
public WaterManipulation(Player player) {
if (water.isEmpty()) {
water.add((byte) 0);
water.add((byte) 8);
water.add((byte) 9);
}
this.player = player;
if (prepare()) {
id = ID;
instances.put(id, this);
prepared.put(player, id);
if (ID == Integer.MAX_VALUE)
ID = Integer.MIN_VALUE;
ID++;
time = System.currentTimeMillis();
}
}
public boolean prepare() {
// Block block = player.getTargetBlock(null, (int) range);
Block block = Methods.getWaterSourceBlock(player, range,
Methods.canPlantbend(player));
// if (prepared.containsKey(player)
// && !Methods.isWaterbendable(block, player)) {
// instances.get(prepared.get(player)).displacing = true;
// instances.get(prepared.get(player)).moveWater();
// }
cancelPrevious();
block(player);
if (block != null) {
sourceblock = block;
focusBlock();
return true;
}
return false;
}
private void cancelPrevious() {
if (prepared.containsKey(player)) {
if (instances.containsKey(prepared.get(player))) {
WaterManipulation old = instances.get(prepared.get(player));
if (!old.progressing) {
old.cancel();
}
}
}
}
public void cancel() {
unfocusBlock();
}
private void focusBlock() {
location = sourceblock.getLocation();
}
private void unfocusBlock() {
remove(id);
}
public void moveWater() {
if (sourceblock != null) {
if (sourceblock.getWorld() == player.getWorld()) {
targetdestination = getTargetLocation(player);
if (targetdestination.distance(location) <= 1) {
progressing = false;
targetdestination = null;
remove(id);
} else {
progressing = true;
settingup = true;
firstdestination = getToEyeLevel();
firstdirection = Methods.getDirection(
sourceblock.getLocation(), firstdestination)
.normalize();
targetdestination = Methods.getPointOnLine(firstdestination,
targetdestination, range);
targetdirection = Methods.getDirection(firstdestination,
targetdestination).normalize();
if (Methods.isPlant(sourceblock))
new Plantbending(sourceblock);
addWater(sourceblock);
}
}
BendingPlayer.getBendingPlayer(player).cooldown(
Abilities.WaterManipulation);
}
}
private static Location getTargetLocation(Player player) {
Entity target = Methods.getTargetedEntity(player, range, new ArrayList<Entity>());
Location location;
if (target == null) {
location = Methods.getTargetedLocation(player, range,
Methods.transparentToEarthbending);
} else {
// targetting = true;
location = ((LivingEntity) target).getEyeLocation();
// location.setY(location.getY() - 1);
}
return location;
}
private Location getToEyeLevel() {
Location loc = sourceblock.getLocation().clone();
double dy = targetdestination.getY() - sourceblock.getY();
if (dy <= 2) {
loc.setY(sourceblock.getY() + 2);
} else {
loc.setY(targetdestination.getY() - 1);
}
return loc;
}
private static void remove(int id) {
Player player = instances.get(id).player;
if (prepared.containsKey(player)) {
if (prepared.get(player) == id)
prepared.remove(player);
}
instances.remove(id);
}
private void redirect(Player player, Location targetlocation) {
if (progressing && !settingup) {
if (location.distance(player.getLocation()) <= range)
targetdirection = Methods.getDirection(location, targetlocation)
.normalize();
targetdestination = targetlocation;
this.player = player;
}
}
public boolean progress() {
if (player.isDead() || !player.isOnline()
|| !Methods.canBend(player.getName(), "WaterManipulation")) {
breakBlock();
return false;
}
if (System.currentTimeMillis() - time >= interval) {
// removeWater(oldwater);
// if (Methods.isRegionProtectedFromBuild(player,
// Abilities.WaterManipulation, location)) {
// breakBlock();
// return false;
// }
time = System.currentTimeMillis();
if (Methods.getBoundAbility(player) == null) {
unfocusBlock();
return false;
}
if (!progressing
&& !falling
&& !Methods.getBoundAbility(player).equalsIgnoreCase("WaterManipulation")) {
unfocusBlock();
return false;
}
if (falling) {
// location = location.clone().add(0, -1, 0);
//
// if (location.getBlock().getType() != Material.AIR) {
// falling = false;
// unfocusBlock();
// return false;
// }
//
// for (Entity entity : Methods.getEntitiesAroundPoint(location,
// 1)) {
// if (entity instanceof LivingEntity) {
// Methods.damageEntity(player, entity, damage);
// falling = false;
// }
// }
//
// if (!falling) {
// breakBlock();
// return false;
// }
//
// location.getBlock().setType(sourceblock.getType());
// sourceblock.setType(Material.AIR);
//
// sourceblock = location.getBlock();
// if (!Methods.isSolid(sourceblock.getRelative(BlockFace.DOWN))
// || targetting) {
// finalRemoveWater(sourceblock);
// } else {
// sourceblock.setData(full);
// affectedblocks.remove(sourceblock);
// }
//
// instances.remove(player.getEntityId());
breakBlock();
new WaterReturn(player, sourceblock);
return false;
} else {
if (!progressing) {
sourceblock.getWorld().playEffect(location, Effect.SMOKE,
4, (int) range);
return false;
}
// Methods.verbose(firstdestination);
if (sourceblock.getLocation().distance(firstdestination) < .5) {
settingup = false;
}
// if (!player.isSneaking() && displacing) {
// displacing = false;
// breakBlock();
// return false;
// }
Vector direction;
if (settingup) {
direction = firstdirection;
} else {
direction = targetdirection;
}
Block block = location.getBlock();
if (displacing) {
Block targetblock = player.getTargetBlock(null, displrange);
direction = Methods.getDirection(location,
targetblock.getLocation()).normalize();
if (!location.getBlock().equals(targetblock.getLocation())) {
location = location.clone().add(direction);
block = location.getBlock();
if (block.getLocation().equals(
sourceblock.getLocation())) {
location = location.clone().add(direction);
block = location.getBlock();
}
}
} else {
Methods.removeSpouts(location, player);
double radius = FireBlast.affectingradius;
Player source = player;
if (EarthBlast.annihilateBlasts(location, radius, source)
|| WaterManipulation.annihilateBlasts(location,
radius, source)
|| FireBlast.annihilateBlasts(location, radius,
source)) {
breakBlock();
new WaterReturn(player, sourceblock);
return false;
}
location = location.clone().add(direction);
block = location.getBlock();
if (block.getLocation().equals(sourceblock.getLocation())) {
location = location.clone().add(direction);
block = location.getBlock();
}
}
if (trail2 != null) {
if (trail2.getBlock().equals(block)) {
trail2.revertBlock();
trail2 = null;
}
}
if (trail != null) {
if (trail.getBlock().equals(block)) {
trail.revertBlock();
trail = null;
if (trail2 != null) {
trail2.revertBlock();
trail2 = null;
}
}
}
if (Methods.isTransparentToEarthbending(player, block)
&& !block.isLiquid()) {
Methods.breakBlock(block);
} else if (block.getType() != Material.AIR
&& !Methods.isWater(block)) {
breakBlock();
new WaterReturn(player, sourceblock);
return false;
}
if (!displacing) {
for (Entity entity : Methods.getEntitiesAroundPoint(location,
FireBlast.affectingradius)) {
if (entity instanceof LivingEntity
&& entity.getEntityId() != player.getEntityId()) {
// Block testblock = location.getBlock();
// Block block1 = entity.getLocation().getBlock();
// Block block2 = ((LivingEntity) entity)
// .getEyeLocation().getBlock();
//
// if (testblock.equals(block1)
// || testblock.equals(block2)) {
Location location = player.getEyeLocation();
Vector vector = location.getDirection();
entity.setVelocity(vector.normalize().multiply(pushfactor));
// entity.setVelocity(entity.getVelocity().clone()
// .add(direction));
if (AvatarState.isAvatarState(player))
damage = AvatarState.getValue(damage);
Methods.damageEntity(player, entity, (int) Methods
.waterbendingNightAugment(damage,
player.getWorld()));
progressing = false;
// }
}
}
}
if (!progressing) {
breakBlock();
new WaterReturn(player, sourceblock);
return false;
}
addWater(block);
reduceWater(sourceblock);
// if (block.getType() != Material.AIR) {
// block.setType(Material.GLOWSTONE);
// } else {
// block.setType(Material.GLASS);
// }
if (trail2 != null) {
trail2.revertBlock();
trail2 = null;
}
if (trail != null) {
trail2 = trail;
trail2.setType(Material.WATER, (byte) 2);
}
trail = new TempBlock(sourceblock, Material.WATER, (byte) 1);
sourceblock = block;
if (location.distance(targetdestination) <= 1
|| location.distance(firstdestination) > range) {
falling = true;
progressing = false;
}
return true;
}
}
return false;
}
private void breakBlock() {
// removeWater(oldwater);
finalRemoveWater(sourceblock);
remove(id);
}
private void reduceWater(Block block) {
if (displacing) {
removeWater(block);
return;
}
if (affectedblocks.containsKey(block)) {
if (!Methods.isAdjacentToThreeOrMoreSources(block)) {
// && !Methods.adjacentToAnyWater(block)) {
block.setType(Material.AIR);
// block.setType(Material.WATER);
// block.setData(half);
}
// oldwater = block;
affectedblocks.remove(block);
}
}
private void removeWater(Block block) {
if (block != null) {
if (affectedblocks.containsKey(block)) {
if (!Methods.isAdjacentToThreeOrMoreSources(block)) {
block.setType(Material.AIR);
}
affectedblocks.remove(block);
}
}
}
private void finalRemoveWater(Block block) {
if (trail != null) {
trail.revertBlock();
trail = null;
}
if (trail2 != null) {
trail2.revertBlock();
trail = null;
}
if (displacing) {
removeWater(block);
return;
}
if (affectedblocks.containsKey(block)) {
if (!Methods.isAdjacentToThreeOrMoreSources(block)) {
// && !Methods.adjacentToAnyWater(block)) {
block.setType(Material.AIR);
// block.setType(Material.WATER);
// block.setData(half);
}
affectedblocks.remove(block);
}
}
private static void addWater(Block block) {
if (!affectedblocks.containsKey(block)) {
affectedblocks.put(block, block);
}
if (FreezeMelt.frozenblocks.containsKey(block))
FreezeMelt.frozenblocks.remove(block);
block.setType(Material.WATER);
block.setData(full);
}
public static void moveWater(Player player) {
// BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
// if (!bPlayer.isOnCooldown(Abilities.WaterManipulation)) {
if (prepared.containsKey(player)) {
if (instances.containsKey(prepared.get(player))) {
instances.get(prepared.get(player)).moveWater();
}
prepared.remove(player);
} else 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())) {
if (getTargetLocation(player).distance(block.getLocation()) > 1) {
block.setType(Material.WATER);
block.setData(full);
WaterManipulation watermanip = new WaterManipulation(
player);
watermanip.moveWater();
if (!watermanip.progressing) {
block.setType(Material.AIR);
} else {
WaterReturn.emptyWaterBottle(player);
}
}
}
}
// }
redirectTargettedBlasts(player);
}
private static void redirectTargettedBlasts(Player player) {
for (int id : instances.keySet()) {
WaterManipulation manip = instances.get(id);
if (!manip.progressing)
continue;
if (!manip.location.getWorld().equals(player.getWorld()))
continue;
// if (Methods.isRegionProtectedFromBuild(player,
// Abilities.WaterManipulation, manip.location))
// continue;
if (manip.player.equals(player))
manip.redirect(player, getTargetLocation(player));
Location location = player.getEyeLocation();
Vector vector = location.getDirection();
Location mloc = manip.location;
if (mloc.distance(location) <= range
&& Methods.getDistanceFromLine(vector, location,
manip.location) < deflectrange
&& mloc.distance(location.clone().add(vector)) < mloc
.distance(location.clone().add(
vector.clone().multiply(-1)))) {
manip.redirect(player, getTargetLocation(player));
}
}
}
private static void block(Player player) {
for (int id : instances.keySet()) {
WaterManipulation manip = instances.get(id);
if (manip.player.equals(player))
continue;
if (!manip.location.getWorld().equals(player.getWorld()))
continue;
if (!manip.progressing)
continue;
//
// if (Methods.isRegionProtectedFromBuild(player,
// Abilities.WaterManipulation, manip.location))
// continue;
Location location = player.getEyeLocation();
Vector vector = location.getDirection();
Location mloc = manip.location;
if (mloc.distance(location) <= range
&& Methods.getDistanceFromLine(vector, location,
manip.location) < deflectrange
&& mloc.distance(location.clone().add(vector)) < mloc
.distance(location.clone().add(
vector.clone().multiply(-1)))) {
manip.breakBlock();
}
}
}
public static boolean progress(int ID) {
if (instances.containsKey(ID))
return instances.get(ID).progress();
return false;
}
public static boolean canFlowFromTo(Block from, Block to) {
// if (to.getType() == Material.TORCH)
// return true;
if (affectedblocks.containsKey(to) || affectedblocks.containsKey(from)) {
// Methods.verbose("affectedblocks");
return false;
}
if (WaterSpout.affectedblocks.containsKey(to)
|| WaterSpout.affectedblocks.containsKey(from)) {
// Methods.verbose("waterspout");
return false;
}
if (WaterWall.affectedblocks.containsKey(to)
|| WaterWall.affectedblocks.containsKey(from)) {
// Methods.verbose("waterwallaffectedblocks");
return false;
}
if (WaterWall.wallblocks.containsKey(to)
|| WaterWall.wallblocks.containsKey(from)) {
// Methods.verbose("waterwallwall");
return false;
}
if (Wave.isBlockWave(to) || Wave.isBlockWave(from)) {
// Methods.verbose("wave");
return false;
}
if (TempBlock.isTempBlock(to) || TempBlock.isTempBlock(from)) {
// Methods.verbose("tempblock");
return false;
}
if (Methods.isAdjacentToFrozenBlock(to)
|| Methods.isAdjacentToFrozenBlock(from)) {
// Methods.verbose("frozen");
return false;
}
return true;
}
public static boolean canPhysicsChange(Block block) {
if (affectedblocks.containsKey(block))
return false;
if (WaterSpout.affectedblocks.containsKey(block))
return false;
if (WaterWall.affectedblocks.containsKey(block))
return false;
if (WaterWall.wallblocks.containsKey(block))
return false;
if (Wave.isBlockWave(block))
return false;
if (TempBlock.isTempBlock(block))
return false;
if (TempBlock.isTouchingTempBlock(block))
return false;
return true;
}
public static void removeAll() {
for (int id : instances.keySet())
instances.get(id).breakBlock();
prepared.clear();
}
public static boolean canBubbleWater(Block block) {
return canPhysicsChange(block);
}
public static String getDescription() {
// TODO Auto-generated method stub
return "To use, place your cursor over a waterbendable object and tap sneak (default: shift). "
+ "Smoke will appear where you've selected, indicating the origin of your ability. "
+ "After you have selected an origin, simply left-click in any direction and you will "
+ "see your water spout off in that direction, slicing any creature in its path. "
+ "If you look towards a creature when you use this ability, it will target that creature. "
+ "A collision from Water Manipulation both knocks the target back and deals some damage. "
+ "Alternatively, if you have source selected and tap shift again, "
+ "you will be able to control the water more directly.";
}
public static void removeAroundPoint(Location location, double radius) {
for (int id : instances.keySet()) {
WaterManipulation manip = instances.get(id);
if (manip.location.getWorld().equals(location.getWorld()))
if (manip.location.distance(location) <= radius)
manip.breakBlock();
}
}
public static boolean annihilateBlasts(Location location, double radius,
Player source) {
boolean broke = false;
for (int id : instances.keySet()) {
WaterManipulation manip = instances.get(id);
if (manip.location.getWorld().equals(location.getWorld())
&& !source.equals(manip.player))
if (manip.location.distance(location) <= radius) {
manip.breakBlock();
broke = true;
}
}
return broke;
}
}

View file

@ -0,0 +1,221 @@
package com.projectkorra.ProjectKorra.waterbending;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.util.Vector;
import com.projectkorra.ProjectKorra.Methods;
import com.projectkorra.ProjectKorra.TempBlock;
public class WaterReturn {
private static ConcurrentHashMap<Player, WaterReturn> instances = new ConcurrentHashMap<Player, WaterReturn>();
// private static int ID = Integer.MIN_VALUE;
private static long interval = 50;
private static final byte full = 0x0;
private static double range = 30;
private Player player;
// private int id;
private Location location;
private TempBlock block;
private long time;
public WaterReturn(Player player, Block block) {
if (instances.containsKey(player))
return;
this.player = player;
location = block.getLocation();
if (Methods.canBend(player.getName(), "WaterManipulation")) {
// if (!Methods.isRegionProtectedFromBuild(player,
// Abilities.WaterManipulation, location)
// && Methods.canBend(player, Abilities.WaterManipulation)) {
if (Methods.isTransparentToEarthbending(player, block)
&& !block.isLiquid())
this.block = new TempBlock(block, Material.WATER, full);
}
// if (ID >= Integer.MAX_VALUE) {
// ID = Integer.MIN_VALUE;
// }
// id = ID++;
instances.put(player, this);
}
private void progress() {
if (!hasEmptyWaterBottle()) {
remove();
return;
}
if (player.isDead() || !player.isOnline()) {
remove();
return;
}
if (player.getWorld() != location.getWorld()) {
remove();
return;
}
if (System.currentTimeMillis() < time + interval)
return;
time = System.currentTimeMillis();
Vector direction = Methods
.getDirection(location, player.getEyeLocation()).normalize();
location = location.clone().add(direction);
if (location == null || block == null) {
remove();
return;
}
if (location.getBlock().equals(block.getLocation().getBlock()))
return;
// if (Methods.isRegionProtectedFromBuild(player,
// Abilities.WaterManipulation, location)) {
// remove();
// return;
// }
if (location.distance(player.getEyeLocation()) > Methods
.waterbendingNightAugment(range, player.getWorld())) {
remove();
return;
}
if (location.distance(player.getEyeLocation()) <= 1.5) {
fillBottle();
return;
}
Block newblock = location.getBlock();
if (Methods.isTransparentToEarthbending(player, newblock)
&& !newblock.isLiquid()) {
block.revertBlock();
block = new TempBlock(newblock, Material.WATER, full);
} else {
remove();
return;
}
}
private void remove() {
if (block != null) {
block.revertBlock();
block = null;
}
instances.remove(player);
}
private boolean hasEmptyWaterBottle() {
PlayerInventory inventory = player.getInventory();
if (inventory.contains(Material.GLASS_BOTTLE)) {
return true;
}
return false;
}
private void fillBottle() {
PlayerInventory inventory = player.getInventory();
if (inventory.contains(Material.GLASS_BOTTLE)) {
int index = inventory.first(Material.GLASS_BOTTLE);
ItemStack item = inventory.getItem(index);
if (item.getAmount() == 1) {
inventory.setItem(index, new ItemStack(Material.POTION));
} else {
item.setAmount(item.getAmount() - 1);
inventory.setItem(index, item);
HashMap<Integer, ItemStack> leftover = inventory
.addItem(new ItemStack(Material.POTION));
for (int left : leftover.keySet()) {
player.getWorld().dropItemNaturally(player.getLocation(),
leftover.get(left));
}
}
}
remove();
}
private static boolean isBending(Player player) {
for (int id : WaterManipulation.instances.keySet()) {
if (WaterManipulation.instances.get(id).player.equals(player))
return true;
}
if (OctopusForm.instances.containsKey(player))
return true;
for (int id : Wave.instances.keySet()) {
if (Wave.instances.get(id).player.equals(player))
return true;
}
for (int id : WaterWall.instances.keySet()) {
if (WaterWall.instances.get(id).player.equals(player))
return true;
}
if (IceSpike2.isBending(player))
return true;
return false;
}
public static boolean hasWaterBottle(Player player) {
if (instances.containsKey(player))
return false;
if (isBending(player))
return false;
PlayerInventory inventory = player.getInventory();
return (inventory.contains(new ItemStack(Material.POTION), 1));
}
public static void emptyWaterBottle(Player player) {
PlayerInventory inventory = player.getInventory();
int index = inventory.first(new ItemStack(Material.POTION));
if (index != -1) {
ItemStack item = inventory.getItem(index);
if (item.getAmount() == 1) {
inventory.setItem(index, new ItemStack(Material.GLASS_BOTTLE));
} else {
item.setAmount(item.getAmount() - 1);
inventory.setItem(index, item);
HashMap<Integer, ItemStack> leftover = inventory
.addItem(new ItemStack(Material.GLASS_BOTTLE));
for (int left : leftover.keySet()) {
player.getWorld().dropItemNaturally(player.getLocation(),
leftover.get(left));
}
}
}
}
public static void progressAll() {
for (Player player : instances.keySet()) {
instances.get(player).progress();
}
}
public static void removeAll() {
for (Player player : instances.keySet()) {
WaterReturn wr = instances.get(player);
if (wr.block != null)
wr.block.revertBlock();
}
instances.clear();
}
}

View file

@ -85,6 +85,13 @@ Abilities:
Radius: 5 Radius: 5
Plantbending: Plantbending:
RegrowTime: 180000 RegrowTime: 180000
WaterManipulation:
Enabled: true
Description: "To use, place your cursor over a waterbendable object and tap sneak (default: shift). Smoke will appear where you've selected, indicating the origin of your ability. After you have selected an origin, simply left-click in any direction and you will see your water spout off in that direction, slicing any creature in its path. If you look towards a creature when you use this ability, it will target that creature. A collision from Water Manipulation both knocks the target back and deals some damage. Alternatively, if you have the source selected and tap shift again, you will be able to control the water more directly."
Damage: 3.0
Range: 20
Speed: 35
Push: .3
WaterSpout: WaterSpout:
Enabled: true Enabled: true
Description: "To use this ability, click while over or in water. You will spout water up from beneath you to experience controlled levitation. This ability is a toggle, so you can activate it then use other abilities and it will remain on. If you try to spout over an area with no water, snow, or ice, the spout will dissipate and you will fall. Click again with this ability selected to deactivate it." Description: "To use this ability, click while over or in water. You will spout water up from beneath you to experience controlled levitation. This ability is a toggle, so you can activate it then use other abilities and it will remain on. If you try to spout over an area with no water, snow, or ice, the spout will dissipate and you will fall. Click again with this ability selected to deactivate it."