0.2.3: Clementia S2 releases a dead, hidden, uncarriable or pathless rider at once (slot and weight back before the same tick's boarding checks); same-browser match recovery never takes the seat of a window that is reloading or still starting (a tab keeps its own session token; seats are stamped at the server's welcome, the older welcome wins); golden: diy-135 moves (outcome unchanged)
This commit is contained in:
1 parent
821ab827bd
commit
ba5b998a72
19 files changed
+580
-60
No files matched your search
@@ -96,6 +96,8 @@ export class Session {
|
||||
this.ws = null;
|
||||
/** @type {boolean} */
|
||||
this.connected = false;
|
||||
/** @type {number | null} local first-welcome stamp of the attached client (optional, not authentication) */
|
||||
this.claimAt = null;
|
||||
/** @type {number} ms epoch of the last inbound frame / pong */
|
||||
this.lastSeen = now;
|
||||
/** @type {number | null} ms epoch when the socket was lost (null while connected) */
|
||||
@@ -647,6 +649,11 @@ export class Network {
|
||||
if (!session) {
|
||||
session = msg.token ? this.registry.byToken(msg.token) : null;
|
||||
if (session) {
|
||||
if (session.connected && session.ws && session.ws !== conn.ws
|
||||
&& (msg.noReplace || (Number.isFinite(msg.claimAt) && session.claimAt != null && msg.claimAt > session.claimAt))) {
|
||||
this.reply(conn, errorMsg(ERR.SESSION_IN_USE, rid));
|
||||
return;
|
||||
}
|
||||
resumed = true;
|
||||
if (session.ws && session.ws !== conn.ws) this.detachReplaced(session.ws);
|
||||
} else {
|
||||
@@ -656,6 +663,7 @@ export class Network {
|
||||
conn.session = session;
|
||||
session.ws = conn.ws;
|
||||
session.connected = true;
|
||||
session.claimAt = Number.isFinite(msg.claimAt) ? msg.claimAt : null;
|
||||
session.disconnectedAt = null;
|
||||
}
|
||||
session.name = name;
|
||||
|
||||
@@ -79,6 +79,17 @@ export default {
|
||||
if (!c.stopped) {
|
||||
c.moved = Math.min(c.distance, c.moved + SPEED * dt);
|
||||
c.x = c.ox + c.dc * c.moved; c.y = c.oy + c.dr * c.moved;
|
||||
// Release before either boarding limit is checked: invalid riders occupy neither a slot
|
||||
// nor weight. Return their current weight, including modifiers applied during the ride.
|
||||
for (let i = c.passengers.length - 1; i >= 0; i--) {
|
||||
const e = c.passengers[i], [er, ec] = tile(e);
|
||||
if (!e.alive || e.hidden || cannotCarry(e)
|
||||
|| !battle.grid.findPath(er, ec, Math.round(c.y), Math.round(c.x))) {
|
||||
battle.removeBuff(e, CARRY + unit.id);
|
||||
c.passengers.splice(i, 1);
|
||||
c.mass += e.weight;
|
||||
}
|
||||
}
|
||||
const cap = num(b2['attack@max_passenger_cnt'], 15);
|
||||
for (const e of battle.enemies) {
|
||||
if (c.passengers.length >= cap) break;
|
||||
@@ -93,10 +104,7 @@ export default {
|
||||
battle.addBuff(e, { key: CARRY + unit.id, flags: { noMove: true, disarm: true, unblockable: true }, source: unit, tags: ['skill'] });
|
||||
}
|
||||
for (const e of c.passengers) {
|
||||
if (!e.alive || e.hidden || cannotCarry(e)) { battle.removeBuff(e, CARRY + unit.id); continue; }
|
||||
if (!e.findBuff(CARRY + unit.id)) continue;
|
||||
const [er, ec] = tile(e);
|
||||
if (!battle.grid.findPath(er, ec, Math.round(c.y), Math.round(c.x))) { battle.removeBuff(e, CARRY + unit.id); continue; }
|
||||
const fromX = e.x, fromY = e.y;
|
||||
e.x = c.x; e.y = c.y;
|
||||
if (e.route) e.route.pts = null;
|
||||
|
||||
Reference in new issue
Block a user