sr2lua/ss01.lua

  1. -- ss01.lua 
  2. -- SR2 mission script 
  3. -- 3/28/07 
  4.  
  5. -- Mission help table text tags 
  6.    DISPLAY_NAME = "ss01_display_name" 
  7.    HT_DRIVE_TO_UNIVERSITY = "ss01_drive_to_university" 
  8.    HT_TEMP_SHAUNDI_BLAH = "ss01_temp_shaundi_blah" 
  9.    HT_KILL_DRUG_DEALERS = "ss01_kill_drug_dealers" 
  10.    HT_FIND_MR_GABBY = "ss01_find_mr_gabby" 
  11.    HT_CATCH_UP = "ss01_catch_up" 
  12.    HT_DRUG_DEALERS_ESCAPED = "ss01_drug_dealers_escaped" 
  13.    HT_MR_GABBY_ESCAPED = "ss01_mr_gabby_escaped" 
  14.    HT_GET_A_SAMPLE = "ss01_get_a_sample" 
  15.    HT_GRAB_STASH = "ss01_grab_stash" 
  16.    HT_LOOSE_STASH = "ss01_loose_stash" 
  17.    HT_TAKE_OUT_MR_GABBY = "ss01_take_out_mr_gabby" 
  18.    HT_X_OF_Y_PACKAGES_COLLECTED = "ss01_x_of_y_packages" 
  19.    HT_GET_SAMPLES_TO_SHAUNDI = "ss01_get_samples_to_shaundi" 
  20.    HT_GRAB_UNION_PACKAGE = "ss01_grab_union_package" 
  21.    HT_GRAB_PARKING_LOT_PACKAGE = "ss01_grab_parking_lot_package" 
  22.    HT_BUDDY_COLLECTED_PACKAGE = "ss01_buddy_collected_package" 
  23.  
  24. -- Groups, NPCs, vehicles, navpoints, and other names 
  25.    REACHED_GOAL_DISTRICT_CHECKPOINT = "Reached_Goal_District" 
  26.    KILLED_INITIAL_DEALERS_CHECKPOINT = "Killed_Initial_Dealers" 
  27.  
  28.    DEFAULT_PISTOL = "beretta" 
  29.    DEFAULT_SMG = "tec9" 
  30.  
  31.    MISSION_NAME = "ss01" 
  32.  
  33.    LOA_DUST_NAME = "loa_dust_package" 
  34.  
  35.    START_NAVPOINT_NAME = "mission_start_sr2_city_$ss01" 
  36.    START_NAVPOINT_NAME_COOP_PLAYER = "ss01_$Coop_Player_Start" 
  37.  
  38.    STARTING_CAR_GROUP_NAME = MISSION_NAME.."_$Starting_Car" 
  39.    STARTING_CAR_COOP_GROUP_NAME = "ss01_$Starting_Car_Coop" 
  40.  
  41.    SAINTS_PARKING_LOT_TRIGGER_NAME = "ss01_$Saints_Parking_Lot_Area" 
  42.  
  43.    UNIVERSITY_LOCATION_NAVPOINT_NAME = "ss01_$University_Location" 
  44.  
  45.    DRUG_DEALER_GROUP_NAMES = { "ss01_$Dealer_Group_01", "ss01_$Dealer_Group_02" } 
  46.    DRUG_DEALER_GROUP_COOP_SUFFIX = "c" 
  47.    DEALER_GROUP_LOCATION_NAVPOINT_NAMES = { "ss01_$Group1_Location", "ss01_$Group2_Location" } 
  48.    DEALER_GROUP_TRIGGER_NAMES = { "ss01_$Group1_Location_Trigger", "ss01_$Group2_Location_Trigger" } 
  49.  
  50.    DEALER_GROUP_CHUNK_NAMES = { "sr2_chunk106", "sr2_chunk085" } 
  51.  
  52.    FINAL_DRUG_DEALER_GROUP_NAVPOINT_NAME = "ss01_$Group3_Location" 
  53.    FINAL_DEALER_TRIGGER_NAME = "ss01_$Group3_Location_Trigger" 
  54.    FINAL_DRUG_DEALER_GROUP_NAME = "ss01_$Dealer_Group_03" 
  55.    FINAL_DEALER_GROUP_VEHICLE_NAME = "ss01_$Group3_v1" 
  56.    FINAL_GROUP_GROUP_NUMBER = 3 
  57.  
  58.    NEIGHBORHOOD_NAMES = { "sr2_ss_university01", "sr2_ss_university02" } 
  59.    GOAL_DISTRICT_NAME = "University" 
  60.  
  61.    MISSION_END_POINT_TRIGGER = "ss01_$Mission_End_Point" 
  62.  
  63.    -- Action Node States 
  64.    SELL_DRUGS = "DrugDealer" 
  65.    BUY_DRUGS = "DrugBuyer" 
  66.  
  67.    -- Group member name: 
  68.    -- GROUP_MEMBER_GROUP_PREFIX..group_index..GROUP_MEMBER_MEMBER_PREFIX..member_index 
  69.    -- Coop group member name: 
  70.    -- GROUP_MEMBER_GROUP_PREFIX..group_index..GROUP_MEMBER_COOP_MEMBER_PREFIX..member_index 
  71.    GROUP_MEMBER_GROUP_PREFIX = "ss01_$Group" 
  72.    GROUP_MEMBER_COOP_PREFIX = "c" 
  73.    GROUP_MEMBER_MEMBER_PREFIX = "_Member_0" 
  74.    GROUP_MEMBER_COOP_MEMBER_PREFIX = GROUP_MEMBER_COOP_PREFIX..GROUP_MEMBER_MEMBER_PREFIX 
  75.  
  76.    GROUP_ONE_BUYERS = { "ss01_$Buyer03", "ss01_$Buyer04" } 
  77.    GROUP_TWO_BUYERS = { "ss01_$Buyer01", "ss01_$Buyer02" } 
  78.  
  79.    GROUPS_POSSIBLE_PACKAGE_HOLDERS = { { "ss01_$Group1_Member_03", "ss01_$Group1_Member_04" }, 
  80.                                        { "ss01_$Group2_Member_03", "ss01_$Group2_Member_04", "ss01_$Group2_Member_05" } } 
  81.  
  82.    GROUPS_DRUG_DEALERS = { { "ss01_$Group1_Member_02", "ss01_$Group1_Member_04" }, 
  83.                            { "ss01_$Group2_Member_03", "ss01_$Group2_Member_04" } } 
  84.  
  85.    CUTSCENE_BUYING_CHARACTER = "ss01_$Drug_Buyer_Cutscene" 
  86.  
  87.    ENEMY_GANG = "samedi" 
  88.    -- Cutscenes 
  89.    CUTSCENE_NAME = "IG_ss01_scene1" 
  90.    CT_INTRO = "ss01-01" 
  91.    CT_OUTRO = "ss01-02" 
  92.  
  93. 	ESCAPE_PATHS = { "ss01_$Escape_Path_01", "ss01_$Escape_Path_02", "ss01_$Escape_Path_03", 
  94. 						  "ss01_$Escape_Path_04", "ss01_$Escape_Path_05", "ss01_$Escape_Path_06" } 
  95.  
  96. -- Audio/Dialog streams 
  97.    SONS_OF_SAMEDI_INTRODUCTION_DIALOG_STREAM = 
  98.    { 
  99.    { "SOS1_BACKGROUND_L1", nil, 0 }, 
  100.    { "PLAYER_SOS1_BACKGROUND_L2", LOCAL_PLAYER, 0 }, 
  101.    { "SOS1_BACKGROUND_L3", nil, 0 }, 
  102.    { "PLAYER_SOS1_BACKGROUND_L4", LOCAL_PLAYER, 0 }, 
  103.    { "SOS1_BACKGROUND_L5", nil, 0 }, 
  104.    { "PLAYER_SOS1_BACKGROUND_L6", LOCAL_PLAYER, 0 } 
  105.    } 
  106.    SONS_OF_SAMEDI_CAR_DEALER_GROUP_DIALOG_STREAM = 
  107.    { 
  108.    { "PLAYER_SOS1_UNHIDDEN_L1", LOCAL_PLAYER, 0 }, 
  109.    { "SOS1_UNHIDDEN_L2", nil, 0 } 
  110.    } 
  111.    SONS_OF_SAMEDI_FINAL_DIALOG_STREAM =  
  112.    { 
  113.    { "PLAYER_SOS1_FINAL_L1", LOCAL_PLAYER, 0 }, 
  114.    { "SOS1_FINAL_L2", nil, 0 } 
  115.    } 
  116.  
  117. -- Distances 
  118.    MAX_ALLOWED_CAR_CHASE_DISTANCE_METERS = 70.0 
  119.    WANDER_RADIUS_METERS = 2.0 
  120.    ADD_PATH_CUTOFF_DIST_METERS = 20 
  121.    ACTION_NODE_SEARCH_RADIUS_METERS = 20 
  122.  
  123. -- Percents and multipliers 
  124.    MR_GABBY_CAR_HIT_POINTS_PERCENT = 0.8 
  125.  
  126. -- Time values 
  127.    OUT_OF_GROUP_AREA_FAIL_TIME_SECONDS = 30.0 
  128.    VICTORY_DELAY_SECONDS = 3.0 
  129.    CAR_CHASE_OUT_OF_RANGE_FAIL_TIME_MS = 30000 
  130.    BEFORE_CELLPHONE_CALL_DELAY_SECONDS = 4.0 
  131.    AFTER_CELLPHONE_CALL_DELAY_SECONDS = 5.0 
  132.    COMPLETE_IDIOT_TIME_SECONDS = 60.0 
  133.    SHAUNDI_START_BLATHERING_SECONDS = 2 
  134. 	BEFORE_UNLEASH_DELAY_SECONDS = 4.0 
  135.    AFTER_FINAL_PACKAGE_COLLECTED_DELAY_SECONDS = 4.0 
  136.  
  137. -- Speeds 
  138.    DEALER_CAR_MAX_SPEED_MPS = 45 
  139.  
  140. -- Constant values and counts 
  141.    INITIAL_DRUG_DEALER_GROUP_COUNT = sizeof_table( DRUG_DEALER_GROUP_NAMES ) 
  142.  
  143.    GROUP1_DEALER_COUNT = 4 
  144.    GROUP1c_DEALER_COUNT = 2 
  145.  
  146.    GROUP2_DEALER_COUNT = 5 
  147.    GROUP2c_DEALER_COUNT = 2 
  148.  
  149.    GROUP_DEALER_COUNTS = { GROUP1_DEALER_COUNT, GROUP2_DEALER_COUNT } 
  150.    GROUP_DEALER_COUNTS_COOP = { GROUP1c_DEALER_COUNT, GROUP2c_DEALER_COUNT } 
  151.  
  152.    FINAL_GROUP_MEMBER_COUNT = 3 
  153.    TOTAL_LOA_DUST_TO_COLLECT = 3 
  154.    LOA_DUST_TO_COLLECT_INITIAL = 2 
  155.  
  156.    END_MISSION_NOTORIETY = 2 
  157.  
  158.    STUDENT_UNION_DEALERS_GROUP_INDEX = 2 
  159.    PARKING_LOT_DEALERS_GROUP_INDEX = 1 
  160.  
  161. -- Global variables 
  162.    Num_dealer_groups_remaining = INITIAL_DRUG_DEALER_GROUP_COUNT 
  163.    Group_members_remaining = {} 
  164.    Failure_thread_handles = { [LOCAL_PLAYER] = nil, [REMOTE_PLAYER] = nil } 
  165.  
  166.    Group_committed_to_kill = { [LOCAL_PLAYER] = nil, [REMOTE_PLAYER] = nil } 
  167.  
  168.    Goal_district_reached = false 
  169.  
  170.    Group1_member_names = {} 
  171.    Group2_member_names = {} 
  172.    Group1_member_names_coop = {} 
  173.    Group2_member_names_coop = {} 
  174.    Final_group_member_names = {} 
  175.    Final_group_members_remaining = FINAL_GROUP_MEMBER_COUNT 
  176.  
  177.    Groups = { Group1_member_names, Group2_member_names } 
  178.    Groups_coop = { Group1_member_names_coop, Group2_member_names_coop } 
  179.    Loa_dust_collected = 0 
  180.  
  181.    Cur_dealer_group_path_location = { LOCAL_PLAYER = "none", REMOTE_PLAYER = "none" } 
  182.  
  183.    Update_waypoint_thread_handle = INVALID_THREAD_HANDLE 
  184.    Dealer_vehicle_escape_thread = INVALID_THREAD_HANDLE 
  185.    Groups_cleared = { false, false, false } 
  186.    Get_sample_ht_played = { [LOCAL_PLAYER] = false, [REMOTE_PLAYER] = false } 
  187.    Pickup_package_prompt_thread_handles = { INVALID_THREAD_HANDLE, INVALID_THREAD_HANDLE } 
  188.    Group_dropped_sample = { false, false, false } 
  189.    Reached_district_checkpoint_set = false 
  190.    Shaundi_call_received = false 
  191.  
  192. 	Group_flee_triggered = false 
  193.  
  194. -- Start and init function 
  195. -- Creates the groups and adds initial waypoint and other guidance. 
  196. -- 
  197. function ss01_start( checkpoint_name, is_restart ) 
  198.    -- Start trigger is hit...the activate button was hit 
  199.    set_mission_author("Mark Gabby and Brad Johnson") 
  200.  
  201.    mission_start_fade_out() 
  202.    if ( checkpoint_name == MISSION_START_CHECKPOINT ) then 
  203. 		-- Setup appropriate lists of starter vehicles based on SP or Coop 
  204. 		local starter_groups = { DRUG_DEALER_GROUP_NAMES[1], DRUG_DEALER_GROUP_NAMES[2], FINAL_DRUG_DEALER_GROUP_NAME, STARTING_CAR_GROUP_NAME } 
  205. 		if ( coop_is_active() ) then 
  206. 			starter_groups = { DRUG_DEALER_GROUP_NAMES[1], DRUG_DEALER_GROUP_NAMES[2], FINAL_DRUG_DEALER_GROUP_NAME, STARTING_CAR_GROUP_NAME, STARTING_CAR_COOP_GROUP_NAME } 
  207. 		end 
  208.  
  209. 		if ( is_restart == false ) then 
  210. 			cutscene_play( CT_INTRO, starter_groups, { START_NAVPOINT_NAME, START_NAVPOINT_NAME_COOP_PLAYER }, false ) 
  211. 			for index, group_name in pairs( starter_groups ) do 
  212. 				group_show( group_name ) 
  213. 			end 
  214. 		else 
  215. 			for index, group_name in pairs( starter_groups ) do 
  216. 				group_create( group_name, true ) 
  217. 			end 
  218. 		end 
  219.    end 
  220.  
  221. 	-- Teleport after all groups are loaded - helps with loading times 
  222. 	if ( checkpoint_name == MISSION_START_CHECKPOINT and is_restart ) then 
  223. 		teleport_coop( START_NAVPOINT_NAME, START_NAVPOINT_NAME_COOP_PLAYER ) 
  224. 	end 
  225.  
  226.    spawning_allow_gang_team_ambient_spawns( HUMAN_TEAM_SAMEDI, false ) 
  227.  
  228.    -- Setup mission item callbacks here - they should always be called 
  229.    on_mission_item_pickup( "ss01_loa_dust_picked_up" ) 
  230.    on_mission_item_drop( "ss01_loa_dust_dropped" ) 
  231.  
  232.    if ( checkpoint_name == MISSION_START_CHECKPOINT ) then 
  233.       -- Add callback for the player getting a phone call from Shaundi 
  234.       trigger_enable( SAINTS_PARKING_LOT_TRIGGER_NAME, true ) 
  235.       on_trigger_exit( "ss01_shaundi_blah", SAINTS_PARKING_LOT_TRIGGER_NAME ) 
  236.       notoriety_force_no_spawn( ENEMY_GANG, true ) 
  237.  
  238.       -- Add callbacks for district changed in order to update objectives 
  239.       -- once the players reach the University district 
  240.       on_district_changed( "ss01_district_changed", LOCAL_PLAYER ) 
  241.       on_district_changed( "ss01_district_changed", REMOTE_PLAYER ) 
  242.  
  243.       ss01_setup_first_two_groups() 
  244.    elseif ( checkpoint_name == REACHED_GOAL_DISTRICT_CHECKPOINT ) then 
  245. 		group_create_hidden( FINAL_DRUG_DEALER_GROUP_NAME, true ) 
  246.       ss01_setup_first_two_groups() 
  247.    elseif ( checkpoint_name == KILLED_INITIAL_DEALERS_CHECKPOINT ) then 
  248.       Loa_dust_collected = LOA_DUST_TO_COLLECT_INITIAL 
  249.  
  250.       -- Spawn the final goal 
  251.       mission_debug( "About to create final drug group." ) 
  252. 		group_create_hidden( FINAL_DRUG_DEALER_GROUP_NAME, true ) 
  253.       ss01_create_final_drug_dealer_group( true ) 
  254.    end 
  255.  
  256. 	mission_start_fade_in() 
  257.  
  258.    -- Guide the players 
  259.    notoriety_set_max( ENEMY_GANG, END_MISSION_NOTORIETY ) 
  260.    notoriety_set_max( "police", END_MISSION_NOTORIETY ) 
  261.     
  262.    if ( checkpoint_name == MISSION_START_CHECKPOINT ) then 
  263.       mission_help_table( HT_DRIVE_TO_UNIVERSITY ) 
  264.       district_set_pulsing( GOAL_DISTRICT_NAME, true, SYNC_ALL ) 
  265.       waypoint_add( UNIVERSITY_LOCATION_NAVPOINT_NAME, SYNC_ALL ) 
  266.       marker_add_navpoint( UNIVERSITY_LOCATION_NAVPOINT_NAME, MINIMAP_ICON_LOCATION, "", SYNC_ALL ) 
  267.    elseif ( checkpoint_name == REACHED_GOAL_DISTRICT_CHECKPOINT ) then 
  268.  
  269.       Goal_district_reached = true 
  270.  
  271.       ss01_prompt_and_guide_for_first_two_groups( SYNC_ALL ) 
  272.    elseif ( checkpoint_name == KILLED_INITIAL_DEALERS_CHECKPOINT ) then 
  273.       objective_text(0, HT_X_OF_Y_PACKAGES_COLLECTED, Loa_dust_collected, TOTAL_LOA_DUST_TO_COLLECT ) 
  274.    end 
  275. end 
  276.  
  277. function ss01_shaundi_call_received() 
  278.    Shaundi_call_received = true 
  279. end 
  280.  
  281. function ss01_shaundi_and_player_converse() 
  282.    mid_mission_phonecall("ss01_shaundi_call_received") 
  283.    repeat 
  284.       thread_yield() 
  285.    until Shaundi_call_received or Goal_district_reached 
  286.  
  287.    if ( Shaundi_call_received ) then 
  288.       audio_play_conversation( SONS_OF_SAMEDI_INTRODUCTION_DIALOG_STREAM, INCOMING_CALL ) 
  289.    end 
  290.    mid_mission_phonecall_reset() 
  291. end 
  292.  
  293.  
  294. function ss01_shaundi_blah() 
  295.    trigger_enable( SAINTS_PARKING_LOT_TRIGGER_NAME, false ) 
  296.    delay( SHAUNDI_START_BLATHERING_SECONDS ) 
  297.  
  298.    ss01_shaundi_and_player_converse() 
  299. end 
  300.  
  301. function ss01_inform_player_of_final_goal() 
  302.    delay( BEFORE_CELLPHONE_CALL_DELAY_SECONDS ) 
  303.    audio_play_conversation( SONS_OF_SAMEDI_CAR_DEALER_GROUP_DIALOG_STREAM, OUTGOING_CALL ) 
  304.    mission_help_table( HT_FIND_MR_GABBY ) 
  305.    delay( AFTER_CELLPHONE_CALL_DELAY_SECONDS ) 
  306. end 
  307.  
  308. function ss01_setup_first_two_groups() 
  309.    -- Activate and setup the triggers for the inital drug dealer groups 
  310.    for index, trigger in pairs( DEALER_GROUP_TRIGGER_NAMES ) do 
  311.       trigger_enable( trigger, true ) 
  312.       on_trigger( "ss01_entered_group_trigger", trigger ) 
  313.       on_trigger_exit( "ss01_left_group_trigger", trigger ) 
  314.    end 
  315.  
  316.    -- Create the initial drug dealer groups, the names of their members, 
  317.    -- and add on-death callbacks for them. 
  318.    for index, group_name in pairs( DRUG_DEALER_GROUP_NAMES ) do 
  319. 		if ( group_is_loaded( group_name ) == false ) then 
  320. 	      group_create( group_name, true ) 
  321. 		end 
  322.       Group_members_remaining[index] = GROUP_DEALER_COUNTS[index] 
  323.       if ( coop_is_active() ) then 
  324.          Group_members_remaining[index] = Group_members_remaining[index] + GROUP_DEALER_COUNTS_COOP[index] 
  325.          group_create( group_name..DRUG_DEALER_GROUP_COOP_SUFFIX, true ) 
  326.       end 
  327.  
  328.       Groups[index], Groups_coop[index] = ss01_create_group_member_names( index, 
  329.                                                                           GROUP_DEALER_COUNTS[index], 
  330.                                                                           GROUP_DEALER_COUNTS_COOP[index] ) 
  331.  
  332.       ss01_group_setup_inventory( index, Groups[index], Groups_coop[index] ) 
  333.       ss01_group_add_death_callbacks( index, Groups[index], Groups_coop[index] ) 
  334.       ss01_group_begin_wander( index, Groups[index], Groups_coop[index] ) 
  335.    end 
  336. end 
  337.  
  338. -- Returns the group index for the passed-in trigger. 
  339. -- 
  340. function ss01_find_group_index_from_trigger_name( trigger_name ) 
  341.    local group_index 
  342.  
  343.    for index, trigger in pairs( DEALER_GROUP_TRIGGER_NAMES ) do 
  344.       if ( trigger_name == trigger ) then 
  345.          group_index = index 
  346.       end 
  347.    end 
  348.  
  349.    return group_index 
  350. end 
  351.  
  352. function ss01_group_play_action_node_actions( group_index ) 
  353.    while( city_chunk_has_extras_loaded( DEALER_GROUP_CHUNK_NAMES[group_index] ) == false ) do 
  354.       thread_yield() 
  355.    end 
  356.    mission_debug( "group "..group_index.."'s chunk has extras loaded.", 15 ) 
  357.  
  358.    for index, dealer_name in pairs( GROUPS_DRUG_DEALERS[group_index] ) do 
  359.       if ( character_is_dead( dealer_name ) == false and Groups_cleared[group_index] == false ) then 
  360.          mission_debug( dealer_name.." has been told to use an action node.", 15 ) 
  361.          npc_use_closest_action_node_of_type( dealer_name, SELL_DRUGS, ACTION_NODE_SEARCH_RADIUS_METERS ) 
  362.       end 
  363.       delay( 2.0 ) 
  364.    end 
  365. end 
  366.  
  367. -- Callback when the player enters one of the group triggers for the drug dealer groups. 
  368. -- 
  369. -- triggerer_name: The name of the person that triggered the trigger. 
  370. -- trigger_name: The name of the trigger than was triggered. 
  371. -- 
  372. function ss01_entered_group_trigger( triggerer_name, trigger_name ) 
  373.    local group_index = ss01_find_group_index_from_trigger_name( trigger_name ) 
  374.  
  375.    -- Play the help text letting the player know what to do if he hasn't had it told to him 
  376.    -- yet 
  377.    if ( Get_sample_ht_played[triggerer_name] == false ) then 
  378.       local sync_type = sync_from_player( triggerer_name ) 
  379.       mission_help_table( HT_GET_A_SAMPLE, "", "", sync_type ) 
  380.       Get_sample_ht_played[triggerer_name] = true 
  381.    end 
  382.  
  383.    -- Find out if the player that's wandered into this trigger is already committed to 
  384.    -- kill a group or not 
  385.    if ( Group_committed_to_kill[triggerer_name] ~= nil ) then 
  386.       -- If so, then if it's this group, kill the failure thread and let this 
  387.       -- player continue the fight 
  388.       if ( Group_committed_to_kill[triggerer_name] == group_index and 
  389.            Failure_thread_handles[triggerer_name] ~= nil ) then 
  390.          mission_debug( "stopped failure timer for "..triggerer_name ) 
  391.          thread_kill( Failure_thread_handles[triggerer_name] ) 
  392.          Failure_thread_handles[triggerer_name] = nil 
  393.       end 
  394.    -- If not, commit this player to do so 
  395.    else 
  396.       -- Have the dealers play their selling actions 
  397.       thread_new( "ss01_group_play_action_node_actions", group_index ) 
  398.  
  399.       local sync_type = sync_from_player( triggerer_name ) 
  400.       for index, navpoint_name in pairs( DEALER_GROUP_LOCATION_NAVPOINT_NAMES ) do 
  401.          mission_debug( "Entered trigger. Removing marker for "..navpoint_name..".", 15 ) 
  402.          marker_remove_navpoint( navpoint_name, sync_type ) 
  403.       end 
  404.       waypoint_remove( sync_type ) 
  405.  
  406.       if ( Update_waypoint_thread_handle ~= INVALID_THREAD_HANDLE ) then 
  407.          thread_kill( Update_waypoint_thread_handle ) 
  408. 	      Update_waypoint_thread_handle = INVALID_THREAD_HANDLE 
  409.       end 
  410.  
  411.       Group_committed_to_kill[triggerer_name] = group_index 
  412.  
  413.       Groups[group_index], Groups_coop[group_index] = ss01_create_group_member_names( group_index, 
  414.                                                                                       GROUP_DEALER_COUNTS[group_index], 
  415.                                                                                       GROUP_DEALER_COUNTS_COOP[group_index] ) 
  416.  
  417.       local other_group_index = STUDENT_UNION_DEALERS_GROUP_INDEX 
  418.       if ( group_index == STUDENT_UNION_DEALERS_GROUP_INDEX ) then 
  419.          other_group_index = PARKING_LOT_DEALERS_GROUP_INDEX 
  420.       end 
  421.  
  422.       -- Only mark this group if there isn't a loose package 
  423.       local package_is_loose = false 
  424.       if ( Group_dropped_sample[other_group_index] and 
  425.            Groups_cleared[other_group_index] == false ) then 
  426.          package_is_loose = true 
  427.       end 
  428.       if ( package_is_loose == false ) then 
  429.          ss01_group_mark( sync_type, Groups[group_index], Groups_coop[group_index] ) 
  430.       end 
  431.    end 
  432. end 
  433.  
  434. -- Returns the group index that the npc with the passed-in name belongs to. 
  435. -- 
  436. function ss01_find_group_index_from_name( name ) 
  437.    -- Check the first group 
  438.    if ( ss01_is_member_in_group( name, Groups[1] ) or  
  439.         ss01_is_member_in_group( name, Groups_coop[1] ) ) then 
  440.       return 1; 
  441.    -- Check the second 
  442.    elseif ( ss01_is_member_in_group( name, Groups[2] ) or 
  443.             ss01_is_member_in_group( name, Groups_coop[2] ) ) then 
  444.       return 2; 
  445.    -- Check the last 
  446.    elseif ( ss01_is_member_in_group( name, Final_group_member_names ) ) then 
  447.       return 3; 
  448.    end 
  449. end 
  450.  
  451. -- Goes through all members in the passed-in list of names and checks to 
  452. -- see if the passed-in name is in the list. If so, returns true. Otherwise, 
  453. -- returns false. 
  454. -- 
  455. function ss01_is_member_in_group( name, group_member_names ) 
  456.    for index, member_name in pairs( group_member_names ) do 
  457.       if ( name == member_name ) then 
  458.          return true 
  459.       end 
  460.    end 
  461.  
  462.    return false 
  463. end 
  464.  
  465. function ss01_group_setup_inventory( group_index, group_member_names, group_member_names_coop ) 
  466.  
  467.    -- Give all the group members pistols only 
  468.    for index, member_name in pairs( group_member_names ) do 
  469.       inv_item_remove_all( member_name ) 
  470.       inv_item_add( DEFAULT_PISTOL, 1, member_name ) 
  471.    end 
  472.  
  473.    if ( coop_is_active() and group_member_names_coop ~= nil ) then 
  474.       for index, member_name in pairs( group_member_names_coop ) do 
  475.          inv_item_remove_all( member_name ) 
  476.          inv_item_add( DEFAULT_PISTOL, 1, member_name ) 
  477.       end 
  478.    end 
  479.  
  480.    -- Now, give one of the group members a submachine gun 
  481.    local num_members = sizeof_table( group_member_names ) 
  482.    local random_member_index = rand_int( 1, num_members ) 
  483.    inv_item_add( DEFAULT_SMG, 1, group_member_names[random_member_index] ) 
  484.  
  485.    -- Finally, give one of the group members the loa dust package 
  486.    --    ( among those who have the potential to have a package ) 
  487.    local members_that_might_have_packages = GROUPS_POSSIBLE_PACKAGE_HOLDERS[group_index] 
  488.    local num_potential_package_holders = sizeof_table( members_that_might_have_packages ) 
  489.  
  490.    random_member_index = rand_int( 1, num_potential_package_holders ) 
  491.    loot_item_add( LOA_DUST_NAME, members_that_might_have_packages[random_member_index] ) 
  492. end 
  493.  
  494. -- Adds death callbacks for the passed-in group. 
  495. -- 
  496. -- group_index: The index of this group. 
  497. -- group_member_names: The names of the group members. 
  498. -- group_member_names_coop: (Optional) The names of the coop additions to the group. 
  499. -- 
  500. function ss01_group_add_death_callbacks( group_index, group_member_names, group_member_names_coop ) 
  501.    for index, member_name in pairs( group_member_names ) do 
  502.       on_death( "ss01_group_member_died_group"..group_index, member_name ) 
  503.    end 
  504.  
  505.    if ( coop_is_active() and group_member_names_coop ~= nil ) then 
  506.       for index, member_name in pairs( group_member_names_coop ) do 
  507.          on_death( "ss01_group_member_died_group"..group_index, member_name ) 
  508.       end 
  509.    end 
  510. end 
  511.  
  512. -- Returns true if this member of this group is a drug dealer, false otherwise. 
  513. -- 
  514. -- group_index: Group this member belongs to. 
  515. -- member_name: Name of the member. 
  516. -- 
  517. -- Note that member_name might not actually belong to this group. It's up to the 
  518. -- caller to assure that. 
  519. -- 
  520. function ss01_member_is_dealer( group_index, member_name ) 
  521.    for index, dealer_name in pairs( GROUPS_DRUG_DEALERS[group_index] ) do 
  522.       if ( member_name == dealer_name ) then 
  523.          return true 
  524.       end 
  525.    end 
  526.    return false 
  527. end 
  528.  
  529. -- Makes the members of the passed-in group wander about. 
  530. -- 
  531. -- group_index: The index of this group. 
  532. -- group_member_names: The names of the group members. 
  533. -- group_member_names_coop: (Optional) The names of the coop additions to the group. 
  534. -- 
  535. function ss01_group_begin_wander( group_index, group_member_names, group_member_names_coop ) 
  536.    for index, member_name in pairs( group_member_names ) do 
  537.       -- We don't want dealers to wander, it'll mess up their action node attachments 
  538.       if ( ss01_member_is_dealer( group_index, member_name ) == false ) then 
  539.          wander_start(member_name, member_name, WANDER_RADIUS_METERS) 
  540.          mission_debug( member_name.." of group "..group_index.." told to wander.", 15 ) 
  541.       end 
  542.    end 
  543.  
  544.    if ( coop_is_active() and group_member_names_coop ~= nil ) then 
  545.       for index, member_name in pairs( group_member_names_coop ) do 
  546. 	      wander_start(member_name, member_name, WANDER_RADIUS_METERS)  
  547.       end 
  548.    end 
  549. end 
  550.  
  551. -- Adds minimap and on-screen markers to the members of the drug dealer group. 
  552. -- 
  553. -- sync_type: Whether to do this for the local player, the remote player, or both. 
  554. -- group_member_names: The names of the group members. 
  555. -- group_member_names_coop: (Optional) The names of the coop additions to the group. 
  556. -- 
  557. function ss01_group_mark( sync_type, group_member_names, group_member_names_coop ) 
  558.    for index, member_name in pairs( group_member_names ) do 
  559.       if ( character_is_dead(member_name ) == false ) then 
  560.          marker_add_npc( member_name, MINIMAP_ICON_KILL, INGAME_EFFECT_KILL, sync_type ) 
  561.       end 
  562.    end 
  563.  
  564.    if ( coop_is_active() and group_member_names_coop ~= nil ) then 
  565.       for index, member_name in pairs( group_member_names_coop ) do 
  566.          if ( character_is_dead(member_name ) == false ) then 
  567.             marker_add_npc( member_name, MINIMAP_ICON_KILL, INGAME_EFFECT_KILL, sync_type ) 
  568.          end 
  569.       end 
  570.    end 
  571. end 
  572.  
  573. -- Removes minimap and on-screen markers to the members of the drug dealer group. 
  574. -- 
  575. -- sync_type: Whether to do this for the local player, the remote player, or both. 
  576. -- group_member_names: The names of the group members. 
  577. -- group_member_names_coop: (Optional) The names of the coop additions to the group. 
  578. -- 
  579. function ss01_group_unmark( sync_type, group_member_names, group_member_names_coop ) 
  580.    for index, member_name in pairs( group_member_names ) do 
  581.       if ( character_is_dead(member_name ) == false ) then 
  582.          marker_remove_npc( member_name, sync_type ) 
  583.       end 
  584.    end 
  585.  
  586.    if ( coop_is_active() and group_member_names_coop ~= nil ) then 
  587.       for index, member_name in pairs( group_member_names_coop ) do 
  588.          if ( character_is_dead(member_name ) == false ) then 
  589.             marker_remove_npc( member_name, sync_type ) 
  590.          end 
  591.       end 
  592.    end 
  593. end 
  594.  
  595. -- Callback when a member of group 1 dies. 
  596. -- Calls ss01_group_member_died with group 1 as a parameter. 
  597. -- 
  598. function ss01_group_member_died_group1( member_name ) 
  599.    ss01_group_member_died( member_name, 1 ) 
  600. end 
  601.  
  602. -- Callback when a member of group 2 dies. 
  603. -- Calls ss01_group_member_died with group 2 as a parameter. 
  604. -- 
  605. function ss01_group_member_died_group2( member_name ) 
  606.    ss01_group_member_died( member_name, 2 ) 
  607. end 
  608.  
  609. -- Deals with updating that's required when a member of the initial 
  610. -- drug dealer groups dies. 
  611. -- 
  612. -- member_name: Name of the member who died. 
  613. -- group_index: The group that this member belongs to. 
  614. -- 
  615. function ss01_group_member_died( member_name, group_index ) 
  616.    -- Remove the marker and track the group count 
  617.    Group_members_remaining[group_index] = Group_members_remaining[group_index] - 1 
  618.    marker_remove_npc( member_name, SYNC_ALL ) 
  619.    mission_debug( Group_members_remaining[group_index].." group members remaining in group "..group_index ) 
  620. end 
  621.  
  622. function ss01_loa_dust_dropped( dropper_name ) 
  623.    local group_index = ss01_find_group_index_from_name( dropper_name ) 
  624.  
  625.    if ( group_index ~= nil ) then 
  626.       Group_dropped_sample[group_index] = true 
  627.  
  628.       mission_debug( "group "..group_index.." dropped a sample.", 10 ) 
  629.  
  630.       local player_responsible = "unknown" 
  631.  
  632.       -- Find out which player was committed to kill this group, and give an 
  633.       -- appropriate help text message if that player hasn't gotten one yet 
  634.       if ( group_index == 3 ) then 
  635.          mission_help_table( HT_GRAB_STASH, "", "", SYNC_ALL ) 
  636.       else 
  637. 			if ( Group_committed_to_kill[LOCAL_PLAYER] == group_index ) then 
  638. 				mission_help_table( HT_GRAB_STASH, "", "", SYNC_LOCAL ) 
  639. 				player_responsible = LOCAL_PLAYER 
  640. 			end 
  641. 			if ( Group_committed_to_kill[REMOTE_PLAYER] == group_index ) then 
  642. 				mission_help_table( HT_GRAB_STASH, "", "", SYNC_REMOTE ) 
  643. 				player_responsible = REMOTE_PLAYER 
  644. 			end 
  645. 		end 
  646.  
  647.       -- Find the first unused pickup prompt thread handle and spawn a pickup 
  648.       -- prompt thread there. This thread will prompt the player that killed the 
  649.       -- guy who dropped the package to pick it up. 
  650.       for index, thread_handle in pairs( Pickup_package_prompt_thread_handles ) do 
  651.          if ( thread_handle == INVALID_THREAD_HANDLE ) then 
  652.             Pickup_package_prompt_thread_handles[index] = thread_new( "ss01_pickup_prompt", player_responsible ) 
  653.             mission_debug( "thread with handle "..Pickup_package_prompt_thread_handles[index].." and index "..index.." spawned.", 10 ) 
  654.             break 
  655.          end 
  656.       end 
  657.  
  658.       -- Remove all markers - the loa dust package should take priority right now 
  659.       for index, location_nav_name in pairs( DEALER_GROUP_LOCATION_NAVPOINT_NAMES ) do 
  660.          marker_remove_navpoint( location_nav_name, SYNC_ALL ) 
  661.       end 
  662.  
  663.       -- Just in case the dealer with the package was killed while the player was outside the trigger, 
  664.       -- remove the GPS guidance if it's active. 
  665.       if ( Update_waypoint_thread_handle ~= INVALID_THREAD_HANDLE ) then 
  666.          thread_kill( Update_waypoint_thread_handle ) 
  667. 	      Update_waypoint_thread_handle = INVALID_THREAD_HANDLE 
  668.       end 
  669.       waypoint_remove( SYNC_ALL ) 
  670.  
  671.       --[[ Strictly follows mission guidelines, but probably a BAD IDEA 
  672.       -- Remove any group markers for groups the other player is killing 
  673.       local players = { LOCAL_PLAYER, REMOTE_PLAYER } 
  674.       for index, player_name in pairs( players ) do 
  675.          if ( Group_committed_to_kill[player_name] ~= group_index and 
  676.               Group_committed_to_kill[player_name] ~= nil ) then 
  677.             local other_group_index = Group_committed_to_kill[player_name] 
  678.             local other_player_sync = sync_from_player[player_name] 
  679.             ss01_group_unmark( other_player_sync, Groups[other_group_index], Groups_coop[group_index] ) 
  680.          end 
  681.       end 
  682.       ]] 
  683.  
  684.       -- Mark the group as non-critical 
  685.       if ( group_index < 3 ) then 
  686.          ss01_dealer_group_non_critical( group_index ) 
  687. 			ss01_dealer_group_unleash( group_index ) 
  688.       else 
  689.          ss01_final_drug_dealer_group_non_critical() 
  690.       end 
  691.    end 
  692. end 
  693.  
  694. -- Delays for a set number of seconds and then lets the players 
  695. -- know to pick up the loa dust package. 
  696. -- 
  697. -- player_responsible: Set to LOCAL_PLAYER, REMOTE_PLAYER, or something else. 
  698. --                     If it's not LOCAL_PLAYER or REMOTE_PLAYER, then we don't 
  699. --                     know who's responsible so prompt everyone. 
  700. -- 
  701. function ss01_pickup_prompt( player_responsible ) 
  702.    delay( COMPLETE_IDIOT_TIME_SECONDS ) 
  703.  
  704.    local sync_type = SYNC_ALL 
  705.    if ( player_responsible == LOCAL_PLAYER ) then 
  706.       sync_type = SYNC_LOCAL 
  707.    elseif ( player_responsible == REMOTE_PLAYER ) then 
  708.       sync_type = SYNC_REMOTE 
  709.    end 
  710.  
  711.    mission_help_table_nag( HT_LOOSE_STASH, "", "", sync_type ) 
  712. end 
  713.  
  714. -- Callback when the loa dust is picked up. 
  715. -- 
  716. function ss01_loa_dust_picked_up( player_name ) 
  717.    Loa_dust_collected = Loa_dust_collected + 1 
  718.  
  719.    -- Find the first running prompt thread and kill it. 
  720.    for index, thread_handle in pairs( Pickup_package_prompt_thread_handles ) do 
  721.       if ( thread_handle ~= INVALID_THREAD_HANDLE ) then 
  722.          thread_kill( thread_handle ) 
  723.          mission_debug( "thread with handle "..Pickup_package_prompt_thread_handles[index].." and index "..index.." killed.", 10 ) 
  724.          Pickup_package_prompt_thread_handles[index] = INVALID_THREAD_HANDLE 
  725.          break 
  726.       end 
  727.    end 
  728.     
  729.    local closest_nav 
  730.    local group_index 
  731.    closest_nav, group_index = ss01_get_closest_nav_to_char( DEALER_GROUP_LOCATION_NAVPOINT_NAMES, player_name ) 
  732.  
  733.    if ( Loa_dust_collected <= LOA_DUST_TO_COLLECT_INITIAL ) then 
  734.       objective_text(0, HT_X_OF_Y_PACKAGES_COLLECTED, Loa_dust_collected, LOA_DUST_TO_COLLECT_INITIAL ) 
  735.  
  736.       -- Mark this group as cleared 
  737.       ss01_dealer_group_cleared( group_index ) 
  738.  
  739.       mission_debug( "Cleared group with index: "..group_index..".", 30 ) 
  740.    else 
  741.       objective_text(0, HT_X_OF_Y_PACKAGES_COLLECTED, Loa_dust_collected, TOTAL_LOA_DUST_TO_COLLECT ) 
  742.    end 
  743.  
  744.    mission_debug( Num_dealer_groups_remaining.." groups remaining, "..Loa_dust_collected.." packages picked up." ) 
  745.  
  746.    if ( Loa_dust_collected == TOTAL_LOA_DUST_TO_COLLECT ) then 
  747.       notoriety_force_no_spawn( ENEMY_GANG, false ) 
  748.  
  749.       notoriety_set_min( ENEMY_GANG, END_MISSION_NOTORIETY ) 
  750.       delay( AFTER_FINAL_PACKAGE_COLLECTED_DELAY_SECONDS ) 
  751.       audio_play_conversation( SONS_OF_SAMEDI_FINAL_DIALOG_STREAM, OUTGOING_CALL ) 
  752.       mission_help_table( HT_GET_SAMPLES_TO_SHAUNDI, "", "", SYNC_ALL ) 
  753.       marker_add_trigger( MISSION_END_POINT_TRIGGER, MINIMAP_ICON_LOCATION, INGAME_EFFECT_VEHICLE_LOCATION, SYNC_ALL ) 
  754.       waypoint_add( MISSION_END_POINT_TRIGGER, SYNC_ALL ) 
  755.       trigger_enable( MISSION_END_POINT_TRIGGER, true ) 
  756.       on_trigger( "ss01_mission_complete", MISSION_END_POINT_TRIGGER ) 
  757.    elseif ( Loa_dust_collected == INITIAL_DRUG_DEALER_GROUP_COUNT ) then 
  758.       mission_set_checkpoint( KILLED_INITIAL_DEALERS_CHECKPOINT ) 
  759.  
  760.       mission_debug( "About to create final drug group." ) 
  761.       ss01_create_final_drug_dealer_group( false ) 
  762.  
  763.       -- Inform the player of the final goal 
  764.       ss01_inform_player_of_final_goal() 
  765.  
  766.       -- Update the objective with the extra package of dust that's required 
  767.       objective_text(0, HT_X_OF_Y_PACKAGES_COLLECTED, Loa_dust_collected, TOTAL_LOA_DUST_TO_COLLECT ) 
  768.  
  769.       -- Spawn the final goal 
  770.       for index, member_name in pairs( Final_group_member_names ) do 
  771.          marker_add_npc( member_name, MINIMAP_ICON_KILL, INGAME_EFFECT_KILL, SYNC_ALL ) 
  772.       end 
  773.       waypoint_add( FINAL_DRUG_DEALER_GROUP_NAVPOINT_NAME, SYNC_ALL ) 
  774.    else 
  775.       -- Let all players that were committed to kill this group know to get the next package 
  776.       local other_player = LOCAL_PLAYER 
  777.       if ( player_name == LOCAL_PLAYER ) then 
  778.          other_player = REMOTE_PLAYER 
  779.       end 
  780.  
  781.       -- Find out whether to tell one or both players about the next index 
  782.       local sync_type = sync_from_player( player_name ) 
  783.       if ( Group_committed_to_kill[other_player] == group_index ) then 
  784.          sync_type = SYNC_ALL 
  785.       end 
  786.  
  787.       -- Find out the index of the other group 
  788.       local other_group_index = STUDENT_UNION_DEALERS_GROUP_INDEX 
  789.       if ( group_index == STUDENT_UNION_DEALERS_GROUP_INDEX ) then 
  790.          other_group_index = PARKING_LOT_DEALERS_GROUP_INDEX 
  791.       end 
  792.  
  793.       --[[ Strictly follows mission guidelines, but probably a bad idea. 
  794.       -- If the other player is busy fighting the other group, then add markers that group for that 
  795.       -- player ( All markers were removed when the dust was dropped. ) 
  796.       if ( Group_committed_to_kill[other_player] == other_group_index and 
  797.            Group_dropped_sample[other_group_index] == false ) then 
  798.          local other_player_sync = sync_from_player[other_player] 
  799.          ss01_group_mark( other_player_sync, Groups[other_group_index], Groups_coop[group_index] ) 
  800.       end 
  801.       ]] 
  802.  
  803.       -- Let the appropriate players know 
  804.       if ( Groups_cleared[STUDENT_UNION_DEALERS_GROUP_INDEX] == false ) then 
  805.          mission_help_table( HT_GRAB_UNION_PACKAGE, "", "", sync_type ) 
  806.       else 
  807.          mission_help_table( HT_GRAB_PARKING_LOT_PACKAGE, "", "", sync_type ) 
  808.       end 
  809.    end 
  810.  
  811. end 
  812.  
  813. -- Called when the last dealer group becomes non-critical. This happens when the group's 
  814. -- package is dropped. 
  815. -- 
  816. function ss01_final_drug_dealer_group_non_critical() 
  817.    mission_debug( "marking final group as non-critical", 10 ) 
  818.    for index, member_name in pairs( Final_group_member_names ) do 
  819.       if ( character_is_dead(member_name ) == false ) then 
  820.          marker_remove_npc( member_name ) 
  821.          on_death( "", member_name ) 
  822.       end 
  823.    end 
  824.    distance_display_off(SYNC_ALL) 
  825.    hud_timer_stop(0) 
  826. end 
  827.  
  828. function ss01_dealer_group_unleash( group_index ) 
  829. 	delay( BEFORE_UNLEASH_DELAY_SECONDS ) 
  830.  
  831. 	for index, name in pairs( Groups[group_index] ) do 
  832. 		npc_leash_remove( name ) 
  833. 	end 
  834. end 
  835.  
  836. -- Called when a dealer group becomes non-critical. This happens when the group's 
  837. -- package is dropped. 
  838. -- 
  839. function ss01_dealer_group_non_critical( group_index ) 
  840.    mission_debug( "Group "..group_index.." no longer critical." ) 
  841.    Num_dealer_groups_remaining = Num_dealer_groups_remaining - 1 
  842.    marker_remove_navpoint( DEALER_GROUP_LOCATION_NAVPOINT_NAMES[group_index], SYNC_ALL ) 
  843.    -- Disable this trigger, it shouldn't be used anymore. 
  844.    trigger_enable( DEALER_GROUP_TRIGGER_NAMES[group_index], false ) 
  845.  
  846.    -- Clear any failure timers that relate to this group, since it's dead 
  847.    if ( Group_committed_to_kill[LOCAL_PLAYER] == group_index ) then 
  848.       if ( Failure_thread_handles[LOCAL_PLAYER] ~= nil ) then 
  849.          mission_debug( "stopped failure timer for "..LOCAL_PLAYER ) 
  850.          thread_kill( Failure_thread_handles[LOCAL_PLAYER] ) 
  851.          Failure_thread_handles[LOCAL_PLAYER] = nil 
  852.       end 
  853.       Group_committed_to_kill[LOCAL_PLAYER] = nil 
  854.    end 
  855.  
  856.    if ( Group_committed_to_kill[REMOTE_PLAYER] == group_index ) then 
  857.       if ( Failure_thread_handles[REMOTE_PLAYER] ~= nil ) then 
  858.          mission_debug( "stopped failure timer for "..REMOTE_PLAYER ) 
  859.          thread_kill( Failure_thread_handles[REMOTE_PLAYER] ) 
  860.          Failure_thread_handles[REMOTE_PLAYER] = nil 
  861.       end 
  862.       Group_committed_to_kill[REMOTE_PLAYER] = nil 
  863.    end 
  864.  
  865.    for index, member_name in pairs( Groups[group_index] ) do 
  866.       if ( character_is_dead(member_name ) == false ) then 
  867.          marker_remove_npc( member_name ) 
  868.          on_death( "", member_name ) 
  869.       end 
  870.    end 
  871.  
  872.    if ( coop_is_active() ) then 
  873.       for index, member_name in pairs( Groups_coop[group_index] ) do 
  874.          if ( character_is_dead(member_name ) == false ) then 
  875.             marker_remove_npc( member_name ) 
  876.             on_death( "", member_name ) 
  877.          end 
  878.       end 
  879.    end 
  880. end 
  881.  
  882. -- Called when a entire group has been cleared by collecting 
  883. -- its Loa dust package. Updates the number of groups left. 
  884. -- 
  885. -- group_index: Index of the group that was cleared. 
  886. -- 
  887. function ss01_dealer_group_cleared( group_index ) 
  888.    Groups_cleared[group_index] = true 
  889.  
  890.    if ( Num_dealer_groups_remaining > 0 ) then 
  891.  
  892.       -- Now that we've cleared a group, kill the update waypoint thread and restart it. 
  893.       -- The new information on what groups are cleared will cause it to update the paths. 
  894.       if ( Update_waypoint_thread_handle ~= INVALID_THREAD_HANDLE ) then 
  895.          thread_kill( Update_waypoint_thread_handle ) 
  896.       end 
  897.       Update_waypoint_thread_handle = thread_new( "ss01_update_waypoint" ) 
  898.  
  899.       -- Go through all the remaining groups and add location markers for them 
  900.       for group_index, cleared in pairs( Groups_cleared ) do 
  901.          if ( cleared == false and group_index <= INITIAL_DRUG_DEALER_GROUP_COUNT ) then 
  902.  
  903.             local players = { REMOTE_PLAYER, LOCAL_PLAYER } 
  904.  
  905.             -- Add markers for this group for players who are not already committed to 
  906.             -- kill this group 
  907.             for player_index, player_name in pairs( players ) do 
  908.                if ( Group_committed_to_kill[player_name] ~= group_index ) then 
  909.                   local sync_type = sync_from_player( player_name ) 
  910.                   marker_add_navpoint( DEALER_GROUP_LOCATION_NAVPOINT_NAMES[group_index], 
  911.                                        MINIMAP_ICON_LOCATION, "", sync_type ) 
  912.                end 
  913.             end 
  914.  
  915.          end 
  916.       end 
  917.    end 
  918. end 
  919.  
  920. -- Function to create the final drug dealer group. 
  921. -- 
  922. function ss01_create_final_drug_dealer_group( from_checkpoint ) 
  923.    group_show( FINAL_DRUG_DEALER_GROUP_NAME ) 
  924.    trigger_enable( FINAL_DEALER_TRIGGER_NAME, true ) 
  925.    on_trigger( "ss01_final_group_trigger", FINAL_DEALER_TRIGGER_NAME ) 
  926.  
  927.    Final_group_member_names = ss01_create_group_member_names( FINAL_GROUP_GROUP_NUMBER, 
  928.                                                               FINAL_GROUP_MEMBER_COUNT, 0 ) 
  929.  
  930.    on_vehicle_destroyed( "ss01_dealer_vehicle_destroyed", FINAL_DEALER_GROUP_VEHICLE_NAME ) 
  931.    on_take_damage( "ss01_final_groups_vehicle_attacked", FINAL_DEALER_GROUP_VEHICLE_NAME ) 
  932.    vehicle_max_speed( FINAL_DEALER_GROUP_VEHICLE_NAME, DEALER_CAR_MAX_SPEED_MPS ) 
  933.  
  934.    local new_car_hp = MR_GABBY_CAR_HIT_POINTS_PERCENT * get_current_hit_points( FINAL_DEALER_GROUP_VEHICLE_NAME ) 
  935.    set_current_hit_points( FINAL_DEALER_GROUP_VEHICLE_NAME, new_car_hp ) 
  936.    set_max_hit_points( FINAL_DEALER_GROUP_VEHICLE_NAME, new_car_hp ) 
  937.  
  938.    for index, member_name in pairs( Final_group_member_names ) do 
  939.       on_death( "ss01_final_group_group_member_died", member_name ) 
  940.       on_take_damage( "ss01_final_group_trigger", member_name ) 
  941.    end 
  942.  
  943.    -- Driver should have the loa dust 
  944.    loot_item_add( LOA_DUST_NAME, Final_group_member_names[1] ) 
  945.  
  946.    vehicle_enter_group_teleport( Final_group_member_names, FINAL_DEALER_GROUP_VEHICLE_NAME ) 
  947.    if ( from_checkpoint ) then 
  948.       for index, member_name in pairs( Final_group_member_names ) do 
  949.          marker_add_npc( member_name, MINIMAP_ICON_KILL, INGAME_EFFECT_KILL, SYNC_ALL ) 
  950.       end 
  951.       waypoint_add( FINAL_DEALER_GROUP_VEHICLE_NAME, SYNC_ALL ) 
  952.       mission_help_table( HT_FIND_MR_GABBY ) 
  953.    end 
  954. end 
  955.  
  956. function ss01_dealer_vehicle_destroyed() 
  957.    hud_timer_stop(0) 
  958.    distance_display_off(SYNC_ALL) 
  959. end 
  960.  
  961. -- Returns the first living member of the group that's found. 
  962. -- 
  963. -- group_members: The names of the group members. 
  964. -- group_members_coop: (Optional) The names of the coop additions to the group. 
  965. -- 
  966. function ss01_get_living_group_member( group_members, group_members_coop ) 
  967.    for index, member_name in pairs( group_members ) do 
  968.       if ( character_is_dead(member_name ) == false ) then 
  969.          return member_name 
  970.       end 
  971.    end 
  972.  
  973.    if ( coop_is_active() and group_members_coop ~= nil ) then 
  974.       for index, member_name in pairs( group_members_coop ) do 
  975.          if ( character_is_dead(member_name ) == false ) then 
  976.             return member_name 
  977.          end 
  978.       end 
  979.    end 
  980.    return nil 
  981. end 
  982.  
  983. -- Callback when the final group's vehicle is attacked. Causes the group 
  984. -- to flee if the attacker is one of the players. 
  985. -- 
  986. function ss01_final_groups_vehicle_attacked( attacker_name ) 
  987.    if ( attacker_name == LOCAL_PLAYER or attacker_name == REMOTE_PLAYER ) then 
  988.       ss01_final_group_trigger( triggerer_name ) 
  989.    end 
  990. end 
  991.  
  992. -- Callback for the final group's trigger. Causes the group to 
  993. -- flee. 
  994. -- 
  995. function ss01_final_group_trigger( triggerer_name ) 
  996. 	if ( Group_flee_triggered == false ) then 
  997. 		Group_flee_triggered = true 
  998. 		-- Remove the callbacks - this function should only be called once 
  999. 		on_take_damage( "", FINAL_DEALER_GROUP_VEHICLE_NAME ) 
  1000. 		for index, member_name in pairs( Final_group_member_names ) do 
  1001. 			on_take_damage( "", member_name ) 
  1002. 		end 
  1003. 		trigger_enable( FINAL_DEALER_TRIGGER_NAME, false ) 
  1004.  
  1005. 		mission_debug( "final group triggered", 10 ) 
  1006. 		-- Now, if the sample hasn't been dropped, this group is still critical. 
  1007. 		-- Otherwise, it's no longer critical, so don't mark it. 
  1008. 		if ( Group_dropped_sample[3] == false ) then 
  1009. 			local sync_type = sync_from_player( triggerer_name ) 
  1010. 			mission_help_table( HT_TAKE_OUT_MR_GABBY, "", "", sync_type ) 
  1011. 			if ( Dealer_vehicle_escape_thread == INVALID_THREAD_HANDLE ) then 
  1012. 				Dealer_vehicle_escape_thread = thread_new( "ss01_vehicle_escape" ) 
  1013. 			end 
  1014. 		else 
  1015. 			for index, member_name in pairs( Final_group_member_names ) do 
  1016. 				marker_remove_npc( member_name ) 
  1017. 			end 
  1018. 			for index, member_name in pairs( Final_group_member_names ) do 
  1019. 				vehicle_exit( member_name ) 
  1020. 				local distance, player = get_dist_closest_player_to_object( member_name ) 
  1021. 				attack_safe( member_name, player, false ) 
  1022. 			end 
  1023. 		end 
  1024. 	end 
  1025. end 
  1026.  
  1027. -- Callback when a member of the final group dies. 
  1028. -- 
  1029. -- member_name: The name of the group member that died. 
  1030. -- 
  1031. function ss01_final_group_group_member_died( member_name ) 
  1032.    Final_group_members_remaining = Final_group_members_remaining - 1 
  1033.    marker_remove_npc( member_name, SYNC_ALL ) 
  1034. end 
  1035. -- End the mission 
  1036. -- 
  1037. function ss01_mission_complete() 
  1038. 	 
  1039. 	if ( character_is_in_vehicle( LOCAL_PLAYER ) ) then 
  1040.  
  1041.        player_controls_disable( LOCAL_PLAYER ) 
  1042. 		 turn_invulnerable(LOCAL_PLAYER, false)  
  1043.  
  1044.        vehicle_stop_do( LOCAL_PLAYER ) 
  1045.  
  1046.     end 
  1047.  
  1048.     if ( coop_is_active() ) then 
  1049.  
  1050.        if ( character_is_in_vehicle( REMOTE_PLAYER ) ) then 
  1051.  
  1052.           player_controls_disable( REMOTE_PLAYER ) 
  1053. 			turn_invulnerable(REMOTE_PLAYER, false) 
  1054.           vehicle_stop_do( REMOTE_PLAYER ) 
  1055.  
  1056.        end 
  1057.  
  1058.     end 
  1059.  
  1060.    mission_end_success( MISSION_NAME, CT_OUTRO) 
  1061. end 
  1062.  
  1063. -- Causes a group to attack the passed-in player. 
  1064. -- 
  1065. -- player_name: The player to attack 
  1066. -- group_member_names: The names of the group members. 
  1067. -- group_member_names_coop: (Optional) The names of the coop additions to the group. 
  1068. -- 
  1069. function ss01_group_attack( player_name, group_member_names, group_member_names_coop ) 
  1070.    for index, member_name in pairs( group_member_names ) do 
  1071.       attack_safe( member_name, player_name ) 
  1072.    end 
  1073.  
  1074.    if ( coop_is_active() ) then 
  1075.       for index, member_name in pairs( group_member_names_coop ) do 
  1076.          attack_safe( member_name, player_name ) 
  1077.       end 
  1078.    end 
  1079. end 
  1080.  
  1081. function ss01_member_escape_human_shield( player_name, member_name ) 
  1082.    character_release_human_shield( player_name, false ) 
  1083.    character_set_cannot_be_grabbed( member_name, true ) 
  1084.  
  1085.    delay( 1 ) 
  1086.  
  1087.    local member_start = member_name 
  1088.    set_ignore_ai_flag( member_name, true ) 
  1089.    move_to_safe( member_name, member_start, 3, true, true ) 
  1090.    set_ignore_ai_flag( member_name, false ) 
  1091.    character_set_cannot_be_grabbed( member_name, false ) 
  1092.    attack_closest_player( member_name ) 
  1093. end 
  1094.  
  1095. -- Failure countdown is started when the player leaves a group trigger if he's committed to 
  1096. -- kill that group. 
  1097. -- 
  1098. function ss01_left_group_trigger( triggerer_name, trigger_name ) 
  1099.    local group_index = ss01_find_group_index_from_trigger_name( trigger_name ) 
  1100.  
  1101.    -- Check to see if this player has a scripted character as a human shield 
  1102.    local human_shield_name = character_get_human_shield_name( triggerer_name ) 
  1103.    if ( human_shield_name ~= nil ) then 
  1104.       -- If so, check to see if it's a member of this group 
  1105.       local human_shields_group_index = ss01_find_group_index_from_name( human_shield_name ) 
  1106.       if ( human_shields_group_index == group_index ) then 
  1107.          -- If so, then have them get loose and run away 
  1108.          thread_new( "ss01_member_escape_human_shield", triggerer_name, human_shield_name ) 
  1109.       end 
  1110.    end 
  1111.  
  1112.    -- Find out if the player that's wandered into this trigger is already committed to 
  1113.    -- kill a group or not 
  1114.    if ( Group_committed_to_kill[triggerer_name] == group_index ) then 
  1115.       -- Only spawn a failure thread if there isn't one already running. 
  1116.       if ( Failure_thread_handles[triggerer_name] == nil ) then 
  1117.          mission_debug( "started failure timer for "..triggerer_name ) 
  1118.          Failure_thread_handles[triggerer_name] = thread_new( "ss01_failure_timer" ) 
  1119.       end 
  1120.    end 
  1121. end 
  1122.  
  1123. -- This function is an internal timer that counts down to mission failure. 
  1124. -- 
  1125. function ss01_failure_timer() 
  1126.    delay( OUT_OF_GROUP_AREA_FAIL_TIME_SECONDS ) 
  1127.  
  1128.    -- The timer's elapsed, call the 'discovered' function. 
  1129.    mission_end_failure( MISSION_NAME, HT_DRUG_DEALERS_ESCAPED ) 
  1130. end 
  1131.  
  1132. -- Callback for district changing. If the district is the target district, 
  1133. -- this function advances the mission to the next stage for the player 
  1134. -- that reaches it. 
  1135. -- 
  1136. function ss01_district_changed( player_name, new_district, prev_district ) 
  1137.    -- If we've made it to the district 
  1138.    if ( new_district == GOAL_DISTRICT_NAME ) then 
  1139.       -- Remove the marker and waypoint path 
  1140.       district_set_pulsing( GOAL_DISTRICT_NAME, false, SYNC_ALL ) 
  1141.       waypoint_remove( SYNC_ALL )  
  1142.       marker_remove_navpoint( UNIVERSITY_LOCATION_NAVPOINT_NAME, SYNC_ALL ) 
  1143.  
  1144.       -- Remove this callback 
  1145.       on_district_changed( "", LOCAL_PLAYER ) 
  1146.       if ( coop_is_active() ) then 
  1147.          on_district_changed( "", REMOTE_PLAYER ) 
  1148.       end 
  1149.  
  1150.       -- Set the player as having reached the goal and update their 
  1151.       -- waypoint GPS path 
  1152.       Goal_district_reached = true 
  1153.  
  1154. 		thread_yield() 
  1155.       if ( Reached_district_checkpoint_set == false ) then 
  1156.          Reached_district_checkpoint_set = true 
  1157. 			ss01_prompt_and_guide_for_first_two_groups( SYNC_ALL ) 
  1158.          mission_set_checkpoint( REACHED_GOAL_DISTRICT_CHECKPOINT ) 
  1159.       end 
  1160.    end 
  1161. end 
  1162.  
  1163. function ss01_prompt_and_guide_for_first_two_groups( sync_type ) 
  1164.    -- Add a help message and navpoints for the drug dealers 
  1165.    mission_help_table( HT_KILL_DRUG_DEALERS, "", "", sync_type ) 
  1166.    delay( .96 ) 
  1167.    --objective_text( HT_X_OF_Y_PACKAGES_COLLECTED, 0, LOA_DUST_TO_COLLECT_INITIAL ) 
  1168.    for index, navpoint_name in pairs( DEALER_GROUP_LOCATION_NAVPOINT_NAMES ) do 
  1169.       -- Only add navpoints for non-cleared groups 
  1170.       if ( Groups_cleared[index] == false ) then 
  1171.          marker_add_navpoint( navpoint_name, MINIMAP_ICON_LOCATION, "", sync_type ) 
  1172.       end 
  1173.    end 
  1174.  
  1175.    -- Add waypoint to the nearest group    
  1176.    if ( Update_waypoint_thread_handle == INVALID_THREAD_HANDLE ) then 
  1177.       Update_waypoint_thread_handle = thread_new( "ss01_update_waypoint" ) 
  1178.    end 
  1179. end 
  1180.  
  1181. --  
  1182. function ss01_get_closest_nav_to_char( navpoint_names, character_name ) 
  1183.    local closest_nav_name = navpoint_names[1] 
  1184.    local closest_dist = get_dist_char_to_nav( character_name, navpoint_names[1] ) 
  1185.    local closest_index = 1 
  1186.  
  1187.    for nav_index, nav_name in pairs( navpoint_names ) do 
  1188.        local cur_dist = get_dist_char_to_nav( character_name, nav_name ) 
  1189.  
  1190.        if ( cur_dist < closest_dist ) then 
  1191.          closest_nav_name = nav_name 
  1192.          closest_dist = cur_dist 
  1193. 	      closest_index = nav_index 
  1194.        end 
  1195.    end 
  1196.  
  1197.    return closest_nav_name, closest_index, closest_dist 
  1198. end 
  1199.  
  1200. function ss01_good_distance() 
  1201.    hud_timer_stop(0) 
  1202. end 
  1203.  
  1204. function ss01_dealer_escaping() 
  1205.    mission_help_table_nag( HT_CATCH_UP ) 
  1206.    -- Add a timer - if he doesn't catch up soon enough, he fails 
  1207.    hud_timer_set(0, CAR_CHASE_OUT_OF_RANGE_FAIL_TIME_MS, "ss01_dealer_vehicle_escaped" ) 
  1208. end 
  1209.  
  1210. function ss01_dealer_vehicle_escaped() 
  1211.    mission_end_failure( MISSION_NAME, HT_MR_GABBY_ESCAPED ) 
  1212. end 
  1213.  
  1214. function ss01_vehicle_escape() 
  1215.  
  1216.    waypoint_remove( SYNC_ALL ) 
  1217.  
  1218.    -- Only have the vehicles escape if the group still exists 
  1219.    if ( Final_group_members_remaining > 0 ) then 
  1220.       -- Add callbacks for the distance 
  1221.       distance_display_on( Final_group_member_names[1], 0, 
  1222.                            MAX_ALLOWED_CAR_CHASE_DISTANCE_METERS, 0, MAX_ALLOWED_CAR_CHASE_DISTANCE_METERS, SYNC_ALL )       
  1223.  
  1224.       -- Update the distance callbacks 
  1225.       on_tailing_good( "ss01_good_distance" ) 
  1226.       on_tailing_too_far( "ss01_dealer_escaping" ) 
  1227.  
  1228.       local use_navmesh = true 
  1229.       local stop_at_goal = false 
  1230.       local num_paths = sizeof_table( ESCAPE_PATHS ) 
  1231.  
  1232.       -- Go through each part of the path 
  1233.       for index, path_name in pairs( ESCAPE_PATHS ) do 
  1234.          -- Stop at the last goal point 
  1235.          if ( num_paths == index ) then 
  1236.             stop_at_goal = true 
  1237.          end 
  1238. 			if ( ( vehicle_exists( FINAL_DEALER_GROUP_VEHICLE_NAME ) and vehicle_is_destroyed( FINAL_DEALER_GROUP_VEHICLE_NAME ) == false ) and 
  1239. 				  ( character_exists( Final_group_member_names[1] ) and character_is_dead( Final_group_member_names[1] ) == false ) ) then 
  1240. 	         vehicle_pathfind_to( FINAL_DEALER_GROUP_VEHICLE_NAME, path_name, use_navmesh, stop_at_goal ) 
  1241. 			end 
  1242.       end 
  1243.  
  1244.       for index, member in pairs( Final_group_member_names ) do 
  1245.          vehicle_exit( member ) 
  1246.          set_attack_player_flag( member, true )  
  1247.       end 
  1248.    end 
  1249. end 
  1250.  
  1251. -- Creates group member names for the groups based on the group index and the 
  1252. -- number of group members and coop group members. 
  1253. -- 
  1254. -- group_index: The index of the group to create. 
  1255. -- member_count: The number of members in this group. 
  1256. -- coop_member_count: The number of additional members for coop mode. 
  1257. -- 
  1258. function ss01_create_group_member_names( group_index, member_count, coop_member_count ) 
  1259.    local member_names = {} 
  1260.    local member_names_coop = {} 
  1261.  
  1262.    local increment = 1 
  1263.  
  1264.    for member_index = 1, member_count, increment do 
  1265.       member_names[member_index] = GROUP_MEMBER_GROUP_PREFIX..group_index..GROUP_MEMBER_MEMBER_PREFIX..member_index 
  1266.    end 
  1267.  
  1268.    if ( coop_is_active() ) then    
  1269.       for member_index = 1, coop_member_count, increment do 
  1270.          member_names_coop[member_index] = GROUP_MEMBER_GROUP_PREFIX..group_index..GROUP_MEMBER_COOP_MEMBER_PREFIX..member_index 
  1271.       end 
  1272.    end 
  1273.  
  1274.    return member_names, member_names_coop 
  1275. end 
  1276.  
  1277. -- This function updates the waypoint paths if the player has moved such that one of the locations 
  1278. -- is closer than another one. 
  1279. -- 
  1280. function ss01_update_waypoint() 
  1281.    local group_locations = {} 
  1282.    local group_location_count = 0 
  1283.  
  1284.    -- Find the surviving groups' locations and store them correctly in the 'group_locations' 
  1285.    -- table. 
  1286.    for index, cleared in Groups_cleared do 
  1287.       if ( cleared == false ) then 
  1288.          if ( index == 1 ) then 
  1289. 	         group_location_count = group_location_count + 1 
  1290. 	         group_locations[group_location_count] = DEALER_GROUP_LOCATION_NAVPOINT_NAMES[1] 
  1291. 	      elseif ( index == 2 ) then 
  1292.             group_location_count = group_location_count + 1 
  1293.             group_locations[group_location_count] = DEALER_GROUP_LOCATION_NAVPOINT_NAMES[2] 
  1294. 	      end 
  1295.        end 
  1296.    end 
  1297.    Cur_dealer_group_path_location[LOCAL_PLAYER] = "" 
  1298.    Cur_dealer_group_path_location[REMOTE_PLAYER] = "" 
  1299.  
  1300.    while ( Loa_dust_collected < 2 ) do 
  1301.       -- Find out if we should update the local player's path 
  1302.       local closest_nav_local, c_index, c_dist = ss01_get_closest_nav_to_char( group_locations, LOCAL_PLAYER ) 
  1303. 		-- Only replot the path if the closest navpoint is different than the last time we checked 
  1304.       if ( Cur_dealer_group_path_location[LOCAL_PLAYER] ~= closest_nav_local ) then 
  1305.          waypoint_remove( SYNC_LOCAL ) 
  1306.          waypoint_add( closest_nav_local, SYNC_LOCAL ) 
  1307.          Cur_dealer_group_path_location[LOCAL_PLAYER] = closest_nav_local 
  1308.       end 
  1309.  
  1310.       -- Find out if we should update the remote player's path 
  1311.       if ( coop_is_active() ) then 
  1312.          local closest_nav_remote, c_index, c_dist = ss01_get_closest_nav_to_char( group_locations, REMOTE_PLAYER ) 
  1313.  
  1314. 			-- Only replot the path if the closest navpoint is different than the last time we checked 
  1315.          if ( Cur_dealer_group_path_location[REMOTE_PLAYER] ~= closest_nav_remote ) then 
  1316.             waypoint_remove( SYNC_REMOTE ) 
  1317.             waypoint_add( closest_nav_remote, SYNC_REMOTE ) 
  1318.             Cur_dealer_group_path_location[REMOTE_PLAYER] = closest_nav_remote 
  1319.          end 
  1320.       end 
  1321.  
  1322.       delay( 1 ) 
  1323.    end 
  1324. end 
  1325.  
  1326. function ss01_cleanup() 
  1327.    -- Cleanup mission here 
  1328.    on_district_changed( "", LOCAL_PLAYER ) 
  1329.    on_district_changed( "", REMOTE_PLAYER ) 
  1330. 	turn_vulnerable(LOCAL_PLAYER)  
  1331. 	if coop_is_active() then 
  1332. 		turn_vulnerable(REMOTE_PLAYER)  
  1333. 	end 
  1334.  
  1335.    mid_mission_phonecall_reset() 
  1336.  
  1337.    notoriety_set_min( ENEMY_GANG, 0 ) 
  1338.    distance_display_off(SYNC_ALL) 
  1339.    on_tailing_good( "" ) 
  1340.    on_tailing_too_far( "" ) 
  1341. 	hud_timer_stop( 0 ) 
  1342.  
  1343.    on_mission_item_pickup( "" ) 
  1344.    on_mission_item_drop( "" ) 
  1345.    on_trigger_exit( "", SAINTS_PARKING_LOT_TRIGGER_NAME ) 
  1346.    for index, trigger in pairs( DEALER_GROUP_TRIGGER_NAMES ) do 
  1347.       on_trigger( "", trigger ) 
  1348.       on_trigger_exit( "", trigger ) 
  1349.    end 
  1350.    waypoint_remove( SYNC_ALL ) 
  1351.    spawning_allow_gang_team_ambient_spawns( HUMAN_TEAM_SAMEDI ) 
  1352.    district_set_pulsing( GOAL_DISTRICT_NAME, false, SYNC_ALL ) 
  1353.  
  1354. 	-- Remove all markers 
  1355. 	marker_remove_navpoint( UNIVERSITY_LOCATION_NAVPOINT_NAME, SYNC_ALL ) 
  1356.    for index, navpoint_name in pairs( DEALER_GROUP_LOCATION_NAVPOINT_NAMES ) do 
  1357. 		marker_remove_navpoint( navpoint_name, SYNC_ALL ) 
  1358. 	end 
  1359. 	marker_remove_trigger( MISSION_END_POINT_TRIGGER, SYNC_ALL ) 
  1360. 	ss01_maybe_remove_group_markers( Final_group_member_names ) 
  1361. 	ss01_maybe_remove_group_markers( Group1_member_names ) 
  1362.    ss01_maybe_remove_group_markers( Group2_member_names ) 
  1363.    ss01_maybe_remove_group_markers( Group1_member_names_coop ) 
  1364.    ss01_maybe_remove_group_markers( Group2_member_names_coop ) 
  1365. end 
  1366.  
  1367. function ss01_maybe_remove_group_markers( group_name ) 
  1368. 	if ( group_name[0] ~= nil ) then 
  1369. 		for index, member_name in pairs( group_name ) do 
  1370.          marker_remove_npc( member_name, SYNC_ALL ) 
  1371.       end 
  1372. 	end 
  1373. end 
  1374.  
  1375. function ss01_success() 
  1376.    -- Called when the mission has ended with success 
  1377.    release_to_world( STARTING_CAR_GROUP_NAME ) 
  1378. end 
  1379.