feat: implement spire descent system with room-aware navigation
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m18s
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m18s
Implements the spec-driven spire multi-room climbing and descent system: - Room navigation: currentRoomIndex, roomsPerFloor, startFloor, exitFloor - Descent tracking: descentPeak, roomResetState, clearedRooms, isDescentComplete - enterDescentMode: snapshots peak, sets climbDirection='down' - advanceRoomOrFloor: room-by-room ascending/descending with floor transitions - onEnterRoomDescend: per-room 50% reset check with auto-skip - onEnterLibraryRoom: discipline XP scaled by floor - Seeded PRNG for deterministic room counts and types - UI: Descend button during ascent, Exit Spire only when isDescentComplete - UI: Room X/Y display, room type badge, in-game time in RoomDisplay - Extracted descent actions to combat-descent-actions.ts (file size limit) - Updated tests for room-aware combat behavior Spec: docs/specs/spire-climbing-spec.md §4.1-§4.9, §6
This commit is contained in:
@@ -26,8 +26,16 @@ function resetStores() {
|
||||
spireMode: false,
|
||||
currentRoom: { roomType: 'combat', enemies: [] },
|
||||
clearedFloors: {},
|
||||
climbDirection: null,
|
||||
climbDirection: 'up',
|
||||
isDescending: false,
|
||||
startFloor: 1,
|
||||
exitFloor: 1,
|
||||
currentRoomIndex: 0,
|
||||
roomsPerFloor: 5,
|
||||
descentPeak: null,
|
||||
roomResetState: {},
|
||||
clearedRooms: {},
|
||||
isDescentComplete: false,
|
||||
golemancy: { enabledGolems: [], summonedGolems: [], lastSummonFloor: 0 },
|
||||
equipmentSpellStates: [],
|
||||
comboHitCount: 0,
|
||||
@@ -103,13 +111,25 @@ describe('processCombatTick', () => {
|
||||
});
|
||||
|
||||
describe('floor advancement', () => {
|
||||
it('should advance floor when HP reaches 0', () => {
|
||||
it('should advance room when HP reaches 0 (not last room)', () => {
|
||||
// Set floor HP very low so it's cleared in one cast
|
||||
useCombatStore.setState({ floorHP: 1, castProgress: 0.99 });
|
||||
// currentRoomIndex=0, roomsPerFloor=5 → clears room 0, advances to room 1
|
||||
useCombatStore.setState({ floorHP: 1, castProgress: 0.99, climbDirection: 'up', currentRoomIndex: 0, roomsPerFloor: 5 });
|
||||
const elements = makeInitialElements(500, {});
|
||||
const result = runCombatTick(1000, elements);
|
||||
// Room advanced, floor stays the same
|
||||
expect(result.currentFloor).toBe(1);
|
||||
// floorHP should be the new room's enemy HP
|
||||
expect(result.floorHP).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('should advance floor when last room on floor is cleared', () => {
|
||||
// Set currentRoomIndex to last room so clearing it advances the floor
|
||||
useCombatStore.setState({ floorHP: 1, castProgress: 0.99, climbDirection: 'up', currentRoomIndex: 4, roomsPerFloor: 5 });
|
||||
const elements = makeInitialElements(500, {});
|
||||
const result = runCombatTick(1000, elements);
|
||||
expect(result.currentFloor).toBe(2);
|
||||
expect(result.floorHP).toBe(getFloorMaxHP(2));
|
||||
expect(result.floorHP).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('should update maxFloorReached when advancing', () => {
|
||||
|
||||
Reference in New Issue
Block a user