update desige 2 3 5 6 7
This commit is contained in:
+263
-56
@@ -641,6 +641,10 @@
|
||||
let stackTowerLifeBarImg = null;
|
||||
let stackTowerLifeHitImg = null;
|
||||
let stackTowerLifeFullImg = null;
|
||||
/** Space Shooter (violent_crime): life HUD โหลดจาก /img/ViolentCrime/ แยกจาก TowerBlock ของ Stack */
|
||||
let violentCrimeLifeBarImg = null;
|
||||
let violentCrimeLifeHitImg = null;
|
||||
let violentCrimeLifeFullImg = null;
|
||||
/** @type {{ until: number } | null} */
|
||||
let stackTowerHeartMinusFx = null;
|
||||
const STACK_TOWER_HEART_MINUS_FX_MS = 1500;
|
||||
@@ -745,7 +749,9 @@
|
||||
}
|
||||
|
||||
ctx.save();
|
||||
ctx.imageSmoothingEnabled = false;
|
||||
/* BG อวกาศเป็นภาพ illustration (loop 1024w สเกลขึ้น ~1.9x) — เปิด smoothing ไม่ให้แตกเป็นบล็อก (stack tower BG กว้าง ~1920 จึงคงปิดไว้) */
|
||||
ctx.imageSmoothingEnabled = true;
|
||||
ctx.imageSmoothingQuality = 'high';
|
||||
ctx.beginPath();
|
||||
ctx.rect(0, 0, cwR, chR);
|
||||
ctx.clip();
|
||||
@@ -5756,6 +5762,26 @@
|
||||
}
|
||||
}
|
||||
|
||||
/** Space Shooter (mnpz6rkp): โหลด life HUD จาก /img/ViolentCrime/ แล้วคืน image set ให้ drawStackTowerLifeIntegrityBarPlay */
|
||||
function ensureViolentCrimeLifeHudImagesPlay() {
|
||||
if (!violentCrimeLifeBarImg) {
|
||||
violentCrimeLifeBarImg = new Image();
|
||||
violentCrimeLifeBarImg.decoding = 'async';
|
||||
violentCrimeLifeBarImg.src = violentCrimeAssetUrl('life-bar.png');
|
||||
}
|
||||
if (!violentCrimeLifeHitImg) {
|
||||
violentCrimeLifeHitImg = new Image();
|
||||
violentCrimeLifeHitImg.decoding = 'async';
|
||||
violentCrimeLifeHitImg.src = violentCrimeAssetUrl('life-hit.png');
|
||||
}
|
||||
if (!violentCrimeLifeFullImg) {
|
||||
violentCrimeLifeFullImg = new Image();
|
||||
violentCrimeLifeFullImg.decoding = 'async';
|
||||
violentCrimeLifeFullImg.src = violentCrimeAssetUrl('life-full.png');
|
||||
}
|
||||
return { bar: violentCrimeLifeBarImg, full: violentCrimeLifeFullImg, hit: violentCrimeLifeHitImg };
|
||||
}
|
||||
|
||||
/**
|
||||
* สัดส่วนสูงของ life-bar.png ที่เป็นข้อความ "SYSTEM INTEGRITY" (ที่เหลือ = แถวหัวใจแยกวาดเอง ไม่ทับขอบ `[` `]` ใน PNG)
|
||||
*/
|
||||
@@ -5764,14 +5790,16 @@
|
||||
/**
|
||||
* วาดหัวข้อจาก life-bar.png (ครอปบน) + แถวหัวใจ life-full / life-hit กึ่งกลาง — คืนความสูงที่ใช้จริง
|
||||
*/
|
||||
function drawStackTowerLifeIntegrityBarPlay(ctx, destX, destY, maxW, maxH, lifeSlots, livesRem) {
|
||||
ensureStackTowerLifeHudImagesPlay();
|
||||
const bar = stackTowerLifeBarImg;
|
||||
const fullIm = (stackTowerLifeFullImg && stackTowerLifeFullImg.complete && stackTowerLifeFullImg.naturalWidth > 0)
|
||||
? stackTowerLifeFullImg
|
||||
function drawStackTowerLifeIntegrityBarPlay(ctx, destX, destY, maxW, maxH, lifeSlots, livesRem, opts) {
|
||||
const imgs = (opts && opts.images)
|
||||
? opts.images
|
||||
: (ensureStackTowerLifeHudImagesPlay(), { bar: stackTowerLifeBarImg, full: stackTowerLifeFullImg, hit: stackTowerLifeHitImg });
|
||||
const bar = imgs.bar;
|
||||
const fullIm = (imgs.full && imgs.full.complete && imgs.full.naturalWidth > 0)
|
||||
? imgs.full
|
||||
: ensureStackTowerHeartMinusImgPlay();
|
||||
const hitIm = stackTowerLifeHitImg && stackTowerLifeHitImg.complete && stackTowerLifeHitImg.naturalWidth > 0
|
||||
? stackTowerLifeHitImg
|
||||
const hitIm = imgs.hit && imgs.hit.complete && imgs.hit.naturalWidth > 0
|
||||
? imgs.hit
|
||||
: null;
|
||||
const slots = Math.max(1, Math.min(20, Math.floor(lifeSlots) || 1));
|
||||
const lives = Math.max(0, Math.min(slots, Math.floor(livesRem) || 0));
|
||||
@@ -6371,6 +6399,7 @@
|
||||
return;
|
||||
}
|
||||
cd.classList.remove('is-hidden');
|
||||
syncGauntletCrownCountdownMg2ModePlay(cd);
|
||||
let n = 3;
|
||||
setCountdown321QuestionAssetGraphic(numEl, n);
|
||||
const step = function () {
|
||||
@@ -6691,6 +6720,7 @@
|
||||
return;
|
||||
}
|
||||
cd.classList.remove('is-hidden');
|
||||
syncGauntletCrownCountdownMg2ModePlay(cd);
|
||||
let n = 3;
|
||||
setCountdown321QuestionAssetGraphic(numEl, n);
|
||||
const step = function () {
|
||||
@@ -7088,6 +7118,7 @@
|
||||
return;
|
||||
}
|
||||
cd.classList.remove('is-hidden');
|
||||
syncGauntletCrownCountdownMg2ModePlay(cd);
|
||||
let n = 3;
|
||||
setCountdown321QuestionAssetGraphic(numEl, n);
|
||||
const step = function () {
|
||||
@@ -7622,6 +7653,7 @@
|
||||
return;
|
||||
}
|
||||
cd.classList.remove('is-hidden');
|
||||
syncGauntletCrownCountdownMg2ModePlay(cd);
|
||||
let n = 3;
|
||||
setCountdown321QuestionAssetGraphic(numEl, n);
|
||||
const step = function () {
|
||||
@@ -9571,6 +9603,19 @@
|
||||
function syncGauntletCrownJumpButton() {
|
||||
const btn = document.getElementById('gauntlet-crown-jump-btn');
|
||||
if (!btn) return;
|
||||
/* MG5 jump_survive (jumper): โชว์ปุ่ม JUMP มุมขวาล่าง (design .mg5-jump 1648/818/231) — ให้ touch กระโดดได้ (เดิม keyboard-only) */
|
||||
if (mapData && isJumpSurviveMissionHudActivePlay()) {
|
||||
btn.classList.remove('is-hidden');
|
||||
btn.setAttribute('aria-hidden', 'false');
|
||||
btn.style.pointerEvents = '';
|
||||
btn.classList.add('mg2-jump');
|
||||
const jimg = btn.querySelector('img');
|
||||
if (jimg && jimg.src.indexOf('/Jumper/') < 0) jimg.src = jumperAssetUrl('btn-jump.png');
|
||||
const hudJ = document.getElementById('play-cyber-hud');
|
||||
if (hudJ && hudJ.classList.contains('play-cyber-hud--quiz-tf-mock')) updateQuizTfMockScale(hudJ);
|
||||
syncMg2MockJumpButtonBoundsPlay();
|
||||
return;
|
||||
}
|
||||
const pregameUi = gauntletCrownPregamePhase === 'howto' || gauntletCrownPregamePhase === 'countdown';
|
||||
const liveUi = gauntletCrownPregamePhase === 'live' && gauntletCrownRunwayAvatarRunAllowedPlay();
|
||||
const show = !!(mapData && isGauntletCrownHeistMapPlay() && !me.gauntletEliminated && (pregameUi || liveUi));
|
||||
@@ -9620,6 +9665,175 @@
|
||||
btn.style.pointerEvents = ok ? '' : 'none';
|
||||
}
|
||||
|
||||
/** MG3 (mnn93hpi): ผู้เล่นตาปัจจุบัน (active node) สำหรับ host portrait ใน DOM HUD */
|
||||
function mg3CurrentSeatRowPlay() {
|
||||
const seat = getStackPreviewCurrentSeat();
|
||||
const order = stackPreviewTurnOrder;
|
||||
let entry = null;
|
||||
if (order && order.length) entry = order.find((e) => e.seat === seat) || null;
|
||||
if (!entry || entry.kind === 'human') {
|
||||
return {
|
||||
id: myId,
|
||||
characterId: me.characterId || getPlayCharacterId(),
|
||||
isMe: true,
|
||||
playTint: me.playTint || resolvePlayTintForPeer(String(myId != null ? myId : 'me')),
|
||||
};
|
||||
}
|
||||
const o = entry.botId ? others.get(entry.botId) : null;
|
||||
return {
|
||||
id: entry.botId,
|
||||
characterId: o ? o.characterId : null,
|
||||
isMe: false,
|
||||
playTint: o ? (o.playTint || resolvePlayTintForPeer(entry.botId)) : null,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* MG3 Stack Tower live HUD → DOM overlay (#mg3-tower-hud) — canvas object-fit:cover ครอป HUD ขอบจอ
|
||||
* จึงย้าย life bar (ขวาบน) + progress (ซ้ายล่าง) + code terminal + host frame มาเป็น DOM สเกลตาม stage
|
||||
*/
|
||||
function syncStackTowerMissionDomHudPlay() {
|
||||
const root = document.getElementById('mg3-tower-hud');
|
||||
if (!root) return;
|
||||
const on = !!(mapData && isStack() && stackMini && isStackTowerMissionHudActivePlay());
|
||||
root.classList.toggle('is-hidden', !on);
|
||||
root.setAttribute('aria-hidden', on ? 'false' : 'true');
|
||||
if (!on) return;
|
||||
|
||||
if (!root.dataset.mg3Assets) {
|
||||
const setSrc = (sel, file) => { const el = root.querySelector(sel); if (el) el.src = stackTowerAssetUrl(file); };
|
||||
setSrc('.mg3-life-bar', 'life-bar.png');
|
||||
setSrc('.mg3-host-frame', 'Avartar.png');
|
||||
setSrc('.mg3-terminal-bg', 'code-bg.png');
|
||||
setSrc('.mg3-progress-label', 'progress-txt.png');
|
||||
setSrc('.mg3-progress-track', 'progress-bg.png');
|
||||
setSrc('.mg3-progress-fill', 'progress.png');
|
||||
root.dataset.mg3Assets = '1';
|
||||
}
|
||||
|
||||
/* วาง design plane 1920×1080 → scale แบบ contain + จัดกึ่งกลางใน stage (HUD เห็นครบ ไม่โดน object-fit:cover ครอป) */
|
||||
const stack = document.getElementById('play-canvas-stack');
|
||||
if (stack) {
|
||||
const r = stack.getBoundingClientRect();
|
||||
const cw = Math.max(1, r.width || 0);
|
||||
const ch = Math.max(1, r.height || 0);
|
||||
const s = Math.min(cw / 1920, ch / 1080);
|
||||
if (s > 0 && isFinite(s)) {
|
||||
const left = Math.round(r.left + (cw - 1920 * s) / 2);
|
||||
const top = Math.round(r.top + (ch - 1080 * s) / 2);
|
||||
const key = left + ',' + top + ',' + s.toFixed(4);
|
||||
if (root.dataset.mg3Box !== key) {
|
||||
root.dataset.mg3Box = key;
|
||||
root.style.left = left + 'px';
|
||||
root.style.top = top + 'px';
|
||||
root.style.transform = 'scale(' + s + ')';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const slots = Math.max(1, Math.min(20, Math.floor(Number(playStackTeamMissesMax) || 3)));
|
||||
const lives = Math.max(0, Math.min(slots, Math.floor(Number(
|
||||
stackMini.teamMissesLeft != null ? stackMini.teamMissesLeft : (stackMini.lives != null ? stackMini.lives : 3),
|
||||
) || 0)));
|
||||
const heartsEl = document.getElementById('mg3-life-hearts');
|
||||
if (heartsEl) {
|
||||
const hk = slots + '/' + lives;
|
||||
if (heartsEl.dataset.hk !== hk) {
|
||||
heartsEl.dataset.hk = hk;
|
||||
heartsEl.innerHTML = '';
|
||||
for (let i = 0; i < slots; i++) {
|
||||
const im = document.createElement('img');
|
||||
im.src = stackTowerAssetUrl(i < lives ? 'life-full.png' : 'life-hit.png');
|
||||
im.alt = '';
|
||||
heartsEl.appendChild(im);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const pct = Math.max(0, Math.min(100, Math.round(Number(stackTowerDecryptPctPlay()) || 0)));
|
||||
if (root.dataset.mg3Pct !== String(pct)) {
|
||||
root.dataset.mg3Pct = String(pct);
|
||||
/* fill เป็น px ในระนาบ design (track ภายในจาก left:30 กว้างสุด ~358px) */
|
||||
const fillEl = document.getElementById('mg3-progress-fill');
|
||||
if (fillEl) fillEl.style.width = Math.round(358 * pct / 100) + 'px';
|
||||
const pctEl = document.getElementById('mg3-progress-pct');
|
||||
if (pctEl) pctEl.textContent = '[ ' + pct + '% ]';
|
||||
}
|
||||
|
||||
const hostAv = document.getElementById('mg3-host-av');
|
||||
if (hostAv) {
|
||||
const row = mg3CurrentSeatRowPlay();
|
||||
const hk = (row.id != null ? row.id : 'me') + '|' + (row.characterId || '');
|
||||
if (hostAv.dataset.hk !== hk) {
|
||||
hostAv.dataset.hk = hk;
|
||||
setCyberHudScoreAvatarImg(hostAv, row);
|
||||
}
|
||||
}
|
||||
|
||||
const logEl = document.getElementById('mg3-terminal-log');
|
||||
if (logEl) {
|
||||
const lines = stackPreviewHudLog && stackPreviewHudLog.length
|
||||
? stackPreviewHudLog.slice(-7)
|
||||
: ['>>> DECRYPT UPLINK READY', '>>> SPACE / CLICK = DROP (ตาคุณ)'];
|
||||
const txt = lines.join('\n');
|
||||
if (logEl.textContent !== txt) logEl.textContent = txt;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* MG6 Space Shooter life → overlay #mg6-life-hud (ระนาบ design 1920×1080 scale ตาม stage แบบเดียวกับ MG3)
|
||||
* life-bar.png + หัวใจ 3 ดวง (ViolentCrime) ตำแหน่ง/ขนาดเท่า MG3 — ไม่พึ่ง flex ของ cyber HUD (กันบีบ/ล้นขอบ)
|
||||
*/
|
||||
function syncSpaceShooterLifeDomHudPlay() {
|
||||
const root = document.getElementById('mg6-life-hud');
|
||||
if (!root) return;
|
||||
const on = !!(mapData && isSpaceShooter() && isSpaceShooterMissionHudActivePlay());
|
||||
root.classList.toggle('is-hidden', !on);
|
||||
root.setAttribute('aria-hidden', on ? 'false' : 'true');
|
||||
if (!on) return;
|
||||
if (!root.dataset.assets) {
|
||||
const bar = root.querySelector('.mg6-life-bar');
|
||||
if (bar) bar.src = violentCrimeAssetUrl('life-bar.png');
|
||||
root.dataset.assets = '1';
|
||||
}
|
||||
const stack = document.getElementById('play-canvas-stack');
|
||||
if (stack) {
|
||||
const r = stack.getBoundingClientRect();
|
||||
const cw = Math.max(1, r.width || 0);
|
||||
const ch = Math.max(1, r.height || 0);
|
||||
const s = Math.min(cw / 1920, ch / 1080);
|
||||
if (s > 0 && isFinite(s)) {
|
||||
const left = Math.round(r.left + (cw - 1920 * s) / 2);
|
||||
const top = Math.round(r.top + (ch - 1080 * s) / 2);
|
||||
const key = left + ',' + top + ',' + s.toFixed(4);
|
||||
if (root.dataset.box !== key) {
|
||||
root.dataset.box = key;
|
||||
root.style.left = left + 'px';
|
||||
root.style.top = top + 'px';
|
||||
root.style.transform = 'scale(' + s + ')';
|
||||
}
|
||||
}
|
||||
}
|
||||
const slots = SPACE_SHOOTER_MISSION_MAX_ASTEROID_HITS;
|
||||
const hits = Math.max(0, Math.min(slots, Number(me.spaceShooterHits) || 0));
|
||||
const rem = slots - hits;
|
||||
const heartsEl = document.getElementById('mg6-life-hearts');
|
||||
if (heartsEl) {
|
||||
const hk = slots + '/' + rem;
|
||||
if (heartsEl.dataset.hk !== hk) {
|
||||
heartsEl.dataset.hk = hk;
|
||||
heartsEl.innerHTML = '';
|
||||
for (let i = 0; i < slots; i++) {
|
||||
const im = document.createElement('img');
|
||||
im.src = violentCrimeAssetUrl(i < rem ? 'life-full.png' : 'life-hit.png');
|
||||
im.alt = '';
|
||||
im.decoding = 'async';
|
||||
heartsEl.appendChild(im);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function resetQuizCarryPlayState() {
|
||||
cancelQuizCarrySessionCompleteResultToSummary();
|
||||
const qcmo = document.getElementById('quiz-carry-mission-overlay');
|
||||
@@ -16240,6 +16454,11 @@
|
||||
const jq = jumpSurviveJumpQueued;
|
||||
jumpSurviveJumpQueued = false;
|
||||
|
||||
/* virtual joystick (touch) — แกน x ป้อนซ้าย/ขวาเหมือนคีย์ A/D (deadzone จัดการในตัว update แล้ว) */
|
||||
const joyX = isJumpSurviveMissionHudActivePlay() ? (Number(quizQuestionMissionJoyVecX) || 0) : 0;
|
||||
const moveLeftIn = !!(keys['ArrowLeft'] || keys['KeyA']) || joyX < -0.001;
|
||||
const moveRightIn = !!(keys['ArrowRight'] || keys['KeyD']) || joyX > 0.001;
|
||||
|
||||
const r = jumpSurvivePhysicsIntegrate(md, {
|
||||
dt,
|
||||
cw,
|
||||
@@ -16249,8 +16468,8 @@
|
||||
vy0: jumpSurviveVy,
|
||||
wasOnGround: jumpSurviveOnGround,
|
||||
jumpQueued: jq,
|
||||
moveLeft: !!(keys['ArrowLeft'] || keys['KeyA']),
|
||||
moveRight: !!(keys['ArrowRight'] || keys['KeyD']),
|
||||
moveLeft: moveLeftIn,
|
||||
moveRight: moveRightIn,
|
||||
});
|
||||
|
||||
if (r.died) {
|
||||
@@ -16267,9 +16486,9 @@
|
||||
stepJumpSurvivePreviewBots(dt, halfViewH);
|
||||
|
||||
if (!jumpSurviveEliminated) {
|
||||
me.isWalking = Math.abs(jumpSurviveVy) > 40 || !!(keys['ArrowLeft'] || keys['KeyA'] || keys['ArrowRight'] || keys['KeyD']);
|
||||
if (keys['ArrowRight'] || keys['KeyD']) me.direction = 'right';
|
||||
else if (keys['ArrowLeft'] || keys['KeyA']) me.direction = 'left';
|
||||
me.isWalking = Math.abs(jumpSurviveVy) > 40 || moveLeftIn || moveRightIn;
|
||||
if (moveRightIn) me.direction = 'right';
|
||||
else if (moveLeftIn) me.direction = 'left';
|
||||
|
||||
if (Date.now() - jumpSurviveLastEmitT > 80) {
|
||||
jumpSurviveLastEmitT = Date.now();
|
||||
@@ -18728,6 +18947,8 @@
|
||||
const mono = '11px ui-monospace, "Cascadia Mono", Consolas, monospace';
|
||||
const monoSm = '9px ui-monospace, Consolas, monospace';
|
||||
const towerMapHud = isStackTowerMissionUiMapPlay();
|
||||
/* MG3 live mission: HUD ย้ายไป DOM (#mg3-tower-hud) แล้ว — ไม่วาดบน canvas (object-fit:cover ครอปขอบหาย) */
|
||||
if (towerMapHud) return;
|
||||
const lifeSlots = towerMapHud
|
||||
? Math.max(1, Math.min(20, Math.floor(Number(playStackTeamMissesMax) || 3)))
|
||||
: 3;
|
||||
@@ -19469,9 +19690,24 @@
|
||||
function syncQuizQuestionMissionJoystickPlay() {
|
||||
const root = document.getElementById('quiz-question-mission-joystick');
|
||||
if (!root) return;
|
||||
const on = !!(isQuizQuestionMissionHudActivePlay() && !isChatFocused());
|
||||
const jumperOn = isJumpSurviveMissionHudActivePlay();
|
||||
const on = !!((isQuizQuestionMissionHudActivePlay() || jumperOn) && !isChatFocused());
|
||||
root.classList.toggle('is-hidden', !on);
|
||||
root.setAttribute('aria-hidden', on ? 'false' : 'true');
|
||||
if (on) {
|
||||
/* สลับรูป joystick ตามฉาก: jumper → /img/Jumper/, quiz คำถาม → /img/QUESTION/ (เปลี่ยน src เฉพาะตอน skin เปลี่ยน) */
|
||||
const skin = jumperOn ? 'jumper' : 'question';
|
||||
const bg = document.getElementById('quiz-q-mission-joystick-bg');
|
||||
const knobImg = document.getElementById('quiz-q-mission-joystick-knob-img');
|
||||
if (bg && bg.dataset.joySkin !== skin) {
|
||||
bg.src = jumperOn ? jumperAssetUrl('btn-joystick-1.png') : questionMissionAssetUrl('btn-joystick-1.png');
|
||||
bg.dataset.joySkin = skin;
|
||||
}
|
||||
if (knobImg && knobImg.dataset.joySkin !== skin) {
|
||||
knobImg.src = jumperOn ? jumperAssetUrl('btn-joystick-2.png') : questionMissionAssetUrl('btn-joystick-2.png');
|
||||
knobImg.dataset.joySkin = skin;
|
||||
}
|
||||
}
|
||||
if (!on) {
|
||||
const base = document.getElementById('quiz-q-mission-joystick-base');
|
||||
if (base && quizQuestionMissionJoyPointerId != null) {
|
||||
@@ -19524,7 +19760,8 @@
|
||||
function syncMg2MockJumpButtonBoundsPlay(stackRect, scale) {
|
||||
const jumpBtn = document.getElementById('gauntlet-crown-jump-btn');
|
||||
const hud = document.getElementById('play-cyber-hud');
|
||||
if (!jumpBtn || !hud || hud.dataset.missionMockSkin !== 'gauntlet_crown') {
|
||||
const _jbSkin = hud ? hud.dataset.missionMockSkin : '';
|
||||
if (!jumpBtn || !hud || (_jbSkin !== 'gauntlet_crown' && _jbSkin !== 'jumper')) {
|
||||
if (jumpBtn) {
|
||||
jumpBtn.style.removeProperty('left');
|
||||
jumpBtn.style.removeProperty('top');
|
||||
@@ -19850,45 +20087,8 @@
|
||||
}
|
||||
if (statusEl) {
|
||||
if (isSpaceShooterMissionHudActivePlay()) {
|
||||
ensureStackTowerLifeHudImagesPlay();
|
||||
const nn = String((me.nickname || nick || 'PILOT')).trim().slice(0, 24);
|
||||
const hits = Math.max(0, Math.min(SPACE_SHOOTER_MISSION_MAX_ASTEROID_HITS, Number(me.spaceShooterHits) || 0));
|
||||
const rem = SPACE_SHOOTER_MISSION_MAX_ASTEROID_HITS - hits;
|
||||
const esc = playCyberHudEsc(nn);
|
||||
const W = 220;
|
||||
const H = 58;
|
||||
const dpr = Math.min(2, Math.max(1, typeof window !== 'undefined' && window.devicePixelRatio ? window.devicePixelRatio : 1));
|
||||
let canv = statusEl.querySelector('canvas.play-cyber-ss-integrity-canvas');
|
||||
let metaEl = statusEl.querySelector('.play-cyber-ss-meta');
|
||||
if (!canv || !metaEl) {
|
||||
statusEl.textContent = '';
|
||||
canv = document.createElement('canvas');
|
||||
canv.className = 'play-cyber-ss-integrity-canvas';
|
||||
canv.setAttribute('aria-hidden', 'true');
|
||||
metaEl = document.createElement('div');
|
||||
metaEl.className = 'play-cyber-ss-meta';
|
||||
statusEl.appendChild(canv);
|
||||
statusEl.appendChild(metaEl);
|
||||
}
|
||||
canv.width = Math.max(1, Math.floor(W * dpr));
|
||||
canv.height = Math.max(1, Math.floor(H * dpr));
|
||||
canv.style.width = W + 'px';
|
||||
canv.style.height = H + 'px';
|
||||
const ctxSs = canv.getContext('2d');
|
||||
if (ctxSs) {
|
||||
ctxSs.setTransform(dpr, 0, 0, dpr, 0, 0);
|
||||
ctxSs.clearRect(0, 0, W + 2, H + 2);
|
||||
drawStackTowerLifeIntegrityBarPlay(
|
||||
ctxSs,
|
||||
2,
|
||||
2,
|
||||
W - 4,
|
||||
H - 4,
|
||||
SPACE_SHOOTER_MISSION_MAX_ASTEROID_HITS,
|
||||
rem,
|
||||
);
|
||||
}
|
||||
metaEl.textContent = 'P1 · ' + esc; /* ตัด 'TEAM 0 · COMBO x0' ปลอม (ค่าไม่เปลี่ยน ไม่ตรง design) */
|
||||
/* MG6 life ย้ายไป overlay เฉพาะ #mg6-life-hud (syncSpaceShooterLifeDomHudPlay) — คุมตำแหน่ง/ขนาดเท่า MG3 */
|
||||
statusEl.textContent = '';
|
||||
} else if (isQuizQuestionMissionHudActivePlay()) {
|
||||
statusEl.textContent = 'QUIZ LINK · ประลองความรู้';
|
||||
} else if (isStackTowerMissionHudActivePlay()) {
|
||||
@@ -21203,6 +21403,8 @@
|
||||
syncQuizCarryGrabButton();
|
||||
syncGauntletCrownJumpButton();
|
||||
syncStackTowerDropButtonPlay();
|
||||
syncStackTowerMissionDomHudPlay();
|
||||
syncSpaceShooterLifeDomHudPlay();
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', (e) => {
|
||||
@@ -21654,7 +21856,10 @@
|
||||
if (!btn) return;
|
||||
btn.addEventListener('click', (ev) => {
|
||||
ev.preventDefault();
|
||||
if (!mapData || !isGauntlet() || isChatFocused()) return;
|
||||
if (isChatFocused()) return;
|
||||
/* MG5 jumper: click = queue jump (mirror keyboard Space/W/↑) */
|
||||
if (mapData && isJumpSurviveMissionHudActivePlay()) { jumpSurviveJumpQueued = true; return; }
|
||||
if (!mapData || !isGauntlet()) return;
|
||||
tryRequestGauntletJumpPlay();
|
||||
});
|
||||
})();
|
||||
@@ -21677,6 +21882,7 @@
|
||||
if (!base) return;
|
||||
if (bg) {
|
||||
bg.src = questionMissionAssetUrl('btn-joystick-1.png');
|
||||
bg.dataset.joySkin = 'question';
|
||||
bg.onerror = function () {
|
||||
this.onerror = null;
|
||||
this.removeAttribute('src');
|
||||
@@ -21684,6 +21890,7 @@
|
||||
}
|
||||
if (knobImg) {
|
||||
knobImg.src = questionMissionAssetUrl('btn-joystick-2.png');
|
||||
knobImg.dataset.joySkin = 'question';
|
||||
knobImg.onerror = function () {
|
||||
this.onerror = null;
|
||||
this.removeAttribute('src');
|
||||
@@ -21698,7 +21905,7 @@
|
||||
quizQuestionMissionJoystickResetVisual();
|
||||
}
|
||||
base.addEventListener('pointerdown', (e) => {
|
||||
if (!isQuizQuestionMissionHudActivePlay() || isChatFocused()) return;
|
||||
if (!(isQuizQuestionMissionHudActivePlay() || isJumpSurviveMissionHudActivePlay()) || isChatFocused()) return;
|
||||
if (e.button != null && e.button !== 0) return;
|
||||
e.preventDefault();
|
||||
try {
|
||||
|
||||
@@ -1424,6 +1424,10 @@
|
||||
#gauntlet-crown-mission-overlay.is-hidden,
|
||||
#gauntlet-crown-countdown.is-hidden,
|
||||
#stack-tower-result-flash.is-hidden { display: none !important; }
|
||||
/* นับถอยหลังใช้ .gcc-num{display:block} ทับ — ต้องมี rule ให้ is-hidden ซ่อนเลขข้อความจริง (เดิมไม่มี → "3" รั่วในเกมที่ใช้รูปกราฟิก) */
|
||||
#gauntlet-crown-countdown .gcc-num.is-hidden { display: none !important; }
|
||||
/* สรุปผล: เส้นแบ่ง vrule แสดงเฉพาะ Last Light (mg2) — non-mg2 มี is-hidden แต่ไม่มี rule ซ่อน → ไปกินช่อง grid ขวา ดัน "โบนัสพิเศษ" ตกลงคอลัมน์ซ้าย */
|
||||
#gcm-vrule.is-hidden { display: none !important; }
|
||||
.gcc-panel {
|
||||
text-align: center;
|
||||
padding: 0;
|
||||
@@ -2089,6 +2093,36 @@
|
||||
image-rendering: pixelated;
|
||||
margin-bottom: 0.28rem;
|
||||
}
|
||||
/* MG6 life (DOM) — life-bar.png เต็มใบ + หัวใจ 3 ดวงในวงเล็บ [ ] เหมือน MG3 */
|
||||
.play-cyber-ss-life {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
margin-bottom: 0.28rem;
|
||||
}
|
||||
.play-cyber-ss-lifebar { width: 100%; display: block; image-rendering: pixelated; }
|
||||
.play-cyber-ss-hearts {
|
||||
position: absolute;
|
||||
left: 24.3%; top: 50%; height: 46%;
|
||||
display: flex; align-items: center; gap: 4%;
|
||||
}
|
||||
.play-cyber-ss-hearts img { height: 100%; width: auto; image-rendering: pixelated; }
|
||||
/* MG6 Space Shooter life overlay — ระนาบ design 1920×1080 scale ตาม stage (coords/หัวใจเท่า MG3) */
|
||||
.mg6-life-hud {
|
||||
position: fixed;
|
||||
width: 1920px; height: 1080px;
|
||||
transform-origin: 0 0;
|
||||
pointer-events: none;
|
||||
z-index: 54;
|
||||
}
|
||||
.mg6-life-hud.is-hidden { display: none !important; }
|
||||
.mg6-life-hud img { image-rendering: pixelated; display: block; }
|
||||
.mg6-life-hud .mg6-life { position: absolute; left: 1410px; top: 63px; width: 341px; height: 111px; }
|
||||
.mg6-life-hud .mg6-life-bar { width: 341px; height: 111px; display: block; }
|
||||
.mg6-life-hud .mg6-life-hearts {
|
||||
position: absolute; left: 83px; top: 56px; height: 52px;
|
||||
display: flex; align-items: center; gap: 10px;
|
||||
}
|
||||
.mg6-life-hud .mg6-life-hearts img { height: 52px; width: auto; }
|
||||
#play-cyber-hud.play-cyber-hud--question-mission .play-cyber-ss-meta {
|
||||
font-size: 0.5rem;
|
||||
letter-spacing: 0.06em;
|
||||
@@ -2105,8 +2139,9 @@
|
||||
max-width: min(96vw, 380px);
|
||||
}
|
||||
#play-cyber-hud.play-cyber-hud--ss-self-integrity-left .play-cyber-self-status {
|
||||
order: 1;
|
||||
flex: 1 1 auto;
|
||||
order: 3;
|
||||
flex: 0 0 auto;
|
||||
width: auto;
|
||||
min-width: 0;
|
||||
}
|
||||
#play-cyber-hud.play-cyber-hud--ss-self-integrity-left .play-cyber-profile-frame {
|
||||
@@ -2125,6 +2160,65 @@
|
||||
#play-cyber-hud.play-cyber-hud--stack-tower-canvas-hud .play-cyber-self {
|
||||
display: none !important;
|
||||
}
|
||||
/* ===== MG3 Stack Tower live HUD — DOM overlay: 1920×1080 design plane scale+center ตาม stage (coords ตรง design game.css/game-hud.css) ===== */
|
||||
.mg3-tower-hud {
|
||||
position: fixed;
|
||||
width: 1920px; height: 1080px;
|
||||
transform-origin: 0 0;
|
||||
pointer-events: none;
|
||||
z-index: 54;
|
||||
}
|
||||
.mg3-tower-hud.is-hidden { display: none !important; }
|
||||
.mg3-tower-hud > div { position: absolute; }
|
||||
.mg3-tower-hud img { image-rendering: pixelated; display: block; }
|
||||
/* SYSTEM INTEGRITY life bar (design .mg3-life left:1410 top:63 w:341 h:111) */
|
||||
.mg3-life { left: 1410px; top: 63px; width: 341px; height: 111px; }
|
||||
.mg3-life-bar { width: 341px; height: 111px; display: block; }
|
||||
.mg3-life-hearts {
|
||||
position: absolute; left: 83px; top: 56px;
|
||||
display: flex; align-items: center; gap: 10px; height: 52px;
|
||||
}
|
||||
.mg3-life-hearts img { height: 52px; width: auto; }
|
||||
/* host portrait frame (design .mg-host left:1729 top:21 w/h:201; face left:49 top:49 104×104) */
|
||||
.mg3-host { left: 1729px; top: 21px; width: 201px; height: 201px; }
|
||||
.mg3-host-frame { position: absolute; inset: 0; width: 100%; height: 100%; }
|
||||
.mg3-host-face {
|
||||
position: absolute; left: 49px; top: 49px; width: 104px; height: 104px;
|
||||
border-radius: 8px; object-fit: cover;
|
||||
}
|
||||
/* code terminal (design .mg3-terminal left:40 bottom:170 w:420) */
|
||||
.mg3-terminal { left: 40px; bottom: 170px; width: 420px; }
|
||||
.mg3-terminal-bg { width: 100%; height: auto; }
|
||||
.mg3-terminal-log {
|
||||
position: absolute; left: 9%; right: 9%; top: 10%; bottom: 10%;
|
||||
overflow: hidden;
|
||||
font: 22px/1.4 ui-monospace, "Cascadia Mono", Consolas, monospace;
|
||||
color: #8fe9ff;
|
||||
text-shadow: 0 0 6px rgba(0, 200, 255, 0.5);
|
||||
white-space: pre-wrap; word-break: break-word;
|
||||
}
|
||||
/* progress (design .mg3-progress left:43 bottom:40 w:418 h:151) — label+pct heading แล้ว track+fill */
|
||||
.mg3-progress {
|
||||
left: 43px; bottom: 40px; width: 418px; height: 151px;
|
||||
display: flex; flex-direction: row; flex-wrap: wrap; gap: 0;
|
||||
}
|
||||
.mg3-progress-heading {
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
width: 100%; flex: 0 0 75%; gap: 3px;
|
||||
}
|
||||
.mg3-progress-label { width: auto; height: 58px; display: block; flex: 0 0 auto; }
|
||||
.mg3-progress-pct {
|
||||
font-family: "NotoSansThai", monospace, sans-serif; font-weight: 700;
|
||||
font-size: 28px; line-height: 44px; color: #8fe8ff; letter-spacing: 0.5px;
|
||||
white-space: nowrap; text-shadow: 0 0 8px rgba(120, 220, 255, 0.6);
|
||||
}
|
||||
.mg3-progress-bar { position: relative; width: 100%; flex: 0 0 100%; }
|
||||
.mg3-progress-track { width: 100%; height: auto; display: block; }
|
||||
.mg3-progress-fill {
|
||||
position: absolute; left: 30px; top: 30px; height: 30px; width: 0;
|
||||
object-fit: cover; object-position: left center;
|
||||
transition: width 0.25s ease;
|
||||
}
|
||||
/* Last Light (mno9kb07): แถบคะแนนแนวนอน — score.png แล้วตามด้วยสูงสุด 6 ช่อง (อวาตาร์ | ชื่อบน / คะแนนล่าง) */
|
||||
#play-cyber-hud.play-cyber-hud--gauntlet-crown-strip .play-cyber-hint {
|
||||
display: none !important;
|
||||
@@ -3352,7 +3446,8 @@
|
||||
height: 104px;
|
||||
overflow: hidden;
|
||||
border-radius: 8px;
|
||||
z-index: 1;
|
||||
/* avatar ต้องอยู่บนกรอบ Avartar.png (กรอบมีพื้นกลางทึบ ทับหน้า avatar = "ถูกบัง") — เหมือน MG3 ที่หน้าอยู่บนสุด */
|
||||
z-index: 3;
|
||||
}
|
||||
#play-cyber-hud.play-cyber-hud--quiz-tf-mock .play-cyber-profile-frame .play-cyber-portrait-img,
|
||||
#play-cyber-hud.play-cyber-hud--quiz-tf-mock.play-cyber-hud--question-mission .play-cyber-profile-frame .play-cyber-portrait-img {
|
||||
@@ -3385,6 +3480,7 @@
|
||||
#play-cyber-hud.play-cyber-hud--quiz-tf-mock .play-cyber-op-widgets {
|
||||
display: none !important;
|
||||
}
|
||||
/* Space Shooter (MG6): life ย้ายไป overlay #mg6-life-hud แล้ว — แผง self-status คงซ่อน (ตาม rule quiz-tf-mock) */
|
||||
/* mic 121px @ (1796,205) — เทียบ mg-mic */
|
||||
#play-cyber-hud.play-cyber-hud--quiz-tf-mock .play-cyber-mic-img {
|
||||
display: block;
|
||||
@@ -4490,6 +4586,38 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- MG3 Stack Tower (mnn93hpi) live HUD — DOM overlay (canvas object-fit:cover ครอป HUD ขอบจอ จึงย้ายมา DOM สเกลตาม stage) -->
|
||||
<div id="mg3-tower-hud" class="mg3-tower-hud is-hidden" aria-hidden="true">
|
||||
<div class="mg3-life">
|
||||
<img class="mg3-life-bar" src="" alt="" decoding="async" />
|
||||
<div class="mg3-life-hearts" id="mg3-life-hearts"></div>
|
||||
</div>
|
||||
<div class="mg3-host">
|
||||
<img class="mg3-host-frame" src="" alt="" decoding="async" />
|
||||
<img class="mg3-host-face" id="mg3-host-av" src="" alt="" decoding="async" />
|
||||
</div>
|
||||
<div class="mg3-terminal">
|
||||
<img class="mg3-terminal-bg" src="" alt="" decoding="async" />
|
||||
<div class="mg3-terminal-log" id="mg3-terminal-log"></div>
|
||||
</div>
|
||||
<div class="mg3-progress">
|
||||
<div class="mg3-progress-heading">
|
||||
<img class="mg3-progress-label" src="" alt="" decoding="async" />
|
||||
<span class="mg3-progress-pct" id="mg3-progress-pct">[ 0% ]</span>
|
||||
</div>
|
||||
<div class="mg3-progress-bar">
|
||||
<img class="mg3-progress-track" src="" alt="" decoding="async" />
|
||||
<img class="mg3-progress-fill" id="mg3-progress-fill" src="" alt="" decoding="async" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- MG6 Space Shooter (mnpz6rkp) live life — DOM overlay สเกล design 1920×1080 เหมือน MG3 (ไม่พึ่ง cyber HUD flex) -->
|
||||
<div id="mg6-life-hud" class="mg6-life-hud is-hidden" aria-hidden="true">
|
||||
<div class="mg6-life">
|
||||
<img class="mg6-life-bar" src="" alt="" decoding="async" />
|
||||
<div class="mg6-life-hearts" id="mg6-life-hearts"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="play-quiz-scoreboard" class="is-hidden" aria-live="polite">
|
||||
<div class="play-quiz-scoreboard-title">คะแนน</div>
|
||||
<ul id="play-quiz-scoreboard-list" class="play-quiz-scoreboard-list"></ul>
|
||||
@@ -4746,7 +4874,7 @@
|
||||
<script src="/app-base.js?v=2"></script>
|
||||
<script src="/Game/socket.io/socket.io.js"></script>
|
||||
<script src="js/version.js?v=0.0306"></script>
|
||||
<script src="js/play.js?v=0.00610200013"></script>
|
||||
<script src="js/play.js?v=0.00610200020"></script>
|
||||
<div class="version-tag">v —</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user