Files
gtav-src/script/dev_ng/singleplayer/include/public/battlebuddy_public.sch
T
2025-09-29 00:52:08 +02:00

408 lines
16 KiB
Scheme
Executable File

// *****************************************************************************************
// *****************************************************************************************
//
// MISSION NAME : battlebuddy_public.sch
// AUTHOR : Sam Hackett
// DESCRIPTION : Interface for taking control of battle buddies
//
// *****************************************************************************************
// *****************************************************************************************
USING "rage_builtins.sch"
USING "globals.sch"
USING "commands_misc.sch"
USING "selector_public.sch"
//-------------------------------------------------------------------------------------------------------------------------------------------
// CONSTANTS
//-------------------------------------------------------------------------------------------------------------------------------------------
CONST_INT MAX_BATTLE_BUDDIES NUM_OF_PLAYABLE_PEDS
//CONST_FLOAT CONST_fBattleBuddyInitialFailDist 400.0//500.0
CONST_FLOAT CONST_fBattleBuddyAvailableFailDist 200.0
CONST_FLOAT CONST_fBattleBuddyLostDist 100.0
CONST_FLOAT CONST_fBattleBuddyMinCreateDist 300.0//400.0//300.0//200.0//
CONST_FLOAT CONST_fBattleBuddyArrivalSpeed 20.0//25.0
CONST_FLOAT CONST_fBattleBuddyArrivalSpeedFast 40.0
//CONST_FLOAT CONST_fBattleBuddyMaxCreateDist 250.0//425.0
CONST_FLOAT CONST_fBattleBuddyMaxOnFootCreateDist 25.0
//-------------------------------------------------------------------------------------------------------------------------------------------
// ENUMS
//-------------------------------------------------------------------------------------------------------------------------------------------
ENUM enumBattleBuddyBehaviourFlag
BBF_SpawnOnSwitchedOffNodes = 0, // Allow switched off nodes when choosing spawn point
BBF_SpawnCheckMilitaryBase, // If player is outside base, spawn point must be outside - If player is inside spawn point must be too
BBF_SpawnCheckDocks, // Don't allow buddy to spawn at sea end of docks
BBF_ArriveOnSwitchOnNodesOnly, // When choosing arrival point, only allow switched on nodes
BBF_SwitchDefaultTrevor, // Quick switch defaults to Trevor
BBF_CombatGroupSpacing, // Group fans out wider and maintains formation
BBF_CombatDefensive, // In combat, uses CM_DEFENSIVE instead of CM_WILLADVANCE
BBF_CombatDelay, // When combat state starts, will have a small random delay to avoid looking synchronised
// BBF_CombatIgnorePlayerDist, // Soldier doesn't need to be near player to enter combat mode
BBF_CombatDefendCargobobArea, // Defend the area where cargobob is created in docks2b
BBF_DriveInConvoy, // If the player and buddy are in different cars, the buddy will stay in his car
BBF_DriveHighSpeed, // Drives faster
BBF_ForceFrontPassengerSeat, // Causes buddies to use front passenger seat
BBF_RejectAllBattleBuddies, // Causes all buddies to leave (and will continue to block buddies whilst on)
BBF_DontFleeCopsWhenDriver, // If the player is a passenger and the buddy is the driver, this won't make him drive randomly when wanted by the cops
BBF_CloseGroupSpacing, // Buddies follow player at 2m
MAX_BATTLEBUDDY_BEHAVIOUR_FLAGS
ENDENUM
#IF IS_DEBUG_BUILD
FUNC STRING GetLabel_enumBattleBuddyBehaviourFlag(enumBattleBuddyBehaviourFlag eFlag)
SWITCH eFlag
CASE BBF_SpawnOnSwitchedOffNodes RETURN "BBF_SpawnOnSwitchedOffNodes" BREAK
CASE BBF_SpawnCheckMilitaryBase RETURN "BBF_SpawnCheckMilitaryBase" BREAK
CASE BBF_SpawnCheckDocks RETURN "BBF_SpawnCheckDocks" BREAK
CASE BBF_ArriveOnSwitchOnNodesOnly RETURN "BBF_ArriveOnSwitchOnNodesOnly" BREAK
CASE BBF_SwitchDefaultTrevor RETURN "BBF_SwitchDefaultTrevor" BREAK
CASE BBF_CombatGroupSpacing RETURN "BBF_CombatGroupSpacing" BREAK
CASE BBF_CombatDefensive RETURN "BBF_CombatDefensive" BREAK
CASE BBF_CombatDelay RETURN "BBF_CombatDelay" BREAK
// CASE BBF_CombatIgnorePlayerDist RETURN "BBF_CombatIgnorePlayerDist" BREAK
CASE BBF_CombatDefendCargobobArea RETURN "BBF_CombatDefendCargobobArea" BREAK
CASE BBF_DriveInConvoy RETURN "BBF_DriveInConvoy" BREAK
CASE BBF_DriveHighSpeed RETURN "BBF_DriveHighSpeed" BREAK
CASE BBF_ForceFrontPassengerSeat RETURN "BBF_ForceFrontPassengerSeat" BREAK
CASE BBF_RejectAllBattleBuddies RETURN "BBF_RejectAllBattleBuddies" BREAK
CASE BBF_DontFleeCopsWhenDriver RETURN "BBF_DontFleeCopsWhenDriver" BREAK
CASE BBF_CloseGroupSpacing RETURN "BBF_CloseGroupSpacing" BREAK
CASE MAX_BATTLEBUDDY_BEHAVIOUR_FLAGS RETURN "MAX_BATTLEBUDDY_BEHAVIOUR_FLAGS" BREAK
ENDSWITCH
SCRIPT_ASSERT("invalid eFlag in GetLabel_enumBattleBuddyBehaviourFlag()")
RETURN "invalid eFlag in GetLabel_enumBattleBuddyBehaviourFlag()"
ENDFUNC
#ENDIF
//-------------------------------------------------------------------------------------------------------------------------------------------
// OVERRIDE INTERFACE
//-------------------------------------------------------------------------------------------------------------------------------------------
/// PURPOSE:
/// This is just the same as getting a ped from the global selector
/// PARAMS:
/// eChar - The character to get the current instance of
/// bAllowCurrentPlayer - You may want to override all potential battle buddies and just keep hold of them,
/// or you may want to override non-player battle buddies to do specific tasks then release them again.
/// In the first case you would allow current player, in the second you wouldn't.
/// RETURNS:
/// The ped handle for the current character instance
FUNC PED_INDEX GET_BATTLEBUDDY_PED(enumCharacterList eChar)
IF ENUM_TO_INT(eChar) > MAX_BATTLE_BUDDIES
CPRINTLN(DEBUG_FRIENDS, "GET_BATTLEBUDDY_PED() - eChar is not a playable char - ", GetLabel_enumCharacterList(eChar))
SCRIPT_ASSERT("GET_BATTLEBUDDY_PED() - eChar is not a playable char")
RETURN NULL
ENDIF
IF eChar = GET_CURRENT_PLAYER_PED_ENUM()
RETURN PLAYER_PED_ID()
ELSE
RETURN g_sPlayerPedRequest.sSelectorPeds.pedID[GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(eChar)]
ENDIF
ENDFUNC
/// PURPOSE:
/// Checks if the passed battlebuddy ped is available to be overridden by a mission.
/// (NB. Will return FALSE is the buddy is injured, the buddy must be alive to be overridden)
FUNC BOOL IS_BATTLEBUDDY_AVAILABLE(PED_INDEX hPed, BOOL bAllowIfPlayer)
RETURN FALSE // BBUDDIES REMOVED
IF NOT IS_PED_INJURED(hPed)
enumCharacterList eChar = GET_PLAYER_PED_ENUM(hPed)
// General tests
IF ENUM_TO_INT(eChar) > MAX_BATTLE_BUDDIES
CPRINTLN(DEBUG_FRIENDS, "IS_BATTLEBUDDY_AVAILABLE() - hPed is not a playable char - ", GetLabel_enumCharacterList(eChar))
SCRIPT_ASSERT("IS_BATTLEBUDDY_AVAILABLE() - hPed is not a playable char")
RETURN FALSE
ENDIF
IF GET_BATTLEBUDDY_PED(eChar) <> hPed
CPRINTLN(DEBUG_FRIENDS, "IS_BATTLEBUDDY_AVAILABLE() - Warning, hPed has gone out of sync with selector - ", GetLabel_enumCharacterList(eChar))
SCRIPT_ASSERT("IS_BATTLEBUDDY_AVAILABLE() - Warning, hPed has gone out of sync with selector")
RETURN FALSE
ENDIF
// May want to exclude player
IF bAllowIfPlayer = FALSE
IF hPed = PLAYER_PED_ID()
RETURN FALSE
ENDIF
ENDIF
// Return true if uninjured and available
IF IS_BIT_SET(g_bitfieldBattleBuddyAvailable, ENUM_TO_INT(eChar))
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Checks if the passed battlebuddy ped is currently overridden by a mission
/// (NB. Will return FALSE is the buddy is injured, the buddy must be alive to be considered overridden)
FUNC BOOL IS_BATTLEBUDDY_OVERRIDDEN(PED_INDEX hPed)
RETURN FALSE // BBUDDIES REMOVED
IF NOT IS_PED_INJURED(hPed)
enumCharacterList eChar = GET_PLAYER_PED_ENUM(hPed)
// General tests
IF ENUM_TO_INT(eChar) > MAX_BATTLE_BUDDIES
CPRINTLN(DEBUG_FRIENDS, "IS_BATTLEBUDDY_OVERRIDDEN() - hPed is not a playable char - ", GetLabel_enumCharacterList(eChar))
SCRIPT_ASSERT("IS_BATTLEBUDDY_OVERRIDDEN() - hPed is not a playable char")
RETURN FALSE
ENDIF
IF GET_BATTLEBUDDY_PED(eChar) <> hPed
CPRINTLN(DEBUG_FRIENDS, "IS_BATTLEBUDDY_OVERRIDDEN() - Warning, hPed has gone out of sync with selector - ", GetLabel_enumCharacterList(eChar))
SCRIPT_ASSERT("IS_BATTLEBUDDY_OVERRIDDEN() - Warning, hPed has gone out of sync with selector")
RETURN FALSE
ENDIF
// Return true if uninjured and overridden
IF IS_BIT_SET(g_bitfieldBattleBuddyOverridden, ENUM_TO_INT(eChar))
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Puts the battlebuddy ped into override mode, so your mission can control it.
/// (NB: You must check if the ped is not overridden first)
/// (NB: Override will only be successful if ped was available for override)
/// PARAMS:
/// hPed - The battlebuddy ped you want to override
/// RETURNS:
/// Returns TRUE if the override was succesful
FUNC BOOL OVERRIDE_BATTLEBUDDY(PED_INDEX hPed, BOOL bAllowIfPlayer)
RETURN FALSE // BBUDDIES REMOVED
IF NOT IS_PED_INJURED(hPed)
enumCharacterList eChar = GET_PLAYER_PED_ENUM(hPed)
// General tests
IF ENUM_TO_INT(eChar) > MAX_BATTLE_BUDDIES
CPRINTLN(DEBUG_FRIENDS, "OVERRIDE_BATTLEBUDDY() - hPed is not a playable char - ", GetLabel_enumCharacterList(eChar))
SCRIPT_ASSERT("OVERRIDE_BATTLEBUDDY() - hPed is not a playable char")
RETURN FALSE
ENDIF
IF GET_BATTLEBUDDY_PED(eChar) <> hPed
CPRINTLN(DEBUG_FRIENDS, "OVERRIDE_BATTLEBUDDY() - Warning, hPed has gone out of sync with selector - ", GetLabel_enumCharacterList(eChar))
SCRIPT_ASSERT("OVERRIDE_BATTLEBUDDY() - Warning, hPed has gone out of sync with selector")
RETURN FALSE
ENDIF
// Specific tests
IF IS_BIT_SET(g_bitfieldBattleBuddyOverridden, ENUM_TO_INT(eChar))
CPRINTLN(DEBUG_FRIENDS, "OVERRIDE_BATTLEBUDDY() - Trying to override battle buddy when already overridden - ", GetLabel_enumCharacterList(eChar))
SCRIPT_ASSERT("OVERRIDE_BATTLEBUDDY() - Trying to override battle buddy when already overridden")
RETURN FALSE
ENDIF
// May want to exclude player
IF bAllowIfPlayer = FALSE
IF hPed = PLAYER_PED_ID()
RETURN FALSE
ENDIF
ENDIF
IF IS_BIT_SET(g_bitfieldBattleBuddyAvailable, ENUM_TO_INT(eChar))
// Override battle buddy
CPRINTLN(DEBUG_FRIENDS, "OVERRIDE_BATTLEBUDDY() - ", GetLabel_enumCharacterList(eChar))
// Unset attributes
SET_PED_INFINITE_AMMO(hPed, FALSE)
SET_ENTITY_LOAD_COLLISION_FLAG(hPed, FALSE)
SET_BIT(g_bitfieldBattleBuddyOverridden, ENUM_TO_INT(eChar))
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Releases the battlebuddy ped from override mode, giving control back to the battle buddy controller.
/// (NB: You must check if the ped is overridden first)
/// PARAMS:
/// hPed - The battlebuddy ped you want to release
/// RETURNS:
/// Returns TRUE if the release was succesful
FUNC BOOL RELEASE_BATTLEBUDDY(PED_INDEX hPed)
RETURN FALSE // BBUDDIES REMOVED
IF NOT IS_PED_INJURED(hPed)
enumCharacterList eChar = GET_PLAYER_PED_ENUM(hPed)
// General tests
IF ENUM_TO_INT(eChar) > MAX_BATTLE_BUDDIES
CPRINTLN(DEBUG_FRIENDS, "OVERRIDE_BATTLEBUDDY() - hPed is not a playable char - ", GetLabel_enumCharacterList(eChar))
SCRIPT_ASSERT("OVERRIDE_BATTLEBUDDY() - hPed is not a playable char")
RETURN FALSE
ENDIF
IF GET_BATTLEBUDDY_PED(eChar) <> hPed
CPRINTLN(DEBUG_FRIENDS, "OVERRIDE_BATTLEBUDDY() - Warning, hPed has gone out of sync with selector - ", GetLabel_enumCharacterList(eChar))
SCRIPT_ASSERT("OVERRIDE_BATTLEBUDDY() - Warning, hPed has gone out of sync with selector")
RETURN FALSE
ENDIF
// Specific tests
IF NOT IS_BIT_SET(g_bitfieldBattleBuddyOverridden, ENUM_TO_INT(eChar))
CPRINTLN(DEBUG_FRIENDS, "OVERRIDE_BATTLEBUDDY() - Trying to release battle buddy that is not overridden - ", GetLabel_enumCharacterList(eChar))
SCRIPT_ASSERT("OVERRIDE_BATTLEBUDDY() - Trying to release battle buddy that is not overridden")
RETURN FALSE
ENDIF
// Release battle buddy
CPRINTLN(DEBUG_FRIENDS, "RELEASE_BATTLEBUDDY() - ", GetLabel_enumCharacterList(eChar))
CLEAR_BIT(g_bitfieldBattleBuddyOverridden, ENUM_TO_INT(eChar))
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
//-------------------------------------------------------------------------------------------------------------------------------------------
// BEHAVIOUR FLAG INTERFACE
//-------------------------------------------------------------------------------------------------------------------------------------------
FUNC BOOL IS_BATTLEBUDDY_BEHAVIOUR_REQUESTED(enumBattleBuddyBehaviourFlag eFlag)
RETURN IS_BIT_SET(g_bitfieldBattleBuddyBehaviour, ENUM_TO_INT(eFlag))
ENDFUNC
PROC SET_BATTLEBUDDY_BEHAVIOUR_REQUEST(enumBattleBuddyBehaviourFlag eFlag)
CPRINTLN(DEBUG_FRIENDS, "SET_BATTLEBUDDY_BEHAVIOUR_REQUEST(", GetLabel_enumBattleBuddyBehaviourFlag(eFlag), ")")
SET_BIT(g_bitfieldBattleBuddyBehaviour, ENUM_TO_INT(eFlag))
ENDPROC
PROC CLEAR_BATTLEBUDDY_BEHAVIOUR_REQUEST(enumBattleBuddyBehaviourFlag eFlag)
CPRINTLN(DEBUG_FRIENDS, "CLEAR_BATTLEBUDDY_BEHAVIOUR_REQUEST(", GetLabel_enumBattleBuddyBehaviourFlag(eFlag), ")")
CLEAR_BIT(g_bitfieldBattleBuddyBehaviour, ENUM_TO_INT(eFlag))
ENDPROC
PROC RESET_ALL_BATTLEBUDDY_BEHAVIOUR_REQUESTS()
CPRINTLN(DEBUG_FRIENDS, "RESET_ALL_BATTLEBUDDY_BEHAVIOUR_REQUESTS()")
g_bitfieldBattleBuddyBehaviour = 0
ENDPROC
/// PURPOSE:
/// The player can call battle buddies when he's near you're mission but before he's launched it,
/// So you won't be able to set behaviour flags for the buddies at that point, as your script isn't running yet.
///
/// Please add any flags here, that you want the buddies to have when being created for your mission, but before the mission is launched.
///
/// Feel free to call this function at the start of your own mission, rather than setting the flags there too. It will help to keep things consistent.
/// PARAMS:
/// eMission - Setup flags is eMission equals your mission
PROC INIT_BATTLEBUDDY_BEHAVIOUR_FOR_MISSION(SP_MISSIONS eMission)
#if USE_CLF_DLC
eMission = eMission
#endif
#if USE_NRM_DLC
eMission = eMission
#endif
#if not USE_CLF_DLC
#if not USE_NRM_DLC
CPRINTLN(DEBUG_FRIENDS, "INIT_BATTLEBUDDY_BEHAVIOUR_FOR_MISSION(", GetLabel_SP_MISSIONS(eMission), ")")
g_bitfieldBattleBuddyBehaviour = 0
// Set flags required by each mission on start up
SWITCH eMission
CASE SP_HEIST_DOCKS_PREP_1
SET_BATTLEBUDDY_BEHAVIOUR_REQUEST(BBF_SpawnCheckDocks)
SET_BATTLEBUDDY_BEHAVIOUR_REQUEST(BBF_SwitchDefaultTrevor)
BREAK
CASE SP_HEIST_DOCKS_PREP_2B
SET_BATTLEBUDDY_BEHAVIOUR_REQUEST(BBF_SpawnOnSwitchedOffNodes)
SET_BATTLEBUDDY_BEHAVIOUR_REQUEST(BBF_SpawnCheckMilitaryBase)
SET_BATTLEBUDDY_BEHAVIOUR_REQUEST(BBF_CombatDelay)
BREAK
CASE SP_HEIST_RURAL_PREP_1
SET_BATTLEBUDDY_BEHAVIOUR_REQUEST(BBF_DriveHighSpeed)
SET_BATTLEBUDDY_BEHAVIOUR_REQUEST(BBF_DriveInConvoy)
SET_BATTLEBUDDY_BEHAVIOUR_REQUEST(BBF_DontFleeCopsWhenDriver)
SET_BATTLEBUDDY_BEHAVIOUR_REQUEST(BBF_CombatDefensive)
// SET_BATTLEBUDDY_BEHAVIOUR_REQUEST(BBF_CombatIgnorePlayerDist)
BREAK
CASE SP_HEIST_AGENCY_PREP_1
SET_BATTLEBUDDY_BEHAVIOUR_REQUEST(BBF_ForceFrontPassengerSeat)
BREAK
CASE SP_HEIST_FINALE_PREP_A
SET_BATTLEBUDDY_BEHAVIOUR_REQUEST(BBF_CloseGroupSpacing)
BREAK
CASE SP_HEIST_FINALE_PREP_B
SET_BATTLEBUDDY_BEHAVIOUR_REQUEST(BBF_ArriveOnSwitchOnNodesOnly)
BREAK
// CASE SP_MISSION_FBI_4_PREP_1
// SET_BATTLEBUDDY_BEHAVIOUR_REQUEST(BBF_DriveInConvoy)
// BREAK
DEFAULT
// Empty
BREAK
ENDSWITCH
#endif
#endif
ENDPROC