sr2lua/ss03.lua

  1. -- ss03.lua 
  2. -- SR2 mission script 
  3. -- 3/28/07 
  4. -- Mission help table text tags 
  5.    HT_DESTROY_FARM_EQUIPMENT = "ss03_destroy_equipment" 
  6.    HT_ELIMINATE_LIEUTENANTS = "ss03_eliminate_lieutenants" 
  7.    HT_HELICOPTER_DESTROYED = "ss03_players_helicopter_destroyed" 
  8.    HT_X_OF_Y_LIEUTENANTS = "ss03_x_of_y_lieutenants" 
  9.    HT_X_OF_Y_TARGETS = "ss03_x_of_y_targets" 
  10.    HT_CHEM_TANK_DESTROYED = "ss03_chem_tank_destroyed" 
  11.    HT_CHEM_DEPOT_DESTROYED = "ss03_chem_depot_destroyed" 
  12.    HT_FUEL_TRUCK_DESTROYED = "ss03_fuel_truck_destroyed" 
  13.    HT_FERTILIZER_TRUCK_DESTROYED = "ss03_fertilizer_truck_destroyed" 
  14.  
  15. -- Mission states 
  16.    MS_INIT = 1 
  17.    MS_REACHED_FARM = 2 
  18.    MS_FARM_DESTROYED = 4 
  19.    MS_BEGIN_CHASE = 5 
  20.  
  21. -- Cutscene names 
  22.  
  23. -- Groups, NPCs, vehicles, navpoints, and other names 
  24.    -- Mission constant names 
  25.    MISSION_NAME = "ss03" 
  26.    ENEMY_GANG = "Samedi" 
  27.    -- ( Mission Prefix ) 
  28.    MP = MISSION_NAME.."_$" 
  29.    -- Checkpoints 
  30.    KILL_LIEUTENANTS_CHECKPOINT = "Kill_Lieutenants" 
  31.  
  32.    -- Weapons 
  33.    SAW_NAME = "AR200" 
  34.  
  35.    -- Groups 
  36.    TOBIAS_GROUP = MP.."Tobias" 
  37.    HELICOPTER_GROUP = MP.."Helicopter" 
  38.  
  39.    GROUND_DEFENDERS_GROUP = MP.."Ground_Defenders" 
  40.  
  41.    TARGET_VEHICLES_GROUP = MP.."Target_Vehicles" 
  42.  
  43.    ESCAPEES_GROUP = MP.."Escapees" 
  44.  
  45.    DRIVE_UP_DEFENDERS_GROUP = MP.."Drive_Up_Defenders" 
  46.  
  47.    GAS_STATION_GROUP = MP.."Gas_Station_Stop" 
  48.  
  49.    -- NPC names 
  50.    TOBIAS_NAME = MP.."Tobias" 
  51.    ESCAPEES_V1 = { MP.."EV1M_01", MP.."EV1M_02", 
  52.                    MP.."EV1M_03", MP.."EV1M_04" } 
  53.    ESCAPEES_V2 = { MP.."EV2M_01", MP.."EV2M_02", 
  54.                    MP.."EV2M_03", MP.."EV2M_04" } 
  55.    ESCAPEES_V3 = { MP.."EV3M_01", MP.."EV3M_02", 
  56.                    MP.."EV3M_03", MP.."EV3M_04" } 
  57.    ESCAPEES_V4 = { MP.."EV4M_01", MP.."EV4M_02", 
  58.                    MP.."EV4M_03", MP.."EV4M_04" } 
  59.  
  60.    GROUND_DEFENDERS = { MP.."GD1", MP.."GD2", MP.."GD3", 
  61.                         MP.."GD4", MP.."GD5", MP.."GD6", 
  62.                         MP.."GD7", MP.."GD8", MP.."GD9", 
  63.                         MP.."GD10", MP.."GD11" } 
  64.  
  65.    ROCKET_LAUNCHER_GUYS = { MP.."GD_Rocket01", MP.."GD_Rocket02", MP.."GD_Rocket03" } 
  66.    AK_47_GUY = MP.."GD_AK" 
  67.  
  68.    ESCAPEES = { ESCAPEES_V1, ESCAPEES_V2, ESCAPEES_V3, ESCAPEES_V4 } 
  69.  
  70.    DUD_MEMBERS = { MP.."DUD_1", MP.."DUD_2", MP.."DUD_3" } 
  71.  
  72.    -- Vehicle names 
  73.    HELICOPTER_NAME = MP.."Helicopter" 
  74.  
  75.    SEWAGE_TRUCK_NAME = MP.."Fertilizer_Truck" 
  76.    FUEL_TRUCK_TANK_NAME = MP.."Fuel_Truck_Tank" 
  77.  
  78.    VEHICLE_TARGETS = { FUEL_TRUCK_TANK_NAME, SEWAGE_TRUCK_NAME } 
  79.    VEHICLE_AND_TRAILER = { MP.."Fuel_Truck_Cab", FUEL_TRUCK_TANK_NAME } 
  80.  
  81.    DUD_VEHICLE = MP.."DUD_V" 
  82.  
  83.    ESCAPEE_VEHICLES = { MP.."EscapeeV1", MP.."EscapeeV2", MP.."EscapeeV3", MP.."EscapeeV4" } 
  84.  
  85.    -- Navpoints and paths 
  86.    MISSION_START_LOCATION = "mission_start_sr2_city_$ss03" 
  87.    REMOTE_PLAYER_START = MP.."Remote_Player_Start" 
  88.  
  89.    NEAR_HELICOPTER = MP.."Near_Helicopter" 
  90.    NEAR_HELICOPTER_REMOTE_PLAYER = MP.."Near_Helicopter_Remote_Player" 
  91.  
  92.    HELI_TO_FARM_PATH = MP.."To_Farm" 
  93.    HELI_CIRCULAR_RAIL_PATHS = { { MP.."Circular_Path" }, { MP.."Circular_Path2_1", MP.."Circular_Path2_2", 
  94.                                                            MP.."Circular_Path2_3", MP.."Circular_Path2_4" } } 
  95.  
  96.    ESCAPEE_START_PATH = MP.."Escapee_Start_Path" 
  97.    ESCAPEE_PATHS = { MP.."EP1", MP.."EP2", MP.."EP3" } 
  98.  
  99.    ESCAPEE_LOOPING_PATHS = { MP.."ELP1", MP.."ELP2" } 
  100.  
  101.    ESCAPEE_TO_GAS_STATION_PATHS_PATH = { MP.."EPL1_01", MP.."EPL1_02", MP.."EPL1_03" } 
  102.    ESCAPEE_GAS_STATION_PATHS = { MP.."EV1_Gas", MP.."EV2_Gas", MP.."EV3_Gas", MP.."EV4_Gas" } 
  103.  
  104.    ADDITIONAL_CARS_UP_TO_PATH = { MP.."Extra_Cars_to_Main_Path" } 
  105.    ADDITIONAL_CARS_PART_ONE = { MP.."EP1_13", MP.."EP1_14", MP.."EP1_15" } 
  106.  
  107.    TO_HOLDING_POSITION = MP.."To_Holding_Position" 
  108.    HELI_HOLDING_POSITION = MP.."Heli_Holding_Position" 
  109.  
  110.    HELI_CHECKPOINT_WARP = MP.."Heli_Checkpoint_Warp" 
  111.    LOCAL_PLAYER_CHECKPOINT_WARP = MP.."Local_Player_Checkpoint_Warp" 
  112.    REMOTE_PLAYER_CHECKPOINT_WARP = MP.."Remote_Player_Checkpoint_Warp" 
  113.    TOBIAS_CHECKPOINT_WARP = MP.."Tobias_Checkpoint_Warp" 
  114.  
  115.    HELICOPTER_FOLLOW_PATHS = { MP.."HFP01", MP.."HFP02", MP.."HFP03" } 
  116.    HELICOPTER_FOLLOW_LOOP_PATHS = { MP.."HLP01", MP.."HLP02" }--, MP.."HLP03" } 
  117.  
  118.    DUD_TO_FARM_PATH = MP.."DUD_To_Farm" 
  119.    DUD_ENTER_FARM_PATH = MP.."DUD_Enter_Farm" 
  120.  
  121.    CHEM_DEPOT_FIRE_LOCATIONS = { MP.."Depot01_Location", MP.."Depot02_Location", MP.."Depot03_Location" } 
  122.    CROP_FIRE_LOCATIONS = { { MP.."Depot01_Crops_Location_01", MP.."Depot01_Crops_Location_02" }, 
  123.                            { MP.."Depot02_Crops_Location_01", MP.."Depot02_Crops_Location_02" }, 
  124.                            { MP.."Depot03_Crops_Location_01", MP.."Depot03_Crops_Location_02", 
  125.                              MP.."Depot03_Crops_Location_03", MP.."Depot03_Crops_Location_04", 
  126.                              MP.."Depot03_Crops_Location_05", MP.."Depot03_Crops_Location_06" } } 
  127.  
  128.    CROP_FIRE_SPREAD_SEQUENCES = { 
  129.                                     { 
  130.                                        { CROP_FIRE_LOCATIONS[1][1] }, 
  131.                                        { CROP_FIRE_LOCATIONS[1][2] } 
  132.                                     }, 
  133.  
  134.                                     { 
  135.                                        { CROP_FIRE_LOCATIONS[2][1] }, 
  136.                                        { CROP_FIRE_LOCATIONS[2][2] }, 
  137.                                     }, 
  138.  
  139.                                     { 
  140.                                         { CROP_FIRE_LOCATIONS[3][1] }, 
  141.                                         { CROP_FIRE_LOCATIONS[3][2], CROP_FIRE_LOCATIONS[3][3], CROP_FIRE_LOCATIONS[3][5] }, 
  142.                                         { CROP_FIRE_LOCATIONS[3][4], CROP_FIRE_LOCATIONS[3][6] } 
  143.                                     }, 
  144.                                 } 
  145.  
  146.    BARN_ROOF_EXPLOSION_LOCATION = MP.."Barn_Roof_Location" 
  147.  
  148.    GAS_STATION_VEHICLE_LOCATION = MP.."v000" 
  149.  
  150.    -- Triggers 
  151.    LIEUTENANT_PASSED_BY_TRIGGERS = { MP.."Car_Caught_Up_Trigger", 
  152.                                      MP.."Car_Caught_Up_Trigger02", 
  153.                                      MP.."Car_Caught_Up_Trigger03" } 
  154.    HAZE_TRIGGERS = { MP.."Haze_01", MP.."Haze_02", MP.."Haze_03", MP.."Haze_04" } 
  155.  
  156.    SPAWN_ADDITIONAL_CARS_TRIGGER = MP.."Spawn_Additional_Cars" 
  157.    -- Movers 
  158.    CHEMICAL_TANK = MP.."Chem_Tank" 
  159.    CHEMICAL_DEPOTS = { MP.."Chem_Depot_01", MP.."Chem_Depot_02", 
  160.                      MP.."Chem_Depot_03" } 
  161.    MOVER_TARGETS = { CHEMICAL_DEPOTS[1], CHEMICAL_DEPOTS[2], 
  162.                      CHEMICAL_DEPOTS[3], CHEMICAL_TANK } 
  163.  
  164.    BILLBOARD_PARTS = { MP.."BB_Part1", MP.."BB_Part2", MP.."BB_Part3" } 
  165.  
  166.    CAR_HUSK = MP.."Car_Husk_In_Barn" 
  167.    BARN_ROOF_NAME = MP.."Barn_Roof" 
  168.  
  169.    -- Effects and animation states 
  170.    CHEM_DEPOT_FIRE = "fire_chemical" 
  171.    CHEM_DEPOT_CROP_FIRE = "fire_chemical_spread" 
  172.    BARN_ROOF_EXPLOSION = "dth_barnroof" 
  173.  
  174.    -- Cutscenes 
  175.    CT_INTRO = "ss03-01" 
  176.    CT_OUTRO = "ss03-02" 
  177.  
  178. -- Sound 
  179.    -- Persona overrides 
  180.    TOBIAS_CHEER_ON_DESTROYED = "SOS03_TOBIAS_ATTACK" 
  181.    TOBIAS_CHEER_ON_DESTROYED_PERSONA_SITUATION = "custom line 1" 
  182.    TOBIAS_HELI_DAMAGED_PERSONA_SITUATION = "custom line 2" 
  183.  
  184.    -- Lines/Dialog Stream 
  185.    TOBIAS_INTRODUCTION_DIALOG_STREAM = 
  186.    { 
  187.    { "SOS3_START_L1", TOBIAS_NAME, 0 }, 
  188.    { "PLAYER_SOS3_START_L2", LOCAL_PLAYER, 0 }, 
  189.    { "SOS3_START_L3", TOBIAS_NAME, 0 }, 
  190.    { "PLAYER_SOS3_START_L4", LOCAL_PLAYER, 0 } 
  191.    } 
  192.    FLEEING_LIEUTENANTS_DIALOG_STREAM = 
  193.    { 
  194.    { "SOS3_FLEE_L1", TOBIAS_NAME, 0 }, 
  195.    { "PLAYER_SOS3_FLEE_L2", LOCAL_PLAYER, 0 } 
  196.    } 
  197.    TOBIAS_ON_BARN_DESTROYED = "TOBIAS_SOS3_BARN_EXPLODE" 
  198.    TOBIAS_CONGRAT_PLAYER = "TOBIAS_SOS3_CONGRAT_PLAYER" 
  199.  
  200. 	TOBIAS_ON_DAMAGED_LINES = { "TOBIAS_SOS03_TAKEDAM_1", "TOBIAS_SOS03_TAKEDAM_2", "TOBIAS_SOS03_TAKEDAM_3", 
  201. 										 "TOBIAS_SOS03_TAKEDAM_4", "TOBIAS_SOS03_TAKEDAM_5", "TOBIAS_SOS03_TAKEDAM_6" } 
  202.  
  203. -- Distances 
  204.  
  205. -- Percents and multipliers 
  206.    HAZE_CLOUD_STRENGTH = 0.75 
  207. 	ROCKET_LAUNCHER_HIT_POINT_MOD = .60 
  208. 	PLAYER_HELI_HIT_POINT_MOD = 2.5 
  209.  
  210. -- Time values 
  211.    HELI_CIRCULAR_RAIL_PATH_DELAYS_SECONDS = { { 0 }, { 6.0, 6.0, 6.0, 0 } } 
  212.    CHECKPOINT_FADE_IN_TIME_SECONDS = 1.0 
  213.  
  214.    MISSION_START_FADE_IN_TIME_SECONDS = 3.0 
  215.    START_NOTORIETY_DELAY_SECONDS = 60.0 
  216.    PERFECT_AIM_DELAY_SECONDS = 0--32 
  217.    HELI_WAIT_ON_CARS_DELAY_SECONDS = 0.0 
  218.    HELICOPTER_FOLLOW_PATH_DELAYS = { 0, 0.0 } 
  219.    HELICOPTER_FOLLOW_LOOP_PASSBY_DELAYS = { 0, 0, 0 } 
  220.  
  221.    DRUG_FIRE_TIME_TO_START_HAZE_EFFECT_SECONDS = 8.0 
  222.  
  223.    HAZE_CLOUD_RAMP_UP_SECONDS = 1.0 
  224.    HAZE_CLOUD_RAMP_DOWN_SECONDS = 12.0 
  225.  
  226.    BEFORE_BARN_EXPLOSION_DELAY_SECONDS = 2.0 
  227.  
  228.    BETWEEN_ESCAPE_CARS_DELAY_SECONDS = 1.5 
  229.    MISSION_END_FADE_OUT_TIME_SECONDS = 3.0 
  230.    DESTROYED_ALL_TARGETS_STOP_CIRCLING_DELAY_SECONDS = 2.0 
  231.    DESTROYED_BARN_LAST_EXTRA_TIME_SECONDS = 4.0 
  232.  
  233. -- Speeds 
  234.    HELI_TO_FARM_SPEED_MPS = 60 
  235.    HELI_CIRCLE_SPEED_MPS = 12 
  236.  
  237.    CAR_FINAL_PATH_SPEED_MPS = 35 
  238.    CAR_LEAD_SPEED_MPS = 35 
  239.    CAR_CHASE_SPEED_MPS = 55 
  240.    HELICOPTER_FOLLOW_PATH_SPEEDS = { 25, 25, 40 } 
  241.    HELICOPTER_FOLLOW_LOOP_PATH_SPEEDS = { 45, 45, 45 } 
  242.  
  243. -- Constant values and counts 
  244.    TOTAL_NUM_TARGETS = sizeof_table( MOVER_TARGETS ) + sizeof_table ( VEHICLE_TARGETS ) 
  245.    TOTAL_LIEUTENANT_VEHICLES = sizeof_table( ESCAPEE_VEHICLES ) 
  246.    TOTAL_GROUND_PERSONNEL = sizeof_table( GROUND_DEFENDERS ) + sizeof_table( ROCKET_LAUNCHER_GUYS ) 
  247.    HELICOPTER_HIT_POINTS = 40000 
  248.    TOBIAS_HIT_POINTS = 500000 
  249.    MIN_MISSION_NOTORIETY = 3 
  250.    NUM_HELI_CIRCULAR_RAIL_PATHS = sizeof_table( HELI_CIRCULAR_RAIL_PATHS ) 
  251.    DUD_SPAWN_THRESHOLD = TOTAL_GROUND_PERSONNEL * .75 
  252.  
  253.    HAZE_CLOUD_RAMP_INCREMENTS = 30 
  254.    NUM_LOOPS_BEFORE_STOP = 2 
  255.    HELI_MAX_BANK_ANGLE = 0.2 
  256.  
  257.    INITIAL_LIEUTENANT_VEHICLE_COUNT = 2 
  258. 	NUM_ON_DAMAGED_LINES = sizeof_table( TOBIAS_ON_DAMAGED_LINES ) 
  259.  
  260. -- Global variables 
  261.    Next_Tobias_cheer_index = 1 
  262.    Num_targets_destroyed = 0 
  263.    Heli_circle_pathing_thread_handle = INVALID_THREAD_HANDLE 
  264.  
  265.    Current_haze_strength = 0 
  266.  
  267.    Car_path_threads = { INVALID_THREAD_HANDLE, INVALID_THREAD_HANDLE } 
  268.  
  269.    Lieutenant_car_passed_by_triggers = { false, false, false } 
  270.  
  271.    Heli_at_holding_position = false 
  272.    Num_cars_killed = 0 
  273.    Num_members_killed = 0 
  274.    Start_notoriety_countdown_thread_handle = INVALID_THREAD_HANDLE 
  275.  
  276.    Num_ground_personnel_remaining = TOTAL_GROUND_PERSONNEL 
  277.    Drive_up_defenders_spawned = false 
  278.    Current_lieutenant_count = TOTAL_LIEUTENANT_VEHICLES 
  279.    Lead_car_name = "none" 
  280.  
  281.    Lead_car_current_path_segment = ESCAPEE_START_PATH 
  282.    Lead_car_resumed_from_index = 0 
  283.  
  284.    Lead_car_loop_index = 1 
  285. 	Cur_on_damage_line_index = 1 
  286. 	 
  287. 	--Toggle Damage yelling 
  288. 	Audio_playing = false 
  289.  
  290.    Extra_vehicles_added_to_chase = false 
  291.  
  292. 	Debug_car_followed = false 
  293.  
  294.  
  295. function ss03_start( checkpoint_name, is_restart ) 
  296. 	-- Start trigger is hit...the activate button was hit 
  297. 	set_mission_author("Brad Johnson and Mark Gabby") 
  298.  
  299.    audio_suppress_ambient_player_lines( true ) 
  300.  
  301.    persona_override_group_start( SAMEDI_PERSONAS, POT_SITUATIONS[POT_ATTACK], "SS03_ATTACK" ) 
  302.  
  303.    -- Vehicles cause problems with the car chase, yo 
  304.    spawning_pedestrians( false ) 
  305.  
  306.    -- TEMP 
  307. 	--checkpoint_name = KILL_LIEUTENANTS_CHECKPOINT 
  308.    -- END TEMP 
  309.  
  310. 	script_profiler_reset() 
  311.  
  312.    mission_start_fade_out() 
  313.  
  314.    if ( checkpoint_name == MISSION_START_CHECKPOINT ) then 
  315. 		if (not is_restart) then 
  316. 			cutscene_play( CT_INTRO, { TOBIAS_GROUP, HELICOPTER_GROUP }, { NEAR_HELICOPTER, NEAR_HELICOPTER_REMOTE_PLAYER }, false ) 
  317. 			script_profiler_start_section( "SS03 Start" ) 
  318. 		else 
  319. 			script_profiler_start_section( "SS03 Start" ) 
  320. 			script_profiler_start_section( "SS03 Restart Teleport Coop" ) 
  321. 	      teleport_coop( NEAR_HELICOPTER, NEAR_HELICOPTER_REMOTE_PLAYER )  
  322. 			script_profiler_end_section( "SS03 Restart Teleport Coop" ) 
  323. 			-- Create the helicopter and seat the player(s) and the pilot 
  324. 			script_profiler_start_section( "SS03 Restart Blocking Group Creates" ) 
  325. 			group_create_hidden( TOBIAS_GROUP, true ) 
  326. 			group_create_hidden( HELICOPTER_GROUP, true ) 
  327. 			script_profiler_end_section( "SS03 Restart Blocking Group Creates" ) 
  328. 		end 
  329.    end 
  330. 	-- Add and equip the appropriate weapons 
  331. 	inv_weapon_add_temporary( LOCAL_PLAYER, SAW_NAME, 1, true, true ) 
  332. 	if ( coop_is_active() ) then 
  333. 		inv_weapon_add_temporary( REMOTE_PLAYER, SAW_NAME, 1, true, true )  
  334. 	end 
  335.    inv_item_equip( SAW_NAME, LOCAL_PLAYER ) 
  336.    if ( coop_is_active() ) then 
  337.       inv_item_equip( SAW_NAME, REMOTE_PLAYER ) 
  338.    end 
  339.  
  340. 	script_profiler_start_section( "SS03 Misc" ) 
  341.    group_create_hidden( GAS_STATION_GROUP ) 
  342.  
  343.    for index, name in pairs( BILLBOARD_PARTS ) do 
  344.       mesh_mover_hide( name ) 
  345.    end 
  346.  
  347.    inv_weapon_disable_all_but_this_slot( WEAPON_SLOT_RIFLE ) 
  348.  
  349.    if ( checkpoint_name == MISSION_START_CHECKPOINT ) then 
  350.       party_dismiss_all() 
  351.  
  352. 		script_profiler_start_section( "Misc Group Setup" ) 
  353. 		group_show( TOBIAS_GROUP ) 
  354. 		group_show( HELICOPTER_GROUP ) 
  355. 		-- Create these groups, but don't blocking load them because we have some time 
  356. 		-- before they're necessary 
  357. 		group_create( TARGET_VEHICLES_GROUP ) 
  358.       group_create( GROUND_DEFENDERS_GROUP ) 
  359. 		group_create_hidden( ESCAPEES_GROUP ) 
  360.       group_create_hidden( DRIVE_UP_DEFENDERS_GROUP ) 
  361. 		script_profiler_end_section( "Misc Group Setup" ) 
  362.  
  363. 		script_profiler_start_section( "Misc Threads" ) 
  364. 		thread_new( "ss03_setup_ground_defenders_when_group_loads" ) 
  365. 		thread_new( "ss03_setup_targets_when_group_loads" ) 
  366. 		script_profiler_end_section( "Misc Threads" ) 
  367.  
  368.       helicopter_set_max_bank_angle( HELICOPTER_NAME, HELI_MAX_BANK_ANGLE ) 
  369. 		ss03_player_heli_hitpoint_adjust( HELICOPTER_NAME ) 
  370.  
  371. 		script_profiler_start_section( "Misc Seat People" ) 
  372.       ss03_board_helicopter() 
  373. 		script_profiler_end_section( "Misc Seat People" ) 
  374.  
  375.       for index, mover_name in pairs( MOVER_TARGETS ) do 
  376.          on_mover_destroyed( "ss03_target_mover_destroyed", mover_name ) 
  377.          marker_add_mover( mover_name, "", INGAME_EFFECT_VEHICLE_KILL, SYNC_ALL ) 
  378.       end 
  379.  
  380. 		script_profiler_start_section( "Misc Do Path" ) 
  381.       -- Have the helicopter start on its path 
  382.       thread_new( "ss03_helicopter_do_path" ) 
  383. 		script_profiler_end_section( "Misc Do Path" ) 
  384.    elseif( checkpoint_name == KILL_LIEUTENANTS_CHECKPOINT ) then 
  385. 		-- This group MUST be ready  
  386. 		group_create_hidden( ESCAPEES_GROUP, true ) 
  387.  
  388.       if ( group_is_loaded( TOBIAS_GROUP ) == false ) then 
  389.          group_create( TOBIAS_GROUP, true ) 
  390.       end 
  391.       teleport( TOBIAS_NAME, TOBIAS_CHECKPOINT_WARP ) 
  392.  
  393.       thread_yield() 
  394.       if ( group_is_loaded( HELICOPTER_GROUP ) == false ) then 
  395.          group_create( HELICOPTER_GROUP, true ) 
  396.       end 
  397.       teleport_vehicle( HELICOPTER_NAME, HELI_CHECKPOINT_WARP ) 
  398.       thread_yield() 
  399.  
  400.       helicopter_set_max_bank_angle( HELICOPTER_NAME, HELI_MAX_BANK_ANGLE ) 
  401.  
  402.       -- Get the helicopter ready and fly it to the holding position 
  403.       ss03_board_helicopter() 
  404.  
  405. 		teleport_vehicle( HELICOPTER_NAME, HELI_HOLDING_POSITION ) 
  406.       helicopter_fly_to( HELICOPTER_NAME, HELI_CIRCLE_SPEED_MPS, HELI_HOLDING_POSITION ) 
  407.       Heli_at_holding_position = true 
  408.  
  409.       -- Set up the effects, including the barn on fire and the fields burning 
  410.       mesh_mover_hide( BARN_ROOF_NAME ) 
  411.       for index, name in pairs( MOVER_TARGETS ) do 
  412.          mesh_mover_hide( name ) 
  413.       end 
  414.       for index, depot_locations in pairs( CHEM_DEPOT_FIRE_LOCATIONS ) do 
  415.          effect_play( CHEM_DEPOT_FIRE, depot_locations, true ) 
  416.       end 
  417.       for index, cluster_group in pairs( CROP_FIRE_SPREAD_SEQUENCES ) do 
  418.          for index, cluster in pairs( cluster_group ) do 
  419.             ss03_ignite_cluster( cluster ) 
  420.          end 
  421.       end 
  422.    end 
  423.  
  424.    -- Don't want the helichopper to go crazy if it's hit by a rocket 
  425.    vehicle_prevent_explosion_fling( HELICOPTER_NAME, true ) 
  426.    -- Boost the helicopter's HP - it'll be under heavy fire, after all 
  427.    set_max_hit_points( HELICOPTER_NAME, HELICOPTER_HIT_POINTS ) 
  428.    set_current_hit_points( HELICOPTER_NAME, HELICOPTER_HIT_POINTS ) 
  429.     
  430.    set_max_hit_points( TOBIAS_NAME, TOBIAS_HIT_POINTS  ) 
  431.    set_current_hit_points( TOBIAS_NAME, TOBIAS_HIT_POINTS ) 
  432.  
  433.    set_player_can_enter_exit_vehicles( LOCAL_PLAYER, false ) 
  434.    if ( coop_is_active() ) then 
  435.       set_player_can_enter_exit_vehicles( REMOTE_PLAYER, false ) 
  436.    end 
  437.  
  438.    inv_item_equip( SAW_NAME, REMOTE_PLAYER ) 
  439.  
  440.    persona_override_character_start( TOBIAS_NAME, TOBIAS_CHEER_ON_DESTROYED_PERSONA_SITUATION, 
  441.                                      TOBIAS_CHEER_ON_DESTROYED ) 
  442. 	script_profiler_end_section( "SS03 Misc" ) 
  443.    if ( checkpoint_name == MISSION_START_CHECKPOINT ) then    
  444. 		script_profiler_end_section( "SS03 Start" ) 
  445.       mission_start_fade_in() 
  446. 		script_profiler_do_printout() 
  447.       thread_new( "ss03_helicopter_conversation" ) 
  448.    else 
  449. 		script_profiler_end_section( "SS03 Start" ) 
  450.       mission_start_fade_in() 
  451. 		script_profiler_do_printout() 
  452.       ss03_switch_state( MS_FARM_DESTROYED ) 
  453.    end 
  454.  
  455.    drug_enable_disable_effect_override( true, SYNC_ALL ) 
  456. end 
  457.  
  458. function ss03_setup_ground_defenders_when_group_loads() 
  459. 	repeat 
  460. 		thread_yield() 
  461. 	until( group_is_loaded( GROUND_DEFENDERS_GROUP ) ) 
  462.  
  463. 	for index, name in pairs( GROUND_DEFENDERS ) do 
  464. 		on_death( "ss03_ground_personnel_member_died", name ) 
  465. 	end 
  466. 	for index, name in pairs( ROCKET_LAUNCHER_GUYS ) do 
  467. 		ss03_rocket_guys_hitpoint_adjust( name ) 
  468. 		on_death( "ss03_ground_personnel_member_died", name ) 
  469. 	end 
  470. end 
  471.  
  472. function ss03_setup_targets_when_group_loads() 
  473. 	repeat 
  474. 		thread_yield() 
  475. 	until( group_is_loaded( TARGET_VEHICLES_GROUP ) ) 
  476.  
  477. 	for index, vehicle_name in pairs( VEHICLE_TARGETS ) do 
  478. 		turn_invulnerable( vehicle_name ) 
  479. 		on_take_damage( "ss03_target_vehicle_player_damage_passthrough", vehicle_name ) 
  480. 		on_vehicle_destroyed( "ss03_target_vehicle_destroyed", vehicle_name ) 
  481. 		marker_add_vehicle( vehicle_name, "", INGAME_EFFECT_VEHICLE_KILL, SYNC_ALL ) 
  482. 	end 
  483. 	vehicle_attach_trailer( VEHICLE_AND_TRAILER[1], VEHICLE_AND_TRAILER[2] ) 
  484. end 
  485.  
  486. function ss03_rocket_guys_hitpoint_adjust( CHARACTER ) 
  487. local rocket_man_hit_points = get_max_hit_points(CHARACTER) 
  488.  
  489. 	-- adjust the ROCKET_LAUNCHER_HIT_POINT_MOD variable to increase or decrease the hitpoints 
  490. 	set_current_hit_points(CHARACTER, (rocket_man_hit_points*ROCKET_LAUNCHER_HIT_POINT_MOD)) 
  491.  
  492. end 
  493.  
  494. function ss03_player_heli_hitpoint_adjust( VEHICLE ) 
  495. 	local heli_hit_points = get_max_hit_points( VEHICLE )	 
  496. 	-- adjust the PLAYER_HELI_HIT_POINT_MOD variable to increase or decrease the hitpoints 
  497. 	set_current_hit_points(VEHICLE, (heli_hit_points*PLAYER_HELI_HIT_POINT_MOD)) 
  498. end 
  499.  
  500. function ss03_tobias_curse_on_damage() 
  501. 	local CURRENT_HELI_HITPOINTS = get_current_hit_points(HELICOPTER_NAME) 
  502. 	local MAX_HELI_HITPOINTS = get_max_hit_points(HELICOPTER_NAME) 
  503.  
  504. 	--Only play lines when the hitpoints of the helicopter are less or = to 50% of the heli max 
  505. 	if Audio_playing == false  and (CURRENT_HELI_HITPOINTS <= (MAX_HELI_HITPOINTS/2)) then 
  506. 		--Make Tobias scream words that make Mark's ears burn when the helicopter is damaged. 
  507. 		Audio_playing = true 
  508. 		audio_play_for_character( TOBIAS_ON_DAMAGED_LINES[Cur_on_damage_line_index], TOBIAS_NAME, "voice", false, true ) 
  509. 		delay(20) 
  510. 		Audio_playing = false 
  511.  
  512. 		Cur_on_damage_line_index = Cur_on_damage_line_index + 1 
  513. 		if ( Cur_on_damage_line_index > NUM_ON_DAMAGED_LINES ) then 
  514. 			Cur_on_damage_line_index = 1 
  515. 		end 
  516. 	end 
  517. end 
  518.  
  519. function ss03_target_vehicle_player_damage_passthrough( victim_name, attacker_name, percent_hp_remaining_after_attack ) 
  520.    if ( attacker_name == LOCAL_PLAYER or 
  521.         attacker_name == REMOTE_PLAYER ) then 
  522.  
  523.       if ( percent_hp_remaining_after_attack > 0 ) then 
  524.          local new_hp = get_max_hit_points( victim_name ) * percent_hp_remaining_after_attack 
  525.          set_current_hit_points( victim_name, new_hp ) 
  526.       else 
  527.          turn_vulnerable( victim_name ) 
  528.       end 
  529.    end 
  530. end 
  531.  
  532. function ss03_drive_up_defenders_run_defense() 
  533.    Drive_up_defenders_spawned = true 
  534.    group_show( DRIVE_UP_DEFENDERS_GROUP ) 
  535.  
  536.    vehicle_enter_group_teleport( DUD_MEMBERS, DUD_VEHICLE ) 
  537.    vehicle_pathfind_to( DUD_VEHICLE, DUD_TO_FARM_PATH, false, false ) 
  538.    vehicle_pathfind_to( DUD_VEHICLE, DUD_ENTER_FARM_PATH, true, true ) 
  539.  
  540.    for index, member_name in pairs( DUD_MEMBERS ) do 
  541.       vehicle_exit( member_name ) 
  542.    end 
  543.    for index, member_name in pairs( DUD_MEMBERS ) do 
  544.       attack_safe( member_name, LOCAL_PLAYER ) 
  545.    end 
  546. end 
  547.  
  548. function ss03_ground_personnel_member_died() 
  549.    Num_ground_personnel_remaining = Num_ground_personnel_remaining - 1 
  550.  
  551.    mission_debug( Num_ground_personnel_remaining.." ground personnel remain." ) 
  552.  
  553.    if ( Num_ground_personnel_remaining <= DUD_SPAWN_THRESHOLD and 
  554.         Drive_up_defenders_spawned == false ) then 
  555.  
  556.       mission_debug( "running DUD" ) 
  557.       ss03_drive_up_defenders_run_defense() 
  558.    end 
  559. end 
  560.  
  561. function ss03_board_helicopter() 
  562. 	script_profiler_start_section( "Seat People Equip Weapons" ) 
  563. 	repeat 
  564. 		thread_yield()	 
  565. 	until ( inv_item_is_equipped( SAW_NAME, LOCAL_PLAYER ) ) 
  566.    if ( coop_is_active() ) then 
  567. 		repeat 
  568. 			thread_yield()	 
  569. 		until ( inv_item_is_equipped( SAW_NAME, REMOTE_PLAYER ) ) 
  570.    end 
  571. 	script_profiler_end_section( "Seat People Equip Weapons" ) 
  572.  
  573. 	-- Wait until both players are in the vehicle before continuing 
  574. 	script_profiler_start_section( "Seat People Enter Helicopter" ) 
  575.    vehicle_enter_teleport( LOCAL_PLAYER, HELICOPTER_NAME, 2, true ) 
  576. 	if ( coop_is_active() ) then 
  577.       vehicle_enter_teleport( REMOTE_PLAYER, HELICOPTER_NAME, 3, true ) 
  578.    end 
  579.    while ( character_is_in_vehicle( LOCAL_PLAYER, HELICOPTER_NAME ) == false ) do 
  580.       delay( 0 ) 
  581.    end 
  582. 	if ( coop_is_active() ) then 
  583.       while ( character_is_in_vehicle( REMOTE_PLAYER, HELICOPTER_NAME ) == false ) do 
  584.          delay( 0 ) 
  585.       end 
  586.    end 
  587. 	script_profiler_end_section( "Seat People Enter Helicopter" ) 
  588.  
  589.    -- Finally, teleport Tobias into the helicopter 
  590.    vehicle_enter_teleport( TOBIAS_NAME, HELICOPTER_NAME, 0, true ) 
  591. 	repeat 
  592. 		thread_yield()	 
  593. 	until ( character_is_in_vehicle( TOBIAS_NAME, HELICOPTER_NAME ) ) 
  594. end 
  595.  
  596. function ss03_helicopter_do_path() 
  597. 	teleport_vehicle( HELICOPTER_NAME, "ss03_$Heli_Start" ) 
  598.  
  599.    helicopter_fly_to( HELICOPTER_NAME, HELI_TO_FARM_SPEED_MPS, HELI_TO_FARM_PATH ) 
  600.  
  601.    ss03_switch_state( MS_REACHED_FARM ) 
  602. end 
  603.  
  604. function ss03_2d_conversation( dialog_stream ) 
  605.    for index, dialog_segment in pairs( dialog_stream ) do 
  606.       if ( dialog_segment[DIALOG_STREAM_CHAR_NAME_INDEX] == LOCAL_PLAYER ) then 
  607.          audio_play_for_character( dialog_segment[DIALOG_STREAM_AUDIO_NAME_INDEX], LOCAL_PLAYER, "voice", false, true ) 
  608.       else 
  609.          audio_play( dialog_segment[DIALOG_STREAM_AUDIO_NAME_INDEX], "voice", true ) 
  610.       end 
  611.    end 
  612. end 
  613.  
  614. function ss03_helicopter_conversation() 
  615.    ss03_2d_conversation( TOBIAS_INTRODUCTION_DIALOG_STREAM ) 
  616. end 
  617.  
  618. function ss03_perfect_aim_delay() 
  619.    delay( PERFECT_AIM_DELAY_SECONDS ) 
  620.  
  621.    for index, name in pairs( ROCKET_LAUNCHER_GUYS ) do 
  622.       set_perfect_aim( name, true ) 
  623.       attack_safe( name, LOCAL_PLAYER ) 
  624.    end 
  625. end 
  626.  
  627. function ss03_switch_state( new_state ) 
  628.    if ( new_state == MS_REACHED_FARM ) then 
  629.       -- Prompt the player and give him guidance on what to do 
  630.       mission_help_table( HT_DESTROY_FARM_EQUIPMENT, "", "", SYNC_ALL ) 
  631.       -- Setup the targets so that the player knows what to shoot and the hits are recorded 
  632.       for index, vehicle_name in pairs( VEHICLE_TARGETS ) do 
  633.          marker_remove_vehicle( vehicle_name ) 
  634.          marker_add_vehicle( vehicle_name, MINIMAP_ICON_KILL, INGAME_EFFECT_VEHICLE_KILL, SYNC_ALL ) 
  635.       end 
  636.       for index, mover_name in pairs( MOVER_TARGETS ) do 
  637.          marker_remove_mover( mover_name ) 
  638.          marker_add_mover( mover_name, MINIMAP_ICON_KILL, INGAME_EFFECT_VEHICLE_KILL, SYNC_ALL ) 
  639.       end 
  640.  
  641.       -- Setup things that trigger notoriety starting 
  642.       on_weapon_fired( "ss03_player_fired_gun", LOCAL_PLAYER ) 
  643.       if ( coop_is_active() ) then 
  644.          on_weapon_fired( "ss03_player_fired_gun", REMOTE_PLAYER ) 
  645.       end 
  646.       Start_notoriety_countdown_thread_handle = thread_new( "ss03_start_notoriety_countdown" ) 
  647.       notoriety_force_no_spawn( ENEMY_GANG, true ) 
  648.  
  649.       local helicopter_hit_points = get_max_hit_points( HELICOPTER_NAME ) 
  650.  
  651.       on_vehicle_destroyed( "ss03_helicopter_destroyed", HELICOPTER_NAME ) 
  652.       on_vehicle_exit( "ss03_left_helicopter", HELICOPTER_NAME ) 
  653. 		on_take_damage("ss03_tobias_curse_on_damage", HELICOPTER_NAME)  
  654.  
  655.       -- Start the helicopter 
  656.       Heli_circle_pathing_thread_handle = thread_new( "ss03_helicopter_circle" ) 
  657.    elseif ( new_state == MS_FARM_DESTROYED ) then 
  658.       while ( Heli_at_holding_position == false ) do 
  659.          delay( 0 ) 
  660.       end 
  661.       mission_set_checkpoint( KILL_LIEUTENANTS_CHECKPOINT ) 
  662.       objective_text_clear( 0 ) 
  663.       group_show( ESCAPEES_GROUP ) 
  664.  
  665.       for group_index, group_members in pairs( ESCAPEES ) do 
  666.          --set_ignore_ai_flag( group_members[1], true ) 
  667.          vehicle_disable_chase( ESCAPEE_VEHICLES[group_index], true ) 
  668.          vehicle_enter_teleport( group_members[1], ESCAPEE_VEHICLES[group_index], 0, true ) 
  669.          turn_invulnerable( group_members[1] ) 
  670.          vehicle_enter_teleport( group_members[2], ESCAPEE_VEHICLES[group_index], 1, true ) 
  671.          vehicle_enter_teleport( group_members[3], ESCAPEE_VEHICLES[group_index], 2, true ) 
  672.          vehicle_enter_teleport( group_members[4], ESCAPEE_VEHICLES[group_index], 3, true ) 
  673.  
  674.          vehicle_max_speed( ESCAPEE_VEHICLES[group_index], 0 )  
  675.  
  676.          vehicle_suppress_npc_exit( ESCAPEE_VEHICLES[group_index], true ) 
  677.  
  678.          on_vehicle_destroyed( "ss03_car_destroyed", ESCAPEE_VEHICLES[group_index] ) 
  679.       end 
  680.  
  681.       objective_text( 0, HT_X_OF_Y_LIEUTENANTS, 0, Current_lieutenant_count ) 
  682.  
  683.       ss03_make_car_lead_car( ESCAPEE_VEHICLES[1] ) 
  684.       Car_path_threads[1] = thread_new( "ss03_lead_car_start_pathfind", 1 ) 
  685.       ss03_add_car_to_convoy( 2 ) 
  686.  
  687.       delay( HELI_WAIT_ON_CARS_DELAY_SECONDS ) 
  688.  
  689.       thread_new( "ss03_heli_follow_cars" ) 
  690.  
  691.       trigger_enable( SPAWN_ADDITIONAL_CARS_TRIGGER, true ) 
  692.       on_trigger( "ss03_add_cars_to_chase", SPAWN_ADDITIONAL_CARS_TRIGGER ) 
  693.  
  694.       delay( 3.0 ) 
  695.       mission_help_table( HT_ELIMINATE_LIEUTENANTS, "", "", SYNC_ALL ) 
  696.  
  697.    elseif ( new_state == MS_BEGIN_CHASE ) then 
  698.    end 
  699. end 
  700.  
  701. function ss03_add_cars_to_chase( triggerer_name, trigger_name ) 
  702.    trigger_enable( trigger_name, false ) 
  703.  
  704.    -- Update the lieutenant count and objective text 
  705.    objective_text( 0, HT_X_OF_Y_LIEUTENANTS, Num_cars_killed, Current_lieutenant_count ) 
  706.  
  707.    local car_alive = false 
  708.  
  709.    -- Find the first living car with a smaller index, if it exists, and follow that car 
  710.    for i = 2, 1, -1 do 
  711.       if ( vehicle_is_destroyed( ESCAPEE_VEHICLES[i] ) == false ) then 
  712. 			car_alive = true 
  713.       end 
  714.    end 
  715.  
  716.    if ( car_alive ) then 
  717. 		Debug_car_followed = true 
  718.       ss03_add_car_to_convoy( 3 ) 
  719.    else 
  720. 		Debug_car_followed = false 
  721.       Lead_car_resumed_from_index = 0 
  722.       Lead_car_current_path_segment = ESCAPEE_PATHS[1] 
  723.       ss03_setup_car_for_pathfinding( 3 ) 
  724.       thread_new( "ss03_make_car_lead_car", ESCAPEE_VEHICLES[3], 17 ) 
  725.    end 
  726.    ss03_add_car_to_convoy( 4 ) 
  727.  
  728.    Extra_vehicles_added_to_chase = true 
  729. end 
  730.  
  731. function ss03_player_fired_gun() 
  732.    ss03_do_notoriety() 
  733.    ss03_clear_notoriety_functions() 
  734. end 
  735.  
  736. function ss03_start_notoriety_countdown() 
  737.    delay( START_NOTORIETY_DELAY_SECONDS ) 
  738.  
  739.    ss03_do_notoriety() 
  740.    ss03_clear_notoriety_functions() 
  741. end 
  742.  
  743. function ss03_do_notoriety() 
  744.    for index, name in pairs( GROUND_DEFENDERS ) do 
  745.       attack_safe( name, LOCAL_PLAYER ) 
  746.    end 
  747.    notoriety_set_min( ENEMY_GANG, MIN_MISSION_NOTORIETY ) 
  748.  
  749.    thread_new( "ss03_perfect_aim_delay" ) 
  750. end 
  751.  
  752. function ss03_clear_notoriety_functions() 
  753.    if ( Start_notoriety_countdown_thread_handle ~= INVALID_THREAD_HANDLE ) then 
  754.       thread_kill( Start_notoriety_countdown_thread_handle ) 
  755.       Start_notoriety_countdown_thread_handle = INVALID_THREAD_HANDLE 
  756.    end 
  757.  
  758.    on_weapon_fired( "", LOCAL_PLAYER ) 
  759.    if ( coop_is_active() ) then 
  760.       on_weapon_fired( "", REMOTE_PLAYER ) 
  761.    end 
  762. end 
  763.  
  764. function ss03_heli_follow_cars() 
  765.  
  766.    for index, path_name in pairs( HELICOPTER_FOLLOW_PATHS ) do 
  767.       delay( HELICOPTER_FOLLOW_PATH_DELAYS[index] ) 
  768.       helicopter_fly_to_direct_follow_dont_stop( HELICOPTER_NAME, HELICOPTER_FOLLOW_PATH_SPEEDS[index], Lead_car_name, path_name ) 
  769.    end 
  770.  
  771.    local loops = 0 
  772.  
  773.    while( Num_cars_killed < TOTAL_LIEUTENANT_VEHICLES and loops < NUM_LOOPS_BEFORE_STOP ) do 
  774.       for index, path_name in pairs( HELICOPTER_FOLLOW_LOOP_PATHS ) do 
  775.          if ( loops == NUM_LOOPS_BEFORE_STOP - 1 ) then 
  776.             helicopter_fly_to_direct_follow( HELICOPTER_NAME, HELICOPTER_FOLLOW_LOOP_PATH_SPEEDS[index], Lead_car_name, path_name ) 
  777.          else 
  778.             helicopter_fly_to_direct_follow_dont_stop( HELICOPTER_NAME, HELICOPTER_FOLLOW_LOOP_PATH_SPEEDS[index], Lead_car_name, path_name ) 
  779.          end 
  780.       end 
  781.  
  782.       delay( 0 ) 
  783.  
  784.       loops = loops + 1 
  785.        
  786.       if ( loops == NUM_LOOPS_BEFORE_STOP - 1 ) then 
  787.          -- We're going to make a stop at the gas station the next time around, so show that group 
  788.          thread_new( "ss03_show_gas_station_groups", 10 ) 
  789.       end 
  790.    end 
  791. end 
  792.  
  793. function ss03_show_gas_station_groups( delay_seconds ) 
  794.    delay( delay_seconds ) 
  795.  
  796.    group_show( GAS_STATION_GROUP ) 
  797. end 
  798.  
  799. -- Returns the index of a escapee vehicle from its name. 
  800. -- Returns -1 if the vehicle wasn't found. 
  801. -- 
  802. function ss03_escapee_vehicle_index_from_name( vehicle_name ) 
  803.    for index, escapee_vehicle_name in pairs( ESCAPEE_VEHICLES ) do 
  804.       if ( vehicle_name == escapee_vehicle_name ) then 
  805.          return index 
  806.       end 
  807.    end 
  808.  
  809.    return -1 
  810. end 
  811.  
  812. -- Finds the index of the next living escapee car after the passed-in car index. 
  813. -- 
  814. -- Returns -1 if there are no living cars after the passed-in index. 
  815. -- Note: Will NEVER return the passed-in index 
  816. -- 
  817. function ss03_find_next_living_escapee_car_index( start_car_index ) 
  818.    local next_car_index = start_car_index + 1 
  819.  
  820.    while ( next_car_index <= Current_lieutenant_count and 
  821.            vehicle_is_destroyed( ESCAPEE_VEHICLES[next_car_index] ) == true ) do 
  822.       next_car_index = next_car_index + 1 
  823.    end 
  824.  
  825.    -- Don't include the extra lieutenants until they've been added 
  826.    if ( ( next_car_index > INITIAL_LIEUTENANT_VEHICLE_COUNT and 
  827.           Extra_vehicles_added_to_chase == false ) ) then 
  828.       return -1 
  829.    end 
  830.  
  831.    -- Don't include car indices past the end 
  832.    if ( next_car_index > Current_lieutenant_count  ) then 
  833.       return -1 
  834.    end 
  835.  
  836.    return next_car_index 
  837. end 
  838.  
  839. function ss03_make_car_lead_car( vehicle_name, path_point_index ) 
  840.    -- If the resume path point index isn't nil, then this car is taking 
  841.    -- over for another lead car that was just destroyed 
  842.    local is_replacement_lead_car = false 
  843.    if ( path_point_index ~= nil ) then 
  844.       is_replacement_lead_car = true 
  845.    end 
  846.  
  847.    Lead_car_name = vehicle_name 
  848.    vehicle_ignore_repulsors( Lead_car_name, true ) 
  849.    helicopter_go_to_change_follow_target( HELICOPTER_NAME, Lead_car_name ) 
  850.    on_vehicle_destroyed( "ss03_lead_car_destroyed", Lead_car_name ) 
  851.    vehicle_max_speed( vehicle_name, CAR_LEAD_SPEED_MPS ) 
  852.    vehicle_speed_override( vehicle_name, CAR_LEAD_SPEED_MPS ) 
  853.  
  854.    if ( is_replacement_lead_car ) then 
  855.       local resume_path_point_index = path_point_index + Lead_car_resumed_from_index 
  856.  
  857.       local car_index = ss03_escapee_vehicle_index_from_name( vehicle_name ) 
  858.       mission_debug( "car "..vehicle_name.." resuming from path point "..resume_path_point_index, 15 ) 
  859.       ss03_new_lead_car_resume_pathfind( car_index, resume_path_point_index ) 
  860.    end 
  861. end 
  862.  
  863. function ss03_lead_car_destroyed( vehicle_name, path_point_index ) 
  864. 	if ( path_point_index ~= nil ) then 
  865. 	   mission_debug( "lead car destroyed. path index returned was "..path_point_index, 15 ) 
  866. 	else 
  867. 		path_point_index = 0 
  868. 	end 
  869.  
  870.    local vehicle_index = ss03_escapee_vehicle_index_from_name( vehicle_name ) 
  871.    local next_car_index = ss03_find_next_living_escapee_car_index( vehicle_index ) 
  872.  
  873.    -- This car was destroyed, do the callback 
  874.    ss03_car_destroyed( vehicle_name ) 
  875.  
  876.    -- If there's another car, then the mission can continue 
  877.    if ( next_car_index ~= -1 ) then 
  878.       ss03_make_car_lead_car( ESCAPEE_VEHICLES[next_car_index], path_point_index ) 
  879.    -- If there's not another car, check to see if maybe the extras haven't been added - 
  880.    -- If so, we need to proceed normally to the trigger where they're added 
  881.    elseif ( Extra_vehicles_added_to_chase == false ) then 
  882.       mission_debug( "cleared follow target" ) 
  883.       helicopter_go_to_clear_follow_target( HELICOPTER_NAME ) 
  884.    end 
  885. end 
  886.  
  887. function ss03_following_car_destroyed( vehicle_name ) 
  888.    -- Fix the gap in the chain of following cars caused by this car's death 
  889.    local vehicle_index = ss03_escapee_vehicle_index_from_name( vehicle_name ) 
  890.    local next_car_index = ss03_find_next_living_escapee_car_index( vehicle_index ) 
  891.    if ( next_car_index > 0 ) then 
  892.       -- already_following = true 
  893.       ss03_add_car_to_convoy( next_car_index, true ) 
  894.       mission_debug( "following car "..vehicle_name.." destroyed. next car index "..next_car_index.." chasing.", 15 ) 
  895.    else 
  896.       mission_debug( "following car "..vehicle_name.." destroyed.", 15 ) 
  897.    end 
  898.  
  899.    -- Handle the car destroyed 
  900.    ss03_car_destroyed( vehicle_name ) 
  901. end 
  902.  
  903. function ss03_all_current_targets_killed() 
  904.    if ( ( Num_cars_killed + Num_members_killed ) == Current_lieutenant_count ) then 
  905.       return true 
  906.    end 
  907.    return false 
  908. end 
  909.  
  910. function ss03_car_destroyed( vehicle_name ) 
  911.    local car_index = ss03_escapee_vehicle_index_from_name( vehicle_name ) 
  912.    turn_vulnerable( ESCAPEES[car_index][1] ) 
  913.    character_kill( ESCAPEES[car_index][1] ) 
  914.    marker_remove_vehicle( vehicle_name ) 
  915.  
  916.    Num_cars_killed = Num_cars_killed + 1 
  917.  
  918.    objective_text( 0, HT_X_OF_Y_LIEUTENANTS, Num_cars_killed, Current_lieutenant_count ) 
  919.     
  920.    ss03_update_objective_text_including_individuals() 
  921.  
  922.    -- The mission ends if all current targets have been killed, 
  923.    -- but only if the extra cars have been added to the chase 
  924.    if ( ss03_all_current_targets_killed() and 
  925.         Current_lieutenant_count >= TOTAL_LIEUTENANT_VEHICLES ) then 
  926.       mission_end_success( MISSION_NAME, CT_OUTRO ) 
  927.    end 
  928. end 
  929.  
  930. function ss03_path_is_in_table( path_name, table_name ) 
  931.    for index, name in pairs( table_name ) do 
  932.       if ( path_name == name ) then 
  933.          return true 
  934.       end 
  935.    end 
  936.  
  937.    return false 
  938. end 
  939.  
  940. function ss03_get_paths_index( path_name, table_name ) 
  941.    for index, name in pairs( table_name ) do 
  942.       if ( path_name == name ) then 
  943.          return index 
  944.       end 
  945.    end 
  946.    return -1 
  947. end 
  948.  
  949. function ss03_resume_lead_car_path( lead_car, resuming_path_index, path_name ) 
  950.    -- Go the rest of the way along this path 
  951.    vehicle_navmesh_pathfind_to_starting_from( lead_car, resuming_path_index, path_name, false, false ) 
  952.    if ( vehicle_is_destroyed( lead_car )  ) then 
  953.       return false 
  954.    end 
  955.    -- Now that the lead car has finished the rest of the old lead car's path, if it dies we'll get the correct index, so no need for this anymore 
  956.    Lead_car_resumed_from_index = 0    
  957.    return true 
  958. end 
  959.  
  960. -- Called when a car is made a lead car. Causes that car to take over the path 
  961. -- of the old lead car. 
  962. -- 
  963. -- car_index: Index of the new lead car. 
  964. -- resuming_path_index: How far along the lead car was on its current path. 
  965. -- 
  966. function ss03_new_lead_car_resume_pathfind( car_index, resuming_path_index ) 
  967.    -- We're going to resume from this index. We need this recorded so that we know 
  968.    -- where to resume from  
  969.    Lead_car_resumed_from_index = resuming_path_index 
  970.  
  971.    local new_lead_car = ESCAPEE_VEHICLES[car_index] 
  972.  
  973.    -- We haven't yet resumed 
  974.    local resumed = false 
  975.  
  976.    -- If the lead car was on the start path, resume from there 
  977.    if ( Lead_car_current_path_segment == ESCAPEE_START_PATH ) then 
  978.       mission_debug( "Resuming from start, index "..resuming_path_index, 15 ) 
  979.  
  980.       resumed = true 
  981.  
  982.       -- Go the rest of the way along the first path 
  983.       vehicle_navmesh_pathfind_to_starting_from( new_lead_car, resuming_path_index, ESCAPEE_START_PATH, false, false ) 
  984.  
  985.       if ( vehicle_is_destroyed( new_lead_car )  ) then 
  986.          return 
  987.       end 
  988.       -- Now that the lead car has finished the rest of the old lead car's path, if it dies we'll get the correct index, so no need for this anymore 
  989.       Lead_car_resumed_from_index = 0 
  990.    end 
  991.  
  992.    -- If we've resumed, do the obvious from here on 
  993.    if ( resumed ) then 
  994.       for index, path_name in pairs( ESCAPEE_PATHS ) do 
  995.          if ( vehicle_is_destroyed( new_lead_car ) ) then 
  996.             return; 
  997.          end 
  998.          Lead_car_current_path_segment = path_name 
  999.          -- use_navmesh, stop_at_goal 
  1000.          vehicle_pathfind_to( new_lead_car, path_name, true, false ) 
  1001.       end 
  1002.    -- If we're resuming, resume 
  1003.    elseif ( ss03_path_is_in_table( Lead_car_current_path_segment, ESCAPEE_PATHS ) ) then 
  1004.       mission_debug( "Resuming from escapee paths, index "..resuming_path_index, 15 ) 
  1005.  
  1006.       resumed = true 
  1007.  
  1008.       local path_index = ss03_get_paths_index( Lead_car_current_path_segment, ESCAPEE_PATHS ) 
  1009.  
  1010.       mission_debug( "Path index is "..path_index..", resume index is "..resuming_path_index..", lead path is "..Lead_car_current_path_segment..", indexed is "..ESCAPEE_PATHS[path_index], 20 ) 
  1011.  
  1012.       -- Go the rest of the way along this path 
  1013.       vehicle_navmesh_pathfind_to_starting_from( new_lead_car, resuming_path_index, ESCAPEE_PATHS[path_index], false, false ) 
  1014.       if ( vehicle_is_destroyed( new_lead_car )  ) then 
  1015.          return 
  1016.       end 
  1017.       -- Now that the lead car has finished the rest of the old lead car's path, if it dies we'll get the correct index, so no need for this anymore 
  1018.       Lead_car_resumed_from_index = 0 
  1019.  
  1020.       for i = path_index + 1, sizeof_table( ESCAPEE_PATHS ) do 
  1021.          if ( vehicle_is_destroyed( new_lead_car ) ) then 
  1022.             return; 
  1023.          end 
  1024.          Lead_car_current_path_segment = ESCAPEE_PATHS[i] 
  1025.          vehicle_pathfind_to( new_lead_car, Lead_car_current_path_segment, true, false ) 
  1026.       end 
  1027.    end 
  1028.  
  1029.    -- Resumed - do the obvious 
  1030.    if ( resumed ) then 
  1031.       for i = Lead_car_loop_index, NUM_LOOPS_BEFORE_STOP do 
  1032.          if ( vehicle_is_destroyed( new_lead_car ) ) then 
  1033.             return; 
  1034.          end 
  1035.  
  1036.          Lead_car_loop_index = i 
  1037.          for index, path_name in pairs( ESCAPEE_LOOPING_PATHS ) do 
  1038.             if ( vehicle_is_destroyed( new_lead_car ) ) then 
  1039.                return; 
  1040.             end 
  1041.  
  1042.             Lead_car_current_path_segment = path_name 
  1043.             -- use_navmesh, stop_at_goal, force_path 
  1044.             vehicle_pathfind_to( ESCAPEE_VEHICLES[car_index], path_name, true, false ) 
  1045.          end 
  1046.          delay( 0 ) 
  1047.       end 
  1048.    -- Finish off the current loop and then proceed to the next one 
  1049.    elseif ( ss03_path_is_in_table( Lead_car_current_path_segment, ESCAPEE_LOOPING_PATHS ) ) then 
  1050.       mission_debug( "Resuming from escapee looping paths, index "..resuming_path_index, 15 ) 
  1051.  
  1052.       resumed = true 
  1053.  
  1054.       local path_index = ss03_get_paths_index( Lead_car_current_path_segment, ESCAPEE_LOOPING_PATHS ) 
  1055.  
  1056.       -- Finish up the current path 
  1057.       vehicle_navmesh_pathfind_to_starting_from( new_lead_car, resuming_path_index, ESCAPEE_LOOPING_PATHS[path_index], false, false ) 
  1058.       if ( vehicle_is_destroyed( new_lead_car )  ) then 
  1059.          return 
  1060.       end 
  1061.       Lead_car_resumed_from_index = 0 
  1062.  
  1063.       -- If it's the last path in the list, then increment the loop count 
  1064.       if ( path_index == sizeof_table( ESCAPEE_LOOPING_PATHS ) ) then 
  1065.          if ( vehicle_is_destroyed( new_lead_car ) ) then 
  1066.             return; 
  1067.          end 
  1068.  
  1069.          Lead_car_loop_index = Lead_car_loop_index + 1 
  1070.       -- Otherwise, finish this loop 
  1071.       else 
  1072.          for index = path_index, sizeof_table( ESCAPEE_LOOPING_PATHS ) do 
  1073.             if ( vehicle_is_destroyed( new_lead_car ) ) then 
  1074.                return; 
  1075.             end 
  1076.             Lead_car_current_path_segment = ESCAPEE_LOOPING_PATHS[index] 
  1077.             -- use_navmesh, stop_at_goal, force_path 
  1078.             vehicle_pathfind_to( ESCAPEE_VEHICLES[car_index], Lead_car_current_path_segment, true, false ) 
  1079.          end 
  1080.  
  1081.          if ( vehicle_is_destroyed( new_lead_car ) ) then 
  1082.             return; 
  1083.          end 
  1084.          Lead_car_loop_index = Lead_car_loop_index + 1 
  1085.       end 
  1086.  
  1087.       -- Start looping again from the loop index you resumed at 
  1088.       for i = Lead_car_loop_index, NUM_LOOPS_BEFORE_STOP do 
  1089.          if ( vehicle_is_destroyed( new_lead_car ) ) then 
  1090.             return; 
  1091.          end 
  1092.  
  1093.          Lead_car_loop_index = i 
  1094.          for index, path_name in pairs( ESCAPEE_LOOPING_PATHS ) do 
  1095.             if ( vehicle_is_destroyed( new_lead_car ) ) then 
  1096.                return; 
  1097.             end 
  1098.  
  1099.             Lead_car_current_path_segment = path_name 
  1100.             -- use_navmesh, stop_at_goal, force_path 
  1101.             vehicle_pathfind_to( ESCAPEE_VEHICLES[car_index], path_name, true, false ) 
  1102.          end 
  1103.          delay( 0 ) 
  1104.       end 
  1105.    end 
  1106.  
  1107.    ss03_do_final_pathing() 
  1108. end 
  1109.  
  1110. function ss03_lead_car_start_pathfind( car_index ) 
  1111.    -- Do any necessary setup on the car 
  1112.    ss03_setup_car_for_pathfinding( car_index ) 
  1113.  
  1114.    Lead_car_current_path_segment = ESCAPEE_START_PATH 
  1115.    -- use_navmesh, stop_at_goal 
  1116.    vehicle_pathfind_to( ESCAPEE_VEHICLES[car_index], ESCAPEE_START_PATH, true, false ) 
  1117.  
  1118.    -- Now, start on the main path 
  1119.    for index, path_name in pairs( ESCAPEE_PATHS ) do 
  1120.       if ( vehicle_is_destroyed( ESCAPEE_VEHICLES[car_index] ) ) then 
  1121.          return; 
  1122.       end 
  1123.       Lead_car_current_path_segment = path_name 
  1124.       -- use_navmesh, stop_at_goal 
  1125.       vehicle_pathfind_to( ESCAPEE_VEHICLES[car_index], path_name, true, false ) 
  1126.    end 
  1127.  
  1128.    -- Do the looping path 
  1129.    for i = 1, NUM_LOOPS_BEFORE_STOP do 
  1130.       if ( vehicle_is_destroyed( ESCAPEE_VEHICLES[car_index] ) ) then 
  1131.          return; 
  1132.       end 
  1133.       Lead_car_loop_index = i 
  1134.       for index, path_name in pairs( ESCAPEE_LOOPING_PATHS ) do 
  1135.          if ( vehicle_is_destroyed( ESCAPEE_VEHICLES[car_index] ) ) then 
  1136.             return; 
  1137.          end 
  1138.          Lead_car_current_path_segment = path_name 
  1139.          -- use_navmesh, stop_at_goal, force_path 
  1140.          vehicle_pathfind_to( ESCAPEE_VEHICLES[car_index], path_name, true, false ) 
  1141.       end 
  1142.       delay( 0 ) 
  1143.    end 
  1144.  
  1145.    ss03_do_final_pathing() 
  1146. end 
  1147.  
  1148. function ss03_car_final_pathing( vehicle_name, vehicle_index ) 
  1149.    -- Set all the cars to the same speed so they don't collide 
  1150.    vehicle_max_speed( vehicle_name, CAR_FINAL_PATH_SPEED_MPS ) 
  1151.    vehicle_speed_override( vehicle_name, CAR_FINAL_PATH_SPEED_MPS )    
  1152.  
  1153.    -- Stop at the gas station 
  1154.    -- use_navmesh, stop_at_goal 
  1155.    vehicle_pathfind_to( vehicle_name, ESCAPEE_TO_GAS_STATION_PATHS_PATH, true, false ) 
  1156.    -- use_navmesh, stop_at_goal 
  1157.    vehicle_pathfind_to( vehicle_name, ESCAPEE_GAS_STATION_PATHS[vehicle_index], true, true ) 
  1158.  
  1159. 	-- If the vehicle stopped and the people got out when they weren't at a good location to do so, 
  1160. 	-- the player should win. 
  1161. 	if ( get_dist_vehicle_to_nav( vehicle_name, MP.."Near_Dropoff_Points" ) > 13.1 ) then 
  1162. 		local car_followed = "true" 
  1163. 		if ( Debug_car_followed == false ) then 
  1164. 			car_followed = "false" 
  1165. 		end 
  1166.  
  1167. 		script_assert( false, vehicle_name.." failed path. Car followed = "..car_followed..". Please get Mark Gabby if you hit this. Thanks!" ) 
  1168. 		vehicle_detonate( vehicle_name ) 
  1169. 		return 
  1170. 	end 
  1171.  
  1172.    vehicle_suppress_npc_exit( vehicle_name, false ) 
  1173.    for index, member_name in pairs( ESCAPEES[vehicle_index] ) do 
  1174.       if ( character_is_dead( member_name ) == false ) then 
  1175.          thread_new( "ss03_vehicle_member_exit_car", member_name ) 
  1176.       end 
  1177.    end 
  1178.    -- This vehicle no longer counts as a required kill 
  1179.    Current_lieutenant_count = Current_lieutenant_count - 1 
  1180.    marker_remove_vehicle( vehicle_name ) 
  1181.    on_vehicle_destroyed( "", vehicle_name ) 
  1182.    ss03_update_objective_text_including_individuals() 
  1183. end 
  1184.  
  1185. -- Handles the gas station stop for all surviving vehicles 
  1186. -- 
  1187. function ss03_do_final_pathing() 
  1188.    for vehicle_index, vehicle_name in pairs( ESCAPEE_VEHICLES ) do 
  1189.       if ( vehicle_is_destroyed( vehicle_name ) == false ) then 
  1190.          thread_new( "ss03_car_final_pathing", vehicle_name, vehicle_index ) 
  1191.       end 
  1192.    end 
  1193. end 
  1194.  
  1195. function ss03_update_objective_text_including_individuals() 
  1196.    objective_text( 0, HT_X_OF_Y_LIEUTENANTS, Num_cars_killed + Num_members_killed, Current_lieutenant_count ) 
  1197. end 
  1198.  
  1199. function ss03_vehicle_member_exit_car( member_name ) 
  1200.    Current_lieutenant_count = Current_lieutenant_count + 1 
  1201.    turn_vulnerable( member_name ) 
  1202.    on_death( "ss03_member_died", member_name ) 
  1203.    ss03_update_objective_text_including_individuals() 
  1204.  
  1205.    marker_add_npc( member_name, MINIMAP_ICON_KILL, INGAME_EFFECT_KILL, SYNC_ALL ) 
  1206.    npc_leash_to_nav( member_name, GAS_STATION_VEHICLE_LOCATION, 20 ) 
  1207.    vehicle_exit( member_name ) 
  1208.    attack_closest_player( member_name ) 
  1209. end 
  1210.  
  1211. function ss03_member_died( member_name ) 
  1212.    marker_remove_npc( member_name ) 
  1213.    Num_members_killed = Num_members_killed + 1 
  1214.    ss03_update_objective_text_including_individuals() 
  1215.    if ( ss03_all_current_targets_killed() ) then 
  1216.       mission_end_success( MISSION_NAME, CT_OUTRO ) 
  1217.    end 
  1218. end 
  1219.  
  1220. -- Adds a car to the convoy. Sets up a car to follow the 
  1221. -- car next in front of this car that is still alive. 
  1222. -- 
  1223. -- already_following: (default false) True if this car was already following. 
  1224. -- 
  1225. function ss03_add_car_to_convoy( car_index, already_following ) 
  1226.    if ( already_following == nil ) then 
  1227.       already_following = false 
  1228.    end 
  1229.  
  1230.    -- Only do setup on this car if it's being freshly added to the chase 
  1231.    if ( already_following == false ) then 
  1232.       ss03_setup_car_for_pathfinding( car_index ) 
  1233.       vehicle_max_speed( ESCAPEE_VEHICLES[car_index], CAR_CHASE_SPEED_MPS ) 
  1234.       vehicle_speed_override( ESCAPEE_VEHICLES[car_index], CAR_CHASE_SPEED_MPS ) 
  1235.       on_vehicle_destroyed( "ss03_following_car_destroyed", ESCAPEE_VEHICLES[car_index] ) 
  1236.    end 
  1237.  
  1238.    -- Find the first living car with a smaller index, if it exists, and follow that car 
  1239.    for i = car_index - 1, 1, -1 do 
  1240.       if ( vehicle_is_destroyed( ESCAPEE_VEHICLES[i] ) == false ) then 
  1241.          vehicle_chase( ESCAPEE_VEHICLES[car_index], ESCAPEES[i][1], false, false, false, true ) 
  1242.          return 
  1243.       end 
  1244.    end 
  1245.  
  1246.    script_assert( false, "Called 'add_car_to_convoy' index "..car_index..", vehicle: "..ESCAPEE_VEHICLES[car_index].." when there were no living cars in front of said car." ) 
  1247. end 
  1248.  
  1249. function ss03_setup_car_for_pathfinding( car_index ) 
  1250.    for member_index, member_name in pairs( ESCAPEES[car_index] ) do 
  1251.       -- ( attacker, yield ) 
  1252.       attack_closest_player( member_name, false ) 
  1253.    end 
  1254.  
  1255.    marker_add_vehicle( ESCAPEE_VEHICLES[car_index], MINIMAP_ICON_KILL, INGAME_EFFECT_VEHICLE_KILL, SYNC_ALL ) 
  1256.    vehicle_set_crazy( ESCAPEE_VEHICLES[car_index], true ) 
  1257.    vehicle_infinite_mass( ESCAPEE_VEHICLES[car_index], true ) 
  1258. end 
  1259.  
  1260. -- Called when the helicopter is damaged. Updates the health bar. 
  1261. -- 
  1262. function ss03_helicopter_damaged() 
  1263.    local helicopter_hit_points = get_current_hit_points( HELICOPTER_NAME ) 
  1264.    hud_bar_set_value(0, helicopter_hit_points, SYNC_ALL ) 
  1265. end 
  1266.  
  1267. function ss03_helicopter_destroyed() 
  1268.    mission_end_failure( MISSION_NAME, HT_HELICOPTER_DESTROYED ) 
  1269. end 
  1270.  
  1271. function ss03_left_helicopter() 
  1272.    mission_end_failure( MISSION_NAME, HT_HELICOPTER_DESTROYED ) 
  1273. end 
  1274.  
  1275. function ss03_helicopter_circle() 
  1276.    local path_index = 1 
  1277.    while( Num_targets_destroyed < TOTAL_NUM_TARGETS ) do 
  1278.       -- Pathfind around the path, segment by segment 
  1279.       for segment_index, segment_name in pairs( HELI_CIRCULAR_RAIL_PATHS[path_index] ) do 
  1280.          helicopter_fly_to( HELICOPTER_NAME, HELI_CIRCLE_SPEED_MPS, segment_name ) 
  1281.          delay( HELI_CIRCULAR_RAIL_PATH_DELAYS_SECONDS[path_index][segment_index] ) 
  1282.          if ( Num_targets_destroyed == TOTAL_NUM_TARGETS ) then 
  1283.             break 
  1284.          end 
  1285.       end 
  1286.       path_index = path_index + 1 
  1287.       if ( path_index > NUM_HELI_CIRCULAR_RAIL_PATHS ) then 
  1288.          path_index = 1 
  1289.       end 
  1290.       delay( 0 ) 
  1291.    end 
  1292. end 
  1293.  
  1294. function ss03_fleeing_lieutenants_dialog() 
  1295.    ss03_2d_conversation( FLEEING_LIEUTENANTS_DIALOG_STREAM ) 
  1296. end 
  1297.  
  1298. function ss03_helicopter_end_circle() 
  1299.    -- Kill the Samedi with rocket launchers so that they don't kill the player when 
  1300.    -- he can't fight back 
  1301.    for index, name in pairs( ROCKET_LAUNCHER_GUYS ) do 
  1302.       if ( character_exists( name ) ) then 
  1303.          if ( character_is_dead( name ) == false ) then 
  1304.             on_death( "", name ) 
  1305.             character_kill( name ) 
  1306.          end 
  1307.       end 
  1308.    end 
  1309.  
  1310.    helicopter_fly_to( HELICOPTER_NAME, HELI_CIRCLE_SPEED_MPS, TO_HOLDING_POSITION ) 
  1311.    thread_new( "ss03_fleeing_lieutenants_dialog" ) 
  1312.    helicopter_fly_to( HELICOPTER_NAME, HELI_CIRCLE_SPEED_MPS, HELI_HOLDING_POSITION ) 
  1313.    -- Turn off the haze triggers now that we've flown through this part of the mission 
  1314.    for index, trigger_name in pairs( HAZE_TRIGGERS ) do 
  1315.       -- Don't disable the last trigger - we're inside it right now 
  1316.       if ( index ~= 4 ) then 
  1317.          trigger_enable( trigger_name, false ) 
  1318.       end 
  1319.    end 
  1320.    Heli_at_holding_position = true 
  1321. end 
  1322.  
  1323. function ss03_target_mover_destroyed( mover_name ) 
  1324.    marker_remove_mover( mover_name, SYNC_ALL ) 
  1325.    ss03_target_destroyed( mover_name ) 
  1326. end 
  1327.  
  1328. function ss03_target_vehicle_destroyed( vehicle_name ) 
  1329.    marker_remove_vehicle( vehicle_name, SYNC_ALL ) 
  1330.    if ( vehicle_name == SEWAGE_TRUCK_NAME ) then 
  1331.       -- Hide the barn 
  1332.       -- Start the huge barn explosion 
  1333.       --delay( BEFORE_BARN_EXPLOSION_DELAY_SECONDS ) 
  1334.  
  1335.       mesh_mover_hide( BARN_ROOF_NAME ) 
  1336.       effect_play( BARN_ROOF_EXPLOSION, BARN_ROOF_EXPLOSION_LOCATION ) 
  1337.  
  1338.       audio_play( TOBIAS_ON_BARN_DESTROYED, "voice", false ) 
  1339.    end 
  1340.    ss03_target_destroyed( vehicle_name ) 
  1341. end 
  1342.  
  1343. -- Called when the player's helicopter hits a haze trigger. 
  1344. -- Meant to simulate the helicopter flying into drug fumes and give the 
  1345. -- player a drug haze effect. 
  1346. -- Each trigger causes the global haze to increase a set delta amount. 
  1347. -- 
  1348. function ss03_entered_haze() 
  1349.    mission_debug( "entered haze" ) 
  1350.    -- Ramp up the haze strength 
  1351.    -- Find out how long we take between updates when ramping up 
  1352.    local ramp_up_update_seconds = HAZE_CLOUD_RAMP_UP_SECONDS / HAZE_CLOUD_RAMP_INCREMENTS 
  1353.    -- Find out how much we bump up the haze strength between updates 
  1354.    local ramp_up_amount_per_update = HAZE_CLOUD_STRENGTH / HAZE_CLOUD_RAMP_INCREMENTS 
  1355.    for i = 1, HAZE_CLOUD_RAMP_INCREMENTS do 
  1356.       delay( ramp_up_update_seconds ) 
  1357.       Current_haze_strength = Current_haze_strength + ramp_up_amount_per_update 
  1358.       local strength_to_set = Current_haze_strength 
  1359.       if ( Current_haze_strength > 1 ) then 
  1360.          strength_to_set = 1 
  1361.       end 
  1362.       drug_effect_set_override_values( 0, strength_to_set, SYNC_ALL ) 
  1363.    end 
  1364.    mission_debug( "Ramp Up: Current_haze_strength = "..Current_haze_strength ) 
  1365.  
  1366. end 
  1367.  
  1368. -- Called when the player's helicopter leaves a haze trigger. 
  1369. -- Meant to simulate the helicopter leaving the drug fumes and the player recovering. 
  1370. -- Each trigger causes the global haze to decrease a set delta amount. 
  1371. -- 
  1372. function ss03_left_haze() 
  1373.    -- Ramp down the haze strength 
  1374.    -- Find out how long we take between updates when ramping down 
  1375.    local ramp_down_update_seconds = HAZE_CLOUD_RAMP_DOWN_SECONDS / HAZE_CLOUD_RAMP_INCREMENTS 
  1376.    -- Find out how much we bump down the haze strength between updates 
  1377.    local ramp_down_amount_per_update = HAZE_CLOUD_STRENGTH / HAZE_CLOUD_RAMP_INCREMENTS 
  1378.  
  1379.    for i = 1, HAZE_CLOUD_RAMP_INCREMENTS do 
  1380.       delay( ramp_down_update_seconds ) 
  1381.       Current_haze_strength = Current_haze_strength - ramp_down_amount_per_update 
  1382.       local strength_to_set = Current_haze_strength 
  1383.       if ( Current_haze_strength > 1 ) then 
  1384.          strength_to_set = 1 
  1385.       end 
  1386.       drug_effect_set_override_values( 0, strength_to_set, SYNC_ALL ) 
  1387.    end 
  1388.    mission_debug( "Ramp Down: Current_haze_strength = "..Current_haze_strength ) 
  1389. end 
  1390.  
  1391. -- This function simulates the time it takes for the haze fire effect to rise 
  1392. -- high enough to drug the player when he passes by. 
  1393. -- 
  1394. -- haze_trigger_index: The index of the haze trigger to enable. 
  1395. --                     Different triggers are linked to different chem depots. 
  1396. -- 
  1397. function ss03_delay_before_enable_haze_trigger( haze_trigger_index ) 
  1398.    delay( DRUG_FIRE_TIME_TO_START_HAZE_EFFECT_SECONDS ) 
  1399.    trigger_enable( HAZE_TRIGGERS[haze_trigger_index], true ) 
  1400.    on_trigger( "ss03_entered_haze", HAZE_TRIGGERS[haze_trigger_index] ) 
  1401.    on_trigger_exit( "ss03_left_haze", HAZE_TRIGGERS[haze_trigger_index] ) 
  1402. end 
  1403.  
  1404. function ss03_ignite_cluster( cluster ) 
  1405.    for index, point in pairs( cluster ) do 
  1406.       effect_play( CHEM_DEPOT_CROP_FIRE, point, true ) 
  1407.    end 
  1408. end 
  1409.  
  1410. function ss03_do_fire_spreading( spread_cluster ) 
  1411.    -- Go through each cluster of navpoints in this  
  1412.    -- part of the spread and ignite them 
  1413.    for index, cluster in pairs( spread_cluster ) do 
  1414.       delay( 10.0 ) 
  1415.       ss03_ignite_cluster( cluster ) 
  1416.    end 
  1417. end 
  1418.  
  1419. function ss03_target_destroyed( target_name ) 
  1420.    Num_targets_destroyed = Num_targets_destroyed + 1 
  1421.  
  1422.    -- Don't play the "cheer" line on the sewage truck, because Tobias cheers when the barn 
  1423.    -- goes up. 
  1424.    if ( target_name ~= SEWAGE_TRUCK_NAME ) then 
  1425.       audio_play_persona_line( TOBIAS_NAME, TOBIAS_CHEER_ON_DESTROYED_PERSONA_SITUATION ) 
  1426.    end 
  1427.  
  1428.    local delay_time_seconds = DESTROYED_ALL_TARGETS_STOP_CIRCLING_DELAY_SECONDS 
  1429.  
  1430.    if ( target_name == CHEMICAL_DEPOTS[1] ) then 
  1431.       mission_help_table( HT_CHEM_DEPOT_DESTROYED ) 
  1432.  
  1433.       -- Play the chemical depot's fire effect 
  1434.       effect_play( CHEM_DEPOT_FIRE, CHEM_DEPOT_FIRE_LOCATIONS[1], true ) 
  1435.       -- Do the crop fire effects 
  1436.       thread_new( "ss03_do_fire_spreading", CROP_FIRE_SPREAD_SEQUENCES[1] ) 
  1437.  
  1438.       -- Enable the "drug haze" trigger for this location 
  1439.       thread_new( "ss03_delay_before_enable_haze_trigger", 1 ) 
  1440.    elseif ( target_name == CHEMICAL_DEPOTS[2] ) then 
  1441.       mission_help_table( HT_CHEM_DEPOT_DESTROYED ) 
  1442.  
  1443.       -- Play the chemical depot's fire effect 
  1444.       effect_play( CHEM_DEPOT_FIRE, CHEM_DEPOT_FIRE_LOCATIONS[2], true ) 
  1445.       -- Do the crop fire effects 
  1446.       thread_new( "ss03_do_fire_spreading", CROP_FIRE_SPREAD_SEQUENCES[2] ) 
  1447.  
  1448.       -- Enable the "drug haze" trigger for this location 
  1449.       thread_new( "ss03_delay_before_enable_haze_trigger", 2 ) 
  1450.    elseif ( target_name == CHEMICAL_DEPOTS[3] ) then 
  1451.       mission_help_table( HT_CHEM_DEPOT_DESTROYED ) 
  1452.  
  1453.       -- Play the chemical depot's fire effect 
  1454.       effect_play( CHEM_DEPOT_FIRE, CHEM_DEPOT_FIRE_LOCATIONS[3], true ) 
  1455.       -- Do the crop fire effects 
  1456.       thread_new( "ss03_do_fire_spreading", CROP_FIRE_SPREAD_SEQUENCES[3] ) 
  1457.  
  1458.       -- Enable the "drug haze" trigger for this location 
  1459.       thread_new( "ss03_delay_before_enable_haze_trigger", 3 ) 
  1460.       -- This trigger is above the flames. It's hit when the helicopter flies to the 
  1461.       -- holding position. 
  1462.       thread_new( "ss03_delay_before_enable_haze_trigger", 4 ) 
  1463.    elseif ( target_name == CHEMICAL_TANK ) then 
  1464.       mission_help_table( HT_CHEM_TANK_DESTROYED ) 
  1465.    elseif ( target_name == SEWAGE_TRUCK_NAME ) then 
  1466.       delay_time_seconds = delay_time_seconds + DESTROYED_BARN_LAST_EXTRA_TIME_SECONDS 
  1467.       mission_help_table( HT_FERTILIZER_TRUCK_DESTROYED ) 
  1468.    elseif ( target_name == FUEL_TRUCK_TANK_NAME ) then 
  1469.       mission_help_table( HT_FUEL_TRUCK_DESTROYED ) 
  1470.    end 
  1471.  
  1472.    objective_text( 0, HT_X_OF_Y_TARGETS, Num_targets_destroyed, TOTAL_NUM_TARGETS ) 
  1473.  
  1474.    if ( Num_targets_destroyed >= TOTAL_NUM_TARGETS ) then 
  1475.       delay( delay_time_seconds ) 
  1476.       thread_new( "ss03_switch_state", MS_FARM_DESTROYED ) 
  1477.    end 
  1478.    if ( Num_targets_destroyed == TOTAL_NUM_TARGETS ) then 
  1479.       ss03_helicopter_end_circle() 
  1480.    end 
  1481. end 
  1482.  
  1483. function ss03_cleanup() 
  1484.    spawning_pedestrians( true ) 
  1485.    on_vehicle_exit( "", HELICOPTER_NAME ) 
  1486.  
  1487.    on_weapon_fired( "", LOCAL_PLAYER ) 
  1488.    if ( coop_is_active() ) then 
  1489.       on_weapon_fired( "", REMOTE_PLAYER ) 
  1490.    end 
  1491.    --mesh_mover_show( CAR_HUSK ) 
  1492.    -- Cleanup mission here 
  1493.    group_destroy( HELICOPTER_GROUP ) 
  1494.    teleport( LOCAL_PLAYER, MISSION_START_LOCATION, true ) 
  1495.    if ( coop_is_active() ) then 
  1496.       teleport( REMOTE_PLAYER, REMOTE_PLAYER_START, true ) 
  1497.    end 
  1498.  
  1499.    notoriety_set_min( ENEMY_GANG, 0 ) 
  1500.    inv_weapon_remove_temporary( LOCAL_PLAYER, SAW_NAME ) 
  1501.    if ( coop_is_active() ) then 
  1502.       inv_weapon_remove_temporary( REMOTE_PLAYER, SAW_NAME )  
  1503.    end 
  1504.  
  1505.    persona_override_group_stop( SAMEDI_PERSONAS, POT_SITUATIONS[POT_ATTACK] ) 
  1506.  
  1507.    set_player_can_enter_exit_vehicles( LOCAL_PLAYER, true ) 
  1508.    if ( coop_is_active() ) then 
  1509.       set_player_can_enter_exit_vehicles( REMOTE_PLAYER, true ) 
  1510.    end 
  1511.    inv_weapon_enable_or_disable_all_slots( true ) 
  1512.    fade_in( 0 ) 
  1513.    drug_enable_disable_effect_override( false, SYNC_ALL ) 
  1514.  
  1515.    for index, name in pairs( BILLBOARD_PARTS ) do 
  1516.       mesh_mover_show( name ) 
  1517.    end 
  1518.  
  1519.    audio_suppress_ambient_player_lines( false ) 
  1520. end 
  1521.  
  1522. function ss03_success() 
  1523. 	-- Called when the mission has ended with success 
  1524. end 
  1525.