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

6206 lines
269 KiB
Python
Executable File

//Compile out Title Update changes to header functions.
//Must be before includes.
//CONST_INT USE_TU_CHANGES 0 // Removed by Kenneth R.
//////////////////////////////////////////////////////////////////////////////////////////
// //
// MISSION NAME : taxiService.sc //
// AUTHOR : Ahron Mason //
// DESCRIPTION : Handles player inside a taxi as a passenger //
// //
//////////////////////////////////////////////////////////////////////////////////////////
USING "rage_builtins.sch"
USING "globals.sch"
USING "cellphone_public.sch"
USING "dialogue_public.sch"
USING "taxi_functions.sch"
USING "randomChar_public.sch"
USING "mission_stat_public.sch"
USING "properties_public.sch"
//USING "rgeneral_include.sch"
USING "website_public.sch"
USING "minigame_public.sch"
USING "vehicle_gen_public.sch"
USING "mp_scaleform_functions.sch"
USING "rgeneral_include.sch"
//-------------------------------------------------------------------------------------------------------------------------------------------------
// :ENUMS
//-------------------------------------------------------------------------------------------------------------------------------------------------
/// PURPOSE: main states for the script
ENUM TAXI_SERVICE_STATE
TAXI_SERVICE_STATE_NONE = 0,
TAXI_SERVICE_STATE_PLAYER_IN_TAXI,
TAXI_SERVICE_END,
TAXI_SERVICE_METER_ONLY
ENDENUM
/// PURPOSE: states whilst in the back of the taxi during TAXI_SERVICE_STATE_PLAYER_IN_TAXI
ENUM TAXI_JOURNEY_STATE
TAXI_JOURNEY_STATE_CREATE_TAXI_METER,
TAXI_JOURNEY_STATE_CHOOSE_LOCATION,
TAXI_JOURNEY_STATE_DRIVING_TO_DESTINATION,
TAXI_JOURNEY_STATE_ORDERED_TO_PULLOVER,
TAXI_JOURNEY_STATE_SKIP_JOURNEY,
TAXI_JOURNEY_STATE_ARRIVED_AT_DESTINATION
ENDENUM
/// PURPOSE: states during the skip taxi journey
ENUM SKIP_JOURNEY_STATE
SKIP_JOURNEY_STATE_FADE_OUT,
SKIP_JOURNEY_STATE_FADED_OUT,
SKIP_JOURNEY_STATE_WAIT_GEN_DESTINATION_INFO,
SKIP_JOURNEY_STATE_MOVE_TAXI_TO_DESTINATION,
SKIP_JOURNEY_STATE_SETUP_LOAD_SCENE,
SKIP_JOURNEY_STATE_LOAD_SCENE_THEN_REQUEST_LEADIN,
SKIP_JOURNEY_STATE_REQUEST_ASSETS_AT_DESTINATION,
SKIP_JOURNEY_STATE_LOADING_ASSETS_AT_DESTINATION,
SKIP_JOURNEY_STATE_FADE_IN,
SKIP_JOURNEY_STATE_FADED_IN,
SKIP_JOURNEY_STATE_SKIP_FINISHED
ENDENUM
/*ENUM TAXI_CLOSEST_TRIGGER_TYPE
TAXI_CTT_SP_MISSION_TRIGGER,
TAXI_CTT_RC_MISSION_TRIGGER,
TAXI_CTT_INVALID_TRIGGER
ENDENUM
TAXI_CLOSEST_TRIGGER_TYPE eClosestTriggerType = TAXI_CTT_INVALID_TRIGGER*/
/// PURPOSE: states for generating safe destination
ENUM TAXI_GENERATE_SAFE_DESTINATION_STATE
TAXI_GSDS_INITIAL_TRIGGER_AREAS_CHECK,
TAXI_GSDS_INITIAL_SPECIAL_AREA_CHECK,
TAXI_GSDS_GENERATE_COORDS,
TAXI_GSDS_TRIGGER_AREAS_RECHECK,
TAXI_GSDS_SAFE_DESTINATION_FOUND,
TAXI_GSDS_SAFE_DESTINATION_NOT_FOUND
ENDENUM
//-------------------------------------------------------------------------------------------------------------------------------------------------
// :CONSTANTS
//-------------------------------------------------------------------------------------------------------------------------------------------------
CONST_FLOAT TAXI_LANE_OFFSET 4.2 // 4.5
CONST_FLOAT TAXI_SPEED_NORMAL 12.0
CONST_FLOAT TAXI_SPEED_FAST 25.0
CONST_FLOAT TAXI_TARGET_REACHED_DIST 45.0
CONST_FLOAT FARE_DISTANCE 50.0
CONST_FLOAT FARE_RATE 0.22
CONST_FLOAT FARE_SKIP_MULTIPLIER 2.4
CONST_INT ENTER_CAR_AS_PASSENGER_TIME 375
CONST_INT START_POSITION 0
CONST_INT MAX_NUMBER_OF_TAXI_DESTINATIONS 40
CONST_INT INITIAL_PRICE 0
CONST_INT STICK_DEAD_ZONE 28
CONST_INT TAXI_SERVICE_CHANGE_DEST_CAM_TIMEOUT 3000 // amount of time (milliseconds) bcfore we class a change destination attempt as ended
//-------------------------------------------------------------------------------------------------------------------------------------------------
// :VARIABLES
//-------------------------------------------------------------------------------------------------------------------------------------------------
BOOL bTaxiHasHitDestinationLocate
BOOL bSkipJourneyLoadSceneStarted = FALSE
BOOL bUpdateTaxiControls
BOOL bSelectingAnotherDestination
BOOL bDestinationSelected
BOOL bDropPointSelected
BOOL bStickInUseUp
BOOL bStickInUseDown
BOOL bHurrying
BOOL bMadeItToDestination
BOOL bPlayerCanLeaveVehicle
BOOL bUsedFloorZ = FALSE //Used to add the extra check against incorrect floor Z coords
CAMERA_INDEX camMeter
// diff between two modes - standard uses DF_StopAtLights, Hurry uses DF_UseShortCutLinks
// B*1380004 - added DF_StopForCars to hurry mode to make them stop for Trains
DRIVINGMODE taxiDrivingModeStandard = DF_SteerAroundStationaryCars|DF_StopForPeds|DF_StopAtLights|DF_ChangeLanesAroundObstructions|DF_StopForCars|DF_ForceJoinInRoadDirection|DF_SteerAroundObjects|DF_UseSwitchedOffNodes|DF_AvoidRestrictedAreas|DF_UseWanderFallbackInsteadOfStraightLine
DRIVINGMODE taxiDrivingModeHurry = DF_SwerveAroundAllCars|DF_StopForPeds|DF_ChangeLanesAroundObstructions|DF_StopForCars|DF_ForceJoinInRoadDirection|DF_SteerAroundObjects|DF_UseSwitchedOffNodes|DF_UseShortCutLinks|DF_AvoidRestrictedAreas|DF_UseWanderFallbackInsteadOfStraightLine
enumCharacterList charWhenTaxiLaunched
FLOAT fDropOffDistFromBlip
FLOAT fFareRate = FARE_RATE
FLOAT camMeterFOV = 50
FLOAT fMinYChange = -4
FLOAT fMaxYChange = 4
FLOAT fMinXChange = -89
FLOAT fMaxXChange = 89
FLOAT fTaxiCamSpeed = 4.0
FLOAT fTaxiCamChangeY
FLOAT fTaxiCamChangeX
FLOAT fFare = INITIAL_PRICE
FLOAT fDistanceToDestination
// Taxi meter UI variables NOTE: these variables have changed since last gen!
FLOAT fTaxiMenu_ScaleSizeX = 0.4
FLOAT fTaxiMenu_ScaleSizeY = 0.6
FLOAT fTaxiMenu_ScaleCentreX = 0.201
FLOAT fTaxiMenu_ScaleCentreY = 0.351
INT iDesinationNodeSearchNumber
INT iSkipJourneyTimer = 0
INT iTimer_WaitForGroupMembers = -1
INT iTotalNumberOfTaxiDestinations = 0
INT iCurrentHighlightedPosition = START_POSITION
INT iRenderTarget
INT iStoredCountedMissionLocations
INT iStoredNumberOfBlips
INT iStoredNumberOfOccupants
INT iStoredTaxiWaypointBlipDestinationIndex
INT iCountBlipsAddedToDestinationListThisFrame
INT iDialogueTimer_BanterDuringJourney = 0
INT iDialogueTimer_ChangeRadio = 0
INT currentJourneyPrice = INITIAL_PRICE
INT lastJourneyPrice
INT iFareTimer
INT iTimer_SelectingAnotherDestinationTimeOut
g_eRC_MissionIDs eClosestRCMission = NO_RC_MISSION
g_eRC_MissionIDs eRCMissionDestination = NO_RC_MISSION
STRING instructButtonStored_changeDest = GET_CONTROL_INSTRUCTIONAL_BUTTONS_STRING(FRONTEND_CONTROL, INPUT_FRONTEND_AXIS_X)
MODEL_NAMES modelMeter = Prop_TAXI_METER_2
OBJECT_INDEX objMeter
PARK_TYPE parkTypeTaxiAtDestination = PARK_TYPE_PULL_OVER
SCALEFORM_INDEX scaleformTaxiMeter
SCALEFORM_INDEX scaleformTaxiControls
SCALEFORM_INSTRUCTIONAL_BUTTONS instructionalButtons
SEQUENCE_INDEX seqTaxi
SPRITE_PLACEMENT aSpriteTaxiControls
SP_MISSIONS eMissionAtBlip
SP_MISSIONS eStoryMissionDestination = SP_MISSION_NONE
STATIC_BLIP_NAME_ENUM eMinigameDestination = STATIC_BLIP_NAME_DUMMY_FINAL
TAXI_DIALOGUE eTaxiDialogue = TAXI_DIALOGUE_NOTHING
TAXI_DEST AllTaxiDestinations[MAX_NUMBER_OF_TAXI_DESTINATIONS]
TAXI_GENERATE_SAFE_DESTINATION_STATE eGenerateSafeDestinationState = TAXI_GSDS_INITIAL_TRIGGER_AREAS_CHECK
TAXI_JOURNEY_STATE eTaxiJourneyState = TAXI_JOURNEY_STATE_CREATE_TAXI_METER
TAXI_SERVICE_STATE eTaxiServiceStage = TAXI_SERVICE_STATE_NONE
SKIP_JOURNEY_STATE eSkipJourneyState = SKIP_JOURNEY_STATE_FADE_OUT
TEXT_LABEL_31 tlAnimDictTaxiDriver = "oddjobs@taxi@driver"
VECTOR vDestinationLocate
VECTOR vPathNodeRequestMin = << 0.0, 0.0, 0.0 >>
VECTOR vPathNodeRequestMax = << 0.0, 0.0, 0.0 >>
VECTOR vOriginal
VECTOR vLastFarePoint
VECTOR vStoredTaxiWaypointBlipDestinationCoords
VECTOR vTaxiCamOffset = << 0.0, -0.25, 0.55 >>
VECTOR vTaxiCamFixedRotation = << -0.3, 1.0, 0.35 >>
VECTOR vMeterOffset = <<-0.0100, 0.6000, 0.2400>>
VECTOR vMeterRotation = << -5, 0, 0 >>
VEHICLE_SEAT eStoredPlayerSeat
//-------------------------------------------------------------------------------------------------------------------------------------------------
// :DEBUG VARIABLES / FUNCS / PROCS / WIDGETS
//-------------------------------------------------------------------------------------------------------------------------------------------------
#IF IS_DEBUG_BUILD
// Debug variables
BLIP_INDEX blipDebug
BLIP_INDEX blipDebugOriginal
BOOL bDebug_OutputInfo
BOOL bDebugLaunchMeterOnly
BOOL bCleanupScript
BOOL bResetMeterOffset
BOOL bDebug_DisplayTaxiToPlayerPullInSpot
BOOL bDebug_DisplayTaxiDropOffPosition
BOOL bDebugDisplayPathNodeLoadArea
BOOL bDebugLoadAllPathNodes
BOOL bDebug_TestIsPositionInSpecialArea
BOOL bDebugUnLoadAllPathNodes
BOOL bDebugDrawSphereAroundActiveTaxi
BOOL bDebugSetBreakOnNodeCommandsUsage
BOOL bDebugPerformGetTaxiPullInSpotTest
BOOL bDebug_UpdateTaxiCamOffsetAndRot = FALSE
BOOL bAddBlipForDestination
BOOL bDebugDrawAllTaxiPickupPositionInfo
BOOL bDebug_DrawGetPullOverResults
VECTOR vDebug_TempPickupPos
VECTOR vDebug_TempDropOffPos
VECTOR vDebug_DriveToNodePos
BOOL bDebug_LaunchMeter = FALSE
PROC DEBUG_DRAW_TAXI_PULL_OVER_INFO(VECTOR vParkCoords, VECTOR vOppositeSideCoords, VECTOR vNodeCoords)
IF bDebug_DrawGetPullOverResults
INT iTempTime = GET_GAME_TIMER()
WHILE (GET_GAME_TIMER() - iTempTime) < 3000
SET_DEBUG_ACTIVE(TRUE)
SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(TRUE)
DRAW_DEBUG_SPHERE(vParkCoords, 2.5, 128, 255, 0, 150) // green
DRAW_DEBUG_SPHERE(vOppositeSideCoords, 2.5, 255, 0, 0, 150) // red
DRAW_DEBUG_SPHERE(vNodeCoords, 1.5, 178, 0, 255, 150) // purple
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PULL_OVER_INFO() : bDebug_DrawGetPullOverResults this frame green = park, purple = node, red = opposite side ")
WAIT(0)
ENDWHILE
ENDIF
ENDPROC
// debug print blip type
PROC DEBUG_PRINT_BLIP_TYPE_TO_TTY(BLIP_INDEX &blipIndex)
IF DOES_BLIP_EXIST(blipIndex)
SWITCH GET_BLIP_INFO_ID_TYPE(blipIndex)
CASE BLIPTYPE_UNUSED
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : DEBUG_PRINT_BLIP_TYPE_TO_TTY : BLIPTYPE_UNUSED")
BREAK
CASE BLIPTYPE_VEHICLE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : DEBUG_PRINT_BLIP_TYPE_TO_TTY : BLIPTYPE_VEHICLE")
BREAK
CASE BLIPTYPE_CHAR
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : DEBUG_PRINT_BLIP_TYPE_TO_TTY : BLIPTYPE_CHAR")
BREAK
CASE BLIPTYPE_OBJECT
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : DEBUG_PRINT_BLIP_TYPE_TO_TTY : BLIPTYPE_OBJECT")
BREAK
CASE BLIPTYPE_COORDS
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : DEBUG_PRINT_BLIP_TYPE_TO_TTY : BLIPTYPE_COORDS")
BREAK
CASE BLIPTYPE_CONTACT
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : DEBUG_PRINT_BLIP_TYPE_TO_TTY : BLIPTYPE_CONTACT")
BREAK
CASE BLIPTYPE_PICKUP
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : DEBUG_PRINT_BLIP_TYPE_TO_TTY : BLIPTYPE_PICKUP")
BREAK
CASE BLIPTYPE_RADIUS
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : DEBUG_PRINT_BLIP_TYPE_TO_TTY : BLIPTYPE_RADIUS")
BREAK
CASE BLIPTYPE_WEAPON_PICKUP
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : DEBUG_PRINT_BLIP_TYPE_TO_TTY : BLIPTYPE_WEAPON_PICKUP")
BREAK
CASE BLIPTYPE_COP
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : DEBUG_PRINT_BLIP_TYPE_TO_TTY : BLIPTYPE_COP")
BREAK
CASE BLIPTYPE_STEALTH
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : DEBUG_PRINT_BLIP_TYPE_TO_TTY : BLIPTYPE_STEALTH")
BREAK
CASE BLIPTYPE_AREA
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : DEBUG_PRINT_BLIP_TYPE_TO_TTY : BLIPTYPE_AREA")
BREAK
ENDSWITCH
ENDIF
ENDPROC
#ENDIF
/// PURPOSE:
/// Checks if the entity exists and is not dead.
/// PARAMS:
/// mEntity - the entity we are checking.
/// RETURNS:
/// True if the entity exists and is not dead.
FUNC BOOL IS_ENTITY_ALIVE(ENTITY_INDEX mEntity)
IF DOES_ENTITY_EXIST(mEntity)
IF NOT IS_ENTITY_DEAD(mEntity)
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Checks that the ped exists, is alive and is not injured
/// PARAMS:
/// mPed - the ped we are checking
/// RETURNS:
/// True if the ped exists, is alive and is not injured. false otherwise.
FUNC BOOL IS_PED_UNINJURED(PED_INDEX mPed)
IF DOES_ENTITY_EXIST(mPed)
IF NOT IS_ENTITY_DEAD(mPed)
IF NOT IS_PED_INJURED(mPed)
RETURN TRUE
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Checks that the vehicle exists, is alive, driveable and not on fire
/// PARAMS:
/// mVehicle - the vehicle we are checking
/// RETURNS:
/// True if the vehicle exists, is alive, driveable and not on fire. false otherwise.
FUNC BOOL IS_VEHICLE_OK(VEHICLE_INDEX mVehicle)
IF IS_ENTITY_ALIVE(mVehicle)
IF IS_VEHICLE_DRIVEABLE(mVehicle)
IF NOT IS_ENTITY_ON_FIRE(mVehicle)
RETURN TRUE
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// check if iTimeAmount has passed since iTimer was set
/// PARAMS:
/// iTimer - the timer
/// iTimeAmount - the amount of time to check has passed
/// RETURNS:
/// True is the specified amount of time has passed for the specified timer.
FUNC BOOL HAS_TIME_PASSED(INT iTimer, INT iTimeAmount)
RETURN (GET_GAME_TIMER() - iTimer) > iTimeAmount
ENDFUNC
/// PURPOSE:
/// cleanup for the script
/// PARAMS:
/// bFadeInForSkipJourney - B* 1456271 - back up fade in if script terminated during a taxi skip - but needs to not happen if cleanup was for repeat play
PROC TAXI_SERVICE_SCRIPT_CLEANUP(BOOL bFadeInForSkipJourney = TRUE)
SET_CINEMATIC_BUTTON_ACTIVE(TRUE)
IF IS_NAMED_RENDERTARGET_REGISTERED("taxi")
RELEASE_NAMED_RENDERTARGET("taxi")
ENDIF
IF DOES_CAM_EXIST(camMeter)
IF IS_CAM_ACTIVE(camMeter)
SET_PARTICLE_FX_CAM_INSIDE_VEHICLE(FALSE) // B*1549323 - stops rain inside taxi
ENDIF
SET_CAM_ACTIVE(camMeter, FALSE)
DESTROY_CAM(camMeter)
RENDER_SCRIPT_CAMS(FALSE, FALSE)
UNLOCK_MINIMAP_POSITION()
UNLOCK_MINIMAP_ANGLE()
SET_RADAR_ZOOM(0)
ENDIF
g_bTaxiShouldForcePhoneDislayOnHud = FALSE // reset global used for B*2053172 - force phone display on HUD
IF DOES_ENTITY_EXIST(objMeter)
DELETE_OBJECT(objMeter)
SET_MODEL_AS_NO_LONGER_NEEDED(modelMeter)
ENDIF
SET_SCALEFORM_MOVIE_AS_NO_LONGER_NEEDED(scaleformTaxiMeter)
SET_SCALEFORM_MOVIE_AS_NO_LONGER_NEEDED(scaleformTaxiControls)
IF IS_PED_UNINJURED(g_WaitingTaxiDriver)
IF IS_ENTITY_PLAYING_ANIM(g_WaitingTaxiDriver, tlAnimDictTaxiDriver, "leanover_enter")
STOP_ENTITY_ANIM(g_WaitingTaxiDriver, "leanover_enter", tlAnimDictTaxiDriver, REALLY_SLOW_BLEND_OUT)
ELIF IS_ENTITY_PLAYING_ANIM(g_WaitingTaxiDriver, tlAnimDictTaxiDriver, "leanover_idle")
STOP_ENTITY_ANIM(g_WaitingTaxiDriver, "leanover_idle", tlAnimDictTaxiDriver, REALLY_SLOW_BLEND_OUT)
ELIF IS_ENTITY_PLAYING_ANIM(g_WaitingTaxiDriver, tlAnimDictTaxiDriver, "leanover_exit")
STOP_ENTITY_ANIM(g_WaitingTaxiDriver, "leanover_exit", tlAnimDictTaxiDriver, REALLY_SLOW_BLEND_OUT)
ENDIF
IF IS_PED_HEADTRACKING_PED(g_WaitingTaxiDriver, PLAYER_PED_ID())
TASK_CLEAR_LOOK_AT(g_WaitingTaxiDriver)
ENDIF
ENDIF
REMOVE_ANIM_DICT(tlAnimDictTaxiDriver)
// cleanup for script ending earlier during Skip Journey state
IF eTaxiJourneyState = TAXI_JOURNEY_STATE_SKIP_JOURNEY
IF eSkipJourneyState != SKIP_JOURNEY_STATE_SKIP_FINISHED
// B*1582742 - ensure now load scene is binned off in cleanup
IF bSkipJourneyLoadSceneStarted
IF IS_NEW_LOAD_SCENE_ACTIVE()
NEW_LOAD_SCENE_STOP()
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " TAXI_SERVICE_SCRIPT_CLEANUP() : NEW_LOAD_SCENE_STOP() called for active load scene ")
ENDIF
bSkipJourneyLoadSceneStarted = FALSE
ENDIF
DISABLE_CELLPHONE(FALSE)
IF IS_AUDIO_SCENE_ACTIVE("FADE_OUT_WORLD_250MS_SCENE")
STOP_AUDIO_SCENE("FADE_OUT_WORLD_250MS_SCENE")
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " TAXI_SERVICE_SCRIPT_CLEANUP() : stopped audio scene FADE_OUT_WORLD_250MS_SCENE")
ENDIF
IF DOES_ENTITY_EXIST(g_WaitingTaxi)
IF IS_VEHICLE_DRIVEABLE(g_WaitingTaxi)
SET_VEHICLE_RADIO_ENABLED(g_WaitingTaxi, TRUE)
FREEZE_ENTITY_POSITION(g_WaitingTaxi, FALSE)
ENDIF
ENDIF
// B* 1456271 - back up fade in if script terminated during a taxi skip - but needs to not happen if cleanup was for repeat play
IF bFadeInForSkipJourney
IF IS_SCREEN_FADED_OUT()
OR IS_SCREEN_FADING_OUT()
IF NOT IS_SCREEN_FADING_IN()
// B* 1684211 - Don't fade the screen in if a replay has started processing mid journey skip. We can assume
// the replay system will fade it in when it needs to.
IF NOT IS_REPLAY_BEING_SET_UP()
AND NOT IS_REPLAY_BEING_PROCESSED()
AND g_replay.replayStageID != RS_ACTIVE
DO_SCREEN_FADE_IN(250)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " TAXI_SERVICE_SCRIPT_CLEANUP() : faded screen in as detcted script terminate in skip journey state")
ENDIF
ENDIF
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " TAXI_SERVICE_SCRIPT_CLEANUP() : fade up NOT done as faded in already")
ENDIF
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " TAXI_SERVICE_SCRIPT_CLEANUP() : fade up NOT done bFadeInForSkipJourney = FALSE")
ENDIF
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " TAXI_SERVICE_SCRIPT_CLEANUP() : fade up NOT done eSkipJourneyState = SKIP_JOURNEY_STATE_SKIP_FINISHED")
ENDIF
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " TAXI_SERVICE_SCRIPT_CLEANUP() : fade up NOT done as eTaxiJourneyState != TAXI_JOURNEY_STATE_SKIP_JOURNEY")
ENDIF
// always make sure player gets out taxi on cleanup unless he's driving
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
IF IS_VEHICLE_OK(g_WaitingTaxi)
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), g_WaitingTaxi, TRUE)
IF GET_PED_IN_VEHICLE_SEAT(g_WaitingTaxi, VS_DRIVER) != PLAYER_PED_ID()
IF NOT TAXI_IS_PED_PERFORMING_TASK(PLAYER_PED_ID(), SCRIPT_TASK_LEAVE_ANY_VEHICLE)
AND NOT TAXI_IS_PED_PERFORMING_TASK(PLAYER_PED_ID(), SCRIPT_TASK_LEAVE_VEHICLE)
TASK_LEAVE_ANY_VEHICLE(PLAYER_PED_ID())
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " TAXI_SERVICE_SCRIPT_CLEANUP() -> player tasked to leave g_WaitingTaxi")
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
CANCEL_GROUP_GETTING_INTO_CAB()
CLEANUP_WAITING_TAXI() // handles release of g_WaitingTaxi and g_WaitingTaxiDriver
g_iTaxiHailedTime = -1
g_bPlayerIsInTaxi = FALSE // B*1401225 - ensure this global is always reset to false when the script ends since it's used in various scripts include IS_IT_SAFE_TO_TRIGGER_SCRIPT_TYPE
g_bRequestTaxiServiceCleanup = FALSE
#IF IS_DEBUG_BUILD
SET_DEBUG_ACTIVE(FALSE)
SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(FALSE)
#ENDIF
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " TAXI_SERVICE_SCRIPT_CLEANUP() : done about to terminate thread")
TERMINATE_THIS_THREAD()
ENDPROC
/// PURPOSE:
/// Request model and creates the taxi meter
/// Requests the scaleform "taxi_display" and sets the render target
/// Requests the scaleform "instructional_buttons" and waits for it to load
/// Requests taxi driver's anim dictionary
/// RETURNS:
/// TRUE once taxi meter has been setup and all
FUNC BOOL REQUEST_AND_LOAD_TAXI_ASSETS()
REQUEST_MODEL(modelMeter)
scaleformTaxiMeter = REQUEST_SCALEFORM_MOVIE("taxi_display")
scaleformTaxiControls = REQUEST_SCALEFORM_MOVIE("instructional_buttons")
REQUEST_ANIM_DICT(tlAnimDictTaxiDriver)
IF HAS_MODEL_LOADED(modelMeter)
AND HAS_SCALEFORM_MOVIE_LOADED(scaleformTaxiMeter)
AND HAS_SCALEFORM_MOVIE_LOADED(scaleformTaxiControls)
AND HAS_ANIM_DICT_LOADED(tlAnimDictTaxiDriver)
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// creates the taxi meter and sets the render target
/// RETURNS:
/// TRUE true when object exists
FUNC BOOL CREATE_TAXI_METER()
IF DOES_ENTITY_EXIST(objMeter)
RETURN TRUE
ENDIF
IF DOES_ENTITY_EXIST(g_WaitingTaxi)
IF IS_VEHICLE_DRIVEABLE(g_WaitingTaxi)
objMeter = CREATE_OBJECT(modelMeter, GET_ENTITY_COORDS(g_WaitingTaxi))
ATTACH_ENTITY_TO_ENTITY(objMeter, g_WaitingTaxi, GET_ENTITY_BONE_INDEX_BY_NAME(g_WaitingTaxi, "Chassis"), vMeterOffset, vMeterRotation)
SET_TAXI_LIGHTS(g_WaitingTaxi, FALSE)
IF NOT IS_NAMED_RENDERTARGET_REGISTERED("taxi")
REGISTER_NAMED_RENDERTARGET("taxi")
LINK_NAMED_RENDERTARGET(GET_ENTITY_MODEL(objMeter))
ENDIF
iRenderTarget = GET_NAMED_RENDERTARGET_RENDER_ID("taxi")
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : CREATE_TAXI_METER() object created")
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// updates fDropOffDistFromBlip used to check player leaving pulled up taxi
/// PARAMS:
/// vDestinationCoord - the place the taxi is supposed to reach
/// vPullOverCoord - the actual position the taxi pulled up
PROC UPDATE_STORED_PULL_OVER_DIST_FROM_DESTINATION(VECTOR vDestinationCoord, VECTOR vPullOverCoord)
VECTOR vDiff_Destination_To_ReturnNode
vDiff_Destination_To_ReturnNode = vDestinationCoord - vPullOverCoord
vDiff_Destination_To_ReturnNode.z = 0.0
fDropOffDistFromBlip = VMAG(vDiff_Destination_To_ReturnNode)
ENDPROC
/// PURPOSE:
/// Check if the blip passed in is the waypoint blip.
FUNC BOOL IS_BLIP_WAYPOINT_BLIP(BLIP_INDEX &blip)
IF DOES_BLIP_EXIST(blip)
AND GET_SPRITE_FOR_BLIP(blip) = GET_WAYPOINT_BLIP_ENUM_ID()
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_BLIP_WAYPOINT_BLIP() : TRUE!")
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// get a valid position for the taxi to drive to - handles requesting the path nodes needed to navigate to the position
/// PARAMS:
/// vehIndexTaxi - handle to the taxi, used in obsured check
/// vOriginCoord - coords pathing from
/// DestinationCoord - coords wanting to reach
/// vReturnCoord -
/// fReturnHeading -
/// iReturnedNodeNumber - return the node number of the last test, used to setup repeat checks
/// iExtraLoadPathDist -
/// RETURNS:
///
FUNC BOOL GET_TAXI_PULL_IN_SPOT_NEAR_COORDS(VEHICLE_INDEX &vehIndexTaxi, VECTOR vOriginCoord, VECTOR DestinationCoord, VECTOR &vReturnCoord, FLOAT &fReturnHeading, INT &iReturnedNodeNumber, BLIP_INDEX &blipDestination, INT iExtraLoadPathDist = 1000)
FLOAT zMeasureMult = 3
FLOAT fZ_Tolerance = 2.5 // B*1430520
VECTOR vec1, vNorth, vSouth
ENTITY_INDEX entityPointObsuredCheck = NULL
INT iNoOfLanes, iLanesNorth, iLanesSouth
FLOAT offsetToKerb, centralReservationWidth
FLOAT fTempZDiff
VEHICLE_NODE_ID tempVehNodeID
BOOL bFoundSuitableCoords = FALSE
// always search switched off nodes, but if we are in the city ensure they aren't dead ends (stop taxi using driveways).
NODE_FLAGS nodeFlags = NF_INCLUDE_SWITCHED_OFF_NODES
IF NOT IS_POSITION_IN_ZONE_SAFE_FOR_DEADEND_NODES(DestinationCoord)
nodeFlags = NF_INCLUDE_SWITCHED_OFF_NODES | NF_IGNORE_SWITCHED_OFF_DEADENDS
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ** GET_TAXI_PULL_IN_SPOT_NEAR_COORDS() : using node flags NF_INCLUDE_SWITCHED_OFF_NODES | NF_IGNORE_SWITCHED_OFF_DEADENDS")
ENDIF
BOOL bUsingSwitchedOffNodes = TRUE
BOOL bIsOneDirectional
BOOL bNodeIsSouth
INT iMaxNodeLoopChecksPerFrame = iReturnedNodeNumber + 2 // limit to checks per frame
INT iMaxNodeLoopChecksInTotal = 50
INT iPropertyFlags
INT iDensity
REQUEST_PATH_NODES_IN_AREA_FOR_TAXI_THIS_FRAME(vOriginCoord, DestinationCoord, vPathNodeRequestMin, vPathNodeRequestMax, iExtraLoadPathDist)
IF ARE_REQUEST_PATH_NODES_LOADED_FOR_TAXI(vPathNodeRequestMin, vPathNodeRequestMax)
// 10 chances to get a valid node otherwise bail out
WHILE (NOT bFoundSuitableCoords AND (iReturnedNodeNumber < iMaxNodeLoopChecksPerFrame))
IF DestinationCoord.z = 1
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ** GET_TAXI_PULL_IN_SPOT_NEAR_COORDS() : zMeasureMult = 0")
zMeasureMult = 0
ENDIF
IF GET_NTH_CLOSEST_VEHICLE_NODE_WITH_HEADING(DestinationCoord, iReturnedNodeNumber, vReturnCoord, fReturnHeading, iNoOfLanes, nodeFlags, zMeasureMult, fZ_Tolerance)
tempVehNodeID = GET_NTH_CLOSEST_VEHICLE_NODE_ID(vReturnCoord, 1, nodeFlags)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ** GET_NTH_CLOSEST_VEHICLE_NODE_WITH_HEADING() : DestinationCoord = ", DestinationCoord, " ReturnNodeCoord = ", vReturnCoord, " fReturnHeading = ", fReturnHeading,
" iNoOfLanes = ", iNoOfLanes, " zMeasureMult = ", zMeasureMult, " fZ_Tolerance = ", fZ_Tolerance, " iCurrentNodeNumber = ", iReturnedNodeNumber)
IF IS_VEHICLE_NODE_ID_VALID(tempVehNodeID)
// grab road info needed to workout the curb offset
IF GET_CLOSEST_ROAD(vReturnCoord, 1, 1, vSouth, vNorth, iLanesSouth, iLanesNorth, centralReservationWidth, bUsingSwitchedOffNodes)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ** GET_CLOSEST_ROAD : vSouth = ", vSouth, " vNorth = ", vNorth, " iLanesSouth = ", iLanesSouth,
" iLanesNorth = ", iLanesNorth, " centralReservationWidth = ", centralReservationWidth)
// taken from net nodes.sch apparently number of lanes south / north' they were opposite so results are flipped
IF (fReturnHeading < 90.0) OR (fReturnHeading >= 270.0)
bNodeIsSouth = TRUE
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ** node heading facing North ...temp south")
ELSE
bNodeIsSouth = FALSE
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ** node heading facing South ...temp North")
ENDIF
bIsOneDirectional = FALSE
IF (bNodeIsSouth)
IF (iNoOfLanes = iLanesSouth)
bIsOneDirectional = TRUE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ** South road is one directional")
ELSE
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ** South road is NOT one directional")
ENDIF
ELSE
IF (iNoOfLanes = iLanesNorth)
bIsOneDirectional = TRUE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ** North road is NOT one directional")
ELSE
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ** North road is NOT one directional")
ENDIF
ENDIF
IF centralReservationWidth < 0
offsetToKerb = 0
ELSE
IF GET_VEHICLE_NODE_IS_SWITCHED_OFF(tempVehNodeID)
OR NOT GET_VEHICLE_NODE_IS_GPS_ALLOWED(tempVehNodeID)
offsetToKerb = 0
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ** offsetToKerb set : ", offsetToKerb, " : for switched off node / no gps")
ELSE
IF (bNodeIsSouth)
IF (bIsOneDirectional)
offsetToKerb = (TAXI_LANE_OFFSET*(TO_FLOAT(iLanesSouth)*0.5))
ELSE
offsetToKerb = (TAXI_LANE_OFFSET*(TO_FLOAT(iLanesSouth)))
ENDIF
// additional offset for more than 1 lane
IF (bIsOneDirectional)
IF (iLanesSouth > 2)
offsetToKerb += ((iLanesSouth-2) * 1.0)
ENDIF
ELSE
IF (iLanesSouth > 1)
offsetToKerb += ((iLanesSouth-1) * 1.0)
ENDIF
ENDIF
ELSE
IF (bIsOneDirectional)
offsetToKerb = (TAXI_LANE_OFFSET*(TO_FLOAT(iLanesNorth)*0.5))
ELSE
offsetToKerb = (TAXI_LANE_OFFSET*(TO_FLOAT(iLanesNorth)))
ENDIF
// additional offset for more than 1 lane
IF (bIsOneDirectional)
IF (iLanesNorth > 2)
offsetToKerb += ((iLanesNorth-2) * 1.0)
ENDIF
ELSE
IF (iLanesNorth > 1)
offsetToKerb += ((iLanesNorth-1) * 1.0)
ENDIF
ENDIF
ENDIF
// overrides
IF GET_VEHICLE_NODE_PROPERTIES(vReturnCoord, iDensity, iPropertyFlags)
// if it is a highway node apply the central reservation
IF NOT ((iPropertyFlags & ENUM_TO_INT(VNP_HIGHWAY)) = 0)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ** GET_VEHICLE_NODE_PROPERTIES : VNP_HIGHWAY - applying central reservation")
offsetToKerb += (0.9 * centralReservationWidth)
ENDIF
// if its on a non-big vehicle road reduce by 0.5
IF NOT ((iPropertyFlags & ENUM_TO_INT(VNP_NO_BIG_VEHICLES)) = 0)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ** GET_VEHICLE_NODE_PROPERTIES : VNP_NO_BIG_VEHICLES - offsetToKerb reduced by 0.7")
offsetToKerb += -0.7
ENDIF
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ** GET_VEHICLE_NODE_PROPERTIES failed!")
ENDIF
ENDIF
ENDIF
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ** final offsetToKerb = ", offsetToKerb)
/*IF (VDIST(GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(vReturnCoord, fReturnHeading, <<offsetToKerb,0,0>> ), DestinationCoord) >
VDIST(GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(vReturnCoord, fReturnHeading, <<-offsetToKerb,0,0>> ), DestinationCoord))
offsetToKerb = -offsetToKerb
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : reversed kerb offset! offsetToKerb = ", offsetToKerb)
ENDIF*/
// map waypoints always set vector z value to 1 so in this instance ignore the height check
//IF DestinationCoord.z = 1
// DestinationCoord.z = vReturnCoord.z
// CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PULL_IN_SPOT_NEAR_COORDS() : DestinationCoord.z = 1 so forced to use vReturnCoord.z = ", DestinationCoord.z)
//ENDIF
// Bug fix B*1245895 - check was returning FALSE for coords with same/similar Z value
fTempZDiff = DestinationCoord.z - vReturnCoord.z
IF fTempZDiff < 0.0
fTempZDiff *= -1.0
ENDIF
IF IS_COORD_ON_SAME_LEVEL_AS_COORD(DestinationCoord, vReturnCoord)
OR (fTempZDiff < 0.5) // Bug fix B*1245895 - check was returning FALSE for coords with same/similar Z value
OR IS_BLIP_WAYPOINT_BLIP(blipDestination) // Bug fix url:bugstar:6541981 - [SP] Extreme 4 - Player was seen falling from the sky after travelling to Dom's blip at Land act Reservoir via cab.
vReturnCoord = GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(vReturnCoord, fReturnHeading, <<offsetToKerb,0,0>>)
IF IS_VEHICLE_DRIVEABLE(vehIndexTaxi)
entityPointObsuredCheck = vehIndexTaxi
ENDIF
//check the position isn't obsured
IF NOT IS_POINT_OBSCURED_BY_A_MISSION_ENTITY(vReturnCoord, <<3,3,3>>, entityPointObsuredCheck)
#IF IS_DEBUG_BUILD
// Spoke with JMart the taxi pathfinding doesn't actually care about GPS being allowed so don't fail the search for GPS not be allowed
IF NOT GET_VEHICLE_NODE_IS_GPS_ALLOWED(tempVehNodeID)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PULL_IN_SPOT_NEAR_COORDS() : node GPS not allowed")
ENDIF
// Since we are now using switched off nodes in the searrch don't fail the search for the selected node being switched off
IF NOT GET_VEHICLE_NODE_IS_SWITCHED_OFF(tempVehNodeID)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PULL_IN_SPOT_NEAR_COORDS() : node is switched off")
ENDIF
#ENDIF
// B*1383513 - need to test the generated spawn point isn't inside a special area
IF ARE_COORDS_IN_SPECIAL_AREA(vReturnCoord, vReturnCoord, fReturnHeading)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PULL_IN_SPOT_NEAR_COORDS() : secondary ARE_COORDS_IN_SPECIAL_AREA() check return TRUE, updated : ",
" vReturnCoord = ", vReturnCoord, " fReturnHeading = ", fReturnHeading)
ENDIF
bFoundSuitableCoords = TRUE
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PULL_IN_SPOT_NEAR_COORDS() : IS_POINT_OBSCURED_BY_A_MISSION_ENTITY() return TRUE, bFoundSuitableNode = FALSE")
ENDIF
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PULL_IN_SPOT_NEAR_COORDS() : IS_COORD_ON_SAME_LEVEL_AS_COORD return FALSE")
ENDIF
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PULL_IN_SPOT_NEAR_COORDS() : GET_CLOSEST_ROAD return FALSE")
ENDIF
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PULL_IN_SPOT_NEAR_COORDS() : IS_VEHICLE_NODE_ID_VALID return FALSE")
ENDIF
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PULL_IN_SPOT_NEAR_COORDS() : GET_NTH_CLOSEST_VEHICLE_NODE_WITH_HEADING return FALSE so iDesinationNodeSearchNumber++")
ENDIF
iReturnedNodeNumber++
// fail safe, don't test past iMaxNodeLoopChecksInTotal
IF (iReturnedNodeNumber >= iMaxNodeLoopChecksInTotal) // don't search past this amount)
vReturnCoord = DestinationCoord
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " ****** : GET_TAXI_PULL_IN_SPOT_NEAR_COORDS() : iReturnedNodeNumber = ", iReturnedNodeNumber, " reached max check amount! bFoundSuitableCoords forced TRUE",
" vReturnCoord = ", vReturnCoord, " just using DestinationCoord, FC = ", GET_FRAME_COUNT())
// B*2027407 - if node generating fails and we fall back to the blip's position ensure for custom waypoint blips we update the Z (since these are always 1.0 which is underground)
IF vReturnCoord.z = 1.0
fTempZDiff = 1.0
fTempZDiff = GET_APPROX_FLOOR_FOR_AREA((vReturnCoord.x - 2.0), (vReturnCoord.y - 2.0), (vReturnCoord.x + 2.0), (vReturnCoord.y + 2.0))
// found valid Z height
IF fTempZDiff > 1.0
bUsedFloorZ = TRUE
vReturnCoord.z = fTempZDiff
vReturnCoord.z += 0.5 // additional leeway - if we skip it will use SET_VEHICLE_ON_GROUND_PROPERLY()
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " ****** : GET_TAXI_PULL_IN_SPOT_NEAR_COORDS() : updated Z for custom waypoint position using approx floor check fTempZDiff : ", fTempZDiff, " vReturnCoord.z += 5.0 : ", vReturnCoord.z)
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " ****** : GET_TAXI_PULL_IN_SPOT_NEAR_COORDS() : FAILED update Z for custom waypoint position using approx floor check")
ENDIF
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " ****** : GET_TAXI_PULL_IN_SPOT_NEAR_COORDS() : vReturnCoord.z != 1 so skipping Z value update")
ENDIF
bFoundSuitableCoords = TRUE
ELSE
// debug print to show reached frame loop limit
#IF IS_DEBUG_BUILD
IF (iReturnedNodeNumber >= iMaxNodeLoopChecksPerFrame)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " ****** : GET_TAXI_PULL_IN_SPOT_NEAR_COORDS() : iReturnedNodeNumber = ", iReturnedNodeNumber, " reached max loop check amount ", iMaxNodeLoopChecksPerFrame, " this frame FC = ", GET_FRAME_COUNT())
ENDIF
#ENDIF
ENDIF
ENDWHILE
IF bFoundSuitableCoords
vec1 = DestinationCoord - vReturnCoord
vec1.z = 0.0
fDropOffDistFromBlip = VMAG(vec1)
IF fDropOffDistFromBlip <> 0 // For compiler
ENDIF
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PULL_IN_SPOT_NEAR_COORDS() : returning TRUE for vReturnCoord = ", vReturnCoord,
" fReturnHeading = ", fReturnHeading, " fDropOffDistFromBlip = ", fDropOffDistFromBlip, " iReturnedNodeNumber = ", iReturnedNodeNumber)
RETURN TRUE
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PULL_IN_SPOT_NEAR_COORDS() : returning FALSE")
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// return the SP_MISSION for the specified blip if it's active
/// NOTE: doesn't check the blip is valid
/// RETURNS:
/// TRUE if blip is active SP_MISSION
#IF USE_CLF_DLC
FUNC SP_MISSIONS GET_BLIPS_ACTIVE_STORY_MISSION_CLF(BLIP_INDEX &blipIndex)
INT iTriggerIndex
REPEAT MAX_MISSION_TRIGGERS_TU iTriggerIndex
IF g_TriggerableMissionsTU[iTriggerIndex].bUsed
// B*1538996 - array overrun safeguard - inactive blips are being set to STATIC_BLIP_NAME_DUMMY_FINAL which happens to be max array size
IF g_TriggerableMissionsTU[iTriggerIndex].eBlip != STATIC_BLIP_NAME_DUMMY_FINAL
IF DOES_BLIP_EXIST(g_GameBlips[g_TriggerableMissionsTU[iTriggerIndex].eBlip].biBlip)
IF g_GameBlips[g_TriggerableMissionsTU[iTriggerIndex].eBlip].biBlip = blipIndex
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_BLIPS_ACTIVE_STORY_MISSION_CLF return :", g_TriggerableMissionsTU[iTriggerIndex].eMissionID)
RETURN g_TriggerableMissionsTU[iTriggerIndex].eMissionID
ENDIF
ENDIF
ENDIF
ENDIF
ENDREPEAT
RETURN SP_MISSION_NONE
ENDFUNC
#ENDIF
#IF USE_NRM_DLC
FUNC SP_MISSIONS GET_BLIPS_ACTIVE_STORY_MISSION_NRM(BLIP_INDEX &blipIndex)
INT iTriggerIndex
REPEAT MAX_MISSION_TRIGGERS_TU iTriggerIndex
IF g_TriggerableMissionsTU[iTriggerIndex].bUsed
// B*1538996 - array overrun safeguard - inactive blips are being set to STATIC_BLIP_NAME_DUMMY_FINAL which happens to be max array size
IF g_TriggerableMissionsTU[iTriggerIndex].eBlip != STATIC_BLIP_NAME_DUMMY_FINAL
IF DOES_BLIP_EXIST(g_GameBlips[g_TriggerableMissionsTU[iTriggerIndex].eBlip].biBlip)
IF g_GameBlips[g_TriggerableMissionsTU[iTriggerIndex].eBlip].biBlip = blipIndex
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_BLIPS_ACTIVE_STORY_MISSION_NRM return :", g_TriggerableMissionsTU[iTriggerIndex].eMissionID)
RETURN g_TriggerableMissionsTU[iTriggerIndex].eMissionID
ENDIF
ENDIF
ENDIF
ENDIF
ENDREPEAT
RETURN SP_MISSION_NONE
ENDFUNC
#ENDIF
FUNC SP_MISSIONS GET_BLIPS_ACTIVE_STORY_MISSION(BLIP_INDEX &blipIndex)
#IF USE_CLF_DLC
RETURN SP_MISSIONS GET_BLIPS_ACTIVE_STORY_MISSION_CLF(blipIndex)
#ENDIF
#IF USE_NRM_DLC
RETURN SP_MISSIONS GET_BLIPS_ACTIVE_STORY_MISSION_CLF(blipIndex)
#ENDIF
#IF NOT USE_CLF_DLC
#IF NOT USE_NRM_DLC
INT iTriggerIndex
REPEAT MAX_MISSION_TRIGGERS iTriggerIndex
IF g_TriggerableMissions[iTriggerIndex].bUsed
// B*1538996 - array overrun safeguard - inactive blips are being set to STATIC_BLIP_NAME_DUMMY_FINAL which happens to be max array size
IF g_TriggerableMissions[iTriggerIndex].eBlip != STATIC_BLIP_NAME_DUMMY_FINAL
IF DOES_BLIP_EXIST(g_GameBlips[g_TriggerableMissions[iTriggerIndex].eBlip].biBlip)
IF g_GameBlips[g_TriggerableMissions[iTriggerIndex].eBlip].biBlip = blipIndex
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_BLIPS_ACTIVE_STORY_MISSION return :", g_TriggerableMissions[iTriggerIndex].eMissionID)
RETURN g_TriggerableMissions[iTriggerIndex].eMissionID
ENDIF
ENDIF
ENDIF
ENDIF
ENDREPEAT
RETURN SP_MISSION_NONE
#ENDIF
#ENDIF
ENDFUNC
/// PURPOSE:
/// get the cloest active story mission to the vTestCoords
/// PARAMS:
/// vTestCoords - position to check from
/// ReturnMission - the returned closest mission else SP_MISSION_NONE
/// fReturnDistance - the returned distance of the closest active mission
/// RETURNS:
/// If unable to find mission SP_MISSION_NONE will return, else valid SP_MISSIONS
#IF USE_CLF_DLC
FUNC BOOL GET_CLOSEST_ACTIVE_STORY_MISSION_CLF(VECTOR &vTestCoords, SP_MISSIONS &eReturnMission, FLOAT &fReturnDistance)
INT iClosestMission = -1
FLOAT fClosestDist = 999999
FLOAT fDist
VECTOR vTemp
INT iTriggerIndex
REPEAT MAX_MISSION_TRIGGERS_TU iTriggerIndex
IF g_TriggerableMissionsTU[iTriggerIndex].bUsed
// B*1538996 - array overrun safeguard - inactive blips are being set to STATIC_BLIP_NAME_DUMMY_FINAL which happens to be max array size
IF g_TriggerableMissionsTU[iTriggerIndex].eBlip != STATIC_BLIP_NAME_DUMMY_FINAL
IF DOES_BLIP_EXIST(g_GameBlips[g_TriggerableMissionsTU[iTriggerIndex].eBlip].biBlip)
// custom waypoints z height always gets set to 1.0 so make even playing field for these dist checks otherwise they won't work
vTemp = GET_BLIP_COORDS(g_GameBlips[g_TriggerableMissionsTU[iTriggerIndex].eBlip].biBlip)
IF vTestCoords.z = 1.0
vTemp.z = 1.0
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_CLOSEST_ACTIVE_STORY_MISSION_CLF updated mission coord Z for waypoint check : ", vTemp)
ENDIF
fDist = VDIST(vTestCoords, vTemp)
IF fDist < fClosestDist
IF fDist < g_TriggerableMissionsTU[iTriggerIndex].sScene.fLoadDistance
fClosestDist = fDist
iClosestMission = iTriggerIndex
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_CLOSEST_ACTIVE_STORY_MISSION_CLF updated iClosestMission = ", iClosestMission)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDREPEAT
IF iClosestMission != -1
fReturnDistance = fClosestDist
eReturnMission = g_TriggerableMissionsTU[iClosestMission].eMissionID
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_CLOSEST_ACTIVE_STORY_MISSION_CLF return TRUE valid mission found eReturnMission : ", eReturnMission)
RETURN TRUE
ENDIF
eReturnMission = SP_MISSION_NONE
fReturnDistance = 999999
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_CLOSEST_ACTIVE_STORY_MISSION_CLF return FALSE no valid mission found eReturnMission : ", eReturnMission)
RETURN FALSE
ENDFUNC
#ENDIF
#IF USE_NRM_DLC
FUNC BOOL GET_CLOSEST_ACTIVE_STORY_MISSION_NRM(VECTOR &vTestCoords, SP_MISSIONS &eReturnMission, FLOAT &fReturnDistance)
INT iClosestMission = -1
FLOAT fClosestDist = 999999
FLOAT fDist
VECTOR vTemp
INT iTriggerIndex
REPEAT MAX_MISSION_TRIGGERS_TU iTriggerIndex
IF g_TriggerableMissionsTU[iTriggerIndex].bUsed
// B*1538996 - array overrun safeguard - inactive blips are being set to STATIC_BLIP_NAME_DUMMY_FINAL which happens to be max array size
IF g_TriggerableMissionsTU[iTriggerIndex].eBlip != STATIC_BLIP_NAME_DUMMY_FINAL
IF DOES_BLIP_EXIST(g_GameBlips[g_TriggerableMissionsTU[iTriggerIndex].eBlip].biBlip)
// custom waypoints z height always gets set to 1.0 so make even playing field for these dist checks otherwise they won't work
vTemp = GET_BLIP_COORDS(g_GameBlips[g_TriggerableMissionsTU[iTriggerIndex].eBlip].biBlip)
IF vTestCoords.z = 1.0
vTemp.z = 1.0
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_CLOSEST_ACTIVE_STORY_MISSION_NRM updated mission coord Z for waypoint check : ", vTemp)
ENDIF
fDist = VDIST(vTestCoords, vTemp)
IF fDist < fClosestDist
IF fDist < g_TriggerableMissionsTU[iTriggerIndex].sScene.fLoadDistance
fClosestDist = fDist
iClosestMission = iTriggerIndex
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_CLOSEST_ACTIVE_STORY_MISSION_NRM updated iClosestMission = ", iClosestMission)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDREPEAT
IF iClosestMission != -1
fReturnDistance = fClosestDist
eReturnMission = g_TriggerableMissionsTU[iClosestMission].eMissionID
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_CLOSEST_ACTIVE_STORY_MISSION_NRM return TRUE valid mission found eReturnMission : ", eReturnMission)
RETURN TRUE
ENDIF
eReturnMission = SP_MISSION_NONE
fReturnDistance = 999999
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_CLOSEST_ACTIVE_STORY_MISSION_NRM return FALSE no valid mission found eReturnMission : ", eReturnMission)
RETURN FALSE
ENDFUNC
#ENDIF
FUNC BOOL GET_CLOSEST_ACTIVE_STORY_MISSION(VECTOR &vTestCoords, SP_MISSIONS &eReturnMission, FLOAT &fReturnDistance)
#IF USE_CLF_DLC
RETURN GET_CLOSEST_ACTIVE_STORY_MISSION_CLF(vTestCoords, eReturnMission, fReturnDistance)
#ENDIF
#IF USE_NRM_DLC
RETURN GET_CLOSEST_ACTIVE_STORY_MISSION_NRM(vTestCoords, eReturnMission, fReturnDistance)
#ENDIF
#IF NOT USE_CLF_DLC
#IF NOT USE_NRM_DLC
INT iClosestMission = -1
FLOAT fClosestDist = 999999
FLOAT fDist
VECTOR vTemp
INT iTriggerIndex
REPEAT MAX_MISSION_TRIGGERS iTriggerIndex
IF g_TriggerableMissions[iTriggerIndex].bUsed
// B*1538996 - array overrun safeguard - inactive blips are being set to STATIC_BLIP_NAME_DUMMY_FINAL which happens to be max array size
IF g_TriggerableMissions[iTriggerIndex].eBlip != STATIC_BLIP_NAME_DUMMY_FINAL
IF DOES_BLIP_EXIST(g_GameBlips[g_TriggerableMissions[iTriggerIndex].eBlip].biBlip)
// custom waypoints z height always gets set to 1.0 so make even playing field for these dist checks otherwise they won't work
vTemp = GET_BLIP_COORDS(g_GameBlips[g_TriggerableMissions[iTriggerIndex].eBlip].biBlip)
IF vTestCoords.z = 1.0
vTemp.z = 1.0
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_CLOSEST_ACTIVE_STORY_MISSION updated mission coord Z for waypoint check : ", vTemp)
ENDIF
fDist = VDIST(vTestCoords, vTemp)
IF fDist < fClosestDist
IF fDist < g_TriggerableMissions[iTriggerIndex].sScene.fLoadDistance
fClosestDist = fDist
iClosestMission = iTriggerIndex
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_CLOSEST_ACTIVE_STORY_MISSION updated iClosestMission = ", iClosestMission)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDREPEAT
IF iClosestMission != -1
fReturnDistance = fClosestDist
eReturnMission = g_TriggerableMissions[iClosestMission].eMissionID
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_CLOSEST_ACTIVE_STORY_MISSION return TRUE valid mission found eReturnMission : ", eReturnMission)
RETURN TRUE
ENDIF
eReturnMission = SP_MISSION_NONE
fReturnDistance = 999999
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_CLOSEST_ACTIVE_STORY_MISSION return FALSE no valid mission found eReturnMission : ", eReturnMission)
RETURN FALSE
#ENDIF
#ENDIF
ENDFUNC
FUNC EnumCharacterList Get_Player_Director_Mode_Compatible()
IF IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR)
//the player enum isn't returned correctly in Director mode, so we go for an explicit model check.
IF NOT IS_ENTITY_DEAD (PLAYER_PED_ID())
IF GET_ENTITY_MODEL(PLAYER_PED_ID()) = g_savedGlobals.sCharSheetData.g_CharacterSheet[CHAR_MICHAEL].game_model //Check the explicit model from the character sheet.
RETURN CHAR_MICHAEL
ELIF GET_ENTITY_MODEL(PLAYER_PED_ID()) = g_savedGlobals.sCharSheetData.g_CharacterSheet[CHAR_FRANKLIN].game_model
RETURN CHAR_FRANKLIN
ELIF GET_ENTITY_MODEL(PLAYER_PED_ID()) = g_savedGlobals.sCharSheetData.g_CharacterSheet[CHAR_TREVOR].game_model
RETURN CHAR_TREVOR
ELSE
RETURN CHAR_MULTIPLAYER //Default to Multiplayer phone as a failsafe. PI_Menu doesn't look to be checking for anyone outwith the standard three SP playable flow characters.
ENDIF
ELSE
RETURN CHAR_MULTIPLAYER
ENDIF
ELSE
//Not in Director Mode, safe to just go ahead with the standard player enum retrieval process.
RETURN GET_CURRENT_PLAYER_PED_ENUM()
ENDIF
ENDFUNC
/// PURPOSE:
/// get the cloest active story mission to the vTestCoords
/// PARAMS:
/// vTestCoords - position to check from
/// eReturnRCM - the returned closest RCM else NO_RC_MISSION
/// fReturnDistance - the returned distance of the closest active mission
/// RETURNS:
/// If unable to find mission SP_MISSION_NONE will return, else valid SP_MISSIONS
FUNC BOOL GET_CLOSEST_ACTIVE_RC_MISSION(VECTOR &vTestCoords, g_eRC_MissionIDs &eReturnRCM, FLOAT &fReturnDistance)
INT iClosestRCM = -1
FLOAT fClosestDist = 999999
FLOAT fDist
VECTOR vTemp
INT iIndex = 0
g_structRCMissionsStatic sRCMissionDetails
REPEAT MAX_RC_MISSIONS iIndex
eReturnRCM = INT_TO_ENUM(g_eRC_MissionIDs, iIndex)
// RC mission is ready to activate
IF (IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[ENUM_TO_INT(eReturnRCM)].rcFlags, ENUM_TO_INT(RC_FLAG_ACTIVATED)))
AND NOT (IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[ENUM_TO_INT(eReturnRCM)].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED)))
// Get the RCM information
Retrieve_Random_Character_Static_Mission_Details(eReturnRCM, sRCMissionDetails)
// ensure the RCM is triggerable by the current player Char
IF IS_BIT_SET(sRCMissionDetails.rcPlayableChars, ENUM_TO_INT(Get_Player_Director_Mode_Compatible()))
// custom waypoints z height always gets set to 1.0 so make even playing field for these dist checks otherwise they won't work
vTemp = sRCMissionDetails.rcCoords
IF vTestCoords.z = 1.0
vTemp.z = 1.0
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_CLOSEST_ACTIVE_RC_MISSION updated mission coord Z for waypoint check : ", vTemp)
ENDIF
fDist = VDIST(vTestCoords, vTemp)
IF fDist < fClosestDist
IF fDist < RC_BRAIN_ACTIVATION_RANGE_EXTRA
fClosestDist = fDist
iClosestRCM = iIndex
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_CLOSEST_ACTIVE_RC_MISSION updated iClosestRCM = ", iClosestRCM, " Name : ", sRCMissionDetails.tRCNameLabel)
ENDIF
ENDIF
ELSE
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_CLOSEST_ACTIVE_RC_MISSION rcm not triggered by current player char iClosestRCM = ", iClosestRCM, " Name : ", sRCMissionDetails.tRCNameLabel)
ENDIF
ENDIF
ENDREPEAT
IF iClosestRCM != -1
fReturnDistance = fClosestDist
eReturnRCM = INT_TO_ENUM(g_eRC_MissionIDs, iClosestRCM)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_CLOSEST_ACTIVE_RC_MISSION return TRUE valid mission found eReturnRCM : ", eReturnRCM)
RETURN TRUE
ENDIF
eReturnRCM = NO_RC_MISSION
fReturnDistance = 999999
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_CLOSEST_ACTIVE_RC_MISSION return FALSE no valid mission found eReturnRCM : ", eReturnRCM)
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// //block some minigames for now as not sure on knockons around mission blips
/// PARAMS:
/// eBlipReturnMinigame - minigame blip
/// RETURNS:
/// TRUE if allowed to grab as closest active
FUNC BOOL IS_MINIGAME_BLIP_DROP_OFF_TYPE_SUPPORTED(STATIC_BLIP_NAME_ENUM &eBlipReturnMinigame)
IF eBlipReturnMinigame = STATIC_BLIP_MINIGAME_OFFROAD_RACE5
OR eBlipReturnMinigame = STATIC_BLIP_MINIGAME_OFFROAD_RACE8
OR eBlipReturnMinigame = STATIC_BLIP_MINIGAME_OFFROAD_RACE9
OR eBlipReturnMinigame = STATIC_BLIP_MINIGAME_OFFROAD_RACE10
OR eBlipReturnMinigame = STATIC_BLIP_MINIGAME_OFFROAD_RACE11
OR eBlipReturnMinigame = STATIC_BLIP_MINIGAME_OFFROAD_RACE12
OR eBlipReturnMinigame = STATIC_BLIP_MINIGAME_PILOT_SCHOOL
OR eBlipReturnMinigame = STATIC_BLIP_MINIGAME_TRAF_AIR
OR eBlipReturnMinigame = STATIC_BLIP_MINIGAME_TRAF_GND
OR eBlipReturnMinigame = STATIC_BLIP_AMBIENT_BASEJUMP_HARBOR
OR eBlipReturnMinigame = STATIC_BLIP_AMBIENT_BASEJUMP_RACE_TRACK
OR eBlipReturnMinigame = STATIC_BLIP_AMBIENT_BASEJUMP_WINDMILLS
OR eBlipReturnMinigame = STATIC_BLIP_AMBIENT_BASEJUMP_NORTH_CLIFF
OR eBlipReturnMinigame = STATIC_BLIP_AMBIENT_BASEJUMP_MAZE_BANK
//OR eBlipReturnMinigame = STATIC_BLIP_AMBIENT_BASEJUMP_CRANE // not needed
OR eBlipReturnMinigame = STATIC_BLIP_AMBIENT_BASEJUMP_RIVER_CLIFF
OR eBlipReturnMinigame = STATIC_BLIP_AMBIENT_BASEJUMP_RUNAWAY_TRAIN
//OR eBlipReturnMinigame = STATIC_BLIP_AMBIENT_BASEJUMP_GOLF_COURSE // not needed
OR eBlipReturnMinigame = STATIC_BLIP_AMBIENT_BASEJUMP_1K
OR eBlipReturnMinigame = STATIC_BLIP_AMBIENT_BASEJUMP_1_5K
OR eBlipReturnMinigame = STATIC_BLIP_AMBIENT_BASEJUMP_CANAL
//OR eBlipReturnMinigame = STATIC_BLIP_AMBIENT_BASEJUMP_ROCK_CLIFF // not needed
OR eBlipReturnMinigame = STATIC_BLIP_MINIGAME_TRIATHLON1 // B*1861605 - triathlon vespucci
OR eBlipReturnMinigame = STATIC_BLIP_MINIGAME_COUNTRY_RACE
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// get the cloest active minigame blip to the vTestCoords
/// PARAMS:
/// vTestCoords - position to check from
/// eReturnRCM - the returned closest STATIC_BLIP_NAME_ENUM else STATIC_BLIP_NAME_DUMMY_FINAL
/// fReturnDistance - the returned distance of the closest active mission
/// RETURNS:
/// If unable to find active minigame STATIC_BLIP_NAME_DUMMY_FINAL will return, else valid STATIC_BLIP_NAME_ENUM
FUNC BOOL GET_CLOSEST_ACTIVE_MINIGAME_BLIP(VECTOR &vTestCoords, STATIC_BLIP_NAME_ENUM &eBlipReturnMinigame, FLOAT &fReturnDistance)
STATIC_BLIP_NAME_ENUM eBlipClosestMinigame = STATIC_BLIP_NAME_DUMMY_FINAL
FLOAT fClosestDist = 999999
FLOAT fDist
INT iIndex
VECTOR vTemp
// minigames
FOR iIndex = ENUM_TO_INT(STATIC_BLIP_MINIGAME_COUNTRY_RACE) TO ENUM_TO_INT(STATIC_BLIP_MINIGAME_YOGA2) // last minigame in the list
eBlipReturnMinigame = INT_TO_ENUM(STATIC_BLIP_NAME_ENUM, iIndex)
//block some minigames for now as not sure on knockons around mission blips
IF IS_MINIGAME_BLIP_DROP_OFF_TYPE_SUPPORTED(eBlipReturnMinigame)
// if the blip is on the map check it
IF IS_STATIC_BLIP_CURRENTLY_VISIBLE(eBlipReturnMinigame)
// custom waypoints z height always gets set to 1.0 so make even playing field for these dist checks otherwise they won't work
vTemp = GET_STATIC_BLIP_POSITION(eBlipReturnMinigame)
IF vTestCoords.z = 1.0
vTemp.z = 1.0
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_CLOSEST_ACTIVE_MINIGAME_BLIP updated blip Z pos for waypoint check : ", vTemp)
ENDIF
fDist = VDIST(vTestCoords, vTemp)
IF fDist < fClosestDist
IF fDist < MINIGAME_LOAD_RANGE
fClosestDist = fDist
eBlipClosestMinigame = eBlipReturnMinigame
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_CLOSEST_ACTIVE_MINIGAME_BLIP updated eBlipClosestMinigame = ", eBlipClosestMinigame, " DEBUG_GET_STRING_NAME_OF_STATIC_BLIP : ", DEBUG_GET_STRING_NAME_OF_STATIC_BLIP(iIndex))
ENDIF
ENDIF
ELSE
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_CLOSEST_ACTIVE_MINIGAME_BLIP blip not visible eBlipClosestMinigame = ", eBlipClosestMinigame, " DEBUG_GET_STRING_NAME_OF_STATIC_BLIP : ", DEBUG_GET_STRING_NAME_OF_STATIC_BLIP(iIndex))
ENDIF
ELSE
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_CLOSEST_ACTIVE_MINIGAME_BLIP blip not currently supported eBlipClosestMinigame = ", eBlipClosestMinigame, " DEBUG_GET_STRING_NAME_OF_STATIC_BLIP : ", DEBUG_GET_STRING_NAME_OF_STATIC_BLIP(iIndex))
ENDIF
ENDFOR
// cycle through the basejumps (blips listed seperate from the rest of the minigames)
FOR iIndex = ENUM_TO_INT(STATIC_BLIP_AMBIENT_BASEJUMP_HARBOR) TO ENUM_TO_INT(STATIC_BLIP_AMBIENT_BASEJUMP_ROCK_CLIFF) // last basejump in the list
eBlipReturnMinigame = INT_TO_ENUM(STATIC_BLIP_NAME_ENUM, iIndex)
//block some minigames for now as not sure on knockons around mission blips
IF IS_MINIGAME_BLIP_DROP_OFF_TYPE_SUPPORTED(eBlipReturnMinigame)
// if the blip is on the map check it
IF IS_STATIC_BLIP_CURRENTLY_VISIBLE(eBlipReturnMinigame)
// custom waypoints z height always gets set to 1.0 so make even playing field for these dist checks otherwise they won't work
vTemp = GET_STATIC_BLIP_POSITION(eBlipReturnMinigame)
IF vTestCoords.z = 1.0
vTemp.z = 1.0
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_CLOSEST_ACTIVE_MINIGAME_BLIP updated blip Z pos for waypoint check : ", vTemp)
ENDIF
fDist = VDIST(vTestCoords, vTemp)
IF fDist < fClosestDist
IF fDist < MINIGAME_LOAD_RANGE
fClosestDist = fDist
eBlipClosestMinigame = eBlipReturnMinigame
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_CLOSEST_ACTIVE_MINIGAME_BLIP updated eBlipClosestMinigame = ", eBlipClosestMinigame, " DEBUG_GET_STRING_NAME_OF_STATIC_BLIP : ", DEBUG_GET_STRING_NAME_OF_STATIC_BLIP(iIndex))
ENDIF
ENDIF
ELSE
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_CLOSEST_ACTIVE_MINIGAME_BLIP blip not visible eBlipClosestMinigame = ", eBlipClosestMinigame, " DEBUG_GET_STRING_NAME_OF_STATIC_BLIP : ", DEBUG_GET_STRING_NAME_OF_STATIC_BLIP(iIndex))
ENDIF
ELSE
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_CLOSEST_ACTIVE_MINIGAME_BLIP blip not currently supported eBlipClosestMinigame = ", eBlipClosestMinigame, " DEBUG_GET_STRING_NAME_OF_STATIC_BLIP : ", DEBUG_GET_STRING_NAME_OF_STATIC_BLIP(iIndex))
ENDIF
ENDFOR
IF eBlipClosestMinigame != STATIC_BLIP_NAME_DUMMY_FINAL
eBlipReturnMinigame = eBlipClosestMinigame
fReturnDistance = fClosestDist
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_CLOSEST_ACTIVE_MINIGAME_BLIP return TRUE valid minigame found eBlipReturnMinigame : ", eBlipReturnMinigame)
RETURN TRUE
ENDIF
eBlipReturnMinigame = STATIC_BLIP_NAME_DUMMY_FINAL
fReturnDistance = 999999
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_CLOSEST_ACTIVE_MINIGAME_BLIP return FALSE no valid minigame found at position : ", vTestCoords)
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// check if the vTestCoords are within a specified mission's trigger area
/// NOTE : custom waypoints placed on the map don't take Z value into account they always default to 1.0 so we need to make the value suitable for the check
/// PARAMS:
/// eSP_Mission - mission to test
/// vTestCoords - coords to test
/// RETURNS:
/// TRUE if coords are inside mission trigger area
FUNC BOOL ARE_COORDS_IN_SPECIFIC_SP_MISSION_TRIGGER_AREA(SP_MISSIONS eSP_Mission, VECTOR vTestCoords)
SWITCH eSP_Mission
CASE SP_MISSION_ASSASSIN_1
// Lester sat on park bench near beach front
IF vTestCoords.Z = 1.0
vTestCoords.Z = 7.0
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<-1535.754028,-922.100952,4.122119>>, <<-1487.869507,-961.392883,26.719219>>, 50.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_SP_MISSION_TRIGGER_AREA return TRUE for SP_MISSION_ASSASSIN_1")
RETURN TRUE
ENDIF
BREAK
CASE SP_MISSION_CARSTEAL_1
// Construction yard - covers nearly all of it with except of a strip near the South edge
IF vTestCoords.Z = 1.0
vTestCoords.Z = 40.0
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<53.128983,-463.999908,36.920799>>, <<99.376099,-329.347626,118.045418>>, 125.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_SP_MISSION_TRIGGER_AREA return TRUE for SP_MISSION_CARSTEAL_1")
RETURN TRUE
ENDIF
BREAK
CASE SP_MISSION_FBI_4_INTRO
FALLTHRU
CASE SP_MISSION_FBI_4
// FIB 4 - meet up in lot El Burro Heights - New Empire Way
IF vTestCoords.Z = 1.0
vTestCoords.Z = 51.0214
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<1420.347290,-2036.557739,47.360718>>, <<1341.110474,-2103.843750,72.326508>>, 55.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_SP_MISSION_TRIGGER_AREA return TRUE for SP_MISSION_FBI_4")
RETURN TRUE
ENDIF
BREAK
CASE SP_MISSION_FRANKLIN_1
FALLTHRU
CASE SP_MISSION_MICHAEL_2
IF vTestCoords.Z = 1.0
vTestCoords.Z = 51.0214
ENDIF
// at Franklin's house (default special area coords auto launch the mission)
IF VDIST2(vTestCoords, << -13.89061, -1449.28967, 29.64636 >>) < (36.0 * 36.0)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_SP_MISSION_TRIGGER_AREA return TRUE for SP_MISSION_FRANKLIN_1 / SP_MISSION_MICHAEL_2")
RETURN TRUE
ENDIF
BREAK
CASE SP_MISSION_MICHAEL_3
IF vTestCoords.Z = 1.0
vTestCoords.Z = 173.47
ENDIF
// at Kortz museum entrance
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<-2306.980225,435.303772,171.466568>>, <<-2303.291016,366.319946,179.601761>>, 65.5)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_SP_MISSION_TRIGGER_AREA return TRUE for SP_MISSION_MICHAEL_3")
RETURN TRUE
ENDIF
BREAK
CASE SP_MISSION_MARTIN_1
// Martin's ranch (also could be used off mission)
IF vTestCoords.Z = 1.0
vTestCoords.Z = 114.0
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<1324.171509,1110.747925,99.654930>>, <<1523.096802,1110.473389,132.885864>>, 170.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_SP_MISSION_TRIGGER_AREA return TRUE for SP_MISSION_MARTIN_1")
RETURN TRUE
ENDIF
BREAK
CASE SP_MISSION_FINALE_A
IF vTestCoords.Z = 1.0
vTestCoords.Z = 46.0
ENDIF
IF VDIST2(vTestCoords, <<1330.3890, -2553.7439, 45.9221>>) < (30.0 * 30.0)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_SP_MISSION_TRIGGER_AREA return TRUE for SP_MISSION_FINALE_A")
RETURN TRUE
ENDIF
BREAK
CASE SP_MISSION_SOLOMON_2
IF vTestCoords.Z = 1.0
vTestCoords.Z = 34.5
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<-995.977966,-517.432434,11.377625>>, <<-1060.725098,-547.558838,65.330429>>, 35.75)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_SP_MISSION_TRIGGER_AREA return TRUE for SP_MISSION_SOLOMON_2")
RETURN TRUE
ENDIF
BREAK
// Heists
CASE SP_HEIST_JEWELRY_1
IF vTestCoords.Z = 1.0
vTestCoords.Z = 23.18
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<682.654419,-968.743896,19.975750>>, <<762.868408,-964.406433,43.037125>>, 53.0)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_SP_MISSION_TRIGGER_AREA return TRUE for SP_HEIST_JEWELRY_1")
RETURN TRUE
ENDIF
BREAK
CASE SP_HEIST_JEWELRY_PREP_1A
IF vTestCoords.Z = 1.0
vTestCoords.Z = 5.0
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<148.836105,-3029.146484,4.277727>>, <<148.139572,-3342.343506,22.903791>>, 97.750000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_SP_MISSION_TRIGGER_AREA return TRUE for SP_HEIST_JEWELRY_PREP_1A")
RETURN TRUE
ENDIF
BREAK
CASE SP_HEIST_FINALE_PREP_A
IF vTestCoords.Z = 1.0
vTestCoords.Z = 28.1893
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<446.817413,-1691.708130,23.282328>>, <<288.556488,-1552.351807,108.311661>>, 155.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_SP_MISSION_TRIGGER_AREA return TRUE for SP_HEIST_FINALE_PREP_A")
RETURN TRUE
ENDIF
BREAK
CASE SP_HEIST_FINALE_PREP_B
IF vTestCoords.Z = 1.0
vTestCoords.Z = 28.1893
ENDIF
// area covering whole block where the compound is
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<910.938171,-1749.909668,14.506144>>, <<921.741455,-1455.247925,99.671249>>, 210.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_SP_MISSION_TRIGGER_AREA return TRUE for SP_HEIST_FINALE_PREP_B")
RETURN TRUE
ENDIF
BREAK
CASE SP_HEIST_FINALE_PREP_D
IF vTestCoords.Z = 1.0
vTestCoords.Z = 37.0
ENDIF
// area covering whole block where the compound is
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<2657.302490,2974.528564,34.534470>>, <<2591.656982,2880.223145,68.081558>>, 78.75)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_SP_MISSION_TRIGGER_AREA return TRUE for SP_HEIST_FINALE_PREP_D")
RETURN TRUE
ENDIF
BREAK
CASE SP_HEIST_FINALE_1
FALLTHRU
CASE SP_HEIST_FINALE_2A
IF vTestCoords.Z = 1.0
vTestCoords.Z = 28.0
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<83.323250,-1312.172241,23.336941>>, <<148.383026,-1273.553223,49.466507>>, 65.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_SP_MISSION_TRIGGER_AREA return TRUE for SP_HEIST_FINALE_1 / SP_HEIST_FINALE_2A")
RETURN TRUE
ENDIF
BREAK
ENDSWITCH
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_SP_MISSION_TRIGGER_AREA return FALSE for SP_MISSIONS ", eSP_Mission, " vTestCoords = ", vTestCoords)
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// get the custom drop off coords and heading for the specified SP mission
/// PARAMS:
/// eSP_Mission - mission to get custom drop off for
/// vReturnCoord - the returned drop off coords
/// fReturnHeading - the returned drop off heading
/// RETURNS:
/// TRUE if custom taxi drop off has been setup
FUNC BOOL GET_CUSTOM_TAXI_DROP_OFF_FOR_SP_MISSION(SP_MISSIONS eSP_Mission, VECTOR &vReturnCoord, FLOAT &fReturnHeading)
INT iVariation
SWITCH eSP_Mission
CASE SP_MISSION_ASSASSIN_1
vReturnCoord = <<-1456.3473, -962.5814, 6.3112>>
fReturnHeading = 140.57
RETURN TRUE
BREAK
CASE SP_MISSION_CARSTEAL_1
vReturnCoord = <<147.6034, -404.7993, 40.0892>> // on main road just North of entrance to the construction yard
fReturnHeading = 164.0206
RETURN TRUE
BREAK
CASE SP_MISSION_FBI_4_INTRO
FALLTHRU
CASE SP_MISSION_FBI_4
vReturnCoord = <<1361.6746, -2040.5747, 51.0214>> // on dust track just outside the lot (West of the entrance) facing East
fReturnHeading = 281.5022
RETURN TRUE
BREAK
CASE SP_MISSION_FRANKLIN_1 // at Franklin's house (default special area coords auto launch the mission)
FALLTHRU
CASE SP_MISSION_MICHAEL_2
iVariation = 2
SWITCH GET_RANDOM_INT_IN_RANGE(0, iVariation)
CASE 0 vReturnCoord = <<-43.9252, -1460.4318, 30.7052>> fReturnHeading = 104.5827 BREAK // West of the house heading West
CASE 1 vReturnCoord = <<14.0313, -1460.4801, 29.4397>> fReturnHeading = 61.9499 BREAK // East of the house heading West
ENDSWITCH
RETURN TRUE
BREAK
CASE SP_MISSION_MICHAEL_3
vReturnCoord = <<-2313.90, 450.90, 173.47>> // outside Kortz museum roundabout
fReturnHeading = 178.6132
RETURN TRUE
BREAK
CASE SP_MISSION_MARTIN_1
iVariation = 3
SWITCH GET_RANDOM_INT_IN_RANGE(0, iVariation)
CASE 0 vReturnCoord = <<1369.2460, 1147.6527, 112.7592>> fReturnHeading = 182.0998 BREAK // front of the steps of the house
CASE 1 vReturnCoord = <<1360.8483, 1139.1210, 112.7592>> fReturnHeading = 83.3356 BREAK // front of house offset to North
CASE 2 vReturnCoord = <<1364.7513, 1154.3668, 112.7592>> fReturnHeading = 223.2795 BREAK // front of house offset to South
ENDSWITCH
RETURN TRUE
BREAK
CASE SP_MISSION_FINALE_A
iVariation = 2
// SWITCH GET_RANDOM_INT_IN_RANGE(0, iVariation)
// CASE 0 vReturnCoord = <<1324.6177, -2596.7603, 46.5998>> fReturnHeading = 285.1668 BREAK // Other side of the road in the layby
vReturnCoord = <<1430.0966, -2588.0654, 47.0326>> fReturnHeading = 353.6747 // up road to east
// ENDSWITCH
RETURN TRUE
BREAK
CASE SP_MISSION_SOLOMON_2
vReturnCoord = <<-943.9154, -487.7569, 35.7331>> // Outside gate with most direct access to mission locate
fReturnHeading = 27.40
RETURN TRUE
BREAK
// Heists
CASE SP_HEIST_JEWELRY_1
vReturnCoord = <<764.6179, -972.5101, 24.9030>> // Just up the road from the warehouse
fReturnHeading = 162.2939
RETURN TRUE
BREAK
CASE SP_HEIST_JEWELRY_PREP_1A
vReturnCoord = <<185.1471, -3047.2285, 4.7824>> // Just up the road from the warehouse
fReturnHeading = 163.8686
RETURN TRUE
BREAK
CASE SP_HEIST_FINALE_PREP_A
iVariation = 2
SWITCH GET_RANDOM_INT_IN_RANGE(0, iVariation)
CASE 0 vReturnCoord = <<504.1742, -1652.4719, 28.1893>> fReturnHeading = 52.3367 BREAK // Across the junction tothe South East
CASE 1 vReturnCoord = <<275.9677, -1554.2201, 28.0311>> fReturnHeading = 303.3013 BREAK // Layby North West of the compound
ENDSWITCH
RETURN TRUE
BREAK
CASE SP_HEIST_FINALE_PREP_B
iVariation = 2
SWITCH GET_RANDOM_INT_IN_RANGE(0, iVariation)
CASE 0 vReturnCoord = <<853.9595, -1590.9219, 30.5996>> fReturnHeading = 7.1480 BREAK // South of the main entrance heading North
CASE 1 vReturnCoord = <<847.5631, -1559.7194, 28.7923>> fReturnHeading = 20.9650 BREAK // North of the main entrance heading North
ENDSWITCH
RETURN TRUE
BREAK
CASE SP_HEIST_FINALE_PREP_D
iVariation = 2
SWITCH GET_RANDOM_INT_IN_RANGE(0, iVariation)
CASE 0 vReturnCoord = <<2602.4272, 2852.1726, 35.2800>> fReturnHeading = 19.36 BREAK // Just South of mission start, heading North
CASE 1 vReturnCoord = <<2686.4038, 2957.3896, 35.4683>> fReturnHeading = 106.36 BREAK // East of mission start, heading West
ENDSWITCH
RETURN TRUE
BREAK
CASE SP_HEIST_FINALE_1
FALLTHRU
CASE SP_HEIST_FINALE_2A
vReturnCoord = <<135.4725, -1309.8962, 28.0485>> fReturnHeading = 301.12 // On alley at front of club
RETURN TRUE
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// check if the vTestCoords are within a specified mission's trigger area
/// NOTE : custom waypoints placed on the map don't take Z value into account they always default to 1.0 so we need to make the value suitable for the check
/// PARAMS:
/// eRC_Mission - mission to test
/// vTestCoords - coords to test
/// RETURNS:
/// TRUE if coords are inside mission trigger area
FUNC BOOL ARE_COORDS_IN_SPECIFIC_RC_MISSION_TRIGGER_AREA(g_eRC_MissionIDs eRC_Mission, VECTOR vTestCoords)
SWITCH eRC_Mission
CASE RC_EPSILON_1
IF vTestCoords.Z = 1.0
vTestCoords.Z = 83.30
ENDIF
// prox veh trigger parked in middle of the dirt track
IF VDIST2(vTestCoords, << -1619.53, 4204.10, 83.30 >>) < (20.0 * 20.0)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_RC_MISSION_TRIGGER_AREA return TRUE for RC_EPSILON_1")
RETURN TRUE
ENDIF
BREAK
CASE RC_EPSILON_3
IF vTestCoords.Z = 1.0
vTestCoords.Z = 35.0
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<1882.789673,4725.034180,34.743729>>, <<1701.497192,4677.470215,47.892891>>, 159.50)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_RC_MISSION_TRIGGER_AREA return TRUE for RC_EPSILON_3")
RETURN TRUE
ENDIF
BREAK
CASE RC_EPSILON_4
IF vTestCoords.Z = 1.0
vTestCoords.Z = 35.0
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<1882.789673,4725.034180,34.743729>>, <<1701.497192,4677.470215,47.892891>>, 159.50)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_RC_MISSION_TRIGGER_AREA return TRUE for RC_EPSILON_4")
RETURN TRUE
ENDIF
BREAK
CASE RC_EPSILON_6
IF vTestCoords.Z = 1.0
vTestCoords.Z = 11.66
ENDIF
// prox veh (plane) trigger parked in middle of the dirt track - big trigger area
IF VDIST2(vTestCoords, <<-2892.93,3192.37,11.66>>) < (50.0 * 50.0)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_RC_MISSION_TRIGGER_AREA return TRUE for RC_EPSILON_6")
RETURN TRUE
ENDIF
BREAK
CASE RC_EXTREME_1
IF vTestCoords.Z = 1.0
vTestCoords.Z = 302.86
ENDIF
IF VDIST2(vTestCoords, << -188.22, 1296.10, 302.86 >>) < (50.0 * 50.0)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_RC_MISSION_TRIGGER_AREA return TRUE for RC_EXTREME_1")
RETURN TRUE
ENDIF
BREAK
CASE RC_EXTREME_2
IF vTestCoords.Z = 1.0
vTestCoords.Z = 14.64
ENDIF
IF VDIST2(vTestCoords, << -954.19, -2760.05, 14.64 >>) < (50.0 * 50.0)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_RC_MISSION_TRIGGER_AREA return TRUE for RC_EXTREME_2")
RETURN TRUE
ENDIF
BREAK
CASE RC_EXTREME_3
// RC - Extreme 3 - top of Maze tower - B*1408629
IF vTestCoords.Z = 1.0
vTestCoords.Z = 325.0
ENDIF
IF VDIST2(vTestCoords, << -75.59782, -818.60815, 325.17450 >>) < (58.0 * 58.0)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_RC_MISSION_TRIGGER_AREA return TRUE for RC_EXTREME_3")
RETURN TRUE
ENDIF
BREAK
CASE RC_EXTREME_4
IF vTestCoords.Z = 1.0
vTestCoords.Z = 170.29
ENDIF
IF VDIST2(vTestCoords, <<1732.27, 96.36, 170.29>>) < (50.0 * 50.0)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_RC_MISSION_TRIGGER_AREA return TRUE for RC_EXTREME_4")
RETURN TRUE
ENDIF
BREAK
CASE RC_FANATIC_1
IF vTestCoords.Z = 1.0
vTestCoords.Z = 44.9677
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<-1903.322266,-401.238403,19.234562>>, <<-1844.879150,-445.726105,73.561974>>, 115.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_RC_MISSION_TRIGGER_AREA return TRUE for RC_FANATIC_1")
RETURN TRUE
ENDIF
BREAK
CASE RC_FANATIC_2
IF vTestCoords.Z = 1.0
vTestCoords.Z = 359.0
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<794.245300,1277.442505,-100>>, <<833.821533,1277.108398,400>>, 19.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_RC_MISSION_TRIGGER_AREA return TRUE for RC_FANATIC_2")
RETURN TRUE
ENDIF
BREAK
CASE RC_FANATIC_3
IF vTestCoords.Z = 1.0
vTestCoords.Z = 5.0
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<-1015.525818,6287.513184,-10.944491>>, <<-761.310425,5895.013672,45.337265>>, 167.75)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_RC_MISSION_TRIGGER_AREA return TRUE for RC_FANATIC_3")
RETURN TRUE
ENDIF
BREAK
CASE RC_HAO_1
IF vTestCoords.Z = 1.0
vTestCoords.Z = 29.6
ENDIF
// wider than the actual trigger area 25.0 (points span the alleyway
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<-72.134911,-1267.586792,27.683605>>, <<-72.180153,-1256.712158,31.0>>, 30.0) // currently a char trigger with range 4.0
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_RC_MISSION_TRIGGER_AREA return TRUE for RC_HAO_1")
RETURN TRUE
ENDIF
BREAK
CASE RC_HUNTING_2
IF vTestCoords.Z = 1.0
vTestCoords.Z = 16.3
ENDIF
// prox trigger to char using 10.0 radius currently
IF VDIST2(vTestCoords, <<-683.41589, 5841.04346, 16.33060 >>) < (20.0 * 20.0) // 20.0 to cover the road since this hunting mission can trigger from the road
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_RC_MISSION_TRIGGER_AREA return TRUE for RC_HUNTING_2")
RETURN TRUE
ENDIF
BREAK
CASE RC_JOSH_2
FALLTHRU
CASE RC_JOSH_3
IF vTestCoords.Z = 1.0
vTestCoords.Z = 29.0
ENDIF
IF VDIST2(vTestCoords, <<566.1639, -1773.8171, 29.0>>) < (50.0 * 50.0)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_RC_MISSION_TRIGGER_AREA return TRUE for RC_JOSH_2/3")
RETURN TRUE
ENDIF
BREAK
CASE RC_JOSH_4
IF vTestCoords.Z = 1.0
vTestCoords.Z = 63.1146
ENDIF
IF VDIST2(vTestCoords, <<-1103.6277, 288.1084, 63.1146>>) < (50.0 * 50.0)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_RC_MISSION_TRIGGER_AREA return TRUE for RC_JOSH_4")
RETURN TRUE
ENDIF
BREAK
CASE RC_MINUTE_2
IF vTestCoords.Z = 1.0
vTestCoords.Z = 100.0
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<-21.123615,4518.907227,119.783615>>, <<43.132828,4538.928711,72.589554>>, 48.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_RC_MISSION_TRIGGER_AREA return TRUE for RC_MINUTE_2")
RETURN TRUE
ENDIF
BREAK
CASE RC_NIGEL_1
IF vTestCoords.Z = 1.0
vTestCoords.Z = 67.5
ENDIF
IF VDIST2(vTestCoords, << -1099.50171, 790.26135, 163.39977 >>) < (30.0 * 30.0) // cover the road since this mission can trigger from the road
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_RC_MISSION_TRIGGER_AREA return TRUE for RC_NIGEL_1")
RETURN TRUE
ENDIF
BREAK
CASE RC_NIGEL_1B
IF vTestCoords.Z = 1.0
vTestCoords.Z = 67.5
ENDIF
// area covering house and surrounding roads covering
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<-1088.425293,372.072266,62.758965>>, <<-967.029968,363.597565,101.348320>>, 75.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_RC_MISSION_TRIGGER_AREA return TRUE for RC_NIGEL_1B")
RETURN TRUE
ENDIF
BREAK
CASE RC_NIGEL_3
IF vTestCoords.Z = 1.0
vTestCoords.Z = 28.2
ENDIF
// area covering all of the block where the alleyways leading to the mission are
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<-91.456764,-1296.975342,26.154373>>, <<40.672878,-1297.458618,58.293682>>, 110.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_RC_MISSION_TRIGGER_AREA return TRUE for RC_NIGEL_3")
RETURN TRUE
ENDIF
BREAK
CASE RC_OMEGA_1
IF vTestCoords.Z = 1.0
vTestCoords.Z = 49.9
ENDIF
// prox trigger to char middle of countryside so can afford generous radius
IF VDIST2(vTestCoords, <<2468.51, 3437.39, 49.90>>) < (30.0 * 30.0) // covers road and building
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_RC_MISSION_TRIGGER_AREA return TRUE for RC_OMEGA_1")
RETURN TRUE
ENDIF
BREAK
CASE RC_PAPARAZZO_2
IF vTestCoords.Z = 1.0
vTestCoords.Z = 110.0
ENDIF
// area covering all of the alleyway
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<-78.380287,285.525421,102.628593>>, <<-51.154598,357.521698,122.061691>>, 40.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_RC_MISSION_TRIGGER_AREA return TRUE for RC_PAPARAZZO_2")
RETURN TRUE
ENDIF
BREAK
CASE RC_PAPARAZZO_3A
IF vTestCoords.Z = 1.0
vTestCoords.Z = 100.0
ENDIF
// area covering the large radius for starting the mission
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<420.519592,116.289169,77.575317>>, <<212.293747,193.679443,131.876694>>, 250.0)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_RC_MISSION_TRIGGER_AREA return TRUE for RC_PAPARAZZO_3A")
RETURN TRUE
ENDIF
BREAK
CASE RC_PAPARAZZO_3B
IF vTestCoords.Z = 1.0
vTestCoords.Z = 64.0
ENDIF
// area covering the large radius for starting the mission
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<1140.157959,-540.964417,49.999439>>, <<972.371643,-535.100220,85.643967>>, 168.25)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_RC_MISSION_TRIGGER_AREA return TRUE for RC_PAPARAZZO_3B")
RETURN TRUE
ENDIF
BREAK
CASE RC_TONYA_1
FALLTHRU
CASE RC_TONYA_2
FALLTHRU
CASE RC_TONYA_5
IF vTestCoords.Z = 1.0
vTestCoords.Z = 29.6
ENDIF
IF VDIST2(vTestCoords, <<-16.5304, -1473.1208, 29.6110>>) < (8.0 * 8.0) // currently a char trigger with range 4.0
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_RC_MISSION_TRIGGER_AREA return TRUE for RC_TONYA_1/2/5")
RETURN TRUE
ENDIF
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// get the custom drop off coords and heading for the specified RC mission
/// PARAMS:
/// eRC_Mission - mission to get custom drop off for
/// vReturnCoord - the returned drop off coords
/// fReturnHeading - the returned drop off heading
/// RETURNS:
/// TRUE if custom taxi drop off has been setup
FUNC BOOL GET_CUSTOM_TAXI_DROP_OFF_FOR_RC_MISSION(g_eRC_MissionIDs eRC_Mission, VECTOR &vReturnCoord, FLOAT &fReturnHeading)
INT iVariation
SWITCH eRC_Mission
CASE RC_EPSILON_1
iVariation = 2
SWITCH GET_RANDOM_INT_IN_RANGE(0, iVariation)
CASE 0 vReturnCoord = <<-1646.1178, 4206.7427, 82.9658>> fReturnHeading = 251.0217 BREAK // up the track to the West
CASE 1 vReturnCoord = <<-1582.8895, 4201.4087, 79.5905>> fReturnHeading = 95.4232 BREAK // down the track to the East
ENDSWITCH
RETURN TRUE
BREAK
CASE RC_EPSILON_3
iVariation = 2
SWITCH GET_RANDOM_INT_IN_RANGE(0, iVariation)
CASE 0 vReturnCoord = <<1885.4458, 4738.6123, 39.4154>> fReturnHeading = 43.9908 BREAK // On dirt road by farm
CASE 1 vReturnCoord = <<1702.4242, 4687.6968, 41.9431>> fReturnHeading = 2.4487 BREAK // In town main road
ENDSWITCH
RETURN TRUE
BREAK
CASE RC_EPSILON_4
iVariation = 2
SWITCH GET_RANDOM_INT_IN_RANGE(0, iVariation)
CASE 0 vReturnCoord = <<1885.4458, 4738.6123, 39.4154>> fReturnHeading = 43.9908 BREAK // On dirt road by farm
CASE 1 vReturnCoord = <<1702.4242, 4687.6968, 41.9431>> fReturnHeading = 2.4487 BREAK // In town main road
ENDSWITCH
RETURN TRUE
BREAK
CASE RC_EPSILON_6
iVariation = 2
SWITCH GET_RANDOM_INT_IN_RANGE(0, iVariation)
CASE 0 vReturnCoord = <<-2934.6604, 3238.4041, 9.4456>> fReturnHeading = 228.5574 BREAK // up the track to the North West
CASE 1 vReturnCoord = <<-2842.0232, 3145.0862, 9.2400>> fReturnHeading = 45.7287 BREAK // down the track to the South East
ENDSWITCH
RETURN TRUE
BREAK
CASE RC_EXTREME_1
vReturnCoord = <<-204.0333, 1313.9728, 303.4189>> // across road from dog
fReturnHeading = 126.7738
RETURN TRUE
BREAK
CASE RC_EXTREME_2
vReturnCoord = <<-906.4329, -2694.2803, 12.8182>> // main road nearby
fReturnHeading = 329.3241
RETURN TRUE
BREAK
CASE RC_EXTREME_3
vReturnCoord = <<-142.3670, -895.0251, 28.1910>> // entrance to the tower
fReturnHeading = 71.6555
RETURN TRUE
BREAK
CASE RC_EXTREME_4
vReturnCoord = <<1753.9014, 107.8206, 170.2481>> // down road from dog
fReturnHeading = 288.8676
RETURN TRUE
BREAK
CASE RC_FANATIC_1
vReturnCoord = <<-1859.5427, -411.3196, 44.9677>> // next to path leading over to the bird
fReturnHeading = 242.8712
RETURN TRUE
BREAK
CASE RC_FANATIC_2
vReturnCoord = << 827.0720, 1282.2883, 359.2872 >>
fReturnHeading = 90.0
RETURN TRUE
BREAK
CASE RC_FANATIC_3
vReturnCoord = <<-640.2675, 6050.9805, 7.4082>> // On the road near the beach
fReturnHeading = 138.3021
RETURN TRUE
BREAK
CASE RC_HAO_1
vReturnCoord = <<-92.2052, -1254.8276, 28.1682>> // on the main road just North of the alleyway
fReturnHeading = 349.9590
RETURN TRUE
BREAK
CASE RC_HUNTING_2
vReturnCoord = <<-701.0541, 5819.1162, 16.1980>> // South along the road, more infront of the lodge (can't be too close since this can trigger on the road)
fReturnHeading = 336.3649
RETURN TRUE
BREAK
CASE RC_JOSH_2
FALLTHRU
CASE RC_JOSH_3
vReturnCoord = <<569.2760, -1730.9674, 28.1277>> // On main road to motel
fReturnHeading = 246.5764
RETURN TRUE
BREAK
CASE RC_JOSH_4
vReturnCoord = <<-1110.0881, 253.6757, 63.5431>> // Across the road from Josh's house
fReturnHeading = 279.1973
RETURN TRUE
BREAK
CASE RC_MINUTE_2
vReturnCoord = <<67.1562, 4560.1343, 97.8678>>
fReturnHeading = 113.4120
RETURN TRUE
BREAK
CASE RC_NIGEL_1
vReturnCoord = <<-1069.0764, 789.2375, 164.9551>> // Up the road to the East just half way along walled property (has to be that high because the ai stops way off!)
fReturnHeading = 98.4554
RETURN TRUE
BREAK
CASE RC_NIGEL_1B
vReturnCoord = <<-1073.1289, 364.1223, 67.3617>> // Road to the West of the house
fReturnHeading = 359.3075
RETURN TRUE
BREAK
CASE RC_NIGEL_3
vReturnCoord = <<-91.4237, -1305.5577, 28.1569>> // Main road West of Nigel in the alleyway
fReturnHeading = 2.2198
RETURN TRUE
BREAK
CASE RC_OMEGA_1
vReturnCoord = <<2479.2490, 3401.2341, 48.9551>> // further down the road
fReturnHeading = 35.1009
RETURN TRUE
BREAK
CASE RC_PAPARAZZO_2
vReturnCoord = <<-60.0571, 292.1416, 104.6818>> // on the main road just East of the alleyway
fReturnHeading = 74.4771
RETURN TRUE
BREAK
CASE RC_PAPARAZZO_3A
vReturnCoord = <<166.2055, 194.8600, 104.9587>> // Off to the side on Vinewood blvrd
fReturnHeading = 247.5814
RETURN TRUE
BREAK
CASE RC_PAPARAZZO_3B
vReturnCoord = <<1149.9778, -506.4045, 63.7076>> // Off to the side of the road outside the radius
fReturnHeading = 97.5469
RETURN TRUE
BREAK
CASE RC_TONYA_1
FALLTHRU
CASE RC_TONYA_2
FALLTHRU
CASE RC_TONYA_5
vReturnCoord = <<-27.2198, -1467.9329, 29.8592>> // just West along the road from her position
fReturnHeading = 273.1409
RETURN TRUE
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// check if the vTestCoords are within a specified mission's trigger area
/// NOTE : custom waypoints placed on the map don't take Z value into account they always default to 1.0 so we need to make the value suitable for the check
/// PARAMS:
/// eRC_Mission - mission to test
/// vTestCoords - coords to test
/// RETURNS:
/// TRUE if coords are inside mission trigger area
FUNC BOOL ARE_COORDS_IN_SPECIFIC_MINIGAME_TRIGGER_AREA(STATIC_BLIP_NAME_ENUM eMinigameBlip, VECTOR vTestCoords)
SWITCH eMinigameBlip
CASE STATIC_BLIP_MINIGAME_PILOT_SCHOOL // Flight school
IF vTestCoords.Z = 1.0
vTestCoords.Z = 15.0
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<-1157.595093,-2726.635742,12.944641>>, <<-1110.793823,-2679.330078,22.944656>>, 26.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_MINIGAME_TRIGGER_AREA return TRUE for STATIC_BLIP_MINIGAME_PILOT_SCHOOL")
RETURN TRUE
ENDIF
BREAK
CASE STATIC_BLIP_MINIGAME_OFFROAD_RACE5 // OFFROAD_RACE_CANYON_CLIFFS
IF vTestCoords.Z = 1.0
vTestCoords.Z = 38.5
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<-1908.065308,4432.692871,51.384197>>, <<-1962.211914,4473.799805,22.939892>>, 70.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_MINIGAME_TRIGGER_AREA return TRUE for STATIC_BLIP_MINIGAME_OFFROAD_RACE5")
RETURN TRUE
ENDIF
BREAK
CASE STATIC_BLIP_MINIGAME_OFFROAD_RACE8 // OFFROAD_RACE_RIDGE_RUN
IF vTestCoords.Z = 1.0
vTestCoords.Z = 206.5
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<-541.831116,2050.598877,186.390442>>, <<-499.787018,1968.325317,228.018326>>, 70.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_MINIGAME_TRIGGER_AREA return TRUE for STATIC_BLIP_MINIGAME_OFFROAD_RACE8")
RETURN TRUE
ENDIF
BREAK
CASE STATIC_BLIP_MINIGAME_OFFROAD_RACE9 // OFFROAD_RACE_VALLEY_TRAIL
IF vTestCoords.Z = 1.0
vTestCoords.Z = 43.1
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<-179.858810,4216.166504,30.265049>>, <<-246.319962,4226.653320,53.778858>>, 70.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_MINIGAME_TRIGGER_AREA return TRUE for STATIC_BLIP_MINIGAME_OFFROAD_RACE9")
RETURN TRUE
ENDIF
BREAK
CASE STATIC_BLIP_MINIGAME_OFFROAD_RACE10 // OFFROAD_RACE_LAKESIDE_SPLASH
IF vTestCoords.Z = 1.0
vTestCoords.Z = 34.0
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<1634.122070,3858.049316,28.339115>>, <<1573.258667,3800.441650,48.354755>>, 70.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_MINIGAME_TRIGGER_AREA return TRUE for STATIC_BLIP_MINIGAME_OFFROAD_RACE10")
RETURN TRUE
ENDIF
BREAK
CASE STATIC_BLIP_MINIGAME_OFFROAD_RACE11 // OFFROAD_RACE_ECO_FRIENDLY
IF vTestCoords.Z = 1.0
vTestCoords.Z = 94.0
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<2057.873047,2059.197510,63.880737>>, <<1999.045410,2190.543701,122.264198>>, 110.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_MINIGAME_TRIGGER_AREA return TRUE for STATIC_BLIP_MINIGAME_OFFROAD_RACE11")
RETURN TRUE
ENDIF
BREAK
CASE STATIC_BLIP_MINIGAME_OFFROAD_RACE12 // OFFROAD_RACE_MINEWARD_SPIRAL
IF vTestCoords.Z = 1.0
vTestCoords.Z = 40.7
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<3028.084473,2768.166992,57.729843>>, <<2944.283936,2772.835938,30.230679>>, 85.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_MINIGAME_TRIGGER_AREA return TRUE for STATIC_BLIP_MINIGAME_OFFROAD_RACE12")
RETURN TRUE
ENDIF
BREAK
CASE STATIC_BLIP_MINIGAME_TRAF_AIR // both at the airfield
FALLTHRU
CASE STATIC_BLIP_MINIGAME_TRAF_GND
IF vTestCoords.Z = 1.0
vTestCoords.Z = 305.0
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<2097.950928,4820.308105,55.481686>>, <<2151.254150,4726.397949,31.073204>>, 120.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_MINIGAME_TRIGGER_AREA return TRUE for STATIC_BLIP_MINIGAME_TRAF_AIR / GND")
RETURN TRUE
ENDIF
BREAK
// Base Jumps
CASE STATIC_BLIP_AMBIENT_BASEJUMP_HARBOR
IF vTestCoords.Z = 1.0
vTestCoords.Z = 4.7
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<-763.508606,-1297.979858,2.000373>>, <<-864.137207,-1278.007202,24.150381>>, 85.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_MINIGAME_TRIGGER_AREA return TRUE for STATIC_BLIP_AMBIENT_BASEJUMP_HARBOR")
RETURN TRUE
ENDIF
BREAK
CASE STATIC_BLIP_AMBIENT_BASEJUMP_RACE_TRACK
IF vTestCoords.Z = 1.0
vTestCoords.Z = 52.0
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<1137.022095,89.068535,74.890221>>, <<1267.820801,292.010620,102.990440>>, 195.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_MINIGAME_TRIGGER_AREA return TRUE for STATIC_BLIP_AMBIENT_BASEJUMP_RACE_TRACK")
RETURN TRUE
ENDIF
BREAK
CASE STATIC_BLIP_AMBIENT_BASEJUMP_WINDMILLS
IF vTestCoords.Z = 1.0
vTestCoords.Z = 35.6
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<2512.304688,1519.461548,28.555042>>, <<2380.373779,1521.587158,58.809845>>, 90.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_MINIGAME_TRIGGER_AREA return TRUE for STATIC_BLIP_AMBIENT_BASEJUMP_WINDMILLS")
RETURN TRUE
ENDIF
BREAK
CASE STATIC_BLIP_AMBIENT_BASEJUMP_NORTH_CLIFF
IF vTestCoords.Z = 1.0
vTestCoords.Z = 10.0979
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<-193.558304,6533.439453,-1.902109>>, <<-299.251190,6645.049316,20.459734>>, 120.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_MINIGAME_TRIGGER_AREA return TRUE for STATIC_BLIP_AMBIENT_BASEJUMP_NORTH_CLIFF")
RETURN TRUE
ENDIF
BREAK
CASE STATIC_BLIP_AMBIENT_BASEJUMP_MAZE_BANK
IF vTestCoords.Z = 1.0
vTestCoords.Z = 325.0 // note: higher for top of the building
ENDIF
IF VDIST2(vTestCoords, << -75.59782, -818.60815, 325.17450 >>) < (58.0 * 58.0)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_MINIGAME_TRIGGER_AREA return TRUE for STATIC_BLIP_AMBIENT_BASEJUMP_MAZE_BANK")
RETURN TRUE
ENDIF
BREAK
// not needed
//CASE STATIC_BLIP_AMBIENT_BASEJUMP_CRANE
//BREAK
CASE STATIC_BLIP_AMBIENT_BASEJUMP_RIVER_CLIFF
IF vTestCoords.Z = 1.0
vTestCoords.Z = 133.0
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<-1171.146729,4647.889648,203.793686>>, <<-1280.149292,4457.596680,5.653551>>, 120.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_MINIGAME_TRIGGER_AREA return TRUE for STATIC_BLIP_AMBIENT_BASEJUMP_RIVER_CLIFF")
RETURN TRUE
ENDIF
BREAK
CASE STATIC_BLIP_AMBIENT_BASEJUMP_RUNAWAY_TRAIN
IF vTestCoords.Z = 1.0
vTestCoords.Z = 91.6
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<-687.973999,4499.519531,114.781013>>, <<-826.008118,4496.863770,49.883595>>, 140.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_MINIGAME_TRIGGER_AREA return TRUE for STATIC_BLIP_AMBIENT_BASEJUMP_RUNAWAY_TRAIN")
RETURN TRUE
ENDIF
BREAK
// not needed - pack against a post near the road
//CASE STATIC_BLIP_AMBIENT_BASEJUMP_GOLF_COURSE
//BREAK
CASE STATIC_BLIP_AMBIENT_BASEJUMP_1K
IF vTestCoords.Z = 1.0
vTestCoords.Z = 23.0
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<-1364.700928,4490.625977,49.524769>>, <<-1367.169312,4340.339844,-1.682158>>, 100.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_MINIGAME_TRIGGER_AREA return TRUE for STATIC_BLIP_AMBIENT_BASEJUMP_1K")
RETURN TRUE
ENDIF
BREAK
CASE STATIC_BLIP_AMBIENT_BASEJUMP_1_5K
IF vTestCoords.Z = 1.0
vTestCoords.Z = 44.0
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<2566.189453,5007.007324,97.368958>>, <<2491.713623,4923.261230,30.434944>>, 80.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_MINIGAME_TRIGGER_AREA return TRUE for STATIC_BLIP_AMBIENT_BASEJUMP_1_5K")
RETURN TRUE
ENDIF
BREAK
CASE STATIC_BLIP_AMBIENT_BASEJUMP_CANAL
IF vTestCoords.Z = 1.0
vTestCoords.Z = 69.0
ENDIF
IF IS_POINT_IN_ANGLED_AREA(vTestCoords, <<1009.917053,-163.468353,102.102791>>, <<1113.474121,-221.329529,49.874504>>, 90.000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_MINIGAME_TRIGGER_AREA return TRUE for STATIC_BLIP_AMBIENT_BASEJUMP_CANAL")
RETURN TRUE
ENDIF
BREAK
// not needed - handled by taxi ARE_COORDS_IN_SPECIAL_AREA checks
//CASE STATIC_BLIP_AMBIENT_BASEJUMP_ROCK_CLIFF
//BREAK
CASE STATIC_BLIP_MINIGAME_TRIATHLON1 // B*1861605 - triathlon vespucci
IF vTestCoords.Z = 1.0
vTestCoords.Z = 12.0 // note: higher for top of the building
ENDIF
IF VDIST2(vTestCoords, <<-1230.6222, -2049.9700, 12.8882>>) < (75.0 * 75.0)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_MINIGAME_TRIGGER_AREA return TRUE for STATIC_BLIP_MINIGAME_TRIATHLON1")
RETURN TRUE
ENDIF
BREAK
CASE STATIC_BLIP_MINIGAME_COUNTRY_RACE
IF vTestCoords.Z = 1.0
vTestCoords.Z = 47.0
ENDIF
IF VDIST2(vTestCoords, <<-1968.1, 3116.7, 46.8882>>) < (30.0 * 30.0)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ARE_COORDS_IN_SPECIFIC_MINIGAME_TRIGGER_AREA return TRUE for STATIC_BLIP_MINIGAME_COUNTRY_RACE")
RETURN TRUE
ENDIF
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// get the custom drop off coords and heading for the specified RC mission
/// PARAMS:
/// eRC_Mission - mission to get custom drop off for
/// vReturnCoord - the returned drop off coords
/// fReturnHeading - the returned drop off heading
/// RETURNS:
/// TRUE if custom taxi drop off has been setup
FUNC BOOL GET_CUSTOM_TAXI_DROP_OFF_FOR_MINIGAME(STATIC_BLIP_NAME_ENUM eMinigameBlip, VECTOR &vReturnCoord, FLOAT &fReturnHeading)
SWITCH eMinigameBlip
CASE STATIC_BLIP_MINIGAME_PILOT_SCHOOL // Flight school
vReturnCoord = <<-1094.7108, -2641.9817, 12.7071>> // moved to main road drop off slip lane to prevent taxi heading into airport
fReturnHeading = 188.2694
RETURN TRUE
BREAK
CASE STATIC_BLIP_MINIGAME_OFFROAD_RACE5 // OFFROAD_RACE_CANYON_CLIFFS
vReturnCoord = <<-1917.7191, 4445.7495, 38.6592>> // on the road to the side
fReturnHeading = 45.8220
RETURN TRUE
BREAK
CASE STATIC_BLIP_MINIGAME_OFFROAD_RACE8 // OFFROAD_RACE_RIDGE_RUN
vReturnCoord = <<-482.5762, 1993.8499, 206.3482>> // on the main road to the East
fReturnHeading = 263.9373
RETURN TRUE
BREAK
CASE STATIC_BLIP_MINIGAME_OFFROAD_RACE9 // OFFROAD_RACE_VALLEY_TRAIL
vReturnCoord = <<-208.3305, 4195.3413, 43.1714>> // main road just before the left turn on to the trigger road
fReturnHeading = 333.4403
RETURN TRUE
BREAK
CASE STATIC_BLIP_MINIGAME_OFFROAD_RACE10 // OFFROAD_RACE_LAKESIDE_SPLASH
vReturnCoord = <<1619.4460, 3820.9602, 33.9381>> // on the main road near the minigame
fReturnHeading = 129.6464
RETURN TRUE
BREAK
CASE STATIC_BLIP_MINIGAME_OFFROAD_RACE11 // OFFROAD_RACE_ECO_FRIENDLY
vReturnCoord = <<2045.1687, 2155.8872, 94.3423>> // just past the start towards the dead end to stop it interfering with the race
fReturnHeading = 347.9475
RETURN TRUE
BREAK
CASE STATIC_BLIP_MINIGAME_OFFROAD_RACE12 // OFFROAD_RACE_MINEWARD_SPIRAL
vReturnCoord = <<2952.7668, 2807.0281, 40.7635>> // into the quarry basin to stop taxi waiting in front of the race
fReturnHeading = 121.2574
RETURN TRUE
BREAK
CASE STATIC_BLIP_MINIGAME_TRAF_AIR
FALLTHRU
CASE STATIC_BLIP_MINIGAME_TRAF_GND
vReturnCoord = <<2119.6763, 4747.1978, 40.1793>> // on main road behind hangar to give things a little time to load in
fReturnHeading = 305.2213
RETURN TRUE
BREAK
//Base jumps
CASE STATIC_BLIP_AMBIENT_BASEJUMP_HARBOR
vReturnCoord = <<-817.3487, -1303.8899, 4.0005>> // near heli facing away - to give it time (if needed) to spawn on skip
fReturnHeading = 253.9379
RETURN TRUE
BREAK
CASE STATIC_BLIP_AMBIENT_BASEJUMP_RACE_TRACK
vReturnCoord = <<1118.7509, 262.0209, 79.8555>> // Horse race course (North East section) car park at side of the grand stand
fReturnHeading = 52.3086
RETURN TRUE
BREAK
CASE STATIC_BLIP_AMBIENT_BASEJUMP_WINDMILLS
vReturnCoord = <<2414.0632, 1503.7697, 35.6614>> // road leading to the loop facing away from heli so it will just drive off it warped to
fReturnHeading = 124.0994
RETURN TRUE
BREAK
CASE STATIC_BLIP_AMBIENT_BASEJUMP_NORTH_CLIFF
vReturnCoord = <<-203.2552, 6536.0894, 10.0979>> // carpark leading to jetty
fReturnHeading = 311.0677
RETURN TRUE
BREAK
CASE STATIC_BLIP_AMBIENT_BASEJUMP_MAZE_BANK
vReturnCoord = <<-142.3670, -895.0251, 28.1910>> // entrance to building
fReturnHeading = 71.6555
RETURN TRUE
BREAK
// not needed
//CASE STATIC_BLIP_AMBIENT_BASEJUMP_CRANE
//BREAK
CASE STATIC_BLIP_AMBIENT_BASEJUMP_RIVER_CLIFF
vReturnCoord = <<-1214.2524, 4629.8872, 133.8730>> // North of the peak, height side
fReturnHeading = 123.1562
RETURN TRUE
BREAK
CASE STATIC_BLIP_AMBIENT_BASEJUMP_RUNAWAY_TRAIN
vReturnCoord = <<-767.9527, 4521.8818, 91.6871>> // road near the chopper (right side of the river)
fReturnHeading = 85.6363
RETURN TRUE
BREAK
// not needed - pack against a post near the road
//CASE STATIC_BLIP_AMBIENT_BASEJUMP_GOLF_COURSE
//BREAK
CASE STATIC_BLIP_AMBIENT_BASEJUMP_1K
vReturnCoord = <<-1363.1832, 4468.6914, 23.1468>> // One the road near the chopper (right side of the river)
fReturnHeading = 272.2546
RETURN TRUE
BREAK
CASE STATIC_BLIP_AMBIENT_BASEJUMP_1_5K
vReturnCoord = <<2477.0884, 4948.6772, 44.0936>> // One the road near the barn entrance
fReturnHeading = 49.3948
RETURN TRUE
BREAK
CASE STATIC_BLIP_AMBIENT_BASEJUMP_CANAL
vReturnCoord = <<1047.9314, -203.8790, 69.0164>> // One the road side near the chopper
fReturnHeading = 62.0197
RETURN TRUE
BREAK
// not needed - handled by taxi ARE_COORDS_IN_SPECIAL_AREA checks
//CASE STATIC_BLIP_AMBIENT_BASEJUMP_ROCK_CLIFF
//BREAK
CASE STATIC_BLIP_MINIGAME_TRIATHLON1 // B*1861605 - triathlon vespucci
vReturnCoord = <<-1200.8625, -2049.4602, 12.9248>> // dead end road behind sign up stand (facing back out to main road)
fReturnHeading = 334.9650
RETURN TRUE
BREAK
CASE STATIC_BLIP_MINIGAME_COUNTRY_RACE
vReturnCoord = <<1960.3881, 3124.7971, 46.8770>>
fReturnHeading = 233.4840
RETURN TRUE
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// checks through SP_MISSIONS, RCMs and Minigames to check if the vTestCoords is inside a trigger area
/// If so it updates the destination to use a custom drop off position and heading
/// PARAMS:
/// vTestCoords - position to test
/// vReturnCoord - the updated custom taxi drop off coords
/// fReturnHeading - the updated custom taxi drop off heading
/// RETURNS:
/// TRUE if the taxi destination was updated to use a custom drop off
FUNC BOOL UPDATE_TAXI_DESTINATION_IF_INSIDE_A_TRIGGER_AREA(VECTOR vTestCoords, VECTOR &vReturnCoord, FLOAT &fReturnHeading)
FLOAT fClosestStoryMissionDist = 99999999
FLOAT fClosestRCMissionDist = 99999999
FLOAT fClosestMinigameDist = 99999999
GET_CLOSEST_ACTIVE_STORY_MISSION(vTestCoords, eStoryMissionDestination, fClosestStoryMissionDist)
GET_CLOSEST_ACTIVE_RC_MISSION(vTestCoords, eRCMissionDestination, fClosestRCMissionDist)
GET_CLOSEST_ACTIVE_MINIGAME_BLIP(vTestCoords, eMinigameDestination, fClosestMinigameDist)
// closest blip is SP mission
IF fClosestStoryMissionDist < fClosestRCMissionDist
AND fClosestStoryMissionDist < fClosestMinigameDist
// test if the current desination would auto trigger the mission
IF ARE_COORDS_IN_SPECIFIC_SP_MISSION_TRIGGER_AREA(eStoryMissionDestination, vTestCoords)
// retreve a custom drop off coord and heading for the SP mission
IF GET_CUSTOM_TAXI_DROP_OFF_FOR_SP_MISSION(eStoryMissionDestination, vReturnCoord, fReturnHeading)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : UPDATE_TAXI_DESTINATION_IF_INSIDE_A_TRIGGER_AREA : RETURN TRUE Destination in SP mission trigger area : vTestCoords = ", vTestCoords,
" vReturnCoord = ", vReturnCoord, " fReturnHeading = ", fReturnHeading)
RETURN TRUE
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : UPDATE_TAXI_DESTINATION_IF_INSIDE_A_TRIGGER_AREA : Destination detected inside trigger area but unable to retreive custom drop off")
ENDIF
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : UPDATE_TAXI_DESTINATION_IF_INSIDE_A_TRIGGER_AREA : Destination wasn't inside closest SP mission trigger area")
ENDIF
// closest blip is RCM
ELIF fClosestRCMissionDist < fClosestStoryMissionDist
AND fClosestRCMissionDist < fClosestMinigameDist
// test if the current desination would auto trigger the mission
IF ARE_COORDS_IN_SPECIFIC_RC_MISSION_TRIGGER_AREA(eRCMissionDestination, vTestCoords)
// retreve a custom drop off coord and heading for the RC mission
IF GET_CUSTOM_TAXI_DROP_OFF_FOR_RC_MISSION(eRCMissionDestination, vReturnCoord, fReturnHeading)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : UPDATE_TAXI_DESTINATION_IF_INSIDE_A_TRIGGER_AREA : RETURN TRUE Destination in RC mission trigger area : vTestCoords = ", vTestCoords,
" vReturnCoord = ", vReturnCoord, " fReturnHeading = ", fReturnHeading)
RETURN TRUE
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : UPDATE_TAXI_DESTINATION_IF_INSIDE_A_TRIGGER_AREA : Destination detected inside RC mission trigger area but unable to retreive custom drop off")
ENDIF
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : UPDATE_TAXI_DESTINATION_IF_INSIDE_A_TRIGGER_AREA : Destination wasn't inside closest RC mission trigger area")
ENDIF
// closest minigame
ELIF fClosestMinigameDist != 99999999
// test if the current desination would trigger the minigame
IF ARE_COORDS_IN_SPECIFIC_MINIGAME_TRIGGER_AREA(eMinigameDestination, vTestCoords)
// retreve a custom drop off coord and heading for the minigame
IF GET_CUSTOM_TAXI_DROP_OFF_FOR_MINIGAME(eMinigameDestination, vReturnCoord, fReturnHeading)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : UPDATE_TAXI_DESTINATION_IF_INSIDE_A_TRIGGER_AREA : RETURN TRUE Destination in minigame trigger area : vTestCoords = ", vTestCoords,
" vReturnCoord = ", vReturnCoord, " fReturnHeading = ", fReturnHeading)
RETURN TRUE
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : UPDATE_TAXI_DESTINATION_IF_INSIDE_A_TRIGGER_AREA : Destination detected inside minigame trigger area but unable to retreive custom drop off")
ENDIF
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : UPDATE_TAXI_DESTINATION_IF_INSIDE_A_TRIGGER_AREA : Destination wasn't inside closest minigame trigger area")
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// generates the drop off destination position and heading the taxi should use for droppping the player off
/// Handles checks for desination being inside a mission /rc trigger range or being inside a special area
/// PARAMS:
/// inBlip - the blip selected by the player to travel to
/// vReturnCoord - the returned drop off position
/// fReturnHeading - the returned drop off heading
/// RETURNS:
/// RETURN if a position as generated successfully
FUNC BOOL GENERATE_TAXI_DROP_OFF_PLAYER_DESTINATION(BLIP_INDEX &inBlip, VECTOR &vReturnCoord, FLOAT &fReturnHeading)
VECTOR vTempDist
IF DOES_BLIP_EXIST(inBlip)
// switch to stagger the blip checks over a few frames
SWITCH eGenerateSafeDestinationState
// initial checks to see if the destination is inside a mission / rc trigger area. Also checks if destination is the mission custom blip
CASE TAXI_GSDS_INITIAL_TRIGGER_AREAS_CHECK
parkTypeTaxiAtDestination = PARK_TYPE_PULL_OVER // standard behaviour if the destination is generated. If scripted use PARK_TYPE_PULL_OVER_IMMEDIATE
vDestinationLocate = GET_RADAR_BLIP_COORDS(inBlip)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GENERATE_TAXI_DROP_OFF_PLAYER_DESTINATION : vDestinationLocate = ", vDestinationLocate)
// if this is a mission blip which has been setup to use the custom drop off we don't need to calculate drop off coords
IF DOES_BLIP_EXIST(g_CustomDropOffBlip)
AND (inBlip = g_CustomDropOffBlip)
vReturnCoord = g_vCustomDropPosition
fReturnHeading = g_fCustomDropHeading
vTempDist = vDestinationLocate - vReturnCoord
vTempDist.z = 0.0
fDropOffDistFromBlip = VMAG(vTempDist)
parkTypeTaxiAtDestination = PARK_TYPE_PULL_OVER_IMMEDIATE // standard behaviour if the destination is generated. If scripted use PARK_TYPE_PULL_OVER_IMMEDIATE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GENERATE_TAXI_DROP_OFF_PLAYER_DESTINATION : RETURN TRUE g_CustomDropOffBlip : vDestinationLocate = ", vDestinationLocate,
" vReturnCoord = ", vReturnCoord, " fReturnHeading = ", fReturnHeading, " fDropOffDistFromBlip = ", fDropOffDistFromBlip)
eGenerateSafeDestinationState = TAXI_GSDS_SAFE_DESTINATION_FOUND
RETURN TRUE
ELSE
// check the location isn't inside a mission / rc trigger area. If it is a custom drop off coords and heading are given
IF UPDATE_TAXI_DESTINATION_IF_INSIDE_A_TRIGGER_AREA(vDestinationLocate, vReturnCoord, fReturnHeading)
vTempDist = vDestinationLocate - vReturnCoord
vTempDist.z = 0.0
fDropOffDistFromBlip = VMAG(vTempDist)
parkTypeTaxiAtDestination = PARK_TYPE_PULL_OVER_IMMEDIATE // standard behaviour if the destination is generated. If scripted use PARK_TYPE_PULL_OVER_IMMEDIATE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GENERATE_TAXI_DROP_OFF_PLAYER_DESTINATION : RETURN TRUE taxi destination updated for trigger area ",
" vDestinationLocate = ", vDestinationLocate, " fDropOffDistFromBlip = ", fDropOffDistFromBlip)
eGenerateSafeDestinationState = TAXI_GSDS_SAFE_DESTINATION_FOUND
RETURN TRUE
ENDIF
eGenerateSafeDestinationState = TAXI_GSDS_INITIAL_SPECIAL_AREA_CHECK
RETURN FALSE
ENDIF
BREAK
// check the location isn't in one of the speical areas. If it is a custom drop off coords and heading are given
CASE TAXI_GSDS_INITIAL_SPECIAL_AREA_CHECK
IF ARE_COORDS_IN_SPECIAL_AREA(vDestinationLocate, vReturnCoord, fReturnHeading)
vTempDist = vDestinationLocate - vReturnCoord
vTempDist.z = 0.0
fDropOffDistFromBlip = VMAG(vTempDist)
parkTypeTaxiAtDestination = PARK_TYPE_PULL_OVER_IMMEDIATE // standard behaviour if the destination is generated. If scripted use PARK_TYPE_PULL_OVER_IMMEDIATE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GENERATE_TAXI_DROP_OFF_PLAYER_DESTINATION : RETURN TRUE destination was in special area : vDestinationLocate = ", vDestinationLocate,
" vReturnCoord = ", vReturnCoord, " fReturnHeading = ", fReturnHeading, " fDropOffDistFromBlip = ", fDropOffDistFromBlip)
eGenerateSafeDestinationState = TAXI_GSDS_SAFE_DESTINATION_FOUND
RETURN TRUE
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GENERATE_TAXI_DROP_OFF_PLAYER_DESTINATION : Destination isn't inside a special area")
iDesinationNodeSearchNumber = 0 // reset readt for node checks
eGenerateSafeDestinationState = TAXI_GSDS_GENERATE_COORDS
RETURN FALSE
ENDIF
BREAK
// generate the taxi's drop off destination
CASE TAXI_GSDS_GENERATE_COORDS
IF DOES_ENTITY_EXIST(g_WaitingTaxi)
IF GET_TAXI_PULL_IN_SPOT_NEAR_COORDS(g_WaitingTaxi, GET_ENTITY_COORDS(g_WaitingTaxi, FALSE), vDestinationLocate, vReturnCoord, fReturnHeading, iDesinationNodeSearchNumber, inBlip)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GENERATE_TAXI_DROP_OFF_PLAYER_DESTINATION : drop off coords generated : vDestinationLocate = ", vDestinationLocate,
" vReturnCoord = ", vReturnCoord, " fReturnHeading = ", fReturnHeading, " fDropOffDistFromBlip = ", fDropOffDistFromBlip)
eGenerateSafeDestinationState = TAXI_GSDS_TRIGGER_AREAS_RECHECK
RETURN FALSE
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GENERATE_TAXI_DROP_OFF_PLAYER_DESTINATION : generating drop off destination...")
//eGenerateSafeDestinationState = TAXI_GSDS_SAFE_DESTINATION_NOT_FOUND
RETURN FALSE
ENDIF
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GENERATE_TAXI_DROP_OFF_PLAYER_DESTINATION : return FALSE : taxi doesn't exist!")
ENDIF
BREAK
// recheck the generated coords aren't now with in a trigger area. If it is a custom drop off coords and heading are given
CASE TAXI_GSDS_TRIGGER_AREAS_RECHECK
IF UPDATE_TAXI_DESTINATION_IF_INSIDE_A_TRIGGER_AREA(vReturnCoord, vReturnCoord, fReturnHeading)
vTempDist = vDestinationLocate - vReturnCoord
vTempDist.z = 0.0
fDropOffDistFromBlip = VMAG(vTempDist)
parkTypeTaxiAtDestination = PARK_TYPE_PULL_OVER_IMMEDIATE // standard behaviour if the destination is generated. If scripted use PARK_TYPE_PULL_OVER_IMMEDIATE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GENERATE_TAXI_DROP_OFF_PLAYER_DESTINATION : Generated taxi destination was inside a trigger area updated for trigger area ",
" vDestinationLocate = ", vDestinationLocate, " fDropOffDistFromBlip = ", fDropOffDistFromBlip)
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GENERATE_TAXI_DROP_OFF_PLAYER_DESTINATION : Generated taxi destination was not inside a trigger area updated for trigger area ",
" vDestinationLocate = ", vDestinationLocate, " fDropOffDistFromBlip = ", fDropOffDistFromBlip)
ENDIF
eGenerateSafeDestinationState = TAXI_GSDS_SAFE_DESTINATION_FOUND
RETURN TRUE
BREAK
CASE TAXI_GSDS_SAFE_DESTINATION_FOUND
RETURN TRUE
BREAK
CASE TAXI_GSDS_SAFE_DESTINATION_NOT_FOUND
BREAK
ENDSWITCH
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GENERATE_TAXI_DROP_OFF_PLAYER_DESTINATION : return FALSE : blip doesn't exist!")
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// check through the passenger seats using IS_VEHICLE_SEAT_FREE
/// PARAMS:
/// vehIndex - vehicle to test
/// RETURNS:
/// VS_ANY_PASSENGER if no valid free seat was found
FUNC VEHICLE_SEAT GET_FIRST_FREE_PASSENGER_SEAT(VEHICLE_INDEX &vehIndex)
IF DOES_ENTITY_EXIST(vehIndex)
IF NOT IS_ENTITY_DEAD(vehIndex)
IF IS_VEHICLE_SEAT_FREE(vehIndex, VS_FRONT_RIGHT)
RETURN VS_FRONT_RIGHT
ENDIF
IF IS_VEHICLE_SEAT_FREE(vehIndex, VS_BACK_LEFT)
RETURN VS_BACK_LEFT
ENDIF
IF IS_VEHICLE_SEAT_FREE(vehIndex, VS_BACK_RIGHT)
RETURN VS_BACK_RIGHT
ENDIF
ENDIF
ENDIF
RETURN VS_ANY_PASSENGER
ENDFUNC
PROC SET_GROUP_INTO_CAB(VEHICLE_SEAT eReservedPlayerSeat)
INT i, j
PED_INDEX GroupPedID
VEHICLE_SEAT eTargetSeat
// if any group members they should also get in taxi
IF DOES_GROUP_EXIST(PLAYER_GROUP_ID())
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SET_GROUP_INTO_CAB : ", " DOES_GROUP_EXIST(PLAYER_GROUP_ID())")
GET_GROUP_SIZE(PLAYER_GROUP_ID(), j, i)
IF (i > 0)
// ensure the second ped in the group has been placed in the front seat before setting the first ped in the group to the back
IF (i > 1)
GroupPedID = GET_PED_AS_GROUP_MEMBER(PLAYER_GROUP_ID(), 1)
IF NOT IS_PED_INJURED(GroupPedID)
IF NOT IS_PED_SITTING_IN_VEHICLE(GroupPedID, g_WaitingTaxi)
eTargetSeat = VS_FRONT_RIGHT
// if the seat is already occupied find another
IF NOT IS_VEHICLE_SEAT_FREE(g_WaitingTaxi, eTargetSeat)
eTargetSeat = GET_FIRST_FREE_PASSENGER_SEAT(g_WaitingTaxi)
IF IS_VEHICLE_SEAT_FREE(g_WaitingTaxi, eTargetSeat)
CLEAR_PED_TASKS(GroupPedID)
SET_PED_INTO_VEHICLE(GroupPedID, g_WaitingTaxi, eTargetSeat)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SET_GROUP_INTO_CAB : ", " 2nd buddy : set into taxi as passenger in backup seat = ", eTargetSeat)
ENDIF
ELSE
CLEAR_PED_TASKS(GroupPedID)
SET_PED_INTO_VEHICLE(GroupPedID, g_WaitingTaxi, eTargetSeat)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SET_GROUP_INTO_CAB : ", " 2nd buddy : set into taxi as passenger in prefered seat = ", eTargetSeat)
ENDIF
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SET_GROUP_INTO_CAB : ", " 2nd buddy : already in the taxi")
ENDIF
ENDIF
ENDIF
// set the first ped in the group into the taxi (prefered back seat with the player)
GroupPedID = GET_PED_AS_GROUP_MEMBER(PLAYER_GROUP_ID(), 0)
IF NOT IS_PED_INJURED(GroupPedID)
IF NOT IS_PED_SITTING_IN_VEHICLE(GroupPedID, g_WaitingTaxi)
CLEAR_PED_TASKS(GroupPedID)
// set target seat (opposite to player's reserved seat)
eTargetSeat = VS_BACK_LEFT
IF eReservedPlayerSeat = VS_BACK_LEFT
eTargetSeat = VS_BACK_RIGHT
ENDIF
// if the seat is already occupied find another
IF NOT IS_VEHICLE_SEAT_FREE(g_WaitingTaxi, eTargetSeat)
eTargetSeat = GET_FIRST_FREE_PASSENGER_SEAT(g_WaitingTaxi)
IF IS_VEHICLE_SEAT_FREE(g_WaitingTaxi, eTargetSeat)
CLEAR_PED_TASKS(GroupPedID)
SET_PED_INTO_VEHICLE(GroupPedID, g_WaitingTaxi, eTargetSeat)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SET_GROUP_INTO_CAB : ", " 1st buddy : set into taxi as passenger backup seat = ", eTargetSeat)
ENDIF
ELSE
CLEAR_PED_TASKS(GroupPedID)
SET_PED_INTO_VEHICLE(GroupPedID, g_WaitingTaxi, eTargetSeat)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SET_GROUP_INTO_CAB : ", " 1st buddy : set into taxi as passenger prefered seat = ", eTargetSeat)
ENDIF
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SET_GROUP_INTO_CAB : ", " 1st buddy : already in the taxi")
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
PROC UPDATE_THE_FARE()
iFareTimer += ROUND(GET_FRAME_TIME() * 1000.0)
IF (iFareTimer > 5000)
fFare += fFareRate
iFareTimer = 0
ENDIF
IF (GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE), vLastFarePoint, FALSE) > FARE_DISTANCE)
fFare += fFareRate
iFareTimer = 0
vLastFarePoint = GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE)
ENDIF
currentJourneyPrice = CEIL(fFare)
IF currentJourneyPrice <> lastJourneyPrice
BEGIN_SCALEFORM_MOVIE_METHOD(scaleformTaxiMeter,"SET_TAXI_PRICE")
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(currentJourneyPrice)
END_SCALEFORM_MOVIE_METHOD()
fDistanceToDestination = VDIST(GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE), g_vTaxiDropOffPosition)
lastJourneyPrice = currentJourneyPrice
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "UPDATE_THE_FARE() : currentJourneyPrice = ", currentJourneyPrice)
ENDIF
ENDPROC
FUNC FLOAT GET_DISTANCE_OF_JOURNEY(VECTOR vStart, VECTOR vEnd)
RETURN(VMAG(vEnd - vStart) * 1.3)
ENDFUNC
/// PURPOSE:
/// B*1211249 - estimates the distance from thep player to the destination blip and increments
PROC UPDATE_DIST_TRAVELED_IN_TAXI_STAT_FOR_SKIP()
STATSENUM eDistAsTaxiPassengerStat
SWITCH charWhenTaxiLaunched
CASE CHAR_MICHAEL
eDistAsTaxiPassengerStat = SP0_DIST_AS_PASSENGER_TAXI
BREAK
CASE CHAR_FRANKLIN
eDistAsTaxiPassengerStat = SP1_DIST_AS_PASSENGER_TAXI
BREAK
CASE CHAR_TREVOR
eDistAsTaxiPassengerStat = SP2_DIST_AS_PASSENGER_TAXI
BREAK
DEFAULT
IF NOT IS_CURRENTLY_ON_MISSION_OF_TYPE (MISSION_TYPE_DIRECTOR)
SCRIPT_ASSERT(" taxiService.sc : UPDATE_DIST_TRAVELED_IN_TAXI_STAT_FOR_SKIP() : invalid player char ID ")
ENDIF
BREAK
ENDSWITCH
IF NOT IS_CURRENTLY_ON_MISSION_OF_TYPE (MISSION_TYPE_DIRECTOR)
FLOAT fEstimatedDistToAdd = CALCULATE_TRAVEL_DISTANCE_BETWEEN_POINTS(GET_ENTITY_COORDS(PLAYER_PED_ID()), g_vTaxiDropOffPosition)
STAT_INCREMENT(eDistAsTaxiPassengerStat, fEstimatedDistToAdd)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : UPDATE_DIST_TRAVELED_IN_TAXI_STAT_FOR_SKIP() : fEstimatedDistToAdd = ", fEstimatedDistToAdd)
ENDIF
/*FLOAT fEstimatedDistToAdd = GET_GPS_DISTANCE(g_vTaxiDropOffPosition)
FLOAT fTotal
IF STAT_GET_FLOAT(eDistAsTaxiPassengerStat, fTotal)
fTotal += fEstimatedDistToAdd
STAT_SET_FLOAT(eDistAsTaxiPassengerStat, fTotal)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : UPDATE_DIST_TRAVELED_IN_TAXI_STAT_FOR_SKIP() : fEstimatedDistToAdd = ", fEstimatedDistToAdd, " new total = ", fTotal)
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : UPDATE_DIST_TRAVELED_IN_TAXI_STAT_FOR_SKIP() : failed STAT_GET_FLOAT returned FALSE")
ENDIF*/
ENDPROC
PROC CALCULATE_SKIP_COST()
FLOAT fTemp
INT i
fTemp = (GET_DISTANCE_OF_JOURNEY(GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE), g_vTaxiDropOffPosition) / 50.0) * fFareRate * FARE_SKIP_MULTIPLIER
i = FLOOR(fFare) + ROUND(fTemp)
// add on another third
fTemp = TO_FLOAT(i)
fTemp *= 1.33
i = ROUND(fTemp)
currentJourneyPrice += i
fFare += currentJourneyPrice
UPDATE_THE_FARE()
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " CALCULATE_SKIP_COST() : currentJourneyPrice = ", currentJourneyPrice, ", g_vTaxiDropOffPosition = ", g_vTaxiDropOffPosition)
ENDPROC
PROC CALCULATE_AND_APPLY_TIME_PASSED()
FLOAT fTemp
INT iHours = 0
INT iMinutes = 0
IF iHours = 0
IF iMinutes = 0
ENDIF
ENDIF
fTemp = GET_DISTANCE_OF_JOURNEY(GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE), g_vTaxiDropOffPosition)
IF bHurrying
iHours = FLOOR((fTemp / 200.0 ) / 60.0)
iMinutes = ROUND((fTemp / 200.0 ) - (60.0 * TO_FLOAT(iHours)))
ELSE
iHours = FLOOR((fTemp / 100.0 ) / 60.0)
iMinutes = ROUND((fTemp / 100.0 ) - (60.0 * TO_FLOAT(iHours)))
ENDIF
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " CALCULATE_AND_APPLY_TIME_PASSED() : iHours = ", iHours, ", iMinutes = ", iMinutes)
ADD_TO_CLOCK_TIME(iHours, iMinutes, 0)
ADVANCE_FRIEND_TIMERS(TO_FLOAT((iHours*60)+iMinutes)/60.0)
ENDPROC
FUNC BOOL IS_TAXI_AT_DESTINATION()
IF IS_ENTITY_AT_COORD(g_WaitingTaxi, g_vTaxiDropOffPosition, << TAXI_TARGET_REACHED_DIST, TAXI_TARGET_REACHED_DIST, 20 >>) // <<20, 20, 15>>) increased size for B*1379650 - jMart said services check for task finished and in range of 50m to destination
OR bTaxiHasHitDestinationLocate
OR (eTaxiJourneyState = TAXI_JOURNEY_STATE_SKIP_JOURNEY)
bTaxiHasHitDestinationLocate = TRUE
IF GET_SCRIPT_TASK_STATUS(g_WaitingTaxiDriver, SCRIPT_TASK_PERFORM_SEQUENCE) = FINISHED_TASK
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// test if the current player ped owns the taxi lot property
/// RETURNS:
/// TRUE if they do
FUNC BOOL IS_TAXI_LOT_OWNED_BY_CURRENT_PLAYER()
IF GET_CURRENT_PROPERTY_OWNER(PROPERTY_TAXI_LOT) = GET_CURRENT_PLAYER_PED_ENUM()
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "IS_TAXI_LOT_OWNED_BY_CURRENT_PLAYER retuirning TRUE")
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
PROC ATTEMPT_PAYMENT()
// B*1082174 - if the player owns the taxi lot, they don't get charged to ride a taxi
IF IS_VEHICLE_DRIVEABLE(g_WaitingTaxi)
IF NOT IS_PED_INJURED(g_WaitingTaxiDriver)
IF IS_PED_SITTING_IN_VEHICLE(g_WaitingTaxiDriver, g_WaitingTaxi)
IF NOT IS_TAXI_LOT_OWNED_BY_CURRENT_PLAYER()
BOOL bNoMoney = TRUE
IF GET_TOTAL_CASH(GET_CURRENT_PLAYER_PED_ENUM()) >= currentJourneyPrice
IF bMadeItToDestination
IF currentJourneyPrice > INITIAL_PRICE
IF fDropOffDistFromBlip > 75.0
eTaxiDialogue = TAXI_DIALOGUE_CLOSE_AS_POSS // set dialogue to trigger in PLAY_TAXI_DIALOGUE()
ELSE
eTaxiDialogue = TAXI_DIALOGUE_ARRIVE // set dialogue to trigger in PLAY_TAXI_DIALOGUE()
ENDIF
PLAY_TAXI_DIALOGUE(g_WaitingTaxiDriver, eTaxiDialogue)
DEBIT_BANK_ACCOUNT(GET_CURRENT_PLAYER_PED_ENUM(), BAAC_TAXI, currentJourneyPrice)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "ATTEMPT_PAYMENT() TAXI_DIALOGUE_ARRIVE journey price paid.")
bNoMoney = FALSE
ENDIF
ELIF bPlayerCanLeaveVehicle
OR eTaxiJourneyState = TAXI_JOURNEY_STATE_ORDERED_TO_PULLOVER
IF currentJourneyPrice > INITIAL_PRICE
eTaxiDialogue = TAXI_DIALOGUE_OUT_EARLY // set dialogue to trigger in PLAY_TAXI_DIALOGUE()
PLAY_TAXI_DIALOGUE(g_WaitingTaxiDriver, eTaxiDialogue)
DEBIT_BANK_ACCOUNT(GET_CURRENT_PLAYER_PED_ENUM(), BAAC_TAXI, currentJourneyPrice)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "ATTEMPT_PAYMENT() TAXI_DIALOGUE_OUT_EARLY journey price paid.")
bNoMoney = FALSE
ENDIF
ELSE
IF GET_ENTITY_SPEED(g_WaitingTaxi) > 5.0 // player bailed out without paying
IF NOT IS_REPLAY_BEING_PROCESSED() //B* 1976297: Don't give wanted level if skipping journey when the replay screen appears
eTaxiDialogue = TAXI_DIALOGUE_RUN_AWAY // set dialogue to trigger in PLAY_TAXI_DIALOGUE()
PLAY_TAXI_DIALOGUE(g_WaitingTaxiDriver, eTaxiDialogue)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "ATTEMPT_PAYMENT() journey price not paid. - player bailed out")
SET_PLAYER_WANTED_LEVEL_NO_DROP(PLAYER_ID(), 1)
SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID())
ENDIF
ELSE
eTaxiDialogue = TAXI_DIALOGUE_OUT_EARLY // set dialogue to trigger in PLAY_TAXI_DIALOGUE()
PLAY_TAXI_DIALOGUE(g_WaitingTaxiDriver, eTaxiDialogue)
IF currentJourneyPrice > INITIAL_PRICE
DEBIT_BANK_ACCOUNT(GET_CURRENT_PLAYER_PED_ENUM(), BAAC_TAXI, currentJourneyPrice)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "ATTEMPT_PAYMENT() TAXI_DIALOGUE_OUT_EARLY journey price paid.")
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "ATTEMPT_PAYMENT() AXI_DIALOGUE_OUT_EARLY nothing to pay.")
ENDIF
bNoMoney = FALSE
ENDIF
ENDIF
ENDIF
IF bNoMoney
IF currentJourneyPrice > INITIAL_PRICE
eTaxiDialogue = TAXI_DIALOGUE_NO_MONEY // set dialogue to trigger in PLAY_TAXI_DIALOGUE()
PLAY_TAXI_DIALOGUE(g_WaitingTaxiDriver, eTaxiDialogue)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "ATTEMPT_PAYMENT() journey price not paid. - no money")
SET_PLAYER_WANTED_LEVEL_NO_DROP(PLAYER_ID(), 1)
SET_PLAYER_WANTED_LEVEL_NOW(PLAYER_ID())
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
FUNC BOOL IS_TAXI_WAITING_FOR_THIS_RC_MISSION(g_eRC_MissionIDs eRCMission)
// An RCM is nearby and ready to play
IF (eRCMission <> NO_RC_MISSION)
// Initial scene hasn't yet been created
IF NOT (g_RandomChars[ENUM_TO_INT(eRCMission)].rcIsAwaitingTrigger)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " IS_TAXI_WAITING_FOR_THIS_RC_MISSION() is waiting for RCM index = ", ENUM_TO_INT(eRCMission))
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// spliting up from SEND_TAXI_TO_DESTINATION - func needs alot more work when i have time
/// RETURNS:
/// TRUE if destination has been selected
FUNC BOOL HAS_PLAYER_SELECTED_DESTINATION()
IF bDestinationSelected
IF bDropPointSelected
RETURN TRUE
ELSE
IF GENERATE_TAXI_DROP_OFF_PLAYER_DESTINATION(currentTaxiDestination.BlipID, g_vTaxiDropOffPosition, g_fTaxiDropOffHeading)
// reset the fare conditions ready for journey
iFareTimer = 0
vLastFarePoint = GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE)
fDistanceToDestination = VDIST(GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE), g_vTaxiDropOffPosition) // 1511984 - update ready for skip control check
bDropPointSelected = TRUE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : HAS_PLAYER_SELECTED_DESTINATION() pull in spot near blip selected ",
" g_vTaxiDropOffPosition = ", g_vTaxiDropOffPosition, " g_fTaxiDropOffHeading = ", g_fTaxiDropOffHeading)
RETURN TRUE
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// set's the taxi driver playing the turn around animations ending in looped look at passenger
/// RETURNS:
/// TRUE if applied
FUNC BOOL SET_DRIVER_PLAY_TURN_AROUND_ANIM()
IF NOT IS_PED_INJURED(g_WaitingTaxiDriver)
AND IS_VEHICLE_DRIVEABLE(g_WaitingTaxi)
IF IS_PED_SITTING_IN_VEHICLE(g_WaitingTaxiDriver, g_WaitingTaxi)
REQUEST_ANIM_DICT(tlAnimDictTaxiDriver)
IF HAS_ANIM_DICT_LOADED(tlAnimDictTaxiDriver)
// B*1563479 - ensure look at is cleared for these anims so he doesn't twist his neck too far
IF IS_PED_HEADTRACKING_PED(g_WaitingTaxiDriver, PLAYER_PED_ID())
TASK_CLEAR_LOOK_AT(g_WaitingTaxiDriver)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SET_DRIVER_PLAY_TURN_AROUND_ANIM cleared look at ready for anim")
ENDIF
OPEN_SEQUENCE_TASK(seqTaxi)
TASK_PLAY_ANIM(NULL, tlAnimDictTaxiDriver, "leanover_enter", SLOW_BLEND_IN, NORMAL_BLEND_OUT, -1)
TASK_PLAY_ANIM(NULL, tlAnimDictTaxiDriver, "leanover_idle", SLOW_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_LOOPING)
CLOSE_SEQUENCE_TASK(seqTaxi)
TASK_PERFORM_SEQUENCE(g_WaitingTaxiDriver, seqTaxi)
CLEAR_SEQUENCE_TASK(seqTaxi)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SET_DRIVER_PLAY_TURN_AROUND_ANIM return TRUE")
RETURN TRUE
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// determine if group members are still trying to enter the taxi
/// and task them to get in. can time out if
/// NOTE: doesn't safety check g_WaitingTaxi
/// NOTE: setup mirrors parts of SET_PLAYER_GROUP_MEMBERS_INTO_TAXI used by taxi launcher
/// PARAMS:
/// iTimeOut -
/// eReservedPlayerSeat - Seat which player will be using
/// RETURNS:
/// TRUE if taxi driver shouln't drive off yet
FUNC BOOL SHOULD_TAXI_WAIT_FOR_PLAYER_GROUP_MEMBERS_TO_ENTER(INT &iTimeOut, VEHICLE_SEAT eReservedPlayerSeat)
IF HAS_TIME_PASSED(iTimeOut, 2000)
OR iTimeOut = -1
RETURN FALSE
ENDIF
// no group to wait for
IF NOT DOES_GROUP_EXIST(PLAYER_GROUP_ID())
iTimeOut = -1
RETURN FALSE
ENDIF
INT i, j
GET_GROUP_SIZE(PLAYER_GROUP_ID(), j, i)
// no group members
IF (i < 1)
iTimeOut = -1
RETURN FALSE
ENDIF
PED_INDEX tempPed
PED_INDEX GroupPedID
BOOL bApplyEnterTask = TRUE
BOOL bFoundReasonForTaxiToWait = FALSE
VEHICLE_SEAT eTargetSeat
// check first member
GroupPedID = GET_PED_AS_GROUP_MEMBER(PLAYER_GROUP_ID(), 0)
IF NOT IS_PED_INJURED(GroupPedID)
// set target seat (opposite to player's reserved seat)
eTargetSeat = VS_BACK_LEFT
IF eReservedPlayerSeat = VS_BACK_LEFT
eTargetSeat = VS_BACK_RIGHT
ENDIF
bApplyEnterTask = TRUE
// don't allow task if needing to jack player, or if ped is already in the seat / entering
tempPed = GET_PED_IN_VEHICLE_SEAT(g_WaitingTaxi, eTargetSeat)
IF DOES_ENTITY_EXIST(tempPed)
// player already sitting in the seat
IF (tempPed = PLAYER_PED_ID())
bApplyEnterTask = FALSE
CDEBUG2LN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_TAXI_WAIT_FOR_PLAYER_GROUP_MEMBERS_TO_ENTER : NOT tasked, player sat 1st group member eTargetSeat : ", eTargetSeat)
// ped is already sitting in the seat
ELIF (tempPed = GroupPedID)
bApplyEnterTask = FALSE
//CDEBUG1LN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_TAXI_WAIT_FOR_PLAYER_GROUP_MEMBERS_TO_ENTER : NOT tasked, 1st group member already sat in eTargetSeat : ", eTargetSeat)
ENDIF
ENDIF
// don't apply task if config flag is set
IF GET_PED_CONFIG_FLAG(GroupPedID, PCF_DontEnterVehiclesInPlayersGroup, FALSE)
bApplyEnterTask = FALSE
CDEBUG1LN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_TAXI_WAIT_FOR_PLAYER_GROUP_MEMBERS_TO_ENTER : NOT tasked, 1st group member PCF_DontEnterVehiclesInPlayersGroup is set eTargetSeat : ", eTargetSeat)
ENDIF
// don't apply task if he's already getting in the seat
IF TAXI_IS_PED_PERFORMING_TASK(GroupPedID, SCRIPT_TASK_ENTER_VEHICLE)
bApplyEnterTask = FALSE
bFoundReasonForTaxiToWait = TRUE
CDEBUG1LN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_TAXI_WAIT_FOR_PLAYER_GROUP_MEMBERS_TO_ENTER : will return TRUE, 1st group member running enter vehicle task")
ENDIF
IF bApplyEnterTask
//CLEAR_PED_TASKS(GroupPedID)
TASK_ENTER_VEHICLE(GroupPedID, g_WaitingTaxi, DEFAULT_TIME_BEFORE_WARP, eTargetSeat, PEDMOVEBLENDRATIO_RUN, ECF_RESUME_IF_INTERRUPTED | ECF_BLOCK_SEAT_SHUFFLING | ECF_DONT_JACK_ANYONE)
bFoundReasonForTaxiToWait = TRUE
CDEBUG1LN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_TAXI_WAIT_FOR_PLAYER_GROUP_MEMBERS_TO_ENTER : will return TRUE, 1st group member task applied eTargetSeat : ", eTargetSeat)
ENDIF
ENDIF
// if group has two member set second member into front passenger seat
IF (i > 1)
GroupPedID = GET_PED_AS_GROUP_MEMBER(PLAYER_GROUP_ID(), 1)
IF NOT IS_PED_INJURED(GroupPedID)
bApplyEnterTask = TRUE
eTargetSeat = VS_FRONT_RIGHT
// don't allow task if needing to jack player, or if ped is already in the seat / entering
tempPed = GET_PED_IN_VEHICLE_SEAT(g_WaitingTaxi, eTargetSeat)
IF DOES_ENTITY_EXIST(tempPed)
// player already sitting in the seat
IF (tempPed = PLAYER_PED_ID())
bApplyEnterTask = FALSE
CDEBUG1LN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_TAXI_WAIT_FOR_PLAYER_GROUP_MEMBERS_TO_ENTER : NOT tasked, player sat 2nd group member eTargetSeat : ", eTargetSeat)
// ped is already sitting in the seat
ELIF (tempPed = GroupPedID)
bApplyEnterTask = FALSE
//CDEBUG1LN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_TAXI_WAIT_FOR_PLAYER_GROUP_MEMBERS_TO_ENTER : NOT tasked, 2nd group member already sat in eTargetSeat : ", eTargetSeat)
ENDIF
ENDIF
// don't apply task if config flag is set
IF GET_PED_CONFIG_FLAG(GroupPedID, PCF_DontEnterVehiclesInPlayersGroup, FALSE)
bApplyEnterTask = FALSE
CDEBUG1LN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_TAXI_WAIT_FOR_PLAYER_GROUP_MEMBERS_TO_ENTER : NOT tasked, 2nd group member PCF_DontEnterVehiclesInPlayersGroup is set eTargetSeat : ", eTargetSeat)
ENDIF
// don't apply task if he's already getting in the seat
IF TAXI_IS_PED_PERFORMING_TASK(GroupPedID, SCRIPT_TASK_ENTER_VEHICLE)
bApplyEnterTask = FALSE
bFoundReasonForTaxiToWait = TRUE
CDEBUG1LN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_TAXI_WAIT_FOR_PLAYER_GROUP_MEMBERS_TO_ENTER : will return TRUE, 2nd group member running enter vehicle task")
ENDIF
IF bApplyEnterTask
//CLEAR_PED_TASKS(GroupPedID)
TASK_ENTER_VEHICLE(GroupPedID, g_WaitingTaxi, DEFAULT_TIME_BEFORE_WARP, eTargetSeat, PEDMOVEBLENDRATIO_RUN, ECF_RESUME_IF_INTERRUPTED | ECF_BLOCK_SEAT_SHUFFLING | ECF_DONT_JACK_ANYONE)
bFoundReasonForTaxiToWait = TRUE
CDEBUG1LN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_TAXI_WAIT_FOR_PLAYER_GROUP_MEMBERS_TO_ENTER : will return TRUE, 2nd group member task applied eTargetSeat : ", eTargetSeat)
ENDIF
ENDIF
ENDIF
IF bFoundReasonForTaxiToWait
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
PROC SEND_TAXI_TO_DESTINATION()
DRIVINGMODE tempTaxiDrivingMode
FLOAT fDrivingSpeed
IF bDestinationSelected
IF bDropPointSelected
UPDATE_THE_FARE()
IF IS_VEHICLE_DRIVEABLE(g_WaitingTaxi)
IF NOT IS_PED_INJURED(g_WaitingTaxiDriver)
IF IS_TAXI_AT_DESTINATION()
//IF IS_VEHICLE_STOPPED(g_WaitingTaxi)
IF GET_ENTITY_SPEED(g_WaitingTaxi) < 2
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), g_WaitingTaxi, TRUE)
TASK_LEAVE_ANY_VEHICLE(PLAYER_PED_ID())
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SEND_TAXI_TO_DESTINATION -> player tasked to leave taxi reached destination")
ENDIF
ENDIF
TASK_VEHICLE_TEMP_ACTION(g_WaitingTaxiDriver, g_WaitingTaxi, TEMPACT_BRAKE, 5000)
SET_PED_KEEP_TASK(g_WaitingTaxiDriver, TRUE)
bMadeItToDestination = TRUE
eTaxiServiceStage = TAXI_SERVICE_END
#IF IS_DEBUG_BUILD
VECTOR vTempCoords = GET_ENTITY_COORDS(g_WaitingTaxi, FALSE)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SEND_TAXI_TO_DESTINATION() taxi stopped at : ", vTempCoords, " : g_vTaxiDropOffPosition = ", g_vTaxiDropOffPosition)
#ENDIF
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SEND_TAXI_TO_DESTINATION() IS_TAXI_AT_DESTINATION() -> TAXI_SERVICE_END")
ENDIF
ELSE
// play exit from lean first
IF IS_ENTITY_PLAYING_ANIM(g_WaitingTaxiDriver, tlAnimDictTaxiDriver, "leanover_enter")
OR IS_ENTITY_PLAYING_ANIM(g_WaitingTaxiDriver, tlAnimDictTaxiDriver, "leanover_idle")
// B*1563479 - ensure look at is cleared for these anims so he doesn't twist his neck too far
IF IS_PED_HEADTRACKING_PED(g_WaitingTaxiDriver, PLAYER_PED_ID())
TASK_CLEAR_LOOK_AT(g_WaitingTaxiDriver)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SET_DRIVER_PLAY_TURN_AROUND_ANIM cleared look at ready for anim")
ENDIF
// wait to reach idle before reverting
//IF IS_ENTITY_PLAYING_ANIM(g_WaitingTaxiDriver, tlAnimDictTaxiDriver, "leanover_idle")
TASK_PLAY_ANIM(g_WaitingTaxiDriver, tlAnimDictTaxiDriver, "leanover_exit", SLOW_BLEND_IN, SLOW_BLEND_OUT)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SEND_TAXI_TO_DESTINATION() applied leanover_exit anim on driver FC = ", GET_FRAME_COUNT())
//ENDIF
ELIF IS_ENTITY_PLAYING_ANIM(g_WaitingTaxiDriver, tlAnimDictTaxiDriver, "leanover_exit")
SET_ENTITY_ANIM_SPEED(g_WaitingTaxiDriver, tlAnimDictTaxiDriver, "leanover_exit", 1.2) // B* 1552508 - speed it up a little take ages to pull off
iTimer_WaitForGroupMembers = GET_GAME_TIMER()
SET_PLAYER_GROUP_MEMBERS_INTO_TAXI(g_WaitingTaxi, eStoredPlayerSeat)
ELSE
IF NOT TAXI_IS_PED_PERFORMING_TASK(g_WaitingTaxiDriver, SCRIPT_TASK_PERFORM_SEQUENCE)
IF SHOULD_TAXI_WAIT_FOR_PLAYER_GROUP_MEMBERS_TO_ENTER(iTimer_WaitForGroupMembers, eStoredPlayerSeat)
IF NOT TAXI_IS_PED_PERFORMING_TASK(g_WaitingTaxiDriver, SCRIPT_TASK_VEHICLE_TEMP_ACTION)
TASK_VEHICLE_TEMP_ACTION(g_WaitingTaxiDriver, g_WaitingTaxi, TEMPACT_WAIT, 1000000)
ENDIF
ELSE
bTaxiHasHitDestinationLocate = FALSE
IF bHurrying
fDrivingSpeed = TAXI_SPEED_FAST
tempTaxiDrivingMode = taxiDrivingModeHurry
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SEND_TAXI_TO_DESTINATION() using hurry setting")
ELSE
fDrivingSpeed = TAXI_SPEED_NORMAL
tempTaxiDrivingMode = taxiDrivingModeStandard
ENDIF
CLEAR_PED_TASKS(g_WaitingTaxiDriver)
TASK_CLEAR_LOOK_AT(g_WaitingTaxiDriver) // B*1282010 - driver always looking at player
SET_DRIVER_ABILITY(g_WaitingTaxiDriver, 0.5)
OPEN_SEQUENCE_TASK(seqTaxi)
TASK_VEHICLE_DRIVE_TO_COORD_LONGRANGE(NULL, g_WaitingTaxi, g_vTaxiDropOffPosition, fDrivingSpeed, tempTaxiDrivingMode, TAXI_TARGET_REACHED_DIST)
TASK_VEHICLE_PARK(NULL, g_WaitingTaxi, g_vTaxiDropOffPosition, g_fTaxiDropOffHeading, parkTypeTaxiAtDestination, 60, TRUE)
CLOSE_SEQUENCE_TASK(seqTaxi)
TASK_PERFORM_SEQUENCE(g_WaitingTaxiDriver, seqTaxi)
CLEAR_SEQUENCE_TASK(seqTaxi)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SEND_TAXI_TO_DESTINATION() drive to destination task drive longrange sequence set : g_vTaxiDropOffPosition = ", g_vTaxiDropOffPosition)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
FUNC BOOL Is_Any_Nearby_Vehicle_In_Prep_Mission_List(VEHICLE_INDEX &viReturnVeh, VECTOR vCoordsAt, float fRadius)
CONST_INT iSearchVehicles 5
MODEL_NAMES vehList[iSearchVehicles]
vehList[0]=CRUSADER
vehList[1]=BARRACKS
vehList[2]=TRASH
vehList[3]=BOXVILLE3
vehList[4]=FBI2
INT i
//Sequential check for get_nearest_vehicles
REPEAT COUNT_OF(vehList) i
viReturnVeh = GET_CLOSEST_VEHICLE(vCoordsAt, fRadius, vehList[i],
VEHICLE_SEARCH_FLAG_ALLOW_VEHICLE_OCCUPANTS_TO_BE_PERFORMING_A_SCRIPTED_TASK|VEHICLE_SEARCH_FLAG_ALLOW_VEHICLE_OCCUPANTS_TO_BE_PERFORMING_A_NON_DEFAULT_TASK|
VEHICLE_SEARCH_FLAG_RETURN_MISSION_VEHICLES|VEHICLE_SEARCH_FLAG_RETURN_RANDOM_VEHICLES)
IF viReturnVeh<>NULL
CDEBUG1LN(debug_taxi_service,"Found vehicle ",GET_MODEL_NAME_OF_VEHICLE_FOR_DEBUG_ONLY(viReturnVeh)," in range ",fRadius," at ",vCoordsAt)
return TRUE
ENDIF
ENDREPEAT
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Moves taxi away from a moving mission blip
PROC SEPARATE_FROM_MOVING_BLIP()
VECTOR vTemp
FLOAT fTemp
SWITCH eStoryMissionDestination
//B*-1965573
CASE SP_HEIST_RURAL_PREP_1
vTemp = GET_STATIC_BLIP_POSITION(STATIC_BLIP_MISSION_RURAL_P1)
fTemp = GET_DISTANCE_BETWEEN_COORDS(g_vTaxiDropOffPosition,vTemp)
IF fTemp < 100
vTemp = NORMALISE_VECTOR(g_vTaxiDropOffPosition-vTemp)
vTemp = <<g_vTaxiDropOffPosition.X+(vTemp.X*(100-ROUND(fTemp))),g_vTaxiDropOffPosition.Y+(vTemp.Y*(100-ROUND(fTemp))),g_vTaxiDropOffPosition.Z>>
GET_CLOSEST_VEHICLE_NODE_WITH_HEADING(vTemp,g_vTaxiDropOffPosition,g_fTaxiDropOffHeading)
SET_ENTITY_COORDS(g_WaitingTaxi, g_vTaxiDropOffPosition)
SET_ENTITY_HEADING(g_WaitingTaxi, g_fTaxiDropOffHeading)
ENDIF
BREAK
ENDSWITCH
ENDPROC
PROC Separate_From_Prep_Mission_Vehicles(FLOAT fRange = 15.0)
//If it's not a prep mission, exit the check
IF NOT (IS_MISSION_AVAILABLE(SP_HEIST_JEWELRY_PREP_1B)
OR IS_MISSION_AVAILABLE(SP_HEIST_JEWELRY_PREP_2A)
OR IS_MISSION_AVAILABLE(SP_HEIST_RURAL_PREP_1)
OR IS_MISSION_AVAILABLE(SP_MISSION_FBI_4_PREP_1)
OR MISSION_FLOW_GET_RUNNING_MISSION() = SP_HEIST_JEWELRY_PREP_1B
OR MISSION_FLOW_GET_RUNNING_MISSION() = SP_HEIST_JEWELRY_PREP_2A
OR MISSION_FLOW_GET_RUNNING_MISSION() = SP_HEIST_RURAL_PREP_1
OR MISSION_FLOW_GET_RUNNING_MISSION() = SP_MISSION_FBI_4_PREP_1)
CPRINTLN(debug_taxi_service,"No prep mission running, exiting check")
EXIT
ENDIF
VEHICLE_INDEX viClosest = NULL
BOOL bAreaClearOfVehicles = FALSE
int iNode = 1
VECTOR vNewPos = g_vTaxiDropOffPosition
WHILE (NOT bAreaClearOfVehicles) AND iNode < 10
//Move taxi ahead
bAreaClearOfVehicles = TRUE
IF Is_Any_Nearby_Vehicle_In_Prep_Mission_List(viClosest,vNewPos,fRange)
bAreaClearOfVehicles = FALSE
CDEBUG1LN(debug_taxi_service,"Getting node #",iNode)
IF GET_NTH_CLOSEST_VEHICLE_NODE(g_vTaxiDropOffPosition,iNode, vNewPos)
CDEBUG1LN(debug_taxi_service,"Found one @ ",vNewPos)
iNode+=1
ENDIF
ENDIF
ENDWHILE
//Move taxi if there were vehicles to be cleared
IF VDIST2(vNewPos,g_vTaxiDropOffPosition)>2
GET_SAFE_COORD_FOR_PED(vNewPos,FALSE,g_vTaxiDropOffPosition)
CPRINTLN(debug_taxi_service,"New taxi dropoff: ",g_vTaxiDropOffPosition)
ENDIF
ENDPROC
/// PURPOSE:
/// handles the player choosing to skip to the destination
PROC SKIP_JOURNEY_TO_DESTINATION()
BOOL bHaveAssetsForTaxiSkipLoaded
BOOL bSkipTime
FLOAT fGroundZ = 1
// don't allow player controls to interfer during a skip
DISABLE_ALL_CONTROL_ACTIONS(PLAYER_CONTROL)
DISABLE_ALL_CONTROL_ACTIONS(CAMERA_CONTROL)
DISABLE_ALL_CONTROL_ACTIONS(FRONTEND_CONTROL)
SWITCH eSkipJourneyState
CASE SKIP_JOURNEY_STATE_FADE_OUT
DISABLE_CELLPHONE(TRUE)
IF HAS_TIME_PASSED(iSkipJourneyTimer, 500)
DO_SCREEN_FADE_OUT(250)
START_AUDIO_SCENE("FADE_OUT_WORLD_250MS_SCENE")
eSkipJourneyState = SKIP_JOURNEY_STATE_FADED_OUT
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : eSkipJourneyState = SKIP_JOURNEY_STATE_FADED_OUT")
ENDIF
BREAK
CASE SKIP_JOURNEY_STATE_FADED_OUT
IF IS_SCREEN_FADED_OUT()
AND IS_AUDIO_SCENE_ACTIVE("FADE_OUT_WORLD_250MS_SCENE")
IF IS_VEHICLE_DRIVEABLE(g_WaitingTaxi)
SET_VEHICLE_RADIO_ENABLED(g_WaitingTaxi, FALSE) // B*1183700 - radio heard at low level during skip
ENDIF
CLEAR_PRINTS()
RENDER_SCRIPT_CAMS(FALSE,FALSE)
// Cleanup the meter is it will no longer be used.
IF IS_NAMED_RENDERTARGET_REGISTERED("taxi")
RELEASE_NAMED_RENDERTARGET("taxi")
ENDIF
IF DOES_ENTITY_EXIST(objMeter)
DELETE_OBJECT(objMeter)
SET_MODEL_AS_NO_LONGER_NEEDED(modelMeter)
ENDIF
IF IS_CAM_ACTIVE(camMeter)
SET_PARTICLE_FX_CAM_INSIDE_VEHICLE(FALSE) // B*1549323 - stops rain inside taxi
g_bTaxiShouldForcePhoneDislayOnHud = FALSE // reset global used for B*2053172 - force phone display on HUD
SET_CAM_ACTIVE(camMeter, FALSE)
RENDER_SCRIPT_CAMS(FALSE, FALSE)
UNLOCK_MINIMAP_POSITION()
UNLOCK_MINIMAP_ANGLE()
SET_RADAR_ZOOM(0)
ENDIF
SET_GROUP_INTO_CAB(eStoredPlayerSeat)
iSkipJourneyTimer = GET_GAME_TIMER() // start the timer which monitors the total amount of time faded down - to ensure we always fade back up
IF bSelectingAnotherDestination
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : bSelectingAnotherDestination true ")
bDropPointSelected = FALSE
bSelectingAnotherDestination = FALSE
currentTaxiDestination = AllTaxiDestinations[iCurrentHighlightedPosition]
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : iCurrentHighlightedPosition = ", iCurrentHighlightedPosition)
#IF IS_DEBUG_BUILD
IF DOES_BLIP_EXIST(currentTaxiDestination.BlipID)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : GET_BLIP_INFO :", GET_BLIP_NAME(currentTaxiDestination.BlipID))
ENDIF
#ENDIF
ENDIF
// if we haven't yet calculated the drop off point do so now to get the warp to coords and heading
IF NOT bDropPointSelected
iDesinationNodeSearchNumber = 0
eGenerateSafeDestinationState = TAXI_GSDS_INITIAL_TRIGGER_AREAS_CHECK
eSkipJourneyState = SKIP_JOURNEY_STATE_WAIT_GEN_DESTINATION_INFO
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : eSkipJourneyState = SKIP_JOURNEY_STATE_WAIT_GEN_DESTINATION_INFO")
ELSE
// B*1392355 - ensure any prestreamed cutscenes at the pickup location are cleaned up before requesting the next or loading scene at a new position
MISSION_FLOW_CLEANUP_MISSION_INTRO_CUTSCENE()
eSkipJourneyState = SKIP_JOURNEY_STATE_MOVE_TAXI_TO_DESTINATION
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : eSkipJourneyState = SKIP_JOURNEY_STATE_MOVE_TAXI_TO_DESTINATION")
ENDIF
ELSE
START_AUDIO_SCENE("FADE_OUT_WORLD_250MS_SCENE")
ENDIF
BREAK
CASE SKIP_JOURNEY_STATE_WAIT_GEN_DESTINATION_INFO
IF GENERATE_TAXI_DROP_OFF_PLAYER_DESTINATION(currentTaxiDestination.BlipID, g_vTaxiDropOffPosition, g_fTaxiDropOffHeading)
// B*1392355 - ensure any prestreamed cutscenes at the pickup location are cleaned up before requesting the next or loading scene at a new position
MISSION_FLOW_CLEANUP_MISSION_INTRO_CUTSCENE()
eSkipJourneyState = SKIP_JOURNEY_STATE_MOVE_TAXI_TO_DESTINATION
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : eSkipJourneyState = SKIP_JOURNEY_STATE_MOVE_TAXI_TO_DESTINATION")
ENDIF
BREAK
CASE SKIP_JOURNEY_STATE_MOVE_TAXI_TO_DESTINATION
// ensure the status of g_iFlowIntroCutsceneRequestID = NULL_OFFMISSION_CUTSCENE_REQUEST before making another request
IF g_iFlowIntroCutsceneRequestID = NULL_OFFMISSION_CUTSCENE_REQUEST
// B*1703207 - ensure property streamvol are cancelled before playr warp (needs to come frame after MISSION_FLOW_CLEANUP_MISSION_INTRO_CUTSCENE() call for B*2061680)
CANCEL_PROPERTY_MAP_LOADS()
UPDATE_DIST_TRAVELED_IN_TAXI_STAT_FOR_SKIP() // B*1211249
CALCULATE_SKIP_COST()
CALCULATE_AND_APPLY_TIME_PASSED()
MISSION_STAT_SYSTEM_ALERT_TIME_WARP()
CLEAR_AREA(g_vTaxiDropOffPosition, 5.0, TRUE)
//Check if there's a prep mission vehicle nearby, wait for it to pass
Separate_From_Prep_Mission_Vehicles()
IF NOT IS_PED_INJURED(g_WaitingTaxiDriver)
AND IS_VEHICLE_DRIVEABLE(g_WaitingTaxi)
SET_ENTITY_COORDS(g_WaitingTaxi, g_vTaxiDropOffPosition)
SET_ENTITY_HEADING(g_WaitingTaxi, g_fTaxiDropOffHeading)
FREEZE_ENTITY_POSITION(g_WaitingTaxi, TRUE)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : set taxi to location - coords (z+1) :", g_vTaxiDropOffPosition, " heading : ", g_fTaxiDropOffHeading)
ENDIF
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
NEW_LOAD_SCENE_STOP() // stop any ongoing load scene ready for new request
// clear the area
CLEAR_AREA(g_vTaxiDropOffPosition, 5000, TRUE, FALSE)
CLEAR_AREA_OF_OBJECTS(g_vTaxiDropOffPosition, 5000)
CLEAR_AREA_OF_PROJECTILES(g_vTaxiDropOffPosition, 30.0)
REMOVE_PARTICLE_FX_IN_RANGE(g_vTaxiDropOffPosition, 5000) // Clear up any smoke / fire effects
REMOVE_DECALS_IN_RANGE(g_vTaxiDropOffPosition, 5000) // Clear up blood decals in the area.
// Make sure no mission triggers are loaded ahead of the new load scene.
IF g_eMissionSceneToCleanup != SP_MISSION_NONE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : Cleaning up any loaded mission triggers ahead of starting new load scene.")
Set_Leave_Area_Flag_For_Mission(g_eMissionSceneToCleanup, TRUE)
MISSION_FLOW_RELEASE_TRIGGER_SCENE_ASSETS(g_eMissionSceneToCleanup)
ENDIF
// If we are warping to a mission trigger with a trigger scene, block it from loading until after
// the new load scene is done.
eMissionAtBlip = MISSION_FLOW_GET_MISSION_AT_BLIP(currentTaxiDestination.BlipID)
IF eMissionAtBlip != SP_MISSION_NONE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : Found mission ", GET_SP_MISSION_DISPLAY_STRING_FROM_ID(eMissionAtBlip), " to preload a lead-in for.")
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() :Blocking loading of trigger until after new load scene.")
Set_Leave_Area_Flag_For_Mission(eMissionAtBlip, TRUE)
ENDIF
bSkipJourneyLoadSceneStarted = FALSE
eSkipJourneyState = SKIP_JOURNEY_STATE_SETUP_LOAD_SCENE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : eSkipJourneyState = SKIP_JOURNEY_STATE_SETUP_LOAD_SCENE")
ENDIF
BREAK
// Create load scene at the drop off position
CASE SKIP_JOURNEY_STATE_SETUP_LOAD_SCENE
IF NEW_LOAD_SCENE_START_SPHERE(g_vTaxiDropOffPosition, REPLAY_LOAD_SCENE_SIZE) // increased from 600 to match replay controller's setup
bSkipJourneyLoadSceneStarted = TRUE
eSkipJourneyState = SKIP_JOURNEY_STATE_LOAD_SCENE_THEN_REQUEST_LEADIN
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : new load scene created at : ", g_vTaxiDropOffPosition, " framecount = ", GET_FRAME_COUNT())
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : eSkipJourneyState = SKIP_JOURNEY_STATE_LOAD_SCENE_THEN_REQUEST_LEADIN")
ELSE
// skip new load scene if we were not able to set one up in time
IF HAS_TIME_PASSED(iSkipJourneyTimer, 2500)
eSkipJourneyState = SKIP_JOURNEY_STATE_LOAD_SCENE_THEN_REQUEST_LEADIN
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : new load scene start timed out")
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : eSkipJourneyState = SKIP_JOURNEY_STATE_LOAD_SCENE_THEN_REQUEST_LEADIN")
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : waiting on new load scene request...")
ENDIF
ENDIF
BREAK
CASE SKIP_JOURNEY_STATE_LOAD_SCENE_THEN_REQUEST_LEADIN
//#1927212 - Wait for load scene to finish before requesting lead-in assets.
IF IS_NEW_LOAD_SCENE_ACTIVE()
IF IS_NEW_LOAD_SCENE_LOADED()
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : New load scene finished...calling NEW_LOAD_SCENE_STOP()")
// If we are warping to a mission trigger with a trigger scene, start preloading
// the assets it will require now the load scene is done.
IF eMissionAtBlip != SP_MISSION_NONE
NEW_LOAD_SCENE_STOP() // we need to clear load scene for mission asset loading
bSkipJourneyLoadSceneStarted = FALSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : Starting preloading of lead-in for ", GET_SP_MISSION_DISPLAY_STRING_FROM_ID(eMissionAtBlip), ".")
MISSION_FLOW_PRELOAD_ASSETS_FOR_MISSION_TRIGGER(eMissionAtBlip)
Set_Leave_Area_Flag_For_Mission(eMissionAtBlip, FALSE)
ENDIF
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : eSkipJourneyState = SKIP_JOURNEY_STATE_REQUEST_ASSETS_AT_DESTINATION")
eSkipJourneyState = SKIP_JOURNEY_STATE_REQUEST_ASSETS_AT_DESTINATION
// time out for new load scene taking too long
ELIF HAS_TIME_PASSED(iSkipJourneyTimer, 20000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : New load scene timed out!")
// If we are warping to a mission trigger with a trigger scene, start preloading
// the assets it will require now the load scene is done.
IF eMissionAtBlip != SP_MISSION_NONE
NEW_LOAD_SCENE_STOP() // we need to clear load scene for mission asset loading
bSkipJourneyLoadSceneStarted = FALSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : Starting preloading of lead-in for ", GET_SP_MISSION_DISPLAY_STRING_FROM_ID(eMissionAtBlip), ".")
MISSION_FLOW_PRELOAD_ASSETS_FOR_MISSION_TRIGGER(eMissionAtBlip)
Set_Leave_Area_Flag_For_Mission(eMissionAtBlip, FALSE)
ENDIF
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : eSkipJourneyState = SKIP_JOURNEY_STATE_REQUEST_ASSETS_AT_DESTINATION")
eSkipJourneyState = SKIP_JOURNEY_STATE_REQUEST_ASSETS_AT_DESTINATION
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : Waiting for IS_NEW_LOAD_SCENE_LOADED() at destination")
ENDIF
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : No load scene active!")
// If we are warping to a mission trigger with a trigger scene, start preloading
// the assets it will require now the load scene is done.
IF eMissionAtBlip != SP_MISSION_NONE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : Starting preloading of lead-in for ", GET_SP_MISSION_DISPLAY_STRING_FROM_ID(eMissionAtBlip), ".")
MISSION_FLOW_PRELOAD_ASSETS_FOR_MISSION_TRIGGER(eMissionAtBlip)
Set_Leave_Area_Flag_For_Mission(eMissionAtBlip, FALSE)
ENDIF
bSkipJourneyLoadSceneStarted = FALSE // we don't call NEW_LOAD_SCENE_STOP() in this instance because it's not active
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : eSkipJourneyState = SKIP_JOURNEY_STATE_REQUEST_ASSETS_AT_DESTINATION")
eSkipJourneyState = SKIP_JOURNEY_STATE_REQUEST_ASSETS_AT_DESTINATION
ENDIF
BREAK
CASE SKIP_JOURNEY_STATE_REQUEST_ASSETS_AT_DESTINATION
RESET_VEHICLE_GEN_LOADED_CHECKS() // B*1354066 - populate veh gens whilst faded down
INSTANTLY_FILL_PED_POPULATION()
INSTANTLY_FILL_VEHICLE_POPULATION()
POPULATE_NOW()
// Story missions
IF eMissionAtBlip != SP_MISSION_NONE // wait for a trigger scene to load if we are warping to a mission trigger blip
// If the mission we are warping to has a time of day restriction, ensure the time is set to bypass the TOD cutscene
bSkipTime = TRUE
IF (g_sMissionStaticData[eMissionAtBlip].startHour = NULL_HOUR AND g_sMissionStaticData[eMissionAtBlip].endHour = NULL_HOUR)
bSkipTime = FALSE
ENDIF
IF bSkipTime
IF (GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL AND NOT IS_BIT_SET(g_sMissionStaticData[eMissionAtBlip].settingsBitset, MF_INDEX_DO_TRIGGER_TOD_M))
OR (GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN AND NOT IS_BIT_SET(g_sMissionStaticData[eMissionAtBlip].settingsBitset, MF_INDEX_DO_TRIGGER_TOD_F))
OR (GET_CURRENT_PLAYER_PED_ENUM() = CHAR_TREVOR AND NOT IS_BIT_SET(g_sMissionStaticData[eMissionAtBlip].settingsBitset, MF_INDEX_DO_TRIGGER_TOD_T))
bSkipTime = FALSE
ENDIF
ENDIF
IF bSkipTime
IF IS_TIME_BETWEEN_THESE_HOURS(g_sMissionStaticData[eMissionAtBlip].startHour, g_sMissionStaticData[eMissionAtBlip].endHour)
bSkipTime = FALSE
ENDIF
ENDIF
//Are we out of mission hours?
IF bSkipTime
// Out of hours, need to skip time to start hour.
ADVANCE_CLOCK_TIME_TO(g_sMissionStaticData[eMissionAtBlip].startHour, 0, 0)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : Game is faded out for taxi warp. mission warping to has TOD restriction, skipped time to advance, hr : ", g_sMissionStaticData[eMissionAtBlip].startHour)
ENDIF
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : Game is faded out for taxi warp. blip not for mission so skipping g_bMissionTriggerLoading wait")
ENDIF
// Check nearest valid RCM #424931 & minigame B*1351272 (off road races only at moment)
eClosestRCMission = GET_NEAREST_VALID_RC_MISSION()
eSkipJourneyState = SKIP_JOURNEY_STATE_LOADING_ASSETS_AT_DESTINATION
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : eSkipJourneyState = SKIP_JOURNEY_STATE_LOADING_ASSETS_AT_DESTINATION")
BREAK
// Wait for assets to load
CASE SKIP_JOURNEY_STATE_LOADING_ASSETS_AT_DESTINATION
bHaveAssetsForTaxiSkipLoaded= TRUE
IF IS_TAXI_WAITING_FOR_THIS_RC_MISSION(eClosestRCMission) // RCs in ranges
bHaveAssetsForTaxiSkipLoaded = FALSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : Waiting on assets at destination ... IS_TAXI_WAITING_FOR_THIS_RC_MISSION")
ENDIF
IF NOT ARE_MINIGAMES_IN_RANGE_LOADED(g_vTaxiDropOffPosition) // minigames
bHaveAssetsForTaxiSkipLoaded = FALSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : Waiting on assets at destination ... ARE_MINIGAMES_IN_RANGE_LOADED")
ENDIF
IF NOT HAVE_ALL_VEHICLE_GENS_LOADED_NEAR_PLAYER() // scripted vehicle vens
bHaveAssetsForTaxiSkipLoaded = FALSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : Waiting on assets at destination ... HAVE_ALL_VEHICLE_GENS_LOADED_NEAR_PLAYER")
ENDIF
IF NOT HAS_INSTANT_FILL_VEHICLE_POPULATION_FINISHED() // veh population
bHaveAssetsForTaxiSkipLoaded = FALSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : Waiting on assets at destination ... HAS_INSTANT_FILL_VEHICLE_POPULATION_FINISHED")
ENDIF
IF bSkipJourneyLoadSceneStarted // new load scene
IF IS_NEW_LOAD_SCENE_ACTIVE()
IF NOT IS_NEW_LOAD_SCENE_LOADED()
bHaveAssetsForTaxiSkipLoaded = FALSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : Waiting on assets at destination ... IS_NEW_LOAD_SCENE_LOADED()")
ENDIF
ENDIF
ENDIF
IF (eMissionAtBlip != SP_MISSION_NONE AND g_bMissionTriggerLoading) // Story missions - wait for any trigger scenes to be created.
bHaveAssetsForTaxiSkipLoaded = FALSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : Waiting on assets at destination... g_bMissionTriggerLoading")
ENDIF
// fail safe time out if something is failing to load
IF HAS_TIME_PASSED(iSkipJourneyTimer, 29500) // B*2044625 - upped max fade time to 20 secs (note 500 sec wait once everything is in place) knock off 2 sec for the streaming one framer
bHaveAssetsForTaxiSkipLoaded = TRUE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : Waiting on assets at destination timed out iSkipJourneyTimer = ", iSkipJourneyTimer)
ENDIF
// assets have loaded
IF bHaveAssetsForTaxiSkipLoaded
// get rid of the stream vol
IF bSkipJourneyLoadSceneStarted
IF IS_NEW_LOAD_SCENE_ACTIVE()
NEW_LOAD_SCENE_STOP()
ENDIF
bSkipJourneyLoadSceneStarted = FALSE
ENDIF
//B* 2277341: Check if the current Z is below the ground Z
IF bUsedFloorZ
bUsedFloorZ = FALSE
GET_GROUND_Z_FOR_3D_COORD(g_vTaxiDropOffPosition+<<0,0,100>>,fGroundZ)
IF fGroundZ > g_vTaxiDropOffPosition.z
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : Floor Z (",g_vTaxiDropOffPosition.z,") was below ground Z (",fGroundZ,"), correcting Z")
g_vTaxiDropOffPosition.z = fGroundZ + 0.5
ENDIF
ENDIF
//Check if there's a prep mission vehicle nearby, wait for it to pass
Separate_From_Prep_Mission_Vehicles(12)
//B*-1965573
SEPARATE_FROM_MOVING_BLIP()
IF NOT IS_PED_INJURED(g_WaitingTaxiDriver)
AND IS_VEHICLE_DRIVEABLE(g_WaitingTaxi)
FREEZE_ENTITY_POSITION(g_WaitingTaxi, FALSE)
SET_ENTITY_HEADING(g_WaitingTaxi, g_fTaxiDropOffHeading)
SET_ENTITY_COORDS(g_WaitingTaxi, g_vTaxiDropOffPosition)
SET_VEHICLE_ON_GROUND_PROPERLY(g_WaitingTaxi)
TASK_VEHICLE_TEMP_ACTION(g_WaitingTaxiDriver, g_WaitingTaxi, TEMPACT_BRAKE, 5000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : set taxi pos : ", g_vTaxiDropOffPosition, " heading : ", g_fTaxiDropOffHeading)
ENDIF
iSkipJourneyTimer = GET_GAME_TIMER()
eSkipJourneyState = SKIP_JOURNEY_STATE_FADE_IN
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : eSkipJourneyState = SKIP_JOURNEY_STATE_FADE_IN")
ENDIF
BREAK
CASE SKIP_JOURNEY_STATE_FADE_IN
IF HAS_TIME_PASSED(iSkipJourneyTimer, 500)
IF IS_AUDIO_SCENE_ACTIVE("FADE_OUT_WORLD_250MS_SCENE")
STOP_AUDIO_SCENE("FADE_OUT_WORLD_250MS_SCENE")
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : stopped audio scene FADE_OUT_WORLD_250MS_SCENE")
ENDIF
IF IS_VEHICLE_DRIVEABLE(g_WaitingTaxi)
SET_VEHICLE_RADIO_ENABLED(g_WaitingTaxi, TRUE) // B*1183700 - radio heard at low level during skip
ENDIF
IF NOT IS_REPLAY_BEING_SET_UP()
DO_SCREEN_FADE_IN(250)
ENDIF
eSkipJourneyState = SKIP_JOURNEY_STATE_FADED_IN
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SKIP_JOURNEY_TO_DESTINATION() : eSkipJourneyState = SKIP_JOURNEY_STATE_FADED_IN")
ENDIF
BREAK
CASE SKIP_JOURNEY_STATE_FADED_IN
IF IS_SCREEN_FADED_IN() OR IS_REPLAY_BEING_SET_UP()
//If we have preloaded assets for a scene but have not warped into its activation range, unload them.
IF NOT g_bTriggerSceneActive
AND eMissionAtBlip != SP_MISSION_NONE
AND eMissionAtBlip != SP_HEIST_DOCKS_PREP_1 //Complicated scene that deletes ropes when released. Shouldn't be unloaded in this case.
AND eMissionAtBlip != SP_HEIST_JEWELRY_PREP_1A // 2146270 - don't release the assets as the mission will start right away after taxi warp
MISSION_FLOW_RELEASE_TRIGGER_SCENE_ASSETS(eMissionAtBlip)
ENDIF
DISABLE_CELLPHONE(FALSE)
//IF GET_ENTITY_SPEED(g_WaitingTaxi) < 2
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), g_WaitingTaxi, TRUE)
TASK_LEAVE_ANY_VEHICLE(PLAYER_PED_ID())
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SEND_TAXI_TO_DESTINATION -> player tasked to leave taxi reached destination")
ENDIF
ENDIF
//ENDIF
TASK_VEHICLE_TEMP_ACTION(g_WaitingTaxiDriver, g_WaitingTaxi, TEMPACT_BRAKE, 5000)
SET_PED_KEEP_TASK(g_WaitingTaxiDriver, TRUE)
bMadeItToDestination = TRUE
#IF IS_DEBUG_BUILD
VECTOR vTempCoords
vTempCoords = GET_ENTITY_COORDS(g_WaitingTaxi, FALSE)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SKIP_JOURNEY_TO_DESTINATION() : taxi stopped at : ", vTempCoords, " : g_vTaxiDropOffPosition = ", g_vTaxiDropOffPosition)
#ENDIF
eTaxiServiceStage = TAXI_SERVICE_END
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SKIP_JOURNEY_TO_DESTINATION() : eTaxiServiceStage = TAXI_SERVICE_END")
eSkipJourneyState = SKIP_JOURNEY_STATE_SKIP_FINISHED
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SKIP_JOURNEY_TO_DESTINATION() : eSkipJourneyState = SKIP_JOURNEY_STATE_SKIP_FINISHED")
ENDIF
BREAK
CASE SKIP_JOURNEY_STATE_SKIP_FINISHED
BREAK
ENDSWITCH
ENDPROC
FUNC BOOL IS_PLAYER_PASSENGER_IN_VALID_TAXI_CAB()
IF g_WaitingTaxiDriver = NULL
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " IS_PLAYER_PASSENGER_IN_VALID_TAXI_CAB() : return FALSE g_WaitingTaxiDriver = NULL")
RETURN FALSE
ENDIF
IF NOT IS_PED_INJURED(g_WaitingTaxiDriver)
IF IS_VEHICLE_DRIVEABLE(g_WaitingTaxi)
IF NOT IS_PED_SITTING_IN_VEHICLE(g_WaitingTaxiDriver, g_WaitingTaxi)
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " IS_PLAYER_PASSENGER_IN_VALID_TAXI_CAB() : return FALSE driver not sat in taxi")
RETURN FALSE
ENDIF
ELSE
RETURN FALSE
ENDIF
ELSE
RETURN FALSE
ENDIF
IF IS_PLAYER_PLAYING(PLAYER_ID())
IF IS_PED_SITTING_IN_ANY_VEHICLE(PLAYER_PED_ID())
IF IS_VEHICLE_DRIVEABLE(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()))
IF IS_CAR_A_TAXI_MODEL(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()))
PED_INDEX DriverID
DriverID = GET_PED_IN_VEHICLE_SEAT(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()))
IF NOT (DriverID = PLAYER_PED_ID())
IF NOT IS_PED_INJURED(DriverID)
g_bPlayerIsInTaxi = TRUE
// IF IS_PLAYER_CONTROL_ON(PLAYER_ID())
// SET_PLAYER_CONTROL(PLAYER_ID(), FALSE, SPC_LEAVE_CAMERA_CONTROL_ON)
// ENDIF
SET_PLAYER_CAN_DO_DRIVE_BY(PLAYER_ID(), FALSE)
HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_WEAPON_ICON)
STOP_PED_SPEAKING(PLAYER_PED_ID(), TRUE)
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " IS_PLAYER_PASSENGER_IN_VALID_TAXI_CAB() : return TRUE")
RETURN TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " IS_PLAYER_PASSENGER_IN_VALID_TAXI_CAB() : return FALSE player not sitting in vehicle")
ENDIF
ENDIF
IF DOES_CAM_EXIST(camMeter)
IF IS_CAM_ACTIVE(camMeter)
SET_PARTICLE_FX_CAM_INSIDE_VEHICLE(FALSE) // B*1549323 - stops rain inside taxi
g_bTaxiShouldForcePhoneDislayOnHud = FALSE // reset global used for B*2053172 - force phone display on HUD
ENDIF
SET_CAM_ACTIVE(camMeter, FALSE)
DESTROY_CAM(camMeter)
RENDER_SCRIPT_CAMS(FALSE, FALSE)
UNLOCK_MINIMAP_POSITION()
UNLOCK_MINIMAP_ANGLE()
SET_RADAR_ZOOM(0)
ENDIF
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " IS_PLAYER_PASSENGER_IN_VALID_TAXI_CAB() : return FALSE")
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// checks for script needing to cleanup
/// PARAMS:
/// eCurrentStage - the taxi service stage
/// RETURNS:
/// TRUE if the script should cleanup
FUNC BOOL SHOULD_TAXI_SERVICE_END_EARLY(TAXI_SERVICE_STATE eCurrentStage)
// cleanup if the player is injured / dead
IF IS_PED_INJURED(PLAYER_PED_ID())
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "SHOULD_TAXI_SERVICE_END_EARLY : return TRUE : player injured check")
RETURN TRUE
ENDIF
// cleanup if player char has changed
IF GET_PLAYER_PED_ENUM(PLAYER_PED_ID()) <> charWhenTaxiLaunched
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "SHOULD_TAXI_SERVICE_END_EARLY : return TRUE : player char changed check")
RETURN TRUE
ENDIF
// commented out for B*1518083 - now allow player to get in but just exit option if no taxi destinations available - this allows them to plot custom waypoint whilst sat in the back
// check if no blips are available
//IF iStoredNumberOfBlips = 0
// CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "SHOULD_TAXI_SERVICE_END_EARLY : return TRUE : iStoredNumberOfBlips = 0")
// RETURN TRUE
//ENDIF
// veh handle not valid
IF NOT DOES_ENTITY_EXIST(g_WaitingTaxi)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "SHOULD_TAXI_SERVICE_END_EARLY : return TRUE : DOES_ENTITY_EXIST(g_WaitingTaxi)")
RETURN TRUE
ENDIF
// vehicle wrecked
IF NOT IS_VEHICLE_DRIVEABLE(g_WaitingTaxi)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "SHOULD_TAXI_SERVICE_END_EARLY : return TRUE : IS_VEHICLE_DRIVEABLE(g_WaitingTaxi)")
RETURN TRUE
ENDIF
// driver handle not valid
IF NOT DOES_ENTITY_EXIST(g_WaitingTaxiDriver)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "SHOULD_TAXI_SERVICE_END_EARLY : return TRUE : DOES_ENTITY_EXIST(g_WaitingTaxiDriver)")
RETURN TRUE
ENDIF
// ped hurt
IF IS_PED_INJURED(g_WaitingTaxiDriver)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "SHOULD_TAXI_SERVICE_END_EARLY : return TRUE : IS_PED_INJURED(g_WaitingTaxiDriver)")
RETURN TRUE
ENDIF
// B*1561424 - don't fail if skipping taxi journey for these conditions
IF eTaxiJourneyState != TAXI_JOURNEY_STATE_SKIP_JOURNEY
// stage specific checks
IF eCurrentStage = TAXI_SERVICE_STATE_PLAYER_IN_TAXI
// cleanup if player has wanted level
IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "SHOULD_TAXI_SERVICE_END_EARLY : return TRUE : player has wanted level check")
RETURN TRUE
ENDIF
// timer for vehicle rolled / stuck
IF IS_VEHICLE_STUCK_TIMER_UP(g_WaitingTaxi, VEH_STUCK_HUNG_UP, HUNG_UP_TIME)
OR IS_VEHICLE_STUCK_TIMER_UP(g_WaitingTaxi, VEH_STUCK_JAMMED, JAMMED_TIME)
OR IS_VEHICLE_STUCK_TIMER_UP(g_WaitingTaxi, VEH_STUCK_ON_ROOF, ROOF_TIME)
OR IS_VEHICLE_STUCK_TIMER_UP(g_WaitingTaxi, VEH_STUCK_ON_SIDE, ROOF_TIME)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "SHOULD_TAXI_SERVICE_END_EARLY : return TRUE : taxi stuck")
RETURN TRUE
ENDIF
ENDIF
VECTOR vTaxiCoords = GET_ENTITY_COORDS(g_WaitingTaxi, FALSE)
// bullet fired near taxi
IF IS_BULLET_IN_AREA(vTaxiCoords, 7.0, FALSE)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_TAXI_SERVICE_END_EARLY : return TRUE : bullet fired near taxi")
RETURN TRUE
ENDIF
FLOAT fProjectileRadiusCheck = 15.0
VECTOR vMin, vMax // is one of the player's projectiles nearby?
vMin = vTaxiCoords
vMax = vMin
vMin.x= vMin.x - fProjectileRadiusCheck
vMin.y = vMin.y -fProjectileRadiusCheck
vMin.z = vMin.z - fProjectileRadiusCheck
vMax.x = vMax.x + fProjectileRadiusCheck
vMax.y = vMax.y + fProjectileRadiusCheck
vMax.z = vMax.z + fProjectileRadiusCheck
IF IS_PROJECTILE_IN_AREA(vMin, vMax, TRUE)
CPRINTLN(DEBUG_TAXI_SERVICE, " : SHOULD_TAXI_SERVICE_END_EARLY : return TRUE : projectile near taxi")
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// handles the specific PLAYER_CONTROL which need to be blocked during the jourey
/// Also calls ALLOW_ALTERNATIVE_SCRIPT_CONTROLS_LAYOUT
PROC BLOCK_SPECIFIC_PLAYER_CONTROLS_FOR_TAXI_JOURNEY_THIS_FRAME()
// B*1293059
ALLOW_ALTERNATIVE_SCRIPT_CONTROLS_LAYOUT(PLAYER_CONTROL)
ALLOW_ALTERNATIVE_SCRIPT_CONTROLS_LAYOUT(CAMERA_CONTROL)
ALLOW_ALTERNATIVE_SCRIPT_CONTROLS_LAYOUT(FRONTEND_CONTROL)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_SELECT_NEXT_WEAPON)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_SELECT_PREV_WEAPON)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_SELECT_NEXT_WEAPON)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_SELECT_PREV_WEAPON)
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_DUCK) // B*1979327 - stop player char ducking when pressing X
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_AIM) // B*1460540 - block aim during taxi journey (note INPUT_VEH_AIM & INPUT_VEH_PASSENGER_AIM didn't fix this for some reason
DISABLE_CELLPHONE_CAMERA_APP_THIS_FRAME_ONLY() // B* 1494563 - block cellphone camera
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_FRONTEND_PAUSE_ALTERNATE) // B* 2229157 - Disable alternate pause so Esc can go back instead of pausing on PC.
// B*1425062 - player exits cab when pressing triangle whilst internet is on screen
IF IS_BROWSER_OPEN()
OR IS_PHONE_ONSCREEN()
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_EXIT)
ENDIF
ENDPROC
/// PURPOSE:
/// calls the relevant suppress procs needed during taxi journey
PROC SUPPRESS_AMBIENT_REACTIONS_FOR_TAXI_JOURNEY_THIS_FRAME()
IF IS_PLAYER_PLAYING(PLAYER_ID())
SET_ALL_RANDOM_PEDS_FLEE_THIS_FRAME(PLAYER_ID())
// B*1380049 - driving knocking ped over gave player a wanted level
SUPPRESS_WITNESSES_CALLING_POLICE_THIS_FRAME(PLAYER_ID())
SUPPRESS_CRIME_THIS_FRAME(PLAYER_ID(), CRIME_RUN_REDLIGHT)
SUPPRESS_CRIME_THIS_FRAME(PLAYER_ID(), CRIME_RECKLESS_DRIVING)
SUPPRESS_CRIME_THIS_FRAME(PLAYER_ID(), CRIME_SPEEDING)
SUPPRESS_CRIME_THIS_FRAME(PLAYER_ID(), CRIME_DRIVE_AGAINST_TRAFFIC)
SUPPRESS_CRIME_THIS_FRAME(PLAYER_ID(), CRIME_RUNOVER_PED)
//SUPPRESS_CRIME_THIS_FRAME(PLAYER_ID(), CRIME_RUNOVER_COP)
ENDIF
ENDPROC
PROC SET_CAMERA_ROT_TO_SAME_AS_VEHICLE(VEHICLE_INDEX inCar, CAMERA_INDEX &inCam, VECTOR vAdditionalRot)
VECTOR vCarRot
FLOAT fPitch, fHeading, fRoll
IF NOT IS_ENTITY_DEAD(inCar)
IF DOES_CAM_EXIST(inCam)
vCarRot = GET_ENTITY_ROTATION(inCar)
fRoll = vCarRot.y // use the cars roll
VECTOR vNorm = NORMALISE_VECTOR(GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(g_WaitingTaxi, vAdditionalRot) - GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(g_WaitingTaxi, vTaxiCamOffset))
GET_PITCH_AND_HEADING_FROM_DIRECTION_VECTOR(vNorm, fPitch, fHeading)
SET_CAM_ROT(inCam, <<fPitch, fRoll, fHeading>>)
//POINT_CAM_AT_COORD(inCam, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(g_WaitingTaxi, vAdditionalRot))
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SET_CAMERA_ROT_TO_SAME_AS_VEHICLE() @@@@@@@@: fPitch = ", fPitch, " fRoll = ", fRoll, " fHeading = ", fHeading)
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// updates the in taxi camera's position, rotation and fov
PROC UPDATE_TAXI_CAM_POSITIONING()
IF DOES_CAM_EXIST(camMeter)
//UPDATE_IN_TAXI_ROT_BASED_OFF_PLAYER_CONTROLS() not currently in use MP had request to make camera static
SET_CAMERA_ROT_TO_SAME_AS_VEHICLE(g_WaitingTaxi, camMeter, vTaxiCamFixedRotation)
//SET_CAM_COORD(camMeter, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(g_WaitingTaxi, vTaxiCamOffset)) // cam is attached so pos doesn't need updating.
SET_CAM_FOV(camMeter, camMeterFOV)
SET_CAM_NEAR_CLIP(camMeter, 0.01)
SET_CAM_IS_INSIDE_VEHICLE(camMeter, TRUE)
SET_SCRIPTED_CAMERA_IS_FIRST_PERSON_THIS_FRAME() // B*2057207 - new command to make scripted shot seem like it's first person
ENDIF
ENDPROC
/// PURPOSE:
/// check to reason to block player using taxi controls
/// RETURNS:
/// TRUE if need to block control
FUNC BOOL SHOULD_TAXI_CONTROLS_BE_BLOCKED_THIS_FRAME()
// don't allow input whilst skipping the journey
IF eTaxiJourneyState = TAXI_JOURNEY_STATE_SKIP_JOURNEY
//CDEBUG2LN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SHOULD_TAXI_CONTROLS_BE_BLOCKED_THIS_FRAME() : return TRUE : eTaxiJourneyState = TAXI_JOURNEY_STATE_SKIP_JOURNEY")
RETURN TRUE
ENDIF
// B*1395644 - don't allow control whilst internet is on screen
IF IS_BROWSER_OPEN()
//CDEBUG2LN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SHOULD_TAXI_CONTROLS_BE_BLOCKED_THIS_FRAME() : return TRUE : IS_BROWSER_OPEN")
RETURN TRUE
ENDIF
IF IS_PAUSE_MENU_ACTIVE()
//CDEBUG2LN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SHOULD_TAXI_CONTROLS_BE_BLOCKED_THIS_FRAME() : return TRUE : IS_PAUSE_MENU_ACTIVE")
RETURN TRUE
ENDIF
IF IS_CUSTOM_MENU_ON_SCREEN()
//CDEBUG2LN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SHOULD_TAXI_CONTROLS_BE_BLOCKED_THIS_FRAME() : return TRUE : IS_CUSTOM_MENU_ON_SCREEN")
RETURN TRUE
ENDIF
IF IS_SCRIPT_HUD_DISPLAYING(HUDPART_TRANSITIONHUD)
//CDEBUG2LN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SHOULD_TAXI_CONTROLS_BE_BLOCKED_THIS_FRAME() : return TRUE : IS_SCRIPT_HUD_DISPLAYING(HUDPART_TRANSITIONHUD)")
RETURN TRUE
ENDIF
IF IS_PHONE_ONSCREEN()
//CDEBUG2LN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SHOULD_TAXI_CONTROLS_BE_BLOCKED_THIS_FRAME() : return TRUE : IS_PHONE_ONSCREEN")
RETURN TRUE
ENDIF
IF IS_SYSTEM_UI_BEING_DISPLAYED()
//CDEBUG2LN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SHOULD_TAXI_CONTROLS_BE_BLOCKED_THIS_FRAME() : return TRUE : IS_SYSTEM_UI_BEING_DISPLAYED")
RETURN TRUE
ENDIF
IF IS_SELECTOR_CAM_ACTIVE()
//CDEBUG2LN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SHOULD_TAXI_CONTROLS_BE_BLOCKED_THIS_FRAME() : return TRUE : IS_SELECTOR_CAM_ACTIVE")
RETURN TRUE
ENDIF
//B* 1913692: Disable while mission passed screen is up
IF g_bResultScreenDisplaying OR g_bResultScreenPrepared
//CDEBUG2LN(debug_taxi_service,"SHOULD_TAXI_CONTROLS_BE_BLOCKED_THIS_FRAME: YES because results screen is being displayed")
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
PROC CLEAR_TAXI_DESTINATION_LIST()
INT i
REPEAT MAX_NUMBER_OF_TAXI_DESTINATIONS i
AllTaxiDestinations[i].BlipID = NULL
ENDREPEAT
iTotalNumberOfTaxiDestinations = 0
iStoredTaxiWaypointBlipDestinationIndex = -1
vStoredTaxiWaypointBlipDestinationCoords = << 0.0, 0.0, 0.0 >>
iCountBlipsAddedToDestinationListThisFrame = 0
ENDPROC
PROC MOVE_TAXI_DESTINATION_UP_LIST(INT iListItemID)
TAXI_DEST NextDest
TAXI_DEST ThisDest
IF (iListItemID > 0)
ThisDest = AllTaxiDestinations[iListItemID]
NextDest = AllTaxiDestinations[iListItemID - 1]
AllTaxiDestinations[iListItemID - 1] = ThisDest
AllTaxiDestinations[iListItemID] = NextDest
ENDIF
ENDPROC
PROC MOVE_TAXI_DESTINATION_DOWN_LIST(INT iListItemID)
TAXI_DEST NextDest
TAXI_DEST ThisDest
IF (iListItemID < (MAX_NUMBER_OF_TAXI_DESTINATIONS - 1))
ThisDest = AllTaxiDestinations[iListItemID]
NextDest = AllTaxiDestinations[iListItemID + 1]
AllTaxiDestinations[iListItemID + 1] = ThisDest
AllTaxiDestinations[iListItemID] = NextDest
ENDIF
ENDPROC
PROC MOVE_TAXI_DESTINATION_TO_BOTTOM_OF_LIST(INT iListItemID)
IF (iListItemID < (MAX_NUMBER_OF_TAXI_DESTINATIONS - 1))
MOVE_TAXI_DESTINATION_DOWN_LIST(iListItemID)
MOVE_TAXI_DESTINATION_TO_BOTTOM_OF_LIST(iListItemID + 1)
ENDIF
ENDPROC
PROC SHIFT_LIST_DOWN_1_PLACE_FROM_POSITION(INT iPosition)
INT i
TAXI_DEST ValueAbove
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SHIFT_LIST_DOWN_1_PLACE_FROM_POSITION - start, position = ", iPosition)
// start at the end of the list and work up
i = MAX_NUMBER_OF_TAXI_DESTINATIONS - 1 // last item in list
WHILE (i > iPosition)
ValueAbove = AllTaxiDestinations[i - 1]
AllTaxiDestinations[i] = ValueAbove
// store waypoint blip destination index so we can test for it changing
IF ((i - 1) = iStoredTaxiWaypointBlipDestinationIndex)
iStoredTaxiWaypointBlipDestinationIndex = i
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " SHIFT_LIST_DOWN_1_PLACE_FROM_POSITION - waypoint blip index shifted i = ", i)
ENDIF
i--
ENDWHILE
ENDPROC
PROC INSERT_NEW_DESTINATION_TO_LIST(TAXI_DEST newDestination, INT iPosition)
SHIFT_LIST_DOWN_1_PLACE_FROM_POSITION(iPosition)
AllTaxiDestinations[iPosition] = newDestination
// store waypoint blip destination index so we can test for it changing
IF GET_SPRITE_FOR_BLIP(AllTaxiDestinations[iPosition].BlipID) = GET_WAYPOINT_BLIP_ENUM_ID()
iStoredTaxiWaypointBlipDestinationIndex = iPosition
vStoredTaxiWaypointBlipDestinationCoords = GET_BLIP_COORDS(AllTaxiDestinations[iPosition].BlipID)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " INSERT_NEW_DESTINATION_TO_LIST - waypoint blip index set iPosition = ", iPosition,
" vStoredTaxiWaypointBlipDestinationCoords set : ", vStoredTaxiWaypointBlipDestinationCoords)
ENDIF
#IF IS_DEBUG_BUILD
IF DOES_BLIP_EXIST(newDestination.BlipID)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " INSERT_NEW_DESTINATION_TO_LIST - set iPosition = ", iPosition, " BlipSprite is ",
ENUM_TO_INT(GET_BLIP_SPRITE(AllTaxiDestinations[iPosition].BlipID)), " named ", GET_BLIP_NAME(AllTaxiDestinations[iPosition].BlipID))
ENDIF
#ENDIF
ENDPROC
PROC REPLACE_LIST_DESTINATION_WITH_NEW_DESTINATION(TAXI_DEST newDestination, INT iPosition)
AllTaxiDestinations[iPosition] = newDestination
// store waypoint blip destination index so we can test for it changing
IF GET_SPRITE_FOR_BLIP(AllTaxiDestinations[iPosition].BlipID) = GET_WAYPOINT_BLIP_ENUM_ID()
iStoredTaxiWaypointBlipDestinationIndex = iPosition
vStoredTaxiWaypointBlipDestinationCoords = GET_BLIP_COORDS(AllTaxiDestinations[iPosition].BlipID)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " REPLACE_LIST_DESTINATION_WITH_NEW_DESTINATION - waypoint blip index updated iPosition = ", iPosition,
" vStoredTaxiWaypointBlipDestinationCoords set : ", vStoredTaxiWaypointBlipDestinationCoords)
ENDIF
#IF IS_DEBUG_BUILD
IF DOES_BLIP_EXIST(newDestination.BlipID)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " INSERT_NEW_DESTINATION_TO_LIST - set iPosition = ", iPosition, " BlipSprite is ",
ENUM_TO_INT(GET_BLIP_SPRITE(AllTaxiDestinations[iPosition].BlipID)), " named ", GET_BLIP_NAME(AllTaxiDestinations[iPosition].BlipID))
ENDIF
#ENDIF
ENDPROC
PROC ADD_TAXI_DESTINATION_TO_LIST(TAXI_DEST inTaxiDestination, BOOL bListNearestOnly)
INT i
INT iFirstOfType
i = 0
iFirstOfType = 0
IF GET_SPRITE_FOR_BLIP(inTaxiDestination.BlipID) = RADAR_TRACE_INVALID
EXIT
ENDIF
// 2. find first item of this type in list
REPEAT MAX_NUMBER_OF_TAXI_DESTINATIONS i
IF (GET_SPRITE_FOR_BLIP(AllTaxiDestinations[i].BlipID) = GET_SPRITE_FOR_BLIP(inTaxiDestination.BlipID) )
iFirstOfType = i
i = MAX_NUMBER_OF_TAXI_DESTINATIONS
ELSE
IF i = iTotalNumberOfTaxiDestinations
iFirstOfType = i
i = MAX_NUMBER_OF_TAXI_DESTINATIONS
ENDIF
ENDIF
ENDREPEAT
// 3. Insert into list, based on the distance from player and its blip type
i = 0
REPEAT MAX_NUMBER_OF_TAXI_DESTINATIONS i
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " ADD_TAXI_DESTINATION_TO_LIST - Start of Repeat - i = ", i)
IF (i < iFirstOfType)
i = iFirstOfType
ENDIF
IF (i < iTotalNumberOfTaxiDestinations)
IF (GET_SPRITE_FOR_BLIP(AllTaxiDestinations[i].BlipID) = GET_SPRITE_FOR_BLIP(inTaxiDestination.BlipID))
IF IS_TAXI_DEST_NEARER_THAN_TAXI_DEST(inTaxiDestination, AllTaxiDestinations[i])
IF (bListNearestOnly)
REPLACE_LIST_DESTINATION_WITH_NEW_DESTINATION(inTaxiDestination, i)
i = MAX_NUMBER_OF_TAXI_DESTINATIONS
EXIT
ELSE
INSERT_NEW_DESTINATION_TO_LIST(inTaxiDestination, i)
iTotalNumberOfTaxiDestinations++
i = MAX_NUMBER_OF_TAXI_DESTINATIONS
EXIT
ENDIF
ELSE
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " ADD_TAXI_DESTINATION_TO_LIST - destination is not nearer than other of same type!")
IF (bListNearestOnly)
i = MAX_NUMBER_OF_TAXI_DESTINATIONS
EXIT
ENDIF
ENDIF
ELSE
INSERT_NEW_DESTINATION_TO_LIST(inTaxiDestination, i)
iTotalNumberOfTaxiDestinations++
i = MAX_NUMBER_OF_TAXI_DESTINATIONS
EXIT
ENDIF
ELSE
INSERT_NEW_DESTINATION_TO_LIST(inTaxiDestination, i)
iTotalNumberOfTaxiDestinations++
i = MAX_NUMBER_OF_TAXI_DESTINATIONS
EXIT
ENDIF
ENDREPEAT
ENDPROC
PROC GET_TAXI_DESTINATION_FROM_SPRITE_BLIP(BLIP_INDEX &RadarBlipID, TAXI_DEST &ReturnedTaxiDest)
// store blip id
ReturnedTaxiDest.BlipID = RadarBlipID
// get street names
IF NOT (ReturnedTaxiDest.BlipID = g_CustomDropOffBlip)
VECTOR vCoords = GET_RADAR_BLIP_COORDS(ReturnedTaxiDest.BlipID)
GET_STREET_NAME_AT_COORD(vCoords, ReturnedTaxiDest.iHashname1, ReturnedTaxiDest.iHashname2)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_DESTINATION_FROM_SPRITE_BLIP() : vCoords = ", vCoords,
" ReturnedTaxiDest.iHashname1 = ", ReturnedTaxiDest.iHashname1, " ReturnedTaxiDest.iHashname2 = ", ReturnedTaxiDest.iHashname2)
ELSE
GET_STREET_NAME_AT_COORD(g_vTaxiDropOffPosition, ReturnedTaxiDest.iHashname1, ReturnedTaxiDest.iHashname2)
ENDIF
ENDPROC
FUNC BOOL IS_DISTANCE_WITHIN_RANGE(BLIP_INDEX BlipID)
// destintion must be at least the minimum distance away (unless its a mission blip)
FLOAT fDistance
IF NOT (GET_SPRITE_FOR_BLIP(BlipID) = taxiStandardBlipSprite)
fDistance = GET_BLIP_DISTANCE(BlipID)
IF (fDistance > 50.0)
//AND (fDistance < 1200.0)
RETURN(TRUE)
ENDIF
ELSE
RETURN(TRUE)
ENDIF
RETURN(FALSE)
ENDFUNC
PROC ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(BLIP_SPRITE BlipSprite, BOOL bListNearestOnly)
TAXI_DEST NewTaxiDest
BOOL bFlag
BLIP_INDEX RadarBlip
RadarBlip = GET_FIRST_BLIP_INFO_ID(BlipSprite)
INT iMaxBlipsAllowedProcessPerFrame = 20
eRADAR_BLIP_TYPE eTempBlipType
SP_MISSIONS eSP_Mission
WHILE DOES_BLIP_EXIST(RadarBlip)
// allow more than one blip to process per frame - long run i think needs rewrite to remove wait call
IF iCountBlipsAddedToDestinationListThisFrame >= iMaxBlipsAllowedProcessPerFrame
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS - WAIT iCountBlipsAddedToDestinationListThisFrame : ", iCountBlipsAddedToDestinationListThisFrame)
WAIT(0)
iCountBlipsAddedToDestinationListThisFrame = 0
IF NOT IS_TAXI_SERVICE_SAFE_TO_RUN()
TAXI_SERVICE_SCRIPT_CLEANUP()
ENDIF
UPDATE_TAXI_CAM_POSITIONING()
BLOCK_SPECIFIC_PLAYER_CONTROLS_FOR_TAXI_JOURNEY_THIS_FRAME()
SUPPRESS_AMBIENT_REACTIONS_FOR_TAXI_JOURNEY_THIS_FRAME()
ENDIF
IF (iTotalNumberOfTaxiDestinations < MAX_NUMBER_OF_TAXI_DESTINATIONS)
IF IS_BLIP_VISIBLE(RadarBlip)
IF IS_DISTANCE_WITHIN_RANGE(RadarBlip)
IF NOT SHOULD_WE_IGNORE_THIS_BLIP(RadarBlip)//, BlipSprite)
// if this is a mission blip, is it higher or lower or normal
bFlag = FALSE
SWITCH BlipSprite
CASE RADAR_TRACE_OBJECTIVE FALLTHRU
CASE RADAR_TRACE_OBJECTIVE_BLUE FALLTHRU
CASE RADAR_TRACE_OBJECTIVE_GREEN FALLTHRU
CASE RADAR_TRACE_OBJECTIVE_RED FALLTHRU
CASE RADAR_TRACE_OBJECTIVE_YELLOW FALLTHRU
CASE RADAR_TRACE_MICHAEL_FAMILY FALLTHRU
CASE RADAR_TRACE_TREVOR_FAMILY FALLTHRU
CASE RADAR_TRACE_FRANKLIN_FAMILY FALLTHRU
CASE RADAR_TRACE_MICHAEL_TREVOR_FAMILY FALLTHRU
CASE RADAR_TRACE_MICHAEL_FAMILY_EXILE FALLTHRU
CASE RADAR_TRACE_TREVOR_FAMILY_EXILE FALLTHRU
CASE RADAR_TRACE_SIMEON_FAMILY FALLTHRU
CASE RADAR_TRACE_LAMAR_FAMILY FALLTHRU
CASE RADAR_TRACE_LESTER_FAMILY FALLTHRU
CASE RADAR_TRACE_CHINESE_STRAND FALLTHRU
CASE RADAR_TRACE_FBI_OFFICERS_STRAND FALLTHRU
CASE RADAR_TRACE_FINANCIER_STRAND FALLTHRU
CASE RADAR_TRACE_SOLOMON_STRAND FALLTHRU
CASE RADAR_TRACE_MARTIN_MADRAZZO FALLTHRU
CASE RADAR_TRACE_FINALE_BANK_HEIST FALLTHRU
CASE RADAR_TRACE_BIOLAB_HEIST FALLTHRU
CASE RADAR_TRACE_DOCKS_HEIST FALLTHRU
CASE RADAR_TRACE_FBI_HEIST FALLTHRU
CASE RADAR_TRACE_JEWELRY_HEIST FALLTHRU
CASE RADAR_TRACE_NICE_HOUSE_HEIST FALLTHRU
CASE RADAR_TRACE_RURAL_BANK_HEIST FALLTHRU
CASE RADAR_TRACE_ASSASSINS_MARK FALLTHRU
CASE RADAR_TRACE_ABIGAIL FALLTHRU
CASE RADAR_TRACE_BARRY FALLTHRU
CASE RADAR_TRACE_CLETUS FALLTHRU
CASE RADAR_TRACE_DOM FALLTHRU
CASE RADAR_TRACE_EPSILON FALLTHRU
CASE RADAR_TRACE_FANATIC FALLTHRU
CASE RADAR_TRACE_JOSH FALLTHRU
CASE RADAR_TRACE_MARYANN FALLTHRU
CASE RADAR_TRACE_MINUTE FALLTHRU
CASE RADAR_TRACE_OMEGA FALLTHRU
CASE RADAR_TRACE_PAPARAZZO FALLTHRU
CASE RADAR_TRACE_TONYA FALLTHRU
CASE RADAR_TRACE_CELEBRITY_THEFT FALLTHRU
CASE RADAR_TRACE_RANDOM_CHARACTER FALLTHRU
CASE RADAR_TRACE_RANDOM_MALE FALLTHRU
CASE RADAR_TRACE_RANDOM_FEMALE FALLTHRU
CASE RADAR_TRACE_PLANNING_LOCATIONS FALLTHRU
CASE RADAR_TRACE_SAFEHOUSE FALLTHRU
CASE RADAR_TRACE_GARAGE FALLTHRU
CASE RADAR_TRACE_DOCK FALLTHRU
CASE RADAR_TRACE_HANGAR FALLTHRU
CASE RADAR_TRACE_GUN_SHOP FALLTHRU
CASE RADAR_TRACE_POLICE_STATION FALLTHRU
CASE RADAR_TRACE_POLICE FALLTHRU
//CASE RADAR_TRACE_FIRE FALLTHRU
CASE RADAR_TRACE_HOSPITAL FALLTHRU
//CASE RADAR_TRACE_AIRPORT FALLTHRU
CASE RADAR_TRACE_BUSINESS FALLTHRU
CASE RADAR_TRACE_BUSINESS_FOR_SALE FALLTHRU
CASE RADAR_TRACE_HELICOPTER FALLTHRU
//CASE RADAR_TRACE_STATION FALLTHRU
CASE RADAR_TRACE_ACTIVITIES FALLTHRU
CASE RADAR_TRACE_ARMS_DEALING FALLTHRU
CASE RADAR_TRACE_BASKETBALL FALLTHRU
//CASE RADAR_TRACE_BOWLING FALLTHRU
CASE RADAR_TRACE_CABERET_CLUB FALLTHRU
CASE RADAR_TRACE_COMEDY_CLUB FALLTHRU
CASE RADAR_TRACE_CINEMA FALLTHRU
CASE RADAR_TRACE_DARTS FALLTHRU
//CASE RADAR_TRACE_DRAG_RACE FALLTHRU
CASE RADAR_TRACE_FLIGHT_SCHOOL FALLTHRU
CASE RADAR_TRACE_GOLF FALLTHRU
CASE RADAR_TRACE_HUNTING FALLTHRU
CASE RADAR_TRACE_MUSIC_VENUE FALLTHRU
CASE RADAR_TRACE_OFF_ROAD_RACING FALLTHRU
CASE RADAR_TRACE_POOL FALLTHRU
CASE RADAR_TRACE_RACEFLAG FALLTHRU
CASE RADAR_TRACE_RAMPAGE FALLTHRU
CASE RADAR_TRACE_SHOOTING_RANGE FALLTHRU
CASE RADAR_TRACE_STRIP_CLUB FALLTHRU
CASE RADAR_TRACE_TENNIS FALLTHRU
CASE RADAR_TRACE_TOW_TRUCK FALLTHRU
CASE RADAR_TRACE_TRIATHLON FALLTHRU
CASE RADAR_TRACE_VINEWOOD_TOURS FALLTHRU
CASE RADAR_TRACE_WEED_STASH FALLTHRU
CASE RADAR_TRACE_BARBER FALLTHRU
CASE RADAR_TRACE_CAR_MOD_SHOP FALLTHRU
CASE RADAR_TRACE_BENNYS FALLTHRU
CASE RADAR_TRACE_GANG_VEHICLE FALLTHRU // vehicle impound (trace might be placeholder)
CASE RADAR_TRACE_CLOTHES_STORE FALLTHRU
//CASE RADAR_TRACE_GYM FALLTHRU
CASE RADAR_TRACE_INTERNET_CAFE FALLTHRU
CASE RADAR_TRACE_TATTOO FALLTHRU
CASE RADAR_TRACE_BAR FALLTHRU
CASE RADAR_TRACE_BURGER_SHOT FALLTHRU
//CASE RADAR_TRACE_CLUCKIN_BELL FALLTHRU
//CASE RADAR_TRACE_DRIVE_THRU FALLTHRU
CASE RADAR_TRACE_RESTAURANT FALLTHRU
//CASE RADAR_TRACE_TACO_VAN FALLTHRU
CASE RADAR_TRACE_RACE_LAND FALLTHRU // B*2045170 - Country Races
CASE RADAR_TRACE_YOGA FALLTHRU
CASE RADAR_TRACE_POI FALLTHRU
CASE RADAR_TRACE_SHRINK FALLTHRU
CASE RADAR_TRACE_FINANCIER_STRAND_GREY FALLTHRU
CASE RADAR_TRACE_TREVOR_FAMILY_GREY FALLTHRU
CASE RADAR_TRACE_TREVOR_FAMILY_RED FALLTHRU
CASE RADAR_TRACE_FRANKLIN_FAMILY_GREY FALLTHRU
CASE RADAR_TRACE_FRANKLIN_FAMILY_BLUE FALLTHRU
CASE RADAR_TRACE_FRANKLIN_A FALLTHRU
CASE RADAR_TRACE_FRANKLIN_B FALLTHRU
CASE RADAR_TRACE_FRANKLIN_C FALLTHRU
CASE RADAR_TRACE_FRIEND_FRANKLIN_P FALLTHRU
CASE RADAR_TRACE_FRIEND_FRANKLIN_X FALLTHRU
CASE RADAR_TRACE_FRIEND_MICHAEL_P FALLTHRU
CASE RADAR_TRACE_FRIEND_MICHAEL_X FALLTHRU
CASE RADAR_TRACE_FRIEND_TREVOR_P FALLTHRU
CASE RADAR_TRACE_FRIEND_TREVOR_X FALLTHRU
CASE RADAR_TRACE_FRIEND_LAMAR FALLTHRU
CASE RADAR_TRACE_FRIEND FALLTHRU
CASE RADAR_TRACE_DEVIN FALLTHRU
CASE RADAR_TRACE_STINGER FALLTHRU
CASE RADAR_TRACE_ZTYPE FALLTHRU
CASE RADAR_TRACE_PROPERTY FALLTHRU
CASE RADAR_TRACE_FAIRGROUND FALLTHRU
CASE RADAR_TRACE_MONROE FALLTHRU
CASE RADAR_TRACE_FIRETRUCK FALLTHRU
CASE RADAR_TRACE_SPIKES FALLTHRU
CASE RADAR_TRACE_DRILL FALLTHRU
CASE RADAR_TRACE_MINIGUN2 FALLTHRU
CASE RADAR_TRACE_CHINOOK FALLTHRU
CASE RADAR_TRACE_SUBMARINE FALLTHRU
CASE RADAR_TRACE_GAS_GRENADE FALLTHRU
CASE RADAR_TRACE_BUGSTAR FALLTHRU
CASE RADAR_TRACE_GETAWAY_CAR FALLTHRU
CASE RADAR_TRACE_TOW FALLTHRU
CASE RADAR_TRACE_GARBAGE
bFlag = TRUE
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS - BlipSprite = FOUND!")
BREAK
// B*1506184 - Radar traces where we need to filter out blips which aren't supported (moving mission blips)
CASE RADAR_TRACE_HEIST_PREP
eSP_Mission = GET_BLIPS_ACTIVE_STORY_MISSION(RadarBlip)
IF eSP_Mission = SP_MISSION_FBI_4_PREP_1 // : STATIC_BLIP_MISSION_FBI_OFFICERS4_P1 : HEAT Prep 1 : Steal Garbage Truck
OR eSP_Mission = SP_HEIST_RURAL_PREP_1 // : STATIC_BLIP_MISSION_RURAL_P1 : The Paleto Score Prep : Ambush military convoy to nick minigun and body armour
OR eSP_Mission = SP_HEIST_JEWELRY_PREP_1B // : STATIC_BLIP_MISSION_JEWELRY_P1B : The Jewel Store Job Prep 1B : Steal LCPD tactical squad van to nick carbine rifles
OR eSP_Mission = SP_HEIST_JEWELRY_PREP_2A // : STATIC_BLIP_MISSION_JEWELRY_P2A : The Jewel Store Job Prep 2A : Intercept delivery van containing BZ grenades
bFlag = FALSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS - BlipSprite blocked, detected moving prep blipSprite")
ELSE
bFlag = TRUE
ENDIF
BREAK
DEFAULT
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS - BlipSprite = SOMETHING ELSE")
bFlag = FALSE
// allow custom waypoint
IF BlipSprite = taxiWaypointBlipSprite
bFlag = TRUE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS - waypoint blip found")
// only allow location mission blips
ELIF BlipSprite = taxiStandardBlipSprite
//eTempBlipType = GET_BLIP_INFO_ID_TYPE(RadarBlip)
#IF IS_DEBUG_BUILD DEBUG_PRINT_BLIP_TYPE_TO_TTY(RadarBlip) #ENDIF
// temp until GET_BLIP_INFO_ID_TYPE is fixed - only allow blue and yellow blips
// allow might still want to check colour since script sometimes have to fudge the blip types
IF IS_BLIP_COLOUR_ALLOWED_FOR_STANDARD_BLIP(RadarBlip)
bFlag = TRUE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS - standard blip found ")
ENDIF
ENDIF
BREAK
ENDSWITCH
// if this is a mission blip, check if its the only mission blip to display
IF DOES_BLIP_EXIST(g_OnlyMissionBlipToDisplayOnTaxiMeter)
IF (GET_SPRITE_FOR_BLIP(RadarBlip) = taxiStandardBlipSprite)
IF NOT (g_OnlyMissionBlipToDisplayOnTaxiMeter = RadarBlip)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS - only a single mission blip has been authorized, and this aint it.")
bFlag = FALSE
ENDIF
ENDIF
ENDIF
IF (bFlag)
bFlag = FALSE
IF IS_BLIP_VISIBLE(RadarBlip)
eTempBlipType = GET_BLIP_INFO_ID_TYPE(RadarBlip)
//#IF IS_DEBUG_BUILD DEBUG_PRINT_BLIP_TYPE_TO_TTY(RadarBlip) #ENDIF
IF (eTempBlipType = BLIPTYPE_COORDS)
OR (eTempBlipType = BLIPTYPE_CONTACT)
OR (eTempBlipType = BLIPTYPE_CHAR)
OR (eTempBlipType = BLIPTYPE_VEHICLE)
bFlag = TRUE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS - blip type acceptable+")
ENDIF
ENDIF
IF (bFlag)
GET_TAXI_DESTINATION_FROM_SPRITE_BLIP(RadarBlip, NewTaxiDest)
ADD_TAXI_DESTINATION_TO_LIST(NewTaxiDest, bListNearestOnly)
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS - blip added to destinations BlipSprite = ", BlipSprite)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS - (iTotalNumberOfTaxiDestinations = MAX_NUMBER_OF_TAXI_DESTINATIONS)")
ENDIF
iCountBlipsAddedToDestinationListThisFrame++
RadarBlip = GET_NEXT_BLIP_INFO_ID(BlipSprite)
ENDWHILE
ENDPROC
PROC INIT_TAXI_DESTINATIONS()
INT i
iTotalNumberOfTaxiDestinations = 0
// 1. clear current list
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " INIT_TAXI_DESTINATIONS - clearing destination list... ")
CLEAR_TAXI_DESTINATION_LIST()
// 2. Use Dereks commands to grab each radar blip and add it to the the list
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " INIT_TAXI_DESTINATIONS - creating new destination list... ")
// mission - top priority
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(taxiStandardBlipSprite , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(taxiWaypointBlipSprite , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_OBJECTIVE , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_OBJECTIVE_BLUE , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_OBJECTIVE_GREEN , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_OBJECTIVE_RED , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_OBJECTIVE_YELLOW , FALSE)
// contacts - next priority
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_MICHAEL_FAMILY , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_TREVOR_FAMILY , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_FRANKLIN_FAMILY , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_MICHAEL_TREVOR_FAMILY, FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_MICHAEL_FAMILY_EXILE , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_TREVOR_FAMILY_EXILE , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_SIMEON_FAMILY , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_LAMAR_FAMILY , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_LESTER_FAMILY , FALSE)
// mission trigger blips
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_CHINESE_STRAND , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_FBI_OFFICERS_STRAND , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_FINANCIER_STRAND , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_SOLOMON_STRAND , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_MARTIN_MADRAZZO , FALSE)
// Heist blips
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_FINALE_BANK_HEIST, FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_BIOLAB_HEIST , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_DOCKS_HEIST , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_FBI_HEIST , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_JEWELRY_HEIST , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_NICE_HOUSE_HEIST , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_RURAL_BANK_HEIST , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_FINANCIER_STRAND_GREY, TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_TREVOR_FAMILY_GREY , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_TREVOR_FAMILY_RED , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_FRANKLIN_FAMILY_GREY , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_FRANKLIN_FAMILY_BLUE , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_FRANKLIN_A , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_FRANKLIN_B , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_FRANKLIN_C , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_FIRETRUCK , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_SPIKES , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_DRILL , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_MINIGUN2 , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_CHINOOK , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_SUBMARINE , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_GAS_GRENADE , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_BUGSTAR , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_GETAWAY_CAR , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_TOW , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_GARBAGE , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_HEIST_PREP , FALSE)
// Car Steal blips
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_DEVIN , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_STINGER , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_ZTYPE , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_PROPERTY , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_FAIRGROUND , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_MONROE , TRUE)
// procedural missions.
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_ABIGAIL , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_BARRY , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_CLETUS , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_DOM , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_EPSILON , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_FANATIC , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_JOSH , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_MARYANN , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_MINUTE , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_OMEGA , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_PAPARAZZO , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_TONYA , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_CELEBRITY_THEFT , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_RANDOM_CHARACTER , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_RANDOM_MALE , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_RANDOM_FEMALE , FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_SHRINK , TRUE)
// safe house & services
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_PLANNING_LOCATIONS, FALSE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_SAFEHOUSE , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_GARAGE , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_DOCK , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_HANGAR , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_GUN_SHOP , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_POLICE_STATION , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_POLICE , TRUE)
//ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_FIRE , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_HOSPITAL , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_BUSINESS , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_BUSINESS_FOR_SALE, TRUE)
// transport
//ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_AIRPORT , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_HELICOPTER , TRUE)
// ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_STATION , TRUE)
// Activities & Minigames
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_FRIEND_FRANKLIN_P, TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_FRIEND_FRANKLIN_X, TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_FRIEND_MICHAEL_P, TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_FRIEND_MICHAEL_X, TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_FRIEND_TREVOR_P, TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_FRIEND_TREVOR_X, TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_FRIEND_LAMAR, TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_FRIEND, TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_ACTIVITIES , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_ARMS_DEALING , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_ASSASSINS_MARK , FALSE) // B*1323779 - Lester and Assassination missions share same blip so have to list all
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_BASKETBALL , TRUE)
//ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_BOWLING , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_CABERET_CLUB , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_COMEDY_CLUB , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_CINEMA , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_DARTS , TRUE)
//ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_DRAG_RACE , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_FLIGHT_SCHOOL , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_GOLF , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_HUNTING , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_MUSIC_VENUE , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_OFF_ROAD_RACING , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_POOL , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_RACEFLAG , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_RAMPAGE , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_SHOOTING_RANGE , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_STRIP_CLUB , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_TENNIS , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_TOW_TRUCK , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_TRIATHLON , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_VINEWOOD_TOURS , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_WEED_STASH , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_YOGA , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_POI , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_RACE_LAND , TRUE) // B*2045170 - Country Races
// shops
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_BARBER , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_CAR_MOD_SHOP , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_BENNYS , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_GANG_VEHICLE , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_CLOTHES_STORE , TRUE)
//ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_GYM , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_INTERNET_CAFE , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_TATTOO , TRUE)
// food & drink
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_BAR , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_BURGER_SHOT , TRUE)
//ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_CLUCKIN_BELL , TRUE)
//ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_DRIVE_THRU , TRUE)
ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_RESTAURANT , TRUE)
//ADD_RADAR_SPRITES_TO_TAXI_DESTINATIONS(RADAR_TRACE_TACO_VAN , TRUE)
// other
iStoredCountedMissionLocations = COUNT_MISSION_BLIPS_ON_RADAR()
iStoredNumberOfBlips = GET_NUMBER_OF_ACTIVE_BLIPS()
// set the current selected blip
IF GET_MISSION_FLAG()
IF iStoredCountedMissionLocations = 0
IF DOES_BLIP_EXIST(g_FirstBlipInTaxiMeter)
REPEAT MAX_NUMBER_OF_TAXI_DESTINATIONS i
IF DOES_BLIP_EXIST(AllTaxiDestinations[i].BlipID)
IF (AllTaxiDestinations[i].BlipID = g_FirstBlipInTaxiMeter)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " First Blip in Taxi meter forced ")
iCurrentHighlightedPosition = i
i = MAX_NUMBER_OF_TAXI_DESTINATIONS
ENDIF
ENDIF
ENDREPEAT
ENDIF
ENDIF
ELSE
IF NOT (g_FirstBlipInTaxiMeter = NULL)
g_FirstBlipInTaxiMeter = NULL
ENDIF
ENDIF
// set the current selected blip (based on blip sprite)
IF GET_MISSION_FLAG()
IF NOT (g_FirstBlipSpriteInTaxiMeter = RADAR_TRACE_INVALID)
REPEAT MAX_NUMBER_OF_TAXI_DESTINATIONS i
IF DOES_BLIP_EXIST(AllTaxiDestinations[i].BlipID)
IF (GET_SPRITE_FOR_BLIP(AllTaxiDestinations[i].BlipID) = g_FirstBlipSpriteInTaxiMeter)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " First Blip Sprite in Taxi meter forced ")
iCurrentHighlightedPosition = i
i = MAX_NUMBER_OF_TAXI_DESTINATIONS
ENDIF
ENDIF
ENDREPEAT
ENDIF
ELSE
IF NOT (g_FirstBlipSpriteInTaxiMeter = RADAR_TRACE_INVALID)
g_FirstBlipSpriteInTaxiMeter = RADAR_TRACE_INVALID
ENDIF
ENDIF
ENDPROC
PROC HIGHLIGHT_CHOSEN_DESTINATION()
INT i = START_POSITION
REPEAT iTotalNumberOfTaxiDestinations i
// Grab the current destination index if the meter has been repopulated.
IF bDestinationSelected
IF currentTaxiDestination.BlipID = AllTaxiDestinations[i].BlipID
iCurrentHighlightedPosition = i
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " HIGHLIGHT_CHOSEN_DESTINATION : iCurrentHighlightedPosition = ", i)
#IF IS_DEBUG_BUILD
IF DOES_BLIP_EXIST(AllTaxiDestinations[iCurrentHighlightedPosition].BlipID)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "HIGHLIGHT_CHOSEN_DESTINATION : GET_BLIP_INFO :", GET_BLIP_NAME(AllTaxiDestinations[iCurrentHighlightedPosition].BlipID))
ENDIF
#ENDIF
ENDIF
ENDIF
ENDREPEAT
/* // B*1415214 - removed this since it occasionally caused meter to default and show the first destination
BEGIN_SCALEFORM_MOVIE_METHOD(scaleformTaxiMeter,"SHOW_TAXI_DESTINATION")
END_SCALEFORM_MOVIE_METHOD()*/
BEGIN_SCALEFORM_MOVIE_METHOD(scaleformTaxiMeter, "HIGHLIGHT_DESTINATION")
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(iCurrentHighlightedPosition) // 1. Position in list.
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "HIGHLIGHT_CHOSEN_DESTINATION : set scaleform move method add para int :", iCurrentHighlightedPosition)
END_SCALEFORM_MOVIE_METHOD()
ENDPROC
//PURPOSE: Sets the MiniMap locking to the destination
PROC SET_MINIMAP_LOCKING()
IF DOES_BLIP_EXIST(currentTaxiDestination.BlipID)
VECTOR vBlipCoords = GET_BLIP_COORDS(currentTaxiDestination.BlipID)
IF DOES_CAM_EXIST(camMeter)
AND IS_CAM_ACTIVE(camMeter)
LOCK_MINIMAP_POSITION(vBlipCoords.X, vBlipCoords.Y)
LOCK_MINIMAP_ANGLE(0)
SET_RADAR_ZOOM(1400)
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// update's the scripted in taxi camera's rotation besed of player input
/// (simulates looking around)
/// NOTE: not currently in use - MP had request to make cam static
PROC UPDATE_IN_TAXI_ROT_BASED_OFF_PLAYER_CONTROLS()
FLOAT fTemp
INT right_stick_x, right_stick_y
right_stick_x = GET_CONTROL_VALUE(FRONTEND_CONTROL,INPUT_SCALED_LOOK_LR) - 128
right_stick_y = GET_CONTROL_VALUE(FRONTEND_CONTROL,INPUT_SCALED_LOOK_UD) - 128
IF NOT IS_LOOK_INVERTED()
right_stick_y *= -1
ENDIF
// invert the vertical
IF (right_stick_y > STICK_DEAD_ZONE)
OR (right_stick_y < (STICK_DEAD_ZONE * -1))
OR IS_USING_KEYBOARD_AND_MOUSE(FRONTEND_CONTROL)
fTemp = TO_FLOAT(right_stick_y)
fTemp *= fTemp
fTemp /= TO_FLOAT(128 - STICK_DEAD_ZONE) * TO_FLOAT(128 - STICK_DEAD_ZONE)
fTemp *= fTaxiCamSpeed
IF (right_stick_y < 0)
fTemp *= -1.0
ENDIF
fTaxiCamChangeY += fTemp
IF (fTaxiCamChangeY < fMinYChange)
fTaxiCamChangeY = fMinYChange
ENDIF
IF (fTaxiCamChangeY > fMaxYChange)
fTaxiCamChangeY = fMaxYChange
ENDIF
ENDIF
IF (right_stick_x > STICK_DEAD_ZONE)
OR (right_stick_x < (STICK_DEAD_ZONE * -1))
OR IS_USING_KEYBOARD_AND_MOUSE(FRONTEND_CONTROL)
fTemp = TO_FLOAT(right_stick_x)
fTemp *= fTemp
fTemp /= TO_FLOAT(128 - STICK_DEAD_ZONE) * TO_FLOAT(128 - STICK_DEAD_ZONE)
fTemp *= fTaxiCamSpeed
IF (right_stick_x > 0)
fTemp *= -1.0
ENDIF
fTaxiCamChangeX += fTemp
IF (fTaxiCamChangeX < fMinXChange)
fTaxiCamChangeX = fMinXChange
ENDIF
IF (fTaxiCamChangeX > fMaxXChange)
fTaxiCamChangeX = fMaxXChange
ENDIF
ENDIF
IF IS_CONTROL_JUST_PRESSED(CAMERA_CONTROL, INPUT_LOOK_BEHIND)
fTaxiCamChangeX = 0
fTaxiCamChangeY = 0
ENDIF
SET_CAMERA_ROT_TO_SAME_AS_VEHICLE(g_WaitingTaxi, camMeter, <<fTaxiCamChangeY, 0, fTaxiCamChangeX>>)
ENDPROC
/// PURPOSE:
/// handles the in taxi camera
PROC RUN_TAXI_INTERIOR_CAM()
IF NOT IS_VEHICLE_DRIVEABLE(g_WaitingTaxi)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : RUN_TAXI_INTERIOR_CAM() - g_WaitingTaxi isn't driveable ")
EXIT
ENDIF
// create the camera
IF NOT DOES_CAM_EXIST(camMeter)
IF NOT IS_SELECTOR_CAM_ACTIVE()
AND NOT IS_SCRIPT_HUD_DISPLAYING(HUDPART_TRANSITIONHUD)
camMeter = CREATE_CAM("DEFAULT_SCRIPTED_CAMERA", FALSE)
ATTACH_CAM_TO_ENTITY(camMeter, g_WaitingTaxi, vTaxiCamOffset) // position every frame instead
UPDATE_TAXI_CAM_POSITIONING()
SET_CAM_CONTROLS_MINI_MAP_HEADING(camMeter, TRUE)
CPRINTLN(DEBUG_TAXI_SERVICE, " RUN_TAXI_INTERIOR_CAM() - created camera")
ENDIF
ELSE
// run destination selection camera
IF NOT bDestinationSelected // if user hasn't selected the initial destination
OR bSelectingAnotherDestination // or user is selecting a new destination
// conditions where camera shouldn't update
IF NOT IS_SELECTOR_CAM_ACTIVE()
AND NOT IS_SCRIPT_HUD_DISPLAYING(HUDPART_TRANSITIONHUD)
// setup destination selection camera
IF NOT IS_CAM_ACTIVE(camMeter)
DISABLE_SCRIPT_HUD(HUDPART_ALL_OVERHEADS, TRUE)
SET_CAM_CONTROLS_MINI_MAP_HEADING(camMeter, TRUE)
SET_MINIMAP_LOCKING()
SET_CAM_ACTIVE(camMeter, TRUE)
RENDER_SCRIPT_CAMS(TRUE, FALSE)
g_bTaxiShouldForcePhoneDislayOnHud = TRUE // B*2053172 - set when phone needs to be forced to display on the hud if active when a passenger in a taxi
SET_PARTICLE_FX_CAM_INSIDE_VEHICLE(TRUE) // B*1549323 - stops rain inside taxi
UPDATE_TAXI_CAM_POSITIONING()
bUpdateTaxiControls = TRUE // regen controls UI for selecting destination camera
CPRINTLN(DEBUG_TAXI_SERVICE, " RUN_TAXI_INTERIOR_CAM() - activated camera")
// cam is active so update it
ELSE
UPDATE_TAXI_CAM_POSITIONING()
ENDIF
// prevent player changing vehicle zoom level whils the destination selection camera is active
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_NEXT_CAMERA)
ENDIF
// cleanup the destination selection camera if it's active
ELSE
IF IS_CAM_ACTIVE(camMeter)
SET_CAM_ACTIVE(camMeter, FALSE)
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
SET_GAMEPLAY_CAM_RELATIVE_PITCH(0.0)
RENDER_SCRIPT_CAMS(FALSE, FALSE)
g_bTaxiShouldForcePhoneDislayOnHud = FALSE // B*2053172 - set when phone needs to be forced to display on the hud if active when a passenger in a taxi
SET_PARTICLE_FX_CAM_INSIDE_VEHICLE(FALSE) // B*1549323 - stops rain inside taxi
UNLOCK_MINIMAP_POSITION()
UNLOCK_MINIMAP_ANGLE()
SET_RADAR_ZOOM(0)
bUpdateTaxiControls = TRUE
HIGHLIGHT_CHOSEN_DESTINATION()
CPRINTLN(DEBUG_TAXI_SERVICE, " RUN_TAXI_INTERIOR_CAM() - deactivated camera")
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// check the interior meter camera exists and is active
/// RETURNS:
/// TRUE if active
FUNC BOOL IS_PLAYER_TRYING_TO_CHANGE_TAXI_DESTINATION()
IF DOES_CAM_EXIST(camMeter)
IF IS_CAM_ACTIVE(camMeter)
RETURN TRUE
ENDIF
ENDIF
IF bSelectingAnotherDestination
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
PROC POPULATE_TAXI_METER()
INT i = START_POSITION, iR, iG, iB, iA
VECTOR vTemp
SHOP_NAME_ENUM eShop
INIT_TAXI_DESTINATIONS()
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : POPULATE_TAXI_METER() SCALEFORM - CLEAR_TAXI_DISPLAY called")
BEGIN_SCALEFORM_MOVIE_METHOD(scaleformTaxiMeter,"CLEAR_TAXI_DISPLAY")
END_SCALEFORM_MOVIE_METHOD()
REPEAT iTotalNumberOfTaxiDestinations i
// safe checks to decide if this entry shouldn't be added
IF NOT DOES_BLIP_EXIST(AllTaxiDestinations[i].BlipID)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : POPULATE_TAXI_METER() SKIPPED! populate due to DOES_BLIP_EXIST(AllTaxiDestinations[", i, "].BlipID) = FALSE")
ELIF GET_SPRITE_FOR_BLIP(AllTaxiDestinations[i].BlipID) = RADAR_TRACE_INVALID
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : POPULATE_TAXI_METER() SKIPPED! populate due to GET_SPRITE_FOR_BLIP(AllTaxiDestinations[", i, "].BlipID) = RADAR_TRACE_INVALID")
ELIF ARE_VECTORS_ALMOST_EQUAL(GET_BLIP_COORDS(AllTaxiDestinations[i].BlipID), <<0,0,0>>)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : POPULATE_TAXI_METER() SKIPPED! populate due to ARE_VECTORS_ALMOST_EQUAL(GET_BLIP_COORDS(AllTaxiDestinations[", i, "].BlipID), <<0,0,0>>)")
// safe to populate the meter with this entry
ELSE
BEGIN_SCALEFORM_MOVIE_METHOD(scaleformTaxiMeter,"ADD_TAXI_DESTINATION")
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(i) // 1. Position in list.
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(ENUM_TO_INT(GET_BLIP_SPRITE(AllTaxiDestinations[i].BlipID))) // 2. The sprite to be displayed.
//Set the sprite colour
GET_HUD_COLOUR(GET_BLIP_HUD_COLOUR(AllTaxiDestinations[i].BlipID), iR, iG, iB, iA)
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(iR)
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(iG)
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(iB)
//SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(iA) // func doesn't take alpha value so don't try to pas it in.
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " POPULATE_TAXI_METER() : BlipSprite is ", ENUM_TO_INT(GET_BLIP_SPRITE(AllTaxiDestinations[i].BlipID)),
" and i is ", i, " named ", GET_BLIP_NAME(AllTaxiDestinations[i].BlipID))
// Check if this is a shop
eShop = GET_SHOP_FROM_MAP_BLIP(AllTaxiDestinations[i].BlipID)
IF eShop = EMPTY_SHOP
// not a shop, use blip name
BEGIN_TEXT_COMMAND_SCALEFORM_STRING("STRING")
ADD_TEXT_COMPONENT_SUBSTRING_BLIP_NAME(AllTaxiDestinations[i].BlipID) // 3. The name of the blip.
END_TEXT_COMMAND_SCALEFORM_STRING()
ELSE
// this is a shop, get its name
BEGIN_TEXT_COMMAND_SCALEFORM_STRING("STRING")
ADD_TEXT_COMPONENT_SUBSTRING_TEXT_LABEL(GET_SHOP_BLIP_NAME(eShop))
END_TEXT_COMMAND_SCALEFORM_STRING()
ENDIF
IF (GET_BLIP_INFO_ID_TYPE(AllTaxiDestinations[i].BlipID) = BLIPTYPE_CHAR)
IF NOT IS_PED_INJURED(GET_PED_INDEX_FROM_ENTITY_INDEX(GET_BLIP_INFO_ID_ENTITY_INDEX(AllTaxiDestinations[i].BlipID)))
vTemp = GET_ENTITY_COORDS(GET_PED_INDEX_FROM_ENTITY_INDEX(GET_BLIP_INFO_ID_ENTITY_INDEX(AllTaxiDestinations[i].BlipID)))
ENDIF
ELIF (GET_BLIP_INFO_ID_TYPE(AllTaxiDestinations[i].BlipID) = BLIPTYPE_VEHICLE)
IF IS_VEHICLE_DRIVEABLE(GET_BLIP_INFO_ID_ENTITY_INDEX(AllTaxiDestinations[i].BlipID))
vTemp = GET_ENTITY_COORDS(GET_BLIP_INFO_ID_ENTITY_INDEX(AllTaxiDestinations[i].BlipID))
ENDIF
ELSE
vTemp = GET_BLIP_COORDS(AllTaxiDestinations[i].BlipID)
ENDIF
SCALEFORM_MOVIE_METHOD_ADD_PARAM_STRING(GET_NAME_OF_ZONE(vTemp)) // 4. Name of zone.
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " POPULATE_TAXI_METER() : ADD_TAXI_DESTINATION destination blip coords ", vTemp)
IF AllTaxiDestinations[i].iHashname2 = 0 // One street name
IF AllTaxiDestinations[i].iHashname1 <> 0 // No Street Name
BEGIN_TEXT_COMMAND_SCALEFORM_STRING("STRTNM1") // ~a~
ADD_TEXT_COMPONENT_SUBSTRING_TEXT_LABEL_HASH_KEY(AllTaxiDestinations[i].iHashname1) // 5a. Name of street.
END_TEXT_COMMAND_SCALEFORM_STRING()
ENDIF
ELSE // Two street names // or
BEGIN_TEXT_COMMAND_SCALEFORM_STRING("STRTNM2") // ~a~ and ~a~
ADD_TEXT_COMPONENT_SUBSTRING_TEXT_LABEL_HASH_KEY(AllTaxiDestinations[i].iHashname1) // 5b. Name of streets.
ADD_TEXT_COMPONENT_SUBSTRING_TEXT_LABEL_HASH_KEY(AllTaxiDestinations[i].iHashname2)
END_TEXT_COMMAND_SCALEFORM_STRING()
ENDIF
END_SCALEFORM_MOVIE_METHOD()
// Grab the current destination index if the meter has been repopulated.
IF bDestinationSelected
IF currentTaxiDestination.BlipID = AllTaxiDestinations[i].BlipID
iCurrentHighlightedPosition = i
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " POPULATE_TAXI_METER : iCurrentHighlightedPosition = ", i)
#IF IS_DEBUG_BUILD
IF DOES_BLIP_EXIST(currentTaxiDestination.BlipID)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "POPULATE_TAXI_METER : GET_BLIP_INFO :", GET_BLIP_NAME(currentTaxiDestination.BlipID))
ENDIF
#ENDIF
ENDIF
ENDIF
ENDIF
ENDREPEAT
IF bDestinationSelected
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : POPULATE_TAXI_METER() SCALEFORM - adding methods - SHOW_TAXI_DESTINATION & HIGHLIGHT_DESTINATION = ", iCurrentHighlightedPosition)
BEGIN_SCALEFORM_MOVIE_METHOD(scaleformTaxiMeter,"SHOW_TAXI_DESTINATION")
END_SCALEFORM_MOVIE_METHOD()
BEGIN_SCALEFORM_MOVIE_METHOD(scaleformTaxiMeter, "HIGHLIGHT_DESTINATION")
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(iCurrentHighlightedPosition)
END_SCALEFORM_MOVIE_METHOD()
ELSE
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : POPULATE_TAXI_METER() SCALEFORM - adding methods - SET_TAXI_PRICE = ", currentJourneyPrice, " SHOW_TAXI_DESTINATION & HIGHLIGHT_DESTINATION = ", iCurrentHighlightedPosition)
BEGIN_SCALEFORM_MOVIE_METHOD(scaleformTaxiMeter,"SET_TAXI_PRICE")
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(currentJourneyPrice)
END_SCALEFORM_MOVIE_METHOD()
BEGIN_SCALEFORM_MOVIE_METHOD(scaleformTaxiMeter,"SHOW_TAXI_DESTINATION")
END_SCALEFORM_MOVIE_METHOD()
BEGIN_SCALEFORM_MOVIE_METHOD(scaleformTaxiMeter, "HIGHLIGHT_DESTINATION")
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(iCurrentHighlightedPosition)
END_SCALEFORM_MOVIE_METHOD()
ENDIF
ENDPROC
FUNC INT GET_NUMBER_OF_TAXI_OCCUPANTS()
INT iOccupants = 0
IF IS_VEHICLE_OK(g_WaitingTaxi)
IF NOT IS_VEHICLE_SEAT_FREE(g_WaitingTaxi, VS_DRIVER)
iOccupants++
ENDIF
IF NOT IS_VEHICLE_SEAT_FREE(g_WaitingTaxi, VS_FRONT_RIGHT)
iOccupants++
ENDIF
IF NOT IS_VEHICLE_SEAT_FREE(g_WaitingTaxi, VS_BACK_LEFT)
iOccupants++
ENDIF
IF NOT IS_VEHICLE_SEAT_FREE(g_WaitingTaxi, VS_BACK_RIGHT)
iOccupants++
ENDIF
ENDIF
RETURN iOccupants
ENDFUNC
FUNC BOOL HAS_TAXI_DESTINATION_LIST_CHANGED()
BOOL bRegenerateList = FALSE
VECTOR vTempBlipCoords
BLIP_INDEX blipWaypointCheck
// B*1948209 - used to force through a destination list regen, set by the input controls when it detects an blip which doesn't exist
// less expensive than cycling through all the blips below
IF NOT DOES_BLIP_EXIST(AllTaxiDestinations[iCurrentHighlightedPosition].BlipID)
// B*1948209 - if the current selected blip doesn't exist we need to regen the list
IF iCurrentHighlightedPosition != iStoredTaxiWaypointBlipDestinationIndex // ignore waypoints since these always get deleted by code as you approach the blip
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " HAS_TAXI_DESTINATION_LIST_CHANGED() - return TRUE : detected current highlighted blip doesn't exist, iCurrentHighlightedPosition : ", iCurrentHighlightedPosition)
RETURN TRUE
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : HAS_TAXI_DESTINATION_LIST_CHANGED() : detected current highlighted blip doesn't exist, but it;s the iStoredTaxiWaypointBlipDestinationIndex : ", iStoredTaxiWaypointBlipDestinationIndex)
ENDIF
ENDIF
// staggered checks
IF TIMERB() > 250
IF NOT (bRegenerateList)
IF iStoredNumberOfBlips <> GET_NUMBER_OF_ACTIVE_BLIPS()
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " HAS_TAXI_DESTINATION_LIST_CHANGED() - Blip count differs from stored count. Is now ",
GET_NUMBER_OF_ACTIVE_BLIPS(), " was ", iStoredNumberOfBlips)
bRegenerateList = TRUE
ENDIF
iStoredNumberOfBlips = GET_NUMBER_OF_ACTIVE_BLIPS()
IF iStoredNumberOfOccupants <> GET_NUMBER_OF_TAXI_OCCUPANTS()
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " HAS_TAXI_DESTINATION_LIST_CHANGED() - Taxi occupant count differs from stored count. Is now ",
GET_NUMBER_OF_TAXI_OCCUPANTS(), " was ", iStoredNumberOfOccupants)
bRegenerateList = TRUE
ENDIF
iStoredNumberOfOccupants = GET_NUMBER_OF_TAXI_OCCUPANTS()
ENDIF
// B*1310466 - check for waypoint blup being updated.
IF NOT (bRegenerateList)
IF iStoredTaxiWaypointBlipDestinationIndex != -1 // don't test for the custom waypoint blip if it hasn't been set already
IF DOES_BLIP_EXIST(AllTaxiDestinations[iStoredTaxiWaypointBlipDestinationIndex].BlipID)
IF GET_SPRITE_FOR_BLIP(AllTaxiDestinations[iStoredTaxiWaypointBlipDestinationIndex].BlipID) = GET_WAYPOINT_BLIP_ENUM_ID()
vTempBlipCoords = GET_BLIP_COORDS(AllTaxiDestinations[iStoredTaxiWaypointBlipDestinationIndex].BlipID)
IF NOT ARE_VECTORS_ALMOST_EQUAL(vTempBlipCoords, vStoredTaxiWaypointBlipDestinationCoords)
bRegenerateList = TRUE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " HAS_TAXI_DESTINATION_LIST_CHANGED - custom waypoint blip position changed! ",
" stored = ", vStoredTaxiWaypointBlipDestinationCoords,
" new = ", vTempBlipCoords)
ENDIF
ENDIF
ELSE
blipWaypointCheck = GET_FIRST_BLIP_INFO_ID(GET_WAYPOINT_BLIP_ENUM_ID())
IF DOES_BLIP_EXIST(blipWaypointCheck)
vTempBlipCoords = GET_BLIP_COORDS(blipWaypointCheck)
IF NOT ARE_VECTORS_ALMOST_EQUAL(vTempBlipCoords, vStoredTaxiWaypointBlipDestinationCoords)
bRegenerateList = TRUE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " HAS_TAXI_DESTINATION_LIST_CHANGED - custom waypoint blip ID and position changed! ",
" stored = ", vStoredTaxiWaypointBlipDestinationCoords,
" new = ", vTempBlipCoords)
ENDIF
ELSE
// this situation will be handled by above check of number stored blips mismatch
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " HAS_TAXI_DESTINATION_LIST_CHANGED - blipWaypointCheck doesn't exist ")
ENDIF
ENDIF
ENDIF
ENDIF
SETTIMERB(0)
ENDIF
RETURN bRegenerateList
ENDFUNC
/// PURPOSE:
/// check to see if skip option should be availabe to player
/// RETURNS:
/// TRUE if he can skip false if not
FUNC BOOL IS_PLAYER_ALLOWED_TO_SKIP_TAXI_JOURNEY()
// only allow skip during driving state
IF eTaxiJourneyState != TAXI_JOURNEY_STATE_DRIVING_TO_DESTINATION
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " IS_PLAYER_ALLOWED_TO_SKIP_TAXI_JOURNEY() : return FALSE : eTaxiJourneyState != TAXI_JOURNEY_STATE_DRIVING_TO_DESTINATION")
RETURN FALSE
ENDIF
// don't allow skip whilst selecting a different destination
IF bSelectingAnotherDestination
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " IS_PLAYER_ALLOWED_TO_SKIP_TAXI_JOURNEY() : return FALSE : bSelectingAnotherDestination = TRUE")
RETURN FALSE
ENDIF
// Taxi has to be min 50 m from destination
IF fDistanceToDestination < 50
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " IS_PLAYER_ALLOWED_TO_SKIP_TAXI_JOURNEY() : return FALSE : fDistanceToDestination < 50")
RETURN FALSE
ENDIF
// don't skip during interior cam as this is used to switch destinations
IF DOES_CAM_EXIST(camMeter)
IF IS_CAM_ACTIVE(camMeter)
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " IS_PLAYER_ALLOWED_TO_SKIP_TAXI_JOURNEY() : return FALSE : IS_CAM_ACTIVE(camMeter)")
RETURN FALSE
ENDIF
ENDIF
RETURN TRUE
ENDFUNC
PROC NEXT_DESTINATION()
BEGIN_SCALEFORM_MOVIE_METHOD(scaleformTaxiMeter, "SET_INPUT_EVENT")
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(ENUM_TO_INT(SCALEFORM_INPUT_EVENT_UP))
END_SCALEFORM_MOVIE_METHOD()
iCurrentHighlightedPosition --
IF iCurrentHighlightedPosition < START_POSITION
iCurrentHighlightedPosition = (iTotalNumberOfTaxiDestinations-1)
ENDIF
IF DOES_BLIP_EXIST(AllTaxiDestinations[iCurrentHighlightedPosition].BlipID)
VECTOR vCoords = GET_BLIP_COORDS(AllTaxiDestinations[iCurrentHighlightedPosition].BlipID)
IF NOT IS_VECTOR_ZERO(vCoords)
LOCK_MINIMAP_POSITION(vCoords.x, vCoords.y)
ENDIF
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " NEXT_DESTINATION() : set BlipSprite is ", ENUM_TO_INT(GET_BLIP_SPRITE(AllTaxiDestinations[iCurrentHighlightedPosition].BlipID)),
" and iCurrentHighlightedPosition is ", iCurrentHighlightedPosition, " named ", GET_BLIP_NAME(AllTaxiDestinations[iCurrentHighlightedPosition].BlipID), " vCoords = ", vCoords)
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " NEXT_DESTINATION() : blip doesn't exist! iCurrentHighlightedPosition = ", iCurrentHighlightedPosition)
ENDIF
ENDPROC
PROC LAST_DESTINATION()
BEGIN_SCALEFORM_MOVIE_METHOD(scaleformTaxiMeter, "SET_INPUT_EVENT")
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(ENUM_TO_INT(SCALEFORM_INPUT_EVENT_DOWN))
END_SCALEFORM_MOVIE_METHOD()
iCurrentHighlightedPosition ++
IF iCurrentHighlightedPosition > (iTotalNumberOfTaxiDestinations-1)
iCurrentHighlightedPosition = START_POSITION
ENDIF
IF DOES_BLIP_EXIST(AllTaxiDestinations[iCurrentHighlightedPosition].BlipID)
VECTOR vCoords = GET_BLIP_COORDS(AllTaxiDestinations[iCurrentHighlightedPosition].BlipID)
IF NOT IS_VECTOR_ZERO(vCoords)
LOCK_MINIMAP_POSITION(vCoords.x, vCoords.y)
ENDIF
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " LAST_DESTINATION() : set BlipSprite is ", ENUM_TO_INT(GET_BLIP_SPRITE(AllTaxiDestinations[iCurrentHighlightedPosition].BlipID)),
" and iCurrentHighlightedPosition is ", iCurrentHighlightedPosition, " named ", GET_BLIP_NAME(AllTaxiDestinations[iCurrentHighlightedPosition].BlipID), " vCoords = ", vCoords)
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " LAST_DESTINATION() : blip doesn't exist! iCurrentHighlightedPosition = ", iCurrentHighlightedPosition)
ENDIF
ENDPROC
/// PURPOSE:
/// detects player control inputs
PROC PROCESS_PLAYER_CONTROL_INPUTS()
// only allow normal exit controls during create taxi meter state
IF eTaxiJourneyState != TAXI_JOURNEY_STATE_CREATE_TAXI_METER
// only allow destination switching if there are enough destinations
IF iTotalNumberOfTaxiDestinations > 1
INT leftX, leftY, rightX, rightY
GET_CONTROL_VALUE_OF_ANALOGUE_STICKS(leftX, leftY, rightX, rightY)
// Need this on PC to prevent conflict with radio controls
IF IS_USING_KEYBOARD_AND_MOUSE(FRONTEND_CONTROL)
SET_INPUT_EXCLUSIVE(FRONTEND_CONTROL, INPUT_CURSOR_SCROLL_UP)
SET_INPUT_EXCLUSIVE(FRONTEND_CONTROL, INPUT_CURSOR_SCROLL_DOWN)
SET_INPUT_EXCLUSIVE(FRONTEND_CONTROL, INPUT_CELLPHONE_SCROLL_FORWARD)
SET_INPUT_EXCLUSIVE(FRONTEND_CONTROL, INPUT_CELLPHONE_SCROLL_BACKWARD)
ENDIF
IF leftX > STICK_DEAD_ZONE
OR IS_DISABLED_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_CELLPHONE_SCROLL_FORWARD)
IF NOT bStickInUseUp
IF bDestinationSelected
IF bSelectingAnotherDestination
LAST_DESTINATION()
ELSE
bUpdateTaxiControls = TRUE
ENDIF
bSelectingAnotherDestination = TRUE
ELSE
LAST_DESTINATION()
ENDIF
iTimer_SelectingAnotherDestinationTimeOut = GET_GAME_TIMER()
bStickInUseUp = TRUE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " PROCESS_PLAYER_CONTROL_INPUTS : bStickInUseUp true ")
ENDIF
ELSE
bStickInUseUp = FALSE
ENDIF
IF leftX < -STICK_DEAD_ZONE
OR IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_CELLPHONE_SCROLL_BACKWARD)
IF NOT bStickInUseDown
IF bDestinationSelected
IF bSelectingAnotherDestination
NEXT_DESTINATION()
ELSE
bUpdateTaxiControls = TRUE
ENDIF
bSelectingAnotherDestination = TRUE
ELSE
NEXT_DESTINATION()
ENDIF
iTimer_SelectingAnotherDestinationTimeOut = GET_GAME_TIMER()
bStickInUseDown = TRUE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " PROCESS_PLAYER_CONTROL_INPUTS : bStickInUseDown true ")
ENDIF
ELSE
bStickInUseDown = FALSE
ENDIF
ENDIF
// Initial selection of destination
IF NOT bDestinationSelected
// only allow destination selection if there is a destination to select
IF iTotalNumberOfTaxiDestinations > 0
SET_CINEMATIC_BUTTON_ACTIVE(FALSE)
IF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_CELLPHONE_SELECT)
IF DOES_BLIP_EXIST(AllTaxiDestinations[iCurrentHighlightedPosition].BlipID)
eTaxiDialogue = TAXI_DIALOGUE_BEGIN_JOURNEY_1 // set dialogue to trigger in PLAY_TAXI_DIALOGUE()
currentTaxiDestination = AllTaxiDestinations[iCurrentHighlightedPosition]
bTaxiHasHitDestinationLocate = FALSE // reset ready
iTimer_WaitForGroupMembers = GET_GAME_TIMER() // set ready for checks
iDialogueTimer_BanterDuringJourney = GET_GAME_TIMER() // set ready for checks
iDialogueTimer_ChangeRadio = GET_GAME_TIMER() // set
iDesinationNodeSearchNumber = 0 // reset ready for grabbing destination node
eGenerateSafeDestinationState = TAXI_GSDS_INITIAL_TRIGGER_AREAS_CHECK
bDestinationSelected = TRUE
bUpdateTaxiControls = TRUE
bSelectingAnotherDestination = FALSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : PROCESS_PLAYER_CONTROL_INPUTS() : initial selection done **** : ",
" BlipSprite is ", ENUM_TO_INT(GET_BLIP_SPRITE(AllTaxiDestinations[iCurrentHighlightedPosition].BlipID)),
" and iCurrentHighlightedPosition is ", iCurrentHighlightedPosition, " named ", GET_BLIP_NAME(AllTaxiDestinations[iCurrentHighlightedPosition].BlipID))
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : PROCESS_PLAYER_CONTROL_INPUTS() : blocked initial selection as destination blip doesn't exist! expect list to be regenerated.")
ENDIF
ENDIF
ENDIF
ELSE
SET_CINEMATIC_BUTTON_ACTIVE(FALSE) // blocked for controls clash
IF eTaxiJourneyState = TAXI_JOURNEY_STATE_DRIVING_TO_DESTINATION
// Stop / Pullover
IF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_CELLPHONE_CANCEL)
eTaxiDialogue = TAXI_DIALOGUE_OUT_EARLY // set dialogue to trigger in PLAY_TAXI_DIALOGUE()
bUpdateTaxiControls = TRUE
IF NOT IS_PED_INJURED(g_WaitingTaxiDriver)
CLEAR_PED_TASKS(g_WaitingTaxiDriver)
ENDIF
eTaxiJourneyState = TAXI_JOURNEY_STATE_ORDERED_TO_PULLOVER
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : PROCESS_PLAYER_CONTROL_INPUTS() : taxi ordered to pullover ***")
ENDIF
// Choosing to hurry to destination.
IF NOT bHurrying
IF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_CELLPHONE_EXTRA_OPTION)
eTaxiDialogue = TAXI_DIALOGUE_STEP_ON_IT_1 // set dialogue to trigger in PLAY_TAXI_DIALOGUE()
bHurrying = TRUE
bUpdateTaxiControls = TRUE
fFareRate = FARE_RATE * 2.0
// B*1552474 - don't clear anim tasks
IF NOT IS_PED_INJURED(g_WaitingTaxiDriver)
IF NOT IS_ENTITY_PLAYING_ANIM(g_WaitingTaxiDriver, tlAnimDictTaxiDriver, "leanover_enter")
IF NOT IS_ENTITY_PLAYING_ANIM(g_WaitingTaxiDriver, tlAnimDictTaxiDriver, "leanover_idle")
IF NOT IS_ENTITY_PLAYING_ANIM(g_WaitingTaxiDriver, tlAnimDictTaxiDriver, "leanover_exit")
CLEAR_PED_TASKS(g_WaitingTaxiDriver)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : PROCESS_PLAYER_CONTROL_INPUTS() : bHurrying - taxi driver tasks cleared for new go to task")
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : PROCESS_PLAYER_CONTROL_INPUTS() : bHurrying - taxi driver tasks not cleared - playing anim leanover_exit")
ENDIF
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : PROCESS_PLAYER_CONTROL_INPUTS() : bHurrying - taxi driver tasks not cleared - playing anim leanover_idle")
ENDIF
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : PROCESS_PLAYER_CONTROL_INPUTS() : bHurrying - taxi driver tasks not cleared - playing anim leanover_enter")
ENDIF
ENDIF
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : PROCESS_PLAYER_CONTROL_INPUTS() : bHurrying true ***")
ENDIF
ENDIF
// don't skip during pick destination cam
IF IS_PLAYER_ALLOWED_TO_SKIP_TAXI_JOURNEY()
IF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_CELLPHONE_SELECT)
IF bDropPointSelected
bUpdateTaxiControls = TRUE
iSkipJourneyTimer = GET_GAME_TIMER()
eSkipJourneyState = SKIP_JOURNEY_STATE_FADE_OUT
eTaxiJourneyState = TAXI_JOURNEY_STATE_SKIP_JOURNEY
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : PROCESS_PLAYER_CONTROL_INPUTS() : eTaxiJourneyState = TAXI_JOURNEY_STATE_SKIP_JOURNEY")
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : PROCESS_PLAYER_CONTROL_INPUTS() : bSkipToDestination blocked as bDropPointSelected is still FALSE ! ")
ENDIF
ENDIF
ENDIF
// additional dialogue
IF eTaxiDialogue = TAXI_DIALOGUE_NOTHING // set dialogue to trigger in PLAY_TAXI_DIALOGUE()
IF iDialogueTimer_BanterDuringJourney != -1
IF HAS_TIME_PASSED(iDialogueTimer_BanterDuringJourney, 68000) //120000)
eTaxiDialogue = TAXI_DIALOGUE_BANTER
iDialogueTimer_BanterDuringJourney = -1
ENDIF
ENDIF
ENDIF
IF eTaxiDialogue = TAXI_DIALOGUE_NOTHING // set dialogue to trigger in PLAY_TAXI_DIALOGUE()
IF iDialogueTimer_ChangeRadio != -1
IF HAS_TIME_PASSED(iDialogueTimer_ChangeRadio, 5000)
IF IS_CONTROL_PRESSED(FRONTEND_CONTROL, INPUT_VEH_NEXT_RADIO)
OR IS_CONTROL_PRESSED(FRONTEND_CONTROL, INPUT_VEH_PREV_RADIO)
OR IS_CONTROL_PRESSED(FRONTEND_CONTROL, INPUT_VEH_RADIO_WHEEL)
eTaxiDialogue = TAXI_DIALOGUE_RADIO_1
iDialogueTimer_BanterDuringJourney = -1
ENDIF
ENDIF
ENDIF
ENDIF
ELIF eTaxiJourneyState = TAXI_JOURNEY_STATE_ORDERED_TO_PULLOVER
// Start - get going to destination again
IF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_CELLPHONE_CANCEL)
eTaxiDialogue = TAXI_DIALOGUE_BEGIN_JOURNEY_2 // set dialogue to trigger in PLAY_TAXI_DIALOGUE()
bUpdateTaxiControls = TRUE
eTaxiJourneyState = TAXI_JOURNEY_STATE_DRIVING_TO_DESTINATION
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : PROCESS_PLAYER_CONTROL_INPUTS() : taxi ordered to start moving again")
ENDIF
ENDIF
// Selecting a new destination while a journey is in progress
IF bSelectingAnotherDestination
IF IS_PLAYER_TRYING_TO_CHANGE_TAXI_DESTINATION() // only allow during pick destination cam
IF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_CELLPHONE_SELECT)
IF DOES_BLIP_EXIST(AllTaxiDestinations[iCurrentHighlightedPosition].BlipID)
eTaxiDialogue = TAXI_DIALOGUE_CHANGE_DEST_1 // set dialogue to trigger in PLAY_TAXI_DIALOGUE()
bDropPointSelected = FALSE
IF eTaxiJourneyState = TAXI_JOURNEY_STATE_ORDERED_TO_PULLOVER // make sure we start moving again
eTaxiJourneyState = TAXI_JOURNEY_STATE_DRIVING_TO_DESTINATION
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : PROCESS_PLAYER_CONTROL_INPUTS() : taxi set moving again from pullover (due to new destination seletection.")
ENDIF
bUpdateTaxiControls = TRUE
currentTaxiDestination = AllTaxiDestinations[iCurrentHighlightedPosition]
bTaxiHasHitDestinationLocate = FALSE // reset ready
iTimer_WaitForGroupMembers = GET_GAME_TIMER() // set ready for checks
iDesinationNodeSearchNumber = 0 // reset ready for grabbing destination node
eGenerateSafeDestinationState = TAXI_GSDS_INITIAL_TRIGGER_AREAS_CHECK
// B*1552474 - don't clear anim tasks
IF NOT IS_PED_INJURED(g_WaitingTaxiDriver)
IF NOT IS_ENTITY_PLAYING_ANIM(g_WaitingTaxiDriver, tlAnimDictTaxiDriver, "leanover_enter")
IF NOT IS_ENTITY_PLAYING_ANIM(g_WaitingTaxiDriver, tlAnimDictTaxiDriver, "leanover_idle")
IF NOT IS_ENTITY_PLAYING_ANIM(g_WaitingTaxiDriver, tlAnimDictTaxiDriver, "leanover_exit")
CLEAR_PED_TASKS(g_WaitingTaxiDriver)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : PROCESS_PLAYER_CONTROL_INPUTS() : bSelectingAnotherDestination - taxi driver tasks cleared for new go to task")
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : PROCESS_PLAYER_CONTROL_INPUTS() : bSelectingAnotherDestination -taxi driver tasks not cleared - playing anim leanover_exit")
ENDIF
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : PROCESS_PLAYER_CONTROL_INPUTS() : bSelectingAnotherDestination - axi driver tasks not cleared - playing anim leanover_idle")
ENDIF
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : PROCESS_PLAYER_CONTROL_INPUTS() : bSelectingAnotherDestination - taxi driver tasks not cleared - playing anim leanover_enter")
ENDIF
ENDIF
iTimer_SelectingAnotherDestinationTimeOut = GET_GAME_TIMER()
bSelectingAnotherDestination = FALSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : PROCESS_PLAYER_CONTROL_INPUTS() : mid journey destination changed : ",
" BlipSprite is ", ENUM_TO_INT(GET_BLIP_SPRITE(AllTaxiDestinations[iCurrentHighlightedPosition].BlipID)),
" and iCurrentHighlightedPosition is ", iCurrentHighlightedPosition, " named ", GET_BLIP_NAME(AllTaxiDestinations[iCurrentHighlightedPosition].BlipID))
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : PROCESS_PLAYER_CONTROL_INPUTS() : blocked changing selection as destination blip doesn't exist! expect list to be regenerated.")
ENDIF
ENDIF
IF HAS_TIME_PASSED(iTimer_SelectingAnotherDestinationTimeOut, TAXI_SERVICE_CHANGE_DEST_CAM_TIMEOUT)
bSelectingAnotherDestination = FALSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : PROCESS_PLAYER_CONTROL_INPUTS() : timedout change destination attempt")
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// displays the taxi meter scaleform on the taxi meter
PROC RENDER_TAXI_METER()
// waut for the taxi meter to be displayed before allowing it to display
IF eTaxiJourneyState != TAXI_JOURNEY_STATE_CREATE_TAXI_METER
SET_TEXT_RENDER_ID(iRenderTarget)
SET_SCRIPT_GFX_DRAW_ORDER(GFX_ORDER_AFTER_HUD) // B* 1543102
SET_SCRIPT_GFX_DRAW_BEHIND_PAUSEMENU(TRUE)
IF IS_VEHICLE_DRIVEABLE(g_WaitingTaxi)
DRAW_SCALEFORM_MOVIE(scaleformTaxiMeter, fTaxiMenu_ScaleCentreX, fTaxiMenu_ScaleCentreY, fTaxiMenu_ScaleSizeX, fTaxiMenu_ScaleSizeY, 0,0,0,255)
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : RENDER_TAXI_METER() : DRAW_SCALEFORM_MOVIE this frame")
#IF IS_DEBUG_BUILD
ELSE
IF bDebugLaunchMeterOnly
DRAW_SCALEFORM_MOVIE(scaleformTaxiMeter, fTaxiMenu_ScaleCentreX, fTaxiMenu_ScaleCentreY, fTaxiMenu_ScaleSizeX, fTaxiMenu_ScaleSizeY, 0,0,0,255)
ELSE
SET_SCALEFORM_MOVIE_AS_NO_LONGER_NEEDED(scaleformTaxiMeter)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : RENDER_TAXI_METER() : IF IS_VEHICLE_DRIVEABLE(g_WaitingTaxi) SET_SCALEFORM_MOVIE_AS_NO_LONGER_NEEDED(scaleformTaxiMeter) ")
ENDIF
#ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// handle displaying the taxi controls
PROC UPDATE_TAXI_INSTRUCTIONAL_BUTTONS()
IF NOT SHOULD_TAXI_CONTROLS_BE_BLOCKED_THIS_FRAME()
IF HAS_SCALEFORM_MOVIE_LOADED(scaleformTaxiControls)
// only allow exit during create taxi meter state
IF eTaxiJourneyState != TAXI_JOURNEY_STATE_CREATE_TAXI_METER
// Check if southpaw controls need an update
STRING tempCurrentButton = GET_CONTROL_INSTRUCTIONAL_BUTTONS_STRING(FRONTEND_CONTROL, INPUT_SCRIPT_LEFT_AXIS_X)
IF NOT ARE_STRINGS_EQUAL(instructButtonStored_changeDest, tempCurrentButton)
instructButtonStored_changeDest = tempCurrentButton
bUpdateTaxiControls = TRUE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : UPDATE_TAXI_INSTRUCTIONAL_BUTTONS() : update for Southpaw this frame")
ENDIF
// STRING tempCurrentButton = GET_CONTROL_GROUP_INSTRUCTIONAL_BUTTONS_STRING(FRONTEND_CONTROL, INPUTGROUP_SCRIPT_LSTICK_ALL)
// IF NOT ARE_STRINGS_EQUAL(instructButtonStored_changeDest, tempCurrentButton)
// instructButtonStored_changeDest = tempCurrentButton
// bUpdateTaxiControls = TRUE
// CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : UPDATE_TAXI_INSTRUCTIONAL_BUTTONS() : update for Southpaw this frame")
// ENDIF
IF bUpdateTaxiControls
aSpriteTaxiControls = GET_SCALEFORM_INSTRUCTIONAL_BUTTON_POSITION()
REFRESH_SCALEFORM_INSTRUCTIONAL_BUTTONS(instructionalButtons)
ADD_SCALEFORM_INSTRUCTIONAL_INPUT(PLAYER_CONTROL, INPUT_VEH_EXIT, "TXM_EXIT", instructionalButtons) // Exit
// only allow destination switching if there is more than 1 destination to select
IF iTotalNumberOfTaxiDestinations > 1
ADD_SCALEFORM_INSTRUCTIONAL_INPUT(FRONTEND_CONTROL, INPUT_SCRIPT_LEFT_AXIS_X, "TXM_CDES", instructionalButtons) // Change Destination
ENDIF
IF NOT bDestinationSelected
// only allow destination selection if there is a destination to select
IF iTotalNumberOfTaxiDestinations > 0
ADD_SCALEFORM_INSTRUCTIONAL_INPUT(FRONTEND_CONTROL, INPUT_CELLPHONE_SELECT, "TXM_SLCT", instructionalButtons) // Choose Destination
ENDIF
ELSE
IF eTaxiJourneyState = TAXI_JOURNEY_STATE_DRIVING_TO_DESTINATION
ADD_SCALEFORM_INSTRUCTIONAL_INPUT(FRONTEND_CONTROL, INPUT_CELLPHONE_CANCEL, "TXM_STOP", instructionalButtons) // Stop
IF bSelectingAnotherDestination
ADD_SCALEFORM_INSTRUCTIONAL_INPUT(FRONTEND_CONTROL, INPUT_CELLPHONE_SELECT, "TXM_SLCT", instructionalButtons) // Choose Destination
ENDIF
IF IS_PLAYER_ALLOWED_TO_SKIP_TAXI_JOURNEY()
ADD_SCALEFORM_INSTRUCTIONAL_INPUT(FRONTEND_CONTROL, INPUT_CELLPHONE_SELECT, "TXM_SKIP", instructionalButtons) // Skip (Extra Cost)
ENDIF
IF NOT bHurrying
ADD_SCALEFORM_INSTRUCTIONAL_INPUT(FRONTEND_CONTROL, INPUT_CELLPHONE_EXTRA_OPTION, "TXM_HURY", instructionalButtons) // Hurry
ENDIF
ELIF eTaxiJourneyState = TAXI_JOURNEY_STATE_ORDERED_TO_PULLOVER
ADD_SCALEFORM_INSTRUCTIONAL_INPUT(FRONTEND_CONTROL, INPUT_CELLPHONE_CANCEL, "TXM_STRT", instructionalButtons) // Start
IF bSelectingAnotherDestination
ADD_SCALEFORM_INSTRUCTIONAL_INPUT(FRONTEND_CONTROL, INPUT_CELLPHONE_SELECT, "TXM_SLCT", instructionalButtons) // Choose Destination
ENDIF
ENDIF
ENDIF
bUpdateTaxiControls = FALSE
ENDIF
SET_TEXT_RENDER_ID(GET_DEFAULT_SCRIPT_RENDERTARGET_RENDER_ID())
SET_SCRIPT_GFX_DRAW_BEHIND_PAUSEMENU(FALSE)
SET_INSTRUCTIONAL_BUTTONS_UNDER_HUD_THIS_FRAME()
SET_LOADING_ICON_SUBTITLES_OFFSET_SHIFT_THIS_FRAME()
RUN_SCALEFORM_INSTRUCTIONAL_BUTTONS(scaleformTaxiControls, aSpriteTaxiControls, instructionalButtons, SHOULD_REFRESH_SCALEFORM_INSTRUCTIONAL_BUTTONS(instructionalButtons))
ENDIF
ELSE
scaleformTaxiControls = REQUEST_SCALEFORM_MOVIE("instructional_buttons")
ENDIF
ELSE
SET_SCALEFORM_MOVIE_AS_NO_LONGER_NEEDED(scaleformTaxiControls)
bUpdateTaxiControls = TRUE
ENDIF
ENDPROC
#IF IS_DEBUG_BUILD
PROC SETUP_DEBUG()
START_WIDGET_GROUP("taxiService")
ADD_WIDGET_BOOL("Add debug blips for destination", bAddBlipForDestination)
ADD_WIDGET_BOOL("Cleanup This Script", bCleanupScript)
ADD_WIDGET_BOOL("Is player in a taxi", g_bPlayerIsInTaxi)
ADD_WIDGET_BOOL("Launch Meter Debug", bDebug_LaunchMeter)
ADD_WIDGET_FLOAT_SLIDER("fTaxiMenu_ScaleCentreX", fTaxiMenu_ScaleCentreX, 0, 1, 0.001)
ADD_WIDGET_FLOAT_SLIDER("fTaxiMenu_ScaleCentreY", fTaxiMenu_ScaleCentreY, 0, 1, 0.001)
ADD_WIDGET_FLOAT_SLIDER("fTaxiMenu_ScaleSizeX", fTaxiMenu_ScaleSizeX, 0, 3, 0.001)
ADD_WIDGET_FLOAT_SLIDER("fTaxiMenu_ScaleSizeY", fTaxiMenu_ScaleSizeY, 0, 3, 0.001)
ADD_WIDGET_FLOAT_SLIDER("vMeterOffset.x", vMeterOffset.x, -3, 3, 0.001)
ADD_WIDGET_FLOAT_SLIDER("vMeterOffset.y", vMeterOffset.y, 0, 3, 0.001)
ADD_WIDGET_FLOAT_SLIDER("vMeterOffset.z", vMeterOffset.z, 0, 3, 0.001)
ADD_WIDGET_FLOAT_SLIDER("vMeterRotation.x", vMeterRotation.x, -180, 180, 1)
ADD_WIDGET_FLOAT_SLIDER("vMeterRotation.y", vMeterRotation.y, -180, 180, 1)
ADD_WIDGET_FLOAT_SLIDER("vMeterRotation.z", vMeterRotation.z, -180, 180, 1)
ADD_WIDGET_FLOAT_SLIDER("vTaxiCamOffset.x", vTaxiCamOffset.x, -3, 3, 0.001)
ADD_WIDGET_FLOAT_SLIDER("vTaxiCamOffset.y", vTaxiCamOffset.y, -3, 3, 0.001)
ADD_WIDGET_FLOAT_SLIDER("vTaxiCamOffset.z", vTaxiCamOffset.z, -3, 3, 0.001)
ADD_WIDGET_FLOAT_SLIDER("vTaxiCamFixedRotation.x", vTaxiCamFixedRotation.x, -180, 180, 1)
ADD_WIDGET_FLOAT_SLIDER("vTaxiCamFixedRotation.y", vTaxiCamFixedRotation.y, -180, 180, 1)
ADD_WIDGET_FLOAT_SLIDER("vTaxiCamFixedRotation.z", vTaxiCamFixedRotation.z, -180, 180, 1)
ADD_WIDGET_BOOL("Update taxi cam offset and rot :", bDebug_UpdateTaxiCamOffsetAndRot)
ADD_WIDGET_FLOAT_SLIDER("camMeterFOV", camMeterFOV, 20, 70, 1)
ADD_WIDGET_BOOL("Output to debug file", bDebug_OutputInfo)
ADD_WIDGET_BOOL("display ALl taxi position info", bDebugDrawAllTaxiPickupPositionInfo)
ADD_WIDGET_BOOL("display taxi pull over results", bDebug_DrawGetPullOverResults)
ADD_WIDGET_BOOL("display taxi to player pull in spot", bDebug_DisplayTaxiToPlayerPullInSpot)
ADD_WIDGET_BOOL("display taxi to destination pull in spot", bDebug_DisplayTaxiDropOffPosition)
ADD_WIDGET_BOOL("display path load node area", bDebugDisplayPathNodeLoadArea)
ADD_WIDGET_BOOL("display identify active taxi", bDebugDrawSphereAroundActiveTaxi)
ADD_WIDGET_BOOL("Set break on node commands usage", bDebugSetBreakOnNodeCommandsUsage)
ADD_WIDGET_BOOL("Debug load all path nodes : for debug only! ", bDebugLoadAllPathNodes)
ADD_WIDGET_BOOL("Debug UNload all path nodes : for debug only! ", bDebugUnLoadAllPathNodes)
ADD_WIDGET_BOOL("Debug perform GET_TAXI_PULL_OVER_INFO / test uses : ", bDebugPerformGetTaxiPullInSpotTest)
ADD_WIDGET_VECTOR_SLIDER("vDebug_DriveToNodePos :", vDebug_DriveToNodePos, -10000.0, 10000.0, 0.0001)
ADD_WIDGET_BOOL("Debug perform ARE_COORDS_IN_SPECIAL_AREA test uses vDebug_TempPickupPos : ", bDebug_TestIsPositionInSpecialArea)
ADD_WIDGET_VECTOR_SLIDER("vDebug_TempPickupPos :", vDebug_TempPickupPos, -10000.0, 10000.0, 0.0001)
ADD_WIDGET_VECTOR_SLIDER("vDebug_TempDropOffPos :", vDebug_TempDropOffPos, -10000.0, 10000.0, 0.0001)
ADD_WIDGET_BOOL("Uncheck to Relaunch Meter", bDebugLaunchMeterOnly)
ADD_WIDGET_BOOL("Reset meter offset", bResetMeterOffset)
STOP_WIDGET_GROUP()
ENDPROC
#ENDIF
#IF IS_DEBUG_BUILD
PROC RUN_DEBUG()
VECTOR vTempReturnCoords
FLOAT fTempReturnHeading
IF bDebug_UpdateTaxiCamOffsetAndRot
IF IS_VEHICLE_DRIVEABLE(g_WaitingTaxi)
IF DOES_CAM_EXIST(camMeter)
DESTROY_CAM(camMeter)
ENDIF
IF NOT DOES_CAM_EXIST(camMeter)
camMeter = CREATE_CAM_WITH_PARAMS("DEFAULT_SCRIPTED_CAMERA", GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(g_WaitingTaxi, vTaxiCamOffset), << 0.0, 0.0, 0.0>>, camMeterFOV, TRUE)
ATTACH_CAM_TO_ENTITY(camMeter, g_WaitingTaxi, vTaxiCamOffset)
UPDATE_TAXI_CAM_POSITIONING()
SET_CAM_NEAR_CLIP(camMeter, 0.01)
RENDER_SCRIPT_CAMS(TRUE, FALSE)
bDebug_UpdateTaxiCamOffsetAndRot = FALSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " RUN_DEBUG() -> ** updated taxi cam offset and rot FC = ", GET_FRAME_COUNT())
ENDIF
ENDIF
ENDIF
IF bDebug_OutputInfo
OPEN_DEBUG_FILE()
SAVE_NEWLINE_TO_DEBUG_FILE()
SAVE_STRING_TO_DEBUG_FILE("BOOL vMeterRotation = ")
SAVE_VECTOR_TO_DEBUG_FILE(vMeterRotation)
SAVE_NEWLINE_TO_DEBUG_FILE()
SAVE_STRING_TO_DEBUG_FILE("BOOL vMeterOffset = ")
SAVE_VECTOR_TO_DEBUG_FILE(vMeterOffset)
SAVE_NEWLINE_TO_DEBUG_FILE()
SAVE_STRING_TO_DEBUG_FILE("FLOAT fTaxiMenu_ScaleSizeX = ")
SAVE_FLOAT_TO_DEBUG_FILE(fTaxiMenu_ScaleSizeX)
SAVE_NEWLINE_TO_DEBUG_FILE()
SAVE_STRING_TO_DEBUG_FILE("FLOAT fTaxiMenu_ScaleSizeY = ")
SAVE_FLOAT_TO_DEBUG_FILE(fTaxiMenu_ScaleSizeY)
SAVE_NEWLINE_TO_DEBUG_FILE()
CLOSE_DEBUG_FILE()
bDebug_OutputInfo = FALSE
ENDIF
IF bAddBlipForDestination
IF NOT DOES_BLIP_EXIST(blipDebug)
blipDebug = ADD_BLIP_FOR_COORD(g_vTaxiDropOffPosition)
SET_BLIP_SCALE(blipDebug, 0.5)
ENDIF
IF NOT DOES_BLIP_EXIST(blipDebugOriginal)
blipDebugOriginal = ADD_BLIP_FOR_COORD(vOriginal)
SET_BLIP_SCALE(blipDebugOriginal, 0.5)
SET_BLIP_COLOUR(blipDebugOriginal, BLIP_COLOUR_GREEN)
ENDIF
ELSE
IF DOES_BLIP_EXIST(blipDebug)
REMOVE_BLIP(blipDebug)
ENDIF
IF DOES_BLIP_EXIST(blipDebugOriginal)
REMOVE_BLIP(blipDebugOriginal)
ENDIF
ENDIF
IF bDebugDrawAllTaxiPickupPositionInfo
SET_DEBUG_ACTIVE(TRUE)
SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(TRUE)
bDebug_DisplayTaxiToPlayerPullInSpot = TRUE
//bDebug_DisplayTaxiDropOffPosition = TRUE
bDebugDrawSphereAroundActiveTaxi = TRUE
ENDIF
IF bDebug_DisplayTaxiDropOffPosition
SET_DEBUG_ACTIVE(TRUE)
SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(TRUE)
DRAW_DEBUG_SPHERE(g_vTaxiDropOffPosition, 2.0, 250, 140, 0, 125)
ENDIF
IF bResetMeterOffset
IF IS_VEHICLE_DRIVEABLE(g_WaitingTaxi)
IF DOES_ENTITY_EXIST(objMeter)
DETACH_ENTITY(objMeter)
ATTACH_ENTITY_TO_ENTITY(objMeter, g_WaitingTaxi, GET_ENTITY_BONE_INDEX_BY_NAME(g_WaitingTaxi, "Chassis"), vMeterOffset, vMeterRotation)
ENDIF
ENDIF
bResetMeterOffset = FALSE
ENDIF
IF eTaxiServiceStage = TAXI_SERVICE_STATE_PLAYER_IN_TAXI
IF NOT DOES_ENTITY_EXIST(objMeter)
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " objMeter no longer exists, who removed it?")
ENDIF
ENDIF
IF bDebugDrawSphereAroundActiveTaxi
SET_DEBUG_ACTIVE(TRUE)
SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(TRUE)
IF IS_VEHICLE_DRIVEABLE(g_WaitingTaxi)
VECTOR vTempDrawPos = GET_ENTITY_COORDS(g_WaitingTaxi)
vTempDrawPos.Z += 14.0
DRAW_DEBUG_SPHERE(vTempDrawPos, 10.0, 0, 250, 0, 120)
ENDIF
ENDIF
IF bDebugDisplayPathNodeLoadArea
VECTOR vTempLoadAreaMin = vPathNodeRequestMin
vTempLoadAreaMin.z -= 100.0
VECTOR vTempLoadAreaMax = vPathNodeRequestMax
vTempLoadAreaMax.z += 150.0
DRAW_DEBUG_BOX(vTempLoadAreaMin, vTempLoadAreaMax, 0, 255, 0, 120)
ENDIF
IF bDebug_TestIsPositionInSpecialArea
IF ARE_COORDS_IN_SPECIAL_AREA(vDebug_TempPickupPos, vTempReturnCoords, fTempReturnHeading)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " bDebug_TestIsPositionInSpecialArea - return TRUE for vDebug_TempPickupPos : ", vDebug_TempPickupPos,
" vTempReturnCoords = ", vTempReturnCoords, " fTempReturnHeading = ", fTempReturnHeading)
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " bDebug_TestIsPositionInSpecialArea - return FALSE for vDebug_TempPickupPos : ", vDebug_TempPickupPos)
ENDIF
SET_DEBUG_ACTIVE(TRUE)
SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(TRUE)
DRAW_DEBUG_SPHERE(vDebug_TempPickupPos, 2.5, 250, 150, 0, 200)
DRAW_DEBUG_SPHERE(vTempReturnCoords, 5.0, 0, 150, 150, 200)
ENDIF
IF bDebugSetBreakOnNodeCommandsUsage
BREAK_ON_NATIVE_COMMAND("LOAD_ALL_PATH_NODES", FALSE)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " DEBUG : BREAK_ON_NATIVE_COMMAND set for LOAD_ALL_PATH_NODES")
bDebugSetBreakOnNodeCommandsUsage = FALSE
ENDIF
IF bDebugLoadAllPathNodes
LOAD_ALL_PATH_NODES(TRUE)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " DEBUG : bDebugLoadAllPathNodes - LOAD_ALL_PATH_NODES(TRUE)")
bDebugLoadAllPathNodes = FALSE
ENDIF
IF bDebugUnLoadAllPathNodes
LOAD_ALL_PATH_NODES(FALSE)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " DEBUG : bDebugUnLoadAllPathNodes - LOAD_ALL_PATH_NODES(FALSE)")
bDebugUnLoadAllPathNodes = FALSE
ENDIF
IF bDebug_LaunchMeter
scaleformTaxiMeter = REQUEST_SCALEFORM_MOVIE("taxi_display")
eTaxiServiceStage = TAXI_SERVICE_METER_ONLY
bDebug_LaunchMeter = FALSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : DEBUG_LAUNCH_TAXI_METER()")
ENDIF
IF bCleanupScript
TAXI_SERVICE_SCRIPT_CLEANUP()
ENDIF
ENDPROC
PROC DEBUG_RUN_METER_ONLY()
#IF IS_DEBUG_BUILD
IF bDebugLaunchMeterOnly
PROCESS_PLAYER_CONTROL_INPUTS()
SET_DEBUG_ACTIVE(TRUE)
SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(TRUE)
ELSE
fTaxiMenu_ScaleSizeX = (3*0.3)
fTaxiMenu_ScaleSizeY = (1.8*0.3)
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE, SPC_LEAVE_CAMERA_CONTROL_ON)
bDebugLaunchMeterOnly = TRUE
WHILE NOT HAS_SCALEFORM_MOVIE_LOADED(scaleformTaxiMeter)
IF NOT IS_TAXI_SERVICE_SAFE_TO_RUN()
TAXI_SERVICE_SCRIPT_CLEANUP()
ENDIF
WAIT(0)
ENDWHILE
POPULATE_TAXI_METER()
ENDIF
#ENDIF
ENDPROC
#ENDIF
/// PURPOSE:
/// sets the taxi service data based off the launch method
/// RETURNS:
/// TRUE if script was setup successfully
FUNC BOOL CAN_SETUP_TAXI_SERVICE()
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
VEHICLE_INDEX vehTaxi = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())
iStoredNumberOfBlips = GET_NUMBER_OF_ACTIVE_BLIPS()
// commented out for B*1518083 - now allow player to get in but just exit option if no taxi destinations available - this allows them to plot custom waypoint whilst sat in the back
// can't give taxi ride if there are no destinatios to choose from
//IF iStoredNumberOfBlips != 0
// safe check player vehicle and it's driver
IF IS_PLAYER_OK_TO_ENTER_VEHICLE_AS_PASSENGER(vehTaxi, GET_TAXI_MODEL(), GET_TAXI_DRIVER_MODEL())
PED_INDEX pedTaxiDriver = GET_PED_IN_VEHICLE_SEAT(vehTaxi, VS_DRIVER)
#IF IS_DEBUG_BUILD SETUP_DEBUG() #ENDIF
//#IF IS_DEBUG_BUILD bDebug_DrawGetPullOverResults = TRUE #ENDIF // bDebug_DrawGetPullOverResults // bDebugDrawAllTaxiPickupPositionInfo
CLEAR_CUSTOM_DROP_OFF()
// taken from old setup
SET_PLAYER_CAN_DO_DRIVE_BY(PLAYER_ID(), FALSE)
HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_WEAPON_ICON)
STOP_PED_SPEAKING(PLAYER_PED_ID(), TRUE)
// store seat player is using to aid tasking group members into the taxi (player only even enters rear seats)
IF GET_PED_IN_VEHICLE_SEAT(vehTaxi, VS_BACK_LEFT) = PLAYER_PED_ID()
eStoredPlayerSeat = VS_BACK_LEFT
ELSE
eStoredPlayerSeat = VS_BACK_RIGHT
ENDIF
// ensure the taxiService.sc script now takes full ownership of g_WaitingTaxi & g_WaitingTaxiDriver
IF STORE_CAR_AS_TAXI_WAITING_FOR_PLAYER(vehTaxi, pedTaxiDriver, TRUE)
vOriginal = GET_ENTITY_COORDS(g_WaitingTaxi) - GET_ENTITY_COORDS(PLAYER_PED_ID())
vOriginal.z = 0.0
fDropOffDistFromBlip = VMAG(vOriginal)
charWhenTaxiLaunched = GET_PLAYER_PED_ENUM(PLAYER_PED_ID())
NON_GROUPED_PASSENGERS_SHOULD_FLEE()
iStoredNumberOfOccupants = GET_NUMBER_OF_TAXI_OCCUPANTS()
bUpdateTaxiControls = TRUE
// B*1456818 - one frame disable to release player enter /exit vehicle request to
// ensure he doesn't just get straight back out upon entering with button held down
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_EXIT)
g_bPlayerIsInTaxi = TRUE
eTaxiJourneyState = TAXI_JOURNEY_STATE_CREATE_TAXI_METER
eTaxiServiceStage = TAXI_SERVICE_STATE_PLAYER_IN_TAXI
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : CAN_SETUP_TAXI_SERVICE() return TRUE")
RETURN TRUE
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : CAN_SETUP_TAXI_SERVICE() return FALSE - STORE_CAR_AS_TAXI_WAITING_FOR_PLAYER check")
ENDIF
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : CAN_SETUP_TAXI_SERVICE() return FALSE - IS_PLAYER_OK_TO_ENTER_VEHICLE_AS_PASSENGER check")
ENDIF
//ELSE
// CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : CAN_SETUP_TAXI_SERVICE() return FALSE - iStoredNumberOfBlips = 0")
//ENDIF
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : CAN_SETUP_TAXI_SERVICE() return FALSE - IS_PED_INJURED(PLAYER_PED_ID()")
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// state during journey where player has asked for taxi to pull over early
PROC JOURNEY_STATE_ORDERED_TO_PULLOVER()
IF NOT IS_PED_INJURED(g_WaitingTaxiDriver)
AND IS_VEHICLE_DRIVEABLE(g_WaitingTaxi)
IF IS_PED_SITTING_IN_VEHICLE(g_WaitingTaxiDriver, g_WaitingTaxi)
IF IS_VEHICLE_STOPPED(g_WaitingTaxi)
IF NOT IS_ENTITY_PLAYING_ANIM(g_WaitingTaxiDriver, tlAnimDictTaxiDriver, "leanover_enter")
AND NOT IS_ENTITY_PLAYING_ANIM(g_WaitingTaxiDriver, tlAnimDictTaxiDriver, "leanover_idle")
IF NOT TAXI_IS_PED_PERFORMING_TASK(g_WaitingTaxiDriver, SCRIPT_TASK_VEHICLE_TEMP_ACTION)
TASK_VEHICLE_TEMP_ACTION(g_WaitingTaxiDriver, g_WaitingTaxi, TEMPACT_WAIT, 1000000)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : JOURNEY_STATE_ORDERED_TO_PULLOVER set stop in place task")
ELSE
SET_DRIVER_PLAY_TURN_AROUND_ANIM()
ENDIF
ENDIF
SET_PLAYER_GROUP_MEMBERS_INTO_TAXI(g_WaitingTaxi, eStoredPlayerSeat)
ELSE
IF NOT TAXI_IS_PED_PERFORMING_TASK(g_WaitingTaxiDriver, SCRIPT_TASK_VEHICLE_PARK)
VECTOR vTemp = GET_ENTITY_COORDS(g_WaitingTaxi)
FLOAT fTemp = GET_ENTITY_HEADING(g_WaitingTaxi)
TASK_VEHICLE_PARK(g_WaitingTaxiDriver, g_WaitingTaxi, vTemp, fTemp, PARK_TYPE_PULL_OVER, 60)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : JOURNEY_STATE_ORDERED_TO_PULLOVER set pull over task")
ENDIF
ENDIF
ENDIF
ENDIF
ENDPROC
/// PURPOSE:
/// Handles the player being in the taxi state
PROC PLAYER_IN_TAXI_STATE()
IF IS_PLAYER_PASSENGER_IN_VALID_TAXI_CAB()
BLOCK_SPECIFIC_PLAYER_CONTROLS_FOR_TAXI_JOURNEY_THIS_FRAME()
SUPPRESS_AMBIENT_REACTIONS_FOR_TAXI_JOURNEY_THIS_FRAME()
CLEAR_CUSTOM_DROP_OFF()
IF NOT SHOULD_TAXI_CONTROLS_BE_BLOCKED_THIS_FRAME()
PROCESS_PLAYER_CONTROL_INPUTS()
ENDIF
RENDER_TAXI_METER()
IF eTaxiJourneyState != TAXI_JOURNEY_STATE_SKIP_JOURNEY
PLAY_TAXI_DIALOGUE(g_WaitingTaxiDriver, eTaxiDialogue)
IF eTaxiJourneyState != TAXI_JOURNEY_STATE_CREATE_TAXI_METER
// check the destinations are up to prior to allowing input to select a destination
IF HAS_TAXI_DESTINATION_LIST_CHANGED()
IF HAS_SCALEFORM_MOVIE_LOADED(scaleformTaxiMeter)
POPULATE_TAXI_METER()
bUpdateTaxiControls = TRUE // update after taxi list gets repopulated incase no blips left / blips added
ENDIF
ENDIF
RUN_TAXI_INTERIOR_CAM()
ENDIF
ENDIF
SWITCH eTaxiJourneyState
// Create the taxi meter object and set up the scaleforms
CASE TAXI_JOURNEY_STATE_CREATE_TAXI_METER
IF NOT IS_PED_INJURED(g_WaitingTaxiDriver)
AND IS_VEHICLE_DRIVEABLE(g_WaitingTaxi)
IF IS_PED_SITTING_IN_VEHICLE(g_WaitingTaxiDriver, g_WaitingTaxi)
IF NOT IS_ENTITY_PLAYING_ANIM(g_WaitingTaxiDriver, tlAnimDictTaxiDriver, "leanover_enter")
AND NOT IS_ENTITY_PLAYING_ANIM(g_WaitingTaxiDriver, tlAnimDictTaxiDriver, "leanover_idle")
IF NOT TAXI_IS_PED_PERFORMING_TASK(g_WaitingTaxiDriver, SCRIPT_TASK_VEHICLE_TEMP_ACTION)
TASK_VEHICLE_TEMP_ACTION(g_WaitingTaxiDriver, g_WaitingTaxi, TEMPACT_WAIT, 1000000)
ENDIF
ENDIF
ENDIF
ENDIF
IF REQUEST_AND_LOAD_TAXI_ASSETS()
IF CREATE_TAXI_METER()
AND NOT IS_PED_GETTING_INTO_A_VEHICLE(PLAYER_PED_ID())
POPULATE_TAXI_METER()
eTaxiDialogue = TAXI_DIALOGUE_WHERE_TO // set dialogue to trigger in PLAY_TAXI_DIALOGUE()
eGenerateSafeDestinationState = TAXI_GSDS_INITIAL_TRIGGER_AREAS_CHECK
g_iTaxiHailedTime = 0 // reset the hail time out so the taxi won't instantly drive off it the player leaves the taxi
iDesinationNodeSearchNumber = 0 // reset ready for getting taxi pull in spot
bPlayerCanLeaveVehicle = FALSE // reset ready for control checks
bTaxiHasHitDestinationLocate = FALSE // reset ready
//iLastTimeExitWasAttempted = 0 // reset ready for control checks
bUpdateTaxiControls = TRUE
SET_DRIVER_PLAY_TURN_AROUND_ANIM()
eTaxiJourneyState = TAXI_JOURNEY_STATE_CHOOSE_LOCATION
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : TAXI_JOURNEY_STATE_CREATE_TAXI_METER -> TAXI_JOURNEY_STATE_CHOOSE_LOCATION : fc = ", GET_FRAME_COUNT())
ELSE
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : TAXI_JOURNEY_STATE_CREATE_TAXI_METER -> waiting on create taxi meter and player getting in veh : fc = ", GET_FRAME_COUNT())
ENDIF
ENDIF
BREAK
// Player makes his initial destination selection
CASE TAXI_JOURNEY_STATE_CHOOSE_LOCATION
IF NOT IS_PED_INJURED(g_WaitingTaxiDriver)
AND IS_VEHICLE_DRIVEABLE(g_WaitingTaxi)
IF IS_PED_SITTING_IN_VEHICLE(g_WaitingTaxiDriver, g_WaitingTaxi)
IF NOT IS_ENTITY_PLAYING_ANIM(g_WaitingTaxiDriver, tlAnimDictTaxiDriver, "leanover_enter")
AND NOT IS_ENTITY_PLAYING_ANIM(g_WaitingTaxiDriver, tlAnimDictTaxiDriver, "leanover_idle")
IF NOT TAXI_IS_PED_PERFORMING_TASK(g_WaitingTaxiDriver, SCRIPT_TASK_VEHICLE_TEMP_ACTION)
TASK_VEHICLE_TEMP_ACTION(g_WaitingTaxiDriver, g_WaitingTaxi, TEMPACT_WAIT, 1000000)
ENDIF
ENDIF
ENDIF
ENDIF
SET_PLAYER_GROUP_MEMBERS_INTO_TAXI(g_WaitingTaxi, eStoredPlayerSeat)
IF HAS_PLAYER_SELECTED_DESTINATION()
STAT_INCREMENT(SP_NUMBER_OF_TAXIS_USED, 1.0) // B*1545773
bUpdateTaxiControls = TRUE
eTaxiJourneyState = TAXI_JOURNEY_STATE_DRIVING_TO_DESTINATION
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " eTaxiJourneyState = TAXI_JOURNEY_STATE_CHOOSE_LOCATION -> TAXI_JOURNEY_STATE_DRIVING_TO_DESTINATION : fc = ", GET_FRAME_COUNT())
ENDIF
BREAK
// Taxi is on route to the destination
CASE TAXI_JOURNEY_STATE_DRIVING_TO_DESTINATION
IF HAS_PLAYER_SELECTED_DESTINATION()
SEND_TAXI_TO_DESTINATION()
ENDIF
BREAK
// State where the player has asked the taxi to pull over during the journey
CASE TAXI_JOURNEY_STATE_ORDERED_TO_PULLOVER
JOURNEY_STATE_ORDERED_TO_PULLOVER()
BREAK
// Player has skipped the journey to the destination
CASE TAXI_JOURNEY_STATE_SKIP_JOURNEY
SKIP_JOURNEY_TO_DESTINATION()
BREAK
ENDSWITCH
UPDATE_TAXI_INSTRUCTIONAL_BUTTONS()
ELSE
eTaxiServiceStage = TAXI_SERVICE_END
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " eTaxiJourneyState = TAXI_SERVICE_STATE_PLAYER_IN_TAXI -> TAXI_SERVICE_END : fc = ", GET_FRAME_COUNT())
ENDIF
ENDPROC
/// PURPOSE:
/// Handles the player getting out of the taxi
PROC TAXI_SERVICE_END_STATE()
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
IF g_bPlayerIsInTaxi
g_bPlayerIsInTaxi = FALSE
IF IS_PLAYER_PLAYING(PLAYER_ID())
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
SET_PLAYER_CAN_DO_DRIVE_BY(PLAYER_ID(), TRUE)
ENDIF
STOP_PED_SPEAKING(PLAYER_PED_ID(), FALSE)
IF eTaxiJourneyState = TAXI_JOURNEY_STATE_DRIVING_TO_DESTINATION
OR eTaxiJourneyState = TAXI_JOURNEY_STATE_ORDERED_TO_PULLOVER
OR eTaxiJourneyState = TAXI_JOURNEY_STATE_SKIP_JOURNEY
ATTEMPT_PAYMENT()
ENDIF
ENDIF
ENDIF
CANCEL_GROUP_GETTING_INTO_CAB()
IF IS_VEHICLE_OK(g_WaitingTaxi)
AND IS_PED_IN_VEHICLE(PLAYER_PED_ID(), g_WaitingTaxi, TRUE)
IF NOT TAXI_IS_PED_PERFORMING_TASK(PLAYER_PED_ID(), SCRIPT_TASK_LEAVE_ANY_VEHICLE)
AND NOT TAXI_IS_PED_PERFORMING_TASK(PLAYER_PED_ID(), SCRIPT_TASK_LEAVE_VEHICLE)
TASK_LEAVE_ANY_VEHICLE(PLAYER_PED_ID(), 0)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " TAXI_SERVICE_END -> player tasked to leave task")
ENDIF
ELSE
// speed off and cleanup if player has wanted level
IF IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0)
IF NOT IS_PED_INJURED(g_WaitingTaxiDriver)
AND IS_VEHICLE_DRIVEABLE(g_WaitingTaxi)
IF IS_PED_IN_VEHICLE(g_WaitingTaxiDriver, g_WaitingTaxi)
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
TASK_VEHICLE_MISSION_PED_TARGET(g_WaitingTaxiDriver, g_WaitingTaxi, PLAYER_PED_ID(), MISSION_FLEE, 25.0, DRIVINGMODE_AVOIDCARS_RECKLESS | DF_AvoidRestrictedAreas, 300.0, 15.0)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " TAXI_SERVICE_END -> drive tasked to flee player in car")
ENDIF
ELSE
IF NOT IS_PED_FLEEING(g_WaitingTaxiDriver)
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
TASK_SMART_FLEE_PED(g_WaitingTaxiDriver, PLAYER_PED_ID(), 300.0, -1)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " TAXI_SERVICE_END -> drive tasked to flee player on foot")
ENDIF
ENDIF
ENDIF
SET_PED_KEEP_TASK(g_WaitingTaxiDriver, TRUE)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(g_WaitingTaxiDriver, FALSE)
ENDIF
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " TAXI_SERVICE_END -> player wanted ending")
ELSE
IF NOT IS_PED_INJURED(g_WaitingTaxiDriver)
AND IS_VEHICLE_DRIVEABLE(g_WaitingTaxi)
IF IS_PED_IN_VEHICLE(g_WaitingTaxiDriver, g_WaitingTaxi)
IF NOT TAXI_IS_PED_PERFORMING_TASK(g_WaitingTaxiDriver, SCRIPT_TASK_VEHICLE_DRIVE_WANDER)
TASK_VEHICLE_DRIVE_WANDER(g_WaitingTaxiDriver, g_WaitingTaxi, TAXI_SPEED_NORMAL, DRIVINGMODE_STOPFORCARS | DF_AvoidRestrictedAreas)
ENDIF
ENDIF
SET_PED_KEEP_TASK(g_WaitingTaxiDriver, TRUE)
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(g_WaitingTaxiDriver, FALSE)
ENDIF
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " TAXI_SERVICE_END -> normal ending")
ENDIF
TAXI_SERVICE_SCRIPT_CLEANUP()
ENDIF
ENDPROC
SCRIPT
IF HAS_FORCE_CLEANUP_OCCURRED(FORCE_CLEANUP_FLAG_SP_TO_MP | FORCE_CLEANUP_FLAG_REPEAT_PLAY)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : force cleanup occured, script set to terminate")
IF GET_CAUSE_OF_MOST_RECENT_FORCE_CLEANUP() = FORCE_CLEANUP_FLAG_REPEAT_PLAY
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : force cleanup - repeat play cleanup")
TAXI_SERVICE_SCRIPT_CLEANUP(FALSE)
ELSE
TAXI_SERVICE_SCRIPT_CLEANUP()
ENDIF
TERMINATE_THIS_THREAD()
ENDIF
IF NOT CAN_SETUP_TAXI_SERVICE()
TAXI_SERVICE_SCRIPT_CLEANUP()
ENDIF
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : initalised ^^^^^")
WHILE(TRUE)
// general checks if the script needs to terminate early
IF NOT IS_TAXI_SERVICE_SAFE_TO_RUN()
TAXI_SERVICE_SCRIPT_CLEANUP()
ENDIF
//IS_REPLAY_BEING_PROCESSED need to add to terminate straight away
IF SHOULD_TAXI_SERVICE_END_EARLY(eTaxiServiceStage)
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_TAXI_SERVICE_END_EARLY returned TRUE for stage : ", eTaxiServiceStage)
TAXI_SERVICE_SCRIPT_CLEANUP()
ENDIF
SWITCH eTaxiServiceStage
CASE TAXI_SERVICE_STATE_PLAYER_IN_TAXI
PLAYER_IN_TAXI_STATE()
BREAK
CASE TAXI_SERVICE_END
TAXI_SERVICE_END_STATE()
BREAK
CASE TAXI_SERVICE_METER_ONLY
#IF IS_DEBUG_BUILD
DEBUG_RUN_METER_ONLY()
#ENDIF
BREAK
ENDSWITCH
#IF IS_DEBUG_BUILD RUN_DEBUG() #ENDIF
WAIT(0)
ENDWHILE
ENDSCRIPT