From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Aikar Date: Sun, 24 Mar 2019 00:24:52 -0400 Subject: [PATCH] Entity#getEntitySpawnReason Allows you to return the SpawnReason for why an Entity Spawned Pre existing entities will return NATURAL if it was a non persistenting Living Entity, SPAWNER for spawners, or DEFAULT since data was not stored. diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java index 00c57501f80fd0988573b36cd7e75a343c7e8e6e..1dbeda9fb385be29b3bb20c33a0487334c6e7c16 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java @@ -72,6 +72,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } }; List entitySlice = null; + public org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason; // Paper end public com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData; // Paper @@ -1587,6 +1588,9 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke if (this.origin != null) { nbttagcompound.set("Paper.Origin", this.createList(origin.getX(), origin.getY(), origin.getZ())); } + if (spawnReason != null) { + nbttagcompound.setString("Paper.SpawnReason", spawnReason.name()); + } // Save entity's from mob spawner status if (spawnedViaMobSpawner) { nbttagcompound.setBoolean("Paper.FromMobSpawner", true); @@ -1721,6 +1725,26 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke } spawnedViaMobSpawner = nbttagcompound.getBoolean("Paper.FromMobSpawner"); // Restore entity's from mob spawner status + if (nbttagcompound.hasKey("Paper.SpawnReason")) { + String spawnReasonName = nbttagcompound.getString("Paper.SpawnReason"); + try { + spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.valueOf(spawnReasonName); + } catch (Exception ignored) { + LogManager.getLogger().error("Unknown SpawnReason " + spawnReasonName + " for " + this); + } + } + if (spawnReason == null) { + if (spawnedViaMobSpawner) { + spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER; + } else if (this instanceof EntityInsentient && (this instanceof EntityAnimal || this instanceof EntityFish) && !((EntityInsentient) this).isTypeNotPersistent(0.0)) { + if (!nbttagcompound.getBoolean("PersistenceRequired")) { + spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL; + } + } + } + if (spawnReason == null) { + spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT; + } // Paper end } catch (Throwable throwable) { diff --git a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java index 1aecc84479b00a019a5b68f5e726d1c2965ae0f7..c3a5db97fd85b31c6b4bce93527b9d0e16a79a45 100644 --- a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java +++ b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java @@ -165,6 +165,7 @@ public abstract class MobSpawnerAbstract { // Spigot End } entity.spawnedViaMobSpawner = true; // Paper + entity.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER; // Paper flag = true; // Paper // Spigot Start if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, blockposition).isCancelled()) { diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java index b6e8cd15fe2893ecde4c227f4fc28fcd07600f7c..625a2b2d0c71c40fa44429b00f0391aac7bce277 100644 --- a/src/main/java/net/minecraft/server/PlayerList.java +++ b/src/main/java/net/minecraft/server/PlayerList.java @@ -262,7 +262,7 @@ public abstract class PlayerList { // CraftBukkit start WorldServer finalWorldServer = worldserver1; Entity entity = EntityTypes.a(nbttagcompound1.getCompound("Entity"), finalWorldServer, (entity1) -> { - return !finalWorldServer.addEntitySerialized(entity1) ? null : entity1; + return !finalWorldServer.addEntitySerialized(entity1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.MOUNT) ? null : entity1; // Paper // CraftBukkit end }); diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java index f047f07e768b77feb469c69166f36a3f6779f561..41d466bcd676e6988c4f754d0232d3addb3b6fc5 100644 --- a/src/main/java/net/minecraft/server/WorldServer.java +++ b/src/main/java/net/minecraft/server/WorldServer.java @@ -930,6 +930,7 @@ public class WorldServer extends World implements GeneratorAccessSeed { // CraftBukkit start private boolean addEntity0(Entity entity, CreatureSpawnEvent.SpawnReason spawnReason) { org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot + if (entity.spawnReason == null) entity.spawnReason = spawnReason; // Paper // Paper start if (entity.valid) { MinecraftServer.LOGGER.error("Attempted Double World add on " + entity, new Throwable()); diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java index 018eea17881feeb6583a5b1ae2ab0795e962095b..e2d4aa9ba7fa007b3d93a166c5fb57c8a90387ed 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -1093,5 +1093,10 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { public boolean fromMobSpawner() { return getHandle().spawnedViaMobSpawner; } + + @Override + public org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason getEntitySpawnReason() { + return getHandle().spawnReason; + } // Paper end }