refactor: remove GUARDIANS constant, consolidate into guardian-data.ts

- Delete src/lib/game/constants/guardians.ts (the old static GUARDIANS constant)
- Create src/lib/game/data/guardian-data.ts with BASE_GUARDIANS (same data, new home)
- Remove GUARDIANS export from constants/index.ts
- Update all 11 files that imported GUARDIANS to use getGuardianForFloor() or BASE_GUARDIANS:
  - useGameDerived.ts, combat-actions.ts, gameStore.ts, prestigeStore.ts
  - combat-utils.ts, room-utils.ts, floor-utils.ts, spire-utils.ts
  - SpireCombatPage.tsx, SpireHeader.tsx
- Update 4 test files to use getGuardianForFloor() instead of GUARDIANS constant
- guardian-encounters.ts now imports BASE_GUARDIANS from guardian-data.ts
- Split room-utils.test.ts (505 lines) into room-utils.test.ts + room-utils-floor-state.test.ts
This commit is contained in:
2026-05-23 16:09:19 +02:00
parent d7b822d965
commit 513cab81a3
21 changed files with 228 additions and 217 deletions
+5 -3
View File
@@ -2,8 +2,10 @@
import type { SpellCost, EquipmentInstance } from '../types';
import type { DisciplineBonuses } from './mana-utils';
import { GUARDIANS, SPELLS_DEF, ELEMENT_OPPOSITES, INCURSION_START_DAY, MAX_DAY } from '../constants';
import { SPELLS_DEF, ELEMENT_OPPOSITES, INCURSION_START_DAY, MAX_DAY } from '../constants';
import { ENCHANTMENT_EFFECTS } from '../data/enchantment-effects';
import { getGuardianForFloor } from '../data/guardian-encounters';
import { BASE_GUARDIANS } from '../data/guardian-data';
// ─── Damage Calculation Params ──────────────────────────────────────────────
@@ -86,7 +88,7 @@ export function getBoonBonuses(signedPacts: number[]): BoonBonuses {
};
for (const floor of signedPacts) {
const guardian = GUARDIANS[floor];
const guardian = getGuardianForFloor(floor);
if (!guardian) continue;
for (const boon of guardian.boons) {
@@ -158,7 +160,7 @@ export function calcDamage(
const elemMasteryBonus = 1 + (skills.elementalMastery || 0) * 0.15;
// Guardian bane bonus
const isGuardianFloor = floorElem && Object.values(GUARDIANS).some(g => g.element === floorElem);
const isGuardianFloor = floorElem && Object.values(BASE_GUARDIANS).some(g => g.element === floorElem);
const guardianBonus = isGuardianFloor
? 1 + (skills.guardianBane || 0) * 0.2
: 1;
+4 -2
View File
@@ -1,9 +1,11 @@
// ─── Floor Helpers ────────────────────────────────────────────────────────────
import { GUARDIANS, FLOOR_ELEM_CYCLE } from '../constants';
import { FLOOR_ELEM_CYCLE } from '../constants';
import { getGuardianForFloor } from '../data/guardian-encounters';
export function getFloorMaxHP(floor: number): number {
if (GUARDIANS[floor]) return GUARDIANS[floor].hp;
const guardian = getGuardianForFloor(floor);
if (guardian) return guardian.hp;
// Improved scaling: slower early game, faster late game
const baseHP = 100;
const floorScaling = floor * 50;
+8 -5
View File
@@ -2,7 +2,8 @@
// Moved from store-modules/room-utils.ts to eliminate legacy dependencies
import type { RoomType, FloorState, EnemyState } from '../types';
import { GUARDIANS, FLOOR_ELEM_CYCLE, PUZZLE_ROOMS, PUZZLE_ROOM_INTERVAL, PUZZLE_ROOM_CHANCE, SWARM_ROOM_CHANCE, SPEED_ROOM_CHANCE, FLOOR_ARMOR_CONFIG, SWARM_CONFIG, SPEED_ROOM_CONFIG } from '../constants';
import { FLOOR_ELEM_CYCLE, PUZZLE_ROOMS, PUZZLE_ROOM_INTERVAL, PUZZLE_ROOM_CHANCE, SWARM_ROOM_CHANCE, SPEED_ROOM_CHANCE, FLOOR_ARMOR_CONFIG, SWARM_CONFIG, SPEED_ROOM_CONFIG } from '../constants';
import { getGuardianForFloor } from '../data/guardian-encounters';
import { getFloorMaxHP } from './floor-utils';
import { getFloorElement } from './floor-utils';
import { getEnemyName, generateSwarmEnemies } from './enemy-utils';
@@ -10,7 +11,7 @@ import { getEnemyName, generateSwarmEnemies } from './enemy-utils';
// Generate room type for a floor
export function generateRoomType(floor: number): RoomType {
// Guardian floors are always guardian type
if (GUARDIANS[floor]) {
if (getGuardianForFloor(floor)) {
return 'guardian';
}
@@ -35,8 +36,9 @@ export function generateRoomType(floor: number): RoomType {
// Get armor for a non-guardian floor
export function getFloorArmor(floor: number): number {
if (GUARDIANS[floor]) {
return GUARDIANS[floor].armor || 0;
const guardian = getGuardianForFloor(floor);
if (guardian) {
return guardian.armor || 0;
}
// Armor becomes more common on higher floors
@@ -84,10 +86,11 @@ export function generateFloorState(floor: number): FloorState {
const roomType = generateRoomType(floor);
const element = getFloorElement(floor);
const baseHP = getFloorMaxHP(floor);
const guardian = GUARDIANS[floor];
const guardian = getGuardianForFloor(floor);
switch (roomType) {
case 'guardian':
if (!guardian) return { roomType: 'combat', enemies: [] };
return {
roomType: 'guardian',
enemies: [{
+3 -3
View File
@@ -2,10 +2,10 @@
// Spire-specific utility functions for room generation, enemy stat scaling, etc.
import type { RoomType, FloorState, EnemyState } from '../types';
import { GUARDIANS, FLOOR_ELEM_CYCLE, PUZZLE_ROOMS } from '../constants';
import { FLOOR_ELEM_CYCLE, PUZZLE_ROOMS } from '../constants';
import { getFloorMaxHP, getFloorElement } from './floor-utils';
import { getEnemyName } from './enemy-utils';
import { isGuardianFloor, getExtendedGuardian } from '../data/guardian-encounters';
import { getGuardianForFloor, isGuardianFloor } from '../data/guardian-encounters';
// ─── Spire Room Configuration ─────────────────────────────────────────────────
@@ -85,7 +85,7 @@ export function generateSpireFloorState(floor: number, roomIndex: number, totalR
switch (roomType) {
case 'guardian': {
const guardian = GUARDIANS[floor] || getExtendedGuardian(floor);
const guardian = getGuardianForFloor(floor);
if (guardian) {
return {
roomType: 'guardian',