From 973f763605ed6c45cbbd20eb9b3500299aed920e Mon Sep 17 00:00:00 2001 From: CraftBukkit/Spigot Date: Wed, 18 Aug 2021 18:04:53 +1000 Subject: [PATCH] #914: Add World#spawn with randomizeData parameter The current implementation of World#spawn or World#spawnEntity respectively, always prepares/finalizes the spawn of every entity spawned through the API. While this is great to simulate natural spawning of entities in the world through the API, it fails at reliably creating default entities for purposes other than vanilla gameplay. While the caller of the API could attempt to undo all of the customization that is applied in the prepare/finalization step, they are numerous (reaching from sheep colour to equipment) and in some cases, such as the chicken jockey, even spawn in other entities. Hence this commit introduces a new overload to the World#spawn and World#spawnEntity methods that accepts the 'randomizeData' parameter that, when set to false, skips the prior mentioned preparation/finalization step. By: Bjarne Koll --- .../craftbukkit/CraftRegionAccessor.java | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java index 039e5dfd7a..f1af8a5b5c 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java @@ -380,6 +380,11 @@ public abstract class CraftRegionAccessor implements RegionAccessor { return spawn(location, entityType.getEntityClass()); } + @Override + public Entity spawnEntity(Location loc, EntityType type, boolean randomizeData) { + return spawn(loc, type.getEntityClass(), null, CreatureSpawnEvent.SpawnReason.CUSTOM, randomizeData); + } + @Override public List getEntities() { List list = new ArrayList(); @@ -472,22 +477,31 @@ public abstract class CraftRegionAccessor implements RegionAccessor { return spawn(location, clazz, function, CreatureSpawnEvent.SpawnReason.CUSTOM); } + @Override + public T spawn(Location location, Class clazz, boolean randomizeData, Consumer function) throws IllegalArgumentException { + return spawn(location, clazz, function, CreatureSpawnEvent.SpawnReason.CUSTOM, randomizeData); + } + public T spawn(Location location, Class clazz, Consumer function, CreatureSpawnEvent.SpawnReason reason) throws IllegalArgumentException { + return spawn(location, clazz, function, reason, true); + } + + public T spawn(Location location, Class clazz, Consumer function, CreatureSpawnEvent.SpawnReason reason, boolean randomizeData) throws IllegalArgumentException { net.minecraft.world.entity.Entity entity = createEntity(location, clazz); - return addEntity(entity, reason, function); + return addEntity(entity, reason, function, randomizeData); } @SuppressWarnings("unchecked") public T addEntity(net.minecraft.world.entity.Entity entity, CreatureSpawnEvent.SpawnReason reason) throws IllegalArgumentException { - return addEntity(entity, reason, null); + return addEntity(entity, reason, null, true); } @SuppressWarnings("unchecked") - public T addEntity(net.minecraft.world.entity.Entity entity, CreatureSpawnEvent.SpawnReason reason, Consumer function) throws IllegalArgumentException { + public T addEntity(net.minecraft.world.entity.Entity entity, CreatureSpawnEvent.SpawnReason reason, Consumer function, boolean randomizeData) throws IllegalArgumentException { Preconditions.checkArgument(entity != null, "Cannot spawn null entity"); - if (entity instanceof EntityInsentient) { + if (randomizeData && entity instanceof EntityInsentient) { ((EntityInsentient) entity).prepare(getHandle(), getHandle().getDamageScaler(entity.getChunkCoordinates()), EnumMobSpawn.COMMAND, (GroupDataEntity) null, null); }