Let NPCs roam as HandleNPCStep does
Checks / web (push) Canceled after 0s

- Random walks and spins from SpriteMovementData, with random sleeps.
- CanObjectMoveInDirection: side walls, land, objects' current and
  previous tiles, the radius (stored plus one) and the screen edge.
- Objects freeze while text is open and during applymovement, and
  return home when both they and their home leave the object window.
- Wandering positions are not saved; test helpers replan around NPCs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Sébastien QUEROLandClaude Opus 5.5 committed 2026-09-23 17:40:12 +02:00
1 parent 796fe8f6d5
commit 6a74f59e46
12 files changed
+386 -20

No files matched your search

+14
View File
@@ -5,6 +5,7 @@ import {
MAP_GROUP_COUNT,
NATIVE_MAPS,
NUM_ENGINE_FLAGS,
NUM_SPRITEMOVEDATA,
RAM,
SYMBOLS,
} from "./profile";
@@ -165,6 +166,7 @@ export class CrystalAssets {
y: r.byte(p + 1) - 4,
x: r.byte(p + 2) - 4,
movement: r.byte(p + 3),
radius: r.byte(p + 4),
hour1: r.byte(p + 5),
hour2: r.byte(p + 6),
palette: r.byte(p + 7) >> 4,
@@ -374,6 +376,18 @@ export class CrystalAssets {
}
return flags;
}
/** SpriteMovementData for a SPRITEMOVEDATA_* type: the movement
* function, flags1 (FIXED_FACING, NOCLIP_*, ...) and palette flags. */
spriteMovement(type: number): {
fn: number;
flags: number;
paletteFlags: number;
} {
if (type >= NUM_SPRITEMOVEDATA) throw new Error("Unknown movement type.");
const r = this.reader,
p = SYMBOLS.spriteMovementData + type * 6;
return { fn: r.byte(p), flags: r.byte(p + 3), paletteFlags: r.byte(p + 5) };
}
/** Emote bubble graphics (data/sprites/emotes.asm). */
emote(index: number): Uint8Array {
const r = this.reader,