Citizens2/v1_16_R3/src/main/java/net/citizensnpcs/nms/v1_16_R3/entity/nonliving/FallingBlockController.java

178 lines
6.4 KiB
Java

package net.citizensnpcs.nms.v1_16_R3.entity.nonliving;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_16_R3.CraftServer;
import org.bukkit.craftbukkit.v1_16_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftFallingBlock;
import org.bukkit.craftbukkit.v1_16_R3.util.CraftMagicNumbers;
import org.bukkit.entity.Entity;
import org.bukkit.entity.FallingBlock;
import org.bukkit.util.Vector;
import net.citizensnpcs.api.event.DespawnReason;
import net.citizensnpcs.api.event.NPCPushEvent;
import net.citizensnpcs.api.event.SpawnReason;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.nms.v1_16_R3.util.NMSImpl;
import net.citizensnpcs.npc.AbstractEntityController;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.npc.ai.NPCHolder;
import net.citizensnpcs.util.Util;
import net.minecraft.server.v1_16_R3.Block;
import net.minecraft.server.v1_16_R3.Blocks;
import net.minecraft.server.v1_16_R3.EntityFallingBlock;
import net.minecraft.server.v1_16_R3.EntityTypes;
import net.minecraft.server.v1_16_R3.EnumMoveType;
import net.minecraft.server.v1_16_R3.IBlockData;
import net.minecraft.server.v1_16_R3.NBTTagCompound;
import net.minecraft.server.v1_16_R3.Vec3D;
import net.minecraft.server.v1_16_R3.World;
import net.minecraft.server.v1_16_R3.WorldServer;
public class FallingBlockController extends AbstractEntityController {
public FallingBlockController() {
super(EntityFallingBlockNPC.class);
}
@Override
protected Entity createEntity(Location at, NPC npc) {
WorldServer ws = ((CraftWorld) at.getWorld()).getHandle();
Block id = Blocks.STONE;
int data = npc.data().get(NPC.ITEM_DATA_METADATA, npc.data().get("falling-block-data", 0));
// TODO: how to incorporate this - probably delete?
if (npc.data().has("falling-block-id") || npc.data().has(NPC.ITEM_ID_METADATA)) {
id = CraftMagicNumbers.getBlock(Material.getMaterial(
npc.data().<String> get(NPC.ITEM_ID_METADATA, npc.data().<String> get("falling-block-id"))));
}
final EntityFallingBlockNPC handle = new EntityFallingBlockNPC(ws, npc, at.getX(), at.getY(), at.getZ(),
id.getBlockData());
return handle.getBukkitEntity();
}
@Override
public FallingBlock getBukkitEntity() {
return (FallingBlock) super.getBukkitEntity();
}
public static class EntityFallingBlockNPC extends EntityFallingBlock implements NPCHolder {
private final CitizensNPC npc;
public EntityFallingBlockNPC(EntityTypes<? extends EntityFallingBlock> types, World world) {
this(types, world, null);
}
public EntityFallingBlockNPC(EntityTypes<? extends EntityFallingBlock> types, World world, NPC npc) {
super(types, world);
this.npc = (CitizensNPC) npc;
}
public EntityFallingBlockNPC(World world, NPC npc, double d0, double d1, double d2, IBlockData data) {
super(world, d0, d1, d2, data);
this.npc = (CitizensNPC) npc;
}
@Override
public void collide(net.minecraft.server.v1_16_R3.Entity entity) {
// this method is called by both the entities involved - cancelling
// it will not stop the NPC from moving.
super.collide(entity);
if (npc != null) {
Util.callCollisionEvent(npc, entity.getBukkitEntity());
}
}
@Override
public boolean d(NBTTagCompound save) {
return npc == null ? super.d(save) : false;
}
@Override
public void i(double x, double y, double z) {
if (npc == null) {
super.i(x, y, z);
return;
}
if (NPCPushEvent.getHandlerList().getRegisteredListeners().length == 0) {
if (!npc.data().get(NPC.DEFAULT_PROTECTED_METADATA, true))
super.i(x, y, z);
return;
}
Vector vector = new Vector(x, y, z);
NPCPushEvent event = Util.callPushEvent(npc, vector);
if (!event.isCancelled()) {
vector = event.getCollisionVector();
super.i(vector.getX(), vector.getY(), vector.getZ());
}
// when another entity collides, this method is called to push the
// NPC so we prevent it from doing anything if the event is
// cancelled.
}
@Override
public CraftEntity getBukkitEntity() {
if (npc != null && !(super.getBukkitEntity() instanceof NPCHolder)) {
NMSImpl.setBukkitEntity(this, new FallingBlockNPC(this));
}
return super.getBukkitEntity();
}
@Override
public NPC getNPC() {
return npc;
}
@Override
public void tick() {
if (npc != null) {
npc.update();
Vec3D mot = getMot();
if (Math.abs(mot.getX()) > EPSILON || Math.abs(mot.getY()) > EPSILON
|| Math.abs(mot.getZ()) > EPSILON) {
mot = mot.d(0.98, 0.98, 0.98);
setMot(mot);
move(EnumMoveType.SELF, mot);
}
} else {
super.tick();
}
}
@Override
public void updateSize() {
if (npc == null) {
super.updateSize();
} else {
NMSImpl.setSize(this, justCreated);
}
}
private static final double EPSILON = 0.001;
}
public static class FallingBlockNPC extends CraftFallingBlock implements NPCHolder {
private final CitizensNPC npc;
public FallingBlockNPC(EntityFallingBlockNPC entity) {
super((CraftServer) Bukkit.getServer(), entity);
this.npc = entity.npc;
}
@Override
public NPC getNPC() {
return npc;
}
public void setType(Material material, int data) {
npc.data().setPersistent(NPC.ITEM_ID_METADATA, material.name());
npc.data().setPersistent(NPC.ITEM_DATA_METADATA, data);
if (npc.isSpawned()) {
npc.despawn(DespawnReason.PENDING_RESPAWN);
npc.spawn(npc.getStoredLocation(), SpawnReason.RESPAWN);
}
}
}
}