4326 lines
143 KiB
Scheme
Executable File
4326 lines
143 KiB
Scheme
Executable File
// *****************************************************************************************
|
|
// *****************************************************************************************
|
|
//
|
|
// MISSION NAME : carwash_shared.sch
|
|
// AUTHOR : Aaron Gandaa
|
|
// DESCRIPTION : Car Wash Shared Structs and Functions
|
|
//
|
|
// *****************************************************************************************
|
|
// *****************************************************************************************
|
|
|
|
//----------------------
|
|
// INCLUDES
|
|
//----------------------
|
|
USING "rgeneral_include.sch"
|
|
USING "RC_Helper_Functions.sch"
|
|
USING "RC_Asset_Public.sch"
|
|
USING "RC_Camera_Public.sch"
|
|
USING "cost_halo.sch"
|
|
USING "net_ambience.sch"
|
|
USING "net_cash_transactions.sch"
|
|
USING "commands_volume.sch"
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
USING "shared_debug.sch"
|
|
#ENDIF
|
|
|
|
//----------------------
|
|
// ENUM
|
|
//----------------------
|
|
ENUM eCarwashAreaState
|
|
ECA_NULL,
|
|
ECA_ENTERED_AREA,
|
|
ECA_INAREA,
|
|
ECA_EXITED_AREA
|
|
ENDENUM
|
|
|
|
ENUM CARWASH_PARTSTATE
|
|
CPS_NULL,
|
|
CPS_STARTUP,
|
|
CPS_WARMUP,
|
|
CPS_ACTIVE,
|
|
CPS_WARMDOWN,
|
|
CPS_SHUTDOWN,
|
|
CPS_FINISHED
|
|
ENDENUM
|
|
|
|
ENUM CARWASH_LOCATIONID
|
|
CARWASH_LOCID_LONG = 1,
|
|
CARWASH_LOCID_SHORT = 2
|
|
ENDENUM
|
|
|
|
//----------------------
|
|
// CONSTANTS
|
|
//---------------------
|
|
CONST_FLOAT CAR_WASH_ACTIVE_RANGE 90.0
|
|
CONST_FLOAT ROLLER_RADIUS 0.55
|
|
CONST_FLOAT ROLLER_SPINRATE 360.0
|
|
CONST_FLOAT VROLLER_CHECKDIFF 0.95
|
|
CONST_FLOAT VROLLER_ZSHIFT 1.5
|
|
CONST_FLOAT VROLLER_CHECKZSHIFT 0.5
|
|
CONST_FLOAT DEFAULT_DUALVROLL_SEP 3.75 // 4.0
|
|
CONST_INT COST_CARWASH 15
|
|
|
|
CONST_FLOAT VROLLER_SEP 1.75 //0.825
|
|
CONST_FLOAT AUTODRIVE_TOLERANCE 30.0
|
|
CONST_FLOAT JET_TRIGGER_DIST 0.6
|
|
CONST_FLOAT ROLLER_TRIGGER_DIST 1.25
|
|
|
|
CONST_INT CAMERASTATE_LASTCAMERA 98
|
|
CONST_INT CAMERASTATE_ALLDONE 99
|
|
|
|
CONST_INT CARWASH_AXIS_X 0
|
|
CONST_INT CARWASH_AXIS_Y 0
|
|
|
|
INT ROLLER_CHECK_INTERVAL = 125
|
|
INT SHAPE_CHECK_INTERVAL = 128
|
|
CONST_INT BLOCKED_SHAPE_CHECK_INTERVAL 250
|
|
FLOAT ROLLER_SHIFT_FACTOR = 0.625
|
|
|
|
//----------------------
|
|
// STRUCT
|
|
//----------------------
|
|
STRUCT CARWASH_CAMERA
|
|
BOOL bSetup = FALSE
|
|
VECTOR vPosition[2]
|
|
VECTOR vRotation[2]
|
|
INT iInterpTime = 0
|
|
FLOAT fFov
|
|
|
|
CAMERA_INDEX cameraID
|
|
ENDSTRUCT
|
|
|
|
STRUCT CARWASH_VROLLER2
|
|
BOOL bSetup = FALSE
|
|
OBJECT_INDEX pivotID
|
|
CARWASH_PARTSTATE state
|
|
|
|
OBJECT_INDEX rollerID[2]
|
|
PTFX_ID fxBrushID[2]
|
|
FLOAT fOffset[2]
|
|
FLOAT fTgtOffset[2]
|
|
|
|
FLOAT fRollerSpinAngle = 0.0
|
|
FLOAT fSpinRate = 0.0
|
|
FLOAT fMoveRate = 1.0 // rate the brush moves in meters per second
|
|
|
|
FLOAT fSensorOffset[2] // this is how far away from the center the sensors are
|
|
FLOAT fSensorRadius[2]
|
|
VECTOR vBasePosition
|
|
|
|
INT iSpinSoundID = -1
|
|
INT iMoveSoundID = -1
|
|
INT iHitSoundID = -1
|
|
|
|
FLOAT fOriginalSep
|
|
BOOL bCollisionOn = TRUE
|
|
BOOL bOldCollision
|
|
BOOL bSensorOn[2]
|
|
|
|
SHAPETEST_INDEX shapeTestID
|
|
VEHICLE_INDEX activeVehicle
|
|
SHAPETEST_INDEX brushShapeTestID[2]
|
|
INT iNextBrushShapeTestTime[2]
|
|
|
|
INT iNextShapeTestTime
|
|
|
|
FLOAT fShutDownMoveRate = 0.3
|
|
BOOL bHitCheck[2]
|
|
BOOL bOldHitCheck[2]
|
|
ENDSTRUCT
|
|
|
|
STRUCT CARWASH_JETS
|
|
BOOL bSetup = FALSE
|
|
BOOL bSteam = FALSE
|
|
|
|
CARWASH_PARTSTATE state
|
|
OBJECT_INDEX pivotID
|
|
|
|
INT iNextCheckTime
|
|
INT iSoundID = -1
|
|
INT iSplashSoundID = -1
|
|
|
|
FLOAT fTriggerDist
|
|
FLOAT fSeperation = 0.0
|
|
FLOAT fHeight = 0.0
|
|
|
|
VECTOR vBasePos
|
|
STRING sJetName
|
|
PTFX_ID fxJets[4]
|
|
|
|
SHAPETEST_INDEX shapeTestID
|
|
INT iNextShapeTestTime
|
|
ENDSTRUCT
|
|
|
|
STRUCT CARWASH_HROLLER
|
|
CARWASH_PARTSTATE state
|
|
BOOL bSetup = FALSE
|
|
VECTOR vPosition // this is the position of the roller when it starts
|
|
VECTOR vContactPoint // this is the contact point for the line test, the brush should be ROLLER_RADIUS m above this
|
|
VECTOR vOldRollerPos
|
|
|
|
FLOAT fRollerPivotAngle = 0.0
|
|
FLOAT fRollerSpinAngle = 0.0
|
|
FLOAT fSpinRate = 0.0
|
|
FLOAT fMoveRate = 2.5 // rate the brush moves in meters per second
|
|
FLOAT fTriggerDist
|
|
|
|
INT iSpinSoundID = -1
|
|
INT iMoveSoundID = -1
|
|
INT iHitSoundID = -1
|
|
|
|
OBJECT_INDEX rollerID
|
|
SHAPETEST_INDEX shapeTestID
|
|
PTFX_ID fxBrushID
|
|
|
|
FLOAT fGroundZero = 0.0 // this is the z height of floor when the carwash is empty
|
|
FLOAT fTargetZ = 0.0
|
|
FLOAT fOriginalZ = 0.0
|
|
|
|
INT iNextCheckTime
|
|
INT iNextShapeTestTime
|
|
ENDSTRUCT
|
|
|
|
STRUCT CARWASH_TRACK
|
|
VECTOR vTrackPoint[2]
|
|
VECTOR vBlockMinMax[2]
|
|
VECTOR vBlockPoint[2]
|
|
VECTOR vVehicleSnapPoint
|
|
FLOAT fTrackHeading
|
|
FLOAT fTrackInterpolate = 0.0
|
|
VECTOR vDirection
|
|
INT iDominantBlockAxis
|
|
ENDSTRUCT
|
|
|
|
STRUCT CARWASH_HANDLER
|
|
CARWASH_TRACK cTrack
|
|
|
|
CARWASH_JETS soapJets
|
|
CARWASH_JETS waterJets
|
|
CARWASH_JETS steamJets
|
|
CARWASH_HROLLER horzRoller
|
|
CARWASH_VROLLER2 vertRoller
|
|
CAMERA_STRUCT carWashCamera[7]
|
|
|
|
BUILDING_NAME_ENUM iplSwap
|
|
STRING sWayPointRec
|
|
FLOAT fForwardSpeed = 1.5
|
|
FLOAT fBoostSpeed
|
|
FLOAT fFinalCameraInterpolate = 0.8 // when we get to here
|
|
|
|
INT iCurrentCameraState = 0
|
|
CAMERA_INDEX cameraID
|
|
|
|
BOOL bTimerStarted = FALSE
|
|
BOOL bTallVehicle
|
|
BOOL bThrottleBoosted
|
|
BOOL bSkipped = FALSE
|
|
BOOL bIsAllowedInMP = FALSE
|
|
INT iNextBlockCheckTime
|
|
INT iLastTimeUsed = 0
|
|
|
|
SHAPETEST_INDEX shapeTestID
|
|
INT iBlockCounts = 0
|
|
INT iTaskSequenceSize = 0 // NUMBER OF TASKS IN SEQUENCE
|
|
|
|
CARWASH_LOCATIONID iLocationID = CARWASH_LOCID_LONG
|
|
|
|
VECTOR vNoPedWalkMin
|
|
VECTOR vNoPedWalkMax
|
|
BOOL bCarwashAborted = FALSE
|
|
BOOL bBackInterruptCheck = FALSE
|
|
BOOL bOldUpdateCheck = FALSE
|
|
INT iAutoAbortTimer // if the time gets bigger than this automatically exit as something has gone wrong
|
|
TIME_DATATYPE iAutoAbortTimerMP //
|
|
ENDSTRUCT
|
|
|
|
//----------------------
|
|
// VARIABLES
|
|
//----------------------
|
|
VECTOR vRollerRadius = <<0, 0, ROLLER_RADIUS * 1.1>>
|
|
BOOL bDrawDebugCarwash = FALSE
|
|
VECTOR vRollerVertPosFX = <<0, 0, -1.125>>
|
|
VECTOR vRollerVertRotFX = <<0, 0, 0>>
|
|
VECTOR vRollerHorzRotFX = <<0, 90, 0>>
|
|
VECTOR vJetRotFX = <<90, 90, 0>>
|
|
VECTOR vSteamRotFX = <<0, 0, 0>>
|
|
VECTOR vSteamPosFX = <<0, 0.1, -0.76>>
|
|
FLOAT fRumbleFactor = 1.0
|
|
BOOL bUseOldVerticleBrushCheck = FALSE
|
|
BOOL bDebugForceClearPedTasks = FALSE
|
|
BOOL bDebugForceRestartTasks = FALSE
|
|
|
|
BOOL bIsDriverRunningCarwashSequence = FALSE
|
|
BOOL bIsDriverFinishedCarwashSequence = FALSE
|
|
INT iDriverCarwashSequenceProgress = -1
|
|
BOOL bUseNewMPVertRollers = TRUE
|
|
BOOL bUseNewSweptSphereTest = TRUE
|
|
FLOAT fSweepSphereRadius = 1.0
|
|
FLOAT fShapeTestXSeperation = 3.0
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
FLOAT fCarDebugRatio
|
|
INT iDebugCarWashTimer
|
|
BOOL bCreateBlockCar
|
|
FLOAT fBlockCarPlaceT = 0.5
|
|
#ENDIF
|
|
|
|
//----------------------
|
|
// MISC FUNCTIONS
|
|
//----------------------
|
|
|
|
/*
|
|
PROC PROCESS_EVENT_CARWASH_NETWORK_SCRIPT_EVENT(CARWASH_HANDLER &ch, INT iCount)
|
|
SCRIPT_EVENT_DATA_CARWASH_EVENT sEvent
|
|
IF GET_EVENT_DATA(SCRIPT_EVENT_QUEUE_NETWORK, iCount, sEvent, SIZE_OF(sEvent))
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - NETWORK SCRIPT EVENT RECIEVED")
|
|
IF (ENUM_TO_INT(ch.iLocationID) = sEvent.iCarwashID)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - NETWORK SCRIPT EVENT PROCESSED BY CARWASH:", ENUM_TO_INT(ch.iLocationID))
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
PROC PROCESS_CARWASH_NETWORK_SCRIPT_EVENT(CARWASH_HANDLER &ch, INT iEventID)
|
|
|
|
STRUCT_EVENT_COMMON_DETAILS Details
|
|
|
|
GET_EVENT_DATA(SCRIPT_EVENT_QUEUE_NETWORK, iEventID, Details, SIZE_OF(Details))
|
|
|
|
SWITCH Details.Type
|
|
CASE SCRIPT_EVENT_CARWASH_EVENT
|
|
PROCESS_EVENT_CARWASH_NETWORK_SCRIPT_EVENT(ch, iEventID)
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
PROC PROCESS_CARWASH_NETWORK_EVENTS(CARWASH_HANDLER &ch)
|
|
|
|
INT iCount
|
|
EVENT_NAMES ThisScriptEvent
|
|
|
|
REPEAT GET_NUMBER_OF_EVENTS(SCRIPT_EVENT_QUEUE_NETWORK) iCount
|
|
ThisScriptEvent = GET_EVENT_AT_INDEX(SCRIPT_EVENT_QUEUE_NETWORK, iCount)
|
|
|
|
SWITCH ThisScriptEvent
|
|
CASE EVENT_NETWORK_SCRIPT_EVENT
|
|
PROCESS_CARWASH_NETWORK_SCRIPT_EVENT(ch, iCount)
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDREPEAT
|
|
ENDPROC
|
|
*/
|
|
|
|
PROC UPDATE_VEHICLE_DOOR_DAMAGE_BIT_FIELD(VEHICLE_INDEX veh, INT &iBitField)
|
|
|
|
iBitField = 0
|
|
|
|
IF NOT IS_THIS_MODEL_A_CAR(GET_ENTITY_MODEL(veh))
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF IS_VEHICLE_DOOR_DAMAGED(veh, SC_DOOR_FRONT_LEFT)
|
|
SET_BIT(iBitField, 0)
|
|
ENDIF
|
|
|
|
IF IS_VEHICLE_DOOR_DAMAGED(veh, SC_DOOR_FRONT_RIGHT)
|
|
SET_BIT(iBitField, 1)
|
|
ENDIF
|
|
|
|
IF IS_VEHICLE_DOOR_DAMAGED(veh, SC_DOOR_REAR_LEFT)
|
|
SET_BIT(iBitField, 2)
|
|
ENDIF
|
|
|
|
IF IS_VEHICLE_DOOR_DAMAGED(veh, SC_DOOR_REAR_RIGHT)
|
|
SET_BIT(iBitField, 3)
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
FUNC BOOL IS_ANY_VEHICLE_MAIN_DOOR_BROKEN(VEHICLE_INDEX veh)
|
|
|
|
IF NOT IS_THIS_MODEL_A_CAR(GET_ENTITY_MODEL(veh))
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF IS_VEHICLE_DOOR_DAMAGED(veh, SC_DOOR_FRONT_LEFT)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF IS_VEHICLE_DOOR_DAMAGED(veh, SC_DOOR_FRONT_RIGHT)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF IS_VEHICLE_DOOR_DAMAGED(veh, SC_DOOR_REAR_LEFT)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF IS_VEHICLE_DOOR_DAMAGED(veh, SC_DOOR_REAR_RIGHT)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF IS_VEHICLE_A_CONVERTIBLE(veh, TRUE)
|
|
IF GET_CONVERTIBLE_ROOF_STATE(veh) = CRS_ROOF_STUCK_LOWERED
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
PROC REMOVE_CARWASH_STUCK_CHECK(VEHICLE_INDEX veh)
|
|
IF NOT IS_ENTITY_ALIVE(veh)
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF DOES_VEHICLE_HAVE_STUCK_VEHICLE_CHECK(veh)
|
|
REMOVE_VEHICLE_STUCK_CHECK(veh)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - Removed stuck check")
|
|
ENDIF
|
|
|
|
IF DECOR_EXIST_ON(veh, "Carwash_Vehicle_Decorator")
|
|
DECOR_REMOVE(veh, "Carwash_Vehicle_Decorator")
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - Vehicle Decorator Removed")
|
|
ENDIF
|
|
|
|
IF NETWORK_IS_GAME_IN_PROGRESS()
|
|
IF NETWORK_HAS_CONTROL_OF_ENTITY(veh)
|
|
SET_VEHICLE_DOORS_LOCKED_FOR_ALL_PLAYERS(veh, FALSE)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - Carwash Network Door Lock Released")
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
PROC UPDATE_COLLISIONS_FOR_CARWASH(CARWASH_HANDLER &ch, VEHICLE_INDEX veh)
|
|
|
|
IF DOES_ENTITY_EXIST(ch.horzRoller.rollerID)
|
|
SET_ENTITY_NO_COLLISION_ENTITY(veh, ch.horzRoller.rollerID, TRUE)
|
|
SET_ENTITY_NO_COLLISION_ENTITY(ch.horzRoller.rollerID, veh, TRUE)
|
|
ENDIF
|
|
|
|
IF DOES_ENTITY_EXIST(ch.vertRoller.rollerID[0])
|
|
SET_ENTITY_NO_COLLISION_ENTITY(veh, ch.vertRoller.rollerID[0], TRUE)
|
|
SET_ENTITY_NO_COLLISION_ENTITY(ch.vertRoller.rollerID[0], veh, TRUE)
|
|
ENDIF
|
|
|
|
IF DOES_ENTITY_EXIST(ch.vertRoller.rollerID[1])
|
|
SET_ENTITY_NO_COLLISION_ENTITY(veh, ch.vertRoller.rollerID[1], TRUE)
|
|
SET_ENTITY_NO_COLLISION_ENTITY(ch.vertRoller.rollerID[1], veh, TRUE)
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
PROC RESET_COLLISIONS_FOR_CARWASH(CARWASH_HANDLER &ch, VEHICLE_INDEX veh = NULL)
|
|
|
|
IF DOES_ENTITY_EXIST(ch.horzRoller.rollerID)
|
|
SET_ENTITY_COLLISION(ch.horzRoller.rollerID, TRUE)
|
|
ENDIF
|
|
|
|
REMOVE_CARWASH_STUCK_CHECK(veh)
|
|
ENDPROC
|
|
|
|
PROC STOP_ALL_CARWASH_SOUNDS(CARWASH_HANDLER &ch)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(ch.horzRoller.iSpinSoundID)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(ch.horzRoller.iMoveSoundID)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(ch.horzRoller.iHitSoundID)
|
|
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(ch.vertRoller.iSpinSoundID)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(ch.vertRoller.iMoveSoundID)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(ch.vertRoller.iHitSoundID)
|
|
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(ch.soapJets.iSoundID)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(ch.soapJets.iSplashSoundID)
|
|
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(ch.waterJets.iSoundID)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(ch.waterJets.iSplashSoundID)
|
|
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(ch.steamJets.iSoundID)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(ch.steamJets.iSplashSoundID)
|
|
ENDPROC
|
|
|
|
PROC SHUTDOWN_CARWASH_JETS_PARTICLES(CARWASH_JETS &roll)
|
|
INT i
|
|
|
|
REPEAT COUNT_OF (roll.fxJets) i
|
|
SAFE_REMOVE_PARTICLE_FX(roll.fxJets[i])
|
|
ENDREPEAT
|
|
ENDPROC
|
|
|
|
PROC STOP_ALL_CARWASH_PARTICLES(CARWASH_HANDLER &ch)
|
|
SHUTDOWN_CARWASH_JETS_PARTICLES(ch.waterJets)
|
|
SHUTDOWN_CARWASH_JETS_PARTICLES(ch.soapJets)
|
|
SHUTDOWN_CARWASH_JETS_PARTICLES(ch.steamJets)
|
|
SAFE_REMOVE_PARTICLE_FX(ch.vertRoller.fxBrushID[0])
|
|
SAFE_REMOVE_PARTICLE_FX(ch.vertRoller.fxBrushID[1])
|
|
SAFE_REMOVE_PARTICLE_FX(ch.horzRoller.fxBrushID)
|
|
ENDPROC
|
|
|
|
PROC CARWASH_NETWORK_WAIT(INT time = 60)
|
|
IF NOT NETWORK_IS_GAME_IN_PROGRESS()
|
|
EXIT
|
|
ENDIF
|
|
|
|
CPRINTLN(DEBUG_MISSION, "---------- CREATE WAIT FOR ", time, "MS ", GET_GAME_TIMER())
|
|
|
|
TIME_DATATYPE abortTime = GET_NETWORK_TIME()
|
|
WHILE (ABSI(GET_TIME_DIFFERENCE(GET_NETWORK_TIME(), abortTime)) < time)
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
CPRINTLN(DEBUG_MISSION, "---------- CREATE WAIT FOR ", time, "MS COMPLETE ", GET_GAME_TIMER())
|
|
ENDPROC
|
|
|
|
PROC PRINT_PLAYER_CAR_DIMENSIONS()
|
|
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
|
|
VECTOR vMin, vMax
|
|
GET_MODEL_DIMENSIONS(GET_ENTITY_MODEL(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())), vMin, vMax)
|
|
CPRINTLN(DEBUG_MISSION, "----------CAR DUMP DATA -----------")
|
|
IF IS_ENTITY_ALIVE(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()))
|
|
CPRINTLN(DEBUG_MISSION, "MODEL:", GET_MODEL_NAME_OF_VEHICLE_FOR_DEBUG_ONLY(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())))
|
|
ELSE
|
|
CPRINTLN(DEBUG_MISSION, "MODEL: dead vehicle")
|
|
ENDIF
|
|
CPRINTLN(DEBUG_MISSION, "MIN:", vMin, " MAX:", vMax)
|
|
CPRINTLN(DEBUG_MISSION, "L:", ABSF(vMax.y - vMin.y), " W:", ABSF(vMax.x - vMin.x), " H:", ABSF(vMax.z - vMin.z))
|
|
CPRINTLN(DEBUG_MISSION, "---------- CAR DUMP END -----------")
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
PROC PRINT_ENTITY_MODEL_DIMENSIONS(MODEL_NAMES mdl, STRING str)
|
|
VECTOR vMin, vMax
|
|
GET_MODEL_DIMENSIONS(mdl, vMin, vMax)
|
|
CPRINTLN(DEBUG_MISSION, "----------MODEL DUMP DATA -----------")
|
|
CPRINTLN(DEBUG_MISSION, "MODEL:", str)
|
|
CPRINTLN(DEBUG_MISSION, "MIN:", vMin, " MAX:", vMax)
|
|
CPRINTLN(DEBUG_MISSION, "L:", ABSF(vMax.y - vMin.y), " W:", ABSF(vMax.x - vMin.x), " H:", ABSF(vMax.z - vMin.z))
|
|
CPRINTLN(DEBUG_MISSION, "---------- MODEL DUMP END -----------")
|
|
ENDPROC
|
|
|
|
FUNC BOOL IS_CARWASH_PED_OK(PED_INDEX ped)
|
|
IF NOT DOES_ENTITY_EXIST(ped)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_DEAD(ped)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF NETWORK_IS_GAME_IN_PROGRESS()
|
|
IF NOT IS_PED_A_PLAYER(ped)
|
|
RETURN FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN NOT IS_PED_DEAD_OR_DYING(ped)
|
|
ENDFUNC
|
|
|
|
PROC APPLY_CARWASH_WASH_TO_VEHICLE(VEHICLE_INDEX veh, FLOAT washDecal, FLOAT dirtLevel)
|
|
IF NETWORK_HAS_CONTROL_OF_ENTITY(veh)
|
|
WASH_DECALS_FROM_VEHICLE(veh, washDecal)
|
|
SET_VEHICLE_DIRT_LEVEL(veh, dirtLevel)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
PROC SET_CARWASH_CAR_LOCK_STATE(VEHICLE_INDEX ind, LOCK_STATE lock)
|
|
IF NOT NETWORK_IS_GAME_IN_PROGRESS()
|
|
SET_VEHICLE_DOORS_LOCKED(ind, lock)
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF NOT IS_VEHICLE_A_PERSONAL_VEHICLE(ind)
|
|
AND NOT IS_VEHICLE_A_TEST_DRIVE_VEHICLE(ind)
|
|
SET_VEHICLE_DOORS_LOCKED(ind, lock)
|
|
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
PROC START_CARWASH_TIMER(CARWASH_HANDLER &ch)
|
|
|
|
ch.bTimerStarted = TRUE
|
|
IF g_bInMultiplayer
|
|
ch.iAutoAbortTimerMP = GET_NETWORK_TIME()
|
|
ELSE
|
|
ch.iAutoAbortTimer = GET_GAME_TIMER()
|
|
ENDIF
|
|
|
|
IF NETWORK_IS_GAME_IN_PROGRESS()
|
|
IF IS_COMMERCE_STORE_OPEN()
|
|
EXIT
|
|
ENDIF
|
|
ENDIF
|
|
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Carwash ", ENUM_TO_INT(ch.iLocationID), " Timer Started")
|
|
ENDPROC
|
|
|
|
FUNC INT GET_CARWASH_TIMER_ELAPSED(CARWASH_HANDLER &ch)
|
|
IF g_bInMultiplayer
|
|
RETURN GET_TIME_DIFFERENCE(GET_NETWORK_TIME(), ch.iAutoAbortTimerMP)
|
|
ELSE
|
|
RETURN GET_GAME_TIMER() - ch.iAutoAbortTimer
|
|
ENDIF
|
|
ENDFUNC
|
|
|
|
FUNC BOOL HAS_ABORT_TIME_EXPIRED(CARWASH_HANDLER &ch)
|
|
|
|
INT iAbortTime = PICK_INT((ch.iLocationID = CARWASH_LOCID_LONG), 20000, 15000)
|
|
|
|
IF g_bInMultiplayer
|
|
RETURN (GET_CARWASH_TIMER_ELAPSED(ch) > iAbortTime) AND (ch.bTimerStarted)
|
|
ENDIF
|
|
|
|
RETURN GET_GAME_TIMER() > (ch.iAutoAbortTimer + iAbortTime)
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
///
|
|
/// PARAMS:
|
|
/// carwashInd -
|
|
PROC CHARGE_PLAYER_FOR_CARWASH(CARWASH_LOCATIONID carwashInd = CARWASH_LOCID_LONG)
|
|
VEHICLE_INDEX veh
|
|
INT iScriptTransactionIndex
|
|
IF NOT g_bInMultiplayer
|
|
CHARGE_CURRENT_PLAYER_PED_ACCOUNT_BALANCE(COST_CARWASH)
|
|
ELSE
|
|
veh = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())
|
|
IF IS_ENTITY_OK(veh)
|
|
IF GET_PED_IN_VEHICLE_SEAT(veh) = PLAYER_PED_ID()
|
|
//Just charge as much as possible up to the cost.
|
|
INT iCost = COST_CARWASH
|
|
INT iDifference
|
|
IF NOT NETWORK_CAN_SPEND_MONEY2(iCost, FALSE, FALSE, TRUE, iDifference)
|
|
iCost -= iDifference
|
|
IF iCost <= 0
|
|
EXIT
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// B*1885699 - Changes to Cash Spent Priorities - Take money from cash then bank (This wasn't actually ever fixed properly until now!)
|
|
IF USE_SERVER_TRANSACTIONS()
|
|
TRIGGER_FIRE_AND_FORGET_SERVICE_TRANSACTION(SERVICE_SPEND_CARWASH, iCost, iScriptTransactionIndex, FALSE, FALSE, TRUE)
|
|
g_cashTransactionData[iScriptTransactionIndex].cashInfo.iItemHash = ENUM_TO_INT(GET_ENTITY_MODEL(veh))
|
|
g_cashTransactionData[iScriptTransactionIndex].cashInfo.iLocation = ENUM_TO_INT(carwashInd)
|
|
ELSE
|
|
NETWORK_SPENT_CARWASH(iCost, ENUM_TO_INT(GET_ENTITY_MODEL(veh)), ENUM_TO_INT(carwashInd), FALSE, TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
FUNC BOOL IS_CARWASH_PART_RUNNING(CARWASH_PARTSTATE state)
|
|
RETURN NOT ((state = CPS_NULL) OR (state = CPS_SHUTDOWN))
|
|
ENDFUNC
|
|
|
|
FUNC BOOL IS_VEHICLE_USING_CARWASH(VEHICLE_INDEX veh)
|
|
IF NOT IS_ENTITY_OK(veh)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
RETURN DECOR_EXIST_ON(veh, "Carwash_Vehicle_Decorator")
|
|
ENDFUNC
|
|
|
|
FUNC BOOL IS_ENTITY_A_CARWASH_PART(ENTITY_INDEX obj)
|
|
IF GET_ENTITY_MODEL(obj) = PROP_CARWASH_ROLLER_HORZ
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF GET_ENTITY_MODEL(obj) = PROP_CARWASH_ROLLER_VERT
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF GET_ENTITY_MODEL(obj) = PROP_LD_TEST_01
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
FUNC BOOL IS_ENTITY_BIG_ENOUGH_TO_BLOCK_CARWASH(ENTITY_INDEX obj)
|
|
VECTOR vMin, vMax, vSize
|
|
GET_MODEL_DIMENSIONS(GET_ENTITY_MODEL(obj), vMin, vMax)
|
|
vSize.x = ABSF(vMax.x - vMin.x)
|
|
vSize.y = ABSF(vMax.y - vMin.y)
|
|
vSize.z = ABSF(vMax.z - vMin.z)
|
|
|
|
RETURN (vSize.x >= 1.4) AND (vSize.y >= 1.4) AND (vSize.z >= 1.4)
|
|
ENDFUNC
|
|
|
|
FUNC BOOL IS_THIS_ENTITY_A_DUMPSTER(ENTITY_INDEX obj)
|
|
IF GET_ENTITY_MODEL(obj) = PROP_DUMPSTER_01A
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF GET_ENTITY_MODEL(obj) = PROP_DUMPSTER_02A
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF GET_ENTITY_MODEL(obj) = PROP_DUMPSTER_02B
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF GET_ENTITY_MODEL(obj) = PROP_DUMPSTER_3A
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF GET_ENTITY_MODEL(obj) = PROP_DUMPSTER_4A
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF GET_ENTITY_MODEL(obj) = PROP_DUMPSTER_4B
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
FUNC BOOL CAN_THIS_ENTITY_BLOCK_THE_CARWASH(ENTITY_INDEX obj)
|
|
IF DOES_ENTITY_EXIST(obj)
|
|
IF IS_ENTITY_A_VEHICLE(obj)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_A_PED(obj)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_A_CARWASH_PART(obj)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF IS_THIS_ENTITY_A_DUMPSTER(obj)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_BIG_ENOUGH_TO_BLOCK_CARWASH(obj)
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Check if ped is network carwash driver
|
|
/// PARAMS:
|
|
/// ped - ped index
|
|
FUNC BOOL IS_PED_IN_CAR_WITH_CARWASH_DRIVER(PED_INDEX ped)
|
|
VEHICLE_INDEX veh
|
|
|
|
IF NOT IS_CARWASH_PED_OK(ped)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF NOT IS_PED_IN_ANY_VEHICLE(ped)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
veh = GET_VEHICLE_PED_IS_IN(ped)
|
|
IF NOT IS_ENTITY_OK(veh)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
PED_INDEX driveped = GET_PED_IN_VEHICLE_SEAT(veh)
|
|
IF NOT IS_CARWASH_PED_OK(driveped)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF (g_bInMultiplayer)
|
|
PLAYER_INDEX player = NETWORK_GET_PLAYER_INDEX_FROM_PED(driveped)
|
|
IF (player = INVALID_PLAYER_INDEX())
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF NOT IS_NET_PLAYER_OK(player, TRUE, FALSE)
|
|
GlobalPlayerBD[NATIVE_TO_INT(player)].bDrivingThroughCarwash = FALSE
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
RETURN GlobalPlayerBD[NATIVE_TO_INT(player)].bDrivingThroughCarwash
|
|
//RETURN IS_NET_PLAYER_OK(player, TRUE, FALSE) AND GlobalPlayerBD[NATIVE_TO_INT(player)].bDrivingThroughCarwash
|
|
ENDIF
|
|
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
PROC DO_CARWASH_PAD_RUMBLE(INT iDuration, INT iFreq)
|
|
IF IS_PED_IN_CAR_WITH_CARWASH_DRIVER(PLAYER_PED_ID())
|
|
FLOAT fFinalFreq = (TO_FLOAT(iFreq) * fRumbleFactor)
|
|
fFinalFreq = CLAMP(fFinalFreq, 0, 256)
|
|
|
|
//SET_PAD_SHAKE(PAD1, iDuration, FLOOR(fFinalFreq))
|
|
|
|
// old function has been depreciated
|
|
SET_CONTROL_SHAKE(PLAYER_CONTROL, iDuration, FLOOR(fFinalFreq))
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
FUNC BOOL IS_ANY_NET_PLAYER_DRIVING_IN_CARWASH()
|
|
INT i
|
|
|
|
REPEAT NUM_NETWORK_PLAYERS i
|
|
IF GlobalPlayerBD[i].bDrivingThroughCarwash
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
FUNC BOOL CHECK_ENTITY_IS_VEHICLE_OK(ENTITY_INDEX hitEntity, BOOL bCheckDriver = TRUE)
|
|
VEHICLE_INDEX veh
|
|
IF IS_ENTITY_A_VEHICLE(hitEntity) AND IS_ENTITY_OK(hitEntity)
|
|
veh = GET_VEHICLE_INDEX_FROM_ENTITY_INDEX(hitEntity)
|
|
|
|
IF (bCheckDriver)
|
|
IF NOT IS_CARWASH_PED_OK(GET_PED_IN_VEHICLE_SEAT(veh))
|
|
RETURN FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF NOT IS_VEHICLE_USING_CARWASH(veh)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
PROC UPDATE_EMERGENCY_PLAYER_WARP_OUT_FOR_CARWASH()
|
|
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<40.279442,-1398.855957,23.846724>>, <<-0.984962,-1398.240234,32.011398>>, 5.750000)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: UPDATE_EMERGENCY_PLAYER_WARP_OUT_FOR_CARWASH - PLAYER IS STUCK IN WALL BEHIND CARWASH 1")
|
|
SET_ENTITY_COORDS(PLAYER_PED_ID(), <<-3.4237, -1396.3101, 28.2554>>)
|
|
SET_ENTITY_HEADING(PLAYER_PED_ID(), 85.1922)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/*
|
|
/// PURPOSE:
|
|
/// Handle push block - stops vehicles from driving in
|
|
/// PARAMS:
|
|
/// ct - carwash track
|
|
/// veh - vehicle
|
|
/// blockRadius - block radius
|
|
FUNC FLOAT UPDATE_VEHICLE_IN_CARWASH(CARWASH_TRACK &ct, VEHICLE_INDEX veh, FLOAT fwdSpeed, FLOAT startDirt)
|
|
|
|
// move car along and stop people dicking about with sun roof
|
|
VECTOR v
|
|
FLOAT r = GET_RATIO_OF_CLOSEST_POINT_ON_LINE(GET_ENTITY_COORDS(veh), ct.vTrackPoint[0], ct.vTrackPoint[1], FALSE)
|
|
IF (r <= 1)
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_EXIT)
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_ROOF)
|
|
v = GET_CLOSEST_POINT_ON_LINE(GET_ENTITY_COORDS(veh), ct.vTrackPoint[0], ct.vTrackPoint[1], FALSE)
|
|
IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(veh, v) < 4.0
|
|
SET_ENTITY_HEADING(veh, ct.fTrackHeading)
|
|
//SET_VEHICLE_ENGINE_ON(veh, TRUE, TRUE)
|
|
|
|
SET_VEHICLE_FORWARD_SPEED(veh, fwdSpeed)
|
|
|
|
IF (r > 0.0)
|
|
SET_VEHICLE_DIRT_LEVEL(veh, startDirt * (1.0 - r))
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN r
|
|
ENDFUNC
|
|
*/
|
|
|
|
PROC SNAP_VEHICLE_BACK_ON_TRACK(VEHICLE_INDEX veh, CARWASH_TRACK &ct)
|
|
VECTOR v = GET_CLOSEST_POINT_ON_LINE(GET_ENTITY_COORDS(veh), ct.vTrackPoint[0], ct.vTrackPoint[1], FALSE)
|
|
SET_ENTITY_COORDS_GROUNDED(veh, v)
|
|
SET_ENTITY_HEADING(veh, ct.fTrackHeading)
|
|
SET_VEHICLE_ON_GROUND_PROPERLY(veh)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Handle push block - stops vehicles from driving in
|
|
/// PARAMS:
|
|
/// ct - carwash track
|
|
/// veh - vehicle
|
|
/// blockRadius - block radius
|
|
PROC UPDATE_VEHICLE_PUSH_BLOCK(CARWASH_TRACK &ct, VEHICLE_INDEX veh, FLOAT blockRadius = 2.0)
|
|
VECTOR v
|
|
|
|
IF NOT IS_VECTOR_ZERO(ct.vBlockPoint[0]) AND NOT IS_VECTOR_ZERO(ct.vBlockPoint[1])
|
|
IF IS_ENTITY_IN_RANGE_COORDS(veh, ct.vBlockPoint[0], blockRadius)
|
|
v = NORMALISE_VECTOR(GET_ENTITY_COORDS(veh) - ct.vBlockPoint[0])
|
|
SET_ENTITY_VELOCITY(veh, v * 2.0)
|
|
ELIF IS_ENTITY_IN_RANGE_COORDS(veh, ct.vBlockPoint[1], blockRadius)
|
|
v = NORMALISE_VECTOR(GET_ENTITY_COORDS(veh) - ct.vBlockPoint[1])
|
|
SET_ENTITY_VELOCITY(veh, v * 2.0)
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Tells the Global BD That this ped is not driver in carwash
|
|
/// PARAMS:
|
|
/// ped - ped index
|
|
PROC FORCE_CLEAR_NET_PED_DRIVING_CARWASH_STATUS(PED_INDEX ped)
|
|
PLAYER_INDEX player = NETWORK_GET_PLAYER_INDEX_FROM_PED(ped)
|
|
IF (player = INVALID_PLAYER_INDEX())
|
|
EXIT
|
|
ENDIF
|
|
|
|
GlobalPlayerBD[NATIVE_TO_INT(player)].bDrivingThroughCarwash = FALSE
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Sets Global BD Net Ped Driving State
|
|
/// PARAMS:
|
|
/// ped - ped index
|
|
/// ok - state
|
|
PROC SET_NET_PED_DRIVING_CARWASH_STATUS(PED_INDEX ped, BOOL ok)
|
|
PLAYER_INDEX player = NETWORK_GET_PLAYER_INDEX_FROM_PED(ped)
|
|
IF (player = INVALID_PLAYER_INDEX())
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF NOT IS_CARWASH_PED_OK(ped)
|
|
GlobalPlayerBD[NATIVE_TO_INT(player)].bDrivingThroughCarwash = FALSE
|
|
EXIT
|
|
ENDIF
|
|
|
|
GlobalPlayerBD[NATIVE_TO_INT(player)].bDrivingThroughCarwash = OK
|
|
ENDPROC
|
|
|
|
|
|
PROC DISABLE_CONTROL_ACTIONS_FOR_CARWASH()
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_ROOF)
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_EXIT)
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_HEADLIGHT)
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_SCRIPT_RRIGHT)
|
|
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_ATTACK)
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_ATTACK2)
|
|
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_PASSENGER_AIM)
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_PASSENGER_ATTACK)
|
|
|
|
RC_DISABLE_CONTROL_ACTIONS_FOR_LEAD_IN()
|
|
|
|
IF NOT (g_bInMultiplayer)
|
|
DISABLE_SELECTOR_THIS_FRAME()
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Loads the carwash models
|
|
PROC REQUEST_AND_LOAD_CARWASH_ASSETS_MP(ASSET_REQUESTER &as, STRING wayPointName = NULL)
|
|
ADD_ASSET_REQUEST_FOR_MODEL(as, 0, PROP_CARWASH_ROLLER_HORZ)
|
|
ADD_ASSET_REQUEST_FOR_MODEL(as, 1, PROP_CARWASH_ROLLER_VERT)
|
|
ADD_ASSET_REQUEST_FOR_MODEL(as, 2, PROP_LD_TEST_01)
|
|
IF HINT_SCRIPT_AUDIO_BANK("SCRIPT\\CARWASH")
|
|
PRINTLN("[CARWASH] Audio bank hinted")
|
|
ENDIF
|
|
ADD_ASSET_REQUEST_FOR_PTFX(as, 3)
|
|
|
|
IF NOT IS_STRING_NULL_OR_EMPTY(wayPointName)
|
|
ADD_ASSET_REQUEST_FROM_STRING(as, 4, ASSET_WAYREC, wayPointName)
|
|
ENDIF
|
|
|
|
WHILE NOT HAVE_ASSET_REQUESTS_LOADED(as)
|
|
SET_INPUT_EXCLUSIVE(FRONTEND_CONTROL, INPUT_CONTEXT)
|
|
SET_INPUT_EXCLUSIVE(FRONTEND_CONTROL, INPUT_VEH_EXIT)
|
|
DISABLE_CONTROL_ACTIONS_FOR_CARWASH()
|
|
WAIT(0)
|
|
ENDWHILE
|
|
ENDPROC
|
|
|
|
PROC REQUEST_AND_LOAD_CARWASH_ASSETS(ASSET_REQUESTER &as, STRING wayPointName = NULL)
|
|
ADD_ASSET_REQUEST_FOR_MODEL(as, 0, PROP_CARWASH_ROLLER_HORZ)
|
|
ADD_ASSET_REQUEST_FOR_MODEL(as, 1, PROP_CARWASH_ROLLER_VERT)
|
|
ADD_ASSET_REQUEST_FOR_MODEL(as, 2, PROP_LD_TEST_01)
|
|
ADD_ASSET_REQUEST_FROM_STRING(as, 3, ASSET_AUDIOBANK, "SCRIPT\\CARWASH")
|
|
ADD_ASSET_REQUEST_FOR_PTFX(as, 4)
|
|
|
|
IF NOT IS_STRING_NULL_OR_EMPTY(wayPointName)
|
|
ADD_ASSET_REQUEST_FROM_STRING(as, 5, ASSET_WAYREC, wayPointName)
|
|
ENDIF
|
|
|
|
WHILE NOT HAVE_ASSET_REQUESTS_LOADED(as)
|
|
SET_INPUT_EXCLUSIVE(FRONTEND_CONTROL, INPUT_CONTEXT)
|
|
SET_INPUT_EXCLUSIVE(FRONTEND_CONTROL, INPUT_VEH_EXIT)
|
|
DISABLE_CONTROL_ACTIONS_FOR_CARWASH()
|
|
WAIT(0)
|
|
ENDWHILE
|
|
ENDPROC
|
|
/// PURPOSE:
|
|
/// Loads the carwash models
|
|
PROC RELEASE_CARWASH_MODEL_ASSETS(ASSET_REQUESTER &as)
|
|
_UNLOAD_ASSET_FROM_REQUESTER(as, 0)
|
|
_UNLOAD_ASSET_FROM_REQUESTER(as, 1)
|
|
_UNLOAD_ASSET_FROM_REQUESTER(as, 2)
|
|
ENDPROC
|
|
|
|
FUNC BOOL IS_CARWASH_POSITION_OCCUPIED(VECTOR v, FLOAT rad, BOOL bVisibleCheck = TRUE)
|
|
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) AND IS_ENTITY_IN_RANGE_COORDS(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), v, rad)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF NOT IS_SPHERE_VISIBLE(v, rad) AND (bVisibleCheck = TRUE)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
RETURN IS_POSITION_OCCUPIED(v, rad, FALSE, TRUE, FALSE, FALSE, FALSE, NULL, TRUE)
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Places vehicle along a two point track, gives it a speed and a go to order
|
|
/// PARAMS:
|
|
/// ind - vehicle index
|
|
/// v1 - position 1
|
|
/// v2 - position 2
|
|
/// fRatio - ratio along track - 0 is back, 1 is front
|
|
/// fSpeed - speed to move aong
|
|
PROC SET_VEHICLE_ALONG_LINE(VEHICLE_INDEX ind, VECTOR v1, VECTOR v2, FLOAT fRatio, FLOAT fSpeed = 0.0)
|
|
VECTOR v
|
|
FLOAT head
|
|
PED_INDEX ped
|
|
|
|
IF NOT IS_ENTITY_OK(ind)
|
|
EXIT
|
|
ENDIF
|
|
|
|
v = INTERPOLATE_VECTOR(v1, v2, fRatio, FALSE)
|
|
head = GET_HEADING_FROM_COORDS(v1, v2)
|
|
SET_ENTITY_COORDS(ind, v)
|
|
SET_ENTITY_HEADING(ind, head)
|
|
FREEZE_ENTITY_POSITION(ind, FALSE)
|
|
IF (fSpeed = 0.0)
|
|
EXIT
|
|
ENDIF
|
|
|
|
SET_VEHICLE_ENGINE_ON(ind, TRUE, TRUE)
|
|
SET_VEHICLE_FORWARD_SPEED(ind, fSpeed)
|
|
|
|
IF (fRatio > 1.0)
|
|
EXIT
|
|
ENDIF
|
|
|
|
ped = GET_PED_IN_VEHICLE_SEAT(ind)
|
|
IF NOT IS_CARWASH_PED_OK(ped)
|
|
EXIT
|
|
ENDIF
|
|
|
|
CPRINTLN(DEBUG_MISSION, "CAR RATIO:", fRatio, " SPEED:", fSpeed, " DEST:", v2)
|
|
TASK_VEHICLE_DRIVE_TO_COORD(ped, ind, v2, fSpeed, DRIVINGSTYLE_STRAIGHTLINE, GET_ENTITY_MODEL(ind), DRIVINGMODE_PLOUGHTHROUGH, 0.5, 1000.0)
|
|
ENDPROC
|
|
|
|
//----------------------
|
|
// TRACK FUNCTIONS
|
|
//----------------------
|
|
|
|
PROC SET_CARWASH_IPL(CARWASH_HANDLER &ch, BUILDING_NAME_ENUM ipl)
|
|
ch.iplSwap = ipl
|
|
SET_BUILDING_STATE(ch.iplSwap, BUILDINGSTATE_DESTROYED)
|
|
ENDPROC
|
|
|
|
PROC SET_CARWASH_WAYPOINT_REC(CARWASH_HANDLER &ch, STRING s)
|
|
ch.sWayPointRec = s
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Sets up a carwash track
|
|
/// PARAMS:
|
|
/// ct - carwash track reference
|
|
/// v1 - track point 1
|
|
/// v2 - track point 2
|
|
PROC SETUP_CARWASH_TRACK(CARWASH_TRACK &ct, VECTOR v1, VECTOR v2)
|
|
ct.vTrackPoint[0] = v1
|
|
ct.vTrackPoint[1] = v2
|
|
ct.vDirection = NORMALISE_VECTOR(v2 - v1)
|
|
ct.fTrackHeading = GET_HEADING_BETWEEN_VECTORS_2D(ct.vTrackPoint[0], ct.vTrackPoint[1])
|
|
CLEAR_CYLINDER_OF_ENTITIES(ct.vTrackPoint[0], ct.vTrackPoint[1], 3.0, FALSE, NOT g_bInMultiplayer, FALSE, TRUE, NOT g_bInMultiplayer)
|
|
ENDPROC
|
|
|
|
PROC SETUP_CARWASH_BLOCK_MIN_MAX(CARWASH_TRACK &ct, VECTOR v1, VECTOR v2)
|
|
ct.vBlockMinMax[0] = v1
|
|
ct.vBlockMinMax[1] = v2
|
|
|
|
IF ABSF(v2.x - v1.x) > ABSF(v2.y - v1.y)
|
|
ct.iDominantBlockAxis = CARWASH_AXIS_X
|
|
ELSE
|
|
ct.iDominantBlockAxis = CARWASH_AXIS_Y
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Setup block points - these stop other vehicles driving in MP
|
|
/// PARAMS:
|
|
/// ct - carwash track reference
|
|
/// v1 - point 1
|
|
/// v2 - point 2
|
|
PROC SETUP_CARWASH_BLOCK_POINTS(CARWASH_TRACK &ct, VECTOR v1, VECTOR v2)
|
|
ct.vBlockPoint[0] = v1
|
|
ct.vBlockPoint[1] = v2
|
|
ENDPROC
|
|
|
|
PROC DRAW_DEBUG_CARWASH_TRACK(CARWASH_TRACK &ct)
|
|
/*
|
|
DRAW_DEBUG_LINE(ct.vTrackPoint[0], ct.vTrackPoint[1])
|
|
DRAW_DEBUG_SPHERE(INTERPOLATE_VECTOR(ct.vTrackPoint[0], ct.vTrackPoint[1], fInter), 0.5)
|
|
|
|
DRAW_DEBUG_BOX(ct.vBlockMinMax[0], ct.vBlockMinMax[1])
|
|
DRAW_DEBUG_CIRCLE(ct.vTrackPoint[1], 1.0, 0, 255, 0, 255)
|
|
DRAW_DEBUG_CIRCLE(ct.vBlockPoint[0], 1.0, 255, 0, 0, 255)
|
|
DRAW_DEBUG_CIRCLE(ct.vBlockPoint[1], 1.0, 255, 0, 0, 255)
|
|
*/
|
|
DRAW_DEBUG_SPHERE(ct.vBlockMinMax[0], 0.0625)
|
|
DRAW_DEBUG_SPHERE(ct.vBlockMinMax[1], 0.0625)
|
|
DRAW_DEBUG_LINE(ct.vBlockMinMax[0], ct.vBlockMinMax[1])
|
|
ENDPROC
|
|
|
|
PROC DRAW_DEBUG_CARWASH(CARWASH_HANDLER &ct)
|
|
/*
|
|
DRAW_DEBUG_LINE(ct.vTrackPoint[0], ct.vTrackPoint[1])
|
|
DRAW_DEBUG_SPHERE(INTERPOLATE_VECTOR(ct.vTrackPoint[0], ct.vTrackPoint[1], fInter), 0.5)
|
|
|
|
DRAW_DEBUG_BOX(ct.vBlockMinMax[0], ct.vBlockMinMax[1])
|
|
DRAW_DEBUG_CIRCLE(ct.vTrackPoint[1], 1.0, 0, 255, 0, 255)
|
|
DRAW_DEBUG_CIRCLE(ct.vBlockPoint[0], 1.0, 255, 0, 0, 255)
|
|
DRAW_DEBUG_CIRCLE(ct.vBlockPoint[1], 1.0, 255, 0, 0, 255)
|
|
*/
|
|
DRAW_DEBUG_SPHERE(ct.cTrack.vBlockMinMax[0], 0.0625)
|
|
DRAW_DEBUG_SPHERE(ct.cTrack.vBlockMinMax[1], 0.0625)
|
|
DRAW_DEBUG_LINE(ct.cTrack.vBlockMinMax[0], ct.cTrack.vBlockMinMax[1])
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Places vehicle along a two point track, gives it a speed and a go to order
|
|
/// PARAMS:
|
|
/// ind - vehicle index
|
|
/// v1 - position 1
|
|
/// v2 - position 2
|
|
/// fRatio - ratio along track - 0 is back, 1 is front
|
|
/// fSpeed - speed to move aong
|
|
PROC SET_VEHICLE_ALONG_CARWASH_TRACK(VEHICLE_INDEX ind, CARWASH_TRACK &ct, FLOAT fRatio, FLOAT fSpeed = 0.0)
|
|
VECTOR v
|
|
FLOAT head
|
|
PED_INDEX ped
|
|
|
|
// work out point along the track we are
|
|
v = INTERPOLATE_VECTOR(ct.vTrackPoint[0], ct.vTrackPoint[1], fRatio, FALSE)
|
|
|
|
// get the closest point to this point on the groove track
|
|
head = GET_HEADING_FROM_COORDS(ct.vTrackPoint[0], ct.vTrackPoint[1])
|
|
SET_ENTITY_COORDS_GROUNDED(ind, v + <<0, 0, 0.1>>)
|
|
SET_ENTITY_HEADING(ind, head)
|
|
FREEZE_ENTITY_POSITION(ind, FALSE)
|
|
IF (fSpeed = 0.0)
|
|
EXIT
|
|
ENDIF
|
|
|
|
SET_VEHICLE_ENGINE_ON(ind, TRUE, TRUE)
|
|
|
|
IF (fRatio > 1.0)
|
|
EXIT
|
|
ENDIF
|
|
|
|
SET_VEHICLE_FORWARD_SPEED(ind, fSpeed)
|
|
ped = GET_PED_IN_VEHICLE_SEAT(ind)
|
|
IF NOT IS_CARWASH_PED_OK(ped)
|
|
EXIT
|
|
ENDIF
|
|
|
|
v = INTERPOLATE_VECTOR(ct.vTrackPoint[0], ct.vTrackPoint[1], 1.1, FALSE)
|
|
CPRINTLN(DEBUG_MISSION, "CAR RATIO:", fRatio, " SPEED:", fSpeed, " DEST:", v)
|
|
TASK_VEHICLE_DRIVE_TO_COORD(ped, ind, v, fSpeed, DRIVINGSTYLE_STRAIGHTLINE, GET_ENTITY_MODEL(ind), DRIVINGMODE_PLOUGHTHROUGH, 0.5, 1000.0)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Get Ratio of Closest Point To Track
|
|
/// PARAMS:
|
|
/// v - point to test
|
|
/// c - cartrack reference
|
|
/// RETURNS:
|
|
/// Ratio - not clamped
|
|
FUNC FLOAT GET_RATIO_ALONG_CARWASH_TRACK(VECTOR v, CARWASH_TRACK &c, BOOL clmp = FALSE)
|
|
RETURN GET_RATIO_OF_CLOSEST_POINT_ON_LINE(v, c.vTrackPoint[0], c.vTrackPoint[1], clmp)
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Get Ratio of Closest Point To Track
|
|
/// PARAMS:
|
|
/// v - point to test
|
|
/// c - cartrack reference
|
|
/// RETURNS:
|
|
/// Ratio - not clamped
|
|
FUNC FLOAT GET_HEADING_ALONG_CARWASH_TRACK(CARWASH_TRACK &c)
|
|
RETURN GET_HEADING_BETWEEN_VECTORS_2D(c.vTrackPoint[0], c.vTrackPoint[1])
|
|
ENDFUNC
|
|
|
|
//----------------------
|
|
// HROLLER FUNCTIONS
|
|
//----------------------
|
|
|
|
PROC SHUTDOWN_CARWASH_HROLLER(CARWASH_HROLLER &roll)
|
|
IF IS_CARWASH_PART_RUNNING(roll.state)
|
|
SAFE_REMOVE_PARTICLE_FX(roll.fxBrushID)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iMoveSoundID)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iSpinSoundID)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iHitSoundID)
|
|
roll.state = CPS_NULL
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
PROC SHARED_CLEANUP_DELETE_CARWASH_HROLLER(CARWASH_HROLLER &roll)
|
|
roll.state = CPS_ACTIVE
|
|
SHUTDOWN_CARWASH_HROLLER(roll)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Cleanup the hroller
|
|
/// PARAMS:
|
|
/// roll - roller reference
|
|
PROC DELETE_CARWASH_HROLLER(CARWASH_HROLLER &roll)
|
|
SHARED_CLEANUP_DELETE_CARWASH_HROLLER(roll)
|
|
SAFE_DELETE_OBJECT(roll.rollerID)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Cleanup the hroller
|
|
/// PARAMS:
|
|
/// roll - roller reference
|
|
PROC CLEANUP_CARWASH_HROLLER(CARWASH_HROLLER &roll)
|
|
SHARED_CLEANUP_DELETE_CARWASH_HROLLER(roll)
|
|
SAFE_RELEASE_OBJECT(roll.rollerID)
|
|
ENDPROC
|
|
|
|
PROC START_CARWASH_HROLLER_PARTICLES(CARWASH_HROLLER &roll)
|
|
SAFE_REMOVE_PARTICLE_FX(roll.fxBrushID)
|
|
|
|
IF IS_ENTITY_OK(roll.rollerID) //AND NOT (g_bInMultiplayer)
|
|
IF NOT DOES_PARTICLE_FX_LOOPED_EXIST(roll.fxBrushID)
|
|
roll.fxBrushID = START_PARTICLE_FX_LOOPED_ON_ENTITY("ent_amb_car_wash", roll.rollerID, <<0.0, 0.0, 0.0>>, vRollerHorzRotFX)
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Update the carwash roller
|
|
/// PARAMS:
|
|
/// roll - roller reference
|
|
PROC _UPDATE_CARWASH_HROLLER_INTERNAL(CARWASH_HROLLER &roll)
|
|
|
|
INT iHits
|
|
VECTOR vec
|
|
VECTOR vHitPos, vHitNormal
|
|
SHAPETEST_STATUS shapeStatus
|
|
ENTITY_INDEX hitEntity
|
|
|
|
IF NOT roll.bSetup = TRUE
|
|
EXIT
|
|
ENDIF
|
|
|
|
// do shape test
|
|
IF (IS_CARWASH_PART_RUNNING(roll.state))
|
|
IF (roll.shapeTestID = NULL)
|
|
IF (GET_GAME_TIMER() > roll.iNextShapeTestTime)
|
|
roll.shapeTestID = START_SHAPE_TEST_LOS_PROBE(roll.vPosition, roll.vPosition - <<0, 0, 5.0>>, SCRIPT_INCLUDE_VEHICLE, roll.rollerID, SCRIPT_SHAPETEST_OPTION_IGNORE_NO_COLLISION)
|
|
IF (roll.shapeTestID = NULL)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: CAN'T GET SHAPETEST FOR HORIZONTAL BRUSH")
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
shapeStatus = GET_SHAPE_TEST_RESULT(roll.shapeTestID, iHits, vHitPos, vHitNormal, hitEntity)
|
|
IF (shapeStatus = SHAPETEST_STATUS_RESULTS_READY)
|
|
|
|
IF (iHits > 0)
|
|
|
|
// set the ground zero point
|
|
IF (roll.fGroundZero = 0.0)
|
|
roll.fGroundZero = vHitPos.z + ROLLER_RADIUS
|
|
ENDIF
|
|
|
|
// work out contact point
|
|
roll.vContactPoint = vHitPos + vRollerRadius
|
|
|
|
// work out target point we should be moving towards
|
|
IF (roll.vContactPoint.z = roll.fGroundZero)
|
|
roll.fTargetZ = roll.vPosition.z - (ROLLER_RADIUS * 1.1)
|
|
ELSE
|
|
roll.fTargetZ = roll.vContactPoint.z + 0.1
|
|
IF CHECK_ENTITY_IS_VEHICLE_OK(hitEntity)
|
|
SET_ENTITY_NO_COLLISION_ENTITY(hitEntity, roll.rollerID, TRUE)
|
|
SET_ENTITY_NO_COLLISION_ENTITY(roll.rollerID, hitEntity, TRUE)
|
|
IF (roll.iHitSoundID = -1)
|
|
roll.iHitSoundID = GET_SOUND_ID()
|
|
PLAY_SOUND_FROM_ENTITY(roll.iHitSoundID, "BRUSHES_HIT_CAR", roll.rollerID, "CARWASH_SOUNDS")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
roll.shapeTestID = NULL
|
|
roll.iNextShapeTestTime = GET_GAME_TIMER() + SHAPE_CHECK_INTERVAL
|
|
ENDIF
|
|
ELSE
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iHitSoundID)
|
|
roll.fTargetZ = roll.fOriginalZ
|
|
ENDIF
|
|
|
|
// move the roller to get to contact point
|
|
vec = GET_ENTITY_COORDS(roll.rollerID)
|
|
IF (vec.z < roll.fTargetZ)
|
|
vec.z += roll.fMoveRate * TIMESTEP()
|
|
IF (vec.z > roll.fTargetZ)
|
|
vec.z = roll.fTargetZ
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF (vec.z > roll.fTargetZ)
|
|
vec.z -= roll.fMoveRate * TIMESTEP()
|
|
IF (vec.z < roll.fTargetZ)
|
|
DO_CARWASH_PAD_RUMBLE(64, 64)
|
|
vec.z = roll.fTargetZ
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF (roll.fGroundZero <> 0.0)
|
|
vec.z = CLAMP(vec.z,roll.fGroundZero, roll.fOriginalZ)
|
|
ENDIF
|
|
|
|
// set position and rotation
|
|
IF NOT ARE_VECTORS_EQUAL(roll.vOldRollerPos, vec)
|
|
SET_ENTITY_COORDS(roll.rollerID, vec)
|
|
ENDIF
|
|
|
|
roll.vOldRollerPos = vec
|
|
|
|
// draw some debug crap
|
|
IF bDrawDebugCarwash = TRUE
|
|
DRAW_DEBUG_CIRCLE(<<roll.vPosition.x, roll.vPosition.y, roll.fGroundZero - ROLLER_RADIUS>>, roll.fTriggerDist)
|
|
DRAW_DEBUG_SPHERE(roll.vPosition, 0.0625)
|
|
DRAW_DEBUG_LINE(roll.vPosition, roll.vContactPoint - vRollerRadius)
|
|
DRAW_DEBUG_SPHERE(roll.vContactPoint - vRollerRadius, 0.03125)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Update the dual roller
|
|
/// PARAMS:
|
|
/// roll - roller reference
|
|
PROC UPDATE_CARWASH_HROLLER(CARWASH_HROLLER &roll, BOOL bSomeOneIn = TRUE)
|
|
|
|
INT iHits
|
|
VECTOR vHitPos, vHitNormal
|
|
SHAPETEST_STATUS shapeStatus
|
|
ENTITY_INDEX hitEntity
|
|
|
|
VECTOR v = roll.vPosition
|
|
FLOAT tStep = ROLLER_SPINRATE * TIMESTEP()
|
|
v.z = roll.fGroundZero
|
|
|
|
IF IS_CARWASH_PART_RUNNING(roll.state)
|
|
IF (bSomeOneIn = FALSE)
|
|
CPRINTLN(DEBUG_MISSION, "Carwash HRoller - Shutdown No One is In Carwash")
|
|
roll.state = CPS_SHUTDOWN
|
|
ENDIF
|
|
|
|
IF NETWORK_IS_GAME_IN_PROGRESS() AND NOT IS_ANY_NET_PLAYER_DRIVING_IN_CARWASH()
|
|
CPRINTLN(DEBUG_MISSION, "Carwash HRoller - NET Shutdown No One is In Carwash")
|
|
roll.state = CPS_SHUTDOWN
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SWITCH (roll.state)
|
|
CASE CPS_NULL
|
|
|
|
IF g_bInMultiplayer
|
|
IF NOT IS_ANY_NET_PLAYER_DRIVING_IN_CARWASH()
|
|
EXIT
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF IS_ANY_VEHICLE_NEAR_POINT(roll.vPosition, 4.0)
|
|
IF (roll.shapeTestID = NULL)
|
|
IF (GET_GAME_TIMER() > roll.iNextShapeTestTime)
|
|
roll.shapeTestID = START_SHAPE_TEST_CAPSULE(roll.vPosition, roll.vPosition - <<0, 0, 6.0>>, roll.fTriggerDist * 1.2, SCRIPT_INCLUDE_VEHICLE, roll.rollerID, SCRIPT_SHAPETEST_OPTION_IGNORE_NO_COLLISION)
|
|
ENDIF
|
|
ELSE
|
|
shapeStatus = GET_SHAPE_TEST_RESULT(roll.shapeTestID, iHits, vHitPos, vHitNormal, hitEntity)
|
|
IF (shapeStatus = SHAPETEST_STATUS_RESULTS_READY)
|
|
IF CHECK_ENTITY_IS_VEHICLE_OK(hitEntity)
|
|
roll.state = CPS_STARTUP
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iSpinSoundID)
|
|
roll.iSpinSoundID = GET_SOUND_ID()
|
|
PLAY_SOUND_FROM_ENTITY(roll.iSpinSoundID, "BRUSHES_SPINNING", roll.rollerID, "CARWASH_SOUNDS")
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: HROLLER STARTUP")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
roll.shapeTestID = NULL
|
|
roll.iNextShapeTestTime = GET_GAME_TIMER() + SHAPE_CHECK_INTERVAL
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE CPS_STARTUP
|
|
IF (bSomeOneIn = FALSE)
|
|
roll.state = CPS_SHUTDOWN
|
|
ELSE
|
|
roll.fSpinRate += tStep
|
|
IF (roll.fSpinRate >= ROLLER_SPINRATE)
|
|
roll.fSpinRate = ROLLER_SPINRATE
|
|
roll.state = CPS_ACTIVE
|
|
START_CARWASH_HROLLER_PARTICLES(roll)
|
|
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iMoveSoundID)
|
|
roll.iMoveSoundID = GET_SOUND_ID()
|
|
PLAY_SOUND_FROM_ENTITY(roll.iMoveSoundID, "BRUSHES_MOVE", roll.rollerID, "CARWASH_SOUNDS")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF NETWORK_IS_GAME_IN_PROGRESS() AND NOT IS_ANY_NET_PLAYER_DRIVING_IN_CARWASH()
|
|
roll.state = CPS_SHUTDOWN
|
|
ENDIF
|
|
BREAK
|
|
CASE CPS_ACTIVE
|
|
IF (bSomeOneIn = FALSE)
|
|
roll.state = CPS_SHUTDOWN
|
|
ELIF (GET_GAME_TIMER() > roll.iNextCheckTime)
|
|
IF NOT IS_CARWASH_POSITION_OCCUPIED(v, roll.fTriggerDist)
|
|
SAFE_REMOVE_PARTICLE_FX(roll.fxBrushID)
|
|
roll.state = CPS_SHUTDOWN
|
|
ENDIF
|
|
roll.iNextCheckTime = GET_GAME_TIMER() + ROLLER_CHECK_INTERVAL
|
|
ENDIF
|
|
|
|
IF NETWORK_IS_GAME_IN_PROGRESS() AND NOT IS_ANY_NET_PLAYER_DRIVING_IN_CARWASH()
|
|
roll.state = CPS_SHUTDOWN
|
|
ENDIF
|
|
BREAK
|
|
CASE CPS_SHUTDOWN
|
|
roll.shapetestID = NULL
|
|
SAFE_REMOVE_PARTICLE_FX(roll.fxBrushID)
|
|
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iHitSoundID)
|
|
roll.fSpinRate -= tStep
|
|
//bDoShapeTest = TRUE
|
|
IF (roll.fSpinRate <= 0)
|
|
roll.fSpinRate = 0
|
|
roll.state = CPS_NULL
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iMoveSoundID)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iSpinSoundID)
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
roll.fRollerSpinAngle += roll.fSpinRate * TIMESTEP()
|
|
IF (roll.fRollerSpinAngle > 360.0)
|
|
roll.fRollerSpinAngle -= 360.0
|
|
ENDIF
|
|
|
|
_UPDATE_CARWASH_HROLLER_INTERNAL(roll)
|
|
|
|
SET_ENTITY_HEADING(roll.rollerID, roll.fRollerPivotAngle)
|
|
SET_ENTITY_ROTATION(roll.rollerID, GET_ENTITY_ROTATION(roll.rollerID) + <<roll.fRollerSpinAngle, 0, 0>>)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Create the carwash horizontal roller
|
|
/// PARAMS:
|
|
/// roll - roller reference
|
|
/// pos - position of the roller arm joint
|
|
/// head - heading
|
|
PROC CREATE_CARWASH_HROLLER(CARWASH_HROLLER &roll, VECTOR pos, FLOAT head = 0.0, FLOAT gz = 0.0)
|
|
FLOAT z
|
|
|
|
roll.vPosition = pos
|
|
roll.rollerID = CREATE_OBJECT(PROP_CARWASH_ROLLER_HORZ, pos, FALSE)
|
|
|
|
roll.vContactPoint = pos
|
|
roll.fTargetZ = pos.z
|
|
roll.fOriginalZ = pos.z
|
|
roll.fRollerPivotAngle = head
|
|
roll.bSetup = TRUE
|
|
|
|
roll.iNextCheckTime = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(1, ROLLER_CHECK_INTERVAL)
|
|
roll.iNextShapeTestTime = GET_GAME_TIMER() + GET_RANDOM_INT_IN_RANGE(2, SHAPE_CHECK_INTERVAL)
|
|
roll.fTriggerDist = ROLLER_TRIGGER_DIST
|
|
|
|
IF (gz = 0.0)
|
|
IF GET_GROUND_Z_FOR_3D_COORD(pos, z)
|
|
IF (z <> 0) AND (z <> INVALID_WORLD_Z)
|
|
roll.fGroundZero = z + ROLLER_RADIUS
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - HRoller GroundZero:", roll.fGroundZero)
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
roll.fGroundZero = gz
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_OK(roll.rollerID)
|
|
SET_ENTITY_HEADING(roll.rollerID, head)
|
|
FREEZE_ENTITY_POSITION(roll.rollerID, TRUE)
|
|
SET_ENTITY_COLLISION(roll.rollerID, TRUE)
|
|
SET_ENTITY_INVINCIBLE(roll.rollerID, TRUE)
|
|
//SET_ENTITY_HAS_GRAVITY(roll.rollerID, FALSE)
|
|
ENDIF
|
|
|
|
// we need to do a forced update here so the roller can find the ground point
|
|
UPDATE_CARWASH_HROLLER(roll)
|
|
ENDPROC
|
|
|
|
//----------------------
|
|
// VERTROLLER FUNCTIONS
|
|
//----------------------
|
|
|
|
PROC START_CARWASH_VERTROLLER_PARTICLES(CARWASH_VROLLER2 &roll)
|
|
INT i
|
|
|
|
REPEAT COUNT_OF(roll.rollerID) i
|
|
SAFE_REMOVE_PARTICLE_FX(roll.fxBrushID[i])
|
|
|
|
IF IS_ENTITY_OK(roll.rollerID[i]) //AND NOT (g_bInMultiplayer)
|
|
IF NOT DOES_PARTICLE_FX_LOOPED_EXIST(roll.fxBrushID[i])
|
|
roll.fxBrushID[i] = START_PARTICLE_FX_LOOPED_ON_ENTITY("ent_amb_car_wash", roll.rollerID[i], vRollerVertPosFX, vRollerVertRotFX)
|
|
ENDIF
|
|
ENDIF
|
|
ENDREPEAT
|
|
ENDPROC
|
|
|
|
PROC SHUTDOWN_CARWASH_VERTROLLER(CARWASH_VROLLER2 &roll)
|
|
IF IS_CARWASH_PART_RUNNING(roll.state)
|
|
SAFE_REMOVE_PARTICLE_FX(roll.fxBrushID[0])
|
|
SAFE_REMOVE_PARTICLE_FX(roll.fxBrushID[1])
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iMoveSoundID)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iSpinSoundID)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iHitSoundID)
|
|
roll.state = CPS_NULL
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
PROC SHARED_CLEANUP_DELETE_CARWASH_VERTROLLER(CARWASH_VROLLER2 &roll)
|
|
roll.state = CPS_NULL
|
|
SHUTDOWN_CARWASH_VERTROLLER(roll)
|
|
SAFE_DELETE_OBJECT(roll.pivotID)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Update the dual roller
|
|
/// PARAMS:
|
|
/// roll - roller reference
|
|
PROC CLEANUP_CARWASH_VERTROLLER(CARWASH_VROLLER2 &roll)
|
|
SHARED_CLEANUP_DELETE_CARWASH_VERTROLLER(roll)
|
|
SAFE_RELEASE_OBJECT(roll.rollerID[0])
|
|
SAFE_RELEASE_OBJECT(roll.rollerID[1])
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Update the dual roller
|
|
/// PARAMS:
|
|
/// roll - roller reference
|
|
PROC DELETE_CARWASH_VERTROLLER(CARWASH_VROLLER2 &roll)
|
|
SHARED_CLEANUP_DELETE_CARWASH_VERTROLLER(roll)
|
|
SAFE_DELETE_OBJECT(roll.rollerID[0])
|
|
SAFE_DELETE_OBJECT(roll.rollerID[1])
|
|
ENDPROC
|
|
|
|
|
|
PROC UPDATE_CARWASH_VERTROLLER_MOVEMENT(CARWASH_VROLLER2 &roll)
|
|
|
|
INT i
|
|
FLOAT fOldSpinAngle = roll.fRollerSpinAngle
|
|
FLOAT fOldOffset[2]
|
|
|
|
// handle and moving spinning
|
|
IF (roll.fSpinRate >= ROLLER_SPINRATE)
|
|
roll.fSpinRate = ROLLER_SPINRATE
|
|
ENDIF
|
|
|
|
IF (roll.fSpinRate <= 0)
|
|
roll.fSpinRate = 0
|
|
ENDIF
|
|
|
|
roll.fRollerSpinAngle += roll.fSpinRate * TIMESTEP()
|
|
IF (roll.fRollerSpinAngle < 0)
|
|
roll.fRollerSpinAngle += 360.0
|
|
ENDIF
|
|
|
|
IF (roll.fRollerSpinAngle > 360.0)
|
|
roll.fRollerSpinAngle -= 360.0
|
|
ENDIF
|
|
|
|
|
|
REPEAT COUNT_OF(roll.rollerID) i
|
|
|
|
fOldOffset[i] = roll.fOffset[i]
|
|
IF (roll.fOffset[i] < roll.fTgtOffset[i])
|
|
roll.fOffset[i] += roll.fMoveRate * TIMESTEP()
|
|
IF (roll.fOffset[i] > roll.fTgtOffset[i])
|
|
DO_CARWASH_PAD_RUMBLE(SHAPE_CHECK_INTERVAL, 64)
|
|
roll.fOffset[i] = roll.fTgtOffset[i]
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF (roll.fOffset[i] > roll.fTgtOffset[i])
|
|
roll.fOffset[i] -= roll.fMoveRate * TIMESTEP()
|
|
IF (roll.fOffset[i] < roll.fTgtOffset[i])
|
|
DO_CARWASH_PAD_RUMBLE(SHAPE_CHECK_INTERVAL, 64)
|
|
roll.fOffset[i] = roll.fTgtOffset[i]
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF (fOldOffset[i] <> roll.fOffset[i])
|
|
SET_ENTITY_COORDS(roll.rollerID[i], GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<roll.fOffset[i], 0, VROLLER_ZSHIFT>>))
|
|
ENDIF
|
|
|
|
IF (fOldSpinAngle <> roll.fRollerSpinAngle)
|
|
SET_ENTITY_HEADING(roll.rollerID[i], roll.fRollerSpinAngle)
|
|
ENDIF
|
|
ENDREPEAT
|
|
ENDPROC
|
|
|
|
PROC UPDATE_CARWASH_VERTROLLER_COLLISION(CARWASH_VROLLER2 &roll)
|
|
IF (roll.bCollisionOn <> roll.bOldCollision)
|
|
CPRINTLN(DEBUG_MISSION, "TURNING BRUSH ROL COLLISION:", roll.bCollisionOn)
|
|
SET_ENTITY_COLLISION(roll.rollerID[0], roll.bCollisionOn)
|
|
SET_ENTITY_COLLISION(roll.rollerID[1], roll.bCollisionOn)
|
|
ENDIF
|
|
|
|
roll.bOldCollision = roll.bCollisionOn
|
|
ENDPROC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Update the dual roller
|
|
/// PARAMS:
|
|
/// roll - roller reference
|
|
PROC UPDATE_CARWASH_VERTROLLER(CARWASH_VROLLER2 &roll, BOOL bSomeOneIn = TRUE, BOOL bAborted = FALSE)
|
|
VECTOR vec
|
|
FLOAT tStep = ROLLER_SPINRATE * TIMESTEP()
|
|
VECTOR v1, v2
|
|
|
|
ENTITY_INDEX hitEntity
|
|
SHAPETEST_STATUS shapeStatus
|
|
VECTOR vHitPos, vHitNormal
|
|
INT i, iHits
|
|
PLANE_SIDE psd
|
|
|
|
//FLOAT fDist
|
|
FLOAT vWidth
|
|
FLOAT vLength
|
|
VECTOR vvMin, vvMax
|
|
VEHICLE_INDEX vehicleIndex
|
|
INT iDriverSeatBoneIndex = -1
|
|
|
|
IF NOT roll.bSetup = TRUE
|
|
EXIT
|
|
ENDIF
|
|
|
|
UPDATE_CARWASH_VERTROLLER_MOVEMENT(roll)
|
|
|
|
IF IS_CARWASH_PART_RUNNING(roll.state)
|
|
IF (bSomeOneIn = FALSE)
|
|
CPRINTLN(DEBUG_MISSION, "Carwash VRoller - Shutdown No One is In Carwash")
|
|
roll.state = CPS_SHUTDOWN
|
|
ENDIF
|
|
|
|
IF NETWORK_IS_GAME_IN_PROGRESS() AND NOT IS_ANY_NET_PLAYER_DRIVING_IN_CARWASH()
|
|
CPRINTLN(DEBUG_MISSION, "Carwash VRoller - NET Shutdown No One is In Carwash")
|
|
bSomeOneIn = FALSE
|
|
roll.state = CPS_SHUTDOWN
|
|
ENDIF
|
|
|
|
IF (bSomeOneIn = FALSE)
|
|
roll.fSpinRate -= (tStep * 2.0)
|
|
IF (roll.fSpinRate <= 0)
|
|
roll.fSpinRate = 0
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iMoveSoundID)
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
roll.fSpinRate -= (tStep * 2.0)
|
|
IF (roll.fSpinRate <= 0)
|
|
roll.fSpinRate = 0
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iMoveSoundID)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// check sensors
|
|
FLOAT fFirstCheckYShift = -1.5 // we shift the file in check by this abount
|
|
FLOAT fCheckYShift = -ROLLER_RADIUS
|
|
// BOOL bBrushesDone
|
|
|
|
IF NOT (bAborted) AND (roll.state <> CPS_SHUTDOWN)
|
|
|
|
IF (GET_GAME_TIMER() > roll.iNextShapeTestTime)
|
|
vec = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<0, roll.fSensorOffset[0], 0>>)
|
|
roll.bSensorOn[0] = IS_CARWASH_POSITION_OCCUPIED(vec, roll.fSensorRadius[0])
|
|
|
|
vec = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<0, roll.fSensorOffset[1], 0>>)
|
|
roll.bSensorOn[1] = IS_CARWASH_POSITION_OCCUPIED(vec, roll.fSensorRadius[1])
|
|
|
|
roll.iNextShapeTestTime = GET_GAME_TIMER() + SHAPE_CHECK_INTERVAL
|
|
ENDIF
|
|
|
|
IF (bDrawDebugCarwash = TRUE)
|
|
vec = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<0, roll.fSensorOffset[0], 0>>)
|
|
|
|
IF (roll.bSensorOn[0])
|
|
DRAW_DEBUG_CIRCLE(vec, roll.fSensorRadius[0], 0, 255, 0, 255)
|
|
ELSE
|
|
DRAW_DEBUG_CIRCLE(vec, roll.fSensorRadius[0], 255, 0, 0, 255)
|
|
ENDIF
|
|
|
|
vec = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<0, roll.fSensorOffset[1], 0>>)
|
|
IF (roll.bSensorOn[1])
|
|
DRAW_DEBUG_CIRCLE(vec, roll.fSensorRadius[1], 0, 255, 0, 255)
|
|
ELSE
|
|
DRAW_DEBUG_CIRCLE(vec, roll.fSensorRadius[1], 0, 0, 255, 255)
|
|
ENDIF
|
|
|
|
DRAW_DEBUG_LINE(GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<-2.5, fFirstCheckYShift, VROLLER_CHECKZSHIFT>>),
|
|
GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<2.5, fFirstCheckYShift, VROLLER_CHECKZSHIFT>>))
|
|
|
|
vec = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<0, 0, VROLLER_CHECKZSHIFT>>)
|
|
DRAW_DEBUG_LINE(vec, vec + GET_ENTITY_FORWARD_VECTOR(roll.pivotID))
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
|
|
|
|
SWITCH (roll.state)
|
|
CASE CPS_NULL
|
|
IF NOT (bAborted)
|
|
IF (bSomeOneIn = TRUE) AND (roll.bSensorOn[0])
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iSpinSoundID)
|
|
roll.iSpinSoundID = GET_SOUND_ID()
|
|
PLAY_SOUND_FROM_ENTITY(roll.iSpinSoundID, "BRUSHES_SPINNING", roll.pivotID, "CARWASH_SOUNDS")
|
|
|
|
roll.fTgtOffset[0] = -ROLLER_RADIUS
|
|
roll.fTgtOffset[1] = ROLLER_RADIUS
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - VERT BRUSHES ACTIVATED")
|
|
|
|
roll.bCollisionOn = FALSE
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - TURNING BRUSH COLLISION OFF ON STARTUP")
|
|
//SET_ENTITY_COLLISION(roll.rollerID[0], roll.bCollisionOn)
|
|
//SET_ENTITY_COLLISION(roll.rollerID[1], roll.bCollisionOn)
|
|
|
|
roll.state = CPS_STARTUP
|
|
roll.bHitCheck[0] = FALSE
|
|
roll.bHitCheck[1] = FALSE
|
|
roll.bOldHitCheck[0] = FALSE
|
|
roll.bOldHitCheck[1] = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE CPS_STARTUP
|
|
roll.fSpinRate += tStep
|
|
|
|
vec = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<0, roll.fSensorOffset[0], 0>>)
|
|
vehicleIndex = GET_RANDOM_VEHICLE_IN_SPHERE(vec, 2.0, DUMMY_MODEL_FOR_SCRIPT, VEHICLE_SEARCH_FLAG_RETURN_VEHICLES_CONTAINING_A_PLAYER | VEHICLE_SEARCH_FLAG_ALLOW_VEHICLE_OCCUPANTS_TO_BE_PERFORMING_A_SCRIPTED_TASK)
|
|
IF CHECK_ENTITY_IS_VEHICLE_OK(vehicleIndex)
|
|
SET_ENTITY_NO_COLLISION_ENTITY(vehicleIndex, roll.rollerID[0], TRUE)
|
|
SET_ENTITY_NO_COLLISION_ENTITY(vehicleIndex, roll.rollerID[1], TRUE)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - COLLISION OFF BETWEEN BUMPERS")
|
|
ENDIF
|
|
|
|
IF (roll.fSpinRate >= ROLLER_SPINRATE)
|
|
roll.fSpinRate = ROLLER_SPINRATE
|
|
|
|
START_CARWASH_VERTROLLER_PARTICLES(roll)
|
|
roll.iMoveSoundID = GET_SOUND_ID()
|
|
PLAY_SOUND_FROM_ENTITY(roll.iMoveSoundID, "BRUSHES_MOVE", roll.pivotID, "CARWASH_SOUNDS")
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - VERT BRUSH SPIN UP COMPLETE")
|
|
|
|
roll.state = CPS_WARMUP
|
|
|
|
|
|
|
|
ENDIF
|
|
BREAK
|
|
CASE CPS_WARMUP
|
|
IF (roll.shapeTestID = NULL)
|
|
IF (bUseOldVerticleBrushCheck)
|
|
vec = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<0, -1, 0>>)
|
|
roll.shapeTestID = START_SHAPE_TEST_CAPSULE(vec, vec + <<0, 0, 1>>, 2.5, SCRIPT_INCLUDE_VEHICLE)
|
|
ELSE
|
|
vec = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<-3.0, fFirstCheckYShift, VROLLER_CHECKZSHIFT>>)
|
|
roll.shapeTestID = START_SHAPE_TEST_LOS_PROBE(vec, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<0, fFirstCheckYShift, VROLLER_CHECKZSHIFT>>), SCRIPT_INCLUDE_VEHICLE)
|
|
ENDIF
|
|
|
|
IF (roll.shapeTestID = NULL)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - UPDATE_CARWASH_VERTROLLER - CPS_WARMUP - CAN'T GET VALID SHAPE TEST")
|
|
ENDIF
|
|
ELSE
|
|
shapeStatus = GET_SHAPE_TEST_RESULT(roll.shapeTestID, iHits, vHitPos, vHitNormal, hitEntity)
|
|
IF (shapeStatus = SHAPETEST_STATUS_RESULTS_READY)
|
|
IF CHECK_ENTITY_IS_VEHICLE_OK(hitEntity)
|
|
roll.activeVehicle = GET_VEHICLE_INDEX_FROM_ENTITY_INDEX(hitEntity)
|
|
IF IS_ENTITY_ALIVE(roll.activeVehicle)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - ACTIVE VEHICLE XX GET:", GET_MODEL_NAME_OF_VEHICLE_FOR_DEBUG_ONLY(roll.activeVehicle))
|
|
ELSE
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - ACTIVE VEHICLE XX GET: dead vehicle")
|
|
ENDIF
|
|
|
|
GET_MODEL_DIMENSIONS(GET_ENTITY_MODEL(roll.activeVehicle), vvMin, vvMax)
|
|
vWidth = ABSF(vvMax.x - vvMin.x)
|
|
|
|
IF (bUseOldVerticleBrushCheck)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - USING OLD STYLE BRUSH CHECK:")
|
|
roll.fTgtOffset[0] = -((ROLLER_RADIUS * 0.75) + (vWidth / 2.0))
|
|
roll.fTgtOffset[1] = (ROLLER_RADIUS * 0.75) + (vWidth / 2.0)
|
|
ELSE
|
|
vec = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(roll.pivotID, vHitPos + (GET_ENTITY_FORWARD_VECTOR(roll.pivotID) * -fFirstCheckYShift))
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - VROLLER MOVE RATE IS 1.5")
|
|
roll.fMoveRate = 1.5
|
|
//roll.fTgtOffset[0] = v.x - ROLLER_RADIUS
|
|
//roll.fTgtOffset[1] = (v.x * -1) + ROLLER_RADIUS
|
|
ENDIF
|
|
|
|
IF (iHits = 0)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - SOMETHING HAS COCKED UP HERE DEFAULTING TO DEFAULT WIDTH")
|
|
roll.fTgtOffset[0] = -((ROLLER_RADIUS) + (vWidth / 2.0))
|
|
roll.fTgtOffset[1] = (ROLLER_RADIUS) + (vWidth / 2.0)
|
|
ENDIF
|
|
|
|
roll.state = CPS_ACTIVE
|
|
roll.fMoveRate = 1.5
|
|
roll.bHitCheck[0] = FALSE
|
|
roll.bHitCheck[1] = FALSE
|
|
roll.bOldHitCheck[0] = FALSE
|
|
roll.bOldHitCheck[1] = FALSE
|
|
roll.iNextBrushShapeTestTime[0] = GET_GAME_TIMER() + 32
|
|
roll.iNextBrushShapeTestTime[1] = GET_GAME_TIMER() + 64
|
|
ENDIF
|
|
ENDIF
|
|
roll.shapeTestID = NULL
|
|
ENDIF
|
|
BREAK
|
|
CASE CPS_ACTIVE
|
|
|
|
// wait till car is in front of brushes before pulling them in.
|
|
IF IS_ENTITY_ALIVE(roll.activeVehicle)
|
|
SET_ENTITY_NO_COLLISION_ENTITY(roll.activeVehicle, roll.rollerID[0], TRUE)
|
|
SET_ENTITY_NO_COLLISION_ENTITY(roll.activeVehicle, roll.rollerID[1], TRUE)
|
|
|
|
GET_MODEL_DIMENSIONS(GET_ENTITY_MODEL(roll.activeVehicle), vvMin, vvMax)
|
|
vLength = ABSF(vvMax.y - vvMin.y) / 2.0
|
|
vWidth = ABSF(vvMax.x - vvMin.x)
|
|
|
|
|
|
|
|
|
|
psd = GET_PLANE_SIDE(GET_ENTITY_FORWARD_VECTOR(roll.pivotID), GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<0, vLength, 0>>), GET_ENTITY_COORDS(roll.activeVehicle))
|
|
IF (psd = INFRONT_PLANE)
|
|
roll.fTgtOffset[0] = -(ROLLER_RADIUS)
|
|
roll.fTgtOffset[1] = (ROLLER_RADIUS)
|
|
ELSE
|
|
IF (bUseOldVerticleBrushCheck)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - USING OLD STYLE BRUSH CHECK:")
|
|
roll.fTgtOffset[0] = -((ROLLER_RADIUS * ROLLER_SHIFT_FACTOR) + (vWidth / 2.0))
|
|
roll.fTgtOffset[1] = (ROLLER_RADIUS * ROLLER_SHIFT_FACTOR) + (vWidth / 2.0)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - VROLLER MOVE RATE IS 1.0")
|
|
roll.fMoveRate = 1.0
|
|
ELSE
|
|
|
|
REPEAT COUNT_OF(roll.rollerID) i
|
|
|
|
v1 = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<0, fCheckYShift, VROLLER_CHECKZSHIFT>>)
|
|
IF (i = 0)
|
|
v2 = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<-fShapeTestXSeperation, fCheckYShift, VROLLER_CHECKZSHIFT>>)
|
|
ELSE
|
|
v2 = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<fShapeTestXSeperation, fCheckYShift, VROLLER_CHECKZSHIFT>>)
|
|
ENDIF
|
|
|
|
iDriverSeatBoneIndex = GET_ENTITY_BONE_INDEX_BY_NAME(roll.activeVehicle, "seat_dside_f")
|
|
IF (iDriverSeatBoneIndex <> -1)
|
|
vec = GET_WORLD_POSITION_OF_ENTITY_BONE(roll.activeVehicle, iDriverSeatBoneIndex)
|
|
v1.z = vec.z
|
|
v2.z = vec.z
|
|
ENDIF
|
|
|
|
IF bDrawDebugCarwash
|
|
DRAW_DEBUG_LINE(v1, v2)
|
|
ENDIF
|
|
|
|
IF (roll.brushShapeTestID[i] = NULL)
|
|
|
|
IF (GET_GAME_TIMER() > roll.iNextBrushShapeTestTime[i])
|
|
|
|
IF (bUseNewSweptSphereTest = TRUE) OR (GET_VEHICLE_MOD(roll.activeVehicle, MOD_SPOILER) != -1)
|
|
roll.brushShapeTestID[i] = START_SHAPE_TEST_SWEPT_SPHERE(v2, v1, fSweepSphereRadius, SCRIPT_INCLUDE_VEHICLE)
|
|
ELSE
|
|
roll.brushShapeTestID[i] = START_SHAPE_TEST_LOS_PROBE(v2, v1, SCRIPT_INCLUDE_VEHICLE)
|
|
ENDIF
|
|
|
|
IF (roll.brushShapeTestID[i] = NULL)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: CAN'T GET SHAPETEST FOR VERTICAL BRUSH ", i)
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
shapeStatus = GET_SHAPE_TEST_RESULT(roll.brushShapeTestID[i], iHits, vHitPos, vHitNormal, hitEntity)
|
|
IF (shapeStatus = SHAPETEST_STATUS_RESULTS_READY)
|
|
roll.bOldHitCheck[i] = roll.bHitCheck[i]
|
|
roll.bHitCheck[i] = FALSE
|
|
|
|
IF (iHits > 0)
|
|
|
|
IF (bDrawDebugCarwash)
|
|
DRAW_DEBUG_SPHERE(vHitPos, 0.06625)
|
|
|
|
ENDIF
|
|
|
|
//CPRINTLN(DEBUG_MISSION, "HIT HIT HIT - BRUSH:", i)
|
|
roll.bHitCheck[i] = TRUE
|
|
ENDIF
|
|
|
|
IF CHECK_ENTITY_IS_VEHICLE_OK(hitEntity)
|
|
vec = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(roll.pivotID, vHitPos + (GET_ENTITY_FORWARD_VECTOR(roll.pivotID) * -fCheckYShift))
|
|
roll.bHitCheck[i] = TRUE
|
|
|
|
IF (i = 0)
|
|
roll.fTgtOffset[i] = vec.x - ROLLER_RADIUS
|
|
ELSE
|
|
roll.fTgtOffset[i] = vec.x + ROLLER_RADIUS
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
roll.brushShapeTestID[i] = NULL
|
|
roll.iNextBrushShapeTestTime[i] = GET_GAME_TIMER() + 120
|
|
ENDIF
|
|
|
|
|
|
IF (roll.bOldHitCheck[i] <> roll.bHitCheck[i])
|
|
IF (roll.bOldHitCheck[i] = TRUE) AND (roll.bHitCheck[i] = FALSE)
|
|
CPRINTLN(DEBUG_MISSION, "CARWASH BRUSH ", i, " ISN'T HITTING ANYTHING ANY MORE")
|
|
// bBrushesDone = true
|
|
ENDIF
|
|
|
|
IF (roll.bOldHitCheck[i] = FALSE) AND (roll.bHitCheck[i] = TRUE)
|
|
CPRINTLN(DEBUG_MISSION, "CARWASH BRUSH ", i, " HAS STARTED HITTING THINGS")
|
|
ENDIF
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
|
|
// // STH: Removed bBrushesDone for b*2019238 - The hit test was briefly returning false in middle of cars pass through rollers, so the rollers came together and clipped through rest of the car
|
|
// IF (bBrushesDone = TRUE)
|
|
// CPRINTLN(DEBUG_MISSION, "CARWASH BRUSHED START WARM DOWN")
|
|
// roll.fTgtOffset[0] = -(ROLLER_RADIUS)
|
|
// roll.fTgtOffset[1] = (ROLLER_RADIUS)
|
|
// roll.fMoveRate = roll.fShutDownMoveRate
|
|
// CPRINTLN(DEBUG_MISSION, "[CARWASH] - VROLLER MOVE RATE IS ", roll.fShutDownMoveRate)
|
|
// SAFE_REMOVE_PARTICLE_FX(roll.fxBrushID[0])
|
|
// SAFE_REMOVE_PARTICLE_FX(roll.fxBrushID[1])
|
|
// roll.state = CPS_WARMDOWN
|
|
// EXIT
|
|
// ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// check to see if car is properly in front of point
|
|
psd = GET_PLANE_SIDE(GET_ENTITY_FORWARD_VECTOR(roll.pivotID), GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<0, vLength * 1.25, 0>>), GET_ENTITY_COORDS(roll.activeVehicle))
|
|
IF (psd = INFRONT_PLANE)
|
|
roll.fSpinRate -= (tStep * 2)
|
|
|
|
IF (roll.fSpinRate < 0)
|
|
roll.fSpinRate = 0
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iHitSoundID)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iSpinSoundID)
|
|
|
|
SAFE_REMOVE_PARTICLE_FX(roll.fxBrushID[0])
|
|
SAFE_REMOVE_PARTICLE_FX(roll.fxBrushID[1])
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - BRUSHES ARE IN FRONT TURNING THEM OFF")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF NOT (roll.bSensorOn[0] OR roll.bSensorOn[1])
|
|
SAFE_REMOVE_PARTICLE_FX(roll.fxBrushID[0])
|
|
SAFE_REMOVE_PARTICLE_FX(roll.fxBrushID[1])
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - SHUTDOWN SPIN RATE:", roll.fSpinRate)
|
|
roll.state = CPS_SHUTDOWN
|
|
ENDIF
|
|
BREAK
|
|
CASE CPS_WARMDOWN
|
|
IF IS_ENTITY_ALIVE(roll.activeVehicle)
|
|
SET_ENTITY_NO_COLLISION_ENTITY(roll.activeVehicle, roll.rollerID[0], TRUE)
|
|
SET_ENTITY_NO_COLLISION_ENTITY(roll.activeVehicle, roll.rollerID[1], TRUE)
|
|
GET_MODEL_DIMENSIONS(GET_ENTITY_MODEL(roll.activeVehicle), vvMin, vvMax)
|
|
vLength = ABSF(vvMax.y - vvMin.y) / 2.0
|
|
vWidth = ABSF(vvMax.x - vvMin.x)
|
|
|
|
// check to see if car is properly in front of point
|
|
psd = GET_PLANE_SIDE(GET_ENTITY_FORWARD_VECTOR(roll.pivotID), GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<0, vLength * 1.25, 0>>), GET_ENTITY_COORDS(roll.activeVehicle))
|
|
IF (psd = INFRONT_PLANE)
|
|
roll.fSpinRate -= (tStep * 2)
|
|
|
|
IF (roll.fSpinRate < 0)
|
|
roll.fSpinRate = 0
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iHitSoundID)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iSpinSoundID)
|
|
|
|
SAFE_REMOVE_PARTICLE_FX(roll.fxBrushID[0])
|
|
SAFE_REMOVE_PARTICLE_FX(roll.fxBrushID[1])
|
|
roll.state = CPS_SHUTDOWN
|
|
|
|
//CPRINTLN(DEBUG_MISSION, "[CARWASH] - BRUSHES ARE IN FRONT TURNING THEM OFF")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF NOT (roll.bSensorOn[0] OR roll.bSensorOn[1])
|
|
SAFE_REMOVE_PARTICLE_FX(roll.fxBrushID[0])
|
|
SAFE_REMOVE_PARTICLE_FX(roll.fxBrushID[1])
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - SHUTDOWN SPIN RATE:", roll.fSpinRate)
|
|
roll.state = CPS_SHUTDOWN
|
|
ENDIF
|
|
BREAK
|
|
CASE CPS_SHUTDOWN
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iHitSoundID)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iSpinSoundID)
|
|
|
|
SAFE_REMOVE_PARTICLE_FX(roll.fxBrushID[0])
|
|
SAFE_REMOVE_PARTICLE_FX(roll.fxBrushID[1])
|
|
|
|
roll.fSpinRate -= tStep
|
|
roll.fTgtOffset[0] = -VROLLER_SEP //-ROLLER_RADIUS * 2.0
|
|
roll.fTgtOffset[1] = VROLLER_SEP //ROLLER_RADIUS * 2.0
|
|
|
|
roll.fMoveRate = 1.5
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - VROLLER MOVE RATE IS ", roll.fMoveRate)
|
|
|
|
roll.bHitCheck[0] = FALSE
|
|
roll.bHitCheck[1] = FALSE
|
|
roll.bOldHitCheck[0] = FALSE
|
|
roll.bOldHitCheck[1] = FALSE
|
|
|
|
IF (roll.fSpinRate <= 0)
|
|
roll.fSpinRate = 0
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iMoveSoundID)
|
|
ENDIF
|
|
|
|
// if aborted wait till area is clear before allowing collsion to turn back on
|
|
IF (GET_GAME_TIMER() > roll.iNextShapeTestTime)
|
|
IF NOT IS_CARWASH_POSITION_OCCUPIED(roll.vBasePosition, 1.0)
|
|
roll.bCollisionOn = TRUE
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - TURNING BRUSH COLLISION ON AFTER SHUTDOWN")
|
|
SET_ENTITY_COLLISION(roll.rollerID[0], roll.bCollisionOn)
|
|
SET_ENTITY_COLLISION(roll.rollerID[1], roll.bCollisionOn)
|
|
|
|
roll.iNextShapeTestTime = 0
|
|
roll.state = CPS_NULL
|
|
ELSE
|
|
roll.iNextShapeTestTime = GET_GAME_TIMER() + SHAPE_CHECK_INTERVAL
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Update the dual roller
|
|
/// PARAMS:
|
|
/// roll - roller reference
|
|
PROC UPDATE_CARWASH_VERTROLLER_MP(CARWASH_VROLLER2 &roll, BOOL bSomeOneIn = TRUE, BOOL bAborted = FALSE)
|
|
|
|
VECTOR vec, v1, v2
|
|
VEHICLE_INDEX vehicleIndex
|
|
FLOAT fFirstCheckYShift = -1.5 // we shift the file in check by this abount
|
|
FLOAT fCheckYShift = -ROLLER_RADIUS
|
|
|
|
INT i, iHits
|
|
ENTITY_INDEX hitEntity
|
|
SHAPETEST_STATUS shapeStatus
|
|
VECTOR vHitPos, vHitNormal
|
|
FLOAT tStep = ROLLER_SPINRATE * TIMESTEP()
|
|
|
|
INT iDriverSeatBoneIndex = -1
|
|
|
|
PLANE_SIDE psd
|
|
FLOAT vLength
|
|
VECTOR vvMin, vvMax
|
|
|
|
IF NOT roll.bSetup = TRUE
|
|
EXIT
|
|
ENDIF
|
|
|
|
UPDATE_CARWASH_VERTROLLER_MOVEMENT(roll)
|
|
|
|
IF IS_CARWASH_PART_RUNNING(roll.state)
|
|
IF (bSomeOneIn = FALSE)
|
|
CPRINTLN(DEBUG_MISSION, "Carwash VRoller - Shutdown No One is In Carwash")
|
|
roll.state = CPS_SHUTDOWN
|
|
ENDIF
|
|
|
|
IF NETWORK_IS_GAME_IN_PROGRESS() AND NOT IS_ANY_NET_PLAYER_DRIVING_IN_CARWASH()
|
|
CPRINTLN(DEBUG_MISSION, "Carwash VRoller - NET Shutdown No One is In Carwash")
|
|
bSomeOneIn = FALSE
|
|
roll.state = CPS_SHUTDOWN
|
|
ENDIF
|
|
|
|
IF (bSomeOneIn = FALSE)
|
|
roll.fSpinRate -= (tStep * 2.0)
|
|
IF (roll.fSpinRate <= 0)
|
|
roll.fSpinRate = 0
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iMoveSoundID)
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
roll.fSpinRate -= (tStep * 2.0)
|
|
IF (roll.fSpinRate <= 0)
|
|
roll.fSpinRate = 0
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iMoveSoundID)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// update sensors
|
|
IF NOT (bAborted) AND (roll.state <> CPS_SHUTDOWN)
|
|
IF (GET_GAME_TIMER() > roll.iNextShapeTestTime)
|
|
vec = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<0, roll.fSensorOffset[0], 0>>)
|
|
roll.bSensorOn[0] = IS_CARWASH_POSITION_OCCUPIED(vec, roll.fSensorRadius[0])
|
|
|
|
vec = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<0, roll.fSensorOffset[1], 0>>)
|
|
roll.bSensorOn[1] = IS_CARWASH_POSITION_OCCUPIED(vec, roll.fSensorRadius[1])
|
|
|
|
roll.iNextShapeTestTime = GET_GAME_TIMER() + SHAPE_CHECK_INTERVAL
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// draw debug for sensors
|
|
IF (bDrawDebugCarwash = TRUE)
|
|
vec = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<0, roll.fSensorOffset[0], 0>>)
|
|
|
|
IF (roll.bSensorOn[0])
|
|
DRAW_DEBUG_CIRCLE(vec, roll.fSensorRadius[0], 0, 255, 0, 255)
|
|
ELSE
|
|
DRAW_DEBUG_CIRCLE(vec, roll.fSensorRadius[0], 255, 0, 0, 255)
|
|
ENDIF
|
|
|
|
vec = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<0, roll.fSensorOffset[1], 0>>)
|
|
IF (roll.bSensorOn[1])
|
|
DRAW_DEBUG_CIRCLE(vec, roll.fSensorRadius[1], 0, 255, 0, 255)
|
|
ELSE
|
|
DRAW_DEBUG_CIRCLE(vec, roll.fSensorRadius[1], 0, 0, 255, 255)
|
|
ENDIF
|
|
|
|
DRAW_DEBUG_LINE(GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<-2.5, fFirstCheckYShift, VROLLER_CHECKZSHIFT>>),
|
|
GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<2.5, fFirstCheckYShift, VROLLER_CHECKZSHIFT>>))
|
|
|
|
vec = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<0, 0, VROLLER_CHECKZSHIFT>>)
|
|
DRAW_DEBUG_LINE(vec, vec + GET_ENTITY_FORWARD_VECTOR(roll.pivotID))
|
|
ENDIF
|
|
|
|
// update state
|
|
SWITCH (roll.state)
|
|
CASE CPS_NULL
|
|
|
|
// if the front sensor is on run shape test
|
|
IF NOT (roll.bSensorOn[0])
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF (roll.shapeTestID = NULL)
|
|
vec = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<0, roll.fSensorOffset[0], 0>>)
|
|
roll.shapeTestID = START_SHAPE_TEST_CAPSULE(vec, vec + <<0, 0, 1>>, 2.25, SCRIPT_INCLUDE_VEHICLE)
|
|
ELSE
|
|
shapeStatus = GET_SHAPE_TEST_RESULT(roll.shapeTestID, iHits, vHitPos, vHitNormal, hitEntity)
|
|
IF (shapeStatus = SHAPETEST_STATUS_RESULTS_READY)
|
|
IF CHECK_ENTITY_IS_VEHICLE_OK(hitEntity)
|
|
vehicleIndex = GET_VEHICLE_INDEX_FROM_ENTITY_INDEX(hitEntity)
|
|
IF IS_DIRECTION_WITHIN_DEGRESS_OF_DESIRED_DIRECTION_SIGNED(GET_ENTITY_FORWARD_VECTOR(vehicleIndex), GET_ENTITY_FORWARD_VECTOR(roll.pivotID), 10.0)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - PLAYER IS POINTING THE RIGHT WAY")
|
|
|
|
vec = GET_ENTITY_SPEED_VECTOR(vehicleIndex, TRUE)
|
|
IF (vec.y <= 0)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - PLAYER IS POINTING THE RIGHT WAY BUT IS REVERSING OR STOPPED")
|
|
ELSE
|
|
roll.state = CPS_STARTUP
|
|
roll.activeVehicle = vehicleIndex
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iSpinSoundID)
|
|
roll.iSpinSoundID = GET_SOUND_ID()
|
|
PLAY_SOUND_FROM_ENTITY(roll.iSpinSoundID, "BRUSHES_SPINNING", roll.pivotID, "CARWASH_SOUNDS")
|
|
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - PLAYER IS POINTING THE RIGHT WAY AND MOVING IN THE RIGHT WAY")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
roll.shapeTestID = NULL
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE CPS_STARTUP
|
|
roll.fSpinRate += tStep
|
|
SET_ENTITY_NO_COLLISION_ENTITY(roll.activeVehicle, roll.rollerID[0], TRUE)
|
|
SET_ENTITY_NO_COLLISION_ENTITY(roll.activeVehicle, roll.rollerID[1], TRUE)
|
|
|
|
IF IS_ENTITY_ALIVE(roll.activeVehicle)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - COLLISION OFF BETWEEN BUMPERS AND ", GET_MODEL_NAME_OF_VEHICLE_FOR_DEBUG_ONLY(roll.activeVehicle))
|
|
ELSE
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - COLLISION OFF BETWEEN BUMPERS AND dead vehicle")
|
|
ENDIF
|
|
|
|
IF (roll.fSpinRate >= ROLLER_SPINRATE)
|
|
roll.fSpinRate = ROLLER_SPINRATE
|
|
START_CARWASH_VERTROLLER_PARTICLES(roll)
|
|
roll.iMoveSoundID = GET_SOUND_ID()
|
|
PLAY_SOUND_FROM_ENTITY(roll.iMoveSoundID, "BRUSHES_MOVE", roll.pivotID, "CARWASH_SOUNDS")
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - VERT BRUSH SPIN UP COMPLETE")
|
|
roll.state = CPS_WARMUP
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE CPS_WARMUP
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - SET VERTROLL STATE - CPS_ACTIVE")
|
|
roll.state = CPS_ACTIVE
|
|
BREAK
|
|
|
|
CASE CPS_ACTIVE
|
|
IF NOT CHECK_ENTITY_IS_VEHICLE_OK(roll.activeVehicle)
|
|
roll.state = CPS_WARMDOWN
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF NOT IS_CARWASH_PED_OK(GET_PED_IN_VEHICLE_SEAT(roll.activeVehicle))
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - SET VERTROLL STATE - CPS_WARMDOWN - PED IN CAR IS NOT OKAY")
|
|
roll.state = CPS_WARMDOWN
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF NETWORK_IS_GAME_IN_PROGRESS() AND NOT IS_ANY_NET_PLAYER_DRIVING_IN_CARWASH()
|
|
roll.state = CPS_WARMDOWN
|
|
EXIT
|
|
ENDIF
|
|
|
|
// wait for vehicle to leave
|
|
GET_MODEL_DIMENSIONS(GET_ENTITY_MODEL(roll.activeVehicle), vvMin, vvMax)
|
|
vLength = ABSF(vvMax.y - vvMin.y) / 2.0
|
|
|
|
psd = GET_PLANE_SIDE(GET_ENTITY_FORWARD_VECTOR(roll.pivotID), GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<0, vLength, 0>>), GET_ENTITY_COORDS(roll.activeVehicle))
|
|
IF (psd = INFRONT_PLANE)
|
|
roll.fTgtOffset[0] = -(ROLLER_RADIUS)
|
|
roll.fTgtOffset[1] = (ROLLER_RADIUS)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - SET VERTROLL STATE - CPS_WARMDOWN - CAR HAS GONE PAST BRUSHES")
|
|
roll.state = CPS_WARMDOWN
|
|
EXIT
|
|
ENDIF
|
|
|
|
REPEAT COUNT_OF(roll.rollerID) i
|
|
IF (i = 0)
|
|
v1 = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<1.0, fCheckYShift, VROLLER_CHECKZSHIFT>>)
|
|
v2 = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<-fShapeTestXSeperation, fCheckYShift, VROLLER_CHECKZSHIFT>>)
|
|
ELSE
|
|
v1 = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<-1.0, fCheckYShift, VROLLER_CHECKZSHIFT>>)
|
|
v2 = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<fShapeTestXSeperation, fCheckYShift, VROLLER_CHECKZSHIFT>>)
|
|
ENDIF
|
|
|
|
iDriverSeatBoneIndex = GET_ENTITY_BONE_INDEX_BY_NAME(roll.activeVehicle, "seat_dside_f")
|
|
IF (iDriverSeatBoneIndex <> -1)
|
|
vec = GET_WORLD_POSITION_OF_ENTITY_BONE(roll.activeVehicle, iDriverSeatBoneIndex)
|
|
v1.z = vec.z
|
|
v2.z = vec.z
|
|
ENDIF
|
|
|
|
IF (roll.brushShapeTestID[i] = NULL)
|
|
IF (GET_GAME_TIMER() > roll.iNextBrushShapeTestTime[i])
|
|
IF (bUseNewSweptSphereTest = TRUE) OR (GET_VEHICLE_MOD(roll.activeVehicle, MOD_SPOILER) != -1)
|
|
roll.brushShapeTestID[i] = START_SHAPE_TEST_SWEPT_SPHERE(v2, v1, fSweepSphereRadius, SCRIPT_INCLUDE_VEHICLE)
|
|
ELSE
|
|
roll.brushShapeTestID[i] = START_SHAPE_TEST_LOS_PROBE(v2, v1, SCRIPT_INCLUDE_VEHICLE)
|
|
ENDIF
|
|
|
|
IF (roll.brushShapeTestID[i] = NULL)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: CAN'T GET SHAPETEST FOR VERTICAL BRUSH ", i)
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
shapeStatus = GET_SHAPE_TEST_RESULT(roll.brushShapeTestID[i], iHits, vHitPos, vHitNormal, hitEntity)
|
|
IF (shapeStatus = SHAPETEST_STATUS_RESULTS_READY)
|
|
roll.bOldHitCheck[i] = roll.bHitCheck[i]
|
|
roll.bHitCheck[i] = FALSE
|
|
|
|
IF (iHits > 0)
|
|
//IF (bDrawDebugCarwash)
|
|
DRAW_DEBUG_SPHERE(vHitPos, 0.06625)
|
|
//ENDIF
|
|
roll.bHitCheck[i] = TRUE
|
|
ENDIF
|
|
|
|
IF CHECK_ENTITY_IS_VEHICLE_OK(hitEntity)
|
|
vec = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(roll.pivotID, vHitPos + (GET_ENTITY_FORWARD_VECTOR(roll.pivotID) * -fCheckYShift))
|
|
|
|
IF (i = 0)
|
|
roll.fTgtOffset[i] = vec.x - ROLLER_RADIUS
|
|
ELSE
|
|
roll.fTgtOffset[i] = vec.x + ROLLER_RADIUS
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
roll.brushShapeTestID[i] = NULL
|
|
roll.iNextBrushShapeTestTime[i] = GET_GAME_TIMER() + 120
|
|
ENDIF
|
|
|
|
IF (roll.bOldHitCheck[i] <> roll.bHitCheck[i])
|
|
IF (roll.bOldHitCheck[i] = TRUE) AND (roll.bHitCheck[i] = FALSE)
|
|
CPRINTLN(DEBUG_MISSION, "CARWASH BRUSH ", i, " ISN'T HITTING ANYTHING ANY MORE")
|
|
ENDIF
|
|
|
|
IF (roll.bOldHitCheck[i] = FALSE) AND (roll.bHitCheck[i] = TRUE)
|
|
CPRINTLN(DEBUG_MISSION, "CARWASH BRUSH ", i, " HAS STARTED HITTING THINGS")
|
|
ENDIF
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
SET_ENTITY_NO_COLLISION_ENTITY(roll.activeVehicle, roll.rollerID[0], TRUE)
|
|
SET_ENTITY_NO_COLLISION_ENTITY(roll.activeVehicle, roll.rollerID[1], TRUE)
|
|
|
|
IF (bAborted)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - SET VERTROLL STATE - CPS_WARMDOWN - PED IN CAR IS NOT OKAY")
|
|
roll.state = CPS_WARMDOWN
|
|
EXIT
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE CPS_WARMDOWN
|
|
roll.activeVehicle = NULL
|
|
roll.fTgtOffset[0] = -roll.fOriginalSep / 2.0
|
|
roll.fTgtOffset[1] = roll.fOriginalSep / 2.0
|
|
|
|
roll.fSpinRate -= (tStep)
|
|
|
|
IF (roll.fSpinRate <= 0)
|
|
roll.fSpinRate = 0
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iHitSoundID)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iSpinSoundID)
|
|
|
|
SAFE_REMOVE_PARTICLE_FX(roll.fxBrushID[0])
|
|
SAFE_REMOVE_PARTICLE_FX(roll.fxBrushID[1])
|
|
ENDIF
|
|
|
|
IF (roll.fTgtOffset[0] = roll.fOffset[0]) AND (roll.fTgtOffset[1] = roll.fOffset[1]) AND (roll.fSpinRate = 0)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iMoveSoundID)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - SET VERTROLL STATE - CPS_SHUTDOWN")
|
|
roll.state = CPS_SHUTDOWN
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE CPS_SHUTDOWN
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iMoveSoundID)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iHitSoundID)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iSpinSoundID)
|
|
|
|
SAFE_REMOVE_PARTICLE_FX(roll.fxBrushID[0])
|
|
SAFE_REMOVE_PARTICLE_FX(roll.fxBrushID[1])
|
|
|
|
roll.fTgtOffset[0] = -roll.fOriginalSep / 2.0
|
|
roll.fTgtOffset[1] = roll.fOriginalSep / 2.0
|
|
roll.fMoveRate = 1.5
|
|
|
|
// if aborted wait till area is clear before allowing collsion to turn back on
|
|
IF (GET_GAME_TIMER() > roll.iNextShapeTestTime)
|
|
IF NOT IS_CARWASH_POSITION_OCCUPIED(roll.vBasePosition, 1.0)
|
|
roll.bCollisionOn = TRUE
|
|
roll.iNextShapeTestTime = 0
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - SET VERTROLL STATE - CPS_NULL")
|
|
roll.state = CPS_NULL
|
|
ELSE
|
|
roll.iNextShapeTestTime = GET_GAME_TIMER() + SHAPE_CHECK_INTERVAL
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
PROC RESET_CARWASH_VERTROLLER_PROPS(CARWASH_VROLLER2 &roll)
|
|
VECTOR v
|
|
|
|
IF IS_ENTITY_ALIVE(roll.pivotID)
|
|
SET_ENTITY_COORDS_NO_OFFSET(roll.pivotID, roll.vBasePosition)
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_ALIVE(roll.rollerID[0])
|
|
v = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<roll.fTgtOffset[0], 0, VROLLER_ZSHIFT>>)
|
|
SET_ENTITY_COORDS(roll.rollerID[0], v)
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_ALIVE(roll.rollerID[1])
|
|
v = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<roll.fTgtOffset[1], 0, VROLLER_ZSHIFT>>)
|
|
SET_ENTITY_COORDS(roll.rollerID[1], v)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
PROC CREATE_CARWASH_VERTROLLER(CARWASH_VROLLER2 &roll, VECTOR pos, FLOAT head, float sep = DEFAULT_DUALVROLL_SEP, FLOAT zShift = 0.0)
|
|
|
|
FLOAT z
|
|
VECTOR v
|
|
|
|
IF GET_GROUND_Z_FOR_3D_COORD(pos + <<0, 0, 0.3>>, z)
|
|
//pos.z = z
|
|
ENDIF
|
|
|
|
roll.vBasePosition = pos
|
|
roll.fOriginalSep = sep
|
|
|
|
pos.z += zShift//
|
|
roll.vBasePosition = pos
|
|
roll.pivotID = CREATE_OBJECT(PROP_LD_TEST_01, pos, FALSE)
|
|
|
|
// setup pivot
|
|
IF IS_ENTITY_ALIVE(roll.pivotID)
|
|
FREEZE_ENTITY_POSITION(roll.pivotID, TRUE)
|
|
SET_ENTITY_COORDS_NO_OFFSET(roll.pivotID, pos)
|
|
SET_ENTITY_HEADING(roll.pivotID, head)
|
|
SET_ENTITY_COLLISION(roll.pivotID, FALSE)
|
|
ENDIF
|
|
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - VROLLER PIVOT BASE POSITION:", pos)
|
|
|
|
// create left brush
|
|
v = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<-sep / 2.0, 0, VROLLER_ZSHIFT>>)
|
|
roll.rollerID[0] = CREATE_OBJECT(PROP_CARWASH_ROLLER_VERT, v, FALSE)
|
|
roll.fTgtOffset[0] = -sep / 2.0
|
|
roll.fOffset[0] = -sep / 2.0
|
|
|
|
FREEZE_ENTITY_POSITION(roll.rollerID[0], TRUE)
|
|
SET_ENTITY_COLLISION(roll.rollerID[0], TRUE)
|
|
SET_ENTITY_INVINCIBLE(roll.rollerID[0], TRUE)
|
|
SET_ENTITY_HAS_GRAVITY(roll.rollerID[0], FALSE)
|
|
SET_ENTITY_COORDS(roll.rollerID[0], v)
|
|
|
|
// create left brush
|
|
v = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<sep / 2.0, 0, VROLLER_ZSHIFT>>)
|
|
roll.rollerID[1] = CREATE_OBJECT(PROP_CARWASH_ROLLER_VERT, v, FALSE)
|
|
roll.fTgtOffset[1] = sep / 2.0
|
|
roll.fOffset[1] = sep / 2.0
|
|
|
|
FREEZE_ENTITY_POSITION(roll.rollerID[1], TRUE)
|
|
SET_ENTITY_COLLISION(roll.rollerID[1], TRUE)
|
|
SET_ENTITY_INVINCIBLE(roll.rollerID[1], TRUE)
|
|
SET_ENTITY_HAS_GRAVITY(roll.rollerID[1], FALSE)
|
|
SET_ENTITY_COORDS(roll.rollerID[1], v)
|
|
|
|
// finialize
|
|
roll.fRollerSpinAngle = 0.0
|
|
roll.state = CPS_NULL
|
|
roll.bSetup = TRUE
|
|
|
|
roll.fSensorOffset[0] = -1.275
|
|
roll.fSensorRadius[0] = 1.25
|
|
|
|
roll.fSensorOffset[1] = 0.0
|
|
roll.fSensorRadius[1] = 0.620
|
|
|
|
roll.fTgtOffset[0] = -VROLLER_SEP
|
|
roll.fTgtOffset[1] = VROLLER_SEP
|
|
|
|
roll.iNextShapeTestTime = 0
|
|
ENDPROC
|
|
|
|
|
|
|
|
//----------------------
|
|
// JETS FUNCTIONS
|
|
//----------------------
|
|
|
|
/// PURPOSE:
|
|
/// Create the carwash jets
|
|
/// PARAMS:
|
|
/// roll - roller reference
|
|
/// pos - the middle point between the two arms - ground based
|
|
/// head - heading
|
|
/// sep - the distance between the arm joints
|
|
/// steam - are these steam jets (their positioning is forced)
|
|
PROC CREATE_CARWASH_JETS(CARWASH_JETS &roll, VECTOR pos, FLOAT head = 0.0, FLOAT sep = DEFAULT_DUALVROLL_SEP, BOOL steam = FALSE, FLOAT jetTrig = JET_TRIGGER_DIST)
|
|
FLOAT z
|
|
|
|
IF IS_STRING_NULL_OR_EMPTY(roll.sJetName)
|
|
roll.sJetName = "ent_amb_car_wash_jet"
|
|
ENDIF
|
|
|
|
roll.bSetup = TRUE
|
|
roll.fSeperation = sep / 2.0
|
|
roll.pivotID = CREATE_OBJECT(PROP_LD_TEST_01, pos, FALSE)
|
|
roll.bSteam = steam
|
|
|
|
IF IS_ENTITY_OK(roll.pivotID)
|
|
SET_ENTITY_HEADING(roll.pivotID, head)
|
|
FREEZE_ENTITY_POSITION(roll.pivotID, TRUE)
|
|
ENDIF
|
|
|
|
IF GET_GROUND_Z_FOR_3D_COORD(pos, z)
|
|
roll.fHeight = ABSF(pos.z - z)
|
|
ENDIF
|
|
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - JETS BASE POS:", pos, " HEIGHT:", roll.fHeight)
|
|
|
|
roll.fTriggerDist = jetTrig
|
|
roll.vBasePos = pos
|
|
roll.vBasePos.z = z
|
|
ENDPROC
|
|
|
|
PROC SET_CARWASH_JETS_PARTICLES(CARWASH_JETS &roll, STRING str)
|
|
roll.sJetName = str
|
|
ENDPROC
|
|
|
|
|
|
|
|
PROC START_CARWASH_JETS_PARTICLES(CARWASH_JETS &roll, STRING str = NULL)
|
|
IF NOT IS_STRING_EMPTY_HUD(str)
|
|
roll.sJetName = str
|
|
ENDIF
|
|
|
|
SHUTDOWN_CARWASH_JETS_PARTICLES(roll)
|
|
IS_VECTOR_ZERO(vSteamRotFX)
|
|
|
|
IF (roll.bSteam = FALSE)
|
|
roll.fxJets[0] = START_PARTICLE_FX_LOOPED_ON_ENTITY(roll.sJetName, roll.pivotID, <<roll.fSeperation, 0, -roll.fHeight * 0.25>>, -vJetRotFX)
|
|
roll.fxJets[1] = START_PARTICLE_FX_LOOPED_ON_ENTITY(roll.sJetName, roll.pivotID, <<-roll.fSeperation, 0, -roll.fHeight * 0.25>>, vJetRotFX)
|
|
roll.fxJets[2] = START_PARTICLE_FX_LOOPED_ON_ENTITY(roll.sJetName, roll.pivotID, <<roll.fSeperation, 0, -roll.fHeight * 0.75>>, -vJetRotFX)
|
|
roll.fxJets[3] = START_PARTICLE_FX_LOOPED_ON_ENTITY(roll.sJetName, roll.pivotID, <<-roll.fSeperation, 0, -roll.fHeight * 0.75>>, vJetRotFX)
|
|
ELSE
|
|
roll.fxJets[0] = START_PARTICLE_FX_LOOPED_ON_ENTITY(roll.sJetName, roll.pivotID, vSteamPosFX, <<0, 90, 0>>)
|
|
roll.fxJets[1] = START_PARTICLE_FX_LOOPED_ON_ENTITY(roll.sJetName, roll.pivotID, <<-1.96, 0.1, -2.16>>, <<0, 35, 0>>)
|
|
roll.fxJets[2] = START_PARTICLE_FX_LOOPED_ON_ENTITY(roll.sJetName, roll.pivotID, <<1.96, 0.1, -2.16>>, <<0, 145, 0>>)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
PROC SHUTDOWN_CARWASH_JETS(CARWASH_JETS &roll)
|
|
IF IS_CARWASH_PART_RUNNING(roll.state)
|
|
SHUTDOWN_CARWASH_JETS_PARTICLES(roll)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iSplashSoundID)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iSoundID)
|
|
roll.state = CPS_NULL
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
PROC SHARED_CLEANUP_DELETE_CARWASH_JETS(CARWASH_JETS &roll)
|
|
roll.state = CPS_ACTIVE
|
|
SHUTDOWN_CARWASH_JETS(roll)
|
|
SAFE_DELETE_OBJECT(roll.pivotID)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Update the dual roller
|
|
/// PARAMS:
|
|
/// roll - roller reference
|
|
PROC CLEANUP_CARWASH_JETS(CARWASH_JETS &roll)
|
|
SHARED_CLEANUP_DELETE_CARWASH_JETS(roll)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Update the dual roller
|
|
/// PARAMS:
|
|
/// roll - roller reference
|
|
PROC DELETE_CARWASH_JETS(CARWASH_JETS &roll)
|
|
SHARED_CLEANUP_DELETE_CARWASH_JETS(roll)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Update the dual roller
|
|
/// PARAMS:
|
|
/// roll - roller reference
|
|
PROC UPDATE_CARWASH_JETS(CARWASH_JETS &roll, BOOL bSomeOneIn = TRUE)
|
|
INT iHits
|
|
VECTOR v1, v2
|
|
VECTOR vHitPos, vHitNormal
|
|
SHAPETEST_STATUS shapeStatus
|
|
ENTITY_INDEX hitEntity
|
|
|
|
IF NOT IS_ENTITY_OK(roll.pivotID) or (roll.bSetup = FALSE)
|
|
EXIT
|
|
ENDIF
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDrawDebugCarwash = TRUE
|
|
DRAW_DEBUG_SPHERE(GET_ENTITY_COORDS(roll.pivotID), 0.03125)
|
|
VECTOR v = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, vSteamPosFX)
|
|
DRAW_DEBUG_SPHERE(v, 0.0625, 0, 255, 0, 255)
|
|
DRAW_DEBUG_CIRCLE(roll.vBasePos, roll.fTriggerDist)
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
IF IS_CARWASH_PART_RUNNING(roll.state)
|
|
IF (bSomeOneIn = FALSE)
|
|
CPRINTLN(DEBUG_MISSION, "Carwash Water - Shutdown No One is In Carwash")
|
|
roll.state = CPS_SHUTDOWN
|
|
ENDIF
|
|
|
|
IF NETWORK_IS_GAME_IN_PROGRESS() AND NOT IS_ANY_NET_PLAYER_DRIVING_IN_CARWASH()
|
|
CPRINTLN(DEBUG_MISSION, "Carwash Water - NET Shutdown No One is In Carwash")
|
|
roll.state = CPS_SHUTDOWN
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SWITCH (roll.state)
|
|
CASE CPS_NULL
|
|
IF (GET_GAME_TIMER() > roll.iNextShapeTestTime) AND (bSomeOneIn = TRUE)
|
|
|
|
IF (roll.bSteam = FALSE)
|
|
IF (roll.shapeTestID = NULL)
|
|
IF (GET_GAME_TIMER() > roll.iNextShapeTestTime)
|
|
v1 = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<-roll.fSeperation * 0.8, 0, -roll.fHeight * 0.75>>)
|
|
v2 = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<roll.fSeperation * 0.8, 0, -roll.fHeight * 0.75>>)
|
|
roll.shapeTestID = START_SHAPE_TEST_LOS_PROBE(v1, v2, SCRIPT_INCLUDE_VEHICLE, roll.pivotID, SCRIPT_SHAPETEST_OPTION_IGNORE_NO_COLLISION)
|
|
STOP_FIRE_IN_RANGE(roll.vBasePos, roll.fTriggerDist)
|
|
ENDIF
|
|
ELSE
|
|
shapeStatus = GET_SHAPE_TEST_RESULT(roll.shapeTestID, iHits, vHitPos, vHitNormal, hitEntity)
|
|
IF (shapeStatus = SHAPETEST_STATUS_RESULTS_READY)
|
|
IF CHECK_ENTITY_IS_VEHICLE_OK(hitEntity)
|
|
roll.state = CPS_STARTUP
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: PARTICLE STARTUP")
|
|
ENDIF
|
|
|
|
roll.iNextShapeTestTime = GET_GAME_TIMER() + SHAPE_CHECK_INTERVAL
|
|
ENDIF
|
|
roll.shapeTestID = NULL
|
|
ENDIF
|
|
ELSE
|
|
roll.iNextShapeTestTime = GET_GAME_TIMER() + SHAPE_CHECK_INTERVAL
|
|
IF IS_CARWASH_POSITION_OCCUPIED(roll.vBasePos, roll.fTriggerDist)
|
|
roll.state = CPS_STARTUP
|
|
roll.shapeTestID = NULL
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE CPS_STARTUP
|
|
roll.state = CPS_ACTIVE
|
|
START_CARWASH_JETS_PARTICLES(roll)
|
|
STOP_FIRE_IN_RANGE(roll.vBasePos, roll.fTriggerDist * 1.2)
|
|
roll.iSoundID = GET_SOUND_ID()
|
|
IF (roll.bSteam = FALSE)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: PARTICLE ACTIVE")
|
|
PLAY_SOUND_FROM_ENTITY(roll.iSoundID, "SPRAY", roll.pivotID, "CARWASH_SOUNDS")
|
|
ELSE
|
|
PLAY_SOUND_FROM_ENTITY(roll.iSoundID, "DRYER", roll.pivotID, "CARWASH_SOUNDS")
|
|
ENDIF
|
|
BREAK
|
|
CASE CPS_ACTIVE
|
|
IF (bSomeOneIn = FALSE)
|
|
CPRINTLN(DEBUG_MISSION, "Carwash Water - Splash Start")
|
|
roll.state = CPS_SHUTDOWN
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF NETWORK_IS_GAME_IN_PROGRESS() AND NOT IS_ANY_NET_PLAYER_DRIVING_IN_CARWASH()
|
|
roll.state = CPS_SHUTDOWN
|
|
EXIT
|
|
ENDIF
|
|
|
|
IF (roll.bSteam = FALSE)
|
|
STOP_FIRE_IN_RANGE(roll.vBasePos, roll.fTriggerDist * 1.2)
|
|
IF (roll.shapeTestID = NULL)
|
|
IF (GET_GAME_TIMER() > roll.iNextShapeTestTime)
|
|
v1 = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<-roll.fSeperation * 0.8, 0, -roll.fHeight * 0.75>>)
|
|
v2 = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(roll.pivotID, <<roll.fSeperation * 0.8, 0, -roll.fHeight * 0.75>>)
|
|
roll.shapeTestID = START_SHAPE_TEST_LOS_PROBE(v1, v2, SCRIPT_INCLUDE_VEHICLE, roll.pivotID, SCRIPT_SHAPETEST_OPTION_IGNORE_NO_COLLISION)
|
|
ENDIF
|
|
ELSE
|
|
shapeStatus = GET_SHAPE_TEST_RESULT(roll.shapeTestID, iHits, vHitPos, vHitNormal, hitEntity)
|
|
IF (shapeStatus = SHAPETEST_STATUS_RESULTS_READY)
|
|
IF NOT CHECK_ENTITY_IS_VEHICLE_OK(hitEntity)
|
|
roll.state = CPS_SHUTDOWN
|
|
ELSE
|
|
IF (roll.iSplashSoundID = -1)
|
|
roll.iSplashSoundID = GET_SOUND_ID()
|
|
PLAY_SOUND_FROM_ENTITY(roll.iSplashSoundID, "SPRAY_CAR", roll.pivotID, "CARWASH_SOUNDS")
|
|
CPRINTLN(DEBUG_MISSION, "Carwash Water - Splash Start")
|
|
ENDIF
|
|
|
|
IF IS_PED_IN_THIS_VEHICLE(PLAYER_PED_ID(), GET_VEHICLE_INDEX_FROM_ENTITY_INDEX(hitEntity))
|
|
//CPRINTLN(DEBUG_MISSION, "Carwash Water - Pad Rumble")
|
|
DO_CARWASH_PAD_RUMBLE(SHAPE_CHECK_INTERVAL, 64)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
roll.iNextShapeTestTime = GET_GAME_TIMER() + SHAPE_CHECK_INTERVAL
|
|
ENDIF
|
|
roll.shapeTestID = NULL
|
|
ENDIF
|
|
|
|
IF (IS_PED_ON_ANY_BIKE(PLAYER_PED_ID()) OR IS_PED_ON_FOOT(PLAYER_PED_ID()))
|
|
OR (IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) AND NOT ARE_ALL_VEHICLE_WINDOWS_INTACT(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())))
|
|
vHitPos = GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(roll.pivotID, GET_ENTITY_COORDS(PLAYER_PED_ID()))
|
|
IF (ABSF(vHitPos.x) < roll.fSeperation) AND (ABSF(vHitPos.y) < 1.2) AND (vHitPos.z < -roll.fHeight * 0.25)
|
|
//CPRINTLN(DEBUG_MISSION, "Carwash Water - Wet")
|
|
SET_PED_WETNESS_HEIGHT(PLAYER_PED_ID(), 3.0)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ELIF (GET_GAME_TIMER() > roll.iNextCheckTime)
|
|
DO_CARWASH_PAD_RUMBLE(ROLLER_CHECK_INTERVAL, 16)
|
|
IF NOT IS_CARWASH_POSITION_OCCUPIED(roll.vBasePos, roll.fTriggerDist * 1.25)
|
|
roll.state = CPS_SHUTDOWN
|
|
ENDIF
|
|
roll.iNextCheckTime = GET_GAME_TIMER() + ROLLER_CHECK_INTERVAL
|
|
ENDIF
|
|
BREAK
|
|
CASE CPS_SHUTDOWN
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: PARTICLE SHUTDOWN")
|
|
SHUTDOWN_CARWASH_JETS_PARTICLES(roll)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iSplashSoundID)
|
|
SAFE_STOP_AND_RELEASE_SOUND_ID(roll.iSoundID)
|
|
roll.state = CPS_NULL
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
|
|
|
|
//----------------------
|
|
// CAM FUNCTIONS
|
|
//----------------------
|
|
|
|
PROC SETUP_CARWASH_CAMERA(CARWASH_CAMERA &cam, VECTOR pos, VECTOR rot, FLOAT fov)
|
|
cam.bSetup = TRUE
|
|
cam.vPosition[0] = pos
|
|
cam.vRotation[0] = rot
|
|
cam.vPosition[1] = <<0, 0, 0>>
|
|
cam.vRotation[1] = <<0, 0, 0>>
|
|
cam.iInterpTime = 0
|
|
cam.fFov = fov
|
|
ENDPROC
|
|
|
|
PROC SETUP_CARWASH_CAMERA_INTERPOLATE(CARWASH_CAMERA &cam, VECTOR pos, VECTOR rot, VECTOR pos2, VECTOR rot2, FLOAT fov, INT itime)
|
|
cam.bSetup = TRUE
|
|
cam.vPosition[0] = pos
|
|
cam.vRotation[0] = rot
|
|
cam.vPosition[1] = pos2
|
|
cam.vRotation[1] = rot2
|
|
cam.iInterpTime = itime
|
|
cam.fFov = fov
|
|
ENDPROC
|
|
|
|
PROC DISABLE_CARWASH_CAMERA(CARWASH_CAMERA &cr)
|
|
IF DOES_CAM_EXIST(cr.cameraID)
|
|
SET_CAM_ACTIVE(cr.cameraID, FALSE)
|
|
RENDER_SCRIPT_CAMS(FALSE, FALSE)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
PROC DESTROY_CARWASH_CAMERA(CARWASH_CAMERA &cr)
|
|
IF DOES_CAM_EXIST(cr.cameraID)
|
|
DISABLE_CARWASH_CAMERA(cr)
|
|
DESTROY_CAM(cr.cameraID)
|
|
ENDIF
|
|
cr.cameraID = NULL
|
|
ENDPROC
|
|
|
|
FUNC BOOL ENABLE_CARWASH_CAMERA(CARWASH_CAMERA &cr)
|
|
IF NOT (cr.bSetup = TRUE)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF NOT DOES_CAM_EXIST(cr.cameraID)
|
|
cr.cameraID = CREATE_CAM_WITH_PARAMS("DEFAULT_SCRIPTED_CAMERA", <<0, 0, 0>>, <<0, 0, 0>>, 60.0, TRUE)
|
|
ENDIF
|
|
|
|
SET_CAM_PARAMS(cr.cameraID, cr.vPosition[0], cr.vRotation[0], cr.fFov, 0)
|
|
SET_CAM_ACTIVE(cr.cameraID, TRUE)
|
|
RENDER_SCRIPT_CAMS(TRUE, FALSE)
|
|
|
|
IF (cr.iInterpTime > 0) AND NOT IS_VECTOR_ZERO(cr.vPosition[1])
|
|
CPRINTLN(DEBUG_MISSION, "CAMERA INTERPOLATE")
|
|
SET_CAM_PARAMS(cr.cameraID, cr.vPosition[1], cr.vRotation[1], cr.fFov, cr.iInterpTime)
|
|
ENDIF
|
|
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
//----------------------
|
|
// HANDLER FUNCTIONS
|
|
//----------------------
|
|
|
|
|
|
FUNC BOOL RESTART_CARWASH_VEHICLE_TASK(VEHICLE_INDEX veh, CARWASH_HANDLER &ch)
|
|
IF NOT IS_ENTITY_OK(veh)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - Aborting as vehicle is broken")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
PED_INDEX ped = GET_PED_IN_VEHICLE_SEAT(veh)
|
|
IF NOT IS_ENTITY_OK(veh)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - Aborting as vehicle has no driver")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF NOT GET_IS_WAYPOINT_RECORDING_LOADED(ch.sWayPointRec)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - Waypoint recording not loaded")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
SET_VEHICLE_DOORS_SHUT(veh, TRUE)
|
|
IF NETWORK_HAS_CONTROL_OF_ENTITY(veh)
|
|
SET_VEHICLE_DOORS_LOCKED_FOR_ALL_PLAYERS(veh, TRUE)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - Carwash Network Door Lock Activated")
|
|
ENDIF
|
|
|
|
SEQUENCE_INDEX seqCarWash
|
|
OPEN_SEQUENCE_TASK(seqCarWash)
|
|
TASK_VEHICLE_FOLLOW_WAYPOINT_RECORDING(NULL, veh, ch.sWayPointRec, DRIVINGMODE_PLOUGHTHROUGH, 0,
|
|
EWAYPOINT_NAVMESH_TO_INITIAL_WAYPOINT | EWAYPOINT_USE_TIGHTER_TURN_SETTINGS | EWAYPOINT_DO_NOT_RESPOND_TO_COLLISION_EVENTS,
|
|
-1, ch.fForwardSpeed, FALSE, 1.25)
|
|
TASK_STAND_STILL(NULL, 3000)
|
|
CLOSE_SEQUENCE_TASK(seqCarWash)
|
|
TASK_PERFORM_SEQUENCE(ped, seqCarWash)
|
|
CLEAR_SEQUENCE_TASK(seqCarWash)
|
|
VEHICLE_WAYPOINT_PLAYBACK_OVERRIDE_SPEED(veh, ch.fForwardSpeed)
|
|
|
|
iDriverCarwashSequenceProgress = -1
|
|
ch.iTaskSequenceSize = 2
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - Task Restarted")
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
FUNC BOOL SET_VEHICLE_THROUGH_CARWASH(VEHICLE_INDEX veh, CARWASH_HANDLER &ch, INT iDelay = 0)
|
|
IF NOT IS_ENTITY_OK(veh)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - Aborting as vehicle is broken")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
PED_INDEX ped = GET_PED_IN_VEHICLE_SEAT(veh)
|
|
IF NOT IS_ENTITY_OK(veh)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - Aborting as vehicle has no driver")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF DOES_VEHICLE_HAVE_ROOF(veh)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - Car has a roof that's good then")
|
|
ENDIF
|
|
|
|
IF IS_VEHICLE_A_CONVERTIBLE(veh, TRUE)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - Car is a convertable - Convertable Roof State:", ENUM_TO_INT(GET_CONVERTIBLE_ROOF_STATE(veh)))
|
|
ENDIF
|
|
|
|
IF IS_STRING_NULL_OR_EMPTY(ch.sWayPointRec)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - Waypoint not set up")
|
|
SET_VEHICLE_ALONG_CARWASH_TRACK(veh, ch.cTrack, 0.0, ch.fForwardSpeed)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF NOT GET_IS_WAYPOINT_RECORDING_LOADED(ch.sWayPointRec)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - Waypoint recording not loaded")
|
|
ENDIF
|
|
|
|
// need to turn off player control when in carwash
|
|
IF (g_bInMultiplayer)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Dis-Enabling Player Controls")
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE, SPC_ALLOW_PLAYER_DAMAGE)
|
|
|
|
IF NETWORK_HAS_CONTROL_OF_ENTITY(veh)
|
|
SET_VEHICLE_DOORS_LOCKED_FOR_ALL_PLAYERS(veh, TRUE)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - Carwash Network Door Lock Activated")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - Spoiler Mod:", GET_VEHICLE_MOD(veh, MOD_SPOILER))
|
|
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - Shutting Doors")
|
|
SET_VEHICLE_DOORS_SHUT(veh, FALSE)
|
|
|
|
|
|
CLEAR_PED_TASKS(ped)
|
|
SET_ENTITY_VELOCITY(veh, <<0, 0, 0>>)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Clear Ped Tasks and Set Car Velocity to Zero")
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Number of Car Seats:", GET_VEHICLE_MAX_NUMBER_OF_PASSENGERS(veh))
|
|
SEQUENCE_INDEX seqCarWash
|
|
|
|
ch.iTaskSequenceSize = 2
|
|
OPEN_SEQUENCE_TASK(seqCarWash)
|
|
IF iDelay > 0
|
|
TASK_STAND_STILL(NULL, iDelay)
|
|
ch.iTaskSequenceSize ++
|
|
ENDIF
|
|
TASK_VEHICLE_FOLLOW_WAYPOINT_RECORDING(NULL, veh, ch.sWayPointRec, DRIVINGMODE_PLOUGHTHROUGH, 0,
|
|
EWAYPOINT_NAVMESH_TO_INITIAL_WAYPOINT | EWAYPOINT_USE_TIGHTER_TURN_SETTINGS | EWAYPOINT_DO_NOT_RESPOND_TO_COLLISION_EVENTS,
|
|
-1, ch.fForwardSpeed, FALSE, 1.25)
|
|
TASK_STAND_STILL(NULL, 3000)
|
|
CLOSE_SEQUENCE_TASK(seqCarWash)
|
|
TASK_PERFORM_SEQUENCE(ped, seqCarWash)
|
|
CLEAR_SEQUENCE_TASK(seqCarWash)
|
|
VEHICLE_WAYPOINT_PLAYBACK_OVERRIDE_SPEED(veh, ch.fForwardSpeed)
|
|
|
|
iDriverCarwashSequenceProgress = -1
|
|
ch.bCarwashAborted = FALSE
|
|
PRINT_PLAYER_CAR_DIMENSIONS()
|
|
|
|
ADD_VEHICLE_STUCK_CHECK_WITH_WARP(veh,0.2,1000,FALSE,FALSE,FALSE,-1)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - Adding stuck check")
|
|
|
|
IF NOT DECOR_EXIST_ON(veh, "Carwash_Vehicle_Decorator")
|
|
DECOR_SET_BOOL(veh, "Carwash_Vehicle_Decorator", TRUE)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] - Adding vehicle decorator")
|
|
ENDIF
|
|
|
|
START_CARWASH_TIMER(ch)
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
FUNC BOOL IS_CARWASH_VEHICLE_STUCK(VEHICLE_INDEX vehPlayerCar)
|
|
|
|
IF NOT DOES_VEHICLE_HAVE_STUCK_VEHICLE_CHECK(vehPlayerCar)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF IS_VEHICLE_STUCK_TIMER_UP(vehPlayerCar,VEH_STUCK_ON_ROOF,5000)
|
|
OR IS_VEHICLE_STUCK_TIMER_UP(vehPlayerCar,VEH_STUCK_ON_SIDE, 5000)
|
|
OR IS_VEHICLE_STUCK_TIMER_UP(vehPlayerCar,VEH_STUCK_HUNG_UP, 5000)
|
|
OR IS_VEHICLE_STUCK_TIMER_UP(vehPlayerCar,VEH_STUCK_JAMMED, 5000)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Handle push block - stops vehicles from driving in
|
|
/// PARAMS:
|
|
/// ct - carwash track
|
|
/// veh - vehicle
|
|
/// blockRadius - block radius
|
|
FUNC FLOAT UPDATE_VEHICLE_THROUGH_CARWASH(CARWASH_HANDLER &ch, VEHICLE_INDEX veh, FLOAT startDirt)
|
|
|
|
// move car along and stop people dicking about with sun roof
|
|
VECTOR v
|
|
FLOAT r = GET_RATIO_OF_CLOSEST_POINT_ON_LINE(GET_ENTITY_COORDS(veh), ch.cTrack.vTrackPoint[0], ch.cTrack.vTrackPoint[1], FALSE)
|
|
IF (r <= 1)
|
|
|
|
IF IS_PED_IN_VEHICLE(PLAYER_PED_ID(), veh)
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_EXIT)
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_ROOF)
|
|
//DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_MAP)
|
|
ENDIF
|
|
|
|
IF GET_PED_IN_VEHICLE_SEAT(veh) = PLAYER_PED_ID()
|
|
DISABLE_CONTROL_ACTIONS_FOR_CARWASH()
|
|
//DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_MAP)
|
|
ENDIF
|
|
|
|
IF NETWORK_HAS_CONTROL_OF_ENTITY(veh)
|
|
v = GET_CLOSEST_POINT_ON_LINE(GET_ENTITY_COORDS(veh), ch.cTrack.vTrackPoint[0], ch.cTrack.vTrackPoint[1], FALSE)
|
|
IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(veh, v) < 4.0
|
|
IF (r > 0.0)
|
|
APPLY_CARWASH_WASH_TO_VEHICLE(veh, 0.005, startDirt * (1.0 - r))
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// force collsion on rollers to be off
|
|
IF (NETWORK_IS_GAME_IN_PROGRESS() = FALSE)
|
|
UPDATE_COLLISIONS_FOR_CARWASH(ch, veh)
|
|
ENDIF
|
|
|
|
IF NETWORK_HAS_CONTROL_OF_ENTITY(veh)
|
|
IF r > 0.85 AND (NOT ch.bThrottleBoosted) AND ch.fBoostSpeed > 0.0
|
|
CPRINTLN(DEBUG_MISSION, "Setting new override speed: ", ch.fBoostSpeed)
|
|
VEHICLE_WAYPOINT_PLAYBACK_OVERRIDE_SPEED(veh, ch.fBoostSpeed)
|
|
ch.bThrottleBoosted = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN r
|
|
ENDFUNC
|
|
|
|
PROC UPDATE_CARWASH_PARTS(CARWASH_HANDLER &ch)
|
|
BOOL update = TRUE
|
|
|
|
IF (g_bInMultiplayer)
|
|
update = IS_ANY_NET_PLAYER_DRIVING_IN_CARWASH()
|
|
IF (update)
|
|
ch.iLastTimeUsed = GET_GAME_TIMER()
|
|
ENDIF
|
|
|
|
IF (update = FALSE) AND (ch.bOldUpdateCheck = TRUE)
|
|
//SCRIPT_ASSERT("NO ONE IS USING CARWASH ANYMORE")
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] NO ONE IS USING CARWASH ANYMORE")
|
|
ch.vertRoller.fSpinRate = 0.0
|
|
ch.bTimerStarted = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF (NETWORK_IS_GAME_IN_PROGRESS() AND bUseNewMPVertRollers)
|
|
UPDATE_CARWASH_VERTROLLER_MP(ch.vertRoller, update, ch.bCarwashAborted)
|
|
ELSE
|
|
UPDATE_CARWASH_VERTROLLER(ch.vertRoller, update, ch.bCarwashAborted)
|
|
ENDIF
|
|
|
|
IF (g_bInMultiplayer)
|
|
ch.bOldUpdateCheck = update
|
|
// don't bother to update if no one has used it for 0.5 seconds
|
|
IF (GET_GAME_TIMER() > ch.iLastTimeUsed + 1500)
|
|
ch.shapeTestID = NULL
|
|
ch.iBlockCounts = 0
|
|
EXIT
|
|
ENDIF
|
|
ENDIF
|
|
|
|
UPDATE_CARWASH_HROLLER(ch.horzRoller, update)
|
|
UPDATE_CARWASH_JETS(ch.waterJets, update)
|
|
UPDATE_CARWASH_JETS(ch.soapJets, update)
|
|
UPDATE_CARWASH_JETS(ch.steamJets, update)
|
|
ENDPROC
|
|
|
|
|
|
PROC SNAP_VEHICLE_TO_CARWASH_START(VEHICLE_INDEX veh, CARWASH_HANDLER &ch, BOOL bForceSnap = FALSE)
|
|
VECTOR fwd
|
|
|
|
IF IS_ENTITY_OK(veh)
|
|
ENABLE_CAMERA_STRUCT(ch.carwashCamera[0], ch.cameraID, ch.bTallVehicle, TRUE)
|
|
|
|
// snap car if angle between forward and carwash track is less than 60 degrees (cos(60) = 0.5)
|
|
fwd = GET_ENTITY_FORWARD_VECTOR(veh)
|
|
|
|
IF NOT IS_DIRECTION_WITHIN_DEGRESS_OF_DESIRED_DIRECTION(ch.cTrack.vDirection, fwd, AUTODRIVE_TOLERANCE) OR (bForceSnap = TRUE)
|
|
|
|
//IF (DOT_PRODUCT_XY(ch.cTrack.vDirection, fwd) < COS(60.0)) OR (bForceSnap = TRUE)
|
|
SET_ENTITY_COORDS_GROUNDED(veh, GET_CLOSEST_POINT_ON_LINE(GET_ENTITY_COORDS(veh), ch.cTrack.vTrackPoint[0], ch.cTrack.vTrackPoint[1], FALSE) + <<0, 0, 0.1>>)
|
|
SET_ENTITY_HEADING(veh, ch.cTrack.fTrackHeading)
|
|
SET_VEHICLE_ON_GROUND_PROPERLY(veh)
|
|
SET_VEHICLE_FORWARD_SPEED(veh, 0.0)
|
|
ENDIF
|
|
|
|
SET_VEHICLE_DOORS_SHUT(veh, FALSE)
|
|
ch.iCurrentCameraState = 0
|
|
ch.bIsAllowedInMP = FALSE
|
|
ch.shapeTestID = NULL
|
|
ch.iBlockCounts = 0
|
|
|
|
// B*1439838 - only the machine who owns this can call this
|
|
IF (g_bInMultiplayer)
|
|
IF NOT NETWORK_HAS_CONTROL_OF_ENTITY(veh)
|
|
EXIT
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SET_CARWASH_CAR_LOCK_STATE(veh, VEHICLELOCK_LOCKED)
|
|
IF IS_VEHICLE_A_CONVERTIBLE(veh, FALSE)
|
|
RAISE_CONVERTIBLE_ROOF(veh, FALSE)
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
PROC SHUTDOWN_CARWASH_CAMERA(CAMERA_INDEX cameraID, BOOL bForce = FALSE)
|
|
VEHICLE_INDEX ind
|
|
|
|
IF DOES_CAM_EXIST(cameraID)
|
|
SHUTDOWN_CAMERA(cameraID)
|
|
DUMMY_REFERENCE_BOOL(bForce)
|
|
SET_EVERYONE_IGNORE_PLAYER(PLAYER_ID(), FALSE)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Carwash Camera ShutDown - ", bForce)
|
|
|
|
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
|
|
ind = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())
|
|
IF IS_ENTITY_OK(ind)
|
|
|
|
IF NOT IS_VEHICLE_A_PERSONAL_VEHICLE(ind)
|
|
IF GET_PED_IN_VEHICLE_SEAT(ind) = PLAYER_PED_ID()
|
|
SET_CARWASH_CAR_LOCK_STATE(ind, VEHICLELOCK_UNLOCKED)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Carwash car doors unlocked")
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
FUNC BOOL IS_THERE_A_VEHICLE_IN_FRONT(VEHICLE_INDEX veh)
|
|
VECTOR checkpoint
|
|
VECTOR dmin, dmax
|
|
|
|
GET_MODEL_DIMENSIONS(GET_ENTITY_MODEL(veh), dmin, dmax)
|
|
|
|
checkPoint = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(veh, <<0, dmax.y + 0.325, 0>>)
|
|
//DRAW_DEBUG_SPHERE(checkPoint, 0.0625)
|
|
//DRAW_DEBUG_LINE(checkPoint, checkPoint + <<0, 0, 10>>)
|
|
|
|
RETURN IS_POSITION_OCCUPIED(checkPoint, 0.75, FALSE, TRUE, FALSE, FALSE, TRUE, veh)
|
|
ENDFUNC
|
|
|
|
FUNC BOOL IS_THERE_A_VEHICLE_IN_FRONT_SHAPETEST(CARWASH_HANDLER &ch, VEHICLE_INDEX veh)
|
|
IF (GET_GAME_TIMER() < ch.iNextBlockCheckTime)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
INT iHits
|
|
VECTOR checkpoint
|
|
VECTOR dmin, dmax
|
|
VECTOR vHitPos, vHitNormal
|
|
SHAPETEST_STATUS shapeStatus
|
|
ENTITY_INDEX hitEntity
|
|
|
|
IF (ch.shapeTestID = NULL)
|
|
GET_MODEL_DIMENSIONS(GET_ENTITY_MODEL(veh), dmin, dmax)
|
|
|
|
IF (ch.bBackInterruptCheck = FALSE)
|
|
checkPoint = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(veh, <<0, dmax.y + 0.325, 0>>)
|
|
ELSE
|
|
checkPoint = GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(veh, <<0, dmin.y - 0.325, 0>>)
|
|
ENDIF
|
|
|
|
/*
|
|
// flip this - not sure if i can do variable = ! variable in this
|
|
IF (ch.bBackInterruptCheck)
|
|
ch.bBackInterruptCheck = FALSE
|
|
ELSE
|
|
ch.bBackInterruptCheck = TRUE
|
|
ENDIF
|
|
*/
|
|
|
|
IF (g_bInMultiplayer)
|
|
ch.shapeTestID = START_SHAPE_TEST_CAPSULE(checkPoint - <<0, 0, 0.1>>, checkPoint + <<0, 0, 0.1>>, 0.75, SCRIPT_INCLUDE_VEHICLE | SCRIPT_INCLUDE_OBJECT, veh)
|
|
ELSE
|
|
ch.shapeTestID = START_SHAPE_TEST_CAPSULE(checkPoint - <<0, 0, 0.1>>, checkPoint + <<0, 0, 0.1>>, 0.75, SCRIPT_INCLUDE_VEHICLE, veh)
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ELSE
|
|
shapeStatus = GET_SHAPE_TEST_RESULT(ch.shapeTestID, iHits, vHitPos, vHitNormal, hitEntity)
|
|
IF (shapeStatus = SHAPETEST_STATUS_RESULTS_READY)
|
|
IF DOES_ENTITY_EXIST(hitEntity)
|
|
IF CAN_THIS_ENTITY_BLOCK_THE_CARWASH(hitEntity)
|
|
ch.iBlockCounts ++
|
|
RETURN TRUE
|
|
ELSE
|
|
ch.iBlockCounts = 0
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ch.iNextBlockCheckTime = GET_GAME_TIMER() + 500
|
|
ch.shapeTestID = NULL
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
FUNC FLOAT GET_CURRENT_RATIO_FOR_VEHICLE_IN_CARWASH(CARWASH_HANDLER &ch, VEHICLE_INDEX veh)
|
|
IF NOT IS_ENTITY_ALIVE(veh)
|
|
RETURN 0.0
|
|
ENDIF
|
|
|
|
RETURN GET_RATIO_OF_CLOSEST_POINT_ON_LINE(GET_ENTITY_COORDS(veh), ch.cTrack.vBlockPoint[0], ch.cTrack.vBlockPoint[1], FALSE)
|
|
ENDFUNC
|
|
|
|
PROC EMERGENCY_ABORT_CARWASH(CARWASH_HANDLER &ch, VEHICLE_INDEX veh = NULL)
|
|
//SCRIPT_ASSERT("EMERGENCY CARWASH ABORT!!")
|
|
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Emergency Carwash Terminate")
|
|
ch.iCurrentCameraState = CAMERASTATE_ALLDONE
|
|
|
|
RESET_COLLISIONS_FOR_CARWASH(ch)
|
|
STOP_ALL_CARWASH_SOUNDS(ch)
|
|
STOP_ALL_CARWASH_PARTICLES(ch)
|
|
SHUTDOWN_CARWASH_CAMERA(ch.cameraID, TRUE)
|
|
SET_NET_PED_DRIVING_CARWASH_STATUS(PLAYER_PED_ID(), FALSE)
|
|
|
|
DELETE_CARWASH_JETS(ch.waterJets)
|
|
DELETE_CARWASH_JETS(ch.soapJets)
|
|
DELETE_CARWASH_JETS(ch.steamJets)
|
|
|
|
SET_EVERYONE_IGNORE_PLAYER(PLAYER_ID(), FALSE)
|
|
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Re-Enabling Player Controls")
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
|
|
|
|
IF (g_bInMultiplayer)
|
|
PLAYER_INDEX player = NETWORK_GET_PLAYER_INDEX_FROM_PED(PLAYER_PED_ID())
|
|
IF (player != INVALID_PLAYER_INDEX())
|
|
IF (GlobalPlayerBD[NATIVE_TO_INT(player)].bDrivingThroughCarwash = TRUE)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: Setting player to net be in carwash")
|
|
GlobalPlayerBD[NATIVE_TO_INT(player)].bDrivingThroughCarwash = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF DOES_ENTITY_EXIST(veh)
|
|
SET_CARWASH_CAR_LOCK_STATE(veh, VEHICLELOCK_UNLOCKED)
|
|
REMOVE_CARWASH_STUCK_CHECK(veh)
|
|
|
|
IF NETWORK_IS_GAME_IN_PROGRESS()
|
|
IF NETWORK_HAS_CONTROL_OF_ENTITY(veh)
|
|
SET_VEHICLE_DOORS_LOCKED_FOR_ALL_PLAYERS(veh, FALSE)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SET_PED_PATHS_BACK_TO_ORIGINAL(ch.vNoPedWalkMin, ch.vNoPedWalkMax)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: Unblocking ped area:", ch.vNoPedWalkMin, " ", ch.vNoPedWalkMax)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Carwash car doors unlocked")
|
|
ch.shapeTestID = NULL
|
|
ch.iBlockCounts = 0
|
|
ch.bCarwashAborted = TRUE
|
|
ch.bTimerStarted = FALSE
|
|
|
|
//SET_VEHICLE_AND_OCCUPANTS_INVINCIBLE(veh, FALSE)
|
|
|
|
IF IS_AUDIO_SCENE_ACTIVE("CAR_WASH_SCENE")
|
|
CPRINTLN(DEBUG_MISSION, "Carwash Stop Audio Scene")
|
|
STOP_AUDIO_SCENE("CAR_WASH_SCENE")
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
FUNC BOOL IS_PED_RUNNING_TASK_OR_HAS_FINISHED(PED_INDEX ped, SCRIPT_TASK_NAME task)
|
|
|
|
IF (GET_SCRIPT_TASK_STATUS(ped, task) = PERFORMING_TASK)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF (GET_SCRIPT_TASK_STATUS(ped, task) = WAITING_TO_START_TASK)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN (GET_SCRIPT_TASK_STATUS(ped, task) = FINISHED_TASK)
|
|
ENDFUNC
|
|
|
|
PROC SHUT_CARWASH_VEHICLE_DOORS(VEHICLE_INDEX veh)
|
|
IF NETWORK_IS_GAME_IN_PROGRESS()
|
|
IF NETWORK_HAS_CONTROL_OF_ENTITY(veh)
|
|
SET_VEHICLE_DOORS_SHUT(veh, TRUE)
|
|
ENDIF
|
|
|
|
EXIT
|
|
ENDIF
|
|
|
|
SET_VEHICLE_DOORS_SHUT(veh, TRUE)
|
|
ENDPROC
|
|
|
|
FUNC BOOL UPDATE_CARWASH_HANDLER_CAMERAS(CARWASH_HANDLER &ch, VEHICLE_INDEX veh)
|
|
PED_INDEX driver
|
|
FLOAT fRatio = GET_CURRENT_RATIO_FOR_VEHICLE_IN_CARWASH(ch, veh)
|
|
BOOL bAbort = FALSE
|
|
BOOL bAbortLastCamera = FALSE
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
fCarDebugRatio = fRatio
|
|
iDebugCarWashTimer = GET_CARWASH_TIMER_ELAPSED(ch)
|
|
#ENDIF
|
|
|
|
IF NOT IS_ENTITY_OK(veh)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Emergency Carwash Terminate - Vehicle Is Not OK")
|
|
EMERGENCY_ABORT_CARWASH(ch, veh)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
// B*1926983 - Car Wash animation stops when player enters Xbox Store and then backing out
|
|
// Reset the timer if the player is in the xbox store or the game will bust out
|
|
IF NETWORK_IS_GAME_IN_PROGRESS()
|
|
IF IS_COMMERCE_STORE_OPEN()
|
|
START_CARWASH_TIMER(ch)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF IS_PAUSE_MENU_ACTIVE()
|
|
START_CARWASH_TIMER(ch)
|
|
ENDIF
|
|
|
|
// update carwash tasks
|
|
driver = GET_PED_IN_VEHICLE_SEAT(veh)
|
|
|
|
IF IS_CARWASH_PED_OK(driver)
|
|
bIsDriverRunningCarwashSequence = ((GET_SCRIPT_TASK_STATUS(driver, SCRIPT_TASK_PERFORM_SEQUENCE) = PERFORMING_TASK) OR (GET_SCRIPT_TASK_STATUS(driver, SCRIPT_TASK_PERFORM_SEQUENCE) = WAITING_TO_START_TASK))
|
|
IF (bIsDriverRunningCarwashSequence)
|
|
iDriverCarwashSequenceProgress = GET_SEQUENCE_PROGRESS(driver)
|
|
bIsDriverFinishedCarwashSequence = (GET_SCRIPT_TASK_STATUS(driver, SCRIPT_TASK_PERFORM_SEQUENCE) = FINISHED_TASK) AND (iDriverCarwashSequenceProgress = (ch.iTaskSequenceSize - 1))
|
|
ENDIF
|
|
|
|
IF (bDebugForceClearPedTasks)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] DEBUG - FORCE CLEAR PED TASKS")
|
|
IF IS_PED_IN_ANY_VEHICLE(driver)
|
|
TASK_LEAVE_ANY_VEHICLE(driver)
|
|
ENDIF
|
|
|
|
//CLEAR_PED_TASKS(driver)
|
|
bDebugForceClearPedTasks = FALSE
|
|
ENDIF
|
|
|
|
IF (bDebugForceRestartTasks)
|
|
RESTART_CARWASH_VEHICLE_TASK(veh, ch)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH] DEBUG - FORCE RESTART TASKS")
|
|
bDebugForceRestartTasks = FALSE
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDrawDebugCarwash
|
|
DRAW_DEBUG_SPHERE(INTERPOLATE_VECTOR(ch.cTrack.vTrackPoint[0], ch.cTrack.vTrackPoint[1], fBlockCarPlaceT, FALSE), 0.0625)
|
|
ENDIF
|
|
|
|
IF (bCreateBlockCar)
|
|
CREATE_VEHICLE(GET_ENTITY_MODEL(veh), INTERPOLATE_VECTOR(ch.cTrack.vTrackPoint[0], ch.cTrack.vTrackPoint[1], fBlockCarPlaceT, FALSE), ch.cTrack.fTrackHeading, FALSE)
|
|
bCreateBlockCar = FALSE
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
|
|
|
|
// abort if driver is killed
|
|
IF (g_bInMultiplayer)
|
|
|
|
IF IS_PLAYER_ON_MP_AMBIENT_SCRIPT(PLAYER_ID(), MPAM_TYPE_TIME_TRIAL)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: Aborting as Driver is part of Time Trial")
|
|
bAbort = TRUE
|
|
ENDIF
|
|
|
|
IF IS_PLAYER_ON_MP_AMBIENT_SCRIPT(PLAYER_ID(), MPAM_TYPE_RC_TIME_TRIAL)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: Aborting as Driver is part of RC Time Trial")
|
|
bAbort = TRUE
|
|
ENDIF
|
|
|
|
IF NOT IS_CARWASH_PED_OK(driver)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: Aborting as Driver is dead")
|
|
bAbort = TRUE
|
|
ENDIF
|
|
|
|
IF IS_PED_IN_VEHICLE(driver, veh, FALSE)
|
|
IF NOT IS_PED_SITTING_IN_VEHICLE(driver, veh)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: ABORT! - Driver is has fallen out of car")
|
|
bAbort = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF NOT IS_PED_IN_CAR_WITH_CARWASH_DRIVER(PLAYER_PED_ID())
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: As Ped isn't in carwash car")
|
|
bAbort = TRUE
|
|
ENDIF
|
|
/*
|
|
ELIF (NOT IS_STRING_NULL_OR_EMPTY(ch.sWayPointRec))
|
|
IF NOT IS_PED_RUNNING_TASK_OR_HAS_FINISHED(driver, SCRIPT_TASK_PERFORM_SEQUENCE) AND (ch.iCurrentCameraState >= 1)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: As Ped driving abandonded task")
|
|
bAbort = TRUE
|
|
ENDIF
|
|
*/
|
|
IF ARE_VEHICLE_TYRES_BURST(veh, 3)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: At least 3 tyres are burst - Car will probably not make it through - Emergency Exit")
|
|
bAbort = TRUE
|
|
ENDIF
|
|
|
|
IF NOT IS_ANY_NET_PLAYER_DRIVING_IN_CARWASH()
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: Emergency Exit - No one at all are using carwash anymore")
|
|
bAbort = TRUE
|
|
ENDIF
|
|
|
|
IF IS_PED_BEING_JACKED(driver)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: Aborting as Driver is being jacked")
|
|
bAbort = TRUE
|
|
ENDIF
|
|
|
|
IF IS_CARWASH_VEHICLE_STUCK(veh)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: Emergency Exit - Carwash car is stuck")
|
|
bAbort = TRUE
|
|
ENDIF
|
|
|
|
IF HAS_ABORT_TIME_EXPIRED(ch)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: Carwash has taken too long to finish something has gone wrong - Emergency Exit")
|
|
EMERGENCY_ABORT_CARWASH(ch, veh)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF (bAbort = TRUE)
|
|
EMERGENCY_ABORT_CARWASH(ch, veh)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF NOT NETWORK_HAS_CONTROL_OF_ENTITY(veh)
|
|
NETWORK_USE_LOGARITHMIC_BLENDING_THIS_FRAME(veh)
|
|
ENDIF
|
|
ELSE
|
|
IF HAS_ABORT_TIME_EXPIRED(ch) AND (ch.bSkipped = FALSE)
|
|
SAFE_FADE_SCREEN_OUT_TO_BLACK(500, TRUE)
|
|
APPLY_CARWASH_WASH_TO_VEHICLE(veh, 100.0, 0.0)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: Carwash has taken too long - Emergency Exit SP - Fade to End")
|
|
ch.bSkipped = TRUE
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// check if task has been aborted
|
|
IF (driver = PLAYER_PED_ID())
|
|
IF (NOT bIsDriverRunningCarwashSequence) AND ((iDriverCarwashSequenceProgress > -1) AND (iDriverCarwashSequenceProgress < ch.iTaskSequenceSize))
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: Emergency - task has aborted improperly")
|
|
RESTART_CARWASH_VEHICLE_TASK(veh, ch)
|
|
ENDIF
|
|
|
|
IF (bIsDriverFinishedCarwashSequence)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: Sequence Finished")
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
IF IS_THERE_A_VEHICLE_IN_FRONT_SHAPETEST(ch, veh)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Someone has tried to drive in - abort")
|
|
EMERGENCY_ABORT_CARWASH(ch, veh)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF (ch.iCurrentCameraState <> CAMERASTATE_ALLDONE)
|
|
DISABLE_CELLPHONE_THIS_FRAME_ONLY()
|
|
SET_EVERYONE_IGNORE_PLAYER(PLAYER_ID(), TRUE)
|
|
IF (ch.iCurrentCameraState > 0)
|
|
HIDE_HUD_AND_RADAR_THIS_FRAME()
|
|
|
|
IF (GET_BUILDING_STATE(ch.iplSwap) != BUILDINGSTATE_DESTROYED)
|
|
SET_BUILDING_STATE(ch.iplSwap, BUILDINGSTATE_DESTROYED)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: The IPL hasn't been swapped for some reason - Swap it back")
|
|
ENDIF
|
|
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SWITCH (ch.iCurrentCameraState)
|
|
CASE 0
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Switching To Camera 0 - Ratio", fRatio)
|
|
CLEAR_CYLINDER_OF_FIRE(ch.cTrack.vTrackPoint[0], ch.cTrack.vTrackPoint[1], 3.0, NOT g_bInMultiplayer)
|
|
SET_PED_PATHS_IN_AREA(ch.vNoPedWalkMin, ch.vNoPedWalkMax, FALSE)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: Blocking ped area:", ch.vNoPedWalkMin, " ", ch.vNoPedWalkMax)
|
|
IF GET_BUILDING_STATE(ch.iplSwap) <> BUILDINGSTATE_DESTROYED
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: Building Swap didn't happen properly?")
|
|
SET_BUILDING_STATE(ch.iplSwap, BUILDINGSTATE_DESTROYED)
|
|
ENDIF
|
|
|
|
ENABLE_CAMERA_STRUCT(ch.carwashCamera[0], ch.cameraID, ch.bTallVehicle, FALSE, GRAPH_TYPE_CUBIC_EASE_IN_OUT, GRAPH_TYPE_CUBIC_EASE_IN_OUT)
|
|
START_CARWASH_TIMER(ch)
|
|
|
|
IF NOT g_bInMultiplayer
|
|
CLEAR_AREA_OF_PEDS(GET_PLAYER_COORDS(GET_PLAYER_INDEX()), 50.0)
|
|
ENDIF
|
|
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Carwash car doors locked")
|
|
|
|
//SET_VEHICLE_AND_OCCUPANTS_INVINCIBLE(veh)
|
|
ch.iCurrentCameraState ++
|
|
|
|
IF NOT IS_AUDIO_SCENE_ACTIVE("CAR_WASH_SCENE")
|
|
START_AUDIO_SCENE("CAR_WASH_SCENE")
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Carwash Start Audio Scene")
|
|
ENDIF
|
|
|
|
IF NOT g_bInMultiplayer
|
|
SET_ENTITY_COORDS(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), ch.cTrack.vVehicleSnapPoint)
|
|
SET_ENTITY_HEADING(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), ch.cTrack.fTrackHeading)
|
|
|
|
IF IS_VEHICLE_A_CONVERTIBLE(veh, FALSE)
|
|
RAISE_CONVERTIBLE_ROOF(veh, TRUE)
|
|
ENDIF
|
|
|
|
SET_CARWASH_CAR_LOCK_STATE(veh, VEHICLELOCK_LOCKED)
|
|
//PRINT_HELP("CWASH_SKIPRIDE")
|
|
ELSE
|
|
// B*1439838 - only the machine who owns this can call this
|
|
IF NETWORK_HAS_CONTROL_OF_ENTITY(veh)
|
|
SET_CARWASH_CAR_LOCK_STATE(veh, VEHICLELOCK_CANNOT_ENTER)
|
|
IF IS_VEHICLE_A_CONVERTIBLE(veh, FALSE)
|
|
RAISE_CONVERTIBLE_ROOF(veh, FALSE)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE 1
|
|
IF HAS_CAMERA_STRUCT_FINISHED_INTERPOLATING(ch.carwashCamera[0], fRatio)
|
|
CLEAR_CYLINDER_OF_FIRE(ch.cTrack.vTrackPoint[0], ch.cTrack.vTrackPoint[1], 3.0, NOT g_bInMultiplayer)
|
|
ENABLE_CAMERA_STRUCT(ch.carwashCamera[1], ch.cameraID, ch.bTallVehicle, FALSE, GRAPH_TYPE_LINEAR)
|
|
SHUT_CARWASH_VEHICLE_DOORS(veh)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Switching to Camera 1 - Car Ratio:", fRatio)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Time Elapsed:", GET_CARWASH_TIMER_ELAPSED(ch))
|
|
START_CARWASH_TIMER(ch)
|
|
ch.iCurrentCameraState ++
|
|
ENDIF
|
|
BREAK
|
|
CASE 2
|
|
IF HAS_CAMERA_STRUCT_FINISHED_INTERPOLATING(ch.carwashCamera[1], fRatio)
|
|
CLEAR_CYLINDER_OF_FIRE(ch.cTrack.vTrackPoint[0], ch.cTrack.vTrackPoint[1], 3.0, NOT g_bInMultiplayer)
|
|
|
|
IF (ch.carWashCamera[2].bSetup)
|
|
ENABLE_CAMERA_STRUCT(ch.carwashCamera[2], ch.cameraID, ch.bTallVehicle, FALSE, GRAPH_TYPE_LINEAR)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Switching to Camera 2 - Car Ratio:", fRatio)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Time Elapsed:", GET_CARWASH_TIMER_ELAPSED(ch))
|
|
ch.iCurrentCameraState ++
|
|
ELSE
|
|
ENABLE_CAMERA_STRUCT(ch.carwashCamera[6], ch.cameraID, ch.bTallVehicle, FALSE, GRAPH_TYPE_LINEAR)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Switching to Camera 6 - Car Ratio:", fRatio)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Time Elapsed;", GET_CARWASH_TIMER_ELAPSED(ch))
|
|
APPLY_CARWASH_WASH_TO_VEHICLE(veh, 50.0, 0.0)
|
|
ch.iCurrentCameraState = CAMERASTATE_LASTCAMERA
|
|
ENDIF
|
|
|
|
SHUT_CARWASH_VEHICLE_DOORS(veh)
|
|
START_CARWASH_TIMER(ch)
|
|
ENDIF
|
|
BREAK
|
|
CASE 3
|
|
IF HAS_CAMERA_STRUCT_FINISHED_INTERPOLATING(ch.carwashCamera[2], fRatio)
|
|
CLEAR_CYLINDER_OF_FIRE(ch.cTrack.vTrackPoint[0], ch.cTrack.vTrackPoint[1], 3.0, NOT g_bInMultiplayer)
|
|
|
|
IF (ch.carWashCamera[3].bSetup)
|
|
ENABLE_CAMERA_STRUCT(ch.carwashCamera[3], ch.cameraID, ch.bTallVehicle, FALSE, GRAPH_TYPE_LINEAR)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Switching to Camera 3 - Car Ratio:", fRatio)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Time Elapsed;", GET_CARWASH_TIMER_ELAPSED(ch))
|
|
ch.iCurrentCameraState ++
|
|
ELSE
|
|
ENABLE_CAMERA_STRUCT(ch.carwashCamera[6], ch.cameraID, ch.bTallVehicle, FALSE, GRAPH_TYPE_LINEAR)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Switching to Camera 6 - Car Ratio:", fRatio)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Time Elapsed;", GET_CARWASH_TIMER_ELAPSED(ch))
|
|
APPLY_CARWASH_WASH_TO_VEHICLE(veh, 50.0, 0.0)
|
|
ch.iCurrentCameraState = CAMERASTATE_LASTCAMERA
|
|
ENDIF
|
|
|
|
SHUT_CARWASH_VEHICLE_DOORS(veh)
|
|
START_CARWASH_TIMER(ch)
|
|
ENDIF
|
|
BREAK
|
|
CASE 4
|
|
IF HAS_CAMERA_STRUCT_FINISHED_INTERPOLATING(ch.carwashCamera[3], fRatio)
|
|
CLEAR_CYLINDER_OF_FIRE(ch.cTrack.vTrackPoint[0], ch.cTrack.vTrackPoint[1], 3.0, NOT g_bInMultiplayer)
|
|
|
|
IF (ch.carWashCamera[4].bSetup)
|
|
ENABLE_CAMERA_STRUCT(ch.carwashCamera[4], ch.cameraID, ch.bTallVehicle, FALSE, GRAPH_TYPE_LINEAR)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Switching to Camera 4 - Car Ratio:", fRatio)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Time Elapsed;", GET_CARWASH_TIMER_ELAPSED(ch))
|
|
ch.iCurrentCameraState ++
|
|
ELSE
|
|
ENABLE_CAMERA_STRUCT(ch.carwashCamera[6], ch.cameraID, ch.bTallVehicle, FALSE, GRAPH_TYPE_LINEAR)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Switching to Camera 6 - Car Ratio:", fRatio)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Time Elapsed:", GET_CARWASH_TIMER_ELAPSED(ch))
|
|
APPLY_CARWASH_WASH_TO_VEHICLE(veh, 50.0, 0.0)
|
|
ch.iCurrentCameraState = CAMERASTATE_LASTCAMERA
|
|
ENDIF
|
|
|
|
SHUT_CARWASH_VEHICLE_DOORS(veh)
|
|
START_CARWASH_TIMER(ch)
|
|
ENDIF
|
|
BREAK
|
|
CASE 5
|
|
IF HAS_CAMERA_STRUCT_FINISHED_INTERPOLATING(ch.carwashCamera[4], fRatio)
|
|
CLEAR_CYLINDER_OF_FIRE(ch.cTrack.vTrackPoint[0], ch.cTrack.vTrackPoint[1], 3.0, NOT g_bInMultiplayer)
|
|
|
|
IF (ch.carWashCamera[5].bSetup)
|
|
ENABLE_CAMERA_STRUCT(ch.carwashCamera[5], ch.cameraID, ch.bTallVehicle, FALSE, GRAPH_TYPE_LINEAR)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Switching to Camera 5 - Car Ratio:", fRatio)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Time Elapsed:", GET_CARWASH_TIMER_ELAPSED(ch))
|
|
ch.iCurrentCameraState ++
|
|
ELSE
|
|
ENABLE_CAMERA_STRUCT(ch.carwashCamera[6], ch.cameraID, ch.bTallVehicle, FALSE, GRAPH_TYPE_LINEAR)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Switching to Camera 6 - Car Ratio:", fRatio)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Time Elapsed:", GET_CARWASH_TIMER_ELAPSED(ch))
|
|
APPLY_CARWASH_WASH_TO_VEHICLE(veh, 50.0, 0.0)
|
|
ch.iCurrentCameraState = CAMERASTATE_LASTCAMERA
|
|
ENDIF
|
|
|
|
SHUT_CARWASH_VEHICLE_DOORS(veh)
|
|
START_CARWASH_TIMER(ch)
|
|
ENDIF
|
|
BREAK
|
|
CASE 6
|
|
IF HAS_CAMERA_STRUCT_FINISHED_INTERPOLATING(ch.carwashCamera[5], fRatio) AND (fRatio >= ch.fFinalCameraInterpolate)
|
|
CLEAR_CYLINDER_OF_FIRE(ch.cTrack.vTrackPoint[0], ch.cTrack.vTrackPoint[1], 3.0, NOT g_bInMultiplayer)
|
|
IF NOT IS_POSITION_OCCUPIED(ch.carwashCamera[6].vPosition[0], 2.0, FALSE, TRUE, FALSE, FALSE, FALSE, veh)
|
|
ENABLE_CAMERA_STRUCT(ch.carwashCamera[6], ch.cameraID, ch.bTallVehicle, FALSE, GRAPH_TYPE_DECEL)
|
|
ENDIF
|
|
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Switching to Camera 6 - Car Ratio:", fRatio)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Time Elapsed:", GET_CARWASH_TIMER_ELAPSED(ch))
|
|
APPLY_CARWASH_WASH_TO_VEHICLE(veh, 100.0, 0.0)
|
|
|
|
IF NOT g_bInMultiplayer
|
|
//REMOVE_DECALS_FROM_VEHICLE(veh)
|
|
ENDIF
|
|
ch.iCurrentCameraState = CAMERASTATE_LASTCAMERA
|
|
|
|
SHUT_CARWASH_VEHICLE_DOORS(veh)
|
|
START_CARWASH_TIMER(ch)
|
|
ENDIF
|
|
BREAK
|
|
CASE CAMERASTATE_LASTCAMERA
|
|
IF IS_POSITION_OCCUPIED(ch.carwashCamera[6].vPosition[0], 2.0, FALSE, TRUE, FALSE, FALSE, FALSE, veh)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: Car in the way of last camera")
|
|
bAbortLastCamera = TRUE
|
|
ENDIF
|
|
|
|
IF HAS_CAMERA_STRUCT_FINISHED_INTERPOLATING(ch.carwashCamera[6], fRatio) OR (bAbortLastCamera)
|
|
CPRINTLN(DEBUG_MISSION, "Carwash Finished")
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Time Elapsed:", GET_CARWASH_TIMER_ELAPSED(ch))
|
|
CLEAR_CYLINDER_OF_FIRE(ch.cTrack.vTrackPoint[0], ch.cTrack.vTrackPoint[1], 3.0, NOT g_bInMultiplayer)
|
|
SHUTDOWN_CARWASH_CAMERA(ch.cameraID, FALSE)
|
|
IF IS_AUDIO_SCENE_ACTIVE("CAR_WASH_SCENE")
|
|
STOP_AUDIO_SCENE("CAR_WASH_SCENE")
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Carwash Stop Audio Scene")
|
|
ENDIF
|
|
|
|
IF IS_PED_IN_CAR_WITH_CARWASH_DRIVER(PLAYER_PED_ID())
|
|
CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
ENDIF
|
|
FORCE_CLEAR_NET_PED_DRIVING_CARWASH_STATUS(PLAYER_PED_ID())
|
|
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Re-Enabling Player Controls")
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
|
|
|
|
//SET_VEHICLE_AND_OCCUPANTS_INVINCIBLE(veh, FALSE)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Carwash is complete")
|
|
ch.iCurrentCameraState = CAMERASTATE_ALLDONE
|
|
ch.shapeTestID = NULL
|
|
ch.iBlockCounts = 0
|
|
bIsDriverFinishedCarwashSequence = FALSE
|
|
bIsDriverRunningCarwashSequence = FALSE
|
|
iDriverCarwashSequenceProgress = -1
|
|
|
|
SET_EVERYONE_IGNORE_PLAYER(PLAYER_ID(), FALSE)
|
|
APPLY_CARWASH_WASH_TO_VEHICLE(veh, 100.0, 0.0)
|
|
REMOVE_CARWASH_STUCK_CHECK(veh)
|
|
IF NOT g_bInMultiplayer
|
|
//REMOVE_DECALS_FROM_VEHICLE(veh)
|
|
ENDIF
|
|
|
|
SET_CARWASH_CAR_LOCK_STATE(veh, VEHICLELOCK_UNLOCKED)
|
|
SET_PED_PATHS_BACK_TO_ORIGINAL(ch.vNoPedWalkMin, ch.vNoPedWalkMax)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: Unblocking ped area:", ch.vNoPedWalkMin, " ", ch.vNoPedWalkMax)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]:Carwash car doors unlocked")
|
|
REGISTER_SCRIPT_IN_COMPLETION_PERCENTAGE_TOTAL(CP_CARWSH)
|
|
RETURN TRUE
|
|
ELSE
|
|
HIDE_HUD_AND_RADAR_THIS_FRAME()
|
|
ENDIF
|
|
BREAK
|
|
CASE CAMERASTATE_ALLDONE
|
|
IF IS_AUDIO_SCENE_ACTIVE("CAR_WASH_SCENE")
|
|
CPRINTLN(DEBUG_MISSION, "Carwash Stop Audio Scene")
|
|
STOP_AUDIO_SCENE("CAR_WASH_SCENE")
|
|
ENDIF
|
|
|
|
SHUTDOWN_CARWASH_CAMERA(ch.cameraID, FALSE)
|
|
ch.shapeTestID = NULL
|
|
ch.iBlockCounts = 0
|
|
ch.bTimerStarted = FALSE
|
|
bIsDriverFinishedCarwashSequence = FALSE
|
|
bIsDriverRunningCarwashSequence = FALSE
|
|
iDriverCarwashSequenceProgress = -1
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
PROC DELETE_CARWASH_HANDLER(CARWASH_HANDLER &ch)
|
|
VEHICLE_INDEX ind
|
|
|
|
IF NOT NETWORK_IS_GAME_IN_PROGRESS()
|
|
RC_END_CUTSCENE_MODE()
|
|
ENDIF
|
|
CPRINTLN(DEBUG_MISSION, "Delete Carwash")
|
|
|
|
FORCE_CLEAR_NET_PED_DRIVING_CARWASH_STATUS(PLAYER_PED_ID())
|
|
DISABLE_CELLPHONE(FALSE)
|
|
|
|
ch.shapeTestID = NULL
|
|
ch.iBlockCounts = 0
|
|
|
|
RESET_COLLISIONS_FOR_CARWASH(ch)
|
|
STOP_ALL_CARWASH_SOUNDS(ch)
|
|
STOP_ALL_CARWASH_PARTICLES(ch)
|
|
DELETE_CARWASH_VERTROLLER(ch.vertRoller)
|
|
DELETE_CARWASH_HROLLER(ch.horzRoller)
|
|
DELETE_CARWASH_JETS(ch.waterJets)
|
|
DELETE_CARWASH_JETS(ch.soapJets)
|
|
DELETE_CARWASH_JETS(ch.steamJets)
|
|
SET_BUILDING_STATE(ch.iplSwap, BUILDINGSTATE_NORMAL)
|
|
|
|
SHUTDOWN_CAMERA(ch.cameraID)
|
|
IF IS_AUDIO_SCENE_ACTIVE("CAR_WASH_SCENE")
|
|
CPRINTLN(DEBUG_MISSION, "Carwash Stop Audio Scene")
|
|
STOP_AUDIO_SCENE("CAR_WASH_SCENE")
|
|
ENDIF
|
|
|
|
IF DOES_ENTITY_EXIST(PLAYER_PED_ID())
|
|
IS_ENTITY_DEAD(PLAYER_PED_ID())
|
|
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
|
|
ind = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())
|
|
IF IS_ENTITY_OK(ind)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: Unlocking Car")
|
|
SET_CARWASH_CAR_LOCK_STATE(ind, VEHICLELOCK_UNLOCKED)
|
|
REMOVE_CARWASH_STUCK_CHECK(ind)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF (g_bInMultiplayer)
|
|
PLAYER_INDEX player = NETWORK_GET_PLAYER_INDEX_FROM_PED(PLAYER_PED_ID())
|
|
IF (player != INVALID_PLAYER_INDEX())
|
|
IF (GlobalPlayerBD[NATIVE_TO_INT(player)].bDrivingThroughCarwash = TRUE)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: Setting player to net be in carwash")
|
|
GlobalPlayerBD[NATIVE_TO_INT(player)].bDrivingThroughCarwash = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ind = GET_PLAYERS_LAST_VEHICLE()
|
|
IF IS_ENTITY_OK(ind)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: Unlocking Players Last Vehicle")
|
|
SET_CARWASH_CAR_LOCK_STATE(ind, VEHICLELOCK_UNLOCKED)
|
|
REMOVE_CARWASH_STUCK_CHECK(ind)
|
|
ENDIF
|
|
|
|
SET_PED_PATHS_BACK_TO_ORIGINAL(ch.vNoPedWalkMin, ch.vNoPedWalkMax)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: Unblocking ped area:", ch.vNoPedWalkMin, " ", ch.vNoPedWalkMax)
|
|
// Enable car wash scenarios
|
|
SET_SCENARIO_TYPE_ENABLED("DRIVE", TRUE)
|
|
SET_SCENARIO_TYPE_ENABLED("WORLD_VEHICLE_DRIVE_SOLO", TRUE)
|
|
ENDPROC
|
|
|
|
PROC SHARED_CARWASH_SCRIPT_CLEANUP(CARWASH_HANDLER &ch, BOOL bSkip = FALSE)
|
|
VECTOR v
|
|
|
|
DELETE_CARWASH_HANDLER(ch)
|
|
|
|
IF (g_bInMultiplayer)
|
|
PLAYER_INDEX player = NETWORK_GET_PLAYER_INDEX_FROM_PED(PLAYER_PED_ID())
|
|
IF (player != INVALID_PLAYER_INDEX())
|
|
IF (GlobalPlayerBD[NATIVE_TO_INT(player)].bDrivingThroughCarwash = TRUE)
|
|
CPRINTLN(DEBUG_MISSION, "[CARWASH]: Setting player to net be in carwash")
|
|
GlobalPlayerBD[NATIVE_TO_INT(player)].bDrivingThroughCarwash = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// B*1331838 - Player wasn't being charged on skip
|
|
IF (bSkip = TRUE)
|
|
CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
SET_VEHICLE_ALONG_CARWASH_TRACK(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), ch.cTrack, 1.0, 0.0)
|
|
SET_VEHICLE_ON_GROUND_PROPERLY(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()))
|
|
SET_ENTITY_VELOCITY(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), <<0, 0, 0>>)
|
|
WAIT(0)
|
|
IS_CARWASH_PED_OK(PLAYER_PED_ID())
|
|
v = GET_ENTITY_COORDS(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()))
|
|
v.z = INVALID_WORLD_Z
|
|
SET_ENTITY_COORDS(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), v)
|
|
|
|
APPLY_CARWASH_WASH_TO_VEHICLE(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), 500.0, 0.0)
|
|
SET_CARWASH_CAR_LOCK_STATE(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), VEHICLELOCK_UNLOCKED)
|
|
|
|
WAIT(125)
|
|
DO_SCREEN_FADE_IN(500)
|
|
WAIT(1000)
|
|
REGISTER_SCRIPT_IN_COMPLETION_PERCENTAGE_TOTAL(CP_CARWSH)
|
|
CHARGE_PLAYER_FOR_CARWASH(ch.iLocationID)
|
|
ELIF NOT NETWORK_IS_GAME_IN_PROGRESS()
|
|
CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
ENDIF
|
|
|
|
IF NOT (g_bInMultiplayer)
|
|
REACTIVATE_NAMED_WORLD_BRAINS_WAITING_TILL_OUT_OF_RANGE("launcher_CarWash")
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Gets bank balance of current player
|
|
/// RETURNS:
|
|
///
|
|
FUNC INT GET_CARWASH_CURRENT_PLAYER_PED_ACCOUNT_BALANCE()
|
|
|
|
IF NETWORK_IS_GAME_IN_PROGRESS()
|
|
RETURN NETWORK_GET_VC_BALANCE()
|
|
ENDIF
|
|
|
|
RETURN GET_TOTAL_CASH(GET_CURRENT_PLAYER_PED_ENUM())
|
|
ENDFUNC
|
|
|
|
FUNC BOOL DO_WE_HAVE_ENOUGH_MONEY_FOR(INT iCost)
|
|
IF NETWORK_IS_GAME_IN_PROGRESS()
|
|
RETURN NETWORK_GET_CAN_SPEND_FROM_BANK_AND_WALLET(iCost)
|
|
ENDIF
|
|
|
|
RETURN (GET_TOTAL_CASH(GET_CURRENT_PLAYER_PED_ENUM()) >= iCost)
|
|
ENDFUNC
|
|
|
|
FUNC BOOL AM_I_DRIVING_CLOSEST_CAR_TO_CARWASH(COST_HALO& halo, VEHICLE_INDEX &vehOut)
|
|
|
|
INT iCount, i
|
|
INT iCar = -1
|
|
FLOAT fDist, fMinDist = 1.0
|
|
VEHICLE_INDEX array[32]
|
|
|
|
IF NOT NETWORK_IS_GAME_IN_PROGRESS()
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
iCount = GET_PED_NEARBY_VEHICLES(PLAYER_PED_ID(), array)
|
|
|
|
REPEAT iCount i
|
|
IF IS_ENTITY_OK(array[i])
|
|
fDist = GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(array[i], halo.vTriggerPoint)
|
|
IF (fDist < fMinDist) OR (fMinDist = -1.0)
|
|
fMinDist = fDist
|
|
iCar = i
|
|
ENDIF
|
|
ENDIF
|
|
ENDREPEAT
|
|
//CPRINTLN(DEBUG_MISSION, "[CARWASH] - CDM:iCar = ", iCar)
|
|
IF (iCar = -1)
|
|
//DISPLAY_TEXT_WITH_LITERAL_STRING(0.1, 0.2, "STRING", "NO CAR")
|
|
RETURN FALSE
|
|
ENDIF
|
|
//CPRINTLN(DEBUG_MISSION, "[CARWASH] - CDM: driver = ", (GET_PED_IN_VEHICLE_SEAT(array[iCar]) != PLAYER_PED_ID()))
|
|
IF (GET_PED_IN_VEHICLE_SEAT(array[iCar]) != PLAYER_PED_ID())
|
|
RETURN FALSE
|
|
//DISPLAY_TEXT_WITH_LITERAL_STRING(0.1, 0.2, "STRING", "NOT DRIVING CAR")
|
|
ENDIF
|
|
|
|
vehOut = array[iCar]
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
FUNC INT COUNT_NUMBER_OF_CARS_IN_CARWASH_HALO(COST_HALO& halo)
|
|
INT iCount, i
|
|
VEHICLE_INDEX array[32]
|
|
FLOAT fDist
|
|
INT iCarCount
|
|
|
|
iCount = GET_PED_NEARBY_VEHICLES(PLAYER_PED_ID(), array)
|
|
|
|
REPEAT iCount i
|
|
IF IS_ENTITY_OK(array[i])
|
|
fDist = GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(array[i], halo.vTriggerPoint)
|
|
IF (fDist <= (halo.fTriggerDist * 2.5))
|
|
iCarCount ++
|
|
ENDIF
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
RETURN iCarCount
|
|
ENDFUNC
|
|
|
|
FUNC BOOL CAN_PLAYER_TRIGGER_CARWASH_HALO_IN_CAR(COST_HALO& halo)
|
|
VEHICLE_INDEX array[32]
|
|
INT iCount, i
|
|
INT iCar = -1
|
|
|
|
FLOAT fDist, fMinDist = 1.0
|
|
|
|
IF NOT NETWORK_IS_GAME_IN_PROGRESS()
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
iCount = GET_PED_NEARBY_VEHICLES(PLAYER_PED_ID(), array)
|
|
|
|
REPEAT iCount i
|
|
IF IS_ENTITY_OK(array[i])
|
|
fDist = GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(array[i], halo.vTriggerPoint)
|
|
IF (fDist <= (halo.fTriggerDist * 2.5))
|
|
IF (fDist < fMinDist) OR (fMinDist = -1.0)
|
|
fMinDist = fDist
|
|
iCar = i
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
IF (iCar = -1)
|
|
//DISPLAY_TEXT_WITH_LITERAL_STRING(0.1, 0.2, "STRING", "NO CAR")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
/*
|
|
DRAW_DEBUG_LINE(GET_ENTITY_COORDS(array[iCar]) - <<0, 0, 2>>, GET_ENTITY_COORDS(array[iCar]) + <<0, 0, 2>>)
|
|
DRAW_DEBUG_LINE(GET_ENTITY_COORDS(array[iCar]), GET_ENTITY_COORDS(PLAYER_PED_ID()))
|
|
*/
|
|
|
|
IF NOT IS_PED_IN_VEHICLE(PLAYER_PED_ID(), array[iCar])
|
|
//DISPLAY_TEXT_WITH_LITERAL_STRING(0.1, 0.2, "STRING", "PLAYER NOT IN CAR")
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Updates the cost halos
|
|
/// PARAMS:
|
|
/// halo - array of halos
|
|
/// hndlr - handler reference (string and other stuff)
|
|
/// bNoWay - if we've passed the no way check
|
|
/// bFadeLaunch - do we fade when we launch
|
|
/// RETURNS:
|
|
/// Returns true if we have launched the script
|
|
FUNC BOOL UPDATE_CARWASH_COSTHALO_HANDLER(COST_HALO& halo[], COSTHALO_HANDLER& hndlr, BOOL bNoWay = FALSE, BOOL bFadeLaunch = FALSE, BOOL bAutoLaunch = TRUE, INT iStack = DEFAULT_STACK_SIZE)
|
|
INT i
|
|
VEHICLE_INDEX vehCheck
|
|
|
|
IF (hndlr.bShowMarkers)
|
|
i = 0
|
|
REPEAT COUNT_OF(halo) i
|
|
DRAW_COST_HALO(halo[i])
|
|
ENDREPEAT
|
|
ENDIF
|
|
|
|
SWITCH (hndlr.selectState)
|
|
CASE APPROACH_HALO
|
|
i = 0
|
|
|
|
IF IS_COSTHALO_ALLOWED_TO_LAUNCH(hndlr.bAllowOnMission)
|
|
//CPRINTLN(DEBUG_MISSION, "[CARWASH] - CDM: IS_COSTHALO_ALLOWED_TO_LAUNCH TRUE")
|
|
REPEAT COUNT_OF(halo) i
|
|
//CPRINTLN(DEBUG_MISSION, "[CARWASH] - CDM: halo[",i,"].bIsActive:", halo[i].bIsActive)
|
|
IF IS_PLAYER_IN_COST_HALO(halo[i]) AND (halo[i].bIsActive)
|
|
//CPRINTLN(DEBUG_MISSION, "[CARWASH] - CDM: IS_PLAYER_IN_COST_HALO TRUE")
|
|
hndlr.iSelectedHalo = i
|
|
|
|
IF IS_PLAYER_ON_MP_AMBIENT_SCRIPT(PLAYER_ID(), MPAM_TYPE_TIME_TRIAL) OR IS_PLAYER_ON_MP_AMBIENT_SCRIPT(PLAYER_ID(), MPAM_TYPE_RC_TIME_TRIAL)
|
|
SET_COSTHALO_HANDLER_STATE(hndlr, CLOSED_HALO)
|
|
ELIF (halo[i].bClosed) OR (GET_MISSION_FLAG() AND (hndlr.bAllowOnMission = FALSE))
|
|
SET_COSTHALO_HANDLER_STATE(hndlr, CLOSED_HALO)
|
|
ELIF (GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0)
|
|
SET_COSTHALO_HANDLER_STATE(hndlr, WANTED_HALO)
|
|
ELIF (bNoWay)
|
|
SET_COSTHALO_HANDLER_STATE(hndlr, DENIED_HALO)
|
|
ELIF (halo[i].bCustomCheck)
|
|
SET_COSTHALO_HANDLER_STATE(hndlr, CUSTOMCHECK_HALO)
|
|
//ELIF (GET_CARWASH_CURRENT_PLAYER_PED_ACCOUNT_BALANCE() < halo[hndlr.iSelectedHalo].iCost)
|
|
ELIF NOT DO_WE_HAVE_ENOUGH_MONEY_FOR(halo[hndlr.iSelectedHalo].iCost)
|
|
SET_COSTHALO_HANDLER_STATE(hndlr, CANTAFFORD_HALO)
|
|
ELIF IS_PLAYER_IN_A_BUST_VEHICLE()
|
|
SET_COSTHALO_HANDLER_STATE(hndlr, DAMAGED_HALO)
|
|
ELIF AM_I_DRIVING_CLOSEST_CAR_TO_CARWASH(halo[i], vehCheck)
|
|
SET_COSTHALO_HANDLER_STATE(hndlr, TRIGGER_HALO)
|
|
ENDIF
|
|
//CPRINTLN(DEBUG_MISSION, "[CARWASH] - CDM: IS_PLAYER_IN_A_BUST_VEHICLE:",IS_PLAYER_IN_A_BUST_VEHICLE())
|
|
//CPRINTLN(DEBUG_MISSION, "[CARWASH] - CDM: AM_I_DRIVING_CLOSEST_CAR_TO_CARWASH:",AM_I_DRIVING_CLOSEST_CAR_TO_CARWASH(halo[i], vehCheck))
|
|
ENDIF
|
|
ENDREPEAT
|
|
ELSE
|
|
CLEAR_COSTHALO_HANDLER_HELP(hndlr)
|
|
ENDIF
|
|
BREAK
|
|
CASE CUSTOMCHECK_HALO
|
|
IF NOT (hndlr.bTriggerHelpShown)
|
|
PRINT_COSTHALO_HELP(hndlr, hndlr.sCustomString)
|
|
ENDIF
|
|
|
|
IF IS_PLAYER_OUT_OF_COST_HALO(halo[hndlr.iSelectedHalo]) OR (halo[i].bCustomCheck = FALSE)
|
|
SET_COSTHALO_HANDLER_STATE(hndlr, APPROACH_HALO)
|
|
RETURN FALSE
|
|
ENDIF
|
|
BREAK
|
|
CASE CANTAFFORD_HALO
|
|
IF NOT (hndlr.bTriggerHelpShown)
|
|
PRINT_COSTHALO_HELP_WITH_NUMBER(hndlr, hndlr.sPoorString, halo[hndlr.iSelectedHalo].iCost)
|
|
ENDIF
|
|
|
|
IF IS_PLAYER_OUT_OF_COST_HALO(halo[hndlr.iSelectedHalo]) OR DO_WE_HAVE_ENOUGH_MONEY_FOR(halo[hndlr.iSelectedHalo].iCost) //(GET_CARWASH_CURRENT_PLAYER_PED_ACCOUNT_BALANCE() >= halo[hndlr.iSelectedHalo].iCost)
|
|
SET_COSTHALO_HANDLER_STATE(hndlr, APPROACH_HALO)
|
|
RETURN FALSE
|
|
ENDIF
|
|
BREAK
|
|
CASE CLOSED_HALO
|
|
IF NOT (hndlr.bTriggerHelpShown)
|
|
PRINT_COSTHALO_HELP(hndlr, hndlr.sBrokenString)
|
|
ENDIF
|
|
|
|
IF IS_PLAYER_OUT_OF_COST_HALO(halo[hndlr.iSelectedHalo]) OR NOT IS_COSTHALO_ALLOWED_TO_LAUNCH(hndlr.bAllowOnMission)
|
|
SET_COSTHALO_HANDLER_STATE(hndlr, APPROACH_HALO)
|
|
RETURN FALSE
|
|
ENDIF
|
|
BREAK
|
|
CASE DENIED_HALO
|
|
IF NOT (hndlr.bTriggerHelpShown)
|
|
PRINT_COSTHALO_HELP(hndlr, hndlr.sNoWayString)
|
|
ENDIF
|
|
|
|
IF IS_PLAYER_OUT_OF_COST_HALO(halo[hndlr.iSelectedHalo]) OR (bNoWay = FALSE) OR NOT IS_COSTHALO_ALLOWED_TO_LAUNCH(hndlr.bAllowOnMission)
|
|
SET_COSTHALO_HANDLER_STATE(hndlr, APPROACH_HALO)
|
|
RETURN FALSE
|
|
ENDIF
|
|
BREAK
|
|
CASE DAMAGED_HALO
|
|
IF NOT (hndlr.bTriggerHelpShown)
|
|
PRINT_COSTHALO_HELP(hndlr, hndlr.sDamagedString)
|
|
ENDIF
|
|
|
|
IF IS_PLAYER_OUT_OF_COST_HALO(halo[hndlr.iSelectedHalo]) OR NOT IS_COSTHALO_ALLOWED_TO_LAUNCH(hndlr.bAllowOnMission)
|
|
SET_COSTHALO_HANDLER_STATE(hndlr, APPROACH_HALO)
|
|
RETURN FALSE
|
|
ENDIF
|
|
BREAK
|
|
CASE WANTED_HALO
|
|
IF NOT (hndlr.bTriggerHelpShown)
|
|
PRINT_COSTHALO_HELP(hndlr, hndlr.sWantedString)
|
|
ENDIF
|
|
|
|
IF IS_PLAYER_OUT_OF_COST_HALO(halo[hndlr.iSelectedHalo]) OR (GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) = 0)
|
|
SET_COSTHALO_HANDLER_STATE(hndlr, APPROACH_HALO)
|
|
RETURN FALSE
|
|
ENDIF
|
|
BREAK
|
|
CASE WRONGWAY_HALO
|
|
IF NOT (hndlr.bTriggerHelpShown)
|
|
IF IS_PLAYER_UPRIGHT()
|
|
PRINT_COSTHALO_HELP(hndlr, hndlr.sWrongWayString)
|
|
ELSE
|
|
PRINT_COSTHALO_HELP(hndlr, hndlr.sUpsideDownString)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF IS_PLAYER_OUT_OF_COST_HALO(halo[hndlr.iSelectedHalo]) OR IS_PLAYER_WITHIN_HALO_TOLERANCE(halo[hndlr.iSelectedHalo])
|
|
SET_COSTHALO_HANDLER_STATE(hndlr, APPROACH_HALO)
|
|
RETURN FALSE
|
|
ENDIF
|
|
BREAK
|
|
CASE TRIGGER_HALO
|
|
SET_INPUT_EXCLUSIVE(FRONTEND_CONTROL, INPUT_CONTEXT)
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_ROOF)
|
|
DISABLE_SELECTOR_THIS_FRAME()
|
|
|
|
IF (GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0)
|
|
SET_COSTHALO_HANDLER_STATE(hndlr, WANTED_HALO)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF (halo[hndlr.iSelectedHalo].bCustomCheck)
|
|
SET_COSTHALO_HANDLER_STATE(hndlr, CUSTOMCHECK_HALO)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF IS_PLAYER_OUT_OF_COST_HALO(halo[hndlr.iSelectedHalo]) OR NOT IS_COSTHALO_ALLOWED_TO_LAUNCH(hndlr.bAllowOnMission)
|
|
SET_COSTHALO_HANDLER_STATE(hndlr, APPROACH_HALO)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
// don't launch if browser is running
|
|
IF (g_bBrowserVisible)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
// need to add wrong type check here
|
|
IF (halo[hndlr.iSelectedHalo].haloType = HALO_VEHICLE)
|
|
IF (NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) OR (GET_SEAT_PED_IS_IN(PLAYER_PED_ID()) <> VS_DRIVER))
|
|
SET_COSTHALO_HANDLER_STATE(hndlr, APPROACH_HALO)
|
|
RETURN FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF (halo[hndlr.iSelectedHalo].bClosed) OR (GET_MISSION_FLAG() AND (hndlr.bAllowOnMission = FALSE))
|
|
SET_COSTHALO_HANDLER_STATE(hndlr, CLOSED_HALO)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF IS_PLAYER_IN_A_BUST_VEHICLE()
|
|
SET_COSTHALO_HANDLER_STATE(hndlr, DAMAGED_HALO)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
//IF (GET_CARWASH_CURRENT_PLAYER_PED_ACCOUNT_BALANCE() < halo[hndlr.iSelectedHalo].iCost)
|
|
IF NOT DO_WE_HAVE_ENOUGH_MONEY_FOR(halo[hndlr.iSelectedHalo].iCost)
|
|
SET_COSTHALO_HANDLER_STATE(hndlr, CANTAFFORD_HALO)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
/*
|
|
IF NOT (CAN_PLAYER_TRIGGER_CARWASH_HALO_IN_CAR(halo[hndlr.iSelectedHalo]))
|
|
//SET_COSTHALO_HANDLER_STATE(hndlr, DENIED_HALO)
|
|
//RETURN FALSE
|
|
DISPLAY_TEXT_WITH_LITERAL_STRING(0.5, 0.5, "STRING", "NO WAY")
|
|
ENDIF
|
|
*/
|
|
IF bNoWay
|
|
SET_COSTHALO_HANDLER_STATE(hndlr, DENIED_HALO)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
|
|
IF !bNoWay AND NOT (hndlr.bTriggerHelpShown)
|
|
PRINT_COSTHALO_HELP_WITH_NUMBER(hndlr, hndlr.sActivateString, halo[hndlr.iSelectedHalo].iCost)
|
|
ENDIF
|
|
|
|
// don't let player trigger if they are driving straight through it
|
|
// cant use a vehicle stuck on roof check as i need to add it so check for roll instead
|
|
IF (halo[hndlr.iSelectedHalo].haloType = HALO_VEHICLE)
|
|
|
|
/*
|
|
IF (GET_ENTITY_SPEED(PLAYER_PED_ID()) > 5.0)
|
|
RETURN FALSE
|
|
ENDIF
|
|
*/
|
|
|
|
// if ped is getting out of vehicle don't allow launch
|
|
IF (IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) AND NOT IS_PED_SITTING_IN_ANY_VEHICLE(PLAYER_PED_ID()))
|
|
RETURN FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF IS_PAUSE_MENU_ACTIVE() OR IS_SYSTEM_UI_BEING_DISPLAYED()
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
// don't let a ped this if the player is on foot but on with both feet on the ground
|
|
IF IS_PED_ON_FOOT(PLAYER_PED_ID())
|
|
IF IS_PED_FALLING(PLAYER_PED_ID()) OR IS_PED_JUMPING(PLAYER_PED_ID()) OR IS_PED_JUMPING_OUT_OF_VEHICLE(PLAYER_PED_ID())
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF IS_PED_RUNNING_RAGDOLL_TASK(PLAYER_PED_ID()) OR IS_PED_RAGDOLL(PLAYER_PED_ID()) OR IS_PED_GETTING_UP(PLAYER_PED_ID())
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF IS_PED_CLIMBING(PLAYER_PED_ID())
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF IS_PED_DUCKING(PLAYER_PED_ID()) OR IS_PED_SWIMMING(PLAYER_PED_ID())
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF (GET_ENTITY_SPEED(PLAYER_PED_ID()) > 0.05)
|
|
RETURN FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
|
|
IF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_CONTEXT) AND (hndlr.bTriggerHelpShown = TRUE) AND bNoWay = FALSE
|
|
IF NOT IS_PLAYER_WITHIN_HALO_TOLERANCE(halo[hndlr.iSelectedHalo])
|
|
SET_COSTHALO_HANDLER_STATE(hndlr, WRONGWAY_HALO)
|
|
ELSE
|
|
SET_COSTHALO_HANDLER_STATE(hndlr, LAUNCH_HALO)
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
CASE LAUNCH_HALO
|
|
IF NETWORK_IS_GAME_IN_PROGRESS()
|
|
IF REQUEST_SCRIPT_AUDIO_BANK("SCRIPT\\CARWASH")
|
|
PRINTLN("[CARWASH] Audio bank loaded")
|
|
ENDIF
|
|
ENDIF
|
|
CLEAR_COSTHALO_HANDLER_HELP(hndlr)
|
|
halo[hndlr.iSelectedHalo].bCustomCheck = FALSE
|
|
IF NOT bAutoLaunch
|
|
SET_COSTHALO_HANDLER_STATE(hndlr, APPROACH_HALO)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
CLEAR_HELP()
|
|
CLEAR_AREA_OF_PROJECTILES(GET_ENTITY_COORDS(PLAYER_PED_ID()), 20.0)
|
|
IF NOT IS_STRING_NULL_OR_EMPTY(halo[hndlr.iSelectedHalo].sScriptName)
|
|
|
|
REQUEST_SCRIPT(halo[hndlr.iSelectedHalo].sScriptName)
|
|
WHILE NOT HAS_SCRIPT_LOADED(halo[hndlr.iSelectedHalo].sScriptName)
|
|
DISABLE_SELECTOR_THIS_FRAME()
|
|
|
|
IF IS_ENTITY_OK(PLAYER_PED_ID())
|
|
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) AND NOT g_bInMultiplayer
|
|
BRING_VEHICLE_TO_HALT_AND_DISABLE_VEH_CONTROLS(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), 2)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SET_INPUT_EXCLUSIVE(FRONTEND_CONTROL, INPUT_CONTEXT)
|
|
REQUEST_SCRIPT(halo[hndlr.iSelectedHalo].sScriptName)
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_ROOF)
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_EXIT)
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_ENTER)
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
IF (bFadeLaunch)
|
|
DO_SCREEN_FADE_OUT(250)
|
|
ENDIF
|
|
|
|
IF HAS_SCRIPT_LOADED(halo[hndlr.iSelectedHalo].sScriptName)
|
|
|
|
IF (bFadeLaunch)
|
|
WHILE NOT IS_SCREEN_FADED_OUT()
|
|
|
|
IF IS_ENTITY_OK(PLAYER_PED_ID())
|
|
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) AND NOT g_bInMultiplayer
|
|
BRING_VEHICLE_TO_HALT_AND_DISABLE_VEH_CONTROLS(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), 2)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SET_INPUT_EXCLUSIVE(FRONTEND_CONTROL, INPUT_CONTEXT)
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_ROOF)
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_VEH_EXIT)
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_ENTER)
|
|
DISABLE_SELECTOR_THIS_FRAME()
|
|
WAIT(0)
|
|
ENDWHILE
|
|
ENDIF
|
|
|
|
START_NEW_SCRIPT(halo[hndlr.iSelectedHalo].sScriptName, iStack)
|
|
SET_SCRIPT_AS_NO_LONGER_NEEDED(halo[hndlr.iSelectedHalo].sScriptName)
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
//----------------------
|
|
// DEBUG FUNCTIONS
|
|
//----------------------
|
|
#IF IS_DEBUG_BUILD
|
|
|
|
/// PURPOSE:
|
|
/// Initializes Debug Widgets
|
|
PROC SETUP_DEBUG_CARWASH_HROLLER_WIDGETS(CARWASH_HROLLER &roll, STRING str = NULL)
|
|
IF IS_STRING_NULL_OR_EMPTY(str)
|
|
str = "Horizontal Roller"
|
|
ENDIF
|
|
|
|
START_WIDGET_GROUP(str)
|
|
ADD_WIDGET_FLOAT_SLIDER("Pivot Angle", roll.fRollerPivotAngle, 0.0, 360.0, 0.25)
|
|
ADD_WIDGET_FLOAT_SLIDER("Move Rate", roll.fMoveRate, 0.0, 15.0, 1.0)
|
|
ADD_WIDGET_FLOAT_SLIDER("Spin Rate", roll.fSpinRate, 0.0, 3600.0, 0.025)
|
|
ADD_WIDGET_FLOAT_SLIDER("Trigger Dist", roll.fTriggerDist, 0.0, 5.0, 0.125)
|
|
ADD_WIDGET_FLOAT_READ_ONLY("Spin Angle", roll.fRollerSpinAngle)
|
|
ADD_WIDGET_FLOAT_READ_ONLY("Ground Zero", roll.fGroundZero)
|
|
ADD_WIDGET_INT_READ_ONLY("Next Check Time", roll.iNextCheckTime)
|
|
ADD_WIDGET_INT_READ_ONLY("Next Shape Time", roll.iNextShapeTestTime)
|
|
STOP_WIDGET_GROUP()
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Initializes Debug Widgets
|
|
PROC SETUP_DEBUG_CARWASH_VERTROLLER_WIDGETS(CARWASH_VROLLER2 &roll, STRING str = NULL)
|
|
IF IS_STRING_NULL_OR_EMPTY(str)
|
|
str = "Vert Roller"
|
|
ENDIF
|
|
|
|
START_WIDGET_GROUP(str)
|
|
ADD_WIDGET_BOOL("Collision On", roll.bCollisionOn)
|
|
ADD_WIDGET_BOOL("Front Sensor", roll.bSensorOn[0])
|
|
ADD_WIDGET_FLOAT_SLIDER("Front Sensor Offset", roll.fSensorOffset[0], -5.0, 5.0, 0.001)
|
|
ADD_WIDGET_FLOAT_SLIDER("Front Sensor Radius", roll.fSensorRadius[0], -5.0, 5.0, 0.001)
|
|
ADD_WIDGET_BOOL("Back Sensor", roll.bSensorOn[1])
|
|
ADD_WIDGET_FLOAT_SLIDER("FrontSensor Offset", roll.fSensorOffset[1], -5.0, 5.0, 0.001)
|
|
ADD_WIDGET_FLOAT_SLIDER("FrontSensor Radius", roll.fSensorRadius[1], -5.0, 5.0, 0.001)
|
|
|
|
ADD_WIDGET_FLOAT_SLIDER("Left Offset", roll.fOffset[0], -5.0, -ROLLER_RADIUS, 0.001)
|
|
ADD_WIDGET_FLOAT_SLIDER("Right Offset", roll.fOffset[1], ROLLER_RADIUS, 5.0, 0.001)
|
|
ADD_WIDGET_FLOAT_SLIDER("Left TGT Offset", roll.fTgtOffset[0], -5.0, -ROLLER_RADIUS, 0.001)
|
|
ADD_WIDGET_FLOAT_SLIDER("Right TGT Offset", roll.fTgtOffset[1], ROLLER_RADIUS, 5.0, 0.001)
|
|
ADD_WIDGET_FLOAT_SLIDER("Move Rate", roll.fMoveRate, 0.0, 15.0, 1.0)
|
|
ADD_WIDGET_FLOAT_SLIDER("Shut Down Move Rate", roll.fShutDownMoveRate, 0.0, 15.0, 0.01)
|
|
ADD_WIDGET_FLOAT_SLIDER("Spin Rate", roll.fSpinRate, 0.0, 3600.0, 10)
|
|
ADD_WIDGET_FLOAT_READ_ONLY("Spin Angle", roll.fRollerSpinAngle)
|
|
STOP_WIDGET_GROUP()
|
|
ENDPROC
|
|
|
|
PROC SETUP_DEBUG_CARWASH_CONSTANT_WIDGETS()
|
|
START_WIDGET_GROUP("Constants")
|
|
ADD_WIDGET_BOOL("Use New MP Rollers", bUseNewMPVertRollers)
|
|
ADD_WIDGET_INT_SLIDER("RollerCheck Interval", ROLLER_CHECK_INTERVAL, 1, 2000, 10)
|
|
ADD_WIDGET_INT_SLIDER("ShapeCheck Interval", SHAPE_CHECK_INTERVAL, 1, 2000, 10)
|
|
|
|
START_WIDGET_GROUP("Particle Values")
|
|
ADD_WIDGET_VECTOR_SLIDER("H Spray ROffset", vRollerHorzRotFX, -360, 360.0, 0.01)
|
|
ADD_WIDGET_VECTOR_SLIDER("V Spray ROffset", vRollerVertRotFX, -360, 360.0, 0.01)
|
|
ADD_WIDGET_VECTOR_SLIDER("V Spray POffset", vRollerVertPosFX, -5, 5, 0.01)
|
|
ADD_WIDGET_VECTOR_SLIDER("Jet Spray ROffset", vJetRotFX, -360, 360.0, 0.01)
|
|
ADD_WIDGET_VECTOR_SLIDER("Steam ROffset", vSteamRotFX, -360, 360.0, 0.01)
|
|
ADD_WIDGET_VECTOR_SLIDER("Steam POffset", vSteamPosFX, -8, 8, 0.01)
|
|
STOP_WIDGET_GROUP()
|
|
|
|
STOP_WIDGET_GROUP()
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Initializes Debug Widgets
|
|
PROC SETUP_DEBUG_CARWASH_JETS_WIDGETS(CARWASH_JETS &roll, STRING str = NULL)
|
|
IF IS_STRING_NULL_OR_EMPTY(str)
|
|
str = "Jets"
|
|
ENDIF
|
|
|
|
START_WIDGET_GROUP(str)
|
|
ADD_WIDGET_BOOL("Steam", roll.bSteam)
|
|
ADD_WIDGET_FLOAT_SLIDER("Trigger Dist", roll.fTriggerDist, 0.0, 5.0, 0.125)
|
|
ADD_WIDGET_FLOAT_SLIDER("Seperation", roll.fSeperation, 0.0, 5.0, 0.0625)
|
|
ADD_WIDGET_INT_READ_ONLY("Next Check Time", roll.iNextCheckTime)
|
|
STOP_WIDGET_GROUP()
|
|
ENDPROC
|
|
|
|
PROC SETUP_DEBUG_CARWASH_HANDLER_WIDGETS(CARWASH_HANDLER &ct)
|
|
START_WIDGET_GROUP("Carwash")
|
|
ADD_WIDGET_BOOL("Draw Debug", bDrawDebugCarwash)
|
|
ADD_WIDGET_BOOL("Use Old Verticle Brush Check", bUseOldVerticleBrushCheck)
|
|
ADD_WIDGET_BOOL("Use New Shape Test", bUseNewSweptSphereTest)
|
|
ADD_WIDGET_FLOAT_SLIDER("Sweep Sphere Radius", fSweepSphereRadius, 0.25, 3.0, 0.05)
|
|
ADD_WIDGET_FLOAT_SLIDER("X Seperation", fShapeTestXSeperation, 0.1, 5.0, 0.125)
|
|
|
|
ADD_WIDGET_BOOL("Aborted", ct.bCarwashAborted)
|
|
|
|
START_WIDGET_GROUP("Tasks")
|
|
ADD_WIDGET_BOOL("Clear Ped Tasks", bDebugForceClearPedTasks)
|
|
ADD_WIDGET_BOOL("Restart Ped Tasks", bDebugForceRestartTasks)
|
|
ADD_WIDGET_BOOL("Is Ped Runing Task", bIsDriverRunningCarwashSequence)
|
|
ADD_WIDGET_BOOL("Is Ped Done Task", bIsDriverFinishedCarwashSequence)
|
|
ADD_WIDGET_BOOL("Create Block Car", bCreateBlockCar)
|
|
ADD_WIDGET_FLOAT_SLIDER("Block Car T", fBlockCarPlaceT, -1.0, 2.0, 0.001)
|
|
ADD_WIDGET_INT_READ_ONLY("Task Sequence Progress", iDriverCarwashSequenceProgress)
|
|
ADD_WIDGET_INT_READ_ONLY("Task Sequence Size", ct.iTaskSequenceSize)
|
|
STOP_WIDGET_GROUP()
|
|
|
|
SETUP_DEBUG_CARWASH_HROLLER_WIDGETS(ct.horzRoller)
|
|
SETUP_DEBUG_CARWASH_VERTROLLER_WIDGETS(ct.vertRoller, "New Vert Roller")
|
|
SETUP_DEBUG_CARWASH_JETS_WIDGETS(ct.steamJets, "Steam")
|
|
SETUP_DEBUG_CARWASH_JETS_WIDGETS(ct.waterJets, "Water")
|
|
SETUP_DEBUG_CARWASH_JETS_WIDGETS(ct.soapJets, "Soaps")
|
|
ADD_WIDGET_FLOAT_SLIDER("Roll Shift Factor", ROLLER_SHIFT_FACTOR, 0.0, 2.0, 0.0001)
|
|
ADD_WIDGET_FLOAT_SLIDER("Forward", ct.fForwardSpeed, 0, 30.0, 0.01)
|
|
ADD_WIDGET_FLOAT_SLIDER("FCInterpolate", ct.fFinalCameraInterpolate, 0, 1.0, 0.01)
|
|
ADD_WIDGET_INT_READ_ONLY("Camera State", ct.iCurrentCameraState)
|
|
ADD_WIDGET_READ_ONLY_VECTOR("Direction", ct.cTrack.vDirection)
|
|
|
|
ADD_WIDGET_FLOAT_READ_ONLY("Car Ratio", fCarDebugRatio)
|
|
ADD_WIDGET_INT_READ_ONLY("Carwash Timer", iDebugCarWashTimer)
|
|
STOP_WIDGET_GROUP()
|
|
ENDPROC
|
|
|
|
PROC DRAW_DEBUG_BOX_WITH_HEADING(VECTOR vPos, VECTOR vDim, FLOAT fHeading)
|
|
|
|
VECTOR vBoxCorner[8]
|
|
|
|
VECTOR vMin = -vDim / 2.0
|
|
VECTOR vMax = vDim / 2.0
|
|
|
|
vBoxCorner[7] = GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(vPos, fHeading, <<vMin.x, vMin.y, vMin.z>>)
|
|
vBoxCorner[6] = GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(vPos, fHeading, <<vMax.x, vMin.y, vMin.z>>)
|
|
vBoxCorner[5] = GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(vPos, fHeading, <<vMax.x, vMax.y, vMin.z>>)
|
|
vBoxCorner[4] = GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(vPos, fHeading, <<vMin.x, vMax.y, vMin.z>>)
|
|
|
|
vBoxCorner[3] = GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(vPos, fHeading, <<vMin.x, vMin.y, vMax.z>>)
|
|
vBoxCorner[2] = GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(vPos, fHeading, <<vMax.x, vMin.y, vMax.z>>)
|
|
vBoxCorner[1] = GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(vPos, fHeading, <<vMax.x, vMax.y, vMax.z>>)
|
|
vBoxCorner[0] = GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(vPos, fHeading, <<vMin.x, vMax.y, vMax.z>>)
|
|
|
|
DRAW_DEBUG_POLY(vBoxCorner[0], vBoxCorner[1], vBoxCorner[5], 200, 100, 0, 100)
|
|
DRAW_DEBUG_POLY(vBoxCorner[0], vBoxCorner[5], vBoxCorner[4], 200, 100, 0, 100)
|
|
|
|
DRAW_DEBUG_POLY(vBoxCorner[1], vBoxCorner[2], vBoxCorner[6], 200, 200, 0, 100)
|
|
DRAW_DEBUG_POLY(vBoxCorner[1], vBoxCorner[6], vBoxCorner[5], 200, 200, 0, 100)
|
|
|
|
DRAW_DEBUG_POLY(vBoxCorner[2], vBoxCorner[3], vBoxCorner[7], 200, 100, 0, 100)
|
|
DRAW_DEBUG_POLY(vBoxCorner[2], vBoxCorner[7], vBoxCorner[6], 200, 100, 0, 100)
|
|
|
|
DRAW_DEBUG_POLY(vBoxCorner[3], vBoxCorner[0], vBoxCorner[4], 200, 200, 0, 100)
|
|
DRAW_DEBUG_POLY(vBoxCorner[3], vBoxCorner[4], vBoxCorner[7], 200, 200, 0, 100)
|
|
|
|
DRAW_DEBUG_POLY(vBoxCorner[2], vBoxCorner[1], vBoxCorner[0], 200, 150, 0, 100)
|
|
DRAW_DEBUG_POLY(vBoxCorner[3], vBoxCorner[2], vBoxCorner[0], 200, 150, 0, 100)
|
|
|
|
DRAW_DEBUG_POLY(vBoxCorner[4], vBoxCorner[5], vBoxCorner[6], 200, 150, 0, 100)
|
|
DRAW_DEBUG_POLY(vBoxCorner[4], vBoxCorner[6], vBoxCorner[7], 200, 150, 0, 100)
|
|
|
|
ENDPROC
|
|
|
|
#ENDIF
|
|
|
|
|
|
|