feat: implement golemancy combat system (spec §6, §9)
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m19s

- Add ActiveGolem interface and activeGolems to GolemancyState
- Add maxRoomDuration to all 12 golem definitions
- Create golem-combat-actions.ts with pure golem combat logic (summoning, maintenance, attacks, room-duration)
- Create golem-combat.ts pipeline for golem combat setup
- Wire golem maintenance and attacks into processCombatTick
- Wire golem summoning into advanceRoomOrFloor on room entry
- Wire golem room-duration countdown into onFloorCleared callback
- Update combat-actions tests for new processCombatTick signature
- All 921 tests pass, all files under 400-line limit

Closes #259
This commit is contained in:
2026-06-03 15:40:39 +02:00
parent 7c0e740226
commit a2cdf6d21c
20 changed files with 583 additions and 41 deletions
+7 -1
View File
@@ -4,7 +4,7 @@
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
import { createSafeStorage } from '../utils/safe-persist';
import type { GameAction, SpellState, FloorState, GolemancyState, ActivityLogEntry, AchievementState, EquipmentSpellState, ActivityEventType } from '../types';
import type { GameAction, SpellState, FloorState, GolemancyState, ActivityLogEntry, AchievementState, EquipmentSpellState, ActivityEventType, ActiveGolem } from '../types';
import { getFloorMaxHP } from '../utils';
import { generateFloorState } from '../utils/room-utils';
import { addActivityLogEntry } from '../utils/activity-log';
@@ -55,6 +55,7 @@ export const useCombatStore = create<CombatStore>()(
golemancy: {
enabledGolems: [],
summonedGolems: [],
activeGolems: [],
lastSummonFloor: 0,
},
@@ -189,6 +190,7 @@ export const useCombatStore = create<CombatStore>()(
currentRoomIndex: 0,
roomsPerFloor: 1,
maxFloorReached: Math.max(s.maxFloorReached, 1),
golemancy: { ...s.golemancy, activeGolems: [], summonedGolems: [] },
}));
},
@@ -298,6 +300,8 @@ export const useCombatStore = create<CombatStore>()(
onFloorCleared: (floor: number, wasGuardian: boolean) => void,
onDamageDealt: (damage: number) => { rawMana: number; elements: Record<string, { current: number; max: number; unlocked: boolean }> },
signedPacts: number[],
golemancyState: { activeGolems: ActiveGolem[] },
golemApplyDamageToRoom: (dmg: number) => { floorHP: number; floorMaxHP: number; roomCleared: boolean },
) => {
return processCombatTick(
get,
@@ -309,6 +313,8 @@ export const useCombatStore = create<CombatStore>()(
onFloorCleared,
onDamageDealt,
signedPacts,
golemancyState,
golemApplyDamageToRoom,
);
},