Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- itms_manager
- by Alundaio
- Copyright (C) 2012 Alundaio
- This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
- Modified by Tronex:
- 2018/7/18 - Added support for new usable items (maps,craft)
- 2018/7/21 - Added the ability to gather/separate muti-use items
- 2018/7/26 - Added the ability to disassemble misc items
- 2018/7/26 - Rewrote a lot of function with better codes
- 2018/7/31 - Added new items, battery consumption for geiger counter and gps tracker
- 2018/8/2 - Drag artefacts on containers to put them in, container tool is no longer used
- 2019/2/16 - Organized the items in tables for global use
- 2019/9/19 - Bolt count manager
- 2020/3/18 - Cleaning
- --]]
- -- local uses = obj:get_remaining_uses()
- -- local max_uses = obj:get_max_uses()
- -- obj:set_remaining_uses(num)
- -- Prepare ini files
- ini_manager = ini_file("items\\settings\\itms_manager.ltx")
- ini_container = ini_file("items\\settings\\arty_container.ltx")
- ini_parts = ini_file("items\\settings\\parts.ltx")
- ini_craft = ini_file("items\\settings\\craft.ltx")
- ini_death = ini_file("items\\settings\\death_generic.ltx")
- ini_reward = ini_file("items\\settings\\item_rewards.ltx")
- local n = 0
- local result,id,value = "","",""
- local string_find = string.find
- local string_gsub = string.gsub
- -- Used to determine current playing instrument to regenerate psy_boost in arszi_psy.script
- playing_instrument = nil
- playing_music_length = 0
- -- Collect item sections of main tools
- itms_arty_container = utils_data.collect_section(ini_container,"containers",true) or {}
- local empty_syringe_items = {}
- n = ini_manager:line_count("empty_syringe_items")
- for i=0,n-1 do
- result, id, value = ini_manager:r_line_ex("empty_syringe_items",i,"","")
- if ini_sys:section_exist(id) then
- empty_syringe_items[id] = true
- end
- end
- item_rewards = {}
- ini_reward:section_for_each(function(section)
- if (not item_rewards[section]) then
- item_rewards[section] = {}
- end
- n = ini_reward:line_count(section)
- for i=0,n-1 do
- result, id, value = ini_reward:r_line_ex(section,i,"","")
- if ini_sys:section_exist(id) then
- item_rewards[section][id] = ini_sys:r_float_ex(id,"tier") or 1
- end
- end
- end)
- item_combine = {}
- n = ini_craft:line_count("item_combination")
- for i=0,n-1 do
- result, id, value = ini_craft:r_line_ex("item_combination",i,"","")
- if id and value then
- local str = str_explode(id,":")
- if str[1] and str[2] and ini_sys:section_exist(str[1]) and ini_sys:section_exist(str[2]) and ini_sys:section_exist(value) then
- if (not item_combine[str[1]]) then
- item_combine[str[1]] = {}
- end
- item_combine[str[1]][str[2]] = value
- else
- printe("!ERROR item_combination | wrong section names")
- end
- end
- end
- -------------------------------
- -- CALLBACKS
- -------------------------------
- function on_game_start()
- RegisterScriptCallback("actor_on_item_before_use",actor_on_item_before_use)
- RegisterScriptCallback("actor_on_first_update",actor_on_first_update)
- RegisterScriptCallback("actor_on_item_drop",actor_on_item_drop)
- RegisterScriptCallback("actor_on_item_use",actor_on_item_use)
- RegisterScriptCallback("actor_on_item_take",actor_on_item_take)
- RegisterScriptCallback("ActorMenu_on_item_drag_drop",ActorMenu_on_item_drag_drop)
- RegisterScriptCallback("ActorMenu_on_item_focus_receive",ActorMenu_on_item_focus_receive)
- RegisterScriptCallback("save_state",save_state)
- end
- local old_booster = {}
- local boost_min = 0.00005
- local booster_string = {
- ["pwr"] = "ui_inv_power",
- ["psy"] = "ui_inv_outfit_telepatic_protection",
- ["bld"] = "ui_inv_bleeding",
- ["hp"] = "ui_inv_health",
- ["rad"] = "ui_inv_radiation",
- }
- function actor_on_item_before_use(obj,flags)
- local sec = obj:section()
- -- no need to check for tools
- if IsItem("tool",sec) then
- --printf("- actor_on_item_before_use [%s] | ignore utility item", sec)
- flags.ret_value = true
- return
- end
- local curr_booster = {}
- local time_g = time_global()
- local str = ""
- local pass = true
- -- read important boosts
- local period = ini_sys:r_float_ex(sec, "boost_time") or 0
- local rad_boost = ini_sys:r_float_ex(sec, "boost_radiation_restore") or 0
- local psy_boost = ini_sys:r_float_ex(sec, "boost_telepat_protection") or 0
- local bld_boost = ini_sys:r_float_ex(sec, "boost_bleeding_restore") or 0
- local hp_boost = ini_sys:r_float_ex(sec, "boost_health_restore") or 0
- local pwr_boost = ini_sys:r_float_ex(sec, "boost_power_restore") or 0
- -- if an item is required
- local require_tool = ini_sys:r_string_ex(sec, "required_tool")
- local obj_tool = require_tool and ini_sys:section_exist(require_tool) and db.actor:object(require_tool)
- -- store boosts in a table
- curr_booster["section"] = sec
- curr_booster["period"] = (period > 0) and (time_g + period*1000) or time_g
- curr_booster["pwr"] = (pwr_boost > boost_min) and pwr_boost or 0
- curr_booster["psy"] = (psy_boost > boost_min) and psy_boost or 0
- curr_booster["bld"] = (bld_boost > boost_min) and bld_boost or 0
- curr_booster["hp"] = (hp_boost > boost_min) and hp_boost or 0
- curr_booster["rad"] = (rad_boost > boost_min) and rad_boost or 0
- -- A required tool is missing -> no eat
- if require_tool and (not obj_tool) then
- --printf("~ actor_on_item_before_use [%s] | require_tool [%s] is missing", sec, require_tool)
- str = strformat(game.translate_string("st_itm_manager_missing_requirements"), ui_item.get_sec_name(require_tool))
- pass = false
- -- older booster is still active
- elseif old_booster["period"] and (old_booster["period"] > time_g) then
- --printf("~ actor_on_item_before_use [%s] | older booster [%s] is still active", sec, old_booster['section'])
- local weaker_effect
- local stronger_effect
- for k,v in pairs(curr_booster) do
- if (k ~= "section") and (k ~= "period") then
- local v2 = old_booster[k]
- if v2 and (v > boost_min) and (v2 > boost_min) then
- if (v <= v2) then
- weaker_effect = k
- else
- stronger_effect = k
- end
- elseif (v2 == 0) and (v > boost_min) then
- stronger_effect = k
- end
- end
- end
- -- older booster has some stronger effect, while new one doesn't have any stronger effect
- if weaker_effect and (not stronger_effect) then
- --printf("~ actor_on_item_before_use [%s] | older booster [%s] has stronger effect: %s", sec, old_booster['section'], weaker_effect)
- local boost_str = game.translate_string(booster_string[weaker_effect])
- str = strformat(game.translate_string("st_itm_manager_greater_effect"),boost_str)
- pass = false
- end
- -- prevent player to take anabiotic during combat
- elseif sec == "drug_anabiotic" then
- if (not is_empty(xr_combat_ignore.fighting_with_actor_npcs)) then
- str = game.translate_string("st_anabiotic_combat")
- pass = false
- end
- end
- -- to eat or not to eat
- if pass then
- --printf("- actor_on_item_before_use [%s] | pass = true", sec)
- flags.ret_value = true
- copy_table(old_booster, curr_booster)
- if obj_tool then
- utils_item.discharge(obj_tool)
- end
- else
- --printf("! actor_on_item_before_use [%s] | pass = false", sec)
- flags.ret_value = false
- --alife_release(obj)
- --alife_create_item(sec,db.actor)
- utils_xml.hide_menu()
- actor_menu.set_msg(1, str,3)
- end
- end
- function actor_on_first_update()
- -- Delete base pda
- local sim = alife()
- local obj, se_obj
- --[[
- for i=1,65534 do
- se_obj = sim:object(i)
- if se_obj and (se_obj:section_name() == "device_pda") then
- sim:release(se_obj,true)
- end
- end
- --]]
- -- Delete animation items on actor
- for sec,_ in pairs(GetItemList("release")) do
- obj = db.actor:object(sec)
- if obj then
- alife_release(obj)
- end
- end
- -- Spawn bolts
- local m_data = alife_storage_manager.get_state()
- local bolt_first = m_data.bolt_first
- if bolt_first then
- alife_create_item(bolt_first, db.actor)
- m_data.bolt_first = nil
- end
- local bolt_slot = m_data.bolt_slot
- if bolt_slot then
- alife_create_item(bolt_slot, db.actor)
- end
- local bolts = m_data.bolts
- if bolts then
- for sec,cnt in pairs(bolts) do
- for i=1,cnt do
- alife_create_item(sec, db.actor)
- end
- end
- end
- -- Damage equipment
- if (not has_alife_info("start_equippment_handled")) and (not IsTestMode()) then
- CreateTimeEvent(0,"delay_new_game_autosave",4,new_game_equippment)
- end
- -- Bolt manager
- CreateTimeEvent("cycle","bolt_manager",60,bolt_manager)
- end
- function actor_on_item_drop(obj)
- if not (obj) then
- return
- end
- if (db.actor:has_info("actor_made_wish_for_riches")) then
- db.actor:transfer_item(obj,db.actor)
- elseif IsWeapon(obj) then
- se_save_var(obj:id(), nil, "strapped_item", obj:condition())
- end
- end
- function actor_on_item_use(obj)
- if (db.actor:has_info("actor_made_wish_for_riches")) then
- return
- end
- local sec = obj:section()
- -- Strelok Notes
- if (sec == "mlr_strelok_item_01") then
- txr_routes.open_route("val","x18")
- return
- -- Deployable mgun
- elseif (sec == "itm_deployable_mgun") then
- use_deployable_mgun(obj)
- return
- -- Watch
- elseif (sec == "hand_watch") then
- use_watch(obj)
- return
- -- Chocolate Bar
- elseif (sec == "chocolate") then
- alife_create_item("chocolate_p", db.actor)
- return
- -- Bolts pack
- elseif (sec == "bolts_pack") then
- local bolts = {}
- local n = math.random(20,30)
- for i=1,n do
- local actor = db.actor
- if math.random(1,100) > 50 then
- bolts[#bolts + 1] = "bolt"
- else
- bolts[#bolts + 1] = "bolt_bullet"
- end
- end
- utils_item.delay_event(bolts, nil, "bolts_pack", false, 5)
- return
- -- give empty syringe on using some medical items
- elseif empty_syringe_items[sec] then
- alife_create_item("e_syringe", db.actor)
- -- weather radar
- elseif (sec == "device_weather_radar") then
- ui_debug_weather.activate()
- return
- end
- -- don't discharge items with no removal
- if IsItem("multiuse_r",sec) then
- local uses = obj:get_remaining_uses()
- local max_uses = obj:get_max_uses()
- if uses and max_uses and (uses < max_uses) then
- obj:set_remaining_uses(uses + 1)
- end
- end
- end
- local str_itm_taken = game.translate_string("st_item_taken")
- function actor_on_item_take(obj)
- local sec = obj:section()
- -- Play sound effect for item taking
- play_item_sound(obj)
- if IsWeapon(obj) and se_load_var(item_id, nil, "strapped_item") then
- se_save_var(obj:id(), nil, "strapped_item", nil)
- -- Explosive barrels
- elseif (sec == "explosive_mobiltank") or (sec == "explosive_tank") then
- local se_obj = alife_object(obj:id())
- local fuel = tostring(math.random(6,8))
- if se_obj then
- alife_release(se_obj)
- alife_create_item("explo_jerrycan_fuel", db.actor, {uses = 2})
- end
- -- Story special
- elseif (sec == "main_story_1_quest_case") and (not has_alife_info("agr_u_bloodsucker_on_case")) then
- db.actor:give_info_portion("agr_u_bloodsucker_on_case")
- xr_effects.create_squad(nil,nil,{"agr_u_bloodsucker_3_squad","agr_u_bloodsucker"})
- end
- -- Show notification
- --local str = strformat(str_itm_taken, ui_item.get_sec_name(sec))
- --actor_menu.set_msg(2, str)
- end
- function dropdrop_ArtyContainer(obj_1, obj_2, sec_1, sec_2) -- Put artefact in container
- local cont = sec_2
- local arty = sec_1
- if ini_sys:section_exist(arty .. "_" .. cont) then
- local cond = obj_1 and obj_1:condition()
- actor_effects.play_item_fx("container_tool_" .. cont .. "_dummy")
- alife_create_item(arty .. "_" .. cont, db.actor, { cond = cond } )
- alife_release(obj_1)
- alife_release(obj_2)
- end
- end
- function dropdrop_Basic_Combination(obj_1, obj_2, sec_1, sec_2) -- Combine basic items
- local sec_new = item_combine[sec_1][sec_2]
- actor_effects.play_item_fx("item_combination")
- alife_create_item(sec_new, db.actor)
- alife_release(obj_1)
- alife_release(obj_2)
- end
- function ActorMenu_on_item_drag_drop(obj_1, obj_2, slot_from, slot_to)
- -- Check capability
- if not (slot_from == EDDListType.iActorBag and slot_to == EDDListType.iActorBag) then
- return
- end
- local sec_1 = obj_1:section()
- local sec_2 = obj_2:section()
- if itms_arty_container[sec_2] then
- if (ini_sys:r_string_ex(sec_1,"class") == "ARTEFACT") or (ini_sys:r_string_ex(sec_1,"class") == "SCRPTART") then
- dropdrop_ArtyContainer(obj_1, obj_2, sec_1, sec_2)
- end
- elseif item_combine[sec_1] and item_combine[sec_1][sec_2] then
- dropdrop_Basic_Combination(obj_1, obj_2, sec_1, sec_2)
- end
- end
- local focus_last_sec
- local focus_tbl = {}
- local focus_upgr = {}
- function ActorMenu_on_item_focus_receive(obj) -- highlight compatible items
- --[[
- local parent = obj:parent()
- if not (parent and parent:id() == AC_ID) then
- return
- end
- --]]
- local sec_focus = obj:section()
- if (focus_last_sec ~= sec_focus) then
- local id = obj:id()
- focus_last_sec = sec_focus
- empty_table(focus_tbl)
- local parent_sec = ini_sys:r_string_ex(sec_focus,"parent_section") or sec_focus
- -- For weapons
- if IsWeapon(obj) then
- -- Ammo
- local ammo = utils_item.get_ammo(sec_focus, id)
- for i=1,#ammo do
- focus_tbl[#focus_tbl + 1] = ammo[i]
- end
- -- Scopes
- local scopes = parse_list(ini_sys, parent_sec, "scopes")
- for i=1,#scopes do
- focus_tbl[#focus_tbl + 1] = scopes[i]
- end
- local scope = utils_item.get_wpn_param(obj, sec_focus, "scopes_sect")
- if scope and (obj:weapon_scope_status() == 2) then
- focus_tbl[#focus_tbl + 1] = scope
- end
- -- Silencer
- local sil = utils_item.get_wpn_param(obj, sec_focus, "silencer_name")
- if sil and (obj:weapon_silencer_status() == 2) then
- focus_tbl[#focus_tbl + 1] = sil
- end
- -- Grenade Launcher
- local gl = utils_item.get_wpn_param(obj, sec_focus, "grenade_launcher_name")
- if gl and (obj:weapon_grenadelauncher_status() == 2) then
- focus_tbl[#focus_tbl + 1] = gl
- end
- end
- -- Parts
- local parts_str = ini_parts:r_string_ex("con_parts_list",parent_sec)
- local parts = parts_str and (parts_str ~= "") and str_explode(parts_str,",")
- if parts then
- for i=1,#parts do
- focus_tbl[#focus_tbl + 1] = parts[i]
- end
- end
- -- Repair kits
- local repair_type = ini_sys:r_string_ex(parent_sec,"repair_type")
- if repair_type and repair_type ~= "" then
- for kit,v in pairs(GetItemList("repair")) do
- if v[repair_type] then
- focus_tbl[#focus_tbl + 1] = kit
- end
- end
- --[[
- for kit,v in pairs(GetItemList("workshop")) do
- if v[repair_type] then
- focus_tbl[#focus_tbl + 1] = kit
- end
- end
- --]]
- end
- -- Upgrade parts
- local upgr_str = ini_sys:r_string_ex(parent_sec,"upgrades")
- if upgr_str and upgr_str ~= "" then
- if (not focus_upgr[parent_sec]) then
- local upgr = parse_list(ini_sys,parent_sec,"upgrades")
- focus_upgr[parent_sec] = {}
- for i=1,#upgr do
- extract_upgr_tools(focus_upgr[parent_sec], upgr[i])
- end
- end
- for tool,_ in pairs(focus_upgr[parent_sec]) do
- --printf("- upgrade part for [%s] -> [%s]", parent_sec, tool)
- focus_tbl[#focus_tbl + 1] = tool
- end
- end
- end
- local inventory = GetActorMenu()
- if not ((#focus_tbl > 0) or (inventory and inventory:IsShown())) then
- return
- end
- for i=1,#focus_tbl do
- inventory:highlight_section_in_slot(focus_tbl[i],EDDListType.iActorBag)
- inventory:highlight_section_in_slot(focus_tbl[i],EDDListType.iPartnerTradeBag)
- inventory:highlight_section_in_slot(focus_tbl[i],EDDListType.iDeadBodyBag)
- inventory:highlight_section_in_slot(focus_tbl[i],EDDListType.iActorTrade)
- inventory:highlight_section_in_slot(focus_tbl[i],EDDListType.iPartnerTrade)
- end
- end
- function save_state(m_data) --// NOTE: bolts aren't saved in alife, so this is a temp solution
- local bolts = {}
- local function itr(obj)
- local sec = obj:section()
- if (sec == "bolt") or (sec == "bolt_bullet") then
- if (not bolts[sec]) then
- bolts[sec] = 0
- end
- bolts[sec] = bolts[sec] + 1
- end
- return false
- end
- db.actor:inventory_for_each(itr)
- m_data.bolts = bolts
- m_data.bolt_slot = db.actor:item_in_slot(6) and db.actor:item_in_slot(6):section() or nil
- end
- -------------------------------
- -- ITEM OPTIONS (MENU)
- -------------------------------
- function menu_open(itm) -- return "open" name
- local p = itm:parent()
- if not (p and p:id() == AC_ID) then return end
- if itms_arty_container[itm:section()] then return end -- default containers
- return game.translate_string("st_item_open")
- end
- function menu_unpack(itm) -- return "unpack" name
- local p = itm:parent()
- if not (p and p:id() == AC_ID) then return end
- return game.translate_string("st_item_unpack")
- end
- function menu_play(itm) -- return "Play" name
- local p = itm:parent()
- if not (p and p:id() == AC_ID) then return end
- return game.translate_string("st_item_play")
- end
- function menu_place(obj) -- return "Place" name
- return game.translate_string("st_item_place")
- end
- -------------------------------
- -- ITEM OPTIONS (FUNCTOR)
- -------------------------------
- function use_package(obj)
- local sec = obj:section()
- local content = parse_list(ini_manager, "package_content", sec)
- if #content > 0 then
- utils_item.delay_event(content, {obj:id()}, "package_content", false, 5)
- end
- end
- function use_package_random(obj)
- local sec = obj:section()
- local content = ini_manager:r_string_ex("package_content",sec)
- if not content then return end
- local t = str_explode(content,",")
- local pick = {}
- for i=1,#t do
- if (#pick < 6) and (math.random(100) < 50) then
- pick[#pick+1] = t[i]
- end
- end
- pick = #pick > 1 and pick or {t[1],t[2],t[3],t[4]}
- utils_item.delay_event(pick, {obj:id()}, "package_content", true, 5)
- end
- function use_deployable_mgun(obj)
- local pos = vector():set(device().cam_pos)
- pos:add(device().cam_dir:mul(3))
- alife_create("deployable_mgun",pos,level.vertex_id(pos),db.actor:game_vertex_id())
- end
- function use_guitar(obj)
- local n = math.random(28)
- local snd = sound_object("music\\guitar_" .. tostring(n))
- if (not snd) then return end
- local period = snd:length()
- snd:play_no_feedback(db.actor, 0, 0, db.actor:position(), 1.0, 1.0)
- playing_instrument = "guitar_a"
- playing_music_length = period / 1000
- actor_effects.play_continuous_effect(period)
- end
- function use_harmonica(obj)
- local n = math.random(5)
- local snd = sound_object("music\\harmonica_" .. tostring(n))
- if (not snd) then return end
- local period = snd:length()
- snd:play_no_feedback(db.actor, 0, 0, db.actor:position(), 1.0, 1.0)
- playing_instrument = "harmonica_a"
- playing_music_length = period / 1000
- actor_effects.play_continuous_effect(period)
- end
- function use_arty_container(obj)
- local break_con
- local break_arty
- local sec = obj:section()
- if (string.find(sec, "(lead.-_box)",3)) then
- break_con = "lead_box"
- break_arty = sec:gsub("_lead_box", "")
- elseif (string.find(sec, "(af.-_iam)",3)) then
- break_con = "af_iam"
- break_arty = sec:gsub("_af_iam", "")
- elseif (string.find(sec, "(af.-_aac)",3)) then
- break_con = "af_aac"
- break_arty = sec:gsub("_af_aac", "")
- elseif (string.find(sec, "(af.-_aam)",3)) then
- break_con = "af_aam"
- break_arty = sec:gsub("_af_aam", "")
- end
- if break_con and break_arty and ini_sys:section_exist(break_con) and ini_sys:section_exist(break_arty) then
- local cond = obj:condition()
- _G.ARTY_FROM_CONT = true -- Hack to prevent player from exploting Artefacts Containers (gaining rank by recieving artefacts)
- actor_effects.play_item_fx(break_con .. "_dummy")
- alife_create_item(break_con, db.actor)
- alife_create_item(break_arty, db.actor, { cond = cond } )
- alife_release(obj)
- end
- end
- function use_watch(obj)
- local Y, M, D, h, mint, sec, ms = game.get_game_time():get()
- local pharse = game.translate_string("st_dyn_news_day_part_am")
- local mints = tostring(mint)
- if (h > 12) then
- h = h - 12
- pharse = game.translate_string("st_dyn_news_day_part_pm")
- elseif (h == 12) then
- pharse = game.translate_string("st_dyn_news_day_part_pm")
- elseif (h == 0) then
- h = 12
- end
- if (mint < 10) then
- mints = "0" .. tostring(mint)
- end
- utils_xml.hide_menu()
- actor_menu.set_msg(1, tostring(h) .. ":" .. mints .. " " .. pharse , 3)
- end
- function use_place(obj)
- local p = obj:parent()
- if not (p and p:id() == AC_ID) then
- return
- end
- local section = obj:section()
- alife_release_id(obj:id())
- local pos = db.actor:position()
- pos:add(device().cam_dir:mul(1.2))
- pos.y = db.actor:position().y + 1
- local lvid = db.actor:level_vertex_id()
- local gvid = db.actor:game_vertex_id()
- local se_obj = alife_create(section,pos,lvid,gvid)
- local rot = device().cam_dir:getH()
- se_obj.angle = vector():set(0,rot,0)
- end
- -------------------------------
- -- OTHERS
- -------------------------------
- function actor_on_trade(obj,sell_bye,money) -- bind_stalker on_trade
- end
- function actor_item_take(obj) -- bind_stalker on_item_take
- end
- function npc_on_item_take_from_box(npc,box,item)
- end
- function new_game_equippment()
- -- Damage equipment
- local function damage_items(actor,itm)
- local sec = itm:section()
- if (IsWeapon(itm) and (sec ~= "wpn_binoc_inv")) or IsOutfit(itm) or IsHeadgear(itm) or IsItem("device",sec) then
- itm:set_condition(math.random(75,85)/100)
- end
- end
- db.actor:iterate_inventory(damage_items,db.actor)
- give_info("start_equippment_handled")
- -- Override autosave
- exec_console_cmd("save " .. user_name() .. " - autosave")
- printf("- Autosaved new game")
- -- Override ammo type if required
- local start_wpn_tbl = alife_storage_manager.get_state().start_wpn_ammo
- if start_wpn_tbl then
- for id, ammo_sec in pairs(start_wpn_tbl) do
- local wpn = level.object_by_id(id)
- if wpn then
- local ammo_list = utils_item.get_ammo(wpn:section(), wpn:id())
- local ammo_type
- for i=1,#ammo_list do
- if (ammo_list[i] == ammo_sec) then
- ammo_type = i-1
- break
- end
- end
- if ammo_type then
- local wpn_ammo_mag_size = ini_sys:r_u32(wpn:section(), "ammo_mag_size")
- if wpn_ammo_mag_size then
- wpn:unload_magazine()
- wpn:set_ammo_type(ammo_type)
- wpn:set_ammo_elapsed(wpn_ammo_mag_size )
- printdbg("- New game weapon | [%s] - ammo type used: %s", wpn:section(), ammo_type)
- end
- end
- end
- end
- end
- return true
- end
- function bolt_manager() -- limit bolt count in actor inventory
- ResetTimeEvent("cycle","bolt_manager",60)
- local sim = alife()
- local bolt_max_num = ini_manager:r_float_ex("settings","bolt_max_num") or 99
- local cnt = 0
- local id, sec, se_obj
- local function itr(temp, obj)
- sec = obj:section()
- if (sec == "bolt") or (sec == "bolt_bullet") then
- cnt = cnt + 1
- if (cnt > bolt_max_num) then
- local se_obj = alife_object(obj:id())
- if se_obj then
- alife_release(se_obj)
- end
- end
- end
- end
- db.actor:iterate_ruck(itr, nil)
- return false
- end
- function give_item_reward(num_of_items)
- num_of_items = num_of_items or 1
- local prior = {
- ["health"] = 2,
- ["rad"] = 2,
- ["drink"] = 2,
- ["food"] = 2,
- ["ammo"] = 2,
- ["battery"] = 0,
- }
- local tot_power,tot_devices = 0,0
- local ammo_suitable = {}
- local ammo_avail = {}
- local function itr(obj)
- local sec = obj:section()
- -- Evaluate medkits
- if item_rewards["items_health"][sec] then
- prior["health"] = prior["health"] - 1
- end
- -- Evaluate anti-rads
- if item_rewards["items_rad"][sec] then
- prior["rad"] = prior["rad"] - 1
- end
- -- Evaluate drink
- if item_rewards["items_drink"][sec] then
- prior["drink"] = prior["drink"] - 1
- end
- -- Evaluate food
- if item_rewards["items_food"][sec] then
- prior["food"] = prior["food"] - 1
- end
- -- Evaluate devices power
- if IsItem("device",sec) then
- tot_devices = tot_devices + 1
- tot_power = tot_power + (obj:condition() * 100)
- end
- -- Evaluate weapons and ammo
- if (sec ~= "wpn_binoc") and IsWeapon(obj) and (not IsMelee(obj)) then
- local ammo = utils_item.get_ammo(obj:section(), obj:id())
- if ammo and #ammo > 1 then
- for i=1,#ammo do
- local sec_ammo = ammo[i]
- if item_rewards["items_ammo"][sec_ammo] then
- ammo_suitable[sec_ammo] = true
- end
- end
- end
- end
- if IsItem("ammo",sec) then
- ammo_avail[sec] = { cnt = obj:ammo_get_count() , box = IsItem("ammo",sec) }
- --printf("ammo_avail[%s] = { cnt = %s | box = %s", sec, ammo_avail[sec].cnt, ammo_avail[sec].box)
- end
- return false
- end
- db.actor:inventory_for_each(itr)
- -- Total power of devices is less than %50 -> need battery
- if (tot_power < (50 * tot_devices)) then
- prior["battery"] = 1
- end
- -- No enough ammo found for existing weapons -> need ammo
- for sec,_ in pairs(ammo_suitable) do
- local ammo = ammo_avail[sec]
- if ammo and (ammo.cnt >= ammo.box) then
- prior["ammo"] = prior["ammo"] - 1
- end
- end
- --[[
- for k,p in pairs(prior) do
- printf("- Prior[%s] = %s",k,p)
- end
- --]]
- -- Give actor items
- for i=1,num_of_items do
- -- Search from higher to lower priority
- local picker = {}
- local pick_prior
- local functor = function(t,a,b) return t[a] > t[b] end
- for k,p in spairs(prior,functor) do
- if (p > 0) then
- if (not pick_prior) or (pick_prior == p) then
- pick_prior = p
- picker[#picker + 1] = k
- end
- end
- end
- if pick_prior and (#picker > 0) then
- -- Pick random type of this priority
- local item_reward
- local k = picker[math.random(#picker)]
- -- Pick random item
- if k == "health" then
- item_reward = random_key_table(item_rewards["items_health"])
- elseif k == "rad" then
- item_reward = random_key_table(item_rewards["items_rad"])
- elseif k == "drink" then
- item_reward = random_key_table(item_rewards["items_drink"])
- elseif k == "food" then
- item_reward = random_key_table(item_rewards["items_food"])
- elseif k == "battery" then
- item_reward = item_device.device_battery
- elseif k == "ammo" then
- item_reward = random_key_table(ammo_suitable)
- end
- if item_reward then
- -- Reduce priority
- prior[k] = prior[k] - 1
- local amount = 1
- -- Give items
- local box_size = IsItem("ammo",item_reward)
- local max_uses = IsItem("multiuse",item_reward)
- local uses = max_uses and (max_uses >= 2) and 2 or 1
- if uses then
- amount = math.random(1,uses)
- end
- alife_create_item(item_reward, db.actor, {uses = amount , ammo = box_size})
- -- Send news
- news_manager.relocate_item(db.actor, "in", item_reward, amount)
- end
- break
- end
- end
- end
- function send_itm_msg(sec)
- local str = strformat(game.translate_string("st_item_taken"), ui_item.get_sec_name(sec))
- actor_menu.set_msg(2, str)
- end
- local upg_gr = {
- ["first"] = 1,
- ["secon"] = 2,
- ["third"] = 3,
- ["fourt"] = 4,
- ["fifth"] = 5,
- }
- local upg_ind = {
- ["a"] = 1,
- ["b"] = 2,
- ["c"] = 3,
- ["d"] = 4,
- ["e"] = 5,
- ["f"] = 6,
- }
- function extract_upgr_tools(t1, current_grp)
- local elements = parse_list(ini_sys, current_grp, "elements")
- -- Gather groups and indexes
- for i=1,#elements do -- search in upgrade group elements
- for k,v in pairs(upg_gr) do
- if string_find(elements[i],k) then -- if we found a legit element
- local indx = elements[i]:sub(9,9) -- get the index
- local upg_idx = indx and upg_ind[indx]
- if upg_idx then
- local prop = ini_sys:r_string_ex(elements[i],"property")
- if prop then
- local pr = str_explode(prop,",")
- local tool = utils_item.get_upgrade_prop_tool(pr[1])
- local num = ((upg_idx <= 2) and 1) or ((upg_idx <= 4) and 2) or 3
- local sec_tool = tool and tool:gsub("%^d", tostring(num)) or nil
- if sec_tool then
- t1[sec_tool] = true
- else
- local sec = ini_sys:r_string_ex(elements[i],"section")
- printdbg("! extract_upgr | can't generate tool for upgrade [%s], property: %s", sec, pr[1])
- end
- end
- end
- end
- end
- end
- -- Repeat
- for i=1,#elements do
- local next_grp = ini_sys:r_string_ex(elements[i],"effects")
- if next_grp and (next_grp ~= "") then
- extract_upgr_tools(t1,next_grp)
- end
- end
- end
- -------------------------------
- -- MULTI-USE ITEMS
- -------------------------------
- function relocate_item_to_actor(actor, npc, section, amount)
- if (not actor) then
- return
- end
- amount = amount or 1
- local npc_inv = npc and (not IsItem("anim",section)) and utils_item.collect_amount(npc, section, 1) or {}
- local sim = alife()
- local cnt = amount
- local max_uses = IsItem("multiuse",section) or 1
- while cnt > 0 do
- -- Create or transfer object from npc
- local id
- if not is_empty(npc_inv) then
- local id_pick = random_key_table(npc_inv)
- local obj = id_pick and level.object_by_id(id_pick)
- if obj then
- npc:transfer_item(obj, actor)
- npc_inv[id_pick] = nil
- id = id_pick
- end
- else
- local se_obj = alife_create_item(section, db.actor)
- id = se_obj and se_obj.id
- -- Register PDA if found
- if npc and id and item_device.device_npc_pda[section] then
- ui_pda_npc_tab.register_pda(npc, section, id)
- end
- end
- -- Set remaining uses if needed
- if id then
- cnt = cnt - max_uses
- if cnt < 0 then
- local uses = (max_uses - (-cnt))
- process_item(section , id, {uses = uses} )
- end
- else
- printe("!ERROR: relocate_item_to_actor | object for section [%s] is bugged!", section)
- break
- end
- end
- local box_size = IsItem("ammo",section)
- if box_size then
- amount = amount * box_size
- end
- news_manager.relocate_item(actor, "in", section, amount)
- end
- function relocate_item_from_actor(actor, npc, section, amount)
- if (not actor) then
- return
- end
- if (npc == nil) then
- --printe("!ERROR: Couldn't relocate_item_from_actor | no npc found!")
- end
- amount = amount or 1
- local cnt = amount
- local max_uses = IsItem("multiuse",section)
- local keep_itr = true
- local function itr(temp, obj)
- --printf("~relocate_item_from_actor | checked [%s]", obj:section())
- if keep_itr and (obj and obj:section() == section) then
- --printf("-relocate_item_from_actor | found needed section [%s]", section)
- local uses = max_uses and obj:get_remaining_uses() or 1
- cnt = cnt - uses
- if (cnt >= 0) then
- if npc then
- actor:transfer_item(obj, npc)
- else
- alife_release_id(obj:id())
- end
- if (cnt == 0) then
- keep_itr = false
- end
- else
- local remain_1 = -cnt
- local remain_2 = max_uses - remain_1
- process_item(section, obj:id(), {uses = remain_1})
- if npc then
- alife_create_item(section, npc, {uses = remain_2})
- end
- keep_itr = false
- end
- end
- end
- actor:iterate_inventory(itr, nil)
- if cnt > 0 then
- printe("! ERROR: Couldn't relocate_item_from_actor | not enough item [%s] recolated! need %s more", section, cnt)
- end
- local box_size = IsItem("ammo",section)
- if box_size then
- amount = amount * box_size
- end
- news_manager.relocate_item(actor, "out", section, amount)
- end
- -------------------------------
- -- Sound Effects
- -------------------------------
- local time_snd_prev = 0
- local snd_on_take = {
- ["coin"] = {"interface\\items\\inv_items_money_coin_2"},
- ["bolt"] = {"interface\\items\\inv_items_ammo_1"},
- ["paper"] = {"interface\\items\\inv_items_money_paper"},
- ["bottle"] = {"interface\\items\\inv_items_bottle_",1,2},
- ["pills"] = {"interface\\items\\inv_items_pills_2"},
- ["part"] = {"interface\\items\\inv_items_parts_",1,2},
- ["outfit"] = {"interface\\items\\inv_items_cloth_",1,3},
- ["ammo"] = {"interface\\items\\inv_items_ammo_",4,7},
- ["grenade"] = {"interface\\items\\inv_items_grenade_",1,2},
- ["knife"] = {"interface\\items\\inv_items_knife_",1,2},
- ["weapon"] = {"interface\\items\\inv_items_wpn_",1,2},
- ["other"] = {"interface\\items\\inv_items_generic_",2,5},
- }
- function play_item_sound(item, vol)
- if (not item) then
- printe("!ERROR itms_manager | play_item_sound | no object recieved!")
- end
- local snd_type = SYS_GetParam(0,item:section(),"snd_on_take")
- if not (snd_type and snd_type ~= "") then
- return
- end
- local snd = snd_on_take[snd_type]
- if (not snd) then
- return
- end
- local snd_obj
- if (#snd == 1) then
- snd_obj = sound_object(snd[1])
- else
- snd_obj = sound_object(snd[1] .. tostring(math.random(snd[2],snd[3])))
- end
- local time_g = time_global()
- if snd_obj and (time_g > time_snd_prev + 25) then
- snd_obj:play(db.actor,0,sound_object.s2d)
- snd_obj.volume = vol or 1
- end
- time_snd_prev = time_g
- end
- -------------------------------
- -- Item Processor
- -------------------------------
- local c_instance
- function get_item_processor()
- if c_instance == nil then
- c_instance = ItemProcessor()
- end
- return c_instance
- end
- function process_item(...)
- if c_instance == nil then
- c_instance = ItemProcessor()
- end
- return c_instance:Process_Item(...)
- end
- function create_item(...)
- if c_instance == nil then
- c_instance = ItemProcessor()
- end
- return c_instance:Create_Item(...)
- end
- class "ItemProcessor"
- function ItemProcessor:__init()
- self.Remove = {}
- self.Cond = {}
- self.Uses = {}
- self.Ammo = {}
- self.Debug = false -- true to debug
- self.Cycles = 10
- end
- function ItemProcessor:update()
- -- Process Condition
- for id,con in pairs(self.Cond) do
- local obj = level.object_by_id(id)
- if obj then
- if self.Debug then
- printf("* ItemProcessor | processing condition | id: %s - con: %s", id, con)
- end
- obj:set_condition(con)
- local new_con = obj:condition()
- if (new_con < con + 0.02) and (new_con > con - 0.02) then -- range check
- self.Cond[id] = nil
- if self.Debug then
- printf("# ItemProcessor | processing condition done | id: %s - con: %s", id, new_con)
- end
- else
- self:Remove_Process(id,"!","can't set condition!")
- end
- elseif alife_object(id) then
- self:Remove_Process(id,"~","server object exists, no game object yet")
- else
- self:Remove_Process(id,"!","no game object!")
- end
- end
- -- Process Uses
- for id,uses in pairs(self.Uses) do
- local obj = level.object_by_id(id)
- if obj then
- if self.Debug then
- printf("* ItemProcessor | processing uses | id: %s - uses: %s", id, uses)
- end
- obj:set_remaining_uses(uses)
- if (obj:get_remaining_uses() == uses) then
- self.Uses[id] = nil
- if self.Debug then
- printf("# ItemProcessor | processing uses done | id: %s - con: %s", id, uses)
- end
- else
- self:Remove_Process(id,"!","can't set uses!")
- end
- elseif alife_object(id) then
- self:Remove_Process(id,"~","server object exists, no game object yet")
- else
- self:Remove_Process(id,"!","no game object!")
- end
- end
- -- Process Ammo
- for id,ammo in pairs(self.Ammo) do
- local obj = level.object_by_id(id)
- if obj then
- if self.Debug then
- printf("* ItemProcessor | processing ammo | id: %s - ammo: %s", id, ammo)
- end
- obj:ammo_set_count(ammo)
- if (obj:ammo_get_count() == ammo) then -- range
- self.Ammo[id] = nil
- if self.Debug then
- printf("# ItemProcessor | processing ammo done | id: %s - con: %s", id, new_con)
- end
- else
- self:Remove_Process(id,"!","can't set ammo!")
- end
- elseif alife_object(id) then
- self:Remove_Process(id,"~","server object exists, no game object yet")
- else
- self:Remove_Process(id,"!","no game object!")
- end
- end
- end
- function ItemProcessor:Create_Item(section, owner, t)
- t = t or {}
- if section then
- local uses
- section, uses = self:Extract_Uses(section)
- if (ini_sys:section_exist(section)) then
- -- Spawn object
- local se_itm
- if owner then
- -- Collect spawn data
- local pos, lvi, gvi, pid, spawn_typ
- if (type(owner) == "table") then
- pos, lvi, gvi, pid = owner[1], owner[2], owner[3], owner[4]
- if pid then
- spawn_typ = "on custom object"
- else
- spawn_typ = "in world"
- end
- elseif (type(owner.id) == "function") then
- pos, lvi, gvi, pid = owner:position(), owner:level_vertex_id(), owner:game_vertex_id(), owner:id()
- spawn_typ = "on game object"
- elseif owner.id then
- pos, lvi, gvi, pid = owner.position, owner.m_level_vertex_id, owner.m_game_vertex_id, owner.id
- spawn_typ = "on server object"
- end
- -- Validate
- if not (pos and lvi and gvi) then
- callstack()
- printe("! ItemProcessor | Missing spawn properties for [%s] | Spawn type: %s | pos: %s, lvi: %s, gvi: %s", section, spawn_typ, pos , lvi , gvi)
- return nil
- end
- if self.Debug then
- local obj_p = pid and alife_object(pid)
- local name_p = obj_p and (obj_p.id == AC_ID and "actor" or obj_p:name()) or ""
- spawn_typ = spawn_typ .. (obj_p and (" (".. name_p .. ")") or "")
- end
- -- Ammo need unique process to spawn multi-objects, return result from here
- if t.ammo and t.ammo > 0 and IsItem("ammo",section) then
- -- Replace damaged items with old if _NO_DAMAGED_AMMO allows it
- if _NO_DAMAGED_AMMO and string_find(section,"verybad") then
- local new_section = string_gsub(section,"verybad","bad")
- if ini_sys:section_exist(new_section) then
- section = new_section
- end
- end
- local num_in_box = ini_sys:r_u32(section, "box_size")
- local num = t.ammo
- local se_tbl = {}
- local sim = alife()
- local p_id = pid or 65535 -- because xray
- while (num > num_in_box) do
- se_tbl[#se_tbl+1] = sim:create_ammo(section, pos, lvi, gvi, p_id, num_in_box)
- alife_record( se_tbl[#se_tbl] , true )
- num = num - num_in_box
- if self.Debug then
- local se_ammo = se_tbl[#se_tbl]
- printf("/ alife_create [%s] (%s) x%s ammo %s", section, se_ammo and se_ammo.id, num_in_box, spawn_typ)
- end
- end
- se_tbl[#se_tbl+1] = sim:create_ammo(section, pos, lvi, gvi, p_id, num)
- alife_record( se_tbl[#se_tbl] , true )
- if self.Debug then
- local se_ammo = se_tbl[#se_tbl]
- printf("/ alife_create [%s] (%s) x%s ammo %s", section, se_ammo and se_ammo.id, num, spawn_typ)
- end
- return se_tbl
- -- Other items
- else
- if pid then
- se_itm = alife():create(section, pos, lvi, gvi, pid)
- else
- se_itm = alife():create(section, pos, lvi, gvi)
- end
- if self.Debug then
- printf("/ alife_create [%s] (%s) on %s", section, se_itm and se_itm.id, spawn_typ)
- end
- end
- else
- printe("! ItemProcessor | Missing spawn owner for [%s]!", section)
- end
- -- Process
- if se_itm then
- alife_record(se_itm,true)
- -- Multiuse items
- if IsItem("multiuse",section) then
- uses = uses or t.uses
- -- Send to process
- if uses then
- self.Uses[se_itm.id] = uses --self:Process_Item(section, se_itm.id, { uses = uses })
- end
- -- Degradable items
- elseif utils_item.is_degradable(nil, section) then
- local cond = t.cond
- -- Parts
- if t.cond_cr and t.cond_ct and IsItem(cond_ct,section) then
- cond = (#t.cond_cr > 2) and self:Random_Choice(t.cond_cr) or self:Random_Condition(t.cond_cr)
- -- others
- elseif t.cond_r then
- cond = (#t.cond_r > 2) and self:Random_Choice(t.cond_r) or self:Random_Condition(t.cond_r)
- end
- -- Send to process
- if cond then
- self.Cond[se_itm.id] = cond --self:Process_Item(section, se_itm.id, { cond = cond })
- end
- end
- return se_itm
- else
- printe("!ERROR [%s] is not spawned by ItemProcessor",section)
- end
- else
- printe("! ItemProcessor | section [%s] doesn't exist!", section)
- end
- else
- printf("~ ItemProcessor | nothing is passed to process!")
- end
- return nil
- end
- function ItemProcessor:Process_Item(section, id, t)
- if t then
- if t.uses then
- self.Uses[id] = t.uses
- elseif t.cond then
- self.Cond[id] = t.cond
- elseif t.ammo then
- self.Ammo[id] = t.ammo
- elseif self.Debug then
- --printf("* ItemProcessor | no process done for [%s] (%s)", section, id)
- end
- end
- end
- function ItemProcessor:Remove_Process(id, mark, str)
- mark = mark or "~"
- self.Remove[id] = self.Remove[id] and (self.Remove[id] + 1) or 0
- if (self.Remove[id] > self.Cycles) then
- self.Cond[id] = nil
- self.Uses[id] = nil
- self.Ammo[id] = nil
- self.Remove[id] = nil
- if self.Debug then
- local obj = level.object_by_id(id)
- local p = obj and obj:parent()
- printf("%s ItemProcessor | %s: (%s) [%s] - owner: (%s) [%s]", mark, str, id, obj and obj:section(), p and p:id() or "-", p and p:section())
- end
- end
- end
- function ItemProcessor:Random_Choice(arg)
- if arg and (#arg > 0) then
- local r = math.random(1, #arg)
- return arg[r]
- end
- end
- function ItemProcessor:Random_Condition(arg)
- if arg and (#arg > 0) then
- return (math.random(arg[1], arg[2])/100)
- end
- end
- function ItemProcessor:Extract_Uses(sec_d)
- local _, __, sec_u, uses = string_find(sec_d,"(.*)__(%d)")
- if sec_u and uses and tonumber(uses) and ini_sys:section_exist(sec_u) then
- return sec_u, tonumber(uses)
- end
- return sec_d
- end
- --------------------------------------------------------------------------------
- -------------------------------
- -- DEBUG
- -------------------------------
- function generate_boosters_list()
- local config = ini_file_ex("booster_stats.ltx",true)
- ini_sys:section_for_each(function(section)
- local cls = ini_sys:r_string_ex(section,"class")
- if (cls == "II_FOOD") and (ini_sys:r_float_ex(section,"boost_time") > 0) then
- local str = ""
- str = str .. ("cost:" .. ini_sys:r_float_ex(section,"cost") .. "|")
- str = str .. (ini_sys:r_float_ex(section,"max_uses") and ("uses:" .. ini_sys:r_float_ex(section,"max_uses") .. "|") or ("uses:1|"))
- str = str .. ("boost_time:" .. ini_sys:r_float_ex(section,"boost_time") .. "|")
- if ini_sys:r_float_ex(section,"boost_max_weight") ~= 0 then
- str = str .. ("boost_max_weight:" .. ini_sys:r_float_ex(section,"boost_max_weight") .. "|")
- end
- if ini_sys:r_float_ex(section,"boost_health_restore") ~= 0 then
- str = str .. ("boost_health_restore:" .. ini_sys:r_float_ex(section,"boost_health_restore") .. "|")
- end
- if ini_sys:r_float_ex(section,"boost_power_restore") ~= 0 then
- str = str .. ("boost_power_restore:" .. ini_sys:r_float_ex(section,"boost_power_restore") .. "|")
- end
- if ini_sys:r_float_ex(section,"boost_radiation_restore") ~= 0 then
- str = str .. ("boost_radiation_restore:" .. ini_sys:r_float_ex(section,"boost_radiation_restore") .. "|")
- end
- if ini_sys:r_float_ex(section,"boost_bleeding_restore") ~= 0 then
- str = str .. ("boost_bleeding_restore:" .. ini_sys:r_float_ex(section,"boost_bleeding_restore") .. "|")
- end
- if ini_sys:r_float_ex(section,"boost_radiation_protection") ~= 0 then
- str = str .. ("boost_radiation_protection:" .. ini_sys:r_float_ex(section,"boost_radiation_protection") .. "|")
- end
- if ini_sys:r_float_ex(section,"boost_telepat_protection") ~= 0 then
- str = str .. ("boost_telepat_protection:" .. ini_sys:r_float_ex(section,"boost_telepat_protection") .. "|")
- end
- if ini_sys:r_float_ex(section,"boost_chemburn_protection") ~= 0 then
- str = str .. ("boost_chemburn_protection:" .. ini_sys:r_float_ex(section,"boost_chemburn_protection") .. "|")
- end
- if ini_sys:r_float_ex(section,"boost_burn_immunity") ~= 0 then
- str = str .. ("boost_burn_immunity:" .. ini_sys:r_float_ex(section,"boost_burn_immunity") .. "|")
- end
- if ini_sys:r_float_ex(section,"boost_shock_immunity") ~= 0 then
- str = str .. ("boost_shock_immunity:" .. ini_sys:r_float_ex(section,"boost_shock_immunity") .. "|")
- end
- if ini_sys:r_float_ex(section,"boost_radiation_immunity") ~= 0 then
- str = str .. ("boost_radiation_immunity:" .. ini_sys:r_float_ex(section,"boost_radiation_immunity") .. "|")
- end
- if ini_sys:r_float_ex(section,"boost_telepat_immunity") ~= 0 then
- str = str .. ("boost_telepat_immunity:" .. ini_sys:r_float_ex(section,"boost_telepat_immunity") .. "|")
- end
- if ini_sys:r_float_ex(section,"boost_chemburn_immunity") ~= 0 then
- str = str .. ("boost_chemburn_immunity:" .. ini_sys:r_float_ex(section,"boost_chemburn_immunity") .. "|")
- end
- if ini_sys:r_float_ex(section,"boost_strike_immunity") ~= 0 then
- str = str .. ("boost_strike_immunity:" .. ini_sys:r_float_ex(section,"boost_strike_immunity") .. "|")
- end
- if ini_sys:r_float_ex(section,"boost_wound_immunity") ~= 0 then
- str = str .. ("boost_wound_immunity:" .. ini_sys:r_float_ex(section,"boost_wound_immunity") .. "|")
- end
- if ini_sys:r_float_ex(section,"boost_explosion_immunity") ~= 0 then
- str = str .. ("boost_explosion_immunity:" .. ini_sys:r_float_ex(section,"boost_explosion_immunity") .. "|")
- end
- if ini_sys:r_float_ex(section,"boost_fire_wound_immunity") ~= 0 then
- str = str .. ("boost_fire_wound_immunity:" .. ini_sys:r_float_ex(section,"boost_fire_wound_immunity") .. "|")
- end
- config:w_value("temp", section, str)
- end
- end)
- config:save()
- end
Advertisement
Comments
-
- To implement the musical instrument psy heal, this modification adds the properties playing_instrument and playing_music_length to this script. These properties will track the instrument played and the music length.
- Modified lines: 40, 41, 604, 605, 615 and 616
Add Comment
Please, Sign In to add comment
Advertisement