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