Better conditional avoidance system
This commit is contained in:
@@ -163,7 +163,7 @@ public class Pathfinder implements Runnable{
|
||||
for(int dy = -r; dy <= r; dy++){
|
||||
int x = dx + unit.tileX(), y = dy + unit.tileY();
|
||||
if(x >= 0 && y >= 0 && x < wwidth && y < wheight && (dx*dx + dy*dy) <= rad2){
|
||||
arr[x + y * wwidth] = Math.max(arr[x + y * wwidth], unit.id);
|
||||
arr[x + y * wwidth] = Math.max(arr[x + y * wwidth], Integer.MAX_VALUE - unit.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -441,7 +441,7 @@ public class Pathfinder implements Runnable{
|
||||
if(other == null) continue;
|
||||
|
||||
int packed = dx/res + dy/res * ww;
|
||||
int avoidance = avoid == null || unitId == 0 ? 0 : avoid[packed] > unitId ? 1 : 0;
|
||||
int avoidance = avoid == null || unitId == 0 ? 0 : avoid[packed] > Integer.MAX_VALUE - unitId ? 1 : 0;
|
||||
int cost = values[packed] + avoidance;
|
||||
|
||||
if(cost < value && avoidance == 0 && (current == null || cost < tl) && path.passable(packed) &&
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package mindustry.ai.types;
|
||||
|
||||
import arc.math.*;
|
||||
import arc.util.*;
|
||||
import mindustry.*;
|
||||
import mindustry.ai.*;
|
||||
import mindustry.entities.*;
|
||||
import mindustry.entities.units.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.world.*;
|
||||
@@ -9,11 +12,16 @@ import mindustry.world.*;
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
public class GroundAI extends AIController{
|
||||
float stuckTime = 0f;
|
||||
float stuckX = -999f, stuckY = -999f;
|
||||
|
||||
static final float stuckThreshold = 1.5f * 60f;
|
||||
|
||||
@Override
|
||||
public void updateMovement(){
|
||||
|
||||
Building core = unit.closestEnemyCore();
|
||||
boolean moved = false;
|
||||
|
||||
if(core != null && unit.within(core, unit.range() / 1.3f + core.block.size * tilesize / 2f)){
|
||||
target = core;
|
||||
@@ -38,7 +46,9 @@ public class GroundAI extends AIController{
|
||||
move = false;
|
||||
}
|
||||
|
||||
if(move) pathfind(Pathfinder.fieldCore);
|
||||
moved = move;
|
||||
|
||||
if(move) pathfind(Pathfinder.fieldCore, true, stuckTime >= stuckThreshold);
|
||||
}
|
||||
|
||||
if(unit.type.canBoost && unit.elevation > 0.001f && !unit.onSolid()){
|
||||
@@ -46,5 +56,28 @@ public class GroundAI extends AIController{
|
||||
}
|
||||
|
||||
faceTarget();
|
||||
|
||||
if(moved){
|
||||
|
||||
if(unit.within(stuckX, stuckY, tilesize * 1.5f)){
|
||||
stuckTime += Time.delta;
|
||||
if(stuckTime - Time.delta < stuckThreshold && stuckTime >= stuckThreshold){
|
||||
float radius = unit.hitSize * Vars.unitCollisionRadiusScale * 2f;
|
||||
Units.nearby(unit.team, unit.x, unit.y, radius, other -> {
|
||||
if(other != unit && other.controller() instanceof GroundAI ai && other.within(unit.x, unit.y, radius + other.hitSize * unitCollisionRadiusScale)){
|
||||
ai.stuckX = other.x;
|
||||
ai.stuckY = other.y;
|
||||
ai.stuckTime = stuckThreshold + 1f;
|
||||
}
|
||||
});
|
||||
}
|
||||
}else{
|
||||
stuckX = unit.x;
|
||||
stuckY = unit.y;
|
||||
stuckTime = 0f;
|
||||
}
|
||||
}else{
|
||||
stuckTime = 0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,11 +132,15 @@ public class AIController implements UnitController{
|
||||
}
|
||||
|
||||
public void pathfind(int pathTarget, boolean stopAtTargetTile){
|
||||
pathfind(pathTarget, stopAtTargetTile, false);
|
||||
}
|
||||
|
||||
public void pathfind(int pathTarget, boolean stopAtTargetTile, boolean avoidance){
|
||||
int costType = unit.type.flowfieldPathType;
|
||||
|
||||
Tile tile = unit.tileOn();
|
||||
if(tile == null) return;
|
||||
Tile targetTile = pathfinder.getField(unit.team, costType, pathTarget).getNextTile(tile, unit.collisionLayer(), unit.id);
|
||||
Tile targetTile = pathfinder.getField(unit.team, costType, pathTarget).getNextTile(tile, avoidance ? unit.collisionLayer() : -1, unit.id);
|
||||
|
||||
if((tile == targetTile && stopAtTargetTile) || !unit.canPass(targetTile.x, targetTile.y)) return;
|
||||
|
||||
|
||||
@@ -519,7 +519,7 @@ public class LExecutor{
|
||||
if(obj instanceof Building b && (exec.privileged || (b.team == exec.team && exec.linkIds.contains(b.id)))){
|
||||
|
||||
if(type == LAccess.enabled){
|
||||
if(p1.bool()) {
|
||||
if(p1.bool()){
|
||||
b.noSleep();
|
||||
}else{
|
||||
b.lastDisabler = exec.build;
|
||||
|
||||
Reference in New Issue
Block a user