364 lines
11 KiB
Plaintext
364 lines
11 KiB
Plaintext
local ini_rel = ini_file("creatures\\game_relations.ltx")
|
|
|
|
function get_new_period()
|
|
local hrs = level.get_time_hours()
|
|
for i, t in ipairs(xcvb_arena_main.arena_main_t) do
|
|
if hrs >= t.min and hrs < t.max then
|
|
return i
|
|
end
|
|
end
|
|
end
|
|
|
|
function spawn_board()
|
|
local pos = vector():set(149.2, 1.40, 70.81)
|
|
local se_obj = alife_create("xcvb_arena_board", pos, 2^32-1, 1684)
|
|
if not se_obj then return end
|
|
|
|
local data = utils_stpk.get_physic_data(se_obj)
|
|
data.custom_data = [[
|
|
[collide]
|
|
ignore_static
|
|
ignore_small_objects
|
|
|
|
[logic]
|
|
cfg = scripts\arena_board_logic.ltx
|
|
]]
|
|
utils_stpk.set_physic_data(data, se_obj)
|
|
|
|
se_obj.angle = vector():set(0, -2.06, 0)
|
|
end
|
|
|
|
function spawn_balcony()
|
|
local pos = vector():set(140.1, -13.51, 102.2)
|
|
local se_obj = alife_create("xcvb_arena_balcony", pos, 2^32-1, 1710)
|
|
if not se_obj then return end
|
|
|
|
local data = utils_stpk.get_physic_data(se_obj)
|
|
data.custom_data = [[
|
|
[collide]
|
|
ignore_static
|
|
ignore_small_objects
|
|
]]
|
|
utils_stpk.set_physic_data(data, se_obj)
|
|
|
|
se_obj.angle = vector():set(0, -1.5708, 0)
|
|
end
|
|
|
|
function handle_removed_teams()
|
|
for i, t in ipairs(xcvb_arena_main.arena_main_t) do
|
|
if #t.team1 > 0 then
|
|
remove_teams = false
|
|
for j, sec in ipairs(t.team1) do
|
|
if string.find(sec, "zombied") then
|
|
remove_teams = true
|
|
break
|
|
end
|
|
end
|
|
for j, sec in ipairs(t.team2) do
|
|
if string.find(sec, "zombied") then
|
|
remove_teams = true
|
|
break
|
|
end
|
|
end
|
|
if remove_teams then
|
|
iempty_table(xcvb_arena_main.arena_main_t[i].team1)
|
|
iempty_table(xcvb_arena_main.arena_main_t[i].team2)
|
|
iempty_table(xcvb_arena_main.arena_main_t[i].pwrs)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local stalkers_t = {
|
|
stalker = { 0, 1, 2, 3, 4 }, bandit = { 0, 1, 2, 3, 4 }, killer = { 0, 1, 2, 3, 4 },
|
|
duty = { 0, 1, 2, 3, 4 }, freedom = { 0, 1, 2, 3, 4 }, army = { 0, 1, 2, 3, 4 },
|
|
ecolog = { 0, 1, 2, 3, 4 }, csky = { 0, 1, 2, 3, 4 }, monolith = { 0, 1, 2, 3, 4 },
|
|
greh = { 0, 1, 2, 3, 4 }, renegade = { 0, 1, 2 }, -- zombied = { 1, 2, 3, 4 }
|
|
}
|
|
|
|
local stalkers_power_t = {
|
|
-- stalkers by rank
|
|
[0] = 1, [1] = 3, [2] = 5, [3] = 8, [4] = 10,
|
|
}
|
|
|
|
function get_stalker_team(amount)
|
|
local ret_ar = {}
|
|
local pwr = 0
|
|
-- pick random comm and fill from it
|
|
local k = random_key_table(stalkers_t)
|
|
for i = 1, amount do
|
|
local rnd_idx = math.random(1, #stalkers_t[k])
|
|
local rank_val = stalkers_t[k][rnd_idx]
|
|
local new_k = k == "army" and "military" or k
|
|
local sec = "sim_default_" .. new_k .. "_" .. rank_val
|
|
ret_ar[#ret_ar + 1] = sec
|
|
pwr = pwr + stalkers_power_t[rank_val]
|
|
end
|
|
return ret_ar, pwr
|
|
end
|
|
|
|
local mutants_t = {
|
|
zombie = {"_weak", "_normal", "_strong", "_blind"},
|
|
boar = {"_normal", "_strong", "_01a_weak", "_02a_weak", "_02a_strong", "_01a_hard", "_02a_hard"},
|
|
dog = {"_normal_red", "_normal_white", "_normal_brown", "_normal_bulterier", "_weak_red", "_weak_white",
|
|
"_weak_brown", "_weak_bulterier", "_strong_red", "_strong_white", "_strong_brown", "_strong_bulterier", "_strong_black"},
|
|
pseudodog = {"_grey_weak", "_normal", "_strong", "_grey_strong"},
|
|
cat = {"_weak_a", "_weak_b", "_weak_c", "_weak_d", "_weak_e", "_normal_a", "_normal_b", "_normal_c", "_normal_d", "_normal_e",
|
|
"_strong_a", "_strong_b", "_strong_c", "_strong_d", "_strong_e"},
|
|
fracture = {"_weak", "_normal", "_strong", "_2", "_3"},
|
|
snork = {"_weak", "_weak2", "_weak3", "_weak4", "_normal", "_normal2", "_normal3", "_normal4", "_strong", "_strong2", "_strong3", "_strong4"},
|
|
lurker = {"_1_weak", "_2_weak", "_3_weak", "_1_normal", "_2_normal", "_3_normal", "_1_strong", "_2_strong", "_3_strong" },
|
|
bloodsucker = {"_red_weak", "_green_weak", "_black_weak", "_red_normal", "_green_normal", "_black_normal",
|
|
"_red_strong", "_green_strong", "_black_strong"},
|
|
psysucker = {"_2_weak", "_3_weak", "_2_normal", "_3_normal", "_2_strong", "_3_strong"},
|
|
psy_dog = {"_normal"},
|
|
chimera = {"_weak", "_normal", "_strong", "_strong2", "_strong3", "_strong4"},
|
|
}
|
|
|
|
local mutants_power_t = {
|
|
zombie = 1, boar = 3, dog = 2, pseudodog = 4, cat = 4, fracture = 5,
|
|
snork = 5, lurker = 5, bloodsucker = 8, psysucker = 8, psy_dog = 8, chimera = 12
|
|
}
|
|
|
|
local mutant_relation_order = {
|
|
"actor","human","zoo_monstr","boar","bloodsucker","flesh","dog","pseudodog","cat","chimera","giant","zombie","burer","controller","poltergeist","snork","fracture","bird","rat","tushkano","corpse","trader","arena_monstr","komar","tark","medwed","rotan","fly","mwolf","psysucker","lurker","karlik"
|
|
}
|
|
|
|
local mutant_relations_t = {}
|
|
|
|
function get_mutant_team(amount, team1_mutant_type)
|
|
local ret_ar = {}
|
|
local pwr = 0
|
|
local k
|
|
|
|
-- make relations table if not created
|
|
if is_empty(mutant_relations_t) then
|
|
fill_mutant_relations_table()
|
|
end
|
|
|
|
-- team1 is mutant - pick enemy mutant
|
|
if team1_mutant_type then
|
|
local team1_enemies_t = mutant_relations_t[team1_mutant_type]
|
|
local t_size = team1_enemies_t and size_table(team1_enemies_t) or 0
|
|
if t_size <= 0 then
|
|
return ret_ar, pwr, k
|
|
end
|
|
k = random_key_table(team1_enemies_t)
|
|
-- team1 is stalker - pick any mutant
|
|
else
|
|
k = random_key_table(mutants_t)
|
|
end
|
|
|
|
for i = 1, amount do
|
|
local rnd_idx = math.random(1, #mutants_t[k])
|
|
local sec = k .. mutants_t[k][rnd_idx]
|
|
ret_ar[#ret_ar + 1] = sec
|
|
pwr = pwr + mutants_power_t[k]
|
|
end
|
|
return ret_ar, pwr, k
|
|
end
|
|
|
|
function fill_mutant_relations_table()
|
|
-- collect and store mutants and their enemies
|
|
local n = ini_rel:line_count("monster_relations")
|
|
for i = 0, n - 1 do
|
|
local _, mutant, values = ini_rel:r_line_ex("monster_relations", i, "", "")
|
|
-- keep only possible fighters
|
|
if mutant and mutants_t[mutant] then
|
|
mutant_relations_t[mutant] = {}
|
|
-- fill it with enemies only
|
|
local rel_ar = str_explode(values, ",") -- {-1, 0, 1}
|
|
for idx, val in ipairs(rel_ar) do
|
|
local enemy_mutant = mutant_relation_order[idx]
|
|
if tonumber(val) < 0 and enemy_mutant and mutants_t[enemy_mutant] then
|
|
mutant_relations_t[mutant][enemy_mutant] = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
-- exclude mutants that are not enemies to each other
|
|
for mutant1, t1 in pairs(mutant_relations_t) do
|
|
for mutant2, t2 in pairs(mutant_relations_t) do
|
|
if mutant1 ~= mutant2 and t2[mutant1] and (not t1[mutant2]) then
|
|
mutant_relations_t[mutant2][mutant1] = nil
|
|
end
|
|
end
|
|
end
|
|
|
|
-- copy psy_dog from pseudodog
|
|
mutant_relations_t["psy_dog"] = {}
|
|
mutant_relations_t["psy_dog"] = dup_table(mutant_relations_t["pseudodog"])
|
|
end
|
|
|
|
function get_team_str(ar)
|
|
for _, sec in ipairs(ar) do
|
|
-- stalkers
|
|
for k, __ in pairs(stalkers_t) do
|
|
if string.find(sec, k) then
|
|
return k == "duty" and "dolg" or k
|
|
elseif string.find(sec, "military") then
|
|
return "army"
|
|
end
|
|
end
|
|
-- mutants
|
|
for k, __ in pairs(mutants_t) do
|
|
if string.find(sec, "^" .. k) then
|
|
if k == "dog" then
|
|
return "encyclopedia_mutants_blind_dog"
|
|
elseif k == "psy_dog" then
|
|
return "encyclopedia_mutants_psydog"
|
|
end
|
|
return "encyclopedia_mutants_" .. k
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function get_actor_arena_pos()
|
|
-- local pos = vector():set(139.1, -13.37, 101.5)
|
|
local pos = vector():set(141.6, -13.35, 102.1)
|
|
local lvid = 37386
|
|
local gvid = 1710
|
|
return pos, lvid, gvid
|
|
end
|
|
|
|
function get_team_pos(n)
|
|
if n == 1 then
|
|
local pos = vector():set(151.2, -20.0543, 128.8)
|
|
local lvid = 40551
|
|
local gvid = 1796
|
|
return pos, lvid, gvid
|
|
elseif n == 2 then
|
|
local pos = vector():set(152.6, -20.0598, 81.2)
|
|
local lvid = 40761
|
|
local gvid = 1684
|
|
return pos, lvid, gvid
|
|
end
|
|
end
|
|
|
|
function arena_fade_in_out(in_dly)
|
|
local fade_in_delay = in_dly or 0
|
|
local fade_out_delay = fade_in_delay + 2
|
|
|
|
CreateTimeEvent("xcvb_arena_fade_in_e", "xcvb_arena_fade_in_a", fade_in_delay, function()
|
|
level.add_pp_effector("fade_in.ppe", 987123)
|
|
return true
|
|
end)
|
|
CreateTimeEvent("xcvb_arena_fade_out_e", "xcvb_arena_fade_out_a", fade_out_delay, function()
|
|
level.add_pp_effector("fade_out.ppe", 987124)
|
|
return true
|
|
end)
|
|
end
|
|
|
|
function set_teams_relation(squad_id1, squad_id2)
|
|
-- for stalkers only
|
|
local squad1 = squad_id1 and alife_object(squad_id1)
|
|
local squad2 = squad_id2 and alife_object(squad_id2)
|
|
if not (squad1 and squad1.commander_id and squad2 and squad2.commander_id) then return end
|
|
if string.find(squad1:section_name(), "mutant") or string.find(squad2:section_name(), "mutant") then return end
|
|
|
|
for m1 in squad1:squad_members() do
|
|
local npc1 = level.object_by_id(m1.id)
|
|
for m2 in squad2:squad_members() do
|
|
local npc2 = level.object_by_id(m2.id)
|
|
if npc1 and npc1:alive() and npc2 and npc2:alive() then
|
|
npc1:force_set_goodwill(-9999, npc2)
|
|
npc2:force_set_goodwill(-9999, npc1)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function set_out_restrictors(squad_id1, squad_id2)
|
|
local squad1 = squad_id1 and alife_object(squad_id1)
|
|
local squad2 = squad_id2 and alife_object(squad_id2)
|
|
if not (squad1 and squad1.commander_id and squad2 and squad2.commander_id) then return end
|
|
|
|
for m1 in squad1:squad_members() do
|
|
local npc1 = level.object_by_id(m1.id)
|
|
if npc1 and npc1:alive() then
|
|
npc1:add_restrictions("bar_arena_restrictor", "")
|
|
end
|
|
end
|
|
|
|
for m2 in squad2:squad_members() do
|
|
local npc2 = level.object_by_id(m2.id)
|
|
if npc2 and npc2:alive() then
|
|
npc2:add_restrictions("bar_arena_restrictor", "")
|
|
end
|
|
end
|
|
end
|
|
|
|
function hit_npcs(squad_id1, squad_id2)
|
|
local squad1 = squad_id1 and alife_object(squad_id1)
|
|
local squad2 = squad_id2 and alife_object(squad_id2)
|
|
if not (squad1 and squad1.commander_id and squad2 and squad2.commander_id) then return end
|
|
|
|
for m1 in squad1:squad_members() do
|
|
local npc1 = level.object_by_id(m1.id)
|
|
for m2 in squad2:squad_members() do
|
|
local npc2 = level.object_by_id(m2.id)
|
|
if npc1 and npc1:alive() and npc2 and npc2:alive() then
|
|
xcvb_arena_utils.scr_hit(npc1, npc2)
|
|
xcvb_arena_utils.scr_hit(npc2, npc1)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function scr_hit(npc, who)
|
|
if not (npc and who) then return end
|
|
-- printf("%s [%s] hits %s [%s]", npc:section(), npc:id(), who:section(), who:id())
|
|
local h = hit()
|
|
h.type = hit.wound
|
|
h.power = 0
|
|
h.impulse = 0
|
|
h.direction = VEC_Z
|
|
h.draftsman = npc
|
|
who:hit(h)
|
|
end
|
|
|
|
|
|
-- override to fix
|
|
function sim_squad_scripted.sim_squad_scripted.get_script_target(self)
|
|
--utils_data.debug_write("sim_squad_scripted:get_script_target")
|
|
local new_target
|
|
if (self.scripted_target) then
|
|
new_target = self.scripted_target
|
|
elseif (axr_task_manager.hostages_by_id[self:commander_id()]) then
|
|
return axr_task_manager.hostages_by_id[self:commander_id()]
|
|
elseif (self.random_targets) then
|
|
if (self.current_action == 0 and self.assigned_target_id == nil) then
|
|
new_target = self.random_targets[math.random(#self.random_targets)]
|
|
else
|
|
return self.assigned_target_id
|
|
end
|
|
elseif (self.action_condlist) then
|
|
new_target = xr_logic.pick_section_from_condlist(db.actor, self, self.action_condlist)
|
|
end
|
|
|
|
-- prevent companions from moving to actor if they cannot teleport and actor is not on same level
|
|
if (axr_companions.companion_squads[self.id]) then
|
|
local se_obj = alife_object(self:commander_id())
|
|
if (self.online ~= true) and (se_obj and se_load_var(se_obj.id,se_obj:name(),"companion_cannot_teleport")) then
|
|
return self.id
|
|
end
|
|
return 0
|
|
end
|
|
|
|
if (new_target == "actor") then
|
|
return 0
|
|
end
|
|
|
|
local smart = new_target and SIMBOARD.smarts_by_names[new_target]
|
|
if (smart) then
|
|
return smart.id
|
|
end
|
|
|
|
local new_id = tonumber(new_target)
|
|
local se_target = new_id and alife_object(new_id)
|
|
if se_target and (se_target:clsid() == clsid.online_offline_group_s or se_target:clsid() == clsid.smart_terrain) then
|
|
return new_id
|
|
end
|
|
end |