From 3e34d5ca52db626c4c83cdd7bc98f63e576f37b8 Mon Sep 17 00:00:00 2001 From: sk89q Date: Tue, 15 Jul 2014 19:47:47 -0700 Subject: [PATCH] Re-implement /remove and /butcher with the new entity API. --- .../sk89q/worldedit/bukkit/BukkitEntity.java | 13 ++ .../worldedit/bukkit/BukkitEntityType.java | 140 ++++++++++++ .../sk89q/worldedit/bukkit/BukkitPlayer.java | 8 + .../sk89q/worldedit/bukkit/BukkitWorld.java | 206 ------------------ .../sk89q/worldedit/forge/ForgeEntity.java | 25 ++- .../worldedit/forge/ForgeEntityType.java | 138 ++++++++++++ .../sk89q/worldedit/forge/ForgePlayer.java | 14 +- .../com/sk89q/worldedit/forge/ForgeWorld.java | 137 +----------- .../java/com/sk89q/worldedit/LocalWorld.java | 18 -- .../worldedit/command/BrushCommands.java | 40 ++-- .../worldedit/command/UtilityCommands.java | 150 ++++++------- .../command/tool/brush/ButcherBrush.java | 15 +- .../command/util/CreatureButcher.java | 135 ++++++++++++ .../worldedit/command/util/EntityRemover.java | 160 ++++++++++++++ .../sk89q/worldedit/entity/BaseEntity.java | 9 + .../com/sk89q/worldedit/entity/Entity.java | 3 +- .../worldedit/entity/metadata/EntityType.java | 151 +++++++++++++ .../extension/platform/PlayerProxy.java | 8 + .../worldedit/extent/ChangeSetExtent.java | 6 + .../extent/clipboard/BlockArrayClipboard.java | 6 + .../worldedit/internal/LocalWorldAdapter.java | 29 --- .../worldedit/regions/CylinderRegion.java | 46 +++- .../com/sk89q/worldedit/util/Faceted.java | 52 +++++ .../util/collection/FastListIterator.java | 6 +- .../sk89q/worldedit/world/AbstractWorld.java | 17 -- .../com/sk89q/worldedit/world/NullWorld.java | 10 - .../java/com/sk89q/worldedit/world/World.java | 43 ---- .../world/registry/EntityRegistry.java | 42 ++++ .../world/registry/LegacyWorldData.java | 6 + .../registry/NullEntityRegistry.java} | 74 +++---- .../worldedit/world/registry/WorldData.java | 7 + 31 files changed, 1110 insertions(+), 604 deletions(-) create mode 100644 src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitEntityType.java create mode 100644 src/forge/java/com/sk89q/worldedit/forge/ForgeEntityType.java create mode 100644 src/main/java/com/sk89q/worldedit/command/util/CreatureButcher.java create mode 100644 src/main/java/com/sk89q/worldedit/command/util/EntityRemover.java create mode 100644 src/main/java/com/sk89q/worldedit/entity/metadata/EntityType.java create mode 100644 src/main/java/com/sk89q/worldedit/util/Faceted.java create mode 100644 src/main/java/com/sk89q/worldedit/world/registry/EntityRegistry.java rename src/main/java/com/sk89q/worldedit/{EntityType.java => world/registry/NullEntityRegistry.java} (70%) diff --git a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitEntity.java b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitEntity.java index 002890778..483b740eb 100644 --- a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitEntity.java +++ b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitEntity.java @@ -23,10 +23,13 @@ import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Player; +import com.sk89q.worldedit.entity.metadata.EntityType; import com.sk89q.worldedit.entity.metadata.Tameable; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.util.Location; +import javax.annotation.Nullable; + import static com.google.common.base.Preconditions.checkNotNull; /** @@ -94,4 +97,14 @@ class BukkitEntity implements Entity { return entity.isDead(); } + @SuppressWarnings("unchecked") + @Nullable + @Override + public T getFacet(Class cls) { + if (EntityType.class.isAssignableFrom(cls)) { + return (T) new BukkitEntityType(entity); + } else { + return null; + } + } } diff --git a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitEntityType.java b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitEntityType.java new file mode 100644 index 000000000..d80526c83 --- /dev/null +++ b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitEntityType.java @@ -0,0 +1,140 @@ +/* + * 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.bukkit; + +import com.sk89q.worldedit.entity.metadata.EntityType; +import com.sk89q.worldedit.util.Enums; +import org.bukkit.entity.Ambient; +import org.bukkit.entity.Animals; +import org.bukkit.entity.Boat; +import org.bukkit.entity.Entity; +import org.bukkit.entity.ExperienceOrb; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.Golem; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Item; +import org.bukkit.entity.ItemFrame; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Minecart; +import org.bukkit.entity.Painting; +import org.bukkit.entity.Projectile; +import org.bukkit.entity.TNTPrimed; +import org.bukkit.entity.Tameable; +import org.bukkit.entity.Villager; + +import static com.google.common.base.Preconditions.checkNotNull; + +class BukkitEntityType implements EntityType { + + private static final org.bukkit.entity.EntityType tntMinecartType = + Enums.findByValue(org.bukkit.entity.EntityType.class, "MINECART_TNT"); + + private final Entity entity; + + BukkitEntityType(Entity entity) { + checkNotNull(entity); + this.entity = entity; + } + + @Override + public boolean isPlayerDerived() { + return entity instanceof HumanEntity; + } + + @Override + public boolean isProjectile() { + return entity instanceof Projectile; + } + + @Override + public boolean isItem() { + return entity instanceof Item; + } + + @Override + public boolean isFallingBlock() { + return entity instanceof FallingBlock; + } + + @Override + public boolean isPainting() { + return entity instanceof Painting; + } + + @Override + public boolean isItemFrame() { + return entity instanceof ItemFrame; + } + + @Override + public boolean isBoat() { + return entity instanceof Boat; + } + + @Override + public boolean isMinecart() { + return entity instanceof Minecart; + } + + @Override + public boolean isTNT() { + return entity instanceof TNTPrimed || entity.getType() == tntMinecartType; + } + + @Override + public boolean isExperienceOrb() { + return entity instanceof ExperienceOrb; + } + + @Override + public boolean isLiving() { + return entity instanceof LivingEntity; + } + + @Override + public boolean isAnimal() { + return entity instanceof Animals; + } + + @Override + public boolean isAmbient() { + return entity instanceof Ambient; + } + + @Override + public boolean isNPC() { + return entity instanceof Villager; + } + + @Override + public boolean isGolem() { + return entity instanceof Golem; + } + + @Override + public boolean isTamed() { + return entity instanceof Tameable && ((Tameable) entity).isTamed(); + } + + @Override + public boolean isTagged() { + return entity instanceof LivingEntity && ((LivingEntity) entity).getCustomName() != null; + } +} diff --git a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java index 22a659abf..8f82aa371 100644 --- a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java +++ b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitPlayer.java @@ -35,6 +35,8 @@ import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import javax.annotation.Nullable; + public class BukkitPlayer extends LocalPlayer { private Player player; private WorldEditPlugin plugin; @@ -184,4 +186,10 @@ public class BukkitPlayer extends LocalPlayer { (float) Math.toRadians(nativeLocation.getYaw()), (float) Math.toRadians(nativeLocation.getPitch())); } + + @Nullable + @Override + public T getFacet(Class cls) { + return null; + } } diff --git a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitWorld.java b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitWorld.java index 2debe4ebd..170ceacb6 100644 --- a/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitWorld.java +++ b/src/bukkit/java/com/sk89q/worldedit/bukkit/BukkitWorld.java @@ -22,8 +22,6 @@ package com.sk89q.worldedit.bukkit; import com.sk89q.worldedit.BiomeType; import com.sk89q.worldedit.BlockVector2D; import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.EntityType; -import com.sk89q.worldedit.LocalEntity; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector2D; @@ -35,12 +33,10 @@ import com.sk89q.worldedit.blocks.LazyBlock; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.util.Enums; import com.sk89q.worldedit.util.TreeGenerator; import com.sk89q.worldedit.world.registry.LegacyWorldData; import com.sk89q.worldedit.world.registry.WorldData; import org.bukkit.Effect; -import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.TreeType; import org.bukkit.World; @@ -48,24 +44,7 @@ import org.bukkit.block.Biome; import org.bukkit.block.Block; import org.bukkit.block.BlockState; import org.bukkit.block.Chest; -import org.bukkit.entity.Ambient; -import org.bukkit.entity.Animals; -import org.bukkit.entity.Boat; import org.bukkit.entity.Entity; -import org.bukkit.entity.ExperienceOrb; -import org.bukkit.entity.FallingBlock; -import org.bukkit.entity.Golem; -import org.bukkit.entity.Hanging; -import org.bukkit.entity.HumanEntity; -import org.bukkit.entity.Item; -import org.bukkit.entity.ItemFrame; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Minecart; -import org.bukkit.entity.Painting; -import org.bukkit.entity.Projectile; -import org.bukkit.entity.TNTPrimed; -import org.bukkit.entity.Tameable; -import org.bukkit.entity.Villager; import org.bukkit.inventory.DoubleChestInventory; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; @@ -75,11 +54,8 @@ import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.EnumMap; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; -import java.util.UUID; import java.util.logging.Level; import java.util.logging.Logger; @@ -88,8 +64,6 @@ import static com.google.common.base.Preconditions.checkNotNull; public class BukkitWorld extends LocalWorld { private static final Logger logger = WorldEdit.logger; - private static final org.bukkit.entity.EntityType tntMinecartType = - Enums.findByValue(org.bukkit.entity.EntityType.class, "MINECART_TNT"); private static final Map effects = new HashMap(); static { @@ -377,168 +351,6 @@ public class BukkitWorld extends LocalWorld { world.dropItemNaturally(BukkitUtil.toLocation(world, pt), bukkitItem); } - @Override - public int killMobs(Vector origin, double radius, int flags) { - World world = getWorld(); - - boolean killPets = (flags & KillFlags.PETS) != 0; - boolean killNPCs = (flags & KillFlags.NPCS) != 0; - boolean killAnimals = (flags & KillFlags.ANIMALS) != 0; - boolean withLightning = (flags & KillFlags.WITH_LIGHTNING) != 0; - boolean killGolems = (flags & KillFlags.GOLEMS) != 0; - boolean killAmbient = (flags & KillFlags.AMBIENT) != 0; - boolean killTagged = (flags & KillFlags.TAGGED) != 0; - - int num = 0; - double radiusSq = radius * radius; - - Location bukkitOrigin = BukkitUtil.toLocation(world, origin); - - for (LivingEntity ent : world.getLivingEntities()) { - if (ent instanceof HumanEntity) { - continue; - } - - if (!killAnimals && ent instanceof Animals) { - continue; - } - - if (!killPets && ent instanceof Tameable && ((Tameable) ent).isTamed()) { - continue; // tamed pet - } - - if (!killGolems && ent instanceof Golem) { - continue; - } - - if (!killNPCs && ent instanceof Villager) { - continue; - } - - if (!killAmbient && ent instanceof Ambient) { - continue; - } - - if (!killTagged && isTagged(ent)) { - continue; - } - - if (radius < 0 || bukkitOrigin.distanceSquared(ent.getLocation()) <= radiusSq) { - if (withLightning) { - world.strikeLightningEffect(ent.getLocation()); - } - ent.remove(); - ++num; - } - } - - return num; - } - - private static boolean isTagged(LivingEntity ent) { - return ent.getCustomName() != null; - } - - /** - * Remove entities in an area. - * - * @param origin - * @param radius - * @return - */ - @Override - public int removeEntities(EntityType type, Vector origin, int radius) { - World world = getWorld(); - - int num = 0; - double radiusSq = Math.pow(radius, 2); - - for (Entity ent : world.getEntities()) { - if (radius != -1 - && origin.distanceSq(BukkitUtil.toVector(ent.getLocation())) > radiusSq) { - continue; - } - - switch (type) { - case ALL: - if (ent instanceof Projectile || ent instanceof Boat || ent instanceof Item - || ent instanceof FallingBlock || ent instanceof Minecart || ent instanceof Hanging - || ent instanceof TNTPrimed || ent instanceof ExperienceOrb) { - ent.remove(); - num++; - } - break; - - case PROJECTILES: - case ARROWS: - if (ent instanceof Projectile) { - // covers: arrow, egg, enderpearl, fireball, fish, snowball, throwpotion, thrownexpbottle - ent.remove(); - ++num; - } - break; - - case BOATS: - if (ent instanceof Boat) { - ent.remove(); - ++num; - } - break; - - case ITEMS: - if (ent instanceof Item) { - ent.remove(); - ++num; - } - break; - - case FALLING_BLOCKS: - if (ent instanceof FallingBlock) { - ent.remove(); - ++num; - } - break; - - case MINECARTS: - if (ent instanceof Minecart) { - ent.remove(); - ++num; - } - break; - - case PAINTINGS: - if (ent instanceof Painting) { - ent.remove(); - ++num; - } - break; - - case ITEM_FRAMES: - if (ent instanceof ItemFrame) { - ent.remove(); - ++num; - } - break; - - case TNT: - if (ent instanceof TNTPrimed || ent.getType() == tntMinecartType) { - ent.remove(); - ++num; - } - break; - - case XP_ORBS: - if (ent instanceof ExperienceOrb) { - ent.remove(); - ++num; - } - break; - } - } - - return num; - } - @SuppressWarnings("deprecation") @Override public boolean isValidBlockType(int type) { @@ -609,24 +421,6 @@ public class BukkitWorld extends LocalWorld { getWorld().getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()).breakNaturally(); } - @Override - public int killEntities(LocalEntity... entities) { - World world = getWorld(); - - int amount = 0; - Set toKill = new HashSet(); - for (LocalEntity entity : entities) { - toKill.add(((com.sk89q.worldedit.bukkit.entity.BukkitEntity) entity).getEntityId()); - } - for (Entity entity : world.getEntities()) { - if (toKill.contains(entity.getUniqueId())) { - entity.remove(); - ++amount; - } - } - return amount; - } - @Override public BaseBlock getBlock(Vector position) { BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter(); diff --git a/src/forge/java/com/sk89q/worldedit/forge/ForgeEntity.java b/src/forge/java/com/sk89q/worldedit/forge/ForgeEntity.java index 750d1a4b1..cf96d9400 100644 --- a/src/forge/java/com/sk89q/worldedit/forge/ForgeEntity.java +++ b/src/forge/java/com/sk89q/worldedit/forge/ForgeEntity.java @@ -22,14 +22,14 @@ package com.sk89q.worldedit.forge; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.entity.metadata.EntityType; import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.internal.helper.MCDirections; -import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.util.Location; -import net.minecraft.entity.EntityHanging; import net.minecraft.entity.EntityList; import net.minecraft.nbt.NBTTagCompound; +import javax.annotation.Nullable; + import static com.google.common.base.Preconditions.checkNotNull; class ForgeEntity implements Entity { @@ -41,6 +41,15 @@ class ForgeEntity implements Entity { this.entity = entity; } + /** + * Return the underlying entity. + * + * @return the underlying entity + */ + net.minecraft.entity.Entity getEntity() { + return entity; + } + @Override public BaseEntity getState() { String id = EntityList.getEntityString(entity); @@ -73,4 +82,14 @@ class ForgeEntity implements Entity { return true; } + @SuppressWarnings("unchecked") + @Nullable + @Override + public T getFacet(Class cls) { + if (EntityType.class.isAssignableFrom(cls)) { + return (T) new ForgeEntityType(entity); + } else { + return null; + } + } } diff --git a/src/forge/java/com/sk89q/worldedit/forge/ForgeEntityType.java b/src/forge/java/com/sk89q/worldedit/forge/ForgeEntityType.java new file mode 100644 index 000000000..a2fc3952e --- /dev/null +++ b/src/forge/java/com/sk89q/worldedit/forge/ForgeEntityType.java @@ -0,0 +1,138 @@ +/* + * 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.forge; + +import com.sk89q.worldedit.entity.metadata.EntityType; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.IMerchant; +import net.minecraft.entity.INpc; +import net.minecraft.entity.IProjectile; +import net.minecraft.entity.item.EntityBoat; +import net.minecraft.entity.item.EntityEnderEye; +import net.minecraft.entity.item.EntityFallingSand; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.item.EntityItemFrame; +import net.minecraft.entity.item.EntityMinecart; +import net.minecraft.entity.item.EntityPainting; +import net.minecraft.entity.item.EntityTNTPrimed; +import net.minecraft.entity.item.EntityXPOrb; +import net.minecraft.entity.monster.EntityGolem; +import net.minecraft.entity.passive.EntityAmbientCreature; +import net.minecraft.entity.passive.EntityTameable; +import net.minecraft.entity.passive.IAnimals; +import net.minecraft.entity.player.EntityPlayer; + +import static com.google.common.base.Preconditions.checkNotNull; + +public class ForgeEntityType implements EntityType { + + private final Entity entity; + + public ForgeEntityType(Entity entity) { + checkNotNull(entity); + this.entity = entity; + } + + @Override + public boolean isPlayerDerived() { + return entity instanceof EntityPlayer; + } + + @Override + public boolean isProjectile() { + return entity instanceof EntityEnderEye || entity instanceof IProjectile; + } + + @Override + public boolean isItem() { + return entity instanceof EntityItem; + } + + @Override + public boolean isFallingBlock() { + return entity instanceof EntityFallingSand; + } + + @Override + public boolean isPainting() { + return entity instanceof EntityPainting; + } + + @Override + public boolean isItemFrame() { + return entity instanceof EntityItemFrame; + } + + @Override + public boolean isBoat() { + return entity instanceof EntityBoat; + } + + @Override + public boolean isMinecart() { + return entity instanceof EntityMinecart; + } + + @Override + public boolean isTNT() { + return entity instanceof EntityTNTPrimed; + } + + @Override + public boolean isExperienceOrb() { + return entity instanceof EntityXPOrb; + } + + @Override + public boolean isLiving() { + return entity instanceof EntityLiving; + } + + @Override + public boolean isAnimal() { + return entity instanceof IAnimals; + } + + @Override + public boolean isAmbient() { + return entity instanceof EntityAmbientCreature; + } + + @Override + public boolean isNPC() { + return entity instanceof INpc || entity instanceof IMerchant; + } + + @Override + public boolean isGolem() { + return entity instanceof EntityGolem; + } + + @Override + public boolean isTamed() { + return entity instanceof EntityTameable && ((EntityTameable) entity).isTamed(); + } + + @Override + public boolean isTagged() { + return entity instanceof EntityLiving && ((EntityLiving) entity).hasCustomNameTag(); + } +} diff --git a/src/forge/java/com/sk89q/worldedit/forge/ForgePlayer.java b/src/forge/java/com/sk89q/worldedit/forge/ForgePlayer.java index d1ce05924..10e4af4a5 100644 --- a/src/forge/java/com/sk89q/worldedit/forge/ForgePlayer.java +++ b/src/forge/java/com/sk89q/worldedit/forge/ForgePlayer.java @@ -20,10 +20,10 @@ package com.sk89q.worldedit.forge; import com.sk89q.util.StringUtil; -import com.sk89q.worldedit.LocalPlayer; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldVector; import com.sk89q.worldedit.entity.BaseEntity; +import com.sk89q.worldedit.extension.platform.AbstractPlayerActor; import com.sk89q.worldedit.extent.inventory.BlockBag; import com.sk89q.worldedit.internal.LocalWorldAdapter; import com.sk89q.worldedit.internal.cui.CUIEvent; @@ -33,7 +33,10 @@ import net.minecraft.item.ItemStack; import net.minecraft.network.packet.Packet250CustomPayload; import net.minecraft.util.ChatMessageComponent; -public class ForgePlayer extends LocalPlayer { +import javax.annotation.Nullable; + +public class ForgePlayer extends AbstractPlayerActor { + private EntityPlayerMP player; protected ForgePlayer(EntityPlayerMP player) { @@ -133,4 +136,11 @@ public class ForgePlayer extends LocalPlayer { public boolean hasPermission(String perm) { return ForgeUtil.hasPermission(this.player, perm); } + + @Nullable + @Override + public T getFacet(Class cls) { + return null; + } + } \ No newline at end of file diff --git a/src/forge/java/com/sk89q/worldedit/forge/ForgeWorld.java b/src/forge/java/com/sk89q/worldedit/forge/ForgeWorld.java index 11576145e..8b1f2c563 100644 --- a/src/forge/java/com/sk89q/worldedit/forge/ForgeWorld.java +++ b/src/forge/java/com/sk89q/worldedit/forge/ForgeWorld.java @@ -22,7 +22,6 @@ package com.sk89q.worldedit.forge; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.BiomeType; import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.EntityType; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector2D; @@ -33,34 +32,15 @@ import com.sk89q.worldedit.blocks.LazyBlock; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.internal.Constants; -import com.sk89q.worldedit.internal.helper.MCDirections; import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.util.Direction; -import com.sk89q.worldedit.util.Direction.Flag; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.TreeGenerator.TreeType; import com.sk89q.worldedit.world.AbstractWorld; import com.sk89q.worldedit.world.registry.LegacyWorldData; import com.sk89q.worldedit.world.registry.WorldData; import net.minecraft.block.Block; -import net.minecraft.entity.EntityHanging; import net.minecraft.entity.EntityList; -import net.minecraft.entity.EntityLiving; -import net.minecraft.entity.IProjectile; -import net.minecraft.entity.item.EntityBoat; -import net.minecraft.entity.item.EntityEnderEye; -import net.minecraft.entity.item.EntityFallingSand; import net.minecraft.entity.item.EntityItem; -import net.minecraft.entity.item.EntityItemFrame; -import net.minecraft.entity.item.EntityMinecart; -import net.minecraft.entity.item.EntityPainting; -import net.minecraft.entity.item.EntityTNTPrimed; -import net.minecraft.entity.item.EntityXPOrb; -import net.minecraft.entity.monster.EntityGolem; -import net.minecraft.entity.passive.EntityAmbientCreature; -import net.minecraft.entity.passive.EntityAnimal; -import net.minecraft.entity.passive.EntityTameable; -import net.minecraft.entity.passive.EntityVillager; import net.minecraft.inventory.IInventory; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; @@ -224,7 +204,7 @@ public class ForgeWorld extends AbstractWorld { checkNotNull(position); checkNotNull(item); - if ((item == null) || (item.getType() == 0)) { + if (item.getType() == 0) { return; } @@ -233,121 +213,6 @@ public class ForgeWorld extends AbstractWorld { getWorld().spawnEntityInWorld(entity); } - @Override - @SuppressWarnings({"unchecked", "ConstantConditions"}) - public int killMobs(Vector origin, double radius, int flags) { - boolean killPets = (flags & 0x1) != 0; - boolean killNPCs = (flags & 0x2) != 0; - boolean killAnimals = (flags & 0x4) != 0; - - boolean killGolems = (flags & 0x8) != 0; - boolean killAmbient = (flags & 0x10) != 0; - - int num = 0; - double radiusSq = radius * radius; - - for (net.minecraft.entity.Entity obj : (Iterable) getWorld().loadedEntityList) { - if ((obj instanceof EntityLiving)) { - EntityLiving ent = (EntityLiving) obj; - - if (!killAnimals && ent instanceof EntityAnimal) { - continue; - } - - if (!killPets && ent instanceof EntityTameable && ((EntityTameable) ent).isTamed()) { - continue; // tamed pet - } - - if (!killGolems && ent instanceof EntityGolem) { - continue; - } - - if (!killNPCs && ent instanceof EntityVillager) { - continue; - } - - if (!killAmbient && ent instanceof EntityAmbientCreature) { - continue; - } - - if ((radius < 0.0D) || (origin.distanceSq(new Vector(ent.posX, ent.posY, ent.posZ)) <= radiusSq)) { - ent.isDead = true; - num++; - } - } - } - - return num; - } - - @Override - @SuppressWarnings("unchecked") - public int removeEntities(EntityType type, Vector origin, int radius) { - checkNotNull(type); - checkNotNull(origin); - - int num = 0; - double radiusSq = Math.pow(radius, 2.0D); - - for (net.minecraft.entity.Entity ent : (Iterable) getWorld().loadedEntityList) { - if ((radius != -1) && (origin.distanceSq(new Vector(ent.posX, ent.posY, ent.posZ)) > radiusSq)) { - continue; - } - if (type == EntityType.ALL) { - if (((ent instanceof EntityBoat)) || ((ent instanceof EntityItem)) || ((ent instanceof EntityFallingSand)) || ((ent instanceof EntityMinecart)) || ((ent instanceof EntityHanging)) || ((ent instanceof EntityTNTPrimed)) || ((ent instanceof EntityXPOrb)) || ((ent instanceof EntityEnderEye)) || ((ent instanceof IProjectile))) { - ent.isDead = true; - num++; - } - } else if ((type == EntityType.PROJECTILES) || (type == EntityType.ARROWS)) { - if (((ent instanceof EntityEnderEye)) || ((ent instanceof IProjectile))) { - ent.isDead = true; - num++; - } - } else if (type == EntityType.BOATS) { - if ((ent instanceof EntityBoat)) { - ent.isDead = true; - num++; - } - } else if (type == EntityType.ITEMS) { - if ((ent instanceof EntityItem)) { - ent.isDead = true; - num++; - } - } else if (type == EntityType.FALLING_BLOCKS) { - if ((ent instanceof EntityFallingSand)) { - ent.isDead = true; - num++; - } - } else if (type == EntityType.MINECARTS) { - if ((ent instanceof EntityMinecart)) { - ent.isDead = true; - num++; - } - } else if (type == EntityType.PAINTINGS) { - if ((ent instanceof EntityPainting)) { - ent.isDead = true; - num++; - } - } else if (type == EntityType.ITEM_FRAMES) { - if ((ent instanceof EntityItemFrame)) { - ent.isDead = true; - num++; - } - } else if (type == EntityType.TNT) { - if ((ent instanceof EntityTNTPrimed)) { - ent.isDead = true; - num++; - } - } else if ((type == EntityType.XP_ORBS) && ((ent instanceof EntityXPOrb))) { - ent.isDead = true; - num++; - } - - } - - return num; - } - @Override public boolean regenerate(Region region, EditSession editSession) { BaseBlock[] history = new BaseBlock[256 * (getMaxY() + 1)]; diff --git a/src/main/java/com/sk89q/worldedit/LocalWorld.java b/src/main/java/com/sk89q/worldedit/LocalWorld.java index 3cf1cf170..ae1112b95 100644 --- a/src/main/java/com/sk89q/worldedit/LocalWorld.java +++ b/src/main/java/com/sk89q/worldedit/LocalWorld.java @@ -33,24 +33,6 @@ import com.sk89q.worldedit.world.World; @Deprecated public abstract class LocalWorld extends AbstractWorld { - /** - * Named flags to use as parameters to {@link LocalWorld#killMobs(Vector, double, int)} - */ - @SuppressWarnings("PointlessBitwiseExpression") - public final class KillFlags { - public static final int PETS = 1 << 0; - public static final int NPCS = 1 << 1; - public static final int ANIMALS = 1 << 2; - public static final int GOLEMS = 1 << 3; - public static final int AMBIENT = 1 << 4; - public static final int TAGGED = 1 << 5; - public static final int FRIENDLY = PETS | NPCS | ANIMALS | GOLEMS | AMBIENT | TAGGED; - public static final int WITH_LIGHTNING = 1 << 20; - - private KillFlags() { - } - } - @Override public BaseBlock getLazyBlock(Vector position) { return getBlock(position); diff --git a/src/main/java/com/sk89q/worldedit/command/BrushCommands.java b/src/main/java/com/sk89q/worldedit/command/BrushCommands.java index 6f3d65062..1ce10523e 100644 --- a/src/main/java/com/sk89q/worldedit/command/BrushCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/BrushCommands.java @@ -25,13 +25,11 @@ import com.sk89q.minecraft.util.commands.CommandPermissions; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalSession; -import com.sk89q.worldedit.LocalWorld.KillFlags; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BlockID; -import com.sk89q.worldedit.command.UtilityCommands.FlagContainer; import com.sk89q.worldedit.command.tool.BrushTool; import com.sk89q.worldedit.command.tool.brush.ButcherBrush; import com.sk89q.worldedit.command.tool.brush.ClipboardBrush; @@ -41,6 +39,7 @@ import com.sk89q.worldedit.command.tool.brush.HollowCylinderBrush; import com.sk89q.worldedit.command.tool.brush.HollowSphereBrush; import com.sk89q.worldedit.command.tool.brush.SmoothBrush; import com.sk89q.worldedit.command.tool.brush.SphereBrush; +import com.sk89q.worldedit.command.util.CreatureButcher; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.function.mask.BlockMask; @@ -229,13 +228,21 @@ public class BrushCommands { @Command( aliases = { "butcher", "kill" }, - usage = "[radius] [command flags]", + usage = "[radius]", + flags = "plangbtf", desc = "Butcher brush", help = "Kills nearby mobs within the specified radius.\n" + - "Any number of 'flags' that the //butcher command uses\n" + - "may be specified as an argument", + "Flags:" + + " -p also kills pets.\n" + + " -n also kills NPCs.\n" + + " -g also kills Golems.\n" + + " -a also kills animals.\n" + + " -b also kills ambient mobs.\n" + + " -t also kills mobs with name tags.\n" + + " -f compounds all previous flags.\n" + + " -l currently does nothing.", min = 0, - max = 2 + max = 1 ) @CommandPermissions("worldedit.brush.butcher") public void butcherBrush(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { @@ -254,24 +261,13 @@ public class BrushCommands { return; } - FlagContainer flags = new FlagContainer(player); - if (args.argsLength() == 2) { - String flagString = args.getString(1); - // straight from the command, using contains instead of hasflag - flags.or(KillFlags.FRIENDLY , flagString.contains("f")); // No permission check here. Flags will instead be filtered by the subsequent calls. - flags.or(KillFlags.PETS , flagString.contains("p"), "worldedit.butcher.pets"); - flags.or(KillFlags.NPCS , flagString.contains("n"), "worldedit.butcher.npcs"); - flags.or(KillFlags.GOLEMS , flagString.contains("g"), "worldedit.butcher.golems"); - flags.or(KillFlags.ANIMALS , flagString.contains("a"), "worldedit.butcher.animals"); - flags.or(KillFlags.AMBIENT , flagString.contains("b"), "worldedit.butcher.ambient"); - flags.or(KillFlags.TAGGED , flagString.contains("t"), "worldedit.butcher.tagged"); - flags.or(KillFlags.WITH_LIGHTNING, flagString.contains("l"), "worldedit.butcher.lightning"); - } + CreatureButcher flags = new CreatureButcher(player); + flags.fromCommand(args); + BrushTool tool = session.getBrushTool(player.getItemInHand()); tool.setSize(radius); - tool.setBrush(new ButcherBrush(flags.flags), "worldedit.brush.butcher"); + tool.setBrush(new ButcherBrush(flags), "worldedit.brush.butcher"); - player.print(String.format("Butcher brush equipped (%.0f).", - radius)); + player.print(String.format("Butcher brush equipped (%.0f).", radius)); } } diff --git a/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java b/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java index d1e0852d8..5dd5cce8d 100644 --- a/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/UtilityCommands.java @@ -26,30 +26,35 @@ import com.sk89q.minecraft.util.commands.CommandException; import com.sk89q.minecraft.util.commands.CommandPermissions; import com.sk89q.minecraft.util.commands.Logging; import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.EntityType; import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalSession; -import com.sk89q.worldedit.LocalWorld.KillFlags; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.command.util.CreatureButcher; +import com.sk89q.worldedit.command.util.EntityRemover; +import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.extension.platform.Actor; +import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.extension.platform.CommandManager; +import com.sk89q.worldedit.extension.platform.Platform; +import com.sk89q.worldedit.function.operation.Operations; +import com.sk89q.worldedit.function.visitor.EntityVisitor; import com.sk89q.worldedit.internal.expression.Expression; import com.sk89q.worldedit.internal.expression.ExpressionException; import com.sk89q.worldedit.internal.expression.runtime.EvaluationException; import com.sk89q.worldedit.patterns.Pattern; import com.sk89q.worldedit.patterns.SingleBlockPattern; import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.regions.CylinderRegion; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.command.CommandCallable; import com.sk89q.worldedit.util.command.CommandMapping; import com.sk89q.worldedit.util.command.Dispatcher; import com.sk89q.worldedit.util.command.PrimaryAliasComparator; import com.sk89q.worldedit.util.command.binding.Text; -import com.sk89q.worldedit.util.command.parametric.Optional; import com.sk89q.worldedit.util.formatting.ColorCodeBuilder; import com.sk89q.worldedit.util.formatting.Style; import com.sk89q.worldedit.util.formatting.StyledFragment; @@ -374,7 +379,7 @@ public class UtilityCommands { " -b also kills ambient mobs.\n" + " -t also kills mobs with name tags.\n" + " -f compounds all previous flags.\n" + - " -l strikes lightning on each killed mob.", + " -l currently does nothing.", min = 0, max = 1 ) @@ -399,26 +404,37 @@ public class UtilityCommands { } } - FlagContainer flags = new FlagContainer(actor); - flags.or(KillFlags.FRIENDLY , args.hasFlag('f')); // No permission check here. Flags will instead be filtered by the subsequent calls. - flags.or(KillFlags.PETS , args.hasFlag('p'), "worldedit.butcher.pets"); - flags.or(KillFlags.NPCS , args.hasFlag('n'), "worldedit.butcher.npcs"); - flags.or(KillFlags.GOLEMS , args.hasFlag('g'), "worldedit.butcher.golems"); - flags.or(KillFlags.ANIMALS , args.hasFlag('a'), "worldedit.butcher.animals"); - flags.or(KillFlags.AMBIENT , args.hasFlag('b'), "worldedit.butcher.ambient"); - flags.or(KillFlags.TAGGED , args.hasFlag('t'), "worldedit.butcher.tagged"); - flags.or(KillFlags.WITH_LIGHTNING, args.hasFlag('l'), "worldedit.butcher.lightning"); - // If you add flags here, please add them to com.sk89q.worldedit.commands.BrushCommands.butcherBrush() as well + CreatureButcher flags = new CreatureButcher(actor); + flags.fromCommand(args); + + List visitors = new ArrayList(); + LocalSession session = null; + EditSession editSession = null; - int killed; if (player != null) { - LocalSession session = we.getSessionManager().get(player); - killed = player.getWorld().killMobs(session.getPlacementPosition(player), radius, flags.flags); - } else { - killed = 0; - for (World world : we.getServer().getWorlds()) { - killed += world.killMobs(new Vector(), radius, flags.flags); + session = we.getSessionManager().get(player); + Vector center = session.getPlacementPosition(player); + editSession = session.createEditSession(player); + List entities; + if (radius >= 0) { + CylinderRegion region = CylinderRegion.createRadius(editSession, center, radius); + entities = editSession.getEntities(region); + } else { + entities = editSession.getEntities(); } + visitors.add(new EntityVisitor(entities.iterator(), flags.createFunction(editSession.getWorld().getWorldData().getEntityRegistry()))); + } else { + Platform platform = we.getPlatformManager().queryCapability(Capability.WORLD_EDITING); + for (World world : platform.getWorlds()) { + List entities = world.getEntities(); + visitors.add(new EntityVisitor(entities.iterator(), flags.createFunction(world.getWorldData().getEntityRegistry()))); + } + } + + int killed = 0; + for (EntityVisitor visitor : visitors) { + Operations.completeLegacy(visitor); + killed += visitor.getAffected(); } if (radius < 0) { @@ -426,25 +442,10 @@ public class UtilityCommands { } else { actor.print("Killed " + killed + " mobs in a radius of " + radius + "."); } - } - public static class FlagContainer { - private final Actor player; - public int flags = 0; - public FlagContainer(Actor player) { - this.player = player; - } - - public void or(int flag, boolean on) { - if (on) flags |= flag; - } - - public void or(int flag, boolean on, String permission) { - or(flag, on); - - if ((flags & flag) != 0 && !player.hasPermission(permission)) { - flags &= ~flag; - } + if (editSession != null) { + session.remember(editSession); + editSession.flushQueue(); } } @@ -457,56 +458,55 @@ public class UtilityCommands { ) @CommandPermissions("worldedit.remove") @Logging(PLACEMENT) - public void remove(Actor actor, @Optional Player player, @Optional LocalSession session, CommandContext args) throws WorldEditException { - + public void remove(Actor actor, CommandContext args) throws WorldEditException, CommandException { String typeStr = args.getString(0); int radius = args.getInteger(1); + Player player = actor instanceof Player ? (Player) actor : null; if (radius < -1) { actor.printError("Use -1 to remove all entities in loaded chunks"); return; } - EntityType type = null; + EntityRemover remover = new EntityRemover(); + remover.fromString(typeStr); - if (typeStr.matches("all")) { - type = EntityType.ALL; - } else if (typeStr.matches("projectiles?|arrows?")) { - type = EntityType.PROJECTILES; - } else if (typeStr.matches("items?") - || typeStr.matches("drops?")) { - type = EntityType.ITEMS; - } else if (typeStr.matches("falling(blocks?|sand|gravel)")) { - type = EntityType.FALLING_BLOCKS; - } else if (typeStr.matches("paintings?") - || typeStr.matches("art")) { - type = EntityType.PAINTINGS; - } else if (typeStr.matches("(item)frames?")) { - type = EntityType.ITEM_FRAMES; - } else if (typeStr.matches("boats?")) { - type = EntityType.BOATS; - } else if (typeStr.matches("minecarts?") - || typeStr.matches("carts?")) { - type = EntityType.MINECARTS; - } else if (typeStr.matches("tnt")) { - type = EntityType.TNT; - } else if (typeStr.matches("xp")) { - type = EntityType.XP_ORBS; + List visitors = new ArrayList(); + LocalSession session = null; + EditSession editSession = null; + + if (player != null) { + session = we.getSessionManager().get(player); + Vector center = session.getPlacementPosition(player); + editSession = session.createEditSession(player); + List entities; + if (radius >= 0) { + CylinderRegion region = CylinderRegion.createRadius(editSession, center, radius); + entities = editSession.getEntities(region); + } else { + entities = editSession.getEntities(); + } + visitors.add(new EntityVisitor(entities.iterator(), remover.createFunction(editSession.getWorld().getWorldData().getEntityRegistry()))); } else { - actor.printError("Acceptable types: projectiles, items, paintings, itemframes, boats, minecarts, tnt, xp, or all"); - return; + Platform platform = we.getPlatformManager().queryCapability(Capability.WORLD_EDITING); + for (World world : platform.getWorlds()) { + List entities = world.getEntities(); + visitors.add(new EntityVisitor(entities.iterator(), remover.createFunction(world.getWorldData().getEntityRegistry()))); + } } int removed = 0; - if (player != null) { - Vector origin = session.getPlacementPosition(player); - removed = player.getWorld().removeEntities(type, origin, radius); - } else { - for (World world : we.getServer().getWorlds()) { - removed += world.removeEntities(type, new Vector(), radius); - } + for (EntityVisitor visitor : visitors) { + Operations.completeLegacy(visitor); + removed += visitor.getAffected(); + } + + actor.print("Marked " + (removed != 1 ? "entities" : "entity") + " for removal."); + + if (editSession != null) { + session.remember(editSession); + editSession.flushQueue(); } - player.print("Marked " + removed + " entit(ies) for removal."); } @Command( diff --git a/src/main/java/com/sk89q/worldedit/command/tool/brush/ButcherBrush.java b/src/main/java/com/sk89q/worldedit/command/tool/brush/ButcherBrush.java index 1a8e4f9cd..637be6d2f 100644 --- a/src/main/java/com/sk89q/worldedit/command/tool/brush/ButcherBrush.java +++ b/src/main/java/com/sk89q/worldedit/command/tool/brush/ButcherBrush.java @@ -22,19 +22,28 @@ package com.sk89q.worldedit.command.tool.brush; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.command.util.CreatureButcher; +import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.function.operation.Operations; import com.sk89q.worldedit.function.pattern.Pattern; +import com.sk89q.worldedit.function.visitor.EntityVisitor; +import com.sk89q.worldedit.regions.CylinderRegion; + +import java.util.List; public class ButcherBrush implements Brush { - private int flags; + private CreatureButcher flags; - public ButcherBrush(int flags) { + public ButcherBrush(CreatureButcher flags) { this.flags = flags; } @Override public void build(EditSession editSession, Vector pos, Pattern mat, double size) throws MaxChangedBlocksException { - editSession.getWorld().killMobs(pos, size, flags); + CylinderRegion region = CylinderRegion.createRadius(editSession, pos, size); + List entities = editSession.getEntities(region); + Operations.completeLegacy(new EntityVisitor(entities.iterator(), flags.createFunction(editSession.getWorld().getWorldData().getEntityRegistry()))); } } diff --git a/src/main/java/com/sk89q/worldedit/command/util/CreatureButcher.java b/src/main/java/com/sk89q/worldedit/command/util/CreatureButcher.java new file mode 100644 index 000000000..822389bbe --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/command/util/CreatureButcher.java @@ -0,0 +1,135 @@ +/* + * 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.command.util; + +import com.sk89q.minecraft.util.commands.CommandContext; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.entity.metadata.EntityType; +import com.sk89q.worldedit.extension.platform.Actor; +import com.sk89q.worldedit.function.EntityFunction; +import com.sk89q.worldedit.world.registry.EntityRegistry; + +/** + * The implementation of /butcher. + */ +public class CreatureButcher { + + final class Flags { + @SuppressWarnings("PointlessBitwiseExpression") + public static final int PETS = 1 << 0; + public static final int NPCS = 1 << 1; + public static final int ANIMALS = 1 << 2; + public static final int GOLEMS = 1 << 3; + public static final int AMBIENT = 1 << 4; + public static final int TAGGED = 1 << 5; + public static final int FRIENDLY = PETS | NPCS | ANIMALS | GOLEMS | AMBIENT | TAGGED; + public static final int WITH_LIGHTNING = 1 << 20; + + private Flags() { + } + } + + private final Actor player; + public int flags = 0; + + public CreatureButcher(Actor player) { + this.player = player; + } + + public void or(int flag, boolean on) { + if (on) flags |= flag; + } + + public void or(int flag, boolean on, String permission) { + or(flag, on); + + if ((flags & flag) != 0 && !player.hasPermission(permission)) { + flags &= ~flag; + } + } + + public void fromCommand(CommandContext args) { + or(Flags.FRIENDLY , args.hasFlag('f')); // No permission check here. Flags will instead be filtered by the subsequent calls. + or(Flags.PETS , args.hasFlag('p'), "worldedit.butcher.pets"); + or(Flags.NPCS , args.hasFlag('n'), "worldedit.butcher.npcs"); + or(Flags.GOLEMS , args.hasFlag('g'), "worldedit.butcher.golems"); + or(Flags.ANIMALS , args.hasFlag('a'), "worldedit.butcher.animals"); + or(Flags.AMBIENT , args.hasFlag('b'), "worldedit.butcher.ambient"); + or(Flags.TAGGED , args.hasFlag('t'), "worldedit.butcher.tagged"); + or(Flags.WITH_LIGHTNING, args.hasFlag('l'), "worldedit.butcher.lightning"); + } + + public EntityFunction createFunction(final EntityRegistry entityRegistry) { + return new EntityFunction() { + @Override + public boolean apply(Entity entity) throws WorldEditException { + boolean killPets = (flags & Flags.PETS) != 0; + boolean killNPCs = (flags & Flags.NPCS) != 0; + boolean killAnimals = (flags & Flags.ANIMALS) != 0; + boolean killGolems = (flags & Flags.GOLEMS) != 0; + boolean killAmbient = (flags & Flags.AMBIENT) != 0; + boolean killTagged = (flags & Flags.TAGGED) != 0; + + EntityType type = entity.getFacet(EntityType.class); + + if (type == null) { + return false; + } + + if (type.isPlayerDerived()) { + return false; + } + + if (!type.isLiving()) { + return false; + } + + if (!killAnimals && type.isAnimal()) { + return false; + } + + if (!killPets && type.isTamed()) { + return false; + } + + if (!killGolems && type.isGolem()) { + return false; + } + + if (!killNPCs && type.isNPC()) { + return false; + } + + if (!killAmbient && type.isAmbient()) { + return false; + } + + if (!killTagged && type.isTagged()) { + return false; + } + + entity.remove(); + return true; + } + }; + } + +} diff --git a/src/main/java/com/sk89q/worldedit/command/util/EntityRemover.java b/src/main/java/com/sk89q/worldedit/command/util/EntityRemover.java new file mode 100644 index 000000000..b6459b186 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/command/util/EntityRemover.java @@ -0,0 +1,160 @@ +/* + * 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.command.util; + +import com.sk89q.minecraft.util.commands.CommandException; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.entity.metadata.EntityType; +import com.sk89q.worldedit.function.EntityFunction; +import com.sk89q.worldedit.world.registry.EntityRegistry; + +import javax.annotation.Nullable; +import java.util.regex.Pattern; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * The implementation of /remove. + */ +public class EntityRemover { + + public enum Type { + ALL("all") { + @Override + boolean matches(EntityType type) { + for (Type value : values()) { + if (value != this && value.matches(type)) { + return true; + } + } + return false; + } + }, + PROJECTILES("projectiles?|arrows?") { + @Override + boolean matches(EntityType type) { + return type.isProjectile(); + } + }, + ITEMS("items?|drops?") { + @Override + boolean matches(EntityType type) { + return type.isItem(); + } + }, + FALLING_BLOCKS("falling(blocks?|sand|gravel)") { + @Override + boolean matches(EntityType type) { + return type.isFallingBlock(); + } + }, + PAINTINGS("paintings?|art") { + @Override + boolean matches(EntityType type) { + return type.isPainting(); + } + }, + ITEM_FRAMES("(item)frames?") { + @Override + boolean matches(EntityType type) { + return type.isItemFrame(); + } + }, + BOATS("boats?") { + @Override + boolean matches(EntityType type) { + return type.isBoat(); + } + }, + MINECARTS("(mine)?carts?") { + @Override + boolean matches(EntityType type) { + return type.isMinecart(); + } + }, + TNT("tnt") { + @Override + boolean matches(EntityType type) { + return type.isTNT(); + } + }, + XP_ORBS("xp") { + @Override + boolean matches(EntityType type) { + return type.isExperienceOrb(); + } + }; + + private final Pattern pattern; + + Type(String pattern) { + this.pattern = Pattern.compile(pattern); + } + + public boolean matches(String str) { + return pattern.matcher(str).matches(); + } + + abstract boolean matches(EntityType type); + + @Nullable + public static Type findByPattern(String str) { + for (Type type : values()) { + if (type.matches(str)) { + return type; + } + } + + return null; + } + } + + private Type type; + + public void fromString(String str) throws CommandException { + Type type = Type.findByPattern(str); + if (type != null) { + this.type = type; + } else { + throw new CommandException("Acceptable types: projectiles, items, paintings, itemframes, boats, minecarts, tnt, xp, or all"); + } + } + + public EntityFunction createFunction(final EntityRegistry entityRegistry) { + final Type type = this.type; + checkNotNull("type can't be null", type); + return new EntityFunction() { + @Override + public boolean apply(Entity entity) throws WorldEditException { + EntityType registryType = entity.getFacet(EntityType.class); + if (registryType != null) { + if (type.matches(registryType)) { + entity.remove(); + return true; + } + } + + return false; + } + }; + } + +} diff --git a/src/main/java/com/sk89q/worldedit/entity/BaseEntity.java b/src/main/java/com/sk89q/worldedit/entity/BaseEntity.java index b1f8b0a91..4f6c40731 100644 --- a/src/main/java/com/sk89q/worldedit/entity/BaseEntity.java +++ b/src/main/java/com/sk89q/worldedit/entity/BaseEntity.java @@ -43,6 +43,15 @@ public class BaseEntity implements NbtValued { setNbtData(nbtData); } + /** + * Create a new base entity with no NBT data. + * + * @param id the entity type ID + */ + public BaseEntity(String id) { + setTypeId(id); + } + /** * Make a clone of a {@link BaseEntity}. * diff --git a/src/main/java/com/sk89q/worldedit/entity/Entity.java b/src/main/java/com/sk89q/worldedit/entity/Entity.java index 7c6d68e7c..4224e5de7 100644 --- a/src/main/java/com/sk89q/worldedit/entity/Entity.java +++ b/src/main/java/com/sk89q/worldedit/entity/Entity.java @@ -20,6 +20,7 @@ package com.sk89q.worldedit.entity; import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.util.Faceted; import com.sk89q.worldedit.util.Location; import javax.annotation.Nullable; @@ -34,7 +35,7 @@ import javax.annotation.Nullable; * can then be used to spawn new instances of that particular entity * description. */ -public interface Entity { +public interface Entity extends Faceted { /** * Get a copy of the entity's state. diff --git a/src/main/java/com/sk89q/worldedit/entity/metadata/EntityType.java b/src/main/java/com/sk89q/worldedit/entity/metadata/EntityType.java new file mode 100644 index 000000000..a12225414 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/entity/metadata/EntityType.java @@ -0,0 +1,151 @@ +/* + * 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.entity.metadata; + +/** + * Describes various classes of entities. + */ +public interface EntityType { + + /** + * Test whether the entity is a player-derived entity. + * + * @return true if a player derived entity + */ + boolean isPlayerDerived(); + + /** + * Test whether the entity is a projectile. + * + * @return true if a projectile + */ + boolean isProjectile(); + + /** + * Test whether the entity is an item. + * + * @return true if an item + */ + boolean isItem(); + + /** + * Test whether the entity is a falling block. + * + * @return true if a falling block + */ + boolean isFallingBlock(); + + /** + * Test whether the entity is a painting. + * + * @return true if a painting + */ + boolean isPainting(); + + /** + * Test whether the entity is an item frame. + * + * @return true if an item frame + */ + boolean isItemFrame(); + + /** + * Test whether the entity is a boat. + * + * @return true if a boat + */ + boolean isBoat(); + + /** + * Test whether the entity is a minecart. + * + * @return true if a minecart + */ + boolean isMinecart(); + + /** + * Test whether the entity is a primed TNT block. + * + * @return true if TNT + */ + boolean isTNT(); + + /** + * Test whether the entity is an experience orb. + * + * @return true if an experience orb + */ + boolean isExperienceOrb(); + + /** + * Test whether the entity is a living entity. + * + *

A "living entity" is the superclass of many living entity classes + * in Minecraft.

+ * + * @return true if a living entity + */ + boolean isLiving(); + + /** + * Test whether the entity is an animal. + * + * @return true if an animal + */ + boolean isAnimal(); + + /** + * Test whether the entity is an ambient creature, which includes + * the bat. + * + * @return true if an ambient creature + */ + boolean isAmbient(); + + /** + * Test whether the entity is a non-player controlled character, which + * includes villagers, NPCs from mods, and so on. + * + * @return true if an NPC + */ + boolean isNPC(); + + /** + * Test whether the entity is the iron golem from Minecraft. + * + * @return true if an iron golem + */ + boolean isGolem(); + + /** + * Test whether the entity is tameable and is tamed. + * + * @return true if tamed + */ + boolean isTamed(); + + /** + * Test whether the entity has been named (tagged). + * + * @return true if named + */ + boolean isTagged(); + +} diff --git a/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java b/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java index 4aeb23d7a..b1d8979aa 100644 --- a/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java +++ b/src/main/java/com/sk89q/worldedit/extension/platform/PlayerProxy.java @@ -28,6 +28,8 @@ import com.sk89q.worldedit.internal.cui.CUIEvent; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.World; +import javax.annotation.Nullable; + import static com.google.common.base.Preconditions.checkNotNull; class PlayerProxy extends AbstractPlayerActor { @@ -137,4 +139,10 @@ class PlayerProxy extends AbstractPlayerActor { public void dispatchCUIEvent(CUIEvent event) { cuiActor.dispatchCUIEvent(event); } + + @Nullable + @Override + public T getFacet(Class cls) { + return basePlayer.getFacet(cls); + } } diff --git a/src/main/java/com/sk89q/worldedit/extent/ChangeSetExtent.java b/src/main/java/com/sk89q/worldedit/extent/ChangeSetExtent.java index 772d8ca57..84af07ab3 100644 --- a/src/main/java/com/sk89q/worldedit/extent/ChangeSetExtent.java +++ b/src/main/java/com/sk89q/worldedit/extent/ChangeSetExtent.java @@ -124,5 +124,11 @@ public class ChangeSetExtent extends AbstractDelegateExtent { } return success; } + + @Nullable + @Override + public T getFacet(Class cls) { + return entity.getFacet(cls); + } } } diff --git a/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java b/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java index 33be36453..43fa5597f 100644 --- a/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java +++ b/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java @@ -164,6 +164,12 @@ public class BlockArrayClipboard implements Clipboard { public boolean remove() { return entities.remove(this); } + + @Nullable + @Override + public T getFacet(Class cls) { + return null; + } } } diff --git a/src/main/java/com/sk89q/worldedit/internal/LocalWorldAdapter.java b/src/main/java/com/sk89q/worldedit/internal/LocalWorldAdapter.java index eba0423bc..2e5ab5c5d 100644 --- a/src/main/java/com/sk89q/worldedit/internal/LocalWorldAdapter.java +++ b/src/main/java/com/sk89q/worldedit/internal/LocalWorldAdapter.java @@ -22,8 +22,6 @@ package com.sk89q.worldedit.internal; import com.sk89q.worldedit.BiomeType; import com.sk89q.worldedit.BlockVector2D; import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.EntityType; -import com.sk89q.worldedit.LocalEntity; import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.Vector; @@ -135,33 +133,6 @@ public class LocalWorldAdapter extends LocalWorld { world.simulateBlockMine(position); } - @Override - public int killEntities(LocalEntity... entity) { - return world.killEntities(entity); - } - - @Override - @Deprecated - public int killMobs(Vector origin, int radius) { - return world.killMobs(origin, radius); - } - - @Override - @Deprecated - public int killMobs(Vector origin, int radius, boolean killPets) { - return world.killMobs(origin, radius, killPets); - } - - @Override - public int killMobs(Vector origin, double radius, int flags) { - return world.killMobs(origin, radius, flags); - } - - @Override - public int removeEntities(EntityType type, Vector origin, int radius) { - return world.removeEntities(type, origin, radius); - } - @Override public boolean regenerate(Region region, EditSession editSession) { return world.regenerate(region, editSession); diff --git a/src/main/java/com/sk89q/worldedit/regions/CylinderRegion.java b/src/main/java/com/sk89q/worldedit/regions/CylinderRegion.java index e6eea8cff..2e9a12817 100644 --- a/src/main/java/com/sk89q/worldedit/regions/CylinderRegion.java +++ b/src/main/java/com/sk89q/worldedit/regions/CylinderRegion.java @@ -19,7 +19,12 @@ package com.sk89q.worldedit.regions; -import com.sk89q.worldedit.*; +import com.sk89q.worldedit.BlockVector; +import com.sk89q.worldedit.BlockVector2D; +import com.sk89q.worldedit.LocalWorld; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.Vector2D; +import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.math.geom.Polygons; import com.sk89q.worldedit.regions.iterator.FlatRegion3DIterator; import com.sk89q.worldedit.regions.iterator.FlatRegionIterator; @@ -28,6 +33,8 @@ import com.sk89q.worldedit.world.World; import java.util.Iterator; import java.util.List; +import static com.google.common.base.Preconditions.checkNotNull; + /** * Represents a cylindrical region. * @@ -84,6 +91,23 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion { hasY = true; } + /** + * Construct the region. + * + * @param center the center position + * @param radius the radius along the X and Z axes + * @param minY the minimum Y, inclusive + * @param maxY the maximum Y, inclusive + */ + public CylinderRegion(Vector center, Vector2D radius, int minY, int maxY) { + super(null); + setCenter(center.toVector2D()); + setRadius(radius); + this.minY = minY; + this.maxY = maxY; + hasY = true; + } + public CylinderRegion(CylinderRegion region) { this(region.world, region.getCenter(), region.getRadius(), region.minY, region.maxY); hasY = region.hasY; @@ -377,4 +401,24 @@ public class CylinderRegion extends AbstractRegion implements FlatRegion { public List polygonize(int maxPoints) { return Polygons.polygonizeCylinder(center, radius, maxPoints); } + + /** + * Return a new instance with the given center and radius in the X and Z + * axes with a Y that extends from the bottom of the extent to the top + * of the extent. + * + * @param extent the extent + * @param center the center position + * @param radius the radius in the X and Z axes + * @return a region + */ + public static CylinderRegion createRadius(Extent extent, Vector center, double radius) { + checkNotNull(extent); + checkNotNull(center); + Vector2D radiusVec = new Vector2D(radius, radius); + int minY = extent.getMinimumPoint().getBlockY(); + int maxY = extent.getMaximumPoint().getBlockY(); + return new CylinderRegion(center, radiusVec, minY, maxY); + } + } diff --git a/src/main/java/com/sk89q/worldedit/util/Faceted.java b/src/main/java/com/sk89q/worldedit/util/Faceted.java new file mode 100644 index 000000000..2b54442b3 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/util/Faceted.java @@ -0,0 +1,52 @@ +/* + * 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.util; + +import com.sk89q.worldedit.entity.Entity; + +import javax.annotation.Nullable; + +/** + * Indicates that an object can provide various "facets," which are + * specific distinct interfaces that can represent a portion of the object. + * + *

For example, an instance of an {@link Entity} may have a facet + * for accessing its inventory (if it contains an inventory) or a facet + * for accessing its health (if it has health).

+ * + *

Facets are referred to by their interface or abstract class and + * it is dependent on the implementation of the object specifying this + * interface to return the most applicable implementation. However, in + * many cases, such an implementation may not apply or it has not been + * implemented so a request for a facet may return {@code null}.

+ */ +public interface Faceted { + + /** + * Get the facet corresponding to the given class or interface. + * + * @param cls the class or interface + * @param the type + * @return an implementation of the facet or {@code null} if one is unavailable + */ + @Nullable + T getFacet(Class cls); + +} diff --git a/src/main/java/com/sk89q/worldedit/util/collection/FastListIterator.java b/src/main/java/com/sk89q/worldedit/util/collection/FastListIterator.java index 1342b91eb..688ce9e55 100644 --- a/src/main/java/com/sk89q/worldedit/util/collection/FastListIterator.java +++ b/src/main/java/com/sk89q/worldedit/util/collection/FastListIterator.java @@ -104,7 +104,11 @@ public class FastListIterator implements Iterator { * @return an iterator */ public static Iterator reverseIterator(List list) { - return new FastListIterator(list, list.size() - 1, list.size(), -1); + if (!list.isEmpty()) { + return new FastListIterator(list, list.size() - 1, list.size(), -1); + } else { + return new FastListIterator(list, 0, 0, -1); + } } } diff --git a/src/main/java/com/sk89q/worldedit/world/AbstractWorld.java b/src/main/java/com/sk89q/worldedit/world/AbstractWorld.java index 95917043e..b51a1cac8 100644 --- a/src/main/java/com/sk89q/worldedit/world/AbstractWorld.java +++ b/src/main/java/com/sk89q/worldedit/world/AbstractWorld.java @@ -21,8 +21,6 @@ package com.sk89q.worldedit.world; import com.sk89q.worldedit.BlockVector2D; import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.LocalEntity; -import com.sk89q.worldedit.LocalWorld.KillFlags; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.WorldEditException; @@ -141,21 +139,6 @@ public abstract class AbstractWorld implements World { } } - @Override - public int killEntities(LocalEntity... entities) { - return 0; - } - - @Override - public int killMobs(Vector origin, int radius) { - return killMobs(origin, radius, false); - } - - @Override - public int killMobs(Vector origin, int radius, boolean killPets) { - return killMobs(origin, radius, killPets ? KillFlags.PETS : 0); - } - @Override public boolean generateTree(EditSession editSession, Vector pt) throws MaxChangedBlocksException { return generateTree(TreeType.TREE, editSession, pt); diff --git a/src/main/java/com/sk89q/worldedit/world/NullWorld.java b/src/main/java/com/sk89q/worldedit/world/NullWorld.java index a4f7a5eed..3b0854dc6 100644 --- a/src/main/java/com/sk89q/worldedit/world/NullWorld.java +++ b/src/main/java/com/sk89q/worldedit/world/NullWorld.java @@ -74,16 +74,6 @@ public class NullWorld extends AbstractWorld { public void dropItem(Vector position, BaseItemStack item) { } - @Override - public int killMobs(Vector origin, double radius, int flags) { - return 0; - } - - @Override - public int removeEntities(EntityType type, Vector origin, int radius) { - return 0; - } - @Override public boolean regenerate(Region region, EditSession editSession) { return false; diff --git a/src/main/java/com/sk89q/worldedit/world/World.java b/src/main/java/com/sk89q/worldedit/world/World.java index c11b1bf2d..bd2d13d1c 100644 --- a/src/main/java/com/sk89q/worldedit/world/World.java +++ b/src/main/java/com/sk89q/worldedit/world/World.java @@ -22,9 +22,6 @@ package com.sk89q.worldedit.world; import com.sk89q.worldedit.BiomeType; import com.sk89q.worldedit.BlockVector2D; import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.EntityType; -import com.sk89q.worldedit.LocalEntity; -import com.sk89q.worldedit.LocalWorld; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector2D; @@ -191,46 +188,6 @@ public interface World extends Extent { */ void simulateBlockMine(Vector position); - /** - * Kill the entities listed in the provided array. - * - * @param entity an array of entities - * @return the number of entities that were removed - */ - int killEntities(LocalEntity... entity); - - /** - * @deprecated Use {@link #killMobs(Vector, double, int)} - */ - @Deprecated - int killMobs(Vector origin, int radius); - - /** - * @deprecated Use {@link #killMobs(Vector, double, int)} - */ - @Deprecated - int killMobs(Vector origin, int radius, boolean killPets); - - /** - * Kill mobs at the given location with the given radius. - * - * @param origin the origin - * @param radius the radius - * @param flags kill flags (see {@link LocalWorld.KillFlags}) - * @return the number of mobs that were killed - */ - int killMobs(Vector origin, double radius, int flags); - - /** - * Remove entities in an area. - * - * @param type the type of entity - * @param origin the origin - * @param radius the radius - * @return the number of mobs that were killed - */ - int removeEntities(EntityType type, Vector origin, int radius); - /** * Regenerate an area. * diff --git a/src/main/java/com/sk89q/worldedit/world/registry/EntityRegistry.java b/src/main/java/com/sk89q/worldedit/world/registry/EntityRegistry.java new file mode 100644 index 000000000..787585327 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/world/registry/EntityRegistry.java @@ -0,0 +1,42 @@ +/* + * 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.world.registry; + +import com.sk89q.worldedit.entity.BaseEntity; +import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.entity.metadata.EntityType; + +import javax.annotation.Nullable; + +/** + * Provides information on entities. + */ +public interface EntityRegistry { + + /** + * Create a new entity using its ID. + * + * @param id the id + * @return the entity, which may be null if the entity does not exist + */ + @Nullable + BaseEntity createFromId(String id); + +} diff --git a/src/main/java/com/sk89q/worldedit/world/registry/LegacyWorldData.java b/src/main/java/com/sk89q/worldedit/world/registry/LegacyWorldData.java index 21ce1ad0d..bed5b401f 100644 --- a/src/main/java/com/sk89q/worldedit/world/registry/LegacyWorldData.java +++ b/src/main/java/com/sk89q/worldedit/world/registry/LegacyWorldData.java @@ -27,6 +27,7 @@ public final class LegacyWorldData implements WorldData { private static final LegacyWorldData INSTANCE = new LegacyWorldData(); private final LegacyBlockRegistry blockRegistry = new LegacyBlockRegistry(); + private final NullEntityRegistry entityRegistry = new NullEntityRegistry(); /** * Create a new instance. @@ -39,6 +40,11 @@ public final class LegacyWorldData implements WorldData { return blockRegistry; } + @Override + public EntityRegistry getEntityRegistry() { + return entityRegistry; + } + /** * Get a singleton instance. * diff --git a/src/main/java/com/sk89q/worldedit/EntityType.java b/src/main/java/com/sk89q/worldedit/world/registry/NullEntityRegistry.java similarity index 70% rename from src/main/java/com/sk89q/worldedit/EntityType.java rename to src/main/java/com/sk89q/worldedit/world/registry/NullEntityRegistry.java index 4b4f83438..b3eadcc10 100644 --- a/src/main/java/com/sk89q/worldedit/EntityType.java +++ b/src/main/java/com/sk89q/worldedit/world/registry/NullEntityRegistry.java @@ -1,37 +1,37 @@ -/* - * 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; - -/** - * List of removable entity types. - */ -public enum EntityType { - ALL, - @Deprecated ARROWS, - PROJECTILES, - ITEMS, - FALLING_BLOCKS, - PAINTINGS, - ITEM_FRAMES, - BOATS, - MINECARTS, - TNT, - XP_ORBS -} +/* + * 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.world.registry; + +import com.sk89q.worldedit.entity.BaseEntity; + +import javax.annotation.Nullable; + +/** + * An implementation of an entity registry that knows nothing. + */ +public class NullEntityRegistry implements EntityRegistry { + + @Nullable + @Override + public BaseEntity createFromId(String id) { + return null; + } + +} diff --git a/src/main/java/com/sk89q/worldedit/world/registry/WorldData.java b/src/main/java/com/sk89q/worldedit/world/registry/WorldData.java index 38bbe2a0e..d8bf886e6 100644 --- a/src/main/java/com/sk89q/worldedit/world/registry/WorldData.java +++ b/src/main/java/com/sk89q/worldedit/world/registry/WorldData.java @@ -32,4 +32,11 @@ public interface WorldData { */ BlockRegistry getBlockRegistry(); + /** + * Get the entity registry. + * + * @return the entity registry + */ + EntityRegistry getEntityRegistry(); + }