Files
core_ng/@sammo/game_logic/src/General.ts
T
2024-03-15 16:13:27 +00:00

179 lines
5.0 KiB
TypeScript

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<IGeneralEntity> {
protected readonly _indirectNames: (keyof IGeneralEntity)[] = [
"id", "nationID", "squadID", "nationID", "turnTime"
];
protected readonly _entityType = "General";
protected readonly _raw: IGeneralEntity;
protected _city!: WeakRef<City>;
protected _squad!: WeakRef<Squad> | undefined;
protected _nation!: WeakRef<Nation>;
protected readonly iActionHandlers = new Map<IActionKey, IAction>;
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;
}
}