mirror of
https://github.com/IntellectualSites/PlotSquared.git
synced 2024-11-26 15:16:45 +01:00
Entity cloning (TODO leashes)
This commit is contained in:
parent
bbf92bfa38
commit
7ab299d22d
@ -0,0 +1,9 @@
|
||||
package com.intellectualcrafters.plot.object.entity;
|
||||
|
||||
public class AgeableStats {
|
||||
|
||||
public int age;
|
||||
public boolean locked;
|
||||
public boolean adult;
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.intellectualcrafters.plot.object.entity;
|
||||
|
||||
public class EntityBaseStats {
|
||||
public EntityWrapper passenger;
|
||||
public float fall;
|
||||
public short fire;
|
||||
public int age;
|
||||
public double v_z;
|
||||
public double v_y;
|
||||
public double v_x;
|
||||
}
|
@ -0,0 +1,591 @@
|
||||
package com.intellectualcrafters.plot.object.entity;
|
||||
|
||||
import org.bukkit.Art;
|
||||
import org.bukkit.DyeColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Rotation;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.Ageable;
|
||||
import org.bukkit.entity.ArmorStand;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Guardian;
|
||||
import org.bukkit.entity.Horse;
|
||||
import org.bukkit.entity.Horse.Color;
|
||||
import org.bukkit.entity.Horse.Style;
|
||||
import org.bukkit.entity.Horse.Variant;
|
||||
import org.bukkit.entity.Rabbit.Type;
|
||||
import org.bukkit.entity.Skeleton.SkeletonType;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.entity.ItemFrame;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Painting;
|
||||
import org.bukkit.entity.Rabbit;
|
||||
import org.bukkit.entity.Sheep;
|
||||
import org.bukkit.entity.Skeleton;
|
||||
import org.bukkit.entity.Tameable;
|
||||
import org.bukkit.inventory.EntityEquipment;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import com.intellectualcrafters.plot.PlotMain;
|
||||
|
||||
public class EntityWrapper {
|
||||
|
||||
public short id;
|
||||
public float yaw;
|
||||
public float pitch;
|
||||
public double x;
|
||||
public double y;
|
||||
public double z;
|
||||
|
||||
public short depth;
|
||||
|
||||
public EntityBaseStats base = null;
|
||||
|
||||
// Extended
|
||||
public ItemStack stack;
|
||||
public ItemStack[] inventory;
|
||||
public byte dataByte;
|
||||
public byte dataByte2;
|
||||
public String dataString;
|
||||
|
||||
|
||||
public LivingEntityStats lived;
|
||||
|
||||
public AgeableStats aged;
|
||||
|
||||
public TameableStats tamed;
|
||||
private HorseStats horse;
|
||||
|
||||
public void storeInventory(final InventoryHolder held) {
|
||||
this.inventory = held.getInventory().getContents().clone();
|
||||
}
|
||||
|
||||
private void restoreLiving(final LivingEntity entity) {
|
||||
if (this.lived.loot) {
|
||||
entity.setCanPickupItems(this.lived.loot);
|
||||
}
|
||||
if (this.lived.name != null) {
|
||||
entity.setCustomName(this.lived.name);
|
||||
entity.setCustomNameVisible(this.lived.visible);
|
||||
}
|
||||
entity.setRemainingAir(this.lived.air);
|
||||
entity.setRemoveWhenFarAway(this.lived.persistent);
|
||||
|
||||
if (lived.equipped) {
|
||||
EntityEquipment equipment = entity.getEquipment();
|
||||
equipment.setItemInHand(this.lived.hands);
|
||||
equipment.setHelmet(this.lived.helmet);
|
||||
equipment.setChestplate(this.lived.chestplate);
|
||||
equipment.setLeggings(this.lived.leggings);
|
||||
equipment.setBoots(this.lived.boots);
|
||||
}
|
||||
|
||||
if (lived.leashed) {
|
||||
// TODO leashes
|
||||
// World world = entity.getWorld();
|
||||
// Entity leash = world.spawnEntity(new Location(world, Math.floor(x) + lived.leash_x, Math.floor(y) + lived.leash_y, Math.floor(z) + lived.leash_z), EntityType.LEASH_HITCH);
|
||||
// entity.setLeashHolder(leash);
|
||||
}
|
||||
}
|
||||
|
||||
private void restoreInventory(final InventoryHolder entity) {
|
||||
entity.getInventory().setContents(this.inventory);
|
||||
}
|
||||
|
||||
public void storeLiving(final LivingEntity lived) {
|
||||
this.lived = new LivingEntityStats();
|
||||
this.lived.loot = lived.getCanPickupItems();
|
||||
this.lived.name = lived.getCustomName();
|
||||
this.lived.visible = lived.isCustomNameVisible();
|
||||
this.lived.health = (float) lived.getHealth();
|
||||
this.lived.air = (short) lived.getRemainingAir();
|
||||
this.lived.persistent = lived.getRemoveWhenFarAway();
|
||||
|
||||
this.lived.leashed = lived.isLeashed();
|
||||
|
||||
if (this.lived.leashed) {
|
||||
final Location loc = lived.getLeashHolder().getLocation();
|
||||
this.lived.leash_x = (short) (this.x - loc.getBlockX());
|
||||
this.lived.leash_y = (short) (this.y - loc.getBlockY());
|
||||
this.lived.leash_z = (short) (this.z - loc.getBlockZ());
|
||||
}
|
||||
|
||||
final EntityEquipment equipment = lived.getEquipment();
|
||||
this.lived.equipped = equipment != null;
|
||||
if (this.lived.equipped) {
|
||||
this.lived.hands = equipment.getItemInHand().clone();
|
||||
this.lived.boots = equipment.getBoots().clone();
|
||||
this.lived.leggings = equipment.getLeggings().clone();
|
||||
this.lived.chestplate = equipment.getChestplate().clone();
|
||||
this.lived.helmet = equipment.getHelmet().clone();
|
||||
}
|
||||
}
|
||||
|
||||
private void restoreTameable(final Tameable entity) {
|
||||
if (this.tamed.tamed) {
|
||||
if (this.tamed.owner != null) {
|
||||
entity.setTamed(true);
|
||||
entity.setOwner(this.tamed.owner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void restoreAgeable(final Ageable entity) {
|
||||
if (!this.aged.adult) {
|
||||
entity.setBaby();
|
||||
}
|
||||
if (this.aged.locked) {
|
||||
entity.setAgeLock(this.aged.locked);
|
||||
}
|
||||
entity.setAge(this.aged.age);
|
||||
}
|
||||
|
||||
public void storeAgeable(final Ageable aged) {
|
||||
this.aged = new AgeableStats();
|
||||
this.aged.age = aged.getAge();
|
||||
this.aged.locked = aged.getAgeLock();
|
||||
this.aged.adult = aged.isAdult();
|
||||
}
|
||||
|
||||
public void storeTameable(final Tameable tamed) {
|
||||
this.tamed = new TameableStats();
|
||||
this.tamed.owner = tamed.getOwner();
|
||||
this.tamed.tamed = tamed.isTamed();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public EntityWrapper(final org.bukkit.entity.Entity entity, final short depth) {
|
||||
this.depth = depth;
|
||||
final Location loc = entity.getLocation();
|
||||
this.yaw = loc.getYaw();
|
||||
this.pitch = loc.getPitch();
|
||||
this.x = loc.getX();
|
||||
this.y = loc.getY();
|
||||
this.z = loc.getZ();
|
||||
this.id = entity.getType().getTypeId();
|
||||
|
||||
if (depth == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.base = new EntityBaseStats();
|
||||
final Entity p = entity.getPassenger();
|
||||
if (p != null) {
|
||||
this.base.passenger = new EntityWrapper(p, depth);
|
||||
}
|
||||
this.base.fall = entity.getFallDistance();
|
||||
this.base.fire = (short) entity.getFireTicks();
|
||||
this.base.age = entity.getTicksLived();
|
||||
final Vector velocity = entity.getVelocity();
|
||||
this.base.v_x = velocity.getX();
|
||||
this.base.v_y = velocity.getY();
|
||||
this.base.v_z = velocity.getZ();
|
||||
|
||||
if (depth == 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (entity.getType()) {
|
||||
case ARROW:
|
||||
case BOAT:
|
||||
case COMPLEX_PART:
|
||||
case EGG:
|
||||
case ENDER_CRYSTAL:
|
||||
case ENDER_PEARL:
|
||||
case ENDER_SIGNAL:
|
||||
case EXPERIENCE_ORB:
|
||||
case FALLING_BLOCK:
|
||||
case FIREBALL:
|
||||
case FIREWORK:
|
||||
case FISHING_HOOK:
|
||||
case LEASH_HITCH:
|
||||
case LIGHTNING:
|
||||
case MINECART:
|
||||
case MINECART_COMMAND:
|
||||
case MINECART_MOB_SPAWNER:
|
||||
case MINECART_TNT:
|
||||
case PLAYER:
|
||||
case PRIMED_TNT:
|
||||
case SLIME:
|
||||
case SMALL_FIREBALL:
|
||||
case SNOWBALL:
|
||||
case MINECART_FURNACE:
|
||||
case SPLASH_POTION:
|
||||
case THROWN_EXP_BOTTLE:
|
||||
case WEATHER:
|
||||
case WITHER_SKULL:
|
||||
case UNKNOWN: {
|
||||
// Do this stuff later
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
PlotMain.sendConsoleSenderMessage("&cCOULD NOT IDENTIFY ENTITY: " + entity.getType());
|
||||
return;
|
||||
}
|
||||
|
||||
// MISC //
|
||||
case DROPPED_ITEM: {
|
||||
final Item item = (Item) entity;
|
||||
this.stack = item.getItemStack();
|
||||
return;
|
||||
}
|
||||
case ITEM_FRAME: {
|
||||
final ItemFrame itemframe = (ItemFrame) entity;
|
||||
this.x = Math.floor(this.x);
|
||||
this.y = Math.floor(this.y);
|
||||
this.z = Math.floor(this.z);
|
||||
this.dataByte = getOrdinal(Rotation.values(), itemframe.getRotation());
|
||||
this.stack = itemframe.getItem().clone();
|
||||
return;
|
||||
}
|
||||
case PAINTING: {
|
||||
final Painting painting = (Painting) entity;
|
||||
this.x = Math.floor(this.x);
|
||||
this.y = Math.floor(this.y);
|
||||
this.z = Math.floor(this.z);
|
||||
final Art a = painting.getArt();
|
||||
this.dataByte = getOrdinal(BlockFace.values(), painting.getFacing());
|
||||
int h = a.getBlockHeight();
|
||||
if (h % 2 == 0) {
|
||||
y -= 1;
|
||||
}
|
||||
this.dataString = a.name();
|
||||
return;
|
||||
}
|
||||
// END MISC //
|
||||
|
||||
// INVENTORY HOLDER //
|
||||
case MINECART_CHEST: {
|
||||
storeInventory((InventoryHolder) entity);
|
||||
return;
|
||||
}
|
||||
case MINECART_HOPPER: {
|
||||
storeInventory((InventoryHolder) entity);
|
||||
return;
|
||||
}
|
||||
|
||||
// START LIVING ENTITY //
|
||||
// START AGEABLE //
|
||||
// START TAMEABLE //
|
||||
case HORSE: {
|
||||
final Horse horse = (Horse) entity;
|
||||
this.horse = new HorseStats();
|
||||
this.horse.jump = horse.getJumpStrength();
|
||||
this.horse.chest = horse.isCarryingChest();
|
||||
this.horse.variant = getOrdinal(Variant.values(), horse.getVariant());
|
||||
this.horse.style = getOrdinal(Style.values(), horse.getStyle());
|
||||
this.horse.color = getOrdinal(Color.values(), horse.getColor());
|
||||
storeTameable((Tameable) entity);
|
||||
storeAgeable((Ageable) entity);
|
||||
storeLiving((LivingEntity) entity);
|
||||
storeInventory((InventoryHolder) entity);
|
||||
return;
|
||||
}
|
||||
// END INVENTORY HOLDER //
|
||||
case WOLF:
|
||||
case OCELOT: {
|
||||
storeTameable((Tameable) entity);
|
||||
storeAgeable((Ageable) entity);
|
||||
storeLiving((LivingEntity) entity);
|
||||
return;
|
||||
}
|
||||
// END AMEABLE //
|
||||
|
||||
case SHEEP: {
|
||||
final Sheep sheep = (Sheep) entity;
|
||||
this.dataByte = (byte) ((sheep).isSheared() ? 1 : 0);
|
||||
this.dataByte2 = sheep.getColor().getDyeData();
|
||||
storeAgeable((Ageable) entity);
|
||||
storeLiving((LivingEntity) entity);
|
||||
return;
|
||||
}
|
||||
|
||||
case VILLAGER:
|
||||
case CHICKEN:
|
||||
case COW:
|
||||
case MUSHROOM_COW:
|
||||
case PIG: {
|
||||
storeAgeable((Ageable) entity);
|
||||
storeLiving((LivingEntity) entity);
|
||||
return;
|
||||
}
|
||||
// END AGEABLE //
|
||||
case RABBIT: { // NEW
|
||||
this.dataByte = getOrdinal(Type.values(), ((Rabbit) entity).getRabbitType());
|
||||
storeAgeable((Ageable) entity);
|
||||
storeLiving((LivingEntity) entity);
|
||||
return;
|
||||
}
|
||||
case GUARDIAN: { // NEW
|
||||
this.dataByte = (byte) (((Guardian) entity).isElder() ? 1 : 0);
|
||||
storeLiving((LivingEntity) entity);
|
||||
return;
|
||||
}
|
||||
|
||||
case SKELETON: { // NEW
|
||||
this.dataByte = (byte) ((Skeleton) entity).getSkeletonType().getId();
|
||||
storeLiving((LivingEntity) entity);
|
||||
return;
|
||||
}
|
||||
|
||||
case ARMOR_STAND: { // NEW
|
||||
// CHECK positions
|
||||
final ArmorStand stand = (ArmorStand) entity;
|
||||
this.inventory = new ItemStack[] { stand.getItemInHand().clone(), stand.getHelmet().clone(), stand.getChestplate().clone(), stand.getLeggings().clone(), stand.getBoots().clone() };
|
||||
storeLiving((LivingEntity) entity);
|
||||
return;
|
||||
}
|
||||
|
||||
case ENDERMITE: // NEW
|
||||
case BAT:
|
||||
case ENDER_DRAGON:
|
||||
case GHAST:
|
||||
case MAGMA_CUBE:
|
||||
case SQUID:
|
||||
case PIG_ZOMBIE:
|
||||
case ZOMBIE:
|
||||
case WITHER:
|
||||
case WITCH:
|
||||
case SPIDER:
|
||||
case CAVE_SPIDER:
|
||||
case SILVERFISH:
|
||||
case GIANT:
|
||||
case ENDERMAN:
|
||||
case CREEPER:
|
||||
case BLAZE:
|
||||
case SNOWMAN:
|
||||
case IRON_GOLEM: {
|
||||
storeLiving((LivingEntity) entity);
|
||||
return;
|
||||
}
|
||||
// END LIVING //
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public Entity spawn(final World world, final int x_offset, final int z_offset) {
|
||||
final Location loc = new Location(world, this.x + x_offset, this.y, this.z + z_offset);
|
||||
loc.setYaw(this.yaw);
|
||||
loc.setPitch(this.pitch);
|
||||
EntityType type = EntityType.fromId(this.id);
|
||||
if (type == EntityType.DROPPED_ITEM) {
|
||||
return world.dropItem(loc, this.stack);
|
||||
}
|
||||
if (type == EntityType.LEASH_HITCH) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Entity entity = world.spawnEntity(loc, type);
|
||||
if (this.depth == 0) {
|
||||
return entity;
|
||||
}
|
||||
if (this.base.passenger != null) {
|
||||
try {
|
||||
entity.setPassenger(this.base.passenger.spawn(world, x_offset, z_offset));
|
||||
} catch (final Exception e) {
|
||||
}
|
||||
}
|
||||
entity.setFallDistance(this.base.fall);
|
||||
entity.setFireTicks(this.base.fire);
|
||||
entity.setTicksLived(this.base.age);
|
||||
entity.setVelocity(new Vector(this.base.v_x, this.base.v_y, this.base.v_z));
|
||||
if (this.depth == 1) {
|
||||
return entity;
|
||||
}
|
||||
switch (entity.getType()) {
|
||||
case ARROW:
|
||||
case BOAT:
|
||||
case COMPLEX_PART:
|
||||
case EGG:
|
||||
case ENDER_CRYSTAL:
|
||||
case ENDER_PEARL:
|
||||
case ENDER_SIGNAL:
|
||||
case EXPERIENCE_ORB:
|
||||
case FALLING_BLOCK:
|
||||
case FIREBALL:
|
||||
case FIREWORK:
|
||||
case FISHING_HOOK:
|
||||
case LEASH_HITCH:
|
||||
case LIGHTNING:
|
||||
case MINECART:
|
||||
case MINECART_COMMAND:
|
||||
case MINECART_MOB_SPAWNER:
|
||||
case MINECART_TNT:
|
||||
case PLAYER:
|
||||
case PRIMED_TNT:
|
||||
case SLIME:
|
||||
case SMALL_FIREBALL:
|
||||
case SNOWBALL:
|
||||
case SPLASH_POTION:
|
||||
case THROWN_EXP_BOTTLE:
|
||||
case WEATHER:
|
||||
case WITHER_SKULL:
|
||||
case MINECART_FURNACE:
|
||||
case UNKNOWN: {
|
||||
// Do this stuff later
|
||||
return entity;
|
||||
}
|
||||
default: {
|
||||
PlotMain.sendConsoleSenderMessage("&cCOULD NOT IDENTIFY ENTITY: " + entity.getType());
|
||||
return entity;
|
||||
}
|
||||
|
||||
// MISC //
|
||||
case ITEM_FRAME: {
|
||||
final ItemFrame itemframe = (ItemFrame) entity;
|
||||
itemframe.setRotation(Rotation.values()[this.dataByte]);
|
||||
itemframe.setItem(this.stack);
|
||||
return entity;
|
||||
}
|
||||
case PAINTING: {
|
||||
final Painting painting = (Painting) entity;
|
||||
painting.setFacingDirection(BlockFace.values()[this.dataByte], true);
|
||||
painting.setArt(Art.getByName(this.dataString), true);
|
||||
return entity;
|
||||
}
|
||||
// END MISC //
|
||||
|
||||
// INVENTORY HOLDER //
|
||||
case MINECART_CHEST: {
|
||||
restoreInventory((InventoryHolder) entity);
|
||||
return entity;
|
||||
}
|
||||
case MINECART_HOPPER: {
|
||||
restoreInventory((InventoryHolder) entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
// START LIVING ENTITY //
|
||||
// START AGEABLE //
|
||||
// START TAMEABLE //
|
||||
case HORSE: {
|
||||
final Horse horse = (Horse) entity;
|
||||
horse.setJumpStrength(this.horse.jump);
|
||||
horse.setCarryingChest(this.horse.chest);
|
||||
horse.setVariant(Variant.values()[this.horse.variant]);
|
||||
horse.setStyle(Style.values()[this.horse.style]);
|
||||
horse.setColor(Color.values()[this.horse.color]);
|
||||
restoreTameable((Tameable) entity);
|
||||
restoreAgeable((Ageable) entity);
|
||||
restoreLiving((LivingEntity) entity);
|
||||
restoreInventory((InventoryHolder) entity);
|
||||
return entity;
|
||||
}
|
||||
// END INVENTORY HOLDER //
|
||||
case WOLF:
|
||||
case OCELOT: {
|
||||
restoreTameable((Tameable) entity);
|
||||
restoreAgeable((Ageable) entity);
|
||||
restoreLiving((LivingEntity) entity);
|
||||
return entity;
|
||||
}
|
||||
// END AMEABLE //
|
||||
|
||||
case SHEEP: {
|
||||
final Sheep sheep = (Sheep) entity;
|
||||
if (this.dataByte == 1) {
|
||||
sheep.setSheared(true);
|
||||
}
|
||||
if (this.dataByte2 != 0) {
|
||||
sheep.setColor(DyeColor.getByDyeData(this.dataByte2));
|
||||
}
|
||||
restoreAgeable((Ageable) entity);
|
||||
restoreLiving((LivingEntity) entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
case VILLAGER:
|
||||
case CHICKEN:
|
||||
case COW:
|
||||
case MUSHROOM_COW:
|
||||
case PIG: {
|
||||
restoreAgeable((Ageable) entity);
|
||||
restoreLiving((LivingEntity) entity);
|
||||
return entity;
|
||||
}
|
||||
// END AGEABLE //
|
||||
case RABBIT: { // NEW
|
||||
if (this.dataByte != 0) {
|
||||
((Rabbit) entity).setRabbitType(Type.values()[this.dataByte]);
|
||||
}
|
||||
restoreAgeable((Ageable) entity);
|
||||
restoreLiving((LivingEntity) entity);
|
||||
return entity;
|
||||
}
|
||||
case GUARDIAN: { // NEW
|
||||
if (this.dataByte != 0) {
|
||||
((Guardian) entity).setElder(true);
|
||||
}
|
||||
restoreLiving((LivingEntity) entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
case SKELETON: { // NEW
|
||||
if (this.dataByte != 0) {
|
||||
((Skeleton) entity).setSkeletonType(SkeletonType.values()[this.dataByte]);
|
||||
}
|
||||
storeLiving((LivingEntity) entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
case ARMOR_STAND: { // NEW
|
||||
// CHECK positions
|
||||
final ArmorStand stand = (ArmorStand) entity;
|
||||
if (this.inventory[0] != null) {
|
||||
stand.setItemInHand(this.inventory[0]);
|
||||
}
|
||||
if (this.inventory[1] != null) {
|
||||
stand.setHelmet(this.inventory[1]);
|
||||
}
|
||||
if (this.inventory[2] != null) {
|
||||
stand.setChestplate(this.inventory[2]);
|
||||
}
|
||||
if (this.inventory[3] != null) {
|
||||
stand.setLeggings(this.inventory[3]);
|
||||
}
|
||||
if (this.inventory[4] != null) {
|
||||
stand.setBoots(this.inventory[4]);
|
||||
}
|
||||
restoreLiving((LivingEntity) entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
case ENDERMITE: // NEW
|
||||
case BAT:
|
||||
case ENDER_DRAGON:
|
||||
case GHAST:
|
||||
case MAGMA_CUBE:
|
||||
case SQUID:
|
||||
case PIG_ZOMBIE:
|
||||
case ZOMBIE:
|
||||
case WITHER:
|
||||
case WITCH:
|
||||
case SPIDER:
|
||||
case CAVE_SPIDER:
|
||||
case SILVERFISH:
|
||||
case GIANT:
|
||||
case ENDERMAN:
|
||||
case CREEPER:
|
||||
case BLAZE:
|
||||
case SNOWMAN:
|
||||
case IRON_GOLEM: {
|
||||
restoreLiving((LivingEntity) entity);
|
||||
return entity;
|
||||
}
|
||||
// END LIVING //
|
||||
}
|
||||
}
|
||||
|
||||
private byte getOrdinal(Object[] list, Object value) {
|
||||
for (byte i = 0; i < list.length; i++) {
|
||||
if (list[i].equals(value)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.intellectualcrafters.plot.object.entity;
|
||||
|
||||
public class HorseStats {
|
||||
|
||||
public double jump;
|
||||
public boolean chest;
|
||||
public int variant;
|
||||
public int color;
|
||||
public int style;
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package com.intellectualcrafters.plot.object.entity;
|
||||
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
public class LivingEntityStats {
|
||||
|
||||
public boolean loot;
|
||||
public String name;
|
||||
public boolean visible;
|
||||
public float health;
|
||||
public short air;
|
||||
public boolean persistent;
|
||||
|
||||
public boolean leashed;
|
||||
public short leash_x;
|
||||
public short leash_y;
|
||||
public short leash_z;
|
||||
|
||||
public boolean equipped;
|
||||
public ItemStack hands;
|
||||
public ItemStack helmet;
|
||||
public ItemStack boots;
|
||||
public ItemStack leggings;
|
||||
public ItemStack chestplate;
|
||||
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.intellectualcrafters.plot.object.entity;
|
||||
|
||||
import org.bukkit.entity.AnimalTamer;
|
||||
|
||||
public class TameableStats {
|
||||
|
||||
public AnimalTamer owner;
|
||||
public boolean tamed;
|
||||
|
||||
}
|
@ -3,6 +3,7 @@ package com.intellectualcrafters.plot.util;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
@ -25,6 +26,8 @@ import org.bukkit.block.Jukebox;
|
||||
import org.bukkit.block.NoteBlock;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.block.Skull;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.intellectualcrafters.plot.PlotMain;
|
||||
@ -32,6 +35,7 @@ import com.intellectualcrafters.plot.object.BlockLoc;
|
||||
import com.intellectualcrafters.plot.object.ChunkLoc;
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import com.intellectualcrafters.plot.object.RegionWrapper;
|
||||
import com.intellectualcrafters.plot.object.entity.EntityWrapper;
|
||||
|
||||
public class ChunkManager {
|
||||
|
||||
@ -104,10 +108,10 @@ public class ChunkManager {
|
||||
private static HashMap<BlockLoc, String[]> signContents;
|
||||
private static HashMap<BlockLoc, Note> noteBlockContents;
|
||||
|
||||
public static boolean clearPlotExperimental(final World world, final Plot plot, final boolean isDelete) {
|
||||
final Location pos1 = PlotHelper.getPlotBottomLoc(world, plot.id).add(1, 0, 1);
|
||||
final Location pos2 = PlotHelper.getPlotTopLoc(world, plot.id);
|
||||
|
||||
private static HashSet<EntityWrapper> entities;
|
||||
|
||||
public static boolean regenerateRegion(Location pos1, Location pos2) {
|
||||
World world = pos1.getWorld();
|
||||
Chunk c1 = world.getChunkAt(pos1);
|
||||
Chunk c2 = world.getChunkAt(pos2);
|
||||
|
||||
@ -122,14 +126,12 @@ public class ChunkManager {
|
||||
int c1z = c1.getZ();
|
||||
int c2x = c2.getX();
|
||||
int c2z = c2.getZ();
|
||||
|
||||
int maxY = world.getMaxHeight();
|
||||
|
||||
int maxY = world.getMaxHeight();
|
||||
for (int x = c1x; x <= c2x; x ++) {
|
||||
for (int z = c1z; z <= c2z; z ++) {
|
||||
Chunk chunk = world.getChunkAt(x, z);
|
||||
boolean loaded = true;
|
||||
|
||||
if (!chunk.isLoaded()) {
|
||||
boolean result = chunk.load(false);
|
||||
if (!result) {
|
||||
@ -139,31 +141,10 @@ public class ChunkManager {
|
||||
loaded = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (loaded) {
|
||||
initMaps();
|
||||
int absX = x << 4;
|
||||
int absZ = z << 4;
|
||||
|
||||
GENERATE_BLOCKS = new HashMap<>();
|
||||
GENERATE_DATA = new HashMap<>();
|
||||
|
||||
chestContents = new HashMap<>();
|
||||
furnaceContents = new HashMap<>();
|
||||
dispenserContents = new HashMap<>();
|
||||
dropperContents = new HashMap<>();
|
||||
brewingStandContents = new HashMap<>();
|
||||
beaconContents = new HashMap<>();
|
||||
hopperContents = new HashMap<>();
|
||||
furnaceTime = new HashMap<>();
|
||||
skullData = new HashMap<>();
|
||||
brewTime = new HashMap<>();
|
||||
jukeDisc = new HashMap<>();
|
||||
spawnerData= new HashMap<>();
|
||||
noteBlockContents = new HashMap<>();
|
||||
signContents = new HashMap<>();
|
||||
cmdData = new HashMap<>();
|
||||
|
||||
|
||||
if (x == c1x || z == c1z) {
|
||||
for (int X = 0; X < 16; X++) {
|
||||
for (int Z = 0; Z < 16; Z++) {
|
||||
@ -182,31 +163,92 @@ public class ChunkManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
saveEntities(chunk, CURRENT_PLOT_CLEAR);
|
||||
world.regenerateChunk(x, z);
|
||||
restoreBlocks(world);
|
||||
restoreBlocks(world, 0, 0);
|
||||
restoreEntities(world, 0, 0);
|
||||
chunk.unload();
|
||||
chunk.load();
|
||||
}
|
||||
}
|
||||
}
|
||||
CURRENT_PLOT_CLEAR = null;
|
||||
initMaps();
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void restoreBlocks(World world) {
|
||||
public static void initMaps() {
|
||||
GENERATE_BLOCKS = new HashMap<>();
|
||||
GENERATE_DATA = new HashMap<>();
|
||||
|
||||
chestContents = new HashMap<>();
|
||||
furnaceContents = new HashMap<>();
|
||||
dispenserContents = new HashMap<>();
|
||||
dropperContents = new HashMap<>();
|
||||
brewingStandContents = new HashMap<>();
|
||||
beaconContents = new HashMap<>();
|
||||
hopperContents = new HashMap<>();
|
||||
furnaceTime = new HashMap<>();
|
||||
skullData = new HashMap<>();
|
||||
brewTime = new HashMap<>();
|
||||
jukeDisc = new HashMap<>();
|
||||
spawnerData= new HashMap<>();
|
||||
noteBlockContents = new HashMap<>();
|
||||
signContents = new HashMap<>();
|
||||
cmdData = new HashMap<>();
|
||||
|
||||
entities = new HashSet<>();
|
||||
}
|
||||
|
||||
public static boolean isIn(RegionWrapper region, int x, int z) {
|
||||
return (x >= region.minX && x <= region.maxX && z >= region.minZ && z <= region.maxZ);
|
||||
}
|
||||
|
||||
public static void saveEntities(Chunk chunk, RegionWrapper region) {
|
||||
for (Entity entity : chunk.getEntities()) {
|
||||
Location loc = entity.getLocation();
|
||||
int x = loc.getBlockX();
|
||||
int z = loc.getBlockZ();
|
||||
if (isIn(region, x, z)) {
|
||||
continue;
|
||||
}
|
||||
if (entity.getVehicle() != null) {
|
||||
continue;
|
||||
}
|
||||
EntityWrapper wrap = new EntityWrapper(entity, (short) 2);
|
||||
entities.add(wrap);
|
||||
|
||||
|
||||
|
||||
// int y = loc.getBlockY();
|
||||
// BlockLoc bl = new BlockLoc(x, y, z);
|
||||
// EntityWrapper wrap = new EntityWrapper(entity.getType().getTypeId());
|
||||
// entities.put(wrap, bl);
|
||||
// System.out.print(entity.isDead());
|
||||
// entity.teleport(new Location(chunk.getWorld(), 0, 65, 0));
|
||||
}
|
||||
}
|
||||
|
||||
public static void restoreEntities(World world, int x_offset, int z_offset) {
|
||||
for (EntityWrapper entity : entities) {
|
||||
entity.spawn(world, x_offset, z_offset);
|
||||
}
|
||||
}
|
||||
|
||||
public static void restoreBlocks(World world, int x_offset, int z_offset) {
|
||||
for (BlockLoc loc: chestContents.keySet()) {
|
||||
Block block = world.getBlockAt(loc.x, loc.y, loc.z);
|
||||
Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
|
||||
BlockState state = block.getState();
|
||||
if (state instanceof Chest) {
|
||||
Chest chest = (Chest) state;
|
||||
chest.getInventory().setContents(chestContents.get(loc));
|
||||
state.update(true);
|
||||
}
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to regenerate chest: "+loc.x+","+loc.y+","+loc.z); }
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to regenerate chest: "+loc.x + x_offset+","+loc.y+","+loc.z + z_offset); }
|
||||
}
|
||||
|
||||
for (BlockLoc loc: signContents.keySet()) {
|
||||
Block block = world.getBlockAt(loc.x, loc.y, loc.z);
|
||||
Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
|
||||
BlockState state = block.getState();
|
||||
if (state instanceof Sign) {
|
||||
Sign sign = (Sign) state;
|
||||
@ -217,51 +259,52 @@ public class ChunkManager {
|
||||
}
|
||||
state.update(true);
|
||||
}
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to regenerate sign: "+loc.x+","+loc.y+","+loc.z); }
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to regenerate sign: "+loc.x + x_offset+","+loc.y+","+loc.z + z_offset); }
|
||||
}
|
||||
|
||||
for (BlockLoc loc: dispenserContents.keySet()) {
|
||||
Block block = world.getBlockAt(loc.x, loc.y, loc.z);
|
||||
Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
|
||||
BlockState state = block.getState();
|
||||
if (state instanceof Dispenser) {
|
||||
((Dispenser) (state)).getInventory().setContents(dispenserContents.get(loc));
|
||||
state.update(true);
|
||||
}
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to regenerate dispenser: "+loc.x+","+loc.y+","+loc.z); }
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to regenerate dispenser: "+loc.x + x_offset+","+loc.y+","+loc.z + z_offset); }
|
||||
}
|
||||
for (BlockLoc loc: dropperContents.keySet()) {
|
||||
Block block = world.getBlockAt(loc.x, loc.y, loc.z);
|
||||
Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
|
||||
BlockState state = block.getState();
|
||||
if (state instanceof Dropper) {
|
||||
((Dropper) (state)).getInventory().setContents(dropperContents.get(loc));
|
||||
state.update(true);
|
||||
}
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to regenerate dispenser: "+loc.x+","+loc.y+","+loc.z); }
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to regenerate dispenser: "+loc.x + x_offset+","+loc.y+","+loc.z + z_offset); }
|
||||
}
|
||||
for (BlockLoc loc: beaconContents.keySet()) {
|
||||
Block block = world.getBlockAt(loc.x, loc.y, loc.z);
|
||||
Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
|
||||
BlockState state = block.getState();
|
||||
if (state instanceof Beacon) {
|
||||
((Beacon) (state)).getInventory().setContents(beaconContents.get(loc));
|
||||
state.update(true);
|
||||
}
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to regenerate beacon: "+loc.x+","+loc.y+","+loc.z); }
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to regenerate beacon: "+loc.x + x_offset+","+loc.y+","+loc.z + z_offset); }
|
||||
}
|
||||
for (BlockLoc loc: jukeDisc.keySet()) {
|
||||
Block block = world.getBlockAt(loc.x, loc.y, loc.z);
|
||||
Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
|
||||
BlockState state = block.getState();
|
||||
if (state instanceof Jukebox) {
|
||||
((Jukebox) (state)).setPlaying(Material.getMaterial(jukeDisc.get(loc)));
|
||||
state.update(true);
|
||||
}
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to restore jukebox: "+loc.x+","+loc.y+","+loc.z); }
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to restore jukebox: "+loc.x + x_offset+","+loc.y+","+loc.z + z_offset); }
|
||||
}
|
||||
for (BlockLoc loc: skullData.keySet()) {
|
||||
Block block = world.getBlockAt(loc.x, loc.y, loc.z);
|
||||
Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
|
||||
BlockState state = block.getState();
|
||||
if (state instanceof Skull) {
|
||||
Object[] data = skullData.get(loc);
|
||||
if (data[0] != null) {
|
||||
System.out.print("SET OWNER");
|
||||
((Skull) (state)).setOwner((String) data[0]);
|
||||
}
|
||||
if (((Integer) data[1]) != 0) {
|
||||
@ -269,81 +312,81 @@ public class ChunkManager {
|
||||
}
|
||||
state.update(true);
|
||||
}
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to restore jukebox: "+loc.x+","+loc.y+","+loc.z); }
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to restore jukebox: "+loc.x + x_offset+","+loc.y+","+loc.z + z_offset); }
|
||||
}
|
||||
for (BlockLoc loc: hopperContents.keySet()) {
|
||||
Block block = world.getBlockAt(loc.x, loc.y, loc.z);
|
||||
Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
|
||||
BlockState state = block.getState();
|
||||
if (state instanceof Hopper) {
|
||||
((Hopper) (state)).getInventory().setContents(hopperContents.get(loc));
|
||||
state.update(true);
|
||||
}
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to regenerate hopper: "+loc.x+","+loc.y+","+loc.z); }
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to regenerate hopper: "+loc.x + x_offset+","+loc.y+","+loc.z + z_offset); }
|
||||
}
|
||||
|
||||
for (BlockLoc loc: noteBlockContents.keySet()) {
|
||||
Block block = world.getBlockAt(loc.x, loc.y, loc.z);
|
||||
Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
|
||||
BlockState state = block.getState();
|
||||
if (state instanceof NoteBlock) {
|
||||
((NoteBlock) (state)).setNote(noteBlockContents.get(loc));
|
||||
state.update(true);
|
||||
}
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to regenerate note block: "+loc.x+","+loc.y+","+loc.z); }
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to regenerate note block: "+loc.x + x_offset+","+loc.y+","+loc.z + z_offset); }
|
||||
}
|
||||
for (BlockLoc loc: brewTime.keySet()) {
|
||||
Block block = world.getBlockAt(loc.x, loc.y, loc.z);
|
||||
Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
|
||||
BlockState state = block.getState();
|
||||
if (state instanceof BrewingStand) {
|
||||
((BrewingStand) (state)).setBrewingTime(brewTime.get(loc));
|
||||
}
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to restore brewing stand cooking: "+loc.x+","+loc.y+","+loc.z); }
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to restore brewing stand cooking: "+loc.x + x_offset+","+loc.y+","+loc.z + z_offset); }
|
||||
}
|
||||
|
||||
for (BlockLoc loc: spawnerData.keySet()) {
|
||||
Block block = world.getBlockAt(loc.x, loc.y, loc.z);
|
||||
Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
|
||||
BlockState state = block.getState();
|
||||
if (state instanceof CreatureSpawner) {
|
||||
((CreatureSpawner) (state)).setCreatureTypeId(spawnerData.get(loc));
|
||||
state.update(true);
|
||||
}
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to restore spawner type: "+loc.x+","+loc.y+","+loc.z); }
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to restore spawner type: "+loc.x + x_offset+","+loc.y+","+loc.z + z_offset); }
|
||||
}
|
||||
for (BlockLoc loc: cmdData.keySet()) {
|
||||
Block block = world.getBlockAt(loc.x, loc.y, loc.z);
|
||||
Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
|
||||
BlockState state = block.getState();
|
||||
if (state instanceof CommandBlock) {
|
||||
((CommandBlock) (state)).setCommand(cmdData.get(loc));
|
||||
state.update(true);
|
||||
}
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to restore command block: "+loc.x+","+loc.y+","+loc.z); }
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to restore command block: "+loc.x + x_offset+","+loc.y+","+loc.z + z_offset); }
|
||||
}
|
||||
for (BlockLoc loc: brewingStandContents.keySet()) {
|
||||
Block block = world.getBlockAt(loc.x, loc.y, loc.z);
|
||||
Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
|
||||
BlockState state = block.getState();
|
||||
if (state instanceof BrewingStand) {
|
||||
((BrewingStand) (state)).getInventory().setContents(brewingStandContents.get(loc));
|
||||
state.update(true);
|
||||
}
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to regenerate brewing stand: "+loc.x+","+loc.y+","+loc.z); }
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to regenerate brewing stand: "+loc.x + x_offset+","+loc.y+","+loc.z + z_offset); }
|
||||
}
|
||||
for (BlockLoc loc: furnaceTime.keySet()) {
|
||||
Block block = world.getBlockAt(loc.x, loc.y, loc.z);
|
||||
Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
|
||||
BlockState state = block.getState();
|
||||
if (state instanceof Furnace) {
|
||||
Short[] time = furnaceTime.get(loc);
|
||||
((Furnace) (state)).setBurnTime(time[0]);
|
||||
((Furnace) (state)).setCookTime(time[1]);
|
||||
}
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to restore furnace cooking: "+loc.x+","+loc.y+","+loc.z); }
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to restore furnace cooking: "+loc.x + x_offset+","+loc.y+","+loc.z + z_offset); }
|
||||
}
|
||||
for (BlockLoc loc: furnaceContents.keySet()) {
|
||||
Block block = world.getBlockAt(loc.x, loc.y, loc.z);
|
||||
Block block = world.getBlockAt(loc.x + x_offset, loc.y, loc.z + z_offset);
|
||||
BlockState state = block.getState();
|
||||
if (state instanceof Furnace) {
|
||||
((Furnace) (state)).getInventory().setContents(furnaceContents.get(loc));
|
||||
state.update(true);
|
||||
}
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to regenerate furnace: "+loc.x+","+loc.y+","+loc.z); }
|
||||
else { PlotMain.sendConsoleSenderMessage("&c[WARN] Plot clear failed to regenerate furnace: "+loc.x + x_offset+","+loc.y+","+loc.z + z_offset); }
|
||||
}
|
||||
}
|
||||
|
||||
@ -449,6 +492,7 @@ public class ChunkManager {
|
||||
hopperContents.put(bl, invHop);
|
||||
break;
|
||||
case 397:
|
||||
System.out.print("SAVING SKULL");
|
||||
bl = new BlockLoc(x, y, z);
|
||||
Skull skull = (Skull) block.getState();
|
||||
String o = skull.getOwner();
|
||||
|
Loading…
Reference in New Issue
Block a user