--[[
m20.lua
SR3 Mission Script
DATE: 8/23/2010
AUTHOR: Nick Heilmann
]]--
HELI_DEFAULT_SPEED = 45
HELI_HIGH_SPEED = 90
VEHICLE_SEAT_DRIVER = 0
VEHICLE_SEAT_PASSENGER = 1
VEHICLE_SEAT_HELI_BACK_DOOR = 2
VEHICLE_SEAT_WRESTLER_BACK_SEAT = 3
PEDS_TO_HIT = 15
M20_LW_APPROACH_DIST = 50
M20_CTH_FLEE_DIST = 150
M20_CTH_CRASH_DIST = 10
M20_RC_RANGE = 500 -- default is currently 200
M20_ANGEL_MAX_BANK = 12 -- degrees
-- Debug flags --
M20_DEBUG = {
infinity = 999999999,
}
-- Tweakable Parameters --
M20_status = {
gym_reached = false,
boat_reached = false,
player_has_rc_vehicle = false,
rc_car_destroyed = false,
rc_car_peds_hit = 0,
rc_boat_destroyed = false,
rc_tank_destroyed = false,
beach_party_crashed = false,
circular_path_reached = false,
wrestler_heli_destroyed = false,
stag_tanks_remaining = 0,
my_rc_boat = nil,
}
-- Weapons --
M20_weapon = {
rc_gun = "Special-RCVehicleGun",
cleanup = { "Special-RCVehicleGun" },
}
-- Camera Navpoints --
M20_cam_nav = {
rc_car = { "Nav Cam RC Car 001", "Nav Cam RC Car 002" },
beach = { "Nav Beach Cam 001", "Nav Beach Cam 002" },
}
-- Navpoints --
M20_navpoint = {
cp_starts = {
mission_start = { player_local = "Nav CP Mission Start Local", player_remote = "Nav CP Mission Start Remote" },
crash_the_car = { player_local = "Nav CP CTC Local", player_remote = "Nav CP CTC Remote" },
crash_the_boat = { player_local = "Nav CP CTB Local", player_remote = "Nav CP CTB Remote" },
crash_the_heli = { player_local = "Nav CP CTH Local", player_remote = "Nav CP CTH Remote" },
airport = { player_local = "Nav CP LW Local", player_remote = "Nav CP LW Remote" },
},
angel_heli_float = {
bar = "Nav Heli Float Bar",
bar_coop = "Nav Heli Mission Start Coop",
gym = "Nav Heli Float Gym",
boat = "Nav Heli Float Boat",
heli = "Nav Heli Float Heli",
airport = "Nav Heli Float Airport",
},
angel_heli_teleport = {
bar = "Nav Heli Teleport Bar",
bar_coop = "Nav Heli Mission Start Coop",
gym = "Nav Heli Teleport Gym",
boat = "Nav Heli Teleport Boat",
heli = "Nav Heli Teleport Heli",
airport = "Nav Heli Teleport Airport",
},
gas_station = "Nav Gas Station",
beach_party = "Nav Beach Party",
ramp = "Nav Ramp",
tourist_heli_rand = { "Nav Heli Rand 001<001>", "Nav Heli Rand 002<001>", "Nav Heli Rand 003<001>", "Nav Heli Rand 004<001>", "Nav Heli Rand 005<001>", "Nav Heli Rand 006<001>",
"Nav Heli Rand 007<001>", "Nav Heli Rand 008<001>", "Nav Heli Rand 009<001>", "Nav Heli Rand 010<001>", "Nav Heli Rand 011<001>", "Nav Heli Rand 012<001>" },
wrestler_heli_rand = { "Nav Heli Rand 001", "Nav Heli Rand 002", "Nav Heli Rand 003", "Nav Heli Rand 004", "Nav Heli Rand 005", "Nav Heli Rand 006",
"Nav Heli Rand 007", "Nav Heli Rand 008", "Nav Heli Rand 009", "Nav Heli Rand 010", "Nav Heli Rand 011", "Nav Heli Rand 012" },
wrestler_teleport = "Nav Wrestler Teleport",
rc_heli_teleport = "Nav RC Heli Teleport",
airport_lw_approach = "Nav Approach LW Plane <001>",
end_local = "Nav End Local",
end_remote = "Nav End Remote",
success_local = "Nav Success Local",
success_remote = "Nav Success Remote",
}
-- Scripted Paths --
M20_scripted_path = {
angel_enter = "SP Angel Enter",
heli_to_gym = "SP Heli To Gym",
heli_to_boat = "SP Heli To Boat",
heli_to_heli = "SP Heli to Heli",
heli_to_airport = "SP Heli To Airport",
heli_around_airport = "SP Heli Around Airport",
cth_target_flee_paths = {
[ 1 ] = { sp_name = "SP CTH Flee Path <001>", n = { 6, 7 }, },
[ 2 ] = { sp_name = "SP CTH Flee Path <002>", p = { -3, -4, -8 }, n = { 9 }, },
[ 3 ] = { sp_name = "SP CTH Flee Path <003>", p = { -5 }, n = { 2, -4, -8 }, super_slow = true, },
[ 4 ] = { sp_name = "SP CTH Flee Path <004>", p = { 5, -6 }, n = { 2, -3, -8 }, super_slow = true, },
[ 5 ] = { sp_name = "SP CTH Flee Path <005>", p = { 4, -6 }, n = { 3 }, },
[ 6 ] = { sp_name = "SP CTH Flee Path <006>", p = { 7 }, n = { 4, 5 }, },
[ 7 ] = { sp_name = "SP CTH Flee Path <007>", p = { 6 }, n = { -9, 8 }, super_slow = true, },
[ 8 ] = { sp_name = "SP CTH Flee Path <008>", p = { -9, -7 }, n = { 2, -3, -4 }, },
[ 9 ] = { sp_name = "SP CTH Flee Path <009>", p = { -2 }, n = { -7, 8 }, super_slow = true, },
},
airport_wrestler_flee_paths = {
[ 1 ] = { sp_name = "SP Wrestler Flee<001>", p = { 8, 10 }, n = { 2, 9, 11 } },
[ 2 ] = { sp_name = "SP Wrestler Flee<002>", p = { -1, 9, 11 }, n = { 3 } },
[ 3 ] = { sp_name = "SP Wrestler Flee<003>", p = { -2 }, n = { 4, 5 } },
[ 4 ] = { sp_name = "SP Wrestler Flee<004>", p = { -3, 5 }, n = { -6, -7, 8, -11 } },
[ 5 ] = { sp_name = "SP Wrestler Flee<005>", p = { -3, 4 }, n = { 6, 7 } },
[ 6 ] = { sp_name = "SP Wrestler Flee<006>", p = { -5, 7 }, n = { -7, 8, -11 } },
[ 7 ] = { sp_name = "SP Wrestler Flee<007>", p = { -5, 6 }, n = { -4, -6, 8, -11 } },
[ 8 ] = { sp_name = "SP Wrestler Flee<008>", p = { -4, -6, -7, -11 }, n = { 1, -10 } },
[ 9 ] = { sp_name = "SP Wrestler Flee<009>", p = { -1, 2, 11 }, n = { 10 } },
[ 10 ] = { sp_name = "SP Wrestler Flee<010>", p = { -9 }, n = { 1, -8 } },
[ 11 ] = { sp_name = "SP Wrestler Flee<011>", p = { -1, 2, 9, 11 }, n = { -4, -6, -7, 8 } },
},
}
-- Triggers --
M20_trigger = {
gym = "Trigger Gym",
boat = "Trigger Boat",
beach_party = "Trigger Beach Party",
circular_path = "Trigger Circular Path",
tank_path = "Trigger Tank Path",
gas_station = {
"Trigger Gas Station<001>", "Trigger Gas Station<002>", "Trigger Gas Station<003>",
"Trigger Gas Station<004>", "Trigger Gas Station<005>", "Trigger Gas Station<006>",
}
}
--[[ Items --
M20_item = {
}
]]-- Characters --
M20_char = {
angel = "NPC Angel MS",
car_target = { "NPC Car Target 001", "NPC Car Target 002", "NPC Car Target 003" },
rc_car = { "NPC RC Car Driver", "NPC RC Car Passenger" },
rc_boat = { "NPC RC Boat Driver 001", "NPC RC Boat Driver 002", "NPC RC Boat Driver 003" },
rc_heli = "NPC RC Heli Driver",
beach_wrestler = "NPC Wrestler Beach",
wrestler = "NPC Heli Wrestler",
pilot = "NPC Heli Pilot",
stag_tank = {
"NPC STAG Tank 001", "NPC STAG Tank 002", "NPC STAG Tank 003", "NPC STAG Tank 004",
"NPC STAG Tank 005", "NPC STAG Tank 006", "NPC STAG Tank 007", "NPC STAG Tank 008",
"NPC STAG Tank 009", "NPC STAG Tank 010", "NPC STAG Tank 011", "NPC STAG Tank 012",
"NPC STAG Tank 013", "NPC STAG Tank 014",
"NPC STAG Tank 003<001>", "NPC STAG Tank 004<001>", "NPC STAG Tank 005<001>", "NPC STAG Tank 006<001>",
"NPC STAG Tank 007<001>", "NPC STAG Tank 008<001>", "NPC STAG Tank 009<001>", "NPC STAG Tank 010<001>",
"NPC STAG Tank 011<001>", "NPC STAG Tank 012<001>",
},
stag_tank_driver = "NPC STAG Tank Driver",
last_wrestler = "NPC Last Wrestler",
mascots = {
{ "NPC Mascot<001>", "NPC Mascot<002>", "NPC Mascot<003>", "NPC Mascot<004>", },
{ "NPC Mascot<005>", "NPC Mascot<006>", "NPC Mascot<007>", "NPC Mascot<008>", },
},
}
-- Vehicles --
M20_vehicle = {
angel_heli = "Veh Angel Heli MS",
rc_car = "Veh RC Car",
rc_boat = { "Veh RC Boat 001", "Veh RC Boat 002", "Veh RC Boat 003" },
rc_heli = "Veh RC Heli",
beach_party = { "Veh Beach Party 001", "Veh Beach Party 002", "Veh Beach Party 003", "Veh Beach Party 007" },
wrestler = "Veh Heli Wrestler",
stag_tank = { "Veh STAG Tank 001", "Veh STAG Tank 002", "Veh STAG Tank 003", "Veh STAG Tank 004", "Veh STAG Tank 005", "Veh STAG Tank 006" , "Veh STAG Tank 007" },
lw_plane = "Veh LW Plane",
lw_truck = "Veh Last Wrestler Truck"
}
-- Groups --
M20_group = {
angel = { name = "GRP Angel MS", chars = { M20_char.angel }, vehicles = { M20_vehicle.angel_heli } },
car_target = { name = "GRP Car Targets", chars = { M20_char.car_target } },
rc_car = { name = "GRP RC Car", chars = M20_char.rc_car, vehicles = { M20_vehicle.rc_car } },
rc_boat = { name = "GRP RC Boat", chars = M20_char.rc_boat, vehicles = M20_vehicle.rc_boat },
rc_heli = { name = "GRP RC Heli", chars = { M20_char.rc_heli }, vehicles = { M20_vehicle.rc_heli } },
beach_party = { name = "GRP Beach Party", chars = { M20_char.beach_wrestler }, vehicles = { M20_vehicle.beach_party } }, -- Bunch of NPCs and vehicles, but we don't really care about (most of) them
wrestler = { name = "GRP Heli Wrestler", chars = { M20_char.wrestler, M20_char.pilot, }, vehicles = { M20_vehicle.wrestler } },
stag_tank = { name = "GRP STAG Tank", chars = M20_char.stag_tank, vehicles = M20_vehicle.stag_tank },
airport = { name = "GRP Airport", chars = { }, vehicles = { M20_vehicle.lw_plane } },
last_wrestler = { name = "GRP Last Wrestler", chars = { M20_char.last_wrestler }, vehicles = { } },
airport_tank_driver = { name = "GRP STAG Tank Driver", chars = { M20_char.stag_tank_driver }, vehicles = { } },
mascots = {
{ name = "GRP Mascots 01", chars = M20_char.mascots[ 1 ], },
{ name = "GRP Mascots 02", chars = M20_char.mascots[ 2 ], },
},
}
-- tracks the peds that have been hit during the "crash the peds" objective
M20_peds_hit = { }
M20_convo_queue = { }
M20_previous_rc_range = 0
--[[ Spawn Groups --
M20_spawn_group = {
}
-- Spawn Regions --
M20_spawn_region = {
}
]]-- Threads --
M20_thread = {
angel_heli_float = INVALID_THREAD_HANDLE,
angel_enter_phone_call = INVALID_THREAD_HANDLE,
viola_phone_call_to_gym = INVALID_THREAD_HANDLE,
player_tells_angel_plan = INVALID_THREAD_HANDLE,
fly_to_gym = INVALID_THREAD_HANDLE,
fly_to_boat = INVALID_THREAD_HANDLE,
wait_for_enter = INVALID_THREAD_HANDLE,
rc_car_enter = { },
beach_party_polling = INVALID_THREAD_HANDLE,
boat_flipped_watchdog = INVALID_THREAD_HANDLE,
boat_on_land_watchdog = INVALID_THREAD_HANDLE,
crash_the_helicopter_convo = INVALID_THREAD_HANDLE,
follow_rc_vehicle = INVALID_THREAD_HANDLE,
heli_rand_flying = INVALID_THREAD_HANDLE,
heli_to_heli = INVALID_THREAD_HANDLE,
one_last_wrestler = INVALID_THREAD_HANDLE,
starting_convos = INVALID_THREAD_HANDLE,
airport_lw_behavior = INVALID_THREAD_HANDLE,
convo_manager = INVALID_THREAD_HANDLE,
airport_attack_player = INVALID_THREAD_HANDLE,
}
-- Checkpoints --
--M20_CHECKPOINT_MISSION_START = MISSION_START_CHECKPOINT -- defined in ug_lib.lua
M20_CHECKPOINT_CRASH_THE_CAR = "ctc"
M20_CHECKPOINT_CRASH_THE_BOAT = "ctb"
M20_CHECKPOINT_CRASH_THE_HELI = "cth"
M20_CHECKPOINT_AIRPORT = "airport"
-- Cutscenes --
M20_cutscene = {
mission_intro = "20_in",
mission_outro = "20_out",
}
-- Text --
M20_text = {
get_in_angel_heli = "M20_OBJ_GET_IN_ANGEL_HELI",
go_to_gym = "M20_OBJ_GO_TO_GYM",
align_heli = "M20_OBJ_ALIGN_HELI",
align_to_boats = "M20_OBJ_ALIGN_TO_BOATS",
align_to_tanks = "M20_OBJ_ALIGN_TO_TANKS",
stay_close = "M20_OBJ_STAY_CLOSE",
rc_the_car = "M20_OBJ_RC_THE_CAR",
run_over_people = "M20_OBJ_RUN_OVER_PEOPLE",
wait_for_enter = "M20_OBJ_WAIT_FOR_ENTER",
get_up_to_speed = "M20_OBJ_GET_UP_TO_SPEED",
go_to_gas_station = "M20_OBJ_GO_TO_GAS_STATION",
crash_the_car = "M20_OBJ_CRASH_THE_CAR",
go_to_boat = "M20_OBJ_GO_TO_BOAT",
go_to_harbor = "M20_OBJ_GO_TO_HARBOR",
rc_the_boat = "M20_OBJ_RC_THE_BOAT",
rc_a_boat = "M20_OBJ_RC_A_BOAT",
crash_beach_party = "M20_OBJ_CRASH_BEACH_PARTY",
use_ramp = "M20_OBJ_USE_RAMP",
crash_the_boat = "M20_OBJ_CRASH_THE_BOAT",
go_to_helicopter = "M20_OBJ_GO_TO_HELICOPTER",
rc_the_helicopter = "M20_OBJ_RC_THE_HELICOPTER",
crash_the_heli = "M20_OBJ_CRASH_THE_HELICOPTER",
go_to_airport = "M20_OBJ_GO_TO_AIRPORT",
rc_a_tank = "M20_OBJ_RC_A_TANK",
kill_the_last_wrestler = "M20_OBJ_KILL_THE_LAST_WRESTLER",
peds_label = "M20_PEDS",
failure_angel_heli_destroyed = "m20_failure_angel_heli_destroyed",
failure_rc_too_late = "m20_failure_rc_too_late",
failure_rc_heli_destroyed = "m20_failure_rc_heli_destroyed",
failure_premature_hijackulation = "m20_failure_premature_hijackulation",
failure_no_tanks_to_you = "m20_failure_no_tanks_to_you",
failure_ctc_destroyed = "m20_failure_ctc_destroyed",
failure_ctb_destroyed = "m20_failure_ctb_destroyed",
failure_lost_signal = "m20_failure_lost_signal",
}
-- Conversations --
M20_convo = {
-- Angel, Kinzie, Player
mission_start = { convo_name = "m20_mission_start", speakers_2d = { "Kinzie" }, player_speaks = true, delay_after = 3 },
-- Angel, Player
flight_1 = { convo_name = "m20_flight_conversation_01", player_speaks = true, delay_after = 3 },
-- radio announcement played on way to ctc
conference_announcement_1 = { persona_2d_params = { "M20_Conference_Announcment_01" }, speakers_2d = { "Interrogation" } },
-- Angel, Player - when arriving at murderdome
first_luchadore = { convo_name = "m20_first_luchadore", player_speaks = true },
-- luchadore, when car is rc'd
car_controlled = { persona_2d_params = { "M20_First_Car_Controlled_Start" }, delay_after = 3, speakers_2d = { "Interrogation" } },
-- player, when "crash the peds" objective is displayed
crash_the_peds = { persona_3d_params = { LOCAL_PLAYER, "M20_Start_Running_Down_People" }, },
-- luchedore, when hitting the 4th, 10th, and 13th ped
ped_hit_1 = { persona_2d_params = { "M20_First_Car_Hitting_People_01" }, delay_after = 3, speakers_2d = { "Interrogation" } },
ped_hit_2 = { persona_2d_params = { "M20_First_Car_Hitting_People_02" }, delay_after = 3, speakers_2d = { "Interrogation" } },
ped_hit_3 = { persona_2d_params = { "M20_First_Car_Hitting_People_03" }, delay_after = 3, speakers_2d = { "Interrogation" } },
-- player, before "crash into pump" objective is displayed
hit_gas_pump = { persona_3d_params = { LOCAL_PLAYER, "M20_First_Luchadore_Crash" }, },
-- player, after car exploded
car_destroyed = { persona_3d_params = { LOCAL_PLAYER, "M20_First_One_Dead_01" }, delay_after = 3 },
-- player, angel - after car_destroyed
explain_2nd_target = { convo_name = "M20_Explain_Second_Target", player_speaks = true, delay_after = 3 },
-- Kinzie, Player - after explain_2nd_target
flight_2 = { convo_name = "m20_flight_conversation_02", speakers_2d = { "Kinzie" }, player_speaks = true, delay_after = 3 },
-- Radio - after flight_2
breaking_news_1 = { persona_2d_params = { "M20_Breaking_News_Car_Crash" }, speakers_2d = { "Anna" }, delay_after = 2 },
conference_announcement_3 = { persona_2d_params = { "M20_Conference_Announcment_03" }, speakers_2d = { "Interrogation" } },
-- boat driver - upon rc boat
boat_takeover_start = { persona_2d_params = { "M20_Second_Boat_Takeover_Start" }, speakers_2d = { "Interrogation" } },
-- boat driver - when boat hits ramp
boat_takeover_ramp = { persona_2d_params = { "M20_Second_Boat_Takeover_Ramp" }, speakers_2d = { "Interrogation" } },
-- Angel, Player not used any more?
-- second_luchadore_boat = { convo_name = "m20_second_luchadore_boat", player_speaks = true },
-- Angel, Player
second_one_dead = { convo_name = "m20_second_one_dead", player_speaks = true, delay_after = 3 },
-- breaking news about boat - after second_one dead
breaking_news_2 = { persona_2d_params = { "M20_Breaking_News_Boat_Crash" }, speakers_2d = { "Anna" } },
conference_announcement_4 = { persona_2d_params = { "M20_Conference_Announcment_04" }, speakers_2d = { "Interrogation" } },
-- Angel, Player
third_luchadore = { convo_name = "m20_third_luchadore", player_speaks = true },
-- Angel, Player
third_one_dead = { convo_name = "m20_third_one_dead", player_speaks = true, delay_after = 3 },
-- Player, Angel - after third_one_dead
flight_3 = { convo_name = "M20_Flight_Conversation_03", player_speaks = true, delay_after = 3 },
-- breaking news about heli - after third_one_dead
breaking_news_3 = { persona_2d_params = { "M20_Breaking_News_Heli_Crash" }, speakers_2d = { "Anna" }, delay_after = 2 },
conference_announcement_5 = { persona_2d_params = { "M20_Conference_Announcment_05" }, speakers_2d = { "Interrogation" } },
-- Kinzie, when rc signal < 25% signal strength
losing_signal = { persona_2d_params = { "M20_Vehicle_Almost_Too_Far" }, speakers_2d = { "Kinzie" } },
-- Kinzie, at rc signal lost
lost_signal = { persona_2d_params = { "M20_Signal_Lost" }, speakers_2d = { "Kinzie" }, delay_after = 2 },
}
M20_movers = {
gas_pumps = {
"Mover Gas Pump <002>", "Mover Gas Pump <003>",
"Mover Gas Pump <006>", "Mover Gas Pump <007>",
"Mover Gas Pump <010>", "Mover Gas Pump <011>",
"Mover Gas Pump <013>", "Mover Gas Pump <015>",
"Mover Gas Pump <017>", "Mover Gas Pump <020>",
"Mover Gas Pump <022>", "Mover Gas Pump <024>",
},
}
-- *************************
--
-- Standard functions
--
-- *************************
-- This is the primary entry point for the mission, and is responsible for starting up the mission
-- at the specified checkpoint.
-- CALLED FROM CODE
--
-- m20_checkpoint: The checkpoint the mission should begin at
-- is_restart: TRUE if the mission is restarting, FALSE otherwise
--
function m20_start(m20_checkpoint, is_restart)
-- Make sure the screen is completly faded out
mission_start_fade_out(0.0)
-- Check if this mission starting from the beginning
if (m20_checkpoint == MISSION_START_CHECKPOINT) then if is_restart == false then
cutscene_play( M20_cutscene.mission_intro, nil, { M20_navpoint.cp_starts.mission_start.player_local, M20_navpoint.cp_starts.mission_start.player_remote }, false )
end
end
-- Handle mission initialization for the current checkpoint
m20_initialize(m20_checkpoint)
-- Run the mission from the current checkpoint
m20_run(m20_checkpoint)
end
-- This is the primary function responsible for running the entire mission from start to finish.
--
-- first_checkpoint: The first checkpoint to begin running the mission at
--
function m20_run(first_checkpoint)
local current_checkpoint = first_checkpoint
local ignore_vehicles = true
local ignore_notoriety = true
if (current_checkpoint == MISSION_START_CHECKPOINT) then
m20_objective_go_to_the_gym()
current_checkpoint = M20_CHECKPOINT_CRASH_THE_CAR
mission_set_checkpoint(M20_CHECKPOINT_CRASH_THE_CAR, ignore_vehicles, ignore_notoriety)
end
if (current_checkpoint == M20_CHECKPOINT_CRASH_THE_CAR) then
m20_objective_take_control_of_the_car()
m20_objective_crash_peds()
m20_objective_crash_the_car()
current_checkpoint = M20_CHECKPOINT_CRASH_THE_BOAT
mission_set_checkpoint(M20_CHECKPOINT_CRASH_THE_BOAT, ignore_vehicles, ignore_notoriety)
end
if (current_checkpoint == M20_CHECKPOINT_CRASH_THE_BOAT) then
m20_objective_crash_the_boat()
current_checkpoint = M20_CHECKPOINT_CRASH_THE_HELI
mission_set_checkpoint(M20_CHECKPOINT_CRASH_THE_HELI, ignore_vehicles, ignore_notoriety)
end
if (current_checkpoint == M20_CHECKPOINT_CRASH_THE_HELI) then
m20_objective_crash_the_helicopter()
current_checkpoint = M20_CHECKPOINT_AIRPORT
mission_set_checkpoint(M20_CHECKPOINT_AIRPORT, ignore_vehicles, ignore_notoriety)
end
if (current_checkpoint == M20_CHECKPOINT_AIRPORT) then
m20_objective_airport()
m20_objective_tanks_to_you()
end
mission_end_success("m20", M20_cutscene.mission_outro, { M20_navpoint.success_local, M20_navpoint.success_remote } )
end
-- This is the primary function responsible for cleaning up the entire mission
-- CALLED FROM CODE (+++MUST RETURN IMMEDIATELY+++)
--
function m20_cleanup()
hud_x_of_y_remove(0)
notoriety_force_no_spawn("luchadores", false)
notoriety_force_no_spawn("deckers", false)
notoriety_force_no_spawn("morningstar", false)
notoriety_force_no_spawn("police", false)
vehicle_suppress_npc_exit(M20_vehicle.angel_heli, false)
set_player_can_enter_exit_vehicles(LOCAL_PLAYER, true)
set_player_can_enter_exit_rc_vehicles(LOCAL_PLAYER, true)
if (coop_is_active()) then
set_player_can_enter_exit_vehicles(REMOTE_PLAYER, true)
set_player_can_enter_exit_rc_vehicles(REMOTE_PLAYER, true)
end
cleanup_threads(M20_thread)
cleanup_callbacks( { M20_char, M20_vehicle } )
cleanup_groups(M20_group)
call_function_on_each_member(m20_clear_trigger, M20_trigger)
m20_convo_cleanup( M20_convo )
inv_weapon_disable_all_slots(false)
cleanup_temporary_weapons(M20_weapon.cleanup)
rc_set_max_signal_range( M20_previous_rc_range )
hud_timer_stop( 1 )
spawn_override_clear_override_for_hood( "HOOD_YEARWOOD" )
spawn_global_override_clear_category()
party_set_recruitable( true )
end
-- Called when the mission has ended with success
-- CALLED FROM CODE (+++MUST RETURN IMMEDIATLY+++)
--
function m20_success()
--[[ INSERT ANY MISSION SPECIFIC SUCCESS STUFF ]]--
end
-- *************************
--
-- Local functions
--
-- *************************
-- Initialize the mission for the specified checkpoint
--
-- checkpoint: Checkpoint to initialize the mission to
--
function m20_initialize(checkpoint)
-- Set the mission author
set_mission_author("Nick Heilmann")
-- Common initialization
m20_initialize_common()
if checkpoint ~= MISSION_START_CHECKPOINT then
-- give magic tank rc gun
inv_weapon_add_temporary(LOCAL_PLAYER, M20_weapon.rc_gun, 1, true, false, false, false, WEAPON_LEVEL4)
inv_weapon_disable_all_but_this_slot(WEAPON_SLOT_SPECIAL, true, SYNC_LOCAL)
end
-- Checkpoint specific initialization
m20_initialize_checkpoint(checkpoint)
-- Start fading in
mission_start_fade_in()
end
-- ***************************************************
--
-- m20_run Helper Functions
--
-- ***************************************************
--[[ ANGEL'S WINGS, GO TO THE GYM (MISSION START) ]]--
function m20_initialize_mission_start()
--fade_out(0.5)
M20_char.angel = "NPC Angel MS"
M20_vehicle.angel_heli = "Veh Angel Heli MS"
M20_group.angel = { name = "GRP Angel MS", chars = { M20_char.angel }, vehicles = { M20_vehicle.angel_heli } }
group_create_hidden(M20_group.angel.name, true)
on_vehicle_destroyed("m20_angel_heli_destroyed_cb", M20_vehicle.angel_heli)
player_force_vehicle_seat(LOCAL_PLAYER, 2, M20_vehicle.angel_heli)
teleport_vehicle(M20_vehicle.angel_heli, M20_navpoint.angel_heli_float.bar)
if (coop_is_active()) then
player_force_vehicle_seat(REMOTE_PLAYER, 0, M20_vehicle.angel_heli)
vehicle_enter_teleport(REMOTE_PLAYER, M20_vehicle.angel_heli, VEHICLE_SEAT_DRIVER, true)
helicopter_fly_to_stop( M20_vehicle.angel_heli, M20_navpoint.angel_heli_float.bar )
vehicle_enter_teleport(M20_char.angel, M20_vehicle.angel_heli, VEHICLE_SEAT_PASSENGER)
vehicle_enter_teleport(LOCAL_PLAYER, M20_vehicle.angel_heli, VEHICLE_SEAT_HELI_BACK_DOOR, true)
set_player_can_enter_exit_vehicles(LOCAL_PLAYER, false)
set_player_can_enter_exit_vehicles(REMOTE_PLAYER, false)
thread_yield()
else
vehicle_enter_teleport(M20_char.angel, M20_vehicle.angel_heli, VEHICLE_SEAT_DRIVER)
vehicle_enter_teleport(LOCAL_PLAYER, M20_vehicle.angel_heli, VEHICLE_SEAT_HELI_BACK_DOOR, true)
set_player_can_enter_exit_vehicles(LOCAL_PLAYER, false)
thread_yield()
end
helicopter_set_max_bank_angle( M20_vehicle.angel_heli, M20_ANGEL_MAX_BANK )
vehicle_suppress_npc_exit(M20_vehicle.angel_heli, true)
-- give magic tank rc gun
inv_weapon_add_temporary(LOCAL_PLAYER, M20_weapon.rc_gun, 1, true, false, false, false, WEAPON_LEVEL4)
inv_weapon_disable_all_but_this_slot(WEAPON_SLOT_SPECIAL, true, SYNC_LOCAL)
group_show( M20_group.angel.name )
fade_in(0.5)
end
-- Angel's heli flies to the gym
--
function m20_objective_go_to_the_gym()
objective_text_clear(0)
objective_text(0, M20_text.go_to_gym, nil, nil, SYNC_ALL, OI_ASSET_LOCATION)
-- turn on special spawning for the destination hood
spawn_override_set_override_category_for_hood( "HOOD_YEARWOOD", "sp_cat_m20Yearwood" )
spawn_global_override_set_category( "sp_cat_m20Yearwood" )
M20_status.gym_reached = false
m20_set_trigger(M20_trigger.gym, "m20_gym_reached_cb", true, true)
if coop_is_active() == false then
thread_kill(M20_thread.angel_heli_float)
M20_thread.angel_heli_float = INVALID_THREAD_HANDLE
M20_thread.fly_to_gym = thread_new("m20_wrapper_thread_forever", helicopter_fly_to_direct, M20_vehicle.angel_heli, HELI_DEFAULT_SPEED, M20_scripted_path.heli_to_gym)
end
-- mission start convos
m20_convo_play( M20_convo.mission_start )
m20_convo_play( M20_convo.flight_1 )
m20_convo_play( M20_convo.conference_announcement_1 )
-- Create the car and wrestler
group_create(M20_group.rc_car, true)
-- create mascots
for i, g in pairs( M20_group.mascots ) do
group_create( g.name )
end
-- Make sure the NPCs won't break their path by going into combat
npc_combat_enable(M20_char.rc_car[1], false)
npc_combat_enable(M20_char.rc_car[2], false)
on_vehicle_destroyed("m20_rc_car_destroyed_cb", M20_vehicle.rc_car)
local npcs_in_motion = false
while true do
if M20_status.gym_reached ~= true then
if object_is_in_trigger( M20_trigger.gym, LOCAL_PLAYER ) == true then
m20_gym_reached_cb()
end
end
-- get the wrestlers walking to thier car when the player enters the trigger
if npcs_in_motion == false and M20_status.gym_reached == true then
M20_thread.rc_car_enter[1] = thread_new("m20_walk_to_and_enter_vehicle_thread", M20_char.rc_car[1], M20_vehicle.rc_car, VEHICLE_SEAT_DRIVER)
M20_thread.rc_car_enter[2] = thread_new("m20_walk_to_and_enter_vehicle_thread", M20_char.rc_car[2], M20_vehicle.rc_car, VEHICLE_SEAT_WRESTLER_BACK_SEAT)
m20_mascot_brawl( M20_group.mascots[ 1 ], M20_group.mascots[ 2 ] )
npcs_in_motion = true
end
if coop_is_active() then
-- coop just move on when we reach the trigger area
if M20_status.gym_reached then
break
end
else
-- SP wait until heli is in position
if get_dist( M20_vehicle.angel_heli, M20_navpoint.angel_heli_float.gym ) < 10 then
marker_remove( M20_navpoint.angel_heli_float.gym )
thread_kill( M20_thread.fly_to_gym )
M20_thread.fly_to_gym = INVALID_THREAD_HANDLE
break
end
end
thread_yield()
end
m20_clear_trigger( M20_trigger.gym )
objective_text_clear(0)
end
-- make the mascots in two groups attack each other
function m20_mascot_brawl( g1, g2 )
for j, c1 in pairs( g1.chars ) do
if g2.chars[ j ] ~= nil then
while character_is_ready( c1 ) == false do
thread_yield()
end
ai_add_enemy_target( c1, g2.chars[ j ], ATTACK_NOW, true )
end
end
end
--[[ CRASH THE CAR ]]--
function m20_initialize_crash_the_car()
teleport_coop(M20_navpoint.cp_starts.crash_the_car.player_local, M20_navpoint.cp_starts.crash_the_car.player_remote, true)
M20_char.angel = "NPC Angel CTC"
M20_vehicle.angel_heli = "Veh Angel Heli CTC"
M20_group.angel = { name = "GRP Angel CTC", chars = { M20_char.angel }, vehicles = { M20_vehicle.angel_heli } }
-- Create Angel and the heli
group_create(M20_group.angel.name, true)
on_vehicle_destroyed("m20_angel_heli_destroyed_cb", M20_vehicle.angel_heli)
-- Now teleport the vehicle to the floating position
teleport_vehicle(M20_vehicle.angel_heli, M20_navpoint.angel_heli_teleport.gym)
if coop_is_active() == false then
helicopter_set_max_bank_angle( M20_vehicle.angel_heli, M20_ANGEL_MAX_BANK )
end
-- put angel in the heli
while (not character_is_in_vehicle(M20_char.angel, M20_vehicle.angel_heli)) do
if (coop_is_active()) then
vehicle_enter_teleport(M20_char.angel, M20_vehicle.angel_heli, VEHICLE_SEAT_PASSENGER)
else
vehicle_enter_teleport(M20_char.angel, M20_vehicle.angel_heli, VEHICLE_SEAT_DRIVER)
end
thread_yield()
end
vehicle_suppress_npc_exit(M20_vehicle.angel_heli, true)
-- put local player in
while (not character_is_in_vehicle(LOCAL_PLAYER, M20_vehicle.angel_heli)) do
vehicle_enter_teleport(LOCAL_PLAYER, M20_vehicle.angel_heli, VEHICLE_SEAT_HELI_BACK_DOOR)
thread_yield()
end
set_player_can_enter_exit_vehicles(LOCAL_PLAYER, false)
-- and remote player or angel's flying thread
if (coop_is_active()) then
while (not character_is_in_vehicle(REMOTE_PLAYER, M20_vehicle.angel_heli)) do
vehicle_enter_teleport(REMOTE_PLAYER, M20_vehicle.angel_heli, VEHICLE_SEAT_DRIVER)
thread_yield()
end
set_player_can_enter_exit_vehicles(REMOTE_PLAYER, false)
else
M20_thread.angel_heli_float = thread_new("m20_wrapper_thread", helicopter_fly_to_direct, M20_vehicle.angel_heli, HELI_DEFAULT_SPEED, M20_navpoint.angel_heli_float.gym)
end
-- group_show( M20_group.angel.name )
group_create(M20_group.rc_car, true)
on_vehicle_destroyed("m20_rc_car_destroyed_cb", M20_vehicle.rc_car)
for i, g in pairs( M20_group.mascots ) do
group_create( g.name )
end
m20_mascot_brawl( M20_group.mascots[ 1 ], M20_group.mascots[ 2 ] )
M20_thread.rc_car_enter[1] = thread_new("m20_walk_to_and_enter_vehicle_thread", M20_char.rc_car[1], M20_vehicle.rc_car, VEHICLE_SEAT_DRIVER)
M20_thread.rc_car_enter[2] = thread_new("m20_walk_to_and_enter_vehicle_thread", M20_char.rc_car[2], M20_vehicle.rc_car, VEHICLE_SEAT_WRESTLER_BACK_SEAT)
if (not coop_is_active()) then
thread_kill(M20_thread.angel_heli_float)
M20_thread.angel_heli_float = INVALID_THREAD_HANDLE
end
end
-- Wrestler and his driver walk to and enter the car, player takes control of it
--
function m20_objective_take_control_of_the_car()
-- Sub-objective 1: RC the car
objective_text(0, M20_text.rc_the_car, nil, nil, SYNC_LOCAL, OI_ASSET_USE)
marker_add(M20_vehicle.rc_car, MINIMAP_ICON_USE, OI_ASSET_USE, OI_FLAGS_DEFAULT, SYNC_LOCAL)
if (coop_is_active()) then
objective_text(1, M20_text.align_heli, nil, nil, SYNC_REMOTE, OI_ASSET_LOCATION)
marker_add(M20_vehicle.rc_car, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_DEFAULT, SYNC_REMOTE)
-- Give them some time to get aligned, since it will be a bit more difficult in co-op than it is for a scripted path
delay(3)
end
m20_convo_play( M20_convo.first_luchadore, false, true )
-- give the player some time to rc the car
hud_timer_set( 1, 45 * 1000, "m20_rc_car_timer_expired", SYNC_ALL )
local player_controls_car = false
local wrestlers_in_car = false
while true do
thread_yield()
if player_controls_car == false and player_is_rc_driver( LOCAL_PLAYER, M20_vehicle.rc_car ) == true then
set_player_can_enter_exit_rc_vehicles( LOCAL_PLAYER, false )
player_controls_car = true
hud_timer_stop( 1 )
-- Don't let the player move the car until the wrestler enters
player_controls_disable(LOCAL_PLAYER)
-- remove marker for both players
marker_remove(M20_vehicle.rc_car, SYNC_ALL)
if coop_is_active() then
-- change remote message to "stay close..."
objective_text_clear( 1 )
m20_coop_follow_obj_start( M20_vehicle.rc_car )
end
m20_kinzie_watch_signal_start( M20_vehicle.rc_car )
if wrestlers_in_car == false then
-- change local message to say "wait for wrestler to enter car"
objective_text(0, M20_text.wait_for_enter, nil, nil, SYNC_LOCAL, OI_ASSET_USE)
end
end
if wrestlers_in_car == false then
if thread_check_done( M20_thread.rc_car_enter[ 1 ] ) and thread_check_done( M20_thread.rc_car_enter[ 2 ] ) then
wrestlers_in_car = true
vehicle_suppress_npc_exit(M20_vehicle.rc_car, true)
character_set_cannot_exit_rc_vehicle( M20_char.rc_car[ 1 ], true )
character_set_cannot_exit_rc_vehicle( M20_char.rc_car[ 2 ], true )
end
end
-- if the player is in control of the vehicle and the wrestlers are in the car then continue
if player_controls_car and wrestlers_in_car then
break
end
end
m20_convo_play( M20_convo.car_controlled )
hud_timer_stop( 1 )
-- Now that the wrestler is in the car, let the player move again
player_controls_enable(LOCAL_PLAYER)
end
-- Player gets the vehicle up to speed, then crashes it
--
function m20_objective_crash_the_car()
m20_convo_play( M20_convo.hit_gas_pump, true, true )
objective_text(0, M20_text.go_to_gas_station, nil, nil, SYNC_LOCAL, OI_ASSET_LOCATION)
marker_add(M20_navpoint.gas_station, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_FULL, SYNC_LOCAL)
mission_waypoint_add(M20_navpoint.gas_station)
M20_status.rc_car_destroyed = false
M20_status.rc_car_prev_hp = get_current_hit_points( M20_vehicle.rc_car )
on_take_damage( "m20_on_take_damage_rc_car", M20_vehicle.rc_car )
if coop_is_active() == false then
M20_thread.follow_rc_vehicle = thread_new("m20_wrapper_thread_forever", helicopter_fly_to_direct_follow, M20_vehicle.angel_heli, 50, M20_vehicle.rc_car, nil, 150, true)
end
local close_to_gas_station = false
while vehicle_is_destroyed( M20_vehicle.rc_car ) == false do
if player_is_rc_driver( LOCAL_PLAYER, M20_vehicle.rc_car ) == false then
m20_convo_play( M20_convo.lost_signal, true, true )
mission_end_failure( "m20", M20_text.failure_lost_signal )
return
end
-- change objective when they are near the gas station
if close_to_gas_station == false and get_dist( M20_vehicle.rc_car, M20_navpoint.gas_station ) < 50 then
objective_text(0, M20_text.crash_the_car, nil, nil, SYNC_LOCAL, OI_ASSET_LOCATION)
close_to_gas_station = true
end
thread_yield()
end
m20_kinzie_watch_signal_stop()
if coop_is_active() == false then
-- Stop following the vehicle (the thread should already have been killed, but just to be safe...)
thread_kill(M20_thread.follow_rc_vehicle)
M20_thread.follow_rc_vehicle = INVALID_THREAD_HANDLE
end
on_take_damage( "", M20_vehicle.rc_car )
set_player_can_enter_exit_rc_vehicles(LOCAL_PLAYER, true)
-- Remove whatever message may still be displayed from the debug conversations being played
message_remove_all()
-- delay a few seconds for camera to pan out from explosion
delay( 1 )
m20_convo_play( M20_convo.car_destroyed, false, true )
delay( 3 )
m20_convo_play( M20_convo.explain_2nd_target )
m20_convo_play( M20_convo.breaking_news_1 )
-- m20_convo_play( M20_convo.conference_announcement_3 )
cleanup_groups(M20_group.rc_car)
if (not coop_is_active()) then
M20_thread.fly_to_boat = thread_new("m20_wrapper_thread", helicopter_fly_to_direct, M20_vehicle.angel_heli, 50, M20_scripted_path.heli_to_boat)
end
m20_coop_follow_obj_stop()
marker_remove( M20_navpoint.gas_station )
mission_waypoint_remove()
marker_remove( M20_vehicle.rc_car )
objective_text_clear(0)
group_create(M20_group.beach_party.name, false)
group_create(M20_group.rc_boat.name, true)
for i,npc in pairs(M20_char.rc_boat) do
vehicle_enter_teleport(npc, M20_vehicle.rc_boat[i])
end
end
-- Player crashes the vehicle into some peds
--
function m20_objective_crash_peds()
objective_text(0, M20_text.run_over_people, nil, nil, SYNC_LOCAL, OI_ASSET_KILL)
m20_convo_play( M20_convo.crash_the_peds )
M20_status.rc_car_peds_hit = 0
M20_peds_hit = { }
local line_played = 0
on_hit_ped("m20_rc_car_hit_ped_cb", M20_vehicle.rc_car)
hud_x_of_y_add( 0, M20_text.peds_label, 0, PEDS_TO_HIT, false, SYNC_LOCAL )
if coop_is_active() == false then
-- follow the player
M20_thread.follow_rc_vehicle = thread_new("m20_wrapper_thread_forever", helicopter_fly_to_direct_follow, M20_vehicle.angel_heli, 50, M20_vehicle.rc_car, nil, 150, true)
end
repeat
thread_yield()
hud_x_of_y_update(0, M20_status.rc_car_peds_hit)
-- play a line when thresholds are hit
if line_played < 1 and M20_status.rc_car_peds_hit > 3 then
m20_convo_play( M20_convo.ped_hit_1, false, true )
elseif line_played < 2 and M20_status.rc_car_peds_hit > 9 then
m20_convo_play( M20_convo.ped_hit_2, false, true )
elseif line_played < 3 and M20_status.rc_car_peds_hit > 12 then
m20_convo_play( M20_convo.ped_hit_3, false, true )
end
-- update line played
-- do it seperate so we don't get two in same frame at least
if M20_status.rc_car_peds_hit > 12 then
line_played = 3
elseif M20_status.rc_car_peds_hit > 9 then
line_played = 2
elseif M20_status.rc_car_peds_hit > 3 then
line_played = 1
end
if player_is_rc_driver( LOCAL_PLAYER, M20_vehicle.rc_car ) == false then
m20_convo_play( M20_convo.lost_signal, true, true )
mission_end_failure( "m20", M20_text.failure_lost_signal )
return
end
until M20_status.rc_car_peds_hit >= PEDS_TO_HIT
if coop_is_active() == false then
-- Stop following the vehicle
thread_kill(M20_thread.follow_rc_vehicle)
M20_thread.follow_rc_vehicle = INVALID_THREAD_HANDLE
end
on_hit_ped("", M20_vehicle.rc_car)
hud_x_of_y_remove(0)
-- Remove whatever message may still be displayed from the debug conversations being played
message_remove_all()
objective_text_clear(0)
end
--[[ CRASH THE BOAT ]]--
function m20_initialize_crash_the_boat()
teleport_coop(M20_navpoint.cp_starts.crash_the_boat.player_local, M20_navpoint.cp_starts.crash_the_boat.player_remote, true)
M20_char.angel = "NPC Angel CTB"
M20_vehicle.angel_heli = "Veh Angel Heli CTB"
M20_group.angel = { name = "GRP Angel CTB", chars = { M20_char.angel }, vehicles = { M20_vehicle.angel_heli } }
-- Create Angel and the heli
group_create_hidden(M20_group.angel.name, true)
on_vehicle_destroyed("m20_angel_heli_destroyed_cb", M20_vehicle.angel_heli)
if coop_is_active() == false then
helicopter_set_max_bank_angle( M20_vehicle.angel_heli, M20_ANGEL_MAX_BANK )
end
-- Put them in the vehicle before teleporting anything
while (not character_is_in_vehicle(M20_char.angel, M20_vehicle.angel_heli)) do
if (coop_is_active()) then
vehicle_enter_teleport(M20_char.angel, M20_vehicle.angel_heli, VEHICLE_SEAT_PASSENGER)
else
vehicle_enter_teleport(M20_char.angel, M20_vehicle.angel_heli, VEHICLE_SEAT_DRIVER)
end
thread_yield()
end
vehicle_suppress_npc_exit(M20_vehicle.angel_heli, true)
while (not character_is_in_vehicle(LOCAL_PLAYER, M20_vehicle.angel_heli)) do
vehicle_enter_teleport(LOCAL_PLAYER, M20_vehicle.angel_heli, VEHICLE_SEAT_HELI_BACK_DOOR)
thread_yield()
end
set_player_can_enter_exit_vehicles(LOCAL_PLAYER, false)
if (coop_is_active()) then
while (not character_is_in_vehicle(REMOTE_PLAYER, M20_vehicle.angel_heli)) do
vehicle_enter_teleport(REMOTE_PLAYER, M20_vehicle.angel_heli, VEHICLE_SEAT_DRIVER)
thread_yield()
end
set_player_can_enter_exit_vehicles(REMOTE_PLAYER, false)
else
-- Now teleport the vehicle to the floating position
teleport_vehicle(M20_vehicle.angel_heli, M20_navpoint.angel_heli_teleport.boat)
M20_thread.angel_heli_float = thread_new("m20_wrapper_thread", helicopter_fly_to_direct, M20_vehicle.angel_heli, HELI_DEFAULT_SPEED, M20_navpoint.angel_heli_float.boat)
end
group_show( M20_group.angel.name )
if (not coop_is_active()) then
thread_kill(M20_thread.angel_heli_float)
M20_thread.angel_heli_float = INVALID_THREAD_HANDLE
else
vehicle_stop( M20_vehicle.angel_heli, true )
end
group_create(M20_group.rc_boat.name, true)
group_create(M20_group.beach_party.name, false)
for i,npc in pairs(M20_char.rc_boat) do
vehicle_enter_teleport(npc, M20_vehicle.rc_boat[i])
end
end
function m20_objective_crash_the_boat()
-- Sub-objective 1: Go to boat
objective_text(0, M20_text.go_to_harbor, nil, nil, SYNC_ALL, OI_ASSET_LOCATION)
m20_convo_play( M20_convo.flight_2 )
if (coop_is_active()) then
M20_status.boat_reached = false
m20_set_trigger(M20_trigger.boat, "m20_boat_reached_cb", true, true)
repeat
thread_yield()
until M20_status.boat_reached
m20_clear_trigger(M20_trigger.boat)
else
mission_waypoint_add( M20_navpoint.angel_heli_float.boat )
marker_add(M20_navpoint.angel_heli_float.boat, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_DEFAULT)
repeat
thread_yield()
until (get_dist(M20_vehicle.angel_heli, M20_navpoint.angel_heli_float.boat) < 60)
mission_waypoint_remove()
marker_remove(M20_navpoint.angel_heli_float.boat)
end
-- Sub-objective 2: RC the boat
objective_text_clear(0)
objective_text(0, M20_text.rc_a_boat, nil, nil, SYNC_LOCAL, OI_ASSET_USE)
if (coop_is_active()) then
objective_text(1, M20_text.align_to_boats, nil, nil, SYNC_REMOTE, OI_ASSET_LOCATION)
for i,boat in pairs(M20_vehicle.rc_boat) do
marker_add(boat, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_DEFAULT, SYNC_REMOTE)
end
end
for i,boat in pairs(M20_vehicle.rc_boat) do
marker_add(boat, MINIMAP_ICON_USE, OI_ASSET_USE, OI_FLAGS_DEFAULT, SYNC_LOCAL)
end
M20_status.player_has_rc_vehicle = false
repeat
thread_yield()
for i,boat in pairs(M20_vehicle.rc_boat) do
if (player_is_rc_driver(LOCAL_PLAYER, boat)) then
set_player_can_enter_exit_rc_vehicles(LOCAL_PLAYER, false)
on_vehicle_destroyed("m20_rc_boat_destroyed_cb", boat)
M20_status.my_rc_boat = boat
M20_status.player_has_rc_vehicle = true
end
end
until (M20_status.player_has_rc_vehicle)
objective_text_clear(0)
for i,boat in pairs(M20_vehicle.rc_boat) do
marker_remove(boat)
end
if (coop_is_active()) then
objective_text_clear( 1 )
m20_coop_follow_obj_start( M20_status.my_rc_boat )
end
m20_kinzie_watch_signal_start( M20_status.my_rc_boat )
m20_convo_play( M20_convo.boat_takeover_start, false, true )
marker_add(M20_char.beach_wrestler, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_DEFAULT, SYNC_LOCAL)
-- Sub-objective 3: Crash the beach party
objective_text(0, M20_text.crash_beach_party, nil, nil, SYNC_LOCAL, OI_ASSET_LOCATION)
M20_status.rc_boat_destroyed = false
M20_status.beach_party_crashed = false
M20_thread.beach_party_polling = thread_new("m20_beach_party_polling_thread")
M20_thread.boat_validation = thread_new("m20_boat_validation_thread")
if (coop_is_active()) then
repeat
if player_is_rc_driver( LOCAL_PLAYER, M20_status.my_rc_boat ) == false then
m20_convo_play( M20_convo.lost_signal, true, true )
mission_end_failure( "m20", M20_text.failure_lost_signal )
return
end
thread_yield()
until M20_status.beach_party_crashed
else
repeat
-- Have the helicopter follow the target vehicle from here on out
M20_thread.follow_rc_vehicle = thread_new("m20_wrapper_thread", helicopter_fly_to_direct_follow, M20_vehicle.angel_heli, 50, M20_status.my_rc_boat, nil, 150, true)
thread_yield()
thread_kill(M20_thread.follow_rc_vehicle)
if player_is_rc_driver( LOCAL_PLAYER, M20_status.my_rc_boat ) == false then
m20_convo_play( M20_convo.lost_signal, true, true )
mission_end_failure( "m20", M20_text.failure_lost_signal )
return
end
until (M20_status.beach_party_crashed)
-- Stop following the vehicle (the thread should already have been killed, but just to be safe...)
thread_kill(M20_thread.follow_rc_vehicle)
M20_thread.follow_rc_vehicle = INVALID_THREAD_HANDLE
end
m20_coop_follow_obj_stop()
m20_kinzie_watch_signal_stop()
m20_convo_play( M20_convo.boat_takeover_ramp, false, true )
m20_convo_play( M20_convo.second_one_dead )
m20_convo_play( M20_convo.breaking_news_2 )
-- m20_convo_play( M20_convo.conference_announcement_4 )
if (vehicle_exists(M20_status.my_rc_boat) and not vehicle_is_destroyed(M20_status.my_rc_boat)) then
vehicle_detonate(M20_status.my_rc_boat)
end
for i,vehicle in pairs(M20_vehicle.beach_party) do
if (vehicle_exists(vehicle) and not vehicle_is_destroyed(vehicle)) then
vehicle_detonate(vehicle)
end
end
-- kill the target
character_kill( M20_char.beach_wrestler )
marker_remove(M20_char.beach_wrestler)
-- delay to show the boat exploding
delay(4)
-- Remove whatever message may still be displayed from the debug conversations being played
message_remove_all()
set_player_can_enter_exit_rc_vehicles(LOCAL_PLAYER, true)
cleanup_groups(M20_group.rc_boat)
objective_text_clear(0)
end
--[[ CRASH THE HELICOPTER ]]--
function m20_initialize_crash_the_helicopter()
teleport_coop(M20_navpoint.cp_starts.crash_the_heli.player_local, M20_navpoint.cp_starts.crash_the_heli.player_remote, true)
M20_char.angel = "NPC Angel CTH"
M20_vehicle.angel_heli = "Veh Angel Heli CTH"
M20_group.angel = { name = "GRP Angel CTH", chars = { M20_char.angel }, vehicles = { M20_vehicle.angel_heli } }
-- Create Angel and the heli
group_create(M20_group.angel.name, true)
on_vehicle_destroyed("m20_angel_heli_destroyed_cb", M20_vehicle.angel_heli)
if coop_is_active() == false then
helicopter_set_max_bank_angle( M20_vehicle.angel_heli, M20_ANGEL_MAX_BANK )
end
-- Put them in the vehicle before teleporting anything
while (not character_is_in_vehicle(M20_char.angel, M20_vehicle.angel_heli)) do
if (coop_is_active()) then
vehicle_enter_teleport(M20_char.angel, M20_vehicle.angel_heli, VEHICLE_SEAT_PASSENGER)
else
vehicle_enter_teleport(M20_char.angel, M20_vehicle.angel_heli, VEHICLE_SEAT_DRIVER)
end
thread_yield()
end
vehicle_suppress_npc_exit(M20_vehicle.angel_heli, true)
while (not character_is_in_vehicle(LOCAL_PLAYER, M20_vehicle.angel_heli)) do
vehicle_enter_teleport(LOCAL_PLAYER, M20_vehicle.angel_heli, VEHICLE_SEAT_HELI_BACK_DOOR)
thread_yield()
end
set_player_can_enter_exit_vehicles(LOCAL_PLAYER, false)
if (coop_is_active()) then
while (not character_is_in_vehicle(REMOTE_PLAYER, M20_vehicle.angel_heli)) do
vehicle_enter_teleport(REMOTE_PLAYER, M20_vehicle.angel_heli, VEHICLE_SEAT_DRIVER)
thread_yield()
end
set_player_can_enter_exit_vehicles(REMOTE_PLAYER, false)
else
-- Now teleport the vehicle to the floating position
teleport_vehicle(M20_vehicle.angel_heli, M20_navpoint.angel_heli_teleport.heli)
M20_thread.angel_heli_float = thread_new("m20_wrapper_thread", helicopter_fly_to_direct, M20_vehicle.angel_heli, HELI_DEFAULT_SPEED, M20_navpoint.angel_heli_float.heli)
end
if (not coop_is_active()) then
thread_kill(M20_thread.angel_heli_float)
M20_thread.angel_heli_float = INVALID_THREAD_HANDLE
end
end
function m20_objective_crash_the_helicopter()
-- Sub-objective 1: Go to helicopter
objective_text( 0, M20_text.go_to_helicopter, nil, nil, SYNC_ALL, OI_ASSET_LOCATION )
M20_status.circular_path_reached = false
m20_set_trigger( M20_trigger.circular_path, "m20_circular_path_reached_cb", true, true )
if not coop_is_active() then
M20_thread.heli_to_heli = thread_new( "m20_heli_to_heli_thread", HELI_DEFAULT_SPEED )
end
repeat
thread_yield()
until M20_status.circular_path_reached
if not coop_is_active() then
thread_kill( M20_thread.heli_to_heli )
M20_thread.heli_to_heli = thread_new( "m20_heli_to_heli_thread", 15 )
end
-- create and manage random behavior of target civ heli
M20_thread.heli_rand_flying = thread_new( "m20_heli_rand_flying_thread", M20_group.rc_heli.name, M20_vehicle.rc_heli, M20_char.rc_heli, M20_navpoint.rc_heli_teleport )
repeat
thread_yield()
until group_is_loaded( M20_group.rc_heli.name )
on_vehicle_destroyed( "m20_rc_heli_destroyed_cb", M20_vehicle.rc_heli )
on_collision( "m20_angel_heli_collided_cb", M20_vehicle.angel_heli )
-- Sub-objective 2: RC the helicopter
objective_text_clear( 0 )
objective_text( 0, M20_text.rc_the_helicopter, nil, nil, SYNC_LOCAL, OI_ASSET_USE )
if coop_is_active() then
objective_text( 1, M20_text.align_heli, nil, nil, SYNC_REMOTE, OI_ASSET_LOCATION )
end
repeat
thread_yield()
until group_is_loaded( M20_group.rc_heli.name )
M20_status.player_has_rc_vehicle = false
repeat
thread_yield()
if player_is_rc_driver( LOCAL_PLAYER, M20_vehicle.rc_heli ) then
set_player_can_enter_exit_rc_vehicles( LOCAL_PLAYER, false )
M20_status.player_has_rc_vehicle = true
end
until M20_status.player_has_rc_vehicle
-- Stop the vehicle so the player can actually control it
vehicle_stop( M20_vehicle.rc_heli, false )
thread_kill( M20_thread.heli_rand_flying )
M20_thread.heli_rand_flying = INVALID_THREAD_HANDLE
vehicle_max_speed( M20_vehicle.rc_heli, HELI_HIGH_SPEED )
-- Sub-objective 3: Crash the helicopter
objective_text( 0, M20_text.crash_the_heli, nil, nil, SYNC_LOCAL, OI_ASSET_KILL )
if coop_is_active() then
objective_text_clear( 1 )
m20_coop_follow_obj_start( M20_vehicle.rc_heli )
end
m20_kinzie_watch_signal_start( M20_vehicle.rc_heli )
M20_thread.heli_rand_flying = thread_new( "m20_cth_target_behavior" )
repeat
thread_yield()
until group_is_loaded( M20_group.wrestler.name )
on_vehicle_destroyed( "m20_wrestler_heli_destroyed_cb", M20_vehicle.wrestler )
-- Only show the indicator on the helicopter you want to crash into
marker_remove( M20_vehicle.rc_heli, SYNC_LOCAL )
if coop_is_active() == false then
-- Have the helicopter follow the target vehicle from here on out
vehicle_max_speed( M20_vehicle.angel_heli, HELI_HIGH_SPEED )
thread_kill( M20_thread.heli_to_heli )
M20_thread.follow_rc_vehicle = thread_new( "m20_wrapper_thread_forever", helicopter_fly_to_direct_follow, M20_vehicle.angel_heli, HELI_HIGH_SPEED, M20_vehicle.rc_heli, nil, 150, true )
end
-- wait for heli to be destroyed
while vehicle_exists( M20_vehicle.wrestler ) and vehicle_is_destroyed( M20_vehicle.wrestler ) == false do
-- blow up the helis when they get close enough
if get_dist( M20_vehicle.rc_heli, M20_vehicle.wrestler ) < M20_CTH_CRASH_DIST then
vehicle_detonate( M20_vehicle.rc_heli )
vehicle_detonate( M20_vehicle.wrestler )
elseif player_is_rc_driver( LOCAL_PLAYER, M20_vehicle.rc_heli ) == false then
m20_convo_play( M20_convo.lost_signal, true, true )
mission_end_failure( "m20", M20_text.failure_lost_signal )
return
end
thread_yield()
end
m20_kinzie_watch_signal_stop()
if coop_is_active() then
m20_coop_follow_obj_stop()
else
-- Stop the follow thread
thread_kill( M20_thread.follow_rc_vehicle )
M20_thread.follow_rc_vehicle = INVALID_THREAD_HANDLE
end
-- delay a few seconds for camera to pan out from explosion
delay( 4 )
on_collision( "", M20_vehicle.angel_heli )
thread_kill( M20_thread.heli_rand_flying )
M20_thread.heli_rand_flying = INVALID_THREAD_HANDLE
m20_convo_play( M20_convo.third_one_dead )
m20_convo_play( M20_convo.breaking_news_3 )
-- m20_convo_play( M20_convo.conference_announcement_5 )
-- Remove whatever message may still be displayed from the debug conversations being played
message_remove_all()
set_player_can_enter_exit_rc_vehicles( LOCAL_PLAYER, true )
cleanup_groups( { M20_group.wrestler, M20_group.rc_heli } )
objective_text_clear(0)
end
-- controls the behavior of the target heli
-- in crash the helicoptor objective
function m20_cth_target_behavior()
local path_iteration = 1
-- bunch of crap needed to do inline pf'ing
local direct = true
local follow = ""
local continue_at_goal = false
local follow_dist = 0.0
local directly_above = false
local loop_path = false
-- create and set up target heli
group_create( M20_group.wrestler.name, true )
vehicle_enter_teleport( M20_char.wrestler, M20_vehicle.wrestler, VEHICLE_SEAT_DRIVER )
vehicle_enter_teleport( M20_char.pilot, M20_vehicle.wrestler, VEHICLE_SEAT_PASSENGER )
marker_add( M20_vehicle.wrestler, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL, SYNC_LOCAL )
teleport_vehicle( M20_vehicle.wrestler, M20_navpoint.wrestler_teleport )
helicopter_fly_to_do( M20_vehicle.wrestler, HELI_DEFAULT_SPEED, direct, follow, continue_at_goal, get_random_table_entry( M20_navpoint.wrestler_heli_rand ), follow_dist, directly_above, loop_path )
while vehicle_exists( M20_vehicle.wrestler ) and not vehicle_is_destroyed( M20_vehicle.wrestler ) do
-- see if target should start fleeing
if get_dist( M20_vehicle.rc_heli, M20_vehicle.wrestler ) < M20_CTH_FLEE_DIST then
break
end
-- otherwise see if we should move to a new rand point
if vehicle_pathfind_check_done( M20_vehicle.wrestler ) ~= 0 then
delay( 5 )
helicopter_fly_to_do( M20_vehicle.wrestler, HELI_DEFAULT_SPEED, direct, follow, continue_at_goal, get_random_table_entry( M20_navpoint.wrestler_heli_rand ), follow_dist, directly_above, loop_path )
end
thread_yield()
end
thread_new( "vehicle_exit_dive", M20_char.pilot )
delay( 1 )
if vehicle_exists( M20_vehicle.wrestler ) and not vehicle_is_destroyed( M20_vehicle.wrestler ) then
m20_convo_play( M20_convo.third_luchadore )
end
local target_path_index = 1
local reverse = false
local paths = M20_scripted_path.cth_target_flee_paths
local speed
while vehicle_exists( M20_vehicle.wrestler ) and not vehicle_is_destroyed( M20_vehicle.wrestler ) do
if paths[ target_path_index ].super_slow == true then
speed = 10
else
speed = 25
end
helicopter_fly_to( M20_vehicle.wrestler, speed, paths[ target_path_index ].sp_name, reverse )
if reverse then
target_path_index = get_random_table_entry( paths[ target_path_index ].p )
else
target_path_index = get_random_table_entry( paths[ target_path_index ].n )
end
if target_path_index < 0 then
reverse = true
target_path_index = target_path_index * -1
else
reverse = false
end
end
m20_convo_cleanup( M20_convo )
end
--[[ LAST MAN STANDING, TANKS TO YOU ]]--
function m20_initialize_airport()
teleport_coop(M20_navpoint.cp_starts.airport.player_local, M20_navpoint.cp_starts.airport.player_remote, true)
M20_char.angel = "NPC Angel LW"
M20_vehicle.angel_heli = "Veh Angel Heli LW"
M20_group.angel = { name = "GRP Angel LW", chars = { M20_char.angel }, vehicles = { M20_vehicle.angel_heli } }
-- Create Angel and the heli
group_create(M20_group.angel.name, true)
on_vehicle_destroyed("m20_angel_heli_destroyed_cb", M20_vehicle.angel_heli)
if coop_is_active() == false then
helicopter_set_max_bank_angle( M20_vehicle.angel_heli, M20_ANGEL_MAX_BANK )
end
-- Put them in the vehicle before teleporting anything
while (not character_is_in_vehicle(M20_char.angel, M20_vehicle.angel_heli)) do
if (coop_is_active()) then
vehicle_enter_teleport(M20_char.angel, M20_vehicle.angel_heli, VEHICLE_SEAT_PASSENGER)
else
vehicle_enter_teleport(M20_char.angel, M20_vehicle.angel_heli, VEHICLE_SEAT_DRIVER)
end
thread_yield()
end
vehicle_suppress_npc_exit(M20_vehicle.angel_heli, true)
while (not character_is_in_vehicle(LOCAL_PLAYER, M20_vehicle.angel_heli)) do
vehicle_enter_teleport(LOCAL_PLAYER, M20_vehicle.angel_heli, VEHICLE_SEAT_HELI_BACK_DOOR)
thread_yield()
end
set_player_can_enter_exit_vehicles(LOCAL_PLAYER, false)
if (coop_is_active()) then
while (not character_is_in_vehicle(REMOTE_PLAYER, M20_vehicle.angel_heli)) do
vehicle_enter_teleport(REMOTE_PLAYER, M20_vehicle.angel_heli, VEHICLE_SEAT_DRIVER)
thread_yield()
end
set_player_can_enter_exit_vehicles(REMOTE_PLAYER, false)
else
-- Now teleport the vehicle to the floating position
teleport_vehicle(M20_vehicle.angel_heli, M20_navpoint.angel_heli_teleport.airport)
M20_thread.angel_heli_float = thread_new("m20_wrapper_thread", helicopter_fly_to_direct, M20_vehicle.angel_heli, HELI_DEFAULT_SPEED, M20_navpoint.angel_heli_float.airport)
end
if (not coop_is_active()) then
thread_kill(M20_thread.angel_heli_float)
M20_thread.angel_heli_float = INVALID_THREAD_HANDLE
end
end
function m20_objective_airport()
objective_text(0, M20_text.go_to_airport, nil, nil, SYNC_ALL, OI_ASSET_LOCATION)
M20_status.tank_path_reached = false
m20_set_trigger(M20_trigger.tank_path, "m20_tank_path_reached_cb", true, true)
if (not coop_is_active()) then
M20_thread.heli_to_airport = thread_new("m20_heli_to_airport_thread", HELI_DEFAULT_SPEED)
end
repeat
thread_yield()
until (M20_status.tank_path_reached)
M20_thread.convo_fourth_luchadore = thread_new("m20_wrapper_thread", audio_play_persona_line, LOCAL_PLAYER, "M20_Fourth_Luchadore")
if (not coop_is_active()) then
M20_thread.heli_to_airport = thread_new("m20_heli_around_airport_thread", 15)
end
M20_status.last_wrestler_killed = false
group_create(M20_group.stag_tank.name, true)
group_create(M20_group.airport.name, true)
for i,tank in pairs( M20_vehicle.stag_tank ) do
-- no weapons for the player
on_vehicle_destroyed("m20_stag_tank_destroyed_cb", tank)
end
objective_text_clear(0)
end
function m20_objective_tanks_to_you()
M20_status.rc_tank_destroyed = false
local rc_tank = nil
-- spawn the last wrestler
group_create( M20_group.last_wrestler, true )
on_death( "m20_last_wrestler_killed_cb", M20_char.last_wrestler )
set_dont_attack_me_on_sight_flag( M20_char.last_wrestler, true )
M20_thread.airport_lw_behavior = thread_new( "m20_airport_lw_behavior" )
repeat
M20_status.stag_tanks_remaining = 0
for i,tank in pairs( M20_vehicle.stag_tank ) do
if vehicle_is_destroyed( tank) == false then
marker_add( tank, MINIMAP_ICON_USE, OI_ASSET_USE, OI_FLAGS_FULL, SYNC_LOCAL )
M20_status.stag_tanks_remaining = M20_status.stag_tanks_remaining + 1
if coop_is_active() then
marker_add( tank, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_FULL, SYNC_REMOTE )
end
end
end
-- If there are no tanks left, fail the mission
if (M20_status.stag_tanks_remaining == 0) then
mission_end_failure("m20", M20_text.failure_no_tanks_to_you)
return
end
-- Sub-objective 1: RC a STAG tank
objective_text(0, M20_text.rc_a_tank, nil, nil, SYNC_LOCAL, OI_ASSET_USE)
if (coop_is_active()) then
objective_text(1, M20_text.align_to_tanks, nil, nil, SYNC_REMOTE, OI_ASSET_LOCATION)
end
if (M20_status.rc_tank_destroyed) then
M20_status.rc_tank_destroyed = false
if (not coop_is_active()) then
M20_thread.heli_to_airport = thread_new("m20_heli_around_airport_thread", 15)
end
end
-- wait for player to rc a tank
M20_status.player_has_rc_vehicle = false
repeat
thread_yield()
for i,stag_tank in pairs(M20_vehicle.stag_tank) do
if (vehicle_exists(stag_tank) and not vehicle_is_destroyed(stag_tank)) then
if (player_is_rc_driver(LOCAL_PLAYER, stag_tank)) then
rc_tank = stag_tank
set_player_can_enter_exit_rc_vehicles(LOCAL_PLAYER, false)
M20_status.player_has_rc_vehicle = true
break
end
end
end
until M20_status.player_has_rc_vehicle
-- create a driver for the tank so the soldiers will attack it
group_create( M20_group.airport_tank_driver.name, true )
vehicle_enter_teleport( M20_char.stag_tank_driver, rc_tank, VEHICLE_SEAT_DRIVER )
vehicle_suppress_npc_exit( rc_tank, true )
set_team( M20_char.stag_tank_driver, "Playas" )
-- npcs attack player in a bit
if M20_thread.airport_attack_player ~= INVALID_THREAD_HANDLE then
thread_kill( M20_thread.airport_attack_player )
end
ai_add_enemy_target( M20_char.last_wrestler, M20_char.stag_tank_driver, ATTACK_NOW, true )
M20_thread.airport_attack_player = thread_new( "m20_airport_attack_player_in_n_seconds", rc_tank, 3 )
-- give the rc tank a bump in hp
-- set_max_hit_points( rc_tank, get_max_hit_points( rc_tank ) * 4 , true)
on_vehicle_destroyed( "m20_rc_tank_destroyed_cb", rc_tank )
on_vehicle_enter_water( "m20_rc_tank_destroyed_cb", rc_tank )
marker_remove( M20_vehicle.stag_tank )
-- Sub-objective 2: Kill the last wrestler
objective_text( 0, M20_text.kill_the_last_wrestler, nil, nil, SYNC_LOCAL, OI_ASSET_KILL )
-- mark target for local player
marker_add( M20_vehicle.lw_truck, MINIMAP_ICON_KILL, OI_ASSET_KILL_FULL, OI_FLAGS_FULL, SYNC_LOCAL)
m20_kinzie_watch_signal_start( rc_tank )
if (coop_is_active()) then
objective_text_clear( 1 )
m20_coop_follow_obj_start( rc_tank )
else
-- Have the helicopter follow the target vehicle from here on out
M20_thread.follow_rc_vehicle = thread_new("m20_wrapper_thread", helicopter_fly_to_direct_follow, M20_vehicle.angel_heli, 50, rc_tank, nil, 50, true)
end
-- wait until rc tank is destroyed or the wrestler is dead
repeat
thread_yield()
until M20_status.rc_tank_destroyed or M20_status.last_wrestler_killed
inv_item_equip(M20_weapon.rc_gun, LOCAL_PLAYER)
m20_kinzie_watch_signal_stop()
if coop_is_active() then
m20_coop_follow_obj_stop()
else
-- Stop following the vehicle (the thread should already have been killed, but just to be safe...)
thread_kill(M20_thread.follow_rc_vehicle)
M20_thread.follow_rc_vehicle = INVALID_THREAD_HANDLE
end
marker_remove( M20_vehicle.lw_truck, SYNC_LOCAL )
objective_text_clear(0)
until (M20_status.last_wrestler_killed)
audio_play_persona_line(LOCAL_PLAYER, "M20_Fourth_One_Dead")
end
function m20_airport_attack_player_in_n_seconds( rc_tank, seconds )
-- wait a bit before having tank drivers to attack player
delay( seconds )
-- make other tanks attack rc'd tank
local tank_driver = vehicle_get_driver( rc_tank, false )
for i,npc in pairs( M20_char.stag_tank ) do
if character_is_dead( npc ) == false then
ai_add_enemy_target( npc, tank_driver, ATTACK_NOW, true )
end
end
M20_thread.airport_attack_player = INVALID_THREAD_HANDLE
end
function m20_airport_lw_behavior()
local target_path_index = 1
local paths = M20_scripted_path.airport_wrestler_flee_paths
-- turn off his ai as he seems to like getting distracted
set_ignore_ai_flag( M20_char.last_wrestler, true )
turn_invulnerable( M20_char.last_wrestler )
-- run to truck
ai_do_scripted_move( M20_char.last_wrestler, M20_vehicle.lw_truck , true, false)
repeat
if character_is_dead( M20_char.last_wrestler ) then
return
end
thread_yield()
until get_dist( M20_char.last_wrestler, M20_vehicle.lw_truck ) < 4 or character_is_dead( M20_char.last_wrestler )
-- get in truck
ai_clear_scripted_action( M20_char.last_wrestler )
vehicle_enter_teleport( M20_char.last_wrestler, M20_vehicle.lw_truck, 0 )
vehicle_suppress_npc_exit( M20_vehicle.lw_truck )
vehicle_disable_chase( M20_vehicle.lw_truck )
vehicle_disable_flee( M20_vehicle.lw_truck )
on_vehicle_destroyed( "m20_last_wrestler_killed_cb", M20_vehicle.lw_truck )
vehicle_set_keyframed_physics( M20_vehicle.lw_truck, false )
set_ignore_ai_flag( M20_char.last_wrestler, false )
-- make truck killable
set_max_hit_points( M20_vehicle.lw_truck, get_max_hit_points( M20_vehicle.lw_truck ) * 4, true )
vehicle_set_invulnerable( M20_vehicle.lw_truck, false )
local reverse = false
local target_path_index = 1
local paths = M20_scripted_path.airport_wrestler_flee_paths
-- ongoing cyclicle fleeing
while true do
vehicle_pathfind_to( M20_vehicle.lw_truck, paths[ target_path_index ].sp_name, true, false, false, true )
-- bail if we are done
if character_is_dead( M20_char.last_wrestler ) or vehicle_is_destroyed( M20_vehicle.lw_truck ) then
break
end
if reverse then
target_path_index = get_random_table_entry( paths[ target_path_index ].p )
else
target_path_index = get_random_table_entry( paths[ target_path_index ].n )
end
if target_path_index < 0 then
reverse = true
target_path_index = target_path_index * -1
else
reverse = false
end
thread_yield()
end
end
-- ***************************************************
--
-- m20_initialize Helper Functions
--
-- ***************************************************
-- Handle any common initialization
--
function m20_initialize_common()
-- Set it to midday
--set_time_of_day(12, 00)
notoriety_force_no_spawn("luchadores", true)
notoriety_force_no_spawn("deckers", true)
notoriety_force_no_spawn("morningstar", true)
notoriety_force_no_spawn("police", true)
M20_previous_rc_range = rc_set_max_signal_range( M20_RC_RANGE )
party_dismiss_all()
party_set_recruitable( false )
mission_set_cancel_warp_location( M20_navpoint.end_local, M20_navpoint.end_remote )
end
-- Checkpoint specific initialization
--
-- checkpoint: The checkpoint to be initialized
function m20_initialize_checkpoint(checkpoint)
if (checkpoint == MISSION_START_CHECKPOINT) then
m20_initialize_mission_start()
elseif (checkpoint == M20_CHECKPOINT_CRASH_THE_CAR) then
m20_initialize_crash_the_car()
elseif (checkpoint == M20_CHECKPOINT_CRASH_THE_BOAT) then
m20_initialize_crash_the_boat()
elseif (checkpoint == M20_CHECKPOINT_CRASH_THE_HELI) then
m20_initialize_crash_the_helicopter()
elseif (checkpoint == M20_CHECKPOINT_AIRPORT) then
m20_initialize_airport()
end
end
-- ***************************************************
--
-- Miscellaneous m20 Helper Funcrtions
--
-- ***************************************************
-- Set a trigger enabled with a mission marker
--
-- trigger: (string) Name of the trigger
-- trigger_callback: (string) Function name to call when trigger is activated
-- add_waypoint: (bool, optional) true to add a waypoint, false otherwise (defaults to true)
-- add_marker: (bool, optional) true to add a marker, false otherwise (defaults to true)
--
function m20_set_trigger(trigger, trigger_callback, add_waypoint, add_marker)
trigger_enable(trigger, true)
if (add_waypoint ~= false) then
mission_waypoint_add(trigger)
end
if (add_marker ~= false) then
marker_add_trigger(trigger, MINIMAP_ICON_LOCATION, INGAME_EFFECT_CHECKPOINT, OI_ASSET_LOCATION, OI_FLAGS_LOCATION, SYNC_ALL)
end
on_trigger(trigger_callback, trigger)
end
-- Disable trigger
--
-- trigger: (string) Name of the trigger
--
function m20_clear_trigger(trigger)
on_trigger("", trigger)
trigger_enable(trigger, false)
marker_remove_trigger(trigger, SYNC_ALL)
mission_waypoint_remove()
end
-- Play an audio conversation
--
-- convo: (table) the conversation to play - contains a name, handle, and table of non-player speakers
-- wait: (bool) don't return until convo has played
-- clear: (bool) clear any pending convos
--
function m20_convo_play( convo, wait, clear )
if (convo == nil) then
return
end
if clear == true then
m20_convo_cleanup( M20_convo )
end
-- add to end of queue
M20_convo_queue[ #M20_convo_queue + 1 ] = convo
-- start a manager thread if needed
if M20_thread.convo_manager == INVALID_THREAD_HANDLE then
M20_thread.convo_manager = thread_new( "m20_convo_manager" )
end
-- wait for convo to finish playing if requested
if wait == true then
local found = true
while found == true do
thread_yield()
found = false
-- see if convo is still playing
for i, c in pairs( M20_convo_queue ) do
if c == convo then
found = true
break
end
end -- for
end -- while
end -- if
end -- function
function m20_convo_manager()
local convo
while #M20_convo_queue > 0 do
convo = M20_convo_queue[ 1 ]
convo.persona_handles = { }
-- Load 2D personas when necessary
if convo.speakers_2d ~= nil then
for i, persona in pairs( convo.speakers_2d ) do
convo.persona_handles[ i ] = audio_persona_load_2d( persona )
-- if we needed to load a persona, delay some to allow soundbank to load. Could be heavy streaming going on
delay(.5)
end
end
-- Load the conversation
if convo.persona_3d_params ~= nil then
audio_play_persona_line( unpack( convo.persona_3d_params ) )
debug_print( "MAD", "playing 3D persona line '".. convo.persona_3d_params[ 2 ] .. "'\n" )
while audio_persona_line_playing( convo.persona_3d_params[ 1 ] ) == true do
thread_yield()
end
elseif convo.persona_2d_params ~= nil then
-- a speakers_2d must have been specified
if convo.persona_handles[ 1 ] ~= nil then
convo.audio_id = audio_play_persona_line_2d( convo.persona_handles[ 1 ], convo.persona_2d_params[ 1 ] )
debug_print( "MAD", "playing 2D persona line '".. convo.persona_2d_params[ 1 ] .. "'\n" )
-- see note below
if convo.persona_2d_params[ 2 ] ~= nil then
delay( convo.persona_2d_params[ 2 ] )
end
-- audio_is_playing() doesn't currently work with this id
-- I am told it should so I'll leave it here but the delay above
-- is what's going to make this work right now -SDR
while audio_is_playing( convo.audio_id ) == true do
thread_yield()
end
convo.audio_id = nil
end
elseif convo.audio_event_params ~= nil then
convo.audio_id = audio_object_post_event( unpack( convo.audio_event_params ) )
while audio_is_playing( convo.audio_id ) == true do
thread_yield()
end
convo.audio_id = nil
elseif convo.convo_name ~= nil then
-- load convo
if convo.player_speaks then
convo.convo_handle = audio_conversation_load( convo.convo_name )
else
convo.convo_handle = audio_conversation_load_direct( convo.convo_name )
end
-- play the conversation
debug_print( "MAD", "Playing convo: " .. convo.convo_name .. "\n" )
audio_conversation_play( convo.convo_handle )
thread_yield()
-- wait for the conversation to end
audio_conversation_wait_for_end( convo.convo_handle )
convo.convo_handle = nil
end
-- clean up personas
for i, handle in pairs( convo.persona_handles ) do
audio_persona_remove_2d( handle )
end
convo.persona_handles = nil
-- delay if needed
if convo.delay_after ~= nil then
delay( convo.delay_after )
end
-- roll up the queue
if #M20_convo_queue > 1 then
for i = 2, #M20_convo_queue do
M20_convo_queue[ i - 1 ] = M20_convo_queue[ i ]
end
end
M20_convo_queue[ #M20_convo_queue ] = nil
end
-- if there's no convos to play just exit the thread
M20_thread.convo_manager = INVALID_THREAD_HANDLE
end
-- *************************
--
-- Callback functions
--
-- *************************
-- Callback for the RC car hitting a ped
--
-- vehicle: (string) name of the vehicle that hit a ped
--
function m20_rc_car_hit_ped_cb(vehicle, human)
if M20_status.rc_car_peds_hit > PEDS_TO_HIT or M20_peds_hit[ human ] == true then
return
end
M20_status.rc_car_peds_hit = M20_status.rc_car_peds_hit + 1
M20_peds_hit[ human ] = true
end
-- Callback for the RC car being destroyed
--
-- vehicle: (string) name of the vehicle that was destroyed
--
function m20_rc_car_destroyed_cb(vehicle)
-- Can't blow this thing up before the people have been killed
if (not (M20_status.rc_car_peds_hit >= PEDS_TO_HIT)) then
mission_end_failure("m20", M20_text.failure_ctc_destroyed)
return
end
-- when the vehicle gets destroyed, the audio listening position moves away, and you
-- cannot hear the explosion. Post a 2D event for an explosion
audio_object_post_event("M20_RC_Vehicle_Explode")
on_vehicle_destroyed("", vehicle)
set_player_can_enter_exit_rc_vehicles(LOCAL_PLAYER, true)
if (coop_is_active()) then
set_player_can_enter_exit_rc_vehicles(REMOTE_PLAYER, true)
end
marker_remove(vehicle)
M20_status.rc_car_destroyed = true
end
-- Callback for the RC boat being destroyed
--
-- vehicle: (string) name of the vehicle that was destroyed
--
function m20_rc_boat_destroyed_cb(vehicle)
-- when the boat gets destroyed, the audio listening position moves away, and you
-- cannot hear the explosion. Post a 2D event for an explosion
audio_object_post_event("M20_RC_Vehicle_Explode")
on_vehicle_destroyed("", vehicle)
audio_play( "M20_Explo" )
set_player_can_enter_exit_rc_vehicles(LOCAL_PLAYER, true)
if (coop_is_active()) then
set_player_can_enter_exit_rc_vehicles(REMOTE_PLAYER, true)
end
if (not M20_status.beach_party_crashed) then
mission_end_failure("m20", M20_text.failure_ctb_destroyed)
end
--marker_remove(vehicle)
M20_status.rc_boat_destroyed = true
end
-- Callback for one of the RC tanks being destroyed
--
-- vehicle: (string) name of the vehicle that was destroyed
--
function m20_rc_tank_destroyed_cb(vehicle)
on_vehicle_destroyed("", vehicle)
audio_play( "M20_Explo" )
-- this also gets called if the tank enters water
if vehicle_is_destroyed( vehicle ) == false then
vehicle_detonate( vehicle )
end
set_player_can_enter_exit_rc_vehicles(LOCAL_PLAYER, true)
if coop_is_active() then
set_player_can_enter_exit_rc_vehicles(REMOTE_PLAYER, true)
end
marker_remove(vehicle)
M20_status.rc_tank_destroyed = true
-- destory the driver - we'll resurrect him if another tank gets rc'd
group_destroy( M20_group.airport_tank_driver.name )
end
-- Callback for reaching the gym trigger (co-op only)
--
function m20_gym_reached_cb()
M20_status.gym_reached = true
end
-- Callback for reaching the boat/harbor trigger (co-op only)
--
function m20_boat_reached_cb()
M20_status.boat_reached = true
end
-- Callback for Angel's heli reaching the path around the wrestler's heli
--
function m20_circular_path_reached_cb()
m20_clear_trigger(M20_trigger.circular_path)
M20_status.circular_path_reached = true
end
-- Callback for Angel's heli being destroyed
--
-- heli: (string) name of Angel's heli
--
function m20_angel_heli_destroyed_cb(heli)
-- NOTE: When Angel's heli is destroyed, there is no arbitrary delay
-- because this is a failure condition that trumps all other scenarios
on_vehicle_destroyed("", heli)
mission_end_failure("m20", M20_text.failure_angel_heli_destroyed)
end
-- Callback for the RC heli being destroyed
--
-- vehicle: (string) name of the RC heli
--
function m20_rc_heli_destroyed_cb(vehicle)
on_vehicle_destroyed("", vehicle)
marker_remove(vehicle)
set_player_can_enter_exit_rc_vehicles(LOCAL_PLAYER, true)
if (coop_is_active()) then
set_player_can_enter_exit_rc_vehicles(REMOTE_PLAYER, true)
end
-- Arbitrary delay to make sure Angel's heli destroyed callback occurs first if they collided with each other
delay(.5)
--if (not M20_status.wrestler_heli_destroyed) then
if (vehicle_exists(M20_vehicle.wrestler) and not vehicle_is_destroyed(M20_vehicle.wrestler)) then
mission_end_failure("m20", M20_text.failure_rc_heli_destroyed)
end
end
-- Callback for the wrestler's heli being destroyed
--
-- vehicle: (string) name of the wrestler's heli
--
function m20_wrestler_heli_destroyed_cb(vehicle)
on_vehicle_destroyed("", vehicle)
audio_play( "M20_Explo" )
marker_remove(vehicle)
set_player_can_enter_exit_rc_vehicles(LOCAL_PLAYER, true)
if (coop_is_active()) then
set_player_can_enter_exit_rc_vehicles(REMOTE_PLAYER, true)
end
-- Arbitrary delay to make sure Angel's heli destroyed callback occurs first if they collided with each other
delay(.5)
-- If the wrestler's heli was blown up by something over than the RC heli,
-- detonate the RC heli to make sure the player isn't stuck in RC mode
if (vehicle_exists(M20_vehicle.rc_heli) and not vehicle_is_destroyed(M20_vehicle.rc_heli)) then
vehicle_detonate(M20_vehicle.rc_heli)
end
M20_status.wrestler_heli_destroyed = true
end
-- Callback for when Angel's heli collides with something (used for the RC heli section)
--
-- angel_heli: (string) name of Angel's heli
-- other_obj: (string) name of the mover/vehicle that was collided with, or nil if the collision was with the world
-- speed_of_impact: (float) speed of the impact (not important for our purposes here)
--
function m20_angel_heli_collided_cb(angel_heli, other_obj, speed_of_impact)
-- If Angel's heli hits the RC heli or the wrestler's heli, blow it up and fail the mission
if (other_obj == M20_vehicle.rc_heli or other_obj == M20_vehicle.wrestler) then
on_collision("", angel_heli)
vehicle_detonate(angel_heli)
mission_end_failure("m20", M20_text.failure_angel_heli_destroyed)
end
end
-- Callback for Angel's heli reaching the path around the STAG tanks
--
function m20_tank_path_reached_cb()
m20_clear_trigger(M20_trigger.tank_path)
M20_status.tank_path_reached = true
end
-- Callback for the last wrestler being killed
--
function m20_last_wrestler_killed_cb()
on_death("", M20_char.last_wrestler)
M20_status.last_wrestler_killed = true
end
-- Callback for one of the STAG tanks at the airport being destroyed
--
-- tank: (string) the tank that was destroyed
--
function m20_stag_tank_destroyed_cb(tank)
on_vehicle_destroyed("", tank)
marker_remove(tank)
end
-- Callback for one of the targets in the RC car section being killed
--
-- npc: (string) the target that was killed
--
function m20_target_death_cb(npc)
marker_remove(npc)
on_death("", npc)
end
-- *************************
--
-- Thread functions
--
-- *************************
-- Causes the NPC to walk toward the vehicle, and when close, enter the vehicle in the selected seat
-- NOTE: For now, NPCs can't be in the driver seat while the player has RC'd the vehicle, so we'll be putting them in passenger seats
--
-- npc: (string) name of the NPC we are sending to the vehicle
-- vehicle: (string) name of the vehicle
-- seat: (number) seat index we want the person to sit in once they reach the vehicle
-- distance: (number) distance from the vehicle at which we will teleport them in (right now NPCs won't get into a vehicle the player has RC control over, so we have to teleport them)
--
function m20_walk_to_and_enter_vehicle_thread(npc, vehicle, seat, distance)
if (distance == nil) then
distance = 4
end
-- Have them walk toward, and not fire at, the vehicle
ai_do_scripted_move(npc, vehicle, false, false)
-- Wait until they get close enough to the vehicle
repeat
thread_yield()
until (get_dist(npc, vehicle) < distance)
-- Teleport them into the seat
vehicle_enter(npc, vehicle, seat)
end
-- Sits and waits for the beach party to be crashed
--
function m20_beach_party_polling_thread()
repeat
thread_yield()
until object_is_in_trigger(M20_trigger.beach_party, M20_status.my_rc_boat)
M20_status.beach_party_crashed = true
end
-- Does some validation on the boat's status, making sure it hasn't capsized or gotten stuck on land
--
function m20_boat_validation_thread()
repeat
thread_yield()
-- Make sure we haven't capsized
if (vehicle_is_flipped(M20_status.my_rc_boat)) then
if (M20_thread.boat_flipped_watchdog == INVALID_THREAD_HANDLE) then
-- If this is the first time the boat is recognized as being flipped over, start the watchdog thread (which is basically just a fail timer)
M20_thread.boat_flipped_watchdog = thread_new("m20_boat_flipped_watchdog_thread")
end
elseif (M20_thread.boat_flipped_watchdog ~= INVALID_THREAD_HANDLE) then
-- If the watchdog timer is active, but the boat is no longer upside down (perhaps you were just doing a barrel roll?), stop the watchdog timer
thread_kill(M20_thread.boat_flipped_watchdog)
M20_thread.boat_flipped_watchdog = INVALID_THREAD_HANDLE
end
-- Make sure we're not stuck on land
if (not vehicle_in_water(M20_status.my_rc_boat)) then
if (M20_thread.boat_on_land_watchdog == INVALID_THREAD_HANDLE) then
M20_thread.boat_on_land_watchdog = thread_new("m20_boat_on_land_watchdog_thread")
end
elseif (M20_thread.boat_on_land_watchdog ~= INVALID_THREAD_HANDLE) then
thread_kill(M20_thread.boat_on_land_watchdog)
M20_thread.boat_on_land_watchdog = INVALID_THREAD_HANDLE
end
until M20_status.beach_party_crashed
thread_kill(M20_thread.boat_flipped_watchdog)
M20_thread.boat_flipped_watchdog = INVALID_THREAD_HANDLE
thread_kill(M20_thread.boat_on_land_watchdog)
M20_thread.boat_on_land_watchdog = INVALID_THREAD_HANDLE
end
-- Starts a timer when the boat flips. If this thread isn't killed before time is up, the mission will fail.
--
function m20_boat_flipped_watchdog_thread()
delay(3)
mission_end_failure("m20", M20_text.failure_ctb_destroyed)
end
-- Starts a timer when the boat is on land. If this thread isn't killed before time is up, the mission will fail.
--
function m20_boat_on_land_watchdog_thread()
delay(3)
mission_end_failure("m20", M20_text.failure_ctb_destroyed)
end
-- Have a heli fly back and forth randomly between a set of navpoints in the air
--
-- group_name: (string) name of the group to spawn
-- heli: (string) name of the heli that's flying around
-- pilot: (string) name of the pilot
-- teleport_nav: (string) name of the navpoint to teleport to
--
function m20_heli_rand_flying_thread(group_name, heli, pilot, teleport_nav)
group_create(group_name, true)
vehicle_enter_teleport(pilot, heli, VEHICLE_SEAT_DRIVER)
if (heli == M20_vehicle.rc_heli) then
if (coop_is_active()) then
marker_add(heli, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_FULL, SYNC_REMOTE)
end
marker_add(heli, MINIMAP_ICON_USE, OI_ASSET_USE, OI_FLAGS_FULL, SYNC_LOCAL)
else
marker_add(heli, MINIMAP_ICON_KILL, OI_ASSET_KILL, OI_FLAGS_FULL, SYNC_LOCAL)
end
teleport_vehicle(heli, teleport_nav)
helicopter_fly_to_direct(heli, HELI_DEFAULT_SPEED, teleport_nav)
while (vehicle_exists(heli) and not vehicle_is_destroyed(heli)) do
thread_yield()
helicopter_fly_to_direct(heli, 15, get_random_table_entry(M20_navpoint.tourist_heli_rand))
thread_yield()
delay(5)
end
end
-- Angel's heli flying circles around the area the wrestler's heli is in
--
-- speed: (number) speed at which the heli should fly
--
function m20_heli_to_heli_thread(speed)
while (1) do
thread_yield()
helicopter_fly_to_direct_dont_stop(M20_vehicle.angel_heli, speed, M20_scripted_path.heli_to_heli)
end
end
-- Angel's heli flying circles around the area the STAG tanks are in
--
-- speed: (number) speed at which the heli should fly
--
function m20_heli_to_airport_thread(speed)
helicopter_fly_to_dont_stop(M20_vehicle.angel_heli, speed, M20_scripted_path.heli_to_airport)
m20_heli_around_airport_thread( speed )
end
function m20_heli_around_airport_thread(speed)
while (1) do
thread_yield()
helicopter_fly_to_direct_dont_stop(M20_vehicle.angel_heli, speed, M20_scripted_path.heli_around_airport)
end
end
function m20_wrapper_thread(function_ref, ...)
function_ref(unpack(arg))
end
function m20_wrapper_thread_forever(function_ref, ...)
while true do
function_ref(unpack(arg))
thread_yield()
end
end
function m20_rc_car_timer_expired()
mission_end_failure("m20", M20_text.failure_rc_too_late)
end
function m20_coop_follow_obj_start( target_vehicle )
if coop_is_active() == false then
return
end
-- turn on bar
hud_bar_on( 1, "default", M20_text.stay_close, 1, SYNC_REMOTE )
marker_add( target_vehicle, MINIMAP_ICON_LOCATION, OI_ASSET_LOCATION, OI_FLAGS_FULL, SYNC_REMOTE )
M20_status.coop_follow_target_vehicle = target_vehicle
-- start thread
M20_thread.coop_follow_obj_thread_id = thread_new( "m20_coop_follow_obj_thread", target_vehicle )
end
function m20_coop_follow_obj_stop()
if coop_is_active() == false then
return
end
-- kill thread
thread_kill( M20_thread.coop_follow_obj_thread_id )
M20_thread.coop_follow_obj_thread_id = nil
-- turn off bar
hud_bar_off( 1, SYNC_REMOTE )
marker_remove( M20_status.coop_follow_target_vehicle )
end
function m20_coop_follow_obj_thread( target_vehicle )
local current_value = -1
local v
while true do
v = vehicle_rc_get_signal_strength( target_vehicle, LOCAL_PLAYER )
if v ~= current_value then
-- update bar
current_value = v
hud_bar_set_value( 1, v, SYNC_REMOTE )
end
thread_yield()
end
end
function m20_convo_cleanup()
-- kill manager thread
if M20_thread.convo_manager ~= INVALID_THREAD_HANDLE then
thread_kill( M20_thread.convo_manager )
M20_thread.convo_manager = INVALID_THREAD_HANDLE
end
-- sweep all convo data and clean it up
for i, convo in pairs( M20_convo_queue ) do
m20_convo_cleanup_item( convo )
end
-- clear pending events
M20_convo_queue = { }
end
function m20_convo_cleanup_item( convo )
if convo.convo_handle ~= nil then
audio_conversation_end( convo.convo_handle )
convo.convo_handle = nil
end
if convo.audio_id ~= nil then
audio_stop( convo.audio_id )
convo.audio_id = nil
end
-- clean up loaded personas
if convo.persona_handles ~= nil then
for i, handle in pairs( convo.persona_handles ) do
audio_persona_remove_2d( handle )
end
convo.persona_handles = nil
end
end
function m20_kinzie_watch_signal_start( target_vehicle )
m20_kinzie_watch_signal_stop()
M20_thread.kinzie_watch_signal = thread_new( "m20_kinzie_watch_signal_thread", target_vehicle )
end
function m20_kinzie_watch_signal_stop()
if M20_thread.kinzie_watch_signal ~= nil then
thread_kill( M20_thread.kinzie_watch_signal )
M20_thread.kinzie_watch_signal = nil
end
end
function m20_kinzie_watch_signal_thread( target_vehicle )
while true do
-- signal dips below 25% then have Kinzie say something
while vehicle_rc_get_signal_strength( target_vehicle, LOCAL_PLAYER ) > 0.25 do
thread_yield()
end
m20_convo_play( M20_convo.losing_signal, false, true )
-- don't say anything for 3 seconds
delay( 3 )
-- wait until signal is > 30% before repeating
while vehicle_rc_get_signal_strength( target_vehicle, LOCAL_PLAYER ) < 0.3 do
thread_yield()
end
end
end
function m20_on_take_damage_rc_car( name, attacker, hp )
-- looking for a hit > threshold
local current_hp = get_max_hit_points( name ) * hp
if M20_status.rc_car_prev_hp - current_hp < 150 then
M20_status.rc_car_prev_hp = current_hp
return
end
-- see if in trigger
local in_trigger = false
for i, trigger in pairs( M20_trigger.gas_station ) do
if object_is_in_trigger( trigger, name ) == true then
in_trigger = true
break
end
end
if in_trigger == true then
on_take_damage( "", name )
audio_play( "M20_Explo" )
vehicle_detonate( name )
end
end