Divergent/mods/Zone Customization Project/gamedata/scripts/smr_loot.script

461 lines
12 KiB
Plaintext

--[[
------------------------------------------------------------
-- Survival Mode Remade - Extra items from stash boxes
------------------------------------------------------------
-- MCM-configurable script to give the player a chance to get some extra items whenever they open a stash box.
-- by dph-hcl
------------------------------------------------------------
]]--
-- REPAIR KITS
local repair_tier1 = {
"glue_a",
"glue_b",
"glue_e",
"gun_oil",
"gun_oil_ru",
"gun_oil_ru_d",
"armor_repair_fa",
"sharpening_stones",
}
local repair_tier2 = {
"sharpening_stones",
"cleaning_kit_p",
"cleaning_kit_s",
"cleaning_kit_r5",
"cleaning_kit_r7",
"sewing_kit_b",
"sewing_kit_a",
}
local repair_tier3 = {
"cleaning_kit_u",
"toolkit_p",
"toolkit_s",
"sewing_kit_h",
"medium_repair_kit",
"helmet_repair_kit",
"light_repair_kit",
}
local repair_tier4 = {
"toolkit_r5",
"toolkit_r7",
"heavy_repair_kit",
"exo_repair_kit",
}
-- BASIC AMMO
local basic_ammo = {
"ammo_11.43x23_fmj",
"ammo_12x70_buck",
"ammo_7.62x25_p",
"ammo_12x76_zhekan",
"ammo_5.45x39_fmj",
"ammo_5.45x39_ep",
"ammo_5.56x45_fmj",
"ammo_5.56x45_ss190",
"ammo_9x18_fmj",
"ammo_9x19_fmj",
"ammo_11.43x23_hydro",
"ammo_12x76_dart",
"ammo_7.62x25_ps",
"ammo_5.45x39_ap",
"ammo_5.56x45_ap",
"ammo_9x18_ap",
"ammo_9x18_pmm",
"ammo_9x19_ap",
"ammo_9x19_pbp",
}
-- ADVANCED AMMO
local advanced_ammo = {
"ammo_357_hp_mag",
"ammo_7.62x39_fmj",
"ammo_7.62x51_fmj",
"ammo_7.62x54_7h1",
"ammo_9x39_pab9",
"ammo_7.62x39_ap",
"ammo_7.62x51_ap",
"ammo_7.62x54_7h14",
"ammo_7.62x54_ap",
"ammo_9x39_ap",
}
-- EXOTIC AMMO
local exotic_ammo = {
"ammo_12.7x55_fmj",
"ammo_4.6x30_fmj",
"ammo_5.7x28_ss195",
"ammo_7.92x33_fmj",
"ammo_m209",
"ammo_vog-25",
"ammo_12.7x55_ap",
"ammo_5.7x28_ss190",
"ammo_50_bmg",
"ammo_7.92x33_ap",
"ammo_magnum_300",
"ammo_pkm_100",
"ammo_gauss",
}
-- USEFUL ITEMS
local useful_tier1 = {
"device_torch_dummy",
"batteries_dead", "batteries_dead", "batteries_dead",
"detector_simple",
"af_iam",
"itm_sleepbag",
"wpn_knife2",
"wpn_axe",
"kit_hunt",
"wpn_binoc_inv",
"itm_actor_backpack",
"leatherman_tool",
"itm_sleepbag",
"equ_small_pack",
"af_aac",
}
local useful_tier2 = {
"device_torch_nv_1",
"detector_advanced",
"wpn_knife3",
"wpn_axe2",
"equ_small_military_pack",
"itm_tent",
}
local useful_tier3 = {
"device_torch_nv_2",
"detector_scientific",
"wpn_knife4",
"wpn_knife5",
"wpn_axe3",
"equ_military_pack",
}
local useful_tier4 = {
"device_torch_nv_3",
"detector_elite",
"af_aam",
"equ_tourist_pack",
}
-- MEDICAL ITEMS
local meds_tier1 = {
"bandage",
"caffeine",
"drug_sleepingpills",
"drug_coagulant",
"yadylin",
"medkit",
"jgut",
"glucose_s",
"antirad",
"antirad_cystamine",
}
local meds_tier2 = {
"medkit_army",
"stimpack",
"salicidic_acid",
"glucose",
"drug_psy_blockade",
"antirad_kalium",
"medkit_ai1",
"akvatab",
}
local meds_tier3 = {
"medkit_scientic",
"stimpack_army",
"morphine",
"drug_radioprotector",
"medkit_ai3",
"adrenalin",
"drug_anabiotic",
}
local meds_tier4 = {
"stimpack_scientic",
"survival_kit",
"medkit_ai2",
}
local lootboxes_tier1 = {
"lootbox_1",
"lootbox_11",
"lootbox_2",
"lootbox_5",
"lootbox_51",
}
local lootboxes_tier2 = {
"lootbox_7",
"lootbox_4",
"lootbox_41",
"lootbox_6",
"lootbox_61",
"lootbox_71",
"lootbox_3",
}
local lootboxes_tier3 = {
"lootbox_8",
"lootbox_81",
"lootbox_9",
}
-- table of already looted boxes
local boxes = {}
-- table of already looted npcs
local npcs = {}
local pda_msg_status = true
local function pda_message(type)
local strs = {
["repair"] = "st_smr_loot_found_repair",
["ammo"] = "st_smr_loot_found_ammo",
["meds"] = "st_smr_loot_found_meds",
["useful"] = "st_smr_loot_found_useful",
["mags"] = "st_smr_loot_found_mags",
["lootbox"] = "st_smr_loot_found_lootbox",
}
if (not smr_loot_mcm.get_config("send_message")) or (not pda_msg_status) then
return
end
db.actor:give_game_news(game.translate_string(strs[type]), "", "ui_inGame2_Polucheni_koordinaty_taynika", 0, 3000)
smr_debug.get_log().info("loot/general", "PDA message sent: %s", strs[type])
xr_sound.set_sound_play(AC_ID, "pda_tips")
end
-- creates an item with a random amount of uses or condition
local function create_item_random_uses(i, box)
smr_debug.get_log().info("loot/general", "Creating item with random uses: %s", i)
local max_uses = ini_sys:r_float_ex(i, "max_uses")
local se_item = alife_create_item(i, box)
if max_uses then
alife_process_item(i, se_item.id, {uses = (math.random(1, max_uses))})
elseif utils_item.is_degradable(nil, se_item.id) then
alife_process_item(i, se_item.id, {cond = (math.random(50,100)/100)})
end
end
local function roll_item_tiered(t, box)
local r = math.random(1,100)
table.sort(t, function(a, b) return a[1] > b[1] end)
for i, n in ipairs(t) do
if (r >= n[1]) then
local itm = n[2][math.random(#n[2])]
smr_debug.get_log().info("loot/rolls", "Rolled succesfully for %s (%s >= %s)", itm, r, n[1])
create_item_random_uses(itm, box)
return true
end
end
return false
end
function try_spawn_lootbox(box)
if math.random(1,100) <= smr_zzintegration_mcm.get_config("lootboxes_chance") then
pda_message("lootbox")
local tbl = {
{ 90, lootboxes_tier3},
{ 50, lootboxes_tier2},
{ 0, lootboxes_tier1},
}
roll_item_tiered(tbl, box)
end
end
function try_spawn_mag(box)
if math.random(1,100) <= smr_zzintegration_mcm.get_config("mags_redux_chance") then
smr_debug.get_log().info("integration", "Rolling for magazine")
local mags = {}
for i=1,3 do
local wpn = db.actor:item_in_slot(i)
if wpn and magazine_binder.is_supported_weapon(wpn) then
mags = magazine_binder.get_mags_for_basetype(magazine_binder.get_weapon_base_type(wpn))
end
end
if (next(mags) == nil) then
return
end
pda_message("mags")
alife_create_item(mags[math.random(#mags)], box)
end
end
-- rolls for a repair kit, and spawns if sucessful
function try_spawn_repair(box)
if math.random(1,100) <= smr_loot_mcm.get_config("repair_chance") then
pda_message("repair")
local tbl = {
{ 90, repair_tier4},
{ 50, repair_tier3},
{ 0, repair_tier2},
}
roll_item_tiered(tbl, box)
end
end
function try_spawn_repair_minor(box)
if math.random(1,100) <= smr_loot_mcm.get_config("repair_minor_chance") then
pda_message("repair")
create_item_random_uses(repair_tier1[math.random(#repair_tier1)], box)
end
end
-- rolls for ammo, and spawns if sucessful
function try_spawn_ammo(box)
if math.random(1,100) <= smr_loot_mcm.get_config("ammo_chance") then
pda_message("ammo")
local r = math.random(1,100)
if r > 90 then create_ammo(exotic_ammo[math.random(#exotic_ammo)], box)
elseif r > 60 then create_ammo(advanced_ammo[math.random(#advanced_ammo)], box)
else create_ammo(basic_ammo[math.random(#basic_ammo)], box)end
end
end
-- rolls for an medical item, and spawns if sucessful
function try_spawn_meds(box)
if math.random(1,100) <= smr_loot_mcm.get_config("meds_chance") then
pda_message("meds")
local tbl = {
{ 90, meds_tier4},
{ 70, meds_tier3},
{ 40, meds_tier2},
{ 0, meds_tier1},
}
roll_item_tiered(tbl, box)
end
end
-- rolls for a useful item, and spawns if sucessful
function try_spawn_useful(box)
local f = factor or 1
if math.random(1,100) <= smr_loot_mcm.get_config("useful_chance") then
pda_message("useful")
local tbl = {
{ 90, useful_tier4},
{ 70, useful_tier3},
{ 40, useful_tier2},
{ 0, useful_tier1},
}
roll_item_tiered(tbl, box)
end
end
-- creates a random amount of ammo in a box
function create_ammo(i, box)
local se_item
if smr_loot_mcm.get_config("ammo_bad_spawn") and (math.random(1,100) <= smr_loot_mcm.get_config("ammo_bad_chance"))
then se_item = alife_create_item(i .. "_bad", box)
else se_item = alife_create_item(i, box) end
local bs = ini_sys:r_float_ex(i, "box_size") or 10
local r = math.ceil(math.random(bs/2, bs*2) * smr_loot_mcm.get_config("ammo_amount"))
alife_process_item(i, se_item.id, {ammo = r})
end
function try_spawn(box)
if smr_zzintegration_mcm.get_config("mags_redux") and magazines then smr_loot.try_spawn_mag(box) end
if smr_zzintegration_mcm.get_config("lootboxes") and arti_lootboxes_mcm then smr_loot.try_spawn_lootbox(box) end
if smr_loot_mcm.get_config("repair_spawn") then smr_loot.try_spawn_repair(box) end
if smr_loot_mcm.get_config("repair_minor_spawn") then smr_loot.try_spawn_repair_minor(box) end
if smr_loot_mcm.get_config("ammo_spawn") then smr_loot.try_spawn_ammo(box) end
if smr_loot_mcm.get_config("useful_spawn") then smr_loot.try_spawn_useful(box) end
if smr_loot_mcm.get_config("meds_spawn") then smr_loot.try_spawn_meds(box) end
end
-- ---
-- ENTRY POINTS
-- ---
-- callback, used to write box table to save
local function save_state(data)
if not (data.smr_loot) then
data.smr_loot = {}
end
data.smr_loot.npcs = npcs
data.smr_loot.boxes = boxes
end
-- callback, used to load box table from save
local function load_state(data)
if not (data.smr_loot) then
return
end
boxes = data.smr_loot.boxes or {}
data.smr_loot.boxes = {}
npcs = data.smr_loot.npcs or {}
data.smr_loot.npcs = {}
end
-- callback, when opening boxes
local function physic_object_on_use_callback(box)
local id = box:id()
local player_stashes = alife_storage_manager.get_state().player_created_stashes
if (id and boxes and boxes[id]) or (player_stashes and player_stashes[id]) then
return
end
if (IsInvbox(box)) then
try_spawn(box)
boxes[id] = true
end
end
local function npc_on_death_callback(obj, who)
local id = obj:id()
if id and npcs and npcs[id] then
return
end
if math.random(1,100) <= smr_loot_mcm.get_config("npc_chance") then
pda_msg_status = false
try_spawn(obj)
pda_msg_status = true
npcs[id] = true
end
end
-- register callback for box opening
local function actor_on_first_update()
if smr_amain_mcm.get_config("smr_enabled") then
RegisterScriptCallback("physic_object_on_use_callback", physic_object_on_use_callback)
if smr_loot_mcm.get_config("npc_spawn") then
RegisterScriptCallback("npc_on_death_callback", npc_on_death_callback)
end
end
end
-- register callbacks for saving/loading
function on_game_start()
if not smr_amain_mcm.get_config("smr_enabled") then
return
end
if smr_zzintegration_mcm.get_config("glowsticks") and zz_glowstick_mcm then
table.insert(useful_tier1, "device_glowstick_orange")
table.insert(useful_tier1, "device_glowstick_red")
table.insert(useful_tier1, "device_glowstick_blue")
table.insert(useful_tier1, "device_glowstick")
end
if smr_zzintegration_mcm.get_config("lootboxes") and arti_lootboxes_mcm then
table.insert(useful_tier1, "lockpick")
table.insert(useful_tier1, "bundle_lockpick")
table.insert(useful_tier2, "lockpick_set")
table.insert(useful_tier4, "skeleton_key")
end
if smr_loot_mcm.get_config("repair_parts_spawn") then
table.insert(repair_tier1, "ramrod_tool")
table.insert(repair_tier1, "rasp_tool")
table.insert(repair_tier1, "sewing_thread")
table.insert(repair_tier2, "heavy_sewing_thread")
end
RegisterScriptCallback("save_state", save_state)
RegisterScriptCallback("load_state", load_state)
RegisterScriptCallback("npc_on_death_callback", npc_on_death_callback)
RegisterScriptCallback("actor_on_first_update", actor_on_first_update)
end