[Sugarcube 2.31.1] Events triggered based on calendar date

Hi everyone! Been using Twine and sugarcube for a while but I’m completely helpless when it comes to coding. I’ve been using “Mad Exile’s Gregorian Date & Time Widgets” so the player can have see days, months and years passing through the course of his/her character’s life. The problem comes when I try to create <> statements with some sort of trigger dependant of the in-game date.

I’m completely clueless about how to implement this sort of idea using Mad Exile’s code…

Here’s the code of the calendar:

/*
	Date & Time Widget Setup
*/
<<set
	window.GameDays to [
		"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
	];
	window.GameMonths to [
		"Jan", "Feb", "Mar", "Apr", "May", "Jun",
		"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
	];

	/*
		Below we have to use the multi-parameter version of the Date
		constructor, rather than the date string version, because the
		date string version treats a missing timezone offset as UTC.
		While there are ways to determine players' timezone offsets,
		so they could be added to a date string, it's more convenient
		simply to use the multi-parameter constructor.

		The point of this is so that you can simply initialize the game
		world clock to whatever date and time you wish without having to
		worry about the players' timezone offsets, while still ensuring
		that they all see the same game world dates and times.
	*/
	/* params: year , month(0-based) , day , hour(24H) , minute [, second ] */
	$gameDate to new Date(2015, 2, 17, 3, 24); /* e.g. Mar 17, 2015 03:24 */
>>


/*
	Date & Time Advancement Widget Definitions
*/
/* Adds the specified number of minutes. */
<<widget "addmins">>\
<<run $gameDate.setMinutes($gameDate.getMinutes() + $args[0])>>\
<</widget>>

/* Adds the specified number of hours. */
<<widget "addhours">>\
<<run $gameDate.setHours($gameDate.getHours() + $args[0])>>\
<</widget>>

/* Adds the specified number of days. */
<<widget "adddays">>\
<<run $gameDate.setHours($gameDate.getHours() + $args[0] * 24)>>\
<</widget>>


/*
	Date & Time Printing Widget Definitions
*/
/* Prints the current date ("{weekday} {month} {day}, {year}"). */
<<widget "date">>\
<<print String.format("{0} {1} {2}, {3}",
	GameDays[$gameDate.getDay()],
	GameMonths[$gameDate.getMonth()],
	$gameDate.getDate(),
	$gameDate.getFullYear()
)>>\
<</widget>>

/* Prints the current time (12H). */
<<widget "time12hr">>\
<<if $gameDate.getHours() eq 0>>\
12\
<<elseif $gameDate.getHours() gt 12>>\
<<print $gameDate.getHours() - 12>>\
<<else>>\
<<print $gameDate.getHours()>>\
<</if>>:\
<<if $gameDate.getMinutes() lt 10>>0<</if>><<print $gameDate.getMinutes()>> \
<<if $gameDate.getHours() gte 12>>PM<<else>>AM<</if>>\
<</widget>>

/* Prints the current time (24H). */
<<widget "time24hr">>\
<<if $gameDate.getHours() lt 10>>0<</if>><<print $gameDate.getHours()>>:\
<<if $gameDate.getMinutes() lt 10>>0<</if>><<print $gameDate.getMinutes()>>\
<</widget>>

/* Prints the current date and time (12H). */
<<widget "datetime">><<date>> <<time12hr>> (<<time24hr>>)<</widget>>
1 Like

I don’t have any answers but I just wanted to say that I am running into the exact same problem with the exact same code so if someone could grace us with their knowledge that would be very helpful :pray:

This forum eats anything in <> angle brackets, so you’ll want to mark that as “Preformatted text”. You should be able to edit your post, I think? Select the text and hit Ctrl+Shift+C or click the </> icon.

I’m assuming that’s an <<if>> statement, or something similar. I believe the way to compare dates is to use the getTime() method and compare those. Something like:

<<if $currentDate.getTime() is $eventDate.getTime()>>

If you use less-than, greater-than, less-than-or-equal comparisons, JavaScript will try to convert the dates to numbers, which does the same thing as getTime, so you can leave it out there. But if you use is or == it will try to check if the two dates are the exact same object rather than if they have the same value. I’d suggest just using getTime all the time so you don’t forget.

You might also run into problems if you’re advancing the date faster than one day at a time: what if you skip the day an event happened? In that case you may want to save the previous date every time you change it:

<<set $prevDate = new Date($curDate.getTime())>>

And then compare with something like:

<<if $eventDate.getTime() > $prevDate.getTime() and $eventDate.getTime() <= $curDate.getTime()>>

Hope that helps…

1 Like

If it helps, you might want to check out the “Time” section of my Twine/SugarCube sample code collection. There are various snippets of code there showing how to work with Date objects.

Also, if you want to redirect to certain passages based on events triggering, then you could create a JavaScript Config.navigation.override function to handle doing that for you. Just remember to make sure that the events don’t keep re-triggering.

Hope that helps! :grinning:

1 Like

Thanks to everybody for their time helping me with this matter. @JoshGrams was right with his answer but I had to spend some time trying to figure out how to make it work. Instead of using

<<if $currentDate.getTime() is $eventDate.getTime()>>

I did this:

<<set
	window.GameDays to [
		"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
	];
	window.GameMonths to [
		"Jan", "Feb", "Mar", "Apr", "May", "Jun",
		"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
	];

	$game1Date to new Date(2015, 2, 17, 3, 24); /* e.g. Mar 17, 2015 03:24 */
>>

So under the Game clock I just created another one, called it $game1Date
Because the game skips days and months, the way of comparing the variables:

<<if $gameDate.getTime() > $game1Date.getTime()>> The city has fallen under enemy control!<</if>>

You want to set $game1Date as the date of the event you want to add in your game. I think you can create as many events as you want just copying, pasting and changing $gameDate to $game2Date

<<if $gameDate.getTime() > $game2Date.getTime()>> Are you even trying to win this war? Another city has fallen!<</if>>

Thanks a lot guys!

Check the solution. Hope you got what you were looking for too!