From 38d7236be3da3c113ee1b0f566acea8dadced303 Mon Sep 17 00:00:00 2001 From: Dorian Date: Mon, 9 Mar 2026 06:29:09 +0000 Subject: [PATCH] refactor: eliminate more any types in FightScene, FightViewer, FightPage Replace any[] with GameObj[], fighter: any with Fighter in speech bubbles, talking anims, showboat system, bow/fistbump/helpup, and dizzy stars. Fix customization as any casts with ?? undefined. Co-Authored-By: Claude Opus 4.6 --- frontend/src/components/FightViewer.vue | 4 ++-- frontend/src/game/FightScene.ts | 24 ++++++++++++------------ frontend/src/pages/FightPage.vue | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/frontend/src/components/FightViewer.vue b/frontend/src/components/FightViewer.vue index e736262..19ccfd9 100644 --- a/frontend/src/components/FightViewer.vue +++ b/frontend/src/components/FightViewer.vue @@ -201,8 +201,8 @@ async function initScene() { try { const scenePromise = createFightScene({ canvas: newCanvas, - botA: { name: props.fight.botA.name, seed: props.fight.botA.avatarSeed || props.fight.botA.name, tier: props.fight.botA.tier, archetype: props.fight.botA.archetype, customization: props.fight.botA.customization as any, wins: props.fight.botA.wins, losses: props.fight.botA.losses }, - botB: { name: props.fight.botB.name, seed: props.fight.botB.avatarSeed || props.fight.botB.name, tier: props.fight.botB.tier, archetype: props.fight.botB.archetype, customization: props.fight.botB.customization as any, wins: props.fight.botB.wins, losses: props.fight.botB.losses }, + botA: { name: props.fight.botA.name, seed: props.fight.botA.avatarSeed || props.fight.botA.name, tier: props.fight.botA.tier, archetype: props.fight.botA.archetype, customization: props.fight.botA.customization ?? undefined, wins: props.fight.botA.wins, losses: props.fight.botA.losses }, + botB: { name: props.fight.botB.name, seed: props.fight.botB.avatarSeed || props.fight.botB.name, tier: props.fight.botB.tier, archetype: props.fight.botB.archetype, customization: props.fight.botB.customization ?? undefined, wins: props.fight.botB.wins, losses: props.fight.botB.losses }, arena: props.fight.arena, }) const timeout = new Promise((resolve) => setTimeout(() => resolve(null), 10_000)) diff --git a/frontend/src/game/FightScene.ts b/frontend/src/game/FightScene.ts index 6d02aa9..4643e24 100644 --- a/frontend/src/game/FightScene.ts +++ b/frontend/src/game/FightScene.ts @@ -1934,10 +1934,10 @@ export async function createFightScene(config: FightSceneConfig) { // Speech bubble above a fighter — colourful with tail // Active speech bubbles — destroy previous before showing new - let activeBubbleA: any[] = [] - let activeBubbleB: any[] = [] + let activeBubbleA: GameObj[] = [] + let activeBubbleB: GameObj[] = [] - function destroyBubble(els: any[]) { + function destroyBubble(els: GameObj[]) { els.forEach(el => { if (el.exists()) el.destroy() }) els.length = 0 } @@ -1950,7 +1950,7 @@ export async function createFightScene(config: FightSceneConfig) { if (side === 'a') destroyBubble(activeBubbleA) else destroyBubble(activeBubbleB) - const allEls: any[] = [] + const allEls: GameObj[] = [] // Sanitize and truncate const clean = safeText(text) @@ -2092,7 +2092,7 @@ export async function createFightScene(config: FightSceneConfig) { } // Talking mouth animation — a small rectangle that opens/closes near the fighter's face - const talkingAnims: Record }> = {} + const talkingAnims: Record }> = {} function startTalking(side: 'a' | 'b') { stopTalking(side) // cleanup any existing @@ -2333,7 +2333,7 @@ export async function createFightScene(config: FightSceneConfig) { } // Respectful bow animation - async function playBow(fighter: any) { + async function playBow(fighter: Fighter) { const origScaleY = fighter.scale.y await k.tween(fighter.scale.y, origScaleY * 0.85, 0.2, (v) => { fighter.scale.y = v }, k.easings.easeOutQuad) await k.wait(0.3) @@ -2341,7 +2341,7 @@ export async function createFightScene(config: FightSceneConfig) { } // Fist bump between two fighters - async function playFistBump(fighterA: any, fighterB: any) { + async function playFistBump(fighterA: Fighter, fighterB: Fighter) { const midX = (fighterA.pos.x + fighterB.pos.x) / 2 const origAX = fighterA.pos.x const origBX = fighterB.pos.x @@ -2361,7 +2361,7 @@ export async function createFightScene(config: FightSceneConfig) { } // Winner helps loser back up - async function playHelpUp(winner: any, loser: any, winningSide: 'a' | 'b') { + async function playHelpUp(winner: Fighter, loser: Fighter, winningSide: 'a' | 'b') { const dir = winningSide === 'a' ? 1 : -1 const origWX = winner.pos.x await k.tween(winner.pos.x, loser.pos.x - dir * 30, 0.4, (v) => { winner.pos.x = v }, k.easings.easeInOutQuad) @@ -2503,7 +2503,7 @@ export async function createFightScene(config: FightSceneConfig) { // Fighters perform these during question/answer phases instead of boring idle bobbing const _showboatActive: Record = { a: false, b: false } - type ShowboatFn = (fighter: any, homeX: number, homeY: number, sx: number, sy: number, dir: number) => Promise + type ShowboatFn = (fighter: Fighter, homeX: number, homeY: number, sx: number, sy: number, dir: number) => Promise // dir: 1 = facing right (bot A), -1 = facing left (bot B) const showboats: ShowboatFn[] = [ @@ -3039,7 +3039,7 @@ export async function createFightScene(config: FightSceneConfig) { k.tween(f.pos.y, hy - 60, 0.2, (v) => { f.pos.y = v }, k.easings.easeOutQuad), ]) // Spawn orbiting ₿ - const orbs: any[] = [] + const orbs: GameObj[] = [] for (let i = 0; i < 8; i++) { const orb = k.add([k.text('₿', { size: 8 + Math.random() * 6 }), k.pos(center, f.pos.y), k.color(safeColor(k, i % 2 === 0 ? '#ffd700' : '#ff8c00')), k.opacity(0.8), k.z(15), k.anchor('center')]) orbs.push(orb) @@ -3347,7 +3347,7 @@ export async function createFightScene(config: FightSceneConfig) { // Creator uses magical showboats 60% of the time, normal 40% const pool = isCreator ? [...showboats, ...creatorShowboats, ...creatorShowboats] : showboats while (_showboatActive[side]) { - const f = k.get(tag)[0] + const f = k.get(tag)[0] as Fighter | undefined if (!f) break const sx = f.scale.x const sy = f.scale.y @@ -3416,7 +3416,7 @@ export async function createFightScene(config: FightSceneConfig) { }, // Physical contact delegates - _spawnDizzyStars(fighter: any, duration: number) { return roundSystem._spawnDizzyStars(fighter, duration) }, + _spawnDizzyStars(fighter: Fighter, duration: number) { return roundSystem._spawnDizzyStars(fighter, duration) }, _resetPositions() { return roundSystem._resetPositions() }, _brawlRapid(winningSide: 'a' | 'b' | null, intensity: number) { return roundSystem._brawlRapid(winningSide, intensity) }, _brawlKnockdown(winningSide: 'a' | 'b' | null, intensity: number) { return roundSystem._brawlKnockdown(winningSide, intensity) }, diff --git a/frontend/src/pages/FightPage.vue b/frontend/src/pages/FightPage.vue index edb0591..6e7ca59 100644 --- a/frontend/src/pages/FightPage.vue +++ b/frontend/src/pages/FightPage.vue @@ -566,7 +566,7 @@ async function watchAnotherFight() { const res = await fetch('/api/fights') if (res.ok) { const fights = await res.json() - const finished = fights.filter((f: any) => f.status === 'finished' && f.id !== fightId.value) + const finished = fights.filter((f: { status: string; id: string }) => f.status === 'finished' && f.id !== fightId.value) if (finished.length > 0) { const pick = finished[Math.floor(Math.random() * finished.length)] router.push(`/arena/${pick.id}`)