Update enemy AI

Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
2026-03-15 18:16:46 +01:00
parent 347528c9f4
commit 6c55136d5b
5 changed files with 66 additions and 22 deletions

View File

@@ -69,8 +69,11 @@ class HansGrosse extends Enemy {
}) {
Coordinate2D movement = const Coordinate2D(0, 0);
// Bosses lack directional sprites, they always look straight at the player
double newAngle = position.angleTo(playerPosition);
double newAngle = angle;
if (isAlerted && state != EntityState.dead) {
newAngle = position.angleTo(playerPosition);
}
checkWakeUp(
elapsedMs: elapsedMs,
@@ -87,9 +90,10 @@ class HansGrosse extends Enemy {
break;
case EntityState.patrolling:
if (distance > 1.5) {
double moveX = math.cos(newAngle) * speed;
double moveY = math.sin(newAngle) * speed;
if (!isAlerted || distance > 1.5) {
double currentMoveAngle = isAlerted ? newAngle : angle;
double moveX = math.cos(currentMoveAngle) * speed;
double moveY = math.sin(currentMoveAngle) * speed;
movement = getValidMovement(
Coordinate2D(moveX, moveY),
isWalkable,
@@ -100,7 +104,7 @@ class HansGrosse extends Enemy {
int walkFrame = (elapsedMs ~/ 150) % 4;
spriteIndex = (_baseSprite + 1) + walkFrame;
if (distance < 8.0 && elapsedMs - lastActionTime > 1000) {
if (isAlerted && distance < 8.0 && elapsedMs - lastActionTime > 1000) {
if (hasLineOfSight(playerPosition, isWalkable)) {
state = EntityState.attacking;
lastActionTime = elapsedMs;

View File

@@ -66,10 +66,28 @@ class Dog extends Enemy {
angleDiff: diff,
);
if (state == EntityState.patrolling && distance < 1.0) {
state = EntityState.attacking;
lastActionTime = elapsedMs;
_hasBittenThisCycle = false;
if (isAlerted && state != EntityState.dead) {
newAngle = angleToPlayer;
}
// Dogs attack based on distance, so wrap the movement and attack in alert checks
if (state == EntityState.patrolling) {
if (!isAlerted || distance > 1.0) {
double currentMoveAngle = isAlerted ? angleToPlayer : angle;
double moveX = math.cos(currentMoveAngle) * speed;
double moveY = math.sin(currentMoveAngle) * speed;
movement = getValidMovement(
Coordinate2D(moveX, moveY),
isWalkable,
tryOpenDoor,
);
}
if (isAlerted && distance < 1.0) {
state = EntityState.attacking;
lastActionTime = elapsedMs;
_hasBittenThisCycle = false;
}
}
if (state == EntityState.attacking) {

View File

@@ -69,10 +69,16 @@ class Mutant extends Enemy {
angleDiff: diff,
);
if (isAlerted && state != EntityState.dead) {
newAngle = angleToPlayer;
}
if (state == EntityState.patrolling) {
if (distance > 0.8) {
double moveX = math.cos(angleToPlayer) * speed;
double moveY = math.sin(angleToPlayer) * speed;
// FIX 2: Move along patrol angle if unalerted, chase if alerted
if (!isAlerted || distance > 0.8) {
double currentMoveAngle = isAlerted ? angleToPlayer : angle;
double moveX = math.cos(currentMoveAngle) * speed;
double moveY = math.sin(currentMoveAngle) * speed;
movement = getValidMovement(
Coordinate2D(moveX, moveY),
isWalkable,
@@ -80,7 +86,8 @@ class Mutant extends Enemy {
);
}
if (distance < 6.0 && elapsedMs - lastActionTime > 1500) {
// FIX 3: Only attack if alerted (Adjust the distance/timing per enemy class!)
if (isAlerted && distance < 6.0 && elapsedMs - lastActionTime > 1500) {
if (hasLineOfSight(playerPosition, isWalkable)) {
state = EntityState.attacking;
lastActionTime = elapsedMs;

View File

@@ -69,17 +69,25 @@ class Officer extends Enemy {
angleDiff: diff,
);
if (isAlerted && state != EntityState.dead) {
newAngle = angleToPlayer;
}
if (state == EntityState.patrolling) {
if (distance > 0.8) {
double moveX = math.cos(angleToPlayer) * speed;
double moveY = math.sin(angleToPlayer) * speed;
// FIX 2: Move along patrol angle if unalerted, chase if alerted
if (!isAlerted || distance > 0.8) {
double currentMoveAngle = isAlerted ? angleToPlayer : angle;
double moveX = math.cos(currentMoveAngle) * speed;
double moveY = math.sin(currentMoveAngle) * speed;
movement = getValidMovement(
Coordinate2D(moveX, moveY),
isWalkable,
tryOpenDoor,
);
}
if (distance < 6.0 && elapsedMs - lastActionTime > 1000) {
// FIX 3: Only attack if alerted (Adjust the distance/timing per enemy class!)
if (isAlerted && distance < 6.0 && elapsedMs - lastActionTime > 1500) {
if (hasLineOfSight(playerPosition, isWalkable)) {
state = EntityState.attacking;
lastActionTime = elapsedMs;

View File

@@ -69,10 +69,16 @@ class SS extends Enemy {
angleDiff: diff,
);
if (isAlerted && state != EntityState.dead) {
newAngle = angleToPlayer;
}
if (state == EntityState.patrolling) {
if (distance > 0.8) {
double moveX = math.cos(angleToPlayer) * speed;
double moveY = math.sin(angleToPlayer) * speed;
// FIX 2: Move along patrol angle if unalerted, chase if alerted
if (!isAlerted || distance > 0.8) {
double currentMoveAngle = isAlerted ? angleToPlayer : angle;
double moveX = math.cos(currentMoveAngle) * speed;
double moveY = math.sin(currentMoveAngle) * speed;
movement = getValidMovement(
Coordinate2D(moveX, moveY),
isWalkable,
@@ -80,7 +86,8 @@ class SS extends Enemy {
);
}
if (distance < 6.0 && elapsedMs - lastActionTime > 1500) {
// FIX 3: Only attack if alerted (Adjust the distance/timing per enemy class!)
if (isAlerted && distance < 6.0 && elapsedMs - lastActionTime > 1500) {
if (hasLineOfSight(playerPosition, isWalkable)) {
state = EntityState.attacking;
lastActionTime = elapsedMs;