Close door after walking through again, and add more test coverage

This commit is contained in:
Peter Stockings
2026-01-05 22:14:10 +11:00
parent b35cf5a964
commit b3954a6408
10 changed files with 445 additions and 33 deletions

View File

@@ -305,36 +305,41 @@ export function decideEnemyAction(w: World, enemy: CombatantActor, player: Comba
// State transitions
let justAlerted = false;
if (canSee && enemy.aiState === "wandering") {
// Spotted player! Transition to alerted state
enemy.aiState = "alerted";
enemy.alertedAt = Date.now();
enemy.lastKnownPlayerPos = { ...player.pos };
justAlerted = true;
} else if (enemy.aiState === "alerted") {
// Check if alert period is over (1 second = 1000ms)
const alertDuration = 1000;
if (Date.now() - (enemy.alertedAt || 0) > alertDuration) {
enemy.aiState = "pursuing";
if (canSee) {
if (enemy.aiState === "wandering" || enemy.aiState === "searching") {
// Spotted player (or re-spotted)! Transition to alerted state
enemy.aiState = "alerted";
enemy.alertedAt = Date.now();
enemy.lastKnownPlayerPos = { ...player.pos };
justAlerted = true;
} else if (enemy.aiState === "pursuing") {
// Keep pursuing, update last known
enemy.lastKnownPlayerPos = { ...player.pos };
}
} else if (enemy.aiState === "pursuing") {
if (canSee) {
// Update last known position
enemy.lastKnownPlayerPos = { ...player.pos };
} else {
// Lost sight - check if we've reached last known position
if (enemy.lastKnownPlayerPos) {
const distToLastKnown = Math.abs(enemy.pos.x - enemy.lastKnownPlayerPos.x) +
Math.abs(enemy.pos.y - enemy.lastKnownPlayerPos.y);
if (distToLastKnown <= 1) {
// Reached last known position, return to wandering
enemy.aiState = "wandering";
enemy.lastKnownPlayerPos = undefined;
} else {
// Cannot see player
if (enemy.aiState === "alerted") {
// Check if alert period is over (1 second = 1000ms)
const alertDuration = 1000;
if (Date.now() - (enemy.alertedAt || 0) > alertDuration) {
enemy.aiState = "pursuing";
}
} else if (enemy.aiState === "pursuing") {
// Lost sight while pursuing -> switch to searching
enemy.aiState = "searching";
} else if (enemy.aiState === "searching") {
// Check if reached last known position
if (enemy.lastKnownPlayerPos) {
const distToLastKnown = Math.abs(enemy.pos.x - enemy.lastKnownPlayerPos.x) +
Math.abs(enemy.pos.y - enemy.lastKnownPlayerPos.y);
if (distToLastKnown <= 1) {
// Reached last known position, return to wandering
enemy.aiState = "wandering";
enemy.lastKnownPlayerPos = undefined;
}
} else {
enemy.aiState = "wandering";
}
} else {
// No last known position, return to wandering
enemy.aiState = "wandering";
}
}
}
@@ -344,7 +349,7 @@ export function decideEnemyAction(w: World, enemy: CombatantActor, player: Comba
}
if (enemy.aiState === "alerted") {
// During alert, stay still (or could do small movement)
// During alert, stay still
return { action: { type: "wait" }, justAlerted };
}