9
0
mirror of https://github.com/BX-Team/DivineMC.git synced 2025-12-19 14:59:25 +00:00

implement back some patches and add new

This commit is contained in:
NONPLAYT
2024-12-16 01:31:23 +03:00
parent 0e5aaddb2f
commit ea3e200ca2
13 changed files with 642 additions and 234 deletions

2
.gitignore vendored
View File

@@ -10,4 +10,4 @@ run
.idea .idea
# Other files and folders # Other files and folders
build-data/dev-imports.txt build-data

View File

@@ -7,7 +7,7 @@ Original code by CaffeineMC, licensed under LGPL v3
You can find the original code on https://github.com/CaffeineMC/lithium-fabric (Yarn mappings) You can find the original code on https://github.com/CaffeineMC/lithium-fabric (Yarn mappings)
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 84ac9ee926a9a4b4d2dcd107cb089162637a2576..e3f3e23540bc2b8b650b680839a4f06f95e9b7e6 100644 index 84ac9ee926a9a4b4d2dcd107cb089162637a2576..012ab9befd112e26d5f593cac1dba8592c0b0021 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java --- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java +++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -2832,6 +2832,7 @@ public abstract class LivingEntity extends Entity implements Attackable { @@ -2832,6 +2832,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
@@ -18,3 +18,11 @@ index 84ac9ee926a9a4b4d2dcd107cb089162637a2576..e3f3e23540bc2b8b650b680839a4f06f
int i = this.getCurrentSwingDuration(); int i = this.getCurrentSwingDuration();
if (this.swinging) { if (this.swinging) {
@@ -3878,6 +3879,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
protected void updateFallFlying() {
this.checkSlowFallDistance();
if (!this.level().isClientSide) {
+ if (!this.isFallFlying() && this.fallFlyTicks == 0) return; // DivineMC - lithium: entity.fast_elytra_check
if (!this.canGlide()) {
if (this.getSharedFlag(7) != false && !CraftEventFactory.callToggleGlideEvent(this, false).isCancelled()) // CraftBukkit
this.setSharedFlag(7, false);

View File

@@ -1,23 +1,23 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Sun, 25 Jun 2023 22:54:47 +0300 Date: Sun, 15 Dec 2024 23:28:29 +0300
Subject: [PATCH] Fix MC-65198 Subject: [PATCH] Fix MC-65198
Original post on Mojira: https://bugs.mojang.com/browse/MC-65198 Original post on Mojira: https://bugs.mojang.com/browse/MC-65198
diff --git a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java diff --git a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java
index b3bd9bbd96efc4784b86c2be6bb857da4db919b8..665d975cdb6c66bc43e4a589f0ee140bba0fcda7 100644 index ac9df238ef0f3d009f25976b95e0b750e963e952..9b187768d645759f12d1a474fe488663d304a068 100644
--- a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java --- a/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java
+++ b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java +++ b/src/main/java/net/minecraft/world/inventory/ItemCombinerMenu.java
@@ -141,6 +141,7 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu { @@ -129,6 +129,7 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu {
ItemStack itemstack1 = slot1.getItem(); ItemStack itemstack1 = slot1.getItem();
itemstack = itemstack1.copy(); itemstack = itemstack1.copy();
+ ItemStack itemStack2 = itemstack.copy(); + ItemStack itemStack2 = itemstack.copy(); // DivineMC - Fix MC-65198
int j = this.getInventorySlotStart(); int j = this.getInventorySlotStart();
int k = this.getUseRowEnd(); int k = this.getUseRowEnd();
@@ -179,7 +180,7 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu { @@ -165,7 +166,7 @@ public abstract class ItemCombinerMenu extends AbstractContainerMenu {
} }
this.activeQuickItem = itemstack; // Purpur - Anvil API this.activeQuickItem = itemstack; // Purpur - Anvil API
@@ -27,10 +27,10 @@ index b3bd9bbd96efc4784b86c2be6bb857da4db919b8..665d975cdb6c66bc43e4a589f0ee140b
} }
diff --git a/src/main/java/net/minecraft/world/inventory/ResultSlot.java b/src/main/java/net/minecraft/world/inventory/ResultSlot.java diff --git a/src/main/java/net/minecraft/world/inventory/ResultSlot.java b/src/main/java/net/minecraft/world/inventory/ResultSlot.java
index 37a89bf79017eb65f82276b054a70ddb5eb5e549..10d2d3a21b9a44ddf28977f2cb8ce4deee20d291 100644 index ff30071f3ef37d1b28cf86e26ce4f7477335a07a..a7b2a88cf2c1e8f717e512a9bc01772a463009bb 100644
--- a/src/main/java/net/minecraft/world/inventory/ResultSlot.java --- a/src/main/java/net/minecraft/world/inventory/ResultSlot.java
+++ b/src/main/java/net/minecraft/world/inventory/ResultSlot.java +++ b/src/main/java/net/minecraft/world/inventory/ResultSlot.java
@@ -46,7 +46,7 @@ public class ResultSlot extends Slot { @@ -49,7 +49,7 @@ public class ResultSlot extends Slot {
@Override @Override
protected void checkTakeAchievements(ItemStack stack) { protected void checkTakeAchievements(ItemStack stack) {
if (this.removeCount > 0) { if (this.removeCount > 0) {
@@ -40,10 +40,10 @@ index 37a89bf79017eb65f82276b054a70ddb5eb5e549..10d2d3a21b9a44ddf28977f2cb8ce4de
if (this.container instanceof RecipeCraftingHolder recipeCraftingHolder) { if (this.container instanceof RecipeCraftingHolder recipeCraftingHolder) {
diff --git a/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java b/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java diff --git a/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java b/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java
index 5ddae1afab0a68465ea60395c84b0997ee994f88..76790f8433698b58265449b3edb6ce5be7e9678b 100644 index 5dce62aead43c7110e06196423458eea2ba31885..120094e07b73e81dbaa5bb1cf727feb3842f7380 100644
--- a/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java --- a/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java
+++ b/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java +++ b/src/main/java/net/minecraft/world/inventory/StonecutterMenu.java
@@ -264,6 +264,7 @@ public class StonecutterMenu extends AbstractContainerMenu { @@ -259,6 +259,7 @@ public class StonecutterMenu extends AbstractContainerMenu {
Item item = itemstack1.getItem(); Item item = itemstack1.getItem();
itemstack = itemstack1.copy(); itemstack = itemstack1.copy();
@@ -51,12 +51,15 @@ index 5ddae1afab0a68465ea60395c84b0997ee994f88..76790f8433698b58265449b3edb6ce5b
if (slot == 1) { if (slot == 1) {
item.onCraftedBy(itemstack1, player.level(), player); item.onCraftedBy(itemstack1, player.level(), player);
if (!this.moveItemStackTo(itemstack1, 2, 38, true)) { if (!this.moveItemStackTo(itemstack1, 2, 38, true)) {
@@ -296,7 +297,7 @@ public class StonecutterMenu extends AbstractContainerMenu { @@ -291,9 +292,9 @@ public class StonecutterMenu extends AbstractContainerMenu {
return ItemStack.EMPTY; return ItemStack.EMPTY;
} }
- slot1.onTake(player, itemstack1); - slot1.onTake(player, itemstack1);
+ slot1.onTake(player, itemStack2); // DivineMC - Fix MC-65198 + slot1.onTake(player, itemStack2); // DivineMC - Fix MC-65198
this.broadcastChanges(); if (slot == 1) {
} - player.drop(itemstack1, false);
+ player.drop(itemStack2, false); // DivineMC - Fix MC-65198
}
this.broadcastChanges();

View File

@@ -0,0 +1,52 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Sun, 15 Dec 2024 23:32:36 +0300
Subject: [PATCH] Carpet-Fixes: RecipeManager Optimize
Original project: https://github.com/fxmorin/carpet-fixes
Optimized the RecipeManager getFirstMatch call to be up to 3x faster
This is a fully vanilla optimization. Improves: [Blast]Furnace/Campfire/Smoker/Stonecutter/Crafting/Sheep Color Choosing
This was mostly made for the auto crafting table, since the performance boost is much more visible while using that mod
diff --git a/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java b/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java
index 2483627f807d7a3907f6848a8bc45d7a798e746d..01b63bf331a39b5fb23734f72a4f9880a98094b2 100644
--- a/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java
+++ b/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java
@@ -197,7 +197,7 @@ public class RecipeManager extends SimplePreparableReloadListener<RecipeMap> imp
public <I extends RecipeInput, T extends Recipe<I>> Optional<RecipeHolder<T>> getRecipeFor(RecipeType<T> type, I input, Level world) {
// CraftBukkit start
- List<RecipeHolder<T>> list = this.recipes.getRecipesFor(type, input, world).toList();
+ List<RecipeHolder<T>> list = this.recipes.getRecipesForList(type, input, world); // DivineMC - Carpet-Fixes - Remove streams to be faster
return (list.isEmpty()) ? Optional.empty() : Optional.of(list.getLast()); // CraftBukkit - SPIGOT-4638: last recipe gets priority
// CraftBukkit end
}
diff --git a/src/main/java/net/minecraft/world/item/crafting/RecipeMap.java b/src/main/java/net/minecraft/world/item/crafting/RecipeMap.java
index c4067fbf827fed882772962a0e4b3ead0d642e62..2d289139f80855f07121861b1f840058f0bc9ec1 100644
--- a/src/main/java/net/minecraft/world/item/crafting/RecipeMap.java
+++ b/src/main/java/net/minecraft/world/item/crafting/RecipeMap.java
@@ -105,4 +105,24 @@ public class RecipeMap {
return recipeholder.value().matches(input, world);
});
}
+
+ // DivineMC start - Carpet-Fixes - Remove streams to be faster
+ public <I extends RecipeInput, T extends Recipe<I>> java.util.List<RecipeHolder<T>> getRecipesForList(RecipeType<T> type, I input, Level world) {
+ java.util.List<RecipeHolder<T>> list;
+
+ if (input.isEmpty()) {
+ return java.util.List.of();
+ } else {
+ list = new java.util.ArrayList<>();
+ }
+
+ for (RecipeHolder<T> recipeholder : this.byType(type)) {
+ if (recipeholder.value().matches(input, world)) {
+ list.add(recipeholder);
+ }
+ }
+
+ return list;
+ }
+ // DivineMC end - Carpet-Fixes - Remove streams to be faster
}

View File

@@ -0,0 +1,78 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Mon, 16 Dec 2024 00:13:15 +0300
Subject: [PATCH] C2ME: Optimize world gen math
diff --git a/src/main/java/net/minecraft/world/level/ChunkPos.java b/src/main/java/net/minecraft/world/level/ChunkPos.java
index 0639e4565c3324d757dec1226adb4e99d841f2c0..7b659fc5cc373e5d26968c693e97b5f725a2e600 100644
--- a/src/main/java/net/minecraft/world/level/ChunkPos.java
+++ b/src/main/java/net/minecraft/world/level/ChunkPos.java
@@ -110,7 +110,12 @@ public class ChunkPos {
@Override
public boolean equals(Object object) {
- return this == object || object instanceof ChunkPos chunkPos && this.x == chunkPos.x && this.z == chunkPos.z;
+ // DivineMC start - Use standard equals
+ if (object == this) return true;
+ if (object == null || object.getClass() != this.getClass()) return false;
+ ChunkPos thatPos = (ChunkPos) object;
+ return this.x == thatPos.x && this.z == thatPos.z;
+ // DivineMC end
}
public int getMiddleBlockX() {
diff --git a/src/main/java/net/minecraft/world/level/levelgen/Beardifier.java b/src/main/java/net/minecraft/world/level/levelgen/Beardifier.java
index ca93a97256350789ca56f910862c9d717ca7670b..3597fa53c6c58540cb37a9bf27c71e18ebf47660 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/Beardifier.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/Beardifier.java
@@ -132,8 +132,14 @@ public class Beardifier implements DensityFunctions.BeardifierOrMarker {
}
private static double getBuryContribution(double x, double y, double z) {
- double d = Mth.length(x, y, z);
- return Mth.clampedMap(d, 0.0, 6.0, 1.0, 0.0);
+ // DivineMC start - Optimize method for beardifier
+ double d = Math.sqrt(x * x + y * y + z * z);
+ if (d > 6.0) {
+ return 0.0;
+ } else {
+ return 1.0 - d / 6.0;
+ }
+ // DivineMC end
}
private static double getBeardContribution(int x, int y, int z, int yy) {
diff --git a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
index 3f39d6c786d9dfdd9ad591e08ff05fcbb41a1df6..3874da1d4d78be91b4a4d67ef7eb3374d944b373 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
@@ -74,11 +74,10 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator {
Aquifer.FluidStatus aquifer_b = new Aquifer.FluidStatus(-54, Blocks.LAVA.defaultBlockState());
int i = settings.seaLevel();
Aquifer.FluidStatus aquifer_b1 = new Aquifer.FluidStatus(i, settings.defaultFluid());
- Aquifer.FluidStatus aquifer_b2 = new Aquifer.FluidStatus(DimensionType.MIN_Y * 2, Blocks.AIR.defaultBlockState());
-
- return (j, k, l) -> {
- return k < Math.min(-54, i) ? aquifer_b : aquifer_b1;
- };
+ // DivineMC start - Optimize world gen
+ final int min = Math.min(-54, i);
+ return (j, k, l) -> k < min ? aquifer_b : aquifer_b1;
+ // DivineMC end
}
@Override
diff --git a/src/main/java/net/minecraft/world/level/levelgen/synth/PerlinNoise.java b/src/main/java/net/minecraft/world/level/levelgen/synth/PerlinNoise.java
index 74a666a45289f0902b426ba57986cd93b41cb42c..c050f59051209dd14a1b8b175a3809769d47bd01 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/synth/PerlinNoise.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/synth/PerlinNoise.java
@@ -218,7 +218,7 @@ public class PerlinNoise {
}
public static double wrap(double value) {
- return value - (double)Mth.lfloor(value / 3.3554432E7 + 0.5) * 3.3554432E7;
+ return value - Math.floor(value / 3.3554432E7 + 0.5) * 3.3554432E7; // DivineMC - Avoid casting
}
protected int firstOctave() {

View File

@@ -9,12 +9,12 @@ You can find the original code on https://github.com/Bloom-host/Petal
Makes most pathfinding-related work happen asynchronously Makes most pathfinding-related work happen asynchronously
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java b/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java b/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
index ecd1bbd17cb0134cf1f4e99a3fea9e205d38f46b..42eaa860860890b90dfa1b4deeee396ae87e00cf 100644 index 273ba657926ce72a7c82861e880a82bf7f322a0b..8fe72d0cfbc6428671081417a6c7d93276b2a3b1 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java --- a/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/AcquirePoi.java
@@ -76,23 +76,56 @@ public class AcquirePoi { @@ -94,23 +94,56 @@ public class AcquirePoi {
io.papermc.paper.util.PoiAccess.findNearestPoiPositions(poiManager, poiPredicate, predicate2, entity.blockPosition(), world.purpurConfig.villagerAcquirePoiSearchRadius, world.purpurConfig.villagerAcquirePoiSearchRadius*world.purpurConfig.villagerAcquirePoiSearchRadius, PoiManager.Occupancy.HAS_SPACE, false, 5, poiposes); // Purpur }
Set<Pair<Holder<PoiType>, BlockPos>> set = new java.util.HashSet<>(poiposes); }
// Paper end - optimise POI access // Paper end - optimise POI access
- Path path = findPathToPois(entity, set); - Path path = findPathToPois(entity, set);
- if (path != null && path.canReach()) { - if (path != null && path.canReach()) {
@@ -31,7 +31,7 @@ index ecd1bbd17cb0134cf1f4e99a3fea9e205d38f46b..42eaa860860890b90dfa1b4deeee396a
+ Path possiblePath = findPathToPois(entity, set); + Path possiblePath = findPathToPois(entity, set);
+ +
+ // wait on the path to be processed + // wait on the path to be processed
+ space.bxteam.divinemc.pathfinding.AsyncPathProcessor.awaitProcessing(entity, possiblePath, path -> { + space.bxteam.divinemc.pathfinding.AsyncPathProcessor.awaitProcessing(possiblePath, path -> {
+ // read canReach check + // read canReach check
+ if (path == null || !path.canReach()) { + if (path == null || !path.canReach()) {
+ for (Pair<Holder<PoiType>, BlockPos> pair : set) { + for (Pair<Holder<PoiType>, BlockPos> pair : set) {
@@ -60,7 +60,6 @@ index ecd1bbd17cb0134cf1f4e99a3fea9e205d38f46b..42eaa860860890b90dfa1b4deeee396a
- long2ObjectMap.computeIfAbsent( - long2ObjectMap.computeIfAbsent(
- pair.getSecond().asLong(), m -> new AcquirePoi.JitteredLinearRetry(world.random, time) - pair.getSecond().asLong(), m -> new AcquirePoi.JitteredLinearRetry(world.random, time)
- ); - );
+ // DivineMC end
+ Path path = findPathToPois(entity, set); + Path path = findPathToPois(entity, set);
+ if (path != null && path.canReach()) { + if (path != null && path.canReach()) {
+ BlockPos blockPos = path.getTarget(); + BlockPos blockPos = path.getTarget();
@@ -78,13 +77,13 @@ index ecd1bbd17cb0134cf1f4e99a3fea9e205d38f46b..42eaa860860890b90dfa1b4deeee396a
+ ); + );
+ } + }
} }
- } }
+ } // DivineMC + // DivineMC end
return true; return true;
} }
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java b/src/main/java/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java b/src/main/java/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java
index 2a7a26ca447cc78f24e61a2bf557411c31eb16b2..b7fa1c3c564d3c45ac559fd4ec73c3f9f6911576 100644 index 2a7a26ca447cc78f24e61a2bf557411c31eb16b2..58f55ce47e277e195058a5c1d07799e4a7850d7c 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java --- a/src/main/java/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/MoveToTargetSink.java
@@ -21,6 +21,7 @@ public class MoveToTargetSink extends Behavior<Mob> { @@ -21,6 +21,7 @@ public class MoveToTargetSink extends Behavior<Mob> {
@@ -104,7 +103,7 @@ index 2a7a26ca447cc78f24e61a2bf557411c31eb16b2..b7fa1c3c564d3c45ac559fd4ec73c3f9
this.lastTargetPos = walkTarget.getTarget().currentBlockPosition(); this.lastTargetPos = walkTarget.getTarget().currentBlockPosition();
return true; return true;
+ } else if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding && !bl) { // DivineMC - async pathfinding + } else if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding && !bl) { // DivineMC - async pathfinding
+ return true; + return true;
} else { } else {
brain.eraseMemory(MemoryModuleType.WALK_TARGET); brain.eraseMemory(MemoryModuleType.WALK_TARGET);
if (bl) { if (bl) {
@@ -112,7 +111,7 @@ index 2a7a26ca447cc78f24e61a2bf557411c31eb16b2..b7fa1c3c564d3c45ac559fd4ec73c3f9
@Override @Override
protected boolean canStillUse(ServerLevel world, Mob entity, long time) { protected boolean canStillUse(ServerLevel world, Mob entity, long time) {
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding && !this.finishedProcessing) return true; // DivineMC - petal - wait for processing + if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding && !this.finishedProcessing) return true; // DivineMC - wait for processing
if (this.path != null && this.lastTargetPos != null) { if (this.path != null && this.lastTargetPos != null) {
Optional<WalkTarget> optional = entity.getBrain().getMemory(MemoryModuleType.WALK_TARGET); Optional<WalkTarget> optional = entity.getBrain().getMemory(MemoryModuleType.WALK_TARGET);
boolean bl = optional.map(MoveToTargetSink::isWalkTargetSpectator).orElse(false); boolean bl = optional.map(MoveToTargetSink::isWalkTargetSpectator).orElse(false);
@@ -181,7 +180,7 @@ index 2a7a26ca447cc78f24e61a2bf557411c31eb16b2..b7fa1c3c564d3c45ac559fd4ec73c3f9
+ +
+ mob.getBrain().setMemory(MemoryModuleType.PATH, this.path); + mob.getBrain().setMemory(MemoryModuleType.PATH, this.path);
+ mob.getNavigation().moveTo(this.path, this.speedModifier); + mob.getNavigation().moveTo(this.path, this.speedModifier);
} + }
+ +
+ Path path = mob.getNavigation().getPath(); + Path path = mob.getNavigation().getPath();
+ Brain<?> brain = mob.getBrain(); + Brain<?> brain = mob.getBrain();
@@ -193,13 +192,12 @@ index 2a7a26ca447cc78f24e61a2bf557411c31eb16b2..b7fa1c3c564d3c45ac559fd4ec73c3f9
+ } + }
+ } + }
+ } else { + } else {
+ // DivineMC end
+ Path path = mob.getNavigation().getPath(); + Path path = mob.getNavigation().getPath();
+ Brain<?> brain = mob.getBrain(); + Brain<?> brain = mob.getBrain();
+ if (this.path != path) { + if (this.path != path) {
+ this.path = path; + this.path = path;
+ brain.setMemory(MemoryModuleType.PATH, path); + brain.setMemory(MemoryModuleType.PATH, path);
+ } }
+ +
+ if (path != null && this.lastTargetPos != null) { + if (path != null && this.lastTargetPos != null) {
+ WalkTarget walkTarget = brain.getMemory(MemoryModuleType.WALK_TARGET).get(); + WalkTarget walkTarget = brain.getMemory(MemoryModuleType.WALK_TARGET).get();
@@ -210,6 +208,7 @@ index 2a7a26ca447cc78f24e61a2bf557411c31eb16b2..b7fa1c3c564d3c45ac559fd4ec73c3f9
+ } + }
+ } + }
+ } + }
+ // DivineMC end
+ } + }
+ +
+ // DivineMC start - Async path processing + // DivineMC start - Async path processing
@@ -228,10 +227,10 @@ index 2a7a26ca447cc78f24e61a2bf557411c31eb16b2..b7fa1c3c564d3c45ac559fd4ec73c3f9
private boolean tryComputePath(Mob entity, WalkTarget walkTarget, long time) { private boolean tryComputePath(Mob entity, WalkTarget walkTarget, long time) {
BlockPos blockPos = walkTarget.getTarget().currentBlockPosition(); BlockPos blockPos = walkTarget.getTarget().currentBlockPosition();
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java b/src/main/java/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java b/src/main/java/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java
index 6802e0c4d331c7125114dd86409f6a110465ab82..0b68b4248e85280199f99da80487520dd0d8b7a0 100644 index 6802e0c4d331c7125114dd86409f6a110465ab82..59e4360006499ca9a90f1b12747024ee7b8ba3ad 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java --- a/src/main/java/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java +++ b/src/main/java/net/minecraft/world/entity/ai/behavior/SetClosestHomeAsWalkTarget.java
@@ -60,16 +60,37 @@ public class SetClosestHomeAsWalkTarget { @@ -60,17 +60,39 @@ public class SetClosestHomeAsWalkTarget {
poiType -> poiType.is(PoiTypes.HOME), predicate, entity.blockPosition(), 48, PoiManager.Occupancy.ANY poiType -> poiType.is(PoiTypes.HOME), predicate, entity.blockPosition(), 48, PoiManager.Occupancy.ANY
) )
.collect(Collectors.toSet()); .collect(Collectors.toSet());
@@ -248,7 +247,7 @@ index 6802e0c4d331c7125114dd86409f6a110465ab82..0b68b4248e85280199f99da80487520d
+ Path possiblePath = AcquirePoi.findPathToPois(entity, set); + Path possiblePath = AcquirePoi.findPathToPois(entity, set);
+ +
+ // wait on the path to be processed + // wait on the path to be processed
+ space.bxteam.divinemc.pathfinding.AsyncPathProcessor.awaitProcessing(entity, possiblePath, path -> { + space.bxteam.divinemc.pathfinding.AsyncPathProcessor.awaitProcessing(possiblePath, path -> {
+ if (path == null || !path.canReach() || mutableInt.getValue() < 5) { // read canReach check + if (path == null || !path.canReach() || mutableInt.getValue() < 5) { // read canReach check
+ long2LongMap.long2LongEntrySet().removeIf(entry -> entry.getLongValue() < mutableLong.getValue()); + long2LongMap.long2LongEntrySet().removeIf(entry -> entry.getLongValue() < mutableLong.getValue());
+ return; + return;
@@ -261,7 +260,7 @@ index 6802e0c4d331c7125114dd86409f6a110465ab82..0b68b4248e85280199f99da80487520d
+ } + }
+ }); + });
+ } else { + } else {
+ // DivineMC end + // Kaiiju end
+ Path path = AcquirePoi.findPathToPois(entity, set); + Path path = AcquirePoi.findPathToPois(entity, set);
+ if (path != null && path.canReach()) { + if (path != null && path.canReach()) {
+ BlockPos blockPos = path.getTarget(); + BlockPos blockPos = path.getTarget();
@@ -276,26 +275,28 @@ index 6802e0c4d331c7125114dd86409f6a110465ab82..0b68b4248e85280199f99da80487520d
- } else if (mutableInt.getValue() < 5) { - } else if (mutableInt.getValue() < 5) {
- long2LongMap.long2LongEntrySet().removeIf(entry -> entry.getLongValue() < mutableLong.getValue()); - long2LongMap.long2LongEntrySet().removeIf(entry -> entry.getLongValue() < mutableLong.getValue());
} }
+ // DivineMC end
return true; return true;
} else {
diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/DoorInteractGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/DoorInteractGoal.java diff --git a/src/main/java/net/minecraft/world/entity/ai/goal/DoorInteractGoal.java b/src/main/java/net/minecraft/world/entity/ai/goal/DoorInteractGoal.java
index 74aca307b4ebffe4e33c4fca3e07c23ca87622ac..638104ed241bd47bff7cbdd65f63870e80d9b091 100644 index 2846790fcd00788cf0284c348161ee1aee415f13..ce229db4fbd364a49d398fcafa9c45a5dff3f211 100644
--- a/src/main/java/net/minecraft/world/entity/ai/goal/DoorInteractGoal.java --- a/src/main/java/net/minecraft/world/entity/ai/goal/DoorInteractGoal.java
+++ b/src/main/java/net/minecraft/world/entity/ai/goal/DoorInteractGoal.java +++ b/src/main/java/net/minecraft/world/entity/ai/goal/DoorInteractGoal.java
@@ -56,7 +56,7 @@ public abstract class DoorInteractGoal extends Goal { @@ -56,7 +56,7 @@ public abstract class DoorInteractGoal extends Goal {
} else { } else {
GroundPathNavigation groundPathNavigation = (GroundPathNavigation)this.mob.getNavigation(); GroundPathNavigation groundPathNavigation = (GroundPathNavigation)this.mob.getNavigation();
Path path = groundPathNavigation.getPath(); Path path = groundPathNavigation.getPath();
- if (path != null && !path.isDone() && groundPathNavigation.canOpenDoors()) { - if (path != null && !path.isDone()) {
+ if (path != null && path.isProcessed() && !path.isDone() && groundPathNavigation.canOpenDoors()) { // DivineMC - async pathfinding - ensure path is processed + if (path != null && path.isProcessed() && !path.isDone()) { // DivineMC - ensure path is processed
for (int i = 0; i < Math.min(path.getNextNodeIndex() + 2, path.getNodeCount()); i++) { for (int i = 0; i < Math.min(path.getNextNodeIndex() + 2, path.getNodeCount()); i++) {
Node node = path.getNode(i); Node node = path.getNode(i);
this.doorPos = new BlockPos(node.x, node.y + 1, node.z); this.doorPos = new BlockPos(node.x, node.y + 1, node.z);
diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java
index ee38e447a810094d2253b85714b74282a4b4c2bc..418961feef15779bbf4a7da42d8d3bd2f0564da5 100644 index 29b852c3262c9cd0d2c77a93c01a386a2c184742..2e97ecce7684b2a701d8b89981426326a1f5bb2a 100644
--- a/src/main/java/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java --- a/src/main/java/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java
+++ b/src/main/java/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/AmphibiousPathNavigation.java
@@ -12,10 +12,26 @@ public class AmphibiousPathNavigation extends PathNavigation { @@ -12,9 +12,25 @@ public class AmphibiousPathNavigation extends PathNavigation {
super(mob, world); super(mob, world);
} }
@@ -313,7 +314,6 @@ index ee38e447a810094d2253b85714b74282a4b4c2bc..418961feef15779bbf4a7da42d8d3bd2
@Override @Override
protected PathFinder createPathFinder(int range) { protected PathFinder createPathFinder(int range) {
this.nodeEvaluator = new AmphibiousNodeEvaluator(false); this.nodeEvaluator = new AmphibiousNodeEvaluator(false);
this.nodeEvaluator.setCanPassDoors(true);
+ // DivineMC start - async path processing + // DivineMC start - async path processing
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) { + if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ return new PathFinder(this.nodeEvaluator, range, nodeEvaluatorGenerator); + return new PathFinder(this.nodeEvaluator, range, nodeEvaluatorGenerator);
@@ -323,10 +323,10 @@ index ee38e447a810094d2253b85714b74282a4b4c2bc..418961feef15779bbf4a7da42d8d3bd2
} }
diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java
index a3e0c5af4cc9323c02e88e768cbda9e46854aea1..05e5b7e2785e09492656261f37e7aadf2669a7de 100644 index 2bd66da93227d4e4fc2ec4df47ae94b17f4d39d3..7b47d4f91eaf38cb132681bbfd0a17a9119ed930 100644
--- a/src/main/java/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java --- a/src/main/java/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java
+++ b/src/main/java/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/FlyingPathNavigation.java
@@ -16,10 +16,26 @@ public class FlyingPathNavigation extends PathNavigation { @@ -16,9 +16,25 @@ public class FlyingPathNavigation extends PathNavigation {
super(entity, world); super(entity, world);
} }
@@ -344,7 +344,6 @@ index a3e0c5af4cc9323c02e88e768cbda9e46854aea1..05e5b7e2785e09492656261f37e7aadf
@Override @Override
protected PathFinder createPathFinder(int range) { protected PathFinder createPathFinder(int range) {
this.nodeEvaluator = new FlyNodeEvaluator(); this.nodeEvaluator = new FlyNodeEvaluator();
this.nodeEvaluator.setCanPassDoors(true);
+ // DivineMC start - async path processing + // DivineMC start - async path processing
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) { + if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ return new PathFinder(this.nodeEvaluator, range, nodeEvaluatorGenerator); + return new PathFinder(this.nodeEvaluator, range, nodeEvaluatorGenerator);
@@ -353,19 +352,19 @@ index a3e0c5af4cc9323c02e88e768cbda9e46854aea1..05e5b7e2785e09492656261f37e7aadf
return new PathFinder(this.nodeEvaluator, range); return new PathFinder(this.nodeEvaluator, range);
} }
@@ -49,6 +65,7 @@ public class FlyingPathNavigation extends PathNavigation { @@ -48,6 +64,7 @@ public class FlyingPathNavigation extends PathNavigation {
if (this.hasDelayedRecomputation) { if (this.hasDelayedRecomputation) {
this.recomputePath(); this.recomputePath();
} }
+ if (this.path != null && !this.path.isProcessed()) return; // DivineMC - petal - async path processing + if (this.path != null && !this.path.isProcessed()) return; // DivineMC - async path processing
if (!this.isDone()) { if (!this.isDone()) {
if (this.canUpdatePath()) { if (this.canUpdatePath()) {
diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java
index 62634bedd97c5be9ecce24ab0cff205715a68da8..dc5f3402eb0b5404af40c248f550e603b9ef9ac2 100644 index 2796df7af365c452b28373adfd7daf1d6730bac5..ec14600b3de361d2265f86092e69eca61d732c44 100644
--- a/src/main/java/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java --- a/src/main/java/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java
+++ b/src/main/java/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java
@@ -23,10 +23,26 @@ public class GroundPathNavigation extends PathNavigation { @@ -24,9 +24,25 @@ public class GroundPathNavigation extends PathNavigation {
super(entity, world); super(entity, world);
} }
@@ -383,7 +382,6 @@ index 62634bedd97c5be9ecce24ab0cff205715a68da8..dc5f3402eb0b5404af40c248f550e603
@Override @Override
protected PathFinder createPathFinder(int range) { protected PathFinder createPathFinder(int range) {
this.nodeEvaluator = new WalkNodeEvaluator(); this.nodeEvaluator = new WalkNodeEvaluator();
this.nodeEvaluator.setCanPassDoors(true);
+ // DivineMC start - async path processing + // DivineMC start - async path processing
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) { + if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ return new PathFinder(this.nodeEvaluator, range, nodeEvaluatorGenerator); + return new PathFinder(this.nodeEvaluator, range, nodeEvaluatorGenerator);
@@ -393,10 +391,10 @@ index 62634bedd97c5be9ecce24ab0cff205715a68da8..dc5f3402eb0b5404af40c248f550e603
} }
diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java
index 544920a31b649985333f82beafa94a3392f5853e..98b97269886b0ff3bbb32444d3e825c39b2ff175 100644 index 48c0de870a5bbf647309e69361dfb10ab56c65ab..fc9605882fe5011606d05f6a0d77728f134a5733 100644
--- a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java --- a/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java
+++ b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/PathNavigation.java
@@ -152,6 +152,10 @@ public abstract class PathNavigation { @@ -168,6 +168,10 @@ public abstract class PathNavigation {
return null; return null;
} else if (!this.canUpdatePath()) { } else if (!this.canUpdatePath()) {
return null; return null;
@@ -407,11 +405,11 @@ index 544920a31b649985333f82beafa94a3392f5853e..98b97269886b0ff3bbb32444d3e825c3
} else if (this.path != null && !this.path.isDone() && positions.contains(this.targetPos)) { } else if (this.path != null && !this.path.isDone() && positions.contains(this.targetPos)) {
return this.path; return this.path;
} else { } else {
@@ -177,11 +181,28 @@ public abstract class PathNavigation { @@ -194,12 +198,30 @@ public abstract class PathNavigation {
int i = (int)(followRange + (float)range); int i = (int)(followRange + (float)range);
PathNavigationRegion pathNavigationRegion = new PathNavigationRegion(this.level, blockPos.offset(-i, -i, -i), blockPos.offset(i, i, i)); PathNavigationRegion pathNavigationRegion = new PathNavigationRegion(this.level, blockPos.offset(-i, -i, -i), blockPos.offset(i, i, i));
Path path = this.pathFinder.findPath(pathNavigationRegion, this.mob, positions, followRange, distance, this.maxVisitedNodesMultiplier); Path path = this.pathFinder.findPath(pathNavigationRegion, this.mob, positions, followRange, distance, this.maxVisitedNodesMultiplier);
- //this.level.getProfiler().pop(); // Purpur - profilerFiller.pop();
- if (path != null && path.getTarget() != null) { - if (path != null && path.getTarget() != null) {
- this.targetPos = path.getTarget(); - this.targetPos = path.getTarget();
- this.reachRange = distance; - this.reachRange = distance;
@@ -421,7 +419,7 @@ index 544920a31b649985333f82beafa94a3392f5853e..98b97269886b0ff3bbb32444d3e825c3
+ // assign early a target position. most calls will only have 1 position + // assign early a target position. most calls will only have 1 position
+ if (!positions.isEmpty()) this.targetPos = positions.iterator().next(); + if (!positions.isEmpty()) this.targetPos = positions.iterator().next();
+ +
+ space.bxteam.divinemc.pathfinding.AsyncPathProcessor.awaitProcessing(mob, path, processedPath -> { + space.bxteam.divinemc.pathfinding.AsyncPathProcessor.awaitProcessing(path, processedPath -> {
+ // check that processing didn't take so long that we calculated a new path + // check that processing didn't take so long that we calculated a new path
+ if (processedPath != this.path) return; + if (processedPath != this.path) return;
+ +
@@ -432,56 +430,58 @@ index 544920a31b649985333f82beafa94a3392f5853e..98b97269886b0ff3bbb32444d3e825c3
+ } + }
+ }); + });
+ } else { + } else {
+ // DivineMC end + profilerFiller.pop();
+ if (path != null && path.getTarget() != null) { + if (path != null && path.getTarget() != null) {
+ this.targetPos = path.getTarget(); + this.targetPos = path.getTarget();
+ this.reachRange = distance; + this.reachRange = distance;
+ this.resetStuckTimeout(); + this.resetStuckTimeout();
+ } + }
} }
+ // DivineMC end
return path; return path;
@@ -233,8 +254,8 @@ public abstract class PathNavigation { }
@@ -250,8 +272,8 @@ public abstract class PathNavigation {
if (this.isDone()) { if (this.isDone()) {
return false; return false;
} else { } else {
- this.trimPath(); - this.trimPath();
- if (this.path.getNodeCount() <= 0) { - if (this.path.getNodeCount() <= 0) {
+ if (path.isProcessed()) this.trimPath(); // DivineMC - petal - only trim if processed + if (path.isProcessed()) this.trimPath(); // DivineMC - only trim if processed
+ if (path.isProcessed() && this.path.getNodeCount() <= 0) { // DivineMC - petal - only check node count if processed + if (path.isProcessed() && this.path.getNodeCount() <= 0) { // DivineMC - only check node count if processed
return false; return false;
} else { } else {
this.speedModifier = speed; this.speedModifier = speed;
@@ -257,6 +278,7 @@ public abstract class PathNavigation { @@ -274,6 +296,7 @@ public abstract class PathNavigation {
if (this.hasDelayedRecomputation) { if (this.hasDelayedRecomputation) {
this.recomputePath(); this.recomputePath();
} }
+ if (this.path != null && !this.path.isProcessed()) return; // DivineMC - petal - skip pathfinding if we're still processing + if (this.path != null && !this.path.isProcessed()) return; // DivineMC - skip pathfinding if we're still processing
if (!this.isDone()) { if (!this.isDone()) {
if (this.canUpdatePath()) { if (this.canUpdatePath()) {
@@ -283,6 +305,7 @@ public abstract class PathNavigation { @@ -300,6 +323,7 @@ public abstract class PathNavigation {
} }
protected void followThePath() { protected void followThePath() {
+ if (!this.path.isProcessed()) return; // DivineMC - petal - skip if not processed + if (!this.path.isProcessed()) return; // DivineMC - skip if not processed
Vec3 vec3 = this.getTempMobPos(); Vec3 vec3 = this.getTempMobPos();
this.maxDistanceToWaypoint = this.mob.getBbWidth() > 0.75F ? this.mob.getBbWidth() / 2.0F : 0.75F - this.mob.getBbWidth() / 2.0F; this.maxDistanceToWaypoint = this.mob.getBbWidth() > 0.75F ? this.mob.getBbWidth() / 2.0F : 0.75F - this.mob.getBbWidth() / 2.0F;
Vec3i vec3i = this.path.getNextNodePos(); Vec3i vec3i = this.path.getNextNodePos();
@@ -439,7 +462,7 @@ public abstract class PathNavigation { @@ -456,7 +480,7 @@ public abstract class PathNavigation {
public boolean shouldRecomputePath(BlockPos pos) { public boolean shouldRecomputePath(BlockPos pos) {
if (this.hasDelayedRecomputation) { if (this.hasDelayedRecomputation) {
return false; return false;
- } else if (this.path != null && !this.path.isDone() && this.path.getNodeCount() != 0) { - } else if (this.path != null && !this.path.isDone() && this.path.getNodeCount() != 0) {
+ } else if (this.path != null && this.path.isProcessed() && !this.path.isDone() && this.path.getNodeCount() != 0) { // DivineMC - petal - Skip if not processed + } else if (this.path != null && this.path.isProcessed() && !this.path.isDone() && this.path.getNodeCount() != 0) { // DivineMC - Skip if not processed
Node node = this.path.getEndNode(); Node node = this.path.getEndNode();
Vec3 vec3 = new Vec3(((double)node.x + this.mob.getX()) / 2.0, ((double)node.y + this.mob.getY()) / 2.0, ((double)node.z + this.mob.getZ()) / 2.0); Vec3 vec3 = new Vec3(((double)node.x + this.mob.getX()) / 2.0, ((double)node.y + this.mob.getY()) / 2.0, ((double)node.z + this.mob.getZ()) / 2.0);
return pos.closerToCenterThan(vec3, (double)(this.path.getNodeCount() - this.path.getNextNodeIndex())); return pos.closerToCenterThan(vec3, (double)(this.path.getNodeCount() - this.path.getNextNodeIndex()));
diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java diff --git a/src/main/java/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java b/src/main/java/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java
index ce7398a617abe6e800c1e014b3ac5c970eb15c8a..c37ec1c55b5104456788b270c1ceee7cc67e5bed 100644 index 943c9944ae17fa7cd72e437cce61beaf3fc9505e..606d00d251126d56d57d2d4f1383dea5087a1147 100644
--- a/src/main/java/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java --- a/src/main/java/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java
+++ b/src/main/java/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java +++ b/src/main/java/net/minecraft/world/entity/ai/navigation/WaterBoundPathNavigation.java
@@ -15,10 +15,26 @@ public class WaterBoundPathNavigation extends PathNavigation { @@ -15,11 +15,27 @@ public class WaterBoundPathNavigation extends PathNavigation {
super(entity, world); super(entity, world);
} }
@@ -500,6 +500,7 @@ index ce7398a617abe6e800c1e014b3ac5c970eb15c8a..c37ec1c55b5104456788b270c1ceee7c
protected PathFinder createPathFinder(int range) { protected PathFinder createPathFinder(int range) {
this.allowBreaching = this.mob.getType() == EntityType.DOLPHIN; this.allowBreaching = this.mob.getType() == EntityType.DOLPHIN;
this.nodeEvaluator = new SwimNodeEvaluator(this.allowBreaching); this.nodeEvaluator = new SwimNodeEvaluator(this.allowBreaching);
this.nodeEvaluator.setCanPassDoors(false);
+ // DivineMC start - async path processing + // DivineMC start - async path processing
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) { + if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ return new PathFinder(this.nodeEvaluator, range, nodeEvaluatorGenerator); + return new PathFinder(this.nodeEvaluator, range, nodeEvaluatorGenerator);
@@ -509,7 +510,7 @@ index ce7398a617abe6e800c1e014b3ac5c970eb15c8a..c37ec1c55b5104456788b270c1ceee7c
} }
diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java
index 9104d7010bda6f9f73b478c11490ef9c53f76da2..4ff94a69f44df3582173be8254754484dca1936a 100644 index 9104d7010bda6f9f73b478c11490ef9c53f76da2..e609d1b11d8c8924e4838e3cf5e9b6ac14807e8d 100644
--- a/src/main/java/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java --- a/src/main/java/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java
+++ b/src/main/java/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java +++ b/src/main/java/net/minecraft/world/entity/ai/sensing/NearestBedSensor.java
@@ -57,17 +57,37 @@ public class NearestBedSensor extends Sensor<Mob> { @@ -57,17 +57,37 @@ public class NearestBedSensor extends Sensor<Mob> {
@@ -526,7 +527,7 @@ index 9104d7010bda6f9f73b478c11490ef9c53f76da2..4ff94a69f44df3582173be8254754484
+ // DivineMC start - await on async path processing + // DivineMC start - await on async path processing
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) { + if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ Path possiblePath = AcquirePoi.findPathToPois(entity, new java.util.HashSet<>(poiposes)); + Path possiblePath = AcquirePoi.findPathToPois(entity, new java.util.HashSet<>(poiposes));
+ space.bxteam.divinemc.pathfinding.AsyncPathProcessor.awaitProcessing(entity, possiblePath, path -> { + space.bxteam.divinemc.pathfinding.AsyncPathProcessor.awaitProcessing(possiblePath, path -> {
+ // read canReach check + // read canReach check
+ if ((path == null || !path.canReach()) && this.triedCount < 5) { + if ((path == null || !path.canReach()) && this.triedCount < 5) {
+ this.batchCache.long2LongEntrySet().removeIf(entry -> entry.getLongValue() < this.lastUpdate); + this.batchCache.long2LongEntrySet().removeIf(entry -> entry.getLongValue() < this.lastUpdate);
@@ -541,7 +542,6 @@ index 9104d7010bda6f9f73b478c11490ef9c53f76da2..4ff94a69f44df3582173be8254754484
+ } + }
+ }); + });
+ } else { + } else {
+ // DivineMC end
+ Path path = AcquirePoi.findPathToPois(entity, new java.util.HashSet<>(poiposes)); + Path path = AcquirePoi.findPathToPois(entity, new java.util.HashSet<>(poiposes));
+ // Paper end - optimise POI access + // Paper end - optimise POI access
+ if (path != null && path.canReach()) { + if (path != null && path.canReach()) {
@@ -555,38 +555,38 @@ index 9104d7010bda6f9f73b478c11490ef9c53f76da2..4ff94a69f44df3582173be8254754484
} }
- } else if (this.triedCount < 5) { - } else if (this.triedCount < 5) {
- this.batchCache.long2LongEntrySet().removeIf(entry -> entry.getLongValue() < this.lastUpdate); - this.batchCache.long2LongEntrySet().removeIf(entry -> entry.getLongValue() < this.lastUpdate);
- } }
+ } // DivineMC + // DivineMC end
} }
} }
} }
diff --git a/src/main/java/net/minecraft/world/entity/animal/Bee.java b/src/main/java/net/minecraft/world/entity/animal/Bee.java diff --git a/src/main/java/net/minecraft/world/entity/animal/Bee.java b/src/main/java/net/minecraft/world/entity/animal/Bee.java
index 5f228ea02b8912283dfb9a7bd18b33802b1d77ab..b9945658239589ad840a2712db6c08175c9c8dc6 100644 index 3fa17c5e74bec5fd719df415eebe2d622a0c28e1..2fb060484f4914e81cb60f51fa2b675b903fe5d7 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Bee.java --- a/src/main/java/net/minecraft/world/entity/animal/Bee.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java +++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java
@@ -1147,7 +1147,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { @@ -1240,7 +1240,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
} else { } else {
Bee.this.pathfindRandomlyTowards(Bee.this.hivePos); Bee.this.pathfindRandomlyTowards(Bee.this.hivePos);
} }
- } else { - } else {
+ } else if (navigation.getPath() != null && navigation.getPath().isProcessed()) { // DivineMC - petal - check processing + } else if (navigation.getPath() != null && navigation.getPath().isProcessed()) { // DivineMC - check processing
boolean flag = this.pathfindDirectlyTowards(Bee.this.hivePos); boolean flag = this.pathfindDirectlyTowards(Bee.this.hivePos);
if (!flag) { if (!flag) {
@@ -1209,7 +1209,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal { @@ -1299,7 +1299,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
} else { } else {
Path pathentity = Bee.this.navigation.getPath(); Path pathentity = Bee.this.navigation.getPath();
- return pathentity != null && pathentity.getTarget().equals(pos) && pathentity.canReach() && pathentity.isDone(); - return pathentity != null && pathentity.getTarget().equals(pos) && pathentity.canReach() && pathentity.isDone();
+ return pathentity != null && pathentity.isProcessed() && pathentity.getTarget().equals(pos) && pathentity.canReach() && pathentity.isDone(); // DivineMC - petal - ensure path is processed + return pathentity != null && pathentity.isProcessed() && pathentity.getTarget().equals(pos) && pathentity.canReach() && pathentity.isDone(); // DivineMC - ensure path is processed
} }
} }
} }
diff --git a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java diff --git a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java
index 418e8b9227789cc100c5972901bbe8c939c652d3..cad95339c2c2e5a8139e57fb761cd47be6edd1a4 100644 index b06946ea57285bb9ec0a70854c9359af9d72e979..40a2a10638b08f786eb6598fd1ee6d6b28329d3c 100644
--- a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java --- a/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java
+++ b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java +++ b/src/main/java/net/minecraft/world/entity/animal/frog/Frog.java
@@ -486,6 +486,17 @@ public class Frog extends Animal implements VariantHolder<Holder<FrogVariant>> { @@ -499,6 +499,17 @@ public class Frog extends Animal implements VariantHolder<Holder<FrogVariant>> {
super(frog, world); super(frog, world);
} }
@@ -604,10 +604,10 @@ index 418e8b9227789cc100c5972901bbe8c939c652d3..cad95339c2c2e5a8139e57fb761cd47b
@Override @Override
public boolean canCutCorner(PathType nodeType) { public boolean canCutCorner(PathType nodeType) {
return nodeType != PathType.WATER_BORDER && super.canCutCorner(nodeType); return nodeType != PathType.WATER_BORDER && super.canCutCorner(nodeType);
@@ -495,6 +506,11 @@ public class Frog extends Animal implements VariantHolder<Holder<FrogVariant>> { @@ -507,6 +518,11 @@ public class Frog extends Animal implements VariantHolder<Holder<FrogVariant>> {
@Override
protected PathFinder createPathFinder(int range) { protected PathFinder createPathFinder(int range) {
this.nodeEvaluator = new Frog.FrogNodeEvaluator(true); this.nodeEvaluator = new Frog.FrogNodeEvaluator(true);
this.nodeEvaluator.setCanPassDoors(true);
+ // DivineMC start - async path processing + // DivineMC start - async path processing
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) { + if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ return new PathFinder(this.nodeEvaluator, range, nodeEvaluatorGenerator); + return new PathFinder(this.nodeEvaluator, range, nodeEvaluatorGenerator);
@@ -617,23 +617,23 @@ index 418e8b9227789cc100c5972901bbe8c939c652d3..cad95339c2c2e5a8139e57fb761cd47b
} }
} }
diff --git a/src/main/java/net/minecraft/world/entity/monster/Drowned.java b/src/main/java/net/minecraft/world/entity/monster/Drowned.java diff --git a/src/main/java/net/minecraft/world/entity/monster/Drowned.java b/src/main/java/net/minecraft/world/entity/monster/Drowned.java
index 94de51bf9acb32421838ffe54602310f0263b3c4..f638ac3097b87ac706f3f82a15bfb514287d17f8 100644 index a28a4cd9544ffa58bd03ac901a761c797044629a..6186d9d30b767b58c61485dad3173ddcd63d6aaf 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Drowned.java --- a/src/main/java/net/minecraft/world/entity/monster/Drowned.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Drowned.java +++ b/src/main/java/net/minecraft/world/entity/monster/Drowned.java
@@ -296,7 +296,7 @@ public class Drowned extends Zombie implements RangedAttackMob { @@ -305,7 +305,7 @@ public class Drowned extends Zombie implements RangedAttackMob {
protected boolean closeToNextPos() { protected boolean closeToNextPos() {
Path pathentity = this.getNavigation().getPath(); Path path = this.getNavigation().getPath();
- if (path != null) {
- if (pathentity != null) { + if (path != null && path.isProcessed()) { // DivineMC - ensure path is processed
+ if (pathentity != null && pathentity.isProcessed()) { // DivineMC - petal - ensure path is processed BlockPos blockPos = path.getTarget();
BlockPos blockposition = pathentity.getTarget(); if (blockPos != null) {
double d = this.distanceToSqr((double)blockPos.getX(), (double)blockPos.getY(), (double)blockPos.getZ());
if (blockposition != null) {
diff --git a/src/main/java/net/minecraft/world/entity/monster/Strider.java b/src/main/java/net/minecraft/world/entity/monster/Strider.java diff --git a/src/main/java/net/minecraft/world/entity/monster/Strider.java b/src/main/java/net/minecraft/world/entity/monster/Strider.java
index 70650cc6f76bed79a31a9e8c86205910994a920f..2340f207c0e741ace9b2f5e008e59d583705de5c 100644 index 779ae2e63202c1f189b1f5647218a07c21a84ccd..a29c273f6420b5b94fea586d92f3f1944e9d24c7 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Strider.java --- a/src/main/java/net/minecraft/world/entity/monster/Strider.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Strider.java +++ b/src/main/java/net/minecraft/world/entity/monster/Strider.java
@@ -610,10 +610,26 @@ public class Strider extends Animal implements ItemSteerable, Saddleable { @@ -608,9 +608,25 @@ public class Strider extends Animal implements ItemSteerable, Saddleable {
super(entity, world); super(entity, world);
} }
@@ -651,7 +651,6 @@ index 70650cc6f76bed79a31a9e8c86205910994a920f..2340f207c0e741ace9b2f5e008e59d58
@Override @Override
protected PathFinder createPathFinder(int range) { protected PathFinder createPathFinder(int range) {
this.nodeEvaluator = new WalkNodeEvaluator(); this.nodeEvaluator = new WalkNodeEvaluator();
this.nodeEvaluator.setCanPassDoors(true);
+ // DivineMC start - async path processing + // DivineMC start - async path processing
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) { + if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ return new PathFinder(this.nodeEvaluator, range, nodeEvaluatorGenerator); + return new PathFinder(this.nodeEvaluator, range, nodeEvaluatorGenerator);
@@ -661,13 +660,13 @@ index 70650cc6f76bed79a31a9e8c86205910994a920f..2340f207c0e741ace9b2f5e008e59d58
} }
diff --git a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java diff --git a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java
index e7c82656e46201ae144629945dcd33f14774b9de..8fda8e6eef03d87298f2173271aa8894cb729a62 100644 index bc8d7ab331239077079be74527714e170b1d1578..215497e90ea57a2215140232cccf1eba91ebdc55 100644
--- a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java --- a/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java
+++ b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java +++ b/src/main/java/net/minecraft/world/entity/monster/warden/Warden.java
@@ -634,6 +634,16 @@ public class Warden extends Monster implements VibrationSystem { @@ -635,6 +635,16 @@ public class Warden extends Monster implements VibrationSystem {
@Override
protected PathFinder createPathFinder(int range) { protected PathFinder createPathFinder(int range) {
this.nodeEvaluator = new WalkNodeEvaluator(); this.nodeEvaluator = new WalkNodeEvaluator();
this.nodeEvaluator.setCanPassDoors(true);
+ // DivineMC start - async path processing + // DivineMC start - async path processing
+ if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) { + if (space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) {
+ return new PathFinder(this.nodeEvaluator, range, GroundPathNavigation.nodeEvaluatorGenerator) { + return new PathFinder(this.nodeEvaluator, range, GroundPathNavigation.nodeEvaluatorGenerator) {
@@ -682,7 +681,7 @@ index e7c82656e46201ae144629945dcd33f14774b9de..8fda8e6eef03d87298f2173271aa8894
@Override @Override
protected float distance(Node a, Node b) { protected float distance(Node a, Node b) {
diff --git a/src/main/java/net/minecraft/world/level/pathfinder/Path.java b/src/main/java/net/minecraft/world/level/pathfinder/Path.java diff --git a/src/main/java/net/minecraft/world/level/pathfinder/Path.java b/src/main/java/net/minecraft/world/level/pathfinder/Path.java
index d9d0fff9962131808d54cca20f209df50b8e4af1..a0b24f4c245f4b0ffa6dadd5ea8e03a231b64092 100644 index d9d0fff9962131808d54cca20f209df50b8e4af1..4f4ab4068dd72aad9b06f6bfe50045b12a48c139 100644
--- a/src/main/java/net/minecraft/world/level/pathfinder/Path.java --- a/src/main/java/net/minecraft/world/level/pathfinder/Path.java
+++ b/src/main/java/net/minecraft/world/level/pathfinder/Path.java +++ b/src/main/java/net/minecraft/world/level/pathfinder/Path.java
@@ -27,6 +27,17 @@ public class Path { @@ -27,6 +27,17 @@ public class Path {
@@ -707,53 +706,36 @@ index d9d0fff9962131808d54cca20f209df50b8e4af1..a0b24f4c245f4b0ffa6dadd5ea8e03a2
} }
public boolean sameAs(@Nullable Path o) { public boolean sameAs(@Nullable Path o) {
+ if (o == this) return true; // DivineMC - petal - short circuit + if (o == this) return true; // DivineMC - short circuit
if (o == null) { if (o == null) {
return false; return false;
} else if (o.nodes.size() != this.nodes.size()) { } else if (o.nodes.size() != this.nodes.size()) {
diff --git a/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java b/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java diff --git a/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java b/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java
index 404080976208c30e9e95e5bee47c2a749e709a45..fb4ea7b86ead263e21eca6cce93d5ee939e4e57b 100644 index cc7d94144e39f7dace7b569b4567def98396e8f9..6a4d85e61efeb47d4b277e44d761dfc6329f4855 100644
--- a/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java --- a/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java
+++ b/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java +++ b/src/main/java/net/minecraft/world/level/pathfinder/PathFinder.java
@@ -1,19 +1,13 @@ @@ -25,11 +25,19 @@ public class PathFinder {
package net.minecraft.world.level.pathfinder;
-import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
+
import java.util.Comparator;
import java.util.List;
import java.util.Map;
-import java.util.Optional;
import java.util.Set;
-import java.util.function.Function;
-import java.util.stream.Collectors;
import javax.annotation.Nullable;
import net.minecraft.core.BlockPos;
-import net.minecraft.util.profiling.ProfilerFiller;
-import net.minecraft.util.profiling.metrics.MetricCategory;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.level.PathNavigationRegion;
@@ -24,37 +18,80 @@ public class PathFinder {
public final NodeEvaluator nodeEvaluator; public final NodeEvaluator nodeEvaluator;
private static final boolean DEBUG = false; private static final boolean DEBUG = false;
private final BinaryHeap openSet = new BinaryHeap(); private final BinaryHeap openSet = new BinaryHeap();
+ private final @Nullable space.bxteam.divinemc.pathfinding.NodeEvaluatorGenerator nodeEvaluatorGenerator; // DivineMC - petal - we use this later to generate an evaluator + private final @Nullable space.bxteam.divinemc.pathfinding.NodeEvaluatorGenerator nodeEvaluatorGenerator; // DivineMC - petal - we use this later to generate an evaluator
- public PathFinder(NodeEvaluator pathNodeMaker, int range) { - public PathFinder(NodeEvaluator pathNodeMaker, int range) {
+ public PathFinder(NodeEvaluator pathNodeMaker, int range, @Nullable space.bxteam.divinemc.pathfinding.NodeEvaluatorGenerator nodeEvaluatorGenerator) { // DivineMC - petal - add nodeEvaluatorGenerator + public PathFinder(NodeEvaluator pathNodeMaker, int range, @Nullable space.bxteam.divinemc.pathfinding.NodeEvaluatorGenerator nodeEvaluatorGenerator) { // DivineMC - add nodeEvaluatorGenerator
this.nodeEvaluator = pathNodeMaker; this.nodeEvaluator = pathNodeMaker;
this.maxVisitedNodes = range; this.maxVisitedNodes = range;
+ // DivineMC start - petal - support nodeEvaluatorgenerators + // DivineMC start - support nodeEvaluatorgenerators
+ this.nodeEvaluatorGenerator = nodeEvaluatorGenerator; + this.nodeEvaluatorGenerator = nodeEvaluatorGenerator;
+ } + }
+ +
+ public PathFinder(NodeEvaluator pathNodeMaker, int range) { + public PathFinder(NodeEvaluator pathNodeMaker, int range) {
+ this(pathNodeMaker, range, null); + this(pathNodeMaker, range, null);
+ // DivineMC end
} }
+ // DivineMC end
public void setMaxVisitedNodes(int range) {
this.maxVisitedNodes = range;
@@ -37,27 +45,64 @@ public class PathFinder {
@Nullable @Nullable
public Path findPath(PathNavigationRegion world, Mob mob, Set<BlockPos> positions, float followRange, int distance, float rangeMultiplier) { public Path findPath(PathNavigationRegion world, Mob mob, Set<BlockPos> positions, float followRange, int distance, float rangeMultiplier) {
@@ -761,8 +743,8 @@ index 404080976208c30e9e95e5bee47c2a749e709a45..fb4ea7b86ead263e21eca6cce93d5ee9
- this.nodeEvaluator.prepare(world, mob); - this.nodeEvaluator.prepare(world, mob);
- Node node = this.nodeEvaluator.getStart(); - Node node = this.nodeEvaluator.getStart();
+ if (!space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding) + if (!space.bxteam.divinemc.configuration.DivineConfig.asyncPathfinding)
+ this.openSet.clear(); // DivineMC - petal - it's always cleared in processPath + this.openSet.clear(); // DivineMC - it's always cleared in processPath
+ // DivineMC start - petal - use a generated evaluator if we have one otherwise run sync + // DivineMC start - use a generated evaluator if we have one otherwise run sync
+ NodeEvaluator nodeEvaluator = this.nodeEvaluatorGenerator == null + NodeEvaluator nodeEvaluator = this.nodeEvaluatorGenerator == null
+ ? this.nodeEvaluator + ? this.nodeEvaluator
+ : space.bxteam.divinemc.pathfinding.NodeEvaluatorCache.takeNodeEvaluator(this.nodeEvaluatorGenerator, this.nodeEvaluator); + : space.bxteam.divinemc.pathfinding.NodeEvaluatorCache.takeNodeEvaluator(this.nodeEvaluatorGenerator, this.nodeEvaluator);
@@ -770,24 +752,24 @@ index 404080976208c30e9e95e5bee47c2a749e709a45..fb4ea7b86ead263e21eca6cce93d5ee9
+ Node node = nodeEvaluator.getStart(); + Node node = nodeEvaluator.getStart();
+ // DivineMC end + // DivineMC end
if (node == null) { if (node == null) {
+ space.bxteam.divinemc.pathfinding.NodeEvaluatorCache.removeNodeEvaluator(nodeEvaluator); // DivineMC - petal - handle nodeEvaluatorGenerator + space.bxteam.divinemc.pathfinding.NodeEvaluatorCache.removeNodeEvaluator(nodeEvaluator); // DivineMC - handle nodeEvaluatorGenerator
return null; return null;
} else { } else {
// Paper start - Perf: remove streams and optimize collection // Paper start - Perf: remove streams and optimize collection
List<Map.Entry<Target, BlockPos>> map = Lists.newArrayList(); List<Map.Entry<Target, BlockPos>> map = Lists.newArrayList();
for (final BlockPos pos : positions) { for (final BlockPos pos : positions) {
- map.add(new java.util.AbstractMap.SimpleEntry<>(this.nodeEvaluator.getTarget(pos.getX(), pos.getY(), pos.getZ()), pos)); - map.add(new java.util.AbstractMap.SimpleEntry<>(this.nodeEvaluator.getTarget(pos.getX(), pos.getY(), pos.getZ()), pos));
+ map.add(new java.util.AbstractMap.SimpleEntry<>(nodeEvaluator.getTarget(pos.getX(), pos.getY(), pos.getZ()), pos)); // DivineMC - petal - handle nodeEvaluatorGenerator + map.add(new java.util.AbstractMap.SimpleEntry<>(nodeEvaluator.getTarget(pos.getX(), pos.getY(), pos.getZ()), pos)); // DivineMC - handle nodeEvaluatorGenerator
} }
// Paper end - Perf: remove streams and optimize collection // Paper end - Perf: remove streams and optimize collection
- Path path = this.findPath(world.getProfiler(), node, map, followRange, distance, rangeMultiplier); - Path path = this.findPath(node, map, followRange, distance, rangeMultiplier);
- this.nodeEvaluator.done(); - this.nodeEvaluator.done();
- return path; - return path;
+ // DivineMC start - petal - async path processing + // DivineMC start - async path processing
+ if (this.nodeEvaluatorGenerator == null) { + if (this.nodeEvaluatorGenerator == null) {
+ // run sync :( + // run sync :(
+ space.bxteam.divinemc.pathfinding.NodeEvaluatorCache.removeNodeEvaluator(nodeEvaluator); + space.bxteam.divinemc.pathfinding.NodeEvaluatorCache.removeNodeEvaluator(nodeEvaluator);
+ return this.findPath(node, map, followRange, distance, rangeMultiplier); + return this.findPath(node, map, followRange, distance, rangeMultiplier); // Gale - Purpur - remove vanilla profiler
+ } + }
+ +
+ return new space.bxteam.divinemc.pathfinding.AsyncPath(Lists.newArrayList(), positions, () -> { + return new space.bxteam.divinemc.pathfinding.AsyncPath(Lists.newArrayList(), positions, () -> {
@@ -807,11 +789,8 @@ index 404080976208c30e9e95e5bee47c2a749e709a45..fb4ea7b86ead263e21eca6cce93d5ee9
@Nullable @Nullable
// Paper start - Perf: remove streams and optimize collection // Paper start - Perf: remove streams and optimize collection
- private Path findPath(ProfilerFiller profiler, Node startNode, List<Map.Entry<Target, BlockPos>> positions, float followRange, int distance, float rangeMultiplier) { private Path findPath(Node startNode, List<Map.Entry<Target, BlockPos>> positions, float followRange, int distance, float rangeMultiplier) {
- //profiler.push("find_path"); // Purpur + // DivineMC start - split pathfinding into the original sync method for compat and processing for delaying
- //profiler.markForCharting(MetricCategory.PATH_FINDING); // Purpur
+ private Path findPath(Node startNode, List<Map.Entry<Target, BlockPos>> positions, float followRange, int distance, float rangeMultiplier) {
+ // DivineMC start - petal - split pathfinding into the original sync method for compat and processing for delaying
+ try { + try {
+ return this.processPath(this.nodeEvaluator, startNode, positions, followRange, distance, rangeMultiplier); + return this.processPath(this.nodeEvaluator, startNode, positions, followRange, distance, rangeMultiplier);
+ } catch (Exception e) { + } catch (Exception e) {
@@ -825,28 +804,20 @@ index 404080976208c30e9e95e5bee47c2a749e709a45..fb4ea7b86ead263e21eca6cce93d5ee9
+ private synchronized @org.jetbrains.annotations.NotNull Path processPath(NodeEvaluator nodeEvaluator, Node startNode, List<Map.Entry<Target, BlockPos>> positions, float followRange, int distance, float rangeMultiplier) { // sync to only use the caching functions in this class on a single thread + private synchronized @org.jetbrains.annotations.NotNull Path processPath(NodeEvaluator nodeEvaluator, Node startNode, List<Map.Entry<Target, BlockPos>> positions, float followRange, int distance, float rangeMultiplier) { // sync to only use the caching functions in this class on a single thread
+ org.apache.commons.lang3.Validate.isTrue(!positions.isEmpty()); // ensure that we have at least one position, which means we'll always return a path + org.apache.commons.lang3.Validate.isTrue(!positions.isEmpty()); // ensure that we have at least one position, which means we'll always return a path
+ // DivineMC end + // DivineMC end
// Set<Target> set = positions.keySet(); ProfilerFiller profilerFiller = Profiler.get();
startNode.g = 0.0F; profilerFiller.push("find_path");
startNode.h = this.getBestH(startNode, positions); // Paper - optimize collection profilerFiller.markForCharting(MetricCategory.PATH_FINDING);
@@ -90,7 +127,7 @@ public class PathFinder { @@ -96,7 +141,7 @@ public class PathFinder {
} }
if (!(node.distanceTo(startNode) >= followRange)) { if (!(node.distanceTo(startNode) >= followRange)) {
- int k = this.nodeEvaluator.getNeighbors(this.neighbors, node); - int k = this.nodeEvaluator.getNeighbors(this.neighbors, node);
+ int k = nodeEvaluator.getNeighbors(this.neighbors, node); // DivineMC - petal - use provided nodeEvaluator + int k = nodeEvaluator.getNeighbors(this.neighbors, node); // DivineMC - use provided nodeEvaluator
for (int l = 0; l < k; l++) { for (int l = 0; l < k; l++) {
Node node2 = this.neighbors[l]; Node node2 = this.neighbors[l];
@@ -123,6 +160,7 @@ public class PathFinder {
best = path;
}
//profiler.pop(); // Purpur
+ //noinspection ConstantConditions // DivineMC - petal - ignore this warning, we know that the above loop always runs at least once since positions is not empty
return best;
// Paper end - Perf: remove streams and optimize collection
}
diff --git a/src/main/java/net/minecraft/world/level/pathfinder/SwimNodeEvaluator.java b/src/main/java/net/minecraft/world/level/pathfinder/SwimNodeEvaluator.java diff --git a/src/main/java/net/minecraft/world/level/pathfinder/SwimNodeEvaluator.java b/src/main/java/net/minecraft/world/level/pathfinder/SwimNodeEvaluator.java
index 6308822f819d7cb84c8070c8a7eec1a3f822114b..3db838279e4407c28671bb1563fc96f981a6c59c 100644 index 6308822f819d7cb84c8070c8a7eec1a3f822114b..c54b4c10976851588b74d09220b01aa6d96fab81 100644
--- a/src/main/java/net/minecraft/world/level/pathfinder/SwimNodeEvaluator.java --- a/src/main/java/net/minecraft/world/level/pathfinder/SwimNodeEvaluator.java
+++ b/src/main/java/net/minecraft/world/level/pathfinder/SwimNodeEvaluator.java +++ b/src/main/java/net/minecraft/world/level/pathfinder/SwimNodeEvaluator.java
@@ -15,7 +15,7 @@ import net.minecraft.world.level.block.state.BlockState; @@ -15,7 +15,7 @@ import net.minecraft.world.level.block.state.BlockState;
@@ -854,17 +825,17 @@ index 6308822f819d7cb84c8070c8a7eec1a3f822114b..3db838279e4407c28671bb1563fc96f9
public class SwimNodeEvaluator extends NodeEvaluator { public class SwimNodeEvaluator extends NodeEvaluator {
- private final boolean allowBreaching; - private final boolean allowBreaching;
+ public final boolean allowBreaching; // DivineMC - make this public + public final boolean allowBreaching; // DivineMC - make public
private final Long2ObjectMap<PathType> pathTypesByPosCache = new Long2ObjectOpenHashMap<>(); private final Long2ObjectMap<PathType> pathTypesByPosCache = new Long2ObjectOpenHashMap<>();
public SwimNodeEvaluator(boolean canJumpOutOfWater) { public SwimNodeEvaluator(boolean canJumpOutOfWater) {
diff --git a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java diff --git a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
index 77e07052a923c46ba28d79d531b43dcccf4cd546..acff9dc2f10ecbd3c219e4eaa0c29a259f2192c7 100644 index c494d88cda016ff7a4da37ac1cee2a05876e595f..ed44eaad59afa76d8ca8ac74d0cee4fb681dfe83 100644
--- a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java --- a/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
+++ b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java +++ b/src/main/java/space/bxteam/divinemc/configuration/DivineConfig.java
@@ -166,4 +166,21 @@ public class DivineConfig { @@ -179,4 +179,21 @@ public class DivineConfig {
optimizedDragonRespawn = getBoolean("settings.optimizations.optimized-dragon-respawn", optimizedDragonRespawn); private static void chatMessageSignatures() {
optimizeNoiseGeneration = getBoolean("settings.optimizations.optimize-noise-generation", optimizeNoiseGeneration); noChatSign = getBoolean("settings.no-chat-sign", noChatSign);
} }
+ +
+ public static boolean asyncPathfinding = true; + public static boolean asyncPathfinding = true;
@@ -886,10 +857,10 @@ index 77e07052a923c46ba28d79d531b43dcccf4cd546..acff9dc2f10ecbd3c219e4eaa0c29a25
} }
diff --git a/src/main/java/space/bxteam/divinemc/pathfinding/AsyncPath.java b/src/main/java/space/bxteam/divinemc/pathfinding/AsyncPath.java diff --git a/src/main/java/space/bxteam/divinemc/pathfinding/AsyncPath.java b/src/main/java/space/bxteam/divinemc/pathfinding/AsyncPath.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..233ab97f287e7ab2cca522147778eebb2f6459be index 0000000000000000000000000000000000000000..da62b8ad100c809753c37220b395d979df9b6b2e
--- /dev/null --- /dev/null
+++ b/src/main/java/space/bxteam/divinemc/pathfinding/AsyncPath.java +++ b/src/main/java/space/bxteam/divinemc/pathfinding/AsyncPath.java
@@ -0,0 +1,284 @@ @@ -0,0 +1,291 @@
+package space.bxteam.divinemc.pathfinding; +package space.bxteam.divinemc.pathfinding;
+ +
+import net.minecraft.core.BlockPos; +import net.minecraft.core.BlockPos;
@@ -906,11 +877,10 @@ index 0000000000000000000000000000000000000000..233ab97f287e7ab2cca522147778eebb
+import java.util.function.Supplier; +import java.util.function.Supplier;
+ +
+public class AsyncPath extends Path { +public class AsyncPath extends Path {
+
+ /** + /**
+ * marks whether this async path has been processed + * marks whether this async path has been processed
+ */ + */
+ private volatile boolean processed = false; + private volatile PathProcessState processState = PathProcessState.WAITING;
+ +
+ /** + /**
+ * runnables waiting for this to be processed + * runnables waiting for this to be processed
@@ -967,14 +937,14 @@ index 0000000000000000000000000000000000000000..233ab97f287e7ab2cca522147778eebb
+ +
+ @Override + @Override
+ public boolean isProcessed() { + public boolean isProcessed() {
+ return this.processed; + return this.processState == PathProcessState.COMPLETED;
+ } + }
+ +
+ /** + /**
+ * returns the future representing the processing state of this path + * returns the future representing the processing state of this path
+ */ + */
+ public synchronized void postProcessing(@NotNull Runnable runnable) { + public synchronized void postProcessing(@NotNull Runnable runnable) {
+ if (this.processed) { + if (isProcessed()) {
+ runnable.run(); + runnable.run();
+ } else { + } else {
+ this.postProcessing.add(runnable); + this.postProcessing.add(runnable);
@@ -999,10 +969,13 @@ index 0000000000000000000000000000000000000000..233ab97f287e7ab2cca522147778eebb
+ * starts processing this path + * starts processing this path
+ */ + */
+ public synchronized void process() { + public synchronized void process() {
+ if (this.processed) { + if (this.processState == PathProcessState.COMPLETED ||
+ this.processState == PathProcessState.PROCESSING) {
+ return; + return;
+ } + }
+ +
+ processState = PathProcessState.PROCESSING;
+
+ final Path bestPath = this.pathSupplier.get(); + final Path bestPath = this.pathSupplier.get();
+ +
+ this.nodes.addAll(bestPath.nodes); // we mutate this list to reuse the logic in Path + this.nodes.addAll(bestPath.nodes); // we mutate this list to reuse the logic in Path
@@ -1010,18 +983,19 @@ index 0000000000000000000000000000000000000000..233ab97f287e7ab2cca522147778eebb
+ this.distToTarget = bestPath.getDistToTarget(); + this.distToTarget = bestPath.getDistToTarget();
+ this.canReach = bestPath.canReach(); + this.canReach = bestPath.canReach();
+ +
+ this.processed = true; + processState = PathProcessState.COMPLETED;
+ +
+ for (Runnable runnable : this.postProcessing) { + for (Runnable runnable : this.postProcessing) {
+ runnable.run(); + runnable.run();
+ } + } // Run tasks after processing
+ } + }
+ +
+ /** + /**
+ * if this path is accessed while it hasn't processed, just process it in-place + * if this path is accessed while it hasn't processed, just process it in-place
+ */ + */
+ private void checkProcessed() { + private void checkProcessed() {
+ if (!this.processed) { + if (this.processState == PathProcessState.WAITING ||
+ this.processState == PathProcessState.PROCESSING) { // Block if we are on processing
+ this.process(); + this.process();
+ } + }
+ } + }
@@ -1057,7 +1031,7 @@ index 0000000000000000000000000000000000000000..233ab97f287e7ab2cca522147778eebb
+ +
+ @Override + @Override
+ public boolean isDone() { + public boolean isDone() {
+ return this.isProcessed() && super.isDone(); + return this.processState == PathProcessState.COMPLETED && super.isDone();
+ } + }
+ +
+ @Override + @Override
@@ -1173,21 +1147,22 @@ index 0000000000000000000000000000000000000000..233ab97f287e7ab2cca522147778eebb
+ +
+ return super.hasNext(); + return super.hasNext();
+ } + }
+
+ public PathProcessState getProcessState() {
+ return processState;
+ }
+} +}
diff --git a/src/main/java/space/bxteam/divinemc/pathfinding/AsyncPathProcessor.java b/src/main/java/space/bxteam/divinemc/pathfinding/AsyncPathProcessor.java diff --git a/src/main/java/space/bxteam/divinemc/pathfinding/AsyncPathProcessor.java b/src/main/java/space/bxteam/divinemc/pathfinding/AsyncPathProcessor.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..d51ecee31eb583ecb4a59c56a6325fa028789abf index 0000000000000000000000000000000000000000..b3222add41b5725cc7409b6651ffe48b0a2858d7
--- /dev/null --- /dev/null
+++ b/src/main/java/space/bxteam/divinemc/pathfinding/AsyncPathProcessor.java +++ b/src/main/java/space/bxteam/divinemc/pathfinding/AsyncPathProcessor.java
@@ -0,0 +1,53 @@ @@ -0,0 +1,48 @@
+package space.bxteam.divinemc.pathfinding; +package space.bxteam.divinemc.pathfinding;
+ +
+import com.google.common.util.concurrent.ThreadFactoryBuilder; +import com.google.common.util.concurrent.ThreadFactoryBuilder;
+ +import net.minecraft.server.MinecraftServer;
+import space.bxteam.divinemc.configuration.DivineConfig;
+import net.minecraft.world.level.pathfinder.Path; +import net.minecraft.world.level.pathfinder.Path;
+import net.minecraft.world.entity.Entity;
+
+import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Nullable;
+ +
@@ -1198,14 +1173,13 @@ index 0000000000000000000000000000000000000000..d51ecee31eb583ecb4a59c56a6325fa0
+ * used to handle the scheduling of async path processing + * used to handle the scheduling of async path processing
+ */ + */
+public class AsyncPathProcessor { +public class AsyncPathProcessor {
+
+ private static final Executor pathProcessingExecutor = new ThreadPoolExecutor( + private static final Executor pathProcessingExecutor = new ThreadPoolExecutor(
+ 1, + 1,
+ DivineConfig.asyncPathfindingMaxThreads, + space.bxteam.divinemc.configuration.DivineConfig.asyncPathfindingMaxThreads,
+ DivineConfig.asyncPathfindingKeepalive, TimeUnit.SECONDS, + space.bxteam.divinemc.configuration.DivineConfig.asyncPathfindingKeepalive, TimeUnit.SECONDS,
+ new LinkedBlockingQueue<>(), + new LinkedBlockingQueue<>(),
+ new ThreadFactoryBuilder() + new ThreadFactoryBuilder()
+ .setNameFormat("petal-async-pathfinding-thread-%d") // This used in ShulkerBoxBlock and Mob classes + .setNameFormat("DivineMC Async Pathfinding Thread - %d")
+ .setPriority(Thread.NORM_PRIORITY - 2) + .setPriority(Thread.NORM_PRIORITY - 2)
+ .build() + .build()
+ ); + );
@@ -1219,14 +1193,13 @@ index 0000000000000000000000000000000000000000..d51ecee31eb583ecb4a59c56a6325fa0
+ * the consumer will be immediately invoked if the path is already processed + * the consumer will be immediately invoked if the path is already processed
+ * the consumer will always be called on the main thread + * the consumer will always be called on the main thread
+ * + *
+ * @param entity affected entity
+ * @param path a path to wait on + * @param path a path to wait on
+ * @param afterProcessing a consumer to be called + * @param afterProcessing a consumer to be called
+ */ + */
+ public static void awaitProcessing(Entity entity, @Nullable Path path, Consumer<@Nullable Path> afterProcessing) { + public static void awaitProcessing(@Nullable Path path, Consumer<@Nullable Path> afterProcessing) {
+ if (path != null && !path.isProcessed() && path instanceof AsyncPath asyncPath) { + if (path != null && !path.isProcessed() && path instanceof AsyncPath asyncPath) {
+ asyncPath.postProcessing(() -> + asyncPath.postProcessing(() ->
+ entity.getBukkitEntity().taskScheduler.schedule(nmsEntity -> afterProcessing.accept(path), null, 1) + MinecraftServer.getServer().scheduleOnMain(() -> afterProcessing.accept(path))
+ ); + );
+ } else { + } else {
+ afterProcessing.accept(path); + afterProcessing.accept(path);
@@ -1235,14 +1208,13 @@ index 0000000000000000000000000000000000000000..d51ecee31eb583ecb4a59c56a6325fa0
+} +}
diff --git a/src/main/java/space/bxteam/divinemc/pathfinding/NodeEvaluatorCache.java b/src/main/java/space/bxteam/divinemc/pathfinding/NodeEvaluatorCache.java diff --git a/src/main/java/space/bxteam/divinemc/pathfinding/NodeEvaluatorCache.java b/src/main/java/space/bxteam/divinemc/pathfinding/NodeEvaluatorCache.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..eb05bea8b9a18c348aa4d3edaefb93b69e1c371f index 0000000000000000000000000000000000000000..11d4c50dbe54cdbf539883cf3ef2f35fd6658307
--- /dev/null --- /dev/null
+++ b/src/main/java/space/bxteam/divinemc/pathfinding/NodeEvaluatorCache.java +++ b/src/main/java/space/bxteam/divinemc/pathfinding/NodeEvaluatorCache.java
@@ -0,0 +1,45 @@ @@ -0,0 +1,44 @@
+package space.bxteam.divinemc.pathfinding; +package space.bxteam.divinemc.pathfinding;
+ +
+import net.minecraft.world.level.pathfinder.NodeEvaluator; +import net.minecraft.world.level.pathfinder.NodeEvaluator;
+
+import org.apache.commons.lang.Validate; +import org.apache.commons.lang.Validate;
+import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.NotNull;
+ +
@@ -1315,19 +1287,18 @@ index 0000000000000000000000000000000000000000..e1aeb6b58349042e649219ad521525bb
+} +}
diff --git a/src/main/java/space/bxteam/divinemc/pathfinding/NodeEvaluatorGenerator.java b/src/main/java/space/bxteam/divinemc/pathfinding/NodeEvaluatorGenerator.java diff --git a/src/main/java/space/bxteam/divinemc/pathfinding/NodeEvaluatorGenerator.java b/src/main/java/space/bxteam/divinemc/pathfinding/NodeEvaluatorGenerator.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..02f00c3e5e463a5fde0c46d6c3548827b19a9fea index 0000000000000000000000000000000000000000..75704577983e59f36f05451a635f0964f1345a8c
--- /dev/null --- /dev/null
+++ b/src/main/java/space/bxteam/divinemc/pathfinding/NodeEvaluatorGenerator.java +++ b/src/main/java/space/bxteam/divinemc/pathfinding/NodeEvaluatorGenerator.java
@@ -0,0 +1,10 @@ @@ -0,0 +1,9 @@
+package space.bxteam.divinemc.pathfinding; +package space.bxteam.divinemc.pathfinding;
+ +
+import net.minecraft.world.level.pathfinder.NodeEvaluator; +import net.minecraft.world.level.pathfinder.NodeEvaluator;
+import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.NotNull;
+ +
+public interface NodeEvaluatorGenerator { +public interface NodeEvaluatorGenerator {
+ + @NotNull
+ @NotNull NodeEvaluator generate(NodeEvaluatorFeatures nodeEvaluatorFeatures); + NodeEvaluator generate(NodeEvaluatorFeatures nodeEvaluatorFeatures);
+
+} +}
diff --git a/src/main/java/space/bxteam/divinemc/pathfinding/NodeEvaluatorType.java b/src/main/java/space/bxteam/divinemc/pathfinding/NodeEvaluatorType.java diff --git a/src/main/java/space/bxteam/divinemc/pathfinding/NodeEvaluatorType.java b/src/main/java/space/bxteam/divinemc/pathfinding/NodeEvaluatorType.java
new file mode 100644 new file mode 100644
@@ -1352,3 +1323,16 @@ index 0000000000000000000000000000000000000000..897e4f676a9c7e47a291f24602ad56ad
+ return WALK; + return WALK;
+ } + }
+} +}
diff --git a/src/main/java/space/bxteam/divinemc/pathfinding/PathProcessState.java b/src/main/java/space/bxteam/divinemc/pathfinding/PathProcessState.java
new file mode 100644
index 0000000000000000000000000000000000000000..e73550cf2368ca16f3e01a8a0705064182570eeb
--- /dev/null
+++ b/src/main/java/space/bxteam/divinemc/pathfinding/PathProcessState.java
@@ -0,0 +1,7 @@
+package space.bxteam.divinemc.pathfinding;
+
+public enum PathProcessState {
+ WAITING,
+ PROCESSING,
+ COMPLETED,
+}

View File

@@ -0,0 +1,309 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Mon, 16 Dec 2024 01:14:03 +0300
Subject: [PATCH] lithium: hashed_list
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 2078124d0bcb0d17a15087e4c42aecd73b28061c..aefaf2a4d787822a2cb51cac08637fdc74d49bbc 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -120,9 +120,9 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
public static final int TICKS_PER_DAY = 24000;
public static final int MAX_ENTITY_SPAWN_Y = 20000000;
public static final int MIN_ENTITY_SPAWN_Y = -20000000;
- public final List<TickingBlockEntity> blockEntityTickers = Lists.newArrayList(); // Paper - public
+ public final List<TickingBlockEntity> blockEntityTickers = new space.bxteam.divinemc.util.lithium.HashedReferenceList<>(Lists.newArrayList()); // Paper - public // DivineMC - lithium: hashed_list
protected final NeighborUpdater neighborUpdater;
- private final List<TickingBlockEntity> pendingBlockEntityTickers = Lists.newArrayList();
+ private final List<TickingBlockEntity> pendingBlockEntityTickers = new space.bxteam.divinemc.util.lithium.HashedReferenceList<>(Lists.newArrayList()); // DivineMC - lithium: hashed_list
private boolean tickingBlockEntities;
public final Thread thread;
private final boolean isDebug;
diff --git a/src/main/java/space/bxteam/divinemc/util/lithium/HashedReferenceList.java b/src/main/java/space/bxteam/divinemc/util/lithium/HashedReferenceList.java
new file mode 100644
index 0000000000000000000000000000000000000000..aafa3e581587e3593cec4bb19bd0417ea28d5e67
--- /dev/null
+++ b/src/main/java/space/bxteam/divinemc/util/lithium/HashedReferenceList.java
@@ -0,0 +1,281 @@
+package space.bxteam.divinemc.util.lithium;
+
+import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
+import it.unimi.dsi.fastutil.objects.ReferenceArrayList;
+import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+
+/**
+ * Wraps a {@link List} with a hash table which provides O(1) lookups for {@link Collection#contains(Object)}. The type
+ * contained by this list must use reference-equality semantics.
+ */
+@SuppressWarnings("SuspiciousMethodCalls")
+public class HashedReferenceList<T> implements List<T> {
+ private final ReferenceArrayList<T> list;
+ private final Reference2IntOpenHashMap<T> counter;
+
+ public HashedReferenceList(List<T> list) {
+ this.list = new ReferenceArrayList<>();
+ this.list.addAll(list);
+
+ this.counter = new Reference2IntOpenHashMap<>();
+ this.counter.defaultReturnValue(0);
+
+ for (T obj : this.list) {
+ this.counter.addTo(obj, 1);
+ }
+ }
+
+ @Override
+ public int size() {
+ return this.list.size();
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return this.list.isEmpty();
+ }
+
+ @Override
+ public boolean contains(Object o) {
+ return this.counter.containsKey(o);
+ }
+
+ @Override
+ public Iterator<T> iterator() {
+ return this.listIterator();
+ }
+
+ @Override
+ public Object[] toArray() {
+ return this.list.toArray();
+ }
+
+ @Override
+ public <T1> T1[] toArray(T1 @NotNull [] a) {
+ return this.list.toArray(a);
+ }
+
+ @Override
+ public boolean add(T t) {
+ this.trackReferenceAdded(t);
+
+ return this.list.add(t);
+ }
+
+ @Override
+ public boolean remove(Object o) {
+ this.trackReferenceRemoved(o);
+
+ return this.list.remove(o);
+ }
+
+ @Override
+ public boolean containsAll(Collection<?> c) {
+ for (Object obj : c) {
+ if (!this.counter.containsKey(obj)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean addAll(Collection<? extends T> c) {
+ for (T obj : c) {
+ this.trackReferenceAdded(obj);
+ }
+
+ return this.list.addAll(c);
+ }
+
+ @Override
+ public boolean addAll(int index, Collection<? extends T> c) {
+ for (T obj : c) {
+ this.trackReferenceAdded(obj);
+ }
+
+ return this.list.addAll(index, c);
+ }
+
+ @Override
+ public boolean removeAll(@NotNull Collection<?> c) {
+ if (this.size() >= 2 && c.size() > 4 && c instanceof List) {
+ //HashReferenceList uses reference equality, so using ReferenceOpenHashSet is fine
+ c = new ReferenceOpenHashSet<>(c);
+ }
+ this.counter.keySet().removeAll(c);
+ return this.list.removeAll(c);
+ }
+
+ @Override
+ public boolean retainAll(@NotNull Collection<?> c) {
+ this.counter.keySet().retainAll(c);
+ return this.list.retainAll(c);
+ }
+
+ @Override
+ public void clear() {
+ this.counter.clear();
+ this.list.clear();
+ }
+
+ @Override
+ public T get(int index) {
+ return this.list.get(index);
+ }
+
+ @Override
+ public T set(int index, T element) {
+ T prev = this.list.set(index, element);
+
+ if (prev != element) {
+ if (prev != null) {
+ this.trackReferenceRemoved(prev);
+ }
+
+ this.trackReferenceAdded(element);
+ }
+
+ return prev;
+ }
+
+ @Override
+ public void add(int index, T element) {
+ this.trackReferenceAdded(element);
+
+ this.list.add(index, element);
+ }
+
+ @Override
+ public T remove(int index) {
+ T prev = this.list.remove(index);
+
+ if (prev != null) {
+ this.trackReferenceRemoved(prev);
+ }
+
+ return prev;
+ }
+
+ @Override
+ public int indexOf(Object o) {
+ return this.list.indexOf(o);
+ }
+
+ @Override
+ public int lastIndexOf(Object o) {
+ return this.list.lastIndexOf(o);
+ }
+
+ @Override
+ public ListIterator<T> listIterator() {
+ return this.listIterator(0);
+ }
+
+ @Override
+ public ListIterator<T> listIterator(int index) {
+ return new ListIterator<>() {
+ private final ListIterator<T> inner = HashedReferenceList.this.list.listIterator(index);
+
+ @Override
+ public boolean hasNext() {
+ return this.inner.hasNext();
+ }
+
+ @Override
+ public T next() {
+ return this.inner.next();
+ }
+
+ @Override
+ public boolean hasPrevious() {
+ return this.inner.hasPrevious();
+ }
+
+ @Override
+ public T previous() {
+ return this.inner.previous();
+ }
+
+ @Override
+ public int nextIndex() {
+ return this.inner.nextIndex();
+ }
+
+ @Override
+ public int previousIndex() {
+ return this.inner.previousIndex();
+ }
+
+ @Override
+ public void remove() {
+ int last = this.previousIndex();
+
+ if (last == -1) {
+ throw new NoSuchElementException();
+ }
+
+ T prev = HashedReferenceList.this.get(last);
+
+ if (prev != null) {
+ HashedReferenceList.this.trackReferenceRemoved(prev);
+ }
+
+ this.inner.remove();
+ }
+
+ @Override
+ public void set(T t) {
+ int last = this.previousIndex();
+
+ if (last == -1) {
+ throw new NoSuchElementException();
+ }
+
+ T prev = HashedReferenceList.this.get(last);
+
+ if (prev != t) {
+ if (prev != null) {
+ HashedReferenceList.this.trackReferenceRemoved(prev);
+ }
+
+ HashedReferenceList.this.trackReferenceAdded(t);
+ }
+
+ this.inner.remove();
+ }
+
+ @Override
+ public void add(T t) {
+ HashedReferenceList.this.trackReferenceAdded(t);
+
+ this.inner.add(t);
+ }
+ };
+ }
+
+ @Override
+ public List<T> subList(int fromIndex, int toIndex) {
+ return this.list.subList(fromIndex, toIndex);
+ }
+
+ private void trackReferenceAdded(T t) {
+ this.counter.addTo(t, 1);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void trackReferenceRemoved(Object o) {
+ if (this.counter.addTo((T) o, -1) <= 1) {
+ this.counter.removeInt(o);
+ }
+ }
+
+}

View File

@@ -0,0 +1,25 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Mon, 16 Dec 2024 01:22:14 +0300
Subject: [PATCH] Fix MC-177381
Original bug on Mojira https://bugs.mojang.com/browse/MC-177381
diff --git a/src/main/java/net/minecraft/server/commands/LocateCommand.java b/src/main/java/net/minecraft/server/commands/LocateCommand.java
index 2972f041eea95b92b37c2ab869f9f8ed3d142a27..894bc308d623be6afded9aceca9a85c3ec4ac66d 100644
--- a/src/main/java/net/minecraft/server/commands/LocateCommand.java
+++ b/src/main/java/net/minecraft/server/commands/LocateCommand.java
@@ -196,8 +196,10 @@ public class LocateCommand {
}
private static float dist(int x1, int y1, int x2, int y2) {
- int i = x2 - x1;
- int j = y2 - y1;
- return Mth.sqrt((float)(i * i + j * j));
+ // DivineMC start - Fix MC-177381
+ double i = x2 - x1;
+ double j = y2 - y1;
+ return (float) Math.hypot(i, j);
+ // DivineMC end
}
}

View File

@@ -1,51 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Sun, 12 May 2024 18:12:53 +0300
Subject: [PATCH] Carpet-Fixes: RecipeManager Optimize
Original project: https://github.com/fxmorin/carpet-fixes
Improves: [Blast]Furnace/Campfire/Smoker/Stonecutter/Crafting/Sheep Color Choosing + auto crafting table
diff --git a/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java b/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java
index de7c77c1b25680ecc65f0f43f2391aff269a974f..0d6aad130ba4c90ce1c90c53daa1a15a1391a582 100644
--- a/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java
+++ b/src/main/java/net/minecraft/world/item/crafting/RecipeManager.java
@@ -21,6 +21,7 @@ import java.util.Map.Entry;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import java.util.ArrayList;
import javax.annotation.Nullable;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.NonNullList;
@@ -128,16 +129,24 @@ public class RecipeManager extends SimpleJsonResourceReloadListener {
}
public <I extends RecipeInput, T extends Recipe<I>> List<RecipeHolder<T>> getAllRecipesFor(RecipeType<T> type) {
- return List.copyOf(this.byType(type));
+ return new java.util.ArrayList<>(this.byType(type)); // DivineMC - Carpet-Fixes: RecipeManager Optimize
}
+ // DivineMC start - Carpet-Fixes: RecipeManager Optimize
public <I extends RecipeInput, T extends Recipe<I>> List<RecipeHolder<T>> getRecipesFor(RecipeType<T> type, I input, Level world) {
- return (List) this.byType(type).stream().filter((recipeholder) -> {
- return recipeholder.value().matches(input, world);
- }).sorted(Comparator.comparing((recipeholder) -> {
- return recipeholder.value().getResultItem(world.registryAccess()).getDescriptionId();
- })).collect(Collectors.toList());
+ List<RecipeHolder<T>> list = new java.util.ArrayList<>();
+
+ for (RecipeHolder<T> recipeholder : this.byType(type)) {
+ if (recipeholder.value().matches(input, world)) {
+ list.add(recipeholder);
+ }
+ }
+
+ list.sort(Comparator.comparing((recipeholder) -> recipeholder.value().getResultItem(world.registryAccess()).getDescriptionId()));
+
+ return list;
}
+ // DivineMC end
private <I extends RecipeInput, T extends Recipe<I>> Collection<RecipeHolder<T>> byType(RecipeType<T> type) {
return (Collection) this.byType.get(type); // CraftBukkit - decompile error