sr2lua/ss02.lua

  1. -- ss02.lua 
  2. -- SR2 mission script 
  3. -- 3/28/07 
  4.  
  5. -- Mission help table text tags 
  6.    HT_DISPLAY_NAME = "ss02_display_name" 
  7.    HT_DOOR_LOCKED = "ss02_door_locked" 
  8.    HT_FIND_A_BOAT = "ss02_find_a_boat" 
  9.    HT_RUNNING_OUT_OF_TIME = "ss02_running_out_of_time" 
  10.    HT_ALMOST_OUT_OF_TIME = "ss02_almost_out_of_time" 
  11.    HT_GET_CLEAR = "ss02_get_clear" 
  12.    HT_GET_OUT_OF_PRISON = "ss02_get_out_of_prison" 
  13.    HT_GET_TO_PRISON = "ss02_get_to_prison" 
  14.    HT_GET_INSIDE_PRISON = "ss02_get_inside_prison" 
  15.    HT_GET_TO_CELLBLOCKS = "ss02_get_to_cellblocks" 
  16.    HT_FIND_DRUG_EXPERT = "ss02_find_drug_expert" 
  17.    HT_PRESS_TO_PLANT_BOMB = "ss02_press_to_plant_bomb" 
  18.    HT_LAURA_DIED = "ss02_laura_died" 
  19.    HT_LAURA_ABANDONDED = "ss02_laura_abandoned" 
  20.    HT_PLANT_C4_ON_TURBINE = "ss02_plant_c4" 
  21.    HT_HAVE_BUDDY_PLANT_BOMB = "ss02_have_buddy_plant_bomb" 
  22.    HT_DESTROY_GRATE = "ss02_destroy_grate" 
  23.    HT_FAILED_TO_PLANT_BOMB_IN_TIME = "ss02_failed_to_plant_bomb" 
  24.    HT_ESCAPE_PRISON_AND_POLICE = "ss02_escape_prison_and_police" 
  25.    HT_LOCATE_POWER_GENERATOR = "ss02_locate_power_generator" 
  26.  
  27. -- Mission states 
  28.    MS_GET_TO_BOAT = 1 
  29.    MS_CHECKPOINT = 2 
  30.    MS_GET_TO_PRISON = 3 
  31.    MS_PLANT_C4 = 4 
  32.    MS_C4_PLANTED = 5 
  33.    MS_PRISON_RIOT = 6 
  34.    MS_ESCAPE_FROM_PRISON = 7 
  35.  
  36. -- Groups, NPCs, vehicles, navpoints, and other names 
  37.    -- Mission constant names 
  38.    MISSION_NAME = "ss02" 
  39.    MP = MISSION_NAME.."_$" 
  40.    PRISON_DEFENDER_TEAM = "Police" 
  41.    PRISON_DISTRICT_NAME = "Prison" 
  42.    DETONATED_C4_CHECKPOINT = "Detonated C4" 
  43.  
  44.    -- Groups 
  45.    STARTER_WATERCRAFT_GROUP_NAME = MP.."Starter_Watercraft" 
  46.  
  47.    GENERATOR_GUARD_GROUP_NAME = MP.."Generator_Patrol_Guard" 
  48.  
  49.    OUTSIDE_GUARDS_GROUP_NAME = MP.."Outside_Guards" 
  50.    ENTRANCE_GUARDS_GROUP_NAME = MP.."Entrance_Guards" 
  51.    CAFETERIA_GUARDS_GROUP_NAME = MP.."Cafeteria_Guards" 
  52.    CAFETERIA_GUARDS_RESPAWN_GROUP_NAME = MP.."Cafeteria_Guard_Respawn" 
  53.    CAFETERIA_INMATES_GROUP_NAMES = { MP.."Cafeteria_Inmates01", MP.."Cafeteria_Inmates02", 
  54.                                      MP.."Cafeteria_Inmates03"--[[, MP.."Cafeteria_Inmates04", 
  55.                                      MP.."Cafeteria_Inmates05"]] } 
  56.    STAIRWELL_GUARDS_GROUP_NAME = MP.."Stairwell_Guards" 
  57.    STAIRWELL_INMATES_GROUP_NAME = MP.."Stairwell_Prisoners" 
  58.    CATWALK_GUARDS_GROUP_NAME = MP.."Catwalk_Guards" 
  59.    LAURA_GROUP_NAME = MP.."Laura" 
  60.    ESCAPE_HELICOPTERS_GROUP_NAME = MP.."Escape_Helicopters" 
  61.  
  62.    AMBIENT_CHAOS_GROUP_NAME = MP.."Ambient_Chaos" 
  63.  
  64.    -- NPC names 
  65.    GENERATOR_GUARD_NAME = MP.."Generator_Patrol_Guard" 
  66.  
  67.    OUTSIDE_PRISON_WANDERING_GUARDS = { MP.."OG_01", MP.."OG_02" } 
  68.  
  69.    LAURA_NAME = MP.."Laura" 
  70.  
  71.    CAFETERIA_GUARD_NAMES = { MP.."Cafeteria_Guard1", MP.."Cafeteria_Guard2", 
  72.                              MP.."Cafeteria_Guard2", MP.."Cafeteria_Guard4", 
  73.                              MP.."Cafeteria_Guard5" } 
  74.  
  75.    CAFETERIA_GROUPS_INMATE_NAMES = { { MP.."CI1_M01", MP.."CI1_M02", MP.."CI1_M03", 
  76.                                        MP.."CI1_M04", MP.."CI1_M05", MP.."CI1_M06" }, 
  77.                                      { MP.."CI2_M01", MP.."CI2_M02", MP.."CI2_M03", 
  78.                                        MP.."CI2_M04", MP.."CI2_M05", MP.."CI2_M06" }, 
  79.                                      { MP.."CI3_M01", MP.."CI3_M02", MP.."CI3_M03", 
  80.                                        MP.."CI3_M04", MP.."CI3_M05", MP.."CI3_M06" }, 
  81.                                      --[[{ MP.."CI4_M01", MP.."CI4_M02", MP.."CI4_M03", 
  82.                                        MP.."CI4_M04", MP.."CI4_M05", MP.."CI4_M06" }, 
  83.                                      { MP.."CI5_M01", MP.."CI5_M02", MP.."CI5_M03", 
  84.                                        MP.."CI5_M04", MP.."CI5_M05", MP.."CI5_M06" }]] } 
  85.  
  86.    CAFETERIA_GUARD_RESPAWN_NAMES = { MP.."Guard_Respawn01", MP.."Guard_Respawn02" --[[, MP.."Guard_Respawn03"]] } 
  87.  
  88.    CAFETERIA_DISABLED_GUARDS = { CAFETERIA_GUARD_NAMES[4], CAFETERIA_GUARD_NAMES[5] } 
  89.  
  90.    STAIRWELL_GUARDS = { MP.."SG_01", MP.."SG_02", MP.."SG_03" } 
  91.    STAIRWELL_INMATES = { MP.."SW_Inmate_01", MP.."SW_Inmate_02", MP.."SW_Inmate_03" } 
  92.  
  93.    AMBIENT_CHAOS_GROUPS_MEMBERS = { { MP.."AC1_C1", MP.."AC1_P1", MP.."AC1_P2" }, 
  94.                                     { MP.."AC2_C1", MP.."AC2_P1", MP.."AC2_P2" }, 
  95.                                     { MP.."AC3_C1", MP.."AC3_P1", MP.."AC3_P2" } } 
  96.    AMBIENT_CHAOS_GROUP_COP_INDEX = 1 
  97.  
  98.    -- Vehicle names 
  99.    STARTER_WATERCRAFT_NAMES = { MP.."Starter_Watercraft01", MP.."Starter_Watercraft02", 
  100.                                 MP.."Starter_Watercraft03", MP.."Starter_Watercraft04" } 
  101.    MARKED_WATERCRAFT = STARTER_WATERCRAFT_NAMES[2] 
  102.  
  103.    HELIPAD_HELICOPTER = MP.."Chopper1" 
  104.  
  105.    ESCAPE_HELICOPTER_NAMES = { HELIPAD_HELICOPTER, MP.."Chopper2" } 
  106.  
  107.    -- Navpoints 
  108.    PRISON_COAL_TUNNELS_ENTRANCE_NAV = MP.."Prison_Coal_Tunnels_Entrance" 
  109.  
  110.    PATROL_POINTS = { MP.."Patrol_Point01", MP.."Patrol_Point02" } 
  111.  
  112.    EXPLOSION_SIDE_NAMES = { MP.."Explosion_Side1", MP.."Explosion_Side2" } 
  113.    GENERATOR_BOX_NAVPOINT_NAME = MP.."Generator_Box" 
  114.    PLANTING_BOMB_VIEW = MP.."Planting_Bomb_View" 
  115.  
  116.    MISSION_START = "mission_start_sr2_city_$ss02" 
  117.    REMOTE_PLAYER_START = MP.."Remote_Player_Start" 
  118.  
  119.    PRISON_ISLAND_LOCATION = MP.."Prison_Island_Location" 
  120.  
  121.    PLANT_C4_LOCATION = MP.."Plant_C4_Location" 
  122.  
  123.    OUTSIDE_ALARMS = { MP.."alarm1", MP.."alarm2", MP.."alarm3" } 
  124.    INSIDE_ALARMS = { MP.."alarm4", MP.."alarm5", MP.."alarm6",  
  125.                      MP.."alarm7", MP.."alarm8" } 
  126.  
  127.    LAURAS_HOUSE_REMOTE_PLAYER_TELEPORT = MP.."Lauras_House_Remote_Player" 
  128.  
  129.    CAFETERIA_PRISONER_LEASH_LOCATION = MP.."Cafeteria_Prisoner_Leash" 
  130.  
  131.    -- Triggers 
  132.    OPEN_DOOR_FROM_OUTSIDE_TRIGGER_NAME = MP.."Open_Door_from_Outside" 
  133.    PLANT_C4_TRIGGER = MP.."Plant_C4_Trigger" 
  134.    PLANT_C4_MESSAGE_TRIGGER = MP.."Plant_C4_Message" 
  135.    GENERATOR_ROOM_UNSAFE_ZONE_TRIGGER = MP.."Generator_Room" 
  136.  
  137.    PRISON_DOCK_TRIGGERS = { MP.."Prison_Dock01", MP.."Prison_Dock02" } 
  138.  
  139.    COAL_TUNNEL_THRESHOLD_TRIGGER = MP.."Entrance_Threshold" 
  140.    COAL_TUNNEL_OUTSIDE_TRIGGER = MP.."Entrance_Outside" 
  141.    COAL_TUNNEL_INSIDE_TRIGGER = MP.."Entrance_Inside" 
  142.  
  143.    PRISON_GATE_TRIGGER_NAME = MP.."Prison_Gate" 
  144.    MAIN_ENTRANCE_TRIGGER_NAME = MP.."Prison_Main_Entrance" 
  145.    CAFETERIA_ENTRANCE_TRIGGER_NAME = MP.."Cafeteria_Entrance" 
  146.    CELL_BLOCKS_ENTRANCE_TRIGGER_NAME = MP.."Cell_Blocks_Entrance" 
  147.    STAIRWELL_TRIGGER_NAME = MP.."Stairwell" 
  148.    SECOND_FLOOR_TRIGGER_NAME = MP.."Second_Floor_Trigger" 
  149.    THIRD_FLOOR_TRIGGER_NAME = MP.."Third_Floor_Trigger" 
  150.    LAURA_TRIGGER_NAME = MP.."Laura_Location" 
  151.    LAURAS_HOUSE_TRIGGER_NAME = MP.."Lauras_House" 
  152.    FLOOR_TRIGGER_NAMES = { nil, MP.."Floor2_Trigger", MP.."Floor3_Trigger" } 
  153.    GENERATOR_ROOM_ESCAPE_TRIGGER_NAME = MP.."Generator_Room_Escape" 
  154.  
  155.    CAFETERIA_SHOW_RESPAWNS_TRIGGER = MP.."Cafeteria_Show_Respawns_Trigger" 
  156.    WATCHING_GUARDS_ATTACK_TRIGGER = MP.."Watching_Guards_Attack_Trigger" 
  157.  
  158.    -- Parking Spawns 
  159.    HELICOPTER_PARKING_SPAWN = "parking_spots_$parking_343" 
  160.  
  161.    -- Movers 
  162.    PRISON_GRATE_NAME = MP.."Grate" 
  163.    PRISON_GRATE_BARRELS = { MP.."Barrel01", MP.."Barrel02" } 
  164.    GENERATOR_ROOM_EXIT_DOOR = MP.."Generator_Room_Exit" 
  165.    PRISON_ENTRANCE_DOORS = { MP.."Prison_Entrance1", MP.."Prison_Entrance2_Door1", MP.."Prison_Entrance2_Door2" } 
  166.    CAFETERIA_ENTRANCE_DOORS = { MP.."Cafeteria_Entrance_Door1", MP.."Cafeteria_Entrance_Door2" } 
  167.  
  168.    DOORS_TO_LOCK = { MP.."Door01", MP.."Door02", MP.."Door03", MP.."Door04", MP.."Door05", MP.."Door06",  
  169.                      MP.."Door07", MP.."Door08", MP.."Door09", MP.."Door10", MP.."Door11", MP.."Door12",  
  170.                      MP.."Door13", MP.."Door14", MP.."Door15", MP.."Door16", MP.."Door17", MP.."Door18",  
  171.                      MP.."Door19", MP.."Door20", MP.."Door21", MP.."Door22", MP.."Door23", MP.."Door24" } 
  172.  
  173.    LAURA_CELLBLOCK_DOORS = { MP.."Laura_Door_01", MP.."Laura_Door_02" } 
  174.  
  175.    -- Effects and animation states 
  176.    GENERATOR_BOX_SMOKE_EFFECT_NAME = "CarDamage-Smoke" 
  177.    SIDE_EXPLOSION_NAME = "Vehicle" 
  178.    C4_EXPLOSION_NAME = "Car Bomb Big" 
  179.    STATE_PLANT_C4 = "crouch plant bomb" 
  180.  
  181.    -- Cutscenes 
  182.    CT_INTRO = "ss02-01" 
  183.    CT_OUTRO = "ss02-02" 
  184.  
  185. -- Sound 
  186.    -- Persona overrides 
  187.    LAURA_PERSONA_OVERRIDES = { { "combat - congratulate player", "LAURA_SOS2_GRATSPLAYER" }, 
  188.                                { "combat - congratulate self", "LAURA_SOS2_GRATSSELF" }, 
  189.                                { "hostage - barters", "LAURA_SOS2_BARTER" }, 
  190.                                { "misc - respond to player taunt w/taunt", "LAURA_SOS2_TAUNT" }, 
  191.                                { "observe - praised by PC", "LAURA_SOS2_PRAISED" }, 
  192.                                { "observe - passenger when driver hits cars", "LAURA_SOS2_HITCAR" }, 
  193.                                { "observe - passenger when driver hits object", "LAURA_SOS2_HITOBJ" }, 
  194.                                { "observe - passenger when driver hits peds", "LAURA_SOS2_HITPED" }, 
  195.                                { "threat - alert (solo attack)", "LAURA_SOS2_ATTACK" }, 
  196.                                { "threat - damage received (firearm)", "LAURA_SOS2_TAKEDAM" }, 
  197.                                { "threat - damage received (melee)", "LAURA_SOS2_TAKEDAM" } } 
  198.  
  199.    -- Lines/Dialog Stream 
  200.    LAURA_SAVED_DIALOG_STREAM = { { "LAURA_SOS2_SEEPLAYER_1", LAURA_NAME, 0 }, 
  201.                                  { "PLAYER_SOS2_LAURA_L2", LOCAL_PLAYER, 0 }, 
  202.                                  { "LAURA_SOS2_SEEPLAYER_2", LAURA_NAME, 0 } } 
  203.    SHAUNDI_PLANT_BOMB_DIALOG_STREAM = { { "PLAYER_SOS2_PHONECALL_L1", LOCAL_PLAYER, 0 }, 
  204.                                         { "SOS2_PHONECALL_L2", nil, 0 }, 
  205.                                         { "PLAYER_SOS2_PHONECALL_L3", LOCAL_PLAYER, 0 }, 
  206.                                         { "SOS2_PHONECALL_L4", nil, 0 }, 
  207.                                         { "PLAYER_SOS2_PHONECALL_L5", LOCAL_PLAYER, 0 } 
  208.                                         } 
  209.  
  210.    PLANT_BOMB_LINE = "PLAYER_SOS2_PLANT_BOMB_01" 
  211.  
  212.    ESCAPED_FROM_PRISON_LINE = "LAURA_SOS2_ARRIVELAND_1" 
  213.    RETURN_TO_STILWATER_LINES = { "LAURA_SOS2_DRIVING_1", "LAURA_SOS2_DRIVING_2", "LAURA_SOS2_DRIVING_3", "LAURA_SOS2_DRIVING_4" } 
  214.  
  215.    -- Sound effects 
  216.    HELICOPTER_FLYBY_SOUND = "SFX_SS02_HELI_FLYBY_SLOW" 
  217.  
  218. -- Distances 
  219.    WANDERING_GUARDS_WANDER_RADIUS_METERS = 3.5 
  220.    FOLLOWER_WIN_DISTANCE_METERS = 2.0 
  221.    DISTANCE_FROM_PRISON_WIN_METERS = 420.0 
  222.    GENERATOR_ROOM_SAFE_ZONE_DIAMETER_METERS = 22 
  223.  
  224.    DISTANCE_FROM_PRISON_DIALOG_METERS = 618.0 
  225.    CAFETERIA_PRISONER_LEASH_DISTANCE_METERS = 10.4 
  226.  
  227. -- Percents and multipliers 
  228.  
  229. -- Time values 
  230.    FIND_A_BOAT_PROMPT_DELAY_SECONDS = 5.0 
  231.    CHECKPOINT_TIME_TO_PLANT_C4_MS = 60000 
  232.    TIME_TO_PLANT_C4_MS = 230000 
  233.    C4_POST_PLANT_DETONATION_TIME_MS = 10000 
  234.    PLANT_C4_TIME_SECONDS = 5.0 
  235.    DROP_C4_TIME_SECONDS = 2.0 
  236.    BETWEEN_LINES_DELAY_MIN_SECONDS = 10 
  237.    BETWEEN_LINES_DELAY_MAX_SECONDS = 20 
  238.    TIME_TO_DIE_SECONDS = 3.0 
  239.  
  240.    -- Delay times for the prompts for the bomb timer running low 
  241.    FIRST_BOMB_PROMPT_TIME_SECONDS = 170 
  242.    SECOND_BOMB_PROMPT_TIME_SECONDS = 30 
  243.  
  244.    PRISON_WINDOW_BLACKOUT_TIME_SECONDS = 10.0 
  245.    START_WINDOW_BLACKOUT_THRESHOLD = 1.0 
  246.    PRISON_WINDOW_NUM_UPDATES = 30 
  247.  
  248.    PW_BLACKOUT_TIME_INDEX = 1 
  249.    PW_BLACKOUT_THRESHOLD_INDEX = 2 
  250.  
  251.    PRISON_ZONE_BLACKOUT_SEQUENCE = { { 2.0, MP.."Blackout_Zone_01" }, 
  252.                                      { 2.0, MP.."Blackout_Zone_02" }, 
  253.                                      { 2.0, MP.."Blackout_Zone_03" }, 
  254.                                      { 2.0, MP.."Blackout_Zone_04" }, 
  255.                                      { 2.0, MP.."Blackout_Zone_05" } } 
  256.    PZ_BLACKOUT_TIME_INDEX = 1 
  257.    PZ_BLACKOUT_ZONE_NAME_INDEX = 2 
  258.  
  259. -- Constant values and counts 
  260.    NOTORIETY_MIN_LEVEL_BREAKIN = 2 
  261.    NOTORIETY_MIN_LEVEL_ESCAPE = 2 
  262.    INVALID_EFFECT_HANDLE = -1 
  263.  
  264. -- Global variables 
  265.    Players_in_threshold = { [LOCAL_PLAYER] = false, [REMOTE_PLAYER] = false } 
  266.    Players_in_inside = { [LOCAL_PLAYER] = false, [REMOTE_PLAYER] = false } 
  267.    Players_in_outside = { [LOCAL_PLAYER] = false, [REMOTE_PLAYER] = false } 
  268.  
  269.    Players_in_coal_tunnels = { [LOCAL_PLAYER] = false, [REMOTE_PLAYER] = false } 
  270.    Players_in_prison_district = { [LOCAL_PLAYER] = false, [REMOTE_PLAYER] = false } 
  271.    Players_in_unsafe_zone = { [LOCAL_PLAYER] = false, [REMOTE_PLAYER] = false } 
  272.  
  273.    Prison_guard_spawned = false 
  274.    Planting_C4 = false 
  275.    C4_correct_detonation_counting_down = false 
  276.  
  277.    Smoke_effect_handle = INVALID_EFFECT_HANDLE 
  278.    Follower_distance_check_threads = { [LOCAL_PLAYER] = nil, [REMOTE_PLAYER] = nil } 
  279.    Generator_guard_patrol_thread = INVALID_THREAD_HANDLE 
  280.    Running_out_of_time_prompts_thread_handle = INVALID_THREAD_HANDLE 
  281. 	Outside_alarm_emitter_ids = { 0, 0, 0 } 
  282.    Inside_alarm_emitter_ids = { 0, 0, 0, 0, 0 } 
  283.  
  284.    Laura_leader_name = "" 
  285.  
  286.    Mission_won = false 
  287.  
  288. -- Plays the alarms for the prison after the bomb goes off. 
  289. -- 
  290. function ss02_play_alarms() 
  291.  
  292.    local	outside_audio_id, outside_type = audio_get_id("SFX_ALARM_5", "foley") 
  293.    local	inside_audio_id, inside_type = audio_get_id("SFX_ALARM_3", "foley") 
  294.  
  295. 	for alarm_index, alarm_location in pairs( OUTSIDE_ALARMS ) do 
  296. 		if ( Outside_alarm_emitter_ids[alarm_index] == 0 ) then 
  297. 			Outside_alarm_emitter_ids[alarm_index] = audio_play_emitting_id_for_navpoint( alarm_location, outside_audio_id ) 
  298. 		end 
  299. 	end 
  300.  
  301. 	for alarm_index, alarm_location in pairs( INSIDE_ALARMS ) do 
  302. 		if ( Inside_alarm_emitter_ids[alarm_index] == 0 ) then 
  303. 			Inside_alarm_emitter_ids[alarm_index] = audio_play_emitting_id_for_navpoint( alarm_location, inside_audio_id ) 
  304. 		end 
  305. 	end 
  306. end 
  307.  
  308. function ss02_stop_alarms() 
  309. 	for alarm_index, alarm_location in pairs( OUTSIDE_ALARMS ) do 
  310. 		if ( Outside_alarm_emitter_ids[alarm_index] ~= 0 ) then 
  311. 			audio_stop_emitting_id( Outside_alarm_emitter_ids[alarm_index] ) 
  312. 			Outside_alarm_emitter_ids[alarm_index] = 0 
  313. 		end 
  314. 	end 
  315.  
  316. 	for alarm_index, alarm_location in pairs( INSIDE_ALARMS ) do 
  317. 		if ( Inside_alarm_emitter_ids[alarm_index] ~= 0 ) then 
  318. 			audio_stop_emitting_id( Inside_alarm_emitter_ids[alarm_index] ) 
  319. 			Inside_alarm_emitter_ids[alarm_index] = 0 
  320. 		end 
  321. 	end 
  322. end 
  323.  
  324. -- Returns true if all players are in the unsafe zone, false otherwise. 
  325. -- ( This is the area in the generator room where the explosion from 
  326. --   the C4 is scripted to kill them if they're there when the bomb 
  327. --   detonates. ) 
  328. -- 
  329. function ss02_all_players_in_unsafe_zone() 
  330.    if ( Players_in_unsafe_zone[LOCAL_PLAYER] ) then 
  331.       if ( coop_is_active() ) then 
  332.          if ( Players_in_unsafe_zone[REMOTE_PLAYER] ) then 
  333.             return true 
  334.          end 
  335.       else 
  336.          return true 
  337.       end 
  338.    end 
  339.    return false 
  340. end 
  341.  
  342. function ss02_running_out_of_time_prompts() 
  343.    delay( FIRST_BOMB_PROMPT_TIME_SECONDS ) 
  344.    mission_help_table_nag( HT_RUNNING_OUT_OF_TIME ) 
  345.  
  346.    delay( SECOND_BOMB_PROMPT_TIME_SECONDS ) 
  347.    mission_help_table_nag( HT_ALMOST_OUT_OF_TIME ) 
  348. end 
  349.  
  350. function ss02_start( checkpoint_name, is_restart ) 
  351.    -- Start trigger is hit...the activate button was hit 
  352.    set_mission_author("Mark G. and Brad Johnson") 
  353.  
  354.    mission_start_fade_out() 
  355.    if ( checkpoint_name == MISSION_START_CHECKPOINT ) then 
  356. 		local starter_groups = { STARTER_WATERCRAFT_GROUP_NAME, OUTSIDE_GUARDS_GROUP_NAME, ENTRANCE_GUARDS_GROUP_NAME, LAURA_GROUP_NAME } 
  357.  
  358. 		if (not is_restart) then 
  359. 			cutscene_play( CT_INTRO, starter_groups, { MISSION_START, REMOTE_PLAYER_START }, false ) 
  360. 		else 
  361. 			for index, group_name in pairs( starter_groups ) do 
  362. 				group_create_hidden( group_name, true ) 
  363. 			end 
  364.  
  365. 		   -- Teleport the players 
  366. 			teleport_coop( MISSION_START, REMOTE_PLAYER_START ) 
  367. 		end 
  368. 		group_show( STARTER_WATERCRAFT_GROUP_NAME ) 
  369. 	else -- checkpoint_name == DETONATED_C4_CHECKPOINT 
  370. 		group_create_hidden( OUTSIDE_GUARDS_GROUP_NAME, true ) 
  371. 		group_create_hidden( ENTRANCE_GUARDS_GROUP_NAME, true ) 
  372. 		group_create_hidden( LAURA_GROUP_NAME, true ) 
  373.    end 
  374.  
  375.    set_time_of_day( 23, 0 ) 
  376.  
  377.    parking_spot_enable( HELICOPTER_PARKING_SPAWN, false ) 
  378.  
  379.    -- Set up district-tracking callbacks 
  380.    if ( coop_is_active() ) then 
  381.       on_district_changed( "ss02_district_changed", REMOTE_PLAYER ) 
  382.    end 
  383.    on_district_changed( "ss02_district_changed", LOCAL_PLAYER ) 
  384.  
  385. 	-- Run the overrides on Laura 
  386.    for index, override in pairs( LAURA_PERSONA_OVERRIDES ) do 
  387.       persona_override_character_start( LAURA_NAME, override[1], override[2] ) 
  388.    end 
  389.  
  390.    local state_to_setup 
  391.  
  392.    if ( checkpoint_name == MISSION_START_CHECKPOINT ) then 
  393.       state_to_setup = MS_GET_TO_BOAT 
  394.    else 
  395.       state_to_setup = MS_CHECKPOINT 
  396.    end 
  397.    mission_start_fade_in() 
  398.  
  399. 	group_create_hidden( GENERATOR_GUARD_GROUP_NAME ) 
  400. 	group_create_hidden( CAFETERIA_GUARDS_GROUP_NAME ) 
  401.    for index, group_name in pairs ( CAFETERIA_INMATES_GROUP_NAMES ) do 
  402.       group_create_hidden( group_name ) 
  403.    end 
  404.  
  405.    notoriety_set_max( PRISON_DEFENDER_TEAM, NOTORIETY_MIN_LEVEL_BREAKIN ) 
  406.  
  407.    ss02_switch_state( state_to_setup ) 
  408. end 
  409.  
  410. function ss02_entered_threshold() 
  411.    waypoint_remove( SYNC_ALL ) 
  412.    marker_remove_navpoint( PRISON_COAL_TUNNELS_ENTRANCE_NAV, SYNC_ALL ) 
  413. end 
  414.  
  415. function ss02_prison_initial_setup( resuming_from_checkpoint ) 
  416. 	if ( resuming_from_checkpoint == nil ) then 
  417. 		resuming_from_checkpoint = false 
  418. 	end 
  419.    -- Prevent the player from getting into the generator room in any way but 
  420.    -- the docks entrance, and add a trigger that lets him know this is the case. 
  421. 	if ( resuming_from_checkpoint == false ) then 
  422. 		door_lock( GENERATOR_ROOM_EXIT_DOOR, true ); 
  423. 		trigger_enable( OPEN_DOOR_FROM_OUTSIDE_TRIGGER_NAME, true ) 
  424. 		on_trigger( "ss02_attempt_open_locked_generator_room_exit_door", OPEN_DOOR_FROM_OUTSIDE_TRIGGER_NAME ) 
  425. 	end 
  426.  
  427.    for index, name in pairs( PRISON_DOCK_TRIGGERS ) do 
  428.       trigger_enable( name, true ) 
  429.       on_trigger( "ss02_reached_dock", name ) 
  430.    end 
  431.  
  432.    trigger_enable( COAL_TUNNEL_THRESHOLD_TRIGGER, true ); 
  433.    trigger_enable( COAL_TUNNEL_OUTSIDE_TRIGGER, true ); 
  434.    trigger_enable( COAL_TUNNEL_INSIDE_TRIGGER, true ); 
  435.    on_trigger( "ss02_entered_threshold", COAL_TUNNEL_THRESHOLD_TRIGGER ) 
  436.    on_trigger_exit( "ss02_left_threshold", COAL_TUNNEL_THRESHOLD_TRIGGER ) 
  437.  
  438.    on_trigger( "ss02_entered_inside", COAL_TUNNEL_INSIDE_TRIGGER ) 
  439.    on_trigger_exit( "ss02_left_inside", COAL_TUNNEL_INSIDE_TRIGGER ) 
  440.    on_trigger( "ss02_entered_outside", COAL_TUNNEL_OUTSIDE_TRIGGER ) 
  441.    on_trigger_exit( "ss02_left_outside", COAL_TUNNEL_OUTSIDE_TRIGGER ) 
  442.  
  443.    trigger_enable( GENERATOR_ROOM_UNSAFE_ZONE_TRIGGER, true ) 
  444.    on_trigger( "ss02_entered_gen_room_unsafe_zone", GENERATOR_ROOM_UNSAFE_ZONE_TRIGGER ) 
  445.    on_trigger_exit( "ss02_left_gen_room_unsafe_zone", GENERATOR_ROOM_UNSAFE_ZONE_TRIGGER ) 
  446.  
  447. 	if ( resuming_from_checkpoint == false ) then 
  448. 		-- Setup the prison doors, so that the players cannot get where they shouldn't be 
  449. 		for index, door in PRISON_ENTRANCE_DOORS do 
  450. 			door_lock( door, true ) 
  451. 		end 
  452. 	end 
  453.    for index, door in DOORS_TO_LOCK do 
  454.       door_lock( door, true ) 
  455.    end 
  456.    mesh_mover_hide( PRISON_GRATE_NAME ) 
  457.    for index, barrel in pairs( PRISON_GRATE_BARRELS ) do 
  458.       mesh_mover_hide( barrel ) 
  459.    end 
  460. end 
  461.  
  462. function ss02_generator_guard_patrol() 
  463.    move_to( GENERATOR_GUARD_NAME, PATROL_POINTS[1], 1, true, true ) 
  464.    move_to( GENERATOR_GUARD_NAME, PATROL_POINTS[2], 1, true, true ) 
  465. end 
  466.  
  467. function ss02_district_changed( player_name, new_district_name, prev_district_name ) 
  468.    -- If a player just moved into the prison district, disable notoriety spawning 
  469.    if ( new_district_name == PRISON_DISTRICT_NAME ) then 
  470.       Players_in_prison_district[player_name] = true 
  471.       ss02_disable_gang_notoriety() 
  472.    -- If a player just moved out of the prison district 
  473.    elseif ( prev_district_name == PRISON_DISTRICT_NAME ) then 
  474.       Players_in_prison_district[player_name] = false 
  475.       -- Only enable notoriety spawning if both players are out of there 
  476.       if ( ss02_both_players_outside_of_prison_district() ) then 
  477.          ss02_enable_gang_notoriety() 
  478.       end 
  479.    end 
  480. end 
  481.  
  482. function ss02_both_players_outside_of_prison_district() 
  483.    if ( Players_in_prison_district[LOCAL_PLAYER] == false and 
  484.         Players_in_prison_district[REMOTE_PLAYER] == false ) then 
  485.       return true 
  486.    end 
  487.    return false 
  488. end 
  489.  
  490. function ss02_both_players_in_prison_district() 
  491.    if ( Players_in_prison_district[LOCAL_PLAYER] and 
  492.         Players_in_prison_district[REMOTE_PLAYER] ) then 
  493.       return true 
  494.    end 
  495.    return false 
  496. end 
  497.  
  498. function ss02_disable_gang_notoriety() 
  499.    notoriety_force_no_spawn( "Samedi", true ) 
  500.    notoriety_force_no_spawn( "Ronin", true ) 
  501.    notoriety_force_no_spawn( "Brotherhood", true ) 
  502. --[[ 
  503.    notoriety_set_max( "Samedi", 0 ) 
  504.    notoriety_set_max( "Ronin", 0 ) 
  505.    notoriety_set_max( "Brotherhood", 0 )]] 
  506. end 
  507.  
  508. function ss02_enable_gang_notoriety() 
  509.    notoriety_force_no_spawn( "Samedi", false ) 
  510.    notoriety_force_no_spawn( "Ronin", false ) 
  511.    notoriety_force_no_spawn( "Brotherhood", false ) 
  512. --[[ 
  513.    notoriety_set_max( "Samedi", MAX_NOTORIETY_LEVEL ) 
  514.    notoriety_set_max( "Ronin", MAX_NOTORIETY_LEVEL ) 
  515.    notoriety_set_max( "Brotherhood", MAX_NOTORIETY_LEVEL )]] 
  516. end 
  517.  
  518. function ss02_play_conversation_when_in_range() 
  519.    local distance 
  520.  
  521.    repeat 
  522.       distance = get_dist_char_to_nav( LOCAL_PLAYER, PRISON_ISLAND_LOCATION ) 
  523.       delay( 0.5 ) 
  524.    -- Keep trying until the local player is close enough 
  525.    until ( distance < DISTANCE_FROM_PRISON_DIALOG_METERS ) 
  526.  
  527.    -- When you're close enough, play the conversation 
  528.    audio_play_conversation( SHAUNDI_PLANT_BOMB_DIALOG_STREAM, OUTGOING_CALL ) 
  529. end 
  530.  
  531. -- Switches to a new state. All the state change code should be here if possible, not spread 
  532. -- out in various trigger callbacks. 
  533. -- 
  534. -- new_state: The new state to switch to. 
  535. -- actor_name: MAY BE nil. The name of the actor that triggered the state change. 
  536. --             Varies based on the state. 
  537. function ss02_switch_state( new_state, actor_name ) 
  538.  
  539.    if( new_state == MS_GET_TO_BOAT ) then 
  540.       ss02_prison_initial_setup() 
  541.  
  542.       -- Let the players know what they have to do next, and give them the time limit 
  543.       hud_timer_set(0, TIME_TO_PLANT_C4_MS, "ss02_failed_to_plant_c4_in_time" ) 
  544.       Running_out_of_time_prompts_thread_handle = thread_new( "ss02_running_out_of_time_prompts" ) 
  545.  
  546.       thread_new( "ss02_play_conversation_when_in_range" ) 
  547.  
  548.       for index, watercraft_name in STARTER_WATERCRAFT_NAMES do 
  549.          on_vehicle_enter( "ss02_player_entered_vehicle_initial", watercraft_name ) 
  550.       end 
  551.       on_vehicle_enter( "ss02_player_entered_vehicle_initial", LOCAL_PLAYER ) 
  552.       if ( coop_is_active() ) then 
  553.          on_vehicle_enter( "ss02_player_entered_vehicle_initial", REMOTE_PLAYER ) 
  554.       end 
  555.       marker_add_vehicle( MARKED_WATERCRAFT, MINIMAP_ICON_LOCATION, INGAME_EFFECT_VEHICLE_INTERACT, SYNC_ALL ) 
  556.  
  557.       mission_help_table( HT_GET_TO_PRISON ) 
  558.    elseif ( new_state == MS_CHECKPOINT ) then 
  559.       -- Setup the prison 
  560.       ss02_prison_initial_setup( true ) 
  561.       -- Clear all the triggers for the stuff we should already have passed 
  562.       --door_lock( GENERATOR_ROOM_EXIT_DOOR, false ); 
  563.       trigger_enable( OPEN_DOOR_FROM_OUTSIDE_TRIGGER_NAME, false ) 
  564.  
  565.       for index, name in pairs( PRISON_DOCK_TRIGGERS ) do 
  566.          trigger_enable( name, false ) 
  567.          on_trigger( "ss02_reached_dock", name ) 
  568.       end 
  569.  
  570.       trigger_enable( COAL_TUNNEL_THRESHOLD_TRIGGER, false ) 
  571.       trigger_enable( COAL_TUNNEL_OUTSIDE_TRIGGER, false ) 
  572.       trigger_enable( COAL_TUNNEL_INSIDE_TRIGGER, false ) 
  573.       trigger_enable( GENERATOR_ROOM_UNSAFE_ZONE_TRIGGER, false ) 
  574.  
  575.       marker_remove_navpoint( PRISON_COAL_TUNNELS_ENTRANCE_NAV, SYNC_ALL ) 
  576.  
  577.       -- Spawn the guards who are outside 
  578.       group_show( OUTSIDE_GUARDS_GROUP_NAME ) 
  579.       for index, member_name in pairs ( OUTSIDE_PRISON_WANDERING_GUARDS ) do 
  580.          wander_start( member_name, member_name, WANDERING_GUARDS_WANDER_RADIUS_METERS ) 
  581.       end 
  582.  
  583.       ss02_do_prison_blackout()    
  584.       ss02_switch_state( MS_PRISON_RIOT ) 
  585.    elseif ( new_state == MS_GET_TO_PRISON ) then 
  586.       -- Update objectives 
  587.       waypoint_remove( SYNC_ALL ) 
  588.       waypoint_add( MP.."Dock_Location", SYNC_ALL ) 
  589.       marker_add_navpoint( PRISON_COAL_TUNNELS_ENTRANCE_NAV, MINIMAP_ICON_LOCATION, INGAME_EFFECT_LOCATION, SYNC_ALL ) 
  590.       marker_remove_trigger( PLANT_C4_TRIGGER, SYNC_ALL ) 
  591.  
  592.       -- Spawn the guards who are outside 
  593.       group_show( OUTSIDE_GUARDS_GROUP_NAME ) 
  594.       for index, member_name in pairs ( OUTSIDE_PRISON_WANDERING_GUARDS ) do 
  595.          wander_start( member_name, member_name, WANDERING_GUARDS_WANDER_RADIUS_METERS ) 
  596.       end 
  597.  
  598.    elseif ( new_state == MS_PLANT_C4 ) then 
  599.       marker_add_trigger( PLANT_C4_TRIGGER, MINIMAP_ICON_LOCATION, INGAME_EFFECT_LOCATION, SYNC_ALL ) 
  600.       marker_remove_navpoint( PRISON_COAL_TUNNELS_ENTRANCE_NAV, SYNC_ALL ) 
  601.       trigger_enable( PLANT_C4_TRIGGER, true ) 
  602.       on_trigger( "ss02_plant_c4", PLANT_C4_TRIGGER ) 
  603.       trigger_enable( PLANT_C4_MESSAGE_TRIGGER, true ) 
  604.       on_trigger( "ss02_plant_c4_message", PLANT_C4_MESSAGE_TRIGGER ) 
  605.       on_trigger_exit( "ss02_plant_c4_message_leave", PLANT_C4_MESSAGE_TRIGGER ) 
  606. 		 
  607.    elseif ( new_state == MS_C4_PLANTED ) then 
  608.       -- Default to setting the timer to the post detonation time 
  609.       local time_to_set_ms = C4_POST_PLANT_DETONATION_TIME_MS 
  610.       -- If there's less time on the timer than this, then use the smaller value 
  611.       local hud_time_remaining_ms = hud_timer_get_remainder( 0 ) 
  612.       if ( hud_time_remaining_ms < time_to_set_ms ) then 
  613.          time_to_set_ms = hud_time_remaining_ms 
  614.       end 
  615. 		set_force_combat_ready_team("police") 
  616.       hud_timer_set(0, time_to_set_ms, "ss02_c4_correct_detonation" ) 
  617.       C4_correct_detonation_counting_down = true 
  618.       hud_timer_pause( 0, false ) 
  619.  
  620.       trigger_enable( PLANT_C4_TRIGGER, false ) 
  621.       trigger_enable( PLANT_C4_MESSAGE_TRIGGER, false ) 
  622.       marker_remove_trigger( PLANT_C4_TRIGGER, SYNC_LOCAL ) 
  623.       trigger_enable( COAL_TUNNEL_INSIDE_TRIGGER, false ) 
  624.       trigger_enable( COAL_TUNNEL_OUTSIDE_TRIGGER, false ) 
  625.       trigger_enable( COAL_TUNNEL_THRESHOLD_TRIGGER, false ) 
  626.       trigger_enable( OPEN_DOOR_FROM_OUTSIDE_TRIGGER_NAME, false ) 
  627.       door_lock( GENERATOR_ROOM_EXIT_DOOR, false ); 
  628.       minimap_icon_add_navpoint_radius( GENERATOR_ROOM_UNSAFE_ZONE_TRIGGER, MINIMAP_ICON_LOCATION, 
  629.                                         GENERATOR_ROOM_SAFE_ZONE_DIAMETER_METERS, nil, SYNC_ALL ) 
  630.    elseif( new_state == MS_PRISON_RIOT ) then 
  631.       -- Switch to the rioting prison chunk 
  632.       city_chunk_swap( "sr2_intsrmisprison02", "riot", true, false, true ) 
  633.  
  634.       -- Play the prison alarms 
  635.       thread_new( "ss02_play_alarms" ) 
  636.  
  637.       -- Set the player's notoriety to a minimum value 
  638.       notoriety_set_min( PRISON_DEFENDER_TEAM, NOTORIETY_MIN_LEVEL_BREAKIN ) 
  639. 	  notoriety_set_max( PRISON_DEFENDER_TEAM, NOTORIETY_MIN_LEVEL_BREAKIN ) 
  640.       -- Prompt the player to go to the prison and use the map 
  641.       -- to guide him there. 
  642.       mission_help_table( HT_GET_INSIDE_PRISON, "", "", SYNC_ALL ) 
  643.       marker_add_trigger( PRISON_GATE_TRIGGER_NAME, MINIMAP_ICON_LOCATION, INGAME_EFFECT_LOCATION, SYNC_ALL ) 
  644.       trigger_enable( PRISON_GATE_TRIGGER_NAME, true ) 
  645.       waypoint_add( PRISON_GATE_TRIGGER_NAME, SYNC_ALL ) 
  646.       on_trigger( "ss02_reached_prison_gate", PRISON_GATE_TRIGGER_NAME ) 
  647.  
  648.       for index, name in PRISON_ENTRANCE_DOORS do 
  649.          on_door_opened( "ss02_cafeteria_door_opened", name ) 
  650.       end 
  651.  
  652.       -- Unlock the doors 
  653.       for index, door in PRISON_ENTRANCE_DOORS do 
  654.          door_lock( door, false ) 
  655.       end 
  656.  
  657.       for index, door in pairs( LAURA_CELLBLOCK_DOORS ) do 
  658.          door_lock( door, true ) 
  659.          mesh_mover_hide( door ) 
  660.       end 
  661.       group_show( ENTRANCE_GUARDS_GROUP_NAME ) 
  662.  
  663.       -- Disable the two guards from attacking, so they look distracted 
  664.       for index, name in pairs( CAFETERIA_DISABLED_GUARDS ) do 
  665.          set_ignore_ai_flag( name, true ) 
  666.          npc_combat_enable( name, false ) 
  667.       end 
  668.       -- Have them attack if you pass them or attack either of them 
  669.       trigger_enable( WATCHING_GUARDS_ATTACK_TRIGGER, true ) 
  670.       on_trigger( "ss02_disabled_guards_attack", WATCHING_GUARDS_ATTACK_TRIGGER ) 
  671.       ss02_tie_members_in_pack( "ss02_disabled_guards_attack", CAFETERIA_DISABLED_GUARDS ) 
  672.    elseif ( new_state == MS_ESCAPE_FROM_PRISON ) then 
  673.       -- Set Laura up correctly for being a follower. 
  674.       npc_combat_enable( LAURA_NAME, false ) 
  675.       set_attack_enemies_flag( LAURA_NAME, false ) 
  676.       --inv_item_add( "beretta", 1, LAURA_NAME ) 
  677.       npc_weapon_pickup_override( LAURA_NAME, false ) 
  678.       set_ignore_ai_flag( LAURA_NAME, false ) 
  679.       on_dismiss( "ss02_follower_dismissed", LAURA_NAME ) 
  680.       -- Make her a follower 
  681.       party_add( LAURA_NAME, actor_name ) 
  682.       Laura_leader_name = actor_name 
  683.  
  684.       -- Release the earlier groups and spawn them again 
  685.       release_to_world( STAIRWELL_GUARDS_GROUP_NAME ) 
  686.       for index, group_name in pairs ( CAFETERIA_INMATES_GROUP_NAMES ) do 
  687.          release_to_world( group_name ) 
  688.       end 
  689.  
  690.       if ( coop_is_active() ) then 
  691.          mission_debug( "running with coop_is_active check version" ) 
  692.          local other_player = LOCAL_PLAYER 
  693.          if ( Laura_leader_name == LOCAL_PLAYER ) then 
  694.             other_player = REMOTE_PLAYER 
  695.          end 
  696.  
  697.          if ( ss02_player_can_see_stairwell_guards( other_player ) == false ) then 
  698.             group_create( STAIRWELL_GUARDS_GROUP_NAME, true ) 
  699.             for index, name in pairs( STAIRWELL_GUARDS ) do 
  700.                attack_closest_player( name, false ) 
  701.             end 
  702.          end 
  703.  
  704.          if ( ss02_player_can_see_respawned_cafeteria_guards( other_player ) == false ) then 
  705.             group_create_hidden( CAFETERIA_GUARDS_RESPAWN_GROUP_NAME, true ) 
  706.             for i = 1, sizeof_table( CAFETERIA_GUARD_RESPAWN_NAMES ) do 
  707.                group_create_hidden( CAFETERIA_INMATES_GROUP_NAMES[i], true ) 
  708.             end 
  709.             thread_new( "ss02_show_cafeteria_groups_and_start_battle" ) 
  710.          end 
  711.       else 
  712.          group_create_hidden( CAFETERIA_GUARDS_RESPAWN_GROUP_NAME ) 
  713.          for i = 1, sizeof_table( CAFETERIA_GUARD_RESPAWN_NAMES ) do 
  714.             group_create_hidden( CAFETERIA_INMATES_GROUP_NAMES[i], true ) 
  715.  
  716.             for index, name in pairs( CAFETERIA_GROUPS_INMATE_NAMES[i] ) do 
  717.                npc_leash_to_nav( name, CAFETERIA_PRISONER_LEASH_LOCATION, CAFETERIA_PRISONER_LEASH_DISTANCE_METERS ) 
  718.                npc_leash_set_unbreakable( name, true ) 
  719.             end 
  720.             --ss02_tie_members_in_pack( "ss02_cafeteria_inmate_damaged_g0"..i, CAFETERIA_GROUPS_INMATE_NAMES[i] ) 
  721.          end 
  722.  
  723.          group_create( STAIRWELL_GUARDS_GROUP_NAME, true ) 
  724.          for index, name in pairs( STAIRWELL_GUARDS ) do 
  725.             attack_closest_player( name, false ) 
  726.          end 
  727.          trigger_enable( CAFETERIA_SHOW_RESPAWNS_TRIGGER, true ) 
  728.          on_trigger( "ss02_show_cafeteria_groups_and_start_battle", CAFETERIA_SHOW_RESPAWNS_TRIGGER ) 
  729.       end 
  730.  
  731.       -- Guide the player out of the prison 
  732.       mission_help_table( HT_GET_OUT_OF_PRISON ) 
  733.       trigger_enable( CELL_BLOCKS_ENTRANCE_TRIGGER_NAME, true ) 
  734.       marker_add_trigger( CELL_BLOCKS_ENTRANCE_TRIGGER_NAME, MINIMAP_ICON_LOCATION, INGAME_EFFECT_LOCATION, SYNC_ALL ) 
  735.       on_trigger( "ss02_reached_cafeteria_escape", CELL_BLOCKS_ENTRANCE_TRIGGER_NAME ) 
  736.  
  737.       ss05_set_or_clear_escape_callbacks( true ) 
  738.  
  739.       notoriety_set_min( PRISON_DEFENDER_TEAM, NOTORIETY_MIN_LEVEL_ESCAPE ) 
  740. 	  notoriety_set_max( PRISON_DEFENDER_TEAM, NOTORIETY_MIN_LEVEL_ESCAPE ) 
  741.  
  742.       local sync_type = sync_from_player( actor_name ) 
  743.  
  744.       -- Make sure that the player that saves Laura is the one that speaks to her! ... hehe 
  745.       LAURA_SAVED_DIALOG_STREAM[2][2] = actor_name 
  746.  
  747. 		group_create( ESCAPE_HELICOPTERS_GROUP_NAME ) 
  748.  
  749.       audio_play_conversation( LAURA_SAVED_DIALOG_STREAM, NOT_CALL ) 
  750.  
  751.       audio_play( HELICOPTER_FLYBY_SOUND ) 
  752.    end 
  753. end 
  754.  
  755.  
  756. function ss02_player_can_see_stairwell_guards( player_name ) 
  757.    for index, name in pairs( STAIRWELL_GUARDS ) do 
  758.       if ( navpoint_in_player_fov( name, player_name ) ) then 
  759.          return true 
  760.       end 
  761.    end 
  762.    return false 
  763. end 
  764.  
  765. function ss02_player_can_see_respawned_cafeteria_guards( player_name ) 
  766.    -- Go through all of the groups 
  767.    for group_index = 1, sizeof_table( CAFETERIA_GUARD_RESPAWN_NAMES ) do 
  768.       -- Check to see if the player can see any of the members 
  769.       for member_index, member_name in pairs( CAFETERIA_GROUPS_INMATE_NAMES[group_index] ) do 
  770.          if ( navpoint_in_player_fov( member_name, player_name ) ) then 
  771.             return true 
  772.          end 
  773.       end 
  774.    end 
  775.    return false 
  776. end 
  777.  
  778. function ss02_show_cafeteria_groups_and_start_battle( triggerer_name, trigger_name ) 
  779.    trigger_enable( trigger_name, false ) 
  780.  
  781.    -- Show the guards 
  782.    group_show( CAFETERIA_GUARDS_RESPAWN_GROUP_NAME ) 
  783.  
  784.    -- Go through all of the groups 
  785.    for group_index = 1, sizeof_table( CAFETERIA_GUARD_RESPAWN_NAMES ) do 
  786.       -- Show each group of prisoners ( only respawn one per guard ) 
  787.       group_show( CAFETERIA_INMATES_GROUP_NAMES[group_index] ) 
  788.       -- Have the guard attack one of the group members 
  789.       attack_safe( CAFETERIA_GUARD_NAMES[group_index], CAFETERIA_GROUPS_INMATE_NAMES[group_index][3], false ) 
  790.  
  791.       -- Have all of the group members attack the guard 
  792.       for member_index, member_name in pairs( CAFETERIA_GROUPS_INMATE_NAMES[group_index] ) do 
  793.          attack_safe( member_name, CAFETERIA_GUARD_NAMES[group_index], false ) 
  794.       end 
  795.    end 
  796. end 
  797.  
  798. function ss02_reached_cafeteria_escape( triggerer_name, trigger_name ) 
  799.    trigger_enable( trigger_name, false ) 
  800.  
  801.    local sync_type = sync_from_player( Laura_leader_name ) 
  802.  
  803.    trigger_enable( MAIN_ENTRANCE_TRIGGER_NAME, true ) 
  804.    marker_add_trigger( MAIN_ENTRANCE_TRIGGER_NAME, MINIMAP_ICON_LOCATION, INGAME_EFFECT_LOCATION, sync_type ) 
  805.    on_trigger( "ss02_left_prison", MAIN_ENTRANCE_TRIGGER_NAME ) 
  806.  
  807.    for index, name in pairs( CAFETERIA_GUARD_RESPAWN_NAMES ) do 
  808.       if ( character_exists( name ) ) then 
  809.          turn_vulnerable( name ) 
  810.       end 
  811.    end 
  812. end 
  813.  
  814. function ss05_set_or_clear_escape_callbacks( set ) 
  815.    local callback_name = "" 
  816.    if ( set == true ) then 
  817.       callback_name = "ss02_player_entered_vehicle_escape" 
  818.    end 
  819.  
  820.    on_vehicle_enter( callback_name, LOCAL_PLAYER ) 
  821.    for index, name in pairs( STARTER_WATERCRAFT_NAMES ) do 
  822.       on_vehicle_enter( callback_name, name ) 
  823.    end 
  824.    for index, name in pairs( ESCAPE_HELICOPTER_NAMES ) do 
  825.       on_vehicle_enter( callback_name, name ) 
  826.    end 
  827.    if ( coop_is_active() ) then 
  828.       on_vehicle_enter( callback_name, REMOTE_PLAYER ) 
  829.    end 
  830. end 
  831.  
  832. -- Called when the player reaches the prison dock. 
  833. -- Sets a checkpoint there. 
  834. -- 
  835. function ss02_reached_dock() 
  836.    for index, name in pairs( PRISON_DOCK_TRIGGERS ) do 
  837.       trigger_enable( name, false ) 
  838.       on_trigger( "", name ) 
  839.    end 
  840. end 
  841.  
  842. function ss02_follower_dismissed( name ) 
  843.    if ( name == LAURA_NAME ) then 
  844.       -- End the mission since Laura was dismissed 
  845.       -- ( ie, abandoned, because she's set to undismissable ) 
  846.       mission_end_failure( MISSION_NAME, HT_LAURA_ABANDONDED ) 
  847.    end 
  848. end 
  849.  
  850. -- Fails the mission if Laura dies. 
  851. function ss02_laura_died() 
  852.    marker_remove_trigger( LAURA_TRIGGER_NAME, SYNC_ALL ) 
  853.    trigger_enable( LAURA_TRIGGER_NAME, false ) 
  854.    delay( 2.0 ) 
  855.    mission_end_failure( MISSION_NAME, HT_LAURA_DIED ) 
  856. end 
  857.  
  858. -- Spawns threads to check if Laura is near the trigger. 
  859. -- If so, the mission is won. 
  860. -- 
  861. function ss02_reached_house( triggerer_name, trigger_name ) 
  862. 	-- 
  863. 	if ( triggerer_name == LOCAL_PLAYER ) then 
  864. 		Follower_distance_check_threads[LOCAL_PLAYER] = thread_new( "ss01_check_for_follower_close_to_win_location" ) 
  865. 	elseif ( triggerer_name == REMOTE_PLAYER ) then 
  866. 		Follower_distance_check_threads[REMOTE_PLAYER] = thread_new( "ss01_check_for_follower_close_to_win_location" ) 
  867. 	end 
  868. end 
  869.  
  870. -- Stops any threads spawned by "ss02_reached_house" 
  871. -- so that the mission isn't counted as won 
  872. -- until one of the players is at the trigger 
  873. -- with Laura nearby. 
  874. -- 
  875. function ss02_left_house( triggerer_name, trigger_name ) 
  876. 	-- 
  877. 	if ( triggerer_name == LOCAL_PLAYER and Follower_distance_check_threads[LOCAL_PLAYER] ~= nil ) then 
  878. 		thread_kill( Follower_distance_check_threads[LOCAL_PLAYER] ) 
  879. 		Follower_distance_check_threads[LOCAL_PLAYER] = nil 
  880. 	elseif ( triggerer_name == REMOTE_PLAYER and Follower_distance_check_threads[REMOTE_PLAYER] ~= nil ) then 
  881. 		thread_kill( Follower_distance_check_threads[REMOTE_PLAYER] ) 
  882. 		Follower_distance_check_threads[REMOTE_PLAYER] = nil 
  883. 	end 
  884. end 
  885.  
  886. -- Called when the players leave the prison. Guides them to the next location. 
  887. -- 
  888. function ss02_left_prison( triggerer_name, trigger_name ) 
  889.    if ( triggerer_name == Laura_leader_name ) then 
  890.       ss02_disable_and_unmark_trigger( trigger_name ) 
  891.  
  892.       -- Guide the player out of here 
  893.       mission_help_table( HT_ESCAPE_PRISON_AND_POLICE ) 
  894.       thread_new( "ss02_prison_escape_distance_win" ) 
  895.       marker_add_vehicle( HELIPAD_HELICOPTER, MINIMAP_ICON_LOCATION, INGAME_EFFECT_VEHICLE_INTERACT, SYNC_ALL ) 
  896.       waypoint_add( HELIPAD_HELICOPTER, SYNC_ALL ) 
  897.  
  898.       notoriety_force_no_spawn( PRISON_DEFENDER_TEAM, false ) 
  899.  
  900.       minimap_icon_add_trigger_radius( MAIN_ENTRANCE_TRIGGER_NAME, MINIMAP_ICON_LOCATION, 
  901.                                        DISTANCE_FROM_PRISON_WIN_METERS, nil, SYNC_ALL ) 
  902.    end 
  903. end 
  904.  
  905. function ss02_prison_escape_distance_win() 
  906.    local distance_from_prison = get_dist_char_to_nav( LAURA_NAME, MAIN_ENTRANCE_TRIGGER_NAME )  
  907.  
  908.    while ( distance_from_prison < DISTANCE_FROM_PRISON_WIN_METERS ) do 
  909.       distance_from_prison = get_dist_char_to_nav( LAURA_NAME, MAIN_ENTRANCE_TRIGGER_NAME )  
  910.       delay( 0 ) 
  911.    end 
  912.  
  913.  
  914.    audio_play_for_character( ESCAPED_FROM_PRISON_LINE, LAURA_NAME, "voice", false, true ) 
  915.  
  916.    Mission_won = true 
  917.  
  918.    mission_end_success( MISSION_NAME, CT_OUTRO, { LAURAS_HOUSE_TRIGGER_NAME, LAURAS_HOUSE_REMOTE_PLAYER_TELEPORT } ) 
  919. end 
  920.  
  921. -- Called when the players make it back to the generator room after escaping the 
  922. -- prison with Laura in tow. 
  923. -- Guides them to the boat. 
  924. -- 
  925. function ss02_got_back_to_generator_room( triggerer_name, trigger_name ) 
  926. --   if ( triggerer_name == LOCAL_PLAYER ) then 
  927.       ss02_disable_and_unmark_trigger( trigger_name ) 
  928. --   end 
  929. end 
  930.  
  931. -- Called on a trigger to disable it and remove any markers on it. 
  932. -- 
  933. function ss02_disable_and_unmark_trigger( trigger_name ) 
  934.    marker_remove_trigger( trigger_name, SYNC_ALL ) 
  935.    trigger_enable( trigger_name, false ) 
  936. end 
  937.  
  938. -- Disables a path trigger. 
  939. -- 
  940. function ss02_disable_path_trigger( trigger_name ) 
  941.    ss02_disable_and_unmark_trigger( trigger_name ) 
  942. end 
  943.  
  944. -- Enables a new path trigger, and binds the passed-in function to it. 
  945. -- 
  946. function ss02_enable_next_path_trigger( function_name, trigger_name, sync_type ) 
  947.    if ( sync_type == nil ) then 
  948.       sync_type = SYNC_ALL 
  949.    end 
  950.    marker_add_trigger( trigger_name, MINIMAP_ICON_LOCATION, INGAME_EFFECT_LOCATION, sync_type ) 
  951.    trigger_enable( trigger_name, true ) 
  952.    on_trigger( function_name, trigger_name ) 
  953. end 
  954.  
  955. function ss02_reached_prison_gate( triggerer_name, trigger_name ) 
  956.    waypoint_remove( SYNC_ALL ) 
  957. --   if ( triggerer_name == LOCAL_PLAYER ) then 
  958.       ss02_disable_path_trigger( trigger_name ) 
  959.       ss02_enable_next_path_trigger( "ss02_reached_prison_entrance", MAIN_ENTRANCE_TRIGGER_NAME, SYNC_ALL ) 
  960. --   end 
  961. end 
  962.  
  963. -- Path trigger callbacks. These guide the player through the prison. 
  964. -- 
  965. function ss02_reached_prison_entrance( triggerer_name, trigger_name ) 
  966. --   if ( triggerer_name == LOCAL_PLAYER ) then 
  967.       notoriety_force_no_spawn( PRISON_DEFENDER_TEAM, true ) 
  968.       ss02_disable_path_trigger( trigger_name ) 
  969.       ss02_enable_next_path_trigger( "ss02_reached_cell_blocks_entrance", CELL_BLOCKS_ENTRANCE_TRIGGER_NAME, SYNC_ALL ) 
  970. --   end 
  971. end 
  972.  
  973. function ss02_reached_cell_blocks_entrance( triggerer_name, trigger_name ) 
  974. --   if ( triggerer_name == LOCAL_PLAYER ) then 
  975.       mission_help_table( HT_FIND_DRUG_EXPERT, "", "", SYNC_ALL ) 
  976.       ss02_disable_path_trigger( trigger_name ) 
  977.       ss02_enable_next_path_trigger( "ss02_reached_stairwell", STAIRWELL_TRIGGER_NAME, SYNC_ALL ) 
  978.        
  979.       thread_new( "ss02_create_and_setup_ambient_chaos" ) 
  980. --   end 
  981. end 
  982.  
  983. function ss02_reached_stairwell( triggerer_name, trigger_name ) 
  984. --   if ( triggerer_name == LOCAL_PLAYER ) then 
  985.       ss02_disable_path_trigger( trigger_name ) 
  986.       ss02_enable_next_path_trigger( "ss02_reached_third_floor", THIRD_FLOOR_TRIGGER_NAME, SYNC_ALL ) 
  987.       mission_help_table( HT_GET_TO_CELLBLOCKS, "", "", SYNC_ALL ) 
  988.       group_create( STAIRWELL_INMATES_GROUP_NAME, true ) 
  989.       group_create( STAIRWELL_GUARDS_GROUP_NAME, true ) 
  990.       for index, guard_name in pairs( STAIRWELL_GUARDS ) do 
  991.          if ( index <= sizeof_table( STAIRWELL_INMATES ) ) then 
  992.             attack_safe( guard_name, STAIRWELL_INMATES[index], false ) 
  993.             attack_safe( STAIRWELL_INMATES[index], guard_name, false ) 
  994.          end 
  995.       end 
  996.  
  997.       group_create( CATWALK_GUARDS_GROUP_NAME, true ) 
  998.  
  999.       ss02_tie_members_in_pack( "ss02_stairwell_guard_damaged", STAIRWELL_GUARDS ) 
  1000.       --ss02_tie_members_in_pack( "ss02_stairwell_inmate_damaged", STAIRWELL_INMATES ) 
  1001. --   end 
  1002. end 
  1003.  
  1004. function ss02_create_and_setup_ambient_chaos() 
  1005.    group_create( AMBIENT_CHAOS_GROUP_NAME, true ) 
  1006.  
  1007.    for group_index, group in pairs( AMBIENT_CHAOS_GROUPS_MEMBERS ) do 
  1008.       for member_index, member_name in pairs( group ) do 
  1009.          -- Make every member by default invulerable except to player damage 
  1010.          turn_invulnerable( member_name, true ) 
  1011.  
  1012.          -- Have the prisoners attack the cop 
  1013.          if ( member_index ~= AMBIENT_CHAOS_GROUP_COP_INDEX ) then 
  1014.             attack_safe( member_name, group[AMBIENT_CHAOS_GROUP_COP_INDEX], false ) 
  1015.          -- Disarm the cop 
  1016.          else 
  1017.             inv_item_remove_all( member_name ) 
  1018.          end 
  1019.       end 
  1020.    end 
  1021. end 
  1022.  
  1023. -- The last path trigger spawns Laura and enables the "talk to Laura" trigger. 
  1024. -- 
  1025. function ss02_reached_third_floor( triggerer_name, trigger_name ) 
  1026. --   if ( triggerer_name == LOCAL_PLAYER ) then 
  1027.       ss02_disable_path_trigger( trigger_name ) 
  1028.       --group_show( CATWALK_GUARDS_GROUP_NAME ) 
  1029.  
  1030.       trigger_enable( LAURA_TRIGGER_NAME, true ) 
  1031.       on_trigger( "ss02_talk_to_laura", LAURA_TRIGGER_NAME ) 
  1032.       group_show( LAURA_GROUP_NAME ) 
  1033.       marker_add_npc( LAURA_NAME, MINIMAP_ICON_PROTECT_ACQUIRE, INGAME_EFFECT_PROTECT_ACQUIRE, SYNC_ALL ) 
  1034.       on_death( "ss02_laura_died", LAURA_NAME ) 
  1035.       set_ignore_ai_flag( LAURA_NAME, true ) 
  1036. --   end 
  1037. end 
  1038.  
  1039. -- Switches the mission into the "Ecape from Prison" state 
  1040. -- 
  1041. function ss02_talk_to_laura( triggerer_name, trigger_name ) 
  1042.    trigger_enable( trigger_name, false ) 
  1043.    marker_remove_npc( LAURA_NAME, SYNC_ALL ) 
  1044.  
  1045.    ss02_switch_state( MS_ESCAPE_FROM_PRISON, triggerer_name ) 
  1046. end 
  1047.  
  1048. function ss02_group_member_damaged( fellow_member_names, attacker_name ) 
  1049.    if ( attacker_name ~= nil ) then  
  1050.       if ( character_is_player( attacker_name ) ) then 
  1051.          for index, name in pairs( fellow_member_names ) do 
  1052.             on_take_damage( "", name ) 
  1053.             attack_closest_player( name, false ) 
  1054.          end 
  1055.       end 
  1056.    end 
  1057. end 
  1058.  
  1059. -- Ties group members together in a pack - if a player attacks one of them, 
  1060. -- they'll all attack the nearest player 
  1061. -- 
  1062. function ss02_tie_members_in_pack( function_name, group_member_names ) 
  1063.    for index, name in pairs( group_member_names ) do 
  1064.       on_take_damage( function_name, name ) 
  1065.    end 
  1066. end 
  1067.  
  1068. function ss02_cafeteria_inmate_group_member_damaged( group_index, attacker_name ) 
  1069.    ss02_group_member_damaged( CAFETERIA_GROUPS_INMATE_NAMES[group_index], attacker_name ) 
  1070. end 
  1071.  
  1072. -- Functions for cafeteria inmate group packs 
  1073. function ss02_cafeteria_inmate_damaged_g01( victim_name, attacker_name ) 
  1074.    ss02_cafeteria_inmate_group_member_damaged( 1, attacker_name ) 
  1075. end 
  1076.  
  1077. function ss02_cafeteria_inmate_damaged_g02( victim_name, attacker_name ) 
  1078.    ss02_cafeteria_inmate_group_member_damaged( 2, attacker_name ) 
  1079. end 
  1080.  
  1081. function ss02_cafeteria_inmate_damaged_g03( victim_name, attacker_name ) 
  1082.    ss02_cafeteria_inmate_group_member_damaged( 3, attacker_name ) 
  1083. end 
  1084.  
  1085. function ss02_cafeteria_inmate_damaged_g04( victim_name, attacker_name ) 
  1086.    ss02_cafeteria_inmate_group_member_damaged( 4, attacker_name ) 
  1087. end 
  1088.  
  1089. function ss02_cafeteria_inmate_damaged_g05( victim_name, attacker_name ) 
  1090.    ss02_cafeteria_inmate_group_member_damaged( 5, attacker_name ) 
  1091. end 
  1092. -- End functions for cafeteria inmate group packs 
  1093.  
  1094. -- Other group packs 
  1095. function ss02_cafeteria_guard_damaged( victim_name, attacker_name ) 
  1096.    ss02_group_member_damaged( CAFETERIA_GUARD_NAMES, attacker_name ) 
  1097. end 
  1098.  
  1099. function ss02_stairwell_guard_damaged( victim_name, attacker_name ) 
  1100.    ss02_group_member_damaged( STAIRWELL_GUARDS, attacker_name ) 
  1101. end 
  1102.  
  1103. function ss02_stairwell_inmate_damaged( victim_name, attacker_name ) 
  1104.    ss02_group_member_damaged( STAIRWELL_INMATES, attacker_name ) 
  1105. end 
  1106.  
  1107. function ss02_guard_respawn_damaged( victim_name, attacker_name ) 
  1108.    ss02_group_member_damaged( CAFETERIA_GUARD_RESPAWN_NAMES, attacker_name ) 
  1109. end 
  1110.  
  1111. -- Triggers the guards in the cafeteria to attack the prisoners. 
  1112. -- 
  1113. function ss02_cafeteria_door_opened() 
  1114.    for index, name in CAFETERIA_ENTRANCE_DOORS do 
  1115.       on_door_opened( "", name ) 
  1116.    end 
  1117.  
  1118.    -- Show the guards and the inmates 
  1119.    group_show( CAFETERIA_GUARDS_GROUP_NAME ) 
  1120.    for group_index, group_name in pairs( CAFETERIA_INMATES_GROUP_NAMES ) do 
  1121.       group_show( group_name ) 
  1122.    end 
  1123.  
  1124.    -- Have the corresponding cop attack a group member and every group member attack 
  1125.    -- the corresponding cop 
  1126.    for group_index, group_member_names in pairs( CAFETERIA_GROUPS_INMATE_NAMES ) do 
  1127.       attack_safe( CAFETERIA_GUARD_NAMES[group_index], group_member_names[3], false ) 
  1128.  
  1129.       --on_death( "ss02_guard_0"..group_index.."_died", CAFETERIA_GUARD_NAMES[group_index] ) 
  1130.  
  1131.       for member_index, member_name in pairs( group_member_names ) do 
  1132.          attack_safe( member_name, CAFETERIA_GUARD_NAMES[group_index], false ) 
  1133.       end 
  1134.    end 
  1135.  
  1136.    for index, pack_member_names in pairs( CAFETERIA_GROUPS_INMATE_NAMES ) do 
  1137.       for index, name in pairs( pack_member_names ) do 
  1138.          npc_leash_to_nav( name, CAFETERIA_PRISONER_LEASH_LOCATION, CAFETERIA_PRISONER_LEASH_DISTANCE_METERS ) 
  1139.          npc_leash_set_unbreakable( name, true ) 
  1140.       end 
  1141.       --ss02_tie_members_in_pack( "ss02_cafeteria_inmate_damaged_g0"..index, pack_member_names ) 
  1142.    end 
  1143. end 
  1144.  
  1145. function ss02_groups_guard_died( group_index ) 
  1146.    for member_index, member_name in pairs( CAFETERIA_GROUPS_INMATE_NAMES[group_index] ) do 
  1147.       attack_closest_player( member_name, false ) 
  1148.    end 
  1149. end 
  1150.  
  1151. function ss02_guard_01_died() 
  1152.    ss02_groups_guard_died( 1 ) 
  1153. end 
  1154. function ss02_guard_02_died() 
  1155.    ss02_groups_guard_died( 2 ) 
  1156. end 
  1157. function ss02_guard_03_died() 
  1158.    ss02_groups_guard_died( 3 ) 
  1159. end 
  1160. function ss02_guard_04_died() 
  1161.    ss02_groups_guard_died( 4 ) 
  1162. end 
  1163. function ss02_guard_05_died() 
  1164.    ss02_groups_guard_died( 5 ) 
  1165. end 
  1166.  
  1167. -- Re-enables both disabled guards when one is hurt, to simulate them 
  1168. -- becoming aware of the player. 
  1169. -- 
  1170. -- name: Name of the guard. 
  1171. -- 
  1172. function ss02_disabled_guards_attack( name ) 
  1173.    trigger_enable( WATCHING_GUARDS_ATTACK_TRIGGER, false ) 
  1174.  
  1175.    for index, guard_name in pairs( CAFETERIA_DISABLED_GUARDS ) do 
  1176.       npc_combat_enable( guard_name, true ) 
  1177.       set_ignore_ai_flag( guard_name, false ) 
  1178.       on_take_damage( "", guard_name ) 
  1179.       attack_closest_player( guard_name, false ) 
  1180.    end 
  1181. end 
  1182.  
  1183. -- These two functions are used to track whether the players are in the 
  1184. -- unsafe zone in the generator room, where they'll be killed if the C4 
  1185. -- goes off. 
  1186. -- 
  1187. function ss02_entered_gen_room_unsafe_zone( triggerer_name, trigger_name ) 
  1188.    Players_in_unsafe_zone[triggerer_name] = true 
  1189.    mission_debug( "entered unsafe zone" ) 
  1190.  
  1191.    if ( C4_correct_detonation_counting_down == true ) then 
  1192.       local sync_type = sync_from_player( triggerer_name ) 
  1193.       mission_debug( "called create marker" ) 
  1194.  
  1195.       minimap_icon_add_navpoint_radius( GENERATOR_ROOM_UNSAFE_ZONE_TRIGGER, MINIMAP_ICON_LOCATION, 
  1196.                                         GENERATOR_ROOM_SAFE_ZONE_DIAMETER_METERS, nil, sync_type ) 
  1197.    end 
  1198. end 
  1199.  
  1200. function ss02_left_gen_room_unsafe_zone( triggerer_name, trigger_name ) 
  1201.    Players_in_unsafe_zone[triggerer_name] = false 
  1202.  
  1203.    mission_debug( "left unsafe zone" ) 
  1204.  
  1205.    if ( C4_correct_detonation_counting_down == true ) then 
  1206.       local sync_type = sync_from_player( triggerer_name ) 
  1207.       mission_debug( "called remove marker" ) 
  1208.  
  1209.       minimap_icon_remove_navpoint( GENERATOR_ROOM_UNSAFE_ZONE_TRIGGER, sync_type ) 
  1210.    end 
  1211. end 
  1212.  
  1213. -- Displays the appropriate message for the local and remote player 
  1214. -- when they wander into the "Plant C4" trigger. 
  1215. -- 
  1216. function ss02_plant_c4_message( triggerer_name, trigger_name ) 
  1217.    if ( triggerer_name == LOCAL_PLAYER ) then 
  1218.       mission_help_table_nag( HT_PRESS_TO_PLANT_BOMB, "", "", SYNC_LOCAL ) 
  1219.    elseif ( triggerer_name == REMOTE_PLAYER ) then 
  1220.       mission_help_table_nag( HT_HAVE_BUDDY_PLANT_BOMB, "", "", SYNC_REMOTE ) 
  1221.    end 
  1222. end 
  1223.  
  1224. -- Clear the messages for the local or remote player 
  1225. -- when they wander out of the "Plant C4" trigger. 
  1226. -- 
  1227. function ss02_plant_c4_message_leave( triggerer_name, trigger_name ) 
  1228.    if ( triggerer_name == LOCAL_PLAYER ) then 
  1229.       mission_help_clear( SYNC_LOCAL ) 
  1230.    elseif ( triggerer_name == REMOTE_PLAYER ) then 
  1231.       mission_help_clear( SYNC_REMOTE ) 
  1232.    end 
  1233. end 
  1234.  
  1235. -- Callback function for the "Plant C4" trigger. 
  1236. -- Guides the player's actions correctly for 
  1237. -- planting C4. 
  1238. -- 
  1239. function ss02_plant_c4( triggerer_name, trigger_name ) 
  1240.    -- Only the local player can plant the C4. 
  1241.    if ( triggerer_name == LOCAL_PLAYER ) then 
  1242.       -- Stop the "You're running out of time!" messages. They are no longer relevant. 
  1243.       if ( Running_out_of_time_prompts_thread_handle ~= INVALID_THREAD_HANDLE ) then 
  1244.          thread_kill( Running_out_of_time_prompts_thread_handle ) 
  1245.          Running_out_of_time_prompts_thread_handle = INVALID_THREAD_HANDLE 
  1246.       end 
  1247.  
  1248.       local bomb_countdown_needs_changing = true 
  1249.       local time_remaining_ms = hud_timer_get_remainder( 0 ) 
  1250.       if ( time_remaining_ms < C4_POST_PLANT_DETONATION_TIME_MS ) then 
  1251.          bomb_countdown_needs_changing = false 
  1252.       end 
  1253.  
  1254.       -- Clear out the help messages 
  1255.       mission_help_clear( SYNC_ALL ) 
  1256.  
  1257.       -- Disable the player's controls and take control of 
  1258.       -- his character 
  1259.       player_controls_disable( triggerer_name ) 
  1260.  
  1261.       local old_equipped_item = inv_item_get_equipped_item( triggerer_name ) 
  1262.       inv_item_equip( nil, triggerer_name ) 
  1263.  
  1264.       move_to( triggerer_name, PLANT_C4_LOCATION, 1, true, false) 
  1265.       thread_yield() 
  1266.       Planting_C4 = true 
  1267. 		character_release_human_shield( triggerer_name ) 
  1268.       camera_look_through( PLANTING_BOMB_VIEW, 0 ) 
  1269.       crouch_start( triggerer_name )		 
  1270.       group_create_hidden( MP.."Bomb" ) 
  1271.       audio_play_for_character( PLANT_BOMB_LINE, triggerer_name, "voice", false, false ) 
  1272.  
  1273.       -- If the player's modifying the bomb countdown timer, then do the 
  1274.       -- plant bomb animation 
  1275.       if ( bomb_countdown_needs_changing ) then 
  1276.          hud_timer_pause( 0, true ) 
  1277.          set_animation_state( triggerer_name, STATE_PLANT_C4 ) 
  1278.          delay( PLANT_C4_TIME_SECONDS ) 
  1279.          clear_animation_state( triggerer_name ) 
  1280.       else 
  1281.          set_animation_state( triggerer_name, STATE_PLANT_C4 ) 
  1282.          delay( DROP_C4_TIME_SECONDS ) 
  1283.          clear_animation_state( triggerer_name ) 
  1284.       end 
  1285.       camera_end_look_through( true ) 
  1286.       group_show( MP.."Bomb" ) 
  1287.       crouch_stop( triggerer_name ) 
  1288.  
  1289.       delay( .5 ) 
  1290.       Planting_C4 = false 
  1291.       inv_item_equip( old_equipped_item, triggerer_name ) 
  1292.       player_controls_enable( triggerer_name ) 
  1293.       mission_help_table( HT_GET_CLEAR, "", "", SYNC_ALL ) 
  1294.  
  1295.  
  1296.       ss02_switch_state( MS_C4_PLANTED ) 
  1297.    end 
  1298. end 
  1299.  
  1300. -- This function is contrasted with ss02_failed_to_plant_c4_in_time, which causes 
  1301. -- the player to detonate and fail the mission. 
  1302. -- 
  1303. function ss02_c4_correct_detonation() 
  1304. 		audio_play_for_character( "SFX_SS05_EXP_DUSTLAB", LOCAL_PLAYER, "foley", false, false ) 
  1305. 		explosion_create( C4_EXPLOSION_NAME, PLANT_C4_TRIGGER, LOCAL_PLAYER, true ) 
  1306.  
  1307. 		group_hide( MP.."Bomb" ) 
  1308. 		minimap_icon_remove_navpoint( GENERATOR_ROOM_UNSAFE_ZONE_TRIGGER, SYNC_ALL ) 
  1309. 		for index, name in EXPLOSION_SIDE_NAMES do 
  1310. 			explosion_create( SIDE_EXPLOSION_NAME, name, LOCAL_PLAYER, true ) 
  1311. 		end 
  1312.  
  1313. 		if ( Players_in_unsafe_zone[LOCAL_PLAYER] ) then 
  1314. 			character_kill( LOCAL_PLAYER ) 
  1315. 			character_ragdoll( LOCAL_PLAYER, 100 ) 
  1316. 		end 
  1317. 		if ( Players_in_unsafe_zone[REMOTE_PLAYER] ) then 
  1318. 			character_kill( REMOTE_PLAYER ) 
  1319. 			character_ragdoll( REMOTE_PLAYER, 100 ) 
  1320. 		end 
  1321.  
  1322. 		-- If at least one of the currently playing players is outside of the 
  1323. 		-- unsafe zone and therefore safe, set the checkpoint 
  1324. 		if ( ss02_all_players_in_unsafe_zone() == false ) then 
  1325. 			mission_set_checkpoint( DETONATED_C4_CHECKPOINT ) 
  1326. 		end 
  1327.  
  1328. 		C4_correct_detonation_counting_down = false 
  1329.  
  1330. 		delay( 1.0 ) 
  1331.  
  1332. 		-- Add smoke on the generator box 
  1333. 		Smoke_effect_handle = effect_play( GENERATOR_BOX_SMOKE_EFFECT_NAME, GENERATOR_BOX_NAVPOINT_NAME, true ) 
  1334.  
  1335. 		thread_kill( Generator_guard_patrol_thread ) 
  1336.  
  1337. 		ss02_do_prison_blackout() 
  1338.  
  1339. 		hud_timer_stop(0) 
  1340. 		notoriety_force_no_spawn( PRISON_DEFENDER_TEAM, false ) 
  1341. 		ss02_switch_state( MS_PRISON_RIOT ) 
  1342. end 
  1343.  
  1344. function ss02_do_prison_blackout() 
  1345.    prison_blackout_start() 
  1346.    thread_new( "ss02_run_window_blackout" ) 
  1347.    thread_new( "ss02_run_zone_blackout" ) 
  1348. end 
  1349.  
  1350. -- Plays the blackout for the windows in the prison. 
  1351. -- 
  1352. function ss02_run_window_blackout() 
  1353.  
  1354.    local delay_seconds_per_update = PRISON_WINDOW_BLACKOUT_TIME_SECONDS / PRISON_WINDOW_NUM_UPDATES 
  1355.    local cur_blackout_threshold = START_WINDOW_BLACKOUT_THRESHOLD 
  1356.    local blackout_reduction_per_update = cur_blackout_threshold / PRISON_WINDOW_NUM_UPDATES 
  1357.  
  1358.    for i = 1, PRISON_WINDOW_NUM_UPDATES do 
  1359.       cur_blackout_threshold = cur_blackout_threshold - blackout_reduction_per_update 
  1360.       mission_debug( "setting threshold to "..cur_blackout_threshold ) 
  1361.       prison_blackout_set_window_threshold( cur_blackout_threshold ) 
  1362.       delay( delay_seconds_per_update ) 
  1363.    end 
  1364.  
  1365.    mission_debug( "setting threshold to 0" ) 
  1366.    prison_blackout_set_window_threshold( 0 ) 
  1367. end 
  1368.  
  1369. -- Plays the blackout for trigger zones in the prison. 
  1370. -- 
  1371. function ss02_run_zone_blackout() 
  1372.    for step_index, sequence_step in pairs( PRISON_ZONE_BLACKOUT_SEQUENCE ) do 
  1373.       delay( sequence_step[PZ_BLACKOUT_TIME_INDEX] ) 
  1374.       prison_blackout_nuke_zone( sequence_step[PZ_BLACKOUT_ZONE_NAME_INDEX] ) 
  1375.    end 
  1376. end 
  1377.  
  1378. -- These five functions keep track of where the players are in relation 
  1379. -- to the inside of the coal tunnels. 
  1380. -- 
  1381. function ss02_left_threshold( triggerer_name, trigger_name ) 
  1382.    if ( Players_in_inside[triggerer_name] == true ) then 
  1383.       Players_in_coal_tunnels[triggerer_name] = true 
  1384.       ss02_switch_state( MS_PLANT_C4 ) 
  1385.    elseif ( Players_in_outside[ triggerer_name] == true ) then 
  1386.       Players_in_coal_tunnels[triggerer_name] = false 
  1387.    end 
  1388. end 
  1389.  
  1390. function ss02_entered_inside( triggerer_name, trigger_name ) 
  1391.    Players_in_inside[triggerer_name] = true 
  1392.    if  ( Prison_guard_spawned == false ) then 
  1393.       notoriety_force_no_spawn( PRISON_DEFENDER_TEAM, true ) 
  1394.       notoriety_set_min( PRISON_DEFENDER_TEAM, 1 ) 
  1395.       mission_help_table( HT_PLANT_C4_ON_TURBINE ) 
  1396.       group_show( GENERATOR_GUARD_GROUP_NAME ) 
  1397.       Generator_guard_patrol_thread = thread_new( "ss02_generator_guard_patrol" ) 
  1398.       Prison_guard_spawned = true 
  1399.    end 
  1400. end 
  1401.  
  1402. function ss02_left_inside( triggerer_name, trigger_name ) 
  1403.    Players_in_inside[triggerer_name] = false 
  1404. end 
  1405.  
  1406. function ss02_entered_outside( triggerer_name, trigger_name ) 
  1407.    Players_in_outside[triggerer_name] = true 
  1408. end 
  1409.  
  1410. function ss02_left_outside( triggerer_name, trigger_name ) 
  1411.    Players_in_outside[triggerer_name] = false 
  1412. end 
  1413.  
  1414. -- Used to let the player know that the outside of the generator room is locked. 
  1415. -- 
  1416. function ss02_attempt_open_locked_generator_room_exit_door( triggerer_name, trigger_name ) 
  1417.    local sync_type = sync_from_player( triggerer_name ) 
  1418.  
  1419.    mission_help_table( HT_DOOR_LOCKED, "", "", sync_type ) 
  1420. end 
  1421.  
  1422. -- Called when the player lets the C4 timer run out before planting the bomb. 
  1423. -- 
  1424. function ss02_failed_to_plant_c4_in_time() 
  1425.    if ( Planting_C4 ) then 
  1426.       camera_end_look_through( true ) 
  1427.  
  1428.       clear_animation_state( LOCAL_PLAYER ) 
  1429.  
  1430.       player_controls_enable( LOCAL_PLAYER ) 
  1431.    end 
  1432.  
  1433.    explosion_create( C4_EXPLOSION_NAME, LOCAL_PLAYER ) 
  1434.    character_kill( LOCAL_PLAYER ) 
  1435.  
  1436.    delay( TIME_TO_DIE_SECONDS ) 
  1437.  
  1438.    mission_end_failure( MISSION_NAME, HT_FAILED_TO_PLANT_BOMB_IN_TIME ) 
  1439. end 
  1440.  
  1441. -- Used to check to see if the player entered a boat to escape the prison. 
  1442. -- Switches the state to "Get to Laura's house" 
  1443. -- 
  1444. function ss02_player_entered_vehicle_escape( player_name, vehicle_name ) 
  1445.    local vehicle_type = get_char_vehicle_type( player_name ) 
  1446.    mission_debug( player_name.." entered vehicle" ) 
  1447.    if ( vehicle_type == VT_WATERCRAFT or vehicle_type == VT_AIRPLANE or vehicle_type == VT_HELICOPTER ) then 
  1448.       -- Clear the vehicle entrance callbacks 
  1449.       ss05_set_or_clear_escape_callbacks( false ) 
  1450.       marker_remove_vehicle( HELIPAD_HELICOPTER, SYNC_ALL ) 
  1451.  
  1452.       thread_new( "ss02_check_for_getting_away_start" ) 
  1453.       waypoint_remove( SYNC_ALL ) 
  1454.    end 
  1455. end 
  1456.  
  1457. function ss02_check_for_getting_away_start() 
  1458.    local vehicle_type 
  1459.    repeat 
  1460.       thread_yield() 
  1461.       vehicle_type = get_char_vehicle_type( Laura_leader_name ) 
  1462.    until ( character_is_in_vehicle( LAURA_NAME ) and 
  1463.            ( vehicle_type == VT_WATERCRAFT or vehicle_type == VT_AIRPLANE or vehicle_type == VT_HELICOPTER ) ) 
  1464.  
  1465.    mission_help_table( HT_ESCAPE_PRISON_AND_POLICE ) 
  1466.    thread_new( "ss02_laura_escape_driving_lines" ) 
  1467. end 
  1468.  
  1469. -- Plays lines for Laura randomly when the player's escaping from the prison island. 
  1470. -- 
  1471. function ss02_laura_escape_driving_lines() 
  1472. 	for index, line in pairs( RETURN_TO_STILWATER_LINES ) do 
  1473. 		local between_lines_delay = rand_float( BETWEEN_LINES_DELAY_MIN_SECONDS, BETWEEN_LINES_DELAY_MAX_SECONDS ) 
  1474. 		delay( between_lines_delay ) 
  1475. 		local vehicle_type 
  1476. 		repeat 
  1477. 			thread_yield() 
  1478. 	      vehicle_type = get_char_vehicle_type( LAURA_NAME ) 
  1479. 		until ( vehicle_type == VT_WATERCRAFT or vehicle_type == VT_AIRPLANE or vehicle_type == VT_HELICOPTER ) 
  1480.  
  1481. 		audio_play_for_character( line, LAURA_NAME, "voice", false, true ) 
  1482. 	end 
  1483. end 
  1484.  
  1485. -- Used to check to see if the player entered a boat to get to the prison. 
  1486. -- Switches the state to "Get to Prison" if so. 
  1487. -- 
  1488. function ss02_player_entered_vehicle_initial( player_name, vehicle_name ) 
  1489.    local vehicle_type = get_char_vehicle_type( player_name ) 
  1490.  
  1491.    if ( vehicle_type == VT_WATERCRAFT or vehicle_type == VT_AIRPLANE or vehicle_type == VT_HELICOPTER ) then 
  1492.       on_vehicle_enter( "", LOCAL_PLAYER ) 
  1493.       if ( coop_is_active() ) then 
  1494.          on_vehicle_enter( "", REMOTE_PLAYER ) 
  1495.       end 
  1496.  
  1497.       for index, watercraft_name in STARTER_WATERCRAFT_NAMES do 
  1498.          on_vehicle_enter( "", watercraft_name ) 
  1499.       end 
  1500.       marker_remove_vehicle( MARKED_WATERCRAFT, SYNC_ALL ) 
  1501.  
  1502.       ss02_switch_state( MS_GET_TO_PRISON ) 
  1503.    end 
  1504. end 
  1505.  
  1506. function ss02_cleanup() 
  1507. 	-- Cleanup mission here 
  1508.    on_vehicle_enter( "", LOCAL_PLAYER ) 
  1509.    if ( coop_is_active() ) then 
  1510.       on_vehicle_enter( "", REMOTE_PLAYER ) 
  1511.    end 
  1512.  
  1513.    on_district_changed( "", LOCAL_PLAYER ) 
  1514.    if ( coop_is_active() ) then 
  1515.       on_district_changed( "", REMOTE_PLAYER ) 
  1516.    end 
  1517.  
  1518.    mesh_mover_show( PRISON_GRATE_NAME ) 
  1519.    for index, barrel in pairs( PRISON_GRATE_BARRELS ) do 
  1520.       mesh_mover_show( barrel ) 
  1521.    end 
  1522.  
  1523.    if Smoke_effect_handle ~= INVALID_EFFECT_HANDLE then 
  1524.        effect_stop( Smoke_effect_handle ) 
  1525.    end 
  1526.    notoriety_set_min( PRISON_DEFENDER_TEAM, 0 ) 
  1527.  
  1528.    ss02_enable_gang_notoriety() 
  1529.  
  1530.    if ( camera_script_is_finished() == false ) then 
  1531.       camera_end_look_through() 
  1532.    end 
  1533.  
  1534.    if ( Mission_won ) then 
  1535.       group_destroy( ESCAPE_HELICOPTERS_GROUP_NAME ) 
  1536.       if ( coop_is_active() ) then 
  1537.          teleport( REMOTE_PLAYER, LAURAS_HOUSE_REMOTE_PLAYER_TELEPORT, true ) 
  1538.       end 
  1539.       teleport( LOCAL_PLAYER, LAURAS_HOUSE_TRIGGER_NAME, true ) 
  1540.    end 
  1541.  
  1542.    for index, door in DOORS_TO_LOCK do 
  1543.       door_lock( door, false ) 
  1544.    end 
  1545.    for index, door in PRISON_ENTRANCE_DOORS do 
  1546.       door_lock( door, false ) 
  1547.    end 
  1548.    for index, door in CAFETERIA_ENTRANCE_DOORS do 
  1549.       door_lock( door, false ) 
  1550.    end 
  1551.  
  1552.    door_lock( GENERATOR_ROOM_EXIT_DOOR, false ) 
  1553.    prison_blackout_restore_everything() 
  1554.  
  1555.    for index, door in pairs( LAURA_CELLBLOCK_DOORS ) do 
  1556.       door_lock( door, false ) 
  1557.       mesh_mover_show( door ) 
  1558.    end 
  1559.    parking_spot_enable( HELICOPTER_PARKING_SPAWN, true ) 
  1560.     
  1561.    hud_timer_stop(0) 
  1562.    city_chunk_swap( "sr2_intsrmisprison02", "normal", true, true, true ) 
  1563. 	ss02_stop_alarms() 
  1564. end 
  1565.  
  1566. function ss02_success() 
  1567. 	-- Called when the mission has ended with success 
  1568. end 
  1569.