From e1ac0b8d78b30b8ecad37476dc5fd27f0497501c Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Sun, 19 Oct 2025 15:29:13 -0400 Subject: [PATCH] v3.3.0: fixed large enemies not swapping targets properly --- .../actors/mobs/DM200.java | 17 +++++++++ .../actors/mobs/Golem.java | 17 +++++++++ .../actors/mobs/Mob.java | 35 ++++++++++--------- 3 files changed, 53 insertions(+), 16 deletions(-) diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/DM200.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/DM200.java index 2705ff1ad..e99a80fd5 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/DM200.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/DM200.java @@ -144,6 +144,11 @@ public class DM200 extends Mob { if (!enemyInFOV || canAttack(enemy)) { return super.act(enemyInFOV, justAlerted); } else { + + if (handleRecentAttackers()){ + return act( true, justAlerted ); + } + enemySeen = true; target = enemy.pos; @@ -172,6 +177,18 @@ public class DM200 extends Mob { } } else { + //attempt to swap targets if the current one can't be reached or vented at + if (!recursing) { + Char oldEnemy = enemy; + enemy = null; + enemy = chooseEnemy(); + if (enemy != null && enemy != oldEnemy) { + recursing = true; + boolean result = act(enemyInFOV, justAlerted); + recursing = false; + return result; + } + } spend( TICK ); return true; } diff --git a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Golem.java b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Golem.java index e7223c8d7..b6ac78436 100644 --- a/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Golem.java +++ b/core/src/main/java/com/shatteredpixel/shatteredpixeldungeon/actors/mobs/Golem.java @@ -212,6 +212,11 @@ public class Golem extends Mob { if (!enemyInFOV || canAttack(enemy)) { return super.act(enemyInFOV, justAlerted); } else { + + if (handleRecentAttackers()){ + return act( true, justAlerted ); + } + enemySeen = true; target = enemy.pos; @@ -241,6 +246,18 @@ public class Golem extends Mob { } } else { + //attempt to swap targets if the current one can't be reached or teleported + if (!recursing) { + Char oldEnemy = enemy; + enemy = null; + enemy = chooseEnemy(); + if (enemy != null && enemy != oldEnemy) { + recursing = true; + boolean result = act(enemyInFOV, justAlerted); + recursing = false; + return result; + } + } spend( TICK ); return true; } 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 208e1e2f9..4e71da10d 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 @@ -1230,22 +1230,8 @@ public abstract class Mob extends Char { //if we cannot attack our target, but were hit by something else that // is visible and attackable or closer, swap targets - if (!recentlyAttackedBy.isEmpty()){ - boolean swapped = false; - for (Char ch : recentlyAttackedBy){ - if (ch != null && ch.isActive() && Actor.chars().contains(ch) && alignment != ch.alignment && fieldOfView[ch.pos] && ch.invisible == 0 && !isCharmedBy(ch)) { - if (canAttack(ch) || enemy == null || Dungeon.level.distance(pos, ch.pos) < Dungeon.level.distance(pos, enemy.pos)) { - enemy = ch; - target = ch.pos; - enemyInFOV = true; - swapped = true; - } - } - } - recentlyAttackedBy.clear(); - if (swapped){ - return act( enemyInFOV, justAlerted ); - } + if (handleRecentAttackers()){ + return act( true, justAlerted ); } if (enemyInFOV) { @@ -1290,6 +1276,23 @@ public abstract class Mob extends Char { } } } + + protected boolean handleRecentAttackers(){ + boolean swapped = false; + if (!recentlyAttackedBy.isEmpty()){ + for (Char ch : recentlyAttackedBy){ + if (ch != null && ch.isActive() && Actor.chars().contains(ch) && alignment != ch.alignment && fieldOfView[ch.pos] && ch.invisible == 0 && !isCharmedBy(ch)) { + if (canAttack(ch) || enemy == null || Dungeon.level.distance(pos, ch.pos) < Dungeon.level.distance(pos, enemy.pos)) { + enemy = ch; + target = ch.pos; + swapped = true; + } + } + } + recentlyAttackedBy.clear(); + } + return swapped; + } } protected class Fleeing implements AiState {