123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778 |
- /// <reference path="NPCAccessor.ts" />
- const npcFieldBoundaries = {
- rel:{min:0,max:100}
- }
- let pronounDictLowerCase = {
- 'he': ['he','she'],
- 'him': ['him','her'],
- 'his': ['his','her'],
- 'himself': ['himself','herself'],
- }
- let pronounDictUpperFirst = {};
- let pronounDictUpperCase = {};
- for (const [key, value] of Object.entries(pronounDictLowerCase)) {
- pronounDictUpperFirst[key.toUpperFirst()] = [value[0].toUpperFirst(),value[1].toUpperFirst()];
- pronounDictUpperCase[key.toUpperCase()] = [value[0].toUpperCase(),value[1].toUpperCase()];
- }
- const pronounDict = Object.assign({},pronounDictLowerCase,pronounDictUpperFirst,pronounDictUpperCase);
- /*
- NPC-Fields:
- date:
- date.count:
- n: Number of dates one had with the NPC.
- During a date, it indicates that it is the nth date
- date.kissed:
- n: Number of times one has kissed the NPC.
- date.nextDateExpected:
- -1: does not expect a date and won't call asking for one
- most commonly set to -1 because a date is already scheduled
- n: will start calling at day n and ask for a date
- rel: Relationship Value / how much the NPC likes you
- familiarity:
- 0 - stranger
- 1000 - knows everything about each other
- */
- class NPCsDict{
- _dynamicData = {}
- _generatedIds = [];
- _generatedIdsCounter = 0;
- _boyfriends = [];
- dec(npcId,field,v,min=-Infinity,max=Infinity){
- this.inc(npcId,field,v * -1,min,max);
- }
-
-
- /**
- * Creates a new NPC and returns his ID.
- * @param {string} purpose the reason the NPC exists. If all purposes are removed, it is flagged for removal.
- * @returns {string}
- */
- create(purpose:string='static'):string{
- this._generatedIdsCounter += 1;
- let id = 'C'+this._generatedIdsCounter;
- this._generatedIds.push(id);
- this.set(id,'_purposes',[purpose]);
- return id;
- }
- createNPC(purpose:string='static'):NPC{
- return this.npc(this.create(purpose));
- }
- delete(npcID:string):void{
- delete this._dynamicData[npcID];
- this._generatedIds.delete(npcID);
- }
- generate(purpose:string,flags:NPCGenerateOptions):NPC{
- return setup.generateNPC(this,purpose,flags);
- }
-
- /**
- * Get a value of a field for a NPC.
- *
- * Will use dynamic data, if present. Otherwise, will use constant data. If constant data is not defined, will try passage data.
- *
- * @param {string} npcId
- * @param {string} field
- * @param {*} [def=undefined]
- * @returns {*}
- */
- get(npcId:string,field:string,def:any=undefined):any{
- let data = this.npcData(npcId);
- if(field in data)
- return data[field];
- if("passage" in data){
- let resultFromPassage = setup.func(data.passage,'vars',field);
- if(resultFromPassage)
- return resultFromPassage;
- }
-
- return def;
- }
-
- getDynamicData(npcId){
- if(npcId in this._dynamicData)
- return this._dynamicData[npcId];
- return {};
- }
- getStaticData(npcId){
- if(npcId in setup.npcs)
- return setup.npcs[npcId];
- return {};
- }
- inc(npcId,field,v:string|number,min=-Infinity,max=Infinity){
- let d:string|number = '';
- if(typeof v === "number")
- d = 0;
- let current = this.get(npcId,field,d);
- let newValue = current + v;
-
- newValue = Math.min(Math.max(current,max),newValue);
- newValue = Math.max(Math.min(current,min),newValue);
- this.set(npcId,field,newValue);
- }
- incBulk(npcIds,field,v,min=-Infinity,max=Infinity){
- for(let npcId of npcIds){
- this.inc(npcId,field,v,min,max);
- }
- }
- incBulkByFilter(filter={},field,v,min=-Infinity,max=Infinity){
- let npcsIds = this.ids(filter);
- this.incBulk(npcsIds,field,v,min,max);
- }
- ids(filter={}){
- let keysStatic = Object.keys(setup.npcs);
- let keysDynamic= Object.keys(this._dynamicData);
- let keys = keysStatic.concatUnique(keysDynamic);
- if(jQuery.isEmptyObject(filter))
- return keys;
- let keysMatchingFilter = [];
- for(let key of keys){
- if(this.npcFitsFilter(key,filter))
- keysMatchingFilter.push(key);
- }
- return keysMatchingFilter;
- }
- makeBoyfriend(npcId){
- if(this._boyfriends.includes(npcId)){
- console.warn('Already boyfriend:',npcId);
- return;
- }
- this.set(npcId,'keepAlive',true);
- let defaults = this.get(npcId,'defaults',[]);
- defaults.push('boyfriend');
- this.set(npcId,'defaults',defaults);
- this._boyfriends.push(npcId);
- }
- memoryUpdate(npcId){
- let rememberedFields = this.get(npcId,'memoryVars',[]);
- if(!rememberedFields.length)
- return;
- let now = State.variables.time.now;
- let memory = {time:now,vars:{}};
- for(let rememberedField of rememberedFields){
- memory.vars[rememberedField] = State.getVar(rememberedField);
- }
- this.set(npcId,'memory',memory);
- console.log('NPC memory updated',npcId,memory);
- }
- memoryUpdateAll(){
- const npcIds = this.ids();
- for(const npcId of npcIds){
- this.memoryUpdate(npcId);
- }
- }
- npc(npcId:string):NPC{
- return new Proxy(new NPCAccessor(npcId),NPCAccessor.handler);
- }
- npcData(npcId){
- let staticData = this.getStaticData(npcId);
- let dynamicData = this.getDynamicData(npcId);
- let data = Object.assign({},staticData,dynamicData);
- if("gender" in data)
- data = Object.assign({},setup.npcDefaults.gender[data.gender],data); //Apply the gender-defaults first.
- if("defaults" in data){
- for(let defaultId of data.defaults){
- let def = setup.npcDefaults[defaultId];
- data = Object.assign({},def,data); //Apply the defaults first. They could be overwritten by static or dynamic data
- }
- }
- return data;
- }
- npcFitsFilter(npcId,filters:{[key:string]:any}={}){
- outerLoop:for (const [filterKey, filterValue] of Object.entries(filters)) {
- let npcValue = undefined;
- if(typeof filterValue === "object" && filterValue.filter){
-
- switch(filterValue.filter){
- case 'minMax':
- let min = filterValue.min ?? -Infinity;
- let max = filterValue.max ?? Infinity;
- npcValue = this.get(npcId,filterKey,0);
- if(npcValue > max || npcValue < min)
- return false;
- continue outerLoop;
- }
- }
- else if(typeof filterValue === "number")
- npcValue = this.get(npcId,filterKey,0);
- else
- npcValue = this.get(npcId,filterKey,'');
- if(npcValue != filterValue){
- return false;
- }
- }
- return true;
- }
- npcLikesAppearance(npcId):boolean{
- let appearanceDemand = this.get(npcId,'appearanceDemand',[null,null,5]);
- let hotcat = State.variables.pc.appearance;
- if(appearanceDemand[0] !== null && hotcat.geneticValue < appearanceDemand[0]) return false;
- if(appearanceDemand[1] !== null && hotcat.lastingValue < appearanceDemand[1]) return false;
- if(appearanceDemand[2] !== null && hotcat.currentValue < appearanceDemand[2]) return false;
-
- let preferenceBalance = this.preferenceBalance(npcId);
- return (preferenceBalance >= 0);
-
- }
-
- /**
- * Hof much the NPC likes / dislikes the PCs current appearance based on preferences.
- * @date 8/30/2023 - 9:43:26 AM
- *
- * @param {string} npcId
- * @returns {number}
- */
- preferenceBalance(npcId):number{
- let preferenceValues = this.preferencesCompare(npcId);
- return Object.values(preferenceValues).reduce((a,x) => a+x, 0);
- }
-
- preferencesComment(npcId,positives=[],negatives=[],today=undefined){
- today ??= State.variables.time.daystart;
- if(positives === null)
- positives = [];
- else if(!Array.isArray(positives))
- positives = [positives];
- if(negatives === null)
- negatives = [];
- else if(!Array.isArray(negatives))
- negatives = [negatives];
- const positiveValue = today;
- const negativeValue = today * -1;
- let comments = this.get(npcId,'preferenceComments',{});
- positives.forEach(e => {comments[e] = positiveValue;});
- negatives.forEach(e => {comments[e] = negativeValue;});
- this.set(npcId,'preferenceComments',comments);
- console.log('NPC Preferences Comments updated',npcId,comments);
- }
- /**
- * Returns an object with all the preferenceIds of the requested NPC as keys and the days since they were commented on as values (negative if the comment was a negative one). The value is null for each preference which was never commented.
- * @date 8/21/2023 - 9:01:37 AM
- *
- * @param {*} npcId The Id of the NPC you want to get the result for.
- * @returns {{}}
- */
- preferenceCommentOffset(npcId,today=undefined){
- today ??= State.variables.time.daystart;
- let result = {};
- let comments = this.get(npcId,'preferenceComments',{});
- let preferences = this.get(npcId,'preference');
- for (const preferenceId of Object.keys(preferences)) {
- if(!(preferenceId in comments)){
- result[preferenceId] = null;
- continue;
- }
- // dayRaw is negative if the NPCs last comment on this issue was a negative one
- let dayRaw = comments[preferenceId];
- let day = Math.abs(dayRaw);
- let commentDirection = Math.sign(dayRaw);
- let dayOffset = today - day;
- result[preferenceId] = (dayOffset + 1) * commentDirection; //+1 so the value isn't 0 for today, which would make it impossible to distinguish between a positive and a negative comment
- }
- return result;
- }
- preferenceCommentWeighted(npcId:string):any{
- let preferenceCommentOffset = this.preferenceCommentOffset(npcId);
- let preferencesCompare = this.preferencesCompare(npcId);
- let preferences = {
- positive:{
- currentMatches: Object.fromEntries(Object.entries(preferencesCompare).filter(([k,v])=>v>0))
- },
- negative:{
- currentMatches: Object.fromEntries(Object.entries(preferencesCompare).filter(([k,v])=>v<0))
- }
- }
- for(let positive_negative of ['positive','negative']){
- preferences[positive_negative].switched = {}; // Priority 1: The NPC made a negative comment before and his opinion is now positive or vice versa.
- preferences[positive_negative].neverCommented = {}; // Priority 2: The NPC never commented this specific aspect.
- preferences[positive_negative].repeat = {}; // Priority 3: The NPC has the same opinion as before and states it again.
- for (const [preferenceId, value] of Object.entries(preferences[positive_negative].currentMatches)) {
- // Value is the number that represents how negative or positive the opinion is
- if(typeof value != "number")
- continue;
- let opinionMagnitude = Math.abs(value);
- let opinionIsPositive = Math.sign(value); //-1: Negative, 1: Positive
- let commentOffsetRaw = preferenceCommentOffset[preferenceId];
- if(commentOffsetRaw === null)
- preferences[positive_negative].neverCommented[preferenceId] = opinionMagnitude;
- else{
- let daysSinceLastCommend = Math.abs(commentOffsetRaw);
- let lastCommentWasPositive = Math.sign(commentOffsetRaw);
- if(opinionIsPositive != lastCommentWasPositive)
- preferences[positive_negative].switched[preferenceId] = opinionMagnitude * daysSinceLastCommend;
- else
- preferences[positive_negative].repeat[preferenceId] = opinionMagnitude * daysSinceLastCommend;
- }
- }
- }
- return preferences;
- /*let preferences = {
- positive: Object.fromEntries(Object.entries(preferencesCompare).filter(([k,v])=>v>0)),
- negative: Object.fromEntries(Object.entries(preferencesCompare).filter(([k,v])=>v<0))
- }
- let switchedTo = {positive:{},negative:{}};
- let neverCommentedOn = {positive:{},negative:{}};
- let other = {positive:{},negative:{}};
- for(let pn of ['positive','negative']){
- for (const [preferenceId, value] of Object.entries(preferences[pn])) {
- let commentOffset = preferenceCommentOffset[preferenceId];
- if(commentOffset === null)
- neverCommentedOn[pn][preferenceId] = value;
- else{
- let daysSinceComment = Math.abs(commentOffset);
- if(Math.sign(commentOffset) == Math.sign(value))
- switchedTo[pn][preferenceId] = value * daysSinceComment;
- else{
- other[pn][preferenceId] = value * daysSinceComment;
- }
- }
- }
- }*/
- //return [preferencesCompare,preferencesPositive,preferencesNegative];
- }
- preferencesToCommentNow(npcId){
- /*let preferenceCommentWeighted = this.preferenceCommentWeighted(npcId);
- let positive = null;
- let negative = null;
- let positiveResult = null;
- let negativeResult = null;
- let positiveResultType = null;
- let negativeResultType = null;
- if(Object.keys(preferenceCommentWeighted.positive.neverCommented).length > 0){
- positive = preferenceCommentWeighted.positive.neverCommented;
- positiveResultType = 'n';
- }else if(Object.keys(preferenceCommentWeighted.positive.switched).length > 0){
- positive = preferenceCommentWeighted.positive.switched;
- positiveResultType = 's';
- }else if(Object.keys(preferenceCommentWeighted.positive.repeat).length > 0){
- positive = preferenceCommentWeighted.positive.repeat;
- positiveResultType = 'r';
- }
- if(Object.keys(preferenceCommentWeighted.negative.switched).length > 0){ // Switch has a higher priority than uncommented for negative. It's the opposite fpr positive
- negative = preferenceCommentWeighted.negative.switched;
- negativeResultType = 's';
- }else if(Object.keys(preferenceCommentWeighted.negative.neverCommented).length > 0){
- negative = preferenceCommentWeighted.negative.neverCommented;
- negativeResultType = 'n';
- }else if(Object.keys(preferenceCommentWeighted.negative.repeat).length > 0){
- negative = preferenceCommentWeighted.negative.repeat;
- negativeResultType = 'r';
- }
- // https://stackoverflow.com/a/1069840
- if(positive){
- const positiveSorted = Object.entries(positive)
- .sort(([,a],[,b]) => b-a);
- positiveResult = positiveSorted.first()[0];
- }
- if(negative){
- const negativeSorted = Object.entries(negative)
- .sort(([,a],[,b]) => b-a);
- negativeResult = negativeSorted.first()[0];
- }
- let balance = Object.values(preferenceCommentWeighted.positive.currentMatches).reduce((a, b) => {return a + b;},0)
- + Object.values(preferenceCommentWeighted.negative.currentMatches).reduce((a, b) => {return a + b;},0);
- return {
- positive: positiveResult,
- positiveResultType: positiveResultType,
- negative: negativeResult,
- negativeResultType:negativeResultType,
- balance: balance
- }*/
- //TODO
- }
-
- /**
- * Checks Preferences of a NPC and returns an object with key: preference id, value: magnitued of success (positive) or failure (negative).
- * @date 8/30/2023 - 7:20:46 AM
- *
- * @example
- * //Returns {"short_skirt_d": 1}
- * @param {*} npcId
- * @returns {{}}
- */
- preferencesCompare(npcId):{[key: string]:number}{
-
- /*let result = {};
- let preferences = this.get(npcId,'preference');
- for (const [preferenceId, value] of Object.entries(preferences)) {
- let preferenceData = setup.npcPreferences[preferenceId];
- if(!preferenceData){
- console.warn('Preference not found:',preferenceId);
- continue;
- }
- let valueSucceeded = value;
- let valueFailed = -value;
- let valueNeutral = 0;
- if(Array.isArray(value)){
- valueSucceeded = value[0];
- valueFailed = value[1];
- }
- if(!preferenceData.s)
- result[preferenceId] = valueSucceeded;
- else if(Scripting.evalTwineScript(preferenceData.s))
- result[preferenceId] = valueSucceeded;
- else if(preferenceData.f && Scripting.evalTwineScript(preferenceData.f))
- result[preferenceId] = valueFailed;
- else
- result[preferenceId] = valueNeutral;
- }
- return result;*/
- //TODO
- return {};
- }
- prerencesKnown(npcId){
- let result = {};
- let preference = this.get(npcId,'preference',{});
- let preferenceComments = this.get(npcId,'preferenceComments',{});
- for(var preferenceKey of Object.keys(preferenceComments)){
- result[preferenceKey] = preference[preferenceKey];
- }
- return result;
- }
- pronoun(npcId,pronoun){
- let gender = this.get(npcId,'gender',0);
- if(pronoun in pronounDict)
- return pronounDict[pronoun][gender];
- return 'GENDER KEY MISSING: '+pronoun+'['+gender+']';
- }
- rel(npcId){
- this.relUpdate(npcId);
- return this.get(npcId,'rel');
- }
-
- /**
- * Increases the relationships of a npc by inc. Diminishing return applied.
- * @deprecated
- * @param {string} npcId The ID of the NPC
- * @param {number} inc The amount by which to increase. Negative numbers decrease the relationship
- * @param {Array} boundaries Won't increase/decrease past these values. Format: [min,max]
- * @param {number} today Daystart of the current day. Used for diminishing return algorithm.
- */
- relInc(npcId,inc,boundaries=[0,100],today=undefined){
- console.warn('Use of $npcs.relInc is deprecated. Use <<relationship>> instead');
- let relGrace = 2; //The change that won't be diminished
- let boundaryLower = boundaries[0];
- let boundaryUpper = boundaries[1];
- today ??= State.variables.time.daystart;
- let rel_current = this.get(npcId,'rel',50);
- if(!inc)
- return;
- if(inc > 0 && rel_current >= boundaryUpper)
- return;
- if(inc < 0 && rel_current <= boundaryLower)
- return;
-
- let rel_date = this.get(npcId,'rel_date',undefined);
- let rel_base = undefined;
- let rel_change_raw = 0;
- if(!rel_date || rel_date != today){
- this.set(npcId,'rel_date',today);
- this.set(npcId,'rel_base',rel_current);
- rel_base = rel_current;
- }else{
- rel_base = this.get(npcId,'rel_base');
- rel_change_raw = this.get(npcId,'rel_change_raw');
- }
- rel_change_raw += inc;
- this.set(npcId,'rel_change_raw',rel_change_raw);
- let rel_new = 0;//TODO: setup.diminishingReturn(rel_base,rel_base + rel_change_raw,relGrace,'sqrt');
- if(inc > 0)
- rel_new = Math.min(rel_new,boundaryUpper);
- else if(inc < 0)
- rel_new = Math.max(rel_new,boundaryLower);
- this.set(npcId,'rel',rel_new);
- }
- relUpdate(npcId){
- const time = State.variables.time;
- const dayStart = time.daystart;
- const lastRelUpdate = this.get(npcId,'relu',-1);
- let currentRel = this.get(npcId,'rel');
- let lastingRel = this.get(npcId,'rell',currentRel);
- if(lastRelUpdate == -1){
- this.set(npcId,'rell',lastingRel);
- this.set(npcId,'relu',dayStart);
- return;
- }
- if(dayStart <= lastRelUpdate)
- return;
-
- for(let updateDay = lastRelUpdate; updateDay < dayStart; updateDay++){
- let relDifference = currentRel - lastingRel;
- let changeInLastingRel = Math.ceilAbs(relDifference / 10);
- lastingRel += changeInLastingRel;
- relDifference = lastingRel - currentRel;//note opposite order
- let changeInCurrentRel = Math.ceilAbs(relDifference / 4);
- currentRel += changeInCurrentRel;
- }
- this.set(npcId,'rel',currentRel);
- this.set(npcId,'rell',lastingRel);
- this.set(npcId,'relu',dayStart);
- }
- set(npcId,field,v){
- if(!(npcId in this._dynamicData))
- this._dynamicData[npcId] = {};
- if(field in npcFieldBoundaries){
- let fieldRules = npcFieldBoundaries[field];
- if("min" in fieldRules)
- v = Math.max(v, fieldRules.min);
- if("max" in fieldRules)
- v = Math.min(v, fieldRules.max);
- }
-
- this._dynamicData[npcId][field] = v;
-
- console.log("NPC value set",npcId,field,v);
- }
- //npcIds: Array of ids
- setBulk(npcIds,field,v){
- for(let npcId of npcIds){
- this.set(npcId,field,v);
- }
- }
- setBulkByFilter(filter={},field,v){
- let npcsIds = this.ids(filter);
- this.setBulk(npcsIds,field,v);
- }
- // ----- Dating -----
- _datingNPCs = [];
- get datingNPCs(){return this._datingNPCs;}
- // Only sets the NPC to dating. Does not make him call you at any point. Use <<datingStart>> for this.
- datingStart(npcID){
- console.log("Start Dating:",npcID);
- this._datingNPCs.push(npcID);
- this.set(npcID,'dating',true);
- }
- //#region Activity
- activity(npcId:string):NPCActivity{
- let activityInformationCached:ExpiringVar<NPCActivity>|null = this.get(npcId,'activity',null);
- if(!State.variables.time.isExpired(activityInformationCached))
- return activityInformationCached.val;
- return this.#updateActivity(npcId).val;
- }
- /**
- * Returns whether the given NPC is at the given activity.
- *
- * @param {string} npcId
- * @param {string|string[]} activity
- * @param {string} [location=undefined]
- * @returns {boolean}
- */
- atActivity(npcId:string,activity:string|string[],location=undefined){
- const locationInformation = this.activity(npcId);
- if(!locationInformation.activity)
- return false;
- if(location && locationInformation.location != location)
- return false;
- if(Array.isArray(activity))
- return locationInformation.activity.includesAll(activity);
- return locationInformation.activity.includes(activity);
- }
-
- /**
- * Ends the current activity and starts the next one.
- * @param {string} npcId
- * @param {string} [activity=undefined]
- * @returns {NPCActivity}
- */
- endActivity(npcId:string,activity:string|string[]=undefined):NPCActivity{
- if(activity && !this.atActivity(npcId,activity))
- return this.activity(npcId);
- let activityInformationCached:ExpiringVar<NPCActivity>|null = this.get(npcId,'activity',null);
-
- if(!activityInformationCached)
- return this.#updateActivity(npcId).val;
- const expirationOfCurrentActivity = activityInformationCached.til;
- return (this.#updateActivity(npcId,expirationOfCurrentActivity)).val;
-
-
- /*const timeWhenNextActivityStarts = new Date(currentActivity.end.getTime()+1);
- this._updateLocation(npcId,timeWhenNextActivityStarts);
- return this.location(npcId);*/
- }
-
- /**
- * @deprecated
- * @param {*} npcId
- * @returns {NPCActivity}
- */
- location(npcId){
- return this.activity(npcId);
- }
- locationGroup(npcIds:string[]):{[locationId:string]:{[npcId:string]:NPCActivity}}{
- let locations:{[key:string]:any} = {};
- for(let npcId of npcIds){
- let activity = this.activity(npcId);
- locations[activity.location] ??= {};
- locations[activity.location][npcId] = activity;
- }
- return locations;
- }
- #updateActivity(npcId,dateTime:Date=undefined):ExpiringVar<NPCActivity>{
- let newActivity:NPCActivity = {location:'',activity:[]};
- let newExpiration = new Date(0);
- const time = State.variables.time;
- dateTime ??= time.now;
- const timeTable:Timetable<NPCActivity> = this.get(npcId,'timetable',null);
- const twoResultsFromTimeTable = time.timetableLookupMultiple(timeTable,dateTime,2);
- const currentActivity = twoResultsFromTimeTable[0];
- const nextActivity = twoResultsFromTimeTable[1];
- let result = {
- til: nextActivity.beginDate,
- val: currentActivity.val
- };
- this.set(npcId,'activity',result);
- return result;
- }
- //#endregion
- //#region System
- constructor(){}
- _init(nPCsDict){
- Object.keys(nPCsDict).forEach(function (pn) {
- this[pn] = clone(nPCsDict[pn]);
- }, this);
- return this;
- }
- clone = function () {
- return (new NPCsDict())._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 NPCsDict())._init($ReviveData$)', ownData);
- };
- //#endregion
- }
- window.NPCsDict = NPCsDict;
|