// ***************************************************************************************** // ***************************************************************************************** // ***************************************************************************************** // // 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, <>) //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