//╒═════════════════════════════════════════════════════════════════════════════╕ //│ 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