fix: move BETA badge after green dot in navbar
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
226d242552
commit
df70f5f093
@@ -451,9 +451,13 @@ async function _doReplay() {
|
||||
await sleep(insanityMode.value ? 50 : 300)
|
||||
}
|
||||
|
||||
// Hide human player's typed answers from replay
|
||||
const replayIsAHuman = props.fight.botA?.archetype === 'human'
|
||||
const replayIsBHuman = props.fight.botB?.archetype === 'human'
|
||||
|
||||
// 2. Bot A: ensure audio ready, then show log + bubble + mouth + voice all at once
|
||||
const isCodeRound = isCodeAnswer(round.challengeType, round.botAResponse || '')
|
||||
if (round.botAResponse) {
|
||||
if (round.botAResponse && !replayIsAHuman) {
|
||||
if (doTTS && !isCodeRound) await awaitAnswerReady(props.fight.botA!.name, round.botAResponse)
|
||||
scene?.stopShowboating('a')
|
||||
logItems.value.push({ type: 'responseA', round: round.roundNumber, text: `${props.fight.botA?.name}: ${round.botAResponse || '[NO RESPONSE]'}`, color: 'neon-cyan' })
|
||||
@@ -473,10 +477,13 @@ async function _doReplay() {
|
||||
if (!doTTS && !insanityMode.value) await sleep(400)
|
||||
scene?.stopTalking('a')
|
||||
scene?.hideSpeechBubble('a')
|
||||
} else if (replayIsAHuman) {
|
||||
scene?.stopShowboating('a')
|
||||
await sleep(insanityMode.value ? 50 : 200)
|
||||
}
|
||||
|
||||
// 3. Bot B: ensure audio ready, then show log + bubble + mouth + voice all at once
|
||||
if (round.botBResponse) {
|
||||
if (round.botBResponse && !replayIsBHuman) {
|
||||
if (doTTS && !isCodeRound) await awaitAnswerReady(props.fight.botB!.name, round.botBResponse)
|
||||
scene?.stopShowboating('b')
|
||||
logItems.value.push({ type: 'responseB', round: round.roundNumber, text: `${props.fight.botB?.name}: ${round.botBResponse || '[NO RESPONSE]'}`, color: 'neon-pink' })
|
||||
@@ -497,6 +504,9 @@ async function _doReplay() {
|
||||
if (!doTTS && !insanityMode.value) await sleep(400)
|
||||
scene?.stopTalking('b')
|
||||
scene?.hideSpeechBubble('b')
|
||||
} else if (replayIsBHuman) {
|
||||
scene?.stopShowboating('b')
|
||||
await sleep(insanityMode.value ? 50 : 200)
|
||||
}
|
||||
|
||||
// Stop all showboating before fight animation
|
||||
|
||||
@@ -39,12 +39,12 @@ const bottomNav = [
|
||||
<span class="font-display font-black text-neon-pink text-lg tracking-widest glow-pink">
|
||||
BOTFIGHTS
|
||||
</span>
|
||||
<span class="font-glitch text-[9px] text-neon-cyan/80 tracking-[0.2em] -rotate-12 -ml-1 -mt-2 select-none">BETA</span>
|
||||
<span
|
||||
class="w-2 h-2 rounded-full transition-colors"
|
||||
:class="isOnline ? 'bg-green-400' : 'bg-red-400 animate-pulse'"
|
||||
:title="isOnline ? 'Online' : 'Offline'"
|
||||
/>
|
||||
<span class="font-glitch text-[9px] text-neon-cyan/80 tracking-[0.2em] -rotate-12 -ml-0.5 select-none">BETA</span>
|
||||
</RouterLink>
|
||||
|
||||
<div class="hidden md:flex items-center gap-6">
|
||||
|
||||
@@ -1222,7 +1222,11 @@ export async function createFightScene(config: FightSceneConfig) {
|
||||
stopShowboating(side: 'a' | 'b') { showboatSystem.stopShowboating(side) },
|
||||
|
||||
async playEntrance() {
|
||||
return entranceSystem.playEntrance()
|
||||
// Timeout entrance to prevent hanging on mobile (max 8s)
|
||||
await Promise.race([
|
||||
entranceSystem.playEntrance(),
|
||||
new Promise<void>(r => setTimeout(r, 8000)),
|
||||
])
|
||||
},
|
||||
|
||||
// Physical contact delegates
|
||||
|
||||
@@ -524,21 +524,30 @@ async function playEntrance() {
|
||||
while (idxB === idxA && attempts < 5) { idxB = pickTierEntrance(botB.tier); attempts++ }
|
||||
|
||||
// Play entrances with slight stagger — creator always gets special entrance
|
||||
// Wrap each in try/catch so one failing doesn't prevent the other
|
||||
announceDeepIntro()
|
||||
if (botA.archetype === 'the_creator') {
|
||||
await creatorEntrance(fA, HOME_A, true)
|
||||
} else {
|
||||
await entrances[idxA](fA, HOME_A, true)
|
||||
try {
|
||||
if (botA.archetype === 'the_creator') {
|
||||
await creatorEntrance(fA, HOME_A, true)
|
||||
} else {
|
||||
await entrances[idxA](fA, HOME_A, true)
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('[Entrance] Fighter A entrance failed:', e)
|
||||
}
|
||||
await k.wait(0.3)
|
||||
if (botB.archetype === 'the_creator') {
|
||||
await creatorEntrance(fB, HOME_B, false)
|
||||
} else {
|
||||
await entrances[idxB](fB, HOME_B, false)
|
||||
try {
|
||||
if (botB.archetype === 'the_creator') {
|
||||
await creatorEntrance(fB, HOME_B, false)
|
||||
} else {
|
||||
await entrances[idxB](fB, HOME_B, false)
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('[Entrance] Fighter B entrance failed:', e)
|
||||
}
|
||||
await k.wait(0.2)
|
||||
|
||||
// Safety: ensure both fighters are visible and at home positions
|
||||
// Safety: ALWAYS ensure both fighters are visible and at home positions
|
||||
fA.pos.x = HOME_A
|
||||
fA.pos.y = GROUND_Y - 6
|
||||
fA.opacity = 1
|
||||
@@ -547,8 +556,8 @@ async function playEntrance() {
|
||||
fB.opacity = 1
|
||||
|
||||
// Both idle at home positions
|
||||
fA.play('idle')
|
||||
fB.play('idle')
|
||||
try { fA.play('idle') } catch { /* sprite may not have anim */ }
|
||||
try { fB.play('idle') } catch { /* sprite may not have anim */ }
|
||||
}
|
||||
|
||||
return { playEntrance }
|
||||
|
||||
@@ -248,13 +248,17 @@ async function handleRoundEnd(data: any) {
|
||||
|
||||
const cLabel = currentChallengeInfo.value?.label || challengeLabel(currentChallengeInfo.value?.type || '')
|
||||
|
||||
// Don't show the human player's typed answer in the battle log
|
||||
const isAHuman = myBotId.value === fd.botA.id && isHumanFight.value
|
||||
const isBHuman = myBotId.value === fd.botB.id && isHumanFight.value
|
||||
|
||||
liveLogItems.value.push(
|
||||
{ type: 'header', round, text: `ROUND ${round}: ${cLabel}`, color: 'neon-purple' },
|
||||
)
|
||||
if (result.botAResponse) {
|
||||
if (result.botAResponse && !isAHuman) {
|
||||
liveLogItems.value.push({ type: 'responseA', round, text: `${fd.botA.name}: ${result.botAResponse}`, color: 'neon-cyan' })
|
||||
}
|
||||
if (result.botBResponse) {
|
||||
if (result.botBResponse && !isBHuman) {
|
||||
liveLogItems.value.push({ type: 'responseB', round, text: `${fd.botB.name}: ${result.botBResponse}`, color: 'neon-pink' })
|
||||
}
|
||||
if (result.narration) {
|
||||
@@ -269,8 +273,8 @@ async function handleRoundEnd(data: any) {
|
||||
|
||||
if (liveScene) {
|
||||
fanfareRound(round)
|
||||
if (result.botAResponse) liveScene.showSpeechBubble('a', result.botAResponse, 3)
|
||||
if (result.botBResponse) {
|
||||
if (result.botAResponse && !isAHuman) liveScene.showSpeechBubble('a', result.botAResponse, 3)
|
||||
if (result.botBResponse && !isBHuman) {
|
||||
setTimeout(() => {
|
||||
if (liveScene && result.botBResponse) liveScene.showSpeechBubble('b', result.botBResponse, 2.5)
|
||||
}, 300)
|
||||
|
||||
Reference in New Issue
Block a user