import { InvalidArgument, NotYetImplemented } from "@sammo/util"; import { City } from "./City.js"; import type { IGeneralEntity } from "./Entity/GeneralEntity.js"; import type { IResourceController } from "./IResourceController.js"; import { DiplomaticPermission, type CityID, type GeneralID, type GeneralName, type NationID, OfficerLevel, type SquadID, NpcType, StaffLevel, CityOfficerLevel } from "./defs.js"; import { must } from "@sammo/util"; import { Nation } from "./Nation.js"; import { Squad } from "./Squad.js"; import { LazyEntityUpdater } from "./LazyEntityUpdater.js"; import type { IAction, IActionKey } from "./IAction.js"; import { addSeconds } from "date-fns"; export class General extends LazyEntityUpdater { protected readonly _indirectNames: (keyof IGeneralEntity)[] = [ "id", "nationID", "squadID", "nationID", "turnTime" ]; protected readonly _entityType = "General"; protected readonly _raw: IGeneralEntity; protected _city!: WeakRef; protected _squad!: WeakRef | undefined; protected _nation!: WeakRef; protected readonly iActionHandlers = new Map; constructor( raw: IGeneralEntity, protected readonly rc: IResourceController ){ super(); this._raw = raw; } public bootstrap(){ const rc = this.rc; const raw = this._raw; this._city = new WeakRef(must(rc.city(raw.cityID))); this._nation = new WeakRef(must(rc.nation(raw.nationID))); if(raw.squadID){ this._squad = new WeakRef(must(rc.squad(raw.squadID, raw.nationID))); } this.reconfigureIActionHandlers(); } public get id(): GeneralID { return this._raw.id; } public get name(): GeneralName { return this._raw.name; } public get city(): City { return must(this._city.deref()); } public get squad(): Squad | undefined { return this._squad?.deref(); } public get nation(): Nation { return must(this._nation.deref()); } public get isUser(): boolean { return this._raw.npcType <= NpcType.user_borrowed_npc; } public get staffLevel(): StaffLevel | undefined { if(this._raw.officerLevel < OfficerLevel.staffIntel3){ return undefined; } return this._raw.officerLevel as number as StaffLevel; } public get cityOfficerLevel(): CityOfficerLevel | undefined { if(this._raw.officerLevel >= OfficerLevel.staffIntel3){ return undefined; } if(this._raw.officerLevel < OfficerLevel.cityLeadership){ return undefined; } return this._raw.officerLevel as number as CityOfficerLevel; } public changeCity(city: City){ this.city.notifyQuitGeneral(this); this._city = new WeakRef(city); this.forceUpdate((raw) => { raw.cityID = city.id; }); city.notifyJoinGeneral(this); this.reconfigureIActionHandlers(); } public quitSquad(){ if(!this._squad){ return; } const squad = must(this._squad.deref()); if(squad.leader.id === this._raw.id){ squad.destroySquad(false); } else{ squad.notifyQuitGeneral(this); } this._squad = undefined; this.forceUpdate((raw) => { raw.squadID = undefined; }); } public changeSquad(squad: Squad){ this.quitSquad(); this._squad = new WeakRef(squad); this.forceUpdate((raw) => { raw.squadID = squad.id; }); squad.notifyJoinGeneral(this); } public changeNation(nation: Nation){ this.quitSquad(); this.nation.notifyQuitGeneral(this); this._nation = new WeakRef(nation); this.forceUpdate((raw) => { raw.nationID = nation.id; raw.diplomaticPermission = DiplomaticPermission.none; if(nation.id == 0){ raw.officerLevel = OfficerLevel.none; } else{ raw.officerLevel = OfficerLevel.normal; } raw.nationJoinedYearMonth = this.rc.gameEnv.raw.yearMonth; }); nation.notifyJoinGeneral(this); this.reconfigureIActionHandlers(); } private reconfigureIActionHandlers(){ throw new NotYetImplemented(); } public updateTurnTime(){ const secondsPerTurn = this.rc.gameEnv.raw.secondsPerTurn; this.forceUpdate((raw) => { raw.turnTime = addSeconds(raw.turnTime, secondsPerTurn); }); } public compareTurnTime(other: General): number { if(this._raw.turnTime < other._raw.turnTime){ return -1; } if(this._raw.turnTime > other._raw.turnTime){ return 1; } if(this._raw.id < other._raw.id){ return -1; } if(this._raw.id > other._raw.id){ return 1; } return 0; } }