mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2026-01-04 15:41:40 +00:00
142 lines
8.5 KiB
Diff
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) {
|