mirror of
https://github.com/TotalFreedomMC/TF-ProjectKorra.git
synced 2024-05-15 17:31:26 +00:00
0b35fb9fda
Created a cancellable event that will fire whenever a bending move would alter the velocity of an entity. ## Additions * Adds 1. > The AbilityVelocityAffectEntityEvent > Adds a new method to GeneralMethods -> setEntityVelocity() > Updates existing setVelocity() calls to use the new method in general methods. > checks to see if anything in the event should be modified or if it should be cancelled. ## Fixes * Fixes 2 > The lack of a way to detect when a bending move pushed a player.
472 lines
13 KiB
Java
472 lines
13 KiB
Java
package com.projectkorra.projectkorra.earthbending.lava;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.ListIterator;
|
|
import java.util.Map;
|
|
import java.util.Random;
|
|
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.FallingBlock;
|
|
import org.bukkit.entity.LivingEntity;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.util.Vector;
|
|
|
|
import com.projectkorra.projectkorra.GeneralMethods;
|
|
import com.projectkorra.projectkorra.ability.ElementalAbility;
|
|
import com.projectkorra.projectkorra.ability.LavaAbility;
|
|
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;
|
|
|
|
public class LavaSurge extends LavaAbility {
|
|
|
|
private static final HashSet<FallingBlock> ALL_FALLING_BLOCKS = new HashSet<>();
|
|
|
|
private boolean hasSurgeStarted;
|
|
private boolean isFractureOpen;
|
|
private boolean canSourceBeEarth;
|
|
private int fallingBlocksCount;
|
|
private int maxBlocks;
|
|
private int particleInterval;
|
|
private int fallingBlockInterval;
|
|
private long time;
|
|
private long lastTime;
|
|
private long cooldown;
|
|
private double impactDamage;
|
|
private double fractureRadius;
|
|
private double prepareRange;
|
|
private double travelRange;
|
|
private Block sourceBlock;
|
|
private Random random;
|
|
private Vector direction;
|
|
private Location startLocation;
|
|
private ArrayList<FallingBlock> fallingBlocks;
|
|
private ArrayList<Block> fracture;
|
|
private ArrayList<TempBlock> fractureTempBlocks;
|
|
private ArrayList<TempBlock> movingLava;
|
|
private Map<FallingBlock, TempBlock> lavaBlocks;
|
|
private ListIterator<Block> listIterator;
|
|
|
|
public LavaSurge(final Player player) {
|
|
super(player);
|
|
|
|
this.impactDamage = getConfig().getInt("Abilities.Earth.LavaSurge.Damage");
|
|
this.cooldown = getConfig().getLong("Abilities.Earth.LavaSurge.Cooldown");
|
|
this.fractureRadius = getConfig().getDouble("Abilities.Earth.LavaSurge.FractureRadius");
|
|
this.prepareRange = getConfig().getInt("Abilities.Earth.LavaSurge.PrepareRange");
|
|
this.travelRange = getConfig().getInt("Abilities.Earth.LavaSurge.TravelRange");
|
|
this.maxBlocks = getConfig().getInt("Abilities.Earth.LavaSurge.MaxLavaWaves");
|
|
this.canSourceBeEarth = getConfig().getBoolean("Abilities.Earth.LavaSurge.SourceCanBeEarth");
|
|
this.particleInterval = 100;
|
|
this.fallingBlockInterval = 100;
|
|
|
|
this.random = new Random();
|
|
this.fallingBlocks = new ArrayList<>();
|
|
this.fracture = new ArrayList<>();
|
|
this.fractureTempBlocks = new ArrayList<>();
|
|
this.movingLava = new ArrayList<>();
|
|
this.lavaBlocks = new ConcurrentHashMap<>();
|
|
|
|
if (!this.isEligible()) {
|
|
return;
|
|
} else if (this.bPlayer.isOnCooldown(this)) {
|
|
return;
|
|
}
|
|
|
|
this.lastTime = System.currentTimeMillis();
|
|
|
|
if (this.prepare()) {
|
|
this.start();
|
|
}
|
|
}
|
|
|
|
public boolean isEligible() {
|
|
return this.bPlayer.canBend(this) && this.bPlayer.canLavabend();
|
|
}
|
|
|
|
public boolean prepare() {
|
|
final Block targetBlock = BlockSource.getEarthSourceBlock(this.player, this.prepareRange, ClickType.SHIFT_DOWN);
|
|
|
|
if (targetBlock == null || !(ElementalAbility.isAir(targetBlock.getRelative(BlockFace.UP).getType())) && !isLava(targetBlock.getRelative(BlockFace.UP))) {
|
|
return false;
|
|
}
|
|
|
|
final LavaSurge otherSurge = getAbility(this.player, this.getClass());
|
|
if (otherSurge != null) {
|
|
otherSurge.revertFracture();
|
|
}
|
|
|
|
if ((this.canSourceBeEarth && this.isEarthbendable(targetBlock)) || this.isLavabendable(targetBlock)) {
|
|
this.startLocation = targetBlock.getLocation().add(0, 1, 0);
|
|
this.sourceBlock = targetBlock;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public void launch() {
|
|
Location targetLocation = GeneralMethods.getTargetedLocation(this.player, this.travelRange * 2);
|
|
|
|
try {
|
|
targetLocation = GeneralMethods.getTargetedEntity(this.player, this.travelRange * 2, null).getLocation();
|
|
} catch (final NullPointerException e) {}
|
|
|
|
if (targetLocation == null) {
|
|
this.remove();
|
|
return;
|
|
}
|
|
|
|
this.time = System.currentTimeMillis();
|
|
this.direction = GeneralMethods.getDirection(this.startLocation, targetLocation).multiply(0.07);
|
|
|
|
if (this.direction.getY() < 0) {
|
|
this.direction.setY(0);
|
|
}
|
|
|
|
if (this.canSourceBeEarth) {
|
|
this.openFracture();
|
|
} else {
|
|
this.skipFracture();
|
|
}
|
|
}
|
|
|
|
public void openFracture() {
|
|
final List<Block> affectedBlocks = GeneralMethods.getBlocksAroundPoint(this.sourceBlock.getLocation(), this.fractureRadius);
|
|
|
|
for (final Block b : affectedBlocks) {
|
|
if (this.isEarthbendable(b)) {
|
|
this.fracture.add(b);
|
|
}
|
|
}
|
|
|
|
this.listIterator = this.fracture.listIterator();
|
|
this.isFractureOpen = true;
|
|
this.bPlayer.addCooldown(this);
|
|
}
|
|
|
|
public void skipFracture() {
|
|
this.listIterator = this.fracture.listIterator();
|
|
this.isFractureOpen = true;
|
|
}
|
|
|
|
public void revertFracture() {
|
|
for (final TempBlock tb : this.fractureTempBlocks) {
|
|
tb.revertBlock();
|
|
}
|
|
this.fracture.clear();
|
|
}
|
|
|
|
@Override
|
|
public void remove() {
|
|
super.remove();
|
|
this.revertFracture();
|
|
}
|
|
|
|
public boolean canMoveThrough(final Block block) {
|
|
if (this.isTransparent(this.startLocation.getBlock()) || this.isEarthbendable(this.startLocation.getBlock()) || this.isLavabendable(this.startLocation.getBlock())) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public void removeLava() {
|
|
for (final TempBlock tb : this.lavaBlocks.values()) {
|
|
tb.revertBlock();
|
|
}
|
|
this.movingLava.clear();
|
|
}
|
|
|
|
@Override
|
|
public void progress() {
|
|
final long curTime = System.currentTimeMillis();
|
|
if (!this.player.isOnline() || this.player.isDead()) {
|
|
this.remove();
|
|
return;
|
|
} else if (!this.hasSurgeStarted && !this.bPlayer.getBoundAbilityName().equals(this.getName())) {
|
|
this.remove();
|
|
return;
|
|
}
|
|
|
|
if (!this.hasSurgeStarted && this.sourceBlock != null && curTime > this.lastTime + this.particleInterval) {
|
|
this.lastTime = curTime;
|
|
ParticleEffect.LAVA.display(this.sourceBlock.getLocation(), 0, 0, 0, 0, 1);
|
|
} else if (this.hasSurgeStarted && curTime > this.lastTime + this.particleInterval) {
|
|
this.lastTime = curTime;
|
|
for (final FallingBlock fblock : this.fallingBlocks) {
|
|
ParticleEffect.LAVA.display(fblock.getLocation(), 0, 0, 0, 0, 1);
|
|
}
|
|
}
|
|
|
|
if (this.isFractureOpen && !this.hasSurgeStarted) {
|
|
if (!this.listIterator.hasNext()) {
|
|
this.hasSurgeStarted = true;
|
|
} else {
|
|
final Block b = this.listIterator.next();
|
|
playEarthbendingSound(b.getLocation());
|
|
|
|
for (int i = 0; i < 2; i++) {
|
|
final TempBlock tb = new TempBlock(b, Material.LAVA);
|
|
this.fractureTempBlocks.add(tb);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (this.hasSurgeStarted) {
|
|
if (this.fallingBlocksCount >= this.maxBlocks) {
|
|
return;
|
|
}
|
|
|
|
if (curTime > this.time + (this.fallingBlockInterval * this.fallingBlocksCount)) {
|
|
final FallingBlock fbs = GeneralMethods.spawnFallingBlock(this.sourceBlock.getLocation().add(0, 1, 0), Material.MAGMA_BLOCK, Material.MAGMA_BLOCK.createBlockData());
|
|
this.fallingBlocks.add(fbs);
|
|
ALL_FALLING_BLOCKS.add(fbs);
|
|
double x = this.random.nextDouble() / 5;
|
|
double z = this.random.nextDouble() / 5;
|
|
|
|
x = (this.random.nextBoolean()) ? -x : x;
|
|
z = (this.random.nextBoolean()) ? -z : z;
|
|
|
|
GeneralMethods.setVelocity(this, fbs, this.direction.clone().add(new Vector(x, 0.2, z)).multiply(1.2));
|
|
fbs.setDropItem(false);
|
|
|
|
for (final Block b : this.fracture) {
|
|
if (this.random.nextBoolean() && b != this.sourceBlock) {
|
|
final FallingBlock fb = GeneralMethods.spawnFallingBlock(b.getLocation().add(new Vector(0, 1, 0)), Material.MAGMA_BLOCK, Material.MAGMA_BLOCK.createBlockData());
|
|
ALL_FALLING_BLOCKS.add(fb);
|
|
this.fallingBlocks.add(fb);
|
|
GeneralMethods.setVelocity(this, fb, this.direction.clone().add(new Vector(this.random.nextDouble() / 10, 0.1, this.random.nextDouble() / 10)).multiply(1.2));
|
|
fb.setDropItem(false);
|
|
}
|
|
}
|
|
|
|
this.fallingBlocksCount++;
|
|
}
|
|
|
|
for (final FallingBlock fb : this.fallingBlocks) {
|
|
for (final Entity e : GeneralMethods.getEntitiesAroundPoint(fb.getLocation(), 2)) {
|
|
if (e instanceof LivingEntity) {
|
|
if (e.getEntityId() != this.player.getEntityId()) {
|
|
DamageHandler.damageEntity(e, this.impactDamage, this);
|
|
e.setFireTicks(100);
|
|
GeneralMethods.setVelocity(this, e, this.direction.clone());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public String getName() {
|
|
return "LavaSurge";
|
|
}
|
|
|
|
@Override
|
|
public Location getLocation() {
|
|
return this.startLocation;
|
|
}
|
|
|
|
@Override
|
|
public long getCooldown() {
|
|
return this.cooldown;
|
|
}
|
|
|
|
@Override
|
|
public boolean isSneakAbility() {
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean isHarmlessAbility() {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean isHiddenAbility() {
|
|
return true; // disabled
|
|
}
|
|
|
|
public static HashSet<FallingBlock> getAllFallingBlocks() {
|
|
return ALL_FALLING_BLOCKS;
|
|
}
|
|
|
|
public boolean isHasSurgeStarted() {
|
|
return this.hasSurgeStarted;
|
|
}
|
|
|
|
public void setHasSurgeStarted(final boolean hasSurgeStarted) {
|
|
this.hasSurgeStarted = hasSurgeStarted;
|
|
}
|
|
|
|
public boolean isFractureOpen() {
|
|
return this.isFractureOpen;
|
|
}
|
|
|
|
public void setFractureOpen(final boolean isFractureOpen) {
|
|
this.isFractureOpen = isFractureOpen;
|
|
}
|
|
|
|
public boolean isCanSourceBeEarth() {
|
|
return this.canSourceBeEarth;
|
|
}
|
|
|
|
public void setCanSourceBeEarth(final boolean canSourceBeEarth) {
|
|
this.canSourceBeEarth = canSourceBeEarth;
|
|
}
|
|
|
|
public int getFallingBlocksCount() {
|
|
return this.fallingBlocksCount;
|
|
}
|
|
|
|
public void setFallingBlocksCount(final int fallingBlocksCount) {
|
|
this.fallingBlocksCount = fallingBlocksCount;
|
|
}
|
|
|
|
public int getMaxBlocks() {
|
|
return this.maxBlocks;
|
|
}
|
|
|
|
public void setMaxBlocks(final int maxBlocks) {
|
|
this.maxBlocks = maxBlocks;
|
|
}
|
|
|
|
public int getParticleInterval() {
|
|
return this.particleInterval;
|
|
}
|
|
|
|
public void setParticleInterval(final int particleInterval) {
|
|
this.particleInterval = particleInterval;
|
|
}
|
|
|
|
public int getFallingBlockInterval() {
|
|
return this.fallingBlockInterval;
|
|
}
|
|
|
|
public void setFallingBlockInterval(final int fallingBlockInterval) {
|
|
this.fallingBlockInterval = fallingBlockInterval;
|
|
}
|
|
|
|
public long getTime() {
|
|
return this.time;
|
|
}
|
|
|
|
public void setTime(final long time) {
|
|
this.time = time;
|
|
}
|
|
|
|
public long getLastTime() {
|
|
return this.lastTime;
|
|
}
|
|
|
|
public void setLastTime(final long lastTime) {
|
|
this.lastTime = lastTime;
|
|
}
|
|
|
|
public double getImpactDamage() {
|
|
return this.impactDamage;
|
|
}
|
|
|
|
public void setImpactDamage(final double impactDamage) {
|
|
this.impactDamage = impactDamage;
|
|
}
|
|
|
|
public double getFractureRadius() {
|
|
return this.fractureRadius;
|
|
}
|
|
|
|
public void setFractureRadius(final double fractureRadius) {
|
|
this.fractureRadius = fractureRadius;
|
|
}
|
|
|
|
public double getPrepareRange() {
|
|
return this.prepareRange;
|
|
}
|
|
|
|
public void setPrepareRange(final double prepareRange) {
|
|
this.prepareRange = prepareRange;
|
|
}
|
|
|
|
public double getTravelRange() {
|
|
return this.travelRange;
|
|
}
|
|
|
|
public void setTravelRange(final double travelRange) {
|
|
this.travelRange = travelRange;
|
|
}
|
|
|
|
public Block getSourceBlock() {
|
|
return this.sourceBlock;
|
|
}
|
|
|
|
public void setSourceBlock(final Block sourceBlock) {
|
|
this.sourceBlock = sourceBlock;
|
|
}
|
|
|
|
public Random getRandom() {
|
|
return this.random;
|
|
}
|
|
|
|
public void setRandom(final Random random) {
|
|
this.random = random;
|
|
}
|
|
|
|
public Vector getDirection() {
|
|
return this.direction;
|
|
}
|
|
|
|
public void setDirection(final Vector direction) {
|
|
this.direction = direction;
|
|
}
|
|
|
|
public Location getStartLocation() {
|
|
return this.startLocation;
|
|
}
|
|
|
|
public void setStartLocation(final Location startLocation) {
|
|
this.startLocation = startLocation;
|
|
}
|
|
|
|
public ListIterator<Block> getListIterator() {
|
|
return this.listIterator;
|
|
}
|
|
|
|
public void setListIterator(final ListIterator<Block> listIterator) {
|
|
this.listIterator = listIterator;
|
|
}
|
|
|
|
public ArrayList<FallingBlock> getFallingBlocks() {
|
|
return this.fallingBlocks;
|
|
}
|
|
|
|
public ArrayList<Block> getFracture() {
|
|
return this.fracture;
|
|
}
|
|
|
|
public ArrayList<TempBlock> getFractureTempBlocks() {
|
|
return this.fractureTempBlocks;
|
|
}
|
|
|
|
public ArrayList<TempBlock> getMovingLava() {
|
|
return this.movingLava;
|
|
}
|
|
|
|
public Map<FallingBlock, TempBlock> getLavaBlocks() {
|
|
return this.lavaBlocks;
|
|
}
|
|
|
|
public void setCooldown(final long cooldown) {
|
|
this.cooldown = cooldown;
|
|
}
|
|
|
|
}
|