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

2629 lines
77 KiB
XML
Executable File

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