mirror of
https://github.com/TotalFreedomMC/TF-ProjectKorra.git
synced 2025-02-21 23:54:34 +00:00
295 lines
No EOL
7.2 KiB
Java
295 lines
No EOL
7.2 KiB
Java
package com.projectkorra.ProjectKorra.earthbending;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
|
import org.bukkit.Location;
|
|
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.Methods;
|
|
|
|
public class Ripple {
|
|
|
|
private static ConcurrentHashMap<Integer, Ripple> instances = new ConcurrentHashMap<Integer, Ripple>();
|
|
private static ConcurrentHashMap<Integer[], Block> blocks = new ConcurrentHashMap<Integer[], Block>();
|
|
|
|
static final double radius = 15;
|
|
private static final int damage = 5;
|
|
|
|
private static int ID = Integer.MIN_VALUE;
|
|
|
|
private Player player;
|
|
private Vector direction;
|
|
private Location origin, location;
|
|
|
|
private ArrayList<Location> locations = new ArrayList<Location>();
|
|
private ArrayList<Entity> entities = new ArrayList<Entity>();
|
|
|
|
private Block block1, block2, block3, block4;
|
|
private int id;
|
|
private int step = 0;
|
|
private int maxstep;
|
|
|
|
public Ripple(Player player, Vector direction) {
|
|
this(player, getInitialLocation(player, direction), direction);
|
|
}
|
|
|
|
public Ripple(Player player, Location origin, Vector direction) {
|
|
this.player = player;
|
|
if (origin == null)
|
|
return;
|
|
this.direction = direction.clone().normalize();
|
|
this.origin = origin.clone();
|
|
this.location = origin.clone();
|
|
|
|
initializeLocations();
|
|
maxstep = locations.size();
|
|
|
|
if (Methods.isEarthbendable(player, origin.getBlock())) {
|
|
id = ID++;
|
|
if (ID >= Integer.MAX_VALUE)
|
|
ID = Integer.MIN_VALUE;
|
|
instances.put(id, this);
|
|
}
|
|
|
|
}
|
|
|
|
private static Location getInitialLocation(Player player, Vector direction) {
|
|
Location location = player.getLocation().clone().add(0, -1, 0);
|
|
direction = direction.normalize();
|
|
|
|
Block block1 = location.getBlock();
|
|
|
|
while (location.getBlock().equals(block1))
|
|
location = location.clone().add(direction);
|
|
for (int i : new int[] { 1, 2, 3, 0, -1 }) {
|
|
Location loc;
|
|
loc = location.clone().add(0, i, 0);
|
|
Block topblock = loc.getBlock();
|
|
Block botblock = loc.clone().add(0, -1, 0).getBlock();
|
|
if (Methods.isTransparentToEarthbending(player, topblock)
|
|
&& Methods.isEarthbendable(player, botblock)) {
|
|
location = loc.clone().add(0, -1, 0);
|
|
return location;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private void progress() {
|
|
|
|
if (step < maxstep) {
|
|
Location newlocation = locations.get(step);
|
|
Block block = location.getBlock();
|
|
location = newlocation.clone();
|
|
if (!newlocation.getBlock().equals(block)) {
|
|
// if (block2 != null)
|
|
// block1 = block2;
|
|
// if (block3 != null)
|
|
// block2 = block3;
|
|
// if (block4 != null)
|
|
// block3 = block4;
|
|
block1 = block2;
|
|
block2 = block3;
|
|
block3 = block4;
|
|
block4 = newlocation.getBlock();
|
|
|
|
if (block1 != null)
|
|
if (hasAnyMoved(block1)) {
|
|
block1 = null;
|
|
}
|
|
if (block2 != null)
|
|
if (hasAnyMoved(block2)) {
|
|
block2 = null;
|
|
}
|
|
if (block3 != null)
|
|
if (hasAnyMoved(block3)) {
|
|
block3 = null;
|
|
}
|
|
if (block4 != null)
|
|
if (hasAnyMoved(block4)) {
|
|
block4 = null;
|
|
}
|
|
|
|
if (step == 0) {
|
|
|
|
if (increase(block4))
|
|
block4 = block4.getRelative(BlockFace.UP);
|
|
|
|
} else if (step == 1) {
|
|
|
|
if (increase(block3))
|
|
block3 = block3.getRelative(BlockFace.UP);
|
|
if (increase(block4))
|
|
block4 = block4.getRelative(BlockFace.UP);
|
|
|
|
} else if (step == 2) {
|
|
|
|
if (decrease(block2))
|
|
block2 = block2.getRelative(BlockFace.DOWN);
|
|
if (increase(block3))
|
|
block3 = block3.getRelative(BlockFace.UP);
|
|
if (increase(block4))
|
|
block4 = block4.getRelative(BlockFace.UP);
|
|
|
|
} else {
|
|
|
|
if (decrease(block1))
|
|
block1 = block1.getRelative(BlockFace.DOWN);
|
|
if (decrease(block2))
|
|
block2 = block2.getRelative(BlockFace.DOWN);
|
|
if (increase(block3))
|
|
block3 = block3.getRelative(BlockFace.UP);
|
|
if (increase(block4))
|
|
block4 = block4.getRelative(BlockFace.UP);
|
|
|
|
}
|
|
}
|
|
} else if (step == maxstep) {
|
|
|
|
if (decrease(block2))
|
|
block2 = block2.getRelative(BlockFace.DOWN);
|
|
if (decrease(block3))
|
|
block3 = block3.getRelative(BlockFace.DOWN);
|
|
if (increase(block4))
|
|
block4 = block4.getRelative(BlockFace.UP);
|
|
|
|
} else if (step == maxstep + 1) {
|
|
|
|
if (decrease(block3))
|
|
block3 = block3.getRelative(BlockFace.DOWN);
|
|
if (decrease(block4))
|
|
block4 = block4.getRelative(BlockFace.DOWN);
|
|
|
|
} else if (step == maxstep + 2) {
|
|
|
|
if (decrease(block4))
|
|
block4 = block4.getRelative(BlockFace.DOWN);
|
|
remove();
|
|
|
|
}
|
|
|
|
step += 1;
|
|
|
|
for (Entity entity : entities)
|
|
affect(entity);
|
|
entities.clear();
|
|
|
|
}
|
|
|
|
private void remove() {
|
|
instances.remove(id);
|
|
}
|
|
|
|
private void initializeLocations() {
|
|
Location location = origin.clone();
|
|
locations.add(location);
|
|
|
|
while (location.distance(origin) < radius) {
|
|
location = location.clone().add(direction);
|
|
for (int i : new int[] { 1, 2, 3, 0, -1 }) {
|
|
Location loc;
|
|
loc = location.clone().add(0, i, 0);
|
|
Block topblock = loc.getBlock();
|
|
Block botblock = loc.clone().add(0, -1, 0).getBlock();
|
|
if (Methods.isTransparentToEarthbending(player, topblock)
|
|
&& !topblock.isLiquid()
|
|
&& Methods.isEarthbendable(player, botblock)) {
|
|
location = loc.clone().add(0, -1, 0);
|
|
locations.add(location);
|
|
break;
|
|
} else if (i == -1) {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private boolean decrease(Block block) {
|
|
if (block == null)
|
|
return false;
|
|
if (hasAnyMoved(block))
|
|
return false;
|
|
setMoved(block);
|
|
Block botblock = block.getRelative(BlockFace.DOWN);
|
|
int length = 1;
|
|
if (Methods.isEarthbendable(player, botblock)) {
|
|
length = 2;
|
|
block = botblock;
|
|
}
|
|
return Methods.moveEarth(player, block, new Vector(0, -1, 0), length,
|
|
false);
|
|
}
|
|
|
|
private boolean increase(Block block) {
|
|
if (block == null)
|
|
return false;
|
|
if (hasAnyMoved(block))
|
|
return false;
|
|
setMoved(block);
|
|
Block botblock = block.getRelative(BlockFace.DOWN);
|
|
int length = 1;
|
|
if (Methods.isEarthbendable(player, botblock)) {
|
|
length = 2;
|
|
}
|
|
if (Methods.moveEarth(player, block, new Vector(0, 1, 0), length, false)) {
|
|
for (Entity entity : Methods.getEntitiesAroundPoint(block
|
|
.getLocation().clone().add(0, 1, 0), 2)) {
|
|
if (entity.getEntityId() != player.getEntityId()
|
|
&& !entities.contains(entity)) {
|
|
if (!(entity instanceof FallingBlock))
|
|
entities.add(entity);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private void affect(Entity entity) {
|
|
|
|
if (entity instanceof LivingEntity) {
|
|
Methods.damageEntity(player, entity, damage);
|
|
}
|
|
|
|
Vector vector = direction.clone();
|
|
vector.setY(.5);
|
|
entity.setVelocity(vector);
|
|
|
|
}
|
|
|
|
private static void setMoved(Block block) {
|
|
int x = block.getX();
|
|
int z = block.getZ();
|
|
Integer[] pair = new Integer[] { x, z };
|
|
blocks.put(pair, block);
|
|
}
|
|
|
|
private static boolean hasAnyMoved(Block block) {
|
|
int x = block.getX();
|
|
int z = block.getZ();
|
|
Integer[] pair = new Integer[] { x, z };
|
|
if (blocks.containsKey(pair))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
public static void progressAll() {
|
|
blocks.clear();
|
|
for (int id : instances.keySet())
|
|
instances.get(id).progress();
|
|
}
|
|
|
|
public static void removeAll() {
|
|
instances.clear();
|
|
|
|
}
|
|
|
|
} |