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

3523 lines
146 KiB
XML
Executable File

//╒═════════════════════════════════════════════════════════════════════════════╕
//│ Communication Controller Private Header │
//╞═════════════════════════════════════════════════════════════════════════════╡
//│ │
//│ AUTHOR: Ben Rollinson │
//│ DATE: 13/10/10 │
//│ DESCRIPTION: The private back-end scripts for the communication │
//│ controller system. │
//│ │
//╘═════════════════════════════════════════════════════════════════════════════╛
USING "rage_builtins.sch"
USING "globals.sch"
USING "dialogue_public.sch"
USING "mission_control_public.sch"
USING "friends_core.sch"
USING "timer_public.sch"
USING "mission_stat_public.sch"
USING "email_public.sch"
USING "vector_id_public.sch"
#IF USE_CLF_DLC
USING "flow_custom_checks_CLF.sch"
#ENDIF
#IF USE_NRM_DLC
USING "flow_custom_checks_NRM.sch"
#ENDIF
#IF NOT USE_SP_DLC
USING "flow_custom_checks_GTA5.sch"
#ENDIF
USING "drunk_public.sch"
USING "comms_control_data_GTA5.sch"
USING "friends_core.sch"
USING "code_control_public.sch"
ENUM COMMS_PAIRS_COMPARISONS // Used when compairing to comms for priority etc.
CPC_LOWER = 0,
CPC_SAME = 1,
CPC_HIGHER = 2
ENDENUM
//╒═════════════════════════════════════════════════════════════════════════════╕
//╞════════════════════════════╡ Debug Functions ╞═════════════════════════════╡
//╘═════════════════════════════════════════════════════════════════════════════╛
#IF IS_DEBUG_BUILD
FUNC STRING PRIVATE_Get_Debug_String_For_Communication_Type(CC_CommunicationType eType)
SWITCH(eType)
CASE CT_END_OF_MISSION
RETURN "End Of Mission"
BREAK
CASE CT_FLOW
RETURN "Flow"
BREAK
CASE CT_FLOW_URGENT
RETURN "Flow (urgent)"
BREAK
CASE CT_FRIEND
RETURN "Friend"
BREAK
CASE CT_FRIEND_urgent
RETURN "Friend (urgent)"
BREAK
CASE CT_MINIGAME
RETURN "Minigame"
BREAK
CASE CT_AMBIENT
RETURN "Ambient"
BREAK
CASE CT_ON_MISSION
RETURN "On Mission"
BREAK
ENDSWITCH
SCRIPT_ASSERT("PRIVATE_Get_Debug_String_For_Communication_Priority: Tried to get a debug string for an invalid communication priority level.")
RETURN "INVALID PRIORITY LEVEL!"
ENDFUNC
FUNC STRING PRIVATE_Get_Debug_String_For_Communication_Priority(CC_CommunicationPriority ePriority)
SWITCH(ePriority)
CASE CPR_VERY_LOW
RETURN "VLOW"
BREAK
CASE CPR_LOW
RETURN "LOW"
BREAK
CASE CPR_MEDIUM_HIGH
RETURN "MHIGH"
BREAK
CASE CPR_MEDIUM
RETURN "MED"
BREAK
CASE CPR_HIGH
RETURN "HIGH"
BREAK
CASE CPR_VERY_HIGH
RETURN "VHIGH"
BREAK
ENDSWITCH
SCRIPT_ASSERT("PRIVATE_Get_Debug_String_For_Communication_Priority: Tried to get a debug string for an invalid communication priority level.")
RETURN "INVALID!"
ENDFUNC
FUNC STRING PRIVATE_Get_Debug_String_For_Communication_Status(CC_CommunicationStatus eStatus)
SWITCH(eStatus)
CASE CS_IN_PROGRESS
RETURN "In Progress"
BREAK
CASE CS_INACTIVE
RETURN "Inactive"
BREAK
CASE CS_WAITING_FOR_GLOBAL_DELAY
RETURN "Wait Global"
BREAK
CASE CS_WAITING_FOR_CHARACTER_DELAY
RETURN "Wait Char"
BREAK
CASE CS_WAITING_FOR_QUEUE_TIMER
RETURN "Wait Timer"
BREAK
CASE CS_WAITING_FOR_HIGHER_PRIORITY
RETURN "Wait Priority"
BREAK
ENDSWITCH
SCRIPT_ASSERT("PRIVATE_Get_Debug_String_For_Communication_Status: Tried to get a debug string for an invalid communication status.")
RETURN "INVALID STATUS!"
ENDFUNC
FUNC STRING PRIVATE_Get_Debug_String_For_Call_Missed_Response(CC_CallMissedResponse eCMR)
SWITCH(eCMR)
CASE CMR_REQUEUE
RETURN "Requeue"
BREAK
CASE CMR_SEND_TEXT
RETURN "Send Text"
BREAK
CASE CMR_REMOVE
RETURN "Remove"
BREAK
ENDSWITCH
SCRIPT_ASSERT("PRIVATE_Get_Debug_String_For_Communication_Status: Tried to get a debug string for an invalid call missed response.")
RETURN "INVALID CMR!"
ENDFUNC
#ENDIF
//╒═════════════════════════════════════════════════════════════════════════════╕
//╞═══════════════════════════╡ Utility Functions ╞════════════════════════════╡
//╘═════════════════════════════════════════════════════════════════════════════╛
FUNC CC_CommunicationPriority PRIVATE_Get_Priority_From_Communication_Type(CC_CommunicationType eCommType)
SWITCH eCommType
CASE CT_END_OF_MISSION
CASE CT_FRIEND_urgent
RETURN CPR_VERY_HIGH
BREAK
CASE CT_ON_MISSION
RETURN CPR_HIGH
BREAK
CASE CT_FLOW_URGENT
RETURN CPR_MEDIUM_HIGH
BREAK
CASE CT_FLOW
RETURN CPR_MEDIUM
BREAK
CASE CT_FRIEND
RETURN CPR_LOW
BREAK
CASE CT_MINIGAME
CASE CT_AMBIENT
RETURN CPR_VERY_LOW
BREAK
ENDSWITCH
SCRIPT_ASSERT("Get_Priority_From_Communication_Type: Communication type not recognised. Could not return a meaningful priority.")
RETURN CPR_ERROR
ENDFUNC
//╒═════════════════════════════════════════════════════════════════════════════╕
//╞═════════════════╡ PedsForConversation Struct Maintenance ╞═════════════════╡
//╘═════════════════════════════════════════════════════════════════════════════╛
FUNC STRING PRIVATE_Get_Voice_ID_For_Charsheet_Character(enumCharacterList eCharacter)
SWITCH eCharacter
CASE CHAR_ABIGAIL
RETURN "ABIGAIL"
BREAK
CASE CHAR_ANTONIA
RETURN "KIDNAPPEDFEMALE"
BREAK
CASE CHAR_AMANDA
RETURN "AMANDA"
BREAK
CASE CHAR_CHENG
RETURN "CHENG"
BREAK
CASE CHAR_CHENGSR
RETURN "CHENGSR"
BREAK
CASE CHAR_DAVE
RETURN "DAVE"
BREAK
CASE CHAR_DEVIN
RETURN "DEVIN"
BREAK
CASE CHAR_DR_FRIEDLANDER
RETURN "FRIEDLANDER"
BREAK
CASE CHAR_ESTATE_AGENT
RETURN "ESTATEAGENT"
BREAK
CASE CHAR_HAO
RETURN "HAO"
BREAK
CASE CHAR_HUNTER
RETURN "CLETUS"
BREAK
CASE CHAR_JIMMY
RETURN "JIMMY"
BREAK
CASE CHAR_JIMMY_BOSTON
RETURN "JIMMYBOSTON"
BREAK
CASE CHAR_LAMAR
RETURN "LAMAR"
BREAK
CASE CHAR_LESTER
RETURN "LESTER"
BREAK
CASE CHAR_MARTIN
RETURN "MARTIN"
BREAK
CASE CHAR_ONEIL
RETURN "ONEIL"
BREAK
CASE CHAR_OSCAR
RETURN "OSCAR"
BREAK
CASE CHAR_PATRICIA
RETURN "PATRICIA"
BREAK
CASE CHAR_RON
RETURN "NERVOUSRON"
BREAK
CASE CHAR_SIMEON
RETURN "SIMEON"
BREAK
CASE CHAR_SOLOMON
RETURN "SOLOMON"
BREAK
CASE CHAR_STEVE
RETURN "STEVE"
BREAK
CASE CHAR_STRETCH
RETURN "STRETCH"
BREAK
CASE CHAR_TANISHA
RETURN "TANISHA"
BREAK
CASE CHAR_TRACEY
RETURN "TRACEY"
BREAK
CASE CHAR_WADE
RETURN "WADE"
BREAK
//Booty call girls.
CASE CHAR_STRIPPER_JULIET
RETURN "JULIET"
BREAK
CASE CHAR_STRIPPER_NIKKI
RETURN "NIKKI"
BREAK
CASE CHAR_STRIPPER_CHASTITY
RETURN "CHASTITY"
BREAK
CASE CHAR_STRIPPER_CHEETAH
RETURN "CHEETAH"
BREAK
CASE CHAR_STRIPPER_SAPPHIRE
RETURN "SAPPHIRE"
BREAK
CASE CHAR_STRIPPER_INFERNUS
RETURN "INFERNUS"
BREAK
CASE CHAR_STRIPPER_FUFU
RETURN "FUFU"
BREAK
CASE CHAR_STRIPPER_PEACH
RETURN "PEACH"
BREAK
CASE CHAR_BROKEN_DOWN_GIRL
RETURN "BDOWNHOTCHICK"
BREAK
CASE CHAR_TAXI_LIZ
RETURN "TaxiLiz"
BREAK
CASE CHAR_HITCHER_GIRL
RETURN "REHH2Hiker"
BREAK
CASE CHAR_RICKIE
RETURN "LIEngineer"
BREAK
//Random characters
CASE CHAR_BEVERLY
RETURN "BEVERLY"
BREAK
CASE CHAR_CRIS
RETURN "CRIS"
BREAK
CASE CHAR_JOSH
RETURN "JOSH"
BREAK
CASE CHAR_MAUDE
RETURN "MAUDE"
BREAK
// Property
CASE CHAR_PROPERTY_TAXI_LOT
RETURN "TaxiDispatch"
BREAK
CASE CHAR_PROPERTY_GOLF_CLUB
RETURN "MANAGER"
BREAK
CASE CHAR_PROPERTY_CINEMA_MORNINGWOOD
RETURN "MANAGER"
BREAK
CASE CHAR_TOW_TONYA
RETURN "TONYA"
BREAK
DEFAULT
SCRIPT_ASSERT("PRIVATE_Get_Voice_ID_For_Charsheet_Character: Tried to get a voice ID for a character that has no voice ID set. Tell BenR!")
BREAK
ENDSWITCH
RETURN "ERROR"
ENDFUNC
//TODO - Grab current player data and set up this stuct properly.
PROC PRIVATE_Fill_Peds_For_Conversation_Struct(CC_CallData &sCallData)
IF IS_BIT_SET(sCallData.sCommData.iPlayerCharBitset, GET_CURRENT_PLAYER_PED_INT())
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_MICHAEL
ADD_PED_FOR_DIALOGUE(g_sPedsForConversation, 0, PLAYER_PED_ID(), "MICHAEL")
BREAK
CASE CHAR_FRANKLIN
ADD_PED_FOR_DIALOGUE(g_sPedsForConversation, 1, PLAYER_PED_ID(), "FRANKLIN")
BREAK
CASE CHAR_TREVOR
ADD_PED_FOR_DIALOGUE(g_sPedsForConversation, 2, PLAYER_PED_ID(), "TREVOR")
BREAK
ENDSWITCH
ELSE
SCRIPT_ASSERT("PRIVATE_Fill_Peds_For_Conversation_Struct: Tried to configure dialogue for a communication that the player is not involved in.")
ENDIF
SWITCH sCallData.sCommData.eNPCCharacter
CASE CHAR_MICHAEL
ADD_PED_FOR_DIALOGUE(g_sPedsForConversation, 0, NULL, "MICHAEL")
BREAK
CASE CHAR_FRANKLIN
ADD_PED_FOR_DIALOGUE(g_sPedsForConversation, 1, NULL, "FRANKLIN")
BREAK
CASE CHAR_TREVOR
ADD_PED_FOR_DIALOGUE(g_sPedsForConversation, 2, NULL, "TREVOR")
BREAK
CASE CHAR_ALL_PLAYERS_CONF
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_MICHAEL
ADD_PED_FOR_DIALOGUE(g_sPedsForConversation, 1, NULL, "FRANKLIN")
ADD_PED_FOR_DIALOGUE(g_sPedsForConversation, 2, NULL, "TREVOR")
BREAK
CASE CHAR_FRANKLIN
ADD_PED_FOR_DIALOGUE(g_sPedsForConversation, 0, NULL, "MICHAEL")
ADD_PED_FOR_DIALOGUE(g_sPedsForConversation, 2, NULL, "TREVOR")
BREAK
CASE CHAR_TREVOR
ADD_PED_FOR_DIALOGUE(g_sPedsForConversation, 0, NULL, "MICHAEL")
ADD_PED_FOR_DIALOGUE(g_sPedsForConversation, 1, NULL, "FRANKLIN")
BREAK
ENDSWITCH
BREAK
CASE CHAR_FRANK_TREV_CONF
ADD_PED_FOR_DIALOGUE(g_sPedsForConversation, 1, NULL, "FRANKLIN")
ADD_PED_FOR_DIALOGUE(g_sPedsForConversation, 2, NULL, "TREVOR")
BREAK
CASE CHAR_MIKE_FRANK_CONF
ADD_PED_FOR_DIALOGUE(g_sPedsForConversation, 0, NULL, "MICHAEL")
ADD_PED_FOR_DIALOGUE(g_sPedsForConversation, 1, NULL, "FRANKLIN")
BREAK
CASE CHAR_MIKE_TREV_CONF
ADD_PED_FOR_DIALOGUE(g_sPedsForConversation, 0, NULL, "MICHAEL")
ADD_PED_FOR_DIALOGUE(g_sPedsForConversation, 2, NULL, "TREVOR")
BREAK
CASE CHAR_STEVE_MIKE_CONF
ADD_PED_FOR_DIALOGUE(g_sPedsForConversation, 0, NULL, "MICHAEL")
ADD_PED_FOR_DIALOGUE(g_sPedsForConversation, 3, NULL, "STEVE")
BREAK
CASE CHAR_STEVE_TREV_CONF
ADD_PED_FOR_DIALOGUE(g_sPedsForConversation, 2, NULL, "TREVOR")
ADD_PED_FOR_DIALOGUE(g_sPedsForConversation, 3, NULL, "STEVE")
BREAK
DEFAULT
ADD_PED_FOR_DIALOGUE(g_sPedsForConversation, sCallData.iSpeakerID, NULL, PRIVATE_Get_Voice_ID_For_Charsheet_Character(sCallData.sCommData.eNPCCharacter))
BREAK
ENDSWITCH
ENDPROC
PROC PRIVATE_Clean_Up_Peds_For_Conversation_Struct()
//Save the global struct as a new instance of the struct type.
structPedsForConversation sNewPedsForConversationStruct
g_sPedsForConversation = sNewPedsForConversationStruct
ENDPROC
/// PURPOSE:
/// Gets the mission ID of a RC mission which is valid, active and ready to play
/// NOTES:
/// This function is duplicated in randomchar_public.sch due to cyclic header error
/// on compilation - please update both functions when making edits
/// RETURNS:
/// The mission ID of the nearest RC valid mission (NO_RC_MISSION is returned if nothing is found or the player isn't playing)
#IF NOT USE_SP_DLC
FUNC g_eRC_MissionIDs PRIVATE_Get_Nearest_Valid_RC_Mission(FLOAT fDistanceToCheck=RC_BRAIN_ACTIVATION_RANGE_EXTRA, BOOL bCheckPlayerChar=TRUE)
// Mission and player info
g_structRCMissionsStatic sRCMissionDetails
g_eRC_MissionIDs eRCMission
g_eRC_MissionIDs eNearestRCM = NO_RC_MISSION
FLOAT fRCMDistance = fDistanceToCheck
FLOAT fCurrentDist
// Valid player check
IF IS_PLAYER_PLAYING(PLAYER_ID())
INT iPlayerChar = GET_CURRENT_PLAYER_PED_BIT()
// Iterate through all RCM's
INT iMission = 0
REPEAT MAX_RC_MISSIONS iMission
eRCMission = INT_TO_ENUM(g_eRC_MissionIDs, iMission)
// RC mission is ready to play
IF IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[ENUM_TO_INT(eRCMission)].rcFlags, ENUM_TO_INT(RC_FLAG_READY_TO_PLAY))
AND NOT IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[ENUM_TO_INT(eRCMission)].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED))
// Get the RCM information (only really need the trigger coords)
Retrieve_Random_Character_Static_Mission_Details(eRCMission, sRCMissionDetails)
// Is this RCM within specified distance and nearer to the player than any previously stored RCM?
fCurrentDist = GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE),sRCMissionDetails.rcCoords)
IF (fCurrentDist < fRCMDistance)
BOOL bValidMission = TRUE
// Is the player currently the correct character for this RCM?
IF bCheckPlayerChar
IF iPlayerChar <> sRCMissionDetails.rcPlayableChars
bValidMission = FALSE
ENDIF
ENDIF
// Store this as the nearest RCM
IF bValidMission
eNearestRCM = eRCMission
fRCMDistance = fCurrentDist
ENDIF
ENDIF
ENDIF
ENDREPEAT
ENDIF
// Return nearest valid RCM (NO_RC_MISSION if nothing is found...)
RETURN eNearestRCM
ENDFUNC
#ENDIF
//╒═════════════════════════════════════════════════════════════════════════════╕
//╞════════════════════════╡ Communication Execution ╞═════════════════════════╡
//╘═════════════════════════════════════════════════════════════════════════════╛
FUNC BOOL PRIVATE_Is_Safe_To_Start_Communication( INT paramToPlayerBitset,
enumCharacterList paramFromChar,
CC_CommunicationPriority paramPriority,
VectorID paramRestrictedArea = VID_BLANK,
INT paramSettings = 0
#IF IS_DEBUG_BUILD , BOOL paramSupressDebug = FALSE #ENDIF)
//Is the screen faded in?
IF NOT IS_SCREEN_FADED_IN()
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because the screen was faded out.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
//Is the cellphone enabled?
IF IS_CELLPHONE_DISABLED()
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CPRINTLN(DEBUG_COMMUNICATIONS, "Could not start communication because the cellphone is disabled.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
IF IS_PLAYER_PLAYING(PLAYER_ID())
IF GET_PED_PARACHUTE_STATE(PLAYER_PED_ID()) != PPS_INVALID
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because Player is parachuting.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
ENDIF
//Is another conversation in progress?
IF IS_SCRIPTED_CONVERSATION_ONGOING()
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because another conversationn was in progress.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
//Is a mission launched?
IF IS_CURRENTLY_ON_MISSION_OF_ANY_TYPE()
AND paramPriority < CPR_HIGH
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because the player is on a mission.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
//Is the player drunk?
IF IS_PLAYER_PLAYING(PLAYER_ID())
IF Is_Ped_Drunk(PLAYER_PED_ID())
IF IS_BIT_SET(paramToPlayerBitset, GET_CURRENT_PLAYER_PED_INT()) AND NOT IS_BIT_SET(paramSettings, COMM_BIT_TXTMSG_FORCE_SILENT)
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because the player is drunk.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
ENDIF
ENDIF
//Are we playing a cutscene?
IF g_bScriptsSetSafeForCutscene
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because scripts are configured to run a cutscene.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
IF IS_CUTSCENE_PLAYING()
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because a mocap cutscene is playing.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
//Is the browser screen visible?
IF g_bBrowserVisible
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because the browser was on screen.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
//Is a heist planning board view active.
IF g_bHeistBoardViewActive
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because a heist planning board view was active.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
//Are we switching?
IF IS_PLAYER_PED_SWITCH_IN_PROGRESS()
OR (g_sSelectorUI.bOnScreen AND g_sSelectorUI.eUIStateCurrent = SELECTOR_UI_FULL)
OR Is_Player_Timetable_Scene_In_Progress()
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because we are switching.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
//Is the player the correct character?
IF IS_BIT_SET(paramSettings, COMM_BIT_TXTMSG_NO_SILENT)
IF NOT IS_BIT_SET(paramToPlayerBitset, GET_CURRENT_PLAYER_PED_INT())
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because the player is not the correct character.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
ENDIF
//Is a replay being processed?
BOOL bReplayInProgress = TRUE
IF g_replay.replayStageID = RS_NOT_REQUIRED
OR g_replay.replayStageID = RS_ACTIVE
OR g_replay.replayStageID = RS_REJECTED
OR g_replay.replayStageID = RS_NOT_RUNNING
bReplayInProgress = FALSE
ENDIF
#IF IS_DEBUG_BUILD
IF g_replay.replayStageID = RS_WAITING_FOR_FLOW
bReplayInProgress = FALSE
ENDIF
#ENDIF
IF bReplayInProgress = TRUE
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because a replay is being processed.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
//Is the player alive?
IF NOT IS_PLAYER_PLAYING(PLAYER_ID())
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because the player is dead/arrested.")
ENDIF
#ENDIF
RETURN FALSE
ELIF paramPriority != CPR_VERY_HIGH
//Does the player have a wanted level?
IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 1
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because the player has a wanted level greater than 1.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
//Is the autosave screen visible?
IF IS_AUTO_SAVE_IN_PROGRESS()
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because an autosave was in progress.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
//Is the player in a mission trigger area?
IF g_bTriggerSceneActive
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because the player is in an active trigger scene.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
#IF NOT USE_SP_DLC
//Is the player near an active random character mission
IF PRIVATE_Get_Nearest_Valid_RC_Mission(RC_BRAIN_COMMS_OVERRIDE_RANGE) <> NO_RC_MISSION
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because the player is near an active random character mission.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
//check if just in a friend event with the character trying to ring.
IF paramFromChar = CHAR_AMANDA
OR paramFromChar = CHAR_LAMAR
OR paramFromChar = CHAR_JIMMY
OR paramFromChar = CHAR_MICHAEL
OR paramFromChar = CHAR_FRANKLIN
OR paramFromChar = CHAR_TREVOR
IF IS_BIT_SET(paramToPlayerBitset, GET_CURRENT_PLAYER_PED_INT())
enumFriend playerID = GET_FRIEND_FROM_CHAR(GET_CURRENT_PLAYER_PED_ENUM())
enumFriend friendID = GET_FRIEND_FROM_CHAR(paramFromChar)
enumFriendConnection friendConnID = GET_CONNECTION_FROM_FRIENDS(playerID, friendID)
IF friendConnID < MAX_FRIEND_CONNECTIONS
IF g_SavedGlobals.sFriendsData.g_FriendConnectData[friendConnID].lastContactType = FRIEND_CONTACT_FACE
OR g_SavedGlobals.sFriendsData.g_FriendConnectData[friendConnID].lastContactType = FRIEND_CONTACT_DISMISSED
IF IS_TIMER_STARTED(g_SavedGlobals.sFriendsData.g_FriendConnectData[friendConnID].lastContactTimer)
IF GET_TIMER_IN_SECONDS(g_SavedGlobals.sFriendsData.g_FriendConnectData[friendConnID].lastContactTimer) < 30.0
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because the player has just finished friend activity with them.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
#ENDIF
ENDIF
//Does the player has a very wanted level?
IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 2
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because the player has a wanted level greater than 2.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
//Is the mission passed screen visible?
IF IS_RESULT_SCREEN_DISPLAYING()
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because a result screen was displaying.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
//Will this comm trigger a mission.
//If so don't allow if we're in a taxi.
IF IS_BIT_SET(paramSettings, COMM_BIT_TRIGGERS_MISSION)
IF g_bPlayerIsInTaxi
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because it would trigger a mission and the player is in a taxi.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
IF IS_PLAYER_PLAYING(PLAYER_ID())
IF GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) > 0
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because it would trigger a mission and the player has a wanted level.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
ENDIF
IF g_PropertySystemData.propertyManagementState != PROPERTY_MANAGEMENT_STATE_WAITING
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because it would trigger a mission and a property mission is active.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
IF g_OnMissionState = MISSION_TYPE_RANDOM_EVENT
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because it would trigger a mission and kill a random event that is in progress.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
ENDIF
//Is the player in the restricted area?
IF paramRestrictedArea <> VID_BLANK
IF IS_PED_AT_VECTOR_ID(PLAYER_PED_ID(), paramRestrictedArea)
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because the player is in the communication's restricted area.")
ENDIF
//Display message on screen to ensure devs know what just happened.
PRINT_NOW("CC_R_AREA", DEFAULT_GOD_TEXT_TIME, 0)
#ENDIF
RETURN FALSE
ENDIF
ENDIF
//Check the nearest 16 peds to see if one of them is a sending character.
enumCharacterList ePlayer = GET_CURRENT_PLAYER_PED_ENUM()
IF IS_PLAYER_PED_PLAYABLE(ePlayer)
PED_INDEX pedsNearby[16]
GET_PED_NEARBY_PEDS(PLAYER_PED_ID(), pedsNearby)
MODEL_NAMES eFromPedModel[2]
//Look up correct model pairs for conference calls.
SWITCH paramFromChar
CASE CHAR_ALL_PLAYERS_CONF
SWITCH ePlayer
CASE CHAR_MICHAEL
eFromPedModel[0] = GET_PLAYER_PED_MODEL(CHAR_FRANKLIN)
eFromPedModel[1] = GET_PLAYER_PED_MODEL(CHAR_TREVOR)
BREAK
CASE CHAR_FRANKLIN
eFromPedModel[0] = GET_PLAYER_PED_MODEL(CHAR_MICHAEL)
eFromPedModel[1] = GET_PLAYER_PED_MODEL(CHAR_TREVOR)
BREAK
CASE CHAR_TREVOR
eFromPedModel[0] = GET_PLAYER_PED_MODEL(CHAR_MICHAEL)
eFromPedModel[1] = GET_PLAYER_PED_MODEL(CHAR_FRANKLIN)
BREAK
ENDSWITCH
BREAK
CASE CHAR_FRANK_TREV_CONF
eFromPedModel[0] = GET_PLAYER_PED_MODEL(CHAR_FRANKLIN)
eFromPedModel[1] = GET_PLAYER_PED_MODEL(CHAR_TREVOR)
BREAK
CASE CHAR_LEST_FRANK_CONF
eFromPedModel[0] = GET_NPC_PED_MODEL(CHAR_LESTER)
eFromPedModel[1] = GET_PLAYER_PED_MODEL(CHAR_FRANKLIN)
BREAK
CASE CHAR_LEST_MIKE_CONF
eFromPedModel[0] = GET_NPC_PED_MODEL(CHAR_LESTER)
eFromPedModel[1] = GET_PLAYER_PED_MODEL(CHAR_MICHAEL)
BREAK
CASE CHAR_MIKE_FRANK_CONF
eFromPedModel[0] = GET_PLAYER_PED_MODEL(CHAR_MICHAEL)
eFromPedModel[1] = GET_PLAYER_PED_MODEL(CHAR_FRANKLIN)
BREAK
CASE CHAR_MIKE_TREV_CONF
eFromPedModel[0] = GET_PLAYER_PED_MODEL(CHAR_MICHAEL)
eFromPedModel[1] = GET_PLAYER_PED_MODEL(CHAR_TREVOR)
BREAK
CASE CHAR_STEVE_MIKE_CONF
eFromPedModel[0] = GET_NPC_PED_MODEL(CHAR_STEVE)
eFromPedModel[1] = GET_PLAYER_PED_MODEL(CHAR_MICHAEL)
BREAK
CASE CHAR_STEVE_TREV_CONF
eFromPedModel[0] = GET_NPC_PED_MODEL(CHAR_STEVE)
eFromPedModel[1] = GET_PLAYER_PED_MODEL(CHAR_MICHAEL)
BREAK
DEFAULT
//Not a conference call.
IF IS_PLAYER_PED_PLAYABLE(paramFromChar)
eFromPedModel[0] = GET_PLAYER_PED_MODEL(paramFromChar)
ELSE
eFromPedModel[0] = GET_NPC_PED_MODEL(paramFromChar)
ENDIF
eFromPedModel[1] = DUMMY_MODEL_FOR_SCRIPT
BREAK
ENDSWITCH
INT iModelIndex
REPEAT 2 iModelIndex
IF eFromPedModel[iModelIndex] != DUMMY_MODEL_FOR_SCRIPT
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Checking for character model ", GET_MODEL_NAME_FOR_DEBUG(eFromPedModel[iModelIndex]), " existing near the player...")
ENDIF
#ENDIF
INT index
REPEAT 16 index
IF DOES_ENTITY_EXIST(pedsNearby[index])
IF GET_ENTITY_MODEL(pedsNearby[index]) = eFromPedModel[iModelIndex]
IF NOT IS_ENTITY_DEAD(pedsNearby[index])
IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
IF VDIST2(GET_ENTITY_COORDS(pedsNearby[index]), GET_ENTITY_COORDS(PLAYER_PED_ID())) < 6400 //80^2
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because an NPC character involved in the call exists near the player.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
ENDIF
ELSE
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because an NPC character involved in the call exists near the player and is dead.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
ENDIF
ENDIF
ENDREPEAT
//Is this a player character? If so check against our global player ped arrays.
PED_INDEX pedTemp = NULL
SWITCH eFromPedModel[iModelIndex]
CASE PLAYER_ZERO pedTemp = g_sPlayerPedRequest.sSelectorPeds.pedID[SELECTOR_PED_MICHAEL] BREAK
CASE PLAYER_ONE pedTemp = g_sPlayerPedRequest.sSelectorPeds.pedID[SELECTOR_PED_FRANKLIN] BREAK
CASE PLAYER_TWO pedTemp = g_sPlayerPedRequest.sSelectorPeds.pedID[SELECTOR_PED_TREVOR] BREAK
ENDSWITCH
IF DOES_ENTITY_EXIST(pedTemp)
IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
IF VDIST2(GET_ENTITY_COORDS(pedTemp, TRUE), GET_ENTITY_COORDS(PLAYER_PED_ID())) < 6400 //80^2
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because the sender was a global player ped nearby.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
ENDIF
ENDIF
SWITCH eFromPedModel[iModelIndex]
CASE PLAYER_ZERO pedTemp = g_ambientSelectorPedDeleteQueue[SELECTOR_PED_MICHAEL] BREAK
CASE PLAYER_ONE pedTemp = g_ambientSelectorPedDeleteQueue[SELECTOR_PED_FRANKLIN] BREAK
CASE PLAYER_TWO pedTemp = g_ambientSelectorPedDeleteQueue[SELECTOR_PED_TREVOR] BREAK
ENDSWITCH
IF DOES_ENTITY_EXIST(pedTemp)
IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID())
IF VDIST2(GET_ENTITY_COORDS(pedTemp, TRUE), GET_ENTITY_COORDS(PLAYER_PED_ID())) < 6400 //80^2
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because the sender was a global player ped queued for deletion nearby.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
ENDIF
ENDIF
ENDIF
ENDREPEAT
ELSE
#IF IS_DEBUG_BUILD
IF NOT paramSupressDebug
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Could not start communication because the player is not a SP story character.")
ENDIF
#ENDIF
RETURN FALSE
ENDIF
RETURN TRUE
ENDFUNC
FUNC BOOL PRIVATE_Is_Character_Busy_In_Mission(enumCharacterList paramCharacter)
INT iAvailableMissionIndex
#IF USE_CLF_DLC
REPEAT MAX_MISSIONS_AVAILABLE_TU iAvailableMissionIndex
INT iCoreVarsIndex = g_availableMissionsTU[iAvailableMissionIndex].index
IF iCoreVarsIndex != ILLEGAL_ARRAY_POSITION
INT iMissionDataIndex = ILLEGAL_ARRAY_POSITION
iMissionDataIndex = g_flowUnsaved.coreVars[g_availableMissionsTU[iAvailableMissionIndex].index].iValue1
#ENDIF
#IF USE_NRM_DLC
REPEAT MAX_MISSIONS_AVAILABLE_TU iAvailableMissionIndex
INT iCoreVarsIndex = g_availableMissionsTU[iAvailableMissionIndex].index
IF iCoreVarsIndex != ILLEGAL_ARRAY_POSITION
INT iMissionDataIndex = ILLEGAL_ARRAY_POSITION
iMissionDataIndex = g_flowUnsaved.coreVars[g_availableMissionsTU[iAvailableMissionIndex].index].iValue1
#ENDIF
#IF NOT USE_SP_DLC
REPEAT MAX_MISSIONS_AVAILABLE iAvailableMissionIndex
INT iCoreVarsIndex = g_availableMissions[iAvailableMissionIndex].index
IF iCoreVarsIndex != ILLEGAL_ARRAY_POSITION
INT iMissionDataIndex = ILLEGAL_ARRAY_POSITION
iMissionDataIndex = g_flowUnsaved.coreVars[g_availableMissions[iAvailableMissionIndex].index].iValue1
#ENDIF
IF iMissionDataIndex != ILLEGAL_ARRAY_POSITION
IF DOES_CHARACTER_BITSET_CONTAIN_FRIEND_CHARACTER(g_sMissionStaticData[iMissionDataIndex].friendCharBitset, paramCharacter)
RETURN TRUE
ENDIF
ENDIF
#IF USE_CLF_DLC
ENDIF
ENDREPEAT
#ENDIF
#IF USE_NRM_DLC
ENDIF
ENDREPEAT
#ENDIF
#IF NOT USE_SP_DLC
ENDIF
ENDREPEAT
#ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL PRIVATE_Attempt_Make_Queued_Call(CC_CallData &sCallData, BOOL &bDoCallBranch)
CPRINTLN(DEBUG_COMMUNICATIONS, "Attempting to make call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), ".")
//Is the cellphone available?
IF IS_PHONE_ONSCREEN()
OR IS_CELLPHONE_DISABLED()
OR IS_CALLING_ANY_CONTACT()
CPRINTLN(DEBUG_COMMUNICATIONS, "Could not start communication ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " because the cellphone was busy.")
RETURN FALSE
ENDIF
IF NOT PRIVATE_Is_Safe_To_Start_Communication( sCallData.sCommData.iPlayerCharBitset,
sCallData.sCommData.eNPCCharacter,
sCallData.sCommData.ePriority,
sCallData.sCommData.eRestrictedAreaID,
sCallData.sCommData.iSettings)
RETURN FALSE
ENDIF
//Run any custom checks bound to this call.
//NB. Branched calls use the check to determine the branch, not whether it should send.
IF NOT IS_BIT_SET(sCallData.sCommData.iSettings, COMM_BIT_CALL_BRANCHED)
IF sCallData.sCommData.eSendCheck != FLOW_CHECK_NONE
IF NOT DO_CUSTOM_FLOW_CHECK(sCallData.sCommData.eSendCheck)
CPRINTLN(DEBUG_COMMUNICATIONS, "Could not start communication ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " because the custom send check ", GET_DEBUG_STRING_FOR_FLOW_CHECK_ID(sCallData.sCommData.eSendCheck), " failed.")
RETURN FALSE
ENDIF
ENDIF
ENDIF
enumConversationPriority ePriority = CONV_PRIORITY_FLOW_ONLY_USE_AMBIENT_SLOT
IF sCallData.sCommData.ePriority = CPR_VERY_HIGH
ePriority = CONV_PRIORITY_FLOW_ONLY_USE_AMBIENT_SLOT_BYPASS_SLEEPMODE
ENDIF
//Attempt to make the call.
IF IS_BIT_SET(sCallData.sCommData.iPlayerCharBitset, GET_CURRENT_PLAYER_PED_INT())
//Configure the PedsForConversaion struct.
PRIVATE_Fill_Peds_For_Conversation_Struct(sCallData)
IF IS_BIT_SET(sCallData.sCommData.iSettings, COMM_BIT_CALL_ADD_TEMP_CONTACT)
enumPhoneBookPresence ePhonebook
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_MICHAEL ePhonebook = MICHAEL_BOOK BREAK
CASE CHAR_FRANKLIN ePhonebook = FRANKLIN_BOOK BREAK
CASE CHAR_TREVOR ePhonebook = TREVOR_BOOK BREAK
ENDSWITCH
#IF USE_CLF_DLC
IF NOT (g_savedGlobalsClifford.sCharSheetData.g_CharacterSheet[sCallData.sCommData.eNPCCharacter].PhonebookState[ePhonebook] = LISTED)
SET_BIT(sCallData.sCommData.iSettings, COMM_BIT_CALL_REMOVE_TEMP_CONTACT)
ADD_CONTACT_TO_PHONEBOOK(sCallData.sCommData.eNPCCharacter, ePhonebook, FALSE)
CPRINTLN(DEBUG_COMMUNICATIONS, "Temporarily added contact for call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " to player phonebook for the duration of the call.")
ENDIF
#ENDIF
#IF USE_NRM_DLC
IF NOT (g_savedGlobalsnorman.sCharSheetData.g_CharacterSheet[sCallData.sCommData.eNPCCharacter].PhonebookState[ePhonebook] = LISTED)
SET_BIT(sCallData.sCommData.iSettings, COMM_BIT_CALL_REMOVE_TEMP_CONTACT)
ADD_CONTACT_TO_PHONEBOOK(sCallData.sCommData.eNPCCharacter, ePhonebook, FALSE)
CPRINTLN(DEBUG_COMMUNICATIONS, "Temporarily added contact for call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " to player phonebook for the duration of the call.")
ENDIF
#ENDIF
#IF NOT USE_SP_DLC
IF NOT (GLOBAL_CHARACTER_SHEET_GET_PHONEBOOK_STATE(sCallData.sCommData.eNPCCharacter, ENUM_TO_INT(ePhonebook)) = LISTED)
SET_BIT(sCallData.sCommData.iSettings, COMM_BIT_CALL_REMOVE_TEMP_CONTACT)
ADD_CONTACT_TO_PHONEBOOK(sCallData.sCommData.eNPCCharacter, ePhonebook, FALSE)
CPRINTLN(DEBUG_COMMUNICATIONS, "Temporarily added contact for call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " to player phonebook for the duration of the call.")
ENDIF
#ENDIF
ENDIF
IF PRIVATE_Get_CommID_Form(sCallData.sCommData.eID) = CF_QUESTION_CALL
CC_QuestionCallStringData sCallStrings
TEXT_LABEL tYesResponse
TEXT_LABEL tNoResponse
PRIVATE_Get_Question_Call_String_Data(sCallData.sCommData.eID, sCallStrings)
PRIVATE_Get_Question_Call_Response_String(sCallData.eYesResponse, tYesResponse)
PRIVATE_Get_Question_Call_Response_String(sCallData.eNoResponse, tNoResponse)
IF IS_BIT_SET(sCallData.sCommData.iSettings, COMM_BIT_CALL_BLOCK_HANGUP)
IF CHAR_CALL_PLAYER_CELLPHONE_WITH_REPLIES_FORCE_ANSWER( g_sPedsForConversation,
sCallData.sCommData.eNPCCharacter,
sCallStrings.tBlock,
sCallStrings.tConversation,
ePriority,
sCallStrings.tQuestion,
tYesResponse,
tNoResponse)
CPRINTLN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " now in progress.")
IF sCallData.sCommData.ePriority = CPR_VERY_HIGH
OR IS_BIT_SET(sCallData.sCommData.iSettings, COMM_BIT_CALL_BLOCK_HANGUP)
DISABLE_HANGUP_FOR_THIS_CALL(TRUE)
ENDIF
RETURN TRUE
ELSE
CPRINTLN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " failed to start as the cellphone controller returned a busy status.")
//Clean up the PedsForConversation struct.
PRIVATE_Clean_Up_Peds_For_Conversation_Struct()
RETURN FALSE
ENDIF
ELSE
IF CHAR_CALL_PLAYER_CELLPHONE_WITH_REPLIES( g_sPedsForConversation,
sCallData.sCommData.eNPCCharacter,
sCallStrings.tBlock,
sCallStrings.tConversation,
ePriority,
sCallStrings.tQuestion,
tYesResponse,
tNoResponse)
CPRINTLN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " now in progress.")
IF sCallData.sCommData.ePriority = CPR_VERY_HIGH
OR IS_BIT_SET(sCallData.sCommData.iSettings, COMM_BIT_CALL_BLOCK_HANGUP)
DISABLE_HANGUP_FOR_THIS_CALL(TRUE)
ENDIF
RETURN TRUE
ELSE
CPRINTLN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " failed to start as the cellphone controller returned a busy status.")
//Clean up the PedsForConversation struct.
PRIVATE_Clean_Up_Peds_For_Conversation_Struct()
RETURN FALSE
ENDIF
ENDIF
ELSE
CC_CallStringData sCallStrings
PRIVATE_Get_Call_String_Data(sCallData.sCommData.eID, sCallStrings)
IF IS_BIT_SET(sCallData.sCommData.iSettings, COMM_BIT_CALL_IS_CONFERENCE)
//TODO Needs updating once Steve has implemented a new CHAR_CONFERENCE_CALL_PLAYER_CELLPHONE or similar.
IF CHAR_CALL_PLAYER_CELLPHONE( g_sPedsForConversation,
sCallData.sCommData.eNPCCharacter,
sCallStrings.tBlock,
sCallStrings.tConversation,
ePriority)
CPRINTLN(DEBUG_COMMUNICATIONS, "Conference call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " now in progress.")
IF sCallData.sCommData.ePriority = CPR_VERY_HIGH
OR IS_BIT_SET(sCallData.sCommData.iSettings, COMM_BIT_CALL_BLOCK_HANGUP)
DISABLE_HANGUP_FOR_THIS_CALL(TRUE)
ENDIF
RETURN TRUE
ELSE
CPRINTLN(DEBUG_COMMUNICATIONS, "Conference call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " failed to start as the cellphone controller returned a busy status.")
//Clean up the PedsForConversation struct.
PRIVATE_Clean_Up_Peds_For_Conversation_Struct()
RETURN FALSE
ENDIF
ELSE
IF IS_BIT_SET(sCallData.sCommData.iSettings, COMM_BIT_FROM_CHAR_IS_PLAYER)
IF PLAYER_CALL_CHAR_CELLPHONE( g_sPedsForConversation,
sCallData.sCommData.eNPCCharacter,
sCallStrings.tBlock,
sCallStrings.tConversation,
ePriority)
CPRINTLN(DEBUG_COMMUNICATIONS, "Call from player ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " now in progress.")
IF sCallData.sCommData.ePriority = CPR_VERY_HIGH
OR IS_BIT_SET(sCallData.sCommData.iSettings, COMM_BIT_CALL_BLOCK_HANGUP)
DISABLE_HANGUP_FOR_THIS_CALL(TRUE)
ENDIF
IF IS_BIT_SET(sCallData.sCommData.iSettings, COMM_BIT_CALL_BRANCHED)
CPRINTLN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " has a branch. Flagging to service branched call after it starts.")
bDoCallBranch = TRUE
ENDIF
RETURN TRUE
ELSE
CPRINTLN(DEBUG_COMMUNICATIONS, "Call from player ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " failed to start as the cellphone controller returned a busy status.")
//Clean up the PedsForConversation struct.
PRIVATE_Clean_Up_Peds_For_Conversation_Struct()
RETURN FALSE
ENDIF
ELSE
IF sCallData.sCommData.ePriority = CPR_VERY_HIGH
IF CHAR_CALL_PLAYER_CELLPHONE_FORCE_ANSWER( g_sPedsForConversation,
sCallData.sCommData.eNPCCharacter,
sCallStrings.tBlock,
sCallStrings.tConversation,
ePriority)
CPRINTLN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " now in progress.")
DISABLE_HANGUP_FOR_THIS_CALL(TRUE)
IF IS_BIT_SET(sCallData.sCommData.iSettings, COMM_BIT_CALL_BRANCHED)
CPRINTLN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " has a branch. Flagging to service branched call after it starts.")
bDoCallBranch = TRUE
ENDIF
RETURN TRUE
ELSE
CPRINTLN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " failed to start as the cellphone controller returned a busy status.")
//Clean up the PedsForConversation struct.
PRIVATE_Clean_Up_Peds_For_Conversation_Struct()
RETURN FALSE
ENDIF
else
IF CHAR_CALL_PLAYER_CELLPHONE( g_sPedsForConversation,
sCallData.sCommData.eNPCCharacter,
sCallStrings.tBlock,
sCallStrings.tConversation,
ePriority)
CPRINTLN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " now in progress.")
IF IS_BIT_SET(sCallData.sCommData.iSettings, COMM_BIT_CALL_BLOCK_HANGUP)
DISABLE_HANGUP_FOR_THIS_CALL(TRUE)
ENDIF
IF IS_BIT_SET(sCallData.sCommData.iSettings, COMM_BIT_CALL_BRANCHED)
CPRINTLN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " has a branch. Flagging to service branched call after it starts.")
bDoCallBranch = TRUE
ENDIF
RETURN TRUE
ELSE
CPRINTLN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " failed to start as the cellphone controller returned a busy status.")
//Clean up the PedsForConversation struct.
PRIVATE_Clean_Up_Peds_For_Conversation_Struct()
RETURN FALSE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
ELSE
CPRINTLN(DEBUG_COMMUNICATIONS, "The player is not one of the receiving characters for call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), ". Failed to send.")
RETURN FALSE
ENDIF
ENDFUNC
FUNC BOOL PRIVATE_Attempt_Make_Outgoing_Call(CC_CallData &sCallData, BOOL &bDoCallBranch)
//First check that the call passed is a quick call or a missed call.
IF NOT IS_BIT_SET(sCallData.sCommData.iSettings, COMM_BIT_CALL_IS_QUICK)
AND NOT IS_BIT_SET(sCallData.sCommData.iSettings, COMM_BIT_CALL_IS_MISSED)
SCRIPT_ASSERT("PRIVATE_Attempt_Make_Outgoing_Call: Call data passed was not for an outgoing call. This shouldn't happen. Tell BenR")
CPRINTLN(DEBUG_COMMUNICATIONS, "Attempted to connect outgoing call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), ". However, this call was not a valid outgoing call.")
RETURN FALSE
ENDIF
IF NOT PRIVATE_Is_Safe_To_Start_Communication( sCallData.sCommData.iPlayerCharBitset,
sCallData.sCommData.eNPCCharacter,
sCallData.sCommData.ePriority,
sCallData.sCommData.eRestrictedAreaID,
sCallData.sCommData.iSettings)
RETURN FALSE
ENDIF
IF PRIVATE_Is_Character_Busy_In_Mission(sCallData.sCommData.eNPCCharacter)
CPRINTLN(DEBUG_COMMUNICATIONS, "Could not start outgoing communication ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " because the character being called is busy in a mission.")
RETURN FALSE
ENDIF
//Run any custom checks bound to this call.
IF sCallData.sCommData.eSendCheck != FLOW_CHECK_NONE
IF NOT DO_CUSTOM_FLOW_CHECK(sCallData.sCommData.eSendCheck)
CPRINTLN(DEBUG_COMMUNICATIONS, "Could not start communication ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " because the custom send check ", GET_DEBUG_STRING_FOR_FLOW_CHECK_ID(sCallData.sCommData.eSendCheck), " failed.")
RETURN FALSE
ENDIF
ENDIF
//Attempt to make the outgoing call.
IF IS_PLAYER_PED_PLAYABLE(GET_CURRENT_PLAYER_PED_ENUM())
IF IS_BIT_SET(sCallData.sCommData.iPlayerCharBitset, GET_CURRENT_PLAYER_PED_INT())
//Configure the PedsForConversaion struct.
PRIVATE_Fill_Peds_For_Conversation_Struct(sCallData)
IF PRIVATE_Get_CommID_Form(sCallData.sCommData.eID) = CF_QUESTION_CALL
CC_QuestionCallStringData sCallStrings
TEXT_LABEL tYesResponse
TEXT_LABEL tNoResponse
PRIVATE_Get_Question_Call_String_Data(sCallData.sCommData.eID, sCallStrings)
PRIVATE_Get_Question_Call_Response_String(sCallData.eYesResponse, tYesResponse)
PRIVATE_Get_Question_Call_Response_String(sCallData.eNoResponse, tNoResponse)
IF PLAYER_CALL_CHAR_CELLPHONE_WITH_REPLIES( g_sPedsForConversation,
sCallData.sCommData.eNPCCharacter,
sCallStrings.tBlock,
sCallStrings.tConversation,
CONV_PRIORITY_FLOW_ONLY_USE_AMBIENT_SLOT, //Always make it very high as we've already queued it based on internal system priority.
sCallStrings.tQuestion,
tYesResponse,
tNoResponse)
CPRINTLN(DEBUG_COMMUNICATIONS, "Outgoing call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " now in progress.")
IF IS_BIT_SET(sCallData.sCommData.iSettings, COMM_BIT_CALL_BRANCHED)
CPRINTLN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " has a branch. Flagging to service branched call after it starts.")
bDoCallBranch = TRUE
ENDIF
RETURN TRUE
ELSE
CPRINTLN(DEBUG_COMMUNICATIONS, "Outgoing call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " failed to start as the cellphone controller returned a busy status.")
//Clean up the PedsForConversation struct.
PRIVATE_Clean_Up_Peds_For_Conversation_Struct()
RETURN FALSE
ENDIF
ELSE
CC_CallStringData sCallStrings
PRIVATE_Get_Call_String_Data(sCallData.sCommData.eID, sCallStrings)
TEXT_LABEL tOutgoingConv
IF IS_STRING_NULL_OR_EMPTY(sCallStrings.tAlt)
tOutgoingConv = sCallStrings.tConversation
ELSE
tOutgoingConv = sCallStrings.tAlt
ENDIF
IF PLAYER_CALL_CHAR_CELLPHONE( g_sPedsForConversation,
sCallData.sCommData.eNPCCharacter,
sCallStrings.tBlock,
tOutgoingConv,
CONV_PRIORITY_FLOW_ONLY_USE_AMBIENT_SLOT) //Always make it very high as we've already queued it based on internal system priority.
CPRINTLN(DEBUG_COMMUNICATIONS, "Outgoing call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " now in progress.")
IF IS_BIT_SET(sCallData.sCommData.iSettings, COMM_BIT_CALL_BRANCHED)
CPRINTLN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " has a branch. Flagging to service branched call after it starts.")
bDoCallBranch = TRUE
ENDIF
RETURN TRUE
ELSE
CPRINTLN(DEBUG_COMMUNICATIONS, "Outgoing call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " failed to start as the cellphone controller returned a busy status.")
//Clean up the PedsForConversation struct.
PRIVATE_Clean_Up_Peds_For_Conversation_Struct()
RETURN FALSE
ENDIF
ENDIF
ELSE
CPRINTLN(DEBUG_COMMUNICATIONS, "The player is not the sending character for outgoing call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), ". Failed to send.")
RETURN FALSE
ENDIF
ENDIF
CPRINTLN(DEBUG_COMMUNICATIONS, "Failed to send outgoing call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), ".")
RETURN FALSE
ENDFUNC
FUNC BOOL PRIVATE_Attempt_Make_Outgoing_Chat_Call(CC_CallData &sCallData)
//Is it safe to make this call?
IF NOT PRIVATE_Is_Safe_To_Start_Communication( sCallData.sCommData.iPlayerCharBitset,
sCallData.sCommData.eNPCCharacter,
sCallData.sCommData.ePriority,
sCallData.sCommData.eRestrictedAreaID,
sCallData.sCommData.iSettings)
RETURN FALSE
ENDIF
IF sCallData.sCommData.eNPCCharacter != CHAR_FRANKLIN
AND sCallData.sCommData.eNPCCharacter != CHAR_TREVOR
AND sCallData.sCommData.eNPCCharacter != CHAR_MICHAEL
IF PRIVATE_Is_Character_Busy_In_Mission(sCallData.sCommData.eNPCCharacter)
CPRINTLN(DEBUG_COMMUNICATIONS, "Could not start outgoing communication ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " because the character being called is busy in a mission.")
RETURN FALSE
ENDIF
ENDIF
//Run any custom checks bound to this call.
IF sCallData.sCommData.eSendCheck != FLOW_CHECK_NONE
IF NOT DO_CUSTOM_FLOW_CHECK(sCallData.sCommData.eSendCheck)
CPRINTLN(DEBUG_COMMUNICATIONS, "Could not start communication ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " because the custom send check ", GET_DEBUG_STRING_FOR_FLOW_CHECK_ID(sCallData.sCommData.eSendCheck), " failed.")
RETURN FALSE
ENDIF
ENDIF
//Configure the PedsForConversaion struct.
PRIVATE_Fill_Peds_For_Conversation_Struct(sCallData)
CC_CallStringData sCallStrings
PRIVATE_Get_Call_String_Data(sCallData.sCommData.eID, sCallStrings)
//Attempt to make the outgoing call.
IF PLAYER_CALL_CHAR_CELLPHONE( g_sPedsForConversation,
sCallData.sCommData.eNPCCharacter, //NPC character.
sCallStrings.tBlock,
sCallStrings.tConversation,
CONV_PRIORITY_FLOW_ONLY_USE_AMBIENT_SLOT) //Always make it very high as we've already queued it based on internal system priority.
CPRINTLN(DEBUG_COMMUNICATIONS, "Outgoing chat call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " now in progress.")
RETURN TRUE
ELSE
CPRINTLN(DEBUG_COMMUNICATIONS, "Outgoing chat call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " failed to start as the cellphone controller returned a busy status.")
//Clean up the PedsForConversation struct.
PRIVATE_Clean_Up_Peds_For_Conversation_Struct()
RETURN FALSE
ENDIF
ENDFUNC
FUNC BOOL PRIVATE_Attempt_Send_Queued_Text_Message(CC_TextMessageData &sTextMessageData)
CPRINTLN(DEBUG_COMMUNICATIONS, "Attempting to send text ", GET_COMM_ID_DEBUG_STRING(sTextMessageData.sCommData.eID), ".")
//Is the cellphone available?
IF IS_PHONE_ONSCREEN()
OR IS_CELLPHONE_DISABLED()
OR IS_CALLING_ANY_CONTACT()
CPRINTLN(DEBUG_COMMUNICATIONS, "Could not send text ", GET_COMM_ID_DEBUG_STRING(sTextMessageData.sCommData.eID), " because the cellphone was busy.")
RETURN FALSE
ENDIF
//Is it safe to send this text?
IF NOT PRIVATE_Is_Safe_To_Start_Communication( sTextMessageData.sCommData.iPlayerCharBitset,
sTextMessageData.sCommData.eNPCCharacter,
sTextMessageData.sCommData.ePriority,
sTextMessageData.sCommData.eRestrictedAreaID,
sTextMessageData.sCommData.iSettings)
RETURN FALSE
ENDIF
//Run any custom checks bound to this text.
IF sTextMessageData.sCommData.eSendCheck != FLOW_CHECK_NONE
IF NOT DO_CUSTOM_FLOW_CHECK(sTextMessageData.sCommData.eSendCheck)
CPRINTLN(DEBUG_COMMUNICATIONS, "Could not start communication ", GET_COMM_ID_DEBUG_STRING(sTextMessageData.sCommData.eID), " because the custom send check ", GET_DEBUG_STRING_FOR_FLOW_CHECK_ID(sTextMessageData.sCommData.eSendCheck), " failed.")
RETURN FALSE
ENDIF
ENDIF
//Is the player in the restricted area?
IF sTextMessageData.sCommData.eRestrictedAreaID <> VID_BLANK
IF IS_PED_AT_VECTOR_ID(PLAYER_PED_ID(), sTextMessageData.sCommData.eRestrictedAreaID)
CPRINTLN(DEBUG_COMMUNICATIONS, "Could not send text ", GET_COMM_ID_DEBUG_STRING(sTextMessageData.sCommData.eID), " because the player is in the communication's restricted area.")
#IF IS_DEBUG_BUILD
//Display message on screen to ensure devs know what just happened.
PRINT_NOW("CC_R_AREA", DEFAULT_GOD_TEXT_TIME, 0)
#ENDIF
RETURN FALSE
ENDIF
ENDIF
//Is this a critical text message.
enumTxtMsgMissionCritical eCritical
IF IS_BIT_SET(sTextMessageData.sCommData.iSettings, COMM_BIT_TXTMSG_NOT_CRITICAL)
eCritical = TXTMSG_NOT_CRITICAL
ELSE
eCritical = TXTMSG_CRITICAL
IF IS_BIT_SET(sTextMessageData.sCommData.iPlayerCharBitset, ENUM_TO_INT(CHAR_MICHAEL))
IF IS_CRITICAL_MESSAGE_ALREADY_PENDING_FOR_PLAYER_ENUM(CHAR_MICHAEL)
CPRINTLN(DEBUG_COMMUNICATIONS, "Critical text message found on a Michael's phone. Overriding all outstanding critical messages.")
OVERRIDE_CRITICAL_MESSAGE_BLOCK_FOR_ALL_PLAYERS()
ENDIF
ENDIF
IF IS_BIT_SET(sTextMessageData.sCommData.iPlayerCharBitset, ENUM_TO_INT(CHAR_FRANKLIN))
IF IS_CRITICAL_MESSAGE_ALREADY_PENDING_FOR_PLAYER_ENUM(CHAR_FRANKLIN)
CPRINTLN(DEBUG_COMMUNICATIONS, "Critical text message found on a Franklin's phone. Overriding all outstanding critical messages.")
OVERRIDE_CRITICAL_MESSAGE_BLOCK_FOR_ALL_PLAYERS()
ENDIF
ENDIF
IF IS_BIT_SET(sTextMessageData.sCommData.iPlayerCharBitset, ENUM_TO_INT(CHAR_TREVOR))
IF IS_CRITICAL_MESSAGE_ALREADY_PENDING_FOR_PLAYER_ENUM(CHAR_TREVOR)
CPRINTLN(DEBUG_COMMUNICATIONS, "Critical text message found on a Trevor's phone. Overriding all outstanding critical messages.")
OVERRIDE_CRITICAL_MESSAGE_BLOCK_FOR_ALL_PLAYERS()
ENDIF
ENDIF
ENDIF
enumTxtMsgLockedStatus eLocked
IF IS_BIT_SET(sTextMessageData.sCommData.iSettings, COMM_BIT_TXTMSG_LOCKED)
eLocked = TXTMSG_LOCKED
ELSE
eLocked = TXTMSG_UNLOCKED
ENDIF
enumTxtMsgIsReplyRequired eReply
IF IS_BIT_SET(sTextMessageData.sCommData.iSettings, COMM_BIT_HAS_QUESTION)
eReply = REPLY_IS_REQUIRED
ELSE
eReply = NO_REPLY_REQUIRED
ENDIF
TEXT_LABEL tTextLabel
PRIVATE_Get_Text_Message_Message_Label(sTextMessageData.sCommData.eID, tTextLabel)
//Check for composite parts to append to the label.
IF sTextMessageData.ePart1 != TPART_NONE
TEXT_LABEL tPart1
PRIVATE_Get_Text_Part_Message_Label(sTextMessageData.ePart1, tPart1)
CPRINTLN(DEBUG_COMMUNICATIONS, "Found a first composite part for text message. Appending \"", tPart1, "\" to the label.")
tTextLabel += tPart1
IF sTextMessageData.ePart2 != TPART_NONE
TEXT_LABEL tPart2
PRIVATE_Get_Text_Part_Message_Label(sTextMessageData.ePart2, tPart2)
CPRINTLN(DEBUG_COMMUNICATIONS, "Found a second composite part for text message. Appending \"", tPart2, "\" to the label.")
tTextLabel += tPart2
ENDIF
ENDIF
//Is the player one of the receiving characters.
IF IS_BIT_SET(sTextMessageData.sCommData.iPlayerCharBitset, GET_CURRENT_PLAYER_PED_INT())
CPRINTLN(DEBUG_COMMUNICATIONS, "Attempting to send text ", GET_COMM_ID_DEBUG_STRING(sTextMessageData.sCommData.eID), " to ", GET_CHARSHEET_DISPLAY_STRING_FROM_CHARSHEET(GET_CURRENT_PLAYER_PED_ENUM()), " with label \"", tTextLabel, "\".")
IF SEND_TEXT_MESSAGE_TO_CURRENT_PLAYER( sTextMessageData.sCommData.eNPCCharacter,
tTextLabel,
eLocked,
eCritical,
TXTMSG_AUTO_UNLOCK_AFTER_READ,
eReply,
ICON_STANDARD_TEXTMSG,
TRUE,
NO_BARTER_REQUIRED,
sTextMessageData.WhichCanCallSenderStatus)
IF NOT IS_BIT_SET(sTextMessageData.sCommData.iSettings, COMM_BIT_TXTMSG_NO_SILENT)
INT iPlayerIndex
REPEAT 3 iPlayerIndex
IF IS_BIT_SET(sTextMessageData.sCommData.iPlayerCharBitset, iPlayerIndex)
AND iplayerIndex != GET_CURRENT_PLAYER_PED_INT()
enumRecipientList eSilentChar
SWITCH iPlayerIndex
CASE 0
CPRINTLN(DEBUG_COMMUNICATIONS, "Attempting to send ", GET_COMM_ID_DEBUG_STRING(sTextMessageData.sCommData.eID), " silently to Michael.")
eSilentChar = SILENT_MICHAEL
BREAK
CASE 1
CPRINTLN(DEBUG_COMMUNICATIONS, "Attempting to send ", GET_COMM_ID_DEBUG_STRING(sTextMessageData.sCommData.eID), " silently to Franklin.")
eSilentChar = SILENT_FRANKLIN
BREAK
CASE 2
CPRINTLN(DEBUG_COMMUNICATIONS, "Attempting to send ", GET_COMM_ID_DEBUG_STRING(sTextMessageData.sCommData.eID), " silently to Trevor.")
eSilentChar = SILENT_TREVOR
BREAK
ENDSWITCH
IF SEND_SILENT_TEXT_MESSAGE_TO_PLAYER_CHARACTER ( sTextMessageData.sCommData.eNPCCharacter,
eSilentChar,
tTextLabel,
eLocked,
TXTMSG_NOT_CRITICAL,
TXTMSG_AUTO_UNLOCK_AFTER_READ,
eReply,
ICON_STANDARD_TEXTMSG,
FALSE,
NO_BARTER_REQUIRED,
sTextMessageData.WhichCanCallSenderStatus)
CPRINTLN(DEBUG_COMMUNICATIONS, GET_COMM_ID_DEBUG_STRING(sTextMessageData.sCommData.eID), " was sent silently to a player character.")
ENDIF
ENDIF
ENDREPEAT
ENDIF
//Send "first text message" help if it hasn't been shown already.
#IF NOT USE_SP_DLC
IF NOT HAS_ONE_TIME_HELP_DISPLAYED(FHM_FIRST_TEXT_RECEIVED)
IF GET_MISSION_COMPLETE_STATE(SP_MISSION_ARMENIAN_2)
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
CASE CHAR_MICHAEL
ADD_HELP_TO_FLOW_QUEUE("AM_H_FTXT", FHP_HIGH, 3000, FLOW_HELP_NEVER_EXPIRES, DEFAULT_GOD_TEXT_TIME, BIT_MICHAEL,CID_BLANK,CID_BLANK, FHF_SAVED)
BREAK
CASE CHAR_FRANKLIN
ADD_HELP_TO_FLOW_QUEUE("AM_H_FTXT", FHP_HIGH, 3000, FLOW_HELP_NEVER_EXPIRES, DEFAULT_GOD_TEXT_TIME, BIT_FRANKLIN,CID_BLANK,CID_BLANK, FHF_SAVED)
BREAK
CASE CHAR_TREVOR
ADD_HELP_TO_FLOW_QUEUE("AM_H_FTXT", FHP_HIGH, 3000, FLOW_HELP_NEVER_EXPIRES, DEFAULT_GOD_TEXT_TIME, BIT_TREVOR,CID_BLANK,CID_BLANK, FHF_SAVED)
BREAK
ENDSWITCH
SET_ONE_TIME_HELP_MESSAGE_DISPLAYED(FHM_FIRST_TEXT_RECEIVED)
ENDIF
ENDIF
#ENDIF
CPRINTLN(DEBUG_COMMUNICATIONS, "Text message ", GET_COMM_ID_DEBUG_STRING(sTextMessageData.sCommData.eID), " sent.")
RETURN TRUE
ELSE
CPRINTLN(DEBUG_COMMUNICATIONS, "Cellphone returned a busy status. Failed to send text.")
RETURN FALSE
ENDIF
ELIF NOT IS_BIT_SET(sTextMessageData.sCommData.iSettings, COMM_BIT_TXTMSG_NO_SILENT)
IF sTextMessageData.iFailCount >= 2 OR IS_BIT_SET(sTextMessageData.sCommData.iSettings, COMM_BIT_TXTMSG_FORCE_SILENT)
#IF IS_DEBUG_BUILD
IF sTextMessageData.iFailCount >= 2
CPRINTLN(DEBUG_COMMUNICATIONS, "Text message ", GET_COMM_ID_DEBUG_STRING(sTextMessageData.sCommData.eID), " has failed too many times. Attempting to send silently to all recipients.")
ELSE
CPRINTLN(DEBUG_COMMUNICATIONS, "Text message ", GET_COMM_ID_DEBUG_STRING(sTextMessageData.sCommData.eID), " was flagged to force send silently. Attempting to send silently to all recipients.")
ENDIF
#ENDIF
INT iPlayerIndex
BOOL bTextSent = FALSE
REPEAT 3 iPlayerIndex
IF IS_BIT_SET(sTextMessageData.sCommData.iPlayerCharBitset, iPlayerIndex)
enumRecipientList eSilentChar
SWITCH iPlayerIndex
CASE 0
CPRINTLN(DEBUG_COMMUNICATIONS, "Attempting to send ", GET_COMM_ID_DEBUG_STRING(sTextMessageData.sCommData.eID), " silently to Michael.")
eSilentChar = SILENT_MICHAEL
BREAK
CASE 1
CPRINTLN(DEBUG_COMMUNICATIONS, "Attempting to send ", GET_COMM_ID_DEBUG_STRING(sTextMessageData.sCommData.eID), " silently to Franklin.")
eSilentChar = SILENT_FRANKLIN
BREAK
CASE 2
CPRINTLN(DEBUG_COMMUNICATIONS, "Attempting to send ", GET_COMM_ID_DEBUG_STRING(sTextMessageData.sCommData.eID), " silently to Trevor.")
eSilentChar = SILENT_TREVOR
BREAK
ENDSWITCH
IF SEND_SILENT_TEXT_MESSAGE_TO_PLAYER_CHARACTER ( sTextMessageData.sCommData.eNPCCharacter,
eSilentChar,
tTextLabel,
eLocked,
eCritical,
TXTMSG_AUTO_UNLOCK_AFTER_READ,
eReply,
ICON_STANDARD_TEXTMSG,
FALSE,
NO_BARTER_REQUIRED,
sTextMessageData.WhichCanCallSenderStatus)
CPRINTLN(DEBUG_COMMUNICATIONS, GET_COMM_ID_DEBUG_STRING(sTextMessageData.sCommData.eID), " was sent silently to a player character.")
bTextSent = TRUE
ENDIF
ENDIF
ENDREPEAT
IF bTextSent
CPRINTLN(DEBUG_COMMUNICATIONS, "Text message ", GET_COMM_ID_DEBUG_STRING(sTextMessageData.sCommData.eID), " sent.")
RETURN TRUE
ENDIF
ELSE
CPRINTLN(DEBUG_COMMUNICATIONS, "The player is not one of the receiving characters for text ", GET_COMM_ID_DEBUG_STRING(sTextMessageData.sCommData.eID), ". Failed to send.")
//Increment fail count for this text.
sTextMessageData.iFailCount++
CPRINTLN(DEBUG_COMMUNICATIONS, "Text failed count increased to ", sTextMessageData.iFailCount, ".")
RETURN FALSE
ENDIF
ENDIF
CPRINTLN(DEBUG_COMMUNICATIONS, "Failed to send the text message to any player characters.")
RETURN FALSE
ENDFUNC
FUNC BOOL PRIVATE_Attempt_Send_Queued_Email(CC_EmailData &sEmailData)
CPRINTLN(DEBUG_COMMUNICATIONS, "Attempting to send email ", GET_COMM_ID_DEBUG_STRING(sEmailData.sCommData.eID), ".")
//Is the cellphone available?
IF IS_PHONE_ONSCREEN()
OR IS_CELLPHONE_DISABLED()
OR IS_CALLING_ANY_CONTACT()
CPRINTLN(DEBUG_COMMUNICATIONS, "Could not send email ", GET_COMM_ID_DEBUG_STRING(sEmailData.sCommData.eID), " because the cellphone was busy.")
RETURN FALSE
ENDIF
//Is it safe to send this text?
IF NOT PRIVATE_Is_Safe_To_Start_Communication( sEmailData.sCommData.iPlayerCharBitset,
sEmailData.sCommData.eNPCCharacter,
sEmailData.sCommData.ePriority,
sEmailData.sCommData.eRestrictedAreaID,
sEmailData.sCommData.iSettings)
RETURN FALSE
ENDIF
//Run any custom checks bound to this text.
IF sEmailData.sCommData.eSendCheck != FLOW_CHECK_NONE
IF NOT DO_CUSTOM_FLOW_CHECK(sEmailData.sCommData.eSendCheck)
CPRINTLN(DEBUG_COMMUNICATIONS, "Could not start communication ", GET_COMM_ID_DEBUG_STRING(sEmailData.sCommData.eID), " because the custom send check ", GET_DEBUG_STRING_FOR_FLOW_CHECK_ID(sEmailData.sCommData.eSendCheck), " failed.")
RETURN FALSE
ENDIF
ENDIF
//Is the player in the restricted area?
IF sEmailData.sCommData.eRestrictedAreaID <> VID_BLANK
IF IS_PED_AT_VECTOR_ID(PLAYER_PED_ID(), sEmailData.sCommData.eRestrictedAreaID)
CPRINTLN(DEBUG_COMMUNICATIONS, "Could not send email ", GET_COMM_ID_DEBUG_STRING(sEmailData.sCommData.eID), " because the player is in the communication's restricted area.")
#IF IS_DEBUG_BUILD
//Display message on screen to ensure devs know what just happened.
PRINT_NOW("CC_R_AREA", DEFAULT_GOD_TEXT_TIME, 0)
#ENDIF
RETURN FALSE
ENDIF
ENDIF
EMAIL_THREAD_ENUMS eEmailThread
PRIVATE_Get_Email_Thread(sEmailData.sCommData.eID, eEmailThread)
INT iCharIndex
BOOL bSilent = FALSE
IF IS_BIT_SET(sEmailData.sCommData.iSettings, COMM_BIT_TXTMSG_NOT_CRITICAL)
CPRINTLN(DEBUG_COMMUNICATIONS, "Email was flagged to be sent silently.")
bSilent = TRUE
ENDIF
//Is the player one of the receiving characters.
IF IS_BIT_SET(sEmailData.sCommData.iPlayerCharBitset, GET_CURRENT_PLAYER_PED_INT())
OR bSilent
REPEAT 3 iCharIndex
IF IS_BIT_SET(sEmailData.sCommData.iPlayerCharBitset, iCharIndex)
CPRINTLN(DEBUG_COMMUNICATIONS,
"Attempting to send email ", GET_COMM_ID_DEBUG_STRING(sEmailData.sCommData.eID), " to ", GET_CHARSHEET_DISPLAY_STRING_FROM_CHARSHEET(INT_TO_ENUM(enumCharacterList, iCharIndex)), ".")
IF IS_STATIC_EMAIL_THREAD_ACTIVE(eEmailThread)
IF NOT IS_STATIC_EMAIL_THREAD_ENDED(eEmailThread)
PROGRESS_EMAIL_THREAD(ENUM_TO_INT(eEmailThread), bSilent)
CPRINTLN(DEBUG_COMMUNICATIONS, "Email thread was progressed successfully.")
RETURN TRUE
ELSE
CPRINTLN(DEBUG_COMMUNICATIONS, "The email thread to be progressed had already finished ", GET_COMM_ID_DEBUG_STRING(sEmailData.sCommData.eID), ". Failed to send.")
RETURN FALSE
ENDIF
ELSE
BEGIN_EMAIL_THREAD(eEmailThread, bSilent)
CPRINTLN(DEBUG_COMMUNICATIONS, "Email thread was started successfully.")
RETURN TRUE
ENDIF
ENDIF
ENDREPEAT
ENDIF
CPRINTLN(DEBUG_COMMUNICATIONS, "The player was not a valid character to receive email ", GET_COMM_ID_DEBUG_STRING(sEmailData.sCommData.eID), ". Failed to send.")
RETURN FALSE
ENDFUNC
PROC PRIVATE_Update_Friend_Timer_Resets_For_Call(enumCharacterList eCallerChar, enumCharacterList eReceiverChar)
IF eCallerChar <> eReceiverChar
enumFriend eCallerFriend = GET_FRIEND_FROM_CHAR(eCallerChar)
enumFriend eReceiverFriend = GET_FRIEND_FROM_CHAR(eReceiverChar)
// If both chars are valid friend chars, see if they have a friend connection
IF eCallerFriend <> NO_FRIEND
AND eReceiverFriend <> NO_FRIEND
enumFriendConnection eConnection = GET_CONNECTION_FROM_FRIENDS(eCallerFriend, eReceiverFriend)
// If they have a valid friend connection, reset the friend-last-contact timer
IF eConnection <> NO_FRIEND_CONNECTION
CPRINTLN(DEBUG_FRIENDS, "RESET_FRIEND_LAST_CONTACT_TIMER(", GetLabel_enumFriendConnection(eConnection), ", FRIEND_CONTACT_PHONE)")
RESTART_TIMER_NOW(g_savedGlobals.sFriendsData.g_FriendConnectData[eConnection].lastContactTimer)
g_SavedGlobals.sFriendsData.g_FriendConnectData[eConnection].lastContactType = FRIEND_CONTACT_PHONE
ENDIF
ENDIF
ENDIF
ENDPROC
//╒═════════════════════════════════════════════════════════════════════════════╕
//╞═══════════════════╡ Communication Queue Manipulation ╞═════════════════════╡
//╘═════════════════════════════════════════════════════════════════════════════╛
PROC PRIVATE_Set_New_Communication_Queue_Time(INT gameTime, CC_CommData &commData, BOOL isTextMessage = FALSE)
//If this is a replay text or end-of-mission phonecall then only queue for 1 seconds before resending.
IF commData.ePriority = CPR_VERY_HIGH
CPRINTLN(DEBUG_COMMUNICATIONS, "Setting requeue timer of ", 1000, " for high priority communication ", GET_COMM_ID_DEBUG_STRING(commData.eID), ".")
commData.iQueueTime = gameTime + 1000
ELIF isTextMessage
CPRINTLN(DEBUG_COMMUNICATIONS, "Setting requeue timer of ", 10000, " for text message ", GET_COMM_ID_DEBUG_STRING(commData.eID), ".")
commData.iQueueTime = gameTime + 10000
ELSE
CPRINTLN(DEBUG_COMMUNICATIONS, "Setting requeue timer of ", commData.iRequeueTime, " for communication ", GET_COMM_ID_DEBUG_STRING(commData.eID), ".")
commData.iQueueTime = gameTime + commData.iRequeueTime
ENDIF
ENDPROC
PROC PRIVATE_Update_Playable_Character_Priority_Level(enumCharacterList ePlayableCharacter)
INT index
CC_CommunicationPriority eNewPriority = CPR_VERY_LOW
//Check the character enum passed references a playable character.
IF NOT IS_PLAYER_PED_PLAYABLE(ePlayableCharacter)
SCRIPT_ASSERT("PRIVATE_Update_Playable_Character_Priority_Level: Character ENUM passed does not refer to a playable character. Could not update priorities.")
EXIT
ENDIF
#IF USE_CLF_DLC
//Iterate through all queued phonecalls.
REPEAT g_savedGlobalsClifford.sCommsControlData.iNoQueuedCalls index
//Is this call linked to the playable character we're querying?
IF IS_BIT_SET(g_savedGlobalsClifford.sCommsControlData.sQueuedCalls[index].sCommData.iPlayerCharBitset, ENUM_TO_INT(ePlayableCharacter))
//Is the priority of this call higher than highest found for this character so far?
IF ENUM_TO_INT(g_savedGlobalsClifford.sCommsControlData.sQueuedCalls[index].sCommData.ePriority) > ENUM_TO_INT(eNewPriority)
eNewPriority = g_savedGlobalsClifford.sCommsControlData.sQueuedCalls[index].sCommData.ePriority
ENDIF
ENDIF
ENDREPEAT
//Iterate through all queued texts.
int txtindex
REPEAT g_savedGlobalsClifford.sCommsControlData.iNoQueuedTexts txtindex
//Is this text linked to the playable character we're querying?
IF IS_BIT_SET(g_savedGlobalsClifford.sCommsControlData.sQueuedTexts[txtindex].sCommData.iPlayerCharBitset, ENUM_TO_INT(ePlayableCharacter))
//Is the priority of this text very high?
IF g_savedGlobalsClifford.sCommsControlData.sQueuedTexts[txtindex].sCommData.ePriority = CPR_VERY_HIGH
eNewPriority = CPR_VERY_HIGH
ENDIF
ENDIF
ENDREPEAT
#IF IS_DEBUG_BUILD
IF eNewPriority <> g_savedGlobalsClifford.sCommsControlData.eCharacterPriorityLevel[ePlayableCharacter]
CPRINTLN(DEBUG_COMMUNICATIONS, "Communication priority level for ",
GET_PLAYER_PED_STRING(ePlayableCharacter),
" changed from ",
PRIVATE_Get_Debug_String_For_Communication_Priority(g_savedGlobalsClifford.sCommsControlData.eCharacterPriorityLevel[ePlayableCharacter]),
" to ",
PRIVATE_Get_Debug_String_For_Communication_Priority(eNewPriority),
".")
ENDIF
#ENDIF
//Update the global priority array.
g_savedGlobalsClifford.sCommsControlData.eCharacterPriorityLevel[ePlayableCharacter] = eNewPriority
#ENDIF
#IF USE_NRM_DLC
//Iterate through all queued phonecalls.
REPEAT g_savedGlobalsnorman.sCommsControlData.iNoQueuedCalls index
//Is this call linked to the playable character we're querying?
IF IS_BIT_SET(g_savedGlobalsnorman.sCommsControlData.sQueuedCalls[index].sCommData.iPlayerCharBitset, ENUM_TO_INT(ePlayableCharacter))
//Is the priority of this call higher than highest found for this character so far?
IF ENUM_TO_INT(g_savedGlobalsnorman.sCommsControlData.sQueuedCalls[index].sCommData.ePriority) > ENUM_TO_INT(eNewPriority)
eNewPriority = g_savedGlobalsnorman.sCommsControlData.sQueuedCalls[index].sCommData.ePriority
ENDIF
ENDIF
ENDREPEAT
//Iterate through all queued texts.
int txtindex
REPEAT g_savedGlobalsnorman.sCommsControlData.iNoQueuedTexts txtindex
//Is this text linked to the playable character we're querying?
IF IS_BIT_SET(g_savedGlobalsnorman.sCommsControlData.sQueuedTexts[txtindex].sCommData.iPlayerCharBitset, ENUM_TO_INT(ePlayableCharacter))
//Is the priority of this text very high?
IF g_savedGlobalsnorman.sCommsControlData.sQueuedTexts[txtindex].sCommData.ePriority = CPR_VERY_HIGH
eNewPriority = CPR_VERY_HIGH
ENDIF
ENDIF
ENDREPEAT
#IF IS_DEBUG_BUILD
IF eNewPriority <> g_savedGlobalsnorman.sCommsControlData.eCharacterPriorityLevel[ePlayableCharacter]
CPRINTLN(DEBUG_COMMUNICATIONS, "Communication priority level for ",
GET_PLAYER_PED_STRING(ePlayableCharacter),
" changed from ",
PRIVATE_Get_Debug_String_For_Communication_Priority(g_savedGlobalsnorman.sCommsControlData.eCharacterPriorityLevel[ePlayableCharacter]),
" to ",
PRIVATE_Get_Debug_String_For_Communication_Priority(eNewPriority),
".")
ENDIF
#ENDIF
//Update the global priority array.
g_savedGlobalsnorman.sCommsControlData.eCharacterPriorityLevel[ePlayableCharacter] = eNewPriority
#ENDIF
#IF NOT USE_SP_DLC
//Iterate through all queued phonecalls.
REPEAT g_savedGlobals.sCommsControlData.iNoQueuedCalls index
//Is this call linked to the playable character we're querying?
IF IS_BIT_SET(g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.iPlayerCharBitset, ENUM_TO_INT(ePlayableCharacter))
//Is the priority of this call higher than highest found for this character so far?
IF ENUM_TO_INT(g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.ePriority) > ENUM_TO_INT(eNewPriority)
eNewPriority = g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.ePriority
ENDIF
ENDIF
ENDREPEAT
//Iterate through all queued texts.
int txtindex
REPEAT g_savedGlobals.sCommsControlData.iNoQueuedTexts txtindex
//Is this text linked to the playable character we're querying?
IF IS_BIT_SET(g_savedGlobals.sCommsControlData.sQueuedTexts[txtindex].sCommData.iPlayerCharBitset, ENUM_TO_INT(ePlayableCharacter))
//Is the priority of this text very high?
IF g_savedGlobals.sCommsControlData.sQueuedTexts[txtindex].sCommData.ePriority = CPR_VERY_HIGH
eNewPriority = CPR_VERY_HIGH
ENDIF
ENDIF
ENDREPEAT
#IF IS_DEBUG_BUILD
IF eNewPriority <> g_savedGlobals.sCommsControlData.eCharacterPriorityLevel[ePlayableCharacter]
CPRINTLN(DEBUG_COMMUNICATIONS, "Communication priority level for ",
GET_PLAYER_PED_STRING(ePlayableCharacter),
" changed from ",
PRIVATE_Get_Debug_String_For_Communication_Priority(g_savedGlobals.sCommsControlData.eCharacterPriorityLevel[ePlayableCharacter]),
" to ",
PRIVATE_Get_Debug_String_For_Communication_Priority(eNewPriority),
".")
ENDIF
#ENDIF
//Update the global priority array.
g_savedGlobals.sCommsControlData.eCharacterPriorityLevel[ePlayableCharacter] = eNewPriority
#ENDIF
ENDPROC
PROC PRIVATE_Remove_Call_From_Queue(INT iQueueIndex)
#IF USE_CLF_DLC
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobalsClifford.sCommsControlData.sQueuedCalls[iQueueIndex].sCommData.eID), " from the call queue.")
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Wiping call at index ", iQueueIndex, ".")
IF iQueueIndex < 0 OR iQueueIndex >= g_savedGlobalsClifford.sCommsControlData.iNoQueuedCalls
CWARNINGLN(DEBUG_COMMUNICATIONS, "Attempted to remove a call at an invalid queue index. Exiting remove command without further action.")
EXIT
ENDIF
INT index
INT iRemovedCallCharBitset
//Save the call's player character so we can update their priority level after removal.
iRemovedCallCharBitset = g_savedGlobalsClifford.sCommsControlData.sQueuedCalls[iQueueIndex].sCommData.iPlayerCharBitset
//Move all array positions up one place and overwrite the call we want to remove.
IF g_savedGlobalsClifford.sCommsControlData.iNoQueuedCalls > 1
FOR index = iQueueIndex TO (g_savedGlobalsClifford.sCommsControlData.iNoQueuedCalls-2)
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Overwriting call ", index, " with call ", index+1, ".")
g_savedGlobalsClifford.sCommsControlData.sQueuedCalls[index] = g_savedGlobalsClifford.sCommsControlData.sQueuedCalls[index+1]
ENDFOR
ENDIF
//Set the old last call in the queue to be blank data to be safe.
CC_CallData sBlankCallData
IF g_savedGlobalsClifford.sCommsControlData.iNoQueuedCalls > 0
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Setting call at index ", g_savedGlobalsClifford.sCommsControlData.iNoQueuedCalls-1, " to be blank.")
g_savedGlobalsClifford.sCommsControlData.sQueuedCalls[g_savedGlobalsClifford.sCommsControlData.iNoQueuedCalls-1] = sBlankCallData
g_savedGlobalsClifford.sCommsControlData.iNoQueuedCalls--
ENDIF
#ENDIF
#IF USE_NRM_DLC
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobalsnorman.sCommsControlData.sQueuedCalls[iQueueIndex].sCommData.eID), " from the call queue.")
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Wiping call at index ", iQueueIndex, ".")
IF iQueueIndex < 0 OR iQueueIndex >= g_savedGlobalsnorman.sCommsControlData.iNoQueuedCalls
CWARNINGLN(DEBUG_COMMUNICATIONS, "Attempted to remove a call at an invalid queue index. Exiting remove command without further action.")
EXIT
ENDIF
INT index
INT iRemovedCallCharBitset
//Save the call's player character so we can update their priority level after removal.
iRemovedCallCharBitset = g_savedGlobalsnorman.sCommsControlData.sQueuedCalls[iQueueIndex].sCommData.iPlayerCharBitset
//Move all array positions up one place and overwrite the call we want to remove.
IF g_savedGlobalsnorman.sCommsControlData.iNoQueuedCalls > 1
FOR index = iQueueIndex TO (g_savedGlobalsnorman.sCommsControlData.iNoQueuedCalls-2)
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Overwriting call ", index, " with call ", index+1, ".")
g_savedGlobalsnorman.sCommsControlData.sQueuedCalls[index] = g_savedGlobalsnorman.sCommsControlData.sQueuedCalls[index+1]
ENDFOR
ENDIF
//Set the old last call in the queue to be blank data to be safe.
CC_CallData sBlankCallData
IF g_savedGlobalsnorman.sCommsControlData.iNoQueuedCalls > 0
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Setting call at index ", g_savedGlobalsnorman.sCommsControlData.iNoQueuedCalls-1, " to be blank.")
g_savedGlobalsnorman.sCommsControlData.sQueuedCalls[g_savedGlobalsnorman.sCommsControlData.iNoQueuedCalls-1] = sBlankCallData
g_savedGlobalsnorman.sCommsControlData.iNoQueuedCalls--
ENDIF
#ENDIF
#IF NOT USE_SP_DLC
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[iQueueIndex].sCommData.eID), " from the call queue.")
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Wiping call at index ", iQueueIndex, ".")
IF iQueueIndex < 0 OR iQueueIndex >= g_savedGlobals.sCommsControlData.iNoQueuedCalls
CWARNINGLN(DEBUG_COMMUNICATIONS, "Attempted to remove a call at an invalid queue index. Exiting remove command without further action.")
EXIT
ENDIF
INT index
INT iRemovedCallCharBitset
//Save the call's player character so we can update their priority level after removal.
iRemovedCallCharBitset = g_savedGlobals.sCommsControlData.sQueuedCalls[iQueueIndex].sCommData.iPlayerCharBitset
//Move all array positions up one place and overwrite the call we want to remove.
IF g_savedGlobals.sCommsControlData.iNoQueuedCalls > 1
FOR index = iQueueIndex TO (g_savedGlobals.sCommsControlData.iNoQueuedCalls-2)
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Overwriting call ", index, " with call ", index+1, ".")
g_savedGlobals.sCommsControlData.sQueuedCalls[index] = g_savedGlobals.sCommsControlData.sQueuedCalls[index+1]
ENDFOR
ENDIF
//Set the old last call in the queue to be blank data to be safe.
CC_CallData sBlankCallData
IF g_savedGlobals.sCommsControlData.iNoQueuedCalls > 0
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Setting call at index ", g_savedGlobals.sCommsControlData.iNoQueuedCalls-1, " to be blank.")
g_savedGlobals.sCommsControlData.sQueuedCalls[g_savedGlobals.sCommsControlData.iNoQueuedCalls-1] = sBlankCallData
g_savedGlobals.sCommsControlData.iNoQueuedCalls--
ENDIF
#ENDIF
//Update character queue priority levels now that this communication is removed.
//Priority level may need to be dropped.
REPEAT 3 index
IF IS_BIT_SET(iRemovedCallCharBitset, index)
PRIVATE_Update_Playable_Character_Priority_Level(INT_TO_ENUM(enumCharacterList, index))
ENDIF
ENDREPEAT
ENDPROC
PROC PRIVATE_Remove_Text_From_Queue(INT iQueueIndex)
#IF USE_CLF_DLC
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing text ", GET_COMM_ID_DEBUG_STRING(g_savedGlobalsClifford.sCommsControlData.sQueuedTexts[iQueueIndex].sCommData.eID), " from the text message queue.")
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Wiping text at index ", iQueueIndex, ".")
IF iQueueIndex < 0 OR iQueueIndex >= g_savedGlobalsClifford.sCommsControlData.iNoQueuedTexts
CWARNINGLN(DEBUG_COMMUNICATIONS, "Attempted to remove a text at an invalid queue index. Exiting remove command without further action.")
EXIT
ENDIF
INT index
//Move all array positions up one place and overwrite the text message we want to remove.
IF g_savedGlobalsClifford.sCommsControlData.iNoQueuedTexts > 1
FOR index = iQueueIndex TO (g_savedGlobalsClifford.sCommsControlData.iNoQueuedTexts-2)
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Overwriting text ", index, " with text ", index+1, ".")
g_savedGlobalsClifford.sCommsControlData.sQueuedTexts[index] = g_savedGlobalsClifford.sCommsControlData.sQueuedTexts[index+1]
ENDFOR
ENDIF
//Set the old last text message in the queue to be blank data to be safe.
IF g_savedGlobalsClifford.sCommsControlData.iNoQueuedTexts > 0
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Setting text at index ", g_savedGlobalsClifford.sCommsControlData.iNoQueuedTexts-1, " to be blank.")
CC_TextMessageData sBlankTextMessageData
g_savedGlobalsClifford.sCommsControlData.sQueuedTexts[g_savedGlobalsClifford.sCommsControlData.iNoQueuedTexts-1] = sBlankTextMessageData
g_savedGlobalsClifford.sCommsControlData.iNoQueuedTexts--
ENDIF
#ENDIF
#IF USE_NRM_DLC
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing text ", GET_COMM_ID_DEBUG_STRING(g_savedGlobalsnorman.sCommsControlData.sQueuedTexts[iQueueIndex].sCommData.eID), " from the text message queue.")
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Wiping text at index ", iQueueIndex, ".")
IF iQueueIndex < 0 OR iQueueIndex >= g_savedGlobalsnorman.sCommsControlData.iNoQueuedTexts
CWARNINGLN(DEBUG_COMMUNICATIONS, "Attempted to remove a text at an invalid queue index. Exiting remove command without further action.")
EXIT
ENDIF
INT index
//Move all array positions up one place and overwrite the text message we want to remove.
IF g_savedGlobalsnorman.sCommsControlData.iNoQueuedTexts > 1
FOR index = iQueueIndex TO (g_savedGlobalsnorman.sCommsControlData.iNoQueuedTexts-2)
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Overwriting text ", index, " with text ", index+1, ".")
g_savedGlobalsnorman.sCommsControlData.sQueuedTexts[index] = g_savedGlobalsnorman.sCommsControlData.sQueuedTexts[index+1]
ENDFOR
ENDIF
//Set the old last text message in the queue to be blank data to be safe.
IF g_savedGlobalsnorman.sCommsControlData.iNoQueuedTexts > 0
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Setting text at index ", g_savedGlobalsnorman.sCommsControlData.iNoQueuedTexts-1, " to be blank.")
CC_TextMessageData sBlankTextMessageData
g_savedGlobalsnorman.sCommsControlData.sQueuedTexts[g_savedGlobalsnorman.sCommsControlData.iNoQueuedTexts-1] = sBlankTextMessageData
g_savedGlobalsnorman.sCommsControlData.iNoQueuedTexts--
ENDIF
#ENDIF
#IF NOT USE_SP_DLC
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing text ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedTexts[iQueueIndex].sCommData.eID), " from the text message queue.")
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Wiping text at index ", iQueueIndex, ".")
IF iQueueIndex < 0 OR iQueueIndex >= g_savedGlobals.sCommsControlData.iNoQueuedTexts
CWARNINGLN(DEBUG_COMMUNICATIONS, "Attempted to remove a text at an invalid queue index. Exiting remove command without further action.")
EXIT
ENDIF
INT index
//Move all array positions up one place and overwrite the text message we want to remove.
IF g_savedGlobals.sCommsControlData.iNoQueuedTexts > 1
FOR index = iQueueIndex TO (g_savedGlobals.sCommsControlData.iNoQueuedTexts-2)
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Overwriting text ", index, " with text ", index+1, ".")
g_savedGlobals.sCommsControlData.sQueuedTexts[index] = g_savedGlobals.sCommsControlData.sQueuedTexts[index+1]
ENDFOR
ENDIF
//Set the old last text message in the queue to be blank data to be safe.
IF g_savedGlobals.sCommsControlData.iNoQueuedTexts > 0
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Setting text at index ", g_savedGlobals.sCommsControlData.iNoQueuedTexts-1, " to be blank.")
CC_TextMessageData sBlankTextMessageData
g_savedGlobals.sCommsControlData.sQueuedTexts[g_savedGlobals.sCommsControlData.iNoQueuedTexts-1] = sBlankTextMessageData
g_savedGlobals.sCommsControlData.iNoQueuedTexts--
ENDIF
#ENDIF
//Update character queue priority levels in case this new text is the new highest priority communication.
//Going to all playable characters. Update all their priorities.
PRIVATE_Update_Playable_Character_Priority_Level(CHAR_MICHAEL)
PRIVATE_Update_Playable_Character_Priority_Level(CHAR_FRANKLIN)
PRIVATE_Update_Playable_Character_Priority_Level(CHAR_TREVOR)
ENDPROC
PROC PRIVATE_Remove_Email_From_Queue(INT iQueueIndex)
#IF USE_CLF_DLC
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing email ", GET_COMM_ID_DEBUG_STRING(g_savedGlobalsClifford.sCommsControlData.sQueuedEmails[iQueueIndex].sCommData.eID), " from the email queue.")
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Wiping email at index ", iQueueIndex, ".")
IF iQueueIndex < 0 OR iQueueIndex >= g_savedGlobalsClifford.sCommsControlData.iNoQueuedEmails
CWARNINGLN(DEBUG_COMMUNICATIONS, "Attempted to remove an email at an invalid queue index. Exiting remove command without further action.")
EXIT
ENDIF
INT index
//Move all array positions up one place and overwrite the email we want to remove.
IF g_savedGlobalsClifford.sCommsControlData.iNoQueuedEmails > 1
FOR index = iQueueIndex TO (g_savedGlobalsClifford.sCommsControlData.iNoQueuedEmails-2)
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Overwriting email ", index, " with email ", index+1, ".")
g_savedGlobalsClifford.sCommsControlData.sQueuedEmails[index] = g_savedGlobalsClifford.sCommsControlData.sQueuedEmails[index+1]
ENDFOR
ENDIF
//Set the old last text message in the queue to be blank data to be safe.
IF g_savedGlobalsClifford.sCommsControlData.iNoQueuedEmails > 0
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Setting email at index ", g_savedGlobalsClifford.sCommsControlData.iNoQueuedEmails-1, " to be blank.")
CC_EmailData sBlankEmailData
g_savedGlobalsClifford.sCommsControlData.sQueuedEmails[g_savedGlobalsClifford.sCommsControlData.iNoQueuedEmails-1] = sBlankEmailData
g_savedGlobalsClifford.sCommsControlData.iNoQueuedEmails--
ENDIF
#ENDIF
#IF USE_NRM_DLC
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing email ", GET_COMM_ID_DEBUG_STRING(g_savedGlobalsnorman.sCommsControlData.sQueuedEmails[iQueueIndex].sCommData.eID), " from the email queue.")
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Wiping email at index ", iQueueIndex, ".")
IF iQueueIndex < 0 OR iQueueIndex >= g_savedGlobalsnorman.sCommsControlData.iNoQueuedEmails
CWARNINGLN(DEBUG_COMMUNICATIONS, "Attempted to remove an email at an invalid queue index. Exiting remove command without further action.")
EXIT
ENDIF
INT index
//Move all array positions up one place and overwrite the email we want to remove.
IF g_savedGlobalsnorman.sCommsControlData.iNoQueuedEmails > 1
FOR index = iQueueIndex TO (g_savedGlobalsnorman.sCommsControlData.iNoQueuedEmails-2)
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Overwriting email ", index, " with email ", index+1, ".")
g_savedGlobalsnorman.sCommsControlData.sQueuedEmails[index] = g_savedGlobalsnorman.sCommsControlData.sQueuedEmails[index+1]
ENDFOR
ENDIF
//Set the old last text message in the queue to be blank data to be safe.
IF g_savedGlobalsnorman.sCommsControlData.iNoQueuedEmails > 0
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Setting email at index ", g_savedGlobalsnorman.sCommsControlData.iNoQueuedEmails-1, " to be blank.")
CC_EmailData sBlankEmailData
g_savedGlobalsnorman.sCommsControlData.sQueuedEmails[g_savedGlobalsnorman.sCommsControlData.iNoQueuedEmails-1] = sBlankEmailData
g_savedGlobalsnorman.sCommsControlData.iNoQueuedEmails--
ENDIF
#ENDIF
#IF NOT USE_SP_DLC
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing email ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedEmails[iQueueIndex].sCommData.eID), " from the email queue.")
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Wiping email at index ", iQueueIndex, ".")
IF iQueueIndex < 0 OR iQueueIndex >= g_savedGlobals.sCommsControlData.iNoQueuedEmails
CWARNINGLN(DEBUG_COMMUNICATIONS, "Attempted to remove an email at an invalid queue index. Exiting remove command without further action.")
EXIT
ENDIF
INT index
//Move all array positions up one place and overwrite the email we want to remove.
IF g_savedGlobals.sCommsControlData.iNoQueuedEmails > 1
FOR index = iQueueIndex TO (g_savedGlobals.sCommsControlData.iNoQueuedEmails-2)
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Overwriting email ", index, " with email ", index+1, ".")
g_savedGlobals.sCommsControlData.sQueuedEmails[index] = g_savedGlobals.sCommsControlData.sQueuedEmails[index+1]
ENDFOR
ENDIF
//Set the old last text message in the queue to be blank data to be safe.
IF g_savedGlobals.sCommsControlData.iNoQueuedEmails > 0
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Setting email at index ", g_savedGlobals.sCommsControlData.iNoQueuedEmails-1, " to be blank.")
CC_EmailData sBlankEmailData
g_savedGlobals.sCommsControlData.sQueuedEmails[g_savedGlobals.sCommsControlData.iNoQueuedEmails-1] = sBlankEmailData
g_savedGlobals.sCommsControlData.iNoQueuedEmails--
ENDIF
#ENDIF
ENDPROC
FUNC CC_CallData PRIVATE_Get_Call_Data_From_Communication_ID(CC_CommID paramCommID)
INT index
#IF USE_CLF_DLC
REPEAT g_savedGlobalsClifford.sCommsControlData.iNoQueuedCalls index
IF g_savedGlobalsClifford.sCommsControlData.sQueuedCalls[index].sCommData.eID = paramCommID
RETURN g_savedGlobalsClifford.sCommsControlData.sQueuedCalls[index]
ENDIF
ENDREPEAT
#ENDIF
#IF USE_NRM_DLC
REPEAT g_savedGlobalsnorman.sCommsControlData.iNoQueuedCalls index
IF g_savedGlobalsnorman.sCommsControlData.sQueuedCalls[index].sCommData.eID = paramCommID
RETURN g_savedGlobalsnorman.sCommsControlData.sQueuedCalls[index]
ENDIF
ENDREPEAT
#ENDIF
#IF NOT USE_SP_DLC
REPEAT g_savedGlobals.sCommsControlData.iNoQueuedCalls index
IF g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.eID = paramCommID
RETURN g_savedGlobals.sCommsControlData.sQueuedCalls[index]
ENDIF
ENDREPEAT
#ENDIF
CC_CallData sEmptyCallData
RETURN sEmptyCallData //Return an empty struct if no data can be found.
ENDFUNC
FUNC CC_TextMessageData PRIVATE_Get_Text_Message_Data_From_Communication_ID(CC_CommID paramCommID)
INT index
#IF USE_CLF_DLC
REPEAT g_savedGlobalsClifford.sCommsControlData.iNoQueuedTexts index
IF g_savedGlobalsClifford.sCommsControlData.sQueuedTexts[index].sCommData.eID = paramCommID
RETURN g_savedGlobalsClifford.sCommsControlData.sQueuedTexts[index]
ENDIF
ENDREPEAT
#ENDIF
#IF USE_NRM_DLC
REPEAT g_savedGlobalsnorman.sCommsControlData.iNoQueuedTexts index
IF g_savedGlobalsnorman.sCommsControlData.sQueuedTexts[index].sCommData.eID = paramCommID
RETURN g_savedGlobalsnorman.sCommsControlData.sQueuedTexts[index]
ENDIF
ENDREPEAT
#ENDIF
#IF NOT USE_SP_DLC
REPEAT g_savedGlobals.sCommsControlData.iNoQueuedTexts index
IF g_savedGlobals.sCommsControlData.sQueuedTexts[index].sCommData.eID = paramCommID
RETURN g_savedGlobals.sCommsControlData.sQueuedTexts[index]
ENDIF
ENDREPEAT
#ENDIF
CC_TextMessageData sEmptyTextData
RETURN sEmptyTextData //Return an empty struct if no data can be found.
ENDFUNC
FUNC CC_EmailData PRIVATE_Get_Email_Data_From_Communication_ID(CC_CommID paramCommID)
INT index
#IF USE_CLF_DLC
REPEAT g_savedGlobalsClifford.sCommsControlData.iNoQueuedEmails index
IF g_savedGlobalsClifford.sCommsControlData.sQueuedEmails[index].sCommData.eID = paramCommID
RETURN g_savedGlobalsClifford.sCommsControlData.sQueuedEmails[index]
ENDIF
ENDREPEAT
#ENDIF
#IF USE_NRM_DLC
REPEAT g_savedGlobalsnorman.sCommsControlData.iNoQueuedEmails index
IF g_savedGlobalsnorman.sCommsControlData.sQueuedEmails[index].sCommData.eID = paramCommID
RETURN g_savedGlobalsnorman.sCommsControlData.sQueuedEmails[index]
ENDIF
ENDREPEAT
#ENDIF
#IF NOT USE_SP_DLC
REPEAT g_savedGlobals.sCommsControlData.iNoQueuedEmails index
IF g_savedGlobals.sCommsControlData.sQueuedEmails[index].sCommData.eID = paramCommID
RETURN g_savedGlobals.sCommsControlData.sQueuedEmails[index]
ENDIF
ENDREPEAT
#ENDIF
CC_EmailData sEmptyEmailData
RETURN sEmptyEmailData //Return an empty struct if no data can be found.
ENDFUNC
FUNC INT PRIVATE_Get_Call_Queue_Index_From_Communication_ID(CC_CommID paramCommID)
INT index
#IF USE_CLF_DLC
REPEAT g_savedGlobalsClifford.sCommsControlData.iNoQueuedCalls index
IF g_savedGlobalsClifford.sCommsControlData.sQueuedCalls[index].sCommData.eID = paramCommID
RETURN index
ENDIF
ENDREPEAT
#ENDIF
#IF USE_NRM_DLC
REPEAT g_savedGlobalsnorman.sCommsControlData.iNoQueuedCalls index
IF g_savedGlobalsnorman.sCommsControlData.sQueuedCalls[index].sCommData.eID = paramCommID
RETURN index
ENDIF
ENDREPEAT
#ENDIF
#IF NOT USE_SP_DLC
REPEAT g_savedGlobals.sCommsControlData.iNoQueuedCalls index
IF g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.eID = paramCommID
RETURN index
ENDIF
ENDREPEAT
#ENDIF
RETURN -1
ENDFUNC
FUNC INT PRIVATE_Get_Text_Message_Queue_Index_From_Communication_ID(CC_CommID paramCommID)
INT index
#IF USE_CLF_DLC
REPEAT g_savedGlobalsClifford.sCommsControlData.iNoQueuedTexts index
IF g_savedGlobalsClifford.sCommsControlData.sQueuedTexts[index].sCommData.eID = paramCommID
RETURN index
ENDIF
ENDREPEAT
#ENDIF
#IF USE_NRM_DLC
REPEAT g_savedGlobalsnorman.sCommsControlData.iNoQueuedTexts index
IF g_savedGlobalsnorman.sCommsControlData.sQueuedTexts[index].sCommData.eID = paramCommID
RETURN index
ENDIF
ENDREPEAT
#ENDIF
#IF NOT USE_SP_DLC
REPEAT g_savedGlobals.sCommsControlData.iNoQueuedTexts index
IF g_savedGlobals.sCommsControlData.sQueuedTexts[index].sCommData.eID = paramCommID
RETURN index
ENDIF
ENDREPEAT
#ENDIF
RETURN -1
ENDFUNC
FUNC INT PRIVATE_Get_Email_Queue_Index_From_Communication_ID(CC_CommID paramCommID)
INT index
#IF USE_CLF_DLC
REPEAT g_savedGlobalsClifford.sCommsControlData.iNoQueuedEmails index
IF g_savedGlobalsClifford.sCommsControlData.sQueuedEmails[index].sCommData.eID = paramCommID
RETURN index
ENDIF
ENDREPEAT
#ENDIF
#IF USE_NRM_DLC
REPEAT g_savedGlobalsnorman.sCommsControlData.iNoQueuedEmails index
IF g_savedGlobalsnorman.sCommsControlData.sQueuedEmails[index].sCommData.eID = paramCommID
RETURN index
ENDIF
ENDREPEAT
#ENDIF
#IF NOT USE_SP_DLC
REPEAT g_savedGlobals.sCommsControlData.iNoQueuedEmails index
IF g_savedGlobals.sCommsControlData.sQueuedEmails[index].sCommData.eID = paramCommID
RETURN index
ENDIF
ENDREPEAT
#ENDIF
RETURN -1
ENDFUNC
FUNC CC_CommunicationStatus PRIVATE_Get_Phonecall_Status(CC_CommID paramCommID, INT iGameTime)
//First check that this comminication ID is queued.
CC_CallData sCallData = PRIVATE_Get_Call_Data_From_Communication_ID(paramCommID)
IF sCallData.sCommData.eID <> paramCommID
SCRIPT_ASSERT("PRIVATE_Get_Phonecall_Status: Tried to get the phonecall status of an ID that does not point to a phonecall.")
RETURN CS_ERROR
ENDIF
//Check we are currently a singleplayer character.
IF NOT IS_PLAYER_PED_PLAYABLE(GET_CURRENT_PLAYER_PED_ENUM())
RETURN CS_INACTIVE
ENDIF
//Is this communication ID registered as being in progress?
IF g_iCallInProgress <> -1
#IF USE_CLF_DLC
IF g_savedGlobalsClifford.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID = paramCommID
RETURN CS_IN_PROGRESS
ENDIF
#ENDIF
#IF USE_NRM_DLC
IF g_savedGlobalsnorman.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID = paramCommID
RETURN CS_IN_PROGRESS
ENDIF
#ENDIF
#IF NOT USE_SP_DLC
IF g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID = paramCommID
RETURN CS_IN_PROGRESS
ENDIF
#ENDIF
ENDIF
//Are we a valid character for this call.
//If so we'll need to check the priority.
BOOL bCorrectCharacter = FALSE
IF IS_BIT_SET(sCallData.sCommData.iPlayerCharBitset, GET_CURRENT_PLAYER_PED_INT())
bCorrectCharacter = TRUE
ENDIF
//Check if we're waiting for a timer.
IF sCallData.sCommData.iQueueTime > iGameTime
RETURN CS_WAITING_FOR_QUEUE_TIMER
ENDIF
IF bCorrectCharacter
#IF USE_CLF_DLC
IF ENUM_TO_INT(sCallData.sCommData.ePriority) < ENUM_TO_INT(g_savedGlobalsClifford.sCommsControlData.eCharacterPriorityLevel[GET_CURRENT_PLAYER_PED_INT()])
RETURN CS_WAITING_FOR_HIGHER_PRIORITY
ENDIF
#ENDIF
#IF USE_NRM_DLC
IF ENUM_TO_INT(sCallData.sCommData.ePriority) < ENUM_TO_INT(g_savedGlobalsnorman.sCommsControlData.eCharacterPriorityLevel[GET_CURRENT_PLAYER_PED_INT()])
RETURN CS_WAITING_FOR_HIGHER_PRIORITY
ENDIF
#ENDIF
#IF NOT USE_SP_DLC
IF ENUM_TO_INT(sCallData.sCommData.ePriority) < ENUM_TO_INT(g_savedGlobals.sCommsControlData.eCharacterPriorityLevel[GET_CURRENT_PLAYER_PED_INT()])
RETURN CS_WAITING_FOR_HIGHER_PRIORITY
ENDIF
#ENDIF
ENDIF
IF g_iCharWaitTime[sCallData.sCommData.eNPCCharacter] > iGameTime
RETURN CS_WAITING_FOR_CHARACTER_DELAY
ENDIF
IF g_iGlobalWaitTime > iGameTime
RETURN CS_WAITING_FOR_GLOBAL_DELAY
ENDIF
RETURN CS_INACTIVE
ENDFUNC
FUNC CC_CommunicationStatus PRIVATE_Get_Text_Message_Status(CC_CommID paramCommID, INT iGameTime)
CC_TextMessageData sTextData = PRIVATE_Get_Text_Message_Data_From_Communication_ID(paramCommID)
IF sTextData.sCommData.eID <> paramCommID
SCRIPT_ASSERT("PRIVATE_Get_Text_Message_Status: Tried to get the text message status of an ID that does not point to a text message.")
RETURN CS_ERROR
ENDIF
//Check we are currently a singleplayer character.
IF NOT IS_PLAYER_PED_PLAYABLE(GET_CURRENT_PLAYER_PED_ENUM())
RETURN CS_ERROR
ENDIF
//Are we a valid character for this text.
//If so we'll need to check the priority.
BOOL bCorrectCharacter = FALSE
IF IS_BIT_SET(sTextData.sCommData.iPlayerCharBitset, GET_CURRENT_PLAYER_PED_INT())
bCorrectCharacter = TRUE
ENDIF
//Check if we're waiting for a timer.
IF sTextData.sCommData.iQueueTime > iGameTime
RETURN CS_WAITING_FOR_QUEUE_TIMER
ENDIF
IF bCorrectCharacter
#IF USE_CLF_DLC
IF ENUM_TO_INT(sTextData.sCommData.ePriority) < ENUM_TO_INT(g_savedGlobalsClifford.sCommsControlData.eCharacterPriorityLevel[GET_CURRENT_PLAYER_PED_INT()])
RETURN CS_WAITING_FOR_HIGHER_PRIORITY
ENDIF
#ENDIF
#IF USE_NRM_DLC
IF ENUM_TO_INT(sTextData.sCommData.ePriority) < ENUM_TO_INT(g_savedGlobalsnorman.sCommsControlData.eCharacterPriorityLevel[GET_CURRENT_PLAYER_PED_INT()])
RETURN CS_WAITING_FOR_HIGHER_PRIORITY
ENDIF
#ENDIF
#IF NOT USE_SP_DLC
IF ENUM_TO_INT(sTextData.sCommData.ePriority) < ENUM_TO_INT(g_savedGlobals.sCommsControlData.eCharacterPriorityLevel[GET_CURRENT_PLAYER_PED_INT()])
RETURN CS_WAITING_FOR_HIGHER_PRIORITY
ENDIF
#ENDIF
ENDIF
IF g_iCharWaitTime[sTextData.sCommData.eNPCCharacter] > iGameTime
RETURN CS_WAITING_FOR_CHARACTER_DELAY
ENDIF
IF g_iGlobalWaitTime > iGameTime
RETURN CS_WAITING_FOR_GLOBAL_DELAY
ENDIF
RETURN CS_INACTIVE
ENDFUNC
FUNC CC_CommunicationStatus PRIVATE_Get_Email_Status(CC_CommID paramCommID, INT iGameTime)
CC_EmailData sEmailData = PRIVATE_Get_Email_Data_From_Communication_ID(paramCommID)
IF sEmailData.sCommData.eID <> paramCommID
SCRIPT_ASSERT("PRIVATE_Get_Email_Status: Tried to get the email status of an ID that does not point to an email.")
RETURN CS_ERROR
ENDIF
//Check we are currently a singleplayer character.
IF NOT IS_PLAYER_PED_PLAYABLE(GET_CURRENT_PLAYER_PED_ENUM())
RETURN CS_ERROR
ENDIF
//Are we a valid character for this email.
//If so we'll need to check the priority.
BOOL bCorrectCharacter = FALSE
IF IS_BIT_SET(sEmailData.sCommData.iPlayerCharBitset, GET_CURRENT_PLAYER_PED_INT())
bCorrectCharacter = TRUE
ENDIF
//Check if we're waiting for a timer.
IF sEmailData.sCommData.iQueueTime > iGameTime
RETURN CS_WAITING_FOR_QUEUE_TIMER
ENDIF
IF bCorrectCharacter
#IF USE_CLF_DLC
IF ENUM_TO_INT(sEmailData.sCommData.ePriority) < ENUM_TO_INT(g_savedGlobalsClifford.sCommsControlData.eCharacterPriorityLevel[GET_CURRENT_PLAYER_PED_INT()])
RETURN CS_WAITING_FOR_HIGHER_PRIORITY
ENDIF
#ENDIF
#IF USE_NRM_DLC
IF ENUM_TO_INT(sEmailData.sCommData.ePriority) < ENUM_TO_INT(g_savedGlobalsnorman.sCommsControlData.eCharacterPriorityLevel[GET_CURRENT_PLAYER_PED_INT()])
RETURN CS_WAITING_FOR_HIGHER_PRIORITY
ENDIF
#ENDIF
#IF NOT USE_SP_DLC
IF ENUM_TO_INT(sEmailData.sCommData.ePriority) < ENUM_TO_INT(g_savedGlobals.sCommsControlData.eCharacterPriorityLevel[GET_CURRENT_PLAYER_PED_INT()])
RETURN CS_WAITING_FOR_HIGHER_PRIORITY
ENDIF
#ENDIF
ENDIF
IF sEmailData.sCommData.eNPCCharacter != CHAR_BLANK_ENTRY
IF g_iCharWaitTime[sEmailData.sCommData.eNPCCharacter] > iGameTime
RETURN CS_WAITING_FOR_CHARACTER_DELAY
ENDIF
ENDIF
IF g_iGlobalWaitTime > iGameTime
RETURN CS_WAITING_FOR_GLOBAL_DELAY
ENDIF
RETURN CS_INACTIVE
ENDFUNC
/// PURPOSE: Resets the communication controller's last call response data.
///
PROC PRIVATE_Clear_Last_Call_Data()
#IF USE_CLF_DLC
g_savedGlobalsClifford.sCommsControlData.eLastCompletedCall = COMM_NONE
g_savedGlobalsClifford.sCommsControlData.bLastCallHadResponse = FALSE
g_savedGlobalsClifford.sCommsControlData.bLastCallResponse = FALSE
#ENDIF
#IF USE_NRM_DLC
g_savedGlobalsnorman.sCommsControlData.eLastCompletedCall = COMM_NONE
g_savedGlobalsnorman.sCommsControlData.bLastCallHadResponse = FALSE
g_savedGlobalsnorman.sCommsControlData.bLastCallResponse = FALSE
#ENDIF
#IF NOT USE_SP_DLC
g_savedGlobals.sCommsControlData.eLastCompletedCall = COMM_NONE
g_savedGlobals.sCommsControlData.bLastCallHadResponse = FALSE
g_savedGlobals.sCommsControlData.bLastCallResponse = FALSE
#ENDIF
ENDPROC
/// PURPOSE: Resets the communication controller's last text message response data.
///
PROC PRIVATE_Clear_Last_Text_Data()
#IF USE_CLF_DLC
g_savedGlobalsClifford.sCommsControlData.eLastCompletedText = COMM_NONE
g_savedGlobalsClifford.sCommsControlData.bLastTextHadResponse = FALSE
g_savedGlobalsClifford.sCommsControlData.bLastTextResponse = FALSE
#ENDIF
#IF USE_NRM_DLC
g_savedGlobalsnorman.sCommsControlData.eLastCompletedText = COMM_NONE
g_savedGlobalsnorman.sCommsControlData.bLastTextHadResponse = FALSE
g_savedGlobalsnorman.sCommsControlData.bLastTextResponse = FALSE
#ENDIF
#IF NOT USE_SP_DLC
g_savedGlobals.sCommsControlData.eLastCompletedText = COMM_NONE
g_savedGlobals.sCommsControlData.bLastTextHadResponse = FALSE
g_savedGlobals.sCommsControlData.bLastTextResponse = FALSE
#ENDIF
ENDPROC
/// PURPOSE: Resets the communication controller's last email data.
///
PROC PRIVATE_Clear_Last_Email_Data()
#IF USE_CLF_DLC
g_savedGlobalsClifford.sCommsControlData.eLastCompletedEmail = COMM_NONE
#ENDIF
#IF USE_NRM_DLC
g_savedGlobalsnorman.sCommsControlData.eLastCompletedEmail = COMM_NONE
#ENDIF
#IF NOT USE_SP_DLC
g_savedGlobals.sCommsControlData.eLastCompletedEmail = COMM_NONE
#ENDIF
ENDPROC
//╒═════════════════════════════════════════════════════════════════════════════╕
//╞═══════════════════╡ Missed Call Functions/Procedures ╞═════════════════════╡
//╘═════════════════════════════════════════════════════════════════════════════╛
FUNC BOOL PRIVATE_Is_Missed_Call_Already_Registered(CC_CommID paramMissedCallID)
INT index
#IF USE_CLF_DLC
REPEAT g_savedGlobalsClifford.sCommsControlData.iNoMissedCalls index
IF g_savedGlobalsClifford.sCommsControlData.sMissedCalls[index].sCommData.eID = paramMissedCallID
RETURN TRUE
ENDIF
ENDREPEAT
#ENDIF
#IF USE_NRM_DLC
REPEAT g_savedGlobalsnorman.sCommsControlData.iNoMissedCalls index
IF g_savedGlobalsnorman.sCommsControlData.sMissedCalls[index].sCommData.eID = paramMissedCallID
RETURN TRUE
ENDIF
ENDREPEAT
#ENDIF
#IF NOT USE_SP_DLC
REPEAT g_savedGlobals.sCommsControlData.iNoMissedCalls index
IF g_savedGlobals.sCommsControlData.sMissedCalls[index].sCommData.eID = paramMissedCallID
RETURN TRUE
ENDIF
ENDREPEAT
#ENDIF
RETURN FALSE
ENDFUNC
PROC PRIVATE_Add_Call_To_Missed_Call_Queue(CC_CallData &sCallData)
CPRINTLN(DEBUG_COMMUNICATIONS, "Adding call ", GET_COMM_ID_DEBUG_STRING(sCallData.sCommData.eID), " to the missed call queue.")
//Check if the missed call is already registered.
IF NOT PRIVATE_Is_Missed_Call_Already_Registered(sCallData.sCommData.eID)
#IF USE_CLF_DLC
//Check the queue isn't full.
IF g_savedGlobalsClifford.sCommsControlData.iNoMissedCalls < CC_MAX_MISSED_CALLS
//Add data to queue.
g_savedGlobalsClifford.sCommsControlData.sMissedCalls[g_savedGlobalsClifford.sCommsControlData.iNoMissedCalls] = sCallData
g_savedGlobalsClifford.sCommsControlData.iNoMissedCalls++
//Set a missed caller status on the in-game phone for the missed call contact.
SET_CONTACT_AS_MISSED_CALLER(sCallData.sCommData.eNPCCharacter)
ELSE
SCRIPT_ASSERT("PRIVATE_Add_Call_To_Missed_Call_Queue: Tried to add a call to the missed call queue, but it was full. CC_MAX_MISSED_CALLS probably needs increasing.")
ENDIF
#ENDIF
#IF USE_NRM_DLC
//Check the queue isn't full.
IF g_savedGlobalsnorman.sCommsControlData.iNoMissedCalls < CC_MAX_MISSED_CALLS
//Add data to queue.
g_savedGlobalsnorman.sCommsControlData.sMissedCalls[g_savedGlobalsnorman.sCommsControlData.iNoMissedCalls] = sCallData
g_savedGlobalsnorman.sCommsControlData.iNoMissedCalls++
//Set a missed caller status on the in-game phone for the missed call contact.
SET_CONTACT_AS_MISSED_CALLER(sCallData.sCommData.eNPCCharacter)
ELSE
SCRIPT_ASSERT("PRIVATE_Add_Call_To_Missed_Call_Queue: Tried to add a call to the missed call queue, but it was full. CC_MAX_MISSED_CALLS probably needs increasing.")
ENDIF
#ENDIF
#IF NOT USE_SP_DLC
//Check the queue isn't full.
IF g_savedGlobals.sCommsControlData.iNoMissedCalls < CC_MAX_MISSED_CALLS
//Add data to queue.
g_savedGlobals.sCommsControlData.sMissedCalls[g_savedGlobals.sCommsControlData.iNoMissedCalls] = sCallData
g_savedGlobals.sCommsControlData.iNoMissedCalls++
//Set a missed caller status on the in-game phone for the missed call contact.
SET_CONTACT_AS_MISSED_CALLER(sCallData.sCommData.eNPCCharacter)
ELSE
SCRIPT_ASSERT("PRIVATE_Add_Call_To_Missed_Call_Queue: Tried to add a call to the missed call queue, but it was full. CC_MAX_MISSED_CALLS probably needs increasing.")
ENDIF
#ENDIF
ELSE
CPRINTLN(DEBUG_COMMUNICATIONS, "The call was already in the missed call queue.")
ENDIF
ENDPROC
PROC PRIVATE_Remove_Call_From_Missed_Call_Queue(CC_CommID paramMissedCallID)
CC_CallData sBlankCallData
INT index
#IF USE_CLF_DLC
REPEAT g_savedGlobalsClifford.sCommsControlData.iNoMissedCalls index
IF g_savedGlobalsClifford.sCommsControlData.sMissedCalls[index].sCommData.eID = paramMissedCallID
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobalsClifford.sCommsControlData.sMissedCalls[index].sCommData.eID), " from the missed call queue.")
//Clear the missed caller status of the missed call contact.
CLEAR_MISSED_CALLER_STATUS_FOR_CONTACT(g_savedGlobalsClifford.sCommsControlData.sMissedCalls[index].sCommData.eNPCCharacter)
//Move all array positions up one place and overwrite the call we want to remove.
INT index2
FOR index2 = index TO (g_savedGlobalsClifford.sCommsControlData.iNoMissedCalls-2)
g_savedGlobalsClifford.sCommsControlData.sMissedCalls[index2] = g_savedGlobalsClifford.sCommsControlData.sMissedCalls[index2+1]
ENDFOR
//Set the old last missed call in the queue to be blank data to be safe.
g_savedGlobalsClifford.sCommsControlData.sMissedCalls[g_savedGlobalsClifford.sCommsControlData.iNoMissedCalls-1] = sBlankCallData
//Reduce the counter tracking the number of missed calls in the queue.
g_savedGlobalsClifford.sCommsControlData.iNoMissedCalls--
EXIT
ENDIF
ENDREPEAT
#ENDIF
#IF USE_NRM_DLC
REPEAT g_savedGlobalsnorman.sCommsControlData.iNoMissedCalls index
IF g_savedGlobalsnorman.sCommsControlData.sMissedCalls[index].sCommData.eID = paramMissedCallID
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobalsnorman.sCommsControlData.sMissedCalls[index].sCommData.eID), " from the missed call queue.")
//Clear the missed caller status of the missed call contact.
CLEAR_MISSED_CALLER_STATUS_FOR_CONTACT(g_savedGlobalsnorman.sCommsControlData.sMissedCalls[index].sCommData.eNPCCharacter)
//Move all array positions up one place and overwrite the call we want to remove.
INT index2
FOR index2 = index TO (g_savedGlobalsnorman.sCommsControlData.iNoMissedCalls-2)
g_savedGlobalsnorman.sCommsControlData.sMissedCalls[index2] = g_savedGlobalsnorman.sCommsControlData.sMissedCalls[index2+1]
ENDFOR
//Set the old last missed call in the queue to be blank data to be safe.
g_savedGlobalsnorman.sCommsControlData.sMissedCalls[g_savedGlobalsnorman.sCommsControlData.iNoMissedCalls-1] = sBlankCallData
//Reduce the counter tracking the number of missed calls in the queue.
g_savedGlobalsnorman.sCommsControlData.iNoMissedCalls--
EXIT
ENDIF
ENDREPEAT
#ENDIF
#IF NOT USE_SP_DLC
REPEAT g_savedGlobals.sCommsControlData.iNoMissedCalls index
IF g_savedGlobals.sCommsControlData.sMissedCalls[index].sCommData.eID = paramMissedCallID
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sMissedCalls[index].sCommData.eID), " from the missed call queue.")
//Clear the missed caller status of the missed call contact.
CLEAR_MISSED_CALLER_STATUS_FOR_CONTACT(g_savedGlobals.sCommsControlData.sMissedCalls[index].sCommData.eNPCCharacter)
//Move all array positions up one place and overwrite the call we want to remove.
INT index2
FOR index2 = index TO (g_savedGlobals.sCommsControlData.iNoMissedCalls-2)
g_savedGlobals.sCommsControlData.sMissedCalls[index2] = g_savedGlobals.sCommsControlData.sMissedCalls[index2+1]
ENDFOR
//Set the old last missed call in the queue to be blank data to be safe.
g_savedGlobals.sCommsControlData.sMissedCalls[g_savedGlobals.sCommsControlData.iNoMissedCalls-1] = sBlankCallData
//Reduce the counter tracking the number of missed calls in the queue.
g_savedGlobals.sCommsControlData.iNoMissedCalls--
EXIT
ENDIF
ENDREPEAT
#ENDIF
ENDPROC
FUNC INT PRIVATE_Get_Missed_Call_Queue_Index(CC_CommID paramMissedCallID)
INT index
#IF USE_CLF_DLC
REPEAT g_savedGlobalsClifford.sCommsControlData.iNoQueuedCalls index
IF g_savedGlobalsClifford.sCommsControlData.sQueuedCalls[index].sCommData.eID = paramMissedCallID
RETURN index
ENDIF
ENDREPEAT
#ENDIF
#IF USE_NRM_DLC
REPEAT g_savedGlobalsnorman.sCommsControlData.iNoQueuedCalls index
IF g_savedGlobalsnorman.sCommsControlData.sQueuedCalls[index].sCommData.eID = paramMissedCallID
RETURN index
ENDIF
ENDREPEAT
#ENDIF
#IF NOT USE_SP_DLC
REPEAT g_savedGlobals.sCommsControlData.iNoQueuedCalls index
IF g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.eID = paramMissedCallID
RETURN index
ENDIF
ENDREPEAT
#ENDIF
RETURN -1
ENDFUNC
//
// Chat Call Functions/Procedures
//
PROC PRIVATE_Remove_Call_From_Chat_Call_Queue(CC_CommID paramCallID)
CC_CallData sBlankCallData
INT index
#IF USE_CLF_DLC
REPEAT g_savedGlobalsClifford.sCommsControlData.iNoChatCalls index
IF g_savedGlobalsClifford.sCommsControlData.sChatCalls[index].sCommData.eID = paramCallID
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobalsClifford.sCommsControlData.sChatCalls[index].sCommData.eID), " from the chat call queue.")
//Move all array positions up one place and overwrite the call we want to remove.
INT index2
FOR index2 = index TO (g_savedGlobalsClifford.sCommsControlData.iNoChatCalls-2)
g_savedGlobalsClifford.sCommsControlData.sChatCalls[index2] = g_savedGlobalsClifford.sCommsControlData.sChatCalls[index2+1]
ENDFOR
//Set the old last chat call in the queue to be blank data to be safe.
g_savedGlobalsClifford.sCommsControlData.sChatCalls[g_savedGlobalsClifford.sCommsControlData.iNoChatCalls-1] = sBlankCallData
//Reduce the counter tracking the number of missed calls in the queue.
g_savedGlobalsClifford.sCommsControlData.iNoChatCalls--
EXIT
ENDIF
ENDREPEAT
#ENDIF
#IF USE_NRM_DLC
REPEAT g_savedGlobalsnorman.sCommsControlData.iNoChatCalls index
IF g_savedGlobalsnorman.sCommsControlData.sChatCalls[index].sCommData.eID = paramCallID
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobalsnorman.sCommsControlData.sChatCalls[index].sCommData.eID), " from the chat call queue.")
//Move all array positions up one place and overwrite the call we want to remove.
INT index2
FOR index2 = index TO (g_savedGlobalsnorman.sCommsControlData.iNoChatCalls-2)
g_savedGlobalsnorman.sCommsControlData.sChatCalls[index2] = g_savedGlobalsnorman.sCommsControlData.sChatCalls[index2+1]
ENDFOR
//Set the old last chat call in the queue to be blank data to be safe.
g_savedGlobalsnorman.sCommsControlData.sChatCalls[g_savedGlobalsnorman.sCommsControlData.iNoChatCalls-1] = sBlankCallData
//Reduce the counter tracking the number of missed calls in the queue.
g_savedGlobalsnorman.sCommsControlData.iNoChatCalls--
EXIT
ENDIF
ENDREPEAT
#ENDIF
#IF NOT USE_SP_DLC
REPEAT g_savedGlobals.sCommsControlData.iNoChatCalls index
IF g_savedGlobals.sCommsControlData.sChatCalls[index].sCommData.eID = paramCallID
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sChatCalls[index].sCommData.eID), " from the chat call queue.")
//Move all array positions up one place and overwrite the call we want to remove.
INT index2
FOR index2 = index TO (g_savedGlobals.sCommsControlData.iNoChatCalls-2)
g_savedGlobals.sCommsControlData.sChatCalls[index2] = g_savedGlobals.sCommsControlData.sChatCalls[index2+1]
ENDFOR
//Set the old last chat call in the queue to be blank data to be safe.
g_savedGlobals.sCommsControlData.sChatCalls[g_savedGlobals.sCommsControlData.iNoChatCalls-1] = sBlankCallData
//Reduce the counter tracking the number of missed calls in the queue.
g_savedGlobals.sCommsControlData.iNoChatCalls--
EXIT
ENDIF
ENDREPEAT
#ENDIF
ENDPROC
//
// Sent Text Functions/Procedures
//
FUNC INT PRIVATE_Get_Sent_Text_Queue_Index(CC_CommID paramSentTextID)
INT index
#IF USE_CLF_DLC
REPEAT g_savedGlobalsClifford.sCommsControlData.iNoSentTexts index
IF g_savedGlobalsClifford.sCommsControlData.sSentTexts[index].sCommData.eID = paramSentTextID
RETURN index
ENDIF
ENDREPEAT
#ENDIF
#IF USE_NRM_DLC
REPEAT g_savedGlobalsnorman.sCommsControlData.iNoSentTexts index
IF g_savedGlobalsnorman.sCommsControlData.sSentTexts[index].sCommData.eID = paramSentTextID
RETURN index
ENDIF
ENDREPEAT
#ENDIF
#IF NOT USE_SP_DLC
REPEAT g_savedGlobals.sCommsControlData.iNoSentTexts index
IF g_savedGlobals.sCommsControlData.sSentTexts[index].sCommData.eID = paramSentTextID
RETURN index
ENDIF
ENDREPEAT
#ENDIF
RETURN -1
ENDFUNC
PROC PRIVATE_Remove_Text_From_Sent_Queue(CC_CommID paramSentTextID)
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing text ", GET_COMM_ID_DEBUG_STRING(paramSentTextID), " from the sent text queue.")
//Work out what array position this text is at.
INT iSentTextIndex = PRIVATE_Get_Sent_Text_Queue_Index(paramSentTextID)
IF iSentTextIndex = -1
SCRIPT_ASSERT("PRIVATE_Remove_Text_From_Sent_Queue: No text with the given ID was found in the sent queue. Failed to remove.")
EXIT
ENDIF
INT index
CC_TextMessageData sBlankTextData
#IF USE_CLF_DLC
//Move all array positions up one place and overwrite the call we want to remove.
FOR index = iSentTextIndex TO (g_savedGlobalsClifford.sCommsControlData.iNoSentTexts-2)
g_savedGlobalsClifford.sCommsControlData.sSentTexts[index] = g_savedGlobalsClifford.sCommsControlData.sSentTexts[index+1]
ENDFOR
//Set the old last call in the queue to be blank data to be safe.
g_savedGlobalsClifford.sCommsControlData.sSentTexts[g_savedGlobalsClifford.sCommsControlData.iNoSentTexts-1] = sBlankTextData
//Reduce the counter tracking the number of calls in the queue.
g_savedGlobalsClifford.sCommsControlData.iNoSentTexts--
#ENDIF
#IF USE_SP_DLC
//Move all array positions up one place and overwrite the call we want to remove.
FOR index = iSentTextIndex TO (g_savedGlobalsnorman.sCommsControlData.iNoSentTexts-2)
g_savedGlobalsnorman.sCommsControlData.sSentTexts[index] = g_savedGlobalsnorman.sCommsControlData.sSentTexts[index+1]
ENDFOR
//Set the old last call in the queue to be blank data to be safe.
g_savedGlobalsnorman.sCommsControlData.sSentTexts[g_savedGlobalsnorman.sCommsControlData.iNoSentTexts-1] = sBlankTextData
//Reduce the counter tracking the number of calls in the queue.
g_savedGlobalsnorman.sCommsControlData.iNoSentTexts--
#ENDIF
#IF NOT USE_SP_DLC
//Move all array positions up one place and overwrite the call we want to remove.
FOR index = iSentTextIndex TO (g_savedGlobals.sCommsControlData.iNoSentTexts-2)
g_savedGlobals.sCommsControlData.sSentTexts[index] = g_savedGlobals.sCommsControlData.sSentTexts[index+1]
ENDFOR
//Set the old last call in the queue to be blank data to be safe.
g_savedGlobals.sCommsControlData.sSentTexts[g_savedGlobals.sCommsControlData.iNoSentTexts-1] = sBlankTextData
//Reduce the counter tracking the number of calls in the queue.
g_savedGlobals.sCommsControlData.iNoSentTexts--
#ENDIF
//Update character queue priority levels in case this new text is the new highest priority communication.
//Going to all playable characters. Update all their priorities.
PRIVATE_Update_Playable_Character_Priority_Level(CHAR_MICHAEL)
PRIVATE_Update_Playable_Character_Priority_Level(CHAR_FRANKLIN)
PRIVATE_Update_Playable_Character_Priority_Level(CHAR_TREVOR)
ENDPROC
FUNC BOOL PRIVATE_Is_Sent_Text_Queued(CC_CommID paramSentTextID)
INT index
#IF USE_CLF_DLC
REPEAT g_savedGlobalsClifford.sCommsControlData.iNoSentTexts index
IF g_savedGlobalsClifford.sCommsControlData.sSentTexts[index].sCommData.eID = paramSentTextID
RETURN TRUE
ENDIF
ENDREPEAT
#ENDIF
#IF USE_NRM_DLC
REPEAT g_savedGlobalsnorman.sCommsControlData.iNoSentTexts index
IF g_savedGlobalsnorman.sCommsControlData.sSentTexts[index].sCommData.eID = paramSentTextID
RETURN TRUE
ENDIF
ENDREPEAT
#ENDIF
#IF NOT USE_SP_DLC
REPEAT g_savedGlobals.sCommsControlData.iNoSentTexts index
IF g_savedGlobals.sCommsControlData.sSentTexts[index].sCommData.eID = paramSentTextID
RETURN TRUE
ENDIF
ENDREPEAT
#ENDIF
RETURN FALSE
ENDFUNC
PROC PRIVATE_Add_Text_To_Sent_Text_Queue(CC_TextMessageData &sTextData)
CPRINTLN(DEBUG_COMMUNICATIONS, "Adding text ", GET_COMM_ID_DEBUG_STRING(sTextData.sCommData.eID), " to the sent text queue.")
//Check if the text is already registered.
IF NOT PRIVATE_Is_Sent_Text_Queued(sTextData.sCommData.eID)
#IF USE_CLF_DLC
//Check the queue isn't full.
IF g_savedGlobalsClifford.sCommsControlData.iNoSentTexts < CC_MAX_SENT_TEXTS
//Add data to queue.
g_savedGlobalsClifford.sCommsControlData.sSentTexts[g_savedGlobalsClifford.sCommsControlData.iNoSentTexts] = sTextData
g_savedGlobalsClifford.sCommsControlData.iNoSentTexts++
ELSE
SCRIPT_ASSERT("PRIVATE_Add_Text_To_Sent_Text_Queue: Tried to add a text to the sent text queue, but it was full. CC_MAX_SENT_TEXTS probably needs increasing.")
ENDIF
#ENDIF
#IF USE_NRM_DLC
//Check the queue isn't full.
IF g_savedGlobalsnorman.sCommsControlData.iNoSentTexts < CC_MAX_SENT_TEXTS
//Add data to queue.
g_savedGlobalsnorman.sCommsControlData.sSentTexts[g_savedGlobalsnorman.sCommsControlData.iNoSentTexts] = sTextData
g_savedGlobalsnorman.sCommsControlData.iNoSentTexts++
ELSE
SCRIPT_ASSERT("PRIVATE_Add_Text_To_Sent_Text_Queue: Tried to add a text to the sent text queue, but it was full. CC_MAX_SENT_TEXTS probably needs increasing.")
ENDIF
#ENDIF
#IF NOT USE_SP_DLC
//Check the queue isn't full.
IF g_savedGlobals.sCommsControlData.iNoSentTexts < CC_MAX_SENT_TEXTS
//Add data to queue.
g_savedGlobals.sCommsControlData.sSentTexts[g_savedGlobals.sCommsControlData.iNoSentTexts] = sTextData
g_savedGlobals.sCommsControlData.iNoSentTexts++
ELSE
SCRIPT_ASSERT("PRIVATE_Add_Text_To_Sent_Text_Queue: Tried to add a text to the sent text queue, but it was full. CC_MAX_SENT_TEXTS probably needs increasing.")
ENDIF
#ENDIF
ELSE
CPRINTLN(DEBUG_COMMUNICATIONS, "The text was already in the sent text queue.")
ENDIF
ENDPROC
PROC PRIVATE_Clean_None_Save_Communications_On_Startup()
CPRINTLN(DEBUG_COMMUNICATIONS, "Checking for none save communications to clear on SP startup.")
INT index
#IF USE_CLF_DLC
REPEAT g_savedGlobalsClifford.sCommsControlData.iNoQueuedCalls index
IF IS_BIT_SET(g_savedGlobalsClifford.sCommsControlData.sQueuedCalls[index].sCommData.iSettings, COMM_BIT_DONT_SAVE)
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing none save comm ", GET_COMM_ID_DEBUG_STRING(g_savedGlobalsClifford.sCommsControlData.sQueuedCalls[index].sCommData.eID), " from the call queue.")
PRIVATE_Remove_Call_From_Queue(index)
ENDIF
ENDREPEAT
REPEAT g_savedGlobalsClifford.sCommsControlData.iNoChatCalls index
IF IS_BIT_SET(g_savedGlobalsClifford.sCommsControlData.sChatCalls[index].sCommData.iSettings, COMM_BIT_DONT_SAVE)
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing none save comm ", GET_COMM_ID_DEBUG_STRING(g_savedGlobalsClifford.sCommsControlData.sChatCalls[index].sCommData.eID), " from the chat call queue.")
PRIVATE_Remove_Call_From_Chat_Call_Queue(g_savedGlobalsClifford.sCommsControlData.sChatCalls[index].sCommData.eID)
ENDIF
ENDREPEAT
REPEAT g_savedGlobalsClifford.sCommsControlData.iNoMissedCalls index
IF IS_BIT_SET(g_savedGlobalsClifford.sCommsControlData.sMissedCalls[index].sCommData.iSettings, COMM_BIT_DONT_SAVE)
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing none save comm ", GET_COMM_ID_DEBUG_STRING(g_savedGlobalsClifford.sCommsControlData.sMissedCalls[index].sCommData.eID), " from the missed call queue.")
PRIVATE_Remove_Call_From_Missed_Call_Queue(g_savedGlobalsClifford.sCommsControlData.sMissedCalls[index].sCommData.eID)
ENDIF
ENDREPEAT
REPEAT g_savedGlobalsClifford.sCommsControlData.iNoQueuedTexts index
IF IS_BIT_SET(g_savedGlobalsClifford.sCommsControlData.sQueuedTexts[index].sCommData.iSettings, COMM_BIT_DONT_SAVE)
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing none save comm ", GET_COMM_ID_DEBUG_STRING(g_savedGlobalsClifford.sCommsControlData.sQueuedTexts[index].sCommData.eID), " from the text queue.")
PRIVATE_Remove_Text_From_Queue(index)
ENDIF
ENDREPEAT
REPEAT g_savedGlobalsClifford.sCommsControlData.iNoQueuedEmails index
IF IS_BIT_SET(g_savedGlobalsClifford.sCommsControlData.sQueuedEmails[index].sCommData.iSettings, COMM_BIT_DONT_SAVE)
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing none save comm ", GET_COMM_ID_DEBUG_STRING(g_savedGlobalsClifford.sCommsControlData.sQueuedEmails[index].sCommData.eID), " from the email queue.")
PRIVATE_Remove_Email_From_Queue(index)
ENDIF
ENDREPEAT
#ENDIF
#IF USE_NRM_DLC
REPEAT g_savedGlobalsnorman.sCommsControlData.iNoQueuedCalls index
IF IS_BIT_SET(g_savedGlobalsnorman.sCommsControlData.sQueuedCalls[index].sCommData.iSettings, COMM_BIT_DONT_SAVE)
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing none save comm ", GET_COMM_ID_DEBUG_STRING(g_savedGlobalsnorman.sCommsControlData.sQueuedCalls[index].sCommData.eID), " from the call queue.")
PRIVATE_Remove_Call_From_Queue(index)
ENDIF
ENDREPEAT
REPEAT g_savedGlobalsnorman.sCommsControlData.iNoChatCalls index
IF IS_BIT_SET(g_savedGlobalsnorman.sCommsControlData.sChatCalls[index].sCommData.iSettings, COMM_BIT_DONT_SAVE)
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing none save comm ", GET_COMM_ID_DEBUG_STRING(g_savedGlobalsnorman.sCommsControlData.sChatCalls[index].sCommData.eID), " from the chat call queue.")
PRIVATE_Remove_Call_From_Chat_Call_Queue(g_savedGlobalsnorman.sCommsControlData.sChatCalls[index].sCommData.eID)
ENDIF
ENDREPEAT
REPEAT g_savedGlobalsnorman.sCommsControlData.iNoMissedCalls index
IF IS_BIT_SET(g_savedGlobalsnorman.sCommsControlData.sMissedCalls[index].sCommData.iSettings, COMM_BIT_DONT_SAVE)
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing none save comm ", GET_COMM_ID_DEBUG_STRING(g_savedGlobalsnorman.sCommsControlData.sMissedCalls[index].sCommData.eID), " from the missed call queue.")
PRIVATE_Remove_Call_From_Missed_Call_Queue(g_savedGlobalsnorman.sCommsControlData.sMissedCalls[index].sCommData.eID)
ENDIF
ENDREPEAT
REPEAT g_savedGlobalsnorman.sCommsControlData.iNoQueuedTexts index
IF IS_BIT_SET(g_savedGlobalsnorman.sCommsControlData.sQueuedTexts[index].sCommData.iSettings, COMM_BIT_DONT_SAVE)
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing none save comm ", GET_COMM_ID_DEBUG_STRING(g_savedGlobalsnorman.sCommsControlData.sQueuedTexts[index].sCommData.eID), " from the text queue.")
PRIVATE_Remove_Text_From_Queue(index)
ENDIF
ENDREPEAT
REPEAT g_savedGlobalsnorman.sCommsControlData.iNoQueuedEmails index
IF IS_BIT_SET(g_savedGlobalsnorman.sCommsControlData.sQueuedEmails[index].sCommData.iSettings, COMM_BIT_DONT_SAVE)
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing none save comm ", GET_COMM_ID_DEBUG_STRING(g_savedGlobalsnorman.sCommsControlData.sQueuedEmails[index].sCommData.eID), " from the email queue.")
PRIVATE_Remove_Email_From_Queue(index)
ENDIF
ENDREPEAT
#ENDIF
#IF NOT USE_SP_DLC
REPEAT g_savedGlobals.sCommsControlData.iNoQueuedCalls index
IF IS_BIT_SET(g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.iSettings, COMM_BIT_DONT_SAVE)
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing none save comm ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.eID), " from the call queue.")
PRIVATE_Remove_Call_From_Queue(index)
ENDIF
ENDREPEAT
REPEAT g_savedGlobals.sCommsControlData.iNoChatCalls index
IF IS_BIT_SET(g_savedGlobals.sCommsControlData.sChatCalls[index].sCommData.iSettings, COMM_BIT_DONT_SAVE)
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing none save comm ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sChatCalls[index].sCommData.eID), " from the chat call queue.")
PRIVATE_Remove_Call_From_Chat_Call_Queue(g_savedGlobals.sCommsControlData.sChatCalls[index].sCommData.eID)
ENDIF
ENDREPEAT
REPEAT g_savedGlobals.sCommsControlData.iNoMissedCalls index
IF IS_BIT_SET(g_savedGlobals.sCommsControlData.sMissedCalls[index].sCommData.iSettings, COMM_BIT_DONT_SAVE)
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing none save comm ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sMissedCalls[index].sCommData.eID), " from the missed call queue.")
PRIVATE_Remove_Call_From_Missed_Call_Queue(g_savedGlobals.sCommsControlData.sMissedCalls[index].sCommData.eID)
ENDIF
ENDREPEAT
REPEAT g_savedGlobals.sCommsControlData.iNoQueuedTexts index
IF IS_BIT_SET(g_savedGlobals.sCommsControlData.sQueuedTexts[index].sCommData.iSettings, COMM_BIT_DONT_SAVE)
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing none save comm ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedTexts[index].sCommData.eID), " from the text queue.")
PRIVATE_Remove_Text_From_Queue(index)
ENDIF
ENDREPEAT
REPEAT g_savedGlobals.sCommsControlData.iNoQueuedEmails index
IF IS_BIT_SET(g_savedGlobals.sCommsControlData.sQueuedEmails[index].sCommData.iSettings, COMM_BIT_DONT_SAVE)
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing none save comm ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedEmails[index].sCommData.eID), " from the email queue.")
PRIVATE_Remove_Email_From_Queue(index)
ENDIF
ENDREPEAT
#ENDIF
ENDPROC
PROC PRIVATE_Maintain_Phone_Sleep_Mode_Flag()
#IF USE_CLF_DLC
IF NOT IS_CURRENTLY_ON_MISSION_OF_ANY_TYPE()
IF IS_BIT_SET(g_savedGlobalsClifford.sFlowCustom.spInitBitset, SP_INIT_RESTORE_SLEEP_MODE)
IF NOT IS_CURRENT_PLAYER_IN_SLEEP_MODE()
CLEAR_BIT(g_savedGlobalsClifford.sFlowCustom.spInitBitset, SP_INIT_RESTORE_SLEEP_MODE)
ENDIF
ELSE
IF IS_CURRENT_PLAYER_IN_SLEEP_MODE()
SET_BIT(g_savedGlobalsClifford.sFlowCustom.spInitBitset, SP_INIT_RESTORE_SLEEP_MODE)
ENDIF
ENDIF
ENDIF
#ENDIF
#IF USE_NRM_DLC
IF NOT IS_CURRENTLY_ON_MISSION_OF_ANY_TYPE()
IF IS_BIT_SET(g_savedGlobalsnorman.sFlowCustom.spInitBitset, SP_INIT_RESTORE_SLEEP_MODE)
IF NOT IS_CURRENT_PLAYER_IN_SLEEP_MODE()
CLEAR_BIT(g_savedGlobalsnorman.sFlowCustom.spInitBitset, SP_INIT_RESTORE_SLEEP_MODE)
ENDIF
ELSE
IF IS_CURRENT_PLAYER_IN_SLEEP_MODE()
SET_BIT(g_savedGlobalsnorman.sFlowCustom.spInitBitset, SP_INIT_RESTORE_SLEEP_MODE)
ENDIF
ENDIF
ENDIF
#ENDIF
#IF NOT USE_SP_DLC
IF NOT IS_CURRENTLY_ON_MISSION_OF_ANY_TYPE()
IF IS_BIT_SET(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_RESTORE_SLEEP_MODE)
IF NOT IS_CURRENT_PLAYER_IN_SLEEP_MODE()
CLEAR_BIT(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_RESTORE_SLEEP_MODE)
ENDIF
ELSE
IF IS_CURRENT_PLAYER_IN_SLEEP_MODE()
SET_BIT(g_savedGlobals.sFlowCustom.spInitBitset, SP_INIT_RESTORE_SLEEP_MODE)
ENDIF
ENDIF
ENDIF
#ENDIF
ENDPROC
PROC Run_Call_Timer_Safeguard( CC_CallData &sCallData )
IF sCallData.sCommData.ePriority = CPR_VERY_HIGH
IF (sCallData.sCommData.iQueueTime - GET_GAME_TIMER()) > CC_END_OF_MISSION_QUEUE_TIME
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Found end of mission call ", GET_COMM_ID_CALL_DEBUG_STRING(sCallData.sCommData.eID), " had a corrupted queue time. Set timer to 6000 ms.")
sCallData.sCommData.iQueueTime = GET_GAME_TIMER() + CC_END_OF_MISSION_QUEUE_TIME
ENDIF
ENDIF
ENDPROC
PROC Run_Text_Timer_Safeguard( CC_TextMessageData &sTextData )
IF sTextData.sCommData.ePriority = CPR_VERY_HIGH
IF (sTextData.sCommData.iQueueTime - GET_GAME_TIMER()) > CC_END_OF_MISSION_QUEUE_TIME
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Found end of mission text ", GET_COMM_ID_TEXT_MESSAGE_DEBUG_STRING(sTextData.sCommData.eID), " had a corrupted queue time. Set timer to 6000 ms.")
sTextData.sCommData.iQueueTime = GET_GAME_TIMER() + CC_END_OF_MISSION_QUEUE_TIME
ENDIF
ENDIF
ENDPROC
PROC Run_Email_Timer_Safeguard( CC_EmailData &sEmailData )
IF sEmailData.sCommData.ePriority = CPR_VERY_HIGH
IF (sEmailData.sCommData.iQueueTime - GET_GAME_TIMER()) > CC_END_OF_MISSION_QUEUE_TIME
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Found end of mission email ", GET_COMM_ID_EMAIL_DEBUG_STRING(sEmailData.sCommData.eID), " had a corrupted queue time. Set timer to 6000 ms.")
sEmailData.sCommData.iQueueTime = GET_GAME_TIMER() + CC_END_OF_MISSION_QUEUE_TIME
ENDIF
ENDIF
ENDPROC
PROC PRIVATE_update_new_queue_timers_from_save()
INT index
REPEAT g_savedGlobals.sCommsControlData.iNoQueuedCalls index
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Updating call ", GET_COMM_ID_CALL_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.eID), " timer from save...")
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Old queue time: ", g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.iQueueTime)
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Saved game time: ", g_savedGlobals.sCommsControlData.iCommsGameTime)
g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.iQueueTime -= g_savedGlobals.sCommsControlData.iCommsGameTime
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Time remaining: ", g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.iQueueTime)
g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.iQueueTime += GET_GAME_TIMER()
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Game timer: ", GET_GAME_TIMER())
CDEBUG1LN( DEBUG_COMMUNICATIONS, "New queue time: ", g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.iQueueTime)
ENDREPEAT
REPEAT g_savedGlobals.sCommsControlData.iNoChatCalls index
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Updating chat call ", GET_COMM_ID_CALL_DEBUG_STRING(g_savedGlobals.sCommsControlData.sChatCalls[index].sCommData.eID), " timer from save...")
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Old queue time: ", g_savedGlobals.sCommsControlData.sChatCalls[index].sCommData.iQueueTime)
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Saved game time: ", g_savedGlobals.sCommsControlData.iCommsGameTime)
g_savedGlobals.sCommsControlData.sChatCalls[index].sCommData.iQueueTime -= g_savedGlobals.sCommsControlData.iCommsGameTime
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Time remaining: ", g_savedGlobals.sCommsControlData.sChatCalls[index].sCommData.iQueueTime)
g_savedGlobals.sCommsControlData.sChatCalls[index].sCommData.iQueueTime += GET_GAME_TIMER()
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Game timer: ", GET_GAME_TIMER())
CDEBUG1LN( DEBUG_COMMUNICATIONS, "New queue time: ", g_savedGlobals.sCommsControlData.sChatCalls[index].sCommData.iQueueTime)
Run_Call_Timer_Safeguard(g_savedGlobals.sCommsControlData.sChatCalls[index])
ENDREPEAT
REPEAT g_savedGlobals.sCommsControlData.iNoMissedCalls index
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Updating missed call ", GET_COMM_ID_CALL_DEBUG_STRING(g_savedGlobals.sCommsControlData.sMissedCalls[index].sCommData.eID), " timer from save...")
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Old queue time: ", g_savedGlobals.sCommsControlData.sMissedCalls[index].sCommData.iQueueTime)
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Saved game time: ", g_savedGlobals.sCommsControlData.iCommsGameTime)
g_savedGlobals.sCommsControlData.sMissedCalls[index].sCommData.iQueueTime -= g_savedGlobals.sCommsControlData.iCommsGameTime
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Time remaining: ", g_savedGlobals.sCommsControlData.sMissedCalls[index].sCommData.iQueueTime)
g_savedGlobals.sCommsControlData.sMissedCalls[index].sCommData.iQueueTime += GET_GAME_TIMER()
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Game timer: ", GET_GAME_TIMER())
CDEBUG1LN( DEBUG_COMMUNICATIONS, "New queue time: ", g_savedGlobals.sCommsControlData.sMissedCalls[index].sCommData.iQueueTime)
Run_Call_Timer_Safeguard(g_savedGlobals.sCommsControlData.sMissedCalls[index])
ENDREPEAT
REPEAT g_savedGlobals.sCommsControlData.iNoQueuedTexts index
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Updating text message ", GET_COMM_ID_TEXT_MESSAGE_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedTexts[index].sCommData.eID), " timer from save...")
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Old queue time: ", g_savedGlobals.sCommsControlData.sQueuedTexts[index].sCommData.iQueueTime)
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Saved game time: ", g_savedGlobals.sCommsControlData.iCommsGameTime)
g_savedGlobals.sCommsControlData.sQueuedTexts[index].sCommData.iQueueTime -= g_savedGlobals.sCommsControlData.iCommsGameTime
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Time remaining: ", g_savedGlobals.sCommsControlData.sQueuedTexts[index].sCommData.iQueueTime)
g_savedGlobals.sCommsControlData.sQueuedTexts[index].sCommData.iQueueTime += GET_GAME_TIMER()
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Game timer: ", GET_GAME_TIMER())
CDEBUG1LN( DEBUG_COMMUNICATIONS, "New queue time: ", g_savedGlobals.sCommsControlData.sQueuedTexts[index].sCommData.iQueueTime)
Run_Text_Timer_Safeguard(g_savedGlobals.sCommsControlData.sQueuedTexts[index])
ENDREPEAT
REPEAT g_savedGlobals.sCommsControlData.iNoQueuedEmails index
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Updating email ", GET_COMM_ID_EMAIL_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedEmails[index].sCommData.eID), " timer from save...")
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Old queue time: ", g_savedGlobals.sCommsControlData.sQueuedEmails[index].sCommData.iQueueTime)
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Saved game time: ", g_savedGlobals.sCommsControlData.iCommsGameTime)
g_savedGlobals.sCommsControlData.sQueuedEmails[index].sCommData.iQueueTime -= g_savedGlobals.sCommsControlData.iCommsGameTime
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Time remaining: ", g_savedGlobals.sCommsControlData.sQueuedEmails[index].sCommData.iQueueTime)
g_savedGlobals.sCommsControlData.sQueuedEmails[index].sCommData.iQueueTime += GET_GAME_TIMER()
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Game timer: ", GET_GAME_TIMER())
CDEBUG1LN( DEBUG_COMMUNICATIONS, "New queue time: ", g_savedGlobals.sCommsControlData.sQueuedEmails[index].sCommData.iQueueTime)
Run_Email_Timer_Safeguard(g_savedGlobals.sCommsControlData.sQueuedEmails[index])
ENDREPEAT
ENDPROC
PROC PRIVATE_Update_Saved_Comms_Game_Clock()
CDEBUG1LN( DEBUG_COMMUNICATIONS, "Updated saved comms game clock from ", g_savedGlobals.sCommsControlData.iCommsGameTime, " to ", GET_GAME_TIMER())
g_savedGlobals.sCommsControlData.iCommsGameTime = GET_GAME_TIMER()
ENDPROC
/// ---------------------------------
/// Email priority queuing functions.
/// ---------------------------------
/// PURPOSE:
/// Clears the data inside the email struct that is passed by ref in the params.
/// PARAMS:
/// sEmailData - The email data struct that is to be cleared.
PROC PRIVATE_Clear_Email_Data( CC_EmailData &sEmailData )
CC_EmailData sBlankEmailData
CDEBUG1LN( DEBUG_COMMUNICATIONS, " - comms_control_private.sch - PRIVATE_Clear_Email_Data - Cleared out email: ", GET_COMM_ID_EMAIL_DEBUG_STRING( sEmailData.sCommData.eID ) )
sEmailData = sBlankEmailData
ENDPROC
/// PURPOSE:
/// Checks to see if the new email is of higher priority than the old email.
/// PARAMS:
/// sEmailDataNew - CC_EmailData of the new email to complare against another email
/// sEmailDataOld - CC_EmailData of the email inwhich the new email will be compared against
/// RETURNS:
/// Returns COMMS_PAIRS_COMPARISONS enum to comparer whether the priority is higher, lower, or the same.
FUNC COMMS_PAIRS_COMPARISONS PRIVATE_Email_Priority_Comparison( CC_EmailData sEmailDataNew, CC_EmailData sEmailDataOld )
CC_CommunicationPriority sPriorityNew = sEmailDataNew.sCommData.ePriority
CC_CommunicationPriority sPriorityOld = sEmailDataOld.sCommData.ePriority
// IF sPriorityNew = CPR_NO_PRIORITY_LEVELS
// OR sPriorityNew = CPR_ERROR // Disregard if errored or no priority.
// RETURN CPC_LOWER
// ENDIF
IF sPriorityNew > sPriorityOld
RETURN CPC_HIGHER
ELIF sPriorityNew < sPriorityOld
RETURN CPC_LOWER
ELSE
RETURN CPC_SAME
ENDIF
ENDFUNC
/// PURPOSE:
/// Checks the email for having a CID.
/// PARAMS:
/// sEmailData - The CC_EmailData to check the CID of the email on the game.
/// RETURNS:
/// Will return TRUE if there is a CID, and FALSE if not.
FUNC BOOL PRIVATE_Does_Email_Have_A_Complete_ID( CC_EmailData sEmailData )
IF sEmailData.sCommData.eExecuteOnCompleteID = CID_BLANK
RETURN FALSE
ELSE
RETURN TRUE
ENDIF
ENDFUNC
/// PURPOSE:
/// Checks and fires off a CID from the email if the email data has one.
/// PARAMS:
/// sEmailData - CC_EmailData for the email to check and fire the CID
PROC PRIVATE_Check_And_Fire_CID( CC_EmailData sEmailData )
IF PRIVATE_Does_Email_Have_A_Complete_ID( sEmailData )
CDEBUG1LN( DEBUG_COMMUNICATIONS, " - comms_control_private.sch - PRIVATE_Check_And_Fire_CID - Fired off CID for email: ", GET_COMM_ID_EMAIL_DEBUG_STRING( sEmailData.sCommData.eID ) )
Execute_Code_ID( sEmailData.sCommData.eExecuteOnCompleteID )
ENDIF
ENDPROC
/// PURPOSE:
/// Checks through the email queue and returns the index of the lowest Precedence email in the queue
/// PARAMS:
/// iLowestPrecendenceIndex - The priority of the lowest priority email passed by ref.
PROC PRIVATE_Get_Lowest_Priority_Email_From_Queue( INT &iLowestPriorityIndex )
iLowestPriorityIndex = 0
INT iCurrentIndex
REPEAT g_savedGlobals.sCommsControlData.iNoQueuedEmails iCurrentIndex
IF PRIVATE_Email_Priority_Comparison( g_savedGlobals.sCommsControlData.sQueuedEmails[iCurrentIndex], g_savedGlobals.sCommsControlData.sQueuedEmails[iLowestPriorityIndex] ) = CPC_LOWER
iLowestPriorityIndex = iCurrentIndex
ENDIF
ENDREPEAT
CDEBUG1LN( DEBUG_COMMUNICATIONS, " - comms_control_private.sch - PRIVATE_Get_Lowest_Priority_Email_From_Queue - iLowestPriorityIndex = ", iLowestPriorityIndex, " - Email: ", GET_COMM_ID_EMAIL_DEBUG_STRING( g_savedGlobals.sCommsControlData.sQueuedEmails[iLowestPriorityIndex].sCommData.eID ) )
ENDPROC
/// PURPOSE:
/// This sets up the CC_EmailData with the data entered into the function and returns the struct.
/// PARAMS: eID - The enum referencing which question phonecall this is. String data stored in comms_control_data_GTA5.sch
/// eCommunicationType - The type of comminication being registered. This type will determine the email's priority.
/// iToPlayersBitset - A bitset containing which player characters this communication should be sent to.
/// eNPCCharacter - A charsheet ENUM defining the character this email is being sent from. Set to CHAR_BLANK_ENTRY if the email isn't bound to a char sheet character.
/// eEmailThread - The email thead that should be progressed when this communication is sent.
/// iQueueTime - The time this email will queue before it will be considered for triggering by the communications controller. Also used for calculating requeuing times.
/// eRestrictedArea - A vector ID that defines an area in the world that the player must not be in for the email to trigger.
/// eExecuteOnComplete - A code ID that defines a block of script that should be executed when the email is sent sucessfully.
/// iExecuteOnCompleteDelay - A time in milliseconds to wait after the communication is sent, before executing the code ID.
/// eCheckBeforeSend - A check ID that defines a check that must pass before this call can be sent.
/// eMissionInteraction - Does this communication unlock or trigger a mission on completion?
/// RETURNS: CC_EmailData - The new email struct
FUNC CC_EmailData PRIVATE_Setup_New_Email_Data( CC_CommID eID,
CC_CommunicationType eCommunicationType,
INT iToPlayersBitset,
enumCharacterList eNPCCharacter,
INT iQueueTime,
INT iRequeueTime,
VectorID eRestrictedArea = VID_BLANK,
CC_CodeID eExecuteOnComplete = CID_BLANK,
FLOW_CHECK_IDS eCheckBeforeSend = FLOW_CHECK_NONE,
INT iSettings = 0 )
CC_EmailData sNewEmailData
//Create a hashed ID for this communication.
//NOTE: All emails are stored in the same block ID.
sNewEmailData.sCommData.eID = eID
//Get a priority for this communication.
sNewEmailData.sCommData.ePriority = PRIVATE_Get_Priority_From_Communication_Type(eCommunicationType)
//Set an initial queue time for this communication.
sNewEmailData.sCommData.iQueueTime = GET_GAME_TIMER() + iQueueTime
sNewEmailData.sCommData.iRequeueTime = iRequeueTime
//Setup email data.
sNewEmailData.sCommData.iSettings = iSettings
sNewEmailData.sCommData.iPlayerCharBitset = iToPlayersBitset
sNewEmailData.sCommData.eNPCCharacter = eNPCCharacter
sNewEmailData.sCommData.eRestrictedAreaID = eRestrictedArea
sNewEmailData.sCommData.eExecuteOnCompleteID = eExecuteOnComplete
sNewEmailData.sCommData.eSendCheck = eCheckBeforeSend
CLEAR_BIT(sNewEmailData.sCommData.iSettings, COMM_BIT_FROM_CHAR_IS_PLAYER)
RETURN sNewEmailData
ENDFUNC