---==================================================================================================================--- --- --- --- Original Author(s) : Unknown --- --- Edited : NLTP_ASHES --- --- Date : 17/04/2023 --- --- License : Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) --- --- --- --- Script used to manage time events, that are persistent through saves. To be used like regular time events. --- --- --- --- The LOAD_DELAY variable is here because the game runs load_state before the save is finished loading. --- --- This results in some function calls happening before the game is ready to play. --- --- --- --- Important : the functions passed to CreatePersistentTimeEvent must not contain pointers to engine classes. --- --- --- ---==================================================================================================================--- -- --------------------------------------------------------------------------------------------------------------------- -- Constants, global variables and imported functions -- --------------------------------------------------------------------------------------------------------------------- local EVENT_QUEUE = {} local LOAD_DELAY = 15000 local dbg_printf = western_goods_utils.dbg_printf -- --------------------------------------------------------------------------------------------------------------------- -- Main Script -- --------------------------------------------------------------------------------------------------------------------- --- Function used to create a time event that will still run after a save/load. --- Warning : DOES NOT TAKE ENGINE CLASSES ! --- @param ev_id string --- @param act_id string --- @param timer number --- @param func function --- @param ... table --- @return nil function CreatePersistentTimeEvent(ev_id,act_id,timer,func,...) if not (EVENT_QUEUE[ev_id]) then EVENT_QUEUE[ev_id] = {} EVENT_QUEUE[ev_id].__size = 0 end if not (EVENT_QUEUE[ev_id][act_id]) then EVENT_QUEUE[ev_id][act_id] = {} EVENT_QUEUE[ev_id][act_id].added_at = time_global() EVENT_QUEUE[ev_id][act_id].timer = time_global() + timer*1000 EVENT_QUEUE[ev_id][act_id].func = func EVENT_QUEUE[ev_id][act_id].params = {...} EVENT_QUEUE[ev_id].__size = EVENT_QUEUE[ev_id].__size + 1 end end --- Function used to remove a time event if it exists. --- @param ev_id string --- @param act_id string --- @return nil function RemovePersistentTimeEvent(ev_id,act_id) if (EVENT_QUEUE[ev_id] and EVENT_QUEUE[ev_id][act_id]) then EVENT_QUEUE[ev_id][act_id] = nil EVENT_QUEUE[ev_id].__size = EVENT_QUEUE[ev_id].__size - 1 end end --- Function used to reset the timer of a time event if it exists. --- @param ev_id string --- @param act_id string --- @param timer number --- @return nil function ResetPersistentTimeEvent(ev_id,act_id,timer) if (EVENT_QUEUE[ev_id] and EVENT_QUEUE[ev_id][act_id]) then EVENT_QUEUE[ev_id][act_id].added_at = time_global() EVENT_QUEUE[ev_id][act_id].timer = time_global() + timer*1000 end end --- Function called every frame to check if time events should run or not. --- @return boolean function ProcessPersistentEventQueue() if western_goods_utils.has_info("sleep_active") then return false end for event_id,actions in pairs(EVENT_QUEUE) do for action_id,act in pairs(actions) do if (action_id ~= "__size") then if time_global() >= act.timer then if (act.func(unpack(act.params)) == true) then EVENT_QUEUE[event_id][action_id] = nil EVENT_QUEUE[event_id].__size = EVENT_QUEUE[event_id].__size - 1 end end end end if (EVENT_QUEUE[event_id].__size == 0) then EVENT_QUEUE[event_id] = nil end end return false end --- Function used to get the number of persistent time events registered to a given event id. --- @param ev_id string|number --- @return number function GetPersistentTimeEventsCount(ev_id) return EVENT_QUEUE[ev_id] and EVENT_QUEUE[ev_id].__size or 0 end -- --------------------------------------------------------------------------------------------------------------------- -- Callbacks registration -- --------------------------------------------------------------------------------------------------------------------- --- Function used to register callbacks. --- @return nil function on_game_start() RegisterScriptCallback("save_state", save_state) RegisterScriptCallback("load_state", load_state) RegisterScriptCallback("actor_on_update", ProcessPersistentEventQueue) end -- --------------------------------------------------------------------------------------------------------------------- -- Data persistence -- --------------------------------------------------------------------------------------------------------------------- --- Function used to store information in the save file. --- @param m_data table --- @return nil function save_state(m_data) local table_to_save = {} copy_table(table_to_save,EVENT_QUEUE) for event_id,actions in pairs(table_to_save) do for action_id,act in pairs(actions) do if (action_id ~= "__size") then local timer = table_to_save[event_id][action_id].timer table_to_save[event_id][action_id].timer = timer - time_global() end end end m_data.persistant_event_queue = table_to_save dbg_printf("[WG] Persistent Time Events | Saved timed event table :\n%s", utils_data.print_table(table_to_save, false, true)) end --- Function used to load information stored in the save file. --- @param m_data table --- @return nil function load_state(m_data) local table_to_load = m_data.persistant_event_queue or {} for event_id,actions in pairs(table_to_load) do for action_id,act in pairs(actions) do if (action_id ~= "__size") then local timer = table_to_load[event_id][action_id].timer table_to_load[event_id][action_id].added_at = time_global() + LOAD_DELAY table_to_load[event_id][action_id].timer = timer + time_global() + LOAD_DELAY end end end copy_table(EVENT_QUEUE,table_to_load) dbg_printf("[WG] Persistent Time Events | Loaded timed event table :\n%s", utils_data.print_table(EVENT_QUEUE, false, true)) end