1915 lines
89 KiB
Python
Executable File
1915 lines
89 KiB
Python
Executable File
//╒═════════════════════════════════════════════════════════════════════════════╕
|
|
//│ Communication Controller Main Script │
|
|
//╞═════════════════════════════════════════════════════════════════════════════╡
|
|
//│ │
|
|
//│ AUTHOR: Ben Rollinson │
|
|
//│ DATE: 12/10/10 │
|
|
//│ DESCRIPTION: A system used to control off-mission communications │
|
|
//│ between characters in the game. │
|
|
//│ │
|
|
//│ -Handles phone communications from characters to the player. │
|
|
//│ -Controls the frequency of communications with the player. │
|
|
//│ -Controls the frequency of communications from each character. │
|
|
//│ -Prioritises all incoming communications to the player. │
|
|
//│ -Intercepts calls from the player to characters. │
|
|
//│ │
|
|
//╘═════════════════════════════════════════════════════════════════════════════╛
|
|
|
|
USING "rage_builtins.sch"
|
|
USING "globals.sch"
|
|
USING "code_control_public.sch"
|
|
USING "comms_control_private.sch"
|
|
USING "comms_control_data_GTA5.sch"
|
|
USING "code_control_data_GTA5.sch"
|
|
USING "cellphone_public.sch"
|
|
USING "vehicle_gen_public.sch"
|
|
USING "ply_to_ply_calls.sch"
|
|
|
|
|
|
//╒═════════════════════════════════════════════════════════════════════════════╕
|
|
//╞═══════════════════════════╡ System Variables ╞═════════════════════════════╡
|
|
//╘═════════════════════════════════════════════════════════════════════════════╛
|
|
|
|
BOOL bCommunicationMade // Has a communication been activated this frame?
|
|
BOOL bFirstCallOngoingHelpQueued
|
|
BOOL bDoCallBranch = FALSE
|
|
BOOL bWaitForForceAwayFlagToClear = FALSE
|
|
INT iTimeCallInitialisationStarted = -1
|
|
|
|
INT iDialBlimpState // Controls blimp delivery (preorder bonus unlocked after landing on the blimp)
|
|
|
|
BOOL bCBActive = FALSE
|
|
INT iCBState = -1 // Controls the state of the CB radio controller
|
|
INT iCBCheckTimer // Stores the last time we checked the CB radio controller
|
|
INT iCBIdentWaitTimer // Stores the last time we played an Ident type of CB conversation
|
|
INT iCBMonConvWaitTimer // Stores the last time we played a Monologue or Conversation type of CB conversation
|
|
INT iSoundID = -1 // Used to stop the background loop noise for the CB radio
|
|
|
|
ENUM CommsControllerState
|
|
CCS_LOOKING_FOR_COMM,
|
|
CCS_INITIALISING_COMM,
|
|
CCS_COMM_IN_PROGRESS
|
|
ENDENUM
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
WIDGET_GROUP_ID widgetID
|
|
BOOL bDoMonologue
|
|
BOOL bDoOneLine
|
|
BOOL bDoConv
|
|
BOOL bFireTestEmails = FALSE
|
|
INT iForceDebugConv = -1
|
|
#ENDIF
|
|
|
|
|
|
CommsControllerState eState = CCS_LOOKING_FOR_COMM
|
|
structPedsForConversation convoStruct
|
|
|
|
//╒═════════════════════════════════════════════════════════════════════════════╕
|
|
//╞═════════════════════════════╡ System Cleanup ╞═════════════════════════════╡
|
|
//╘═════════════════════════════════════════════════════════════════════════════╛
|
|
|
|
// PURPOSE: Ensures that the script gets a chance to cleanup under specific circumstances (ie: moving from SP to MP)
|
|
PROC Script_Cleanup()
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Comms controller cleaning up.")
|
|
|
|
g_iCallInProgress = -1
|
|
|
|
CC_CallData sBlankCallData
|
|
INT index
|
|
REPEAT g_savedGlobals.sCommsControlData.iNoMissedCalls index
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "SCRIPT CLEANUP: Removing call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sMissedCalls[index].sCommData.eID), " from the missed call queue.")
|
|
//Clear the missed caller status of the missed call contact.
|
|
CLEAR_MISSED_CALLER_STATUS_FOR_CONTACT(g_savedGlobals.sCommsControlData.sMissedCalls[index].sCommData.eNPCCharacter)
|
|
//Move all array positions up one place and overwrite the call we want to remove.
|
|
INT index2
|
|
FOR index2 = index TO (g_savedGlobals.sCommsControlData.iNoMissedCalls-2)
|
|
g_savedGlobals.sCommsControlData.sMissedCalls[index2] = g_savedGlobals.sCommsControlData.sMissedCalls[index2+1]
|
|
ENDFOR
|
|
//Set the old last missed call in the queue to be blank data to be safe.
|
|
g_savedGlobals.sCommsControlData.sMissedCalls[g_savedGlobals.sCommsControlData.iNoMissedCalls-1] = sBlankCallData
|
|
//Reduce the counter tracking the number of missed calls in the queue.
|
|
g_savedGlobals.sCommsControlData.iNoMissedCalls--
|
|
ENDREPEAT
|
|
|
|
//Currently nothing to clean up.
|
|
TERMINATE_THIS_THREAD()
|
|
ENDPROC
|
|
|
|
|
|
//╒═════════════════════════════════════════════════════════════════════════════╕
|
|
//╞══════════════════════════╡ System Subfunctions ╞═══════════════════════════╡
|
|
//╘═════════════════════════════════════════════════════════════════════════════╛
|
|
|
|
PROC Pause_Timers()
|
|
INT index
|
|
INT iFrameTime = CEIL(GET_FRAME_TIME()*1000)
|
|
|
|
//Extend global timer
|
|
g_iGlobalWaitTime += iFrameTime
|
|
|
|
//Extend queued call timers.
|
|
REPEAT g_savedGlobals.sCommsControlData.iNoQueuedCalls index
|
|
g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.iQueueTime += iFrameTime
|
|
ENDREPEAT
|
|
|
|
//Extend queued text message timers.
|
|
REPEAT g_savedGlobals.sCommsControlData.iNoQueuedTexts index
|
|
g_savedGlobals.sCommsControlData.sQueuedTexts[index].sCommData.iQueueTime += iFrameTime
|
|
ENDREPEAT
|
|
|
|
//Extend queued email timers.
|
|
REPEAT g_savedGlobals.sCommsControlData.iNoQueuedEmails index
|
|
g_savedGlobals.sCommsControlData.sQueuedEmails[index].sCommData.iQueueTime += iFrameTime
|
|
ENDREPEAT
|
|
|
|
//Extend queued chat call timers.
|
|
REPEAT g_savedGlobals.sCommsControlData.iNoChatCalls index
|
|
g_savedGlobals.sCommsControlData.sChatCalls[index].sCommData.iQueueTime += iFrameTime
|
|
ENDREPEAT
|
|
|
|
//Extend character timers.
|
|
INT iMaxCharacter = ENUM_TO_INT(GLOBAL_CHARACTER_SHEET_GET_MAX_CHARACTERS_FOR_GAMEMODE())
|
|
REPEAT iMaxCharacter index
|
|
g_iCharWaitTime[index] += iFrameTime
|
|
ENDREPEAT
|
|
ENDPROC
|
|
|
|
|
|
PROC Execute_Special_Code_For_Communication(CC_CommData &sCommData)
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Checking for CodeID to run for communication ", GET_COMM_ID_DEBUG_STRING(sCommData.eID), "...")
|
|
|
|
//Double check we don't have an invalid CID set.
|
|
IF sCommData.eExecuteOnCompleteID = CID_MAX
|
|
SCRIPT_ASSERT("Execute_Special_Code_For_Communication: A communication had a CodeID of CID_MAX set. This is an invalid CodeID and should be guarded against!")
|
|
EXIT
|
|
ENDIF
|
|
|
|
//Add contact to character phonebooks if requested.
|
|
IF IS_BIT_SET(sCommData.iSettings, COMM_BIT_ADD_CONTACT)
|
|
INT iPlayerIndex
|
|
REPEAT 3 iPlayerIndex
|
|
IF IS_BIT_SET(sCommData.iPlayerCharBitset, iPlayerIndex)
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Adding contact ", GET_CHARSHEET_DISPLAY_STRING_FROM_CHARSHEET(sCommData.eNPCCharacter),
|
|
" to ", GET_CHARSHEET_DISPLAY_STRING_FROM_CHARSHEET(INT_TO_ENUM(enumCharacterList, iPlayerIndex)),
|
|
"'s phonebook as communication ", GET_COMM_ID_DEBUG_STRING(sCommData.eID), " sends.")
|
|
ADD_CONTACT_TO_PHONEBOOK(sCommData.eNPCCharacter, INT_TO_ENUM(enumPhoneBookPresence, iPlayerIndex), FALSE)
|
|
ENDIF
|
|
ENDREPEAT
|
|
ENDIF
|
|
|
|
//Check if the CID has been set to something of meaning.
|
|
IF sCommData.eExecuteOnCompleteID <> CID_BLANK
|
|
//Tell code controller to execute CID without a delay.
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Running ", Get_Debug_String_For_Communication_Code_ID(sCommData.eExecuteOnCompleteID), " with no delay.")
|
|
Execute_Code_ID(sCommData.eExecuteOnCompleteID)
|
|
EXIT
|
|
ENDIF
|
|
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "No CodeID found.")
|
|
ENDPROC
|
|
|
|
|
|
PROC Process_Cleanup_Of_Sent_Text(INT &gameTime, CC_TextMessageData &sentText)
|
|
//Execute any special code assigned to this text.
|
|
Execute_Special_Code_For_Communication(sentText.sCommData)
|
|
//Register this as the last completed text message.
|
|
g_savedGlobals.sCommsControlData.eLastCompletedText = sentText.sCommData.eID
|
|
//Update the system's global wait time.
|
|
g_iGlobalWaitTime = gameTime + CC_GLOBAL_DELAY_BETWEEN_COMMS
|
|
//Update the sending character's wait time.
|
|
g_iCharWaitTime[sentText.sCommData.eNPCCharacter] = gameTime + CC_CHARACTER_DELAY_BETWEEN_COMMS
|
|
//Remove text from sent text queue.
|
|
PRIVATE_Remove_Text_From_Sent_Queue(sentText.sCommData.eID)
|
|
ENDPROC
|
|
|
|
|
|
PROC Process_Cleanup_Of_Sent_Email(INT &gameTime, CC_EmailData &sentEmail)
|
|
//Execute any special code assigned to this text.
|
|
Execute_Special_Code_For_Communication(sentEmail.sCommData)
|
|
//Register this as the last completed text message.
|
|
g_savedGlobals.sCommsControlData.eLastCompletedEmail = sentEmail.sCommData.eID
|
|
//Update the system's global wait time.
|
|
g_iGlobalWaitTime = gameTime + CC_GLOBAL_DELAY_BETWEEN_COMMS
|
|
//Update the sending character's wait time.
|
|
IF sentEmail.sCommData.eNPCCharacter != CHAR_BLANK_ENTRY
|
|
g_iCharWaitTime[sentEmail.sCommData.eNPCCharacter] = gameTime + CC_CHARACTER_DELAY_BETWEEN_COMMS
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
PROC Check_For_Queued_Phonecall_To_Player_To_Run(INT &gameTime)
|
|
// Ensure we are a playable character
|
|
IF NOT IS_PLAYER_PED_PLAYABLE(GET_CURRENT_PLAYER_PED_ENUM())
|
|
EXIT
|
|
ENDIF
|
|
|
|
INT index = 0
|
|
|
|
WHILE (index < g_savedGlobals.sCommsControlData.iNoQueuedCalls) AND NOT bCommunicationMade
|
|
|
|
Run_Call_Timer_Safeguard(g_savedGlobals.sCommsControlData.sQueuedCalls[index])
|
|
|
|
//Is this call going to a playable character?
|
|
IF NOT IS_BIT_SET(g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.iSettings, COMM_BIT_FROM_CHAR_IS_PLAYER)
|
|
|
|
//Check if the priority of this call is high enough to override character and global timers.
|
|
BOOL bPriorityTimerOverride = FALSE
|
|
IF ENUM_TO_INT(g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.ePriority) >= ENUM_TO_INT(CPR_VERY_HIGH)
|
|
bPriorityTimerOverride = TRUE
|
|
ENDIF
|
|
|
|
//Is the global wait timer at 0?
|
|
IF gameTime >= g_iGlobalWaitTime
|
|
OR bPriorityTimerOverride
|
|
OR IS_BIT_SET(g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.iSettings, COMM_BIT_INGORE_GLOBAL_DELAY)
|
|
|
|
//Is this queued phonecall the correct priority?
|
|
IF g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.ePriority = g_savedGlobals.sCommsControlData.eCharacterPriorityLevel[GET_CURRENT_PLAYER_PED_ENUM()]
|
|
OR NOT IS_BIT_SET(g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.iPlayerCharBitset, GET_CURRENT_PLAYER_PED_INT())
|
|
|
|
//Are the characters involved in this call waiting for timers?
|
|
IF gameTime >= g_iCharWaitTime[g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.eNPCCharacter]
|
|
OR bPriorityTimerOverride
|
|
|
|
//Is this queued call ready to be triggered?
|
|
IF gameTime >= g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.iQueueTime
|
|
//Attempt to make the call.
|
|
IF PRIVATE_Attempt_Make_Queued_Call(g_savedGlobals.sCommsControlData.sQueuedCalls[index], bDoCallBranch)
|
|
//Register a call in progress.
|
|
g_iCallInProgress = index
|
|
iTimeCallInitialisationStarted = -1
|
|
eState = CCS_INITIALISING_COMM
|
|
g_savedGlobals.sCommsControlData.bLastCallHadResponse = FALSE
|
|
bCommunicationMade = TRUE
|
|
|
|
IF HAS_CELLPHONE_JUST_BEEN_FORCED_AWAY()
|
|
bWaitForForceAwayFlagToClear = TRUE
|
|
ENDIF
|
|
ELSE
|
|
//Call failed to start. Reschedule the call.
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.eID), " failed to start. Rescheduling.")
|
|
PRIVATE_Set_New_Communication_Queue_Time(gameTime, g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
index++
|
|
|
|
ENDWHILE
|
|
ENDPROC
|
|
|
|
|
|
PROC Check_For_Queued_Phonecall_From_Player_To_Run(INT &gameTime)
|
|
|
|
// Ensure we are a playable character
|
|
IF NOT IS_PLAYER_PED_PLAYABLE(GET_CURRENT_PLAYER_PED_ENUM())
|
|
EXIT
|
|
ENDIF
|
|
|
|
INT index = 0
|
|
|
|
WHILE (index < g_savedGlobals.sCommsControlData.iNoQueuedCalls) AND NOT bCommunicationMade
|
|
|
|
Run_Call_Timer_Safeguard(g_savedGlobals.sCommsControlData.sQueuedCalls[index])
|
|
|
|
//Is this call coming from a playable character?
|
|
IF IS_BIT_SET(g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.iSettings, COMM_BIT_FROM_CHAR_IS_PLAYER)
|
|
|
|
//Check if the priority of this call is high enough to override character and global timers.
|
|
BOOL bPriorityTimerOverride = FALSE
|
|
IF ENUM_TO_INT(g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.ePriority) >= ENUM_TO_INT(CPR_VERY_HIGH)
|
|
bPriorityTimerOverride = TRUE
|
|
ENDIF
|
|
|
|
//Is the global wait timer at 0?
|
|
IF gameTime >= g_iGlobalWaitTime
|
|
OR IS_BIT_SET(g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.iSettings, COMM_BIT_INGORE_GLOBAL_DELAY)
|
|
OR bPriorityTimerOverride
|
|
|
|
//Is this queued phonecall the correct priority?
|
|
IF g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.ePriority = g_savedGlobals.sCommsControlData.eCharacterPriorityLevel[GET_CURRENT_PLAYER_PED_ENUM()]
|
|
OR NOT IS_BIT_SET(g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.iPlayerCharBitset, GET_CURRENT_PLAYER_PED_INT())
|
|
|
|
//Is this queued call ready to be triggered?
|
|
IF gameTime >= g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.iQueueTime
|
|
|
|
//Attempt to make the call.
|
|
IF PRIVATE_Attempt_Make_Queued_Call(g_savedGlobals.sCommsControlData.sQueuedCalls[index], bDoCallBranch)
|
|
//Register a call in progress.
|
|
g_iCallInProgress = index
|
|
iTimeCallInitialisationStarted = -1
|
|
eState = CCS_INITIALISING_COMM
|
|
g_savedGlobals.sCommsControlData.bLastCallHadResponse = FALSE
|
|
bCommunicationMade = TRUE
|
|
|
|
IF HAS_CELLPHONE_JUST_BEEN_FORCED_AWAY()
|
|
bWaitForForceAwayFlagToClear = TRUE
|
|
ENDIF
|
|
ELSE
|
|
//Call failed to start. Reschedule the call.
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.eID), " failed to start. Rescheduling.")
|
|
PRIVATE_Set_New_Communication_Queue_Time(gameTime, g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData)
|
|
ENDIF
|
|
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
index++
|
|
|
|
ENDWHILE
|
|
|
|
ENDPROC
|
|
|
|
|
|
PROC Check_For_Queued_Text_Message_To_Run(INT &gameTime)
|
|
|
|
// Ensure we are a playable character
|
|
IF NOT IS_PLAYER_PED_PLAYABLE(GET_CURRENT_PLAYER_PED_ENUM())
|
|
EXIT
|
|
ENDIF
|
|
|
|
INT index = 0
|
|
|
|
WHILE (index < g_savedGlobals.sCommsControlData.iNoQueuedTexts) AND NOT bCommunicationMade
|
|
|
|
Run_Text_Timer_Safeguard(g_savedGlobals.sCommsControlData.sQueuedTexts[index])
|
|
|
|
//Check if the priority of this text is high enough to override character and global timers.
|
|
BOOL bPriorityTimerOverride = FALSE
|
|
IF ENUM_TO_INT(g_savedGlobals.sCommsControlData.sQueuedTexts[index].sCommData.ePriority) >= ENUM_TO_INT(CPR_VERY_HIGH)
|
|
bPriorityTimerOverride = TRUE
|
|
ENDIF
|
|
|
|
//Is the global wait timer at 0?
|
|
IF gameTime >= g_iGlobalWaitTime
|
|
OR IS_BIT_SET(g_savedGlobals.sCommsControlData.sQueuedTexts[index].sCommData.iSettings, COMM_BIT_INGORE_GLOBAL_DELAY)
|
|
OR bPriorityTimerOverride
|
|
|
|
//Are the characters involved in this text waiting for timers?
|
|
IF gameTime >= g_iCharWaitTime[g_savedGlobals.sCommsControlData.sQueuedTexts[index].sCommData.eNPCCharacter]
|
|
OR bPriorityTimerOverride
|
|
//Is this queued text ready to be triggered?
|
|
IF gameTime >= g_savedGlobals.sCommsControlData.sQueuedTexts[index].sCommData.iQueueTime
|
|
|
|
//Attempt to send the text.
|
|
IF PRIVATE_Attempt_Send_Queued_Text_Message(g_savedGlobals.sCommsControlData.sQueuedTexts[index])
|
|
//Add a copy of the text message that we've just sent to the sent text queue.
|
|
PRIVATE_Add_Text_To_Sent_Text_Queue(g_savedGlobals.sCommsControlData.sQueuedTexts[index])
|
|
//Tell the communication controller that we're waiting for a response.
|
|
g_savedGlobals.sCommsControlData.bLastTextHadResponse = FALSE
|
|
//Remove text entry from queue.
|
|
PRIVATE_Remove_Text_From_Queue(index)
|
|
bCommunicationMade = TRUE
|
|
ELSE
|
|
//Text message failed. Reschedule the text message.
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Text ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedTexts[index].sCommData.eID), " failed to send. Rescheduling.")
|
|
PRIVATE_Set_New_Communication_Queue_Time(gameTime, g_savedGlobals.sCommsControlData.sQueuedTexts[index].sCommData, TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
index++
|
|
|
|
ENDWHILE
|
|
|
|
ENDPROC
|
|
|
|
|
|
PROC Check_For_Quick_Calls_To_Run(INT &gameTime)
|
|
INT index
|
|
|
|
//Check if there are any quick calls to run.
|
|
REPEAT g_savedGlobals.sCommsControlData.iNoQueuedCalls index
|
|
IF IS_BIT_SET(g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.iSettings, COMM_BIT_CALL_IS_QUICK)
|
|
IF IS_CALLING_CONTACT(g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.eNPCCharacter)
|
|
IF gameTime >= g_iCharWaitTime[g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.eNPCCharacter]
|
|
|
|
//Attempt to make the quick call.
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Attempting to make outgoing quick call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.eID), ".")
|
|
IF PRIVATE_Attempt_Make_Outgoing_Call(g_savedGlobals.sCommsControlData.sQueuedCalls[index], bDoCallBranch)
|
|
//Register a call in progress.
|
|
g_iCallInProgress = index
|
|
iTimeCallInitialisationStarted = -1
|
|
eState = CCS_INITIALISING_COMM
|
|
g_savedGlobals.sCommsControlData.bLastCallHadResponse = FALSE
|
|
bCommunicationMade = TRUE
|
|
|
|
IF HAS_CELLPHONE_JUST_BEEN_FORCED_AWAY()
|
|
bWaitForForceAwayFlagToClear = TRUE
|
|
ENDIF
|
|
ELSE
|
|
//Call failed to start. Reschedule the call.
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Quick call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.eID), " failed to start. Rescheduling.")
|
|
PRIVATE_Set_New_Communication_Queue_Time(gameTime, g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData)
|
|
ENDIF
|
|
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDREPEAT
|
|
ENDPROC
|
|
|
|
|
|
PROC Check_For_Missed_Calls_To_Run(INT &gameTime)
|
|
INT index
|
|
|
|
//Check if there are any missed calls queued to run.
|
|
REPEAT g_savedGlobals.sCommsControlData.iNoMissedCalls index
|
|
|
|
IF IS_CALLING_CONTACT(g_savedGlobals.sCommsControlData.sMissedCalls[index].sCommData.eNPCCharacter)
|
|
IF gameTime >= g_iCharWaitTime[g_savedGlobals.sCommsControlData.sMissedCalls[index].sCommData.eNPCCharacter]
|
|
//Try and get the missed call queue index.
|
|
INT iQueueIndex = PRIVATE_Get_Missed_Call_Queue_Index(g_savedGlobals.sCommsControlData.sMissedCalls[index].sCommData.eID)
|
|
//Call not in the queue. Add it.
|
|
IF iQueueIndex = -1
|
|
iQueueIndex = g_savedGlobals.sCommsControlData.iNoQueuedCalls
|
|
g_savedGlobals.sCommsControlData.sQueuedCalls[iQueueIndex] = g_savedGlobals.sCommsControlData.sMissedCalls[index]
|
|
g_savedGlobals.sCommsControlData.iNoQueuedCalls++
|
|
|
|
//Update character queue priority levels in case this new call is the new highest priority communication.
|
|
INT iPlayerIndex
|
|
REPEAT 3 iPlayerIndex
|
|
IF IS_BIT_SET(g_savedGlobals.sCommsControlData.sMissedCalls[index].sCommData.iPlayerCharBitset, iPlayerIndex)
|
|
PRIVATE_Update_Playable_Character_Priority_Level(INT_TO_ENUM(enumCharacterList, iPlayerIndex))
|
|
ENDIF
|
|
ENDREPEAT
|
|
ENDIF
|
|
|
|
//Attempt to make the missed call.
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Attempting to make outgoing missed call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[iQueueIndex].sCommData.eID), ".")
|
|
IF PRIVATE_Attempt_Make_Outgoing_Call(g_savedGlobals.sCommsControlData.sQueuedCalls[iQueueIndex], bDoCallBranch)
|
|
//Register a call in progress.
|
|
g_iCallInProgress = index
|
|
iTimeCallInitialisationStarted = -1
|
|
eState = CCS_INITIALISING_COMM
|
|
g_savedGlobals.sCommsControlData.bLastCallHadResponse = FALSE
|
|
bCommunicationMade = TRUE
|
|
|
|
IF HAS_CELLPHONE_JUST_BEEN_FORCED_AWAY()
|
|
bWaitForForceAwayFlagToClear = TRUE
|
|
ENDIF
|
|
ELSE
|
|
//Call failed to start. Reschedule the call.
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Missed call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[iQueueIndex].sCommData.eID), " failed to start. Rescheduling.")
|
|
PRIVATE_Set_New_Communication_Queue_Time(gameTime, g_savedGlobals.sCommsControlData.sQueuedCalls[iQueueIndex].sCommData)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDREPEAT
|
|
ENDPROC
|
|
|
|
|
|
PROC Check_For_Chat_Calls_To_Run(INT &gameTime)
|
|
INT index
|
|
|
|
//Check if there are any chat calls to run.
|
|
REPEAT g_savedGlobals.sCommsControlData.iNoChatCalls index
|
|
|
|
enumCharacterList ePlayer = GET_CURRENT_PLAYER_PED_ENUM()
|
|
IF IS_PLAYER_PED_PLAYABLE(ePlayer)
|
|
IF IS_BIT_SET(g_savedGlobals.sCommsControlData.sChatCalls[index].sCommData.iPlayerCharBitset, ENUM_TO_INT(ePlayer))
|
|
IF IS_CALLING_CONTACT(g_savedGlobals.sCommsControlData.sChatCalls[index].sCommData.eNPCCharacter)
|
|
IF gameTime >= g_iCharWaitTime[g_savedGlobals.sCommsControlData.sChatCalls[index].sCommData.eNPCCharacter]
|
|
|
|
//Chat call should be able to run. Check if we have it in the main queue yet.
|
|
BOOL bAlreadyQueued = FALSE
|
|
INT iQueueIndex = 0
|
|
WHILE (iQueueIndex < g_savedGlobals.sCommsControlData.iNoQueuedCalls) AND NOT bAlreadyQueued
|
|
IF g_savedGlobals.sCommsControlData.sQueuedCalls[iQueueIndex].sCommData.eID = g_savedGlobals.sCommsControlData.sChatCalls[index].sCommData.eID
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Chat call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sChatCalls[index].sCommData.eID), " already in main queue.")
|
|
bAlreadyQueued = TRUE
|
|
ENDIF
|
|
iQueueIndex++
|
|
ENDWHILE
|
|
|
|
//Add the chat call to the main communication queue.
|
|
IF NOT bAlreadyQueued
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Player is calling contact for chat call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sChatCalls[index].sCommData.eID), ". Adding to main call queue.")
|
|
iQueueIndex = g_savedGlobals.sCommsControlData.iNoQueuedCalls
|
|
IF iQueueIndex < CC_MAX_QUEUED_CALLS
|
|
g_savedGlobals.sCommsControlData.sQueuedCalls[iQueueIndex] = g_savedGlobals.sCommsControlData.sChatCalls[index]
|
|
g_savedGlobals.sCommsControlData.iNoQueuedCalls++
|
|
|
|
//Update character queue priority levels in case this new call is the new highest priority communication.
|
|
INT iPlayerIndex
|
|
REPEAT 3 iPlayerIndex
|
|
IF IS_BIT_SET(g_savedGlobals.sCommsControlData.sQueuedCalls[iQueueIndex].sCommData.iPlayerCharBitset, iPlayerIndex)
|
|
PRIVATE_Update_Playable_Character_Priority_Level(INT_TO_ENUM(enumCharacterList, iPlayerIndex))
|
|
ENDIF
|
|
ENDREPEAT
|
|
ELSE
|
|
SCRIPT_ASSERT("Check_For_Chat_Calls_To_Run: Tried to add a chat call to the main queue, but it was full. Bug BenR.")
|
|
EXIT
|
|
ENDIF
|
|
ENDIF
|
|
|
|
//Attempt to make the chat call.
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Attempting to make outgoing chat call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[iQueueIndex].sCommData.eID), ".")
|
|
IF PRIVATE_Attempt_Make_Outgoing_Chat_Call(g_savedGlobals.sCommsControlData.sQueuedCalls[iQueueIndex])
|
|
//Register a call in progress.
|
|
g_iCallInProgress = iQueueIndex
|
|
iTimeCallInitialisationStarted = -1
|
|
eState = CCS_INITIALISING_COMM
|
|
g_savedGlobals.sCommsControlData.bLastCallHadResponse = FALSE
|
|
bCommunicationMade = TRUE
|
|
|
|
IF HAS_CELLPHONE_JUST_BEEN_FORCED_AWAY()
|
|
bWaitForForceAwayFlagToClear = TRUE
|
|
ENDIF
|
|
ELSE
|
|
//Call failed to start. Remove chat call from the main queue.
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Chat call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sChatCalls[iQueueIndex].sCommData.eID), " failed to start.")
|
|
PRIVATE_Remove_Call_From_Queue(iQueueIndex)
|
|
ENDIF
|
|
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDREPEAT
|
|
ENDPROC
|
|
|
|
|
|
PROC Check_For_Queued_Email_To_Run(INT &gameTime)
|
|
|
|
// Ensure we are a playable character
|
|
IF NOT IS_PLAYER_PED_PLAYABLE(GET_CURRENT_PLAYER_PED_ENUM())
|
|
EXIT
|
|
ENDIF
|
|
|
|
INT index = 0
|
|
|
|
WHILE (index < g_savedGlobals.sCommsControlData.iNoQueuedEmails) AND NOT bCommunicationMade
|
|
|
|
Run_Email_Timer_Safeguard(g_savedGlobals.sCommsControlData.sQueuedEmails[index])
|
|
|
|
//Check if the priority of this text is high enough to override character and global timers.
|
|
BOOL bPriorityTimerOverride = FALSE
|
|
IF ENUM_TO_INT(g_savedGlobals.sCommsControlData.sQueuedEmails[index].sCommData.ePriority) >= ENUM_TO_INT(CPR_VERY_HIGH)
|
|
bPriorityTimerOverride = TRUE
|
|
ENDIF
|
|
|
|
//Is the global wait timer at 0?
|
|
IF gameTime >= g_iGlobalWaitTime
|
|
OR IS_BIT_SET(g_savedGlobals.sCommsControlData.sQueuedEmails[index].sCommData.iSettings, COMM_BIT_INGORE_GLOBAL_DELAY)
|
|
OR bPriorityTimerOverride
|
|
|
|
//Are the characters involved in this call waiting for timers?
|
|
IF gameTime >= g_iCharWaitTime[g_savedGlobals.sCommsControlData.sQueuedEmails[index].sCommData.eNPCCharacter]
|
|
OR bPriorityTimerOverride
|
|
//Is this queued text ready to be triggered?
|
|
IF gameTime >= g_savedGlobals.sCommsControlData.sQueuedEmails[index].sCommData.iQueueTime
|
|
|
|
//Attempt to send the text.
|
|
IF PRIVATE_Attempt_Send_Queued_Email(g_savedGlobals.sCommsControlData.sQueuedEmails[index])
|
|
//Remove text entry from queue.
|
|
iTimeCallInitialisationStarted = -1
|
|
Process_Cleanup_Of_Sent_Email(gameTime, g_savedGlobals.sCommsControlData.sQueuedEmails[index])
|
|
PRIVATE_Remove_Email_From_Queue(index)
|
|
bCommunicationMade = TRUE
|
|
ELSE
|
|
//Email failed. Reschedule the email.
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Email ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedEmails[index].sCommData.eID), " failed to send. Rescheduling.")
|
|
PRIVATE_Set_New_Communication_Queue_Time(gameTime, g_savedGlobals.sCommsControlData.sQueuedEmails[index].sCommData)
|
|
ENDIF
|
|
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
index++
|
|
|
|
ENDWHILE
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Activate the closest blimp vehicle gen to the player
|
|
FUNC BOOL Activate_Closest_Blimp_Location()
|
|
|
|
IF IS_PED_INJURED(PLAYER_PED_ID())
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
INT i
|
|
FLOAT fShortestDist = 99999.99
|
|
INT iClosestGen = -1
|
|
VECTOR vGenCoords[2]
|
|
VECTOR vPlayerCoords = GET_ENTITY_COORDS(PLAYER_PED_ID())
|
|
|
|
vGenCoords[0] = << 1133.21, 120.20, 80.9 >>
|
|
vGenCoords[1] = << -806.31, -2679.65, 13.9 >>
|
|
|
|
REPEAT 2 i
|
|
IF GET_DISTANCE_BETWEEN_COORDS(vPlayerCoords, vGenCoords[i]) < fShortestDist
|
|
fShortestDist = GET_DISTANCE_BETWEEN_COORDS(vPlayerCoords, vGenCoords[i])
|
|
iClosestGen = i
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
CLEANUP_VEHICLE_GEN_VEHICLE(VEHGEN_BLIMP_CASINO)
|
|
CLEANUP_VEHICLE_GEN_VEHICLE(VEHGEN_BLIMP_DOCKS)
|
|
|
|
// B*1558610 - Swap gen if the player is within 250m of the blimp spawn position
|
|
IF IS_SPHERE_VISIBLE(vGenCoords[iClosestGen], 300) OR fShortestDist < 300
|
|
|
|
// Swap to Docks from Casino...
|
|
IF iClosestGen = 0
|
|
iClosestGen = 1
|
|
|
|
// ...or vice versa
|
|
ELSE
|
|
iClosestGen = 0
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Casino
|
|
IF iClosestGen = 0
|
|
SET_VEHICLE_GEN_AVAILABLE(VEHGEN_BLIMP_CASINO, TRUE)
|
|
CLEAR_MUST_LEAVE_AREA_VEHICLE_GEN_FLAG(VEHGEN_BLIMP_CASINO)
|
|
RETURN TRUE
|
|
|
|
// Docks
|
|
ELIF iClosestGen = 1
|
|
SET_VEHICLE_GEN_AVAILABLE(VEHGEN_BLIMP_DOCKS, TRUE)
|
|
CLEAR_MUST_LEAVE_AREA_VEHICLE_GEN_FLAG(VEHGEN_BLIMP_DOCKS)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
FUNC BOOL Is_Blimp_Nearby()
|
|
VEHICLE_INDEX vehArray[15]
|
|
INT numberOfVehicles = GET_PED_NEARBY_VEHICLES(PLAYER_PED_ID(),vehArray)
|
|
INT i
|
|
FOR i = 0 TO (numberOfVehicles - 1)
|
|
IF GET_ENTITY_MODEL(vehArray[i]) = BLIMP
|
|
IF NOT IS_ENTITY_DEAD(vehArray[i]) AND IS_VEHICLE_DRIVEABLE(vehArray[i])
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDFOR
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
FUNC BOOL Is_Player_In_Blimp()
|
|
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID(),TRUE)
|
|
IF GET_ENTITY_MODEL(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID(), TRUE)) = BLIMP
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
PROC Check_For_Ability_Calls_To_Run(INT &gameTime)
|
|
STRING sRootLabel[5]
|
|
|
|
// Dial a Blimp!
|
|
SWITCH iDialBlimpState
|
|
|
|
// Wait for player to call
|
|
CASE 0
|
|
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
|
|
IF IS_CALLING_CONTACT(CHAR_BLIMP)
|
|
|
|
// Has preorder content
|
|
IF IS_PREORDER_GAME()
|
|
OR IS_COLLECTORS_EDITION_GAME()
|
|
OR IS_SPECIAL_EDITION_GAME()
|
|
OR IS_JAPANESE_SPECIAL_EDITION_GAME()
|
|
OR IS_LAST_GEN_PLAYER()
|
|
|
|
// Don't connect if a blimp already exists in the world
|
|
IF NOT DOES_ENTITY_EXIST(GET_VEHICLE_GEN_VEHICLE_INDEX(VEHGEN_BLIMP_CASINO))
|
|
AND NOT DOES_ENTITY_EXIST(GET_VEHICLE_GEN_VEHICLE_INDEX(VEHGEN_BLIMP_DOCKS))
|
|
//If the blip is called in a mission trigger we get an assert B*1868387
|
|
AND g_iOffMissionCutsceneRequestAllowed = NULL_OFFMISSION_CUTSCENE_REQUEST
|
|
AND NOT Is_Player_In_Blimp()
|
|
AND NOT Is_Blimp_Nearby()
|
|
|
|
// Michael
|
|
IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL
|
|
ADD_PED_FOR_DIALOGUE(convoStruct, 0, PLAYER_PED_ID(), "MICHAEL")
|
|
ADD_PED_FOR_DIALOGUE(convoStruct, 3, NULL, "DBLIMPOperator")
|
|
|
|
sRootLabel[0] = "DAB_HELLO"
|
|
sRootLabel[1] = "DAB_MICHAEL"
|
|
sRootLabel[2] = "DAB_SEND"
|
|
sRootLabel[3] = "DAB_THANK_M"
|
|
sRootLabel[4] = "DAB_BYE"
|
|
|
|
// Franklin
|
|
ELIF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_FRANKLIN
|
|
ADD_PED_FOR_DIALOGUE(convoStruct, 1, PLAYER_PED_ID(), "FRANKLIN")
|
|
ADD_PED_FOR_DIALOGUE(convoStruct, 3, NULL, "DBLIMPOperator")
|
|
|
|
sRootLabel[0] = "DAB_HELLO"
|
|
sRootLabel[1] = "DAB_FRANKLIN"
|
|
sRootLabel[2] = "DAB_SEND"
|
|
sRootLabel[3] = "DAB_THANK_F"
|
|
sRootLabel[4] = "DAB_BYE"
|
|
|
|
// Trevor
|
|
ELIF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_TREVOR
|
|
ADD_PED_FOR_DIALOGUE(convoStruct, 2, PLAYER_PED_ID(), "TREVOR")
|
|
ADD_PED_FOR_DIALOGUE(convoStruct, 3, NULL, "DBLIMPOperator")
|
|
|
|
sRootLabel[0] = "DAB_HELLO"
|
|
sRootLabel[1] = "DAB_TREVOR"
|
|
sRootLabel[2] = "DAB_SEND"
|
|
sRootLabel[3] = "DAB_THANK_T"
|
|
sRootLabel[4] = "DAB_BYE"
|
|
ENDIF
|
|
|
|
// Attempt phonecall
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Check_For_Ability_Calls_To_Run - Blimp - Initiating Call")
|
|
|
|
IF PLAYER_CALL_CHAR_CELLPHONE_MULTIPART_WITH_N_LINES(5, convoStruct, CHAR_BLIMP, "BLIMPAU", sRootLabel, sRootLabel, CONV_PRIORITY_CELLPHONE)
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Check_For_Ability_Calls_To_Run - blimp - Call in progess")
|
|
iDialBlimpState++
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
// Wait for player to finish call
|
|
CASE 1
|
|
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
|
|
|
|
IF NOT IS_CALLING_CONTACT(CHAR_BLIMP) AND NOT IS_PHONE_ONSCREEN(TRUE)
|
|
g_iGlobalWaitTime = gameTime + CC_GLOBAL_DELAY_BETWEEN_COMMS
|
|
|
|
IF NOT IS_CELLPHONE_CONVERSATION_PLAYING()
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Check_For_Ability_Calls_To_Run - Blimp - Call Completed")
|
|
/*
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Waiting 15 Seconds for delivery")
|
|
iDialBlimpState++
|
|
*/
|
|
// Bypass delay for now
|
|
iDialBlimpState = 3
|
|
ENDIF
|
|
ELSE
|
|
//If the blip is called in a mission trigger we get an assert B*1868387
|
|
IF g_iOffMissionCutsceneRequestAllowed != NULL_OFFMISSION_CUTSCENE_REQUEST
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Check_For_Ability_Calls_To_Run - a cutscene is being requested while ringing for a blimp")
|
|
HANG_UP_AND_PUT_AWAY_PHONE()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
// Wait some time for delivery
|
|
CASE 2
|
|
IF (GET_GAME_TIMER() > g_iGlobalWaitTime)
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Check_For_Ability_Calls_To_Run - Blimp - Delay before Delivery Complete")
|
|
iDialBlimpState++
|
|
ENDIF
|
|
BREAK
|
|
|
|
// Activate suitable vehicle gen
|
|
CASE 3
|
|
|
|
// Get the nearest blimp location to the player
|
|
Activate_Closest_Blimp_Location()
|
|
iDialBlimpState = 0
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
|
|
PROC Check_For_Any_Outgoing_Calls_To_Run(INT &gameTime)
|
|
IF IS_CALLING_ANY_CONTACT()
|
|
IF eState = CCS_LOOKING_FOR_COMM
|
|
Check_For_Quick_Calls_To_Run(gameTime)
|
|
ENDIF
|
|
IF eState = CCS_LOOKING_FOR_COMM
|
|
Check_For_Missed_Calls_To_Run(gameTime)
|
|
ENDIF
|
|
IF eState = CCS_LOOKING_FOR_COMM
|
|
Check_For_Chat_Calls_To_Run(gameTime)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Keep this out the calling contact loop as we need
|
|
// to run some script when the call ends.
|
|
Check_For_Ability_Calls_To_Run(gameTime)
|
|
ENDPROC
|
|
|
|
|
|
PROC Update_Call_In_Progress_Responses()
|
|
//Does the call in progress have a question that needs responding to?
|
|
IF IS_BIT_SET(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.iSettings, COMM_BIT_HAS_QUESTION)
|
|
|
|
//Check if we need to display help text for making a decision on the phone.
|
|
IF NOT HAS_ONE_TIME_HELP_DISPLAYED(FHM_FIRST_CALL_DECISION)
|
|
IF IS_CELLPHONE_CALL_WITH_REPLIES_WAITING_ON_USER_INPUT()
|
|
SWITCH g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID
|
|
CASE QCALL_ME_AMANDA
|
|
CASE QCALL_ME_JIMMY
|
|
CASE QCALL_ME_TRACEY
|
|
PRINT_HELP("AM_H_FDEC")
|
|
SET_ONE_TIME_HELP_MESSAGE_DISPLAYED(FHM_FIRST_CALL_DECISION)
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDIF
|
|
ENDIF
|
|
|
|
//Yes. Check for responses from the player.
|
|
IF NOT g_savedGlobals.sCommsControlData.bLastCallHadResponse
|
|
IF (CHECK_RESPONSE_TO_CELLPHONE_PROMPT() <> RESPONSE_STORE_EMPTY)
|
|
IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("AM_H_FDEC")
|
|
CLEAR_HELP(FALSE)
|
|
ENDIF
|
|
IF (CHECK_RESPONSE_TO_CELLPHONE_PROMPT() = RESPONDED_YES)
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID), " received a YES response.")
|
|
g_savedGlobals.sCommsControlData.bLastCallResponse = TRUE
|
|
g_savedGlobals.sCommsControlData.bLastCallHadResponse = TRUE
|
|
ELSE
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID), " received a NO response.")
|
|
IF g_iCommsCandidateID != NO_CANDIDATE_ID
|
|
Mission_Over(g_iCommsCandidateID)
|
|
Set_Leave_Area_Flag_For_All_Blipped_Missions()
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Mission triggering call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID), " was rejected so cleaned-up mission candidate.")
|
|
|
|
CONST_FLOAT fCONST_FRIEND_TIME_RESET_FOR_MISSION_BACKOUT 300.0
|
|
enumFriendConnection friendConnID
|
|
REPEAT MAX_FRIEND_CONNECTIONS friendConnID
|
|
IF g_SavedGlobals.sFriendsData.g_FriendConnectData[friendConnID].lastContactType = FRIEND_CONTACT_PHONE
|
|
#IF IS_DEBUG_BUILD
|
|
CPRINTLN(DEBUG_FRIENDS, "RESTART_TIMER_AT(", GetLabel_enumFriendConnection(friendConnID), ", ", fCONST_FRIEND_TIME_RESET_FOR_MISSION_BACKOUT, ")")
|
|
#ENDIF
|
|
|
|
RESTART_TIMER_AT(g_savedGlobals.sFriendsData.g_FriendConnectData[friendConnID].lastContactTimer, fCONST_FRIEND_TIME_RESET_FOR_MISSION_BACKOUT)
|
|
ENDIF
|
|
ENDREPEAT
|
|
ENDIF
|
|
g_savedGlobals.sCommsControlData.bLastCallResponse = FALSE
|
|
g_savedGlobals.sCommsControlData.bLastCallHadResponse = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
//If we've flagged to load dynamic dialogue for a branched call, load the correct branch here.
|
|
PROC Update_Branched_Call_Dialogue()
|
|
IF bDoCallBranch
|
|
FLOW_CHECK_IDS eBranchCheck = g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eSendCheck
|
|
IF eBranchCheck != FLOW_CHECK_NONE
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Running check ", GET_DEBUG_STRING_FOR_FLOW_CHECK_ID(eBranchCheck), " for ongoing branched call.")
|
|
|
|
//Grab dialogue details based on the flow check outcome.
|
|
CC_CommID eBranch
|
|
IF DO_CUSTOM_FLOW_CHECK(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eSendCheck)
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Branched call loading the TRUE branch.")
|
|
eBranch = g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].eCommExtra
|
|
ELSE
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Branched call loading the FALSE branch.")
|
|
eBranch = g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].eCommExtra2
|
|
ENDIF
|
|
|
|
IF eBranch != COMM_NONE
|
|
CC_CallStringData sCallStrings
|
|
PRIVATE_Get_Call_String_Data(eBranch, sCallStrings)
|
|
SET_DYNAMIC_BRANCH_FOR_ONGOING_CALL(sCallStrings.tBlock, sCallStrings.tConversation)
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Branched call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID), " adding dynamic conversation ending ", GET_COMM_ID_DEBUG_STRING(eBranch), " to the call.")
|
|
ELSE
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Branch for call was blank. No dynamic dialogue being added.")
|
|
ENDIF
|
|
ELSE
|
|
SCRIPT_ASSERT("Update_Branched_Call_Dialogue: Branched call did not have a valid branch check defined.")
|
|
ENDIF
|
|
bDoCallBranch = FALSE
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
PROC Update_Call_Help()
|
|
IF NOT HAS_ONE_TIME_HELP_DISPLAYED(FHM_FIRST_CALL_RINGING)
|
|
IF GET_MISSION_COMPLETE_STATE(SP_MISSION_ARMENIAN_1)
|
|
IF NOT GET_MISSION_COMPLETE_STATE(SP_MISSION_ARMENIAN_2)
|
|
IF IS_PHONE_ONSCREEN(TRUE)
|
|
IF g_iCallInProgress != -1
|
|
IF g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID = CALL_ARM2_UNLOCK
|
|
or g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID = CALL_CARDMG_ARM2_UNLOCK
|
|
SWITCH GET_FLOW_HELP_MESSAGE_STATUS("AM_H_FCAL1")
|
|
CASE FHS_EXPIRED
|
|
ADD_HELP_TO_FLOW_QUEUE("AM_H_FCAL1", FHP_HIGH, 0, 1000, DEFAULT_GOD_TEXT_TIME)
|
|
BREAK
|
|
CASE FHS_DISPLAYED
|
|
SET_ONE_TIME_HELP_MESSAGE_DISPLAYED(FHM_FIRST_CALL_RINGING)
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF NOT HAS_ONE_TIME_HELP_DISPLAYED(FHM_FIRST_CALL_ONGOING)
|
|
IF NOT bFirstCallOngoingHelpQueued
|
|
IF GET_MISSION_COMPLETE_STATE(SP_MISSION_ARMENIAN_1)
|
|
IF NOT GET_MISSION_COMPLETE_STATE(SP_MISSION_ARMENIAN_2)
|
|
IF IS_PHONE_ONSCREEN(TRUE)
|
|
IF g_iCallInProgress != -1
|
|
IF g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID = CALL_ARM2_UNLOCK
|
|
or g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID = CALL_CARDMG_ARM2_UNLOCK
|
|
IF IS_CELLPHONE_CONVERSATION_PLAYING()
|
|
IF IS_FLOW_HELP_MESSAGE_QUEUED("AM_H_FCAL1")
|
|
REMOVE_HELP_FROM_FLOW_QUEUE("AM_H_FCAL1")
|
|
ENDIF
|
|
IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("AM_H_FCAL1")
|
|
CLEAR_HELP(FALSE)
|
|
ENDIF
|
|
SET_ONE_TIME_HELP_MESSAGE_DISPLAYED(FHM_FIRST_CALL_RINGING)
|
|
ADD_HELP_TO_FLOW_QUEUE("AM_H_FCAL2", FHP_HIGH, 0, 1000, DEFAULT_GOD_TEXT_TIME)
|
|
bFirstCallOngoingHelpQueued = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
IF GET_FLOW_HELP_MESSAGE_STATUS("AM_H_FCAL2") = FHS_EXPIRED
|
|
bFirstCallOngoingHelpQueued = FALSE
|
|
ELIF GET_FLOW_HELP_MESSAGE_STATUS("AM_H_FCAL2") = FHS_DISPLAYED
|
|
SET_ONE_TIME_HELP_MESSAGE_DISPLAYED(FHM_FIRST_CALL_ONGOING)
|
|
ENDIF
|
|
|
|
IF NOT IS_CELLPHONE_CONVERSATION_PLAYING()
|
|
REMOVE_HELP_FROM_FLOW_QUEUE("AM_H_FCAL2")
|
|
IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("AM_H_FCAL2")
|
|
CLEAR_HELP(FALSE)
|
|
ENDIF
|
|
SET_ONE_TIME_HELP_MESSAGE_DISPLAYED(FHM_FIRST_CALL_ONGOING)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF g_savedGlobals.sCommsControlData.eLastCompletedCall = CALL_ARM2_UNLOCK
|
|
or g_savedGlobals.sCommsControlData.eLastCompletedCall = CALL_CARDMG_ARM2_UNLOCK
|
|
SET_ONE_TIME_HELP_MESSAGE_DISPLAYED(FHM_FIRST_CALL_ONGOING)
|
|
SET_ONE_TIME_HELP_MESSAGE_DISPLAYED(FHM_FIRST_CALL_RINGING)
|
|
IF IS_FLOW_HELP_MESSAGE_QUEUED("AM_H_FCAL1")
|
|
REMOVE_HELP_FROM_FLOW_QUEUE("AM_H_FCAL1")
|
|
ENDIF
|
|
IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("AM_H_FCAL1")
|
|
CLEAR_HELP(FALSE)
|
|
ENDIF
|
|
IF IS_FLOW_HELP_MESSAGE_QUEUED("AM_H_FCAL2")
|
|
REMOVE_HELP_FROM_FLOW_QUEUE("AM_H_FCAL2")
|
|
ENDIF
|
|
IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("AM_H_FCAL2")
|
|
CLEAR_HELP(FALSE)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
FUNC BOOL Update_Secure_Mission_Candidate_For_Mission_Triggering_Call()
|
|
SWITCH Request_Mission_Launch(g_iCommsCandidateID, MCTID_PHONECALL_TO_PLAYER, MISSION_TYPE_STORY)
|
|
CASE MCRET_ACCEPTED
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID), " secured a candidate ID for mission that will trigger from this call.")
|
|
RETURN TRUE
|
|
BREAK
|
|
CASE MCRET_DENIED
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Backing out of call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID), " because it couldn't secure a candidate ID.")
|
|
HANG_UP_AND_PUT_AWAY_PHONE()
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
CDEBUG1LN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID), " waiting to secure a candidate ID.")
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
PROC Process_Early_Cancellation_Of_Call(INT &gameTime, BOOL bForceReqeue = FALSE)
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Processing early cancellation of call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID), ".")
|
|
|
|
HANG_UP_AND_PUT_AWAY_PHONE()
|
|
|
|
IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("AM_H_FCAL1")
|
|
CLEAR_HELP(FALSE)
|
|
ENDIF
|
|
|
|
//Do we need to clean up a temporary contact?
|
|
IF IS_BIT_SET(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.iSettings, COMM_BIT_CALL_REMOVE_TEMP_CONTACT)
|
|
enumPhoneBookPresence ePhonebook
|
|
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
|
|
CASE CHAR_MICHAEL ePhonebook = MICHAEL_BOOK BREAK
|
|
CASE CHAR_FRANKLIN ePhonebook = FRANKLIN_BOOK BREAK
|
|
CASE CHAR_TREVOR ePhonebook = TREVOR_BOOK BREAK
|
|
ENDSWITCH
|
|
REMOVE_CONTACT_FROM_INDIVIDUAL_PHONEBOOK(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eNPCCharacter, ePhonebook)
|
|
CLEAR_BIT(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.iSettings, COMM_BIT_CALL_REMOVE_TEMP_CONTACT)
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing temporary contact for call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID), " was cancelled.")
|
|
ENDIF
|
|
|
|
//If the call has a question handle cleaning up its responses and adding unique character delays.
|
|
IF IS_BIT_SET(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.iSettings, COMM_BIT_HAS_QUESTION)
|
|
IF NOT g_savedGlobals.sCommsControlData.bLastCallHadResponse
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Backed out of call with question. Forcing requeue flag on and adding to missed call queue.")
|
|
SET_BIT(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.iSettings, COMM_BIT_CALL_REQUEUE_ON_MISS)
|
|
PRIVATE_Add_Call_To_Missed_Call_Queue(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress])
|
|
IF g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eNPCCharacter = CHAR_AMANDA
|
|
Execute_Code_ID(CID_SET_LONG_AMANDA_TIMER)
|
|
ELIF g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eNPCCharacter = CHAR_JIMMY
|
|
Execute_Code_ID(CID_SET_LONG_JIMMY_TIMER)
|
|
ELIF g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eNPCCharacter = CHAR_TRACEY
|
|
Execute_Code_ID(CID_SET_LONG_TRACEY_TIMER)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF g_iCommsCandidateID != NO_CANDIDATE_ID
|
|
Set_Leave_Area_Flag_For_All_Blipped_Missions()
|
|
Mission_Over(g_iCommsCandidateID)
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Backed out of mission triggering call so cleaned-up mission candidate.")
|
|
|
|
CONST_FLOAT fCONST_FRIEND_TIME_RESET_FOR_MISSION_BACKOUT 300.0
|
|
enumFriendConnection friendConnID
|
|
REPEAT MAX_FRIEND_CONNECTIONS friendConnID
|
|
IF g_SavedGlobals.sFriendsData.g_FriendConnectData[friendConnID].lastContactType = FRIEND_CONTACT_PHONE
|
|
#IF IS_DEBUG_BUILD
|
|
CPRINTLN(DEBUG_FRIENDS, "RESTART_TIMER_AT(", GetLabel_enumFriendConnection(friendConnID), ", ", fCONST_FRIEND_TIME_RESET_FOR_MISSION_BACKOUT, ")")
|
|
#ENDIF
|
|
|
|
RESTART_TIMER_AT(g_savedGlobals.sFriendsData.g_FriendConnectData[friendConnID].lastContactTimer, fCONST_FRIEND_TIME_RESET_FOR_MISSION_BACKOUT)
|
|
ENDIF
|
|
ENDREPEAT
|
|
ENDIF
|
|
|
|
//Requeue if missed.
|
|
IF IS_BIT_SET(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.iSettings, COMM_BIT_CALL_REQUEUE_ON_MISS)
|
|
OR bForceReqeue
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Executing call missed response for call: Requeuing.")
|
|
PRIVATE_Set_New_Communication_Queue_Time(gameTime, g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData)
|
|
|
|
IF IS_BIT_SET(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.iSettings, COMM_BIT_TRIGGERS_MISSION)
|
|
IF g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.iRequeueTime < 300000
|
|
g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.iRequeueTime += 60000
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Added 1 min to next requeue time of mission trigger communication ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID), ".")
|
|
ENDIF
|
|
ENDIF
|
|
//Check if we should add the call to the missed call queue.
|
|
IF IS_BIT_SET(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.iSettings, COMM_BIT_CALL_IS_MISSED)
|
|
PRIVATE_Add_Call_To_Missed_Call_Queue(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress])
|
|
ENDIF
|
|
|
|
//Text if missed.
|
|
ELIF IS_BIT_SET(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.iSettings, COMM_BIT_CALL_TEXT_ON_MISS)
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Executing call missed response for call: Sending text message [", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].eCommExtra), "].")
|
|
REGISTER_TEXT_MESSAGE_FROM_CHARACTER_TO_PLAYER( g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].eCommExtra,
|
|
CT_FLOW,
|
|
g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.iPlayerCharBitset,
|
|
g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eNPCCharacter,
|
|
g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.iRequeueTime,
|
|
g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.iRequeueTime,
|
|
g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eRestrictedAreaID,
|
|
g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eExecuteOnCompleteID,
|
|
g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eSendCheck,
|
|
g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.iSettings)
|
|
//Flag this call as the last completed call.
|
|
g_savedGlobals.sCommsControlData.eLastCompletedCall = g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID
|
|
//Clear the last call answered flag.
|
|
g_savedGlobals.sCommsControlData.bLastCallAnswered = FALSE
|
|
PRIVATE_Remove_Call_From_Missed_Call_Queue(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID)
|
|
PRIVATE_Remove_Call_From_Chat_Call_Queue(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID)
|
|
PRIVATE_Remove_Call_From_Queue(g_iCallInProgress)
|
|
|
|
//Remove from queue if missed.
|
|
ELSE
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Executing call missed response for call: Removing from queue.")
|
|
//Flag this call as the last completed call.
|
|
g_savedGlobals.sCommsControlData.eLastCompletedCall = g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID
|
|
//Clear the last call answered flag.
|
|
g_savedGlobals.sCommsControlData.bLastCallAnswered = FALSE
|
|
PRIVATE_Remove_Call_From_Missed_Call_Queue(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID)
|
|
PRIVATE_Remove_Call_From_Chat_Call_Queue(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID)
|
|
PRIVATE_Remove_Call_From_Queue(g_iCallInProgress)
|
|
ENDIF
|
|
|
|
//Clean up the PedsForConversation struct.
|
|
PRIVATE_Clean_Up_Peds_For_Conversation_Struct()
|
|
|
|
g_iCallInProgress = -1
|
|
ENDPROC
|
|
|
|
|
|
PROC Update_Mission_Triggering_Calls_Safeguards(INT paramGameTime)
|
|
IF IS_BIT_SET(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.iSettings, COMM_BIT_TRIGGERS_MISSION)
|
|
VectorID eRestrictedArea = g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eRestrictedAreaID
|
|
IF eRestrictedArea != VID_BLANK
|
|
//If the player gets 2/3 of the way into the restricted area before the call finishes, end it early.
|
|
IF IS_PED_AT_VECTOR_ID( PLAYER_PED_ID(), eRestrictedArea, g_sVectorIDData[eRestrictedArea].radius * 0.35)
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID), " was cancelled early as the player got too close the a mission triggering restricted area.")
|
|
Process_Early_Cancellation_Of_Call(paramGameTime)
|
|
HANG_UP_AND_PUT_AWAY_PHONE()
|
|
eState = CCS_LOOKING_FOR_COMM
|
|
g_iGlobalWaitTime = paramGameTime + CC_GLOBAL_DELAY_BETWEEN_COMMS
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
PROC Process_Termination_Of_Last_Call(INT &gameTime)
|
|
IF g_iCallInProgress != -1
|
|
|
|
//Was the call hung up before a required response was made?
|
|
IF IS_BIT_SET(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.iSettings, COMM_BIT_HAS_QUESTION) AND NOT g_savedGlobals.sCommsControlData.bLastCallHadResponse
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID), " ended before a response was made.")
|
|
Process_Early_Cancellation_Of_Call(gameTime)
|
|
//The call succeeded.
|
|
ELSE
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID), " sucessfully completed.")
|
|
//Set the last call answered flag.
|
|
g_savedGlobals.sCommsControlData.bLastCallAnswered = TRUE
|
|
// Reset friend last-contact timer
|
|
PRIVATE_Update_Friend_Timer_Resets_For_Call(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eNPCCharacter, GET_CURRENT_PLAYER_PED_ENUM())
|
|
//Clean up the PedsForConversation struct.
|
|
PRIVATE_Clean_Up_Peds_For_Conversation_Struct()
|
|
//Execute any special code assigned to this call.
|
|
Execute_Special_Code_For_Communication(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData)
|
|
//Register this as the last completed call.
|
|
g_savedGlobals.sCommsControlData.eLastCompletedCall = g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID
|
|
//Update the system's global wait time.
|
|
g_iGlobalWaitTime = gameTime + CC_GLOBAL_DELAY_BETWEEN_COMMS
|
|
//Update the sending character's wait time.
|
|
g_iCharWaitTime[g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eNPCCharacter] = gameTime + CC_CHARACTER_DELAY_BETWEEN_COMMS
|
|
//Remove call from missed call queue (if it's in it).
|
|
PRIVATE_Remove_Call_From_Missed_Call_Queue(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID)
|
|
//Remove call from chat call queue (if it's in it).
|
|
PRIVATE_Remove_Call_From_Chat_Call_Queue(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID)
|
|
//Remove call entry from queue.
|
|
PRIVATE_Remove_Call_From_Queue(g_iCallInProgress)
|
|
|
|
//Do we need to clean up a temporary contact?
|
|
IF IS_BIT_SET(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.iSettings, COMM_BIT_CALL_REMOVE_TEMP_CONTACT)
|
|
enumPhoneBookPresence ePhonebook
|
|
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
|
|
CASE CHAR_MICHAEL ePhonebook = MICHAEL_BOOK BREAK
|
|
CASE CHAR_FRANKLIN ePhonebook = FRANKLIN_BOOK BREAK
|
|
CASE CHAR_TREVOR ePhonebook = TREVOR_BOOK BREAK
|
|
ENDSWITCH
|
|
REMOVE_CONTACT_FROM_INDIVIDUAL_PHONEBOOK(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eNPCCharacter, ePhonebook)
|
|
CLEAR_BIT(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.iSettings, COMM_BIT_CALL_REMOVE_TEMP_CONTACT)
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Removing temporary contact for call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID), " from player phonebook as call has finished.")
|
|
ENDIF
|
|
|
|
//Special case. Clear help when hanging up the first flow phonecall.
|
|
IF HAS_ONE_TIME_HELP_DISPLAYED(FHM_FIRST_CALL_ONGOING)
|
|
IF NOT GET_MISSION_COMPLETE_STATE(SP_MISSION_ARMENIAN_2)
|
|
IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("AM_H_FCAL2")
|
|
CLEAR_HELP(FALSE)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
|
|
PROC Update_Sent_Text_Responses(INT &gameTime, CC_TextMessageData &sentText)
|
|
|
|
TEXT_LABEL tTextMessageLabel
|
|
PRIVATE_Get_Text_Message_Message_Label(sentText.sCommData.eID, tTextMessageLabel)
|
|
|
|
//Check the status of the text message that was sent.
|
|
SWITCH GET_TEXT_MESSAGE_REPLY_STATUS(tTextMessageLabel)
|
|
CASE NO_REPLY_REQUIRED
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "A response is not required for sent text ", GET_COMM_ID_DEBUG_STRING(sentText.sCommData.eID), ".")
|
|
g_savedGlobals.sCommsControlData.bLastTextHadResponse = FALSE
|
|
Process_Cleanup_Of_Sent_Text(gameTime, sentText)
|
|
BREAK
|
|
|
|
CASE REPLIED_YES
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "YES response received for sent text ", GET_COMM_ID_DEBUG_STRING(sentText.sCommData.eID), ".")
|
|
g_savedGlobals.sCommsControlData.bLastTextHadResponse = TRUE
|
|
g_savedGlobals.sCommsControlData.bLastTextResponse = TRUE
|
|
Process_Cleanup_Of_Sent_Text(gameTime, sentText)
|
|
BREAK
|
|
|
|
CASE REPLIED_NO
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "NO response received for sent text ", GET_COMM_ID_DEBUG_STRING(sentText.sCommData.eID), ".")
|
|
g_savedGlobals.sCommsControlData.bLastTextHadResponse = TRUE
|
|
g_savedGlobals.sCommsControlData.bLastTextResponse = FALSE
|
|
BREAK
|
|
|
|
//NB. If REPLY_REQUIRED then the text is not cleaned up and we will run this check again next frame.
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
|
|
DEBUGONLY PROC Debug_Draw_All_Queued_Comms_Restricted_Areas()
|
|
IF g_iCallInProgress = -1
|
|
//No call in progress. Render restricted area for queued communications.
|
|
INT index
|
|
REPEAT g_savedGlobals.sCommsControlData.iNoQueuedCalls index
|
|
VectorID eRestrictedArea = g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.eRestrictedAreaID
|
|
IF eRestrictedArea != VID_BLANK
|
|
DEBUG_DRAW_VECTOR_ID_AREA(eRestrictedArea, GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[index].sCommData.eID))
|
|
ENDIF
|
|
ENDREPEAT
|
|
REPEAT g_savedGlobals.sCommsControlData.iNoQueuedTexts index
|
|
VectorID eRestrictedArea = g_savedGlobals.sCommsControlData.sQueuedTexts[index].sCommData.eRestrictedAreaID
|
|
IF eRestrictedArea != VID_BLANK
|
|
DEBUG_DRAW_VECTOR_ID_AREA(eRestrictedArea, GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedTexts[index].sCommData.eID))
|
|
ENDIF
|
|
ENDREPEAT
|
|
REPEAT g_savedGlobals.sCommsControlData.iNoQueuedEmails index
|
|
VectorID eRestrictedArea = g_savedGlobals.sCommsControlData.sQueuedEmails[index].sCommData.eRestrictedAreaID
|
|
IF eRestrictedArea != VID_BLANK
|
|
DEBUG_DRAW_VECTOR_ID_AREA(eRestrictedArea, GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedEmails[index].sCommData.eID))
|
|
ENDIF
|
|
ENDREPEAT
|
|
ELSE
|
|
//Call in progress. If this call triggers a mission, render its cancel area.
|
|
VectorID eRestrictedArea = g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eRestrictedAreaID
|
|
IF eRestrictedArea != VID_BLANK
|
|
IF IS_BIT_SET(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.iSettings, COMM_BIT_TRIGGERS_MISSION)
|
|
DEBUG_DRAW_VECTOR_ID_AREA(eRestrictedArea, "Call Cancel-Area", g_sVectorIDData[eRestrictedArea].radius*0.35)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
PROC GET_CHARACTER_INDEXES_FOR_CB_CONV_INDEX(INT iConvIndex, INT &iChar1, INT &iChar2)
|
|
SWITCH iConvIndex
|
|
CASE 1
|
|
iChar1 = 1
|
|
iChar2 = 8
|
|
BREAK
|
|
CASE 2
|
|
iChar1 = 5
|
|
iChar2 = 2
|
|
BREAK
|
|
CASE 3
|
|
iChar1 = 3
|
|
iChar2 = 10
|
|
BREAK
|
|
CASE 4
|
|
iChar1 = 4
|
|
iChar2 = 13
|
|
BREAK
|
|
CASE 5
|
|
iChar1 = 7
|
|
iChar2 = 6
|
|
BREAK
|
|
CASE 6
|
|
iChar1 = 12
|
|
iChar2 = 9
|
|
BREAK
|
|
CASE 7
|
|
iChar1 = 11
|
|
iChar2 = 44
|
|
BREAK
|
|
CASE 8
|
|
iChar1 = 34
|
|
iChar2 = 14
|
|
BREAK
|
|
CASE 9
|
|
iChar1 = 15
|
|
iChar2 = 28
|
|
BREAK
|
|
CASE 10
|
|
iChar1 = 43
|
|
iChar2 = 16
|
|
BREAK
|
|
CASE 11
|
|
iChar1 = 17
|
|
iChar2 = 18
|
|
BREAK
|
|
CASE 12
|
|
iChar1 = 19
|
|
iChar2 = 20
|
|
BREAK
|
|
CASE 13
|
|
iChar1 = 26
|
|
iChar2 = 21
|
|
BREAK
|
|
CASE 14
|
|
iChar1 = 22
|
|
iChar2 = 23
|
|
BREAK
|
|
CASE 15
|
|
iChar1 = 24
|
|
iChar2 = 25
|
|
BREAK
|
|
CASE 16
|
|
iChar1 = 27
|
|
iChar2 = 29
|
|
BREAK
|
|
CASE 17
|
|
iChar1 = 30
|
|
iChar2 = 31
|
|
BREAK
|
|
CASE 18
|
|
iChar1 = 33
|
|
iChar2 = 32
|
|
BREAK
|
|
CASE 19
|
|
iChar1 = 35
|
|
iChar2 = 36
|
|
BREAK
|
|
CASE 20
|
|
iChar1 = 38
|
|
iChar2 = 37
|
|
BREAK
|
|
CASE 21
|
|
iChar1 = 40
|
|
iChar2 = 39
|
|
BREAK
|
|
CASE 22
|
|
iChar1 = 41
|
|
iChar2 = 42
|
|
BREAK
|
|
DEFAULT
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Tried to get speaker IDs for a CB conversation # that doesn't exist!")
|
|
iChar1 = 1
|
|
iChar2 = 2
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Checks whether the current weather is OK for this monologue to play (in case it references weather like Mon 5)
|
|
/// PARAMS:
|
|
/// iMonID - the ID we're checking
|
|
/// RETURNS:
|
|
/// TRUE if the monologue makes sense if said with the current weather (most do), false if not
|
|
FUNC BOOL IS_CURRENT_WEATHER_OK_FOR_MONOLOGUE(int iMonID)
|
|
SWITCH iMonID
|
|
CASE 5
|
|
IF IS_PREV_WEATHER_TYPE("SMOG")
|
|
OR IS_PREV_WEATHER_TYPE("OVERCAST")
|
|
OR IS_PREV_WEATHER_TYPE("RAIN")
|
|
OR IS_PREV_WEATHER_TYPE("THUNDER")
|
|
OR IS_PREV_WEATHER_TYPE("SNOW")
|
|
OR IS_NEXT_WEATHER_TYPE("SMOG")
|
|
OR IS_NEXT_WEATHER_TYPE("OVERCAST")
|
|
OR IS_NEXT_WEATHER_TYPE("RAIN")
|
|
OR IS_NEXT_WEATHER_TYPE("THUNDER")
|
|
OR IS_NEXT_WEATHER_TYPE("SNOW")
|
|
RETURN FALSE
|
|
ENDIF
|
|
BREAK
|
|
DEFAULT // If it ain't in this list, it can be used
|
|
RETURN TRUE
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Generates a random ID for a monologue (int between 1 and 43), checks to make sure it's okay to be played now, and regenerates it if not
|
|
/// RETURNS:
|
|
/// An int between 1 and 43
|
|
FUNC INT RETURN_APPROPRIATE_MONOLOGUE_ID()
|
|
TIMEOFDAY newTOD = GET_CURRENT_TIMEOFDAY()
|
|
INT iHour = GET_TIMEOFDAY_HOUR(newTOD)
|
|
|
|
BOOL bCanUseID = FALSE
|
|
INT iConvNum
|
|
|
|
WHILE bCanUseID = FALSE
|
|
iConvNum = GET_RANDOM_INT_IN_RANGE(1, 44)
|
|
|
|
SWITCH iConvNum
|
|
CASE 5
|
|
IF iHour > 19
|
|
// Too late in the day for this monologue to make sense
|
|
bCanUseID = FALSE
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Too late for Monologue ", iConvNum, " to play, regenerating another one")
|
|
ELIF iHour < 9
|
|
// Too early in the day for this monologue to make sense
|
|
bCanUseID = FALSE
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Too early for Monologue ", iConvNum, " to play, regenerating another one")
|
|
ELIF NOT IS_CURRENT_WEATHER_OK_FOR_MONOLOGUE(iConvNum)
|
|
bCanUseID = FALSE
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Current weather makes Monologue ", iConvNum, " not make sense, regenerating another one")
|
|
ELSE
|
|
bCanUseID = TRUE // Yay, we can use it
|
|
ENDIF
|
|
BREAK
|
|
DEFAULT // If it ain't in this list, it can be used
|
|
bCanUseID = TRUE
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
WAIT(0)
|
|
|
|
ENDWHILE
|
|
|
|
//Force debug conversation
|
|
#IF IS_DEBUG_BUILD
|
|
IF iForceDebugConv != -1
|
|
iConvNum = CLAMP_INT(iForceDebugConv,1,43)
|
|
iForceDebugConv = -1
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
RETURN iConvNum
|
|
ENDFUNC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Try to do a monologue or conversation type CB convo
|
|
/// RETURNS:
|
|
/// TRUE if the conversation was successful
|
|
FUNC BOOL Do_CB_MonConvo()
|
|
|
|
TEXT_LABEL_15 tlConv
|
|
INT iConvNum
|
|
TEXT_LABEL_15 tlPedName
|
|
BOOL bDecision = GET_RANDOM_BOOL()
|
|
|
|
// If any of these RAG widget bools are true, override the random decision because one of us wants a specific conv type
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDoMonologue
|
|
bDecision = TRUE
|
|
ELIF bDoConv
|
|
bDecision = FALSE
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
IF bDecision // If true, do a monologue - if false, do a conversation
|
|
|
|
tlConv = "CB_MON"
|
|
iConvNum = RETURN_APPROPRIATE_MONOLOGUE_ID()
|
|
tlConv += iConvNum // Creates the label we want, e.g. "CB_MON23"
|
|
tlPedName = "CB_CHAR"
|
|
tlPedName += iConvNum // Reuse the conv number we just generated to get the correct ped ID (they must match in D*!)
|
|
|
|
ADD_PED_FOR_DIALOGUE(convoStruct, 3, NULL, tlPedName, FALSE, FALSE)
|
|
IF CREATE_CONVERSATION(convoStruct, "CBRADAU", tlConv, CONV_PRIORITY_AMBIENT_LOW, DO_NOT_DISPLAY_SUBTITLES)
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDoMonologue
|
|
bDoMonologue = FALSE
|
|
ENDIF
|
|
#ENDIF
|
|
PLAY_SOUND_FRONTEND(-1, "Start_Squelch", "CB_RADIO_SFX")
|
|
PLAY_SOUND_FRONTEND(iSoundID, "Background_Loop", "CB_RADIO_SFX")
|
|
RETURN TRUE
|
|
ENDIF
|
|
ELSE
|
|
INT iChar1
|
|
INT iChar2
|
|
TEXT_LABEL_15 tlPedName2 // Need a second ped name for a conversation!
|
|
|
|
tlConv = "CB_CONVO"
|
|
iConvNum = GET_RANDOM_INT_IN_RANGE(1, 23)
|
|
//Force debug conversation
|
|
#IF IS_DEBUG_BUILD
|
|
IF iForceDebugConv != -1
|
|
iConvNum = CLAMP_INT(iForceDebugConv,1,22)
|
|
iForceDebugConv = -1
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
tlConv += iConvNum // Creates the label we want, e.g. "CB_CONVO10"
|
|
|
|
GET_CHARACTER_INDEXES_FOR_CB_CONV_INDEX(iConvNum, iChar1, iChar2)
|
|
|
|
// Set up the two characters
|
|
tlPedName = "CB_CHAR"
|
|
tlPedName += iChar1
|
|
ADD_PED_FOR_DIALOGUE(convoStruct, 3, NULL, tlPedName, FALSE, FALSE)
|
|
tlPedName2 = "CB_CHAR"
|
|
tlPedName2 += iChar2
|
|
ADD_PED_FOR_DIALOGUE(convoStruct, 4, NULL, tlPedName2, FALSE, FALSE)
|
|
|
|
IF CREATE_CONVERSATION(convoStruct, "CBRADAU", tlConv, CONV_PRIORITY_AMBIENT_LOW, DO_NOT_DISPLAY_SUBTITLES)
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDoConv
|
|
bDoConv = FALSE
|
|
ENDIF
|
|
#ENDIF
|
|
PLAY_SOUND_FRONTEND(-1, "Start_Squelch", "CB_RADIO_SFX")
|
|
PLAY_SOUND_FRONTEND(iSoundID, "Background_Loop", "CB_RADIO_SFX")
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
// Something went wrong...
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Try to do an Ident type CB conversation
|
|
/// RETURNS:
|
|
/// TRUE if the conversation was successful
|
|
FUNC BOOL Do_CB_Ident()
|
|
TEXT_LABEL_15 tlConv = "CB_IDN"
|
|
INT iConvNum = GET_RANDOM_INT_IN_RANGE(1, 44)
|
|
#IF IS_DEBUG_BUILD
|
|
IF iForceDebugConv != -1
|
|
iConvNum = CLAMP_INT(iForceDebugConv,1,43)
|
|
iForceDebugConv = -1
|
|
ENDIF
|
|
#ENDIF
|
|
tlConv += iConvNum // Creates the label we want, e.g. "CB_IDN6"
|
|
|
|
TEXT_LABEL_15 tlPedName = "CB_CHAR"
|
|
tlPedName += iConvNum // Reuse the conv number we just generated to get the correct ped ID (they must match in D*!)
|
|
|
|
ADD_PED_FOR_DIALOGUE(convoStruct, 3, NULL, tlPedName, FALSE, FALSE)
|
|
IF CREATE_CONVERSATION(convoStruct, "CBRADAU", tlConv, CONV_PRIORITY_AMBIENT_LOW, DO_NOT_DISPLAY_SUBTITLES)
|
|
// Reset the RAG debug bool if it's set
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDoOneLine
|
|
bDoOneLine = FALSE
|
|
ENDIF
|
|
#ENDIF
|
|
PLAY_SOUND_FRONTEND(-1, "Start_Squelch", "CB_RADIO_SFX")
|
|
PLAY_SOUND_FRONTEND(iSoundID, "Background_Loop", "CB_RADIO_SFX")
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Handles CB radio conversations in vehicles.
|
|
/// The player must be Trevor, and the player must in a vehicle that supports a CB radio and be within range of a transmitter.
|
|
PROC Handle_CB_Radio_In_Vehicles()
|
|
IF bCBActive = TRUE // Check the ongoing convo status to handle the player leaving the vehicle
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
STOP_SOUND(iSoundID)
|
|
PLAY_SOUND_FRONTEND(-1, "End_Squelch", "CB_RADIO_SFX")
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Stopped CB loop, played end squelch")
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "CB conversation finished, now inactive")
|
|
bCBActive = FALSE // If no conversation is ongoing, the CB conversation must have finished
|
|
ELSE
|
|
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID(), TRUE)
|
|
KILL_FACE_TO_FACE_CONVERSATION_DO_NOT_FINISH_LAST_LINE() // If the player exits the vehicle, kill the conversation early
|
|
STOP_SOUND(iSoundID)
|
|
PLAY_SOUND_FRONTEND(-1, "End_Squelch", "CB_RADIO_SFX")
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Player exited vehicle during CB dialogue - loop stopped, end squelch played")
|
|
bCBActive = FALSE // If no conversation is ongoing, the CB conversation must have finished
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
// Only check this every 10 seconds, except if we're trying to do a CB radio conversation
|
|
IF (GET_GAME_TIMER() - iCBCheckTimer) >= 10000
|
|
OR iCBState >= 1
|
|
IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_TREVOR
|
|
IF IS_PLAYER_PLAYING(PLAYER_ID())
|
|
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
|
|
IF CAN_VEHICLE_RECEIVE_CB_RADIO(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID(), FALSE))
|
|
SWITCH iCBState
|
|
// Initialise
|
|
CASE -1
|
|
iCBIdentWaitTimer = GET_GAME_TIMER()
|
|
iCBMonConvWaitTimer = GET_GAME_TIMER()
|
|
iCBState++ // Done initialising
|
|
iSoundID = GET_SOUND_ID()
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Initialised CB radio in Trevor's vehicle")
|
|
BREAK
|
|
|
|
// Check timers for either Ident or Monologue/Conversation time tiggers
|
|
CASE 0
|
|
IF (GET_GAME_TIMER() - iCBIdentWaitTimer) >= 120000 // 2 MINUTES
|
|
iCBState = 1 // Ident time
|
|
ENDIF
|
|
IF (GET_GAME_TIMER() - iCBMonConvWaitTimer) >= 300000 // 5 MINUTES
|
|
iCBState = 2 // Monologue/Conversation time
|
|
ENDIF
|
|
// Check for the RAG debug bools overriding the timer
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDoOneLine
|
|
iCBState = 1
|
|
ELIF (bDoMonologue OR bDoConv)
|
|
iCBState = 2
|
|
ENDIF
|
|
#ENDIF
|
|
BREAK
|
|
|
|
// Do an Ident CB call
|
|
CASE 1
|
|
IF Do_CB_Ident()
|
|
bCBActive = TRUE // Set CB conversation as active
|
|
iCBIdentWaitTimer = GET_GAME_TIMER() // Reset the timer for Idents
|
|
iCBState = 0 // Back to waiting...
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Started an ident CB radio conversation! ")
|
|
ENDIF
|
|
BREAK
|
|
|
|
// Do an Monologue/Conversation CB call
|
|
CASE 2
|
|
IF Do_CB_MonConvo()
|
|
bCBActive = TRUE // Set CB conversation as active
|
|
iCBMonConvWaitTimer = GET_GAME_TIMER() // Reset the timer for Idents
|
|
iCBState = 0 // Back to waiting...
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Started a monologue/conversation CB radio conversation!")
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDIF
|
|
ELSE
|
|
IF iCBState != -1
|
|
iCBState = -1 // Reset the state back to the initialise stage
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
iCBCheckTimer = GET_GAME_TIMER() // Reset the check timer now we've run this at least once
|
|
ENDIF
|
|
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Handles updating calls to Cletus. Calls need to change based on what's gon on in hunting recently.
|
|
PROC MAINTAIN_HUNTING_PHONECALL_STATUS()
|
|
//Early out if no hunter call timer is set.
|
|
IF ENUM_TO_INT(g_SavedGlobals.sAmbient.todHuntedWeekExp) = 0
|
|
EXIT
|
|
ENDIF
|
|
|
|
//Early out if the hunting minigame hasn't been unlocked.
|
|
IF NOT GET_MISSION_FLOW_BITSET_BIT_STATE(FLOWBITSET_MINIGAME_ACTIVE, ENUM_TO_INT(MINIGAME_HUNTING))
|
|
EXIT
|
|
ENDIF
|
|
|
|
// If the conversations saying that the palyer has hunted in the last week are registered, and it's been more than a week
|
|
// swap them.
|
|
IF IS_COMMUNICATION_REGISTERED(CHAT_CLE1_1) OR IS_COMMUNICATION_REGISTERED(CHAT_CLE1_2)
|
|
IF IS_NOW_AFTER_TIMEOFDAY(g_SavedGlobals.sAmbient.todHuntedWeekExp)
|
|
// These calls have expired because the player hasn't hunted recently. Remove them, and register the conversations
|
|
// where the hunter comments on the fact that Trevor hasn't hunted recently.
|
|
CANCEL_COMMUNICATION(CHAT_CLE1_1)
|
|
CANCEL_COMMUNICATION(CHAT_CLE1_2)
|
|
|
|
// Register the "You haven't hunted in a while recently." conversations.
|
|
REGISTER_CHAT_CALL_FROM_PLAYER_TO_CHARACTER(CHAT_CLE2_1, BIT_TREVOR, CHAR_HUNTER, 3, 7200000)
|
|
REGISTER_CHAT_CALL_FROM_PLAYER_TO_CHARACTER(CHAT_CLE2_2, BIT_TREVOR, CHAR_HUNTER, 3, 7200000)
|
|
|
|
EXIT
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Cletus comments on the player's last awesome hunt is happening, remove it, and register something else.
|
|
IF (GET_LAST_COMPLETED_CALL() = CHAT_CLE3_1)
|
|
CANCEL_COMMUNICATION(CHAT_CLE3_1)
|
|
CANCEL_COMMUNICATION(CHAT_CLE1_1)
|
|
CANCEL_COMMUNICATION(CHAT_CLE1_2)
|
|
CANCEL_COMMUNICATION(CHAT_CLE2_1)
|
|
CANCEL_COMMUNICATION(CHAT_CLE2_2)
|
|
|
|
// Wipe that call...
|
|
g_savedGlobals.sCommsControlData.eLastCompletedCall = COMM_NONE
|
|
|
|
IF IS_NOW_AFTER_TIMEOFDAY(g_SavedGlobals.sAmbient.todHuntedWeekExp)
|
|
// Not hunted in a while, register that.
|
|
REGISTER_CHAT_CALL_FROM_PLAYER_TO_CHARACTER(CHAT_CLE2_1, BIT_TREVOR, CHAR_HUNTER, 3, 7200000)
|
|
REGISTER_CHAT_CALL_FROM_PLAYER_TO_CHARACTER(CHAT_CLE2_2, BIT_TREVOR, CHAR_HUNTER, 3, 7200000)
|
|
ELSE
|
|
REGISTER_CHAT_CALL_FROM_PLAYER_TO_CHARACTER(CHAT_CLE1_1, BIT_TREVOR, CHAR_HUNTER, 3, 7200000)
|
|
REGISTER_CHAT_CALL_FROM_PLAYER_TO_CHARACTER(CHAT_CLE1_2, BIT_TREVOR, CHAR_HUNTER, 3, 7200000)
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
//╒═════════════════════════════════════════════════════════════════════════════╕
|
|
//╞═════════════════════════╡ Controller Main Loop ╞═══════════════════════════╡
|
|
//╘═════════════════════════════════════════════════════════════════════════════╛
|
|
|
|
SCRIPT
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Starting communication controller.")
|
|
|
|
// This script needs to cleanup only when the game moves from SP to MP
|
|
IF HAS_FORCE_CLEANUP_OCCURRED(FORCE_CLEANUP_FLAG_SP_TO_MP|FORCE_CLEANUP_FLAG_DEBUG_MENU|FORCE_CLEANUP_FLAG_REPEAT_PLAY)
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "The communication controller has been forced to cleanup.")
|
|
Script_Cleanup()
|
|
ENDIF
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF NOT DOES_WIDGET_GROUP_EXIST(widgetID)
|
|
widgetID = START_WIDGET_GROUP("Comms Controller")
|
|
ADD_WIDGET_STRING("CB Radio debug")
|
|
ADD_WIDGET_STRING("(Will only work if player is Trevor, is inside a CB-equipped vehicle, and within range of a transmitter!)")
|
|
ADD_WIDGET_STRING("(Only checked every 10 seconds - there may be a delay between ticking the box and the conv starting)")
|
|
ADD_WIDGET_BOOL("Do One Line CB Radio Conversation", bDoOneLine)
|
|
ADD_WIDGET_BOOL("Do Monologue CB Radio Conversation", bDoMonologue)
|
|
ADD_WIDGET_BOOL("Do Full Conv CB Radio Conversation", bDoConv)
|
|
ADD_WIDGET_BOOL("Fire test emails into queue...", bFireTestEmails)
|
|
ADD_WIDGET_INT_SLIDER("Force conversarion number, -1 for random",iForceDebugConv,-1,43,1)
|
|
STOP_WIDGET_GROUP()
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
|
|
g_iGlobalWaitTime = GET_GAME_TIMER() + CC_GLOBAL_DELAY_BETWEEN_COMMS
|
|
INT iCommsCheckStage = 0 //Used to cycle through a different queue check each frame.
|
|
iCBCheckTimer = GET_GAME_TIMER() // Initialise the CB check timer
|
|
|
|
WHILE TRUE
|
|
#IF IS_DEBUG_BUILD
|
|
IF NOT g_flowUnsaved.bUpdatingGameflow
|
|
IF bFireTestEmails
|
|
//INIT_AND_FIRE_TEST_EMAIL_QUEUE() // Commented out in comms_control_public.sch
|
|
bFireTestEmails = FALSE
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
INT iGameTime = GET_GAME_TIMER()
|
|
|
|
SWITCH (eState)
|
|
CASE CCS_LOOKING_FOR_COMM
|
|
//If we go on mission while idling looking for a call then clean up.
|
|
IF IS_CURRENTLY_ON_MISSION_OF_ANY_TYPE()
|
|
and not IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_EXILE)
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Cleaning up as we go on mission.")
|
|
Script_Cleanup()
|
|
ENDIF
|
|
|
|
//No call in progress. Look for a communication to process.
|
|
bCommunicationMade = FALSE
|
|
IF iTimeCallInitialisationStarted != -1
|
|
iTimeCallInitialisationStarted = -1
|
|
ENDIF
|
|
SWITCH(iCommsCheckStage)
|
|
CASE 0
|
|
Check_For_Queued_Phonecall_To_Player_To_Run(iGameTime)
|
|
BREAK
|
|
CASE 1
|
|
Check_For_Queued_Phonecall_From_Player_To_Run(iGameTime)
|
|
BREAK
|
|
CASE 2
|
|
Check_For_Queued_Text_Message_To_Run(iGameTime)
|
|
BREAK
|
|
CASE 3
|
|
Check_For_Any_Outgoing_Calls_To_Run(iGameTime)
|
|
BREAK
|
|
CASE 4
|
|
Check_For_Queued_Email_To_Run(iGameTime)
|
|
BREAK
|
|
ENDSWITCH
|
|
//Loop check stage counter.
|
|
iCommsCheckStage++
|
|
IF iCommsCheckStage > 4
|
|
iCommsCheckStage = 0
|
|
ENDIF
|
|
|
|
// Try and check the CB radio, if possible
|
|
IF NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_STORY)
|
|
AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_RANDOM_CHAR)
|
|
AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_RANDOM_EVENT)
|
|
AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_STORY_PREP)
|
|
AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_SPMC)
|
|
AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_STORY_FRIENDS)
|
|
AND NOT IS_MISSION_LEADIN_ACTIVE()
|
|
Handle_CB_Radio_In_Vehicles()
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE CCS_INITIALISING_COMM
|
|
//Has a mission launched before this call could go through?
|
|
IF g_iCommsCandidateID = NO_CANDIDATE_ID
|
|
IF NOT CAN_MISSION_TYPE_START_AGAINST_CURRENT_TYPE(MISSION_TYPE_STORY)
|
|
AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_EXILE)
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID), " cancelled as mission started before it initialised.")
|
|
Process_Early_Cancellation_Of_Call(iGameTime)
|
|
eState = CCS_LOOKING_FOR_COMM
|
|
ENDIF
|
|
ENDIF
|
|
|
|
//Has the phone been hung up before it could be answered?
|
|
IF eState = CCS_INITIALISING_COMM
|
|
IF bWaitForForceAwayFlagToClear
|
|
IF NOT HAS_CELLPHONE_JUST_BEEN_FORCED_AWAY()
|
|
bWaitForForceAwayFlagToClear = FALSE
|
|
ENDIF
|
|
ELSE
|
|
IF CHECK_CELLPHONE_LAST_CALL_REJECTED()
|
|
OR WAS_LAST_CELLPHONE_CALL_INTERRUPTED()
|
|
OR HAS_CELLPHONE_JUST_BEEN_FORCED_AWAY()
|
|
OR g_bScriptsSetSafeForCutscene
|
|
#IF IS_DEBUG_BUILD
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID), " rejected or forced away for the following reason/s:")
|
|
IF CHECK_CELLPHONE_LAST_CALL_REJECTED()
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "CHECK_CELLPHONE_LAST_CALL_REJECTED = TRUE")
|
|
ENDIF
|
|
IF WAS_LAST_CELLPHONE_CALL_INTERRUPTED()
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "WAS_LAST_CELLPHONE_CALL_INTERRUPTED = TRUE")
|
|
ENDIF
|
|
IF HAS_CELLPHONE_JUST_BEEN_FORCED_AWAY()
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "HAS_CELLPHONE_JUST_BEEN_FORCED_AWAY = TRUE")
|
|
ENDIF
|
|
IF g_bScriptsSetSafeForCutscene
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "g_bScriptsSetSafeForCutscene = TRUE")
|
|
ENDIF
|
|
#ENDIF
|
|
Process_Early_Cancellation_Of_Call(iGameTime)
|
|
eState = CCS_LOOKING_FOR_COMM
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
//Has this call been answered yet?
|
|
IF eState = CCS_INITIALISING_COMM
|
|
IF IS_PHONE_ONSCREEN(FALSE)
|
|
IF IS_CELLPHONE_CONVERSATION_PLAYING()
|
|
IF g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.ePriority = CPR_VERY_HIGH
|
|
DISABLE_HANGUP_FOR_THIS_CALL(FALSE)
|
|
ENDIF
|
|
|
|
//Does this call need to secure a candidate ID for a mission?
|
|
IF IS_BIT_SET(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.iSettings, COMM_BIT_TRIGGERS_MISSION)
|
|
IF Update_Secure_Mission_Candidate_For_Mission_Triggering_Call()
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID), " finished initialising.")
|
|
eState = CCS_COMM_IN_PROGRESS
|
|
ENDIF
|
|
ELSE
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID), " finished initialising.")
|
|
eState = CCS_COMM_IN_PROGRESS
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
//Check for call initialisation taking too long. Timeout and requeue as a failsafe.
|
|
IF eState = CCS_INITIALISING_COMM
|
|
IF iTimeCallInitialisationStarted = -1
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Setting new initialisation timer for call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID), ".")
|
|
iTimeCallInitialisationStarted = GET_GAME_TIMER()
|
|
ELIF (GET_GAME_TIMER() - iTimeCallInitialisationStarted) > 20000
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID), " failed to initialise in time. Killing call and requeuing.")
|
|
KILL_PHONE_CONVERSATION()
|
|
HANG_UP_AND_PUT_AWAY_PHONE(TRUE)
|
|
Process_Early_Cancellation_Of_Call(iGameTime, TRUE)
|
|
iTimeCallInitialisationStarted = -1
|
|
eState = CCS_LOOKING_FOR_COMM
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE CCS_COMM_IN_PROGRESS
|
|
IF HAS_CELLPHONE_CALL_FINISHED()
|
|
CPRINTLN(DEBUG_COMMUNICATIONS, "Call ", GET_COMM_ID_DEBUG_STRING(g_savedGlobals.sCommsControlData.sQueuedCalls[g_iCallInProgress].sCommData.eID), " has finished.")
|
|
Process_Termination_Of_Last_Call(iGameTime)
|
|
bDoCallBranch = FALSE
|
|
g_iGlobalWaitTime = iGameTime + CC_GLOBAL_DELAY_BETWEEN_COMMS
|
|
eState = CCS_LOOKING_FOR_COMM
|
|
g_iCallInProgress = -1
|
|
ELIF g_iCallInProgress != -1
|
|
Update_Branched_Call_Dialogue()
|
|
Update_Call_In_Progress_Responses()
|
|
Update_Mission_Triggering_Calls_Safeguards(iGameTime)
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
//Process all texts that are sitting in the sent text queue.
|
|
INT index
|
|
REPEAT g_savedGlobals.sCommsControlData.iNoSentTexts index
|
|
Update_Sent_Text_Responses(iGameTime, g_savedGlobals.sCommsControlData.sSentTexts[index])
|
|
ENDREPEAT
|
|
|
|
Update_Call_Help()
|
|
|
|
IF g_bPauseCommsQueues OR g_bPauseCommsQueuesThisFrame
|
|
Pause_Timers()
|
|
g_bPauseCommsQueuesThisFrame = FALSE
|
|
ENDIF
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
ENDIF
|
|
|
|
IF g_bTriggerDebugOn
|
|
Debug_Draw_All_Queued_Comms_Restricted_Areas()
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
MAINTAIN_HUNTING_PHONECALL_STATUS()
|
|
|
|
WAIT(0)
|
|
ENDWHILE
|
|
ENDSCRIPT
|