play: clamp preview bot position to footprint bounds; separate clumped bots
Made-with: Cursor
This commit is contained in:
@@ -2091,6 +2091,12 @@
|
||||
} else {
|
||||
stepPreviewBotAlongPath(o, w, h);
|
||||
}
|
||||
clampPlayEntityFootprintToMap(o, mapData);
|
||||
});
|
||||
separateClumpedPreviewBots();
|
||||
[...others.keys()].filter(isPreviewBotId).forEach((bid) => {
|
||||
const ob = others.get(bid);
|
||||
if (ob) clampPlayEntityFootprintToMap(ob, mapData);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -5620,6 +5626,50 @@
|
||||
return { cw: leg, ch: leg };
|
||||
}
|
||||
|
||||
/** กันตัวละคร footprint ล้นออกนอกแมป — เดิมใช้ w-0.01 ทำให้ cw/ch>1 ชนขอบแล้วตรรกะเดินค้าง */
|
||||
function clampPlayEntityFootprintToMap(oEnt, md) {
|
||||
if (!oEnt || !md) return;
|
||||
const w = md.width || 20, h = md.height || 15;
|
||||
const { cw, ch } = getCharacterFootprintWH(md);
|
||||
const maxX = Math.max(0, w - cw + 0.999);
|
||||
const maxY = Math.max(0, h - ch + 0.999);
|
||||
if (!Number.isFinite(oEnt.x)) oEnt.x = 0.5;
|
||||
if (!Number.isFinite(oEnt.y)) oEnt.y = 0.5;
|
||||
oEnt.x = Math.max(0, Math.min(maxX, oEnt.x));
|
||||
oEnt.y = Math.max(0, Math.min(maxY, oEnt.y));
|
||||
}
|
||||
|
||||
/** แยกบอท preview ที่ทับกันบนจุดเดียว (มักชนกันที่ขอบแมป) */
|
||||
function separateClumpedPreviewBots() {
|
||||
if (!previewFillBots || !mapData) return;
|
||||
const ids = [...others.keys()].filter(isPreviewBotId);
|
||||
const minD = 0.52;
|
||||
const pushAmt = MOVE_SPEED * 0.5;
|
||||
for (let i = 0; i < ids.length; i++) {
|
||||
for (let j = i + 1; j < ids.length; j++) {
|
||||
const a = others.get(ids[i]);
|
||||
const b = others.get(ids[j]);
|
||||
if (!a || !b) continue;
|
||||
let ddx = b.x - a.x, ddy = b.y - a.y;
|
||||
let d = Math.sqrt(ddx * ddx + ddy * ddy);
|
||||
if (d >= minD) continue;
|
||||
if (d < 1e-5) {
|
||||
ddx = (i + j * 2) % 2 === 0 ? 1 : -1;
|
||||
ddy = ((i + j) % 3) - 1;
|
||||
d = Math.sqrt(ddx * ddx + ddy * ddy) || 1;
|
||||
}
|
||||
const ux = -ddx / d, uy = -ddy / d;
|
||||
const vx = ddx / d, vy = ddy / d;
|
||||
const ax2 = a.x + ux * pushAmt, ay2 = a.y + uy * pushAmt;
|
||||
const bx2 = b.x + vx * pushAmt, by2 = b.y + vy * pushAmt;
|
||||
if (canWalkLikeLobbyForBot(ax2, ay2, a.x, a.y, a)) { a.x = ax2; a.y = ay2; }
|
||||
if (canWalkLikeLobbyForBot(bx2, by2, b.x, b.y, b)) { b.x = bx2; b.y = by2; }
|
||||
clampPlayEntityFootprintToMap(a, mapData);
|
||||
clampPlayEntityFootprintToMap(b, mapData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function quizTilesFootprintPlay(px, py) {
|
||||
const s = new Set();
|
||||
if (!mapData) return s;
|
||||
@@ -5825,8 +5875,7 @@
|
||||
if (Math.sqrt(ux * ux + uy * uy) > PATH_ARRIVE_THRESH) break;
|
||||
path.shift();
|
||||
}
|
||||
o.x = Math.max(0, Math.min(w - 0.01, o.x));
|
||||
o.y = Math.max(0, Math.min(h - 0.01, o.y));
|
||||
clampPlayEntityFootprintToMap(o, mapData);
|
||||
return;
|
||||
}
|
||||
const len = dist || 1;
|
||||
@@ -5870,8 +5919,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
o.x = Math.max(0, Math.min(w - 0.01, o.x));
|
||||
o.y = Math.max(0, Math.min(h - 0.01, o.y));
|
||||
clampPlayEntityFootprintToMap(o, mapData);
|
||||
if (Math.abs(o.x - ox) > 1e-5 || Math.abs(o.y - oy) > 1e-5) {
|
||||
o.botIsWalking = true;
|
||||
o.botPathStuckTicks = 0;
|
||||
@@ -5953,10 +6001,16 @@
|
||||
o.botWanderDy = d[1];
|
||||
o.botWanderNextTurn = now + 200 + Math.floor(Math.random() * 600);
|
||||
}
|
||||
o.x = Number.isFinite(o.x) ? Math.max(0, Math.min(w - 0.01, o.x)) : 0.5;
|
||||
o.y = Number.isFinite(o.y) ? Math.max(0, Math.min(h - 0.01, o.y)) : 0.5;
|
||||
if (!Number.isFinite(o.x)) o.x = 0.5;
|
||||
if (!Number.isFinite(o.y)) o.y = 0.5;
|
||||
clampPlayEntityFootprintToMap(o, mapData);
|
||||
if (Math.abs(o.x - ox) > 1e-5 || Math.abs(o.y - oy) > 1e-5) o.botIsWalking = true;
|
||||
});
|
||||
separateClumpedPreviewBots();
|
||||
[...others.keys()].filter(isPreviewBotId).forEach((bid) => {
|
||||
const ob = others.get(bid);
|
||||
if (ob) clampPlayEntityFootprintToMap(ob, mapData);
|
||||
});
|
||||
if (isQuizBattle() && quizBattlePathModeActive(mapData)) {
|
||||
others.forEach((o, id) => {
|
||||
if (!isPreviewBotId(id)) return;
|
||||
|
||||
@@ -669,7 +669,7 @@
|
||||
</div>
|
||||
<script src="/Game/socket.io/socket.io.js"></script>
|
||||
<script src="js/version.js?v=0.0166"></script>
|
||||
<script src="js/play.js?v=0.084"></script>
|
||||
<script src="js/play.js?v=0.085"></script>
|
||||
<div class="version-tag">v —</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user