minigame 2 just begin1.4
This commit is contained in:
+25
-11
@@ -2655,6 +2655,19 @@ function gauntletLaserVerticalSpanFromMap(md) {
|
||||
return { y0, y1 };
|
||||
}
|
||||
|
||||
/**
|
||||
* แถว grid ของ lane obstacle: แถวเท้า (ขอบล่าง footprint; แถวบนของตัว = player y)
|
||||
* — สูงกว่าแบบ top+ch หนึ่งช่อง (ไม่ให้ลงเกินพรม)
|
||||
*/
|
||||
function gauntletLaneGridRowFromPlayerTop(md, topY, h) {
|
||||
const { ch } = getCharacterFootprintWHForMove(md);
|
||||
const top = Math.floor(Number(topY));
|
||||
if (!Number.isFinite(top) || top < 0 || top >= h) return null;
|
||||
const lr = top + ch - 1;
|
||||
if (lr < 0 || lr >= h) return null;
|
||||
return lr;
|
||||
}
|
||||
|
||||
function runGauntletTick(sid, space) {
|
||||
const md = (space.mapId && maps.get(space.mapId)) || space.mapData;
|
||||
if (!md || md.gameType !== 'gauntlet') {
|
||||
@@ -2684,23 +2697,23 @@ function runGauntletTick(sid, space) {
|
||||
for (let i = 0; i < gr.obstacles.length; i++) gr.obstacles[i].x -= 1;
|
||||
gr.obstacles = gr.obstacles.filter((o) => o.x >= 0);
|
||||
|
||||
const occupiedY = new Set();
|
||||
const laneSpawnRows = new Set();
|
||||
space.peers.forEach((peer) => {
|
||||
const fy = Math.floor(Number(peer.y));
|
||||
if (Number.isFinite(fy) && fy >= 0 && fy < h) occupiedY.add(fy);
|
||||
const lr = gauntletLaneGridRowFromPlayerTop(md, peer.y, h);
|
||||
if (lr != null) laneSpawnRows.add(lr);
|
||||
});
|
||||
/* แถวที่ client แจ้ง (บอท preview อยู่บน client ไม่ใช่ peer) — ให้ spawn lane บนแถวบอทด้วย */
|
||||
/* แถวบนที่ client แจ้ง (บอท preview) — แปลงเป็นแถว lane เดียวกับ peer */
|
||||
const previewRows = space.gauntletPreviewRowsBySocket;
|
||||
if (previewRows && previewRows.size) {
|
||||
previewRows.forEach((set) => {
|
||||
set.forEach((y) => {
|
||||
const fy = Math.floor(Number(y));
|
||||
if (Number.isFinite(fy) && fy >= 0 && fy < h) occupiedY.add(fy);
|
||||
const lr = gauntletLaneGridRowFromPlayerTop(md, y, h);
|
||||
if (lr != null) laneSpawnRows.add(lr);
|
||||
});
|
||||
});
|
||||
}
|
||||
/* lane obstacle เฉพาะแถวที่มีคน — ลบชิ้นที่ลอยในแถวว่าง */
|
||||
gr.obstacles = gr.obstacles.filter((o) => o.kind !== 'lane' || occupiedY.has(o.y));
|
||||
/* lane obstacle เฉพาะแถวที่ยังมีผู้เล่น/บอทในเลนนั้น — ลบชิ้นที่ไม่มีใครแล้ว */
|
||||
gr.obstacles = gr.obstacles.filter((o) => o.kind !== 'lane' || laneSpawnRows.has(o.y));
|
||||
|
||||
gr.spawnAcc = (gr.spawnAcc || 0) + 1;
|
||||
if (gr.spawnAcc >= (gr.nextSpawnIn || 3)) {
|
||||
@@ -2711,8 +2724,8 @@ function runGauntletTick(sid, space) {
|
||||
const span = gauntletLaserVerticalSpanFromMap(md);
|
||||
gr.obstacles.push({ id: ++gr.nextObsId, kind: 'laser', x: w - 1, y0: span.y0, y1: span.y1 });
|
||||
}
|
||||
/* ประเภท 1: แยกเลน — เฉพาะแถวที่มีผู้เล่นยืนอยู่ (สุ่มแยกแถว) */
|
||||
occupiedY.forEach((ly) => {
|
||||
/* ประเภท 1: แยกเลน — แถวเท้า (ไม่ใช่แถวหัว; ไม่ใช่แถวใต้เท้าอีกช่อง) */
|
||||
laneSpawnRows.forEach((ly) => {
|
||||
if (Math.random() < GAUNTLET_LANE_ROW_SPAWN_CHANCE) {
|
||||
gr.obstacles.push({ id: ++gr.nextObsId, kind: 'lane', x: w - 1, y: ly });
|
||||
}
|
||||
@@ -2720,6 +2733,7 @@ function runGauntletTick(sid, space) {
|
||||
}
|
||||
|
||||
/* กระโดดข้ามสำเร็จ → เลื่อนผู้เล่นไปขวา แต่ไม่ลบ obstacle (ยังไหลต่อให้คนอื่น/รอบถัดไป) */
|
||||
const { ch: gauntletCh } = getCharacterFootprintWHForMove(md);
|
||||
space.peers.forEach((p) => {
|
||||
let px = Math.floor(Number(p.x)) || 0;
|
||||
let py = Math.floor(Number(p.y)) || 0;
|
||||
@@ -2729,7 +2743,7 @@ function runGauntletTick(sid, space) {
|
||||
let advanceX = false;
|
||||
let hitBack = false;
|
||||
for (const o of gr.obstacles) {
|
||||
if (o.kind === 'lane' && o.x === px && o.y === py) {
|
||||
if (o.kind === 'lane' && o.x === px && o.y >= py && o.y < py + gauntletCh) {
|
||||
if (air) advanceX = true;
|
||||
else hitBack = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user