aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0301-Entity-getEntitySpawnReason.patch
blob: bea69f8ae77e0bdf0ad394adce8d6fb57580227e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
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/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index eace3ac2219a9746800811037074578ccc23f072..8e2129c78c212c61456efc3a40fb13b877d52259 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -1429,6 +1429,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
             return true;
         }
         // Paper end
+        if (entity.spawnReason == null) entity.spawnReason = spawnReason; // Paper
         if (entity.isRemoved()) {
             // Paper start
             if (DEBUG_ENTITIES) {
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index e038240042366e1c491c04016982c91c91ee86cd..cccaf594392a0283f00986f182cc89d56181bc40 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -233,6 +233,11 @@ public abstract class PlayerList {
             worldserver1 = worldserver;
         }
 
+        // Paper start
+        if (nbttagcompound == null) {
+            player.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT; // set Player SpawnReason to DEFAULT on first login
+        }
+        // Paper end
         player.setServerLevel(worldserver1);
         String s1 = "local";
 
@@ -373,7 +378,7 @@ public abstract class PlayerList {
             // CraftBukkit start
             ServerLevel finalWorldServer = worldserver1;
             Entity entity = EntityType.loadEntityRecursive(nbttagcompound1.getCompound("Entity"), finalWorldServer, (entity1) -> {
-                return !finalWorldServer.addWithUUID(entity1) ? null : entity1;
+                return !finalWorldServer.addWithUUID(entity1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.MOUNT) ? null : entity1; // Paper
                 // CraftBukkit end
             });
 
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 9780ebabd27def10b09deebc5be2043d063de9f3..7be82f903e5f65d00b68dc7ee7c1cb4b2be1dc8d 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -234,6 +234,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
         }
     }
     // Paper end
+    public org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason; // Paper
 
     public com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData; // Paper
     private CraftEntity bukkitEntity;
@@ -2181,6 +2182,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
                 }
                 nbt.put("Paper.Origin", this.newDoubleList(origin.getX(), origin.getY(), origin.getZ()));
             }
+            if (spawnReason != null) {
+                nbt.putString("Paper.SpawnReason", spawnReason.name());
+            }
             // Save entity's from mob spawner status
             if (spawnedViaMobSpawner) {
                 nbt.putBoolean("Paper.FromMobSpawner", true);
@@ -2327,6 +2331,26 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
             }
 
             spawnedViaMobSpawner = nbt.getBoolean("Paper.FromMobSpawner"); // Restore entity's from mob spawner status
+            if (nbt.contains("Paper.SpawnReason")) {
+                String spawnReasonName = nbt.getString("Paper.SpawnReason");
+                try {
+                    spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.valueOf(spawnReasonName);
+                } catch (Exception ignored) {
+                    LOGGER.error("Unknown SpawnReason " + spawnReasonName + " for " + this);
+                }
+            }
+            if (spawnReason == null) {
+                if (spawnedViaMobSpawner) {
+                    spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER;
+                } else if (this instanceof Mob && (this instanceof net.minecraft.world.entity.animal.Animal || this instanceof net.minecraft.world.entity.animal.AbstractFish) && !((Mob) this).removeWhenFarAway(0.0)) {
+                    if (!nbt.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/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java
index 0af2d9420ec6c454970ac89b74676585010d11e9..b0ae290342b4f540b77a928b19a86dd61166b210 100644
--- a/src/main/java/net/minecraft/world/level/BaseSpawner.java
+++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java
@@ -184,6 +184,7 @@ public abstract class BaseSpawner {
                         }
 
                         entity.spawnedViaMobSpawner = true; // Paper
+                        entity.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER; // Paper
                         flag = true; // Paper
                         // CraftBukkit start
                         if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, pos).isCancelled()) {
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index 0008f8365b13e10d842a3e2e7c4f87448014a857..8b48c0379d395f1e5a2e5ac90a9bb50e26649a71 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -1311,5 +1311,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
 }