diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/Spigot_v1_13_R1.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/Spigot_v1_13_R1.java index 56c350f96..f66060e8c 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/Spigot_v1_13_R1.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/Spigot_v1_13_R1.java @@ -21,6 +21,7 @@ package com.boydti.fawe.bukkit.adapter; import static com.google.common.base.Preconditions.checkNotNull; +import com.boydti.fawe.Fawe; import com.google.common.collect.ImmutableList; import com.google.common.collect.Maps; import com.sk89q.jnbt.ByteArrayTag; @@ -132,7 +133,11 @@ public final class Spigot_v1_13_R1 implements BukkitImplAdapter { * @param tag the tag */ private static void readTagIntoTileEntity(NBTTagCompound tag, TileEntity tileEntity) { - tileEntity.load(tag); + try { + tileEntity.load(tag); + } catch (Throwable e) { + Fawe.debug("Invalid tag " + tag + " | " + tileEntity); + } } /** @@ -305,6 +310,7 @@ public final class Spigot_v1_13_R1 implements BukkitImplAdapter { worldServer.addEntity(createdEntity, SpawnReason.CUSTOM); return createdEntity.getBukkitEntity(); } else { + Fawe.debug("Invalid entity " + state.getType().getId()); return null; } } diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v0/BukkitChunk_All.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v0/BukkitChunk_All.java index 855dde5c6..3adc0d9a9 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v0/BukkitChunk_All.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v0/BukkitChunk_All.java @@ -145,7 +145,7 @@ public class BukkitChunk_All extends IntFaweChunk { float pitch = rotTag.getFloat(1); Location loc = new Location(world, x, y, z, yaw, pitch); Entity created = adapter.createEntity(loc, new BaseEntity(EntityTypes.get(id), tag)); - if (previous != null) { + if (created != null) { UUID uuid = created.getUniqueId(); Map map = ReflectionUtils.getMap(tag.getValue()); map.put("UUIDLeast", new LongTag(uuid.getLeastSignificantBits())); @@ -220,7 +220,6 @@ public class BukkitChunk_All extends IntFaweChunk { Location mutableLoc = new Location(world, 0, 0, 0); if (!checkTime) { - System.out.println("Set " + layer); int index = 0; for (int y = 0; y < 16; y++) { int yy = (layer << 4) + y; diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitEntityRegistry.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitEntityRegistry.java new file mode 100644 index 000000000..4fba200f6 --- /dev/null +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitEntityRegistry.java @@ -0,0 +1,23 @@ +package com.sk89q.worldedit.bukkit; + +import com.sk89q.worldedit.world.registry.EntityRegistry; +import org.bukkit.entity.EntityType; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class BukkitEntityRegistry implements EntityRegistry { + @Override + public Collection registerEntities() { + List types = new ArrayList<>(); + for (EntityType type : EntityType.values()) { + String name = type.getName(); + if (name != null) { + if (name.indexOf(':') == -1) name = "minecraft:" + name; + types.add(name); + } + } + return types; + } +} \ No newline at end of file diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitRegistries.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitRegistries.java index e6409c557..6a50bf507 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitRegistries.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitRegistries.java @@ -19,10 +19,7 @@ package com.sk89q.worldedit.bukkit; -import com.sk89q.worldedit.world.registry.BiomeRegistry; -import com.sk89q.worldedit.world.registry.BlockRegistry; -import com.sk89q.worldedit.world.registry.BundledRegistries; -import com.sk89q.worldedit.world.registry.ItemRegistry; +import com.sk89q.worldedit.world.registry.*; /** * World data for the Bukkit platform. @@ -33,6 +30,7 @@ class BukkitRegistries extends BundledRegistries { private final BlockRegistry blockRegistry = new BukkitBlockRegistry(); private final ItemRegistry itemRegistry = new BukkitItemRegistry(); private final BiomeRegistry biomeRegistry = new BukkitBiomeRegistry(); + private final EntityRegistry entityRegistry = new BukkitEntityRegistry(); /** * Create a new instance. @@ -55,6 +53,11 @@ class BukkitRegistries extends BundledRegistries { return itemRegistry; } + @Override + public EntityRegistry getEntityRegistry() { + return entityRegistry; + } + /** * Get a static instance. * diff --git a/worldedit-core/src/main/java/com/boydti/fawe/jnbt/SchematicStreamer.java b/worldedit-core/src/main/java/com/boydti/fawe/jnbt/SchematicStreamer.java index fd701868f..e4b749951 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/jnbt/SchematicStreamer.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/jnbt/SchematicStreamer.java @@ -1,5 +1,6 @@ package com.boydti.fawe.jnbt; +import com.boydti.fawe.Fawe; import com.boydti.fawe.config.Settings; import com.boydti.fawe.object.FaweInputStream; import com.boydti.fawe.object.FaweOutputStream; @@ -12,6 +13,7 @@ import com.boydti.fawe.object.io.FastByteArraysInputStream; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.ListTag; import com.sk89q.jnbt.NBTInputStream; +import com.sk89q.jnbt.StringTag; import com.sk89q.worldedit.BlockVector; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.blocks.BlockMaterial; @@ -22,6 +24,7 @@ import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.registry.state.PropertyKey; import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.world.block.*; +import com.sk89q.worldedit.world.entity.EntityType; import com.sk89q.worldedit.world.entity.EntityTypes; import com.sk89q.worldedit.world.item.ItemTypes; import com.sk89q.worldedit.world.registry.LegacyMapper; @@ -155,8 +158,14 @@ public class SchematicStreamer extends NBTStreamer { } ListTag positionTag = compound.getListTag("Pos"); ListTag directionTag = compound.getListTag("Rotation"); - BaseEntity state = new BaseEntity(EntityTypes.parse(id), compound); - fc.createEntity(clipboard, positionTag.asDouble(0), positionTag.asDouble(1), positionTag.asDouble(2), (float) directionTag.asDouble(0), (float) directionTag.asDouble(1), state); + EntityType type = EntityTypes.parse(id); + if (type != null) { + compound.getValue().put("Id", new StringTag(type.getId())); + BaseEntity state = new BaseEntity(type, compound); + fc.createEntity(clipboard, positionTag.asDouble(0), positionTag.asDouble(1), positionTag.asDouble(2), (float) directionTag.asDouble(0), (float) directionTag.asDouble(1), state); + } else { + Fawe.debug("Invalid entity: " + id); + } } }); } @@ -262,14 +271,23 @@ public class SchematicStreamer extends NBTStreamer { break; default: int group = group(type); - if (group != -1) { - BlockStateHolder set = block; - if (set.getState(PropertyKey.NORTH) == Boolean.FALSE && merge(group, x, y, z - 1)) set = set.with(PropertyKey.NORTH, true); - if (set.getState(PropertyKey.EAST) == Boolean.FALSE && merge(group, x + 1, y, z)) set = set.with(PropertyKey.EAST, true); - if (set.getState(PropertyKey.SOUTH) == Boolean.FALSE && merge(group, x, y, z + 1)) set = set.with(PropertyKey.SOUTH, true); - if (set.getState(PropertyKey.WEST) == Boolean.FALSE && merge(group, x - 1, y, z)) set = set.with(PropertyKey.WEST, true); - if (set != block) fc.setBlock(x, y, z, set); + if (group == -1) return; + BlockStateHolder set = block; + + if (set.getState(PropertyKey.NORTH) == Boolean.FALSE && merge(group, x, y, z - 1)) set = set.with(PropertyKey.NORTH, true); + if (set.getState(PropertyKey.EAST) == Boolean.FALSE && merge(group, x + 1, y, z)) set = set.with(PropertyKey.EAST, true); + if (set.getState(PropertyKey.SOUTH) == Boolean.FALSE && merge(group, x, y, z + 1)) set = set.with(PropertyKey.SOUTH, true); + if (set.getState(PropertyKey.WEST) == Boolean.FALSE && merge(group, x - 1, y, z)) set = set.with(PropertyKey.WEST, true); + + if (group == 2) { + int ns = ((Boolean) set.getState(PropertyKey.NORTH) ? 1 : 0) + ((Boolean) set.getState(PropertyKey.SOUTH) ? 1 : 0); + int ew = ((Boolean) set.getState(PropertyKey.EAST) ? 1 : 0) + ((Boolean) set.getState(PropertyKey.WEST) ? 1 : 0); + if (Math.abs(ns - ew) != 2 || fc.getBlock(x, y + 1, z).getBlockType().getMaterial().isSolid()) { + set = set.with(PropertyKey.UP, true); + } } + + if (set != block) fc.setBlock(x, y, z, set); break; } } diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/extent/FastWorldEditExtent.java b/worldedit-core/src/main/java/com/boydti/fawe/object/extent/FastWorldEditExtent.java index 9956001ba..cc5d2a69e 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/extent/FastWorldEditExtent.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/extent/FastWorldEditExtent.java @@ -5,11 +5,7 @@ import com.boydti.fawe.object.FaweQueue; import com.boydti.fawe.object.HasFaweQueue; import com.boydti.fawe.util.MainUtil; import com.boydti.fawe.util.ReflectionUtils; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.jnbt.DoubleTag; -import com.sk89q.jnbt.ListTag; -import com.sk89q.jnbt.StringTag; -import com.sk89q.jnbt.Tag; +import com.sk89q.jnbt.*; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.WorldEditException; @@ -27,8 +23,7 @@ import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; -import java.util.List; -import java.util.Map; +import java.util.*; public class FastWorldEditExtent extends AbstractDelegateExtent implements HasFaweQueue { @@ -81,15 +76,25 @@ public class FastWorldEditExtent extends AbstractDelegateExtent implements HasFa public Entity createEntity(final Location loc, final BaseEntity entity) { if (entity != null) { CompoundTag tag = entity.getNbtData(); + if (tag == null) { + HashMap map = new HashMap<>(); + tag = new CompoundTag(map); + } Map map = ReflectionUtils.getMap(tag.getValue()); map.put("Id", new StringTag(entity.getType().getId())); ListTag pos = (ListTag) map.get("Pos"); - if (pos != null) { + if (pos == null) { + map.put("Pos", new ListTag(DoubleTag.class, Arrays.asList(new DoubleTag(loc.getX()), new DoubleTag(loc.getY()), new DoubleTag(loc.getZ())))); + } else { List posList = ReflectionUtils.getList(pos.getValue()); posList.set(0, new DoubleTag(loc.getX())); posList.set(1, new DoubleTag(loc.getY())); posList.set(2, new DoubleTag(loc.getZ())); } + ListTag rot = (ListTag) map.get("Rotation"); + if (rot == null) { + map.put("Rotation", new ListTag(FloatTag.class, Arrays.asList(new FloatTag(loc.getYaw()), new DoubleTag(loc.getPitch())))); + } queue.setEntity(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), tag); } return null; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java index 579f2c27d..8a250f790 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java @@ -2685,7 +2685,6 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue, int count = stateCount[propId]; if (count != 0) { BlockStateHolder state = type.withPropertyId(propId); - System.out.println(type + " | " + state); distribution.add(new Countable<>(state, count)); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/entity/BaseEntity.java b/worldedit-core/src/main/java/com/sk89q/worldedit/entity/BaseEntity.java index 5c853a2a6..fe897baca 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/entity/BaseEntity.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/entity/BaseEntity.java @@ -25,6 +25,8 @@ import com.sk89q.worldedit.world.entity.EntityType; import javax.annotation.Nullable; +import java.util.HashMap; + import static com.google.common.base.Preconditions.checkNotNull; /** diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/logging/AbstractLoggingExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/logging/AbstractLoggingExtent.java new file mode 100644 index 000000000..cbe5e256e --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/logging/AbstractLoggingExtent.java @@ -0,0 +1,58 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.extent.logging; + +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.extent.AbstractDelegateExtent; +import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockStateHolder; + +/** + * An abstract class to implement block loggers and so on with. + */ +public abstract class AbstractLoggingExtent extends AbstractDelegateExtent { + + /** + * Create a new instance. + * + * @param extent the extent + */ + protected AbstractLoggingExtent(Extent extent) { + super(extent); + } + + /** + * Called when a block is being changed. + * + * @param position the position + * @param newBlock the new block to replace the old one + */ + protected void onBlockChange(Vector position, BlockStateHolder newBlock) { + } + + @Override + public final boolean setBlock(Vector position, BlockStateHolder block) throws WorldEditException { + onBlockChange(position, block); + return super.setBlock(position, block); + } +} \ No newline at end of file diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityType.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityType.java index 71779e953..b9f898fd5 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityType.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityType.java @@ -21,46 +21,15 @@ package com.sk89q.worldedit.world.entity; import com.sk89q.worldedit.registry.NamespacedRegistry; -public class EntityType { - - public static final NamespacedRegistry REGISTRY = new NamespacedRegistry<>("entity type"); - - private String id; - - public EntityType(String id) { - // If it has no namespace, assume minecraft. - if (!id.contains(":")) { - id = "minecraft:" + id; - } - this.id = id; - } - - public String getId() { - return this.id; - } +public interface EntityType { + String getId(); /** * Gets the name of this item, or the ID if the name cannot be found. * * @return The name, or ID */ - public String getName() { + default String getName() { return getId(); } - - @Override - public String toString() { - return getId(); - } - - @Override - public int hashCode() { - return this.id.hashCode(); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof EntityType && this.id.equals(((EntityType) obj).id); - } - } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityTypes.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityTypes.java index d8ac07270..9fdfcfd89 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityTypes.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/entity/EntityTypes.java @@ -19,109 +19,156 @@ package com.sk89q.worldedit.world.entity; +import com.boydti.fawe.util.ReflectionUtils; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.blocks.BaseItem; +import com.sk89q.worldedit.blocks.BaseItemStack; +import com.sk89q.worldedit.entity.BaseEntity; +import com.sk89q.worldedit.extension.platform.Capability; +import com.sk89q.worldedit.world.block.BlockTypes; +import com.sk89q.worldedit.world.item.ItemType; +import com.sk89q.worldedit.world.registry.LegacyMapper; + import javax.annotation.Nullable; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; -public class EntityTypes { +public enum EntityTypes implements EntityType { + /* + ----------------------------------------------------- + Replaced at runtime by the entity registry + ----------------------------------------------------- + */ + AREA_EFFECT_CLOUD, + ARMOR_STAND, + ARROW, + BAT, + BLAZE, + BOAT, + CAVE_SPIDER, + CHEST_MINECART, + CHICKEN, + COD, + COMMAND_BLOCK_MINECART, + COW, + CREEPER, + DOLPHIN, + DONKEY, + DRAGON_FIREBALL, + DROWNED, + EGG, + ELDER_GUARDIAN, + END_CRYSTAL, + ENDER_DRAGON, + ENDER_PEARL, + ENDERMAN, + ENDERMITE, + EVOKER, + EVOKER_FANGS, + EXPERIENCE_BOTTLE, + EXPERIENCE_ORB, + EYE_OF_ENDER, + FALLING_BLOCK, + FIREBALL, + FIREWORK_ROCKET, + FISHING_BOBBER, + FURNACE_MINECART, + GHAST, + GIANT, + GUARDIAN, + HOPPER_MINECART, + HORSE, + HUSK, + ILLUSIONER, + IRON_GOLEM, + ITEM, + ITEM_FRAME, + LEASH_KNOT, + LIGHTNING_BOLT, + LLAMA, + LLAMA_SPIT, + MAGMA_CUBE, + MINECART, + MOOSHROOM, + MULE, + OCELOT, + PAINTING, + PARROT, + PHANTOM, + PIG, + PLAYER, + POLAR_BEAR, + POTION, + PUFFERFISH, + RABBIT, + SALMON, + SHEEP, + SHULKER, + SHULKER_BULLET, + SILVERFISH, + SKELETON, + SKELETON_HORSE, + SLIME, + SMALL_FIREBALL, + SNOW_GOLEM, + SNOWBALL, + SPAWNER_MINECART, + SPECTRAL_ARROW, + SPIDER, + SQUID, + STRAY, + TNT, + TNT_MINECART, + TRIDENT, + TROPICAL_FISH, + TURTLE, + VEX, + VILLAGER, + VINDICATOR, + WITCH, + WITHER, + WITHER_SKELETON, + WITHER_SKULL, + WOLF, + ZOMBIE, + ZOMBIE_HORSE, + ZOMBIE_PIGMAN, + ZOMBIE_VILLAGER, - public static final EntityType AREA_EFFECT_CLOUD = register("minecraft:area_effect_cloud"); - public static final EntityType ARMOR_STAND = register("minecraft:armor_stand"); - public static final EntityType ARROW = register("minecraft:arrow"); - public static final EntityType BAT = register("minecraft:bat"); - public static final EntityType BLAZE = register("minecraft:blaze"); - public static final EntityType BOAT = register("minecraft:boat"); - public static final EntityType CAVE_SPIDER = register("minecraft:cave_spider"); - public static final EntityType CHEST_MINECART = register("minecraft:chest_minecart"); - public static final EntityType CHICKEN = register("minecraft:chicken"); - public static final EntityType COD = register("minecraft:cod"); - public static final EntityType COMMAND_BLOCK_MINECART = register("minecraft:command_block_minecart"); - public static final EntityType COW = register("minecraft:cow"); - public static final EntityType CREEPER = register("minecraft:creeper"); - public static final EntityType DOLPHIN = register("minecraft:dolphin"); - public static final EntityType DONKEY = register("minecraft:donkey"); - public static final EntityType DRAGON_FIREBALL = register("minecraft:dragon_fireball"); - public static final EntityType DROWNED = register("minecraft:drowned"); - public static final EntityType EGG = register("minecraft:egg"); - public static final EntityType ELDER_GUARDIAN = register("minecraft:elder_guardian"); - public static final EntityType END_CRYSTAL = register("minecraft:end_crystal"); - public static final EntityType ENDER_DRAGON = register("minecraft:ender_dragon"); - public static final EntityType ENDER_PEARL = register("minecraft:ender_pearl"); - public static final EntityType ENDERMAN = register("minecraft:enderman"); - public static final EntityType ENDERMITE = register("minecraft:endermite"); - public static final EntityType EVOKER = register("minecraft:evoker"); - public static final EntityType EVOKER_FANGS = register("minecraft:evoker_fangs"); - public static final EntityType EXPERIENCE_BOTTLE = register("minecraft:experience_bottle"); - public static final EntityType EXPERIENCE_ORB = register("minecraft:experience_orb"); - public static final EntityType EYE_OF_ENDER = register("minecraft:eye_of_ender"); - public static final EntityType FALLING_BLOCK = register("minecraft:falling_block"); - public static final EntityType FIREBALL = register("minecraft:fireball"); - public static final EntityType FIREWORK_ROCKET = register("minecraft:firework_rocket"); - public static final EntityType FISHING_BOBBER = register("minecraft:fishing_bobber"); - public static final EntityType FURNACE_MINECART = register("minecraft:furnace_minecart"); - public static final EntityType GHAST = register("minecraft:ghast"); - public static final EntityType GIANT = register("minecraft:giant"); - public static final EntityType GUARDIAN = register("minecraft:guardian"); - public static final EntityType HOPPER_MINECART = register("minecraft:hopper_minecart"); - public static final EntityType HORSE = register("minecraft:horse"); - public static final EntityType HUSK = register("minecraft:husk"); - public static final EntityType ILLUSIONER = register("minecraft:illusioner"); - public static final EntityType IRON_GOLEM = register("minecraft:iron_golem"); - public static final EntityType ITEM = register("minecraft:item"); - public static final EntityType ITEM_FRAME = register("minecraft:item_frame"); - public static final EntityType LEASH_KNOT = register("minecraft:leash_knot"); - public static final EntityType LIGHTNING_BOLT = register("minecraft:lightning_bolt"); - public static final EntityType LLAMA = register("minecraft:llama"); - public static final EntityType LLAMA_SPIT = register("minecraft:llama_spit"); - public static final EntityType MAGMA_CUBE = register("minecraft:magma_cube"); - public static final EntityType MINECART = register("minecraft:minecart"); - public static final EntityType MOOSHROOM = register("minecraft:mooshroom"); - public static final EntityType MULE = register("minecraft:mule"); - public static final EntityType OCELOT = register("minecraft:ocelot"); - public static final EntityType PAINTING = register("minecraft:painting"); - public static final EntityType PARROT = register("minecraft:parrot"); - public static final EntityType PHANTOM = register("minecraft:phantom"); - public static final EntityType PIG = register("minecraft:pig"); - public static final EntityType PLAYER = register("minecraft:player"); - public static final EntityType POLAR_BEAR = register("minecraft:polar_bear"); - public static final EntityType POTION = register("minecraft:potion"); - public static final EntityType PUFFERFISH = register("minecraft:pufferfish"); - public static final EntityType RABBIT = register("minecraft:rabbit"); - public static final EntityType SALMON = register("minecraft:salmon"); - public static final EntityType SHEEP = register("minecraft:sheep"); - public static final EntityType SHULKER = register("minecraft:shulker"); - public static final EntityType SHULKER_BULLET = register("minecraft:shulker_bullet"); - public static final EntityType SILVERFISH = register("minecraft:silverfish"); - public static final EntityType SKELETON = register("minecraft:skeleton"); - public static final EntityType SKELETON_HORSE = register("minecraft:skeleton_horse"); - public static final EntityType SLIME = register("minecraft:slime"); - public static final EntityType SMALL_FIREBALL = register("minecraft:small_fireball"); - public static final EntityType SNOW_GOLEM = register("minecraft:snow_golem"); - public static final EntityType SNOWBALL = register("minecraft:snowball"); - public static final EntityType SPAWNER_MINECART = register("minecraft:spawner_minecart"); - public static final EntityType SPECTRAL_ARROW = register("minecraft:spectral_arrow"); - public static final EntityType SPIDER = register("minecraft:spider"); - public static final EntityType SQUID = register("minecraft:squid"); - public static final EntityType STRAY = register("minecraft:stray"); - public static final EntityType TNT = register("minecraft:tnt"); - public static final EntityType TNT_MINECART = register("minecraft:tnt_minecart"); - public static final EntityType TRIDENT = register("minecraft:trident"); - public static final EntityType TROPICAL_FISH = register("minecraft:tropical_fish"); - public static final EntityType TURTLE = register("minecraft:turtle"); - public static final EntityType VEX = register("minecraft:vex"); - public static final EntityType VILLAGER = register("minecraft:villager"); - public static final EntityType VINDICATOR = register("minecraft:vindicator"); - public static final EntityType WITCH = register("minecraft:witch"); - public static final EntityType WITHER = register("minecraft:wither"); - public static final EntityType WITHER_SKELETON = register("minecraft:wither_skeleton"); - public static final EntityType WITHER_SKULL = register("minecraft:wither_skull"); - public static final EntityType WOLF = register("minecraft:wolf"); - public static final EntityType ZOMBIE = register("minecraft:zombie"); - public static final EntityType ZOMBIE_HORSE = register("minecraft:zombie_horse"); - public static final EntityType ZOMBIE_PIGMAN = register("minecraft:zombie_pigman"); - public static final EntityType ZOMBIE_VILLAGER = register("minecraft:zombie_villager"); + ; - private EntityTypes() { + private String id; + + EntityTypes() { + this(null); } + EntityTypes(String id) { + if (id == null) id = "minecraft:" + name().toLowerCase(); + // If it has no namespace, assume minecraft. + else if (!id.contains(":")) { + id = "minecraft:" + id; + } + this.id = id; + } + + @Override + public String getId() { + return id; + } + + @Override + public String toString() { + return getId(); + } + + /* + ----------------------------------------------------- + Static Initializer + ----------------------------------------------------- + */ + public static EntityType parse(String id) { if (id.startsWith("minecraft:")) id = id.substring(10); switch (id) { @@ -148,7 +195,7 @@ public class EntityTypes { default: if (Character.isUpperCase(id.charAt(0))) { StringBuilder result = new StringBuilder(); - for (int i = 0; i < result.length(); i++) { + for (int i = 0; i < id.length(); i++) { char c = id.charAt(i); if (Character.isUpperCase(c)) { c = Character.toLowerCase(c); @@ -189,18 +236,56 @@ public class EntityTypes { } } - private static EntityType register(final String id) { - return register(new EntityType(id)); + private static final Map $REGISTRY = new HashMap<>(); + + public static final EntityTypes[] values; + + static { + try { + Collection ents = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getEntityRegistry().registerEntities(); + if (!ents.isEmpty()) { // No types found - use defaults + for (String ent : ents) { + register(ent); + } + } + // Cache the values + values = values(); + } catch (Throwable e) { + e.printStackTrace(); + throw new RuntimeException(e); + } } - public static EntityType register(final EntityType entityType) { - String id = entityType.getId(); - if (id.startsWith("minecraft:")) EntityType.REGISTRY.register(id.substring(10), entityType); - return EntityType.REGISTRY.register(id, entityType); + private static EntityTypes register(final String id) { + // Get the enum name (remove namespace if minecraft:) + int propStart = id.indexOf('['); + String typeName = id.substring(0, propStart == -1 ? id.length() : propStart); + String enumName = (typeName.startsWith("minecraft:") ? typeName.substring(10) : typeName).toUpperCase(); + // Check existing + EntityTypes existing = null; + try { existing = valueOf(enumName.toUpperCase()); } catch (IllegalArgumentException ignore) {} + if (existing != null) { + // TODO additional registration + } else { + // Create it + existing = ReflectionUtils.addEnum(EntityTypes.class, enumName, new Class[]{String.class}, new Object[]{id}); + } + if (typeName.startsWith("minecraft:")) $REGISTRY.put(typeName.substring(10), existing); + $REGISTRY.put(typeName, existing); + return existing; } - public static @Nullable EntityType get(final String id) { - return EntityType.REGISTRY.get(id); + public static final @Nullable EntityTypes get(final String id) { + return $REGISTRY.get(id); + } + + @Deprecated + public static final EntityTypes get(final int ordinal) { + return values[ordinal]; + } + + public static int size() { + return values.length; } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemTypes.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemTypes.java index 6d507b807..00c6ff186 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemTypes.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/item/ItemTypes.java @@ -28,6 +28,7 @@ import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.registry.NamespacedRegistry; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; +import com.sk89q.worldedit.world.entity.EntityTypes; import com.sk89q.worldedit.world.registry.BundledItemData; import com.sk89q.worldedit.world.registry.LegacyMapper; @@ -914,10 +915,10 @@ public enum ItemTypes implements ItemType { } /* - ----------------------------------------------------- - Static Initializer - ----------------------------------------------------- - */ + ----------------------------------------------------- + Static Initializer + ----------------------------------------------------- + */ private static final Map $REGISTRY = new HashMap<>(); public static final ItemTypes[] values; @@ -961,7 +962,8 @@ public enum ItemTypes implements ItemType { String typeName = id.substring(0, propStart == -1 ? id.length() : propStart); String enumName = (typeName.startsWith("minecraft:") ? typeName.substring(10) : typeName).toUpperCase(); // Check existing - ItemTypes existing = valueOf(enumName.toUpperCase()); + ItemTypes existing = null; + try { existing = valueOf(enumName.toUpperCase()); } catch (IllegalArgumentException ignore) {} if (existing != null) { // TODO additional registration } else { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/EntityRegistry.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/EntityRegistry.java index 2a3830134..bbfec725f 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/EntityRegistry.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/EntityRegistry.java @@ -19,9 +19,16 @@ package com.sk89q.worldedit.world.registry; +import com.sk89q.worldedit.blocks.BaseItem; import com.sk89q.worldedit.entity.BaseEntity; +import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.world.entity.EntityTypes; +import com.sk89q.worldedit.world.item.ItemType; +import com.sk89q.worldedit.world.item.ItemTypes; import javax.annotation.Nullable; +import java.util.Collection; +import java.util.Collections; /** * Provides information on entities. @@ -35,6 +42,15 @@ public interface EntityRegistry { * @return the entity, which may be null if the entity does not exist */ @Nullable - BaseEntity createFromId(String id); + default BaseEntity createFromId(String id) { + EntityTypes entType = EntityTypes.get(id); + return entType == null ? null : new BaseEntity(entType); + } + /** + * Register all entities + */ + default Collection registerEntities() { + return Collections.emptyList(); + } }