fix: complete golemancy component-based redesign cleanup
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
- Fix summonGolemsForRoom to use golemLoadout instead of removed enabledGolems - Fix discBonus hardcoded to 0 in golem-combat.ts pipeline (now computed from discipline effects) - Remove deprecated types: SummonedGolem, ActiveGolem, GolemDef - Remove legacy GolemancyState fields: enabledGolems, summonedGolems, legacyActiveGolems - Remove orphaned store actions: toggleGolem, setEnabledGolems - Delete orphaned legacy data files: base-golems.ts, elemental-golems.ts, hybrid-golems.ts - Update GolemDebugSection to use new golemLoadout system - Update golemancy-spec.md §17 to reflect all features as complete - Update all test files to match new type shapes - All 958 tests passing
This commit is contained in:
@@ -7,7 +7,7 @@ import { getGuardianForFloor } from '../data/guardian-encounters';
|
||||
import type { CombatStore, CombatState } from './combat-state.types';
|
||||
import type { SpellState, EnemyState, EquipmentInstance, FloorState } from '../types';
|
||||
import { applyOnHitEffect, processDoTPhase } from './dot-runtime';
|
||||
import type { ActiveGolem, RuntimeActiveGolem } from '../types';
|
||||
import type { RuntimeActiveGolem } from '../types';
|
||||
import { getFloorMaxHP, getFloorElement, getMultiElementBonus, calcDamage, calcMeleeDamage, canAffordSpellCost, deductSpellCost } from '../utils';
|
||||
import { computeDisciplineEffects } from '../effects/discipline-effects';
|
||||
import {
|
||||
|
||||
@@ -142,16 +142,17 @@ export function advanceRoomOrFloor(get: GetFn, set: SetFn): void {
|
||||
function summonGolemsForRoom(get: GetFn, set: SetFn): void {
|
||||
const s = get();
|
||||
const manaState = useManaStore.getState();
|
||||
const enabledGolems = s.golemancy?.enabledGolems ?? [];
|
||||
if (enabledGolems.length === 0) return;
|
||||
const loadout = s.golemancy?.golemLoadout ?? [];
|
||||
if (loadout.length === 0) return;
|
||||
|
||||
const currentActiveGolems = s.golemancy?.activeGolems ?? [];
|
||||
const summonResult = summonGolemsOnRoomEntry(
|
||||
enabledGolems,
|
||||
loadout,
|
||||
manaState.rawMana,
|
||||
manaState.elements,
|
||||
s.currentFloor,
|
||||
currentActiveGolems,
|
||||
0, // discBonus — computed in pipeline, not here
|
||||
);
|
||||
|
||||
if (summonResult.logMessages.length > 0) {
|
||||
@@ -244,7 +245,7 @@ export function createEnterSpireMode(get: GetFn, set: SetFn) {
|
||||
roomResetState: {},
|
||||
descentPeak: null,
|
||||
isDescentComplete: false,
|
||||
golemancy: { enabledGolems: [], summonedGolems: [], activeGolems: [], lastSummonFloor: 0, golemDesigns: {}, golemLoadout: [], legacyActiveGolems: [] },
|
||||
golemancy: { activeGolems: [], lastSummonFloor: 0, golemDesigns: {}, golemLoadout: [] },
|
||||
});
|
||||
|
||||
get().addActivityLog('floor_transition',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// ─── Combat State Types ────────────────────────────────────────────────────────
|
||||
// Shared types for combat store and combat actions to avoid circular dependency
|
||||
|
||||
import type { GameAction, SpellState, FloorState, GolemancyState, ActivityLogEntry, AchievementState, EquipmentSpellState, ActivityEventType, ActiveGolem, RuntimeActiveGolem, EnemyState, EquipmentInstance, SerializedGolemDesign } from '../types';
|
||||
import type { GameAction, SpellState, FloorState, GolemancyState, ActivityLogEntry, AchievementState, EquipmentSpellState, ActivityEventType, RuntimeActiveGolem, EnemyState, EquipmentInstance, SerializedGolemDesign } from '../types';
|
||||
|
||||
/** Signature for the advanceRoomOrFloor callback to break circular dependency */
|
||||
export type AdvanceRoomFn = (get: () => CombatStore, set: (s: Partial<CombatState>) => void) => void;
|
||||
@@ -128,8 +128,6 @@ export interface CombatActions {
|
||||
stayLongerInRoom: () => void;
|
||||
|
||||
// Golemancy
|
||||
toggleGolem: (golemId: string) => void;
|
||||
setEnabledGolems: (golemIds: string[]) => void;
|
||||
addGolemDesign: (design: SerializedGolemDesign) => void;
|
||||
removeGolemDesign: (designId: string) => void;
|
||||
toggleGolemLoadoutEntry: (designId: string) => void;
|
||||
|
||||
@@ -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, ActiveGolem, RuntimeActiveGolem, EnemyState, EquipmentInstance } from '../types';
|
||||
import type { GameAction, SpellState, FloorState, GolemancyState, ActivityLogEntry, AchievementState, EquipmentSpellState, ActivityEventType, RuntimeActiveGolem, EnemyState, EquipmentInstance } from '../types';
|
||||
import { getFloorMaxHP } from '../utils';
|
||||
import { generateSpireFloorState, getRoomsForFloor } from '../utils/spire-utils';
|
||||
import { addActivityLogEntry } from '../utils/activity-log';
|
||||
@@ -55,15 +55,10 @@ export const useCombatStore = create<CombatStore>()(
|
||||
|
||||
// Golemancy (component-based)
|
||||
golemancy: {
|
||||
// New component-based fields
|
||||
golemDesigns: {},
|
||||
golemLoadout: [],
|
||||
activeGolems: [] as RuntimeActiveGolem[],
|
||||
lastSummonFloor: 0,
|
||||
// Legacy fields (deprecated)
|
||||
enabledGolems: [],
|
||||
summonedGolems: [],
|
||||
legacyActiveGolems: [],
|
||||
},
|
||||
|
||||
// Equipment spell states
|
||||
@@ -204,7 +199,7 @@ export const useCombatStore = create<CombatStore>()(
|
||||
currentRoomIndex: 0,
|
||||
roomsPerFloor: 1,
|
||||
maxFloorReached: Math.max(s.maxFloorReached, 1),
|
||||
golemancy: { ...s.golemancy, activeGolems: [] as RuntimeActiveGolem[], summonedGolems: [], legacyActiveGolems: [] },
|
||||
golemancy: { ...s.golemancy, activeGolems: [] as RuntimeActiveGolem[] },
|
||||
};
|
||||
});
|
||||
},
|
||||
@@ -224,27 +219,6 @@ export const useCombatStore = create<CombatStore>()(
|
||||
stayLongerInRoom: () => stayLongerInRoom(get, set),
|
||||
|
||||
// Golemancy
|
||||
toggleGolem: (golemId: string) => {
|
||||
set((s) => {
|
||||
const enabledGolems = s.golemancy?.enabledGolems || [];
|
||||
const isEnabled = enabledGolems.includes(golemId);
|
||||
return {
|
||||
golemancy: {
|
||||
...s.golemancy,
|
||||
enabledGolems: isEnabled
|
||||
? enabledGolems.filter(id => id !== golemId)
|
||||
: [...enabledGolems, golemId]
|
||||
},
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
setEnabledGolems: (golemIds: string[]) => {
|
||||
set((s) => ({
|
||||
golemancy: { ...s.golemancy, enabledGolems: golemIds },
|
||||
}));
|
||||
},
|
||||
|
||||
addGolemDesign: (d) => addGolemDesign(set, d),
|
||||
removeGolemDesign: (id) => removeGolemDesign(set, id),
|
||||
toggleGolemLoadoutEntry: (id) => toggleGolemLoadoutEntry(set, id),
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
countdownGolemRoomDuration,
|
||||
} from '../golem-combat-actions';
|
||||
import { useAttunementStore } from '../attunementStore';
|
||||
import { computeDisciplineEffects } from '../../effects/discipline-effects';
|
||||
import type { RuntimeActiveGolem } from '../../types';
|
||||
|
||||
export interface GolemCombatContext {
|
||||
@@ -107,7 +108,8 @@ export function processGolemRoomEntry(
|
||||
const cs = useCombatStore.getState();
|
||||
const attStore = useAttunementStore.getState();
|
||||
const fabLevel = attStore.attunements?.fabricator?.level ?? 0;
|
||||
const discBonus = 0; // TODO: compute from discipline
|
||||
const discEffects = computeDisciplineEffects();
|
||||
const discBonus = Math.floor(discEffects.bonuses.golemCapacity || 0);
|
||||
|
||||
return summonGolemsOnRoomEntry(
|
||||
loadout as any,
|
||||
|
||||
Reference in New Issue
Block a user