412 lines
15 KiB
Plaintext
412 lines
15 KiB
Plaintext
|
--[[
|
||
|
------------------------------------------------------------
|
||
|
-- Survival Mode Remade - Setup Zone population and manage smart terrain spawms
|
||
|
------------------------------------------------------------
|
||
|
-- by dph-hcl
|
||
|
------------------------------------------------------------
|
||
|
]]--
|
||
|
|
||
|
local zombie_spawn_table = {}
|
||
|
local zombie_spawn_cfg = {
|
||
|
["zombifiedp"] = { "zombied_sim_squad_novice", "zombied_sim_squad_advanced", "zombied_sim_squad_veteran" },
|
||
|
["fracturep"] = { "simulation_fracture" },
|
||
|
["snorkp"] = { "simulation_snork" },
|
||
|
["bloodsuckerp"] = { "simulation_bloodsucker" },
|
||
|
["psysuckerp"] = { "simulation_psysucker" },
|
||
|
["blindp"] = { "simulation_zombie_blind_3zomb_civ", "simulation_zombie_blind_3zomb" },
|
||
|
}
|
||
|
|
||
|
|
||
|
local faction_spawn_table = {}
|
||
|
local faction_spawn_cfg = {
|
||
|
"stalker", "bandit", "csky", "duty", "freedom", "merc", "army", "ecolog", "monolith", "renegade", "greh", "isg", "zombied"
|
||
|
}
|
||
|
|
||
|
local retarded_squad_names = {
|
||
|
["duty_sim_squad_alpha"] = "dolg_sim_squad_alpha",
|
||
|
["merc_sim_squad_alpha"] = "killer_sim_squad_alpha",
|
||
|
["duty_sim_squad_trader"] = "dolg_sim_squad_trader",
|
||
|
["duty_sim_squad_medic"] = "dolg_sim_squad_medic",
|
||
|
["duty_sim_squad_barman"] = "dolg_sim_squad_barman",
|
||
|
["duty_sim_squad_mechanic"] = "dolg_sim_squad_mechanic",
|
||
|
}
|
||
|
|
||
|
local mutant_spawn_table = {}
|
||
|
local mutant_spawn_cfg = {
|
||
|
["psysucker_"] = "psysuckerp",
|
||
|
["bloodsucker_"] = "bloodsuckerp",
|
||
|
["boar_"] = "boarp",
|
||
|
["snork_"] = "snorkp",
|
||
|
["chimera_"] = "chimerap",
|
||
|
["m_controller_"] = "controllerp",
|
||
|
["dog_"] = "dogp",
|
||
|
["tushkano_"] = "tushkanop",
|
||
|
["pseudodog_"] = "dogp",
|
||
|
["fracture_"] = "fracturep",
|
||
|
["lurker_"] = "lurkerp",
|
||
|
["cat_"] = "catp",
|
||
|
["psy_dog_"] = "psydogp",
|
||
|
["m_karlik_"] = "karlikp",
|
||
|
["burer_"] = "burerp",
|
||
|
["m_poltergeist_"] = "poltergeistp",
|
||
|
["gigant_"] = "gigantp",
|
||
|
["flesh_"] = "fleshp",
|
||
|
["rat_"] = "ratp",
|
||
|
["zombie_"] = "zombiep",
|
||
|
["borya_"] = "boryap",
|
||
|
["bibliotekar_"] = "bibliotekarp",
|
||
|
}
|
||
|
|
||
|
local unused_mutant_spawn_table = {}
|
||
|
local unused_mutant_spawn_cfg = {
|
||
|
["bloodsucker_strong_bigp"] = { "bloodsucker_strong_big" },
|
||
|
["burer_electrap"] = { "burer_electra" },
|
||
|
["burer_firerp"] = { "burer_fire" },
|
||
|
["flesh_bolotp"] = { "flesh_bolot", "flesh_bolot1" },
|
||
|
["gigant_jumperp"] = { "gigant_jumper" },
|
||
|
["snork_no_maskp"] = { "snork_normal_no_mask", "snork_strong_no_mask", "snork_weak_no_mask" },
|
||
|
["zombie_babkap"] = { "zombi_babka_1", "zombi_babka_2", "zombi_babka_3" },
|
||
|
["zombie_gholp"] = { "zombie_ghol" },
|
||
|
["zombie_ghostp"] = { "zombie_ghost" },
|
||
|
["zombie_tetap"] = { "zombie_teta" },
|
||
|
["zombie_wichp"] = { "zombie_wich" },
|
||
|
}
|
||
|
|
||
|
local mutant_spawn_squads = {}
|
||
|
|
||
|
|
||
|
local function please_die_sid()
|
||
|
local ids = {"red_forester_tech", "esc_m_trader"}
|
||
|
for i, n in ipairs(ids) do
|
||
|
smr_debug.get_log().info("population", "removing story object %s", n)
|
||
|
local so = get_story_object_id(n)
|
||
|
if so then alife_release_id(so) end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function get_mutant_spawn_squads()
|
||
|
if next(mutant_spawn_squads) == nil then
|
||
|
local ini = ini_file("plugins\\zcp\\squads_by_type.ltx")
|
||
|
for m, c in pairs(mutant_spawn_cfg) do
|
||
|
if (smr_mutants_mcm.get_config(c) == true) then
|
||
|
local squads = smr_utils.ini_lines_to_table(ini, c)
|
||
|
for i, v in ipairs(squads) do
|
||
|
table.insert(mutant_spawn_squads, v)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
return mutant_spawn_squads
|
||
|
end
|
||
|
|
||
|
function get_unused_mutant_spawn_table()
|
||
|
if next(unused_mutant_spawn_table) == nil then
|
||
|
for m, c in pairs(unused_mutant_spawn_cfg) do
|
||
|
if (smr_mutants_mcm.get_config(m) == true) then
|
||
|
local mn = str_explode(m, "_")
|
||
|
if not unused_mutant_spawn_table[mn[1]] then
|
||
|
unused_mutant_spawn_table[mn[1]] = {}
|
||
|
end
|
||
|
for i, v in ipairs(c) do
|
||
|
table.insert(unused_mutant_spawn_table[mn[1]], v)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
return unused_mutant_spawn_table
|
||
|
end
|
||
|
|
||
|
function get_zombie_spawn_table()
|
||
|
if next(zombie_spawn_table) == nil then
|
||
|
for k, n in pairs(zombie_spawn_cfg) do
|
||
|
if smr_zombies_mcm.get_config(k) then
|
||
|
for i, s in ipairs(n) do
|
||
|
table.insert(zombie_spawn_table, s)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
if next(zombie_spawn_table) == nil or smr_zombies_mcm.get_config("zombiesp") then
|
||
|
for i = 1, smr_zombies_mcm.get_config("zombies_amount") do
|
||
|
table.insert(zombie_spawn_table, "simulation_zombie")
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
return zombie_spawn_table
|
||
|
end
|
||
|
|
||
|
function get_faction_spawn_table()
|
||
|
if next(faction_spawn_table) == nil then
|
||
|
for k, n in ipairs(faction_spawn_cfg) do
|
||
|
if smr_stalkers_mcm.get_config(n) then
|
||
|
table.insert(faction_spawn_table, n)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
if next(faction_spawn_table) == nil then
|
||
|
table.insert(faction_spawn_table, "stalker")
|
||
|
end
|
||
|
return faction_spawn_table
|
||
|
end
|
||
|
|
||
|
function is_squad_faction_enabled(squad)
|
||
|
local t = get_faction_spawn_table()
|
||
|
local faction = ini_sys:r_string_ex(squad, "faction")
|
||
|
if faction == "dolg" then
|
||
|
faction = "duty"
|
||
|
end
|
||
|
if faction == "killer" then
|
||
|
faction = "merc"
|
||
|
end
|
||
|
for i, f in ipairs(t) do
|
||
|
if (faction == f) then
|
||
|
return true
|
||
|
end
|
||
|
end
|
||
|
return false
|
||
|
end
|
||
|
|
||
|
function get_mutant_spawn_table()
|
||
|
if next(mutant_spawn_table) == nil then
|
||
|
for m, c in pairs(mutant_spawn_cfg) do
|
||
|
if (smr_mutants_mcm.get_config(c) == true) then
|
||
|
table.insert(mutant_spawn_table, m)
|
||
|
end
|
||
|
end
|
||
|
if next(mutant_spawn_table) == nil then
|
||
|
table.insert(mutant_spawn_table, "chimera_")
|
||
|
end
|
||
|
end
|
||
|
return mutant_spawn_table
|
||
|
end
|
||
|
|
||
|
function is_mutant_type_enabled(section)
|
||
|
local t = get_mutant_spawn_table()
|
||
|
for i, m in pairs(t) do
|
||
|
if (string.sub(section, 1, string.len(m)) == m) then
|
||
|
return true
|
||
|
end
|
||
|
end
|
||
|
return false
|
||
|
end
|
||
|
|
||
|
local function get_random_enabled_mutant_squad()
|
||
|
local t = get_mutant_spawn_squads()
|
||
|
return t[math.random(#t)]
|
||
|
end
|
||
|
|
||
|
local function get_common_squad_type(squad_name)
|
||
|
local ss = str_explode(squad_name, "_")
|
||
|
if ss[4] == "novice"
|
||
|
or ss[4] == "advanced"
|
||
|
or ss[4] == "veteran"
|
||
|
or ss[4] == "alpha"
|
||
|
or ss[4] == "trader"
|
||
|
or ss[4] == "medic"
|
||
|
or ss[4] == "barman"
|
||
|
or ss[4] == "mechanic"
|
||
|
then
|
||
|
return ss[4]
|
||
|
end
|
||
|
return false
|
||
|
end
|
||
|
|
||
|
local function release_npc_or_squad(npc, squad)
|
||
|
alife_release(npc)
|
||
|
if (squad:npc_count() <= 1) then
|
||
|
alife_release_id(squad.id)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function try_spawn_faction(orig_spawn, smart)
|
||
|
if (not orig_spawn) then
|
||
|
return false
|
||
|
end
|
||
|
-- setup comparable squad of random enabled faction
|
||
|
local t = get_faction_spawn_table()
|
||
|
local st = { "novice", "veteran", "advanced" }
|
||
|
local squad_type = get_common_squad_type(orig_spawn) or st[math.random(#st)]
|
||
|
local tt = t[math.random(#t)] .. "_sim_squad_" .. squad_type
|
||
|
for n, r in pairs(retarded_squad_names) do
|
||
|
if tt == n then
|
||
|
tt = r
|
||
|
end
|
||
|
end
|
||
|
-- random stalkers
|
||
|
if smr_stalkers_mcm.get_config("random_stalkers")
|
||
|
and (math.random(1,100) <= smr_stalkers_mcm.get_config("random_stalkers_chance"))
|
||
|
-- only replace common squads with random stalkers
|
||
|
and (ini_sys:r_bool_ex(orig_spawn, "common"))
|
||
|
-- check if smart is base
|
||
|
and (not smr_civil_war.smart_is_base(smart:name()))
|
||
|
then
|
||
|
smr_debug.get_log().info("population/stalkers", "replaced squad %s with random stalkers %s (smart: %s)", orig_spawn, tt, smart:name())
|
||
|
return tt
|
||
|
end
|
||
|
-- check if faction is enabled
|
||
|
if is_squad_faction_enabled(orig_spawn) then
|
||
|
smr_debug.get_log().info("population/stalkers", "faction enabled - returning %s", orig_spawn)
|
||
|
return orig_spawn
|
||
|
end
|
||
|
-- replace if option enabled
|
||
|
if not smr_stalkers_mcm.get_config("factions_replace_squads") then
|
||
|
smr_debug.get_log().info("population/stalkers", "faction %s not enabled - not spawning squad %s", ini_sys:r_string_ex(orig_spawn,"faction"), orig_spawn)
|
||
|
return false
|
||
|
end
|
||
|
smr_debug.get_log().info("population/stalkers", "faction %s not enabled: replaced squad %s with random stalkers %s", ini_sys:r_string_ex(orig_spawn,"faction"), orig_spawn, tt)
|
||
|
return tt
|
||
|
end
|
||
|
|
||
|
local function add_random_npc_to_squad(squad, smart)
|
||
|
local npcs = ini_sys:r_string_ex(squad:section_name(),"npc_random")
|
||
|
if (not npcs) then
|
||
|
-- npcs = ini_sys:r_string_ex(squad:section_name(),"npc")
|
||
|
return
|
||
|
end
|
||
|
local t = parse_names(npcs)
|
||
|
local section = t[math.random(#t)]
|
||
|
local faction = ini_sys:r_string_ex(squad:section_name(), "faction")
|
||
|
if is_squad_monster[faction] and (not is_mutant_type_enabled(section)) then
|
||
|
smr_debug.get_log().warn("population/monsters", "could not add %s to squad %s (type disabled)", section, squad:section_name(), faction)
|
||
|
return nil
|
||
|
end
|
||
|
local npc = alife_create(section, smart)
|
||
|
if not npc then
|
||
|
smr_debug.get_log().error("population/monsters", "error while adding %s to squad %s", section, squad:section_name())
|
||
|
return nil
|
||
|
end
|
||
|
squad:register_member(npc.id)
|
||
|
smr_debug.get_log().info("population/monsters", "added %s to squad %s", section, squad:section_name())
|
||
|
return npc
|
||
|
end
|
||
|
|
||
|
-- ---
|
||
|
-- ENTRY POINTS
|
||
|
-- ---
|
||
|
|
||
|
-- smart_terrain.se_smart_terrain:try_respawn()
|
||
|
-- simulation_board:fill_start_position()
|
||
|
function smr_handle_spawn(orig_spawn, smart)
|
||
|
-- player wished for control
|
||
|
if has_alife_info("actor_made_wish_for_control") then
|
||
|
return SIMBOARD:create_squad(smart, "simulation_controller_psy")
|
||
|
end
|
||
|
-- ZCP not enabled
|
||
|
if not smr_amain_mcm.get_config("smr_enabled") then
|
||
|
smr_debug.get_log().info("population", "not replacing spawn -- ZCP disabled")
|
||
|
return SIMBOARD:create_squad(smart, orig_spawn)
|
||
|
end
|
||
|
-- zombies
|
||
|
local rnd = math.random(1,100)
|
||
|
if smr_zombies_mcm.get_config("zombie_spawn")
|
||
|
and rnd <= smr_zombies_mcm.get_config("zombie_chance")
|
||
|
-- only replace common squads
|
||
|
and ini_sys:r_bool_ex(orig_spawn,"common")
|
||
|
-- skip bases
|
||
|
and (not smr_civil_war.smart_is_base(smart))
|
||
|
then
|
||
|
local t = get_zombie_spawn_table()
|
||
|
local tt = t[math.random(#t)]
|
||
|
smr_debug.get_log().info("population/zombies", "replaced squad %s with zombie variant %s (%s <= %s)", orig_spawn, tt, rnd, smr_zombies_mcm.get_config("zombie_chance"))
|
||
|
return SIMBOARD:create_squad(smart, tt)
|
||
|
end
|
||
|
local faction = ini_sys:r_string_ex(orig_spawn, "faction")
|
||
|
-- mutant squads
|
||
|
if is_squad_monster[faction] then
|
||
|
if (string.sub(orig_spawn, 1, string.len("simulation_")) == "simulation_")
|
||
|
and smr_mutants_mcm.get_config("random_mutants")
|
||
|
and (math.random(1,100) <= smr_mutants_mcm.get_config("random_mutants_chance"))
|
||
|
then
|
||
|
local m
|
||
|
if smr_spawns_mcm.get_config("preset_apply_random") then
|
||
|
m = smr_spawn_template.get_random_squad_for_smart(smart) or get_random_enabled_mutant_squad()
|
||
|
smr_debug.get_log().info("population/monsters", "replaced squad %s with random mutant %s (template)", orig_spawn, m)
|
||
|
else
|
||
|
m = get_random_enabled_mutant_squad()
|
||
|
smr_debug.get_log().info("population/monsters", "replaced squad %s with random mutant %s", orig_spawn, m)
|
||
|
end
|
||
|
return SIMBOARD:create_squad(smart, m)
|
||
|
end
|
||
|
-- stalker squads
|
||
|
else
|
||
|
local maybe_squad_section = try_spawn_faction(orig_spawn, smart)
|
||
|
if maybe_squad_section then
|
||
|
return SIMBOARD:create_squad(smart, maybe_squad_section)
|
||
|
end
|
||
|
return nil
|
||
|
end
|
||
|
-- return original spawn
|
||
|
return SIMBOARD:create_squad(smart, orig_spawn)
|
||
|
end
|
||
|
|
||
|
-- smart_terrain.se_smart_terrain:try_respawn()
|
||
|
function smart_can_respawn(smart)
|
||
|
local name = smart:name()
|
||
|
local last_respawn_update = smart.last_respawn_update
|
||
|
-- default value
|
||
|
if (not smr_amain_mcm.get_config("smr_enabled")) and (smr_amain_mcm.get_config("respawn_idle") ~= 86400) then
|
||
|
smr_debug.get_log().info("population/smart", "default respawn check value: ZCP disabled or respawn_idle set to 86400 (testing for smart %s)", name)
|
||
|
return last_respawn_update == nil or curr_time:diffSec(last_respawn_update) > smart.respawn_idle
|
||
|
end
|
||
|
-- last update was nil
|
||
|
local cfg = smr_amain_mcm.get_config("respawn_idle")
|
||
|
if last_respawn_update == nil then
|
||
|
smr_debug.get_log().info("population/smart", "respawn check sucessful for smart %s (last update was nil)", name)
|
||
|
return true
|
||
|
end
|
||
|
-- respawns disabled
|
||
|
if cfg == -1 then
|
||
|
smr_debug.get_log().info("population/smart", "respawn check failed: respawns disabled (testing for smart %s)", name)
|
||
|
return false
|
||
|
end
|
||
|
-- use ZCP config value
|
||
|
local diff = game.get_game_time():diffSec(last_respawn_update)
|
||
|
if diff > cfg then
|
||
|
return true
|
||
|
else
|
||
|
return false
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- smart_terrain.se_smart_terrain:try_respawn()
|
||
|
-- simulation_board:fill_start_position()
|
||
|
function get_stalker_pop_factor()
|
||
|
if smr_amain_mcm.get_config("smr_enabled") then
|
||
|
--smr_debug.get_log().info("population/stalkers", "overriding population factor")
|
||
|
return smr_amain_mcm.get_config("stalker_pop_factor")
|
||
|
end
|
||
|
--smr_debug.get_log().info("population/stalkers", "ZCP disabled: using default population factor")
|
||
|
return ui_options.get("alife/general/alife_stalker_pop")
|
||
|
end
|
||
|
|
||
|
-- smart_terrain.se_smart_terrain:try_respawn()
|
||
|
-- simulation_board:fill_start_position()
|
||
|
function get_monster_pop_factor()
|
||
|
if smr_amain_mcm.get_config("smr_enabled") then
|
||
|
--smr_debug.get_log().info("population/monsters", "overriding population factor")
|
||
|
return smr_amain_mcm.get_config("monster_pop_factor")
|
||
|
end
|
||
|
--smr_debug.get_log().info("population/monsters", "ZCP disabled: using default population factor")
|
||
|
return ui_options.get("alife/general/alife_mutant_pop")
|
||
|
end
|
||
|
|
||
|
-- simulation_board:fill_start_position()
|
||
|
function get_population_preset()
|
||
|
if smr_amain_mcm.get_config("smr_enabled") and (smr_stalkers_mcm.get_config("base_population") ~= "sim_smr_default") then
|
||
|
smr_debug.get_log().info("population", "using population preset %s", "misc\\"..smr_stalkers_mcm.get_config("base_population")..".ltx")
|
||
|
return ini_file("misc\\"..smr_stalkers_mcm.get_config("base_population")..".ltx")
|
||
|
else
|
||
|
smr_debug.get_log().info("population", "using default population preset")
|
||
|
return ini_file("misc\\simulation.ltx")
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function actor_on_first_update()
|
||
|
if smr_amain_mcm.get_config("smr_enabled") and (smr_stalkers_mcm.get_config("base_population") == "sim_smr_none") then
|
||
|
smr_debug.get_log().info("population", "removing story objects")
|
||
|
please_die_sid()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
function on_game_start()
|
||
|
RegisterScriptCallback("actor_on_first_update", actor_on_first_update)
|
||
|
end
|