// ***************************************************************************************** // ***************************************************************************************** // // 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