From 4f972e8582b051902c4212a636dea7570f147b02 Mon Sep 17 00:00:00 2001 From: someaddons <38401808+someaddons@users.noreply.github.com> Date: Sun, 25 Aug 2024 14:15:10 +0200 Subject: [PATCH] Fix npe with bad crafting recipes after e.g. mod removal (#10163) Fix npe with bad crafting recipes after e.g. mod removal Fix pathing to consider pathblocks again(no those are not diving) Adjust cost calculation to add randomness first, so those cannot overshadow cost reductions Improve builder work position to not go too close to the placed block, avoiding to place a block inside itself Improve Study and - Research pathing to bookcases, they now have a bigger valid range, still try to move close though --- .../minecolonies/api/util/EntityUtils.java | 5 +-- .../AbstractCraftingBuildingModule.java | 3 +- .../builder/EntityAIStructureBuilder.java | 3 +- .../ai/workers/education/EntityAIStudy.java | 7 +-- .../education/EntityAIWorkResearcher.java | 3 +- .../AbstractAdvancedPathNavigate.java | 9 +++- .../MinecoloniesAdvancedPathNavigate.java | 6 +++ .../navigation/PathfindingAIHelper.java | 44 +++++++++++++++++++ .../pathfinding/pathjobs/AbstractPathJob.java | 14 +++--- .../pathjobs/PathJobMoveAwayFromLocation.java | 12 ++++- .../pathjobs/PathJobMoveCloseToXNearY.java | 7 ++- 11 files changed, 89 insertions(+), 24 deletions(-) create mode 100644 src/main/java/com/minecolonies/core/entity/pathfinding/navigation/PathfindingAIHelper.java diff --git a/src/main/java/com/minecolonies/api/util/EntityUtils.java b/src/main/java/com/minecolonies/api/util/EntityUtils.java index 70b02a2fa60..3c4bc2f7a4d 100755 --- a/src/main/java/com/minecolonies/api/util/EntityUtils.java +++ b/src/main/java/com/minecolonies/api/util/EntityUtils.java @@ -3,10 +3,9 @@ import com.ldtteam.structurize.util.BlockUtils; import com.minecolonies.api.crafting.ItemStorage; import com.minecolonies.api.entity.citizen.AbstractEntityCitizen; -import com.minecolonies.core.entity.pathfinding.SurfaceType; import com.minecolonies.api.items.ModTags; +import com.minecolonies.core.entity.pathfinding.SurfaceType; import net.minecraft.core.BlockPos; -import net.minecraft.core.Vec3i; import net.minecraft.tags.BlockTags; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; @@ -325,7 +324,7 @@ public static boolean isEntityAtPosition(final Entity entity, final Level world, public static boolean isLivingAtSite(@NotNull final LivingEntity entityLiving, final int x, final int y, final int z, final int range) { final BlockPos pos = BlockPos.containing(entityLiving.getX(), entityLiving.getY(), entityLiving.getZ()); - return pos.distSqr(new Vec3i(x, y, z)) < MathUtils.square(range); + return BlockPosUtil.distSqr(pos, x, y, z) < MathUtils.square(range); } /** diff --git a/src/main/java/com/minecolonies/core/colony/buildings/modules/AbstractCraftingBuildingModule.java b/src/main/java/com/minecolonies/core/colony/buildings/modules/AbstractCraftingBuildingModule.java index fac38964d18..802c83a9053 100644 --- a/src/main/java/com/minecolonies/core/colony/buildings/modules/AbstractCraftingBuildingModule.java +++ b/src/main/java/com/minecolonies/core/colony/buildings/modules/AbstractCraftingBuildingModule.java @@ -653,7 +653,8 @@ public IRecipeStorage getFirstRecipe(final Predicate stackPredicate) continue; } final IRecipeStorage storage = IColonyManager.getInstance().getRecipeManager().getRecipes().get(token); - if (storage != null && (stackPredicate.test(storage.getPrimaryOutput()) || storage.getAlternateOutputs().stream().anyMatch(stackPredicate::test))) + if (storage != null && (stackPredicate.test(storage.getPrimaryOutput()) || storage.getAlternateOutputs().stream().anyMatch(stackPredicate::test)) + && storage.getClassicForMultiOutput(stackPredicate) != null) { if(foundRecipe == null) { diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/builder/EntityAIStructureBuilder.java b/src/main/java/com/minecolonies/core/entity/ai/workers/builder/EntityAIStructureBuilder.java index be00a9e242c..360fa56d6ce 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/builder/EntityAIStructureBuilder.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/builder/EntityAIStructureBuilder.java @@ -212,10 +212,11 @@ public boolean walkToConstructionSite(final BlockPos currentBlock) final PathJobMoveCloseToXNearY pathJob = new PathJobMoveCloseToXNearY(world, currentBlock, job.getWorkOrder().getLocation(), - 5, + 4, worker); gotoPath = ((MinecoloniesAdvancedPathNavigate) worker.getNavigation()).setPathJob(pathJob, currentBlock, 1.0, false); pathJob.getPathingOptions().dropCost = 200; + pathJob.extraNodes = 0; } else if (gotoPath.isDone()) { diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIStudy.java b/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIStudy.java index dc75056f0f7..3b389599029 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIStudy.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIStudy.java @@ -10,10 +10,11 @@ import com.minecolonies.core.colony.buildings.workerbuildings.BuildingLibrary; import com.minecolonies.core.colony.jobs.JobStudent; import com.minecolonies.core.entity.ai.workers.AbstractEntityAISkill; +import com.minecolonies.core.entity.pathfinding.navigation.PathfindingAIHelper; +import net.minecraft.core.BlockPos; import net.minecraft.sounds.SoundEvents; -import net.minecraft.world.item.ItemStack; import net.minecraft.world.InteractionHand; -import net.minecraft.core.BlockPos; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; import org.jetbrains.annotations.NotNull; @@ -108,7 +109,7 @@ private IAIState study() studyPos = building.getRandomBookShelf(); } - if (walkToBlock(studyPos)) + if (PathfindingAIHelper.walkCloseToXNearY(worker, studyPos, building.getPosition(), 7)) { setDelay(WALK_DELAY); return getState(); diff --git a/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIWorkResearcher.java b/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIWorkResearcher.java index f3decd0ca28..976acb9d692 100755 --- a/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIWorkResearcher.java +++ b/src/main/java/com/minecolonies/core/entity/ai/workers/education/EntityAIWorkResearcher.java @@ -7,6 +7,7 @@ import com.minecolonies.core.colony.buildings.workerbuildings.BuildingUniversity; import com.minecolonies.core.colony.jobs.JobResearch; import com.minecolonies.core.entity.ai.workers.AbstractEntityAIInteract; +import com.minecolonies.core.entity.pathfinding.navigation.PathfindingAIHelper; import net.minecraft.core.BlockPos; import net.minecraft.sounds.SoundEvents; import org.jetbrains.annotations.NotNull; @@ -67,7 +68,7 @@ private IAIState study() studyPos = building.getRandomBookShelf(); } - if (walkToBlock(studyPos)) + if (PathfindingAIHelper.walkCloseToXNearY(worker, studyPos, building.getPosition(), 7)) { return getState(); } diff --git a/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/AbstractAdvancedPathNavigate.java b/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/AbstractAdvancedPathNavigate.java index b10f83e2bb1..69d0cc2eed1 100644 --- a/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/AbstractAdvancedPathNavigate.java +++ b/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/AbstractAdvancedPathNavigate.java @@ -4,12 +4,10 @@ import com.minecolonies.api.crafting.ItemStorage; import com.minecolonies.api.entity.pathfinding.IPathJob; import com.minecolonies.api.entity.pathfinding.IStuckHandler; -import com.minecolonies.api.util.Tuple; import com.minecolonies.core.entity.pathfinding.PathingOptions; import com.minecolonies.core.entity.pathfinding.pathjobs.AbstractPathJob; import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; import com.minecolonies.core.entity.pathfinding.pathresults.TreePathResult; -import com.minecolonies.core.entity.pathfinding.pathresults.WaterPathResult; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Mob; @@ -216,4 +214,11 @@ public Mob getOurEntity() * @param pauseTicks */ protected abstract void setPauseTicks(int pauseTicks); + + /** + * Gets the current path result + * + * @return + */ + public abstract PathResult getPathResult(); } diff --git a/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/MinecoloniesAdvancedPathNavigate.java b/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/MinecoloniesAdvancedPathNavigate.java index 3e905ecfee2..deb8a6cff9c 100644 --- a/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/MinecoloniesAdvancedPathNavigate.java +++ b/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/MinecoloniesAdvancedPathNavigate.java @@ -1177,4 +1177,10 @@ public void setPauseTicks(final int pauseTicks) this.pauseTicks = pauseTicks; } } + + @Override + public PathResult getPathResult() + { + return pathResult; + } } diff --git a/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/PathfindingAIHelper.java b/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/PathfindingAIHelper.java new file mode 100644 index 00000000000..d58381a65b4 --- /dev/null +++ b/src/main/java/com/minecolonies/core/entity/pathfinding/navigation/PathfindingAIHelper.java @@ -0,0 +1,44 @@ +package com.minecolonies.core.entity.pathfinding.navigation; + +import com.minecolonies.api.entity.other.AbstractFastMinecoloniesEntity; +import com.minecolonies.api.util.BlockPosUtil; +import com.minecolonies.core.entity.pathfinding.pathjobs.PathJobMoveCloseToXNearY; +import net.minecraft.core.BlockPos; + +public class PathfindingAIHelper +{ + /** + * Tries to walk close to a given pos, staying near another position. + * + * @param entity + * @param desiredPosition + * @param nearbyPosition + * @param distToDesired + * @return True while walking, false when reached + */ + public static boolean walkCloseToXNearY( + final AbstractFastMinecoloniesEntity entity, final BlockPos desiredPosition, + final BlockPos nearbyPosition, + final int distToDesired) + { + final MinecoloniesAdvancedPathNavigate nav = ((MinecoloniesAdvancedPathNavigate) entity.getNavigation()); + + if (nav.isDone() || (nav.getPathResult() != null + && !(nav.getPathResult().getJob() instanceof PathJobMoveCloseToXNearY job + && job.nearbyPosition.equals(nearbyPosition) + && job.desiredPosition.equals(desiredPosition) + && job.distToDesired == distToDesired))) + { + // Check distance once navigation is done, to let the entity walk + if (BlockPosUtil.dist(entity.blockPosition(), desiredPosition) < distToDesired) + { + return false; + } + + PathJobMoveCloseToXNearY pathJob = new PathJobMoveCloseToXNearY(entity.level, desiredPosition, nearbyPosition, distToDesired, entity); + nav.setPathJob(pathJob, desiredPosition, 1.0, false); + } + + return true; + } +} diff --git a/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/AbstractPathJob.java b/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/AbstractPathJob.java index c7b682a1f0b..c0150cced10 100644 --- a/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/AbstractPathJob.java +++ b/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/AbstractPathJob.java @@ -113,7 +113,7 @@ public abstract class AbstractPathJob implements Callable, IPathJob * Additional nodes that get explored when reaching the target, useful when the destination is an area or not in a great spot. * Pathjobs may increase this value as they see fit */ - protected int extraNodes = 0; + public int extraNodes = 0; /** * Debug settings @@ -763,7 +763,7 @@ else if (!node.isCornerNode() && newY - node.y < 0 && (dX != 0 || dZ != 0) && costFrom = node.parent; } - nextCost = computeCost(costFrom, dX, dY, dZ, isSwimming, isDiving, onRoad, onRails, railsExit, swimStart, ladder, state, belowState, nextX, nextY, nextZ); + nextCost = computeCost(costFrom, dX, dY, dZ, isSwimming, onRoad, isDiving, onRails, railsExit, swimStart, ladder, state, belowState, nextX, nextY, nextZ); nextCost = modifyCost(nextCost, costFrom, swimStart, isSwimming, nextX, nextY, nextZ, state, belowState); if (nextCost > maxCost) @@ -897,6 +897,11 @@ protected double computeCost( { double cost = 1; + if (pathingOptions.randomnessFactor > 0.0d) + { + cost += ColonyConstants.rand.nextDouble() * pathingOptions.randomnessFactor; + } + if (!isSwimming) { if (onPath) @@ -909,11 +914,6 @@ protected double computeCost( } } - if (pathingOptions.randomnessFactor > 0.0d) - { - cost += ColonyConstants.rand.nextDouble() * pathingOptions.randomnessFactor; - } - if (state.getBlock() == Blocks.CAVE_AIR) { cost += pathingOptions.caveAirCost; diff --git a/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/PathJobMoveAwayFromLocation.java b/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/PathJobMoveAwayFromLocation.java index b12fd50eacf..c63f0cfcfc8 100644 --- a/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/PathJobMoveAwayFromLocation.java +++ b/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/PathJobMoveAwayFromLocation.java @@ -2,12 +2,13 @@ import com.minecolonies.api.colony.IColony; import com.minecolonies.api.entity.citizen.AbstractEntityCitizen; -import com.minecolonies.core.entity.pathfinding.SurfaceType; -import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; import com.minecolonies.api.util.BlockPosUtil; import com.minecolonies.api.util.Log; import com.minecolonies.core.MineColonies; import com.minecolonies.core.entity.pathfinding.MNode; +import com.minecolonies.core.entity.pathfinding.PathingOptions; +import com.minecolonies.core.entity.pathfinding.SurfaceType; +import com.minecolonies.core.entity.pathfinding.pathresults.PathResult; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.Mob; import net.minecraft.world.level.Level; @@ -145,4 +146,11 @@ protected double getEndNodeScore(@NotNull final MNode n) { return -BlockPosUtil.dist(avoid, n.x, n.y, n.z); } + + @Override + public void setPathingOptions(final PathingOptions pathingOptions) + { + super.setPathingOptions(pathingOptions); + pathingOptions.dropCost = 5; + } } diff --git a/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/PathJobMoveCloseToXNearY.java b/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/PathJobMoveCloseToXNearY.java index 690b382acc2..4ce22b2ada0 100644 --- a/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/PathJobMoveCloseToXNearY.java +++ b/src/main/java/com/minecolonies/core/entity/pathfinding/pathjobs/PathJobMoveCloseToXNearY.java @@ -1,7 +1,6 @@ package com.minecolonies.core.entity.pathfinding.pathjobs; import com.minecolonies.api.util.BlockPosUtil; -import com.minecolonies.api.util.ShapeUtil; import com.minecolonies.core.entity.pathfinding.MNode; import com.minecolonies.core.entity.pathfinding.PathfindingUtils; import com.minecolonies.core.entity.pathfinding.SurfaceType; @@ -20,17 +19,17 @@ public class PathJobMoveCloseToXNearY extends AbstractPathJob /** * Position to go close to */ - protected final BlockPos desiredPosition; + public final BlockPos desiredPosition; /** * Position to stay nearby */ - protected final BlockPos nearbyPosition; + public final BlockPos nearbyPosition; /** * Required distance to reach */ - protected final int distToDesired; + public final int distToDesired; public PathJobMoveCloseToXNearY( final Level world,