Refactor collectible handling and scoring system

- Introduced `CollectiblePickupContext` and `CollectiblePickupEffect` to streamline the collectible pickup logic in the Player class.
- Updated the `tryPickup` method in the Player class to utilize the new effect system for health, ammo, score, keys, and weapons.
- Refactored collectible classes to implement the new `tryCollect` method, returning a `CollectiblePickupEffect`.
- Enhanced enemy classes to expose score values based on their type.
- Added unit tests for scoring ownership and shareware menu module functionality.
- Updated rendering logic in various renderer classes to use the new mapped picture retrieval system.
- Improved the `WolfClassicMenuArt` class to utilize a more structured approach for image retrieval based on registry keys.

Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
2026-03-19 14:25:14 +01:00
parent 6e53da7095
commit 57dde0f31c
15 changed files with 584 additions and 223 deletions
@@ -370,7 +370,7 @@ class AsciiRenderer extends CliRendererBackend<dynamic> {
final art = WolfClassicMenuArt(engine.data);
if (engine.menuManager.activeMenu == WolfMenuScreen.gameSelect) {
final cursor = art.pic(
final cursor = art.mappedPic(
engine.menuManager.isCursorAltFrame(engine.timeAliveMs) ? 9 : 8,
);
const int rowYStart = 84;
@@ -433,7 +433,7 @@ class AsciiRenderer extends CliRendererBackend<dynamic> {
if (engine.menuManager.activeMenu == WolfMenuScreen.episodeSelect) {
_fillRect320(12, 18, 296, 168, panelColor);
final cursor = art.pic(
final cursor = art.mappedPic(
engine.menuManager.isCursorAltFrame(engine.timeAliveMs) ? 9 : 8,
);
const int rowYStart = 24;
@@ -534,7 +534,7 @@ class AsciiRenderer extends CliRendererBackend<dynamic> {
_blitVgaImageAscii(face, 28 + 264 - face.width - 18, 92);
}
final cursor = art.pic(
final cursor = art.mappedPic(
engine.menuManager.isCursorAltFrame(engine.timeAliveMs) ? 9 : 8,
);
const rowYStart = 86;
@@ -356,7 +356,7 @@ class SixelRenderer extends CliRendererBackend<String> {
final art = WolfClassicMenuArt(engine.data);
if (engine.menuManager.activeMenu == WolfMenuScreen.gameSelect) {
_drawMenuTextCentered('SELECT GAME', 48, headingIndex, scale: 2);
final cursor = art.pic(
final cursor = art.mappedPic(
engine.menuManager.isCursorAltFrame(engine.timeAliveMs) ? 9 : 8,
);
const int rowYStart = 84;
@@ -387,7 +387,7 @@ class SixelRenderer extends CliRendererBackend<String> {
headingIndex,
scale: 2,
);
final cursor = art.pic(
final cursor = art.mappedPic(
engine.menuManager.isCursorAltFrame(engine.timeAliveMs) ? 9 : 8,
);
const int rowYStart = 30;
@@ -442,7 +442,7 @@ class SixelRenderer extends CliRendererBackend<String> {
scale: _menuHeadingScale,
);
final bottom = art.pic(15);
final bottom = art.mappedPic(15);
if (bottom != null) {
_blitVgaImage(bottom, (320 - bottom.width) ~/ 2, 200 - bottom.height - 8);
}
@@ -454,7 +454,7 @@ class SixelRenderer extends CliRendererBackend<String> {
_blitVgaImage(face, 28 + 264 - face.width - 10, 92);
}
final cursor = art.pic(
final cursor = art.mappedPic(
engine.menuManager.isCursorAltFrame(engine.timeAliveMs) ? 9 : 8,
);
const rowYStart = 86;
@@ -482,7 +482,7 @@ class SixelRenderer extends CliRendererBackend<String> {
}
void _drawMenuFooterArt(WolfClassicMenuArt art) {
final bottom = art.pic(15);
final bottom = art.mappedPic(15);
if (bottom == null) {
return;
}
@@ -194,7 +194,7 @@ class SoftwareRenderer extends RendererBackend<FrameBuffer> {
_drawMenuTextCentered('SELECT GAME', 38, headingColor, scale: 2);
final cursor = art.pic(
final cursor = art.mappedPic(
engine.menuManager.isCursorAltFrame(engine.timeAliveMs) ? 9 : 8,
);
@@ -234,7 +234,7 @@ class SoftwareRenderer extends RendererBackend<FrameBuffer> {
_drawMenuTextCentered('WHICH EPISODE TO PLAY?', 6, headingColor, scale: 2);
final cursor = art.pic(
final cursor = art.mappedPic(
engine.menuManager.isCursorAltFrame(engine.timeAliveMs) ? 9 : 8,
);
const int rowYStart = 30;
@@ -277,7 +277,7 @@ class SoftwareRenderer extends RendererBackend<FrameBuffer> {
}
void _drawCenteredMenuFooter(WolfClassicMenuArt art) {
final bottom = art.pic(15);
final bottom = art.mappedPic(15);
if (bottom != null) {
final int x = ((width - bottom.width) ~/ 2).clamp(0, width - 1);
final int y = (height - bottom.height - 8).clamp(0, height - 1);
@@ -339,7 +339,7 @@ class SoftwareRenderer extends RendererBackend<FrameBuffer> {
_drawMenuTextCentered(Difficulty.menuText, 48, headingColor, scale: 2);
final bottom = art.pic(15);
final bottom = art.mappedPic(15);
if (bottom != null) {
final x = (width - bottom.width) ~/ 2;
final y = height - bottom.height - 8;
@@ -353,7 +353,7 @@ class SoftwareRenderer extends RendererBackend<FrameBuffer> {
_blitVgaImage(face, panelX + panelW - face.width - 10, panelY + 22);
}
final cursor = art.pic(
final cursor = art.mappedPic(
engine.menuManager.isCursorAltFrame(engine.timeAliveMs) ? 9 : 8,
);
const int rowYStart = panelY + 16;