USING "rage_builtins.sch" USING "commands_audio.sch" USING "commands_pad.sch" USING "cellphone_public.sch" USING "cellphone_private.sch" USING "net_hud_activating.sch" PROC ClearConversationData() //Need to get rid of all label data here... //...then build, then play... INT index FOR index = 0 TO (constConversationLabels - 1) //Subtract one to prevent array overrun g_ConversationLabels[index] = "" #IF IS_DEBUG_BUILD /* cdPrintnl() cdPrintstring ("Clearing label: ") cdPrintint (index) cdPrintnl() */ #endif //g_SpecificLabels ENDFOR STOP_SCRIPTED_CONVERSATION (FALSE) //make sure any lingering conversation is stopped - task 167661. This will stop a conversation if the phone starts to ring. //Left in on a trial basis. It is safer this way. 21.07.11 //Set conversation status enum to "building" so that dialogue handler knows that it has the information it requires in order to start building a conversation g_ConversationStatus = CONV_STATE_BUILDING ENDPROC PROC ClearConversationPedsData() //Need to get rid of all ped struct data here... INT index FOR index = 0 TO (constMaxNum_Conversers - 1) //Subtract one to prevent array overrun g_ConversationPedsStruct.PedInfo[index].Index = NULL g_ConversationPedsStruct.PedInfo[index].VoiceId = "" g_ConversationPedsStruct.PedInfo[index].ActiveInConversation = FALSE g_ConversationPedsStruct.PedInfo[index].PlayAmbientAnims = FALSE /* #IF IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("Clearing Ped Array: ") cdPrintint (index) cdPrintnl() #endif */ ENDFOR g_ConversationPedsStruct.NullPed_Number_for_VoicePlacement = -99 g_ConversationPedsStruct.NullPed_Vector_for_VoicePlacement = <<0.0, 0.0, 0.0>> ENDPROC PROC CommonDialogueCleanup() #if USE_TU_CHANGES g_Holder_ForceDLC_DialogueRequest = FALSE g_ForceDLC_DialogueRequest = FALSE #endif g_ShouldPhoneBeForcedOnScreen = FALSE g_ShouldPhoneBeForcedOnScreenHolder = FALSE g_IsThisAnMPChatCall = FALSE g_IsThisAnMPChatCallHolder = FALSE g_ConversationPedsStruct.NullPed_Number_for_VoicePlacement = -99 g_ConversationPedsStruct.NullPed_Vector_for_VoicePlacement = <<0.0, 0.0, 0.0>> //Newly added 25.05.10. Check this if any conference call issue should crop up. g_IsConferenceCall = FALSE g_IsConferenceCallHolder = FALSE g_ForcePlayerAnswer = FALSE g_ForcePlayerAnswerHolder = FALSE g_HasStateBeenPreserved = FALSE //This might need to be a global so that it can be called by another function, namely hang-up. g_CallRequiringPlayerResponse = FALSE g_CallRequiringPlayerResponseHolder = FALSE g_IsEmergencyServicesCall = FALSE g_IsEmergencyServicesCallHolder = FALSE g_CellphonePromptResponse = RESPONSE_STORE_EMPTY //reset answer stored. //g_CellphoneJobOfferResponse = RESPONSE_STORE_EMPTY //moved to BuildCellphoneConversation() g_PrepareCallForDynamicBranch = FALSE IF g_Cellphone.PhoneDS = PDS_ATTEMPTING_TO_CALL_CONTACT #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring("DIALOGUE_PRIV - Phone in attempting_to_call_contact state, so won't remove phone from ear in CommonDialogueCleanup.") cdPrintnl() #endif ELSE IF IS_BIT_SET (BitSet_CellphoneDisplay, g_BS_PHONE_UP_TO_EAR) //Pull away the phone from the ear only if the last conversation was a phonecall. Remove_Cellphone_From_Ear() ENDIF ENDIF g_IsThisConversationForPhone = FALSE g_IsThisConversationForPhoneHolder = FALSE g_IsThisAnMpJobOffer = FALSE g_IsThisAnMpJobOfferHolder = FALSE g_PlayingSingleLineHolder = FALSE g_PlayingSingleLine = FALSE g_PlayingFromLineHolder = FALSE g_PlayingFromLine = FALSE g_IsThisFaceToFacePreloadedHolder = FALSE g_IsThisFaceToFacePreloaded = FALSE g_i_PreloadAutoPlayTime = 0 g_i_PreloadAutoPlayTimeHolder = 0 g_TotalMultiparts = 0 g_TotalMultipartsHolder = 0 g_TotalReplyMultiparts = 0 g_TotalReplyMultipartsHolder = 0 g_b_Is_MultipartRepliesInProgress = FALSE g_Outgoing_Call_Pause_Answering_Time = g_Const_Outgoing_Call_Pause_Answering_Time //reset other character's answering time g_B_External_Interrupt_Autoplay_MovieFail_Flag = FALSE CLEAR_BIT (BitSet_CellphoneDisplay, g_BS_DISABLE_INCOMING_OR_OUTGOING_CALL_HANGUP) //Make sure the hangup functionality is re-enabled. CLEAR_BIT (BitSet_CellphoneDisplay, g_BS_FORCE_CALL_WITH_REPLIES_NEGATIVE) //Make sure cellphone will no longer force negative response. CLEAR_BIT (BitSet_CellphoneDisplay_Continued, g_BSC_CELLPHONE_WITH_REPLIES_WAITING_ON_USER_INPUT) CLEAR_BIT (BitSet_CellphoneDisplay_Third, g_BSTHIRD_KEEP_MP_CALL_ACTIVE_ON_PAUSE_MENU) //Make sure that future calls will continue to be terminated when the game is paused. //Make sure universal system components for N multipart line response branches are fully cleared. CLEAR_BIT (BitSet_CellphoneDisplay_Continued, g_BSC_UNIVERSAL_REPLIES_FOR_N_LINES_HAS_BEEN_SET) //Make sure the "is answerphone" message flag is cleared. CLEAR_BIT (BitSet_CellphoneDisplay_Continued, g_BSC_THIS_IS_AN_ANSWERPHONE_CALL) //Make sure that line skip is available for future calls. CLEAR_BIT (BitSet_CellphoneDisplay_Continued, g_BSC_PREVENT_CELLPHONE_LINESKIP) CLEAR_BIT (BitSet_CellphoneDisplay_Third, g_BSTHIRD_PREVENT_PRELOADED_PHONECALL_START) //Clear critical bit only used by Alwyn's player timetable switch. g_i_Total_UniversalYesReplies = 0 g_i_Total_UniversalNoReplies = 0 //This routine may have been called via a HANG_UP_AND_PUT_AWAY_PHONE. However, a face-to-face conversation might have been going on and HANG_UP only stops //cellphone conversations now. Conversely, if we know that a face-to-face conversation was taking place, then a phone call wasn't, so it's safe to reset //the other vars above. If a face-to-face conversation was taking place during a HANG_UP then we don't set the conversation state to free, reset the //pause var or get the timestamp. These will be handled when the face-to-face conversation actually finishes because during that cleanup IS_SCRIPTED... //can't return true. IF IS_SCRIPTED_CONVERSATION_ONGOING() #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring("Conversation assignment 87. Phone, interruption cleanup has been called. Selectively resetting variables. Scripted conversation ongoing so may be finishing last line. ") cdPrintnl() #endif g_ConversationStatus = CONV_STATE_PLAYING //If this was a script HANG_UP... a face-to-face conversation must still be playing after a hang up. Reassign so as to not to spam from temporary CONV_STATE_HANGUPAWAY. //If a KILL_FACE_TO_FACE_CONVERSATION has been requested and we want to finish the last line as normal, then CONV_STATE_FINISHED will be signalled for a frame, run this //procedure and reassign to CONV_STATE_PLAYING. This lets me know that this cleanup event has happened. IS_SCRIPTED_CONVERSATION_ONGOING() will return TRUE while finishing the last //line. This is expected. The CONV_STATE isn't truly free yet. //Rag will dump "DIALOG_HAND - Face to face conversation finished" when the CONV_STATE_PLAYING checks in Dialogue Handler detect the native scripted conversation has //completely finished. My system will run through to this proc again via cleanup but this time set the CONV_STATE_FREE below as IS_SCRIPTED_CONVERSATION_ONGOING() will be false. ELSE #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring("Conversation assignment 88. Dialogue Private assigns CONV_STATE_FREE") cdPrintnl() #endif g_ConversationStatus = CONV_STATE_FREE g_ConversationPaused = FALSE g_Timestamp_of_last_ConvStateFree = GET_GAME_TIMER() ENDIF ENDPROC //Fully cleans up any conversation and frees the slot for any subsequent access. The phone retains the same state it had before the conversation was cued with the exception of attempting //to call a contact proactively. See appContacts for more info. PROC ConversationCleanup() //Moved to just before termination of PlayCellphoneConversation() in dialogue_handler.sc and specific phone call kills so that the unified conversation cleanup which handles phonecalls and //face to face conversation doesn't interfere with the phone state. You could be mucking around with the phone during a face-to-face for example. //g_Cellphone.PhoneDS = BeforeCallPhoneDS //set the phone back to whatever state it was before a call was inbound. g_UpcomingConversationInboundForCellphone = FALSE g_InboundCallWaitAccRej = CALL_NONE_WAITING CommonDialogueCleanup() ENDPROC //Fully cleans up any conversation and frees the slot for any subsequent access. As this is a full hang up the phone is put away no matter what state it was in originally. //The differences between the two clean ups will increase during development. PROC ScriptHungupAwayCleanup() //g_ConversationStatus = CONV_STATE_FREE g_UpcomingConversationInboundForCellphone = FALSE g_InboundCallWaitAccRej = CALL_NONE_WAITING //This section moved to HANG_UP_AND_PUT_AWAY_PHONE() public function and SET_SCRIPTS_SAFE_FOR_CUTSCENE in cutscene_public.sch //Put phone away... only if not disabled /* IF NOT IS_CELLPHONE_DISABLED_OR_DISABLED_THIS_FRAME_ONLY() g_Cellphone.PhoneDS = PDS_AWAY #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring("STATE ASSIGNMENT 3. Dialogue Private assigns PDS_AWAY") cdPrintnl() #endif ENDIF */ CommonDialogueCleanup() ENDPROC PROC KillAllConversations() #IF IS_DEBUG_BUILD cdPrintstring("DIALOG_PRIV - Tidying up any unfinished conversations...") cdPrintnl() #endif RESTART_SCRIPTED_CONVERSATION() g_ConversationPaused = FALSE //Make sure that any paused conversations can be cleaned up. IF IS_MOBILE_PHONE_CALL_ONGOING() OR g_Cellphone.PhoneDS = PDS_ONGOING_CALL //New trial addition to make sure call is put away during answering time pause... //OR g_Cellphone.PhoneDS = PDS_ATTEMPTING_TO_CALL_CONTACT //New trial addition... TRIAL FAILED! If a test conversation was ongoing and you attempted to call out to //a friend hangout option or secondary option the phone would abort as this would return true! Investigate further! OR g_InboundCallWaitAccRej = CALL_WAITING_TO_BE_ANSWERED //make sure that any inbound call which is still waiting on an accept / reject is also cleaned up... //If we wanted to take precedence over calls waiting on a yes / no response we could do this: //OR g_CallRequiringPlayerResponse = TRUE STOP_SCRIPTED_CONVERSATION (FALSE) //don't finish last line of conversation as this is a call.... g_ConversationStatus = CONV_STATE_FINISHED //calls normal conversation cleanup via dialogue_handler.sc as we don't necessarily want to put the phone away. //g_Cellphone.PhoneDS = BeforeCallPhoneDS //set the phone back to whatever state it was before any call was made. //Trial to fix problem with calling 911 / Taxi etc. and phone staying on "connected" screen... //911 call won't be using an IF Player_Call so only runs once. If it calls a kill conversation we need to stop it forcing the phone away, the player must be calling the //right contact after all. See bug 831744 g_Cellphone.PhoneDS = PDS_AWAY #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring("STATE ASSIGNMENT 4. Dialogue Private assigns BeforeCallDS") cdPrintnl() #endif #IF IS_DEBUG_BUILD cdPrintstring("DIALOG_PRIV - Killed phone conversation from KillAllConversations()") cdPrintnl() #endif EXIT ENDIF IF IS_SCRIPTED_CONVERSATION_ONGOING() STOP_SCRIPTED_CONVERSATION (TRUE) //finish last line of conversation as this is a normal face-to-face conversation. g_ConversationStatus = CONV_STATE_FINISHED //calls normal conversation cleanup via dialogue_handler.sc #IF IS_DEBUG_BUILD cdPrintstring("DIALOG_PRIV - Killed face-to-face conversation from KillAllConversations()") cdPrintnl() #endif EXIT ENDIF ENDPROC PROC KillFaceToFaceConversationImmediately() RESTART_SCRIPTED_CONVERSATION() g_ConversationPaused = FALSE //Make sure that any paused conversations can be cleaned up. IF IS_SCRIPTED_CONVERSATION_ONGOING() STOP_SCRIPTED_CONVERSATION (FALSE) //do NOT finish last line of conversation. g_ConversationStatus = CONV_STATE_FINISHED //calls normal conversation cleanup via dialogue_handler.sc #IF IS_DEBUG_BUILD cdPrintstring("DIALOG_PRIV - Killed face-to-face conversation immediately called. Deliberately not finishing the last line.") cdPrintnl() #endif ENDIF ENDPROC PROC KillPhoneConversation() IF IS_MOBILE_PHONE_CALL_ONGOING() OR g_InboundCallWaitAccRej = CALL_WAITING_TO_BE_ANSWERED //make sure that any inbound call which is still waiting on an accept / reject is also cleaned up... //If we wanted to take precedence over calls waiting on a yes / no response we could do this: //OR g_CallRequiringPlayerResponse = TRUE RESTART_SCRIPTED_CONVERSATION() g_ConversationPaused = FALSE //Make sure that any paused conversations can be cleaned up. STOP_SCRIPTED_CONVERSATION (FALSE) //don't finish last line of conversation as this is a call.... //g_InboundCallWaitAccRej = CALL_NONE_WAITING //make sure that any inbound call which is still waiting on an accept / reject is also cleaned up... //g_UpcomingConversationInboundForCellphone = FALSE g_ConversationStatus = CONV_STATE_FINISHED //calls normal conversation cleanup via dialogue_handler.sc as we don't necessarily want to put the phone away. g_Cellphone.PhoneDS = BeforeCallPhoneDS //set the phone back to whatever state it was before any call was made. #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring("STATE ASSIGNMENT 5. Dialogue Private assigns BeforeCallDS") cdPrintnl() #endif #IF IS_DEBUG_BUILD cdPrintstring("DIALOG_PRIV - Killed phone conversation from KillPhoneConversation()") cdPrintnl() #endif EXIT ENDIF ENDPROC PROC InterruptPhoneCall() RESTART_SCRIPTED_CONVERSATION() g_ConversationPaused = FALSE //Make sure that any paused conversations can be cleaned up. STOP_SCRIPTED_CONVERSATION (TRUE) //finish last line of phone conversation ENDPROC PROC KillFaceToFaceConversation() IF IS_SCRIPTED_CONVERSATION_ONGOING() RESTART_SCRIPTED_CONVERSATION() g_ConversationPaused = FALSE //Make sure that any paused conversations can be cleaned up. STOP_SCRIPTED_CONVERSATION (TRUE) //finish last line of conversation as this is a normal face-to-face conversation. g_ConversationStatus = CONV_STATE_FINISHED //calls normal conversation cleanup via dialogue_handler.sc #IF IS_DEBUG_BUILD cdPrintstring("DIALOG_PRIV - Killed face-to-face conversation from KillFaceToFaceConversation()") cdPrintnl() #endif EXIT ENDIF ENDPROC PROC CheckForLineSkip() IF (Is_Phone_Control_Just_Pressed (FRONTEND_CONTROL, INT_TO_ENUM (CONTROL_ACTION, PHONE_NAV_DOWN_INPUT))) IF g_ConversationPaused = FALSE //IF IS_SCRIPTED_CONVERSATION_ONGOING() //taken this out so phonecalls can be skipped also. IF g_IsThisConversationForPhone IF IS_BIT_SET (BitSet_CellphoneDisplay_Continued, g_BSC_PREVENT_CELLPHONE_LINESKIP) #if IS_DEBUG_BUILD cdPrintstring ("DIALOG_PRIV - Cannot skip cellphone dialogue line as lineskip prevention is in force.") cdPrintnl() #endif ELSE SKIP_TO_NEXT_SCRIPTED_CONVERSATION_LINE() #if IS_DEBUG_BUILD cdPrintstring ("DIALOG_PRIV - Current conversation line skipped...") cdPrintnl() #endif ENDIF ENDIF ENDIF ENDIF ENDPROC PROC SetUpPhoneConversation() //Assign the "master" ongoing phonecall globals //The phone is "free" to accept calls so we can copy these across safely. If we didn't use temp holders //there would be a danger of these key globals used during any ongoing call being overwritten whenever //someone calls a public phone function during an ongoing call. g_CallRequiringPlayerResponse = g_CallRequiringPlayerResponseHolder g_ForcePlayerAnswer = g_ForcePlayerAnswerHolder g_YesSegmentLabel = g_YesSegmentLabelHolder g_NoSegmentLabel = g_NoSegmentLabelHolder g_IsEmergencyServicesCall = g_IsEmergencyServicesCallHolder g_AmbulanceSegmentLabel = g_AmbulanceSegmentLabelHolder g_FireSegmentLabel = g_FireSegmentLabelHolder g_PoliceSegmentLabel = g_PoliceSegmentLabelHolder g_QuestionGodLabel = g_QuestionGodLabelHolder g_TheContactInvolvedinCall = g_TheContactInvolvedinCallHolder g_AdditionalContactInvolvedinCall = g_AdditionalContactInvolvedinCallHolder g_ShouldPhoneBeForcedOnScreen = g_ShouldPhoneBeForcedOnScreenHolder g_IsThisAnMPChatCall = g_IsThisAnMPChatCallHolder #if IS_DEBUG_BUILD IF g_IsThisAnMPChatCallHolder = TRUE cdPrintString ("CHAT_CALL assignment 3 - has been set to TRUE") cdPrintnl() cdPrintnl() ELSE cdPrintString ("CHAT_CALL assignment 4 - has been set to FALSE") cdPrintnl() cdPrintnl() ENDIF #endif g_ChatCallerString = g_ChatCallerStringHolder g_IsConferenceCall = g_IsConferenceCallHolder g_LastInboundCallRejected = FALSE g_LastCellphoneCallInterrupted = FALSE g_LastCallHungupDuringCallViaJoypad = FALSE CLEAR_BIT (BitSet_CellphoneDisplay_Continued, g_BSC_LAST_CALL_ABORTED_DUE_TO_SCRIPT_HANGUP) //g_ConversationData.g_DisplaySubtitles = g_DisplaySubtitlesHolder //g_ConversationData.g_AddToBriefScreen = g_addToBriefScreenHolder //g_ConversationData.g_CloneConversation = g_CloneConversationHolder ENDPROC FUNC BOOL CheckCurrentConversationStatus (STRING WhichSegmentLabel, enumConversationPriority PassedConversationPriority, BOOL IsThisInboundForCellphone) //Just using priority just now... would pass in entire struct. #IF IS_DEBUG_BUILD IF g_bEnableConversationMute cdPrintnl() cdPrintstring ("DIALOG_PRIV - g_bEnableConversationMute debug is ENABLED. Can't play conversations (CheckCurrentConversationStatus)!") cdPrintnl() RETURN FALSE ENDIF #ENDIF g_Non_Essential_Call_Aborted_and_CS_Already_Free = FALSE //Important. This must be set on every time CheckCurrent... is accessed. IF g_ConversationStatus = CONV_STATE_FREE //No conversation of any priority is currently playing. A face-to-face conversation or a phonecall can be cued... OR g_CurrentlyPlayingConvPriority = CONV_PRIORITY_NON_CRITICAL_CALL //New trial addition to solve 911 / taxi issues. ST 07.05.12 //These measures should prevent users from deliberately holding up mission dialogue by dialling certain numbers. IF g_ConversationStatus <> CONV_STATE_FREE //Must have been the CONV_PRIORITY_NON_CRITICAL_CALL that got us here... IF PassedConversationPriority > g_CurrentlyPlayingConvPriority //The attempting call or dialogue has to be a higher priority! Incoming calls should be! //IF g_CurrentlyPlayingConvPriority = CONV_PRIORITY_NON_CRITICAL_CALL //Double check. All non essential calls need to use this conversation priority. //IF IsThisInboundForCellphone = FALSE //Must be face-to-face dialogue or outbound call. May alter to prevent outbound calls interrupting also but any potential //weirdness would indicate dodgy use elsewhere - repeated spamming of IS_CALLING_CONTACT probably. IF g_IsThisConversationForPhoneHolder = FALSE STOP_SCRIPTED_CONVERSATION (FALSE) g_Cellphone.PhoneDS = PDS_AWAY //The phonecall has been stopped, so we force the phone away but don't go through cleanup, //The holders will overwrite the main globals later in the explicit conversation data and SetUpPhoneConversation() g_ConversationStatus = CONV_STATE_FREE g_Non_Essential_Call_Aborted_and_CS_Already_Free = TRUE //Must be set so calls waiting for a question response, don't try to set the conversation //state to finished when the script code that deals with that realises no response is required. g_CallRequiringPlayerResponse = FALSE //Conceivably there might be a very remote chance of another higher priority "with replies" outbound call //interrupting an non-essential call so this should take care of that by making sure the original tidies up. g_TotalMultiparts = 0 g_TotalMultipartsHolder = 0 g_ShouldPhoneBeForcedOnScreen = FALSE // Fix for bug 1066934. Force screen flag was persisting, causing phone to go to previous call screen on takeout. //New March 5th 2015. Work for bug: 2264002 //When a chat call was incoming and a higher priority Lester face-to-face conversation fired, these two criticals weren't getting cleaned up //when the phone was forced away in the above segment. //This wasn't an issue with 911 or taxi calls which are non-critical as they wouldn't be incoming calls waiting for an accept or reject. //As these weren't being cleaned up, the phone would be behave weirdly when the user brought the phone out during the conversation. g_UpcomingConversationInboundForCellphone = FALSE //2264002 g_InboundCallWaitAccRej = CALL_NONE_WAITING //2264002 #if IS_DEBUG_BUILD cdPrintnl() cdPrintnl() cdPrintstring ("DIALOG_PRIV - Non-essential call being interrupted automatically.") cdPrintnl() cdPrintnl() #endif ELSE //If we get to here that must mean IsThisInboundForCellphone was TRUE. We will interrupt the call and force a hangup but not play immediately. //Anyone firing off incoming phone calls should really be checking for a return value and repeating their function accordingly. So no shortcuts here! #if IS_DEBUG_BUILD cdPrintnl() cdPrintnl() cdPrintstring ("DIALOG_PRIV - Non-essential call interrupted by another incoming call / conversation of higher priority. Will return true next frame.") cdPrintnl() cdPrintnl() #endif KillAllConversations() RETURN FALSE ENDIF ELSE #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Non-Essential phonecall in progress but it is still higher priority than newly passed request. Can't play latter!") cdPrintnl() #endif RETURN FALSE ENDIF ENDIF IF IS_SCRIPTED_CONVERSATION_ONGOING() #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring("DIALOG_PRIV - CONV_STATE_FREE but scripted conversation ongoing as a result of bad use of HANG_UP_PUT_AWAY_PHONE.") cdPrintnl() #endif RETURN FALSE ENDIF //Includes hits to MP global blocks. SP dlc can't run this check and shouldn't need to. -BenR #IF NOT USE_SP_DLC IF IS_SCRIPT_HUD_DISPLAYING (HUDPART_TRANSITIONHUD) #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring("DIALOG_PRIV - CONV_STATE_FREE but transition hud is onscreen. Can't play conversation.") cdPrintnl() #endif RETURN FALSE ENDIF #ENDIF //These master globals are common to both phone and face-to_face conversations. g_BlockToLoad = g_BlockToLoadHolder //copy across required text block to load in additional text slot for this conversation ClearConversationPedsData() //Clear out old master peds struct. g_ConversationPedsStruct = g_ConversationPedsHolderStruct g_IsThisConversationForPhone = g_IsThisConversationForPhoneHolder //As conversation state is free, we can copy across phonecall / face to face differentiator to //a global that remains fixed for the duration of the phonecall. g_IsThisAnMPChatCall = g_IsThisAnMPChatCallHolder #if IS_DEBUG_BUILD IF g_IsThisAnMPChatCallHolder = TRUE cdPrintString ("CHAT_CALL assignment 5 - has been set to TRUE") cdPrintnl() cdPrintnl() ELSE cdPrintString ("CHAT_CALL assignment 6 - has been set to FALSE") cdPrintnl() cdPrintnl() ENDIF #endif #if USE_TU_CHANGES g_ForceDLC_DialogueRequest = g_Holder_ForceDLC_DialogueRequest #if IS_DEBUG_BUILD IF g_ForceDLC_DialogueRequest = TRUE cdPrintnl() cdPrintString ("Jan 14 TU - CheckCurrentConversationStatus - g_ForceDLC_DialogueRequest has been set to TRUE ") cdPrintnl() ELSE cdPrintnl() cdPrintString ("Jan 14 TU - CheckCurrentConversationStatus - g_ForceDLC_DialogueRequest has been set to FALSE ") cdPrintnl() ENDIF #endif #endif g_ChatCallerString = g_ChatCallerStringHolder g_IsThisAnMpJobOffer = g_IsThisAnMpJobOfferHolder g_PlayingSingleLine = g_PlayingSingleLineHolder //As conversation state is free we can copy across "single line" differentiator to a global fixed for the duration of the conversation. g_SpecificLabel = g_SpecificLabelHolder //if we are playing a single line, this is the specific label that needs to be played. g_IsThisFaceToFacePreloaded = g_IsThisFaceToFacePreloadedHolder g_i_PreloadAutoPlayTime = g_i_PreloadAutoPlayTimeHolder g_PlayingFromLine = g_PlayingFromLineHolder g_ConversationData.g_CloneConversation = g_CloneConversationHolder g_ConversationData.g_DisplaySubtitles = g_DisplaySubtitlesHolder g_ConversationData.g_AddToBriefScreen = g_addToBriefScreenHolder //Multipart conversation work. g_TotalMultiparts = g_TotalMultipartsHolder IF g_IsThisConversationForPhone //This conversation is a phonecall. We need to do a few checks and some set up for phone specific globals. CLEAR_BIT (BitSet_CellphoneDisplay, g_BS_DISABLE_INCOMING_OR_OUTGOING_CALL_HANGUP) //Make sure the hangup functionality is re-enabled. CLEAR_BIT (BitSet_CellphoneDisplay_Continued, g_BSC_PREVENT_CELLPHONE_LINESKIP) //Make sure that line skip is available for future calls. CLEAR_BIT (BitSet_CellphoneDisplay_Third, g_BSTHIRD_KEEP_MP_CALL_ACTIVE_ON_PAUSE_MENU) //Make sure that future calls will continue to be terminated when the game is paused. #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring("DIALOG_PRIV - Enabled hangup and line skip for this call via direct clear bits.") cdPrintnl() #endif IF IsThisInboundForCellphone //Only block incoming calls in sleep mode. Get_Cellphone_Owner() //IF g_savedGlobals.sCellphoneSettingsData.This_Cellphone_Owner_Settings[g_Cellphone.PhoneOwner].g_SettingList[ENUM_TO_INT(SETTING_PROFILE)].Setting_Currently_Selected_Option = ENUM_TO_INT(PROFILE_SLEEP_MODE) //check if phone is in sleep mode. IF This_Cellphone_Owner_Settings_ListContents[g_Cellphone.PhoneOwner].g_SettingList[ENUM_TO_INT(SETTING_PROFILE)].Setting_Currently_Selected_Option = ENUM_TO_INT(PROFILE_SLEEP_MODE) //check if phone is in sleep mode. IF PassedConversationPriority = CONV_PRIORITY_FLOW_ONLY_USE_AMBIENT_SLOT_BYPASS_SLEEPMODE #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Cellphone is in sleep profile but this call has been passed with BYPASS_SLEEPMODE") cdPrintnl() #endif ELSE #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Cellphone is in sleep profile! Unable to take incoming calls.") cdPrintnl() #endif RETURN FALSE ENDIF ENDIF IF g_Cellphone.PhoneDS > PDS_AWAY #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Preload work means phone no longer able to take incoming calls whilst in use!") cdPrintnl() #endif RETURN FALSE ENDIF ENDIF IF g_Phone_Blocked_While_Moving_Down = TRUE #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Cellphone moving offscreen! Can't play your call until it is fully offscreen!") cdPrintnl() #endif RETURN FALSE ENDIF /* Text message preview currently disabled. IF IS_BIT_SET (BitSet_CellphoneDisplay, g_BS_DO_TEXT_MESSAGE_PREVIEW) #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Text Message Preview ongoing. Can't launch call.") cdPrintnl() #endif RETURN FALSE ENDIF */ IF IS_PLAYER_PLAYING (PLAYER_ID()) /*Getting rid of this check... causes too many problems. See bug 766694 IF NOT g_bInMultiplayer WEAPON_TYPE TempCheck GET_CURRENT_PED_WEAPON (PLAYER_PED_ID(), TempCheck) IF TempCheck = WEAPONTYPE_GRENADE #if IS_DEBUG_BUILD cdPrintstring ("DIALOG_PRIV - Can't launch phone to play call as current player character is holding a grenade.") cdPrintnl() #endif RETURN FALSE ENDIF ENDIF */ IF IS_PED_IN_MELEE_COMBAT(PLAYER_PED_ID()) #if IS_DEBUG_BUILD cdPrintstring ("DIALOG_PRIV - Can't launch phone to play call as current player character is in melee combat") cdPrintnl() #endif RETURN FALSE ENDIF IF CHECK_AIMING_FIRING_STATE_FOR_CALL_LAUNCH() #if IS_DEBUG_BUILD cdPrintstring ("DIALOG_PRIV - Can't launch phone to play call as current player character is aiming or firing.") cdPrintnl() #endif RETURN FALSE ENDIF IF IS_PED_SPRINTING(PLAYER_PED_ID()) #if IS_DEBUG_BUILD cdPrintString ("DIALOG_PRIV - Can't launch phone to play call as current player character is sprinting") cdPrintnl() #endif RETURN FALSE ENDIF IF IS_PED_RAGDOLL(PLAYER_PED_ID()) #if IS_DEBUG_BUILD cdPrintstring ("DIALOG_PRIV - Can't launch phone to play call as current player character is ragdolling.") cdPrintnl() #endif RETURN FALSE ENDIF IF IS_PED_IN_PARACHUTE_FREE_FALL (PLAYER_PED_ID()) #if IS_DEBUG_BUILD cdPrintstring ("DIALOG_PRIV - Can't launch phone to play call as current player character is freefalling. Parachute likely in inventory.") cdPrintnl() #endif RETURN FALSE ENDIF IF GET_IS_PED_GADGET_EQUIPPED(PLAYER_PED_ID(), GADGETTYPE_PARACHUTE) #if IS_DEBUG_BUILD cdPrintstring ("DIALOG_PRIV - Can't launch phone to play call as current player character has parachute equipped.") cdPrintnl() #endif RETURN FALSE ENDIF IF NOT g_bInMultiplayer //Multiplayer allows phone use in water and while climbing //IF NOT (g_Cellphone.PhoneOwner = CHAR_FRANKLIN) //i.e Michael or Trevor IF IS_ENTITY_IN_WATER (PLAYER_PED_ID()) //and they are in the water #if IS_DEBUG_BUILD cdPrintstring ("DIALOG_PRIV - Can't launch phone to play call as current player character in water. Still blocking this even though phone can be taken out.") cdPrintnl() #endif RETURN FALSE ENDIF /* Removed on general consensus of bug 1406509 IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) VEHICLE_INDEX tempCP_VehicleIndex tempCP_VehicleIndex = GET_VEHICLE_PED_IS_IN (PLAYER_PED_ID()) //Any additions to the model list below should be cloned in appCamera's abort list as a failsafe. IF (IS_THIS_MODEL_A_BICYCLE(GET_ENTITY_MODEL (tempCP_VehicleIndex))) #if IS_DEBUG_BUILD cdPrintstring ("CELLPHONE_PUB - Can't launch phone to play call. Player on a bicycle. #1116950") cdPrintnl () #endif RETURN FALSE ENDIF ENDIF */ IF IS_PLAYER_CLIMBING (PLAYER_ID()) #if IS_DEBUG_BUILD cdPrintstring ("DIALOG_PRIV - Can't launch phone to play call as current player character is climbing.") cdPrintnl() #endif RETURN FALSE ENDIF IF IS_PED_PLANTING_BOMB (PLAYER_PED_ID()) #if IS_DEBUG_BUILD cdPrintstring ("DIALOG_PRIV - Can't launch phone to play call as current player character is planting a bomb.") cdPrintnl() #endif RETURN FALSE ENDIF IF IS_SPECIAL_ABILITY_ACTIVE (PLAYER_ID()) //This will assert if called in MP. See bug 492556 #if IS_DEBUG_BUILD cdPrintstring ("DIALOG_PRIV - Can't launch phone to play call as current player is using special ability.") cdPrintnl() #endif RETURN FALSE ENDIF ENDIF ENDIF IF IS_CELLPHONE_DISABLED_OR_DISABLED_THIS_FRAME_ONLY() //If the phone is disabled, no phonecall can be made, so we must return false. #if IS_DEBUG_BUILD IF g_Cellphone.PhoneDS = PDS_DISABLED_THIS_FRAME_ONLY cdPrintstring ("DIALOG_PRIV - Cellphone is disabled for this frame! Can't play your call!") cdPrintnl() ELSE cdPrintnl() cdPrintstring ("DIALOG_PRIV - Cellphone is disabled permanently! Can't play your call!") cdPrintnl() ENDIF #endif RETURN FALSE ELSE SWITCH g_Cellphone.PhoneDS CASE PDS_RUNNINGAPP #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Cellphone is running app in simple state. Cannot receive call at this time.") cdPrintnl() #endif RETURN FALSE BREAK CASE PDS_COMPLEXAPP #IF IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Cellphone is running app in complex state. Cannot receive call at this time.") cdPrintnl() #endif RETURN FALSE BREAK //Dangerous to have this return false because of multi-stage calls that involve responses... CASE PDS_ONGOING_CALL #IF IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Cellphone is in ongoing call state. Higher priority call can be accepted") cdPrintnl() #endif BREAK //This can't return false currently because answerphone messages need to cue so they must get through... //There are ways around this. See TASK 11882 CASE PDS_ATTEMPTING_TO_CALL_CONTACT #IF IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Cellphone is attempting to call contact. Higher priority call can be accepted") cdPrintnl() #endif BREAK DEFAULT #IF IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - CheckCurrentConversationStatus says cellphone can receive call...") cdPrintnl() #endif BREAK ENDSWITCH IF IS_BIT_SET (BitSet_CellphoneDisplay, g_BS_SENDING_CELLPHONE_CAM_PIC) #IF IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Cellphone is sending cam pic. Cannot receive incoming call at this time.") cdPrintnl() #endif RETURN FALSE ENDIF ENDIF //Comment in for resolution of 1135663 /* IF NOT IS_BIT_SET (BitSet_CellphoneDisplay_Third, g_CELLPHONE_MOVIE_STREAMING_IN) //Cellphone flashhand cannot SET_BIT (BitSet_CellphoneDisplay, g_BS_LAUNCH_PHONE_TO_HOMESCREEN) RETURN FALSE ENDIF */ //End of comment in for resolution of 1135663 SetUpPhoneConversation() g_UpcomingConversationInboundForCellphone = IsThisInboundForCellphone ENDIF //We need to grab the conversation parameters passed in from the public functions for building and use throughout playback. //Speakers and handlers will need to be grabbed here when implemented from new XLS replacement tool. g_CurrentlyPlayingConvPriority = PassedConversationPriority g_ConversationData.ConversationSegmentToGrab = WhichSegmentLabel BitSet_DialogueHandler = 0 //Critical! Make sure dialogue handler buffer bitset is cleared, so that any buffered conversations cease to poll the system ClearConversationData() //clear old conversation data and set conversation state to CONV_STATE_BUILDING SETUP_NPC_PHONE_PLAYSTATS_PHONECALL() RETURN TRUE ELSE IF g_ConversationStatus = CONV_STATE_HANGUPAWAY #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Conversation state blocked by ongoing phone hang up. Can't play your request this frame.") cdPrintnl() #endif RETURN FALSE ENDIF IF (ENUM_TO_INT(PassedConversationPriority)) < (ENUM_TO_INT(g_CurrentlyPlayingConvPriority)) OR (ENUM_TO_INT(PassedConversationPriority)) = (ENUM_TO_INT(g_CurrentlyPlayingConvPriority)) #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Conversation of higher or equal priority in progress. Can't play your request!") cdPrintnl() #endif RETURN FALSE ELSE #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Interrupting lower priority conversation with your request. Will kill and clean up old conversation and return true when last line has finished.") cdPrintnl() #endif IF PassedConversationPriority = CONV_PRIORITY_NON_CRITICAL_CALL //If dialogue of even lower priority than a non critical call was playing, it would be possible //to abort it by dialling out on 911. This also aborted the phone due to KillAllConversations. #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Interruption aborted. User was trying to trigger non-critical call during ongoing dialogue.") cdPrintnl() #endif ELSE KillAllConversations() //Stop any face-to-face conversation or phonecall then set the conversation state to CONV_STATE_FINISHED so it cleans up properly. ENDIF /*If the conversation has been killed then any requests for face-to-face conversations will now pass through the first CONV_STATE_FREE if gate next cycle //The lines below are legacy for reference. ClearConversationData() SetUpConversation() g_CurrentlyPlayingConvPriority = PassedConversationPriority g_ConversationData.ConversationSegmentToGrab = WhichSegmentLabel g_UpcomingConversationInboundForCellphone = IsThisInboundForCellphone */ RETURN FALSE //should still pass back false this time round. Even though the conversation has been interrupted. The requesting script will still need to call //again now that the slot is free, allowing the handling scripts to build the conversation safely. ENDIF ENDIF ENDFUNC FUNC BOOL CheckCurrentConversationStatusForMultipart (STRING &WhichMPSegmentLabel[], STRING &WhichMPSpecificLabel[], enumConversationPriority PassedConversationPriority, BOOL IsThisInboundForCellphone) //Just using priority just now... would pass in entire struct. #IF IS_DEBUG_BUILD IF g_bEnableConversationMute cdPrintnl() cdPrintstring ("DIALOG_PRIV - g_bEnableConversationMute debug is ENABLED. Can't play conversations (CheckCurrentConversationStatusForMultipart)!") cdPrintnl() RETURN FALSE ENDIF #ENDIF g_Non_Essential_Call_Aborted_and_CS_Already_Free = FALSE //Important. This must be set on every time CheckCurrent... is accessed. IF g_ConversationStatus = CONV_STATE_FREE //No conversation of any priority is currently playing. A face-to-face conversation or a phonecall can be OR g_CurrentlyPlayingConvPriority = CONV_PRIORITY_NON_CRITICAL_CALL //New trial addition to solve 911 / taxi issues. ST 07.05.12 //These measures should prevent users from deliberately holding up mission dialogue by dialling certain numbers. IF g_ConversationStatus <> CONV_STATE_FREE //Must have been the CONV_PRIORITY_NON_CRITICAL_CALL that got us here... IF PassedConversationPriority > g_CurrentlyPlayingConvPriority //The attempting call or dialogue has to be a higher priority! Incoming calls should be! //IF g_CurrentlyPlayingConvPriority = CONV_PRIORITY_NON_CRITICAL_CALL //Double check. All non essential calls need to use this conversation priority. IF IsThisInboundForCellphone = FALSE //Must be face-to-face dialogue or outbound call. May alter to prevent outbound calls interrupting also but any potential //weirdness would indicate dodgy use elsewhere - repeated spamming of IS_CALLING_CONTACT probably. STOP_SCRIPTED_CONVERSATION (FALSE) g_Cellphone.PhoneDS = PDS_AWAY //The phonecall has been stopped, so we force the phone away but don't go through cleanup, //The holders will overwrite the main globals later in the explicit conversation data and SetUpPhoneConversation() g_ConversationStatus = CONV_STATE_FREE g_Non_Essential_Call_Aborted_and_CS_Already_Free = TRUE //Must be set so calls waiting for a question response, don't try to set the conversation //state to finished when the script code that deals with that realises no response is required. g_CallRequiringPlayerResponse = FALSE //Conceivably there might be a very remote chance of another higher priority "with replies" outbound call //interrupting an non-essential call so this should take care of that by making sure the original tidies up. g_TotalMultiparts = 0 g_TotalMultipartsHolder = 0 #if IS_DEBUG_BUILD cdPrintnl() cdPrintnl() cdPrintstring ("DIALOG_PRIV - Multipart. Non-essential call being interrupted automatically.") cdPrintnl() cdPrintnl() #endif ELSE //If we get to here that must mean IsThisInboundForCellphone was TRUE. We will interrupt the call and force a hangup but not play immediately. //Anyone firing off incoming phone calls should really be checking for a return value and repeating their function accordingly. So no shortcuts here! #if IS_DEBUG_BUILD cdPrintnl() cdPrintnl() cdPrintstring ("DIALOG_PRIV - Multipart. Non-essential call interrupted by another incoming call of higher priority. Will return true next frame.") cdPrintnl() cdPrintnl() #endif KillAllConversations() RETURN FALSE ENDIF ELSE #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Multipart. Non-Essential phonecall in progress but it is still higher priority than newly passed request. Can't play latter!") cdPrintnl() #endif RETURN FALSE ENDIF ENDIF IF IS_SCRIPTED_CONVERSATION_ONGOING() #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring("DIALOG_PRIV - CONV_STATE_FREE but scripted conversation ongoing as a result of bad use of HANG_UP_PUT_AWAY_PHONE.") cdPrintnl() #endif RETURN FALSE ENDIF IF IS_SCRIPT_HUD_DISPLAYING (HUDPART_TRANSITIONHUD) #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring("DIALOG_PRIV - CONV_STATE_FREE but transition hud is onscreen. Can't play multipart conversation.") cdPrintnl() #endif RETURN FALSE ENDIF //These master globals are common to both phone and face-to_face conversations. g_BlockToLoad = g_BlockToLoadHolder //copy across required text block to load in additional text slot for this conversation ClearConversationPedsData() //Clear out old master peds struct. g_ConversationPedsStruct = g_ConversationPedsHolderStruct g_IsThisConversationForPhone = g_IsThisConversationForPhoneHolder //As conversation state is free, we can copy across phonecall / face to face differentiator to //a global that remains fixed for the duration of the phonecall. g_IsThisAnMPChatCall = g_IsThisAnMPChatCallHolder #if IS_DEBUG_BUILD IF g_IsThisAnMPChatCallHolder = TRUE cdPrintString ("CHAT_CALL assignment 7 - has been set to TRUE") cdPrintnl() cdPrintnl() ELSE cdPrintString ("CHAT_CALL assignment 8 - has been set to FALSE") cdPrintnl() cdPrintnl() ENDIF #endif #if USE_TU_CHANGES g_ForceDLC_DialogueRequest = g_Holder_ForceDLC_DialogueRequest #if IS_DEBUG_BUILD IF g_ForceDLC_DialogueRequest = TRUE cdPrintnl() cdPrintString ("Jan 14 TU - CheckCurrentConversationStatusForMultipart - g_ForceDLC_DialogueRequest has been set to TRUE ") cdPrintnl() ELSE cdPrintnl() cdPrintString ("Jan 14 TU - CheckCurrentConversationStatusForMultipart - g_ForceDLC_DialogueRequest has been set to FALSE ") cdPrintnl() ENDIF #endif #endif g_ChatCallerString = g_ChatCallerStringHolder g_IsThisAnMpJobOffer = g_IsThisAnMpJobOfferHolder g_PlayingSingleLine = g_PlayingSingleLineHolder //As conversation state is free we can copy across "single line" differentiator to a global fixed for the duration of the conversation. g_SpecificLabel = g_SpecificLabelHolder //if we are playing a single line, this is the specific label that needs to be played. g_PlayingFromLine = g_PlayingFromLineHolder g_IsThisFaceToFacePreloaded = g_IsThisFaceToFacePreloadedHolder g_i_PreloadAutoPlayTime = g_i_PreloadAutoPlayTimeHolder g_ConversationData.g_DisplaySubtitles = g_DisplaySubtitlesHolder g_ConversationData.g_AddToBriefScreen = g_addToBriefScreenHolder g_ConversationData.g_CloneConversation = g_CloneConversationHolder //Multipart conversation work. g_TotalMultiparts = g_TotalMultipartsHolder g_TotalReplyMultiparts = g_TotalReplyMultipartsHolder IF g_b_Is_MultipartRepliesInProgress = FALSE //We only want to overwrite the in progress reply labels with the holders if a multipart reply portion of the call is not taking precedence. g_Multipart_YesSegmentLabel[0] = g_Multipart_YesSegmentLabelHolder[0] g_Multipart_YesSegmentLabel[1] = g_Multipart_YesSegmentLabelHolder[1] g_Multipart_YesSpecificLabel[0] = g_Multipart_YesSpecificLabelHolder[0] g_Multipart_YesSpecificLabel[1] = g_Multipart_YesSpecificLabelHolder[1] g_Multipart_NoSegmentLabel[0] = g_Multipart_NoSegmentLabelHolder[0] g_Multipart_NoSegmentLabel[1] = g_Multipart_NoSegmentLabelHolder[1] g_Multipart_NoSpecificLabel[0] = g_Multipart_NoSpecificLabelHolder[0] g_Multipart_NoSpecificLabel[1] = g_Multipart_NoSpecificLabelHolder[1] #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Copying multipart YES reply holders into main variables.") cdPrintnl() cdPrintstring (g_Multipart_YesSegmentLabel[0]) cdPrintnl() cdPrintstring (g_Multipart_YesSpecificLabel[0]) cdPrintnl() cdPrintstring (g_Multipart_YesSegmentLabel[1]) cdPrintnl() cdPrintstring (g_Multipart_YesSpecificLabel[1]) cdPrintnl() cdPrintnl() cdPrintstring ("DIALOG_PRIV - Copying multipart NO reply holders into main variables.") cdPrintnl() cdPrintstring (g_Multipart_NoSegmentLabel[0]) cdPrintnl() cdPrintstring (g_Multipart_NoSpecificLabel[0]) cdPrintnl() cdPrintstring (g_Multipart_NoSegmentLabel[1]) cdPrintnl() cdPrintstring (g_Multipart_NoSpecificLabel[1]) cdPrintnl() #endif ENDIF IF g_IsThisConversationForPhone //This conversation is a phonecall. We need to do a few checks and some set up for phone specific globals. CLEAR_BIT (BitSet_CellphoneDisplay, g_BS_DISABLE_INCOMING_OR_OUTGOING_CALL_HANGUP) //Make sure the hangup functionality is re-enabled. //Make sure that line skip is available for future calls. CLEAR_BIT (BitSet_CellphoneDisplay_Continued, g_BSC_PREVENT_CELLPHONE_LINESKIP) CLEAR_BIT (BitSet_CellphoneDisplay_Third, g_BSTHIRD_KEEP_MP_CALL_ACTIVE_ON_PAUSE_MENU) //Make sure that future calls will continue to be terminated when the game is paused. #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring("DIALOG_PRIV - Enabled hangup and line skip for this call via direct clear bits.") cdPrintnl() #endif IF IsThisInboundForCellphone //Only block incoming calls in sleep mode. Get_Cellphone_Owner() //IF g_savedGlobals.sCellphoneSettingsData.This_Cellphone_Owner_Settings[g_Cellphone.PhoneOwner].g_SettingList[ENUM_TO_INT(SETTING_PROFILE)].Setting_Currently_Selected_Option = ENUM_TO_INT(PROFILE_SLEEP_MODE) //check if phone is in sleep mode. IF This_Cellphone_Owner_Settings_ListContents[g_Cellphone.PhoneOwner].g_SettingList[ENUM_TO_INT(SETTING_PROFILE)].Setting_Currently_Selected_Option = ENUM_TO_INT(PROFILE_SLEEP_MODE) //check if phone is in sleep mode. IF PassedConversationPriority = CONV_PRIORITY_FLOW_ONLY_USE_AMBIENT_SLOT_BYPASS_SLEEPMODE #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Cellphone is in sleep profile but this call has been passed with BYPASS_SLEEPMODE") cdPrintnl() #endif ELSE #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Cellphone is in sleep profile! Unable to take incoming multipart calls.") cdPrintnl() #endif RETURN FALSE ENDIF ENDIF IF g_Cellphone.PhoneDS > PDS_AWAY #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Preload work means phone no longer able to take incoming multipart calls whilst in use!") cdPrintnl() #endif RETURN FALSE ENDIF ENDIF IF g_Phone_Blocked_While_Moving_Down = TRUE #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Cellphone moving offscreen! Can't play your multipart call until it is fully offscreen!") cdPrintnl() #endif RETURN FALSE ENDIF /* Text message preview currently disabled. IF IS_BIT_SET (BitSet_CellphoneDisplay, g_BS_DO_TEXT_MESSAGE_PREVIEW) #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Text Message Preview ongoing. Can't launch multipart call.") cdPrintnl() #endif RETURN FALSE ENDIF */ IF IS_PLAYER_PLAYING (PLAYER_ID()) /*Getting rid of this check... causes too many problems. See bug 766694 IF NOT g_bInMultiplayer WEAPON_TYPE TempCheck GET_CURRENT_PED_WEAPON (PLAYER_PED_ID(), TempCheck) IF TempCheck = WEAPONTYPE_GRENADE #if IS_DEBUG_BUILD cdPrintstring ("DIALOG_PRIV - Can't launch phone to play multipart call as current player character is holding a grenade.") cdPrintnl() #endif RETURN FALSE ENDIF ENDIF */ IF IS_PED_IN_MELEE_COMBAT(PLAYER_PED_ID()) #if IS_DEBUG_BUILD cdPrintstring ("DIALOG_PRIV - Can't launch phone to play multipart call as current player character is in melee combat") cdPrintnl() #endif RETURN FALSE ENDIF IF CHECK_AIMING_FIRING_STATE_FOR_CALL_LAUNCH() #if IS_DEBUG_BUILD cdPrintstring ("DIALOG_PRIV - Can't launch phone to play multipart call as current player character is aiming or firing.") cdPrintnl() #endif RETURN FALSE ENDIF IF IS_PED_RAGDOLL(PLAYER_PED_ID()) #if IS_DEBUG_BUILD cdPrintstring ("DIALOG_PRIV - Can't launch phone to play multipart call as current player character is ragdolling.") cdPrintnl() #endif RETURN FALSE ENDIF IF IS_PED_IN_PARACHUTE_FREE_FALL (PLAYER_PED_ID()) #if IS_DEBUG_BUILD cdPrintstring ("DIALOG_PRIV - Can't launch phone to play multipart call as current player character is freefalling. Parachute likely in inventory.") cdPrintnl() #endif RETURN FALSE ENDIF IF GET_IS_PED_GADGET_EQUIPPED(PLAYER_PED_ID(), GADGETTYPE_PARACHUTE) #if IS_DEBUG_BUILD cdPrintstring ("DIALOG_PRIV - Can't launch phone to play multipart call as current player character has parachute equipped.") cdPrintnl() #endif RETURN FALSE ENDIF IF NOT g_bInMultiplayer //Multiplayer allows phone use in water and while climbing... IF g_b_Is_MultipartRepliesInProgress = FALSE //2026826 //IF NOT (g_Cellphone.PhoneOwner = CHAR_FRANKLIN) //i.e Michael or Trevor IF IS_ENTITY_IN_WATER (PLAYER_PED_ID()) //and they are in the water #IF IS_DEBUG_BUILD cdPrintstring ("DIALOG_PRIV - Can't launch cellphone to play call as current player character does not have waterproof phone.") //Still block this! cdPrintnl () #endif RETURN FALSE ENDIF IF IS_PLAYER_CLIMBING (PLAYER_ID()) #if IS_DEBUG_BUILD cdPrintstring ("DIALOG_PRIV - Can't launch phone to play multipart call as current player character is climbing.") cdPrintnl() #endif RETURN FALSE ENDIF IF IS_PED_PLANTING_BOMB (PLAYER_PED_ID()) #if IS_DEBUG_BUILD cdPrintstring ("DIALOG_PRIV - Can't launch phone to play call as current player character is planting a bomb.") cdPrintnl() #endif RETURN FALSE ENDIF IF IS_SPECIAL_ABILITY_ACTIVE (PLAYER_ID()) //This will assert if called in MP. See bug 492556 #if IS_DEBUG_BUILD cdPrintstring ("DIALOG_PRIV - Can't launch phone to play multipart call as current player is using special ability.") cdPrintnl() #endif RETURN FALSE ENDIF ENDIF ENDIF ENDIF IF IS_CELLPHONE_DISABLED_OR_DISABLED_THIS_FRAME_ONLY() //If the phone is disabled, no phonecall can be made, so we must return false. #if IS_DEBUG_BUILD IF g_Cellphone.PhoneDS = PDS_DISABLED_THIS_FRAME_ONLY cdPrintstring ("DIALOG_PRIV - Cellphone is disabled for this frame! Can't play your call!") cdPrintnl() ELSE cdPrintnl() cdPrintstring ("DIALOG_PRIV - Cellphone is disabled permanently! Can't play your call!") cdPrintnl() ENDIF #endif RETURN FALSE ELSE SWITCH g_Cellphone.PhoneDS CASE PDS_RUNNINGAPP #IF IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Cellphone is running app in simple state. Cannot receive call at this time.") cdPrintnl() #endif RETURN FALSE BREAK CASE PDS_COMPLEXAPP #IF IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Cellphone is running app in complex state. Cannot receive call at this time.") cdPrintnl() #endif RETURN FALSE BREAK //Dangerous to have this return false because of multi-stage calls that involve responses... CASE PDS_ONGOING_CALL #IF IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Cellphone is in ongoing call state. Higher priority call can be accepted") cdPrintnl() #endif BREAK //This can't return false currently because answerphone messages need to cue so they must get through... //There are ways around this. See TASK 11882 CASE PDS_ATTEMPTING_TO_CALL_CONTACT #IF IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Cellphone is attempting to call contact. Higher priority call can be accepted") cdPrintnl() #endif BREAK DEFAULT #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - CheckCurrentConversationStatus says cellphone can receive call...") cdPrintnl() #endif BREAK ENDSWITCH ENDIF //Comment in for resolution of 1135663 /* IF NOT IS_BIT_SET (BitSet_CellphoneDisplay_Third, g_CELLPHONE_MOVIE_STREAMING_IN) //Cellphone flashhand cannot SET_BIT (BitSet_CellphoneDisplay, g_BS_LAUNCH_PHONE_TO_HOMESCREEN) RETURN FALSE ENDIF */ //End of comment in for resolution of 1135663 SetUpPhoneConversation() g_UpcomingConversationInboundForCellphone = IsThisInboundForCellphone ENDIF //We need to grab the conversation parameters passed in from the public functions for building and use throughout playback. //Speakers and handlers will need to be grabbed here when implemented from new XLS replacement tool. g_CurrentlyPlayingConvPriority = PassedConversationPriority //Multipart conversation work. //Get temporary multiparts into stable holders. IF g_TotalMultiparts > 0 INT mpSegmentIndex = 0 WHILE mpSegmentIndex < g_TotalMultiParts g_ConversationData.MultipartSegmentToGrab[mpSegmentIndex] = WhichMPSegmentLabel[mpSegmentIndex] g_ConversationData.MultipartSpecificLabel[mpSegmentIndex] = WhichMPSpecificLabel[mpSegmentIndex] #if IS_DEBUG_BUILD cdPrintstring ("DIALOG_PRIV copied ") cdPrintstring (g_ConversationData.MultipartSpecificLabel[mpSegmentIndex]) cdPrintstring (" into a stable container.") cdPrintnl() #endif mpSegmentIndex ++ ENDWHILE ENDIF BitSet_DialogueHandler = 0 //Critical! Make sure dialogue handler buffer bitset is cleared, so that any buffered conversations cease to poll the system ClearConversationData() //clear old conversation data and set conversation state to CONV_STATE_BUILDING RETURN TRUE ELSE IF g_ConversationStatus = CONV_STATE_HANGUPAWAY #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Conversation state blocked by ongoing phone hang up. Can't play your request this frame.") cdPrintnl() #endif RETURN FALSE ENDIF IF (ENUM_TO_INT(PassedConversationPriority)) < (ENUM_TO_INT(g_CurrentlyPlayingConvPriority)) OR (ENUM_TO_INT(PassedConversationPriority)) = (ENUM_TO_INT(g_CurrentlyPlayingConvPriority)) #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Conversation of higher or equal priority in progress. Can't play your request!") cdPrintnl() #endif RETURN FALSE ELSE #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Interrupting lower priority conversation with your multipart request. Will kill and clean up old conversation and return true when last line has finished!") cdPrintnl() #endif IF PassedConversationPriority = CONV_PRIORITY_NON_CRITICAL_CALL //If dialogue of even lower priority than a non critical call was playing, it would be possible //to abort it by dialling out on 911. This also aborted the phone due to KillAllConversations. #if IS_DEBUG_BUILD cdPrintnl() cdPrintstring ("DIALOG_PRIV - Interruption aborted. User was trying to trigger non-critical call during ongoing dialogue.") cdPrintnl() #endif ELSE KillAllConversations() //Stop any face-to-face conversation or phonecall then set the conversation state to CONV_STATE_FINISHED so it cleans up properly. ENDIF /*If the conversation has been killed then any requests for face-to-face conversations will now pass through the first CONV_STATE_FREE if gate next cycle //The lines below are legacy for reference. ClearConversationData() SetUpConversation() g_CurrentlyPlayingConvPriority = PassedConversationPriority g_ConversationData.ConversationSegmentToGrab = WhichSegmentLabel g_UpcomingConversationInboundForCellphone = IsThisInboundForCellphone */ RETURN FALSE //should still pass back false this time round. Even though the conversation has been interrupted. The requesting script will still need to call //again now that the slot is free, allowing the handling scripts to build the conversation safely. ENDIF ENDIF ENDFUNC