Divergent/mods/Anomaly Dependencies/gamedata/scripts/loadouts_injector.script

255 lines
8.9 KiB
Plaintext
Raw Permalink Normal View History

2024-03-17 20:18:03 -04:00
-- 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