From 24e56dbfc2b29229ed6253b84635a16db87659fb Mon Sep 17 00:00:00 2001 From: orwell96 Date: Wed, 19 Jun 2019 09:56:30 +0200 Subject: Railway Time: Basic time counter and utility functions --- advtrains_line_automation/init.lua | 10 ++- advtrains_line_automation/railwaytime.lua | 132 ++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 advtrains_line_automation/railwaytime.lua (limited to 'advtrains_line_automation') diff --git a/advtrains_line_automation/init.lua b/advtrains_line_automation/init.lua index 5609524..eba288f 100644 --- a/advtrains_line_automation/init.lua +++ b/advtrains_line_automation/init.lua @@ -18,6 +18,7 @@ advtrains.lines = { local modpath = minetest.get_modpath(minetest.get_current_modname()) .. DIR_DELIM +dofile(modpath.."railwaytime.lua") dofile(modpath.."stoprail.lua") @@ -25,12 +26,19 @@ function advtrains.lines.load(data) if data then advtrains.lines.stations = data.stations or {} advtrains.lines.stops = data.stops or {} + advtrains.lines.rwt.set_time(data.rwt_time) end end function advtrains.lines.save() return { stations = advtrains.lines.stations, - stops = advtrains.lines.stops + stops = advtrains.lines.stops, + rwt_time = advtrains.lines.rwt.get_time() } end + +function advtrains.lines.step(dtime) + advtrains.lines.rwt.step(dtime) + atdebug(advtrains.lines.rwt.now()) +end diff --git a/advtrains_line_automation/railwaytime.lua b/advtrains_line_automation/railwaytime.lua new file mode 100644 index 0000000..d117af1 --- /dev/null +++ b/advtrains_line_automation/railwaytime.lua @@ -0,0 +1,132 @@ +-- railwaytime.lua +-- Advtrains uses a desynchronized time for train movement. Everything is counted relative to this time counter. +-- The advtrains-internal time is in no way synchronized to the real-life time, due to: +-- - Lag +-- - Server stops/restarts +-- However, this means that implementing a "timetable" system using the "real time" is not practical. Therefore, +-- we introduce a custom time system, the RWT(Railway Time), which has nothing to do with RLT(Real-Life Time) +-- RWT has a time cycle of 1 hour. This should be sufficient for most train lines that will ever be built in Minetest. +-- A RWT looks like this: 37;25 +-- The ; is to distinguish it from a normal RLT (which has colons e.g. 12:34:56). Left number is minutes, right number is seconds. +-- The minimum RWT is 00;00, the maximum is 59;59. +-- It is OK to leave one places out at either end, esp. when writing relative times, such as: +-- 43;3 22;0 2;30 0;10 ;10 +-- Those places are then filled with zeroes. Indeed, ";" would be valid for 00;00 . + +--[[ +1;23;45 = { + s=45, + m=23, + c=1, -- Cycle(~hour), not displayed most time +} + +]] + +local rwt = {} + +--Time Stamp (Seconds since start of world) +local e_time = 0 + +-- Current rw time, cached and updated each step +local crwtime + +function rwt.set_time(t) + e_time = t or 0 +end + +function rwt.get_time() + return e_time +end + +function rwt.step(dt) + e_time = e_time + dt +end + +function rwt.now() + return rwt.from_sec(e_time) +end + +function rwt.new(c, m, s) + return { + c = c or 0, + m = m or 0, + s = s or 0 + } +end +function rwt.copy(rwtime) + return { + c = rwtime.c or 0, + m = rwtime.m or 0, + s = rwtime.s or 0 + } +end + +function rwt.from_sec(stime) + local res = {} + local seconds = atfloor(stime) + res.s = seconds % 60 + local minutes = atfloor(seconds/60) + res.m = minutes % 60 + res.c = atfloor(minutes/60) + return res +end + +function rwt.to_sec(rwtime, c_over) + return (c_over or rwtime.c)*60*60 + rwtime.m*60 + rwtime.s +end + +function rwt.add(t1, t2) + local t1s = rwt.to_sec(t1) + local t2s = rwt.to_sec(t1) + return rwt.from_sec(t1s + t2s) +end + +function rwt.sub(t1, t2) + local t1s = rwt.to_sec(t1) + local t2s = rwt.to_sec(t1) + return rwt.from_sec(t1s - t2s) +end + +-- Threshold values +-- "reftime" is the time to which this is made relative and defaults to now. +rwt.CA_FUTURE = 60*60 - 1 -- Selected so that time lies at or in the future of reftime (at nearest point in time) +rwt.CA_FUTURES = 60*60 -- Same, except when times are equal, advances one full cycle +rwt.CA_PAST = 0 -- Selected so that time lies at or in the past of reftime +rwt.CA_PASTS = -1 -- Same, except when times are equal, goes back one full cycle +rwt.CA_CENTER = 30*60 -- If time is within past 30 minutes of reftime, selected as past, else selected as future. + +-- Adjusts the "cycle" value of a railway time to be in some relation to reftime. +-- Modifies rwtime in-place +function rwt.adjust(rwtime, reftime_p, thresh) + local reftime = reftime_p or rwt.now() + + local reftimes = rwt.to_sec(reftime) + + local rwtimes = rwt.to_sec(rwtime, 0) + local timeres = reftimes + thresh - rwtimes + local cycles = atfloor(timeres / (60*60)) + + rwtime.c = cycles +end + +function rwt.get_adjust(rwtime, reftime, thresh) + local res = rwt.copy(rwtime) + rwt.adjust(res, reftime, thresh) + return res +end + +function rwt.to_string(rwtime, places) + local pl = places or 2 + if rwtime.c~=0 or pl>=3 then + return string.format("%d;%02d;%02d", rwtime.c, rwtime.m, rwtime.s) + elseif rwtime.m~=0 or pl>=2 then + return string.format("%02d;%02d", rwtime.m, rwtime.s) + else + return string.format(";%02d",rwtime.s) + end + return str +end + + + +advtrains.lines.rwt = rwt -- cgit v1.2.3