9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2025-12-23 00:49:31 +00:00
Files
Leaf/patches/server/0066-Hearse-Fix-some-sort-problems-in-some-sensors.patch
2023-01-27 08:39:13 -05:00

135 lines
6.7 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: wangxyper <wangxyper@163.com>
Date: Wed, 18 Jan 2023 19:58:12 +0800
Subject: [PATCH] Hearse: Fix some sort problems in some sensors
Original license: MIT
Original project: https://github.com/Era4FunMC/Hearse
diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/NearestItemSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/NearestItemSensor.java
index 2c4517850a9692f1c2b1332b58e8312fe1166772..bee1aa7eded53b3302f39053bfd9c4af5f3008c3 100644
--- a/src/main/java/net/minecraft/world/entity/ai/sensing/NearestItemSensor.java
+++ b/src/main/java/net/minecraft/world/entity/ai/sensing/NearestItemSensor.java
@@ -27,12 +27,11 @@ public class NearestItemSensor extends Sensor<Mob> {
List<ItemEntity> list = world.getEntitiesOfClass(ItemEntity.class, entity.getBoundingBox().inflate(32.0D, 16.0D, 32.0D), (itemEntity) -> {
return itemEntity.closerThan(entity, 9.0D) && entity.wantsToPickUp(itemEntity.getItem()); // Paper - move predicate into getEntities
});
- list.sort((e1, e2) -> Double.compare(entity.distanceToSqr(e1), entity.distanceToSqr(e2))); // better to take the sort perf hit than using line of sight more than we need to.
+ list.sort(Comparator.comparingDouble(entity::distanceToSqr)); // better to take the sort perf hit than using line of sight more than we need to.
// Paper start - remove streams
// Paper start - remove streams in favour of lists
ItemEntity nearest = null;
- for (int i = 0; i < list.size(); i++) {
- ItemEntity entityItem = list.get(i);
+ for (ItemEntity entityItem : list) {
if (entity.hasLineOfSight(entityItem)) {
// Paper end - remove streams
nearest = entityItem;
diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/PlayerSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/PlayerSensor.java
index 75d9c4f011b5a97def215784c92bb57bbb35d06b..af6dcbd8f531705c356780cc79aa1868a10cfaf9 100644
--- a/src/main/java/net/minecraft/world/entity/ai/sensing/PlayerSensor.java
+++ b/src/main/java/net/minecraft/world/entity/ai/sensing/PlayerSensor.java
@@ -1,11 +1,14 @@
package net.minecraft.world.entity.ai.sensing;
+import co.earthme.hearse.util.EntityPositionCache;
import com.google.common.collect.ImmutableSet;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
+
+import java.util.*;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
+
+import it.unimi.dsi.fastutil.objects.ObjectArrayList;
+import it.unimi.dsi.fastutil.objects.ObjectLists;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.EntitySelector;
import net.minecraft.world.entity.LivingEntity;
@@ -14,6 +17,9 @@ import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import net.minecraft.world.entity.player.Player;
public class PlayerSensor extends Sensor<LivingEntity> {
+ private final List<Player> playerList = ObjectLists.synchronize(new ObjectArrayList<>());
+ private final AtomicBoolean calling = new AtomicBoolean();
+
@Override
public Set<MemoryModuleType<?>> requires() {
return ImmutableSet.of(MemoryModuleType.NEAREST_PLAYERS, MemoryModuleType.NEAREST_VISIBLE_PLAYER, MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER);
@@ -21,30 +27,51 @@ public class PlayerSensor extends Sensor<LivingEntity> {
@Override
protected void doTick(ServerLevel world, LivingEntity entity) {
- // Paper start - remove streams
- List<Player> players = (List)world.getNearbyPlayers(entity, entity.getX(), entity.getY(), entity.getZ(), 16.0D, EntitySelector.NO_SPECTATORS);
- players.sort((e1, e2) -> Double.compare(entity.distanceToSqr(e1), entity.distanceToSqr(e2)));
- Brain<?> brain = entity.getBrain();
-
- brain.setMemory(MemoryModuleType.NEAREST_PLAYERS, players);
-
- Player firstTargetable = null;
- Player firstAttackable = null;
- for (int index = 0, len = players.size(); index < len; ++index) {
- Player player = players.get(index);
- if (firstTargetable == null && isEntityTargetable(entity, player)) {
- firstTargetable = player;
- }
- if (firstAttackable == null && isEntityAttackable(entity, player)) {
- firstAttackable = player;
- }
+ if (this.calling.get()){
+ return;
+ }
+
+ this.calling.set(true);
+ try {
+ // Paper start - remove streams
+ List<EntityPositionCache> playersPosCaches = new ArrayList<>(List.of(world
+ .getNearbyPlayers(entity, entity.getX(), entity.getY(), entity.getZ(), 16.0D, EntitySelector.NO_SPECTATORS)
+ .stream()
+ .map(EntityPositionCache::new)
+ .toArray(EntityPositionCache[]::new)));
+
+ final EntityPositionCache entityPositionCache = new EntityPositionCache(entity);
+
+ playersPosCaches.sort(Comparator.comparingDouble(entityPositionCache::distanceToSqr));
+
+ final List<Player> players = playersPosCaches
+ .stream()
+ .map(cache -> ((Player) cache.getCurrentEntity()))
+ .toList();
+
+ Brain<?> brain = entity.getBrain();
+
+ brain.setMemory(MemoryModuleType.NEAREST_PLAYERS, players);
+
+ Player firstTargetable = null;
+ Player firstAttackable = null;
+ for (Player player : players) {
+ if (firstTargetable == null && isEntityTargetable(entity, player)) {
+ firstTargetable = player;
+ }
+ if (firstAttackable == null && isEntityAttackable(entity, player)) {
+ firstAttackable = player;
+ }
- if (firstAttackable != null && firstTargetable != null) {
- break;
+ if (firstAttackable != null && firstTargetable != null) {
+ break;
+ }
}
+ brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_PLAYER, firstTargetable);
+ brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER, Optional.ofNullable(firstAttackable));
+ // Paper end - remove streams
+ }finally {
+ this.calling.set(false);
}
- brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_PLAYER, firstTargetable);
- brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER, Optional.ofNullable(firstAttackable));
- // Paper end - remove streams
}
}