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++){
|
for(int dy = -r; dy <= r; dy++){
|
||||||
int x = dx + unit.tileX(), y = dy + unit.tileY();
|
int x = dx + unit.tileX(), y = dy + unit.tileY();
|
||||||
if(x >= 0 && y >= 0 && x < wwidth && y < wheight && (dx*dx + dy*dy) <= rad2){
|
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;
|
if(other == null) continue;
|
||||||
|
|
||||||
int packed = dx/res + dy/res * ww;
|
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;
|
int cost = values[packed] + avoidance;
|
||||||
|
|
||||||
if(cost < value && avoidance == 0 && (current == null || cost < tl) && path.passable(packed) &&
|
if(cost < value && avoidance == 0 && (current == null || cost < tl) && path.passable(packed) &&
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
package mindustry.ai.types;
|
package mindustry.ai.types;
|
||||||
|
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
|
import arc.util.*;
|
||||||
|
import mindustry.*;
|
||||||
import mindustry.ai.*;
|
import mindustry.ai.*;
|
||||||
|
import mindustry.entities.*;
|
||||||
import mindustry.entities.units.*;
|
import mindustry.entities.units.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
@@ -9,11 +12,16 @@ import mindustry.world.*;
|
|||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class GroundAI extends AIController{
|
public class GroundAI extends AIController{
|
||||||
|
float stuckTime = 0f;
|
||||||
|
float stuckX = -999f, stuckY = -999f;
|
||||||
|
|
||||||
|
static final float stuckThreshold = 1.5f * 60f;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateMovement(){
|
public void updateMovement(){
|
||||||
|
|
||||||
Building core = unit.closestEnemyCore();
|
Building core = unit.closestEnemyCore();
|
||||||
|
boolean moved = false;
|
||||||
|
|
||||||
if(core != null && unit.within(core, unit.range() / 1.3f + core.block.size * tilesize / 2f)){
|
if(core != null && unit.within(core, unit.range() / 1.3f + core.block.size * tilesize / 2f)){
|
||||||
target = core;
|
target = core;
|
||||||
@@ -38,7 +46,9 @@ public class GroundAI extends AIController{
|
|||||||
move = false;
|
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()){
|
if(unit.type.canBoost && unit.elevation > 0.001f && !unit.onSolid()){
|
||||||
@@ -46,5 +56,28 @@ public class GroundAI extends AIController{
|
|||||||
}
|
}
|
||||||
|
|
||||||
faceTarget();
|
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){
|
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;
|
int costType = unit.type.flowfieldPathType;
|
||||||
|
|
||||||
Tile tile = unit.tileOn();
|
Tile tile = unit.tileOn();
|
||||||
if(tile == null) return;
|
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;
|
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(obj instanceof Building b && (exec.privileged || (b.team == exec.team && exec.linkIds.contains(b.id)))){
|
||||||
|
|
||||||
if(type == LAccess.enabled){
|
if(type == LAccess.enabled){
|
||||||
if(p1.bool()) {
|
if(p1.bool()){
|
||||||
b.noSleep();
|
b.noSleep();
|
||||||
}else{
|
}else{
|
||||||
b.lastDisabler = exec.build;
|
b.lastDisabler = exec.build;
|
||||||
|
|||||||
Reference in New Issue
Block a user