0 votes
by (8.9k points)

I just incorporated TheMadExile's excellent Gregorian date & time widgets, from this thread, into my game.  It works brilliantly and is very simple to use in game.

/*
	Date & Time Widget Setup
*/
<<set
	window.GameDays to [
		"SUNDAY", "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY"
	];
	window.GameMonths to [
		"JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE",
		"JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER"
	];

	/*
		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(2019, 3, 5, 7, 2); /* 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>>

However, I'd really like to be able to advance the time to the next instance of a certain day.  For example, say Chess Club happens every Wednesday at 5PM.  If the player visits Chess Club, I'd like $gameDate to advance to 5PM on the next Wednesday.  I can't quite picture how to do this; can anyone help?

 

1 Answer

+1 vote
by (159k points)
selected by
 
Best answer

note: Based on the wording of your question I am assuming that the current Day of the Week of the Javascript Date object stored in the $gameDate story variable is Wednesday.

The solution to your issue can be broken down into two parts:

1. How to add 7 days to the existing Date object value.

<<adddays 7>>

2. How to change the current Hour of the Day of the existing Date object value to 5PM, which can be done using the Date object's setHours() function. (5PM is the 17th hour of the day)

<<set $gameDate.setHours(17)>>

 

by (8.9k points)

Thanks, Elf!  That wasn't quite what I meant to ask – I wanted to know how to advance to Wednesday dynamically, from any day of the week.

However, reading the way you broke down your answer made me realise I could do this with a widget and some <<if>> statements.

/* Advance to a certain day */
<<widget "cuNextMonday">>\
<<set _today to $gameDate.getDay()>>\
<<if _today == 0>>\
<<adddays 1>>\
<<elseif _today == 1>>\
<<adddays 7>>\
<<elseif _today == 2>>\
<<adddays 6>>\
<<elseif _today == 3>>\
<<adddays 5>>\
<<elseif _today == 4>>\
<<adddays 4>>\
<<elseif _today == 5>>\
<<adddays 3>>\
<<elseif _today == 6>>\
<<adddays 2>>\
<</if>>\
<</widget>>

<<widget "cuNextTuesday">>\
<<set _today to $gameDate.getDay()>>\
<<if _today == 0>>\
<<adddays 2>>\
<<elseif _today == 1>>\
<<adddays 1>>\
<<elseif _today == 2>>\
<<adddays 7>>\
<<elseif _today == 3>>\
<<adddays 6>>\
<<elseif _today == 4>>\
<<adddays 5>>\
<<elseif _today == 5>>\
<<adddays 4>>\
<<elseif _today == 6>>\
<<adddays 3>>\
<</if>>\
<</widget>>

<<widget "cuNextWednesday">>\
<<set _today to $gameDate.getDay()>>\
<<if _today == 0>>\
<<adddays 3>>\
<<elseif _today == 1>>\
<<adddays 2>>\
<<elseif _today == 2>>\
<<adddays 1>>\
<<elseif _today == 3>>\
<<adddays 7>>\
<<elseif _today == 4>>\
<<adddays 6>>\
<<elseif _today == 5>>\
<<adddays 5>>\
<<elseif _today == 6>>\
<<adddays 4>>\
<</if>>\
<</widget>>

<<widget "cuNextThursday">>\
<<set _today to $gameDate.getDay()>>\
<<if _today == 0>>\
<<adddays 4>>\
<<elseif _today == 1>>\
<<adddays 3>>\
<<elseif _today == 2>>\
<<adddays 2>>\
<<elseif _today == 3>>\
<<adddays 1>>\
<<elseif _today == 4>>\
<<adddays 7>>\
<<elseif _today == 5>>\
<<adddays 6>>\
<<elseif _today == 6>>\
<<adddays 5>>\
<</if>>\
<</widget>>

