Files
Mana-Loop/src/lib/game/store-modules/initial-state.ts
T
Refactoring Agent d2d28887b1
Build and Publish Mana Loop Docker Image / build-and-publish (push) Failing after 1m9s
Refactor large files into modular components
- Refactored page.tsx (613→252 lines) with GameOverScreen and LeftPanel extracted
- Refactored StatsTab.tsx (584→92 lines) with section components
- Refactored SkillsTab.tsx (434→54 lines) with sub-components
- Created modular structure for GameContext, LootInventory, and other components
- All extracted components organized into feature directories
2026-05-02 17:35:03 +02:00

224 lines
7.2 KiB
TypeScript

// ─── Initial State Factory ────────────────────────────────────────────────────
// Extracted from store.ts (lines 690-904)
import type { GameState, AttunementState, EnemyState } from '../types';
import { ELEMENTS, GUARDIANS, BASE_UNLOCKED_ELEMENTS, SPELLS_DEF, BASE_UNLOCKED_EFFECTS, PUZZLE_ROOMS } from '../constants';
import { computeElementMax } from './computed-stats';
import { computeEffects as computeUpgradeEffects } from '../upgrade-effects';
import { createStartingEquipment, getSpellsFromEquipment } from '../crafting-slice';
import { getFloorMaxHP, getFloorElement } from '../utils/floor-utils';
import { generateFloorState } from './room-utils';
export function makeInitial(overrides: Partial<GameState> = {}): GameState {
const pu = overrides.prestigeUpgrades || {};
const startFloor = 1 + (pu.spireKey || 0) * 2;
const effects = overrides.skillUpgrades ? computeUpgradeEffects(overrides.skillUpgrades || {}, overrides.skillTiers || {}) : undefined;
const manaHeartBonus = overrides.manaHeartBonus || 0;
const unlockedManaTypeUpgrades = overrides.unlockedManaTypeUpgrades || [];
const elements: Record<string, { current: number; max: number; unlocked: boolean }> = {};
Object.keys(ELEMENTS).forEach((k) => {
const isUnlocked = BASE_UNLOCKED_ELEMENTS.includes(k);
let startAmount = 0;
// Start with some elemental mana if elemStart upgrade
if (isUnlocked && pu.elemStart) {
startAmount = pu.elemStart * 5;
}
// Calculate per-element max capacity including unlockedManaTypeCapacity upgrades
const baseElemMax = computeElementMax({
skills: overrides.skills || {},
prestigeUpgrades: pu,
skillUpgrades: overrides.skillUpgrades || {},
skillTiers: overrides.skillTiers || {},
unlockedManaTypeUpgrades
}, effects, k);
elements[k] = {
current: overrides.elements?.[k]?.current ?? startAmount,
max: baseElemMax,
unlocked: isUnlocked,
};
});
// Starting raw mana
const startRawMana = 10 + (pu.manaWell || 0) * 500 + (pu.quickStart || 0) * 100;
// Create starting equipment (staff with mana bolt, clothes)
const startingEquipment = createStartingEquipment();
// Get spells from starting equipment
const equipmentSpells = getSpellsFromEquipment(
startingEquipment.equipmentInstances,
Object.values(startingEquipment.equippedInstances)
);
// Starting spells - now come from equipment instead of being learned directly
const startSpells: Record<string, { learned: boolean; level: number; studyProgress: number }> = {};
// Add spells from equipment
for (const spellId of equipmentSpells) {
startSpells[spellId] = { learned: true, level: 1, studyProgress: 0 };
}
// Add random starting spells from spell memory upgrade (pact spells)
if (pu.spellMemory) {
const availableSpells = Object.keys(SPELLS_DEF).filter(s => !startSpells[s]);
const shuffled = availableSpells.sort(() => Math.random() - 0.5);
for (let i = 0; i < Math.min(pu.spellMemory, shuffled.length); i++) {
startSpells[shuffled[i]] = { learned: true, level: 1, studyProgress: 0 };
}
}
// Starting attunements - player begins with Enchanter
const startingAttunements: Record<string, AttunementState> = {
enchanter: { id: 'enchanter', active: true, level: 1, experience: 0 },
};
// Add any attunements from previous loops (for persistence)
if (overrides.attunements) {
Object.entries(overrides.attunements).forEach(([id, state]) => {
if (id !== 'enchanter') {
startingAttunements[id] = state;
}
});
}
// Unlock transference element for Enchanter attunement
if (elements['transference']) {
elements['transference'] = { ...elements['transference'], unlocked: true };
}
return {
day: 1,
hour: 0,
loopCount: overrides.loopCount || 0,
gameOver: false,
victory: false,
paused: false,
rawMana: startRawMana,
meditateTicks: 0,
totalManaGathered: overrides.totalManaGathered || 0,
// Attunements (class-like system)
attunements: startingAttunements,
elements: elements as Record<string, { current: number; max: number; unlocked: boolean }>,
currentFloor: startFloor,
floorHP: getFloorMaxHP(startFloor),
floorMaxHP: getFloorMaxHP(startFloor),
maxFloorReached: startFloor,
signedPacts: [],
activeSpell: 'manaBolt',
currentAction: 'meditate',
castProgress: 0,
// Initialize room state
currentRoom: generateFloorState(startFloor),
spells: startSpells,
skills: overrides.skills || {},
skillProgress: {},
skillUpgrades: overrides.skillUpgrades || {},
skillTiers: overrides.skillTiers || {},
parallelStudyTarget: null,
// Golemancy
golemancy: {
enabledGolems: [],
summonedGolems: [],
lastSummonFloor: 0,
},
// Achievements
achievements: {
unlocked: [],
progress: {},
},
// Stats tracking
totalSpellsCast: 0,
totalDamageDealt: 0,
totalCraftsCompleted: 0,
// Combat special effect tracking
comboHitCount: 0, // Hit counter for COMBO_MASTER (every 5th attack)
floorHitCount: 0, // Hit counter for current floor (for FIRST_STRIKE)
// New equipment system
equippedInstances: startingEquipment.equippedInstances,
equipmentInstances: startingEquipment.equipmentInstances,
enchantmentDesigns: [],
designProgress: null,
designProgress2: null,
preparationProgress: null,
applicationProgress: null,
equipmentCraftingProgress: null,
unlockedEffects: [...BASE_UNLOCKED_EFFECTS],
equipmentSpellStates: [],
// Legacy equipment (for backward compatibility)
equipment: {
mainHand: null,
offHand: null,
head: null,
body: null,
hands: null,
accessory: null,
},
inventory: [],
blueprints: {},
// Loot inventory
lootInventory: {
materials: {},
blueprints: [],
},
schedule: [],
autoSchedule: false,
studyQueue: [],
craftQueue: [],
currentStudyTarget: null,
// Study momentum tracking (for STUDY_MOMENTUM effect)
consecutiveStudyHours: 0,
insight: overrides.insight || 0,
totalInsight: overrides.totalInsight || 0,
prestigeUpgrades: pu,
memorySlots: 3 + (pu.deepMemory || 0),
memories: overrides.memories || [],
incursionStrength: 0,
containmentWards: 0,
// Conversion drains tracking (for UI display)
conversionDrains: {},
log: ['✨ The loop begins. You start with a Basic Staff (Mana Bolt) and civilian clothes. Gather your strength, mage.'],
loopInsight: 0,
flowSurgeEndTime: 0, // Hour timestamp for FLOW_SURGE effect (0 = inactive)
// Mana Well Effects (Phase 4)
manaHeartBonus: manaHeartBonus, // Cumulative +10% max mana per loop from MANA_HEART
// Spire Mode - simplified UI for climbing
spireMode: false,
clearedFloors: {},
climbDirection: null,
isDescending: false,
// Activity Log (for Spire Mode UI)
activityLog: [],
// Track selected mana types for unlockedManaTypeCapacity upgrade
unlockedManaTypeUpgrades: unlockedManaTypeUpgrades,
};
}