9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2026-01-04 15:41:40 +00:00
Files
Leaf/patches/server/0112-Optimize-nearby-alive-players-for-spawning.patch
2025-01-07 21:07:30 -05:00

142 lines
8.5 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com>
Date: Sat, 19 Oct 2024 03:28:33 -0400
Subject: [PATCH] Optimize nearby alive players for spawning
Use SpottedLeaf's nearby players system to avoid iterating over all online players
and reduce the cost on predicate test
diff --git a/src/main/java/net/minecraft/world/entity/EntitySelector.java b/src/main/java/net/minecraft/world/entity/EntitySelector.java
index 59c4d3753c7084e92402608b7fb3c4adbc6c2f65..68b59afe54fa1dcc1b24e90fb0cdcff83d898232 100644
--- a/src/main/java/net/minecraft/world/entity/EntitySelector.java
+++ b/src/main/java/net/minecraft/world/entity/EntitySelector.java
@@ -44,7 +44,7 @@ public final class EntitySelector {
private EntitySelector() {}
// Paper start - Affects Spawning API
public static final Predicate<Entity> PLAYER_AFFECTS_SPAWNING = (entity) -> {
- return !entity.isSpectator() && entity.isAlive() && entity instanceof Player player && player.affectsSpawning;
+ return !entity.isSpectator() && entity.isAlive() && entity instanceof Player player && player.affectsSpawning; // Leaf - Optimize nearby alive players for spawning - diff on change
};
// Paper end - Affects Spawning API
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 6efb548b6e1b466628eb70bc45ef98d09604c9df..d053019e3a1fb2d15ad231e31f761d136dca8417 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
@@ -413,7 +413,7 @@ public class Zombie extends Monster {
if (SpawnPlacements.isSpawnPositionOk(entitytypes, world, blockposition) && SpawnPlacements.checkSpawnRules(entitytypes, world, EntitySpawnReason.REINFORCEMENT, blockposition, world.random)) {
entityzombie.setPos((double) i1, (double) j1, (double) k1);
- if (!world.hasNearbyAlivePlayerThatAffectsSpawning((double) i1, (double) j1, (double) k1, 7.0D) && world.isUnobstructed(entityzombie) && world.noCollision((Entity) entityzombie) && (entityzombie.canSpawnInLiquids() || !world.containsAnyLiquid(entityzombie.getBoundingBox()))) { // Paper - affects spawning api
+ if (!world.hasNearbyAlivePlayerThatAffectsSpawningForZombie(i1, j1, k1, 7.0D) && world.isUnobstructed(entityzombie) && world.noCollision((Entity) entityzombie) && (entityzombie.canSpawnInLiquids() || !world.containsAnyLiquid(entityzombie.getBoundingBox()))) { // Paper - affects spawning api // Leaf - Optimize nearby alive players for spawning
entityzombie.setTarget(entityliving, EntityTargetEvent.TargetReason.REINFORCEMENT_TARGET, true); // CraftBukkit
entityzombie.finalizeSpawn(world, world.getCurrentDifficultyAt(entityzombie.blockPosition()), EntitySpawnReason.REINFORCEMENT, (SpawnGroupData) null);
world.addFreshEntityWithPassengers(entityzombie, CreatureSpawnEvent.SpawnReason.REINFORCEMENTS); // CraftBukkit
diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java
index b23397ae135f31abb7ac6bafd9064d7ef5e94218..37c98981c71b73daa078c49319e124c20628fcc8 100644
--- a/src/main/java/net/minecraft/world/level/BaseSpawner.java
+++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java
@@ -60,7 +60,7 @@ public abstract class BaseSpawner {
public boolean isNearPlayer(Level world, BlockPos pos) {
if (world.purpurConfig.spawnerDeactivateByRedstone && world.hasNeighborSignal(pos)) return false; // Purpur
- 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
+ return world.hasNearbyAlivePlayerThatAffectsSpawningForSpawner((double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, this.requiredPlayerRange); // Paper - Affects Spawning API // Leaf - Optimize nearby alive players for spawning
}
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 6b2cda6d578a0983b2401ea20629275431018433..47f80547a4f2285dc097c6f73954419848cfe895 100644
--- a/src/main/java/net/minecraft/world/level/EntityGetter.java
+++ b/src/main/java/net/minecraft/world/level/EntityGetter.java
@@ -180,6 +180,89 @@ public interface EntityGetter extends ca.spottedleaf.moonrise.patches.chunk_syst
}
return false;
}
+
+ // Leaf start - Optimize nearby alive players for spawning
+ default boolean hasNearbyAlivePlayerThatAffectsSpawningForSpawner(double x, double y, double z, double range) {
+ if (range > 33) {
+ return hasNearbyAlivePlayerThatAffectsSpawningForLargerRangeSpawner(x, y, z, range);
+ }
+
+ final net.minecraft.core.BlockPos.MutableBlockPos mutablePos = new net.minecraft.core.BlockPos.MutableBlockPos();
+
+ mutablePos.set(x, y, z);
+
+ final ca.spottedleaf.moonrise.common.list.ReferenceList<net.minecraft.server.level.ServerPlayer> players = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel) this).moonrise$getNearbyPlayers().getPlayers(
+ mutablePos, ca.spottedleaf.moonrise.common.misc.NearbyPlayers.NearbyMapType.GENERAL // range: 33
+ );
+
+ if (players == null) {
+ return false;
+ }
+
+ final net.minecraft.server.level.ServerPlayer[] raw = players.getRawDataUnchecked();
+ final int len = players.size();
+
+ java.util.Objects.checkFromIndexSize(0, len, raw.length);
+
+ for (int i = 0; i < len; ++i) {
+ final net.minecraft.server.level.ServerPlayer player = raw[i];
+ final double distanceSqr = player.distanceToSqr(x, y, z);
+
+ if (range < 0.0D || distanceSqr < range * range) {
+ if (!player.isSpectator() && player.isAlive() && player.affectsSpawning) { // combines NO_SPECTATORS and LIVING_ENTITY_STILL_ALIVE with an "affects spawning" check
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ default boolean hasNearbyAlivePlayerThatAffectsSpawningForLargerRangeSpawner(double x, double y, double z, double range) {
+ for (Player player : this.players()) {
+ double distanceSqr = player.distanceToSqr(x, y, z);
+ if (range < 0.0D || distanceSqr < range * range) {
+ if (!player.isSpectator() && player.isAlive() && player.affectsSpawning) { // combines NO_SPECTATORS and LIVING_ENTITY_STILL_ALIVE with an "affects spawning" check
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ default boolean hasNearbyAlivePlayerThatAffectsSpawningForZombie(int x, int y, int z, double range) {
+ final net.minecraft.core.BlockPos.MutableBlockPos mutablePos = new net.minecraft.core.BlockPos.MutableBlockPos();
+
+ mutablePos.set(x, y, z);
+
+ final ca.spottedleaf.moonrise.common.list.ReferenceList<net.minecraft.server.level.ServerPlayer> players = ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel) this).moonrise$getNearbyPlayers().getPlayers(
+ mutablePos, ca.spottedleaf.moonrise.common.misc.NearbyPlayers.NearbyMapType.SPAWN_RANGE // range: 8
+ );
+
+ if (players == null) {
+ return false;
+ }
+
+ final net.minecraft.server.level.ServerPlayer[] raw = players.getRawDataUnchecked();
+ final int len = players.size();
+
+ java.util.Objects.checkFromIndexSize(0, len, raw.length);
+
+ for (int i = 0; i < len; ++i) {
+ final net.minecraft.server.level.ServerPlayer player = raw[i];
+ final double distanceSqr = player.distanceToSqr(x, y, z);
+
+ if (range < 0.0D || distanceSqr < range * range) {
+ if (!player.isSpectator() && player.isAlive() && player.affectsSpawning) { // combines NO_SPECTATORS and LIVING_ENTITY_STILL_ALIVE with an "affects spawning" check
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+ // Leaf end - Optimize nearby alive players for spawning
// Paper end - Affects Spawning API
default boolean hasNearbyAlivePlayer(double x, double y, double z, double range) {