3673 lines
200 KiB
Python
Executable File
3673 lines
200 KiB
Python
Executable File
//////////////////////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// MISSION NAME : taxiLauncher.sc //
|
|
// AUTHOR : Ahron Mason //
|
|
// DESCRIPTION : Handles player calling a cab or entering a cab, //
|
|
// Also launches TaxiService.sc which handles player in a cab //
|
|
// //
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
USING "rage_builtins.sch"
|
|
USING "globals.sch"
|
|
|
|
USING "area_checks.sch"
|
|
USING "cellphone_public.sch"
|
|
USING "context_control_public.sch"
|
|
USING "flow_help_public.sch"
|
|
USING "taxi_functions.sch"
|
|
USING "tv_control_public.sch"
|
|
USING "website_public.sch"
|
|
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------------------------
|
|
// :ENUMS:
|
|
//-------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
/// PURPOSE: state of the launcher
|
|
ENUM TAXI_LAUNCHER_STATE
|
|
TL_STATE_IDLE,
|
|
TL_STATE_PLAYER_NOT_IN_TAXI,
|
|
TL_STATE_PLAYER_IN_TAXI
|
|
ENDENUM
|
|
|
|
/// PURPOSE: state for the phone launching
|
|
ENUM TAXI_LAUNCHER_PHONE_STATE
|
|
TL_PHONE_STATE_AWAITING_CALL,
|
|
TL_PHONE_STATE_WAIT_TO_RESET_CALL,
|
|
TL_PHONE_STATE_CALL_IN_PROGRESS
|
|
ENDENUM
|
|
|
|
/// PURPOSE: states for the dispatched taxi
|
|
ENUM TAXI_LAUNCHER_DISPATCHED_STATE
|
|
TL_DISPATCHED_STATE_IDLE,
|
|
TL_DISPATCHED_STATE_CREATE_TAXI,
|
|
TL_DISPATCHED_STATE_DRIVE_TO_PICKUP_PLAYER,
|
|
TL_DISPATCHED_STATE_PULL_OVER_TO_PICKUP_PLAYER
|
|
ENDENUM
|
|
|
|
/// PURPOSE: states for controlling player getting into taxis
|
|
ENUM TAXI_LAUNCHER_ENTER_TAXI_STATE
|
|
TL_ENTER_TAXI_STATE_IDLE,
|
|
TL_ENTER_TAXI_STATE_ENTERING,
|
|
TL_ENTER_TAXI_STATE_INSIDE,
|
|
TL_ENTER_TAXI_STATE_WAIT_FOR_PLAYER_TO_EXIT
|
|
ENDENUM
|
|
|
|
/// PURPOSE: states for controlling player getting into taxis
|
|
ENUM TAXI_LAUNCHER_HAIL_TAXI_STATE
|
|
TL_HAIL_TAXI_STATE_IDLE,
|
|
TL_HAIL_TAXI_STATE_DETECT_HAIL,
|
|
TL_HAIL_TAXI_STATE_SUCCESSFUL_ATTEMPT,
|
|
TL_HAIL_TAXI_STATE_FAILED_ATTEMPT,
|
|
TL_HAIL_TAXI_STATE_TAXI_WAITING
|
|
ENDENUM
|
|
|
|
/// PURPOSE: data used by the taxi dispatched by the phone call
|
|
STRUCT DISPATCHED_TAXI_STRUCT
|
|
VEHICLE_INDEX vehicleIndex
|
|
PED_INDEX pedIndex
|
|
BOOL bHasActiveTask
|
|
BOOL bForcedPullOverAtCurrentPosition = FALSE
|
|
BOOL bFailedZCheck = FALSE
|
|
FLOAT fDistToTarget
|
|
FLOAT fDriveToHeading
|
|
FLOAT fTargetReached
|
|
INT iNodeSearchNumber
|
|
INT iTimer_TaxiDispatchDelay
|
|
INT iSpawnAttempts
|
|
VECTOR vDistToPlayer
|
|
VECTOR vDriveToCoords
|
|
VECTOR vPullOverCoords
|
|
VECTOR vPlayerCalledCoords
|
|
VECTOR vPathNodeRequestMin
|
|
VECTOR vPathNodeRequestMax
|
|
DRIVINGMODE taxiDrivingModeStandard
|
|
enumCharacterList eCharDispatchedFor
|
|
ENDSTRUCT
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------------------------
|
|
// :CONSTANTS
|
|
//-------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
CONST_FLOAT TAXI_HAIL_DISTANCE 35.0
|
|
CONST_FLOAT TAXI_MOVING_GET_IN_SPEED 0.5
|
|
CONST_INT ENTER_CAR_AS_PASSENGER_TIME 275
|
|
CONST_INT STICK_DEAD_ZONE 28
|
|
CONST_INT TIME_DELAY_TAXI_DISPATCHED 10000
|
|
CONST_INT PROG_INITIALISE 0
|
|
CONST_INT PROG_ATTEMPT_HAIL 1
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------------------------
|
|
// :VARIABLES
|
|
//-------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
TAXI_LAUNCHER_STATE eTaxiLauncherState = TL_STATE_IDLE
|
|
TAXI_LAUNCHER_PHONE_STATE eCallTaxiServiceState = TL_PHONE_STATE_AWAITING_CALL
|
|
TAXI_LAUNCHER_DISPATCHED_STATE eDispatchedTaxiState = TL_DISPATCHED_STATE_IDLE
|
|
TAXI_LAUNCHER_ENTER_TAXI_STATE eEnterTaxiState = TL_ENTER_TAXI_STATE_IDLE
|
|
TAXI_LAUNCHER_HAIL_TAXI_STATE eHailTaxiState = TL_HAIL_TAXI_STATE_IDLE
|
|
DISPATCHED_TAXI_STRUCT sDispatchedTaxi
|
|
|
|
BOOL bPlayAdditionalFuckYouDialogue
|
|
BOOL bHintTriggeredByTaxiLauncher
|
|
BOOL bHelpEnterTaxiDisplayed = FALSE
|
|
BOOL bUpdateHailTargetThisFrame = TRUE
|
|
BOOL bPhonecallReachedSuccessfulLine = FALSE
|
|
BOOL bBlockingPlayerAmbientIdles = FALSE
|
|
|
|
BLIP_INDEX blipWaitingTaxi
|
|
|
|
INT iHailPromptCounter
|
|
INT iTaxiHailIntention = NEW_CONTEXT_INTENTION
|
|
INT iTimer_DelayTaxiSearch
|
|
INT iTimer_HailAnimTriggered
|
|
INT iTimer_HailFailedDialogueDelay
|
|
|
|
MODEL_NAMES mnTaxiDriverModel = GET_TAXI_DRIVER_MODEL()
|
|
MODEL_NAMES mnTaxiModel = GET_TAXI_MODEL()
|
|
|
|
// Phonecall Vars
|
|
structPedsForConversation phonecallStruct
|
|
STRING playerVoice
|
|
STRING playerLine1
|
|
STRING playerLine3
|
|
|
|
THREADID tTaxiServiceThread
|
|
TEXT_LABEL_15 tlTaxiAnimDict = "TAXI_HAIL"
|
|
|
|
VECTOR vPlayerPos
|
|
|
|
VEHICLE_INDEX vehClosestTaxi
|
|
VEHICLE_INDEX vehHailTarget
|
|
|
|
VEHICLE_SEAT ePlayerChosenSeat
|
|
|
|
|
|
//-------------------------------------------------------------------------------------------------------------------------------------------------
|
|
// :DEBUG FUNCS / PROCS / WIDGETS
|
|
//-------------------------------------------------------------------------------------------------------------------------------------------------
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
|
|
BLIP_INDEX bDebug_blip1
|
|
BLIP_INDEX bDebug_blip2
|
|
BLIP_INDEX bDebug_blip3
|
|
BOOL bDebug_AddBlips = FALSE
|
|
BOOL bDebug_CallCab = FALSE
|
|
BOOL bDebug_DisplayInfo = FALSE
|
|
BOOL bDebug_DisplayCleanupTTY = FALSE
|
|
BOOL bDebug_KillPlayerVehicle = FALSE
|
|
BOOL bDebug_VisualiseDispatchTaxi = FALSE
|
|
BOOL bDebug_OutputText = FALSE
|
|
BOOL bDebug_Point1 = TRUE
|
|
BOOL bDebug_ZeroPlayerCash = FALSE
|
|
BOOL bDebug_DrawGetPullOverResults = FALSE
|
|
BOOL bDebug_SetCanPlayerUseTaxiFalse = FALSE
|
|
BOOL bDebug_SetCanPlayerUseTaxiTrue = FALSE
|
|
BOOL bDebug_VisualiseIsPointInAngledAreaCheck = FALSE
|
|
VECTOR vDebug_PointInAngledTest
|
|
VECTOR vDebug_PointInAngledAreaCheck[2]
|
|
FLOAT fDebug_PointInAngledAreaWidth
|
|
BOOL bDebug_UseForceTaxiSpawnCoordsAndHeading = FALSE
|
|
VECTOR vDebug_ForcedTaxiSpawnCoords
|
|
FLOAT fDebug_ForcedTaxiSpawnHeading
|
|
//BOOL bDebugPerformGenerateTaxiSpawnPos = FALSE
|
|
//BOOL bDebugPerformGetTaxiDriveToPlayerTest = FALSE
|
|
//BOOL bDebug_TestIsPositionInSpecialArea = FALSE
|
|
//BOOL bDebugPerformGetTaxiPullInSpotTest = FALSE
|
|
FLOAT fDebug_DistBetween1n4[8]
|
|
//FLOAT fDebug_DriveToNodeHeading
|
|
INT iDebug_CurrentArea
|
|
VECTOR vDebug_AreaBound1[8]
|
|
VECTOR vDebug_AreaBound2[8]
|
|
VECTOR vDebug_DispatchTaxiSpawnPos
|
|
//VECTOR vDebug_TaxiPos
|
|
//VECTOR vDebug_DriveToNodePos
|
|
//VECTOR vDebug_TempPickupPos
|
|
WIDGET_GROUP_ID widgetGroup
|
|
|
|
/// PURPOSE:
|
|
/// Sets up the script's widget groups, which get created in RAG->SCRIPT
|
|
PROC DEBUG_SETUP_WIDGETS()
|
|
widgetGroup = START_WIDGET_GROUP("taxiLauncher")
|
|
ADD_WIDGET_BOOL("Output additional TTY info", bDebug_DisplayInfo)
|
|
ADD_WIDGET_BOOL("Output additional cleanup TTY info", bDebug_DisplayCleanupTTY)
|
|
ADD_WIDGET_BOOL("Zero Player Cash", bDebug_ZeroPlayerCash)
|
|
ADD_WIDGET_BOOL("Add/remove some blips", bDebug_AddBlips)
|
|
ADD_WIDGET_BOOL("Is player in a taxi", g_bPlayerIsInTaxi)
|
|
ADD_WIDGET_BOOL("Disable Hailing status", g_bTaxiHailingIsDisabled)
|
|
ADD_WIDGET_BOOL("bDebug_SetCanPlayerUseTaxiFalse", bDebug_SetCanPlayerUseTaxiFalse)
|
|
ADD_WIDGET_BOOL("bDebug_SetCanPlayerUseTaxiTrue", bDebug_SetCanPlayerUseTaxiTrue)
|
|
ADD_WIDGET_BOOL("Kill current car", bDebug_KillPlayerVehicle)
|
|
ADD_WIDGET_BOOL("Call a cab", bDebug_CallCab)
|
|
ADD_WIDGET_BOOL("Dispatched Taxi : visualise info : ", bDebug_VisualiseDispatchTaxi)
|
|
|
|
ADD_WIDGET_VECTOR_SLIDER("vDebug_ForcedTaxiSpawnCoords : ", vDebug_ForcedTaxiSpawnCoords, -10000.0, 10000.0, 0.0001)
|
|
ADD_WIDGET_FLOAT_SLIDER("fDebug_ForcedTaxiSpawnHeading : ", fDebug_ForcedTaxiSpawnHeading, -360.0, 360.0, 0.01)
|
|
ADD_WIDGET_BOOL("Use Forced dispatch taxi spawn coords and heading: ", bDebug_UseForceTaxiSpawnCoordsAndHeading)
|
|
|
|
ADD_WIDGET_BOOL("bDebug_VisualiseIsPointInAngledAreaCheck", bDebug_VisualiseIsPointInAngledAreaCheck)
|
|
ADD_WIDGET_VECTOR_SLIDER("vDebug_PointInAngledTest : ", vDebug_PointInAngledTest, -10000.0, 10000.0, 0.0001)
|
|
ADD_WIDGET_VECTOR_SLIDER("vDebug_PointInAngledAreaCheck[0] : ", vDebug_PointInAngledAreaCheck[0], -10000.0, 10000.0, 0.0001)
|
|
ADD_WIDGET_VECTOR_SLIDER("vDebug_PointInAngledAreaCheck[1] : ", vDebug_PointInAngledAreaCheck[1], -10000.0, 10000.0, 0.0001)
|
|
ADD_WIDGET_FLOAT_SLIDER("fDebug_PointInAngledAreaWidth : ", fDebug_PointInAngledAreaWidth, 0.0, 1000.0, 0.01)
|
|
|
|
/*ADD_WIDGET_BOOL("display taxi pull over results", bDebug_DrawGetPullOverResults)
|
|
ADD_WIDGET_BOOL("Debug perform GET_TAXI_PICK_UP_PLAYER_DESTINATION test uses : ", bDebugPerformGetTaxiDriveToPlayerTest)
|
|
ADD_WIDGET_BOOL("Debug perform GENERATE_TAXI_SPAWN_POS_AND_HEADING_TO_PLAYER test : ", bDebugPerformGenerateTaxiSpawnPos)
|
|
ADD_WIDGET_BOOL("Debug perform ARE_COORDS_IN_SPECIAL_AREA test uses vDebug_TempPickupPos : ", bDebug_TestIsPositionInSpecialArea)
|
|
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_VECTOR_SLIDER("vDebug_TempPickupPos :", vDebug_TempPickupPos, -10000.0, 10000.0, 0.0001)*/
|
|
STOP_WIDGET_GROUP()
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// updates the script's widgets, based off RAG input
|
|
PROC DEBUG_UPDATE_WIDGETS()
|
|
//MONITOR_CUSTOM_DROP_OFF_BLIP()
|
|
|
|
IF bDebug_ZeroPlayerCash
|
|
//BREAK_ON_NATIVE_COMMAND("PRINTNL", TRUE)
|
|
DEBIT_BANK_ACCOUNT(GET_CURRENT_PLAYER_PED_ENUM(), BAAC_TAXI, GET_TOTAL_CASH(GET_CURRENT_PLAYER_PED_ENUM()))
|
|
bDebug_ZeroPlayerCash = FALSE
|
|
ENDIF
|
|
|
|
IF bDebug_AddBlips
|
|
IF NOT DOES_BLIP_EXIST(bDebug_blip1)
|
|
bDebug_blip1 = ADD_BLIP_FOR_COORD(<< -820.1073, -356.7995, 36.5842 >>)
|
|
SET_TAXI_DROPOFF_LOCATION_FOR_BLIP(bDebug_blip1, << -158.2055, -854.6122, 28.8008 >>, 339.2080)
|
|
ENDIF
|
|
IF NOT DOES_BLIP_EXIST(bDebug_blip2)
|
|
bDebug_blip2 = ADD_BLIP_FOR_COORD(<< -1579.8685, -503.4034, 34.3710 >>)
|
|
SET_TAXI_DROPOFF_LOCATION_FOR_BLIP(bDebug_blip1, << -158.2055, -854.6122, 28.8008 >>, 339.2080)
|
|
ENDIF
|
|
IF NOT DOES_BLIP_EXIST(bDebug_blip3)
|
|
bDebug_blip3 = ADD_BLIP_FOR_COORD(<< -735.7357, -1185.1532, 9.6465 >>)
|
|
SET_TAXI_DROPOFF_LOCATION_FOR_BLIP(bDebug_blip1, << -158.2055, -854.6122, 28.8008 >>, 339.2080)
|
|
ENDIF
|
|
ELSE
|
|
IF DOES_BLIP_EXIST(bDebug_blip1)
|
|
REMOVE_BLIP(bDebug_blip1)
|
|
ENDIF
|
|
IF DOES_BLIP_EXIST(bDebug_blip2)
|
|
REMOVE_BLIP(bDebug_blip2)
|
|
ENDIF
|
|
IF DOES_BLIP_EXIST(bDebug_blip3)
|
|
REMOVE_BLIP(bDebug_blip3)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF bDebug_SetCanPlayerUseTaxiFalse
|
|
DISABLE_TAXI_HAILING(TRUE)
|
|
bDebug_SetCanPlayerUseTaxiFalse = FALSE
|
|
ELIF bDebug_SetCanPlayerUseTaxiTrue
|
|
DISABLE_TAXI_HAILING(FALSE)
|
|
bDebug_SetCanPlayerUseTaxiTrue = FALSE
|
|
ENDIF
|
|
|
|
IF bDebug_KillPlayerVehicle
|
|
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
|
|
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
|
|
SET_VEHICLE_ENGINE_HEALTH(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), 0)
|
|
ENDIF
|
|
ENDIF
|
|
bDebug_KillPlayerVehicle = FALSE
|
|
ENDIF
|
|
|
|
IF bDebug_VisualiseIsPointInAngledAreaCheck
|
|
IF IS_POINT_IN_ANGLED_AREA(vDebug_PointInAngledTest, vDebug_PointInAngledAreaCheck[0], vDebug_PointInAngledAreaCheck[1], fDebug_PointInAngledAreaWidth, TRUE)
|
|
DRAW_DEBUG_SPHERE(vDebug_PointInAngledTest, 0.5, 10, 200, 50, 150)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " DEBUG: IS_POINT_IN_ANGLED_AREA vDebug_PointInAngledTest = ", vDebug_PointInAngledTest)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF bDebug_VisualiseDispatchTaxi
|
|
IF DOES_ENTITY_EXIST(sDispatchedTaxi.vehicleIndex)
|
|
SET_DEBUG_ACTIVE(TRUE)
|
|
SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(TRUE)
|
|
VECTOR vTempDrawPos
|
|
VECTOR vTempPos = GET_ENTITY_COORDS(sDispatchedTaxi.vehicleIndex, FALSE)
|
|
IF IS_VEHICLE_DRIVEABLE(g_WaitingTaxi)
|
|
vTempDrawPos = vTempPos
|
|
vTempDrawPos.Z += 14.0
|
|
DRAW_DEBUG_SPHERE(vTempDrawPos, 10.0, 0, 250, 100, 120)
|
|
ENDIF
|
|
DRAW_DEBUG_LINE(vDebug_DispatchTaxiSpawnPos, vTempPos, 255, 0, 0, 255) // red
|
|
DRAW_DEBUG_LINE(sDispatchedTaxi.vDriveToCoords, vTempPos, 255, 165, 0, 255) // orange
|
|
DRAW_DEBUG_LINE(sDispatchedTaxi.vPullOverCoords , vTempPos, 75, 255, 0, 255) // light green
|
|
ENDIF
|
|
ENDIF
|
|
|
|
/*
|
|
IF bDebugPerformGenerateTaxiSpawnPos
|
|
IF GENERATE_TAXI_SPAWN_POS_AND_HEADING_TO_PLAYER(vTempReturnCoords, fTempReturnHeading)
|
|
STRING sTemp
|
|
OPEN_DEBUG_FILE()
|
|
SAVE_NEWLINE_TO_DEBUG_FILE()
|
|
sTemp = "DEBUG : bDebugPerformGenerateTaxiSpawnPos results : vReturnCoords = "
|
|
SAVE_STRING_TO_DEBUG_FILE(sTemp)
|
|
SAVE_VECTOR_TO_DEBUG_FILE(vTempReturnCoords)
|
|
sTemp = " : vReturnHeading = "
|
|
SAVE_STRING_TO_DEBUG_FILE(sTemp)
|
|
SAVE_FLOAT_TO_DEBUG_FILE(fTempReturnHeading)
|
|
SAVE_NEWLINE_TO_DEBUG_FILE()
|
|
CLOSE_DEBUG_FILE()
|
|
bDebugPerformGenerateTaxiSpawnPos = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF bDebugPerformGetTaxiDriveToPlayerTest
|
|
iDesinationNodeSearchNumber = 0
|
|
IF GET_TAXI_PICK_UP_PLAYER_DESTINATION(vDebug_TempPickupPos, vDebug_DriveToNodePos, fDebug_DriveToNodeHeading, iDesinationNodeSearchNumber)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " bDebugPerformGetTaxiDriveToPlayerTest - return TRUE for vDebug_TempPickupPos : ", vDebug_TempPickupPos,
|
|
" vDebug_DriveToNodePos = ", vDebug_DriveToNodePos, " fDebug_DriveToNodeHeading = ", fDebug_DriveToNodeHeading)
|
|
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 bDebugPerformGetTaxiPullInSpotTest
|
|
vDebug_TaxiPos = vPlayerPos
|
|
IF GET_TAXI_PULL_OVER_INFO(vDebug_TaxiPos, vDebug_DriveToNodePos, fDebug_DriveToNodeHeading, vTempReturnCoords, fTempReturnHeading)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " bDebugPerformGetTaxiPullInSpotTest - return TRUE for vDebug_TaxiPos : ", vDebug_TaxiPos,
|
|
" vDebug_DriveToNodePos = ", vDebug_DriveToNodePos, " fDebug_DriveToNodeHeading = ", fDebug_DriveToNodeHeading,
|
|
" vTempReturnCoords = ", vTempReturnCoords, " fTempReturnHeading = ", fTempReturnHeading)
|
|
ENDIF
|
|
//DRAW_DEBUG_SPHERE(vDebug_TaxiPos, 0.25, 50, 0, 250, 200)
|
|
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*/
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// not sure - maybe custom area checks?
|
|
PROC DEBUG_SETUP_AREAS_WIDGETS()
|
|
vDebug_AreaBound1[0] = <<-1812.778320,-2764.928711,13.047204>>
|
|
vDebug_AreaBound2[0] = <<-800.595398,-3344.736816,16.444502>>
|
|
fDebug_DistBetween1n4[0] = 250.000000
|
|
SET_CURRENT_WIDGET_GROUP(widgetGroup)
|
|
CLEAR_CURRENT_WIDGET_GROUP(widgetGroup)
|
|
START_WIDGET_GROUP("Area Debug")
|
|
ADD_WIDGET_BOOL("Output areas to debug file", bDebug_OutputText)
|
|
ADD_WIDGET_INT_SLIDER("Which area", iDebug_CurrentArea, 0, 7, 1)
|
|
ADD_WIDGET_BOOL("Is this point 1", bDebug_Point1)
|
|
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound1[0].x", vDebug_AreaBound1[0].x, -4000, 4000, 0.001)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound1[0].y", vDebug_AreaBound1[0].y, -4000, 4000, 0.1)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound1[0].z", vDebug_AreaBound1[0].z, -10, 200, 0.1)
|
|
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound2[0].x", vDebug_AreaBound2[0].x, -4000, 4000, 0.001)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound2[0].y", vDebug_AreaBound2[0].y, -4000, 4000, 0.1)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound2[0].z", vDebug_AreaBound2[0].z, -10, 200, 0.1)
|
|
|
|
ADD_WIDGET_FLOAT_SLIDER("fDebug_DistBetween1n4[0]", fDebug_DistBetween1n4[0], 0, 1000, 0.1)
|
|
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound1[1].x", vDebug_AreaBound1[1].x, -4000, 4000, 0.001)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound1[1].y", vDebug_AreaBound1[1].y, -4000, 4000, 0.1)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound1[1].z", vDebug_AreaBound1[1].z, -10, 200, 0.1)
|
|
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound2[1].x", vDebug_AreaBound2[1].x, -4000, 4000, 0.001)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound2[1].y", vDebug_AreaBound2[1].y, -4000, 4000, 0.1)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound2[1].z", vDebug_AreaBound2[1].z, -10, 200, 0.1)
|
|
|
|
ADD_WIDGET_FLOAT_SLIDER("fDebug_DistBetween1n4[1]", fDebug_DistBetween1n4[1], 0, 1000, 0.1)
|
|
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound1[2].x", vDebug_AreaBound1[2].x, -4000, 4000, 0.001)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound1[2].y", vDebug_AreaBound1[2].y, -4000, 4000, 0.1)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound1[2].z", vDebug_AreaBound1[2].z, -10, 200, 0.1)
|
|
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound2[2].x", vDebug_AreaBound2[2].x, -4000, 4000, 0.001)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound2[2].y", vDebug_AreaBound2[2].y, -4000, 4000, 0.1)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound2[2].z", vDebug_AreaBound2[2].z, -10, 200, 0.1)
|
|
|
|
ADD_WIDGET_FLOAT_SLIDER("fDebug_DistBetween1n4[2]", fDebug_DistBetween1n4[2], 0, 1000, 0.1)
|
|
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound1[3].x", vDebug_AreaBound1[3].x, -4000, 4000, 0.001)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound1[3].y", vDebug_AreaBound1[3].y, -4000, 4000, 0.1)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound1[3].z", vDebug_AreaBound1[3].z, -10, 200, 0.1)
|
|
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound2[3].x", vDebug_AreaBound2[3].x, -4000, 4000, 0.001)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound2[3].y", vDebug_AreaBound2[3].y, -4000, 4000, 0.1)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound2[3].z", vDebug_AreaBound2[3].z, -10, 200, 0.1)
|
|
|
|
ADD_WIDGET_FLOAT_SLIDER("fDebug_DistBetween1n4[3]", fDebug_DistBetween1n4[3], 0, 1000, 0.1)
|
|
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound1[4].x", vDebug_AreaBound1[4].x, -4000, 4000, 0.001)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound1[4].y", vDebug_AreaBound1[4].y, -4000, 4000, 0.1)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound1[4].z", vDebug_AreaBound1[4].z, -10, 200, 0.1)
|
|
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound2[4].x", vDebug_AreaBound2[4].x, -4000, 4000, 0.001)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound2[4].y", vDebug_AreaBound2[4].y, -4000, 4000, 0.1)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound2[4].z", vDebug_AreaBound2[4].z, -10, 200, 0.1)
|
|
|
|
ADD_WIDGET_FLOAT_SLIDER("fDebug_DistBetween1n4[4]", fDebug_DistBetween1n4[4], 0, 1000, 0.1)
|
|
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound1[5].x", vDebug_AreaBound1[5].x, -4000, 4000, 0.001)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound1[5].y", vDebug_AreaBound1[5].y, -4000, 4000, 0.1)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound1[5].z", vDebug_AreaBound1[5].z, -10, 200, 0.1)
|
|
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound2[5].x", vDebug_AreaBound2[5].x, -4000, 4000, 0.001)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound2[5].y", vDebug_AreaBound2[5].y, -4000, 4000, 0.1)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound2[5].z", vDebug_AreaBound2[5].z, -10, 200, 0.1)
|
|
|
|
ADD_WIDGET_FLOAT_SLIDER("fDebug_DistBetween1n4[5]", fDebug_DistBetween1n4[5], 0, 1000, 0.1)
|
|
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound1[6].x", vDebug_AreaBound1[6].x, -4000, 4000, 0.001)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound1[6].y", vDebug_AreaBound1[6].y, -4000, 4000, 0.1)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound1[6].z", vDebug_AreaBound1[6].z, -10, 200, 0.1)
|
|
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound2[6].x", vDebug_AreaBound2[6].x, -4000, 4000, 0.001)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound2[6].y", vDebug_AreaBound2[6].y, -4000, 4000, 0.1)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound2[6].z", vDebug_AreaBound2[6].z, -10, 200, 0.1)
|
|
|
|
ADD_WIDGET_FLOAT_SLIDER("fDebug_DistBetween1n4[6]", fDebug_DistBetween1n4[6], 0, 1000, 0.1)
|
|
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound1[7].x", vDebug_AreaBound1[7].x, -4000, 4000, 0.001)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound1[7].y", vDebug_AreaBound1[7].y, -4000, 4000, 0.1)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound1[7].z", vDebug_AreaBound1[7].z, -10, 200, 0.1)
|
|
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound2[7].x", vDebug_AreaBound2[7].x, -4000, 4000, 0.001)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound2[7].y", vDebug_AreaBound2[7].y, -4000, 4000, 0.1)
|
|
ADD_WIDGET_FLOAT_SLIDER("vDebug_AreaBound2[7].z", vDebug_AreaBound2[7].z, -10, 200, 0.1)
|
|
|
|
ADD_WIDGET_FLOAT_SLIDER("fDebug_DistBetween1n4[7]", fDebug_DistBetween1n4[7], 0, 1000, 0.1)
|
|
STOP_WIDGET_GROUP()
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// not sure - maybe custom area checks?
|
|
PROC DEBUG_UPDATE_AREA_WIDGETS()
|
|
INT i
|
|
VECTOR vInput = <<0,0,0>>
|
|
REPEAT 8 i
|
|
|
|
IF VDIST(vDebug_AreaBound1[i], vDebug_AreaBound2[i]) > 0
|
|
DRAW_DEBUG_LINE(vDebug_AreaBound1[i], vDebug_AreaBound2[i])
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
IF IS_COORD_IN_SPECIFIED_AREA(vInput, AC_PRISON)
|
|
ENDIF
|
|
|
|
IF bDebug_Point1
|
|
vDebug_AreaBound1[iDebug_CurrentArea] = GET_SCRIPT_MOUSE_POINTER_IN_WORLD_COORDS()
|
|
ELSE
|
|
vDebug_AreaBound2[iDebug_CurrentArea] = GET_SCRIPT_MOUSE_POINTER_IN_WORLD_COORDS()
|
|
ENDIF
|
|
|
|
IF bDebug_OutputText
|
|
i=0
|
|
OPEN_DEBUG_FILE()
|
|
REPEAT 8 i
|
|
SAVE_NEWLINE_TO_DEBUG_FILE()
|
|
SAVE_STRING_TO_DEBUG_FILE("BOOL vDebug_AreaBound1[")
|
|
SAVE_INT_TO_DEBUG_FILE(i)
|
|
SAVE_STRING_TO_DEBUG_FILE("] = ")
|
|
SAVE_VECTOR_TO_DEBUG_FILE(vDebug_AreaBound1[i])
|
|
SAVE_NEWLINE_TO_DEBUG_FILE()
|
|
|
|
SAVE_NEWLINE_TO_DEBUG_FILE()
|
|
SAVE_STRING_TO_DEBUG_FILE("BOOL vDebug_AreaBound2[")
|
|
SAVE_INT_TO_DEBUG_FILE(i)
|
|
SAVE_STRING_TO_DEBUG_FILE("] = ")
|
|
SAVE_VECTOR_TO_DEBUG_FILE(vDebug_AreaBound2[i])
|
|
SAVE_NEWLINE_TO_DEBUG_FILE()
|
|
|
|
SAVE_NEWLINE_TO_DEBUG_FILE()
|
|
SAVE_STRING_TO_DEBUG_FILE("FLOAT fDebug_DistBetween1n4[")
|
|
SAVE_INT_TO_DEBUG_FILE(i)
|
|
SAVE_STRING_TO_DEBUG_FILE("] = ")
|
|
SAVE_FLOAT_TO_DEBUG_FILE(fDebug_DistBetween1n4[i])
|
|
SAVE_NEWLINE_TO_DEBUG_FILE()
|
|
ENDREPEAT
|
|
CLOSE_DEBUG_FILE()
|
|
|
|
bDebug_OutputText = FALSE
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// used to draw the taxi's pull over to pick up player info
|
|
/// PARAMS:
|
|
/// vParkCoords - place parking at
|
|
/// vOppositeSideCoords - position selected as side of the road
|
|
/// vNodeCoords - the node coords
|
|
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
|
|
#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:
|
|
/// blocks specific player controls relating to weapon equip swap, to be called during hail animations
|
|
/// Implemented for B*2074743 - block aiming during hail animation
|
|
PROC DISABLE_PLAYER_WEAPON_CONTROLS_FOR_HAIL_THIS_FRAME()
|
|
|
|
// B*2074743 - block aiming during hail animation
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_AIM)
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_SELECT_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_WEAPON_WHEEL_UD)
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_WEAPON_WHEEL_LR)
|
|
SET_PED_CONFIG_FLAG(PLAYER_PED_ID(), PCF_KeepWeaponHolsteredUnlessFired, TRUE)
|
|
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : DISABLE_PLAYER_WEAPON_CONTROLS_FOR_HAIL_THIS_FRAME : ", GET_FRAME_COUNT())
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// used to toggle the ped config flag PCF_AICanDrivePlayerAsRearPassenger of the taxi driver of the vehicleIndex
|
|
/// this is needed to allow the player to enter as passenger with input press. Input hold will jack the driver
|
|
/// PARAMS:
|
|
/// vehicleIndex - vehicle of driver to have flag updated
|
|
/// bSetActive - if flag is going to be set active or off
|
|
PROC SET_TAXI_DRIVER_ENTER_AS_PASSENGER_FLAG(VEHICLE_INDEX &vehicleIndex, BOOL bSetActive)
|
|
|
|
IF DOES_ENTITY_EXIST(vehicleIndex)
|
|
IF IS_VEHICLE_DRIVEABLE(vehicleIndex)
|
|
PED_INDEX pedIndex = GET_PED_IN_VEHICLE_SEAT(vehicleIndex)
|
|
IF DOES_ENTITY_EXIST(pedIndex)
|
|
IF IS_PED_MODEL(pedIndex, GET_TAXI_DRIVER_MODEL())
|
|
IF NOT IS_PED_INJURED(pedIndex)
|
|
// B*1536974 - Press to enter taxi as passenger hold to jack driver - opposite to how it worked on IV
|
|
// to get IV behaviour you have to ensur this flag is false then task the player in script to enter as rear passenger when input detected
|
|
SET_PED_CONFIG_FLAG(pedIndex, PCF_AICanDrivePlayerAsRearPassenger, bSetActive)
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SET_TAXI_DRIVER_ENTER_AS_PASSENGER_FLAG() - set : ", bSetActive) ENDIF #ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// get the vehicle seat player should be aiming for based on where they are and if the entry point is clear
|
|
/// RETURNS:
|
|
/// VEHICLE_SEAT to use in the TASK_ENTER_VEHICLE task along with direct entry
|
|
/// returns VS_ANY_PASSENGER if neither of the rear seats are ok to use
|
|
FUNC VEHICLE_SEAT GET_PLAYER_PREFERRED_REAR_PASSENGER_SEAT(VEHICLE_INDEX &vehIndexTaxi, VECTOR vTempPlayerPosition)
|
|
|
|
BOOL bUseLeftEntry = TRUE
|
|
VEHICLE_SEAT eTempSeat = VS_BACK_LEFT
|
|
PED_INDEX pedTempInSeat
|
|
|
|
IF (TAXI_GET_SIDE_COORDS_IS_TO_ENTITY(vehIndexTaxi, GET_ENTITY_COORDS(vehIndexTaxi, FALSE), vTempPlayerPosition) = 1)
|
|
bUseLeftEntry = FALSE
|
|
eTempSeat = VS_BACK_RIGHT
|
|
ENDIF
|
|
|
|
// attempt to enter the prefered side
|
|
IF IS_ENTRY_POINT_FOR_SEAT_CLEAR(PLAYER_PED_ID(), vehIndexTaxi, eTempSeat, TRUE, bUseLeftEntry)
|
|
IF IS_VEHICLE_SEAT_FREE(vehIndexTaxi, eTempSeat)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_PLAYER_PREFERRED_REAR_PASSENGER_SEAT : closest side seat empty selected : seat = ", eTempSeat)
|
|
RETURN eTempSeat
|
|
ELSE
|
|
pedTempInSeat = GET_PED_IN_VEHICLE_SEAT(vehIndexTaxi, eTempSeat)
|
|
IF DOES_ENTITY_EXIST(pedTempInSeat)
|
|
IF NOT (pedTempInSeat = PLAYER_PED_ID())
|
|
// don't jake group members
|
|
IF NOT IS_PED_GROUP_MEMBER(pedTempInSeat, PLAYER_GROUP_ID())
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_PLAYER_PREFERRED_REAR_PASSENGER_SEAT : closest side seat occupied selected : seat = ", eTempSeat)
|
|
RETURN eTempSeat
|
|
ELSE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_PLAYER_PREFERRED_REAR_PASSENGER_SEAT : closest side seat rejected for group member in seat selected : seat = ", eTempSeat)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// back up attempt to enter from opposite side
|
|
IF bUseLeftEntry
|
|
bUseLeftEntry = FALSE
|
|
eTempSeat = VS_BACK_RIGHT
|
|
ELSE
|
|
bUseLeftEntry = TRUE
|
|
eTempSeat = VS_BACK_LEFT
|
|
ENDIF
|
|
|
|
IF IS_ENTRY_POINT_FOR_SEAT_CLEAR(PLAYER_PED_ID(), vehIndexTaxi, eTempSeat, TRUE, bUseLeftEntry)
|
|
IF IS_VEHICLE_SEAT_FREE(vehIndexTaxi, eTempSeat)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_PLAYER_PREFERRED_REAR_PASSENGER_SEAT : far side seat empty selected : seat = ", eTempSeat)
|
|
RETURN eTempSeat
|
|
ELSE
|
|
pedTempInSeat = GET_PED_IN_VEHICLE_SEAT(vehIndexTaxi, eTempSeat)
|
|
IF DOES_ENTITY_EXIST(pedTempInSeat)
|
|
IF NOT (pedTempInSeat = PLAYER_PED_ID())
|
|
// don't jake group members
|
|
IF NOT IS_PED_GROUP_MEMBER(pedTempInSeat, PLAYER_GROUP_ID())
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_PLAYER_PREFERRED_REAR_PASSENGER_SEAT : far side seat occupied selected : seat = ", eTempSeat)
|
|
RETURN eTempSeat
|
|
ELSE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_PLAYER_PREFERRED_REAR_PASSENGER_SEAT : far side seat rejected for group member in seat selected : seat = ", eTempSeat)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN VS_ANY_PASSENGER
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// create the waiting taxi blip for g_WaitingTaxi
|
|
PROC CREATE_WAITING_TAXI_BLIP()
|
|
|
|
IF DOES_BLIP_EXIST(blipWaitingTaxi)
|
|
SET_BLIP_ROUTE(blipWaitingTaxi, FALSE)
|
|
REMOVE_BLIP(blipWaitingTaxi)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : CREATE_WAITING_TAXI_BLIP() : blip already existed removed")
|
|
ENDIF
|
|
IF IS_VEHICLE_OK(g_WaitingTaxi)
|
|
IF NOT DOES_BLIP_EXIST(blipWaitingTaxi)
|
|
blipWaitingTaxi = ADD_BLIP_FOR_ENTITY(g_WaitingTaxi)
|
|
SET_BLIP_SPRITE(blipWaitingTaxi, RADAR_TRACE_TAXI)
|
|
SET_BLIP_NAME_FROM_TEXT_FILE(blipWaitingTaxi, "TXM_BLIP")
|
|
SET_BLIP_FLASHES(blipWaitingTaxi, TRUE)
|
|
SET_BLIP_FLASH_TIMER(blipWaitingTaxi, 10000)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : CREATE_WAITING_TAXI_BLIP() : blip added to g_WaitingTaxi")
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// returns the search flags used for getting closest taxi
|
|
/// RETURNS:
|
|
/// INT bit set value
|
|
FUNC INT GET_TAXI_SEARCH_FLAGS()
|
|
|
|
RETURN (VEHICLE_SEARCH_FLAG_RETURN_MISSION_VEHICLES |
|
|
VEHICLE_SEARCH_FLAG_RETURN_RANDOM_VEHICLES |
|
|
VEHICLE_SEARCH_FLAG_RETURN_VEHICLES_CONTAINING_GROUP_MEMBERS |
|
|
VEHICLE_SEARCH_FLAG_RETURN_VEHICLES_WITH_PEDS_ENTERING_OR_EXITING |
|
|
VEHICLE_SEARCH_FLAG_ALLOW_VEHICLE_OCCUPANTS_TO_BE_PERFORMING_A_SCRIPTED_TASK)
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Cleanup the process enter closest taxi
|
|
PROC CLEANUP_ENTER_CLOSEST_TAXI()
|
|
|
|
IF eEnterTaxiState = TL_ENTER_TAXI_STATE_ENTERING
|
|
SET_PLAYER_CAN_DO_DRIVE_BY(PLAYER_ID(), TRUE)
|
|
CANCEL_GROUP_GETTING_INTO_CAB()
|
|
ELIF eEnterTaxiState = TL_ENTER_TAXI_STATE_INSIDE
|
|
IF HAS_SCRIPT_LOADED("taxiService")
|
|
SET_SCRIPT_AS_NO_LONGER_NEEDED("taxiService")
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : CLEANUP_ENTER_CLOSEST_TAXI eEnterTaxiState was TL_ENTER_TAXI_STATE_ENTERING - ET_SCRIPT_AS_NO_LONGER_NEEDED(taxiService)") ENDIF #ENDIF
|
|
ENDIF
|
|
SET_PLAYER_CAN_DO_DRIVE_BY(PLAYER_ID(), TRUE)
|
|
CANCEL_GROUP_GETTING_INTO_CAB()
|
|
ENDIF
|
|
|
|
CLEANUP_WAITING_TAXI() // handles release of g_WaitingTaxi and g_WaitingTaxiDriver
|
|
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " CLEANUP_ENTER_CLOSEST_TAXI() : called CLEANUP_WAITING_TAXI()")
|
|
|
|
IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("TX_H02") // Hold ~INPUT_ENTER~ to enter the cab as a passenger.
|
|
CLEAR_HELP(TRUE)
|
|
ENDIF
|
|
iTimer_DelayTaxiSearch = 0 //reset
|
|
eEnterTaxiState = TL_ENTER_TAXI_STATE_IDLE
|
|
//#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : CLEANUP_ENTER_CLOSEST_TAXI() : eEnterTaxiState = TL_ENTER_TAXI_STATE_IDLE") ENDIF #ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Cleanup the process hail taxi
|
|
PROC CLEANUP_HAIL_TAXI()
|
|
|
|
// stop scripted player anims
|
|
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
|
|
IF IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), tlTaxiAnimDict, "HAIL_TAXI")
|
|
STOP_ENTITY_ANIM(PLAYER_PED_ID(), "HAIL_TAXI", tlTaxiAnimDict, REALLY_SLOW_BLEND_OUT)
|
|
ELIF IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), tlTaxiAnimDict, "FP_HAIL_TAXI")
|
|
STOP_ENTITY_ANIM(PLAYER_PED_ID(), "FP_HAIL_TAXI", tlTaxiAnimDict, REALLY_SLOW_BLEND_OUT)
|
|
ELIF IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), tlTaxiAnimDict, "FUCK_U")
|
|
STOP_ENTITY_ANIM(PLAYER_PED_ID(), "FUCK_U", tlTaxiAnimDict, REALLY_SLOW_BLEND_OUT)
|
|
ELIF IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), tlTaxiAnimDict, "FORGET_IT")
|
|
STOP_ENTITY_ANIM(PLAYER_PED_ID(), "FORGET_IT", tlTaxiAnimDict, REALLY_SLOW_BLEND_OUT)
|
|
ENDIF
|
|
// B*1515351 - SET_PED_CONFIG_FLAG needs alive check
|
|
IF iTaxiHailIntention != NEW_CONTEXT_INTENTION
|
|
SET_PED_CONFIG_FLAG(PLAYER_PED_ID(), PCF_KeepWeaponHolsteredUnlessFired, FALSE)
|
|
ENDIF
|
|
// B*1991223 - RESET need to block ambient anims during hail anims
|
|
IF bBlockingPlayerAmbientIdles = TRUE
|
|
SET_PED_CAN_PLAY_AMBIENT_ANIMS(PLAYER_PED_ID(), TRUE)
|
|
bBlockingPlayerAmbientIdles = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
REMOVE_ANIM_DICT(tlTaxiAnimDict)
|
|
IF iTaxiHailIntention != NEW_CONTEXT_INTENTION
|
|
RELEASE_CONTEXT_INTENTION(iTaxiHailIntention)
|
|
ENDIF
|
|
IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("TXM_H01") // Press ~INPUT_CONTEXT~ to hail a Taxi.
|
|
iHailPromptCounter++
|
|
IF iHailPromptCounter = 3
|
|
g_savedGlobals.sAmbient.bTaxiHailingHelpDisplayed = TRUE
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " CLEANUP_HAIL_TAXI() : g_savedGlobals.sAmbient.bTaxiHailingHelpDisplayed = TRUE") ENDIF #ENDIF
|
|
ENDIF
|
|
CLEAR_HELP(TRUE)
|
|
ENDIF
|
|
IF DOES_BLIP_EXIST(blipWaitingTaxi)
|
|
SET_BLIP_ROUTE(blipWaitingTaxi, FALSE)
|
|
REMOVE_BLIP(blipWaitingTaxi)
|
|
ENDIF
|
|
IF bHintTriggeredByTaxiLauncher
|
|
IF IS_GAMEPLAY_HINT_ACTIVE()
|
|
STOP_GAMEPLAY_HINT()
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// stop his aknowledge anims
|
|
IF DOES_ENTITY_EXIST(g_WaitingTaxiDriver)
|
|
IF NOT IS_PED_INJURED(g_WaitingTaxiDriver)
|
|
IF IS_ENTITY_PLAYING_ANIM(g_WaitingTaxiDriver, tlTaxiAnimDict, "Aknowledge_R")
|
|
STOP_ENTITY_ANIM(g_WaitingTaxiDriver, "Aknowledge_R", tlTaxiAnimDict, SLOW_BLEND_OUT)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " CLEANUP_HAIL_TAXI() : stopped driver aknowledge anim Aknowledge_R")
|
|
ELIF IS_ENTITY_PLAYING_ANIM(g_WaitingTaxiDriver, tlTaxiAnimDict, "Aknowledge_L")
|
|
STOP_ENTITY_ANIM(g_WaitingTaxiDriver, "Aknowledge_L", tlTaxiAnimDict, SLOW_BLEND_OUT)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " CLEANUP_HAIL_TAXI() : stopped driver aknowledge anim Aknowledge_L")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// don't stomp on the global handle g_WaitingTaxi (if player is entering a taxi)
|
|
IF eEnterTaxiState = TL_ENTER_TAXI_STATE_IDLE
|
|
CLEANUP_WAITING_TAXI() // handles release of g_WaitingTaxi and g_WaitingTaxiDriver
|
|
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " CLEANUP_HAIL_TAXI() : called CLEANUP_WAITING_TAXI()")
|
|
ENDIF
|
|
|
|
vehHailTarget = NULL
|
|
bPlayAdditionalFuckYouDialogue = FALSE
|
|
bHintTriggeredByTaxiLauncher = FALSE
|
|
iTimer_HailAnimTriggered = 0
|
|
iTimer_HailFailedDialogueDelay = 0
|
|
g_iTaxiHailedTime = -1
|
|
eHailTaxiState = TL_HAIL_TAXI_STATE_IDLE
|
|
//#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : CLEANUP_HAIL_TAXI() : eHailTaxiState = TL_HAIL_TAXI_STATE_IDLE") ENDIF #ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// clear all the dispatched taxi data struct
|
|
PROC CLEANUP_DISPATCHED_TAXI_DATA()
|
|
|
|
// set driver's behaviour and release
|
|
IF DOES_ENTITY_EXIST(sDispatchedTaxi.pedIndex)
|
|
IF DOES_ENTITY_BELONG_TO_THIS_SCRIPT(sDispatchedTaxi.pedIndex, FALSE)
|
|
// don't stomp on the global handle
|
|
IF sDispatchedTaxi.pedIndex != g_WaitingTaxiDriver
|
|
IF NOT IS_PED_INJURED(sDispatchedTaxi.pedIndex)
|
|
|
|
// RESET FLAG for cleanup B*1536974 - Press to enter taxi as passenger hold to jack driver - opposite to how it worked on IV
|
|
// to get IV behaviour you have to ensur this flag is false then task the player in script to enter as rear passenger when input detected
|
|
SET_PED_CONFIG_FLAG(sDispatchedTaxi.pedIndex, PCF_AICanDrivePlayerAsRearPassenger, FALSE)
|
|
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(sDispatchedTaxi.pedIndex, FALSE)
|
|
|
|
IF NOT IS_PED_FLEEING(sDispatchedTaxi.pedIndex)
|
|
AND NOT IS_PED_IN_COMBAT(sDispatchedTaxi.pedIndex)
|
|
IF IS_PED_IN_ANY_VEHICLE(sDispatchedTaxi.pedIndex)
|
|
IF DOES_ENTITY_EXIST(sDispatchedTaxi.vehicleIndex)
|
|
IF IS_VEHICLE_DRIVEABLE(sDispatchedTaxi.vehicleIndex)
|
|
IF IS_PED_SITTING_IN_VEHICLE(sDispatchedTaxi.pedIndex, sDispatchedTaxi.vehicleIndex)
|
|
SEQUENCE_INDEX seq
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
// if any of the players buddies are in the taxi then wait for then to get out
|
|
IF NOT IS_VEHICLE_SEAT_FREE(sDispatchedTaxi.vehicleIndex, VS_BACK_LEFT)
|
|
OR NOT IS_VEHICLE_SEAT_FREE(sDispatchedTaxi.vehicleIndex, VS_BACK_RIGHT)
|
|
OR NOT IS_VEHICLE_SEAT_FREE(sDispatchedTaxi.vehicleIndex, VS_FRONT_RIGHT)
|
|
TASK_PAUSE(NULL, 2000)
|
|
ELSE
|
|
TASK_PAUSE(NULL, 500)
|
|
ENDIF
|
|
TASK_VEHICLE_DRIVE_WANDER(NULL, sDispatchedTaxi.vehicleIndex, 12.0, DRIVINGMODE_STOPFORCARS | DF_AvoidRestrictedAreas)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(sDispatchedTaxi.pedIndex, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " CLEANUP_DISPATCHED_TAXI_DATA() : tasked sDispatchedTaxi.pedIndex to TASK_VEHICLE_DRIVE_WANDER")
|
|
ELSE
|
|
TASK_SMART_FLEE_PED(sDispatchedTaxi.pedIndex, PLAYER_PED_ID(), 500, -1)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " CLEANUP_DISPATCHED_TAXI_DATA() : tasked sDispatchedTaxi.pedIndex driver to flee as not sat in sDispatchedTaxi.vehicleIndex")
|
|
ENDIF
|
|
ELSE
|
|
TASK_SMART_FLEE_PED(sDispatchedTaxi.pedIndex, PLAYER_PED_ID(), 500, -1)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " CLEANUP_DISPATCHED_TAXI_DATA() : tasked sDispatchedTaxi.pedIndex driver to flee as sDispatchedTaxi.vehicleIndex was not driverable")
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
// just walk off not fleeing but on foot
|
|
TASK_WANDER_STANDARD(sDispatchedTaxi.pedIndex)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " CLEANUP_DISPATCHED_TAXI_DATA() : tasked sDispatchedTaxi.pedIndex to TASK_WANDER_STANDARD on foot")
|
|
ENDIF
|
|
ELSE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " CLEANUP_DISPATCHED_TAXI_DATA() : NOT tasked sDispatchedTaxi.pedIndex since IS_PED_FLEEING / combat returned TRUE")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// release assets
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(GET_ENTITY_MODEL(sDispatchedTaxi.pedIndex))
|
|
SET_PED_AS_NO_LONGER_NEEDED(sDispatchedTaxi.pedIndex)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " CLEANUP_DISPATCHED_TAXI_DATA : set sDispatchedTaxi.pedIndex model and vehicle as no longer needed")
|
|
ELSE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " CLEANUP_DISPATCHED_TAXI_DATA : sDispatchedTaxi.pedIndex = g_WaitingTaxiDriver so not released entity and model")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// release vehicle handle
|
|
IF DOES_ENTITY_EXIST(sDispatchedTaxi.vehicleIndex)
|
|
IF DOES_ENTITY_BELONG_TO_THIS_SCRIPT(sDispatchedTaxi.vehicleIndex, FALSE)
|
|
// don't stomp on the global handle
|
|
IF sDispatchedTaxi.vehicleIndex != g_WaitingTaxi
|
|
//SET_MODEL_AS_NO_LONGER_NEEDED(ENTITY_MODEL(sDispatchedTaxi.vehicleIndex))
|
|
SET_VEHICLE_AS_NO_LONGER_NEEDED(sDispatchedTaxi.vehicleIndex)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " CLEANUP_DISPATCHED_TAXI_DATA : set sDispatchedTaxi.vehicleIndex as no longer needed")
|
|
ELSE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " CLEANUP_DISPATCHED_TAXI_DATA : sDispatchedTaxi.vehicleIndex = g_WaitingTaxi so not released entity and model")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// release asset requests
|
|
IF eDispatchedTaxiState = TL_DISPATCHED_STATE_CREATE_TAXI
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(mnTaxiModel)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(mnTaxiDriverModel)
|
|
ENDIF
|
|
|
|
// reset struct vars
|
|
sDispatchedTaxi.vehicleIndex = NULL
|
|
sDispatchedTaxi.pedIndex = NULL
|
|
sDispatchedTaxi.bHasActiveTask = FALSE
|
|
sDispatchedTaxi.bForcedPullOverAtCurrentPosition = FALSE
|
|
sDispatchedTaxi.fDistToTarget = 0
|
|
sDispatchedTaxi.fDriveToHeading = 0
|
|
sDispatchedTaxi.fTargetReached = 45.0
|
|
sDispatchedTaxi.iNodeSearchNumber = 0
|
|
sDispatchedTaxi.iSpawnAttempts = 0
|
|
sDispatchedTaxi.iTimer_TaxiDispatchDelay = 0
|
|
sDispatchedTaxi.vDistToPlayer = << 0.0, 0.0, 0.0 >>
|
|
sDispatchedTaxi.vDriveToCoords = << 0.0, 0.0, 0.0 >>
|
|
sDispatchedTaxi.vPullOverCoords = << 0.0, 0.0, 0.0 >>
|
|
sDispatchedTaxi.vPlayerCalledCoords = << 0.0, 0.0, 0.0 >>
|
|
sDispatchedTaxi.vPathNodeRequestMin = << 0.0, 0.0, 0.0 >>
|
|
sDispatchedTaxi.vPathNodeRequestMax = << 0.0, 0.0, 0.0 >>
|
|
sDispatchedTaxi.taxiDrivingModeStandard = DF_SteerAroundStationaryCars|DF_StopForPeds|DF_StopAtLights|DF_ChangeLanesAroundObstructions|DF_StopForCars|DF_ForceJoinInRoadDirection|DF_SteerAroundObjects|DF_UseSwitchedOffNodes|DF_AvoidRestrictedAreas
|
|
sDispatchedTaxi.eCharDispatchedFor = GLOBAL_CHARACTER_SHEET_GET_MAX_CHARACTERS_FOR_GAMEMODE()
|
|
// reset state machine
|
|
eDispatchedTaxiState = TL_DISPATCHED_STATE_IDLE
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// resets the taxi launcher and sets eTaxiLauncherState = TL_STATE_IDLE
|
|
|
|
/// PURPOSE:
|
|
/// reset everything in the script
|
|
/// PARAMS:
|
|
/// bResetLauncherState - if TRUE eTaxiLauncherState will get reset to TL_STATE_IDLE
|
|
PROC RESET_TAXI_LAUNCHER(BOOL bResetLauncherState = TRUE)
|
|
|
|
SET_VEHICLE_MODEL_IS_SUPPRESSED(TAXI, FALSE)
|
|
CLEANUP_DISPATCHED_TAXI_DATA()
|
|
CLEANUP_ENTER_CLOSEST_TAXI()
|
|
CLEANUP_HAIL_TAXI()
|
|
|
|
// expect there will be other variables i'll need to reset here as and when i find them
|
|
bUpdateHailTargetThisFrame = TRUE
|
|
bHintTriggeredByTaxiLauncher = FALSE
|
|
eCallTaxiServiceState = TL_PHONE_STATE_AWAITING_CALL
|
|
eDispatchedTaxiState = TL_DISPATCHED_STATE_IDLE
|
|
eHailTaxiState = TL_HAIL_TAXI_STATE_IDLE
|
|
eEnterTaxiState = TL_ENTER_TAXI_STATE_IDLE
|
|
iTimer_DelayTaxiSearch = 0
|
|
IF bResetLauncherState
|
|
eTaxiLauncherState = TL_STATE_IDLE
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// cleanup for the script
|
|
PROC TAXI_LAUNCHER_SCRIPT_CLEANUP()
|
|
|
|
CLEANUP_WAITING_TAXI() // handles release of g_WaitingTaxi and g_WaitingTaxiDriver
|
|
RESET_TAXI_LAUNCHER()
|
|
REMOVE_ANIM_DICT(tlTaxiAnimDict)
|
|
SET_VEHICLE_MODEL_IS_SUPPRESSED(TAXI, FALSE)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(mnTaxiModel)
|
|
SET_MODEL_AS_NO_LONGER_NEEDED(mnTaxiDriverModel)
|
|
IF bHintTriggeredByTaxiLauncher
|
|
IF IS_GAMEPLAY_HINT_ACTIVE()
|
|
STOP_GAMEPLAY_HINT()
|
|
ENDIF
|
|
ENDIF
|
|
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " TAXI_LAUNCHER_SCRIPT_CLEANUP() : done")
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// queries if g_CustomDropOffBlip exists
|
|
PROC MONITOR_CUSTOM_DROP_OFF_BLIP()
|
|
IF g_fTaxiDropOffHeading <> 0
|
|
IF DOES_BLIP_EXIST(g_CustomDropOffBlip)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : MONITOR_CUSTOM_DROP_OFF_BLIP() g_CustomDropOffBlip exists")
|
|
ELSE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : MONITOR_CUSTOM_DROP_OFF_BLIP() set g_CustomDropOffBlip doesn't exists")
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// sets dialogue info for the current player ped
|
|
PROC IDENTIFY_PLAYER()
|
|
|
|
enumCharacterList eCurrentPlayerChar = GET_CURRENT_PLAYER_PED_ENUM()
|
|
|
|
IF eCurrentPlayerChar = CHAR_MICHAEL
|
|
playerVoice = "MICHAEL"
|
|
playerLine1 = "TX_1M"
|
|
playerLine3 = "TX_3M"
|
|
ELIF eCurrentPlayerChar = CHAR_FRANKLIN
|
|
playerVoice = "FRANKLIN"
|
|
playerLine1 = "TX_1F"
|
|
playerLine3 = "TX_3F"
|
|
ELIF eCurrentPlayerChar = CHAR_TREVOR
|
|
playerVoice = "TREVOR"
|
|
playerLine1 = "TX_1T"
|
|
playerLine3 = "TX_3T"
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// checks for the player being allowed to enter a taxi as a passenger
|
|
/// RETURNS:
|
|
/// TRUE if player is allowed to enter as a passenger
|
|
FUNC BOOL IS_PLAYER_ALLOWED_TO_ENTER_TAXI_AS_PASSENGER()
|
|
|
|
// check global flags for being allowed taxi rides
|
|
IF NOT IS_PLAYER_ALLOWED_TO_RIDE_IN_TAXIS()
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayCleanupTTY CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_PLAYER_ALLOWED_TO_ENTER_TAXI_AS_PASSENGER() - return FALSE - IS_PLAYER_ALLOWED_TO_RIDE_IN_TAXIS") ENDIF #ENDIF
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
/* already gets tested in
|
|
// check player isn't injured
|
|
IF IS_PED_INJURED(PLAYER_PED_ID())
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayCleanupTTY CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_PLAYER_ALLOWED_TO_ENTER_TAXI_AS_PASSENGER() - return FALSE - IS_PED_INJURED(PLAYER_PED_ID())") ENDIF #ENDIF
|
|
RETURN FALSE
|
|
ENDIF */
|
|
|
|
// check the player has control
|
|
IF NOT IS_PLAYER_PLAYING(PLAYER_ID())
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayCleanupTTY CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_PLAYER_ALLOWED_TO_ENTER_TAXI_AS_PASSENGER() - return FALSE - IS_PLAYER_PLAYING(PLAYER_ID())") ENDIF #ENDIF
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
// check for player being wanted
|
|
IF IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0)
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayCleanupTTY CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_PLAYER_ALLOWED_TO_ENTER_TAXI_AS_PASSENGER() - return FALSE - IS_PLAYER_WANTED_LEVEL_GREATER(PLAYER_ID(), 0)") ENDIF #ENDIF
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// checks for the player being allowed to hail a taxi
|
|
/// RETURNS:
|
|
/// TRUE if player is allowed to hail a taxi
|
|
FUNC BOOL IS_PLAYER_ALLOWED_TO_HAIL_A_TAXI()
|
|
|
|
// don't allow player to hail a whilst getting in one
|
|
IF eEnterTaxiState != TL_ENTER_TAXI_STATE_IDLE
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayCleanupTTY CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_PLAYER_ALLOWED_TO_HAIL_A_TAXI() - return FALSE - eEnterTaxiState != TL_ENTER_TAXI_STATE_IDLE") ENDIF #ENDIF
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
// don't allow hail if player has an ambient task
|
|
// apparently checks climbing, on ladders, current task is idle, combat, jumping, shooting
|
|
IF NOT IS_PLAYER_FREE_FOR_AMBIENT_TASK(PLAYER_ID())
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayCleanupTTY CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_PLAYER_ALLOWED_TO_HAIL_A_TAXI() - return FALSE - IS_PLAYER_FREE_FOR_AMBIENT_TASK(PLAYER_ID())") ENDIF #ENDIF
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
// aim a weapon
|
|
IF IS_PLAYER_FREE_AIMING(PLAYER_ID())
|
|
OR IS_PLAYER_TARGETTING_ANYTHING(PLAYER_ID())
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayCleanupTTY CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_PLAYER_ALLOWED_TO_HAIL_A_TAXI() - return FALSE - IS_PLAYER_FREE_AIMING(PLAYER_ID())") ENDIF #ENDIF
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
// in the air
|
|
IF IS_ENTITY_IN_AIR(PLAYER_PED_ID())
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayCleanupTTY CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_PLAYER_ALLOWED_TO_HAIL_A_TAXI() - return FALSE - IS_ENTITY_IN_AIR(PLAYER_PED_ID())") ENDIF #ENDIF
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
// falling over (exclude drunk for some reason?)
|
|
IF NOT g_playerIsDrunk
|
|
AND IS_PED_RAGDOLL(PLAYER_PED_ID())
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayCleanupTTY CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_PLAYER_ALLOWED_TO_HAIL_A_TAXI() - return FALSE - IS_PED_RAGDOLL(PLAYER_PED_ID())") ENDIF #ENDIF
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
// already inside a vehicle
|
|
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID(), TRUE)
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayCleanupTTY CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_PLAYER_ALLOWED_TO_HAIL_A_TAXI() - return FALSE - IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID(), TRUE)") ENDIF #ENDIF
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
// don't allow hail whilst phone is on screen
|
|
IF IS_PHONE_ONSCREEN()
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayCleanupTTY CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_PLAYER_ALLOWED_TO_HAIL_A_TAXI() - return FALSE - IS_PHONE_ONSCREEN()") ENDIF #ENDIF
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
// is internet on screen
|
|
IF IS_BROWSER_OPEN()
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayCleanupTTY CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_PLAYER_ALLOWED_TO_HAIL_A_TAXI() - return FALSE -IS_BROWSER_OPEN()") ENDIF #ENDIF
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
// if player is shopping
|
|
IF IS_PLAYER_BROWSING_ITEMS_IN_ANY_SHOP()
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayCleanupTTY CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_PLAYER_ALLOWED_TO_HAIL_A_TAXI() - return FALSE - IS_PLAYER_BROWSING_ITEMS_IN_ANY_SHOP()") ENDIF #ENDIF
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
// custom menu active
|
|
IF IS_CUSTOM_MENU_ON_SCREEN()
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayCleanupTTY CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_PLAYER_ALLOWED_TO_HAIL_A_TAXI() - return FALSE - IS_CUSTOM_MENU_ON_SCREEN()") ENDIF #ENDIF
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
// don't allow taxis during minigames
|
|
IF IS_MINIGAME_IN_PROGRESS()
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayCleanupTTY CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_PLAYER_ALLOWED_TO_HAIL_A_TAXI() - return FALSE - IS_MINIGAME_IN_PROGRESS()") ENDIF #ENDIF
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// checks for the player being allowed to call a taxi
|
|
/// RETURNS:
|
|
/// TRUE if player is allowed a taxi
|
|
FUNC BOOL IS_PLAYER_ALLOWED_TO_CALL_TAXI()
|
|
|
|
// check if a dispatched taxi is already on route to the player
|
|
IF eDispatchedTaxiState != TL_DISPATCHED_STATE_IDLE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_PLAYER_ALLOWED_TO_CALL_TAXI() - return FALSE - eDispatchedTaxiState check")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
// don't allow a taxi to be dispatched if player has a hailed taxi waiting
|
|
IF eHailTaxiState = TL_HAIL_TAXI_STATE_TAXI_WAITING
|
|
OR eHailTaxiState = TL_HAIL_TAXI_STATE_SUCCESSFUL_ATTEMPT
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_PLAYER_ALLOWED_TO_CALL_TAXI() - return FALSE - eHailTaxiState check")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
// check if a enter taxi state is idle (player isn't currently getting in a taxi)
|
|
IF eEnterTaxiState != TL_ENTER_TAXI_STATE_IDLE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_PLAYER_ALLOWED_TO_CALL_TAXI() - return FALSE - eEnterTaxiState check")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
// check the player isn't currently in a taxi journey
|
|
IF IS_THREAD_ACTIVE(tTaxiServiceThread)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_PLAYER_ALLOWED_TO_CALL_TAXI() - return FALSE - IS_THREAD_ACTIVE(tTaxiServiceThread)")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
// check the player isn't already in a taxi
|
|
IF NOT IS_PLAYER_ALLOWED_TO_ENTER_TAXI_AS_PASSENGER()
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_PLAYER_ALLOWED_TO_CALL_TAXI() - return FALSE - IS_PLAYER_ALLOWED_TO_ENTER_TAXI_AS_PASSENGER")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
// test for player being in the air (presumably to prevent calls during flights
|
|
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
|
|
IF IS_ENTITY_IN_AIR(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()))
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_PLAYER_ALLOWED_TO_CALL_TAXI() - return FALSE - IS_ENTITY_IN_AIR whilst in VEHICLE")
|
|
RETURN FALSE
|
|
ENDIF
|
|
ENDIF
|
|
IS_PLAYER_IN_ANY_COMMUNICATION_RESTRICTED_AREAS()
|
|
// ideally perform GET_TAXI_PICK_UP_PLAYER_DESTINATION now and store the pickup position ready
|
|
// that way if it was unable to get a position the tdispatch service could decline the call
|
|
|
|
// check player is close to the road network
|
|
VECTOR vNode
|
|
FLOAT fDistMinFromNode = 50.0
|
|
|
|
// 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(vPlayerPos)
|
|
nodeFlags = NF_INCLUDE_SWITCHED_OFF_NODES | NF_IGNORE_SWITCHED_OFF_DEADENDS
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_PLAYER_ALLOWED_TO_CALL_TAXI() : using node flags NF_INCLUDE_SWITCHED_OFF_NODES | NF_IGNORE_SWITCHED_OFF_DEADENDS")
|
|
ENDIF
|
|
|
|
IF NOT GET_CLOSEST_VEHICLE_NODE(vPlayerPos, vNode, nodeFlags, 100.0, 2.5)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_PLAYER_ALLOWED_TO_CALL_TAXI() : return FALSE - failed to find closest valid node nearby :", vPlayerPos)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF NOT IS_ENTITY_AT_COORD(PLAYER_PED_ID(), vNode, <<fDistMinFromNode, fDistMinFromNode, 20.0>>)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_PLAYER_ALLOWED_TO_CALL_TAXI() : return FALSE - player more than ", fDistMinFromNode, " away from closest valid node")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
/*VEHICLE_NODE_ID tempVehNodeID = GET_NTH_CLOSEST_VEHICLE_NODE_ID(vNode, 1, nodeFlags)
|
|
IF IS_VEHICLE_NODE_ID_VALID(tempVehNodeID)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_PLAYER_ALLOWED_TO_CALL_TAXI() : return FALSE - no valid node nearby")
|
|
RETURN FALSE
|
|
ENDIF*/
|
|
|
|
// make sure he's not calling from an inaccessible area
|
|
IF IS_POSITION_IN_TAXI_RESTRICTED_AREA(vPlayerPos, TRUE)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_PLAYER_ALLOWED_TO_CALL_TAXI() : return FALSE - IS_POSITION_IN_TAXI_RESTRICTED_AREA check")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : IS_PLAYER_ALLOWED_TO_CALL_TAXI() - return TRUE")
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// check if the taxi service is listed for the player to call
|
|
/// PARAMS:
|
|
/// ePlayer - the player to check, passing GLOBAL_CHARACTER_SHEET_GET_MAX_CHARACTERS_FOR_GAMEMODE() will test all players and return TRUE if one of them have the taxi listed
|
|
/// RETURNS:
|
|
/// TRUE if specified char has taxi listed (if GLOBAL_CHARACTER_SHEET_GET_MAX_CHARACTERS_FOR_GAMEMODE() parameter return TRUE if any of them have listed)
|
|
FUNC BOOL IS_TAXI_SERVICE_LISTED_IN_PLAYERS_PHONEBOOK(enumCharacterList ePlayer = MAX_CHARACTERS)
|
|
|
|
IF ePlayer = CHAR_MICHAEL
|
|
OR ePlayer = CHAR_FRANKLIN
|
|
OR ePlayer = CHAR_TREVOR
|
|
IF (GLOBAL_CHARACTER_SHEET_GET_PHONEBOOK_STATE(CHAR_TAXI, ENUM_TO_INT(ePlayer))= LISTED)
|
|
RETURN TRUE
|
|
ENDIF
|
|
ELIF ePlayer = GLOBAL_CHARACTER_SHEET_GET_MAX_CHARACTERS_FOR_GAMEMODE()
|
|
IF (GLOBAL_CHARACTER_SHEET_GET_PHONEBOOK_STATE(CHAR_TAXI, ENUM_TO_INT(CHAR_MICHAEL)) = LISTED
|
|
OR GLOBAL_CHARACTER_SHEET_GET_PHONEBOOK_STATE(CHAR_TAXI, ENUM_TO_INT(CHAR_FRANKLIN)) = LISTED
|
|
OR GLOBAL_CHARACTER_SHEET_GET_PHONEBOOK_STATE(CHAR_TAXI, ENUM_TO_INT(CHAR_TREVOR)) = LISTED)
|
|
RETURN TRUE
|
|
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
|
|
FUNC FLOAT GET_DIST_BETWEEN_VECTORS_NONE_Z(VECTOR vDestinationCoord, VECTOR vPullOverCoord)
|
|
VECTOR vDiff_Destination_To_ReturnNode
|
|
vDiff_Destination_To_ReturnNode = vDestinationCoord - vPullOverCoord
|
|
vDiff_Destination_To_ReturnNode.z = 0.0
|
|
RETURN VMAG(vDiff_Destination_To_ReturnNode)
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// generate a positin and heading which will lead the taxi along the path nodes to the player's position
|
|
/// shouldn't need to load the path nodes prior to the checks on this one, since the spawn dist should easliy be with in 400m loaded around player
|
|
/// PARAMS:
|
|
/// vSpawnPos - the positio to set value returned by reference
|
|
/// fSpawnHeading - the heading value to be returned by reference
|
|
/// iReturnedNodeNumber - return the node number of the last test, used to setup repeat checks
|
|
/// nodeFlags - default to NF_INCLUDE_SWITCHED_OFF_NODES
|
|
/// fMinSpawnRadius - min dist for spawn point from player
|
|
/// RETURNS:
|
|
/// TRUE if position and heading were successfully generated
|
|
FUNC BOOL GENERATE_TAXI_SPAWN_POS_AND_HEADING_TO_PLAYER(VECTOR &vSpawnPos, FLOAT &fSpawnHeading, INT &iReturnedNodeNumber, NODE_FLAGS nodeFlags = NF_INCLUDE_SWITCHED_OFF_NODES, FLOAT fMinSpawnRadius = 25.0)
|
|
|
|
VECTOR vClosestNodeToPlayer, vGeneratedSpawnPos, vResultLinkDir
|
|
FLOAT fGeneratedHeading = 0.0
|
|
INT iNumLanes
|
|
BOOL bIncludeSwitchedOffNodes = TRUE
|
|
IF nodeFlags = NF_NONE
|
|
bIncludeSwitchedOffNodes = FALSE
|
|
ENDIF
|
|
BOOL bGeneratedPositionFound = FALSE
|
|
INT iLoopCounter = 0
|
|
FLOAT fZ_MeasureMulti = 100.0 // increased as per B*1183689
|
|
FLOAT fZ_Tolerance = 2.5 // B*1430520
|
|
VECTOR vPosHeadingTest, vOffset1, vOffset2
|
|
TAXI_SPECIAL_AREAS_ENUM eSpecialAreaCheck
|
|
|
|
/*#IF IS_DEBUG_BUILD
|
|
VECTOR vSpawnPosWithFavDirection
|
|
FLOAT fSpawnHeadingWithFavDirection
|
|
#ENDIF*/
|
|
|
|
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
|
|
VECTOR vPlayerCoords = GET_ENTITY_COORDS(PLAYER_PED_ID())
|
|
|
|
// first check we don't need to force a special spawn position and heading for the taxi if the player is in a special area
|
|
eSpecialAreaCheck = GET_TAXI_SPECIAL_AREA_AT_COORDS(vPlayerCoords)
|
|
|
|
IF eSpecialAreaCheck != TAXI_SPECIAL_AREAS_INVALID
|
|
IF GET_TAXI_SPAWN_INFO_FOR_TAXI_SPECIAL_AREA(vPlayerCoords, eSpecialAreaCheck, vSpawnPos, fSpawnHeading)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " GENERATE_TAXI_SPAWN_POS_AND_HEADING_TO_PLAYER special area setup eSpecialAreaCheck = ", eSpecialAreaCheck,
|
|
" : vSpawnPos = ", vSpawnPos, " : fSpawnHeading = ", fSpawnHeading, " - return TRUE")
|
|
RETURN TRUE
|
|
ELSE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " GENERATE_TAXI_SPAWN_POS_AND_HEADING_TO_PLAYER - GET_TAXI_SPAWN_INFO_FOR_TAXI_SPECIAL_AREA - return FALSE")
|
|
ENDIF
|
|
ELSE
|
|
// first get the closest node to the player's position (using high zMulti) to work from (this should stop spawn issues where different z height nodes are around)
|
|
// without it causes bug 1183689 - player is closest to road node above than on the road he's stood on
|
|
// so GENERATE_VEHICLE_CREATION_POS_FROM_PATHS returns pos on the roof
|
|
IF GET_NTH_CLOSEST_VEHICLE_NODE_WITH_HEADING(vPlayerCoords, iReturnedNodeNumber, vClosestNodeToPlayer, fGeneratedHeading, iNumLanes, nodeFlags, fZ_MeasureMulti, fZ_Tolerance)
|
|
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " GENERATE_TAXI_SPAWN_POS_AND_HEADING_TO_PLAYER - gen closest node to player result : vPlayer = ", vPlayerCoords,
|
|
" : result vClosestNodeToPlayer = ", vClosestNodeToPlayer, " : node in = ", iReturnedNodeNumber, " : out heading = ", fGeneratedHeading, " : inumlanes = ", iNumLanes)
|
|
|
|
// 5 chances to get a valid node otherwise bail out
|
|
WHILE (NOT bGeneratedPositionFound AND (iLoopCounter < 5))
|
|
|
|
IF GENERATE_VEHICLE_CREATION_POS_FROM_PATHS(vClosestNodeToPlayer, vGeneratedSpawnPos, vResultLinkDir, 0, 180, fMinSpawnRadius, bIncludeSwitchedOffNodes, TRUE, FALSE)
|
|
|
|
fGeneratedHeading = TAXI_GET_HEADING_FROM_COORDS(<< 0.0, 0.0, 0.0 >>, vResultLinkDir) // not working reliably so verting back to old setup for now -
|
|
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " GENERATE_TAXI_SPAWN_POS_AND_HEADING_TO_PLAYER - gen veh creation pos : search pos (vClosestNodeToPlayer) = ", vClosestNodeToPlayer, " : result pos (vGeneratedSpawnPos) = ", vGeneratedSpawnPos,
|
|
" : result link direction = ", vResultLinkDir, " fGeneratedHeading = ", fGeneratedHeading)
|
|
|
|
// check the generated spawn point isn't within a special area
|
|
// if so the function will update the spawn pos to use a suitable position
|
|
//eSpecialAreaCheck = GET_TAXI_SPECIAL_AREA_AT_COORDS(vPlayerCoords)
|
|
|
|
//IF ARE_COORDS_IN_SPECIAL_AREA(vGeneratedSpawnPos, vGeneratedSpawnPos, fGeneratedHeading)
|
|
// CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " generate creation pos was inside a special area - updated vGeneratedSpawnPos = ", vGeneratedSpawnPos, " updated fGeneratedHeading = ", fGeneratedHeading)
|
|
//ENDIF
|
|
|
|
// check the generated position is safe
|
|
IF IS_SPAWN_POSITION_SAFE_FOR_TAXI(vPlayerCoords, vGeneratedSpawnPos)
|
|
|
|
bGeneratedPositionFound = TRUE
|
|
|
|
vPosHeadingTest = GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(vGeneratedSpawnPos, fGeneratedHeading, <<0.0, 1.0, 0.0>>)
|
|
// Vehicle Vector
|
|
vOffset1 = vPosHeadingTest - vGeneratedSpawnPos
|
|
// Vector to Player
|
|
vOffset2 = vClosestNodeToPlayer - vGeneratedSpawnPos
|
|
|
|
IF (GET_ANGLE_BETWEEN_2D_VECTORS(vOffset1.x, vOffset1.y, vOffset2.x, vOffset2.y) > 60.0)
|
|
fGeneratedHeading += 180
|
|
fGeneratedHeading = WRAP(fGeneratedHeading, 0, 360)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "GENERATE_TAXI_SPAWN_POS_AND_HEADING_TO_PLAYER - revised fGeneratedHeading = ", fGeneratedHeading)
|
|
ENDIF
|
|
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " GENERATE_TAXI_SPAWN_POS_AND_HEADING_TO_PLAYER - update fGeneratedHeading = ", fGeneratedHeading, " vResultLinkDir.Z = ", vResultLinkDir.Z,
|
|
" : heading from 2d vector = ", GET_HEADING_FROM_VECTOR_2D(vResultLinkDir.X, vResultLinkDir.Y), " : result link direction = ", vResultLinkDir, " ")
|
|
|
|
// check the generated spawn point isn't within a special area
|
|
//IF ARE_COORDS_IN_SPECIAL_AREA(vGeneratedSpawnPos, vGeneratedSpawnPos, fGeneratedHeading)
|
|
// CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " GENERATE_TAXI_SPAWN_POS_AND_HEADING_TO_PLAYER - ARE_COORDS_IN_SPECIAL_AREA return TRUE so values updated : vGeneratedSpawnPos = ", vGeneratedSpawnPos, " : fGeneratedHeading = ", fGeneratedHeading)
|
|
//ENDIF
|
|
|
|
/*#IF IS_DEBUG_BUILD
|
|
IF GET_NTH_CLOSEST_VEHICLE_NODE_FAVOUR_DIRECTION(vGeneratedSpawnPos, vClosestNodeToPlayer, 0, vSpawnPosWithFavDirection, fSpawnHeadingWithFavDirection, nodeFlags, 1)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " GENERATE_TAXI_SPAWN_POS_AND_HEADING_TO_PLAYER - node fav direction would give : ",
|
|
" fSpawnHeadingWithFavDirection = ", fSpawnHeadingWithFavDirection, " vSpawnPosWithFavDirection = ", vSpawnPosWithFavDirection)
|
|
ENDIF
|
|
#ENDIF*/
|
|
|
|
vSpawnPos = vGeneratedSpawnPos
|
|
fSpawnHeading = fGeneratedHeading
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " GENERATE_TAXI_SPAWN_POS_AND_HEADING_TO_PLAYER - vSpawnPos = ", vSpawnPos, " : fSpawnHeading = ", fSpawnHeading, " - return TRUE")
|
|
RETURN TRUE
|
|
ELSE
|
|
iLoopCounter++
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GENERATE_TAXI_SPAWN_POS_AND_HEADING_TO_PLAYER : IS_SPAWN_POSITION_SAFE_FOR_TAXI return FALSE vGeneratedSpawnPos :", vGeneratedSpawnPos, " iLoopCounter = ", iLoopCounter)
|
|
ENDIF
|
|
ELSE
|
|
iLoopCounter++
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " GENERATE_TAXI_SPAWN_POS_AND_HEADING_TO_PLAYER - * GENERATE_VEHICLE_CREATION_POS_FROM_PATHS - returned FALSE bIncludeSwitchedOffNodes = ", bIncludeSwitchedOffNodes, " iLoopCounter = ", iLoopCounter)
|
|
ENDIF
|
|
ENDWHILE
|
|
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " GENERATE_TAXI_SPAWN_POS_AND_HEADING_TO_PLAYER - return FALSE : failed to generate spawn pos from node pos = ", vClosestNodeToPlayer, " iNodeNumber = ", iReturnedNodeNumber)
|
|
iReturnedNodeNumber++ // increment for retry next frame
|
|
ELSE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " GENERATE_TAXI_SPAWN_POS_AND_HEADING_TO_PLAYER - GET_NTH_CLOSEST_VEHICLE_NODE_WITH_HEADING to player - return FALSE : iNodeNumber = ", iReturnedNodeNumber)
|
|
iReturnedNodeNumber++ // increment for retry next frame
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " GENERATE_TAXI_SPAWN_POS_AND_HEADING_TO_PLAYER - player injured - return FALSE")
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// get a valid node position for the taxi to drive to - handles requesting the path nodes at the position to find a valid node
|
|
/// PARAMS:
|
|
/// vDestinationCoord - location we want to reach
|
|
/// vReturnNodeCoord - the returned coords for the VEHICLE_NODE_ID
|
|
/// fReturnHeading - the returned node heading
|
|
/// iReturnedNodeNumber - return the node number of the last test, used to setup repeat checks
|
|
/// iExtraLoadPathDist - dist around vDestinationCoord to load the path nodes in for the search
|
|
/// RETURNS:
|
|
/// TRUE if a valid VEHICLE_NODE_ID was found
|
|
FUNC BOOL GET_TAXI_PICK_UP_PLAYER_DESTINATION(VECTOR vDestinationCoord, VECTOR &vReturnNodeCoord, FLOAT &fReturnHeading, INT &iReturnedNodeNumber, INT iExtraLoadPathDist = 250)
|
|
|
|
FLOAT zMeasureMult = 3
|
|
FLOAT fZ_Tolerance = 2.5 // B*1430520
|
|
FLOAT fTempZDiff
|
|
|
|
ENTITY_INDEX entityPointObsuredCheck = NULL
|
|
INT iNoOfLanes
|
|
VEHICLE_NODE_ID tempVehNodeID
|
|
INT iMaxNodeLoopChecksPerFrame = iReturnedNodeNumber + 2 // limit checks per frame
|
|
INT iMaxNodeLoopChecksInTotal = 50 // don't search past this amount
|
|
BOOL bFoundSuitableNode = 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(vDestinationCoord)
|
|
nodeFlags = NF_INCLUDE_SWITCHED_OFF_NODES | NF_IGNORE_SWITCHED_OFF_DEADENDS
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PICK_UP_PLAYER_DESTINATION() : using node flags NF_INCLUDE_SWITCHED_OFF_NODES | NF_IGNORE_SWITCHED_OFF_DEADENDS")
|
|
ENDIF
|
|
|
|
REQUEST_PATH_NODES_IN_AREA_FOR_TAXI_THIS_FRAME(vDestinationCoord, vDestinationCoord, sDispatchedTaxi.vPathNodeRequestMin, sDispatchedTaxi.vPathNodeRequestMax, iExtraLoadPathDist)
|
|
IF ARE_REQUEST_PATH_NODES_LOADED_FOR_TAXI(sDispatchedTaxi.vPathNodeRequestMin, sDispatchedTaxi.vPathNodeRequestMax)
|
|
|
|
IF NOT ARE_COORDS_IN_SPECIAL_AREA(vDestinationCoord, vReturnNodeCoord, fReturnHeading)
|
|
// get closest point that is on a road.
|
|
|
|
// 3 chances to get a valid node otherwise bail out this frame
|
|
WHILE (NOT bFoundSuitableNode AND (iReturnedNodeNumber < iMaxNodeLoopChecksPerFrame))
|
|
|
|
IF vDestinationCoord.z = 1
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PICK_UP_PLAYER_DESTINATION() : zMeasureMult = 0 ")
|
|
zMeasureMult = 0
|
|
ENDIF
|
|
|
|
IF GET_NTH_CLOSEST_VEHICLE_NODE_WITH_HEADING(vDestinationCoord, iReturnedNodeNumber, vReturnNodeCoord, fReturnHeading, iNoOfLanes, nodeFlags, zMeasureMult, fZ_Tolerance)
|
|
|
|
// get the VEHICLE_NODE_ID for returned node positin
|
|
tempVehNodeID = GET_NTH_CLOSEST_VEHICLE_NODE_ID(vReturnNodeCoord, 1, nodeFlags)
|
|
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PICK_UP_PLAYER_DESTINATION() : vDestinationCoord = ", vDestinationCoord, " iReturnedNodeNumber = ", iReturnedNodeNumber,
|
|
" vReturnNodeCoord = ", vReturnNodeCoord, " iNoOfLanes = ", iNoOfLanes)
|
|
|
|
IF IS_VEHICLE_NODE_ID_VALID(tempVehNodeID)
|
|
|
|
// Bug fix B*1245895 - check was returning FALSE for coords with same/similar Z value
|
|
fTempZDiff = vDestinationCoord.z - vReturnNodeCoord.z
|
|
IF fTempZDiff < 0.0
|
|
fTempZDiff *= -1.0
|
|
ENDIF
|
|
|
|
IF IS_COORD_ON_SAME_LEVEL_AS_COORD(vDestinationCoord, vReturnNodeCoord)
|
|
OR (fTempZDiff < 0.5) // Bug fix B*1245895 - check was returning FALSE for coords with same/similar Z value
|
|
|
|
IF IS_VEHICLE_DRIVEABLE(sDispatchedTaxi.vehicleIndex)
|
|
entityPointObsuredCheck = sDispatchedTaxi.vehicleIndex
|
|
ENDIF
|
|
|
|
//check the position isn't obsured
|
|
IF NOT IS_POINT_OBSCURED_BY_A_MISSION_ENTITY(vReturnNodeCoord, <<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_PICK_UP_PLAYER_DESTINATION() : 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_PICK_UP_PLAYER_DESTINATION() : node is switched off")
|
|
ENDIF
|
|
#ENDIF
|
|
bFoundSuitableNode = TRUE
|
|
ELSE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PICK_UP_PLAYER_DESTINATION() : IS_POINT_OBSCURED_BY_A_MISSION_ENTITY() return TRUE, bFoundSuitableNode = FALSE")
|
|
ENDIF
|
|
ELSE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PICK_UP_PLAYER_DESTINATION() : IS_COORD_ON_SAME_LEVEL_AS_COORD return FALSE")
|
|
ENDIF
|
|
ELSE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PICK_UP_PLAYER_DESTINATION() : IS_VEHICLE_NODE_ID_VALID return FALSE")
|
|
ENDIF
|
|
ELSE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PICK_UP_PLAYER_DESTINATION() : GET_NTH_CLOSEST_VEHICLE_NODE_WITH_HEADING return FALSE")
|
|
ENDIF
|
|
|
|
iReturnedNodeNumber++
|
|
// fail safe, don't test past iMaxNodeLoopChecksInTotal
|
|
IF (iReturnedNodeNumber >= iMaxNodeLoopChecksInTotal) // don't search past this amount)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PICK_UP_PLAYER_DESTINATION() : iReturnedNodeNumber = ", iReturnedNodeNumber, " reached max check amount, bFoundSuitableNode = TRUE, FC = ", GET_FRAME_COUNT())
|
|
bFoundSuitableNode = TRUE
|
|
ENDIF
|
|
// 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_PICK_UP_PLAYER_DESTINATION() : iReturnedNodeNumber = ", iReturnedNodeNumber, " reached max loop check amount this frame FC = ", GET_FRAME_COUNT())
|
|
ENDIF
|
|
#ENDIF
|
|
ENDWHILE
|
|
ELSE
|
|
// destination in special area
|
|
bFoundSuitableNode = TRUE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PICK_UP_PLAYER_DESTINATION() : ARE_COORDS_IN_SPECIAL_AREA returned TRUE, vDestinationCoord = ", vDestinationCoord, " vReturnNodeCoord = ", vReturnNodeCoord,
|
|
" fReturnHeading = ", fReturnHeading)
|
|
ENDIF
|
|
|
|
IF bFoundSuitableNode
|
|
sDispatchedTaxi.fDistToTarget = GET_DIST_BETWEEN_VECTORS_NONE_Z(vDestinationCoord, vReturnNodeCoord)
|
|
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PICK_UP_PLAYER_DESTINATION() : returning TRUE for vReturnNodeCoord = ", vReturnNodeCoord,
|
|
" fReturnHeading = ", fReturnHeading, " sDispatchedTaxi.fDistToTarget = ", sDispatchedTaxi.fDistToTarget)
|
|
RETURN TRUE
|
|
ELSE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PICK_UP_PLAYER_DESTINATION() : returning FALSE")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// handles taxi driving to the player / or pickup position and detecting when he's close enough to pull over
|
|
/// RETURNS:
|
|
/// TRUE if he's reached the pickup player location
|
|
FUNC BOOL HAS_DISPATCHED_TAXI_ARRIVED_TO_PICKUP_PLAYER()
|
|
|
|
VECTOR vTaxiPos
|
|
|
|
IF NOT sDispatchedTaxi.bHasActiveTask
|
|
IF GET_TAXI_PICK_UP_PLAYER_DESTINATION(sDispatchedTaxi.vPlayerCalledCoords, sDispatchedTaxi.vDriveToCoords, sDispatchedTaxi.fDriveToHeading, sDispatchedTaxi.iNodeSearchNumber)
|
|
TASK_VEHICLE_DRIVE_TO_COORD(sDispatchedTaxi.pedIndex, sDispatchedTaxi.vehicleIndex, sDispatchedTaxi.vDriveToCoords, 12.0, DRIVINGSTYLE_NORMAL, GET_ENTITY_MODEL(sDispatchedTaxi.vehicleIndex), sDispatchedTaxi.taxiDrivingModeStandard, (sDispatchedTaxi.fTargetReached - 20), 20)
|
|
//TASK_VEHICLE_MISSION_COORS_TARGET(sDispatchedTaxi.pedIndex, sDispatchedTaxi.vehicleIndex, sDispatchedTaxi.vDriveToCoords, MISSION_GOTO, 12.0, taxiDrivingModeStandard, (sDispatchedTaxi.fTargetReached - 20), 20, FALSE)
|
|
// B*1329777 - JMart request Can we just use the regular Goto and not Longrange when tasking the taxi to go to the player's position
|
|
//TASK_VEHICLE_DRIVE_TO_COORD_LONGRANGE(sDispatchedTaxi.pedIndex, sDispatchedTaxi.vehicleIndex, sDispatchedTaxi.vDriveToCoords, 12.0, taxiDrivingModeStandard, sDispatchedTaxi.fTargetReached)
|
|
sDispatchedTaxi.bHasActiveTask = TRUE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : HAS_DISPATCHED_TAXI_ARRIVED_TO_PICKUP_PLAYER() : vehicle task drive coord, sDispatchedTaxi.vDriveToCoords = ", sDispatchedTaxi.vDriveToCoords, " sDispatchedTaxi.fDriveToHeading = ", sDispatchedTaxi.fDriveToHeading)
|
|
ENDIF
|
|
ELSE
|
|
vTaxiPos = GET_ENTITY_COORDS(sDispatchedTaxi.vehicleIndex)
|
|
|
|
// check to see when the taxi gets with in range
|
|
IF TAXI_IS_COORD_IN_RANGE_OF_COORD(vTaxiPos, sDispatchedTaxi.vDriveToCoords, sDispatchedTaxi.fTargetReached)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : HAS_DISPATCHED_TAXI_ARRIVED_TO_PICKUP_PLAYER() return TRUE - reached sDispatchedTaxi.vDriveToCoords : ", sDispatchedTaxi.vDriveToCoords)
|
|
RETURN TRUE
|
|
ELIF TAXI_IS_COORD_IN_RANGE_OF_COORD(vTaxiPos, vPlayerPos, 5.0)
|
|
sDispatchedTaxi.vDriveToCoords = vPlayerPos
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : HAS_DISPATCHED_TAXI_ARRIVED_TO_PICKUP_PLAYER() return TRUE - reached vPlayerPos : ", vPlayerPos, " so updated sDispatchedTaxi.vDriveToCoords to match")
|
|
RETURN TRUE
|
|
ELSE
|
|
// reapply the drive to task if it failed for some reason
|
|
IF NOT TAXI_IS_PED_PERFORMING_TASK(sDispatchedTaxi.pedIndex, SCRIPT_TASK_VEHICLE_DRIVE_TO_COORD)
|
|
// B*1329777 - JMart request Can we just use the regular Goto and not Longrange when tasking the taxi to go to the player's position?
|
|
//IF NOT TAXI_IS_PED_PERFORMING_TASK(sDispatchedTaxi.pedIndex, SCRIPT_TASK_VEHICLE_DRIVE_TO_COORD_LONGRANGE)
|
|
sDispatchedTaxi.bHasActiveTask = FALSE // commented out for now since performing task return false when it shouldn't see B*
|
|
sDispatchedTaxi.iNodeSearchNumber = 0 // reset ready for retest
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : HAS_DISPATCHED_TAXI_ARRIVED_TO_PICKUP_PLAYER() : vehicle task drive coord, failed so set to reapply")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Tests Z distance between 2 vectors
|
|
/// PARAMS:
|
|
/// vector1 - pull over position
|
|
/// vector2 - road node
|
|
/// RETURNS:
|
|
/// TRUE if Z difference is greater than 0.45 meters, otherwise FALSE
|
|
FUNC BOOL TEST_VECTOR_Z_DIFFERENCE(VECTOR vector1, VECTOR vector2)
|
|
IF(vector1.z - vector2.z > 0.45) OR (vector1.z - vector2.z < -0.45)
|
|
RETURN TRUE
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
/// PURPOSE:
|
|
/// Z checks taxi pull over position, Finds a valid position for the taxi to stop at, that passes the Z check.
|
|
/// PARAMS:
|
|
/// vReturnPullOverPosition - the taxi needing to pull over position
|
|
/// vNodePosition - closest road node
|
|
/// RETURNS:
|
|
/// TRUE if Z check failed and another postion had to be found. FALSE, if Z check passed
|
|
FUNC BOOL DO_PARK_Z_CHECK(VECTOR &vReturnPullOverPosition, VECTOR vNodePosition)
|
|
FLOAT zCoord
|
|
IF NOT GET_GROUND_Z_FOR_3D_COORD(<<vReturnPullOverPosition.x,vReturnPullOverPosition.y,1000>>,zCoord)
|
|
vReturnPullOverPosition = vNodePosition
|
|
RETURN FALSE
|
|
ENDIF
|
|
VECTOR tempVec = << vReturnPullOverPosition.x, vReturnPullOverPosition.y, zCoord >>
|
|
IF TEST_VECTOR_Z_DIFFERENCE(tempVec,vNodePosition)
|
|
VECTOR vDirection = (vNodePosition-tempVec)/5.0
|
|
INT i
|
|
FOR i = 1 TO 5
|
|
tempVec = tempVec + vDirection
|
|
IF NOT TEST_VECTOR_Z_DIFFERENCE(tempVec,vNodePosition)
|
|
vReturnPullOverPosition = tempVec
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDFOR
|
|
vReturnPullOverPosition = vNodePosition
|
|
RETURN TRUE
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// get a valid position and heading for the taxi to pull over based from passed in node coords
|
|
/// PARAMS:
|
|
/// vTaxiCoords - the taxi needing to pull over position
|
|
/// vDestinationNodeCoords - the destination node's position
|
|
/// fDestinationNodeHeading - the destination node's heading
|
|
/// vRetunPullOverPosition - the position the taxi should park
|
|
/// fReturnPullOverHeading - the desired heading the taxi should use to park
|
|
/// RETURNS:
|
|
/// TRUE if a valid positon was found
|
|
FUNC BOOL GET_TAXI_PULL_OVER_INFO(VECTOR vTaxiCoords, VECTOR vDestinationNodeCoords, FLOAT fDestinationNodeHeading, VECTOR &vReturnPullOverPosition, FLOAT &fReturnPullOverHeading)
|
|
|
|
VECTOR vNodePosition
|
|
VECTOR vRoadSideForwards
|
|
VECTOR vRoadSideBackwards
|
|
VEHICLE_NODE_ID tempVehNodeID
|
|
// 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(vDestinationNodeCoords)
|
|
nodeFlags = NF_INCLUDE_SWITCHED_OFF_NODES | NF_IGNORE_SWITCHED_OFF_DEADENDS
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PULL_OVER_INFO() : using node flags NF_INCLUDE_SWITCHED_OFF_NODES | NF_IGNORE_SWITCHED_OFF_DEADENDS")
|
|
ENDIF
|
|
|
|
// get the VEHICLE_NODE_ID for node position
|
|
tempVehNodeID = GET_NTH_CLOSEST_VEHICLE_NODE_ID(vDestinationNodeCoords, 1, nodeFlags)
|
|
|
|
// check there is a valid vehicle node at the destination
|
|
IF IS_VEHICLE_NODE_ID_VALID(tempVehNodeID)
|
|
|
|
GET_VEHICLE_NODE_POSITION(tempVehNodeID, vNodePosition)
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF NOT ARE_VECTORS_ALMOST_EQUAL(vNodePosition, vDestinationNodeCoords, 0.5)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PULL_OVER_INFO() : passed in node coords didn't match the cloest node position :
|
|
vDestinationNodeCoords = ", vDestinationNodeCoords, " vNodePosition = ", vNodePosition)
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
// try to find a position on both sides of the road
|
|
IF GET_POSITION_BY_SIDE_OF_ROAD(vNodePosition, 0, vRoadSideForwards) // iDirection - should be a direction (0=forwards, 1=back, -1=doesn't matter)
|
|
AND GET_POSITION_BY_SIDE_OF_ROAD(vNodePosition, 1, vRoadSideBackwards) // iDirection - should be a direction (0=forwards, 1=back, -1=doesn't matter)
|
|
|
|
VECTOR v1, v2, v3
|
|
|
|
v1 = vRoadSideForwards - vNodePosition
|
|
|
|
v2 = << -v1.y, v1.x, 0.0 >>
|
|
|
|
v3 = vTaxiCoords - vDestinationNodeCoords
|
|
|
|
FLOAT fDotProduct = DOT_PRODUCT(v2, v3)
|
|
|
|
IF fDotProduct < 0.0
|
|
vReturnPullOverPosition = vRoadSideForwards
|
|
fReturnPullOverHeading = fDestinationNodeHeading
|
|
|
|
//z check - B* 1869986
|
|
IF DO_PARK_Z_CHECK(vReturnPullOverPosition,vNodePosition)
|
|
sDispatchedTaxi.bFailedZCheck = TRUE
|
|
ENDIF
|
|
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PULL_OVER_INFO() : return TRUE cloest side found (forwards)",
|
|
" vReturnPullOverPosition : ", vReturnPullOverPosition, " fReturnPullOverHeading = ", fReturnPullOverHeading)
|
|
#IF IS_DEBUG_BUILD DEBUG_DRAW_TAXI_PULL_OVER_INFO(vReturnPullOverPosition, vRoadSideBackwards, vNodePosition) #ENDIF
|
|
ELSE
|
|
vReturnPullOverPosition = vRoadSideBackwards
|
|
fReturnPullOverHeading += 180
|
|
fReturnPullOverHeading = WRAP(fReturnPullOverHeading, 0, 360)
|
|
|
|
//z check - B* 1869986
|
|
IF DO_PARK_Z_CHECK(vReturnPullOverPosition,vNodePosition)
|
|
sDispatchedTaxi.bFailedZCheck = TRUE
|
|
ENDIF
|
|
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PULL_OVER_INFO() : return TRUE cloest side found (backwards)",
|
|
" vReturnPullOverPosition : ", vReturnPullOverPosition, " fReturnPullOverHeading = ", fReturnPullOverHeading)
|
|
#IF IS_DEBUG_BUILD DEBUG_DRAW_TAXI_PULL_OVER_INFO(vReturnPullOverPosition, vRoadSideForwards, vNodePosition) #ENDIF
|
|
ENDIF
|
|
|
|
RETURN TRUE
|
|
|
|
// try to find any valid position at the side of the road
|
|
ELIF GET_POSITION_BY_SIDE_OF_ROAD(vNodePosition, -1, vRoadSideForwards) // iDirection - should be a direction (0=forwards, 1=back, -1=doesn't matter)
|
|
|
|
vReturnPullOverPosition = vRoadSideForwards
|
|
fReturnPullOverHeading = fDestinationNodeHeading
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PULL_OVER_INFO() : return TRUE just the one position found vReturnPullOverPosition : ", vReturnPullOverPosition)
|
|
RETURN TRUE
|
|
|
|
// unable to find a valid position at the side of the road
|
|
ELSE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PULL_OVER_INFO() : return FALSE unable to find a valid position by the side of the road vDestinationNodeCoords : ", vDestinationNodeCoords)
|
|
ENDIF
|
|
ELSE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : GET_TAXI_PULL_OVER_INFO() : return FALSE IS_VEHICLE_NODE_ID_VALID vDestinationNodeCoords : ", vDestinationNodeCoords)
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// handles the taxi pulling over to pickup the player
|
|
/// RETURNS:
|
|
/// TRUE if taxi has pulled over successfully
|
|
FUNC BOOL HAS_DISPATCHED_TAXI_PULLED_OVER_TO_PICKUP_PLAYER()
|
|
|
|
VECTOR vTaxiPos
|
|
|
|
vTaxiPos = GET_ENTITY_COORDS(sDispatchedTaxi.vehicleIndex, FALSE)
|
|
|
|
IF NOT sDispatchedTaxi.bHasActiveTask
|
|
|
|
// if player has got close to taxi before it's reached it's pull up position allow the task to be reapplied using current position
|
|
IF NOT sDispatchedTaxi.bForcedPullOverAtCurrentPosition
|
|
IF GET_TAXI_PULL_OVER_INFO(vTaxiPos, sDispatchedTaxi.vDriveToCoords, sDispatchedTaxi.fDriveToHeading, sDispatchedTaxi.vPullOverCoords, sDispatchedTaxi.fDriveToHeading)
|
|
|
|
IF NOT IS_ENTITY_DEAD(sDispatchedTaxi.pedIndex)
|
|
SET_DRIVER_ABILITY(sDispatchedTaxi.pedIndex, 0.5)
|
|
|
|
//z check - B* 1869986
|
|
IF sDispatchedTaxi.bFailedZCheck
|
|
TASK_VEHICLE_DRIVE_TO_COORD(sDispatchedTaxi.pedIndex, sDispatchedTaxi.vehicleIndex, sDispatchedTaxi.vPullOverCoords, 10, DRIVINGSTYLE_NORMAL, GET_ENTITY_MODEL(sDispatchedTaxi.vehicleIndex), sDispatchedTaxi.taxiDrivingModeStandard, 5, GET_DISTANCE_BETWEEN_COORDS(vTaxiPos,sDispatchedTaxi.vPullOverCoords))
|
|
sDispatchedTaxi.bFailedZCheck = FALSE
|
|
ELSE
|
|
// info: apparently TASK_VEHICLE_PARK should work from as far 50m away also as the path nodes are loaded. Needs to kick in earlier than later.
|
|
// can take up to 10 metres to stop, so best to pass in a position offset from the actual spot you want to stop
|
|
//TASK_VEHICLE_PARK(sDispatchedTaxi.pedIndex, sDispatchedTaxi.vehicleIndex, sDispatchedTaxi.vPullOverCoords, sDispatchedTaxi.fDriveToHeading, PARK_TYPE_PULL_OVER, 90, TRUE)
|
|
TASK_VEHICLE_PARK(sDispatchedTaxi.pedIndex, sDispatchedTaxi.vehicleIndex, sDispatchedTaxi.vPullOverCoords, sDispatchedTaxi.fDriveToHeading, PARK_TYPE_PULL_OVER, 90, TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
sDispatchedTaxi.bHasActiveTask = TRUE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : HAS_DISPATCHED_TAXI_PULLED_OVER_TO_PICKUP_PLAYER() applied park task ",
|
|
" sDispatchedTaxi.vPullOverCoords : ", sDispatchedTaxi.vPullOverCoords, " sDispatchedTaxi.fDriveToHeading = ", sDispatchedTaxi.fDriveToHeading)
|
|
ENDIF
|
|
ELSE
|
|
SET_DRIVER_ABILITY(sDispatchedTaxi.pedIndex, 0.5)
|
|
sDispatchedTaxi.vPullOverCoords = vTaxiPos
|
|
|
|
TASK_VEHICLE_TEMP_ACTION(sDispatchedTaxi.pedIndex, sDispatchedTaxi.vehicleIndex, TEMPACT_HANDBRAKESTRAIGHT, 15000)
|
|
sDispatchedTaxi.bHasActiveTask = TRUE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : HAS_DISPATCHED_TAXI_PULLED_OVER_TO_PICKUP_PLAYER() applied TEMPACT_HANDBRAKESTRAIGHT task ",
|
|
" sDispatchedTaxi.vPullOverCoords : ", sDispatchedTaxi.vPullOverCoords)
|
|
|
|
// info: apparently TASK_VEHICLE_PARK should work from as far 50m away also as the path nodes are loaded. Needs to kick in earlier than later.
|
|
// can take up to 10 metres to stop, so best to pass in a position offset from the actual spot you want to stop
|
|
//TASK_VEHICLE_PARK(sDispatchedTaxi.pedIndex, sDispatchedTaxi.vehicleIndex, sDispatchedTaxi.vPullOverCoords, sDispatchedTaxi.fDriveToHeading, PARK_TYPE_PULL_OVER, 90, TRUE)
|
|
//bTaxiDriverHasActiveTask = TRUE
|
|
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : HAS_DISPATCHED_TAXI_PULLED_OVER_TO_PICKUP_PLAYER() applied park task ",
|
|
// " sDispatchedTaxi.vPullOverCoords : ", sDispatchedTaxi.vPullOverCoords, " sDispatchedTaxi.fDriveToHeading = ", sDispatchedTaxi.fDriveToHeading)
|
|
ENDIF
|
|
ELSE
|
|
IF NOT TAXI_IS_PED_PERFORMING_TASK(sDispatchedTaxi.pedIndex, SCRIPT_TASK_VEHICLE_PARK)
|
|
IF IS_VEHICLE_STOPPED(sDispatchedTaxi.vehicleIndex)
|
|
//AND TAXI_IS_COORD_IN_RANGE_OF_COORD(vTaxiPos, sDispatchedTaxi.vPullOverCoords, 15.0) // seems they can pull over far away
|
|
TASK_VEHICLE_TEMP_ACTION(sDispatchedTaxi.pedIndex, sDispatchedTaxi.vehicleIndex, TEMPACT_WAIT, 1000000)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : HAS_DISPATCHED_TAXI_PULLED_OVER_TO_PICKUP_PLAYER() : driver tasked TEMPACT_WAIT")
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : HAS_DISPATCHED_TAXI_PULLED_OVER_TO_PICKUP_PLAYER() : return TRUE - stopped at : ", vTaxiPos)
|
|
RETURN TRUE
|
|
ENDIF
|
|
ELSE
|
|
// if the player get close and the vehicle is already stopped just left him get in
|
|
IF TAXI_IS_COORD_IN_RANGE_OF_COORD(vTaxiPos, vPlayerPos, 5.0)
|
|
IF IS_VEHICLE_STOPPED(sDispatchedTaxi.vehicleIndex)
|
|
OR IS_VEHICLE_STOPPED_AT_TRAFFIC_LIGHTS(sDispatchedTaxi.vehicleIndex)
|
|
TASK_VEHICLE_TEMP_ACTION(sDispatchedTaxi.pedIndex, sDispatchedTaxi.vehicleIndex, TEMPACT_WAIT, 1000000)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : HAS_DISPATCHED_TAXI_PULLED_OVER_TO_PICKUP_PLAYER() : driver tasked TEMPACT_WAIT")
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : HAS_DISPATCHED_TAXI_PULLED_OVER_TO_PICKUP_PLAYER() : return TRUE - stopped early for player prox : ", vTaxiPos)
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
IF NOT sDispatchedTaxi.bForcedPullOverAtCurrentPosition
|
|
|
|
// allow player to flag it earlier if he gets close to it before it's had a chance finish it's pull over task
|
|
IF NOT TAXI_IS_COORD_IN_RANGE_OF_COORD(vTaxiPos, sDispatchedTaxi.vPullOverCoords, 10.0)
|
|
IF TAXI_IS_COORD_IN_RANGE_OF_COORD(vTaxiPos, vPlayerPos, 5.0)
|
|
sDispatchedTaxi.vDriveToCoords = vPlayerPos
|
|
sDispatchedTaxi.bForcedPullOverAtCurrentPosition = TRUE
|
|
sDispatchedTaxi.bHasActiveTask = FALSE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : HAS_DISPATCHED_TAXI_PULLED_OVER_TO_PICKUP_PLAYER() : player got close before pulled over so reapplied")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Creates a taxi ready to drive to the player - for when they have rang for a taxi
|
|
PROC DISPATCHED_STATE_CREATE_TAXI()
|
|
|
|
IF IS_PLAYER_PLAYING(PLAYER_ID()) // might not be needed now?
|
|
|
|
// B*1339179 - Taxi came a bit too quickly - always have a minimum time of 10 seconds then it arriving. Les Bug
|
|
IF HAS_TIME_PASSED(sDispatchedTaxi.iTimer_TaxiDispatchDelay, TIME_DELAY_TAXI_DISPATCHED)
|
|
|
|
REQUEST_MODEL(mnTaxiModel)
|
|
REQUEST_MODEL(mnTaxiDriverModel)
|
|
|
|
IF HAS_MODEL_LOADED(mnTaxiModel)
|
|
IF HAS_MODEL_LOADED(mnTaxiDriverModel)
|
|
|
|
VECTOR vSpawnPos
|
|
FLOAT fHeading
|
|
NODE_FLAGS nodeFlags
|
|
|
|
// Info from J Mart - switched off nodes should be ok in most case, but if we are in the city ensure they aren't dead ends (stop taxi using driveways).
|
|
IF IS_POSITION_IN_ZONE_SAFE_FOR_DEADEND_NODES(GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE))
|
|
// COUNTRYSIDE / OK FOR DEADEND NODES -
|
|
// try to make taxi spawn on major road networks first to fix issues where they spawn in blocked off areas/deadends
|
|
IF sDispatchedTaxi.iSpawnAttempts < 2
|
|
nodeFlags = NF_NONE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : DISPATCHED_STATE_CREATE_TAXI() : countryside : using node flags NF_NONE : iSpawnAttempts = ", sDispatchedTaxi.iSpawnAttempts)
|
|
// then attempt spawn not using deadends
|
|
ELIF sDispatchedTaxi.iSpawnAttempts < 5
|
|
nodeFlags = NF_INCLUDE_SWITCHED_OFF_NODES | NF_IGNORE_SWITCHED_OFF_DEADENDS
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : DISPATCHED_STATE_CREATE_TAXI() : countryside : using node flags NF_INCLUDE_SWITCHED_OFF_NODES | NF_IGNORE_SWITCHED_OFF_DEADENDS : iSpawnAttempts = ", sDispatchedTaxi.iSpawnAttempts)
|
|
ELSE
|
|
nodeFlags = NF_INCLUDE_SWITCHED_OFF_NODES
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : DISPATCHED_STATE_CREATE_TAXI() : countryside : using node flags NF_INCLUDE_SWITCHED_OFF_NODES : iSpawnAttempts = ", sDispatchedTaxi.iSpawnAttempts)
|
|
ENDIF
|
|
ELSE
|
|
// CITY / NOT OK FOR DEADEND NODES -
|
|
// try to make taxi spawn on major road networks first to fix issues where they spawn in blocked off areas/deadends
|
|
IF sDispatchedTaxi.iSpawnAttempts < 5
|
|
nodeFlags = NF_NONE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : DISPATCHED_STATE_CREATE_TAXI() : using node flags NF_NONE : iSpawnAttempts = ", sDispatchedTaxi.iSpawnAttempts)
|
|
ELSE
|
|
nodeFlags = NF_INCLUDE_SWITCHED_OFF_NODES | NF_IGNORE_SWITCHED_OFF_DEADENDS
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : DISPATCHED_STATE_CREATE_TAXI() : area NOT safe for DeadEnds : using node flags NF_INCLUDE_SWITCHED_OFF_NODES | NF_IGNORE_SWITCHED_OFF_DEADENDS : iSpawnAttempts = ", sDispatchedTaxi.iSpawnAttempts)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF GENERATE_TAXI_SPAWN_POS_AND_HEADING_TO_PLAYER(vSpawnPos, fHeading, sDispatchedTaxi.iNodeSearchNumber, nodeFlags, DEFAULT)
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
vDebug_DispatchTaxiSpawnPos = vSpawnPos
|
|
|
|
IF bDebug_UseForceTaxiSpawnCoordsAndHeading
|
|
vSpawnPos = vDebug_ForcedTaxiSpawnCoords
|
|
fHeading = fDebug_ForcedTaxiSpawnHeading
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : DISPATCHED_STATE_CREATE_TAXI() : DEBUG! forcing spawn coords & heading")
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
CLEAR_AREA(vSpawnPos, 5.0, TRUE)
|
|
|
|
IF CREATE_TAXI_AND_DRIVER(sDispatchedTaxi.vehicleIndex, sDispatchedTaxi.pedIndex, vSpawnPos, fHeading)
|
|
|
|
sDispatchedTaxi.fDistToTarget = GET_DIST_BETWEEN_VECTORS_NONE_Z(GET_ENTITY_COORDS(sDispatchedTaxi.vehicleIndex), GET_ENTITY_COORDS(PLAYER_PED_ID()))
|
|
|
|
sDispatchedTaxi.bHasActiveTask = FALSE // reset ready for next task
|
|
sDispatchedTaxi.iNodeSearchNumber = 0 // reset ready for destination node search
|
|
|
|
eDispatchedTaxiState = TL_DISPATCHED_STATE_DRIVE_TO_PICKUP_PLAYER
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : eDispatchedTaxiState = TL_DISPATCHED_STATE_DRIVE_TO_PICKUP_PLAYER : fc = ", GET_FRAME_COUNT())
|
|
ELSE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " DISPATCHED_STATE_CREATE_TAXI - CREATE_TAXI - return FALSE")
|
|
ENDIF
|
|
|
|
ELSE
|
|
// fail safe for create taxi not being able to generate suitable creation node
|
|
IF sDispatchedTaxi.iNodeSearchNumber >= 5 // limit to 5 so taxi is still trying to generate a path close to the player
|
|
sDispatchedTaxi.iSpawnAttempts++
|
|
|
|
// 10 retry attempts since it might just be the player's camera angle blocking a successful spawn
|
|
IF sDispatchedTaxi.iSpawnAttempts > 10
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : DISPATCHED_STATE_CREATE_TAXI - Bail Out : failed to generate taxi creation position! : fc = ", GET_FRAME_COUNT())
|
|
CLEANUP_DISPATCHED_TAXI_DATA()
|
|
ELSE
|
|
sDispatchedTaxi.iNodeSearchNumber = 0 // reset ready for retry
|
|
sDispatchedTaxi.iTimer_TaxiDispatchDelay = (GET_GAME_TIMER() - (TIME_DELAY_TAXI_DISPATCHED - 1000)) // retry go through in a seconds time
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : DISPATCHED_STATE_CREATE_TAXI - setup Retry : failed to generate taxi creation position! : fc = ", GET_FRAME_COUNT())
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " DISPATCHED_STATE_CREATE_TAXI - HAS_MODEL_LOADED(mnTaxiDriverModel) - return FALSE")
|
|
ENDIF
|
|
ELSE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " DISPATCHED_STATE_CREATE_TAXI - HAS_MODEL_LOADED(mnTaxiModel) - return FALSE")
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " DISPATCHED_STATE_CREATE_TAXI - IS_PLAYER_PLAYING() - return FALSE")
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// handles the created taxi driving over to the player
|
|
PROC DISPATCHED_STATE_DRIVE_TO_PICKUP_PLAYER()
|
|
|
|
IF HAS_DISPATCHED_TAXI_ARRIVED_TO_PICKUP_PLAYER()
|
|
sDispatchedTaxi.bHasActiveTask = FALSE // reset ready for next task
|
|
eDispatchedTaxiState = TL_DISPATCHED_STATE_PULL_OVER_TO_PICKUP_PLAYER
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : eDispatchedTaxiState = TL_DISPATCHED_STATE_PULL_OVER_TO_PICKUP_PLAYER : fc = ", GET_FRAME_COUNT())
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Handles the created taxi finding a pull over spot to park up near the player upon arrival
|
|
PROC DISPATCHED_STATE_PULL_OVER_TO_PICKUP_PLAYER()
|
|
|
|
IF HAS_DISPATCHED_TAXI_PULLED_OVER_TO_PICKUP_PLAYER()
|
|
|
|
// only set this up as waiting if player isn't getting into a taxi and there isn't one waiting
|
|
IF eEnterTaxiState = TL_ENTER_TAXI_STATE_IDLE
|
|
AND eHailTaxiState != TL_HAIL_TAXI_STATE_TAXI_WAITING
|
|
|
|
// clear ready for next updated state
|
|
CLEANUP_HAIL_TAXI()
|
|
|
|
//update handles
|
|
IF STORE_CAR_AS_TAXI_WAITING_FOR_PLAYER(sDispatchedTaxi.vehicleIndex, sDispatchedTaxi.pedIndex)
|
|
|
|
g_iTaxiHailedTime = 0
|
|
|
|
IF IS_VEHICLE_OK(g_WaitingTaxi)
|
|
START_VEHICLE_HORN(g_WaitingTaxi, 2500, GET_HASH_KEY("NORMAL"))
|
|
ENDIF
|
|
IF DOES_ENTITY_EXIST(g_WaitingTaxiDriver)
|
|
IF NOT IS_PED_INJURED(g_WaitingTaxiDriver)
|
|
TASK_LOOK_AT_ENTITY(g_WaitingTaxiDriver, PLAYER_PED_ID(), 3000)
|
|
TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), g_WaitingTaxiDriver, 3000)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
CREATE_WAITING_TAXI_BLIP()
|
|
|
|
// set the taxi hailing taxi to taxi waiting
|
|
eHailTaxiState = TL_HAIL_TAXI_STATE_TAXI_WAITING
|
|
|
|
CLEANUP_DISPATCHED_TAXI_DATA()
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : DISPATCHED_STATE_PULL_OVER_TO_PICKUP_PLAYER() : marked taxi as waiting : fc = ", GET_FRAME_COUNT())
|
|
ELSE
|
|
CLEANUP_DISPATCHED_TAXI_DATA()
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : DISPATCHED_STATE_PULL_OVER_TO_PICKUP_PLAYER() : failed attempt to mark taxi as waiting : fc = ", GET_FRAME_COUNT())
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// check if the taxi already have a fare on board
|
|
/// NOTE: doesn't safety check entity
|
|
/// RETURNS:
|
|
/// TRUE if found ped in rear seat who isn't in player group
|
|
FUNC BOOL DOES_TAXI_ALREADY_HAVE_A_FARE(VEHICLE_INDEX &vehicleIndex)
|
|
|
|
PED_INDEX pedIndex
|
|
IF NOT IS_VEHICLE_SEAT_FREE(vehicleIndex, VS_BACK_LEFT)
|
|
pedIndex = GET_PED_IN_VEHICLE_SEAT (vehicleIndex, VS_BACK_LEFT)
|
|
|
|
IF NOT (pedIndex = PLAYER_PED_ID())
|
|
// don't worry if it's got player group member in
|
|
IF NOT IS_PED_GROUP_MEMBER(pedIndex, PLAYER_GROUP_ID())
|
|
|
|
// not sure why this is here! but there you go
|
|
IF IS_TAXI_LIGHT_ON(vehicleIndex)
|
|
SET_TAXI_LIGHTS(vehicleIndex, FALSE)
|
|
ENDIF
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDIF
|
|
IF NOT IS_VEHICLE_SEAT_FREE(vehicleIndex, VS_BACK_RIGHT)
|
|
pedIndex = GET_PED_IN_VEHICLE_SEAT (vehicleIndex, VS_BACK_RIGHT)
|
|
|
|
IF NOT (pedIndex = PLAYER_PED_ID())
|
|
// don't worry if it's got player group member in
|
|
IF NOT IS_PED_GROUP_MEMBER(pedIndex, PLAYER_GROUP_ID())
|
|
|
|
// not sure why this is here! but there you go
|
|
IF IS_TAXI_LIGHT_ON(vehicleIndex)
|
|
SET_TAXI_LIGHTS(vehicleIndex, FALSE)
|
|
ENDIF
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Player comment for hailed taxi not stopping
|
|
/// FUNC needs improving
|
|
PROC PLAY_FUCK_YOU_DIALOGUE()
|
|
BOOL bFlag
|
|
// shout 'fuck you'
|
|
IF (bPlayAdditionalFuckYouDialogue)
|
|
IF HAS_TIME_PASSED(iTimer_HailFailedDialogueDelay, 1000)
|
|
IF (GET_SCRIPT_TASK_STATUS(PLAYER_PED_ID(), SCRIPT_TASK_PLAY_ANIM) = FINISHED_TASK)
|
|
IF (GET_SCRIPT_TASK_STATUS(PLAYER_PED_ID(), SCRIPT_TASK_PERFORM_SEQUENCE) = FINISHED_TASK)
|
|
IF NOT IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), tlTaxiAnimDict, "HAIL_TAXI")
|
|
AND NOT IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), tlTaxiAnimDict, "FP_HAIL_TAXI")
|
|
AND NOT IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), tlTaxiAnimDict, "FUCK_U")
|
|
AND NOT IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), tlTaxiAnimDict, "FORGET_IT")
|
|
IF NOT (g_playerIsDrunk)
|
|
// has player been shut up for mission?
|
|
bFlag = IS_AMBIENT_SPEECH_DISABLED(PLAYER_PED_ID())
|
|
//bFlag = TRUE
|
|
IF NOT (bFlag)
|
|
STOP_PED_SPEAKING(PLAYER_PED_ID(), TRUE)
|
|
ENDIF
|
|
|
|
PLAY_PED_AMBIENT_SPEECH(PLAYER_PED_ID(), "TAXI_DRIVES_PAST")
|
|
IF NOT (bFlag)
|
|
STOP_PED_SPEAKING(PLAYER_PED_ID(), FALSE)
|
|
ENDIF
|
|
ENDIF
|
|
SET_PED_CONFIG_FLAG(PLAYER_PED_ID(), PCF_KeepWeaponHolsteredUnlessFired, FALSE)
|
|
// B*1991223 - RESET need to block ambient anims during hail anims
|
|
IF bBlockingPlayerAmbientIdles = TRUE
|
|
SET_PED_CAN_PLAY_AMBIENT_ANIMS(PLAYER_PED_ID(), TRUE)
|
|
bBlockingPlayerAmbientIdles = FALSE
|
|
ENDIF
|
|
bPlayAdditionalFuckYouDialogue = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// check if the player is moving the analogue sticks
|
|
/// RETURNS:
|
|
/// TRUE if movement detected
|
|
FUNC BOOL IS_PLAYER_MOVING()
|
|
// get stick vec
|
|
INT LSx, LSy, RSx, RSy
|
|
GET_CONTROL_VALUE_OF_ANALOGUE_STICKS(LSx, LSy, RSx, RSy)
|
|
IF (LSx > 64)
|
|
OR (LSx < -64)
|
|
OR (LSy > 64)
|
|
OR (LSy < -64)
|
|
RETURN(TRUE)
|
|
ENDIF
|
|
RETURN(FALSE)
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// stops the gameplay hint cam if it was applied by the launcher
|
|
PROC CLEAR_HINT_CAM_IF_PLAYER_IS_MOVING()
|
|
IF IS_GAMEPLAY_HINT_ACTIVE()
|
|
IF bHintTriggeredByTaxiLauncher
|
|
IF IS_PLAYER_MOVING()
|
|
STOP_GAMEPLAY_HINT()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// check if the vehicle is going below TAXI_MOVING_GET_IN_SPEED
|
|
/// PARAMS:
|
|
/// vehicleIndex - vehicle to check
|
|
/// RETURNS:
|
|
/// TRUE if speed is less than TAXI_MOVING_GET_IN_SPEED
|
|
FUNC BOOL IS_CAR_ALMOST_STOPPED(VEHICLE_INDEX vehicleIndex)
|
|
IF IS_VEHICLE_DRIVEABLE(vehicleIndex)
|
|
IF (GET_ENTITY_SPEED(vehicleIndex) < TAXI_MOVING_GET_IN_SPEED)
|
|
RETURN(TRUE)
|
|
ENDIF
|
|
ELSE
|
|
RETURN(TRUE)
|
|
ENDIF
|
|
RETURN(FALSE)
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// check if the vehicle's roll is ok
|
|
/// PARAMS:
|
|
/// vehicleIndex -
|
|
/// RETURNS:
|
|
/// TRUE if roll is ok
|
|
FUNC BOOL IS_CAR_ROLL_ACCEPTABLE(VEHICLE_INDEX vehicleIndex)
|
|
IF IS_VEHICLE_DRIVEABLE(vehicleIndex)
|
|
//IF (GET_ENTITY_ROLL(vehicleIndex) < 45.0)
|
|
//AND (GET_ENTITY_ROLL(vehicleIndex) > -45.0)
|
|
IF IS_ENTITY_UPRIGHT(vehicleIndex)
|
|
RETURN(TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
RETURN(FALSE)
|
|
ENDFUNC
|
|
|
|
PROC STOP_PLAYER_RAGDOLLING()
|
|
IF IS_PLAYER_PLAYING(PLAYER_ID())
|
|
IF NOT (IS_PED_RAGDOLL(PLAYER_PED_ID()))
|
|
EXIT
|
|
ENDIF
|
|
SET_PED_CAN_RAGDOLL (PLAYER_PED_ID(), TRUE )
|
|
//CREATE_NM_MESSAGE(NM_START_STOP , NM_BALANCE_MSG)
|
|
//SEND_NM_MESSAGE(PLAYER_PED_ID())
|
|
|
|
SET_PED_TO_ANIMATED(PLAYER_PED_ID(), FALSE)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
FUNC BOOL HAS_PLAYER_CANCELLED_GETTING_IN_TAXI()
|
|
|
|
VECTOR vec
|
|
|
|
IF IS_CONTROL_PRESSED(FRONTEND_CONTROL, INPUT_ENTER)
|
|
RETURN(FALSE)
|
|
ENDIF
|
|
|
|
// get camera heading in world
|
|
|
|
FLOAT fCamHeading
|
|
VECTOR vGameCamVec
|
|
|
|
vec = GET_GAMEPLAY_CAM_ROT()
|
|
fCamHeading = vec.z
|
|
vGameCamVec = <<0.0, 1.0, 0.0>>
|
|
ROTATE_VECTOR(vGameCamVec, <<0.0, 0.0, fCamHeading>>)
|
|
|
|
// get stick vec
|
|
INT LSx, LSy, RSx, RSy
|
|
VECTOR vStickVec
|
|
|
|
GET_CONTROL_VALUE_OF_ANALOGUE_STICKS(LSx, LSy, RSx, RSy)
|
|
vec.x = LSx / 128.0
|
|
vec.y = LSy / -128.0
|
|
vec.z = 0.0
|
|
// check the stick is moving
|
|
IF (VMAG(vec) < 0.5)
|
|
RETURN(FALSE)
|
|
ENDIF
|
|
vStickVec = <<0.0, 1.0, 0.0>>
|
|
ROTATE_VECTOR(vStickVec, <<0.0, 0.0, fCamHeading>>)
|
|
ROTATE_VECTOR(vStickVec, <<0.0, 0.0, GET_HEADING_FROM_VECTOR_2D(vec.x, vec.y)>>)
|
|
|
|
// get player heading vec
|
|
VECTOR vPlayerVec
|
|
FLOAT fPlayerHeading
|
|
IF IS_PLAYER_PLAYING(PLAYER_ID())
|
|
fPlayerHeading = GET_ENTITY_HEADING(PLAYER_PED_ID())
|
|
vPlayerVec = <<0.0, 1.0, 0.0>>
|
|
ROTATE_VECTOR(vPlayerVec, <<0.0, 0.0, fPlayerHeading>>)
|
|
ENDIF
|
|
|
|
// // draw player and stick vec
|
|
// VECTOR pos, pos2
|
|
// IF IS_PLAYER_PLAYING(PLAYER_ID())
|
|
// // player vec
|
|
// GET_ENTITY_COORDS(PLAYER_PED_ID(), pos.x, pos.y, pos.z)
|
|
// pos2 = pos + vPlayerVec
|
|
// LINE(pos.x, pos.y, pos.z, pos2.x, pos2.y, pos2.z)
|
|
// // stick vec
|
|
// pos2 = pos + vStickVec
|
|
// LINE(pos.x, pos.y, pos.z, pos2.x, pos2.y, pos2.z)
|
|
// ENDIF
|
|
|
|
// check the angle between stick and player heading
|
|
IF (GET_ANGLE_BETWEEN_2D_VECTORS(vPlayerVec.x, vPlayerVec.y, vStickVec.x, vStickVec.y) > 60.0)
|
|
RETURN(TRUE)
|
|
ENDIF
|
|
|
|
RETURN(FALSE)
|
|
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// updates the player's allowed to ride in taxi's status
|
|
/// Scripts can set the status to false so this safe guards against the scripts not resetting the status back when they terminate
|
|
PROC UPDATE_PLAYER_ALLOWED_TO_RIDE_IN_TAXIS_STATUS()
|
|
|
|
// taxi script appears to track hailing disabled using bool (g_bTaxiHailingIsDisabled) and a stored script name (g_sTaxiHailingDisabledByThisScript)
|
|
IF NOT IS_PLAYER_ALLOWED_TO_RIDE_IN_TAXIS()
|
|
|
|
IF ARE_STRINGS_EQUAL("NULL", g_sTaxiHailingDisabledByThisScript)
|
|
DISABLE_TAXI_HAILING(FALSE)
|
|
ELSE
|
|
IF GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(GET_HASH_KEY(g_sTaxiHailingDisabledByThisScript)) = 0
|
|
DISABLE_TAXI_HAILING(FALSE)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// checks to decide if it's safe for the player be given the enter vehicle task
|
|
/// NOTE: safe checks will have already been performed at this stage
|
|
/// RETURNS:
|
|
/// TRUE if ok to apply task
|
|
FUNC BOOL IS_PLAYER_OK_TO_USE_ENTER_VEHICLE_TASK(VEHICLE_INDEX &vehicleIndex)
|
|
|
|
// can't apply task when player doesn't have controls
|
|
IF NOT IS_PLAYER_PLAYING(PLAYER_ID())
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
// only process enter controls when player gets close
|
|
IF NOT IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), vehicleIndex, <<5.0, 5.0, 2.0>>, FALSE)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
// make sure the player doesn't try to enter a speeding vehicle
|
|
IF GET_ENTITY_SPEED(vehicleIndex) > 0.5
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
// interior check - don't give enter task if player isn't in same room
|
|
//IF GET_ROOM_KEY_FROM_ENTITY(vehicleIndex) != GET_ROOM_KEY_FROM_ENTITY(PLAYER_PED_ID())
|
|
IF GET_INTERIOR_FROM_ENTITY(vehicleIndex) != GET_INTERIOR_FROM_ENTITY(PLAYER_PED_ID())
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
// taxi not suitable for player to enter
|
|
IF NOT IS_CAR_ROLL_ACCEPTABLE(vehicleIndex)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Get handles to the closest taxi for PROCESS_PLAYER_ENTER_CLOSEST_TAXI
|
|
/// and also the most desireable to hail for PROCESS_PLAYER_HAILING_TAXI
|
|
/// using GET_PED_NEARBY_VEHICLES
|
|
FUNC BOOL ALT_UPDATE_TAXI_SEARCH_HANDLES()
|
|
|
|
// only search for taxis if the player isn't currently getting into one
|
|
IF eEnterTaxiState = TL_ENTER_TAXI_STATE_IDLE
|
|
|
|
IF HAS_TIME_PASSED(iTimer_DelayTaxiSearch, 500)
|
|
|
|
INT iMaxDesiredTaxiHandles
|
|
INT iHailTargetIndex = -1
|
|
INT iClosestTaxiIndex = -1
|
|
INT iCount
|
|
INT i
|
|
INT iNumTaxisFound = 0
|
|
FLOAT fTaxiScore
|
|
FLOAT fTaxiHighScore = -99999
|
|
FLOAT fMinRange
|
|
VECTOR vTaxiCoords
|
|
FLOAT fDistance
|
|
VECTOR vPlayerForward
|
|
VECTOR vDiff
|
|
|
|
// only update the hail taxi target if we are waiting for the player to hail
|
|
IF (eHailTaxiState != TL_HAIL_TAXI_STATE_IDLE
|
|
AND eHailTaxiState != TL_HAIL_TAXI_STATE_DETECT_HAIL)
|
|
bUpdateHailTargetThisFrame = FALSE
|
|
ENDIF
|
|
|
|
// and when the update timer has passed
|
|
IF bUpdateHailTargetThisFrame
|
|
iMaxDesiredTaxiHandles = 3 // grab three closest taxis
|
|
fMinRange = TAXI_HAIL_DISTANCE // only worry about vehicles with in the hail distance
|
|
ELSE
|
|
// if we aren't searching for hail targets this frame only need a small number of close vehicle
|
|
iMaxDesiredTaxiHandles = 1 // only grab the one closest taxi
|
|
fMinRange = 10.0 // only worry about vehicles with 10m
|
|
ENDIF
|
|
|
|
VEHICLE_INDEX vehIndexArray[12]
|
|
|
|
// this function returns vehicles in order of closeness
|
|
iCount = GET_PED_NEARBY_VEHICLES(PLAYER_PED_ID(), vehIndexArray)
|
|
|
|
IF iCount > 0
|
|
FOR i = 0 TO (iCount - 1)
|
|
IF iNumTaxisFound < iMaxDesiredTaxiHandles
|
|
|
|
// if the entity doesn't exist (drop out the loop since all other entities shouldn't exist either
|
|
IF DOES_ENTITY_EXIST(vehIndexArray[i])
|
|
|
|
// check the vehicle is a taxi
|
|
IF (GET_ENTITY_MODEL(vehIndexArray[i]) = mnTaxiModel)
|
|
|
|
// dist check first (break out loop if veh isn't in range since the array in filled closest first)
|
|
vTaxiCoords = GET_ENTITY_COORDS(vehIndexArray[i], FALSE)
|
|
fDistance = VDIST2(vPlayerPos, vTaxiCoords)
|
|
|
|
IF fDistance <= (fMinRange * fMinRange)
|
|
|
|
// check the taxi and it's driver is suitable
|
|
IF IS_PLAYER_OK_TO_ENTER_VEHICLE_AS_PASSENGER(vehIndexArray[i], mnTaxiModel, mnTaxiDriverModel)
|
|
|
|
// Store the closest Taxi
|
|
IF iClosestTaxiIndex = -1
|
|
iClosestTaxiIndex = i
|
|
//#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ALT_UPDATE_TAXI_SEARCH_HANDLES : Closest taxi set this frame : ", GET_FRAME_COUNT(), " array index = ", i) ENDIF #ENDIF
|
|
ENDIF
|
|
|
|
// only care about the rest of the checks if searching for a taxi to hail
|
|
IF bUpdateHailTargetThisFrame
|
|
|
|
// don't hail the waiting taxi (potential move this check to hail so he never hails when one is pulled up waiting?
|
|
IF (vehIndexArray[i] != g_WaitingTaxi)
|
|
|
|
// not allowed to hail taxis with light off
|
|
//IF NOT DOES_TAXI_HAVE_LIGHT_ON(vehicleIndex)
|
|
|
|
// don't consider if not in same interior
|
|
IF GET_INTERIOR_FROM_ENTITY(vehIndexArray[i]) = GET_INTERIOR_FROM_ENTITY(PLAYER_PED_ID())
|
|
|
|
// Update hail score
|
|
fTaxiScore = 1.0
|
|
|
|
// score the distance
|
|
fDistance /= fDistance
|
|
fDistance -= TAXI_HAIL_DISTANCE
|
|
fDistance *= -1.0
|
|
fDistance /= TAXI_HAIL_DISTANCE
|
|
fDistance *= 0.5 // min score is 0.5
|
|
fDistance += 0.5
|
|
|
|
// multiple score by distance score
|
|
fTaxiScore *= fDistance
|
|
|
|
fDistance = vPlayerPos.z - vTaxiCoords.z
|
|
IF fDistance < 0.0
|
|
fDistance *= -1.0
|
|
ENDIF
|
|
|
|
// don't hail taxi if the Z diff is too high
|
|
IF fDistance < 4.0
|
|
|
|
// if taxi isn't inside 120 2D arc of player don't consider it (using Sam's IS_ENTITY_IN_ARC_2D)
|
|
vPlayerForward = GET_ENTITY_FORWARD_VECTOR(PLAYER_PED_ID())
|
|
vDiff = vTaxiCoords - vPlayerPos
|
|
|
|
IF (((vPlayerForward.x*vDiff.x)+(vPlayerForward.y*vDiff.y)) / VDIST(vDiff, <<0,0,0>>)) > COS(120)
|
|
|
|
// reduce score if taxi is off screen
|
|
IF IS_SPHERE_VISIBLE(vTaxiCoords, 2)
|
|
fTaxiScore *= 0.5
|
|
ENDIF
|
|
|
|
// reduce score if taxi is occupied, so unoccupied taxis have priority
|
|
IF DOES_TAXI_ALREADY_HAVE_A_FARE(vehIndexArray[i])
|
|
fTaxiScore *= 0.2
|
|
ENDIF
|
|
|
|
// disregard if unside down or in water
|
|
IF NOT IS_ENTITY_UPRIGHT(vehIndexArray[i])
|
|
OR IS_ENTITY_IN_WATER(vehIndexArray[i])
|
|
fTaxiScore = 0
|
|
ENDIF
|
|
|
|
// set the highscore and store the index for the hail target
|
|
IF fTaxiScore > fTaxiHighScore
|
|
fTaxiHighScore = fTaxiScore
|
|
iHailTargetIndex = i
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ALT_UPDATE_TAXI_SEARCH_HANDLES : Updated iHailTargetIndex = ", i, " score = ", fTaxiHighScore) ENDIF #ENDIF
|
|
ENDIF
|
|
ELSE
|
|
//#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ALT_UPDATE_TAXI_SEARCH_HANDLES : taxi ", i, " rejected wasn't infront of player ") ENDIF #ENDIF
|
|
ENDIF
|
|
ELSE
|
|
//#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ALT_UPDATE_TAXI_SEARCH_HANDLES : taxi ", i, " rejected Z diff to high = ", fDistance) ENDIF #ENDIF
|
|
ENDIF
|
|
ELSE
|
|
//#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ALT_UPDATE_TAXI_SEARCH_HANDLES : taxi ", i, " rejected interior check ") ENDIF #ENDIF
|
|
ENDIF
|
|
//ENDIF
|
|
ELSE
|
|
//#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ALT_UPDATE_TAXI_SEARCH_HANDLES : taxi ", i, " rejected taxi is g_WaitingTaxi ") ENDIF #ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
//#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ALT_UPDATE_TAXI_SEARCH_HANDLES : i = ", i, " grabbed handle to taxi") ENDIF #ENDIF
|
|
iNumTaxisFound++
|
|
ELSE
|
|
//#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ALT_UPDATE_TAXI_SEARCH_HANDLES : taxi ", i, " rejected not suitable") ENDIF #ENDIF
|
|
ENDIF
|
|
ELSE
|
|
//#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ALT_UPDATE_TAXI_SEARCH_HANDLES : i = ", i, " looped ended as detected veh dist out of range = ", fDistance) ENDIF #ENDIF
|
|
i = iCount
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
//#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ALT_UPDATE_TAXI_SEARCH_HANDLES : i = ", i, " looped ended as detected veh didn't exist ") ENDIF #ENDIF
|
|
i = iCount
|
|
ENDIF
|
|
ELSE
|
|
//#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ALT_UPDATE_TAXI_SEARCH_HANDLES : i = ", i, " looped ended as iNumTaxisFound = ", iNumTaxisFound) ENDIF #ENDIF
|
|
i = iCount
|
|
ENDIF
|
|
ENDFOR
|
|
ENDIF
|
|
|
|
// Store the closest Taxi
|
|
IF iClosestTaxiIndex = -1
|
|
|
|
// ensure the previous taxi's driver's flag is reset to normal behaviour
|
|
SET_TAXI_DRIVER_ENTER_AS_PASSENGER_FLAG(vehClosestTaxi, FALSE)
|
|
|
|
vehClosestTaxi = NULL
|
|
|
|
// reset timer for delaying search for hailable taxis
|
|
//iTimer_DelayTaxiSearch = GET_GAME_TIMER()
|
|
ELSE
|
|
//iTimer_DelayTaxiSearch = 0 // ensure the taxi search goes through every frame when a taxi is in range
|
|
|
|
// update the handle if it's changed
|
|
IF vehClosestTaxi != vehIndexArray[iClosestTaxiIndex]
|
|
|
|
// ensure the previous taxi's driver's flag is reset to normal behaviour
|
|
SET_TAXI_DRIVER_ENTER_AS_PASSENGER_FLAG(vehClosestTaxi, FALSE)
|
|
|
|
vehClosestTaxi = vehIndexArray[iClosestTaxiIndex]
|
|
|
|
// Set the new closest driver's flag so the player can enter as passenger
|
|
SET_TAXI_DRIVER_ENTER_AS_PASSENGER_FLAG(vehClosestTaxi, TRUE)
|
|
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ALT_UPDATE_TAXI_SEARCH_HANDLES : Closest taxi updated this frame : ", GET_FRAME_COUNT(), " array index = ", iClosestTaxiIndex) ENDIF #ENDIF
|
|
ENDIF
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ALT_UPDATE_TAXI_SEARCH_HANDLES : Closest taxi set this frame : ", GET_FRAME_COUNT(), " array index = ", iClosestTaxiIndex) ENDIF #ENDIF
|
|
ENDIF
|
|
|
|
// update whether or not we want to search for hail targets next opportunity
|
|
IF bUpdateHailTargetThisFrame
|
|
|
|
// Store the hail Taxi
|
|
IF iHailTargetIndex = -1
|
|
vehHailTarget = NULL
|
|
ELSE
|
|
vehHailTarget = vehIndexArray[iHailTargetIndex]
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ALT_UPDATE_TAXI_SEARCH_HANDLES : Hail target taxi set this frame : ", GET_FRAME_COUNT(), " array index = ", iHailTargetIndex) ENDIF #ENDIF
|
|
ENDIF
|
|
|
|
bUpdateHailTargetThisFrame = FALSE // don't recheck next frame
|
|
ELSE
|
|
bUpdateHailTargetThisFrame = TRUE // recheck next frame
|
|
ENDIF
|
|
|
|
// reset timer for delaying search for taxis
|
|
iTimer_DelayTaxiSearch = GET_GAME_TIMER()
|
|
|
|
//#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ALT_UPDATE_TAXI_SEARCH_HANDLES : handles update this frame : ", GET_FRAME_COUNT()) ENDIF #ENDIF
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Get handles to the closest taxi for PROCESS_PLAYER_ENTER_CLOSEST_TAXI
|
|
/// and also the most desireable to hail for PROCESS_PLAYER_HAILING_TAXI
|
|
/// using GET_RANDOM_VEHICLE_IN_SPHERE
|
|
PROC UPDATE_TAXI_SEARCH_HANDLES()
|
|
|
|
// only search for taxis if the player is currently getting into one
|
|
IF eEnterTaxiState = TL_ENTER_TAXI_STATE_IDLE
|
|
|
|
IF HAS_TIME_PASSED(iTimer_DelayTaxiSearch, 750)
|
|
|
|
INT iHailTargetIndex = -1
|
|
INT iClosestTaxiIndex = -1
|
|
INT iCount
|
|
INT i
|
|
FLOAT fTaxiScore
|
|
FLOAT fTaxiHighScore = -99999
|
|
FLOAT fMinRange = TAXI_HAIL_DISTANCE // only worry about vehicles with in the hail distance
|
|
VECTOR vTaxiCoords
|
|
FLOAT fDistance
|
|
VECTOR vPlayerForward
|
|
VECTOR vDiff
|
|
FLOAT fClosestTaxiDist = 9999999.0
|
|
|
|
iCount = 3
|
|
VEHICLE_INDEX vehIndexArray[3]
|
|
vehIndexArray[0] = GET_RANDOM_VEHICLE_IN_SPHERE(vPlayerPos, TAXI_HAIL_DISTANCE * 0.33, mnTaxiModel, VEHICLE_SEARCH_FLAG_RETURN_RANDOM_VEHICLES | VEHICLE_SEARCH_FLAG_CHECK_VEHICLE_OCCUPANTS_STATES | VEHICLE_SEARCH_FLAG_RETURN_MISSION_VEHICLES | VEHICLE_SEARCH_FLAG_ALLOW_VEHICLE_OCCUPANTS_TO_BE_PERFORMING_A_SCRIPTED_TASK)
|
|
vehIndexArray[1] = GET_RANDOM_VEHICLE_IN_SPHERE(vPlayerPos, TAXI_HAIL_DISTANCE * 0.66, mnTaxiModel, VEHICLE_SEARCH_FLAG_RETURN_RANDOM_VEHICLES | VEHICLE_SEARCH_FLAG_CHECK_VEHICLE_OCCUPANTS_STATES | VEHICLE_SEARCH_FLAG_RETURN_MISSION_VEHICLES | VEHICLE_SEARCH_FLAG_ALLOW_VEHICLE_OCCUPANTS_TO_BE_PERFORMING_A_SCRIPTED_TASK)
|
|
vehIndexArray[2] = GET_RANDOM_VEHICLE_IN_SPHERE(vPlayerPos, TAXI_HAIL_DISTANCE * 1.00, mnTaxiModel, VEHICLE_SEARCH_FLAG_RETURN_RANDOM_VEHICLES | VEHICLE_SEARCH_FLAG_CHECK_VEHICLE_OCCUPANTS_STATES | VEHICLE_SEARCH_FLAG_RETURN_MISSION_VEHICLES | VEHICLE_SEARCH_FLAG_ALLOW_VEHICLE_OCCUPANTS_TO_BE_PERFORMING_A_SCRIPTED_TASK)
|
|
|
|
FOR i = 0 TO (iCount - 1)
|
|
// check the taxi and it's driver is suitable
|
|
IF IS_PLAYER_OK_TO_ENTER_VEHICLE_AS_PASSENGER(vehIndexArray[i], mnTaxiModel, mnTaxiDriverModel)
|
|
|
|
vTaxiCoords = GET_ENTITY_COORDS(vehIndexArray[i], FALSE)
|
|
fDistance = VDIST2(vPlayerPos, vTaxiCoords)
|
|
|
|
// only worry about taxis close enough to hail
|
|
IF fDistance <= (fMinRange * fMinRange)
|
|
|
|
// update the closest taxi index
|
|
IF fDistance < fClosestTaxiDist
|
|
fClosestTaxiDist = fDistance
|
|
iClosestTaxiIndex = i
|
|
//#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : UPDATE_TAXI_SEARCH_HANDLES : Closest taxi updated dist = ", fClosestTaxiDist, " array index = ", i) ENDIF #ENDIF
|
|
ENDIF
|
|
|
|
// don't hail the waiting taxi (potential move this check to hail so he never hails when one is pulled up waiting?
|
|
IF (vehIndexArray[i] != g_WaitingTaxi)
|
|
|
|
// not allowed to hail taxis with light off
|
|
//IF NOT DOES_TAXI_HAVE_LIGHT_ON(vehicleIndex[i])
|
|
|
|
// don't consider if not in same interior
|
|
IF GET_INTERIOR_FROM_ENTITY(vehIndexArray[i]) = GET_INTERIOR_FROM_ENTITY(PLAYER_PED_ID())
|
|
|
|
// Update hail score
|
|
fTaxiScore = 1.0
|
|
|
|
// score the distance
|
|
fDistance /= fDistance
|
|
fDistance -= TAXI_HAIL_DISTANCE
|
|
fDistance *= -1.0
|
|
fDistance /= TAXI_HAIL_DISTANCE
|
|
fDistance *= 0.5 // min score is 0.5
|
|
fDistance += 0.5
|
|
|
|
// multiple score by distance score
|
|
fTaxiScore *= fDistance
|
|
|
|
// don't hail taxi if the Z diff is too different
|
|
fDistance = vPlayerPos.z - vTaxiCoords.z
|
|
IF fDistance < 0.0
|
|
fDistance *= -1.0
|
|
ENDIF
|
|
|
|
IF fDistance < 4.0
|
|
|
|
// if taxi isn't inside 120 2D arc of player don't consider it (using Sam's IS_ENTITY_IN_ARC_2D)
|
|
vPlayerForward = GET_ENTITY_FORWARD_VECTOR(PLAYER_PED_ID())
|
|
vDiff = vTaxiCoords - vPlayerPos
|
|
|
|
IF (((vPlayerForward.x*vDiff.x)+(vPlayerForward.y*vDiff.y)) / VDIST(vDiff, <<0,0,0>>)) > COS(120)
|
|
|
|
// reduce score if taxi is off screen
|
|
IF IS_SPHERE_VISIBLE(vTaxiCoords, 2)
|
|
fTaxiScore *= 0.5
|
|
ENDIF
|
|
|
|
// reduce score if taxi is occupied, so unoccupied taxis have priority
|
|
IF DOES_TAXI_ALREADY_HAVE_A_FARE(vehIndexArray[i])
|
|
fTaxiScore *= 0.2
|
|
ENDIF
|
|
|
|
// set the highscore and store the index for the hail target
|
|
IF fTaxiScore > fTaxiHighScore
|
|
fTaxiHighScore = fTaxiScore
|
|
iHailTargetIndex = i
|
|
//#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : UPDATE_TAXI_SEARCH_HANDLES : Updated iHailTargetIndex = ", i, " score = ", fTaxiHighScore) ENDIF #ENDIF
|
|
ENDIF
|
|
ELSE
|
|
//#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : UPDATE_TAXI_SEARCH_HANDLES : taxi ", i, " rejected wasn't infront of player ") ENDIF #ENDIF
|
|
ENDIF
|
|
ELSE
|
|
//#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : UPDATE_TAXI_SEARCH_HANDLES : taxi ", i, " rejected Z diff to high = ", fDistance) ENDIF #ENDIF
|
|
ENDIF
|
|
ELSE
|
|
//#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : UPDATE_TAXI_SEARCH_HANDLES : taxi ", i, " rejected interior check ") ENDIF #ENDIF
|
|
ENDIF
|
|
//ENDIF
|
|
ELSE
|
|
//#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : UPDATE_TAXI_SEARCH_HANDLES : taxi ", i, " rejected taxi is g_WaitingTaxi ") ENDIF #ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDFOR
|
|
|
|
// Store the closest Taxi
|
|
IF iClosestTaxiIndex = -1
|
|
vehClosestTaxi = NULL
|
|
ELSE
|
|
// discard the taxi if its not going to be close enough to enter
|
|
IF fClosestTaxiDist < (10.0 * 10.0)
|
|
vehClosestTaxi = vehIndexArray[iClosestTaxiIndex]
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : UPDATE_TAXI_SEARCH_HANDLES : Closest taxi set this frame : ", GET_FRAME_COUNT(), " array index = ", iClosestTaxiIndex) ENDIF #ENDIF
|
|
ELSE
|
|
vehClosestTaxi = NULL
|
|
ENDIF
|
|
ENDIF
|
|
iTimer_DelayTaxiSearch = GET_GAME_TIMER()
|
|
|
|
// only update the hail target when one isn't waiting
|
|
IF (eHailTaxiState = TL_HAIL_TAXI_STATE_IDLE
|
|
OR eHailTaxiState = TL_HAIL_TAXI_STATE_DETECT_HAIL)
|
|
IF iHailTargetIndex = -1
|
|
vehHailTarget = NULL
|
|
ELSE
|
|
vehHailTarget = vehIndexArray[iHailTargetIndex]
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : UPDATE_TAXI_SEARCH_HANDLES : Hail target taxi set this frame : ", GET_FRAME_COUNT(), " array index = ", iHailTargetIndex) ENDIF #ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// check if the waiting taxi should cleanup
|
|
/// RETURNS:
|
|
/// TRUE if reason to cleanup found
|
|
FUNC BOOL SHOULD_WAITING_TAXI_CLEANUP()
|
|
|
|
// Check for hailed taxi timing out
|
|
IF eHailTaxiState = TL_HAIL_TAXI_STATE_TAXI_WAITING
|
|
IF g_iTaxiHailedTime = -1 OR g_iTaxiHailedTime = 0
|
|
g_iTaxiHailedTime = GET_GAME_TIMER()
|
|
ELSE
|
|
IF HAS_TIME_PASSED(g_iTaxiHailedTime, 30000)
|
|
IF eEnterTaxiState = TL_ENTER_TAXI_STATE_IDLE
|
|
OR eEnterTaxiState = TL_ENTER_TAXI_STATE_WAIT_FOR_PLAYER_TO_EXIT
|
|
IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), g_WaitingTaxi, TRUE) // Bug fix - extra check to make sure player isn't in the process of getting in the taxi
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), ": SHOULD_WAITING_TAXI_CLEANUP : return TRUE : hail timer expired : timer = ", g_iTaxiHailedTime)
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// taxi checks
|
|
IF IS_VEHICLE_OK(g_WaitingTaxi)
|
|
|
|
VECTOR vTaxiCoords = GET_ENTITY_COORDS(g_WaitingTaxi, FALSE)
|
|
|
|
// Check for player abandoning taxi
|
|
IF eHailTaxiState = TL_HAIL_TAXI_STATE_TAXI_WAITING
|
|
IF NOT TAXI_IS_COORD_IN_RANGE_OF_COORD(vPlayerPos, vTaxiCoords, 75.0)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_WAITING_TAXI_CLEANUP : return TRUE : player abandoned taxi")
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// player attacked taxi
|
|
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(g_WaitingTaxi, PLAYER_PED_ID())
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_WAITING_TAXI_CLEANUP : return TRUE : damaged taxi check")
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
// bullet fired near taxi
|
|
IF IS_BULLET_IN_AREA(vTaxiCoords, 7.0, FALSE)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_WAITING_TAXI_CLEANUP : 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_WAITING_TAXI_CLEANUP : return TRUE : projectile near taxi")
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF TAXI_IS_COORD_IN_RANGE_OF_COORD(vPlayerPos, vTaxiCoords, 20.0)
|
|
|
|
// aiming at the taxi
|
|
IF IS_PLAYER_FREE_AIMING_AT_ENTITY(PLAYER_ID(), g_WaitingTaxi)
|
|
OR IS_PLAYER_TARGETTING_ENTITY(PLAYER_ID(), g_WaitingTaxi)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_WAITING_TAXI_CLEANUP : return TRUE : aiming at the taxi")
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
// check for player shooting near waiting taxi
|
|
IF IS_PED_SHOOTING(PLAYER_PED_ID())
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_WAITING_TAXI_CLEANUP : return TRUE : player shooting check")
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_TAXI_SERVICE_END_EARLY : return TRUE : taxi ok check")
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
// check the driver is ok
|
|
IF IS_PED_UNINJURED(g_WaitingTaxiDriver)
|
|
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(g_WaitingTaxiDriver, PLAYER_PED_ID())
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_WAITING_TAXI_CLEANUP : return TRUE : damaged taxi driver check")
|
|
RETURN TRUE
|
|
ENDIF
|
|
ELSE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_WAITING_TAXI_CLEANUP : return TRUE : taxi driver ok check")
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// handles the player hailing nearby taxi
|
|
PROC HAIL_STATE_DETECT_HAIL()
|
|
|
|
PLAY_FUCK_YOU_DIALOGUE()
|
|
|
|
CLEAR_HINT_CAM_IF_PLAYER_IS_MOVING()
|
|
|
|
// don't process taxi hailing if a taxi wasn't found to hail
|
|
IF DOES_ENTITY_EXIST(vehHailTarget)
|
|
|
|
// contains safe checks on taxi and it's driver
|
|
IF IS_PLAYER_OK_TO_ENTER_VEHICLE_AS_PASSENGER(vehHailTarget, mnTaxiModel, mnTaxiDriverModel)
|
|
|
|
IF IS_PLAYER_ALLOWED_TO_HAIL_A_TAXI()
|
|
|
|
REQUEST_ANIM_DICT(tlTaxiAnimDict)
|
|
IF HAS_ANIM_DICT_LOADED(tlTaxiAnimDict)
|
|
|
|
IF NOT IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), tlTaxiAnimDict, "HAIL_TAXI")
|
|
AND NOT IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), tlTaxiAnimDict, "FP_HAIL_TAXI")
|
|
AND NOT IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), tlTaxiAnimDict, "FUCK_U")
|
|
AND NOT IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), tlTaxiAnimDict, "FORGET_IT")
|
|
|
|
IF NOT DOES_TAXI_ALREADY_HAVE_A_FARE(vehHailTarget)
|
|
IF NOT IS_TAXI_LIGHT_ON(vehHailTarget)
|
|
SET_TAXI_LIGHTS(vehHailTarget, TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF iTaxiHailIntention = NEW_CONTEXT_INTENTION
|
|
REGISTER_CONTEXT_INTENTION(iTaxiHailIntention, CP_TAXI_PRIORITY, "TXM_H01", TRUE) // Press ~INPUT_CONTEXT~ to hail a Taxi.
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " PROCESS_PLAYER_HAILING_TAXI() : REGISTER_CONTEXT_INTENTION - TX_H01") ENDIF #ENDIF
|
|
ENDIF
|
|
|
|
// Wait to detect player input for taxi hail
|
|
IF HAS_CONTEXT_BUTTON_TRIGGERED(iTaxiHailIntention)
|
|
|
|
IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("TXM_H01") // Press ~INPUT_CONTEXT~ to hail a Taxi.
|
|
CLEAR_HELP()
|
|
ENDIF
|
|
|
|
// B*1991223 - RESET need to block ambient anims during hail anims
|
|
IF bBlockingPlayerAmbientIdles = FALSE
|
|
SET_PED_CAN_PLAY_AMBIENT_ANIMS(PLAYER_PED_ID(), FALSE)
|
|
bBlockingPlayerAmbientIdles = TRUE
|
|
ENDIF
|
|
|
|
// task the player
|
|
TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), vehHailTarget, 5000)
|
|
PLAY_HAIL_ANIMS_AND_DIALOGUE()
|
|
// B*2074743 - block aiming during hail animation
|
|
DISABLE_PLAYER_WEAPON_CONTROLS_FOR_HAIL_THIS_FRAME()
|
|
iTimer_HailAnimTriggered = GET_GAME_TIMER()
|
|
|
|
RELEASE_CONTEXT_INTENTION(iTaxiHailIntention)
|
|
|
|
// Failed attempt if taxi already has passengers
|
|
IF DOES_TAXI_ALREADY_HAVE_A_FARE(vehHailTarget)
|
|
|
|
IF IS_VEHICLE_DRIVEABLE(vehHailTarget)
|
|
SET_TAXI_LIGHTS(vehHailTarget, FALSE)
|
|
ENDIF
|
|
|
|
bHintTriggeredByTaxiLauncher = FALSE
|
|
|
|
eHailTaxiState = TL_HAIL_TAXI_STATE_FAILED_ATTEMPT
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " PROCESS_PLAYER_HAILING_TAXI() : eHailTaxiState = TL_HAIL_TAXI_STATE_FAILED_ATTEMPT") ENDIF #ENDIF
|
|
ELSE
|
|
// Successful attempt to hail a taxi
|
|
|
|
//update handles g_WaitingTaxi = vehicleIndex, g_WaitingTaxiDriver = pedIndex
|
|
PED_INDEX pedIndex
|
|
pedIndex = GET_PED_IN_VEHICLE_SEAT(vehHailTarget)
|
|
|
|
IF STORE_CAR_AS_TAXI_WAITING_FOR_PLAYER(vehHailTarget, pedIndex)
|
|
|
|
//release handle
|
|
vehHailTarget = NULL
|
|
|
|
TASK_LOOK_AT_ENTITY(PLAYER_PED_ID(), g_WaitingTaxi, 5000)
|
|
|
|
g_iTaxiHailedTime = GET_GAME_TIMER()
|
|
|
|
IF IS_VEHICLE_DRIVEABLE(g_WaitingTaxi)
|
|
IF NOT IS_GAMEPLAY_HINT_ACTIVE()
|
|
SET_GAMEPLAY_VEHICLE_HINT(g_WaitingTaxi, <<0,0,0>>, TRUE, 4000)
|
|
bHintTriggeredByTaxiLauncher = TRUE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " PROCESS_PLAYER_HAILING_TAXI() : TRIGGER hint cam for taxi hail")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
g_savedGlobals.sAmbient.bTaxiHailingHelpDisplayed = TRUE
|
|
|
|
eHailTaxiState = TL_HAIL_TAXI_STATE_SUCCESSFUL_ATTEMPT
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " PROCESS_PLAYER_HAILING_TAXI() : eHailTaxiState = TL_HAIL_TAXI_STATE_SUCCESSFUL_ATTEMPT") ENDIF #ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
CLEANUP_HAIL_TAXI()
|
|
ENDIF
|
|
ELSE
|
|
CLEANUP_HAIL_TAXI()
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// handle taxi driver gesturing to player to get in
|
|
PROC HAIL_TAXI_STATE_SUCCESSFUL_ATTEMPT()
|
|
|
|
// contains safe checks on taxi and it's driver
|
|
IF IS_TAXI_AND_DRIVER_OK_FOR_PLAYER_TO_ENTER_AS_PASSENGER(g_WaitingTaxi, g_WaitingTaxiDriver, mnTaxiModel, mnTaxiDriverModel)
|
|
|
|
BOOL bFlag = FALSE
|
|
IF IS_CONTROL_PRESSED(FRONTEND_CONTROL, INPUT_ENTER)
|
|
bFlag = TRUE
|
|
ENDIF
|
|
IF HAS_TIME_PASSED(iTimer_HailAnimTriggered, 1000)
|
|
IF (GET_SCRIPT_TASK_STATUS(PLAYER_PED_ID(), SCRIPT_TASK_PLAY_ANIM) = FINISHED_TASK)
|
|
IF NOT IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), tlTaxiAnimDict, "HAIL_TAXI")
|
|
AND NOT IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), tlTaxiAnimDict, "FP_HAIL_TAXI")
|
|
AND NOT IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), tlTaxiAnimDict, "FUCK_U")
|
|
AND NOT IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), tlTaxiAnimDict, "FORGET_IT")
|
|
IF (GET_SCRIPT_TASK_STATUS(PLAYER_PED_ID(), SCRIPT_TASK_PERFORM_SEQUENCE) = FINISHED_TASK)
|
|
SET_PED_CONFIG_FLAG(PLAYER_PED_ID(), PCF_KeepWeaponHolsteredUnlessFired, FALSE)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " HAIL_TAXI_STATE_SUCCESSFUL_ATTEMPT: PCF_KeepWeaponHolsteredUnlessFired, FALSE")
|
|
// B*1991223 - RESET need to block ambient anims during hail anims
|
|
IF bBlockingPlayerAmbientIdles = TRUE
|
|
SET_PED_CAN_PLAY_AMBIENT_ANIMS(PLAYER_PED_ID(), TRUE)
|
|
bBlockingPlayerAmbientIdles = FALSE
|
|
ENDIF
|
|
bFlag = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF (bFlag)
|
|
REQUEST_ANIM_DICT(tlTaxiAnimDict)
|
|
IF HAS_ANIM_DICT_LOADED(tlTaxiAnimDict)
|
|
// chance shouting for taxi
|
|
IF GET_RANDOM_INT_IN_RANGE(0, 10) < 8
|
|
IF NOT IS_ANY_DIALOGUE_PLAYING(NULL, FALSE)
|
|
BOOL bPauseAmbientSpeech = IS_AMBIENT_SPEECH_DISABLED(PLAYER_PED_ID())
|
|
IF bPauseAmbientSpeech
|
|
STOP_PED_SPEAKING(PLAYER_PED_ID(), FALSE)
|
|
ENDIF
|
|
PLAY_PED_AMBIENT_SPEECH(PLAYER_PED_ID(), "TAXI_HAIL", SPEECH_PARAMS_SHOUTED)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " HAIL_TAXI_STATE_SUCCESSFUL_ATTEMPT() : trigger TAXI_HAIL dialogue : bPauseAmbientSpeech = ", bPauseAmbientSpeech)
|
|
IF bPauseAmbientSpeech
|
|
STOP_PED_SPEAKING(PLAYER_PED_ID(), TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
SEQUENCE_INDEX seq
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_LOOK_AT_ENTITY(NULL, PLAYER_PED_ID(), 5000, SLF_WHILE_NOT_IN_FOV)
|
|
IF IS_PLAYER_TO_RIGHT_OF_CAR(g_WaitingTaxi)
|
|
TASK_PLAY_ANIM(NULL, tlTaxiAnimDict, "Aknowledge_R", NORMAL_BLEND_IN, SLOW_BLEND_OUT, -1, AF_SECONDARY|AF_UPPERBODY|AF_ABORT_ON_WEAPON_DAMAGE|AF_EXIT_AFTER_INTERRUPTED)
|
|
ELSE
|
|
TASK_PLAY_ANIM(NULL, tlTaxiAnimDict, "Aknowledge_L", NORMAL_BLEND_IN, SLOW_BLEND_OUT, -1, AF_SECONDARY|AF_UPPERBODY|AF_ABORT_ON_WEAPON_DAMAGE|AF_EXIT_AFTER_INTERRUPTED)
|
|
ENDIF
|
|
TASK_VEHICLE_MISSION(NULL, g_WaitingTaxi, g_WaitingTaxi, MISSION_PULL_OVER, 12.0, DRIVINGMODE_STOPFORCARS_STRICT, 3, 3)
|
|
TASK_VEHICLE_MISSION(NULL, g_WaitingTaxi, g_WaitingTaxi, MISSION_STOP, 12.0, DRIVINGMODE_STOPFORCARS_STRICT, 3, 3)
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(g_WaitingTaxiDriver, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
//INCREMENT_INT_STAT_NO_MESSAGE(STAT_NUMBER_TAXIS_HAILED, 1)
|
|
|
|
CREATE_WAITING_TAXI_BLIP()
|
|
|
|
eHailTaxiState = TL_HAIL_TAXI_STATE_TAXI_WAITING
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " HAIL_TAXI_STATE_SUCCESSFUL_ATTEMPT() : eHailTaxiState = TL_HAIL_TAXI_STATE_TAXI_WAITING") ENDIF #ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
CLEANUP_HAIL_TAXI()
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// player aknowledges failed attempt
|
|
PROC HAIL_TAXI_STATE_FAILED_ATTEMPT()
|
|
|
|
// wait for the hail anims to end
|
|
IF IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), tlTaxiAnimDict, "HAIL_TAXI")
|
|
OR IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), tlTaxiAnimDict, "FP_HAIL_TAXI")
|
|
EXIT
|
|
|
|
ELIF HAS_TIME_PASSED(iTimer_HailAnimTriggered, 3000)
|
|
|
|
REQUEST_ANIM_DICT(tlTaxiAnimDict)
|
|
IF HAS_ANIM_DICT_LOADED(tlTaxiAnimDict)
|
|
|
|
// contains checks to make anim can play safely
|
|
IF IS_PLAYER_ALLOWED_TO_HAIL_A_TAXI()
|
|
CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
|
|
SET_PED_CONFIG_FLAG(PLAYER_PED_ID(), PCF_KeepWeaponHolsteredUnlessFired, TRUE)
|
|
|
|
IF (GET_RANDOM_INT_IN_RANGE(0,3) < 2)
|
|
TASK_PLAY_ANIM(PLAYER_PED_ID(), tlTaxiAnimDict, "FORGET_IT", SLOW_BLEND_IN, REALLY_SLOW_BLEND_OUT, -1, AF_UPPERBODY|AF_SECONDARY)
|
|
ELSE
|
|
TASK_PLAY_ANIM(PLAYER_PED_ID(), tlTaxiAnimDict, "FUCK_U", SLOW_BLEND_IN, REALLY_SLOW_BLEND_OUT, -1, AF_UPPERBODY|AF_SECONDARY)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF (GET_RANDOM_INT_IN_RANGE(0,5) = 1)
|
|
IF NOT (g_playerIsDrunk)
|
|
bPlayAdditionalFuckYouDialogue = TRUE
|
|
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "Played additional taxi fuck you dialogue ")
|
|
ENDIF
|
|
ENDIF
|
|
iTimer_HailAnimTriggered = GET_GAME_TIMER() // reset for fuck you dialogue
|
|
iTimer_HailFailedDialogueDelay = GET_GAME_TIMER() // dialogue delay
|
|
|
|
// B*1991223 - RESET need to block ambient anims during hail anims
|
|
IF bBlockingPlayerAmbientIdles = TRUE
|
|
SET_PED_CAN_PLAY_AMBIENT_ANIMS(PLAYER_PED_ID(), TRUE)
|
|
bBlockingPlayerAmbientIdles = FALSE
|
|
ENDIF
|
|
|
|
IF iTaxiHailIntention <> NEW_CONTEXT_INTENTION
|
|
RELEASE_CONTEXT_INTENTION(iTaxiHailIntention)
|
|
//SET_PED_CONFIG_FLAG(PLAYER_PED_ID(), PCF_KeepWeaponHolsteredUnlessFired, FALSE)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, "HAIL_TAXI_STATE_FAILED_ATTEMPT() - RELEASE_CONTEXT_INTENTION iTaxiHailIntention")
|
|
ENDIF
|
|
eHailTaxiState = TL_HAIL_TAXI_STATE_IDLE
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " HAIL_TAXI_STATE_FAILED_ATTEMPT() : eHailTaxiState = TL_HAIL_TAXI_STATE_IDLE") ENDIF #ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// handles taxi which is classed as waiting for the player
|
|
PROC HAIL_TAXI_STATE_TAXI_WAITING()
|
|
|
|
IF IS_TAXI_AND_DRIVER_OK_FOR_PLAYER_TO_ENTER_AS_PASSENGER(g_WaitingTaxi, g_WaitingTaxiDriver, mnTaxiModel, mnTaxiDriverModel)
|
|
|
|
IF NOT SHOULD_WAITING_TAXI_CLEANUP()
|
|
|
|
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
|
|
|
|
// B*1536974 - Press to enter taxi as passenger hold to jack driver - opposite to how it worked on IV
|
|
// to get IV behaviour you have to ensur this flag is false then task the player in script to enter as rear passenger when input detected
|
|
SET_PED_CONFIG_FLAG(g_WaitingTaxiDriver, PCF_AICanDrivePlayerAsRearPassenger, TRUE)
|
|
|
|
CLEAR_HINT_CAM_IF_PLAYER_IS_MOVING()
|
|
|
|
// taxi blip flash updated (if exists) could get here from entering nearby taxi
|
|
IF DOES_BLIP_EXIST(blipWaitingTaxi)
|
|
SET_BLIP_FLASH_TIMER(blipWaitingTaxi, 10000)
|
|
ENDIF
|
|
ELSE
|
|
CLEANUP_HAIL_TAXI()
|
|
ENDIF
|
|
ELSE
|
|
CLEANUP_HAIL_TAXI()
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// handles script task for the player getting in the taxi vehicleIndex
|
|
/// Sets eEnterTaxiState = TL_ENTER_TAXI_STATE_ENTERING when attempt has been made
|
|
/// NOTE: safe checks will have already been performed at this stage
|
|
PROC DETECT_PLAYER_ATTEMPT_TO_ENTER_TAXI()
|
|
|
|
IF IS_PLAYER_OK_TO_USE_ENTER_VEHICLE_TASK(vehClosestTaxi)
|
|
|
|
//IF NOT IS_ENTITY_UPRIGHT(vehIndexArray[i])
|
|
//OR IS_ENTITY_IN_WATER(vehIndexArray[i])
|
|
|
|
// if it's the hailed taxi pull up help text
|
|
IF NOT bHelpEnterTaxiDisplayed
|
|
// only show help if this is a taxi we have called / hailed
|
|
IF (vehClosestTaxi = g_WaitingTaxi)
|
|
AND eHailTaxiState = TL_HAIL_TAXI_STATE_TAXI_WAITING
|
|
IF NOT IS_HELP_MESSAGE_ON_SCREEN()
|
|
IF NOT IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("TX_H02") // Hold ~INPUT_ENTER~ to enter the cab as a passenger.
|
|
IF g_savedGlobals.sAmbient.iTaxiEnterPromptDisplayed < 5
|
|
PRINT_HELP("TX_H02") //Hold ~INPUT_ENTER~ to enter the cab as a passenger.
|
|
g_savedGlobals.sAmbient.iTaxiEnterPromptDisplayed++
|
|
ENDIF
|
|
bHelpEnterTaxiDisplayed = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
VEHICLE_INDEX vehTemp = GET_VEHICLE_PED_IS_ENTERING(PLAYER_PED_ID()) // this will return active task so when he's also pathing to the vehicle
|
|
|
|
// check for player getting into the taxi
|
|
IF DOES_ENTITY_EXIST(vehTemp)
|
|
IF (vehTemp = vehClosestTaxi)
|
|
|
|
// grab handle to the taxi driver
|
|
PED_INDEX pedIndex = GET_PED_IN_VEHICLE_SEAT(vehClosestTaxi) // all safe checks have already been performed in IS_PLAYER_OK_TO_ENTER_VEHICLE_AS_PASSENGER
|
|
|
|
// if this taxi isn't the current waiting taxi cleanup the hailed state
|
|
IF eHailTaxiState = TL_HAIL_TAXI_STATE_TAXI_WAITING
|
|
OR eHailTaxiState = TL_HAIL_TAXI_STATE_SUCCESSFUL_ATTEMPT
|
|
IF (vehClosestTaxi != g_WaitingTaxi)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : DETECT_PLAYER_ATTEMPT_TO_ENTER_TAXI reset eHailTaxiState for already inside a taxi which isn't g_WaitingTaxi")
|
|
CLEANUP_HAIL_TAXI()
|
|
ENDIF
|
|
ENDIF
|
|
|
|
DISABLE_SELECTOR_THIS_FRAME() // B*1559411 - block char switching whilst entering a taxi
|
|
|
|
//update handles g_WaitingTaxi = vehicleIndex, g_WaitingTaxiDriver = pedIndex
|
|
IF STORE_CAR_AS_TAXI_WAITING_FOR_PLAYER(vehClosestTaxi, pedIndex)
|
|
|
|
//release handle - don't do this since we can kick back here from enter failed
|
|
//vehClosestTaxi = NULL
|
|
|
|
IF bHintTriggeredByTaxiLauncher // B* 1478914 - stop hint cam when player getting in
|
|
IF IS_GAMEPLAY_HINT_ACTIVE()
|
|
STOP_GAMEPLAY_HINT()
|
|
ENDIF
|
|
bHintTriggeredByTaxiLauncher = FALSE
|
|
ENDIF
|
|
|
|
// just doing this when player is in seat now
|
|
//SET_PLAYER_GROUP_MEMBERS_INTO_TAXI(g_WaitingTaxi, ePlayerChosenSeat) // GET_GROUP_INTO_CAB(GET_NEAREST_PASSENGER_SIDE(g_WaitingTaxi))
|
|
|
|
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 TAXI_IS_PED_PERFORMING_TASK(g_WaitingTaxiDriver, SCRIPT_TASK_VEHICLE_TEMP_ACTION)
|
|
TASK_VEHICLE_TEMP_ACTION(g_WaitingTaxiDriver, g_WaitingTaxi, TEMPACT_WAIT, 10000)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
bHelpEnterTaxiDisplayed = FALSE
|
|
|
|
eEnterTaxiState = TL_ENTER_TAXI_STATE_ENTERING
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : DETECT_PLAYER_ATTEMPT_TO_ENTER_TAXI() : eEnterTaxiState = TL_ENTER_TAXI_STATE_ENTERING FC = ", GET_FRAME_COUNT())
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
// should'nt require any cleanup at this point
|
|
IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("TX_H02") // Hold ~INPUT_ENTER~ to enter the cab as a passenger.
|
|
CLEAR_HELP()
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// updates the player's script task to get into the taxi vehicleIndex
|
|
/// NOTE: safe checks will have already been performed at this stage
|
|
PROC UPDATE_PLAYER_ENTER_TAXI_TASK()
|
|
|
|
IF IS_PLAYER_OK_TO_USE_ENTER_VEHICLE_TASK(g_WaitingTaxi) // should only get tasked to enter g_waitingtaxi
|
|
|
|
VEHICLE_INDEX vehTemp = GET_VEHICLE_PED_IS_ENTERING(PLAYER_PED_ID()) // this will return active task so when he's also pathing to the vehicle
|
|
|
|
// check for player getting into the taxi
|
|
IF DOES_ENTITY_EXIST(vehTemp)
|
|
IF (vehTemp = vehClosestTaxi)
|
|
|
|
DISABLE_SELECTOR_THIS_FRAME() // B*1559411 - block char switching whilst entering a taxi
|
|
|
|
// make sure the driver waits until the player gets in
|
|
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 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
|
|
ELSE
|
|
eEnterTaxiState = TL_ENTER_TAXI_STATE_IDLE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : UPDATE_PLAYER_ENTER_TAXI_TASK reset to IS_PLAYER_OK_TO_USE_ENTER_VEHICLE_TASK player entering different vehicle check FC = ", GET_FRAME_COUNT())
|
|
ENDIF
|
|
ELSE
|
|
eEnterTaxiState = TL_ENTER_TAXI_STATE_IDLE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : UPDATE_PLAYER_ENTER_TAXI_TASK reset to IS_PLAYER_OK_TO_USE_ENTER_VEHICLE_TASK player not entering vehicle now check FC = ", GET_FRAME_COUNT())
|
|
ENDIF
|
|
ELSE
|
|
eEnterTaxiState = TL_ENTER_TAXI_STATE_IDLE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : UPDATE_PLAYER_ENTER_TAXI_TASK reset to IS_PLAYER_OK_TO_USE_ENTER_VEHICLE_TASK check FC = ", GET_FRAME_COUNT())
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// handle awaiting player attempt to enter a taxi state
|
|
PROC ENTER_TAXI_STATE_IDLE()
|
|
|
|
// don't process checks if the closest taxi hasn't been found
|
|
IF DOES_ENTITY_EXIST(vehClosestTaxi)
|
|
|
|
// make sure the taxi is suitable to get in
|
|
IF IS_PLAYER_OK_TO_ENTER_VEHICLE_AS_PASSENGER(vehClosestTaxi, mnTaxiModel, mnTaxiDriverModel)
|
|
|
|
// don't process checks if player is already in vehicle
|
|
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
|
|
|
|
// now Handles by UPDATE_TAXI_SEARCH_HANDLES()
|
|
//vehIndexTemp = GET_CLOSEST_VEHICLE(vPlayerPos, 10.0, TAXI, GET_TAXI_SEARCH_FLAGS())
|
|
|
|
// once detected enter taxi attempt g_WaitingTaxi and g_WaitingTaxiDriver handles are updated
|
|
DETECT_PLAYER_ATTEMPT_TO_ENTER_TAXI()
|
|
ELSE
|
|
IF IS_PED_SITTING_IN_ANY_VEHICLE(PLAYER_PED_ID())
|
|
// check the vehicle he's in isn't infact the taxi
|
|
IF IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), vehClosestTaxi)
|
|
//IF (GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID(), FALSE) = vehClosestTaxi)
|
|
|
|
// grab handle to the taxi driver
|
|
PED_INDEX pedIndex = GET_PED_IN_VEHICLE_SEAT(vehClosestTaxi) // all safe checks have already been performed in IS_PLAYER_OK_TO_ENTER_VEHICLE_AS_PASSENGER
|
|
|
|
// store the seat Player is in to task the group members to enter
|
|
IF NOT IS_VEHICLE_SEAT_FREE(vehClosestTaxi, VS_BACK_LEFT)
|
|
IF (GET_PED_IN_VEHICLE_SEAT(vehClosestTaxi, VS_BACK_LEFT) = PLAYER_PED_ID())
|
|
ePlayerChosenSeat = VS_BACK_LEFT
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ENTER_TAXI_STATE_IDLE player already sat in taxi seat VS_BACK_LEFT")
|
|
ENDIF
|
|
ENDIF
|
|
IF NOT IS_VEHICLE_SEAT_FREE(vehClosestTaxi, VS_BACK_RIGHT)
|
|
IF (GET_PED_IN_VEHICLE_SEAT(vehClosestTaxi, VS_BACK_RIGHT) = PLAYER_PED_ID())
|
|
ePlayerChosenSeat = VS_BACK_RIGHT
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ENTER_TAXI_STATE_IDLE player already sat in taxi seat VS_BACK_RIGHT")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// if this taxi isn't the current waiting taxi cleanup the hailed state
|
|
IF eHailTaxiState = TL_HAIL_TAXI_STATE_TAXI_WAITING
|
|
OR eHailTaxiState = TL_HAIL_TAXI_STATE_SUCCESSFUL_ATTEMPT
|
|
IF (vehClosestTaxi != g_WaitingTaxi)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ENTER_TAXI_STATE_IDLE reset eHailTaxiState for entering a veh which isn't g_WaitingTaxi")
|
|
CLEANUP_HAIL_TAXI()
|
|
ENDIF
|
|
ENDIF
|
|
|
|
DISABLE_SELECTOR_THIS_FRAME() // B*1559411 - block char switching whilst entering a taxi
|
|
|
|
//update handles g_WaitingTaxi = vehicleIndex, g_WaitingTaxiDriver = pedIndex
|
|
IF STORE_CAR_AS_TAXI_WAITING_FOR_PLAYER(vehClosestTaxi, pedIndex)
|
|
|
|
//release handle
|
|
vehClosestTaxi = NULL
|
|
|
|
eEnterTaxiState = TL_ENTER_TAXI_STATE_INSIDE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ENTER_TAXI_STATE_IDLE() : TL_ENTER_TAXI_STATE_IDLE -> TL_ENTER_TAXI_STATE_INSIDE FC = ", GET_FRAME_COUNT())
|
|
ENDIF
|
|
ELSE
|
|
// got in a vehicle which wasn't the closest taxi so cleanup
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ENTER_TAXI_STATE_IDLE() : cleanup for entering veh which wasn't vehClosestTaxi FC = ", GET_FRAME_COUNT())
|
|
CLEANUP_ENTER_CLOSEST_TAXI()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Player is process of entering taxi using scripted task
|
|
PROC ENTER_TAXI_STATE_ENTERING()
|
|
|
|
// make sure the vehicle the player has been tasks to enter is still ok
|
|
IF IS_PLAYER_OK_TO_ENTER_VEHICLE_AS_PASSENGER(g_WaitingTaxi, mnTaxiModel, mnTaxiDriverModel)
|
|
|
|
// check for the player making it into the taxi (IS_PLAYER_OK_TO_ENTER_VEHICLE_AS_PASSENGER checks driver if in driver seat)
|
|
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), g_WaitingTaxi)
|
|
IF IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), g_WaitingTaxi)
|
|
|
|
eEnterTaxiState = TL_ENTER_TAXI_STATE_INSIDE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ENTER_TAXI_STATE_ENTERING() : TL_ENTER_TAXI_STATE_ENTERING -> TL_ENTER_TAXI_STATE_INSIDE FC = ", GET_FRAME_COUNT())
|
|
ENDIF
|
|
DISABLE_SELECTOR_THIS_FRAME() // B*1559411 - block char switching whilst entering a taxi
|
|
ELSE
|
|
UPDATE_PLAYER_ENTER_TAXI_TASK()
|
|
ENDIF
|
|
ELSE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ENTER_TAXI_STATE_ENTERING() : cleanup for IS_PLAYER_OK_TO_USE_ENTER_VEHICLE_TASK check")
|
|
CLEANUP_ENTER_CLOSEST_TAXI()
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Player has successfully got in the back of a taxi - launche the taxiService.sc script
|
|
PROC ENTER_TAXI_STATE_INSIDE()
|
|
|
|
// make sure the vehicle the player has been tasks to enter is still ok
|
|
IF IS_PLAYER_OK_TO_ENTER_VEHICLE_AS_PASSENGER(g_WaitingTaxi, mnTaxiModel, mnTaxiDriverModel)
|
|
|
|
// check for the player making it into the taxi (IS_PLAYER_OK_TO_ENTER_VEHICLE_AS_PASSENGER checks driver if in driver seat)
|
|
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), g_WaitingTaxi)
|
|
IF IS_PED_SITTING_IN_VEHICLE(PLAYER_PED_ID(), g_WaitingTaxi)
|
|
|
|
DISABLE_SELECTOR_THIS_FRAME() // B*1559411 - block char switching whilst entering a taxi
|
|
|
|
// store the seat the player is in to task the group members
|
|
IF GET_PED_IN_VEHICLE_SEAT(g_WaitingTaxi, VS_BACK_LEFT) = PLAYER_PED_ID()
|
|
ePlayerChosenSeat = VS_BACK_LEFT
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ENTER_TAXI_STATE_INSIDE() : stored ePlayerChosenSeat = VS_BACK_LEFT")
|
|
ELSE
|
|
ePlayerChosenSeat = VS_BACK_RIGHT
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ENTER_TAXI_STATE_INSIDE() : stored ePlayerChosenSeat = VS_BACK_RIGHT but test only based of not being in back left seat")
|
|
ENDIF
|
|
|
|
SET_PLAYER_GROUP_MEMBERS_INTO_TAXI(g_WaitingTaxi, ePlayerChosenSeat) // GET_GROUP_INTO_CAB(GET_NEAREST_PASSENGER_SIDE(g_WaitingTaxi))
|
|
|
|
// make sure the driver waits until the script kicks in
|
|
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 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
|
|
|
|
// make sure any taxi on route to the player cleans up
|
|
CLEANUP_DISPATCHED_TAXI_DATA()
|
|
CLEANUP_HAIL_TAXI()
|
|
IF bHelpEnterTaxiDisplayed
|
|
IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("TX_H02") // Hold ~INPUT_ENTER~ to enter the cab as a passenger.
|
|
CLEAR_HELP()
|
|
ENDIF
|
|
bHelpEnterTaxiDisplayed = FALSE
|
|
ENDIF
|
|
NON_GROUPED_PASSENGERS_SHOULD_FLEE()
|
|
SET_JACKED_PED_TO_FLEE()
|
|
SET_PLAYER_CAN_DO_DRIVE_BY(PLAYER_ID(), FALSE)
|
|
|
|
// request the taxiService.sc script
|
|
REQUEST_SCRIPT("taxiService")
|
|
IF HAS_SCRIPT_LOADED("taxiService")
|
|
|
|
tTaxiServiceThread = START_NEW_SCRIPT("taxiService", SPECIAL_ABILITY_STACK_SIZE)
|
|
SET_SCRIPT_AS_NO_LONGER_NEEDED("taxiService")
|
|
|
|
eTaxiLauncherState = TL_STATE_PLAYER_IN_TAXI
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ENTER_TAXI_STATE_INSIDE() : TL_ENTER_TAXI_STATE_INSIDE launched taxiService.sc FC = ", GET_FRAME_COUNT())
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ENTER_TAXI_STATE_INSIDE() : player got out cab so RESET_TAXI_LAUNCHER() FC = ", GET_FRAME_COUNT())
|
|
RESET_TAXI_LAUNCHER()
|
|
ENDIF
|
|
ELSE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : ENTER_TAXI_STATE_INSIDE() : cleanup for IS_PLAYER_OK_TO_USE_ENTER_VEHICLE_TASK check FC = ", GET_FRAME_COUNT())
|
|
CLEANUP_ENTER_CLOSEST_TAXI()
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Check reasons to reset and cleanup the dispatched taxi
|
|
/// RETURNS:
|
|
/// TRUE if dispatched taxi should cleanup
|
|
FUNC BOOL SHOULD_DISPATCHED_TAXI_CLEANUP()
|
|
|
|
// check for player leaving area taxi was requested from if so clenup
|
|
IF NOT TAXI_IS_COORD_IN_RANGE_OF_COORD(vPlayerPos, sDispatchedTaxi.vPlayerCalledCoords, 100.0)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_DISPATCHED_TAXI_CLEANUP() : return TRUE : Player left area taxi requested from ")
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
// cleanup if player char has changed
|
|
IF GET_PLAYER_PED_ENUM(PLAYER_PED_ID()) <> sDispatchedTaxi.eCharDispatchedFor
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_DISPATCHED_TAXI_CLEANUP() : return TRUE : Player char changed ")
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
// cleanup if player has a waiting taxi
|
|
IF eHailTaxiState = TL_HAIL_TAXI_STATE_TAXI_WAITING
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_DISPATCHED_TAXI_CLEANUP() : return TRUE : eHailTaxiState = TL_HAIL_TAXI_STATE_TAXI_WAITING")
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
// stage specific checks
|
|
IF eDispatchedTaxiState = TL_DISPATCHED_STATE_DRIVE_TO_PICKUP_PLAYER
|
|
OR eDispatchedTaxiState = TL_DISPATCHED_STATE_PULL_OVER_TO_PICKUP_PLAYER
|
|
IF NOT IS_PED_UNINJURED(sDispatchedTaxi.pedIndex)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_DISPATCHED_TAXI_CLEANUP() : return TRUE : sDispatchedTaxi.pedIndex injured")
|
|
RETURN TRUE
|
|
ENDIF
|
|
IF NOT IS_VEHICLE_OK(sDispatchedTaxi.vehicleIndex)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_DISPATCHED_TAXI_CLEANUP() : return TRUE : sDispatchedTaxi.vehicleIndex veh wrecked")
|
|
RETURN TRUE
|
|
ENDIF
|
|
// driver no longer in the taxi
|
|
IF NOT IS_PED_SITTING_IN_VEHICLE(sDispatchedTaxi.pedIndex, sDispatchedTaxi.vehicleIndex)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_DISPATCHED_TAXI_CLEANUP() : return TRUE : sDispatchedTaxi.pedIndex not sat in DispatchedTaxi.vehicleIndex")
|
|
RETURN TRUE
|
|
ENDIF
|
|
IF IS_PED_FLEEING(sDispatchedTaxi.pedIndex)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_DISPATCHED_TAXI_CLEANUP() : return TRUE : sDispatchedTaxi.pedIndex is fleeing")
|
|
RETURN TRUE
|
|
ENDIF
|
|
IF IS_PED_IN_COMBAT(sDispatchedTaxi.pedIndex)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_DISPATCHED_TAXI_CLEANUP() : return TRUE : sDispatchedTaxi.pedIndex is in combat")
|
|
RETURN TRUE
|
|
ENDIF
|
|
// player attacked taxi
|
|
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(sDispatchedTaxi.vehicleIndex, PLAYER_PED_ID())
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_DISPATCHED_TAXI_CLEANUP : return TRUE : damaged taxi check")
|
|
RETURN TRUE
|
|
ENDIF
|
|
IF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(sDispatchedTaxi.pedIndex, PLAYER_PED_ID())
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_DISPATCHED_TAXI_CLEANUP : return TRUE : damaged taxi driver check")
|
|
RETURN TRUE
|
|
ENDIF
|
|
VECTOR vTaxiCoords = GET_ENTITY_COORDS(sDispatchedTaxi.vehicleIndex, FALSE)
|
|
|
|
// bullet fired near taxi
|
|
IF IS_BULLET_IN_AREA(vTaxiCoords, 7.0, FALSE)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_DISPATCHED_TAXI_CLEANUP : 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_DISPATCHED_TAXI_CLEANUP : return TRUE : projectile near taxi")
|
|
RETURN TRUE
|
|
ENDIF
|
|
IF TAXI_IS_COORD_IN_RANGE_OF_COORD(vPlayerPos, vTaxiCoords, 20.0)
|
|
|
|
// aiming at the taxi
|
|
IF IS_PLAYER_FREE_AIMING_AT_ENTITY(PLAYER_ID(), sDispatchedTaxi.vehicleIndex)
|
|
OR IS_PLAYER_TARGETTING_ENTITY(PLAYER_ID(), sDispatchedTaxi.vehicleIndex)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_DISPATCHED_TAXI_CLEANUP : return TRUE : aiming at the taxi")
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
// check for player shooting near waiting taxi
|
|
IF IS_PED_SHOOTING(PLAYER_PED_ID())
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : SHOULD_DISPATCHED_TAXI_CLEANUP : return TRUE : player shooting check")
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// handles the player calling for a taxi and it arriving to pick him up
|
|
PROC PROCESS_TAXI_PHONECALLS()
|
|
|
|
// Player starts by calling the taxi firm
|
|
IF eCallTaxiServiceState = TL_PHONE_STATE_AWAITING_CALL
|
|
|
|
IF IS_CALLING_CONTACT(CHAR_TAXI)
|
|
#IF IS_DEBUG_BUILD OR bDebug_CallCab #ENDIF
|
|
IF IS_TAXI_SERVICE_LISTED_IN_PLAYERS_PHONEBOOK(GET_CURRENT_PLAYER_PED_ENUM())
|
|
IDENTIFY_PLAYER()
|
|
ADD_PED_FOR_DIALOGUE(phonecallStruct, 0, PLAYER_PED_ID(), playerVoice)
|
|
ADD_PED_FOR_DIALOGUE(phonecallStruct, 1, NULL, "TaxiDispatch")
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " IS_CALLING_CONTACT(CHAR_TAXI)")
|
|
|
|
IF IS_PLAYER_ALLOWED_TO_CALL_TAXI()
|
|
|
|
// #if USE_TU_CHANGES
|
|
// IF IS_CURRENT_MISSION_DLC() //Added by Steve T to make taxi calls DLC compliant. 06.02.14
|
|
//
|
|
// IF PLAYER_CALL_CHAR_CELLPHONE_MULTIPART_WITH_3_LINES_USING_V_CONTENT_IN_DLC(phonecallStruct, CHAR_TAXI, "TAXISAU", playerLine1, playerLine1, "TX_2", "TX_2", playerLine3, playerLine3, CONV_PRIORITY_NON_CRITICAL_CALL)
|
|
// #IF IS_DEBUG_BUILD OR bDebug_CallCab #ENDIF
|
|
// bPhonecallReachedSuccessfulLine = FALSE
|
|
// eCallTaxiServiceState = TL_PHONE_STATE_CALL_IN_PROGRESS
|
|
// CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "PROCESS_TAXI_PHONECALLS : TL_PHONE_STATE_AWAITING_CALL -> TL_PHONE_STATE_CALL_IN_PROGRESS : using ",
|
|
// " FirstRootLabel = ", playerLine1, " FirstSpecificLabel = ", playerLine1, " SecondRootLabel = TX_2 ", " SecondSpecificLabel = TX_2",
|
|
// " ThirdRootLabel = ", playerLine3, " ThirdSpecificLabel = ", playerLine3)
|
|
// ENDIF
|
|
//
|
|
// ELSE
|
|
// #endif
|
|
|
|
IF PLAYER_CALL_CHAR_CELLPHONE_MULTIPART_WITH_3_LINES(phonecallStruct, CHAR_TAXI, "TAXISAU", playerLine1, playerLine1, "TX_2", "TX_2", playerLine3, playerLine3, CONV_PRIORITY_NON_CRITICAL_CALL)
|
|
#IF IS_DEBUG_BUILD OR bDebug_CallCab #ENDIF
|
|
bPhonecallReachedSuccessfulLine = FALSE
|
|
eCallTaxiServiceState = TL_PHONE_STATE_CALL_IN_PROGRESS
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "PROCESS_TAXI_PHONECALLS : TL_PHONE_STATE_AWAITING_CALL -> TL_PHONE_STATE_CALL_IN_PROGRESS : using ",
|
|
" FirstRootLabel = ", playerLine1, " FirstSpecificLabel = ", playerLine1, " SecondRootLabel = TX_2 ", " SecondSpecificLabel = TX_2",
|
|
" ThirdRootLabel = ", playerLine3, " ThirdSpecificLabel = ", playerLine3)
|
|
ENDIF
|
|
|
|
// #if USE_TU_CHANGES
|
|
// ENDIF
|
|
// #endif
|
|
|
|
|
|
ELSE
|
|
|
|
// #if USE_TU_CHANGES
|
|
// IF IS_CURRENT_MISSION_DLC() //Added by Steve T to make taxi calls DLC compliant. 06.02.14
|
|
//
|
|
// IF PLAYER_CALL_CHAR_CELLPHONE_MULTIPART_WITH_2_LINES_USING_V_CONTENT_IN_DLC(phonecallStruct, CHAR_TAXI, "TAXISAU", playerLine1, playerLine1, "TX_2A", "TX_2A", CONV_PRIORITY_NON_CRITICAL_CALL)
|
|
// eCallTaxiServiceState = TL_PHONE_STATE_WAIT_TO_RESET_CALL
|
|
// CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "PROCESS_TAXI_PHONECALLS : TL_PHONE_STATE_AWAITING_CALL -> TL_PHONE_STATE_WAIT_TO_RESET_CALL : using ",
|
|
// " FirstRootLabel = ", playerLine1, " FirstSpecificLabel = ", playerLine1, " SecondRootLabel = TX_2A ", " SecondSpecificLabel = TX_2A")
|
|
// ENDIF
|
|
//
|
|
// ELSE
|
|
// #endif
|
|
|
|
IF PLAYER_CALL_CHAR_CELLPHONE_MULTIPART_WITH_2_LINES(phonecallStruct, CHAR_TAXI, "TAXISAU", playerLine1, playerLine1, "TX_2A", "TX_2A", CONV_PRIORITY_NON_CRITICAL_CALL)
|
|
eCallTaxiServiceState = TL_PHONE_STATE_WAIT_TO_RESET_CALL
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "PROCESS_TAXI_PHONECALLS : TL_PHONE_STATE_AWAITING_CALL -> TL_PHONE_STATE_WAIT_TO_RESET_CALL : using ",
|
|
" FirstRootLabel = ", playerLine1, " FirstSpecificLabel = ", playerLine1, " SecondRootLabel = TX_2A ", " SecondSpecificLabel = TX_2A")
|
|
ENDIF
|
|
|
|
// #if USE_TU_CHANGES
|
|
// ENDIF
|
|
// #endif
|
|
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// state to wait in until an unsuccessful call for a taxi has finished
|
|
ELIF eCallTaxiServiceState = TL_PHONE_STATE_WAIT_TO_RESET_CALL
|
|
|
|
IF HAS_CELLPHONE_CALL_FINISHED()
|
|
eCallTaxiServiceState = TL_PHONE_STATE_AWAITING_CALL
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "PROCESS_TAXI_PHONECALLS : TL_PHONE_STATE_WAIT_TO_RESET_CALL -> TL_PHONE_STATE_AWAITING_CALL")
|
|
ENDIF
|
|
|
|
// successful call to order a taxi
|
|
ELIF eCallTaxiServiceState = TL_PHONE_STATE_CALL_IN_PROGRESS
|
|
|
|
IF HAS_CELLPHONE_CALL_FINISHED()
|
|
|
|
// check for player hanging up before phnecall finished
|
|
IF WAS_LAST_CELLPHONE_CALL_INTERRUPTED()
|
|
|
|
// if phonecall reached successful line allow register as successful call anyway
|
|
IF NOT bPhonecallReachedSuccessfulLine
|
|
eCallTaxiServiceState = TL_PHONE_STATE_AWAITING_CALL
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "PROCESS_TAXI_PHONECALLS : TL_PHONE_STATE_CALL_IN_PROGRESS -> TL_PHONE_STATE_AWAITING_CALL : WAS_LAST_CELLPHONE_CALL_INTERRUPTED()")
|
|
ENDIF
|
|
|
|
// check if the player receives an injury or starts ragdolling then during the phonecall
|
|
ELIF HAS_CELLPHONE_JUST_BEEN_FORCED_AWAY()
|
|
|
|
// if phonecall reached successful line allow register as successful call anyway
|
|
IF NOT bPhonecallReachedSuccessfulLine
|
|
eCallTaxiServiceState = TL_PHONE_STATE_AWAITING_CALL
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "PROCESS_TAXI_PHONECALLS : TL_PHONE_STATE_CALL_IN_PROGRESS -> TL_PHONE_STATE_AWAITING_CALL : HAS_CELLPHONE_JUST_BEEN_FORCED_AWAY()")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// successful phonecall
|
|
IF eCallTaxiServiceState != TL_PHONE_STATE_AWAITING_CALL
|
|
|
|
IF NOT HAS_ONE_TIME_HELP_DISPLAYED(FHM_TAXI_PHONE_INTRODUCED)
|
|
SET_ONE_TIME_HELP_MESSAGE_DISPLAYED(FHM_TAXI_PHONE_INTRODUCED)
|
|
ENDIF
|
|
|
|
CLEANUP_DISPATCHED_TAXI_DATA()
|
|
sDispatchedTaxi.iTimer_TaxiDispatchDelay = GET_GAME_TIMER() // set timer ready for delay
|
|
sDispatchedTaxi.vPlayerCalledCoords = vPlayerPos // set position player is when call was processed
|
|
sDispatchedTaxi.eCharDispatchedFor = GET_PLAYER_PED_ENUM(PLAYER_PED_ID()) // store which ped we are dispatched for
|
|
sDispatchedTaxi.iNodeSearchNumber = 0 // set ready for creation node checks
|
|
sDispatchedTaxi.iSpawnAttempts = 0 // set ready for creation checks
|
|
|
|
// set the dispatched taxi state running
|
|
eDispatchedTaxiState = TL_DISPATCHED_STATE_CREATE_TAXI
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "PROCESS_TAXI_PHONECALLS : eDispatchedTaxiState = TL_DISPATCHED_STATE_CREATE_TAXI")
|
|
|
|
eCallTaxiServiceState = TL_PHONE_STATE_AWAITING_CALL
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "PROCESS_TAXI_PHONECALLS : TL_PHONE_STATE_CALL_IN_PROGRESS -> TL_PHONE_STATE_AWAITING_CALL : dispatched taxi")
|
|
ENDIF
|
|
ELSE
|
|
// register when we've reached the positive response line to set call as successful
|
|
IF NOT bPhonecallReachedSuccessfulLine
|
|
// info from Steven - If audio added SFX pauses at a later date it may screw up your logic.
|
|
// Unfortunately GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_ROOT() & GET_CURRENTLY_PLAYING_STANDARD_CONVERSATION_LABEL() don't work for this
|
|
IF GET_CURRENT_SCRIPTED_CONVERSATION_LINE() = 1
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), "PROCESS_TAXI_PHONECALLS : TL_PHONE_STATE_CALL_IN_PROGRESS : reached successful call line > 2 TX_2 : ")
|
|
bPhonecallReachedSuccessfulLine = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// we now have to maintain some checks everyframe the player is not in a taxi
|
|
PROC PROCESS_EVERYFRAME_NOT_IN_TAXI_UPDATES()
|
|
|
|
// B*2074743 - need to call the aim blocking everyframe the hail animation is active
|
|
IF eHailTaxiState = TL_HAIL_TAXI_STATE_SUCCESSFUL_ATTEMPT
|
|
OR eHailTaxiState = TL_HAIL_TAXI_STATE_FAILED_ATTEMPT
|
|
IF IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), tlTaxiAnimDict, "HAIL_TAXI")
|
|
OR IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), tlTaxiAnimDict, "FP_HAIL_TAXI")
|
|
DISABLE_PLAYER_WEAPON_CONTROLS_FOR_HAIL_THIS_FRAME()
|
|
ENDIF
|
|
ENDIF
|
|
//CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : PROCESS_EVERYFRAME_NOT_IN_TAXI_UPDATES hit this frame: ", GET_FRAME_COUNT())
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// handles creating the dispatched taxi and navigating it to the player
|
|
PROC PROCESS_DISPATCHED_TAXI()
|
|
|
|
// Check reasons to reset and cleanup the dispatched taxi
|
|
IF eDispatchedTaxiState != TL_DISPATCHED_STATE_IDLE
|
|
IF SHOULD_DISPATCHED_TAXI_CLEANUP()
|
|
CLEANUP_DISPATCHED_TAXI_DATA()
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " PROCESS_DISPATCHED_TAXI() : CLEANUP_DISPATCHED_TAXI_DATA()")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// state where the script will wait until a request to dispatch a taxi has been processed
|
|
IF eDispatchedTaxiState = TL_DISPATCHED_STATE_IDLE
|
|
|
|
// create a taxi to go over to the player
|
|
ELIF eDispatchedTaxiState = TL_DISPATCHED_STATE_CREATE_TAXI
|
|
DISPATCHED_STATE_CREATE_TAXI()
|
|
|
|
// handle driving the taxi over to the player
|
|
ELIF eDispatchedTaxiState = TL_DISPATCHED_STATE_DRIVE_TO_PICKUP_PLAYER
|
|
DISPATCHED_STATE_DRIVE_TO_PICKUP_PLAYER()
|
|
|
|
// make the taxi pull over to pickup the player
|
|
ELIF eDispatchedTaxiState = TL_DISPATCHED_STATE_PULL_OVER_TO_PICKUP_PLAYER
|
|
DISPATCHED_STATE_PULL_OVER_TO_PICKUP_PLAYER()
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// handles the player hailing taxis
|
|
PROC PROCESS_PLAYER_HAILING_TAXI()
|
|
|
|
// state to wait until a hail target has been found by UPDATE_TAXI_SEARCH_HANDLES
|
|
IF eHailTaxiState = TL_HAIL_TAXI_STATE_IDLE
|
|
IF DOES_ENTITY_EXIST(vehHailTarget)
|
|
eHailTaxiState = TL_HAIL_TAXI_STATE_DETECT_HAIL
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " PROCESS_PLAYER_HAILING_TAXI() : TL_HAIL_TAXI_STATE_IDLE -> TL_HAIL_TAXI_STATE_DETECT_HAIL") ENDIF #ENDIF
|
|
ENDIF
|
|
|
|
// waiting to for player to attempt to hail a taxi
|
|
ELIF eHailTaxiState = TL_HAIL_TAXI_STATE_DETECT_HAIL
|
|
HAIL_STATE_DETECT_HAIL()
|
|
|
|
// taxi driver responses - gestures player to get in
|
|
ELIF eHailTaxiState = TL_HAIL_TAXI_STATE_SUCCESSFUL_ATTEMPT
|
|
HAIL_TAXI_STATE_SUCCESSFUL_ATTEMPT()
|
|
|
|
// player aknowledges failed attempt
|
|
ELIF eHailTaxiState = TL_HAIL_TAXI_STATE_FAILED_ATTEMPT
|
|
HAIL_TAXI_STATE_FAILED_ATTEMPT()
|
|
|
|
// Taxi is classed a waiting (blipped up waits for player to enter)
|
|
ELIF eHailTaxiState = TL_HAIL_TAXI_STATE_TAXI_WAITING
|
|
HAIL_TAXI_STATE_TAXI_WAITING()
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// handles the player getting into the back of the closest taxi
|
|
PROC PROCESS_PLAYER_ENTER_CLOSEST_TAXI()
|
|
|
|
// Waiting to detect player attempt to enter a taxi
|
|
IF eEnterTaxiState = TL_ENTER_TAXI_STATE_IDLE
|
|
ENTER_TAXI_STATE_IDLE()
|
|
|
|
// Player has been tasked to enter the Taxi, wait to see if he gets in
|
|
ELIF eEnterTaxiState = TL_ENTER_TAXI_STATE_ENTERING
|
|
ENTER_TAXI_STATE_ENTERING()
|
|
|
|
// Player is in the back of the taxi - launch the taxiService.sc script
|
|
ELIF eEnterTaxiState = TL_ENTER_TAXI_STATE_INSIDE
|
|
ENTER_TAXI_STATE_INSIDE()
|
|
|
|
// State waiting until player left the taxi
|
|
ELIF eEnterTaxiState = TL_ENTER_TAXI_STATE_WAIT_FOR_PLAYER_TO_EXIT
|
|
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
|
|
eEnterTaxiState = TL_ENTER_TAXI_STATE_IDLE
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " PROCESS_PLAYER_ENTER_CLOSEST_TAXI() : TL_ENTER_TAXI_STATE_WAIT_FOR_PLAYER_TO_EXIT -> TL_ENTER_TAXI_STATE_IDLE : FC = ", GET_FRAME_COUNT()) ENDIF #ENDIF
|
|
ELSE
|
|
#IF IS_DEBUG_BUILD IF bDebug_DisplayInfo CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " PROCESS_PLAYER_ENTER_CLOSEST_TAXI() : TL_ENTER_TAXI_STATE_WAIT_FOR_PLAYER_TO_EXIT waiting for player to leave veh : FC = ", GET_FRAME_COUNT()) ENDIF #ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
SCRIPT
|
|
|
|
IF HAS_FORCE_CLEANUP_OCCURRED(FORCE_CLEANUP_FLAG_SP_TO_MP|FORCE_CLEANUP_FLAG_MAGDEMO)
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : force cleanup occured, script set to terminate")
|
|
TAXI_LAUNCHER_SCRIPT_CLEANUP()
|
|
TERMINATE_THIS_THREAD()
|
|
ENDIF
|
|
|
|
#IF IS_DEBUG_BUILD DEBUG_SETUP_WIDGETS() #ENDIF
|
|
//#IF IS_DEBUG_BUILD DEBUG_SETUP_AREAS_WIDGETS() #ENDIF
|
|
|
|
g_savedGlobals.sAmbient.bTaxiHailingHelpDisplayed = TRUE
|
|
|
|
WHILE TRUE
|
|
|
|
SWITCH eTaxiLauncherState
|
|
|
|
// State where the launch will wait until it's safe to run
|
|
CASE TL_STATE_IDLE
|
|
|
|
IF IS_TAXI_SERVICE_SAFE_TO_RUN()
|
|
eTaxiLauncherState = TL_STATE_PLAYER_NOT_IN_TAXI
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : TL_STATE_IDLE -> TL_STATE_PLAYER_NOT_IN_TAXI")
|
|
ELSE
|
|
WAIT(500)
|
|
ENDIF
|
|
BREAK
|
|
|
|
// State where player can use a taxi
|
|
CASE TL_STATE_PLAYER_NOT_IN_TAXI
|
|
|
|
IF IS_TAXI_SERVICE_SAFE_TO_RUN()
|
|
// used multiple times so only grabbed once per frame, injured status is tested in IS_TAXI_SERVICE_SAFE_TO_RUN
|
|
vPlayerPos = GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE)
|
|
|
|
PROCESS_TAXI_PHONECALLS()
|
|
|
|
IF IS_PLAYER_ALLOWED_TO_ENTER_TAXI_AS_PASSENGER()
|
|
SET_VEHICLE_MODEL_IS_SUPPRESSED(TAXI, FALSE)
|
|
|
|
// We now have first instance of something which needs to be maintained everyframe
|
|
PROCESS_EVERYFRAME_NOT_IN_TAXI_UPDATES()
|
|
|
|
// optimisation - only process funcs if handles weren't updated this frame
|
|
IF NOT ALT_UPDATE_TAXI_SEARCH_HANDLES()
|
|
PROCESS_DISPATCHED_TAXI()
|
|
PROCESS_PLAYER_HAILING_TAXI()
|
|
PROCESS_PLAYER_ENTER_CLOSEST_TAXI()
|
|
ENDIF
|
|
ELSE
|
|
RESET_TAXI_LAUNCHER(FALSE)
|
|
eTaxiLauncherState = TL_STATE_PLAYER_NOT_IN_TAXI // esure we remain in this launcher state
|
|
UPDATE_PLAYER_ALLOWED_TO_RIDE_IN_TAXIS_STATUS()
|
|
WAIT(500)
|
|
ENDIF
|
|
ELSE
|
|
RESET_TAXI_LAUNCHER()
|
|
eTaxiLauncherState = TL_STATE_IDLE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : TL_STATE_PLAYER_NOT_IN_TAXI -> TL_STATE_IDLE")
|
|
ENDIF
|
|
BREAK
|
|
|
|
// State where TaxiService.sc has been launched and we await the script terminating
|
|
CASE TL_STATE_PLAYER_IN_TAXI
|
|
|
|
IF NOT IS_THREAD_ACTIVE(tTaxiServiceThread)
|
|
RESET_TAXI_LAUNCHER()
|
|
// because the taxiService script can terminate before player is completely out the taxi - wait to recheck
|
|
eEnterTaxiState = TL_ENTER_TAXI_STATE_WAIT_FOR_PLAYER_TO_EXIT
|
|
|
|
eTaxiLauncherState = TL_STATE_IDLE
|
|
CPRINTLN(DEBUG_TAXI_SERVICE, GET_THIS_SCRIPT_NAME(), " : TL_STATE_PLAYER_IN_TAXI -> TL_STATE_IDLE")
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
#IF IS_DEBUG_BUILD DEBUG_UPDATE_WIDGETS() #ENDIF
|
|
//#IF IS_DEBUG_BUILD DEBUG_UPDATE_AREA_WIDGETS() #ENDIF
|
|
|
|
WAIT(0)
|
|
|
|
ENDWHILE
|
|
|
|
ENDSCRIPT
|