Divergent/mods/Western Goods/gamedata/scripts/western_goods_persistent_ti...

168 lines
7.4 KiB
Plaintext

---==================================================================================================================---
--- ---
--- 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