diff --git a/www/html/Game/public/js/play.js b/www/html/Game/public/js/play.js index b23c27c..3d3e327 100644 --- a/www/html/Game/public/js/play.js +++ b/www/html/Game/public/js/play.js @@ -4726,21 +4726,29 @@ gauntletCrownHowtoVisible = true; ov.classList.remove('is-hidden'); const st = document.getElementById('gauntlet-crown-howto-status'); - if (st) { - st.textContent = ''; - st.classList.remove('gch-status--jumper'); - st.classList.add('is-hidden'); - } + if (st) st.classList.remove('gch-status--jumper'); const btn = document.getElementById('btn-gch-ready'); - if (btn) { - const humans = quizCarryPregameHumanIds(); - const soleHuman = humans.length === 1; - const canGo = soleHuman || isMePlayHost(); - btn.classList.remove('is-start-phase'); - btn.classList.toggle('is-read-only', !canGo); - btn.disabled = !canGo; - btn.title = canGo ? 'READY — เริ่มนับถอยหลัง' : 'รอโฮสต์ · Wait for host'; - btn.setAttribute('aria-pressed', 'false'); + const humans = quizCarryPregameHumanIds(); + const totPlayers = Math.max(1, quizCarryPregameTotalPlayers()); + /** ผู้เล่นจริงในห้องคนเดียว และไม่มีบอท/peer อื่นในนับรวม — เท่านั้นที่ข้าม lobby */ + const soleParticipant = totPlayers === 1; + if (soleParticipant) { + if (st) { + st.textContent = ''; + st.classList.add('is-hidden'); + } + if (btn) { + const canGo = isMePlayHost() || humans.length === 1; + btn.classList.remove('is-start-phase'); + btn.classList.toggle('is-read-only', !canGo); + btn.disabled = !canGo; + btn.title = canGo ? 'READY — เริ่มนับถอยหลัง' : 'รอโฮสต์ · Wait for host'; + btn.setAttribute('aria-pressed', 'false'); + } + } else { + if (socket && socket.connected) socket.emit('gauntlet-crown-lobby-sync-request'); + gauntletCrownSyncGuestReadyIfNeeded(); + updateQuizQuestionMissionHowtoHud(); } } @@ -8117,7 +8125,8 @@ } function gauntletCrownSyncGuestReadyIfNeeded() { - if (gauntletCrownPregamePhase !== 'howto') return; + const inQuizQuestionHowto = isQuizQuestionMissionUiMapPlay() && quizQuestionMissionPhase === 'howto'; + if (gauntletCrownPregamePhase !== 'howto' && !inQuizQuestionHowto) return; if (myId == null || isMePlayHost()) return; const sid = String(myId); if (gauntletCrownLobbyReadyMap[sid]) return; @@ -8125,6 +8134,27 @@ if (socket && socket.connected) socket.emit('gauntlet-crown-lobby-ready', { ready: true }); } + /** ภารกิจคำถาม mng8a80o — Ready Status / ปุ่ม แบบเดียวกับ Mega Virus (gauntlet-crown-lobby-sync) */ + function updateQuizQuestionMissionHowtoHud() { + if (!isQuizQuestionMissionUiMapPlay() || quizQuestionMissionPhase !== 'howto') return; + const st = document.getElementById('gauntlet-crown-howto-status'); + const btn = document.getElementById('btn-gch-ready'); + if (!st || !btn) return; + const humans = quizCarryPregameHumanIds(); + const tot = Math.max(1, quizCarryPregameTotalPlayers()); + const num = gauntletCrownPregameReadyNumerator(); + st.classList.remove('is-hidden'); + st.textContent = 'Ready Status : ' + num + '/' + tot; + const humansReady = humans.length > 0 && humans.every((id) => !!gauntletCrownLobbyReadyMap[id]); + btn.classList.toggle('is-start-phase', humansReady); + btn.classList.toggle('is-read-only', !isMePlayHost()); + btn.disabled = !isMePlayHost(); + btn.setAttribute('aria-pressed', humansReady ? 'false' : ((myId && gauntletCrownLobbyReadyMap[String(myId)]) ? 'true' : 'false')); + btn.title = isMePlayHost() + ? (humansReady ? 'START' : ((myId && gauntletCrownLobbyReadyMap[String(myId)]) ? 'ยกเลิก READY' : 'READY')) + : (humansReady ? 'START (โฮสต์เท่านั้น)' : 'READY (โฮสต์เท่านั้น)'); + } + function updateGauntletCrownHowtoHud() { const st = document.getElementById('gauntlet-crown-howto-status'); const btn = document.getElementById('btn-gch-ready'); @@ -11628,10 +11658,12 @@ }); if (previewFillBots) rebalancePreviewBots(); if (quizCarryPregameActive && isQuizCarry()) updateQuizCarryPregameHud(); + if (isQuizQuestionMissionUiMapPlay() && quizQuestionMissionPhase === 'howto') updateQuizQuestionMissionHowtoHud(); }); socket.on('host-changed', (d) => { if (d && d.hostId != null) playHostId = d.hostId; if (quizCarryPregameActive && isQuizCarry()) updateQuizCarryPregameHud(); + if (isQuizQuestionMissionUiMapPlay() && quizQuestionMissionPhase === 'howto') updateQuizQuestionMissionHowtoHud(); }); socket.on('quiz-carry-lobby-sync', (d) => { if (!d || typeof d.readyMap !== 'object') return; @@ -11651,9 +11683,16 @@ if (gauntletCrownPregamePhase === 'howto') { gauntletCrownSyncGuestReadyIfNeeded(); updateGauntletCrownHowtoHud(); + } else if (isQuizQuestionMissionUiMapPlay() && quizQuestionMissionPhase === 'howto') { + gauntletCrownSyncGuestReadyIfNeeded(); + updateQuizQuestionMissionHowtoHud(); } }); socket.on('gauntlet-crown-lobby-started', () => { + if (isQuizQuestionMissionUiMapPlay() && quizQuestionMissionPhase === 'howto') { + beginQuizQuestionMissionCountdownThenRun(); + return; + } if (!usesCrownLobbyShellPlay()) return; beginGauntletCrownCountdownThenRun(); }); @@ -11760,6 +11799,7 @@ if (!data || isPreviewBotId(data.id)) return; others.delete(data.id); if (previewFillBots) rebalancePreviewBots(); + if (isQuizQuestionMissionUiMapPlay() && quizQuestionMissionPhase === 'howto') updateQuizQuestionMissionHowtoHud(); }); socket.on('chat', (data) => { const box = document.getElementById('chat-messages'); @@ -14797,9 +14837,32 @@ } if (isQuizQuestionMissionUiMapPlay()) { if (quizQuestionMissionPhase !== 'howto') return; - const humansQ = quizCarryPregameHumanIds(); - if (!(humansQ.length === 1 || isMePlayHost())) return; - beginQuizQuestionMissionCountdownThenRun(); + const humans = quizCarryPregameHumanIds(); + const totPlayers = Math.max(1, quizCarryPregameTotalPlayers()); + if (totPlayers === 1) { + beginQuizQuestionMissionCountdownThenRun(); + return; + } + if (!isMePlayHost()) { + if (myId == null) return; + const sid = String(myId); + const next = !gauntletCrownLobbyReadyMap[sid]; + gauntletCrownLobbyReadyMap[sid] = next; + updateQuizQuestionMissionHowtoHud(); + if (socket && socket.connected) socket.emit('gauntlet-crown-lobby-ready', { ready: next }); + return; + } + if (myId == null) return; + const humansReady = humans.length > 0 && humans.every((id) => !!gauntletCrownLobbyReadyMap[id]); + if (humansReady) { + socket.emit('gauntlet-crown-lobby-start', {}, (r) => { if (!r || !r.ok) { /* ignore */ } }); + return; + } + const sidH = String(myId); + const nextH = !gauntletCrownLobbyReadyMap[sidH]; + gauntletCrownLobbyReadyMap[sidH] = nextH; + updateQuizQuestionMissionHowtoHud(); + if (socket && socket.connected) socket.emit('gauntlet-crown-lobby-ready', { ready: nextH }); return; } if (isStackTowerMissionUiMapPlay()) { diff --git a/www/html/Game/public/js/version.js b/www/html/Game/public/js/version.js index fad0f59..5a29e61 100644 --- a/www/html/Game/public/js/version.js +++ b/www/html/Game/public/js/version.js @@ -1,6 +1,6 @@ // ทุกครั้งที่มีการเพิ่มหรือเปลี่ยน ให้เพิ่ม v +0.0001 // หลังแก้ค่าแล้วต้อง copy ไป path ที่ Nginx ชี้ (หรือรัน copy-frogger-files-only.sh) ถึงจะเห็นบนเว็บ -window.APP_VERSION = '0.0191'; +window.APP_VERSION = '0.0195'; document.addEventListener('DOMContentLoaded', function () { var t = document.querySelector('.version-tag'); if (t) t.textContent = 'v ' + window.APP_VERSION; diff --git a/www/html/Game/public/play.html b/www/html/Game/public/play.html index 4c927b9..8e996f4 100644 --- a/www/html/Game/public/play.html +++ b/www/html/Game/public/play.html @@ -1071,6 +1071,9 @@ margin: 0; max-width: 100%; text-align: center; + font-weight: 800; + color: #f8fafc; + font-size: clamp(0.75rem, 2vw, 0.9rem); text-shadow: 0 1px 4px rgba(0, 0, 0, 0.85), 0 0 14px rgba(0, 0, 0, 0.55); } .gch-inner.gch-inner--art .btn-gch-ready { @@ -2014,8 +2017,8 @@ - - + +