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