Hover pathfinding bugfixes

This commit is contained in:
Anuken 2024-04-19 15:24:36 -04:00
parent 1d30a9bcdb
commit a407d88e28
2 changed files with 22 additions and 9 deletions

View File

@ -1101,7 +1101,9 @@ public class ControlPathfinder implements Runnable{
//cache raycast results to run every time the world updates, and every tile the unit crosses
if(lastRaycastTile != packedPos){
//near the destination, standard raycasting tends to break down, so use the more permissive 'near' variant that doesn't take into account edges of walls
raycastResult = unit.within(destination, tilesize * 2.5f) ? !raycastRect(unit.x, unit.y, destination.x, destination.y, team, cost, tileX, tileY, actualDestX, actualDestY, tileRectSize) : !raycast(team, cost, tileX, tileY, actualDestX, actualDestY);
raycastResult = unit.within(destination, tilesize * 2.5f) ?
!raycastRect(unit.x, unit.y, destination.x, destination.y, team, cost, tileX, tileY, actualDestX, actualDestY, tileRectSize) :
!raycast(team, cost, tileX, tileY, actualDestX, actualDestY);
if(request != null){
request.lastRaycastTile = packedPos;
@ -1141,7 +1143,7 @@ public class ControlPathfinder implements Runnable{
boolean recalc = false;
//TODO last pos can change if the flowfield changes.
if(initialTileOn.pos() != request.lastTile || request.lastTargetTile == null){
if(initialTileOn.pos() != request.lastTile || request.lastTargetTile == null || true){
boolean anyNearSolid = false;
//find the next tile until one near a solid block is discovered
@ -1176,7 +1178,7 @@ public class ControlPathfinder implements Runnable{
if(!(current == null || (costId == costIdGround && current.dangerous() && !tileOn.dangerous()))){
//when anyNearSolid is false, no solid tiles have been encountered anywhere so far, so raycasting is a waste of time
if(anyNearSolid && !tileOn.dangerous() && raycastRect(unit.x, unit.y, current.x * tilesize, current.y * tilesize, team, cost, initialTileOn.x, initialTileOn.y, current.x, current.y, tileRectSize)){
if(anyNearSolid && !(tileOn.dangerous() && costId == costIdGround) && raycastRect(unit.x, unit.y, current.x * tilesize, current.y * tilesize, team, cost, initialTileOn.x, initialTileOn.y, current.x, current.y, tileRectSize)){
//TODO this may be a mistake
if(tileOn == initialTileOn){
@ -1206,6 +1208,7 @@ public class ControlPathfinder implements Runnable{
}
if(request.lastTargetTile != null){
Fx.breakBlock.at(request.lastTargetTile.worldx(), request.lastTargetTile.worldy(), 1);
out.set(request.lastTargetTile);
request.lastTile = recalc ? -1 : initialTileOn.pos();
return true;

View File

@ -205,6 +205,9 @@ public class CommandAI extends AIController{
boolean alwaysArrive = false;
float engageRange = unit.type.range - 10f;
boolean withinAttackRange = attackTarget != null && unit.within(attackTarget, engageRange) && stance != UnitStance.ram;
if(targetPos != null){
boolean move = true, isFinalPoint = commandQueue.size == 0;
vecOut.set(targetPos);
@ -249,7 +252,16 @@ public class CommandAI extends AIController{
timeSpentBlocked = 0f;
}
move = controlPath.getPathPosition(unit, vecMovePos, targetPos, vecOut, noFound) && (!blockingUnit || timeSpentBlocked > maxBlockTime);
//if the unit is next to the target, stop asking the pathfinder how to get there, it's a waste of CPU
//TODO maybe stop moving too?
if(withinAttackRange){
move = true;
noFound[0] = false;
vecOut.set(vecMovePos);
}else{
move = controlPath.getPathPosition(unit, vecMovePos, targetPos, vecOut, noFound) && (!blockingUnit || timeSpentBlocked > maxBlockTime);
}
//rare case where unit must be perfectly aligned (happens with 1-tile gaps)
alwaysArrive = vecOut.epsilonEquals(unit.tileX() * tilesize, unit.tileY() * tilesize);
//we've reached the final point if the returned coordinate is equal to the supplied input
@ -268,18 +280,16 @@ public class CommandAI extends AIController{
vecOut.set(vecMovePos);
}
float engageRange = unit.type.range - 10f;
if(move){
if(unit.type.circleTarget && attackTarget != null){
target = attackTarget;
circleAttack(80f);
}else{
moveTo(vecOut,
attackTarget != null && unit.within(attackTarget, engageRange) && stance != UnitStance.ram ? engageRange :
withinAttackRange ? engageRange :
unit.isGrounded() ? 0f :
attackTarget != null && stance != UnitStance.ram ? engageRange :
0f, unit.isFlying() ? 40f : 100f, false, null, isFinalPoint || alwaysArrive);
attackTarget != null && stance != UnitStance.ram ? engageRange : 0f,
unit.isFlying() ? 40f : 100f, false, null, isFinalPoint || alwaysArrive);
}
}