TF-ProjectKorra/src/com/projectkorra/projectkorra/waterbending/WaterManipulation.java

777 lines
22 KiB
Java
Raw Normal View History

package com.projectkorra.projectkorra.waterbending;
Various fixes * Lots of Fixes • Added 1.9 and 1.10 particle effects • Fixed Particle Effect version from being wrong • Fixed {ability} not being replaced when trying to bind non-existent move • Fixed permremoving command not sending a message to the executor • Fixed remove command sending user 2 remove messages if they removed their own bending • Fixed who command not replacing {target} in message for players that aren't found • Fixed Chat prefixes not being in the language file * Fixed Chat Prefixes • Fixed chat prefixes from not generating in language.yml file • Added Nonbender prefix * Fixed Waterbending Bugs • Fixes waterbending getting a super far away source when selecting under water • Water from Bottlebending now shows bubbles when under water * Fixed WaterWave & WaterManip Bugs • Fixed WaterManipulation disappearing when the player taps shift • Fixed being able to use current WaterManips as sources for other WaterManips • Fixed WaterWave being able to use more sources while spinning around the player * OfflinePlayer lookup fix + IceWave DeathMessage • Fixed IceWave not having a death message • Fixed /b who not working on offline players * Fixed bad english ;-; * Changes + Fixes • Added Properties.TogglePassivesWithAllBending config option (whether passives should be toggled when bending is toggled globally) • Changed chat prefixes • Re-enabled WarriorStance • Fixed IceBlast being removed when pressing shift • Fixed IceWave and IceBullet from having the wrong colored death messages • Fixed not being able to select ice and plants as sources for WaterManip • Fixed help command showing hidden abilities (WaterReturn, etc) • Fixed WaterManip turning ice sources to air
2016-06-19 16:41:18 +00:00
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Random;
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.BendingPlayer;
import com.projectkorra.projectkorra.GeneralMethods;
2016-01-13 21:14:34 +00:00
import com.projectkorra.projectkorra.ability.AirAbility;
import com.projectkorra.projectkorra.ability.WaterAbility;
import com.projectkorra.projectkorra.ability.util.Collision;
import com.projectkorra.projectkorra.util.BlockSource;
import com.projectkorra.projectkorra.util.ClickType;
import com.projectkorra.projectkorra.util.DamageHandler;
import com.projectkorra.projectkorra.util.ParticleEffect;
import com.projectkorra.projectkorra.util.TempBlock;
import com.projectkorra.projectkorra.waterbending.ice.PhaseChange;
import com.projectkorra.projectkorra.waterbending.plant.PlantRegrowth;
import com.projectkorra.projectkorra.waterbending.util.WaterReturn;
2016-01-13 21:14:34 +00:00
public class WaterManipulation extends WaterAbility {
private static final Map<Block, Block> AFFECTED_BLOCKS = new ConcurrentHashMap<>();
2016-01-13 21:14:34 +00:00
private boolean progressing;
private boolean falling;
private boolean settingUp;
private boolean displacing;
private boolean prepared;
private int dispelRange;
private long time;
2016-01-13 21:14:34 +00:00
private long cooldown;
private long interval;
private double selectRange, range;
2016-01-13 21:14:34 +00:00
private double pushFactor;
private double damage;
private double speed;
private double deflectRange;
2016-01-16 21:07:14 +00:00
private double collisionRadius;
2016-01-13 21:14:34 +00:00
private Block sourceBlock;
private Location location;
private TempBlock trail;
private TempBlock trail2;
private Location firstDestination;
private Location targetDestination;
private Vector firstDirection;
private Vector targetDirection;
private HashSet<Byte> waterTypes;
public WaterManipulation(Player player) {
2016-01-13 21:14:34 +00:00
super(player);
2016-01-13 21:14:34 +00:00
this.progressing = false;
this.falling = false;
this.settingUp = false;
this.displacing = false;
2016-01-16 21:07:14 +00:00
this.collisionRadius = getConfig().getDouble("Abilities.Water.WaterManipulation.CollisionRadius");
2016-01-13 21:14:34 +00:00
this.cooldown = getConfig().getLong("Abilities.Water.WaterManipulation.Cooldown");
this.selectRange = getConfig().getDouble("Abilities.Water.WaterManipulation.SelectRange");
this.range = getConfig().getDouble("Abilities.Water.WaterManipulation.Range");
2016-01-13 21:14:34 +00:00
this.pushFactor = getConfig().getDouble("Abilities.Water.WaterManipulation.Push");
this.damage = getConfig().getDouble("Abilities.Water.WaterManipulation.Damage");
this.speed = getConfig().getDouble("Abilities.Water.WaterManipulation.Speed");
2016-01-16 21:07:14 +00:00
this.deflectRange = getConfig().getDouble("Abilities.Water.WaterManipulation.DeflectRange");
2016-01-13 21:14:34 +00:00
this.waterTypes = new HashSet<Byte>();
2016-01-13 21:14:34 +00:00
this.interval = (long) (1000. / speed);
this.waterTypes.add((byte) 0);
this.waterTypes.add((byte) 8);
this.waterTypes.add((byte) 9);
if (prepare()) {
2016-01-13 21:14:34 +00:00
prepared = true;
start();
time = System.currentTimeMillis();
}
}
2016-01-13 21:14:34 +00:00
private void cancelPrevious() {
Various fixes * Lots of Fixes • Added 1.9 and 1.10 particle effects • Fixed Particle Effect version from being wrong • Fixed {ability} not being replaced when trying to bind non-existent move • Fixed permremoving command not sending a message to the executor • Fixed remove command sending user 2 remove messages if they removed their own bending • Fixed who command not replacing {target} in message for players that aren't found • Fixed Chat prefixes not being in the language file * Fixed Chat Prefixes • Fixed chat prefixes from not generating in language.yml file • Added Nonbender prefix * Fixed Waterbending Bugs • Fixes waterbending getting a super far away source when selecting under water • Water from Bottlebending now shows bubbles when under water * Fixed WaterWave & WaterManip Bugs • Fixed WaterManipulation disappearing when the player taps shift • Fixed being able to use current WaterManips as sources for other WaterManips • Fixed WaterWave being able to use more sources while spinning around the player * OfflinePlayer lookup fix + IceWave DeathMessage • Fixed IceWave not having a death message • Fixed /b who not working on offline players * Fixed bad english ;-; * Changes + Fixes • Added Properties.TogglePassivesWithAllBending config option (whether passives should be toggled when bending is toggled globally) • Changed chat prefixes • Re-enabled WarriorStance • Fixed IceBlast being removed when pressing shift • Fixed IceWave and IceBullet from having the wrong colored death messages • Fixed not being able to select ice and plants as sources for WaterManip • Fixed help command showing hidden abilities (WaterReturn, etc) • Fixed WaterManip turning ice sources to air
2016-06-19 16:41:18 +00:00
Collection<WaterManipulation> manips = getAbilities(player, WaterManipulation.class);
for (WaterManipulation oldmanip : manips) {
if (oldmanip != null && !oldmanip.progressing) {
oldmanip.remove();
}
}
}
2016-01-13 21:14:34 +00:00
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 (AFFECTED_BLOCKS.containsKey(block)) {
if (!GeneralMethods.isAdjacentToThreeOrMoreSources(block)) {
block.setType(Material.AIR);
}
2016-01-13 21:14:34 +00:00
AFFECTED_BLOCKS.remove(block);
}
}
private void focusBlock() {
2016-01-13 21:14:34 +00:00
location = sourceBlock.getLocation();
}
2016-01-13 21:14:34 +00:00
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;
}
public void moveWater() {
2016-01-13 21:14:34 +00:00
if (sourceBlock != null) {
if (sourceBlock.getWorld().equals(player.getWorld())) {
targetDestination = getTargetLocation(player, range);
2016-01-13 21:14:34 +00:00
if (targetDestination.distanceSquared(location) <= 1) {
progressing = false;
2016-01-13 21:14:34 +00:00
targetDestination = null;
remove();
return;
} else {
progressing = true;
2016-01-13 21:14:34 +00:00
settingUp = true;
firstDestination = getToEyeLevel();
2017-01-16 06:48:20 +00:00
firstDirection = GeneralMethods.getDirection(sourceBlock.getLocation(), firstDestination).normalize();
targetDestination = GeneralMethods.getPointOnLine(firstDestination, targetDestination, range);
2016-01-13 21:14:34 +00:00
targetDirection = GeneralMethods.getDirection(firstDestination, targetDestination).normalize();
if (isPlant(sourceBlock) || isSnow(sourceBlock)) {
2016-01-13 21:14:34 +00:00
new PlantRegrowth(player, sourceBlock);
sourceBlock.setType(Material.AIR);
} else if (!isIce(sourceBlock)) {
addWater(sourceBlock);
2016-01-13 21:14:34 +00:00
}
}
}
2016-01-13 21:14:34 +00:00
bPlayer.addCooldown(this);
}
}
2016-01-13 21:14:34 +00:00
public boolean prepare() {
2017-01-16 06:48:20 +00:00
Block block = BlockSource.getWaterSourceBlock(player, selectRange, ClickType.SHIFT_DOWN, true, true, bPlayer.canPlantbend());
2016-01-13 21:14:34 +00:00
cancelPrevious();
//block(player);
2016-01-13 21:14:34 +00:00
if (block != null) {
sourceBlock = block;
focusBlock();
return true;
}
2016-01-13 21:14:34 +00:00
return false;
}
2016-01-13 21:14:34 +00:00
@Override
public void progress() {
if (!bPlayer.canBendIgnoreBindsCooldowns(this)) {
remove();
return;
}
if (System.currentTimeMillis() - time >= interval) {
2016-01-13 21:14:34 +00:00
if (!progressing && !falling && !bPlayer.getBoundAbilityName().equalsIgnoreCase(getName())) {
remove();
return;
}
if (falling) {
2016-01-13 21:14:34 +00:00
remove();
new WaterReturn(player, sourceBlock);
return;
} else {
if (!progressing) {
Various fixes * Lots of Fixes • Added 1.9 and 1.10 particle effects • Fixed Particle Effect version from being wrong • Fixed {ability} not being replaced when trying to bind non-existent move • Fixed permremoving command not sending a message to the executor • Fixed remove command sending user 2 remove messages if they removed their own bending • Fixed who command not replacing {target} in message for players that aren't found • Fixed Chat prefixes not being in the language file * Fixed Chat Prefixes • Fixed chat prefixes from not generating in language.yml file • Added Nonbender prefix * Fixed Waterbending Bugs • Fixes waterbending getting a super far away source when selecting under water • Water from Bottlebending now shows bubbles when under water * Fixed WaterWave & WaterManip Bugs • Fixed WaterManipulation disappearing when the player taps shift • Fixed being able to use current WaterManips as sources for other WaterManips • Fixed WaterWave being able to use more sources while spinning around the player * OfflinePlayer lookup fix + IceWave DeathMessage • Fixed IceWave not having a death message • Fixed /b who not working on offline players * Fixed bad english ;-; * Changes + Fixes • Added Properties.TogglePassivesWithAllBending config option (whether passives should be toggled when bending is toggled globally) • Changed chat prefixes • Re-enabled WarriorStance • Fixed IceBlast being removed when pressing shift • Fixed IceWave and IceBullet from having the wrong colored death messages • Fixed not being able to select ice and plants as sources for WaterManip • Fixed help command showing hidden abilities (WaterReturn, etc) • Fixed WaterManip turning ice sources to air
2016-06-19 16:41:18 +00:00
if (!(isWater(sourceBlock.getType()) || (isIce(sourceBlock) && bPlayer.canIcebend()) || (isSnow(sourceBlock) && bPlayer.canIcebend()) || (isPlant(sourceBlock) && bPlayer.canPlantbend()))) {
remove();
return;
}
sourceBlock.getWorld().playEffect(location, Effect.SMOKE, 4, (int) selectRange);
2016-01-13 21:14:34 +00:00
return;
}
2016-01-13 21:14:34 +00:00
if (sourceBlock.getLocation().distanceSquared(firstDestination) < 0.5 * 0.5) {
settingUp = false;
}
Vector direction;
2016-01-13 21:14:34 +00:00
if (settingUp) {
direction = firstDirection;
} else {
2016-01-13 21:14:34 +00:00
direction = targetDirection;
}
Block block = location.getBlock();
if (displacing) {
2016-01-13 21:14:34 +00:00
Block targetBlock = player.getTargetBlock((HashSet<Material>) null, dispelRange);
direction = GeneralMethods.getDirection(location, targetBlock.getLocation()).normalize();
if (!location.getBlock().equals(targetBlock.getLocation())) {
location = location.clone().add(direction);
block = location.getBlock();
2016-01-13 21:14:34 +00:00
if (block.getLocation().equals(sourceBlock.getLocation())) {
location = location.clone().add(direction);
block = location.getBlock();
}
}
} else {
2016-01-13 21:14:34 +00:00
if ((new Random()).nextInt(4) == 0) {
playWaterbendingSound(location);
}
location = location.clone().add(direction);
block = location.getBlock();
2016-01-13 21:14:34 +00:00
if (block.getLocation().equals(sourceBlock.getLocation())) {
location = location.clone().add(direction);
block = location.getBlock();
}
}
if (trail2 != null) {
if (!TempBlock.isTempBlock(block) && (trail2.getBlock().equals(block))) {
trail2.revertBlock();
trail2 = null;
}
}
if (trail != null) {
if (!TempBlock.isTempBlock(block) && trail.getBlock().equals(block)) {
trail.revertBlock();
trail = null;
if (trail2 != null) {
trail2.revertBlock();
trail2 = null;
}
}
}
2016-01-15 01:07:59 +00:00
if (isTransparent(player, block) && !block.isLiquid()) {
GeneralMethods.breakBlock(block);
2016-01-13 21:14:34 +00:00
} else if (block.getType() != Material.AIR && !isWater(block)) {
remove();
new WaterReturn(player, sourceBlock);
return;
}
if (!displacing) {
2016-01-16 21:07:14 +00:00
for (Entity entity : GeneralMethods.getEntitiesAroundPoint(location, collisionRadius)) {
if (entity instanceof LivingEntity && entity.getEntityId() != player.getEntityId()) {
Location location = player.getEyeLocation();
Vector vector = location.getDirection();
2016-01-13 21:14:34 +00:00
entity.setVelocity(vector.normalize().multiply(pushFactor));
2016-01-13 21:14:34 +00:00
if (bPlayer.isAvatarState()) {
damage = getConfig().getDouble("Abilities.Avatar.AvatarState.Water.WaterManipulation.Damage");
2016-01-13 21:14:34 +00:00
}
damage = getNightFactor(damage);
DamageHandler.damageEntity(entity, damage, this);
2016-01-13 21:14:34 +00:00
AirAbility.breakBreathbendingHold(entity);
progressing = false;
}
}
}
if (!progressing) {
2016-01-13 21:14:34 +00:00
remove();
new WaterReturn(player, sourceBlock);
return;
}
addWater(block);
2016-01-13 21:14:34 +00:00
reduceWater(sourceBlock);
if (trail2 != null) {
trail2.revertBlock();
trail2 = null;
}
if (trail != null) {
trail2 = trail;
trail2.setType(Material.STATIONARY_WATER, (byte) 2);
}
2016-01-13 21:14:34 +00:00
trail = new TempBlock(sourceBlock, Material.STATIONARY_WATER, (byte) 1);
sourceBlock = block;
2017-01-16 06:48:20 +00:00
if (location.distanceSquared(targetDestination) <= 1 || location.distanceSquared(firstDestination) > range * range) {
falling = true;
progressing = false;
}
}
}
}
2016-01-13 21:14:34 +00:00
private void redirect(Player player, Location targetlocation) {
if (progressing && !settingUp) {
if (location.distanceSquared(player.getLocation()) <= range * range) {
2016-01-13 21:14:34 +00:00
targetDirection = GeneralMethods.getDirection(location, targetlocation).normalize();
}
targetDestination = targetlocation;
this.setPlayer(player);
2016-01-13 21:14:34 +00:00
}
}
private void reduceWater(Block block) {
if (displacing) {
removeWater(block);
return;
}
2016-01-13 21:14:34 +00:00
if (AFFECTED_BLOCKS.containsKey(block)) {
if (!GeneralMethods.isAdjacentToThreeOrMoreSources(block)) {
block.setType(Material.AIR);
}
2016-01-13 21:14:34 +00:00
AFFECTED_BLOCKS.remove(block);
}
}
private void removeWater(Block block) {
if (block != null) {
2016-01-13 21:14:34 +00:00
if (AFFECTED_BLOCKS.containsKey(block)) {
if (!GeneralMethods.isAdjacentToThreeOrMoreSources(block)) {
block.setType(Material.AIR);
}
2016-01-13 21:14:34 +00:00
AFFECTED_BLOCKS.remove(block);
}
}
}
2016-01-13 21:14:34 +00:00
private static void addWater(Block block) {
if (!isWater(block)) {
if (!AFFECTED_BLOCKS.containsKey(block)) {
AFFECTED_BLOCKS.put(block, block);
}
PhaseChange recode and EarthGrab fix (#661) * Fix metalclips - Removed a check that was preventing metalclips from progressing past 1 clip on a target. * Fix metalclips - Fixed a bug limiting the metal clip count to one * Improve MetalClips - Fixed bug where shooting at a block spawned two clips - Added ShootCooldown and CrushCooldown - ShootCooldown only applies to shooting clips - Changed how crushing works: --- Removed old style and variables --- When controlling an entity with 4 clips, the controller can click to cause the armor to "crush" and damage the entity. --- Has own cooldown, default of 2000 (2 seconds) - Changed launching --- Works with all clip amounts except 4 --- When the user releases sneak, the entity will be launched at varying power depending on how many clips were attached. - Changed ability cooldown to activate only after the ability is finished. * Add CrushDamage option to MetalClips * New Damage Type, MetalClips changes - Fixed MetalClips bug caused in magnetizing - Added ignoreArmor option to damageEntity method, default true for most abilities. If wanted to be changed, someone needs to go through and add false as a parameter - Changed default config option for MetalClips description * PhaseChange recode * Chris wanted changes * Chris doesn't want bugs * Only you can prevent bugs - Added checks for worlds to prevent errors * Remove unnecessary auto generated comments * Loony didn't like the passive * Added RegionProtection checks * PhaseChange * Revert "PhaseChange" This reverts commit 761c73f5756771674719ffca52413cffa09243a8. * Revert "Added RegionProtection checks" This reverts commit b53a02a74d0276d4d1e773e1c197666cbcfab624. * Revert "Loony didn't like the passive" This reverts commit 6612bb7fa8eea3e26c01d0ef761c658447779e03. * Revert "Remove unnecessary auto generated comments" This reverts commit da9c45106d0b7e256c278e6a84d15f7a7340a140. * Revert "Only you can prevent bugs" This reverts commit 630161659ea89bfb106924c8ab1fbcdb8f6f1310. * Revert "Chris doesn't want bugs" This reverts commit eda2dee6b52dd38c73f35680c5e4484adc5b5b91. * Revert "Chris wanted changes" This reverts commit 30b76c10c4adc63784ea7115eb4f9c636650d6c5. * Revert "PhaseChange recode" This reverts commit f8f290dd8c57a3467a87de7e43b58ce635196c62. * Conflicts * Stupid conflicts * I hope and pray * Revert "Revert "Chris wanted changes"" This reverts commit e612607c8a16a735c92014714c00aa671954b4a5. * Revert "Revert "Chris doesn't want bugs"" This reverts commit bd656b814d7ffa2d9c84fa304d3adb8f1535f782. * Revert "Revert "Only you can prevent bugs"" This reverts commit 7772c95737130cf414ff1af49dcfb48865be5374. * Revert "Revert "Remove unnecessary auto generated comments"" This reverts commit 69315dc7baa6cd237fbd89394e544913596ec6e3. * Revert "Revert "Loony didn't like the passive"" This reverts commit ea397c6323e50d219395d5912850513afd6f2a7b. * Revert "Revert "Added RegionProtection checks"" This reverts commit 8cb41709f65e4322e68b2f0e1792987f7fc214f2. * Revert "Revert "PhaseChange"" This reverts commit da6b0e7071acf74df6447b15daf4ae6e39f057f6. * Working PhaseChange finally * Fix EarthGrab * Air fixes, PhaseChange changes
2016-12-20 04:43:56 +00:00
if (PhaseChange.getFrozenBlocksAsBlock().contains(block)) {
PhaseChange.getFrozenBlocksAsBlock().remove(block);
}
2017-01-16 06:48:20 +00:00
new TempBlock(block, Material.WATER, (byte) 0);
} else {
if (isWater(block) && !AFFECTED_BLOCKS.containsKey(block)) {
2017-01-16 06:48:20 +00:00
ParticleEffect.WATER_BUBBLE.display((float) Math.random(), (float) Math.random(), (float) Math.random(), 0f, 5, block.getLocation().clone().add(.5, .5, .5), 255.0);
}
}
2016-01-13 21:14:34 +00:00
}
/**
* This method was used for the old collision detection system. Please see
* {@link Collision} for the new system.
*/
@Deprecated
2016-01-13 21:14:34 +00:00
public static boolean annihilateBlasts(Location location, double radius, Player player) {
boolean broke = false;
2016-01-16 21:07:14 +00:00
for (WaterManipulation manip : getAbilities(WaterManipulation.class)) {
Various fixes * Lots of Fixes • Added 1.9 and 1.10 particle effects • Fixed Particle Effect version from being wrong • Fixed {ability} not being replaced when trying to bind non-existent move • Fixed permremoving command not sending a message to the executor • Fixed remove command sending user 2 remove messages if they removed their own bending • Fixed who command not replacing {target} in message for players that aren't found • Fixed Chat prefixes not being in the language file * Fixed Chat Prefixes • Fixed chat prefixes from not generating in language.yml file • Added Nonbender prefix * Fixed Waterbending Bugs • Fixes waterbending getting a super far away source when selecting under water • Water from Bottlebending now shows bubbles when under water * Fixed WaterWave & WaterManip Bugs • Fixed WaterManipulation disappearing when the player taps shift • Fixed being able to use current WaterManips as sources for other WaterManips • Fixed WaterWave being able to use more sources while spinning around the player * OfflinePlayer lookup fix + IceWave DeathMessage • Fixed IceWave not having a death message • Fixed /b who not working on offline players * Fixed bad english ;-; * Changes + Fixes • Added Properties.TogglePassivesWithAllBending config option (whether passives should be toggled when bending is toggled globally) • Changed chat prefixes • Re-enabled WarriorStance • Fixed IceBlast being removed when pressing shift • Fixed IceWave and IceBullet from having the wrong colored death messages • Fixed not being able to select ice and plants as sources for WaterManip • Fixed help command showing hidden abilities (WaterReturn, etc) • Fixed WaterManip turning ice sources to air
2016-06-19 16:41:18 +00:00
if (manip.location.getWorld().equals(location.getWorld()) && !player.equals(manip.player) && manip.progressing) {
2016-01-13 21:14:34 +00:00
if (manip.location.distanceSquared(location) <= radius * radius) {
manip.remove();
broke = true;
}
}
}
2016-01-13 21:14:34 +00:00
return broke;
}
2017-01-16 06:48:20 +00:00
/** Blocks other water manips */
public static void block(Player player) {
Various fixes * Lots of Fixes • Added 1.9 and 1.10 particle effects • Fixed Particle Effect version from being wrong • Fixed {ability} not being replaced when trying to bind non-existent move • Fixed permremoving command not sending a message to the executor • Fixed remove command sending user 2 remove messages if they removed their own bending • Fixed who command not replacing {target} in message for players that aren't found • Fixed Chat prefixes not being in the language file * Fixed Chat Prefixes • Fixed chat prefixes from not generating in language.yml file • Added Nonbender prefix * Fixed Waterbending Bugs • Fixes waterbending getting a super far away source when selecting under water • Water from Bottlebending now shows bubbles when under water * Fixed WaterWave & WaterManip Bugs • Fixed WaterManipulation disappearing when the player taps shift • Fixed being able to use current WaterManips as sources for other WaterManips • Fixed WaterWave being able to use more sources while spinning around the player * OfflinePlayer lookup fix + IceWave DeathMessage • Fixed IceWave not having a death message • Fixed /b who not working on offline players * Fixed bad english ;-; * Changes + Fixes • Added Properties.TogglePassivesWithAllBending config option (whether passives should be toggled when bending is toggled globally) • Changed chat prefixes • Re-enabled WarriorStance • Fixed IceBlast being removed when pressing shift • Fixed IceWave and IceBullet from having the wrong colored death messages • Fixed not being able to select ice and plants as sources for WaterManip • Fixed help command showing hidden abilities (WaterReturn, etc) • Fixed WaterManip turning ice sources to air
2016-06-19 16:41:18 +00:00
for (WaterManipulation manip : getAbilities(WaterManipulation.class)) {
2016-01-13 21:14:34 +00:00
if (!manip.location.getWorld().equals(player.getWorld())) {
continue;
} else if (!manip.progressing) {
continue;
Various fixes * Lots of Fixes • Added 1.9 and 1.10 particle effects • Fixed Particle Effect version from being wrong • Fixed {ability} not being replaced when trying to bind non-existent move • Fixed permremoving command not sending a message to the executor • Fixed remove command sending user 2 remove messages if they removed their own bending • Fixed who command not replacing {target} in message for players that aren't found • Fixed Chat prefixes not being in the language file * Fixed Chat Prefixes • Fixed chat prefixes from not generating in language.yml file • Added Nonbender prefix * Fixed Waterbending Bugs • Fixes waterbending getting a super far away source when selecting under water • Water from Bottlebending now shows bubbles when under water * Fixed WaterWave & WaterManip Bugs • Fixed WaterManipulation disappearing when the player taps shift • Fixed being able to use current WaterManips as sources for other WaterManips • Fixed WaterWave being able to use more sources while spinning around the player * OfflinePlayer lookup fix + IceWave DeathMessage • Fixed IceWave not having a death message • Fixed /b who not working on offline players * Fixed bad english ;-; * Changes + Fixes • Added Properties.TogglePassivesWithAllBending config option (whether passives should be toggled when bending is toggled globally) • Changed chat prefixes • Re-enabled WarriorStance • Fixed IceBlast being removed when pressing shift • Fixed IceWave and IceBullet from having the wrong colored death messages • Fixed not being able to select ice and plants as sources for WaterManip • Fixed help command showing hidden abilities (WaterReturn, etc) • Fixed WaterManip turning ice sources to air
2016-06-19 16:41:18 +00:00
} else if (manip.getPlayer().equals(player)) {
continue;
2016-01-13 21:14:34 +00:00
} else if (GeneralMethods.isRegionProtectedFromBuild(manip, manip.location)) {
continue;
}
Location location = player.getEyeLocation();
Vector vector = location.getDirection();
Location mloc = manip.location;
2017-01-16 06:48:20 +00:00
if (mloc.distanceSquared(location) <= manip.selectRange * manip.selectRange && GeneralMethods.getDistanceFromLine(vector, location, manip.location) < manip.deflectRange && mloc.distanceSquared(location.clone().add(vector)) < mloc.distanceSquared(location.clone().add(vector.clone().multiply(-1)))) {
2016-01-13 21:14:34 +00:00
manip.remove();
}
}
2016-01-13 21:14:34 +00:00
}
public static boolean canBubbleWater(Block block) {
return canPhysicsChange(block);
}
public static boolean canFlowFromTo(Block from, Block to) {
if (AFFECTED_BLOCKS.containsKey(to) || AFFECTED_BLOCKS.containsKey(from)) {
return false;
} else if (WaterSpout.getAffectedBlocks().containsKey(to) || WaterSpout.getAffectedBlocks().containsKey(from)) {
return false;
} else if (SurgeWall.getAffectedBlocks().containsKey(to) || SurgeWall.getAffectedBlocks().containsKey(from)) {
return false;
} else if (SurgeWall.getWallBlocks().containsKey(to) || SurgeWall.getWallBlocks().containsKey(from)) {
return false;
} else if (SurgeWave.isBlockWave(to) || SurgeWave.isBlockWave(from)) {
return false;
} else if (isAdjacentToFrozenBlock(to) || isAdjacentToFrozenBlock(from)) {
return false;
}
2016-01-13 21:14:34 +00:00
return true;
}
public static boolean canPhysicsChange(Block block) {
if (AFFECTED_BLOCKS.containsKey(block)) {
return false;
} else if (WaterSpout.getAffectedBlocks().containsKey(block)) {
return false;
} else if (SurgeWall.getAffectedBlocks().containsKey(block)) {
return false;
} else if (SurgeWall.getWallBlocks().containsKey(block)) {
return false;
} else if (SurgeWave.isBlockWave(block)) {
return false;
} else if (TempBlock.isTempBlock(block) && !WaterAbility.isBendableWaterTempBlock(block)) {
2016-01-13 21:14:34 +00:00
return false;
}
return true;
}
private static Location getTargetLocation(Player player, double range) {
Location location;
Entity target = GeneralMethods.getTargetedEntity(player, range);
2016-01-13 21:14:34 +00:00
if (target == null) {
1.8.6 (#825) ## Fixes * Fixed Combos and possibly Passives appearing in `/pk b <Ability>` auto-tabbing. * Fixed Combos not loading properly on certain servers. * Fixed issue with `PreciousStones` by updating to the latest version to resolve API change issues. * Fixed `RapidPunch` damage. * Fixed incorrect summation of chiblocking chance. * Fixed possible issue in PKListener#onPlayerInteraction() * Fixed `Earth.LavaSound`. * Fixed Chi attempting to chiblock targets with any move. * Fixed hitting an entity with `TempArmor` not ignoring armor. * Fixed `Immobilize` config path. ## Additions * Added "Contributing" section to the `README` to help guide active community members. * Added more detail to the `PULL_REQUEST_TEMPLATE` to allow for more uniform pull requests. * Added many new blocks to our ability block interaction. * Added check to combo collisions to discard dead entities. * Added functionality to allow chiblocking abilities to affect all entities. * Added exception handling to the configurable `Sound` options to prevent `IllegalArgumentExcpetions`. * Added sounds and `ActionBar` messages to being Bloodbent, Electrocuted, Immobilized, MetalClipped, and Paralyzed. (Abilities: `Bloodbending`, `Lightning`, `Immobilize`, `MetalClips`, and `Paralyze`) * Added sound and `ActionBar` message for being Chiblocked. * Added interval config option to `RapidPunch`. (time between each punch) ## API Changes * Updated to `Spigot 1.12.1`. * Confirmed to be backward compatible with `Spigot 1.12` and `Spigot 1.11.2`. * Renamed `ElementalAbility#getTransparentMaterial()` to `ElementalAbility#getTransparentMaterials()`. * Converted most `byte`/`int` dependent `Material` logic to use `Material` instead. * `ElementalAbility#getTransparentMaterialSet()` now returns a `HashSet<Material>` instead of a `HashSet<Byte>`. * `ElementalAbility#getTransparentMaterials()` and `GeneralMethods.NON_OPAQUE` now return `Material[]` instead of `Integer[]`. * `GeneralMethods#getTargetedLocation()` now takes a `varargs Material[]` instead of a `varargs Integer[]`. * Removed `ElementalAbility.TRANSPARENT_MATERIAL`. It was outdated and became irrelevent after `GeneralMethods.NON_OPAQUE` was updated. * Removed `Java 7` Travi-CI JDK check. * Updated `pom.xml` to build in `Java 8`. * Added new `MovementHandler` utility class to control entity movement. (currently only capable of stopping movement.
2017-08-06 07:18:12 +00:00
location = GeneralMethods.getTargetedLocation(player, range, getTransparentMaterials());
2016-01-13 21:14:34 +00:00
} else {
location = ((LivingEntity) target).getEyeLocation();
}
return location;
}
public static void moveWater(Player player) {
2016-01-13 21:14:34 +00:00
BendingPlayer bPlayer = BendingPlayer.getBendingPlayer(player);
if (bPlayer == null) {
return;
}
if (bPlayer.isOnCooldown("WaterManipulation")) {
2016-01-13 21:14:34 +00:00
redirectTargettedBlasts(player);
return;
}
boolean handledPrepare = false;
double range = 25;
2016-01-16 21:07:14 +00:00
for (WaterManipulation waterManip : getAbilities(player, WaterManipulation.class)) {
range = waterManip.range;
2016-01-13 21:14:34 +00:00
if (waterManip.prepared) {
waterManip.prepared = false;
handledPrepare = true;
waterManip.moveWater();
}
2016-01-13 21:14:34 +00:00
}
2016-01-13 21:14:34 +00:00
if (!handledPrepare && WaterReturn.hasWaterBottle(player)) {
Location eyeLoc = player.getEyeLocation();
Block block = eyeLoc.add(eyeLoc.getDirection().normalize()).getBlock();
if (!AFFECTED_BLOCKS.containsKey(block)) {
AFFECTED_BLOCKS.put(block, block);
}
2016-01-15 01:07:59 +00:00
if (isTransparent(player, block) && isTransparent(player, eyeLoc.getBlock())) {
2016-01-13 21:14:34 +00:00
if (getTargetLocation(player, range).distanceSquared(block.getLocation()) > 1) {
2017-01-16 06:48:20 +00:00
TempBlock tb = new TempBlock(block, Material.WATER, (byte) 0);
2016-01-13 21:14:34 +00:00
WaterManipulation waterManip = new WaterManipulation(player);
waterManip.moveWater();
if (!waterManip.progressing) {
block.setType(Material.AIR);
tb.revertBlock();
} else {
WaterReturn.emptyWaterBottle(player);
tb.revertBlock();
}
}
}
}
redirectTargettedBlasts(player);
}
private static void redirectTargettedBlasts(Player player) {
2016-01-16 21:07:14 +00:00
for (WaterManipulation manip : getAbilities(WaterManipulation.class)) {
2016-01-13 21:14:34 +00:00
if (!manip.progressing) {
continue;
2016-01-13 21:14:34 +00:00
} else if (!manip.location.getWorld().equals(player.getWorld())) {
continue;
2016-01-13 21:14:34 +00:00
} else if (GeneralMethods.isRegionProtectedFromBuild(player, "WaterManipulation", manip.location)) {
continue;
2016-01-13 21:14:34 +00:00
}
2016-01-13 21:14:34 +00:00
if (manip.player.equals(player)) {
manip.redirect(player, getTargetLocation(player, manip.range));
2016-01-13 21:14:34 +00:00
}
Location location = player.getEyeLocation();
Vector vector = location.getDirection();
Location mloc = manip.location;
2017-01-16 06:48:20 +00:00
if (mloc.distanceSquared(location) <= manip.selectRange * manip.selectRange && GeneralMethods.getDistanceFromLine(vector, location, manip.location) < manip.deflectRange && mloc.distanceSquared(location.clone().add(vector)) < mloc.distanceSquared(location.clone().add(vector.clone().multiply(-1)))) {
manip.redirect(player, getTargetLocation(player, manip.selectRange));
}
2016-01-13 21:14:34 +00:00
}
}
2016-01-13 21:14:34 +00:00
@Override
public void remove() {
super.remove();
finalRemoveWater(sourceBlock);
}
public static void removeAroundPoint(Location location, double radius) {
2016-01-16 21:07:14 +00:00
for (WaterManipulation manip : getAbilities(WaterManipulation.class)) {
2016-01-13 21:14:34 +00:00
if (manip.location.getWorld().equals(location.getWorld())) {
if (manip.location.distanceSquared(location) <= radius * radius) {
manip.remove();
}
}
}
}
2016-01-13 21:14:34 +00:00
@Override
public String getName() {
return "WaterManipulation";
}
2016-01-13 21:14:34 +00:00
@Override
public Location getLocation() {
if (location != null) {
return location;
} else if (sourceBlock != null) {
return sourceBlock.getLocation();
}
return null;
}
2016-01-13 21:14:34 +00:00
@Override
public long getCooldown() {
return cooldown;
}
2016-01-13 21:14:34 +00:00
@Override
public boolean isSneakAbility() {
return true;
}
2016-01-13 21:14:34 +00:00
@Override
public boolean isHarmlessAbility() {
return false;
}
2017-01-16 06:48:20 +00:00
@Override
public boolean isCollidable() {
return progressing;
}
2017-01-16 06:48:20 +00:00
@Override
public double getCollisionRadius() {
return collisionRadius;
}
2017-01-16 06:48:20 +00:00
@Override
public void handleCollision(Collision collision) {
super.handleCollision(collision);
if (collision.isRemovingFirst()) {
new WaterReturn(player, sourceBlock);
}
}
2016-01-13 21:14:34 +00:00
public boolean isProgressing() {
return progressing;
}
2016-01-13 21:14:34 +00:00
public void setProgressing(boolean progressing) {
this.progressing = progressing;
}
2016-01-13 21:14:34 +00:00
public boolean isFalling() {
return falling;
}
2016-01-13 21:14:34 +00:00
public void setFalling(boolean falling) {
this.falling = falling;
}
2016-01-13 21:14:34 +00:00
public boolean isSettingUp() {
return settingUp;
}
2016-01-13 21:14:34 +00:00
public void setSettingUp(boolean settingUp) {
this.settingUp = settingUp;
}
2016-01-13 21:14:34 +00:00
public boolean isDisplacing() {
return displacing;
}
2016-01-13 21:14:34 +00:00
public void setDisplacing(boolean displacing) {
this.displacing = displacing;
}
2016-01-13 21:14:34 +00:00
public boolean isPrepared() {
return prepared;
}
2016-01-13 21:14:34 +00:00
public void setPrepared(boolean prepared) {
this.prepared = prepared;
}
2016-01-13 21:14:34 +00:00
public int getDispelRange() {
return dispelRange;
}
2016-01-13 21:14:34 +00:00
public void setDispelRange(int dispelRange) {
this.dispelRange = dispelRange;
}
2016-01-13 21:14:34 +00:00
public long getTime() {
return time;
}
2016-01-13 21:14:34 +00:00
public void setTime(long time) {
this.time = time;
}
2016-01-13 21:14:34 +00:00
public long getInterval() {
return interval;
}
public void setInterval(long interval) {
this.interval = interval;
}
public double getRange() {
return range;
}
public void setRange(double range) {
this.range = range;
}
public double getSelectRange() {
return selectRange;
}
public void setSelectRange(double selectRange) {
this.selectRange = selectRange;
}
2016-01-13 21:14:34 +00:00
public double getPushFactor() {
return pushFactor;
}
2016-01-13 21:14:34 +00:00
public void setPushFactor(double pushFactor) {
this.pushFactor = pushFactor;
}
2016-01-13 21:14:34 +00:00
public double getDamage() {
return damage;
}
public void setDamage(double damage) {
this.damage = damage;
}
public double getSpeed() {
return speed;
}
public void setSpeed(double speed) {
this.speed = speed;
}
public double getDeflectRange() {
return deflectRange;
}
public void setDeflectRange(double deflectRange) {
this.deflectRange = deflectRange;
}
public Block getSourceBlock() {
return sourceBlock;
}
public void setSourceBlock(Block sourceBlock) {
this.sourceBlock = sourceBlock;
}
public TempBlock getTrail() {
return trail;
}
public void setTrail(TempBlock trail) {
this.trail = trail;
}
public TempBlock getTrail2() {
return trail2;
}
public void setTrail2(TempBlock trail2) {
this.trail2 = trail2;
}
public Location getFirstDestination() {
return firstDestination;
}
public void setFirstDestination(Location firstDestination) {
this.firstDestination = firstDestination;
}
public Location getTargetDestination() {
return targetDestination;
}
public void setTargetDestination(Location targetDestination) {
this.targetDestination = targetDestination;
}
public Vector getFirstDirection() {
return firstDirection;
}
public void setFirstDirection(Vector firstDirection) {
this.firstDirection = firstDirection;
}
public Vector getTargetDirection() {
return targetDirection;
}
public void setTargetDirection(Vector targetDirection) {
this.targetDirection = targetDirection;
}
public static Map<Block, Block> getAffectedBlocks() {
2016-01-13 21:14:34 +00:00
return AFFECTED_BLOCKS;
}
public HashSet<Byte> getWaterTypes() {
return waterTypes;
}
public void setCooldown(long cooldown) {
this.cooldown = cooldown;
}
2016-01-13 21:14:34 +00:00
public void setLocation(Location location) {
this.location = location;
}
2016-01-16 21:07:14 +00:00
public void setCollisionRadius(double collisionRadius) {
this.collisionRadius = collisionRadius;
}
2016-01-13 21:14:34 +00:00
}