From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jedediah Smith 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..3207166061bf9c4d7bf3f38e5a9f7aff23ccd5c1 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 CAN_BE_COLLIDED_WITH = EntitySelector.NO_SPECTATORS.and(Entity::canBeCollidedWith); private EntitySelector() {} + // Paper start - Affects Spawning API + public static final Predicate PLAYER_AFFECTS_SPAWNING = (entity) -> { + return !entity.isSpectator() && entity.isAlive() && entity instanceof Player player && player.affectsSpawning; + }; + // Paper end - Affects Spawning API public static Predicate 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 1ab169b362cc18d2467e5ed6a4af325d7f6dd247..2de1ad28d42d4beec69901bf985ac0be582f00b9 100644 --- a/src/main/java/net/minecraft/world/entity/Mob.java +++ b/src/main/java/net/minecraft/world/entity/Mob.java @@ -850,7 +850,7 @@ public abstract class Mob extends LivingEntity implements Targeting { if (this.level().getDifficulty() == Difficulty.PEACEFUL && this.shouldDespawnInPeaceful()) { this.discard(EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause } 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 - Affects Spawning API 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 38fb2a14b7c7c535f5a0b13d698a2521ca9d0c1a..0e2725d92002c181f542e2335cdd6e6de69155e1 100644 --- a/src/main/java/net/minecraft/world/entity/monster/Silverfish.java +++ b/src/main/java/net/minecraft/world/entity/monster/Silverfish.java @@ -128,7 +128,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 a779d32f87b59f347408974e402fad22fdc47f09..15ccde8ee8bac1f70c6047464595aff6db073646 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 1ac22d4cbab0f385b1c1e0b4ced59ca7c3ca4af4..0cd534ddc28758f7fa6203c66505f167ecbdd3de 100644 --- a/src/main/java/net/minecraft/world/entity/player/Player.java +++ b/src/main/java/net/minecraft/world/entity/player/Player.java @@ -181,6 +181,7 @@ public abstract class Player extends LivingEntity { @Nullable public FishingHook fishing; protected float hurtDir; + public boolean affectsSpawning = true; // Paper - Affects Spawning API // 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 b6a3c75b84d9f768afee33aa0f226207b307c1c0..07e7851ca27ea0f8166be52b086a6504c0deea09 100644 --- a/src/main/java/net/minecraft/world/level/EntityGetter.java +++ b/src/main/java/net/minecraft/world/level/EntityGetter.java @@ -70,6 +70,11 @@ public interface EntityGetter { } } + // Paper start - Affects Spawning API + default @Nullable Player findNearbyPlayer(Entity entity, double maxDistance, @Nullable Predicate predicate) { + return this.getNearestPlayer(entity.getX(), entity.getY(), entity.getZ(), maxDistance, predicate); + } + // Paper end - Affects Spawning API @Nullable default Player getNearestPlayer(double x, double y, double z, double maxDistance, @Nullable Predicate targetPredicate) { double d = -1.0D; @@ -99,6 +104,20 @@ public interface EntityGetter { return this.getNearestPlayer(x, y, z, maxDistance, predicate); } + // Paper start - Affects Spawning API + 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 - Affects Spawning API + 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 d53e15a3a70de8e2a405d3a39ff51a3551e82dbc..a592ee955a823309f1936a607823ff93822cd369 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -2338,6 +2338,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;