summaryrefslogtreecommitdiffhomepage
path: root/patches/server/0761-Remove-streams-for-villager-AI.patch
diff options
context:
space:
mode:
authorNassim Jahnke <[email protected]>2022-07-27 23:19:52 +0200
committerNassim Jahnke <[email protected]>2022-07-27 23:19:52 +0200
commitc7304035b6a3ca33196d88a5c46f746dbff178fe (patch)
tree67c8b104ad3c4dd3b049977b38120c8bc1add6c7 /patches/server/0761-Remove-streams-for-villager-AI.patch
parentaab40382a5d9b01b1c712fa17de9fdf0668ccc28 (diff)
downloadPaper-c7304035b6a3ca33196d88a5c46f746dbff178fe.tar.gz
Paper-c7304035b6a3ca33196d88a5c46f746dbff178fe.zip
More more more more work
Diffstat (limited to 'patches/server/0761-Remove-streams-for-villager-AI.patch')
-rw-r--r--patches/server/0761-Remove-streams-for-villager-AI.patch216
1 files changed, 216 insertions, 0 deletions
diff --git a/patches/server/0761-Remove-streams-for-villager-AI.patch b/patches/server/0761-Remove-streams-for-villager-AI.patch
new file mode 100644
index 0000000000..3af840ec77
--- /dev/null
+++ b/patches/server/0761-Remove-streams-for-villager-AI.patch
@@ -0,0 +1,216 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Spottedleaf <[email protected]>
+Date: Thu, 27 Aug 2020 20:51:40 -0700
+Subject: [PATCH] Remove streams for villager AI
+
+
+diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/GateBehavior.java b/src/main/java/net/minecraft/world/entity/ai/behavior/GateBehavior.java
+index 5a5d454b5987bb01d03f91c15b7a6bff46f1de71..c545539fc5d20cc69a0e5d2e261ef46a8f6fa4f0 100644
+--- a/src/main/java/net/minecraft/world/entity/ai/behavior/GateBehavior.java
++++ b/src/main/java/net/minecraft/world/entity/ai/behavior/GateBehavior.java
+@@ -30,11 +30,19 @@ public class GateBehavior<E extends LivingEntity> extends Behavior<E> {
+
+ @Override
+ protected boolean canStillUse(ServerLevel world, E entity, long time) {
+- return this.behaviors.stream().filter((task) -> {
+- return task.getStatus() == Behavior.Status.RUNNING;
+- }).anyMatch((task) -> {
+- return task.canStillUse(world, entity, time);
+- });
++ // Paper start - remove streams
++ List<ShufflingList.WeightedEntry<Behavior<? super E>>> entries = this.behaviors.entries;
++ for (int i = 0; i < entries.size(); i++) {
++ ShufflingList.WeightedEntry<Behavior<? super E>> entry = entries.get(i);
++ Behavior<? super E> behavior = entry.getData();
++ if (behavior.getStatus() == Status.RUNNING) {
++ if (behavior.canStillUse(world, entity, time)) {
++ return true;
++ }
++ }
++ }
++ return false;
++ // Paper end - remove streams
+ }
+
+ @Override
+@@ -45,25 +53,35 @@ public class GateBehavior<E extends LivingEntity> extends Behavior<E> {
+ @Override
+ protected void start(ServerLevel world, E entity, long time) {
+ this.orderPolicy.apply(this.behaviors);
+- this.runningPolicy.apply(this.behaviors.stream(), world, entity, time);
++ this.runningPolicy.apply(this.behaviors.entries, world, entity, time); // Paper - remove streams
+ }
+
+ @Override
+ protected void tick(ServerLevel world, E entity, long time) {
+- this.behaviors.stream().filter((task) -> {
+- return task.getStatus() == Behavior.Status.RUNNING;
+- }).forEach((task) -> {
+- task.tickOrStop(world, entity, time);
+- });
++ // Paper start - remove streams
++ List<ShufflingList.WeightedEntry<Behavior<? super E>>> entries = this.behaviors.entries;
++ for (int i = 0; i < entries.size(); i++) {
++ ShufflingList.WeightedEntry<Behavior<? super E>> entry = entries.get(i);
++ Behavior<? super E> behavior = entry.getData();
++ if (behavior.getStatus() == Status.RUNNING) {
++ behavior.tickOrStop(world, entity, time);
++ }
++ }
++ // Paper end - remove streams
+ }
+
+ @Override
+ protected void stop(ServerLevel world, E entity, long time) {
+- this.behaviors.stream().filter((task) -> {
+- return task.getStatus() == Behavior.Status.RUNNING;
+- }).forEach((task) -> {
+- task.doStop(world, entity, time);
+- });
++ // Paper start - remove streams
++ List<ShufflingList.WeightedEntry<Behavior<? super E>>> entries = this.behaviors.entries;
++ for (int i = 0; i < entries.size(); i++) {
++ ShufflingList.WeightedEntry<Behavior<? super E>> entry = entries.get(i);
++ Behavior<? super E> behavior = entry.getData();
++ if (behavior.getStatus() == Status.RUNNING) {
++ behavior.doStop(world, entity, time);
++ }
++ }
++ // Paper end - remove streams
+ this.exitErasedMemories.forEach(entity.getBrain()::eraseMemory);
+ }
+
+@@ -94,25 +112,33 @@ public class GateBehavior<E extends LivingEntity> extends Behavior<E> {
+ public static enum RunningPolicy {
+ RUN_ONE {
+ @Override
+- public <E extends LivingEntity> void apply(Stream<Behavior<? super E>> tasks, ServerLevel world, E entity, long time) {
+- tasks.filter((task) -> {
+- return task.getStatus() == Behavior.Status.STOPPED;
+- }).filter((task) -> {
+- return task.tryStart(world, entity, time);
+- }).findFirst();
++ // Paper start - remove streams
++ public <E extends LivingEntity> void apply(List<ShufflingList.WeightedEntry<Behavior<? super E>>> tasks, ServerLevel world, E entity, long time) {
++ for (int i = 0; i < tasks.size(); i++) {
++ ShufflingList.WeightedEntry<Behavior<? super E>> task = tasks.get(i);
++ Behavior<? super E> behavior = task.getData();
++ if (behavior.getStatus() == Status.STOPPED && behavior.tryStart(world, entity, time)) {
++ break;
++ }
++ }
++ // Paper end - remove streams
+ }
+ },
+ TRY_ALL {
+ @Override
+- public <E extends LivingEntity> void apply(Stream<Behavior<? super E>> tasks, ServerLevel world, E entity, long time) {
+- tasks.filter((task) -> {
+- return task.getStatus() == Behavior.Status.STOPPED;
+- }).forEach((task) -> {
+- task.tryStart(world, entity, time);
+- });
++ // Paper start - remove streams
++ public <E extends LivingEntity> void apply(List<ShufflingList.WeightedEntry<Behavior<? super E>>> tasks, ServerLevel world, E entity, long time) {
++ for (int i = 0; i < tasks.size(); i++) {
++ ShufflingList.WeightedEntry<Behavior<? super E>> task = tasks.get(i);
++ Behavior<? super E> behavior = task.getData();
++ if (behavior.getStatus() == Status.STOPPED) {
++ behavior.tryStart(world, entity, time);
++ }
++ }
++ // Paper end - remove streams
+ }
+ };
+
+- public abstract <E extends LivingEntity> void apply(Stream<Behavior<? super E>> tasks, ServerLevel world, E entity, long time);
++ public abstract <E extends LivingEntity> void apply(List<ShufflingList.WeightedEntry<Behavior<? super E>>> tasks, ServerLevel world, E entity, long time); // Paper - remove streams
+ }
+ }
+diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/ShufflingList.java b/src/main/java/net/minecraft/world/entity/ai/behavior/ShufflingList.java
+index 090bba46b6ecd7d0e1415feb678b9b23264fe5e9..ca771d60283d94c00aa65d06ef93071e412357e8 100644
+--- a/src/main/java/net/minecraft/world/entity/ai/behavior/ShufflingList.java
++++ b/src/main/java/net/minecraft/world/entity/ai/behavior/ShufflingList.java
+@@ -12,7 +12,7 @@ import java.util.stream.Stream;
+ import net.minecraft.util.RandomSource;
+
+ public class ShufflingList<U> {
+- protected final List<ShufflingList.WeightedEntry<U>> entries;
++ public final List<ShufflingList.WeightedEntry<U>> entries; // Paper - public
+ private final RandomSource random = RandomSource.create();
+ private final boolean isUnsafe; // Paper
+
+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 1dfcc5cba6ffb463acf161a23fff1ca452184290..2c4517850a9692f1c2b1332b58e8312fe1166772 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
+@@ -25,13 +25,16 @@ public class NearestItemSensor extends Sensor<Mob> {
+ protected void doTick(ServerLevel world, Mob entity) {
+ Brain<?> brain = entity.getBrain();
+ List<ItemEntity> list = world.getEntitiesOfClass(ItemEntity.class, entity.getBoundingBox().inflate(32.0D, 16.0D, 32.0D), (itemEntity) -> {
+- return true;
++ return itemEntity.closerThan(entity, 9.0D) && entity.wantsToPickUp(itemEntity.getItem()); // Paper - move predicate into getEntities
+ });
+- list.sort(Comparator.comparingDouble(entity::distanceToSqr));
++ 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.
++ // Paper start - remove streams
+ // Paper start - remove streams in favour of lists
+ ItemEntity nearest = null;
+- for (ItemEntity entityItem : list) {
+- if (entity.wantsToPickUp(entityItem.getItem()) && entityItem.closerThan(entity, 32.0D) && entity.hasLineOfSight(entityItem)) {
++ for (int i = 0; i < list.size(); i++) {
++ ItemEntity entityItem = list.get(i);
++ if (entity.hasLineOfSight(entityItem)) {
++ // Paper end - remove streams
+ nearest = entityItem;
+ break;
+ }
+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 312775d0430f793720211dc29bb293503e799d11..75d9c4f011b5a97def215784c92bb57bbb35d06b 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
+@@ -21,25 +21,30 @@ public class PlayerSensor extends Sensor<LivingEntity> {
+
+ @Override
+ protected void doTick(ServerLevel world, LivingEntity entity) {
+- List<Player> players = new java.util.ArrayList<>(world.players());
+- players.removeIf(player -> !EntitySelector.NO_SPECTATORS.test(player) || !entity.closerThan(player, 16.0D));
+- players.sort(Comparator.comparingDouble(entity::distanceTo));
++ // 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 nearest = null, nearestTargetable = null;
+- for (Player player : players) {
+- if (Sensor.isEntityTargetable(entity, player)) {
+- if (nearest == null) nearest = player;
+- if (Sensor.isEntityAttackable(entity, player)) {
+- nearestTargetable = player;
+- break; // Both variables are assigned, no reason to loop further
+- }
++ 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 (firstAttackable != null && firstTargetable != null) {
++ break;
+ }
+ }
+- brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_PLAYER, nearest);
+- brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER, nearestTargetable);
+- // Paper end
++ brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_PLAYER, firstTargetable);
++ brain.setMemory(MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER, Optional.ofNullable(firstAttackable));
++ // Paper end - remove streams
+ }
+ }