123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- class GameLocation{
- _isPublic = false; get isPublic(){return this._isPublic;}
- _isOutdoors = false; get isOutdoors(){return this._isOutdoors;}
- _isHome = false; get isHome(){return this._isHome;}
- _region = ''; get region(){return this._region;}
- _passage = '';
- _passageArguments = []; get passageArguments(){return this._passageArguments;}
- _passageQueue = [];
- _passageQueueMaxLength = 3;
- get locationIdentifier():LocationIdentifier{
- return new LocationIdentifier(this.passage,this.passageArguments);
- }
- set locationIdentifier(v:LocationIdentifier){
- this.update(v.passage,v.passageArguments);
- }
- get passage(){return this._passage;}
- set passage(v:string){
- if(typeof v != "string")
- {
- console.error('Location set to invalid passage:',v);
- return;
- }
- if(!Story.has(v)){
- console.error('Location set to non-existing passage:',v);
- return;
- }
- this._passageQueue.push(this._passage);
- while(this._passageQueue.length > this._passageQueueMaxLength) this._passageQueue.shift();
- this._passage = v;
- let passage_tags = tags(v);
- if(passage_tags.includes('indoors'))
- this._isOutdoors = false;
- else if(passage_tags.includes('outdoors'))
- this._isOutdoors = true;
- else
- console.warn("Location-passage does not contain an indoors- or outdoors-tag:",v);
- if(passage_tags.includes('private'))
- this._isPublic = false;
- else if(passage_tags.includes('public'))
- this._isPublic = true;
- else
- console.warn("Location-passage does not contain a private- or public-tag:",v);
- let homeTag = State.variables.housing.home;
- this._isHome = passage_tags.includes(homeTag);
- for(let tag of passage_tags){
- if(tag.startsWith('region_')){
- this._region = tag.replace('region_','');
- break;
- }
- }
- }
-
- /**
- * A unique identifier for the place the player is at.
- * @readonly
- * @type {string}
- */
- get here(){
- return this.passage;
- }
- get hasWardrobeAccess(){
- return this.isHome || this.tags.includes('wardrobe');
- }
- get tags(){
- return tags(this.passage);
- }
- #constantLocationData(locationId:string):LocationDefinition{
- return setup.getLocation(locationId);
- }
- _locationValues = {};
- get<T extends any>(locationId:string,field:string,def:T):T{
- const constData = this.#constantLocationData(locationId);
- const dynamicData = this._locationValues[locationId] ?? {};
- const combinedData = Object.assign({},constData,dynamicData);
- return combinedData[field] ?? def;
- }
- getHere(field:string,def:any=false){
- return this.get(this.here,field,def);
- }
- inc(locationId:string,field:string,v=1){
- this.set(locationId,field,this.get(locationId,field,0)+v);
- }
- set(locationId:string,field:string,v:any){
- this._locationValues[locationId] ??= {};
- this._locationValues[locationId][field] = v;
- }
- setHere(field:string,v:any){
- this.set(this.here,field,v);
- }
-
- /**
- * Updates the current location and passage arguments.
- * @param {string} locationId
- * @param {Array<any>} [locationArguments=[]]
- */
- update(locationId:string,locationArguments:Array<any>=[]){
- this.passage = locationId;
- this._passageArguments = locationArguments;
- }
- //#region Furniture
- get furniture(){
- return this.getHere('furniture',{});
- }
- hasFurniture(furnitureId:string){
- return (furnitureId in this.furniture);
- }
- removeFurniture(furnitureId:string){
- let furniture = this.furniture;
- delete furniture[furnitureId];
- this.setHere('furniture',furniture);
- }
- updateFurniture(furnitureId:string,updateObject:object){
- let furniture = this.furniture;
- furniture[furnitureId] = setup.mergeDeep(furniture[furnitureId] ?? {},updateObject);
- this.setHere('furniture',furniture);
- }
- //#endregion
- //#region OpenTime
- isOpen(locationId: string=undefined){
- locationId ??= this.passage;
- const openTimes:TimespanIdentifier = this.get(locationId,'openTimes',{});
- return State.variables.time.timespanIdentifierMatches(openTimes);
- }
- openingTimesStr(locationId: string=undefined){
- locationId ??= this.passage;
- const openTimes:TimespanIdentifier = this.get(locationId,'openTimes',{});
- return State.variables.time.timespanIdentifierToString(openTimes);
- }
- //#endregion
- //#region TagValues
- _tagValues={};
- getTagValue(tag:string,field:string,def:any=undefined){
- return (this._tagValues[tag]?.[field] ?? def);
- }
- getTagsValues(tags:string[],field:string,def:any=undefined):any[]{
- let result = [];
- for(const tag of tags){
- result.push(this.getTagValue(tag,field,def));
- }
- return result;
- }
- getTagsValuesHere(field:string,def:any=undefined):any[]{
- return this.getTagsValues(this.tags,field,def);
- }
- /*getTagsValuesAccumulated(tags:string[],field:string,acummulation:string):any{
- switch (acummulation) {
- case '||':
- let val_or = this.getTagsValues(tags,field,false);
- return val_or.includes(true);
- case '&&':
- let val_and = this.getTagsValues(tags,field,false);
- return !val_and.includes(false);
- case 'latest':
- const startdate = new Date(0);
- let val_latest:Date[] = this.getTagsValues(tags,field,startdate);
- return val_latest.reduce(
- (previous,current)=>new Date(
- Math.max(
- previous.getTime(),
- current.getTime()
- )
- )
- ,startdate);
- default:
- break;
- }
- }*/
- setTagValue(tag:string,field:string,tagValue:any){
- this._tagValues[tag] ??= {};
- this._tagValues[tag][field] = tagValue;
- }
- //#endregion
- //#region System
- _init(location){
- Object.keys(location).forEach(function (pn) {
- this[pn] = clone(location[pn]);
- }, this);
- return this;
- }
- clone = function () {
- return (new setup.Location())._init(this);
- };
- toJSON = function () {
- var ownData = {};
- Object.keys(this).forEach(function (pn) {
- if(typeof this[pn] !== "function")
- ownData[pn] = clone(this[pn]);
- }, this);
- return JSON.reviveWrapper('(new setup.Location())._init($ReviveData$)', ownData);
- };
- //#endregion
- }
- setup.Location = GameLocation;
|