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

387 lines
11 KiB
Python
Executable File

// *****************************************************************************************
// *****************************************************************************************
//
// MISSION NAME : launcher_carwash.sc
// AUTHOR : Aaron Gandaa
// DESCRIPTION : Car Wash Handler
//
// CARWASH 1 - BLIP:
// *****************************************************************************************
// *****************************************************************************************
//----------------------
// INCLUDES
//----------------------
USING "cost_halo.sch"
#IF IS_DEBUG_BUILD
USING "shared_debug.sch"
#ENDIF
//----------------------
// ENUM
//----------------------
//----------------------
// STRUCT
//----------------------
//----------------------
// CONSTANTS
//----------------------
CONST_INT MAX_CARWASHES 2
//----------------------
// VARIABLES
//----------------------
COST_HALO carWash[MAX_CARWASHES]
COSTHALO_HANDLER carWashHandler
BOOL bHasRoof
VECTOR vCarwashEntryPoint[MAX_CARWASHES] // we check the radius here if someone is blocking don't allow carwash
INT iNextClosedCheckTime[MAX_CARWASHES]
SHAPETEST_INDEX shapeTest[MAX_CARWASHES]
//----------------------
// DEBUG VARIABLES
//----------------------
#IF IS_DEBUG_BUILD
WIDGET_GROUP_ID m_WidgetGroup
BOOL bQuitScript = FALSE
BOOL bDirtyCar = FALSE
BOOL bForceClearHelp = FALSE
INT iStateDebug
VECTOR vPlayerRot
VECTOR vPlayerCarRot
BOOL bExtras[8]
BOOL bWashDecals
FLOAT fWashDecals = 0.0
FLOAT fPlayerSpeed = 0.0
BOOL bFillCar
#ENDIF
//----------------------
// DEBUG FUNCTIONS
//----------------------
#IF IS_DEBUG_BUILD
/// PURPOSE:
/// Setups Debug Widgets
PROC SETUP_DEBUG_WIDGETS()
INT i
TEXT_LABEL lbl
//SET_PROFILING_OF_THIS_SCRIPT(TRUE)
m_WidgetGroup = START_WIDGET_GROUP("Carwash Launcher")
ADD_WIDGET_BOOL("Quit Script", bQuitScript)
ADD_WIDGET_BOOL("Dirty Car", bDirtyCar)
ADD_WIDGET_BOOL("Help Shown", carWashHandler.bTriggerHelpShown)
ADD_WIDGET_BOOL("Show Markers", carWashHandler.bShowMarkers)
ADD_WIDGET_BOOL("Force Clear Help", bForceClearHelp)
ADD_WIDGET_BOOL("Wash Decals", bWashDecals)
ADD_WIDGET_BOOL("Have Roof", bHasRoof)
ADD_WIDGET_BOOL("Fill Car", bFillCar)
ADD_WIDGET_FLOAT_SLIDER("Wash Slider", fWashDecals, 0.0, 40.0, 0.005)
ADD_WIDGET_READ_ONLY_VECTOR("Player Rot", vPlayerRot)
ADD_WIDGET_READ_ONLY_VECTOR("Player Car Rot", vPlayerCarRot)
ADD_WIDGET_INT_READ_ONLY("State", iStateDebug)
ADD_WIDGET_INT_READ_ONLY("Current Halo", carWashHandler.iSelectedHalo)
ADD_WIDGET_READ_ONLY_VECTOR("Carwash 0 Desired", carWash[0].vDesiredDirection)
ADD_WIDGET_FLOAT_READ_ONLY("Carwash 0 Tol", carWash[0].fHeadingTolerance)
ADD_WIDGET_READ_ONLY_VECTOR("Carwash 1 Desired", carWash[1].vDesiredDirection)
ADD_WIDGET_FLOAT_READ_ONLY("Carwash 1 Tol", carWash[1].fHeadingTolerance)
ADD_WIDGET_FLOAT_READ_ONLY("Player Speed", fPlayerSpeed )
START_WIDGET_GROUP("Extras")
REPEAT COUNT_OF(bExtras) i
lbl = "Extra"
lbl += i
ADD_WIDGET_BOOL(lbl, bExtras[i])
ENDREPEAT
STOP_WIDGET_GROUP()
STOP_WIDGET_GROUP()
ENDPROC
/// PURPOSE:
/// Removes Debug Widgets
PROC CLEANUP_DEBUG_WIDGETS()
IF DOES_WIDGET_GROUP_EXIST(m_WidgetGroup)
DELETE_WIDGET_GROUP(m_WidgetGroup)
ENDIF
ENDPROC
#ENDIF
//----------------------
// SCRIPT FUNCTIONS
//----------------------
PROC UPDATE_CARWASH_BLOCK_CHECK(INT iCarwashID)
SHAPETEST_STATUS sTestStatus
ENTITY_INDEX hitentity
VECTOR vhit, vnorm
INT ihits
IF NOT IS_PLAYER_IN_COST_HALO(carWash[iCarWashID])
carWash[iCarWashID].bCustomCheck = FALSE // clear the custom check [blocked]
shapeTest[iCarWashID] = NULL
EXIT
ENDIF
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
carWash[iCarWashID].bCustomCheck = FALSE // clear the custom check [blocked]
shapeTest[iCarWashID] = NULL
EXIT
ENDIF
IF (shapeTest[iCarWashID] = NULL)
IF (GET_GAME_TIMER() > iNextClosedCheckTime[iCarWashID])
shapeTest[iCarWashID] = START_SHAPE_TEST_SWEPT_SPHERE(vCarWashEntryPoint[iCarwashID], vCarWashEntryPoint[iCarwashID] + <<0, 0, 1>>, 2.0, SCRIPT_INCLUDE_VEHICLE, GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()))
ENDIF
ELSE
sTestStatus = GET_SHAPE_TEST_RESULT(shapeTest[iCarWashID], ihits, vhit, vnorm, hitentity)
IF (sTestStatus = SHAPETEST_STATUS_RESULTS_READY)
carWash[iCarWashID].bCustomCheck = FALSE
IF (iHits > 0)
IF DOES_ENTITY_EXIST(hitentity)
IF IS_ENTITY_A_VEHICLE(hitEntity)
carWash[iCarWashID].bCustomCheck = TRUE
ENDIF
ENDIF
ENDIF
shapeTest[iCarWashID] = NULL
ENDIF
IF (sTestStatus = SHAPETEST_STATUS_NONEXISTENT)
shapeTest[iCarWashID] = NULL
ENDIF
iNextClosedCheckTime[iCarWashID] = GET_GAME_TIMER() + 250
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
/// PURPOSE:
/// Setups up the script
PROC SCRIPT_SETUP()
SETUP_COST_HALO(carWash[0], HALO_VEHICLE, "Carwash1", GET_POSITION_FROM_STATIC_BLIP(STATIC_BLIP_AMBIENT_CARWASH_LONG), 15, "", FALSE, 4.0) // long
SETUP_COST_HALO(carWash[1], HALO_VEHICLE, "Carwash2", GET_POSITION_FROM_STATIC_BLIP(STATIC_BLIP_AMBIENT_CARWASH_SHORT), 15, "", FALSE, 4.0) // small
SETUP_COST_HALO_DIRECTION_TOLERANCE(carWash[0], <<-1, 0, 0>>, 360.0)
SETUP_COST_HALO_DIRECTION_TOLERANCE(carWash[1], <<0, -1, 0>>, 360.0)
SET_STRINGS_FOR_CARWASH_HALO_HANDLER(carWashHandler)
vCarwashEntryPoint[0] = <<47.6, -1392.0, 29.4>>
vCarwashEntryPoint[1] = <<-700.0, -925.3, 19.0>>
ENDPROC
/// PURPOSE:
/// Cleanups Script and terminates thread - this should be the last function called
PROC SCRIPT_CLEANUP()
#IF IS_DEBUG_BUILD
CLEANUP_DEBUG_WIDGETS()
#ENDIF
SHUTDOWN_COST_HALOS(carWash)
CLEAR_COSTHALO_HANDLER_HELP(carWashHandler)
CPRINTLN(DEBUG_AMBIENT, "Launcher Carwash Cleanup")
TERMINATE_THIS_THREAD()
ENDPROC
//----------------------
// UPDATE FUNCTIONS
//----------------------
#IF IS_DEBUG_BUILD
/// PURPOSE:
/// Updates Debug Widgets and draw debug stuff
PROC UPDATE_DEBUG_WIDGETS()
INT i
VEHICLE_INDEX veh
iStateDebug = ENUM_TO_INT(carWashHandler.selectState)
IF (bQuitScript)
SCRIPT_CLEANUP()
ENDIF
fPlayerSpeed = GET_ENTITY_SPEED(PLAYER_PED_ID())
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
vPlayerCarRot = GET_ENTITY_ROTATION(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()))
REPEAT COUNT_OF(bExtras) i
//bExtras[i] = IS_VEHICLE_EXTRA_TURNED_ON(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), i)
ENDREPEAT
ENDIF
vPlayerRot = GET_ENTITY_ROTATION(PLAYER_PED_ID())
IF (bDirtyCar)
veh = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())
IF IS_ENTITY_ALIVE(veh)
SET_VEHICLE_DIRT_LEVEL(veh, 14.9)
ENDIF
bDirtyCar = FALSE
ENDIF
IF (bWashDecals)
veh = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())
IF IS_ENTITY_ALIVE(veh)
WASH_DECALS_FROM_VEHICLE(veh, fWashDecals)
ENDIF
bWashDecals = FALSE
ENDIF
IF (bForceClearHelp)
CLEAR_COSTHALO_HANDLER_HELP(carWashHandler)
bForceClearHelp = FALSE
ENDIF
IF (bFillCar)
veh = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())
IF IS_ENTITY_ALIVE(veh)
REPEAT GET_VEHICLE_MAX_NUMBER_OF_PASSENGERS(veh) i
IF IS_VEHICLE_SEAT_FREE(veh, INT_TO_ENUM(VEHICLE_SEAT, i))
CREATE_PED_INSIDE_VEHICLE_AUTO_SEAT(GET_PLAYER_MODEL(), veh)
ENDIF
ENDREPEAT
ENDIF
bFillCar = FALSE
ENDIF
ENDPROC
#ENDIF
//----------------------
// MAIN SCRIPT
//----------------------
SCRIPT(coords_struct in_coords)
BOOL bNoWay
VEHICLE_INDEX veh
VECTOR vInCoords = in_coords.vec_coord[0] // Update world point
IF GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH (HASH("launcher_carwash")) > 1
CPRINTLN(DEBUG_AMBIENT, GET_THIS_SCRIPT_NAME(), " is attempting to launch with an instance already active.")
TERMINATE_THIS_THREAD()
ENDIF
// Setup callback when player is killed, arrested or goes to multiplayer
IF NETWORK_IS_GAME_IN_PROGRESS()
NETWORK_SET_SCRIPT_IS_SAFE_FOR_NETWORK_GAME()
CPRINTLN(DEBUG_AMBIENT, "CAR WASH LAUNCHER:: PROCESS_PRE_GAME started in MP")
SET_THIS_SCRIPT_CAN_BE_PAUSED(FALSE)
ELSE
CPRINTLN(DEBUG_AMBIENT, "CAR WASH LAUNCHER:: PROCESS_PRE_GAME started in SP")
IF HAS_FORCE_CLEANUP_OCCURRED(DEFAULT_FORCE_CLEANUP_FLAGS | FORCE_CLEANUP_FLAG_MAGDEMO | FORCE_CLEANUP_FLAG_REPEAT_PLAY)
SCRIPT_CLEANUP()
ENDIF
ENDIF
// Load Clifford Version
IF g_bLoadedClifford
IF GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(HASH("launcher_carwashCLF")) = 0
REQUEST_SCRIPT_WITH_NAME_HASH(HASH("launcher_carwashCLF"))
WHILE NOT HAS_SCRIPT_WITH_NAME_HASH_LOADED(HASH("launcher_carwashCLF"))
WAIT(0)
ENDWHILE
START_NEW_SCRIPT_WITH_NAME_HASH_AND_ARGS(HASH("launcher_carwashCLF"),in_coords, SIZE_OF(in_coords),DEFAULT_STACK_SIZE)
ENDIF
//Shutdown bed save script since we're switching to AGT
TERMINATE_THIS_THREAD()
ENDIF
CPRINTLN(DEBUG_AMBIENT, "Launcher Carwash:", 102, " Initializing - World Point:", vInCoords)
IF IS_ENTITY_OK(PLAYER_PED_ID())
CPRINTLN(DEBUG_AMBIENT, "Distance From Player To World Point: ", GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), vInCoords, FALSE))
ENDIF
#IF IS_DEBUG_BUILD
SETUP_DEBUG_WIDGETS()
#ENDIF
SCRIPT_SETUP()
WHILE (TRUE)
IS_ENTITY_OK(PLAYER_PED_ID())
#IF IS_DEBUG_BUILD
UPDATE_DEBUG_WIDGETS()
#ENDIF
IF (GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), vInCoords, FALSE) > (RC_BRAIN_ACTIVATION_RANGE_NORMAL + 20.0))
CPRINTLN(DEBUG_AMBIENT, "Launcher Carwash - Terminating Out Of Range")
SCRIPT_CLEANUP()
ENDIF
// check vehicle validity
bNoWay = FALSE
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
veh = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())
bNoWay = IS_VEHICLE_NOT_ALLOWED_IN_CAR_WASH(veh) OR IS_ANY_VEHICLE_MAIN_DOOR_BROKEN(veh)
bHasRoof = DOES_VEHICLE_HAVE_ROOF(veh)
DUMMY_REFERENCE_BOOL(bHasRoof)
ENDIF
INT i
REPEAT COUNT_OF(carWash) i
UPDATE_CARWASH_BLOCK_CHECK(i)
ENDREPEAT
// update halos
IF UPDATE_COSTHALO_HANDLER(carWash, carWashHandler, bNoWay)
CPRINTLN(DEBUG_AMBIENT, "Launcher Carwash - Terminating - Running Carwash")
SCRIPT_CLEANUP()
ENDIF
WAIT(0)
ENDWHILE
ENDSCRIPT