Enhance enemy AI and area connectivity

- Introduced area grid management in WolfEngine to track player-connected areas.
- Updated enemy behavior to consider area connectivity when alerting and moving.
- Added debugging logs for enemy states and movements to assist in tracking AI behavior.
- Implemented fallback area generation for levels lacking area data.
- Enhanced patrol behavior for dogs and guards to prevent rapid direction changes after hitting walls.
- Updated tests to validate new area connectivity logic and enemy behavior under various conditions.

Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
2026-03-19 18:03:01 +01:00
parent 7b1ec777d3
commit 4700e669ce
21 changed files with 565 additions and 135 deletions

View File

@@ -1,3 +1,4 @@
import 'dart:developer';
import 'dart:io';
import 'dart:typed_data';
@@ -12,7 +13,7 @@ Future<Map<GameVersion, WolfensteinData>> discoverInDirectory({
}) async {
final dir = Directory(directoryPath ?? Directory.current.path);
if (!await dir.exists()) {
print('Warning: Directory does not exist -> ${dir.path}');
log('Warning: Directory does not exist -> ${dir.path}');
return {};
}
@@ -60,7 +61,9 @@ Future<Map<GameVersion, WolfensteinData>> discoverInDirectory({
.where((f) => !foundFiles.containsKey(f))
.map((f) => '${f.baseName}.$ext')
.join(', ');
print('Found partial data for ${version.name}. Missing: $missingFiles');
log(
'Found partial data for ${version.name}. Missing: $missingFiles',
);
continue;
}
@@ -73,10 +76,10 @@ Future<Map<GameVersion, WolfensteinData>> discoverInDirectory({
final hash = md5.convert(vswapBytes).toString();
final identity = DataVersion.fromChecksum(hash);
print('--- Found ${version.name} ---');
print('MD5 Identity: ${identity.name} ($hash)');
log('--- Found ${version.name} ---');
log('MD5 Identity: ${identity.name} ($hash)');
if (identity == DataVersion.version10Retail) {
print(
log(
'Note: Detected v1.0 specific file structure (MAPTEMP support active).',
);
}
@@ -97,7 +100,7 @@ Future<Map<GameVersion, WolfensteinData>> discoverInDirectory({
loadedVersions[version] = data;
} catch (e) {
print('Error parsing data for ${version.name}: $e');
log('Error parsing data for ${version.name}: $e');
}
}

View File

@@ -11,6 +11,8 @@ import 'package:wolf_3d_dart/wolf_3d_data_types.dart';
/// objects (walls, sprites, audio, levels, and UI elements) using original
/// algorithms like Carmackization, RLEW, and Huffman expansion.
abstract class WLParser {
static const int _areaTileBase = 107;
// --- Original Song Lookup Tables ---
static const List<int> _sharewareMusicMap = [
2, 3, 4, 5, 2, 3, 4, 5, 6, 7, // Episode 1
@@ -486,16 +488,25 @@ abstract class WLParser {
// --- BUILD 64x64 GRIDS ---
List<List<int>> wallGrid = [];
List<List<int>> objectGrid = [];
List<List<int>> areaGrid = [];
for (int y = 0; y < 64; y++) {
List<int> wallRow = [];
List<int> objectRow = [];
List<int> areaRow = [];
for (int x = 0; x < 64; x++) {
wallRow.add(flatWallGrid[y * 64 + x]);
final rawWallId = flatWallGrid[y * 64 + x];
wallRow.add(rawWallId);
objectRow.add(flatObjectGrid[y * 64 + x]);
if (rawWallId >= _areaTileBase) {
areaRow.add(rawWallId - _areaTileBase);
} else {
areaRow.add(-1);
}
}
wallGrid.add(wallRow);
objectGrid.add(objectRow);
areaGrid.add(areaRow);
}
// --- ASSIGN MUSIC ---
@@ -508,6 +519,7 @@ abstract class WLParser {
name: parsedName,
wallGrid: wallGrid,
objectGrid: objectGrid,
areaGrid: areaGrid,
musicIndex: trackIndex,
),
);