refactor: eliminate as any type casts across 18 source files
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 1m34s
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:
@@ -5,7 +5,7 @@ import { GameCard } from '@/components/ui/game-card';
|
||||
import { Separator } from '@/components/ui/separator';
|
||||
import { EQUIPMENT_TYPES } from '@/lib/game/data/equipment';
|
||||
import { ENCHANTMENT_EFFECTS } from '@/lib/game/data/enchantment-effects';
|
||||
import type { EquipmentInstance, EnchantmentDesign, DesignEffect, EquipmentCraftingProgress } from '@/lib/game/types';
|
||||
import type { EquipmentInstance, EnchantmentDesign, DesignEffect, EquipmentCraftingProgress, EquipmentCategory } from '@/lib/game/types';
|
||||
import type { EnchantmentDesignerProps } from './EnchantmentDesigner/types';
|
||||
import { EquipmentTypeSelector } from './EnchantmentDesigner/EquipmentTypeSelector';
|
||||
import { EffectSelector } from './EnchantmentDesigner/EffectSelector';
|
||||
@@ -85,7 +85,7 @@ export function EnchantmentDesigner({
|
||||
const ownedEquipmentTypes = getOwnedEquipmentTypes(equipmentInstances);
|
||||
|
||||
// Get the reason why an effect is incompatible
|
||||
const getIncompatibilityReasonWrapper = (effect: { id: string; name: string; description: string; allowedEquipmentCategories: any[] }) => {
|
||||
const getIncompatibilityReasonWrapper = (effect: { id: string; name: string; description: string; allowedEquipmentCategories: EquipmentCategory[] }) => {
|
||||
return getIncompatibilityReason(effect, selectedEquipmentType);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import type { FloorState, EnemyState } from '@/lib/game/types';
|
||||
import type { FloorState, EnemyState, RoomType } from '@/lib/game/types';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Progress } from '@/components/ui/progress';
|
||||
@@ -73,14 +73,14 @@ function EnemyRow({ enemy, floor }: { enemy: EnemyState; floor: number }) {
|
||||
}
|
||||
|
||||
export function RoomDisplay({ floorState, floor }: RoomDisplayProps) {
|
||||
const roomDisplay = getSpireRoomTypeDisplay(floorState.roomType as any);
|
||||
const roomDisplay = getSpireRoomTypeDisplay(floorState.roomType as RoomType);
|
||||
|
||||
// Handle special room types (cast to string for extended types)
|
||||
const rt = floorState.roomType as string;
|
||||
|
||||
if (rt === 'recovery') {
|
||||
const progress = (floorState as any).puzzleProgress || 0;
|
||||
const required = (floorState as any).puzzleRequired || 1;
|
||||
const progress = floorState.puzzleProgress || 0;
|
||||
const required = floorState.puzzleRequired || 1;
|
||||
return (
|
||||
<Card className="bg-gray-900/80 border-green-800/40">
|
||||
<CardHeader className="pb-2">
|
||||
|
||||
@@ -78,8 +78,7 @@ export function SpireCombatPage() {
|
||||
const equipmentInstances = useCraftingStore((s) => s.equipmentInstances);
|
||||
|
||||
// Discipline effects
|
||||
const disciplineStoreState = useDisciplineStore();
|
||||
const disciplineEffects = computeDisciplineEffects(disciplineStoreState as any);
|
||||
const disciplineEffects = computeDisciplineEffects();
|
||||
|
||||
// Compute derived stats
|
||||
const upgradeEffects = getUnifiedEffects({
|
||||
@@ -94,7 +93,7 @@ export function SpireCombatPage() {
|
||||
prestigeUpgrades,
|
||||
skillUpgrades: {},
|
||||
skillTiers: {},
|
||||
}, upgradeEffects as any, disciplineEffects);
|
||||
}, upgradeEffects, disciplineEffects);
|
||||
|
||||
const baseRegen = computeRegen({
|
||||
skills: {},
|
||||
@@ -102,7 +101,7 @@ export function SpireCombatPage() {
|
||||
skillUpgrades: {},
|
||||
skillTiers: {},
|
||||
attunements: {},
|
||||
}, upgradeEffects as any, disciplineEffects);
|
||||
}, upgradeEffects, disciplineEffects);
|
||||
|
||||
// Total rooms for current floor
|
||||
const totalRooms = useMemo(() => getRoomsForFloor(currentFloor), [currentFloor]);
|
||||
|
||||
@@ -28,7 +28,19 @@ export function StatsTab() {
|
||||
effectiveRegen={manaStats.effectiveRegen}
|
||||
clickMana={manaStats.clickMana}
|
||||
meditationMultiplier={manaStats.meditationMultiplier}
|
||||
upgradeEffects={manaStats.upgradeEffects}
|
||||
upgradeEffects={{
|
||||
...manaStats.upgradeEffects,
|
||||
incursionStrength: manaStats.incursionStrength,
|
||||
rawMana: manaStats.maxMana,
|
||||
hasSteadyStream: manaStats.hasSteadyStream,
|
||||
hasManaTorrent: manaStats.hasManaTorrent,
|
||||
hasDesperateWells: manaStats.hasDesperateWells,
|
||||
manaCascadeBonus: manaStats.manaCascadeBonus,
|
||||
manaWaterfallBonus: manaStats.manaWaterfallBonus,
|
||||
hasFlowSurge: manaStats.hasFlowSurge,
|
||||
hasManaOverflow: manaStats.hasManaOverflow,
|
||||
hasEternalFlow: manaStats.hasEternalFlow,
|
||||
}}
|
||||
elemMax={elemMax}
|
||||
/>
|
||||
<CombatStatsSection
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Swords } from 'lucide-react';
|
||||
import { fmt, fmtDec } from '@/lib/game/stores';
|
||||
import type { SpellDef } from '@/lib/game/types';
|
||||
|
||||
interface CombatStatsSectionProps {
|
||||
activeSpellDef: any;
|
||||
activeSpellDef: SpellDef | null;
|
||||
pactMultiplier: number;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import { FlaskConical } from 'lucide-react';
|
||||
import { ELEMENTS } from '@/lib/game/constants';
|
||||
import { fmt, fmtDec } from '@/lib/game/stores';
|
||||
import { usePrestigeStore, useManaStore } from '@/lib/game/stores';
|
||||
import type { ElementState } from '@/lib/game/types';
|
||||
|
||||
interface ElementStatsSectionProps {
|
||||
elemMax: number;
|
||||
@@ -38,16 +39,16 @@ export function ElementStatsSection({ elemMax }: ElementStatsSectionProps) {
|
||||
<div className="space-y-2">
|
||||
<div className="flex justify-between text-sm">
|
||||
<span style={{ color: 'var(--text-muted)' }}>Unlocked Elements:</span>
|
||||
<span style={{ color: 'var(--color-success)' }}>{Object.values(elements || {}).filter((e: any) => e.unlocked).length} / {Object.keys(ELEMENTS).length}</span>
|
||||
<span style={{ color: 'var(--color-success)' }}>{Object.values(elements || {}).filter((e: ElementState) => e.unlocked).length} / {Object.keys(ELEMENTS).length}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Separator className="bg-[var(--border-subtle)] my-3" />
|
||||
<div className="text-xs" style={{ color: 'var(--text-muted)' }}>Elemental Mana Pools:</div>
|
||||
<div className="grid grid-cols-4 sm:grid-cols-6 md:grid-cols-8 gap-2">
|
||||
{Object.entries(elements)
|
||||
.filter(([, state]: [string, any]) => state.unlocked)
|
||||
.map(([id, state]: [string, any]) => {
|
||||
{Object.entries(elements || {})
|
||||
.filter((entry): entry is [string, ElementState] => entry[1].unlocked)
|
||||
.map(([id, state]) => {
|
||||
const def = ELEMENTS[id];
|
||||
return (
|
||||
<div key={id} className="p-2 rounded transition-colors" style={{ border: `1px solid ${def?.color}30`, background: 'var(--bg-sunken)/50', textAlign: 'center' }}>
|
||||
|
||||
@@ -5,6 +5,7 @@ import { Separator } from '@/components/ui/separator';
|
||||
import { RotateCcw } from 'lucide-react';
|
||||
import { fmt } from '@/lib/game/stores';
|
||||
import { useCombatStore, usePrestigeStore, useManaStore } from '@/lib/game/stores';
|
||||
import type { SpellState } from '@/lib/game/types';
|
||||
|
||||
export function LoopStatsSection() {
|
||||
const spells = useCombatStore((s) => s.spells);
|
||||
@@ -15,7 +16,7 @@ export function LoopStatsSection() {
|
||||
const loopCount = usePrestigeStore((s) => s.loopCount);
|
||||
const memorySlots = usePrestigeStore((s) => s.memorySlots);
|
||||
|
||||
const spellsLearned = Object.values(spells || {}).filter((s: any) => s.learned).length;
|
||||
const spellsLearned = Object.values(spells || {}).filter((s: SpellState) => s.learned).length;
|
||||
|
||||
return (
|
||||
<Card className="bg-[var(--bg-panel)] border-[var(--border-subtle)]">
|
||||
|
||||
@@ -3,6 +3,20 @@
|
||||
import { fmt, fmtDec } from '@/lib/game/stores';
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Droplet } from 'lucide-react';
|
||||
import type { ComputedEffects } from '@/lib/game/effects/upgrade-effects.types';
|
||||
|
||||
interface ManaStatsEffects extends ComputedEffects {
|
||||
incursionStrength: number;
|
||||
rawMana: number;
|
||||
hasSteadyStream: boolean;
|
||||
hasManaTorrent: boolean;
|
||||
hasDesperateWells: boolean;
|
||||
manaCascadeBonus: number;
|
||||
manaWaterfallBonus: number;
|
||||
hasFlowSurge: boolean;
|
||||
hasManaOverflow: boolean;
|
||||
hasEternalFlow: boolean;
|
||||
}
|
||||
|
||||
interface ManaStatsSectionProps {
|
||||
maxMana: number;
|
||||
@@ -10,7 +24,7 @@ interface ManaStatsSectionProps {
|
||||
effectiveRegen: number;
|
||||
clickMana: number;
|
||||
meditationMultiplier: number;
|
||||
upgradeEffects: any;
|
||||
upgradeEffects: ManaStatsEffects;
|
||||
elemMax: number;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user