Files
gtav-src/script/dev_ng/singleplayer/scripts/Minigames/Triathlon/tri_gate.sch
T
2025-09-29 00:52:08 +02:00

498 lines
18 KiB
XML
Executable File

// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************
//
// SCRIPT NAME : tri_gate.sch
// AUTHOR : Nicholas Zippmann
// DESCRIPTION : Single Player Races - Gate procs/functions file
//
// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************
USING "tri_Head.sch"
USING "tri_Helpers.sch"
USING "stunt_plane_public.sch"
USING "chase_hint_cam.sch"
USING "script_oddjob_funcs.sch"
// -----------------------------------
// SETUP PROCS/FUNCTIONS
// -----------------------------------
PROC TRI_Gate_Init(TRI_GATE_STRUCT& sGate)
CDEBUG1LN(DEBUG_TRIATHLON, "[TRI_Gate_Init] Procedure called.")
sGate.vPos = TRI_Master.vDefRcrPos
sGate.fRadius = TRI_GATE_CHKPNT_SCL
sGate.eChkpntType = TRI_CHKPT_OFFROAD_DEFAULT
sGate.fHeightCheck = TRI_GATE_HEIGHT_CHECK // To Fix Bug # 666112 - DS
sGate.bIsFading = FALSE
ENDPROC
PROC TRI_Gate_Setup(TRI_GATE_STRUCT& sGate, VECTOR vPos, FLOAT fRadius, TRI_RACE_CHECKPOINT_TYPE eChkpntType, BOOL bPlaySound = TRUE)
//DEBUG_MESSAGE("TRI_Gate_Setup")
sGate.vPos = vPos
sGate.fRadius = fRadius
sGate.eChkpntType = eChkpntType
IF bPlaySound
SET_TRI_GATE_FLAG(sGate,TRI_RACE_GATE_FLAG_PLAY_SOUND)
ENDIF
ENDPROC
PROC TRI_Gate_Set_Condition_Flag(TRI_GATE_STRUCT& sGate, ENUM_TO_INT iFlag)
SET_BITMASK_AS_ENUM(sGate.iGateFlags, iFlag)
ENDPROC
PROC TRI_Gate_Clear_Condition_Flag(TRI_GATE_STRUCT& sGate, ENUM_TO_INT iFlag)
CLEAR_BITMASK_AS_ENUM(sGate.iGateFlags, iFlag)
ENDPROC
FUNC BOOL TRI_Gate_Check_Condition_Flag(TRI_GATE_STRUCT& sGate, ENUM_TO_INT iFlag)
RETURN IS_BITMASK_AS_ENUM_SET(sGate.iGateFlags, iFlag)
ENDFUNC
// -----------------------------------
// CREATION PROCS/FUNCTIONS
// -----------------------------------
FUNC BOOL TRI_Gate_Blip_Create(TRI_GATE_STRUCT& sGate, BLIP_SPRITE eBlipSprite = RADAR_TRACE_INVALID, FLOAT fScale = 1.0, INT iCurGate = -1, INT iNumGates = -1)
//DEBUG_MESSAGE("TRI_Gate_Blip_Create")
IF NOT TRI_Blip_Coord_Create(sGate.Blip, sGate.vPos, eBlipSprite, fScale, iCurGate, iNumGates)
DEBUG_MESSAGE("TRI_Gate_Blip_Create: Failed to create gate blip!")
RETURN FALSE
ENDIF
RETURN TRUE
ENDFUNC
PROC TRI_Gate_Blip_Destroy(TRI_GATE_STRUCT& sGate)
//DEBUG_MESSAGE("TRI_Gate_Blip_Destroy")
TRI_Blip_Destroy(sGate.Blip)
ENDPROC
FUNC BOOL TRI_Gate_Chkpnt_Create(VECTOR vPrevGate, TRI_GATE_STRUCT& sGate, VECTOR vPointAt, FLOAT fScale = TRI_GATE_CHKPNT_SCL)
//DEBUG_MESSAGE("TRI_Gate_Chkpnt_Create")
//IF NOT TRI_Chkpnt_Create(sGate.Chkpnt, sGate.eChkpntType, sGate.vPos, vPointAt, fScale)
IF NOT TRI_Chkpnt_Create(vPrevGate, sGate, vPointAt, fScale)
DEBUG_MESSAGE("TRI_Gate_Chkpnt_Create: Failed to create gate checkpoint!")
RETURN FALSE
ENDIF
RETURN TRUE
ENDFUNC
PROC TRI_Gate_Chkpnt_Destroy(TRI_GATE_STRUCT& sGate)
//DEBUG_MESSAGE("TRI_Gate_Chkpnt_Destroy")
TRI_Chkpnt_Destroy(sGate.Chkpnt)
ENDPROC
// DEBUG DRAW FUNCTION FOR GATE CLEARING (STUNT PLANE RACES)
PROC DRAW_STUNT_TARGET(VECTOR vCenter, VECTOR vOrtho, FLOAT fSmallRadius, FLOAT fLargeRadius)
SCRIPT_ASSERT("Running Draw Stunt Target")
VECTOR vVertices[16]
VECTOR vRight = CROSS_PRODUCT(vOrtho, <<0,0,1>>)
VECTOR vSmallProj = fSmallRadius * vRight
VECTOR vLargeProj = fLargeRadius * vRight
INT iInnerVert, iOuterVert
INT i
// Determine horizontal crosshair verts.
vVertices[ 0] = vCenter + vSmallProj
vVertices[ 4] = vCenter - vSmallProj
vVertices[ 8] = vCenter + vLargeProj
vVertices[12] = vCenter - vLargeProj
VECTOR vUp = CROSS_PRODUCT(vOrtho, vRight)
vSmallProj = fSmallRadius * vUp
vLargeProj = fLargeRadius * vUp
// Determine vertical crosshair verts.
vVertices[ 2] = vCenter + vSmallProj
vVertices[ 6] = vCenter - vSmallProj
vVertices[10] = vCenter + vLargeProj
vVertices[14] = vCenter - vLargeProj
vSmallProj = GET_VECTOR_OF_LENGTH((vRight + vUp) / 2.0, fSmallRadius)
vLargeProj = GET_VECTOR_OF_LENGTH((vRight + vUp) / 2.0, fLargeRadius)
// Determine vertical vert set 1.
vVertices[ 1] = vCenter + vSmallProj
vVertices[ 5] = vCenter - vSmallProj
vVertices[ 9] = vCenter + vLargeProj
vVertices[13] = vCenter - vLargeProj
vSmallProj -= vRight * (fSmallRadius * 1.414)
vLargeProj -= vRight * (fLargeRadius * 1.414)
// Determine vertical vert set 2.
vVertices[ 3] = vCenter + vSmallProj
vVertices[ 7] = vCenter - vSmallProj
vVertices[11] = vCenter + vLargeProj
vVertices[15] = vCenter - vLargeProj
// Draw the shape.
REPEAT 8 i
// Draw the radial line.
DRAW_DEBUG_LINE(vCenter, vVertices[i+8], 127, 0, 0, 255)
IF i = 7
iInnerVert = 0
iOuterVert = 8
ELSE
iInnerVert = i + 1
iOuterVert = i + 9
ENDIF
// Draw the inner & outer lines.
DRAW_DEBUG_LINE(vVertices[i ], vVertices[iInnerVert], 0, 200, 0, 255)
DRAW_DEBUG_LINE(vVertices[i+8], vVertices[iOuterVert], 0, 0, 200, 255)
ENDREPEAT
ENDPROC
PROC DRAW_ENTITY_AXES(ENTITY_INDEX myIndex, FLOAT fscale)
VECTOR vFront, vSide, vUp, vPos
GET_ENTITY_MATRIX(myIndex, vFront, vSide, vUp, vPos)
DRAW_DEBUG_LINE(vPos, vPos + fScale * vSide, 255, 0, 0, 255)
DRAW_DEBUG_LINE(vPos, vPos + fScale * vFront, 255, 0, 0, 255)
DRAW_DEBUG_LINE(vPos, vPos + fScale * vUp, 255, 0, 0, 255)
ENDPROC
// -----------------------------------
// HELPER PROCS/FUNCTIONS
// -----------------------------------
/// PURPOSE:
/// Tracks when a racer ped has crossed a checkpoint.
/// PARAMS:
/// race - A reference to a struct containing all race data.
/// GateCur - The current checkpoint.
/// Driver - The ped being checked against the current checkpoint.
/// iRacerIndex - The index of the racer (ped+vehicle) in the racer array.
/// RETURNS:
///
FUNC TRI_RACE_GATE_STATUS TRI_CHECK_RACER_GATE_STATUS(TRI_RACE_STRUCT &race, TRI_GATE_STRUCT& GateCur, PED_INDEX Driver, INT iRacerIndex)
#IF NOT DEFINED(bAudioPlayedLastGate)
BOOL bAudioPlayedLastGate
bAudioPlayedLastGate = bAudioPlayedLastGate
#ENDIF
IF IS_ENTITY_DEAD(Driver)
// No need to go through the logic below. The driver is dead, so the driver's gate status is invalid.
RETURN TRI_RACE_GATE_STATUS_INVALID
ENDIF
CONST_FLOAT fInnerRadius 110.0 //squared
CONST_FLOAT fOutterRadius 900.0 //squared
// Ensure the player meets the requirements of the current race leg when trying to cross a gate.
IF (GateCur.eChkpntType = TRI_CHKPT_TRI_BIKE) OR (GateCur.eChkpntType = TRI_CHKPT_TRI_SECOND_TRANS)
// Require the player to be in a vehicle when clearing bike gates.
IF NOT IS_PED_IN_ANY_VEHICLE(Driver)
IF (GateCur.eChkpntType = TRI_CHKPT_TRI_SECOND_TRANS AND NOT IS_PED_RAGDOLL(Driver))
OR GateCur.eChkpntType <> TRI_CHKPT_TRI_SECOND_TRANS
RETURN TRI_RACE_GATE_STATUS_INVALID
ENDIF
ELSE
// The player is in a vehicle, so check if the vehicle is a tribike.
IF NOT ( IS_PED_IN_MODEL(Driver, TRIBIKE) OR IS_PED_IN_MODEL(Driver, TRIBIKE2) OR IS_PED_IN_MODEL(Driver, TRIBIKE3) )
RETURN TRI_RACE_GATE_STATUS_INVALID
ENDIF
ENDIF
ELSE
// Require the player to be out of a vehicle when clearing swim and run gates.
IF IS_PED_IN_ANY_VEHICLE(Driver) OR IS_PED_GETTING_INTO_A_VEHICLE(Driver)
RETURN TRI_RACE_GATE_STATUS_INVALID
ENDIF
ENDIF
// Variables used in the swim gate check below (CASE TRI_CHKPT_TRI_SWIM).
VECTOR vBuoy
VECTOR vRacerPos
VECTOR vBuoyToGate
VECTOR vBuoyToRacer
FLOAT fDot
// Since there are different types of race legs and gates, check the type of the current gate to appropriately check its status.
SWITCH GateCur.eChkpntType
// LAST GATE: These gates are angled areas so their orientation can be lined up with that of the race path.
CASE TRI_CHKPT_TRI_FINISH
SWITCH INT_TO_ENUM(TRIATHLON_RACE_INDEX, TRI_Master.iRaceCur)
CASE TRIATHLON_RACE_ALAMO_SEA
IF IS_ENTITY_IN_ANGLED_AREA(Driver, << 1753.24, 3895.40, 33.82 >>, << 1762.06, 3900.40, 40.81 >>, 9.7)
IF Driver <> PLAYER_PED_ID()
IF Race.Racer[iRacerIndex].iRank = 1
ADD_TRI_NEWS_EVENT( TRNE_NPC_WON_RACE )
ENDIF
ENDIF
KILL_RACE_HINT_CAM(localChaseHintCamStruct)
RETURN TRI_RACE_GATE_STATUS_PASS
ENDIF
BREAK
CASE TRIATHLON_RACE_VESPUCCI
IF IS_ENTITY_IN_ANGLED_AREA(Driver, << -1327.06, -1041.91, 6.40 >>, << -1336.80, -1047.55, 13.47 >>, 9.7)
IF Driver <> PLAYER_PED_ID()
IF Race.Racer[iRacerIndex].iRank = 1
ADD_TRI_NEWS_EVENT( TRNE_NPC_WON_RACE )
ENDIF
ENDIF
KILL_RACE_HINT_CAM(localChaseHintCamStruct)
RETURN TRI_RACE_GATE_STATUS_PASS
ENDIF
BREAK
CASE TRIATHLON_RACE_IRONMAN
IF IS_ENTITY_IN_ANGLED_AREA(Driver, << -2298.94, 459.13, 173.47 >>, << -2310.46, 460.32, 180.47 >>, 9.7) // Ironman
IF Driver <> PLAYER_PED_ID()
IF Race.Racer[iRacerIndex].iRank = 1
ADD_TRI_NEWS_EVENT( TRNE_NPC_WON_RACE )
ENDIF
ENDIF
KILL_RACE_HINT_CAM(localChaseHintCamStruct)
RETURN TRI_RACE_GATE_STATUS_PASS
ENDIF
BREAK
ENDSWITCH
BREAK
// BIKE-TO-RUN GATE: These gates are angled areas so their orientation can be lined up with that of the race path.
CASE TRI_CHKPT_TRI_SECOND_TRANS
SWITCH INT_TO_ENUM(TRIATHLON_RACE_INDEX, TRI_Master.iRaceCur)
CASE TRIATHLON_RACE_ALAMO_SEA
IF IS_ENTITY_IN_ANGLED_AREA(Driver, << 1974.43, 3887.36, 31.35 >>, << 1961.63, 3879.74, 38.30 >>, 18.0)
IF Driver <> PLAYER_PED_ID()
IF Race.Racer[iRacerIndex].iRank = 1
ADD_TRI_NEWS_EVENT( TRNE_NPC_WON_BIKE )
ENDIF
ENDIF
RETURN TRI_RACE_GATE_STATUS_PASS
ENDIF
BREAK
CASE TRIATHLON_RACE_VESPUCCI
IF IS_ENTITY_IN_ANGLED_AREA(Driver, << -1172.74, -844.98, 13.36 >>, << -1166.32, -856.93, 20.16 >>, 18.0)
IF Driver <> PLAYER_PED_ID()
IF Race.Racer[iRacerIndex].iRank = 1
ADD_TRI_NEWS_EVENT( TRNE_NPC_WON_BIKE )
ENDIF
ENDIF
RETURN TRI_RACE_GATE_STATUS_PASS
ENDIF
BREAK
CASE TRIATHLON_RACE_IRONMAN
IF IS_ENTITY_IN_ANGLED_AREA(Driver, << -1283.32, 274.68, 63.78 >>, << -1275.79, 283.86, 70.86 >>, 12.0) // Ironman
IF Driver <> PLAYER_PED_ID()
IF Race.Racer[iRacerIndex].iRank = 1
ADD_TRI_NEWS_EVENT( TRNE_NPC_WON_BIKE )
ENDIF
ENDIF
RETURN TRI_RACE_GATE_STATUS_PASS
ENDIF
BREAK
ENDSWITCH
BREAK
// SWIM GATE
CASE TRI_CHKPT_TRI_SWIM
vBuoy = GET_ENTITY_COORDS(race.objSwimLegBuoys[race.Racer[iRacerIndex].iGateCur])
vRacerPos = GET_ENTITY_COORDS(Driver)
vBuoyToGate = GateCur.vPos - vBuoy
vBuoyToRacer = vRacerPos - vBuoy
fDot = DOT_PRODUCT(vBuoyToGate, vBuoyToRacer)
IF (IS_ENTITY_AT_COORD(Driver, GateCur.vPos, <<GateCur.fRadius,GateCur.fRadius,GateCur.fRadius>>) AND fDot >= 0)
IF (Driver = PLAYER_PED_ID())
KILL_RACE_HINT_CAM(localChaseHintCamStruct)
// do gate clear audio here:
IF IS_TRI_GATE_FLAG_SET( GateCur,TRI_RACE_GATE_FLAG_PLAY_SOUND)
PLAY_SOUND_FRONTEND(-1, STUNT_PLANE_SFX_CHECKPOINT_CLEAR, "HUD_MINI_GAME_SOUNDSET")
ENDIF
ENDIF
RETURN TRI_RACE_GATE_STATUS_PASS
ENDIF
BREAK
// DEFAULT: All other gates not handled above.
DEFAULT
IF IS_ENTITY_AT_COORD(Driver, GateCur.vPos, <<GateCur.fRadius,GateCur.fRadius,GateCur.fRadius>>)
IF (Driver = PLAYER_PED_ID())
KILL_RACE_HINT_CAM(localChaseHintCamStruct)
// do gate clear audio here:
IF IS_TRI_GATE_FLAG_SET( GateCur,TRI_RACE_GATE_FLAG_PLAY_SOUND)
PLAY_SOUND_FRONTEND(-1, STUNT_PLANE_SFX_CHECKPOINT_CLEAR, "HUD_MINI_GAME_SOUNDSET")
ENDIF
ELSE
IF GateCur.eChkpntType = TRI_CHKPT_TRI_FIRST_TRANS
IF Driver <> PLAYER_PED_ID()
IF Race.Racer[iRacerIndex].iRank = 1
ADD_TRI_NEWS_EVENT( TRNE_NPC_WON_SWIM )
ENDIF
ENDIF
ENDIF
ENDIF
RETURN TRI_RACE_GATE_STATUS_PASS
ENDIF
BREAK
ENDSWITCH
RETURN TRI_RACE_GATE_STATUS_INVALID
ENDFUNC
#IF IS_DEBUG_BUILD
PROC TRI_Race_Gate_Draw_Marker_Type(MARKER_TYPE MarkerType, VECTOR scrVecPosition, VECTOR scrVecDirection, BOOL bIsActive, FLOAT fDefScale)
FLOAT fScale = 0.7
FLOAT fMarkerHeight = fDefScale
INT iMarkerRed = 0
INT iMarkerGreen = 0
INT iMarkerBlue = 0
IF biSActive
fScale = 1.0
iMarkerRed = 255
fMarkerHeight *= 3
ELSE
iMarkerRed = 254
iMarkerGreen = 207
iMarkerBlue = 12
ENDIF
SWITCH MarkerType
CASE MARKER_ARROW
DRAW_MARKER(MarkerType, scrVecPosition, scrVecDirection, <<0,0,90>>, <<fDefScale, fDefScale, fMarkerHeight>>*fScale, iMarkerRed, iMarkerGreen, iMarkerBlue, 100, FALSE, TRUE)
BREAK
CASE MARKER_FLAG
DRAW_MARKER(MarkerType, scrVecPosition, scrVecDirection, <<0,0,0>>, <<fDefScale, fDefScale, fMarkerHeight>>*fScale, iMarkerRed, iMarkerGreen, iMarkerBlue, 100, FALSE, FALSE)
BREAK
CASE MARKER_CYLINDER
DRAW_MARKER(MarkerType, scrVecPosition, scrVecDirection, <<0,0,0>>, <<fDefScale, fDefScale, fMarkerHeight*2>>*fScale, iMarkerRed, iMarkerGreen, iMarkerBlue, 100)
BREAK
CASE MARKER_RING
DRAW_MARKER(MarkerType, scrVecPosition, scrVecDirection, <<0,-45,0>>, <<fDefScale, fDefScale, fMarkerHeight*2>>*fScale, iMarkerRed, iMarkerGreen, iMarkerBlue, 100, FALSE, TRUE)
BREAK
CASE MARKER_PLANE
DRAW_MARKER(MarkerType, scrVecPosition, scrVecDirection, <<0,0,0>>, <<fDefScale, fDefScale, fMarkerHeight*2>>*fScale, iMarkerRed, iMarkerGreen, iMarkerBlue, 100, FALSE, TRUE)
BREAK
DEFAULT
DEBUG_MESSAGE("TRI_Race_Gate_Draw_Marker_Type: bad MarkerType")
BREAK
ENDSWITCH
ENDPROC
PROC TRI_Race_Gate_Draw_Marker(TRI_GATE_STRUCT& GateCur, VECTOR vMarkerDir, BOOL bIsActive = TRUE)
SWITCH GateCur.eChkpntType
CASE TRI_CHKPT_OFFROAD_DEFAULT
TRI_Race_Gate_Draw_Marker_Type(MARKER_ARROW, GateCur.vPos, vMarkerDir, bIsActive, TRI_GATE_CHKPNT_OFFROAD_ARROW_SCL)
TRI_Race_Gate_Draw_Marker_Type(MARKER_CYLINDER, GateCur.vPos, vMarkerDir, bIsActive, TRI_GATE_CHKPNT_OFFROAD_CYLINDER_SCL)
BREAK
CASE TRI_CHKPT_OFFROAD_FINISH
TRI_Race_Gate_Draw_Marker_Type(MARKER_FLAG, GateCur.vPos, vMarkerDir, bIsActive, TRI_GATE_CHKPNT_OFFROAD_FLAG_SCL)
TRI_Race_Gate_Draw_Marker_Type(MARKER_CYLINDER, GateCur.vPos, vMarkerDir, bIsActive, TRI_GATE_CHKPNT_OFFROAD_CYLINDER_SCL)
BREAK
CASE TRI_CHKPT_STUNT_DEFAULT
TRI_Race_Gate_Draw_Marker_Type(MARKER_RING, GateCur.vPos, vMarkerDir, bIsActive, TRI_GATE_CHKPNT_STUNT_RING_SCL)
TRI_Race_Gate_Draw_Marker_Type(MARKER_PLANE, GateCur.vPos, vMarkerDir, bIsActive, TRI_GATE_CHKPNT_STUNT_PLANE_SCL)
BREAK
CASE TRI_CHKPT_STUNT_FINISH
TRI_Race_Gate_Draw_Marker_Type(MARKER_FLAG, GateCur.vPos, vMarkerDir, bIsActive, TRI_GATE_CHKPNT_STUNT_FLAG_SCL)
TRI_Race_Gate_Draw_Marker_Type(MARKER_PLANE, GateCur.vPos, vMarkerDir, bIsActive, TRI_GATE_CHKPNT_STUNT_PLANE_SCL)
BREAK
CASE TRI_CHKPT_TRI_SWIM
TRI_Race_Gate_Draw_Marker_Type(MARKER_ARROW, GateCur.vPos, vMarkerDir, bIsActive, TRI_GATE_CHKPNT_TRI_ARROW_SCL)
BREAK
CASE TRI_CHKPT_TRI_BIKE
TRI_Race_Gate_Draw_Marker_Type(MARKER_ARROW, GateCur.vPos, vMarkerDir, bIsActive, TRI_GATE_CHKPNT_TRI_ARROW_SCL)
TRI_Race_Gate_Draw_Marker_Type(MARKER_CYLINDER, GateCur.vPos, vMarkerDir, bIsActive, TRI_GATE_CHKPNT_TRI_CYLINDER_SCL)
BREAK
CASE TRI_CHKPT_TRI_RUN
TRI_Race_Gate_Draw_Marker_Type(MARKER_ARROW, GateCur.vPos, vMarkerDir, bIsActive, TRI_GATE_CHKPNT_TRI_ARROW_SCL)
TRI_Race_Gate_Draw_Marker_Type(MARKER_CYLINDER, GateCur.vPos, vMarkerDir, bIsActive, TRI_GATE_CHKPNT_TRI_CYLINDER_SCL)
BREAK
CASE TRI_CHKPT_TRI_FINISH
TRI_Race_Gate_Draw_Marker_Type(MARKER_FLAG, GateCur.vPos, vMarkerDir, bIsActive, TRI_GATE_CHKPNT_TRI_FLAG_SCL)
TRI_Race_Gate_Draw_Marker_Type(MARKER_CYLINDER, GateCur.vPos, vMarkerDir, bIsActive, TRI_GATE_CHKPNT_TRI_CYLINDER_SCL)
BREAK
CASE TRI_CHKPT_TRI_FIRST_TRANS
TRI_Race_Gate_Draw_Marker_Type(MARKER_FLAG, GateCur.vPos, vMarkerDir, bIsActive, TRI_GATE_CHKPNT_TRI_FLAG_SCL)
TRI_Race_Gate_Draw_Marker_Type(MARKER_CYLINDER, GateCur.vPos, vMarkerDir, bIsActive, TRI_GATE_CHKPNT_TRI_CYLINDER_SCL)
BREAK
CASE TRI_CHKPT_TRI_SECOND_TRANS
TRI_Race_Gate_Draw_Marker_Type(MARKER_FLAG, GateCur.vPos, vMarkerDir, bIsActive, TRI_GATE_CHKPNT_TRI_FLAG_SCL)
TRI_Race_Gate_Draw_Marker_Type(MARKER_CYLINDER, GateCur.vPos, vMarkerDir, bIsActive, TRI_GATE_CHKPNT_TRI_CYLINDER_SCL)
BREAK
DEFAULT
DEBUG_MESSAGE("TRI_Race_Gate_Draw_Marker: bad eChkpntType")
BREAK
ENDSWITCH
ENDPROC
PROC TRI_Race_Gate_Draw_All_Inactive_Markers(TRI_RACE_STRUCT& Race, INT iSelected)
//DEBUG_MESSAGE("TRI_Race_Gate_Draw_All_Markers")
INT iGate
REPEAT Race.iGateCnt iGate
IF (iGate < (TRI_GATE_MAX - 2))
IF (iSelected != iGate)
AND ((iSelected+1) != iGate)
AND (iGate <= (iSelected+31))
AND (iGate >= (iSelected-30))
DRAW_MARKER(MARKER_CYLINDER, Race.sGate[iGate].vPos, <<0,0,0>>, <<0,0,0>>, <<10, 10, 30>>, 254, 207, 12, 100)
ENDIF
ENDIF
IF NOT DOES_BLIP_EXIST(Race.sGate[iGate].Blip)
BLIP_SPRITE eBlipSprite = RADAR_TRACE_OBJECTIVE_BLUE
IF (iGate = (Race.iGateCnt - 1))
eBlipSprite = RADAR_TRACE_RACEFLAG
ENDIF
TRI_Blip_Coord_Create(Race.sGate[iGate].Blip, Race.sGate[iGate].vPos, eBlipSprite, TRI_GATE_BLIPNXT_SCL, iGate, Race.iGateCnt)
SET_BLIP_PRIORITY(Race.sGate[iGate].Blip, BLIPPRIORITY_HIGHEST)
ENDIF
ENDREPEAT
ENDPROC
PROC TRI_Race_Gate_Create_Custom_GPS_Route(TRI_RACE_STRUCT& Race)
//DEBUG_MESSAGE("TRI_Race_Gate_Draw_All_Markers")
CLEAR_GPS_CUSTOM_ROUTE()
START_GPS_CUSTOM_ROUTE(HUD_COLOUR_YELLOW, TRUE, FALSE)
INT iGate
REPEAT Race.iGateCnt iGate
ADD_POINT_TO_GPS_CUSTOM_ROUTE(Race.sGate[iGate].vPos)
ENDREPEAT
SET_GPS_CUSTOM_ROUTE_RENDER(TRUE, 18, 30)
ENDPROC
#ENDIF
// END OF FILE! DO NOT ADD ANYTHING BELOW THIS LINE!