minigame 2 just begin1.67
This commit is contained in:
@@ -5382,6 +5382,106 @@
|
||||
return g !== 'F';
|
||||
}
|
||||
|
||||
function gauntletCrownRankBonusLocal(rankOrdinal) {
|
||||
if (rankOrdinal === 1) return 100;
|
||||
if (rankOrdinal === 2) return 80;
|
||||
if (rankOrdinal === 3) return 60;
|
||||
return 0;
|
||||
}
|
||||
|
||||
function gauntletCrownRollRewardCardLocal(grade) {
|
||||
const r = Math.random();
|
||||
if (grade === 'A') {
|
||||
if (r < 0.3) return { kind: 'culprit', th: 'การ์ดชี้คนร้าย', en: 'Culprit card' };
|
||||
if (r < 0.8) return { kind: 'rare', th: 'การ์ด Rare', en: 'Rare card' };
|
||||
return { kind: 'common', th: 'การ์ดธรรมดา', en: 'Common card' };
|
||||
}
|
||||
if (grade === 'B') {
|
||||
if (r < 0.2) return { kind: 'culprit', th: 'การ์ดชี้คนร้าย', en: 'Culprit card' };
|
||||
if (r < 0.5) return { kind: 'rare', th: 'การ์ด Rare', en: 'Rare card' };
|
||||
return { kind: 'common', th: 'การ์ดธรรมดา', en: 'Common card' };
|
||||
}
|
||||
if (r < 0.2) return { kind: 'rare', th: 'การ์ด Rare', en: 'Rare card' };
|
||||
return { kind: 'common', th: 'การ์ดธรรมดา', en: 'Common card' };
|
||||
}
|
||||
|
||||
/**
|
||||
* Editor embed + preview bots: รวมแถวอันดับกับบอท (สูงสุด 5 ช่อง) และคำนวณรวม/เฉลี่ย/เกรดให้สอดคล้องกับแถวที่โชว์
|
||||
* — อันดับในช่องใช้ลำดับ 1..5 หลังเรียงคะแนน (เหมือนแนว quiz_carry mission row)
|
||||
*/
|
||||
function gauntletCrownBuildDisplayMission(mission) {
|
||||
if (!mission || !Array.isArray(mission.ranked)) return mission;
|
||||
if (!(previewFillBots && isGauntletCrownHeistMapPlay() && others && typeof others.forEach === 'function')) return mission;
|
||||
|
||||
const seen = new Set();
|
||||
const baseRows = [];
|
||||
mission.ranked.forEach((r) => {
|
||||
if (!r) return;
|
||||
const sid = String(r.id);
|
||||
if (seen.has(sid)) return;
|
||||
seen.add(sid);
|
||||
baseRows.push({
|
||||
id: r.id,
|
||||
nickname: (r.nickname && String(r.nickname).trim()) ? String(r.nickname).trim() : 'ผู้เล่น',
|
||||
characterId: r.characterId ?? null,
|
||||
baseScore: r.eliminated ? 0 : Math.max(0, Number(r.baseScore) || 0),
|
||||
eliminated: !!r.eliminated,
|
||||
});
|
||||
});
|
||||
others.forEach((o, id) => {
|
||||
if (!o || !isPreviewBotId(id)) return;
|
||||
const sid = String(id);
|
||||
if (seen.has(sid)) return;
|
||||
seen.add(sid);
|
||||
baseRows.push({
|
||||
id: id,
|
||||
nickname: (o.nickname && String(o.nickname).trim()) ? String(o.nickname).trim() : sid,
|
||||
characterId: o.characterId ?? null,
|
||||
baseScore: o.gauntletEliminated ? 0 : Math.max(0, Number(o.gauntletScore) | 0),
|
||||
eliminated: !!o.gauntletEliminated,
|
||||
});
|
||||
});
|
||||
|
||||
baseRows.sort((a, b) => {
|
||||
if (b.baseScore !== a.baseScore) return b.baseScore - a.baseScore;
|
||||
const nick = String(a.nickname).localeCompare(String(b.nickname), 'th');
|
||||
if (nick !== 0) return nick;
|
||||
return String(a.id).localeCompare(String(b.id));
|
||||
});
|
||||
const top = baseRows.slice(0, 5);
|
||||
const ranked = top.map((row, idx) => {
|
||||
const pos = idx + 1;
|
||||
const rankBonus = gauntletCrownRankBonusLocal(pos);
|
||||
const rankLabel = pos === 1 ? '1st' : pos === 2 ? '2nd' : pos === 3 ? '3rd' : String(pos);
|
||||
const finalScore = row.baseScore + rankBonus;
|
||||
return {
|
||||
id: row.id,
|
||||
nickname: row.nickname,
|
||||
characterId: row.characterId,
|
||||
baseScore: row.baseScore,
|
||||
eliminated: row.eliminated,
|
||||
rank: pos,
|
||||
rankLabel: rankLabel,
|
||||
rankBonus: rankBonus,
|
||||
finalScore: finalScore,
|
||||
};
|
||||
});
|
||||
|
||||
const totalSum = ranked.reduce(function (s, r) { return s + r.finalScore; }, 0);
|
||||
const n = ranked.length || 1;
|
||||
const averageScore = Math.floor(totalSum / n);
|
||||
const grade = averageScore >= 80 ? 'A' : averageScore >= 60 ? 'B' : 'C';
|
||||
const rewardCard = gauntletCrownRollRewardCardLocal(grade);
|
||||
return {
|
||||
ranked: ranked,
|
||||
totalSum: totalSum,
|
||||
averageScore: averageScore,
|
||||
grade: grade,
|
||||
rewardCard: rewardCard,
|
||||
totalParts: ranked.map(function (r) { return r.finalScore; }),
|
||||
};
|
||||
}
|
||||
|
||||
function showGauntletCrownMissionOverlay(mission) {
|
||||
const ov = document.getElementById('gauntlet-crown-mission-overlay');
|
||||
const rowEl = document.getElementById('gcm-rank-row');
|
||||
@@ -5390,8 +5490,10 @@
|
||||
const bonusEl = document.getElementById('gcm-bonus');
|
||||
const btn = document.getElementById('btn-gcm-done');
|
||||
if (!ov || !rowEl || !mission || !Array.isArray(mission.ranked)) return;
|
||||
const disp = gauntletCrownBuildDisplayMission(mission);
|
||||
if (!disp || !Array.isArray(disp.ranked)) return;
|
||||
rowEl.innerHTML = '';
|
||||
mission.ranked.forEach((r) => {
|
||||
disp.ranked.forEach((r) => {
|
||||
const cell = document.createElement('div');
|
||||
cell.className = 'gcm-cell';
|
||||
const tag = document.createElement('div');
|
||||
@@ -5436,7 +5538,10 @@
|
||||
nick.textContent = r.nickname || '—';
|
||||
const sc = document.createElement('div');
|
||||
sc.className = 'gcm-sc';
|
||||
sc.textContent = String(r.baseScore || 0) + '(+' + String(r.rankBonus || 0) + ')';
|
||||
const botScorePlain = previewFillBots && isGauntletCrownHeistMapPlay() && isPreviewBotId(r.id);
|
||||
sc.textContent = botScorePlain
|
||||
? String(Math.max(0, Number(r.baseScore) || 0))
|
||||
: String(r.baseScore || 0) + '(+' + String(r.rankBonus || 0) + ')';
|
||||
cell.appendChild(tag);
|
||||
cell.appendChild(frame);
|
||||
cell.appendChild(nick);
|
||||
@@ -5444,13 +5549,13 @@
|
||||
rowEl.appendChild(cell);
|
||||
});
|
||||
if (totalEl) {
|
||||
const parts = (mission.totalParts || []).map((n) => String(Math.max(0, Number(n) || 0)));
|
||||
const sum = Math.max(0, Number(mission.totalSum) || 0);
|
||||
const avg = Math.max(0, Math.floor(Number(mission.averageScore) || 0));
|
||||
const parts = (disp.totalParts || []).map((n) => String(Math.max(0, Number(n) || 0)));
|
||||
const sum = Math.max(0, Number(disp.totalSum) || 0);
|
||||
const avg = Math.max(0, Math.floor(Number(disp.averageScore) || 0));
|
||||
totalEl.innerHTML = 'คะแนนรวม <span class="gcm-total-nums">(' + parts.join('+') + ') = ' + sum + '</span> · เฉลี่ย ' + avg + ' → เกรด';
|
||||
}
|
||||
if (gradeEl) {
|
||||
const g = String(mission.grade || 'C').toUpperCase().charAt(0);
|
||||
const g = String(disp.grade || 'C').toUpperCase().charAt(0);
|
||||
gradeEl.textContent = g;
|
||||
gradeEl.className = 'gcm-grade gcm-grade--' + g.toLowerCase();
|
||||
}
|
||||
@@ -5472,7 +5577,7 @@
|
||||
row.appendChild(chk);
|
||||
row.appendChild(sp);
|
||||
bonusEl.appendChild(row);
|
||||
const rc = mission.rewardCard;
|
||||
const rc = disp.rewardCard;
|
||||
if (rc && rc.th) {
|
||||
const pl = document.createElement('div');
|
||||
pl.className = 'gcm-plaque';
|
||||
@@ -5489,7 +5594,7 @@
|
||||
btn.onclick = function () {
|
||||
if (previewMode && editorEmbedReturn) {
|
||||
ov.classList.add('is-hidden');
|
||||
showQuizCarryTimeupOnDeskLayer(function () { return gauntletCrownEmbedMissionAnyOk(mission); });
|
||||
showQuizCarryTimeupOnDeskLayer(function () { return gauntletCrownEmbedMissionAnyOk(disp); });
|
||||
} else {
|
||||
goLobby();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// ทุกครั้งที่มีการเพิ่มหรือเปลี่ยน ให้เพิ่ม v +0.0001
|
||||
// หลังแก้ค่าแล้วต้อง copy ไป path ที่ Nginx ชี้ (หรือรัน copy-frogger-files-only.sh) ถึงจะเห็นบนเว็บ
|
||||
window.APP_VERSION = '0.0174';
|
||||
window.APP_VERSION = '0.0175';
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
var t = document.querySelector('.version-tag');
|
||||
if (t) t.textContent = 'v ' + window.APP_VERSION;
|
||||
|
||||
@@ -1858,8 +1858,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<script src="/Game/socket.io/socket.io.js"></script>
|
||||
<script src="js/version.js?v=0.0174"></script>
|
||||
<script src="js/play.js?v=0.199"></script>
|
||||
<script src="js/version.js?v=0.0175"></script>
|
||||
<script src="js/play.js?v=0.201"></script>
|
||||
<div class="version-tag">v —</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -5382,6 +5382,106 @@
|
||||
return g !== 'F';
|
||||
}
|
||||
|
||||
function gauntletCrownRankBonusLocal(rankOrdinal) {
|
||||
if (rankOrdinal === 1) return 100;
|
||||
if (rankOrdinal === 2) return 80;
|
||||
if (rankOrdinal === 3) return 60;
|
||||
return 0;
|
||||
}
|
||||
|
||||
function gauntletCrownRollRewardCardLocal(grade) {
|
||||
const r = Math.random();
|
||||
if (grade === 'A') {
|
||||
if (r < 0.3) return { kind: 'culprit', th: 'การ์ดชี้คนร้าย', en: 'Culprit card' };
|
||||
if (r < 0.8) return { kind: 'rare', th: 'การ์ด Rare', en: 'Rare card' };
|
||||
return { kind: 'common', th: 'การ์ดธรรมดา', en: 'Common card' };
|
||||
}
|
||||
if (grade === 'B') {
|
||||
if (r < 0.2) return { kind: 'culprit', th: 'การ์ดชี้คนร้าย', en: 'Culprit card' };
|
||||
if (r < 0.5) return { kind: 'rare', th: 'การ์ด Rare', en: 'Rare card' };
|
||||
return { kind: 'common', th: 'การ์ดธรรมดา', en: 'Common card' };
|
||||
}
|
||||
if (r < 0.2) return { kind: 'rare', th: 'การ์ด Rare', en: 'Rare card' };
|
||||
return { kind: 'common', th: 'การ์ดธรรมดา', en: 'Common card' };
|
||||
}
|
||||
|
||||
/**
|
||||
* Editor embed + preview bots: รวมแถวอันดับกับบอท (สูงสุด 5 ช่อง) และคำนวณรวม/เฉลี่ย/เกรดให้สอดคล้องกับแถวที่โชว์
|
||||
* — อันดับในช่องใช้ลำดับ 1..5 หลังเรียงคะแนน (เหมือนแนว quiz_carry mission row)
|
||||
*/
|
||||
function gauntletCrownBuildDisplayMission(mission) {
|
||||
if (!mission || !Array.isArray(mission.ranked)) return mission;
|
||||
if (!(previewFillBots && isGauntletCrownHeistMapPlay() && others && typeof others.forEach === 'function')) return mission;
|
||||
|
||||
const seen = new Set();
|
||||
const baseRows = [];
|
||||
mission.ranked.forEach((r) => {
|
||||
if (!r) return;
|
||||
const sid = String(r.id);
|
||||
if (seen.has(sid)) return;
|
||||
seen.add(sid);
|
||||
baseRows.push({
|
||||
id: r.id,
|
||||
nickname: (r.nickname && String(r.nickname).trim()) ? String(r.nickname).trim() : 'ผู้เล่น',
|
||||
characterId: r.characterId ?? null,
|
||||
baseScore: r.eliminated ? 0 : Math.max(0, Number(r.baseScore) || 0),
|
||||
eliminated: !!r.eliminated,
|
||||
});
|
||||
});
|
||||
others.forEach((o, id) => {
|
||||
if (!o || !isPreviewBotId(id)) return;
|
||||
const sid = String(id);
|
||||
if (seen.has(sid)) return;
|
||||
seen.add(sid);
|
||||
baseRows.push({
|
||||
id: id,
|
||||
nickname: (o.nickname && String(o.nickname).trim()) ? String(o.nickname).trim() : sid,
|
||||
characterId: o.characterId ?? null,
|
||||
baseScore: o.gauntletEliminated ? 0 : Math.max(0, Number(o.gauntletScore) | 0),
|
||||
eliminated: !!o.gauntletEliminated,
|
||||
});
|
||||
});
|
||||
|
||||
baseRows.sort((a, b) => {
|
||||
if (b.baseScore !== a.baseScore) return b.baseScore - a.baseScore;
|
||||
const nick = String(a.nickname).localeCompare(String(b.nickname), 'th');
|
||||
if (nick !== 0) return nick;
|
||||
return String(a.id).localeCompare(String(b.id));
|
||||
});
|
||||
const top = baseRows.slice(0, 5);
|
||||
const ranked = top.map((row, idx) => {
|
||||
const pos = idx + 1;
|
||||
const rankBonus = gauntletCrownRankBonusLocal(pos);
|
||||
const rankLabel = pos === 1 ? '1st' : pos === 2 ? '2nd' : pos === 3 ? '3rd' : String(pos);
|
||||
const finalScore = row.baseScore + rankBonus;
|
||||
return {
|
||||
id: row.id,
|
||||
nickname: row.nickname,
|
||||
characterId: row.characterId,
|
||||
baseScore: row.baseScore,
|
||||
eliminated: row.eliminated,
|
||||
rank: pos,
|
||||
rankLabel: rankLabel,
|
||||
rankBonus: rankBonus,
|
||||
finalScore: finalScore,
|
||||
};
|
||||
});
|
||||
|
||||
const totalSum = ranked.reduce(function (s, r) { return s + r.finalScore; }, 0);
|
||||
const n = ranked.length || 1;
|
||||
const averageScore = Math.floor(totalSum / n);
|
||||
const grade = averageScore >= 80 ? 'A' : averageScore >= 60 ? 'B' : 'C';
|
||||
const rewardCard = gauntletCrownRollRewardCardLocal(grade);
|
||||
return {
|
||||
ranked: ranked,
|
||||
totalSum: totalSum,
|
||||
averageScore: averageScore,
|
||||
grade: grade,
|
||||
rewardCard: rewardCard,
|
||||
totalParts: ranked.map(function (r) { return r.finalScore; }),
|
||||
};
|
||||
}
|
||||
|
||||
function showGauntletCrownMissionOverlay(mission) {
|
||||
const ov = document.getElementById('gauntlet-crown-mission-overlay');
|
||||
const rowEl = document.getElementById('gcm-rank-row');
|
||||
@@ -5390,8 +5490,10 @@
|
||||
const bonusEl = document.getElementById('gcm-bonus');
|
||||
const btn = document.getElementById('btn-gcm-done');
|
||||
if (!ov || !rowEl || !mission || !Array.isArray(mission.ranked)) return;
|
||||
const disp = gauntletCrownBuildDisplayMission(mission);
|
||||
if (!disp || !Array.isArray(disp.ranked)) return;
|
||||
rowEl.innerHTML = '';
|
||||
mission.ranked.forEach((r) => {
|
||||
disp.ranked.forEach((r) => {
|
||||
const cell = document.createElement('div');
|
||||
cell.className = 'gcm-cell';
|
||||
const tag = document.createElement('div');
|
||||
@@ -5436,7 +5538,10 @@
|
||||
nick.textContent = r.nickname || '—';
|
||||
const sc = document.createElement('div');
|
||||
sc.className = 'gcm-sc';
|
||||
sc.textContent = String(r.baseScore || 0) + '(+' + String(r.rankBonus || 0) + ')';
|
||||
const botScorePlain = previewFillBots && isGauntletCrownHeistMapPlay() && isPreviewBotId(r.id);
|
||||
sc.textContent = botScorePlain
|
||||
? String(Math.max(0, Number(r.baseScore) || 0))
|
||||
: String(r.baseScore || 0) + '(+' + String(r.rankBonus || 0) + ')';
|
||||
cell.appendChild(tag);
|
||||
cell.appendChild(frame);
|
||||
cell.appendChild(nick);
|
||||
@@ -5444,13 +5549,13 @@
|
||||
rowEl.appendChild(cell);
|
||||
});
|
||||
if (totalEl) {
|
||||
const parts = (mission.totalParts || []).map((n) => String(Math.max(0, Number(n) || 0)));
|
||||
const sum = Math.max(0, Number(mission.totalSum) || 0);
|
||||
const avg = Math.max(0, Math.floor(Number(mission.averageScore) || 0));
|
||||
const parts = (disp.totalParts || []).map((n) => String(Math.max(0, Number(n) || 0)));
|
||||
const sum = Math.max(0, Number(disp.totalSum) || 0);
|
||||
const avg = Math.max(0, Math.floor(Number(disp.averageScore) || 0));
|
||||
totalEl.innerHTML = 'คะแนนรวม <span class="gcm-total-nums">(' + parts.join('+') + ') = ' + sum + '</span> · เฉลี่ย ' + avg + ' → เกรด';
|
||||
}
|
||||
if (gradeEl) {
|
||||
const g = String(mission.grade || 'C').toUpperCase().charAt(0);
|
||||
const g = String(disp.grade || 'C').toUpperCase().charAt(0);
|
||||
gradeEl.textContent = g;
|
||||
gradeEl.className = 'gcm-grade gcm-grade--' + g.toLowerCase();
|
||||
}
|
||||
@@ -5472,7 +5577,7 @@
|
||||
row.appendChild(chk);
|
||||
row.appendChild(sp);
|
||||
bonusEl.appendChild(row);
|
||||
const rc = mission.rewardCard;
|
||||
const rc = disp.rewardCard;
|
||||
if (rc && rc.th) {
|
||||
const pl = document.createElement('div');
|
||||
pl.className = 'gcm-plaque';
|
||||
@@ -5489,7 +5594,7 @@
|
||||
btn.onclick = function () {
|
||||
if (previewMode && editorEmbedReturn) {
|
||||
ov.classList.add('is-hidden');
|
||||
showQuizCarryTimeupOnDeskLayer(function () { return gauntletCrownEmbedMissionAnyOk(mission); });
|
||||
showQuizCarryTimeupOnDeskLayer(function () { return gauntletCrownEmbedMissionAnyOk(disp); });
|
||||
} else {
|
||||
goLobby();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user