So, I came up with the beginnings of an event system. My idea is to form a timestamp each and every passage and to use that to see if an event is still on-going or not, and if not, to cull it. I guess I'll call it something like TopicalListUpdate or so.
But, I haven't done that bit yet. I've just done the timestamp stuff. So code:
setup.makeTimestamp = function () {
var sv = State.variables;
return Number(""
+ sv.time.years.toString()
+ (sv.time.months < 10 ? "0" + sv.time.months.toString() : sv.time.months.toString())
+ (sv.time.days < 10 ? "0" + sv.time.days.toString() : sv.time.days.toString())
+ (sv.time.hours < 10 ? "0" + sv.time.hours.toString() : sv.time.hours.toString())
+ (sv.time.minutes < 10 ? "0" + sv.time.minutes.toString() : sv.time.minutes.toString()));
};
Is this an OK function to have essentially running at the start of every passage?
The way I'm storing time would mean a lot more comparing between different elements to determine if an event has expired or not. With the timestamp, that comparison is just a simple number comparison. So, I think I win that way, since there's far less comparisons to do (each passage).
Another thing I was thinking of implementing is a sorted array with all these timstamps. The timestamp is just a number, 201709302100 for instance. And I'm pretty sure I can maintain an array of smallest to biggest numbers in it. For comparison, I have a while loop to compare the numbers until it encounters one that's bigger.
Time moves along discretely, with passage after passage. I just make the time up. A few minutes here, some hours there. So, between passages, a whole lot of time could have passed. And the topical stuff that had been present in the last passage aren't valid anymore. Hence the culling.
Or that's the idea I'm running with.
So, not only this timestamp function, but a while loop comparing a sorted event list. These two done at the start of each turn. A good way? Or too complex? Or is there a sneaky better way?
What stage would it be best to do these kinds of calculation in? predisplay? prerender?
I guess it has a baring, since what's displayed in the main passage will be determined by what's still in the list. I think. So, opinion? Here's another timestamp, just so we're clear with what these look like: 201805070923. They're just numbers. I'm thinking... I add durations to them too, to elevate the timestamp to when an event can/should expire. But, that's something to do in a little bit.
===
With the event array, what if I had the events as objects? I figure at any given passage, more than just one event might trigger, so you'd have multiple events with the same "identifying" timestamp. To guard against this, maybe we put a tag in as well. Like this:
<<set $pcTopicalEventList.pushUnique({ timestamp: setup.makeTimestamp(), tag: "groundedTAG" })>>
So, I already know that pushUnique won't do its job with complex objects. Do I need to roll my own? Or is it better to just put these into an object container and use object methods to search, modify, delete? The main disadvantage with that is, that I'd need to run through the whole containing object to make sure I accounted for all the events, not just the first ones in an ordered array. So... what think?
===
So, I came up with some more code. And it seems to do what I was aiming for:
setup.setTimestamp = function () {
var sv = State.variables;
sv.time.timestamp = Number(""
+ sv.time.years.toString()
+ (sv.time.months < 10 ? "0"
+ sv.time.months.toString() : sv.time.months.toString())
+ (sv.time.days < 10 ? "0"
+ sv.time.days.toString() : sv.time.days.toString())
+ (sv.time.hours < 10 ? "0"
+ sv.time.hours.toString() : sv.time.hours.toString())
+ (sv.time.minutes < 10 ? "0"
+ sv.time.minutes.toString() : sv.time.minutes.toString()));
};
setup.formatDuration = function () {
var sv = State.variables;
var minutes = sv.time.minutes,
hours = sv.time.hours,
days = sv.time.days,
months = sv.time.months,
years = sv.time.years;
if (arguments[1] != null) {
minutes = minutes + arguments[1];
if (minutes > 59) {
minutes = minutes - 59;
hours++;
}
}
if (arguments[0] != null) {
hours = hours + arguments[0];
if (hours > 23) {
hours = hours - 23;
days++;
}
}
if (arguments[2] != null) {
days = days + arguments[2];
if (days > setup.calendar[years][months].days) {
days = days - setup.calendar[years][months].days;
months++;
}
}
if (arguments[3] != null) {
months = months + arguments[3];
if (months > 12) {
months = months - 12;
years++;
}
}
if (arguments[4] != null) {
years = years + arguments[4];
}
return Number(""
+ years.toString()
+ (months < 10 ? "0" + months.toString() : months.toString())
+ (days < 10 ? "0" + days.toString() : days.toString())
+ (hours < 10 ? "0" + hours.toString() : hours.toString())
+ (minutes < 10 ? "0" + minutes.toString() : minutes.toString()));
};
And this is what I'm using to test with:
<<timeSet 21 0 30>>
<<= $time.timeString + ", " + $time.dayString>>
<<run setup.setTimestamp()>>
<<= $time.timestamp>>
<<set $pcTopicalEventList.pushUnique({ duration: setup.formatDuration(0, 4, 2, 1, 1), tag: "anniversaryTAG" })>>
<<timeSet 9 23 7 5 2018>>
<<= $time.timeString + ", " + $time.dayString>>
<<run setup.setTimestamp()>>
<<= $time.timestamp>>
<<set $pcTopicalEventList.pushUnique( {timestamp: setup.formatDuration(), tag: "dunnoTAG" })>>
So, this produces strings like:
"pcTopicalEventList": [
{
"duration": 201811022104,
"tag": "anniversaryTAG"
},
{
"timestamp": 201805070923,
"tag": "dunnoTAG"
}
]
Now, assuming the time advances enough to make those future times less than the current timestamp, we can delete them or whatever. Am I on the right track with this? Or is it just some unnecessary busy work?
===
The actual format of the list object I was thinking of using for the events, is something like this:
{
dura: 0,
tag: "",
level: 0,
desc: ""
}
Although, I'm not sure how to handle different levels. Like, say I use this to track damage. Then, a severe beating could be level 3 and have a duration for a couple of weeks. I'm still undecided if there should be residual levels after that level 3 damage has been recovered from. Or... and this is making things easy, if that three weeks includes the healing time that those injuries would require. I think I'm doing enough tracking work as it is. With new levels, I could change the desc and such. But, I'm not quite sure how this will go in practice. How big the periods will be. Anyway, I guess... I'll think about it a bit more.