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
+2 -2
View File
@@ -9,7 +9,7 @@ import { ActionButtons } from '@/components/game';
import { AttunementStatus } from '@/components/game/AttunementStatus';
import { ActivityLogPanel } from '@/components/game/ActivityLogPanel';
import { DebugName } from '@/components/game/debug/debug-context';
import { useGameStore, useManaStore, useCombatStore, useCraftingStore, usePrestigeStore, useDisciplineStore } from '@/lib/game/stores';
import { useGameStore, useManaStore, useCombatStore, useCraftingStore, usePrestigeStore } from '@/lib/game/stores';
import { computeDisciplineEffects } from '@/lib/game/effects/discipline-effects';
import { getUnifiedEffects } from '@/lib/game/effects';
import { getMeditationBonus, getIncursionStrength } from '@/lib/game/stores';
@@ -57,7 +57,7 @@ export function LeftPanel() {
const maxMana = computeTotalMaxMana({ skills: {}, prestigeUpgrades, skillUpgrades: {}, skillTiers: {}, equippedInstances, equipmentInstances }, upgradeEffects);
const baseRegen = computeTotalRegen({ skills: {}, prestigeUpgrades, skillUpgrades: {}, skillTiers: {}, equippedInstances, equipmentInstances }, upgradeEffects);
const clickMana = computeTotalClickMana({ skills: {}, skillUpgrades: {}, skillTiers: {}, equippedInstances, equipmentInstances }, upgradeEffects);
const meditationMultiplier = getMeditationBonus(meditateTicks, {}, (upgradeEffects as any).meditationEfficiency);
const meditationMultiplier = getMeditationBonus(meditateTicks, {}, upgradeEffects.meditationEfficiency);
const incursionStrength = getIncursionStrength(useGameStore((s) => s.day), useGameStore((s) => s.hour));
const effectiveRegen = baseRegen * (1 - incursionStrength) * meditationMultiplier;
+16 -17
View File
@@ -11,7 +11,6 @@ import {
useCombatStore,
usePrestigeStore,
useCraftingStore,
useDisciplineStore,
fmt,
computeMaxMana,
computeRegen,
@@ -21,10 +20,11 @@ import {
} from '@/lib/game/stores';
import { computeDisciplineEffects } from '@/lib/game/effects/discipline-effects';
import { useGameLoop } from '@/lib/game/stores/gameHooks';
import { getUnifiedEffects } from '@/lib/game/effects';
import { getUnifiedEffects, type UnifiedEffects } from '@/lib/game/effects';
import { SPELLS_DEF } from '@/lib/game/constants';
import { TimeDisplay } from '@/components/game';
import { hasSpecial, SPECIAL_EFFECTS } from '@/lib/game/effects';
import type { SpellDef } from '@/lib/game/types';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
@@ -62,9 +62,9 @@ const TabLoadingFallback = () => <div className="p-4 text-center text-gray-400">
// ============================================================================
function GrimoireTab() {
const [grimoireSpells, setGrimoireSpells] = useState<any[]>(() => {
const [grimoireSpells, setGrimoireSpells] = useState<[string, SpellDef][]>(() => {
if (typeof window !== 'undefined' && SPELLS_DEF) {
return Object.values(SPELLS_DEF).filter((s: any) => s.grimoire);
return Object.entries(SPELLS_DEF).filter((entry): entry is [string, SpellDef] => !!entry[1].grimoire);
}
return [];
});
@@ -94,26 +94,26 @@ function GrimoireTab() {
<ScrollArea className="h-[600px] rounded border border-gray-700 p-4">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{grimoireSpells.map((spell: any) => (
{grimoireSpells.map(([id, spell]) => (
<div
key={spell.id}
key={id}
className="p-4 bg-gray-800/50 rounded border border-gray-600 hover:border-gray-500 transition-colors"
>
<div className="flex items-start justify-between mb-2">
<span className="font-bold text-gray-100">{spell.name}</span>
<Badge variant="outline" className="border-gray-600">
{spell.element}
{spell.elem}
</Badge>
</div>
<p className="text-sm text-gray-400 mb-3">{spell.desc}</p>
{spell.desc && <p className="text-sm text-gray-400 mb-3">{spell.desc}</p>}
<div className="text-xs text-gray-500 space-y-1">
<div>Cost: {spell.cost.amount} {
spell.cost.type === 'element'
? spell.cost.element
: 'raw mana'
}</div>
<div>Power: {spell.power}</div>
{spell.effect && <div>Effect: {spell.effect}</div>}
<div>Power: {spell.dmg}</div>
{spell.effects && spell.effects.length > 0 && <div>Effects: {spell.effects.map(e => e.type).join(', ')}</div>}
</div>
</div>
))}
@@ -155,15 +155,14 @@ export default function ManaLoopGame() {
});
// Compute discipline bonuses from active disciplines
const disciplineStoreState = useDisciplineStore();
const disciplineEffects = computeDisciplineEffects(disciplineStoreState as any);
const disciplineEffects = computeDisciplineEffects();
const maxMana = computeMaxMana({
skills: {},
prestigeUpgrades,
skillUpgrades: {},
skillTiers: {}
}, upgradeEffects as any, disciplineEffects);
}, upgradeEffects, disciplineEffects);
const baseRegen = computeRegen({
skills: {},
@@ -171,25 +170,25 @@ export default function ManaLoopGame() {
skillUpgrades: {},
skillTiers: {},
attunements: {},
}, upgradeEffects as any, disciplineEffects);
}, upgradeEffects, disciplineEffects);
const clickMana = computeClickMana({
skills: {},
}, disciplineEffects);
const meditationMultiplier = getMeditationBonus(meditateTicks, {}, (upgradeEffects as any).meditationEfficiency);
const meditationMultiplier = getMeditationBonus(meditateTicks, {}, upgradeEffects.meditationEfficiency);
const incursionStrength = getIncursionStrength(day, hour);
// Effective regen with incursion penalty
const effectiveRegenWithSpecials = baseRegen * (1 - incursionStrength);
// Mana Cascade bonus
const manaCascadeBonus = hasSpecial(upgradeEffects as any, SPECIAL_EFFECTS.MANA_CASCADE)
const manaCascadeBonus = hasSpecial(upgradeEffects, SPECIAL_EFFECTS.MANA_CASCADE)
? Math.floor(maxMana / 100) * 0.1
: 0;
// Mana Waterfall bonus
const manaWaterfallBonus = hasSpecial(upgradeEffects as any, SPECIAL_EFFECTS.MANA_WATERFALL)
const manaWaterfallBonus = hasSpecial(upgradeEffects, SPECIAL_EFFECTS.MANA_WATERFALL)
? Math.floor(maxMana / 100) * 0.25
: 0;