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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jedediah Smith <jedediah@silencegreys.com>
Date: Tue, 1 Mar 2016 14:47:52 -0600
Subject: [PATCH] Player affects spawning API
diff --git a/src/main/java/net/minecraft/world/entity/EntitySelector.java b/src/main/java/net/minecraft/world/entity/EntitySelector.java
index 3126e8cab3c40e3af47f4c8925e1c6a9523309ba..170fbb1d80947b9b21c2106497baae5c37bcdc0c 100644
--- a/src/main/java/net/minecraft/world/entity/EntitySelector.java
+++ b/src/main/java/net/minecraft/world/entity/EntitySelector.java
@@ -30,6 +30,11 @@ public final class EntitySelector {
public static final Predicate<Entity> CAN_BE_COLLIDED_WITH = EntitySelector.NO_SPECTATORS.and(Entity::canBeCollidedWith);
private EntitySelector() {}
+ // Paper start
+ public static final Predicate<Entity> PLAYER_AFFECTS_SPAWNING = (entity) -> {
+ return !entity.isSpectator() && entity.isAlive() && entity instanceof Player player && player.affectsSpawning;
+ };
+ // Paper end
public static Predicate<Entity> withinDistance(double x, double y, double z, double max) {
double d4 = max * max;
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
index 007a5c9a6dc70ca6a215fdeb3fe77f8a8ee46818..3d054cfa5050f4b75eab4a18035655c1bfd9290b 100644
--- a/src/main/java/net/minecraft/world/entity/Mob.java
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
@@ -849,7 +849,7 @@ public abstract class Mob extends LivingEntity implements Targeting {
if (this.level().getDifficulty() == Difficulty.PEACEFUL && this.shouldDespawnInPeaceful()) {
this.discard();
} else if (!this.isPersistenceRequired() && !this.requiresCustomPersistence()) {
- Player entityhuman = this.level().getNearestPlayer(this, -1.0D);
+ Player entityhuman = this.level().findNearbyPlayer(this, -1.0D, EntitySelector.PLAYER_AFFECTS_SPAWNING); // Paper
if (entityhuman != null) {
double d0 = entityhuman.distanceToSqr((Entity) this);
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java b/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java
index c7ab59aa0e2fd0f3e7252647ddb25b82ac604830..8f20239f3ef7ebe41fac8ee6e024c36dafec33c4 100644
--- a/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java
@@ -25,7 +25,7 @@ public class SkeletonTrapGoal extends Goal {
@Override
public boolean canUse() {
- return this.horse.level().hasNearbyAlivePlayer(this.horse.getX(), this.horse.getY(), this.horse.getZ(), 10.0D);
+ return this.horse.level().hasNearbyAlivePlayerThatAffectsSpawning(this.horse.getX(), this.horse.getY(), this.horse.getZ(), 10.0D); // Paper - Affects Spawning API
}
@Override
diff --git a/src/main/java/net/minecraft/world/entity/monster/Silverfish.java b/src/main/java/net/minecraft/world/entity/monster/Silverfish.java
index 96181e8925aef7f3d0a2010305caf1f6d9bcfcc9..6f452605e9dc9ebd9980eae9fdeea34417a37a88 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Silverfish.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Silverfish.java
@@ -127,7 +127,7 @@ public class Silverfish extends Monster {
if (checkAnyLightMonsterSpawnRules(type, world, spawnReason, pos, random)) {
Player entityhuman = world.getNearestPlayer((double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, 5.0D, true);
- return entityhuman == null;
+ return !(entityhuman != null && !entityhuman.affectsSpawning) && entityhuman == null; // Paper - Affects Spawning API
} else {
return false;
}
diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
index 38403a5bb8569f105056d61ca444d6b3a19becd2..2aec8e2f45fe6ba56d84e5a51a6e30d36505df42 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
@@ -326,7 +326,7 @@ public class Zombie extends Monster {
if (NaturalSpawner.isSpawnPositionOk(entitypositiontypes_surface, this.level(), blockposition, entitytypes) && SpawnPlacements.checkSpawnRules(entitytypes, worldserver, MobSpawnType.REINFORCEMENT, blockposition, this.level().random)) {
entityzombie.setPos((double) i1, (double) j1, (double) k1);
- if (!this.level().hasNearbyAlivePlayer((double) i1, (double) j1, (double) k1, 7.0D) && this.level().isUnobstructed(entityzombie) && this.level().noCollision((Entity) entityzombie) && !this.level().containsAnyLiquid(entityzombie.getBoundingBox())) {
+ if (!this.level().hasNearbyAlivePlayerThatAffectsSpawning((double) i1, (double) j1, (double) k1, 7.0D) && this.level().isUnobstructed(entityzombie) && this.level().noCollision((Entity) entityzombie) && !this.level().containsAnyLiquid(entityzombie.getBoundingBox())) { // Paper - Affects Spawning API
entityzombie.setTarget(entityliving, EntityTargetEvent.TargetReason.REINFORCEMENT_TARGET, true); // CraftBukkit
entityzombie.finalizeSpawn(worldserver, this.level().getCurrentDifficultyAt(entityzombie.blockPosition()), MobSpawnType.REINFORCEMENT, (SpawnGroupData) null, (CompoundTag) null);
worldserver.addFreshEntityWithPassengers(entityzombie, CreatureSpawnEvent.SpawnReason.REINFORCEMENTS); // CraftBukkit
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
index eed6481bc88ed15a5e3fe7056b545ab44ed81983..86d187cadb73dbe0757f9417c4549e358ff303ca 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -179,6 +179,9 @@ public abstract class Player extends LivingEntity {
@Nullable
public FishingHook fishing;
protected float hurtDir;
+ // Paper start
+ public boolean affectsSpawning = true;
+ // Paper end
// CraftBukkit start
public boolean fauxSleeping;
diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java
index d156f7e3430685947d2b4c30aa867e8002ca70ad..e888cf862662ae6baa6d0de8188aa74a9c6a8e00 100644
--- a/src/main/java/net/minecraft/world/level/BaseSpawner.java
+++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java
@@ -56,7 +56,7 @@ public abstract class BaseSpawner {
}
public boolean isNearPlayer(Level world, BlockPos pos) {
- return world.hasNearbyAlivePlayer((double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, (double) this.requiredPlayerRange);
+ return world.hasNearbyAlivePlayerThatAffectsSpawning((double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, (double) this.requiredPlayerRange); // Paper - Affects Spawning API
}
public void clientTick(Level world, BlockPos pos) {
diff --git a/src/main/java/net/minecraft/world/level/EntityGetter.java b/src/main/java/net/minecraft/world/level/EntityGetter.java
index 2ec2b1d9d987c7f31c685aec3d3c87f42758c94b..36d793b492d9776ee36f8285b5bab09e6463cdce 100644
--- a/src/main/java/net/minecraft/world/level/EntityGetter.java
+++ b/src/main/java/net/minecraft/world/level/EntityGetter.java
@@ -82,6 +82,11 @@ public interface EntityGetter {
}
}
+ // Paper start
+ default @Nullable Player findNearbyPlayer(Entity entity, double maxDistance, @Nullable Predicate<Entity> predicate) {
+ return this.getNearestPlayer(entity.getX(), entity.getY(), entity.getZ(), maxDistance, predicate);
+ }
+ // Paper end
@Nullable
default Player getNearestPlayer(double x, double y, double z, double maxDistance, @Nullable Predicate<Entity> targetPredicate) {
double d = -1.0D;
@@ -111,6 +116,20 @@ public interface EntityGetter {
return this.getNearestPlayer(x, y, z, maxDistance, predicate);
}
+ // Paper start
+ default boolean hasNearbyAlivePlayerThatAffectsSpawning(double x, double y, double z, double range) {
+ for (Player player : this.players()) {
+ if (EntitySelector.PLAYER_AFFECTS_SPAWNING.test(player)) { // combines NO_SPECTATORS and LIVING_ENTITY_STILL_ALIVE with an "affects spawning" check
+ double distanceSqr = player.distanceToSqr(x, y, z);
+ if (range < 0.0D || distanceSqr < range * range) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ // Paper end
+
default boolean hasNearbyAlivePlayer(double x, double y, double z, double range) {
for(Player player : this.players()) {
if (EntitySelector.NO_SPECTATORS.test(player) && EntitySelector.LIVING_ENTITY_STILL_ALIVE.test(player)) {
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 41a4f6126f24848a26ff0f928a23b5be13783c90..4bdcff78393b618b2201753bbffbd9001d5ad2d1 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -2267,6 +2267,17 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
return this.getHandle().language;
}
+ // Paper start
+ public void setAffectsSpawning(boolean affects) {
+ this.getHandle().affectsSpawning = affects;
+ }
+
+ @Override
+ public boolean getAffectsSpawning() {
+ return this.getHandle().affectsSpawning;
+ }
+ // Paper end
+
@Override
public void updateCommands() {
if (this.getHandle().connection == null) return;
|