refactor: consolidate duplicate functions (calculateDesignTime, calculateDesignCapacityCost, generateSwarmEnemies)
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m21s
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m21s
This commit is contained in:
@@ -190,22 +190,19 @@ Mana-Loop/
|
|||||||
│ │ │ ├── store-method-tests/
|
│ │ │ ├── store-method-tests/
|
||||||
│ │ │ ├── achievements.test.ts
|
│ │ │ ├── achievements.test.ts
|
||||||
│ │ │ ├── bug-fixes.test.ts
|
│ │ │ ├── bug-fixes.test.ts
|
||||||
│ │ │ ├── combat-store.test.ts
|
|
||||||
│ │ │ ├── combat-utils.test.ts
|
│ │ │ ├── combat-utils.test.ts
|
||||||
│ │ │ ├── computed-stats.test.ts
|
│ │ │ ├── computed-stats.test.ts
|
||||||
│ │ │ ├── discipline-math.test.ts
|
│ │ │ ├── discipline-math.test.ts
|
||||||
│ │ │ ├── discipline-store.test.ts
|
|
||||||
│ │ │ ├── enemy-generator.test.ts
|
│ │ │ ├── enemy-generator.test.ts
|
||||||
│ │ │ ├── floor-utils.test.ts
|
│ │ │ ├── floor-utils.test.ts
|
||||||
│ │ │ ├── formatting.test.ts
|
│ │ │ ├── formatting.test.ts
|
||||||
│ │ │ ├── mana-store.test.ts
|
|
||||||
│ │ │ ├── mana-utils.test.ts
|
│ │ │ ├── mana-utils.test.ts
|
||||||
│ │ │ ├── prestige-store.test.ts
|
|
||||||
│ │ │ ├── regression-fixes.test.ts
|
│ │ │ ├── regression-fixes.test.ts
|
||||||
│ │ │ ├── spire-utils.test.ts
|
│ │ │ ├── spire-utils.test.ts
|
||||||
│ │ │ ├── test-setup.ts
|
│ │ │ ├── store-actions-combat-prestige.test.ts
|
||||||
│ │ │ ├── tick-debug.test.ts
|
│ │ │ ├── store-actions-discipline.test.ts
|
||||||
│ │ │ ├── tick-integration-pact.test.ts
|
│ │ │ ├── store-actions-mana.test.ts
|
||||||
|
│ │ │ ├── store-actions.test.ts
|
||||||
│ │ │ └── tick-integration.test.ts
|
│ │ │ └── tick-integration.test.ts
|
||||||
│ │ ├── constants/
|
│ │ ├── constants/
|
||||||
│ │ │ ├── spells-modules/
|
│ │ │ ├── spells-modules/
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { EQUIPMENT_TYPES } from '@/lib/game/data/equipment';
|
import { EQUIPMENT_TYPES } from '@/lib/game/data/equipment';
|
||||||
import { ENCHANTMENT_EFFECTS, calculateEffectCapacityCost } from '@/lib/game/data/enchantment-effects';
|
import { ENCHANTMENT_EFFECTS, calculateEffectCapacityCost } from '@/lib/game/data/enchantment-effects';
|
||||||
import type { DesignEffect, EquipmentInstance, EquipmentCategory } from '@/lib/game/types';
|
import type { DesignEffect, EquipmentInstance, EquipmentCategory } from '@/lib/game/types';
|
||||||
|
import { calculateDesignCapacityCost as calcCapacityCost, calculateDesignTime as calcDesignTime } from '@/lib/game/crafting-design';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get available effects for selected equipment type (only unlocked ones)
|
* Get available effects for selected equipment type (only unlocked ones)
|
||||||
@@ -85,15 +86,13 @@ export function getIncompatibilityReason(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate total capacity cost for current design
|
* Calculate total capacity cost for current design
|
||||||
|
* Delegates to canonical calculateDesignCapacityCost from crafting-design
|
||||||
*/
|
*/
|
||||||
export function calculateDesignCapacityCost(
|
export function calculateDesignCapacityCost(
|
||||||
selectedEffects: DesignEffect[],
|
selectedEffects: DesignEffect[],
|
||||||
efficiencyBonus: number
|
efficiencyBonus: number
|
||||||
): number {
|
): number {
|
||||||
return selectedEffects.reduce(
|
return calcCapacityCost(selectedEffects, efficiencyBonus);
|
||||||
(total, eff) => total + calculateEffectCapacityCost(eff.effectId, eff.stacks, efficiencyBonus),
|
|
||||||
0
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -105,9 +104,10 @@ export function getEquipmentCapacity(selectedEquipmentType: string | null): numb
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate design time
|
* Calculate design time
|
||||||
|
* Delegates to canonical calculateDesignTime from crafting-design
|
||||||
*/
|
*/
|
||||||
export function calculateDesignTime(selectedEffects: DesignEffect[]): number {
|
export function calculateDesignTime(selectedEffects: DesignEffect[]): number {
|
||||||
return selectedEffects.reduce((total, eff) => total + 0.5 * eff.stacks, 1);
|
return calcDesignTime(selectedEffects);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
// ─── Crafting Helper Utilities ─────────────────────────────────────────────────
|
// ─── Crafting Helper Utilities ─────────────────────────────────────────────────
|
||||||
// Instance/ID generation and helper functions
|
// Instance/ID generation and helper functions
|
||||||
|
|
||||||
import type { EquipmentInstance, EnchantmentDesign, DesignEffect } from './types';
|
import type { EquipmentInstance, EnchantmentDesign } from './types';
|
||||||
import { EQUIPMENT_TYPES, type EquipmentCategory, type EquipmentSlot } from './data/equipment';
|
import { EQUIPMENT_TYPES, type EquipmentCategory, type EquipmentSlot } from './data/equipment';
|
||||||
import { ENCHANTMENT_EFFECTS, calculateEffectCapacityCost } from './data/enchantment-effects';
|
|
||||||
import { CRAFTING_RECIPES, canCraftRecipe, type CraftingRecipe } from './data/crafting-recipes';
|
import { CRAFTING_RECIPES, canCraftRecipe, type CraftingRecipe } from './data/crafting-recipes';
|
||||||
|
|
||||||
// ─── Instance/ID Generation ──────────────────────────────────────────────────
|
// ─── Instance/ID Generation ──────────────────────────────────────────────────
|
||||||
@@ -29,10 +28,6 @@ export function getEquipmentType(typeId: string) {
|
|||||||
|
|
||||||
// ─── Capacity Calculation Helpers ────────────────────────────────────────────
|
// ─── Capacity Calculation Helpers ────────────────────────────────────────────
|
||||||
|
|
||||||
export function calculateDesignCapacityCost(effects: DesignEffect[], efficiencyBonus: number = 0): number {
|
|
||||||
return effects.reduce((total, eff) => total + calculateEffectCapacityCost(eff.effectId, eff.stacks, efficiencyBonus), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getAvailableCapacity(instance: EquipmentInstance): number {
|
export function getAvailableCapacity(instance: EquipmentInstance): number {
|
||||||
return instance.totalCapacity - instance.usedCapacity;
|
return instance.totalCapacity - instance.usedCapacity;
|
||||||
}
|
}
|
||||||
@@ -43,17 +38,6 @@ export function designFitsInEquipment(design: EnchantmentDesign, instance: Equip
|
|||||||
|
|
||||||
// ─── Time Calculation Helpers ────────────────────────────────────────────────
|
// ─── Time Calculation Helpers ────────────────────────────────────────────────
|
||||||
|
|
||||||
export function calculateDesignTime(effects: DesignEffect[]): number {
|
|
||||||
let time = 1;
|
|
||||||
for (const eff of effects) {
|
|
||||||
const effectDef = ENCHANTMENT_EFFECTS[eff.effectId];
|
|
||||||
if (effectDef) {
|
|
||||||
time += 0.5 * eff.stacks;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return time;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function calculatePrepTime(equipmentCapacity: number): number {
|
export function calculatePrepTime(equipmentCapacity: number): number {
|
||||||
return 2 + Math.floor(equipmentCapacity / 50);
|
return 2 + Math.floor(equipmentCapacity / 50);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,24 @@
|
|||||||
// ─── Enemy Naming System ───────────────────────────────────────────────
|
// ─── Enemy Naming & Swarm Generation ──────────────────────────────────
|
||||||
// Moved from store-modules/enemy-utils.ts to eliminate legacy dependencies
|
// Moved from store-modules/enemy-utils.ts to eliminate legacy dependencies
|
||||||
|
|
||||||
import type { EnemyState } from '../types';
|
import type { EnemyState } from '../types';
|
||||||
import { SWARM_CONFIG } from '../constants';
|
import { SWARM_CONFIG } from '../constants';
|
||||||
import { getFloorMaxHP, getFloorElement } from './floor-utils';
|
import { getFloorMaxHP, getFloorElement } from './floor-utils';
|
||||||
|
|
||||||
|
// Barrier elements more likely to have barrier
|
||||||
|
const BARRIER_ELEMENTS = ['light', 'water', 'earth'];
|
||||||
|
|
||||||
|
// Get barrier for an enemy (0-1 as percentage of max HP)
|
||||||
|
function getEnemyBarrier(floor: number, element: string): number {
|
||||||
|
if (floor < 20) return 0;
|
||||||
|
const baseChance = BARRIER_ELEMENTS.includes(element) ? 0.15 : 0.08;
|
||||||
|
const floorBonus = Math.min(0.25, (floor - 20) * 0.003);
|
||||||
|
const barrierChance = Math.min(0.4, baseChance + floorBonus);
|
||||||
|
if (Math.random() > barrierChance) return 0;
|
||||||
|
const floorProgress = Math.min(1, (floor - 20) / 80);
|
||||||
|
return 0.1 + floorProgress * 0.2;
|
||||||
|
}
|
||||||
|
|
||||||
// Enemy names by element and floor tier
|
// Enemy names by element and floor tier
|
||||||
const ENEMY_NAMES_BY_ELEMENT: Record<string, string[]> = {
|
const ENEMY_NAMES_BY_ELEMENT: Record<string, string[]> = {
|
||||||
fire: ['Fire Imp', 'Flame Sprite', 'Emberling', 'Scorchling', 'Inferno Whelp'],
|
fire: ['Fire Imp', 'Flame Sprite', 'Emberling', 'Scorchling', 'Inferno Whelp'],
|
||||||
@@ -49,8 +63,7 @@ export function generateSwarmEnemies(floor: number): EnemyState[] {
|
|||||||
maxHP: Math.floor(baseHP * SWARM_CONFIG.hpMultiplier),
|
maxHP: Math.floor(baseHP * SWARM_CONFIG.hpMultiplier),
|
||||||
armor: SWARM_CONFIG.armorBase + Math.floor(floor / 10) * SWARM_CONFIG.armorPerFloor,
|
armor: SWARM_CONFIG.armorBase + Math.floor(floor / 10) * SWARM_CONFIG.armorPerFloor,
|
||||||
dodgeChance: 0,
|
dodgeChance: 0,
|
||||||
healthRegen: 0, // Will be set by caller if needed
|
barrier: getEnemyBarrier(floor, element),
|
||||||
barrier: 0, // Will be set by caller if needed
|
|
||||||
element,
|
element,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ 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 { 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 { getFloorMaxHP } from './floor-utils';
|
import { getFloorMaxHP } from './floor-utils';
|
||||||
import { getFloorElement } from './floor-utils';
|
import { getFloorElement } from './floor-utils';
|
||||||
import { getEnemyName } from './enemy-utils';
|
import { getEnemyName, generateSwarmEnemies } from './enemy-utils';
|
||||||
|
|
||||||
// Generate room type for a floor
|
// Generate room type for a floor
|
||||||
export function generateRoomType(floor: number): RoomType {
|
export function generateRoomType(floor: number): RoomType {
|
||||||
@@ -79,30 +79,6 @@ export function getEnemyBarrier(floor: number, element: string): number {
|
|||||||
return 0.1 + floorProgress * 0.2;
|
return 0.1 + floorProgress * 0.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate enemies for a swarm room
|
|
||||||
export function generateSwarmEnemies(floor: number): EnemyState[] {
|
|
||||||
const baseHP = getFloorMaxHP(floor);
|
|
||||||
const element = getFloorElement(floor);
|
|
||||||
const numEnemies = SWARM_CONFIG.minEnemies +
|
|
||||||
Math.floor(Math.random() * (SWARM_CONFIG.maxEnemies - SWARM_CONFIG.minEnemies + 1));
|
|
||||||
|
|
||||||
const enemies: EnemyState[] = [];
|
|
||||||
for (let i = 0; i < numEnemies; i++) {
|
|
||||||
const enemyName = getEnemyName(element, floor);
|
|
||||||
enemies.push({
|
|
||||||
id: `enemy_${i}`,
|
|
||||||
name: enemyName,
|
|
||||||
hp: Math.floor(baseHP * SWARM_CONFIG.hpMultiplier),
|
|
||||||
maxHP: Math.floor(baseHP * SWARM_CONFIG.hpMultiplier),
|
|
||||||
armor: SWARM_CONFIG.armorBase + Math.floor(floor / 10) * SWARM_CONFIG.armorPerFloor,
|
|
||||||
dodgeChance: 0,
|
|
||||||
barrier: getEnemyBarrier(floor, element),
|
|
||||||
element,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return enemies;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate initial floor state
|
// Generate initial floor state
|
||||||
export function generateFloorState(floor: number): FloorState {
|
export function generateFloorState(floor: number): FloorState {
|
||||||
const roomType = generateRoomType(floor);
|
const roomType = generateRoomType(floor);
|
||||||
|
|||||||
Reference in New Issue
Block a user