139 lines
3.4 KiB
Plaintext
139 lines
3.4 KiB
Plaintext
--[[
|
|
Functionality for specialized storage boxes
|
|
Author: HarukaSai (visit us at: https://discord.gg/efp)
|
|
19-06-2023
|
|
]]
|
|
|
|
-- no real way to tell apart canned food, so we just have a table with them
|
|
canned_food = {
|
|
["beans"] = true,
|
|
["chili"] = true,
|
|
["conserva"] = true,
|
|
["corn"] = true,
|
|
["tomato"] = true,
|
|
["tushonka"] = true
|
|
}
|
|
|
|
storage_types = {
|
|
["ammo"] = function(obj)
|
|
return IsAmmo(obj)
|
|
end,
|
|
["meds"] = function(obj)
|
|
return SYS_GetParam(0, obj:section(), "kind") == "i_medical"
|
|
end,
|
|
["canned_food"] = function(obj)
|
|
local sec = obj:section()
|
|
return canned_food[sec] or false
|
|
end
|
|
}
|
|
|
|
-- Wrapper for CreateTimeEvent that checks if object exists
|
|
function CreateSafeObjEvent(obj, ev_id, act_id, timer, f, ...)
|
|
local id = obj:id()
|
|
|
|
CreateTimeEvent(ev_id, act_id, timer, function(...)
|
|
if level.object_by_id(id) then
|
|
return f(obj, ...)
|
|
end
|
|
|
|
return true
|
|
end, ...)
|
|
end
|
|
|
|
local check_ids = {
|
|
[EDDListType.iActorBag] = true,
|
|
[EDDListType.iActorBelt] = true,
|
|
[EDDListType.iActorTrade] = true,
|
|
[EDDListType.iActorSlot] = true
|
|
}
|
|
|
|
function actor_on_item_before_move(flags, npc_id, obj, mode, bag_id)
|
|
if not (check_ids[bag_id] and obj and mode == "loot") then return end
|
|
|
|
local box = get_object_by_id(npc_id)
|
|
|
|
if (not box) then return end
|
|
|
|
local specialized_storage = SYS_GetParam(0, box:section(), "specialized_storage")
|
|
|
|
if (not storage_types[specialized_storage]) or storage_types[specialized_storage](obj) then
|
|
return
|
|
end
|
|
|
|
flags.ret_value = false
|
|
end
|
|
|
|
local levels = {
|
|
[0] = 0,
|
|
[1] = 1,
|
|
[2] = 2,
|
|
[3] = 2,
|
|
[4] = 3,
|
|
}
|
|
|
|
function update_display(box)
|
|
local items = 0
|
|
|
|
box:iterate_inventory_box(function(box)
|
|
items = items + 1
|
|
end, box)
|
|
|
|
local level = levels[clamp(math.floor(items/12), 0, 4)] or 0
|
|
|
|
for i = 1, 3 do
|
|
local ev_id = string.format("update_tuna_box_bone_%s_%s", box:id(), i)
|
|
|
|
CreateSafeObjEvent(box, ev_id, ev_id, i/25, function()
|
|
box:set_bone_visible("tuna_" .. i, level >= i, false, false)
|
|
return true
|
|
end)
|
|
end
|
|
end
|
|
|
|
function update_tuna_box(box)
|
|
local id = box:id()
|
|
|
|
ResetTimeEvent("update_tuna_box" .. id, "update_tuna_box" .. id, 0.1)
|
|
|
|
CreateSafeObjEvent(box, "update_tuna_box" .. id, "update_tuna_box" .. id, 0.1, function()
|
|
update_display(box)
|
|
return true
|
|
end, id)
|
|
end
|
|
|
|
function is_tuna_box(box)
|
|
return box:section() == "placeable_cans_tuna"
|
|
end
|
|
|
|
function actor_on_item_take_from_box(box, item)
|
|
if (not is_tuna_box(box)) then
|
|
return
|
|
end
|
|
|
|
update_tuna_box(box)
|
|
end
|
|
|
|
function actor_on_item_put_in_box(box, item)
|
|
if (not is_tuna_box(box)) then
|
|
return
|
|
end
|
|
|
|
update_tuna_box(box)
|
|
end
|
|
|
|
binder_update = bind_physic_object.generic_physics_binder.update
|
|
|
|
bind_physic_object.generic_physics_binder.update = function(self, delta)
|
|
binder_update(self, delta)
|
|
|
|
if is_tuna_box(self.object) and (not self.tuna_box_updated) then
|
|
update_display(self.object)
|
|
self.tuna_box_updated = true
|
|
end
|
|
end
|
|
|
|
function on_game_start()
|
|
RegisterScriptCallback("actor_on_item_take_from_box", actor_on_item_take_from_box)
|
|
RegisterScriptCallback("actor_on_item_put_in_box", actor_on_item_put_in_box)
|
|
RegisterScriptCallback("ActorMenu_on_item_before_move", actor_on_item_before_move)
|
|
end |