Refine archive world spawn and interaction handling
All checks were successful
Build Org Website / build (push) Successful in 38s
All checks were successful
Build Org Website / build (push) Successful in 38s
This commit is contained in:
@@ -9,6 +9,11 @@ test("fresh v2 state applies safe defaults", () => {
|
||||
assert.equal(fresh.name, "Ada");
|
||||
assert.equal(fresh.palette, "moss");
|
||||
assert.equal(fresh.position.area, "town");
|
||||
assert.deepEqual(
|
||||
{ x: fresh.position.x, y: fresh.position.y },
|
||||
data.AREAS.town.safeSpawns.gate
|
||||
);
|
||||
assert.ok(fresh.position.y > data.AREAS.town.gates[0].y + data.AREAS.town.gates[0].height);
|
||||
assert.equal(fresh.health, 100);
|
||||
assert.equal(fresh.settings.soundEnabled, false);
|
||||
assert.deepEqual(fresh.sigils, []);
|
||||
|
||||
@@ -102,6 +102,31 @@ test("invalid collision positions resolve to a named safe spawn", () => {
|
||||
assert.ok(["gate", "square", "library", "study", "inn", "workshop", "playroom", "museum", "garden"].includes(safe.spawn));
|
||||
});
|
||||
|
||||
test("locked-gate saves inside town recover to the outside opening spawn", () => {
|
||||
const current = state.fresh("Ada", "brass");
|
||||
current.position = { area: "town", spawn: "square", x: 724, y: 555, facing: "south" };
|
||||
const safe = systems.safeSpawnForState(current);
|
||||
assert.deepEqual(
|
||||
{ area: safe.area, spawn: safe.spawn, x: safe.x, y: safe.y },
|
||||
{ area: "town", spawn: "gate", ...data.AREAS.town.safeSpawns.gate }
|
||||
);
|
||||
|
||||
current.sigils.push("gate");
|
||||
const unlocked = systems.safeSpawnForState(current);
|
||||
assert.equal(unlocked.spawn, "saved");
|
||||
assert.equal(unlocked.y, 555);
|
||||
});
|
||||
|
||||
test("interaction ranges are type-specific and NPC conversations require close approach", () => {
|
||||
const npc = { type: "npc", id: "orin", x: 0, y: 0 };
|
||||
const landmark = { type: "landmark", id: "gate", x: 56, y: 0 };
|
||||
assert.equal(systems.interactionRadius(npc), 46);
|
||||
assert.equal(systems.nearestInteraction([npc], 47, 0), null);
|
||||
assert.equal(systems.nearestInteraction([npc], 45, 0), npc);
|
||||
assert.equal(systems.nearestInteraction([npc, landmark], 0, 0), npc);
|
||||
assert.equal(systems.nearestInteraction([landmark], 0, 0), landmark);
|
||||
});
|
||||
|
||||
test("all declared safe spawns and enemy homes are outside collision geometry", () => {
|
||||
Object.entries(data.AREAS).forEach(([areaId, area]) => {
|
||||
Object.entries(area.safeSpawns).forEach(([spawnId, spawn]) => {
|
||||
@@ -125,3 +150,11 @@ test("town landmarks and NPC interaction points remain reachable", () => {
|
||||
assert.equal(systems.isSafe("town", x, y), true, `npc:${npcId}`);
|
||||
});
|
||||
});
|
||||
|
||||
test("town safe spawns do not place the player inside an NPC body", () => {
|
||||
Object.entries(data.AREAS.town.safeSpawns).forEach(([spawnId, spawn]) => {
|
||||
data.AREAS.town.npcs.forEach(([npcId, x, y]) => {
|
||||
assert.ok(Math.hypot(spawn.x - x, spawn.y - y) >= 30, `${spawnId} overlaps npc:${npcId}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user