Files
2025-09-29 00:52:08 +02:00

816 lines
30 KiB
Python
Executable File

// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************
//
// SCRIPT NAME : launcher_Triathlon.sch
// AUTHOR(S) : Ryan Paradis [RP], Carlos Mijares [CM]
// DESCRIPTION : Handles launching Triathlon from the in-game world.
//
// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************
//Compile out Title Update changes to header functions.
//Must be before includes.
//CONST_INT USE_TU_CHANGES 0 // Removed by Kenneth R.
CONST_INT LAUNCHER_POINT_ENTER 1 // Tells the script that you kick it off by entering a point.
CONST_INT LAUNCHER_BUTTON_PRESS 1 // Need to press a button in that radius to play triathlon. Using default LB.
CONST_INT LAUNCHER_CUSTOM_SCRIPT_LAUNCH 1
CONST_INT LAUNCHER_SNAP_CHECKPOINT_TO_GROUND 1
CONST_INT LAUNCHER_DONT_CHECK_RELOAD_RANGE 1
CONST_INT LAUNCHER_ON_FOOT_RESTRICTED 1
CONST_INT LAUNCHER_CLEAR_SCENE_ON_START 1
CONST_INT LAUNCHER_HAS_TRIGGER_SCENE 1
TWEAK_FLOAT TRI_CHATTER_PROB 0.50
TWEAK_FLOAT TRI_CHATTER_RANGE 30.0
TWEAK_INT NEXT_CHATTER_WAIT 10000
//CONST_INT LAUNCHER_PED_VARIATIONS 1
// =====================================
// FILE INCLUDES
// =====================================
USING "generic_launcher_header.sch"
// =====================================
// E N D FILE INCLUDES
// =====================================
// =====================================
// TRIATHLON LAUNCHER VARIABLES
// =====================================
VECTOR vCurrentRacePosition
VECTOR vChairPos
OBJECT_INDEX oStartBanner
OBJECT_INDEX oTable
OBJECT_INDEX oChair
OBJECT_INDEX oClipboard
OBJECT_INDEX oPencil
PED_INDEX pedStartPed
SCENARIO_BLOCKING_INDEX sbiChair
BOOL bAllowTriLauncherScene = TRUE
BOOL bAreWeInExile = FALSE
BOOL bHintCamReady = TRUE
INT iChatterStamp
TRIATHLON_RACE_INDEX eCurrentRace = TRIATHLON_RACE_NONE
INT iNavBlockAreas[5]
// =====================================
// E N D TRIATHLON LAUNCHER VARIABLES
// =====================================
PROC SETUP_NAVMESH_BLOCKING_VALUES_HARDCODED(TRIATHLON_RACE_INDEX eCurrentTriRace, INT iNavIndex, VECTOR& vPos, VECTOR& vScale, FLOAT& fHeading)
SWITCH eCurrentTriRace
CASE TRIATHLON_RACE_VESPUCCI
SWITCH iNavIndex
CASE 0
vPos = << -1285.28811, -2039.94321, 1.60045 >>
vScale = << 4.0, 10.2, 10.0>>
fHeading = 2.3168
BREAK
CASE 1
vPos = << -1268.66729, -2024.77961, 1.56780 >>
vScale = << 4.0, 10.2, 10.0>>
fHeading = 2.4
BREAK
CASE 2
vPos = << -1227.08472, -2053.45801, 12.98837 >>
vScale = << 5.0, 14.0, 10.0 >>
fHeading = 2.6
BREAK
CASE 3
vPos = << -1210.86499, -2052.28882, 13.0 >>
vScale = << 1.96, 3.0, 10.0 >>
fHeading = 2.865
BREAK
CASE 4
vPos = << -1215.45227, -2065.8811, 13.0 >>
vScale = << 1.63, 2.9, 10.0 >>
fHeading = 2.685
BREAK
ENDSWITCH
BREAK
CASE TRIATHLON_RACE_ALAMO_SEA
SWITCH iNavIndex
CASE 0
vPos = << 2384.31685, 4268.87617, 30.44363 >>
vScale = << 4.0, 10.0, 10.0>>
fHeading = 6.047
BREAK
CASE 1
vPos = << 2384.97534, 4289.71924, 30.32816 >>
vScale = << 4.0, 10.0, 10.0>>
fHeading = 3.238
BREAK
CASE 2
vPos = << 2436.90698, 4282.84961, 35.58720 >>
vScale = << 4.5, 13.0, 10.0 >>
fHeading = 3.019
BREAK
CASE 3
vPos = << 2411.25024, 4298.00635, 34.98311 >>
vScale = << 2.1, 3.2, 10.0 >>
fHeading = 1.19
BREAK
CASE 4
vPos = << 0.0, 0.0, 0.0 >>
vScale = << 1.63, 2.9, 0.0 >>
fHeading = 2.685
BREAK
ENDSWITCH
BREAK
CASE TRIATHLON_RACE_IRONMAN
SWITCH iNavIndex
CASE 0
vPos = << 1568.879, 3829.782, 30.95098 >>
vScale = << 4.0, 9.9, 10.0>>
fHeading = 2.107
BREAK
CASE 1
vPos = << 1586.192, 3842.765, 30.538 >>
vScale = << 4.0, 9.9, 10.0>>
fHeading = 2.295
BREAK
CASE 2
vPos = << 1594.00220, 3810.71753, 33.55904 >>
vScale = << 4.0, 12.0, 10.0 >>
fHeading = 2.251
BREAK
CASE 3
vPos = << 1604.67896, 3828.30786, 33.82485 >>
vScale = << 1.96, 3.0, 10.0 >>
fHeading = 0.876
BREAK
CASE 4
vPos = << 1607.13513, 3824.38794, 33.06039 >>
vScale = << 1.63, 2.9, 0.0 >>
fHeading = 0.0
BREAK
ENDSWITCH
BREAK
ENDSWITCH
ENDPROC
// ====================================================
// TRIATHLON LAUNCHER FUNCTIONS AND PROCEDURES
// ====================================================
PROC HANDLE_CHATTERING_PEDS_AT_LAUNCHER()
IF GET_GAME_TIMER() > iChatterStamp AND fPlayerDistToLauncher < (TRI_CHATTER_RANGE * TRI_CHATTER_RANGE)
iChatterStamp = GET_GAME_TIMER() + NEXT_CHATTER_WAIT
CPRINTLN(DEBUG_TRIATHLON, "[LAUNCHER_CUSTOM_APPROACH_WAIT] Time to cheer, next wait=", iChatterStamp)
IF GET_RANDOM_FLOAT_IN_RANGE() <= TRI_CHATTER_PROB
CPRINTLN(DEBUG_TRIATHLON, "[LAUNCHER_CUSTOM_APPROACH_WAIT] Probability check passed")
// Pick the exclude ped so we don't get the player chattering
PED_TYPE pedExclude
enumCharacterList ePlayerChar = GET_CURRENT_PLAYER_PED_ENUM()
IF ePlayerChar = CHAR_MICHAEL
pedExclude = PEDTYPE_PLAYER1
ELIF ePlayerChar = CHAR_FRANKLIN
pedExclude = PEDTYPE_PLAYER2
ELIF ePlayerChar = CHAR_TREVOR
pedExclude = PEDTYPE_PLAYER_UNUSED
ENDIF
// Find the range from the player we're going to grab a cheering ped from
PED_INDEX pedsNearby[10]
SET_SCENARIO_PEDS_TO_BE_RETURNED_BY_NEXT_COMMAND(TRUE)
INT iPedsNearby = GET_PED_NEARBY_PEDS(PLAYER_PED_ID(), pedsNearby, pedExclude)
PED_INDEX pedChattering
INT p
REPEAT iPedsNearby p
IF NOT IS_PED_INJURED(pedsNearby[p]) AND NOT DOES_ENTITY_EXIST(pedChattering)
IF GET_ENTITY_MODEL(pedsNearby[p]) = A_M_Y_ROADCYC_01
pedChattering = pedsNearby[p]
CPRINTLN(DEBUG_TRIATHLON, "chattering ped selected")
ENDIF
ENDIF
ENDREPEAT
CPRINTLN(DEBUG_TRIATHLON, "DOES_ENTITY_EXIST(pedChattering)", PICK_STRING(DOES_ENTITY_EXIST(pedChattering), "TRUE", "FALSE"))
// Make sure the cheering ped exists
IF DOES_ENTITY_EXIST(pedChattering) AND NOT IS_PED_INJURED(pedChattering)
TEXT_LABEL_31 texVoice = "A_M_Y_TRIATHLON_01_MINI_0"
texVoice += GET_RANDOM_INT_IN_RANGE(1, 5)
PLAY_PED_AMBIENT_SPEECH_WITH_VOICE(pedChattering, "TRIATHLON_WARMUP", texVoice, SPEECH_PARAMS_FORCE_NORMAL)
CPRINTLN(DEBUG_TRIATHLON, "[LAUNCHER_CUSTOM_APPROACH_WAIT] ", texVoice, " is chattering for me. Ped is ", GET_ENTITY_MODEL(pedChattering))
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Request everything you need here. Feel free to add a handful of variables up above (don't go bonkers.)
/// Note that the generic launcher system automatically handles streaming the minigame script.
/// This function is called once, at startup.
PROC LAUNCHER_CUSTOM_REQUEST_ASSETS()
IF bAllowTriLauncherScene
PRINTLN("[launcher_Triathlon.sc->LAUNCHER_CUSTOM_REQUEST_ASSETS] Loading Triathlon launcher assets for ", ENUM_TO_INT(eCurrentRace), " race.")
REQUEST_MODEL(PROP_TRI_TABLE_01)
REQUEST_MODEL(PROP_CHAIR_08)
REQUEST_MODEL(A_M_Y_RoadCyc_01)
REQUEST_MODEL(P_CS_CLIPBOARD)
REQUEST_MODEL(PROP_PENCIL_01)
REQUEST_ANIM_DICT( "amb@prop_human_seat_chair@male@generic@idle_a" )
SWITCH eCurrentRace
CASE TRIATHLON_RACE_VESPUCCI
IF NOT IS_IPL_ACTIVE("AP1_04_TriAf01")
REQUEST_IPL("AP1_04_TriAf01")
ENDIF
BREAK
CASE TRIATHLON_RACE_ALAMO_SEA
IF NOT IS_IPL_ACTIVE("CS2_06_TriAf02")
REQUEST_IPL("CS2_06_TriAf02")
ENDIF
BREAK
CASE TRIATHLON_RACE_IRONMAN
IF NOT IS_IPL_ACTIVE("CS4_04_TriAf03")
REQUEST_IPL("CS4_04_TriAf03")
ENDIF
BREAK
ENDSWITCH
ELSE
//DEBUG_MESSAGE("[launcher_Triathlon.sc->LAUNCHER_CUSTOM_REQUEST_ASSETS] Cannot load Triathlon assets. bAllowTriLauncherSceneis FALSE")
ENDIF
ENDPROC
/// PURPOSE:
/// Return TRUE when you're done streaming the things you requested up above! FALSE if you're still streaming.
/// The system loops on this until you return TRUE.
FUNC BOOL LAUNCHER_CUSTOM_ASSETS_LOADED()
IF bAllowTriLauncherScene
IF NOT HAS_MODEL_LOADED(PROP_TRI_TABLE_01)
DEBUG_MESSAGE("Waiting on PROP_TRI_TABLE_01")
RETURN FALSE
ENDIF
IF NOT HAS_MODEL_LOADED(PROP_CHAIR_08)
DEBUG_MESSAGE("Waiting on PROP_CHAIR_08")
RETURN FALSE
ENDIF
IF NOT HAS_MODEL_LOADED(A_M_Y_RoadCyc_01)
DEBUG_MESSAGE("Waiting on A_M_Y_RoadCyc_01")
RETURN FALSE
ENDIF
IF NOT HAS_ANIM_DICT_LOADED("amb@prop_human_seat_chair@male@generic@idle_a")
DEBUG_MESSAGE("Waiting on amb@prop_human_seat_chair@male@generic@idle_a")
RETURN FALSE
ENDIF
IF NOT HAS_MODEL_LOADED(P_CS_CLIPBOARD)
DEBUG_MESSAGE("Waiting on P_CS_CLIPBOARD")
RETURN FALSE
ENDIF
IF NOT HAS_MODEL_LOADED(PROP_PENCIL_01)
DEBUG_MESSAGE("Waiting on PROP_PENCIL_01")
RETURN FALSE
ENDIF
ELSE
//DEBUG_MESSAGE("[launcher_Triathlon.sc->LAUNCHER_CUSTOM_ASSETS_LOADED] Cannot check loading Triathlon assets. bAllowTriLauncherSceneis FALSE")
ENDIF
// Code should never reach here.
RETURN TRUE
ENDFUNC
/// PURPOSE:
/// returns true if we havent complete exile 1 yet.
/// RETURNS:
///
FUNC BOOL LAUNCHER_TRIATHLON_IS_MISSION_FLOW_BEFORE_EXILE() // check to see if we're inbetween exile and fib5
// PRINTLN("LAUNCHER_TRIATHLON_IS_MISSION_FLOW_BEFORE_EXILE()")
IF NOT GET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_MICHAEL_TREVOR_EXILE_STARTED)
PRINTLN("Mike and Trev not in Exile yet.")
RETURN TRUE
ENDIF
// PRINTLN("We have not completed family 5")
RETURN FALSE
ENDFUNC
PROC LAUNCHER_TRIATHLON_HANDLE_HINT_CAM()
IF IS_PLAYER_PLAYING(PLAYER_ID()) AND NOT IS_ENTITY_DEAD( pedStartPed )
IF bHintCamReady
SET_GAMEPLAY_ENTITY_HINT( pedStartPed, <<0,0,0>> )
bHintCamReady = FALSE
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// returns true if we finished fib 5
/// RETURNS:
///
FUNC BOOL LAUNCHER_TRIATHLON_IS_MISSION_FLOW_AFTER_EXILE() // check to see if we're inbetween exile and fib5
// PRINTLN("LAUNCHER_TRIATHLON_IS_MISSION_FLOW_AFTER_FIB_5()")
IF GET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_MICHAEL_TREVOR_EXILE_FINISHED)
// PRINTLN("We have completed FIB 5")
RETURN TRUE
ENDIF
// PRINTLN("We haven't complete FIB 5")
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Initialize specific Triathlon launcher code.
PROC LAUNCHER_CUSTOM_SCRIPT_INIT()
DEBUG_MESSAGE("[launcher_Triathlon.sc->LAUNCHER_CUSTOM_SCRIPT_INIT] Procedure started.")
scriptName = "TriathlonSP"
helpButtonPress = "PLAY_TRIATH"
// michaelVariations.pedCompTorsoDrw = 13 //removing outfit requirement for bug 1171468
// michaelVariations.pedCompTorsoTxt = 0
// michaelVariations.pedCompLegDrw = 12
// michaelVariations.pedCompLegTxt = 0
// michaelVariations.pedCompFeetDrw = 8
// michaelVariations.pedCompFeetTxt = 0
//
// trevorVariations.pedCompTorsoDrw = 10
// trevorVariations.pedCompTorsoTxt = 0
// trevorVariations.pedCompLegDrw = 10
// trevorVariations.pedCompLegTxt = 0
// trevorVariations.pedCompFeetDrw = 4
// trevorVariations.pedCompFeetTxt = 0
//
// franklinVariations.pedCompTorsoDrw = 5
// franklinVariations.pedCompTorsoTxt = 0
// franklinVariations.pedCompLegDrw = 5
// franklinVariations.pedCompLegTxt = 0
// franklinVariations.pedCompFeetDrw = 3
// franklinVariations.pedCompFeetTxt = 0
//
// outfitHelpLabel = "MG_TRI_OUTFIT"
eMinigame = MINIGAME_TRIATHLON
SET_BITMASK_AS_ENUM(launcherFlags, LAUNCHER_SHUTDOWN_ALLOW_MULTIPLE_COPIES)
iStackSize = MISSION_STACK_SIZE
bAllowTriLauncherScene = TRUE
// Check what Triathlon race is closest to the player.
IF NOT IS_ENTITY_DEAD(GET_PLAYER_PED(GET_PLAYER_INDEX()))
// This is just to avoid an assert.
ENDIF
// VECTOR vPlayerPosition = GET_ENTITY_COORDS(GET_PLAYER_PED(GET_PLAYER_INDEX()))
eCurrentRace = GET_TRIATHLON_RACE_INDEX_BY_COORDS(vLaunchLocation, vCurrentRacePosition)
IF LAUNCHER_TRIATHLON_IS_MISSION_FLOW_BEFORE_EXILE() OR LAUNCHER_TRIATHLON_IS_MISSION_FLOW_AFTER_EXILE()
//we're fine
ELSE
bAreWeInExile = TRUE
ENDIF
SWITCH (eCurrentRace)
CASE TRIATHLON_RACE_VESPUCCI
eLauncherStaticBlip = STATIC_BLIP_MINIGAME_TRIATHLON1
BREAK
CASE TRIATHLON_RACE_ALAMO_SEA
eLauncherStaticBlip = STATIC_BLIP_MINIGAME_TRIATHLON2
BREAK
CASE TRIATHLON_RACE_IRONMAN
eLauncherStaticBlip = STATIC_BLIP_MINIGAME_TRIATHLON3
IF bAreWeInExile
PRINTLN("terminating tri launcher since we're between exile_1 and FIB_5")
SET_BITMASK_AS_ENUM(launcherFlags, LAUNCHER_SHUTDOWN_FORCED_ON_INIT)
GENERIC_LAUNCHER_FORCE_WAIT_TERMINATE_AND_CLEAR_STATIC_BLIP(eLauncherStaticBlip)
ENDIF
BREAK
ENDSWITCH
// Make sure our global isn't stuck at an unknown race.
IF (g_savedGlobals.sTriathlonData.eCurrentRaceUnlocked = TRIATHLON_RACE_NONE)
PRINTLN("TRIATHLON LAUNCHER UNLOCKING OUR FIRST RACE!")
g_savedGlobals.sTriathlonData.eCurrentRaceUnlocked = TRIATHLON_RACE_VESPUCCI
ENDIF
// Okay, so according to # 252503, we need to handle the blipping and unlocking in a progression.
// so right here, if this is a race that isn't yet unlocked, then force quit.
// If our current unlocked index is < the one we're at, we cant' run.
IF (g_savedGlobals.sTriathlonData.eCurrentRaceUnlocked < eCurrentRace)
PRINTLN("TRIATHLON LAUNCHER QUITTING AS THIS IS A RACE THAT'S NOT UNLOCKED BY FLOW YET!")
SET_BITMASK_AS_ENUM(launcherFlags, LAUNCHER_SHUTDOWN_FORCED_ON_INIT)
ENDIF
ENDPROC
/// PURPOSE:
/// Creates the launcher assets in the current race's location.
/// Here's where you'll spawn your dudes, and give them starting tasks.
/// This function is called once, after streaming is done.
PROC LAUNCHER_CUSTOM_SPAWN_SCENE()
IF bAllowTriLauncherScene
PRINTLN("[launcher_Triathlon.sc] Spawning duffel bag for ", ENUM_TO_INT(eCurrentRace), " race at ", vCurrentRacePosition)
CLEAR_AREA_OF_OBJECTS(vCurrentRacePosition, 25)
IF DOES_SCENARIO_GROUP_EXIST("Triathlon_1_Start") AND eCurrentRace = TRIATHLON_RACE_ALAMO_SEA
SET_SCENARIO_GROUP_ENABLED("Triathlon_1_Start", TRUE)
PRINTLN("Enabling Scenario Group 'Triathlon_1_Start'")
ELSE
PRINTLN("Trying to enable Scenario Group 'Triathlon_1_Start' but it doesn't exist!")
ENDIF
IF DOES_SCENARIO_GROUP_EXIST("Triathlon_2_Start") AND eCurrentRace = TRIATHLON_RACE_VESPUCCI
SET_SCENARIO_GROUP_ENABLED("Triathlon_2_Start", TRUE)
PRINTLN("Enabling Scenario Group 'Triathlon_2_Start'")
ELSE
PRINTLN("Trying to enable Scenario Group 'Triathlon_2_Start' but it doesn't exist!")
ENDIF
IF DOES_SCENARIO_GROUP_EXIST("Triathlon_3_Start") AND eCurrentRace = TRIATHLON_RACE_IRONMAN
SET_SCENARIO_GROUP_ENABLED("Triathlon_3_Start", TRUE)
PRINTLN("Enabling Scenario Group 'Triathlon_3_Start'")
ELSE
PRINTLN("Trying to enable Scenario Group 'Triathlon_3_Start' but it doesn't exist!")
ENDIF
PRINTLN("Spawing start banner for triathlon")
FLOAT fHeading
VECTOR vTablePos, vPencilPos
IF NOT DOES_ENTITY_EXIST(oTable)
vTablePos = PICK_VECTOR(eCurrentRace = TRIATHLON_RACE_ALAMO_SEA, <<2434.1621, 4282.7744, 35.5112>>, PICK_VECTOR(eCurrentRace = TRIATHLON_RACE_VESPUCCI, <<-1231.2026, -2051.5308, 12.9317>>, PICK_VECTOR(eCurrentRace = TRIATHLON_RACE_IRONMAN, <<1591.0991, 3814.0264, 33.2697>>, <<0,0,0>>)))//PICK_VECTOR(eCurrentRace = TRIATHLON_RACE_ALAMO_SEA, <<2433.8008, 4282.8262, 35.4846>>, PICK_VECTOR(eCurrentRace = TRIATHLON_RACE_VESPUCCI, <<-1231.3861, -2051.5359, 12.9380>>/*<<-1231.0848, -2051.6245, 12.9332>>*/, PICK_VECTOR(eCurrentRace = TRIATHLON_RACE_IRONMAN, <<1590.8715, 3814.2053, 33.2459>>, <<0,0,0>>)))
fHeading = PICK_FLOAT(eCurrentRace = TRIATHLON_RACE_ALAMO_SEA, 264.0724, PICK_FLOAT(eCurrentRace = TRIATHLON_RACE_VESPUCCI, 256.2876, PICK_FLOAT(eCurrentRace = TRIATHLON_RACE_IRONMAN, 222.6197, 0.0)))
oTable = CREATE_OBJECT(PROP_TRI_TABLE_01, vTablePos)
SET_ENTITY_HEADING(oTable, fHeading)
FREEZE_ENTITY_POSITION(oTable, TRUE)
SET_MODEL_AS_NO_LONGER_NEEDED(PROP_TRI_TABLE_01)
ENDIF
IF NOT DOES_ENTITY_EXIST(oChair)
vChairPos = PICK_VECTOR(eCurrentRace = TRIATHLON_RACE_ALAMO_SEA, <<2434.9551, 4282.7109, 35.5333>>, PICK_VECTOR(eCurrentRace = TRIATHLON_RACE_VESPUCCI, <<-1230.3606, -2051.7612, 12.9180>>, PICK_VECTOR(eCurrentRace = TRIATHLON_RACE_IRONMAN, <<1591.6860, 3813.4014, 33.3371>>, <<0,0,0>>)))
fHeading = PICK_FLOAT(eCurrentRace = TRIATHLON_RACE_ALAMO_SEA, 264.3256, PICK_FLOAT(eCurrentRace = TRIATHLON_RACE_VESPUCCI, 253.0440, PICK_FLOAT(eCurrentRace = TRIATHLON_RACE_IRONMAN, 220.7912, 0.0)))
oChair = CREATE_OBJECT(PROP_CHAIR_08, vChairPos)
SET_ENTITY_HEADING(oChair, fHeading)
FREEZE_ENTITY_POSITION(oChair, TRUE)
SET_MODEL_AS_NO_LONGER_NEEDED(PROP_CHAIR_08)
ENDIF
IF NOT DOES_ENTITY_EXIST(oClipboard)
vTablePos.z += 0.54
oClipboard = CREATE_OBJECT(P_CS_CLIPBOARD, vTablePos)
SET_ENTITY_ROTATION(oClipboard, <<-90.0, 0.0, 90.0>>, DEFAULT, FALSE)
ACTIVATE_PHYSICS(oClipboard)
SET_MODEL_AS_NO_LONGER_NEEDED(P_CS_CLIPBOARD)
ENDIF
IF NOT DOES_ENTITY_EXIST(pedStartPed)
fHeading = PICK_FLOAT(eCurrentRace = TRIATHLON_RACE_ALAMO_SEA, 79.9315, PICK_FLOAT(eCurrentRace = TRIATHLON_RACE_VESPUCCI, 77.5972, PICK_FLOAT(eCurrentRace = TRIATHLON_RACE_IRONMAN, 47.2081, 0.0)))
pedStartPed = CREATE_PED(PEDTYPE_CIVMALE, A_M_Y_RoadCyc_01, vChairPos, fHeading)
SET_PED_COMPONENT_VARIATION(pedStartPed, PED_COMP_HEAD, 1, 0, 0)
SET_PED_COMPONENT_VARIATION(pedStartPed, PED_COMP_LEG, 0, 3, 0)
SET_PED_COMPONENT_VARIATION(pedStartPed, PED_COMP_TORSO, 0, 2, 0)
SET_MODEL_AS_NO_LONGER_NEEDED(A_M_Y_RoadCyc_01)
ENDIF
IF NOT DOES_ENTITY_EXIST(oPencil)
IF (eCurrentRace = TRIATHLON_RACE_ALAMO_SEA)
vPencilPos = <<2433.74, 4283.08, 36.235>>
ELIF (eCurrentRace = TRIATHLON_RACE_VESPUCCI)
vPencilPos = <<-1231.47, -2051.23, 13.68>>
ELIF (eCurrentRace = TRIATHLON_RACE_IRONMAN)
vPencilPos = <<1591.11, 3814.46, 33.99>>
ENDIF
oPencil = CREATE_OBJECT(PROP_PENCIL_01, vPencilPos)
SET_MODEL_AS_NO_LONGER_NEEDED(PROP_PENCIL_01)
ENDIF
IF NOT IS_PED_INJURED(pedStartPed)
IF DOES_SCENARIO_EXIST_IN_AREA(vChairPos, 3.0, TRUE)
TASK_USE_NEAREST_SCENARIO_TO_COORD_WARP(pedStartPed, vChairPos, 2.0)
ELSE
VECTOR vScenarioPos
FLOAT fScenarioHeading
SWITCH eCurrentRace
CASE TRIATHLON_RACE_VESPUCCI
vScenarioPos = <<-1230.3704, -2051.7656, 13.4441>>
fScenarioHeading = 69.8085
BREAK
CASE TRIATHLON_RACE_ALAMO_SEA
vScenarioPos = <<2435.0420, 4282.7163, 36.0357>>
fScenarioHeading = 83.5805
BREAK
CASE TRIATHLON_RACE_IRONMAN
vScenarioPos = <<1591.7103, 3813.3552, 33.8383>>
fScenarioHeading = 41.0251
BREAK
ENDSWITCH
TASK_START_SCENARIO_AT_POSITION(pedStartPed, "PROP_HUMAN_SEAT_CHAIR", vScenarioPos, fScenarioHeading, -1)
ENDIF
ENDIF
VECTOR vNavAreaPos, vNavAreaScale
FLOAT fNavAreaHeading
INT iNavAreaIter
REPEAT COUNT_OF(iNavBlockAreas) iNavAreaIter
SETUP_NAVMESH_BLOCKING_VALUES_HARDCODED(eCurrentRace, iNavAreaIter, vNavAreaPos, vNavAreaScale, fNavAreaHeading)
IF NOT IS_VECTOR_ZERO(vNavAreaPos)
iNavBlockAreas[iNavAreaIter] = ADD_NAVMESH_BLOCKING_OBJECT(vNavAreaPos, vNavAreaScale, fNavAreaHeading)
ENDIF
ENDREPEAT
ELSE
DEBUG_MESSAGE("[launcher_Triathlon.sc->LAUNCHER_CUSTOM_SPAWN_SCENE] Cannot spawn scene. bAllowTriLauncherSceneis FALSE")
ENDIF
ENDPROC
/// PURPOSE:
/// Start a new script.
/// RETURNS:
/// New script started.
FUNC THREADID LAUNCHER_CUSTOM_RUN_SCRIPT()
DEBUG_MESSAGE("[launcher_Triathlon.sc->LAUNCHER_CUSTOM_RUN_SCRIPT] Function started.")
// Clear all previously printed help.
CLEAR_HELP()
TRIATHLON_LAUNCH_DATA TriLaunchData
TriLaunchData.raceToLaunch = eCurrentRace
TriLaunchData.raceStartLocation = vCurrentRacePosition
TriLaunchData.oTable = oTable
TriLaunchData.pedStartPed = pedStartPed
TriLaunchData.oClipboard = oClipboard
TriLaunchData.oPencil = oPencil
// You'll want this at the very least.
THREADID threadTemp = START_NEW_SCRIPT_WITH_ARGS(scriptName, TriLaunchData, SIZE_OF(TRIATHLON_LAUNCH_DATA), iStackSize)
SET_SCRIPT_AS_NO_LONGER_NEEDED(scriptName)
DEBUG_MESSAGE("[launcher_Triathlon.sc->LAUNCHER_CUSTOM_RUN_SCRIPT] Function completed. Returning thread ID.")
RETURN threadTemp
ENDFUNC
/// PURPOSE:
/// This is called every update when the player is within 100m of the script start point, but before he actually starts the minigame.
PROC LAUNCHER_CUSTOM_APPROACH_WAIT()
IF eCurrentRace = TRIATHLON_RACE_IRONMAN AND bAreWeInExile
PRINTLN("terminating tri launcher since we're between exile_1 and FIB_5")
GENERIC_LAUNCHER_FORCE_WAIT_TERMINATE_AND_CLEAR_STATIC_BLIP(eLauncherStaticBlip)
ELIF IS_PED_INJURED(pedStartPed)
OR IS_SHOCKING_EVENT_IN_SPHERE(EVENT_SHOCKING_GUNSHOT_FIRED,GET_ENTITY_COORDS(pedStartPed),40.0)
OR IS_SHOCKING_EVENT_IN_SPHERE(EVENT_SHOCKING_SEEN_WEAPON_THREAT,GET_ENTITY_COORDS(pedStartPed),40.0)
PRINT_HELP("TRI_DEATH")
PRINTLN("You injured the table guy")
//In this instance store a reference to our current static blip so we can restore the
//reference after cleanup.
STATIC_BLIP_NAME_ENUM eTempStaticBlip = eLauncherStaticBlip
GENERIC_LAUNCHER_FORCE_WAIT_TERMINATE_AND_CLEAR_STATIC_BLIP(eLauncherStaticBlip)
eLauncherStaticBlip = eTempStaticBlip
ELIF NOT bAreWeInExile
IF LAUNCHER_TRIATHLON_IS_MISSION_FLOW_BEFORE_EXILE() OR LAUNCHER_TRIATHLON_IS_MISSION_FLOW_AFTER_EXILE()
//we're fine
ELSE
bAreWeInExile = TRUE
//we're in exile!!
ENDIF
ENDIF
IF DOES_ENTITY_EXIST(pedStartPed)
IF NOT IS_ENTITY_DEAD(pedStartPed)
AND NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
IF VDIST2(GET_ENTITY_COORDS(pedStartPed), GET_ENTITY_COORDS(PLAYER_PED_ID())) <= 12*12
IF GET_SCRIPT_TASK_STATUS(pedStartPed, SCRIPT_TASK_LOOK_AT_ENTITY) <> PERFORMING_TASK
TASK_LOOK_AT_ENTITY(pedStartPed, PLAYER_PED_ID(), -1)
ENDIF
ELIF GET_SCRIPT_TASK_STATUS(pedStartPed, SCRIPT_TASK_LOOK_AT_ENTITY) = PERFORMING_TASK
TASK_CLEAR_LOOK_AT(pedStartPed)
ENDIF
ENDIF
ENDIF
IF bAllowTriLauncherScene
#IF IS_DEBUG_BUILD
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_UP)
START_WIDGET_GROUP("TriLauncher")
ADD_WIDGET_FLOAT_SLIDER("TRI_CHATTER_PROB", TRI_CHATTER_PROB, 0, 1, 0.01)
ADD_WIDGET_FLOAT_SLIDER("TRI_CHATTER_RANGE", TRI_CHATTER_RANGE, 0, 30, 0.01)
ADD_WIDGET_INT_SLIDER("NEXT_CHATTER_WAIT", NEXT_CHATTER_WAIT, 0, 10000, 100)
STOP_WIDGET_GROUP()
ENDIF
#ENDIF
HANDLE_CHATTERING_PEDS_AT_LAUNCHER()
ENDIF
ENDPROC
/// PURPOSE:
/// This function is called when your minigame script starts.
PROC LAUNCHER_CUSTOM_CLEAR_SCENE()
IF bAllowTriLauncherScene
INT iNavAreaIter
REPEAT COUNT_OF(iNavBlockAreas) iNavAreaIter
IF DOES_NAVMESH_BLOCKING_OBJECT_EXIST(iNavBlockAreas[iNavAreaIter])
REMOVE_NAVMESH_BLOCKING_OBJECT(iNavBlockAreas[iNavAreaIter])
ENDIF
ENDREPEAT
RESET_EXCLUSIVE_SCENARIO_GROUP()
DEBUG_MESSAGE("[launcher_Triathlon.sc->LAUNCHER_CUSTOM_CLEAR_SCENE] Procedure started. Clearing scene.")
ENDIF
ENDPROC
//Unlock the next race and activate its blip
PROC LAUNCHER_ACTIVATE_NEXT_RACE()
// Handle a win flag here.
IF IS_BITMASK_AS_ENUM_SET(g_savedGlobals.sTriathlonData.iBitFlags, TRIATHLON_WonRace)
CLEAR_BITMASK_AS_ENUM(g_savedGlobals.sTriathlonData.iBitFlags, TRIATHLON_WonRace)
// If we just played the highest rank race available to us, set us to be allowed to play the next.
IF (eCurrentRace = g_savedGlobals.sTriathlonData.eCurrentRaceUnlocked)
IF (g_savedGlobals.sTriathlonData.eCurrentRaceUnlocked <> TRIATHLON_RACE_IRONMAN)
g_savedGlobals.sTriathlonData.eCurrentRaceUnlocked =
INT_TO_ENUM(TRIATHLON_RACE_INDEX, ENUM_TO_INT(g_savedGlobals.sTriathlonData.eCurrentRaceUnlocked) + 1)
// Set the next race blip open.
IF (g_savedGlobals.sTriathlonData.eCurrentRaceUnlocked = TRIATHLON_RACE_ALAMO_SEA)
PRINTLN("launcher_Triathlon: ** Opening Race #2")
SET_STATIC_BLIP_ACTIVE_STATE(STATIC_BLIP_MINIGAME_TRIATHLON2, TRUE)
SET_BUILDING_STATE(BUILDINGNAME_IPL_TRIATHLON_2_INFLATABLE, BUILDINGSTATE_DESTROYED)
ELIF (g_savedGlobals.sTriathlonData.eCurrentRaceUnlocked = TRIATHLON_RACE_IRONMAN)
SET_STATIC_BLIP_ACTIVE_STATE(STATIC_BLIP_MINIGAME_TRIATHLON3, TRUE)
SET_BUILDING_STATE(BUILDINGNAME_IPL_TRIATHLON_3_INFLATABLE, BUILDINGSTATE_DESTROYED)
PRINTLN("launcher_Triathlon: ** Opening Race #3")
ENDIF
//B* 1711966: Make the help text for TRI_3 appear only after exiled
IF bAreWeInExile AND g_savedGlobals.sTriathlonData.eCurrentRaceUnlocked = TRIATHLON_RACE_IRONMAN
CLEAR_ONE_TIME_HELP_MESSAGE_DISPLAYED(FHM_TRI_3_UNLOCKED_IN_EXILE)
ELSE
ADD_HELP_TO_FLOW_QUEUE("TRI_NEWRC")
SET_ONE_TIME_HELP_MESSAGE_DISPLAYED(FHM_TRI_3_UNLOCKED_IN_EXILE)
ENDIF
ENDIF
// We just passed this race, set our blip to be short range.
IF (eCurrentRace = TRIATHLON_RACE_VESPUCCI)
PRINTLN("launcher_Triathlon: ** Setting Race #1 short range. Setting Race #2 long range.")
SET_STATIC_BLIP_SHORT_RANGE(STATIC_BLIP_MINIGAME_TRIATHLON1)
SET_STATIC_BLIP_LONG_RANGE(STATIC_BLIP_MINIGAME_TRIATHLON2)
SET_STATIC_BLIP_HAS_CHECKMARK(STATIC_BLIP_MINIGAME_TRIATHLON1, TRUE)
SET_STATIC_BLIP_HIDE_ON_WANTED(STATIC_BLIP_MINIGAME_TRIATHLON2, TRUE)
ELIF (eCurrentRace = TRIATHLON_RACE_ALAMO_SEA)
PRINTLN("launcher_Triathlon: ** Setting Race #1 & 2 short range. Setting Race #3 long range.")
SET_STATIC_BLIP_SHORT_RANGE(STATIC_BLIP_MINIGAME_TRIATHLON1)
SET_STATIC_BLIP_SHORT_RANGE(STATIC_BLIP_MINIGAME_TRIATHLON2)
SET_STATIC_BLIP_LONG_RANGE(STATIC_BLIP_MINIGAME_TRIATHLON3)
SET_STATIC_BLIP_HAS_CHECKMARK(STATIC_BLIP_MINIGAME_TRIATHLON1, TRUE)
SET_STATIC_BLIP_HAS_CHECKMARK(STATIC_BLIP_MINIGAME_TRIATHLON2, TRUE)
SET_STATIC_BLIP_HIDE_ON_WANTED(STATIC_BLIP_MINIGAME_TRIATHLON3, TRUE)
ELIF (eCurrentRace = TRIATHLON_RACE_IRONMAN)
PRINTLN("launcher_Triathlon: ** Setting Race #1, 2 & 3 short range.")
SET_STATIC_BLIP_SHORT_RANGE(STATIC_BLIP_MINIGAME_TRIATHLON1)
SET_STATIC_BLIP_SHORT_RANGE(STATIC_BLIP_MINIGAME_TRIATHLON2)
SET_STATIC_BLIP_SHORT_RANGE(STATIC_BLIP_MINIGAME_TRIATHLON3)
SET_STATIC_BLIP_HAS_CHECKMARK(STATIC_BLIP_MINIGAME_TRIATHLON1, TRUE)
SET_STATIC_BLIP_HAS_CHECKMARK(STATIC_BLIP_MINIGAME_TRIATHLON2, TRUE)
SET_STATIC_BLIP_HAS_CHECKMARK(STATIC_BLIP_MINIGAME_TRIATHLON3, TRUE)
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// This is called once when your minigame script is no longer running. After it has been noticed by the launcher that your thread is terminated.
PROC LAUNCHER_CUSTOM_SCRIPT_END()
// If we're close to the signup ped, or he's visible, jsut take ownership again.
//VECTOR vChairPos = PICK_VECTOR(eCurrentRace = TRIATHLON_RACE_ALAMO_SEA, <<2434.9551, 4282.7109, 35.5333>>, PICK_VECTOR(eCurrentRace = TRIATHLON_RACE_VESPUCCI, <<-1230.3606, -2051.7612, 12.9180>>, PICK_VECTOR(eCurrentRace = TRIATHLON_RACE_IRONMAN, <<1591.6860, 3813.4014, 33.3371>>, <<0,0,0>>)))
//IF IS_POINT_VISIBLE(vChairPos, 10.0, 150)
IF DOES_ENTITY_EXIST(pedStartPed)
SET_ENTITY_AS_MISSION_ENTITY(pedStartPed, TRUE, TRUE)
ENDIF
IF DOES_ENTITY_EXIST(oClipboard)
SET_ENTITY_AS_MISSION_ENTITY(oClipboard, TRUE, TRUE)
ENDIF
IF DOES_ENTITY_EXIST(oPencil)
SET_ENTITY_AS_MISSION_ENTITY(oPencil, TRUE, TRUE)
ENDIF
//ENDIF
sbiChair = ADD_SCENARIO_BLOCKING_AREA(<<vChairPos.x - 3.0, vChairPos.y - 3.0, vChairPos.z - 3.0>>, <<vChairPos.x + 3.0, vChairPos.y + 3.0, vChairPos.z + 3.0>>)
//Activate next race and make an autosave request
LAUNCHER_ACTIVATE_NEXT_RACE()
MAKE_AUTOSAVE_REQUEST()
ENDPROC
//SPECIAL FUNCTION TO PERFORM A TASK ONLY ONCE
//USED IN THIS CASE TO ACTIVATE THE NEXT RACE BLIP
FUNC BOOL PERFORM_ONE_TIME_TASK()
LAUNCHER_ACTIVATE_NEXT_RACE()
RETURN TRUE
ENDFUNC
/// PURPOSE:
/// This is called once when the launcher script terminates. Last chance to do any cleanup.
PROC LAUNCHER_CUSTOM_CLEANUP()
IF fFlatSquaredPlayerDistanceToLauncher > fLauncherShutdownDist*fLauncherShutdownDist
// SWITCH eCurrentRace
// CASE TRIATHLON_RACE_VESPUCCI
// IF IS_IPL_ACTIVE("AP1_04_TriAf01")
// REMOVE_IPL("AP1_04_TriAf01")
// ENDIF
// BREAK
// CASE TRIATHLON_RACE_ALAMO_SEA
// IF IS_IPL_ACTIVE("CS2_06_TriAf02")
// REMOVE_IPL("CS2_06_TriAf02")
// ENDIF
// BREAK
// CASE TRIATHLON_RACE_IRONMAN
// IF IS_IPL_ACTIVE("CS4_04_TriAf03")
// REMOVE_IPL("CS4_04_TriAf03")
// ENDIF
// BREAK
// ENDSWITCH
IF DOES_ENTITY_EXIST(oStartBanner)
DELETE_OBJECT(oStartBanner)
ENDIF
ENDIF
CLEANUP_MENU_ASSETS()
INT iNavAreaIter
REPEAT COUNT_OF(iNavBlockAreas) iNavAreaIter
IF DOES_NAVMESH_BLOCKING_OBJECT_EXIST(iNavBlockAreas[iNavAreaIter])
REMOVE_NAVMESH_BLOCKING_OBJECT(iNavBlockAreas[iNavAreaIter])
ENDIF
ENDREPEAT
REMOVE_SCENARIO_BLOCKING_AREA(sbiChair)
IF NOT bHintCamReady
STOP_GAMEPLAY_HINT()
bHintCamReady = TRUE
ENDIF
ENDPROC
// ====================================================
// E N D TRIATHLON LAUNCHER FUNCTIONS AND PROCEDURES
// ====================================================
USING "generic_launcher.sch"
/// CHANGELOG
///
/// 10/18/2011
/// - [CM] Removing all references to race ambient functionality.
///
/// 10/14/2011
/// - [CM] Started to fill out Ryan P's functions and procedures, and using
/// launcher_Offroad_Races.sc as a reference.
// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************
//
// END OF FILE - DO NOT ADD ANYTHING BELOW THIS BLOCK!
//
// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************