USING "commands_audio.sch" USING "commands_camera.sch" USING "commands_graphics.sch" USING "commands_hud.sch" USING "commands_misc.sch" USING "commands_script.sch" USING "commands_task.sch" USING "commands_fire.sch" USING "model_enums.sch" USING "rage_builtins.sch" USING "script_player.sch" USING "shared_hud_displays.sch" USING "ambience_run_checks.sch" // Race ENUMs ENUM RACE_COURSE RACE_COURSE_NONE, RACE_COURSE_MT_BIKE1, RACE_COURSE_RC_FANATIC2, RACE_COURSE_RC_FANATIC2ALT, RACE_COURSE_RC_FANATIC2ALTB, RACE_COURSE_RC_EXTREME1, RACE_COURSE_END ENDENUM ENUM RACE_VEHICLE_CLASS RACE_VEHICLE_CLASS_NONE, RACE_VEHICLE_CLASS_RC, RACE_VEHICLE_CLASS_RC_CHECKS, RACE_VEHICLE_CLASS_RALLY, RACE_VEHICLE_CLASS_MOTORBIKES, RACE_VEHICLE_CLASS_MUSCLE_CARS, RACE_VEHICLE_CLASS_SUPER_CARS, RACE_VEHICLE_CLASS_CURRENT, RACE_VEHICLE_CLASS_MOUNTAIN_BIKE, RACE_VEHICLE_CLASS_END ENDENUM ENUM RACER_STATUS RACER_STATUS_DEAD, RACER_STATUS_WINNING, RACER_STATUS_LOSING, RACER_STATUS_WON, RACER_STATUS_LOST, RACER_STATUS_FINISHED, RACER_STATUS_END ENDENUM ENUM RACE_GRID_FLYBY_STYLE RG_FLYBY_NONE, RG_FLYBY_LEFT_FRONT_TO_BACK, RG_FLYBY_RIGHT_FRONT_TO_BACK, RG_FLYBY_CENTRE_FRONT_TO_BACK, RG_FLYBY_LEFT_BACK_TO_FRONT, RG_FLYBY_RIGHT_BACK_TO_FRONT, RG_FLYBY_CENTRE_BACK_TO_FRONT, RG_FLYBY_DRAG_BACK_TO_FRONT, RG_FLYBY_END ENDENUM STRUCT RACE_INFO_STRUCT // Position & heading from which the race is generated VECTOR sourcePos FLOAT sourceHeading // Checkpoint positions VECTOR checkPos[40] //AI straight line Distance FLOAT straightLineDist // Number of checkpoints INT totalChecks // Number of laps INT totalLaps // Number of racers INT totalRacers // Player's start position // VECTOR playerPos // Buddy's start position // VECTOR buddyPos // FLOAT buddyHeading // Taxi Drop off position // VECTOR taxiPos // Chosen course RACE_COURSE chosenCourse // String to print in console // TEXT_LABEL_31 raceName // Vehicle CLass RACE_VEHICLE_CLASS raceCLass CAMERA_INDEX raceSourceCam CAMERA_INDEX raceDestCam ENDSTRUCT //Checkpoint size FLOAT checkSize = 20.0 INT prevAlpha CONST_INT TOTAL_NUMBER_OF_RACERS 8 STRUCT RACER_INFO_STRUCT PED_INDEX racer // MODEL_NAMES pedModel VEHICLE_INDEX raceVehicle // MODEL_NAMES vehicleModel // BLIP_INDEX racerBlip // BLIP_INDEX raceVehicleBlip BLIP_INDEX checkBlip BLIP_INDEX nextCheckBlip CHECKPOINT_INDEX checkPoint CHECKPOINT_INDEX PrevCheckPoint VECTOR racerPos // FLOAT racerHeading INT currentCheck INT nextCheck INT currentLap FLOAT currentSpeed FLOAT distanceToNextCheck RACER_STATUS racerStatus ENDSTRUCT FUNC BOOL IS_A_RACE_MISSION_SCRIPT_RUNNING() IF GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(HASH("sp_races")) = 1 RETURN TRUE ENDIF RETURN FALSE ENDFUNC FUNC BOOL IS_PLAYER_ABLE_TO_DRIVE_CURRENT_VEHICLE() IF NOT IS_PED_INJURED(PLAYER_PED_ID()) IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) IF IS_VEHICLE_DRIVEABLE(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())) AND NOT IS_ENTITY_ON_FIRE(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())) IF NOT IS_VEHICLE_MODEL(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), FORKLIFT) IF GET_PED_IN_VEHICLE_SEAT(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())) = PLAYER_PED_ID() RETURN TRUE ENDIF ENDIF ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC FUNC MODEL_NAMES GENERATE_RANDOM_MODEL_FROM_RACE_CLASS(RACE_VEHICLE_CLASS vehicleClass) MODEL_NAMES vehicleModels[24] INT TOTAL_MODELS_IN_CLASS = 0 SWITCH vehicleClass CASE RACE_VEHICLE_CLASS_MOTORBIKES vehicleModels[0] = SANCHEZ vehicleModels[1] = SANCHEZ TOTAL_MODELS_IN_CLASS = 2 BREAK CASE RACE_VEHICLE_CLASS_MUSCLE_CARS vehicleModels[0] = SULTAN // Sultan isn't a muscle car TOTAL_MODELS_IN_CLASS = 7 BREAK CASE RACE_VEHICLE_CLASS_RALLY vehicleModels[0] = TAILGATER TOTAL_MODELS_IN_CLASS = 1 BREAK CASE RACE_VEHICLE_CLASS_SUPER_CARS vehicleModels[0] = INFERNUS TOTAL_MODELS_IN_CLASS = 1 BREAK CASE RACE_VEHICLE_CLASS_RC //vehicleModels[0] = RCBANDITO ///vehicleModels[1] = RCBANDITO TOTAL_MODELS_IN_CLASS = 2 BREAK ENDSWITCH RETURN vehicleModels[GET_RANDOM_INT_IN_RANGE(0, TOTAL_MODELS_IN_CLASS)] ENDFUNC PROC ASSIGN_RACE_CHECKPOINT(RACE_INFO_STRUCT &raceInfo, VECTOR checkPosition) raceInfo.checkPos[raceInfo.totalChecks] = checkPosition raceInfo.totalChecks++ ENDPROC PROC GENERATE_RACE_INFO(RACE_INFO_STRUCT &raceInfo) raceInfo.totalChecks = 0 IF raceInfo.chosenCourse = RACE_COURSE_NONE SCRIPT_ASSERT("GENERATE_RACE_INFO. raceInfo.chosenCourse = RACE_COURSE_NONE. Choose a course prior to generating info.") ENDIF SWITCH raceInfo.chosenCourse CASE RACE_COURSE_MT_BIKE1 raceInfo.raceCLass = RACE_VEHICLE_CLASS_MOUNTAIN_BIKE // raceInfo.raceName = "RR_RC_BS" raceInfo.sourcePos = << -331.1481, 4753.7290, 227.6643 >> raceInfo.sourceHeading = 229.0 raceInfo.totalRacers = 2 ASSIGN_RACE_CHECKPOINT(raceInfo, <<-329.1481, 4749.7290, 228.6643>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-291.5515, 4691.3052, 235.7776 >> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-310.1067, 4684.8662, 246.5917 >> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-415.3808, 4672.3550, 253.3204 >> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-430.9800, 4707.3994, 253.2198 >> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-447.7660, 4737.7837, 244.1033 >> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-502.0252, 4732.6729, 239.5285 >> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-579.2366, 4750.3970, 211.4045>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-622.6068, 4716.0449, 225.8445 >> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-672.1638, 4728.6938, 238.2206 >> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-736.2177, 4783.1631, 226.5020 >> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-795.5958, 4867.9976, 255.8227>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-855.1999, 4865.0620, 289.7517 >> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-876.2197, 4796.1655, 298.3487 >> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-944.4310, 4773.4795, 284.3422 >> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-1026.6361, 4834.1626, 255.4192>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-1070.0287, 4825.0630, 231.3936 >> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-1089.9250, 4804.0610, 216.7211 >> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-1279.2612, 4841.3320, 151.8451 >> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-1375.7675, 4798.2275, 126.2156>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-1467.2419, 4803.9292, 81.1326 >> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-1485.8629, 4750.4497, 58.8107 >> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-1541.9647, 4738.9575, 50.8111 >> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-1581.1320, 4839.4600, 52.7062 >> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-1494.7415, 4971.1670, 46.7483 >> ) raceInfo.totalLaps = 0 raceInfo.straightLineDist = 15 // raceInfo.taxiPos = << -329.4604, 4752.3691, 228.0300 >> // raceInfo.buddyPos = << -329.4604, 4752.3691, 228.0300 >> // raceInfo.buddyHeading = 275 BREAK CASE RACE_COURSE_RC_FANATIC2 raceInfo.raceCLass = RACE_VEHICLE_CLASS_MOUNTAIN_BIKE // raceInfo.raceName = "RC_FAN2" raceInfo.sourcePos = << 376.5668, 1058.3768, 236.1919 >> raceInfo.sourceHeading = 2.9613 raceInfo.totalRacers = 1 ASSIGN_RACE_CHECKPOINT(raceInfo, <<374.2899, 1074.4827, 235.7123>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<362.0448, 1110.6335, 235.1055>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<319.5104, 1161.1849, 235.4029>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<300.0755, 1237.2719, 234.0581>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<269.5442, 1263.0739, 232.5312>> ) //ASSIGN_RACE_CHECKPOINT(raceInfo, <<258.5526, 1218.9199, 228.3669>> ) // Alternate route starts here ASSIGN_RACE_CHECKPOINT(raceInfo, <<240.08, 1180.87, 224.46>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<214.48, 1216.27, 224.59>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<183.42, 1205.29, 224.59>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<188.68, 1187.18, 224.59>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<198.22, 1180.16, 226.01>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<203.38, 1121.57, 224.59>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<260.94, 1135.36, 220.60>> ) //ASSIGN_RACE_CHECKPOINT(raceInfo, <<271.5604, 1140.6415, 220.7155>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<290.6088, 1094.6976, 215.5821>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<309.9068, 1019.8271, 209.4761>> ) raceInfo.totalLaps = 0 raceInfo.straightLineDist = 15 // raceInfo.taxiPos = << 376.5668, 1058.3768, 236.1919 >> // raceInfo.buddyPos = << 376.5668, 1058.3768, 236.1919 >> // raceInfo.buddyHeading = 0 BREAK CASE RACE_COURSE_RC_FANATIC2ALT raceInfo.raceCLass = RACE_VEHICLE_CLASS_MOUNTAIN_BIKE // raceInfo.raceName = "RC_FAN2A" raceInfo.sourcePos = << 857.7981, 1278.2418, 358.1998 >> raceInfo.sourceHeading = 152.4354 raceInfo.totalRacers = 1 // Start of long race ASSIGN_RACE_CHECKPOINT(raceInfo, <<827.49, 1278.53, 359.37>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<846.14, 1276.50, 358.83>> ) //ASSIGN_RACE_CHECKPOINT(raceInfo, <<852.6194, 1265.3116, 357.7758>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<835.8340, 1244.0568, 351.7520>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<799.0862, 1223.3503, 340.1938>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<741.2345, 1201.0686, 325.2563>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<676.7847, 1219.0261, 322.9875>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<624.7384, 1217.0782, 315.5874>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<566.5258, 1191.4326, 301.3754>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<519.7023, 1226.5149, 290.0847>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<469.1648, 1233.8317, 277.0887>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<439.77, 1292.51, 270.32>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<407.94, 1253.81, 258.00>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<409.55, 1205.16, 249.29>> ) //12 ASSIGN_RACE_CHECKPOINT(raceInfo, <<422.5302, 1114.8162, 233.0>> ) //Foot of hill - 13 ASSIGN_RACE_CHECKPOINT(raceInfo, <<436.9201, 1045.1660, 235.1103>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<406.2167, 1031.1447, 236.0167>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<380.8393, 1048.0707, 236.4371>> ) // Start of short race ASSIGN_RACE_CHECKPOINT(raceInfo, <<374.2899, 1074.4827, 235.7123>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<362.0448, 1110.6335, 235.1055>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<319.5104, 1161.1849, 235.4029>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<300.0755, 1237.2719, 234.0581>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<267.55, 1261.09, 232.0>> ) // coming off of forest path ASSIGN_RACE_CHECKPOINT(raceInfo, <<252.79, 1238.97, 230.0>> ) // into turn //ASSIGN_RACE_CHECKPOINT(raceInfo, <<248.64, 1214.70, 228.14>> ) // first proper cpt on 2nd road - 22 ASSIGN_RACE_CHECKPOINT(raceInfo, <<268.05, 1137.00, 220.53>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<307.27, 1050.44, 210.96>> ) //ASSIGN_RACE_CHECKPOINT(raceInfo, <<306.41, 1012.17, 209.52>> ) // At junction ASSIGN_RACE_CHECKPOINT(raceInfo, <<298.58, 989.24, 209.66>> ) //ASSIGN_RACE_CHECKPOINT(raceInfo, <<284.01, 966.09, 210.14>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<279.85, 946.37, 209.82>> ) raceInfo.totalLaps = 0 raceInfo.straightLineDist = 15 // raceInfo.taxiPos = << 822.8073, 1278.0714, 359.4283 >> // raceInfo.buddyPos = << 857.7981, 1278.2418, 358.1998 >> // raceInfo.buddyHeading = 0 BREAK CASE RACE_COURSE_RC_FANATIC2ALTB raceInfo.raceCLass = RACE_VEHICLE_CLASS_MOUNTAIN_BIKE // raceInfo.raceName = "RC_FAN2B" raceInfo.sourcePos = << 857.7981, 1278.2418, 358.1998 >> raceInfo.sourceHeading = 152.4354 raceInfo.totalRacers = 1 // Start of long race ASSIGN_RACE_CHECKPOINT(raceInfo, <<827.49, 1278.53, 359.37>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<850.14, 1280.21, 358.57>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<852.6194, 1265.3116, 357.7758>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<835.8340, 1244.0568, 351.7520>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<799.0862, 1223.3503, 340.1938>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<741.2345, 1201.0686, 325.2563>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<676.7847, 1219.0261, 322.9875>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<624.7384, 1217.0782, 315.5874>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<566.5258, 1191.4326, 301.3754>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<519.7023, 1226.5149, 290.0847>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<469.1648, 1233.8317, 277.0887>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<445.0087, 1295.1957, 271.5344>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<411.0428, 1234.2543, 254.5870>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<438.20, 1112.65, 231.80>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<500.16, 1096.98, 229.77>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<532.43, 1064.83, 223.78>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<533.50, 1027.03, 216.61>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<491.57, 968.53, 204.70>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<462.99, 893.08, 197.09>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<416.58, 894.30, 198.00>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<399.39, 933.08, 201.46>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<377.99, 993.49, 207.88>> ) ASSIGN_RACE_CHECKPOINT(raceInfo, <<328.88, 1007.05, 209.52>> ) // ASSIGN_RACE_CHECKPOINT(raceInfo, <<422.5302, 1114.8162, 233.2663>> ) // ASSIGN_RACE_CHECKPOINT(raceInfo, <<436.9201, 1045.1660, 235.1103>> ) // ASSIGN_RACE_CHECKPOINT(raceInfo, <<406.2167, 1031.1447, 236.0167>> ) // ASSIGN_RACE_CHECKPOINT(raceInfo, <<380.8393, 1048.0707, 236.4371>> ) // // Start of short race // ASSIGN_RACE_CHECKPOINT(raceInfo, <<374.2899, 1074.4827, 235.7123>> ) // ASSIGN_RACE_CHECKPOINT(raceInfo, <<362.0448, 1110.6335, 235.1055>> ) // ASSIGN_RACE_CHECKPOINT(raceInfo, <<319.5104, 1161.1849, 235.4029>> ) // ASSIGN_RACE_CHECKPOINT(raceInfo, <<300.0755, 1237.2719, 234.0581>> ) // ASSIGN_RACE_CHECKPOINT(raceInfo, <<269.5442, 1263.0739, 232.5312>> ) // ASSIGN_RACE_CHECKPOINT(raceInfo, <<258.5526, 1218.9199, 228.3669>> ) // ASSIGN_RACE_CHECKPOINT(raceInfo, <<271.5604, 1140.6415, 220.7155>> ) // ASSIGN_RACE_CHECKPOINT(raceInfo, <<290.6088, 1094.6976, 215.5821>> ) // ASSIGN_RACE_CHECKPOINT(raceInfo, <<309.9068, 1019.8271, 209.4761>> ) raceInfo.totalLaps = 0 // raceInfo.taxiPos = << 822.8073, 1278.0714, 359.4283 >> raceInfo.straightLineDist = 15 //raceInfo.buddyPos = << 857.7981, 1278.2418, 358.1998 >> //raceInfo.buddyHeading = 0 BREAK CASE RACE_COURSE_RC_EXTREME1 raceInfo.raceCLass = RACE_VEHICLE_CLASS_MOUNTAIN_BIKE // raceInfo.raceName = "RC_EXT1" raceInfo.sourcePos = << 500.6770, 5598.2622, 794.8943 >> raceInfo.sourceHeading = 156.5849 raceInfo.totalRacers = 2 ASSIGN_RACE_CHECKPOINT(raceInfo, <<481.4428, 5521.1191, 771.8>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<435.2, 5507.4, 743.7>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<380.6, 5498.7, 713.3>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<349.6, 5447.3, 675.5>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<312.5256, 5385.5020, 642.6>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<276.9, 5347.8, 630.6>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<226.4586, 5295.5039, 618.1>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<231.5871, 5249.3643, 600.8>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<201.4, 5247.7, 590.0>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<172.3, 5203.5, 570.0>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<145.6254, 5185.0322, 551.3>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<130.1801, 5224.4473, 541.8>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<113.3, 5174.3, 526.5>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<113.9507, 5107.9199, 509.5>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<88.1, 5073.2, 491.5>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<89.5557, 5017.5713, 460.8>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<30.4282, 5050.1685, 454.2>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<7.4203, 5010.6812, 443.9>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-46.7, 5005.9, 408.6>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-65.7, 4955.6, 392.4>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-131.1, 4919.0, 353.3>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-184.3982, 4900.4634, 329.1>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-271.4, 4916.4, 290.0>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-304.0, 4950.3, 261.0>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-335.4192, 4997.4253, 220.3>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-366.6329, 4919.2505, 196.0>>) // iCurrentBikeRaceConversation (in Extreme1.sc) gets set to 2 here ASSIGN_RACE_CHECKPOINT(raceInfo, <<-460.1884, 4883.4795, 186.7>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-544.8522, 4874.6475, 167.6>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-573.7510, 4893.3311, 168.5>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-590.3, 4962.9, 156.5>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-625.4877, 5013.7354, 143.4>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-634.5757, 5056.1675, 142.8>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-706.3599, 5069.9321, 140.4>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-762.2672, 5126.6323, 135.7>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-764.7, 5192.5, 111.5>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-789.0667, 5263.0425, 88.1>>) ASSIGN_RACE_CHECKPOINT(raceInfo, <<-849.2, 5259.7, 86>>) raceInfo.totalLaps = 0 raceInfo.straightLineDist = 15 // raceInfo.taxiPos = << -329.4604, 4752.3691, 228.0300 >> // raceInfo.buddyPos = << -329.4604, 4752.3691, 228.0300 >> // raceInfo.buddyHeading = 275 BREAK ENDSWITCH ENDPROC FUNC VECTOR GET_RACER_GRID_POSITION(RACER_INFO_STRUCT &racerInfo, RACE_INFO_STRUCT raceInfo, INT &gridNumber) INT gridRow VECTOR sideOffset, behindOffset FLOAT vehLength = 3.0 FLOAT vehWidth = 1.0 FLOAT scaleSide, scaleBehind racerInfo.racerPos.z = 0.0 // raceInfo.sourcePos // Generate offset multipliers from race source heading sideOffset.x = -1.0 * SIN(raceInfo.sourceHeading+90.0) sideOffset.y = COS(raceInfo.sourceHeading+90.0) behindOffset.x = -1.0 * SIN(raceInfo.sourceHeading+180.0) behindOffset.y = COS(raceInfo.sourceHeading+180.0) // Get X Offset gridRow = gridNumber / 2 IF gridRow * 2 = gridNumber scaleSide = (vehWidth+GET_RANDOM_FLOAT_IN_RANGE(0.0, 0.7)) ELSE scaleSide = (-vehWidth+GET_RANDOM_FLOAT_IN_RANGE(0.0, 0.7)) ENDIF IF gridNumber = TOTAL_NUMBER_OF_RACERS-1 scaleSide = (-vehWidth+0.5) ENDIF // Get Y offset scaleBehind = (vehLength+GET_RANDOM_FLOAT_IN_RANGE(-1.0, 1.0)) scaleBehind += TO_FLOAT(gridRow) * (2 * vehLength) // Get world coordinates for offsets racerInfo.racerPos.x = (scaleSide * sideOffset.x) + (scaleBehind * behindOffset.x) racerInfo.racerPos.y = (scaleSide * sideOffset.y) + (scaleBehind * behindOffset.y) racerInfo.racerPos += raceInfo.sourcePos RETURN racerInfo.racerPos ENDFUNC FUNC BOOL IS_PED_IN_ACCEPTABLE_RACE_VEHICLE(RACER_INFO_STRUCT &playerRacer, RACE_VEHICLE_CLASS vehicleClass) IF NOT IS_ENTITY_DEAD(playerRacer.raceVehicle) IF IS_PED_IN_VEHICLE(playerRacer.racer, playerRacer.raceVehicle) IF vehicleClass = RACE_VEHICLE_CLASS_MOTORBIKES IF NOT IS_PED_ON_ANY_BIKE(playerRacer.racer) RETURN FALSE ELSE RETURN TRUE ENDIF ELSE IF IS_VEHICLE_MODEL(playerRacer.raceVehicle, FBI) OR IS_VEHICLE_MODEL(playerRacer.raceVehicle, FIRETRUK) OR IS_VEHICLE_MODEL(playerRacer.raceVehicle, POLICE) RETURN FALSE ELSE RETURN TRUE ENDIF ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC PROC START_RACE_GRID_FLYBY(RACE_GRID_FLYBY_STYLE &flybyStyle, RACER_INFO_STRUCT &racerInfo[], RACE_INFO_STRUCT &raceInfo) VECTOR sourceCamPos VECTOR sourceCamTarget VECTOR destCamPos VECTOR destCamTarget VECTOR sourceMod INT postion11 = TOTAL_NUMBER_OF_RACERS-1 INT postion10 = TOTAL_NUMBER_OF_RACERS-3 INT position8 = TOTAL_NUMBER_OF_RACERS-4 INT position9 = TOTAL_NUMBER_OF_RACERS-3 INT temp2 = 2 RACER_INFO_STRUCT tempRacerInfo IF flybyStyle <> RG_FLYBY_NONE SWITCH flybyStyle CASE RG_FLYBY_LEFT_FRONT_TO_BACK sourceCamPos = racerInfo[1].racerPos sourceCamTarget = racerInfo[2].racerPos destCamPos = racerInfo[postion11].racerPos destCamTarget = racerInfo[position8].racerPos sourceMod = sourceCamPos - sourceCamTarget sourceCamPos += sourceMod destCamPos += sourceMod sourceMod = racerInfo[position9].racerPos - racerInfo[postion11].racerPos destCamPos += sourceMod sourceCamPos.z += 1.0 destCamPos.z += 2.0 BREAK CASE RG_FLYBY_RIGHT_FRONT_TO_BACK sourceCamPos = racerInfo[2].racerPos sourceCamTarget = racerInfo[1].racerPos destCamPos = racerInfo[position8].racerPos destCamTarget = racerInfo[postion11].racerPos sourceMod = sourceCamPos - sourceCamTarget sourceCamPos += sourceMod destCamPos += sourceMod sourceMod = racerInfo[position8].racerPos - racerInfo[postion10].racerPos destCamPos += sourceMod sourceCamPos.z += 3.0 destCamPos.z += 4.0 BREAK CASE RG_FLYBY_CENTRE_FRONT_TO_BACK sourceCamPos = raceInfo.sourcePos sourceMod = racerInfo[2].racerPos - racerInfo[0].racerPos sourceCamTarget = sourceCamPos + sourceMod sourceCamTarget += sourceMod sourceCamTarget += sourceMod sourceCamTarget += sourceMod destCamPos = sourceCamTarget sourceCamTarget += sourceMod sourceCamTarget += sourceMod sourceCamTarget += sourceMod destCamTarget = sourceCamTarget sourceCamTarget.z += 1.0 destCamTarget.z += 1.5 sourceCamPos.z += 1.0 destCamPos.z += 2.5 BREAK CASE RG_FLYBY_LEFT_BACK_TO_FRONT destCamPos = racerInfo[1].racerPos destCamTarget = racerInfo[2].racerPos sourceCamPos = racerInfo[postion11].racerPos sourceCamTarget = racerInfo[position8].racerPos sourceMod = sourceCamPos - sourceCamTarget sourceCamPos += sourceMod destCamPos += sourceMod sourceMod = racerInfo[position9].racerPos - racerInfo[postion11].racerPos destCamPos += sourceMod sourceCamPos.z += 1.0 destCamPos.z += 2.0 BREAK CASE RG_FLYBY_RIGHT_BACK_TO_FRONT destCamPos = racerInfo[2].racerPos destCamTarget = racerInfo[1].racerPos sourceCamPos = racerInfo[position8].racerPos sourceCamTarget= racerInfo[postion11].racerPos sourceMod = sourceCamPos - sourceCamTarget sourceCamPos += sourceMod destCamPos += sourceMod sourceMod = racerInfo[position8].racerPos - racerInfo[postion10].racerPos destCamPos += sourceMod sourceCamPos.z += 3.0 destCamPos.z += 4.0 BREAK CASE RG_FLYBY_CENTRE_BACK_TO_FRONT destCamPos = raceInfo.sourcePos sourceMod = racerInfo[2].racerPos - racerInfo[0].racerPos sourceCamTarget = destCamPos + sourceMod sourceCamTarget += sourceMod sourceCamTarget += sourceMod sourceCamTarget += sourceMod sourceCamPos = sourceCamTarget sourceCamTarget += sourceMod sourceCamTarget += sourceMod sourceCamTarget += sourceMod destCamTarget = sourceCamTarget sourceCamTarget.z += 1.0 destCamTarget.z += 1.5 sourceCamPos.z += 2.5 destCamPos.z += 1.0 BREAK CASE RG_FLYBY_DRAG_BACK_TO_FRONT destCamPos = raceInfo.sourcePos sourceMod = GET_RACER_GRID_POSITION(tempRacerInfo, raceInfo, temp2) - racerInfo[0].racerPos sourceCamTarget = destCamPos + sourceMod sourceCamTarget += sourceMod sourceCamTarget += sourceMod sourceCamTarget += sourceMod sourceCamPos = sourceCamTarget sourceCamTarget += sourceMod sourceCamTarget += sourceMod sourceCamTarget += sourceMod destCamTarget = sourceCamTarget sourceCamTarget.z += 1.0 destCamTarget.z += 1.5 sourceCamPos.z += 2.5 destCamPos.z += 1.0 BREAK ENDSWITCH IF NOT DOES_CAM_EXIST(raceInfo.raceSourceCam) raceInfo.raceSourceCam = CREATE_CAM_WITH_PARAMS("DEFAULT_SCRIPTED_CAMERA", sourceCamPos, sourceCamPos, 30) POINT_CAM_AT_COORD(raceInfo.raceSourceCam, sourceCamTarget) raceInfo.raceDestCam = CREATE_CAM_WITH_PARAMS("DEFAULT_SCRIPTED_CAMERA", destCamPos, destCamPos, 30) POINT_CAM_AT_COORD(raceInfo.raceDestCam, destCamTarget) SET_CAM_ACTIVE_WITH_INTERP(raceInfo.raceDestCam, raceInfo.raceSourceCam, 7500, GRAPH_TYPE_SIN_ACCEL_DECEL, GRAPH_TYPE_LINEAR) ENDIF ENDIF ENDPROC FUNC RACE_GRID_FLYBY_STYLE RANDOM_RG_FLYBY_STYLE() RACE_GRID_FLYBY_STYLE returnedStyle SWITCH GET_RANDOM_INT_IN_RANGE(1, 6) CASE 1 returnedStyle = RG_FLYBY_LEFT_FRONT_TO_BACK BREAK CASE 2 returnedStyle = RG_FLYBY_RIGHT_FRONT_TO_BACK BREAK CASE 3 returnedStyle = RG_FLYBY_CENTRE_FRONT_TO_BACK BREAK CASE 4 returnedStyle = RG_FLYBY_LEFT_BACK_TO_FRONT BREAK CASE 5 returnedStyle = RG_FLYBY_RIGHT_BACK_TO_FRONT BREAK CASE 6 returnedStyle = RG_FLYBY_CENTRE_BACK_TO_FRONT BREAK ENDSWITCH //// Global checked to allow for the initial race to have an intro cutscene - negating the need for a flyby. // IF g_roadRashRacesWon = 0 // returnedStyle = RG_FLYBY_NONE // ENDIF RETURN returnedStyle ENDFUNC FUNC BOOL HAS_RACE_GRID_FLYBY_FINISHED(RACE_GRID_FLYBY_STYLE flybyStyle, RACE_INFO_STRUCT &raceInfo) IF flybyStyle <> RG_FLYBY_NONE IF DOES_CAM_EXIST(raceInfo.raceSourceCam) IF NOT IS_CAM_INTERPOLATING(raceInfo.raceSourceCam) // OR IS_CUTSCENE_SKIP_BUTTON_JUST_PRESSED() IF DOES_CAM_EXIST(raceInfo.raceSourceCam) SET_CAM_ACTIVE (raceInfo.raceSourceCam, FALSE) DESTROY_CAM(raceInfo.raceSourceCam) ENDIF IF DOES_CAM_EXIST(raceInfo.raceDestCam) SET_CAM_ACTIVE (raceInfo.raceDestCam, FALSE) DESTROY_CAM(raceInfo.raceDestCam) SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0) ENDIF RETURN TRUE ENDIF ENDIF ELSE RETURN TRUE ENDIF RETURN FALSE ENDFUNC FUNC BOOL HAS_RACE_COUNTDOWN_AND_FLYBY_FINISHED(INT &raceCount, INT &countdownStart, INT &countdownEnd, RACE_GRID_FLYBY_STYLE flybyStyle, RACER_INFO_STRUCT &racerInfo[], RACE_INFO_STRUCT &raceInfo) CONST_INT raceFour 4 CONST_INT raceThree 3 CONST_INT raceTwo 2 CONST_INT raceOne 1 CONST_INT raceGo 0 FLOAT textX = 0.5 FLOAT textY = 0.5 SWITCH raceCount CASE raceFour IF countdownEnd < (countdownStart + 3000) START_RACE_GRID_FLYBY(flybyStyle, racerInfo, raceInfo) countdownEnd = GET_GAME_TIMER() CLEAR_PRINTS() ELSE IF HAS_RACE_GRID_FLYBY_FINISHED(flybyStyle, raceInfo) //PRINT_WITH_NUMBER_BIG("NUMBER", 3, 1100, 1) DISPLAY_TEXT_WITH_NUMBER(textX, textY, "NUMBER", 3) PLAY_SOUND_FRONTEND(-1, "3_2_1", "HUD_MINI_GAME_SOUNDSET") countdownStart = GET_GAME_TIMER() raceCount = (raceThree) ENDIF ENDIF BREAK CASE raceThree IF countdownEnd < (countdownStart + 1000) DISPLAY_TEXT_WITH_NUMBER(textX, textY, "NUMBER", 3) countdownEnd = GET_GAME_TIMER() ELSE //PRINT_WITH_NUMBER_BIG("NUMBER", 2, 1100, 1) DISPLAY_TEXT_WITH_NUMBER(textX, textY, "NUMBER", 2) PLAY_SOUND_FRONTEND(-1, "3_2_1", "HUD_MINI_GAME_SOUNDSET") countdownStart = GET_GAME_TIMER() raceCount = (raceTwo) ENDIF BREAK CASE raceTwo IF countdownEnd < (countdownStart + 1000) DISPLAY_TEXT_WITH_NUMBER(textX, textY, "NUMBER", 2) countdownEnd = GET_GAME_TIMER() ELSE //PRINT_WITH_NUMBER_BIG("NUMBER", 1, 1100, 1) DISPLAY_TEXT_WITH_NUMBER(textX, textY, "NUMBER", 1) PLAY_SOUND_FRONTEND(-1, "3_2_1", "HUD_MINI_GAME_SOUNDSET") countdownStart = GET_GAME_TIMER() raceCount = (raceOne) ENDIF BREAK CASE raceOne IF countdownEnd < (countdownStart + 1000) DISPLAY_TEXT_WITH_NUMBER(textX, textY, "NUMBER", 1) countdownEnd = GET_GAME_TIMER() ELSE //PRINT_WITH_NUMBER_BIG("GO", 3, 1100, 1) DISPLAY_TEXT(textX, textY, "GOBR") PLAY_SOUND_FRONTEND(-1, "GO", "HUD_MINI_GAME_SOUNDSET") countdownStart = GET_GAME_TIMER() raceCount = (raceGo) ENDIF BREAK CASE raceGo RETURN TRUE BREAK ENDSWITCH RETURN FALSE ENDFUNC FUNC BOOL HAS_RACER_ABANDONED_RACE_VEHICLE(RACER_INFO_STRUCT &playerRacer, RACE_VEHICLE_CLASS vehicleClass, int &iRaceTimer, int &iTimeStamp, int iTimeLimit) INT iTimeDiff INT iCountdownTime INT iPrintTime IF IS_PED_IN_ACCEPTABLE_RACE_VEHICLE(playerRacer, vehicleClass) iTimeStamp = iRaceTimer ELSE iTimeDiff = iRaceTimer - iTimeStamp iCountdownTime = iTimeLimit - iTimeDiff iPrintTime = iCountdownTime / 1000 IF iPrintTime > 0 ADD_NEXT_MESSAGE_TO_PREVIOUS_BRIEFS(false) iPrintTime = iCountdownTime / 1000 IF iPrintTime < 11 // IF playerRacer.raceVehicleBlip = null // IF vehicleClass <> RACE_VEHICLE_CLASS_MOTORBIKES // IF iPrintTime = 1 // PRINT_WITH_NUMBER_NOW("RACEOUTCAR", iPrintTime, 250, 1) // ELSE // PRINT_WITH_NUMBER_NOW("RACEOUTCARs", iPrintTime, 250, 1) // ENDIF // ELSE // IF iPrintTime = 1 // PRINT_WITH_NUMBER_NOW("RACEOUTBIK", iPrintTime, 250, 1) // ELSE // PRINT_WITH_NUMBER_NOW("RACEOUTBIKs", iPrintTime, 250, 1) // ENDIF // ENDIF // ELSE IF vehicleClass <> RACE_VEHICLE_CLASS_MOTORBIKES IF iPrintTime = 1 PRINT_WITH_NUMBER_NOW("RACEOUTCARBLIP", iCountdownTime / 1000, 250, 1) ELSE PRINT_WITH_NUMBER_NOW("RACEOUTCARBLIPS", iCountdownTime / 1000, 250, 1) ENDIF ELSE IF iPrintTime = 1 PRINT_WITH_NUMBER_NOW("RACEOUTBIKBLIP", iCountdownTime / 1000, 250, 1) ELSE PRINT_WITH_NUMBER_NOW("RACEOUTBIKBLIPS", iCountdownTime / 1000, 250, 1) ENDIF ENDIF // ENDIF ENDIF ELSE RETURN TRUE ENDIF ENDIF RETURN FALSE ENDFUNC FUNC BOOL HAS_RACER_HIT_CHECK(RACER_INFO_STRUCT &racerInfo, RACE_INFO_STRUCT &raceInfo) IF raceInfo.raceCLass = RACE_VEHICLE_CLASS_RC_CHECKS OR raceInfo.raceCLass = RACE_VEHICLE_CLASS_RC checkSize = LOCATE_SIZE_ON_FOOT_ONLY ELSE IF raceInfo.chosenCourse = RACE_COURSE_RC_EXTREME1 checkSize = LOCATE_SIZE_ANY_MEANS+2 // B*1531743 Increase radius for Extreme1 race ELSE checkSize = LOCATE_SIZE_ANY_MEANS ENDIF ENDIF IF racerInfo.currentCheck > -1 IF IS_ENTITY_AT_COORD(racerInfo.racer, raceInfo.checkPos[racerInfo.currentCheck], <>, FALSE) RETURN TRUE ENDIF ELSE RETURN TRUE ENDIF RETURN FALSE ENDFUNC FUNC CHECKPOINT_TYPE GET_CHECKPOINT_TYPE(INT iCheckNum, RACE_INFO_STRUCT &raceInfo) VECTOR pos, pos2, pos3 VECTOR vec1, vec2 FLOAT fReturnAngle FLOAT fChevron1 = 180.0 FLOAT fChevron2 = 140.0 FLOAT fChevron3 = 80.0 pos = raceInfo.checkPos[iCheckNum] IF iCheckNum+1 = raceInfo.totalChecks - 1 pos2 = raceInfo.checkPos[0] ELSE pos2 = raceInfo.checkPos[iCheckNum + 1] ENDIF IF iCheckNum - 1 >= 0 pos3 = raceInfo.checkPos[iCheckNum-1] ENDIF 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 CHECKPOINT_RACE_GROUND_CHEVRON_3 ELIF fReturnAngle < fChevron2 RETURN CHECKPOINT_RACE_GROUND_CHEVRON_2 ELIF fReturnAngle < fChevron1 RETURN CHECKPOINT_RACE_GROUND_CHEVRON_1 ELSE RETURN CHECKPOINT_RACE_GROUND_CHEVRON_1 ENDIF RETURN CHECKPOINT_RACE_GROUND_CHEVRON_1 ENDFUNC FUNC HUD_COLOURS GET_CHECKPOINT_COLOUR(CHECKPOINT_TYPE cpType) // IF cpType = CHECKPOINT_RACE_GROUND_CHEVRON_3 // RETURN HUD_COLOUR_YELLOWDARK // ELIF cpType = CHECKPOINT_RACE_GROUND_CHEVRON_2 // RETURN HUD_COLOUR_YELLOW // ELSE // RETURN HUD_COLOUR_YELLOWLIGHT // ENDIF // Returning YELLOWDARK for all checkpoints (B*1454575) cpType = cpType // Compile fix, no point changing the function because this won't stay... RETURN HUD_COLOUR_YELLOWDARK ENDFUNC PROC SET_PLAYER_CHECKPOINTS_AND_BLIPS(RACER_INFO_STRUCT &playerInfo, RACE_INFO_STRUCT &raceInfo) VECTOR tempPos FLOAT fBlipScale = 0.7 FLOAT fCheckSize = 7.5*2*0.66 BOOL bDrawNextBlip = TRUE // Get checkpoint arrow CHECKPOINT_TYPE checkArrow = GET_CHECKPOINT_TYPE(playerInfo.currentCheck, raceInfo) CHECKPOINT_TYPE checkFlag = CHECKPOINT_RACE_GROUND_FLAG // Get checkpoint colour INT iR, iG, iB, iA GET_HUD_COLOUR(GET_CHECKPOINT_COLOUR(checkArrow), iR, iG, iB, iA) IF DOES_BLIP_EXIST(playerInfo.checkBlip) REMOVE_BLIP(playerInfo.checkBlip) DELETE_CHECKPOINT(playerInfo.checkPoint) INT piR, piG, piB, piA GET_HUD_COLOUR(HUD_COLOUR_WHITE, piR, piG, piB, piA) PrevAlpha = 180 tempPos = raceInfo.checkPos[playerInfo.currentCheck-1] tempPos += <<0,0,7.5>> IF playerInfo.currentCheck = (raceInfo.totalChecks - 1) playerInfo.PrevCheckpoint = CREATE_CHECKPOINT(checkFlag, tempPos, raceInfo.checkPos[playerInfo.currentCheck], fCheckSize, PiR, PiG, PiB, PrevAlpha) SET_CHECKPOINT_CYLINDER_HEIGHT(playerInfo.PrevCheckpoint,3.0,3.0,100) SET_CHECKPOINT_RGBA(playerInfo.PrevCheckpoint, PiR, PiG, PiB, PrevAlpha) SET_CHECKPOINT_RGBA2(playerInfo.PrevCheckpoint, PiR, PiG, PiB, PrevAlpha) ELSE playerInfo.PrevCheckpoint = CREATE_CHECKPOINT(GET_CHECKPOINT_TYPE(playerInfo.currentCheck-1, raceInfo), tempPos, raceInfo.checkPos[playerInfo.currentCheck], fCheckSize, PiR, PiG, PiB, PrevAlpha) SET_CHECKPOINT_CYLINDER_HEIGHT(playerInfo.PrevCheckpoint,3.0,3.0,100) SET_CHECKPOINT_RGBA(playerInfo.PrevCheckpoint, PiR, PiG, PiB, PrevAlpha) SET_CHECKPOINT_RGBA2(playerInfo.PrevCheckpoint, PiR, PiG, PiB, PrevAlpha) ENDIF ENDIF // Current checkpoint IF NOT DOES_BLIP_EXIST(playerInfo.checkBlip) // Blip checkpoint playerInfo.checkBlip = ADD_BLIP_FOR_COORD(raceInfo.checkPos[playerInfo.currentCheck]) SET_BLIP_DISPLAY(playerInfo.checkBlip, DISPLAY_BLIP) SET_BLIP_NAME_FROM_TEXT_FILE(playerInfo.checkBlip, "BLIP_CPOINT") SET_BLIP_SCALE(playerInfo.checkBlip, 1.2) SHOW_HEIGHT_ON_BLIP(playerInfo.checkBlip, FALSE) // Values taken from multiplayer/single player street races tempPos = raceInfo.checkPos[playerInfo.currentCheck] tempPos += <<0,0,7.5>> IF playerInfo.currentCheck = (raceInfo.totalChecks - 1) // Final checkpoint IF playerInfo.currentLap = raceInfo.totalLaps playerInfo.checkPoint = CREATE_CHECKPOINT(checkFlag, tempPos, raceInfo.checkPos[playerInfo.currentCheck], fCheckSize, iR, iG, iB) GET_HUD_COLOUR(HUD_COLOUR_YELLOWLIGHT, iR, iG, iB, iA) SET_CHECKPOINT_RGBA(playerInfo.checkPoint, iR, iG, iB, iA) GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iR, iG, iB, iA) SET_CHECKPOINT_RGBA2(playerInfo.checkPoint, iR, iG, iB, iA) SET_CHECKPOINT_CYLINDER_HEIGHT(playerInfo.checkPoint,3.0,3.0,100) FLOAT fDis = GET_DISTANCE_BETWEEN_COORDS(raceInfo.checkPos[playerInfo.currentCheck],GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE)) IF playerInfo.checkPoint != NULL // Make sure the checkpoint exists first IF playerInfo.distanceToNextCheck > 100.0 iA = 200 GET_HUD_COLOUR(HUD_COLOUR_YELLOWLIGHT, iR, iG, iB, iA) SET_CHECKPOINT_RGBA(playerInfo.checkPoint, iR, iG, iB, iA) GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iR, iG, iB, iA) SET_CHECKPOINT_RGBA2(playerInfo.checkPoint, iR, iG, iB, iA) ELSE GET_HUD_COLOUR(HUD_COLOUR_YELLOWLIGHT, iR, iG, iB, iA) iA = ROUND(fDis*2) SET_CHECKPOINT_RGBA(playerInfo.checkPoint, iR, iG, iB, iA) GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iR, iG, iB, iA) iA = ROUND(fDis*2) SET_CHECKPOINT_RGBA2(playerInfo.checkPoint, iR, iG, iB, iA) ENDIF ENDIF SET_BLIP_SPRITE(playerInfo.checkBlip, RADAR_TRACE_RACEFLAG) bDrawNextBlip = FALSE ELSE // Next lap playerInfo.checkPoint = CREATE_CHECKPOINT(checkFlag, tempPos, raceInfo.checkPos[0], fCheckSize, iR, iG, iB, iA) GET_HUD_COLOUR(HUD_COLOUR_YELLOWLIGHT, iR, iG, iB, iA) SET_CHECKPOINT_RGBA(playerInfo.checkPoint, iR, iG, iB, iA) GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iR, iG, iB, iA) SET_CHECKPOINT_RGBA2(playerInfo.checkPoint, iR, iG, iB, iA) SET_CHECKPOINT_CYLINDER_HEIGHT(playerInfo.checkPoint,3.0,3.0,100) FLOAT fDis = GET_DISTANCE_BETWEEN_COORDS(raceInfo.checkPos[playerInfo.currentCheck],GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE)) IF playerInfo.checkPoint != NULL // Make sure the checkpoint exists first IF playerInfo.distanceToNextCheck > 100.0 iA = 200 GET_HUD_COLOUR(HUD_COLOUR_YELLOWLIGHT, iR, iG, iB, iA) SET_CHECKPOINT_RGBA(playerInfo.checkPoint, iR, iG, iB, iA) GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iR, iG, iB, iA) SET_CHECKPOINT_RGBA2(playerInfo.checkPoint, iR, iG, iB, iA) ELSE GET_HUD_COLOUR(HUD_COLOUR_YELLOWLIGHT, iR, iG, iB, iA) iA = ROUND(fDis*2) SET_CHECKPOINT_RGBA(playerInfo.checkPoint, iR, iG, iB, iA) GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iR, iG, iB, iA) iA = ROUND(fDis*2) SET_CHECKPOINT_RGBA2(playerInfo.checkPoint, iR, iG, iB, iA) ENDIF ENDIF ENDIF ELSE playerInfo.checkPoint = CREATE_CHECKPOINT(checkArrow, tempPos, raceInfo.checkPos[(playerInfo.currentCheck+1)], fCheckSize, iR, iG, iB, 150) GET_HUD_COLOUR(HUD_COLOUR_YELLOWLIGHT, iR, iG, iB, iA) SET_CHECKPOINT_RGBA(playerInfo.checkPoint, iR, iG, iB, iA) GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iR, iG, iB, iA) SET_CHECKPOINT_RGBA2(playerInfo.checkPoint, iR, iG, iB, iA) SET_CHECKPOINT_CYLINDER_HEIGHT(playerInfo.checkPoint,3.0,3.0,100) FLOAT fDis = GET_DISTANCE_BETWEEN_COORDS(raceInfo.checkPos[playerInfo.currentCheck],GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE)) IF playerInfo.checkPoint != NULL // Make sure the checkpoint exists first IF playerInfo.distanceToNextCheck > 100.0 iA = 200 SET_CHECKPOINT_RGBA(playerInfo.checkPoint, iR, iG, iB, iA) GET_HUD_COLOUR(HUD_COLOUR_YELLOWLIGHT, iR, iG, iB, iA) SET_CHECKPOINT_RGBA(playerInfo.checkPoint, iR, iG, iB, iA) GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iR, iG, iB, iA) SET_CHECKPOINT_RGBA2(playerInfo.checkPoint, iR, iG, iB, iA) ELSE GET_HUD_COLOUR(HUD_COLOUR_YELLOWLIGHT, iR, iG, iB, iA) iA = ROUND(fDis*2) SET_CHECKPOINT_RGBA(playerInfo.checkPoint, iR, iG, iB, iA) GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iR, iG, iB, iA) iA = ROUND(fDis*2) SET_CHECKPOINT_RGBA2(playerInfo.checkPoint, iR, iG, iB, iA) ENDIF ENDIF ENDIF ENDIF // Next checkpoint IF DOES_BLIP_EXIST(playerInfo.nextCheckBlip) REMOVE_BLIP(playerInfo.nextCheckBlip) ENDIF IF bDrawNextBlip IF NOT DOES_BLIP_EXIST(playerInfo.nextCheckBlip) IF playerInfo.nextCheck < (raceInfo.totalChecks - 1) playerInfo.nextCheckBlip = ADD_BLIP_FOR_COORD(raceInfo.checkPos[playerInfo.nextCheck]) SET_BLIP_DISPLAY(playerInfo.nextCheckBlip, DISPLAY_BLIP) SET_BLIP_SCALE(playerInfo.nextCheckBlip, fBlipScale) SHOW_HEIGHT_ON_BLIP(playerInfo.nextCheckBlip, FALSE) SET_BLIP_NAME_FROM_TEXT_FILE(playerInfo.nextCheckBlip, "BLIP_CPOINT") ELSE IF playerInfo.nextCheck = (raceInfo.totalChecks - 1) IF playerInfo.currentLap = raceInfo.totalLaps playerInfo.nextCheckBlip = ADD_BLIP_FOR_COORD(raceInfo.checkPos[playerInfo.nextCheck]) SET_BLIP_SPRITE(playerInfo.nextCheckBlip, RADAR_TRACE_RACEFLAG) SET_BLIP_DISPLAY(playerInfo.nextCheckBlip, DISPLAY_BLIP) SET_BLIP_SCALE(playerInfo.nextCheckBlip, 1.2) // Final blip should be 1.2 scale SHOW_HEIGHT_ON_BLIP(playerInfo.nextCheckBlip, FALSE) SET_BLIP_NAME_FROM_TEXT_FILE(playerInfo.nextCheckBlip, "BLIP_CPOINT") ELSE playerInfo.nextCheckBlip = ADD_BLIP_FOR_COORD(raceInfo.checkPos[playerInfo.nextCheck]) SET_BLIP_DISPLAY(playerInfo.nextCheckBlip, DISPLAY_BLIP) SET_BLIP_SCALE(playerInfo.nextCheckBlip, fBlipScale) SHOW_HEIGHT_ON_BLIP(playerInfo.nextCheckBlip, FALSE) SET_BLIP_NAME_FROM_TEXT_FILE(playerInfo.nextCheckBlip, "BLIP_CPOINT") ENDIF ENDIF ENDIF ENDIF ENDIF ENDPROC FUNC BOOL RUN_PLAYER_CHECKPOINTS_AND_BLIPS(RACER_INFO_STRUCT &playerInfo, RACE_INFO_STRUCT &raceInfo, BOOL bOnlyIfInVehicle = TRUE) IF IS_PED_IN_ACCEPTABLE_RACE_VEHICLE(playerInfo, raceInfo.raceClass) // Vehicle class shouldn't be hard wired. OR bOnlyIfInVehicle = FALSE IF playerInfo.PrevCheckpoint != NULL PrevAlpha -= 25 IF PrevAlpha > 0 INT piR, piG, piB, piA GET_HUD_COLOUR(HUD_COLOUR_WHITE, piR, piG, piB, piA) SET_CHECKPOINT_RGBA(playerInfo.PrevCheckpoint, piR, piG, piB, PrevAlpha) SET_CHECKPOINT_RGBA2(playerInfo.PrevCheckpoint, piR, piG, piB, PrevAlpha) ELSE DELETE_CHECKPOINT(playerInfo.PrevCheckpoint) ENDIF ENDIF IF HAS_RACER_HIT_CHECK(playerInfo, raceInfo) IF playerInfo.currentCheck < (raceInfo.totalChecks - 1) playerInfo.currentCheck++ IF playerInfo.nextCheck = (raceInfo.totalChecks-1) IF playerInfo.currentLap < raceInfo.totalLaps playerInfo.nextCheck = 0 ENDIF ELSE playerInfo.nextCheck++ ENDIF SET_PLAYER_CHECKPOINTS_AND_BLIPS(playerInfo, raceInfo) PLAY_SOUND_FRONTEND(-1, "CHECKPOINT_NORMAL", "HUD_MINI_GAME_SOUNDSET", FALSE) RETURN TRUE ELSE IF playerInfo.currentLap < raceInfo.totalLaps playerInfo.currentCheck = 0 playerInfo.nextCheck = 1 playerInfo.currentLap++ SET_PLAYER_CHECKPOINTS_AND_BLIPS(playerInfo, raceInfo) // Play the checkpoint lap sound? PLAY_SOUND_FRONTEND(-1, "CHECKPOINT_NORMAL", "HUD_MINI_GAME_SOUNDSET", FALSE) RETURN TRUE ELSE IF DOES_BLIP_EXIST(playerInfo.checkBlip) playerInfo.racerStatus = RACER_STATUS_FINISHED REMOVE_BLIP(playerInfo.checkBlip) DELETE_CHECKPOINT(playerInfo.checkPoint) PLAY_SOUND_FRONTEND(-1, "CHECKPOINT_NORMAL", "HUD_MINI_GAME_SOUNDSET", FALSE) ENDIF ENDIF ENDIF ELSE IF NOT DOES_BLIP_EXIST(playerInfo.checkBlip) SET_PLAYER_CHECKPOINTS_AND_BLIPS(playerInfo, raceInfo) ENDIF ENDIF CHECKPOINT_TYPE checkArrow = GET_CHECKPOINT_TYPE(playerInfo.currentCheck, raceInfo) // Get checkpoint colour INT iR, iG, iB, iA GET_HUD_COLOUR(GET_CHECKPOINT_COLOUR(checkArrow), iR, iG, iB, iA) // Do alpha fade of current checkpoint as player gets closer to it playerInfo.distanceToNextCheck = VDIST(GET_ENTITY_COORDS(playerInfo.racer), raceInfo.checkPos[playerInfo.currentCheck]) IF playerInfo.checkPoint != NULL // Make sure the checkpoint exists first IF playerInfo.distanceToNextCheck > 100.0 GET_HUD_COLOUR(HUD_COLOUR_YELLOWLIGHT, iR, iG, iB, iA) iA = 240 SET_CHECKPOINT_RGBA(playerInfo.checkPoint, iR, iG, iB, iA) GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iR, iG, iB, iA) iA = 240 SET_CHECKPOINT_RGBA2(playerInfo.checkPoint, iR, iG, iB, iA) ELSE GET_HUD_COLOUR(HUD_COLOUR_YELLOWLIGHT, iR, iG, iB, iA) iA = ROUND(playerInfo.distanceToNextCheck*2.4) IF iA < 60 iA = 60 ENDIF SET_CHECKPOINT_RGBA(playerInfo.checkPoint, iR, iG, iB, iA) GET_HUD_COLOUR(HUD_COLOUR_NORTH_BLUE, iR, iG, iB, iA) iA = ROUND(playerInfo.distanceToNextCheck*2.4) IF iA < 60 iA = 60 ENDIF SET_CHECKPOINT_RGBA2(playerInfo.checkPoint, iR, iG, iB, iA) ENDIF ENDIF ELSE IF DOES_BLIP_EXIST(playerInfo.checkBlip) REMOVE_BLIP(playerInfo.checkBlip) DELETE_CHECKPOINT(playerInfo.checkPoint) ENDIF IF DOES_BLIP_EXIST(playerInfo.nextCheckBlip) REMOVE_BLIP(playerInfo.nextCheckBlip) ENDIF ENDIF RETURN FALSE ENDFUNC PROC RACER_SPEED_UP(RACER_INFO_STRUCT &thisRacer) FLOAT speedAdjustment = 0.2 //* (g_roadRashRacesWon+1) // Speed adjustment based on number of races won IF speedAdjustment > 2.0 speedAdjustment = 2.0 ENDIF IF thisRacer.racer <> PLAYER_PED_ID() IF NOT IS_ENTITY_DEAD(thisRacer.racer) AND NOT IS_ENTITY_DEAD(thisRacer.raceVehicle) IF thisRacer.currentSpeed < 50.0 IF IS_PED_IN_VEHICLE(thisRacer.racer, thisRacer.raceVehicle) IF GET_SCRIPT_TASK_STATUS (thisRacer.racer, SCRIPT_TASK_VEHICLE_DRIVE_TO_COORD) = PERFORMING_TASK thisRacer.currentSpeed += 0.2 SET_DRIVE_TASK_CRUISE_SPEED(thisRacer.racer, thisRacer.currentSpeed) ENDIF ENDIF ENDIF ENDIF ENDIF ENDPROC PROC RACER_SLOW_DOWN(RACER_INFO_STRUCT &thisRacer) IF thisRacer.racer <> PLAYER_PED_ID() IF NOT IS_ENTITY_DEAD(thisRacer.racer) AND NOT IS_ENTITY_DEAD(thisRacer.raceVehicle) IF thisRacer.currentSpeed > 25.0 IF IS_PED_IN_VEHICLE(thisRacer.racer, thisRacer.raceVehicle) IF GET_SCRIPT_TASK_STATUS (thisRacer.racer, SCRIPT_TASK_VEHICLE_DRIVE_TO_COORD) = PERFORMING_TASK thisRacer.currentSpeed -= 0.005 SET_DRIVE_TASK_CRUISE_SPEED(thisRacer.racer, thisRacer.currentSpeed) ENDIF ENDIF ENDIF ENDIF ENDIF ENDPROC FUNC BOOL IS_RACER_HEADING_ACCEPTABLE_FOR_RACE_START(RACER_INFO_STRUCT &playerRacer, RACE_INFO_STRUCT &raceInfo) FLOAT upperHeadingLimit = 15.0 FLOAT lowerHeadingLimit = 15.0 IF NOT IS_ENTITY_DEAD(playerRacer.raceVehicle) lowerHeadingLimit = raceInfo.sourceHeading - lowerHeadingLimit IF lowerHeadingLimit < 0.0 lowerHeadingLimit += 360.0 ENDIF upperHeadingLimit = raceInfo.sourceHeading + 15.0 IF upperHeadingLimit >= 360.0 upperHeadingLimit -= 360.0 ENDIF IF upperHeadingLimit > lowerHeadingLimit IF GET_ENTITY_HEADING(playerRacer.raceVehicle) < upperHeadingLimit AND GET_ENTITY_HEADING(playerRacer.raceVehicle) > lowerHeadingLimit RETURN TRUE ELSE RETURN FALSE ENDIF ELSE IF GET_ENTITY_HEADING(playerRacer.raceVehicle) < upperHeadingLimit OR GET_ENTITY_HEADING(playerRacer.raceVehicle) > lowerHeadingLimit RETURN TRUE ELSE RETURN FALSE ENDIF ENDIF ELSE RETURN FALSE ENDIF ENDFUNC FUNC INT GET_RACE_POSITION(RACER_INFO_STRUCT &playerRacer, RACER_INFO_STRUCT &otherRacers[], RACE_INFO_STRUCT &raceInfo) INT racePosition = (raceInfo.totalRacers -1) INT i REPEAT (raceInfo.totalRacers-1) i // printDebugStringAndInt("playerRacer.currentLap = ", playerRacer.currentLap) // printDebugString("\n") // printDebugStringAndInt("playerRacer.currentCheck = ", playerRacer.currentCheck) // printDebugString("\n") // printDebugStringAndFloat("playerRacer.distanceToNextCheck = ", playerRacer.distanceToNextCheck) // printDebugString("\n") // // printDebugStringAndInt("otherRacers[", i) // printDebugStringAndInt("].currentLap = ", otherRacers[i].currentLap) // printDebugString("\n") // printDebugStringAndInt("otherRacers[", i) // printDebugStringAndInt("].currentCheck = ", otherRacers[i].currentCheck) // printDebugString("\n") // printDebugStringAndFloat("otherRacers[i].distanceToNextCheck = ", otherRacers[i].distanceToNextCheck) // printDebugString("\n") IF playerRacer.currentLap = otherRacers[i].currentLap IF playerRacer.currentCheck = otherRacers[i].currentCheck IF playerRacer.distanceToNextCheck < otherRacers[i].distanceToNextCheck IF racePosition > 0 racePosition-- RACER_SPEED_UP(otherRacers[i]) ENDIF ELSE RACER_SLOW_DOWN(otherRacers[i]) ENDIF ELSE IF playerRacer.currentCheck > otherRacers[i].currentCheck IF racePosition > 0 racePosition-- RACER_SPEED_UP(otherRacers[i]) ENDIF ELSE RACER_SLOW_DOWN(otherRacers[i]) ENDIF ENDIF ELSE IF playerRacer.currentLap > otherRacers[i].currentLap IF racePosition > 0 racePosition-- RACER_SPEED_UP(otherRacers[i]) ENDIF ELSE //IF racePosition > 0 RACER_SLOW_DOWN(otherRacers[i]) //ENDIF ENDIF ENDIF ENDREPEAT RETURN racePosition ENDFUNC PROC RUN_AI_RACERS(RACER_INFO_STRUCT &playerRacer, RACER_INFO_STRUCT &racerInfo[], RACE_INFO_STRUCT &raceInfo) INT i INT thisCheckpoint REPEAT raceInfo.totalRacers i IF NOT IS_PED_INJURED(racerInfo[i].racer) IF IS_VEHICLE_DRIVEABLE(racerInfo[i].raceVehicle) IF IS_PED_IN_VEHICLE(racerInfo[i].racer, racerInfo[i].raceVehicle) IF HAS_RACER_HIT_CHECK(racerInfo[i], raceInfo) IF playerRacer.racer <> racerInfo[i].racer IF racerInfo[i].currentCheck < (raceInfo.totalChecks - 1) racerInfo[i].currentCheck++ ELSE IF racerInfo[i].currentLap < raceInfo.totalLaps racerInfo[i].currentLap++ racerInfo[i].currentCheck = 0 ELSE IF racerInfo[i].currentLap = raceInfo.totalLaps racerInfo[i].racerStatus = RACER_STATUS_FINISHED ENDIF ENDIF ENDIF IF GET_SCRIPT_TASK_STATUS(racerInfo[i].racer, SCRIPT_TASK_PLAY_ANIM) = FINISHED_TASK thisCheckpoint = racerInfo[i].currentCheck TASK_VEHICLE_DRIVE_TO_COORD(racerInfo[i].racer, racerInfo[i].raceVehicle, raceInfo.checkPos[thisCheckpoint], racerInfo[i].currentSpeed, DRIVINGSTYLE_RACING, DUMMY_MODEL_FOR_SCRIPT, DRIVINGMODE_PLOUGHTHROUGH, checkSize, raceInfo.straightLineDist) ENDIF ENDIF ELSE thisCheckpoint = racerInfo[i].currentCheck ENDIF ELSE IF playerRacer.racer <> racerInfo[i].racer IF NOT IS_ENTITY_ON_SCREEN(racerInfo[i].racer)AND NOT IS_ENTITY_ON_SCREEN(racerInfo[i].raceVehicle) IF NOT IS_SPHERE_VISIBLE(GET_ENTITY_COORDS(racerInfo[i].racer), 50) SET_PED_INTO_VEHICLE(racerInfo[i].racer, racerInfo[i].raceVehicle) ENDIF ELSE IF NOT IS_PED_GETTING_INTO_A_VEHICLE(racerInfo[i].racer) IF GET_SCRIPT_TASK_STATUS(racerInfo[i].racer, SCRIPT_TASK_ENTER_VEHICLE) = FINISHED_TASK TASK_ENTER_VEHICLE(racerInfo[i].racer, racerInfo[i].raceVehicle) ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF racerInfo[i].distanceToNextCheck = VDIST(GET_ENTITY_COORDS(racerInfo[i].racer), raceInfo.checkPos[thisCheckpoint]) ENDIF ENDREPEAT ENDPROC FUNC BOOL IS_RACER_WARPING_DISTANCE_BEHIND(RACER_INFO_STRUCT &playerRacer, RACER_INFO_STRUCT &aiRacer, RACE_INFO_STRUCT &raceInfo) INT checkDiff IF playerRacer.currentLap = aiRacer.currentLap IF playerRacer.currentCheck > aiRacer.currentCheck checkDiff = playerRacer.currentCheck - aiRacer.currentCheck IF checkDiff > 1 RETURN TRUE ENDIF ENDIF ELIF playerRacer.currentLap > aiRacer.currentLap IF aiRacer.currentCheck = (raceInfo.totalChecks - 1) IF playerRacer.currentCheck > 0 RETURN TRUE ENDIF ELSE RETURN TRUE ENDIF ENDIF RETURN FALSE ENDFUNC PROC WARP_AI_RACERS_IF_FALLING_BEHIND(RACER_INFO_STRUCT &playerRacer, RACER_INFO_STRUCT &racerInfo[], RACE_INFO_STRUCT &raceInfo) INT i INT nextCheckpoint INT thisCheckpoint FLOAT tempZ VECTOR vTemp REPEAT raceInfo.totalRacers i IF NOT IS_PED_INJURED(racerInfo[i].racer) IF racerInfo[i].racer <> playerRacer.racer IF GET_SCRIPT_TASK_STATUS(racerInfo[i].racer, SCRIPT_TASK_VEHICLE_DRIVE_TO_COORD) = FINISHED_TASK IF GET_SCRIPT_TASK_STATUS(racerInfo[i].racer, SCRIPT_TASK_PLAY_ANIM) = FINISHED_TASK thisCheckpoint = racerInfo[i].currentCheck IF IS_PED_IN_ANY_VEHICLE(racerInfo[i].racer) IF IS_VEHICLE_DRIVEABLE(racerInfo[i].raceVehicle) TASK_VEHICLE_DRIVE_TO_COORD(racerInfo[i].racer, racerInfo[i].raceVehicle, raceInfo.checkPos[thisCheckpoint], racerInfo[i].currentSpeed, DRIVINGSTYLE_RACING, DUMMY_MODEL_FOR_SCRIPT, DRIVINGMODE_PLOUGHTHROUGH, checkSize, raceInfo.straightLineDist) ELSE TASK_VEHICLE_DRIVE_TO_COORD(racerInfo[i].racer, NULL, raceInfo.checkPos[thisCheckpoint], racerInfo[i].currentSpeed, DRIVINGSTYLE_RACING, DUMMY_MODEL_FOR_SCRIPT, DRIVINGMODE_PLOUGHTHROUGH, checkSize, raceInfo.straightLineDist) ENDIF ENDIF ENDIF ENDIF IF IS_RACER_WARPING_DISTANCE_BEHIND(playerRacer, racerInfo[i], raceInfo) thisCheckpoint = racerInfo[i].currentCheck IF thisCheckpoint < (raceInfo.totalChecks-1) nextCheckpoint = (thisCheckpoint+1) ELSE nextCheckpoint = 0 ENDIF IF NOT IS_ENTITY_ON_SCREEN(racerInfo[i].racer) IF NOT IS_SPHERE_VISIBLE(raceInfo.checkPos[thisCheckpoint], 25) IF NOT IS_POINT_OBSCURED_BY_A_MISSION_ENTITY(raceInfo.checkPos[thisCheckpoint], <<5,5,5>>) IF NOT IS_ENTITY_AT_COORD(playerRacer.racer, raceInfo.checkPos[thisCheckpoint], <<15,15,15>>) IF NOT IS_PED_RAGDOLL(racerInfo[i].racer) GET_GROUND_Z_FOR_3D_COORD(<>, tempZ) vTemp = raceInfo.checkPos[nextCheckpoint] - raceInfo.checkPos[thisCheckpoint] SET_ENTITY_HEADING(racerInfo[i].racer, GET_HEADING_FROM_VECTOR_2D (vTemp.x, vTemp.y)) vTemp = <> /*SET_ENTITY_COORDS*/ SET_PED_COORDS_KEEP_VEHICLE(racerInfo[i].racer, vTemp) ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDREPEAT ENDPROC //FUNC BOOL CHOOSE_SUITABLE_RACE_COURSE(RACE_INFO_STRUCT &raceInfo) // INT i // BOOL positionChosen = FALSE // RACE_INFO_STRUCT tempInfo // RACE_COURSE raceCourse[13] // raceCourse[0] = RACE_COURSE_MT_BIKE1 // // // VECTOR playerPos // FLOAT storedDistance = 99999999999999.0 // STRING g_sSelectedRaceName = "RR_RC_BS" // IF NOT IS_PED_INJURED(PLAYER_PED_ID()) // playerPos = GET_ENTITY_COORDS(PLAYER_PED_ID()) // ENDIF // // IF raceInfo.chosenCourse <> RACE_COURSE_NONE // GENERATE_RACE_INFO(raceInfo) // positionChosen = TRUE // ELSE // REPEAT 1 i // tempInfo.chosenCourse = raceCourse[i] // GENERATE_RACE_INFO(tempInfo) // IF IS_A_RACE_MISSION_SCRIPT_RUNNING() // IF ARE_STRINGS_EQUAL(g_sSelectedRaceName, tempInfo.raceName) // AND VDIST(tempInfo.taxiPos, playerPos) < 25.0 // raceInfo = tempInfo // raceInfo.chosenCourse = raceCourse[i] // positionChosen = TRUE // ENDIF // ELSE // IF ARE_STRINGS_EQUAL(g_sSelectedRaceName, tempInfo.raceName) // // AND NOT IS_BIT_SET(friendRacesWonBitSet, ENUM_TO_INT(raceCourse[i])) // raceInfo = tempInfo // raceInfo.chosenCourse = raceCourse[i] // storedDistance = VDIST(tempInfo.taxiPos, playerPos) // positionChosen = TRUE // ELSE // IF VDIST(tempInfo.taxiPos, playerPos) < storedDistance // What if too close to the last race start? // // IF NOT IS_BIT_SET(friendRacesWonBitSet, ENUM_TO_INT(raceCourse[i])) // // raceInfo = tempInfo // // raceInfo.chosenCourse = raceCourse[i] // // storedDistance = VDIST(tempInfo.taxiPos, playerPos) // // positionChosen = TRUE // // ELIF g_roadRashRacesWon = g_totalRoadRashRaces // // raceInfo = tempInfo // // raceInfo.chosenCourse = raceCourse[i] // // storedDistance = VDIST(tempInfo.taxiPos, playerPos) // // positionChosen = TRUE // // ENDIF // ENDIF // ENDIF // ENDIF // ENDREPEAT // ENDIF // // IF positionChosen // RETURN TRUE // ENDIF // RETURN FALSE //ENDFUNC //FUNC VECTOR RACE_TAXI_POSITION() // RACE_INFO_STRUCT tempInfo // IF CHOOSE_SUITABLE_RACE_COURSE(tempInfo) //// g_sSelectedRaceName = tempInfo.raceName // RETURN tempInfo.taxiPos // ENDIF // RETURN <<0.0, 0.0, 0.0>> //ENDFUNC // //FUNC FLOAT RACE_TAXI_HEADING() // RACE_INFO_STRUCT tempInfo // IF CHOOSE_SUITABLE_RACE_COURSE(tempInfo) //// g_sSelectedRaceName = tempInfo.raceName // RETURN tempInfo.sourceHeading // ENDIF // RETURN -1.0 //ENDFUNC PROC DRAW_RACE_POSITION(INT racePosition, INT totalRacers) IF totalRacers > 1 DISPLAY_TEXT_WITH_2_NUMBERS(0.080, 0.580, "RACE_POS", racePosition, totalRacers) ENDIF ENDPROC PROC DRAW_RACE_LAP_COUNTER(INT currentLap, INT totalLaps) IF totalLaps > 1 DISPLAY_TEXT_WITH_2_NUMBERS(0.080, 0.680, "RACE_LAP", currentLap, totalLaps) ENDIF ENDPROC PROC DRAW_RACE_TIME(INT iRaceTime, BOOL bFlash = FALSE) INT iR, iG, iB, iA INT iSeconds, iMilliseconds iSeconds = iRaceTime/1000 iMilliseconds = iRaceTime - (iSeconds*1000) IF iSeconds < 5 GET_HUD_COLOUR(HUD_COLOUR_RED, iR, iG, iB, iA) SET_TEXT_COLOUR(iR, iG, iB, iA) ENDIF IF bFlash GET_HUD_COLOUR(HUD_COLOUR_YELLOW, iR, iG, iB, iA) SET_TEXT_COLOUR(iR, iG, iB, iA) ENDIF iSeconds = iRaceTime/1000 DISPLAY_TEXT_WITH_2_NUMBERS(0.080, 0.680, "RACE_TIME", iSeconds, iMilliseconds) ENDPROC FUNC INT GIVE_RACE_TIME_BONUS(INT &iTimeRemaining, INT iTimeGiven) iTimeRemaining += iTimeGiven RETURN iTimeRemaining ENDFUNC // //PROC DRAW_RACE_TIMER(INT raceTimer, BOOL countUp = TRUE) // //ENDPROC //PROC DRAW_RACE_WIN_SPLASH() //PROC DRAW_RACE_LOSE_SPLASH()