feat: remove mock fight button for production, cleanup fight UI
- Remove "Fight a Classic Bot" button (mock endpoints blocked in prod) - Simplify speech bubble rendering (remove glow/accent layers) - Sound and FightViewer improvements - BotProfilePage enhancements Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
bb9a966d4e
commit
56785cfdea
@@ -7,6 +7,7 @@ import {
|
||||
announceFinishHim, announceFlawlessVictory,
|
||||
sfxCrowdCheer, sfxCrowdGasp, sfxCrowdOoh, sfxApplause, sfxDrumRoll,
|
||||
setMusicIntensity, stopAllAudio,
|
||||
setMasterMute, isMasterMuted, ensureAudioContext,
|
||||
} from '../game/sounds'
|
||||
|
||||
interface Round {
|
||||
@@ -60,6 +61,13 @@ const hitTextColor = ref('#ff2d2d')
|
||||
const hitTextX = ref(50)
|
||||
const hitTextY = ref(30)
|
||||
const glitching = ref(false)
|
||||
const soundOn = ref(true)
|
||||
|
||||
function toggleSound() {
|
||||
soundOn.value = !soundOn.value
|
||||
ensureAudioContext()
|
||||
setMasterMute(!soundOn.value)
|
||||
}
|
||||
|
||||
// Staggered log
|
||||
const logItems = ref<{ type: string; round: number; text: string; color: string }[]>([])
|
||||
@@ -201,7 +209,10 @@ async function replay() {
|
||||
currentRound.value = 0
|
||||
|
||||
await initScene()
|
||||
scene?.startMusic()
|
||||
if (soundOn.value) {
|
||||
ensureAudioContext()
|
||||
scene?.startMusic()
|
||||
}
|
||||
await sleep(300)
|
||||
|
||||
// Deep movie trailer intro
|
||||
@@ -230,11 +241,20 @@ async function replay() {
|
||||
await showOverlay(challengeLabel(round.challengeType), '#b83dff', 600)
|
||||
await sleep(80)
|
||||
fanfareFight()
|
||||
announceRoundHype()
|
||||
sfxCrowdCheer()
|
||||
await showOverlay('FIGHT!', '#ff2d7b', 400)
|
||||
await sleep(80)
|
||||
|
||||
// Show speech bubbles BEFORE the fight animation so viewers see what bots said
|
||||
if (scene) {
|
||||
if (round.botAResponse) scene.showSpeechBubble('a', round.botAResponse.slice(0, 60), 3.5)
|
||||
if (round.botBResponse) {
|
||||
setTimeout(() => {
|
||||
if (scene && round.botBResponse) scene.showSpeechBubble('b', round.botBResponse.slice(0, 60), 3.2)
|
||||
}, 400)
|
||||
}
|
||||
}
|
||||
await sleep(300)
|
||||
|
||||
// Log + fight animation in parallel
|
||||
const logPromise = addRoundToLog(round, true)
|
||||
const isCritical = Math.abs((round.botAScore || 0) - (round.botBScore || 0)) > 4
|
||||
@@ -257,16 +277,7 @@ async function replay() {
|
||||
console.error(`[FightViewer] playRound ${round.roundNumber} error:`, err)
|
||||
}
|
||||
|
||||
// Speech bubbles showing bot responses
|
||||
if (scene) {
|
||||
if (round.botAResponse) scene.showSpeechBubble('a', round.botAResponse.slice(0, 100), 2.8)
|
||||
// Stagger bot B slightly so they don't pop in at the exact same time
|
||||
setTimeout(() => {
|
||||
if (scene && round.botBResponse) scene.showSpeechBubble('b', round.botBResponse.slice(0, 100), 2.5)
|
||||
}, 300)
|
||||
}
|
||||
|
||||
// Hit text overlay
|
||||
// Hit text overlay — after playRound completes so it lands on the result
|
||||
const hitWords = isCritical
|
||||
? ['CRITICAL!', 'DEVASTATING!', 'OBLITERATED!', 'ANNIHILATED!', 'WRECKED!']
|
||||
: ['POW!', 'BAM!', 'WHAM!', 'CRACK!', 'SMASH!', 'BOOM!', 'THWACK!']
|
||||
@@ -276,17 +287,6 @@ async function replay() {
|
||||
isCritical ? '#ffe14d' : '#ff2d2d',
|
||||
aWon ? 65 : 35,
|
||||
)
|
||||
// Crowd reactions
|
||||
if (isCritical) {
|
||||
sfxCrowdGasp()
|
||||
setTimeout(() => sfxCrowdOoh(), 400)
|
||||
} else if (Math.random() < 0.4) {
|
||||
sfxCrowdOoh()
|
||||
}
|
||||
// Random hype voiceover on big moments
|
||||
if (isCritical || Math.random() < 0.3) {
|
||||
setTimeout(() => announceRandomHype(), 300)
|
||||
}
|
||||
}
|
||||
|
||||
await logPromise
|
||||
@@ -529,6 +529,19 @@ async function replay() {
|
||||
>
|
||||
{{ isReplaying ? 'FIGHTING...' : 'REPLAY FIGHT' }}
|
||||
</button>
|
||||
<button
|
||||
class="w-8 h-8 flex items-center justify-center border border-border/50 text-text-muted
|
||||
hover:text-neon-cyan hover:border-neon-cyan/50 transition-all"
|
||||
:title="soundOn ? 'Mute' : 'Unmute'"
|
||||
@click="toggleSound"
|
||||
>
|
||||
<svg v-if="soundOn" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="w-4 h-4">
|
||||
<path d="M11 5L6 9H2v6h4l5 4V5z"/><path d="M19.07 4.93a10 10 0 010 14.14M15.54 8.46a5 5 0 010 7.07"/>
|
||||
</svg>
|
||||
<svg v-else xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="w-4 h-4">
|
||||
<path d="M11 5L6 9H2v6h4l5 4V5z"/><line x1="23" y1="9" x2="17" y2="15"/><line x1="17" y1="9" x2="23" y2="15"/>
|
||||
</svg>
|
||||
</button>
|
||||
<span class="font-pixel text-[10px] text-text-muted">{{ fight.status === 'finished' ? 'FINISHED' : fight.status.toUpperCase() }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user