wip: 개체 작업 진행
This commit is contained in:
@@ -1,10 +1,149 @@
|
||||
import type { GeneralID, GeneralName } from "./defs.js";
|
||||
import { InvalidArgument } from "@sammo/util";
|
||||
import { City } from "./City.js";
|
||||
import type { IGeneralEntity } from "./GeneralEntity.js";
|
||||
import type { IResourceController } from "./ResourceController.js";
|
||||
import { DiplomaticPermission, type CityID, type GeneralID, type GeneralName, type NationID, OfficerLevel, type TroopID } from "./defs.js";
|
||||
import { must } from "@sammo/util";
|
||||
import { Nation } from "./Nation.js";
|
||||
import { Troop } from "./Troop.js";
|
||||
|
||||
export class General {
|
||||
constructor(
|
||||
public readonly id: GeneralID,
|
||||
public name: GeneralName,
|
||||
){
|
||||
private _raw: IGeneralEntity;
|
||||
private _city: WeakRef<City>;
|
||||
private _troop: WeakRef<Troop> | undefined;
|
||||
private _nation: WeakRef<Nation>;
|
||||
|
||||
public get raw(): Readonly<IGeneralEntity> {
|
||||
return this._raw;
|
||||
}
|
||||
|
||||
constructor(
|
||||
raw: IGeneralEntity,
|
||||
private resourceController: IResourceController
|
||||
){
|
||||
this._raw = raw;
|
||||
this._city = new WeakRef(must(resourceController.getCity(raw.cityID)));
|
||||
this._nation = new WeakRef(must(resourceController.getNation(raw.nationID)));
|
||||
|
||||
if(raw.troopID){
|
||||
this._troop = new WeakRef(must(resourceController.getTroop(raw.troopID, raw.nationID)));
|
||||
}
|
||||
}
|
||||
|
||||
public get id(): GeneralID {
|
||||
return this._raw.id;
|
||||
}
|
||||
|
||||
public get name(): GeneralName {
|
||||
return this._raw.name;
|
||||
}
|
||||
|
||||
public update(callback: (oldRaw: IGeneralEntity) => void, force = false) {
|
||||
|
||||
const oldCityID = this._raw.cityID;
|
||||
const oldTroopID = this._raw.troopID;
|
||||
const oldNationID = this._raw.nationID;
|
||||
|
||||
callback(this._raw);
|
||||
|
||||
if(!force){
|
||||
if(oldCityID !== this._raw.cityID){
|
||||
throw new Error("City change by update() is not allowed");
|
||||
}
|
||||
if(oldTroopID !== this._raw.troopID){
|
||||
throw new Error("Troop change by update() is not allowed");
|
||||
}
|
||||
if(oldNationID !== this._raw.nationID){
|
||||
throw new Error("Nation change by update() is not allowed");
|
||||
}
|
||||
}
|
||||
this.resourceController.setDirtyGeneral(this._raw);
|
||||
}
|
||||
|
||||
public changeCity(city: CityID | City){
|
||||
const cityObj: City = (()=>{
|
||||
if(city instanceof City){
|
||||
return city;
|
||||
}
|
||||
const cityObj = this.resourceController.getCity(city);
|
||||
if(!cityObj){
|
||||
throw new InvalidArgument(`City not found: ${city}`);
|
||||
}
|
||||
return cityObj;
|
||||
})();
|
||||
this._city = new WeakRef(cityObj);
|
||||
|
||||
//TODO: ResourceController에게 알려야 하는가?
|
||||
this.update((raw) => {
|
||||
raw.cityID = cityObj.id;
|
||||
}, true);
|
||||
}
|
||||
|
||||
public quitTroop(){
|
||||
if(!this._troop){
|
||||
return;
|
||||
}
|
||||
|
||||
const troop = must(this._troop.deref());
|
||||
if(troop.leader.id === this._raw.id){
|
||||
troop.destructTroop(false);
|
||||
}
|
||||
else{
|
||||
troop.members.delete(this._raw.id);
|
||||
}
|
||||
|
||||
this._troop = undefined;
|
||||
this.update((raw) => {
|
||||
raw.troopID = undefined;
|
||||
}, true);
|
||||
}
|
||||
|
||||
public changeTroop(troop: TroopID | Troop){
|
||||
this.quitTroop();
|
||||
|
||||
const troopObj: Troop = (()=>{
|
||||
if(troop instanceof Troop){
|
||||
return troop;
|
||||
}
|
||||
const troopObj = this.resourceController.getTroop(troop, this._raw.nationID);
|
||||
if(!troopObj){
|
||||
throw new InvalidArgument(`Troop not found: ${troop}`);
|
||||
}
|
||||
return troopObj;
|
||||
})();
|
||||
|
||||
troopObj.members.set(this._raw.id, new WeakRef(this));
|
||||
this._troop = new WeakRef(troopObj);
|
||||
this.update((raw) => {
|
||||
raw.troopID = troopObj.id;
|
||||
}, true);
|
||||
}
|
||||
|
||||
public changeNation(nation: NationID | Nation){
|
||||
const nationObj: Nation = (()=>{
|
||||
if(nation instanceof Nation){
|
||||
return nation;
|
||||
}
|
||||
const nationObj = this.resourceController.getNation(nation);
|
||||
if(!nationObj){
|
||||
throw new InvalidArgument(`Nation not found: ${nation}`);
|
||||
}
|
||||
return nationObj;
|
||||
})();
|
||||
this._nation = new WeakRef(nationObj);
|
||||
this.quitTroop();
|
||||
|
||||
this.update((raw) => {
|
||||
raw.nationID = nationObj.id;
|
||||
raw.diplomaticPermission = DiplomaticPermission.none;
|
||||
if(nationObj.id == 0){
|
||||
raw.officerLevel = OfficerLevel.none;
|
||||
}
|
||||
else{
|
||||
raw.officerLevel = OfficerLevel.normal;
|
||||
}
|
||||
raw.nationBelong = 0;
|
||||
}, true);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user