--============================================================= -- -- axr_companions.script -- CoC 1.5b r4 - DoctorX Call of The Zone 1.0 -- -- Modified by: DoctorX -- Last revised: August 10, 2019 -- --============================================================= --[[ axr_companions by Alundaio -]] -- SEE configs\ai_tweaks\axr_companions allow_only_friends_as_companions = true allow_simulation_squads_as_companions = false max_actor_squad_size = 0 -- used only for non task companions -- Companion tables. All companions are added to companion_squads table by their squad id. Only non-task companions are tracked by non_task_companions table. companion_squads = {} non_task_companions = {} ------------------------------------------ local _current_move_mode = 1 local _current_combat_mode = 1 local _current_stealth_mode = true local _particle_valid = nil local _particle_invalid = nil local drx_cotz_config = ini_file( "drx\\drx_cotz_config.ltx" ) local enable_companion_health_regen = drx_cotz_config:r_bool_ex( "misc_settings", "enable_companion_health_regen") or false local companion_healing_rate = drx_cotz_config:r_float_ex( "misc_settings", "companion_healing_rate") or 0.1 ------------------------------------------ -- Localized Functions ------------------------------------------ local function on_fighting_actor(npc) if not (IsStalker(npc)) then return end --alun_utils.debug_write(strformat("axr_companions.on_fighting_actor")) for id,squad in pairs(companion_squads) do xr_combat_ignore.safe_zone_npcs[id] = nil if (squad and squad.commander_id) then for k in squad:squad_members() do local member = db.storage[k.id] and db.storage[k.id].object if (member and member:alive()) then member:set_relation(game_object.enemy,npc) npc:set_relation(game_object.enemy,member) end end end end end local function squad_on_npc_death(squad,se_npc) --alun_utils.debug_write(strformat("axr_companions.squad_on_npc_death")) non_task_companions[se_npc.id] = nil if (squad:npc_count() == 0) then companion_squads[squad.id] = nil end end local function squad_on_register(squad) if (companion_squads[squad.id] ~= nil) then companion_squads[squad.id] = squad squad:set_squad_relation("friend") squad.scripted_target = "actor" end -- backward save compatiblity. remove later for k in squad:squad_members() do if (k.id and k.object and utils.se_obj_load_var(k.id,k.object:name(),"companion")) then companion_squads[squad.id] = squad squad.scripted_target = "actor" break end end end local function squad_on_unregister(squad) companion_squads[squad.id] = nil end local function squad_on_update(squad) --alun_utils.debug_write(strformat("axr_companions.squad_on_update - heli_enemy_flag")) if (companion_squads[squad.id]) then squad.scripted_target = "actor" for k in squad:squad_members() do if (db.storage[k.id]) then db.storage[k.id].heli_enemy_flag = utils.load_var(db.actor,"heli_enemy_flag") end end end end local function on_level_changing() local sim = alife() local se_actor = sim:actor() local gg = game_graph() local gvid = se_actor.m_game_vertex_id local vert = gg:vertex(gvid) local lvid = vert:level_vertex_id() local pos = vert:level_point() for id,v in pairs(companion_squads) do local squad = sim:object(id) if (squad and squad.commander_id) then if (companion_squad_can_teleport(squad)) then TeleportSquad(squad,pos,lvid,gvid) end end end end local function actor_on_item_drop(item) if (ActorMenu.get_menu_mode() == 4) then local npc = ActorMenu.get_actor_menu():GetPartner() if (npc and npc:alive() and npc:has_info("npcx_is_companion")) then local m_data = alife_storage_manager.get_state() if not (m_data.companion_borrow_item) then m_data.companion_borrow_item = {} end m_data.companion_borrow_item[item:id()] = true end end end -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> -- CotZ for IWP: Companions regenerate health. (Code taken from -- Anomaly, lightly modified) -- -- Author(s) : Anomaly Dev Team, moonshroom -- Added : 20/01/2025 11:25 pm -- Ver. : Indev 6.6 -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> local function healing_timer() -- auto-healing every x seconds ResetTimeEvent("cycle","companion_healing",10) if ( enable_companion_health_regen == false ) then return false end for id,squad in pairs(companion_squads) do if (squad and squad.commander_id) then for k in squad:squad_members() do st = db.storage[k.id] local member = st and st.object if (member and member:alive() and not member:wounded()) then local health = member.health -- local old_health = member.health if (health < 1) then health = clamp(health + companion_healing_rate, 0, 1) member:set_health_ex( health ) -- printf("Healed companion | before: %s, after: %s", old_health, health) end end end end end return false end -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> local function save_state(m_data) m_data.non_task_companions = non_task_companions m_data.companion_squads = {} for id,squad in pairs(companion_squads) do if (squad and squad.commander_id) then m_data.companion_squads[id] = false end end end local function load_state(m_data) non_task_companions = m_data.non_task_companions or non_task_companions m_data.non_task_companions = nil if (m_data.companion_squads) then companion_squads = m_data.companion_squads or companion_squads for id,bool in pairs(m_data.companion_squads) do companion_squads[id] = false end end m_data.companion_squads = nil end -- backward save compatiblity, remove me later! local function on_game_load() -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> -- CotZ for IWP: Companions regenerate health. (Code taken from -- Anomaly, lightly modified) -- -- Author(s) : Anomaly Dev Team, moonshroom -- Added : 20/01/2025 11:25 pm -- Ver. : Indev 6.6 -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> CreateTimeEvent("cycle","companion_healing",10,healing_timer) -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> local c_idx = 1 local cid = alun_utils.load_var(db.actor,"companion_1") while (cid ~= nil) do local se_obj = alife_object(cid) if (se_obj) then non_task_companions[se_obj.id] = true local squad = se_obj.group_id and se_obj.group_id ~= 65535 and alife_object(se_obj.group_id) if (squad) then companion_squads[squad.id] = squad end end alun_utils.save_var(db.actor,"companion_"..c_idx,nil) c_idx = c_idx + 1 cid = alun_utils.load_var(db.actor,"companion_"..c_idx) end end --------------------------------- -- Register Callbacks --------------------------------- function on_game_start() local ini = ini_file("ai_tweaks\\axr_companions.ltx") Enabled = ini:r_bool_ex("main","enable",false) if not (Enabled) then return end RegisterScriptCallback("npc_on_fighting_actor",on_fighting_actor) RegisterScriptCallback("squad_on_update",squad_on_update) RegisterScriptCallback("squad_on_npc_death",squad_on_npc_death) RegisterScriptCallback("squad_on_register",squad_on_register) RegisterScriptCallback("squad_on_unregister",squad_on_unregister) RegisterScriptCallback("on_level_changing",on_level_changing) RegisterScriptCallback("actor_on_item_drop",actor_on_item_drop) RegisterScriptCallback("save_state",save_state) RegisterScriptCallback("load_state",load_state) RegisterScriptCallback("on_game_load",on_game_load) allow_only_friends_as_companions = ini:r_bool_ex("main","allow_only_friends_as_companions",false) allow_simulation_squads_as_companions = ini:r_bool_ex("main","allow_simulation_squads_as_companions",false) max_actor_squad_size = ini:r_float_ex("main","max_actor_squad_size") or 2 end function companion_squad_can_teleport(squad) local id = squad:commander_id() local sim = alife() local se_obj = sim:object(id) if (se_obj) then if (utils.se_obj_load_var(se_obj.id,se_obj:name(),"companion_cannot_teleport")) then return false end end if (id) and (sim:has_info(id,"npcx_beh_patrol_mode") or sim:has_info(id,"npcx_beh_wait")) then return false end return true end -- doesn't include task companions function get_companion_count() return table.size(non_task_companions) end -- includes task companions too function list_actor_squad_by_id() local t = {} local size_t = 0 for id,squad in spairs(companion_squads, function(t,a,b) return a < b end) do if (squad and squad.commander_id) then if not (xrs_kill_wounded.hostage_list[squad:commander_id()]) then for k in squad:squad_members() do --printf("member %s",k.id) size_t = size_t + 1 t[size_t] = k.id end end end end return t end function setup_companion_logic(npc,st,loaded,cannot_dismiss) npc:give_info_portion("npcx_is_companion") if (cannot_dismiss or utils.se_obj_load_var(npc:id(),npc:name(),"companion_cannot_dismiss")) then npc:give_info_portion("npcx_beh_cannot_dismiss") end local ltx_name = "scripts\\beh_companion.ltx" local ltx = ini_file(ltx_name) if not (ltx) then log("ERROR: do not have access to scripts\\beh_companion.ltx! Make sure you installed properly!") return end local id = npc:id() local sim = alife() local se_npc = sim:object(id) local unreg_id = se_npc and se_npc.m_smart_terrain_id if (unreg_id and unreg_id ~= 65535) then local unreg = sim:object(unreg_id) if (unreg) then unreg:unregister_npc(se_npc) end end xr_logic.configure_schemes(npc, ltx, ltx_name, modules.stype_stalker, loaded and st.loaded_section_logic or "logic", "") local section = loaded and st.loaded_active_section or xr_logic.determine_section_to_activate(npc, ltx, "logic", db.actor) xr_logic.activate_by_section(npc, ltx, section, "", loaded) --printf("setup complete") end function add_to_actor_squad(npc) local id = npc:id() non_task_companions[id] = true utils.se_obj_save_var(id,npc:name(),"companion",true) npc:inactualize_patrol_path() setup_companion_logic(npc,db.storage[id],false) end function remove_from_actor_squad(npc) local squad = get_object_squad(npc) if (squad) then squad.scripted_target = nil companion_squads[squad.id] = nil end -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> -- CotZ for IWP: Player-owned items are automatically -- given back to the player on dismissal -- of companionos. -- -- Author(s) : moonshroom -- Added : 24/12/2024 11:03 am -- Ver. : Indev 6.6 -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> local function return_player_items( npc, item ) if ( alife_storage_manager.get_state().companion_borrow_item and alife_storage_manager.get_state().companion_borrow_item[item:id()] ) then npc:transfer_item( item, db.actor ) news_manager.relocate_item( db.actor, "in", item:section() ) end end npc:iterate_inventory( return_player_items, npc ) -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> non_task_companions[npc:id()] = nil npc:disable_info_portion("npcx_is_companion") npc:disable_info_portion("npcx_beh_cannot_dismiss") axr_logic.restore_scheme_and_logic(npc) local se_obj = alife_object(npc:id()) if not (se_obj) then return end utils.se_obj_save_var(se_obj.id,se_obj:name(),"companion",nil) utils.se_obj_save_var(se_obj.id,se_obj:name(),"companion_cannot_dismiss",nil) utils.se_obj_save_var(se_obj.id,se_obj:name(),"companion_cannot_teleport",nil) end function remove_all_from_actor_squad() for id,squad in pairs(companion_squads) do if (squad) then for k in squad:squad_members() do local se_obj = k.object or alife():object(k.id) if (se_obj) then squad.scripted_target = nil utils.se_obj_save_var(se_obj.id,se_obj:name(),"companion",nil) utils.se_obj_save_var(se_obj.id,se_obj:name(),"companion_cannot_dismiss",nil) utils.se_obj_save_var(se_obj.id,se_obj:name(),"companion_cannot_teleport",nil) local member = db.storage[se_obj.id] and db.storage[se_obj.id].object or level.object_by_id(se_obj.id) if (member) then member:disable_info_portion("npcx_is_companion") member:disable_info_portion("npcx_beh_cannot_dismiss") axr_logic.restore_scheme_and_logic(member) end end end end companion_squads[id] = nil end for id,b in pairs(non_task_companions) do non_task_companions[id] = nil end end function set_companion_allow_teleport(npc) local se_obj = alife_object(npc:id()) if not (se_obj) then return end utils.se_obj_save_var(se_obj.id,se_obj:name(),"companion_cannot_teleport",nil) end function set_companion_disable_teleport(npc) local se_obj = alife_object(npc:id()) if not (se_obj) then return end utils.se_obj_save_var(se_obj.id,se_obj:name(),"companion_cannot_teleport",true) end function set_companion_to_wait_state(npc) npc:give_info_portion("npcx_beh_wait") utils.save_var(npc,"fight_from_point",npc:level_vertex_id()) end function set_companion_to_follow_state(npc) npc:disable_info_portion("npcx_beh_wait") npc:disable_info_portion("npcx_beh_hide_in_cover") npc:disable_info_portion("npcx_beh_patrol_mode") utils.save_var(npc,"fight_from_point",nil) end function set_companion_to_attack_state(npc) npc:disable_info_portion("npcx_beh_ignore_combat") npc:disable_info_portion("npcx_beh_ignore_actor_enemies") end function set_companion_to_ignore_combat_state(npc) npc:give_info_portion("npcx_beh_ignore_combat") npc:give_info_portion("npcx_beh_ignore_actor_enemies") end function set_companion_to_attack_only_actor_combat_enemy_state(npc) npc:give_info_portion("npcx_beh_ignore_combat") npc:disable_info_portion("npcx_beh_ignore_actor_enemies") end function set_companion_to_stealth_substate(npc) npc:give_info_portion("npcx_beh_substate_stealth") end function set_companion_to_default_substate(npc) npc:disable_info_portion("npcx_beh_substate_stealth") npc:disable_info_portion("npcx_beh_substate_relax") end function switch_companion_distance(npc) if ( npc:has_info("npcx_beh_distance_far") ) then npc:disable_info_portion("npcx_beh_distance_far") else npc:give_info_portion("npcx_beh_distance_far") end end function switch_companion_patrol_mode(npc) if ( npc:has_info("npcx_beh_patrol_mode") ) then npc:disable_info_portion("npcx_beh_patrol_mode") else npc:give_info_portion("npcx_beh_patrol_mode") end end function switch_companion_gather_items(npc) if ( npc:has_info("npcx_beh_gather_items") ) then SetHudMsg(game.translate_string("st_disable_looting"),8) npc:disable_info_portion("npcx_beh_gather_items") else SetHudMsg(game.translate_string("st_enable_looting"),8) npc:give_info_portion("npcx_beh_gather_items") end end function switch_companion_loot_corpses(npc) if ( npc:has_info("npcx_beh_loot_corpses") ) then npc:disable_info_portion("npcx_beh_loot_corpses") else npc:give_info_portion("npcx_beh_loot_corpses") end end function companion_remove_waypoints(npc) npc:disable_info_portion("npcx_beh_patrol_mode") local i = 1 local p = utils.se_obj_load_var(npc:id(),npc:name(),"pathpoint"..i)--utils.load_var(npc,"pathpoint"..tostring(i)) while p do utils.se_obj_save_var(npc:id(),npc:name(),"pathpoint"..i,nil)--utils.save_var(npc,"pathpoint"..tostring(i),nil) i = i + 1 p = utils.se_obj_load_var(npc:id(),npc:name(),"pathpoint"..i)--utils.load_var(npc,"pathpoint"..tostring(i)) end end function companion_add_waypoints(npc,pos) local i = 1 local p = utils.se_obj_load_var(npc:id(),npc:name(),"pathpoint"..i)--utils.load_var(npc,"pathpoint"..tostring(i)) while p do i = i + 1 p = utils.se_obj_load_var(npc:id(),npc:name(),"pathpoint"..i)--utils.load_var(npc,"pathpoint"..tostring(i)) end local pos = db.actor:position() local s = "5000,patrol | pos:"..pos.x..","..pos.y..","..pos.z utils.se_obj_save_var(npc:id(),npc:name(),"pathpoint"..i,s)--utils.save_var(npc,"pathpoint"..tostring(i),s) end function cycle_companions_combat_mode(force_mode) -- /////////////////////////////////////////////////////////////////////////////////////////////// -- -- Load Combat Mode -- -- Added by DoctorX -- for DoctorX Call of The Zone 1.0 -- July 26, 2018 -- -- ----------------------------------------------------------------------------------------------- _current_combat_mode = utils.load_var( db.actor, "drx_companion_combat_mode", 1 ) -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> -- CotZ for IWP: Restored "fire at will" state for companions -- when cycling through combat states. (Old -- Companion Keybinds Optional) -- -- Author(s) : moonshroom -- Added : 20/01/2025 11:11 pm -- Ver. : Indev 6.6 -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> local t = {"set_companion_to_attack_state","set_companion_to_ignore_combat_state","set_companion_to_attack_only_actor_combat_enemy_state"} -- local t = {"set_companion_to_attack_only_actor_combat_enemy_state", "set_companion_to_ignore_combat_state"} -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> if (_current_combat_mode+1 > #t) then _current_combat_mode = 1 else _current_combat_mode = _current_combat_mode + 1 end _current_combat_mode = force_mode or _current_combat_mode SetHudMsg(game.translate_string("st_"..t[_current_combat_mode]),8) local f = this[t[_current_combat_mode]] if (f) then for id,squad in pairs(companion_squads) do if (squad and squad.commander_id) then if not (xrs_kill_wounded.hostage_list[squad:commander_id()]) then for k in squad:squad_members() do local member = db.storage[k.id] and db.storage[k.id].object if (member and member:alive()) then f(member) end end end end end end -- /////////////////////////////////////////////////////////////////////////////////////////////// -- -- Save Combat Mode -- -- Added by DoctorX -- for DoctorX Call of The Zone 1.0 -- July 26, 2018 -- -- ----------------------------------------------------------------------------------------------- utils.save_var( db.actor, "drx_companion_combat_mode", _current_combat_mode ) -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ end function cycle_companions_move_mode(force_mode) -- /////////////////////////////////////////////////////////////////////////////////////////////// -- -- Load Move Mode -- -- Added by DoctorX -- for DoctorX Call of The Zone 1.0 -- July 26, 2018 -- -- ----------------------------------------------------------------------------------------------- _current_move_mode = utils.load_var( db.actor, "drx_companion_move_mode", 1 ) -- local t = {"set_companion_to_wait_state", "set_companion_to_follow_state"} local t = {"set_companion_to_follow_state", "set_companion_to_wait_state"} -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ if (_current_move_mode+1 > #t) then _current_move_mode = 1 else _current_move_mode = _current_move_mode + 1 end _current_move_mode = force_mode or _current_move_mode SetHudMsg(game.translate_string("st_"..t[_current_move_mode]),8) local f = this[t[_current_move_mode]] if (f) then for id,squad in pairs(companion_squads) do if (squad and squad.commander_id) then if not (xrs_kill_wounded.hostage_list[squad:commander_id()]) then for k in squad:squad_members() do st = db.storage[k.id] if (k.id == squad:commander_id()) then if (st and st.beh) then st.beh.rally_lvid = nil end end local member = st and st.object if (member and member:alive()) then f(member) end end end end end end -- /////////////////////////////////////////////////////////////////////////////////////////////// -- -- Save Move Mode -- -- Added by DoctorX -- for DoctorX Call of The Zone 1.0 -- July 26, 2018 -- -- ----------------------------------------------------------------------------------------------- utils.save_var( db.actor, "drx_companion_move_mode", _current_move_mode ) -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ end function cycle_companions_stealth_mode() -- /////////////////////////////////////////////////////////////////////////////////////////////// -- -- Load Stealth Mode -- -- Added by DoctorX -- for DoctorX Call of The Zone 1.0 -- July 26, 2018 -- -- ----------------------------------------------------------------------------------------------- _current_stealth_mode = utils.load_var( db.actor, "drx_companion_stealth_mode" ) if ( _current_stealth_mode == nil ) then _current_stealth_mode = false end _current_stealth_mode = (not _current_stealth_mode) -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ for id,squad in pairs(axr_companions.companion_squads) do if (squad and squad.commander_id) then for k in squad:squad_members() do if not (xrs_kill_wounded.hostage_list[k.id]) then st = db.storage[k.id] local member = st and st.object if (member and member:alive()) then if (_current_stealth_mode) then member:give_info_portion("npcx_beh_substate_stealth") SetHudMsg(game.translate_string("st_companion_state_stealth_disabled"),8) else member:disable_info_portion("npcx_beh_substate_stealth") SetHudMsg(game.translate_string("st_companion_state_stealth_enabled"),8) end end end end end end -- /////////////////////////////////////////////////////////////////////////////////////////////// -- -- Save Stealth Mode -- -- Added by DoctorX -- for DoctorX Call of The Zone 1.0 -- July 26, 2018 -- -- ----------------------------------------------------------------------------------------------- -- _current_stealth_mode = not _current_stealth_mode utils.save_var( db.actor, "drx_companion_stealth_mode", _current_stealth_mode ) -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ end function get_test_member() for _,squad in pairs(companion_squads) do if (squad.online) then local id = squad:commander_id() local npc = db.storage[id] and db.storage[id].object if (npc) then return npc end end end end function move_to_point(p) -- /////////////////////////////////////////////////////////////////////////////////////////////// -- -- Reset to follow mode -- -- Added by DoctorX -- for DoctorX Call of The Zone 1.0 -- August 10, 2019 -- -- ----------------------------------------------------------------------------------------------- -- Reset all companions to follow mode: for id,squad in pairs(companion_squads) do if (squad and squad.commander_id) then if not (xrs_kill_wounded.hostage_list[squad:commander_id()]) then for k in squad:squad_members() do st = db.storage[k.id] local member = st and st.object if (member and member:alive()) then set_companion_to_follow_state(member) _current_move_mode = 1 end end end end end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ if (p==1) then SetHudMsg(game.translate_string("st_hold_then_release"),8) _particle_valid = particles_object("_samples_particles_\\flash_light") _particle_invalid = particles_object("_samples_particles_\\flash_light_red") elseif (p==2) then if (_particle_valid) then local r = level.get_target_dist and level.get_target_dist() if (r) then local pos = vector():set(device().cam_pos) pos:add(device().cam_dir:mul(r)) local lvid = level.vertex_id(pos) local npc = lvid and lvid < 4294967295 and get_test_member() if (npc and npc:accessible(pos)) then if (_particle_invalid:playing()) then _particle_invalid:stop() end _particle_valid:play_at_pos(vector():set(pos.x,pos.y-0.5,pos.z)) else if (_particle_valid:playing()) then _particle_valid:stop() end _particle_invalid:play_at_pos(vector():set(pos.x,pos.y-0.5,pos.z)) end end end else if (_particle_valid:playing()) then _particle_valid:stop() end _particle_valid = nil if (_particle_invalid:playing()) then _particle_invalid:stop() end _particle_invalid = nil local r = level.get_target_dist and level.get_target_dist() if (r) then local pos = vector():set(device().cam_pos) pos:add(device().cam_dir:mul(r)) local lvid = level.vertex_id(pos) -- ///////////////////////////////////////////////////////////////////////////////////////////// -- -- Delay setting move mode until valid lvid found -- -- Modified by DoctorX -- for DoctorX Call of The Zone 1.0 -- August 10, 2019 -- -- --------------------------------------------------------------------------------------------- -- _current_move_mode = 1 -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ SetHudMsg(game.translate_string("st_move_to_point"),8) for id,squad in pairs(companion_squads) do if (squad and squad.commander_id) then if not (xrs_kill_wounded.hostage_list[squad:commander_id()]) then for k in squad:squad_members() do st = db.storage[k.id] local member = st and st.object if (member and member:alive()) then set_companion_to_follow_state(member) if (lvid and lvid >= 4294967295) then lvid = nil end utils.save_var(member,"fight_from_point",lvid) end if (k.id == squad:commander_id()) then if (st and st.beh) then if (lvid) then if (lvid >= 4294967295) then lvid = nil end if not (member:accessible(lvid)) then lvid = member:accessible_nearest(level.vertex_position(lvid),vector()) end -- ////////////////////////////////////////////////////////////////////////////////////// -- -- Set Current Move Mode -- -- Added by DoctorX -- for DoctorX Call of The Zone 1.0 -- August 10, 2019 -- -- -------------------------------------------------------------------------------------- -- Set current move mode: if ( lvid ) then _current_move_mode = 0 end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ end st.beh.rally_lvid = lvid end end end end end end end end -- /////////////////////////////////////////////////////////////////////////////////////////////// -- -- Save Move Mode -- -- Added by DoctorX -- for DoctorX Call of The Zone 1.0 -- August 10, 2019 -- -- ----------------------------------------------------------------------------------------------- utils.save_var( db.actor, "drx_companion_move_mode", _current_move_mode ) -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ end function set_companion_squad_move_mode(mode,npc,squad) local t = {"set_companion_to_wait_state","set_companion_to_follow_state"} local f = this[t[mode]] if (f) then squad = squad or get_object_squad(npc) if (squad and squad.commander_id) then if not (xrs_kill_wounded.hostage_list[squad:commander_id()]) then for k in squad:squad_members() do st = db.storage[k.id] if (k.id == squad:commander_id()) then if (st and st.beh) then st.beh.rally_lvid = nil end end local member = st and st.object if (member and member:alive()) then f(member) end end end end end end function set_companion_squad_combat_mode(mode,npc,squad) local t = {"set_companion_to_attack_state","set_companion_to_ignore_combat_state","set_companion_to_attack_only_actor_combat_enemy_state"} local f = this[t[mode]] if (f) then squad = squad or get_object_squad(npc) if (squad and squad.commander_id) then if not (xrs_kill_wounded.hostage_list[squad:commander_id()]) then for k in squad:squad_members() do local member = db.storage[k.id] and db.storage[k.id].object if (member and member:alive()) then f(member) end end end end end end function set_companion_squad_stealth_mode(mode,npc,squad) squad = squad or get_object_squad(npc) if (squad and squad.commander_id) then if not (xrs_kill_wounded.hostage_list[squad:commander_id()]) then for k in squad:squad_members() do local member = db.storage[k.id] and db.storage[k.id].object if (member and member:alive()) then if (mode == 1) then member:give_info_portion("npcx_beh_substate_stealth") else member:disable_info_portion("npcx_beh_substate_stealth") end end end end end end function set_companion_squad_distance_mode(mode,npc,squad) squad = squad or get_object_squad(npc) if (squad and squad.commander_id) then if not (xrs_kill_wounded.hostage_list[squad:commander_id()]) then for k in squad:squad_members() do local member = db.storage[k.id] and db.storage[k.id].object if (member and member:alive()) then if (mode == 1) then member:give_info_portion("npcx_beh_distance_far") else member:disable_info_portion("npcx_beh_distance_far") end end end end end end function set_companion_squad_gather_mode(mode,npc,squad) squad = squad or get_object_squad(npc) if (squad and squad.commander_id) then if not (xrs_kill_wounded.hostage_list[squad:commander_id()]) then for k in squad:squad_members() do local member = db.storage[k.id] and db.storage[k.id].object if (member and member:alive()) then if (mode == 1) then member:give_info_portion("npcx_beh_gather_items") else member:disable_info_portion("npcx_beh_gather_items") end end end end end end function set_companion_squad_loot_mode(mode,npc,squad) squad = squad or get_object_squad(npc) if (squad and squad.commander_id) then if not (xrs_kill_wounded.hostage_list[squad:commander_id()]) then for k in squad:squad_members() do local member = db.storage[k.id] and db.storage[k.id].object if (member and member:alive()) then if (mode == 1) then member:give_info_portion("npcx_beh_loot_corpses") else member:disable_info_portion("npcx_beh_loot_corpses") end end end end end end