Files
gtav-src/script/dev_ng/singleplayer/scripts/Ambient/AmbAreaController/controller_AmbientArea.sch
T
2025-09-29 00:52:08 +02:00

227 lines
8.1 KiB
XML
Executable File

// controller_AmbientArea.sch
USING "globals.sch"
USING "mission_control_public.sch"
USING "net_common_functions.sch"
USING "flow_public_game.sch"
// GLOBAL DATA STORED IN
// X:\gta5\script\dev\singleplayer\include\globals\AmbientArea_globals.sch
CONST_INT AMB_AREAS_PER_LOOP 2 // How many out of our list of ambient areas should we update per loop.
CONST_INT AMB_AREA_CONTROLLER_WAIT 500 // How long to wait between each update loop.
CONST_FLOAT AMB_AREA_TERMINATE_ADD 400.0 // 20.0m squared.
/// PURPOSE:
/// Fills in the array of g_AmbientAreaData when the controller starts.
PROC AMBIENTAREA_INIT_GLOBAL_DATA()
g_AmbientAreaData[eAMBAREA_ARMYBASE].vAmbAreaCenter = << -2189.5447, 3129.6125, 0.0 >>
g_AmbientAreaData[eAMBAREA_ARMYBASE].fRadius2 = 1000.0*1000.0
g_AmbientAreaData[eAMBAREA_ARMYBASE].ambAreaFlags = eAmbientArea_NoFlags
g_AmbientAreaData[eAMBAREA_ARMYBASE].thisThread = NULL
g_AmbientAreaData[eAMBAREA_GOLF].vAmbAreaCenter = << -1172.8221, 66.5235, 0.0 >>
g_AmbientAreaData[eAMBAREA_GOLF].fRadius2 = 300.0*300.0
g_AmbientAreaData[eAMBAREA_GOLF].ambAreaFlags = eAmbientArea_NoFlags
g_AmbientAreaData[eAMBAREA_GOLF].thisThread = NULL
g_AmbientAreaData[eAMBAREA_PRISON].vAmbAreaCenter = << 1692.1469, 2562.3127, 0.0 >>
g_AmbientAreaData[eAMBAREA_PRISON].fRadius2 = 300.0*300.0
g_AmbientAreaData[eAMBAREA_PRISON].ambAreaFlags = eAmbientArea_NoFlags
g_AmbientAreaData[eAMBAREA_PRISON].thisThread = NULL
g_AmbientAreaData[eAMBAREA_PUTTING].vAmbAreaCenter = << -1329.6797, 60.3478, 0.0 >>
g_AmbientAreaData[eAMBAREA_PUTTING].fRadius2 = 250.0*250.0
g_AmbientAreaData[eAMBAREA_PUTTING].ambAreaFlags = eAmbientArea_NoFlags
g_AmbientAreaData[eAMBAREA_PUTTING].thisThread = NULL
g_AmbientAreaData[eAMBAREA_STRIPCLUB].vAmbAreaCenter = <<114.64, -1290.34, 0.0>>
g_AmbientAreaData[eAMBAREA_STRIPCLUB].fRadius2 = 100.0*100.0
g_AmbientAreaData[eAMBAREA_STRIPCLUB].ambAreaFlags = eAmbientArea_AllowDuringMission
g_AmbientAreaData[eAMBAREA_STRIPCLUB].thisThread = NULL
// Make sure those vectors are using 0.0 as the Z, just incase it wasn't already done above.
INT index
FOR index = 0 TO ENUM_TO_INT(NUMBER_OF_AMB_AREAS) - 1
g_AmbientAreaData[index].vAmbAreaCenter.z = 0.0
ENDFOR
ENDPROC
/// PURPOSE:
/// Checks to see if an ambient area is currently flagged as running.
FUNC BOOL AMBIENT_AREA_IS_RUNNING(AMBIENT_AREA_DATA & sAmbData)
RETURN IS_BITMASK_ENUM_AS_ENUM_SET(sAmbData.ambAreaFlags, eAmbientArea_Running)
ENDFUNC
/// PURPOSE:
/// General check to see if the ambient area is allowed to launch.
/// RETURNS:
/// TRUE if the item can launch.
FUNC BOOL AMBIENT_AREA_CAN_LAUNCH(AMBIENT_AREA_DATA & sAmbData, VECTOR vPlayerPos)
// If we're not allowed during a mission, check to see if a mission is running.
IF NOT IS_BITMASK_ENUM_AS_ENUM_SET(sAmbData.ambAreaFlags, eAmbientArea_AllowDuringMission)
IF IS_CURRENTLY_ON_MISSION_OF_ANY_TYPE()
AND NOT IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_FRIEND_ACTIVITY)
// PRINTLN("NOT RUNNING AMBIENT ARMY BASE")
RETURN FALSE
ELSE
// PRINTLN("FAILING ON MISSION CHECK")
ENDIF
ELSE
// PRINTLN("FAILING BIT CHECK")
ENDIF
// Distance check. If we're outside the radius, then we can't launch.
IF VDIST2(vPlayerPos, sAmbData.vAmbAreaCenter) > (sAmbData.fRadius2)
RETURN FALSE
ENDIF
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), << -2080.115, 3292.193, -11.667 >>, << -2112.049, 3224.331, 11.667 >>, 115.000, TRUE, FALSE)
// PRINTLN("UNABLE TO LAUNCH, PLAYER IS INSIDE THE UNDERGROUND TUNNEL SYSTEM")
RETURN FALSE
ENDIF
ENDIF
// IF g_bTriggerSceneActive
//// PRINTLN("AMBIENT AREA CONTROLLER: g_bTriggerSceneActive IS TRUE")
// RETURN FALSE
// ENDIF
// Debug only refusals...
#IF IS_DEBUG_BUILD
// Can't run during the freemode mission builder.
IF GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(HASH("FM_Main_Menu")) != 0
RETURN FALSE
ENDIF
#ENDIF
// We can run!
RETURN TRUE
ENDFUNC
/// PURPOSE:
/// Checks to see if a currently running ambient area should quit.
/// RETURNS:
/// TRUE if it should terminate.
FUNC BOOL AMBIENT_AREA_SHOULD_TERMINATE(AMBIENT_AREAS eArea, VECTOR vPlayerPos)
// Zero this out so that we don't take into acct height.
// already been zero'ed out in working points.
vPlayerPos.z = 0.0
#IF IS_DEBUG_BUILD
IF g_bDebugBlockAmbientScripts
// PRINTLN("WE'RE RUNNING WITH NO AMBIENT COMMAND LINE - TERMINATE NOW")
RETURN TRUE
ELSE
// PRINTLN("NO COMMAND LINE - GOOD TO RUN")
ENDIF
#ENDIF
//g_AmbientAreaData[eArea]
// If running:
IF NOT IS_THREAD_ACTIVE(g_AmbientAreaData[eArea].thisThread)
// - Has the thread shut down on its own?
RETURN TRUE
ENDIF
IF IS_BITMASK_ENUM_AS_ENUM_SET(g_AmbientAreaData[eArea].ambAreaFlags, eAmbientArea_ForceDeactivate)
// - Has something ordered us to deactivate? If so, end the script.
RETURN TRUE
ENDIF
IF IS_CURRENTLY_ON_MISSION_OF_ANY_TYPE()
AND NOT IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_FRIEND_ACTIVITY)
IF NOT IS_BITMASK_ENUM_AS_ENUM_SET(g_AmbientAreaData[eArea].ambAreaFlags, eAmbientArea_AllowDuringMission)
// - A mission is running, and we're not allowed to run during missions. End the script.
// Not true in all cases... for instance, the golf ambient area can run during golf...
// Do those specialized checks here.
IF (eArea = eAMBAREA_GOLF) OR (eArea = eAMBAREA_PUTTING)
IF (GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(HASH("golf")) = 0)
// Golf isn't running, but a mission is running. Should kill the golf associated ambients.
RETURN TRUE
ENDIF
ELSE
// Mission is running, it's not a special case.
RETURN TRUE
ENDIF
ENDIF
ENDIF
IF (VDIST2(g_AmbientAreaData[eArea].vAmbAreaCenter, vPlayerPos) > g_AmbientAreaData[eArea].fRadius2 + AMB_AREA_TERMINATE_ADD)
// - Has the player left the area (by more than 10m)? If so, end the script.
PRINTLN("PLAYER HAS LEFT THE AREA!!!")
RETURN TRUE
ENDIF
// Debug only terminates...
#IF IS_DEBUG_BUILD
// Can't run during the freemode mission builder.
IF (GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(HASH("FM_Main_Menu")) != 0)
RETURN TRUE
ENDIF
#ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Starts an ambient area.
PROC AMBIENT_AREA_LAUNCH(AMBIENT_AREAS eAreaToLaunch)
STRING sThreadName
INT iThreadHash
INT iStackSize = DEFAULT_STACK_SIZE
BOOL bIsMultiplayerAllowed = TRUE
SWITCH (eAreaToLaunch)
CASE eAMBAREA_ARMYBASE
sThreadName = "re_ArmyBase"
iThreadHash = HASH("re_ArmyBase")
BREAK
CASE eAMBAREA_GOLF
iStackSize = MULTIPLAYER_MISSION_STACK_SIZE
sThreadName = "golf_ai_foursome"
iThreadHash = HASH("golf_ai_foursome")
bIsMultiplayerAllowed = FALSE
BREAK
CASE eAMBAREA_PRISON
sThreadName = "re_Prison"
iThreadHash = HASH("re_Prison")
BREAK
CASE eAMBAREA_PUTTING
iStackSize = MULTIPLAYER_MISSION_STACK_SIZE
sThreadName = "golf_ai_foursome_putting"
iThreadHash = HASH("golf_ai_foursome_putting")
bIsMultiplayerAllowed = FALSE
BREAK
CASE eAMBAREA_STRIPCLUB
iStackSize = FRIEND_STACK_SIZE
sThreadName = "stripclub"
iThreadHash = HASH("stripclub")
bIsMultiplayerAllowed = FALSE
BREAK
ENDSWITCH
IF NOT bIsMultiplayerAllowed AND IS_FREEMODE()
EXIT //for some reason the ambient area control is launching in freemode, not all scripts are valid
ENDIF
IF (GET_LENGTH_OF_LITERAL_STRING(sThreadName) != 0)
IF GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(iThreadHash) = 0
PRINTLN("*************** controller_AmbientArea launching: ", sThreadName, " ***************")
REQUEST_SCRIPT(sThreadName)
WHILE NOT HAS_SCRIPT_LOADED(sThreadName)
WAIT(0)
ENDWHILE
g_AmbientAreaData[eAreaToLaunch].thisThread = START_NEW_SCRIPT(sThreadName, iStackSize)
SET_SCRIPT_AS_NO_LONGER_NEEDED(sThreadName)
IF (g_AmbientAreaData[eAreaToLaunch].thisThread != NULL)
SET_BITMASK_ENUM_AS_ENUM(g_AmbientAreaData[eAreaToLaunch].ambAreaFlags, eAmbientArea_Running)
ENDIF
ENDIF
ENDIF
ENDPROC