Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serveral pathfinding fixes #10409

Merged
merged 1 commit into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
"enchantments": [
{
"enchantment": "minecraft:silk_touch",
"levels": 1
"levels": {
"min": 1
}
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
"values": [
"#minecolonies:concrete",
"#minecraft:stone_bricks",
"#minecraft:planks",
"#minecraft:wooden_slabs",
"#minecraft:wool_carpets",
"minecraft:stone_brick_stairs",
"minecraft:stone_brick_slab",
"minecraft:mossy_stone_brick_slab",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ protected ServerConfiguration(final ForgeConfigSpec.Builder builder)

pathfindingDebugVerbosity = defineInteger(builder, "pathfindingdebugverbosity", 0, 0, 10);
minimumRailsToPath = defineInteger(builder, "minimumrailstopath", 8, 5, 100);
pathfindingMaxThreadCount = defineInteger(builder, "pathfindingmaxthreadcount", 2, 1, 10);
pathfindingMaxThreadCount = defineInteger(builder, "pathfindingmaxthreadcount", 1, 1, 10);

swapToCategory(builder, "requestSystem");

Expand Down
3 changes: 2 additions & 1 deletion src/main/java/com/minecolonies/api/util/EntityUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.minecolonies.api.crafting.ItemStorage;
import com.minecolonies.api.entity.citizen.AbstractEntityCitizen;
import com.minecolonies.api.items.ModTags;
import com.minecolonies.core.entity.pathfinding.PathfindingUtils;
import com.minecolonies.core.entity.pathfinding.SurfaceType;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
Expand Down Expand Up @@ -205,7 +206,7 @@ private static boolean checkValidSpawn(@NotNull final BlockGetter world, final B
for (int dy = 0; dy < height; dy++)
{
final BlockState state = world.getBlockState(pos.above(dy));
if (!state.is(ModTags.validSpawn) && BlockUtils.isAnySolid(state))
if (!state.is(ModTags.validSpawn) && (PathfindingUtils.isLiquid(state) || ShapeUtil.hasCollision(world, pos.above(dy), state)))
Raycoms marked this conversation as resolved.
Show resolved Hide resolved
{
return false;
}
Expand Down
38 changes: 38 additions & 0 deletions src/main/java/com/minecolonies/api/util/ShapeUtil.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.minecolonies.api.util;

import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;

Expand Down Expand Up @@ -99,4 +102,39 @@ public static double getEndY(final VoxelShape bb, final double def)
{
return isEmpty(bb) ? def : max(bb, Direction.Axis.Y);
}

/**
* Check if the given block has a collision shape
*
* @param world
* @param pos
* @param state
* @return
*/
public static boolean hasCollision(final BlockGetter world, final BlockPos pos, final BlockState state)
{
if (!state.getBlock().hasCollision)
{
return false;
}

return hasCollision(state, state.getCollisionShape(world, pos));
}

/**
* Check if the given block has a collision shape
*
* @param state
* @param collisionShape
* @return
*/
public static boolean hasCollision(final BlockState state, final VoxelShape collisionShape)
{
if (!state.getBlock().hasCollision)
{
return false;
}

return !ShapeUtil.isEmpty(collisionShape);
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package com.minecolonies.core.entity.mobs.aitasks;

import com.minecolonies.api.entity.ai.combat.threat.IThreatTableEntity;
import com.minecolonies.api.entity.ai.statemachine.states.IState;
import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.ITickRateStateMachine;
import com.minecolonies.api.entity.ai.combat.threat.IThreatTableEntity;
import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob;
import com.minecolonies.api.util.DamageSourceKeys;
import com.minecolonies.core.entity.pathfinding.pathresults.PathResult;
import com.minecolonies.api.util.SoundUtils;
import com.minecolonies.api.util.constant.Constants;
import com.minecolonies.core.MineColonies;
import com.minecolonies.core.entity.ai.combat.AttackMoveAI;
import com.minecolonies.core.entity.citizen.EntityCitizen;
import com.minecolonies.core.entity.pathfinding.pathresults.PathResult;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.chat.contents.TranslatableContents;
import net.minecraft.resources.ResourceKey;
Expand Down Expand Up @@ -79,6 +78,7 @@ protected double getAttackDistance()
@Override
protected int getAttackDelay()
{
// TODO: use own difficulty
return MAX_ATTACK_DELAY - MineColonies.getConfig().getServer().raidDifficulty.get() * 4;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
package com.minecolonies.core.entity.mobs.aitasks;

import com.minecolonies.api.entity.mobs.ICustomAttackSound;
import com.minecolonies.api.entity.ai.combat.threat.IThreatTableEntity;
import com.minecolonies.api.entity.ai.statemachine.states.IState;
import com.minecolonies.api.entity.ai.statemachine.tickratestatemachine.ITickRateStateMachine;
import com.minecolonies.api.entity.ai.combat.threat.IThreatTableEntity;
import com.minecolonies.api.entity.mobs.AbstractEntityRaiderMob;
import com.minecolonies.api.entity.mobs.ICustomAttackSound;
import com.minecolonies.api.entity.mobs.IRangedMobEntity;
import com.minecolonies.core.entity.pathfinding.pathresults.PathResult;
import com.minecolonies.api.util.EntityUtils;
import com.minecolonies.core.MineColonies;
import com.minecolonies.core.entity.other.CustomArrowEntity;
import com.minecolonies.core.entity.ai.combat.AttackMoveAI;
import com.minecolonies.core.entity.ai.combat.CombatUtils;
import com.minecolonies.core.entity.citizen.EntityCitizen;
import com.minecolonies.core.entity.other.CustomArrowEntity;
import com.minecolonies.core.entity.pathfinding.pathresults.PathResult;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.InteractionHand;
Expand Down Expand Up @@ -153,7 +153,7 @@ protected int getAttackDelay()
{
return 10;
}

// TODO: config is included in own difficulty
return (int) (Math.max(MIN_ATTACK_DELAY, MAX_ATTACK_DELAY - MineColonies.getConfig().getServer().raidDifficulty.get() * 4 * user.getDifficulty())
* user.getAttackDelayModifier());
}
Expand Down
24 changes: 20 additions & 4 deletions src/main/java/com/minecolonies/core/entity/pathfinding/MNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public class MNode implements Comparable<MNode>
/**
* Checks if the node has been closed already.
*/
private boolean visited = false;
private int visitedCount = 0;

/**
* Checks if the node is on a ladder.
Expand Down Expand Up @@ -190,7 +190,17 @@ public boolean equals(@Nullable final Object o)
*/
public boolean isVisited()
{
return visited;
return visitedCount != 0;
}

/**
* Get the visited count
*
* @return
*/
public int getVisitedCount()
{
return visitedCount;
}

/**
Expand All @@ -216,9 +226,9 @@ public boolean isSwimming()
/**
* Sets the node as closed.
*/
public void setVisited()
public void increaseVisited()
{
visited = true;
visitedCount++;
}

/**
Expand Down Expand Up @@ -388,4 +398,10 @@ public static int computeNodeKey(final int x, final int y, final int z)
| ((y & 0xFF) << SHIFT_Y_BY)
| (z & 0xFFF);
}

@Override
public String toString()
{
return "Node: [" + x + "," + y + "," + z + "] visited:" + visitedCount + " cost:" + cost + " heuristic:" + heuristic;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class PathingOptions
/**
* Cost improvement of paths - base 1.
*/
public double onPathCost = 1 / 4d;
public double onPathCost = 1 / 6d;

/**
* Cost improvement of paths - base 1.
Expand Down Expand Up @@ -55,7 +55,7 @@ public class PathingOptions
/**
* Cost to traverse trap doors
*/
public double traverseToggleAbleCost = 5D;
public double traverseToggleAbleCost = 3D;

/**
* Cost to climb a non ladder.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,11 +256,6 @@ public PathResult<AbstractPathJob> setPathJob(
return null;
}

if (PathfindingUtils.trackingMap.containsValue(ourEntity.getUUID()))
{
Log.getLogger().info(ourEntity + " started pathjob to:" + dest + " job type:" + job.getClass().getSimpleName());
}

stop();

this.destination = dest;
Expand Down Expand Up @@ -319,6 +314,7 @@ public void tick()
else if (pathResult.getStatus() == PathFindingStatus.CALCULATION_COMPLETE)
{
processCompletedCalculationResult();
wantedPosition = null;
}
}

Expand Down Expand Up @@ -675,10 +671,11 @@ private void processCompletedCalculationResult()
}

// Calculate an overtime-heuristic adjustment for pathfinding to use which fits the terrain
if (pathResult.costPerDist != 1)
if (pathResult.getPathLength() > 2 && pathResult.costPerDist != 1)
{
heuristicAvg -= heuristicAvg / 20;
heuristicAvg += pathResult.costPerDist / 20;
final double factor = 1 + pathResult.getPathLength() / 30.0;
heuristicAvg -= heuristicAvg / (50 / factor);
heuristicAvg += pathResult.costPerDist / (50 / factor);
}

if (pathResult.failedToReachDestination())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,28 @@ public static boolean walkCloseToXNearY(
{
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)))
// Three cases
// 1. Navigation Finished
// 2. Navigation is progressing towards a previous task
// 3. Navigation did not try once
boolean isOnRightTask = (nav.getPathResult() != null
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

final?

&& nav.getPathResult().getJob() instanceof PathJobMoveCloseToXNearY job
&& job.nearbyPosition.equals(nearbyPosition)
&& job.desiredPosition.equals(desiredPosition));

if (nav.isDone() || !isOnRightTask)
{
// Check distance once navigation is done, to let the entity walk
if (BlockPosUtil.dist(entity.blockPosition(), desiredPosition) < distToDesired)
if (isOnRightTask)
{
return false;
// Check distance once navigation is done, to let the entity walk
if (BlockPosUtil.dist(entity.blockPosition(), desiredPosition) < distToDesired)
{
nav.stop();
return false;
}
}

PathJobMoveCloseToXNearY pathJob = new PathJobMoveCloseToXNearY(entity.level, desiredPosition, nearbyPosition, distToDesired, entity);
PathJobMoveCloseToXNearY pathJob = new PathJobMoveCloseToXNearY(entity.level, desiredPosition, nearbyPosition, 1, entity);
Raycoms marked this conversation as resolved.
Show resolved Hide resolved
nav.setPathJob(pathJob, desiredPosition, 1.0, false);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ private void tryUnstuck(final AbstractAdvancedPathNavigate navigator)
}

navigator.stop();
final int range = ColonyConstants.rand.nextInt(20) + Math.min(100, BlockPosUtil.distManhattan(navigator.ourEntity.blockPosition(), prevDestination));
final int range = ColonyConstants.rand.nextInt(20) + Math.min(100, Math.max(20, BlockPosUtil.distManhattan(navigator.ourEntity.blockPosition(), prevDestination)));
navigator.moveTowards(navigator.getOurEntity().blockPosition().relative(movingAwayDir, 40), range, 1.0f);
movingAwayDir = movingAwayDir.getClockWise();
navigator.setPauseTicks(range * TICKS_PER_BLOCK);
Expand Down
Loading