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

2678 lines
73 KiB
Scheme
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************
//
// SCRIPT NAME : SPTT_Helpers.sch
// AUTHOR : Nicholas Zippmann
// DESCRIPTION : Single Player Races - Helper procs/functions file
//
// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************
USING "event_public.sch"
USING "SPTT_Head.sch"
USING "lineactivation.sch" // Include this so it compiles in release, for using GET_OFFSET_FROM_COORD_IN_WORLD_COORDS
//USING "minigames_helpers.sch"
USING "script_camera.sch"
CHASE_HINT_CAM_STRUCT localChaseHintCamStruct
STRING spttFailString = "SPR_UI_FAILD"
STRING spttFailStrapline = "SPR_UI_FRETRY"
BOOL bMissedStuntGate
#IF NOT DEFINED(TASK_TRI_RACER_TO_FOLLOW_RACE_COURSE)
PROC TASK_TRI_RACER_TO_FOLLOW_RACE_COURSE(SPTT_RACE_STRUCT& Race, VECTOR vCurrentGatePos, INT iRacerIndex)
PRINTLN("[spr_helpers.sch->TASK_TRI_RACER_TO_FOLLOW_RACE_COURSE] Dummy procedure called.")
// Account for unreferenced variables.
Race.iGateCnt = Race.iGateCnt
vCurrentGatePos = vCurrentGatePos
iRacerIndex = iRacerIndex
ENDPROC
#ENDIF
ENUM SPTT_GENERAL_BITS
SPTT_SCORECARD_INIT = BIT0,
SPTT_SCORECARD_STREAMED = BIT1,
SPTT_PLAYED_STINGER = BIT2,
SPTT_FORCE_GATE_ACTIVATION = BIT3,
SPTT_FIRST_GATE_ACTIVATION = BIT4,
SPTT_PRINTED_IDLE_WARNING = BIT5,
SPTT_END_RETURN_TO_GAMPLAY_CAM = BIT6
ENDENUM
ENUM SPTT_COUNTDOWN_STAGE
SPTT_COUNTDOWN_STAGE_INIT,
SPTT_COUNTDOWN_RUN,
SPTT_COUNTDOWN_STAGE_WAIT
ENDENUM
/// PURPOSE: Bitfield enum for controlling help and objective prints
ENUM SPTT_HELP_AND_OBJECTIVES
SPTT_DIST_HELP = BIT0,
SPTT_DAMG_HELP = BIT1,
SPTT_WARN_HELP = BIT2,
SPTT_FAIL_HELP = BIT3,
SPTT_RETURN_WARN = BIT4,
SPTT_RETURN_FAIL = BIT5,
SPTT_RETURN_DES = BIT6,
SPTT_EXIT_WARN = BIT7,
SPTT_EXIT_FAIL = BIT8,
SPTT_EXIT_FAIL2 = BIT9,
SPTT_TXIT_WARN = BIT10,
SPTT_TXIT_FAIL = BIT11,
SPTT_MOVE_WARN = BIT12,
SPTT_MOVE_FAIL = BIT13,
SPTT_HELP_WANT = BIT14
ENDENUM
//really should consolidate all of these bits into a single INT
ENUM SPTT_HELP
SPTT_RESET_HELP = BIT15,
SPTT_RESET_HELP1 = BIT16,
SPTT_RESET_INFO = BIT17,
SPTT_TIME_INFO = BIT18
ENDENUM
structTimer exitTimer
//structTimer waterTimer
structTimer idleTimer
structTimer ExitVehicleTimer
BOOL bTriMounted = FALSE
INT iSPRGeneralBits
INT SPTT_HELP_BIT
SPTT_HINT_CAM_STRUCT SPTT_HINT_CAM
ENUM ExitVehicleEnum
vehicleExited = BIT0
ENDENUM
COUNTDOWN_UI SPTT_CountDownUI
SPTT_COUNTDOWN_STAGE eCountdownStage = SPTT_COUNTDOWN_STAGE_INIT
STREAMVOL_ID iSPTTStream
// -----------------------------------
// GLOBAL PROCS/FUNCTIONS
// -----------------------------------
FUNC BOOL ORR_DOES_RACE_REQUIRE_MOTORCYCLE()
IF SPTT_Master.eRaceType != SPTT_RACE_TYPE_OFFROAD
RETURN FALSE
ENDIF
IF (SPTT_Master.iRaceCur = 1
OR SPTT_Master.iRaceCur = 4)
RETURN FALSE
ENDIF
RETURN TRUE
ENDFUNC
FUNC MODEL_NAMES ORR_GET_RANDOM_MOTORCYCLE_MODEL()
INT randInt = GET_RANDOM_INT_IN_RANGE(0, 10000) % 2
SWITCH (randInt)
CASE 0
RETURN A_M_Y_MOTOX_01
CASE 1
RETURN A_M_Y_MOTOX_02
DEFAULT
CDEBUG1LN(DEBUG_OR_RACES, "WARNING! Random motorcycle model returned default value")
RETURN A_M_Y_MOTOX_01
ENDSWITCH
ENDFUNC
PROC SPTT_LastTime_Set(INT iRace, FLOAT fLastTime)
SPTT_Master.fLastTime[iRace] = fLastTime
ENDPROC
FUNC INT SPTT_Global_BestRank_Get(INT iRace)
INT iBestRank = 0
iBestRank = g_savedGlobals.sSPTTData.iBestRank[iRace]
RETURN iBestRank
ENDFUNC
PROC SPTT_Global_BestRank_Set(INT iRace, INT iBestRank)
g_savedGlobals.sSPTTData.iBestRank[iRace] = iBestRank
ENDPROC
FUNC FLOAT SPTT_Global_BestTime_Get(INT iRace)
FLOAT fBestTime
fBestTime = g_savedGlobals.sSPTTData.fBestTime[iRace]
RETURN fBestTime
ENDFUNC
PROC SPTT_Global_BestTime_Set(INT iRace, FLOAT fBestTime)
g_savedGlobals.sSPTTData.fBestTime[iRace] = fBestTime
ENDPROC
// -----------------------------------
// DEBUG PROCS/FUNCTIONS
// -----------------------------------
PROC SPTT_Racer_DebugPrint(SPTT_RACER_STRUCT& Racer)
//DEBUG_MESSAGE("SPTT_Racer_DebugPrint")
PRINTSTRING("DRIVER: ")
PRINTINT(NATIVE_TO_INT(Racer.Driver))
PRINTSTRING(" ")
IF DOES_ENTITY_EXIST(Racer.Driver)
PRINTSTRING("DOES EXIST & ")
IF NOT IS_ENTITY_DEAD(Racer.Driver)
PRINTSTRING("IS ALIVE")
ELSE
PRINTSTRING("ISN'T ALIVE")
ENDIF
ELSE
PRINTSTRING("DOESN'T EXIST")
ENDIF
PRINTNL()
PRINTSTRING("VEHICLE: ")
PRINTINT(NATIVE_TO_INT(Racer.Vehicle))
PRINTSTRING(" ")
IF DOES_ENTITY_EXIST(Racer.Vehicle)
PRINTSTRING("DOES EXIST & ")
IF NOT IS_ENTITY_DEAD(Racer.Vehicle)
PRINTSTRING("IS ALIVE")
ELSE
PRINTSTRING("ISN'T ALIVE")
ENDIF
ELSE
PRINTSTRING("DOESN'T EXIST")
ENDIF
PRINTNL()
ENDPROC
// -----------------------------------
// SCENE PROCS/FUNCTIONS
// -----------------------------------
FUNC BOOL SPTT_FadeIn_Safe(INT iTime)
//DEBUG_MESSAGE("SPTT_FadeIn_Safe")
IF IS_SCREEN_FADED_OUT()
DO_SCREEN_FADE_IN(iTime)
ELIF IS_SCREEN_FADED_IN()
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL SPTT_FadeOut_Safe(INT iTime)
//DEBUG_MESSAGE("SPTT_FadeOut_Safe")
IF IS_SCREEN_FADED_IN()
DO_SCREEN_FADE_OUT(iTime)
ELIF IS_SCREEN_FADED_OUT()
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
// -----------------------------------
// MARKER PROCS/FUNCTIONS
// -----------------------------------
PROC SPTT_Blip_Destroy(BLIP_INDEX& Blip)
//DEBUG_MESSAGE("SPTT_Blip_Destroy")
IF DOES_BLIP_EXIST(Blip)
REMOVE_BLIP(Blip)
ENDIF
ENDPROC
FUNC BOOL SPTT_Blip_Coord_Create(BLIP_INDEX& Blip, VECTOR vPos, BLIP_SPRITE eBlipSprite = RADAR_TRACE_INVALID, FLOAT fScale = 1.0, INT iCurGate = -1, INT iNumGates = -1, SPTT_RACE_STUNT_GATE_ENUM eStuntType = SPTT_RACE_STUNT_GATE_NORMAL)
//DEBUG_MESSAGE("SPTT_Blip_Coord_Create")
SPTT_Blip_Destroy(Blip)
Blip = ADD_BLIP_FOR_COORD(vPos)
IF NOT DOES_BLIP_EXIST(Blip)
DEBUG_MESSAGE("SPTT_Blip_Coord_Create: Failed to create blip!")
RETURN FALSE
ENDIF
IF (eBlipSprite <> RADAR_TRACE_INVALID)
SET_BLIP_SPRITE(Blip, eBlipSprite)
ENDIF
SET_BLIP_SCALE(Blip, fScale)
SET_BLIP_DISPLAY(Blip, DISPLAY_BOTH)
// set knife gate blips to GREEN
IF (eStuntType = SPTT_RACE_STUNT_GATE_SIDE_LEFT) OR (eStuntType = SPTT_RACE_STUNT_GATE_SIDE_RIGHT)
SET_BLIP_COLOUR(Blip, BLIP_COLOUR_GREEN)
ENDIF
// set inverted gate blips to BLUE
IF (eStuntType = SPTT_RACE_STUNT_GATE_INVERTED)
SET_BLIP_COLOUR(Blip, BLIP_COLOUR_BLUE)
ENDIF
IF iCurGate = iNumGates-1
BEGIN_TEXT_COMMAND_SET_BLIP_NAME("GATEBLIPFIN")
END_TEXT_COMMAND_SET_BLIP_NAME(Blip)
// BEGIN_TEXT_COMMAND_SET_BLIP_NAME("GATEBLIP")
// ADD_TEXT_COMPONENT_INTEGER(iCurGate)
// ADD_TEXT_COMPONENT_INTEGER(iNumGates)
// END_TEXT_COMMAND_SET_BLIP_NAME(Blip)
ELSE
IF (eStuntType = SPTT_RACE_STUNT_GATE_INVERTED)
BEGIN_TEXT_COMMAND_SET_BLIP_NAME("GATEBLIPINV")
ELIF (eStuntType = SPTT_RACE_STUNT_GATE_SIDE_LEFT)
OR (eStuntType = SPTT_RACE_STUNT_GATE_SIDE_RIGHT)
BEGIN_TEXT_COMMAND_SET_BLIP_NAME("GATEBLIPKNF")
ELSE
BEGIN_TEXT_COMMAND_SET_BLIP_NAME("GATEBLIPDEF")
ENDIF
END_TEXT_COMMAND_SET_BLIP_NAME(Blip)
ENDIF
//
// IF iCurGate != -1
// AND iNumGates != -1
// BEGIN_TEXT_COMMAND_SET_BLIP_NAME("GATEBLIP")
// ADD_TEXT_COMPONENT_INTEGER(iCurGate)
// ADD_TEXT_COMPONENT_INTEGER(iNumGates)
// END_TEXT_COMMAND_SET_BLIP_NAME(Blip)
// ELSE
// SET_BLIP_NAME_FROM_TEXT_FILE(Blip, "GATEBLIPDEF")
// ENDIF
RETURN TRUE
ENDFUNC
FUNC BOOL SPTT_Blip_Entity_Create(BLIP_INDEX& Blip, ENTITY_INDEX Entity, BOOL bFriendly = TRUE, FLOAT fScale = 1.0)
//DEBUG_MESSAGE("SPTT_Blip_Entity_Create")
SPTT_Blip_Destroy(Blip)
IF IS_ENTITY_DEAD(Entity)
DEBUG_MESSAGE("SPTT_Blip_Entity_Create: Entity is not alive!")
RETURN FALSE
ENDIF
Blip = ADD_BLIP_FOR_ENTITY(Entity)
IF NOT DOES_BLIP_EXIST(Blip)
DEBUG_MESSAGE("SPTT_Blip_Entity_Create: Failed to create blip!")
RETURN FALSE
ENDIF
SET_BLIP_AS_FRIENDLY(Blip, bFriendly)
SET_BLIP_SCALE(Blip, fScale)
RETURN TRUE
ENDFUNC
PROC SPTT_Chkpnt_Destroy(CHECKPOINT_INDEX& Chkpnt)
//DEBUG_MESSAGE("SPTT_Chkpnt_Destroy")
IF (Chkpnt <> NULL)
DELETE_CHECKPOINT(Chkpnt)
Chkpnt = NULL
ENDIF
ENDPROC
PROC SPTT_Chkpnt_BeginFade(CHECKPOINT_INDEX& ChkpntToFade, CHECKPOINT_INDEX& FadeStorage, INT& iAlpha, BOOL bIsLastGate)
SPTT_Chkpnt_Destroy(FadeStorage)
IF (ChkpntToFade <> NULL)
FadeStorage = ChkpntToFade
ChkpntToFade = NULL
iAlpha = 255
IF bIsLastGate
iAlpha = 0
ENDIF
INT iRed, iGreen, iBlue
HUD_COLOURS eColor
IF bMissedStuntGate
eColor = HUD_COLOUR_RED
ELSE
eColor = HUD_COLOUR_WHITE
ENDIF
GET_RGB_FROM_INT(GET_INT_FROM_HUD_COLOUR(eColor), iRed, iGreen, iBlue, iAlpha)
SET_CHECKPOINT_RGBA(FadeStorage, iRed, iGreen, iBlue, iAlpha)
SET_CHECKPOINT_RGBA2(FadeStorage, iRed, iGreen, iBlue, iAlpha)
ENDIF
ENDPROC
FUNC CHECKPOINT_TYPE SPTT_Get_ChnkPnt_Type_From_SPTT_Type(SPTT_RACE_CHECKPOINT_TYPE eChkpntType, SPTT_RACE_STUNT_GATE_ENUM eStuntType)
SWITCH eChkpntType
CASE SPTT_CHKPT_OFFROAD_DEFAULT
RETURN CHECKPOINT_RACE_GROUND_CHEVRON_1
BREAK
CASE SPTT_CHKPT_OFFROAD_FINISH
RETURN CHECKPOINT_RACE_GROUND_FLAG
BREAK
CASE SPTT_CHKPT_STUNT_DEFAULT
RETURN CHECKPOINT_PLANE_FLAT
BREAK
CASE SPTT_CHKPT_STUNT_STUNT
If eStuntType = SPTT_RACE_STUNT_GATE_SIDE_LEFT
RETURN CHECKPOINT_PLANE_SIDE_L
ELIF eStuntType = SPTT_RACE_STUNT_GATE_SIDE_RIGHT
RETURN CHECKPOINT_PLANE_SIDE_R
ELIF eStuntType = SPTT_RACE_STUNT_GATE_INVERTED
RETURN CHECKPOINT_PLANE_INVERTED
ENDIF
BREAK
CASE SPTT_CHKPT_STUNT_FINISH
RETURN CHECKPOINT_RACE_AIR_FLAG
BREAK
CASE SPTT_CHKPT_TRI_SWIM
RETURN CHECKPOINT_RACE_TRI_SWIM_CHEVRON_1
BREAK
CASE SPTT_CHKPT_TRI_BIKE
RETURN CHECKPOINT_RACE_TRI_CYCLE_CHEVRON_1
BREAK
CASE SPTT_CHKPT_TRI_RUN
RETURN CHECKPOINT_RACE_TRI_RUN_CHEVRON_1
BREAK
CASE SPTT_CHKPT_TRI_FINISH
RETURN CHECKPOINT_RACE_TRI_RUN_FLAG
//RETURN CHECKPOINT_RACE_AIR_FLAG // Ideally, the top half of this checkpoint visually works as a finish line.
BREAK
CASE SPTT_CHKPT_TRI_FIRST_TRANS
RETURN CHECKPOINT_RACE_TRI_SWIM_FLAG
BREAK
CASE SPTT_CHKPT_TRI_SECOND_TRANS
RETURN CHECKPOINT_RACE_TRI_CYCLE_FLAG
BREAK
ENDSWITCH
RETURN CHECKPOINT_RACE_GROUND_CHEVRON_1
ENDFUNC
// Copied from SPTT_Gate.sch
FUNC BOOL SPTT_Helpers_Check_Condition_Flag(SPTT_GATE_STRUCT& sGate, ENUM_TO_INT iFlag)
RETURN IS_BITMASK_AS_ENUM_SET(sGate.iGateFlags, iFlag)
ENDFUNC
//******************************************************************************
//******************************************************************************
// Hint Cam Stuff
//******************************************************************************
//******************************************************************************
PROC SPTT_INIT_HINT_CAM()
SPTT_HINT_CAM.bActive = FALSE
SPTT_HINT_CAM.bQuickTapActivates = FALSE
// SPTT_HINT_CAM.Entity = NULL
SPTT_HINT_CAM.Coord = <<0,0,0>>
// SPTT_HINT_CAM.HintType =
SPTT_HINT_CAM.CustomCam = NULL
SPTT_HINT_CAM.fCamTimer = 0
ENDPROC
PROC SPTT_SET_HINT_CAM_ACTIVE(BOOL bActive)
// SPTT_HINT_CAM.bActive = bActive
SET_CINEMATIC_BUTTON_ACTIVE(!bActive)
ENDPROC
PROC SPTT_SET_HINT_CAM_COORD(VECTOR vThisEntity)
KILL_RACE_HINT_CAM(localChaseHintCamStruct)
SPTT_HINT_CAM.Coord = vThisEntity
ENDPROC
PROC SPTT_CLEAR_HINT_CAM_TARGET()
SPTT_HINT_CAM.Coord = <<0,0,0>>
ENDPROC
PROC SPTT_KILL_HINT_CAM()
SPTT_INIT_HINT_CAM()
SET_CINEMATIC_BUTTON_ACTIVE(TRUE)
ENDPROC
PROC SPTT_INCREASE_HINT_CAM_TIMER()
SPTT_HINT_CAM.fCamTimer += GET_FRAME_TIME()
ENDPROC
FUNC FLOAT SPTT_GET_HINT_CAM_TIMER()
RETURN SPTT_HINT_CAM.fCamTimer
ENDFUNC
PROC SPTT_RESET_HINT_CAM_TIMER()
SPTT_HINT_CAM.fCamTimer = 0
ENDPROC
FUNC BOOL SPTT_IS_HINT_CAM_BUTTON_PRESSED()
RETURN IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_VEH_CIN_CAM)// OR IS_CONTROL_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_CANCEL)//IS_BUTTON_PRESSED(PAD1, CIRCLE)
ENDFUNC
FUNC BOOL SPTT_IS_HINT_CAM_BUTTON_JUST_RELEASED()
RETURN IS_CONTROL_JUST_RELEASED(PLAYER_CONTROL, INPUT_VEH_CIN_CAM)
ENDFUNC
FUNC VECTOR SPTT_GET_NEXT_CHECKPOINT(SPTT_RACE_STRUCT &Race)
IF Race.Racer[0].iGateCur < SPTT_Master.iRaceCnt-1
RETURN Race.sGate[Race.Racer[0].iGateCur+1].vPos
ENDIF
RETURN <<0, 0, 0>>
ENDFUNC
FUNC BOOL SPTT_IS_POINT_TOO_CLOSE_TO_PLAYER(VECTOR vPos)
FLOAT fPlayerSpeed = GET_ENTITY_SPEED(PLAYER_PED_ID())
IF VDIST2(vPos, GET_PLAYER_COORDS(PLAYER_ID())) < (150.0 + fPlayerSpeed * fPlayerSpeed)
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
PROC SPTT_UPDATE_HINT_CAM(SPTT_RACE_STRUCT &Race)
IF SPTT_IS_HINT_CAM_BUTTON_PRESSED()
IF NOT SPTT_HINT_CAM.bActive
SPTT_HINT_CAM.bActive = TRUE
SPTT_HINT_CAM.bQuickTapActivates = TRUE
ELSE
SPTT_HINT_CAM.bQuickTapActivates = FALSE
ENDIF
ELIF SPTT_IS_HINT_CAM_BUTTON_JUST_RELEASED()
IF (NOT SPTT_HINT_CAM.bQuickTapActivates) OR SPTT_GET_HINT_CAM_TIMER() >= SPTT_HINT_CAM_TIMER_THRESHOLD
IF SPTT_HINT_CAM.bActive
SPTT_HINT_CAM.bActive = FALSE
ENDIF
ENDIF
ENDIF
IF SPTT_IS_HINT_CAM_BUTTON_JUST_RELEASED()
SPTT_INCREASE_HINT_CAM_TIMER()
ELSE
SPTT_RESET_HINT_CAM_TIMER()
ENDIF
IF SPTT_HINT_CAM.bActive
IF NOT IS_VECTOR_ZERO(SPTT_HINT_CAM.Coord) AND NOT SPTT_IS_POINT_TOO_CLOSE_TO_PLAYER(SPTT_HINT_CAM.Coord)
CONTROL_RACE_HINT_CAM(localChaseHintCamStruct, SPTT_HINT_CAM.Coord)
ELSE
IF DOES_CAM_EXIST(SPTT_HINT_CAM.CustomCam)
DESTROY_CAM(SPTT_HINT_CAM.CustomCam)
ENDIF
IF SPTT_IS_POINT_TOO_CLOSE_TO_PLAYER(SPTT_HINT_CAM.Coord)
SPTT_HINT_CAM.Coord = SPTT_GET_NEXT_CHECKPOINT(Race)
ENDIF
KILL_RACE_HINT_CAM(localChaseHintCamStruct)
SPTT_HINT_CAM.bActive = FALSE
ENDIF
ELSE
IF DOES_CAM_EXIST(SPTT_HINT_CAM.CustomCam)
DESTROY_CAM(SPTT_HINT_CAM.CustomCam)
ELSE
IF SPTT_IS_POINT_TOO_CLOSE_TO_PLAYER(SPTT_HINT_CAM.Coord)
SPTT_HINT_CAM.Coord = SPTT_GET_NEXT_CHECKPOINT(Race)
ENDIF
// PRINTLN("killing race cam")
KILL_RACE_HINT_CAM(localChaseHintCamStruct)
SPTT_HINT_CAM.bActive = FALSE
ENDIF
ENDIF
ENDPROC
/// PURPOSE: Works out which checkpoint type is needed based upon angle between checkpoints
FUNC CHECKPOINT_TYPE GET_CHEVRON_CHECKPOINT_TYPE(SPTT_RACE_CHECKPOINT_TYPE sprType, VECTOR pos3, VECTOR pos, VECTOR pos2)
VECTOR vec1, vec2
FLOAT fReturnAngle
FLOAT fChevron1 = 180.0
FLOAT fChevron2 = 140.0
FLOAT fChevron3 = 80.0
CHECKPOINT_TYPE Chevron1, Chevron2, Chevron3
IF sprType = SPTT_CHKPT_OFFROAD_DEFAULT
Chevron1 = CHECKPOINT_RACE_GROUND_CHEVRON_1
Chevron2 = CHECKPOINT_RACE_GROUND_CHEVRON_2
Chevron3 = CHECKPOINT_RACE_GROUND_CHEVRON_3
ELIF sprType = SPTT_CHKPT_STUNT_DEFAULT
Chevron1 = CHECKPOINT_RACE_AIR_CHEVRON_1
Chevron2 = CHECKPOINT_RACE_AIR_CHEVRON_2
Chevron3 = CHECKPOINT_RACE_AIR_CHEVRON_3
ELIF sprType = SPTT_CHKPT_TRI_SWIM
Chevron1 = CHECKPOINT_RACE_TRI_SWIM_CHEVRON_1
Chevron2 = CHECKPOINT_RACE_TRI_SWIM_CHEVRON_2
Chevron3 = CHECKPOINT_RACE_TRI_SWIM_CHEVRON_3
ELIF sprType = SPTT_CHKPT_TRI_BIKE
Chevron1 = CHECKPOINT_RACE_TRI_CYCLE_CHEVRON_1
Chevron2 = CHECKPOINT_RACE_TRI_CYCLE_CHEVRON_2
Chevron3 = CHECKPOINT_RACE_TRI_CYCLE_CHEVRON_3
ELIF sprType = SPTT_CHKPT_TRI_RUN
Chevron1 = CHECKPOINT_RACE_TRI_RUN_CHEVRON_1
Chevron2 = CHECKPOINT_RACE_TRI_RUN_CHEVRON_2
Chevron3 = CHECKPOINT_RACE_TRI_RUN_CHEVRON_3
ENDIF
IF NOT ARE_VECTORS_EQUAL(pos3, <<0,0,0>>)//if not first checkpoint
vec1 = pos3 - pos
vec2 = pos2 - pos
fReturnAngle = GET_ANGLE_BETWEEN_2D_VECTORS(vec1.x, vec1.y, vec2.x, vec2.y)
IF fReturnAngle > 180
fReturnAngle = (360.0 - fReturnAngle)
ENDIF
IF fReturnAngle < fChevron3
RETURN Chevron3
ELIF fReturnAngle < fChevron2
RETURN Chevron2
ELIF fReturnAngle < fChevron1
RETURN Chevron1
ENDIF
ENDIF
RETURN Chevron1
ENDFUNC
//FUNC BOOL SPTT_Chkpnt_Create(CHECKPOINT_INDEX& Chkpnt, SPTT_RACE_CHECKPOINT_TYPE ChkpntType, VECTOR vPos, VECTOR vPointAt, FLOAT fScale = SPTT_GATE_CHKPNT_SCL)
FUNC BOOL SPTT_Chkpnt_Create(VECTOR vPrevGate, SPTT_GATE_STRUCT& sGate, VECTOR vPointAt, FLOAT fScale = SPTT_GATE_CHKPNT_SCL)
//DEBUG_MESSAGE("SPTT_Chkpnt_Create")
vPrevGate = vPrevGate
CHECKPOINT_TYPE curCheckpointType
SPTT_Chkpnt_Destroy(sGate.Chkpnt)
INT iRed, iGreen, iBlue, iAlpha
IF sGate.eChkpntType = SPTT_CHKPT_STUNT_DEFAULT
// draw normal checkpoint
curCheckpointType = GET_CHEVRON_CHECKPOINT_TYPE(sGate.eChkpntType, vPrevGate, sGate.vPos, vPointAt)
GET_RGB_FROM_INT(GET_INT_FROM_HUD_COLOUR(MG_GET_RACE_CHECKPOINT_DEFAULT_COLOUR()), iRed, iGreen, iBlue, iAlpha)
sGate.Chkpnt = CREATE_CHECKPOINT(curCheckpointType, sGate.vPos, vPointAt, fScale, iRed, iGreen, iBlue, MG_GET_CHECKPOINT_ALPHA(sGate.vPos))
ELIF (sGate.eChkpntType = SPTT_CHKPT_STUNT_STUNT)
IF (sGate.eStuntType = SPTT_RACE_STUNT_GATE_SIDE_LEFT) OR (sGate.eStuntType = SPTT_RACE_STUNT_GATE_SIDE_RIGHT)
// draw green checkpoint for Knife gates
GET_RGB_FROM_INT(GET_INT_FROM_HUD_COLOUR(HUD_COLOUR_GREEN), iRed, iGreen, iBlue, iAlpha)
sGate.Chkpnt = CREATE_CHECKPOINT(SPTT_Get_ChnkPnt_Type_From_SPTT_Type(sGate.eChkpntType, sGate.eStuntType), sGate.vPos, vPointAt, fScale, iRed, iGreen, iBlue, MG_GET_CHECKPOINT_ALPHA(sGate.vPos))
ELIF (sGate.eStuntType = SPTT_RACE_STUNT_GATE_INVERTED)
// draw blue checkpoint for inverted gates
GET_RGB_FROM_INT(GET_INT_FROM_HUD_COLOUR(HUD_COLOUR_BLUE), iRed, iGreen, iBlue, iAlpha)
sGate.Chkpnt = CREATE_CHECKPOINT(SPTT_Get_ChnkPnt_Type_From_SPTT_Type(sGate.eChkpntType, sGate.eStuntType), sGate.vPos, vPointAt, fScale, iRed, iGreen, iBlue, MG_GET_CHECKPOINT_ALPHA(sGate.vPos))
ENDIF
ELSE
sGate.Chkpnt = CREATE_CHECKPOINT(SPTT_Get_ChnkPnt_Type_From_SPTT_Type(sGate.eChkpntType, sGate.eStuntType), sGate.vPos, vPointAt, fScale, 254, 207, 12, MG_GET_CHECKPOINT_ALPHA(sGate.vPos))
ENDIF
IF (sGate.Chkpnt = NULL)
DEBUG_MESSAGE("SPTT_Chkpnt_Create: Failed to create checkpoint!")
RETURN FALSE
ENDIF
RETURN TRUE
ENDFUNC
PROC Remove_Reset_UI()
// REMOVE_MINIGAME_INSTRUCTION(SPTT_Master.uiInput, ICON_UP)
ENDPROC
PROC SPTT_RESET_DO_VEHICLE_CHECKS(SPTT_RACE_STRUCT& Race)
INT iVehHealth, iEngHealth
iVehHealth = GET_ENTITY_HEALTH(Race.Racer[0].Vehicle)
IF NOT IS_ENTITY_DEAD(Race.Racer[0].Vehicle)
iEngHealth = ROUND(GET_VEHICLE_ENGINE_HEALTH(Race.Racer[0].Vehicle))
ENDIF
// health check
IF iVehHealth < 500.0
IF (SPTT_Master.eRaceType = SPTT_RACE_TYPE_TRIATHLON)
IF NOT IS_ENTITY_DEAD(Race.Racer[0].Vehicle)
AND NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), Race.Racer[0].Vehicle)
bTriMounted = TRUE
ENDIF
ENDIF
IF bTriMounted
IF (Race.sGate[Race.Racer[0].iGateCur].eChkpntType = SPTT_CHKPT_TRI_BIKE) OR (Race.sGate[Race.Racer[0].iGateCur].eChkpntType = SPTT_CHKPT_TRI_SECOND_TRANS)
IF NOT IS_MESSAGE_BEING_DISPLAYED()
PRINT_NOW_ONCE("SPR_HELP_DAMG", 5000, 0, SPTT_HELP_BIT, SPTT_DAMG_HELP)
ENDIF
ENDIF
ENDIF
ELSE
// nuke all existing messages and conversations before displaying vehicle health prompt
IF IS_MESSAGE_BEING_DISPLAYED()
CLEAR_PRINTS()
ENDIF
PRINT_NOW_ONCE("SPR_HELP_DAMG", 5000, 0, SPTT_HELP_BIT, SPTT_DAMG_HELP)
ENDIF
ENDIF
IF (SPTT_Master.eRaceType = SPTT_RACE_TYPE_OFFROAD)
IF iEngHealth < 200.0
DEBUG_MESSAGE("Player Vehicle Engine health is too low, prompt to reset")
// nuke all existing messages and conversations before displaying vehicle health prompt
IF IS_MESSAGE_BEING_DISPLAYED()
CLEAR_PRINTS()
ENDIF
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
KILL_ANY_CONVERSATION()
ENDIF
PRINT_NOW_ONCE("SPR_HELP_DAMG", 5000, 0, SPTT_HELP_BIT, SPTT_DAMG_HELP)
ENDIF
ENDIF
ENDPROC
PROC SPTT_RESET_DO_DISTANCE_TO_RACE_LINE_CHECKS(SPTT_RACE_STRUCT& Race)
VECTOR vCurGatePos, vPrevGatePos
vCurGatePos = Race.sGate[Race.Racer[0].iGateCur].vPos
IF (Race.Racer[0].iGateCur > 0)
vPrevGatePos = Race.sGate[Race.Racer[0].iGateCur-1].vPos
ELSE
vPrevGatePos = <<0,0,0>>
ENDIF
// Check distance between race start and first gate
FLOAT fWarnDist = GET_DISTANCE_BETWEEN_COORDS(vCurGatePos, vPrevGatePos)
FLOAT fFailDist = fWarnDist
IF (Race.Racer[0].iGateCur = 0) // at start of race
fWarnDist += 200.0
fFailDist += 750.0
ELSE
fWarnDist += 200.0
fFailDist += 750.0
ENDIF
VECTOR vPlayerPosition = GET_ENTITY_COORDS(Race.Racer[0].Driver)
VECTOR vNearestPos
IF ARE_VECTORS_ALMOST_EQUAL(vPrevGatePos, <<0,0,0>>)
vNearestPos = vCurGatePos
ELSE
vNearestPos = GET_CLOSEST_POINT_ON_LINE(vPlayerPosition, vPrevGatePos, vCurGatePos)
ENDIF
FLOAT fPlayerDistance = GET_DISTANCE_BETWEEN_COORDS(vNearestPos, vPlayerPosition)
BOOL bWarningDist = (fPlayerDistance >= fWarnDist)
BOOL bFailureDist = (fPlayerDistance >= fFailDist)
IF (SPTT_Master.eRaceType = SPTT_RACE_TYPE_OFFROAD)
IF ABSF(vNearestPos.z-vPlayerPosition.z) > 15.0 //291946 - Canyon Cliff race Not informed on how to reposition on falling off cliff
bWarningDist = TRUE
ENDIF
ENDIF
// Act on failure distance
IF bFailureDist
PRINTLN("Player has gone too far from race, going to FAIL OVER")
RESTART_TIMER_NOW(exitTimer)
Race.bFailChecking = FALSE
PRINTLN("RESET_TUTORIAL: Race.bFailChecking set to FALSE")
CLEAR_PRINTS()
SET_MINIGAME_SPLASH_SHOWING(TRUE)
Race.Racer[0].eReset = SPTT_RACER_RESET_FAIL_OVER
INIT_SIMPLE_USE_CONTEXT(SPTT_Master.uiInput, FALSE, FALSE, TRUE, TRUE)
ADD_SIMPLE_USE_CONTEXT_INPUT(SPTT_Master.uiInput, "IB_RETRY", FRONTEND_CONTROL, INPUT_FRONTEND_ACCEPT)
ADD_SIMPLE_USE_CONTEXT_INPUT(SPTT_Master.uiInput, "FE_HLP16", FRONTEND_CONTROL, INPUT_FRONTEND_CANCEL)
TRIGGER_MUSIC_EVENT("MGSP_FAIL")
spttFailStrapline = "SPR_HELP_FAIL"
ELSE
// Act on warning distance
IF bWarningDist
IF fPlayerDistance <= (fFailDist - 15) //make sure we're a good distance away so we dont stack msgs
PRINT_HELP("SPR_HELP_RESET")
ENDIF
IF fPlayerDistance <= (fFailDist - 15) //make sure we're a good distance away so we dont stack msgs
PRINT_NOW_ONCE("SPR_HELP_WARN", 5000, 0, SPTT_HELP_BIT, SPTT_WARN_HELP)
ENDIF
ELSE
CLEAR_THIS_PRINT("SPR_HELP_WARN")
IF IS_BITMASK_AS_ENUM_SET(SPTT_HELP_BIT, SPTT_WARN_HELP)
CLEAR_BITMASK_AS_ENUM(SPTT_HELP_BIT, SPTT_WARN_HELP)
DEBUG_MESSAGE("RESET TUTORIAL: Clearing global WARN DIST BIT")
ENDIF
ENDIF
ENDIF
ENDPROC
// ----------------------------------
// RESET TUTORIAL // FAIL CASE
// ----------------------------------
PROC RESET_TUTORIAL(SPTT_RACE_STRUCT& Race)
IF Race.bFailChecking
SPTT_RESET_DO_DISTANCE_TO_RACE_LINE_CHECKS(Race)
SPTT_RESET_DO_VEHICLE_CHECKS(Race)
ENDIF
ENDPROC
// EXIT VEHICLE FAILURE
PROC EXIT_VEHICLE_FAILURE(SPTT_RACE_STRUCT& Race, BLIP_INDEX& returnToVehBlip)
IF (SPTT_Master.eRaceType = SPTT_RACE_TYPE_PLANE)
IF NOT IS_ENTITY_DEAD(Race.Racer[0].Vehicle)
IF NOT IS_PED_SITTING_IN_ANY_VEHICLE(PLAYER_PED_ID())
// IF NOT DOES_BLIP_EXIST(returnToVehBlip)
// IF DOES_ENTITY_EXIST(Race.Racer[0].Vehicle)
// returnToVehBlip = ADD_BLIP_FOR_ENTITY(Race.Racer[0].Vehicle)
// SET_BLIP_COLOUR(returnToVehBlip, BLIP_COLOUR_BLUE)
// ELSE
// IF DOES_BLIP_EXIST(returnToVehBlip)
// REMOVE_BLIP(returnToVehBlip)
// ENDIF
// ENDIF
// ENDIF
// IF NOT IS_TIMER_STARTED(ExitVehicleTimer)
// START_TIMER_AT(ExitVehicleTimer, 0)
//
// PRINT_NOW_ONCE("SPR_EXIT_FAIL", 5000, 0, SPR_HELP_BIT, SPR_EXIT_FAIL)
// SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
// ELSE
// IF (GET_TIMER_IN_SECONDS(ExitVehicleTimer) >= 10.0)
// PRINT_NOW_ONCE("SPR_EXIT_WARN", 10000, 0, SPR_HELP_BIT, SPR_EXIT_WARN)
// ENDIF
CLEAR_PRINTS()
STOP_SCRIPTED_CONVERSATION(FALSE)
// IF (GET_TIMER_IN_SECONDS(ExitVehicleTimer) >= 1.0) //25.0)
// SET_PLAYER_INVINCIBLE(PLAYER_ID(), FALSE)
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)//, SPC_ALLOW_PLAYER_DAMAGE)
IF DOES_BLIP_EXIST(returnToVehBlip)
REMOVE_BLIP(returnToVehBlip)
IF (Race.Racer[0].iGateCur <= Race.iGateCnt-1)
IF DOES_BLIP_EXIST(Race.sGate[Race.Racer[0].iGateCur].blip)
SET_BLIP_DISPLAY(Race.sGate[Race.Racer[0].iGateCur].blip, DISPLAY_NOTHING)
ENDIF
ENDIF
IF ((Race.Racer[0].iGateCur+1) <= (Race.iGateCnt-2))
IF DOES_BLIP_EXIST(Race.sGate[Race.Racer[0].iGateCur+1].blip)
SET_BLIP_DISPLAY(Race.sGate[Race.Racer[0].iGateCur+1].blip, DISPLAY_NOTHING)
ENDIF
ENDIF
ENDIF
// CANCEL_TIMER(ExitVehicleTimer)
// RESTART_TIMER_NOW(exitTimer)
Race.bFailChecking = FALSE
CLEAR_PRINTS()
spttFailStrapline = "SPR_RETR_DES"
MG_INIT_FAIL_FADE_EFFECT(SPTT_Master.failFadeEffect, TRUE)
//SET_SCALEFORM_BIG_MESSAGE(Race.bigMessageUI, spttFailString, spttFailStrapline, -1, HUD_COLOUR_RED, DEFAULT, TRUE, 0.15)
DEBUG_MESSAGE("EXIT_VEHICLE_FAILURE.3: Race.bFailChecking set to FALSE")
Race.Racer[0].eReset = SPTT_RACER_QUIT_FADE_OUT
// ENDIF
// ENDIF
ELSE
// IF DOES_BLIP_EXIST(returnToVehBlip)
// REMOVE_BLIP(returnToVehBlip)
// ENDIF
// CANCEL_TIMER(ExitVehicleTimer)
// IF IS_THIS_PRINT_BEING_DISPLAYED("SPR_EXIT_WARN")
// CLEAR_THIS_PRINT("SPR_EXIT_WARN")
// ENDIF
// IF IS_THIS_PRINT_BEING_DISPLAYED("SPR_EXIT_FAIL")
// CLEAR_THIS_PRINT("SPR_EXIT_FAIL")
// ENDIF
// IF IS_BITMASK_AS_ENUM_SET(SPR_HELP_BIT, SPTT_EXIT_WARN)
// CLEAR_BITMASK_AS_ENUM(SPR_HELP_BIT, SPTT_EXIT_WARN)
// ENDIF
// IF IS_BITMASK_AS_ENUM_SET(SPR_HELP_BIT, SPTT_EXIT_FAIL)
// CLEAR_BITMASK_AS_ENUM(SPR_HELP_BIT, SPTT_EXIT_FAIL)
// ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
// DEAD VEHICLE FAILURE
PROC Dead_Race_Vehicle(SPTT_RACE_STRUCT& Race, BLIP_INDEX& returnToVehBlip)
IF Race.bFailChecking
IF NOT IS_VEHICLE_DRIVEABLE(Race.Racer[0].Vehicle)
OR (GET_ENTITY_HEALTH(Race.Racer[0].Vehicle) < 5)
OR IS_PED_INJURED(PLAYER_PED_ID())
RESTART_TIMER_NOW(exitTimer)
IF DOES_BLIP_EXIST(returnToVehBlip)
REMOVE_BLIP(returnToVehBlip)
ENDIF
IF (Race.Racer[0].iGateCur <= Race.iGateCnt-1)
IF DOES_BLIP_EXIST(Race.sGate[Race.Racer[0].iGateCur].blip)
SET_BLIP_DISPLAY(Race.sGate[Race.Racer[0].iGateCur].blip, DISPLAY_NOTHING)
ENDIF
ENDIF
IF ((Race.Racer[0].iGateCur+1) <= (Race.iGateCnt-2))
IF DOES_BLIP_EXIST(Race.sGate[Race.Racer[0].iGateCur+1].blip)
SET_BLIP_DISPLAY(Race.sGate[Race.Racer[0].iGateCur+1].blip, DISPLAY_NOTHING)
ENDIF
ENDIF
DEBUG_MESSAGE("Dead_Race_Vehicle: Race.bFailChecking set to FALSE")
Race.bFailChecking = FALSE
CLEAR_PRINTS()
spttFailStrapline = "SPR_RETR_DES"
Race.Racer[0].eReset = SPTT_RACER_RESET_FAIL_OVER
ENDIF
EXIT //quit early in the case that we're playing stunt plane races
ENDIF
ENDPROC
/// PURPOSE:
/// Check if player vehicle has entered water, and reset player accordingly.
PROC waterFailure(SPTT_RACE_STRUCT& Race)
IF DOES_ENTITY_EXIST(Race.Racer[0].Vehicle)
IF IS_ENTITY_IN_WATER(Race.Racer[0].Vehicle)
spttFailStrapline = "SPR_RETR_DES"
Race.bFailChecking = FALSE
Race.Racer[0].eReset = SPTT_RACER_RESET_FAIL_OVER
// IF NOT IS_TIMER_STARTED(waterTimer)
// START_TIMER_NOW_SAFE(waterTimer)
// DEBUG_MESSAGE("Started water Timer")
// ELIF (GET_TIMER_IN_SECONDS(waterTimer) >= 0.75)
// RESTART_TIMER_NOW(waterTimer)
// RESTART_TIMER_NOW(exitTimer)
//
// DEBUG_MESSAGE("waterFailure: Race.bFailChecking set to FALSE")
//// DO_SCREEN_FADE_OUT(SPTT_FADE_QUICK_TIME)
//
// DEBUG_MESSAGE("Moving to SPTT_RACER_RESET_FADE_OUT")
// ENDIF
// ELIF IS_TIMER_STARTED(waterTimer)
// RESTART_TIMER_NOW(waterTimer)
ENDIF
ENDIF
ENDPROC
// NOT MOVING FAILURE
PROC idleFailure(SPTT_RACE_STRUCT& Race)
IF (GET_TIMER_IN_SECONDS(Race.tClock) > 15.0)
IF (GET_ENTITY_SPEED(Race.Racer[0].Vehicle) < 5.0)
IF NOT IS_TIMER_STARTED(idleTimer)
START_TIMER_NOW_SAFE(idleTimer)
ELSE
IF (GET_TIMER_IN_SECONDS(idleTimer) > 60.0)
DEBUG_MESSAGE("idleTimer over 30 failing due to idle")
PRINT_NOW_ONCE("SPR_MOVE_FAIL", 5000, 0, SPTT_HELP_BIT, SPTT_MOVE_FAIL)
IF (Race.Racer[0].iGateCur <= Race.iGateCnt-1)
IF DOES_BLIP_EXIST(Race.sGate[Race.Racer[0].iGateCur].blip)
SET_BLIP_DISPLAY(Race.sGate[Race.Racer[0].iGateCur].blip, DISPLAY_NOTHING)
ENDIF
ENDIF
IF ((Race.Racer[0].iGateCur+1) <= (Race.iGateCnt-2))
IF DOES_BLIP_EXIST(Race.sGate[Race.Racer[0].iGateCur+1].blip)
SET_BLIP_DISPLAY(Race.sGate[Race.Racer[0].iGateCur+1].blip, DISPLAY_NOTHING)
ENDIF
ENDIF
RESTART_TIMER_NOW(idleTimer)
RESTART_TIMER_NOW(exitTimer)
Race.bFailChecking = FALSE
DEBUG_MESSAGE("Idle Failure Race.bFailChecking set to FALSE")
CLEAR_PRINTS()
spttFailStrapline = "SPR_RETR_IDLE"
Race.Racer[0].eReset = SPTT_RACER_RESET_FAIL_OVER
ELIF GET_TIMER_IN_SECONDS(idleTimer) > 30
IF NOT IS_BITMASK_AS_ENUM_SET(iSPRGeneralBits, SPTT_PRINTED_IDLE_WARNING)
PRINT_HELP_ONCE("SPR_IDLE_WARN", iSPRGeneralBits, SPTT_PRINTED_IDLE_WARNING)
ENDIF
ENDIF
ENDIF
ELSE
IF IS_TIMER_STARTED(idleTimer)
CLEAR_BITMASK_AS_ENUM(iSPRGeneralBits, SPTT_PRINTED_IDLE_WARNING)
RESTART_TIMER_NOW(idleTimer)
ENDIF
ENDIF
ELSE
IF IS_TIMER_STARTED(idleTimer)
CLEAR_BITMASK_AS_ENUM(iSPRGeneralBits, SPTT_PRINTED_IDLE_WARNING)
RESTART_TIMER_NOW(idleTimer)
ENDIF
ENDIF
ENDPROC
// WANTED FAILURE
PROC wantedFailure()
// Failcheck for illegal stuffs
IF (GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0)
CLEAR_PLAYER_WANTED_LEVEL(PLAYER_ID())
ENDIF
ENDPROC
// -----------------------------------
// PLACEMENT PROCS/FUNCTIONS
// -----------------------------------
PROC SPTT_GetRelPos_Ground_Side(VECTOR& vRelPos, FLOAT fDist)
//DEBUG_MESSAGE("SPTT_GetRelPos_Ground_Side")
VECTOR vSide = <<1.0, 0.0, 0.0>>
vSide = vSide * fDist
vRelPos = vRelPos + vSide
ENDPROC
PROC SPTT_GetRelPos_Ground_Fwd(VECTOR& vRelPos, FLOAT fDist)
//DEBUG_MESSAGE("SPTT_GetRelPos_Ground_Fwd")
VECTOR vFwd = <<0.0, 1.0, 0.0>>
vFwd = vFwd * fDist
vRelPos = vRelPos + vFwd
ENDPROC
PROC SPTT_GetRelPos_Ground_Up(VECTOR& vRelPos, FLOAT fDist)
//DEBUG_MESSAGE("SPTT_GetRelPos_Ground_Up")
FLOAT fHeight = 0.0
IF NOT GET_GROUND_Z_FOR_3D_COORD(vRelPos, fHeight)
GET_WATER_HEIGHT_NO_WAVES(vRelPos, fHeight)
ENDIF
vRelPos.z -= fHeight
vRelPos.z += fDist
ENDPROC
PROC SPTT_GetRelPos_Entity_Side(ENTITY_INDEX Entity, VECTOR& vRelPos, FLOAT fDist, BOOL bAbsolute)
//DEBUG_MESSAGE("SPTT_GetRelPos_Entity_Side")
IF NOT IS_ENTITY_DEAD(Entity)
VECTOR vSide, vTmp1, vTmp2, vTmp3
GET_ENTITY_MATRIX(Entity, vTmp1, vSide, vTmp2, vTmp3)
IF bAbsolute
vRelPos.x = vTmp3.x
ENDIF
vSide = vSide * fDist
vRelPos = vRelPos + vSide
ENDIF
ENDPROC
PROC SPTT_GetRelPos_Entity_Fwd(ENTITY_INDEX Entity, VECTOR& vRelPos, FLOAT fDist, BOOL bAbsolute)
//DEBUG_MESSAGE("SPTT_GetRelPos_Entity_Fwd")
IF NOT IS_ENTITY_DEAD(Entity)
VECTOR vFwd, vTmp1, vTmp2, vTmp3
GET_ENTITY_MATRIX(Entity, vFwd, vTmp1, vTmp2, vTmp3)
IF bAbsolute
vRelPos.y = vTmp3.y
ENDIF
vFwd = vFwd * fDist
vRelPos = vRelPos + vFwd
ENDIF
ENDPROC
PROC SPTT_GetRelPos_Entity_Up(ENTITY_INDEX Entity, VECTOR& vRelPos, FLOAT fDist, BOOL bAbsolute)
//DEBUG_MESSAGE("SPTT_GetRelPos_Entity_Up")
IF NOT IS_ENTITY_DEAD(Entity)
VECTOR vUp, vTmp1, vTmp2, vTmp3
GET_ENTITY_MATRIX(Entity, vTmp1, vTmp2, vUp, vTmp3)
IF bAbsolute
vRelPos.z = vTmp3.z
ENDIF
vUp = vUp * fDist
vRelPos = vRelPos + vUp
ENDIF
ENDPROC
PROC SPTT_GetRelPos_Coord_Side(VECTOR vCoord1, VECTOR vCoord2, VECTOR& vRelPos, FLOAT fDist, BOOL bAbsolute)
//DEBUG_MESSAGE("SPTT_GetRelPos_Coord_Side")
IF bAbsolute
vRelPos.x = vCoord1.x
ENDIF
VECTOR vFwd = vCoord2 - vCoord1
VECTOR vUp = <<0.0, 0.0, 1.0>>
VECTOR vSide = CROSS_PRODUCT(vFwd, vUp)
vSide = NORMALISE_VECTOR(vSide)
vSide = vSide * fDist
vRelPos = vRelPos + vSide
ENDPROC
PROC SPTT_GetRelPos_Coord_Fwd(VECTOR vCoord1, VECTOR vCoord2, VECTOR& vRelPos, FLOAT fDist, BOOL bAbsolute)
//DEBUG_MESSAGE("SPTT_GetRelPos_Coord_Fwd")
IF bAbsolute
vRelPos.y = vCoord1.y
ENDIF
VECTOR vFwd = vCoord2 - vCoord1
vFwd = NORMALISE_VECTOR(vFwd)
vFwd = vFwd * fDist
vRelPos = vRelPos + vFwd
ENDPROC
PROC SPTT_GetRelPos_Coord_Up(VECTOR vCoord1, VECTOR& vRelPos, FLOAT fDist, BOOL bAbsolute)
//DEBUG_MESSAGE("SPTT_GetRelPos_Coord_Up")
IF bAbsolute
vRelPos.z = vCoord1.z
ENDIF
vRelPos.z += fDist
ENDPROC
// -----------------------------------
// HUD/UI PROCS/FUNCTIONS
// -----------------------------------
/// PURPOSE:
/// Displays the countdown at the start of the race.
///
/// PARAMS:
/// Display - Struct with a timer, and int and float counters.
/*PROC SPTT_Set_Countdown_Message()
IF nCountdownNumber > 0
BEGIN_SCALEFORM_MOVIE_METHOD(SPTT_COUNTDOWN_UI, "SET_MESSAGE")
BEGIN_TEXT_COMMAND_SCALEFORM_STRING("NUMBER")
ADD_TEXT_COMPONENT_INTEGER(nCountdownNumber)
END_TEXT_COMMAND_SCALEFORM_STRING()
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(252)
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(219)
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(78)
END_SCALEFORM_MOVIE_METHOD()
ELIF nCountdownNumber = 0
BEGIN_SCALEFORM_MOVIE_METHOD(SPTT_COUNTDOWN_UI, "SET_MESSAGE")
SCALEFORM_MOVIE_METHOD_ADD_PARAM_STRING("SPR_COUNT_GO")
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(127)
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(255)
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(0)
END_SCALEFORM_MOVIE_METHOD()
ENDIF
ENDPROC
*/
PROC SPTT_HUD_DISPLAY_COURSE_NAME()
TEXT_LABEL_23 temp
INT iCourseID = ENUM_TO_INT(g_current_selected_SPTT_Race)
UPDATE_MISSION_NAME_DISPLAYING(temp, FALSE, FALSE, FALSE, FALSE, iCourseID)
ENDPROC
/// PURPOSE:
/// Displays the countdown at the start of the race.
///
/// PARAMS:
/// Display - Struct with a timer, and int and float counters.
///
/// RETURNS:
/// BOOL - Countdown still displaying.
FUNC BOOL SPTT_Countdown_Display(SPTT_DISPLAY_STRUCT& Display)
SPTT_HUD_DISPLAY_COURSE_NAME()
SWITCH(eCountdownStage)
CASE SPTT_COUNTDOWN_STAGE_INIT
START_TIMER_NOW_SAFE(Display.tCnt)
SET_MINIGAME_COUNTDOWN_UI_NUMBER(SPTT_CountDownUI, 3)
eCountdownStage = SPTT_COUNTDOWN_RUN
BREAK
CASE SPTT_COUNTDOWN_RUN
IF TIMER_DO_WHEN_READY(Display.tCnt, 1)
UPDATE_MINIGAME_COUNTDOWN_UI(SPTT_CountDownUI)
eCountdownStage = SPTT_COUNTDOWN_STAGE_WAIT
ENDIF
BREAK
CASE SPTT_COUNTDOWN_STAGE_WAIT
IF UPDATE_MINIGAME_COUNTDOWN_UI(SPTT_CountDownUI, FALSE)
RETURN FALSE
ENDIF
BREAK
/* CASE SPTT_COUNTDOWN_STAGE_2
IF TIMER_DO_WHEN_READY(Display.tCnt, 2)
SPTT_Set_Countdown_Message(1)
eCountdownStage = SPTT_COUNTDOWN_STAGE_1
ENDIF
BREAK
CASE SPTT_COUNTDOWN_STAGE_1
IF TIMER_DO_WHEN_READY(Display.tCnt, 3)
SPTT_Set_Countdown_Message(0)
eCountdownStage = SPTT_COUNTDOWN_STAGE_GO
ENDIF
BREAK
CASE SPTT_COUNTDOWN_STAGE_GO
IF TIMER_DO_ONCE_WHEN_READY(Display.tCnt, 3.1)
// Countdown no longer being displayed.
RETURN FALSE
eCountdownStage = SPTT_COUNTDOWN_STAGE_WAIT
ENDIF
BREAK
*/ RETURN TRUE
ENDSWITCH
// DRAW_SCALEFORM_MOVIE(SPTT_COUNTDOWN_UI, 0.5, 0.5, 1.0, 1.0, 255, 255, 255, 100)
// Countdown still displaying.
RETURN TRUE
ENDFUNC
/*
FUNC BOOL DEPRECATED_SPTT_Countdown_Display(SPTT_DISPLAY_STRUCT& Display)
//DEBUG_MESSAGE("SPTT_Countdown_Display")
// If timer isn't started, play a sound and start it.
IF NOT IS_TIMER_STARTED(Display.tCnt)
PLAY_SOUND_FRONTEND(-1, "PHONE_GENERIC_KEY_01", "HUD_MINIGAME_SOUNDSET")
RESTART_TIMER_NOW(Display.tCnt)
// Otherwise, if ocunter > zero, display countdown (num) for proper amount of time.
ELIF (Display.iCnt > 0)
SET_TEXT_SCALE(SPTT_UI_CD_NUM_SCALE, SPTT_UI_CD_NUM_SCALE)
DISPLAY_TEXT_WITH_NUMBER(SPTT_UI_CD_NUM_POS_X, SPTT_UI_CD_NUM_POS_Y, "SPR_COUNT_NUM", Display.iCnt)
IF TIMER_DO_WHEN_READY(Display.tCnt, SPTT_UI_CD_NUM_TIME)
CANCEL_TIMER(Display.tCnt)
--Display.iCnt
ENDIF
// Otherwise, ocunter is zero, display countdown (go) for proper amount of time.
ELSE
//SET_TEXT_SCALE(SPTT_UI_CD_GO_SCALE, SPTT_UI_CD_GO_SCALE)
//DISPLAY_TEXT(SPTT_UI_CD_GO_POS_X, SPTT_UI_CD_GO_POS_Y, "SPR_COUNT_GO")
//IF TIMER_DO_WHEN_READY(Display.tCnt, SPTT_UI_CD_GO_TIME)
// CANCEL_TIMER(Display.tCnt)
RETURN FALSE
//ENDIF
ENDIF
// Countdown still displaying.
RETURN TRUE
ENDFUNC
*/
FUNC BOOL SPTT_Finish_Display(SPTT_DISPLAY_STRUCT& Display)
//DEBUG_MESSAGE("SPTT_Finish_Display")
IF NOT IS_TIMER_STARTED(Display.tCnt)
RESTART_TIMER_NOW(Display.tCnt) //not sure if timer is used elsewhereso keeping it here, prob safe to remove tho- SiM - 10/31/2011
ENDIF
MISSION_FLOW_PLAY_END_OF_MISSION_MUSIC(TRUE)
RETURN TRUE
ENDFUNC
PROC SPTT_Rank_Display(INT iRank, FLOAT fPosX, FLOAT fPosY, FLOAT fScale)
//DEBUG_MESSAGE("SPTT_Rank_Display")
TEXT_LABEL_15 szRank
SWITCH iRank
CASE 1
szRank = "SPR_PLACE_ST"
BREAK
CASE 2
szRank = "SPR_PLACE_ND"
BREAK
CASE 3
szRank = "SPR_PLACE_RD"
BREAK
DEFAULT
szRank = "SPR_PLACE_TH"
BREAK
ENDSWITCH
SET_TEXT_SCALE(fScale, fScale)
DISPLAY_TEXT_WITH_NUMBER(fPosX, fPosY, szRank, iRank)
ENDPROC
PROC SPTT_Clock_GetComponents(FLOAT fClock, INT& iMinutes, INT& iSeconds, INT& iMilliSecs)
//DEBUG_MESSAGE("SPTT_Clock_GetComponents")
// Get total milliseconds on clock.
INT iTotal = FLOOR(fClock * 100.0)*10
// Use millisecond total to get clock components (m/s/ms).
iMinutes = (iTotal / 1000) / 60
iSeconds = (iTotal - (iMinutes * 60 * 1000)) / 1000
iMilliSecs = (iTotal - ((iSeconds + (iMinutes * 60)) * 1000))
ENDPROC
FUNC TEXT_LABEL_15 SPTT_Clock_MakeString(FLOAT fClock, FLOAT& fPosX, FLOAT fScale, BOOL bDynamic)
//DEBUG_MESSAGE("SPTT_Clock_MakeString")
// Local variables.
TEXT_LABEL_15 szClock
INT iMinutes, iSeconds, iMilliSecs
FLOAT fNumWidth = SPTT_HUD_NUM_WIDTH * fScale
FLOAT fClnWidth = SPTT_HUD_CLN_WIDTH * fScale
// Get clock components (m/s/ms).
SPTT_Clock_GetComponents(fClock, iMinutes, iSeconds, iMilliSecs)
// Truncate milliseconds (dynamic - tenths, static - hundreths).
IF bDynamic
iMilliSecs /= 100
ELSE
iMilliSecs /= 10
ENDIF
// Assemble string from clock components (dynamic - #:##.#, static - ##:##.##).
IF (iMinutes < 10)
IF bDynamic
IF (iMinutes >= 1)
fPosX += fNumWidth
ENDIF
ELSE
szClock += "0"
ENDIF
ENDIF
IF (iMinutes < 1)
IF bDynamic
fPosX += fNumWidth
fPosX += fClnWidth
ELSE
szClock += "0:"
ENDIF
ELSE
szClock += iMinutes
szClock += ":"
ENDIF
IF (iSeconds < 10)
IF bDynamic
AND (iMinutes < 1)
fPosX += fNumWidth
ELSE
szClock += "0"
ENDIF
ENDIF
IF (iSeconds < 1)
IF bDynamic
AND (iMinutes < 1)
fPosX += fNumWidth
ELSE
szClock += "0"
ENDIF
ELSE
szClock += iSeconds
ENDIF
szClock += "."
szClock += iMilliSecs
IF NOT bDynamic
AND (iMilliSecs < 10)
szClock += "0"
ENDIF
// Return clock string.
RETURN szClock
ENDFUNC
PROC SPTT_Clock_Display(FLOAT fClock, FLOAT fPosX, FLOAT fPosY, FLOAT fScale, BOOL bDynamic)
//DEBUG_MESSAGE("SPTT_Clock_Display")
// Make clock string and offset position to accommodate format (dynamic/static).
SPTT_Clock_MakeString(fClock, fPosX, fScale, bDynamic) //still using for scale
// Display clock string at desired position/scale.
SET_TEXT_SCALE(fScale, fScale)
BEGIN_TEXT_COMMAND_DISPLAY_TEXT("STRING")
ADD_TEXT_COMPONENT_SUBSTRING_TIME(FLOOR(fClock*1000), TIME_FORMAT_MINUTES|TIME_FORMAT_SECONDS|TIME_FORMAT_MILLISECONDS)
END_TEXT_COMMAND_DISPLAY_TEXT(fPosX, fPosY)
ENDPROC
FUNC TEXT_LABEL_15 SPTT_PlusMinus_MakeString(FLOAT fPlusMinus, FLOAT& fPosX, FLOAT fScale, BOOL bPlusMinus)
//DEBUG_MESSAGE("SPTT_PlusMinus_MakeString")
// Local variables.
TEXT_LABEL_15 szPlusMinus
INT iMinutes, iSeconds, iMilliSecs
FLOAT fNumWidth = SPTT_HUD_NUM_WIDTH * fScale
FLOAT fClnWidth = SPTT_HUD_CLN_WIDTH * fScale
// Get clock components (m/s/ms).
SPTT_Clock_GetComponents(fPlusMinus, iMinutes, iSeconds, iMilliSecs)
// Truncate milliseconds (hundreths).
iMilliSecs /= 10
// Start string with a plus/minus accordingly.
IF bPlusMinus
szPlusMinus = "+"
fPosX -= (SPTT_HUD_PLS_WIDTH * fScale)
ELSE
szPlusMinus = "-"
fPosX -= (SPTT_HUD_MNS_WIDTH * fScale)
ENDIF
// Assemble string from clock components (plus - +##:##.##, minus - -##:##.##).
IF (iMinutes < 10)
IF (iMinutes >= 1)
fPosX += fNumWidth
ENDIF
ENDIF
IF (iMinutes < 1)
fPosX += fNumWidth
fPosX += fClnWidth
ELSE
szPlusMinus += iMinutes
szPlusMinus += ":"
ENDIF
IF (iSeconds < 10)
IF (iMinutes < 1)
fPosX += fNumWidth
ELSE
szPlusMinus += "0"
ENDIF
ENDIF
IF (iSeconds < 1)
IF (iMinutes < 1)
fPosX += fNumWidth
ELSE
szPlusMinus += "0"
ENDIF
ELSE
szPlusMinus += iSeconds
ENDIF
szPlusMinus += "."
szPlusMinus += iMilliSecs
IF (iMilliSecs < 10)
szPlusMinus += "0"
ENDIF
// Return plus/minus string.
RETURN szPlusMinus
ENDFUNC
PROC SPTT_RadarOverlay_Display(FLOAT fRacerRoll)
//DEBUG_MESSAGE("SPTT_RadarOverlay_Display")
// TODO: Ask Alwyn why this isn't drawing over HUD.
// Calculate radar overlay rotation using racer roll.
FLOAT fOverlayRot = fRacerRoll * SPTT_HUD_RADAR_ROT_SCL
// Display radar overlay (sprite).
DRAW_SPRITE("PilotSchool", "PlaneRadarOver",
SPTT_HUD_RADAR_POS_X, SPTT_HUD_RADAR_POS_Y,
SPTT_HUD_RADAR_WIDTH, SPTT_HUD_RADAR_HEIGHT,
fOverlayRot, 128, 255, 128, 128)
ENDPROC
PROC SPTT_ChkpntType_Populate(TEXT_LABEL_31& szChkpntType[])
//DEBUG_MESSAGE("SPTT_ChkpntType_Populate")
szChkpntType[0] = "Offroad Default"
szChkpntType[1] = "Offroad Finish"
szChkpntType[2] = "Stunt Plane Default"
szChkpntType[3] = "Stunt Plane Finish"
szChkpntType[4] = "Triathlon Swim"
szChkpntType[5] = "Triathlon Bike"
szChkpntType[6] = "Triathlon Run"
szChkpntType[7] = "Triathlon Finish"
szChkpntType[8] = "Triathlon Swim>Bike"
szChkpntType[9] = "Triathlon Bike>Run"
ENDPROC
FUNC SPTT_RACE_CHECKPOINT_TYPE SPTT_ChkpntType_GetEnum(INT iChkpntType)
//DEBUG_MESSAGE("SPTT_ChkpntType_GetEnum")
SPTT_RACE_CHECKPOINT_TYPE eChkpntType
SWITCH iChkpntType
// Ground Arrow.
CASE 0
eChkpntType = SPTT_CHKPT_OFFROAD_DEFAULT
BREAK
// Ground Flag.
CASE 1
eChkpntType = SPTT_CHKPT_OFFROAD_FINISH
BREAK
// Air Arrow.
CASE 2
eChkpntType = SPTT_CHKPT_STUNT_DEFAULT
BREAK
// Air Flag.
CASE 3
eChkpntType = SPTT_CHKPT_STUNT_FINISH
BREAK
// Water Arrow.
CASE 4
eChkpntType = SPTT_CHKPT_TRI_SWIM
BREAK
// Water Arrow.
CASE 5
eChkpntType = SPTT_CHKPT_TRI_BIKE
BREAK
// Water Arrow.
CASE 6
eChkpntType = SPTT_CHKPT_TRI_RUN
BREAK
// Water Flag.
CASE 7
eChkpntType = SPTT_CHKPT_TRI_FINISH
BREAK
CASE 8
eChkpntType = SPTT_CHKPT_TRI_FIRST_TRANS
BREAK
CASE 9
eChkpntType = SPTT_CHKPT_TRI_SECOND_TRANS
BREAK
ENDSWITCH
RETURN eChkpntType
ENDFUNC
FUNC INT SPTT_ChkpntType_GetIndex(SPTT_RACE_CHECKPOINT_TYPE eChkpntType)
//DEBUG_MESSAGE("SPTT_ChkpntType_GetIndex")
INT iChkpntType
SWITCH eChkpntType
// Ground Arrow.
CASE SPTT_CHKPT_OFFROAD_DEFAULT
iChkpntType = 0
BREAK
// Ground Flag.
CASE SPTT_CHKPT_OFFROAD_FINISH
iChkpntType = 1
BREAK
// Air Arrow.
CASE SPTT_CHKPT_STUNT_DEFAULT
iChkpntType = 2
BREAK
// Air Flag.
CASE SPTT_CHKPT_STUNT_FINISH
iChkpntType = 3
BREAK
// Water Arrow.
CASE SPTT_CHKPT_TRI_SWIM
iChkpntType = 4
BREAK
// Water Arrow.
CASE SPTT_CHKPT_TRI_BIKE
iChkpntType = 5
BREAK
// Water Arrow.
CASE SPTT_CHKPT_TRI_RUN
iChkpntType = 6
BREAK
// Water Flag.
CASE SPTT_CHKPT_TRI_FINISH
iChkpntType = 7
BREAK
// Water Flag.
CASE SPTT_CHKPT_TRI_FIRST_TRANS
iChkpntType = 8
BREAK
// Water Flag.
CASE SPTT_CHKPT_TRI_SECOND_TRANS
iChkpntType = 9
BREAK
ENDSWITCH
RETURN iChkpntType
ENDFUNC
FUNC TEXT_LABEL_31 SPTT_ChkpntType_GetString(SPTT_RACE_CHECKPOINT_TYPE eChkpntType)
//DEBUG_MESSAGE("SPTT_ChkpntType_GetString")
TEXT_LABEL_31 szChkpntType
SWITCH eChkpntType
// Ground Arrow.
CASE SPTT_CHKPT_OFFROAD_DEFAULT
szChkpntType = "SPTT_CHKPT_OFFROAD_DEFAULT"
BREAK
// Ground Flag.
CASE SPTT_CHKPT_OFFROAD_FINISH
szChkpntType = "SPTT_CHKPT_OFFROAD_FINISH"
BREAK
// Air Arrow.
CASE SPTT_CHKPT_STUNT_DEFAULT
szChkpntType = "SPTT_CHKPT_STUNT_DEFAULT"
BREAK
// Air Flag.
CASE SPTT_CHKPT_STUNT_FINISH
szChkpntType = "SPTT_CHKPT_STUNT_FINISH"
BREAK
// Water Arrow.
CASE SPTT_CHKPT_TRI_SWIM
szChkpntType = "SPTT_CHKPT_TRI_SWIM"
BREAK
// Water Flag.
CASE SPTT_CHKPT_TRI_BIKE
szChkpntType = "SPTT_CHKPT_TRI_BIKE"
BREAK
// Water Arrow.
CASE SPTT_CHKPT_TRI_RUN
szChkpntType = "SPTT_CHKPT_TRI_RUN"
BREAK
// Water Flag.
CASE SPTT_CHKPT_TRI_FINISH
szChkpntType = "SPTT_CHKPT_TRI_FINISH"
BREAK
// Water Flag.
CASE SPTT_CHKPT_TRI_FIRST_TRANS
szChkpntType = "SPTT_CHKPT_TRI_FIRST_TRANS"
BREAK
// Water Flag.
CASE SPTT_CHKPT_TRI_SECOND_TRANS
szChkpntType = "SPTT_CHKPT_TRI_SECOND_TRANS"
BREAK
ENDSWITCH
RETURN szChkpntType
ENDFUNC
PROC SPTT_DriverType_Populate(TEXT_LABEL_31& szDriverType[])
//DEBUG_MESSAGE("SPTT_DriverType_Populate")
szDriverType[0] = "Player"
szDriverType[1] = "AI Male"
szDriverType[2] = "AI Female"
szDriverType[3] = "Triathlon Male"
ENDPROC
FUNC PED_TYPE SPTT_DriverType_GetEnum(INT iDriverType)
//DEBUG_MESSAGE("SPTT_DriverType_GetEnum")
PED_TYPE eDriverType
SWITCH iDriverType
// Player.
CASE 0
eDriverType = PEDTYPE_PLAYER1
BREAK
// AI Male.
CASE 1
eDriverType = PEDTYPE_CIVMALE
BREAK
// AI Female.
CASE 2
eDriverType = PEDTYPE_CIVFEMALE
BREAK
ENDSWITCH
RETURN eDriverType
ENDFUNC
FUNC INT SPTT_DriverType_GetIndex(PED_TYPE eDriverType)
//DEBUG_MESSAGE("SPTT_DriverType_GetIndex")
INT iDriverType
SWITCH eDriverType
// Player.
CASE PEDTYPE_PLAYER1
iDriverType = 0
BREAK
// AI Male.
CASE PEDTYPE_CIVMALE
iDriverType = 1
BREAK
// AI Female.
CASE PEDTYPE_CIVFEMALE
iDriverType = 2
BREAK
ENDSWITCH
RETURN iDriverType
ENDFUNC
FUNC TEXT_LABEL_31 SPTT_DriverType_GetString(PED_TYPE eDriverType)
//DEBUG_MESSAGE("SPTT_DriverType_GetString")
TEXT_LABEL_31 szDriverType
SWITCH eDriverType
// Player.
CASE PEDTYPE_PLAYER1
szDriverType = "PEDTYPE_PLAYER1"
BREAK
// AI Male.
CASE PEDTYPE_CIVMALE
szDriverType = "PEDTYPE_CIVMALE"
BREAK
// AI Female.
CASE PEDTYPE_CIVFEMALE
szDriverType = "PEDTYPE_CIVFEMALE"
BREAK
ENDSWITCH
RETURN szDriverType
ENDFUNC
PROC SPTT_DriverModel_Populate(TEXT_LABEL_31& szDriverModel[])
//DEBUG_MESSAGE("SPTT_DriverModel_Populate")
szDriverModel[0] = "Player"
szDriverModel[1] = "AI Male"
szDriverModel[2] = "AI Female"
szDriverModel[3] = "Triathlon Male"
ENDPROC
FUNC MODEL_NAMES SPTT_DriverModel_GetEnum(INT iDriverModel)
//DEBUG_MESSAGE("SPTT_DriverModel_GetEnum")
MODEL_NAMES eDriverModel
SWITCH iDriverModel
// Player.
CASE 0
eDriverModel = PLAYER_ONE
BREAK
// AI Male.
CASE 1
eDriverModel = A_M_Y_GENSTREET_01
BREAK
// AI Female.
CASE 2
eDriverModel = A_F_Y_TOURIST_01
BREAK
// AI Female.
CASE 3
eDriverModel = A_M_Y_RoadCyc_01
BREAK
ENDSWITCH
RETURN eDriverModel
ENDFUNC
FUNC INT SPTT_DriverModel_GetIndex(MODEL_NAMES eDriverModel)
//DEBUG_MESSAGE("SPTT_DriverModel_GetIndex")
INT iDriverModel
SWITCH eDriverModel
// Player.
CASE PLAYER_ONE
iDriverModel = 0
BREAK
// AI Male.
CASE A_M_Y_GENSTREET_01
iDriverModel = 1
BREAK
// AI Female.
CASE A_F_Y_TOURIST_01
iDriverModel = 2
BREAK
// AI Female.
CASE A_M_Y_RoadCyc_01
iDriverModel = 3
BREAK
ENDSWITCH
RETURN iDriverModel
ENDFUNC
FUNC TEXT_LABEL_31 SPTT_DriverModel_GetString(MODEL_NAMES eDriverModel)
//DEBUG_MESSAGE("SPTT_DriverModel_GetString")
TEXT_LABEL_31 szDriverModel
SWITCH eDriverModel
// Player.
CASE PLAYER_ONE
szDriverModel = "PLAYER_ONE"
BREAK
// AI Male.
CASE A_M_Y_GENSTREET_01
szDriverModel = "A_M_Y_GENSTREET_01"
BREAK
// AI Female.
CASE A_F_Y_TOURIST_01
szDriverModel = "A_F_Y_TOURIST_01"
BREAK
// AI Female.
CASE A_M_Y_RoadCyc_01
szDriverModel = "A_M_Y_RoadCyc_01"
BREAK
ENDSWITCH
RETURN szDriverModel
ENDFUNC
PROC SPTT_VehicleModel_Populate(TEXT_LABEL_31& szVehicleModel[])
//DEBUG_MESSAGE("SPTT_VehicleModel_Populate")
szVehicleModel[0] = "Cheetah (Sport)"
szVehicleModel[1] = "Infernus (Sport)"
szVehicleModel[2] = "JB700 (Sport)"
szVehicleModel[3] = "Monroe (Sport)"
szVehicleModel[4] = "Ninef 1 (Sport)"
szVehicleModel[5] = "Ninef 2 (Sport)"
szVehicleModel[6] = "Rapid GT 1 (Sport)"
szVehicleModel[7] = "Rapid GT 2 (Sport)"
szVehicleModel[8] = "Z Type (Sport)"
szVehicleModel[9] = "Entity XF (Sport)"
szVehicleModel[10] = "BF Injection 1 (2-Door)"
szVehicleModel[11] = "Bison (2-Door)"
szVehicleModel[12] = "Dominator (2-Door)"
szVehicleModel[13] = "Feltzer 2010 (2-Door)"
szVehicleModel[14] = "Penumbra (2-Door)"
szVehicleModel[15] = "Phoenix (2-Door)"
szVehicleModel[16] = "Stinger (2-Door)"
szVehicleModel[17] = "Cargobob (Helicopter)"
szVehicleModel[18] = "Maverick (Helicopter)"
szVehicleModel[19] = "Picador (2-Door)"
szVehicleModel[20] = "Tornado (2-Door)"
szVehicleModel[21] = "Baller (4-Door)"
szVehicleModel[22] = "Dubsta 1 (4-Door)"
szVehicleModel[23] = "Dubsta 2 (4-Door)"
szVehicleModel[24] = "FQ2 (4-Door)"
szVehicleModel[25] = "Granger (4-Door)"
szVehicleModel[26] = "Mesa (4-Door)"
szVehicleModel[27] = "Radius (4-Door)"
szVehicleModel[28] = "Sadler (4-Door)"
szVehicleModel[29] = "Surfer 1 (4-Door)"
szVehicleModel[30] = "Surfer 2 (4-Door)"
szVehicleModel[31] = "BJXL (4-Door)"
szVehicleModel[32] = "Jackal (4-Door)"
szVehicleModel[33] = "Blazer (4-Wheeler)"
szVehicleModel[34] = "Hexer (Motorcycle)"
szVehicleModel[35] = "Vader 1 (Motorcycle)"
szVehicleModel[36] = "Vader 2 (Motorcycle)"
szVehicleModel[37] = "Sanchez (Dirtbike)"
szVehicleModel[38] = "Faggio (Moped)"
szVehicleModel[39] = "BMX (Bicycle)"
szVehicleModel[40] = "Scorcher (Bicycle)"
szVehicleModel[41] = "Skivvy 1 (Boat)" //deprecated!!!
szVehicleModel[42] = "Skivvy 2 (Boat)" //deprecated!!!
szVehicleModel[43] = "Seashark (Jetski)"
szVehicleModel[44] = "Cuban 800 (Plane)"
szVehicleModel[45] = "Stunt (Plane)"
szVehicleModel[46] = "Vulkan (Plane)"
szVehicleModel[47] = "On Foot (No Vehicle)"
ENDPROC
FUNC MODEL_NAMES SPTT_VehicleModel_GetEnum(INT iVehicleModel)
//DEBUG_MESSAGE("SPTT_VehicleModel_GetEnum")
MODEL_NAMES eVehicleModel
SWITCH iVehicleModel
// Cheetah (Sport).
CASE 0
eVehicleModel = CHEETAH
BREAK
// Infernus (Sport).
CASE 1
eVehicleModel = INFERNUS
BREAK
// JB700 (Sport).
CASE 2
eVehicleModel = JB700
BREAK
// Monroe (Sport).
CASE 3
eVehicleModel = MONROE
BREAK
// Ninef 1 (Sport).
CASE 4
eVehicleModel = NINEF
BREAK
// Ninef 2 (Sport).
CASE 5
eVehicleModel = NINEF2
BREAK
// Rapid GT 1 (Sport).
CASE 6
eVehicleModel = RAPIDGT
BREAK
// Rapid GT 2 (Sport).
CASE 7
eVehicleModel = RAPIDGT2
BREAK
// Z Type (Sport).
CASE 8
eVehicleModel = ZTYPE
BREAK
// Entity XF (Sport).
CASE 9
eVehicleModel = ENTITYXF
BREAK
// BF Injection 1 (2-Door).
CASE 10
eVehicleModel = BFINJECTION
BREAK
// Bison (2-Door).
CASE 11
eVehicleModel = BISON
BREAK
// Dominator (2-Door).
CASE 12
eVehicleModel = DOMINATOR
BREAK
// Feltzer 2010 (2-Door).
CASE 13
eVehicleModel = FELTZER2
BREAK
// Penumbra (2-Door).
CASE 14
eVehicleModel = PENUMBRA
BREAK
// Phoenix (2-Door).
CASE 15
eVehicleModel = PHOENIX
BREAK
// Stinger (2-Door).
CASE 16
eVehicleModel = STINGER
BREAK
// Maverick (Helicopter).
CASE 17
eVehicleModel = CARGOBOB
BREAK
// Cargobob (Helicopter).
CASE 18
eVehicleModel = MAVERICK
BREAK
// Picador (2-Door).
CASE 19
eVehicleModel = PICADOR
BREAK
// Tornado (2-Door).
CASE 20
eVehicleModel = TORNADO
BREAK
// Baller (4-Door).
CASE 21
eVehicleModel = BALLER
BREAK
// Dubsta 1 (4-Door).
CASE 22
eVehicleModel = DUBSTA
BREAK
// Dubsta 2 (4-Door).
CASE 23
eVehicleModel = DUBSTA2
BREAK
// FQ2 (4-Door).
CASE 24
eVehicleModel = FQ2
BREAK
// Granger (4-Door).
CASE 25
eVehicleModel = GRANGER
BREAK
// Mesa (4-Door).
CASE 26
eVehicleModel = MESA
BREAK
// Radius (4-Door).
CASE 27
eVehicleModel = RADI
BREAK
// Sadler (4-Door).
CASE 28
eVehicleModel = SADLER
BREAK
// Surfer 1 (4-Door).
CASE 29
eVehicleModel = SURFER
BREAK
// Surfer 2 (4-Door).
CASE 30
eVehicleModel = SURFER2
BREAK
// BJXL (4-Door).
CASE 31
eVehicleModel = BJXL
BREAK
// Jackal (4-Door).
CASE 32
eVehicleModel = JACKAL
BREAK
// Blazer (4-Wheeler).
CASE 33
eVehicleModel = BLAZER
BREAK
// Hexer (Motorcycle).
CASE 34
eVehicleModel = HEXER
BREAK
// Vader 1 (Motorcycle).
CASE 35
eVehicleModel = VADER
BREAK
// Vader 2 (Motorcycle).
CASE 36
eVehicleModel = VADER
BREAK
// Sanchez (Dirtbike).
CASE 37
eVehicleModel = SANCHEZ
BREAK
// Faggio (Moped).
CASE 38
eVehicleModel = FAGGIO2
BREAK
// BMX (Bicycle).
CASE 39
eVehicleModel = BMX
BREAK
// Scorcher (Bicycle).
CASE 40
eVehicleModel = SCORCHER
BREAK
// Seashark (Jetski).
CASE 43
eVehicleModel = SEASHARK
BREAK
// Cuban 800 (Plane).
CASE 44
eVehicleModel = CUBAN800
BREAK
// Stunt (Plane).
CASE 45
eVehicleModel = STUNT
BREAK
// On Foot (No Vehicle).
CASE 46
eVehicleModel = DUMMY_MODEL_FOR_SCRIPT
BREAK
ENDSWITCH
RETURN eVehicleModel
ENDFUNC
FUNC INT SPTT_VehicleModel_GetIndex(MODEL_NAMES eVehicleModel)
//DEBUG_MESSAGE("SPTT_VehicleModel_GetIndex")
INT iVehicleModel
SWITCH eVehicleModel
// Cheetah (Sport).
CASE CHEETAH
iVehicleModel = 0
BREAK
// Infernus (Sport).
CASE INFERNUS
iVehicleModel = 1
BREAK
// JB700 (Sport).
CASE JB700
iVehicleModel = 2
BREAK
// Monroe (Sport).
CASE MONROE
iVehicleModel = 3
BREAK
// Ninef 1 (Sport).
CASE NINEF
iVehicleModel = 4
BREAK
// Ninef 2 (Sport).
CASE NINEF2
iVehicleModel = 5
BREAK
// Rapid GT 1 (Sport).
CASE RAPIDGT
iVehicleModel = 6
BREAK
// Rapid GT 2 (Sport).
CASE RAPIDGT2
iVehicleModel = 7
BREAK
// Z Type (Sport).
CASE ZTYPE
iVehicleModel = 8
BREAK
// Entity XF (Sport).
CASE ENTITYXF
iVehicleModel = 9
BREAK
// BF Injection 1 (2-Door).
CASE BFINJECTION
iVehicleModel = 10
BREAK
// Bison (2-Door).
CASE BISON
iVehicleModel = 11
BREAK
// Dominator (2-Door).
CASE DOMINATOR
iVehicleModel = 12
BREAK
// Feltzer 2010 (2-Door).
CASE FELTZER2
iVehicleModel = 13
BREAK
// Penumbra (2-Door).
CASE PENUMBRA
iVehicleModel = 14
BREAK
// Phoenix (2-Door).
CASE PHOENIX
iVehicleModel = 15
BREAK
// Stinger (2-Door).
CASE STINGER
iVehicleModel = 16
BREAK
// Cargobob (Helicopter).
CASE CARGOBOB
iVehicleModel = 17
BREAK
// Maverick (Helicopter).
CASE MAVERICK
iVehicleModel = 18
BREAK
// Picador (2-Door).
CASE PICADOR
iVehicleModel = 19
BREAK
// Tornado (2-Door).
CASE TORNADO
iVehicleModel = 20
BREAK
// Baller (4-Door).
CASE BALLER
iVehicleModel = 21
BREAK
// Dubsta 1 (4-Door).
CASE DUBSTA
iVehicleModel = 22
BREAK
// Dubsta 2 (4-Door).
CASE DUBSTA2
iVehicleModel = 23
BREAK
// FQ2 (4-Door).
CASE FQ2
iVehicleModel = 24
BREAK
// Granger (4-Door).
CASE GRANGER
iVehicleModel = 25
BREAK
// Mesa (4-Door).
CASE MESA
iVehicleModel = 26
BREAK
// Radius (4-Door).
CASE RADI
iVehicleModel = 27
BREAK
// Sadler (4-Door).
CASE SADLER
iVehicleModel = 28
BREAK
// Surfer 1 (4-Door).
CASE SURFER
iVehicleModel = 29
BREAK
// Surfer 2 (4-Door).
CASE SURFER2
iVehicleModel = 30
BREAK
// BJXL (4-Door).
CASE BJXL
iVehicleModel = 31
BREAK
// Jackal (4-Door).
CASE JACKAL
iVehicleModel = 32
BREAK
// Blazer (4-Wheeler).
CASE BLAZER
iVehicleModel = 33
BREAK
// Hexer (Motorcycle).
CASE HEXER
iVehicleModel = 34
BREAK
// Vader 1 (Motorcycle).
CASE VADER
iVehicleModel = 35
BREAK
// Vader 2 (Motorcycle).
// CASE VADER2
// iVehicleModel = 36
// BREAK
// Sanchez (Dirtbike).
CASE SANCHEZ
iVehicleModel = 37
BREAK
// Faggio (Moped).
CASE FAGGIO2
iVehicleModel = 38
BREAK
// BMX (Bicycle).
CASE BMX
iVehicleModel = 39
BREAK
// Scorcher (Bicycle).
CASE SCORCHER
iVehicleModel = 40
BREAK
// Seashark (Jetski).
CASE SEASHARK
iVehicleModel = 43
BREAK
// Cuban 800 (Plane).
CASE CUBAN800
iVehicleModel = 44
BREAK
// Stunt (Plane).
CASE STUNT
iVehicleModel = 45
BREAK
// On Foot (No Vehicle).
CASE DUMMY_MODEL_FOR_SCRIPT
iVehicleModel = 46
BREAK
ENDSWITCH
RETURN iVehicleModel
ENDFUNC
FUNC TEXT_LABEL_31 SPTT_VehicleModel_GetString(MODEL_NAMES eVehicleModel)
//DEBUG_MESSAGE("SPTT_VehicleModel_GetString")
TEXT_LABEL_31 szVehicleModel
SWITCH eVehicleModel
// Cheetah (Sport).
CASE CHEETAH
szVehicleModel = "CHEETAH"
BREAK
// Infernus (Sport).
CASE INFERNUS
szVehicleModel = "INFERNUS"
BREAK
// JB700 (Sport).
CASE JB700
szVehicleModel = "JB700"
BREAK
// Monroe (Sport).
CASE MONROE
szVehicleModel = "MONROE"
BREAK
// Ninef 1 (Sport).
CASE NINEF
szVehicleModel = "NINEF"
BREAK
// Ninef 2 (Sport).
CASE NINEF2
szVehicleModel = "NINEF2"
BREAK
// Rapid GT 1 (Sport).
CASE RAPIDGT
szVehicleModel = "RAPIDGT"
BREAK
// Rapid GT 2 (Sport).
CASE RAPIDGT2
szVehicleModel = "RAPIDGT"//1624012
BREAK
// Z Type (Sport).
CASE ZTYPE
szVehicleModel = "ZTYPE"
BREAK
// Entity XF (Sport).
CASE ENTITYXF
szVehicleModel = "ENTITYXF"
BREAK
// BF Injection 1 (2-Door).
CASE BFINJECTION
szVehicleModel = "BFINJECTION"
BREAK
// Bison (2-Door).
CASE BISON
szVehicleModel = "BISON"
BREAK
// Dominator (2-Door).
CASE DOMINATOR
szVehicleModel = "DOMINATOR"
BREAK
// Penumbra (2-Door).
CASE PENUMBRA
szVehicleModel = "PENUMBRA"
BREAK
// Phoenix (2-Door).
CASE PHOENIX
szVehicleModel = "PHOENIX"
BREAK
// Stinger (2-Door).
CASE STINGER
szVehicleModel = "STINGER"
BREAK
// Cargobob (Helicopter).
CASE CARGOBOB
szVehicleModel = "CARGOBOB"
BREAK
// Maverick (Helicopter).
CASE MAVERICK
szVehicleModel = "MAVERICK"
BREAK
// Picador (2-Door).
CASE PICADOR
szVehicleModel = "PICADOR"
BREAK
// Tornado (2-Door).
CASE TORNADO
szVehicleModel = "TORNADO"
BREAK
// Baller (4-Door).
CASE BALLER
szVehicleModel = "BALLER"
BREAK
// Dubsta 1 (4-Door).
CASE DUBSTA
szVehicleModel = "DUBSTA"
BREAK
// Dubsta 2 (4-Door).
CASE DUBSTA2
szVehicleModel = "DUBSTA2"
BREAK
// FQ2 (4-Door).
CASE FQ2
szVehicleModel = "FQ2"
BREAK
// Granger (4-Door).
CASE GRANGER
szVehicleModel = "GRANGER"
BREAK
// Mesa (4-Door).
CASE MESA
szVehicleModel = "MESA"
BREAK
// Radius (4-Door).
CASE RADI
szVehicleModel = "RADI"
BREAK
// Sadler (4-Door).
CASE SADLER
szVehicleModel = "SADLER"
BREAK
// Surfer 1 (4-Door).
CASE SURFER
szVehicleModel = "SURFER"
BREAK
// Surfer 2 (4-Door).
CASE SURFER2
szVehicleModel = "SURFER2"
BREAK
// BJXL (4-Door).
CASE BJXL
szVehicleModel = "BJXL"
BREAK
// Jackal (4-Door).
CASE JACKAL
szVehicleModel = "JACKAL"
BREAK
// Blazer (4-Wheeler).
CASE BLAZER
szVehicleModel = "BLAZER"
BREAK
// Hexer (Motorcycle).
CASE HEXER
szVehicleModel = "HEXER"
BREAK
// Vader 1 (Motorcycle).
CASE VADER
szVehicleModel = "VADER"
BREAK
// Vader 2 (Motorcycle).
// CASE VADER2
// szVehicleModel = "VADER2"
// BREAK
// Sanchez (Dirtbike).
CASE SANCHEZ
szVehicleModel = "SANCHEZ"
BREAK
// Faggio (Moped).
CASE FAGGIO2
szVehicleModel = "FAGGIO2"
BREAK
// BMX (Bicycle).
CASE BMX
szVehicleModel = "BMX"
BREAK
// Scorcher (Bicycle).
CASE SCORCHER
szVehicleModel = "SCORCHER"
BREAK
// Seashark (Jetski).
CASE SEASHARK
szVehicleModel = "SEASHARK"
BREAK
// Cuban 800 (Plane).
CASE CUBAN800
szVehicleModel = "CUBAN800"
BREAK
// Stunt (Plane).
CASE STUNT
szVehicleModel = "STUNT"
BREAK
// On Foot (No Vehicle).
CASE DUMMY_MODEL_FOR_SCRIPT
szVehicleModel = "DUMMY_MODEL_FOR_SCRIPT"
BREAK
ENDSWITCH
RETURN szVehicleModel
ENDFUNC
// -----------------------------------
// MISC PROCS/FUNCTION
// -----------------------------------
// TODO: Organize these into proper categories.
FUNC TEXT_LABEL_31 SPTT_RacerName_GetString(INT nLookUp)
TEXT_LABEL_31 szRacerName
SWITCH (nLookUp)
CASE 0
szRacerName = "Michael Bagley"
BREAK
CASE 1
szRacerName = "Alan Blaine"
BREAK
CASE 2
szRacerName = "Chris Bourassa"
BREAK
CASE 3
szRacerName = "Jason Umbriet"
BREAK
CASE 4
szRacerName = "John Diaz"
BREAK
CASE 5
szRacerName = "Goeffry Show"
BREAK
CASE 6
szRacerName = "DJ Jones"
BREAK
CASE 7
szRacerName = "Ghyan Koehne"
BREAK
CASE 8
szRacerName = "Stevie Messinger"
BREAK
CASE 9
szRacerName = "Silas Morse"
BREAK
CASE 10
szRacerName = "Ryan Paradis"
BREAK
CASE 11
szRacerName = "Yomal Perera"
BREAK
CASE 12
szRacerName = "Troy Schram"
BREAK
CASE 13
szRacerName = "John Sripan"
BREAK
CASE 14
szRacerName = "David Stinchcomb"
BREAK
CASE 15
szRacerName = "Stephen Russo"
BREAK
CASE 16
szRacerName = "Adrian Castaneda"
BREAK
CASE 17
szRacerName = "David Kunkler"
BREAK
CASE 18
szRacerName = "Steve Martin"
BREAK
CASE 19
szRacerName = "John Ricchio"
BREAK
CASE 20
szRacerName = "Eric Smith"
BREAK
CASE 21
szRacerName = "Ted Carson"
BREAK
CASE 22
szRacerName = "Michael Currington"
BREAK
CASE 23
szRacerName = "Fredrik Farnstrom"
BREAK
CASE 24
szRacerName = "Andrew Gardner"
BREAK
CASE 25
szRacerName = "Alan Goykhman"
BREAK
CASE 26
szRacerName = "Jason Jurecka"
BREAK
CASE 27
szRacerName = "Jonathan Martin"
BREAK
CASE 28
szRacerName = "Bryan Musson"
BREAK
CASE 29
szRacerName = "Robert Percival"
BREAK
CASE 30
szRacerName = "C. Rakowsky"
BREAK
CASE 31
szRacerName = "Ryan Satrappe"
BREAK
CASE 32
szRacerName = "Tom Shepherd"
BREAK
CASE 33
szRacerName = "Aaron Robuck"
BREAK
DEFAULT
szRacerName = "Racer"
BREAK
ENDSWITCH
RETURN szRacerName
ENDFUNC
PROC SPTT_RacerName_Populate(TEXT_LABEL_31& szRacerName[])
INT i, j, iLimit
INT tempNumbers[10]
REPEAT COUNT_OF(szRacerName) i
//szRacerName[i] = SPTT_RacerName_GetString()
tempNumbers[i]=GET_RANDOM_INT_IN_RANGE(0, 34)
/*PRINTSTRING("Picking a random number for slot ")
PRINTINT(i)
PRINTNL()*/
IF (i > 0)
j = i - 1
iLimit = 0
WHILE (j >= 0)
/*PRINTINT(i)
PRINTSTRING(" value of ")
PRINTINT(tempNumbers[i])
PRINTSTRING(" vs. ")
PRINTINT(j)
PRINTSTRING(" value of ")
PRINTINT(tempNumbers[j])
PRINTNL()*/
IF tempNumbers[i] = tempNumbers[j] //ARE_STRINGS_EQUAL(szRacerName[i], szRacerName[j])
IF (iLimit < 100)
//szRacerName[i] = SPTT_RacerName_GetString()
tempNumbers[i]=GET_RANDOM_INT_IN_RANGE(0, 34)
++iLimit
ELSE
--j
ENDIF
ELSE
iLimit = 0
--j
ENDIF
ENDWHILE
ENDIF
ENDREPEAT
i=0
REPEAT COUNT_OF(szRacerName) i
szRacerName[i]=SPTT_RacerName_GetString(tempNumbers[i])
ENDREPEAT
ENDPROC
FUNC TEXT_LABEL SPTT_Race_Racer_Format_Time(FLOAT fUnformattedTime)
TEXT_LABEL sFormattedTime = "0:00\:000"
INT iNumMinutes = 0
INT iNumSeconds = 0
INT iNumMilliSeconds = 0
FLOAT fMilliseconds = 0
WHILE fUnformattedTime >= 60.0
iNumMinutes++
fUnformattedTime -= 60.0
ENDWHILE
iNumSeconds = FLOOR(fUnformattedTime)
fMilliseconds = (fUnformattedTime - iNumSeconds)*1000
iNumMilliSeconds = FLOOR(fMilliseconds)
sFormattedTime = iNumMinutes
sFormattedTime += "'"
IF iNumSeconds < 10
sFormattedTime += "0"
ENDIF
sFormattedTime += iNumSeconds
sFormattedTime += "\""
sFormattedTime += iNumMilliSeconds
RETURN sFormattedTime
ENDFUNC
PROC SPTT_Race_Racer_Update_Rubberband_Speed(SPTT_RACE_STRUCT& Race, INT iRacerIndex)
IF iRacerIndex < 0
OR iRacerIndex > COUNT_OF(Race.Racer)
DEBUG_MESSAGE("SPTT_Race_Racer_Update_Rubberband_Cruise_Speed: Bad racer index!")
EXIT
ENDIF
IF NOT IS_ENTITY_DEAD(Race.Racer[iRacerIndex].Driver)
IF NOT IS_ENTITY_DEAD(Race.Racer[iRacerIndex].Vehicle)
IF IS_PED_IN_VEHICLE(Race.Racer[iRacerIndex].Driver, Race.Racer[iRacerIndex].Vehicle)
FLOAT aiSpeed = GET_VEHICLE_ESTIMATED_MAX_SPEED(Race.Racer[iRacerIndex].Vehicle) // TO_FLOAT(GET_RANDOM_INT_IN_RANGE(60,80))
IF Race.Racer[0].iGateCur = Race.Racer[iRacerIndex].iGateCur
// PRINTSTRING("racer is on same gate as player, keep speed the same")
ELIF Race.Racer[iRacerIndex].iGateCur > Race.Racer[0].iGateCur //ai is too far ahead lets slow them down
aiSpeed*=0.69
// PRINTSTRING("racer is ahead of player, reducing speed")
ELSE
aiSpeed*=1.0
// PRINTSTRING("racer is behind player, setting to 1.25 max vehicle speed")
ENDIF
// TEXT_LABEL_3 txt=CEIL(aiSpeed)
// PRINTSTRING("updating the ai to SPEED of : ")
// PRINTSTRING(txt)
// PRINTNL()
IF IS_PED_SITTING_IN_VEHICLE(Race.Racer[iRacerIndex].Driver, Race.Racer[iRacerIndex].Vehicle)
IF IS_VEHICLE_SEAT_FREE(Race.Racer[iRacerIndex].Vehicle, VS_DRIVER)
SET_PED_INTO_VEHICLE(Race.Racer[iRacerIndex].Driver, Race.Racer[iRacerIndex].Vehicle, VS_DRIVER)
SET_DRIVE_TASK_CRUISE_SPEED(Race.Racer[iRacerIndex].Driver, aiSpeed)
ENDIF
ENDIF
ENDIF
ENDIF
/* // Check if the race is Triathlon and on foot or water.
IF (SPTT_Master.eRaceType = SPTT_RACE_TYPE_TRIATHLON)
IF NOT ( Race.sGate[Race.Racer[iRacerIndex].iGateCur].eChkpntType = MARKER_ARROW )
FLOAT fRacerSpeed = GET_PED_DESIRED_MOVE_BLEND_RATIO(Race.Racer[iRacerIndex].Driver)
// If the player is ahead by a checkpoint lets speed the racer up a bit, or slow him down if the opposite happens.
IF Race.Racer[0].iGateCur > Race.Racer[iRacerIndex].iGateCur
fRacerSpeed *= 1.1
ELIF Race.Racer[iRacerIndex].iGateCur > Race.Racer[0].iGateCur
fRacerSpeed *= 0.9
ENDIF
FLOAT fSpeedMin = TO_FLOAT(ENUM_TO_INT(MS_ON_FOOT_WALK))+((TO_FLOAT(ENUM_TO_INT(MS_ON_FOOT_RUN))-TO_FLOAT(ENUM_TO_INT(MS_ON_FOOT_WALK)))/2)
IF fRacerSpeed < fSpeedMin
fRacerSpeed = fSpeedMin
ELIF fRacerSpeed > ENUM_TO_INT(MS_ON_FOOT_SPRINT)
fRacerSpeed = TO_FLOAT(ENUM_TO_INT(MS_ON_FOOT_SPRINT))
ENDIF
SET_PED_DESIRED_MOVE_BLEND_RATIO(Race.Racer[iRacerIndex].Driver, fRacerSpeed)
ENDIF
ENDIF
*/
ENDIF
ENDPROC
PROC SPTT_Race_Racer_Task_Go_To_Next_Gate(SPTT_RACE_STRUCT& Race, PED_INDEX iDriver, VEHICLE_INDEX iVehicle, VECTOR vGateGoto, SPTT_RACE_CHECKPOINT_TYPE eChkpntType, INT iRacerIndex)
// Task ai to go to next gate position.
IF NOT IS_ENTITY_DEAD(iDriver)
IF (SPTT_Master.eRaceType = SPTT_RACE_TYPE_OFFROAD)
//CLEAR_PED_TASKS(Race.Racer[i].Driver)
IF NOT IS_ENTITY_DEAD(iVehicle)
TASK_VEHICLE_DRIVE_TO_COORD(iDriver, iVehicle, vGateGoto, GET_VEHICLE_ESTIMATED_MAX_SPEED(iVehicle),
DRIVINGSTYLE_RACING, DUMMY_MODEL_FOR_SCRIPT, DRIVINGMODE_AVOIDCARS, 5.0, -1 )
ENDIF
ELIF (SPTT_Master.eRaceType = SPTT_RACE_TYPE_TRIATHLON)
eChkpntType = eChkpntType //may need for later
TASK_TRI_RACER_TO_FOLLOW_RACE_COURSE(Race, vGateGoto, iRacerIndex)
ENDIF
ENDIF
ENDPROC
PROC SPTT_SAFELY_SET_SCENARIO_GROUP_ENABLED(STRING sThisGroupName, BOOL bSetActive)
IF NOT IS_STRING_NULL_OR_EMPTY(sThisGroupName)
IF DOES_SCENARIO_GROUP_EXIST(sThisGroupName)
IF NOT IS_SCENARIO_GROUP_ENABLED(sThisGroupName)
SET_SCENARIO_GROUP_ENABLED(sThisGroupName, bSetActive)
ENDIF
ELSE
IF SPTT_Master.eRaceType = SPTT_RACE_TYPE_OFFROAD
PRINTLN("Scenario group ", sThisGroupName, " does not exist")
ELIF SPTT_Master.eRaceType = SPTT_RACE_TYPE_PLANE
CDEBUG1LN(DEBUG_OR_RACES, "Scenario group ", sThisGroupName, " does not exist")
ELIF SPTT_Master.eRaceType = SPTT_RACE_TYPE_TRIATHLON
CDEBUG1LN(DEBUG_TRIATHLON, "Scenario group ", sThisGroupName, " does not exist")
ENDIF
ENDIF
ELSE
IF SPTT_Master.eRaceType = SPTT_RACE_TYPE_OFFROAD
PRINTLN("String is null or empty!")
ELIF SPTT_Master.eRaceType = SPTT_RACE_TYPE_PLANE
CDEBUG1LN(DEBUG_OR_RACES, "String is null or empty!")
ELIF SPTT_Master.eRaceType = SPTT_RACE_TYPE_TRIATHLON
CDEBUG1LN(DEBUG_TRIATHLON, "String is null or empty!")
ENDIF
ENDIF
ENDPROC
PROC SPTT_Race_Init_Offroad_Intro_Cam(CAMERA_INDEX& introCamIndex, VECTOR vPlayerVehInit, FLOAT fPlayerVehInit)
introCamIndex = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA")
VECTOR vStartCam
vStartCam = vPlayerVehInit
vStartCam.z += 5.0
VECTOR vStartCamLookAt
vStartCamLookAt = GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(vStartCam, fPlayerVehInit, <<0, 10, 0>>)
SET_CAM_PARAMS(introCamIndex, vStartCam, <<0,0,0>>, GET_GAMEPLAY_CAM_FOV())
POINT_CAM_AT_COORD(introCamIndex, vStartCamLookAt)
//SET_CAM_ACTIVE_WITH_INTERP(Intro_Cam_Start, Intro_Cam_Start, 10000, GRAPH_TYPE_LINEAR)
SET_CAM_ACTIVE(introCamIndex, TRUE)
RENDER_SCRIPT_CAMS(TRUE, FALSE)
ENDPROC
PROC SPTT_RACE_CLEANUP_FINISH_STREAMVOL()
NEW_LOAD_SCENE_STOP()
IF STREAMVOL_IS_VALID(iSPTTStream)
STREAMVOL_DELETE(iSPTTStream)
ENDIF
PRINTLN("SPTT_RACE_CLEANUP_FINISH_STREAMVOL")
ENDPROC
PROC SPTT_RACE_CREATE_FINISH_STREAMVOL(SPTT_RACE_STRUCT& Race)
IF Race.Racer[0].iGateCur >= (Race.iGateCnt-2)
FLOAT fDist = VDIST(Race.sGate[Race.iGateCnt-2].vPos, SPTT_GET_END_SCREEN_CAM_POS())
IF NOT STREAMVOL_IS_VALID(iSPTTStream)
IF ( VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), SPTT_GET_END_SCREEN_CAM_POS()) <= (fDist*1.5)*(fDist*1.5) )
iSPTTStream = STREAMVOL_CREATE_FRUSTUM(SPTT_GET_END_SCREEN_CAM_POS(), Race.sGate[Race.iGateCnt-1].vPos - SPTT_GET_END_SCREEN_CAM_POS(), 2000.0, FLAG_MAPDATA)
PRINTLN("SPTT_RACE_CREATE_FINISH_STREAMVOL")
ENDIF
ELIF NOT ( VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), SPTT_GET_END_SCREEN_CAM_POS()) <= (fDist*2)*(fDist*2) )
SPTT_RACE_CLEANUP_FINISH_STREAMVOL()
ENDIF
ENDIF
ENDPROC
PROC SPTT_RACE_MANAGE_CHECKPOINT_ALPHAS(SPTT_GATE_STRUCT& GateCur, SPTT_GATE_STRUCT& GateNxt)
INT iRed, iGreen, iBlue, iAlpha
IF GateCur.Chkpnt != NULL
HUD_COLOURS eColor = MG_GET_RACE_CHECKPOINT_DEFAULT_COLOUR()
IF (GateCur.eStuntType = SPTT_RACE_STUNT_GATE_SIDE_LEFT)
OR (GateCur.eStuntType = SPTT_RACE_STUNT_GATE_SIDE_RIGHT)
eColor = HUD_COLOUR_GREEN
ELIF (GateCur.eStuntType = SPTT_RACE_STUNT_GATE_INVERTED)
eColor = HUD_COLOUR_BLUE
ENDIF
GET_RGB_FROM_INT(GET_INT_FROM_HUD_COLOUR(eColor), iRed, iGreen, iBlue, iAlpha)
SET_CHECKPOINT_RGBA(GateCur.Chkpnt, iRed, iGreen, iBlue, MG_GET_CHECKPOINT_ALPHA(GateCur.vPos))
ENDIF
IF GateNxt.Chkpnt != NULL
HUD_COLOURS eColor = MG_GET_RACE_CHECKPOINT_DEFAULT_COLOUR()
IF (GateNxt.eStuntType = SPTT_RACE_STUNT_GATE_SIDE_LEFT)
OR (GateNxt.eStuntType = SPTT_RACE_STUNT_GATE_SIDE_RIGHT)
eColor = HUD_COLOUR_GREEN
ELIF (GateNxt.eStuntType = SPTT_RACE_STUNT_GATE_INVERTED)
eColor = HUD_COLOUR_BLUE
ENDIF
GET_RGB_FROM_INT(GET_INT_FROM_HUD_COLOUR(eColor), iRed, iGreen, iBlue, iAlpha)
SET_CHECKPOINT_RGBA(GateNxt.Chkpnt, iRed, iGreen, iBlue, MG_GET_CHECKPOINT_ALPHA(GateNxt.vPos))
ENDIF
ENDPROC
// -----------------------------------
// TEST WORKSPACE
// -----------------------------------
// END OF FILE! DO NOT ADD ANYTHING BELOW THIS LINE!