// ***************************************************************************************** // ***************************************************************************************** // ***************************************************************************************** // // SCRIPT NAME : TRI_Helpers.sch // AUTHOR : Nicholas Zippmann // DESCRIPTION : Single Player Races - Helper procs/functions file // // ***************************************************************************************** // ***************************************************************************************** // ***************************************************************************************** USING "event_public.sch" USING "TRI_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" USING "tri_ai.sch" CONST_INT MAX_DISTANCE_FROM_BIKE 5 CHASE_HINT_CAM_STRUCT localChaseHintCamStruct CAMERA_INDEX camSynchScene INT iSynchSceneIntro #IF NOT DEFINED(TASK_TRI_RACER_TO_FOLLOW_RACE_COURSE) PROC TASK_TRI_RACER_TO_FOLLOW_RACE_COURSE(TRI_RACE_STRUCT& Race, VECTOR vCurrentGatePos, INT iRacerIndex) CPRINTLN(DEBUG_TRIATHLON, "[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 TRI_GENERAL_BITS TRI_SCORECARD_INIT = BIT0, TRI_SCORECARD_STREAMED = BIT1, TRI_PLAYED_STINGER = BIT2, TRI_FORCE_GATE_ACTIVATION = BIT3, TRI_FIRST_GATE_ACTIVATION = BIT4, TRI_PRINTED_IDLE_WARNING = BIT5, TRI_END_RETURN_TO_GAMPLAY_CAM = BIT6, TRI_ENDSCREEN_READY = BIT7, TRI_PLAYER_VEHICLE_SAVED =BIT8 ENDENUM ENUM TRI_COUNTDOWN_STAGE TRI_COUNTDOWN_STAGE_INIT, TRI_COUNTDOWN_RUN, TRI_COUNTDOWN_STAGE_WAIT ENDENUM /// PURPOSE: Bitfield enum for controlling help and objective prints ENUM TRI_HELP_AND_OBJECTIVES TRI_DIST_HELP = BIT0, TRI_DAMG_HELP = BIT1, TRI_WARN_HELP = BIT2, TRI_FAIL_HELP = BIT3, TRI_RETURN_WARN = BIT4, TRI_RETURN_FAIL = BIT5, TRI_RETURN_DES = BIT6, TRI_EXIT_WARN = BIT7, TRI_EXIT_FAIL = BIT8, TRI_EXIT_FAIL2 = BIT9, TRI_TXIT_WARN = BIT10, TRI_TXIT_FAIL = BIT11, TRI_MOVE_WARN = BIT12, TRI_MOVE_FAIL = BIT13, TRI_HELP_WANT = BIT14 ENDENUM structTimer exitTimer structTimer waterTimer structTimer ExitVehicleTimer INT iSPRGeneralBits INT TRI_HELP_BIT TRI_HINT_CAM_STRUCT TRI_HINT_CAM COUNTDOWN_UI TRI_CountDownUI TRI_COUNTDOWN_STAGE eCountdownStage = TRI_COUNTDOWN_STAGE_INIT // ----------------------------------- // GLOBAL PROCS/FUNCTIONS // ----------------------------------- PROC SET_TRI_SCENARIO_PAPARAZZI_PEDS() CPRINTLN(DEBUG_TRIATHLON, "[tri_helpers.sch :: SET_TRI_SCENARIO_PAPARAZZI_PEDS] called") PED_INDEX pedsNearby[30] INT iNearbyPeds SET_SCENARIO_PEDS_TO_BE_RETURNED_BY_NEXT_COMMAND(TRUE) iNearbyPeds = GET_PED_NEARBY_PEDS(PLAYER_PED_ID(), pedsNearby) CPRINTLN(DEBUG_TRIATHLON, "[tri_helpers.sch :: SET_TRI_SCENARIO_PAPARAZZI_PEDS] iNearbyPeds=", iNearbyPeds) INT p=0 WHILE p < iNearbyPeds IF DOES_ENTITY_EXIST(pedsNearby[p]) MODEL_NAMES eModel = GET_ENTITY_MODEL(pedsNearby[p]) IF eModel = A_M_M_PAPARAZZI_01 OR eModel = U_M_Y_PAPARAZZI CPRINTLN(DEBUG_TRIATHLON, "[tri_helpers.sch :: SET_TRI_SCENARIO_PAPARAZZI_PEDS] Setting pedsNearby[", p, "] with new clipset") IF NOT IS_PED_INJURED(pedsNearby[p]) #IF IS_DEBUG_BUILD TEXT_LABEL_7 texPed = "ped_" texPed += p DEBUG_RECORD_SPHERE(texPed, GET_ENTITY_COORDS(pedsNearby[p]), 1.0, (<<0,0,1>>)) #ENDIF SET_PED_WEAPON_MOVEMENT_CLIPSET(pedsNearby[p], "random@escape_paparazzi@standing@") ENDIF ENDIF ENDIF p++ ENDWHILE ENDPROC FUNC BOOL ORR_DOES_RACE_REQUIRE_MOTORCYCLE() IF TRI_Master.eRaceType != TRI_RACE_TYPE_OFFROAD RETURN FALSE ENDIF IF (TRI_Master.iRaceCur = 1 OR TRI_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 FUNC INT TRI_Global_BestRank_Get(INT iRace) INT iBestRank = 0 iBestRank = g_savedGlobals.sTriathlonData.iBestRank[iRace] RETURN iBestRank ENDFUNC PROC TRI_Global_BestRank_Set(INT iRace, INT iBestRank) CDEBUG2LN(DEBUG_TRIATHLON, "TRI_Global_BestRank_Set :: iRace=", iRace, ", iBestRank=", iBestRank) g_savedGlobals.sTriathlonData.iBestRank[iRace] = iBestRank ENDPROC FUNC FLOAT TRI_Global_BestTime_Get(INT iRace) FLOAT fBestTime fBestTime = g_savedGlobals.sTriathlonData.fBestTime[iRace] RETURN fBestTime ENDFUNC PROC TRI_Global_BestTime_Set(INT iRace, FLOAT fBestTime) g_savedGlobals.sTriathlonData.fBestTime[iRace] = fBestTime ENDPROC // ----------------------------------- // DEBUG PROCS/FUNCTIONS // ----------------------------------- PROC TRI_Racer_DebugPrint(TRI_RACER_STRUCT& Racer) //DEBUG_MESSAGE("TRI_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 TRI_ACTIVATE_INTRO_SKY_CAM(CAMERA_INDEX &camTriSky, VECTOR vEndPos, VECTOR vEndRot) UNUSED_PARAMETER( vEndPos ) UNUSED_PARAMETER( vEndRot ) IF NOT DOES_CAM_EXIST(camTriSky) CPRINTLN(DEBUG_TRIATHLON, "[tri_helpers.sch::TRI_ACTIVATE_INTRO_SKY_CAM] intro cam set") // VECTOR vStartPos, vStartRot // vStartPos = GET_GAMEPLAY_CAM_COORD() // vStartRot = GET_GAMEPLAY_CAM_ROT() //camTriSky = CREATE_CAMERA_WITH_PARAMS(CAMTYPE_SCRIPTED, vEndPos, vEndRot, 50, TRUE) //RENDER_SCRIPT_CAMS( TRUE, FALSE, 0 ) //SET_CAM_PARAMS(camTriSky, vEndPos, vEndRot, 50, 2700) //SET_CAM_ACTIVE( camTriSky, TRUE ) //RENDER_SCRIPT_CAMS(TRUE, TRUE) //UNUSED_PARAMETER(vEndPos) //UNUSED_PARAMETER(vEndRot) VECTOR vSceneLoc, vSceneOrient // // SWITCH eCurrentTriRace // CASE TRIATHLON_RACE_ALAMO_SEA // vSceneLoc = <<2424.7747, 4284.3188, 34.5886>> // vSceneOrient = <<0.0, 0.0, 257.9987>> // BREAK // CASE TRIATHLON_RACE_VESPUCCI // vSceneLoc = <<-1231.6990, -2049.9199, 12.8787>> // vSceneOrient = <<0.0, 0.0, 254.8048>> // BREAK // CASE TRIATHLON_RACE_IRONMAN // vSceneLoc = <<1593.2665, 3812.9990, 33.4477>> // vSceneOrient = <<0.0, 0.0, 209.8786>> // BREAK // ENDSWITCH SET_ENTITY_AS_MISSION_ENTITY(Tri_Master.oTable, TRUE, TRUE) vSceneLoc = GET_ENTITY_COORDS(Tri_Master.oTable, FALSE) vSceneOrient = <<0.0, 0.0, GET_ENTITY_HEADING(Tri_Master.oTable)>> UNUSED_PARAMETER( camSynchScene ) iSynchSceneIntro = CREATE_SYNCHRONIZED_SCENE( vSceneLoc, vSceneOrient ) camTriSky = CREATE_CAM("DEFAULT_ANIMATED_CAMERA", FALSE) SET_CAM_ACTIVE( camTriSky, TRUE ) RENDER_SCRIPT_CAMS( TRUE, FALSE ) PLAY_SYNCHRONIZED_CAM_ANIM( camTriSky, iSynchSceneIntro, "_table_sign_in_cam", "mini@triathlonintro" ) IF NOT IS_PED_INJURED(PLAYER_PED_ID()) TASK_SYNCHRONIZED_SCENE( PLAYER_PED_ID(), iSynchSceneIntro, "mini@triathlonintro", "_table_sign_in_michael", INSTANT_BLEND_IN, INSTANT_BLEND_OUT ) // Ensure the player isn't holding a weapon at the start of the race. SET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_UNARMED) // NOTE: This looks odd, but at the time it was necessary to avoid the player still // showing the weapon on his hand despite not being equipped. SET_PED_CURRENT_WEAPON_VISIBLE(PLAYER_PED_ID(), FALSE) SET_PED_CURRENT_WEAPON_VISIBLE(PLAYER_PED_ID(), TRUE) ENDIF IF NOT IS_PED_INJURED(Tri_Master.pedTableGuy) CLEAR_PED_TASKS_IMMEDIATELY(Tri_Master.pedTableGuy) TASK_SYNCHRONIZED_SCENE(Tri_Master.pedTableGuy, iSynchSceneIntro, "mini@triathlonintro", "_table_sign_in_ped", INSTANT_BLEND_IN, INSTANT_BLEND_OUT) FORCE_PED_AI_AND_ANIMATION_UPDATE( Tri_Master.pedTableGuy ) ENDIF PLAY_SYNCHRONIZED_ENTITY_ANIM( Tri_Master.oClipboard, iSynchSceneIntro, "_table_sign_in_clipboard", "mini@triathlonintro", 1/*INSTANT_BLEND_IN*/ ) FORCE_ENTITY_AI_AND_ANIMATION_UPDATE( Tri_Master.oClipboard ) DISPLAY_RADAR(FALSE) TEXT_LABEL_23 tlConvo IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL tlConvo = "MGTR_introM" ELIF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN tlConvo = "MGTR_introF" ELIF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_TREVOR tlConvo = "MGTR_introT" ENDIF FLOAT fRand fRand = GET_RANDOM_FLOAT_IN_RANGE(0, 3000) IF fRand < 1000 tlConvo += "2" ELIF fRand < 2000 tlConvo += "3" ENDIF ADD_PED_FOR_DIALOGUE(TriDialog.convoStruct, 3, Tri_Master.pedTableGuy, "TRIRACER1") CREATE_CONVERSATION(TriDialog.convoStruct, "mgtraud", tlConvo, CONV_PRIORITY_VERY_HIGH) RETURN TRUE ELIF NOT IS_CAM_INTERPOLATING(camTriSky) CPRINTLN(DEBUG_TRIATHLON, "[tri_helpers.sch::TRI_ACTIVATE_INTRO_SKY_CAM] intro cam finished interp") RETURN TRUE ENDIF RETURN FALSE ENDFUNC FUNC BOOL TRI_FadeIn_Safe(INT iTime) //DEBUG_MESSAGE("TRI_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 TRI_FadeOut_Safe(INT iTime) //DEBUG_MESSAGE("TRI_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 TRI_Blip_Destroy(BLIP_INDEX& Blip) //DEBUG_MESSAGE("TRI_Blip_Destroy") IF DOES_BLIP_EXIST(Blip) REMOVE_BLIP(Blip) ENDIF ENDPROC FUNC BOOL TRI_Blip_Coord_Create(BLIP_INDEX& Blip, VECTOR vPos, BLIP_SPRITE eBlipSprite = RADAR_TRACE_INVALID, FLOAT fScale = 1.0, INT iCurGate = -1, INT iNumGates = -1) //DEBUG_MESSAGE("TRI_Blip_Coord_Create") TRI_Blip_Destroy(Blip) Blip = ADD_BLIP_FOR_COORD(vPos) IF NOT DOES_BLIP_EXIST(Blip) DEBUG_MESSAGE("TRI_Blip_Coord_Create: Failed to create blip!") RETURN FALSE ENDIF //Set last blip to checkered flag IF (iCurGate = (iNumGates - 1)) SET_BLIP_SPRITE(Blip, RADAR_TRACE_RACEFLAG) ENDIF UNUSED_PARAMETER(eBlipSprite) SET_BLIP_SCALE(Blip, fScale) SET_BLIP_DISPLAY(Blip, DISPLAY_BOTH) 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 TRI_Blip_Entity_Create(BLIP_INDEX& Blip, ENTITY_INDEX Entity, FLOAT fScale = 1.0) //DEBUG_MESSAGE("TRI_Blip_Entity_Create") TRI_Blip_Destroy(Blip) IF IS_ENTITY_DEAD(Entity) DEBUG_MESSAGE("TRI_Blip_Entity_Create: Entity is not alive!") RETURN FALSE ENDIF Blip = ADD_BLIP_FOR_ENTITY(Entity) IF NOT DOES_BLIP_EXIST(Blip) DEBUG_MESSAGE("TRI_Blip_Entity_Create: Failed to create blip!") RETURN FALSE ENDIF SET_BLIP_COLOUR(blip, BLIP_COLOUR_BLUE) BEGIN_TEXT_COMMAND_SET_BLIP_NAME("OFF_OPP") END_TEXT_COMMAND_SET_BLIP_NAME(Blip) SET_BLIP_SCALE(Blip, fScale) CPRINTLN(DEBUG_TRIATHLON, "TRI_Blip_Entity_Create: blip created! fScale: ", fScale) RETURN TRUE ENDFUNC PROC TRI_Chkpnt_Destroy(CHECKPOINT_INDEX& Chkpnt) //DEBUG_MESSAGE("TRI_Chkpnt_Destroy") IF (Chkpnt <> NULL) DELETE_CHECKPOINT(Chkpnt) SET_TRI_CONTROL_FLAG(TCF_UNPATCH_CORONA) Chkpnt = NULL ENDIF ENDPROC FUNC CHECKPOINT_TYPE TRI_Get_ChnkPnt_Type_From_TRI_Type(TRI_RACE_CHECKPOINT_TYPE eChkpntType) SWITCH eChkpntType CASE TRI_CHKPT_TRI_SWIM RETURN CHECKPOINT_RACE_TRI_SWIM_CHEVRON_1 BREAK CASE TRI_CHKPT_TRI_BIKE RETURN CHECKPOINT_RACE_TRI_CYCLE_CHEVRON_1 BREAK CASE TRI_CHKPT_TRI_RUN RETURN CHECKPOINT_RACE_TRI_RUN_CHEVRON_1 BREAK CASE TRI_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 TRI_CHKPT_TRI_FIRST_TRANS // RETURN CHECKPOINT_RACE_TRI_SWIM_LAP RETURN CHECKPOINT_RACE_TRI_SWIM_FLAG BREAK CASE TRI_CHKPT_TRI_SECOND_TRANS // RETURN CHECKPOINT_RACE_TRI_CYCLE_LAP // Prop_MK_Tri_Run RETURN CHECKPOINT_RACE_TRI_CYCLE_FLAG BREAK ENDSWITCH RETURN CHECKPOINT_RACE_GROUND_CHEVRON_1 ENDFUNC // Copied from TRI_Gate.sch FUNC BOOL TRI_Helpers_Check_Condition_Flag(TRI_GATE_STRUCT& sGate, ENUM_TO_INT iFlag) RETURN IS_BITMASK_AS_ENUM_SET(sGate.iGateFlags, iFlag) ENDFUNC //****************************************************************************** //****************************************************************************** // Hint Cam Stuff //****************************************************************************** //****************************************************************************** PROC TRI_INIT_HINT_CAM() TRI_HINT_CAM.bActive = FALSE // TRI_HINT_CAM.Entity = NULL TRI_HINT_CAM.Coord = <<0,0,0>> // TRI_HINT_CAM.HintType = TRI_HINT_CAM.CustomCam = NULL ENDPROC PROC TRI_SET_HINT_CAM_ACTIVE(BOOL bActive) TRI_HINT_CAM.bActive = bActive SET_CINEMATIC_BUTTON_ACTIVE(!bActive) ENDPROC PROC TRI_SET_HINT_CAM_COORD(VECTOR vThisEntity) KILL_RACE_HINT_CAM(localChaseHintCamStruct) TRI_HINT_CAM.Coord = vThisEntity ENDPROC PROC TRI_CLEAR_HINT_CAM_TARGET() TRI_HINT_CAM.Coord = <<0,0,0>> ENDPROC PROC TRI_KILL_HINT_CAM() TRI_INIT_HINT_CAM() SET_CINEMATIC_BUTTON_ACTIVE(TRUE) ENDPROC FUNC BOOL TRI_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 PROC TRI_UPDATE_HINT_CAM() IF NOT TRI_HINT_CAM.bActive EXIT ENDIF // VECTOR vCheckpointToTest = TRI_GET_CURRENT_CHECKPOINT() // IF NOT ARE_VECTORS_EQUAL(TRI_HINT_CAM.Coord, vCheckpointToTest) // TRI_SET_HINT_CAM_COORD(vCheckpointToTest) // IF DOES_CAM_EXIST(TRI_HINT_CAM.CustomCam) // SWITCH TRI_HINT_CAM.HintType // CASE TRI_HINT_FROM_CARGOPLANE // RENDER_SCRIPT_CAMS(FALSE, FALSE) // BREAK // DEFAULT // BREAK // ENDSWITCH // DESTROY_CAM(TRI_HINT_CAM.CustomCam) // ELSE // KILL_RACE_HINT_CAM(localChaseHintCamStruct) // ENDIF // ENDIF IF TRI_IS_HINT_CAM_BUTTON_PRESSED() IF NOT IS_VECTOR_ZERO(TRI_HINT_CAM.Coord) CONTROL_RACE_HINT_CAM(localChaseHintCamStruct, TRI_HINT_CAM.Coord) ELSE DEBUG_MESSAGE("no coord to point at") ENDIF ELSE IF DOES_CAM_EXIST(TRI_HINT_CAM.CustomCam) DESTROY_CAM(TRI_HINT_CAM.CustomCam) ELSE KILL_RACE_HINT_CAM(localChaseHintCamStruct) ENDIF ENDIF ENDPROC /// PURPOSE: Works out which checkpoint type is needed based upon angle between checkpoints FUNC CHECKPOINT_TYPE GET_CHEVRON_CHECKPOINT_TYPE(TRI_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 = TRI_CHKPT_OFFROAD_DEFAULT Chevron1 = CHECKPOINT_RACE_GROUND_CHEVRON_1 Chevron2 = CHECKPOINT_RACE_GROUND_CHEVRON_2 Chevron3 = CHECKPOINT_RACE_GROUND_CHEVRON_3 ELIF sprType = TRI_CHKPT_STUNT_DEFAULT Chevron1 = CHECKPOINT_RACE_AIR_CHEVRON_1 Chevron2 = CHECKPOINT_RACE_AIR_CHEVRON_2 Chevron3 = CHECKPOINT_RACE_AIR_CHEVRON_3 ELIF sprType = TRI_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 = TRI_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 = TRI_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 TRI_Chkpnt_Create(CHECKPOINT_INDEX& Chkpnt, TRI_RACE_CHECKPOINT_TYPE ChkpntType, VECTOR vPos, VECTOR vPointAt, FLOAT fScale = TRI_GATE_CHKPNT_SCL) FUNC BOOL TRI_Chkpnt_Create(VECTOR vPrevGate, TRI_GATE_STRUCT& sGate, VECTOR vPointAt, FLOAT fScale = TRI_GATE_CHKPNT_SCL) CDEBUG1LN(DEBUG_TRIATHLON, "[TRI_Chkpnt_Create] Function called.") vPrevGate = vPrevGate CHECKPOINT_TYPE curCheckpointType TRI_Chkpnt_Destroy(sGate.Chkpnt) sGate.vHeading = vPointAt INT iRed, iGreen, iBlue, iUnusedAlpha IF sGate.eChkpntType != TRI_CHKPT_STUNT_DEFAULT AND sGate.eChkpntType != TRI_CHKPT_STUNT_STUNT AND sGate.eChkpntType != TRI_CHKPT_STUNT_FINISH AND sGate.eChkpntType != TRI_CHKPT_TRI_SWIM AND sGate.eChkpntType != TRI_CHKPT_OFFROAD_DEFAULT AND NOT TRI_Helpers_Check_Condition_Flag(sGate, TRI_RACE_GATE_FLAG_DO_NOT_SNAP_TO_GROUND) FLOAT fGroundZ IF NOT GET_GROUND_Z_FOR_3D_COORD(sGate.vPos, fGroundZ) DEBUG_MESSAGE("TRI_Chkpnt_Create: using default position, probe failed") ELSE FLOAT fHeightMod = 0.5 sGate.vPos.z = fGroundZ + (fHeightMod*fScale) //2.6m is arbitrary...using it from my tunings in drag races - SM ENDIF ENDIF IF sGate.eChkpntType = TRI_CHKPT_TRI_SWIM OR sGate.eChkpntType = TRI_CHKPT_TRI_BIKE OR sGate.eChkpntType = TRI_CHKPT_TRI_RUN 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, sGate.iHUDAlphaAfterPass) sGate.Chkpnt = CREATE_CHECKPOINT(curCheckpointType, sGate.vPos, vPointAt, fScale, iRed, iGreen, iBlue, MG_GET_CHECKPOINT_ALPHA(sGate.vPos)) GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iRed, iGreen, iBlue, iUnusedAlpha) SET_CHECKPOINT_RGBA2(sGate.Chkpnt, iRed, iGreen, iBlue, MG_GET_CHECKPOINT_ALPHA(sGate.vPos)) //CDEBUG1LN(DEBUG_TRIATHLON, "[TRI_Chkpnt_Create] Default chk arrow colors are RED: ", iRed, ", GREEN: ", iGreen, ", BLUE: ", iBlue, ", ALPHA: ", MG_GET_CHECKPOINT_ALPHA(sGate.vPos)) ELSE sGate.Chkpnt = CREATE_CHECKPOINT(TRI_Get_ChnkPnt_Type_From_TRI_Type(sGate.eChkpntType), sGate.vPos, vPointAt, fScale, 254, 207, 12, MG_GET_CHECKPOINT_ALPHA(sGate.vPos)) GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iRed, iGreen, iBlue, sGate.iHUDAlphaAfterPass) SET_CHECKPOINT_RGBA2(sGate.Chkpnt, iRed, iGreen, iBlue, MG_GET_CHECKPOINT_ALPHA(sGate.vPos)) //CDEBUG1LN(DEBUG_TRIATHLON, "[TRI_Chkpnt_Create] Special chk arrow colors are RED: ", iRed, ", GREEN: ", iGreen, ", BLUE: ", iBlue, ", ALPHA: ", MG_GET_CHECKPOINT_ALPHA(sGate.vPos)) ENDIF SET_CHECKPOINT_CYLINDER_HEIGHT(sGate.Chkpnt, 1.6, 1.6, 100) DECAL_RENDERSETTING_ID driDecal SWITCH TRI_Get_ChnkPnt_Type_From_TRI_Type(sGate.eChkpntType) CASE CHECKPOINT_RACE_TRI_SWIM_CHEVRON_1 driDecal = DECAL_RSID_TRIATHLON_SWIMMING BREAK CASE CHECKPOINT_RACE_TRI_CYCLE_CHEVRON_1 driDecal = DECAL_RSID_TRIATHLON_CYCLING BREAK CASE CHECKPOINT_RACE_TRI_RUN_CHEVRON_1 driDecal = DECAL_RSID_TRIATHLON_RUNNING BREAK CASE CHECKPOINT_RACE_TRI_RUN_FLAG driDecal = DECAL_RSID_TRIATHLON_RUNNING BREAK CASE CHECKPOINT_RACE_TRI_SWIM_FLAG driDecal = DECAL_RSID_TRIATHLON_SWIMMING BREAK CASE CHECKPOINT_RACE_TRI_CYCLE_FLAG driDecal = DECAL_RSID_TRIATHLON_CYCLING BREAK ENDSWITCH STRING sDecal SWITCH TRI_Get_ChnkPnt_Type_From_TRI_Type(sGate.eChkpntType) CASE CHECKPOINT_RACE_TRI_SWIM_CHEVRON_1 sDecal = "Corona_Marker" BREAK CASE CHECKPOINT_RACE_TRI_CYCLE_CHEVRON_1 sDecal = "Corona_Marker" BREAK CASE CHECKPOINT_RACE_TRI_RUN_CHEVRON_1 sDecal = "Corona_Marker" BREAK CASE CHECKPOINT_RACE_TRI_RUN_FLAG sDecal = "Corona_Marker" BREAK CASE CHECKPOINT_RACE_TRI_SWIM_FLAG sDecal = "Corona_Marker" BREAK CASE CHECKPOINT_RACE_TRI_CYCLE_FLAG sDecal = "Corona_Marker" BREAK ENDSWITCH PATCH_DECAL_DIFFUSE_MAP(driDecal, texCheckPatch, sDecal) IF (sGate.Chkpnt = NULL) CDEBUG1LN(DEBUG_TRIATHLON, "[TRI_Chkpnt_Create] ERROR: FAILED to created checkpoint!") RETURN FALSE ENDIF RETURN TRUE ENDFUNC PROC Remove_Reset_UI() // REMOVE_MINIGAME_INSTRUCTION(TRI_Master.uiInput, ICON_UP) ENDPROC PROC Display_Reset_UI(TRI_RACE_STRUCT& Race, TRI_RACER_STRUCT& Racer, BOOL bRacerIsPlayer) // Setup Scaleform UI for reset/restart. // SHOULDN'T BE DOING THIS. YOU'RE SETTING UP AND UPDATING EVERY FRAME. // SETUP ONCE, UPDATE EVERY FRAME. CDEBUG2LN(DEBUG_TRIATHLON, "Display_Reset_UI :: SPR_UI_RESET") INIT_SIMPLE_USE_CONTEXT(TRI_Master.uiInput, FALSE, FALSE, TRUE, TRUE) ADD_SIMPLE_USE_CONTEXT_INPUT(TRI_Master.uiInput, "SPR_UI_RESET", FRONTEND_CONTROL, INPUT_FRONTEND_ACCEPT) ADD_SIMPLE_USE_CONTEXT_INPUT(TRI_Master.uiInput, "SPR_UI_QUIT", FRONTEND_CONTROL, INPUT_FRONTEND_Y) ADD_SIMPLE_USE_CONTEXT_INPUT(TRI_Master.uiInput, "SPR_UI_RESTART", FRONTEND_CONTROL, INPUT_FRONTEND_X) SET_SIMPLE_USE_CONTEXT_FULLSCREEN(TRI_Master.uiInput, TRUE) // If racer is player, display reset/restart options. IF bRacerIsPlayer UPDATE_SIMPLE_USE_CONTEXT(TRI_Master.uiInput) IF IS_CONTROL_JUST_PRESSED( FRONTEND_CONTROL, INPUT_FRONTEND_ACCEPT) // Reset vehicle. Remove_Reset_UI(Race) Racer.eReset = TRI_RACER_RESET_FADE_OUT ELIF IS_CONTROL_JUST_PRESSED( FRONTEND_CONTROL, INPUT_FRONTEND_RLEFT) // Restart race. SET_TRI_CONTROL_FLAG(TCF_RACE_RESTARTING) Remove_Reset_UI(Race) Racer.eReset = TRI_RACER_RESET_FADE_OUT ELIF IS_CONTROL_JUST_PRESSED( FRONTEND_CONTROL, INPUT_FRONTEND_RUP) CLEAR_TRI_CONTROL_FLAG(TCF_RACE_RESTARTING) Remove_Reset_UI(Race) IF (TRI_Master.eRaceType = TRI_RACE_TYPE_OFFROAD) TRI_Master.iRaceCur = -1 //forcing a quit here as there is no menu for offroad races Racer.eReset = TRI_RACER_QUIT_FADE_IN ELSE DEBUG_MESSAGE("Quitting from rest UI, going to RACER_QUIT_FADE_OUT") Racer.eReset = TRI_RACER_QUIT_FADE_OUT ENDIF ENDIF ENDIF ENDPROC PROC TRI_RESET_DO_VEHICLE_CHECKS(TRI_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 (TRI_Master.eRaceType = TRI_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) SET_TRI_CONTROL_FLAG(TCF_TRI_MOUNTED) ENDIF ENDIF IF IS_TRI_CONTROL_FLAG_SET(TCF_TRI_MOUNTED) IF (Race.sGate[Race.Racer[0].iGateCur].eChkpntType = TRI_CHKPT_TRI_BIKE) OR (Race.sGate[Race.Racer[0].iGateCur].eChkpntType = TRI_CHKPT_TRI_SECOND_TRANS) IF NOT IS_MESSAGE_BEING_DISPLAYED() PRINT_NOW_ONCE("SPR_HELP_DAMG", 5000, 0, TRI_HELP_BIT, TRI_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, TRI_HELP_BIT, TRI_DAMG_HELP) ENDIF ENDIF IF (TRI_Master.eRaceType = TRI_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, TRI_HELP_BIT, TRI_DAMG_HELP) ENDIF ENDIF ENDPROC PROC TRI_RESET_DO_DISTANCE_TO_RACE_LINE_CHECKS(TRI_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 = TRI_Master.vDefRcrPos ENDIF // Check distance between race start and first gate FLOAT fWarnDist = GET_DISTANCE_BETWEEN_COORDS(vCurGatePos, vPrevGatePos) FLOAT fFailDist = fWarnDist SWITCH TRI_Master.eRaceType CASE TRI_RACE_TYPE_OFFROAD IF (Race.Racer[0].iGateCur = 0) //first gate fWarnDist += 10.0 fFailDist += 100.0 ELSE fWarnDist += 50.0 fFailDist += 300.0 ENDIF BREAK CASE TRI_RACE_TYPE_PLANE IF (Race.Racer[0].iGateCur = 0) // at start of race fWarnDist += 200.0 fFailDist += 750.0 ELSE fWarnDist += 200.0 fFailDist += 9000 ENDIF BREAK CASE TRI_RACE_TYPE_TRIATHLON IF (Race.Racer[0].iGateCur = 0) // at start of race fWarnDist += 10.0 fFailDist += 60.0 ELSE IF NOT IS_ENTITY_DEAD(Race.Racer[0].Driver) IF IS_PED_IN_ANY_VEHICLE(Race.Racer[0].Driver) fWarnDist += 20.0 fFailDist += 170.0 ELSE fWarnDist += 20.0 fFailDist += 70.0 ENDIF ENDIF ENDIF BREAK ENDSWITCH VECTOR vPlayerPosition = GET_ENTITY_COORDS(Race.Racer[0].Driver) VECTOR vNearestPos = GET_CLOSEST_POINT_ON_LINE(vPlayerPosition, vPrevGatePos, vCurGatePos) FLOAT fPlayerDistance = GET_DISTANCE_BETWEEN_COORDS(vNearestPos, vPlayerPosition) BOOL bWarningDist = (fPlayerDistance >= fWarnDist) BOOL bFailureDist = (fPlayerDistance >= fFailDist) IF (TRI_Master.eRaceType = TRI_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 CPRINTLN(DEBUG_TRIATHLON, "Player has gone too far from race, going to FAIL OVER") IF (TRI_Master.eRaceType = TRI_RACE_TYPE_TRIATHLON) AND IS_THIS_PRINT_BEING_DISPLAYED("TRI_LEAVE_VEH") CLEAR_THIS_PRINT("TRI_LEAVE_VEH") CPRINTLN(DEBUG_TRIATHLON, "Clearing TRI_LEAVE_VEH message") ENDIF RESTART_TIMER_NOW(exitTimer) CLEAR_TRI_CONTROL_FLAG(TCF_FAIL_CHECKING) CPRINTLN(DEBUG_TRIATHLON, "RESET_TUTORIAL: TCF_FAIL_CHECKING cleared") Race.Racer[0].eReset = TRI_RACER_RESET_FAIL_OVER Race.FailString = "SPR_HELP_FAIL" //IF fPlayerDistance <= (fFailDist - 15) //make sure we're a good distance away so we dont stack msgs // PRINT_NOW("SPR_HELP_FAIL", 5000, 0) //ENDIF ELSE // Act on warning distance IF bWarningDist IF (TRI_Master.eRaceType = TRI_RACE_TYPE_TRIATHLON) IF NOT IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("SPR_HELP_DIST_2") CLEAR_HELP() PRINT_HELP_FOREVER("SPR_HELP_DIST_2") ADD_TRI_NEWS_EVENT(TRNE_PLAYER_MISSED_CHECKPT) CPRINTLN( DEBUG_TRIATHLON, "Adding missed checkpoint event." ) ENDIF ELSE IF fPlayerDistance <= (fFailDist - 15) //make sure we're a good distance away so we dont stack msgs IF NOT IS_HELP_MESSAGE_BEING_DISPLAYED() PRINT_HELP("SPR_HELP_DIST") ENDIF ENDIF 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, TRI_HELP_BIT, TRI_WARN_HELP) ENDIF ELSE CLEAR_THIS_PRINT("SPR_HELP_WARN") IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("SPR_HELP_DIST_2") CLEAR_HELP() ENDIF IF IS_BITMASK_AS_ENUM_SET(TRI_HELP_BIT, TRI_WARN_HELP) CLEAR_BITMASK_AS_ENUM(TRI_HELP_BIT, TRI_WARN_HELP) DEBUG_MESSAGE("RESET TUTORIAL: Clearing global WARN DIST BIT") ENDIF ENDIF ENDIF //if we want to see where the intersection is in the world // #IF IS_DEBUG_BUILD // SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(TRUE) // DRAW_DEBUG_SPHERE(vNearestPos, 1.0) // #ENDIF ENDPROC // ---------------------------------- // RESET TUTORIAL // FAIL CASE // ---------------------------------- PROC RESET_TUTORIAL(TRI_RACE_STRUCT& Race) IF IS_TRI_CONTROL_FLAG_SET(TCF_FAIL_CHECKING) TRI_RESET_DO_DISTANCE_TO_RACE_LINE_CHECKS(Race) TRI_RESET_DO_VEHICLE_CHECKS(Race) ENDIF ENDPROC // EXIT VEHICLE FAILURE PROC EXIT_VEHICLE_FAILURE(TRI_RACE_STRUCT& Race, BLIP_INDEX& blipVeh) // TRIATHLON IF (TRI_Master.eRaceType = TRI_RACE_TYPE_TRIATHLON) // check if the player has gotten on the bike before failchecking it IF NOT IS_ENTITY_DEAD(Race.Racer[0].Vehicle) IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), Race.Racer[0].Vehicle) SET_TRI_CONTROL_FLAG(TCF_TRI_MOUNTED) ENDIF ENDIF IF IS_TRI_CONTROL_FLAG_SET(TCF_TRI_MOUNTED) IF (Race.sGate[Race.Racer[0].iGateCur].eChkpntType = TRI_CHKPT_TRI_BIKE) OR (Race.sGate[Race.Racer[0].iGateCur].eChkpntType = TRI_CHKPT_TRI_SECOND_TRANS) //DEBUG_MESSAGE("Inside Vehicle check for tri") IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), Race.Racer[0].Vehicle) FLOAT fDist = VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(Race.Racer[0].Vehicle)) IF fDist > MAX_DISTANCE_FROM_BIKE * MAX_DISTANCE_FROM_BIKE IF NOT DOES_BLIP_EXIST(blipVeh) blipVeh = ADD_BLIP_FOR_ENTITY(Race.Racer[0].Vehicle) SET_BLIP_COLOUR(blipVeh, BLIP_COLOUR_BLUE) CPRINTLN(DEBUG_TRIATHLON, "ADD_BLIP_FOR_ENTITY(Race.Racer[0].Vehicle)") ENDIF IF NOT IS_TIMER_STARTED(ExitVehicleTimer) START_TIMER_NOW_SAFE(ExitVehicleTimer) ELSE IF (GET_TIMER_IN_SECONDS(ExitVehicleTimer) >= 10.0) PRINT_NOW_ONCE("SPR_TXIT_WARN", 15000, 0, TRI_HELP_BIT, TRI_TXIT_WARN) ENDIF IF (GET_TIMER_IN_SECONDS(ExitVehicleTimer) >= 35.0) // PRINT_NOW_ONCE("SPR_TXIT_FAIL", 15000, 0, TRI_HELP_BIT, TRI_TXIT_FAIL) DEBUG_MESSAGE("Failed to get back into vehicle") RESTART_TIMER_NOW(exitTimer) CANCEL_TIMER(ExitVehicleTimer) // RESTART_TIMER_NOW(ExitVehicleTimer) IF DOES_BLIP_EXIST(blipVeh) REMOVE_BLIP(blipVeh) 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 CLEAR_TRI_CONTROL_FLAG(TCF_FAIL_CHECKING) Race.FailString = "SPR_TXIT_FAIL" DEBUG_MESSAGE("EXIT_VEHICLE_FAILURE.4: TCF_FAIL_CHECKING cleared") Race.Racer[0].eReset = TRI_RACER_RESET_FAIL_OVER ENDIF ENDIF ENDIF ELSE IF DOES_BLIP_EXIST(blipVeh) REMOVE_BLIP(blipVeh) ENDIF CANCEL_TIMER(ExitVehicleTimer) IF IS_BITMASK_AS_ENUM_SET(TRI_HELP_BIT, TRI_TXIT_WARN) CLEAR_BITMASK_AS_ENUM(TRI_HELP_BIT, TRI_TXIT_WARN) ENDIF IF IS_BITMASK_AS_ENUM_SET(TRI_HELP_BIT, TRI_TXIT_FAIL) CLEAR_BITMASK_AS_ENUM(TRI_HELP_BIT, TRI_TXIT_FAIL) ENDIF ENDIF ELSE IF DOES_BLIP_EXIST(blipVeh) REMOVE_BLIP(blipVeh) CPRINTLN(DEBUG_TRIATHLON, "REMOVE_BLIP(blipVeh)") ENDIF CLEAR_TRI_CONTROL_FLAG(TCF_TRI_MOUNTED) ENDIF ENDIF ENDIF ENDPROC // DEAD VEHICLE FAILURE PROC Dead_Race_Vehicle(TRI_RACE_STRUCT& Race, BLIP_INDEX& blipVeh) IF IS_TRI_CONTROL_FLAG_SET(TCF_FAIL_CHECKING) IF (TRI_Master.eRaceType = TRI_RACE_TYPE_TRIATHLON) AND (Race.sGate[Race.Racer[0].iGateCur].eChkpntType != TRI_CHKPT_TRI_BIKE) AND (Race.sGate[Race.Racer[0].iGateCur].eChkpntType != TRI_CHKPT_TRI_SECOND_TRANS) EXIT ENDIF IF (GET_ENTITY_HEALTH(Race.Racer[0].Vehicle) < 5) // Set failcase to false // PRINT_NOW_ONCE("SPR_RETR_DES", 10000, 0, TRI_HELP_BIT, TRI_RETURN_FAIL) RESTART_TIMER_NOW(exitTimer) IF DOES_BLIP_EXIST(blipVeh) REMOVE_BLIP(blipVeh) 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: TCF_FAIL_CHECKING cleared") CLEAR_TRI_CONTROL_FLAG(TCF_FAIL_CHECKING) Race.FailString = "SPR_RETR_DES" Race.Racer[0].eReset = TRI_RACER_RESET_FAIL_OVER ENDIF ENDIF ENDPROC FUNC BOOL IS_PLAYER_ON_TRI_BIKE() IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) VEHICLE_INDEX vehRacerIsOn = GET_VEHICLE_PED_IS_USING(PLAYER_PED_ID()) IF IS_VEHICLE_MODEL(vehRacerIsOn, TRIBIKE) OR IS_VEHICLE_MODEL(vehRacerIsOn, TRIBIKE2) OR IS_VEHICLE_MODEL(vehRacerIsOn, TRIBIKE3) RETURN TRUE ELSE RETURN FALSE ENDIF ENDIF RETURN FALSE ENDFUNC //TODO //Ideally tri would have some sort of main fail function liek UPDATE_FAIL_CONDITIONS bur for now following the conventions in this script PROC vehicleFailure(TRI_RACE_STRUCT& Race) IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID()) IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) IF NOT IS_PLAYER_ON_TRI_BIKE() DEBUG_MESSAGE("vehicleFailure = RI_RACER_RESET_FAIL_OVER") Race.FailString = "SPR_EXIT_FAIL2" Race.Racer[0].eReset = TRI_RACER_RESET_FAIL_OVER ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: /// Check if player vehicle has entered water, and reset player accordingly. PROC waterFailure(TRI_RACE_STRUCT& Race) IF (TRI_Master.eRaceType = TRI_RACE_TYPE_OFFROAD) IF NOT IS_ENTITY_DEAD(Race.Racer[0].Vehicle) IF IS_ENTITY_IN_WATER(Race.Racer[0].Vehicle) IF NOT IS_TIMER_STARTED(waterTimer) START_TIMER_NOW_SAFE(waterTimer) DEBUG_MESSAGE("Started water Timer") ELSE IF IS_PED_IN_VEHICLE(Race.Racer[0].Driver, Race.Racer[0].Vehicle) IF (IS_VEHICLE_MODEL(Race.Racer[0].Vehicle, SANCHEZ)) IF IS_VEHICLE_ON_ALL_WHEELS(Race.Racer[0].Vehicle) RESTART_TIMER_NOW(waterTimer) ELIF (GET_TIMER_IN_SECONDS(waterTimer) >= 2.75) RESTART_TIMER_NOW(waterTimer) RESTART_TIMER_NOW(exitTimer) DEBUG_MESSAGE("waterFailure: TCF_FAIL_CHECKING cleared") CLEAR_TRI_CONTROL_FLAG(TCF_FAIL_CHECKING) Race.Racer[0].eReset = TRI_RACER_RESET_FADE_OUT DEBUG_MESSAGE("Moving to TRI_RACER_RESET_FADE_OUT") ENDIF ELSE IF IS_VEHICLE_ON_ALL_WHEELS(Race.Racer[0].Vehicle) RESTART_TIMER_NOW(waterTimer) ELIF (GET_TIMER_IN_SECONDS(waterTimer) >= 1.5) RESTART_TIMER_NOW(waterTimer) RESTART_TIMER_NOW(exitTimer) CLEAR_TRI_CONTROL_FLAG(TCF_FAIL_CHECKING) DEBUG_MESSAGE("WaterFailure.2: TCF_FAIL_CHECKING cleared") Race.Racer[0].eReset = TRI_RACER_RESET_FADE_OUT DEBUG_MESSAGE("Moving to TRI_RACER_RESET_FADE_OUT") ENDIF ENDIF ELSE IF (GET_TIMER_IN_SECONDS(waterTimer) >= 1.5) RESTART_TIMER_NOW(waterTimer) RESTART_TIMER_NOW(exitTimer) CLEAR_TRI_CONTROL_FLAG(TCF_FAIL_CHECKING) DEBUG_MESSAGE("waterFailure.3: TCF_FAIL_CHECKING cleared") Race.Racer[0].eReset = TRI_RACER_RESET_FADE_OUT DEBUG_MESSAGE("Moving to TRI_RACER_RESET_FADE_OUT") ENDIF ENDIF ENDIF ELIF IS_TIMER_STARTED(waterTimer) RESTART_TIMER_NOW(waterTimer) ENDIF ENDIF ENDIF IF (TRI_Master.eRaceType = TRI_RACE_TYPE_TRIATHLON) IF (Race.sGate[Race.Racer[0].iGateCur].eChkpntType = TRI_CHKPT_TRI_BIKE) OR (Race.sGate[Race.Racer[0].iGateCur].eChkpntType = TRI_CHKPT_TRI_SECOND_TRANS) IF DOES_ENTITY_EXIST(Race.Racer[0].Vehicle) //CPRINTLN(DEBUG_TRIATHLON, "[TRI_Helpers.sch->waterFailure] Player's bike EXISTS.") IF IS_ENTITY_IN_WATER(Race.Racer[0].Vehicle) //CPRINTLN(DEBUG_TRIATHLON, "[TRI_Helpers.sch->waterFailure] Player's bike is IN WATER.") IF NOT IS_TIMER_STARTED(waterTimer) //CPRINTLN(DEBUG_TRIATHLON, "[TRI_Helpers.sch->waterFailure] Water time has NOT been started. Starting water timer.") START_TIMER_NOW_SAFE(waterTimer) ENDIF //CPRINTLN(DEBUG_TRIATHLON, "[TRI_Helpers.sch->waterFailure] Player's bike is in WATER. Check if player is on bike.") IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), Race.Racer[0].Vehicle) //CPRINTLN(DEBUG_TRIATHLON, "[TRI_Helpers.sch->waterFailure] Player is ON THE BIKE. Restarting water timer.") RESTART_TIMER_NOW(waterTimer) ELIF (GET_TIMER_IN_SECONDS(waterTimer) >= 1.5) //CPRINTLN(DEBUG_TRIATHLON, "[TRI_Helpers.sch->waterFailure] Player is NOT ON THE BIKE. Not fail-checking anymore.") CPRINTLN(DEBUG_TRIATHLON, "waterFailure.4: TCF_FAIL_CHECKING cleared") CLEAR_TRI_CONTROL_FLAG(TCF_FAIL_CHECKING) Race.Racer[0].eReset = TRI_RACER_RESET_FADE_OUT ENDIF ELIF IS_TIMER_STARTED(waterTimer) //CPRINTLN(DEBUG_TRIATHLON, "[TRI_Helpers.sch->waterFailure] Player's bike is NOT IN WATER. Restarting water timer.") RESTART_TIMER_NOW(waterTimer) ENDIF ELSE CPRINTLN(DEBUG_TRIATHLON, "[TRI_Helpers.sch->waterFailure] Player's bike does NOT EXIST.") ENDIF ENDIF ENDIF ENDPROC // WANTED FAILURE PROC wantedFailure(TRI_RACE_STRUCT& Race) // Failcheck for illegal stuffs IF TRI_Master.eRaceType <> TRI_RACE_TYPE_PLANE IF (GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0) CPRINTLN(DEBUG_TRIATHLON, "Wanted Failure: Player is wanted.") CPRINTLN(DEBUG_TRIATHLON, "Player's wanted level is: ", GET_PLAYER_WANTED_LEVEL(PLAYER_ID())) // PRINT_NOW("SPR_HELP_WANT", 5000, 0) 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(exitTimer) Race.FailString = "SPR_HELP_WANT" CLEAR_TRI_CONTROL_FLAG(TCF_FAIL_CHECKING) CPRINTLN(DEBUG_TRIATHLON, "wantedFailure: TCF_FAIL_CHECKING cleared") Race.Racer[0].eReset = TRI_RACER_RESET_FAIL_OVER ELIF GET_MAX_WANTED_LEVEL() = 0 SET_MAX_WANTED_LEVEL(6) //setting this in case its been set too low. ENDIF IF IS_PED_SHOOTING(PLAYER_PED_ID()) SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 1) SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID()) CPRINTLN(DEBUG_TRIATHLON, "Wanted Failcase: Player has fired weapon, set wanted 1") ENDIF IF TRI_Master.eRaceType = TRI_RACE_TYPE_OFFROAD IF NOT IS_PED_INJURED(PLAYER_PED_ID()) IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) IF HAS_PLAYER_DAMAGED_AT_LEAST_ONE_PED(PLAYER_ID()) INT i PED_INDEX injuredPed //check for killed peds who arent mission entities IF Has_Ped_Been_Killed() REPEAT Get_Number_Of_Ped_Killed_Events() i IF DOES_ENTITY_EXIST(Get_Index_Of_Killed_Ped(i)) injuredPed = GET_PED_INDEX_FROM_ENTITY_INDEX(Get_Index_Of_Killed_Ped(i)) IF injuredPed <> PLAYER_PED_ID() AND HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(injuredPed, PLAYER_PED_ID()) SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 1) SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID()) CPRINTLN(DEBUG_TRIATHLON, "Wanted Failcase: Player has killed a ped with a car, set wanted 1") CLEAR_PLAYER_HAS_DAMAGED_AT_LEAST_ONE_PED(PLAYER_ID()) EXIT ENDIF ENDIF ENDREPEAT ENDIF //check for injured peds who arent mission entities IF Has_Ped_Been_Injured() REPEAT Get_Number_Of_Ped_Injured_Events() i IF DOES_ENTITY_EXIST(Get_Index_Of_Injured_Ped(i)) injuredPed = GET_PED_INDEX_FROM_ENTITY_INDEX(Get_Index_Of_Injured_Ped(i)) IF injuredPed <> PLAYER_PED_ID() AND HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(injuredPed, PLAYER_PED_ID()) IF NOT IS_ENTITY_A_MISSION_ENTITY(injuredPed) SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 1) SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID()) CPRINTLN(DEBUG_TRIATHLON, "Wanted Failcase: Player has injured a ped with a car, set wanted 1") CLEAR_PLAYER_HAS_DAMAGED_AT_LEAST_ONE_PED(PLAYER_ID()) ENDIF ENDIF ENDIF ENDREPEAT ENDIF ENDIF ENDIF ENDIF ELSE IF NOT IS_PED_INJURED(PLAYER_PED_ID()) IF HAS_PLAYER_DAMAGED_AT_LEAST_ONE_PED(PLAYER_ID()) IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) VEHICLE_INDEX vehRacerIsOn = GET_VEHICLE_PED_IS_USING(Race.Racer[0].Driver) IF NOT (IS_VEHICLE_MODEL( vehRacerIsOn, TRIBIKE) OR IS_VEHICLE_MODEL( vehRacerIsOn, TRIBIKE2) OR IS_VEHICLE_MODEL( vehRacerIsOn, TRIBIKE3)) SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), 1) SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID()) CPRINTLN(DEBUG_TRIATHLON, "Wanted Failcase: Player has hit a ped with a car, set wanted 1") ENDIF ENDIF CLEAR_PLAYER_HAS_DAMAGED_AT_LEAST_ONE_PED(PLAYER_ID()) ENDIF ENDIF ENDIF ELSE IF (GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0) CLEAR_PLAYER_WANTED_LEVEL(PLAYER_ID()) ENDIF ENDIF ENDPROC // ----------------------------------- // PLACEMENT PROCS/FUNCTIONS // ----------------------------------- PROC TRI_GetRelPos_Ground_Side(VECTOR& vRelPos, FLOAT fDist) //DEBUG_MESSAGE("TRI_GetRelPos_Ground_Side") VECTOR vSide = <<1.0, 0.0, 0.0>> vSide = vSide * fDist vRelPos = vRelPos + vSide ENDPROC PROC TRI_GetRelPos_Ground_Fwd(VECTOR& vRelPos, FLOAT fDist) //DEBUG_MESSAGE("TRI_GetRelPos_Ground_Fwd") VECTOR vFwd = <<0.0, 1.0, 0.0>> vFwd = vFwd * fDist vRelPos = vRelPos + vFwd ENDPROC PROC TRI_GetRelPos_Ground_Up(VECTOR& vRelPos, FLOAT fDist) //DEBUG_MESSAGE("TRI_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 TRI_GetRelPos_Entity_Side(ENTITY_INDEX Entity, VECTOR& vRelPos, FLOAT fDist, BOOL bAbsolute) //DEBUG_MESSAGE("TRI_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 TRI_GetRelPos_Entity_Fwd(ENTITY_INDEX Entity, VECTOR& vRelPos, FLOAT fDist, BOOL bAbsolute) //DEBUG_MESSAGE("TRI_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 TRI_GetRelPos_Entity_Up(ENTITY_INDEX Entity, VECTOR& vRelPos, FLOAT fDist, BOOL bAbsolute) //DEBUG_MESSAGE("TRI_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 TRI_GetRelPos_Coord_Side(VECTOR vCoord1, VECTOR vCoord2, VECTOR& vRelPos, FLOAT fDist, BOOL bAbsolute) //DEBUG_MESSAGE("TRI_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 TRI_GetRelPos_Coord_Fwd(VECTOR vCoord1, VECTOR vCoord2, VECTOR& vRelPos, FLOAT fDist, BOOL bAbsolute) //DEBUG_MESSAGE("TRI_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 TRI_GetRelPos_Coord_Up(VECTOR vCoord1, VECTOR& vRelPos, FLOAT fDist, BOOL bAbsolute) //DEBUG_MESSAGE("TRI_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. /// /// RETURNS: /// BOOL - Countdown still displaying. FUNC BOOL TRI_Countdown_Display(TRI_DISPLAY_STRUCT& Display) SWITCH(eCountdownStage) CASE TRI_COUNTDOWN_STAGE_INIT START_TIMER_NOW_SAFE(Display.tCnt) SET_MINIGAME_COUNTDOWN_UI_NUMBER(TRI_CountDownUI, 3) eCountdownStage = TRI_COUNTDOWN_RUN BREAK CASE TRI_COUNTDOWN_RUN IF TIMER_DO_WHEN_READY(Display.tCnt, 1) UPDATE_MINIGAME_COUNTDOWN_UI(TRI_CountDownUI) eCountdownStage = TRI_COUNTDOWN_STAGE_WAIT ENDIF BREAK CASE TRI_COUNTDOWN_STAGE_WAIT IF UPDATE_MINIGAME_COUNTDOWN_UI(TRI_CountDownUI, FALSE) RETURN FALSE ENDIF BREAK RETURN TRUE ENDSWITCH // Countdown still displaying. RETURN TRUE ENDFUNC /* FUNC BOOL DEPRECATED_TRI_Countdown_Display(TRI_DISPLAY_STRUCT& Display) //DEBUG_MESSAGE("TRI_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(TRI_UI_CD_NUM_SCALE, TRI_UI_CD_NUM_SCALE) DISPLAY_TEXT_WITH_NUMBER(TRI_UI_CD_NUM_POS_X, TRI_UI_CD_NUM_POS_Y, "TRI_COUNT_NUM", Display.iCnt) IF TIMER_DO_WHEN_READY(Display.tCnt, TRI_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(TRI_UI_CD_GO_SCALE, TRI_UI_CD_GO_SCALE) //DISPLAY_TEXT(TRI_UI_CD_GO_POS_X, TRI_UI_CD_GO_POS_Y, "TRI_COUNT_GO") //IF TIMER_DO_WHEN_READY(Display.tCnt, TRI_UI_CD_GO_TIME) // CANCEL_TIMER(Display.tCnt) RETURN FALSE //ENDIF ENDIF // Countdown still displaying. RETURN TRUE ENDFUNC */ FUNC BOOL TRI_Finish_Display(TRI_DISPLAY_STRUCT& Display) //DEBUG_MESSAGE("TRI_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 TRI_Rank_Display(INT iRank, FLOAT fPosX, FLOAT fPosY, FLOAT fScale) //DEBUG_MESSAGE("TRI_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 TRI_Clock_GetComponents(FLOAT fClock, INT& iMinutes, INT& iSeconds, INT& iMilliSecs) //DEBUG_MESSAGE("TRI_Clock_GetComponents") // Get total milliseconds on clock. INT iTotal = ROUND(fClock * 1000.0) // 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 TRI_Clock_MakeString(FLOAT fClock, FLOAT& fPosX, FLOAT fScale, BOOL bDynamic) //DEBUG_MESSAGE("TRI_Clock_MakeString") // Local variables. TEXT_LABEL_15 szClock INT iMinutes, iSeconds, iMilliSecs FLOAT fNumWidth = TRI_HUD_NUM_WIDTH * fScale FLOAT fClnWidth = TRI_HUD_CLN_WIDTH * fScale // Get clock components (m/s/ms). TRI_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 TRI_Clock_Display(FLOAT fClock, FLOAT fPosX, FLOAT fPosY, FLOAT fScale, BOOL bDynamic) //DEBUG_MESSAGE("TRI_Clock_Display") // Make clock string and offset position to accommodate format (dynamic/static). TRI_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 TRI_PlusMinus_MakeString(FLOAT fPlusMinus, FLOAT& fPosX, FLOAT fScale, BOOL bPlusMinus) //DEBUG_MESSAGE("TRI_PlusMinus_MakeString") // Local variables. TEXT_LABEL_15 szPlusMinus INT iMinutes, iSeconds, iMilliSecs FLOAT fNumWidth = TRI_HUD_NUM_WIDTH * fScale FLOAT fClnWidth = TRI_HUD_CLN_WIDTH * fScale // Get clock components (m/s/ms). TRI_Clock_GetComponents(fPlusMinus, iMinutes, iSeconds, iMilliSecs) // Truncate milliseconds (hundreths). iMilliSecs /= 10 // Start string with a plus/minus accordingly. IF bPlusMinus szPlusMinus = "+" fPosX -= (TRI_HUD_PLS_WIDTH * fScale) ELSE szPlusMinus = "-" fPosX -= (TRI_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 TRI_RadarOverlay_Display(FLOAT fRacerRoll) //DEBUG_MESSAGE("TRI_RadarOverlay_Display") // TODO: Ask Alwyn why this isn't drawing over HUD. // Calculate radar overlay rotation using racer roll. FLOAT fOverlayRot = fRacerRoll * TRI_HUD_RADAR_ROT_SCL // Display radar overlay (sprite). DRAW_SPRITE("PilotSchool", "PlaneRadarOver", TRI_HUD_RADAR_POS_X, TRI_HUD_RADAR_POS_Y, TRI_HUD_RADAR_WIDTH, TRI_HUD_RADAR_HEIGHT, fOverlayRot, 128, 255, 128, 128) ENDPROC // ----------------------------------- // FILE I/O PROCS/FUNCTIONS // ----------------------------------- #IF IS_DEBUG_BUILD FUNC TEXT_LABEL_31 TRI_FileName_MakeString(STRING sFileName) //DEBUG_MESSAGE("TRI_FileName_MakeString") STRING sValid = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789" INT i, j BOOL bStrValid = FALSE BOOL bChrValid = FALSE TEXT_LABEL_31 szFileName TEXT_LABEL_3 szBuf1, szBuf2 REPEAT GET_LENGTH_OF_LITERAL_STRING(sFileName) i bChrValid = FALSE szBuf1 = GET_STRING_FROM_STRING(sFileName, i, i + 1) REPEAT GET_LENGTH_OF_LITERAL_STRING(sValid) j szBuf2 = GET_STRING_FROM_STRING(sValid, j, j + 1) IF ARE_STRINGS_EQUAL(szBuf1, szBuf2) j = GET_LENGTH_OF_LITERAL_STRING(sValid) bChrValid = TRUE ENDIF ENDREPEAT IF bChrValid bStrValid = TRUE szFileName += szBuf1 ELIF bStrValid szBuf1 = "_" szFileName += szBuf1 ENDIF IF (GET_LENGTH_OF_LITERAL_STRING(szFileName) >= 30) i = GET_LENGTH_OF_LITERAL_STRING(sFileName) ENDIF ENDREPEAT IF NOT bStrValid szFileName = "" ENDIF RETURN szFileName ENDFUNC FUNC BOOL TRI_XML_Load(STRING sFileName) //DEBUG_MESSAGE("SPR_XML_Load") IF NOT LOAD_XML_FILE(sFileName) DEBUG_MESSAGE("SPR_XML_Load: Can't open XML file!") RETURN FALSE ENDIF IF (GET_NUMBER_OF_XML_NODES() = 0) DEBUG_MESSAGE("SPR_XML_Load: XML file has zero nodes!") RETURN FALSE ENDIF RETURN TRUE ENDFUNC PROC TRI_XML_GetRootNode(INT& iXMLNodeCnt, INT& iXMLNodeName) //DEBUG_MESSAGE("SPR_XML_GetRootNode") iXMLNodeCnt = 0 iXMLNodeName = GET_HASH_KEY(GET_XML_NODE_NAME()) ENDPROC PROC TRI_XML_GetNextNode(INT& iXMLNodeCnt, INT& iXMLNodeName) //DEBUG_MESSAGE("SPR_XML_GetNextNode") GET_NEXT_XML_NODE() ++iXMLNodeCnt iXMLNodeName = GET_HASH_KEY(GET_XML_NODE_NAME()) ENDPROC PROC TRI_HashKey_PrintString(STRING sString) //DEBUG_MESSAGE("SPR_HashKey_PrintString") PRINTSTRING("STRING - HASHKEY : ") PRINTSTRING(sString) PRINTSTRING(" - ") PRINTINT(GET_HASH_KEY(sString)) PRINTNL() ENDPROC #ENDIF // IS_DEBUG_BUILD // ----------------------------------- // WIDGET PROCS/FUNCTIONS // ----------------------------------- PROC TRI_ChkpntType_Populate(TEXT_LABEL_31& szChkpntType[]) //DEBUG_MESSAGE("TRI_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 TRI_RACE_CHECKPOINT_TYPE TRI_ChkpntType_GetEnum(INT iChkpntType) //DEBUG_MESSAGE("TRI_ChkpntType_GetEnum") TRI_RACE_CHECKPOINT_TYPE eChkpntType SWITCH iChkpntType // Ground Arrow. CASE 0 eChkpntType = TRI_CHKPT_OFFROAD_DEFAULT BREAK // Ground Flag. CASE 1 eChkpntType = TRI_CHKPT_OFFROAD_FINISH BREAK // Air Arrow. CASE 2 eChkpntType = TRI_CHKPT_STUNT_DEFAULT BREAK // Air Flag. CASE 3 eChkpntType = TRI_CHKPT_STUNT_FINISH BREAK // Water Arrow. CASE 4 eChkpntType = TRI_CHKPT_TRI_SWIM BREAK // Water Arrow. CASE 5 eChkpntType = TRI_CHKPT_TRI_BIKE BREAK // Water Arrow. CASE 6 eChkpntType = TRI_CHKPT_TRI_RUN BREAK // Water Flag. CASE 7 eChkpntType = TRI_CHKPT_TRI_FINISH BREAK CASE 8 eChkpntType = TRI_CHKPT_TRI_FIRST_TRANS BREAK CASE 9 eChkpntType = TRI_CHKPT_TRI_SECOND_TRANS BREAK ENDSWITCH RETURN eChkpntType ENDFUNC FUNC INT TRI_ChkpntType_GetIndex(TRI_RACE_CHECKPOINT_TYPE eChkpntType) //DEBUG_MESSAGE("TRI_ChkpntType_GetIndex") INT iChkpntType SWITCH eChkpntType // Ground Arrow. CASE TRI_CHKPT_OFFROAD_DEFAULT iChkpntType = 0 BREAK // Ground Flag. CASE TRI_CHKPT_OFFROAD_FINISH iChkpntType = 1 BREAK // Air Arrow. CASE TRI_CHKPT_STUNT_DEFAULT iChkpntType = 2 BREAK // Air Flag. CASE TRI_CHKPT_STUNT_FINISH iChkpntType = 3 BREAK // Water Arrow. CASE TRI_CHKPT_TRI_SWIM iChkpntType = 4 BREAK // Water Arrow. CASE TRI_CHKPT_TRI_BIKE iChkpntType = 5 BREAK // Water Arrow. CASE TRI_CHKPT_TRI_RUN iChkpntType = 6 BREAK // Water Flag. CASE TRI_CHKPT_TRI_FINISH iChkpntType = 7 BREAK // Water Flag. CASE TRI_CHKPT_TRI_FIRST_TRANS iChkpntType = 8 BREAK // Water Flag. CASE TRI_CHKPT_TRI_SECOND_TRANS iChkpntType = 9 BREAK ENDSWITCH RETURN iChkpntType ENDFUNC FUNC TEXT_LABEL_31 TRI_ChkpntType_GetString(TRI_RACE_CHECKPOINT_TYPE eChkpntType) //DEBUG_MESSAGE("TRI_ChkpntType_GetString") TEXT_LABEL_31 szChkpntType SWITCH eChkpntType // Ground Arrow. CASE TRI_CHKPT_OFFROAD_DEFAULT szChkpntType = "TRI_CHKPT_OFFROAD_DEFAULT" BREAK // Ground Flag. CASE TRI_CHKPT_OFFROAD_FINISH szChkpntType = "TRI_CHKPT_OFFROAD_FINISH" BREAK // Air Arrow. CASE TRI_CHKPT_STUNT_DEFAULT szChkpntType = "TRI_CHKPT_STUNT_DEFAULT" BREAK // Air Flag. CASE TRI_CHKPT_STUNT_FINISH szChkpntType = "TRI_CHKPT_STUNT_FINISH" BREAK // Water Arrow. CASE TRI_CHKPT_TRI_SWIM szChkpntType = "TRI_CHKPT_TRI_SWIM" BREAK // Water Flag. CASE TRI_CHKPT_TRI_BIKE szChkpntType = "TRI_CHKPT_TRI_BIKE" BREAK // Water Arrow. CASE TRI_CHKPT_TRI_RUN szChkpntType = "TRI_CHKPT_TRI_RUN" BREAK // Water Flag. CASE TRI_CHKPT_TRI_FINISH szChkpntType = "TRI_CHKPT_TRI_FINISH" BREAK // Water Flag. CASE TRI_CHKPT_TRI_FIRST_TRANS szChkpntType = "TRI_CHKPT_TRI_FIRST_TRANS" BREAK // Water Flag. CASE TRI_CHKPT_TRI_SECOND_TRANS szChkpntType = "TRI_CHKPT_TRI_SECOND_TRANS" BREAK ENDSWITCH RETURN szChkpntType ENDFUNC PROC TRI_DriverType_Populate(TEXT_LABEL_31& szDriverType[]) //DEBUG_MESSAGE("TRI_DriverType_Populate") szDriverType[0] = "Player" szDriverType[1] = "AI Male" szDriverType[2] = "AI Female" szDriverType[3] = "Triathlon Male" ENDPROC FUNC PED_TYPE TRI_DriverType_GetEnum(INT iDriverType) //DEBUG_MESSAGE("TRI_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 TRI_DriverType_GetIndex(PED_TYPE eDriverType) //DEBUG_MESSAGE("TRI_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 TRI_DriverType_GetString(PED_TYPE eDriverType) //DEBUG_MESSAGE("TRI_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 TRI_DriverModel_Populate(TEXT_LABEL_31& szDriverModel[]) //DEBUG_MESSAGE("TRI_DriverModel_Populate") szDriverModel[0] = "Player" szDriverModel[1] = "AI Male" szDriverModel[2] = "AI Female" szDriverModel[3] = "Triathlon Male" ENDPROC FUNC MODEL_NAMES TRI_DriverModel_GetEnum(INT iDriverModel) //DEBUG_MESSAGE("TRI_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 TRI_DriverModel_GetIndex(MODEL_NAMES eDriverModel) //DEBUG_MESSAGE("TRI_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 TRI_DriverModel_GetString(MODEL_NAMES eDriverModel) //DEBUG_MESSAGE("TRI_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 TRI_VehicleModel_Populate(TEXT_LABEL_31& szVehicleModel[]) //DEBUG_MESSAGE("TRI_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[47] = "On Foot (No Vehicle)" ENDPROC FUNC MODEL_NAMES TRI_VehicleModel_GetEnum(INT iVehicleModel) //DEBUG_MESSAGE("TRI_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 47 eVehicleModel = DUMMY_MODEL_FOR_SCRIPT BREAK ENDSWITCH RETURN eVehicleModel ENDFUNC FUNC INT TRI_VehicleModel_GetIndex(MODEL_NAMES eVehicleModel) //DEBUG_MESSAGE("TRI_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 = 47 BREAK ENDSWITCH RETURN iVehicleModel ENDFUNC FUNC TEXT_LABEL_31 TRI_VehicleModel_GetString(MODEL_NAMES eVehicleModel) //DEBUG_MESSAGE("TRI_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 TRI_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 TRI_RacerName_Populate(TEXT_LABEL_31& szRacerName[]) INT i, j, iLimit INT tempNumbers[10] REPEAT COUNT_OF(szRacerName) i //szRacerName[i] = TRI_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] = TRI_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]=TRI_RacerName_GetString(tempNumbers[i]) ENDREPEAT ENDPROC FUNC TEXT_LABEL TRI_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 /// PURPOSE: /// Task ai to go to next gate position. /// PARAMS: /// Race - /// iDriver - /// iVehicle - /// vGateGoto - /// eChkpntType - /// iRacerIndex - PROC TRI_Race_Racer_Task_Go_To_Next_Gate(TRI_RACE_STRUCT& Race, PED_INDEX iDriver, VEHICLE_INDEX iVehicle, VECTOR vGateGoto, TRI_RACE_CHECKPOINT_TYPE eChkpntType, INT iRacerIndex) CPRINTLN(DEBUG_TRIATHLON, "[tri_helpers.sch::TRI_Race_Racer_Task_Go_To_Next_Gate] ", iRacerIndex) IF NOT IS_ENTITY_DEAD(iDriver) iVehicle = iVehicle eChkpntType = eChkpntType //may need for later TASK_TRI_RACER_TO_FOLLOW_RACE_COURSE(Race, vGateGoto, iRacerIndex) ELSE CPRINTLN(DEBUG_TRIATHLON, "[tri_helpers.sch::TRI_Race_Racer_Task_Go_To_Next_Gate] entity is dead for iRacerIndex ", iRacerIndex) ENDIF ENDPROC PROC TRI_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 TRI_Master.eRaceType = TRI_RACE_TYPE_OFFROAD CDEBUG1LN(DEBUG_SP_RACES, "Scenario group ", sThisGroupName, " does not exist") ELIF TRI_Master.eRaceType = TRI_RACE_TYPE_PLANE CDEBUG1LN(DEBUG_OR_RACES, "Scenario group ", sThisGroupName, " does not exist") ELIF TRI_Master.eRaceType = TRI_RACE_TYPE_TRIATHLON CPRINTLN(DEBUG_TRIATHLON, "Scenario group ", sThisGroupName, " does not exist") ENDIF ENDIF ELSE IF TRI_Master.eRaceType = TRI_RACE_TYPE_OFFROAD CDEBUG1LN(DEBUG_SP_RACES, "String is null or empty!") ELIF TRI_Master.eRaceType = TRI_RACE_TYPE_PLANE CDEBUG1LN(DEBUG_OR_RACES, "String is null or empty!") ELIF TRI_Master.eRaceType = TRI_RACE_TYPE_TRIATHLON CPRINTLN(DEBUG_TRIATHLON, "String is null or empty!") ENDIF ENDIF ENDPROC FUNC BOOL TRI_Master_Choose_Tri_Race() //DEBUG_MESSAGE("TRI_Master_Choose_Race") // Update Choose Race controls. // D-Pad Down - Increment current race. IF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_DOWN) IF (TRI_Master.iRaceCur < (TRI_Master.iRaceCnt - 1)) ++TRI_Master.iRaceCur ENDIF // D-Pad Up - Decrement current race. ELIF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_UP) IF (TRI_Master.iRaceCur > 0) --TRI_Master.iRaceCur ENDIF // A/X Button - Choose current race. ELIF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_ACCEPT) RETURN FALSE // B/O Button - Exit race script. ELIF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_CANCEL) TRI_Master.iRaceCur = -1 RETURN FALSE ENDIF // Display Choose Race heading. SET_TEXT_SCALE(TRI_UI_CR_HEAD_SCALE, TRI_UI_CR_HEAD_SCALE) DISPLAY_TEXT(TRI_UI_CR_HEAD_POS_X, TRI_UI_CR_HEAD_POS_Y, "SPR_CHOOSERACE") // Display Choose Race info (name/rank/time). // TODO: Need some sort of display line limit and scrolling. INT i INT iBestRank FLOAT fBestClockTime REPEAT TRI_Master.iRaceCnt i // Cache Best Rank and Clock Time. iBestRank = TRI_Global_BestRank_Get(i) fBestClockTime = TRI_Global_BestTime_Get(i) // Cache Choose Race info position-y. FLOAT fInfoPosY = TRI_UI_CR_INFO_POS_Y + (i * TRI_UI_CR_INFO_SPC_Y) // Display Choose Race name. IF (i = TRI_Master.iRaceCur) SET_TEXT_COLOUR(255, 255, 0, 255) ENDIF SET_TEXT_SCALE(TRI_UI_CR_INFO_SCALE, TRI_UI_CR_INFO_SCALE) BEGIN_TEXT_COMMAND_DISPLAY_TEXT(TRI_Master.szRaceName[i]) END_TEXT_COMMAND_DISPLAY_TEXT(TRI_UI_CR_INFO_POS_X, fInfoPosY) // Display Choose Race best rank. IF (i = TRI_Master.iRaceCur) SET_TEXT_COLOUR(255, 255, 0, 255) ENDIF IF (iBestRank <= 0) SET_TEXT_SCALE(TRI_UI_CR_INFO_SCALE, TRI_UI_CR_INFO_SCALE) DISPLAY_TEXT(TRI_UI_CR_INFO_POS_X + TRI_UI_CR_INFO_SPC_X1, fInfoPosY, "SPR_PLACE_NA") ELSE TRI_Rank_Display(iBestRank, TRI_UI_CR_INFO_POS_X + TRI_UI_CR_INFO_SPC_X1, fInfoPosY, TRI_UI_CR_INFO_SCALE) ENDIF // Display Choose Race best time. IF (i = TRI_Master.iRaceCur) SET_TEXT_COLOUR(255, 255, 0, 255) ENDIF IF (fBestClockTime <= 0.0) SET_TEXT_SCALE(TRI_UI_CR_INFO_SCALE, TRI_UI_CR_INFO_SCALE) DISPLAY_TEXT(TRI_UI_CR_INFO_POS_X + TRI_UI_CR_INFO_SPC_X2, fInfoPosY, "SPR_CLOCK_NA") ELSE TRI_Clock_Display(fBestClockTime, TRI_UI_CR_INFO_POS_X + TRI_UI_CR_INFO_SPC_X2, fInfoPosY, TRI_UI_LB_INFO_SCALE, FALSE) ENDIF ENDREPEAT // Display Choose Race controls (select/enter/exit). SET_TEXT_SCALE(TRI_UI_CR_SEL_SCALE, TRI_UI_CR_SEL_SCALE) DISPLAY_TEXT(TRI_UI_CR_SEL_POS_X, TRI_UI_CR_SEL_POS_Y, "SPR_UI_SELECT") SET_TEXT_SCALE(TRI_UI_CR_ENT_SCALE, TRI_UI_CR_ENT_SCALE) DISPLAY_TEXT(TRI_UI_CR_ENT_POS_X, TRI_UI_CR_ENT_POS_Y, "SPR_UI_ENTER") SET_TEXT_SCALE(TRI_UI_CR_EXIT_SCALE, TRI_UI_CR_EXIT_SCALE) DISPLAY_TEXT(TRI_UI_CR_EXIT_POS_X, TRI_UI_CR_EXIT_POS_Y, "SPR_UI_EXIT") // Display Choose Race rectangle. DRAW_RECT(TRI_UI_CR_RECT_POS_X, TRI_UI_CR_RECT_POS_Y, TRI_UI_CR_RECT_WIDTH, TRI_UI_CR_RECT_HEIGHT, 0, 0, 0, TRI_UI_CR_RECT_ALPHA) // Choose SPR Race still running. RETURN TRUE ENDFUNC /// PURPOSE: /// Does the waiting around while the player animates during the countdown. /// PARAMS: /// Race - PROC HANDLE_TRI_COUNTDOWN_ANIMS(TRI_RACE_STRUCT &Race) INT p REPEAT Race.iRacerCnt p Race.Racer[p].fAnimWait += GET_FRAME_TIME() IF Race.Racer[p].fAnimWait > ANIM_WAIT_THRESHOLD AND Race.Racer[p].fAnimWait < ANIM_WAIT_THRESHOLD * 3 IF NOT IS_ENTITY_DEAD(Race.Racer[p].Driver) INT iAnim = GET_RANDOM_INT_IN_RANGE(1, 14) STRING sAnim sAnim = PICK_STRING(iAnim = 1, "ig_2_gen_warmup_01", PICK_STRING(iAnim = 2, "ig_2_gen_warmup_02", PICK_STRING(iAnim = 3, "ig_2_gen_warmup_03", PICK_STRING(iAnim = 4, "ig_2_gen_warmup_04", PICK_STRING(iAnim = 5, "ig_2_gen_warmup_05", PICK_STRING(iAnim = 6, "ig_2_gen_warmup_06", PICK_STRING(iAnim = 7, "ig_2_gen_warmup_07", PICK_STRING(iAnim = 8, "ig_2_gen_warmup_08", PICK_STRING(iAnim = 9, "ig_2_gen_warmup_09", PICK_STRING(iAnim = 10, "ig_2_gen_warmup_10", PICK_STRING(iAnim = 11, "ig_2_gen_warmup_11", PICK_STRING(iAnim = 12, "ig_2_gen_warmup_12", "ig_2_gen_warmup_13")))))))))))) TASK_PLAY_ANIM(Race.Racer[p].Driver, "mini@triathlon", sAnim, default, default, default, AF_ABORT_ON_PED_MOVEMENT | AF_EXIT_AFTER_INTERRUPTED) Race.Racer[p].fAnimWait = ANIM_WAIT_THRESHOLD * 5 // make the timer huge so we only do this once. CPRINTLN(DEBUG_TRIATHLON, "[tri_helpers.sch::HANDLE_TRI_COUNTDOWN_ANIMS] Setting iRacer[", p, "] with ", sAnim) ENDIF ENDIF ENDREPEAT ENDPROC FUNC INT TRI_GET_NUM_RACERS_FINISHED( TRI_RACE_STRUCT& race ) INT iIndex INT iRetVal = 0 REPEAT race.iRacerCnt iIndex IF race.Racer[iIndex].Driver <> PLAYER_PED_ID() IF HAS_TRI_RACER_FINISHED_RACE(race, race.Racer[iIndex]) ++iRetVal ENDIF ENDIF ENDREPEAT RETURN iRetVal ENDFUNC PROC TRI_RACE_MANAGE_CHECKPOINT_ALPHAS(TRI_GATE_STRUCT& GateCur, TRI_GATE_STRUCT& GateNxt) INT iRed, iGreen, iBlue, iAlpha IF GateCur.Chkpnt != NULL AND NOT GateCur.bIsFading HUD_COLOURS eColor = MG_GET_RACE_CHECKPOINT_DEFAULT_COLOUR() //HUD_COLOURS eColor = HUD_COLOUR_BLUE 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)) GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iRed, iGreen, iBlue, iAlpha) SET_CHECKPOINT_RGBA2(GateCur.Chkpnt, iRed, iGreen, iBlue, MG_GET_CHECKPOINT_ALPHA(GateCur.vPos)) //CDEBUG1LN(DEBUG_TRIATHLON, "[TRI_RACE_MANAGE_CHECKPOINT_ALPHAS] Current arrow colors are RED: ", iRed, ", GREEN: ", iGreen, ", BLUE: ", iBlue, ", ALPHA: ", MG_GET_CHECKPOINT_ALPHA(GateCur.vPos)) ENDIF //EXIT IF GateNxt.Chkpnt != NULL AND NOT GateNxt.bIsFading HUD_COLOURS eColor = MG_GET_RACE_CHECKPOINT_DEFAULT_COLOUR() //HUD_COLOURS eColor = HUD_COLOUR_BLUE 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)) GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iRed, iGreen, iBlue, iAlpha) SET_CHECKPOINT_RGBA2(GateNxt.Chkpnt, iRed, iGreen, iBlue, MG_GET_CHECKPOINT_ALPHA(GateNxt.vPos)) //CDEBUG1LN(DEBUG_TRIATHLON, "[TRI_RACE_MANAGE_CHECKPOINT_ALPHAS] Next arrow colors are RED: ", iRed, ", GREEN: ", iGreen, ", BLUE: ", iBlue, ", ALPHA: ", MG_GET_CHECKPOINT_ALPHA(GateNxt.vPos)) ENDIF ENDPROC /// PURPOSE: /// Once the player passes a gate, change its color and fade it out. /// PARAMS: /// Race - Contains all race data. PROC TRI_RACE_MANAGE_GATE_FADE_ON_PASS(TRI_RACE_STRUCT& Race, INT iGateIdx) Race.sGate[iGateIdx].iHUDAlphaAfterPass -= 25 CDEBUG1LN(DEBUG_TRIATHLON, "[TRI_RACE_MANAGE_GATE_FADE_ON_PASS] For gate ", iGateIdx, ", iHUDAlphaAfterPass decremented to ", Race.sGate[iGateIdx].iHUDAlphaAfterPass) IF Race.sGate[iGateIdx].iHUDAlphaAfterPass > 0 CDEBUG1LN(DEBUG_TRIATHLON, "[TRI_RACE_MANAGE_GATE_FADE_ON_PASS] Alpha of gate ", iGateIdx, " has NOT reached 0. Updating alpha value on checkpoint and arrow.") SET_CHECKPOINT_RGBA(Race.sGate[iGateIdx].Chkpnt, 255, 255, 255, Race.sGate[iGateIdx].iHUDAlphaAfterPass) SET_CHECKPOINT_RGBA2(Race.sGate[iGateIdx].Chkpnt, 255, 255, 255, Race.sGate[iGateIdx].iHUDAlphaAfterPass) ELSE CDEBUG1LN(DEBUG_TRIATHLON, "[TRI_RACE_MANAGE_GATE_FADE_ON_PASS] Alpha reached 0 with Race.sGate[", iGateIdx, "].iHUDAlphaAfterPass at ", Race.sGate[iGateIdx].iHUDAlphaAfterPass,". Deleting checkpoint.") TRI_Chkpnt_Destroy(Race.sGate[iGateIdx].Chkpnt) Race.sGate[iGateIdx].bIsFading = FALSE ENDIF ENDPROC /// PURPOSE: /// Manage the gates fading once the player passes them. /// PARAMS: /// Race - Contains all race data. PROC TRI_RACE_MANAGE_ALL_GATES_FADE_ON_PASS(TRI_RACE_STRUCT& Race) INT iGateIdx REPEAT Race.iGateCnt iGateIdx IF Race.sGate[iGateIdx].bIsFading CDEBUG1LN(DEBUG_TRIATHLON, "[TRI_RACE_MANAGE_ALL_GATES_FADE_ON_PASS] Gate ", iGateIdx, " is fading.") TRI_RACE_MANAGE_GATE_FADE_ON_PASS(Race, iGateIdx) ENDIF ENDREPEAT ENDPROC // END OF FILE! DO NOT ADD ANYTHING BELOW THIS LINE!