v2.1.1: enemies now go for targets they can reach over ones they can't

This commit is contained in:
Evan Debenham
2023-06-08 13:46:44 -04:00
parent ca0d8bbda7
commit a49215ccc7
2 changed files with 18 additions and 40 deletions

View File

@@ -957,8 +957,7 @@ public class Dungeon {
BArray.setFalse(passable);
}
public static PathFinder.Path findPath(Char ch, int to, boolean[] pass, boolean[] vis, boolean chars) {
public static boolean[] findPassable(Char ch, boolean[] pass, boolean[] vis, boolean chars){
setupPassable();
if (ch.flying || ch.buff( Amok.class ) != null) {
BArray.or( pass, Dungeon.level.avoid, passable );
@@ -978,7 +977,12 @@ public class Dungeon {
}
}
return PathFinder.find( ch.pos, to, passable );
return passable;
}
public static PathFinder.Path findPath(Char ch, int to, boolean[] pass, boolean[] vis, boolean chars) {
return PathFinder.find( ch.pos, to, findPassable(ch, pass, vis, chars) );
}
@@ -988,47 +992,17 @@ public class Dungeon {
return Actor.findChar( to ) == null && (pass[to] || Dungeon.level.avoid[to]) ? to : -1;
}
setupPassable();
if (ch.flying || ch.buff( Amok.class ) != null) {
BArray.or( pass, Dungeon.level.avoid, passable );
} else {
System.arraycopy( pass, 0, passable, 0, Dungeon.level.length() );
}
if (Char.hasProp(ch, Char.Property.LARGE)){
BArray.and( passable, Dungeon.level.openSpace, passable );
}
if (chars){
for (Char c : Actor.chars()) {
if (visible[c.pos]) {
passable[c.pos] = false;
}
}
}
return PathFinder.getStep( ch.pos, to, passable );
return PathFinder.getStep( ch.pos, to, findPassable(ch, pass, visible, chars) );
}
public static int flee( Char ch, int from, boolean[] pass, boolean[] visible, boolean chars ) {
setupPassable();
if (ch.flying) {
BArray.or( pass, Dungeon.level.avoid, passable );
} else {
System.arraycopy( pass, 0, passable, 0, Dungeon.level.length() );
}
if (Char.hasProp(ch, Char.Property.LARGE)){
BArray.and( passable, Dungeon.level.openSpace, passable );
}
//only consider chars impassable if our retreat path runs into them
boolean[] passable = findPassable(ch, pass, visible, false);
passable[ch.pos] = true;
//only consider chars impassable if our retreat path runs into them
int step = PathFinder.getStepBack( ch.pos, from, passable );
while (step != -1 && Actor.findChar(step) != null){
while (step != -1 && Actor.findChar(step) != null && chars){
passable[step] = false;
step = PathFinder.getStepBack( ch.pos, from, passable );
}

View File

@@ -375,16 +375,20 @@ public abstract class Mob extends Char {
if (enemies.isEmpty()){
return null;
} else {
//go after the closest potential enemy, preferring enemies that can be attacked, and the hero if two are equidistant
//go after the closest potential enemy, preferring enemies that can be reached/attacked, and the hero if two are equidistant
PathFinder.buildDistanceMap(pos, Dungeon.findPassable(this, Dungeon.level.passable, fieldOfView, true));
Char closest = null;
for (Char curr : enemies){
if (closest == null){
closest = curr;
} else if (canAttack(closest) && !canAttack(curr)){
continue;
} else if ((canAttack(curr) && !canAttack(closest))
|| (Dungeon.level.distance(pos, curr.pos) < Dungeon.level.distance(pos, closest.pos))
|| (Dungeon.level.distance(pos, curr.pos) == Dungeon.level.distance(pos, closest.pos) && curr == Dungeon.hero)){
|| (PathFinder.distance[curr.pos] < PathFinder.distance[closest.pos])){
closest = curr;
} else if ( curr == Dungeon.hero &&
(PathFinder.distance[curr.pos] == PathFinder.distance[closest.pos]) || (canAttack(curr) && canAttack(closest))){
closest = curr;
}
}