From a49215ccc7f116b1adb4a02863c4bbeb06a9177f Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Thu, 8 Jun 2023 13:46:44 -0400 Subject: [PATCH] v2.1.1: enemies now go for targets they can reach over ones they can't --- .../shatteredpixeldungeon/Dungeon.java | 48 +++++-------------- .../actors/mobs/Mob.java | 10 ++-- 2 files changed, 18 insertions(+), 40 deletions(-) diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java index b53a2745c..043b5d8fb 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/Dungeon.java @@ -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 ); } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java index eb8aeebd1..12f399826 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Mob.java @@ -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; } }