-- custom loadouts local custom_loadouts = { name = {}, squad = {}, visual = {} } local custom_weapons = {} local ini_npc_loadouts = ini_file("loadouts\\npc_importer.ltx") local ini_wep_loadouts = ini_file("loadouts\\wep_importer.ltx") local ini_loadouts = ini_file("items\\settings\\npc_loadouts\\npc_loadouts.ltx") local scope_chance = {} local MAX_ITER = 10 local factions = { ["stalker"] = true, ["csky"] = true, ["dolg"] = true, ["ecolog"] = true, ["freedom"] = true, ["killer"] = true, ["army"] = true, ["bandit"]= true, ["monolith"] = true, ["renegade"] = true, ["isg"] = true, ["zombied"] = true, ["greh"] = true } local ranks = { ["novice"] = true, ["trainee"] = true, ["experienced"] = true, ["professional"] = true, ["veteran"] = true, ["expert"] = true, ["master"] = true, ["legend"] = true, } local slots = { ["primary"] = "primary", ["p"] = "primary", ["secondary"] = "secondary", ["s"] = "secondary", ["extra"] = "extra", ["e"] = "extra", } function preload() tmp = ini_loadouts:r_string_ex("settings","scope_chance") if tmp then tmp = str_explode(tmp,",") for i=1,#tmp do scope_chance[i] = tonumber(tmp[i]) or 0 end end custom_loadouts.meta = {} ini_npc_loadouts:section_for_each(function(section) local loadouts = ini_npc_loadouts:r_string_ex(section, "loadout_sec") loadouts = str_explode(loadouts, ",") local weapons = ini_npc_loadouts:r_string_ex(section, "weapons_sec") -- skip if loadout/weapons not defined (bad section) if is_empty(loadouts) or not weapons then return end if not ini_wep_loadouts:section_exist(weapons) then return end local n = ini_wep_loadouts:line_count(weapons) for i=0,n-1 do local _, id, value = ini_wep_loadouts:r_line_ex(weapons,i) --printf("Adding custom weapon %s", id) if not custom_weapons[id] then tmp = str_explode(id,":") if tmp and tmp[1] and ini_sys:section_exist(tmp[1]) then custom_weapons[id] = {} custom_weapons[id].sec = tmp[1] custom_weapons[id].attachment = tmp[2] or "0" custom_weapons[id].ammo_type = tmp[3] or "0" custom_weapons[id].chance = tonumber(tmp[4]) or 50 end end end for k,loadout in pairs(loadouts) do add_weapons_to_loadout(loadout, weapons) end end) end function add_weapons_to_loadout(loadout, weapons) --printf("Adding %s section of weapons to %s", weapons, loadout) tokens = str_explode(loadout, "_") if not (#tokens == 2 or #tokens == 3) then --printf("Invalid length") return end if not tokens[3] then tokens[3] = "primary" end if not factions[tokens[1]] then --printf("%s not faction", tokens[1]) return end if not ranks[tokens[2]] then --printf("%s not rank", tokens[2]) return end if not slots[tokens[3]] then --printf("%s not slot", tokens[3]) return end faction, rank, slot = unpack(tokens) slot = slots[slot] if not custom_loadouts[faction] then custom_loadouts[faction] = {} end if not custom_loadouts[faction][rank] then custom_loadouts[faction][rank] = {} end if not custom_loadouts[faction][rank][slot] then custom_loadouts[faction][rank][slot] = {} end local n = ini_wep_loadouts:line_count(weapons) --printf("Adding %s weapons for %s %s %s", n, faction, rank, slot) for i=0,n-1 do local _, id, value = ini_wep_loadouts:r_line_ex(weapons,i) if custom_weapons[id] then l = custom_loadouts[faction][rank][slot] l[#l+1] = id end end end function get_table(comm, rank, slot) if not custom_loadouts[comm] then return {} end if not custom_loadouts[comm][rank] then return {} end return custom_loadouts[comm][rank][slot] or {} end CreateItem = xrs_rnd_npc_loadout.create_item_on_npc function xrs_rnd_npc_loadout.create_item_on_npc(se_npc, squad_name, comm, rank, visual, player_id, slot_type) -- Get loadout section local loadout = ini_loadouts:r_string_ex("loadouts_per_squad",squad_name) or ini_loadouts:r_string_ex("loadouts_per_name",se_npc:section_name()) or ini_loadouts:r_string_ex("loadouts_per_visual",visual) or (comm .. "_" .. rank) if (not ini_loadouts:section_exist(loadout)) then loadout = comm if (not ini_loadouts:section_exist(loadout)) then loadout = "default" end end -- Get slot section local slot = ini_loadouts:r_string_ex(loadout,slot_type) --printf("Reading entries for slot %s, for %s %s %s", slot, comm, rank, slot_type) local vanilla_loadout_entries = not (slot and ini_loadouts:section_exist(slot)) and 0 or ini_loadouts:line_count(slot) local custom_tbl = get_table(comm, rank, slot_type) if not custom_tbl or is_empty(custom_tbl) then --printf("Defaulting to vanilla loadout") CreateItem(se_npc, squad_name, comm, rank, visual, player_id, slot_type) return end -- randomly pick entries from this range -- if the range is in vanilla loadout entries, roll from there -- otherwise local to_pick = vanilla_loadout_entries + #custom_tbl --printf("Picking from %s + %s entries", vanilla_loadout_entries, #custom_tbl) local pick = nil local iterations = 0 while not pick and iterations < MAX_ITER do local p = math.random(to_pick) if p > vanilla_loadout_entries then local new_entry = p - vanilla_loadout_entries local wpn = custom_weapons[custom_tbl[new_entry]] if math.random(100) < wpn.chance then pick = p break end elseif math.random(100) < 50 then pick = p break end iterations = iterations + 1 end if not pick then pick = math.random(to_pick) end local weapon_entry if pick > vanilla_loadout_entries then pick = pick - vanilla_loadout_entries id = custom_tbl[pick] if id then weapon_entry = custom_weapons[id] end end if weapon_entry then create_item(se_npc, weapon_entry) else CreateItem(se_npc, squad_name, comm, rank, visual, player_id, slot_type) end end function create_item(se_npc, item_data) local section = item_data.sec local ammo_typ = item_data.ammo_type local attachment = item_data.attachment -- Items if (slot_type == "extra") then alife_create_item(section, se_npc) -- Weapons else -- Add random scope local cha = game_difficulties.get_eco_factor("scope_chance") or scope_chance[ game_difficulties.get_eco_factor("type") or 1 ] cha = cha * 100 if ini_sys:line_exist(section,"scopes") and (math.random(100) <= cha) then local scopes = parse_list(ini_sys, section, "scopes") if scopes and (#scopes > 0) then local pick_scope = scopes[math.random(#scopes)] if pick_scope and ini_sys:section_exist(section .. "_" .. pick_scope) then section = section .. "_" .. pick_scope end end end local se_wpn = alife_create_item(section, se_npc) if (se_wpn) then local ammos = parse_list(ini_sys, section, "ammo_class") local ct = ammos and #ammos local ammo_type = (ammos and ammo_typ and ammo_typ == "r" and ct and math.random(0,ct-1)) or (ammos and ammo_typ and tonumber(ammo_typ)) or 0 local ammo_section = ammo_type and ammos[ammo_type+1] if not (ammo_section) then ammo_type = 0 ammo_section = ammo_type and ammos[ammo_type+1] printe("! ERROR: NPC Loadouts | wrong ammo_type set for [%s], missing value in ammo_class", section) end if (attachment or ammo_typ) then local data = utils_stpk.get_weapon_data(se_wpn) local flag = tonumber(attachment) or 0 if (attachment == "r") then flag = 0 if (utils_data.read_from_ini(nil,section,"scope_status","float",nil)) then flag = flag + 1 end if (utils_data.read_from_ini(nil,section,"grenade_launcher_status","float",nil)) then flag = flag + 2 end if (utils_data.read_from_ini(nil,section,"silencer_status","float",nil)) then flag = flag + 4 end flag = math.random(0,flag) end data.addon_flags = flag data.ammo_type = ammo_type utils_stpk.set_weapon_data(data,se_wpn) end end end end function on_game_start() preload() end