Refactor enemy sound handling and improve enemy type definitions

- Updated enemy classes to include alert and attack sound IDs.
- Refactored checkWakeUp and attack logic to play sounds appropriately.
- Enhanced enemy type definitions with sound mappings.
- Added unit tests for enemy spawn and validation.

Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
2026-03-18 02:26:44 +01:00
parent b040b88d8a
commit 806c9b6966
13 changed files with 179 additions and 33 deletions

View File

@@ -197,8 +197,8 @@ class Player {
return pickedUp;
}
void fire(int currentTime) {
if (switchState != WeaponSwitchState.idle) return;
bool fire(int currentTime) {
if (switchState != WeaponSwitchState.idle) return false;
// We pass the isFiring state to handle automatic vs semi-auto behavior
bool shotFired = currentWeapon.fire(currentTime, currentAmmo: ammo);
@@ -206,6 +206,8 @@ class Player {
if (shotFired && currentWeapon.type != WeaponType.knife) {
ammo--;
}
return shotFired;
}
void releaseTrigger() {

View File

@@ -85,6 +85,7 @@ class WolfEngine {
/// Initializes the engine, sets the starting episode, and loads the first level.
void init() {
audio.activeGame = data;
_currentEpisodeIndex = startingEpisode;
_currentLevelIndex = 0;
_loadLevel();
@@ -247,9 +248,13 @@ class WolfEngine {
}
if (input.isFiring) {
player.fire(_timeAliveMs);
final bool shotFired = player.fire(_timeAliveMs);
if (_timeAliveMs - _lastAcousticAlertTime > 400) {
if (shotFired) {
_playPlayerWeaponSound();
}
if (shotFired && _timeAliveMs - _lastAcousticAlertTime > 400) {
_propagateGunfire();
_lastAcousticAlertTime = _timeAliveMs;
}
@@ -356,6 +361,7 @@ class WolfEngine {
isWalkable: isWalkable,
tryOpenDoor: doorManager.tryOpenDoor,
onDamagePlayer: (int damage) => player.takeDamage(damage),
onPlaySound: audio.playSoundEffect,
);
// Scale the enemy's movement intent to prevent super-speed on 90Hz/120Hz displays
@@ -429,6 +435,7 @@ class WolfEngine {
if (entity.position.x.toInt() == tile.x &&
entity.position.y.toInt() == tile.y) {
entity.isAlerted = true;
audio.playSoundEffect(entity.alertSoundId);
// Wake them up!
if (entity.state == EntityState.idle ||
@@ -480,6 +487,17 @@ class WolfEngine {
return false;
}
void _playPlayerWeaponSound() {
final sfxId = switch (player.currentWeapon.type) {
WeaponType.knife => WolfSound.knifeAttack,
WeaponType.pistol => WolfSound.pistolFire,
WeaponType.machineGun => WolfSound.machineGunFire,
WeaponType.chainGun => WolfSound.gatlingFire,
};
audio.playSoundEffect(sfxId);
}
/// Clamps movement to a maximum of 0.2 tiles per step to prevent wall-clipping
/// and map-boundary jumps during low framerate/high delta spikes.
Coordinate2D _clampMovement(Coordinate2D intent) {