Divergent/mods/Hideout Furniture Expansion/gamedata/scripts/meat_spoiling.script

185 lines
4.8 KiB
Plaintext
Raw Permalink Normal View History

2024-03-17 20:18:03 -04:00
--[[
Full rewrite of Rotten Meat addon by HarukaSai for EFP (visit at: https://discord.com/invite/stalker-efp)
Created: 13-11-2022
Credits for original addon: Arszi
Features:
- Rewritten logic
- Refrigiration
- MCM configuration
]]
local mcm_id = "meat_spoiling"
local expiration_time = nil
local expiration_table = {}
local ini_meat = ini_file_ex("plugins\\meat_spoiling_settings.ltx")
meats = utils_data.collect_section(ini_meat.ini, "meats", true)
local function t2c(t)
if not t then return nil end
local ct = game.CTime()
ct:set(t.Y,t.M,t.D,t.h,t.m,t.s,t.ms)
return ct
end
local function c2t(ct)
if not ct then return nil end
local Y, M, D, h, m, s, ms = 0, 0, 0, 0, 0, 0, 0
Y, M, D, h, m, s, ms = ct:get(Y, M, D, h, m, s, ms)
return { Y=Y, M=M, D=D, h=h, m=m, s=s, ms=ms }
end
local previous_time = nil
function actor_on_update()
local curr_time = game.get_game_time()
if (previous_time == nil) then previous_time = curr_time end
if not (curr_time:diffSec(previous_time) > 1) then
return
end
previous_time = curr_time
tick_expiration()
end
function actor_on_item_take(item)
local id = item:id()
local sec = item:section()
if not (meats[sec] and (not expiration_table[id])) then
return
end
expiration_table[id] = {
duration = string.match(sec, "meat_") and expiration_time.cooked or expiration_time.raw,
last_update = c2t(game.get_game_time())
}
end
function actor_on_item_use(obj)
if (obj and expiration_table[obj:id()]) then
expiration_table[obj:id()] = nil
end
end
function get_meat_is_frozen(se_obj)
if (not se_obj) then return false end
local se_parent = se_obj.parent_id and se_obj.parent_id < 65535 and alife_object(se_obj.parent_id)
if (not se_parent) or (se_parent:section_name() ~= "placeable_fridge") then
return false
end
return true
end
function tick_expiration()
local curr_time = game.get_game_time()
for id, data in pairs(expiration_table) do
repeat
local se_obj = alife_object(id)
if (not se_obj) or (not meats[se_obj:section_name()]) then
expiration_table[id] = nil
do break end
end
if (not get_meat_is_frozen(se_obj)) then
data.duration = data.duration - curr_time:diffSec(t2c(data.last_update))
end
data.last_update = c2t(curr_time)
if (data.duration <= 0) then
expire_food(se_obj)
expiration_table[id] = nil
end
until true
end
end
function expire_food(se_obj)
if (not se_obj.parent_id) or se_obj.parent_id >= 65535 then
alife_release(se_obj)
return
end
local se_parent = alife_object(se_obj.parent_id)
alife_release(se_obj)
if se_parent and (IsInvbox(se_parent) or se_parent.id == AC_ID) then
alife_create_item("rotten_meat", se_parent)
end
end
function save_state(m_data)
m_data.expiration_table = expiration_table
end
function load_state(m_data)
expiration_table = m_data.expiration_table or {}
end
function on_option_change()
expiration_time = {
raw = ui_mcm and ui_mcm.get(mcm_id .. "/expiration_hours_raw") * 60 * 60 or 48 * 60 * 60,
cooked = ui_mcm and ui_mcm.get(mcm_id .. "/expiration_hours_cooked") * 60 * 60 or 120 * 60 * 60
}
end
local clr_frozen = GetARGB(40,0,197,255)
function get_meat_is_frozen_cell(cell)
local se_obj = cell.ID and expiration_table[cell.ID] and alife_object(cell.ID)
if get_meat_is_frozen(se_obj) then
return true
end
end
function on_game_start()
RegisterScriptCallback("actor_on_item_use", actor_on_item_use)
RegisterScriptCallback("save_state",save_state)
RegisterScriptCallback("load_state",load_state)
RegisterScriptCallback("actor_on_item_take",actor_on_item_take)
RegisterScriptCallback("actor_on_update", actor_on_update)
RegisterScriptCallback("on_option_change", on_option_change)
rax_persistent_highlight.register("frozen_meat", function(cell)
return get_meat_is_frozen_cell(cell) and clr_frozen or false
end)
local anchor_x = function(axis, margin, w)
return (axis.w - w) - margin
end
local anchor_y = function(axis, margin, h)
return margin
end
rax_icon_layers.register("frozen_meat", function(cell, obj, sec)
if get_meat_is_frozen_cell(cell) then
local axis = utils_xml.get_item_axis(sec)
return {
texture = "ui_icon_freeze",
x = anchor_x(axis, 2, 13),
y = anchor_y(axis, 2, 13),
w = 13,
h = 13
}
end
end)
on_option_change()
end