Divergent/mods/Hideout Furniture/gamedata/scripts/bind_hf_base.script

206 lines
5.2 KiB
Plaintext
Raw Permalink Normal View History

2024-03-17 20:18:03 -04:00
gc = game.translate_string
---@param id number
---@return bind_hf_base.hf_binder_wrapper|nil
function get_wrapper(id)
local obj = get_object_by_id(id)
if not obj then return end
local binder = obj:binded_object()
if not binder then return end
return binder.wrapper
end
function freeze_obj(id)
local obj = level.object_by_id(id)
if not obj then return end
local phys = obj:get_physics_shell()
if not phys then return end
phys:freeze()
local wrapper = get_wrapper(id)
if wrapper then wrapper.is_frozen = true end
return true
end
function init(obj)
obj:bind_object(hf_binder_wrapper(obj).binder)
end
---@param obj game_object
---@param field string
---@return function
function get_function_from_field(obj, field)
local func_string = ini_sys:r_string_ex(obj:section(), field)
if not func_string then return end
local func_split = {}
for s in string.gmatch(func_string, "([^.]+)") do
table.insert(func_split, s)
end
return _G[func_split[1]][func_split[2]]
end
--------------------------------------------------------------------------------
-- Class "hf_binder_wrapper"
--------------------------------------------------------------------------------
class "hf_binder_wrapper"
-- Class constructor
function hf_binder_wrapper:__init(obj)
local binder = base_binder(obj)
binder.wrapper = self
obj:bind_object(binder)
self.binder = binder
---@type game_object
self.object = obj
-- *hopefully* source of truth of frozenness since objects are not frozen by default
self.is_frozen = false
end
function hf_binder_wrapper:update(delta)
end
function hf_binder_wrapper:net_spawn()
CreateTimeEvent("hf_freeze", self.object:id(), 0, freeze_obj, self.object:id())
end
function hf_binder_wrapper:net_destroy()
-- Remove time event just in case object is released before freezing
RemoveTimeEvent("hf_freeze", self.object:id())
-- Clean up references
self.binder.wrapper = nil
self.binder = nil
self.object = nil
end
function hf_binder_wrapper:use_callback()
local callback = get_function_from_field(self.object, "ui_on_interaction")
if callback then callback(self.object:id()) end
end
function hf_binder_wrapper:use_callback_simple()
local callback = get_function_from_field(self.object, "ui_on_simple_interaction")
if callback then callback(self.object:id()) end
end
function hf_binder_wrapper:is_pickupable()
local data = hf_obj_manager.get_data(self.object:id())
if data.is_world_obj then
return false
end
return true
end
function hf_binder_wrapper:pickup()
local item_section = ini_sys:r_string_ex(self.object:section(), "item_section")
local condition = self.fuel
alife_create_item(item_section, db.actor, {cond=condition})
alife_release(self.object)
return true
end
---@param bool boolean
function hf_binder_wrapper:set_frozen(bool)
local data = hf_obj_manager.get_data(self.object:id())
if data.is_world_obj then return end
local phys = self.object:get_physics_shell()
if not phys then return end -- idk how an object wouldn't have a physics shell
if bool then
phys:freeze()
else
phys:unfreeze()
end
self.is_frozen = bool
end
--------------------------------------------------------------------------------
-- Class "base_binder"
--------------------------------------------------------------------------------
class "base_binder" (object_binder)
-- Class constructor
function base_binder:__init(obj) super(obj)
self.object:set_tip_text(gc("st_interact"))
---@type bind_hf_base.hf_binder_wrapper
self.wrapper = nil
end
-- Class update
function base_binder:update(delta)
object_binder.update(self, delta)
-- self.object:set_callback(callback.use_object, self.use_callback, self)
if self.wrapper and self.wrapper.update then
self.wrapper:update(delta)
end
end
-- Reload object
function base_binder:reload(section)
object_binder.reload(self, section)
if self.wrapper and self.wrapper.reload then
self.wrapper:reload(section)
end
end
-- Reinitialize object
function base_binder:reinit()
object_binder.reinit(self)
if self.wrapper and self.wrapper.reinit then
self.wrapper:reinit()
end
end
-- Net spawn
function base_binder:net_spawn(se_abstract)
if not(object_binder.net_spawn(self, se_abstract)) then
return false
end
if self.wrapper and self.wrapper.net_spawn then
self.wrapper:net_spawn()
end
return true
end
-- Net destroy
function base_binder:net_destroy()
self:save_data()
object_binder.net_destroy(self)
if self.wrapper and self.wrapper.net_destroy then
self.wrapper:net_destroy()
end
end
-- Standart function for save
function base_binder:net_save_relevant()
return true
end
-- Saving container
function base_binder:save(stpk)
object_binder.save(self, stpk)
if self.wrapper and self.wrapper.save then
self.wrapper:save(stpk)
end
end
-- Loading container
function base_binder:load(stpk)
object_binder.load(self, stpk)
end
-- Save to mdata by calling hf_obj_manager.update_data
function base_binder:save_data()
if self.wrapper and self.wrapper.save_data then
self.wrapper:save_data()
end
end