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

272 lines
9.5 KiB
XML
Executable File

// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************
//
// SCRIPT NAME : SPTT_Gate.sch
// AUTHOR : Nicholas Zippmann
// DESCRIPTION : Single Player Races - Gate procs/functions file
//
// *****************************************************************************************
// *****************************************************************************************
// *****************************************************************************************
USING "SPTT_Head.sch"
USING "SPTT_Helpers.sch"
USING "stunt_plane_public.sch"
USING "chase_hint_cam.sch"
USING "script_oddjob_funcs.sch"
//CHASE_HINT_CAM_STRUCT localChaseHintCamStruct
// -----------------------------------
// SETUP PROCS/FUNCTIONS
// -----------------------------------
PROC SPTT_Gate_Init(SPTT_GATE_STRUCT& sGate)
// DEBUG_MESSAGE("SPTT_Gate_Init")
sGate.vPos = SPTT_Master.vDefRcrPos
sGate.fRadius = SPTT_GATE_CHKPNT_SCL
sGate.eChkpntType = SPTT_CHKPT_OFFROAD_DEFAULT
sGate.fHeightCheck = SPTT_GATE_HEIGHT_CHECK // To Fix Bug # 666112 - DS
ENDPROC
PROC SPTT_Gate_Setup(SPTT_GATE_STRUCT& sGate, VECTOR vPos, FLOAT fRadius, SPTT_RACE_CHECKPOINT_TYPE eChkpntType, SPTT_RACE_STUNT_GATE_ENUM eStuntType = SPTT_RACE_STUNT_GATE_NORMAL)
//DEBUG_MESSAGE("SPTT_Gate_Setup")
sGate.vPos = vPos
sGate.fRadius = fRadius
sGate.eChkpntType = eChkpntType
sGate.eStuntType = eStuntType
ENDPROC
PROC SPTT_Gate_Set_Condition_Flag(SPTT_GATE_STRUCT& sGate, ENUM_TO_INT iFlag)
SET_BITMASK_AS_ENUM(sGate.iGateFlags, iFlag)
ENDPROC
PROC SPTT_Gate_Clear_Condition_Flag(SPTT_GATE_STRUCT& sGate, ENUM_TO_INT iFlag)
CLEAR_BITMASK_AS_ENUM(sGate.iGateFlags, iFlag)
ENDPROC
FUNC BOOL SPTT_Gate_Check_Condition_Flag(SPTT_GATE_STRUCT& sGate, ENUM_TO_INT iFlag)
RETURN IS_BITMASK_AS_ENUM_SET(sGate.iGateFlags, iFlag)
ENDFUNC
// -----------------------------------
// CREATION PROCS/FUNCTIONS
// -----------------------------------
FUNC BOOL SPTT_Gate_Blip_Create(SPTT_GATE_STRUCT& sGate, BLIP_SPRITE eBlipSprite = RADAR_TRACE_INVALID, FLOAT fScale = 1.0, INT iCurGate = -1, INT iNumGates = -1)
//DEBUG_MESSAGE("SPTT_Gate_Blip_Create")
IF NOT SPTT_Blip_Coord_Create(sGate.Blip, sGate.vPos, eBlipSprite, fScale, iCurGate, iNumGates, sGate.eStuntType)
DEBUG_MESSAGE("SPTT_Gate_Blip_Create: Failed to create gate blip!")
RETURN FALSE
ENDIF
RETURN TRUE
ENDFUNC
PROC SPTT_Gate_Blip_Destroy(SPTT_GATE_STRUCT& sGate)
//DEBUG_MESSAGE("SPTT_Gate_Blip_Destroy")
SPTT_Blip_Destroy(sGate.Blip)
ENDPROC
FUNC BOOL SPTT_Gate_Chkpnt_Create(VECTOR vPrevGate, SPTT_GATE_STRUCT& sGate, VECTOR vPointAt, FLOAT fScale = SPTT_GATE_CHKPNT_SCL)
//DEBUG_MESSAGE("SPTT_Gate_Chkpnt_Create")
//IF NOT SPTT_Chkpnt_Create(sGate.Chkpnt, sGate.eChkpntType, sGate.vPos, vPointAt, fScale)
IF NOT SPTT_Chkpnt_Create(vPrevGate, sGate, vPointAt, fScale)
DEBUG_MESSAGE("SPTT_Gate_Chkpnt_Create: Failed to create gate checkpoint!")
RETURN FALSE
ENDIF
RETURN TRUE
ENDFUNC
PROC SPTT_Gate_Chkpnt_Destroy(SPTT_GATE_STRUCT& sGate)
//DEBUG_MESSAGE("SPTT_Gate_Chkpnt_Destroy")
SPTT_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
// -----------------------------------
FUNC SPTT_RACE_GATE_STATUS SPTT_Gate_Check_Pass(SPTT_GATE_STRUCT& GateCur, PED_INDEX Driver)
CONST_FLOAT fInnerRadius 110.0 //squared
CONST_FLOAT fOutterRadius 900.0 //squared
VECTOR vGatePos = GateCur.vPos
VECTOR vPlanePos
VECTOR vPlaneRight
VECTOR vPlaneUp
VECTOR vPlaneForward
GET_ENTITY_MATRIX(Driver, vPlaneForward, vPlaneRight, vPlaneUp, vPlanePos)
VECTOR vPlaneToGate = (vGatePos - vPlanePos)
FLOAT fPlaneForwardDot = ABSF(DOT_PRODUCT(vPlaneToGate, vPlaneForward))
// Add check for cylinder depth
FLOAT fPlaneUpDot = ABSF(DOT_PRODUCT(vPlaneToGate, vPlaneUp))
FLOAT fPlaneRightDot = ABSF(DOT_PRODUCT(vPlaneToGate, vPlaneRight))
// Radius checks
FLOAT fTargetRadiis = (fPlaneUpDot*fPlaneUpDot) + (fPlaneRightDot*fPlaneRightDot)
// DRAW_STUNT_TARGET(GateCur.vPos, vPlaneForward, 6.0, 15.0)
// DRAW_ENTITY_AXES(Driver, 3.0)
IF (fPlaneForwardDot > 6.5)
RETURN SPTT_RACE_GATE_STATUS_INCOMPLETE
ELSE
IF (fTargetRadiis > fOutterRadius)
DEBUG_MESSAGE("SPRGATE: Returning INCOMPLETE (outside outter)")
IF (Driver = PLAYER_PED_ID())
KILL_RACE_HINT_CAM(localChaseHintCamStruct)
ENDIF
RETURN SPTT_RACE_GATE_STATUS_INCOMPLETE
ENDIF
IF (fTargetRadiis > fInnerRadius)
DEBUG_MESSAGE("SPRGATE: Returning PASS_OUTTER")
IF (Driver = PLAYER_PED_ID())
KILL_RACE_HINT_CAM(localChaseHintCamStruct)
ENDIF
PLAY_SOUND_FRONTEND(-1, STUNT_PLANE_SFX_CHECKPOINT_CLEAR, "HUD_MINI_GAME_SOUNDSET")
RETURN SPTT_RACE_GATE_STATUS_PASS_OUTTER
ELSE
DEBUG_MESSAGE("SPRGATE: Returning PASS_INNER")
IF (Driver = PLAYER_PED_ID())
KILL_RACE_HINT_CAM(localChaseHintCamStruct)
ENDIF
PLAY_SOUND_FRONTEND(-1, STUNT_PLANE_SFX_CHECKPOINT_CLEAR, "HUD_MINI_GAME_SOUNDSET")
RETURN SPTT_RACE_GATE_STATUS_PASS_INNER
ENDIF
ENDIF
RETURN SPTT_RACE_GATE_STATUS_INVALID
ENDFUNC
FUNC BOOL SPTT_Gate_Check_Miss(SPTT_GATE_STRUCT& GateCur, SPTT_GATE_STRUCT& GateNxt, PED_INDEX Driver)
//DEBUG_MESSAGE("SPTT_Gate_Check_Miss")
IF NOT ARE_VECTORS_ALMOST_EQUAL(GateCur.vPos, GateNxt.vPos)
FLOAT fRadius = GateCur.fRadius * SPTT_GATE_MISS_DIST_SCL
IF IS_ENTITY_AT_COORD(Driver, GateCur.vPos, <<fRadius,fRadius,fRadius>>)
//VECTOR vDrvVec = GET_ENTITY_COORDS(Driver) - GateCur.vPos
VECTOR vGateVec = NORMALISE_VECTOR(GateNxt.vPos - GateCur.vPos)
// subtract this
IF DOT_PRODUCT(GET_ENTITY_COORDS(Driver), vGateVec) - DOT_PRODUCT(GateCur.vPos, vGateVec) > 15.0
//IF (DOT_PRODUCT(vDrvVec, vGateVec) > 15.0)
// do gate miss audio here:
PLAY_SOUND_FRONTEND(-1, STUNT_PLANE_SFX_CHECKPOINT_MISS, "HUD_MINI_GAME_SOUNDSET")
RETURN TRUE
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL SPTT_Stunt_Gate_Missed(SPTT_RACE_GATE_STATUS thisGateStatus)
IF thisGateStatus = SPTT_RACE_GATE_STATUS_STUNT_KL_HIT
OR thisGateStatus = SPTT_RACE_GATE_STATUS_STUNT_KR_HIT
OR thisGateStatus = SPTT_RACE_GATE_STATUS_STUNT_INV_HIT
OR thisGateStatus = SPTT_RACE_GATE_STATUS_STUNT_KL_MISS
OR thisGateStatus = SPTT_RACE_GATE_STATUS_STUNT_KR_MISS
OR thisGateStatus = SPTT_RACE_GATE_STATUS_STUNT_INV_MISS
OR thisGateStatus = SPTT_RACE_GATE_STATUS_MISSED_GATE
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL SPTT_Race_Racer_Get_CheckGround_For_AutoPilot(SPTT_RACE_STRUCT& Race, SPTT_RACER_STRUCT& Racer)
SWITCH SPTT_Master.eRaceType
CASE SPTT_RACE_TYPE_PLANE
IF Racer.Driver = PLAYER_PED_ID()
AND Racer.iGateCur != -1
PRINTSTRING("SPTT_Race_Racer_Get_CheckGround_For_AutoPilot: ignore ground is TRUE for gate: ")
PRINTINT(Racer.iGateCur)
PRINTNL()
RETURN SPTT_Gate_Check_Condition_Flag(Race.sGate[Race.Racer[0].iGateCur], SPTT_RACE_GATE_FLAG_AP_IGNORE_GROUND)
ENDIF
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC