mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 11:30:43 +00:00
core(game): derive plan-driven state from motion plans
- Remove `markUnitPlanDriven` from `Game`/`GameImpl` - Centralize “maybe emit UnitUpdate” behind `GameImpl.onUnitMoved` - Record trade ship motion plan before the first move to avoid redundant per-step unit updates
This commit is contained in:
@@ -48,9 +48,6 @@ export class TradeShipExecution implements Execution {
|
||||
targetUnit: this._dstPort,
|
||||
lastSetSafeFromPirates: ticks,
|
||||
});
|
||||
// This unit can move immediately, but plan-driven units don't emit per-step Unit updates.
|
||||
// Mark it plan-driven up-front so its first move doesn't generate redundant traffic.
|
||||
this.mg.markUnitPlanDriven(this.tradeShip.id());
|
||||
this.mg.stats().boatSendTrade(this.origOwner, this._dstPort.owner());
|
||||
}
|
||||
|
||||
@@ -109,12 +106,49 @@ export class TradeShipExecution implements Execution {
|
||||
return;
|
||||
}
|
||||
|
||||
const result = this.pathFinder.next(curTile, this._dstPort.tile());
|
||||
const dst = this._dstPort.tile();
|
||||
const result = this.pathFinder.next(curTile, dst);
|
||||
|
||||
switch (result.status) {
|
||||
case PathStatus.PENDING:
|
||||
if (dst !== this.motionPlanDst) {
|
||||
this.motionPlanId++;
|
||||
const from = curTile;
|
||||
const path = this.pathFinder.findPath(from, dst) ?? [from];
|
||||
if (path.length === 0 || path[0] !== from) {
|
||||
path.unshift(from);
|
||||
}
|
||||
|
||||
this.mg.recordMotionPlan({
|
||||
kind: "grid",
|
||||
unitId: this.tradeShip.id(),
|
||||
planId: this.motionPlanId,
|
||||
startTick: ticks + 1,
|
||||
ticksPerStep: 1,
|
||||
path,
|
||||
});
|
||||
this.motionPlanDst = dst;
|
||||
}
|
||||
break;
|
||||
case PathStatus.NEXT:
|
||||
if (dst !== this.motionPlanDst) {
|
||||
this.motionPlanId++;
|
||||
const from = result.node;
|
||||
const path = this.pathFinder.findPath(from, dst) ?? [from];
|
||||
if (path.length === 0 || path[0] !== from) {
|
||||
path.unshift(from);
|
||||
}
|
||||
|
||||
this.mg.recordMotionPlan({
|
||||
kind: "grid",
|
||||
unitId: this.tradeShip.id(),
|
||||
planId: this.motionPlanId,
|
||||
startTick: ticks + 1,
|
||||
ticksPerStep: 1,
|
||||
path,
|
||||
});
|
||||
this.motionPlanDst = dst;
|
||||
}
|
||||
// Update safeFromPirates status
|
||||
if (this.mg.isWater(result.node) && this.mg.isShoreline(result.node)) {
|
||||
this.tradeShip.setSafeFromPirates();
|
||||
@@ -133,26 +167,6 @@ export class TradeShipExecution implements Execution {
|
||||
this.active = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const dst = this._dstPort.tile();
|
||||
if (dst !== this.motionPlanDst) {
|
||||
this.motionPlanId++;
|
||||
const from = this.tradeShip.tile();
|
||||
const path = this.pathFinder.findPath(from, dst) ?? [from];
|
||||
if (path.length === 0 || path[0] !== from) {
|
||||
path.unshift(from);
|
||||
}
|
||||
|
||||
this.mg.recordMotionPlan({
|
||||
kind: "grid",
|
||||
unitId: this.tradeShip.id(),
|
||||
planId: this.motionPlanId,
|
||||
startTick: ticks + 1,
|
||||
ticksPerStep: 1,
|
||||
path,
|
||||
});
|
||||
this.motionPlanDst = dst;
|
||||
}
|
||||
}
|
||||
|
||||
private complete() {
|
||||
|
||||
@@ -768,11 +768,6 @@ export interface Game extends GameMap {
|
||||
inSpawnPhase(): boolean;
|
||||
executeNextTick(): GameUpdates;
|
||||
drainPackedTileUpdates(): Uint32Array;
|
||||
/**
|
||||
* Marks a unit as "plan-driven" so its per-tile `Unit` updates can be suppressed.
|
||||
* The client is expected to advance the unit position via motion plans.
|
||||
*/
|
||||
markUnitPlanDriven(unitId: number): void;
|
||||
recordMotionPlan(record: MotionPlanRecord): void;
|
||||
drainPackedMotionPlans(): Uint32Array | null;
|
||||
setWinner(winner: Player | Team, allPlayersStats: AllPlayersStats): void;
|
||||
|
||||
@@ -433,10 +433,6 @@ export class GameImpl implements Game {
|
||||
return packed;
|
||||
}
|
||||
|
||||
markUnitPlanDriven(unitId: number): void {
|
||||
this.planDrivenUnitIds.add(unitId);
|
||||
}
|
||||
|
||||
recordMotionPlan(record: MotionPlanRecord): void {
|
||||
switch (record.kind) {
|
||||
case "grid":
|
||||
@@ -452,10 +448,21 @@ export class GameImpl implements Game {
|
||||
this.motionPlanRecords.push(record);
|
||||
}
|
||||
|
||||
isUnitPlanDriven(unitId: number): boolean {
|
||||
private isUnitPlanDriven(unitId: number): boolean {
|
||||
return this.planDrivenUnitIds.has(unitId);
|
||||
}
|
||||
|
||||
maybeAddUnitUpdate(unit: Unit): void {
|
||||
if (!this.isUnitPlanDriven(unit.id())) {
|
||||
this.addUpdate(unit.toUpdate());
|
||||
}
|
||||
}
|
||||
|
||||
onUnitMoved(unit: Unit): void {
|
||||
this.updateUnitTile(unit);
|
||||
this.maybeAddUnitUpdate(unit);
|
||||
}
|
||||
|
||||
drainPackedMotionPlans(): Uint32Array | null {
|
||||
const records = this.motionPlanRecords;
|
||||
if (records.length === 0) {
|
||||
|
||||
@@ -159,10 +159,7 @@ export class UnitImpl implements Unit {
|
||||
}
|
||||
this._lastTile = this._tile;
|
||||
this._tile = tile;
|
||||
this.mg.updateUnitTile(this);
|
||||
if (!this.mg.isUnitPlanDriven(this._id)) {
|
||||
this.mg.addUpdate(this.toUpdate());
|
||||
}
|
||||
this.mg.onUnitMoved(this);
|
||||
}
|
||||
|
||||
setTroops(troops: number): void {
|
||||
|
||||
Reference in New Issue
Block a user