v3.3.0: fixed large enemies not swapping targets properly

This commit is contained in:
Evan Debenham
2025-10-19 15:29:13 -04:00
parent 6e1ea49540
commit e1ac0b8d78
3 changed files with 53 additions and 16 deletions

View File

@@ -144,6 +144,11 @@ public class DM200 extends Mob {
if (!enemyInFOV || canAttack(enemy)) { if (!enemyInFOV || canAttack(enemy)) {
return super.act(enemyInFOV, justAlerted); return super.act(enemyInFOV, justAlerted);
} else { } else {
if (handleRecentAttackers()){
return act( true, justAlerted );
}
enemySeen = true; enemySeen = true;
target = enemy.pos; target = enemy.pos;
@@ -172,6 +177,18 @@ public class DM200 extends Mob {
} }
} else { } 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 ); spend( TICK );
return true; return true;
} }

View File

@@ -212,6 +212,11 @@ public class Golem extends Mob {
if (!enemyInFOV || canAttack(enemy)) { if (!enemyInFOV || canAttack(enemy)) {
return super.act(enemyInFOV, justAlerted); return super.act(enemyInFOV, justAlerted);
} else { } else {
if (handleRecentAttackers()){
return act( true, justAlerted );
}
enemySeen = true; enemySeen = true;
target = enemy.pos; target = enemy.pos;
@@ -241,6 +246,18 @@ public class Golem extends Mob {
} }
} else { } 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 ); spend( TICK );
return true; return true;
} }

View File

@@ -1230,22 +1230,8 @@ public abstract class Mob extends Char {
//if we cannot attack our target, but were hit by something else that //if we cannot attack our target, but were hit by something else that
// is visible and attackable or closer, swap targets // is visible and attackable or closer, swap targets
if (!recentlyAttackedBy.isEmpty()){ if (handleRecentAttackers()){
boolean swapped = false; return act( true, justAlerted );
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 (enemyInFOV) { 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 { protected class Fleeing implements AiState {