human fight sequence fix

This commit is contained in:
Dorian
2026-03-11 10:34:08 +00:00
parent 29a0a48eb1
commit ea72c097c4
5 changed files with 80 additions and 37 deletions
+30 -7
View File
@@ -47,7 +47,7 @@ const challenge = useHumanChallenge(fightId, myBotId)
const {
humanChallenge, humanAnswer, humanTimer, humanSubmitted, humanChoices,
roundCooldown, pendingChallengeData,
applyChallenge, submitChoice, startHumanPolling, stopHumanPolling,
applyChallenge, submitHumanAnswer, submitChoice, startHumanPolling, stopHumanPolling,
startCooldown, clearChallenge, stopCooldown, resetState: resetChallengeState, handleSSEChallenge,
setEntrancePlaying, animatingRound,
} = challenge
@@ -452,7 +452,7 @@ watch(() => route.params.fightId, async (newId) => {
isLive.value = true
}
if (isLive.value) {
startPolling({ onFinished: () => stopHumanPolling(), onTimeout: () => stopHumanPolling() })
startPolling({ onFinished: () => stopHumanPolling(), onTimeout: () => stopHumanPolling(), keepLive: isHumanFight.value })
wireSSE()
if (isHumanFight.value) {
startHumanPolling()
@@ -523,7 +523,7 @@ onMounted(async () => {
}
if (isLive.value) {
startPolling({ onFinished: () => stopHumanPolling(), onTimeout: () => stopHumanPolling() })
startPolling({ onFinished: () => stopHumanPolling(), onTimeout: () => stopHumanPolling(), keepLive: isHumanFight.value })
if (isHumanFight.value) {
wireSSE()
// Init scene first, then start challenge polling — ensures entrance
@@ -567,7 +567,8 @@ async function fightAgain(botId: string) {
liveHpA.value = 100
liveHpB.value = 100
liveCurrentRound.value = 0
// Stop ALL old polling/connections before starting new fight
// Stop ALL old audio/polling/connections before starting new fight
stopAllAudio()
stopHumanPolling()
stopPolling()
disconnectSSE()
@@ -582,7 +583,7 @@ async function fightAgain(botId: string) {
liveRounds.value = 0
fightError.value = ''
window.history.replaceState({}, '', `/arena/${data.fightId}`)
startPolling({ onFinished: () => stopHumanPolling(), onTimeout: () => stopHumanPolling() })
startPolling({ onFinished: () => stopHumanPolling(), onTimeout: () => stopHumanPolling(), keepLive: isHumanFight.value })
if (isHumanFight.value) {
wireSSE()
for (let i = 0; i < 20; i++) {
@@ -621,6 +622,7 @@ async function matchmake(botId: string) {
liveHpA.value = 100
liveHpB.value = 100
liveCurrentRound.value = 0
stopAllAudio()
stopHumanPolling()
stopPolling()
disconnectSSE()
@@ -634,7 +636,7 @@ async function matchmake(botId: string) {
liveRounds.value = 0
fightError.value = ''
window.history.replaceState({}, '', `/arena/${data.fightId}`)
startPolling({ onFinished: () => stopHumanPolling(), onTimeout: () => stopHumanPolling() })
startPolling({ onFinished: () => stopHumanPolling(), onTimeout: () => stopHumanPolling(), keepLive: isHumanFight.value })
} else {
fightError.value = `Matchmaking failed (${res.status})`
}
@@ -784,7 +786,7 @@ function stopAutoBattle() {
{{ humanChallenge.prompt }}
</p>
<!-- Multiple choice buttons -->
<div class="flex flex-col gap-2">
<div v-if="humanChoices.length > 0" class="flex flex-col gap-2">
<button
v-for="(choice, i) in humanChoices"
:key="i"
@@ -800,6 +802,27 @@ function stopAutoBattle() {
{{ choice }}
</button>
</div>
<!-- Text input for open-ended / creative questions -->
<form v-else @submit.prevent="submitHumanAnswer" class="flex gap-2">
<input
v-model="humanAnswer"
type="text"
class="flex-1 px-3 py-2 bg-black/50 border-2 border-neon-cyan/30 rounded-lg
font-mono text-sm text-text-primary placeholder-text-muted/50
focus:outline-none focus:border-neon-cyan/60"
placeholder="Type your answer..."
autocomplete="off"
/>
<button
type="submit"
:disabled="!humanAnswer.trim()"
class="px-4 py-2 bg-neon-cyan/10 border-2 border-neon-cyan/50 text-neon-cyan
font-display font-bold text-xs tracking-wider rounded-lg
hover:bg-neon-cyan/20 disabled:opacity-30 disabled:cursor-not-allowed transition-all"
>
SEND
</button>
</form>
</div>
<div v-else-if="humanSubmitted" class="text-center py-3">
<p class="font-display text-text-muted text-sm tracking-wider animate-pulse">SCORING ROUND...</p>