refactor: eliminate as any type casts across 18 source files
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m34s

- Fix computeDisciplineEffects() to not require GameState parameter
- Fix getUnifiedEffects() to accept proper partial state type
- Replace upgradeEffects as any with proper UnifiedEffects type
- Replace explicit : any annotations with proper types (ComputedEffects, DesignProgress, SpellDef, etc.)
- Fix activity-log.ts eventType casting
- Fix crafting-design.ts computedEffects and designProgress types
- Fix page.tsx grimoire spell rendering with proper SpellDef property names
- Fix StatsTab ManaStatsSection with proper ManaStatsEffects interface
- Remove unused imports (useDisciplineStore from page.tsx, LeftPanel.tsx)

Remaining: 1 as any in craftingStore.ts (pre-existing CraftingStore/GameState architectural mismatch)
This commit is contained in:
2026-05-20 17:22:52 +02:00
parent df316c2865
commit 742a992d59
36 changed files with 1820 additions and 1460 deletions
+1 -1
View File
@@ -38,7 +38,7 @@ export function processCombatTick(
}
// Compute discipline bonuses once per tick
const disciplineEffects = computeDisciplineEffects(useDisciplineStore.getState() as any);
const disciplineEffects = computeDisciplineEffects();
// Calculate cast speed (no skill bonus)
const totalAttackSpeed = attackSpeedMult;
+2 -1
View File
@@ -2,6 +2,7 @@
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
import type { DesignProgress, EnchantmentDesign, DesignEffect } from '../types';
import type { EquipmentSlot } from '../types/equipmentSlot';
import type { CraftingStore, CraftingState } from './craftingStore.types';
import * as CraftingUtils from '../crafting-utils';
import * as CraftingDesign from '../crafting-design';
@@ -342,7 +343,7 @@ export const useCraftingStore = create<CraftingStore>()(
let newEquipped = { ...state.equippedInstances };
for (const [slot, id] of Object.entries(newEquipped)) {
if (id === instanceId) {
newEquipped[slot as any] = null;
newEquipped[slot as EquipmentSlot] = null;
}
}
+3 -2
View File
@@ -1,4 +1,5 @@
import { computeMaxMana, computeClickMana } from '../utils';
import type { GameCoordinatorState } from './gameStore';
import { useUIStore } from './uiStore';
import { usePrestigeStore } from './prestigeStore';
import { useManaStore } from './manaStore';
@@ -6,7 +7,7 @@ import { useCombatStore } from './combatStore';
import { computeDisciplineEffects } from '../effects/discipline-effects';
import { useDisciplineStore } from './discipline-slice';
export const createResetGame = (set: (state: any) => void, initialState: any) => () => {
export const createResetGame = (set: (state: Partial<GameCoordinatorState>) => void, initialState: GameCoordinatorState) => () => {
// Clear all persisted state
if (typeof window !== 'undefined') {
localStorage.removeItem('mana-loop-ui-storage');
@@ -34,7 +35,7 @@ export const createResetGame = (set: (state: any) => void, initialState: any) =>
export const createGatherMana = () => () => {
const prestigeState = usePrestigeStore.getState();
const disciplineEffects = computeDisciplineEffects(useDisciplineStore.getState() as any);
const disciplineEffects = computeDisciplineEffects();
// Compute click mana with discipline bonuses (mana-channeling → clickManaMultiplier)
const cm = computeClickMana(
+10 -12
View File
@@ -6,7 +6,7 @@ import { useCombatStore } from './combatStore';
import { useUIStore } from './uiStore';
import { useCraftingStore } from './craftingStore';
import { useDisciplineStore } from './discipline-slice';
import { getUnifiedEffects } from '../effects';
import { getUnifiedEffects, type UnifiedEffects } from '../effects';
import { computeDisciplineEffects } from '../effects/discipline-effects';
import {
computeMaxMana,
@@ -32,8 +32,7 @@ export function useGameLoop() {
export function useUnifiedEffects() {
const equippedInstances = useCraftingStore((s) => s.equippedInstances);
const equipmentInstances = useCraftingStore((s) => s.equipmentInstances);
const disciplineStoreState = useDisciplineStore();
const disciplineEffects = computeDisciplineEffects(disciplineStoreState as any);
const disciplineEffects = computeDisciplineEffects();
return {
...getUnifiedEffects({
@@ -56,8 +55,7 @@ export function useManaStats() {
const hour = useGameStore((s) => s.hour);
const equippedInstances = useCraftingStore((s) => s.equippedInstances);
const equipmentInstances = useCraftingStore((s) => s.equipmentInstances);
const disciplineStoreState = useDisciplineStore();
const disciplineEffects = computeDisciplineEffects(disciplineStoreState as any);
const disciplineEffects = computeDisciplineEffects();
const upgradeEffects = getUnifiedEffects({
skillUpgrades: {},
@@ -68,13 +66,13 @@ export function useManaStats() {
const maxMana = computeMaxMana(
{ skills: {}, prestigeUpgrades, skillUpgrades: {}, skillTiers: {} },
upgradeEffects as any,
upgradeEffects,
disciplineEffects,
);
const baseRegen = computeRegen(
{ skills: {}, prestigeUpgrades, skillUpgrades: {}, skillTiers: {}, attunements: {} },
upgradeEffects as any,
upgradeEffects,
disciplineEffects,
);
@@ -82,18 +80,18 @@ export function useManaStats() {
skills: {},
}, disciplineEffects);
const meditationMultiplier = getMeditationBonus(meditateTicks, {}, (upgradeEffects as any).meditationEfficiency);
const meditationMultiplier = getMeditationBonus(meditateTicks, {}, upgradeEffects.meditationEfficiency);
const incursionStrength = getIncursionStrength(day, hour);
const effectiveRegenWithSpecials = baseRegen * (1 - incursionStrength);
// Mana Cascade bonus
const manaCascadeBonus = (upgradeEffects as any).specials.has('mana_cascade')
? Math.floor(maxMana /100) * 0.1
const manaCascadeBonus = upgradeEffects.specials.has('mana_cascade')
? Math.floor(maxMana / 100) * 0.1
: 0;
// Mana Waterfall bonus
const manaWaterfallBonus = (upgradeEffects as any).specials.has('mana_waterfall')
? Math.floor(maxMana /100) * 0.25
const manaWaterfallBonus = upgradeEffects.specials.has('mana_waterfall')
? Math.floor(maxMana / 100) * 0.25
: 0;
const effectiveRegen = (effectiveRegenWithSpecials + manaCascadeBonus + manaWaterfallBonus) * meditationMultiplier;
+3 -2
View File
@@ -1,4 +1,5 @@
import { calcInsight, getFloorMaxHP } from '../utils';
import type { GameCoordinatorState } from './gameStore';
import { makeInitialSpells } from './combatStore';
import { SPELLS_DEF } from '../constants';
import { useUIStore } from './uiStore';
@@ -8,12 +9,12 @@ import { useCombatStore } from './combatStore';
import { computeDisciplineEffects } from '../effects/discipline-effects';
import { useDisciplineStore } from './discipline-slice';
export const createStartNewLoop = (set: (state: any) => void) => () => {
export const createStartNewLoop = (set: (state: Partial<GameCoordinatorState>) => void) => () => {
const prestigeState = usePrestigeStore.getState();
const combatState = useCombatStore.getState();
const manaState = useManaStore.getState();
const disciplineEffects = computeDisciplineEffects(useDisciplineStore.getState() as any);
const disciplineEffects = computeDisciplineEffects();
const insightGained = prestigeState.loopInsight || calcInsight({
maxFloorReached: combatState.maxFloorReached,
totalManaGathered: manaState.totalManaGathered,
+1 -3
View File
@@ -79,15 +79,13 @@ export const useGameStore = create<GameCoordinatorStore>()(
const manaState = useManaStore.getState();
const combatState = useCombatStore.getState();
const craftingState = useCraftingStore.getState();
const disciplineStoreState = useDisciplineStore.getState();
// Compute equipment specials from enchanted gear
const equipmentEffects = computeEquipmentEffects(
craftingState.equipmentInstances || {},
craftingState.equippedInstances || {}
);
// Compute discipline specials from active discipline perks
const disciplineEffects = computeDisciplineEffects(disciplineStoreState as any);
const disciplineEffects = computeDisciplineEffects();
// Merge all specials into a single set for hasSpecial checks
const allSpecials = new Set<string>([
...equipmentEffects.specials,