-- ============================================================ -- -- Main Functions for Tasks (xr_effects.script) -- DoctorX Call of The Zone 1.2 -- -- Modified by: DoctorX -- Last revised: January 11, 2021 -- -- ============================================================ -- ---------------------------------------------------------------------------------------------------- -- Îáùèå ôóíêöèè -- ---------------------------------------------------------------------------------------------------- -- TODO: Remove all unused COP story functions local DIALOG_LAST_ID = nil --------------------------------------------------------------------------------------------------------------- -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- Settings File -- -- Created by DoctorX -- for DoctorX Questlines 2.0 -- April 09, 2019 -- -- ------------------------------------------------------------------------------------------------ -- Location of the settings file: local drx_ql_ini = ini_file( "drx\\drx_ql_config.ltx" ) -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- Global Arrays -- -- Created by DoctorX -- for DoctorX Questlines 2.0 -- July 23, 2018 -- -- ------------------------------------------------------------------------------------------------ -- Storage for hidden target ids: drx_ql_hidden_targets = {} -- Storage for undiscovered float fetch tasks: drx_ql_float_fetch_tasks = {} -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_xre_save_state_callback function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Scripts to run when a game is saved -- -- Usage: -- (called on game save) -- -- Parameters: -- none -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified July 23, 2018 -- ------------------------------------------------------------------------------------------------ -- Scripts to run when the game is saved: local function drx_ql_xre_save_state_callback( m_data ) -- Save hidden targets list: m_data.drx_ql_hidden_targets = drx_ql_hidden_targets -- Save undiscovered float fetch tasks: m_data.drx_ql_float_fetch_tasks = drx_ql_float_fetch_tasks end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_xre_load_state_callback function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Scripts to run when a game is loaded -- -- Usage: -- (called on game load) -- -- Parameters: -- none -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified July 23, 2018 -- ------------------------------------------------------------------------------------------------ -- Scripts to run when the game is loaded: local function drx_ql_xre_load_state_callback( m_data ) -- Restore hidden targets list: if ( m_data.drx_ql_hidden_targets ) then drx_ql_hidden_targets = m_data.drx_ql_hidden_targets m_data.drx_ql_hidden_targets = nil end -- Restore undiscovered float fetch task list: if ( m_data.drx_ql_float_fetch_tasks ) then drx_ql_float_fetch_tasks = m_data.drx_ql_float_fetch_tasks m_data.drx_ql_float_fetch_tasks = nil end end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- on_game_start function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Registers callback scripts -- -- Usage: -- (called when a game session begins) -- -- Parameters: -- none -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified March 19, 2018 -- ------------------------------------------------------------------------------------------------ -- Register callback scripts: function on_game_start( ) RegisterScriptCallback( "save_state", drx_ql_xre_save_state_callback ) RegisterScriptCallback( "load_state", drx_ql_xre_load_state_callback ) end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_add_hidden_target function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Adds a hidden target id to the global hidden target list -- -- Usage: -- drx_ql_add_hidden_target( p[1], p[2] ) -- -- Parameters: -- p[1] (type: task id) -- - Task id of the task calling this function -- p[2] (type: task id or npc id) -- - NPC id of the hidden target to add (optional; if omitted target stored in axr_task_manager.bounties_by_id will be used) -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- -- Last modified: 22/07/2024 8:53:01 PM -- -> Modified function to allow for hidden targets in prisoner quests [moonshroom] -- ------------------------------------------------------------------------------------------------ -- Add hidden target to global array: function drx_ql_add_hidden_target( actor, npc, p ) local is_prisoner_task = ( ( task_manager.task_ini:r_bool_ex( p[1], "prisoner_task" ) ) or false ) -- Get the assassination target id: local npc_id if ( (#p > 1) and (p[2]) ) then npc_id = get_story_object_id( p[2] ) elseif ( is_prisoner_task == true ) then npc_id = ( db.actor and utils.load_var( db.actor, string.format( "%s_target_id", p[1] ) ) ) else npc_id = axr_task_manager.bounties_by_id[p[1]] end -- Save the id as a hidden target: drx_ql_hidden_targets[npc_id] = p[1] -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_remove_hidden_target function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Removes a hidden target id from the global hidden target list -- -- Usage: -- drx_ql_remove_hidden_target( p[1] ) -- -- Parameters: -- p[1] (type: task id) -- - Task id of the task calling this function -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified March 19, 2018 -- ------------------------------------------------------------------------------------------------ -- Remove hidden target from global array: function drx_ql_remove_hidden_target( actor, npc, p ) -- Remove the id from the hidden target list: for npc_id, task_id in pairs( drx_ql_hidden_targets ) do if ( (task_id) and (task_id == p[1]) ) then drx_ql_hidden_targets[npc_id] = nil break end end -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_meet_random_honcho function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Finds a random friendly honcho and creates task to meet -- -- Usage: -- drx_ql_meet_random_honcho( ) -- -- Parameters: -- p[1] (type: bool) -- - If true, just the selected task id will be returned, the task will not be given -- - If false or not supplied, the selected task will be given to the actor -- -- Persistent storage: -- drx_ql_current_honcho (type: string, npc name) -- - Current meet honcho target npc -- drx_ql_current_task (type: string, task id) -- - ID of the current questline task the player has -- drx_ql_current_task_number (type: int) -- - Current meet honcho task number -- drx_ql_meet_task_history_{x} (type: string, npc section name) -- - Previous meet task targets -- -- Ini requirements: -- drx\drx_ql_config.ltx -- [sim_task_props] -- meet_task_history (int) -- - Number of meet tasks to keep in history to minimize repeats -- [questline_honchos] (type: string, npc name = cdl string, faction names) -- - List of questline honchos to meet and their surrounding factions -- misc\drx_ql_tasks\drx_ql_sl_meet_tasks.ltx -- - Config file containing meet with tasks for questline honchos -- -- Return value (type: string, task id): -- Returns the selected task id on success -- Returns nil on failure -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified November 25, 2019 -- ------------------------------------------------------------------------------------------------ -- Give actor meet honcho task: function drx_ql_meet_random_honcho( actor, npc, p ) -- Check if questline should continue: if ( (has_alife_info( "drx_ql_info_questline_ended" )) or (has_alife_info( "actor_made_wish" )) ) then return end -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Could not select meet honcho, db.actor not available" ) return end -- Build list of available meet honchos: local honcho_list = {} local meet_history = (drx_ql_ini:r_float_ex( "sim_task_props", "meet_task_history" ) or 0) local available_honcho_list = alun_utils.collect_section( drx_ql_ini, "questline_honchos" ) if ( (not available_honcho_list) or (#available_honcho_list < 1) ) then printf( "DRX QL Error: Could not select meet honcho, no available honchos found" ) return end -- Inspect each available honcho: for i = 1, ( #available_honcho_list ) do -- Check if the current honcho is not the current task giver: local honcho = available_honcho_list[i] if ( honcho ~= utils.load_var( db.actor, "drx_ql_current_honcho", "" ) ) then -- Check if the current honcho is alive: local honcho_id = get_story_object_id(honcho) local honcho_obj = (honcho_id and alife():object(honcho_id)) if ( (honcho == "esc_m_trader") or (honcho == "zat_b30_owl_stalker_trader") or (honcho_obj and honcho_obj:alive( )) ) then -- Check if the honcho surrounding factions are not enemies: local is_enemy = false local honcho_factions = alun_utils.parse_list( drx_ql_ini, "questline_honchos", honcho ) if ( (not honcho_factions) or (#honcho_factions < 1) ) then printf( "DRX QL Error: No surrounding factions specified for %s", honcho ) else for j = 1, ( #honcho_factions ) do if ( relation_registry.community_relation( honcho_factions[j], alife( ):actor( ):community( ) ) <= game_relations.ENEMIES ) then is_enemy = true break end end -- Check if honcho smart terrain not currently affected by the Brain Scorcher: if ( not is_enemy ) then local smart_obj if ( honcho == "esc_m_trader" ) then smart_obj = SIMBOARD.smarts_by_names["esc_smart_terrain_2_12"] elseif ( honcho == "zat_b30_owl_stalker_trader" ) then smart_obj = SIMBOARD.smarts_by_names["zat_stalker_base_smart"] else local smart_id = honcho_obj.m_smart_terrain_id -- printf("smart_id: %s\n", game.translate_string(smart_id)) smart_obj = alife( ):object( smart_id ) end if ( not smart_obj ) then printf( "DRX QL Error: Unable to find smart terrain for %s\n", honcho ) else if ( xr_conditions.drx_ql_smart_not_scorched( actor, npc, {smart_obj:name( )} ) ) then local weight = 1 -- Check if honcho is in recent history: local honcho_in_history = false for k = 1, ( meet_history ) do local prev_honcho = utils.load_var( db.actor, string.format( "drx_ql_meet_task_history_%s", k ) ) if ( (prev_honcho) and (prev_honcho == honcho) ) then honcho_in_history = true break end end -- Weight the current honcho as inverse of distance to actor: if ( not honcho_in_history ) then local nearest_smart_id = smart_terrain.nearest_to_actor_smart.id local nearest_smart_obj = alife( ):object( nearest_smart_id ) if ( not nearest_smart_obj ) then printf( "DRX QL Error: Unable to find smart terrain closest to actor" ) else local dist = utils.graph_distance( nearest_smart_obj.m_game_vertex_id, smart_obj.m_game_vertex_id ) if ( dist < 5000 ) then weight = (5 - math.ceil(dist / 1000) + 1) end end end -- If game is trying to force important task, filter out honchos that do not provide infoportions required in current phase. -- Else, proceed as normal. if ( has_alife_info( "drx_ql_force_important_task" ) ) then local can_give_info = false local important_task_phase = utils.load_var( db.actor, "drx_ql_important_task_phase", 1 ) local info_required_list = alun_utils.parse_list( drx_ql_ini, "important_task_phases", string.format( "phase_%s", important_task_phase ) ) local honcho_info_list = alun_utils.parse_list( drx_ql_ini, "important_honchos", honcho ) if ( ( not honcho_info_list ) or ( #honcho_info_list < 1 ) ) then printf( "DRX QL Error: No info list specified for %s", honcho ) else -- Go through list of required infoportions in current phase and see if the honcho can provide any of them. for p = 1, ( #info_required_list ) do for j = 1, ( #honcho_info_list ) do if ( info_required_list[p] == honcho_info_list[j] ) then can_give_info = true goto continue end end end ::continue:: -- If the honcho can give infoportions required in current phase, add him to the pile. if ( can_give_info == true ) then for n = 1, ( weight ) do honcho_list[#honcho_list + 1] = honcho end end end else -- Add the current honcho to the list of meet honchos: for n = 1, ( weight ) do honcho_list[#honcho_list + 1] = honcho end end end end end end end end end -- Pick next honcho: local next_honcho = utils.load_var( db.actor, "drx_ql_current_honcho", nil ) if ( #honcho_list > 0 ) then next_honcho = honcho_list[math.random( #honcho_list )] end utils.save_var( db.actor, "drx_ql_current_honcho", next_honcho ) -- Update history: for m = meet_history, 1, -1 do -- Store current meet honcho: if ( m == 1 ) then utils.save_var( db.actor, string.format( "drx_ql_meet_task_history_%s", m ), next_honcho ) -- Shift previous meet honchos: else utils.save_var( db.actor, string.format( "drx_ql_meet_task_history_%s", m ), utils.load_var( db.actor, string.format( "drx_ql_meet_task_history_%s", (m - 1) ) ) ) end end -- Increment current task number: utils.save_var( db.actor, "drx_ql_current_task_number", (utils.load_var( db.actor, "drx_ql_current_task_number", 1 ) + 1) ) printf( "DRX QL task count: %s", utils.load_var( db.actor, "drx_ql_current_task_number", 1 ) ) -- Build list of available meet current honcho tasks: local task_ltx_file = ini_file( "misc\\drx_ql_tasks\\drx_ql_sl_meet_tasks.ltx" ) local honcho_task_list = {} local honcho_task_id = "" local i = 1 while ( true ) do honcho_task_id = string.format( "drx_ql_%s_meet_task_%s", next_honcho, i ) if ( task_ltx_file:section_exist( honcho_task_id ) ) then -- table.insert( honcho_task_list, honcho_task_id ) honcho_task_list[#honcho_task_list + 1] = honcho_task_id i = (i + 1) else break end end -- Ensure at least one task was found: if ( (not honcho_task_list) or (#honcho_task_list < 1) ) then printf( "DRX QL Error: No meet honcho tasks available for %s", next_honcho ) return end -- Give player meet next honcho task: honcho_task_id = honcho_task_list[math.random( #honcho_task_list )] utils.save_var( db.actor, "drx_ql_current_task", honcho_task_id ) printf( "DRX QL: Current storyline task is %s", honcho_task_id ) give_info( string.format( "drx_ql_meet_honcho_%s", next_honcho ) ) if ( (not p) or (#p < 1) or (not p[1]) ) then task_manager.get_task_manager( ):give_task( honcho_task_id ) end -- Set return value: return honcho_task_id end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_decrease_sl_tasks_count function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Decreases the number of completed storyline tasks -- -- Usage: -- drx_ql_decrease_sl_tasks_count( ) -- -- Parameters: -- none -- -- Persistent storage: -- drx_ql_current_task_number (type: int) -- Current meet honcho task number -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified November 08, 2017 -- ------------------------------------------------------------------------------------------------ -- Decrease number of completed storyline tasks: function drx_ql_decrease_sl_tasks_count( actor, npc, p ) -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Could not decrement storyline task count, db.actor not available" ) return end -- Get the current task count: local task_count = utils.load_var( db.actor, "drx_ql_current_task_number", 1 ) -- Decrement the current task count: task_count = (task_count - 1) if ( task_count < 1 ) then task_count = 1 end -- Decrement unimportant tasks count. local unimportant_count = utils.load_var( db.actor, "drx_ql_unimportant_sl_task_count", 0 ) unimportant_count = ( unimportant_count - 1 ) if ( unimportant_count < 0 ) then unimportant_count = 0 end -- Save the current task count: utils.save_var( db.actor, "drx_ql_current_task_number", task_count ) utils.save_var( db.actor, "drx_ql_unimportant_sl_task_count", unimportant_count ) printf( "DRX QL: Player failed last storyline task, decrementing drx_ql_current_task_number" ) printf( "DRX QL task count: %s", task_count ) printf( "CotZ for IWP | xr_effects.script / drx_ql_decrease_sl_tasks_count() | [DBG] Unimportant storyline task count: %s", unimportant_count ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_reset_task function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Resets the task count and pstor vars associated with the specified task and task giver -- -- Usage: -- drx_ql_reset_task( [p1] ) -- -- Parameters: -- p[1] (type: string) -- - Task id of the finished task -- -- Persistent storage: -- drx_ql_hostage_giver_{npc_id} (type: bool) -- - Flag indicating whether or not the npc is a hostage task giver -- drx_ql_npc_stored_task_{npc_id} (type: string, task id) -- - Stored task the npc has to offer -- drx_ql_task_giver_{npc_id} (type: int) -- - Count of currently active tasks the npc has given the player -- drx_ql_{task_id}_{npc_id}_assassination_target (type: npc id) -- - Id of selected assassination target for specified task -- drx_ql_{task_id}_{npc_id}_target_smart (type: npc id) -- - Id of target smart terrain for specified task -- drx_ql_{task_id}_{npc_id}_enemy_smart_name (type: smart terrain name) -- - Name of the stored enemy smart terrain for a brawl task -- drx_ql_{task_id}_{npc_id}_friendly_smart_name (type: smart terrain name) -- - Name of the stored friendly smart terrain for a brawl task -- drx_ql_{task_id}_{npc_id}_enemy_faction (type: faction name) -- - Name of the stored enemy faction -- drx_ql_{task_id}_{npc_id}_friendly_faction (type: faction name) -- - Name of the stored friendly faction -- drx_ql_{task_id}_no_kill_id_{x} (type: int, npc id) -- - NPC's the player must not kill during the task -- {task_id}_fetch (type: object id) -- - Id of requested items for fetch task -- {task_id}_fetch_count (type: float, decimal percent) -- - Number of fetch items to collect -- {task_id}_fetch_cond (type: float, decimal percent) -- - Minimum acceptable condition of the fetch items -- {task_id}_id (type: smart terrain id) -- - Id of current target smart terrain for specified task -- {task_id}_max_dist (type: float) -- - Maximum distance from center to spawn a target item -- {task_id}_reward (type: object id) -- - Name of task reward item -- {task_id}_reward_value (type: float) -- - Value of task reward -- {task_id}_target_id (type: smart terrain id) -- - Id of current target for specified task -- {task_id}_target_level (type: section name) -- - Name of level the task target is on -- {task_id}_target_name (type: location name) -- - Name of the target smart terrain or special location for the specified task -- {task_id}_target_spawned (type: bool) -- - Flag indicating whether or not a task target has been spawned -- {task_id}_helper (type: string, squad id) -- - Squad id of the helper for the specified float fetch task -- {task_id}_enemy_smart (type: smart terrain name) -- - Name of the stored enemy smart terrain for a brawl task -- {task_id}_friendly_smart (type: smart terrain name) -- - Name of the stored friendly smart terrain for a brawl task -- {task_id}_enemy_faction (type: faction name) -- - Name of the stored enemy faction -- {task_id}_friendly_faction (type: faction name) -- - Name of the stored friendly faction -- {task_id}_enemy_count (type: int) -- - Number of enemy squads to spawn -- {task_id}_friendly_count (type: int) -- - Number of friendly squads to spawn -- {task_id}_search_time (type: int, seconds) -- - Amount of time a search will take -- {task_id}_start_time (type: ctime) -- - Time stamp for the start of a search -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified July 24, 2019 -- ------------------------------------------------------------------------------------------------ -- Reset task vars: function drx_ql_reset_task( actor, npc, p ) -- Validate input: if ( (not p) or (#p < 1) or (not p[1]) ) then printf( "DRX QL Error: Unable to reset task, no task id specified" ) return end -- Send update to the console: printf( "DRX QL: Task ended: %s", p[1] ) -- Remove task helper squad as actor companion: drx_ql_remove_task_helper( actor, npc, {p[1]} ) -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to reset task vars, db.actor not available" ) else -- Reset do not kill targets: local i = 0 while ( true ) do i = (i + 1) if ( utils.load_var( db.actor, string.format( "drx_ql_%s_no_kill_id_%s", p[1], i ), nil ) ~= nil ) then utils.save_var( db.actor, string.format( "drx_ql_%s_no_kill_id_%s", p[1], i ), nil ) else break end end -- Reset fetch task target: if ( utils.load_var( db.actor, string.format( "%s_fetch", p[1] ), nil ) ~= nil ) then utils.save_var( db.actor, string.format( "%s_fetch", p[1] ), nil ) end if ( utils.load_var( db.actor, string.format( "%s_fetch_count", p[1] ), nil ) ~= nil ) then utils.save_var( db.actor, string.format( "%s_fetch_count", p[1] ), nil ) end if ( utils.load_var( db.actor, string.format( "%s_fetch_cond", p[1] ), nil ) ~= nil ) then utils.save_var( db.actor, string.format( "%s_fetch_cond", p[1] ), nil ) end -- Reset smart terrain target: if ( utils.load_var( db.actor, string.format( "%s_id", p[1] ), nil ) ~= nil ) then utils.save_var( db.actor, string.format( "%s_id", p[1] ), nil ) end if ( utils.load_var( db.actor, string.format( "%s_target_id", p[1] ), nil ) ~= nil ) then utils.save_var( db.actor, string.format( "%s_target_id", p[1] ), nil ) end if ( utils.load_var( db.actor, string.format( "%s_target_name", p[1] ), nil ) ~= nil ) then utils.save_var( db.actor, string.format( "%s_target_name", p[1] ), nil ) end -- Reset max offset distance: if ( utils.load_var( db.actor, string.format( "%s_max_dist", p[1] ), nil ) ~= nil ) then utils.save_var( db.actor, string.format( "%s_max_dist", p[1] ), nil ) end -- Reset task reward: if ( utils.load_var( db.actor, string.format( "%s_reward", p[1] ), nil ) ~= nil ) then utils.save_var( db.actor, string.format( "%s_reward", p[1] ), nil ) end if ( utils.load_var( db.actor, string.format( "%s_reward_value", p[1] ), nil ) ~= nil ) then utils.save_var( db.actor, string.format( "%s_reward_value", p[1] ), nil ) end -- Reset task target level: if ( utils.load_var( db.actor, string.format( "%s_target_level", p[1] ), nil ) ~= nil ) then utils.save_var( db.actor, string.format( "%s_target_level", p[1] ), nil ) end -- Reset task helper id: if ( utils.load_var( db.actor, string.format( "%s_helper", p[1] ), nil ) ~= nil ) then utils.save_var( db.actor, string.format( "%s_helper", p[1] ), nil ) end -- Reset brawl task parameters: if ( utils.load_var( db.actor, string.format( "%s_enemy_smart", p[1] ), nil ) ~= nil ) then utils.save_var( db.actor, string.format( "%s_enemy_smart", p[1] ), nil ) end if ( utils.load_var( db.actor, string.format( "%s_friendly_smart", p[1] ), nil ) ~= nil ) then utils.save_var( db.actor, string.format( "%s_friendly_smart", p[1] ), nil ) end if ( utils.load_var( db.actor, string.format( "%s_enemy_faction", p[1] ), nil ) ~= nil ) then utils.save_var( db.actor, string.format( "%s_enemy_faction", p[1] ), nil ) end if ( utils.load_var( db.actor, string.format( "%s_friendly_faction", p[1] ), nil ) ~= nil ) then utils.save_var( db.actor, string.format( "%s_friendly_faction", p[1] ), nil ) end if ( utils.load_var( db.actor, string.format( "%s_enemy_count", p[1] ), nil ) ~= nil ) then utils.save_var( db.actor, string.format( "%s_enemy_count", p[1] ), nil ) end if ( utils.load_var( db.actor, string.format( "%s_friendly_count", p[1] ), nil ) ~= nil ) then utils.save_var( db.actor, string.format( "%s_friendly_count", p[1] ), nil ) end -- Reset search time: if ( utils.load_var( db.actor, string.format( "%s_search_time", p[1] ), nil ) ~= nil ) then utils.save_var( db.actor, string.format( "%s_search_time", p[1] ), nil ) end -- Reset target spawned flag: if ( utils.load_var( db.actor, string.format( "%s_target_spawned", p[1] ), nil ) ~= nil ) then utils.save_var( db.actor, string.format( "%s_target_spawned", p[1] ), nil ) end -- Reset task search start time: if ( utils.load_ctime( db.actor, string.format( "%s_start_time", p[1] ), nil ) ~= nil ) then utils.save_ctime( db.actor, string.format( "%s_start_time", p[1] ), nil ) end -- Get task giver id: local task_info = task_manager.get_task_manager( ).task_info local giver_id = task_info[p[1]].task_giver_id if ( giver_id ) then -- Decrement active given task count for the task giver: local giver_task_count = (utils.load_var( db.actor, string.format( "drx_ql_task_giver_%s", giver_id ), 0 ) - 1) if ( giver_task_count < 0 ) then giver_task_count = 0 end utils.save_var( db.actor, string.format( "drx_ql_task_giver_%s", giver_id ), giver_task_count ) printf( "DRX QL: drx_ql_task_giver_%s unregistered (%s outstanding)", giver_id, giver_task_count ) -- Reset stored task for task giver: utils.save_var( db.actor, string.format( "drx_ql_npc_stored_task_%s", giver_id ), nil ) -- Reset stored assassination target: if ( utils.load_var( db.actor, string.format( "drx_ql_%s_%s_assassination_target", p[1], giver_id ), nil ) ~= nil ) then utils.save_var( db.actor, string.format( "drx_ql_%s_%s_assassination_target", p[1], giver_id ), nil ) end -- Reset stored smart terrain target: if ( utils.load_var( db.actor, string.format( "drx_ql_%s_%s_target_smart", p[1], giver_id ), nil ) ~= nil ) then utils.save_var( db.actor, string.format( "drx_ql_%s_%s_target_smart", p[1], giver_id ), nil ) end -- Reset stored dynamic brawl task parameters: if ( utils.load_var( db.actor, string.format( "drx_ql_%s_%s_enemy_smart_name", p[1], giver_id ), nil ) ~= nil ) then utils.save_var( db.actor, string.format( "drx_ql_%s_%s_enemy_smart_name", p[1], giver_id ), nil ) end if ( utils.load_var( db.actor, string.format( "drx_ql_%s_%s_friendly_smart_name", p[1], giver_id ), nil ) ~= nil ) then utils.save_var( db.actor, string.format( "drx_ql_%s_%s_friendly_smart_name", p[1], giver_id ), nil ) end if ( utils.load_var( db.actor, string.format( "drx_ql_%s_%s_enemy_faction", p[1], giver_id ), nil ) ~= nil ) then utils.save_var( db.actor, string.format( "drx_ql_%s_%s_enemy_faction", p[1], giver_id ), nil ) end if ( utils.load_var( db.actor, string.format( "drx_ql_%s_%s_friendly_faction", p[1], giver_id ), nil ) ~= nil ) then utils.save_var( db.actor, string.format( "drx_ql_%s_%s_friendly_faction", p[1], giver_id ), nil ) end -- Unregister hostage task giver: if ( utils.load_var( db.actor, string.format( "drx_ql_hostage_giver_%s", giver_id ), nil ) ~= nil ) then utils.save_var( db.actor, string.format( "drx_ql_hostage_giver_%s", giver_id ), false ) printf( "DRX QL: drx_ql_hostage_giver_%s unregistered", giver_id ) end end end -- Remove high value fetch item task from global list: drx_ql_remove_havfetch_task( actor, npc, {p[1]} ) -- Remove hidden target id from global list: drx_ql_remove_hidden_target( actor, npc, {p[1]} ) -- Remove undiscovered float fetch task from global list: for j = 1, ( #drx_ql_float_fetch_tasks ) do if ( drx_ql_float_fetch_tasks[j] == p[1] ) then table.remove( drx_ql_float_fetch_tasks, j ) break end end -- Remove assassination target from target array: axr_task_manager.bounties_by_id[p[1]] = nil -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_money_task_payment function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Takes payment from actor for a money task -- -- Usage: -- drx_ql_money_task_payment( p[1] ) -- -- Parameters: -- p[1] (type: string) -- - Task ID of the task requesting payment -- -- Persistent storage: -- {task_id}_fetch (type: int) -- - Amount of money requested for the money task -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified October 17, 2017 -- ------------------------------------------------------------------------------------------------ -- Take money task payment: function drx_ql_money_task_payment( actor, npc, p ) -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to complete money task payment, db.actor not available" ) return end -- Validate input: if ( (not p) or (#p < 1) or (p[1] == nil) ) then printf( "DRX QL Error: Unable to complete money task payment, task id not specified" ) return end -- Take money from player: local money = tonumber( utils.load_var( db.actor, string.format( "%s_fetch", p[1] ), 0 ) ) db.actor:give_money( -(money) ) news_manager.relocate_money( db.actor, "out", money ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_change_factions function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Changes the actor to the specified faction -- -- Usage: -- drx_ql_change_factions( p[1] ) -- -- Parameters: -- p[1] (type: string, faction name) -- - Faction for the actor to join (stalker, dolg, freedom, csky, ecolog, killer, army, bandit, or monolith) -- -- External strings: -- drx_ql_strings.xml -- drx_ql_str_joined_faction_news (type: string) -- - Text to display in dynamic news alert when player changes factions -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified November 22, 2019 -- ------------------------------------------------------------------------------------------------ -- Change actor faction: function drx_ql_change_factions( actor, npc, p ) -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to change actor faction, db.actor not available" ) return end -- Validate input: if ( (not p) or (#p < 1) or (p[1] == nil) ) then printf( "DRX QL Error: Unable to change actor faction, invalid faction name" ) return end local new_faction = p[1] -- Check if actor faction is same as new faction: if ( string.find( character_community( db.actor ), new_faction ) ) then printf( "DRX QL: Actor faction not changed, actor is already requested faction" ) return end -- Set actor faction: db.actor:set_character_community( string.format( "actor_%s", new_faction ), 0, 0 ) local communities = alun_utils.get_communities_list( ) for i, community in pairs( communities ) do relation_registry.set_community_goodwill( community, db.actor:id( ), 0 ) end printf( "DRX QL: Actor faction changed to %s", new_faction ) -- Set companion faction: for id, squad in pairs( axr_companions.companion_squads ) do if ( squad and squad.commander_id ) then -- Check if squad contains a prisoner: local is_prisoner_squad = false for n in squad:squad_members( ) do local member = (db.storage[n.id] and db.storage[n.id].object) if ( member and member:alive( ) ) then if ( member:has_info( "drx_ql_npc_is_prisoner" ) ) then is_prisoner_squad = true break end end end -- Change squad faction: if ( not is_prisoner_squad ) then squad.player_id = new_faction squad:set_squad_relation( game_relations.FRIENDS ) 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_character_community( new_faction, 0, 0 ) for i, community in pairs( communities ) do member:set_community_goodwill( community, 0 ) end printf( "DRX QL: Companion faction changed to %s", new_faction ) end end end end end -- Send dynamic news alert: news_manager.send_tip( db.actor, string.format( game.translate_string( "drx_ql_str_joined_faction_news" ), game.translate_string( new_faction ) ), nil, "completionist", nil, nil ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_give_escort_task_companions function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Gives an escort task companion squad to the player -- -- Usage: -- drx_ql_give_escort_task_companions( p[1], p[2], ... ) -- -- Parameters: -- p[1] (type: string, squad section name) -- - Special task squad to spawn at the actor's location -- p[2], ... (type: string, item section names) -- - Items to spawn on each companion (optional) -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified December 06, 2019 -- ------------------------------------------------------------------------------------------------ -- Give escort task companions: function drx_ql_give_escort_task_companions( actor, npc, p ) -- Validate input: if ( (not p) or (#p < 1) or (not p[1]) or (not system_ini( ):section_exist( p[1] )) ) then printf( "DRX QL: Unable to give escort task companions, requested companion squad is invalid" ) return end -- Get smart terrain actor is currently at: local nearest_smart_id = smart_terrain.nearest_to_actor_smart.id local smart = alife_object( nearest_smart_id ) if ( not smart ) then printf( "DRX QL: Unable to give escort task companions, cannot determine actor smart terrain" ) return end -- Spawn the requested companion squad: local squad = alife( ):create( p[1], smart.position, smart.m_level_vertex_id, smart.m_game_vertex_id ) if ( not squad ) then printf( "DRX QL Error: Unable to give escort task companions, could not spawn requested companion squad" ) return end squad:create_npc( smart ) squad:set_squad_relation( game_relations.FRIENDS ) axr_companions.companion_squads[squad.id] = squad -- Set companion squad properties: for k in ( squad:squad_members( ) ) do local se_obj = (k.object or (k.id and alife( ):object( k.id ))) if ( se_obj ) then -- Set up companion npc: SIMBOARD:setup_squad_and_group( se_obj ) utils.se_obj_save_var( se_obj.id, se_obj:name( ), "companion", true ) utils.se_obj_save_var( se_obj.id, se_obj:name( ), "companion_cannot_dismiss", true ) utils.se_obj_save_var( se_obj.id, se_obj:name( ), "companion_cannot_teleport", false ) -- Spawn requested loadout on npc: for i = 2, ( #p ) do if ( system_ini( ):section_exist( p[i] ) ) then alife( ):create( p[i], se_obj.position, se_obj.m_level_vertex_id, se_obj.m_game_vertex_id, k.id ) end end end end -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_setup_hostage_task function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Sets up a rescue hostage task -- - Modification of setup_companion_task (CoC 1.5b r4) -- -- Usage: -- drx_ql_setup_hostage_task( p[1] ) -- -- Parameters: -- p[1] (type: string, squad name) -- - Section name of the hostage squad to spawn -- p[2] (type: string, smart terrain name) -- - Smart terrain to spawn the hostage at or nil (see p[3]) -- p[3] (type: var name) -- - Name of the pstor var containing the smart terrain to spawn the hostage at if p[2] is nil -- -- Persistent storage: -- drx_ql_hostage_giver_needed (type: bool) -- - Flag indicating whether or not the current npc needs to be registered as a hostage task giver -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified May 17, 2019 -- ------------------------------------------------------------------------------------------------ -- Set up hostage task: function drx_ql_setup_hostage_task( actor, npc, p ) -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to set up hostage task, db.actor not available" ) return end -- Validate specified hostage squad: if ( not system_ini( ):section_exist( p[1] ) ) then printf( "DRX QL Error: Unable to set up hostage task, invalid hostage squad specified" ) return end -- Determine the smart terrain to spawn the hostage at: local smart if ( (p[2]) and (p[2] ~= "nil") ) then smart = SIMBOARD.smarts_by_names[p[2]] elseif ( (p[3]) and (p[3] ~= "nil") ) then smart = alife_object( utils.load_var( db.actor, p[3] ) ) end -- Verify a valid smart terrain was specified: if ( not smart ) then printf( "DRX QL Error: Unable to set up hostage task, invalid smart terrain specified" ) return end -- Spawn the hostage squad: local squad = alife( ):create( p[1], smart.position, smart.m_level_vertex_id, smart.m_game_vertex_id ) if ( not squad ) then printf( "DRX QL Error: Unable to set up hostage task, could not spawn hostage squad" ) return end squad:create_npc( smart ) squad:set_squad_relation( game_relations.FRIENDS ) axr_companions.companion_squads[squad.id] = squad -- Set hostage squad properties: for k in ( squad:squad_members( ) ) do local se_obj = (k.object or (k.id and alife( ):object( k.id ))) if ( se_obj ) then SIMBOARD:setup_squad_and_group( se_obj ) local member_obj = (k.id and (db.storage[k.id] and db.storage[k.id].object)) if ( member_obj ) then member_obj:give_info_portion( "npcx_beh_ignore_combat" ) member_obj:give_info_portion( "npcx_beh_ignore_actor_enemies" ) end utils.se_obj_save_var( se_obj.id, se_obj:name( ), "companion", true ) utils.se_obj_save_var( se_obj.id, se_obj:name( ), "companion_cannot_dismiss", true ) utils.se_obj_save_var( se_obj.id, se_obj:name( ), "companion_cannot_teleport", true ) xrs_kill_wounded.hostage_list[se_obj.id] = smart.id end end -- Set flag indicating hostage task giver needs to be registered: utils.save_var( db.actor, "drx_ql_hostage_giver_needed", true ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_give_stored_smart_target function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Gives a smart terrain as task target -- -- Usage: -- drx_ql_give_stored_smart_target( p[1], p[2] ) -- -- Parameters: -- p[1] (type: string, task id) -- - Name of the task calling this function -- p[2] (type: string, smart terrain name) -- - If supplied, the smart terrain that will be given as target instead of stored target -- -- Persistent storage: -- drx_ql_{task_id}_{npc_id}_target_smart (type: smart terrain id) -- - Id of selected target smart terrain for specified task -- drx_ql_{task_id}_{npc_id}_enemy_faction (type: string, faction name) -- - Enemy faction for specified task -- {task_id}_id (type: smart terrain id) -- - Id of current target smart terrain for specified task -- {task_id}_enemy_faction (type: string, faction name) -- - Enemy faction for specified task -- -- Return value (type: bool): -- Returns true if a stored smart is given -- Returns false if a valid stored smart cannot be determined -- -- Notes: -- - Target given is the one stored in pstor var drx_ql_{npc_id}_{task_id}_target_smart -- - Enemy faction is the one stored in pstor var drx_ql_{npc_id}_{task_id}_enemy_faction -- - Target given is subsequently stored in pstor var {task_id}_id -- - Enemy faction is subsequently stored in pstor var {task_id}_enemy_faction -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified August 04, 2019 -- ------------------------------------------------------------------------------------------------ -- Give smart target: function drx_ql_give_stored_smart_target( actor, npc, p ) -- Validate input: if ( not p[1] ) then printf( "DRX QL Error: Unable to give smart terrain target, invalid parameters supplied" ) return false end -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to give smart terrain target, db.actor not available" ) return false end -- Get the id of the npc the actor is currently speaking with: local npc_id = utils.load_var( db.actor, "drx_ql_current_npc_speaker_id", nil ) if ( npc_id == nil ) then printf( "DRX QL Error: Unable to give smart terrain target, could not get id of current speaker" ) return false end -- Ensure a smart terrain target has been supplied: local smart_target if ( (#p > 1) and (p[2]) ) then smart_target = SIMBOARD.smarts_by_names[p[2]].id else smart_target = utils.load_var( db.actor, string.format( "drx_ql_%s_%s_target_smart", p[1], npc_id ), nil ) end if ( not smart_target ) then printf( "DRX QL Error: Unable to give smart terrain target, no valid smart target specified" ) return false end -- Get enemy faction: local enemy_faction = utils.load_var( db.actor, string.format( "drx_ql_%s_%s_enemy_faction", p[1], npc_id ) ) -- printf("give_stored_smart_target | enemy_faction: %s", game.translate_string(enemy_faction)) -- Give smart terrain target: utils.save_var( db.actor, string.format( "%s_id", p[1] ), smart_target ) utils.save_var( db.actor, string.format( "%s_enemy_faction", p[1] ), enemy_faction ) -- Reset stored target: utils.save_var( db.actor, string.format( "drx_ql_%s_%s_target_smart", p[1], npc_id ), nil ) utils.save_var( db.actor, string.format( "drx_ql_%s_%s_enemy_faction", p[1], npc_id ), nil ) -- Set return value: return true end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_give_assault_target function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Gives an assault task target -- -- Usage: -- drx_ql_give_assault_target( p[1], p[2] ) -- -- Parameters: -- p[1] (type: string, task id) -- - Name of the task calling this function -- p[2] (type: string, smart terrain name) -- - If supplied, the smart terrain that will be given as target instead of stored target -- -- Return value (type: bool): -- Returns true if a stored smart is given -- Returns false if a valid stored smart cannot be determined -- -- Notes: -- - Target given is the one stored in pstor var drx_ql_{npc_id}_{task_id}_target_smart -- - Target given is subsequently stored in pstor var {task_id}_id -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified August 04, 2019 -- ------------------------------------------------------------------------------------------------ -- Give assault task target: function drx_ql_give_assault_target( actor, npc, p ) -- Set return value: return drx_ql_give_stored_smart_target( actor, npc, p ) end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_setup_brawl_task function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Sets up a dynamic brawl task -- -- Usage: -- drx_ql_setup_brawl_task( p[1]:p[2]:p[3] ) -- -- Parameters: -- p[1] (type: string, task id) -- - Name of the task calling this function -- p[2] (type: int) -- - Number of enemy squads to spawn -- p[3] (type: int) -- - Number of friendly squads to spawn -- -- Persistent storage: -- drx_ql_{task_id}_{npc_id}_enemy_smart_name (type: smart terrain name) -- - Name of the stored enemy smart terrain for a brawl task -- drx_ql_{task_id}_{npc_id}_friendly_smart_name (type: smart terrain name) -- - Name of the stored friendly smart terrain for a brawl task -- drx_ql_{task_id}_{npc_id}_enemy_faction (type: faction name) -- - Name of the stored enemy faction -- drx_ql_{task_id}_{npc_id}_friendly_faction (type: faction name) -- - Name of the stored friendly faction -- drx_ql_current_npc_speaker_id (type: npc id) -- - Id of the current npc the actor is speaking to -- {task_id}_enemy_smart (type: smart terrain name) -- - Name of the stored enemy smart terrain for a brawl task -- {task_id}_friendly_smart (type: smart terrain name) -- - Name of the stored friendly smart terrain for a brawl task -- {task_id}_enemy_faction (type: faction name) -- - Name of the stored enemy faction -- {task_id}_friendly_faction (type: faction name) -- - Name of the stored friendly faction -- {task_id}_enemy_count (type: int) -- - Number of enemy squads to spawn -- {task_id}_friendly_count (type: int) -- - Number of friendly squads to spawn -- -- Ini requirements: -- drx\drx_ql_config.ltx -- [brawl_settings] -- max_squad_count (type: int) -- - Maximum number of brawl squads per faction -- -- Return value (type: bool): -- Returns true, false on error -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified July 24, 2019 -- ------------------------------------------------------------------------------------------------ -- Setup dynamic brawl task: function drx_ql_setup_brawl_task( actor, npc, p ) -- Validate input: if ( (not p) or (#p < 3) ) then printf( "DRX QL Error: Unable to setup brawl task, invalid parameters supplied" ) return false end -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to setup brawl task, db.actor not available" ) return false end -- Get the id of the npc the actor is currently speaking with: local npc_id = utils.load_var( db.actor, "drx_ql_current_npc_speaker_id", nil ) if ( npc_id == nil ) then printf( "DRX QL Error: Unable to setup brawl task, could not get id of current speaker" ) return false end -- Get max number of brawl squads: local max_squad_count = (drx_ql_ini:r_float_ex( "brawl_settings", "max_squad_count" ) or 0) if ( max_squad_count < 1 ) then return false end -- Store enemy squad count: local enemy_count = p[2] if ( enemy_count > max_squad_count ) then enemy_count = max_squad_count end utils.save_var( db.actor, string.format( "%s_enemy_count", p[1] ), enemy_count ) -- Store friendly squad count: local friendly_count = p[3] if ( friendly_count > max_squad_count ) then friendly_count = max_squad_count end utils.save_var( db.actor, string.format( "%s_friendly_count", p[1] ), friendly_count ) -- Store enemy smart terrain name: local enemy_smart_name = utils.load_var( db.actor, string.format( "drx_ql_%s_%s_enemy_smart_name", p[1], npc_id ) ) utils.save_var( db.actor, string.format( "%s_enemy_smart", p[1] ), enemy_smart_name ) utils.save_var( db.actor, string.format( "drx_ql_%s_%s_enemy_smart_name", p[1], npc_id ), nil ) -- Store friendly smart terrain name: local friendly_smart_name = utils.load_var( db.actor, string.format( "drx_ql_%s_%s_friendly_smart_name", p[1], npc_id ) ) utils.save_var( db.actor, string.format( "%s_friendly_smart", p[1] ), friendly_smart_name ) utils.save_var( db.actor, string.format( "drx_ql_%s_%s_friendly_smart_name", p[1], npc_id ), nil ) -- Store enemy faction name: local enemy_faction = utils.load_var( db.actor, string.format( "drx_ql_%s_%s_enemy_faction", p[1], npc_id ) ) utils.save_var( db.actor, string.format( "%s_enemy_faction", p[1] ), enemy_faction ) utils.save_var( db.actor, string.format( "drx_ql_%s_%s_enemy_faction", p[1], npc_id ), nil ) -- Store friendly faction name: local friendly_faction = utils.load_var( db.actor, string.format( "drx_ql_%s_%s_friendly_faction", p[1], npc_id ) ) utils.save_var( db.actor, string.format( "%s_friendly_faction", p[1] ), friendly_faction ) utils.save_var( db.actor, string.format( "drx_ql_%s_%s_friendly_faction", p[1], npc_id ), nil ) -- Set return value: return true end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_setup_brawl_task_ambush function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Sets up a dynamic brawl task, in ambush mode -- -- Usage: -- drx_ql_setup_brawl_task( p[1]:p[2]:p[3] ) -- -- Parameters: -- p[1] (type: string, task id) -- - Name of the task calling this function -- p[2] (type: int) -- - Number of enemy squads to spawn -- p[3] (type: int) -- - Number of ambush squads to spawn -- -- Persistent storage: -- drx_ql_{task_id}_{npc_id}_enemy_smart_name (type: smart terrain name) -- - Name of the stored enemy smart terrain for a brawl task -- drx_ql_{task_id}_{npc_id}_ambush_smart_name (type: smart terrain name) -- - Name of the stored ambush smart terrain for a brawl task -- drx_ql_{task_id}_{npc_id}_enemy_faction (type: faction name) -- - Name of the stored enemy faction -- drx_ql_{task_id}_{npc_id}_ambush_faction (type: faction name) -- - Name of the stored ambush faction -- drx_ql_current_npc_speaker_id (type: npc id) -- - Id of the current npc the actor is speaking to -- {task_id}_enemy_smart (type: smart terrain name) -- - Name of the stored enemy smart terrain for a brawl task -- {task_id}_ambush_smart (type: smart terrain name) -- - Name of the stored ambush smart terrain for a brawl task -- {task_id}_enemy_faction (type: faction name) -- - Name of the stored enemy faction -- {task_id}_ambush_faction (type: faction name) -- - Name of the stored ambush faction -- {task_id}_enemy_count (type: int) -- - Number of enemy squads to spawn -- {task_id}_ambush_count (type: int) -- - Number of ambush squads to spawn -- -- Ini requirements: -- drx\drx_ql_config.ltx -- [brawl_settings] -- max_squad_count (type: int) -- - Maximum number of brawl squads per faction -- -- Return value (type: bool): -- Returns true, false on error -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX, modified by GoozE for ambush behaviors -- for DoctorX Call of The Zone -- Last modified August 9, 2022 -- ------------------------------------------------------------------------------------------------ -- Setup dynamic brawl task, in ambush mode: function drx_ql_setup_brawl_task_ambush( actor, npc, p ) -- Validate input: if ( (not p) or (#p < 3) ) then printf( "DRX QL Error: Unable to setup brawl task, invalid parameters supplied" ) return false end -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to setup brawl task, db.actor not available" ) return false end -- Get the id of the npc the actor is currently speaking with: local npc_id = utils.load_var( db.actor, "drx_ql_current_npc_speaker_id", nil ) if ( npc_id == nil ) then printf( "DRX QL Error: Unable to setup brawl task, could not get id of current speaker" ) return false end -- Get max number of brawl squads: local max_squad_count = (drx_ql_ini:r_float_ex( "brawl_settings", "max_squad_count" ) or 0) if ( max_squad_count < 1 ) then return false end -- Store enemy squad count: local enemy_count = p[2] if ( enemy_count > max_squad_count ) then enemy_count = max_squad_count end utils.save_var( db.actor, string.format( "%s_enemy_count", p[1] ), enemy_count ) -- Store ambush squad count: local ambush_count = p[3] if ( ambush_count > max_squad_count ) then ambush_count = max_squad_count end utils.save_var( db.actor, string.format( "%s_ambush_count", p[1] ), ambush_count ) -- Store enemy smart terrain name: local enemy_smart_name = utils.load_var( db.actor, string.format( "drx_ql_%s_%s_enemy_smart_name", p[1], npc_id ) ) utils.save_var( db.actor, string.format( "%s_enemy_smart", p[1] ), enemy_smart_name ) utils.save_var( db.actor, string.format( "drx_ql_%s_%s_enemy_smart_name", p[1], npc_id ), nil ) -- Store ambush smart terrain name: local ambush_smart_name = utils.load_var( db.actor, string.format( "drx_ql_%s_%s_ambush_smart_name", p[1], npc_id ) ) utils.save_var( db.actor, string.format( "%s_ambush_smart", p[1] ), ambush_smart_name ) utils.save_var( db.actor, string.format( "drx_ql_%s_%s_ambush_smart_name", p[1], npc_id ), nil ) -- Store enemy faction name: local enemy_faction = utils.load_var( db.actor, string.format( "drx_ql_%s_%s_enemy_faction", p[1], npc_id ) ) utils.save_var( db.actor, string.format( "%s_enemy_faction", p[1] ), enemy_faction ) utils.save_var( db.actor, string.format( "drx_ql_%s_%s_enemy_faction", p[1], npc_id ), nil ) -- Store ambush faction name: local ambush_faction = utils.load_var( db.actor, string.format( "drx_ql_%s_%s_ambush_faction", p[1], npc_id ) ) utils.save_var( db.actor, string.format( "%s_ambush_faction", p[1] ), ambush_faction ) utils.save_var( db.actor, string.format( "drx_ql_%s_%s_ambush_faction", p[1], npc_id ), nil ) -- Set return value: return true end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_end_brawl_task function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Ends a dynamic brawl task -- -- Usage: -- drx_ql_end_brawl_task( p[1] ) -- -- Parameters: -- p[1] (type: string, task id) -- - Name of the task calling this function -- -- Persistent storage: -- {task_id}_enemy_faction (type: faction name) -- - Name of the stored enemy faction -- {task_id}_friendly_faction (type: faction name) -- - Name of the stored friendly faction -- -- Ini requirements: -- drx\drx_ql_config.ltx -- [brawl_settings] -- max_squad_count (type: int) -- - Maximum number of brawl squads per faction -- -- Return value (type: bool): -- Returns true, false on error -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified August 25, 2019 -- ------------------------------------------------------------------------------------------------ -- End dynamic brawl task: function drx_ql_end_brawl_task( actor, npc, p ) -- Validate input: if ( (not p) or (#p < 1) ) then printf( "DRX QL Error: Unable to end brawl task, invalid parameters supplied" ) return false end -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to end brawl task, db.actor not available" ) return false end -- Get max number of brawl squads: local max_squad_count = (drx_ql_ini:r_float_ex( "brawl_settings", "max_squad_count" ) or 0) if ( max_squad_count < 1 ) then return false end -- Build array of brawl squads to remove: local squad_list = {} local enemy_faction = utils.load_var( db.actor, string.format( "%s_enemy_faction", p[1] ) ) local friendly_faction = utils.load_var( db.actor, string.format( "%s_friendly_faction", p[1] ) ) for i = 1, ( max_squad_count ) do -- table.insert( squad_list, string.format( "drx_ql_brawl_squad_%s_%s", enemy_faction, i ) ) squad_list[#squad_list + 1] = string.format( "drx_ql_brawl_squad_%s_%s", enemy_faction, i ) -- table.insert( squad_list, string.format( "drx_ql_brawl_squad_%s_%s", friendly_faction, i ) ) squad_list[#squad_list + 1] = string.format( "drx_ql_brawl_squad_%s_%s", friendly_faction, i ) end -- Despawn squads: drx_ql_remove_story_squad( actor, npc, squad_list ) -- Set return value: return true end -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_end_brawl_task_ambush function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Ends a dynamic brawl task, in ambush mode. -- -- Usage: -- drx_ql_end_brawl_task_ambush( p[1] ) -- -- Parameters: -- p[1] (type: string, task id) -- - Name of the task calling this function -- -- Persistent storage: -- {task_id}_enemy_faction (type: faction name) -- - Name of the stored enemy faction -- {task_id}_ambush_faction (type: faction name) -- - Name of the stored friendly faction -- -- Ini requirements: -- drx\drx_ql_config.ltx -- [brawl_settings] -- max_squad_count (type: int) -- - Maximum number of brawl squads per faction -- -- Return value (type: bool): -- Returns true, false on error -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX, modified by GoozE for ambush implementation -- for DoctorX Questlines 2.0 -- Last modified August 9, 2022 -- ------------------------------------------------------------------------------------------------ -- End dynamic brawl task: function drx_ql_end_brawl_task_ambush( actor, npc, p ) -- Validate input: if ( (not p) or (#p < 1) ) then printf( "DRX QL Error: Unable to end brawl task, invalid parameters supplied" ) return false end -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to end brawl task, db.actor not available" ) return false end -- Get max number of brawl squads: local max_squad_count = (drx_ql_ini:r_float_ex( "brawl_settings", "max_squad_count" ) or 0) if ( max_squad_count < 1 ) then return false end -- Build array of brawl squads to remove: local squad_list = {} local enemy_faction = utils.load_var( db.actor, string.format( "%s_enemy_faction", p[1] ) ) local ambush_faction = utils.load_var( db.actor, string.format( "%s_ambush_faction", p[1] ) ) for i = 1, ( max_squad_count ) do -- table.insert( squad_list, string.format( "drx_ql_brawl_squad_%s_%s", enemy_faction, i ) ) squad_list[#squad_list + 1] = string.format( "drx_ql_brawl_squad_%s_%s", enemy_faction, i ) -- table.insert( squad_list, string.format( "drx_ql_brawl_squad_ambush_%s_%s", ambush_faction, i ) ) squad_list[#squad_list + 1] = string.format( "drx_ql_brawl_squad_ambush_%s_%s", ambush_faction, i ) end -- Despawn squads: drx_ql_remove_story_squad( actor, npc, squad_list ) -- Set return value: return true end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_show_assassination_target function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Displays previously selected assassination target during task job description dialog -- - Modification of on_init_bounty_hunt (CoC 1.5b r4) -- -- Usage: -- drx_ql_show_assassination_target( p[1], p[2] ) -- -- Parameters: -- p[1] (type: string, task id) -- - Name of the task calling this function -- p[2] (type: bool, target type) -- - Determines if target is hidden or not (true = hidden, false = not hidden) -- -- Persistent storage: -- drx_ql_{task_id}_{npc_id}_assassination_target (type: npc id) -- - Id of selected assassination target for specified task -- drx_ql_current_npc_speaker_id (type: npc id) -- - Id of the current npc the actor is speaking to -- -- Return value (type: nil): -- none -- -- Notes: -- - Target given is the one stored in pstor var drx_ql_{task_id}_{npc_id}_assassination_target (from xr_conditions.drx_ql_find_assassination_target) -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- -- Last modified: Jul 4, 2024, 12:13 AM -- Modified by: moonshroom -- Call of the Zone for IWP (Indev 2) -- ------------------------------------------------------------------------------------------------ -- Show assassination target: function drx_ql_show_assassination_target( actor, npc, p ) -- Validate input: if ( #p < 2 ) then printf( "DRX QL Error: Unable to display assassination task target, invalid parameters supplied" ) return end -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to display assassination task target, db.actor not available" ) return end -- Get the id of the npc the actor is currently speaking with: local npc_id = utils.load_var( db.actor, "drx_ql_current_npc_speaker_id", nil ) if ( npc_id == nil ) then printf( "DRX QL Error: Unable to display assassination task target, could not get id of current speaker" ) return false end local target_hidden = p[2] -- Ensure an assassination target has been supplied: local target_id = utils.load_var( db.actor, string.format( "drx_ql_%s_%s_assassination_target", p[1], npc_id ), nil ) if ( not target_id ) then printf( "DRX QL Error: Unable to display assassination task target, no stored target found" ) return end -- Function for displaying target information: local function postpone_for_next_frame( target_id ) local se_obj = alife( ):object( target_id ) if ( se_obj ) then local news_caption = game.translate_string( task_manager.task_ini:r_string_ex( p[1], "title" ) ) local news_text if (target_hidden == "true") then news_text = string.format( "%s %s\\n %s %s", game.translate_string( "st_mm_faction_cap_character_name"), se_obj:character_name( ), game.translate_string( "st_mm_faction_cap_faction" ), game.translate_string( se_obj:community( ))) elseif (target_hidden == "false") then news_text = string.format( "%s %s\\n %s %s\\n %s %s", game.translate_string( "st_mm_faction_cap_character_name"), se_obj:character_name( ), game.translate_string( "st_mm_faction_cap_faction" ), game.translate_string( se_obj:community( )), game.translate_string( "st_location" ), game.translate_string(alife():level_name(game_graph():vertex(se_obj.m_game_vertex_id):level_id()))) end db.actor:give_talk_message2( news_caption, news_text, se_obj:character_icon( ), "iconed_answer_item" ) end return true end -- Create time event for displaying target information: CreateTimeEvent( 0, "drx_ql_show_assassination_target", 0, postpone_for_next_frame, target_id ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_give_assassination_target function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Gives previously selected assassination target as task target -- - Modification of on_init_bounty_hunt (CoC 1.5b r4) -- -- Usage: -- drx_ql_give_assassination_target( p[1] ) -- -- Parameters: -- p[1] (type: string, task id) -- - Name of the task calling this function -- -- Persistent storage: -- drx_ql_{task_id}_{npc_id}_assassination_target (type: npc id) -- - Id of selected assassination target for specified task -- drx_ql_{task_id}_no_kill_id_{x} (type: int, npc id) -- - NPC's the player must not kill during the task -- drx_ql_current_npc_speaker_id (type: npc id) -- - Id of the current npc the actor is speaking to -- -- Return value (type: nil): -- none -- -- Notes: -- - Target given is the one stored in pstor var drx_ql_{task_id}_{npc_id}_assassination_target (from xr_conditions.drx_ql_find_assassination_target) -- - Target given is subsequently stored in axr_task_manager.bounties_by_id[{task_id}] -- - Target companion ids are stored in drx_ql_{task_id}_no_kill_id_{x} -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- -- Last modified: September 10, 2019 -- ------------------------------------------------------------------------------------------------ -- Give assassination target: function drx_ql_give_assassination_target( actor, npc, p ) -- Validate input: if ( not p[1] ) then printf( "DRX QL Error: Unable to give assassination task target, invalid parameters supplied" ) return end -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to give assassination task target, db.actor not available" ) return end -- Get the id of the npc the actor is currently speaking with: local npc_id = utils.load_var( db.actor, "drx_ql_current_npc_speaker_id", nil ) if ( npc_id == nil ) then printf( "DRX QL Error: Unable to give assassination task target, could not get id of current speaker" ) return false end -- Ensure an assassination target has been supplied: local target_id = utils.load_var( db.actor, string.format( "drx_ql_%s_%s_assassination_target", p[1], npc_id ), nil ) if ( not target_id ) then printf( "DRX QL Error: Unable to give assassination task target, no stored target found" ) return end -- Give assassination task target: axr_task_manager.bounties_by_id[p[1]] = target_id -- Store assassination target squad companion ids: local tgt_obj = alife( ):object( target_id ) if ( tgt_obj ) then local tgt_squad = get_object_squad( tgt_obj ) if ( tgt_squad ) then local i = 0 for member in tgt_squad:squad_members( ) do if ( (member) and (member.id) and (member.id ~= target_id) ) then i = (i + 1) utils.save_var( db.actor, string.format( "drx_ql_%s_no_kill_id_%s", p[1], i ), member.id ) end end end end -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_give_prisoner_target function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Gives previously selected assassination target as a prisoner task target -- -- Usage: -- drx_ql_give_prisoner_target( p[1] ) -- -- Parameters: -- p[1] (type: string, task id) -- - Name of the task calling this function -- -- Persistent storage: -- drx_ql_{task_id}_{npc_id}_assassination_target (type: npc id) -- - Id of selected assassination target for specified task -- drx_ql_current_npc_speaker_id (type: npc id) -- - Id of the current npc the actor is speaking to -- {task_id}_target_id (type: npc id) -- - Id of selected target for specified task -- -- Return value (type: nil): -- none -- -- Notes: -- - Target given is the one stored in pstor var drx_ql_{task_id}_{npc_id}_assassination_target (from xr_conditions.drx_ql_find_assassination_target) -- - Target given is subsequently stored in pstor var {task_id}_target_id -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified November 17, 2019 -- ------------------------------------------------------------------------------------------------ -- Give assassination target: function drx_ql_give_prisoner_target( actor, npc, p ) -- Validate input: if ( not p[1] ) then printf( "DRX QL Error: Unable to give prisoner task target, invalid parameters supplied" ) return end -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to give prisoner task target, db.actor not available" ) return end -- Get the id of the npc the actor is currently speaking with: local npc_id = utils.load_var( db.actor, "drx_ql_current_npc_speaker_id", nil ) if ( npc_id == nil ) then printf( "DRX QL Error: Unable to give prisoner task target, could not get id of current speaker" ) return false end -- Ensure an assassination target has been supplied: local target_id = utils.load_var( db.actor, string.format( "drx_ql_%s_%s_assassination_target", p[1], npc_id ), nil ) if ( not target_id ) then printf( "DRX QL Error: Unable to give prisoner task target, no stored target found" ) return end -- Give prisoner task target: drx_ql_force_wounded.drx_ql_force_wound_npcs[target_id] = true utils.save_var( db.actor, string.format( "%s_target_id", p[1] ), target_id ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_reset_prisoner_task function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Resets a prisoner snatch task -- -- Usage: -- drx_ql_reset_prisoner_task( p[1] ) -- -- Parameters: -- p[1] (type: string, task id) -- - Name of the task calling this function -- -- Persistent storage: -- {task_id}_target_id (type: npc id) -- - Id of selected target for specified task -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified November 17, 2019 -- ------------------------------------------------------------------------------------------------ -- Reset prisoner snatch task: function drx_ql_reset_prisoner_task( actor, npc, p ) -- Validate input: if ( not p[1] ) then printf( "DRX QL Error: Unable to reset prisoner task, invalid parameters supplied" ) return end -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to reset prisoner task, db.actor not available" ) return end -- Get the target id: local prisoner_id = utils.load_var( db.actor, string.format( "%s_target_id", p[1] ) ) if ( not prisoner_id ) then return end -- Remove target as companion: local prisoner_obj = alife( ):object( prisoner_id ) if ( prisoner_obj ) then local squad = get_object_squad( prisoner_obj ) if ( squad ) then squad.scripted_target = nil squad.current_action = nil axr_companions.companion_squads[squad.id] = nil for member in squad:squad_members( ) do local member_obj = (member.id and db.storage[member.id] and db.storage[member.id].object) if ( member_obj ) then axr_logic.restore_scheme_and_logic( member_obj ) member_obj:disable_info_portion( "npcx_is_companion" ) member_obj:disable_info_portion( "npcx_beh_cannot_dismiss" ) utils.se_obj_save_var( member.id, member.object:name( ), "companion", nil ) utils.se_obj_save_var( member.id, member.object:name( ), "companion_cannot_dismiss", nil ) utils.se_obj_save_var( member.id, member.object:name( ), "companion_cannot_teleport", nil ) end end end end -- Remove target as force wounded NPC: drx_ql_force_wounded.drx_ql_force_wound_npcs[prisoner_id] = nil -- Remove force wounded flags: local prisoner_npc = ((db.storage[prisoner_id] and db.storage[prisoner_id].object) or level.object_by_id( prisoner_id )) if (prisoner_npc ) then prisoner_npc:disable_info_portion( "drx_ql_npc_make_force_wounded" ) prisoner_npc:disable_info_portion( "drx_ql_npc_is_force_wounded" ) prisoner_npc:disable_info_portion( "drx_ql_npc_is_prisoner" ) prisoner_npc:disable_info_portion( "drx_ql_npc_prisoner_needs_healed" ) -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> -- CotZ for IWP: Remove "is_prisoner_target" infoportion after task completion. -- -- Author(s) : moonshroom -- Added : 09/01/2025 7:29 pm -- Ver. : Indev 6.6 -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> prisoner_npc:disable_info_portion( "moon_cotz_is_prisoner_target" ) -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> end -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_remove_prisoner function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Removes a prisoner squad -- -- Usage: -- drx_ql_remove_prisoner( p[1] ) -- -- Parameters: -- p[1] (type: string, task id) -- - Name of the task calling this function -- -- Ini requirements: -- drx\drx_ql_config.ltx -- [sim_task_props] -- max_blackscreen_dist (type: float, meters) -- - Max squad distance from actor to show black screen when removing squad -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified November 17, 2019 -- ------------------------------------------------------------------------------------------------ -- Remove prisoner squad: function drx_ql_remove_prisoner( actor, npc, p ) -- Validate input: if ( not p[1] ) then printf( "DRX QL Error: Unable to remove prisoner squad, invalid parameters supplied" ) return end -- Get the prisoner id: local prisoner_id = utils.load_var( db.actor, string.format( "%s_target_id", p[1] ) ) if ( not prisoner_id ) then return end -- Get the prisoner squad: local prisoner_obj = alife( ):object( prisoner_id ) if ( not prisoner_obj ) then return end local squad = get_object_squad( prisoner_obj ) if ( not squad ) then return end -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> -- CotZ for IWP: Player-owned items are automatically given back to the player on dismissal of companions. -- -- Author(s) : moonshroom -- Added : 14/01/2025 9:28 pm -- 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 -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> -- Check if any members of squad are in actor's view: local squad_in_view = false local max_blackscreen_dist = (drx_ql_ini:r_float_ex( "sim_task_props", "max_blackscreen_dist" ) or 0) if ( (squad.dist_to_actor ~= nil) and (squad.dist_to_actor <= max_blackscreen_dist) ) then squad_in_view = true else for member in squad:squad_members( ) do local member_obj = (db.storage[member.id] and db.storage[member.id].object) if ( member_obj and npc_in_actor_frustrum( member_obj ) ) then squad_in_view = true break end end end -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> -- CotZ for IWP: Player-owned items are automatically given back to -- the player on dismissal of companions. -- -- Author(s) : moonshroom -- Added : 14/01/2025 9:28 pm -- Ver. : Indev 6.6 -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> for member in squad:squad_members() do local member_obj = ( db.storage[member.id] and db.storage[member.id].object ) if ( member_obj and member_obj:alive() ) then member_obj:iterate_inventory( return_player_items, member_obj ) end end -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> -- Momentarily show black screen if a squad is in actor view: if ( squad_in_view ) then level.add_pp_effector( "black.ppe", 1313, false ) end -- Remove the squad: SIMBOARD:remove_squad( squad ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_reward_random function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Gives player a random reward of specified value -- -- Usage: -- drx_ql_reward_random( p[1] ) -- -- Parameters: -- p[1] (type: int) -- - Minimum value of the reward -- p[2] (type: int) -- - Maximum value of the reward -- -- Ini requirements: -- drx\drx_ql_config.ltx -- [reward_values] -- money_chance (type: float, decimal percent) -- - Percent chance money will be given as a reward from a reward_random function -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified April 09, 2019 -- ------------------------------------------------------------------------------------------------ -- Give player random reward: function drx_ql_reward_random( actor, npc, p ) -- Validate input: if ( (not p) or (#p < 2) ) then printf( "DRX QL Error: Unable to give random reward, no value range specified" ) return end -- Get the percent chance for money reward: local money_chance = (drx_ql_ini:r_float_ex( "reward_values", "money_chance" ) or 0.5) -- Give player random reward of money or item: if ( (money_chance > 0) and (math.random( ) <= money_chance) ) then drx_ql_reward_money( actor, npc, {p[1], p[2]} ) else drx_ql_reward_item( actor, npc, {p[1], p[2]} ) end -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_reward_money function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Gives player a random money reward within a specified range -- -- Usage: -- drx_ql_reward_money( p[1], p[2] ) -- -- Parameters: -- p[1] (type: int) -- - Minimum value of the reward -- p[2] (type: int) -- - Maximum value of the reward (optional; if ommitted p[1] will be used) -- -- Ini requirements: -- drx\drx_ql_config.ltx -- [reward_values] -- reward_multiplier (type: float, decimal percent) -- - Global multiplier for reward values -- -- Return value (type: nil): -- none -- -- Notes: -- - Values are rounded to the nearest 50 -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified April 09, 2019 -- ------------------------------------------------------------------------------------------------ -- Give player money reward: function drx_ql_reward_money( actor, npc, p ) -- Validate input: if ( (not p) or (not p[1]) ) then printf( "DRX QL Error: Unable to give money reward, no minimum value specified" ) return end -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to give money reward, db.actor not available" ) return end -- Determine range of value: local multiplier = (drx_ql_ini:r_float_ex( "reward_values", "reward_multiplier" ) or 1.0) local min_val = (tonumber( p[1] ) * multiplier) local max_val = ((p[2] and tonumber( p[2] ) or min_val) * multiplier) -- Determine value of money reward and round up to nearest 50: local money = math.random( math.ceil( (min_val / 50) ), math.ceil( (max_val / 50) ) ) money = (money * 50) -- Give actor money reward: dialogs.relocate_money( db.actor, money, "in" ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_take_money function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Takes money from the player -- -- Usage: -- drx_ql_take_money( p[1] ) -- -- Parameters: -- p[1] (type: int) -- - Amount of money to take from the actor -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified December 06, 2017 -- ------------------------------------------------------------------------------------------------ -- Take money from player: function drx_ql_take_money( actor, npc, p ) -- Validate input: if ( (not p) or (not p[1]) ) then return end -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to take money from actor, db.actor not available" ) return end -- Take money from actor: dialogs.relocate_money( db.actor, tonumber( p[1] ), "out" ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_reward_item function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Gives player a random item reward within a specified value range -- -- Usage: -- drx_ql_reward_item( p[1], p[2], p[3], ... ) -- -- Parameters: -- p[1] (type: int) -- - Minimum value of the reward -- p[2] (type: int) -- - Maximum value of the reward (optional; if ommitted p[1] will be used) -- p[3], ... (type: string, section names) -- - List of section names from drx_ql_items.ltx to pull reward items from (optional; if ommitted all reward sections will be included) -- -- Persistent storage: -- {task_id}_fetch (type: object id) -- - Id of requested items for fetch task -- -- Ini requirements: -- drx\drx_ql_config.ltx -- [reward_values] -- reward_multiplier (type: float, decimal percent) -- - Global multiplier for reward values -- cost_multiplier (type: float, decimal percent) -- - Multiplier to use on base cost of items when determining item value as a reward -- [reward_item_sections] (type: string, section names) -- - List of sections to include from drx_ql_items.ltx as rewards -- drx\drx_ql_items.ltx -- [{section_name}] -- {item_section_name} = {cost} -- - List of item section names to use as reward items and their base costs -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified April 09, 2019 -- ------------------------------------------------------------------------------------------------ -- Give player item reward: function drx_ql_reward_item( actor, npc, p ) -- Validate input: if ( (not p) or (not p[1]) ) then printf( "DRX QL Error: Could not select reward item, no minimum value specified" ) return end -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Could not select reward item, db.actor not available" ) return end -- Get the location of the items config file: local drx_ql_items_ini = ini_file( "drx\\drx_ql_items.ltx" ) if ( not drx_ql_items_ini ) then printf( "DRX QL Error: Could not select reward item, items config file not found" ) return end -- Get the cost multiplier for item value: local cost_multiplier = drx_ql_ini:r_float_ex( "reward_values", "cost_multiplier" ) if ( not cost_multiplier ) then printf( "DRX QL Error: Could not select reward item, cost multiplier value not specified" ) return end -- Determine range of values: local multiplier = (drx_ql_ini:r_float_ex( "reward_values", "reward_multiplier" ) or 1.0) local min_val = (tonumber( p[1] ) * multiplier) local max_val = ((p[2] and tonumber( p[2] ) or min_val) * multiplier) -- Reward sections to use from the items config file: local reward_sections = alun_utils.collect_section( drx_ql_ini, "reward_item_sections" ) -- Pick rewards from appropriate sections: local rewards_list = {} for i = 1, ( #reward_sections ) do -- Get the current section name: local current_section = reward_sections[i] -- Determine if current section should be included: local include_current_section = false if ( (#p < 3) or (not p[3]) or (p[3] == "") ) then include_current_section = true else for j = 3, ( #p ) do if ( current_section == p[j] ) then include_current_section = true break end end end -- Add eligible items from the current section to the reward list: if ( include_current_section ) then local items_list = alun_utils.collect_section( drx_ql_items_ini, current_section ) for k = 1, ( #items_list ) do -- Get the current item: local current_item = items_list[k] local item_cost = drx_ql_items_ini:r_float_ex( current_section, current_item ) local item_value = (item_cost * cost_multiplier) -- Determine if current item should be added to rewards list: if ( (item_value >= min_val) and (item_value <= max_val) ) then -- table.insert( rewards_list, current_item ) rewards_list[#rewards_list + 1] = current_item end end end end -- Select reward item: if ( #rewards_list < 1 ) then printf( "DRX QL Error: Could not select reward item, no items available in the specified value range, money given instead" ) drx_ql_reward_money( actor, npc, {p[1], p[2]} ) return end local reward_item = rewards_list[math.random( #rewards_list )] -- If the player is on high value fetch item task use eligible havfetch item as reward: local havfetch_items_list = {} if ( (drx_ql_task_funcs.drx_ql_havfetch_tasks) and (#drx_ql_task_funcs.drx_ql_havfetch_tasks > 0) ) then for r = 1, ( #drx_ql_task_funcs.drx_ql_havfetch_tasks ) do local current_task = drx_ql_task_funcs.drx_ql_havfetch_tasks[r] local task_info = task_manager.get_task_manager( ).task_info[current_task] if ( task_info ) then if ( task_info.stage < 2 ) then local havfetch_item = utils.load_var( db.actor, string.format( "%s_fetch", current_task ) ) if ( havfetch_item ) then for s = 1, ( #rewards_list ) do if ( havfetch_item == rewards_list[s] ) then -- table.insert( havfetch_items_list, havfetch_item ) havfetch_items_list[#havfetch_items_list + 1] = havfetch_item end end end end end end end if ( #havfetch_items_list > 0 ) then reward_item = havfetch_items_list[math.random( #havfetch_items_list )] end -- Give actor item reward: dialogs.relocate_item_section( db.actor, reward_item, "in" ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_fetch_reward_random function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Removes fetch items from player and gives player a random reward of equivalent value -- -- Usage: -- drx_ql_fetch_reward_random( p[1], p[2] ) -- -- Parameters: -- p[1] (type: string, task section name) -- - Name of the task requiring the reward -- p[2] (type: float) -- - Multiplier to apply to fetch item base cost when determining reward value -- -- Persistent storage: -- {task_id}_fetch (type: item section name) -- - Fetch quest item for specified task -- {task_id}_fetch_count (type: int) -- - Number of fetch quest items for specified task -- -- Ini requirements: -- drx\drx_ql_config.ltx -- [reward_values] -- reward_delta (type: float, decimal percent) -- - Percent offset from item value to use for reward value range -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified April 09, 2019 -- ------------------------------------------------------------------------------------------------ -- Give player random reward: function drx_ql_fetch_reward_random( actor, npc, p ) -- Validate input: if ( (not p) or (#p < 1) or (not p[1]) or (p[1] == "") ) then printf( "DRX QL Error: Unable to give random fetch reward, no fetch task specified" ) return end -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to give random fetch reward, db.actor not available" ) return end -- Get fetch item: local fetch_item = utils.load_var( db.actor, string.format( "%s_fetch", p[1] ) ) if ( not fetch_item ) then return end local item_obj = db.actor:object( fetch_item ) if not ( item_obj ) then return end -- Get fetch item count: local fetch_count = utils.load_var( db.actor, string.format( "%s_fetch_count", p[1] ), 1 ) -- Determine reward value range: local fetch_value = math.floor( ((item_obj:cost( ) * (tonumber( p[2] ) or 1)) * fetch_count) ) local delta = math.floor( (fetch_value * (drx_ql_ini:r_float_ex( "reward_values", "reward_delta" ) or 0)) ) local min_value = (fetch_value - delta) local max_value = (fetch_value + delta) -- Give actor random reward: drx_ql_reward_random( actor, npc, {min_value, max_value} ) -- Remove fetch task items: remove_item( actor, npc, {fetch_item, fetch_count} ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_fetch_reward_money function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Removes fetch items from player and gives player a money reward of equivalent value -- -- Usage: -- drx_ql_fetch_reward_money( p[1], p[2] ) -- -- Parameters: -- p[1] (type: string, task section name) -- - Name of the task requiring the reward -- p[2] (type: float) -- - Multiplier to apply to fetch item base cost when determining reward value -- -- Persistent storage: -- {task_id}_fetch (type: item section name) -- - Fetch quest item for specified task -- {task_id}_fetch_count (type: int) -- - Number of fetch quest items for specified task -- -- Ini requirements: -- drx\drx_ql_config.ltx -- [reward_values] -- reward_delta (type: float, decimal percent) -- - Percent offset from item value to use for reward value range -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified April 09, 2019 -- ------------------------------------------------------------------------------------------------ -- Give player money reward: function drx_ql_fetch_reward_money( actor, npc, p ) -- Validate input: if ( (not p) or (#p < 1) or (not p[1]) or (p[1] == "") ) then printf( "DRX QL Error: Unable to give money fetch reward, no fetch task specified" ) return end -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to give money fetch reward, db.actor not available" ) return end -- Get fetch item: local fetch_item = utils.load_var( db.actor, string.format( "%s_fetch", p[1] ) ) if ( not fetch_item ) then return end local item_obj = db.actor:object( fetch_item ) if not ( item_obj ) then return end -- Get fetch item count: local fetch_count = utils.load_var( db.actor, string.format( "%s_fetch_count", p[1] ), 1 ) -- Determine reward value range: local fetch_value = math.floor( ((item_obj:cost( ) * (tonumber( p[2] ) or 1)) * fetch_count) ) local delta = math.floor( (fetch_value * (drx_ql_ini:r_float_ex( "reward_values", "reward_delta" ) or 0)) ) local min_value = (fetch_value - delta) local max_value = (fetch_value + delta) -- Give actor money reward: drx_ql_reward_money( actor, npc, {min_value, max_value} ) -- Remove fetch task items: remove_item( actor, npc, {fetch_item, fetch_count} ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_fetch_reward_item function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Removes fetch items from player and gives player an item reward of equivalent value -- -- Usage: -- drx_ql_fetch_reward_item( p[1], p[2], p[3], ... ) -- -- Parameters: -- p[1] (type: string, task section name) -- - Name of the task requiring the reward -- p[2] (type: float) -- - Multiplier to apply to fetch item base cost when determining reward value -- p[3], ... (type: string, section names) -- - Sections in the drx_ql_items.ltx file to include as reward items (optional; if ommitted all reward sections will be used) -- -- Persistent storage: -- {task_id}_fetch (type: item section name) -- - Fetch quest item for specified task -- {task_id}_fetch_count (type: int) -- - Number of fetch quest items for specified task -- -- Ini requirements: -- drx\drx_ql_config.ltx -- [reward_values] -- reward_delta (type: float, decimal percent) -- - Percent offset from item value to use for reward value range -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified April 09, 2019 -- ------------------------------------------------------------------------------------------------ -- Give player item reward: function drx_ql_fetch_reward_item( actor, npc, p ) -- Validate input: if ( (not p) or (#p < 1) or (not p[1]) or (p[1] == "") ) then printf( "DRX QL Error: Unable to give item fetch reward, no fetch task specified" ) return end -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to give money fetch reward, db.actor not available" ) return end -- Get fetch item: local fetch_item = utils.load_var( db.actor, string.format( "%s_fetch", p[1] ) ) if ( not fetch_item ) then return end local item_obj = db.actor:object( fetch_item ) if not ( item_obj ) then return end -- Get fetch item count: local fetch_count = utils.load_var( db.actor, string.format( "%s_fetch_count", p[1] ), 1 ) -- Determine reward value range: local fetch_value = math.floor( ((item_obj:cost( ) * (tonumber( p[2] ) or 1)) * fetch_count) ) local delta = math.floor( (fetch_value * (drx_ql_ini:r_float_ex( "reward_values", "reward_delta" ) or 0)) ) local min_value = (fetch_value - delta) local max_value = (fetch_value + delta) -- Give actor item reward: local params_array = {min_value, max_value} for i = 3, ( #p ) do -- table.insert( params_array, p[i] ) params_array[#params_array + 1] = p[i] end drx_ql_reward_item( actor, npc, params_array ) -- Remove fetch task items: remove_item( actor, npc, {fetch_item, fetch_count} ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_reward_stash function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Randomly gives actor stash location -- -- Usage: -- drx_ql_reward_stash( p[1], p[2], ... ) -- -- Parameters: -- p[1] (type: float, decimal percent) -- - Percent chance to give reward stash (optional; if ommitted stash_chance value from config file will be used) -- p[2], ... (type: string, section names) -- - Additional items to include in the stash (optional) -- -- Ini requirements: -- drx\drx_ql_config.ltx -- [reward_values] -- stash_chance (type: float, decimal percent) -- - Percent chance a stash will be rewarded on task completion -- toolkit_chance (type: float, decimal percent) -- - Percent chance a mechanic toolkit will be included in a reward stash -- bonus_min_cost (type: int) -- - Stash bonus item minimum cost -- bonus_max_cost (type: int) -- - Stash bonus item maximum cost -- bonus_min_spread (type: float, decimal percent) -- - Stash bonus item minimum cost spread between minimum cost and maximum cost -- bonus_max_items (type: int) -- - Stash bonus maximum item count -- bonus_exp (type: float) -- - Exponent for calculating stash bonus item max value -- bonus_item_chance (type: float) -- - Percent chance for each bonus item -- [reward_item_sections] (type" string, reward item section names) -- - Sections to include from drx_ql_items.ltx as reward items -- drx\drx_ql_items.ltx -- [{section_name}] -- {item_section_name} = {cost} -- - List of item section names to use as reward items and their base costs -- -- Return value (type: obj id): -- - Returns the id of the stash -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified April 09, 2019 -- ------------------------------------------------------------------------------------------------ -- Give actor stash location: function drx_ql_reward_stash( actor, npc, p ) -- Get the location of the items config file: local drx_ql_items_ini = ini_file( "drx\\drx_ql_items.ltx" ) if ( not drx_ql_items_ini ) then printf( "DRX QL Error: Unable to give reward stash, items config file not found" ) return end -- Get the percent chance to reward stash: local stash_chance = (drx_ql_ini:r_float_ex( "reward_values", "stash_chance" ) or 1) if ( (p) and (p[1] ~= nil) ) then stash_chance = p[1] end -- Check if stash should be awarded: if ( (stash_chance == 0) or (math.random( ) > stash_chance) ) then return end -- Reward sections to use from the items config file: local reward_sections = alun_utils.collect_section( drx_ql_ini, "reward_item_sections" ) -- Get the minimum bonus item cost: local bonus_min_cost = (drx_ql_ini:r_float_ex( "reward_values", "bonus_min_cost" ) or 0) -- Get the maximum bonus item cost: local bonus_max_cost = (drx_ql_ini:r_float_ex( "reward_values", "bonus_max_cost" ) or 0) -- Get the minimum bonus item cost spread: local bonus_min_spread = (drx_ql_ini:r_float_ex( "reward_values", "bonus_min_spread" ) or 0) -- Get the maximum number of bonus items: local bonus_max_items = (drx_ql_ini:r_float_ex( "reward_values", "bonus_max_items" ) or 1) -- Get the bonus exponent to use for calculating max value: local bonus_exp = (drx_ql_ini:r_float_ex( "reward_values", "bonus_exp" ) or 1) -- Get the percent chance for each bonus item: local bonus_item_chance = (drx_ql_ini:r_float_ex( "reward_values", "bonus_item_chance" ) or 1) -- Add parameter items to bonus list: local bonus_list = {} if ( (p) and (#p > 1) ) then for n = 2, ( #p ) do -- table.insert( bonus_list, p[n] ) bonus_list[#bonus_list + 1] = p[n] end end -- Add stash bonus items: local percent_chance = 1 for m = 1, ( bonus_max_items ) do -- Add new item to stash: if ( (percent_chance > 0) and (math.random( ) <= percent_chance) ) then -- Generate max cost for current iteration: local max_cost = (bonus_min_cost + math.ceil( (bonus_min_cost * bonus_min_spread) )) if ( max_cost > bonus_max_cost ) then max_cost = bonus_max_cost end local delta = (bonus_max_cost - max_cost) if ( delta > 0 ) then max_cost = (max_cost + math.ceil( (delta * ((math.random( delta ) ^ bonus_exp) / (delta ^ bonus_exp))) )) end -- Pick bonus from appropriate sections: local rewards_list = {} for i = 1, ( #reward_sections ) do -- Get the current section name: local current_section = reward_sections[i] -- Add eligible items from the current section to the reward list: local items_list = alun_utils.collect_section( drx_ql_items_ini, current_section ) for k = 1, ( #items_list ) do -- Get the current item: local current_item = items_list[k] local item_cost = drx_ql_items_ini:r_float_ex( current_section, current_item ) -- Determine if current item should be added to rewards list: if ( (item_cost >= bonus_min_cost) and (item_cost <= max_cost) ) then -- table.insert( rewards_list, current_item ) rewards_list[#rewards_list + 1] = current_item end end end -- Select bonus item and update percent chance after adding first item to ensure at least one item is generated: if ( #rewards_list > 0 ) then -- table.insert( bonus_list, rewards_list[math.random( #rewards_list )] ) bonus_list[#bonus_list + 1] = rewards_list[math.random( #rewards_list )] percent_chance = bonus_item_chance end end end -- Get the percent chance to include a mechanic toolkit: local toolkit_chance = (drx_ql_ini:r_float_ex( "reward_values", "toolkit_chance" ) or 0) -- Randomly add toolkit to stash: if ( (toolkit_chance > 0) and (math.random( ) <= toolkit_chance) ) then -- table.insert( bonus_list, string.format( "itm_repairkit_tier_%s", math.random( 3 ) ) ) bonus_list[#bonus_list + 1] = string.format( "itm_repairkit_tier_%s", math.random( 3 ) ) end -- Create the stash: local stash_id = coc_treasure_manager.create_random_stash( nil, nil, bonus_list ) -- Set return value: return stash_id end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_reward_psi_helmet function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Gives the player a good psi helmet -- -- Usage: -- drx_ql_reward_psi_helmet( ) -- -- Parameters: -- none -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified September 27, 2019 -- ------------------------------------------------------------------------------------------------ -- Give actor good psi helmet: function drx_ql_reward_psi_helmet( actor, npc, p ) -- Give actor psi helmet: give_actor( actor, npc, {"good_psy_helmet"} ) give_info( "drx_ql_actor_has_psi_helmet" ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- Variables used for: -- moon_cotz_reenable_quest_stash -- drx_ql_create_quest_stash local moon_created_stash_items -- (type: string) : Holds the items of the quest stash. local moon_created_stash_id -- (type: object id) : Holds the ID of the quest stash. -- ===================================================================== -- Function Name: -- moon_cotz_reenable_quest_stash -- -- Description: -- function used to reinstate the -- removed quest stash from modified -- drx_ql_create_quest_stash() -- -- Usage: -- moon_cotz_reenable_quest_stash() -- -- Parameters: -- N/A -- -- Persistent Storage: -- N/A -- -- Return Value: -- N/A -- ===================================================================== -- Call of the Zone for IWP -- Indev 2 -- -- Authors: moonshroom -- Last modified: Jun 3, 2024, 12:50 PM -- ===================================================================== function moon_cotz_reenable_quest_stash(actor, npc, p) -- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -- VERIFICATION CHECKS -- Ensure player exists. if (not db.actor) then printf("CotZ for IWP | xr_effects.script | moon_cotz_reenable_quest_stash() | ERR: db.actor does not exist.") return false end -- Ensure the quest stash ID was saved. if (not moon_created_stash_id) then printf("CotZ for IWP | xr_effects.script | moon_cotz_reenable_quest_stash() | ERR: moon_created_stash_id contains no stash ID.") return false end -- Ensure the items within the quest stash were saved. if (not moon_created_stash_items) then printf("CotZ for IWP | xr_effects.script | moon_cotz_reenable_quest_stash() | ERR: moon_created_stash_items contains no stash items.") return false end -- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// coc_treasure_manager.caches[moon_created_stash_id] = moon_created_stash_items -- Give items back to the quest stash. level.map_add_object_spot_ser(moon_created_stash_id, "treasure", "") -- Add the stash map spot back. -- Set variables back to nil. moon_created_stash_items = nil moon_created_stash_id = nil -- printf("CotZ for IWP | xr_effects.script | moon_cotz_reenable_quest_stash() | DBG: caches[moon_created_stash_id] = %s", moon_created_stash_items) return -- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// end -- ===================================================================== -- Function Name: -- drx_ql_create_quest_stash -- -- Description: -- modified function of the original one -- by DoctorX to allow the location -- of the quest stash to be shown -- in the dialog box prior to accepting task -- -- Usage: -- drx_ql_create_quest_stash(p[1], p[2]) -- -- Parameters: -- p[1] (type: string, section name) -- - Quest item to spawn in the stash. -- p[2] (type: string, task section name) -- - Name of the task calling this function. -- -- Persistent Storage: -- {quest_item}_stash_id (type: obj id) -- - ID of the stash containing the quest item. -- -- Return Value: -- N/A -- -- Notes: -- - This code is very icky. But for now, it works. -- - Created quest stashes are made empty in case player -- decides to not take the task. Their ID and list of -- items are saved in variables to be used for re-enabling -- the stash if the player decides to accept the task. -- - Quest stashes are not memorized. It rerolls everytime -- the player asks for a stash task even if it's the same task -- from the same NPC. -- ===================================================================== -- Call of the Zone for IWP -- Indev 2 -- -- Authors: DoctorX, moonshroom -- Last modified: Jul 3, 2024, 12:51 PM -- ===================================================================== function drx_ql_create_quest_stash( actor, npc, p ) -- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -- VERIFICATION CHECKS -- Ensure parameters were correctly given. if ( (not p) or (#p < 2) ) then printf("CotZ for IWP | xr_effects.script | drx_ql_create_quest_stash() | ERR: Invalid parameters given.") return false end -- Ensure player exists. if ( not db.actor ) then printf("CotZ for IWP | xr_effects.script | drx_ql_create_quest_stash() | ERR: db.actor does not exist.") return false end -- Ensure player is talking to someone. local npc_id = utils.load_var( db.actor, "drx_ql_current_npc_speaker_id", nil ) if ( npc_id == nil ) then printf("CotZ for IWP | xr_effects.script | drx_ql_create_quest_stash() | ERR: Could not find ID of currently speaking NPC.") return false end -- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// local item_name = system_ini():r_string_ex(p[1], "inv_name") or nil -- Create the stash. local stash_id = drx_ql_reward_stash(actor, npc, {1, p[1]}) if ( not stash_id ) then printf("CotZ for IWP | xr_effects.script | drx_ql_create_quest_stash() | ERR: Stash creation failed.") return false end moon_created_stash_id = stash_id -- Save the stash ID so it can be reenabled if the player chooses to accept it. moon_created_stash_items = coc_treasure_manager.caches[stash_id] -- Save the items in the stash above. -- Save the stash ID. utils.save_var(db.actor, string.format("%s_stash_id", p[1]), stash_id) -- Disable the stash for now. coc_treasure_manager.caches[stash_id] = false -- Remove items from the stash / set stash to empty. level.map_remove_object_spot(stash_id, "treasure") -- Remove all possible stash spots from the stash. -- level.map_remove_object_spot(stash_id, "treasure_player") -- level.map_remove_object_spot(stash_id, "treasure_searched") -- level.map_remove_object_spot(stash_id, "treasure_unique") -- Show task information on the dialog box. local function postpone_for_next_frame( stash_id ) local se_obj = alife( ):object( stash_id ) if ( se_obj ) then local news_caption = game.translate_string( task_manager.task_ini:r_string_ex( p[2], "title" ) ) local news_text = string.format( "%s %s\\n %s %s", game.translate_string("st_desired_item"), game.translate_string(item_name), game.translate_string( "st_location" ), game.translate_string(alife():level_name(game_graph():vertex(se_obj.m_game_vertex_id):level_id()))) db.actor:give_talk_message2( news_caption, news_text, task_manager.task_ini:r_string_ex( p[2], "icon" ), "iconed_answer_item" ) end return true end -- Create time event for displaying task information CreateTimeEvent( 0, "drx_ql_create_quest_stash", 0, postpone_for_next_frame, stash_id ) -- Set return value return -- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// end -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_create_quest_stash function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Spawns a quest item in a random available stash location -- -- Usage: -- drx_ql_create_quest_stash( p[1] ) -- -- Parameters: -- p[1] (type: string, section name) -- - Quest item to spawn in the stash -- -- Persistent storage: -- {quest_item}_stash_id (type: obj id) -- - Id of the stash containing the quest item -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Modified by DoctorX -- for DoctorX Questlines 2.0 -- Last modified January 30, 2018 -- ------------------------------------------------------------------------------------------------ -- Create quest stash: -- function drx_ql_create_quest_stash( actor, npc, p ) -- -- -- Verify db.actor is available: -- if ( not db.actor ) then -- printf( "DRX QL Error: Unable to create quest stash, db.actor not available" ) -- return -- end -- -- -- Create the stash: -- local stash_id = drx_ql_reward_stash( actor, npc, {1, p[1]} ) -- if ( not stash_id ) then -- printf( "DRX QL Error: Unable to create quest stash" ) -- end -- -- -- Save the stash id: -- utils.save_var( db.actor, string.format( "%s_stash_id", p[1] ), stash_id ) -- -- -- Set return value: -- return -- -- end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_remove_quest_stash function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Removes a previously spawned quest stash -- -- Usage: -- drx_ql_remove_quest_stash( p[1] ) -- -- Parameters: -- p[1] (type: string, section name) -- - Quest item spawned in the stash -- -- Persistent storage: -- {quest_item}_stash_id (type: obj id) -- - Id of the stash containing the quest item -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Modified by DoctorX -- for DoctorX Questlines 2.0 -- Last modified August 31, 2018 -- ------------------------------------------------------------------------------------------------ -- Remove quest stash: function drx_ql_remove_quest_stash( actor, npc, p ) -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to remove quest stash, db.actor not available" ) return end -- Empty the quest stash: local stash_id = utils.load_var( db.actor, string.format( "%s_stash_id", p[1] ) ) if ( stash_id ) then coc_treasure_manager.caches[stash_id] = false level.map_remove_object_spot( stash_id, "treasure" ) level.map_remove_object_spot( stash_id, "treasure_player" ) level.map_remove_object_spot( stash_id, "treasure_searched" ) level.map_remove_object_spot( stash_id, "treasure_unique" ) end -- Remove the quest item from the actor: remove_item( actor, npc, {p[1]} ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_setup_fetch_task function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Sets up a fetch task -- - Modification of setup_generic_fetch_task (CoC 1.5b r4) -- -- Usage: -- drx_ql_setup_fetch_task( p[1], p[2], p[3], p[4], p[5], p[6], p[7], ... ) -- -- Parameters: -- p[1] (type: string, task section name) -- - Name of the task -- p[2] (type: int) -- - Minimum total cost of the fetch items -- p[3] (type: int) -- - Maximum total cost of the fetch items -- p[4] (type: int) -- - Minimum count of fetch items to get -- p[5] (type: int) -- - Maximum count of fetch items to get -- p[6] (type: float, decimal percent) -- - Minimum condition of fetch items -- p[7], ... (type: string, section names) -- - Sections in the drx_ql_items.ltx file to include as fetch items -- -- Persistent storage: -- {task_id}_fetch (type: item section name) -- - Fetch quest item for specified task -- {task_id}_fetch_count (type: int) -- - Number of fetch quest items for specified task -- {task_id}_fetch_cond (type: float, decimal percent) -- - Minimum acceptable condition of the fetch items -- -- Ini requirements: -- drx\drx_ql_items.ltx -- [{section_name}] -- {item_section_name} = {cost} -- - List of item section names to use as fetch items and their base costs -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified August 24, 2018 -- ------------------------------------------------------------------------------------------------ -- Setup fetch task: function drx_ql_setup_fetch_task( actor, npc, p ) -- Validate input: if ( (not p) or (#p < 7) ) then printf( "DRX QL Error: Unable to setup fetch task, invalid parameters supplied" ) return end -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to setup fetch task, db.actor not available" ) return end -- Get saved fetch item: local fetch_item = ((DIALOG_LAST_ID) and (DIALOG_LAST_ID == inventory_upgrades.victim_id) and (utils.load_var( db.actor, string.format( "%s_fetch", p[1] ) ))) local fetch_count = utils.load_var( db.actor, string.format( "%s_fetch_count", p[1] ) ) DIALOG_LAST_ID = inventory_upgrades.victim_id -- If a saved fetch item exists then use it: if ( (fetch_item) and (system_ini( ):section_exist( fetch_item )) ) then dialogs._FETCH_TEXT = game.translate_string( system_ini():r_string_ex( fetch_item, "inv_name" ) or "" ) dialogs._FETCH_COUNT = fetch_count return end -- Get the location of the items config file: local drx_ql_items_ini = ini_file( "drx\\drx_ql_items.ltx" ) if ( not drx_ql_items_ini ) then printf( "DRX QL Error: Unable to setup fetch task, items config file not found" ) return end -- Select fetch item: local min_val = tonumber( p[2] ) local max_val = tonumber( p[3] ) local min_count = tonumber( p[4] ) local max_count = tonumber( p[5] ) local fetch_items_list = {} for i = 7, ( #p ) do -- Get the current section name: local current_section = p[i] -- Add eligible items from the current section to the fetch list: local items_list = alun_utils.collect_section( drx_ql_items_ini, current_section ) for k = 1, ( #items_list ) do -- Get the current item and cost: local current_item = items_list[k] local item_cost = drx_ql_items_ini:r_float_ex( current_section, current_item ) -- Determine if current item should be added to fetch list: if ( ((item_cost * max_count) >= min_val) and ((item_cost * min_count) <= max_val) ) then -- table.insert( fetch_items_list, {current_item, item_cost} ) fetch_items_list[#fetch_items_list + 1] = {current_item, item_cost} end end end -- Ensure at least one item was added to the list: if ( #fetch_items_list < 1 ) then printf( "DRX QL Error: Unable to setup fetch task, no items available in the specified value range" ) return end -- Select random item from the list: local fetch_pair = fetch_items_list[math.random( #fetch_items_list )] if ( (not fetch_pair) or (#fetch_pair < 2) ) then printf( "DRX QL Error: Unable to setup fetch task, fetch pair picked is not valid" ) return end fetch_item = fetch_pair[1] local fetch_item_cost = fetch_pair[2] if ( (not fetch_item_cost) or (not fetch_item) or (not system_ini( ):section_exist( fetch_item )) ) then printf( "DRX QL Error: Unable to setup fetch task, invalid fetch item selected" ) return end utils.save_var( db.actor, string.format( "%s_fetch", p[1] ), fetch_item ) -- Set the count of items to get: local new_min_count = math.ceil( (min_val / fetch_item_cost) ) if ( new_min_count > min_count ) then min_count = new_min_count end local new_max_count = math.floor( (max_val / fetch_item_cost) ) if ( new_max_count < max_count ) then max_count = new_max_count end local count = math.random( min_count, max_count ) utils.save_var( db.actor, string.format( "%s_fetch_count", p[1] ), count ) -- Set the minimum fetch item condition: utils.save_var( db.actor, string.format( "%s_fetch_cond", p[1] ), p[6] ) -- Set the fetch text: dialogs._FETCH_TEXT = game.translate_string( ( system_ini( ):r_string_ex( fetch_item, "inv_name" ) or "" ) ) dialogs._FETCH_COUNT = count -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_setup_swap_task function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Sets up a swap item task -- -- Usage: -- drx_ql_setup_swap_task( p[1], p[2], p[3], p[4] ) -- -- Parameters: -- p[1] (type: string, task name) -- - Name of the task calling this function -- p[2] (type: int, RU) -- - Minimum cost value of the swap items -- p[3] (type: int, RU) -- - Maximum cost value of the swap items -- p[4] (type: float, decimal percent) -- - Minimum acceptable condition of the fetch item -- -- Persistent storage: -- {task_id}_fetch (type: object id) -- - Id of requested items for fetch task -- {task_id}_fetch_count (type: int) -- - Number of fetch quest items for specified task -- {task_id}_fetch_cond (type: float, decimal percent) -- - Minimum acceptable condition of the fetch items -- {task_id}_reward (type: object id) -- - Name of task reward item -- -- Ini requirements: -- drx\drx_ql_config.ltx -- [reward_item_sections] (type" string, reward item section names) -- - Sections to include from drx_ql_items.ltx as reward items -- drx\drx_ql_items.ltx -- [{section_name}] -- {item_section_name} = {cost} -- - List of item section names to use as reward items and their base costs -- -- Return value (type: nil): -- none -- -- Notes: -- - If the player is on a havfetch task the havfetch item will be offered as the reward -- - Reward item is stored in in pstor var {p[1]}_reward -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified April 09, 2019 -- ------------------------------------------------------------------------------------------------ -- Setup a swap item task: function drx_ql_setup_swap_task( actor, npc, p ) -- Validate input: if ( (not p) or (#p < 4) ) then printf( "DRX QL Error: Unable to setup swap item task, invalid parameters supplied" ) return end -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to setup swap item task, db.actor not available" ) return end -- Get saved fetch item: local fetch_item = ((DIALOG_LAST_ID) and (DIALOG_LAST_ID == inventory_upgrades.victim_id) and (utils.load_var( db.actor, string.format( "%s_fetch", p[1] ) ))) DIALOG_LAST_ID = inventory_upgrades.victim_id -- If a saved fetch item exists then use it: if ( (fetch_item) and (system_ini( ):section_exist( fetch_item )) ) then dialogs._FETCH_TEXT = (game.translate_string( system_ini( ):r_string_ex( fetch_item, "inv_name" ) or "" )) dialogs._FETCH_COUNT = 1 return end -- Get the location of the items config file: local drx_ql_items_ini = ini_file( "drx\\drx_ql_items.ltx" ) if ( not drx_ql_items_ini ) then printf( "DRX QL Error: Unable to setup swap item task, items config file not found" ) return end -- Reset stored task reward: utils.save_var( db.actor, string.format( "%s_reward", p[1] ), nil ) local task_reward = nil -- Check if the player is on a high value fetch item task: if ( (drx_ql_task_funcs.drx_ql_havfetch_tasks) and (#drx_ql_task_funcs.drx_ql_havfetch_tasks > 0) ) then -- Build a list of valid havfetch items: local havfetch_items_list = {} for i = 1, ( #drx_ql_task_funcs.drx_ql_havfetch_tasks ) do local current_task = drx_ql_task_funcs.drx_ql_havfetch_tasks[i] local task_info = task_manager.get_task_manager( ).task_info[current_task] if ( task_info ) then if ( task_info.stage < 2 ) then local havfetch_item = utils.load_var( db.actor, string.format( "%s_fetch", current_task ) ) if ( havfetch_item ) then -- table.insert( havfetch_items_list, havfetch_item ) havfetch_items_list[#havfetch_items_list + 1] = havfetch_item end end end end -- Select random item from the list: if ( #havfetch_items_list > 0 ) then task_reward = havfetch_items_list[math.random( #havfetch_items_list )] end end -- If no havfetch items then determine reward item: local reward_sections = alun_utils.collect_section( drx_ql_ini, "reward_item_sections" ) if ( not task_reward ) then -- Select reward item: local rewards_list = {} for j = 1, ( #reward_sections ) do -- Add eligible items from the current section to the reward list: local current_section = reward_sections[j] local items_list = alun_utils.collect_section( drx_ql_items_ini, current_section ) for k = 1, ( #items_list ) do -- Determine if current item should be added to rewards list: local current_item = items_list[k] local item_cost = drx_ql_items_ini:r_float_ex( current_section, current_item ) if ( (item_cost >= tonumber( p[2] )) and (item_cost <= tonumber( p[3] )) ) then -- table.insert( rewards_list, current_item ) rewards_list[#rewards_list + 1] = current_item end end end -- Select random item from the list: if ( #rewards_list > 0 ) then task_reward = rewards_list[math.random( #rewards_list )] end end -- Ensure a reward item was determined: if ( not task_reward ) then printf( "DRX QL Error: Unable to setup swap item task, could not determine task reward" ) return end -- Get the cost of the reward item: local reward_cost = 0 for m = 1, ( #reward_sections ) do local current_section = reward_sections[m] local items_list = alun_utils.collect_section( drx_ql_items_ini, current_section ) for n = 1, ( #items_list ) do -- Determine if current item is the reward item: local current_item = items_list[n] if ( current_item == task_reward ) then reward_cost = drx_ql_items_ini:r_float_ex( current_section, current_item ) break end end -- Check if cost was found: if ( reward_cost > 0 ) then break end end -- Get cost range for fetch item: local delta = math.floor( (reward_cost * (drx_ql_ini:r_float_ex( "reward_values", "reward_delta" ) or 0)) ) local fetch_min_value = (reward_cost - delta) local fetch_max_value = (reward_cost + delta) -- Determine a fetch item to swap: local fetch_items_list = {} for s = 1, ( #reward_sections ) do -- Get the current section name: local current_section = reward_sections[s] -- Add eligible items from the current section to the fetch list: local items_list = alun_utils.collect_section( drx_ql_items_ini, current_section ) for t = 1, ( #items_list ) do -- Get the current item and cost: local current_item = items_list[t] local item_cost = drx_ql_items_ini:r_float_ex( current_section, current_item ) -- Determine if current item should be added to fetch list: if ( (current_item ~= task_reward) and (item_cost >= fetch_min_value) and (item_cost <= fetch_max_value) ) then -- table.insert( fetch_items_list, current_item ) fetch_items_list[#fetch_items_list + 1] = current_item end end end -- Ensure at least one item was added to the list: if ( #fetch_items_list < 1 ) then printf( "DRX QL Error: Unable to setup swap item task, no items available in the specified value range" ) return end -- Select random item from the list: local fetch_item = fetch_items_list[math.random( #fetch_items_list )] if ( (not fetch_item) or (not system_ini( ):section_exist( fetch_item )) ) then printf( "DRX QL Error: Unable to setup swap item task, invalid fetch item selected" ) return end -- Save task vars: utils.save_var( db.actor, string.format( "%s_fetch", p[1] ), fetch_item ) utils.save_var( db.actor, string.format( "%s_fetch_count", p[1] ), 1 ) utils.save_var( db.actor, string.format( "%s_fetch_cond", p[1] ), p[4] ) utils.save_var( db.actor, string.format( "%s_reward", p[1] ), task_reward ) dialogs._FETCH_TEXT = game.translate_string( (system_ini( ):r_string_ex( fetch_item, "inv_name" ) or "") ) dialogs._FETCH_COUNT = 1 -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_save_pstor_ctime function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Saves a timestamp at the current time -- -- Usage: -- drx_ql_save_pstor_ctime( p[1] ) -- -- Parameters: -- p[1] (type: string) -- - Var name to use for the stored timestamp -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified December 23, 2017 -- ------------------------------------------------------------------------------------------------ -- Save current timestamp: function drx_ql_save_pstor_ctime( actor, npc, p ) -- Validate input: if ( (not p) or (not p[1]) ) then printf( "DRX QL Error: Unable to save ctime, invalid parameters supplied" ) return end -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to save ctime, db.actor not available" ) return end -- Save the current timestamp: utils.save_ctime( db.actor, p[1], game.get_game_time( ) ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_add_havfetch_task function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Designates a fetch task as a high value fetch item task -- -- Usage: -- drx_ql_add_havfetch_task( p[1] ) -- -- Parameters: -- p[1] (type: string, task name) -- - Name of the fetch task to register -- -- Return value (type: nil): -- none -- -- Notes: -- - High value fetch item tasks are stored in drx_ql_task_funcs.drx_ql_havfetch_tasks array -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified January 07, 2018 -- ------------------------------------------------------------------------------------------------ -- Add high value fetch task: function drx_ql_add_havfetch_task( actor, npc, p ) -- Validate input: if ( (not p) or (not p[1]) ) then printf( "DRX QL Error: Unable to add havfetch task, invalid parameters supplied" ) return end -- Add the task to the global high value fetch task array: -- table.insert( drx_ql_task_funcs.drx_ql_havfetch_tasks, p[1] ) drx_ql_task_funcs.drx_ql_havfetch_tasks[#drx_ql_task_funcs.drx_ql_havfetch_tasks + 1] = p[1] -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_remove_havfetch_task function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Undesignates a fetch task as a high value fetch item task -- -- Usage: -- drx_ql_remove_havfetch_task( p[1] ) -- -- Parameters: -- p[1] (type: string, task name) -- - Name of the fetch task to unregister -- -- Return value (type: nil): -- none -- -- Notes: -- - High value fetch item tasks are stored in drx_ql_task_funcs.drx_ql_havfetch_tasks array -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified January 08, 2018 -- ------------------------------------------------------------------------------------------------ -- Remove high value fetch task: function drx_ql_remove_havfetch_task( actor, npc, p ) -- Validate input: if ( (not p) or (not p[1]) ) then printf( "DRX QL Error: Unable to remove havfetch task, invalid parameters supplied" ) return end -- Remove the task from the global high value fetch task array: for i = 1, ( #drx_ql_task_funcs.drx_ql_havfetch_tasks ) do if ( drx_ql_task_funcs.drx_ql_havfetch_tasks[i] == p[1] ) then table.remove( drx_ql_task_funcs.drx_ql_havfetch_tasks, i ) break end end -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_give_stored_reward function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Gives player a previously stored reward item or money -- -- Usage: -- drx_ql_give_stored_reward( p[1] ) -- -- Parameters: -- p[1] (type: string, task name) -- - Name of the task calling this function -- -- Persistent storage: -- {task_id}_reward (type: item section name) -- - Name of task reward item -- {task_id}_reward_value (type: float) -- - Value of task reward -- -- Return value (type: nil): -- none -- -- Notes: -- - Task reward items can be stored in pstor var {p[1]}_reward -- - Task reward money value can be stored in pstor var {p[1]}_reward_value -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified April 02, 2018 -- ------------------------------------------------------------------------------------------------ -- Give player stored reward: function drx_ql_give_stored_reward( actor, npc, p ) -- Validate input: if ( (#p < 1) or (not p[1]) ) then printf( "DRX QL Error: Unable to give actor stored task reward, invalid parameters supplied" ) return end -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to give actor stored task reward, db.actor not available" ) return end -- Give actor item reward: local reward_item = utils.load_var( db.actor, string.format( "%s_reward", p[1] ) ) local reward_money = utils.load_var( db.actor, string.format( "%s_reward_value", p[1] ) ) if ( (reward_item) and (system_ini( ):section_exist( reward_item )) ) then dialogs.relocate_item_section( db.actor, reward_item, "in" ) -- Give actor money reward: elseif ( reward_money ) then drx_ql_reward_money( actor, npc, {tonumber( reward_money )} ) -- Display error message else printf( "DRX QL Error: Could not give stored reward, no stored rewards found" ) end -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_setup_float_task function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Spawns a specified item at a random position within a specified location -- -- Usage: -- drx_ql_setup_float_task( p[1], p[2], p[3], p[4], ... ) -- -- Parameters: -- p[1] (type: string, task name) -- - Name of the task calling this function -- p[2] (type: string, item name) -- - Section name of the item to spawn -- p[3] (type: float) -- - Max offset from center of location to spawn the item -- p[4], ... (type: string, section name) -- - List of potential smart terrains or special areas to spawn the item at (see notes) -- -- Persistent storage: -- {task_id}_id (type: smart terrain id) -- - Id of current target smart terrain for specified task -- {task_id}_target_name (type: location name) -- - Name of the target smart terrain or special location for the specified task -- {task_id}_max_dist (type: float) -- - Maximum distance from center to spawn a target item -- {task_id}_fetch (type: string, section name) -- - Section name of the fetch item for specified task -- {task_id}_target_id (type: object id) -- - Id of the spawned float item -- -- Return value (type: nil): -- none -- -- Notes: -- - Special area location data is defined in configs\drx\drx_ql_locations.ltx -- - If p[4], ... is omitted the stored terrain selected by the task precondition will be used -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified July 16, 2019 -- ------------------------------------------------------------------------------------------------ -- Spawn float item: function drx_ql_setup_float_task( actor, npc, p ) -- Validate input: if ( (not p) or (#p < 3) ) then printf( "DRX QL Error: Unable to spawn float item, invalid parameters supplied" ) return end -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to spawn float item, db.actor not available" ) return end -- Pick a random location from the list and store it: local location_name local task_id = p[1] if ( #p >= 4 ) then location_name = p[math.random( 4, #p )] -- If a list was not supplied then check if a target was already determined: else drx_ql_give_stored_smart_target( actor, npc, {task_id} ) local location_id = utils.load_var( db.actor, string.format( "%s_id", task_id ) ) -- If a target was not determined then select a smart terrain inside a building: if ( not location_id ) then xr_conditions.drx_ql_find_special_smart_terrain( actor, npc, {task_id, "building_smarts"} ) drx_ql_give_stored_smart_target( actor, npc, {task_id} ) location_id = utils.load_var( db.actor, string.format( "%s_id", task_id ) ) end -- Get location name: if ( location_id ) then local smart_obj = alife( ):object( location_id ) if ( smart_obj ) then location_name = smart_obj:name( ) end end end -- Save the spawn location: if ( not location_name ) then printf( "DRX QL Error: Unable to spawn float item, cannot find suitable terrain" ) return end utils.save_var( db.actor, string.format( "%s_target_name", task_id ), location_name ) -- Get float item and max dist from terrain center: local max_dist = tonumber( p[3] ) local float_item = p[2] utils.save_var( db.actor, string.format( "%s_max_dist", task_id ), max_dist ) utils.save_var( db.actor, string.format( "%s_fetch", task_id ), float_item ) -- Attempt to spawn the float item: local smart = SIMBOARD.smarts_by_names[location_name] if ( (max_dist == 0) or (not smart) or (smart and smart.online) ) then local float_id = drx_ql_task_funcs.drx_ql_spawn_float_obj( float_item, location_name, max_dist ) if ( float_id ) then utils.save_var( db.actor, string.format( "%s_target_id", task_id ), float_id ) printf( "DRX QL: Float item %s spawned at %s", float_item, location_name ) end end -- Add the current task to the undiscovered float fetch task array: if ( max_dist > 0 ) then -- table.insert( drx_ql_float_fetch_tasks, task_id ) drx_ql_float_fetch_tasks[#drx_ql_float_fetch_tasks + 1] = task_id end -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_setup_story_item_task function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Spawns a quest item at a specified location -- -- Usage: -- drx_ql_setup_story_item_task( p[1], p[2] ) -- -- Parameters: -- p[1] (type: string, task name) -- - Name of the task calling this function -- p[2] (type: string, item name) -- - Section name of the story item to spawn -- -- Return value (type: nil): -- none -- -- Notes: -- - Spawn locations for the item are defined in configs\drx\drx_ql_locations.ltx -- - Spawn location sections are named as follows: -- [drx_ql_location_{story_item}_{x}] -- - {story_id} = section name of the quest item -- - {x} = sequential int starting with 1 (if more than one location is defined, the spawn location will be chosen randomly from those defined) -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified October 02, 2019 -- ------------------------------------------------------------------------------------------------ -- Spawn float item: function drx_ql_setup_story_item_task( actor, npc, p ) -- Validate input: if ( (not p) or (#p < 2) ) then printf( "DRX QL Error: Unable to setup story item task, invalid parameters supplied" ) return end -- Check if the story item already exists: local story_item = p[2] if ( get_story_object( story_item ) ) then printf( "DRX QL: Story item %s already spawned", story_item ) -- Spawn the story item: else local float_id = drx_ql_task_funcs.drx_ql_spawn_float_obj( story_item ) if ( not float_id ) then printf( "DRX QL Error: Unable to spawn story item %s", story_item ) return end printf( "DRX QL: Story item %s spawned", story_item ) -- Register float item story id: local float_obj = alife( ):object( float_id ) if ( float_obj ) then story_objects.check_spawn_ini_for_story_id( float_obj ) end end -- Setup fetch task for story item: setup_generic_fetch_task( actor, npc, {string.format( "%s_fetch", p[1] ), 1, story_item} ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_release_float_item function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Removes a specified item from the game -- -- Usage: -- drx_ql_release_float_item( p[1] ) -- -- Parameters: -- p[1] (type: string, task name) -- - Name of the task calling this function -- -- Persistent storage: -- {task_name}_target_id (type: object id) -- - Id of the spawned float item -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Call of The Zone 1.2 -- Last modified January 11, 2021 -- ------------------------------------------------------------------------------------------------ -- Release the float item: function drx_ql_release_float_item( actor, npc, p ) -- Validate input: if ( (not p) or (#p < 1) ) then printf( "DRX QL Error: Unable to release float item, invalid parameters supplied" ) return end -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to release float item, db.actor not available" ) return end -- Release the item: local item_id = utils.load_var( db.actor, string.format( "%s_target_id", p[1] ) ) if ( item_id ) then local se_obj = alife( ):object( item_id ) if ( not se_obj ) then se_obj = level.object_by_id( item_id ) end if ( se_obj ) then alife( ):release( se_obj, true ) end end -- Remove the current task from the undiscovered float fetch task array: for i = 1, ( #drx_ql_float_fetch_tasks ) do if ( drx_ql_float_fetch_tasks[i] == p[1] ) then table.remove( drx_ql_float_fetch_tasks, i ) break end end -- Send update to the console: printf( "DRX QL: %s float item released", p[1] ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_release_story_item function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Removes a spawned story item from the game -- -- Usage: -- drx_ql_release_story_item( p[1] ) -- -- Parameters: -- p[1] (type: string, section name) -- - Section name of the spawned story item to release -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified October 02, 2019 -- ------------------------------------------------------------------------------------------------ -- Release the story item: function drx_ql_release_story_item( actor, npc, p ) -- Validate input: if ( (not p) or (#p < 1) ) then printf( "DRX QL Error: Unable to release story item, invalid parameters supplied" ) return end -- Remove item from actory inventory: remove_item( actor, npc, p ) -- Release the item if it was outside of actor inventory: local item_id = get_story_object_id( p[1] ) if ( item_id ) then local se_obj = alife( ):object( item_id ) if ( not se_obj ) then se_obj = level.object_by_id( item_id ) end if ( se_obj ) then alife( ):release( se_obj ) end end -- Send update to the console: printf( "DRX QL: %s story item released", p[1] ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_fail_task function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Function to run if a task is failed or cancelled -- -- Usage: -- drx_ql_fail_task( p[1] ) -- -- Parameters: -- p[1] (type: string, task name) -- - Name of the task calling this function -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified January 28, 2019 -- ------------------------------------------------------------------------------------------------ -- Function to run on task fail: function drx_ql_fail_task( actor, npc, p ) -- Validate input: if ( (not p) or (#p < 1) ) then printf( "DRX QL Error: Unable to run task fail function, invalid parameters supplied" ) return end -- If task is a storyline task then decrement sl task count and send actor to next honcho: if ( string.find( p[1], "_sl_task_" ) ) then drx_ql_decrease_sl_tasks_count( ) drx_ql_meet_random_honcho( ) end -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_add_task_giver_companion function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Adds a task giver as a companion to the actor -- - Modification of add_task_companion (CoC 1.5b r4) -- -- Usage: -- drx_ql_add_task_giver_companion( p[1] ) -- -- Parameters: -- p[1] (type: string, task name) -- - Name of the task calling this function -- -- Persistent storage: -- drx_ql_current_npc_speaker_id (type: npc id) -- - Id of the current npc the actor is speaking to -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified July 27, 2018 -- ------------------------------------------------------------------------------------------------ -- Add task giver as task companion: function drx_ql_add_task_giver_companion( actor, npc, p ) -- Validate input: if ( (not p) or (#p < 1) ) then printf( "DRX QL Error: Unable to add task giver as companion, invalid parameters supplied" ) return end -- Get task giver id: local task_giver_id = utils.load_var( db.actor, "drx_ql_current_npc_speaker_id", nil ) if ( task_giver_id == nil ) then printf( "DRX QL Error: Unable to add task giver as companion, could not get id of current speaker" ) return false end local task_giver_obj = alife( ):object( task_giver_id ) if ( not task_giver_obj ) then printf( "DRX QL Error: Unable to add task giver as companion, task giver is invalid" ) return end -- Get task giver squad: local squad = get_object_squad( task_giver_obj ) if ( not squad ) then printf( "DRX QL Error: Unable to add task giver as companion, unable to get task giver squad object" ) return end -- Add task giver squad as companions to actor: axr_companions.companion_squads[squad.id] = squad squad:set_squad_relation( game_relations.FRIENDS ) SIMBOARD:assign_squad_to_smart( squad, nil ) for member in squad:squad_members( ) do local member_obj = (member.id and (db.storage[member.id] and db.storage[member.id].object)) if ( member_obj and member_obj:alive( ) ) then utils.se_obj_save_var( member.id, member.object:name( ), "companion", true ) utils.se_obj_save_var( member.id, member.object:name( ), "companion_cannot_dismiss", true ) utils.se_obj_save_var( member.id, member.object:name( ), "companion_cannot_teleport", nil ) member_obj:inactualize_patrol_path( ) axr_companions.setup_companion_logic( member_obj, db.storage[member.id], false, true ) end end -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_remove_task_giver_companion function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Removes a task giver as a companion to the actor -- - Modification of remove_task_companion (CoC 1.5b r4) -- -- Usage: -- drx_ql_remove_task_giver_companion( p[1] ) -- -- Parameters: -- p[1] (type: string, task name) -- - Name of the task calling this function -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified April 02, 2018 -- ------------------------------------------------------------------------------------------------ -- Remove task giver as task companion: function drx_ql_remove_task_giver_companion( actor, npc, p ) -- Validate input: if ( (not p) or (#p < 1) ) then printf( "DRX QL Error: Unable to remove task giver as companion, invalid parameters supplied" ) return end -- Get task giver id: local tsk = task_manager.get_task_manager( ).task_info[ p[1] ] if ( not tsk ) then printf( "DRX QL Error: Unable to remove task giver as companion, task is invalid" ) return end local task_giver_id = tsk.task_giver_id local task_giver_obj = alife( ):object( task_giver_id ) if ( not task_giver_obj ) then return end -- Get task giver squad: local squad = get_object_squad( task_giver_obj ) if ( not squad ) then return end -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> -- CotZ for IWP: Player-owned items are automatically given back to the player on dismissal of companions. -- -- Author(s) : moonshroom -- Added : 14/01/2025 9:28 pm -- 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 -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> -- Remove task giver squad as companions to actor: squad.scripted_target = nil squad.current_action = nil axr_companions.companion_squads[squad.id] = nil for member in squad:squad_members( ) do local member_obj = (member.id and db.storage[member.id] and db.storage[member.id].object) if ( member_obj ) then axr_logic.restore_scheme_and_logic( member_obj ) member_obj:disable_info_portion( "npcx_is_companion" ) member_obj:disable_info_portion( "npcx_beh_cannot_dismiss" ) utils.se_obj_save_var( member.id, member.object:name( ), "companion", nil ) utils.se_obj_save_var( member.id, member.object:name( ), "companion_cannot_dismiss", nil ) utils.se_obj_save_var( member.id, member.object:name( ), "companion_cannot_teleport", nil ) -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> -- CotZ for IWP: Player-owned items are automatically given -- back to the player on dismissal of companions. -- -- Author(s) : moonshroom -- Added : 14/01/2025 9:28 pm -- Ver. : Indev 6.6 -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> member_obj:iterate_inventory( return_player_items, member_obj ) -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> end end -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_remove_task_helper function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Removes a task helper squad as actor companion -- -- Usage: -- drx_ql_remove_task_giver_companion( p[1] ) -- -- Parameters: -- p[1] (type: string, task name) -- - Name of the task calling this function -- -- Persistent storage: -- {task_id}_helper (type: string, squad id) -- - Squad id of the helper for the specified float fetch task -- -- External strings: -- drx_ql_strings.xml -- drx_ql_str_helper_farewell_{x} (type: string) -- - PDA farewell message from task helper squad when done helping ({x} = sequential int starting at 1) -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified January 30, 2019 -- ------------------------------------------------------------------------------------------------ -- Remove task helper squad as companion: function drx_ql_remove_task_helper( actor, npc, p ) -- Validate input: if ( (not p) or (#p < 1) ) then printf( "DRX QL Error: Unable to remove task helper as companion, invalid parameters supplied" ) return end -- Get the helper squad: local squad_id = utils.load_var( db.actor, string.format( "%s_helper", p[1] ) ) if ( not squad_id ) then return end local squad = axr_companions.companion_squads[squad_id] if ( not squad ) then return end -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> -- CotZ for IWP: Player-owned items are automatically given back to the player on dismissal of companions. -- -- Author(s) : moonshroom -- Added : 14/01/2025 9:28 pm -- 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 -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> -- Remove task helper squad as companions to actor: local farewell_sent = false squad.scripted_target = nil squad.current_action = nil axr_companions.companion_squads[squad.id] = nil for member in squad:squad_members( ) do local member_obj = (member.id and db.storage[member.id] and db.storage[member.id].object) if ( member_obj and member_obj:alive( ) ) then -- Send farewell message: if ( (db.actor) and (not farewell_sent) ) then local se_obj = alife( ):object( member.id ) if ( se_obj ) then local caption_text = string.format( "%s, %s", se_obj:character_name( ), game.translate_string( se_obj:community( ) ) ) local farewell_text = drx_ql_dialog_funcs.drx_ql_random_phrase( "drx_ql_str_helper_farewell" ) db.actor:give_game_news( caption_text, farewell_text, se_obj:character_icon( ), 0, 5000, 0 ) xr_sound.set_sound_play( db.actor:id( ), "pda_tips" ) farewell_sent = true end end -- Remove the current npc as actor companion: axr_logic.restore_scheme_and_logic( member_obj ) member_obj:disable_info_portion( "npcx_is_companion" ) member_obj:disable_info_portion( "npcx_beh_cannot_dismiss" ) utils.se_obj_save_var( member.id, member.object:name( ), "companion", nil ) utils.se_obj_save_var( member.id, member.object:name( ), "companion_cannot_dismiss", nil ) utils.se_obj_save_var( member.id, member.object:name( ), "companion_cannot_teleport", nil ) -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> -- CotZ for IWP: Player-owned items are automatically given -- back to the player on dismissal of companions. -- -- Author(s) : moonshroom -- Added : 14/01/2025 9:28 pm -- Ver. : Indev 6.6 -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> member_obj:iterate_inventory( return_player_items, member_obj ) -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> end end -- Remove the helper squad from persistent memory: utils.save_var( db.actor, string.format( "%s_helper", p[1] ), nil ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_create_squad function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Spawns a squad at a specified smart terrain -- - Modification of create_squad (CoC 1.5b r4) -- -- Usage: -- drx_ql_create_squad( p[1], p[2] ) -- -- Parameters: -- p[1] (type: string, squad section name) -- - Name of the squad to spawn -- p[2] (type: string, smart terrain name) -- - Smart terrain to spawn the squad on -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified April 13, 2019 -- ------------------------------------------------------------------------------------------------ -- Spawn squad: function drx_ql_create_squad( actor, obj, p ) -- Validate input: if ( #p < 2 ) then printf( "DRX QL Error: Unable to create squad, invalid parameters supplied" ) return end -- Check if squad is valid: local squad_id = p[1] if ( not system_ini( ):section_exist( squad_id ) ) then printf( "DRX QL Error: Unable to create squad, squad id is invalid" ) return end -- Check if squad already exists: if ( not string.find( squad_id, "sim_squad" ) ) then if ( get_story_squad( squad_id ) ~= nil ) then printf( "DRX QL: Not spawning %s, squad already exists", squad_id ) return end end -- Get smart terrain: local smart_name = p[2] local smart = SIMBOARD.smarts_by_names[smart_name] if ( smart == nil ) then printf( "DRX QL Error: Unable to create squad, smart terrain is invalid" ) return end -- Spawn the squad: local squad = SIMBOARD:create_squad( smart, squad_id ) if ( not squad ) then printf( "DRX QL Error: Unable to create squad" ) return end -- Set up squad: for k in ( squad:squad_members( ) ) do local se_obj = (k.object or (k.id and alife( ):object( k.id ))) if ( se_obj ) then SIMBOARD:setup_squad_and_group( se_obj ) end end -- Send update to the console: printf( "DRX QL: %s spawned at %s", squad_id, smart_name ) -- Set return value: return squad end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_spawn_horde function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Spawns a group of individual NPC's -- -- Usage: -- drx_ql_spawn_horde( p[1], p[2], p[3], ... ) -- -- Parameters: -- p[1] (type: string, smart terrain name) -- - Smart terrain to spawn the horde at or special location specified in drx_ql_locations.ltx -- p[2] (type: int) -- - Number of NPC's to spawn in the horde -- p[3], ... (type: string, npc section name) -- - NPC's to include in the horde -- -- Ini requirements: -- drx\drx_ql_locations.ltx -- [{special_location_name}] -- pos_x (type: float) -- - x-position of the location -- pos_y (type: float) -- - y-position of the location -- pos_z (type: float) -- - z-position of the location -- lvid (type: int, level vertex id) -- - Level vertex id of the location -- gvid (type: int, game vertex id) -- - Game vertex id of the location -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified October 26, 2019 -- ------------------------------------------------------------------------------------------------ -- Spawn horde: function drx_ql_spawn_horde( actor, obj, p ) -- Locations ini file: local loc_ini = ini_file( "drx\\drx_ql_locations.ltx" ) if ( not loc_ini ) then printf( "DRX QL: Unable to spawn horde, locations ini file not found" ) return end -- Validate input: if ( #p < 3 ) then printf( "DRX QL Error: Unable to spawn horde, invalid parameters supplied" ) return end -- Get location data: local pos_x = 0 local pos_y = 0 local pos_z = 0 local lvid = 0 local gvid = 0 local smart = SIMBOARD.smarts_by_names[p[1]] if ( smart ) then pos_x = smart.position.x pos_y = smart.position.y pos_z = smart.position.z lvid = smart.m_level_vertex_id gvid = smart.m_game_vertex_id else pos_x = (loc_ini:r_float_ex( p[1], "pos_x" ) or 0) pos_y = (loc_ini:r_float_ex( p[1], "pos_y" ) or 0) pos_z = (loc_ini:r_float_ex( p[1], "pos_z" ) or 0) lvid = (loc_ini:r_float_ex( p[1], "lvid" ) or 0) gvid = (loc_ini:r_float_ex( p[1], "gvid" ) or 0) end -- Spawn the horde: for i = 1, ( tonumber( p[2] ) ) do local npc_sect = p[math.random( 3, #p )] local npc_obj = alife( ):create( npc_sect, vector( ):set( pos_x, pos_y, pos_z ), lvid, gvid ) if ( not npc_obj ) then printf( "DRX QL Error: Unable to spawn horde member %s at %s", npc_sect, p[3] ) end end -- Send update to the console: printf( "DRX QL: %s horde spawned at %s", p[3], p[1] ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_create_big_mutant_squad function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Spawns a random big mutant squad at a specified smart terrain -- - Modification of create_squad (CoC 1.5b r4) -- -- Usage: -- drx_ql_create_big_mutant_squad( p[1] ) -- -- Parameters: -- p[1] (type: string, task id) -- - Name of the task calling this function -- -- Persistent storage: -- {task_id}_id (type: smart terrain id) -- - Id of current target smart terrain for specified task -- {task_id}_target_id (type: squad section name) -- - Name of the target squad for specified task -- -- Return value (type: nil): -- none -- -- Notes: -- - The name of the target squad chosen is stored in pstor var {task_id}_target_id -- - Big mutant squads are defined in configs\misc\squad_descr_special.ltx -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified May 01, 2018 -- ------------------------------------------------------------------------------------------------ -- Spawn big mutant squad: function drx_ql_create_big_mutant_squad( actor, npc, p ) -- Validate input: if ( #p < 1 ) then printf( "DRX QL Error: Unable to create big mutant squad, invalid parameters supplied" ) return end -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to create big mutant squad, db.actor not available" ) return end -- Get the smart terrain to spawn the squad at: local smart_id = utils.load_var( db.actor, string.format( "%s_id", p[1] ) ) if ( smart_id == nil ) then printf( "DRX QL Error: Unable to create big mutant squad, no target smart found" ) return end local smart_obj = alife( ):object( smart_id ) if ( not smart_obj ) then printf( "DRX QL Error: Unable to create big mutant squad, target smart invalid" ) return end local smart_name = smart_obj:name( ) local smart = SIMBOARD.smarts_by_names[smart_name] if ( smart == nil ) then printf( "DRX QL Error: Unable to create big mutant squad, target smart invalid" ) return end -- Get the squad to spawn: local ltx = system_ini( ) local eligible_squads = 0 while ( ltx:section_exist( string.format( "drx_ql_big_mutant_squad_%s", (eligible_squads + 1) ) ) ) do eligible_squads = (eligible_squads + 1) end if ( eligible_squads < 1 ) then printf( "DRX QL Error: Unable to create big mutant squad, no eligible squads defined" ) return end local squad_name = string.format( "drx_ql_big_mutant_squad_%s", math.random( eligible_squads ) ) utils.save_var( db.actor, string.format( "%s_target_id", p[1] ), squad_name ) -- Spawn the squad: local squad = SIMBOARD:create_squad( smart, squad_name ) if ( not squad ) then printf( "DRX QL Error: Unable to create big mutant squad, squad is invalid" ) return end -- Set squad target smart: squad.action_condlist = alun_utils.parse_condlist( smart_name ) -- Setup squad: for k in squad:squad_members( ) do local se_obj = (k.object or (k.id and alife( ):object( k.id ))) if ( se_obj ) then SIMBOARD:setup_squad_and_group( se_obj ) end end -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_create_interceptor_squad function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Spawns an interceptor task target squad -- -- Usage: -- drx_ql_create_interceptor_squad( p[1] ) -- -- Parameters: -- p[1] (type: string, task id) -- - Name of the task calling this function -- p[2] (type: string, squad section name) -- - Squad type to spawn -- -- Persistent storage: -- {task_id}_id (type: smart terrain id) -- - Id of current target smart terrain for specified task -- {task_id}_target_id (type: npc id) -- - Id of the npc carrying interceptor task item -- -- Return value (type: nil): -- none -- -- Notes: -- - The id of the target npc is stored in pstor var {task_id}_target_id -- - Interceptor target squads are defined in configs\misc\squad_descr_special.ltx -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified August 26, 2018 -- ------------------------------------------------------------------------------------------------ -- Spawn interceptor task target squad: function drx_ql_create_interceptor_squad( actor, npc, p ) -- Validate input: if ( #p < 2 ) then printf( "DRX QL Error: Unable to create interceptor squad, invalid parameters supplied" ) return end -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to create interceptor squad, db.actor not available" ) return end -- Get the smart terrain to spawn the squad at: local smart_id = utils.load_var( db.actor, string.format( "%s_id", p[1] ) ) if ( smart_id == nil ) then printf( "DRX QL Error: Unable to create interceptor squad, no target smart found" ) return end local smart_obj = alife( ):object( smart_id ) if ( not smart_obj ) then printf( "DRX QL Error: Unable to create interceptor squad, target smart invalid" ) return end local smart_name = smart_obj:name( ) local smart = SIMBOARD.smarts_by_names[smart_name] if ( smart == nil ) then printf( "DRX QL Error: Unable to create interceptor squad, target smart invalid" ) return end -- Spawn the squad: local squad = SIMBOARD:create_squad( smart, p[2] ) if ( not squad ) then printf( "DRX QL Error: Unable to create interceptor squad, squad is invalid" ) return end -- Setup squad: for k in squad:squad_members( ) do local se_obj = (k.object or (k.id and alife( ):object( k.id ))) if ( se_obj ) then SIMBOARD:setup_squad_and_group( se_obj ) end end -- Select interceptor item carrier: local carrier_id = nil for m in squad:squad_members( ) do local se_obj = (m.object or (m.id and alife( ):object( m.id ))) if ( (se_obj) and (se_obj:alive( )) ) then carrier_id = m.id break end end -- Save the interceptor target npc id: if ( carrier_id == nil ) then printf( "DRX QL Error: Unable to create interceptor squad, target squad contains no valid npcs" ) return end utils.save_var( db.actor, string.format( "%s_target_id", p[1] ), carrier_id ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_remove_story_squad function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Removes a spawned story squad -- - Modification of remove_special_task_squad (CoC 1.5b r4) -- -- Usage: -- drx_ql_remove_story_squad( p[1]:... ) -- -- Parameters: -- p[1]:... (type: string, squad story id) -- - Story ids of the squads to remove -- -- Ini requirements: -- drx\drx_ql_config.ltx -- [sim_task_props] -- max_blackscreen_dist (type: float, meters) -- - Max squad distance from actor to show black screen when removing squad -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified August 25, 2019 -- ------------------------------------------------------------------------------------------------ -- Remove assassin squad: function drx_ql_remove_story_squad( actor, npc, p ) -- Validate input: if ( (not p) or (#p < 1) or (p[1] == nil) ) then printf( "DRX QL Error: Could not remove story squad, invalid parameters supplied" ) end -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> -- CotZ for IWP: Player-owned items are automatically given back to the player on dismissal of companions. -- -- Author(s) : moonshroom -- Added : 14/01/2025 9:28 pm -- 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 -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> -- Check if any squads in actor view: local squad_in_view = false for i = 1, ( #p ) do -- Get the squad object: local squad = get_story_squad( p[i] ) if ( squad ) then -- Check if any members of squad are in actor's view: for member in squad:squad_members( ) do local member_obj = (db.storage[member.id] and db.storage[member.id].object) -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> -- CotZ for IWP: Player-owned items are automatically given back to -- the player on dismissal of companions. -- -- Author(s) : moonshroom -- Added : 14/01/2025 9:28 pm -- Ver. : Indev 6.6 -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> if ( member_obj ) then if ( member_obj:alive() ) then member_obj:iterate_inventory( return_player_items, member_obj ) end if ( npc_in_actor_frustrum( member_obj ) ) then squad_in_view = true end end -- <>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<>--<> end if ( squad_in_view ) then break end -- Check if squad is near actor: local max_blackscreen_dist = (drx_ql_ini:r_float_ex( "sim_task_props", "max_blackscreen_dist" ) or 0) if ( (squad.dist_to_actor ~= nil) and (squad.dist_to_actor <= max_blackscreen_dist) ) then squad_in_view = true break end end end -- Momentarily show black screen if a squad is in actor view: if ( squad_in_view ) then level.add_pp_effector( "black.ppe", 1313, false ) end -- Remove the squads: for k = 1, ( #p ) do local squad = get_story_squad( p[k] ) if ( squad ) then SIMBOARD:remove_squad( squad ) end end -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_activate_teleport function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Updates the map spot visibility for level changer teleports -- -- Usage: -- drx_ql_activate_teleport( p[1], ... ) -- -- Parameters: -- p[1], ... (type: string, teleport names) -- - Names of the teleports to activate -- -- Ini requirements: -- sr_teleport_sections.ltx -- [{teleport_name}] -- - Teleport space restrictor properties -- -- Return value (type: nil): -- none -- -- Notes: -- - Add enable condition in sr_teleport_sections.ltx containing infoportion check to allow activation via this function -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified August 19, 2019 -- ------------------------------------------------------------------------------------------------ -- Enable teleport: function drx_ql_activate_teleport( actor, npc, p ) -- Teleport config file: local sr_teleport_ini = ini_file( "sr_teleport_sections.ltx" ) if ( not sr_teleport_ini ) then printf( "DRX QL Error: Cannot activate teleport, config file not found" ) end -- Validate input: if ( (not p) or (#p < 1) ) then printf( "DRX QL Error: Cannot activate teleport, invalid parameters supplied" ) end -- Enable teleports: for i = 1, ( #p ) do -- Get teleport id: local teleport_name = p[i] local teleport_id = get_story_object_id( teleport_name ) if ( not teleport_id ) then printf( "DRX QL Error: Cannot activate teleport %s, teleport is invalid", teleport_name ) end -- Give activate teleport infoportion: give_info( string.format( "drx_ql_info_%s_active", teleport_name ) ) -- Update map spot: local map_spot = (sr_teleport_ini:line_exist( teleport_name, "spot") and sr_teleport_ini:r_string_ex( teleport_name, "spot" )) if ( (map_spot) and (level.map_has_object_spot( teleport_id, map_spot ) == 0) ) then local label_text = (sr_teleport_ini:line_exist( teleport_name, "hint" ) and sr_teleport_ini:r_string_ex( teleport_name, "hint" )) label_text = (label_text and game.translate_string( label_text )) level.map_add_object_spot_ser( teleport_id, map_spot, label_text ) end end -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_remove_assassin_squad function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Removes a spawned assassin squad -- - Modification of remove_special_task_squad (CoC 1.5b r4) -- -- Usage: -- drx_ql_remove_assassin_squad( ) -- -- Parameters: -- none -- -- Ini requirements: -- drx\drx_ql_config.ltx -- [hunted_task_factions] (type: string, faction names) -- - List of factions that can be assassins -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified May 19, 2019 -- ------------------------------------------------------------------------------------------------ -- Remove assassin squad: function drx_ql_remove_assassin_squad( actor, npc, p ) -- Get a list of assassin squad factions: local factions_list = alun_utils.collect_section( drx_ql_ini, "hunted_task_factions" ) if ( (not factions_list) or (#factions_list < 1) ) then printf( "DRX QL Error: Unable to remove assassin squad, no assassin factions specified" ) return end -- Remove assassin squad: for i = 1, ( #factions_list ) do local squad_name = string.format( "drx_ql_assassin_squad_%s", factions_list[i] ) drx_ql_remove_story_squad( actor, npc, {squad_name} ) end -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_reward_psi_helmet function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Gives the player a good psi helmet -- -- Usage: -- drx_ql_reward_psi_helmet( ) -- -- Parameters: -- none -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified September 27, 2019 -- ------------------------------------------------------------------------------------------------ -- Give actor good psi helmet: function drx_ql_reward_psi_helmet( actor, npc, p ) -- Give actor psi helmet: give_actor( actor, npc, {"good_psy_helmet"} ) give_info( "drx_ql_actor_has_psi_helmet" ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_banter function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Plays PDA banter messages between 2 or more NPC's -- -- Usage: -- drx_ql_banter( p[1] ) -- -- Parameters: -- p[1] (type: string) -- - Banter message sequence identifier to play -- -- Persistent storage: -- drx_ql_bnt_dialog_no_{identifier} (type: int) -- - Current banter dialog number ({identifier} = value passed for p[1] -- -- Ini requirements: -- drx\drx_ql_banter.ltx -- [{identifier_{x}] -- {y} = {npc_story_id} -- - Banter sequence speaker order ({x}, {y} = sequential int starting with 1) -- drx\drx_ql_config.ltx -- [message_settings] -- msg_time (type: float, miliseconds) -- - Minimum message display time -- max_chars (type: int) -- - Message characters at minimum display time -- -- External strings: -- drx_ql_banter_strings.ltx -- {identifier}_{x}_{y} (type: string) -- - Messages to display in PDA banter ({x}, {y} = sequential int starting with 1) -- -- Return value (type: nil): -- none -- -- Notes: -- - To create a banter sequence, create a section in drx_ql_banter.ltx in the following format: -- [{identifier}_{x}]] ({identifier} = value passed for p[1], {x} = sequential int starting with 1) -- {y} = {npc_story_id} ({y} = sequential int starting with 1, {npc_story_id} = story id for the current speaker in the sequence) -- - Each element in the sequence must have a string with the following string id: -- {identifier}_{x}_{y} ({identifier}_{x} = section name used in above config file, {y} = current element number (same as {y} in config file) -- - All speakers will be verified to be alive before playing a sequence -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified October 17, 2019 -- ------------------------------------------------------------------------------------------------ -- Global vars: local drx_ql_bnt_dialog_array = {} local drx_ql_bnt_section = "" local drx_ql_bnt_index = 0 -- Create PDA banter sequence: function drx_ql_banter( actor, npc, p ) -- Location of the banter settings file: local ini = ini_file( "drx\\drx_ql_banter.ltx" ) if ( not ini ) then printf( "DRX QL Error: Cannot play banter sequence, banter config file not found" ) return end -- Location of the main settings file: local drx_ql_ini = ini_file( "drx\\drx_ql_config.ltx" ) if ( not drx_ql_ini ) then printf( "DRX QL Error: Cannot play banter sequence, Questlines config file not found" ) return end -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Cannot play banter sequence, db.actor not available" ) return end -- Validate input: if ( (not p) or (#p < 1) ) then printf( "DRX QL Error: Cannot play banter sequence, invalid parameters supplied" ) return end -- Check if a banter sequence is already playing: if ( has_alife_info( "drx_ql_banter_playing" ) ) then return end -- Check actor not fighting: if ( not is_empty( xr_combat_ignore.fighting_with_actor_npcs ) ) then return end -- Check actor not sleeping: if ( has_alife_info( "sleep_active" ) or has_alife_info( "actor_is_sleeping" ) ) then return end -- Clear out existing banter: drx_ql_bnt_dialog_array = {} drx_ql_bnt_section = "" drx_ql_bnt_index = 0 -- Pick next sequential dialog: local dialog_no = (utils.load_var( db.actor, string.format( "drx_ql_bnt_dialog_no_%s", p[1] ), 0 ) + 1) if ( not ini:section_exist( string.format( "%s_%s", p[1], dialog_no ) ) ) then dialog_no = 1 end if ( not ini:section_exist( string.format( "%s_%s", p[1], dialog_no ) ) ) then printf( "DRX QL Error: Cannot play banter sequence, no dialogs available for %s", p[1] ) return end drx_ql_bnt_section = string.format( "%s_%s", p[1], dialog_no ) utils.save_var( db.actor, string.format( "drx_ql_bnt_dialog_no_%s", p[1] ), dialog_no ) -- Fill dialog array: drx_ql_bnt_dialog_array = alun_utils.collect_section( ini, drx_ql_bnt_section, true ) if ( (not drx_ql_bnt_dialog_array) or (table.size( drx_ql_bnt_dialog_array ) < 1) ) then printf( "DRX QL Error: Cannot play banter sequence, no dialogs found within section %s", drx_ql_bnt_section ) return end -- Validate speakers: for i = 1, ( table.size( drx_ql_bnt_dialog_array ) ) do -- Check speaker is alive: local npc_id = get_story_object_id( drx_ql_bnt_dialog_array[tostring( i )] ) local npc_obj = (npc_id and alife( ):object( npc_id )) if ( (not npc_obj) or (not npc_obj:alive( )) ) then printf( "DRX QL Error: Cannot play banter sequence, speaker %s is not alive", drx_ql_bnt_dialog_array[tostring( i )] ) return end -- Check speaker not sleeping, fighting, wounded, or hostage: local speaker_obj = (db.storage[npc_id] and db.storage[npc_id].object) if ( not speaker_obj ) then return end if ( (state_mgr.get_state( speaker_obj ) == "sleep") or (speaker_obj:wounded( )) or (xrs_kill_wounded.hostage_list[npc_id]) or (speaker_obj:best_enemy( )) ) then return end end -- Create banter sequence: local display_time = math.ceil( ((drx_ql_ini:r_float_ex( "message_settings", "msg_time" ) or 0) / 1000) ) local max_chars = (drx_ql_ini:r_float_ex( "message_settings", "max_chars" ) or 0) local delay_time = 0 for k = 1, ( table.size( drx_ql_bnt_dialog_array ) ) do -- Add current message to queue: CreateTimeEvent( k, string.format( "drx_ql_bnt_show_msg_%s", k ), delay_time, drx_ql_bnt_show_msg ) -- Calculate total delay time for next message: local char_count = string.len( game.translate_string( string.format( "%s_%s", drx_ql_bnt_section, k ) ) ) if ( (max_chars) and (char_count > max_chars) ) then display_time = math.floor( display_time * (char_count / max_chars) ) end if ( display_time ) then delay_time = (delay_time + display_time) end end -- Flag banter sequence as playing: give_info( "drx_ql_banter_playing" ) -- Set return value: return end -- Display banter sequence message: function drx_ql_bnt_show_msg( ) -- Check if banter was interrupted: if ( not has_alife_info( "drx_ql_banter_playing" ) ) then return true end -- Increment the index: drx_ql_bnt_index = ((drx_ql_bnt_index or 0) + 1) if ( drx_ql_bnt_index > table.size( drx_ql_bnt_dialog_array ) ) then disable_info( "drx_ql_banter_playing" ) return true end -- Check actor not fighting: if ( not is_empty( xr_combat_ignore.fighting_with_actor_npcs ) ) then disable_info( "drx_ql_banter_playing" ) return true end -- Get speaker: local speaker_story_id = drx_ql_bnt_dialog_array[tostring( drx_ql_bnt_index )] local speaker_id = (speaker_story_id and get_story_object_id( speaker_story_id )) if ( not speaker_id ) then printf( "DRX QL Error: Cannot display banter sequence message, speaker %s is not valid", speaker_story_id ) disable_info( "drx_ql_banter_playing" ) return true end local speaker_obj = (db.storage[speaker_id] and db.storage[speaker_id].object) if ( (not speaker_obj) or (not speaker_obj:alive( )) ) then printf( "DRX QL Error: Cannot play banter sequence, speaker %s is not alive", speaker_story_id ) disable_info( "drx_ql_banter_playing" ) return true end -- Check speaker not fighting or wounded: if ( speaker_obj:wounded( ) or speaker_obj:best_enemy( ) ) then disable_info( "drx_ql_banter_playing" ) return true end -- Display PDA message: local msg_text = game.translate_string( string.format( "%s_%s", drx_ql_bnt_section, drx_ql_bnt_index ) ) drx_ql_display_message( speaker_id, msg_text ) -- Check if sequence is finished: if ( drx_ql_bnt_index == table.size( drx_ql_bnt_dialog_array ) ) then disable_info( "drx_ql_banter_playing" ) end -- Set return value: return true end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_display_message function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Displays a PDA message from an NPC -- -- Usage: -- drx_ql_display_message( sender_id, msg_text ) -- -- Parameters: -- sender_id (type: npc id) -- - ID of the npc sending the message -- msg_text (type: string) -- - Message to display -- -- Ini requirements: -- drx\drx_ql_config.ltx -- [message_settings] -- msg_time (type: float, miliseconds) -- - Minimum message display time -- max_chars (type: int) -- - Message characters at minimum display time -- -- Return value (type: bool): -- Returns true on success, false on failure -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified October 15, 2019 -- ------------------------------------------------------------------------------------------------ -- Play PDA message: function drx_ql_display_message( sender_id, msg_text ) -- Ensure db.actor is available: if ( not db.actor ) then return false end -- Location of the settings file: local ini = ini_file( "drx\\drx_ql_config.ltx" ) if ( not ini ) then return false end -- Validate input: if ( not sender_id ) then return false end -- Get sender object: local sender_obj = alife( ):object( sender_id ) if ( not sender_obj ) then return false end -- Format message caption text: local faction_name = "" if ( alife( ):has_info( sender_id, "npcx_is_companion" ) ) then faction_name = game.translate_string( "st_ui_pda_companion" ) else faction_name = game.translate_string( sender_obj:community( ) ) end local caption_text = string.format( "%s, %s", sender_obj:character_name( ), faction_name ) -- Calculate display time: local display_time = (ini:r_float_ex( "message_settings", "msg_time" ) or 0) local max_chars = (ini:r_float_ex( "message_settings", "max_chars" ) or 0) local char_count = string.len( msg_text ) if ( (max_chars) and (char_count > max_chars) ) then display_time = math.floor( display_time * (char_count / max_chars) ) end if ( not display_time ) then return false end -- Display message: db.actor:give_game_news( caption_text, msg_text, sender_obj:character_icon( ), 0, display_time, 0 ) xr_sound.set_sound_play( db.actor:id( ), "pda_tips" ) -- Set return value: return true end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_setup_mon_inf_task function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Initiates Monolith Infiltration task -- -- Usage: -- drx_ql_setup_mon_inf_task( ) -- -- Parameters: -- none -- -- Ini requirements: -- drx\drx_ql_config.ltx -- [mon_inf_settings] -- injection_delay (type: float, seconds) -- - Length of time between accepting task and receiving serum injection -- serum_delay (type: float, seconds) -- - Length of time after receiving injection before getting lightheaded -- lightheaded_time (type: float, seconds) -- - Length of time to hold lightheaded effect before full blackout -- fade_to_black_time (type: float, seconds) -- - Length of time to play fade to black effect -- blackout_time (type: float, seconds) -- - Length of time to hold black screen before playing cutscene -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified April 09, 2019 -- ------------------------------------------------------------------------------------------------ -- Set up player as Monolith infiltrator: function drx_ql_setup_mon_inf_task( actor, npc, p ) -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to set up Monolith infiltration task, db.actor not available" ) return end -- Reset infoportions: disable_info( "drx_ql_info_mon_inf_start" ) disable_info( "drx_ql_info_mon_inf_stop" ) -- End conversation: if ( db.actor:is_talking( ) ) then db.actor:stop_talk( ) end -- Pause before injecting serum: local injection_delay = (drx_ql_ini:r_float_ex( "mon_inf_settings", "injection_delay" ) or 0) CreateTimeEvent( 1, "drx_ql_mi_injecting_serum", injection_delay, drx_ql_setup_mon_inf_task_1 ) -- Set return value: return true end -- Injecting serum: function drx_ql_setup_mon_inf_task_1( actor, npc, p ) -- Play injection sound: xr_effects.play_sound_on_actor( nil, nil, {"interface\\inv_pills"} ) -- Delay before player starts losing consciousness: local serum_delay = (drx_ql_ini:r_float_ex( "mon_inf_settings", "serum_delay" ) or 0) CreateTimeEvent( 2, "drx_ql_mi_lightheaded_delay", serum_delay, drx_ql_setup_mon_inf_task_2 ) -- Set return value: return true end -- Player gets lightheaded: function drx_ql_setup_mon_inf_task_2( actor, npc, p ) -- Make player vision go lightheaded: level.add_pp_effector( "alcohol.ppe", 9800, false ) level.add_cam_effector( "camera_effects\\drunk.anm", 9801, false ) -- Hold lightheaded effect briefly before moving on to full blackout: local lightheaded_time = (drx_ql_ini:r_float_ex( "mon_inf_settings", "lightheaded_time" ) or 0) CreateTimeEvent( 3, "drx_ql_mi_lightheaded_hold", lightheaded_time, drx_ql_setup_mon_inf_task_3 ) -- Set return value: return true end -- Player vision fades to black: function drx_ql_setup_mon_inf_task_3( actor, npc, p ) -- Make player start blacking out: level.add_pp_effector( "agr_u_fade.ppe", 9802, false ) -- Fade out timer: local fade_to_black_time = (drx_ql_ini:r_float_ex( "mon_inf_settings", "fade_to_black_time" ) or 0) CreateTimeEvent( 4, "drx_ql_mi_fade_to_black", fade_to_black_time, drx_ql_setup_mon_inf_task_4 ) -- Set return value: return true end -- Player blacked out: function drx_ql_setup_mon_inf_task_4( actor, npc, p ) -- Make screen go completely black: level.add_pp_effector( "black.ppe", 9803, true ) -- Remove companions: axr_companions.remove_all_from_actor_squad( ) -- Hold blackout effect briefly before playing cutscene: local blackout_time = (drx_ql_ini:r_float_ex( "mon_inf_settings", "blackout_time" ) or 0) CreateTimeEvent( 5, "drx_ql_mi_blacked_out", blackout_time, drx_ql_setup_mon_inf_task_5 ) -- Set return value: return true end -- Play cutscene: function drx_ql_setup_mon_inf_task_5( actor, npc, p ) -- Play Death Truck cut scene (calls drx_ql_mon_inf_teleport( ) on complete): game.start_tutorial( "drx_ql_mon_inf_mov" ) -- Remove blackout effect: level.remove_cam_effector( 9801 ) level.remove_pp_effector( 9800 ) level.remove_pp_effector( 9803 ) -- Set return value: return true end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_mon_inf_teleport function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Teleports actor to crashed Death Truck location in Pripyat -- -- Usage: -- drx_ql_mon_inf_teleport( ) -- -- Parameters: -- none -- -- Ini requirements: -- drx\drx_ql_config.ltx -- [mon_inf_settings] -- driver_corpse (type: string, npc section name) -- - Death truck driver corpse -- rookie_corpse (type: string, npc section name) -- - Death truck rookie victim corpse -- zombie_corpse (type: string, npc section name) -- - Death truck zombified victim corpse -- drx\drx_ql_locations.ltx -- [drx_ql_location_mon_inf_teleport] -- pos_x (type: float) -- - x-location of Monolith infiltration task teleport destination -- pos_y (type: float) -- - y-location of Monolith infiltration task teleport destination -- pos_z (type: float) -- - z-location of Monolith infiltration task teleport destination -- lvid (type: int, level vertex id) -- - Level vertex id of Monolith infiltration task teleport destination -- gvid (type: int, game vertex id) -- - Game vertex id of Monolith infiltration task teleport destination -- [drx_ql_location_mon_inf_driver_corpse] -- pos_x (type: float) -- - x-location of Monolith infiltration task death truck driver corpse -- pos_y (type: float) -- - y-location of Monolith infiltration task death truck driver corpse -- pos_z (type: float) -- - z-location of Monolith infiltration task death truck driver corpse -- lvid (type: int, level vertex id) -- - Level vertex id of Monolith infiltration task death truck driver corpse -- gvid (type: int, game vertex id) -- - Game vertex id of Monolith infiltration task death truck driver corpse -- [drx_ql_location_mon_inf_rookie_corpse] -- pos_x (type: float) -- - x-location of Monolith infiltration task death truck rookie victim corpse -- pos_y (type: float) -- - y-location of Monolith infiltration task death truck rookie victim corpse -- pos_z (type: float) -- - z-location of Monolith infiltration task death truck rookie victim corpse -- lvid (type: int, level vertex id) -- - Level vertex id of Monolith infiltration task death truck rookie victim corpse -- gvid (type: int, game vertex id) -- - Game vertex id of Monolith infiltration task death truck rookie victim corpse -- [drx_ql_location_mon_inf_zombie_corpse] -- pos_x (type: float) -- - x-location of Monolith infiltration task death truck zombified victim corpse -- pos_y (type: float) -- - y-location of Monolith infiltration task death truck zombified victim corpse -- pos_z (type: float) -- - z-location of Monolith infiltration task death truck zombified victim corpse -- lvid (type: int, level vertex id) -- - Level vertex id of Monolith infiltration task death truck zombified victim corpse -- gvid (type: int, game vertex id) -- - Game vertex id of Monolith infiltration task death truck zombified victim corpse -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified April 09, 2019 -- ------------------------------------------------------------------------------------------------ -- Teleport actor to Pripyat: function drx_ql_mon_inf_teleport( actor, npc, p ) -- Locations ini file: local loc_ini = ini_file( "drx\\drx_ql_locations.ltx" ) if ( not loc_ini ) then printf( "DRX QL: Unable to teleport actor for Monolith infiltration task, locations ini file not found" ) end -- Give start monolith infiltrator task infoportion: give_info( "drx_ql_info_mon_inf_start" ) -- Spawn death truck driver corpse: local pos_x = (loc_ini:r_float_ex( "drx_ql_location_mon_inf_driver_corpse", "pos_x" ) or 0) local pos_y = (loc_ini:r_float_ex( "drx_ql_location_mon_inf_driver_corpse", "pos_y" ) or 0) local pos_z = (loc_ini:r_float_ex( "drx_ql_location_mon_inf_driver_corpse", "pos_z" ) or 0) local lvid = (loc_ini:r_float_ex( "drx_ql_location_mon_inf_driver_corpse", "lvid" ) or 0) local gvid = (loc_ini:r_float_ex( "drx_ql_location_mon_inf_driver_corpse", "gvid" ) or 0) local driver_corpse = drx_ql_ini:r_string_ex( "mon_inf_settings", "driver_corpse" ) local driver_corpse_obj = (driver_corpse and alife( ):create( driver_corpse, vector( ):set( pos_x, pos_y, pos_z ), lvid, gvid )) if ( driver_corpse_obj ) then driver_corpse_obj:kill( ) end -- Spawn rookie victim corpse: local pos_x = (loc_ini:r_float_ex( "drx_ql_location_mon_inf_rookie_corpse", "pos_x" ) or 0) local pos_y = (loc_ini:r_float_ex( "drx_ql_location_mon_inf_rookie_corpse", "pos_y" ) or 0) local pos_z = (loc_ini:r_float_ex( "drx_ql_location_mon_inf_rookie_corpse", "pos_z" ) or 0) local lvid = (loc_ini:r_float_ex( "drx_ql_location_mon_inf_rookie_corpse", "lvid" ) or 0) local gvid = (loc_ini:r_float_ex( "drx_ql_location_mon_inf_rookie_corpse", "gvid" ) or 0) local rookie_corpse = drx_ql_ini:r_string_ex( "mon_inf_settings", "rookie_corpse" ) local rookie_corpse_obj = (rookie_corpse and alife( ):create( rookie_corpse, vector( ):set( pos_x, pos_y, pos_z ), lvid, gvid )) if ( rookie_corpse_obj ) then rookie_corpse_obj:kill( ) end -- Spawn zombified victim corpse: local pos_x = (loc_ini:r_float_ex( "drx_ql_location_mon_inf_zombie_corpse", "pos_x" ) or 0) local pos_y = (loc_ini:r_float_ex( "drx_ql_location_mon_inf_zombie_corpse", "pos_y" ) or 0) local pos_z = (loc_ini:r_float_ex( "drx_ql_location_mon_inf_zombie_corpse", "pos_z" ) or 0) local lvid = (loc_ini:r_float_ex( "drx_ql_location_mon_inf_zombie_corpse", "lvid" ) or 0) local gvid = (loc_ini:r_float_ex( "drx_ql_location_mon_inf_zombie_corpse", "gvid" ) or 0) local zombie_corpse = drx_ql_ini:r_string_ex( "mon_inf_settings", "zombie_corpse" ) local zombie_corpse_obj = (zombie_corpse and alife( ):create( zombie_corpse, vector( ):set( pos_x, pos_y, pos_z ), lvid, gvid )) if ( zombie_corpse_obj ) then zombie_corpse_obj:kill( ) end -- Teleport actor to Pripyat: local pos_x = (loc_ini:r_float_ex( "drx_ql_location_mon_inf_teleport", "pos_x" ) or 0) local pos_y = (loc_ini:r_float_ex( "drx_ql_location_mon_inf_teleport", "pos_y" ) or 0) local pos_z = (loc_ini:r_float_ex( "drx_ql_location_mon_inf_teleport", "pos_z" ) or 0) local lvid = (loc_ini:r_float_ex( "drx_ql_location_mon_inf_teleport", "lvid" ) or 0) local gvid = (loc_ini:r_float_ex( "drx_ql_location_mon_inf_teleport", "gvid" ) or 0) ChangeLevel( vector( ):set( pos_x, pos_y, pos_z ), lvid, gvid, vector( ):set( 0, 0, 0 ) ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_display_switched_locked_msg function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Displays a HUD message indicating a switch is blocked -- -- Usage: -- drx_ql_display_switched_locked_msg( ) -- -- Parameters: -- none -- -- External strings: -- drx_ql_strings.xml -- drx_ql_str_switch_locked (type: string) -- - Message to display when a switch is blocked -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified October 08, 2019 -- ------------------------------------------------------------------------------------------------ -- Set up Osoznanie bad ending: function drx_ql_display_switched_locked_msg( ) -- Display HUD message: SetHudMsg( game.translate_string( "drx_ql_str_switch_locked" ), 4 ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_osoznanie_bad_ending function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Sets up the Osoznanie bad choice ending -- -- Usage: -- drx_ql_osoznanie_bad_ending( ) -- -- Parameters: -- none -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified October 09, 2019 -- ------------------------------------------------------------------------------------------------ -- Set up Osoznanie bad ending: function drx_ql_osoznanie_bad_ending( ) -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to set up Osoznanie bad ending, db.actor not available" ) return end -- Kill off any companions: for id, squad in pairs( axr_companions.companion_squads ) do 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:kill( ) end end end end -- Teleport actor to Generators: local point = patrol( "warlab_jump_gen_walk" ) local look = patrol( "warlab_jump_gen_look" ) db.actor:set_actor_position( point:point( 0 ) ) local dir = look:point( 0 ):sub( point:point( 0 ) ) db.actor:set_actor_direction( -dir:getH( ) ) -- Give bad ending infoportion: db.actor:give_info_portion( "drx_ql_info_osoznanie_bad_ending" ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_spawn_osoznanie_protectors function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Spawns Osoznanie protectors -- -- Usage: -- drx_ql_spawn_osoznanie_protectors( ) -- -- Parameters: -- none -- -- Persistent storage: -- drx_ql_osoznanie_protector_spawn_num (type: int) -- Current spawn number for Osoznanie protectors -- -- Ini requirements: -- drx\drx_ql_config.ltx -- [osoznanie_settings] -- max_alive (type: int) -- - Maximum number of Osoznanie protectors alive at one time -- [osoznanie_protectors] (type: string, npc name) -- - Osoznanie protectors -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified April 09, 2019 -- ------------------------------------------------------------------------------------------------ -- Spawn Osoznanie protectors: function drx_ql_spawn_osoznanie_protectors( ) -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to spawn Osoznanie protectors, db.actor not available" ) return end -- Get list of Osoznanie protectors: local protectors_list = alun_utils.collect_section( drx_ql_ini, "osoznanie_protectors" ) if ( (not protectors_list) or (#protectors_list < 1) ) then printf( "DRX QL Error: Unable to spawn Osoznanie protectors, no protectors specified" ) return end -- Get current spawn number local spawn_num = utils.load_var( db.actor, "drx_ql_osoznanie_protector_spawn_num", 0 ) -- Clean up corpses: local num_alive = 0 local hud = get_hud() if ( spawn_num > 0 ) then for i = 1, ( spawn_num ) do local protector_id = get_story_object_id( protectors_list[i] ) if ( protector_id ) then local se_obj = alife( ):object( protector_id ) if ( se_obj ) then if ( se_obj:alive( ) ) then num_alive = (num_alive + 1) else if (hud) then hud:HideActorMenu() end alife( ):release( se_obj ) end end end end end -- Check if max alive is exceeded: if ( num_alive >= (drx_ql_ini:r_float_ex( "osoznanie_settings", "max_alive" ) or 0) ) then return end -- Increment the current spawn number: spawn_num = (spawn_num + 1) if ( spawn_num > #protectors_list ) then return end -- Spawn the protector: spawn_object( nil, nil, {protectors_list[spawn_num], "oso_walk", 0} ) -- Store the current spawn number: utils.save_var( db.actor, "drx_ql_osoznanie_protector_spawn_num", spawn_num ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_ql_kill_osoznanie_protectors function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Kills Osoznanie protectors -- -- Usage: -- drx_ql_kill_osoznanie_protectors( ) -- -- Parameters: -- none -- -- Persistent storage: -- drx_ql_osoznanie_protector_spawn_num (type: int) -- Current spawn number for Osoznanie protectors -- -- Ini requirements: -- drx\drx_ql_config.ltx -- [osoznanie_protectors] (type: string, npc name) -- - Osoznanie protectors -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Questlines 2.0 -- Last modified April 09, 2019 -- ------------------------------------------------------------------------------------------------ -- Kill off Osoznanie protectors: function drx_ql_kill_osoznanie_protectors( ) -- Verify db.actor is available: if ( not db.actor ) then printf( "DRX QL Error: Unable to kill Osoznanie protectors, db.actor not available" ) return end -- Get list of Osoznanie protectors: local protectors_list = alun_utils.collect_section( drx_ql_ini, "osoznanie_protectors" ) if ( (not protectors_list) or (#protectors_list < 1) ) then return end -- Get current spawn number local spawn_num = utils.load_var( db.actor, "drx_ql_osoznanie_protector_spawn_num", 0 ) if ( spawn_num > #protectors_list ) then printf( "DRX QL Error: Unable to kill Osoznanie protectors, stored spawn number greater than available spawns" ) return end -- Kill off protectors in reverse spawn order: for i = spawn_num, 1, -1 do kill_npc( nil, nil, {protectors_list[i]} ) end -- Store the current spawn number: utils.save_var( db.actor, "drx_ql_osoznanie_protector_spawn_num", 0 ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- drx_cz_play_music_looped function -- -- ------------------------------------------------------------------------------------------------ -- -- Description: -- - Plays a looped music track -- - Modification of play_sound_looped (CoC 1.5b r4) -- -- Usage: -- drx_cz_play_music_looped( p[1] ) -- -- Parameters: -- p[1] (type: string, sound theme) -- -- Looped sound theme to play (defined in configs\misc\sound\script_sound.ltx) -- -- Return value (type: nil): -- none -- -- ------------------------------------------------------------------------------------------------ -- Created by DoctorX -- for DoctorX Call of The Zone 1.1 -- Last modified May 29, 2020 -- ------------------------------------------------------------------------------------------------ -- Play looped music: function drx_cz_play_music_looped( actor, obj, p ) -- Get music volume setting: local music_vol = get_console( ):get_float( "snd_volume_music" ) -- Play looped music: local theme = p[1] xr_sound.play_sound_looped( obj:id( ), theme ) xr_sound.set_volume_sound_looped( obj:id( ), theme, music_vol ) -- Set return value: return end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ -- Initialize a task to find a faction stayed at a smart anywhere on actor current level. ID of smart is tracked in pstor by a given var name -- param 1 - var name -- param 2+ - faction a.k.a. squad behavior/player_id function find_smart_under_faction_control(actor,npc,p) if not (p[1]) then return end local target_id for name,smart in pairs(SIMBOARD.smarts_by_names) do if (smart.online) and (smart.sim_avail == nil or xr_logic.pick_section_from_condlist(actor, smart, smart.sim_avail) == "true") then local smrt = SIMBOARD.smarts[smart.id] if (smrt) then for k,squad in pairs(smrt.squads) do if (squad and squad.stay_time and squad.current_target_id and squad.current_target_id == smart.id and not squad:get_script_target()) then for i=2,#p do if (p[i] == "monster" and is_squad_monster[squad.player_id] or squad.player_id == p[i]) then utils.save_var(db.actor,p[1],smart.id) return end end end end end end end end -- same as above but checks all levels function find_smart_under_faction_control_ex(actor,npc,p) if not (p[1]) then return end local sim = alife() local gg = game_graph() local actor_level = sim:level_name(gg:vertex(sim:actor().m_game_vertex_id):level_id()) local target_id for name,smart in pairs(SIMBOARD.smarts_by_names) do if (smart.sim_avail == nil or xr_logic.pick_section_from_condlist(actor, smart, smart.sim_avail) == "true") then local smrt = SIMBOARD.smarts[smart.id] if (smrt) then for k,squad in pairs(smrt.squads) do if (squad and squad.current_target_id and squad.current_target_id == smart.id and not squad:get_script_target()) then for i=2,#p do if (p[i] == "monster" and is_squad_monster[squad.player_id] or squad.player_id == p[i]) then utils.save_var(db.actor,p[1],smart.id) return end end end end end end end end -- remove a companion squad by story id function remove_task_companion(actor,npc,p) local squad = p[1] and get_story_squad(p[1]) if not (squad) then return end squad.scripted_target = nil squad.current_action = nil axr_companions.companion_squads[squad.id] = nil for k in squad:squad_members() do local npc = k.id and (db.storage[k.id] and db.storage[k.id].object or level.object_by_id(k.id)) if (npc) then axr_logic.restore_scheme_and_logic(npc) npc:disable_info_portion("npcx_is_companion") npc:disable_info_portion("npcx_beh_cannot_dismiss") utils.se_obj_save_var(k.id,k.object:name(),"companion",nil) utils.se_obj_save_var(k.id,k.object:name(),"companion_cannot_dismiss",nil) utils.se_obj_save_var(k.id,k.object:name(),"companion_cannot_teleport",nil) end end end function add_task_companion(actor,npc,p) local squad = p[1] and get_story_squad(p[1]) if not (squad) then return end axr_companions.companion_squads[squad.id] = squad for k in squad:squad_members() do local npc = k.id and (db.storage[k.id] and db.storage[k.id].object) if (npc) then utils.se_obj_save_var(k.id,k.object:name(),"companion",true) utils.se_obj_save_var(k.id,k.object:name(),"companion_cannot_dismiss",true) utils.se_obj_save_var(k.id,k.object:name(),"companion_cannot_teleport",nil) axr_companions.setup_companion_logic(npc,db.storage[k.id],false,true) end end end function inc_task_stage(actor,npc,p) local tsk = p[1] and task_manager.get_task_manager().task_info[p[1]] if (tsk and tsk.stage) then --printf("inc_task_stage=%s stage=%s",p[1],tsk.stage) tsk.stage = tsk.stage + 1 end end function dec_task_stage(actor,npc,p) local tsk = p[1] and task_manager.get_task_manager().task_info[p[1]] if (tsk and tsk.stage) then tsk.stage = tsk.stage - 1 end end function set_smart_faction(actor,npc,p) local smart = p and p[1] and SIMBOARD.smarts_by_names[p[1]] if not (smart) then return false end smart.faction = p[2] end --param 1 task_id --param 2+ factions that can be targetted; can be list function on_init_bounty_hunt(actor,npc,p) axr_task_manager.bounties_by_id[p[1]] = nil local valid_targets = {} local size_t = 0 local sim = alife() local comm local sfind = string.find local faction_lookup = {} for i=2,#p do faction_lookup[p[i]] = true end for i=1,65534 do local se_obj = sim:object(i) -- find random sim stalker if (se_obj and IsStalker(nil,se_obj:clsid()) and se_obj:alive() and sfind(se_obj:section_name(),"sim_default") and get_object_story_id(i) == nil) and (se_obj.group_id == nil or se_obj.group_id == 65535 or get_object_story_id(se_obj.group_id) == nil) then comm = alife_character_community(se_obj) if (faction_lookup[comm] == true) then size_t = size_t + 1 valid_targets[size_t] = i end end end if (size_t <= 0) then printf("on_init_bounty_hunt failed, no targets") return end local target_id = valid_targets[math.random(size_t)] if not(target_id) then return end axr_task_manager.bounties_by_id[p[1]] = target_id --printf("on_init_bounty_hunt %s",target_id) --utils.save_var(db.actor,p[1],target_id) local function postpone_for_next_frame(target_id) local se_obj = sim:object(target_id) if (se_obj) then local news_caption = game.translate_string(task_manager.task_ini:r_string_ex(p[1], "title")) or "error" local news_text = game.translate_string("st_mm_faction_cap_character_name") .. " " .. se_obj:character_name() .. "\\n " .. game.translate_string("st_mm_faction_cap_faction") .. " " .. game.translate_string(se_obj:community()) .. "\\n " .. game.translate_string("st_ui_pda_legend_primary_objects_tips") .. " " .. game.translate_string(alife():level_name(game_graph():vertex(se_obj.m_game_vertex_id):level_id())) db.actor:give_talk_message2(news_caption, news_text, se_obj:character_icon(), "iconed_answer_item") end return true end CreateTimeEvent(0,"on_init_bounty_hunt",0,postpone_for_next_frame,target_id) end function disable_meet_nimble_info() db.actor:disable_info_portion("actor_meet_nimble_room") end function fail_task_dec_goodwill(actor,npc,p) local amt = tonumber(p[1]) or 50 for i=2,#p do inc_faction_goodwill_to_actor(db.actor, nil, {p[i], -(amt)}) end end -- param1 - amount of goodwill to increase -- param2+ - community function complete_task_inc_goodwill(actor,npc,p) local amt = tonumber(p[1]) or 50 for i=2,#p do inc_faction_goodwill_to_actor(db.actor, nil, {p[i], amt}) end end function reward_money(actor,npc,p) dialogs.relocate_money(db.actor,tonumber(p[1] or 500),"in") end function reward_stash(actor,npc,p) local chance = 0.4 local chancee = 0.3 if (has_alife_info("achieved_rag_and_bone")) then chance = chance + 0.2 chancee = chancee + 0.2 end if (p and p[1] ~= "true") or ((math.random(1,100)/100) <= chance) then local bonus if ((math.random(1,100)/100) <= chancee) then local t = {"itm_repairkit_tier_1","itm_repairkit_tier_1","itm_repairkit_tier_1","itm_repairkit_tier_2","itm_repairkit_tier_2","itm_repairkit_tier_3", "itm_gunsmith_toolkit", "itm_gunsmith_toolkit", "itm_outfit_toolkit", "itm_outfit_toolkit", "detector_elite", "equ_military_pack"} bonus = {t[math.random(#t)]} end coc_treasure_manager.create_random_stash(nil, "st_reward_stash", bonus) end end function reward_item_cost_mult_and_remove(actor,npc,p) local sec = utils.load_var(db.actor,p[1]) if not (sec) then return end local item = db.actor:object(sec) if not (item) then return end dialogs.relocate_money(db.actor, math.floor((tonumber(p[2]) or 1)*item:cost()) ,"in") remove_item(actor, npc, {sec,p[3]}) end function reward_weapon_cost_mult_and_remove(actor,npc,p) local sec = utils.load_var(db.actor,p[1]) if not (sec) then return end local item = db.actor:object(sec) if not (item) then return end local cond = item:condition() dialogs.relocate_money(db.actor, math.floor((tonumber(p[2]) or 1)*item:cost()*cond) ,"in") remove_item(actor, npc, {sec,p[3]}) end function reward_and_remove(actor,npc,p) local section = utils.load_var(db.actor,p[1]) if not (section) then return end local item = db.actor:object(section) if not (item) then return end if (section and db.actor:object(section)) then local amt = utils.load_var(db.actor,p[1].."_count") or 1 local mult = tonumber(p[2]) or 1 dialogs.relocate_money(db.actor, math.floor(((amt) or 1)*item:cost()*mult) ,"in") remove_item(actor, npc, {section,amt}) end end function reward_random_item(actor,npc,p) if (#p > 0) then local section = p[math.random(#p)] if (system_ini():section_exist(section)) then local se_item = alife():create(section,vector(),0,0,0) local cls = se_item:clsid() if (IsWeapon(nil,cls) and cls ~= clsid.wpn_knife_s) then se_item.condition = math.random(60,90)/100 end news_manager.relocate_item(db.actor, "in", section) end end end function reward_random_money(actor,npc,p) dialogs.relocate_money(db.actor,math.random(tonumber(p[1] or 500),tonumber(p[2] or 1000)),"in") end function remove_special_task_squad(actor,npc,p) level.add_pp_effector("black.ppe", 1313, false) remove_squad(actor,npc,p) end function reset_task_target_anomaly(actor,npc,p) utils.save_var(db.actor,"task_target_anomaly",nil) end -- Spawn a squad that will become actor companion for special tasks -- param 1 - squad section -- param 2 - smart -- param 3 - variable name. Will use smart_id in a pstor variable instead -- param 4 - disable level transition for the squad -- param 5 - is a hostage function setup_companion_task(actor,npc,p) local id = p[3] and p[3] ~= "nil" and utils.load_var(db.actor,p[3]) local smart = id and alife_object(id) or p[2] and p[2] ~= "nil" and SIMBOARD.smarts_by_names[p[2]] if not (smart) then return end if not (system_ini():section_exist(p[1])) then printf("setup_companion_task: Trying to setup companion squad with a non-existent section!") return end local sim = alife() local squad = sim:create(p[1],smart.position,smart.m_level_vertex_id,smart.m_game_vertex_id) squad:create_npc(smart) squad:set_squad_relation() axr_companions.companion_squads[squad.id] = squad for k in squad:squad_members() do local se_obj = k.object or k.id and sim:object(k.id) if (se_obj) then SIMBOARD:setup_squad_and_group(se_obj) utils.se_obj_save_var(se_obj.id,se_obj:name(),"companion",true) utils.se_obj_save_var(se_obj.id,se_obj:name(),"companion_cannot_dismiss",true) utils.se_obj_save_var(se_obj.id,se_obj:name(),"companion_cannot_teleport",p[4] == "true") if (p[5] == "true") then xrs_kill_wounded.hostage_list[se_obj.id] = smart.id end end end --utils.save_var(db.actor,p[3] or "task_companion_slot_1",squad.id) --CreateTimeEvent(0,"add_special_task_squad",5,add_special_task_squad,squad.id,p[4] == "true") end -- setup for special escort to anomaly task function setup_task_target_anomaly(actor,npc,p) local targets = {} for k,v in pairs(db.anomaly_by_name) do targets[#targets+1] = k end if (#targets <= 0) then return end local target_name = targets[math.random(#targets)] utils.save_var(db.actor,"task_target_anomaly",target_name) end -- param1 - variable name -- param2 - count -- param3+ - sections function setup_generic_fetch_task(actor,npc,p) if (p[1] and p[2] and p[3]) then local sec = DIALOG_LAST_ID and DIALOG_LAST_ID == inventory_upgrades.victim_id and utils.load_var(db.actor,p[1]) DIALOG_LAST_ID = inventory_upgrades.victim_id if (sec and system_ini():section_exist(sec)) then dialogs._FETCH_TEXT = game.translate_string(system_ini():r_string_ex(sec,"inv_name") or "") else sec = #p > 3 and p[math.random(3,#p)] or p[3] if (sec and system_ini():section_exist(sec)) then utils.save_var(db.actor,p[1],sec) local count = tonumber(p[2]) or 1 if (count > 1) then utils.save_var(db.actor,p[1].."_count",count) end dialogs._FETCH_TEXT = game.translate_string(system_ini():r_string_ex(sec,"inv_name") or "") else printf("ERROR: xr_effects:setup_generic_fetch_task - invalid section %s",sec) end end end end -- param1 - variable name -- param2 - min count -- param3 - max count -- param4+ - sections function setup_generic_fetch_task_random(actor,npc,p) if (p[1] and p[2] and p[3] and p[4]) then local sec = DIALOG_LAST_ID and DIALOG_LAST_ID == inventory_upgrades.victim_id and utils.load_var(db.actor,p[1]) DIALOG_LAST_ID = inventory_upgrades.victim_id if (sec and system_ini():section_exist(sec)) then dialogs._FETCH_TEXT = game.translate_string(system_ini():r_string_ex(sec,"inv_name") or "") else sec = #p > 4 and p[math.random(4,#p)] or p[4] if (sec and system_ini():section_exist(sec)) then utils.save_var(db.actor,p[1],sec) local count = tonumber(p[2]) or 1 if (count > 1) then utils.save_var(db.actor,p[1].."_count",math.random(p[2] and tonumber(p[2]) or 1,p[3] and tonumber(p[3]) or 1)) end dialogs._FETCH_TEXT = game.translate_string(system_ini():r_string_ex(sec,"inv_name") or "") else printf("ERROR: xr_effects:setup_generic_fetch_task - invalid section %s",sec) end end end end -- param1 - variable name function setup_rare_mutant_fetch_task(actor,npc,p) local part = DIALOG_LAST_ID and DIALOG_LAST_ID == inventory_upgrades.victim_id and utils.load_var(db.actor,p[1]) DIALOG_LAST_ID = inventory_upgrades.victim_id if (part and system_ini():section_exist(part)) then dialogs._FETCH_TEXT = game.translate_string(system_ini():r_string_ex(part,"inv_name") or "") else local parts = { "mutant_part_controller_glass", "mutant_part_controller_hand", "mutant_part_burer_hand", "mutant_part_pseudogigant_eye", "mutant_part_pseudogigant_hand", "mutant_part_chimera_claw", "mutant_part_chimera_kogot" } part = parts[math.random(#parts)] utils.save_var(db.actor,p[1],part) dialogs._FETCH_TEXT = game.translate_string(system_ini():r_string_ex(part,"inv_name") or "") end end -- param1 - variable name function setup_artefact_fetch_task(actor,npc,p) local artefact = DIALOG_LAST_ID and DIALOG_LAST_ID == inventory_upgrades.victim_id and utils.load_var(db.actor,p[1]) DIALOG_LAST_ID = inventory_upgrades.victim_id if (artefact and system_ini():section_exist(artefact)) then dialogs._FETCH_TEXT = game.translate_string(system_ini():r_string_ex(artefact,"inv_name") or "") else local arts = { "af_cristall", "af_fireball", "af_dummy_glassbeads", "af_eye", "af_fire", "af_medusa", "af_cristall_flower", "af_night_star", "af_vyvert", "af_gravi", "af_gold_fish", "af_blood", "af_mincer_meat", "af_soul", "af_fuzz_kolobok", "af_baloon", "af_glass", "af_electra_sparkler", "af_electra_flash", "af_electra_moonlight", "af_dummy_battery", "af_dummy_dummy", "af_ice", -- IWP -- "af_ameba_slime", "af_ameba_slug", "af_drops", "af_dummy_spring", "af_rusty_thorn", "af_rusty_kristall", "af_cocoon", "af_fountain", "af_repei", "af_skull_miser", "af_generator", "af_fonar", "af_tapeworm", "af_zelonka", "af_kashtan", "amk_yoyo", "amk_ice_s", "af_plenka", "amk_cristal_drops", "af_fire_loop", "af_spaika", "af_bat", "af_chelust", "af_kislushka", "af_ball", "af_elektron", "amk_snezhok", "af_gauss" } artefact = arts[math.random(#arts)] utils.save_var(db.actor,p[1],artefact) dialogs._FETCH_TEXT = game.translate_string(system_ini():r_string_ex(artefact,"inv_name") or "") end end function setup_weapon_fetch_task(actor,npc,p) local wpn = DIALOG_LAST_ID and DIALOG_LAST_ID == inventory_upgrades.victim_id and utils.load_var(db.actor,p[1]) DIALOG_LAST_ID = inventory_upgrades.victim_id if (wpn and system_ini():section_exist(wpn)) then dialogs._FETCH_TEXT = game.translate_string(system_ini():r_string_ex(wpn,"inv_name") or "") else local itm = { -- "wpn_bm16", "wpn_toz34", "wpn_wincheaster1300", "wpn_spas12", "wpn_protecta", "wpn_ak74u", "wpn_mp5", "wpn_ak74", "wpn_abakan", "wpn_l85", "wpn_lr300", "wpn_sig550", "wpn_groza", "wpn_val", "wpn_vintorez", "wpn_svu", "wpn_svd", -- "wpn_rg-6", "wpn_rpg7", "wpn_g36", "wpn_fn2000", "wpn_pkm", -- IWP -- "wpn_ak103", "wpn_aug", "wpn_b725", "wpn_bm16_full", "wpn_bizon", "wpn_coltm45a1", "wpn_desert_eagle", "wpn_dvl_10", "wpn_fiveseven", "wpn_galil", "wpn_galil31", "wpn_glock", "wpn_glock18", "wpn_m249", "wpn_m320", "wpn_m700", "wpn_mdr", "wpn_mosin", -- "wpn_mp43", "wpn_mp43_full", "wpn_mp133", "wpn_mp153", "wpn_mp9", "wpn_p90", "wpn_rgm40", "wpn_rpk74", "wpn_rpk74m", "wpn_rpk16", "wpn_sa58", "wpn_saiga12", "wpn_scarh", "wpn_sks", "wpn_sr1m", "wpn_sr2m", "wpn_sv98", "wpn_vityaz", "wpn_usp", "wpn_sig220", "wpn_pm_actor", "wpn_vpo101" } wpn = itm[math.random(#itm)] dialogs._FETCH_TEXT = game.translate_string(system_ini():r_string_ex(wpn,"inv_name") or "") utils.save_var(db.actor,p[1],wpn) end end -- param 1 - var name -- param 2 - min count -- param 3 - max count function setup_supplies_fetch_task(actor,npc,p) local itm = DIALOG_LAST_ID and DIALOG_LAST_ID == inventory_upgrades.victim_id and utils.load_var(db.actor,p[1]) DIALOG_LAST_ID = inventory_upgrades.victim_id if (itm and system_ini():section_exist(itm)) then dialogs._FETCH_TEXT = game.translate_string(system_ini():r_string_ex(itm,"inv_name") or "") else local itms = { "bandage", "antirad", "medkit", "medkit_army", "medkit_scientic", "drug_booster", "drug_coagulant", "drug_psy_blockade", "drug_antidot", "drug_radioprotector", "drug_anabiotic", "bread", "kolbasa", "conserva", "vodka", "energy_drink", -- IWP -- "energy_drink1", "snickers", "flyaga", "flyaga1", "mineral_water", "drug_sleep" } itm = itms[math.random(#itms)] dialogs._FETCH_TEXT = game.translate_string(system_ini():r_string_ex(itm,"inv_name") or "") utils.save_var(db.actor,p[1],itm) utils.save_var(db.actor,p[1].."_count",math.random(p[2] and tonumber(p[2]) or 1,p[3] and tonumber(p[3]) or 1)) end end function remove_fetch_item(actor,npc,p) local section = utils.load_var(db.actor,p[1]) if (section and db.actor:object(section)) then local amt = p[2] or utils.load_var(db.actor,p[1].."_count") or 1 remove_item(actor, npc, {section,amt}) end end function force_talk(actor,npc,p) local allow_break = p[1] and p[1] == "true" or false db.actor:run_talk_dialog(npc, allow_break) end function unlock_smart(actor,npc,p) local id = p[1] and p[1] ~= "nil" and utils.load_var(db.actor,p[1]) local smart = id and alife_object(id) if (smart) then smart.locked = nil end end -- Ïðèíóäèòåëüíî àïäåéòèò ëîãèêó ó îáúåêòîâ, ïåðåäàííûõ ïàðàìåòðîì. Ïîêà ðàáîòàåò òîëüêî ñ ÍÏÑ function update_npc_logic(actor, object, p) --printf("UPDATE NPC LOGIC %s", device():time_global()) for k,v in pairs(p) do local npc = get_story_object(v) if npc ~= nil then xr_motivator.update_logic(npc) local planner = npc:motivation_action_manager() planner:update() planner:update() planner:update() db.storage[npc:id()].state_mgr:update() db.storage[npc:id()].state_mgr:update() db.storage[npc:id()].state_mgr:update() db.storage[npc:id()].state_mgr:update() db.storage[npc:id()].state_mgr:update() db.storage[npc:id()].state_mgr:update() db.storage[npc:id()].state_mgr:update() end end end function update_obj_logic(actor, object, p) --printf("UPDATE OBJ LOGIC %s", device():time_global()) for k,v in pairs(p) do local obj = get_story_object(v) if obj ~= nil then local st = db.storage[obj:id()] xr_logic.try_switch_to_another_section(obj, st[st.active_scheme], actor) -- if st.active_scheme == "sr_cutscene" then -- st[st.active_scheme].cutscene_action -- end end end end local ui_active_slot = 0 function disable_ui(actor, npc, p) if db.actor:is_talking() then db.actor:stop_talk() end level.show_weapon(false) if not p or (p and p[1] ~= "true") then local slot = db.actor:active_slot() if(slot~=0) then ui_active_slot = slot db.actor:activate_slot(0) end end level.disable_input() level.hide_indicators_safe() local hud = get_hud() if (hud) then hud:HideActorMenu() hud:HidePdaMenu() end disable_actor_nightvision(nil,nil) disable_actor_torch(nil,nil) end local animator_restored_slot = -1 function disable_anabiotic(actor, npc, p) if db.actor:is_talking() then db.actor:stop_talk() end if db.actor:is_hud_animator_active() then animator_restored_slot = db.actor:get_hud_animator_restored_slot() end if not p or (p and p[1] ~= "true") then local slot = db.actor:active_slot() if(slot~=0) then ui_active_slot = slot db.actor:activate_slot(0) end end level.disable_input() level.hide_indicators_safe() local hud = get_hud() if (hud) then hud:HideActorMenu() hud:HidePdaMenu() end disable_actor_nightvision(nil,nil) end function disable_ui_only(actor, npc) if db.actor:is_talking() then db.actor:stop_talk() end level.show_weapon(false) if not p or (p and p[1] ~= "true") then local slot = db.actor:active_slot() if(slot~=0) then ui_active_slot = slot db.actor:activate_slot(0) end end level.disable_input() level.hide_indicators_safe() local hud = get_hud() if (hud) then hud:HideActorMenu() hud:HidePdaMenu() end disable_actor_nightvision(nil,nil) end function disable_ui_change_level(actor, npc) if db.actor:is_talking() then db.actor:stop_talk() end local cons = get_console() _G.mus_vol = cons:get_float("snd_volume_music") _G.amb_vol = cons:get_float("snd_volume_eff") cons:execute("snd_volume_music 0") cons:execute("snd_volume_eff 0") level.disable_input() level.hide_indicators_safe() local hud = get_hud() if (hud) then hud:HideActorMenu() hud:HidePdaMenu() end end function disable_nv(actor, npc) if db.actor:is_talking() then db.actor:stop_talk() end level.show_weapon(false) if not p or (p and p[1] ~= "true") then local slot = db.actor:active_slot() if(slot~=0) then ui_active_slot = slot db.actor:activate_slot(0) end end disable_actor_nightvision(nil,nil) disable_actor_torch(nil,nil) end function disable_ui_lite_with_imput(actor, npc) if db.actor:is_talking() then db.actor:stop_talk() end level.show_weapon(false) if not p or (p and p[1] ~= "true") then local slot = db.actor:active_slot() if(slot~=0) then ui_active_slot = slot db.actor:activate_slot(0) end end level.disable_input() level.hide_indicators_safe() end function disable_ui_lite(actor, npc) if db.actor:is_talking() then db.actor:stop_talk() end level.show_weapon(false) if not p or (p and p[1] ~= "true") then local slot = db.actor:active_slot() if(slot~=0) then ui_active_slot = slot db.actor:activate_slot(0) end end level.hide_indicators_safe() end function disable_ui_inventory(actor, npc) if db.actor:is_talking() then db.actor:stop_talk() end -- level.show_weapon(false) if not p or (p and p[1] ~= "true") then local slot = db.actor:active_slot() if(slot~=0) then ui_active_slot = slot db.actor:activate_slot(0) end end local hud = get_hud() if (hud) then hud:HidePdaMenu() hud:HideActorMenu() end end function enable_ui(actor, npc, p) --db.actor:restore_weapon() if not p or (p and p[1] ~= "true") then if ui_active_slot ~= 0 and db.actor:item_in_slot(ui_active_slot) ~= nil then db.actor:activate_slot(ui_active_slot) end end ui_active_slot = 0 level.enable_input() level.show_weapon(true) level.show_indicators() enable_actor_nightvision(nil,nil) enable_actor_torch(nil,nil) end function enable_ui_anabiotic(actor, npc, p) if animator_restored_slot ~= -1 then db.actor:activate_slot(animator_restored_slot) animator_restored_slot = -1 end --if not p or (p and p[1] ~= "true") then -- if ui_active_slot ~= 0 and db.actor:item_in_slot(ui_active_slot) ~= nil then -- db.actor:activate_slot(ui_active_slot) -- end --end ui_active_slot = 0 level.enable_input() level.show_weapon(true) level.show_indicators() enable_actor_nightvision(nil,nil) enable_actor_torch(nil,nil) end function enable_ui_lite_with_imput(actor, npc, p) --db.actor:restore_weapon() if not p or (p and p[1] ~= "true") then if ui_active_slot ~= 0 and db.actor:item_in_slot(ui_active_slot) ~= nil then db.actor:activate_slot(ui_active_slot) end end ui_active_slot = 0 level.enable_input() level.show_weapon(true) level.show_indicators() enable_actor_nightvision(nil,nil) enable_actor_torch(nil,nil) end function enable_ui_lite(actor, npc, p) --db.actor:restore_weapon() if not p or (p and p[1] ~= "true") then if ui_active_slot ~= 0 and db.actor:item_in_slot(ui_active_slot) ~= nil then db.actor:activate_slot(ui_active_slot) end end ui_active_slot = 0 level.enable_input() level.show_weapon(true) level.show_indicators() enable_actor_nightvision(nil,nil) enable_actor_torch(nil,nil) end function enable_nv_and_imput(actor, npc, p) --db.actor:restore_weapon() if not p or (p and p[1] ~= "true") then if ui_active_slot ~= 0 and db.actor:item_in_slot(ui_active_slot) ~= nil then db.actor:activate_slot(ui_active_slot) end end level.enable_input() enable_actor_nightvision(nil,nil) enable_actor_torch(nil,nil) end function enable_nv(actor, npc, p) --db.actor:restore_weapon() if not p or (p and p[1] ~= "true") then if ui_active_slot ~= 0 and db.actor:item_in_slot(ui_active_slot) ~= nil then db.actor:activate_slot(ui_active_slot) end end enable_actor_nightvision(nil,nil) enable_actor_torch(nil,nil) end local cam_effector_playing_object_id = nil function run_cam_effector(actor, npc, p) if p[1] then local loop, num = false, (1000 + math.random(100)) if p[2] and type(p[2]) == "number" and p[2] > 0 then num = p[2] end if p[3] and p[3] == "true" then loop = true end --level.add_pp_effector(p[1] .. ".ppe", num, loop) level.add_cam_effector("camera_effects\\" .. p[1] .. ".anm", num, loop, "xr_effects.cam_effector_callback") cam_effector_playing_object_id = npc:id() end end function stop_cam_effector(actor, npc, p) if p[1] and type(p[1]) == "number" and p[1] > 0 then level.remove_cam_effector(p[1]) end end function run_cam_effector_global(actor, npc, p) local num = 1000 + math.random(100) if p[2] and type(p[2]) == "number" and p[2] > 0 then num = p[2] end local fov = device().fov if p[3] ~= nil and type(p[3]) == "number" then fov = p[3] end level.add_cam_effector2("camera_effects\\" .. p[1] .. ".anm", num, false, "xr_effects.cam_effector_callback", fov) cam_effector_playing_object_id = npc:id() end function cam_effector_callback() if cam_effector_playing_object_id == nil then printf("cam_eff:callback1!") return end local st = db.storage[cam_effector_playing_object_id] if st == nil or st.active_scheme == nil then printf("cam_eff:callback2!") return end if st[st.active_scheme].signals == nil then printf("cam_eff:callback3!") return end st[st.active_scheme].signals["cameff_end"] = true end function run_postprocess(actor, npc, p) if (p[1]) then if(system_ini():section_exist(p[1])) then local num = 2000 + math.random(100) if(p[2] and type(p[2]) == "number" and p[2]>0) then num = p[2] end printf("adding complex effector [%s], id [%s], from [%s]", p[1], tostring(p[2]), tostring(npc:name())) level.add_complex_effector(p[1], num) else printf("Complex effector section is no set! [%s]", tostring(p[1])) end end end function stop_postprocess(actor, npc, p) if(p[1] and type(p[1]) == "number" and p[1]>0) then printf("removing complex effector id [%s] from [%s]", tostring(p[1]), tostring(npc:name())) level.remove_complex_effector(p[1]) end end function run_tutorial(actor, npc, p) --printf("run tutorial called") game.start_tutorial(p[1]) end --[[ function run_tutorial_if_newbie(actor, npc, p) if has_alife_info("esc_trader_newbie") then game.start_tutorial(p[1]) end end ]]-- function jup_b32_place_scanner(actor, npc) for i = 1, 5 do if xr_conditions.actor_in_zone(actor, npc, {"jup_b32_sr_scanner_place_"..i}) and not has_alife_info("jup_b32_scanner_"..i.."_placed") then db.actor:give_info_portion("jup_b32_scanner_"..i.."_placed") db.actor:give_info_portion("jup_b32_tutorial_done") remove_item(actor, npc, {"jup_b32_scanner_device"}) spawn_object(actor, nil, {"jup_b32_ph_scanner","jup_b32_scanner_place_"..i}) end end end function jup_b32_pda_check(actor, npc) end function pri_b306_generator_start(actor, npc) if xr_conditions.actor_in_zone(actor, npc, {"pri_b306_sr_generator"}) then give_info("pri_b306_lift_generator_used") end end function jup_b206_get_plant(actor, npc) if xr_conditions.actor_in_zone(actor, npc, {"jup_b206_sr_quest_line"}) then give_info("jup_b206_anomalous_grove_has_plant") give_actor(actor, npc, {"jup_b206_plant"}) destroy_object(actor, npc, {"story", "jup_b206_plant_ph"}) end end function pas_b400_switcher(actor, npc) if xr_conditions.actor_in_zone(actor, npc, {"pas_b400_sr_switcher"}) then give_info("pas_b400_switcher_use") end end function jup_b209_place_scanner(actor, npc) if xr_conditions.actor_in_zone(actor, npc, {"jup_b209_hypotheses"}) then scenario_autosave(db.actor, nil, {"st_save_jup_b209_placed_mutant_scanner"}) db.actor:give_info_portion("jup_b209_scanner_placed") remove_item(actor, npc, {"jup_b209_monster_scanner"}) spawn_object(actor, nil, {"jup_b209_ph_scanner","jup_b209_scanner_place_point"}) end end function jup_b9_heli_1_searching(actor, npc) if xr_conditions.actor_in_zone(actor, npc, {"jup_b9_heli_1"}) then db.actor:give_info_portion("jup_b9_heli_1_searching") end end function pri_a18_use_idol(actor, npc) if xr_conditions.actor_in_zone(actor, npc, {"pri_a18_use_idol_restrictor"}) then db.actor:give_info_portion("pri_a18_run_cam") end end function jup_b8_heli_4_searching(actor, npc) if xr_conditions.actor_in_zone(actor, npc, {"jup_b8_heli_4"}) then db.actor:give_info_portion("jup_b8_heli_4_searching") end end function jup_b10_ufo_searching(actor, npc) if xr_conditions.actor_in_zone(actor, npc, {"jup_b10_ufo_restrictor"}) then db.actor:give_info_portion("jup_b10_ufo_memory_started") give_actor(db.actor,nil,{"jup_b10_ufo_memory"}) end end function zat_b101_heli_5_searching(actor, npc) if xr_conditions.actor_in_zone(actor, npc, {"zat_b101_heli_5"}) then db.actor:give_info_portion("zat_b101_heli_5_searching") end end function zat_b28_heli_3_searching(actor, npc) if xr_conditions.actor_in_zone(actor, npc, {"zat_b28_heli_3"}) then db.actor:give_info_portion("zat_b28_heli_3_searching") end end function zat_b100_heli_2_searching(actor, npc) if xr_conditions.actor_in_zone(actor, npc, {"zat_b100_heli_2"}) then db.actor:give_info_portion("zat_b100_heli_2_searching") end end function teleport_actor(actor, npc, p) local point = patrol(p[1]) if not (point) then printf("xr_effects.teleport_actor no patrol path %s exists!",p[1]) return end local dir if p[2] ~= nil then local look = patrol(p[2]) dir = -look:point(0):sub(point:point(0)):getH() db.actor:set_actor_direction(dir) end for k,v in pairs(db.no_weap_zones) do if utils.npc_in_zone(db.actor, k) then db.no_weap_zones[k] = true end end if npc and npc:name() ~= nil then printf("teleporting actor from [%s]", tostring(npc:name())) end db.actor:set_actor_position(point:point(0)) end local function reset_animation(npc) local state_mgr = db.storage[npc:id()].state_mgr if state_mgr == nil then return end local planner = npc:motivation_action_manager() state_mgr.animation:set_state(nil, true) state_mgr.animation:set_control() state_mgr.animstate:set_state(nil, true) state_mgr.animstate:set_control() state_mgr:set_state("idle", nil, nil, nil, {fast_set = true}) -- planner:update() -- planner:update() -- planner:update() state_mgr:update() state_mgr:update() state_mgr:update() state_mgr:update() state_mgr:update() state_mgr:update() state_mgr:update() npc:set_body_state(move.standing) npc:set_mental_state(anim.free) end function teleport_npc_lvid(actor,npc,p) local vid = tonumber(p[1]) if not (vid) then return end local position = level.vertex_position(vid) if (p[2]) then local obj = get_story_object(p[2]) if (obj) then obj:set_npc_position(position) end return end npc:set_npc_position(position) end function teleport_npc_pos(actor,npc,p) for i=1,3 do p[i] = string.gsub(p[i],"n","-") end local pos = vector():set(tonumber(p[1]),tonumber(p[2]),tonumber(p[3])) if not (pos) then return end if (p[4]) then local obj = get_story_object(p[4]) if (obj) then obj:set_npc_position(pos) end return end npc:set_npc_position(pos) end function teleport_squad_lvid(actor,npc,p) local vid = tonumber(p[1]) if not (vid) then return end local squad = p[2] and get_story_squad(p[2]) or get_object_squad(npc) if not (squad) then return end local position = level.vertex_position(vid) squad:set_squad_position(position) end function teleport_npc(actor, npc, p) if not (p[1]) then return end local position = patrol(p[1]):point(tonumber(p[2]) or 0) --reset_animation(npc) npc:set_npc_position(position) end function teleport_npc_by_story_id(actor, npc, p) local story_id = p[1] local patrol_point = p[2] local patrol_point_index = p[3] or 0 if story_id == nil or patrol_point == nil then printf("Wrong parameters in 'teleport_npc_by_story_id' function!!!") end local position = patrol(tostring(patrol_point)):point(patrol_point_index) local npc_id = get_story_object_id(story_id) if npc_id == nil then printf("There is no story object with id [%s]", story_id) end local cl_object = level.object_by_id(npc_id) if cl_object then reset_animation(cl_object) cl_object:set_npc_position(position) else alife_object(npc_id).position = position end end function teleport_squad(actor, npc, p) local squad = p[1] and get_story_squad(p[1]) if not (squad) then printf("There is no squad with story id [%s]", p[1]) end local path = patrol(p[2]) if not (path) then printf("Wrong parameters in 'teleport_squad' function!!!") return end local idx = p[3] or 0 TeleportSquad(squad,path:point(idx),path:level_vertex_id(idx),path:game_vertex_id(idx)) --squad:set_squad_position(path:point(idx)) end function jup_teleport_actor(actor, npc) local point_in = patrol("jup_b16_teleport_in"):point(0) local point_out = patrol("jup_b16_teleport_out"):point(0) local actor_position = actor:position() local out_position = vector():set(actor_position.x - point_in.x + point_out.x, actor_position.y - point_in.y + point_out.y , actor_position.z - point_in.z + point_out.z) db.actor:set_actor_position(out_position) end ----------------------------------------------------------------------------- --[[ local drop_point, drop_object = 0, 0 local function drop_object_item(item) drop_object:drop_item_and_teleport(item, drop_point) end function drop_actor_inventory(actor, npc, p) if p[1] then drop_point = patrol(p[1]):point(0) drop_object = actor actor:inventory_for_each(drop_object_item) end end -- FIXME: drop_npc_inventory doesn't work function drop_npc_inventory(actor, npc, p) if p[1] then drop_point = patrol(p[1]):point(0) drop_object = npc npc:inventory_for_each(drop_object_item) end end function drop_npc_item(actor, npc, p) if p[1] then local item = npc:object(p[1]) if item then npc:drop_item(item) end end end function drop_npc_items(actor, npc, p) local item = 0 for i, v in pairs(p) do item = npc:object(v) if item then npc:drop_item(item) end end end ]]-- function give_items(actor, npc, p) local pos, lv_id, gv_id, npc_id = npc:position(), npc:level_vertex_id(), npc:game_vertex_id(), npc:id() for i, v in pairs(p) do alife():create(v, pos, lv_id, gv_id, npc_id) end end function give_item(actor, npc, p) if p[2] ~= nil then npc_id = get_story_object_id(p[2]) else npc_id = npc:id() end local se_npc = alife_object(npc_id) if not (se_npc) then return end local pos, lv_id, gv_id, npc_id = se_npc.position, se_npc.m_level_vertex_id, se_npc.m_game_vertex_id, se_npc.id alife():create(p[1], pos, lv_id, gv_id, npc_id) end function play_particle_on_path(actor, npc, p) local name = p[1] local path = p[2] local point_prob = p[3] if name == nil or path == nil then return end if point_prob == nil then point_prob = 100 end local path = patrol(path) local count = path:count() for a = 0,count-1,1 do local particle = particles_object(name) if math.random(100) <= point_prob then particle:play_at_pos(path:point(a)) end end end ----------------------------------------------------------------------------- --[[ send_tip(news_id:sender:sender_id) 1. news_id 2. sender* 3. sender_id* * - not necessary --]] function send_tip(actor, npc, p) news_manager.send_tip(actor, p[1], nil, p[2], nil, p[3]) end function send_tip_task(actor,npc,p) local tsk = p[1] and task_manager.get_task_manager().task_info[p[1]] if (tsk and p[2]) then news_manager.send_task(actor, p[2], tsk) end end --[[ Äàòü ñòàëêåðó íåáîëüøîé ïèíîê. Íàïðèìåð ÷òîá ñêèíóòü åãî ñ âîçâûøåíèÿ. ïàðàìåòðû: actor, npc, p[direction,bone,power,impulse,reverse=false] 1. direction - åñëè ñòðîêà, òî ñ÷èòàåòñÿ, ÷òî ýòî èìÿ ïóòè è â ñòîðîíó ïåðâîé òî÷êè ïðîèçâîäèòñÿ òîë÷åê. Åñëè æå ýòî ÷èñëî, òî îíî ðàññìàòðèâàåòñÿ êàê story_id ïåðñîíàæà îò êîòîðîãî äîëæåí ïîñòóïèòü õèò. 2. bone - ñòðîêà. Èìÿ êîñòè, ïî êîòîðîé íàíîñèòñÿ óäàð. 3. power - ñèëà óäàðà 4. impulse - èìïóëüñ 5. reverse (true/false) - èçìåíåíèå íàïðàâëåíèÿ óäàðà. ïî óìîë÷àíèþ false --]] function hit_npc(actor, npc, p) local h = hit() local rev = p[6] and p[6] == 'true' h.draftsman = npc h.type = hit.wound if p[1] ~= "self" then local hitter = get_story_object(p[1]) if not hitter then return end if rev then h.draftsman = hitter h.direction = hitter:position():sub(npc:position()) else h.direction = npc:position():sub(hitter:position()) end else if rev then h.draftsman = nil h.direction = npc:position():sub(patrol(p[2]):point(0)) else h.direction = patrol(p[2]):point(0):sub(npc:position()) end end h:bone(p[3]) h.power = p[4] h.impulse = p[5] --printf("HIT EFFECT: (%s, %s,%d,%d) health(%s)", npc:name(), p[2], h.power, h.impulse, npc.health) npc:hit(h) end --[[ Äàòü îáüåêòó, çàäàííîìó story_id, õèò. ïàðàìåòðû: actor, npc, p[sid,bone,power,impulse,hit_src=npc:position()] 1. sid - story_id îáüåêòà, ïî êîòîðîìó íàíîñèòñÿ õèò. 2. bone - ñòðîêà. Èìÿ êîñòè, ïî êîòîðîé íàíîñèòñÿ óäàð. 3. power - ñèëà óäàðà 4. impulse - èìïóëüñ 5. hit_src - åñëè ÷èñëî, òî ðàññìàòðèâàåòñÿ êàê story_id îáüåêòà, ñî ñòîðîíû êîòîðîãî íàíîñèòñÿ õèò (îí æå ÿâëÿåòñÿ è èíèöèàòîðîì õèòà), èíà÷å ýòî òî÷êà (waypoint), èç êîòîðîé ïî îáúåêòó íàíîñèòñÿ õèò. Åñëè íå çàäàíî, òî áåðåòñÿ ïîçèöèÿ îáüåêòà, èç êîòîðîãî áûëà âûçâàíà äàííàÿ ôóíêöèÿ. --]] function hit_obj(actor, npc, p) local h = hit() local obj = get_story_object(p[1]) local sid = nil if not obj then -- printf("HIT_OBJ [%s]. Target object does not exist", npc:name()) return end h:bone(p[2]) h.power = p[3] h.impulse = p[4] if p[5] then sid = get_story_object(sid) if sid then h.direction = vector():sub(sid:position(), obj:position()) end if not sid then h.direction = vector():sub(patrol(p[5]):point(0), obj:position()) end else h.direction = vector():sub(npc:position(), obj:position()) end h.draftsman = sid or npc h.type = hit.wound obj:hit(h) end function hit_obj_chemical(actor, npc, p) local h = hit() local obj = get_story_object(p[1]) local sid = nil if not obj then -- printf("HIT_OBJ [%s]. Target object does not exist", npc:name()) return end h:bone(p[2]) h.power = p[3] h.impulse = p[4] if p[5] then sid = get_story_object(sid) if sid then h.direction = vector():sub(sid:position(), obj:position()) end if not sid then h.direction = vector():sub(patrol(p[5]):point(0), obj:position()) end else h.direction = vector():sub(npc:position(), obj:position()) end h.draftsman = sid or npc h.type = hit.chemical_burn obj:hit(h) end function hit_obj_fire_wound(actor, npc, p) local h = hit() local obj = get_story_object(p[1]) local sid = nil if not obj then -- printf("HIT_OBJ [%s]. Target object does not exist", npc:name()) return end h:bone(p[2]) h.power = p[3] h.impulse = p[4] if p[5] then sid = get_story_object(sid) if sid then h.direction = vector():sub(sid:position(), obj:position()) end if not sid then h.direction = vector():sub(patrol(p[5]):point(0), obj:position()) end else h.direction = vector():sub(npc:position(), obj:position()) end h.draftsman = sid or npc h.type = hit.fire_wound obj:hit(h) end --[[ Äàòü ñòàëêåðó íåáîëüøîé ïèíîê ïîñëå ñìåðòè. Àíàëîãè÷íî ïðåäûäóùåìó, òîëüêî íàïðàâëåíèå õèòà òåïåðü âû÷èñëÿåòñÿ ÷åðåç óáèéöó. Ïîýòîìó ïàðàìåòðà direction íåò. ïàðàìåòðû: actor, npc, p[bone,power,impulse] FIXME: killer:position() isn't working <-(Because you are fucking stupid) --]] function hit_by_killer(actor, npc, p) if not npc then return end local t = db.storage[npc:id()].death if not (t) then return false end if (t.killer == nil or t.killer == -1) then return false end local killer = ( db.storage[t.killer] and db.storage[t.killer].object ) or level.object_by_id(t.killer) if not (killer) then return false end local p1, p2 p1 = npc:position() p2 = killer:position() local h = hit() h.draftsman = npc h.type = hit.wound h.direction = vector():set(p1):sub(p2) h.bone = p[1] h.power = p[2] h.impulse = p[3] npc:hit(h) end function hit_npc_from_actor(actor, npc, p) local h = hit() local sid = nil h.draftsman = actor h.type = hit.wound if p and p[1] then sid = get_story_object(p[1]) if sid then h.direction = actor:position():sub(sid:position()) end if not sid then h.direction = actor:position():sub(npc:position()) end else h.direction = actor:position():sub(npc:position()) sid = npc end h:bone("bip01_spine") h.power = 0.001 h.impulse = 0.001 sid:hit(h) end --[[ -- Õèòóåò íïñ îò íïñ, åñëè çàäàí îäèí ïàðàìåòð (ñòîðè àéäè), òî íïñ ñ òàêèì ñòîðè àéäè õèòíåò íïñ ó êîòîðîãî âûçâàëè ýòó ôóíêöèþ. -- åñëè çàäàíî 2 ñòîðè àéäè , òî íïñ ñ 1-ûì ñòîðè àéäè õèòíåò íïñ ñî 2-ûì ñòîðè àéäè. function hit_npc_from_npc(actor, npc, p) if p == nil then printf("Invalid parameter in function 'hit_npc_from_npc'!!!!") end local h = hit() local hitted_npc = npc h.draftsman = get_story_object(p[1]) if p[2] ~= nil then hitted_npc = get_story_object(p[2]) end h.type = hit.wound h.direction = h.draftsman:position():sub(hitted_npc:position()) h:bone("bip01_spine") h.power = 0.03 h.impulse = 0.03 hitted_npc:hit(h) end function hit_actor(actor, npc, p) local h = hit() h.direction = vector():set(0,0,0) h.draftsman = actor h.type = hit.shock h:bone("bip01_spine") h.power = (p and p[1] and tonumber(p[1])) or 0.001 h.impulse = 0.001 actor:hit(h) end ]]-- function restore_health_portion(actor, npc) local health = npc.health local diff = 1 - health if diff > 0 then npc.health = health + math.random(diff / 2, diff * 0.95) end end function restore_health(actor, npc) --printf("HEALTH RESTORE") npc.health = 1 end function make_enemy(actor, npc, p) --[[ if p == nil then printf("Invalid parameter in function 'hit_npc_from_npc'!!!!") end local h = hit() local hitted_npc = npc h.draftsman = get_story_object(p[1]) if p[2] ~= nil then hitted_npc = get_story_object(p[2]) end h.type = hit.wound h.direction = h.draftsman:position():sub(hitted_npc:position()) h:bone("bip01_spine") h.power = 0.03 h.impulse = 0.03 hitted_npc:hit(h) --]] local npc1 = get_story_object(p[1]) if not (npc1) then return end local npc2 = get_story_object(p[2]) if not (npc2) then return end npc1:set_relation(game_object.enemy,npc2) npc2:set_relation(game_object.enemy,npc1) end function sniper_fire_mode(actor, npc, p) if p[1] == "true" then --printf("SNIPER FIRE MODE ON") npc:sniper_fire_mode(true) else --printf("SNIPER FIRE MODE OFF") npc:sniper_fire_mode(false) end end function kill_npc(actor, npc, p) if p and p[1] then npc = get_story_object(p[1]) end if npc ~= nil and npc:alive() then npc:kill(npc) end end function remove_npc(actor, npc, p) if p and p[1] then npc_id = get_story_object_id(p[1]) end if npc_id ~= nil then local se_obj = alife_object(npc_id) if (se_obj) then safe_release_manager.release(se_obj) --alife():release(se_obj, true) end end end -- ïðèáàâèòü ê óêàçàííîìó ñ÷¸ò÷èêó àêò¸ðà 1 function inc_counter(actor, npc, p) if p and p[1] then local inc_value = p[2] or 1 local new_value = utils.load_var(actor, p[1], 0) + inc_value if npc and npc:name() then printf("inc_counter '%s' to value [%s], by [%s]", p[1], tostring(new_value), tostring(npc:name())) end utils.save_var(actor, p[1], new_value) end end function dec_counter(actor, npc, p) if p and p[1] then local dec_value = p[2] or 1 local new_value = utils.load_var(actor, p[1], 0) - dec_value if new_value < 0 then new_value = 0 end utils.save_var(actor, p[1], new_value) if npc and npc:name() then printf( "dec_counter [%s] value [%s] by [%s]", p[1], utils.load_var(actor, p[1], 0), tostring(npc:name())) end end end function set_counter(actor, npc, p) if p and p[1] then local count = p[2] or 0 -- printf( "set_counter '%s' %s", p[1], count) utils.save_var(actor, p[1], count) -- printf("counter [%s] value [%s]", p[1], utils.load_var(actor, p[1], 0)) end end ------------------------------------------------------------------------------------------------------------------------ -- ïîñòïðîöåññ è âëèÿíèå óäàðà â ìîðäó function actor_punch(npc) if db.actor:position():distance_to_sqr(npc:position()) > 4 then return end set_inactivate_input_time(30) level.add_cam_effector("camera_effects\\fusker.anm", 999, false, "") local active_slot = db.actor:active_slot() if active_slot ~= 2 and active_slot ~= 3 then return end local active_item = db.actor:active_item() if active_item then db.actor:drop_item(active_item) end end -- çàáûâàíèå îáèäû function clearAbuse(npc) printf("CLEAR_ABUSE") xr_abuse.clear_abuse(npc) end function turn_off_underpass_lamps(actor, npc) local lamps_table = { ["pas_b400_lamp_start_flash"] = true, ["pas_b400_lamp_start_red"] = true, ["pas_b400_lamp_elevator_green"] = true, ["pas_b400_lamp_elevator_flash"] = true, ["pas_b400_lamp_elevator_green_1"] = true, ["pas_b400_lamp_elevator_flash_1"] = true, ["pas_b400_lamp_track_green"] = true, ["pas_b400_lamp_track_flash"] = true, ["pas_b400_lamp_downstairs_green"] = true, ["pas_b400_lamp_downstairs_flash"] = true, ["pas_b400_lamp_tunnel_green"] = true, ["pas_b400_lamp_tunnel_flash"] = true, ["pas_b400_lamp_tunnel_green_1"] = true, ["pas_b400_lamp_tunnel_flash_1"] = true, ["pas_b400_lamp_control_down_green"] = true, ["pas_b400_lamp_control_down_flash"] = true, ["pas_b400_lamp_control_up_green"] = true, ["pas_b400_lamp_control_up_flash"] = true, ["pas_b400_lamp_hall_green"] = true, ["pas_b400_lamp_hall_flash"] = true, ["pas_b400_lamp_way_green"] = true, ["pas_b400_lamp_way_flash"] = true, } for k,v in pairs(lamps_table) do local obj = get_story_object(k) if obj then obj:get_hanging_lamp():turn_off() else printf("function 'turn_off_underpass_lamps' lamp [%s] does not exist", tostring(k)) --printf("function 'turn_off_underpass_lamps' lamp [%s] does not exist", tostring(k)) end end end ---Âûêëþ÷åíèå äèíàìè÷åñêîé ëàìïî÷êè (hanging_lamp) function turn_off(actor, npc, p) for k,v in pairs(p) do local obj = get_story_object(v) if not obj then printf("TURN_OFF. Target object with story_id [%s] does not exist", v) return end obj:get_hanging_lamp():turn_off() --printf("TURN_OFF. Target object with story_id [%s] turned off.", v) end end function turn_off_object(actor, npc) npc:get_hanging_lamp():turn_off() end ---Âêëþ÷åíèå äèíàìè÷åñêîé ëàìïî÷êè (hanging_lamp) function turn_on(actor, npc, p) for k,v in pairs(p) do local obj = get_story_object(v) if not obj then printf("TURN_ON [%s]. Target object does not exist", npc:name()) return end obj:get_hanging_lamp():turn_on() end end ---Âêëþ÷åíèå è çàïóñê äèíàìè÷åñêîé ëàìïî÷êè (hanging_lamp) function turn_on_and_force(actor, npc, p) local obj = get_story_object(p[1]) if not obj then printf("TURN_ON_AND_FORCE. Target object does not exist") return end if p[2] == nil then p[2] = 55 end if p[3] == nil then p[3] = 14000 end obj:set_const_force(vector():set(0,1,0), p[2], p[3]) obj:start_particles("weapons\\light_signal", "link") obj:get_hanging_lamp():turn_on() end ---Âûêëþ÷åíèå äèíàìè÷åñêîé ëàìïî÷êè è ïàðòèêëîâ (hanging_lamp) function turn_off_and_force(actor, npc, p) local obj = get_story_object(p[1]) if not obj then printf("TURN_OFF [%s]. Target object does not exist", npc:name()) return end obj:stop_particles("weapons\\light_signal", "link") obj:get_hanging_lamp():turn_off() end function turn_on_object(actor, npc) npc:get_hanging_lamp():turn_on() end function turn_off_object(actor, npc) npc:get_hanging_lamp():turn_off() end -- Âûçîâ ýòîé ôóíêöèè îòêëþ÷èò îáðàáîò÷èê [combat] áîÿ äëÿ ïåðñîíàæà. -- Èñïîëüçóåòñÿ â ñëó÷àÿõ, êîãäà âñå íåîáõîäèìûå äåéñòâèÿ, òàêèå êàê ïåðåêëþ÷åíèå íà äðóãóþ ñåêöèþ, -- óæå âûïîëíåíû, è ïîâòîðíî âûïîëíÿòü èõ âî âðåìÿ áîÿ íåëüçÿ (à óñëîâèÿ ñåêöèè [combat] ïðîâåðÿþòñÿ íà êàæäîì -- àïäåéòå, êîãäà ïåðñîíàæ â áîþ, åñëè, êîíå÷íî, íå îòêëþ÷åíû âûçîâîì ýòîé ôóíêöèè). function disable_combat_handler(actor, npc) if db.storage[npc:id()].combat then db.storage[npc:id()].combat.enabled = false end if db.storage[npc:id()].mob_combat then db.storage[npc:id()].mob_combat.enabled = false end end -- Âûçîâ ýòîé ôóíêöèè îòêëþ÷èò îáðàáîò÷èê [combat_ignore] ïåðåõâàòà áîÿ äëÿ ïåðñîíàæà. function disable_combat_ignore_handler(actor, npc) if db.storage[npc:id()].combat_ignore then db.storage[npc:id()].combat_ignore.enabled = false end end ------------------------------------------------------------------------------------- -- Ôóíêöèè äëÿ ðàáîòû ñ âåðòîë¸òàìè ------------------------------------------------------------------------------------- --[[ function heli_set_enemy_actor(actor, npc) local st = db.storage[npc:id()] if not st.combat.enemy_id and actor:alive() then st.combat.enemy_id = actor:id() heli_snd.play_snd( st, heli_snd.snd_see_enemy, 1 ) end end function heli_set_enemy(actor, npc, p) local st = db.storage[npc:id()] local obj = get_story_object( p[1] ) if not st.combat.enemy_id and obj:alive() then st.combat.enemy_id = obj:id() heli_snd.play_snd( st, heli_snd.snd_see_enemy, 1 ) end end function heli_clear_enemy(actor, npc) db.storage[npc:id()].combat:forget_enemy() end ]]-- function heli_start_flame(actor, npc) bind_heli.heli_start_flame( npc ) end function heli_die(actor, npc) bind_heli.heli_die( npc ) end --'----------------------------------------------------------------------------------- --' Ôóíêöèè äëÿ ðàáîòû ñ ïîãîäíûìè ýôôåêòàìè --'----------------------------------------------------------------------------------- -- Ïðèíóäèòåëüíàÿ óñòàíîâêà ïîãîäíûõ óñëîâèé -- =set_weather(<ñåêöèÿ ïîãîäû>:true) - óñòàíîâêà ïîãîäû ñðàçó, false - ÷åðåç íåêîòîðîå âðåìÿ -- Áóäåò èñïîëüçîâàòüñÿ íà ñòàðòå èãðû Çîâ Ïðèïÿòè è â ñöåíå jup_b15 - óòðî ïîñëå ïüÿíêè ñ Çóëóñîì function set_weather(actor, npc, p) if(p[1]) then if(p[2]=="true") then level.set_weather(p[1],true) else level.set_weather(p[1],false) end end end --[[ function update_weather(actor, npc, p) if p and p[1] then if p[1] == "true" then level_weathers.get_weather_manager():select_weather(true) elseif p[1] == "false" then level_weathers.get_weather_manager():select_weather(false) end end end function start_small_reject(actor, npc) level.set_weather_fx("fx_surge_day_3") level.add_pp_effector("vibros_p.ppe", 1974, false) this.aes_earthshake(npc) end function start_full_reject(actor, npc) level.set_weather_fx("fx_surge_day_3") level.remove_pp_effector(1974) level.remove_cam_effector(1975) level.add_cam_effector("camera_effects\\earthquake.anm", 1975, true, "") end function stop_full_reject(actor, npc) level.remove_pp_effector(1974) level.remove_cam_effector(1975) end function run_weather_pp(actor,npc, p) local weather_fx = p[1] if weather_fx == nil then weather_fx = "fx_surge_day_3" end level.set_weather_fx(weather_fx) end ]]-- function game_disconnect(actor, npc) local c = get_console() c:execute("disconnect") -- c:execute_deferred("main_menu off") -- c:execute_deferred("hide") end function game_credits(actor, npc) db.gameover_credits_started = true game.start_tutorial("credits_seq") end function game_over(actor, npc) if db.gameover_credits_started ~= true then return end local c = get_console() printf("main_menu on console command is executed") c:execute("main_menu on") end function after_credits(actor, npc) get_console():execute ("main_menu on") end function before_credits(actor, npc) get_console():execute ("main_menu off") end function on_tutor_gameover_stop() local c = get_console() printf("main_menu on console command is executed") c:execute("main_menu on") end function on_tutor_gameover_quickload() local c = get_console() c:execute("load_last_save") end function start_effect(actor, npc) level.add_pp_effector("start_game.ppe", 10182, false) end -- äëÿ ñìåíû ðàáîòû function get_stalker_for_new_job(actor, npc, p) xr_gulag.find_stalker_for_job(npc,p[1]) end function switch_to_desired_job(actor, npc, p) xr_gulag.switch_to_desired_job(npc) end --[[ function death_hit(actor, npc, p) local draftsman = get_story_object (p[1]) local hitted_obj = (p[2] ~= nil and get_story_object (p[2])) or npc if draftsman == nil or hitted_obj == nil then return end local h = hit() h.power = 1000 h.direction = hitted_obj:direction() h.draftsman = draftsman h.impulse = 1 h.type = hit.wound hitted_obj:hit(h) end ]]-- --'----------------------------------------------------------------------------------- --' Ôóíêöèè äëÿ ðàáîòû ñ ïîäñïàóíîì --'----------------------------------------------------------------------------------- function spawn_object(actor, obj, p) --' p[1] - ñåêöèÿ êîãî ñïàóíèòü --' p[2] - èìÿ ïàòðóëüíîãî ïóòè ãäå ñïà óíèòü. local spawn_sect = p[1] if spawn_sect == nil then printf("Wrong spawn section for 'spawn_object' function %s. For object %s", tostring(spawn_sect), obj:name()) end local path_name = p[2] if path_name == nil then printf("Wrong path_name for 'spawn_object' function %s. For object %s", tostring(path_name), obj:name()) end if not level.patrol_path_exists(path_name) then printf("Path %s doesnt exist. Function 'spawn_object' for object %s ", tostring(path_name), obj:name()) end local ptr = patrol(path_name) local index = p[3] or 0 local yaw = p[4] or 0 --' printf("Spawning %s at %s, %s", tostring(p[1]), tostring(p[2]), tostring(p[3])) local se_obj = alife():create(spawn_sect,ptr:point(index),ptr:level_vertex_id(0),ptr:game_vertex_id(0)) if (se_obj) then if IsStalker( nil, se_obj:clsid()) then se_obj:o_torso().yaw = yaw * math.pi / 180 elseif se_obj:clsid() == clsid.script_phys then se_obj:set_yaw(yaw * math.pi / 180) end end end local jup_b219_position local jup_b219_lvid local jup_b219_gvid function jup_b219_save_pos() local obj = get_story_object("jup_b219_gate_id") if obj and obj:position() then jup_b219_position = obj:position() jup_b219_lvid = obj:level_vertex_id() jup_b219_gvid = obj:game_vertex_id() else return end sobj = alife_object(obj:id()) if sobj then alife():release(sobj, true) end end function jup_b219_restore_gate() local yaw = 0 local spawn_sect = "jup_b219_gate" if jup_b219_position then local se_obj = alife():create(spawn_sect,vector():set(jup_b219_position),jup_b219_lvid,jup_b219_gvid) if (se_obj) then se_obj:set_yaw(yaw * math.pi / 180) end end end function spawn_corpse(actor, obj, p) --' p[1] - ñåêöèÿ êîãî ñïàóíèòü --' p[2] - èìÿ ïàòðóëüíîãî ïóòè ãäå ñïàóíèòü. local spawn_sect = p[1] if spawn_sect == nil then printf("Wrong spawn section for 'spawn_corpse' function %s. For object %s", tostring(spawn_sect), obj:name()) end local path_name = p[2] if path_name == nil then printf("Wrong path_name for 'spawn_corpse' function %s. For object %s", tostring(path_name), obj:name()) end if not level.patrol_path_exists(path_name) then printf("Path %s doesnt exist. Function 'spawn_corpse' for object %s ", tostring(path_name), obj:name()) end local ptr = patrol(path_name) local index = p[3] or 0 local se_obj = alife():create(spawn_sect,ptr:point(index),ptr:level_vertex_id(0),ptr:game_vertex_id(0)) if (se_obj) then se_obj:kill() end end function spawn_object_in(actor, obj, p) --' p[1] - ñåêöèÿ êîãî ñïàóíèòü --' p[2] - ñòîðè àéäè îáüåêòà â êîòîðûé ñïàâíèòü local spawn_sect = p[1] if spawn_sect == nil then printf("Wrong spawn section for 'spawn_object' function %s. For object %s", tostring(spawn_sect), obj:name()) end if p[2] == nil then printf("Wrong target_name for 'spawn_object_in' function %s. For object %s", tostring(target_name), obj:name()) end -- local box = alife_object(target_name) -- if(box==nil) then printf("xr_effects.spawn_object_in trying to find object %s", tostring(p[2])) local target_obj_id = get_story_object_id(p[2]) if target_obj_id ~= nil then box = alife_object(target_obj_id) if box == nil then printf("xr_effects.spawn_object_in There is no such object %s", p[2]) end alife():create(spawn_sect,vector(),0,0,target_obj_id) else printf("xr_effects.spawn_object_in object is nil %s", tostring(p[2])) end end function spawn_npc_in_zone(actor, obj, p) --' p[1] - ñåêöèÿ êîãî ñïàóíèòü --' p[2] - èìÿ çîíû â êîòîðîé ñïàóíèòü. local spawn_sect = p[1] if spawn_sect == nil then printf("Wrong spawn section for 'spawn_object' function %s. For object %s", tostring(spawn_sect), obj:name()) end local zone_name = p[2] if zone_name == nil then printf("Wrong zone_name for 'spawn_object' function %s. For object %s", tostring(zone_name), obj:name()) end if db.zone_by_name[zone_name] == nil then printf("Zone %s doesnt exist. Function 'spawn_object' for object %s ", tostring(zone_name), obj:name()) end local zone = db.zone_by_name[zone_name] -- printf("spawn_npc_in_zone: spawning %s at zone %s, squad %s", tostring(p[1]), tostring(p[2]), tostring(p[3])) local spawned_obj = alife():create( spawn_sect, zone:position(), zone:level_vertex_id(), zone:game_vertex_id()) spawned_obj.sim_forced_online = true spawned_obj.squad = 1 or p[3] db.script_ids[spawned_obj.id] = zone_name end function destroy_object(actor, obj, p) local sobj if (p == nil or p[1] == nil) then sobj = alife_object(obj:id()) elseif (p[1] == "story" and p[2] ~= nil) then local id = get_story_object_id(p[2]) if not (id) then printf("destroy_object %s story id doesn't exist!",p[2]) end sobj = id and alife_object(id) end if not (sobj) then return end local cls = sobj:clsid() if (cls == clsid.online_offline_group_s or IsStalker(nil,cls) or IsMonster(nil,cls)) then safe_release_manager.release(sobj) else alife():release(sobj, true) end end function give_actor(actor, npc, p) for k,v in pairs(p) do alife():create(v, db.actor:position(), db.actor:level_vertex_id(), db.actor:game_vertex_id(), db.actor:id()) news_manager.relocate_item(db.actor, "in", v) end end function activate_weapon_slot(actor, npc, p) db.actor:activate_slot(p[1]) end function anim_obj_forward(actor, npc, p) for k,v in pairs(p) do if v ~= nil then db.anim_obj_by_name[v]:anim_forward() end end end function anim_obj_backward(actor, npc, p) if p[1] ~= nil then db.anim_obj_by_name[p[1]]:anim_backward() end end function anim_obj_stop(actor, npc, p) if p[1] ~= nil then db.anim_obj_by_name[p[1]]:anim_stop() end end -- Ôóíêöèè äëÿ ðàáîòû ñ îãíåííûìè çîíàìè. --[[ function turn_on_fire_zone(actor, npc, p) bind_campfire.fire_zones_table[ p[1] ]:turn_on() end function turn_off_fire_zone(actor, npc, p) bind_campfire.fire_zones_table[ p[1] ]:turn_off() end ]]-- --'----------------------------------------------------------------------------------- --' Ôóíêöèè äëÿ îòûãðûâàíèÿ çâóêà --'----------------------------------------------------------------------------------- function play_sound_on_actor(actor,obj,p) local snd = sound_object(p[1]) if (snd) then --snd:play_at_pos(db.actor,db.actor:position(),0,sound_object.s3d) snd:play(db.actor, 0, sound_object.s2d) end end function play_sound(actor, obj, p) local theme = p[1] local faction = p[2] local point if (p[3]) then local smart = SIMBOARD.smarts_by_names[p[3]] if (smart) then point = smart.id else point = p[3] end end if obj and IsStalker(obj) then if not obj:alive() then printf("Stalker [%s][%s] is dead, but you wants to say something for you: [%s]!", tostring(obj:id()), tostring(obj:name()), p[1]) end end xr_sound.set_sound_play(obj:id(), theme, faction, point) end function play_sound_by_story(actor, obj, p) local story_obj = get_story_object_id(p[1]) local theme = p[2] local faction = p[3] local point = SIMBOARD.smarts_by_names[p[4]] if point ~= nil then point = point.id elseif p[4]~=nil then point = p[4] end xr_sound.set_sound_play(story_obj, theme, faction, point) end function stop_sound(actor, npc) xr_sound.stop_sounds_by_id(npc:id()) end function play_sound_looped(actor, obj, p) local theme = p[1] xr_sound.play_sound_looped(obj:id(), theme) end function stop_sound_looped(actor, obj) xr_sound.stop_sound_looped(obj:id()) end function barrel_explode (actor , npc , p) local expl_obj = get_story_object (p[1]) if expl_obj ~= nil then expl_obj:explode(0) end end --'----------------------------------------------------------------------------------- --' Alife support --'----------------------------------------------------------------------------------- --[[ function start_sim(actor, obj) SIMBOARD:start_sim() end function stop_sim(actor, obj) SIMBOARD:stop_sim() end function update_faction_brain(actor, obj, p) if p[1] == nil then printf("Wrong parameters update_faction_brain") end local board = SIMBOARD local player = board.players[ p[1] ] if player == nil then printf("Can't find player %s", tostring(p[1])) end player:faction_brain_update() end ]]-- function create_squad(actor, obj, p) -- if obj ~= nil then -- printf("pl:creating_squad from obj [%s] in section [%s]", tostring(obj:name()), tostring(db.storage[obj:id()].active_section)) -- end local squad_id = p[1] if squad_id == nil then printf("Wrong squad identificator [NIL] in create_squad function") end local smart_name = p[2] if smart_name == nil then printf("Wrong smart name [NIL] in create_squad function") end local ltx = system_ini() if not ltx:section_exist(squad_id) then printf("Wrong squad identificator [%s]. Squad descr doesnt exist.", tostring(squad_id)) end local board = SIMBOARD local smart = board.smarts_by_names[smart_name] if smart == nil then printf("Wrong smart_name [%s] for [%s] faction in create_squad function", tostring(smart_name), tostring(player_name)) end --printf("Create squad %s BEFORE",squad_id) local squad = board:create_squad(smart, squad_id) if not (squad) then return end --printf("Create squad %s AFTER",squad_id) --board:enter_smart(squad, smart.id) local sim = alife() for k in squad:squad_members() do local se_obj = k.object or k.id and sim:object(k.id) if (se_obj) then board:setup_squad_and_group(se_obj) end end --squad:update() return squad end function create_squad_member(actor, obj, p) local squad_member_sect = p[1] local story_id = p[2] local position = nil local level_vertex_id = nil local game_vertex_id = nil if story_id == nil then printf("Wrong squad identificator [NIL] in 'create_squad_member' function") end local board = SIMBOARD local squad = get_story_squad(story_id) if not (squad) then return end local squad_smart = squad.smart_id and board.smarts[squad.smart_id].smrt if not (squad_smart) then return end if p[3] ~= nil then local spawn_point if p[3] == "simulation_point" then spawn_point = system_ini():r_string_ex(squad:section_name(),"spawn_point") if spawn_point == "" or spawn_point == nil then spawn_point = xr_logic.parse_condlist(obj, "spawn_point", "spawn_point", squad_smart.spawn_point) else spawn_point = xr_logic.parse_condlist(obj, "spawn_point", "spawn_point", spawn_point) end spawn_point = xr_logic.pick_section_from_condlist(db.actor, obj, spawn_point) else spawn_point = p[3] end position = patrol(spawn_point):point(0) level_vertex_id = patrol(spawn_point):level_vertex_id(0) game_vertex_id = patrol(spawn_point):game_vertex_id(0) else local commander = alife_object(squad:commander_id()) position = commander.position level_vertex_id = commander.m_level_vertex_id game_vertex_id = commander.m_game_vertex_id end local new_member_id = squad:add_squad_member(squad_member_sect, position, level_vertex_id, game_vertex_id) local se_obj = new_member_id and alife_object(new_member_id) if (se_obj) then squad_smart:register_npc(se_obj) board:setup_squad_and_group(se_obj) end --squad_smart:refresh() squad:update() end function remove_squad(actor, obj, p) local story_id = p[1] if story_id == nil then printf("Wrong squad identificator [NIL] in remove_squad function") end local squad = get_story_squad(story_id) if squad == nil then assert("Wrong squad identificator [%s]. squad doesnt exist", tostring(story_id)) return end SIMBOARD:remove_squad(squad) end function kill_squad(actor, obj, p) local story_id = p[1] if story_id == nil then printf("Wrong squad identificator [NIL] in kill_squad function") end local squad = get_story_squad(story_id) if squad == nil then return end local squad_npcs = {} for k in squad:squad_members() do squad_npcs[k.id] = true end for k,v in pairs(squad_npcs) do local cl_obj = db.storage[k] and db.storage[k].object if cl_obj == nil then alife_object(tonumber(k)):kill() else cl_obj:kill(cl_obj) end end end function heal_squad(actor, obj, p) local story_id = p[1] local health_mod = 1 if p[2] and p[2] ~= nil then health_mod = math.ceil(p[2]/100) end if story_id == nil then printf("Wrong squad identificator [NIL] in heal_squad function") end local squad = get_story_squad(story_id) if squad == nil then return end for k in squad:squad_members() do local cl_obj = db.storage[k.id] and db.storage[k.id].object if cl_obj ~= nil then cl_obj.health = health_mod end end end --[[ function update_squad(actor, obj, p) local squad_id = p[1] if squad_id == nil then printf("Wrong squad identificator [NIL] in remove_squad function") end local board = SIMBOARD local squad = board.squads[squad_id] if squad == nil then assert("Wrong squad identificator [%s]. squad doesnt exist", tostring(squad_id)) return end squad:update() end ]]-- -- this deletes squads from a smart function clear_smart_terrain(actor, obj, p) local smart_name = p[1] if smart_name == nil then printf("Wrong squad identificator [NIL] in clear_smart_terrain function") end local board = SIMBOARD local smart = board.smarts_by_names[smart_name] local smart_id = smart.id for k,v in pairs(board.smarts[smart_id].squads) do if p[2] and p[2] == "true" then board:remove_squad(v) else if not get_object_story_id(v.id) then board:remove_squad(v) end end end end -- This forces squads to leave a smart function flush_smart_terrain(actor,obj,p) local smart_name = p[1] if smart_name == nil then printf("Wrong squad identificator [NIL] in clear_smart_terrain function") end local board = SIMBOARD local function unregister(squad) squad.assigned_target_id = nil squad.current_target_id = nil squad.current_action = nil board:assign_squad_to_smart(squad, nil) for k in squad:squad_members() do local se_obj = alife_object(k.id) if (se_obj) then local smart_id = se_obj.m_smart_terrain_id if (smart_id and smart_id ~= 65535) then local smart = alife_object(smart_id) if (smart) then smart:unregister_npc(se_obj) end end end end end local smart = board.smarts_by_names[smart_name] local smart_id = smart.id for k,v in pairs(board.smarts[smart_id].squads) do if p[2] and p[2] == "true" then unregister(v) else if not get_object_story_id(v.id) then unregister(v) end end end end --[[ function set_actor_faction(actor, obj, p) if p[1] == nil then printf("Wrong parameters") end SIMBOARD:set_actor_community(p[1]) end ]]-- --'----------------------------------------------------------------------------------- --' Quest support --'----------------------------------------------------------------------------------- -- TODO: add param 2 for story_id which can be used to get the npc's squad id or object id for task_giver_id function give_task(actor, obj, p) if p[1] == nil then printf("No parameter in give_task function.") end task_manager.get_task_manager():give_task(p[1]) end function set_active_task(actor, npc, p) if(p[1]) then local t = db.actor:get_task(tostring(p[1]), true) if(t) then db.actor:set_active_task(t) end end end function set_task_completed(actor,npc,p) if (p[1]) then task_manager.get_task_manager():set_task_completed(p[1]) end end function set_task_failed(actor,npc,p) if (p[1]) then task_manager.get_task_manager():set_task_failed(p[1]) end end -- Ôóíêöèè äëÿ ðàáîòû ñ îòíîøåíèÿìè function actor_friend(actor, npc) printf("_bp: xr_effects: actor_friend(): npc='%s': time=%d", npc:name(), time_global()) npc:force_set_goodwill( 1000, actor) end function actor_neutral(actor, npc) npc:force_set_goodwill( 0, actor) end function actor_enemy(actor, npc) npc:force_set_goodwill( -1000, actor) end function set_squad_neutral_to_actor(actor, npc, p) local story_id = p[1] local squad = get_story_squad(story_id) if squad == nil then printf("There is no squad with id[%s]", tostring(story_id)) return end squad:set_squad_relation("neutral") end function set_squad_friend_to_actor(actor, npc, p) local story_id = p[1] local squad = get_story_squad(story_id) if squad == nil then printf("There is no squad with id[%s]", tostring(story_id)) return end squad:set_squad_relation("friend") end --Ñäåëàòü àêòåðà âðàãîì ê îòðÿäó, ïåðåäàåòñÿ èìÿ îòðÿäà function set_squad_enemy_to_actor( actor, npc, p) local story_id = p[1] local squad = get_story_squad(story_id) if squad == nil then printf("There is no squad with id[%s]", tostring(story_id)) return end squad:set_squad_relation("enemy") end --[[ function set_friends(actor, npc, p) local npc1 for i, v in pairs(p) do npc1 = get_story_object(v) if npc1 and npc1:alive() then --printf("_bp: %d:set_friends(%d)", npc:id(), npc1:id()) npc:set_relation(game_object.friend, npc1) npc1:set_relation(game_object.friend, npc) end end end function set_enemies(actor, npc, p) local npc1 for i, v in pairs(p) do --printf("_bp: set_enemies(%d)", v) npc1 = get_story_object(v) if npc1 and npc1:alive() then npc:set_relation(game_object.enemy, npc1) npc1:set_relation(game_object.enemy, npc) end end end function set_gulag_relation_actor(actor, npc, p) if(p[1]) and (p[2]) then game_relations.set_gulag_relation_actor(p[1], p[2]) end end function set_factions_community(actor, npc, p) if(p[1]~=nil) and (p[2]~=nil) and (p[3]~=nil) then game_relations.set_factions_community(p[1], p[2], p[3]) end end function set_squad_community_goodwill(actor, npc, p) if(p[1]~=nil) and (p[2]~=nil) and (p[3]~=nil) then game_relations.set_squad_community_goodwill(p[1], p[2], p[3]) end end ]]-- --sets NPC relation to actor --set_npc_sympathy(number) --call only from npc`s logic function set_npc_sympathy(actor, npc, p) if(p[1]~=nil) then game_relations.set_npc_sympathy(npc, p[1]) end end --sets SQUAD relation to actor --set_squad_goodwill(faction:number) function set_squad_goodwill(actor, npc, p) if(p[1]~=nil) and (p[2]~=nil) then game_relations.set_squad_goodwill(p[1], p[2]) end end function set_squad_goodwill_to_npc(actor, npc, p) if(p[1]~=nil) and (p[2]~=nil) then game_relations.set_squad_goodwill_to_npc(npc, p[1], p[2]) end end function inc_faction_goodwill_to_actor(actor, npc, p) local community = p[1] local delta = p[2] if delta and community then game_relations.change_factions_community_num(community,actor:id(), tonumber(delta)) -- ////////////////////////////////////////////////////////////////////////////////////////////// -- -- Restore Companion Relations -- -- Added by DoctorX -- for DoctorX Questlines 2.0 -- July 25, 2018 -- -- ---------------------------------------------------------------------------------------------- for id, squad in pairs( axr_companions.companion_squads ) do squad:set_squad_relation( game_relations.FRIENDS ) end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ else printf("Wrong parameters in function 'inc_faction_goodwill_to_actor'") end end function dec_faction_goodwill_to_actor(actor, npc, p) local community = p[1] local delta = p[2] if delta and community then game_relations.change_factions_community_num(community,actor:id(), -tonumber(delta)) -- ////////////////////////////////////////////////////////////////////////////////////////////// -- -- Restore Companion Relations -- -- Added by DoctorX -- for DoctorX Questlines 2.0 -- July 25, 2018 -- -- ---------------------------------------------------------------------------------------------- for id, squad in pairs( axr_companions.companion_squads ) do squad:set_squad_relation( game_relations.FRIENDS ) end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ else printf("Wrong parameters in function 'dec_faction_goodwill_to_actor'") end end --[[ function add_custom_static(actor, npc, p) if p[1] ~= nil and p[2] ~= nil then get_hud():AddCustomStatic(p[1], true) get_hud():GetCustomStatic(p[1]):wnd():SetTextST(p[2]) else printf("Invalid parameters in function add_custom_static!!!") end end function remove_custom_static(actor, npc, p) if p[1] ~= nil then get_hud():RemoveCustomStatic(p[1]) else printf("Invalid parameters in function remove_custom_static!!!") end end ]]-- function kill_actor(actor, npc) db.actor:kill(db.actor) end ----------------------------------------------------------------------- -- Treasures support ----------------------------------------------------------------------- function give_treasure (actor, npc, p) end --[[ function change_tsg(actor, npc, p) npc:change_team(p[1], p[2], p[3]) end function exit_game(actor, npc) get_console():execute("quit") end ]]-- function start_surge(actor, npc, p) surge_manager.start_surge(p) end function stop_surge(actor, npc, p) surge_manager.stop_surge() end function set_surge_mess_and_task(actor, npc, p) if(p) then surge_manager.set_surge_message(p[1]) if(p[2]) then surge_manager.set_surge_task(p[2]) end end end --[[ function enable_level_changer(actor, npc, p) if(p[1]~=nil) then local obj = get_story_object(p[1]) if(obj) then if db.storage[obj:id()] and db.storage[obj:id()].s_obj then db.storage[obj:id()].s_obj.enabled = true db.storage[obj:id()].s_obj.hint = "level_changer_invitation" else return end obj:enable_level_changer(true) level_tasks.add_lchanger_location() obj:set_level_changer_invitation("level_changer_invitation") end end end function disable_level_changer(actor, npc, p) if(p[1]~=nil) then local obj = get_story_object(p[1]) if(obj) then if not(db.storage[obj:id()] and db.storage[obj:id()].s_obj) then return end obj:enable_level_changer(false) level_tasks.del_lchanger_mapspot(tonumber(p[1])) db.storage[obj:id()].s_obj.enabled = false if(p[2]==nil) then obj:set_level_changer_invitation("level_changer_disabled") db.storage[obj:id()].s_obj.hint = "level_changer_disabled" else obj:set_level_changer_invitation(p[2]) db.storage[obj:id()].s_obj.hint = p[2] end end end end function change_actor_community(actor, npc, p) if(p[1]~=nil) then db.actor:set_character_community(p[1], 0, 0) end end function set_faction_community_to_actor(actor, npc, p) -- run_string xr_effects.change_actor_community(nil,nil,{"actor_dolg"}) if(p[1]~=nil) and (p[2]~=nil) then local rel = 0 if(p[2]=="enemy") then rel = -3000 elseif(p[2]=="friend") then rel = 1000 end db.actor:set_community_goodwill(p[1], rel) end end function disable_collision(actor, npc) npc:wounded(true) end function enable_collision(actor, npc) npc:wounded(false) end function disable_actor_collision(actor, npc) actor:wounded(true) end function enable_actor_collision(actor, npc) actor:wounded(false) end function relocate_actor_inventory_to_box(actor, npc, p) local function transfer_object_item(item) if item:section() ~= "wpn_binoc" and item:section() ~= "wpn_knife" and item:section() ~= "device_torch" then db.actor:transfer_item(item, inv_box_1) end end inv_box_1 = get_story_object (p[1]) actor:inventory_for_each(transfer_object_item) end ]]-- function make_actor_visible_to_squad(actor,npc,p) local story_id = p and p[1] local squad = get_story_squad(story_id) if squad == nil then printf("There is no squad with id[%s]", story_id) end for k in squad:squad_members() do local obj = ( db.storage[k.id] and db.storage[k.id].object ) or level.object_by_id[k.id] if obj ~= nil then obj:make_object_visible_somewhen( db.actor ) end end end function pstor_set(actor,npc,p) p[2] = tonumber(p[2]) if (p[1] and p[2]) then utils.save_var(db.actor,p[1],p[2]) end end function pstor_reset(actor,npc,p) if (p[1]) then utils.save_var(db.actor,p[1],nil) end end function stop_sr_cutscene(actor,npc,p) local obj = db.storage[npc:id()] if(obj.active_scheme~=nil) then obj[obj.active_scheme].signals["cam_effector_stop"] = true end end --[[ function reset_dialog_end_signal(actor, npc, p) local st = db.storage[npc:id()] if(st.active_scheme==nil) then return end if(st[st.active_scheme].signals==nil) then return end st[st.active_scheme].signals["dialog_end"] = nil end function add_map_spot(actor, npc, p) if(p[1]==nil) then printf("Story id for add map spot function is not set") else local story_id = tonumber(p[1]) local id = id_by_sid(story_id) if(id==nil) then local obj = alife_object(p[1]) id = obj and obj.id end if(id~=nil) then if(p[2]==nil) then p[2] = "primary_task_location" end if(p[3]==nil) then p[3] = "default" end if level.map_has_object_spot(id, p[2]) == 0 then level.map_add_object_spot_ser(id, p[2], p[3]) end else printf("Wrong story id or name [%s] for map spot function", tostring(story_id)) end end end function remove_map_spot(actor, npc, p) if(p[1]==nil) then printf("Story id for add map spot function is not set") else local story_id = tonumber(p[1]) local id = id_by_sid(story_id) if(id==nil) then local obj = alife_object(p[1]) id = obj and obj.id end if(id~=nil) then if(p[2]==nil) then p[2] = "primary_task_location" end if level.map_has_object_spot(id, p[2]) ~= 0 then level.map_remove_object_spot(id, p[2]) end else printf("Wrong story id or name [%s] for map spot function", tostring(story_id)) end end end ]]-- -- Anomal fields support function enable_anomaly(actor, npc, p) if p[1] == nil then printf("Story id for enable_anomaly function is not set") end local obj = get_story_object(p[1]) if not obj then printf("There is no object with story_id %s for enable_anomaly function", tostring(p[1])) end obj:enable_anomaly() end function disable_anomaly(actor, npc, p) if p[1] == nil then printf("Story id for disable_anomaly function is not set") end local obj = get_story_object(p[1]) if not obj then printf("There is no object with story_id %s for disable_anomaly function", tostring(p[1])) end obj:disable_anomaly() end function launch_signal_rocket(actor, obj, p) if p==nil then printf("Signal rocket name is not set!") end if db.signal_light[p[1]] then db.signal_light[p[1]]:launch() else printf("No such signal rocket: [%s] on level", tostring(p[1])) end end --[[ function reset_faction_goodwill(actor, obj, p) if db.actor and p[1] then local board = SIMBOARD local faction = board.players[ p[1] ] if faction then db.actor:set_community_goodwill(p[1], 0) end end end ]]-- function add_cs_text(actor, npc, p) if p[1] then local hud = get_hud() if (hud) then local cs_text = hud:GetCustomStatic("text_on_screen_center") if cs_text then hud:RemoveCustomStatic("text_on_screen_center") end hud:AddCustomStatic("text_on_screen_center", true) cs_text = hud:GetCustomStatic("text_on_screen_center") cs_text:wnd():TextControl():SetText(game.translate_string(p[1])) end end end function del_cs_text(actor, npc, p) local hud = get_hud() if (hud) then cs_text = hud:GetCustomStatic("text_on_screen_center") if cs_text then hud:RemoveCustomStatic("text_on_screen_center") end end end function spawn_item_to_npc(actor, npc, p) local new_item = p[1] if p[1] then alife():create(new_item, npc:position(), npc:level_vertex_id(), npc:game_vertex_id(), npc:id()) end end function give_money_to_npc(actor, npc, p) local money = p[1] if p[1] then npc:give_money(money) end end function seize_money_to_npc(actor, npc, p) local money = p[1] if p[1] then npc:give_money(-money) end end -- Ïåðåäà÷à ïðåäìåòà îò íåïèñÿ ê íåïèñþ -- relocate_item(item_name:story_id_from:story_id_to) function relocate_item(actor, npc, p) local item = p and p[1] local from_obj = p and get_story_object(p[2]) local to_obj = p and get_story_object(p[3]) if to_obj ~= nil then if from_obj ~= nil and from_obj:object(item) ~= nil then from_obj:transfer_item(from_obj:object(item), to_obj) else alife():create(item, to_obj:position(), to_obj:level_vertex_id(), to_obj:game_vertex_id(), to_obj:id()) end else printf("Couldn't relocate item to NULL") end end -- Ñäåëàòü ñêâàäû âðàãàìè, ïåðåäàþòñÿ äâà ñêâàäà set_squads_enemies(squad_name_1:squad_name_2) function set_squads_enemies(actor, npc, p) if (p[1] == nil or p[2] == nil) then printf("Wrong parameters in function set_squad_enemies") return end local squad_1 = get_story_squad(p[1]) local squad_2 = get_story_squad(p[2]) if squad_1 == nil then assert("There is no squad with id[%s]", tostring(p[1])) return end if squad_2 == nil then assert("There is no squad with id[%s]", tostring(p[2])) return end for k in squad_1:squad_members() do local npc_obj_1 = db.storage[k.id] and db.storage[k.id].object if npc_obj_1 ~= nil then for kk in squad_2:squad_members() do local npc_obj_2 = db.storage[kk.id] and db.storage[kk.id].object if npc_obj_2 ~= nil then npc_obj_1:set_relation(game_object.enemy, npc_obj_2) npc_obj_2:set_relation(game_object.enemy, npc_obj_1) printf("set_squads_enemies: %d:set_enemy(%d)", npc_obj_1:id(), npc_obj_2:id()) end end end end end local particles_table = { [1] = {particle = particles_object("anomaly2\\teleport_out_00"), sound = sound_object("anomaly\\teleport_incoming")}, [2] = {particle = particles_object("anomaly2\\teleport_out_00"), sound = sound_object("anomaly\\teleport_incoming")}, [3] = {particle = particles_object("anomaly2\\teleport_out_00"), sound = sound_object("anomaly\\teleport_incoming")}, [4] = {particle = particles_object("anomaly2\\teleport_out_00"), sound = sound_object("anomaly\\teleport_incoming")}, } function jup_b16_play_particle_and_sound(actor, npc, p) particles_table[p[1]].particle :play_at_pos(patrol(npc:name().."_particle"):point(0)) --particles_table[p[1]].sound :play_at_pos(actor, patrol(npc:name().."_particle"):point(0), 0, sound_object.s3d) end --Ôóíêöèÿ óñòàíîâêè ñîñòîÿíèÿ âèäèìîñòè êðîâîñîñà. -- Âîçìîæíûé íàáîð ïàðàìåòðîâ --> story_id:visibility_state(ìîæíî âûçûâàòü îòêóäà óãîäíî) èëè visibility_state(åñëè âûçûâàåòñÿ èç êàñòîìäàòû êðîâîñîñà) -- visibility_state --> -- 0 - íåâèäèìûé -- 1 - ïîëóâèäèìûé -- 2 - ïîëíîñòüþ âèäèìûé function set_bloodsucker_state(actor, npc, p) if (p and p[1]) == nil then printf("Wrong parameters in function 'set_bloodsucker_state'!!!") end local state = p[1] if p[2] ~= nil then state = p[2] npc = get_story_object(p[1]) end if npc ~= nil then if state == "default" then npc:force_visibility_state(-1) else npc:force_visibility_state(tonumber(state)) end end end --Ôóíêöèÿ âñòàâêè ïðåäìåòà â îïðåäåëåííóþ òî÷êó, ñäåëàë äëÿ ñöåíû á57 function drop_object_item_on_point(actor, npc, p) local drop_object = db.actor:object(p[1]) local drop_point = patrol(p[2]):point(0) db.actor:drop_item_and_teleport(drop_object, drop_point) end --Ôóíêöèÿ îòíÿòèÿ ïðåäìåòà ó èãðîêà function remove_item(actor, npc, p) local sec = p[1] if not (sec) then printf("Wrong parameters in function 'remove_item'!!!") return end local amt = p[2] and tonumber(p[2]) or 1 local removed = 0 local sim = alife() local se_item local function release_actor_item(temp, item) if (item:section() == sec and amt > 0) then se_item = sim:object(item:id()) if (se_item) then sim:release(se_item,true) amt = amt - 1 removed = removed + 1 end end end db.actor:iterate_inventory(release_actor_item,nil) if (removed > 0) then news_manager.relocate_item(db.actor,"out",sec,removed) end end -- Ñþæåòíîå ñîõðàíåíèå â âàæíûõ ìåñòàõ function scenario_autosave(actor, npc, p) local save_name = p[1] if save_name == nil then printf("You are trying to use scenario_autosave without save name") end -- clear excess corpses everytime player saves --release_body_manager.get_release_body_manager():clear() if IsImportantSave() then local prefix = axr_misery and axr_misery.ActorClass or user_name() local save_param = prefix.." - "..game.translate_string(save_name) get_console():execute("save "..save_param) end end function zat_b29_create_random_infop(actor, npc, p) if p[2] == nil then printf("Not enough parameters for zat_b29_create_random_infop!") end local amount_needed = p[1] local current_infop = 0 local total_infop = 0 if (not amount_needed or amount_needed == nil) then amount_needed = 1 end for k,v in pairs(p) do if k > 1 then total_infop = total_infop + 1 disable_info(v) end end if amount_needed > total_infop then amount_needed = total_infop end for i = 1, amount_needed do current_infop = math.random(1, total_infop) for k,v in pairs(p) do if k > 1 then if (k == current_infop + 1 and (not has_alife_info(v))) then db.actor:give_info_portion(v) break end end end end end function give_item_b29(actor, npc, p) -- local story_object = p and get_story_object(p[1]) local az_name local az_table = { "zat_b55_anomal_zone", "zat_b54_anomal_zone", "zat_b53_anomal_zone", "zat_b39_anomal_zone", "zaton_b56_anomal_zone", } for i = 16, 23 do if has_alife_info(dialogs_zaton.zat_b29_infop_bring_table[i]) then for k,v in pairs(az_table) do if has_alife_info(v) then az_name = v disable_info(az_name) break end end pick_artefact_from_anomaly(nil, nil, {p[1], az_name, dialogs_zaton.zat_b29_af_table[i]}) break end end end function relocate_item_b29(actor, npc, p) local item for i = 16, 23 do if has_alife_info(dialogs_zaton.zat_b29_infop_bring_table[i]) then item = dialogs_zaton.zat_b29_af_table[i] break end end local from_obj = p and get_story_object(p[1]) local to_obj = p and get_story_object(p[2]) if to_obj ~= nil then if from_obj ~= nil and from_obj:object(item) ~= nil then from_obj:transfer_item(from_obj:object(item), to_obj) else alife():create(item, to_obj:position(), to_obj:level_vertex_id(), to_obj:game_vertex_id(), to_obj:id()) end else printf("Couldn't relocate item to NULL") end end -- Ôóíêöèÿ ðåñåòèò ñåêâåíñíóþ çâóêîêóþ òåìó ó íåïèñÿ. by peacemaker, hein, redstain function reset_sound_npc(actor, npc, p) local obj_id = npc:id() if obj_id and xr_sound.sound_table and xr_sound.sound_table[obj_id] then xr_sound.sound_table[obj_id]:reset(obj_id) end end function jup_b202_inventory_box_relocate(actor, npc) local inv_box_out = get_story_object("jup_b202_actor_treasure") local inv_box_in = get_story_object("jup_b202_snag_treasure") local items_to_relocate = {} local function relocate(inv_box_out, item) items_to_relocate[#items_to_relocate+1] = item end inv_box_out:iterate_inventory_box (relocate, inv_box_out) for k,v in ipairs(items_to_relocate) do inv_box_out:transfer_item(v, inv_box_in) end end function clear_box(actor, npc, p) if (p and p[1]) == nil then printf("Wrong parameters in function 'clear_box'!!!") end local inv_box = get_story_object(p[1]) if inv_box == nil then printf("There is no object with story_id [%s]", tostring(p[1])) end local items_table = {} local function add_items(inv_box, item) items_table[#items_table+1] = item end inv_box:iterate_inventory_box(add_items, inv_box) for k,v in pairs(items_table) do alife():release(alife_object(v:id()), true) end end function activate_weapon(actor, npc, p) local object = actor:object(p[1]) if object == nil then assert("Actor has no such weapon! [%s]", p[1]) end if object ~= nil then actor:make_item_active(object) end end function set_game_time(actor, npc, p) local real_hours = level.get_time_hours() local real_minutes = level.get_time_minutes() local hours = tonumber(p[1]) local minutes = tonumber(p[2]) if p[2] == nil then minutes = 0 end local hours_to_change = hours - real_hours if hours_to_change <= 0 then hours_to_change = hours_to_change + 24 end local minutes_to_change = minutes - real_minutes if minutes_to_change <= 0 then minutes_to_change = minutes_to_change + 60 hours_to_change = hours_to_change - 1 elseif hours == real_hours then hours_to_change = hours_to_change - 24 end level.change_game_time(0,hours_to_change,minutes_to_change) level_weathers.get_weather_manager():forced_weather_change() surge_manager.SurgeManager.time_forwarded = true printf("set_game_time: time changed to [%d][%d]", hours_to_change, minutes_to_change) end function forward_game_time(actor, npc, p) if not p then printf("Insufficient or invalid parameters in function 'forward_game_time'!") end local hours = tonumber(p[1]) local minutes = tonumber(p[2]) if p[2] == nil then minutes = 0 end level.change_game_time(0,hours,minutes) level_weathers.get_weather_manager():forced_weather_change() surge_manager.SurgeManager.time_forwarded = true printf("forward_game_time: time forwarded on [%d][%d]", hours, minutes) end function stop_tutorial() --printf("stop tutorial called") game.stop_tutorial() end function jup_b10_spawn_drunk_dead_items(actor, npc, p) local items_all = { ["wpn_ak74"] = 1, ["ammo_5.45x39_fmj"] = 5, ["ammo_5.45x39_ap"] = 3, ["wpn_fort"] = 1, ["ammo_9x18_fmj"] = 3, ["ammo_12x70_buck"] = 5, ["ammo_11.43x23_hydro"] = 2, ["grenade_rgd5"] = 3, ["grenade_f1"] = 2, ["medkit_army"] = 2, ["medkit"] = 4, ["bandage"] = 4, ["antirad"] = 2, ["vodka"] = 3, ["energy_drink"] = 2, ["conserva"] = 1, ["jup_b10_ufo_memory_2"] = 1, } local items = { [2] = { ["wpn_sig550_luckygun"] = 1, }, [1] = { ["ammo_5.45x39_fmj"] = 5, ["ammo_5.45x39_ap"] = 3, ["wpn_fort"] = 1, ["ammo_9x18_fmj"] = 3, ["ammo_12x70_buck"] = 5, ["ammo_11.43x23_hydro"] = 2, ["grenade_rgd5"] = 3, ["grenade_f1"] = 2, }, [0] = { ["medkit_army"] = 2, ["medkit"] = 4, ["bandage"] = 4, ["antirad"] = 2, ["vodka"] = 3, ["energy_drink"] = 2, ["conserva"] = 1, }, } if p and p[1] ~= nil then local cnt = utils.load_var(actor, "jup_b10_ufo_counter", 0) if cnt > 2 then return end for k,v in pairs(items[cnt]) do local target_obj_id = get_story_object_id(p[1]) if target_obj_id ~= nil then box = alife_object(target_obj_id) if box == nil then printf("There is no such object %s", p[1]) end for i = 1,v do alife():create(k,vector(),0,0,target_obj_id) end else printf("object is nil %s", tostring(p[1])) end end else for k,v in pairs(items_all) do for i = 1,v do alife():create(k, npc:position(), npc:level_vertex_id(), npc:game_vertex_id(), npc:id()) end end end end function pick_artefact_from_anomaly(actor, npc, p) local se_obj local az_name = p and p[2] local af_name = p and p[3] local af_id local af_obj local anomal_zone = db.anomaly_by_name[az_name] if p and p[1] then -- if p[1] == "actor" then -- npc = db.actor -- else -- npc = get_story_object(p[1]) -- end local npc_id = get_story_object_id(p[1]) if npc_id == nil then printf("Couldn't relocate item to NULL in function 'pick_artefact_from_anomaly!'") end se_obj = alife_object(npc_id) if se_obj and (not IsStalker(nil,se_obj:clsid()) or not se_obj:alive()) then printf("Couldn't relocate item to NULL (dead or not stalker) in function 'pick_artefact_from_anomaly!'") end end if anomal_zone == nil then printf("No such anomal zone in function 'pick_artefact_from_anomaly!'") end if anomal_zone.spawned_count < 1 then printf("No artefacts in anomal zone [%s]", az_name) return end for k,v in pairs(anomal_zone.artefact_ways_by_id) do if alife_object(tonumber(k)) and af_name == alife_object(tonumber(k)):section_name() then af_id = tonumber(k) af_obj = alife_object(tonumber(k)) break end if af_name == nil then af_id = tonumber(k) af_obj = alife_object(tonumber(k)) af_name = af_obj:section_name() break end end if af_id == nil then printf("No such artefact [%s] found in anomal zone [%s]", tostring(af_name), az_name) return end anomal_zone:on_artefact_take(af_obj) alife():release(af_obj, true) give_item(db.actor, se_obj, {af_name, p[1]}) -- alife():create(af_name, -- npc.position, -- npc.level_vertex_id, -- npc.game_vertex_id, -- npc.id) end function anomaly_turn_off (actor, npc, p) local anomal_zone = db.anomaly_by_name[p[1]] if anomal_zone == nil then printf("No such anomal zone in function 'anomaly_turn_off!'") end anomal_zone:turn_off() end function anomaly_turn_on (actor, npc, p) local anomal_zone = db.anomaly_by_name[p[1]] if anomal_zone == nil then printf("No such anomal zone in function 'anomaly_turn_on!'") end if p[2] then anomal_zone:turn_on(true) else anomal_zone:turn_on(false) end end function zat_b202_spawn_random_loot(actor, npc, p) local si_table = {} si_table[1] = { [1] = {item = {"bandage","bandage","bandage","bandage","bandage","medkit","medkit","medkit","conserva","conserva"}}, [2] = {item = {"medkit","medkit","medkit","medkit","medkit","vodka","vodka","vodka","kolbasa","kolbasa"}}, [3] = {item = {"antirad","antirad","antirad","medkit","medkit","bandage","kolbasa","kolbasa","conserva"}}, } si_table[2] = { [1] = {item = {"grenade_f1","grenade_f1","grenade_f1"}}, [2] = {item = {"grenade_rgd5","grenade_rgd5","grenade_rgd5","grenade_rgd5","grenade_rgd5"}} } si_table[3] = { [1] = {item = {"detector_elite"}}, [2] = {item = {"detector_advanced"}} } si_table[4] = { [1] = {item = {"helm_hardhat"}}, [2] = {item = {"helm_respirator"}} } si_table[5] = { [1] = {item = {"wpn_val","ammo_9x39_ap","ammo_9x39_ap","ammo_9x39_ap"}}, [2] = {item = {"wpn_spas12","ammo_12x70_buck","ammo_12x70_buck","ammo_12x70_buck","ammo_12x70_buck"}}, [3] = {item = {"wpn_desert_eagle","ammo_11.43x23_fmj","ammo_11.43x23_fmj","ammo_11.43x23_hydro","ammo_11.43x23_hydro"}}, [4] = {item = {"wpn_abakan","ammo_5.45x39_ap","ammo_5.45x39_ap"}}, [5] = {item = {"wpn_sig550","ammo_5.56x45_ap","ammo_5.56x45_ap"}}, [6] = {item = {"wpn_ak74","ammo_5.45x39_fmj","ammo_5.45x39_fmj"}}, [7] = {item = {"wpn_l85","ammo_5.56x45_ss190","ammo_5.56x45_ss190"}} } si_table[6] = { [1] = {item = {"specops_outfit"}}, [2] = {item = {"stalker_outfit"}} } weight_table = {} weight_table[1] = 2 weight_table[2] = 2 weight_table[3] = 2 weight_table[4] = 2 weight_table[5] = 4 weight_table[6] = 4 local spawned_item = {} local max_weight = 12 repeat local n = 0 repeat n = math.random(1, #weight_table) local prap = true for k,v in pairs(spawned_item) do if v == n then prap = false break end end until (prap) and ((max_weight - weight_table[n]) >= 0) max_weight = max_weight - weight_table[n] spawned_item[#spawned_item+1] = n local item = math.random(1, #si_table[n]) for k,v in pairs(si_table[n][item].item) do spawn_object_in(actor, npc, {tostring(v),"jup_b202_snag_treasure"}) end until max_weight <= 0 end function zat_a1_tutorial_end_give(actor, npc) -- level.add_pp_effector("black.ppe", 1313, true) ---do not stop on r1 ! db.actor:give_info_portion("zat_a1_tutorial_end") end function oasis_heal() local d_health = 0.005 local d_power = 0.01 local d_bleeding = 0.05 local d_radiation = -0.05 if(db.actor.health<1) then db.actor.health = d_health end if(db.actor.power<1) then db.actor.power = d_power end if(db.actor.radiation>0) then db.actor.radiation = d_radiation end if(db.actor.bleeding>0) then db.actor.bleeding = d_bleeding end db.actor.satiety = 0.01 end --Ôóíêöèÿ ïðèíèìàåò òîëüêî îäíî çíà÷åíèå, îïðåäåëÿþùåå äëÿ êàêîé ãðóïèðîâêè çàïóñêàåòñÿ. äîñòóïíûå çíà÷åíèÿ [duty, freedom] function jup_b221_play_main(actor, npc, p) local info_table = {} local main_theme local reply_theme local info_need_reply local reachable_theme = {} local theme_to_play = 0 if (p and p[1]) == nil then printf("No such parameters in function 'jup_b221_play_main'") end --Ñîñòàâëÿåì òàáëèöó èíôîïîðøèíîâ îïðåäåëÿþùèõ äîñòóïíîñòü òîé èëè èíîé òåìû, îïðåäåëÿåì ïðåôèêñû òåìû, îòâåòà è ðåàêöèè, ñîîòâåòñòâåííî äëÿ äîëãà èëè äëÿ ñâîáîäû. if tostring(p[1]) == "duty" then info_table = { [1] = "jup_b25_freedom_flint_gone", [2] = "jup_b25_flint_blame_done_to_duty", [3] = "jup_b4_monolith_squad_in_duty", [4] = "jup_a6_duty_leader_bunker_guards_work", [5] = "jup_a6_duty_leader_employ_work", [6] = "jup_b207_duty_wins" } main_theme = "jup_b221_duty_main_" reply_theme = "jup_b221_duty_reply_" info_need_reply = "jup_b221_duty_reply" elseif tostring(p[1]) == "freedom" then info_table = { [1] = "jup_b207_freedom_know_about_depot", [2] = "jup_b46_duty_founder_pda_to_freedom", [3] = "jup_b4_monolith_squad_in_freedom", [4] = "jup_a6_freedom_leader_bunker_guards_work", [5] = "jup_a6_freedom_leader_employ_work", [6] = "jup_b207_freedom_wins" } main_theme = "jup_b221_freedom_main_" reply_theme = "jup_b221_freedom_reply_" info_need_reply = "jup_b221_freedom_reply" else printf("Wrong parameters in function 'jup_b221_play_main'") end --Ñîñòàâëÿåì òàáëèöó äîñòûïíûõ òåì(òëüêî íîìåðà òåì). for k,v in pairs(info_table) do if (has_alife_info(v)) and (not has_alife_info(main_theme .. tostring(k) .. "_played")) then table.insert(reachable_theme,k) -- printf("jup_b221_play_main: table reachable_theme ------------------------------> [%s]", tostring(k)) end end --Åñëè òàáëèöà äîñòóïíûõ òåì ïóñòà èãðàåì îòâåò. Åñëè æå îíà íå ïóñòà èãðàåì îñíîâíóþ òåìó. Åñëè èãðàåì îñíîâíóþ òåìó çàíîñèì çíà÷åíèå ñ÷åò÷èêà äëÿ ïîâòîðíîãî âûïîëíåíèÿ ôóíêöèè. Òåìó âûáèðàåì ïî ðàíäîìó. if #reachable_theme ~= 0 then disable_info(info_need_reply) theme_to_play = reachable_theme[math.random(1, #reachable_theme)] -- printf("jup_b221_play_main: variable theme_to_play ------------------------------> [%s]", tostring(theme_to_play)) utils.save_var(actor,"jup_b221_played_main_theme",tostring(theme_to_play)) db.actor:give_info_portion(main_theme .. tostring(theme_to_play) .."_played") if theme_to_play ~= 0 then play_sound(actor, npc, {main_theme .. tostring(theme_to_play)}) else printf("No such theme_to_play in function 'jup_b221_play_main'") end else db.actor:give_info_portion(info_need_reply) theme_to_play = tonumber(utils.load_var(actor,"jup_b221_played_main_theme",0)) if theme_to_play ~= 0 then play_sound(actor, npc, {reply_theme..tostring(theme_to_play)}) else printf("No such theme_to_play in function 'jup_b221_play_main'") end utils.save_var(actor,"jup_b221_played_main_theme","0") end end function pas_b400_play_particle(actor, npc, p) db.actor:start_particles("zones\\zone_acidic_idle","bip01_head") end function pas_b400_stop_particle(actor, npc, p) db.actor:stop_particles("zones\\zone_acidic_idle","bip01_head") end function damage_actor_items_on_start(actor, npc) local actor = db.actor local obj = actor:object("helm_respirator") if obj ~= nil then obj:set_condition(0.8) end obj = actor:object("stalker_outfit") if obj ~= nil then obj:set_condition(0.76) end obj = actor:object("wpn_pm_actor") if obj ~= nil then obj:set_condition(0.9) end obj = actor:object("wpn_ak74u") if obj ~= nil then obj:set_condition(0.7) end end function damage_pri_a17_gauss() local obj = get_story_object("pri_a17_gauss_rifle") --local obj = npc:object("pri_a17_gauss_rifle") if obj ~= nil then obj:set_condition(0.0) end end function pri_a17_hard_animation_reset(actor, npc, p) --db.storage[npc:id()].state_mgr:set_state("pri_a17_fall_down", nil, nil, nil, {fast_set = true}) db.storage[npc:id()].state_mgr:set_state("pri_a17_fall_down") local state_mgr = db.storage[npc:id()].state_mgr if state_mgr ~= nil then state_mgr.animation:set_state(nil, true) state_mgr.animation:set_state("pri_a17_fall_down") state_mgr.animation:set_control() end end function jup_b217_hard_animation_reset(actor, npc, p) db.storage[npc:id()].state_mgr:set_state("jup_b217_nitro_straight") local state_mgr = db.storage[npc:id()].state_mgr if state_mgr ~= nil then state_mgr.animation:set_state(nil, true) state_mgr.animation:set_state("jup_b217_nitro_straight") state_mgr.animation:set_control() end end function sleep(actor, npc) local sleep_zones = { "actor_surge_hide_2", "agr_army_sleep", "agr_sr_sleep_tunnel", "agr_sr_sleep_wagon", "bar_actor_sleep_zone", "cit_merc_sleep", "ds_farmhouse_sleep", "esc_basement_sleep_area", "esc_secret_sleep", "gar_angar_sleep", "gar_dolg_sleep", "jup_a6_sr_sleep", "mar_a3_sr_sleep", "mil_freedom_sleep", "mil_smart_terran_2_4_sleep", "pri_a16_sr_sleep", "pri_monolith_sleep", "pri_room27_sleep", "rad_sleep_room", "ros_vagon_sleep", "val_abandoned_house_sleep", "val_vagon_sleep", "yan_bunker_sleep_restrictor", "zat_a2_sr_sleep", } for k,v in pairs(sleep_zones) do if utils.npc_in_zone(db.actor, v) then ui_sleep_dialog.sleep() give_info("sleep_active") end end end --[[ function set_tip_to_story(actor, npc, p) if p == nil or p[2] == nil then printf("Not enough parameters in 'set_tip_to_story' function!") end local obj = get_story_object(p[1]) if not obj then return end local tip = p[2] obj:set_tip_text(tip) end function clear_tip_from_story(actor, npc, p) if p == nil or p[1] == nil then printf("Not enough parameters in 'clear_tip_from_story' function!") end local obj = get_story_object(p[1]) if not obj then return end obj:set_tip_text("") end ]]-- function mech_discount(actor, npc, p) if(p[1]) then inventory_upgrades.mech_discount(tonumber(p[1]) or 1) end end function polter_actor_ignore(actor, npc, p) if p[1] and p[1] == "true" then npc:poltergeist_set_actor_ignore(true) elseif p[1] and p[1] == "false" then npc:poltergeist_set_actor_ignore(false) end end function burer_force_gravi_attack(actor, npc) npc:burer_set_force_gravi_attack(true) end function burer_force_anti_aim(actor, npc) npc:set_force_anti_aim(true) end function show_freeplay_dialog(actor, npc, p) if p[1] and p[2] and p[2] == "true" then ui_freeplay_dialog.show("message_box_yes_no", p[1]) elseif p[1] then ui_freeplay_dialog.show("message_box_ok", p[1]) end end -- Òîëüêî äëÿ state_mgr function get_best_detector(npc) local detectors = { "detector_simple", "detector_advanced", "detector_elite", "detector_scientific" } for k,v in pairs(detectors) do local obj = npc:object(v) if obj ~= nil then obj:enable_attachable_item(true) return end end end function hide_best_detector(npc) local detectors = { "detector_simple", "detector_advanced", "detector_elite", "detector_scientific" } for k,v in pairs(detectors) do local obj = npc:object(v) if obj ~= nil then obj:enable_attachable_item(false) return end end end -- Èíôîïîðøíû äëÿ ñèíõðîíèçàöèè àíèìàöèè íïñ ñ ïðî÷èìè äåéñòâèÿìè, è äëÿ äðóãèõ öåëåé function pri_a18_radio_start(actor, npc) db.actor:give_info_portion("pri_a18_radio_start") end function pri_a17_ice_climb_end(actor, npc) db.actor:give_info_portion("pri_a17_ice_climb_end") end function jup_b219_opening(actor, npc) db.actor:give_info_portion("jup_b219_opening") end function jup_b219_entering_underpass(actor, npc) db.actor:give_info_portion("jup_b219_entering_underpass") end function pri_a17_pray_start(actor, npc) db.actor:give_info_portion("pri_a17_pray_start") end function zat_b38_open_info(actor, npc) db.actor:give_info_portion("zat_b38_open_info") end function zat_b38_switch_info(actor, npc) db.actor:give_info_portion("zat_b38_switch_info") end function zat_b38_cop_dead(actor, npc) db.actor:give_info_portion("zat_b38_cop_dead") end function jup_b15_zulus_drink_anim_info(actor, npc) db.actor:give_info_portion("jup_b15_zulus_drink_anim_info") end function pri_a17_preacher_death(actor, npc) db.actor:give_info_portion("pri_a17_preacher_death") end function zat_b3_tech_surprise_anim_end(actor, npc) db.actor:give_info_portion("zat_b3_tech_surprise_anim_end") end function zat_b3_tech_waked_up(actor, npc) db.actor:give_info_portion("zat_b3_tech_waked_up") end function zat_b3_tech_drinked_out(actor, npc) db.actor:give_info_portion("zat_b3_tech_drinked_out") end function pri_a28_kirillov_hq_online(actor, npc) db.actor:give_info_portion("pri_a28_kirillov_hq_online") end function pri_a20_radio_start(actor, npc) db.actor:give_info_portion("pri_a20_radio_start") end function pri_a22_kovalski_speak(actor, npc) db.actor:give_info_portion("pri_a22_kovalski_speak") end function zat_b38_underground_door_open(actor, npc) db.actor:give_info_portion("zat_b38_underground_door_open") end function zat_b38_jump_tonnel_info(actor, npc) db.actor:give_info_portion("zat_b38_jump_tonnel_info") end function jup_a9_cam1_actor_anim_end(actor, npc) db.actor:give_info_portion("jup_a9_cam1_actor_anim_end") end function pri_a28_talk_ssu_video_end(actor, npc) db.actor:give_info_portion("pri_a28_talk_ssu_video_end") end function set_torch_state(actor, npc, p) if p == nil or p[2] == nil then printf("Not enough parameters in 'set_torch_state' function!") end local obj = get_story_object(p[1]) if not obj then return end local torch = obj:object("device_torch") if torch then if p[2] == "on" then torch:enable_attachable_item(true) elseif p[2] == "off" then torch:enable_attachable_item(false) end end end local actor_nightvision = false local actor_torch = false function disable_actor_nightvision(actor, npc) --local nightvision = db.actor:object("device_torch") --if not (nightvision) then -- return --end --if nightvision:night_vision_enabled() then -- nightvision:enable_night_vision(false) -- actor_nightvision = true --end end function enable_actor_nightvision(actor, npc) --local nightvision = db.actor:object("device_torch") --if not (nightvision) then -- return --end --if not nightvision:night_vision_enabled() and actor_nightvision then -- nightvision:enable_night_vision(true) -- actor_nightvision = false --end end function disable_actor_torch(actor, npc) local torch = db.actor:object("device_torch") if not (torch) then return end if torch:torch_enabled() then torch:enable_torch(false) actor_torch = true end end function enable_actor_torch(actor, npc) local torch = db.actor:object("device_torch") if not (torch) then return end if not torch:torch_enabled() and actor_torch then torch:enable_torch(true) actor_torch = false end end function create_cutscene_actor_with_weapon(actor, npc, p) --' p[1] - ñåêöèÿ êîãî ñïàóíèòü --' p[2] - èìÿ ïàòðóëüíîãî ïóòè ãäå ñïàóíèòü. --' p[3] - òî÷êà ïàòðóëüíîãî ïóòè --' p[4] - ïîâîðîò ïî îñè Y --' p[5] - ïðèíóäèòåëüíûé ñëîò - áóäåò ðàáîòàòü äàæå ïðè disable_ui local spawn_sect = p[1] if spawn_sect == nil then printf("Wrong spawn section for 'spawn_object' function %s. For object %s", tostring(spawn_sect), obj:name()) end local path_name = p[2] if path_name == nil then printf("Wrong path_name for 'spawn_object' function %s. For object %s", tostring(path_name), obj:name()) end if not level.patrol_path_exists(path_name) then printf("Path %s doesnt exist. Function 'spawn_object' for object %s ", tostring(path_name), obj:name()) end local ptr = patrol(path_name) local index = p[3] or 0 local yaw = p[4] or 0 local npc = alife():create(spawn_sect, ptr:point(index), ptr:level_vertex_id(0), ptr:game_vertex_id(0)) if IsStalker( nil, npc:clsid()) then npc:o_torso().yaw = yaw * math.pi / 180 else npc.angle.y = yaw * math.pi / 180 end local slot_override = p[5] or 0 local slot local active_item if slot_override == 0 then slot = db.actor:active_slot() if(slot~=2 and slot~=3) then return end active_item = db.actor:active_item() else if db.actor:item_in_slot(slot_override) ~= nil then active_item = db.actor:item_in_slot(slot_override) else if db.actor:item_in_slot(3) ~= nil then active_item = db.actor:item_in_slot(3) elseif db.actor:item_in_slot(2) ~= nil then active_item = db.actor:item_in_slot(2) else return end end end local actor_weapon = alife_object(active_item:id()) local section_name = actor_weapon:section_name() if section_name == "pri_a17_gauss_rifle" then section_name = "wpn_gauss" end if (active_item) then local new_weapon = alife():create(section_name, ptr:point(index), ptr:level_vertex_id(0), ptr:game_vertex_id(0), npc.id) if section_name ~= "wpn_gauss" then new_weapon:clone_addons(actor_weapon) end end end -- Çàñòàâèòü èãðàòü óíèêàëüíûå àíèìàöèè ñíà(ó êðîâîñîñà) function set_force_sleep_animation(actor, npc, p) local num = p[1] npc:force_stand_sleep_animation(tonumber(num)) end -- Óáðàòü óíèêàëüíûå àíèìàöèè ñíà(ó êðîâîñîñà) function release_force_sleep_animation(actor, npc) npc:release_stand_sleep_animation() end function zat_b33_pic_snag_container(actor, npc) if xr_conditions.actor_in_zone(actor, npc, {"zat_b33_tutor"}) then give_actor(actor, npc, {"zat_b33_safe_container"}) db.actor:give_info_portion("zat_b33_find_package") if not has_alife_info("zat_b33_safe_container") then local zone = db.zone_by_name["zat_b33_tutor"] play_sound(actor, zone, {"pda_news"}) end end end --Îòêëþ÷åíèå âîçäåéñòâèÿ âðàæåñêîãî íïñ íà èíäèêàòîð âèäèìîñòè âðàãà íà õàäå èãðîêà. --Èñï. òîëüêî èç ëîãèêè íïñ. function set_visual_memory_enabled(actor, npc, p) if (p and p[1]) and (tonumber(p[1]) >= 0) and (tonumber(p[1]) <= 1) then local boolval = false if (tonumber(p[1]) == 1) then boolval = true end npc:set_visual_memory_enabled(boolval) end end function disable_memory_object (actor, npc) local best_enemy = npc:best_enemy() if best_enemy then npc:enable_memory_object(best_enemy, false) end end function zat_b202_spawn_b33_loot(actor, npc, p) local info_table = { "zat_b33_first_item_gived", "zat_b33_second_item_gived", "zat_b33_third_item_gived", "zat_b33_fourth_item_gived", "zat_b33_fifth_item_gived" } local item_table = {} item_table[1] = { "wpn_fort_snag" } item_table[2] = { "medkit_scientic", "medkit_scientic", "medkit_scientic", "antirad", "antirad", "antirad", "bandage", "bandage", "bandage", "bandage", "bandage" } item_table[3] = { "wpn_ak74u_snag" } item_table[4] = { "af_soul" } item_table[5] = { "helm_hardhat_snag" } for k,v in pairs(info_table) do local obj_id if (k == 1) or (k == 3) then obj_id = "jup_b202_stalker_snag" else obj_id = "jup_b202_snag_treasure" end if not has_alife_info(tostring(v)) then for l,m in pairs(item_table[k]) do -- printf("zat_b202_spawn_b33_loot: number [%s] item [%s] to [%s]", tostring(k), tostring(m), tostring(obj_id)) spawn_object_in(actor, npc, {tostring(m),tostring(obj_id)}) end end end end function set_monster_animation (actor, npc, p) if not (p and p[1]) then printf("Wrong parameters in function 'set_monster_animation'!!!") end npc:set_override_animation (p[1]) end function clear_monster_animation (actor, npc) npc:clear_override_animation () end local actor_position_for_restore local actor_direction_for_restore function save_actor_position() actor_position_for_restore = get_story_object("actor"):position() --actor_direction_for_restore = get_story_object("actor"):direction() end function restore_actor_position() --db.actor:set_actor_direction(actor_direction_for_restore) db.actor:set_actor_position(actor_position_for_restore) end function upgrade_hint(actor, npc, p) if(p) then inventory_upgrades.cur_hint = p end end function force_obj(actor, npc, p) local obj = get_story_object(p[1]) if not obj then printf("'force_obj' Target object does not exist") return end if p[2] == nil then p[2] = 20 end if p[3] == nil then p[3] = 100 end obj:set_const_force(vector():set(0,1,0), p[2], p[3]) end function pri_a28_check_zones() local story_obj_id local dist local index = 0 local zones_tbl = { [1] = "pri_a28_sr_mono_add_1", [2] = "pri_a28_sr_mono_add_2", [3] = "pri_a28_sr_mono_add_3", } local info_tbl = { [1] = "pri_a28_wave_1_spawned", [2] = "pri_a28_wave_2_spawned", [3] = "pri_a28_wave_3_spawned", } local squad_tbl = { [1] = "pri_a28_heli_mono_add_1", [2] = "pri_a28_heli_mono_add_2", [3] = "pri_a28_heli_mono_add_3", } for k,v in pairs(zones_tbl) do story_obj_id = get_story_object_id(v) if story_obj_id then local se_obj = alife_object(story_obj_id) local curr_dist = se_obj.position:distance_to(db.actor:position()) if index == 0 then dist = curr_dist index = k elseif dist < curr_dist then dist = curr_dist index = k end end end if index == 0 then printf("Found no distance or zones in func 'pri_a28_check_zones'") end if has_alife_info(info_tbl[index]) then for k,v in pairs(info_tbl) do if not has_alife_info(info_tbl[k]) then db.actor:give_info_portion(info_tbl[k]) end end else db.actor:give_info_portion(info_tbl[index]) end create_squad(db.actor,nil,{squad_tbl[index],"pri_a28_heli"}) end function eat_vodka_script() if db.actor:object("vodka_script") ~= nil then db.actor:eat(db.actor:object("vodka_script")) end end local mat_table = { "jup_b200_material_1", "jup_b200_material_2", "jup_b200_material_3", "jup_b200_material_4", "jup_b200_material_5", "jup_b200_material_6", "jup_b200_material_7", "jup_b200_material_8", "jup_b200_material_9", } function jup_b200_count_found(actor) local cnt = 0 for k,v in pairs(mat_table) do local material_obj = get_story_object(v) if material_obj then local parent = material_obj:parent() if parent then local parent_id = parent:id() if parent_id ~= 65535 and parent_id == actor:id() then cnt = cnt + 1 end end end end cnt = cnt + utils.load_var(actor, "jup_b200_tech_materials_brought_counter", 0) utils.save_var(actor, "jup_b200_tech_materials_found_counter", cnt) end function sr_teleport(actor,npc,p) ui_sr_teleport.create(npc,p and p[1],p and p[2]) end function make_a_wish(actor,npc,p) -- /////////////////////////////////////////////////////////////////////////////////////////////// -- -- End Find Wish Granter Storyline Task -- -- Added by DoctorX -- for DoctorX Questlines 2.0 -- January 13, 2018 -- -- ----------------------------------------------------------------------------------------------- -- Give Wish Granter Found infoportion: give_info( "drx_ql_wish_granter_found" ) -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ local action_list = {} -- Prevent Monolith or Zombified players from making a wish. if (character_community(db.actor) == "actor_zombied" or character_community(db.actor) == "actor_monolith") then return end action_list[1] = function() -- ////////////////////////////////////////////////////////////////////////////////////////////// -- -- Wish #1 -- -- Modified by DoctorX -- for DoctorX Questlines 2.0 -- October 09, 2019 -- -- ---------------------------------------------------------------------------------------------- -- error(game.translate_string("st_wish_granted"),2) give_info( "actor_made_wish" ) -- game_credits( actor, npc ) -- kill_actor( actor, npc ) run_tutorial( actor, npc, {"drx_ql_wish_disappear_mov"} ) -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ return end action_list[2] = function() give_info("actor_made_wish") give_info("actor_made_wish_for_control") return end action_list[3] = function() local sim = alife() local squad for i=1,65534 do squad = sim:object(i) if (squad and squad:clsid() == clsid.online_offline_group_s) then SIMBOARD:assign_squad_to_smart(squad, nil) squad:remove_squad() end end give_info("actor_made_wish_for_peace") give_info("actor_made_wish") return end action_list[4] = function() local sim = alife() local sysini = system_ini() local valid_ids = {[1] = true, [2] = true , [3] = true, [4] = true, [8] = true, [12] = true, [13] = true, [14] = true, [15] = true} for k,v in pairs(ui_debug_main.id_to_spawn_table) do if (valid_ids[k]) then local list = ui_debug_main.get_spawn_table(v) if (list) then for kk,vv in pairs(list) do if (sysini:section_exist(vv)) then sim:create(vv,vector(),0,0,0) end end end end end local function remove_backpack(id) local function itr(npc,itm) if (itm:section() == "itm_actor_backpack" or itm:section() == "itm_backpack") then local se_itm = alife_object(itm:id()) if (se_itm) then alife():release(se_itm,true) end return end end db.actor:iterate_inventory(itr,db.actor) end CreateTimeEvent(0,"remove_backpack",1,remove_backpack,0) give_info("actor_made_wish_for_riches") give_info("actor_made_wish") return end action_list[5] = function() local se_actor = alife():actor() local data = stpk_utils.get_actor_data(se_actor) if (data) then data.specific_character = "actor_zombied" stpk_utils.set_actor_data(data,se_actor) end db.actor:set_character_community("actor_zombied", 0, 0) give_info("actor_made_wish_immortal") give_info("actor_made_wish") -- local spawn_path = patrol("spawn_player_stalker") -- if (spawn_path) then -- local pos = spawn_path:point(0) -- local lvid = spawn_path:level_vertex_id(0) -- local gvid = spawn_path:game_vertex_id(0) -- local gg = game_graph() -- if (gvid and gg:valid_vertex_id(gvid)) then -- ChangeLevel(pos,lvid,gvid,vector():set(0,0,0)) -- end -- end -- Teleports the player to a smashed open grave in the Great Swamp. -- Goodwill is increased with the Monolith and Zombified faction to ensure they aren't hostile. inc_faction_goodwill_to_actor(db.actor, nil, {"monolith", 5000}) inc_faction_goodwill_to_actor(db.actor, nil, {"zombied", 5000}) ChangeLevel(vector():set(266.99, 0.00, -131.07), 310937, 181, vector():set(0,0,0)) return end -- Hide and disable the immortality wish if actor is in Zombified or Monolith factions. if (character_community(db.actor) == "actor_zombied" or character_community(db.actor) == "actor_monolith") then action_list[5] = nil ui_dyn_msg_box.multi_choice(action_list,"st_wish_1","st_wish_2","st_wish_3","st_wish_4","st_wish_99") else ui_dyn_msg_box.multi_choice(action_list,"st_wish_1","st_wish_2","st_wish_3","st_wish_4","st_wish_5","st_wish_99") end end function clear_logic(actor,npc,p) local st = db.storage[npc:id()] st.ini_filename = "" st.ini = xr_logic.get_customdata_or_ini_file(npc, st.ini_filename) st.active_section = nil st.active_scheme = nil st.section_logic = "logic" xr_logic.switch_to_section(npc,nil,nil) end function set_new_scheme_and_logic(actor,npc,p) local st = db.storage[npc:id()] st.ini_filename = ini_filename st.ini = ini_file(ini_filename) if not (st.ini) then printf("Error: set_new_scheme_and_logic: can't find ini %s",ini_filename) return end -- Set new section logic st.section_logic = logic -- Select new active section local new_section = section or xr_logic.determine_section_to_activate(npc, st.ini, st.section_logic) -- Switch to new section xr_logic.switch_to_section(npc, st.ini, new_section) st.overrides = xr_logic.cfg_get_overrides(st.ini, new_section, npc) end function set_script_danger(actor,npc,p) xr_danger.set_script_danger(npc,p and tonumber(p[1]) or 5000) end function spawn_npc_at_position(actor,npc,p) if not (p) then return end local pos = vector():set(tonumber(p[2]),tonumber(p[3]),tonumber(p[4])) alife():create(p[1],pos,p[5],p[6]) end function kill_obj_on_job(actor,npc,p) local board = SIMBOARD local smart = p[1] and board and board.smarts_by_names[p[1]] local id = smart and smart.npc_by_job_section["logic@"..p[2]] local obj = id and db.storage[id] and db.storage[id].object if not obj or not obj:alive() then return false end local h = hit() h:bone("bip01_neck") h.power = 1 h.impulse = 1 h.direction = vector():sub(npc:position(), obj:position()) h.draftsman = npc h.type = hit.wound obj:hit(h) end function obj_at_job_switch_section(actor,npc,p) local board = SIMBOARD local smart = p[1] and board and board.smarts_by_names[p[1]] local id = smart and smart.npc_by_job_section["logic@"..p[2]] local obj = id and db.storage[id] and db.storage[id].object if not obj or not obj:alive() then return end local st = db.storage[obj:id()] if not (st) then return end xr_logic.switch_to_section(obj, st.ini, p[3]) end function change_visual(actor,npc,p) if (not axr_main) then return end local sobj = alife_object(npc:id()) if not (sobj) then return end if (axr_main) then CreateTimeEvent(sobj.id,"update_visual",1,update_visual,sobj.id,p[1]) end end function switch_offline(actor,npc,p) local se_obj = npc and alife_object(npc:id()) if (se_obj and se_obj:can_switch_offline()) then se_obj:switch_offline() end end ------------------- util functions function update_visual(id,vis) local se_npc = id and alife_object(id) if not (se_npc) then return true end if (se_npc.online) then se_npc:switch_offline() return false end if not (vis) then return true end local data = stpk_utils.get_stalker_data(se_npc) if (data) then data.visual_name = vis stpk_utils.set_stalker_data(data,se_npc) end return true end function up_start() --up.up_objects_spawn() --up.up_stalkers_spawn() end function up_freeplay() --up.freeplay_clean_territory() end function stop_sr_cutscene(actor,npc,p) local obj = db.storage[npc:id()] if(obj.active_scheme~=nil) then obj[obj.active_scheme].signals["cam_effector_stop"] = true end end function update_weather(actor, npc, p) if p and p[1] then if p[1] == "true" then level_weathers.get_weather_manager():select_weather(true) elseif p[1] == "false" then level_weathers.get_weather_manager():select_weather(false) end end end function trade_job_sell_items(actor,npc,p) axr_trade_manager.npc_trade_buy_sell(npc) end function trade_job_give_id(actor,npc,p) local board = SIMBOARD local smart = p[1] and board and board.smarts_by_names[p[1]] local id = smart and smart.npc_by_job_section["logic@"..p[2]] local npc_info = id and smart.npc_info[id] --printf("smart=%s id=%s npc_info=%s job=%s",smart and smart:name(),id,npc_info ~= nil,npc_info and npc_info.job and npc_info.job.section) if not (npc_info and npc_info.job) then return end npc_info.job.seller_id = npc:id() end --X16 machine switch off function yan_gluk (actor, npc) local sound_obj_l = xr_sound.get_safe_sound_object( [[affects\psy_blackout_l]] ) local sound_obj_r = xr_sound.get_safe_sound_object( [[affects\psy_blackout_r]] ) sound_obj_l:play_no_feedback(db.actor, sound_object.s2d, 0, vector():set(-1, 0, 1), 1.0) sound_obj_r:play_no_feedback(db.actor, sound_object.s2d, 0, vector():set( 1, 0, 1), 1.0) level.add_cam_effector("camera_effects\\earthquake.anm", 1974, false, "") end function yan_saharov_message(actor, npc, p) -- /////////////////////////////////////////////////////////////////////////////////////////////// -- -- Remove Sakharov X-16 PDA Messages -- -- Modified by DoctorX -- for DoctorX Questlines 2.0 -- February 22, 2019 -- -- ----------------------------------------------------------------------------------------------- -- if (p[1] == 1) then -- news_manager.send_tip(db.actor, "st_yan_saharov_message", nil, "saharov", 15000, nil) -- db.actor:give_info_portion("labx16_find") -- elseif (p[1] == 2) then -- news_manager.send_tip(db.actor, "st_yan_saharov_message_2", nil, "saharov", 20000, nil) -- elseif (p[1] == 3) then -- news_manager.send_tip(db.actor, "st_yan_saharov_message_3", nil, "saharov", 15000, nil) -- elseif (p[1] == "free_upgrade") then -- news_manager.send_tip(db.actor, "st_yan_saharov_message_free_upgrade", nil, "saharov", 15000, nil) -- end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ end --X18 dream function x18_gluk (actor, npc) level.add_pp_effector ("blink.ppe", 234, false) local sound_obj_l = xr_sound.get_safe_sound_object( [[affects\psy_blackout_l]] ) local sound_obj_r = xr_sound.get_safe_sound_object( [[affects\psy_blackout_r]] ) local snd_obj = xr_sound.get_safe_sound_object( [[affects\tinnitus3a]] ) snd_obj:play_no_feedback(db.actor, sound_object.s2d, 0, vector():set(0,0,0), 1.0) sound_obj_l:play_no_feedback(db.actor, sound_object.s2d, 0, vector():set(-1, 0, 1), 1.0) sound_obj_r:play_no_feedback(db.actor, sound_object.s2d, 0, vector():set( 1, 0, 1), 1.0) level.add_cam_effector("camera_effects\\earthquake.anm", 1974, false, "") end function end_yantar_dream(actor, npc) db.actor:give_info_portion("yantar_find_ghost_task_start") end function end_x18_dream(actor, npc) db.actor:give_info_portion("dar_x18_dream") end function end_radar_dream(actor, npc) db.actor:give_info_portion("bun_patrol_start") end function end_warlab_dream(actor, npc) db.actor:give_info_portion("end_warlab_dream") end function end_final_peace(actor, npc) db.actor:give_info_portion("end_final_peace") end -- //////////////////////////////////////////////////////////////////////////////////////////////// -- -- End Pod Scene Video -- -- Added by DoctorX -- for DoctorX Questlines 2.0 -- October 09, 2019 -- -- ------------------------------------------------------------------------------------------------ -- Give info portion at end of pod scene video: function end_mov_join_osoznanie( actor, npc ) db.actor:give_info_portion( "end_mov_join_osoznanie" ) end -- \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ --------------------------------------------------------- -- Sarcofag2 --------------------------------------------------------- function aes_earthshake (npc) local snd_obj = xr_sound.get_safe_sound_object([[ambient\earthquake]]) snd_obj:play_no_feedback(db.actor, sound_object.s2d, 0, vector():set(0,0,0), 1.0) level.add_cam_effector("camera_effects\\earthquake.anm", 1974, false, "") --set_postprocess ("scripts\\earthshake.ltx") end function oso_init_dialod () -- local oso = level_object_by_sid(osoznanie) -- db.actor:run_talk_dialog(oso) end function warlab_stop_particle(actor, npc, p) db.actor:stop_particles("anomaly2\\control_monolit_holo", "link") end function play_snd_from_obj(actor, npc, p) if p[1] and p[2] then local snd_obj = xr_sound.get_safe_sound_object(p[2]) local obj = level_object_by_sid(p[1]) if obj ~= nil then printf("can't find object with story id %s", tostring(p[1])) -- snd_obj:play_at_pos(obj, obj:position(), sound_object.s3d) snd_obj:play_no_feedback(obj, sound_object.s3d, 0, obj:position(), 1.0) end end end function play_snd(actor, npc, p) if p[1] then local snd_obj = xr_sound.get_safe_sound_object(p[1]) --snd_obj:play(actor, p[2] or 0, sound_object.s2d) snd_obj:play_no_feedback(actor, sound_object.s2d, p[2] or 0, vector():set(0,0,0), 1.0) end end function erase_pstor_ctime(actor,npc,p) if not (p[1]) then return end utils.save_ctime(db.actor,p[1],nil) end -- Shows progress bar health for last hit enemy with db.storage[id].show_health = true -- param 1: Story ID -- param 2: true or false; default is true. True will set db.storage[id].show_health = true while false will remove custom static from screen function show_health(actor,npc,p) if (p[2] == "false") then ui_enemy_health.cs_remove() else local id = get_story_object_id(p[1]) local st = id and db.storage[id] if (st) then st.show_health = true end end end function disable_monolith_zones(actor,npc,p) local remove_sections = { ["zone_monolith"] = true } local sim = alife() for i=1,65534 do local se_obj = sim:object(i) if (se_obj and remove_sections[se_obj:section_name()]) then sim:release(se_obj,true) end end end function disable_generator_zones(actor,npc,p) local remove_sections = { ["generator_torrid"] = true, ["generator_dust"] = true, ["generator_electra"] = true, ["generator_dust_static"] = true } local sim = alife() for i=1,65534 do local se_obj = sim:object(i) if (se_obj and remove_sections[se_obj:section_name()]) then sim:release(se_obj,true) end end end --OLD ARENA function bar_arena_hit(actor, npc) local h = hit() h.power = 0.01 h.direction = npc:direction() h.draftsman = db.actor h.impulse = 1 h.type = hit.wound npc:hit(h) end function bar_arena_introduce(actor, npc) if db.actor:has_info("bar_arena_pseudodog_choosen") then news_manager.send_tip(db.actor, "bar_arena_fight_pseudodog", nil, "arena", 24000, nil) elseif db.actor:has_info("bar_arena_snork_choosen") then news_manager.send_tip(db.actor, "bar_arena_fight_snork", nil, "arena", 30000, nil) elseif db.actor:has_info("bar_arena_bloodsucker_choosen") then news_manager.send_tip(db.actor, "bar_arena_fight_bloodsucker", nil, "arena", 30000, nil) elseif db.actor:has_info("bar_arena_burer_choosen") then news_manager.send_tip(db.actor, "bar_arena_fight_burer", nil, "arena", 52000, nil) elseif db.actor:has_info("bar_arena_savage_choosen") then news_manager.send_tip(db.actor, "bar_arena_fight_savage", nil, "arena", 34000, nil) end end function bar_arena_fight_begin(actor, npc) news_manager.send_tip(db.actor, "bar_arena_fight_begin", nil, "arena") end function bar_arena_fight_10(actor, npc) news_manager.send_tip(db.actor, "bar_arena_fight_10", nil, "arena") end function bar_arena_fight_20(actor, npc) news_manager.send_tip(db.actor, "bar_arena_fight_20", nil, "arena") end function bar_arena_fight_30(actor, npc) news_manager.send_tip(db.actor, "bar_arena_fight_30", nil, "arena") end function bar_arena_fight_40(actor, npc) news_manager.send_tip(db.actor, "bar_arena_fight_40", nil, "arena") end function bar_arena_fight_50(actor, npc) news_manager.send_tip(db.actor, "bar_arena_fight_50", nil, "arena") end function bar_arena_fight_60(actor, npc) news_manager.send_tip(db.actor, "bar_arena_fight_60", nil, "arena") end function bar_arena_fight_70(actor, npc) news_manager.send_tip(db.actor, "bar_arena_fight_70", nil, "arena") end function bar_arena_fight_80(actor, npc) news_manager.send_tip(db.actor, "bar_arena_fight_80", nil, "arena") end function bar_arena_fight_90(actor, npc) news_manager.send_tip(db.actor, "bar_arena_fight_90", nil, "arena") end function bar_arena_check_lose(actor, npc) if db.actor:has_info("bar_arena_100_p") then if db.actor:has_info("bar_arena_fight_30") then db.actor:give_info_portion("bar_arena_actor_lose") news_manager.send_tip(actor, "bar_arena_fight_timeout", nil, "arena") end return end if db.actor:has_info("bar_arena_50_p") then if db.actor:has_info("bar_arena_fight_90") then db.actor:give_info_portion("bar_arena_actor_lose") news_manager.send_tip(actor, "bar_arena_fight_timeout", nil, "arena") end return end end function bar_arena_after_fight(actor, npc) if db.actor:dont_has_info("bar_arena_actor_lose") then db.actor:give_info_portion("bar_arena_actor_victory") news_manager.send_tip(actor, "bar_arena_fight_victory", nil, "arena") else news_manager.send_tip(actor, "bar_arena_fight_lose", nil, "arena") end db.actor:give_info_portion("bar_arena_start_introduce") end function bar_arena_actor_afraid(actor, npc) news_manager.send_tip(db.actor, "bar_arena_actor_afraid", nil, "arena") end function bar_arena_actor_dead(actor, npc) news_manager.send_tip(db.actor, "bar_arena_fight_dead", nil, "arena") end --NEW ARENA function bar_arena_teleport (actor, npc) local hud = get_hud() if (hud) then hud:HideActorMenu() end local box = get_story_object("bar_arena_inventory_box") if (box) then local function transfer_object_item(item) db.actor:transfer_item(item, box) end db.actor:inventory_for_each(transfer_object_item) end local spawn_items = {} if has_alife_info("bar_arena_fight_1") then table.insert(spawn_items, "wpn_pm") table.insert(spawn_items, "ammo_9x18_pmm") table.insert(spawn_items, "ammo_9x18_pmm") --table.insert(spawn_items, "wpn_knife") elseif has_alife_info("bar_arena_fight_2") then table.insert(spawn_items, "wpn_mp5") table.insert(spawn_items, "ammo_9x19_pbp") --table.insert(spawn_items, "wpn_knife") elseif has_alife_info("bar_arena_fight_3") then table.insert(spawn_items, "wpn_bm16") table.insert(spawn_items, "ammo_12x70_buck") table.insert(spawn_items, "ammo_12x70_buck") --table.insert(spawn_items, "wpn_knife") elseif has_alife_info("bar_arena_fight_4") then table.insert(spawn_items, "wpn_ak74") table.insert(spawn_items, "ammo_5.45x39_ap") table.insert(spawn_items, "ammo_5.45x39_ap") --table.insert(spawn_items, "wpn_knife") table.insert(spawn_items, "bandage") table.insert(spawn_items, "bandage") elseif has_alife_info("bar_arena_fight_5") then table.insert(spawn_items, "wpn_abakan") table.insert(spawn_items, "ammo_5.45x39_ap") table.insert(spawn_items, "ammo_5.45x39_ap") table.insert(spawn_items, "ammo_5.45x39_ap") --table.insert(spawn_items, "wpn_knife") table.insert(spawn_items, "bandage") table.insert(spawn_items, "medkit") table.insert(spawn_items, "svoboda_light_outfit") elseif has_alife_info("bar_arena_fight_6") then table.insert(spawn_items, "wpn_groza") table.insert(spawn_items, "ammo_9x39_ap") table.insert(spawn_items, "ammo_9x39_ap") table.insert(spawn_items, "ammo_9x39_ap") --table.insert(spawn_items, "wpn_knife") table.insert(spawn_items, "grenade_f1") table.insert(spawn_items, "specops_outfit") elseif has_alife_info("bar_arena_fight_7") then table.insert(spawn_items, "wpn_knife") table.insert(spawn_items, "bandage") table.insert(spawn_items, "grenade_f1") table.insert(spawn_items, "grenade_f1") table.insert(spawn_items, "grenade_f1") table.insert(spawn_items, "grenade_f1") elseif has_alife_info("bar_arena_fight_8") then table.insert(spawn_items, "wpn_g36") table.insert(spawn_items, "exo_outfit") table.insert(spawn_items, "ammo_5.56x45_ap") table.insert(spawn_items, "ammo_5.56x45_ap") table.insert(spawn_items, "ammo_5.56x45_ap") table.insert(spawn_items, "ammo_5.56x45_ap") --table.insert(spawn_items, "wpn_knife") end local k,v = 0,0 for k,v in pairs(spawn_items) do alife():create(v, db.actor:position(), db.actor:level_vertex_id(), db.actor:game_vertex_id(), db.actor:id()) end end function bar_arena_weapon_slot (actor,npc,p) db.actor:activate_slot(tonumber(p[1]) or 1) end function bar_arena_teleport_2 (actor, npc) local hud = get_hud() if (hud) then hud:HideActorMenu() end -- remove items from actor given to him by arena local box = get_story_object("bar_arena_inventory_box_2") if (box) then local function transfer_object_item(item) db.actor:transfer_item(item, box) end db.actor:inventory_for_each(transfer_object_item) end -- purge all marked items xr_zones.purge_arena_items("bar_arena") level.add_pp_effector ("blink.ppe", 234, false) db.actor:set_actor_position(patrol("t_walk_2"):point(0)) local dir = patrol("t_look_2"):point(0):sub(patrol("t_walk_2"):point(0)) db.actor:set_actor_direction(-dir:getH()) -- give actor back his items that were taken local box = get_story_object("bar_arena_inventory_box") if (box) then local function transfer_object_item(box,item) box:transfer_item(item, db.actor) end box:iterate_inventory_box(transfer_object_item,box) end end function purge_zone(actor,npc,p) if (p and p[1]) then xr_zones.purge_arena_items(p[1]) end end function clear_weather(actor,npc,p) local wm = level_weathers.get_weather_manager() wm.current_state = "clear" --wm.next_state = "clear" wm:select_weather(true) end function actor_surge_immuned(actor,npc,p) utils.save_var(db.actor,"surge_immuned",p[1] == "true" or nil) end function force_always_online(actor,npc,p) local squad = p[1] and get_story_squad(p[1]) if not (squad) then return end alife():set_switch_offline(squad.id,false) alife():set_switch_online(squad.id,true) end -- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// --[[ Call of the Zone for IWP Indev 2 New "show location" functions for the different tasks. These are used to show the location of various tasks (locate the PDA, search the stash, etc.). --]] -- ===================================================================== -- Function Name: -- moon_cotz_show_stored_smart_target_location -- -- Description: -- Used to show the "area-of-operations" for a task in the -- dialog box. -- -- Used by the following task types: -- - Float item tasks (the ones where you have -- to find a dropped item in a building) -- - Guide tasks -- - Mutant hunt tasks -- - Find missing NPC tasks -- -- Usage: -- moon_cotz_show_stored_smart_target_location(p[1]) -- -- Parameters: -- p[1] (type: string, task section name) -- - Name of the task calling this function. -- p[2] (type: string, location name) -- - Name of the location to spawn the item in. -- p[3] (type: string, item section name) -- - Name of the desired item (for float tasks). -- -- Persistent Storage: -- N/A -- -- Return Value: -- N/A -- ===================================================================== -- Call of the Zone for IWP -- Indev 2 -- -- Authors: moonshroom -- Last modified: Jul 3, 2024, 11:42 AM -- ===================================================================== function moon_cotz_show_stored_smart_target_location(actor, npc, p) local drx_ql_ini = ini_file( "drx\\drx_ql_locations.ltx" ) -- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -- VERIFICATION CHECKS if ( not p[1] ) then printf("CotZ for IWP | xr_effects.script | moon_cotz_show_stored_smart_target_location() | ERR: Invalid parameters given.") -- Ensure parameters were correctly given when calling. return false end if ( not db.actor ) then printf("CotZ for IWP | xr_effects.script | moon_cotz_show_stored_smart_target_location() | ERR: db.actor does not exist.") -- Ensure player exists. return false end local npc_id = utils.load_var( db.actor, "drx_ql_current_npc_speaker_id", nil ) if ( npc_id == nil ) then printf("CotZ for IWP | xr_effects.script | moon_cotz_show_stored_smart_target_location() | ERR: Could not get ID of the NPC currently speaking.") -- Ensure player is talking to someone. return false end local location_was_given = false -- VAR: boolean for if location was given. if ( p[2] and p[2] ~= "nil" ) then -- If specific location was given... location_was_given = true -- Set location_was_given to true. end local item_was_given = false -- VAR: boolean for if item to fetch was given. if ( p[3] and p[3] ~= "nil" ) then -- If item to fetch was given... item_was_given = true -- Set item_was_gvien to true. end -- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// local task_id = p[1] -- Task name. local item_name -- Item name to be shown (if p[3] was given) local location_name -- Special location name (if p[2] was given) local target_level -- Level target is in (if p[2] was given) if (item_was_given == true) then item_name = system_ini():r_string_ex( p[3], "inv_name" ) end if ( location_was_given == true ) then -- If specific location was given, then... location_name = p[2] -- Get the special location name. local target_gvid = drx_ql_ini:r_float_ex( location_name, "gvid" ) -- Get pos values of the location from the ini file. if ( target_gvid ) then -- If given location found in ini... target_level = alife():level_name( game_graph():vertex( target_gvid ):level_id() ) -- Set target level using gvid. else -- If given location not found in ini, likely smart terrain name, so... local id = SIMBOARD.smarts_by_names[location_name].id -- Grab id attached to smart terrain name. local se_obj = alife():object( id ) -- Grab server object using id. if ( se_obj ) then -- If server object was found, then... target_level = alife():level_name( game_graph():vertex( se_obj.m_game_vertex_id ):level_id() ) -- Set target level using server object's m_game_vertex_id. end end else -- Else... (no specific location was given) local id = utils.load_var( db.actor, string.format( "drx_ql_%s_%s_target_smart", task_id, npc_id ) ) -- Grab id from whatever stored smart target variable. local se_obj = alife():object( id ) -- Grab server object using id. if ( se_obj ) then -- If server object was found, then... target_level = alife():level_name( game_graph():vertex( se_obj.m_game_vertex_id ):level_id() ) -- Set target level using server object's m_game_vertex_id. end end -- Show task information in the dialog box. local function postpone_for_next_frame( target_level ) -- Local function for showing information in dialog box. local news_caption = game.translate_string( task_manager.task_ini:r_string_ex( task_id, "title" ) ) -- VAR: Title of the task. local news_text -- VAR: Actual information to be formatted. if (item_name or item_was_given == true) then -- If item to fetch was specified, then... news_text = string.format( "%s %s\\n %s %s", -- Format information as: game.translate_string( "st_desired_item" ), game.translate_string( item_name ), -- "Desired item: " game.translate_string( "st_location" ), game.translate_string( target_level ) ) -- "Location: " else -- Else... (no item to fetch given) news_text = string.format( "%s %s", -- Format information as: game.translate_string( "st_location" ), game.translate_string( target_level ) ) -- "Location: " end db.actor:give_talk_message2( news_caption, news_text, task_manager.task_ini:r_string_ex( p[1], "icon" ), "iconed_answer_item" ) -- Grab task icon. return true end CreateTimeEvent( 0, "moon_cotz_show_stored_smart_target_location", 0, postpone_for_next_frame, target_level ) -- Create time event for displaying task inforamtion. return -- Return. -- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// end -- ===================================================================== -- Function Name: -- moon_cotz_show_fetch_task_info -- -- Description: -- Used to show the desired item for a fetch task. -- -- Usage: -- moon_cotz_show_fetch_task_info(p[1]) -- -- Parameters: -- p[1] (type: string, task section name) -- - Name of the task calling this function. -- -- Persistent Storage: -- N/A -- -- Return Value: -- N/A -- ===================================================================== -- Call of the Zone for IWP -- Indev 2 -- -- Authors: moonshroom -- Last modified: Jul 3, 2024, 11:47 AM -- ===================================================================== function moon_cotz_show_fetch_task_info( actor, npc, p ) -- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -- VERIFICATION CHECKS -- Ensure parameters were correctly given. if ( not p[1] ) then printf("CotZ for IWP | xr_effects.script | moon_cotz_show_fetch_task_info() | ERR: Invalid parameters given.") return false end -- Ensure player exists. if ( not db.actor ) then printf("CotZ for IWP | xr_effects.script | moon_cotz_show_fetch_task_info() | ERR: db.actor does not exist.") return end -- Ensure player is talking to someone. local npc_id = utils.load_var( db.actor, "drx_ql_current_npc_speaker_id", nil ) if ( not npc_id ) then printf("CotZ for IWP | xr_effects.script | moon_cotz_show_fetch_task_info() | ERR: Could not get ID of the NPC currently speaking.") return false end -- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -- Get fetch amount. -- local count = utils.load_var( db.actor, string.format( "%s_fetch_count", p[1] ) ) or dialogs._FETCH_COUNT -- Show task location in the dialog box. local function postpone_for_next_frame( ) local news_caption_unformatted = game.translate_string( task_manager.task_ini:r_string_ex( p[1], "title" ) ) -- Unformatted task title (contains a %s). local news_caption = string.format(news_caption_unformatted, dialogs._FETCH_TEXT) -- Properly formatted task title. local news_text = string.format( "%s %s\\n %s %s", game.translate_string("st_desired_item"), dialogs._FETCH_TEXT, game.translate_string("st_desired_item_count"), dialogs._FETCH_COUNT ) -- "Desired item: | Amount: " db.actor:give_talk_message2( news_caption, news_text, task_manager.task_ini:r_string_ex( p[1], "icon" ), "iconed_answer_item" ) -- Icon used for the task. return true end -- Create time event for displaying target information CreateTimeEvent( 0, "drx_ql_show_fetch_task_info", 0, postpone_for_next_frame ) -- Set return value return -- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// end -- ===================================================================== -- Function Name: -- moon_cotz_show_brawl_task_info -- -- Description: -- Used to show the location of a brawl task. -- -- Usage: -- moon_cotz_show_brawl_task_info(p[1]) -- -- Parameters: -- p[1] (type: string, task section name) -- - Name of the task calling this function. -- -- Persistent Storage: -- N/A -- -- Return Value: -- N/A -- ===================================================================== -- Call of the Zone for IWP -- Indev 2 -- -- Authors: moonshroom -- Last modified: Jul 3, 2024, 11:47 AM -- ===================================================================== function moon_cotz_show_brawl_task_info(actor, npc, p) -- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -- VERIFICATION CHECKS -- Ensure correct paramters were given. if (not p[1]) then printf( "DRX QL Error: Unable to show brawl task info, invalid parameters supplied" ) return false end -- Ensure player exists. if ( not db.actor ) then printf( "DRX QL Error: Unable to brawl task info, db.actor not available" ) return end -- Ensure player is talking to someone. local npc_id = utils.load_var( db.actor, "drx_ql_current_npc_speaker_id", nil ) if (npc_id == nil) then printf( "DRX QL Error: Unable to show brawl task info, could not get id of current speaker" ) return false end -- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// local task_id = p[1] -- Task section name. local smart_name -- Name of the smart. local smart_id -- ID of the smart. local enemy_faction -- Faction player will be fighting. smart_name = utils.load_var(db.actor, string.format("drx_ql_%s_%s_enemy_smart_name", task_id, npc_id), nil) -- Get the name of the target smart terrain. printf("DRX QL: Smart terrain name is %s", game.translate_string(smart_name)) -- Check smart_name is not nil. if (not smart_name) then printf("DRX QL Error: Unable to give smart terrain target, no valid smart target specified") return false else smart_id = SIMBOARD.smarts_by_names[smart_name].id -- Get the ID of the smart terrain using its name. if (not smart_id) then -- Check smart_id is not nil. printf("DRX QL Error: Unable to show brawl task info, smart name to id translation failed") return false end end enemy_faction = utils.load_var(db.actor, string.format("drx_ql_%s_%s_enemy_faction", task_id, npc_id), nil) -- Get the enemy faction. printf("DRX QL: Enemy faction is %s", game.translate_string(enemy_faction)) if (not enemy_faction) then -- Check enemy_faction isn't nil. printf( "DRX QL Error: Unable to display brawl task target, no stored target found" ) return false end -- Show task information in dialog box. local function postpone_for_next_frame(smart_id) local se_obj = alife():object(smart_id) if (se_obj) then local news_caption = game.translate_string( task_manager.task_ini:r_string_ex( p[1], "title" ) ) local news_text = string.format("%s %s\\n %s %s", game.translate_string("st_mm_faction_cap_faction"), game.translate_string(enemy_faction), game.translate_string("st_location"), game.translate_string(alife():level_name(game_graph():vertex(se_obj.m_game_vertex_id):level_id()))) db.actor:give_talk_message2(news_caption, news_text, task_manager.task_ini:r_string_ex( p[1], "icon" ), "iconed_answer_item") return true end end -- Create time event for displaying target information CreateTimeEvent( 0, "drx_ql_show_brawl_task_info", 0, postpone_for_next_frame, smart_id) -- Set return value return end function moon_cotz_update_important_phase( actor, npc, p ) -- Load the config file. local ini = ini_file( "drx\\drx_ql_config.ltx" ) if ( not ini ) then printf( "DRX QL Error: Unable to generate dynamic task, cannot locate ini file" ) return false end -- Verify actor is available. if ( not db.actor ) then printf( "DRX QL Error: Unable to generate dynamic task, db.actor not available" ) return false end -- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// local current_phase = 1 -- Initialize current phase variable. local phase_list = alun_utils.collect_section( ini, "important_task_phases" ) -- Gather all phases (phase_1, phase_2, ...) from ini. -- Go through every phase in phase list for i = 1, ( #phase_list ) do local info_list = alun_utils.parse_list( ini, "important_task_phases", string.format( "phase_%s", i ) ) -- Gather all infoportions from selected phase. -- Go through all listed infoportions in the selected phase. for j = 1, ( #info_list ) do -- If at least one of the infoportions in the selected phase is missing, set current phase to selected phase. if ( not has_alife_info( info_list[j] ) ) then current_phase = i goto continue end end end -- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ::continue:: utils.save_var( db.actor, "drx_ql_important_task_phase", current_phase ) printf( "CotZ for IWP | xr_effects.script / moon_cotz_update_important_phase() | DBG: Current important task phase is: %s", current_phase ) return end function moon_cotz_can_use_force_important_task( actor, npc, p ) -- Verify db.actor is available: if ( not db.actor ) then printf( "CotZ for IWP | xr_effects.script / moon_cotz_can_use_force_important_task() | [ERR] db.actor not available." ) return false end -- Get settings file: local ini = ini_file( "drx\\drx_ql_config.ltx" ) if ( not ini ) then printf( "CotZ for IWP | xr_effects.script / moon_cotz_can_use_force_important_task() | [ERR] Cannot find ini file." ) return false end -- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// local is_endgame = drx_ql_dialog_funcs.drx_ql_is_end_game( nil, nil ) or false local is_faction_valid = false local actor_faction = alife():actor():community() actor_faction = string.gsub( actor_faction, "actor_", "" ) local important_factions = alun_utils.collect_section( ini, "important_factions" ) if ( ( not important_factions ) or ( #important_factions < 1 ) ) then printf( "CotZ for IWP | xr_effects.script / moon_cotz_can_use_force_important_task() | [ERR] Cannot find important factions list, will not use force important task system." ) return false end for i = 1, ( #important_factions ) do if ( actor_faction == important_factions[i] ) then is_faction_valid = true break end end if ( is_endgame == false ) and ( is_faction_valid == true ) then printf( "CotZ for IWP | xr_effects.script / moon_cotz_can_use_force_important_task() | [DBG] Player can use force important task system." ) return true end printf( "CotZ for IWP | xr_effects.script / moon_cotz_can_use_force_important_task() | [DBG] Player cannot use force important task system." ) return false end -- Reset info portions of Faction Base Defense tasks. function reset_base_defense_task() disable_info( "faction_base_defense_enemy_killed" ) disable_info( "faction_base_defense_2nd_enemy_killed" ) disable_info( "yan_faction_base_defense_zombi_wave_1_killed" ) disable_info( "yan_faction_base_defense_zombi_wave_2_killed" ) disable_info( "yan_faction_base_defense_zombi_wave_3_killed" ) disable_info( "yan_faction_base_defense_zombi_wave_4_killed" ) disable_info( "yan_faction_base_defense_zombi_wave_5_killed" ) disable_info( "yan_faction_base_defense_zombi_wave_6_killed" ) disable_info( "yan_faction_base_defense_zombi_wave_7_1_killed" ) disable_info( "yan_faction_base_defense_zombi_wave_7_2_killed" ) disable_info( "yan_faction_base_defense_zombi_wave_7_3_killed" ) end