From da8bbfee9abf7b6e8f197f4ade7127e6dc805647 Mon Sep 17 00:00:00 2001 From: LeMagnesium Date: Thu, 12 May 2016 23:07:37 +0200 Subject: [PATCH] Add support for ingame seasons - Rework the status system - Rework booting order - Add feature requested in #2 --- init.lua | 178 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 108 insertions(+), 70 deletions(-) diff --git a/init.lua b/init.lua index 6a72657..49dd34c 100644 --- a/init.lua +++ b/init.lua @@ -3,22 +3,27 @@ -- By Mg/LeMagnesium -- License: WTFPL -- Last modification : --- 02/17/16 @ 07:33PM GMT+1 (Mg) +-- 05/12/16 @ 12:20PM GMT+1 (Mg) -- -- Namespace first, with basic informations time_reg = {} -time_reg.version = "00.01.16" +time_reg.version = "00.01.23" time_reg.authors = {"Mg/LeMagnesium"} -- Definitions time_reg.enabled = not (minetest.setting_getbool("disable_time_regulation") or false) time_reg.seasons_mode = minetest.setting_getbool("seasonal_time_regulation") or false +time_reg.real_life_seasons = minetest.setting_getbool("use_real_life_seasons") or false time_reg.offset = 0.5 -time_reg.day_of_year = tonumber(os.date("%j")) -- Updated at first update_constants +if time_reg.real_life_seasons then + time_reg.day_of_year = tonumber(os.date("%j")) +else + time_reg.day_of_year = 0 -- Updated at first update_constants +end -time_reg.time_speed = minetest.setting_get("time_speed") or 72 +time_reg.time_speed = tonumber(minetest.setting_get("time_speed") or "72") time_reg.loop_interval = 0 time_reg.loop_active = false @@ -33,11 +38,13 @@ time_reg.day_time_speed = 0 time_reg.night_time_speed = 0 --[[ Status : 0: Dead - 1: Idle - 2: Active + 1: Booting + 2: Idle + 3: Active ]] -time_reg.status = 2 +time_reg.STATUS_DEAD, time_reg.STATUS_BOOTING, time_reg.STATUS_IDLE, time_reg.STATUS_ACTIVE = 0, 1, 2, 3 +time_reg.status = time_reg.STATUS_BOOTING time_reg.ratio = { -- Expressed in percent day = tonumber(minetest.setting_get("day_time_ratio")) or 50, @@ -52,10 +59,9 @@ end local old_settime_func = core.chatcommands["time"].func core.chatcommands["time"].func = function(...) local res, msg = old_settime_func(...) - if res and time_reg.status == 2 then - time_reg.update_constants() + if res and time_reg.status == time_reg.STATUS_ACTIVE then time_reg.loop(false, true) - minetest.log("action", "[TimeRegulation] Settime override : updating regulation") + time_reg.log("Settime override : updating regulation") end return res, msg end @@ -63,85 +69,103 @@ end local old_set_func = core.chatcommands["set"].func core.chatcommands["set"].func = function(...) local res, msg = old_set_func(...) - if res and time_reg.status ~= 0 then - time_reg.update_constants() + if res and time_reg.status ~= time_reg.STATUS_DEAD then time_reg.loop(false, true) - minetest.log("action", "[TimeRegulation] Set override : updating constants and regulation") + time_reg.log("Set override : updating constants and regulation") end return res, msg end --- Then methods -function time_reg.do_calculation() +-- Then functions + +-- Information functions +-- Function meant to be an alias to minetest.log("action", "[TimeRegulation] " + parameters) +function time_reg.log(x) minetest.log("action", "[TimeRegulation] " .. (x or "")) end + +-- Standard calculation function +-- Function used when performing calculation of standard method (meaning that we already have the ratio) +function time_reg.std_calculation() local day_htime, night_htime = time_reg.duration * (time_reg.ratio.day/100), time_reg.duration * (time_reg.ratio.night/100) - time_reg.day_time_speed = 1440 / (day_htime * 2) - time_reg.night_time_speed = 1440 / (night_htime * 2) + time_reg.day_time_speed = 1440 / (day_htime) + time_reg.night_time_speed = 1440 / (night_htime) end +-- Seasonal calculation function +-- It contains the formula to calculate day/night ratio depending on in game/real life day of a year function time_reg.seasonal_calculation() - local year = tonumber(os.date("%Y")) local ylength = 365 - if (year % 4 == 0) and ((year % 400 ~= 0 and year % 600 == 0) or (year % 600 ~= 0 and year % 400 == 0)) then + local year = math.floor(time_reg.day_of_year / ylength) + if time_reg.real_time_seasons and (year % 4 == 0) and ((year % 400 ~= 0 and year % 600 == 0) or (year % 600 ~= 0 and year % 400 == 0)) then ylength = 366 end - if (year % 4) == 0 and not (year % 1000) ~= 0 then - ylength = 366 - end time_reg.ratio.night = (((math.cos((time_reg.day_of_year / ylength) * 2 * math.pi) * time_reg.offset) / 2.0) + 0.5) * 100 time_reg.ratio.day = 100 - time_reg.ratio.night - minetest.log("action", "[TimeRegulation] Seasonal calculation done") + time_reg.log("Seasonal calculation done") end +-- Constants update function +-- Global constant update function which determines what calculation method to use function time_reg.update_constants() time_reg.time_speed = minetest.setting_get("time_speed") or time_reg.time_speed -- Absolute Time Speed - time_reg.day_of_year = tonumber(os.date("%j")) + if time_reg.real_life_seasons then + time_reg.day_of_year = tonumber(os.date("%j")) + else + time_reg.day_of_year = minetest.get_day_count() + end - if time_reg.status == 1 and time_reg.time_speed > 0 then - time_reg.set_status(2, "ACTIVE") + if time_reg.status == time_reg.STATUS_IDLE and time_reg.time_speed > 0 then + time_reg.set_status(time_reg.STATUS_ACTIVE, "ACTIVE") end - if time_reg.status == 2 then + if time_reg.status == time_reg.STATUS_ACTIVE then if time_reg.seasons_mode then time_reg.seasonal_calculation() -- Calculate season-dependant ratio end time_reg.duration = 1440 / time_reg.time_speed -- Absolute Human Speed - time_reg.do_calculation() -- Use ratio and time_speed to calculate time - time_reg.loop_interval = (math.min(time_reg.night_time_speed / 1440, time_reg.night_time_speed / 1440) / 12) * 60 + time_reg.std_calculation() -- Use ratio and time_speed to calculate time + time_reg.loop_interval = math.min(1440 / time_reg.night_time_speed, 1440 / time_reg.night_time_speed) * 60 end end +-- Start the Loop +-- Launch the Loop with the order to repeat itself indefinitely function time_reg.start_loop() if time_reg.loop_active then - minetest.log("action", "[TimeRegulation] Will not start the loop : one is already running") + time_reg.log("Will not start the loop : one is already running") return false end time_reg.loop_active = true - minetest.log("action", "[TimeRegulation] Loop started") - minetest.after(0, time_reg.loop, true) + time_reg.log("Loop started") + time_reg.loop(true) return true end +-- Stop the Loop +-- Break the Loop by setting time_reg.loop_active to false, unless it isn't running function time_reg.stop_loop() if not time_reg.loop_active then - minetest.log("action", "[TimeRegulation] Will not break the loop : no loop running") + time_reg.log("Will not break the loop : no loop running") return false end time_reg.loop_active = false - minetest.log("action", "[TimeRegulation] Loop asked to stop") + time_reg.log("Loop asked to stop") return true end +-- Set status +-- Set the mechanism's current status (an integer, and a title) function time_reg.set_status(x, title) - minetest.log("action", "[TimeRegulation] Entered status " .. x .. " (" .. title .. ")") + time_reg.log("Entered status " .. x .. " (" .. title .. ")") time_reg.status = x end -- And the loop function time_reg.loop(loop, forceupdate) - -- Determine TOD and current moment + -- Do all calculations + time_reg.update_constants() local tod = minetest.get_timeofday() * 24000 local moment = "day" @@ -150,7 +174,7 @@ function time_reg.loop(loop, forceupdate) end if time_reg.time_speed == 0 then - time_reg.set_status(1, "IDLE") + time_reg.set_status(time_reg.STATUS_IDLE, "IDLE") return end @@ -162,28 +186,27 @@ function time_reg.loop(loop, forceupdate) if moment == "day" then if time_reg.ratio.day == 0 then minetest.set_timeofday(time_reg.threshold.night / 24000) - minetest.log("action", "[TimeRegulation] Entering day period : period skipped") + time_reg.log("Entering day period : period skipped") else minetest.setting_set("time_speed", time_reg.day_time_speed) - minetest.log("action", "[TimeRegulation] Entering day period : time_speed " .. time_reg.day_time_speed) + time_reg.log("Entering day period : time_speed " .. time_reg.day_time_speed) end else if time_reg.ratio.night == 0 then minetest.set_timeofday(time_reg.threshold.day / 24000) - minetest.log("action", "[TimeRegulation] Entering night period : period skipped") + time_reg.log("Entering night period : period skipped") else minetest.setting_set("time_speed", time_reg.night_time_speed) - minetest.log("action", "[TimeRegulation] Entering night period : time_speed " .. time_reg.night_time_speed) + time_reg.log("Entering night period : time_speed " .. time_reg.night_time_speed) end end - time_reg.update_constants() end -- Loop if we weren't broken if loop then minetest.after(time_reg.loop_interval, time_reg.loop, time_reg.loop_active) else - minetest.log("action", "[TimeRegulation] Loop stopped") + time_reg.log("Loop stopped") end end @@ -201,7 +224,7 @@ minetest.register_chatcommand("time_reg", { elseif param == "stop" then local res = time_reg.stop_loop() if res then - time_reg.set_status(0, "DEAD") + time_reg.set_status(time_reg.STATUS_DEAD, "DEAD") return true, "Loop was told to stop\nTime regulation disabled" else return false, "Loop couldn't be stopped, it isn't running" @@ -210,7 +233,7 @@ minetest.register_chatcommand("time_reg", { elseif param == "start" then local res = time_reg.start_loop() if res then - time_reg.set_status(2, "ACTIVE") + time_reg.set_status(time_reg.STATUS_ACTIVE, "ACTIVE") time_reg.update_constants() return true, "Loop started. Time regulation enabled" else @@ -274,40 +297,55 @@ minetest.register_chatcommand("time_reg", { return false, "Unknown state : " .. params[2] .. ". Use either 'on' or 'off'" end +-- elseif param:split(" ")[1] == -- For real time use toggling; NIY + else return false, "Unknown subcommand: " .. param end end }) --- Startup informations -local function log(x) minetest.log("action", "[TimeRegulation] " .. (x or "")) end +-- Init +-- Set all variables and activate all mechanisms +function time_reg.init() + time_reg.set_status(time_reg.STATUS_ACTIVE, "ACTIVE") + time_reg.log("Starting time regulation mechanisms...") -time_reg.update_constants() -log("Thank you for using TimeRegulation v" .. time_reg.version .. " by " .. table.concat(time_reg.authors, ", ")) -log("Status: " .. time_reg.status) -log("Absolute Time Speed: " .. time_reg.time_speed) -log("Duration: " .. time_reg.duration) -log("Loop interval: " .. time_reg.loop_interval .. "s") -if time_reg.seasons_mode then - log("Seasonal ratio calculation: on") -else - log("Seasonal ratio calculation: off") + if time_reg.seasons_mode then + time_reg.log("Seasonal ratio calculation: on") + if time_reg.real_life_seasons then + time_reg.log("Seasonal ratio calculated from real life date") + else + time_reg.log("Seasonal ratio calculated from game date") + end + else + time_reg.log("Seasonal ratio calculation: off") + end + + if not time_reg.enabled then + time_reg.log("Time Regulation is disabled by default. Use /time_reg start to start it") + else + time_reg.start_loop() + end + + time_reg.log("Duration: " .. time_reg.duration .. " minutes") + time_reg.log("Loop interval: " .. time_reg.loop_interval .. "s") + time_reg.log("Ratio:") + time_reg.log("\tDay: " .. time_reg.ratio.day .. "%") + time_reg.log("\tNight: " .. time_reg.ratio.night .. "%") + time_reg.log("Applied time speeds:") + time_reg.log("\tDay: " .. time_reg.day_time_speed) + time_reg.log("\tNight: " .. time_reg.night_time_speed) + time_reg.log("Human Durations:") + time_reg.log("\tDay: " .. 1440 / time_reg.day_time_speed .. " minutes") + time_reg.log("\tNight: " .. 1440 / time_reg.night_time_speed .. " minutes") end -if not time_reg.enabled then - log("Time Regulation is disabled by default. Use /time_reg start to start it") -else - time_reg.start_loop() -end +-- --[[ NOW WE SHALL START ]]-- -- -minetest.after(0.5, function() - log("Ratio:") - log("\tDay: " .. time_reg.ratio.day .. "%") - log("\tNight: " .. time_reg.ratio.night .. "%") - log("Applied time speeds:") - log("\tDay: " .. time_reg.day_time_speed) - log("\tNight: " .. time_reg.night_time_speed) -end) +time_reg.log("Thank you for using TimeRegulation v" .. time_reg.version .. " by " .. table.concat(time_reg.authors, ", ")) +time_reg.log("Status: " .. time_reg.status) +time_reg.log("Absolute Time Speed: " .. time_reg.time_speed) +minetest.after(0.1, time_reg.init)