<<widget "cuNextFriday">>\
<<set _today to $gameDate.getDay()>>\
<<if _today == 0>>\
<<adddays 5>>\
<<elseif _today == 1>>\
<<adddays 4>>\
<<elseif _today == 2>>\
<<adddays 3>>\
<<elseif _today == 3>>\
<<adddays 2>>\
<<elseif _today == 4>>\
<<adddays 1>>\
<<elseif _today == 5>>\
<<adddays 7>>\
<<elseif _today == 6>>\
<<adddays 6>>\
<</if>>\
<</widget>>

<<widget "cuNextSaturday">>\
<<set _today to $gameDate.getDay()>>\
<<if _today == 0>>\
<<adddays 6>>\
<<elseif _today == 1>>\
<<adddays 5>>\
<<elseif _today == 2>>\
<<adddays 4>>\
<<elseif _today == 3>>\
<<adddays 3>>\
<<elseif _today == 4>>\
<<adddays 2>>\
<<elseif _today == 5>>\
<<adddays 1>>\
<<elseif _today == 6>>\
<<adddays 7>>\
<</if>>\
<</widget>>

<<widget "cuNextSunday">>\
<<set _today to $gameDate.getDay()>>\
<<if _today == 0>>\
<<adddays 7>>\
<<elseif _today == 1>>\
<<adddays 6>>\
<<elseif _today == 2>>\
<<adddays 5>>\
<<elseif _today == 3>>\
<<adddays 4>>\
<<elseif _today == 4>>\
<<adddays 3>>\
<<elseif _today == 5>>\
<<adddays 2>>\
<<elseif _today == 6>>\
<<adddays 1>>\
<</if>>\
<</widget>>

Now, using the widget <<cuNextWednesday>> will move the game calendar forward to the next Wednesday.

Thanks, Elf, you made me realise how I could do this.  :-)

 
by (159k points)

If you want a single widget that changes the DoW of the current Date forward to the next instance of a particular DoW then try the following.

/* Change DoW to the next instances of a particular DoW. */
<<widget "changeDoW">>\
	<<silently>>
		<<set _day to $args[0].toUpperCase()>>
		<<if GameDays.contains(_day)>>
			<<set _DoW to $gameDate.getDay()>>
			<<set _newDoW to GameDays.indexOf($args[0].toUpperCase())>>
			<<set _offset to _newDoW - _DoW>>
			<<if _newDoW <= _DoW>>
				<<set _offset += 7>>
			<</if>>
			<<adddays _offset>>
		<</if>>
	<</silently>>\
<</widget>>

The above changedow macro assumes you will pass it one of the Day Names defined in the window.GameDays variable, it then calculates the offset (number of days) between the current Day and the next Day with the required name.

The following example demonstrates the usage of the new macro, for simplicity sake the example resets the original date between calls to the new macro.

<<set $gameDate to new Date(2017, 11, 6, 17, 0, 0)>>\
Original date: <<datetime>>

<<changedow "MONDAY">>\
next Monday: <<datetime>>

<<set $gameDate to new Date(2017, 11, 6, 17, 0, 0)>>\
<<changedow "TUESDAY">>\
next Tuesday: <<datetime>>

<<set $gameDate to new Date(2017, 11, 6, 17, 0, 0)>>\
<<changedow "WEDNESDAY">>\
next Wednesday: <<datetime>>

<<set $gameDate to new Date(2017, 11, 6, 17, 0, 0)>>\
<<changedow "THURSDAY">>\
next Thursday: <<datetime>>

<<set $gameDate to new Date(2017, 11, 6, 17, 0, 0)>>\
<<changedow "FRIDAY">>\
next Friday: <<datetime>>

<<set $gameDate to new Date(2017, 11, 6, 17, 0, 0)>>\
<<changedow "SATURDAY">>\
next Saturday: <<datetime>>

<<set $gameDate to new Date(2017, 11, 6, 17, 0, 0)>>\
<<changedow "SUNDAY">>\
next Sunday: <<datetime>>

 

by (8.9k points)

Wow, what took me 133 lines of code, you did in 15.  :-)  Thanks, Greyelf, that's so much more elegant than my solution.

 
...