--[[ USING THE MISSION START TEMPLATE
1. Read "SR3 Mission Scripting Standards" if you haven't already.
2. Save this file as "mSatan.lua" in the missions directory.
3. Replace "mSatan" with the name of your mission (must use the same name as your mission start node).
3a. Replace "mSatan" with the capitalized name of your mission
4. Replace "20130821" with today's date.
5. Replace "hvs" with your name.
6. Replace "first_checkpoint_nav" with the name of the first location to go to
7. Replace "fcp with a 3-4 letter abbreviation for the first checkpoint.
8. Replace "next_checkpoint_nav" with the second checkpoint name (first is named start)
9. Replace "ncp" with a 3-4 letter abbreviation for the next checkpoint.
10. If you find an error with this template, fix it and check it in!!!!
11. Remove these instructions. You're on your own now!
]]--
--[[
mSatan.lua
SR3 Mission Script
DATE: 2013-09-23
AUTHOR: Arturo Mata
]]--
-- Debug flags --
-- Tweakable Parameters --
--------------------------------------------------------------------------------------------------
--[[ GROUPS ]]--
--------------------------------------------------------------------------------------------------
mSatan_group = {
--[[ FLIGHT TEST GROUP ]]--
satan = {
name = "Satan_group",
members = { "satan<001>" },
},
kinzie = {
name = "Kinzie_group",
members = { "kinzie<001>" },
},
johnny = {
name = "Johnny_group",
members = { "johnny<001>" },
},
}
--------------------------------------------------------------------------------------------------
--[[ THREADS ]]--
--------------------------------------------------------------------------------------------------
mSatan_thread = {
mSatan_set_velocity = INVALID_THREAD_HANDLE,
}
--------------------------------------------------------------------------------------------------
--[[ CHECKPOINTS ]]--
--------------------------------------------------------------------------------------------------
mSatan_checkpoint = {
{
name = MISSION_START_CHECKPOINT, -- Throne Room Checkpoint (thr)
init = "mSatan_thr_init",
run = "mSatan_thr_run",
cleanup = "mSatan_thr_cleanup",
next_checkpoint = "",
host_start = "Throne_Nav_Host",
client_start = "Throne_Nav_Client",
p1_car_nav = "",
p2_car_nav = "",
start_groups = { },
cp_only_groups = { },
},
}
--------------------------------------------------------------------------------------------------
--[[ CUTSCENES ]]--
--------------------------------------------------------------------------------------------------
mSatan_scene = {
intro = "Bink_Wedding_Party",
face_punch = "Satan_Punch_out",
outro = "outro"
}
--------------------------------------------------------------------------------------------------
--[[ CONVERSATIONS ]]--
--------------------------------------------------------------------------------------------------
mSatan_convo = {
--[[ = {
name = "file_name without voice (_bm, _wm, _bf...",
player_talks = true or false,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60, -- if the conversation doesn't complete before this time, kill it
timer_thread = INVALID_THREAD_HANDLE,
priority = CONVO_PRIORITY_HIGH or CONVO_PRIORITY_NORMAL or CONVO_PRIORITY_OPTIONAL
(optional) persona_line = true, -- this is a single line
(required if persona_line) speaker_name = "name of speaker", -- single line speaker (might be set before call to play is made?)
(optional)phone_call = true, -- this is a phone conversation (phone persona must be preloaded)
(required if phone_call) receiving_call = true or false -- auto-answer is always true in missions (until proven otherwise)
},]]
--[[
face_punch = {
name = "mdrained_elevator",
player_talks = false,
handle = INVALID_CONVERSATION_HANDLE,
convo_thread = INVALID_THREAD_HANDLE,
max_wait_seconds = 60,
timer_thread = INVALID_THREAD_HANDLE,
priority = CONVO_PRIORITY_NORMAL,
},
]]--
}
mSatan_convo_queue = {
--[[start_drive_queue = {
{ delay = 2.0, convo = mSatan_convo.goto_first_checkpoint_nav },
{ delay = 4.0, convo = mSatan_convo.goto_first_checkpoint_nav2 },
{ delay = 3.0, convo = mSatan_convo.goto_first_checkpoint_nav3 },
{ delay = 5.0, convo = mSatan_convo.goto_first_checkpoint_nav4 }
},
]]--
}
--------------------------------------------------------------------------------------------------
--[[ TRIGGERS ]]--
--------------------------------------------------------------------------------------------------
mSatan_trigger = {
-- = {
-- name = "_trigger",
-- hit = false,
-- last_hit_by = nil, -- last_hit_human = nil (set to the last human to enter the trigger in the default trigger callback)
-- (optional)callback = "mSatan_function_name_cb"
-- (optional)marker = TRIGGER_LOCATION or TRIGGER_USE or custom or don't include for no marker
-- (optional)waypoint = true,
-- (optional)teleport_to = {
-- host = "host_nav",
-- client = "client_nav"
-- },
-- (optional)conversation = mSatan_convo.convo_name -- play a conversation
-- (optional)next_trigger = "next_trigger_name" sets up next trigger when triggered (breadcrumbs)
--},
--[[ first_checkpoint_nav TRIGGERS ]]--
--end_trigger = {
-- name = "end_mission_trigger",
-- hit = false,
-- marker = TRIGGER_LOCATION,
-- waypoint = false,
--},
--[[ next_checkpoint_nav TRIGGERS ]]--
--trigger_01 = {
-- name = "trigger<001>",
-- hit = false,
-- marker = TRIGGER_LOCATION,
-- waypoint = true,
--},
}
--------------------------------------------------------------------------------------------------
--[[ INTERROGATION DATA ]]--
--------------------------------------------------------------------------------------------------
--mSatan_interrogate = {
-- leader = {
-- target = mSatan_group.friendly_fire.owner,
-- persona = "Interrogation",
-- objective = "mSatan_INTERROGATE_OWNER",
-- -- (optional)conversation = mSatan_convo.convo_name -- play a conversation while interrogating
-- },
--}
--------------------------------------------------------------------------------------------------
--[[ OTHER ]]--
--------------------------------------------------------------------------------------------------
--HVS_JBG : The FIRST navpoint in this list should be directly in front of the throne!
mSatan_navpoints = {
teleport_nav = { "satan_tele_nav<001>","satan_tele_nav<002>","satan_tele_nav<003>","satan_tele_nav<004>",
"satan_tele_nav<005>","satan_tele_nav<006>","satan_tele_nav<007>","satan_tele_nav<008>",
"satan_tele_nav<009>","satan_tele_nav<010>","satan_tele_nav<011>","satan_tele_nav<012>",
"satan_tele_nav<013>"},
}
mSatan_runtime = {
satan_downed = false,
face_punch_complete = false,
mission_end_complete = false,
kinzie_swap_complete = false,
satan_wings_ready = false,
}
mSatan_homie = {
kinzie = "",
johnny = "",
}
--------------------------------------------------------------------------------------------------
--[[**********************]]--
--[[ ]]--
--[[ 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
--
-- start_checkpoint_name: (string) The checkpoint the mission should begin at
-- is_restart: (bool) TRUE if the mission is restarting, FALSE otherwise
--
function mSatan_start(start_checkpoint_name, is_restart)
mission_start_fade_out(0.0)
set_ped_override_density(.1)
set_traffic_density(.1)
parking_spot_disable_all(true)
-- initialize systems
mission_startup(mSatan_trigger, mSatan_convo) -- mSatan_checkpoint
local start_cp = get_table_by_name(mSatan_checkpoint, MISSION_START_CHECKPOINT)
--hvUnlockLoadout("mSatan")
-- Check if this mission starting from the beginning
if (start_checkpoint_name == start_cp.name) then
if (is_restart == false and mSatan_scene.intro ~= "") then
-- First time playing mission
local fade_in_after = false
cutscene_play(mSatan_scene.intro, nil, {start_cp.host_start, start_cp.client_start}, fade_in_after)
else
teleport_coop(start_cp.host_start, start_cp.client_start, true)
end
fade_out(0)
end
-- Handle mission initialization for the current checkpoint
mSatan_initialize(start_checkpoint_name)
-- Run the mission from the current checkpoint
checkpoint_run_mission(mSatan_checkpoint, start_checkpoint_name)
if(mSatan_runtime.mission_end_complete == false) then
mission_end_success("mSatan", mSatan_scene.outro, {"cancel_end_host", "cancel_end_client"})
end
--mission_end_success("mSatan", mSatan_scene.outro)--, {, })
end
-- This is the primary function responsible for cleaning up the entire mission
-- CALLED FROM CODE (+++MUST RETURN IMMEDIATELY+++)
--
function mSatan_cleanup()
camera_revert_target() -- HVS_RCK - Just in case you quit while the camera was on Satan
satan_maybe_restore_control() --HVS_RCK - same just in case as above: Restore player control
--[[ INSERT ANY MISSION SPECIFIC CLEAN-UP ]]--
satan_clear_resources()
on_seamless_animated_moment_end("")
--make sure zone is off
city_zone_swap("m_Sthrone", false)
-- cleanup all threads
cleanup_threads(mSatan_thread)
-- run checkpoint cleanups (move into mission_shutdown?)
checkpoint_cleanup_mission(mSatan_checkpoint)
-- cleanup triggers, convos, kill_list and interrogations
mission_shutdown()
-- cleanup all groups
cleanup_groups(mSatan_group)
--return normal player jump/sprint values
tweak_table_restore_value ("Jump_super_max_height_scripted")
tweak_table_restore_value ("Sprint_super_max_speed_scripted")
set_ped_override_density(-1)
set_traffic_density(1)
parking_spot_disable_all(false)
end
-- Called when the mission has ended with success
-- CALLED FROM CODE (+++MUST RETURN IMMEDIATELY+++)
--
function mSatan_success()
--[[ INSERT ANY MISSION SPECIFIC SUCCESS STUFF ]]--
end
--------------------------------------------------------------------------------------------------
--[[**********************]]--
--[[ ]]--
--[[ Initialize functions ]]--
--[[ ]]--
--[[**********************]]--
-- Initialize the mission for the specified checkpoint
--
-- checkpoint_name: (string) Checkpoint to initialize the mission to
--
function mSatan_initialize(checkpoint_name)
-- Common initialization
mSatan_initialize_common()
-- Checkpoint specific initialization
checkpoint_init(mSatan_checkpoint, checkpoint_name)
-- Remove any present subtitles
message_remove_all()
-- Start fading in
mission_start_fade_in()
audio_object_post_event("Play_AMB_INT_Throne_Room_1")
end
-- Handle any common initialization
--
function mSatan_initialize_common()
--[[ INSERT ANY COMMON INITIALIZATION CODE HERE ]]--
mission_set_cancel_warp_location("cancel_end_host", "cancel_end_client")
audio_object_post_event("Play_SatanMusic")
audio_object_post_event("Play_AMB_INT_Throne_Room_1")
end
--------------------------------------------------------------------------------------------------
--[[**********************]]--
--[[ ]]--
--[[ Checkpoint functions ]]--
--[[ ]]--
--[[**********************]]--
------------------------------------
--
-- Checkpoint helper functions
--
------------------------------------
------------------------------------
--
-- Checkpoint callback functions
--
------------------------------------
------------------------------------
--
-- Checkpoint thread functions
--
------------------------------------
--------------------------------------------------------------------------------------------------
--[[ Throne Room Checkpoint ]]--
--------------------------------------------------------------------------------------------------
-- Initialize this checkpoint.
--
-- mission_start: (bool) Whether we're initializing from a mission (re)start or from
-- a natural play-through.
--
function mSatan_thr_init(mission_start)
--set up single player only homie Kinzie
if (coop_is_active() == false) then
local block = true
-- if player is johnny, spawn kinzie as a homie, else spawn johnny as the homie
if character_get_anim_set(LOCAL_PLAYER) == "PLYM" then
group_create( mSatan_group.kinzie.name, block )
mSatan_homie.kinzie = mSatan_group.kinzie.members[1]
party_add(mSatan_homie.kinzie, LOCAL_PLAYER)
follower_set_can_abandon( mSatan_homie.kinzie, false )
on_death ( "mSatan_failure_kinzie_died_cb", mSatan_homie.kinzie )
on_dismiss ( "mSatan_failure_kinzie_dismissed_cb", mSatan_homie.kinzie )
turn_invulnerable( mSatan_group.kinzie.members[1] )
character_set_never_catch_fire(mSatan_group.kinzie.members[1])
else
group_create( mSatan_group.johnny.name, block )
mSatan_homie.johnny = mSatan_group.johnny.members[1]
party_add(mSatan_homie.johnny, LOCAL_PLAYER)
follower_set_can_abandon( mSatan_homie.johnny, false )
on_death ( "mSatan_failure_johnny_died_cb", mSatan_homie.johnny )
on_dismiss ( "mSatan_failure_johnny_dismissed_cb", mSatan_homie.johnny )
turn_invulnerable( mSatan_group.johnny.members[1] )
character_set_never_catch_fire(mSatan_group.johnny.members[1])
end
party_set_dismissable(false)
end
mission_start_fade_out()
city_zone_swap("m_Sthrone", true)
-- HVS_JBG - moved this before the fade so we don't see satan pop in.
-- it should also give his wings a chance to open and get into the anim network in time for the player swap SAM.
local block = true
group_create( mSatan_group.satan.name, block )
satan_disable_combat(true)
satan_set_flight_mode(mSatan_group.satan.members[1], false)
local cp = get_table_by_name(mSatan_checkpoint, MISSION_START_CHECKPOINT)
teleport_coop(cp.host_start, cp.client_start, true)
teleport( mSatan_group.satan.members[1], mSatan_navpoints.teleport_nav[1] )
human_clear_teleport_navpoints(mSatan_group.satan.members[1])
for i, nav in ipairs(mSatan_navpoints.teleport_nav) do
human_add_teleport_navpoint(mSatan_group.satan.members[1], nav)
end
satan_set_proxy_push_navpoint("satan_proxy_push_nav")
mission_start_fade_in()
--reduce player jump/sprint values
tweak_table_override_value("Jump_super_max_height_scripted",26)
tweak_table_override_value("Sprint_super_max_speed_scripted",28)
notoriety_force_no_spawn(true)
--while (mSatan_runtime.satan_wings_ready == false) do
-- thread_yield();
--end
if (coop_is_active() == false) then
-- if the player character isn't johnny, play the kinzie swap SAM.
if character_get_anim_set(LOCAL_PLAYER) ~= "PLYM" then
on_seamless_animated_moment_end("mSatan_Kinzie_swap_Complete")
satan_wing_pcswap_sam(mSatan_group.satan.members[1], true)
local actor_list2 = { mSatan_homie.johnny, LOCAL_PLAYER, mSatan_group.satan.members[1] }
seamless_animated_moment_prep("sam_kinzie_switch", actor_list2)
seamless_animated_moment_start("sam_kinzie_switch", actor_list2)
audio_object_post_event("Play_MSatan_Player_Swap")
delay(13.2)
player_swap_character()
party_dismiss_all()
group_destroy(mSatan_group.johnny)
--set up kinzie as a homie.
group_create( mSatan_group.kinzie.name, true )
mSatan_homie.kinzie = mSatan_group.kinzie.members[1]
party_add(mSatan_homie.kinzie, LOCAL_PLAYER)
follower_set_can_abandon( mSatan_homie.kinzie, false )
on_death ( "mSatan_failure_kinzie_died_cb", mSatan_homie.kinzie )
on_dismiss ( "mSatan_failure_kinzie_dismissed_cb", mSatan_homie.kinzie )
turn_invulnerable( mSatan_group.kinzie.members[1] )
character_set_never_catch_fire(mSatan_group.kinzie.members[1])
while(mSatan_runtime.kinzie_swap_complete == false) do
thread_yield()
end
on_seamless_animated_moment_end("")
else
satan_disable_combat(false)
end
else
satan_disable_combat(false)
end
end
-- The first objective
--
function mSatan_thr_run()
--objective_text(0,"","","",SYNC_ALL,OI_ASSET_LOCATION)
while not mSatan_runtime.satan_downed do
thread_yield()
end
objective_text_clear(0)
convo_end_all()
--convo_start(mSatan_convo.face_punch)
on_seamless_animated_moment_end("mSatan_Face_Punch_Complete")
-- since we swap out kinzie for johnny now, the homie actor will always be kinzie
local player_char = LOCAL_PLAYER
local homie = mSatan_homie.kinzie
-- HVS_BDF: gotta account for co-op
if coop_is_active() then
-- If the local player isn't Johnny, then they must be Kinzie.
if character_get_anim_set(LOCAL_PLAYER) ~= "PLYM" then
player_char = REMOTE_PLAYER
homie = LOCAL_PLAYER
else
homie = REMOTE_PLAYER
end
end
local actor_list1 = { mSatan_group.satan.members[1], player_char, homie }
seamless_animated_moment_prep("sam_satan_punch", actor_list1)
seamless_animated_moment_start("sam_satan_punch", actor_list1)
audio_object_post_event("Play_MSatan_Punch")
-- register a callback function to be called at the end
on_anim_trigger( "mSatan_SAM_fade_out", mSatan_group.satan.members[1] )
while(mSatan_runtime.face_punch_complete == false) do
thread_yield()
end
on_seamless_animated_moment_end("")
end
-- Callback handler for the Shadow Demon's SAM animation trigger
function mSatan_SAM_fade_out()
--seamless_animated_moment_cleanup() -- HVS_BDF: we don't want this here because it causes the camera to pan back during the fade-out
fade_out(0)
end
-- Do any cleanup for this checkpoint.
--
-- (+++THIS IS CALLED FROM MISSION CLEANUP, MUST RETURN IMMEDIATELY+++)
--
-- mission_exit: (bool) Whether we're exiting the mission entirely, or just
-- moving on to the next checkpoint.
--
function mSatan_thr_cleanup(mission_exit)
if mission_exit then
mSatan_cleanup_homies()
end
on_anim_trigger( "", mSatan_group.satan.members[1] )
end
function mSatan_Face_Punch_Complete()
mSatan_runtime.mission_end_complete = true;
mSatan_runtime.face_punch_complete = true;
seamless_animated_moment_cleanup()
mission_end_success("mSatan", mSatan_scene.outro, {"cancel_end_host", "cancel_end_client"})
end
function mSatan_Kinzie_swap_Complete()
mSatan_runtime.kinzie_swap_complete = true;
satan_wing_pcswap_sam(mSatan_group.satan.members[1], false)
satan_disable_combat(false)
seamless_animated_moment_cleanup()
end
function mSatan_cleanup_homies()
if mSatan_homie.kinzie ~= nil and mSatan_homie.kinzie ~= "" then
on_death("", mSatan_homie.kinzie)
on_dismiss("", mSatan_homie.kinzie)
end
end
function mSatan_failure_kinzie_died_cb()
mission_end_failure("mSatan", "GM_SATAN_FAIL_KINZIE_DIED")
end
function mSatan_failure_johnny_died_cb()
mission_end_failure("mSatan", "GM_SATAN_FAIL_JOHNNY_DIED")
end
function mSatan_failure_kinzie_dismissed_cb()
mission_end_failure("mSatan", "GM_SATAN_FAIL_KINZIE_DIS")
end
function mSatan_failure_johnny_dismissed_cb()
mission_end_failure("mSatan", "GM_SATAN_FAIL_JOHNNY_DIS")
end
------------------------------------
--
-- Checkpoint helper functions
--
------------------------------------
------------------------------------
--
-- Checkpoint callback functions
--
------------------------------------
------------------------------------
--
-- Checkpoint thread functions
--
------------------------------------
--------------------------------------------------------------------------------------------------
--[[ next_checkpoint_nav ]]--
--------------------------------------------------------------------------------------------------
------------------------------------
--
-- Checkpoint helper functions
--
------------------------------------
------------------------------------
--
-- Checkpoint callback functions
--
------------------------------------
------------------------------------
--
-- Checkpoint thread functions
--
------------------------------------
--------------------------------------------------------------------------------------------------
--[[**********************]]--
--[[ ]]--
--[[ Common functions ]]--
--[[ ]]--
--[[**********************]]--
--------------------------------------------------------------------------------------------------
--[[**********************]]--
--[[ ]]--
--[[ Callback functions ]]--
--[[ ]]--
--[[**********************]]--
--------------------------------------------------------------------------------------------------
function mSatan_face_punch( npc )
mSatan_runtime.satan_downed = true;
end
function mSatan_wings_ready( npc )
mSatan_runtime.satan_wings_ready = true;
end
--[[**********************]]--
--[[ ]]--
--[[ Thread functions ]]--
--[[ ]]--
--[[**********************]]--