sr2lua/ss06.lua

  1. -- ss06.lua 
  2. -- SR2 mission script 
  3. -- 3/28/07 
  4.  
  5. -- Mission help table text tags 
  6.    HT_GET_BACK_TO_HQ_OBJECTIVE = "ss06_get_back_to_HQ" 
  7.    HT_SHAUNDI_RUNNING_OUT_OF_TIME = "ss06_shaundi_running_out_of_time" 
  8.    HT_DEFEND_HQ_OBJECTIVE = "ss06_defend_HQ" 
  9.    HT_X_OF_Y_WAVES_DEFEATED = "ss06_x_of_y_waves_defeated" 
  10.    HT_SHAUNDI_DIED = "ss06_shaundi_died" 
  11.    HT_SHAUNDI_DIED_HIGHLIGHTED = "ss06_shaundi_died_highlighted" 
  12.    HT_PIERCE_DIED = "ss06_pierce_died" 
  13.    HT_PIERCE_DIED_HIGHLIGHTED = "ss06_pierce_died_highlighted" 
  14.    HT_SHAUNDI_ABANDONED = "ss06_shaundi_abandoned" 
  15.    HT_PIERCE_ABANDONED = "ss06_pierce_abandoned" 
  16.    HT_HELP_PIERCE = "ss06_help_pierce" 
  17.    HT_SAMEDI_GANG_MEMBERS_KILLED = "ss06_samedi_gang_members_killed" 
  18.    HT_RESCUE_SHAUNDI = "ss06_rescue_shaundi" 
  19.  
  20.    HT_SHAUNDI_HEALTH_BAR_LABEL = "ss06_shaundi_health_bar_label" 
  21.    HT_PIERCE_HEALTH_BAR_LABEL = "ss06_pierce_health_bar_label" 
  22.    HT_RETURN_TO_HQ_DEFENSE_SECONDS_TEXT = "ss06_return_to_hideout_seconds" 
  23.    HT_LEFT_HQ_UNDEFENDED_FAILURE = "ss06_left_hq_undefended" 
  24.    HT_SECONDS_TO_REVIVE_HOMIE_TEXT = "ss06_seconds_to_revive_homie" 
  25.  
  26. -- Mission states 
  27.    MS_NONE = 1 
  28.    MS_BEGUN = 2 
  29.    MS_SPAWN_RESUMED = 3 
  30.    MS_SAVED_SHAUNDI = 4 
  31.    MS_KILL_DRIVEUP_ATTACKERS = 5 
  32.    MS_PIERCE_APPEARS = 6 
  33.    MS_DEFENDING_HQ = 7 
  34.    MS_FAILURE = 8 
  35.  
  36. -- Checkpoints 
  37.    CP_SAVED_SHAUNDI = "Saved Shaundi" 
  38.  
  39. -- Groups, NPCs, vehicles, navpoints, and other names 
  40.    -- Mission constant names 
  41.    ENEMY_GANG = "samedi" 
  42.    MISSION_NAME = "ss06" 
  43.    MP = MISSION_NAME.."_$" 
  44.    CLOSEST_PLAYER = "#PLAYER#" 
  45.  
  46.    -- Groups 
  47.    NORTH_ROADBLOCK_NAME = MP.."North_Roadblock" 
  48.    SOUTH_ROADBLOCK_NAME = MP.."South_Roadblock" 
  49.    ON_FOOT_SQUAD_GROUP_NAMES = { MP.."On_foot_squad1", MP.."On_foot_squad2", MP.."On_foot_squad3" } 
  50.    ON_FOOT_SQUAD_GROUP_NAMES_COOP = { MP.."On_foot_squad1_coop", MP.."On_foot_squad2_coop", MP.."On_foot_squad3_coop" }    
  51.    ALT_ESCAPE_GROUP_NAME = MP.."Alt_Escape_Squad1" 
  52.    ALT_ESCAPE_COOP_GROUP_NAME = MP.."Alt_Escape_Squad1c" 
  53.  
  54.    MISSION_START_COLLISION_GROUP_NAME = MP.."Collision" 
  55.  
  56.    INITIAL_ATTACKERS_GROUP_NAME = MP.."Initial_Base_Attackers" 
  57.  
  58.    SHAUNDI_GROUP_NAME = MP.."Shaundi" 
  59.    SHAUNDI_ATTACKERS_GROUP_NAME = MP.."Shaundi_Attackers" 
  60.    HQ_GUN_SPAWN = MP.."HQ_Gun_Spawn" 
  61.  
  62.    ENTRANCE_REINFORCEMENTS_GROUP_NAME = MP.."Entrance_Reinforcements" 
  63.    PRE_PIERCE_REINFORCEMENTS_GROUP_NAME = MP.."Pre_Pierce_Reinforcements" 
  64.    PIERCE_GROUP_NAME = MP.."Pierce" 
  65.    PIERCE_PURSUIT_GROUP_NAME = MP.."Pierce_Pursuit" 
  66.  
  67.    -- Wave group prefix 
  68.    WAVE_GROUP = MP.."Wave" 
  69.    -- Example: Wave 4: 
  70.    -- WAVE_GROUP.."4" = "ss06_$Wave4" 
  71.  
  72.    FINAL_ATTACK_GROUP_NAME = MP.."Final_Attack_Wave" 
  73.  
  74.    -- NPC names 
  75.    SOUTH_CAMPER_NAMES = { MP.."South_Camper_01", MP.."South_Camper_02" } 
  76.    NORTH_CAMPER_NAMES = { MP.."North_Camper_01", MP.."North_Camper_02" } 
  77.  
  78.    ON_FOOT_SQUAD_1_MEMBERS = { MP.."On_foot_1_lead", MP.."On_foot_1_01", MP.."On_foot_1_02" } 
  79.    ON_FOOT_SQUAD_1C_MEMBERS = { MP.."On_foot_1c_lead" } 
  80.     
  81.    ON_FOOT_SQUAD_2_MEMBERS = { MP.."On_foot_2_lead", MP.."On_foot_2_01", MP.."On_foot_2_02" } 
  82.    ON_FOOT_SQUAD_2C_MEMBERS = { MP.."On_foot_2c_lead" } 
  83.  
  84.    ON_FOOT_SQUAD_3_MEMBERS = { MP.."On_foot_3_lead", MP.."On_foot_3_01", MP.."On_foot_3_02" } 
  85.    ON_FOOT_SQUAD_3C_MEMBERS = { MP.."On_foot_3c_lead" } 
  86.    ON_FOOT_SQUAD_MEMBERS = { ON_FOOT_SQUAD_1_MEMBERS, ON_FOOT_SQUAD_2_MEMBERS, ON_FOOT_SQUAD_3_MEMBERS } 
  87.    ON_FOOT_SQUAD_MEMBERS_COOP = { ON_FOOT_SQUAD_1C_MEMBERS, ON_FOOT_SQUAD_2C_MEMBERS, ON_FOOT_SQUAD_3C_MEMBERS } 
  88.  
  89.    ALT_ESCAPE_SQUAD_MEMBERS = { MP.."Alt_Escape_Squad1_01", MP.."Alt_Escape_Squad1_02", MP.."Alt_Escape_Squad1_03" } 
  90.    ALT_ESCAPE_COOP_MEMBERS = { MP.."Alt_Escape_Squad1c_01" } 
  91.  
  92.    COLLISION_CAR_MEMBERS = { { MP.."CM1_1" }, { MP.."CM2_1" }, { MP.."CM3_1" }, { MP.."CM4_1" }, { MP.."CM5_1" } } 
  93.  
  94.    INITIAL_BASE_ATTACKERS_MEMBERS = { MP.."Initial_01", MP.."Initial_02", MP.."Initial_03", MP.."Initial_04" } 
  95.    SHAUNDI_ATTACKERS_MEMBERS = { MP.."SA_01", MP.."SA_02", MP.."SA_03" } 
  96.    SHAUNDI_DIRECT_ATTACKERS = { SHAUNDI_ATTACKERS_MEMBERS[1], SHAUNDI_ATTACKERS_MEMBERS[2] } 
  97.    ENTRANCE_REINFORCEMENTS_MEMBERS = { MP.."ER_01", MP.."ER_02", MP.."ER_03", MP.."ER_04", MP.."ER_05" } 
  98.    PRE_PIERCE_SQUADS_MEMBERS = { { MP.."PP_S1_01", MP.."PP_S1_02", MP.."PP_S1_03" }, 
  99.                                  { MP.."PP_S2_01", MP.."PP_S2_02", MP.."PP_S2_03" } } 
  100.  
  101.    ENTRANCE_REINFORCEMENTS_DRIVERS = { MP.."ER_D1", MP.."ER_D2" } 
  102.  
  103.  
  104.    ENTRANCE_REINFORCEMENTS_V1_PASSENGERS = { ENTRANCE_REINFORCEMENTS_DRIVERS[1], ENTRANCE_REINFORCEMENTS_MEMBERS[1], 
  105.                                              ENTRANCE_REINFORCEMENTS_MEMBERS[2], ENTRANCE_REINFORCEMENTS_MEMBERS[3] } 
  106.    ENTRANCE_REINFORCEMENTS_V2_PASSENGERS = { ENTRANCE_REINFORCEMENTS_DRIVERS[2], ENTRANCE_REINFORCEMENTS_MEMBERS[4], 
  107.                                              ENTRANCE_REINFORCEMENTS_MEMBERS[5] } 
  108.  
  109.    ENTRANCE_REINFORCEMENT_VEHICLE_PASSENGERS = { ENTRANCE_REINFORCEMENTS_V1_PASSENGERS, 
  110.                                                  ENTRANCE_REINFORCEMENTS_V2_PASSENGERS } 
  111.  
  112.    PIERCE_NAME = MP.."Pierce" 
  113.  
  114.    PIERCE_PURSUIT_SQUADS_MEMBERS = { { MP.."Pursuit_S1_01", MP.."Pursuit_S1_02", MP.."Pursuit_S1_03" }, 
  115.                                      { MP.."Pursuit_S2_01", MP.."Pursuit_S2_02", MP.."Pursuit_S2_03" } } 
  116.  
  117.    SHAUNDI_NAME = MP.."Shaundi" 
  118.  
  119.    WAVE_COUNT = 10--2 Reduced by 1  
  120.    WAVES_SQUAD_COUNT = { 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 } 
  121.  
  122.    WAVES_SQUAD_MEMBER_COUNT = { { 4 }, { 4 }, 
  123.                                 { 2, 2 }, { 2, 2 }, { 2, 2 }, 
  124.                                 { 3, 2 }, { 3, 2 }, { 3, 2 }, { 3, 2 }, 
  125.                                 { 3, 3 }, { 3, 3 }, { 3, 3 } } 
  126.  
  127.    WAVES_IS_VEHICLE_SQUAD = { { true }, { false }, 
  128.                               { true, true }, { true, false }, { false, false }, 
  129.                               { true, true }, { true, false }, { false, false }, { false, true }, 
  130.                               { true, true }, { true, false }, { false, false } } 
  131.  
  132.    WAVE_VEHICLE_SQUAD_CHARGE = { { false }, { false }, 
  133.                                  { true, false }, { false, true }, { false, false }, 
  134.                                  { false, false }, { false, false }, { false, false }, { false, true }, 
  135.                                  { false, false }, { false, false }, { false, false } } 
  136.  
  137.    -- Wave prefix 
  138.    WAVE = MP.."W" 
  139.    -- Squad prefix 
  140.    SQUAD = "_S" 
  141.    -- Member index prefix 
  142.    MIP = "_0" 
  143.    -- Example: Wave 1, squad 2, member number 3: 
  144.    -- WAVE.."1"..SQUAD.."2"..MIP.."3" -> "ss06_$W1_S2_03" 
  145.  
  146.    -- Squad vehicle suffix 
  147.    VEHICLE = "_V" 
  148.    -- Example: Wave 3 squad 1 vehicle 
  149.    -- WAVE.."3"..SQUAD.."1"..VEHICLE 
  150.  
  151.    FINAL_ATTACK_MEMBER_NAMES = { MP.."FA_01", MP.."FA_02" } 
  152.    FINAL_ATTACK_VEHICLE_NAME = MP.."FA_V" 
  153.  
  154.    -- Weapons 
  155.    PISTOL = "beretta" 
  156.    SMG = "SKR-9" 
  157.    AK47 = "ak47" 
  158.    INITIAL_BASE_ATTACKERS_WEAPONS = { PISTOL, SMG, AK47, SMG } 
  159.    SHAUNDI_ATTACKERS_WEAPONS = { PISTOL, SMG, SMG } 
  160.    ENTRANCE_REINFORCEMENTS_WEAPONS = { PISTOL, SMG, AK47, SMG, AK47 } 
  161.    PRE_PIERCE_SQUADS_WEAPONS = { { PISTOL, SMG, AK47 }, { PISTOL, PISTOL, AK47 } } 
  162.    PIERCE_PURSUIT_SQUADS_WEAPONS = { { PISTOL, SMG, AK47 }, { PISTOL, PISTOL, AK47 } } 
  163.  
  164.    -- Vehicle names 
  165.    COLLISION_VEHICLE_NAMES = { MP.."CV1", MP.."CV2", MP.."CV3", MP.."CV4", MP.."CV5" } 
  166.  
  167.    ALT_ESCAPE_VEHICLE_NAME = MP.."Alt_Escape_v1" 
  168.  
  169.    ENTRANCE_REINFORCEMENTS_VEHICLES = { MP.."ER_V1", MP.."ER_V2" } 
  170.    PRE_PIERCE_VEHICLE_NAMES = { MP.."PrePierce_V1", MP.."PrePierce_V2" } 
  171.    PIERCE_PURSUIT_VEHICLE_NAMES = { MP.."Pierce_Pursuit_V1", MP.."Pierce_Pursuit_V2" } 
  172.    PIERCE_VEHICLE_NAME = MP.."Pierce_Car" 
  173.  
  174.    -- Navpoints 
  175.    START_NAVPOINT_NAME = "mission_start_sr2_city_$ss06" 
  176.    START_NAVPOINT_REMOTE_PLAYER_NAME = MP.."Start_Navpoint_Remote_Player" 
  177.    WS_WEST_STOP = MP.."Wave_Stop_04" 
  178.    WS_NORTH_STOP = MP.."Wave_Stop_03" 
  179.    WS_NORTHEAST_STOP = MP.."Wave_Stop_02" 
  180.    WS_SOUTH_STOP = MP.."Wave_Stop_01" 
  181.    WS_SOUTHEAST_STOP = MP.."Wave_Stop_02" 
  182.    ALT_ESCAPE_ATTACKER_STOP_NAVPOINT_NAME = MP.."Alt_Escape_Attacker_Stop_01" 
  183.  
  184.    ENTRANCE_REINFORCEMENTS_DROPOFF_POINTS = { MP.."ER_V1_Dropoff", MP.."ER_V2_Dropoff" } 
  185.    PRE_PIERCE_REINFORCEMENTS_VEHICLE_PATHS = { MP.."PrePierce_V1_Path", MP.."PrePierce_V2_Path" } 
  186.    ENTRANCE_REINFORCEMENTS_TO_HQ_PATH = MP.."ER_To_HQ_Path" 
  187.  
  188.    -- These are the goal points that the entrance reinforcements run to after arriving at the Saints HQ 
  189.    ENTRANCE_REINFORCEMENTS_GOAL_POINTS = { MP.."ER_Goal_01", MP.."ER_Goal_02", MP.."ER_Goal_03", 
  190.                                            MP.."ER_Goal_04", MP.."ER_Goal_05" } 
  191.  
  192.    ENTRANCE_REINFORCEMENTS_VEHICLE_EXIT_PATH = MP.."ER_Exit_Path" 
  193.    ENTRANCE_REINFORCEMENTS_VEHICLE_DEST = MP.."ER_Vehicle_Destination" 
  194.    PIERCE_FLEE_PATHS = { MP.."Pierce_Flee_Path", MP.."Pierce_Alt_Flee_Path" } 
  195.    PIERCE_PURSUIT_WARP_POINTS = { { PIERCE_PURSUIT_VEHICLE_NAMES[1], PIERCE_PURSUIT_VEHICLE_NAMES[2], PIERCE_VEHICLE_NAME }, 
  196.                                   { MP.."Pierce_Pursuit_V1_Alt_Spawn", MP.."Pierce_Pursuit_V2_Alt_Spawn", MP.."Pierce_Alt_Spawn" } } 
  197.  
  198.    PIERCE_SPAWN_LOCATIONS = { PIERCE_PURSUIT_WARP_POINTS[1][3], PIERCE_PURSUIT_WARP_POINTS[2][3] } 
  199.  
  200.    SAVED_SHAUNDI_CHECKPOINT_WARPS = { [LOCAL_PLAYER] = MP.."Saved_Shaundi_Checkpoint_Warp_Local", 
  201.                                       [REMOTE_PLAYER] = MP.."Saved_Shaundi_Checkpoint_Warp_Remote" } 
  202.  
  203.    -- Start positions for vehicle drive-in attack squads 
  204.    NORTHEAST_VEHICLE_START = MP.."NorthE_Vehicle_Start" 
  205.    NORTHWEST_VEHICLE_START = MP.."NorthW_Vehicle_Start" 
  206.    SOUTH_VEHICLE_START = MP.."South_Vehicle_Start" 
  207.    EAST_VEHICLE_START = MP.."East_Vehicle_Start" 
  208.    WEST_VEHICLE_START = MP.."West_Vehicle_Start" 
  209.    VEHICLE_START_POSITIONS = { NORTHEAST_VEHICLE_START, NORTHWEST_VEHICLE_START, SOUTH_VEHICLE_START, 
  210.                                EAST_VEHICLE_START, WEST_VEHICLE_START } 
  211.  
  212.    -- Paths that vehicle drive-in attack squads take to the HQ 
  213.    NORTHEAST_VEHICLE_PATH = MP.."NorthE_Vehicle_Path" 
  214.    NORTHWEST_VEHICLE_PATH = MP.."NorthW_Vehicle_Path" 
  215.    SOUTH_VEHICLE_PATH = MP.."South_Vehicle_Path" 
  216.    EAST_VEHICLE_PATH = MP.."East_Vehicle_Path" 
  217.    WEST_VEHICLE_PATH = MP.."West_Vehicle_Path" 
  218.    VEHICLE_DRIVE_UP_PATHS = { NORTHEAST_VEHICLE_PATH, NORTHWEST_VEHICLE_PATH, SOUTH_VEHICLE_PATH, 
  219.                               EAST_VEHICLE_PATH, WEST_VEHICLE_PATH } 
  220.  
  221.    -- Dropoff points that vehicle drive-in attack squads use 
  222.    NORTHEAST_DROPOFFS = { MP.."NorthE_Dropoff_01", MP.."NorthE_Dropoff_02" } 
  223.    NORTHWEST_DROPOFFS = { MP.."NorthW_Dropoff_01", MP.."NorthW_Dropoff_02", MP.."NorthW_Dropoff_03", MP.."NorthW_Dropoff_04" } 
  224.    SOUTH_DROPOFFS = { MP.."South_Dropoff_01", MP.."South_Dropoff_02", MP.."South_Dropoff_03" } 
  225.    EAST_DROPOFFS = { MP.."East_Dropoff_01", MP.."East_Dropoff_02", MP.."East_Dropoff_03", MP.."East_Dropoff_04" } 
  226.    WEST_DROPOFFS = { MP.."West_Dropoff_01", MP.."West_Dropoff_02", MP.."West_Dropoff_03" } 
  227.    VEHICLE_DROPOFF_POINTS = { NORTHEAST_DROPOFFS, NORTHWEST_DROPOFFS, SOUTH_DROPOFFS, 
  228.                               EAST_DROPOFFS, WEST_DROPOFFS } 
  229.  
  230.    -- Start positions for on-foot Samedi attackers 
  231.    NORTHEAST_RALLY_POINTS = { MP.."NorthE_On_Foot_Rally_01" } 
  232.    NORTHWEST_RALLY_POINTS = { MP.."NorthW_On_Foot_Rally_01", MP.."NorthW_On_Foot_Rally_02" } 
  233.    SOUTH_RALLY_POINTS = { MP.."South_On_Foot_Rally_01", MP.."South_On_Foot_Rally_02" } 
  234.    EAST_RALLY_POINTS = { MP.."East_On_Foot_Rally_01" } 
  235.    WEST_RALLY_POINTS = { MP.."West_On_Foot_Rally_01" } 
  236.    RALLY_POINTS = { NORTHEAST_RALLY_POINTS, NORTHWEST_RALLY_POINTS, SOUTH_RALLY_POINTS, 
  237.                     EAST_RALLY_POINTS, WEST_RALLY_POINTS } 
  238.  
  239.    -- Triggers 
  240.    SAINTS_HQ_POS = MP.."Saints_HQ_Position" 
  241.    START_TRIGGER_REGION_NAME = MP.."Starting_Box" 
  242.    START_TRIGGER_ANNEX_NAME = MP.."Starting_Box_Annex" 
  243.    ALTERNATE_ESCAPE_SPAWN_TRIGGER_NAME = MP.."Alternate_Escape_Spawn" 
  244.    SAINTS_HQ_AREA = MP.."Saints_HQ_Area" 
  245.    WAVE_STOP_WEST_TRIGGER = MP.."Wave_Stop_Trigger_West" 
  246.    WAVE_STOP_NORTH_TRIGGER = MP.."Wave_Stop_Trigger_North" 
  247.    WAVE_STOP_NORTHEAST_TRIGGER = MP.."Wave_Stop_Trigger_Northeast" 
  248.    WAVE_STOP_SOUTH_TRIGGER = MP.."Wave_Stop_Trigger_South" 
  249.    WAVE_STOP_SOUTHEAST_TRIGGER = MP.."Wave_Stop_Trigger_Southeast" 
  250.    SOUTH_TRIGGER_NAME = MP.."South_trigger" 
  251.    NORTH_TRIGGER_NAME = MP.."North_trigger" 
  252.    SOUTH_CAMPER_TRIGGER_NAME = MP.."South_Camper_Trigger" 
  253.    NORTH_CAMPER_TRIGGER_NAME = MP.."North_Camper_Trigger" 
  254.    SHAUNDI_BREADCRUMBS = { MP.."Shaundi_BC01", MP.."Shaundi_BC02" } 
  255.    REACHED_SHAUNDI_TRIGGER = MP.."Reached_Shaundi_Trigger" 
  256.    NEAR_PIERCE_TRIGGER_NAME = MP.."Near_Pierce_Trigger" 
  257.  
  258. 	SAINTS_HQ_UP_ELEVATOR_TRIGGER = "redlight_$SHQ_heli_elevator_up" 
  259. 	SAINTS_HQ_DOWN_ELEVATOR_TRIGGER = "redlight_$SHQ_heli_elevator_down" 
  260.  
  261.    -- Movers 
  262. 	HIDEOUT_ENTRANCE_DOORS = { MP.."Hideout_Entrance01", MP.."Hideout_Entrance02" } 
  263.  
  264.    -- Effects and animation states 
  265.  
  266.    -- Cutscenes 
  267.    CT_INTRO = "ss06-01" 
  268.    CT_OUTRO = "ss06-02" 
  269. -- Sound 
  270.    -- Persona overrides 
  271.    SHAUNDI_COMBAT_PERSONA_SITUATION = "custom line 1" 
  272.    PIERCE_COMBAT_PERSONA_SITUATION = "custom line 1" 
  273.    PLAYER_COMBAT_PERSONA_SITUATION = "custom line 1" 
  274.  
  275.    SHAUNDI_PERSONA_OVERRIDES = 
  276.    { 
  277.    { "hostage - barters", "SOS06_SHAUNDI_BARTER" }, 
  278.    { "misc - respond to player taunt w/taunt", "SOS06_SHAUNDI_TAUNT" }, 
  279.    { "observe - praised by pc", "SOS06_SHAUNDI_PRAISED" }, 
  280.    { "threat - alert (group attack)", "SOS06_SHAUNDI_ATTACK" }, 
  281.    { "threat - alert (solo attack)", "SOS06_SHAUNDI_ATTACK" }, 
  282.    { "threat - damage received (firearm)", "SOS06_SHAUNDI_TAKEDAM" }, 
  283.    { "threat - damage received (melee)", "SOS06_SHAUNDI_TAKEDAM" }, 
  284.    { SHAUNDI_COMBAT_PERSONA_SITUATION, "SHAUNDI_SOS6_COMBAT" } 
  285.    } 
  286.    PIERCE_PERSONA_OVERRIDES =  
  287.    { 
  288.    { PIERCE_COMBAT_PERSONA_SITUATION, "PIERCE_SOS6_COMBAT" } 
  289.    } 
  290.    PLAYER_PERSONA_OVERRIDES = 
  291.    { 
  292.    { PLAYER_COMBAT_PERSONA_SITUATION, "PLAYER_SOS6_COMBAT" } 
  293.    } 
  294.  
  295.    SS06_SAINTS_PERSONAS = { 
  296.       ["AM_TSS2"]	=	"AMTSS2", 
  297.       ["AM_TSS3"]	=	"AMTSS3", 
  298.  
  299.       ["BM_TSS1"]	=	"BMTSS1", 
  300.       ["BM_TSS2"]	=	"BMTSS2", 
  301.  
  302.       ["BF_TSS1"]	=	"BFTSS1", 
  303.       ["BF_TSS2"]	=	"BFTSS2", 
  304.  
  305.       ["HM_TSS1"]	=	"HMTSS1", 
  306.       ["HM_TSS2"]	=	"HMTSS2", 
  307.       ["HM_TSS3"]	=	"HMTSS3", 
  308.  
  309.       ["HF_TSS3"]	=	"HFTSS3", 
  310.  
  311.       ["WM_TSS2"]	=	"WMTSS2", 
  312.       ["WM_TSS3"]	=	"WMTSS3", 
  313.  
  314.       ["WF_TSS1"]	=	"WFTSS1", 
  315.       ["WF_TSS2"]	=	"WFTSS2", 
  316.       ["WF_TSS3"]	=	"WFTSS3", 
  317.    } 
  318.  
  319.    -- Lines/Dialog Stream 
  320.    INITIAL_PHONE_CALL_DIALOG_STREAM = { { "SOS6_PHONECALL_L1", nil, 0 }, 
  321.                                         { "PLAYER_SOS6_PHONECALL_L2", LOCAL_PLAYER, 0 }, 
  322.                                         { "SOS6_PHONECALL_L3", nil, 0 }, 
  323.                                         { "PLAYER_SOS6_PHONECALL_L4", LOCAL_PLAYER, 0 }, 
  324.                                         { "SOS6_PHONECALL_L5", nil, 0 } } 
  325.    MISSION_END_DIALOG_STREAM = { { "SOS6_END_L1", SHAUNDI_NAME, 0 }, 
  326.                                  { "SOS6_END_L2", PIERCE_NAME, 0 }, 
  327.                                  { "PLAYER_SOS6_END_L3", LOCAL_PLAYER, 0 } } 
  328.  
  329.    SAVED_SHAUNDI_DIALOG_LINE = "SHAUNDI_SOS6_CHECKPOINT_01" 
  330.    SAVED_PIERCE_DIALOG_LINE = "PIERCE_SOS6_ARRIVE_01" 
  331.  
  332.    SHAUNDI_COMBAT_LINES = "SHAUNDI_SOS6_COMBAT" 
  333.    PIERCE_COMBAT_LINES = "PIERCE_SOS6_COMBAT" 
  334.    PLAYER_COMBAT_LINES = "PLAYER_SOS6_COMBAT" 
  335.  
  336.    -- Sound effects 
  337.  
  338. -- Distances 
  339.    SAINTS_HQ_TRIGGER_RADIUS_METERS = 40 
  340.    SAINTS_HQ_AREA_RADIUS_METERS = 53.5 
  341.    PIERCE_LEASH_DISTANCE = 10.1 
  342.  
  343. -- Percents and multipliers 
  344.    DRUNK_EFFECT_MAGNITUDE = 0.75 
  345.    WEED_EFFECT_MAGNITUDE = 1.0 
  346.  
  347.    PER_STATE_HAZE_MULTIPLIERS = { 1.0, 0.75, 0.30, 0.20, 0.15, 0.00, 0.00, 0.00, 0.00 } 
  348.    PER_STATE_WEED_MULTIPLIERS = { 1.0, 0.90, 0.80, 0.50, 0.50, 0.45, 0.45, 0.45, 0.45 } 
  349.    -- This is the range for the number of chunks the life timers will be divided into. 
  350.    -- The exact numbers are randomly chosen from within this range. 
  351.    GET_TO_HQ_DIVISION_RANGE = { 5, 5 } 
  352.    SAVE_PIERCE_DIVISION_RANGE = { 5, 5 } 
  353.  
  354.    -- How far below the average percent for chunks the max size is allowed to be 
  355.    -- Between and 0 and 1. If it's one, then the chunks will all be the same size. 
  356.    HEALTH_CHUNK_MIN_MULTIPLIER = 0.50 
  357.    TIME_CHUNK_MIN_MULTIPLIER = 0.50 
  358.    -- How far above the average percent for chunks the max size is allowed to be 
  359.    -- Between and 0 and 1. If it's zero, then all chunks will be the same size. 
  360.    HEALTH_CHUNK_MAX_MULTIPLIER = 0.50 
  361.    TIME_CHUNK_MAX_MULTIPLIER = 0.50 
  362.  
  363. -- Constant values and counts 
  364.    MISSION_START_NOTORIETY = 3 
  365.    MISSION_MIN_NOTORIETY = 3 
  366.    MISSION_MAX_NOTORIETY = 4 
  367.    GAME_MAX_NOTORIETY = 5 
  368.    ATTACK_CAR_OVERRIDE_SPEED = 70.0 
  369.  
  370.    INITIAL_ATTACK_SQUAD = 1 
  371.    SOUTH_ATTACK_SQUAD = 2 
  372.    NORTH_ATTACK_SQUAD = 3 
  373.  
  374.    LOCAL_PLAYER_INDEX = 1 
  375.    REMOTE_PLAYER_INDEX = 2 
  376.  
  377.    ENTRANCE_REINFORCEMENTS_REMAINING_THRESHOLD = 2 
  378.    PRE_PIERCE_ATTACKERS_REMAINING_THRESHOLD = 3 
  379.    ATTACKS_REMAINING_SPAWN_NEW_WAVE_THRESHOLD = 4 
  380.  
  381.    VEHICLE_DRIVE_UP_DIRECTION_COUNT = sizeof_table( VEHICLE_START_POSITIONS ) 
  382.    RALLY_POINT_DIRECTION_COUNT = sizeof_table( RALLY_POINTS ) 
  383.  
  384.    -- Trigger options 
  385.    TRIGGER_ONCE_FIRST_TRIGGERER = 1 
  386.    TRIGGER_ONCE_PER_PLAYER = 2 
  387.    TRIGGER_MULTIPLE_TIMES = 3 
  388.    -- End trigger options 
  389.  
  390.    -- Wave and squad index of the tow truck 
  391.    TOW_TRUCK_INDEX = { 5, 2 } 
  392.  
  393. -- Time values 
  394.    DRUG_EFFECT_STATE_SWITCH_REDUCTION_TIME_SECONDS = 30.0 
  395.    NOTORIETY_BACK_TO_MIN_SECONDS = 30 
  396.    NOTORIETY_BACK_TO_MIN_INCREASE_PER_SECOND = MISSION_MIN_NOTORIETY / NOTORIETY_BACK_TO_MIN_SECONDS 
  397.    BETWEEN_WAVE_DELAY_RANGE_SECONDS = { 2.0, 3.0 } 
  398.    function get_between_wave_delay() 
  399.       return rand_float( BETWEEN_WAVE_DELAY_RANGE_SECONDS[1], BETWEEN_WAVE_DELAY_RANGE_SECONDS[2] ) 
  400.    end 
  401.    BETWEEN_SQUADS_COOP_DELAY_SECONDS = 12.0 
  402.    BETWEEN_SQUADS_DELAY_SECONDS = 8.0 
  403.  
  404.    FAILURE_TIMEOUT_ON_LEAVE_DEFENSE_AREA_SECONDS = 30 
  405.    GET_TO_HQ_TIME_SECONDS = 120.0 
  406.    BEFORE_CELLPHONE_CALL_DELAY = 2.0 
  407.    AFTER_CELLPHONE_CALL_DELAY = 5.0 
  408.    RESET_OBJECTIVE_TIME_SECONDS = 3.0 
  409.    WIN_DELAY_SECONDS = 2.0 
  410.    FADE_IN_SECONDS = 2.0 
  411.    INVALID_TIMER_VALUE = -1 
  412.    WAVE_ANNOUNCE_DELAY_SECONDS = 6 
  413.    SAVE_PIERCE_TIME_SECONDS = 30 
  414.    FREE_UP_VEHICLE_TELEPORT_LOCATION_DELAY_SECONDS = 5 
  415.  
  416. -- Global variables 
  417.    Process_thread_handle = 0 
  418.    Current_mission_state = MS_NONE 
  419.    Cur_attack_wave = 0 
  420.    Players_arrived = { false, false } 
  421.    Players_south_trigger = { false, false } 
  422.    Players_north_trigger = { false, false } 
  423.  
  424.    Players_in_starting_box = { true, true } 
  425.    Players_in_annex = { false, false } 
  426.  
  427.    Players_in_defense_area = { false, false } 
  428.    Players_near_Pierce = { [LOCAL_PLAYER] = false, [REMOTE_PLAYER] = false } 
  429.    Player_failure_timer_thread_handles = { [LOCAL_PLAYER] = INVALID_THREAD_HANDLE, [REMOTE_PLAYER] = INVALID_THREAD_HANDLE } 
  430.  
  431.    Waiting_on_wave_spawn = true 
  432.  
  433.    Cur_haze_multiplier = PER_STATE_HAZE_MULTIPLIERS[1] 
  434.    Cur_weed_multiplier = PER_STATE_WEED_MULTIPLIERS[1] 
  435.  
  436.    Cur_wave_vehicle_count = 0 
  437.    Cur_wave_vehicle_names = {} 
  438.    Cur_wave_driver_names = {} 
  439.    Cur_wave_coop_vehicle_count = 0 
  440.    Cur_wave_coop_vehicle_names = {} 
  441.    Cur_wave_coop_driver_names = {} 
  442.  
  443.    Health_timer_cur_bar_values = {} 
  444.  
  445.    Shaundi_health_timer_thread_handle = INVALID_THREAD_HANDLE 
  446.    Pierce_health_timer_thread_handle = INVALID_THREAD_HANDLE 
  447.    Initial_base_attackers_remaining = sizeof_table( INITIAL_BASE_ATTACKERS_MEMBERS ) 
  448.    Shaundi_attackers_remaining = sizeof_table( SHAUNDI_ATTACKERS_MEMBERS ) 
  449.    Shaundi_direct_attackers_remaining = sizeof_table( SHAUNDI_DIRECT_ATTACKERS ) 
  450.    Entrance_reinforcements_remaining = sizeof_table( ENTRANCE_REINFORCEMENTS_MEMBERS ) 
  451.    Pre_Pierce_reinforcements_remaining = sizeof_table( PRE_PIERCE_SQUADS_MEMBERS[1] ) + 
  452.                                          sizeof_table( PRE_PIERCE_SQUADS_MEMBERS[2] ) 
  453.    Total_attackers_remaining = 0 
  454.    Num_attackers_killed_by_player = { [LOCAL_PLAYER] = 0, [REMOTE_PLAYER] = 0 } 
  455.    Cur_attack_wave_index = 1 
  456.  
  457.    -- 'Timer' variables 
  458.    Reset_objective_time_remaining_seconds = RESET_OBJECTIVE_TIME_SECONDS 
  459.    Drug_effect_reduction_time_remaining_seconds = DRUG_EFFECT_STATE_SWITCH_REDUCTION_TIME_SECONDS 
  460.    Win_delay_seconds = WIN_DELAY_SECONDS 
  461.  
  462.    -- Dropoff point used/not used data 
  463.    Northeast_dropoffs_used = { false, false } 
  464.    Northwest_dropoffs_used = { false, false, false, false } 
  465.    South_dropoffs_used = { false, false, false } 
  466.    East_dropoffs_used = { false, false, false, false } 
  467.    West_dropoffs_used = { false, false, false } 
  468.    Dropoffs_used = { Northeast_dropoffs_used, Northwest_dropoffs_used, South_dropoffs_used, 
  469.                      East_dropoffs_used, West_dropoffs_used } 
  470.  
  471.    Vehicle_teleport_locations_used = { false, false, false, false, false } 
  472.  
  473.    Northeast_rally_points_used = { false } 
  474.    Northwest_rally_points_used = { false, false } 
  475.    South_rally_points_used = { false, false } 
  476.    East_rally_points_used = { false } 
  477.    West_rally_points_used = { false } 
  478.    Rally_points_used = { Northeast_rally_points_used, Northwest_rally_points_used, South_rally_points_used, 
  479.                          East_rally_points_used, West_rally_points_used } 
  480.  
  481.    Wave_currently_spawning = false 
  482.    Shaundi_saved = false 
  483.    Pierce_needs_to_be_rescued = false 
  484.    Final_attack_wave_started = false 
  485.  
  486.    Last_vehicle_direction_used = -1 
  487.    Player_with_Shaundi = LOCAL_PLAYER 
  488.    Shaundi_call_received = false 
  489.    Shaundi_call_complete = false 
  490.    Marked_member_names = {} 
  491.  
  492. -- Direction points query function - are there unused points 
  493. -- in this or that direction? 
  494. -- 
  495. -- direction_points_used: One of the arrays listing used or 
  496. --                        unused points. 
  497. -- 
  498. function ss06_some_points_unused( direction_points_used ) 
  499.    for index, used in pairs( direction_points_used ) do 
  500.       -- If any are unused, return true 
  501.       if ( used == false ) then 
  502.          return true 
  503.       end 
  504.    end 
  505.  
  506.    -- Otherwise, return false - no unused ones were found 
  507.    return false 
  508. end 
  509.  
  510. function ss06_remove_group_required_kill_markers( group_members ) 
  511.    for index, member_name in pairs( group_members ) do 
  512.       if ( ss06_character_has_been_released( member_name ) == false ) then 
  513.          if ( Marked_member_names[member_name] == true ) then 
  514.             marker_remove_npc( member_name, SYNC_ALL ) 
  515.             Marked_member_names[member_name] = false 
  516.          end 
  517.       end 
  518.    end 
  519. end 
  520.  
  521. function ss06_add_group_required_kill_markers( group_members ) 
  522.    for index, member_name in pairs( group_members ) do 
  523.       if ( ss06_character_has_been_released( member_name ) == false ) then 
  524.          marker_add_npc( member_name, MINIMAP_ICON_KILL, INGAME_EFFECT_KILL, SYNC_ALL ) 
  525.          Marked_member_names[member_name] = true 
  526.       end 
  527.    end 
  528. end 
  529.  
  530. function ss06_delay_then_free_directions( vehicle_directions_used ) 
  531.    delay( FREE_UP_VEHICLE_TELEPORT_LOCATION_DELAY_SECONDS ) 
  532.  
  533.    for squad_index, direction in pairs( vehicle_directions_used ) do 
  534.       Vehicle_teleport_locations_used[direction] = false 
  535.    end 
  536. end 
  537.  
  538. function ss06_spawn_next_attack_wave() 
  539.    -- Do not spawn a new wave until the current one is done spawning 
  540.    while ( Wave_currently_spawning ) do 
  541.       thread_yield() 
  542.    end 
  543.    Wave_currently_spawning = true 
  544.  
  545.    -- Keep spawning attack cycles until we reach the max count 
  546.    if ( Cur_attack_wave_index <= WAVE_COUNT ) then 
  547.       -- Create the group, first of all 
  548.       group_create( WAVE_GROUP..Cur_attack_wave_index, true ) 
  549.       local cur_wave_squad_count = WAVES_SQUAD_COUNT[Cur_attack_wave_index] 
  550.       local cur_squads_in_vehicles = WAVES_IS_VEHICLE_SQUAD[Cur_attack_wave_index] 
  551.  
  552.       --mission_debug( "Creating wave "..Cur_attack_wave_index..". "..cur_wave_squad_count.." squads." ) 
  553.  
  554.       local squad_attack_threads = {} 
  555.       local vehicle_directions_used = {} 
  556.  
  557.       for squad_index = 1, cur_wave_squad_count do 
  558.          local squad_member_count = WAVES_SQUAD_MEMBER_COUNT[Cur_attack_wave_index][squad_index] 
  559.          Total_attackers_remaining = Total_attackers_remaining + squad_member_count 
  560.  
  561.          if ( cur_squads_in_vehicles[squad_index] ) then 
  562.             local direction, goal = ss06_find_attack_direction_and_attack_point( VEHICLE_DROPOFF_POINTS, Dropoffs_used, 
  563.                                                                                  VEHICLE_DRIVE_UP_DIRECTION_COUNT, true ) 
  564.             squad_attack_threads[squad_index] = thread_new( "ss06_spawn_and_path_vehicle_squad", 
  565.                                                             Cur_attack_wave_index, squad_index, squad_member_count, direction, goal ) 
  566.             vehicle_directions_used[squad_index] = direction 
  567.          else 
  568.             squad_attack_threads[squad_index] = thread_new( "ss06_spawn_and_attack_on_foot_squad", 
  569.                                                             Cur_attack_wave_index, squad_index, squad_member_count ) 
  570.          end 
  571.       end 
  572.  
  573.       -- We've teleported this wave - the next wave should be free to use these locations 
  574.       thread_new( "ss06_delay_then_free_directions", vehicle_directions_used ) 
  575.       for index, used in pairs( Vehicle_teleport_locations_used ) do 
  576.          Vehicle_teleport_locations_used[index] = false 
  577.       end 
  578.  
  579.       -- Wait for all of the attack threads to complete 
  580.       local attack_threads_complete = false 
  581.       while ( attack_threads_complete == false ) do 
  582.          attack_threads_complete = true 
  583.          for index, thread_handle in pairs( squad_attack_threads ) do 
  584.             if ( thread_check_done( thread_handle ) == false ) then 
  585.                attack_threads_complete = false 
  586.             end 
  587.          end 
  588.          thread_yield() 
  589.       end 
  590.  
  591.       -- Now that the threads are done, we're certainly done spawning, so move onto the next wave 
  592.       Cur_attack_wave_index = Cur_attack_wave_index + 1 
  593.       Wave_currently_spawning = false 
  594.  
  595.       local character_choice = rand_int( 1, 3 ) 
  596.       if ( character_choice == 1 ) then 
  597.          audio_play_persona_line( SHAUNDI_NAME, SHAUNDI_COMBAT_PERSONA_SITUATION ) 
  598.       elseif ( character_choice == 2 ) then 
  599.          audio_play_persona_line( PIERCE_NAME, PIERCE_COMBAT_PERSONA_SITUATION ) 
  600.       else 
  601.          audio_play_persona_line( LOCAL_PLAYER, PLAYER_COMBAT_PERSONA_SITUATION ) 
  602.       end 
  603.  
  604.    else 
  605.       ss06_spawn_final_attack_wave() 
  606.    end 
  607. end 
  608.  
  609. -- Gets the index of the first unused point based on a list of 
  610. -- points that have been used. 
  611. -- 
  612. function ss06_get_first_unused_point_index( points_used ) 
  613.    for index, point_used in pairs( points_used ) do 
  614.       if ( point_used == false ) then 
  615.          return index 
  616.       end 
  617.    end 
  618.    return 1 
  619. end 
  620.  
  621. -- Sets all the "used" flags to false. 
  622. -- Usually called when all points have been used once. 
  623. -- 
  624. function ss06_reset_used_states( used_states ) 
  625.    -- Go through each direction 
  626.    for used_in_direction_index, used_in_direction in pairs( used_states ) do 
  627.       -- For each direction, go through each "used" value 
  628.       for used_index, point_used in pairs( used_in_direction ) do 
  629.          used_states[used_in_direction_index][used_index] = false 
  630.       end 
  631.    end 
  632. end 
  633.  
  634. function ss06_create_attack_squad_member_names( wave_index, squad_index, squad_member_count ) 
  635.    -- Temp storage for the names 
  636.    local squad_members = {} 
  637.  
  638.    -- Calculate the prefix once 
  639.    local squad_member_prefix = WAVE..wave_index..SQUAD..squad_index..MIP 
  640.  
  641.    -- Create the list of member names 
  642.    for member_index = 1, squad_member_count do 
  643.       squad_members[member_index] = squad_member_prefix..member_index 
  644.    end 
  645.  
  646.    return squad_members 
  647. end 
  648.  
  649. -- Randomly selects an attack direction and an attack point based on whether 
  650. -- they've been used. 
  651. -- 
  652. -- location_values: A list of attack points. 
  653. -- used_value: A list of which attack points have been used. 
  654. -- direction_count: The number of attack directions. 
  655. -- is_vehicle_squad: (Optional, default false) Whether or not we're looking 
  656. --                   for a vehicle squad attack direction. 
  657. -- 
  658. function ss06_find_attack_direction_and_attack_point( location_points, used_values, direction_count, is_vehicle_squad ) 
  659.    if ( is_vehicle_squad == nil ) then 
  660.       is_vehicle_squad = false 
  661.    end 
  662.  
  663.    -- Randomly choose a search start for an unused direction 
  664.    local attack_direction = rand_int( 1, direction_count ) 
  665.    local unused_direction_found = false 
  666.  
  667.    -- Go through each direction once 
  668.    for i = 1, direction_count do 
  669.       if ( ss06_some_points_unused( used_values[attack_direction] ) ) then 
  670.          -- If this is a vehicle squad and this location is unused, we've found a valid direction, or 
  671.          -- if it isn't a vehicle squad we're also found one 
  672.          if ( ( is_vehicle_squad and Vehicle_teleport_locations_used[attack_direction] == false ) or 
  673.               ( is_vehicle_squad == false ) ) then 
  674.             unused_direction_found = true 
  675.             break 
  676.          end 
  677.       end 
  678.  
  679.       -- Go to the next value, possibly rolling over 
  680.       attack_direction = attack_direction + 1 
  681.       if ( attack_direction > direction_count ) then 
  682.          attack_direction = 1 
  683.       end 
  684.    end 
  685.  
  686.    -- Which point drop off at in this direction 
  687.    local point_index = 1 
  688.  
  689.    -- If we found a direction with unused dropoff points, then find the first unused point 
  690.    if ( unused_direction_found ) then 
  691.       point_index = ss06_get_first_unused_point_index( used_values[attack_direction] ) 
  692.    -- Otherwise, just set everything to unused, because everything has been used once 
  693.    else 
  694.       ss06_reset_used_states( used_values ) 
  695.  
  696.       -- Make sure we don't use the last used direction again 
  697.       if ( is_vehicle_squad and Last_vehicle_direction_used == attack_direction ) then 
  698.          attack_direction = attack_direction + 1 
  699.          if ( attack_direction > direction_count ) then 
  700.             attack_direction = 1 
  701.          end 
  702.       end 
  703.    end 
  704.     
  705.    -- If this is a vehicle squad, record the chosen direction 
  706.    -- and keep track of the used directions 
  707.    if ( is_vehicle_squad ) then 
  708.       Last_vehicle_direction_used = attack_direction 
  709.       Vehicle_teleport_locations_used[attack_direction] = true 
  710.    end 
  711.  
  712.    -- Record this particular point index in this direction as used 
  713.    used_values[attack_direction][point_index] = true 
  714.  
  715.    return attack_direction, location_points[attack_direction][point_index] 
  716. end 
  717.  
  718. -- Creates an on-foot attack squad and has it attack 
  719. -- 
  720. -- wave_index: Which wave this squad belongs to. A wave can have more than one squad. 
  721. -- squad_index: The index of this squad within the wave. 
  722. -- squad_member_count: The number of members in this squad. 
  723. -- 
  724. function ss06_spawn_and_attack_on_foot_squad( wave_index, squad_index, squad_member_count ) 
  725.    -- Create the squad member names 
  726.    local squad_members = ss06_create_attack_squad_member_names( wave_index, squad_index, 
  727.                                                                 squad_member_count ) 
  728.  
  729.    -- Teleport the squad to an attack location 
  730.    local direction, rally_point = ss06_find_attack_direction_and_attack_point( RALLY_POINTS, Rally_points_used, 
  731.                                                                                RALLY_POINT_DIRECTION_COUNT, true ) 
  732.  
  733.    -- First, add callbacks to prevent weirdness with death tracking 
  734.    for index, member_name in pairs( squad_members ) do 
  735.       on_death( "ss06_base_attacker_died", member_name ) 
  736.    end 
  737.  
  738.    -- Now, teleport the entire group to the rally point, and mark each as you 
  739.    -- teleport 
  740.    for index, member_name in pairs( squad_members ) do 
  741.       teleport( member_name, rally_point ) 
  742.       marker_add_npc( member_name, MINIMAP_ICON_KILL, INGAME_EFFECT_KILL, SYNC_ALL ) 
  743.       Marked_member_names[member_name] = true 
  744.       local distance, closest_player = get_dist_closest_player_to_object( member_name ) 
  745.  
  746.       attack_safe( member_name, closest_player, false ) 
  747.    end 
  748.  
  749.    --mission_debug( "Squad "..squad_index.." attacking on foot.") 
  750. end 
  751.  
  752. -- Creates a vehicle attack squad and has it drive up 
  753. -- 
  754. -- wave_index: Which wave this squad belongs to. A wave can have more than one squad. 
  755. -- squad_index: The index of this squad within the wave. 
  756. -- squad_member_count: The number of members in this squad. 
  757. -- direction: What attack direction this squad comes from 
  758. -- goal: The dropoff point goal of this squad 
  759. -- 
  760. function ss06_spawn_and_path_vehicle_squad( wave_index, squad_index, squad_member_count, direction, goal ) 
  761.  
  762.    -- Create the squad member names 
  763.    local squad_members = ss06_create_attack_squad_member_names( wave_index, squad_index, 
  764.                                                                 squad_member_count ) 
  765.    for index, member_name in pairs( squad_members ) do 
  766.       on_death( "ss06_base_attacker_died", member_name ) 
  767.    end 
  768.  
  769.    -- Create the vehicle's name 
  770.    local squad_vehicle = WAVE..wave_index..SQUAD..squad_index..VEHICLE 
  771.  
  772.    -- Seat the squad 
  773.    vehicle_enter_group_teleport( squad_members, squad_vehicle ) 
  774.  
  775.    -- Teleport the vehicle to the attack start location 
  776.    teleport_vehicle( squad_vehicle, VEHICLE_START_POSITIONS[direction] ) 
  777.  
  778.    -- Mark the NPCs now that they're in the correct location 
  779.    for index, member_name in pairs( squad_members ) do 
  780.       marker_add_npc( member_name, MINIMAP_ICON_KILL, INGAME_EFFECT_KILL, SYNC_ALL ) 
  781.       Marked_member_names[member_name] = true 
  782.    end 
  783.  
  784.    -- Drive from the start location along the attack direction path 
  785.    vehicle_pathfind_to( squad_vehicle, VEHICLE_DRIVE_UP_PATHS[direction], true, false ) 
  786.  
  787.    -- If we're not supposed to charge the player, just go to the goal and stop there 
  788.    if ( WAVE_VEHICLE_SQUAD_CHARGE[wave_index][squad_index] == false ) then 
  789.       mission_debug( "NOT charging the player", 10 ) 
  790.       vehicle_pathfind_to( squad_vehicle, goal, true, true ) 
  791.  
  792.       for index, member_name in pairs( squad_members ) do 
  793.          if ( ss06_character_has_been_released( member_name ) == false ) then 
  794.             vehicle_exit( member_name ) 
  795.          end 
  796.       end 
  797.    -- Otherwise, attack the closest player 
  798.    else 
  799.       mission_debug( "Charging the player", 10 ) 
  800.       local distance, player = get_dist_closest_player_to_object( squad_members[1] ) 
  801.       attack_safe( squad_members[1], player, false ) 
  802.    end 
  803.    release_to_world( squad_vehicle ) 
  804. end 
  805.  
  806. function ss06_cleanup() 
  807.    -- Cleanup mission here 
  808.    thread_kill( Process_thread_handle ) 
  809.    notoriety_set_min( ENEMY_GANG, 0 ) 
  810.    notoriety_set_max( ENEMY_GANG, GAME_MAX_NOTORIETY ) 
  811.    notoriety_set( ENEMY_GANG, 0 ) 
  812.    spawning_vehicles( true ) 
  813.    notoriety_force_no_spawn( ENEMY_GANG, false ) 
  814.    party_dismiss_all() 
  815.    party_set_dismissable( true ) 
  816.    party_allow_max_followers( false ) 
  817.    release_to_world( HQ_GUN_SPAWN ) 
  818.    drug_effect_set_override_values( 0, 0, SYNC_ALL ) 
  819.    drug_enable_disable_effect_override( false, SYNC_ALL ) 
  820.    minimap_icon_remove_navpoint( SAINTS_HQ_AREA, SYNC_ALL ) 
  821.    persona_override_group_stop( SS06_SAINTS_PERSONAS, POT_SITUATIONS[POT_ATTACK] ) 
  822.  
  823.    for index, override in pairs( PLAYER_PERSONA_OVERRIDES ) do 
  824.       persona_override_character_stop( LOCAL_PLAYER, override[1] ) 
  825.    end 
  826.  
  827. 	trigger_enable( SAINTS_HQ_UP_ELEVATOR_TRIGGER, true ) 
  828. 	trigger_enable( SAINTS_HQ_DOWN_ELEVATOR_TRIGGER, true ) 
  829.  
  830. 	trigger_type_enable( "warp", true ) 
  831.  
  832.    mid_mission_phonecall_reset() 
  833.    mission_cleanup_maybe_reenable_player_controls() 
  834. end 
  835.  
  836. function ss06_spawn_final_attack_wave() 
  837.    -- Create the group, update the number of attackers, and add on-death callbacks to assure that the 
  838.    -- mission progresses correctly 
  839.    group_create( FINAL_ATTACK_GROUP_NAME, true ) 
  840.    Total_attackers_remaining = Total_attackers_remaining + sizeof_table( FINAL_ATTACK_MEMBER_NAMES ) 
  841.  
  842.    for index, member_name in pairs( FINAL_ATTACK_MEMBER_NAMES ) do 
  843.       on_death( "ss06_base_attacker_died", member_name ) 
  844.    end 
  845.  
  846.    -- Seat the squad 
  847.    vehicle_enter_group_teleport( FINAL_ATTACK_MEMBER_NAMES, FINAL_ATTACK_VEHICLE_NAME ) 
  848.  
  849.    -- Get an attack direction and goal point 
  850.    local direction = ss06_find_attack_direction_and_attack_point( VEHICLE_DROPOFF_POINTS, Dropoffs_used, 
  851.                                                                   VEHICLE_DRIVE_UP_DIRECTION_COUNT ) 
  852.  
  853.    teleport_vehicle( FINAL_ATTACK_VEHICLE_NAME, VEHICLE_START_POSITIONS[direction] ) 
  854.  
  855.    -- Mark the NPCs now that they're in the correct location 
  856.    for index, member_name in pairs( FINAL_ATTACK_MEMBER_NAMES ) do 
  857.       marker_add_npc( member_name, MINIMAP_ICON_KILL, INGAME_EFFECT_KILL, SYNC_ALL ) 
  858.       Marked_member_names[member_name] = true 
  859.    end 
  860.  
  861.    -- Drive from the start location along the attack direction path 
  862.    vehicle_pathfind_to( FINAL_ATTACK_VEHICLE_NAME, VEHICLE_DRIVE_UP_PATHS[direction], true, false ) 
  863.  
  864.    -- Have the vehicle attack the player 
  865.    local distance, player = get_dist_closest_player_to_object( FINAL_ATTACK_MEMBER_NAMES[1] ) 
  866.    attack_safe( FINAL_ATTACK_MEMBER_NAMES[1], player, false ) 
  867.     
  868.    Final_attack_wave_started = true 
  869. end 
  870.  
  871. function ss06_start( checkpoint_name, is_restart ) 
  872.    -- Start trigger is hit...the activate button was hit 
  873.    set_mission_author( "Mark Gabby & Brad Johnson" ) 
  874.  
  875.    party_allow_max_followers( true ) 
  876.  
  877. 	trigger_type_enable( "warp", false ) 
  878.  
  879.    -- Unload vehicles - there are problems with insufficient resources 
  880.    spawning_vehicles( false ) 
  881.    thread_yield() 
  882.  
  883.    mission_start_fade_out() 
  884.  
  885. 	trigger_enable( SAINTS_HQ_UP_ELEVATOR_TRIGGER, false ) 
  886. 	trigger_enable( SAINTS_HQ_DOWN_ELEVATOR_TRIGGER, false ) 
  887.  
  888.    local next_state = "Puerto Rico" 
  889.    local resume_from_checkpoint = false 
  890.    if ( checkpoint_name == MISSION_START_CHECKPOINT ) then 
  891. 		if ( is_restart == false ) then 
  892. 			cutscene_play( CT_INTRO, MISSION_START_COLLISION_GROUP_NAME, { START_NAVPOINT_NAME, START_NAVPOINT_REMOTE_PLAYER_NAME }, false ) 
  893. 		else 
  894. 	      teleport_coop( START_NAVPOINT_NAME, START_NAVPOINT_REMOTE_PLAYER_NAME ) 
  895. 			group_create_hidden( MISSION_START_COLLISION_GROUP_NAME, true ) 
  896. 		end 
  897.    end 
  898.  
  899.    if ( checkpoint_name == MISSION_START_CHECKPOINT ) then 
  900.       -- Create the mess around the player 
  901.       group_show( MISSION_START_COLLISION_GROUP_NAME ) 
  902.       for vehicle_index, vehicle_name in pairs( COLLISION_VEHICLE_NAMES ) do 
  903.          if ( COLLISION_CAR_MEMBERS[vehicle_index] ~= nil ) then 
  904.             vehicle_enter_group_teleport( COLLISION_CAR_MEMBERS[vehicle_index], vehicle_name ) 
  905.          end 
  906.          vehicle_speed_override( vehicle_name, 0 ) 
  907.       end 
  908.  
  909.       -- Create the roadblocks and the first attack squad 
  910.       group_create( NORTH_ROADBLOCK_NAME, true ) 
  911.       group_create( SOUTH_ROADBLOCK_NAME, true ) 
  912.       group_create_hidden( SHAUNDI_ATTACKERS_GROUP_NAME, true ) 
  913.       group_create_hidden( INITIAL_ATTACKERS_GROUP_NAME, true ) 
  914.  
  915.       ss06_spawn_attack_group( ON_FOOT_SQUAD_GROUP_NAMES[SOUTH_ATTACK_SQUAD], 
  916.                                ON_FOOT_SQUAD_GROUP_NAMES_COOP[SOUTH_ATTACK_SQUAD] ) 
  917.       ss06_spawn_attack_group( ON_FOOT_SQUAD_GROUP_NAMES[NORTH_ATTACK_SQUAD], 
  918.                                ON_FOOT_SQUAD_GROUP_NAMES_COOP[NORTH_ATTACK_SQUAD] ) 
  919.       ss06_spawn_hidden_attack_group( ALT_ESCAPE_GROUP_NAME, ALT_ESCAPE_COOP_GROUP_NAME ) 
  920.  
  921.       camera_look_through( START_NAVPOINT_NAME ) 
  922.       camera_end_look_through( true ) 
  923.       next_state = MS_BEGUN 
  924.    elseif ( checkpoint_name == CP_SAVED_SHAUNDI ) then 
  925.       -- Re-enable vehicle spawning if we're resuming from the "Saved Shaundi" checkpoint, because 
  926.       -- vehicles should be enabled 
  927.       spawning_vehicles( true ) 
  928.       Shaundi_saved = true 
  929.       teleport_coop( SAVED_SHAUNDI_CHECKPOINT_WARPS[LOCAL_PLAYER], SAVED_SHAUNDI_CHECKPOINT_WARPS[REMOTE_PLAYER] ) 
  930.  
  931.       notoriety_force_no_spawn( ENEMY_GANG, true ) 
  932.  
  933.       if ( group_is_loaded( SHAUNDI_GROUP_NAME ) == false ) then 
  934.          group_create( SHAUNDI_GROUP_NAME ) 
  935.       end 
  936.  
  937.       -- Get the pre-Pierce appearance people ready to appear 
  938.       group_create_hidden( PRE_PIERCE_REINFORCEMENTS_GROUP_NAME, true ) 
  939.       -- Finally, get the groups for Pierce's appearance ready 
  940.       group_create_hidden( PIERCE_GROUP_NAME, true ) 
  941.       group_create_hidden( PIERCE_PURSUIT_GROUP_NAME, true ) 
  942.  
  943.       -- Load in the very next group that appears after Shaundi is 
  944.       -- saved 
  945.       group_create( ENTRANCE_REINFORCEMENTS_GROUP_NAME, true ) 
  946.       next_state = MS_SAVED_SHAUNDI 
  947.       resume_from_checkpoint = true 
  948.  
  949. 		for index, door_name in pairs( HIDEOUT_ENTRANCE_DOORS ) do 
  950. 			door_open( door_name ) 
  951. 		end 
  952.  
  953.       mission_help_table( HT_DEFEND_HQ_OBJECTIVE ) 
  954.    end 
  955.    -- Start the process thread ( Do this before fadein so drug effect looks good ) 
  956.    Process_thread_handle = thread_new( "ss06_per_frame_process" ) 
  957.  
  958.    mission_start_fade_in() 
  959.  
  960.    ss06_setup_state( next_state, resume_from_checkpoint ) 
  961. end 
  962.  
  963. function ss06_divide_section_into_chunks( section_size, num_chunks, min_below_average_percent, max_above_average_percent ) 
  964.    local chunks = {} 
  965.    local increment = 1 
  966.    local section_percent_remaining = 1.0 
  967.  
  968.    local average_percent_per_chunk = section_percent_remaining / num_chunks 
  969.    -- Use the values to calculate a min and max  
  970.    local chunk_min_size_percent = ( min_below_average_percent ) * average_percent_per_chunk 
  971.    local chunk_max_size_percent = ( max_above_average_percent + 1.0 ) * average_percent_per_chunk 
  972.  
  973.    -- For each chunk we're dividing the section into 
  974.    for index = 1, num_chunks - 1, increment do 
  975.       -- Find the number of chunks remaining to be allocated after this one 
  976.       local num_chunks_remaining_after_this = num_chunks - index 
  977.  
  978.       -- Find the average percent remaining for all other chunks depending on our choice here 
  979.       local average_percent_per_chunk_remaining_max = ( section_percent_remaining - chunk_min_size_percent ) / num_chunks_remaining_after_this 
  980.       local average_percent_per_chunk_remaining_min = ( section_percent_remaining - chunk_max_size_percent ) / num_chunks_remaining_after_this 
  981.  
  982.       -- Find a random number between the min and max size of this chunk 
  983.       local chunk_percent_of_section = rand_float( chunk_min_size_percent, chunk_max_size_percent ) 
  984.  
  985.       -- Keep the min and max within bounds to assure that we don't mess things up 
  986.       -- If the remaining average is less than the minimum if we choose the maximum value, choose the minumum value instead 
  987.       if ( average_percent_per_chunk_remaining_min < chunk_min_size_percent ) then 
  988.          chunk_percent_of_section = chunk_min_size_percent 
  989.       -- And vice versa 
  990.       elseif ( average_percent_per_chunk_remaining_max > chunk_max_size_percent ) then 
  991.          chunk_percent_of_section = chunk_max_size_percent 
  992.       end 
  993.  
  994.       chunks[index] = chunk_percent_of_section * section_size 
  995.  
  996.       section_percent_remaining = section_percent_remaining - chunk_percent_of_section 
  997.    end 
  998.  
  999.    -- The last chunk gets whatever's left 
  1000.    chunks[num_chunks] = section_percent_remaining * section_size 
  1001.  
  1002.    return chunks 
  1003. end 
  1004.  
  1005. -- Returns the number of chunks that the timer was divided into, 
  1006. -- the actual health chunks, and the actual time chunks. ( in that order. ) 
  1007. -- 
  1008. -- total_time: The total amount of time to divide between the chunks. 
  1009. -- chunk_count_range: The minimum and maximum value for the number of chunks that 
  1010. --                    should be created. 
  1011. -- 
  1012. function ss06_calculate_health_timer_data( total_time, chunk_count_range ) 
  1013.    local num_chunks = rand_int( chunk_count_range[1], chunk_count_range[2] ) 
  1014.  
  1015.    local health_chunks = ss06_divide_section_into_chunks( 1.0, num_chunks, 
  1016.                                                           HEALTH_CHUNK_MIN_MULTIPLIER, 
  1017.                                                           HEALTH_CHUNK_MAX_MULTIPLIER )    
  1018.    local time_chunks_seconds = ss06_divide_section_into_chunks( total_time, num_chunks, 
  1019.                                                                 TIME_CHUNK_MIN_MULTIPLIER, 
  1020.                                                                 TIME_CHUNK_MAX_MULTIPLIER ) 
  1021.  
  1022.    return num_chunks, health_chunks, time_chunks_seconds 
  1023. end 
  1024.  
  1025. function ss06_per_frame_process() 
  1026.    -- Loop until the mission end conditions are met 
  1027.    while ( 1 ) do 
  1028.       local time_elapsed = get_frame_time() 
  1029.  
  1030.       if ( Current_mission_state ~= MS_FAILURE ) then 
  1031.          ss06_process_mission_notoriety( time_elapsed ) 
  1032.          ss06_process_haze( time_elapsed ) 
  1033.       end 
  1034.       delay( 0 ) 
  1035.    end 
  1036. end 
  1037.  
  1038. function ss06_follower_died(name) 
  1039.    if ( name == SHAUNDI_NAME ) then 
  1040.       -- End the mission since Shaundi was killed 
  1041.       mission_end_failure( MISSION_NAME, HT_SHAUNDI_DIED ) 
  1042.    elseif ( name == PIERCE_NAME ) then 
  1043.       -- End the mission since Pierce was killed 
  1044.       mission_end_failure( MISSION_NAME, HT_PIERCE_DIED ) 
  1045.    end 
  1046. end 
  1047.  
  1048. function ss06_follower_abandoned( name ) 
  1049.    if ( name == SHAUNDI_NAME ) then 
  1050.       -- End the mission since Shaundi was abandoned 
  1051.       mission_end_failure( MISSION_NAME, HT_SHAUNDI_ABANDONED ) 
  1052.    elseif ( name == PIERCE_NAME ) then 
  1053.       -- End the mission since Pierce was killed 
  1054.       mission_end_failure( MISSION_NAME, HT_PIERCE_ABANDONED ) 
  1055.    end 
  1056. end 
  1057.  
  1058. function ss06_kill_health_timer( timer_thread_handle, hud_bar_index, character_name ) 
  1059.    if ( timer_thread_handle ~= INVALID_THREAD_HANDLE ) then 
  1060.       local char_max_hp = get_max_hit_points( character_name ) 
  1061.       local char_new_hp = char_max_hp * Health_timer_cur_bar_values[hud_bar_index] 
  1062.       set_current_hit_points( character_name, char_new_hp ) 
  1063.       thread_kill( timer_thread_handle ) 
  1064.       timer_thread_handle = INVALID_THREAD_HANDLE 
  1065.       hud_bar_off( hud_bar_index ) 
  1066.    end 
  1067. end 
  1068.  
  1069. function ss06_rescue_shaundi_message() 
  1070.    mission_help_table( HT_RESCUE_SHAUNDI ) 
  1071. end 
  1072.  
  1073. function ss06_process_health_timer( hud_bar_index, timer_label, warning_time, warning_hp_percent, 
  1074.                                     chunk_count, health_chunks, time_chunks_seconds, 
  1075.                                     out_of_time_message, failure_message, callback_on_first_damage ) 
  1076.    -- Enable the HUD bar's display 
  1077.    hud_bar_on( hud_bar_index, "Health", timer_label, 1.0 ) 
  1078.    Health_timer_cur_bar_values[hud_bar_index] = 1.0 
  1079.    hud_bar_set_range( hud_bar_index, 0, Health_timer_cur_bar_values[hud_bar_index], SYNC_ALL ) 
  1080.    hud_bar_set_value( hud_bar_index, Health_timer_cur_bar_values[hud_bar_index], SYNC_ALL ) 
  1081.  
  1082.    -- Setup values required to be above the loop's scope 
  1083.    local cur_chunk_index = 1 
  1084.  
  1085.    local cur_time_chunk_delay_seconds = time_chunks_seconds[cur_chunk_index] 
  1086.    local total_time_elapsed = 0 
  1087.  
  1088.    local out_of_time_message_triggered = false 
  1089.  
  1090.    while ( cur_chunk_index <= chunk_count ) do 
  1091.       --mission_debug( cur_time_chunk_delay_seconds.." seconds remaining", 15 ) 
  1092.       delay( cur_time_chunk_delay_seconds ) 
  1093.       total_time_elapsed = total_time_elapsed + cur_time_chunk_delay_seconds 
  1094.  
  1095.       if ( callback_on_first_damage ~= nil ) then 
  1096.          callback_on_first_damage() 
  1097.          callback_on_first_damage = nil 
  1098.       end 
  1099.  
  1100.       Health_timer_cur_bar_values[hud_bar_index] = Health_timer_cur_bar_values[hud_bar_index] - health_chunks[cur_chunk_index] 
  1101.       --mission_debug( Health_timer_cur_bar_values[hud_bar_index].." percent remaining", 15 ) 
  1102.       hud_bar_set_value( hud_bar_index, Health_timer_cur_bar_values[hud_bar_index], SYNC_ALL ) 
  1103.  
  1104.       -- Only prompt the player with the out-of-time message once 
  1105.       if ( out_of_time_message_triggered == false and out_of_time_message ~= nil and out_of_time_message ~= "" ) then 
  1106.          -- If health is at the halfway point and more than half of the time to get there 
  1107.          -- has elapsed, tell the player to hurry up 
  1108.          if ( total_time_elapsed >= warning_time and 
  1109.               Health_timer_cur_bar_values[hud_bar_index] < warning_hp_percent ) then 
  1110.             mission_help_table( out_of_time_message ) 
  1111.             out_of_time_message_triggered = true 
  1112.          end 
  1113.       end 
  1114.  
  1115.       cur_chunk_index = cur_chunk_index + 1 
  1116.       cur_time_chunk_delay_seconds = time_chunks_seconds[cur_chunk_index] 
  1117.    end 
  1118.  
  1119. 	mission_debug( "mission failure being called" ) 
  1120.  
  1121.    -- If we fall through here, the mission has failed 
  1122.    mission_end_failure( MISSION_NAME, failure_message ) 
  1123. end 
  1124.  
  1125. function ss06_collision_members_flee() 
  1126.    for vehicle_index, vehicle_name in pairs( COLLISION_VEHICLE_NAMES ) do 
  1127.       if ( COLLISION_CAR_MEMBERS[vehicle_index] ~= nil ) then 
  1128.          for member_index, member_name in pairs( COLLISION_CAR_MEMBERS[vehicle_index] ) do 
  1129.             vehicle_exit( member_name ) 
  1130.             delay( rand_float( 0, 0.5 ) ) 
  1131.             flee( member_name, LOCAL_PLAYER, false, true ) 
  1132.          end 
  1133.       end 
  1134.    end 
  1135. end 
  1136.  
  1137. function ss06_shaundi_call_received() 
  1138.    Shaundi_call_received = true 
  1139. end 
  1140.  
  1141. function ss06_shaundi_mission_start_call() 
  1142.    Shaundi_call_received = false 
  1143.  
  1144.    mid_mission_phonecall( "ss06_shaundi_call_received" ) 
  1145.    local incoming_call_thread = thread_new( "ss06_play_shaundi_call_on_answer" ) 
  1146.  
  1147.    delay( 10.0 ) 
  1148.  
  1149.    if ( Shaundi_call_received == false ) then 
  1150.       thread_kill( incoming_call_thread ) 
  1151.       mid_mission_phonecall_reset() 
  1152.  
  1153.       audio_play( CELLPHONE_INCOMING ) 
  1154.       delay( 1.0 ) 
  1155.  
  1156.       cellphone_animate_start_do() 
  1157.       audio_play_conversation( INITIAL_PHONE_CALL_DIALOG_STREAM, INCOMING_CALL ) 
  1158.  
  1159.       Shaundi_call_complete = true 
  1160.    end 
  1161. end 
  1162.  
  1163. function ss06_play_shaundi_call_on_answer() 
  1164.    repeat 
  1165.       thread_yield() 
  1166.    until Shaundi_call_received 
  1167.  
  1168.    audio_play_conversation( INITIAL_PHONE_CALL_DIALOG_STREAM, INCOMING_CALL ) 
  1169.    mid_mission_phonecall_reset() 
  1170.    Shaundi_call_complete = true 
  1171. end 
  1172.  
  1173. -- Sets up a new mission state. 
  1174. -- 
  1175. -- state_to_setup: The new state. 
  1176. -- resume_from_checkpoint: Used by MS_SAVED_SHAUNDI to specify whether or not 
  1177. --                         this is being resumed from a checkpoint ( true for being 
  1178. --                         resumed ) 
  1179. function ss06_setup_state( state_to_setup, resume_from_checkpoint ) 
  1180.    -- State tracking and haze status tracking 
  1181.    Drug_effect_reduction_time_remaining_seconds = DRUG_EFFECT_STATE_SWITCH_REDUCTION_TIME_SECONDS 
  1182.    Current_mission_state = state_to_setup 
  1183.  
  1184.    -- Mission starts - sets up the ambush and drug effect, etc 
  1185.    if ( state_to_setup == MS_BEGUN ) then 
  1186.       -- Have the members in the collision vehicles run away 
  1187.       thread_new( "ss06_collision_members_flee" ) 
  1188.  
  1189.       -- Set notoriety as per design 
  1190.       notoriety_set_max( ENEMY_GANG, MISSION_MAX_NOTORIETY ) 
  1191.       notoriety_set( ENEMY_GANG, MISSION_START_NOTORIETY ) 
  1192.       notoriety_set_min( ENEMY_GANG, MISSION_MIN_NOTORIETY ) 
  1193.  
  1194.       notoriety_force_no_spawn( ENEMY_GANG, true ) 
  1195.  
  1196.       -- Add the triggers for leaving the starting area and reaching the Saint's HQ. 
  1197.       trigger_enable( START_TRIGGER_REGION_NAME, true ) 
  1198.       on_trigger_exit( "ss06_leave_starting_box_or_annex", START_TRIGGER_REGION_NAME ) 
  1199.       on_trigger( "ss06_enter_starting_box", START_TRIGGER_REGION_NAME ) 
  1200.  
  1201.       trigger_enable( START_TRIGGER_ANNEX_NAME, true ) 
  1202.       on_trigger_exit( "ss06_leave_starting_box_or_annex", START_TRIGGER_ANNEX_NAME )    
  1203.       on_trigger( "enter_annex", START_TRIGGER_ANNEX_NAME ) 
  1204.  
  1205.       trigger_enable( NORTH_CAMPER_TRIGGER_NAME, true ) 
  1206.       on_trigger( "ss06_north_camper_trigger", NORTH_CAMPER_TRIGGER_NAME )    
  1207.       for index, member in pairs(NORTH_CAMPER_NAMES) do 
  1208.          set_ignore_ai_flag( member, true ) 
  1209.          delay( .25 ) 
  1210.          crouch_start( member ) 
  1211.       end 
  1212.  
  1213.       trigger_enable( SOUTH_CAMPER_TRIGGER_NAME, true ) 
  1214.       on_trigger( "ss06_south_camper_trigger", SOUTH_CAMPER_TRIGGER_NAME ) 
  1215.       for index, member in pairs(SOUTH_CAMPER_NAMES) do 
  1216.          set_ignore_ai_flag( member, true ) 
  1217.          delay( .25 ) 
  1218.          crouch_start( member ) 
  1219.       end 
  1220.  
  1221.       trigger_enable( ALTERNATE_ESCAPE_SPAWN_TRIGGER_NAME, true ) 
  1222.       on_trigger( "ss06_alternate_escape_attack", ALTERNATE_ESCAPE_SPAWN_TRIGGER_NAME ) 
  1223.  
  1224.       -- Enable the overrides for the "haze" effect 
  1225.       drug_enable_disable_effect_override( true, SYNC_ALL ) 
  1226.       drug_effect_set_override_values( DRUNK_EFFECT_MAGNITUDE * Cur_haze_multiplier, 
  1227.                                        WEED_EFFECT_MAGNITUDE * Cur_weed_multiplier, SYNC_ALL ) 
  1228.  
  1229.  
  1230.       ss06_attack_squad_attack( ON_FOOT_SQUAD_MEMBERS[NORTH_ATTACK_SQUAD], 
  1231.                                 ON_FOOT_SQUAD_MEMBERS_COOP[NORTH_ATTACK_SQUAD] ) 
  1232.       ss06_attack_squad_attack( ON_FOOT_SQUAD_MEMBERS[SOUTH_ATTACK_SQUAD], 
  1233.                                 ON_FOOT_SQUAD_MEMBERS_COOP[SOUTH_ATTACK_SQUAD] ) 
  1234.  
  1235.       thread_new( "ss06_shaundi_mission_start_call" ) 
  1236.  
  1237.       repeat 
  1238.          thread_yield() 
  1239.       until ( Shaundi_call_complete ) 
  1240.  
  1241.       -- Let the player know what their next objective is 
  1242.       mission_help_table( HT_GET_BACK_TO_HQ_OBJECTIVE ) 
  1243.       trigger_enable( SAINTS_HQ_POS, true ) 
  1244.       on_trigger( "ss06_reached_saints_hq_entrance", SAINTS_HQ_POS ) 
  1245.       marker_add_trigger( SAINTS_HQ_POS, MINIMAP_ICON_LOCATION, INGAME_EFFECT_LOCATION, SYNC_ALL ) 
  1246.       waypoint_add( SAINTS_HQ_POS, SYNC_ALL ) 
  1247.  
  1248.       -- Setup the area trigger to disable notoriety spawning when the player 
  1249.       -- reaches the Saints HQ. 
  1250.       trigger_enable( SAINTS_HQ_AREA, true ) 
  1251.       on_trigger( "ss06_disable_notoriety_spawning", SAINTS_HQ_AREA ) 
  1252.  
  1253.       -- Setup the get-back-to-HQ timer stuff 
  1254.       local num_chunks, 
  1255.             health_chunks, 
  1256.             time_chunks_seconds = ss06_calculate_health_timer_data( GET_TO_HQ_TIME_SECONDS, GET_TO_HQ_DIVISION_RANGE ) 
  1257.       local warning_time_threshold = GET_TO_HQ_TIME_SECONDS / 2 
  1258.       local warning_health_threshold = 0.5 
  1259.       Shaundi_health_timer_thread_handle = thread_new( "ss06_process_health_timer", 0, HT_SHAUNDI_HEALTH_BAR_LABEL, 
  1260.                                                        warning_time_threshold, warning_health_threshold, 
  1261.                                                        num_chunks, health_chunks, time_chunks_seconds, 
  1262.                                                        HT_SHAUNDI_RUNNING_OUT_OF_TIME, HT_SHAUNDI_DIED_HIGHLIGHTED, 
  1263.                                                        ss06_rescue_shaundi_message ) 
  1264.  
  1265.       -- Clear up some resources 
  1266.       release_to_world( NORTH_ROADBLOCK_NAME ) 
  1267.       release_to_world( SOUTH_ROADBLOCK_NAME ) 
  1268.       release_to_world( MISSION_START_COLLISION_GROUP_NAME ) 
  1269.  
  1270.       thread_yield() 
  1271.  
  1272.       -- Create the groups that we'll be needing later in the mission 
  1273.       group_create_hidden( ENTRANCE_REINFORCEMENTS_GROUP_NAME, true ) 
  1274.       -- Get the pre-Pierce appearance people ready to appear 
  1275.       group_create_hidden( PRE_PIERCE_REINFORCEMENTS_GROUP_NAME, true ) 
  1276.  
  1277. 		delay( 20.0 ) 
  1278.  
  1279.       -- Finally, get the groups for Pierce's appearance ready 
  1280.       group_create_hidden( PIERCE_GROUP_NAME, true ) 
  1281.       group_create_hidden( PIERCE_PURSUIT_GROUP_NAME, true ) 
  1282.  
  1283.    elseif ( state_to_setup == MS_SPAWN_RESUMED ) then 
  1284.       --mission_debug( "all players left" ) 
  1285.       trigger_enable( START_TRIGGER_REGION_NAME, false ) 
  1286.       trigger_enable( START_TRIGGER_ANNEX_NAME, false ) 
  1287.       notoriety_force_no_spawn( ENEMY_GANG, false ) 
  1288.       spawning_vehicles( true ) 
  1289.  
  1290.       -- Disable the north and south triggers 
  1291.       trigger_enable(NORTH_TRIGGER_NAME, false) 
  1292.       trigger_enable(SOUTH_TRIGGER_NAME, false) 
  1293.       -- Release the attack groups 
  1294.       ss06_release_attack_group( ON_FOOT_SQUAD_GROUP_NAMES[NORTH_ATTACK_SQUAD], 
  1295.                                  ON_FOOT_SQUAD_GROUP_NAMES_COOP[NORTH_ATTACK_SQUAD] ) 
  1296.       ss06_release_attack_group( ON_FOOT_SQUAD_GROUP_NAMES[SOUTH_ATTACK_SQUAD], 
  1297.                                  ON_FOOT_SQUAD_GROUP_NAMES_COOP[SOUTH_ATTACK_SQUAD] ) 
  1298.  
  1299.       release_to_world( MISSION_START_COLLISION_GROUP_NAME ) 
  1300.  
  1301.       -- Release the camper attack groups, restore their AI and their crouch status, and disable the triggers 
  1302.       trigger_enable( NORTH_CAMPER_TRIGGER_NAME, false ) 
  1303.       for index, member in pairs(NORTH_CAMPER_NAMES) do 
  1304.          set_ignore_ai_flag( member, false ) 
  1305.          delay( .25 ) 
  1306.          crouch_stop( member ) 
  1307.       end 
  1308.       trigger_enable( SOUTH_CAMPER_TRIGGER_NAME, false ) 
  1309.       for index, member in pairs(SOUTH_CAMPER_NAMES) do 
  1310.          set_ignore_ai_flag( member, false ) 
  1311.          delay( .25 ) 
  1312.          crouch_stop( member ) 
  1313.       end 
  1314.  
  1315.       -- Create Shaundi 
  1316.       group_create( SHAUNDI_GROUP_NAME, true ) 
  1317.       set_ignore_ai_flag( SHAUNDI_NAME, true ) 
  1318.       turn_invulnerable( SHAUNDI_NAME ) 
  1319.  
  1320.       -- Show the people who will be attacking Shaundi 
  1321.       group_show( SHAUNDI_ATTACKERS_GROUP_NAME ) 
  1322.       ss06_give_weapons( SHAUNDI_ATTACKERS_MEMBERS, SHAUNDI_ATTACKERS_WEAPONS ) 
  1323.       Total_attackers_remaining = Total_attackers_remaining + Shaundi_attackers_remaining 
  1324.       for index, member in pairs( SHAUNDI_ATTACKERS_MEMBERS ) do 
  1325.          turn_invulnerable( member ) 
  1326.       end 
  1327.       group_show( INITIAL_ATTACKERS_GROUP_NAME ) 
  1328.       ss06_give_weapons( INITIAL_BASE_ATTACKERS_MEMBERS, INITIAL_BASE_ATTACKERS_WEAPONS ) 
  1329.       Total_attackers_remaining = Total_attackers_remaining + sizeof_table( INITIAL_BASE_ATTACKERS_MEMBERS ) 
  1330.       for index, member in pairs( INITIAL_BASE_ATTACKERS_MEMBERS ) do 
  1331.          on_death( "ss06_initial_base_attacker_death", member ) 
  1332.       end 
  1333.  
  1334.       trigger_enable( REACHED_SHAUNDI_TRIGGER, true ) 
  1335.       on_trigger( "ss06_reached_shaundi_trigger", REACHED_SHAUNDI_TRIGGER ) 
  1336.  
  1337.       -- HACK: Hide this character, because he's having some behavioral problems 
  1338.       character_hide( INITIAL_BASE_ATTACKERS_MEMBERS[4] ) 
  1339.  
  1340.    elseif ( state_to_setup == MS_SAVED_SHAUNDI ) then 
  1341.       Shaundi_saved = true 
  1342.  
  1343.       local distance, player = get_dist_closest_player_to_object( SHAUNDI_NAME ) 
  1344.  
  1345. 		-- If Shaundi is already dead, don't add her to the player's party 
  1346. 		if ( resume_from_checkpoint == false or 
  1347. 			  resume_from_checkpoint == nil ) then 
  1348. 			if ( thread_check_done( Shaundi_health_timer_thread_handle ) == true ) then 
  1349. 				mission_debug( "Shaundi is already dead." ) 
  1350. 				return 
  1351. 			end 
  1352. 		end 
  1353.  
  1354.       party_add( SHAUNDI_NAME, player ) 
  1355.       Player_with_Shaundi = player 
  1356.  
  1357.       npc_leash_remove( SHAUNDI_NAME ) 
  1358.       on_death( "ss06_follower_died", SHAUNDI_NAME ) 
  1359.       on_dismiss( "ss06_follower_abandoned", SHAUNDI_NAME ) 
  1360.       turn_vulnerable( SHAUNDI_NAME ) 
  1361.  
  1362.       -- Only do these things if we're not resuming from a checkpoint 
  1363.       if ( resume_from_checkpoint == false or 
  1364.            resume_from_checkpoint == nil ) then 
  1365.          ss06_kill_health_timer( Shaundi_health_timer_thread_handle, 0, SHAUNDI_NAME ) 
  1366.  
  1367.          -- Start the "get back to the HQ!" failure timers 
  1368.          if ( Players_in_defense_area[LOCAL_PLAYER_INDEX] == false ) then 
  1369.             Player_failure_timer_thread_handles[LOCAL_PLAYER] = thread_new( "ss06_get_to_hq_or_fail", LOCAL_PLAYER ) 
  1370.          end 
  1371.          if ( coop_is_active() and Players_in_defense_area[REMOTE_PLAYER_INDEX] == false ) then 
  1372.             Player_failure_timer_thread_handles[REMOTE_PLAYER] = thread_new( "ss06_get_to_hq_or_fail", REMOTE_PLAYER ) 
  1373.          end 
  1374.  
  1375.          mission_set_checkpoint( CP_SAVED_SHAUNDI ) 
  1376.  
  1377.          marker_remove_npc( SHAUNDI_NAME ) 
  1378.  
  1379.          -- Add markers for all the required kills and unleash them 
  1380.          for index, name in pairs( INITIAL_BASE_ATTACKERS_MEMBERS ) do 
  1381.             if ( ss06_character_has_been_released( name ) == false ) then 
  1382.                marker_add_npc( name, MINIMAP_ICON_KILL, INGAME_EFFECT_KILL, SYNC_ALL ) 
  1383.                Marked_member_names[name] = true 
  1384.                npc_leash_remove( name ) 
  1385.             end 
  1386.          end 
  1387.          for index, name in pairs( SHAUNDI_ATTACKERS_MEMBERS ) do 
  1388.             if ( ss06_character_has_been_released( name ) == false ) then 
  1389.                marker_add_npc( name, MINIMAP_ICON_KILL, INGAME_EFFECT_KILL, SYNC_ALL ) 
  1390.                Marked_member_names[name] = true 
  1391.                npc_leash_remove( name ) 
  1392.             end 
  1393.          end 
  1394.          for vehicle_index, vehicle_passengers in pairs( ENTRANCE_REINFORCEMENT_VEHICLE_PASSENGERS ) do 
  1395.             for member_index, member_name in pairs( vehicle_passengers ) do 
  1396.                if ( member_index ~= 1 ) then 
  1397.                   if ( ss06_character_has_been_released( member_name ) == false ) then 
  1398.                      marker_add_npc( member_name, MINIMAP_ICON_KILL, INGAME_EFFECT_KILL, SYNC_ALL ) 
  1399.                      Marked_member_names[member_name] = true 
  1400.                   end 
  1401.                end 
  1402.             end 
  1403.          end 
  1404.          audio_play_for_character( SAVED_SHAUNDI_DIALOG_LINE, SHAUNDI_NAME, "voice", false, false ) 
  1405.       else--if ( resume_from_checkpoint == true ) 
  1406.          -- The group was loaded by the resume-from-checkpoint code 
  1407.          local group_loaded_hidden = false 
  1408.          ss06_setup_and_process_entrance_reinforcements( group_loaded_hidden ) 
  1409.          ss06_add_group_required_kill_markers( ENTRANCE_REINFORCEMENTS_MEMBERS ) 
  1410.  
  1411.          trigger_enable( SAINTS_HQ_AREA, true ) 
  1412.          on_trigger( "ss06_entered_saints_hq_area", SAINTS_HQ_AREA ) 
  1413.          on_trigger_exit( "ss06_left_saints_hq_area", SAINTS_HQ_AREA ) 
  1414.       end 
  1415.  
  1416.       mission_help_table( HT_DEFEND_HQ_OBJECTIVE ) 
  1417.  
  1418.    elseif ( state_to_setup == MS_KILL_DRIVEUP_ATTACKERS ) then 
  1419.       -- Create the two cars and have them drive up to either side of the 
  1420.       -- Saints HQ. 
  1421.       group_show( PRE_PIERCE_REINFORCEMENTS_GROUP_NAME ) 
  1422.       Total_attackers_remaining = Total_attackers_remaining + sizeof_table( PRE_PIERCE_SQUADS_MEMBERS[1] ) 
  1423.       Total_attackers_remaining = Total_attackers_remaining + sizeof_table( PRE_PIERCE_SQUADS_MEMBERS[2] ) 
  1424.  
  1425.       ss06_give_weapons( PRE_PIERCE_SQUADS_MEMBERS[1], PRE_PIERCE_SQUADS_WEAPONS[1] ) 
  1426.       ss06_give_weapons( PRE_PIERCE_SQUADS_MEMBERS[2], PRE_PIERCE_SQUADS_WEAPONS[2] ) 
  1427.  
  1428.       thread_new( "ss06_pre_pierce_reinforcements_group_do_pathing", 1 ) 
  1429.       thread_new( "ss06_pre_pierce_reinforcements_group_do_pathing", 2 ) 
  1430.  
  1431.    elseif ( state_to_setup == MS_PIERCE_APPEARS ) then 
  1432.       -- Add trigger that will be used for tracking Pierce later 
  1433.       trigger_enable( NEAR_PIERCE_TRIGGER_NAME, true ) 
  1434.       on_trigger( "ss06_near_pierce", NEAR_PIERCE_TRIGGER_NAME ) 
  1435.       on_trigger_exit( "ss06_left_pierce_area", NEAR_PIERCE_TRIGGER_NAME ) 
  1436.        
  1437.       -- Seat the Pierce pursuers 
  1438.       for vehicle_index, vehicle_name in pairs( PIERCE_PURSUIT_VEHICLE_NAMES ) do 
  1439.          vehicle_enter_group_teleport( PIERCE_PURSUIT_SQUADS_MEMBERS[vehicle_index], 
  1440.                                        vehicle_name ) 
  1441.       end       
  1442.       -- Seat Pierce in his car 
  1443.       vehicle_enter_teleport( PIERCE_NAME, PIERCE_VEHICLE_NAME ) 
  1444.  
  1445.       -- Find the appropriate warp point and then seat 
  1446.       local warp_point_index = 1 
  1447.       if ( coop_is_active() ) then 
  1448.          -- Find out the player that could possibly be in the correct place to see Pierce spawn 
  1449.          local player_without_shaundi = LOCAL_PLAYER 
  1450.          if ( Player_with_Shaundi == LOCAL_PLAYER ) then 
  1451.             player_without_shaundi = REMOTE_PLAYER 
  1452.          end 
  1453.  
  1454.          -- We want the index of the point furthest from this player so that he won't see Pierce spawn 
  1455.          local warp_point_distance = get_dist_char_to_nav( player_without_shaundi, PIERCE_SPAWN_LOCATIONS[warp_point_index] ) 
  1456.  
  1457.          -- Find the point furthest away from this player 
  1458.          for index, location_name in pairs( PIERCE_SPAWN_LOCATIONS ) do 
  1459.             local cur_point_distance = get_dist_char_to_nav( player_without_shaundi, location_name ) 
  1460.  
  1461.             if ( cur_point_distance > warp_point_distance ) then 
  1462.                warp_point_distance = cur_point_distance 
  1463.                warp_point_index = index 
  1464.             end 
  1465.          end 
  1466.  
  1467.          mission_debug( "Warp point found index"..warp_point_index ) 
  1468.  
  1469.          -- Now that we've found the farthest index, teleport Pierce and the pursuers here if they aren't here already 
  1470.          if ( warp_point_index > 1 ) then 
  1471.             for vehicle_index, vehicle_name in pairs( PIERCE_PURSUIT_VEHICLE_NAMES ) do 
  1472.                teleport_vehicle( vehicle_name, PIERCE_PURSUIT_WARP_POINTS[warp_point_index][vehicle_index] ) 
  1473.             end 
  1474.             teleport_vehicle( PIERCE_VEHICLE_NAME, PIERCE_PURSUIT_WARP_POINTS[warp_point_index][3] ) 
  1475.          end 
  1476.       end 
  1477.  
  1478.       group_show( PIERCE_GROUP_NAME ) 
  1479.       group_show( PIERCE_PURSUIT_GROUP_NAME ) 
  1480.       Total_attackers_remaining = Total_attackers_remaining + sizeof_table( PIERCE_PURSUIT_SQUADS_MEMBERS[1] ) 
  1481.       Total_attackers_remaining = Total_attackers_remaining + sizeof_table( PIERCE_PURSUIT_SQUADS_MEMBERS[2] ) 
  1482.  
  1483.       ss06_give_weapons( PIERCE_PURSUIT_SQUADS_MEMBERS[1], PIERCE_PURSUIT_SQUADS_WEAPONS[1] ) 
  1484.       ss06_give_weapons( PIERCE_PURSUIT_SQUADS_MEMBERS[2], PIERCE_PURSUIT_SQUADS_WEAPONS[2] ) 
  1485.  
  1486.       thread_new( "ss06_pierce_flee_to_hq", warp_point_index ) 
  1487.       thread_new( "ss06_pierce_pursuit_group_do_chase", 1 ) 
  1488.       thread_new( "ss06_pierce_pursuit_group_do_chase", 2 ) 
  1489.  
  1490.    elseif ( state_to_setup == MS_DEFENDING_HQ ) then 
  1491.       -- These overrides only really make sense at this point in the mission 
  1492.       for index, override in pairs( SHAUNDI_PERSONA_OVERRIDES ) do 
  1493.          persona_override_character_start( SHAUNDI_NAME, override[1], override[2] ) 
  1494.       end 
  1495.       for index, override in pairs( PIERCE_PERSONA_OVERRIDES ) do 
  1496.          persona_override_character_start( PIERCE_NAME, override[1], override[2] ) 
  1497.       end 
  1498.       for index, override in pairs( PLAYER_PERSONA_OVERRIDES ) do 
  1499.          persona_override_character_start( LOCAL_PLAYER, override[1], override[2] ) 
  1500.       end 
  1501.       persona_override_group_start( SS06_SAINTS_PERSONAS, POT_SITUATIONS[POT_ATTACK], "SS06_DEFEND" ) 
  1502.  
  1503.       -- Mark all NPCs as required kills 
  1504.       -- The ones who started in the entrance and the ones that were attacking Shaundi 
  1505.       ss06_add_group_required_kill_markers( INITIAL_BASE_ATTACKERS_MEMBERS ) 
  1506.       ss06_add_group_required_kill_markers( SHAUNDI_ATTACKERS_MEMBERS ) 
  1507.  
  1508.       -- The two groups that came before Pierce 
  1509.       -- The ones that did the dropoff 
  1510.       for vehicle_index, vehicle_passengers in pairs( ENTRANCE_REINFORCEMENT_VEHICLE_PASSENGERS ) do 
  1511.          for member_index, member_name in pairs( vehicle_passengers ) do 
  1512.             if ( member_index ~= 1 ) then 
  1513.                if ( ss06_character_has_been_released( member_name ) == false ) then 
  1514.                   marker_add_npc( member_name, MINIMAP_ICON_KILL, INGAME_EFFECT_KILL, SYNC_ALL ) 
  1515.                   Marked_member_names[member_name] = true 
  1516.                   local distance, player = get_dist_closest_player_to_object( member_name ) 
  1517.                   attack_safe( member_name, player, false ) 
  1518.                end 
  1519.             end 
  1520.          end 
  1521.       end 
  1522.       -- The ones that drove up to either side of the doors 
  1523.       for squad_index, pre_pierce_squad in pairs( PRE_PIERCE_SQUADS_MEMBERS ) do 
  1524.          ss06_add_group_required_kill_markers( pre_pierce_squad ) 
  1525.       end 
  1526.  
  1527.       -- The group that arrived chasing Pierce 
  1528.       for squad_index, pierce_pursuit_squad in pairs( PIERCE_PURSUIT_SQUADS_MEMBERS ) do 
  1529.          ss06_add_group_required_kill_markers( pierce_pursuit_squad ) 
  1530.       end 
  1531.  
  1532.       marker_remove_npc( PIERCE_NAME, SYNC_ALL ) 
  1533.       Pierce_needs_to_be_rescued = false 
  1534.  
  1535.       --mission_debug( "Switched to Defending HQ state", 15 ) 
  1536.       ss06_kill_health_timer( Pierce_health_timer_thread_handle, 0, PIERCE_NAME ) 
  1537.       trigger_enable( NEAR_PIERCE_TRIGGER_NAME, false ) 
  1538.       npc_leash_remove( PIERCE_NAME ) 
  1539.       turn_vulnerable( PIERCE_NAME ) 
  1540.       on_death( "ss06_follower_died", PIERCE_NAME ) 
  1541.       on_dismiss( "ss06_follower_abandoned", PIERCE_NAME ) 
  1542.       party_set_dismissable( false ) 
  1543.  
  1544.       -- In coop, if the local player already has Shaundi as a homie, give Pierce to the remote player       
  1545.       if ( coop_is_active() and Player_with_Shaundi == LOCAL_PLAYER ) then 
  1546.          party_add( PIERCE_NAME, REMOTE_PLAYER ) 
  1547.       -- Otherwise and in single player, give Pierce to the local player 
  1548.       else 
  1549.          party_add( PIERCE_NAME, LOCAL_PLAYER ) 
  1550.       end 
  1551.  
  1552.       audio_play_for_character( SAVED_PIERCE_DIALOG_LINE, PIERCE_NAME, "voice", false, false ) 
  1553.  
  1554.       -- TODO: Check to see if there are few enough attackers for us to 
  1555.       -- spawn an attack wave 
  1556.       if ( Total_attackers_remaining == 0 ) then 
  1557.          ss06_spawn_next_attack_wave() 
  1558.       end 
  1559.    end 
  1560. end 
  1561.  
  1562. function ss06_get_to_hq_or_fail( player_name ) 
  1563.    local sync_type = sync_from_player( player_name ) 
  1564.    waypoint_add( SAINTS_HQ_AREA, sync_type )  
  1565.    mission_help_table_nag( HT_GET_BACK_TO_HQ_OBJECTIVE, "", "", sync_type ) 
  1566.    delay( 5.0 ) 
  1567.    ss06_failure_timer( GET_TO_HQ_TIME_SECONDS, 6,  sync_type ) 
  1568. end 
  1569.  
  1570. -- Disables notoriety spawning when the player reaches a trigger. 
  1571. -- Also disables the trigger to prevent notoriety spawning from 
  1572. -- being disabled multiple times. 
  1573. -- 
  1574. function ss06_disable_notoriety_spawning( triggerer_name, trigger_name ) 
  1575.    on_trigger( "ss06_entered_saints_hq_area", SAINTS_HQ_AREA ) 
  1576.    on_trigger_exit( "ss06_left_saints_hq_area", SAINTS_HQ_AREA ) 
  1577.  
  1578.    notoriety_force_no_spawn( ENEMY_GANG, true ) 
  1579.    ss06_entered_saints_hq_area( triggerer_name, trigger_name ) 
  1580. end 
  1581.  
  1582. -- This callback is used to guide the player to Shaundi's location 
  1583. -- smoothly. 
  1584. -- 
  1585. function ss06_reached_saints_hq_entrance( triggerer_name, trigger_name ) 
  1586.    waypoint_remove( SYNC_ALL ) 
  1587.    trigger_enable( trigger_name, false ) 
  1588.  
  1589.    trigger_enable( SHAUNDI_BREADCRUMBS[1], true ) 
  1590.    marker_add_trigger( SHAUNDI_BREADCRUMBS[1], 
  1591.                        MINIMAP_ICON_LOCATION, INGAME_EFFECT_LOCATION, SYNC_ALL ) 
  1592.    on_trigger( "ss06_shaundi_breadcrumb01", SHAUNDI_BREADCRUMBS[1] ) 
  1593. end 
  1594.  
  1595. -- If the player just defeated a wave, update the objective 
  1596. -- display with this information. 
  1597. -- 
  1598. function ss06_update_objective() 
  1599.    objective_text(0, HT_X_OF_Y_WAVES_DEFEATED, Cur_attack_wave, WAVE_COUNT ) 
  1600. end 
  1601.  
  1602. function ss06_initial_base_attacker_death( member_name, attacker_name ) 
  1603.    ss06_base_attacker_died( member_name, attacker_name ) 
  1604.    Initial_base_attackers_remaining = Initial_base_attackers_remaining - 1 
  1605. end 
  1606.  
  1607. -- Callback for a member of the Shaundi attackers that are directly attacking her. 
  1608. -- Decrements the number of direct attackers and possibly switches to the saved 
  1609. -- Shaundi state. 
  1610. -- 
  1611. function ss06_shaundi_direct_attacker_death( member_name, attacker_name ) 
  1612.    ss06_base_attacker_died( member_name, attacker_name ) 
  1613.    Shaundi_direct_attackers_remaining = Shaundi_direct_attackers_remaining - 1 
  1614.  
  1615.    if ( Shaundi_direct_attackers_remaining == 0 ) then 
  1616.       if ( Current_mission_state < MS_SAVED_SHAUNDI ) then 
  1617.          trigger_enable( REACHED_SHAUNDI_TRIGGER, false ) 
  1618.          ss06_setup_state( MS_SAVED_SHAUNDI ) 
  1619.       end 
  1620.    end 
  1621. end 
  1622.  
  1623. -- Called when one of the reinforcements at the entrance is killed - 
  1624. -- the next state is triggered based on the number left. 
  1625. -- 
  1626. function ss06_entrance_reinforcement_member_killed( member_name, attacker_name ) 
  1627.    ss06_base_attacker_died( member_name, attacker_name ) 
  1628.    Entrance_reinforcements_remaining = Entrance_reinforcements_remaining - 1 
  1629.  
  1630.    if ( Entrance_reinforcements_remaining == ENTRANCE_REINFORCEMENTS_REMAINING_THRESHOLD ) then 
  1631.       ss06_setup_state( MS_KILL_DRIVEUP_ATTACKERS ) 
  1632.    end 
  1633.  
  1634. end 
  1635.  
  1636. -- Called when one of the reinforcements that appear right before Pierce 
  1637. -- shows up dies. If enough of them die, it switches to the state where Pierce 
  1638. -- shows up. 
  1639. -- 
  1640. -- member_name: The reinforcement guy who just died. 
  1641. -- 
  1642. function ss06_pre_pierce_reinforcements_member_died( member_name, attacker_name ) 
  1643.    Pre_Pierce_reinforcements_remaining = Pre_Pierce_reinforcements_remaining - 1 
  1644.    ss06_base_attacker_died( member_name, attacker_name ) 
  1645.  
  1646.    if ( Pre_Pierce_reinforcements_remaining == PRE_PIERCE_ATTACKERS_REMAINING_THRESHOLD ) then 
  1647.       ss06_setup_state( MS_PIERCE_APPEARS ) 
  1648.    end 
  1649. end 
  1650.  
  1651. -- This function is called whenever a character considered to 
  1652. -- be a Saints HQ attacker is killed - it controls spawning 
  1653. -- of reinforcements 
  1654. -- 
  1655. function ss06_base_attacker_died( member_name, attacker_name ) 
  1656.    Total_attackers_remaining = Total_attackers_remaining - 1 
  1657.    mission_debug( "total remaining: "..Total_attackers_remaining ) 
  1658.    if ( Marked_member_names[member_name] == true ) then 
  1659.       marker_remove_npc( member_name, SYNC_ALL ) 
  1660.       Marked_member_names[member_name] = false 
  1661.    end 
  1662.    release_to_world( member_name ) 
  1663.  
  1664.    if ( attacker_name == LOCAL_PLAYER or attacker_name == REMOTE_PLAYER ) then 
  1665.       local sync_type = sync_from_player( attacker_name ) 
  1666.  
  1667.       local cur_num_killed = Num_attackers_killed_by_player[attacker_name] 
  1668.       cur_num_killed = cur_num_killed + 1 
  1669.       Num_attackers_killed_by_player[attacker_name] = cur_num_killed 
  1670.       mission_debug( "player "..attacker_name..", sync type "..sync_type.." number killed: "..cur_num_killed, 5 ) 
  1671.  
  1672.       -- Only show the "number killed" objective in cases where no "Save the Homie" health bar is visible 
  1673.       if ( Shaundi_saved == true and Pierce_needs_to_be_rescued == false ) then 
  1674.          local player_index = LOCAL_PLAYER_INDEX 
  1675.          if ( attacker_name == REMOTE_PLAYER ) then 
  1676.             player_index = REMOTE_PLAYER_INDEX 
  1677.          end 
  1678.  
  1679.          objective_text( player_index, HT_SAMEDI_GANG_MEMBERS_KILLED, cur_num_killed, "", sync_type ) 
  1680.       end 
  1681.    end 
  1682.  
  1683.    if ( Current_mission_state >= MS_DEFENDING_HQ ) then 
  1684.       -- Spawn another wave if few attackers remain 
  1685.       if ( Total_attackers_remaining == ATTACKS_REMAINING_SPAWN_NEW_WAVE_THRESHOLD or 
  1686.            ( Total_attackers_remaining == 0 and Cur_attack_wave_index < WAVE_COUNT ) ) then 
  1687.          ss06_spawn_next_attack_wave() 
  1688.       elseif ( Total_attackers_remaining == 0 and Final_attack_wave_started ) then 
  1689. 			-- Clean up these triggers so that their functions aren't called when the cutscene teleports the players 
  1690.          on_trigger( "", SAINTS_HQ_AREA ) 
  1691.          on_trigger_exit( "", SAINTS_HQ_AREA ) 
  1692.          mission_end_success( MISSION_NAME, CT_OUTRO, { "ss06_$Post_CT_Warp_Local", "ss06_$Post_CT_Warp_Remote" } ) 
  1693.       end 
  1694.    end 
  1695. end 
  1696.  
  1697. -- Applies the mission's "haze" effect, and updates 
  1698. -- it based on how far into the mission the player is. 
  1699. -- 
  1700. -- time_elapsed: The number of seconds elapsed since 
  1701. --               the last time this function was called. 
  1702. -- 
  1703. function ss06_process_haze( time_elapsed ) 
  1704.    -- Update the haze reduction time 
  1705.    Drug_effect_reduction_time_remaining_seconds = Drug_effect_reduction_time_remaining_seconds - time_elapsed 
  1706.    if ( Drug_effect_reduction_time_remaining_seconds > 0 ) then 
  1707.       -- Find the difference between the current effect multiplier and the desired minimum at this stage 
  1708.       -- in the mission 
  1709.       local haze_diff = Cur_haze_multiplier - PER_STATE_HAZE_MULTIPLIERS[Current_mission_state] 
  1710.       local weed_diff = Cur_weed_multiplier - PER_STATE_WEED_MULTIPLIERS[Current_mission_state] 
  1711.       -- Find out the number of percent per second to reduce the current multiplier to get it at the 
  1712.       -- desired minimum in the reduction time 
  1713.       local haze_reduction_percent_per_second = haze_diff / Drug_effect_reduction_time_remaining_seconds 
  1714.       local weed_reduction_percent_per_second = weed_diff / Drug_effect_reduction_time_remaining_seconds 
  1715.  
  1716.       -- Reduce the effect by the amount of time that passed 
  1717.       Cur_haze_multiplier = Cur_haze_multiplier - ( time_elapsed * haze_reduction_percent_per_second ) 
  1718.       Cur_weed_multiplier = Cur_weed_multiplier - ( time_elapsed * weed_reduction_percent_per_second ) 
  1719.    else 
  1720.       Drug_effect_reduction_time_remaining_seconds = 0 
  1721.    end 
  1722.  
  1723.    drug_effect_set_override_values( DRUNK_EFFECT_MAGNITUDE * Cur_haze_multiplier, 
  1724.                                     WEED_EFFECT_MAGNITUDE * Cur_weed_multiplier, SYNC_ALL ) 
  1725. end 
  1726.  
  1727. -- Updates the mission notoriety based on the mission's 
  1728. -- state and the notoriety's current value 
  1729. -- 
  1730. function ss06_process_mission_notoriety( time_elapsed ) 
  1731.    local current_enemy_notoriety = notoriety_get_decimal( ENEMY_GANG ) 
  1732.  
  1733.    -- We don't have to do any processing of the notoriety unless it 
  1734.    -- drops below the min. If it has, that means the player has used 
  1735.    -- a "Forgive and Forget," and we need to raise it back up as per 
  1736.    -- the mission spec 
  1737.    if ( current_enemy_notoriety < MISSION_MIN_NOTORIETY ) then 
  1738.  
  1739.       -- Find the new notoriety based on the old, the time elapsed since last frame, and the increase 
  1740.       -- per second back to the minimum notoriety value 
  1741.       local new_notoriety = current_enemy_notoriety + ( time_elapsed * NOTORIETY_BACK_TO_MIN_INCREASE_PER_SECOND ) 
  1742.  
  1743.       -- If we're still below the minimum, then set to this value 
  1744.       if ( new_notoriety < MISSION_MIN_NOTORIETY ) then 
  1745.          notoriety_set( ENEMY_GANG, new_notoriety ) 
  1746.       -- If we've hit the min, then set the hard minimum 
  1747.       else 
  1748.          notoriety_set_min( ENEMY_GANG, MISSION_MIN_NOTORIETY ) 
  1749.       end 
  1750.    end 
  1751. end 
  1752.  
  1753. -- Callback when the player leaves the starting area. Re-enables spawning and 
  1754. -- notoriety spawning if at least one player is outside both of the annex and 
  1755. -- starting box. 
  1756. -- 
  1757. function ss06_leave_starting_box_or_annex( human_name, trigger_name ) 
  1758.  
  1759.    -- Based on which player and which trigger, update the players' 
  1760.    -- in-or-out status 
  1761.    if ( trigger_name == START_TRIGGER_ANNEX_NAME ) then 
  1762.       if ( human_name == LOCAL_PLAYER ) then 
  1763.          Players_in_annex[LOCAL_PLAYER_INDEX] = false 
  1764.       elseif ( human_name == REMOTE_PLAYER ) then 
  1765.          Players_in_annex[REMOTE_PLAYER_INDEX] = false 
  1766.       end 
  1767.    elseif ( trigger_name == START_TRIGGER_REGION_NAME ) then 
  1768.       if ( human_name == LOCAL_PLAYER ) then 
  1769.          Players_in_starting_box[LOCAL_PLAYER_INDEX] = false 
  1770.       elseif ( human_name == REMOTE_PLAYER ) then 
  1771.          Players_in_starting_box[REMOTE_PLAYER_INDEX] = false 
  1772.       end 
  1773.    end 
  1774.  
  1775.    -- Check to see if a player is outside both boxes 
  1776.    local player_completely_left = false 
  1777.    if ( Players_in_starting_box[LOCAL_PLAYER_INDEX] == false and 
  1778.        Players_in_annex[LOCAL_PLAYER_INDEX] == false ) then 
  1779. 		player_completely_left = true 
  1780. 	-- If the local player's not outside, check the remote player if we're in coop 
  1781.    elseif ( coop_is_active() ) then 
  1782. 		if ( Players_in_starting_box[REMOTE_PLAYER_INDEX] == false and  
  1783. 			 Players_in_annex[REMOTE_PLAYER_INDEX] == false ) then 
  1784. 			player_completely_left = true 
  1785. 		end 
  1786. 	 end 
  1787.  
  1788.    -- If a player is outside, then do all the spawning updates 
  1789.    if ( player_completely_left ) then 
  1790.       ss06_setup_state( MS_SPAWN_RESUMED ) 
  1791.    end 
  1792. end 
  1793.  
  1794. -- First of two triggers that guide the player to Shaundi. 
  1795. -- 
  1796. function ss06_shaundi_breadcrumb01( triggerer_name, trigger_name ) 
  1797.    trigger_enable( trigger_name, false ) 
  1798.  
  1799.    trigger_enable( SHAUNDI_BREADCRUMBS[2] ) 
  1800.    marker_add_trigger( SHAUNDI_BREADCRUMBS[2], 
  1801.                        MINIMAP_ICON_LOCATION, INGAME_EFFECT_LOCATION, SYNC_ALL ) 
  1802.  
  1803.    -- HACK: Show this character 
  1804.    character_show( INITIAL_BASE_ATTACKERS_MEMBERS[4] ) 
  1805.  
  1806.    on_trigger( "ss06_shaundi_breadcrumb02", SHAUNDI_BREADCRUMBS[2] ) 
  1807. end 
  1808.  
  1809. --  
  1810. function ss06_shaundi_breadcrumb02( triggerer_name, trigger_name ) 
  1811.    trigger_enable( trigger_name, false ) 
  1812.  
  1813.    set_ignore_ai_flag( SHAUNDI_NAME, false ) 
  1814.  
  1815.    attack_safe( SHAUNDI_NAME, SHAUNDI_ATTACKERS_MEMBERS[1], false ) 
  1816.    -- Make the attackers vulnerable again and have them attack 
  1817.    for index, member in pairs( SHAUNDI_ATTACKERS_MEMBERS ) do 
  1818.       attack_safe( member, SHAUNDI_NAME, false ) 
  1819.       turn_vulnerable( member ) 
  1820.       on_death( "ss06_base_attacker_died", member ) 
  1821.    end 
  1822.  
  1823.    for index, member in pairs( SHAUNDI_DIRECT_ATTACKERS ) do 
  1824.       on_death( "ss06_shaundi_direct_attacker_death", member ) 
  1825.    end 
  1826.  
  1827.    marker_add_npc( SHAUNDI_NAME, 
  1828.                    MINIMAP_ICON_PROTECT_ACQUIRE, INGAME_EFFECT_PROTECT_ACQUIRE, SYNC_ALL ) 
  1829.  
  1830.    local group_loaded_hidden = true 
  1831.    ss06_setup_and_process_entrance_reinforcements( group_loaded_hidden ) 
  1832. end 
  1833.  
  1834. -- Sets up the entrance reinforcements and has them path up to the Saints HQ 
  1835. -- entrance and attack. 
  1836. -- 
  1837. -- group_loaded_hidden: If this is true, the group was loaded hidden and 
  1838. --                      needs to be shown. 
  1839. -- 
  1840. function ss06_setup_and_process_entrance_reinforcements( group_loaded_hidden ) 
  1841.    if ( group_loaded_hidden ) then 
  1842.       group_show( ENTRANCE_REINFORCEMENTS_GROUP_NAME ) 
  1843.    end 
  1844.    Total_attackers_remaining = Total_attackers_remaining + Entrance_reinforcements_remaining 
  1845.  
  1846.    ss06_give_weapons( ENTRANCE_REINFORCEMENTS_MEMBERS, ENTRANCE_REINFORCEMENTS_WEAPONS ) 
  1847.  
  1848.  
  1849.    vehicle_enter_group_teleport( ENTRANCE_REINFORCEMENTS_V1_PASSENGERS, 
  1850.                                  ENTRANCE_REINFORCEMENTS_VEHICLES[1] ) 
  1851.  
  1852.    vehicle_enter_group_teleport( ENTRANCE_REINFORCEMENTS_V2_PASSENGERS, 
  1853.                                  ENTRANCE_REINFORCEMENTS_VEHICLES[2] ) 
  1854.  
  1855.    vehicle_suppress_npc_exit( ENTRANCE_REINFORCEMENTS_VEHICLES[1], true ) 
  1856.    vehicle_suppress_npc_exit( ENTRANCE_REINFORCEMENTS_VEHICLES[2], true ) 
  1857.  
  1858.  
  1859.    for index, member_name in pairs( ENTRANCE_REINFORCEMENTS_MEMBERS ) do 
  1860.       on_death( "ss06_entrance_reinforcement_member_killed", member_name ) 
  1861.    end 
  1862.  
  1863.    thread_new( "ss06_do_dropoff", 1 ) 
  1864.    thread_new( "ss06_do_dropoff", 2 ) 
  1865. end 
  1866.  
  1867. function ss06_entrance_reinforcement_index_from_name( name ) 
  1868.    for i = 1, sizeof_table( ENTRANCE_REINFORCEMENTS_MEMBERS ) do 
  1869.       if ( name == ENTRANCE_REINFORCEMENTS_MEMBERS[i] ) then 
  1870.          return i 
  1871.       end 
  1872.    end 
  1873. end 
  1874.  
  1875. function ss06_character_has_been_released( character_name ) 
  1876.    if ( character_exists( character_name ) == false ) then 
  1877.       return true 
  1878.    end 
  1879.    return false 
  1880. end 
  1881.  
  1882. function ss06_do_dropoff( vehicle_index ) 
  1883.    vehicle_pathfind_to( ENTRANCE_REINFORCEMENTS_VEHICLES[vehicle_index], 
  1884.                         ENTRANCE_REINFORCEMENTS_TO_HQ_PATH, true, true ) 
  1885.  
  1886.    vehicle_pathfind_to( ENTRANCE_REINFORCEMENTS_VEHICLES[vehicle_index], 
  1887.                         ENTRANCE_REINFORCEMENTS_DROPOFF_POINTS[vehicle_index], true, true ) 
  1888.  
  1889.    for index, member_name in pairs( ENTRANCE_REINFORCEMENT_VEHICLE_PASSENGERS[vehicle_index] ) do 
  1890.       -- Have everyone but the driver get out 
  1891.       if ( index ~= 1 ) then 
  1892.          if ( ss06_character_has_been_released( member_name ) == false ) then 
  1893.             vehicle_exit( member_name ) 
  1894.             thread_new( "ss06_reinforcement_member_pathfind", member_name ) 
  1895.          end 
  1896.       end 
  1897.    end 
  1898.  
  1899.    -- Have the vehicle pathfind away 
  1900.    vehicle_pathfind_to( ENTRANCE_REINFORCEMENTS_VEHICLES[vehicle_index], 
  1901.                         ENTRANCE_REINFORCEMENTS_VEHICLE_EXIT_PATH, true, false ) 
  1902.  
  1903.    vehicle_pathfind_to( ENTRANCE_REINFORCEMENTS_VEHICLES[vehicle_index], 
  1904.                         ENTRANCE_REINFORCEMENTS_VEHICLE_DEST, false, false ) 
  1905.  
  1906.    -- Have the driver get out, and release the vehicle and driver to the world 
  1907.    vehicle_exit( ENTRANCE_REINFORCEMENT_VEHICLE_PASSENGERS[vehicle_index][1] ) 
  1908.    release_to_world( ENTRANCE_REINFORCEMENT_VEHICLE_PASSENGERS[vehicle_index][1] ) 
  1909.    release_to_world( ENTRANCE_REINFORCEMENTS_VEHICLES[vehicle_index] ) 
  1910. end 
  1911.  
  1912. function ss06_reinforcement_member_pathfind( member_name ) 
  1913.    local member_index = ss06_entrance_reinforcement_index_from_name( member_name ) 
  1914.    move_to_safe( member_name, ENTRANCE_REINFORCEMENTS_GOAL_POINTS[member_index], 3, true, true ) 
  1915.  
  1916.    --npc_leash_to_nav( member_name, ENTRANCE_REINFORCEMENTS_GOAL_POINTS[member_index], 3 ) 
  1917.  
  1918.    --attack_closest_player( member_name ) 
  1919. end 
  1920.  
  1921. function ss06_pre_pierce_reinforcements_group_do_pathing( group_index ) 
  1922.    -- Seat the people, add callbacks 
  1923.    vehicle_enter_group_teleport( PRE_PIERCE_SQUADS_MEMBERS[group_index], 
  1924.                                  PRE_PIERCE_VEHICLE_NAMES[group_index] ) 
  1925.  
  1926.    for index, member_name in pairs( PRE_PIERCE_SQUADS_MEMBERS[group_index] ) do 
  1927.       on_death( "ss06_pre_pierce_reinforcements_member_died", member_name ) 
  1928.    end 
  1929.  
  1930.    -- Pathfind 
  1931.    vehicle_pathfind_to( PRE_PIERCE_VEHICLE_NAMES[group_index], 
  1932.                         PRE_PIERCE_REINFORCEMENTS_VEHICLE_PATHS[group_index], 
  1933.                         true, true ) 
  1934.  
  1935.    -- Get out and attack the player 
  1936.    for index, member_name in pairs( PRE_PIERCE_SQUADS_MEMBERS[group_index] ) do 
  1937.       if ( ss06_character_has_been_released( member_name ) == false ) then 
  1938.          marker_add_npc( member_name, MINIMAP_ICON_KILL, INGAME_EFFECT_KILL, SYNC_ALL ) 
  1939.          Marked_member_names[member_name] = true 
  1940.          vehicle_exit( member_name ) 
  1941.       end 
  1942.    end 
  1943.    for index, member_name in pairs( PRE_PIERCE_SQUADS_MEMBERS[group_index] ) do 
  1944.       if ( ss06_character_has_been_released( member_name ) == false ) then 
  1945.          local distance, player = get_dist_closest_player_to_object( member_name ) 
  1946.          attack_safe( member_name, player, false ) 
  1947.       end 
  1948.    end 
  1949. end 
  1950.  
  1951. function ss06_pierce_flee_to_hq( flee_path_index ) 
  1952.    turn_invulnerable( PIERCE_NAME ) 
  1953.  
  1954.    -- Have him flee to the HQ, and stop there 
  1955.    vehicle_pathfind_to( PIERCE_VEHICLE_NAME, PIERCE_FLEE_PATHS[flee_path_index], true, true ) 
  1956.  
  1957.    -- Have him get out 
  1958.    vehicle_exit( PIERCE_NAME ) 
  1959.    -- If the players are in range of Pierce, simply switch to the "defend the HQ" state. 
  1960.    if ( Players_near_Pierce[LOCAL_PLAYER] or 
  1961.         Players_near_Pierce[REMOTE_PLAYER] ) then 
  1962.       ss06_setup_state( MS_DEFENDING_HQ ) 
  1963.    -- Otherwise, do the whole "he's running out of hit points!" sequence 
  1964.    else 
  1965.       Pierce_needs_to_be_rescued = true 
  1966.       objective_text_clear( LOCAL_PLAYER_INDEX ) 
  1967.       objective_text_clear( REMOTE_PLAYER_INDEX ) 
  1968.       mission_help_table( HT_HELP_PIERCE ) 
  1969.  
  1970.       local num_chunks, 
  1971.             health_chunks, 
  1972.             time_chunks_seconds = ss06_calculate_health_timer_data( SAVE_PIERCE_TIME_SECONDS, SAVE_PIERCE_DIVISION_RANGE ) 
  1973.       local warning_time_threshold = SAVE_PIERCE_TIME_SECONDS / 2 
  1974.       local warning_health_threshold = 0.5 
  1975.       Pierce_health_timer_thread_handle = thread_new( "ss06_process_health_timer", 0, HT_PIERCE_HEALTH_BAR_LABEL, 
  1976.                                                        warning_time_threshold, warning_health_threshold, 
  1977.                                                        num_chunks, health_chunks, time_chunks_seconds, 
  1978.                                                        "", HT_PIERCE_DIED_HIGHLIGHTED ) 
  1979.  
  1980.       -- Remove required-kill markers for all NPCs that are still alive 
  1981.       -- The ones who started in the entrance and the ones that were attacking Shaundi 
  1982.       ss06_remove_group_required_kill_markers( INITIAL_BASE_ATTACKERS_MEMBERS ) 
  1983.       ss06_remove_group_required_kill_markers( SHAUNDI_ATTACKERS_MEMBERS ) 
  1984.  
  1985.       -- The two groups that came before Pierce 
  1986.       -- The ones that did the dropoff 
  1987.       for vehicle_index, vehicle_passengers in pairs( ENTRANCE_REINFORCEMENT_VEHICLE_PASSENGERS ) do 
  1988.          for member_index, member_name in pairs( vehicle_passengers ) do 
  1989.             if ( member_index ~= 1 ) then 
  1990.                if ( ss06_character_has_been_released( member_name ) == false ) then 
  1991.                   if ( Marked_member_names[member_name] == true ) then 
  1992.                      marker_remove_npc( member_name, SYNC_ALL ) 
  1993.                      Marked_member_names[member_name] = false 
  1994.                   end 
  1995.                end 
  1996.             end 
  1997.          end 
  1998.       end 
  1999.       -- The ones that drove up to either side of the doors 
  2000.       for squad_index, pre_pierce_squad in pairs( PRE_PIERCE_SQUADS_MEMBERS ) do 
  2001.          ss06_remove_group_required_kill_markers( pre_pierce_squad ) 
  2002.       end 
  2003.  
  2004.       -- Mark Pierce with a protect/acquire marker 
  2005.       marker_add_npc( PIERCE_NAME, MINIMAP_ICON_PROTECT_ACQUIRE, INGAME_EFFECT_PROTECT_ACQUIRE, SYNC_ALL ) 
  2006.  
  2007.       -- Leash him to his trigger 
  2008.       npc_leash_to_nav( PIERCE_NAME, NEAR_PIERCE_TRIGGER_NAME, PIERCE_LEASH_DISTANCE ) 
  2009.    end 
  2010. end 
  2011.  
  2012. function ss06_pierce_pursuit_group_do_chase( group_index ) 
  2013.    for index, member_name in pairs( PIERCE_PURSUIT_SQUADS_MEMBERS[group_index] ) do 
  2014.       on_death( "ss06_base_attacker_died", member_name ) 
  2015.    end 
  2016.  
  2017.    vehicle_chase( PIERCE_PURSUIT_VEHICLE_NAMES[group_index], PIERCE_NAME ) 
  2018. end 
  2019.  
  2020. function ss06_reached_shaundi_trigger() 
  2021.    trigger_enable( REACHED_SHAUNDI_TRIGGER, false ) 
  2022.  
  2023.    ss06_setup_state( MS_SAVED_SHAUNDI, false ) 
  2024. end 
  2025.  
  2026. function ss06_enter_starting_box( human_name, trigger_name ) 
  2027.    if ( human_name == LOCAL_PLAYER ) then 
  2028.       Players_in_starting_box[LOCAL_PLAYER_INDEX] = true 
  2029.    elseif( human_name == REMOTE_PLAYER ) then 
  2030.       Players_in_starting_box[REMOTE_PLAYER_INDEX] = true 
  2031.    end 
  2032. end 
  2033.  
  2034. function enter_annex( human_name, trigger_name ) 
  2035.    if ( human_name == LOCAL_PLAYER ) then 
  2036.       Players_in_annex[LOCAL_PLAYER_INDEX] = true 
  2037.    elseif( human_name == REMOTE_PLAYER ) then 
  2038.       Players_in_annex[REMOTE_PLAYER_INDEX] = true 
  2039.    end 
  2040. end 
  2041.  
  2042.  
  2043. function ss06_give_weapons( members, weapons ) 
  2044.    for index, member_name in pairs( members ) do 
  2045.       inv_item_remove_all( member_name ) 
  2046.  
  2047.       inv_item_add( weapons[index], 1, member_name ) 
  2048.    end 
  2049. end 
  2050.  
  2051. function ss06_near_pierce( human_name, trigger_name ) 
  2052.    Players_near_Pierce[human_name] = true 
  2053.  
  2054.    if ( Pierce_health_timer_thread_handle ~= INVALID_THREAD_HANDLE ) then 
  2055.       ss06_setup_state( MS_DEFENDING_HQ ) 
  2056.    end 
  2057. end 
  2058.  
  2059. function ss06_left_pierce_area( human_name, trigger_name ) 
  2060.    Players_near_Pierce[human_name] = false 
  2061. end 
  2062.  
  2063. -- Callback when either player enters the Saints HQ defend-the-base area. 
  2064. -- 
  2065. function ss06_entered_saints_hq_area( human_name, trigger_name ) 
  2066.    if ( human_name == LOCAL_PLAYER ) then 
  2067.       Players_in_defense_area[LOCAL_PLAYER_INDEX] = true 
  2068.    elseif ( human_name == REMOTE_PLAYER ) then 
  2069.       Players_in_defense_area[REMOTE_PLAYER_INDEX] = true 
  2070.    end 
  2071.  
  2072.    if ( Shaundi_saved ) then 
  2073.       local sync_type = sync_from_player( human_name ) 
  2074.       waypoint_remove( sync_type ) 
  2075.       minimap_icon_remove_navpoint( SAINTS_HQ_AREA, sync_type ) 
  2076.    end 
  2077.    ss06_stop_failure_timer( human_name ) 
  2078. end 
  2079.  
  2080. -- Callback when either player leaves the Saints HQ defend-the-base area. 
  2081. -- 
  2082. function ss06_left_saints_hq_area( human_name, trigger_name ) 
  2083.    if ( human_name == LOCAL_PLAYER ) then 
  2084.       Players_in_defense_area[LOCAL_PLAYER_INDEX] = false 
  2085.    elseif ( human_name == REMOTE_PLAYER ) then 
  2086.       Players_in_defense_area[REMOTE_PLAYER_INDEX] = false 
  2087.    end 
  2088.  
  2089.    if ( Shaundi_saved ) then 
  2090.       local sync_type = sync_from_player( human_name ) 
  2091.       waypoint_add( SAINTS_HQ_AREA, sync_type ) 
  2092.       minimap_icon_add_navpoint_radius( SAINTS_HQ_AREA, MINIMAP_ICON_LOCATION, SAINTS_HQ_AREA_RADIUS_METERS, nil, sync_type ) 
  2093.       ss06_start_failure_timer( human_name ) 
  2094.    end 
  2095. end 
  2096.  
  2097. -- Starts the "return to the HQ's defense" timer 
  2098. -- Called when a player wanders away from the HQ 
  2099. -- when they should be defending it 
  2100. -- 
  2101. function ss06_start_failure_timer( human_name ) 
  2102.    local sync_type = sync_from_player( human_name ) 
  2103.  
  2104.    Player_failure_timer_thread_handles[human_name] = thread_new( "ss06_failure_timer", FAILURE_TIMEOUT_ON_LEAVE_DEFENSE_AREA_SECONDS, 6,  sync_type ) 
  2105. end 
  2106.  
  2107. function ss06_failure_timer( time_seconds, num_updates, sync_type ) 
  2108.    local time_remaining_seconds = time_seconds 
  2109.    local increment_seconds = time_seconds / num_updates 
  2110.  
  2111.    mission_help_table_nag( HT_RETURN_TO_HQ_DEFENSE_SECONDS_TEXT, time_remaining_seconds, "", sync_type ) 
  2112.    while ( time_remaining_seconds > 0 ) do 
  2113.       delay( increment_seconds ) 
  2114.       time_remaining_seconds = time_remaining_seconds - increment_seconds 
  2115.       mission_help_table_nag( HT_RETURN_TO_HQ_DEFENSE_SECONDS_TEXT, time_remaining_seconds, "", sync_type ) 
  2116.    end 
  2117.    mission_end_failure( MISSION_NAME, HT_LEFT_HQ_UNDEFENDED_FAILURE ) 
  2118. end 
  2119.  
  2120. -- Stops the "return to the HQ's defense" timer 
  2121. -- Called when a player returns to the HQ 
  2122. -- after leaving the defense area 
  2123. -- 
  2124. function ss06_stop_failure_timer( human_name ) 
  2125.    if ( Player_failure_timer_thread_handles[human_name] ~= INVALID_THREAD_HANDLE ) then 
  2126.       thread_kill( Player_failure_timer_thread_handles[human_name] ) 
  2127.       Player_failure_timer_thread_handles[human_name] = INVALID_THREAD_HANDLE 
  2128.    end 
  2129. end 
  2130.  
  2131. -- The south trigger callback in the starting zone. Spawns an  
  2132. -- attack squad to attack the player. 
  2133. -- 
  2134. function ss06_south_trigger( human_name, trigger_name ) 
  2135.    -- The south trigger needs to catch either player to spawn an attack 
  2136.    -- squad nearby 
  2137.    if ( ss06_either_player_triggered( human_name, Players_south_trigger, TRIGGER_ONCE_FIRST_TRIGGERER ) ) then 
  2138.       trigger_enable( SOUTH_TRIGGER_NAME, false ) 
  2139.       ss06_show_attack_group( ON_FOOT_SQUAD_GROUP_NAMES[SOUTH_ATTACK_SQUAD], 
  2140.                               ON_FOOT_SQUAD_GROUP_NAMES_COOP[SOUTH_ATTACK_SQUAD]  ) 
  2141.       ss06_attack_squad_attack( ON_FOOT_SQUAD_MEMBERS[SOUTH_ATTACK_SQUAD], 
  2142.                                 ON_FOOT_SQUAD_MEMBERS_COOP[SOUTH_ATTACK_SQUAD], human_name, true ) 
  2143.    end 
  2144. end 
  2145.  
  2146. -- The north trigger callback in the starting zone. Spawns an  
  2147. -- attack squad to attack the player. 
  2148. -- 
  2149. function ss06_north_trigger( human_name, trigger_name ) 
  2150.    -- The north trigger needs to catch either player to spawn an attack 
  2151.    -- squad nearby 
  2152.    if ( ss06_either_player_triggered( human_name, Players_north_trigger, TRIGGER_ONCE_FIRST_TRIGGERER ) ) then 
  2153.       trigger_enable( NORTH_TRIGGER_NAME, false ) 
  2154.       ss06_show_attack_group( ON_FOOT_SQUAD_GROUP_NAMES[NORTH_ATTACK_SQUAD], 
  2155.                               ON_FOOT_SQUAD_GROUP_NAMES_COOP[NORTH_ATTACK_SQUAD] ) 
  2156.       ss06_attack_squad_attack( ON_FOOT_SQUAD_MEMBERS[NORTH_ATTACK_SQUAD], 
  2157.                                 ON_FOOT_SQUAD_MEMBERS_COOP[NORTH_ATTACK_SQUAD], human_name, true ) 
  2158.    end 
  2159. end 
  2160.  
  2161. -- The south camper trigger callback. Causes the campers at the blockade to 
  2162. -- pop out and attack the player. 
  2163. -- 
  2164. function ss06_south_camper_trigger( human_name, trigger_name ) 
  2165.    trigger_enable( SOUTH_CAMPER_TRIGGER_NAME, false ) 
  2166.    for index, member in pairs(SOUTH_CAMPER_NAMES) do 
  2167.       set_ignore_ai_flag( member, false ) 
  2168.       crouch_stop( member ) 
  2169.       attack_safe( member, human_name, false ) 
  2170.    end 
  2171. end 
  2172.  
  2173. -- The north camper trigger callback. Causes the campers at the blockade to 
  2174. -- pop out and attack the player. 
  2175. -- 
  2176. function ss06_north_camper_trigger( human_name, trigger_name ) 
  2177.    trigger_enable( NORTH_CAMPER_TRIGGER_NAME, false ) 
  2178.    for index, member in pairs(NORTH_CAMPER_NAMES) do 
  2179.       set_ignore_ai_flag( member, false ) 
  2180.       crouch_stop( member ) 
  2181.       attack_safe( member, human_name, false ) 
  2182.    end 
  2183. end 
  2184.  
  2185. -- Attack squad that appears if the player tries to exit from the side alley 
  2186. -- 
  2187. -- human_name: The player that hit the alley exit trigger 
  2188. -- trigger_name: The name of the alley exit trigger 
  2189. -- 
  2190. function ss06_alternate_escape_attack( human_name, trigger_name ) 
  2191.    local either_triggered = ss06_either_player_triggered( human_name ) 
  2192.    if ( either_triggered ) then 
  2193.       trigger_enable( trigger_name, false ) 
  2194.       ss06_show_attack_group( ALT_ESCAPE_GROUP_NAME, ALT_ESCAPE_COOP_GROUP_NAME ) 
  2195.       ss06_seat_attack_squad( ALT_ESCAPE_SQUAD_MEMBERS, ALT_ESCAPE_COOP_MEMBERS, ALT_ESCAPE_VEHICLE_NAME, ALT_ESCAPE_VEHICLE_NAME ) 
  2196.       --ss06_attack_squad_attack( ALT_ESCAPE_SQUAD_MEMBERS, ALT_ESCAPE_COOP_MEMBERS, human_name ) 
  2197.       vehicle_speed_override( ALT_ESCAPE_VEHICLE_NAME, ATTACK_CAR_OVERRIDE_SPEED )  
  2198.       vehicle_pathfind_to( ALT_ESCAPE_VEHICLE_NAME, ALT_ESCAPE_ATTACKER_STOP_NAVPOINT_NAME, true, true ) 
  2199.    end 
  2200. end 
  2201.  
  2202. -- Function to deal with trigger for multiple players 
  2203. -- 
  2204. -- human_name: The name of the human that triggered it 
  2205. -- players_trigger_trackers: (Optional if trigger_option is TRIGGER_MULTIPLE_TIMES. ) Variables that track the trigger 
  2206. -- trigger_option: (Optional) If not set, defaults to TRIGGER_MULTIPLE_TIMES. 
  2207. -- 
  2208. function ss06_either_player_triggered( human_name, players_trigger_trackers, trigger_option ) 
  2209.  
  2210.    local local_p_triggered 
  2211.    local remote_p_triggered 
  2212.  
  2213.    -- Check to see if it's a player 
  2214.    if ( human_name == LOCAL_PLAYER ) then 
  2215.       local_p_triggered = true 
  2216.    elseif ( human_name == REMOTE_PLAYER ) then 
  2217.       remote_p_triggered = true 
  2218.    end 
  2219.  
  2220.    -- Trigger multiple times - if either player triggered, return true 
  2221.    if ( trigger_option == nil or trigger_option == TRIGGER_MULTIPLE_TIMES ) then 
  2222.       if ( local_p_triggered == true ) then 
  2223.          return true 
  2224.       elseif ( remote_p_triggered == true ) then 
  2225.          return true 
  2226.       end 
  2227.    -- Trigger once for the first person that triggers it 
  2228.    elseif ( trigger_option == TRIGGER_ONCE_FIRST_TRIGGERER ) then 
  2229.       if ( ( local_p_triggered or remote_p_triggered ) and  
  2230.            ( players_trigger_trackers[LOCAL_PLAYER_INDEX] or players_trigger_trackers[2] ) ) then 
  2231.          return false 
  2232.       else 
  2233.          if ( local_p_triggered ) then 
  2234.             players_trigger_trackers[LOCAL_PLAYER_INDEX] = true 
  2235.          elseif ( remote_p_triggered ) then 
  2236.             players_trigger_trackers[REMOTE_PLAYER_INDEX] = true 
  2237.          end 
  2238.          return true 
  2239.       end 
  2240.    -- Trigger once for each player 
  2241.    elseif ( trigger_option == TRIGGER_ONCE_PER_PLAYER ) then 
  2242.       if ( local_p_triggered == true ) then 
  2243.          if ( players_trigger_trackers[LOCAL_PLAYER_INDEX] == false ) then 
  2244.             players_trigger_trackers[LOCAL_PLAYER_INDEX] = true 
  2245.             return true 
  2246.          end 
  2247.       elseif ( remote_p_triggered == true ) then 
  2248.          if ( players_trigger_trackers[REMOTE_PLAYER_INDEX] == false ) then 
  2249.             players_trigger_trackers[REMOTE_PLAYER_INDEX] = true 
  2250.             return true 
  2251.          end 
  2252.       else 
  2253.          return false 
  2254.       end 
  2255.    end 
  2256.    return false 
  2257. end 
  2258.  
  2259. -- Checks to see if a trigger has been triggered by all the players. 
  2260. -- In coop, that's two. In single player, that's one. 
  2261. -- 
  2262. -- human_name: Name of the one that triggered the trigger. 
  2263. -- Players_trigger_trackers: Table of two booleans that track player 1 and 2's 
  2264. --                      previous status of triggering this trigger. 
  2265. -- trigger_multiple_times: (Optional) Set to "true" if the trigger should be 
  2266. --                     allowed to be triggered multiple times. 
  2267. -- 
  2268. function ss06_all_players_triggered( human_name, players_trigger_trackers, trigger_multiple_times ) 
  2269.    local coop_on = coop_is_active() 
  2270.  
  2271.    -- If both trackers mark this trigger as being triggered, then it's already been 
  2272.    -- triggered and shouldn't be re-triggered. 
  2273.    -- ( If "trigger multiple times" is set, it will have cleared these values already. 
  2274.    --   See the last "if" statement in this function. ) 
  2275.    if ( players_trigger_trackers[LOCAL_PLAYER_INDEX] == true ) then 
  2276.       if ( coop_on == false ) then 
  2277.          return false 
  2278.       elseif ( players_trigger_trackers[REMOTE_PLAYER_INDEX] == true ) then 
  2279.          return false 
  2280.       end 
  2281.    end 
  2282.  
  2283.    -- Check to see who triggered the trigger 
  2284.    if ( human_name == LOCAL_PLAYER ) then 
  2285.       players_trigger_trackers[LOCAL_PLAYER_INDEX] = true 
  2286.    elseif ( human_name == REMOTE_PLAYER ) then 
  2287.       players_trigger_trackers[REMOTE_PLAYER_INDEX] = true 
  2288.    end 
  2289.  
  2290.    -- Figure out if the trigger has been triggered for everyone 
  2291.    local trigger_triggered_for_all_players = false 
  2292.  
  2293.    if ( players_trigger_trackers[LOCAL_PLAYER_INDEX] ) then 
  2294.       if ( coop_on == false ) then 
  2295.          trigger_triggered_for_all_players = true 
  2296.       elseif ( players_trigger_trackers[REMOTE_PLAYER_INDEX] ) then 
  2297.          trigger_triggered_for_all_players = true 
  2298.       end 
  2299.    end 
  2300.  
  2301.    -- If we're supposed to track if the trigger is triggered more than once, then 
  2302.    -- reset the "triggered by player x" trigger values if the trigger was triggered 
  2303.    if ( trigger_multiple_times ) then 
  2304.       if ( trigger_triggered_for_all_players ) then 
  2305.          players_trigger_trackers[LOCAL_PLAYER_INDEX] = false 
  2306.          players_trigger_trackers[REMOTE_PLAYER_INDEX] = false 
  2307.       end 
  2308.    end 
  2309.  
  2310.    return trigger_triggered_for_all_players 
  2311. end 
  2312.  
  2313. -- Creates the attack wave group specified 
  2314. -- 
  2315. -- group_name: The name of the attack wave group 
  2316. -- group_name_coop: The coop additions to the attack wave group, might be nil 
  2317. -- 
  2318. function ss06_spawn_attack_group( group_name, group_name_coop ) 
  2319.    -- Create the squad, and its coop counterpart if applicable 
  2320.    group_create( group_name, true ) 
  2321.    if ( coop_is_active() and group_name_coop ~= nil ) then 
  2322.       group_create( group_name_coop, true ) 
  2323.    end 
  2324. end 
  2325.  
  2326. -- Creates the attack squad at the specified index, 
  2327. -- hidden 
  2328. -- 
  2329. -- group_name: The name of the attack group 
  2330. -- group_name_coop: The coop additions to the attack group, might be nil 
  2331. -- 
  2332. function ss06_spawn_hidden_attack_group( group_name, group_name_coop ) 
  2333.  
  2334.    -- Create the squad, and its coop counterpart if applicable 
  2335.    group_create_hidden( group_name, true ) 
  2336.    if ( coop_is_active() and group_name_coop ~= nil ) then 
  2337.       group_create_hidden( group_name_coop, true ) 
  2338.    end 
  2339. end 
  2340.  
  2341. -- Seats an attack squad in vehicles. 
  2342. -- 
  2343. -- squad_members: The squad members 
  2344. -- squad_members_coop: The coop squad members ( extra squad for coop-play, might be nil ) 
  2345. -- squad_vehicle: The squad's vehicle 
  2346. -- squad_vehicle_coop: The coop squad's vehicle 
  2347. -- 
  2348. function ss06_seat_attack_squad( squad_members, squad_members_coop, squad_vehicle, squad_vehicle_coop ) 
  2349.  
  2350.    vehicle_enter_group_teleport( squad_members, squad_vehicle ) 
  2351.    --for index, member in pairs( squad_members[squad_index] ) do 
  2352.    --   vehicle_enter( member, squad_vehicle[squad_index] ) 
  2353.    --end 
  2354.  
  2355.    if ( coop_is_active() and squad_members_coop ~= nil and sizeof_table( squad_members_coop ) > 0 ) then 
  2356.       --for index, member in pairs( squad_members_coop[squad_index] ) do 
  2357.       --   vehicle_enter( member, squad_vehicle_coop[squad_index] ) 
  2358.       --end 
  2359.       vehicle_enter_group_teleport( squad_members_coop, squad_vehicle_coop ) 
  2360.    end 
  2361. end 
  2362.  
  2363. -- Have the specified squad_members attack a target 
  2364. -- 
  2365. -- squad_members: The squad_members 
  2366. -- squad_members_coop: The coop additions to the squad_members ( can be nil ) 
  2367. -- target_name: The name of the target to attack 
  2368. -- never_give_up_never_surrender: Sets the 'cant_flee' flag for the NPCs if true. 
  2369. -- 
  2370. function ss06_attack_squad_attack( squad_members, squad_members_coop, target_name, never_give_up_never_surrender ) 
  2371.    -- Attack, but don't yield thread control 
  2372.    for index, member in pairs(squad_members) do 
  2373.       if ( never_give_up_never_surrender == true ) then 
  2374.          set_cant_flee_flag( member, true ) 
  2375.       end 
  2376.       attack_safe( member, target_name, false )    
  2377.    end 
  2378.  
  2379.    if ( coop_is_active() and squad_members_coop ~= nil ) then 
  2380.       -- Attack, but don't yield thread control 
  2381.       for index, member in pairs(squad_members_coop) do 
  2382.          if ( never_give_up_never_surrender == true ) then 
  2383.             set_cant_flee_flag( member, true ) 
  2384.          end 
  2385.          attack_safe( member, target_name, false )    
  2386.       end 
  2387.    end 
  2388. end 
  2389.  
  2390. -- Puts a marker over all the squad members in the specified attack squad. 
  2391. -- 
  2392. -- squad_members: The squad members 
  2393. -- squad_members_coop: The coop squad members ( extra squad for coop-play, might be nil ) 
  2394. -- squad_vehicle: The squad's vehicle 
  2395. -- squad_vehicle_coop: The coop squad's vehicle 
  2396. -- 
  2397. function ss06_mark_attack_squad( squad_members, squad_members_coop, squad_vehicle, squad_vehicle_coop ) 
  2398.  
  2399.    -- For each NPC, add a marker 
  2400.    for index, member in pairs( squad_members ) do 
  2401.       marker_add_npc(member, MINIMAP_ICON_KILL, INGAME_EFFECT_KILL, SYNC_ALL) 
  2402.       Marked_member_names[member] = true 
  2403.    end 
  2404.    -- Add a vehicle marker for the squad's vehicle 
  2405.    -- marker_add_vehicle(squad_vehicle, MINIMAP_ICON_KILL, INGAME_EFFECT_KILL, SYNC_ALL )  
  2406.  
  2407.    -- If we're in coop, do this for any existing coop attack squads too 
  2408.    if ( coop_is_active() and squad_members_coop ~= nil ) then 
  2409.     
  2410.       -- For each NPC, add a marker 
  2411.       for index, member in pairs( squad_members_coop ) do 
  2412.          marker_add_npc(member, MINIMAP_ICON_KILL, INGAME_EFFECT_KILL, SYNC_ALL)  
  2413.          Marked_member_names[member] = true 
  2414.       end 
  2415.       -- Add a vehicle marker for the squad's vehicle 
  2416.       -- marker_add_vehicle(squad_vehicle_coop, MINIMAP_ICON_KILL, INGAME_EFFECT_KILL, SYNC_ALL )  
  2417.    end 
  2418. end 
  2419.  
  2420. -- Shows a hidden attack group 
  2421. -- 
  2422. -- group_name: The name of the attack squad group 
  2423. -- group_name_coop: The coop additions to the attack squad 
  2424. -- 
  2425. function ss06_show_attack_group( group_name, group_name_coop ) 
  2426.    group_show( group_name ) 
  2427.    if ( coop_is_active() and group_name_coop ~= nil ) then 
  2428.       group_show( group_name_coop ) 
  2429.    end 
  2430. end 
  2431.  
  2432. -- Releases a wave's group to the world 
  2433. -- 
  2434. -- group_name: The name of the group 
  2435. -- group_name_coop: The coop additions to the group 
  2436. -- 
  2437. function ss06_release_attack_group( group_name, group_name_coop ) 
  2438.    --marker_remove_group( group_name ) 
  2439.    release_to_world( group_name ) 
  2440.    if ( coop_is_active() and group_name_coop ~= nil ) then 
  2441.       --marker_remove_group( group_name_coop ) 
  2442.       release_to_world( group_name_coop ) 
  2443.    end 
  2444. end 
  2445.  
  2446. function ss06_success() 
  2447. end 
  2448.