//- commands headers -// USING "rage_builtins.sch" USING "globals.sch" //- script headers -// USING "commands_script.sch" //- public headers -// USING "player_ped_public.sch" USING "timer_public.sch" USING "dialogue_public.sch" USING "blip_control_public.sch" USING "flow_public_core_override.sch" USING "stats_enums.sch" USING "organiser_public.sch" USING "selector_public.sch" USING "chase_hint_cam.sch" USING "friends_core.sch" //- private headers -// #IF IS_DEBUG_BUILD //- debug headers -// USING "script_debug.sch" USING "shared_debug.sch" #ENDIF ///private header for friends scripts /// sam.hackett@rockstarleeds.com /// FUNC BOOL PRIVATE_IS_POINT_IN_CITY(VECTOR v) IF v.y < 400.0 IF v.x < 1400.0 IF v.x > -1900.0 IF v.y > -3500.0 RETURN TRUE ENDIF ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC // ******************************************************************************************* // LAST CONTACT TIMER - private // ******************************************************************************************* /// PURPOSE: /// Gets the time since last contact between two friends (in seconds) /// PARAMS: /// playerCharID - FriendA /// friendCharID - FriendB /// RETURNS: /// The time since last contact / in seconds FUNC FLOAT Private_GET_FRIEND_LAST_CONTACT_TIME(enumCharacterList playerCharID, enumCharacterList friendCharID) enumFriend playerID = GET_FRIEND_FROM_CHAR(playerCharID) enumFriend friendID = GET_FRIEND_FROM_CHAR(friendCharID) enumFriendConnection friendConnID = GET_CONNECTION_FROM_FRIENDS(playerID, friendID) IF friendConnID < MAX_FRIEND_CONNECTIONS IF IS_TIMER_STARTED(g_SavedGlobals.sFriendsData.g_FriendConnectData[friendConnID].lastContactTimer) RETURN GET_TIMER_IN_SECONDS(g_SavedGlobals.sFriendsData.g_FriendConnectData[friendConnID].lastContactTimer) ENDIF ELSE SCRIPT_ASSERT("Private_GET_FRIEND_LAST_CONTACT_TIME() - Invalid friendConnID") ENDIF RETURN 0.0 ENDFUNC /// PURPOSE: /// Gets the most recent type of contact between two friends /// PARAMS: /// playerCharID - FriendA /// friendCharID - FriendB /// RETURNS: /// The type of contact / phone or face FUNC enumFriendContactType Private_GET_FRIEND_LAST_CONTACT_TYPE(enumCharacterList playerCharID, enumCharacterList friendCharID) enumFriend playerID = GET_FRIEND_FROM_CHAR(playerCharID) enumFriend friendID = GET_FRIEND_FROM_CHAR(friendCharID) enumFriendConnection friendConnID = GET_CONNECTION_FROM_FRIENDS(playerID, friendID) IF friendConnID < MAX_FRIEND_CONNECTIONS RETURN g_SavedGlobals.sFriendsData.g_FriendConnectData[friendConnID].lastContactType ELSE SCRIPT_ASSERT("Private_GET_FRIEND_LAST_CONTACT_TYPE() - Invalid friendConnID") ENDIF RETURN FRIEND_CONTACT_FACE ENDFUNC /// PURPOSE: /// Adds the given time to the timer - for use by debug menus /// PARAMS: /// playerCharID - FriendA /// friendCharID - FriendB /// Delay_Time - The time to add PROC Private_ALTER_FRIEND_LAST_CONTACT_TIME(enumCharacterList playerCharID, enumCharacterList friendCharID, FLOAT Delay_Time) CPRINTLN(DEBUG_FRIENDS, "Private_ALTER_FRIEND_LAST_CONTACT_TIME(FR_", GetLabel_enumFriend(GLOBAL_CHARACTER_SHEET_GET_FRIEND(friendCharID)), ", ", Delay_Time, ")") enumFriend playerID = GET_FRIEND_FROM_CHAR(playerCharID) enumFriend friendID = GET_FRIEND_FROM_CHAR(friendCharID) enumFriendConnection friendConnID = GET_CONNECTION_FROM_FRIENDS(playerID, friendID) IF friendConnID < MAX_FRIEND_CONNECTIONS FLOAT Start_Time = 0.0 IF IS_TIMER_STARTED(g_SavedGlobals.sFriendsData.g_FriendConnectData[friendConnID].lastContactTimer) Start_Time = GET_TIMER_IN_SECONDS(g_SavedGlobals.sFriendsData.g_FriendConnectData[friendConnID].lastContactTimer) ENDIF RESTART_timer_AT(g_SavedGlobals.sFriendsData.g_FriendConnectData[friendConnID].lastContactTimer, Start_Time + Delay_Time) ELSE SCRIPT_ASSERT("Private_ALTER_FRIEND_LAST_CONTACT_TIME() - Invalid friendConnID") ENDIF ENDPROC /// PURPOSE: /// Adds the given time to the timer - for use by debug menus /// PARAMS: /// playerCharID - FriendA /// friendCharID - FriendB /// Delay_Time - The time to add PROC Private_ALTER_FRIEND_LAST_CONTACT_TYPE(enumCharacterList playerCharID, enumCharacterList friendCharID, enumFriendContactType type) CPRINTLN(DEBUG_FRIENDS, "Private_ALTER_FRIEND_LAST_CONTACT_TYPE(FR_", GetLabel_enumFriend(GLOBAL_CHARACTER_SHEET_GET_FRIEND(friendCharID)), ", ", type, ")") enumFriend playerID = GET_FRIEND_FROM_CHAR(playerCharID) enumFriend friendID = GET_FRIEND_FROM_CHAR(friendCharID) enumFriendConnection friendConnID = GET_CONNECTION_FROM_FRIENDS(playerID, friendID) IF friendConnID < MAX_FRIEND_CONNECTIONS g_SavedGlobals.sFriendsData.g_FriendConnectData[friendConnID].lastContactType = type ELSE SCRIPT_ASSERT("Private_ALTER_FRIEND_LAST_CONTACT_TYPE() - Invalid friendConnID") ENDIF ENDPROC //--------------------------------------------------------------------------------------------------- //-- Friend ped setters //--------------------------------------------------------------------------------------------------- PROC PRIVATE_SET_FRIEND_A_PED_ID(PED_INDEX activityFriendID) g_pActivityFriendA = activityFriendID ENDPROC PROC PRIVATE_SET_FRIEND_B_PED_ID(PED_INDEX activityFriendID) g_pActivityFriendB = activityFriendID ENDPROC //--------------------------------------------------------------------------------------------------- //-- Direct connection manipulation functions //--------------------------------------------------------------------------------------------------- FUNC BOOL GET_CONNECTION(enumCharacterList ePlayerChar, enumCharacterList eFriendChar, enumFriendConnection& eConn) // Are chars valid as friends? enumFriend ePlayerID = GET_FRIEND_FROM_CHAR(ePlayerChar) enumFriend eFriendID = GET_FRIEND_FROM_CHAR(eFriendChar) IF ePlayerID <> NO_FRIEND AND eFriendID <> NO_FRIEND // Check desired connection is ContactWait eConn = GET_CONNECTION_FROM_FRIENDS(ePlayerID, eFriendID) IF eConn <> NO_FRIEND_CONNECTION RETURN TRUE ENDIF ENDIF eConn = NO_FRIEND_CONNECTION RETURN FALSE ENDFUNC FUNC enumFriendConnectionState GET_CONNECTION_STATE(enumFriendConnection eConn) IF eConn < MAX_FRIEND_CONNECTIONS RETURN g_FriendConnectState[eConn].state ELSE SCRIPT_ASSERT("GET_CONNECTION_STATE() - Invalid friend connection ID") RETURN FC_STATE_Invalid ENDIF ENDFUNC PROC SET_CONNECTION_STATE(enumFriendConnection eConn, enumFriendConnectionState state) IF eConn < MAX_FRIEND_CONNECTIONS #IF IS_DEBUG_BUILD TEXT_LABEL_63 tConn = GetLabel_enumFriendConnection(eConn) TEXT_LABEL_63 tState = GetLabel_enumFriendConnectionState(state) CPRINTLN(DEBUG_FRIENDS, "SET_CONNECTION_STATE(", tConn, ", ", tState, ")") #ENDIF g_FriendConnectState[eConn].state = state IF state = FC_STATE_ContactWait g_FriendConnectState[eConn].mode = FC_MODE_Friend #IF IS_DEBUG_BUILD CDEBUG1LN(DEBUG_FRIENDS, "(Auto setting ", tConn, " init mode to FC_MODE_Friend)") #ENDIF ENDIF ELSE SCRIPT_ASSERT("SET_CONNECTION_STATE() - Invalid friend connection ID") ENDIF ENDPROC FUNC enumFriendConnectionMode GET_CONNECTION_MODE(enumFriendConnection eConn) IF eConn < MAX_FRIEND_CONNECTIONS RETURN g_FriendConnectState[eConn].mode ELSE SCRIPT_ASSERT("GET_CONNECTION_MODE() - Invalid friend connection ID") RETURN FC_MODE_Friend ENDIF ENDFUNC PROC SET_CONNECTION_MODE(enumFriendConnection eConn, enumFriendConnectionMode eMode) IF eConn < MAX_FRIEND_CONNECTIONS #IF IS_DEBUG_BUILD TEXT_LABEL_63 tConn = GetLabel_enumFriendConnection(eConn) TEXT_LABEL_63 tMode = GetLabel_enumFriendConnectionMode(eMode) CPRINTLN(DEBUG_FRIENDS, "SET_CONNECTION_MODE(", tConn, ", ", tMode, ")") #ENDIF g_FriendConnectState[eConn].mode = eMode ELSE SCRIPT_ASSERT("SET_CONNECTION_MODE() - Invalid friend connection ID") ENDIF ENDPROC PROC SET_CONNECTION_FLAG(enumFriendConnection eConnection, enumFriendConnectionFlag eFlag, BOOL bEnable) #IF IS_DEBUG_BUILD TEXT_LABEL_63 tConn = GetLabel_enumFriendConnection(eConnection) IF bEnable CPRINTLN(DEBUG_FRIENDS, "SET_CONNECTION_FLAG(", tConn, ", flag=", ENUM_TO_INT(eFlag), ", bEnable=TRUE") ELSE CPRINTLN(DEBUG_FRIENDS, "SET_CONNECTION_FLAG(", tConn, ", flag=", ENUM_TO_INT(eFlag), ", bEnable=FALSE") ENDIF #ENDIF IF eConnection < MAX_FRIEND_CONNECTIONS IF bEnable SET_BIT(g_SavedGlobals.sFriendsData.g_FriendConnectData[eConnection].flags, ENUM_TO_INT(eFlag)) ELSE CLEAR_BIT(g_SavedGlobals.sFriendsData.g_FriendConnectData[eConnection].flags, ENUM_TO_INT(eFlag)) ENDIF ELSE SCRIPT_ASSERT("SET_CONNECTION_FLAG() - Invalid friend connection ID") ENDIF ENDPROC FUNC BOOL IS_CONNECTION_FLAG_SET(enumFriendConnection eConnection, enumFriendConnectionFlag eFlag) IF eConnection < MAX_FRIEND_CONNECTIONS RETURN IS_BIT_SET(g_SavedGlobals.sFriendsData.g_FriendConnectData[eConnection].flags, ENUM_TO_INT(eFlag)) ELSE #IF IS_DEBUG_BUILD TEXT_LABEL_63 tConn = GetLabel_enumFriendConnection(eConnection) CPRINTLN(DEBUG_FRIENDS, "IS_CONNECTION_FLAG_SET(", tConn, ", flag=", ENUM_TO_INT(eFlag), ") - Invalid friend connection") #ENDIF SCRIPT_ASSERT("SET_CONNECTION_FLAG() - Invalid friend connection ID") ENDIF RETURN FALSE ENDFUNC FUNC BOOL ARE_ANY_CONNECTIONS_PENDING_OR_PHONE() enumFriendConnection eConn REPEAT MAX_FRIEND_CONNECTIONS eConn IF g_FriendConnectState[eConn].state = FC_STATE_PhoneAccept OR g_FriendConnectState[eConn].state = FC_STATE_PhoneDecline OR g_FriendConnectState[eConn].state = FC_STATE_Init RETURN TRUE ENDIF ENDREPEAT RETURN FALSE ENDFUNC FUNC BOOL ARE_ANY_FRIEND_CONNECTIONS_PENDING_OR_ACTIVE() enumFriendConnection eConn REPEAT MAX_FRIEND_CONNECTIONS eConn IF g_FriendConnectState[eConn].state = FC_STATE_Init OR g_FriendConnectState[eConn].state = FC_STATE_Active IF g_FriendConnectState[eConn].mode = FC_MODE_Friend RETURN TRUE ENDIF ENDIF ENDREPEAT RETURN FALSE ENDFUNC FUNC BOOL ARE_ANY_SQUAD_CONNECTIONS_PENDING_OR_ACTIVE(BOOL bIncludePhone = FALSE, BOOL bIncludeReplay = FALSE) enumFriendConnection eConn REPEAT MAX_FRIEND_CONNECTIONS eConn enumFriendConnectionMode eMode = g_FriendConnectState[eConn].mode IF eMode = FC_MODE_Squad OR (bIncludeReplay AND eMode = FC_MODE_ReplayGroup) enumFriendConnectionState eState = g_FriendConnectState[eConn].state IF eState = FC_STATE_Init OR eState = FC_STATE_Active RETURN TRUE ENDIF IF bIncludePhone IF eState = FC_STATE_PhoneAccept RETURN TRUE ENDIF ENDIF ENDIF ENDREPEAT RETURN FALSE ENDFUNC FUNC INT GET_PENDING_CONNECTIONS(enumFriendConnection& eFirstMatchingConnection) INT iCount = 0 eFirstMatchingConnection = NO_FRIEND_CONNECTION enumFriendConnection eConn REPEAT MAX_FRIEND_CONNECTIONS eConn IF g_FriendConnectState[eConn].state = FC_STATE_Init IF eFirstMatchingConnection = NO_FRIEND_CONNECTION eFirstMatchingConnection = eConn ENDIF iCount++ ENDIF ENDREPEAT RETURN iCount ENDFUNC FUNC INT GET_ACTIVE_CONNECTIONS(enumFriendConnection& eFirstMatchingConnection) INT iCount = 0 eFirstMatchingConnection = NO_FRIEND_CONNECTION enumFriendConnection eConn REPEAT MAX_FRIEND_CONNECTIONS eConn IF g_FriendConnectState[eConn].state = FC_STATE_Active IF eFirstMatchingConnection = NO_FRIEND_CONNECTION eFirstMatchingConnection = eConn ENDIF iCount++ ENDIF ENDREPEAT RETURN iCount ENDFUNC FUNC INT GET_PENDING_OR_ACTIVE_CONNECTIONS(enumFriendConnection& eFirstMatchingConnection) INT iCount = 0 eFirstMatchingConnection = NO_FRIEND_CONNECTION enumFriendConnection eConn REPEAT MAX_FRIEND_CONNECTIONS eConn IF g_FriendConnectState[eConn].state = FC_STATE_Init OR g_FriendConnectState[eConn].state = FC_STATE_Active IF eFirstMatchingConnection = NO_FRIEND_CONNECTION eFirstMatchingConnection = eConn ENDIF iCount++ ENDIF ENDREPEAT RETURN iCount ENDFUNC FUNC BOOL GET_COMMON_CONNECTION(enumFriendConnection eConnA, enumFriendConnection eConnB, enumFriendConnection& eCommonConn) enumFriend eFriend1 = NO_FRIEND enumFriend eFriend2 = NO_FRIEND IF g_SavedGlobals.sFriendsData.g_FriendConnectData[eConnA].friendA = g_SavedGlobals.sFriendsData.g_FriendConnectData[eConnB].friendA eFriend1 = g_SavedGlobals.sFriendsData.g_FriendConnectData[eConnA].friendB eFriend2 = g_SavedGlobals.sFriendsData.g_FriendConnectData[eConnB].friendB ELIF g_SavedGlobals.sFriendsData.g_FriendConnectData[eConnA].friendB = g_SavedGlobals.sFriendsData.g_FriendConnectData[eConnB].friendB eFriend1 = g_SavedGlobals.sFriendsData.g_FriendConnectData[eConnA].friendA eFriend2 = g_SavedGlobals.sFriendsData.g_FriendConnectData[eConnB].friendA ELIF g_SavedGlobals.sFriendsData.g_FriendConnectData[eConnA].friendA = g_SavedGlobals.sFriendsData.g_FriendConnectData[eConnB].friendB eFriend1 = g_SavedGlobals.sFriendsData.g_FriendConnectData[eConnA].friendB eFriend2 = g_SavedGlobals.sFriendsData.g_FriendConnectData[eConnB].friendA ELIF g_SavedGlobals.sFriendsData.g_FriendConnectData[eConnA].friendB = g_SavedGlobals.sFriendsData.g_FriendConnectData[eConnB].friendA eFriend1 = g_SavedGlobals.sFriendsData.g_FriendConnectData[eConnA].friendA eFriend2 = g_SavedGlobals.sFriendsData.g_FriendConnectData[eConnB].friendB ENDIF IF IS_PLAYER_PED_PLAYABLE(GET_CHAR_FROM_FRIEND(eFriend1)) OR IS_PLAYER_PED_PLAYABLE(GET_CHAR_FROM_FRIEND(eFriend2)) eCommonConn = GET_CONNECTION_FROM_FRIENDS(eFriend1, eFriend2) IF eCommonConn <> NO_FRIEND_CONNECTION RETURN TRUE ENDIF ENDIF eCommonConn = NO_FRIEND_CONNECTION RETURN FALSE ENDFUNC FUNC BOOL DOES_CONNECTION_INVOLVE_CHAR(enumFriendConnection eConnection, enumCharacterList eChar) enumFriend eFriend = GET_FRIEND_FROM_CHAR(eChar) IF eFriend < MAX_FRIENDS IF g_SavedGlobals.sFriendsData.g_FriendConnectData[eConnection].friendA = eFriend OR g_SavedGlobals.sFriendsData.g_FriendConnectData[eConnection].friendB = eFriend RETURN TRUE ENDIF ENDIF RETURN FALSE ENDFUNC FUNC BOOL GET_PENDING_CONNECTION_CHAR(enumFriendConnection eConnection, enumCharacterList& eFriendChar) // Get friend char from pending connection enumFriend eFriendID IF GET_OTHER_FRIEND_FROM_CONNECTION(eConnection, eFriendID) eFriendChar = GET_CHAR_FROM_FRIEND(eFriendID) IF eFriendChar <> NO_CHARACTER RETURN TRUE ENDIF ENDIF eFriendChar = NO_CHARACTER RETURN FALSE ENDFUNC // ******************************************************************************************* FUNC BOOL IS_FRIEND_ACTIVITY_SCRIPT_RUNNING() RETURN IS_THREAD_ACTIVE(INT_TO_NATIVE(THREADID, g_SavedGlobals.sFriendsData.g_FriendScriptThread)) ENDFUNC FUNC BOOL ACTIVATE_CONNECTION(enumFriendConnection eConnection, enumFriendConnectionMode eMode) // Should this do something to delay the creation, if the another friend is still pending? enumFriendConnection eActiveConnection enumFriendConnection eCommonConnection INT iActiveFriends = GET_ACTIVE_CONNECTIONS(eActiveConnection) IF iActiveFriends = 0 SET_CONNECTION_STATE(eConnection, FC_STATE_Active) SET_CONNECTION_MODE(eConnection, eMode) RETURN TRUE ELIF iActiveFriends = 1 IF GET_COMMON_CONNECTION(eConnection, eActiveConnection, eCommonConnection) AND GET_CONNECTION_STATE(eCommonConnection) <> FC_STATE_Invalid SET_CONNECTION_STATE(eConnection, FC_STATE_Active) SET_CONNECTION_STATE(eCommonConnection, FC_STATE_Active) SET_CONNECTION_MODE(eConnection, eMode) SET_CONNECTION_MODE(eCommonConnection, eMode) RETURN TRUE ENDIF ENDIF //ELIF iActiveFriends > 1 RETURN FALSE ENDFUNC FUNC BOOL DEACTIVATE_CHAR_CONNECTIONS(enumCharacterList eChar) // Reset active connections involving given char enumFriendConnection eConnection enumCharacterList eConnCharA enumCharacterList eConnCharB BOOL bDeactivated = FALSE REPEAT MAX_FRIEND_CONNECTIONS eConnection GET_FRIEND_CHARS_FROM_CONNECTION(eConnection, eConnCharA, eConnCharB) IF eConnCharA = eChar OR eConnCharB = eChar enumFriendConnectionState eState = GET_CONNECTION_STATE(eConnection) IF eState = FC_STATE_Init OR eState = FC_STATE_Active SET_CONNECTION_STATE(eConnection, FC_STATE_ContactWait) bDeactivated = TRUE ENDIF ENDIF ENDREPEAT RETURN bDeactivated ENDFUNC FUNC BOOL DEACTIVATE_ALL_CONNECTIONS() BOOL bDeactivated = FALSE // Reset any friend connections enumFriendConnection eConnection REPEAT MAX_FRIEND_CONNECTIONS eConnection enumFriendConnectionState eState = GET_CONNECTION_STATE(eConnection) IF eState = FC_STATE_Init OR eState = FC_STATE_Active SET_CONNECTION_STATE(eConnection, FC_STATE_ContactWait) bDeactivated = TRUE ENDIF ENDREPEAT RETURN bDeactivated ENDFUNC // ******************************************************************************************* #IF IS_DEBUG_BUILD PROC DEBUG_PRINT_ALL_CONNECTIONS() CPRINTLN(DEBUG_FRIENDS, "DEBUG_PRINT_ALL_CONNECTIONS()...") // Reset any friend connections enumFriendConnection eConnection REPEAT MAX_FRIEND_CONNECTIONS eConnection TEXT_LABEL_63 tConn = GetLabel_enumFriendConnection(eConnection) TEXT_LABEL_63 tState = GetLabel_enumFriendConnectionState(GET_CONNECTION_STATE(eConnection)) TEXT_LABEL_63 tMode = GetLabel_enumFriendConnectionMode(GET_CONNECTION_MODE(eConnection)) CPRINTLN(DEBUG_FRIENDS, " ", tConn, " ", tState, " (", tMode, ")") ENDREPEAT ENDPROC #ENDIF // ******************************************************************************************* //PROC INC_FRIEND_CALL_STAT(enumCharacterList ePlayerChar, enumCharacterList eFriendChar) // // #IF IS_DEBUG_BUILD // TEXT_LABEL_63 tPlayerChar = GetLabel_enumCharacterList(ePlayerChar) // TEXT_LABEL_63 tFriendChar = GetLabel_enumCharacterList(eFriendChar) // CPRINTLN(DEBUG_FRIENDS, "INC_FRIEND_CALL_STAT(", tPlayerChar, ", ", tFriendChar, ")") // #ENDIF // // STATSENUM eStat // // IF ePlayerChar = CHAR_MICHAEL // IF eFriendChar = CHAR_FRANKLIN eStat = TIMES_M_INIT_F_FRIEND // ELIF eFriendChar = CHAR_TREVOR eStat = TIMES_M_INIT_T_FRIEND // ELIF eFriendChar = CHAR_JIMMY eStat = TIMES_M_INIT_J_FRIEND // ELIF eFriendChar = CHAR_AMANDA eStat = TIMES_M_INIT_A_FRIEND // ELSE // SCRIPT_ASSERT("INC_FRIEND_CALL_STAT() - eFriendChar has no connection with the given player char") // EXIT // ENDIF // // ELIF ePlayerChar = CHAR_FRANKLIN // IF eFriendChar = CHAR_MICHAEL eStat = TIMES_F_INIT_M_FRIEND // ELIF eFriendChar = CHAR_TREVOR eStat = TIMES_F_INIT_T_FRIEND // ELIF eFriendChar = CHAR_LAMAR eStat = TIMES_F_INIT_L_FRIEND // ELIF eFriendChar = CHAR_JIMMY eStat = TIMES_F_INIT_J_FRIEND // ELSE // SCRIPT_ASSERT("INC_FRIEND_CALL_STAT() - eFriendChar has no connection with the given player char") // EXIT // ENDIF // // ELIF ePlayerChar = CHAR_TREVOR // IF eFriendChar = CHAR_MICHAEL eStat = TIMES_T_INIT_M_FRIEND // ELIF eFriendChar = CHAR_FRANKLIN eStat = TIMES_T_INIT_F_FRIEND // ELIF eFriendChar = CHAR_LAMAR eStat = TIMES_T_INIT_L_FRIEND // ELIF eFriendChar = CHAR_JIMMY eStat = TIMES_T_INIT_J_FRIEND // ELSE // SCRIPT_ASSERT("INC_FRIEND_CALL_STAT() - eFriendChar has no connection with the given player char") // EXIT // ENDIF // // ELSE // SCRIPT_ASSERT("INC_FRIEND_CALL_STAT() - ePlayerChar is not a valid player character") // EXIT // ENDIF // // STAT_INCREMENT(eStat, 1) // // #IF IS_DEBUG_BUILD // INT iCount = 0 // STAT_GET_INT(eStat, iCount) // CPRINTLN(DEBUG_FRIENDS, "INC_FRIEND_CALL_STAT() New value = ", iCount) // #ENDIF // //ENDPROC //PROC INC_BBUDDY_CALL_STAT(enumCharacterList ePlayerChar, enumCharacterList eFriendChar) // BBUDDIES REMOVED // // #IF IS_DEBUG_BUILD // TEXT_LABEL_63 tPlayerChar = GetLabel_enumCharacterList(ePlayerChar) // TEXT_LABEL_63 tFriendChar = GetLabel_enumCharacterList(eFriendChar) // CPRINTLN(DEBUG_FRIENDS, "INC_BBUDDY_CALL_STAT(", tPlayerChar, ", ", tFriendChar, ")") // #ENDIF // // STATSENUM eStat // // IF ePlayerChar = CHAR_MICHAEL // IF eFriendChar = CHAR_FRANKLIN eStat = TIMES_M_INIT_F_BBUDDY // ELIF eFriendChar = CHAR_TREVOR eStat = TIMES_M_INIT_T_BBUDDY // ELSE // SCRIPT_ASSERT("INC_BBUDDY_CALL_STAT() - eFriendChar has no connection with the given player char") // EXIT // ENDIF // // ELIF ePlayerChar = CHAR_FRANKLIN // IF eFriendChar = CHAR_MICHAEL eStat = TIMES_F_INIT_M_BBUDDY // ELIF eFriendChar = CHAR_TREVOR eStat = TIMES_F_INIT_T_BBUDDY // ELSE // SCRIPT_ASSERT("INC_BBUDDY_CALL_STAT() - eFriendChar has no connection with the given player char") // EXIT // ENDIF // // ELIF ePlayerChar = CHAR_TREVOR // IF eFriendChar = CHAR_MICHAEL eStat = TIMES_T_INIT_M_BBUDDY // ELIF eFriendChar = CHAR_FRANKLIN eStat = TIMES_T_INIT_F_BBUDDY // ELSE // SCRIPT_ASSERT("INC_BBUDDY_CALL_STAT() - eFriendChar has no connection with the given player char") // EXIT // ENDIF // // ELSE // SCRIPT_ASSERT("INC_BBUDDY_CALL_STAT() - ePlayerChar is not a valid player character") // EXIT // ENDIF // // STAT_INCREMENT(eStat, 1) // // #IF IS_DEBUG_BUILD // INT iCount = 0 // STAT_GET_INT(eStat, iCount) // CPRINTLN(DEBUG_FRIENDS, "INC_BBUDDY_CALL_STAT() New value = ", iCount) // #ENDIF // //ENDPROC //------------------------------------------------------------------------------------------------------------------------------ // Delete queue //------------------------------------------------------------------------------------------------------------------------------ PROC Private_AddPedToDeleteQueue(PED_INDEX hPed) INT iQueueSpot = -1, iQueue REPEAT COUNT_OF(g_ambientSelectorPedDeleteQueue) iQueue IF (iQueueSpot < 0) IF NOT DOES_ENTITY_EXIST(g_ambientSelectorPedDeleteQueue[iQueue]) iQueueSpot = iQueue ENDIF ENDIF ENDREPEAT IF (iQueueSpot < 0) OR (iQueueSpot > COUNT_OF(g_ambientSelectorPedDeleteQueue)) SCRIPT_ASSERT("invalid iQueueSpot???") iQueueSpot = 0 ENDIF g_ambientSelectorPedDeleteQueue[iQueueSpot] = hPed ENDPROC FUNC BOOL Private_IsPedInDeleteQueue(PED_INDEX hPed) INT iQueue REPEAT COUNT_OF(g_ambientSelectorPedDeleteQueue) iQueue IF g_ambientSelectorPedDeleteQueue[iQueue] = hPed RETURN TRUE ENDIF ENDREPEAT RETURN FALSE ENDFUNC PROC SET_PED_AS_AMBIENT_FRIEND(PED_INDEX hPed, enumCharacterList eChar, enumAmbGrabMode eMode) // TODO: What if ped is the player? CPRINTLN(DEBUG_FRIENDS, "SET_PED_AS_AMBIENT_FRIEND(", GetLabel_enumCharacterList(eChar), ")") IF IS_PED_INJURED(hPed) CPRINTLN(DEBUG_FRIENDS, "SET_PED_AS_AMBIENT_FRIEND() - ped is injured, set as no longer needed") SET_PED_AS_NO_LONGER_NEEDED(hPed) // Private_AddPedToDeleteQueue(hPed) ELIF NOT IS_PLAYER_PED_PLAYABLE(eChar) CPRINTLN(DEBUG_FRIENDS, "SET_PED_AS_AMBIENT_FRIEND() - ped is NPC, set as no longer needed") SET_PED_AS_NO_LONGER_NEEDED(hPed) // Private_AddPedToDeleteQueue(hPed) ELIF g_bInMultiplayer CPRINTLN(DEBUG_FRIENDS, "SET_PED_AS_AMBIENT_FRIEND() - multiplayer is active, adding to global delete queue") SET_PED_AS_NO_LONGER_NEEDED(hPed) // Private_AddPedToDeleteQueue(hPed) ELIF GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH(HASH("friends_controller")) = 0 CPRINTLN(DEBUG_FRIENDS, "SET_PED_AS_AMBIENT_FRIEND() - friends controller isn't running, adding to global delete queue") SET_PED_AS_NO_LONGER_NEEDED(hPed) // Private_AddPedToDeleteQueue(hPed) ELIF IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_STORY_PREP) CPRINTLN(DEBUG_FRIENDS, "SET_PED_AS_AMBIENT_FRIEND() - friends controller is running but prep mission is active, adding to global delete queue") SET_PED_AS_NO_LONGER_NEEDED(hPed) // Private_AddPedToDeleteQueue(hPed) ELIF (g_OnMissionState = MISSION_TYPE_FRIEND_ACTIVITY OR g_OnMissionState = MISSION_TYPE_FRIEND_ACTIVITY_WITH_MG) AND g_eCurrentActivityLoc < MAX_ACTIVITY_LOCATIONS CPRINTLN(DEBUG_FRIENDS, "SET_PED_AS_AMBIENT_FRIEND() - friends controller is running but fr. activity has started, adding to global delete queue") SET_PED_AS_NO_LONGER_NEEDED(hPed) // Private_AddPedToDeleteQueue(hPed) ELSE IF NOT IS_PED_INJURED(g_pDismissPeds[eChar]) CPRINTLN(DEBUG_FRIENDS, "SET_PED_AS_AMBIENT_FRIEND() - already a ped in list, set old ped as no longer needed") SET_PED_AS_NO_LONGER_NEEDED(hPed) // Private_AddPedToDeleteQueue(hPed) ENDIF CPRINTLN(DEBUG_FRIENDS, "SET_PED_AS_AMBIENT_FRIEND() - successfully added ", GetLabel_enumCharacterList(eChar), " to ambfriend queue") g_pDismissPeds[eChar] = hPed g_pDismissMode[eChar] = eMode ENDIF ENDPROC PROC SET_PED_AS_AMBIENT_FRIEND_WANDER(PED_INDEX hPed, enumCharacterList eChar) CPRINTLN(DEBUG_FRIENDS, "SET_PED_AS_AMBIENT_FRIEND_WANDER(", GetLabel_enumCharacterList(eChar), ")") // Set tasks IF NOT IS_PED_INJURED(hPed) IF IS_PED_GROUP_MEMBER(hPed, PLAYER_GROUP_ID()) REMOVE_PED_FROM_GROUP(hPed) ENDIF SET_PED_KEEP_TASK(hPed, TRUE) SCRIPTTASKSTATUS eStatus = GET_SCRIPT_TASK_STATUS(hPed, SCRIPT_TASK_WANDER_STANDARD) IF eStatus <> PERFORMING_TASK AND eStatus <> WAITING_TO_START_TASK CLEAR_PED_TASKS(hPed) TASK_WANDER_STANDARD(hPed) ENDIF ENDIF // Release to system SET_PED_AS_AMBIENT_FRIEND(hPed, eChar, AMBGRAB_TRANSFER_WANDER) ENDPROC PROC SET_PED_AS_AMBIENT_FRIEND_FLEE(PED_INDEX hPed, enumCharacterList eChar) CPRINTLN(DEBUG_FRIENDS, "SET_PED_AS_AMBIENT_FRIEND_FLEE(", GetLabel_enumCharacterList(eChar), ")") // Set tasks IF NOT IS_PED_INJURED(hPed) IF IS_PED_GROUP_MEMBER(hPed, PLAYER_GROUP_ID()) REMOVE_PED_FROM_GROUP(hPed) ENDIF SET_PED_KEEP_TASK(hPed, TRUE) SCRIPTTASKSTATUS eStatus = GET_SCRIPT_TASK_STATUS(hPed, SCRIPT_TASK_SMART_FLEE_PED) IF eStatus <> PERFORMING_TASK AND eStatus <> WAITING_TO_START_TASK CLEAR_PED_TASKS(hPed) TASK_SMART_FLEE_PED(hPed, PLAYER_PED_ID(), 5000.0, -1, TRUE, FALSE) ENDIF ENDIF // Release to system SET_PED_AS_AMBIENT_FRIEND(hPed, eChar, AMBGRAB_TRANSFER_FLEE) ENDPROC //PROC SET_PED_AS_AMBIENT_FRIEND_FLEE(PED_INDEX hPed, enumCharacterList eChar) // // CPRINTLN(DEBUG_FRIENDS, "SET_PED_AS_AMBIENT_FRIEND_FLEE(", GetLabel_enumCharacterList(eChar), ")") // // // Set tasks // IF NOT IS_PED_INJURED(hPed) // IF IS_PED_GROUP_MEMBER(hPed, PLAYER_GROUP_ID()) // REMOVE_PED_FROM_GROUP(hPed) // ENDIF // SET_PED_KEEP_TASK(hPed, TRUE) // // // Player // IF IS_PLAYER_PED_PLAYABLE(eChar) // SCRIPTTASKSTATUS eStatus = GET_SCRIPT_TASK_STATUS(hPed, SCRIPT_TASK_SMART_FLEE_PED) // IF eStatus <> PERFORMING_TASK AND eStatus <> WAITING_TO_START_TASK // CLEAR_PED_TASKS(hPed) // TASK_SMART_FLEE_PED(hPed, PLAYER_PED_ID(), 5000.0, -1, TRUE, FALSE) // ENDIF // // // NPC // ELSE // CLEAR_PED_TASKS(hPed) // // // Get out of car and run away // SEQUENCE_INDEX seq // OPEN_SEQUENCE_TASK(seq) // IF IS_PED_IN_ANY_VEHICLE(hPed, TRUE) // TASK_LEAVE_ANY_VEHICLE(null) // ENDIF // TASK_SMART_FLEE_PED(null, PLAYER_PED_ID(), 5000.0, -1, TRUE, FALSE) // TASK_WANDER_STANDARD(null) // CLOSE_SEQUENCE_TASK(seq) // TASK_PERFORM_SEQUENCE(hPed, seq) // CLEAR_SEQUENCE_TASK(seq) // ENDIF // // ENDIF // // // Release to system // SET_PED_AS_AMBIENT_FRIEND(hPed, eChar, AMBMODE_FLEE) // //ENDPROC PROC SET_PED_AS_AMBIENT_FRIEND_REJECTED(PED_INDEX hPed, enumCharacterList eChar, SP_MISSIONS eMission) CPRINTLN(DEBUG_FRIENDS, "SET_PED_AS_AMBIENT_FRIEND_REJECTED(", GetLabel_enumCharacterList(eChar), ")") // Set tasks IF NOT IS_PED_INJURED(hPed) IF IS_PED_GROUP_MEMBER(hPed, PLAYER_GROUP_ID()) REMOVE_PED_FROM_GROUP(hPed) ENDIF SET_PED_KEEP_TASK(hPed, TRUE) CLEAR_PED_TASKS(hPed) // Get mission position BOOL bHasDestPos = FALSE VECTOR vRejectionDest #if USE_CLF_DLC IF eMission <> SP_MISSION_NONE #ENDIF #if USE_NRM_DLC IF eMission <> SP_MISSION_NONE #ENDIF #if not USE_CLF_DLC #if not USE_NRM_DLC IF eMission = SP_MISSION_LESTER_1 vRejectionDest = <<1382.8588, -1706.0695, 62.8927>> // Hardcode the destination for leaving Lester's house bHasDestPos = TRUE ELIF eMission <> SP_MISSION_NONE #ENDIF #ENDIF STATIC_BLIP_NAME_ENUM eMissionBlip VECTOR vMissionPos eMissionBlip = g_sMissionStaticData[eMission].blip IF IS_STATIC_BLIP_MULTIMODE(eMissionBlip) vMissionPos = GET_STATIC_BLIP_POSITION(eMissionBlip, GET_CURRENT_PLAYER_PED_INT()) ELSE vMissionPos = GET_STATIC_BLIP_POSITION(eMissionBlip) ENDIF // Get rejection dest FLOAT fHeadingDummy INT iLanesDummy vRejectionDest = vMissionPos + (NORMALISE_VECTOR(GET_ENTITY_COORDS(hPed) - vMissionPos) * 50.0) IF GET_SAFE_VEHICLE_NODE(vRejectionDest, vRejectionDest, fHeadingDummy, iLanesDummy, 1, FALSE) bHasDestPos = TRUE ENDIF ENDIF // Walk away from the mission SEQUENCE_INDEX seq OPEN_SEQUENCE_TASK(seq) IF IS_PED_IN_ANY_VEHICLE(hPed, TRUE) TASK_LEAVE_ANY_VEHICLE(null) ENDIF TASK_LOOK_AT_ENTITY(null, PLAYER_PED_ID(), 2000, SLF_WHILE_NOT_IN_FOV|SLF_USE_TORSO) TASK_PAUSE(null, GET_RANDOM_INT_IN_RANGE(800, 1200)) IF bHasDestPos TASK_FOLLOW_NAV_MESH_TO_COORD(null, vRejectionDest, PEDMOVE_WALK, DEFAULT_TIME_NEVER_WARP, DEFAULT_NAVMESH_RADIUS, ENAV_GO_FAR_AS_POSSIBLE_IF_TARGET_NAVMESH_NOT_LOADED|ENAV_NO_STOPPING) ENDIF TASK_WANDER_STANDARD(null) CLOSE_SEQUENCE_TASK(seq) TASK_PERFORM_SEQUENCE(hPed, seq) CLEAR_SEQUENCE_TASK(seq) ENDIF // Release to system SET_PED_AS_AMBIENT_FRIEND(hPed, eChar, AMBGRAB_TRANSFER_REJECTED) ENDPROC