281 lines
6.9 KiB
Plaintext
281 lines
6.9 KiB
Plaintext
-- Fixes to scripts via monkey patches
|
|
local tonumber = tonumber
|
|
local tostring = tostring
|
|
local unpack = unpack
|
|
|
|
-- Correct behaviour of actor_on_item_before_pickup callback
|
|
function bind_stalker_ext.actor_on_item_before_pickup(item) -- called from engine!
|
|
-- Called when actor is pressing use key to pick up an item
|
|
-- return false will prevent actor from pickup the item
|
|
local flags = { ret_value = true }
|
|
SendScriptCallback("actor_on_item_before_pickup",item,flags)
|
|
return flags.ret_value
|
|
end
|
|
|
|
-- Fix to NPC PDA not working with active weapon when using "view" function
|
|
-- Thanks Catspaw for testing
|
|
function ui_pda_npc_tab.use_view(obj)
|
|
local p = obj:parent()
|
|
if not (p and p:id() == AC_ID) then
|
|
return
|
|
end
|
|
|
|
hide_hud_inventory()
|
|
|
|
if get_console_cmd(1,"g_3d_pda") then
|
|
db.actor:make_item_active(obj)
|
|
ActorMenu.get_pda_menu():SetActiveSubdialog("eptNPC")
|
|
else
|
|
db.actor:move_to_slot(obj, 14)
|
|
|
|
if db.actor:active_slot() ~= 0 then
|
|
db.actor:activate_slot(0)
|
|
end
|
|
|
|
local tg = time_global()
|
|
CreateTimeEvent(0, "delay_2d_pda_draw", 0, function()
|
|
if time_global() - tg > 5000 then
|
|
-- timeout
|
|
return true
|
|
end
|
|
if not db.actor:active_item() then
|
|
ActorMenu.get_pda_menu():ShowDialog(true)
|
|
ActorMenu.get_pda_menu():SetActiveSubdialog("eptNPC")
|
|
return true
|
|
end
|
|
end)
|
|
end
|
|
end
|
|
|
|
-- Additional params for callbacks
|
|
-- Called on CHudItem Motion Mark
|
|
_G.CHudItem__OnMotionMark = function(state, mark, obj, owner)
|
|
SendScriptCallback("actor_on_hud_animation_mark", state, mark, obj, owner)
|
|
end
|
|
|
|
_G.CHudItem__PlayHUDMotion = function(anm_table, obj, owner)
|
|
SendScriptCallback("actor_on_hud_animation_play", anm_table, obj, owner)
|
|
return anm_table
|
|
end
|
|
|
|
-- Disable caching of ini values to utilize engine functions and reduce memory footprint
|
|
_G.USE_INI_MEMOIZE = false
|
|
clear_ini_cache(ini_sys)
|
|
if ini_cache then
|
|
empty_table(ini_cache)
|
|
end
|
|
|
|
_G.ini_file.r_string_ex = function(ini, s, k, def)
|
|
return ini:line_exist(s, k) and ini:r_string(s, k) or def
|
|
end
|
|
_G.ini_file.r_float_ex = function(ini, s, k, def)
|
|
if not ini:line_exist(s, k) then
|
|
return def
|
|
end
|
|
local v = ini:r_string(s, k)
|
|
if v == nil then
|
|
return def
|
|
end
|
|
return tonumber(v) or def
|
|
end
|
|
_G.ini_file.r_bool_ex = function(ini, s, k, def)
|
|
if not ini:line_exist(s, k) then
|
|
return def
|
|
end
|
|
local v = ini:r_string(s, k)
|
|
if v == nil then
|
|
return def
|
|
end
|
|
return v == "true" or v == "1" or v == "yes" or v == "on"
|
|
end
|
|
_G.ini_file.r_sec_ex = function(ini, s, k, def)
|
|
local result = ini_file.r_string_ex(ini, s, k, def)
|
|
if result and ini_sys:section_exist(result) then
|
|
return result
|
|
end
|
|
return nil
|
|
end
|
|
_G.ini_file.r_line_ex = function(ini, s, k)
|
|
return ini:r_line(s, k, "", "")
|
|
end
|
|
|
|
-- ini_file_ex disabled cache
|
|
_G.ini_file_ex.r_value = function(self, s, k, typ, def)
|
|
if not self.cleaned_cache then
|
|
self.cleaned_cache = true
|
|
empty_table(self.cache)
|
|
end
|
|
if not self.ini:line_exist(s, k) then
|
|
return def
|
|
end
|
|
local v = self.ini:r_string(s, k)
|
|
if v == nil then
|
|
-- Original 1.5.2 behaviour of r_value with bool type and r_bool_ex
|
|
-- is to return false if section and line exist and value is nil
|
|
-- In future it should be replaced with returning def
|
|
if typ == 1 then
|
|
return false
|
|
else
|
|
return def
|
|
end
|
|
end
|
|
if typ == 1 then
|
|
return v == "true" or v == "1" or v == "yes" or v == "on"
|
|
elseif typ == 2 then
|
|
return tonumber(v) or def
|
|
end
|
|
return v
|
|
end
|
|
|
|
_G.ini_file_ex.w_value = function(self, s, k, val, comment)
|
|
self.ini:w_string(s, k, val ~= nil and tostring(val) or "", comment ~= nil and tostring(comment) or "")
|
|
end
|
|
|
|
_G.ini_file_ex.line_exist = function(self, section, key)
|
|
return self.ini:line_exist(section, key)
|
|
end
|
|
|
|
_G.ini_file_ex.r_string_ex = function(self, s, k)
|
|
return self.ini:r_string_ex(s, k)
|
|
end
|
|
|
|
_G.ini_file_ex.r_bool_ex = function(self, s, k, def)
|
|
-- In future replace with self.ini:r_bool_ex(s, k, def)
|
|
return self:r_value(s, k, 1, def)
|
|
end
|
|
|
|
_G.ini_file_ex.r_float_ex = function(self, s, k)
|
|
return self.ini:r_float_ex(s, k)
|
|
end
|
|
|
|
-- SYS_GetParam disabled ini caching in benefit to use engine functions and reduce memory footprint
|
|
empty_table(INISYS_CACHE)
|
|
_G.INISYS_TYPES = {
|
|
-- string
|
|
[0] = function(typ, sec, param, def)
|
|
return ini_sys:r_string_ex(sec, param, def)
|
|
end,
|
|
-- bool
|
|
[1] = function(typ, sec, param, def)
|
|
return ini_sys:r_bool_ex(sec, param)
|
|
end,
|
|
-- float
|
|
[2] = function(typ, sec, param, def)
|
|
return ini_sys:r_float_ex(sec, param, def)
|
|
end,
|
|
}
|
|
_G.SYS_GetParam = function(typ, sec, param, def)
|
|
if not (typ and INISYS_TYPES[typ]) then
|
|
printf("!ERROR SYS_GetParam(%s, %s, %s, %s), incorrect type %s", typ, sec, param, def, typ)
|
|
callstack()
|
|
return
|
|
end
|
|
|
|
if not (sec and param) then
|
|
printf("!ERROR SYS_GetParam(%s, %s, %s, %s) | What's missing?", typ, sec, param, def)
|
|
callstack()
|
|
return
|
|
end
|
|
|
|
local result = INISYS_TYPES[typ](typ, sec, param, def)
|
|
return result
|
|
end
|
|
|
|
-- ini_file_ex replacement that is inherited from ini_file
|
|
class "new_ini_file_ex" (ini_file)
|
|
function new_ini_file_ex:__init(fname, advanced_mode)
|
|
super(fname)
|
|
self.fname = getFS():update_path('$game_config$', '')..fname
|
|
self.ini = self
|
|
if advanced_mode then
|
|
self:set_override_names(true)
|
|
self:set_readonly(false)
|
|
self:save_at_end(false)
|
|
end
|
|
end
|
|
|
|
function new_ini_file_ex:save()
|
|
self:save_as(self.fname)
|
|
end
|
|
|
|
function new_ini_file_ex:r_value(s, k, typ, def)
|
|
if not self:line_exist(s, k) then
|
|
return def
|
|
end
|
|
local v = self:r_string(s, k)
|
|
if v == nil then
|
|
-- Original 1.5.2 behaviour of r_value with bool type and r_bool_ex
|
|
-- is to return false if section and line exist and value is nil
|
|
-- In future it should be replaced with returning def
|
|
if typ == 1 then
|
|
return false
|
|
else
|
|
return def
|
|
end
|
|
end
|
|
if typ == 1 then
|
|
return v == "true" or v == "1" or v == "yes" or v == "on"
|
|
elseif typ == 2 then
|
|
return tonumber(v) or def
|
|
end
|
|
return v
|
|
end
|
|
|
|
function new_ini_file_ex:w_value(s, k, val, comment)
|
|
self:w_string(s, k, val ~= nil and tostring(val) or "", comment ~= nil and tostring(comment) or "")
|
|
end
|
|
|
|
-- In future delete this override
|
|
function new_ini_file_ex:r_bool_ex(s, k, def)
|
|
return self:r_value(s, k, 1, def)
|
|
end
|
|
|
|
function new_ini_file_ex:collect_section(section)
|
|
local _t = {}
|
|
|
|
local n = self:section_exist(section) and self:line_count(section) or 0
|
|
for i = 0, n - 1 do
|
|
local res, id, val = self:r_line(section, i, "", "")
|
|
_t[id] = val
|
|
end
|
|
|
|
return _t
|
|
end
|
|
|
|
function new_ini_file_ex:get_sections(keytable)
|
|
local t = {}
|
|
local function itr(section)
|
|
if keytable then
|
|
t[section] = true
|
|
else
|
|
t[#t + 1] = section
|
|
end
|
|
return false
|
|
end
|
|
self:section_for_each(itr)
|
|
return t
|
|
end
|
|
|
|
function new_ini_file_ex:r_string_to_condlist(s, k, def)
|
|
local src = self:r_string_ex(s, k) or def
|
|
if src then
|
|
return xr_logic.parse_condlist(nil, s, k, src)
|
|
end
|
|
end
|
|
|
|
function new_ini_file_ex:r_list(s, k, def)
|
|
local src = self:r_string_ex(s, k) or def
|
|
if src then
|
|
return parse_names(src)
|
|
end
|
|
end
|
|
|
|
function new_ini_file_ex:r_mult(s, k, ...)
|
|
local src = self:r_string_ex(s, k) or def
|
|
if src then
|
|
return unpack(parse_names(src))
|
|
end
|
|
return ...
|
|
end
|
|
_G.ini_file_ex = new_ini_file_ex
|