11local _ENV = mkmodule('datetime')
22
3- local DAYS_PER_MONTH = 28
4- local DAYS_PER_YEAR = 336
5- local MONTHS_PER_YEAR = 12
3+ DAYS_PER_MONTH = 28
4+ DAYS_PER_YEAR = 336
5+ MONTHS_PER_YEAR = 12
66
77DWARF_TICKS_PER_DAY = 1200
88--local DWARF_TICKS_PER_MONTH = DWARF_TICKS_PER_DAY * DAYS_PER_MONTH
@@ -16,7 +16,7 @@ ADVENTURE_TICKS_PER_DAY = 172800
1616--local TICKS_PER_MONTH = DWARF_TICKS_PER_MONTH
1717--local TICKS_PER_YEAR = TICKS_PER_MONTH * MONTHS_PER_YEAR
1818
19- local CALENDAR_MONTHS = {
19+ CALENDAR_MONTHS = {
2020 'Granite',
2121 'Slate',
2222 'Felsite',
@@ -73,25 +73,24 @@ DwarfCalendar.ATTRS{
7373}
7474
7575function DwarfCalendar:init()
76- self:setTickRates (self.ticks_per_day)
76+ self:setTickRate (self.ticks_per_day)
7777 self:normalize()
7878end
7979
80- function DwarfCalendar:setTickRates (ticks_per_day)
80+ function DwarfCalendar:setTickRate (ticks_per_day)
8181 -- game_mode.DWARF and .ADVENTURE values are < 10
8282 -- too low for sane tick rates, so we can utilize em.
8383 -- this might be useful if the caller wants to set by game mode
8484 if (ticks_per_day == df.game_mode.DWARF) then
8585 self.ticks_per_day = DWARF_TICKS_PER_DAY
86- elseif (ticks_per_day == df.game_mode.ADVENTURE)
86+ elseif (ticks_per_day == df.game_mode.ADVENTURE) then
8787 self.ticks_per_day = ADVENTURE_TICKS_PER_DAY
8888 else
89- -- should we throw an error if caller passed in <= 0 here?
90- -- if not, we'll divide by zero later
9189 self.ticks_per_day = (ticks_per_day > 0) and ticks_per_day or DWARF_TICKS_PER_DAY
9290 end
9391 self.ticks_per_month = self.ticks_per_day * DAYS_PER_MONTH
94- self.ticks_per_year = self.ticks_per_month * MONTHS_PER_YEAR
92+ self.ticks_per_year = self.ticks_per_day * DAYS_PER_YEAR
93+ return self
9594end
9695
9796function DwarfCalendar:addTicks(ticks)
@@ -101,13 +100,13 @@ function DwarfCalendar:addTicks(ticks)
101100end
102101
103102function DwarfCalendar:addDays(days)
104- self.year_tick = self.year_tick + self. daysToTicks(days)
103+ self.year_tick = self.year_tick + self: daysToTicks(days)
105104 self:normalize()
106105 return self
107106end
108107
109108function DwarfCalendar:addMonths(months)
110- self.year_tick = self.year_tick + self. monthsToTicks(months)
109+ self.year_tick = self.year_tick + self: monthsToTicks(months)
111110 self:normalize()
112111 return self
113112end
@@ -123,8 +122,11 @@ function DwarfCalendar:getYears()
123122 return self.year, self.year_tick
124123end
125124
126- function DwarfCalendar:setDayOfMonth(month, day)
127- self.year_tick = DwarfCalendar.monthsToTicks(month) + DwarfCalendar.daysToTicks(day)
125+ function DwarfCalendar:setDayOfMonth(day, month)
126+ month = month or self:getMonth()
127+ -- zero based when converting to ticks
128+ self.year_tick = self:monthsToTicks(month-1) + self:daysToTicks(day-1)
129+ return self
128130end
129131
130132-- returns an integer pair: (day of month starting from 1), (day tick count)
@@ -211,14 +213,14 @@ function DwarfCalendar:nextFullMoon()
211213 2, 28
212214 }
213215
214- if (dateT:getDayOfMonth() < fm[cur_m])
215- dateT:setDayOfMonth(cur_m, fm[cur_m])
216+ if (dateT:getDayOfMonth() < fm[cur_m]) then
217+ dateT:setDayOfMonth(fm[cur_m], cur_m )
216218 else
217219 -- Next full moon is on the next month
218220 -- or next year if addDays() rolled us over.
219- -- Obsidian is a possible exception since it has 2 full moons
220- -- this also handles the case when Obsidian day is between 2 and 28 exclusive
221- dateT:setDayOfMonth(cur_m, fm[cur_m+1])
221+ -- Obsidian is special since it has 2 full moons
222+ -- also handles the case when Obsidian day is between 2 and 28 exclusive
223+ dateT:setDayOfMonth(fm[cur_m+1], cur_m )
222224 end
223225
224226 return dateT
@@ -241,29 +243,22 @@ end
241243function DwarfCalendar:__add(other)
242244 if DEBUG then self:_debugOps(other) end
243245 -- normalize() handles adjustments to year and year_tick
244- return DwarfCalendar{ year = (self.year + other.year), year_tick = (self.year_tick + other.year_tick) }
246+ return DwarfCalendar{ year = (self.year + other.year), year_tick = (self.year_tick + other.year_tick), ticks_per_day = self.ticks_per_day }
245247end
246248
247249function DwarfCalendar:__sub(other)
248250 if DEBUG then self:_debugOps(other) end
249251 -- normalize() handles adjustments to year and year_tick
250- return DwarfCalendar{ year = (self.year - other.year) , year_tick = (self.year_tick - other.year_tick) }
252+ return DwarfCalendar{ year = (self.year - other.year) , year_tick = (self.year_tick - other.year_tick), ticks_per_day = self.ticks_per_day }
251253end
252254
253255function DwarfCalendar:_debugOps(other)
254256 print('first: '..self.year,self.year_tick)
255257 print('second: '..other.year,other.year_tick)
256258end
257259
258-
259- function DwarfCalendar.getMonthNames()
260- return CALENDAR_MONTHS
261- end
262-
263-
264260DateTime = defclass(DateTime, DwarfCalendar)
265261
266-
267262-- returns hours (24 hour format), minutes, seconds
268263function DateTime:getTime()
269264 -- probably only useful in adv mode where a day is 144x longer
@@ -292,28 +287,31 @@ end
292287-- where the caller provides the time unit specifiers
293288-- i.e. getDuration/toDuration('ymd') or toDuration('y', 'm', 'd'), etc
294289function DateTime:toDuration()
295- return Duration{ year = self.year, year_tick = self.year_tick }
290+ return Duration{ year = self.year, year_tick = self.year_tick, ticks_per_day = self.ticks_per_day }
296291end
297292
298293function DateTime:__add(other)
299294 if DEBUG then self:_debugOps(other) end
300295 -- normalize() handles adjustments to year and year_tick
301- return DateTime{ year = (self.year + other.year), year_tick = (self.year_tick + other.year_tick) }
296+ return DateTime{ year = (self.year + other.year), year_tick = (self.year_tick + other.year_tick), ticks_per_day = self.ticks_per_day }
302297end
303298
304299-- might make sense to return a Duration here
305300function DateTime:__sub(other)
306301 if DEBUG then self:_debugOps(other) end
307302 -- normalize() handles adjustments to year and year_tick
308- return DateTime{ year = (self.year - other.year) , year_tick = (self.year_tick - other.year_tick) }
303+ return DateTime{ year = (self.year - other.year) , year_tick = (self.year_tick - other.year_tick), ticks_per_day = self.ticks_per_day }
309304end
310305
311306function DateTime.now(game_mode)
312307 game_mode = game_mode or df.global.gamemode
313308 -- if game_mode is not given or not ADVENTURE then default to DWARF mode
314309 local ticks = (game_mode == df.game_mode.ADVENTURE) and
315310 (df.global.cur_year_tick_advmode) or (df.global.cur_year_tick)
316- return DateTime{ year = df.global.cur_year, year_tick = ticks }
311+ -- Tick rate defaults to DWARF mode, we should set the tick rate here as well
312+ -- For a custom rate the caller can use setTickRate() or we can add a second
313+ -- optional parameter
314+ return DateTime{ year = df.global.cur_year, year_tick = ticks }:setTickRate(game_mode)
317315end
318316
319317Duration = defclass(Duration, DwarfCalendar)
@@ -354,5 +352,4 @@ function Duration:__sub(other)
354352 return Duration{ year = (self.year - other.year) , year_tick = (self.year_tick - other.year_tick) }
355353end
356354
357-
358355return _ENV
0 commit comments