mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-22 05:23:48 +00:00
5aa8356513
## Description: Record player stats for the analytics worker to import in to to postgres. This changes defines a new Analytics schema version, `v0.0.2`, containing additional metadata about each player. ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced - [x] I understand that submitting code with bugs that could have been caught through manual testing blocks releases and new features for all contributors
203 lines
5.5 KiB
TypeScript
203 lines
5.5 KiB
TypeScript
import { renderNumber } from "../../client/Utils";
|
|
import { consolex } from "../Consolex";
|
|
import {
|
|
Execution,
|
|
Game,
|
|
MessageType,
|
|
Player,
|
|
PlayerID,
|
|
Unit,
|
|
UnitType,
|
|
} from "../game/Game";
|
|
import { TileRef } from "../game/GameMap";
|
|
import { PathFindResultType } from "../pathfinding/AStar";
|
|
import { PathFinder } from "../pathfinding/PathFinding";
|
|
import { distSortUnit } from "../Util";
|
|
|
|
export class TradeShipExecution implements Execution {
|
|
private active = true;
|
|
private mg: Game | null = null;
|
|
private origOwner: Player | null = null;
|
|
private tradeShip: Unit | null = null;
|
|
private index = 0;
|
|
private wasCaptured = false;
|
|
private tilesTraveled = 0;
|
|
|
|
constructor(
|
|
private _owner: PlayerID,
|
|
private srcPort: Unit,
|
|
private _dstPort: Unit,
|
|
private pathFinder: PathFinder,
|
|
) {}
|
|
|
|
init(mg: Game, ticks: number): void {
|
|
this.mg = mg;
|
|
this.origOwner = mg.player(this._owner);
|
|
}
|
|
|
|
tick(ticks: number): void {
|
|
if (this.mg === null || this.origOwner === null) {
|
|
throw new Error("Not initialized");
|
|
}
|
|
if (this.tradeShip === null) {
|
|
const spawn = this.origOwner.canBuild(
|
|
UnitType.TradeShip,
|
|
this.srcPort.tile(),
|
|
);
|
|
if (spawn === false) {
|
|
consolex.warn(`cannot build trade ship`);
|
|
this.active = false;
|
|
return;
|
|
}
|
|
this.tradeShip = this.origOwner.buildUnit(UnitType.TradeShip, spawn, {
|
|
dstPort: this._dstPort,
|
|
lastSetSafeFromPirates: ticks,
|
|
});
|
|
|
|
// Record stats
|
|
this.mg.stats().boatSendTrade(this.origOwner, this._dstPort.owner());
|
|
}
|
|
|
|
if (!this.tradeShip.isActive()) {
|
|
this.active = false;
|
|
return;
|
|
}
|
|
|
|
if (this.origOwner !== this.tradeShip.owner()) {
|
|
// Store as variable in case ship is recaptured by previous owner
|
|
this.wasCaptured = true;
|
|
}
|
|
|
|
// If a player captures another player's port while trading we should delete
|
|
// the ship.
|
|
if (this._dstPort.owner().id() === this.srcPort.owner().id()) {
|
|
this.tradeShip.delete(false);
|
|
this.active = false;
|
|
return;
|
|
}
|
|
|
|
if (
|
|
!this.wasCaptured &&
|
|
(!this._dstPort.isActive() ||
|
|
!this.tradeShip.owner().canTrade(this._dstPort.owner()))
|
|
) {
|
|
this.tradeShip.delete(false);
|
|
this.active = false;
|
|
return;
|
|
}
|
|
|
|
if (this.wasCaptured) {
|
|
const ports = this.tradeShip
|
|
.owner()
|
|
.units(UnitType.Port)
|
|
.sort(distSortUnit(this.mg, this.tradeShip));
|
|
if (ports.length === 0) {
|
|
this.tradeShip.delete(false);
|
|
this.active = false;
|
|
return;
|
|
} else {
|
|
this._dstPort = ports[0];
|
|
this.tradeShip.setTargetUnit(this._dstPort);
|
|
}
|
|
}
|
|
|
|
const cachedNextTile = this._dstPort.cacheGet(this.tradeShip.tile());
|
|
if (cachedNextTile !== undefined) {
|
|
if (
|
|
this.mg.isWater(cachedNextTile) &&
|
|
this.mg.isShoreline(cachedNextTile)
|
|
) {
|
|
this.tradeShip.setSafeFromPirates();
|
|
}
|
|
this.tradeShip.move(cachedNextTile);
|
|
this.tilesTraveled++;
|
|
return;
|
|
}
|
|
|
|
const result = this.pathFinder.nextTile(
|
|
this.tradeShip.tile(),
|
|
this._dstPort.tile(),
|
|
);
|
|
|
|
switch (result.type) {
|
|
case PathFindResultType.Completed:
|
|
this.complete();
|
|
break;
|
|
case PathFindResultType.Pending:
|
|
// Fire unit event to rerender.
|
|
this.tradeShip.touch();
|
|
break;
|
|
case PathFindResultType.NextTile:
|
|
this._dstPort.cachePut(this.tradeShip.tile(), result.tile);
|
|
// Update safeFromPirates status
|
|
if (this.mg.isWater(result.tile) && this.mg.isShoreline(result.tile)) {
|
|
this.tradeShip.setSafeFromPirates();
|
|
}
|
|
this.tradeShip.move(result.tile);
|
|
this.tilesTraveled++;
|
|
break;
|
|
case PathFindResultType.PathNotFound:
|
|
consolex.warn("captured trade ship cannot find route");
|
|
if (this.tradeShip.isActive()) {
|
|
this.tradeShip.delete(false);
|
|
}
|
|
this.active = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
private complete() {
|
|
if (this.mg === null || this.origOwner === null) {
|
|
throw new Error("Not initialized");
|
|
}
|
|
if (this.tradeShip === null) return;
|
|
this.active = false;
|
|
this.tradeShip.delete(false);
|
|
const gold = this.mg.config().tradeShipGold(this.tilesTraveled);
|
|
|
|
if (this.wasCaptured) {
|
|
const player = this.tradeShip.owner();
|
|
player.addGold(gold);
|
|
this.mg.displayMessage(
|
|
`Received ${renderNumber(gold)} gold from ship captured from ${this.origOwner.displayName()}`,
|
|
MessageType.SUCCESS,
|
|
this.tradeShip.owner().id(),
|
|
);
|
|
|
|
// Record stats
|
|
this.mg.stats().boatCapturedTrade(player, this.origOwner, gold);
|
|
} else {
|
|
this.srcPort.owner().addGold(gold);
|
|
this._dstPort.owner().addGold(gold);
|
|
this.mg.displayMessage(
|
|
`Received ${renderNumber(gold)} gold from trade with ${this.srcPort.owner().displayName()}`,
|
|
MessageType.SUCCESS,
|
|
this._dstPort.owner().id(),
|
|
);
|
|
this.mg.displayMessage(
|
|
`Received ${renderNumber(gold)} gold from trade with ${this._dstPort.owner().displayName()}`,
|
|
MessageType.SUCCESS,
|
|
this.srcPort.owner().id(),
|
|
);
|
|
|
|
// Record stats
|
|
this.mg
|
|
.stats()
|
|
.boatArriveTrade(this.srcPort.owner(), this._dstPort.owner(), gold);
|
|
}
|
|
return;
|
|
}
|
|
|
|
isActive(): boolean {
|
|
return this.active;
|
|
}
|
|
|
|
activeDuringSpawnPhase(): boolean {
|
|
return false;
|
|
}
|
|
|
|
dstPort(): TileRef {
|
|
return this._dstPort.tile();
|
|
}
|
|
}
|