From 7ab299d22d259092a6a833f8c7752df04916022e Mon Sep 17 00:00:00 2001 From: boy0001 Date: Tue, 10 Feb 2015 03:21:59 +1100 Subject: [PATCH] Entity cloning (TODO leashes) --- .../plot/object/entity/AgeableStats.java | 9 + .../plot/object/entity/EntityBaseStats.java | 11 + .../plot/object/entity/EntityWrapper.java | 591 ++++++++++++++++++ .../plot/object/entity/HorseStats.java | 10 + .../plot/object/entity/LivingEntityStats.java | 26 + .../plot/object/entity/TameableStats.java | 10 + .../plot/util/ChunkManager.java | 166 +++-- 7 files changed, 762 insertions(+), 61 deletions(-) create mode 100644 PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/AgeableStats.java create mode 100644 PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/EntityBaseStats.java create mode 100644 PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/EntityWrapper.java create mode 100644 PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/HorseStats.java create mode 100644 PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/LivingEntityStats.java create mode 100644 PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/TameableStats.java diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/AgeableStats.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/AgeableStats.java new file mode 100644 index 000000000..779bfddc8 --- /dev/null +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/AgeableStats.java @@ -0,0 +1,9 @@ +package com.intellectualcrafters.plot.object.entity; + +public class AgeableStats { + + public int age; + public boolean locked; + public boolean adult; + +} diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/EntityBaseStats.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/EntityBaseStats.java new file mode 100644 index 000000000..5ce545351 --- /dev/null +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/EntityBaseStats.java @@ -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; +} diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/EntityWrapper.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/EntityWrapper.java new file mode 100644 index 000000000..15f2e8164 --- /dev/null +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/EntityWrapper.java @@ -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; + } +} diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/HorseStats.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/HorseStats.java new file mode 100644 index 000000000..8fc524c3e --- /dev/null +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/HorseStats.java @@ -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; +} diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/LivingEntityStats.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/LivingEntityStats.java new file mode 100644 index 000000000..dcfd400fe --- /dev/null +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/LivingEntityStats.java @@ -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; + +} diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/TameableStats.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/TameableStats.java new file mode 100644 index 000000000..9ff08b87c --- /dev/null +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/entity/TameableStats.java @@ -0,0 +1,10 @@ +package com.intellectualcrafters.plot.object.entity; + +import org.bukkit.entity.AnimalTamer; + +public class TameableStats { + + public AnimalTamer owner; + public boolean tamed; + +} diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/ChunkManager.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/ChunkManager.java index 5805d764f..3c15c481a 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/ChunkManager.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/ChunkManager.java @@ -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 signContents; private static HashMap 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 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();