USING "globals.sch" USING "commands_path.sch" USING "commands_vehicle.sch" USING "commands_camera.sch" USING "commands_ped.sch" USING "commands_hud.sch" USING "commands_graphics.sch" USING "commands_streaming.sch" USING "commands_interiors.sch" USING "commands_pad.sch" USING "script_player.sch" USING "script_maths.sch" USING "commands_audio.sch" USING "shop_public.sch" CONST_INT LAST_CAR_RECORDING_FILE_NUMBER 3000 CONST_INT TRAFFIC_FLAGS_VEH_IS_A_COP 0 CONST_INT TRAFFIC_FLAGS_DRIVER_HAS_BEEN_CREATED 1 CONST_INT TRAFFIC_FLAGS_VEH_IS_A_BIKE 2 CONST_INT TRAFFIC_FLAGS_FREEZE_CAR_FOR_COLLISION 3 CONST_INT TRAFFIC_FLAGS_DONT_SWITCH_TO_AI_EARLY 4 CONST_FLOAT LOAD_AHEAD_TIME 7000.0 CONST_FLOAT MIN_CAR_CRUISE_SPEED 8.0 CONST_FLOAT MAX_CAR_CRUISE_SPEED 62.9 CONST_FLOAT CAUGHT_UP_DIST_PERCENT 0.4 ENUM block_colour_ENUM dont_block_colour = -1, traffic_black = 0, traffic_grey, traffic_silver, traffic_red, traffic_white, traffic_blue, traffic_navy, traffic_light_blue, traffic_cream, traffic_turquoise, traffic_green, traffic_orange, traffic_gun_metal_grey, traffic_burgundy, traffic_gold ENDENUM ENUM UBER_PLAYBACK_PED_MODEL UBER_PLAYBACK_PED_MODEL_DEFAULT, UBER_PLAYBACK_PED_MODEL_AMBIENT, UBER_PLAYBACK_PED_MODEL_COP ENDENUM BOOL bResetPlaybackToTime = FALSE BOOL bPausePlayback = FALSE BOOL bDeleteCarsWhenDone = FALSE BOOL bShowParkedCars = TRUE BOOL bSetPieceCarIsRecording = FALSE BOOL bReRecordingIsEnabled = FALSE BOOL bReRecordingControlHijacked = FALSE BOOL bResetSetPiece = FALSE BOOL bReGrabSetPiecePositionAndQuat = FALSE BOOL bTrafficDontSwitchToAI = FALSE BOOL bCarsAreOn = TRUE BOOL bPlayerIsAheadOfChase = FALSE BOOL bSetPieceRecordingsAreActive = FALSE BOOL bSetPieceRecordingsHaveBeenActivated = FALSE BOOL bCreateAllWaitingCars = FALSE BOOL bRefreshAllCarsAfterSkippingCalled = FALSE BOOL bCalculatePlaybackSpeedInitialised = FALSE BOOL bIsCatchingUp = FALSE BOOL bDontUpdateUberCars = FALSE BOOL bPlayTrafficRecordingEvenIfPlayerIsAheadOfChase = FALSE BOOL bSetPieceCarsDontSwitchToAI = FALSE BOOL bDontProcessTrafficHornsAndLights = FALSE BOOL switch_SetPieceCar_to_ai_on_collision = FALSE BOOL block_vehicle_colour = FALSE BOOL bTrafficOnlySwitchToAIOnCollision = FALSE BOOL bTrafficDontCleanupRecordingFiles = FALSE BOOL allow_trailer_touching_check = FALSE BOOL bTrafficForceDefaultPedModel = FALSE BOOL allow_veh_to_stop_on_any_veh_impact = FALSE BOOL allow_veh_to_stop_on_PLAYER_impact = FALSE BOOL bDontCleanUpUberCarsForTrailer = FALSE //Don't flag this without permission! Intended use is for trailer scenes. BOOL bCreatedUberPlaybackEntityThisFrame = FALSE BOOL bUberPlaybackRemoveDefaultPedModel = TRUE BOOL bSetReleasedDriversToExitOnFlee = FALSE FLOAT TrafficCarQuatX[TOTAL_NUMBER_OF_TRAFFIC_CARS] FLOAT TrafficCarQuatY[TOTAL_NUMBER_OF_TRAFFIC_CARS] FLOAT TrafficCarQuatZ[TOTAL_NUMBER_OF_TRAFFIC_CARS] FLOAT TrafficCarQuatW[TOTAL_NUMBER_OF_TRAFFIC_CARS] FLOAT TrafficCarStartime[TOTAL_NUMBER_OF_TRAFFIC_CARS] FLOAT fSetPieceQuatX, fSetPieceQuatY, fSetPieceQuatZ, fSetPieceQuatW FLOAT SetPieceCarQuatX[TOTAL_NUMBER_OF_SET_PIECE_CARS] FLOAT SetPieceCarQuatY[TOTAL_NUMBER_OF_SET_PIECE_CARS] FLOAT SetPieceCarQuatZ[TOTAL_NUMBER_OF_SET_PIECE_CARS] FLOAT SetPieceCarQuatW[TOTAL_NUMBER_OF_SET_PIECE_CARS] FLOAT SetPieceCarStartime[TOTAL_NUMBER_OF_SET_PIECE_CARS] FLOAT SetPieceCarRecordingSpeed[TOTAL_NUMBER_OF_SET_PIECE_CARS] FLOAT ParkedCarQuatX[TOTAL_NUMBER_OF_PARKED_CARS] FLOAT ParkedCarQuatY[TOTAL_NUMBER_OF_PARKED_CARS] FLOAT ParkedCarQuatZ[TOTAL_NUMBER_OF_PARKED_CARS] FLOAT ParkedCarQuatW[TOTAL_NUMBER_OF_PARKED_CARS] FLOAT fPlaybackCarStreamingDistance = 120.0 FLOAT fResetTime = 0.0 FLOAT fTriggerCarPlaybackTime FLOAT fMasterPlaybackSpeed = 1.0 FLOAT fNewSetPieceTriggerTime = 0.0 FLOAT fPausePlaybackTime = 1.0 FLOAT fClearSurroundingCarsDistance = 30.0 FLOAT fClearCarTimer FLOAT fAirRes = 1.0 FLOAT fMaxAirRes = 5.0 FLOAT fMinAirRes = 1.0 FLOAT fAirResMultiplier = 1.0 FLOAT fUberPlaybackDensitySwitchOffRange = 100.0 FLOAT fUberPlaybackMinCreationDistance = 100.0 //The minimum distance a car has to be from the player to be allowed to create. FLOAT fUberPlaybackParkedCarCleanupDistance = 0.0 FLOAT fUberMinTimeBeforePlaybackStartToCreate = LOAD_AHEAD_TIME //The minimum time before the playback start time of particular car before that car can be created. FLOAT fTimeRoadsWereLastSwitchedOff = 0.0 FLOAT fTimeRoadsWereLastSwitchedOn = 0.0 FLOAT fPlaybackSpeedMaxAcceleration = 0.3 FLOAT fPlaybackSpeedMaxDecceleration = 0.5 FLOAT fSwitchOffRoadDist = 50.0 INT TrafficCarRecording[TOTAL_NUMBER_OF_TRAFFIC_CARS] INT TrafficCarProgress[TOTAL_NUMBER_OF_TRAFFIC_CARS] INT TrafficCarFlags[TOTAL_NUMBER_OF_TRAFFIC_CARS] INT SetPieceCarRecording[TOTAL_NUMBER_OF_SET_PIECE_CARS] INT SetPieceCarProgress[TOTAL_NUMBER_OF_SET_PIECE_CARS] INT SetPieceCarFlags[TOTAL_NUMBER_OF_SET_PIECE_CARS] INT ParkedCarProgress[TOTAL_NUMBER_OF_PARKED_CARS] INT iCurrentNumberOfTrafficPlaybacks = 0 INT iCurrentNumberOfSetPieceCarPlaybacks = 0 INT iCurrentNumberOfParkedCars = 0 INT iTriggerCarRecordingNumber = -1 INT iFirstCarToProcess = 0 INT iFirstParkedCarToProcess = 0 INT iFirstSetpieceCarToProcess = 0 INT iParkedCarsWaitingToCreate = 0 INT iSetPieceCarsWaitingToCreate = 0 INT iTrafficCarsWaitingToCreate = 0 INT iSwitchRoadsIndex = 0 INT iDontSwitchThisSetpieceRecordingToAI = -1 //Allows a special case vehicle IF uber set-pieces are set to switch to AI. INT iDontSwitchThisSetpieceRecordingToAI2 = -1 //Allows a special case vehicle IF uber set-pieces are set to switch to AI. INT iSwitchRoadsOnIndex = 0 INT iLastTrafficCarProcessedForCollisions = 0 INT iLastTrafficCarProcessedForCreation = 0 INT iUberClearCarsIndex = 0 VECTOR TrafficCarPos[TOTAL_NUMBER_OF_TRAFFIC_CARS] VECTOR ParkedCarPos[TOTAL_NUMBER_OF_PARKED_CARS] VECTOR SetPieceCarPos[TOTAL_NUMBER_OF_SET_PIECE_CARS] VECTOR RecordedSetPieceCarPos VECTOR vRoadsOffAtStartMin VECTOR vRoadsOffAtStartMax VECTOR vRoadSwitchedOffMin VECTOR vRoadSwitchedOffMax VECTOR vSwitchRoadsTempMin VECTOR vSwitchRoadsTempMax VECTOR vSwitchRoadsOnMin VECTOR vSwitchRoadsOnMax TEXT_LABEL_63 strUberName REL_GROUP_HASH rgh_traffic MODEL_NAMES TrafficCarModel[TOTAL_NUMBER_OF_TRAFFIC_CARS] MODEL_NAMES ParkedCarModel[TOTAL_NUMBER_OF_PARKED_CARS] MODEL_NAMES SetPieceCarModel[TOTAL_NUMBER_OF_SET_PIECE_CARS] MODEL_NAMES modelDefaultPed = DUMMY_MODEL_FOR_SCRIPT block_colour_ENUM colour_to_block_0 block_colour_ENUM colour_to_block_1 VEHICLE_INDEX TrafficCarID[TOTAL_NUMBER_OF_TRAFFIC_CARS] VEHICLE_INDEX RecordedTrafficCarID[MAX_NUMBER_OF_TRAFFIC_CARS_PLAYING_BACK] VEHICLE_INDEX ParkedCarID[TOTAL_NUMBER_OF_PARKED_CARS] VEHICLE_INDEX SetPieceCarID[TOTAL_NUMBER_OF_SET_PIECE_CARS] VEHICLE_INDEX RecordedParkedCarID[MAX_NUMBER_OF_PARKED_CARS_PLAYING_BACK] VEHICLE_INDEX MainRecordingCar VEHICLE_INDEX SetPieceRecordingCar VEHICLE_INDEX DontRemoveThisCar VEHICLE_INDEX ActiveTrafficCarID[MAX_NUMBER_OF_TRAFFIC_CARS_PLAYING_BACK] #IF IS_DEBUG_BUILD BOOL bEnableReRecording = FALSE BOOL bStartRecordingSetPieceCar = FALSE BOOL bAllowSetPieceRecOverwrite = TRUE BOOL bWidgetCreated = FALSE BOOL bDeleteTrafficWhenRecorded = TRUE BOOL bDeleteRedundantTrafficCars = TRUE BOOL bDeleteRedundantParkedCars = TRUE BOOL bStopParkedCarsFromBeingSpawned = FALSE BOOL bShowExtraTrafficWidgets = FALSE BOOL bShowRecordingCone = FALSE BOOL bResetToStartPosition = FALSE BOOL bClearArea = FALSE BOOL bAllRandomCarsAreSwitchedOn = FALSE BOOL bLoadSetPieceDataForReRec = FALSE BOOL bReRecSetPieceDataLoaded = FALSE BOOL bStartSetPieceReRec = FALSE BOOL bStartReRecOnButtonPress = TRUE BOOL bShowSetPieceReRecPath = FALSE BOOL bShowSetPieceReRecGhost = FALSE BOOL bStopSetPieceReRecOnButtonPress = FALSE BOOL bShowSetPieceIndices = FALSE BOOL bShowTrafficIndices = FALSE BOOL bDrawTrafficProgress = FALSE BOOL bDrawSetpieceProgress = FALSE BOOL bShowTriggerCarPath = FALSE BOOL bShowTrafficCarPaths = FALSE BOOL bShowSetPiecePaths = FALSE BOOL bOutputParkedCarInfo = FALSE BOOL bShowUberWidgets = FALSE BOOL bPrevShowUberWidgets = FALSE BOOL bStartRecordingPlayersCarWithTraffic = FALSE BOOL bIncludeParkedCars = TRUE BOOL bTrafficDebugOn = FALSE BOOL bDrawSpeedVector = FALSE BOOL bOutputCleanedData = FALSE BOOL bSetPieceCarsToConvert[TOTAL_NUMBER_OF_SET_PIECE_CARS] BOOL bSetPieceCarsConverted[TOTAL_NUMBER_OF_SET_PIECE_CARS] INT iHighlightedTrafficCar = -1 INT iHighlightedParkedCar = -1 INT iCurrentNumberOfTrafficRecordings = 0 INT iSetPieceCarRecordingFile = 0 INT iCarsProcessedThisFrame = 0 INT iMainCarRecordingFile = 0 INT iTotalNumberOfParkedCarsRecorded = 0 INT iInitialRecordingFileNumber = 1 INT iTotalNumberOfTrafficCarsRecorded = 0 INT iSetPieceReRecNum = 0 INT iSetPieceReRecNewRecNum = 0 FLOAT fRecordingAngle = 25.0 FLOAT fRecordingHeightAngle = 15.0 FLOAT fRecordingMinHeight = 2.0 FLOAT fRecordingMinWidth = 4.0 FLOAT fRecordingTimer = 0.0 FLOAT fMinRecordingOffset = 5.0 FLOAT fCarDensityMultiplier = 1.0 FLOAT fRecordingDistance = 90.0 FLOAT fTrafficRecordingDistanceAroundCar = 10.0 FLOAT fRecordingClearAreaPercentageOfCone = 0.5 FLOAT fInputPlaybackSpeed FLOAT fMainRecordingStartQuatX FLOAT fMainRecordingStartQuatY FLOAT fMainRecordingStartQuatZ FLOAT fMainRecordingStartQuatW VECTOR vMainRecordingStartPosition BLIP_INDEX HighlightedTrafficCarBlipID BLIP_INDEX HighlightedParkedCarBlipID BLIP_INDEX ActiveParkedCarBlipID[MAX_NUMBER_OF_PARKED_CARS_PLAYING_BACK] BLIP_INDEX ActiveTrafficCarBlipID[MAX_NUMBER_OF_TRAFFIC_CARS_PLAYING_BACK] VEHICLE_INDEX HighlightedTrafficCarID VEHICLE_INDEX HighlightedParkedCarID VEHICLE_INDEX vehForSetPieceReRec WIDGET_GROUP_ID uberParentWidgetGroup = NULL WIDGET_GROUP_ID uberWidgetGroup = NULL #ENDIF FUNC MODEL_NAMES DEFAULT_PED_MODEL() IF modelDefaultPed = DUMMY_MODEL_FOR_SCRIPT RETURN(A_M_Y_BUSINESS_01) ELSE RETURN modelDefaultPed ENDIF ENDFUNC FUNC MODEL_NAMES DEFAULT_CAR_MODEL() RETURN(SULTAN) ENDFUNC FUNC MODEL_NAMES COP_CAR_MODEL() RETURN(POLICE) ENDFUNC FUNC MODEL_NAMES COP_PED_MODEL() RETURN(S_M_Y_COP_01) ENDFUNC FUNC BOOL IS_VEH_MODEL_A_COP_MODEL(MODEL_NAMES model) IF model = POLICE OR model = POLICE2 OR model = POLICE3 OR model = POLICEB OR model = POLICET OR model = POLMAV OR model = PRANGER OR model = SHERIFF RETURN TRUE ENDIF RETURN FALSE ENDFUNC PROC MARK_CAR_AS_NO_LONGER_NEEDED_KEEP_ID(VEHICLE_INDEX inCar) IF DOES_ENTITY_EXIST(inCar) SET_VEHICLE_AS_NO_LONGER_NEEDED(inCar) ENDIF ENDPROC PROC MARK_CHAR_AS_NO_LONGER_NEEDED_KEEP_ID(PED_INDEX inChar) IF DOES_ENTITY_EXIST(inChar) SET_PED_AS_NO_LONGER_NEEDED(inChar) ENDIF ENDPROC PROC DONT_LET_UBER_PLAYBACK_CLEANUP_THIS_CAR(VEHICLE_INDEX &InCar) DontRemoveThisCar = InCar ENDPROC /// PURPOSE: /// If TRUE - forces the uber playback to use the default ped model rather than grabbing random ped models. PROC SET_FORCE_UBER_PLAYBACK_TO_USE_DEFAULT_PED_MODEL(BOOL bUseDefaultModel) bTrafficForceDefaultPedModel = bUseDefaultModel ENDPROC /// PURPOSE: /// Traffic cars by default will switch to AI after the trigger car has passed them. Use this procedure to change this behaviour /// for a given traffic car. This is useful if you find a particular traffic car causing issues when switching to AI early (e.g. swerving /// into other cars, doing U-turns, etc). /// PARAMS: /// iTrafficArrayID - The the traffic car that you want to change. /// bSwitchToAIEarly - TRUE is the default behaviour, FALSE will stop this car from switching to AI early. PROC SET_TRAFFIC_CAR_SWITCH_TO_AI_EARLY(INT iTrafficArrayID, BOOL bSwitchToAIEarly) IF iTrafficArrayID > -1 AND iTrafficArrayID < COUNT_OF(TrafficCarFlags) IF bSwitchToAIEarly CLEAR_BIT(TrafficCarFlags[iTrafficArrayID], TRAFFIC_FLAGS_DONT_SWITCH_TO_AI_EARLY) ELSE SET_BIT(TrafficCarFlags[iTrafficArrayID], TRAFFIC_FLAGS_DONT_SWITCH_TO_AI_EARLY) ENDIF ELSE #IF IS_DEBUG_BUILD SCRIPT_ASSERT("SET_TRAFFIC_CAR_SWITCH_TO_AI_EARLY - invalid array ID given.") #ENDIF ENDIF ENDPROC /// PURPOSE: /// B*1490105 - Used to stop released uber veh drivers interferring with chase by reacting to player shooting /// SET_PED_FLEE_ATTRIBUTES(pedDriver, FA_FORCE_EXIT_VEHICLE, TRUE) /// SET_PED_FLEE_ATTRIBUTES(pedDriver, FA_USE_VEHICLE, FALSE) /// PARAMS: /// bSetActive - If TRUE flee flags will be set PROC SET_RELEASED_DRIVERS_TO_EXIT_VEHICLES_ON_FLEE(BOOL bSetActive = FALSE) bSetReleasedDriversToExitOnFlee = bSetActive ENDPROC /// PURPOSE: /// Changes the default model used by the uber recorder when creating peds. /// PARAMS: /// modelPed - The new model, If set to DUMMY_MODEL_FOR_SCRIPT the uber recorder will revert to its own default. PROC SET_UBER_PLAYBACK_DEFAULT_PED_MODEL(MODEL_NAMES modelPed = DUMMY_MODEL_FOR_SCRIPT) modelDefaultPed = modelPed ENDPROC /// PURPOSE: /// If TRUE the header will set the default ped model as no longer needed after use. If FALSE it's left up to the mission script to remove the model. PROC SET_UBER_PLAYBACK_TO_CLEANUP_DEFAULT_PED_MODEL(BOOL bCleanup) bUberPlaybackRemoveDefaultPedModel = bCleanup ENDPROC /// PURPOSE: /// Replaces the driver of a vehicle in the uber chase with a ped using a given model. For use if there are vehicles in the chase that would require /// a custom ped different to the default selection. /// RETURNS: /// TRUE once the ped has been successfully swapped. FUNC BOOL OVERRIDE_VEHICLE_DRIVER_MODEL(VEHICLE_INDEX veh, MODEL_NAMES newModel, PED_TYPE pedType = PEDTYPE_MISSION) IF IS_VEHICLE_DRIVEABLE(veh) BOOL bOkToCreatePed = FALSE PED_INDEX ped = GET_PED_IN_VEHICLE_SEAT(veh) IF DOES_ENTITY_EXIST(ped) IF ped != PLAYER_PED_ID() IF GET_ENTITY_MODEL(ped) != newModel bOkToCreatePed = TRUE ELSE RETURN TRUE //Ped already exists and is the correct model. ENDIF ENDIF ELSE bOkToCreatePed = TRUE ENDIF IF bOkToCreatePed REQUEST_MODEL(newModel) IF HAS_MODEL_LOADED(newModel) IF DOES_ENTITY_EXIST(ped) SET_ENTITY_AS_MISSION_ENTITY(ped) DELETE_PED(ped) ENDIF /*IF IS_ENTITY_A_MISSION_ENTITY(ped) DELETE_PED(ped) ELSE VECTOR v_clear_pos = GET_PED_BONE_COORDS(ped, BONETAG_HEAD, <<0.0, 0.0, 0.0>>) SET_PED_AS_NO_LONGER_NEEDED(ped) CLEAR_AREA_OF_PEDS(v_clear_pos, 2.0) ENDIF*/ PED_INDEX pedNew = CREATE_PED_INSIDE_VEHICLE(veh, pedType, newModel, DEFAULT, FALSE, FALSE) IF IS_VEH_MODEL_A_COP_MODEL(GET_ENTITY_MODEL(veh)) SET_PED_RELATIONSHIP_GROUP_HASH(pedNew, rgh_traffic) ENDIF SET_PED_RANDOM_COMPONENT_VARIATION(pedNew) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(pedNew, TRUE) SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(pedNew, TRUE) SET_PED_SUFFERS_CRITICAL_HITS(pedNew, FALSE) SET_PED_CONFIG_FLAG(pedNew, PCF_WillFlyThroughWindscreen, FALSE) // B*1490105 - Used to stop released uber veh drivers interferring with chase by reacting to player shooting IF bSetReleasedDriversToExitOnFlee SET_PED_FLEE_ATTRIBUTES(pedNew, FA_DISABLE_ACCELERATE_IN_VEHICLE, TRUE) SET_PED_FLEE_ATTRIBUTES(pedNew, FA_FORCE_EXIT_VEHICLE, TRUE) SET_PED_FLEE_ATTRIBUTES(pedNew, FA_USE_VEHICLE, FALSE) SET_DISABLE_PRETEND_OCCUPANTS(veh, TRUE) // see B*1490105 - could affect fps ENDIF SET_MODEL_AS_NO_LONGER_NEEDED(newModel) MARK_CHAR_AS_NO_LONGER_NEEDED_KEEP_ID(pedNew) RETURN TRUE ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC PROC SWITCH_ALL_RANDOM_CARS_OFF() SET_ALL_VEHICLE_GENERATORS_ACTIVE_IN_AREA(<<-9000.0, -9000.0, -1000.0>>, <<9000.0, 9000.0, 1500.0>>, FALSE) SET_NUMBER_OF_PARKED_VEHICLES(0) SET_GARBAGE_TRUCKS(FALSE) SET_ALL_LOW_PRIORITY_VEHICLE_GENERATORS_ACTIVE(FALSE) SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.0) SET_VEHICLE_POPULATION_BUDGET(0) SET_PED_POPULATION_BUDGET(3) ENDPROC PROC SWITCH_ALL_RANDOM_CARS_ON() SET_ALL_VEHICLE_GENERATORS_ACTIVE() //SWITCH_ON_ACTIVATED_SCRIPT_CAR_GENS() SET_NUMBER_OF_PARKED_VEHICLES(-1) SET_GARBAGE_TRUCKS(TRUE) SET_ALL_LOW_PRIORITY_VEHICLE_GENERATORS_ACTIVE(TRUE) SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(1.0) SET_VEHICLE_POPULATION_BUDGET(3) SET_PED_POPULATION_BUDGET(3) ENDPROC /// PURPOSE: /// Call every frame to set the vehicle density based on the player's distance from the trigger car. PROC UPDATE_CAR_DENSITY_BASED_ON_PLAYERS_DISTANCE_FROM_CAR(VEHICLE_INDEX vehTrigger, FLOAT fRadius = 250.0) IF NOT (bSetPieceRecordingsHaveBeenActivated) IF NOT IS_ENTITY_DEAD(vehTrigger) IF IS_PLAYER_PLAYING(PLAYER_ID()) IF (VDIST2(GET_ENTITY_COORDS(vehTrigger), GET_ENTITY_COORDS(PLAYER_PED_ID())) > (fRadius * fRadius)) SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(1.0) ELSE SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.0) ENDIF ENDIF ENDIF ENDIF ENDPROC PROC UPDATE_CAR_POPULATION_BUDGET_BASED_ON_PLAYERS_DISTANCE_FROM_CAR(VEHICLE_INDEX vehTrigger, FLOAT fRadius = 250.0) IF NOT (bSetPieceRecordingsHaveBeenActivated) IF NOT IS_ENTITY_DEAD(vehTrigger) IF IS_PLAYER_PLAYING(PLAYER_ID()) IF (VDIST2(GET_ENTITY_COORDS(vehTrigger), GET_ENTITY_COORDS(PLAYER_PED_ID())) > (fRadius * fRadius)) SET_VEHICLE_POPULATION_BUDGET(1) ELSE SET_VEHICLE_POPULATION_BUDGET(0) ENDIF ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: /// Call this every frame before UPDATE_UBER_PLAYBACK to force cars to create without performing any visibility/optimisation checks. /// Intended use is for forcing cars to create in special cases and debug, calling this during normal playback may cause cars to pop into view. PROC CREATE_ALL_WAITING_UBER_CARS() bCreateAllWaitingCars = TRUE ENDPROC FUNC BOOL IS_POINT_VISIBLE_TO_PLAYER(VECTOR vPos, FLOAT fRadius, FLOAT fDistance = 100.0) VECTOR vPlayerPos VECTOR vDiff IF NOT IS_SCREEN_FADED_OUT() IF NOT (bSetPieceRecordingsHaveBeenActivated) IF NOT (bResetPlaybackToTime) IF IS_SPHERE_VISIBLE(vPos, fRadius) IF IS_PLAYER_PLAYING(PLAYER_ID()) vPlayerPos = GET_ENTITY_COORDS(PLAYER_PED_ID()) // vec from player to point vDiff = vPlayerPos - vPos // dist from player to edge of sphere IF ((VMAG(vDiff) - fRadius) < fDistance) RETURN(TRUE) ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF RETURN(FALSE) ENDFUNC /// PURPOSE: /// Private function for the uber header: checks if a point is visible or within a given distance of the player's position. /// Assumes the player's coord has already been passed, this is to cut down on uneccesary calls to fetch coords. FUNC BOOL private_IS_POINT_VISIBLE_TO_PLAYER_POS(VECTOR vPointPos, VECTOR vPlayerPos, FLOAT fRadius, FLOAT fDistance = 100.0) IF NOT IS_SCREEN_FADED_OUT() IF NOT (bSetPieceRecordingsHaveBeenActivated) IF NOT (bResetPlaybackToTime) // dist from player to edge of sphere IF ((VMAG2(vPlayerPos - vPointPos) - fRadius) < fDistance * fDistance) IF IS_SPHERE_VISIBLE(vPointPos, fRadius) RETURN TRUE ENDIF ENDIF ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC /// Private function for the uber header: clears an area of vehicles if safe to do so. PROC private_SAFE_CLEAR_AREA_OF_VEHICLES(VECTOR vPosToClear, VECTOR vPlayerPos, FLOAT fRadius) BOOL bSafeToClear = TRUE IF NOT (bSetPieceRecordingsHaveBeenActivated) IF NOT private_IS_POINT_VISIBLE_TO_PLAYER_POS(vPosToClear, vPlayerPos, fRadius, 200.0) // check player's last car is not in this area IF IS_PLAYER_PLAYING(PLAYER_ID()) VEHICLE_INDEX vehPlayersLastCar vehPlayersLastCar = GET_PLAYERS_LAST_VEHICLE() IF NOT IS_ENTITY_DEAD(vehPlayersLastCar) IF IS_ENTITY_AT_COORD(vehPlayersLastCar, vPosToClear, <>, FALSE, TRUE) bSafeToClear = FALSE ENDIF ENDIF ENDIF IF bSafeToClear CLEAR_AREA_OF_VEHICLES(vPosToClear, fRadius) ENDIF ENDIF ENDIF ENDPROC FUNC BOOL SAFELY_SET_VEHICLE_ON_GROUND_PROPERLY(VEHICLE_INDEX CarID) MODEL_NAMES CarModel IF NOT IS_ENTITY_DEAD(CarID) CarModel = GET_ENTITY_MODEL(CarID) IF IS_THIS_MODEL_A_CAR(CarModel) OR IS_THIS_MODEL_A_BIKE(CarModel) RETURN(SET_VEHICLE_ON_GROUND_PROPERLY(CarID)) ENDIF ENDIF RETURN(FALSE) ENDFUNC /// PURPOSE: /// Searches the array of active traffic recordings and finds a free index. Returns -1 if no index was found. FUNC INT GET_FREE_ACTIVE_CAR_SLOT() INT i REPEAT MAX_NUMBER_OF_TRAFFIC_CARS_PLAYING_BACK i IF NOT DOES_ENTITY_EXIST(ActiveTrafficCarID[i]) RETURN i ENDIF ENDREPEAT RETURN -1 ENDFUNC /// PURPOSE: /// Searches the array of recorded traffic cars and finds a free index. Returns -1 if no index was found. FUNC INT GET_FREE_RECORDED_TRAFFIC_CAR_SLOT() INT i REPEAT MAX_NUMBER_OF_TRAFFIC_CARS_PLAYING_BACK i IF NOT DOES_ENTITY_EXIST(RecordedTrafficCarID[i]) RETURN i ENDIF ENDREPEAT RETURN -1 ENDFUNC /// PURPOSE: /// Searches the array of recorded parked cars and finds a free index. Returns -1 if no index was found. FUNC INT GET_FREE_RECORDED_PARKED_CAR_SLOT() INT i REPEAT MAX_NUMBER_OF_PARKED_CARS_PLAYING_BACK i IF NOT DOES_ENTITY_EXIST(RecordedParkedCarID[i]) RETURN i ENDIF ENDREPEAT RETURN -1 ENDFUNC /// PURPOSE: /// Loads a vehicle recording and gets the total duration of it. FUNC FLOAT GET_RECORDING_LENGTH(INT iRecNo) REQUEST_VEHICLE_RECORDING(iRecNo, strUberName) WHILE NOT HAS_VEHICLE_RECORDING_BEEN_LOADED(iRecNo, strUberName) WAIT(0) ENDWHILE FLOAT fRecordingLength = GET_TOTAL_DURATION_OF_VEHICLE_RECORDING(iRecNo, strUberName) REMOVE_VEHICLE_RECORDING(iRecNo, strUberName) RETURN fRecordingLength ENDFUNC #IF IS_DEBUG_BUILD PROC SET_UBER_PARENT_WIDGET_GROUP(WIDGET_GROUP_ID parentWidgetGroupID) uberParentWidgetGroup = parentWidgetGroupID ENDPROC PROC CREATE_TRAFFIC_WIDGET() TEXT_LABEL str TEXT_LABEL_63 strWidgetName INT i IF bShowUberWidgets != bPrevShowUberWidgets AND bWidgetCreated DELETE_WIDGET_GROUP(uberWidgetGroup) bWidgetCreated = FALSE ENDIF bPrevShowUberWidgets = bShowUberWidgets IF NOT (bWidgetCreated) IF NOT IS_STRING_NULL(strUberName) strWidgetName = "UBER - " strWidgetName += strUberName ELSE strWidgetName = "Uber Playback / Recording" ENDIF IF (uberParentWidgetGroup != NULL) SET_CURRENT_WIDGET_GROUP(uberParentWidgetGroup) else SCRIPT_ASSERT("You have not called SET_UBER_PARENT_WIDGET_GROUP in traffic.sch") ENDIF uberWidgetGroup = START_WIDGET_GROUP(strWidgetName) ADD_WIDGET_BOOL("Show uber playback widgets", bShowUberWidgets) IF bShowUberWidgets START_WIDGET_GROUP("Playback") ADD_WIDGET_FLOAT_SLIDER("fMasterPlaybackSpeed", fMasterPlaybackSpeed, -5.0, 5.0, 0.001) ADD_WIDGET_FLOAT_SLIDER("Input playback speed", fInputPlaybackSpeed, -5.0, 100.0, 0.001) ADD_WIDGET_FLOAT_SLIDER("Current Playback Time", fTriggerCarPlaybackTime, 0.0, 9999999.9, 1000.0) ADD_WIDGET_BOOL("Pause Playback", bPausePlayback) ADD_WIDGET_BOOL("Delete cars when done", bDeleteCarsWhenDone) ADD_WIDGET_FLOAT_SLIDER("Reset Time", fResetTime, 0.0, 9999999.9, 1000.0) ADD_WIDGET_BOOL("Jump To Reset Time", bResetPlaybackToTime) ADD_WIDGET_INT_SLIDER("Trigger Car Recording", iTriggerCarRecordingNumber, -1, LAST_CAR_RECORDING_FILE_NUMBER, 1) ADD_WIDGET_BOOL("Show Trigger Car Path", bShowTriggerCarPath) ADD_WIDGET_BOOL("Output cleaned up data (may take a few seconds)", bOutputCleanedData) #IF IS_DEBUG_BUILD ADD_WIDGET_BOOL("Show debug output", bTrafficDebugOn) #ENDIF IF (bShowExtraTrafficWidgets) ADD_WIDGET_BOOL("Enable Re-Recording", bEnableReRecording) ENDIF ADD_WIDGET_FLOAT_SLIDER("fPausePlaybackTime", fPausePlaybackTime, 0.0, 1.0, 0.01) ADD_WIDGET_BOOL("bDontUpdateUberCars", bDontUpdateUberCars) ADD_WIDGET_BOOL("bCreateAllWaitingCars", bCreateAllWaitingCars) START_WIDGET_GROUP("Traffic") ADD_WIDGET_FLOAT_SLIDER("Streaming Distance", fPlaybackCarStreamingDistance, 0.0, 999.9, 1.0) #IF IS_DEBUG_BUILD ADD_WIDGET_INT_SLIDER("Highlighted Traffic Car", iHighlightedTrafficCar, -1 , TOTAL_NUMBER_OF_TRAFFIC_CARS, 1) #ENDIF ADD_WIDGET_INT_SLIDER("Current No Of Playbacks", iCurrentNumberOfTrafficPlaybacks, 0 , 99, 1) ADD_WIDGET_BOOL("Show Traffic Paths", bShowTrafficCarPaths) ADD_WIDGET_BOOL("Show Traffic Indices", bShowTrafficIndices) ADD_WIDGET_BOOL("Draw Traffic Progress", bDrawTrafficProgress) ADD_WIDGET_BOOL("Dont switch to AI", bTrafficDontSwitchToAI) ADD_WIDGET_INT_SLIDER("Cars Processed This Frame", iCarsProcessedThisFrame, -1, 1000, 1) ADD_WIDGET_INT_SLIDER("First Car to Process", iFirstCarToProcess, -1, 1000, 1) ADD_WIDGET_INT_SLIDER("iTrafficCarsWaitingToCreate", iTrafficCarsWaitingToCreate, -999, 999, 1) START_WIDGET_GROUP("Traffic Progress") REPEAT TOTAL_NUMBER_OF_TRAFFIC_CARS i str = "Progress[" str += i str += "]" ADD_WIDGET_INT_SLIDER(str,TrafficCarProgress[i], -1, 99, 1) str = "StartTime[" str += i str += "]" ADD_WIDGET_FLOAT_SLIDER(str, TrafficCarStartime[i], 0.0, 9999999.9, 1000.0) str = "StartPos[" str += i str += "].x" ADD_WIDGET_FLOAT_SLIDER(str, TrafficCarPos[i].x, -999999.9, 999999.9, 0.00001) str = "StartPos[" str += i str += "].y" ADD_WIDGET_FLOAT_SLIDER(str, TrafficCarPos[i].y, -999999.9, 999999.9, 0.00001) str = "StartPos[" str += i str += "].z" ADD_WIDGET_FLOAT_SLIDER(str, TrafficCarPos[i].z, -999999.9, 999999.9, 0.00001) ENDREPEAT STOP_WIDGET_GROUP() STOP_WIDGET_GROUP() START_WIDGET_GROUP("Parked Cars") #IF IS_DEBUG_BUILD ADD_WIDGET_INT_SLIDER("Highlighted Parked Car", iHighlightedParkedCar, -1 , TOTAL_NUMBER_OF_PARKED_CARS, 1) #ENDIF ADD_WIDGET_BOOL("Show parked cars", bShowParkedCars) ADD_WIDGET_INT_SLIDER("iCurrentNumberOfParkedCars", iCurrentNumberOfParkedCars, 0 , 99, 1) //ADD_WIDGET_INT_SLIDER("Cars Processed This Frame", iParkedCarsProcessedThisFrame, -1, 1000, 1) ADD_WIDGET_INT_SLIDER("First Car to Process", iFirstParkedCarToProcess, -1, 1000, 1) ADD_WIDGET_INT_SLIDER("iParkedCarsWaitingToCreate", iParkedCarsWaitingToCreate, -999, 999, 1) STOP_WIDGET_GROUP() START_WIDGET_GROUP("Set Piece Cars") ADD_WIDGET_INT_SLIDER("Current No Of Playbacks", iCurrentNumberOfSetPieceCarPlaybacks, 0 , 99, 1) ADD_WIDGET_BOOL("Show Set Piece Paths", bShowSetPiecePaths) ADD_WIDGET_BOOL("Show Set Piece Indices", bShowSetPieceIndices) ADD_WIDGET_BOOL("Draw Set Piece Progress", bDrawSetpieceProgress) ADD_WIDGET_INT_SLIDER("iSetPieceCarsWaitingToCreate", iSetPieceCarsWaitingToCreate, -999, 999, 1) ADD_WIDGET_INT_SLIDER("First Car to Process", iFirstSetpieceCarToProcess, -1, 1000, 1) ADD_WIDGET_BOOL("bDrawSpeedVector", bDrawSpeedVector) START_WIDGET_GROUP("Set Piece Progress") REPEAT TOTAL_NUMBER_OF_SET_PIECE_CARS i str = "Progress[" str += i str += "]" ADD_WIDGET_INT_SLIDER(str,SetPieceCarProgress[i], -1, 99, 1) str = "StartTime[" str += i str += "]" ADD_WIDGET_FLOAT_SLIDER(str, SetPieceCarStartime[i], 0.0, 9999999.9, 1000.0) str = "StartPos[" str += i str += "].x" ADD_WIDGET_FLOAT_SLIDER(str, SetPieceCarPos[i].x, -999999.9, 999999.9, 0.00001) str = "StartPos[" str += i str += "].y" ADD_WIDGET_FLOAT_SLIDER(str, SetPieceCarPos[i].y, -999999.9, 999999.9, 0.00001) str = "StartPos[" str += i str += "].z" ADD_WIDGET_FLOAT_SLIDER(str, SetPieceCarPos[i].z, -999999.9, 999999.9, 0.00001) ENDREPEAT STOP_WIDGET_GROUP() START_WIDGET_GROUP("Convert Set Piece cars To Traffic cars") REPEAT TOTAL_NUMBER_OF_SET_PIECE_CARS i IF (SetPieceCarRecordingSpeed[i] = 1.0) str = "Car number " str += i ADD_WIDGET_BOOL(str, bSetPieceCarsToConvert[i]) ENDIF ENDREPEAT ADD_WIDGET_BOOL("Convert & output new data (will take a few seconds)", bOutputCleanedData) STOP_WIDGET_GROUP() STOP_WIDGET_GROUP() START_WIDGET_GROUP("Random Cars") ADD_WIDGET_BOOL("Clear Random Cars", bCarsAreOn) ADD_WIDGET_FLOAT_SLIDER("Clear Distance", fClearSurroundingCarsDistance, 0.0, 500.0, 1.0) STOP_WIDGET_GROUP() START_WIDGET_GROUP("Air Resistance") ADD_WIDGET_FLOAT_SLIDER("Current Air Resistance", fAirRes, 1.0, 15.0, 0.01) ADD_WIDGET_FLOAT_SLIDER("Max Air Resistance", fMaxAirRes, 1.0, 15.0, 0.01) ADD_WIDGET_FLOAT_SLIDER("Min Air Resistance", fMinAirRes, 1.0, 15.0, 0.01) ADD_WIDGET_FLOAT_SLIDER("Air Resistance Multiplier", fAirResMultiplier, 0.0, 5.0, 0.01) STOP_WIDGET_GROUP() START_WIDGET_GROUP("Debug Stuff") ADD_WIDGET_BOOL("bAllRandomCarsAreSwitchedOn", bAllRandomCarsAreSwitchedOn) ADD_WIDGET_FLOAT_SLIDER("fPlaybackSpeedMaxAcceleration", fPlaybackSpeedMaxAcceleration, 0.0, 5.0, 0.01) ADD_WIDGET_FLOAT_SLIDER("fPlaybackSpeedMaxDecceleration", fPlaybackSpeedMaxDecceleration, 0.0, 5.0, 0.01) ADD_WIDGET_BOOL("bPlayerIsAheadOfChase", bPlayerIsAheadOfChase) ADD_WIDGET_FLOAT_SLIDER("fSwitchOffRoadDist", fSwitchOffRoadDist, 0.0, 1000.0, 1.0) ADD_WIDGET_BOOL("bCalculatePlaybackSpeedInitialised", bCalculatePlaybackSpeedInitialised) ADD_WIDGET_BOOL("bCreateAllWaitingCars", bCreateAllWaitingCars) STOP_WIDGET_GROUP() STOP_WIDGET_GROUP() START_WIDGET_GROUP("Recording") ADD_WIDGET_BOOL("Start Recording", bStartRecordingPlayersCarWithTraffic) ADD_WIDGET_FLOAT_SLIDER("Recording Time", fRecordingTimer, 0.0, 9999999.9, 1.0) ADD_WIDGET_BOOL("Reset to start position", bResetToStartPosition) ADD_WIDGET_BOOL("Clear surrounding area", bClearArea) ADD_WIDGET_FLOAT_SLIDER("Car Density Multiplier", fCarDensityMultiplier, 0.0, 100.0, 0.1) START_WIDGET_GROUP("Trigger Car") ADD_WIDGET_INT_SLIDER("Recording File", iMainCarRecordingFile, 0, LAST_CAR_RECORDING_FILE_NUMBER, 1) STOP_WIDGET_GROUP() START_WIDGET_GROUP("Traffic") ADD_WIDGET_INT_SLIDER("First Traffic Recording File", iInitialRecordingFileNumber, 0, LAST_CAR_RECORDING_FILE_NUMBER, 1) ADD_WIDGET_INT_SLIDER("Current No Of Recordings", iCurrentNumberOfTrafficRecordings, 0, 99, 1) ADD_WIDGET_INT_SLIDER("Total No Of Recordings", iTotalNumberOfTrafficCarsRecorded, 0, TOTAL_NUMBER_OF_TRAFFIC_CARS, 1) ADD_WIDGET_FLOAT_SLIDER("Recording Distance", fRecordingDistance, 0.0, 200.0, 1.0) ADD_WIDGET_FLOAT_SLIDER("Recording Offset", fMinRecordingOffset, 0.0, 100.0, 0.1) ADD_WIDGET_FLOAT_SLIDER("Recording Angle", fRecordingAngle, 0.0, 179.0, 1.0) ADD_WIDGET_FLOAT_SLIDER("Recording Height Angle", fRecordingHeightAngle, 0.0, 89.0, 1.0) ADD_WIDGET_FLOAT_SLIDER("Recording Min Width", fRecordingMinWidth, 0.0, 20.0, 0.1) ADD_WIDGET_FLOAT_SLIDER("Recording Min Height", fRecordingMinHeight, 0.0, 20.0, 0.1) ADD_WIDGET_BOOL("Draw Recording Cone", bShowRecordingCone) //ADD_WIDGET_BOOL("Delete when recorded", bDeleteTrafficWhenRecorded) ADD_WIDGET_FLOAT_SLIDER("fRecordingClearAreaPercentageOfCone", fRecordingClearAreaPercentageOfCone, 0.0, 1.0, 0.01) ADD_WIDGET_FLOAT_SLIDER("fTrafficRecordingDistanceAroundCar", fTrafficRecordingDistanceAroundCar, 0.0, 100.0, 0.1) ADD_WIDGET_BOOL("bDeleteRedundantTrafficCars", bDeleteRedundantTrafficCars) STOP_WIDGET_GROUP() START_WIDGET_GROUP("Parked Cars") ADD_WIDGET_BOOL("Output current vehicle as a parked car", bOutputParkedCarInfo) ADD_WIDGET_BOOL("stop parked cars spawning", bStopParkedCarsFromBeingSpawned) ADD_WIDGET_BOOL("include parked cars", bIncludeParkedCars) ADD_WIDGET_INT_SLIDER("iTotalNumberOfParkedCarsRecorded", iTotalNumberOfParkedCarsRecorded, 0, 99, 1) ADD_WIDGET_BOOL("bDeleteRedundantParkedCars", bDeleteRedundantParkedCars) STOP_WIDGET_GROUP() START_WIDGET_GROUP("Set Piece Cars") ADD_WIDGET_BOOL("Set Environment for set piece recording", bSetPieceRecordingsAreActive) ADD_WIDGET_BOOL("Allow set piece recording overwrite", bAllowSetPieceRecOverwrite) ADD_WIDGET_BOOL("record new car", bStartRecordingSetPieceCar) ADD_WIDGET_INT_SLIDER("iSetPieceCarRecordingFile", iSetPieceCarRecordingFile, 0 , LAST_CAR_RECORDING_FILE_NUMBER, 1) ADD_WIDGET_FLOAT_SLIDER("fNewSetPieceTriggerTime", fNewSetPieceTriggerTime, 0.0, 99999999.9, 1.0) ADD_WIDGET_BOOL("Grab current position as start", bReGrabSetPiecePositionAndQuat) ADD_WIDGET_BOOL("bResetSetPiece", bResetSetPiece) #IF IS_DEBUG_BUILD START_WIDGET_GROUP("Set piece re-record") ADD_WIDGET_INT_SLIDER("Set piece array index", iSetPieceReRecNum, 0 , (TOTAL_NUMBER_OF_SET_PIECE_CARS-1), 1) ADD_WIDGET_BOOL("Load set piece data and go to start", bLoadSetPieceDataForReRec) ADD_WIDGET_INT_SLIDER("New setpiece recording number", iSetPieceReRecNewRecNum, 0 , LAST_CAR_RECORDING_FILE_NUMBER, 1) add_widget_bool("Start Recording when accelerator is pressed?", bStartReRecOnButtonPress) ADD_WIDGET_BOOL("Start recording", bStartSetPieceReRec) add_widget_bool("Stop Recording when PS SQUARE OR XBOX X is pressed", bStopSetPieceReRecOnButtonPress) add_widget_bool("Show Setpiece Recording Path", bShowSetPieceReRecPath) add_widget_bool("Show Setpiece Ghost Car", bShowSetPieceReRecGhost) STOP_WIDGET_GROUP() #ENDIF STOP_WIDGET_GROUP() IF (bShowExtraTrafficWidgets) START_WIDGET_GROUP("Re-Recording") ADD_WIDGET_BOOL("bReRecordingIsEnabled", bReRecordingIsEnabled) ADD_WIDGET_BOOL("bReRecordingControlHijacked", bReRecordingControlHijacked) STOP_WIDGET_GROUP() ENDIF STOP_WIDGET_GROUP() ENDIF STOP_WIDGET_GROUP() IF (uberParentWidgetGroup != NULL) CLEAR_CURRENT_WIDGET_GROUP(uberParentWidgetGroup) ENDIF bWidgetCreated = TRUE ENDIF ENDPROC #ENDIF /// PURPOSE: /// Private function for the traffic header: creates a ped inside a given uber playback vehicle, will determine the right ped based on vehicle type and availability /// of ambient ped models. NOTE: assumes that the ped model has already loaded. /// PARAMS: /// veh - The vehicle to add the ped inside /// modelVeh - The model of the vehicle /// ePedModelToUse - Which model typre to use (e.g. cops, default, or attempt to use ambient population). /// RETURNS: /// TRUE if the ped successfully created. FUNC BOOL private_CREATE_PED_INSIDE_UBER_PLAYBACK_CAR(VEHICLE_INDEX &veh, UBER_PLAYBACK_PED_MODEL ePedModelToUse, BOOL bCarIsASetpiece = FALSE) IF NOT IS_ENTITY_DEAD(veh) IF IS_VEHICLE_SEAT_FREE(veh, VS_DRIVER) PED_INDEX pedTemp IF ePedModelToUse = UBER_PLAYBACK_PED_MODEL_COP pedTemp = CREATE_PED_INSIDE_VEHICLE(veh, PEDTYPE_COP, COP_PED_MODEL(), DEFAULT, FALSE, FALSE) SET_PED_RELATIONSHIP_GROUP_HASH(pedTemp, rgh_traffic) SET_MODEL_AS_NO_LONGER_NEEDED(COP_PED_MODEL()) ELIF ePedModelToUse = UBER_PLAYBACK_PED_MODEL_AMBIENT pedTemp = CREATE_RANDOM_PED_AS_DRIVER(veh) IF IS_THIS_MODEL_A_BIKE(GET_ENTITY_MODEL(veh)) GIVE_PED_HELMET(pedTemp) ENDIF ELSE pedTemp = CREATE_PED_INSIDE_VEHICLE(veh, PEDTYPE_CIVMALE, DEFAULT_PED_MODEL(), DEFAULT, FALSE, FALSE) IF bUberPlaybackRemoveDefaultPedModel SET_MODEL_AS_NO_LONGER_NEEDED(DEFAULT_PED_MODEL()) ENDIF ENDIF IF bCarIsASetpiece SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(pedTemp, TRUE) SET_PED_SUFFERS_CRITICAL_HITS(pedTemp, FALSE) SET_PED_CONFIG_FLAG(pedTemp, PCF_WillFlyThroughWindscreen, FALSE) ENDIF // B*1490105 - Used to stop released uber veh drivers interferring with chase by reacting to player shooting IF bSetReleasedDriversToExitOnFlee SET_PED_FLEE_ATTRIBUTES(pedTemp, FA_DISABLE_ACCELERATE_IN_VEHICLE, TRUE) SET_PED_FLEE_ATTRIBUTES(pedTemp, FA_FORCE_EXIT_VEHICLE, TRUE) SET_PED_FLEE_ATTRIBUTES(pedTemp, FA_USE_VEHICLE, FALSE) SET_DISABLE_PRETEND_OCCUPANTS(veh, TRUE) // see B*1490105 - could affect fps ENDIF SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(pedTemp, TRUE) MARK_CHAR_AS_NO_LONGER_NEEDED_KEEP_ID(pedTemp) bCreatedUberPlaybackEntityThisFrame = TRUE #IF IS_DEBUG_BUILD IF (bTrafficDebugOn) PRINTLN("traffic.sch - private_CREATE_PED_INSIDE_UBER_PLAYBACK_CAR ", fTriggerCarPlaybackTime, " bCarIsASetpiece = ", PICK_INT(bCarIsASetpiece, 1, 0)) ENDIF #ENDIF RETURN TRUE ELSE //Already a ped in the seat, just RETURN TRUE. RETURN TRUE ENDIF ENDIF RETURN FALSE ENDFUNC FUNC FLOAT GET_DISTANCE_FROM_LEAD_CAR(VEHICLE_INDEX LeadCar, VEHICLE_INDEX FollowCar) // Car A is assumed to be the car in front VECTOR vForward VECTOR vAB VECTOR vPosA VECTOR vPosB FLOAT fAngle IF IS_VEHICLE_DRIVEABLE(LeadCar) vForward.x = GET_ENTITY_FORWARD_X(LeadCar) vForward.y = GET_ENTITY_FORWARD_Y(LeadCar) vPosA = GET_ENTITY_COORDS(LeadCar) ENDIF IF IS_VEHICLE_DRIVEABLE(FollowCar) vPosB = GET_ENTITY_COORDS(FollowCar) ENDIF vAB = vPosB - vPosA fAngle = GET_ANGLE_BETWEEN_2D_VECTORS(vAB.x, vAB.y, vForward.x, vForward.y) fAngle += -90.0 IF (fAngle < 0.0) fAngle *= -1.0 ENDIF vAB.z = 0.0 RETURN VMAG(vAB) * SIN(fAngle) ENDFUNC FUNC BOOL IS_CAR_FURTHER_IN_FRONT_THAN_WIDE(VEHICLE_INDEX LeadCar, VEHICLE_INDEX FollowCar) IF NOT IS_ENTITY_DEAD(LeadCar) AND NOT IS_ENTITY_DEAD(FollowCar) VECTOR vOffset = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(LeadCar, GET_ENTITY_COORDS(FollowCar)) IF ABSF(vOffset.y) > ABSF(vOffset.x) RETURN TRUE ENDIF ENDIF RETURN FALSE ENDFUNC FUNC FLOAT GET_CHAR_DISTANCE_FROM_LEAD_CAR(VEHICLE_INDEX LeadCar, PED_INDEX FollowChar) // Car A is assumed to be the car in front VECTOR vForward VECTOR vAB VECTOR vPosA VECTOR vPosB FLOAT fAngle IF IS_VEHICLE_DRIVEABLE(LeadCar) vForward.x = GET_ENTITY_FORWARD_X(LeadCar) vForward.y = GET_ENTITY_FORWARD_Y(LeadCar) vPosA = GET_ENTITY_COORDS(LeadCar) ENDIF IF NOT IS_ENTITY_DEAD(FollowChar) vPosB = GET_ENTITY_COORDS(FollowChar) ENDIF vAB = vPosB - vPosA fAngle = GET_ANGLE_BETWEEN_2D_VECTORS(vAB.x, vAB.y, vForward.x, vForward.y) fAngle += -90.0 IF (fAngle < 0.0) fAngle *= -1.0 ENDIF vAB.z = 0.0 RETURN(VMAG(vAB) * SIN(fAngle)) ENDFUNC FUNC FLOAT GET_ACTUAL_CHAR_DISTANCE_FROM_LEAD_CAR(VEHICLE_INDEX LeadCar, PED_INDEX FollowChar) // Car A is assumed to be the car in front VECTOR vPosA VECTOR vPosB VECTOR vAB FLOAT fDist IF NOT IS_ENTITY_DEAD(LeadCar) vPosA = GET_ENTITY_COORDS(LeadCar) ENDIF IF NOT IS_ENTITY_DEAD(FollowChar) vPosB = GET_ENTITY_COORDS(FollowChar) ENDIF vAB = vPosB - vPosA vAB.z = 0.0 fDist = VMAG(vAB) RETURN(fDist) ENDFUNC FUNC FLOAT GET_DIFF_IN_SPEED_HEADINGS_BETWEEN_CHAR_AND_LEAD_CAR(VEHICLE_INDEX LeadCar, PED_INDEX FollowChar) VECTOR vA VECTOR vPosB, vPosB2, vB FLOAT fDiff VEHICLE_INDEX temp_car IF NOT IS_ENTITY_DEAD(LeadCar) // GET_VEHICLE_COORDS @_return_by_value(LeadCar, vPosA.x, vPosA.y, vPosA.z) // GET_OFFSET_FROM_VEHICLE_IN_WORLD_COORDS @_return_by_value(LeadCar, 0.0, 5.0, 0.0, vPosA2.x, vPosA2.y, vPosA2.z) // vA = vPosA2 - vPosA vA.x = GET_ENTITY_FORWARD_X(LeadCar) vA.y = GET_ENTITY_FORWARD_Y(LeadCar) ENDIF IF NOT IS_ENTITY_DEAD(FollowChar) vPosB = GET_ENTITY_COORDS(FollowChar) IF IS_PED_IN_ANY_VEHICLE(FollowChar) temp_car = GET_VEHICLE_PED_IS_IN(FollowChar) //GET_OFFSET_FROM_VEHICLE_IN_WORLD_COORDS @_return_by_value(FollowChar, 0.0, 5.0, 0.0, vPosB2.x, vPosB2.y, vPosB2.z) vB.x = GET_ENTITY_FORWARD_X(temp_car) vB.y = GET_ENTITY_FORWARD_Y(temp_car) ELSE vPosB2 = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(FollowChar, <<0.0, 5.0, 0.0>>) vB = vPosB2 - vPosB ENDIF //LINE(vPosB.x, vPosB.y, vPosB.z, vPosB2.x, vPosB2.y, vPosB2.z) ENDIF fDiff = GET_ANGLE_BETWEEN_2D_VECTORS(vA.x, vA.y, vB.x, vB.y) RETURN(fDiff) ENDFUNC FUNC BOOL IS_CAR_IN_FRONT_OF_CAR(VEHICLE_INDEX inCar1, VEHICLE_INDEX inCar2, BOOL bBaseOnCar2Speed = FALSE) VECTOR posA // car1 position VECTOR posB // car2 position VECTOR posC VECTOR vecAB // vector from car1 to car2 VECTOR vecCar2 // unit vector pointing in the direction the car2 is facing VECTOR vVel // get positions IF IS_VEHICLE_DRIVEABLE(inCar1) posA = GET_ENTITY_COORDS(inCar1) ENDIF IF IS_VEHICLE_DRIVEABLE(inCar2) posB = GET_ENTITY_COORDS(inCar2) // get unit vector pointing forwards from car2 IF bBaseOnCar2Speed vVel = GET_ENTITY_VELOCITY(inCar2) vecCar2 = vVel / VMAG(vVel) ELSE posC = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(inCar2, <<0.0, 5.0, 0.0>>) vecCar2 = posC - posB ENDIF ENDIF // get vec from car1 to car2 vecAB = posB - posA // take the z out vecAB.z = 0.0 vecCar2.z = 0.0 // calculate dot product of vecAB and vecCar2 IF (DOT_PRODUCT(vecAB,vecCar2) < 0.0) RETURN(TRUE) ENDIF RETURN(FALSE) ENDFUNC FUNC BOOL IS_PED_IN_FRONT_OF_CAR(PED_INDEX inPed, VEHICLE_INDEX inCar) VECTOR posA // ped position VECTOR posB // car position VECTOR posC VECTOR vecAB // vector from ped to car VECTOR vecCar // unit vector pointing in the direction the car is facing FLOAT fTemp // If ped is in this car RETURN FALSE IF NOT IS_PED_INJURED(inPed) IF NOT IS_ENTITY_DEAD(inCar) IF IS_PED_IN_VEHICLE(inPed, inCar) RETURN(FALSE) ENDIF ENDIF ENDIF // get positions IF NOT IS_ENTITY_DEAD(inPed) posA = GET_ENTITY_COORDS(inPed) ENDIF IF IS_VEHICLE_DRIVEABLE(inCar) posB = GET_ENTITY_COORDS(inCar) // get unit vector pointing forwards from car posC = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(inCar, <<0.0, 5.0, 0.0>>) vecCar = posC - posB ENDIF // get vec from ped to car vecAB = posB - posA // take the z out vecAB.z = 0.0 vecCar.z = 0.0 // calculate dot product of vecAB and vecCar2 fTemp = DOT_PRODUCT(vecAB,vecCar) IF (fTemp < 0.0) RETURN(TRUE) ENDIF RETURN(FALSE) ENDFUNC FUNC BOOL ARE_CARS_TRAVELLING_IN_SAME_DIRECTION(VEHICLE_INDEX inCar1, VEHICLE_INDEX inCar2) VECTOR vForward1 VECTOR vForward2 FLOAT fTemp IF IS_VEHICLE_DRIVEABLE(inCar1) vForward1 = GET_ENTITY_SPEED_VECTOR(inCar1) ELSE RETURN(FALSE) ENDIF IF IS_VEHICLE_DRIVEABLE(inCar2) vForward2 = GET_ENTITY_SPEED_VECTOR(inCar2) ELSE RETURN(FALSE) ENDIF // ignore the z vForward1.z = 0.0 vForward2.z = 0.0 fTemp = DOT_PRODUCT(vForward1,vForward2) IF (fTemp < 0.0) RETURN(FALSE) ENDIF RETURN(TRUE) ENDFUNC FUNC BOOL ARE_CARS_TRAVELLING_IN_SAME_DIRECTION_BELOW_ANGLE(VEHICLE_INDEX inCar1, VEHICLE_INDEX inCar2, FLOAT fInAngle) VECTOR vForward1 VECTOR vForward2 FLOAT fTemp IF IS_VEHICLE_DRIVEABLE(inCar1) vForward1 = GET_ENTITY_SPEED_VECTOR(inCar1) ELSE RETURN(FALSE) ENDIF IF IS_VEHICLE_DRIVEABLE(inCar2) vForward2 = GET_ENTITY_SPEED_VECTOR(inCar2) ELSE RETURN(FALSE) ENDIF // ignore the z vForward1.z = 0.0 vForward2.z = 0.0 fTemp = DOT_PRODUCT(vForward1,vForward2) IF (fTemp < 0.0) RETURN(FALSE) ENDIF // check is within angle fTemp = GET_ANGLE_BETWEEN_2D_VECTORS(vForward1.x, vForward1.y, vForward2.x, vForward2.y) IF NOT (fTemp < fInAngle) RETURN(FALSE) ENDIF RETURN(TRUE) ENDFUNC PROC DRAW_CAR_SPEED_VECTOR(VEHICLE_INDEX inCar) VECTOR vForward VECTOR vPos IF IS_VEHICLE_DRIVEABLE(inCar) vForward = GET_ENTITY_SPEED_VECTOR(inCar) vForward *= 5.0 vPos = GET_ENTITY_COORDS(inCar) DRAW_DEBUG_LINE(vPos, <>) ENDIF ENDPROC FUNC BOOL SET_CAR_AT_PLAYBACK_POSITION(VEHICLE_INDEX &InCar, INT iRec, FLOAT fTime, BOOL bPlay, BOOL bUseAI, BOOL bForceUpdate = FALSE, BOOL bSwitchToAIOnPlayerImpact = FALSE, BOOL bSwitchToAIOnAnyImpact = FALSE) FLOAT fTemp IF (iRec > 0) REQUEST_VEHICLE_RECORDING(iRec, strUberName) IF HAS_VEHICLE_RECORDING_BEEN_LOADED(iRec, strUberName) IF IS_VEHICLE_DRIVEABLE(InCar) IF NOT IS_PLAYBACK_GOING_ON_FOR_VEHICLE(InCar) FREEZE_ENTITY_POSITION(InCar, FALSE) IF (bUseAI) START_PLAYBACK_RECORDED_VEHICLE_USING_AI(InCar, iRec, strUberName) ELSE IF iRec != iDontSwitchThisSetpieceRecordingToAI AND iRec != iDontSwitchThisSetpieceRecordingToAI2 IF bSwitchToAIOnAnyImpact START_PLAYBACK_RECORDED_VEHICLE_WITH_FLAGS(InCar, iRec, strUberName, ENUM_TO_INT(SWITCH_ON_ANY_VEHICLE_IMPACT) | ENUM_TO_INT(TURN_ON_ENGINE_INSTANTLY)) ELIF bSwitchToAIOnPlayerImpact START_PLAYBACK_RECORDED_VEHICLE_WITH_FLAGS(InCar, iRec, strUberName, ENUM_TO_INT(SWITCH_ON_PLAYER_VEHICLE_IMPACT) | ENUM_TO_INT(TURN_ON_ENGINE_INSTANTLY)) ELSE START_PLAYBACK_RECORDED_VEHICLE(InCar, iRec, strUberName) ENDIF ELSE START_PLAYBACK_RECORDED_VEHICLE(InCar, iRec, strUberName) ENDIF SKIP_TIME_IN_PLAYBACK_RECORDED_VEHICLE(InCar, fTime) IF bForceUpdate FORCE_PLAYBACK_RECORDED_VEHICLE_UPDATE(InCar) ENDIF RETURN(TRUE) ENDIF ELSE IF (GET_CURRENT_PLAYBACK_FOR_VEHICLE(InCar) = GET_VEHICLE_RECORDING_ID(iRec, strUberName)) fTemp = GET_TIME_POSITION_IN_RECORDING(InCar) SKIP_TIME_IN_PLAYBACK_RECORDED_VEHICLE(InCar, (fTime - fTemp)) IF NOT (bPlay) STOP_PLAYBACK_RECORDED_VEHICLE(InCar) REQUEST_VEHICLE_RECORDING(iRec, strUberName) ENDIF IF bForceUpdate FORCE_PLAYBACK_RECORDED_VEHICLE_UPDATE(InCar) ENDIF RETURN(TRUE) ELSE STOP_PLAYBACK_RECORDED_VEHICLE(InCar) FREEZE_ENTITY_POSITION(InCar, FALSE) IF (bUseAI) START_PLAYBACK_RECORDED_VEHICLE_USING_AI(InCar, iRec, strUberName) ELSE IF iRec != iDontSwitchThisSetpieceRecordingToAI AND iRec != iDontSwitchThisSetpieceRecordingToAI2 IF bSwitchToAIOnAnyImpact START_PLAYBACK_RECORDED_VEHICLE_WITH_FLAGS(InCar, iRec, strUberName, ENUM_TO_INT(SWITCH_ON_ANY_VEHICLE_IMPACT) | ENUM_TO_INT(TURN_ON_ENGINE_INSTANTLY)) ELIF bSwitchToAIOnPlayerImpact START_PLAYBACK_RECORDED_VEHICLE_WITH_FLAGS(InCar, iRec, strUberName, ENUM_TO_INT(SWITCH_ON_PLAYER_VEHICLE_IMPACT) | ENUM_TO_INT(TURN_ON_ENGINE_INSTANTLY)) ELSE START_PLAYBACK_RECORDED_VEHICLE(InCar, iRec, strUberName) ENDIF ELSE START_PLAYBACK_RECORDED_VEHICLE(InCar, iRec, strUberName) ENDIF ENDIF SKIP_TIME_IN_PLAYBACK_RECORDED_VEHICLE(InCar, fTime) IF bForceUpdate FORCE_PLAYBACK_RECORDED_VEHICLE_UPDATE(InCar) ENDIF RETURN(TRUE) ENDIF ENDIF ENDIF ENDIF ELSE #IF IS_DEBUG_BUILD SCRIPT_ASSERT("SET_CAR_AT_PLAYBACK_POSITION - recording ID must be greater than 0.") #ENDIF ENDIF RETURN(FALSE) ENDFUNC /// PURPOSE: /// New rubber-banding procedure for GTA V: takes into account special abilities and can reduce the player's max speed using new commands. /// PARAMS: /// fDesiredPlaybackSpeed - Stores the calculated speed. /// vehPlayer - The player's vehicle /// vehTrigger - The trigger vehicle /// fClosestDist - The minimum distance the player should be behind the trigger. /// fIdealDist - The ideal distance you want the player to be behind the trigger. /// fMaxDist - The max distance the player should be behind the trigger. /// fLosingTriggerDist - At this distance or greater extra slowdown will be applied if safe to do so. /// fMaxDistInFront - If the player is ahead the speed is increased, the max speed is achieved at this distance. /// fDefaultPlaybackSpeed - The default playback speed: when at the ideal distance the chase will run around this speed. /// fMinSpeedIfBehind - The minimum playback speed allowed if behind, values lower than 0.7 may be too noticeable. /// fMinSpeedIfLosingTrigger - The minimum playback speed allowed if the player is really far behind (this value is only used IF the trigger is not visible). /// fMaxSpeedIfTooClose - The max speed allowed if the player gets too close. /// bApplySlowdownToPlayer - If TRUE slowdown will be applied to the player based on playback speed (using MODIFY_VEHICLE_TOP_SPEED). /// fDefaultSlowdownPercent - The default percentage of top speed removed from the player. /// fMaxPlayerSlowdownPercent - The maximum percentage of top speed that can be removed from the player. /// bAccountForSpecialAbility - If TRUE then extra adjustments are made when Franklin's special ability is active. PROC CALCULATE_DESIRED_PLAYBACK_SPEED_FROM_TRIGGER_CAR(FLOAT &fDesiredPlaybackSpeed, VEHICLE_INDEX &vehPlayer, VEHICLE_INDEX vehTrigger, FLOAT fClosestDist = 5.0, FLOAT fIdealDist = 10.0, FLOAT fMaxDist = 50.0, FLOAT fLosingTriggerDist = 100.0, FLOAT fMaxDistInFront = 30.0, FLOAT fDefaultPlaybackSpeed = 1.0, FLOAT fMinSpeedIfBehind = 0.7, FLOAT fMinSpeedIfLosingTrigger = 0.5, FLOAT fMaxSpeedIfTooClose = 2.0, BOOL bApplySlowdownToPlayer = FALSE, FLOAT fDefaultSlowdownPercent = 0.0, FLOAT fMaxSlowdownPercent = 15.0, BOOL bAccountForSpecialAbility = TRUE) VECTOR vPlayerPos = GET_ENTITY_COORDS(vehPlayer) VECTOR vTriggerPos = GET_ENTITY_COORDS(vehTrigger) VECTOR vOffset = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(vehTrigger, vPlayerPos) FLOAT fDist = VDIST(vPlayerPos, vTriggerPos) FLOAT fDistRatio = 0.0 FLOAT fMaxSpeedToAddIfClose = fMaxSpeedIfTooClose - 1.0 FLOAT fMaxSpeedToRemoveIfBehind = 1.0 - fMinSpeedIfBehind IF vOffset.y < 1.0 //Player is behind the car. IF fDist > fMaxDist //Player is a long way behind, slow the trigger car down even more (if not on screen). BOOL bReallyFarBehind = FALSE IF fDist > fLosingTriggerDist IF fDist > fLosingTriggerDist * 2.0 bReallyFarBehind = TRUE ENDIF fDist = fLosingTriggerDist ENDIF fDistRatio = ((fDist - fMaxDist) / (fLosingTriggerDist - fMaxDist)) IF NOT IS_ENTITY_ON_SCREEN(vehTrigger) OR bReallyFarBehind fDesiredPlaybackSpeed = fMinSpeedIfBehind - ((fMinSpeedIfBehind - fMinSpeedIfLosingTrigger) * fDistRatio) ELSE //Not safe to slow down any further, so cap at min speed. fDesiredPlaybackSpeed = fMinSpeedIfBehind ENDIF ELIF fDist > fIdealDist //Player is slightly behind ideal distance. Slow the trigger car down relative to how far behind the player is. fDistRatio = ((fDist - fIdealDist) / (fMaxDist - fIdealDist)) fDesiredPlaybackSpeed = 1.0 - (fMaxSpeedToRemoveIfBehind * fDistRatio) ELSE //Player is getting too close, speed up the trigger car relative to how close the player is. IF fDist < fClosestDist fDist = fClosestDist ENDIF fDistRatio = (fIdealDist - fDist) / (fIdealDist - fClosestDist) IF IS_SPECIAL_ABILITY_ACTIVE(PLAYER_ID()) AND bAccountForSpecialAbility fDesiredPlaybackSpeed = 1.0 + ((fDistRatio * fMaxSpeedToAddIfClose) * 2.0) ELSE fDesiredPlaybackSpeed = 1.0 + (fDistRatio * fMaxSpeedToAddIfClose) ENDIF ENDIF ELSE //Player is in front, speed up trigger car based on the player's own speed. IF fDist > fMaxDistInFront fDist = fMaxDistInFront ENDIF fDistRatio = fDist / fMaxDistInFront FLOAT fSpeedDiff = GET_ENTITY_SPEED(vehTrigger) - GET_ENTITY_SPEED(vehPlayer) //If the player is already going slower then don't speed up the buddy as much. IF fSpeedDiff > 0.0 fDistRatio = fDistRatio * 0.5 ENDIF IF IS_SPECIAL_ABILITY_ACTIVE(PLAYER_ID()) AND bAccountForSpecialAbility fDesiredPlaybackSpeed = 2.0 + fDistRatio ELSE IF GET_ENTITY_SPEED(vehPlayer) < 5.0 AND fSpeedDiff > 0.0 //If the player has slowed down slow the buddy down so it's not as harsh if they plough through. fDesiredPlaybackSpeed = 0.6 + fDistRatio ELSE fDesiredPlaybackSpeed = 1.0 + fDistRatio ENDIF ENDIF ENDIF //Adjust final value for any differences in the default. fDesiredPlaybackSpeed = fDesiredPlaybackSpeed * fDefaultPlaybackSpeed //Modify the player's speed if the desired playback speed is getting too much. IF bApplySlowdownToPlayer FLOAT fPlayersSpeedModifier = fDefaultSlowdownPercent IF IS_SPECIAL_ABILITY_ACTIVE(PLAYER_ID()) AND bAccountForSpecialAbility fMaxSlowdownPercent = fMaxSlowdownPercent * 2.0 fDefaultSlowdownPercent = fDefaultSlowdownPercent * 2.0 ENDIF IF fDesiredPlaybackSpeed > 1.0 fPlayersSpeedModifier = fDefaultSlowdownPercent + ((fMaxSlowdownPercent - fDefaultSlowdownPercent) * (fDesiredPlaybackSpeed - 1.0)) ENDIF MODIFY_VEHICLE_TOP_SPEED(vehPlayer, -fPlayersSpeedModifier) ENDIF ENDPROC /// PURPOSE: /// Same as CALCULATE_DESIRED_PLAYBACK_SPEED_FROM_TRIGGER_CAR but with new updates for NG/DLC: this is currently added separately otherwise it will change how the rubber banding works for old missions, but can /// be used for any new DLC missions (on the next standalone project this will replace the old proc). PROC CALCULATE_DESIRED_PLAYBACK_SPEED_FROM_TRIGGER_CAR_NG_VERSION(FLOAT &fDesiredPlaybackSpeed, VEHICLE_INDEX &vehPlayer, VEHICLE_INDEX vehTrigger, FLOAT fClosestDist = 5.0, FLOAT fIdealDist = 10.0, FLOAT fMaxDist = 50.0, FLOAT fLosingTriggerDist = 100.0, FLOAT fMaxDistInFront = 30.0, FLOAT fDefaultPlaybackSpeed = 1.0, FLOAT fMinSpeedIfBehind = 0.7, FLOAT fMinSpeedIfLosingTrigger = 0.5, FLOAT fMaxSpeedIfTooClose = 2.0, BOOL bApplySlowdownToPlayer = FALSE, FLOAT fDefaultSlowdownPercent = 0.0, FLOAT fMaxSlowdownPercent = 15.0, BOOL bAccountForSpecialAbility = TRUE) VECTOR vPlayerPos = GET_ENTITY_COORDS(vehPlayer) VECTOR vTriggerPos = GET_ENTITY_COORDS(vehTrigger) VECTOR vOffset = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(vehTrigger, vPlayerPos) FLOAT fDist = VDIST(vPlayerPos, vTriggerPos) FLOAT fDistRatio = 0.0 FLOAT fMaxSpeedToAddIfClose = fMaxSpeedIfTooClose - fDefaultPlaybackSpeed FLOAT fMaxSpeedToRemoveIfBehind = fDefaultPlaybackSpeed - fMinSpeedIfBehind IF vOffset.y < 1.0 //Player is behind the car. IF fDist > fMaxDist //Player is a long way behind, slow the trigger car down even more (if not on screen). BOOL bReallyFarBehind = FALSE IF fDist > fLosingTriggerDist IF fDist > fLosingTriggerDist * 2.0 bReallyFarBehind = TRUE ENDIF fDist = fLosingTriggerDist ENDIF fDistRatio = ((fDist - fMaxDist) / (fLosingTriggerDist - fMaxDist)) IF NOT IS_ENTITY_ON_SCREEN(vehTrigger) OR bReallyFarBehind fDesiredPlaybackSpeed = fMinSpeedIfBehind - ((fMinSpeedIfBehind - fMinSpeedIfLosingTrigger) * fDistRatio) ELSE //Not safe to slow down any further, so cap at min speed. fDesiredPlaybackSpeed = fMinSpeedIfBehind ENDIF ELIF fDist > fIdealDist //Player is slightly behind ideal distance. Slow the trigger car down relative to how far behind the player is. fDistRatio = ((fDist - fIdealDist) / (fMaxDist - fIdealDist)) fDesiredPlaybackSpeed = fDefaultPlaybackSpeed - (fMaxSpeedToRemoveIfBehind * fDistRatio) ELSE //Player is getting too close, speed up the trigger car relative to how close the player is. IF fDist < fClosestDist fDist = fClosestDist ENDIF fDistRatio = (fIdealDist - fDist) / (fIdealDist - fClosestDist) IF IS_SPECIAL_ABILITY_ACTIVE(PLAYER_ID()) AND bAccountForSpecialAbility fDesiredPlaybackSpeed = fDefaultPlaybackSpeed + ((fDistRatio * fMaxSpeedToAddIfClose) * 2.0) ELSE fDesiredPlaybackSpeed = fDefaultPlaybackSpeed + (fDistRatio * fMaxSpeedToAddIfClose) ENDIF ENDIF ELSE //Player is in front, speed up trigger car based on the player's own speed. IF fDist > fMaxDistInFront fDist = fMaxDistInFront ENDIF fDistRatio = fDist / fMaxDistInFront FLOAT fSpeedDiff = GET_ENTITY_SPEED(vehTrigger) - GET_ENTITY_SPEED(vehPlayer) //If the player is already going slower then don't speed up the buddy as much. IF fSpeedDiff > 0.0 fDistRatio = fDistRatio * 0.5 ENDIF IF IS_SPECIAL_ABILITY_ACTIVE(PLAYER_ID()) AND bAccountForSpecialAbility fDesiredPlaybackSpeed = (fDefaultPlaybackSpeed * 2.0) + fDistRatio ELSE IF GET_ENTITY_SPEED(vehPlayer) < 5.0 AND fSpeedDiff > 0.0 //If the player has slowed down slow the buddy down so it's not as harsh if they plough through. fDesiredPlaybackSpeed = (fDefaultPlaybackSpeed - 0.4) + fDistRatio ELSE fDesiredPlaybackSpeed = fDefaultPlaybackSpeed + fDistRatio ENDIF ENDIF ENDIF //Modify the player's speed if the desired playback speed is getting too much. IF bApplySlowdownToPlayer FLOAT fPlayersSpeedModifier = fDefaultSlowdownPercent IF IS_SPECIAL_ABILITY_ACTIVE(PLAYER_ID()) AND bAccountForSpecialAbility fMaxSlowdownPercent = fMaxSlowdownPercent * 2.0 fDefaultSlowdownPercent = fDefaultSlowdownPercent * 2.0 ENDIF IF fDesiredPlaybackSpeed > 1.0 fPlayersSpeedModifier = fDefaultSlowdownPercent + ((fMaxSlowdownPercent - fDefaultSlowdownPercent) * (fDesiredPlaybackSpeed - 1.0)) ENDIF MODIFY_VEHICLE_TOP_SPEED(vehPlayer, -fPlayersSpeedModifier) ENDIF #IF IS_DEBUG_BUILD IF bTrafficDebugOn SET_TEXT_SCALE(0.5, 0.5) TEXT_LABEL_63 strDist = "Distance: " strDist += GET_STRING_FROM_FLOAT(fDist) DISPLAY_TEXT_WITH_LITERAL_STRING(0.1, 0.1, "STRING", strDist) SET_TEXT_SCALE(0.5, 0.5) TEXT_LABEL_63 strSpeed = "Desired playback speed: " strSpeed += GET_STRING_FROM_FLOAT(fDesiredPlaybackSpeed) DISPLAY_TEXT_WITH_LITERAL_STRING(0.1, 0.15, "STRING", strSpeed) SET_TEXT_SCALE(0.5, 0.5) TEXT_LABEL_63 strDiff = "Speed diff (m/s): " strDiff += GET_STRING_FROM_FLOAT(GET_ENTITY_SPEED(vehTrigger) - GET_ENTITY_SPEED(vehPlayer)) DISPLAY_TEXT_WITH_LITERAL_STRING(0.1, 0.2, "STRING", strDiff) SET_TEXT_SCALE(0.5, 0.5) TEXT_LABEL_63 strState = "Trigger car state: " IF vOffset.y < 0.0 strState += "in front and " ELSE strState += "behind and " ENDIF IF IS_ENTITY_ON_SCREEN(vehTrigger) strState += "on screen." ELSE strState += "off screen." ENDIF DISPLAY_TEXT_WITH_LITERAL_STRING(0.1, 0.25, "STRING", strState) ENDIF #ENDIF ENDPROC /// PURPOSE: /// Used in conjunction with CALCULATE_DESIRED_PLAYBACK_SPEED_FROM_TRIGGER_CAR, this will give you a new playback speed that's smoothed based on the current playback speed and /// the calculated speed. This is separated from the main calculations to allow for special cases for desired speed in missions. /// PARAMS: /// fCurrentSpeed - The current playback speed. /// fDesiredSpeed - The speed the trigger car should be at based on any distance calculations. /// fAccel - Modify this to increase/decrease the rate that the current speed changes to achieve the desired speed. Changing this can help if you see the trigger car noticeably speed off during a chase. PROC UPDATE_CURRENT_PLAYBACK_SPEED_WITH_SMOOTHING(FLOAT &fCurrentSpeed, FLOAT fDesiredSpeed, FLOAT fAccel = 0.01) fCurrentSpeed = fCurrentSpeed +@ (((fDesiredSpeed - fCurrentSpeed) * fAccel) * 30.0) #IF IS_DEBUG_BUILD IF bTrafficDebugOn SET_TEXT_SCALE(0.5, 0.5) TEXT_LABEL_63 strCurrentSpeed = "Current Speed: " strCurrentSpeed += GET_STRING_FROM_FLOAT(fCurrentSpeed) DISPLAY_TEXT_WITH_LITERAL_STRING(0.1, 0.3, "STRING", strCurrentSpeed) ENDIF #ENDIF ENDPROC /// PURPOSE: /// Function is now obsolete, please use CALCULATE_DESIRED_PLAYBACK_SPEED_FROM_TRIGGER_CAR. PROC CALCULATE_NEW_PLAYBACK_SPEED_FROM_CHAR(VEHICLE_INDEX InCarID, PED_INDEX TargetCharID, FLOAT &fPlaybackSpeed, FLOAT fDefaultPlaybackSpeed = 1.0, FLOAT fMinDist = 5.0, FLOAT fIdealDist = 20.0, FLOAT fSlowDownDist = 125.0, FLOAT fMaxPlaybackSpeedMultiplier = 2.0, FLOAT fAirResistanceMultiplier = 1.0, FLOAT fCatchupSpeedMultiplier = 0.7, BOOL bDoAirResistance = TRUE) FLOAT fMaxPlaybackSpeed FLOAT fTemp FLOAT fCurrentDistance FLOAT fCorrectedDistance FLOAT fDesiredPlaybackSpeed FLOAT fCatchupSpeed FLOAT fCaughtUpDist FLOAT fMultiplyingFactor FLOAT fMaxAllowedAccelThisFrame IF (bCalculatePlaybackSpeedInitialised = FALSE) IF (fPlaybackSpeed < fDefaultPlaybackSpeed) fPlaybackSpeed = fDefaultPlaybackSpeed bCalculatePlaybackSpeedInitialised = TRUE ENDIF ENDIF #IF IS_DEBUG_BUILD IF (fMinDist < 0.0) PRINTSTRING("CALCULATE_NEW_PLAYBACK_SPEED_FROM_CHAR - fMinDist = ") PRINTFLOAT(fMinDist) PRINTSTRING("\n") SCRIPT_ASSERT("CALCULATE_NEW_PLAYBACK_SPEED_FROM_CHAR - fMinDist cannot be less than zero.") ENDIF IF (fMinDist >= fIdealDist) PRINTSTRING("CALCULATE_NEW_PLAYBACK_SPEED_FROM_CHAR - fMinDist = ") PRINTFLOAT(fMinDist) PRINTSTRING(", fIdealDist = ") PRINTFLOAT(fIdealDist) PRINTSTRING("\n") SCRIPT_ASSERT("CALCULATE_NEW_PLAYBACK_SPEED_FROM_CHAR - fMinDist must be less than fIdealDist") ENDIF IF (fMinDist >= fSlowDownDist) PRINTSTRING("CALCULATE_NEW_PLAYBACK_SPEED_FROM_CHAR - fMinDist = ") PRINTFLOAT(fMinDist) PRINTSTRING(", fSlowDownDist = ") PRINTFLOAT(fSlowDownDist) PRINTSTRING("\n") SCRIPT_ASSERT("CALCULATE_NEW_PLAYBACK_SPEED_FROM_CHAR - fMinDist must be less than fSlowDownDist") ENDIF IF (fIdealDist < 0.0) PRINTSTRING("CALCULATE_NEW_PLAYBACK_SPEED_FROM_CHAR - fIdealDist = ") PRINTFLOAT(fIdealDist) PRINTSTRING("\n") SCRIPT_ASSERT("CALCULATE_NEW_PLAYBACK_SPEED_FROM_CHAR - fIdealDist cannot be less than zero.") ENDIF IF (fIdealDist >= fSlowDownDist) PRINTSTRING("CALCULATE_NEW_PLAYBACK_SPEED_FROM_CHAR - fIdealDist = ") PRINTFLOAT(fIdealDist) PRINTSTRING(", fSlowDownDist = ") PRINTFLOAT(fSlowDownDist) PRINTSTRING("\n") SCRIPT_ASSERT("CALCULATE_NEW_PLAYBACK_SPEED_FROM_CHAR - fIdealDist must be less than fSlowDownDist") ENDIF IF (fSlowDownDist < 0.0) PRINTSTRING("CALCULATE_NEW_PLAYBACK_SPEED_FROM_CHAR - fSlowDownDist = ") PRINTFLOAT(fSlowDownDist) PRINTSTRING("\n") SCRIPT_ASSERT("CALCULATE_NEW_PLAYBACK_SPEED_FROM_CHAR - fSlowDownDist cannot be less than zero.") ENDIF #ENDIF IF (fAirResistanceMultiplier < 0.0) fAirResistanceMultiplier = fAirResMultiplier ENDIF fMaxPlaybackSpeed = fDefaultPlaybackSpeed * fMaxPlaybackSpeedMultiplier IF NOT (fMaxPlaybackSpeed > fDefaultPlaybackSpeed) fMaxPlaybackSpeed = fDefaultPlaybackSpeed + 0.1 ENDIF fCatchupSpeed = fDefaultPlaybackSpeed * fCatchupSpeedMultiplier fCaughtUpDist = ((fSlowDownDist - fIdealDist) * CAUGHT_UP_DIST_PERCENT) + fIdealDist fCurrentDistance = GET_CHAR_DISTANCE_FROM_LEAD_CAR(InCarID, TargetCharID) IF (fCurrentDistance < 0.0) fCurrentDistance *= -1.0 ENDIF // Limit current distance fCorrectedDistance = fCurrentDistance IF (fCorrectedDistance < fMinDist) fCorrectedDistance = fMinDist ENDIF IF (fCorrectedDistance > fCaughtUpDist) fCorrectedDistance = fCaughtUpDist ENDIF // figure out the deisried playback speed fDesiredPlaybackSpeed = fDefaultPlaybackSpeed IF NOT IS_ENTITY_DEAD(TargetCharID) IF IS_PED_IN_FRONT_OF_CAR(TargetCharID, InCarID) IF IS_PED_IN_ANY_VEHICLE(TargetCharID) // in car , infront of chase car - max speed fDesiredPlaybackSpeed = fMaxPlaybackSpeed ELSE // on foot, infront of chase car - max speed unless within 50m IF (fCurrentDistance < 50.0) fDesiredPlaybackSpeed = fDefaultPlaybackSpeed ELSE fDesiredPlaybackSpeed = fMaxPlaybackSpeed ENDIF ENDIF ELSE // in car , behind - adjust the playback speed accordingly IF (fCurrentDistance < fIdealDist) IF (GET_ACTUAL_CHAR_DISTANCE_FROM_LEAD_CAR(InCarID, TargetCharID) < fIdealDist) fTemp = GET_DIFF_IN_SPEED_HEADINGS_BETWEEN_CHAR_AND_LEAD_CAR(InCarID, TargetCharID) // 15 and under degrees = 1.0 // 90 degrees = 0.0 fTemp += -15.0 IF (fTemp < 0.0) fTemp = 0.0 ENDIF IF (fTemp > 75.0) fTemp = 75.0 ENDIF fMultiplyingFactor = (75.0 - fTemp) / 75.0 ELSE fMultiplyingFactor = 1.0 ENDIF // speed up fDesiredPlaybackSpeed = (((((fIdealDist - fMinDist) - (fCorrectedDistance - fMinDist)) / (fIdealDist - fMinDist)) * (fMaxPlaybackSpeed - fDefaultPlaybackSpeed)) * fMultiplyingFactor) + fDefaultPlaybackSpeed ELSE // slow down if hit catchup distance IF (fCurrentDistance > fSlowDownDist) fDesiredPlaybackSpeed = fCatchupSpeed bIsCatchingUp = TRUE ELSE // player is catching up IF (bIsCatchingUp) // player has caught up IF (fCurrentDistance < fCaughtUpDist) fDesiredPlaybackSpeed = fDefaultPlaybackSpeed bIsCatchingUp = FALSE ELSE fDesiredPlaybackSpeed = fCatchupSpeed ENDIF ELSE // keep the speed at the default fDesiredPlaybackSpeed = fDefaultPlaybackSpeed ENDIF ENDIF ENDIF ENDIF ENDIF // accelerate towards the actual playback speed fTemp = (fDesiredPlaybackSpeed - fPlaybackSpeed) IF (fTemp > 0.0) // check rate of acceleration fTemp = GET_FRAME_TIME() fMaxAllowedAccelThisFrame = (fPlaybackSpeedMaxAcceleration * fDefaultPlaybackSpeed) * fTemp fTemp = (fDesiredPlaybackSpeed - fPlaybackSpeed) IF (fTemp > fMaxAllowedAccelThisFrame) fTemp = fMaxAllowedAccelThisFrame ENDIF // PRINTSTRING("PLAYBACK SPEED INCREASED BY ") // PRINTFLOAT(fTemp) // PRINTSTRING(", fMaxAllowedAccelThisFrame = ") // PRINTFLOAT(fMaxAllowedAccelThisFrame) // PRINTSTRING("\n") fPlaybackSpeed += fTemp ELSE // check rate of deceleration fTemp = GET_FRAME_TIME() fMaxAllowedAccelThisFrame = (fPlaybackSpeedMaxDecceleration * fDefaultPlaybackSpeed) * fTemp fTemp = (fDesiredPlaybackSpeed - fPlaybackSpeed) IF (fTemp < (fMaxAllowedAccelThisFrame * -1.0)) fTemp = (fMaxAllowedAccelThisFrame * -1.0) ENDIF // PRINTSTRING("PLAYBACK SPEED DECREASED BY ") // PRINTFLOAT(fTemp) // PRINTSTRING(", fMaxAllowedAccelThisFrame = ") // PRINTFLOAT(fMaxAllowedAccelThisFrame) // PRINTSTRING("\n") fPlaybackSpeed += fTemp ENDIF // set air resistance for chasing car VEHICLE_INDEX TempCar MODEL_NAMES TempModelName IF (bDoAirResistance) IF NOT IS_PED_INJURED(TargetCharID) IF IS_PED_IN_ANY_VEHICLE(TargetCharID) TempCar = GET_VEHICLE_PED_IS_IN(TargetCharID) IF NOT IS_ENTITY_DEAD(TempCar) TempModelName = GET_ENTITY_MODEL(TempCar) IF IS_THIS_MODEL_A_CAR(TempModelName) OR IS_THIS_MODEL_A_BIKE(TempModelName) IF IS_VEHICLE_DRIVEABLE(TempCar) fTemp = fDesiredPlaybackSpeed IF (fTemp < fDefaultPlaybackSpeed) fTemp = fDefaultPlaybackSpeed ENDIF fTemp -= fDefaultPlaybackSpeed fTemp /= (fMaxPlaybackSpeed - fDefaultPlaybackSpeed) fTemp *= fAirResistanceMultiplier fTemp *= (fMaxAirRes - fMinAirRes) fTemp += fMinAirRes fAirRes = fTemp IF (fAirRes < fMinAirRes) fAirRes = fMinAirRes ENDIF IF (fAirRes > fMaxAirRes) fAirRes = fMaxAirRes ENDIF SET_AIR_DRAG_MULTIPLIER_FOR_PLAYERS_VEHICLE(PLAYER_ID(), fAirRes) ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: /// Function is now obsolete, please use CALCULATE_DESIRED_PLAYBACK_SPEED_FROM_TRIGGER_CAR. PROC CALCULATE_PLAYBACK_SPEED_FROM_CHAR(VEHICLE_INDEX InCarID, PED_INDEX TargetCharID, FLOAT &fPlaybackSpeed, FLOAT fIdealChaseDist = 20.0, FLOAT fMinChaseDist = 5.0, FLOAT fMaxChaseDist = 40.0, FLOAT fMinPlaybackSpeed = 0.6, FLOAT fMaxPlaybackSpeed = 2.0, FLOAT fDefaultPlaybackSpeed = 1.0, BOOL bUseAirResistance = TRUE) FLOAT fMaxPlaybackSpeedMult FLOAT fCatchupSpeedMult FLOAT fSlowDist // check min dist is < than ideal IF NOT (fMinChaseDist < fIdealChaseDist) fMinChaseDist = fIdealChaseDist - 0.1 ENDIF // figure out fDefaultPlaybackSpeed IF (fMinPlaybackSpeed > fDefaultPlaybackSpeed) fDefaultPlaybackSpeed = fMinPlaybackSpeed ENDIF // figure out fMaxPlaybackSpeedMultiplier fMaxPlaybackSpeedMult = (fMaxPlaybackSpeed / fDefaultPlaybackSpeed) // figure out fCatchupSpeedMultiplier fCatchupSpeedMult = (fMinPlaybackSpeed / fDefaultPlaybackSpeed) // figure out fSlowDownDist fSlowDist = ((fMaxChaseDist - fIdealChaseDist) * (1.0 / CAUGHT_UP_DIST_PERCENT)) + fIdealChaseDist CALCULATE_NEW_PLAYBACK_SPEED_FROM_CHAR(InCarID, TargetCharID, fPlaybackSpeed, fDefaultPlaybackSpeed, fMinChaseDist, fIdealChaseDist, fSlowDist, fMaxPlaybackSpeedMult, 1.0, fCatchupSpeedMult, bUseAirResistance) ENDPROC #IF IS_DEBUG_BUILD STRUCT FACE_STRUCT // face must be clockwise VECTOR v1 VECTOR v2 VECTOR v3 VECTOR v4 ENDSTRUCT FUNC VECTOR GET_FACE_NORMAL(FACE_STRUCT inFace) VECTOR vReturn VECTOR v1, v2 v1 = inFace.v2 - inFace.v1 v2 = inFace.v3 - inFace.v2 vReturn = CROSS_PRODUCT(v1, v2) vReturn *= -1.0 RETURN(vReturn) ENDFUNC FUNC VECTOR GET_FACE_MIDPOINT(FACE_STRUCT inFace) VECTOR vReturn vReturn = inFace.v1 + inFace.v2 + inFace.v3 + inFace.v4 vReturn *= 0.25 RETURN(vReturn) ENDFUNC PROC DRAW_FACE(FACE_STRUCT inFace) DRAW_DEBUG_LINE(inFace.v1, inFace.v2) DRAW_DEBUG_LINE(inFace.v2, inFace.v3) DRAW_DEBUG_LINE(inFace.v3, inFace.v4) DRAW_DEBUG_LINE(inFace.v4, inFace.v1) ENDPROC FUNC BOOL IS_POINT_BEHIND_FACE(VECTOR vInPoint, FACE_STRUCT inFace) VECTOR vMidpoint VECTOR vNormal VECTOR vVecFromPointToMidpoint vMidpoint = GET_FACE_MIDPOINT(inFace) vNormal = GET_FACE_NORMAL(inFace) vVecFromPointToMidpoint = vMidpoint - vInPoint IF (DOT_PRODUCT(vVecFromPointToMidpoint,vNormal) > 0.0) RETURN(TRUE) ENDIF RETURN(FALSE) ENDFUNC FUNC BOOL IS_POINT_INSIDE_RECORDING_CONE(VECTOR vInPoint, VEHICLE_INDEX TriggerCar) VECTOR posA VECTOR posB VECTOR posC VECTOR posD VECTOR posE VECTOR posF VECTOR posG VECTOR posH FLOAT fAngleOffsetDist FLOAT fHeightAngleOffsetDist FACE_STRUCT face[6] // A,B,C,D - quad near car IF IS_VEHICLE_DRIVEABLE(TriggerCar) posA = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(TriggerCar, <<(fRecordingMinWidth * -0.5), fMinRecordingOffset, (fRecordingMinHeight * 0.5)>>) posB = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(TriggerCar, <<(fRecordingMinWidth * 0.5), fMinRecordingOffset, (fRecordingMinHeight * 0.5)>>) posC = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(TriggerCar, <<(fRecordingMinWidth * -0.5), fMinRecordingOffset, (fRecordingMinHeight * -0.5)>>) posD = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(TriggerCar, <<(fRecordingMinWidth * 0.5), fMinRecordingOffset, (fRecordingMinHeight * -0.5)>>) ENDIF // E,F,G,H - quad away from car IF IS_VEHICLE_DRIVEABLE(TriggerCar) fAngleOffsetDist = (fRecordingDistance * TAN(0.5 * fRecordingAngle)) fHeightAngleOffsetDist = (fRecordingDistance * TAN(0.5 * fRecordingHeightAngle)) posE = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(TriggerCar, <<(fRecordingMinWidth * -0.5) - fAngleOffsetDist, fMinRecordingOffset + fRecordingDistance, (fRecordingMinHeight * 0.5) + fHeightAngleOffsetDist>>) posF = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(TriggerCar, <<(fRecordingMinWidth * 0.5) + fAngleOffsetDist, fMinRecordingOffset + fRecordingDistance, (fRecordingMinHeight * 0.5) + fHeightAngleOffsetDist>>) posG = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(TriggerCar, <<(fRecordingMinWidth * -0.5) - fAngleOffsetDist, fMinRecordingOffset + fRecordingDistance, (fRecordingMinHeight * -0.5) - fHeightAngleOffsetDist>>) posH = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(TriggerCar, <<(fRecordingMinWidth * 0.5) + fAngleOffsetDist, fMinRecordingOffset + fRecordingDistance, (fRecordingMinHeight * -0.5) - fHeightAngleOffsetDist>>) ENDIF // setup faces face[0].v1 = posA face[0].v2 = posB face[0].v3 = posD face[0].v4 = posC face[1].v1 = posA face[1].v2 = posE face[1].v3 = posF face[1].v4 = posB face[2].v1 = posB face[2].v2 = posF face[2].v3 = posH face[2].v4 = posD face[3].v1 = posD face[3].v2 = posH face[3].v3 = posG face[3].v4 = posC face[4].v1 = posC face[4].v2 = posG face[4].v3 = posE face[4].v4 = posA face[5].v1 = posF face[5].v2 = posE face[5].v3 = posG face[5].v4 = posH IF IS_POINT_BEHIND_FACE(vInPoint, face[0]) IF IS_POINT_BEHIND_FACE(vInPoint, face[1]) IF IS_POINT_BEHIND_FACE(vInPoint, face[2]) IF IS_POINT_BEHIND_FACE(vInPoint, face[3]) IF IS_POINT_BEHIND_FACE(vInPoint, face[4]) IF IS_POINT_BEHIND_FACE(vInPoint, face[5]) RETURN(TRUE) ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF RETURN(FALSE) ENDFUNC PROC DRAW_RECORDING_CONE(VEHICLE_INDEX TriggerCar) VECTOR posA VECTOR posB VECTOR posC VECTOR posD VECTOR posE VECTOR posF VECTOR posG VECTOR posH FLOAT fAngleOffsetDist FLOAT fHeightAngleOffsetDist FACE_STRUCT face[6] // A,B,C,D - quad near car IF IS_VEHICLE_DRIVEABLE(TriggerCar) posA = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(TriggerCar, <<(fRecordingMinWidth * -0.5), fMinRecordingOffset, (fRecordingMinHeight * 0.5)>>) posB = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(TriggerCar, <<(fRecordingMinWidth * 0.5), fMinRecordingOffset, (fRecordingMinHeight * 0.5)>>) posC = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(TriggerCar, <<(fRecordingMinWidth * -0.5), fMinRecordingOffset, (fRecordingMinHeight * -0.5)>>) posD = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(TriggerCar, <<(fRecordingMinWidth * 0.5), fMinRecordingOffset, (fRecordingMinHeight * -0.5)>>) ENDIF // E,F,G,H - quad away from car IF IS_VEHICLE_DRIVEABLE(TriggerCar) fAngleOffsetDist = (fRecordingDistance * TAN(0.5 * fRecordingAngle)) fHeightAngleOffsetDist = (fRecordingDistance * TAN(0.5 * fRecordingHeightAngle)) posE = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(TriggerCar, <<(fRecordingMinWidth * -0.5) - fAngleOffsetDist, fMinRecordingOffset + fRecordingDistance, (fRecordingMinHeight * 0.5) + fHeightAngleOffsetDist>>) posF = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(TriggerCar, <<(fRecordingMinWidth * 0.5) + fAngleOffsetDist, fMinRecordingOffset + fRecordingDistance, (fRecordingMinHeight * 0.5) + fHeightAngleOffsetDist>>) posG = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(TriggerCar, <<(fRecordingMinWidth * -0.5) - fAngleOffsetDist, fMinRecordingOffset + fRecordingDistance, (fRecordingMinHeight * -0.5) - fHeightAngleOffsetDist>>) posH = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(TriggerCar, <<(fRecordingMinWidth * 0.5) + fAngleOffsetDist, fMinRecordingOffset + fRecordingDistance, (fRecordingMinHeight * -0.5) - fHeightAngleOffsetDist>>) ENDIF // setup faces face[0].v1 = posA face[0].v2 = posB face[0].v3 = posD face[0].v4 = posC face[1].v1 = posA face[1].v2 = posE face[1].v3 = posF face[1].v4 = posB face[2].v1 = posB face[2].v2 = posF face[2].v3 = posH face[2].v4 = posD face[3].v1 = posD face[3].v2 = posH face[3].v3 = posG face[3].v4 = posC face[4].v1 = posC face[4].v2 = posG face[4].v3 = posE face[4].v4 = posA face[5].v1 = posF face[5].v2 = posE face[5].v3 = posG face[5].v4 = posH DRAW_FACE(face[0]) DRAW_FACE(face[1]) DRAW_FACE(face[2]) DRAW_FACE(face[3]) DRAW_FACE(face[4]) DRAW_FACE(face[5]) ENDPROC #ENDIF #IF IS_DEBUG_BUILD FUNC BOOL HAS_TRAFFIC_CAR_BEEN_RECORDED(VEHICLE_INDEX &InCar) INT i //REPEAT TOTAL_NUMBER_OF_TRAFFIC_CARS i // remove as once a car has been recorded it gets deleted REPEAT MAX_NUMBER_OF_TRAFFIC_CARS_PLAYING_BACK i IF (RecordedTrafficCarID[i] = InCar) RETURN(TRUE) ENDIF ENDREPEAT // check its not a set peice car REPEAT TOTAL_NUMBER_OF_SET_PIECE_CARS i IF (SetPieceCarID[i] = InCar) RETURN(TRUE) ENDIF ENDREPEAT RETURN(FALSE) ENDFUNC FUNC BOOL HAS_PARKED_CAR_BEEN_RECORDED(VEHICLE_INDEX &InCar) INT i REPEAT MAX_NUMBER_OF_PARKED_CARS_PLAYING_BACK i IF (RecordedParkedCarID[i] = InCar) RETURN(TRUE) ENDIF ENDREPEAT RETURN(FALSE) ENDFUNC #ENDIF #IF IS_DEBUG_BUILD FUNC BOOL IS_TRAFFIC_CAR_GOOD_TO_RECORD(VEHICLE_INDEX InCar, VEHICLE_INDEX TriggerCar) PED_INDEX temp_char VECTOR pos IF IS_VEHICLE_DRIVEABLE(InCar) IF NOT (InCar = TriggerCar) IF NOT IS_ENTITY_A_MISSION_ENTITY(InCar) IF NOT IS_RECORDING_GOING_ON_FOR_VEHICLE(InCar) IF NOT IS_VEHICLE_MODEL(InCar, COP_CAR_MODEL()) IF NOT HAS_TRAFFIC_CAR_BEEN_RECORDED(InCar) IF IS_CAR_IN_FRONT_OF_CAR(InCar, TriggerCar) pos = GET_ENTITY_COORDS(InCar) IF IS_POINT_INSIDE_RECORDING_CONE(pos, TriggerCar) temp_char = GET_PED_IN_VEHICLE_SEAT(InCar) IF NOT IS_ENTITY_DEAD(temp_char) RETURN(TRUE) ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF RETURN(FALSE) ENDFUNC #ENDIF #IF IS_DEBUG_BUILD FUNC BOOL IS_THIS_A_PARKED_CAR(VEHICLE_INDEX InCar) PED_INDEX temp_char IF IS_VEHICLE_DRIVEABLE(InCar) temp_char = GET_PED_IN_VEHICLE_SEAT(InCar) IF NOT DOES_ENTITY_EXIST(temp_char) RETURN(TRUE) ENDIF ENDIF RETURN(FALSE) ENDFUNC #ENDIF #IF IS_DEBUG_BUILD FUNC BOOL IS_PARKED_CAR_GOOD_TO_RECORD(VEHICLE_INDEX InCar, VEHICLE_INDEX TriggerCar) VECTOR pos IF IS_VEHICLE_DRIVEABLE(InCar) IF NOT (InCar = TriggerCar) IF NOT IS_ENTITY_A_MISSION_ENTITY(InCar) IF NOT IS_RECORDING_GOING_ON_FOR_VEHICLE(InCar) IF IS_THIS_A_PARKED_CAR(InCar) IF NOT HAS_PARKED_CAR_BEEN_RECORDED(InCar) pos = GET_ENTITY_COORDS(InCar) IF IS_POINT_INSIDE_RECORDING_CONE(pos, TriggerCar) IF IS_CAR_IN_FRONT_OF_CAR(InCar, TriggerCar) RETURN(TRUE) ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF RETURN(FALSE) ENDFUNC #ENDIF #IF IS_DEBUG_BUILD /// PURPOSE: /// Grabs a random traffic vehicle that's currently in front of the player, and checks if it's inside the recording cone. FUNC VEHICLE_INDEX FIND_TRAFFIC_CAR_TO_RECORD(VEHICLE_INDEX vehPlayer) IF IS_VEHICLE_DRIVEABLE(vehPlayer) VECTOR vSphereCentre = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(vehPlayer, <<0.0, fRecordingDistance * 0.5, 0.0>>) VEHICLE_INDEX vehResult = GET_RANDOM_VEHICLE_IN_SPHERE(vSphereCentre, fRecordingDistance * 0.5, DUMMY_MODEL_FOR_SCRIPT, VEHICLE_SEARCH_FLAG_RETURN_RANDOM_VEHICLES) IF IS_TRAFFIC_CAR_GOOD_TO_RECORD(vehResult, vehPlayer) RETURN vehResult ENDIF ENDIF RETURN NULL ENDFUNC /// PURPOSE: /// Grabs a random parked vehicle that's currently in front of the player, and checks if it's inside the recording cone. FUNC VEHICLE_INDEX FIND_PARKED_CAR_TO_RECORD(VEHICLE_INDEX vehPlayer) IF IS_VEHICLE_DRIVEABLE(vehPlayer) VECTOR vSphereCentre = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(vehPlayer, <<0.0, fRecordingDistance * 0.5, 0.0>>) VEHICLE_INDEX vehResult = GET_RANDOM_VEHICLE_IN_SPHERE(vSphereCentre, fRecordingDistance * 0.5, DUMMY_MODEL_FOR_SCRIPT, VEHICLE_SEARCH_FLAG_RETURN_RANDOM_VEHICLES) IF IS_PARKED_CAR_GOOD_TO_RECORD(vehResult, vehPlayer) RETURN vehResult ENDIF ENDIF RETURN NULL ENDFUNC #ENDIF #IF IS_DEBUG_BUILD PROC START_RECORDING_SET_PIECE_CAR(VEHICLE_INDEX inCar, VEHICLE_INDEX TriggerCar, BOOL bAllowOverwrite) TEXT_LABEL_63 str // start new recording IF IS_VEHICLE_DRIVEABLE(inCar) IF NOT START_RECORDING_VEHICLE(inCar, iSetPieceCarRecordingFile, strUberName, bAllowOverwrite) str = "Error with car recording " str += iSetPieceCarRecordingFile str += " ensure file is checked out." SCRIPT_ASSERT(str) ENDIF SetPieceRecordingCar = inCar OPEN_DEBUG_FILE() // start position RecordedSetPieceCarPos = GET_ENTITY_COORDS(inCar) SAVE_NEWLINE_TO_DEBUG_FILE() str = "SetPieceCar" SAVE_STRING_TO_DEBUG_FILE(str) str = "Pos[] = <<" SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(RecordedSetPieceCarPos.x) SAVE_STRING_TO_DEBUG_FILE(", ") SAVE_FLOAT_TO_DEBUG_FILE(RecordedSetPieceCarPos.y) SAVE_STRING_TO_DEBUG_FILE(", ") SAVE_FLOAT_TO_DEBUG_FILE(RecordedSetPieceCarPos.z) SAVE_STRING_TO_DEBUG_FIle(">>") // start quaternion GET_ENTITY_QUATERNION(inCar, fSetPieceQuatX, fSetPieceQuatY, fSetPieceQuatZ, fSetPieceQuatW) SAVE_NEWLINE_TO_DEBUG_FILE() str = "SetPieceCar" SAVE_STRING_TO_DEBUG_FILE(str) str = "QuatX[] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(fSetPieceQuatX) SAVE_NEWLINE_TO_DEBUG_FILE() str = "SetPieceCar" SAVE_STRING_TO_DEBUG_FILE(str) str = "QuatY[] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(fSetPieceQuatY) SAVE_NEWLINE_TO_DEBUG_FILE() str = "SetPieceCar" SAVE_STRING_TO_DEBUG_FILE(str) str = "QuatZ[] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(fSetPieceQuatZ) SAVE_NEWLINE_TO_DEBUG_FILE() str = "SetPieceCar" SAVE_STRING_TO_DEBUG_FILE(str) str = "QuatW[] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(fSetPieceQuatW) // recording number SAVE_NEWLINE_TO_DEBUG_FILE() str = "SetPieceCar" SAVE_STRING_TO_DEBUG_FILE(str) str = "Recording[] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_INT_TO_DEBUG_FILE(iSetPieceCarRecordingFile) // recording start time SAVE_NEWLINE_TO_DEBUG_FILE() str = "SetPieceCar" SAVE_STRING_TO_DEBUG_FILE(str) str = "Startime[] = " SAVE_STRING_TO_DEBUG_FILE(str) IF IS_VEHICLE_DRIVEABLE(TriggerCar) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(TriggerCar) fNewSetPieceTriggerTime = GET_TIME_POSITION_IN_RECORDING(TriggerCar) SAVE_FLOAT_TO_DEBUG_FILE(fNewSetPieceTriggerTime) ELSE IF IS_RECORDING_GOING_ON_FOR_VEHICLE(TriggerCar) fNewSetPieceTriggerTime = GET_TIME_POSITION_IN_RECORDED_RECORDING(TriggerCar) SAVE_FLOAT_TO_DEBUG_FILE(fNewSetPieceTriggerTime) ENDIF ENDIF ENDIF // recording speed SAVE_NEWLINE_TO_DEBUG_FILE() str = "SetPieceCar" SAVE_STRING_TO_DEBUG_FILE(str) str = "RecordingSpeed" SAVE_STRING_TO_DEBUG_FILE(str) str = "[] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(1.0 / fMasterPlaybackSpeed) // model type SAVE_NEWLINE_TO_DEBUG_FILE() str = "SetPieceCar" SAVE_STRING_TO_DEBUG_FILE(str) str = "Model[] = " SAVE_STRING_TO_DEBUG_FILE(str) str = GET_MODEL_NAME_OF_VEHICLE_FOR_DEBUG_ONLY(inCar) SAVE_STRING_TO_DEBUG_FILE(str) SAVE_NEWLINE_TO_DEBUG_FILE() CLOSE_DEBUG_FILE() ENDIF ENDPROC #ENDIF #IF IS_DEBUG_BUILD PROC RECORD_TRAFFIC(VEHICLE_INDEX TriggerCar) VEHICLE_INDEX vehNew VEHICLE_INDEX car_to_delete VECTOR pos, pos2, vec FLOAT QuatX, QuatY, QuatZ, QuatW FLOAT fTemp TEXT_LABEL_63 str INT i INT iRecordingSlot IF (bShowRecordingCone) DRAW_RECORDING_CONE(TriggerCar) ENDIF // start new recordings REPEAT 20 i IF iCurrentNumberOfTrafficRecordings < MAX_NUMBER_OF_TRAFFIC_CARS_PLAYING_BACK vehNew = FIND_TRAFFIC_CAR_TO_RECORD(TriggerCar) // get free recoded traffic car slot iRecordingSlot = GET_FREE_RECORDED_TRAFFIC_CAR_SLOT() IF NOT (iRecordingSlot = -1) IF IS_VEHICLE_DRIVEABLE(vehNew) IF DOES_BLIP_EXIST(ActiveTrafficCarBlipID[iRecordingSlot]) REMOVE_BLIP(ActiveTrafficCarBlipID[iRecordingSlot]) ENDIF ActiveTrafficCarBlipID[iRecordingSlot] = ADD_BLIP_FOR_ENTITY(vehNew) RecordedTrafficCarID[iRecordingSlot] = vehNew SET_ENTITY_AS_MISSION_ENTITY(vehNew) IF NOT START_RECORDING_VEHICLE(vehNew, (iTotalNumberOfTrafficCarsRecorded + iInitialRecordingFileNumber), strUberName, TRUE) str = "Error with car recording " str += (iTotalNumberOfTrafficCarsRecorded + iInitialRecordingFileNumber) str += " ensure file is checked out." SCRIPT_ASSERT(str) ENDIF // start position pos = GET_ENTITY_COORDS(vehNew) SAVE_NEWLINE_TO_DEBUG_FILE() str = "TrafficCarPos[" SAVE_STRING_TO_DEBUG_FILE(str) str = iTotalNumberOfTrafficCarsRecorded str += "] = <<" SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(pos.x) SAVE_STRING_TO_DEBUG_FILE(", ") SAVE_FLOAT_TO_DEBUG_FILE(pos.y) SAVE_STRING_TO_DEBUG_FILE(", ") SAVE_FLOAT_TO_DEBUG_FILE(pos.z) SAVE_STRING_TO_DEBUG_FIle(">>") // start quaternion GET_ENTITY_QUATERNION(vehNew, QuatX, QuatY, QuatZ, QuatW) SAVE_NEWLINE_TO_DEBUG_FILE() str = "TrafficCarQuatX" SAVE_STRING_TO_DEBUG_FILE(str) str = "[" str += iTotalNumberOfTrafficCarsRecorded str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(QuatX) SAVE_NEWLINE_TO_DEBUG_FILE() str = "TrafficCarQuatY" SAVE_STRING_TO_DEBUG_FILE(str) str = "[" str += iTotalNumberOfTrafficCarsRecorded str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(QuatY) SAVE_NEWLINE_TO_DEBUG_FILE() str = "TrafficCarQuatZ" SAVE_STRING_TO_DEBUG_FILE(str) str = "[" str += iTotalNumberOfTrafficCarsRecorded str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(QuatZ) SAVE_NEWLINE_TO_DEBUG_FILE() str = "TrafficCarQuatW" SAVE_STRING_TO_DEBUG_FILE(str) str = "[" str += iTotalNumberOfTrafficCarsRecorded str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(QuatW) // recording number SAVE_NEWLINE_TO_DEBUG_FILE() str = "TrafficCarRecor" SAVE_STRING_TO_DEBUG_FILE(str) str = "ding[" str += iTotalNumberOfTrafficCarsRecorded str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_INT_TO_DEBUG_FILE(iTotalNumberOfTrafficCarsRecorded + iInitialRecordingFileNumber) // recording start time SAVE_NEWLINE_TO_DEBUG_FILE() str = "TrafficCarStart" SAVE_STRING_TO_DEBUG_FILE(str) str = "ime[" str += iTotalNumberOfTrafficCarsRecorded str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) IF IS_VEHICLE_DRIVEABLE(TriggerCar) IF IS_RECORDING_GOING_ON_FOR_VEHICLE(TriggerCar) fTemp = GET_TIME_POSITION_IN_RECORDED_RECORDING(TriggerCar) SAVE_FLOAT_TO_DEBUG_FILE(fTemp) ENDIF ENDIF // model type SAVE_NEWLINE_TO_DEBUG_FILE() str = "TrafficCarModel" SAVE_STRING_TO_DEBUG_FILE(str) str = "[" str += iTotalNumberOfTrafficCarsRecorded str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) str = GET_MODEL_NAME_OF_VEHICLE_FOR_DEBUG_ONLY(vehNew) SAVE_STRING_TO_DEBUG_FILE(str) SAVE_NEWLINE_TO_DEBUG_FILE() iTotalNumberOfTrafficCarsRecorded++ ENDIF ENDIF ENDIF ENDREPEAT // end existing recordings IF IS_VEHICLE_DRIVEABLE(TriggerCar) REPEAT MAX_NUMBER_OF_TRAFFIC_CARS_PLAYING_BACK i IF NOT IS_ENTITY_DEAD(RecordedTrafficCarID[i]) IF IS_RECORDING_GOING_ON_FOR_VEHICLE(RecordedTrafficCarID[i]) IF NOT IS_CAR_IN_FRONT_OF_CAR(RecordedTrafficCarID[i], TriggerCar) pos = GET_ENTITY_COORDS(TriggerCar) pos2 = GET_ENTITY_COORDS(RecordedTrafficCarID[i]) vec = pos2 - pos vec.z = 0.0 IF (VMAG2(vec) > (fTrafficRecordingDistanceAroundCar * fTrafficRecordingDistanceAroundCar)) //IF NOT IS_VEHICLE_AT_COORD @_No_of_params (RecordedTrafficCarID[i], pos.x, pos.y, fTrafficRecordingDistanceAroundCar, fTrafficRecordingDistanceAroundCar, FALSE) STOP_RECORDING_VEHICLE(RecordedTrafficCarID[i]) IF (bDeleteTrafficWhenRecorded) #IF IS_DEBUG_BUILD IF (bTrafficDebugOn) PRINTLN("traffic.sch - DELETING TRAFFIC CAR - been recorded and now behind fTrafficRecordingDistanceAroundCar distance away") ENDIF #ENDIF IF DOES_BLIP_EXIST(ActiveTrafficCarBlipID[i]) REMOVE_BLIP(ActiveTrafficCarBlipID[i]) ENDIF DELETE_VEHICLE(RecordedTrafficCarID[i]) RecordedTrafficCarID[i] = NULL ENDIF ENDIF ENDIF ENDIF ENDIF ENDREPEAT ENDIF // remove any cars that arn't being recorded IF (bDeleteRedundantTrafficCars) REPEAT 10 i pos = GET_ENTITY_COORDS(TriggerCar) car_to_delete = GET_RANDOM_VEHICLE_IN_SPHERE(pos, 30.0 ,DUMMY_MODEL_FOR_SCRIPT, VEHICLE_SEARCH_FLAG_RETURN_RANDOM_VEHICLES) IF IS_VEHICLE_DRIVEABLE(car_to_delete) IF NOT IS_THIS_A_PARKED_CAR(car_to_delete) IF NOT HAS_TRAFFIC_CAR_BEEN_RECORDED(car_to_delete) IF NOT IS_RECORDING_GOING_ON_FOR_VEHICLE(car_to_delete) #IF IS_DEBUG_BUILD IF (bTrafficDebugOn) PRINTLN("traffic.sch - DELETING TRAFFIC CAR - deemed redundant") ENDIF #ENDIF DELETE_VEHICLE(car_to_delete) ENDIF ENDIF ENDIF ENDIF ENDREPEAT ENDIF // delete ANY cop cars REPEAT 10 i pos = GET_ENTITY_COORDS(TriggerCar) car_to_delete = GET_RANDOM_VEHICLE_IN_SPHERE(pos, fRecordingDistance, DUMMY_MODEL_FOR_SCRIPT, VEHICLE_SEARCH_FLAG_RETURN_LAW_ENFORCER_VEHICLES_ONLY) IF IS_VEHICLE_DRIVEABLE(car_to_delete) IF NOT IS_RECORDING_GOING_ON_FOR_VEHICLE(car_to_delete) DELETE_VEHICLE(car_to_delete) ENDIF ENDIF ENDREPEAT // clear area around car, soon only cars that get recorded in the cone survive pos = GET_ENTITY_COORDS(TriggerCar) CLEAR_AREA_OF_VEHICLES(pos, (fRecordingDistance + fMinRecordingOffset) * fRecordingClearAreaPercentageOfCone) //, TRUE) // count all the current cars being recorded / delete any old ones iCurrentNumberOfTrafficRecordings = 0 REPEAT MAX_NUMBER_OF_TRAFFIC_CARS_PLAYING_BACK i IF DOES_ENTITY_EXIST(RecordedTrafficCarID[i]) IF NOT IS_ENTITY_DEAD(RecordedTrafficCarID[i]) IF IS_RECORDING_GOING_ON_FOR_VEHICLE(RecordedTrafficCarID[i]) iCurrentNumberOfTrafficRecordings++ ELSE #IF IS_DEBUG_BUILD IF (bTrafficDebugOn) PRINTLN("traffic.sch - DELETING TRAFFIC CAR - recorded and finished") ENDIF #ENDIF IF DOES_BLIP_EXIST(ActiveTrafficCarBlipID[i]) REMOVE_BLIP(ActiveTrafficCarBlipID[i]) ENDIF DELETE_VEHICLE(RecordedTrafficCarID[i]) RecordedTrafficCarID[i] = NULL ENDIF ELSE #IF IS_DEBUG_BUILD IF (bTrafficDebugOn) PRINTLN("traffic.sch - DELETING TRAFFIC CAR - car is dead") ENDIF #ENDIF IF DOES_BLIP_EXIST(ActiveTrafficCarBlipID[i]) REMOVE_BLIP(ActiveTrafficCarBlipID[i]) ENDIF DELETE_VEHICLE(RecordedTrafficCarID[i]) RecordedTrafficCarID[i] = NULL ENDIF ENDIF ENDREPEAT ENDPROC #ENDIF #IF IS_DEBUG_BUILD FUNC BOOL IS_SET_PIECE_CAR_VALID(INT i) IF NOT (bSetPieceCarsConverted[i]) IF (SetPieceCarRecording[i] > 0) IF NOT (SetPieceCarModel[i] = DUMMY_MODEL_FOR_SCRIPT) RETURN(TRUE) ENDIF ENDIF ENDIF RETURN(FALSE) ENDFUNC FUNC BOOL IS_TRAFFIC_CAR_VALID(INT i) IF (TrafficCarRecording[i] > 0) IF NOT (TrafficCarModel[i] = DUMMY_MODEL_FOR_SCRIPT) RETURN(TRUE) ENDIF ENDIF RETURN(FALSE) ENDFUNC FUNC BOOL IS_PARKED_CAR_VALID(INT i) IF NOT (ParkedCarModel[i] = DUMMY_MODEL_FOR_SCRIPT) RETURN(TRUE) ENDIF RETURN(FALSE) ENDFUNC /// PURPOSE: /// Sorts the traffic array in order of start time. PROC SORT_TRAFFIC_ARRAY() INT i = 0 INT j = TOTAL_NUMBER_OF_TRAFFIC_CARS - 1 WHILE i < TOTAL_NUMBER_OF_TRAFFIC_CARS j = TOTAL_NUMBER_OF_TRAFFIC_CARS - 1 WHILE j > i IF TrafficCarStartime[j-1] > TrafficCarStartime[j] OR NOT IS_TRAFFIC_CAR_VALID(j-1) VEHICLE_INDEX tempID = TrafficCarID[j-1] MODEL_NAMES tempModel = TrafficCarModel[j-1] VECTOR tempPos = TrafficCarPos[j-1] INT tempProgress = TrafficCarProgress[j-1] FLOAT tempQuatW = TrafficCarQuatW[j-1] FLOAT tempQuatX = TrafficCarQuatX[j-1] FLOAT tempQuatY = TrafficCarQuatY[j-1] FLOAT tempQuatZ = TrafficCarQuatZ[j-1] INT tempRecording = TrafficCarRecording[j-1] FLOAT tempStartTime = TrafficCarStartime[j-1] TrafficCarID[j-1] = TrafficCarID[j] TrafficCarModel[j-1] = TrafficCarModel[j] TrafficCarPos[j-1] = TrafficCarPos[j] TrafficCarProgress[j-1] = TrafficCarProgress[j] TrafficCarQuatW[j-1] = TrafficCarQuatW[j] TrafficCarQuatX[j-1] = TrafficCarQuatX[j] TrafficCarQuatY[j-1] = TrafficCarQuatY[j] TrafficCarQuatZ[j-1] = TrafficCarQuatZ[j] TrafficCarRecording[j-1] = TrafficCarRecording[j] TrafficCarStartime[j-1] = TrafficCarStartime[j] TrafficCarID[j] = tempID TrafficCarModel[j] = tempModel TrafficCarPos[j] = tempPos TrafficCarProgress[j] = tempProgress TrafficCarQuatW[j] = tempQuatW TrafficCarQuatX[j] = tempQuatX TrafficCarQuatY[j] = tempQuatY TrafficCarQuatZ[j] = tempQuatZ TrafficCarRecording[j] = tempRecording TrafficCarStartime[j] = tempStartTime ENDIF j-- ENDWHILE i++ IF (i % 5) = 0 WAIT(0) //This is required due to the number of operations needed to sort the array, the downside is this proc can take a few seconds to finish if the array is large. ENDIF ENDWHILE ENDPROC FUNC INT LOWEST_SET_PIECE_CAR_TO_CONVERT() INT i FLOAT fCurrentLowestTime INT iCurrentLowestNumber fCurrentLowestTime = 9999999.9 iCurrentLowestNumber = -1 REPEAT TOTAL_NUMBER_OF_SET_PIECE_CARS i IF (bSetPieceCarsToConvert[i]) IF (SetPieceCarStartime[i] < fCurrentLowestTime) IF IS_SET_PIECE_CAR_VALID(i) fCurrentLowestTime = SetPieceCarStartime[i] iCurrentLowestNumber = i ENDIF ENDIF ENDIF ENDREPEAT RETURN(iCurrentLowestNumber) ENDFUNC PROC OUTPUT_PARKED_CAR_DATA(VEHICLE_INDEX veh) #IF IS_DEBUG_BUILD IF NOT IS_ENTITY_DEAD(veh) VECTOR v_pos = GET_ENTITY_COORDS(veh) FLOAT fQuatX, fQuatY, fQuatZ, fQuatW GET_ENTITY_QUATERNION(veh, fQuatX, fQuatY, fQuatZ, fQuatW) OPEN_DEBUG_FILE() SAVE_NEWLINE_TO_DEBUG_FILE() SAVE_STRING_TO_DEBUG_FILE("ParkedCarPos[] = <<") SAVE_FLOAT_TO_DEBUG_FILE(v_pos.x) SAVE_STRING_TO_DEBUG_FILE(", ") SAVE_FLOAT_TO_DEBUG_FILE(v_pos.y) SAVE_STRING_TO_DEBUG_FILE(", ") SAVE_FLOAT_TO_DEBUG_FILE(v_pos.z) SAVE_STRING_TO_DEBUG_FIle(">>") SAVE_NEWLINE_TO_DEBUG_FILE() SAVE_STRING_TO_DEBUG_FILE("ParkedCarQuatX[] = ") SAVE_FLOAT_TO_DEBUG_FILE(fQuatX) SAVE_NEWLINE_TO_DEBUG_FILE() SAVE_STRING_TO_DEBUG_FILE("ParkedCarQuatY[] = ") SAVE_FLOAT_TO_DEBUG_FILE(fQuatY) SAVE_NEWLINE_TO_DEBUG_FILE() SAVE_STRING_TO_DEBUG_FILE("ParkedCarQuatZ[] = ") SAVE_FLOAT_TO_DEBUG_FILE(fQuatZ) SAVE_NEWLINE_TO_DEBUG_FILE() SAVE_STRING_TO_DEBUG_FILE("ParkedCarQuatW[] = ") SAVE_FLOAT_TO_DEBUG_FILE(fQuatW) SAVE_NEWLINE_TO_DEBUG_FILE() SAVE_STRING_TO_DEBUG_FILE("ParkedCarModel[] = ") SAVE_STRING_TO_DEBUG_FILE(GET_MODEL_NAME_FOR_DEBUG(GET_ENTITY_MODEL(veh))) SAVE_NEWLINE_TO_DEBUG_FILE() CLOSE_DEBUG_FILE() ENDIF #ENDIF ENDPROC PROC OUTPUT_CLEANED_DATA() INT iTotalNoOfOutputTraffic INT iTotalNoOfOutputParkedCars INT iTotalNoOfOutputSetPieceCars INT i INT iLowestCarToConvert TEXT_LABEL str BOOL bSetPieceCarConverted iTotalNoOfOutputTraffic = 0 iTotalNoOfOutputParkedCars = 0 iTotalNoOfOutputSetPieceCars = 0 #IF IS_DEBUG_BUILD PRINTLN("traffic.sch - Sorting traffic array, may take a few seconds...") #ENDIF SORT_TRAFFIC_ARRAY() #IF IS_DEBUG_BUILD PRINTLN("traffic.sch - Saving data to temp_debug...") #ENDIF OPEN_DEBUG_FILE() // output traffic //str = "\n\n// **** UBER RECORDED TRAFFIC **** \n\n" SAVE_STRING_TO_DEBUG_FILE("\n\n// **** UBER RECORDED TRAFFIC **** \n\n") REPEAT TOTAL_NUMBER_OF_TRAFFIC_CARS i iLowestCarToConvert = LOWEST_SET_PIECE_CAR_TO_CONVERT() bSetPieceCarConverted = FALSE // should we insert the set piece car here? IF NOT (iLowestCarToConvert = -1) IF (SetPieceCarStartime[iLowestCarToConvert] < TrafficCarStartime[i]) SAVE_STRING_TO_DEBUG_FILE("TrafficCarPos[") str = iTotalNoOfOutputTraffic str += "] = <<" SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(SetPieceCarPos[iLowestCarToConvert].x) SAVE_STRING_TO_DEBUG_FILE(", ") SAVE_FLOAT_TO_DEBUG_FILE(SetPieceCarPos[iLowestCarToConvert].y) SAVE_STRING_TO_DEBUG_FILE(", ") SAVE_FLOAT_TO_DEBUG_FILE(SetPieceCarPos[iLowestCarToConvert].z) SAVE_STRING_TO_DEBUG_FIle(">>\n") SAVE_STRING_TO_DEBUG_FILE("TrafficCarQuatX[") str = iTotalNoOfOutputTraffic str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(SetPieceCarQuatX[iLowestCarToConvert]) SAVE_STRING_TO_DEBUG_FILE("\n") SAVE_STRING_TO_DEBUG_FILE("TrafficCarQuatY[") str = iTotalNoOfOutputTraffic str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(SetPieceCarQuatY[iLowestCarToConvert]) SAVE_STRING_TO_DEBUG_FILE("\n") SAVE_STRING_TO_DEBUG_FILE("TrafficCarQuatZ[") str = iTotalNoOfOutputTraffic str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(SetPieceCarQuatZ[iLowestCarToConvert]) SAVE_STRING_TO_DEBUG_FILE("\n") SAVE_STRING_TO_DEBUG_FILE("TrafficCarQuatW[") str = iTotalNoOfOutputTraffic str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(SetPieceCarQuatW[iLowestCarToConvert]) SAVE_STRING_TO_DEBUG_FILE("\n") SAVE_STRING_TO_DEBUG_FILE("TrafficCarRecording[") str = iTotalNoOfOutputTraffic str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_INT_TO_DEBUG_FILE(SetPieceCarRecording[iLowestCarToConvert]) SAVE_STRING_TO_DEBUG_FILE("\n") SAVE_STRING_TO_DEBUG_FILE("TrafficCarStartime[") str = iTotalNoOfOutputTraffic str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(SetPieceCarStartime[iLowestCarToConvert]) SAVE_STRING_TO_DEBUG_FILE("\n") SAVE_STRING_TO_DEBUG_FILE("TrafficCarModel") str = "[" str += iTotalNoOfOutputTraffic str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) str = GET_MODEL_NAME_FOR_DEBUG(SetPieceCarModel[iLowestCarToConvert]) SAVE_STRING_TO_DEBUG_FILE(str) SAVE_STRING_TO_DEBUG_FILE("\n") SAVE_STRING_TO_DEBUG_FILE("\n") bSetPieceCarsConverted[iLowestCarToConvert] = TRUE iTotalNoOfOutputTraffic++ bSetPieceCarConverted = TRUE ENDIF ENDIF // normal traffic cars IF NOT (bSetPieceCarConverted) IF IS_TRAFFIC_CAR_VALID(i) SAVE_STRING_TO_DEBUG_FILE("TrafficCarPos[") str = iTotalNoOfOutputTraffic str += "] = <<" SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(TrafficCarPos[i].x) SAVE_STRING_TO_DEBUG_FILE(", ") SAVE_FLOAT_TO_DEBUG_FILE(TrafficCarPos[i].y) SAVE_STRING_TO_DEBUG_FILE(", ") SAVE_FLOAT_TO_DEBUG_FILE(TrafficCarPos[i].z) SAVE_STRING_TO_DEBUG_FIle(">>\n") SAVE_STRING_TO_DEBUG_FILE("TrafficCarQuatX[") str = iTotalNoOfOutputTraffic str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(TrafficCarQuatX[i]) SAVE_STRING_TO_DEBUG_FILE("\n") SAVE_STRING_TO_DEBUG_FILE("TrafficCarQuatY[") str = iTotalNoOfOutputTraffic str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(TrafficCarQuatY[i]) SAVE_STRING_TO_DEBUG_FILE("\n") SAVE_STRING_TO_DEBUG_FILE("TrafficCarQuatZ[") str = iTotalNoOfOutputTraffic str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(TrafficCarQuatZ[i]) SAVE_STRING_TO_DEBUG_FILE("\n") SAVE_STRING_TO_DEBUG_FILE("TrafficCarQuatW[") str = iTotalNoOfOutputTraffic str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(TrafficCarQuatW[i]) SAVE_STRING_TO_DEBUG_FILE("\n") SAVE_STRING_TO_DEBUG_FILE("TrafficCarRecording[") str = iTotalNoOfOutputTraffic str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_INT_TO_DEBUG_FILE(TrafficCarRecording[i]) SAVE_STRING_TO_DEBUG_FILE("\n") SAVE_STRING_TO_DEBUG_FILE("TrafficCarStartime[") str = iTotalNoOfOutputTraffic str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(TrafficCarStartime[i]) SAVE_STRING_TO_DEBUG_FILE("\n") SAVE_STRING_TO_DEBUG_FILE("TrafficCarModel") str = "[" str += iTotalNoOfOutputTraffic str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) str = GET_MODEL_NAME_FOR_DEBUG(TrafficCarModel[i]) SAVE_STRING_TO_DEBUG_FILE(str) SAVE_STRING_TO_DEBUG_FILE("\n") SAVE_STRING_TO_DEBUG_FILE("\n") iTotalNoOfOutputTraffic++ ENDIF ELSE i-- ENDIF ENDREPEAT SAVE_STRING_TO_DEBUG_FILE("\n\n// **** UBER RECORDED PARKED CARS **** \n\n") REPEAT TOTAL_NUMBER_OF_PARKED_CARS i IF IS_PARKED_CAR_VALID(i) SAVE_STRING_TO_DEBUG_FILE("ParkedCarPos[") str = iTotalNoOfOutputParkedCars str += "] = <<" SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(ParkedCarPos[i].x) SAVE_STRING_TO_DEBUG_FILE(", ") SAVE_FLOAT_TO_DEBUG_FILE(ParkedCarPos[i].y) SAVE_STRING_TO_DEBUG_FILE(", ") SAVE_FLOAT_TO_DEBUG_FILE(ParkedCarPos[i].z) SAVE_STRING_TO_DEBUG_FIle(">>\n") SAVE_STRING_TO_DEBUG_FILE("ParkedCarQuatX[") str = iTotalNoOfOutputParkedCars str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(ParkedCarQuatX[i]) SAVE_STRING_TO_DEBUG_FILE("\n") SAVE_STRING_TO_DEBUG_FILE("ParkedCarQuatY[") str = iTotalNoOfOutputParkedCars str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(ParkedCarQuatY[i]) SAVE_STRING_TO_DEBUG_FILE("\n") SAVE_STRING_TO_DEBUG_FILE("ParkedCarQuatZ[") str = iTotalNoOfOutputParkedCars str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(ParkedCarQuatZ[i]) SAVE_STRING_TO_DEBUG_FILE("\n") SAVE_STRING_TO_DEBUG_FILE("ParkedCarQuatW[") str = iTotalNoOfOutputParkedCars str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(ParkedCarQuatW[i]) SAVE_STRING_TO_DEBUG_FILE("\n") SAVE_STRING_TO_DEBUG_FILE("ParkedCarModel") str = "[" str += iTotalNoOfOutputParkedCars str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) str = GET_MODEL_NAME_FOR_DEBUG(ParkedCarModel[i]) SAVE_STRING_TO_DEBUG_FILE(str) SAVE_STRING_TO_DEBUG_FILE("\n") SAVE_STRING_TO_DEBUG_FILE("\n") iTotalNoOfOutputParkedCars++ ENDIF ENDREPEAT SAVE_STRING_TO_DEBUG_FILE("\n\n// **** UBER RECORDED SET PIECE CARS **** \n\n") REPEAT TOTAL_NUMBER_OF_SET_PIECE_CARS i IF IS_SET_PIECE_CAR_VALID(i) SAVE_STRING_TO_DEBUG_FILE("SetPieceCarPos[") str = iTotalNoOfOutputSetPieceCars str += "] = <<" SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(SetPieceCarPos[i].x) SAVE_STRING_TO_DEBUG_FILE(", ") SAVE_FLOAT_TO_DEBUG_FILE(SetPieceCarPos[i].y) SAVE_STRING_TO_DEBUG_FILE(", ") SAVE_FLOAT_TO_DEBUG_FILE(SetPieceCarPos[i].z) SAVE_STRING_TO_DEBUG_FIle(">>\n") SAVE_STRING_TO_DEBUG_FILE("SetPieceCarQuatX[") str = iTotalNoOfOutputSetPieceCars str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(SetPieceCarQuatX[i]) SAVE_STRING_TO_DEBUG_FILE("\n") SAVE_STRING_TO_DEBUG_FILE("SetPieceCarQuatY[") str = iTotalNoOfOutputSetPieceCars str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(SetPieceCarQuatY[i]) SAVE_STRING_TO_DEBUG_FILE("\n") SAVE_STRING_TO_DEBUG_FILE("SetPieceCarQuatZ[") str = iTotalNoOfOutputSetPieceCars str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(SetPieceCarQuatZ[i]) SAVE_STRING_TO_DEBUG_FILE("\n") SAVE_STRING_TO_DEBUG_FILE("SetPieceCarQuatW[") str = iTotalNoOfOutputSetPieceCars str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(SetPieceCarQuatW[i]) SAVE_STRING_TO_DEBUG_FILE("\n") SAVE_STRING_TO_DEBUG_FILE("SetPieceCarRecording[") str = iTotalNoOfOutputSetPieceCars str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_INT_TO_DEBUG_FILE(SetPieceCarRecording[i]) SAVE_STRING_TO_DEBUG_FILE("\n") SAVE_STRING_TO_DEBUG_FILE("SetPieceCarStartime[") str = iTotalNoOfOutputSetPieceCars str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(SetPieceCarStartime[i]) SAVE_STRING_TO_DEBUG_FILE("\n") SAVE_STRING_TO_DEBUG_FILE("SetPieceCarRecordingSpeed[") str = iTotalNoOfOutputSetPieceCars str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(SetPieceCarRecordingSpeed[i]) SAVE_STRING_TO_DEBUG_FILE("\n") SAVE_STRING_TO_DEBUG_FILE("SetPieceCarModel") str = "[" str += iTotalNoOfOutputSetPieceCars str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) str = GET_MODEL_NAME_FOR_DEBUG(SetPieceCarModel[i]) SAVE_STRING_TO_DEBUG_FILE(str) SAVE_STRING_TO_DEBUG_FILE("\n") SAVE_STRING_TO_DEBUG_FILE("\n") iTotalNoOfOutputSetPieceCars++ ENDIF ENDREPEAT SAVE_STRING_TO_DEBUG_FILE("\n\n// **** POSSIBLE REDUNDANT CAR RECORDINGS **** \n") SAVE_STRING_TO_DEBUG_FILE("//\n") SAVE_STRING_TO_DEBUG_FILE("// The following car recordings MIGHT be redundant. \n") SAVE_STRING_TO_DEBUG_FILE("// They were associated with traffic and set piece cars \n") SAVE_STRING_TO_DEBUG_FILE("// which are now invalid. Please check carefully if they \n") SAVE_STRING_TO_DEBUG_FILE("// are being used somewhere else. If not, remove them from \n") SAVE_STRING_TO_DEBUG_FILE("// alienbrian and the car recording image. \n") SAVE_STRING_TO_DEBUG_FILE("//\n") // traffic REPEAT TOTAL_NUMBER_OF_TRAFFIC_CARS i IF NOT IS_TRAFFIC_CAR_VALID(i) IF NOT (TrafficCarRecording[i] = 0) SAVE_STRING_TO_DEBUG_FILE("// ") SAVE_INT_TO_DEBUG_FILE(TrafficCarRecording[i]) SAVE_STRING_TO_DEBUG_FILE("\n") ENDIF ENDIF ENDREPEAT // set piece REPEAT TOTAL_NUMBER_OF_SET_PIECE_CARS i IF NOT IS_SET_PIECE_CAR_VALID(i) IF NOT (SetPieceCarRecording[i] = 0) SAVE_STRING_TO_DEBUG_FILE("// ") SAVE_INT_TO_DEBUG_FILE(SetPieceCarRecording[i]) SAVE_STRING_TO_DEBUG_FILE("\n") ENDIF ENDIF ENDREPEAT SAVE_STRING_TO_DEBUG_FILE("//\n") SAVE_STRING_TO_DEBUG_FILE("\n // **** end of uber output **** \n") CLOSE_DEBUG_FILE() ENDPROC #ENDIF PROC MAKE_CAR_DRIVE_RANDOMLY(VEHICLE_INDEX inCar) FLOAT fTemp PED_INDEX temp_char IF IS_VEHICLE_DRIVEABLE(inCar) temp_char = GET_PED_IN_VEHICLE_SEAT(inCar) IF NOT IS_PED_INJURED(temp_char) IF NOT (temp_char = PLAYER_PED_ID()) fTemp = GET_ENTITY_SPEED(inCar) IF (fTemp < MIN_CAR_CRUISE_SPEED) fTemp = MIN_CAR_CRUISE_SPEED ENDIF IF (fTemp > MAX_CAR_CRUISE_SPEED) fTemp = MAX_CAR_CRUISE_SPEED ENDIF TASK_VEHICLE_MISSION(temp_char, inCar, NULL, MISSION_CRUISE, fTemp, DRIVINGMODE_STOPFORCARS, 5, 5) SET_PED_FLEE_ATTRIBUTES(temp_char, FA_DISABLE_ACCELERATE_IN_VEHICLE, TRUE) // B*1490105 - Used to stop released uber veh drivers interferring with chase by reacting to player shooting IF bSetReleasedDriversToExitOnFlee SET_PED_FLEE_ATTRIBUTES(temp_char, FA_FORCE_EXIT_VEHICLE, TRUE) SET_PED_FLEE_ATTRIBUTES(temp_char, FA_USE_VEHICLE, FALSE) ENDIF SET_PED_COMBAT_ATTRIBUTES(temp_char, CA_FLEE_WHILST_IN_VEHICLE, FALSE) ENDIF ENDIF ENDIF ENDPROC PROC CHANGE_PLAYBACK_TO_USE_AI_AND_KEEP_SPEED(VEHICLE_INDEX inCar) IF IS_VEHICLE_DRIVEABLE(inCar) MAKE_CAR_DRIVE_RANDOMLY(inCar) SET_PLAYBACK_TO_USE_AI(inCar) ENDIF ENDPROC #IF IS_DEBUG_BUILD PROC RECORD_PARKED_CARS(VEHICLE_INDEX TriggerCar) VEHICLE_INDEX vehNew VEHICLE_INDEX car_to_delete VECTOR pos, pos2, vec FLOAT QuatX, QuatY, QuatZ, QuatW TEXT_LABEL str INT iParkedCarSlot INT i // start new recordings //IF iTotalNumberOfParkedCarsRecorded < TOTAL_NUMBER_OF_PARKED_CARS REPEAT 10 i IF (iCurrentNumberOfParkedCars < MAX_NUMBER_OF_PARKED_CARS_PLAYING_BACK) vehNew = FIND_PARKED_CAR_TO_RECORD(TriggerCar) IF IS_VEHICLE_DRIVEABLE(vehNew) iParkedCarSlot = GET_FREE_RECORDED_PARKED_CAR_SLOT() IF NOT (iParkedCarSlot = -1) IF DOES_BLIP_EXIST(ActiveParkedCarBlipID[iParkedCarSlot]) REMOVE_BLIP(ActiveParkedCarBlipID[iParkedCarSlot]) ENDIF SET_ENTITY_AS_MISSION_ENTITY(vehNew) ActiveParkedCarBlipID[iParkedCarSlot] = ADD_BLIP_FOR_ENTITY(vehNew) SET_BLIP_SCALE(ActiveParkedCarBlipID[iParkedCarSlot], 0.5) RecordedParkedCarID[iParkedCarSlot] = vehNew // start position pos = GET_ENTITY_COORDS(vehNew) SAVE_NEWLINE_TO_DEBUG_FILE() str = "ParkedCarPos[" SAVE_STRING_TO_DEBUG_FILE(str) str = iTotalNumberOfParkedCarsRecorded str += "] = <<" SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(pos.x) SAVE_STRING_TO_DEBUG_FILE(", ") SAVE_FLOAT_TO_DEBUG_FILE(pos.y) SAVE_STRING_TO_DEBUG_FILE(", ") SAVE_FLOAT_TO_DEBUG_FILE(pos.z) SAVE_STRING_TO_DEBUG_FIle(">>") // start quaternion GET_ENTITY_QUATERNION(vehNew, QuatX, QuatY, QuatZ, QuatW) SAVE_NEWLINE_TO_DEBUG_FILE() str = "ParkedCarQuatX" SAVE_STRING_TO_DEBUG_FILE(str) str = "[" str += iTotalNumberOfParkedCarsRecorded str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(QuatX) SAVE_NEWLINE_TO_DEBUG_FILE() str = "ParkedCarQuatY" SAVE_STRING_TO_DEBUG_FILE(str) str = "[" str += iTotalNumberOfParkedCarsRecorded str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(QuatY) SAVE_NEWLINE_TO_DEBUG_FILE() str = "ParkedCarQuatZ" SAVE_STRING_TO_DEBUG_FILE(str) str = "[" str += iTotalNumberOfParkedCarsRecorded str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(QuatZ) SAVE_NEWLINE_TO_DEBUG_FILE() str = "ParkedCarQuatW" SAVE_STRING_TO_DEBUG_FILE(str) str = "[" str += iTotalNumberOfParkedCarsRecorded str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) SAVE_FLOAT_TO_DEBUG_FILE(QuatW) // model type SAVE_NEWLINE_TO_DEBUG_FILE() str = "ParkedCarModel" SAVE_STRING_TO_DEBUG_FILE(str) str = "[" str += iTotalNumberOfParkedCarsRecorded str += "] = " SAVE_STRING_TO_DEBUG_FILE(str) str = GET_MODEL_NAME_OF_VEHICLE_FOR_DEBUG_ONLY(vehNew) SAVE_STRING_TO_DEBUG_FILE(str) SAVE_NEWLINE_TO_DEBUG_FILE() iTotalNumberOfParkedCarsRecorded++ ENDIF ENDIF ENDIF ENDREPEAT // remove parked cars that have been recorded IF IS_VEHICLE_DRIVEABLE(TriggerCar) REPEAT MAX_NUMBER_OF_PARKED_CARS_PLAYING_BACK i IF DOES_ENTITY_EXIST(RecordedParkedCarID[i]) IF IS_VEHICLE_DRIVEABLE(RecordedParkedCarID[i]) IF NOT IS_RECORDING_GOING_ON_FOR_VEHICLE(RecordedParkedCarID[i]) IF NOT IS_CAR_IN_FRONT_OF_CAR(RecordedParkedCarID[i], TriggerCar) pos = GET_ENTITY_COORDS(TriggerCar) pos2 = GET_ENTITY_COORDS(RecordedParkedCarID[i]) vec = pos2 - pos vec.z = 0.0 IF (VMAG2(vec) > (fTrafficRecordingDistanceAroundCar * fTrafficRecordingDistanceAroundCar)) //IF NOT IS_VEHICLE_AT_COORD @_No_of_params (RecordedParkedCarID[i], pos.x, pos.y, fTrafficRecordingDistanceAroundCar, fTrafficRecordingDistanceAroundCar, FALSE) IF (bDeleteTrafficWhenRecorded) IF DOES_BLIP_EXIST(ActiveParkedCarBlipID[i]) REMOVE_BLIP(ActiveParkedCarBlipID[i]) ENDIF DELETE_VEHICLE(RecordedParkedCarID[i]) ENDIF ENDIF ENDIF ENDIF ELSE IF DOES_BLIP_EXIST(ActiveParkedCarBlipID[i]) REMOVE_BLIP(ActiveParkedCarBlipID[i]) ENDIF DELETE_VEHICLE(RecordedParkedCarID[i]) ENDIF ENDIF ENDREPEAT ENDIF // remove any cars that arn't being recorded IF (bDeleteRedundantParkedCars) REPEAT 20 i pos = GET_ENTITY_COORDS(TriggerCar) car_to_delete = GET_RANDOM_VEHICLE_IN_SPHERE(pos, 30.0 ,DUMMY_MODEL_FOR_SCRIPT, VEHICLE_SEARCH_FLAG_RETURN_RANDOM_VEHICLES) IF DOES_ENTITY_EXIST(car_to_delete) IF NOT IS_RECORDING_GOING_ON_FOR_VEHICLE(car_to_delete) IF IS_THIS_A_PARKED_CAR(car_to_delete) IF NOT HAS_PARKED_CAR_BEEN_RECORDED(car_to_delete) DELETE_VEHICLE(car_to_delete) ENDIF ENDIF ENDIF ENDIF ENDREPEAT ENDIF // count current number of parked cars iCurrentNumberOfParkedCars = 0 REPEAT MAX_NUMBER_OF_PARKED_CARS_PLAYING_BACK i IF DOES_ENTITY_EXIST(RecordedParkedCarID[i]) iCurrentNumberOfParkedCars++ ENDIF ENDREPEAT ENDPROC #ENDIF #IF IS_DEBUG_BUILD PROC RECORD_CAR(VEHICLE_INDEX InCar, INT iRecNo) IF IS_VEHICLE_DRIVEABLE(InCar) IF NOT IS_RECORDING_GOING_ON_FOR_VEHICLE(InCar) OPEN_DEBUG_FILE() vMainRecordingStartPosition = GET_ENTITY_COORDS(InCar) GET_ENTITY_QUATERNION(InCar, fMainRecordingStartQuatX, fMainRecordingStartQuatY, fMainRecordingStartQuatZ, fMainRecordingStartQuatW) PRINT_NOW("CRECSTART5", 5000, 1) // PRINT_NOW("STARTED", 5000, 1) IF NOT START_RECORDING_VEHICLE(InCar, iRecNo, strUberName, TRUE) TEXT_LABEL_63 str str = "Error with car recording " str += iRecNo str += " ensure file is checked out." SCRIPT_ASSERT(str) ENDIF fRecordingTimer = 0.0 ELSE FLOAT frame_time frame_time = GET_FRAME_TIME() fRecordingTimer += (frame_time * 1000.0) //fRecordingTimer = GET_TIME_POSITION_IN_RECORDING(InCar) ENDIF ENDIF ENDPROC #ENDIF #IF IS_DEBUG_BUILD FUNC BOOL RECORD_PLAYERS_CAR_WITH_TRAFFIC() IF IS_PLAYER_PLAYING(PLAYER_ID()) IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) MainRecordingCar = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()) ELSE RETURN(FALSE) ENDIF ENDIF IF IS_VEHICLE_DRIVEABLE(MainRecordingCar) RECORD_CAR(MainRecordingCar, iMainCarRecordingFile) IF IS_RECORDING_GOING_ON_FOR_VEHICLE(MainRecordingCar) IF (bIncludeParkedCars) RECORD_PARKED_CARS(MainRecordingCar) ENDIF RECORD_TRAFFIC(MainRecordingCar) RETURN(TRUE) ELSE ENDIF ENDIF RETURN(FALSE) ENDFUNC #ENDIF #IF IS_DEBUG_BUILD PROC STOP_RECORDING_PLAYERS_CAR_AND_TRAFFIC() INT i IF IS_VEHICLE_DRIVEABLE(MainRecordingCar) IF IS_RECORDING_GOING_ON_FOR_VEHICLE(MainRecordingCar) STOP_RECORDING_VEHICLE(MainRecordingCar) //PRINT_NOW("STOPPED", 5000, 1) PRINT_NOW("CRECSTOP5", 5000, 1) CLOSE_DEBUG_FILE() ENDIF ENDIF REPEAT MAX_NUMBER_OF_TRAFFIC_CARS_PLAYING_BACK i IF IS_VEHICLE_DRIVEABLE(RecordedTrafficCarID[i]) IF IS_RECORDING_GOING_ON_FOR_VEHICLE(RecordedTrafficCarID[i]) STOP_RECORDING_VEHICLE(RecordedTrafficCarID[i]) ENDIF IF DOES_BLIP_EXIST(ActiveTrafficCarBlipID[i]) REMOVE_BLIP(ActiveTrafficCarBlipID[i]) ENDIF DELETE_VEHICLE(RecordedTrafficCarID[i]) ENDIF ENDREPEAT REPEAT MAX_NUMBER_OF_PARKED_CARS_PLAYING_BACK i IF IS_VEHICLE_DRIVEABLE(RecordedParkedCarID[i]) IF IS_RECORDING_GOING_ON_FOR_VEHICLE(RecordedParkedCarID[i]) STOP_RECORDING_VEHICLE(RecordedParkedCarID[i]) ENDIF IF DOES_BLIP_EXIST(ActiveParkedCarBlipID[i]) REMOVE_BLIP(ActiveParkedCarBlipID[i]) ENDIF DELETE_VEHICLE(RecordedParkedCarID[i]) ENDIF ENDREPEAT // reset variables iCurrentNumberOfTrafficRecordings = 0 iCurrentNumberOfParkedCars = 0 iTotalNumberOfParkedCarsRecorded = 0 iTotalNumberOfTrafficCarsRecorded = 0 ENDPROC #ENDIF #IF IS_DEBUG_BUILD PROC UPDATE_TRAFFIC_RECORDING() CREATE_TRAFFIC_WIDGET() VECTOR pos // clear surrounding area IF (bClearArea) IF IS_PLAYER_PLAYING(PLAYER_ID()) pos = GET_ENTITY_COORDS(PLAYER_PED_ID()) CLEAR_AREA(pos, 1000.0, TRUE) ENDIF bClearArea = FALSE ENDIF IF (bStopParkedCarsFromBeingSpawned) SET_NUMBER_OF_PARKED_VEHICLES(0) ELSE SET_NUMBER_OF_PARKED_VEHICLES(-1) ENDIF // traffic density SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(fCarDensityMultiplier) IF (bResetToStartPosition) bStartRecordingPlayersCarWithTraffic = FALSE ENDIF IF (bStartRecordingPlayersCarWithTraffic) IF NOT RECORD_PLAYERS_CAR_WITH_TRAFFIC() bStartRecordingPlayersCarWithTraffic = FALSE ENDIF ELSE STOP_RECORDING_PLAYERS_CAR_AND_TRAFFIC() IF (bResetToStartPosition) IF IS_PLAYER_PLAYING(PLAYER_ID()) IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) MainRecordingCar = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()) IF IS_VEHICLE_DRIVEABLE(MainRecordingCar) SET_ENTITY_HEALTH(MainRecordingCar, 1000) SET_VEHICLE_FIXED(MainRecordingCar) SET_ENTITY_COORDS(MainRecordingCar, vMainRecordingStartPosition) SET_ENTITY_QUATERNION(MainRecordingCar, fMainRecordingStartQuatX, fMainRecordingStartQuatY, fMainRecordingStartQuatZ, fMainRecordingStartQuatW) LOAD_SCENE(vMainRecordingStartPosition) SET_ENTITY_COORDS(MainRecordingCar, vMainRecordingStartPosition) SET_ENTITY_QUATERNION(MainRecordingCar, fMainRecordingStartQuatX, fMainRecordingStartQuatY, fMainRecordingStartQuatZ, fMainRecordingStartQuatW) ENDIF ENDIF ENDIF bResetToStartPosition = FALSE ENDIF ENDIF ENDPROC #ENDIF PROC DELETE_ALL_TRAFFIC_CARS() INT i REPEAT TOTAL_NUMBER_OF_TRAFFIC_CARS i IF DOES_ENTITY_EXIST(TrafficCarID[i]) IF IS_VEHICLE_DRIVEABLE(TrafficCarID[i]) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(TrafficCarID[i]) STOP_PLAYBACK_RECORDED_VEHICLE(TrafficCarID[i]) ENDIF //Delete the driver PED_INDEX ped_temp = GET_PED_IN_VEHICLE_SEAT(TrafficCarID[i]) IF DOES_ENTITY_EXIST(ped_temp) AND ped_temp != PLAYER_PED_ID() IF IS_ENTITY_A_MISSION_ENTITY(ped_temp) DELETE_PED(ped_temp) ENDIF ENDIF ENDIF IF IS_ENTITY_A_MISSION_ENTITY(TrafficCarID[i]) DELETE_VEHICLE(TrafficCarID[i]) ENDIF ENDIF IF NOT bSetPieceRecordingsAreActive AND NOT bTrafficDontCleanupRecordingFiles IF TrafficCarRecording[i] > 0 REMOVE_VEHICLE_RECORDING(TrafficCarRecording[i], strUberName) ENDIF ENDIF TrafficCarProgress[i] = 0 ENDREPEAT REPEAT TOTAL_NUMBER_OF_TRAFFIC_CARS i IF NOT (TrafficCarModel[i] = DUMMY_MODEL_FOR_SCRIPT) SET_MODEL_AS_NO_LONGER_NEEDED(TrafficCarModel[i]) ENDIF ENDREPEAT iFirstCarToProcess = 0 iCurrentNumberOfTrafficPlaybacks = 0 ENDPROC PROC DELETE_ALL_PARKED_CARS() INT i REPEAT TOTAL_NUMBER_OF_PARKED_CARS i IF DOES_ENTITY_EXIST(ParkedCarID[i]) IF IS_ENTITY_A_MISSION_ENTITY(ParkedCarID[i]) DELETE_VEHICLE(ParkedCarID[i]) ENDIF ENDIF ParkedCarProgress[i] = 0 ENDREPEAT REPEAT TOTAL_NUMBER_OF_PARKED_CARS i IF NOT (ParkedCarModel[i] = DUMMY_MODEL_FOR_SCRIPT) SET_MODEL_AS_NO_LONGER_NEEDED(ParkedCarModel[i]) ENDIF ENDREPEAT iFirstParkedCarToProcess = 0 iCurrentNumberOfParkedCars = 0 ENDPROC PROC DELETE_ALL_SET_PIECE_CARS() INT i REPEAT TOTAL_NUMBER_OF_SET_PIECE_CARS i IF DOES_ENTITY_EXIST(SetPieceCarID[i]) IF IS_VEHICLE_DRIVEABLE(SetPieceCarID[i]) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(SetPieceCarID[i]) STOP_PLAYBACK_RECORDED_VEHICLE(SetPieceCarID[i]) ENDIF //Delete the driver PED_INDEX ped_temp = GET_PED_IN_VEHICLE_SEAT(SetPieceCarID[i]) IF DOES_ENTITY_EXIST(ped_temp) AND ped_temp != PLAYER_PED_ID() IF IS_ENTITY_A_MISSION_ENTITY(ped_temp) DELETE_PED(ped_temp) ENDIF ENDIF ENDIF IF IS_ENTITY_A_MISSION_ENTITY(SetPieceCarID[i]) DELETE_VEHICLE(SetPieceCarID[i]) ENDIF ENDIF SetPieceCarProgress[i] = 0 IF NOT bSetPieceRecordingsAreActive AND NOT bTrafficDontCleanupRecordingFiles IF SetPieceCarRecording[i] > 0 REMOVE_VEHICLE_RECORDING(SetPieceCarRecording[i], strUberName) ENDIF ENDIF ENDREPEAT REPEAT TOTAL_NUMBER_OF_SET_PIECE_CARS i IF NOT (SetPieceCarModel[i] = DUMMY_MODEL_FOR_SCRIPT) SET_MODEL_AS_NO_LONGER_NEEDED(SetPieceCarModel[i]) ENDIF ENDREPEAT ENDPROC PROC DELETE_ALL_CARS_IN_UBER_PLAYBACK() DELETE_ALL_TRAFFIC_CARS() DELETE_ALL_PARKED_CARS() DELETE_ALL_SET_PIECE_CARS() ENDPROC PROC MARK_ALL_TRAFFIC_CARS_AS_NO_LONGER_NEEDED() INT i REPEAT TOTAL_NUMBER_OF_TRAFFIC_CARS i IF DOES_ENTITY_EXIST(TrafficCarID[i]) IF NOT IS_ENTITY_DEAD(TrafficCarID[i]) SET_ENTITY_COLLISION(TrafficCarID[i], TRUE) ENDIF IF IS_VEHICLE_DRIVEABLE(TrafficCarID[i]) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(TrafficCarID[i]) STOP_PLAYBACK_RECORDED_VEHICLE(TrafficCarID[i]) ENDIF ENDIF MAKE_CAR_DRIVE_RANDOMLY(TrafficCarID[i]) MARK_CAR_AS_NO_LONGER_NEEDED_KEEP_ID(TrafficCarID[i]) ENDIF TrafficCarProgress[i] = 0 TrafficCarFlags[i] = 0 IF NOT bSetPieceRecordingsAreActive AND NOT bTrafficDontCleanupRecordingFiles IF TrafficCarRecording[i] > 0 REMOVE_VEHICLE_RECORDING(TrafficCarRecording[i], strUberName) ENDIF ENDIF ENDREPEAT REPEAT TOTAL_NUMBER_OF_TRAFFIC_CARS i IF NOT (TrafficCarModel[i] = DUMMY_MODEL_FOR_SCRIPT) SET_MODEL_AS_NO_LONGER_NEEDED(TrafficCarModel[i]) ENDIF ENDREPEAT iFirstCarToProcess = 0 iCurrentNumberOfTrafficPlaybacks = 0 ENDPROC PROC MARK_ALL_PARKED_CARS_AS_NO_LONGER_NEEDED() INT i REPEAT TOTAL_NUMBER_OF_PARKED_CARS i IF DOES_ENTITY_EXIST(ParkedCarID[i]) IF NOT IS_ENTITY_DEAD(ParkedCarID[i]) SET_ENTITY_COLLISION(ParkedCarID[i], TRUE) ENDIF MARK_CAR_AS_NO_LONGER_NEEDED_KEEP_ID(ParkedCarID[i]) ENDIF ENDREPEAT REPEAT TOTAL_NUMBER_OF_PARKED_CARS i IF NOT (ParkedCarModel[i] = DUMMY_MODEL_FOR_SCRIPT) SET_MODEL_AS_NO_LONGER_NEEDED(ParkedCarModel[i]) ENDIF ENDREPEAT iFirstParkedCarToProcess = 0 iCurrentNumberOfParkedCars = 0 ENDPROC PROC MARK_ALL_SET_PIECE_CARS_AS_NO_LONGER_NEEDED() INT i REPEAT TOTAL_NUMBER_OF_SET_PIECE_CARS i IF DOES_ENTITY_EXIST(SetPieceCarID[i]) // IF NOT IS_ENTITY_DEAD(SetPieceCarID[i]) // SET_ENTITY_COLLISION(SetPieceCarID[i], TRUE) // ENDIF IF IS_VEHICLE_DRIVEABLE(SetPieceCarID[i]) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(SetPieceCarID[i]) STOP_PLAYBACK_RECORDED_VEHICLE(SetPieceCarID[i]) ENDIF ENDIF MAKE_CAR_DRIVE_RANDOMLY(SetPieceCarID[i]) MARK_CAR_AS_NO_LONGER_NEEDED_KEEP_ID(SetPieceCarID[i]) ENDIF SetPieceCarProgress[i] = 0 SetPieceCarFlags[i] = 0 IF NOT bSetPieceRecordingsAreActive AND NOT bTrafficDontCleanupRecordingFiles IF SetPieceCarRecording[i] > 0 REMOVE_VEHICLE_RECORDING(SetPieceCarRecording[i], strUberName) ENDIF ENDIF ENDREPEAT REPEAT TOTAL_NUMBER_OF_SET_PIECE_CARS i IF NOT (SetPieceCarModel[i] = DUMMY_MODEL_FOR_SCRIPT) SET_MODEL_AS_NO_LONGER_NEEDED(SetPieceCarModel[i]) ENDIF ENDREPEAT iFirstSetpieceCarToProcess = 0 ENDPROC PROC FLUSH_ALL_TRAFFIC_DATA() INT i REPEAT TOTAL_NUMBER_OF_TRAFFIC_CARS i TrafficCarID[i] = NULL TrafficCarPos[i] = <<0.0, 0.0, 0.0>> TrafficCarQuatX[i] = 0.0 TrafficCarQuatY[i] = 0.0 TrafficCarQuatZ[i] = 0.0 TrafficCarQuatW[i] = 0.0 TrafficCarRecording[i] = 0 TrafficCarStartime[i] = 0.0 TrafficCarProgress[i] = 0 TrafficCarModel[i] = DUMMY_MODEL_FOR_SCRIPT TrafficCarFlags[i] = 0 ENDREPEAT REPEAT MAX_NUMBER_OF_TRAFFIC_CARS_PLAYING_BACK i RecordedTrafficCarID[i] = NULL ENDREPEAT iCurrentNumberOfTrafficPlaybacks = 0 #IF IS_DEBUG_BUILD iTotalNumberOfTrafficCarsRecorded = 0 iCurrentNumberOfTrafficRecordings = 0 #ENDIF REPEAT TOTAL_NUMBER_OF_PARKED_CARS i ParkedCarID[i] = NULL ParkedCarPos[i] = <<0.0, 0.0, 0.0>> ParkedCarQuatX[i] = 0.0 ParkedCarQuatY[i] = 0.0 ParkedCarQuatZ[i] = 0.0 ParkedCarQuatW[i] = 0.0 ParkedCarProgress[i] = 0 ParkedCarModel[i] = DUMMY_MODEL_FOR_SCRIPT ENDREPEAT REPEAT MAX_NUMBER_OF_PARKED_CARS_PLAYING_BACK i RecordedParkedCarID[i] = NULL ENDREPEAT #IF IS_DEBUG_BUILD iTotalNumberOfParkedCarsRecorded = 0 #ENDIF iCurrentNumberOfParkedCars = 0 REPEAT TOTAL_NUMBER_OF_SET_PIECE_CARS i SetPieceCarID[i] = NULL SetPieceCarPos[i] = <<0.0, 0.0, 0.0>> SetPieceCarQuatX[i] = 0.0 SetPieceCarQuatY[i] = 0.0 SetPieceCarQuatZ[i] = 0.0 SetPieceCarQuatW[i] = 0.0 SetPieceCarRecording[i] = 0 SetPieceCarStartime[i] = 0.0 SetPieceCarProgress[i] = 0 SetPieceCarModel[i] = DUMMY_MODEL_FOR_SCRIPT SetPieceCarFlags[i] = 0 ENDREPEAT iCurrentNumberOfSetPieceCarPlaybacks = 0 iFirstCarToProcess = 0 iParkedCarsWaitingToCreate = 0 iSetPieceCarsWaitingToCreate = 0 iTrafficCarsWaitingToCreate = 0 ENDPROC PROC UPDATE_PARKED_CARS(VEHICLE_INDEX TriggerCar) INT i VECTOR vPlayerPos, vParkedCarPos //INTERIOR_INSTANCE_INDEX CarInterior IF IS_PLAYER_PLAYING(PLAYER_ID()) vPlayerPos = GET_ENTITY_COORDS(PLAYER_PED_ID()) ENDIF //iParkedCarsProcessedThisFrame = 0 #IF IS_DEBUG_BUILD IF (iHighlightedParkedCar > -1) AND (iHighlightedParkedCar < TOTAL_NUMBER_OF_PARKED_CARS) // remove blip if car doesn't exist IF NOT DOES_ENTITY_EXIST(ParkedCarID[iHighlightedParkedCar]) IF DOES_BLIP_EXIST(HighlightedParkedCarBlipID) REMOVE_BLIP(HighlightedParkedCarBlipID) ENDIF HighlightedParkedCarID = NULL ENDIF // remove blip if highlighted car is dIFferent from the current one. IF DOES_ENTITY_EXIST(HighlightedParkedCarID) IF DOES_ENTITY_EXIST(ParkedCarID[iHighlightedParkedCar]) IF NOT (ParkedCarID[iHighlightedParkedCar] = HighlightedParkedCarID) IF DOES_BLIP_EXIST(HighlightedParkedCarBlipID) REMOVE_BLIP(HighlightedParkedCarBlipID) ENDIF HighlightedParkedCarID = NULL ENDIF ENDIF ELSE IF DOES_BLIP_EXIST(HighlightedParkedCarBlipID) REMOVE_BLIP(HighlightedParkedCarBlipID) ENDIF ENDIF // add blip IF NOT DOES_ENTITY_EXIST(HighlightedParkedCarID) IF DOES_ENTITY_EXIST(ParkedCarID[iHighlightedParkedCar]) IF NOT DOES_BLIP_EXIST(HighlightedParkedCarBlipID) HighlightedParkedCarBlipID = ADD_BLIP_FOR_ENTITY(ParkedCarID[iHighlightedParkedCar]) SET_BLIP_COLOUR(HighlightedParkedCarBlipID, BLIP_COLOUR_WHITE) HighlightedParkedCarID = ParkedCarID[iHighlightedParkedCar] ENDIF ENDIF ENDIF ELSE IF DOES_BLIP_EXIST(HighlightedParkedCarBlipID) REMOVE_BLIP(HighlightedParkedCarBlipID) ENDIF ENDIF #ENDIF IF IS_VEHICLE_DRIVEABLE(TriggerCar) BOOL bRemovedCarThisFrame = FALSE BOOL bFoundFirstCarToProcess = FALSE #IF IS_DEBUG_BUILD TEXT_LABEL_63 debugCarName #ENDIF i = iFirstParkedCarToProcess WHILE i < TOTAL_NUMBER_OF_PARKED_CARS SWITCH ParkedCarProgress[i] CASE 0 IF NOT (ParkedCarModel[i] = DUMMY_MODEL_FOR_SCRIPT) IF IS_ENTITY_AT_COORD(TriggerCar, ParkedCarPos[i], <>, FALSE, TRUE) iParkedCarsWaitingToCreate++ ParkedCarProgress[i]++ ENDIF ELSE ParkedCarProgress[i] = 99 ENDIF BREAK CASE 1 IF MAX_NUMBER_OF_PARKED_CARS_PLAYING_BACK > iCurrentNumberOfParkedCars IF NOT DOES_ENTITY_EXIST(ParkedCarID[i]) REQUEST_MODEL(ParkedCarModel[i]) IF HAS_MODEL_LOADED(ParkedCarModel[i]) IF bResetPlaybackToTime OR bCreateAllWaitingCars OR (NOT bCreatedUberPlaybackEntityThisFrame AND NOT private_IS_POINT_VISIBLE_TO_PLAYER_POS(ParkedCarPos[i], vPlayerPos, 5.0, fUberPlaybackMinCreationDistance)) IF (bCarsAreOn) private_SAFE_CLEAR_AREA_OF_VEHICLES(ParkedCarPos[i], vPlayerPos, fClearSurroundingCarsDistance) ENDIF ParkedCarID[i] = CREATE_VEHICLE(ParkedCarModel[i], ParkedCarPos[i], DEFAULT, FALSE, FALSE) IF ParkedCarModel[i] = POLMAV SET_VEHICLE_LIVERY(ParkedCarID[i], 0) ENDIF #IF IS_DEBUG_BUILD debugCarName += "Parked " debugCarName += i SET_VEHICLE_NAME_DEBUG(ParkedCarID[i], debugCarName) #ENDIF SET_ENTITY_QUATERNION(ParkedCarID[i], ParkedCarQuatX[i], ParkedCarQuatY[i], ParkedCarQuatZ[i], ParkedCarQuatW[i]) SET_MODEL_AS_NO_LONGER_NEEDED(ParkedCarModel[i]) IF IS_VEHICLE_MODEL(ParkedCarID[i], COP_CAR_MODEL()) SET_VEHICLE_SIREN(ParkedCarID[i], TRUE) IF NOT IS_THIS_MODEL_A_BIKE(ParkedCarModel[i]) SET_SIREN_WITH_NO_DRIVER(ParkedCarID[i], TRUE) ENDIF ENDIF IF IS_VEHICLE_MODEL(ParkedCarID[i], DEFAULT_CAR_MODEL()) SET_VEHICLE_COLOURS(ParkedCarID[i], 0, 0) ENDIF SET_ENTITY_SHOULD_FREEZE_WAITING_ON_COLLISION(ParkedCarID[i], TRUE) //[MF] Fix for B* 1699535 // check if in an interior //CarInterior = GET_INTERIOR_FROM_ENTITY(ParkedCarID[i]) //IF NOT (CarInterior = NULL) //SET_CAR_HAS_BEEN_CREATED_IN_INTERIOR(ParkedCarID[i]) //ENDIF iParkedCarsWaitingToCreate-- iCurrentNumberOfParkedCars++ ParkedCarProgress[i]++ bCreatedUberPlaybackEntityThisFrame = TRUE ENDIF ENDIF ELSE //Parked car already exists, so just progress as normal. iParkedCarsWaitingToCreate-- iCurrentNumberOfParkedCars++ ParkedCarProgress[i]++ ENDIF ENDIF BREAK CASE 2 IF NOT bRemovedCarThisFrame IF IS_VEHICLE_DRIVEABLE(ParkedCarID[i]) vParkedCarPos = GET_ENTITY_COORDS(ParkedCarID[i]) ENDIF //If the parked cars are more critical to the mission the scripter can set fUberPlaybackParkedCarCleanupDistance. This means the player has to be within //this distance of the parked car before it's set as no longer needed. IF fUberPlaybackParkedCarCleanupDistance = 0.0 OR VDIST2(vPlayerPos, vParkedCarPos) < (fUberPlaybackParkedCarCleanupDistance * fUberPlaybackParkedCarCleanupDistance) IF NOT IS_CAR_IN_FRONT_OF_CAR(ParkedCarID[i], TriggerCar) IF NOT (bDeleteCarsWhenDone) MARK_CAR_AS_NO_LONGER_NEEDED_KEEP_ID(ParkedCarID[i]) ELSE DELETE_VEHICLE(ParkedCarID[i]) ENDIF iCurrentNumberOfParkedCars-- ParkedCarProgress[i] = 99 bRemovedCarThisFrame = TRUE ENDIF ENDIF ENDIF BREAK ENDSWITCH IF ParkedCarProgress[i] != 99 //If this is the first car we've reached that hasn't been removed from processing, mark it as the start point for the next frame. IF NOT bFoundFirstCarToProcess iFirstParkedCarToProcess = i bFoundFirstCarToProcess = TRUE ENDIF ENDIF i++ ENDWHILE ELSE MARK_ALL_PARKED_CARS_AS_NO_LONGER_NEEDED() ENDIF ENDPROC PROC REMOVE_TRAFFIC_CAR_FROM_PROCESSING(INT iTrafficArrayIndex, FLOAT fCruiseSpeed = MIN_CAR_CRUISE_SPEED) PED_INDEX pedDriver IF NOT (TrafficCarModel[iTrafficArrayIndex] = DUMMY_MODEL_FOR_SCRIPT) SET_MODEL_AS_NO_LONGER_NEEDED(TrafficCarModel[iTrafficArrayIndex]) ENDIF IF NOT IS_ENTITY_DEAD(TrafficCarID[iTrafficArrayIndex]) SET_ENTITY_COLLISION(TrafficCarID[iTrafficArrayIndex], TRUE) FREEZE_ENTITY_POSITION(TrafficCarID[iTrafficArrayIndex], FALSE) pedDriver = GET_PED_IN_VEHICLE_SEAT(TrafficCarID[iTrafficArrayIndex]) IF NOT IS_PED_INJURED(pedDriver) AND pedDriver != PLAYER_PED_ID() SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(pedDriver, FALSE) IF (fCruiseSpeed < MIN_CAR_CRUISE_SPEED) fCruiseSpeed = MIN_CAR_CRUISE_SPEED ENDIF IF (fCruiseSpeed > MAX_CAR_CRUISE_SPEED) fCruiseSpeed = MAX_CAR_CRUISE_SPEED ENDIF TASK_VEHICLE_MISSION(pedDriver, TrafficCarID[iTrafficArrayIndex], NULL, MISSION_CRUISE, fCruiseSpeed, DRIVINGMODE_STOPFORCARS, 5, 5) SET_PED_FLEE_ATTRIBUTES(pedDriver, FA_DISABLE_ACCELERATE_IN_VEHICLE, TRUE) // B*1490105 - Used to stop released uber veh drivers interferring with chase by reacting to player shooting IF bSetReleasedDriversToExitOnFlee SET_PED_FLEE_ATTRIBUTES(pedDriver, FA_FORCE_EXIT_VEHICLE, TRUE) SET_PED_FLEE_ATTRIBUTES(pedDriver, FA_USE_VEHICLE, FALSE) ENDIF SET_PED_COMBAT_ATTRIBUTES(pedDriver, CA_FLEE_WHILST_IN_VEHICLE, FALSE) SET_DRIVE_TASK_CRUISE_SPEED(pedDriver, fCruiseSpeed) ENDIF ENDIF IF NOT bDeleteCarsWhenDone IF NOT bDontCleanUpUberCarsForTrailer MARK_CHAR_AS_NO_LONGER_NEEDED_KEEP_ID(pedDriver) MARK_CAR_AS_NO_LONGER_NEEDED_KEEP_ID(TrafficCarID[iTrafficArrayIndex]) ENDIF ELSE IF DOES_ENTITY_EXIST(pedDriver) DELETE_PED(pedDriver) ENDIF IF DOES_ENTITY_EXIST(TrafficCarID[iTrafficArrayIndex]) DELETE_VEHICLE(TrafficCarID[iTrafficArrayIndex]) ENDIF ENDIF IF NOT bSetPieceRecordingsAreActive AND NOT bTrafficDontCleanupRecordingFiles IF TrafficCarRecording[iTrafficArrayIndex] > 0 REMOVE_VEHICLE_RECORDING(TrafficCarRecording[iTrafficArrayIndex], strUberName) ENDIF ENDIF TrafficCarProgress[iTrafficArrayIndex] = 99 ENDPROC //allows you to block 2 vehicle colours. If you only need to block one colour just pass in NULL to colour_1 PROC traffic_block_vehicle_colour(BOOL block_colour, block_colour_ENUM colour_0, block_colour_ENUM colour_1 = dont_block_colour) IF block_colour block_vehicle_colour = TRUE colour_to_block_0 = colour_0 colour_to_block_1 = colour_1 ENDIF ENDPROC PROC traffic_block_vehicle_colour_from_generating(VEHICLE_INDEX traffic_file_veh) INT random_INT block_colour_ENUM traffic_colour random_int = get_random_int_in_range(0, 12) IF (colour_to_block_0 >= dont_block_colour) and (colour_to_block_1 >= dont_block_colour) while (random_int = ENUM_TO_INT(colour_to_block_0)) or (random_int = ENUM_TO_INT(colour_to_block_1)) random_int++ endwhile elif (colour_to_block_0 >= dont_block_colour) IF random_int = ENUM_TO_INT(colour_to_block_0)//colour_to_block is set in traffic_block_vehicle_colour() random_int++ ENDIF ENDIF traffic_colour = INT_TO_ENUM(block_colour_ENUM, random_int) switch traffic_colour case traffic_black set_vehicle_colours(traffic_file_veh, 0, 0) break case traffic_grey set_vehicle_colours(traffic_file_veh, 2, 2) break case traffic_silver set_vehicle_colours(traffic_file_veh, 4, 4) break case traffic_red set_vehicle_colours(traffic_file_veh, 27, 27) break case traffic_white set_vehicle_colours(traffic_file_veh, 7, 7) break case traffic_blue set_vehicle_colours(traffic_file_veh, 73, 73) break case traffic_navy set_vehicle_colours(traffic_file_veh, 68, 68) break case traffic_light_blue set_vehicle_colours(traffic_file_veh, 62, 62) break case traffic_cream set_vehicle_colours(traffic_file_veh, 132, 132) break case traffic_turquoise set_vehicle_colours(traffic_file_veh, 117, 0) break case traffic_green set_vehicle_colours(traffic_file_veh, 52, 52) break case traffic_orange set_vehicle_colours(traffic_file_veh, 88, 88) break case traffic_gun_metal_grey set_vehicle_colours(traffic_file_veh, 1, 1) break case traffic_burgundy set_vehicle_colours(traffic_file_veh, 36, 36) break case traffic_gold set_vehicle_colours(traffic_file_veh, 95, 95) //blue break default set_vehicle_colours(traffic_file_veh, 73, 73) //blue break endswitch ENDPROC /// PURPOSE: /// Call every frame: this stops the uber playback from processing horns and lights. This may be useful if you need to cut down on processor time (these can be costly) /// or if you have your own scripts in place for triggering horns/lights. PROC DONT_PROCESS_UBER_PLAYBACK_HORNS_AND_LIGHTS() bDontProcessTrafficHornsAndLights = TRUE ENDPROC FUNC BOOL is_trailer_touching_entity(VEHICLE_INDEX mission_vehicle) IF allow_trailer_touching_check VEHICLE_INDEX trailer_veh VEHICLE_INDEX players_last_veh MODEL_NAMES truck_model players_last_veh = GET_PLAYERS_LAST_VEHICLE() IF NOT IS_ENTITY_DEAD(players_last_veh) truck_model = GET_ENTITY_MODEL(players_last_veh) IF truck_model = phantom IF IS_VEHICLE_ATTACHED_TO_TRAILER(players_last_veh) IF GET_VEHICLE_TRAILER_VEHICLE(players_last_veh, trailer_veh) IF IS_VEHICLE_DRIVEABLE(trailer_veh) IF IS_ENTITY_TOUCHING_ENTITY(trailer_veh, mission_vehicle) RETURN TRUE ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC PROC UPDATE_TRAFFIC_PLAYBACK(VEHICLE_INDEX TriggerCar, FLOAT fPlaybackSpeed, BOOL bForceCreateCars = FALSE) CONST_INT MAX_NUM_CARS_TO_COLLISION_PROCESS_PER_FRAME 3 CONST_INT MAX_NUM_CARS_TO_CREATION_PROCESS_PER_FRAME 8 INT i, iExitCount, iNumTrafficCarsProcessedThisFrame, iNumTrafficCarsProcessedForCreationThisFrame PED_INDEX temp_char VEHICLE_INDEX vehPlayersCar = NULL VECTOR pos, pos2, vPlayerPos FLOAT fSkipTime, fTemp BOOL bFlag BOOL bPlayerIsAlive = IS_PLAYER_PLAYING(PLAYER_ID()) BOOL bCanCreateRandomDriver = CAN_CREATE_RANDOM_DRIVER() BOOL bCanCreateRandomBikeRider = CAN_CREATE_RANDOM_BIKE_RIDER() UBER_PLAYBACK_PED_MODEL ePedModelToUse //INTERIOR_INSTANCE_INDEX CarInterior IF bPlayerIsAlive IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) vehPlayersCar = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()) ENDIF vPlayerPos = GET_ENTITY_COORDS(PLAYER_PED_ID()) ENDIF iExitCount = 0 #IF IS_DEBUG_BUILD iCarsProcessedThisFrame = 0 IF (iHighlightedTrafficCar > -1) AND (iHighlightedTrafficCar < TOTAL_NUMBER_OF_TRAFFIC_CARS) // remove blip if car doesn't exist IF NOT DOES_ENTITY_EXIST(TrafficCarID[iHighlightedTrafficCar]) IF DOES_BLIP_EXIST(HighlightedTrafficCarBlipID) REMOVE_BLIP(HighlightedTrafficCarBlipID) ENDIF HighlightedTrafficCarID = NULL ENDIF // remove blip if highlighted car is dIFferent from the current one. IF DOES_ENTITY_EXIST(HighlightedTrafficCarID) IF DOES_ENTITY_EXIST(TrafficCarID[iHighlightedTrafficCar]) IF NOT (TrafficCarID[iHighlightedTrafficCar] = HighlightedTrafficCarID) IF DOES_BLIP_EXIST(HighlightedTrafficCarBlipID) REMOVE_BLIP(HighlightedTrafficCarBlipID) ENDIF HighlightedTrafficCarID = NULL ENDIF ENDIF ELSE IF DOES_BLIP_EXIST(HighlightedTrafficCarBlipID) REMOVE_BLIP(HighlightedTrafficCarBlipID) ENDIF ENDIF // add blip IF NOT DOES_ENTITY_EXIST(HighlightedTrafficCarID) IF DOES_ENTITY_EXIST(TrafficCarID[iHighlightedTrafficCar]) IF NOT DOES_BLIP_EXIST(HighlightedTrafficCarBlipID) HighlightedTrafficCarBlipID = ADD_BLIP_FOR_ENTITY(TrafficCarID[iHighlightedTrafficCar]) SET_BLIP_COLOUR(HighlightedTrafficCarBlipID, BLIP_COLOUR_WHITE) HighlightedTrafficCarID = TrafficCarID[iHighlightedTrafficCar] ENDIF ENDIF ENDIF ELSE IF DOES_BLIP_EXIST(HighlightedTrafficCarBlipID) REMOVE_BLIP(HighlightedTrafficCarBlipID) ENDIF ENDIF #ENDIF IF IS_VEHICLE_DRIVEABLE(TriggerCar) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(TriggerCar) fTriggerCarPlaybackTime = GET_TIME_POSITION_IN_RECORDING(TriggerCar) ENDIF // to help save on processing time, skip to the first car that needs processed (when cars are removed from processing this number is increased) INT iFirstCarThatNeedsProcessingThisFrame = -1 BOOL bExitLoop = FALSE BOOL bSwitchToAI = FALSE i = iFirstCarToProcess WHILE i < TOTAL_NUMBER_OF_TRAFFIC_CARS AND NOT bExitLoop //SWITCH TrafficCarProgress[i] //CASE 0 IF TrafficCarProgress[i] != 99 IF TrafficCarProgress[i] = 0 IF TrafficCarRecording[i] > 0 AND TrafficCarModel[i] != DUMMY_MODEL_FOR_SCRIPT IF NOT (bResetPlaybackToTime) IF fTriggerCarPlaybackTime < TrafficCarStartime[i] + 20000.0 IF (fTriggerCarPlaybackTime >= (TrafficCarStartime[i] - (LOAD_AHEAD_TIME * fPlaybackSpeed))) IF IS_VEH_MODEL_A_COP_MODEL(TrafficCarModel[i]) SET_BIT(TrafficCarFlags[i], TRAFFIC_FLAGS_VEH_IS_A_COP) ELIF IS_THIS_MODEL_A_BIKE(TrafficCarModel[i]) SET_BIT(TrafficCarFlags[i], TRAFFIC_FLAGS_VEH_IS_A_BIKE) ENDIF CLEAR_BIT(TrafficCarFlags[i], TRAFFIC_FLAGS_DRIVER_HAS_BEEN_CREATED) iTrafficCarsWaitingToCreate++ TrafficCarProgress[i]++ ELSE IF (iExitCount > 2) bExitLoop = TRUE //Future cars in the array don't require processing yet: quit the loop to save processor time. ELSE iExitCount++ ENDIF ENDIF ELSE #IF IS_DEBUG_BUILD IF (bTrafficDebugOn) PRINTLN("traffic.sch - Removing car: Trigger time is already passed recording point - ", i) ENDIF #ENDIF REMOVE_TRAFFIC_CAR_FROM_PROCESSING(i) ENDIF ELSE // should this traffic car be playing? fSkipTime = fTriggerCarPlaybackTime - TrafficCarStartime[i] IF (fSkipTime >= 0.0) IF (fSkipTime < GET_RECORDING_LENGTH(TrafficCarRecording[i])) IF IS_VEH_MODEL_A_COP_MODEL(TrafficCarModel[i]) SET_BIT(TrafficCarFlags[i], TRAFFIC_FLAGS_VEH_IS_A_COP) ELIF IS_THIS_MODEL_A_BIKE(TrafficCarModel[i]) SET_BIT(TrafficCarFlags[i], TRAFFIC_FLAGS_VEH_IS_A_BIKE) ENDIF CLEAR_BIT(TrafficCarFlags[i], TRAFFIC_FLAGS_DRIVER_HAS_BEEN_CREATED) iTrafficCarsWaitingToCreate++ TrafficCarProgress[i]++ ELSE REMOVE_TRAFFIC_CAR_FROM_PROCESSING(i) ENDIF ENDIF ENDIF ELSE REMOVE_TRAFFIC_CAR_FROM_PROCESSING(i) ENDIF ELIF TrafficCarProgress[i] = 1 REQUEST_VEHICLE_RECORDING(TrafficCarRecording[i], strUberName) bFlag = FALSE IF IS_BIT_SET(TrafficCarFlags[i], TRAFFIC_FLAGS_VEH_IS_A_COP) REQUEST_MODEL(COP_PED_MODEL()) IF HAS_MODEL_LOADED(COP_PED_MODEL()) bFlag = TRUE ENDIF ELSE IF NOT bTrafficForceDefaultPedModel AND ((NOT IS_BIT_SET(TrafficCarFlags[i], TRAFFIC_FLAGS_VEH_IS_A_BIKE) AND bCanCreateRandomDriver) OR (IS_BIT_SET(TrafficCarFlags[i], TRAFFIC_FLAGS_VEH_IS_A_BIKE) AND bCanCreateRandomBikeRider)) bFlag = TRUE ELSE REQUEST_MODEL(DEFAULT_PED_MODEL()) bFlag = HAS_MODEL_LOADED(DEFAULT_PED_MODEL()) ENDIF ENDIF //Create the car if safe to do so. IF NOT DOES_ENTITY_EXIST(TrafficCarID[i]) REQUEST_MODEL(TrafficCarModel[i]) IF HAS_MODEL_LOADED(TrafficCarModel[i]) AND HAS_VEHICLE_RECORDING_BEEN_LOADED(TrafficCarRecording[i], strUberName) AND bFlag IF (fTriggerCarPlaybackTime >= (TrafficCarStartime[i] - (fUberMinTimeBeforePlaybackStartToCreate * fPlaybackSpeed))) IF bCreateAllWaitingCars OR bForceCreateCars OR (NOT bCreatedUberPlaybackEntityThisFrame AND NOT private_IS_POINT_VISIBLE_TO_PLAYER_POS(TrafficCarPos[i], vPlayerPos, 5.0, fUberPlaybackMinCreationDistance)) //Create the car if the creation point isn't visible/obstructed or IF it's being forced to create. IF (bCarsAreOn) private_SAFE_CLEAR_AREA_OF_VEHICLES(TrafficCarPos[i], vPlayerPos, fClearSurroundingCarsDistance) ENDIF TrafficCarID[i] = CREATE_VEHICLE(TrafficCarModel[i], TrafficCarPos[i], DEFAULT, FALSE, FALSE) IF TrafficCarModel[i] = POLMAV SET_VEHICLE_LIVERY(TrafficCarID[i], 0) ENDIF IF block_vehicle_colour AND NOT IS_BIT_SET(TrafficCarFlags[i], TRAFFIC_FLAGS_VEH_IS_A_COP) traffic_block_vehicle_colour_from_generating(TrafficCarID[i]) ENDIF #IF IS_DEBUG_BUILD TEXT_LABEL_63 debugCarName = "Traffic " debugCarName += i SET_VEHICLE_NAME_DEBUG(TrafficCarID[i], debugCarName) #ENDIF SET_ENTITY_COORDS_NO_OFFSET(TrafficCarID[i], TrafficCarPos[i]) SET_ENTITY_QUATERNION(TrafficCarID[i], TrafficCarQuatX[i], TrafficCarQuatY[i], TrafficCarQuatZ[i], TrafficCarQuatW[i]) IF IS_THIS_MODEL_A_CAR(TrafficCarModel[i]) OR IS_THIS_MODEL_A_BIKE(TrafficCarModel[i]) SET_VEHICLE_ON_GROUND_PROPERLY(TrafficCarID[i]) ENDIF IF IS_BIT_SET(TrafficCarFlags[i], TRAFFIC_FLAGS_FREEZE_CAR_FOR_COLLISION) SET_ENTITY_SHOULD_FREEZE_WAITING_ON_COLLISION(TrafficCarID[i], TRUE) ENDIF IF NOT IS_BIT_SET(TrafficCarFlags[i], TRAFFIC_FLAGS_VEH_IS_A_COP) SET_VEHICLE_ENGINE_ON(TrafficCarID[i], TRUE, TRUE) IF GET_CLOCK_HOURS() > 19 OR GET_CLOCK_HOURS() < 7 SET_VEHICLE_LIGHTS(TrafficCarID[i], SET_VEHICLE_LIGHTS_ON) ENDIF ENDIF FREEZE_ENTITY_POSITION(TrafficCarID[i], TRUE) SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(TrafficCarID[i], TRUE) SET_MODEL_AS_NO_LONGER_NEEDED(TrafficCarModel[i]) iTrafficCarsWaitingToCreate-- TrafficCarProgress[i]++ bCreatedUberPlaybackEntityThisFrame = TRUE ELSE IF (fTriggerCarPlaybackTime > TrafficCarStartime[i]) #IF IS_DEBUG_BUILD IF (bTrafficDebugOn) PRINTLN("traffic.sch - Traffic Car not created - point was visible to player - i = ", i) ENDIF #ENDIF iTrafficCarsWaitingToCreate-- REMOVE_TRAFFIC_CAR_FROM_PROCESSING(i) ENDIF ENDIF ENDIF ENDIF ENDIF ELIF TrafficCarProgress[i] = 2 bFlag = FALSE IF (iNumTrafficCarsProcessedForCreationThisFrame < MAX_NUM_CARS_TO_CREATION_PROCESS_PER_FRAME AND (i > iLastTrafficCarProcessedForCreation OR iLastTrafficCarProcessedForCreation = 0)) OR bCreateAllWaitingCars OR bForceCreateCars IF NOT IS_BIT_SET(TrafficCarFlags[i], TRAFFIC_FLAGS_DRIVER_HAS_BEEN_CREATED) IF IS_BIT_SET(TrafficCarFlags[i], TRAFFIC_FLAGS_VEH_IS_A_COP) REQUEST_MODEL(COP_PED_MODEL()) bFlag = HAS_MODEL_LOADED(COP_PED_MODEL()) ePedModelToUse = UBER_PLAYBACK_PED_MODEL_COP ELSE IF NOT bTrafficForceDefaultPedModel AND ((NOT IS_BIT_SET(TrafficCarFlags[i], TRAFFIC_FLAGS_VEH_IS_A_BIKE) AND bCanCreateRandomDriver) OR (IS_BIT_SET(TrafficCarFlags[i], TRAFFIC_FLAGS_VEH_IS_A_BIKE) AND bCanCreateRandomBikeRider)) bFlag = TRUE ePedModelToUse = UBER_PLAYBACK_PED_MODEL_AMBIENT ELSE REQUEST_MODEL(DEFAULT_PED_MODEL()) bFlag = HAS_MODEL_LOADED(DEFAULT_PED_MODEL()) ePedModelToUse = UBER_PLAYBACK_PED_MODEL_DEFAULT ENDIF ENDIF //Peds now aren't created until playback starts, as a failsafe also create the ped if the player gets close to the vehicle. IF NOT IS_ENTITY_DEAD(TrafficCarID[i]) IF NOT bCreatedUberPlaybackEntityThisFrame AND IS_VEHICLE_SEAT_FREE(TrafficCarID[i]) IF bFlag IF VDIST2(GET_ENTITY_COORDS(TrafficCarID[i]), vPlayerPos) < 10000.0 OR bForceCreateCars OR bCreateAllWaitingCars #IF IS_DEBUG_BUILD IF (bTrafficDebugOn) PRINTLN("traffic.sch - Traffic ped created early: ", fTriggerCarPlaybackTime, " index = ", i) ENDIF #ENDIF private_CREATE_PED_INSIDE_UBER_PLAYBACK_CAR(TrafficCarID[i], ePedModelToUse) SET_BIT(TrafficCarFlags[i], TRAFFIC_FLAGS_DRIVER_HAS_BEEN_CREATED) ENDIF ENDIF ENDIF ENDIF ENDIF IF IS_VEHICLE_DRIVEABLE(TrafficCarID[i]) REQUEST_VEHICLE_RECORDING(TrafficCarRecording[i], strUberName) IF (fTriggerCarPlaybackTime >= TrafficCarStartime[i]) IF MAX_NUMBER_OF_TRAFFIC_CARS_PLAYING_BACK > iCurrentNumberOfTrafficPlaybacks fSkipTime = fTriggerCarPlaybackTime - TrafficCarStartime[i] // check its not too late IF HAS_VEHICLE_RECORDING_BEEN_LOADED(TrafficCarRecording[i], strUberName) IF fSkipTime < GET_TOTAL_DURATION_OF_VEHICLE_RECORDING(TrafficCarRecording[i],strUberName) // check we're not updating to a position on screen, from an offscreen position pos = GET_ENTITY_COORDS(TrafficCarID[i]) pos2 = GET_POSITION_OF_VEHICLE_RECORDING_AT_TIME(TrafficCarRecording[i], fSkipTime,strUberName) IF NOT private_IS_POINT_VISIBLE_TO_PLAYER_POS(pos, vPlayerPos, 5.0, fUberPlaybackMinCreationDistance) AND private_IS_POINT_VISIBLE_TO_PLAYER_POS(pos2, vPlayerPos, 5.0, fUberPlaybackMinCreationDistance) #IF IS_DEBUG_BUILD IF (bTrafficDebugOn) PRINTLN("traffic.sch - Traffic car failed to start: start pos is visible car = ", i) ENDIF #ENDIF IF NOT IS_BIT_SET(TrafficCarFlags[i], TRAFFIC_FLAGS_DRIVER_HAS_BEEN_CREATED) private_CREATE_PED_INSIDE_UBER_PLAYBACK_CAR(TrafficCarID[i], ePedModelToUse) ENDIF REMOVE_TRAFFIC_CAR_FROM_PROCESSING(i) ELSE IF NOT bCreatedUberPlaybackEntityThisFrame OR IS_BIT_SET(TrafficCarFlags[i], TRAFFIC_FLAGS_DRIVER_HAS_BEEN_CREATED) OR bCreateAllWaitingCars OR bForceCreateCars IF SET_CAR_AT_PLAYBACK_POSITION(TrafficCarID[i], TrafficCarRecording[i], fSkipTime, TRUE, FALSE, FALSE, TRUE, allow_veh_to_stop_on_any_veh_impact) IF NOT IS_BIT_SET(TrafficCarFlags[i], TRAFFIC_FLAGS_DRIVER_HAS_BEEN_CREATED) private_CREATE_PED_INSIDE_UBER_PLAYBACK_CAR(TrafficCarID[i], ePedModelToUse) ENDIF SET_ENTITY_COLLISION(TrafficCarID[i], TRUE) SET_PLAYBACK_SPEED(TrafficCarID[i], fPlaybackSpeed) iCurrentNumberOfTrafficPlaybacks++ TrafficCarProgress[i]++ ENDIF ENDIF ENDIF ELSE #IF IS_DEBUG_BUILD IF (bTrafficDebugOn) PRINTLN("traffic.sch - Traffic car removed from processing (check A: already passed the playback end time) car = ", i) ENDIF #ENDIF IF NOT IS_BIT_SET(TrafficCarFlags[i], TRAFFIC_FLAGS_DRIVER_HAS_BEEN_CREATED) private_CREATE_PED_INSIDE_UBER_PLAYBACK_CAR(TrafficCarID[i], ePedModelToUse) ENDIF REMOVE_TRAFFIC_CAR_FROM_PROCESSING(i) ENDIF ELSE IF fSkipTime > GET_TOTAL_DURATION_OF_VEHICLE_RECORDING(TrafficCarRecording[i],strUberName) #IF IS_DEBUG_BUILD IF (bTrafficDebugOn) PRINTLN("traffic.sch - Traffic car removed from processing (check B: recording didn't load in time) car = ", i) ENDIF #ENDIF IF NOT IS_BIT_SET(TrafficCarFlags[i], TRAFFIC_FLAGS_DRIVER_HAS_BEEN_CREATED) private_CREATE_PED_INSIDE_UBER_PLAYBACK_CAR(TrafficCarID[i], ePedModelToUse) ENDIF REMOVE_TRAFFIC_CAR_FROM_PROCESSING(i) ENDIF ENDIF ELSE #IF IS_DEBUG_BUILD IF (bTrafficDebugOn) PRINTLN("traffic.sch - Traffic car removed from processing (check C: reached limit of simultaneous playbacks) car = ", i) ENDIF #ENDIF IF NOT IS_BIT_SET(TrafficCarFlags[i], TRAFFIC_FLAGS_DRIVER_HAS_BEEN_CREATED) private_CREATE_PED_INSIDE_UBER_PLAYBACK_CAR(TrafficCarID[i], ePedModelToUse) ENDIF REMOVE_TRAFFIC_CAR_FROM_PROCESSING(i) ENDIF ELSE IF (bPlayerIsAheadOfChase) AND NOT (bPlayTrafficRecordingEvenIfPlayerIsAheadOfChase) #IF IS_DEBUG_BUILD IF (bTrafficDebugOn) PRINTLN("traffic.sch - Traffic car removed from processing (check D: player ahead of chase, not safe to create) car = ", i) ENDIF #ENDIF IF NOT IS_BIT_SET(TrafficCarFlags[i], TRAFFIC_FLAGS_DRIVER_HAS_BEEN_CREATED) private_CREATE_PED_INSIDE_UBER_PLAYBACK_CAR(TrafficCarID[i], ePedModelToUse) ENDIF REMOVE_TRAFFIC_CAR_FROM_PROCESSING(i) ENDIF ENDIF ELSE #IF IS_DEBUG_BUILD IF (bTrafficDebugOn) PRINTLN("traffic.sch - Traffic car removed from processing (check E: car is undriveable) car = ", i) ENDIF #ENDIF IF NOT IS_BIT_SET(TrafficCarFlags[i], TRAFFIC_FLAGS_DRIVER_HAS_BEEN_CREATED) private_CREATE_PED_INSIDE_UBER_PLAYBACK_CAR(TrafficCarID[i], ePedModelToUse) ENDIF REMOVE_TRAFFIC_CAR_FROM_PROCESSING(i) ENDIF iNumTrafficCarsProcessedForCreationThisFrame++ iLastTrafficCarProcessedForCreation = i ENDIF ELIF TrafficCarProgress[i] = 3 IF IS_VEHICLE_DRIVEABLE(TrafficCarID[i]) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(TrafficCarID[i]) #IF IS_DEBUG_BUILD IF (bShowTrafficCarPaths) DISPLAY_PLAYBACK_RECORDED_VEHICLE(TrafficCarID[i], RDM_WHOLELINE) ELSE DISPLAY_PLAYBACK_RECORDED_VEHICLE(TrafficCarID[i], RDM_NONE) ENDIF #ENDIF temp_char = GET_PED_IN_VEHICLE_SEAT(TrafficCarID[i]) IF NOT IS_PED_INJURED(temp_char) // player his hit traffic? if so switch to ai IF bPlayerIsAlive bSwitchToAI = FALSE //Traffic cars by default are set to switch to AI on player collisions. Do any additional checks here. IF NOT bTrafficDontSwitchToAI IF NOT bSetPieceCarIsRecording AND NOT bPausePlayback AND is_trailer_touching_entity(TrafficCarID[i]) IF iNumTrafficCarsProcessedThisFrame < MAX_NUM_CARS_TO_COLLISION_PROCESS_PER_FRAME AND (i > iLastTrafficCarProcessedForCollisions OR iLastTrafficCarProcessedForCollisions = 0) IF NOT IS_ENTITY_DEAD(vehPlayersCar) bFlag = FALSE IF NOT ARE_CARS_TRAVELLING_IN_SAME_DIRECTION(TrafficCarID[i], vehPlayersCar) OR IS_CAR_IN_FRONT_OF_CAR(vehPlayersCar, TrafficCarID[i]) bSwitchToAI = TRUE ENDIF ENDIF iLastTrafficCarProcessedForCollisions = i iNumTrafficCarsProcessedThisFrame++ ENDIF ELSE IF NOT bTrafficOnlySwitchToAIOnCollision AND NOT IS_BIT_SET(TrafficCarFlags[i], TRAFFIC_FLAGS_DONT_SWITCH_TO_AI_EARLY) AND iNumTrafficCarsProcessedThisFrame < MAX_NUM_CARS_TO_COLLISION_PROCESS_PER_FRAME AND (i > iLastTrafficCarProcessedForCollisions OR iLastTrafficCarProcessedForCollisions = 0) //Switch the car to AI if it's behind the trigger car by a significant amount. VECTOR vTrafficOffsetFromTrigger = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(TriggerCar, GET_ENTITY_COORDS(TrafficCarID[i])) IF vTrafficOffsetFromTrigger.y < 0.0 IF ABSF(vTrafficOffsetFromTrigger.y) > ABSF(vTrafficOffsetFromTrigger.x) bSwitchToAI = TRUE ENDIF ENDIF //Old version /*IF IS_CAR_IN_FRONT_OF_CAR(TriggerCar, TrafficCarID[i]) IF IS_CAR_FURTHER_IN_FRONT_THAN_WIDE(TriggerCar, TrafficCarID[i]) bSwitchToAI = TRUE ENDIF ENDIF*/ iNumTrafficCarsProcessedThisFrame++ iLastTrafficCarProcessedForCollisions = i ENDIF ENDIF ENDIF IF bSwitchToAI CHANGE_PLAYBACK_TO_USE_AI_AND_KEEP_SPEED(TrafficCarID[i]) TrafficCarProgress[i]++ ELSE SET_PLAYBACK_SPEED(TrafficCarID[i], fPlaybackSpeed) ENDIF ENDIF ELSE STOP_PLAYBACK_RECORDED_VEHICLE(TrafficCarID[i]) ENDIF ELSE TrafficCarProgress[i]++ ENDIF ELSE TrafficCarProgress[i]++ ENDIF ELIF TrafficCarProgress[i] = 4 IF IS_VEHICLE_DRIVEABLE(TrafficCarID[i]) IF NOT IS_PLAYBACK_GOING_ON_FOR_VEHICLE(TrafficCarID[i]) TrafficCarProgress[i]++ ELSE temp_char = GET_PED_IN_VEHICLE_SEAT(TrafficCarID[i]) IF NOT IS_PED_INJURED(temp_char) SET_PLAYBACK_SPEED(TrafficCarID[i], fPlaybackSpeed) #IF IS_DEBUG_BUILD IF (bShowTrafficCarPaths) DISPLAY_PLAYBACK_RECORDED_VEHICLE(TrafficCarID[i], RDM_WHOLELINE) ELSE DISPLAY_PLAYBACK_RECORDED_VEHICLE(TrafficCarID[i], RDM_NONE) ENDIF #ENDIF ELSE STOP_PLAYBACK_RECORDED_VEHICLE(TrafficCarID[i]) ENDIF // check if current time is after the finish time IF HAS_VEHICLE_RECORDING_BEEN_LOADED(TrafficCarRecording[i], strUberName) IF (fTriggerCarPlaybackTime > (TrafficCarStartime[i] + GET_TOTAL_DURATION_OF_VEHICLE_RECORDING(TrafficCarRecording[i],strUberName))) STOP_PLAYBACK_RECORDED_VEHICLE(TrafficCarID[i]) ENDIF ELSE STOP_PLAYBACK_RECORDED_VEHICLE(TrafficCarID[i]) ENDIF ENDIF ELSE TrafficCarProgress[i]++ ENDIF ELIF TrafficCarProgress[i] = 5 IF NOT IS_ENTITY_DEAD(TrafficCarID[i]) fTemp = GET_ENTITY_SPEED(TrafficCarID[i]) ENDIF iCurrentNumberOfTrafficPlaybacks-- REMOVE_TRAFFIC_CAR_FROM_PROCESSING(i, fTemp) ENDIF //If this is the first car to still require processing then mark it as the start point for the next frame. IF iFirstCarThatNeedsProcessingThisFrame = -1 iFirstCarThatNeedsProcessingThisFrame = i ENDIF ENDIF //ENDSWITCH #IF IS_DEBUG_BUILD iCarsProcessedThisFrame++ TEXT_LABEL str_index = "" //Draws the array index for each traffic car above it IF bShowTrafficIndices IF DOES_ENTITY_EXIST(TrafficCarID[i]) str_index = i DRAW_DEBUG_TEXT(str_index, GET_ENTITY_COORDS(TrafficCarID[i], FALSE) + <<0.0, 0.0, 2.5>>) ENDIF ENDIF IF bDrawTrafficProgress IF DOES_ENTITY_EXIST(TrafficCarID[i]) str_index = TrafficCarProgress[i] DRAW_DEBUG_TEXT(str_index, GET_ENTITY_COORDS(TrafficCarID[i], FALSE) + <<0.0, 0.0, 2.0>>) ENDIF ENDIF #ENDIF // maximum of 20 cars processed per frame // IF (iCarsProcessedThisFrame >= 20) // bExitLoop = TRUE // ENDIF i++ ENDWHILE IF iFirstCarThatNeedsProcessingThisFrame != -1 iFirstCarToProcess = iFirstCarThatNeedsProcessingThisFrame ENDIF //If we didn't hit enough cars to process this frame then reset the last car counter to start back at the beginning. IF iNumTrafficCarsProcessedThisFrame < MAX_NUM_CARS_TO_COLLISION_PROCESS_PER_FRAME iLastTrafficCarProcessedForCollisions = 0 ENDIF IF iNumTrafficCarsProcessedForCreationThisFrame < MAX_NUM_CARS_TO_CREATION_PROCESS_PER_FRAME iLastTrafficCarProcessedForCreation = 0 ENDIF ELSE MARK_ALL_TRAFFIC_CARS_AS_NO_LONGER_NEEDED() ENDIF ENDPROC PROC UPDATE_SET_PIECE_CARS(VEHICLE_INDEX TriggerCar, FLOAT fPlaybackSpeed, BOOL bForceCreateCars = FALSE) INT i PED_INDEX temp_char VEHICLE_INDEX vehPlayersCar VECTOR pos, pos2, vPlayerPos FLOAT fSkipTime, fTemp BOOL bFlag BOOL bPlayerAlive = IS_PLAYER_PLAYING(PLAYER_ID()) BOOL bCanCreateRandomDriver = CAN_CREATE_RANDOM_DRIVER() BOOL bCanCreateRandomBikeRider = CAN_CREATE_RANDOM_BIKE_RIDER() BOOL bFoundFirstCarToProcess = FALSE UBER_PLAYBACK_PED_MODEL eModelToUse //INTERIOR_INSTANCE_INDEX CarInterior IF bPlayerAlive IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) vehPlayersCar = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()) ENDIF vPlayerPos = GET_ENTITY_COORDS(PLAYER_PED_ID()) ENDIF IF IS_VEHICLE_DRIVEABLE(TriggerCar) i = iFirstSetpieceCarToProcess WHILE i < TOTAL_NUMBER_OF_SET_PIECE_CARS //SWITCH SetPieceCarProgress[i] //CASE 0 IF SetPieceCarProgress[i] != 99 IF SetPieceCarProgress[i] = 0 IF (SetPieceCarRecording[i] > 0) IF NOT (bResetPlaybackToTime) IF (fTriggerCarPlaybackTime > (SetPieceCarStartime[i] - (LOAD_AHEAD_TIME * fPlaybackSpeed))) IF IS_VEH_MODEL_A_COP_MODEL(SetPieceCarModel[i]) SET_BIT(SetPieceCarFlags[i], TRAFFIC_FLAGS_VEH_IS_A_COP) ELIF IS_THIS_MODEL_A_BIKE(SetPieceCarModel[i]) SET_BIT(SetPieceCarFlags[i], TRAFFIC_FLAGS_VEH_IS_A_BIKE) ENDIF CLEAR_BIT(SetPieceCarFlags[i], TRAFFIC_FLAGS_DRIVER_HAS_BEEN_CREATED) SetPieceCarProgress[i]++ iSetPieceCarsWaitingToCreate++ ENDIF ELSE // should this set piece car be playing? fSkipTime = fTriggerCarPlaybackTime - SetPieceCarStartime[i] fSkipTime *= SetPieceCarRecordingSpeed[i] IF (fSkipTime >= 0.0) IF (fSkipTime < GET_RECORDING_LENGTH(SetPieceCarRecording[i])) IF IS_VEH_MODEL_A_COP_MODEL(SetPieceCarModel[i]) SET_BIT(SetPieceCarFlags[i], TRAFFIC_FLAGS_VEH_IS_A_COP) ELIF IS_THIS_MODEL_A_BIKE(SetPieceCarModel[i]) SET_BIT(SetPieceCarFlags[i], TRAFFIC_FLAGS_VEH_IS_A_BIKE) ENDIF CLEAR_BIT(SetPieceCarFlags[i], TRAFFIC_FLAGS_DRIVER_HAS_BEEN_CREATED) SetPieceCarProgress[i]++ iSetPieceCarsWaitingToCreate++ ELSE SetPieceCarProgress[i] = 99 // this playback would have already finished ENDIF ENDIF ENDIF ELSE SetPieceCarProgress[i] = 99 ENDIF ELIF SetPieceCarProgress[i] = 1 bFlag = FALSE REQUEST_VEHICLE_RECORDING(SetPieceCarRecording[i], strUberName) IF IS_BIT_SET(SetPieceCarFlags[i], TRAFFIC_FLAGS_VEH_IS_A_COP) REQUEST_MODEL(COP_PED_MODEL()) bFlag = HAS_MODEL_LOADED(COP_PED_MODEL()) ELSE IF NOT bTrafficForceDefaultPedModel AND ((NOT IS_BIT_SET(SetPieceCarFlags[i], TRAFFIC_FLAGS_VEH_IS_A_BIKE) AND bCanCreateRandomDriver) OR (IS_BIT_SET(SetPieceCarFlags[i], TRAFFIC_FLAGS_VEH_IS_A_BIKE) AND bCanCreateRandomBikeRider)) bFlag = TRUE ELSE REQUEST_MODEL(DEFAULT_PED_MODEL()) bFlag = HAS_MODEL_LOADED(DEFAULT_PED_MODEL()) ENDIF ENDIF //Create the car if safe to do so. IF bFlag IF NOT DOES_ENTITY_EXIST(SetPieceCarID[i]) REQUEST_MODEL(SetPieceCarModel[i]) IF HAS_MODEL_LOADED(SetPieceCarModel[i]) AND HAS_VEHICLE_RECORDING_BEEN_LOADED(SetPieceCarRecording[i], strUberName) IF (fTriggerCarPlaybackTime >= (SetPieceCarStartime[i] - (fUberMinTimeBeforePlaybackStartToCreate * fPlaybackSpeed))) IF bCreateAllWaitingCars OR bForceCreateCars OR (NOT bCreatedUberPlaybackEntityThisFrame AND NOT private_IS_POINT_VISIBLE_TO_PLAYER_POS(SetPieceCarPos[i], vPlayerPos, 5.0, fUberPlaybackMinCreationDistance)) //Create the car if the creation point isn't visible/obstructed or IF it's being forced to create. IF (bCarsAreOn) private_SAFE_CLEAR_AREA_OF_VEHICLES(SetPieceCarPos[i], vPlayerPos, fClearSurroundingCarsDistance) ENDIF SetPieceCarID[i] = CREATE_VEHICLE(SetPieceCarModel[i], SetPieceCarPos[i], DEFAULT, FALSE, FALSE) IF SetPieceCarModel[i] = POLMAV SET_VEHICLE_LIVERY(SetPieceCarID[i], 0) ENDIF IF block_vehicle_colour AND NOT IS_BIT_SET(SetPieceCarFlags[i], TRAFFIC_FLAGS_VEH_IS_A_COP) traffic_block_vehicle_colour_from_generating(SetPieceCarID[i]) ENDIF IF IS_BIT_SET(SetPieceCarFlags[i], TRAFFIC_FLAGS_FREEZE_CAR_FOR_COLLISION) SET_ENTITY_SHOULD_FREEZE_WAITING_ON_COLLISION(SetPieceCarID[i], TRUE) ENDIF #IF IS_DEBUG_BUILD TEXT_LABEL_63 debugCarName = "SetPiece " debugCarName += i SET_VEHICLE_NAME_DEBUG(SetPieceCarID[i], debugCarName) #ENDIF SET_ENTITY_COORDS_NO_OFFSET(SetPieceCarID[i], SetPieceCarPos[i]) SET_ENTITY_QUATERNION(SetPieceCarID[i], SetPieceCarQuatX[i], SetPieceCarQuatY[i], SetPieceCarQuatZ[i], SetPieceCarQuatW[i]) IF IS_THIS_MODEL_A_CAR(SetPieceCarModel[i]) OR IS_THIS_MODEL_A_BIKE(SetPieceCarModel[i]) SET_VEHICLE_ON_GROUND_PROPERLY(SetPieceCarID[i]) ENDIF IF NOT IS_BIT_SET(SetPieceCarFlags[i], TRAFFIC_FLAGS_VEH_IS_A_COP) SET_VEHICLE_ENGINE_ON(SetPieceCarID[i], TRUE, TRUE) IF GET_CLOCK_HOURS() > 19 OR GET_CLOCK_HOURS() < 7 SET_VEHICLE_LIGHTS(SetPieceCarID[i], SET_VEHICLE_LIGHTS_ON) ENDIF ENDIF FREEZE_ENTITY_POSITION(SetPieceCarID[i], TRUE) SET_MODEL_AS_NO_LONGER_NEEDED(SetPieceCarModel[i]) iSetpieceCarsWaitingToCreate-- SetPieceCarProgress[i]++ bCreatedUberPlaybackEntityThisFrame = TRUE ENDIF ENDIF ENDIF ELSE //The vehicle already exists. IF NOT IS_ENTITY_DEAD(SetPieceCarID[i]) AND IS_VEHICLE_DRIVEABLE(SetPieceCarID[i]) #IF IS_DEBUG_BUILD TEXT_LABEL_63 debugCarName = "SetPiece " debugCarName += i SET_VEHICLE_NAME_DEBUG(SetPieceCarID[i], debugCarName) #ENDIF SET_ENTITY_COORDS_NO_OFFSET(SetPieceCarID[i], SetPieceCarPos[i]) SET_ENTITY_QUATERNION(SetPieceCarID[i], SetPieceCarQuatX[i], SetPieceCarQuatY[i], SetPieceCarQuatZ[i], SetPieceCarQuatW[i]) IF IS_THIS_MODEL_A_CAR(SetPieceCarModel[i]) OR IS_THIS_MODEL_A_BIKE(SetPieceCarModel[i]) SET_VEHICLE_ON_GROUND_PROPERLY(SetPieceCarID[i]) ENDIF FREEZE_ENTITY_POSITION(SetPieceCarID[i], TRUE) SET_MODEL_AS_NO_LONGER_NEEDED(SetPieceCarModel[i]) iSetpieceCarsWaitingToCreate-- SetPieceCarProgress[i]++ ENDIF ENDIF ENDIF ELIF SetPieceCarProgress[i] = 2 REQUEST_VEHICLE_RECORDING(SetPieceCarRecording[i], strUberName) IF NOT IS_BIT_SET(SetPieceCarFlags[i], TRAFFIC_FLAGS_DRIVER_HAS_BEEN_CREATED) bFlag = FALSE IF IS_BIT_SET(SetPieceCarFlags[i], TRAFFIC_FLAGS_VEH_IS_A_COP) REQUEST_MODEL(COP_PED_MODEL()) bFlag = HAS_MODEL_LOADED(COP_PED_MODEL()) eModelToUse = UBER_PLAYBACK_PED_MODEL_COP ELSE IF NOT bTrafficForceDefaultPedModel AND ((NOT IS_BIT_SET(SetPieceCarFlags[i], TRAFFIC_FLAGS_VEH_IS_A_BIKE) AND bCanCreateRandomDriver) OR (IS_BIT_SET(SetPieceCarFlags[i], TRAFFIC_FLAGS_VEH_IS_A_BIKE) AND bCanCreateRandomBikeRider)) bFlag = TRUE eModelToUse = UBER_PLAYBACK_PED_MODEL_AMBIENT ELSE REQUEST_MODEL(DEFAULT_PED_MODEL()) bFlag = HAS_MODEL_LOADED(DEFAULT_PED_MODEL()) eModelToUse = UBER_PLAYBACK_PED_MODEL_DEFAULT ENDIF ENDIF //Peds now aren't created until playback starts, as a failsafe also create the ped if the player gets close to the vehicle. IF NOT IS_ENTITY_DEAD(SetPieceCarID[i]) IF NOT bCreatedUberPlaybackEntityThisFrame AND IS_VEHICLE_SEAT_FREE(SetPieceCarID[i]) IF bFlag IF VDIST2(GET_ENTITY_COORDS(SetPieceCarID[i]), vPlayerPos) < 10000.0 OR bForceCreateCars OR bCreateAllWaitingCars private_CREATE_PED_INSIDE_UBER_PLAYBACK_CAR(SetPieceCarID[i], eModelToUse, TRUE) SET_BIT(SetPieceCarFlags[i], TRAFFIC_FLAGS_DRIVER_HAS_BEEN_CREATED) ENDIF ENDIF ENDIF ENDIF ENDIF IF IS_VEHICLE_DRIVEABLE(SetPieceCarID[i]) IF (fTriggerCarPlaybackTime >= SetPieceCarStartime[i]) IF MAX_NUMBER_OF_SET_PIECE_CARS_PLAYING_BACK > iCurrentNumberOfSetPieceCarPlaybacks // work out skip time fSkipTime = fTriggerCarPlaybackTime - SetPieceCarStartime[i] fSkipTime *= SetPieceCarRecordingSpeed[i] // check its not too late IF HAS_VEHICLE_RECORDING_BEEN_LOADED(SetPieceCarRecording[i], strUberName) IF fSkipTime < GET_TOTAL_DURATION_OF_VEHICLE_RECORDING(SetPieceCarRecording[i],strUberName) // check we're not updating to a position on screen, from an offscreen position pos = GET_ENTITY_COORDS(SetPieceCarID[i]) pos2 = GET_POSITION_OF_VEHICLE_RECORDING_AT_TIME(SetPieceCarRecording[i], fSkipTime,strUberName) IF NOT private_IS_POINT_VISIBLE_TO_PLAYER_POS(pos, vPlayerPos, 5.0, fUberPlaybackMinCreationDistance) AND private_IS_POINT_VISIBLE_TO_PLAYER_POS(pos2, vPlayerPos, 5.0, fUberPlaybackMinCreationDistance) AND NOT (bCreateAllWaitingCars) AND NOT bForceCreateCars #IF IS_DEBUG_BUILD IF (bTrafficDebugOn) PRINTLN("traffic.sch - Couldn't start set-piece playback ", i, ": point is visible.") ENDIF #ENDIF IF NOT IS_BIT_SET(SetPieceCarFlags[i], TRAFFIC_FLAGS_DRIVER_HAS_BEEN_CREATED) private_CREATE_PED_INSIDE_UBER_PLAYBACK_CAR(SetPieceCarID[i], eModelToUse, TRUE) ENDIF iCurrentNumberOfSetPieceCarPlaybacks++ // increment this regardless SetPieceCarProgress[i]++ ELSE IF NOT bCreatedUberPlaybackEntityThisFrame OR IS_BIT_SET(SetPieceCarFlags[i], TRAFFIC_FLAGS_DRIVER_HAS_BEEN_CREATED) OR bCreateAllWaitingCars OR bForceCreateCars IF SET_CAR_AT_PLAYBACK_POSITION(SetPieceCarID[i], SetPieceCarRecording[i], fSkipTime, TRUE, FALSE, FALSE, allow_veh_to_stop_on_PLAYER_impact, allow_veh_to_stop_on_any_veh_impact) SET_PLAYBACK_SPEED(SetPieceCarID[i], (fPlaybackSpeed * SetPieceCarRecordingSpeed[i])) //SET_ENTITY_COLLISION(SetPieceCarID[i], TRUE) #IF IS_DEBUG_BUILD IF (bTrafficDebugOn) PRINTLN("traffic.sch - Set-piece playback started ", i) ENDIF #ENDIF IF IS_VEHICLE_DRIVEABLE(SetPieceCarID[i]) IF IS_BIT_SET(SetPieceCarFlags[i], TRAFFIC_FLAGS_VEH_IS_A_COP) SET_VEHICLE_ENGINE_ON(SetPieceCarID[i], TRUE, TRUE) SET_VEHICLE_SIREN(SetPieceCarID[i], TRUE) SET_VEHICLE_LIGHTS(SetPieceCarID[i], FORCE_VEHICLE_LIGHTS_ON) IF NOT IS_THIS_MODEL_A_BIKE(SetPieceCarModel[i]) SET_SIREN_WITH_NO_DRIVER(SetPieceCarID[i], TRUE) ENDIF ENDIF ENDIF #IF IS_DEBUG_BUILD IF (bShowSetPiecePaths) DISPLAY_PLAYBACK_RECORDED_VEHICLE(SetPieceCarID[i], RDM_WHOLELINE) ELSE DISPLAY_PLAYBACK_RECORDED_VEHICLE(SetPieceCarID[i], RDM_NONE) ENDIF #ENDIF // IS_DEBUG_BUILD IF NOT IS_BIT_SET(SetPieceCarFlags[i], TRAFFIC_FLAGS_DRIVER_HAS_BEEN_CREATED) private_CREATE_PED_INSIDE_UBER_PLAYBACK_CAR(SetPieceCarID[i], eModelToUse, TRUE) ENDIF iCurrentNumberOfSetPieceCarPlaybacks++ SetPieceCarProgress[i]++ ENDIF ENDIF ENDIF ELSE #IF IS_DEBUG_BUILD IF (bTrafficDebugOn) PRINTLN("traffic.sch - Couldn't start set-piece playback ", i, ": chase already passed the start time.") ENDIF #ENDIF IF NOT IS_BIT_SET(SetPieceCarFlags[i], TRAFFIC_FLAGS_DRIVER_HAS_BEEN_CREATED) private_CREATE_PED_INSIDE_UBER_PLAYBACK_CAR(SetPieceCarID[i], eModelToUse, TRUE) ENDIF iCurrentNumberOfSetPieceCarPlaybacks++ // increment this regardless SetPieceCarProgress[i]++ ENDIF ENDIF ELSE #IF IS_DEBUG_BUILD IF (bTrafficDebugOn) PRINTLN("traffic.sch - Couldn't start set-piece playback ", i, ": too many set-piece cars playing at once.") ENDIF #ENDIF IF NOT IS_BIT_SET(SetPieceCarFlags[i], TRAFFIC_FLAGS_DRIVER_HAS_BEEN_CREATED) private_CREATE_PED_INSIDE_UBER_PLAYBACK_CAR(SetPieceCarID[i], eModelToUse, TRUE) ENDIF iCurrentNumberOfSetPieceCarPlaybacks++ // increment this regardless SetPieceCarProgress[i]++ ENDIF ENDIF ELSE #IF IS_DEBUG_BUILD IF (bTrafficDebugOn) PRINTLN("traffic.sch - Couldn't start set-piece playback ", i, ": vehicle is not driveable.") ENDIF #ENDIF IF NOT IS_BIT_SET(SetPieceCarFlags[i], TRAFFIC_FLAGS_DRIVER_HAS_BEEN_CREATED) private_CREATE_PED_INSIDE_UBER_PLAYBACK_CAR(SetPieceCarID[i], eModelToUse, TRUE) ENDIF iCurrentNumberOfSetPieceCarPlaybacks++ // increment this regardless SetPieceCarProgress[i]++ ENDIF ELIF SetPieceCarProgress[i] = 3 IF IS_VEHICLE_DRIVEABLE(SetPieceCarID[i]) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(SetPieceCarID[i]) #IF IS_DEBUG_BUILD IF (bShowSetPiecePaths) DISPLAY_PLAYBACK_RECORDED_VEHICLE(SetPieceCarID[i], RDM_WHOLELINE) ELSE DISPLAY_PLAYBACK_RECORDED_VEHICLE(SetPieceCarID[i], RDM_NONE) ENDIF #ENDIF temp_char = GET_PED_IN_VEHICLE_SEAT(SetPieceCarID[i]) IF NOT IS_PED_INJURED(temp_char) #IF IS_DEBUG_BUILD IF (bDrawSpeedVector) DRAW_CAR_SPEED_VECTOR(SetPieceCarID[i]) ENDIF #ENDIF // switch to ai? IF bPlayerAlive IF NOT bSetPieceCarIsRecording AND NOT bPausePlayback AND NOT bSetPieceCarsDontSwitchToAI AND ((NOT allow_veh_to_stop_on_PLAYER_impact AND NOT allow_veh_to_stop_on_any_veh_impact AND IS_ENTITY_TOUCHING_ENTITY(PLAYER_PED_ID(), SetPieceCarID[i])) OR is_trailer_touching_entity(SetPieceCarID[i])) //Old stuff for switching cars to AI. IF DOES_ENTITY_EXIST(vehPlayersCar) bFlag = FALSE IF switch_SetPieceCar_to_ai_on_collision #IF IS_DEBUG_BUILD IF (bTrafficDebugOn) PRINTLN("traffic.sch - Set Piece Car ", i, " switch_SetPieceCar_to_ai_on_collision = TRUE - switching to ai") ENDIF #ENDIF bFlag = TRUE ELSE fTemp = GET_ENTITY_SPEED(vehPlayersCar) IF fTemp < 1.0 #IF IS_DEBUG_BUILD IF (bTrafficDebugOn) PRINTLN("traffic.sch - Set Piece Car ", i, " hit players stationary car - switching to ai") ENDIF #ENDIF bFlag = TRUE ELIF ABSF(fTemp - GET_ENTITY_SPEED(SetPieceCarID[i])) > 15.0 #IF IS_DEBUG_BUILD IF (bTrafficDebugOn) PRINTLN("traffic.sch - Set Piece Car ", i, " and players car hit with different speeds - switching to ai") ENDIF #ENDIF bFlag = TRUE ELIF NOT ARE_CARS_TRAVELLING_IN_SAME_DIRECTION_BELOW_ANGLE(SetPieceCarID[i], vehPlayersCar, 45.0) #IF IS_DEBUG_BUILD IF (bTrafficDebugOn) PRINTLN("traffic.sch - Set Piece Car ", i, " is not travelling in same direction - switching to ai") ENDIF #ENDIF bFlag = TRUE ELIF IS_CAR_IN_FRONT_OF_CAR(vehPlayersCar, SetPieceCarID[i]) #IF IS_DEBUG_BUILD IF (bTrafficDebugOn) PRINTLN("traffic.sch - Set Piece Car ", i, " is behind player - switching to ai") ENDIF #ENDIF bFlag = TRUE ENDIF ENDIF IF (bFlag) CHANGE_PLAYBACK_TO_USE_AI_AND_KEEP_SPEED(SetPieceCarID[i]) SetPieceCarProgress[i]++ ENDIF ENDIF ELSE SET_PLAYBACK_SPEED(SetPieceCarID[i], (fPlaybackSpeed * SetPieceCarRecordingSpeed[i])) ENDIF ENDIF ELSE #IF IS_DEBUG_BUILD IF (bTrafficDebugOn) IF DOES_ENTITY_EXIST(temp_char) PRINTLN("traffic.sch - Set Piece Car ", i, " driver does not exist") ELSE PRINTLN("traffic.sch - Set Piece Car ", i, " driver is injured.") ENDIF ENDIF #ENDIF STOP_PLAYBACK_RECORDED_VEHICLE(SetPieceCarID[i]) ENDIF ELSE #IF IS_DEBUG_BUILD IF (bTrafficDebugOn) PRINTLN("traffic.sch - Set Piece Car ", i, " playback already stopped.") ENDIF #ENDIF SetPieceCarProgress[i]++ ENDIF ELSE #IF IS_DEBUG_BUILD IF (bTrafficDebugOn) PRINTLN("traffic.sch - Set Piece Car ", i, " vehicle is not driveable") ENDIF #ENDIF SetPieceCarProgress[i]++ ENDIF ELIF SetPieceCarProgress[i] = 4 IF IS_VEHICLE_DRIVEABLE(SetPieceCarID[i]) IF NOT IS_PLAYBACK_GOING_ON_FOR_VEHICLE(SetPieceCarID[i]) SetPieceCarProgress[i]++ ELSE temp_char = GET_PED_IN_VEHICLE_SEAT(SetPieceCarID[i]) IF NOT IS_PED_INJURED(temp_char) SET_PLAYBACK_SPEED(SetPieceCarID[i], (fPlaybackSpeed * SetPieceCarRecordingSpeed[i])) #IF IS_DEBUG_BUILD IF (bShowSetPiecePaths) DISPLAY_PLAYBACK_RECORDED_VEHICLE(SetPieceCarID[i], RDM_WHOLELINE) ELSE DISPLAY_PLAYBACK_RECORDED_VEHICLE(SetPieceCarID[i], RDM_NONE) ENDIF #ENDIF // IS_DEBUG_BUILD ELSE STOP_PLAYBACK_RECORDED_VEHICLE(SetPieceCarID[i]) ENDIF // check if current time is after the finish time IF HAS_VEHICLE_RECORDING_BEEN_LOADED(SetPieceCarRecording[i], strUberName) IF (fTriggerCarPlaybackTime > (SetPieceCarStartime[i] + GET_TOTAL_DURATION_OF_VEHICLE_RECORDING(SetPieceCarRecording[i],strUberName))) STOP_PLAYBACK_RECORDED_VEHICLE(SetPieceCarID[i]) ENDIF ELSE STOP_PLAYBACK_RECORDED_VEHICLE(SetPieceCarID[i]) ENDIF ENDIF ELSE SetPieceCarProgress[i]++ ENDIF ELIF SetPieceCarProgress[i] = 5 IF NOT (SetPieceCarID[i] = DontRemoveThisCar) // set the cruise speed. IF IS_VEHICLE_DRIVEABLE(SetPieceCarID[i]) temp_char = GET_PED_IN_VEHICLE_SEAT(SetPieceCarID[i]) IF NOT IS_PED_INJURED(temp_char) SCRIPTTASKSTATUS TempTaskStatus TempTaskStatus = GET_SCRIPT_TASK_STATUS(temp_char, SCRIPT_TASK_PERFORM_SEQUENCE) IF (TempTaskStatus = FINISHED_TASK) fTemp = GET_ENTITY_SPEED(SetPieceCarID[i]) IF (fTemp < MIN_CAR_CRUISE_SPEED) fTemp = MIN_CAR_CRUISE_SPEED ENDIF IF (fTemp > MAX_CAR_CRUISE_SPEED) fTemp = MAX_CAR_CRUISE_SPEED ENDIF SET_DRIVE_TASK_CRUISE_SPEED(temp_char, fTemp) ENDIF ENDIF ENDIF //Remove the vehicle recording #IF IS_DEBUG_BUILD IF NOT bStartSetPieceReRec IF i <> iSetPieceReRecNum IF NOT bSetPieceRecordingsAreActive AND NOT bTrafficDontCleanupRecordingFiles IF SetPieceCarRecording[i] > 0 REMOVE_VEHICLE_RECORDING(SetPieceCarRecording[i], strUberName) ENDIF ENDIF ENDIF ENDIF #ENDIF #IF IS_FINAL_BUILD IF NOT bSetPieceRecordingsAreActive AND NOT bTrafficDontCleanupRecordingFiles IF SetPieceCarRecording[i] > 0 REMOVE_VEHICLE_RECORDING(SetPieceCarRecording[i], strUberName) ENDIF ENDIF #ENDIF IF NOT (bDeleteCarsWhenDone) IF NOT bDontCleanUpUberCarsForTrailer #IF IS_DEBUG_BUILD IF NOT bStartSetPieceReRec IF i <> iSetPieceReRecNum //-- Added by Dave W //-- If running debug mode, only clean up setpiece car rec if set piece re-recording isn't takeing place //-- This is because the collision on the set-piece vehicle gets turned on when it gets cleaned up //-- which can mess up the re-recording. MARK_CAR_AS_NO_LONGER_NEEDED_KEEP_ID(SetPieceCarID[i]) ENDIF ENDIF #ENDIF #IF IS_FINAL_BUILD MARK_CAR_AS_NO_LONGER_NEEDED_KEEP_ID(SetPieceCarID[i]) #ENDIF ENDIF ELSE IF DOES_ENTITY_EXIST(SetPieceCarID[i]) DELETE_VEHICLE(SetPieceCarID[i]) ENDIF ENDIF ENDIF iCurrentNumberOfSetPieceCarPlaybacks-- SetPieceCarProgress[i] = 99 ENDIF //If this is the first car we've reached that hasn't been removed from processing, mark it as the start point for the next frame. IF NOT bFoundFirstCarToProcess iFirstSetPieceCarToProcess = i bFoundFirstCarToProcess = TRUE ENDIF ENDIF //ENDSWITCH #IF IS_DEBUG_BUILD TEXT_LABEL str_index = "" //Draws the array index for each traffic car above it IF bShowSetPieceIndices IF DOES_ENTITY_EXIST(SetPieceCarID[i]) str_index = i DRAW_DEBUG_TEXT(str_index, GET_ENTITY_COORDS(SetPieceCarID[i], FALSE) + <<0.0, 0.0, 2.5>>) ENDIF ENDIF IF bDrawSetpieceProgress IF DOES_ENTITY_EXIST(SetPieceCarID[i]) str_index = SetPieceCarProgress[i] DRAW_DEBUG_TEXT(str_index, GET_ENTITY_COORDS(SetPieceCarID[i], FALSE) + <<0.0, 0.0, 2.0>>) ENDIF ENDIF #ENDIF i++ ENDWHILE ELSE MARK_ALL_SET_PIECE_CARS_AS_NO_LONGER_NEEDED() ENDIF ENDPROC PROC deactivate_SetPieceCars_up_to_time(INT deactivate_time) INT i = 0 FOR i = 0 to TOTAL_NUMBER_OF_SET_PIECE_CARS - 1 IF SetPieceCarStartime[i] < deactivate_time SetPieceCarProgress[i] = 99 ENDIF ENDFOR ENDPROC #IF IS_DEBUG_BUILD PROC INIT_UBER_RECORDING(STRING strNameOfUber) MARK_ALL_TRAFFIC_CARS_AS_NO_LONGER_NEEDED() MARK_ALL_PARKED_CARS_AS_NO_LONGER_NEEDED() MARK_ALL_SET_PIECE_CARS_AS_NO_LONGER_NEEDED() SET_WANTED_LEVEL_MULTIPLIER(0.0) SET_WEATHER_TYPE_NOW_PERSIST("EXTRASUNNY") //ALLOW_EMERGENCY_SERVICES(FALSE) IF IS_PLAYER_PLAYING(PLAYER_ID()) CLEAR_PLAYER_WANTED_LEVEL(PLAYER_ID()) SET_DISPATCH_COPS_FOR_PLAYER(PLAYER_ID(), FALSE) SET_CREATE_RANDOM_COPS(FALSE) ENDIF ADD_RELATIONSHIP_GROUP("rgh_traffic", rgh_traffic) strUberName = strNameOfUber SWITCH_ALL_RANDOM_CARS_ON() ENDPROC #ENDIF #IF IS_DEBUG_BUILD PROC UPDATE_UBER_RECORDING() IF bDrawSpeedVector OR bShowSetPieceIndices OR bShowSetPiecePaths OR bShowRecordingCone OR bShowSetPieceReRecPath OR bShowTrafficIndices OR bShowTrafficCarPaths OR bShowTriggerCarPath OR bDrawTrafficProgress OR bDrawSetpieceProgress SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(TRUE) ENDIF SET_PED_DENSITY_MULTIPLIER_THIS_FRAME(0.0) UPDATE_TRAFFIC_RECORDING() ENDPROC #ENDIF PROC INITIALISE_UBER_PLAYBACK(STRING strNameOfUber, INT iTriggerCarNumber, BOOL bClearCars = TRUE, BOOL bDisableShops = TRUE) VECTOR pos strUberName = strNameOfUber // set any initial flags bCarsAreOn = TRUE bRefreshAllCarsAfterSkippingCalled = FALSE iCurrentNumberOfTrafficPlaybacks = 0 iCurrentNumberOfSetPieceCarPlaybacks = 0 iCurrentNumberOfParkedCars = 0 iTriggerCarRecordingNumber = iTriggerCarNumber iFirstCarToProcess = 0 iFirstParkedCarToProcess = 0 iFirstSetpieceCarToProcess = 0 //iParkedCarsProcessedThisFrame = 0 iSwitchRoadsIndex = 0 iSwitchRoadsOnIndex = 0 iDontSwitchThisSetpieceRecordingToAI = -1 iDontSwitchThisSetpieceRecordingToAI2 = -1 iLastTrafficCarProcessedForCollisions = 0 iLastTrafficCarProcessedForCreation = 0 fTimeRoadsWereLastSwitchedOff = 0.0 fTimeRoadsWereLastSwitchedOn = 0.0 #IF IS_DEBUG_BUILD iCurrentNumberOfTrafficRecordings = 0 iTotalNumberOfParkedCarsRecorded = 0 iTotalNumberOfTrafficCarsRecorded = 0 iSetPieceCarRecordingFile = 0 iCarsProcessedThisFrame = 0 iMainCarRecordingFile = 0 iInitialRecordingFileNumber = 1 #ENDIF fTriggerCarPlaybackTime = 0.0 bCalculatePlaybackSpeedInitialised = FALSE IF IS_PLAYER_PLAYING(PLAYER_ID()) pos = GET_ENTITY_COORDS(PLAYER_PED_ID()) vRoadsOffAtStartMin.x = pos.x - 100.0 vRoadsOffAtStartMin.y = pos.y - 100.0 vRoadsOffAtStartMin.z = pos.z - 100.0 vRoadsOffAtStartMax.x = pos.x + 100.0 vRoadsOffAtStartMax.y = pos.y + 100.0 vRoadsOffAtStartMax.z = pos.z + 100.0 SET_ROADS_IN_AREA(vRoadsOffAtStartMin, vRoadsOffAtStartMax, FALSE, FALSE) IF (bClearCars) CLEAR_AREA_OF_VEHICLES(pos, 500.0) ENDIF ENDIF ADD_RELATIONSHIP_GROUP("rgh_traffic", rgh_traffic) SWITCH_ALL_RANDOM_CARS_OFF() #IF IS_DEBUG_BUILD bAllRandomCarsAreSwitchedOn = FALSE #ENDIF IF bDisableShops SET_ALL_SHOPS_TEMPORARILY_UNAVAILABLE(TRUE) ENDIF IF IS_PLAYER_PLAYING(PLAYER_ID()) SET_DISPATCH_COPS_FOR_PLAYER(PLAYER_ID(), FALSE) SET_CREATE_RANDOM_COPS(FALSE) ENDIF FLUSH_ALL_TRAFFIC_DATA() ENDPROC PROC SWITCH_ALL_ROADS_BACK_TO_ORIGINAL() SET_ROADS_BACK_TO_ORIGINAL(vRoadSwitchedOffMin, vRoadSwitchedOffMax) SET_ROADS_BACK_TO_ORIGINAL(vRoadsOffAtStartMin, vRoadsOffAtStartMax) ENDPROC /// PURPOSE: /// Cleans up all cars for the uber chase and resets ambient traffic. /// NOTE: This command does nothing if uber playback was not initialised previously. PROC CLEANUP_UBER_PLAYBACK(BOOL bDeleteAllCars = FALSE, BOOL bTurnShopsBackOn = TRUE) IF NOT IS_STRING_NULL_OR_EMPTY(strUberName) bCalculatePlaybackSpeedInitialised = FALSE SWITCH_ALL_RANDOM_CARS_ON() #IF IS_DEBUG_BUILD bAllRandomCarsAreSwitchedOn = TRUE #ENDIF REMOVE_RELATIONSHIP_GROUP(rgh_traffic) //SWITCH_ALL_ROADS_BACK_TO_ORIGINAL() SET_ROADS_BACK_TO_ORIGINAL(<<-9999.0, -9999.0, -9999.0>>, <<9999.0, 9999.0, 9999.0>>) IF IS_PLAYER_PLAYING(PLAYER_ID()) SET_AIR_DRAG_MULTIPLIER_FOR_PLAYERS_VEHICLE(PLAYER_ID(), 1.0) SET_DISPATCH_COPS_FOR_PLAYER(PLAYER_ID(), TRUE) SET_CREATE_RANDOM_COPS(TRUE) ENDIF IF bUberPlaybackRemoveDefaultPedModel SET_MODEL_AS_NO_LONGER_NEEDED(DEFAULT_PED_MODEL()) ENDIF SET_MODEL_AS_NO_LONGER_NEEDED(DEFAULT_CAR_MODEL()) SET_MODEL_AS_NO_LONGER_NEEDED(COP_CAR_MODEL()) SET_MODEL_AS_NO_LONGER_NEEDED(COP_PED_MODEL()) IF NOT IS_SCREEN_FADED_OUT() AND NOT (bDeleteAllCars) MARK_ALL_TRAFFIC_CARS_AS_NO_LONGER_NEEDED() MARK_ALL_PARKED_CARS_AS_NO_LONGER_NEEDED() MARK_ALL_SET_PIECE_CARS_AS_NO_LONGER_NEEDED() ELSE DELETE_ALL_CARS_IN_UBER_PLAYBACK() FLUSH_ALL_TRAFFIC_DATA() ENDIF CDEBUG1LN(DEBUG_MISSION, "[traffic.sch] - CLEANUP_UBER_PLAYBACK called.") IF bTurnShopsBackOn SET_ALL_SHOPS_TEMPORARILY_UNAVAILABLE(FALSE) ENDIF ENDIF ENDPROC /// PURPOSE: /// New procedure for turning off roads during playback: one part switches off roads at two second intervals in front of the chase, one part switches /// them back on after the chase has passed. PROC private_SWITCH_ROADS_OFF_DURING_PLAYBACK(VEHICLE_INDEX vehTrigger, FLOAT fTime) IF NOT IS_ENTITY_DEAD(vehTrigger) AND IS_PLAYBACK_GOING_ON_FOR_VEHICLE(vehTrigger) RECORDING_ID recID FLOAT fNextSwitchOffTime = fTimeRoadsWereLastSwitchedOff + 2000.0 FLOAT fNextSwitchOnTime = fTimeRoadsWereLastSwitchedOn + 2000.0 FLOAT fTemp BOOL bJustSwitchedRoadsOff = FALSE //Switch roads off: go up to 25 seconds ahead of the current playback time. IF fNextSwitchOffTime < fTime + 25000.0 recID = GET_CURRENT_PLAYBACK_FOR_VEHICLE(vehTrigger) IF fNextSwitchOffTime <= GET_TOTAL_DURATION_OF_VEHICLE_RECORDING_ID(recID) IF iSwitchRoadsIndex = 0 vSwitchRoadsTempMin = GET_POSITION_OF_VEHICLE_RECORDING_ID_AT_TIME(recID, fTimeRoadsWereLastSwitchedOff) iSwitchRoadsIndex++ ELIF iSwitchRoadsIndex = 1 vSwitchRoadsTempMax = GET_POSITION_OF_VEHICLE_RECORDING_ID_AT_TIME(recID, fNextSwitchOffTime) iSwitchRoadsIndex++ ELSE IF NOT bCreatedUberPlaybackEntityThisFrame IF vSwitchRoadsTempMin.x > vSwitchRoadsTempMax.x fTemp = vSwitchRoadsTempMin.x vSwitchRoadsTempMin.x = vSwitchRoadsTempMax.x vSwitchRoadsTempMax.x = fTemp ENDIF IF vSwitchRoadsTempMin.y > vSwitchRoadsTempMax.y fTemp = vSwitchRoadsTempMin.y vSwitchRoadsTempMin.y = vSwitchRoadsTempMax.y vSwitchRoadsTempMax.y = fTemp ENDIF IF vSwitchRoadsTempMin.z > vSwitchRoadsTempMax.z fTemp = vSwitchRoadsTempMin.z vSwitchRoadsTempMin.z = vSwitchRoadsTempMax.z vSwitchRoadsTempMax.z = fTemp ENDIF vSwitchRoadsTempMin -= <> vSwitchRoadsTempMax += <> SET_ROADS_IN_AREA(vSwitchRoadsTempMin, vSwitchRoadsTempMax, FALSE, FALSE) fTimeRoadsWereLastSwitchedOff = fNextSwitchOffTime iSwitchRoadsIndex = 0 #IF IS_DEBUG_BUILD IF bTrafficDebugOn PRINTLN("traffic.sch - Switching off roads ", vSwitchRoadsTempMin, " ", vSwitchRoadsTempMax, " ", fNextSwitchOffTime) ENDIF #ENDIF ENDIF ENDIF ENDIF ENDIF //Switch roads on: wait a few seconds after the current chase time. IF fNextSwitchOnTime < fTime - 8000.0 recID = GET_CURRENT_PLAYBACK_FOR_VEHICLE(vehTrigger) IF iSwitchRoadsOnIndex = 0 vSwitchRoadsOnMin = GET_POSITION_OF_VEHICLE_RECORDING_ID_AT_TIME(recID, fTimeRoadsWereLastSwitchedOn) iSwitchRoadsOnIndex++ ELIF iSwitchRoadsOnIndex = 1 vSwitchRoadsOnMax = GET_POSITION_OF_VEHICLE_RECORDING_ID_AT_TIME(recID, fNextSwitchOnTime) iSwitchRoadsOnIndex++ ELSE IF NOT bCreatedUberPlaybackEntityThisFrame AND NOT bJustSwitchedRoadsOff IF vSwitchRoadsOnMin.x > vSwitchRoadsOnMax.x fTemp = vSwitchRoadsOnMin.x vSwitchRoadsOnMin.x = vSwitchRoadsOnMax.x vSwitchRoadsOnMax.x = fTemp ENDIF IF vSwitchRoadsOnMin.y > vSwitchRoadsOnMax.y fTemp = vSwitchRoadsOnMin.y vSwitchRoadsOnMin.y = vSwitchRoadsOnMax.y vSwitchRoadsOnMax.y = fTemp ENDIF IF vSwitchRoadsOnMin.z > vSwitchRoadsOnMax.z fTemp = vSwitchRoadsOnMin.z vSwitchRoadsOnMin.z = vSwitchRoadsOnMax.z vSwitchRoadsOnMax.z = fTemp ENDIF vSwitchRoadsOnMin -= <> vSwitchRoadsOnMax += <> SET_ROADS_BACK_TO_ORIGINAL(vSwitchRoadsOnMin, vSwitchRoadsOnMax) fTimeRoadsWereLastSwitchedOn = fNextSwitchOnTime #IF IS_DEBUG_BUILD IF bTrafficDebugOn PRINTLN("traffic.sch - Switching on roads ", vSwitchRoadsOnMin, " ", vSwitchRoadsOnMax, " ", fNextSwitchOnTime) ENDIF #ENDIF iSwitchRoadsOnIndex = 0 ENDIF ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: /// Private function for switching off roads around the uber chase route. /// NOTE: new version of this PROC for bug 299051. Uses much less CPU time. PROC SWITCH_ROADS_OFF_IN_PLAYBACK(VEHICLE_INDEX TriggerCar, FLOAT fTime) RECORDING_ID recID VECTOR pos IF iSwitchRoadsIndex < 15 IF iSwitchRoadsIndex = 0 vSwitchRoadsTempMin = <<99999.9, 99999.9, 99999.9>> vSwitchRoadsTempMax = <<-99999.9, -99999.9, -99999.9>> ENDIF IF IS_VEHICLE_DRIVEABLE(TriggerCar) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(TriggerCar) recID = GET_CURRENT_PLAYBACK_FOR_VEHICLE(TriggerCar) pos = GET_POSITION_OF_VEHICLE_RECORDING_ID_AT_TIME(recID, fTime + (TO_FLOAT(iSwitchRoadsIndex - 1) * 2000)) // update current min, max values IF (pos.x < vSwitchRoadsTempMin.x) vSwitchRoadsTempMin.x = pos.x ENDIF IF (pos.y < vSwitchRoadsTempMin.y) vSwitchRoadsTempMin.y = pos.y ENDIF IF (pos.z < vSwitchRoadsTempMin.z) vSwitchRoadsTempMin.z = pos.z ENDIF IF (pos.x > vSwitchRoadsTempMax.x) vSwitchRoadsTempMax.x = pos.x ENDIF IF (pos.y > vSwitchRoadsTempMax.y) vSwitchRoadsTempMax.y = pos.y ENDIF IF (pos.z > vSwitchRoadsTempMax.z) vSwitchRoadsTempMax.z = pos.z ENDIF ENDIF ENDIF iSwitchRoadsIndex++ ELSE IF NOT bCreatedUberPlaybackEntityThisFrame //Split this call from the next one, as it causes a large peak in usage. SET_ROADS_BACK_TO_ORIGINAL(<<-9999.9, -9999.9, -9999.9>>, <<9999.9, 9999.9, 9999.9>>) // add on safety vSwitchRoadsTempMin += << (fSwitchOffRoadDist * -1.0), (fSwitchOffRoadDist * -1.0), (fSwitchOffRoadDist * -1.0)>> vSwitchRoadsTempMax += << fSwitchOffRoadDist, fSwitchOffRoadDist, fSwitchOffRoadDist>> vRoadSwitchedOffMin = vSwitchRoadsTempMin vRoadSwitchedOffMax = vSwitchRoadsTempMax SET_ROADS_IN_AREA(vRoadSwitchedOffMin, vRoadSwitchedOffMax, FALSE, FALSE) iSwitchRoadsIndex = 0 // LINE(vRoadSwitchedOffMin.x, vRoadSwitchedOffMin.y, vRoadSwitchedOffMin.z, vRoadSwitchedOffMax.x, vRoadSwitchedOffMin.y, vRoadSwitchedOffMin.z) // LINE(vRoadSwitchedOffMin.x, vRoadSwitchedOffMin.y, vRoadSwitchedOffMin.z, vRoadSwitchedOffMin.x, vRoadSwitchedOffMax.y, vRoadSwitchedOffMin.z) // LINE(vRoadSwitchedOffMax.x, vRoadSwitchedOffMax.y, vRoadSwitchedOffMin.z, vRoadSwitchedOffMax.x, vRoadSwitchedOffMin.y, vRoadSwitchedOffMin.z) // LINE(vRoadSwitchedOffMax.x, vRoadSwitchedOffMax.y, vRoadSwitchedOffMin.z, vRoadSwitchedOffMin.x, vRoadSwitchedOffMax.y, vRoadSwitchedOffMin.z) // // LINE(vRoadSwitchedOffMin.x, vRoadSwitchedOffMin.y, vRoadSwitchedOffMax.z, vRoadSwitchedOffMax.x, vRoadSwitchedOffMin.y, vRoadSwitchedOffMax.z) // LINE(vRoadSwitchedOffMin.x, vRoadSwitchedOffMin.y, vRoadSwitchedOffMax.z, vRoadSwitchedOffMin.x, vRoadSwitchedOffMax.y, vRoadSwitchedOffMax.z) // LINE(vRoadSwitchedOffMax.x, vRoadSwitchedOffMax.y, vRoadSwitchedOffMax.z, vRoadSwitchedOffMax.x, vRoadSwitchedOffMin.y, vRoadSwitchedOffMax.z) // LINE(vRoadSwitchedOffMax.x, vRoadSwitchedOffMax.y, vRoadSwitchedOffMax.z, vRoadSwitchedOffMin.x, vRoadSwitchedOffMax.y, vRoadSwitchedOffMax.z) // // LINE(vRoadSwitchedOffMin.x, vRoadSwitchedOffMin.y, vRoadSwitchedOffMin.z, vRoadSwitchedOffMin.x, vRoadSwitchedOffMin.y, vRoadSwitchedOffMax.z) // LINE(vRoadSwitchedOffMin.x, vRoadSwitchedOffMax.y, vRoadSwitchedOffMin.z, vRoadSwitchedOffMin.x, vRoadSwitchedOffMax.y, vRoadSwitchedOffMax.z) // LINE(vRoadSwitchedOffMax.x, vRoadSwitchedOffMin.y, vRoadSwitchedOffMin.z, vRoadSwitchedOffMax.x, vRoadSwitchedOffMin.y, vRoadSwitchedOffMax.z) // LINE(vRoadSwitchedOffMax.x, vRoadSwitchedOffMax.y, vRoadSwitchedOffMin.z, vRoadSwitchedOffMax.x, vRoadSwitchedOffMax.y, vRoadSwitchedOffMax.z) // // PRINTSTRING("vRoadSwitchedOffMin = ") // PRINTFLOAT(vRoadSwitchedOffMin.x) // PRINTSTRING(", ") // PRINTFLOAT(vRoadSwitchedOffMin.y) // PRINTSTRING(", ") // PRINTFLOAT(vRoadSwitchedOffMin.z) // PRINTSTRING(", vRoadSwitchedOffMax = ") // PRINTFLOAT(vRoadSwitchedOffMax.x) // PRINTSTRING(", ") // PRINTFLOAT(vRoadSwitchedOffMax.y) // PRINTSTRING(", ") // PRINTFLOAT(vRoadSwitchedOffMax.z) // PRINTSTRING("\n ") ENDIF ENDIF ENDPROC PROC SAFE_CLEAR_AREA_OF_CARS_IN_PLAYBACK(VEHICLE_INDEX TriggerCar, FLOAT fTime, FLOAT fRadius) RECORDING_ID recID VECTOR pos, pos2, vec, vPlayerPos FLOAT fTemp IF IS_PLAYER_PLAYING(PLAYER_ID()) vPlayerPos = GET_ENTITY_COORDS(PLAYER_PED_ID()) ENDIF IF IS_VEHICLE_DRIVEABLE(TriggerCar) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(TriggerCar) recID = GET_CURRENT_PLAYBACK_FOR_VEHICLE(TriggerCar) pos = GET_POSITION_OF_VEHICLE_RECORDING_ID_AT_TIME(recID, fTime) pos2 = GET_ENTITY_COORDS(TriggerCar) // make sure we don't clear the area behind the trigger car vec = pos2 - pos fTemp = VMAG(vec) IF (fTemp > fRadius) fTemp = fRadius ENDIF private_SAFE_CLEAR_AREA_OF_VEHICLES(pos, vPlayerPos, fTemp) ENDIF ENDIF ENDPROC FUNC BOOL HAS_UBER_PLAYBACK_BEEN_SKIPPED_TO_PLAYBACK_TIME(VEHICLE_INDEX &TriggerCar, FLOAT finResetTime) IF NOT (bRefreshAllCarsAfterSkippingCalled) bResetPlaybackToTime = TRUE DELETE_ALL_CARS_IN_UBER_PLAYBACK() IF IS_VEHICLE_DRIVEABLE(TriggerCar) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(TriggerCar) STOP_PLAYBACK_RECORDED_VEHICLE(TriggerCar) SET_VEHICLE_FIXED(TriggerCar) ENDIF IF NOT (iTriggerCarRecordingNumber = -1) WHILE NOT SET_CAR_AT_PLAYBACK_POSITION(TriggerCar, iTriggerCarRecordingNumber, finResetTime, TRUE, FALSE) WAIT(0) ENDWHILE IF NOT (bReRecordingIsEnabled) bPausePlayback = TRUE fPausePlaybackTime = 0.0 iFirstCarToProcess = 0 iFirstSetpieceCarToProcess = 0 iFirstParkedCarToProcess = 0 iCurrentNumberOfTrafficPlaybacks = 0 iCurrentNumberOfSetPieceCarPlaybacks = 0 iCurrentNumberOfParkedCars = 0 iParkedCarsWaitingToCreate = 0 iSetPieceCarsWaitingToCreate = 0 iTrafficCarsWaitingToCreate = 0 ENDIF ENDIF ENDIF bRefreshAllCarsAfterSkippingCalled = TRUE ELSE IF IS_VEHICLE_DRIVEABLE(TriggerCar) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(TriggerCar) SET_PLAYBACK_SPEED(TriggerCar, (1.0 * fMasterPlaybackSpeed * fPausePlaybackTime)) SET_CAR_AT_PLAYBACK_POSITION(TriggerCar, iTriggerCarRecordingNumber, finResetTime, TRUE, FALSE) ENDIF ENDIF fTriggerCarPlaybackTime = finResetTime //Reset the road switching variables iSwitchRoadsIndex = 0 iSwitchRoadsOnIndex = 0 fTimeRoadsWereLastSwitchedOn = 0.0 fTimeRoadsWereLastSwitchedOff = 0.0 UPDATE_SET_PIECE_CARS(TriggerCar, (1.0 * fMasterPlaybackSpeed * fPausePlaybackTime), TRUE) UPDATE_TRAFFIC_PLAYBACK(TriggerCar, (1.0 * fMasterPlaybackSpeed * fPausePlaybackTime), TRUE) UPDATE_PARKED_CARS(TriggerCar) IF (iParkedCarsWaitingToCreate = 0) AND (iSetPieceCarsWaitingToCreate = 0) AND (iTrafficCarsWaitingToCreate = 0) bPausePlayback = FALSE bResetPlaybackToTime = FALSE bRefreshAllCarsAfterSkippingCalled = FALSE RETURN(TRUE) ENDIF ENDIF RETURN(FALSE) ENDFUNC PROC SET_UBER_PLAYBACK_TO_TIME_NOW(VEHICLE_INDEX TriggerCar, FLOAT finResetTime) INT i FLOAT fSkipTime BOOL bDelete IF IS_VEHICLE_DRIVEABLE(TriggerCar) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(TriggerCar) CREATE_ALL_WAITING_UBER_CARS() // set main car back SET_CAR_AT_PLAYBACK_POSITION(TriggerCar, iTriggerCarRecordingNumber, finResetTime, TRUE, FALSE, TRUE) fTriggerCarPlaybackTime = finResetTime // set any set pieces that are currently playing back to the reset time REPEAT TOTAL_NUMBER_OF_SET_PIECE_CARS i IF (SetPieceCarProgress[i] > 2) AND (SetPieceCarProgress[i] < 6) bDelete = FALSE IF DOES_ENTITY_EXIST(SetPieceCarID[i]) IF NOT IS_ENTITY_DEAD(SetPieceCarID[i]) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(SetPieceCarID[i]) fSkipTime = finResetTime - SetPieceCarStartime[i] fSkipTime *= SetPieceCarRecordingSpeed[i] IF (fSkipTime >= 0.0) IF (fSkipTime < GET_RECORDING_LENGTH(SetPieceCarRecording[i])) SET_CAR_AT_PLAYBACK_POSITION(SetPieceCarID[i], SetPieceCarRecording[i], fSkipTime, TRUE, FALSE, TRUE, allow_veh_to_stop_on_PLAYER_impact, allow_veh_to_stop_on_any_veh_impact) ELSE bDelete = TRUE ENDIF ELSE bDelete = TRUE ENDIF ELSE bDelete = TRUE ENDIF ELSE bDelete = TRUE ENDIF ELSE bDelete = TRUE ENDIF IF (bDelete) SetPieceCarProgress[i] = 99 iCurrentNumberOfSetPieceCarPlaybacks-- ENDIF ENDIF ENDREPEAT // set any traffic cars that are currently playing back to the reset time REPEAT TOTAL_NUMBER_OF_TRAFFIC_CARS i IF (TrafficCarProgress[i] > 2) AND (TrafficCarProgress[i] < 6) bDelete = FALSE IF DOES_ENTITY_EXIST(TrafficCarID[i]) IF NOT IS_ENTITY_DEAD(TrafficCarID[i]) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(TrafficCarID[i]) fSkipTime = finResetTime - TrafficCarStartime[i] IF (fSkipTime >= 0.0) IF (fSkipTime < GET_RECORDING_LENGTH(TrafficCarRecording[i])) SET_CAR_AT_PLAYBACK_POSITION(TrafficCarID[i], TrafficCarRecording[i], fSkipTime, TRUE, FALSE, TRUE, TRUE, allow_veh_to_stop_on_any_veh_impact) ELSE bDelete = TRUE ENDIF ELSE bDelete = TRUE ENDIF ELSE bDelete = TRUE ENDIF ELSE bDelete = TRUE ENDIF ELSE bDelete = TRUE ENDIF IF (bDelete) TrafficCarProgress[i] = 99 iCurrentNumberOfTrafficPlaybacks-- ENDIF ENDIF ENDREPEAT // reset first traffic car to process iFirstCarToProcess = 0 iFirstSetpieceCarToProcess = 0 // recreate any parked cars REPEAT TOTAL_NUMBER_OF_PARKED_CARS i IF (ParkedCarProgress[i] > 2) IF DOES_ENTITY_EXIST(ParkedCarID[i]) IF NOT IS_ENTITY_DEAD(ParkedCarID[i]) SET_ENTITY_AS_MISSION_ENTITY(ParkedCarID[i]) iCurrentNumberOfParkedCars++ ParkedCarProgress[i] = 2 ENDIF ELSE ParkedCarProgress[i] = 0 ENDIF ENDIF ENDREPEAT iFirstParkedCarToProcess = 0 //Set the road switching variables to start from the new time iSwitchRoadsIndex = 0 iSwitchRoadsOnIndex = 0 fTimeRoadsWereLastSwitchedOn = finResetTime fTimeRoadsWereLastSwitchedOff = finResetTime VECTOR vTriggerPos = GET_ENTITY_COORDS(TriggerCar) vRoadsOffAtStartMin = vTriggerPos - <<100.0, 100.0, 100.0>> vRoadsOffAtStartMax = vTriggerPos + <<100.0, 100.0, 100.0>> SET_ROADS_IN_AREA(vRoadsOffAtStartMin, vRoadsOffAtStartMax, FALSE, FALSE) ENDIF ENDIF ENDPROC PROC UPDATE_UBER_PLAYBACK(VEHICLE_INDEX TriggerCar, FLOAT fPlaybackSpeed) //PRINTSTRING("update uber playback called! \n") #IF IS_DEBUG_BUILD PED_INDEX temp_char IF bDrawSpeedVector OR bShowSetPieceIndices OR bShowSetPiecePaths OR bShowRecordingCone OR bShowSetPieceReRecPath OR bShowTrafficIndices OR bShowTrafficCarPaths OR bShowTriggerCarPath OR bDrawTrafficProgress OR bDrawSetpieceProgress SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(TRUE) ENDIF #ENDIF FLOAT fTemp VECTOR pos // VECTOR pos2, vec BOOL bFlag fTemp = GET_FRAME_TIME() // update timers fTemp *= 1000.0 #IF IS_DEBUG_BUILD CREATE_TRAFFIC_WIDGET() // for outputing to the widget fInputPlaybackSpeed = fPlaybackSpeed #ENDIF //Output current vehicle as a parked car to temp_debug #IF IS_DEBUG_BUILD IF bOutputParkedCarInfo IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) VEHICLE_INDEX veh = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()) OUTPUT_PARKED_CAR_DATA(veh) ENDIF bOutputParkedCarInfo = FALSE ENDIF #ENDIF bCreatedUberPlaybackEntityThisFrame = FALSE // environment setting for doing set piece recordings IF NOT (bSetPieceRecordingsHaveBeenActivated) IF (bSetPieceRecordingsAreActive) SWITCH_ALL_RANDOM_CARS_OFF() #IF IS_DEBUG_BUILD bAllRandomCarsAreSwitchedOn = FALSE #ENDIF IF IS_PLAYER_PLAYING(PLAYER_ID()) pos = GET_ENTITY_COORDS(PLAYER_PED_ID()) CLEAR_AREA(pos, 1000.0, TRUE) ENDIF bSetPieceRecordingsHaveBeenActivated = TRUE ENDIF ELSE IF NOT (bSetPieceRecordingsAreActive) SWITCH_ALL_RANDOM_CARS_ON() #IF IS_DEBUG_BUILD bAllRandomCarsAreSwitchedOn = TRUE #ENDIF bSetPieceRecordingsHaveBeenActivated = FALSE ENDIF ENDIF IF (bSetPieceRecordingsAreActive) fPlaybackSpeed = 1.0 SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME(0.0) ENDIF IF NOT (bReRecordingControlHijacked) // PAUSE AND UNPAUSE THE UBER PLAYBACK IF (bPausePlayback) fPausePlaybackTime = 0.0 ELSE fPausePlaybackTime = 1.0 ENDIF // UPDATE TRIGGER CAR PLAYBACK IF IS_VEHICLE_DRIVEABLE(TriggerCar) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(TriggerCar) // check if player is ahead of trigger car IF IS_PLAYER_PLAYING(PLAYER_ID()) IF IS_PED_IN_FRONT_OF_CAR(PLAYER_PED_ID(), TriggerCar) bPlayerIsAheadOfChase = TRUE ELSE bPlayerIsAheadOfChase = FALSE ENDIF ENDIF fTriggerCarPlaybackTime = GET_TIME_POSITION_IN_RECORDING(TriggerCar) SET_PLAYBACK_SPEED(TriggerCar, (fPlaybackSpeed * fMasterPlaybackSpeed * fPausePlaybackTime)) #IF IS_DEBUG_BUILD IF (bShowTriggerCarPath) DISPLAY_PLAYBACK_RECORDED_VEHICLE(TriggerCar, RDM_WHOLELINE) ELSE DISPLAY_PLAYBACK_RECORDED_VEHICLE(TriggerCar, RDM_NONE) ENDIF #ENDIF // IS_DEBUG_BUILD IF (bCarsAreOn) // switch roads off up ahead //SWITCH_ROADS_OFF_IN_PLAYBACK(TriggerCar, fTriggerCarPlaybackTime) private_SWITCH_ROADS_OFF_DURING_PLAYBACK(TriggerCar, fTriggerCarPlaybackTime) UPDATE_CAR_DENSITY_BASED_ON_PLAYERS_DISTANCE_FROM_CAR(TriggerCar, fUberPlaybackDensitySwitchOffRange) // clear the next few seconds of random traffic (only do every second) IF (fClearCarTimer > 1000.0) IF iUberClearCarsIndex = 0 UPDATE_CAR_POPULATION_BUDGET_BASED_ON_PLAYERS_DISTANCE_FROM_CAR(TriggerCar, fUberPlaybackDensitySwitchOffRange) ENDIF fTemp = fTriggerCarPlaybackTime + 4000.0 + (TO_FLOAT(iUberClearCarsIndex) * 2000.0) SAFE_CLEAR_AREA_OF_CARS_IN_PLAYBACK(TriggerCar, fTemp, fClearSurroundingCarsDistance) iUberClearCarsIndex++ IF iUberClearCarsIndex > 2 fClearCarTimer = 0.0 ENDIF ELSE iUberClearCarsIndex = 0 fClearCarTimer += (GET_FRAME_TIME() * 1000.0) ENDIF ENDIF ENDIF ENDIF // only call the update functions if... bFlag = FALSE IF IS_VEHICLE_DRIVEABLE(TriggerCar) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(TriggerCar) bFlag = TRUE ENDIF ENDIF IF (fTriggerCarPlaybackTime = 0) OR IS_SCREEN_FADED_OUT() bFlag = TRUE ENDIF IF (bFlag) AND NOT (bDontUpdateUberCars) // TRAFFIC IF NOT (bResetPlaybackToTime) UPDATE_TRAFFIC_PLAYBACK(TriggerCar, (fPlaybackSpeed * fMasterPlaybackSpeed * fPausePlaybackTime)) IF NOT bDontProcessTrafficHornsAndLights //NOTE: This variable is obsolete but still being used in some missions for V, should be removed in a future project. ENDIF bDontProcessTrafficHornsAndLights = FALSE //Ensure command is called every frame ENDIF // PARKED CARS IF (bShowParkedCars) UPDATE_PARKED_CARS(TriggerCar) ENDIF // SET PIECE CARS IF NOT (bResetPlaybackToTime) UPDATE_SET_PIECE_CARS(TriggerCar, (fPlaybackSpeed * fMasterPlaybackSpeed * fPausePlaybackTime)) ENDIF ENDIF // START RECORDING A NEW SET PIECE CAR #IF IS_DEBUG_BUILD // if set piece has been reset, then make sure the current recording stops. IF (bResetSetPiece) CDEBUG1LN(DEBUG_MISSION, "[traffic.sch] - Stopped set-piece recording, set-piece has been reset.") bStartRecordingSetPieceCar = FALSE ENDIF IF (bStartRecordingSetPieceCar) IF (bPausePlayback) bPausePlayback = FALSE ENDIF IF NOT (bSetPieceCarIsRecording) IF IS_PLAYER_PLAYING(PLAYER_ID()) IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) MainRecordingCar = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()) IF NOT IS_ENTITY_DEAD(MainRecordingCar) CDEBUG1LN(DEBUG_MISSION, "[traffic.sch] - Set-piece recording started.") // PRINT_NOW("STARTED", 5000, 1) PRINT_NOW("CRECSTART5", 5000, 1) START_RECORDING_SET_PIECE_CAR(MainRecordingCar, TriggerCar, bAllowSetPieceRecOverwrite) bSetPieceCarIsRecording = TRUE ELSE CDEBUG1LN(DEBUG_MISSION, "[traffic.sch] - Stopped set-piece recording, current vehicle is dead.") bStartRecordingSetPieceCar = FALSE ENDIF ELSE CDEBUG1LN(DEBUG_MISSION, "[traffic.sch] - Stopped set-piece recording, player is not in a vehicle.") bStartRecordingSetPieceCar = FALSE ENDIF ELSE CDEBUG1LN(DEBUG_MISSION, "[traffic.sch] - Stopped set-piece recording, player is not playing.") bStartRecordingSetPieceCar = FALSE ENDIF ELSE // check if got out car IF IS_PLAYER_PLAYING(PLAYER_ID()) IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) MainRecordingCar = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()) IF IS_ENTITY_DEAD(MainRecordingCar) CDEBUG1LN(DEBUG_MISSION, "[traffic.sch] - Stopped set-piece recording, current vehicle is dead.") bStartRecordingSetPieceCar = FALSE ENDIF ELSE CDEBUG1LN(DEBUG_MISSION, "[traffic.sch] - Stopped set-piece recording, player is not in a vehicle.") bStartRecordingSetPieceCar = FALSE ENDIF ELSE CDEBUG1LN(DEBUG_MISSION, "[traffic.sch] - Stopped set-piece recording, player is not playing.") bStartRecordingSetPieceCar = FALSE ENDIF ENDIF bSetPieceRecordingsAreActive = TRUE ELSE IF (bSetPieceCarIsRecording) IF IS_VEHICLE_DRIVEABLE(MainRecordingCar) IF IS_RECORDING_GOING_ON_FOR_VEHICLE(MainRecordingCar) STOP_RECORDING_VEHICLE(MainRecordingCar) PRINT_NOW("CRECSTOP5", 5000, 1) // PRINT_NOW("STOPPED", 5000, 1) ENDIF ENDIF bPausePlayback = TRUE fPausePlaybackTime = 0.0 bSetPieceCarIsRecording = FALSE bStartRecordingSetPieceCar = FALSE ENDIF ENDIF #ENDIF // REGRAB THE SETPIECE CARS START POSITION AND COORDS IF (bReGrabSetPiecePositionAndQuat) IF IS_PLAYER_PLAYING(PLAYER_ID()) IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) MainRecordingCar = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()) RecordedSetPieceCarPos = GET_ENTITY_COORDS(MainRecordingCar) GET_ENTITY_QUATERNION(MainRecordingCar, fSetPieceQuatX, fSetPieceQuatY, fSetPieceQuatZ, fSetPieceQuatW) ENDIF ENDIF bReGrabSetPiecePositionAndQuat = FALSE ENDIF // RERECORDING - If switched on #IF IS_DEBUG_BUILD IF (bEnableReRecording) IF NOT (bReRecordingIsEnabled) IF IS_VEHICLE_DRIVEABLE(TriggerCar) temp_char = GET_PED_IN_VEHICLE_SEAT(TriggerCar) IF NOT (temp_char = PLAYER_PED_ID()) DELETE_PED(temp_char) ENDIF IF IS_PLAYER_PLAYING(PLAYER_ID()) IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), TriggerCar) CLEAR_PED_TASKS_IMMEDIATELY(PLAYER_PED_ID()) SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), TriggerCar) //SET_GAMEPLAY_CAM_RELATIVE_HEADING(GET_ENTITY_HEADING(PLAYER_PED_ID())) ENDIF ENDIF ENDIF fResetTime = 0.0 bResetPlaybackToTime = TRUE bReRecordingIsEnabled = TRUE bStartRecordingPlayersCarWithTraffic = TRUE ENDIF ENDIF #ENDIF // RESET THE SET PEICE CAR IF (bResetSetPiece) IF DOES_ENTITY_EXIST(MainRecordingCar) MARK_CAR_AS_NO_LONGER_NEEDED_KEEP_ID(SetPieceRecordingCar) SetPieceRecordingCar = MainRecordingCar ENDIF IF IS_VEHICLE_DRIVEABLE(SetPieceRecordingCar) SET_ENTITY_COORDS(SetPieceRecordingCar, RecordedSetPieceCarPos) SET_ENTITY_QUATERNION(SetPieceRecordingCar, fSetPieceQuatX, fSetPieceQuatY, fSetPieceQuatZ, fSetPieceQuatW) ENDIF fResetTime = fNewSetPieceTriggerTime bResetPlaybackToTime = TRUE bResetSetPiece = FALSE ENDIF #IF IS_DEBUG_BUILD //-- Set-piece re-recording controls - Added by Dave W PED_INDEX pedTemp IF bReRecSetPieceDataLoaded //-- Get in here if bLoadSetPieceDataForReRec has been set //-- Start re-record. IF bStartSetPieceReRec IF NOT IS_ENTITY_DEAD(SetPieceCarID[iSetPieceReRecNum]) IF NOT IS_ENTITY_DEAD(vehForSetPieceReRec) IF fPausePlaybackTime = 1.0 //-- Requeired to get old/new recordings to sync. IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(vehForSetPieceReRec) UNPAUSE_PLAYBACK_RECORDED_VEHICLE(vehForSetPieceReRec) ENDIF ENDIF bAllowSetPieceRecOverwrite = TRUE bStartRecordingSetPieceCar = TRUE bDeleteCarsWhenDone = FALSE ENDIF ENDIF ELSE bStartRecordingSetPieceCar = FALSE ENDIF //-- Start re-record if R2 is pressed IF bStartReRecOnButtonPress IF NOT IS_ENTITY_DEAD(vehForSetPieceReRec) IF IS_BUTTON_PRESSED(PAD1, RIGHTSHOULDER2) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(vehForSetPieceReRec) STOP_PLAYBACK_RECORDED_vehicle(vehForSetPieceReRec) ENDIF bStartSetPieceReRec = TRUE ENDIF ENDIF ENDIF //--Stop recording if square is pressed IF bStopSetPieceReRecOnButtonPress IF NOT IS_ENTITY_DEAD(vehForSetPieceReRec) IF IS_CONTROL_PRESSED(player_control, input_jump) bStartSetPieceReRec = FALSE bStartRecordingSetPieceCar = FALSE ENDIF ENDIF ENDIF IF NOT IS_ENTITY_DEAD(SetPieceCarID[iSetPieceReRecNum]) //--Show ghost car SET_ENTITY_VISIBLE(SetPieceCarID[iSetPieceReRecNum], bShowSetPieceReRecGhost) pedTemp = GET_PED_IN_VEHICLE_SEAT(SetPieceCarID[iSetPieceReRecNum]) IF pedTemp <> NULL SET_ENTITY_VISIBLE(pedTemp, bShowSetPieceReRecGhost) ENDIF //--Show car rec route IF IS_PLAYBACK_GOING_ON_FOR_vehicle(SetPieceCarID[iSetPieceReRecNum]) IF (bShowSetPieceReRecPath) DISPLAY_PLAYBACK_RECORDED_vehicle(SetPieceCarID[iSetPieceReRecNum], RDM_WHOLELINE) ELSE DISPLAY_PLAYBACK_RECORDED_vehicle(SetPieceCarID[iSetPieceReRecNum], RDM_NONE) ENDIF ENDIF ENDIF ENDIF IF bLoadSetPieceDataForReRec IF SetPieceCarRecording[iSetPieceReRecNum] > 0 bStartSetPieceReRec = FALSE WHILE NOT HAS_UBER_PLAYBACK_BEEN_SKIPPED_TO_PLAYBACK_TIME(TriggerCar, SetPieceCarStartime[iSetPieceReRecNum]) WAIT(0) ENDWHILE bPausePlayback = TRUE IF NOT IS_ENTITY_DEAD(SetPieceCarID[iSetPieceReRecNum]) SET_ENTITY_COLLISION(SetPieceCarID[iSetPieceReRecNum], FALSE) pedTemp = GET_PED_IN_VEHICLE_SEAT(SetPieceCarID[iSetPieceReRecNum]) IF pedTemp <> NULL SET_ENTITY_COLLISION(pedTemp, FALSE) SET_ENTITY_VISIBLE(pedTemp, FALSE) ENDIF SET_ENTITY_VISIBLE(SetPieceCarID[iSetPieceReRecNum], FALSE) IF IS_PLAYER_PLAYING(PLAYER_ID()) CLEAR_ped_TASKS_IMMEDIATELY(PLAYER_ped_ID()) ENDIF IF DOES_ENTITY_EXIST(vehForSetPieceReRec) SET_VEHICLE_AS_NO_LONGER_NEEDED(vehForSetPieceReRec) ENDIF VECTOR vPos = GET_POSITION_OF_vehicle_RECORDING_AT_TIME(SetPieceCarRecording[iSetPieceReRecNum], 0.0, strUberName) CLEAR_AREA(vPos, 5.0, TRUE) vehForSetPieceReRec = CREATE_VEHICLE(SetPieceCarModel[iSetPieceReRecNum], vPos, DEFAULT, FALSE, FALSE) SET_PED_INTO_VEHICLE(PLAYER_PED_ID(), vehForSetPieceReRec) START_PLAYBACK_RECORDED_VEHICLE(vehForSetPieceReRec, SetPieceCarRecording[iSetPieceReRecNum], strUberName) PAUSE_PLAYBACK_RECORDED_VEHICLE(vehForSetPieceReRec) ELSE SCRIPT_ASSERT("Set piece vehicle is dead!") ENDIF bLoadSetPieceDataForReRec = FALSE bReRecSetPieceDataLoaded = TRUE ELSE SCRIPT_ASSERT("Setpiece re-recorder: Invalid setpiece array index!") ENDIF ENDIF #ENDIF // RESET TO A SPECIFIC TIME IN THE RECORDING IF (bResetPlaybackToTime) WHILE NOT HAS_UBER_PLAYBACK_BEEN_SKIPPED_TO_PLAYBACK_TIME(TriggerCar, fResetTime) WAIT(0) ENDWHILE bPausePlayback = TRUE ENDIF // RERECORDING - start the rerecording #IF IS_DEBUG_BUILD IF (bReRecordingIsEnabled) IF IS_BUTTON_PRESSED(PAD1, CROSS) IF IS_VEHICLE_DRIVEABLE(TriggerCar) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(TriggerCar) STOP_PLAYBACK_RECORDED_VEHICLE(TriggerCar) ENDIF ENDIF INIT_UBER_RECORDING(strUberName) PRINT_NOW("HIJACKED", 5000, 1) bReRecordingControlHijacked = TRUE ENDIF UPDATE_UBER_RECORDING() ENDIF #ENDIF IF (bCreateAllWaitingCars) bCreateAllWaitingCars = FALSE ENDIF ELSE #IF IS_DEBUG_BUILD UPDATE_UBER_RECORDING() #ENDIF ENDIF // output clean data #IF IS_DEBUG_BUILD IF (bOutputCleanedData) OUTPUT_CLEANED_DATA() bOutputCleanedData = FALSE ENDIF #ENDIF ENDPROC