Files
gtav-src/script/dev_ng/singleplayer/scripts/friends/friendActivity.sc
T
2025-09-29 00:52:08 +02:00

1285 lines
43 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// _________________________________________________________________________________________
// _________________________________________________________________________________________
// ___ ___
// ___ Author: Sam Hackett Date: 19/07/2012 ___
// _________________________________________________________________________________________
// ___ ___
// ___ (A1) - FriendActivity file for use FriendActivity.sc ___
// ___ ___
// _________________________________________________________________________________________
//Compile out Title Update changes to header functions.
//Must be before includes.
//CONST_INT USE_TU_CHANGES 0 // Removed by Kenneth R.
USING "rage_builtins.sch"
USING "globals.sch"
USING "model_enums.sch"
USING "commands_streaming.sch"
USING "script_blips.sch"
//- commands headers -//
//- script headers -//
//- public headers -//
USING "cellphone_public.sch"
USING "cutscene_public.sch"
USING "friends_public.sch"
USING "mission_control_public.sch"
USING "mission_control_public.sch"
USING "selector_public.sch"
USING "timer_public.sch"
//- private headers -//
USING "player_scene_schedule.sch"
USING "friendActivity_pickup_private.sch"
USING "friendActivity_journey_private.sch"
USING "friendActivity_bar_private.sch"
USING "friendActivity_squad_private.sch"
USING "friendActivity_dropoff_private.sch"
#IF IS_DEBUG_BUILD
//- debug headers -//
USING "friends_debug.sch"
USING "script_debug.sch"
USING "shared_debug.sch"
USING "code_control_public.sch"
#ENDIF
// *******************************************************************************************
// VARIABLES
// *******************************************************************************************
BOOL gIsActivityInProgress = TRUE
BOOL bAddedInitialPeds = FALSE
// Widget stuff (WIDGET_ID and BOOL and INT and FLOAT and VECTOR)
#IF IS_DEBUG_BUILD
WIDGET_GROUP_ID friend_activitys_widget
INT debug_iCurActivityState
BOOL debug_bRegisterATextMessage
// BOOL debug_bDisplayFriend
// BOOL debug_bJumpToDropoffOnfoot
// BOOL debug_bJumpToDropoffIncar
#ENDIF
// *******************************************************************************************
// GENERAL FUNCTIONS AND PROCEDURES
// *******************************************************************************************
//PURPOSE: Stores the most recent friend for hospital cutscene (needs to store here rather than on pickup, in case player switched since then)
FUNC BOOL Private_StoreRecentFriend()
enumCharacterList ePlayerChar = GET_CURRENT_PLAYER_PED_ENUM()
enumCharacterList eChar
REPEAT MAX_BATTLE_BUDDIES eChar
IF ePlayerChar <> eChar
AND Private_HasSoldierBeenAvailable(gActivity.mSoldiers[eChar], FALSE)
g_eRecentFriendChar = eChar
CPRINTLN(DEBUG_FRIENDS, "Priavte_StoreRecentFriend() - ", GetLabel_enumCharacterList(g_eRecentFriendChar), " (soldier)")
RETURN TRUE
ENDIF
ENDREPEAT
IF gActivity.mFriendA.bWasPickedUp
g_eRecentFriendChar = gActivity.mFriendA.eChar
CPRINTLN(DEBUG_FRIENDS, "Priavte_StoreRecentFriend() - ", GetLabel_enumCharacterList(g_eRecentFriendChar), " (friendA)")
RETURN TRUE
ENDIF
IF gActivity.mFriendB.bWasPickedUp
g_eRecentFriendChar = gActivity.mFriendB.eChar
CPRINTLN(DEBUG_FRIENDS, "Priavte_StoreRecentFriend() - ", GetLabel_enumCharacterList(g_eRecentFriendChar), " (friendB)")
RETURN TRUE
ENDIF
CPRINTLN(DEBUG_FRIENDS, "Priavte_StoreRecentFriend() - no-one to store")
g_eRecentFriendChar = NO_CHARACTER
RETURN FALSE
ENDFUNC
//PURPOSE: Called on completion of the mission to release memory used for models etc
PROC FriendActivity_Cleanup()
IF bAddedInitialPeds
// Cleanup each activity member...
Private_CleanupFriend(gActivity.mPlayer, MC_AmbientWander)
Private_CleanupFriend(gActivity.mFriendA, MC_AmbientWander)
Private_CleanupFriend(gActivity.mFriendB, MC_AmbientWander)
// Cleanup each squad member...
INT i
REPEAT MAX_BATTLE_BUDDIES i
Private_CleanupSoldier(gActivity.mSoldiers[i]) // TODO: This needs working out
ENDREPEAT
PRIVATE_SET_FRIEND_A_PED_ID(null)
PRIVATE_SET_FRIEND_B_PED_ID(null)
// Remove anim dicts
Private_ReleaseFriendPickupResources()
// Destroy scripted cams
SET_CINEMATIC_BUTTON_ACTIVE(TRUE)
#IF IS_DEBUG_BUILD
// Delete the mission widget
IF DOES_WIDGET_GROUP_EXIST(friend_activitys_widget)
DELETE_WIDGET_GROUP(friend_activitys_widget)
ENDIF
#ENDIF
// Kill mission text link
SET_GAME_PAUSED(FALSE)
KILL_FACE_TO_FACE_CONVERSATION()
// Restore stirp club
IF gActivity.bRestoreStripClub
SET_MISSION_FLOW_BITSET_BIT_STATE(FLOWBITSET_MINIGAME_ACTIVE, ENUM_TO_INT(MINIGAME_STRIPCLUB), TRUE)
ENDIF
// Unblock scenarios at dropoff (if necessary)
// Private_ClearDropoffScenarioBlocking()
// Reset relgroups the soldiers may have set the playergroup to hate // BBUDDIES REMOVED
// Private_ResetHatedRelGroups()
#IF IS_DEBUG_BUILD
SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(FALSE)
#ENDIF
ENDIF
// Clear adhoc location
Private_ClearAdhocFriendLoc()
// Clearing Load Scene
IF IS_NEW_LOAD_SCENE_ACTIVE()
NEW_LOAD_SCENE_STOP()
ENDIF
// Reset battle buddy behaviour
// RESET_ALL_BATTLEBUDDY_BEHAVIOUR_REQUESTS()
// Reset flags
g_bitfieldFriendFlags = 0
g_bitfieldBattleBuddyAvailable = 0
g_bitfieldBattleBuddyOverridden = 0
// Enable selector and ambient player creation
g_bSupressAmbientPlayersForFriendActivity = FALSE
// Reset any friend connections that are active (in case player is third party)
g_SavedGlobals.sFriendsData.g_FriendScriptThread = 0
DEACTIVATE_ALL_CONNECTIONS()
// Restore location blips
IF gActivity.bRestoreLocationBlips
Private_RestoreLocationBlips()
gActivity.bRestoreLocationBlips = FALSE
ENDIF
IF (gActivity.iCandidateID <> NO_CANDIDATE_ID)
CPRINTLN(DEBUG_FRIENDS, "FriendActivity_Cleanup() - Candidate ID: ", gActivity.iCandidateID)
Mission_Over(gActivity.iCandidateID)
ELSE
CPRINTLN(DEBUG_FRIENDS, "FriendActivity_Cleanup() - No candidate ID")
ENDIF
TERMINATE_THIS_THREAD()
ENDPROC
//PURPOSE: Called on successful completion of the mission
PROC FriendActivity_Passed()
CLEAR_PRINTS()
MAKE_AUTOSAVE_REQUEST()
gIsActivityInProgress = FALSE
ENDPROC
//PURPOSE: Called when mission had been failed. Currently ends
PROC FriendActivity_Failed(enumActivityFailReason eFail)
#IF IS_DEBUG_BUILD
IF gActivity.mPlayer.eState <> FRIEND_NULL AND Private_IsPlayerThirdParty()
CPRINTLN(DEBUG_FRIENDS, "FriendActivity_Failed() - Player is third party - no text messages will be sent")
ENDIF
#ENDIF
enumCharacterList ePlayerChar = GET_CURRENT_PLAYER_PED_ENUM()
IF gActivity.eLogFailCharA <> NO_CHARACTER
PLAYSTATS_FRIEND_ACTIVITY(ENUM_TO_INT(gActivity.eLogFailCharA), 1)
ENDIF
IF gActivity.eLogFailCharB <> NO_CHARACTER
AND gActivity.eLogFailCharB <> gActivity.eLogFailCharA
PLAYSTATS_FRIEND_ACTIVITY(ENUM_TO_INT(gActivity.eLogFailCharB), 1)
ENDIF
SWITCH eFail
#IF IS_DEBUG_BUILD
CASE FAF_Debug
CPRINTLN(DEBUG_FRIENDS, "FriendActivity_Failed: FAF_Debug")
PRINT_NOW("FR_X_DEBUG", DEFAULT_GOD_TEXT_TIME, 0)
BREAK
#ENDIF
// Player - multiplayer --------------------------------------------------
CASE FAF_Multiplayer
CPRINTLN(DEBUG_FRIENDS, "FriendActivity_Failed: FAF_Multiplayer")
BREAK
// Player - death/arrest -------------------------------------------------
CASE FAF_PlayerDeathArrest
CPRINTLN(DEBUG_FRIENDS, "FriendActivity_Failed: FAF_PlayerDeathArrest")
enumFriendTextMessage eTxtMessage
IF IS_PLAYER_BEING_ARRESTED(PLAYER_ID())
eTxtMessage = FTM_PLAYER_BUSTED
ELSE
eTxtMessage = FTM_PLAYER_DIED
Private_StoreRecentFriend() // Flags to Alwyns respawn controller that it should do some dialogue about dying with the friend
ENDIF
IF ePlayerChar <> CHAR_MICHAEL AND Private_HasSoldierBeenAvailable(gActivity.mSoldiers[CHAR_MICHAEL], TRUE)
REGISTERED_FRIEND_TEXT_MESSAGE_TO_PLAYER(ePlayerChar, CHAR_MICHAEL, eTxtMessage)
ELIF ePlayerChar <> CHAR_FRANKLIN AND Private_HasSoldierBeenAvailable(gActivity.mSoldiers[CHAR_FRANKLIN], TRUE)
REGISTERED_FRIEND_TEXT_MESSAGE_TO_PLAYER(ePlayerChar, CHAR_FRANKLIN, eTxtMessage)
ELIF ePlayerChar <> CHAR_TREVOR AND Private_HasSoldierBeenAvailable(gActivity.mSoldiers[CHAR_TREVOR], TRUE)
REGISTERED_FRIEND_TEXT_MESSAGE_TO_PLAYER(ePlayerChar, CHAR_TREVOR, eTxtMessage)
ELIF ePlayerChar <> CHAR_MICHAEL AND Private_HasSoldierBeenAvailable(gActivity.mSoldiers[CHAR_MICHAEL], FALSE)
REGISTERED_FRIEND_TEXT_MESSAGE_TO_PLAYER(ePlayerChar, CHAR_MICHAEL, eTxtMessage)
ELIF ePlayerChar <> CHAR_FRANKLIN AND Private_HasSoldierBeenAvailable(gActivity.mSoldiers[CHAR_FRANKLIN], FALSE)
REGISTERED_FRIEND_TEXT_MESSAGE_TO_PLAYER(ePlayerChar, CHAR_FRANKLIN, eTxtMessage)
ELIF ePlayerChar <> CHAR_TREVOR AND Private_HasSoldierBeenAvailable(gActivity.mSoldiers[CHAR_TREVOR], FALSE)
REGISTERED_FRIEND_TEXT_MESSAGE_TO_PLAYER(ePlayerChar, CHAR_TREVOR, eTxtMessage)
ELIF gActivity.mPlayer.eState = FRIEND_NULL OR NOT Private_IsPlayerThirdParty()
IF gActivity.mFriendA.eState <> FRIEND_NULL
REGISTERED_FRIEND_TEXT_MESSAGE_TO_PLAYER(ePlayerChar, gActivity.mFriendA.eChar, eTxtMessage)
ELIF gActivity.mFriendB.eState <> FRIEND_NULL
REGISTERED_FRIEND_TEXT_MESSAGE_TO_PLAYER(ePlayerChar, gActivity.mFriendB.eChar, eTxtMessage)
ENDIF
ENDIF
BREAK
// Player - on mission ---------------------------------------------------
CASE FAF_PlayerOnMission
CPRINTLN(DEBUG_FRIENDS, "FriendActivity_Failed: FAF_PlayerOnMission")
BREAK
// Player - switched -----------------------------------------------------
CASE FAF_PlayerSwitch
CPRINTLN(DEBUG_FRIENDS, "FriendActivity_Failed: FAF_PlayerSwitch")
// PRINT_HELP("FR_X_CANCEL") // The friend activity has been cancelled.
BREAK
// Retry abort -----------------------------------------------------------
CASE FAF_RetryAbort
CPRINTLN(DEBUG_FRIENDS, "FriendActivity_Failed: FAF_RetryAbort")
// Delete all members
Private_CleanupSoldier(gActivity.mSoldiers[0], MC_Delete)
Private_CleanupSoldier(gActivity.mSoldiers[1], MC_Delete)
Private_CleanupSoldier(gActivity.mSoldiers[2], MC_Delete)
Private_CleanupFriend(gActivity.mPlayer, MC_Delete)
Private_CleanupFriend(gActivity.mFriendA, MC_Delete)
Private_CleanupFriend(gActivity.mFriendB, MC_Delete)
BREAK
// Playback abort --------------------------------------------------------
CASE FAF_PlaybackAbort
CPRINTLN(DEBUG_FRIENDS, "FriendActivity_Failed: FAF_PlaybackAbort")
// Delete all members
Private_CleanupSoldier(gActivity.mSoldiers[0], MC_DeletePedAndCar)
Private_CleanupSoldier(gActivity.mSoldiers[1], MC_DeletePedAndCar)
Private_CleanupSoldier(gActivity.mSoldiers[2], MC_DeletePedAndCar)
Private_CleanupFriend(gActivity.mPlayer, MC_DeletePedAndCar)
Private_CleanupFriend(gActivity.mFriendA, MC_DeletePedAndCar)
Private_CleanupFriend(gActivity.mFriendB, MC_DeletePedAndCar)
BREAK
// Member fails...
CASE FAF_MemberFail
// TODO: Add FRIEND_FAIL_REMOVED and differentiate from FRIEND_CANCEL. Then make the cancel one print "cancelled" fail reason
BREAK
DEFAULT
CPRINTLN(DEBUG_FRIENDS, "FriendActivity_Failed: UNKNOWN enumActivityFailReason")
SCRIPT_ASSERT("FriendActivity_Failed: UNKNOWN enumActivityFailReason")
BREAK
ENDSWITCH
// Push text messages into comms manager queue
IF eFail <> FAF_Multiplayer
Private_FlushTextMessageQueue()
ENDIF
gIsActivityInProgress = FALSE
ENDPROC
#IF IS_DEBUG_BUILD
// *******************************************************************************************
// DEBUGGING FUNCTIONS AND PROCEDURES
// *******************************************************************************************
PROC DEBUG_DisplayGeneralInfo()
// Print activity state
DrawFriendLiteralString(GetLabel_enumActivityState(gActivity.mState), 1, HUD_COLOUR_GREY)
// Print dialogue state
TEXT_LABEL_63 tDialogueState = GetLabel_enumFriendDialogueState(gActivity.mDialogue.eState)
tDialogueState += ": "
IF IS_TIMER_STARTED(gActivity.mDialogue.mGeneralTimer)
tDialogueState += GET_STRING_FROM_MILISECONDS(ROUND(GET_TIMER_IN_SECONDS(gActivity.mDialogue.mGeneralTimer) * 1000.0))
ENDIF
DrawFriendLiteralString(tDialogueState, 2, HUD_COLOUR_GREYLIGHT)
// TEXT_LABEL_63 tDialogueState = "General timer: "
// IF IS_TIMER_STARTED(gActivity.mDialogue.mGeneralTimer)
// tDialogueState += GET_STRING_FROM_MILISECONDS(ROUND(GET_TIMER_IN_SECONDS(gActivity.mDialogue.mGeneralTimer) * 1000.0))
// ENDIF
// DrawFriendLiteralString(tDialogueState, 2, HUD_COLOUR_GREYLIGHT)
tDialogueState = "Chat timer: "
IF IS_TIMER_STARTED(gActivity.mDialogue.mChatTimer)
tDialogueState += GET_STRING_FROM_MILISECONDS(ROUND(GET_TIMER_IN_SECONDS(gActivity.mDialogue.mChatTimer) * 1000.0))
ENDIF
DrawFriendLiteralString(tDialogueState, 3, HUD_COLOUR_GREYLIGHT)
// IF gActivity.mDialogue.eState <> gActivity.mDialogue.eDefaultState
// TEXT_LABEL_63 tDefaultState = GetLabel_enumFriendDialogueState(gActivity.mDialogue.eDefaultState)
// DrawFriendLiteralString(tDefaultState, 3, HUD_COLOUR_GREYDARK)
// ENDIF
// Print dialogue chat timer
// IF gActivity.mDialogue.eState = FDIALOGUE_JOURNEY_IDLE
// TEXT_LABEL_63 tTimerState = "Chat:"
// IF IS_TIMER_STARTED(gActivity.mDialogue.mGeneralTimer)
// tTimerState += GET_STRING_FROM_MILISECONDS(ROUND(GET_TIMER_IN_SECONDS(gActivity.mDialogue.mChatTimer) * 1000.0))
// ENDIF
//
// DrawFriendLiteralString(tTimerState, 3, HUD_COLOUR_GREY)
// ENDIF
// IF IS_TIMER_STARTED(gActivity.mDialogue.mGeneralTimer)
// tDialogueState += " g"
// tDialogueState += FLOOR(GET_TIMER_IN_SECONDS(gActivity.mDialogue.mGeneralTimer))
// ENDIF
// IF IS_TIMER_STARTED(gActivity.mDialogue.mChatTimer)
// tDialogueState += " c"
// tDialogueState += FLOOR(GET_TIMER_IN_SECONDS(gActivity.mDialogue.mChatTimer))
// ENDIF
// tDialogueState += " / "
// tDialogueState += GetLabel_enumFriendAudioState(gActivity.mAudio.eState)
// DrawFriendLiteralString(tDialogueState, 2, HUD_COLOUR_GREY)
ENDPROC
//PURPOSE: Initialises the mission widget
PROC Create_FriendActivity_Widget()
INT iWidget
TEXT_LABEL_63 str = "friendActivity.sc - "
str += GetLabel_enumCharacterList(gActivity.mFriendA.eChar)
friend_activitys_widget = START_WIDGET_GROUP(str)
START_NEW_WIDGET_COMBO()
REPEAT COUNT_OF(enumActivityState) iWidget
ADD_TO_WIDGET_COMBO(GetLabel_enumActivityState(INT_TO_ENUM(enumActivityState, iWidget)))
ENDREPEAT
STOP_WIDGET_COMBO("debug_iCurActivityState", debug_iCurActivityState)
ADD_WIDGET_INT_SLIDER("gActivity.iVisitedCount", gActivity.iVisitedCount, 0, CONST_iMaxVisitedLocations, 1)
ADD_WIDGET_BOOL("bRegisterATextMessage", debug_bRegisterATextMessage)
STOP_WIDGET_GROUP()
ENDPROC
//PROC DEBUG_Get_Row_For_DrawFriendLiteralString()
//
// iACTIVITY_DRAW_ROW = 5
//
// IF g_iDebugSelectedFriendConnDisplay > 0
// IF g_iDebugSelectedFriendConnDisplay = 1
// //F8 display is on
// enumFamilyMember loopAsStrandID
// REPEAT NUM_OF_PLAYABLE_PEDS loopAsStrandID
// TIMEOFDAY sLastTimeActive = g_savedGlobals.sPlayerData.sInfo.sLastTimeActive[loopAsStrandID]
// IF Is_TimeOfDay_Valid(sLastTimeActive)
// iACTIVITY_DRAW_ROW++
// ENDIF
// ENDREPEAT
//
// ELIF g_iDebugSelectedFriendConnDisplay = 2
// //F10 display is on
// iACTIVITY_DRAW_ROW = 4
// ELSE
// //some other display is on???
// CPRINTLN(DEBUG_FRIENDS, "g_iDebugSelectedFriendConnDisplay: ", g_iDebugSelectedFriendConnDisplay)
// ENDIF
// ENDIF
//
// BOOL bBefore = FALSE
// enumFriendConnection connID
// REPEAT MAX_FRIEND_CONNECTIONS connID
// enumFriend friendA_ID = g_SavedGlobals.sFriendsData.g_FriendConnectData[connID].friendA
// enumFriend friendB_ID = g_SavedGlobals.sFriendsData.g_FriendConnectData[connID].friendB
//
// enumCharacterList friendA_CharID = GET_CHAR_FROM_FRIEND(friendA_ID)
// enumCharacterList friendB_CharID = GET_CHAR_FROM_FRIEND(friendB_ID)
//
// IF HAVE_CHARS_ARRANGED_FRIEND_ACTIVITY(friendA_CharID, friendB_CharID)
// IF ((gActivity.mPlayer.eChar = friendA_CharID) AND (gActivity.mFriendA.eChar = friendB_CharID))
// OR ((gActivity.mPlayer.eChar = friendB_CharID) AND (gActivity.mFriendA.eChar = friendA_CharID))
// bBefore = TRUE
// ELSE
// IF NOT bBefore
// iACTIVITY_DRAW_ROW += 4
// ENDIF
// ENDIF
// ENDIF
// ENDREPEAT
//
//ENDPROC
//PURPOSE: Moniters for any changes in the mission widget
PROC Watch_FriendActivity_Widget()
debug_iCurActivityState = ENUM_TO_INT(gActivity.mState)
IF debug_bRegisterATextMessage
enumFriendTextMessage eFriendTextMessage = INT_TO_ENUM(enumFriendTextMessage, GET_RANDOM_INT_IN_RANGE(0, ENUM_TO_INT(MAX_FRIEND_TEXT_MESSAGES)))
IF gActivity.mPlayer.eChar <> NO_CHARACTER
g_iCharWaitTime[gActivity.mPlayer.eChar] = GET_GAME_TIMER()
ENDIF
IF gActivity.mFriendA.eChar <> NO_CHARACTER
g_iCharWaitTime[gActivity.mFriendA.eChar] = GET_GAME_TIMER()
ENDIF
IF REGISTERED_FRIEND_TEXT_MESSAGE_TO_PLAYER(gActivity.mPlayer.eChar, gActivity.mFriendA.eChar, eFriendTextMessage)
debug_bRegisterATextMessage = FALSE
ENDIF
ENDIF
ENDPROC
PROC DEBUG_GetJumpLocationText(enumActivityLocation eJumpLoc, TEXT_LABEL_63& tLocName, INT& Red, INT& Green, INT& Blue)
INT iAlpha
IF eJumpLoc = MAX_ACTIVITY_LOCATIONS
IF gActivity.iVisitedCount > 0
GET_HUD_COLOUR(HUD_COLOUR_PURE_WHITE, Red, Green, Blue, iAlpha)
ELSE
GET_HUD_COLOUR(HUD_COLOUR_RED, Red, Green, Blue, iAlpha)
ENDIF
tLocName = "Dropoff"
ELIF eJumpLoc = ALOC_suspendFriends
GET_HUD_COLOUR(HUD_COLOUR_PURE_WHITE, Red, Green, Blue, iAlpha)
tLocName = "Cancel warp"
ELSE
// Check if visited already
BOOL bAlreadyVisited = IS_EXTENDED_BIT_SET(gActivity.bitsVisitedActivities, ENUM_TO_INT(g_ActivityLocations[eJumpLoc].type))
structBits64 emptyBits
RESET_EXTENDED_BITS(emptyBits)
// Determine text colour
IF Private_IsLocationAvailable(eJumpLoc, gActivity.mPlayer.eChar, gActivity.mFriendA.eChar, gActivity.mFriendB.eChar, emptyBits, emptyBits, gActivity.eDropoffLoc, IS_CINEMA_OPEN_NOW(), IS_GOLF_OPEN_NOW(), FALSE) // NB: Tell it there are no visited locations, so we can get visited ones, then colour them yellow if visited
IF NOT bAlreadyVisited
GET_HUD_COLOUR(HUD_COLOUR_PURE_WHITE, Red, Green, Blue, iAlpha)
ELSE
GET_HUD_COLOUR(HUD_COLOUR_GREY, Red, Green, Blue, iAlpha)
ENDIF
ELSE
GET_HUD_COLOUR(HUD_COLOUR_RED, Red, Green, Blue, iAlpha)
ENDIF
tLocName = GetLabel_enumActivityLocation(eJumpLoc)
ENDIF
ENDPROC
PROC DEBUG_SelectJumpLocation(enumActivityLocation &eJumpLoc)
WHILE IS_KEYBOARD_KEY_PRESSED(KEY_J)
//-- Update key input
INT iJumpLoc = ENUM_TO_INT(eJumpLoc)
INT iMAX_LOCATIONS = ENUM_TO_INT(MAX_ACTIVITY_LOCATIONS)
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_H)
iJumpLoc--
IF iJumpLoc < 0
iJumpLoc = iMAX_LOCATIONS
ENDIF
ENDIF
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_K)
iJumpLoc++
IF iJumpLoc > iMAX_LOCATIONS
iJumpLoc = 0
ENDIF
ENDIF
INT iPrevLoc = iJumpLoc - 1
IF iPrevLoc < 0
iPrevLoc = iMAX_LOCATIONS
ENDIF
INT iNextLoc = ENUM_TO_INT(iJumpLoc) + 1
IF iNextLoc > iMAX_LOCATIONS
iNextLoc = 0
ENDIF
eJumpLoc = INT_TO_ENUM(enumActivityLocation, iJumpLoc)
enumActivityLocation ePrevLoc = INT_TO_ENUM(enumActivityLocation, iPrevLoc)
enumActivityLocation eNextLoc = INT_TO_ENUM(enumActivityLocation, iNextLoc)
//-- Display current selection
CONST_FLOAT fDEBUG_TEXT_SCALE 0.5
CONST_FLOAT fDEBUG_TEXT_CENTRE_X 0.40
CONST_FLOAT fDEBUG_TEXT_CENTRE_Y 0.75
SET_TEXT_SCALE(fDEBUG_TEXT_SCALE, fDEBUG_TEXT_SCALE)
INT JumpRed=0, JumpGreen=0, JumpBlue=0
INT PrevRed=0, PrevGreen=0, PrevBlue=0
INT NextRed=0, NextGreen=0, NextBlue=0
TEXT_LABEL_63 tJumpLocName = "", tPrevLocName = "", tNextLocName = ""
DEBUG_GetJumpLocationText(eJumpLoc, tJumpLocName, JumpRed, JumpGreen, JumpBlue)
DEBUG_GetJumpLocationText(ePrevLoc, tPrevLocName, PrevRed, PrevGreen, PrevBlue)
DEBUG_GetJumpLocationText(eNextLoc, tNextLocName, NextRed, NextGreen, NextBlue)
// Display current selection
SET_TEXT_COLOUR(JumpRed, JumpGreen, JumpBlue, 255)
DISPLAY_TEXT_WITH_LITERAL_STRING(fDEBUG_TEXT_CENTRE_X, fDEBUG_TEXT_CENTRE_Y, "FR_DEBUG_J", tJumpLocName)
// Display previous selection
SET_TEXT_SCALE(fDEBUG_TEXT_SCALE*0.9, fDEBUG_TEXT_SCALE*0.9)
SET_TEXT_COLOUR(PrevRed, PrevGreen, PrevBlue, 128)
DISPLAY_TEXT_WITH_LITERAL_STRING(fDEBUG_TEXT_CENTRE_X-0.05, fDEBUG_TEXT_CENTRE_Y-0.03, "STRING", tPrevLocName)
// Display next selection
SET_TEXT_SCALE(fDEBUG_TEXT_SCALE*0.9, fDEBUG_TEXT_SCALE*0.9)
SET_TEXT_COLOUR(NextRed, NextGreen, NextBlue, 128)
DISPLAY_TEXT_WITH_LITERAL_STRING(fDEBUG_TEXT_CENTRE_X+0.05, fDEBUG_TEXT_CENTRE_Y+0.03, "STRING", tNextLocName)
WAIT(0)
ENDWHILE
ENDPROC
//PURPOSE: Moniters for any keyboard inputs that would alter the mission (debug pass etc)
PROC FriendActivity_Debug_Options()
IF (gActivity.mState <> ACTIVITY_STATE_Pickup)
AND (gActivity.mState <> ACTIVITY_STATE_Minigame)
// AND (gActivity.mState <> ACTIVITY_STATE_SquadMission)
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_S)
Private_ClearObjective()
Private_CleanupFriend(gActivity.mFriendA, MC_Delete)
Private_CleanupFriend(gActivity.mFriendB, MC_Delete)
INT i
REPEAT MAX_BATTLE_BUDDIES i
Private_CleanupSoldier(gActivity.mSoldiers[i], MC_Delete)
ENDREPEAT
FriendActivity_Passed()
ENDIF
IF IS_KEYBOARD_KEY_JUST_PRESSED(KEY_F)
Private_ClearObjective()
Private_CleanupFriend(gActivity.mFriendA, MC_Delete)
Private_CleanupFriend(gActivity.mFriendB, MC_Delete)
INT i
REPEAT MAX_BATTLE_BUDDIES i
Private_CleanupSoldier(gActivity.mSoldiers[i], MC_Delete)
ENDREPEAT
FriendActivity_Failed(FAF_Debug)
ENDIF
ENDIF
IF IS_KEYBOARD_KEY_PRESSED(KEY_J) // Jump to next mission stage
IF IS_PLAYER_CONTROL_ON(PLAYER_ID())
SWITCH gActivity.mState
CASE ACTIVITY_STATE_Pickup
VECTOR vDriveway
VECTOR vPickupJumpOffset
IF gActivity.mFriendA.eState = FRIEND_PICKUP
vDriveway = gActivity.mFriendA.vDriveway
vPickupJumpOffset = DEBUG_GetFriendLocJumpOffset(gActivity.mFriendA.ePickup)
ELIF gActivity.mFriendB.eState = FRIEND_PICKUP
vDriveway = gActivity.mFriendB.vDriveway
vPickupJumpOffset = DEBUG_GetFriendLocJumpOffset(gActivity.mFriendB.ePickup)
ELSE
EXIT // BREAK - Not sure if this would break the parsing in this language
ENDIF
IF NOT GET_MISSION_FLAG()
// BOOL bNeedToLoadScene
IF NOT IS_ENTITY_AT_COORD(PLAYER_PED_ID(), vDriveway, <<20.0, 20.0, 20.0>>)
SET_PED_COORDS_KEEP_VEHICLE(PLAYER_PED_ID(), vDriveway+vPickupJumpOffset)
SET_ENTITY_HEADING(PLAYER_PED_ID(), GET_HEADING_FROM_VECTOR_2D(-vPickupJumpOffset.x, -vPickupJumpOffset.y))
// bNeedToLoadScene = TRUE
ELSE
SET_PED_COORDS_KEEP_VEHICLE(PLAYER_PED_ID(), vDriveway)
SET_ENTITY_HEADING(PLAYER_PED_ID(), GET_RANDOM_FLOAT_IN_RANGE(0.0, 360.0))
// bNeedToLoadScene = FALSE
ENDIF
// Force create member peds within 100m radius
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
BOOL bCreatedAllPeds
bCreatedAllPeds = FALSE
WHILE NOT bCreatedAllPeds
bCreatedAllPeds = TRUE
// IF gActivity.mPlayer.eState = FRIEND_PICKUP
// IF NOT DOES_ENTITY_EXIST(gActivity.mPlayer.hPed)
// VECTOR vCreatePos = g_savedGlobals.sPlayerData.sInfo.vLastKnownCoords[friend.eChar]
// FLOAT fCreateRot = g_savedGlobals.sPlayerData.sInfo.fLastKnownHead[friend.eChar]
// TIMEOFDAY sLastTimeActive = g_savedGlobals.sPlayerData.sInfo.sLastTimeActive[friend.eChar]
//
// IF Is_TIMEOFDAY_Valid(sLastTimeActive)
// AND NOT HasNumOfHoursPassedSincePedTimeStruct(sLastTimeActive, 1)
// AND NOT ARE_VECTORS_EQUAL(vCreatePos, <<0,0,0>>) AND (fCreateRot = 0)
// IF Util_IsPedInsideRange(PLAYER_PED_ID(), vCreatePos, 100.0)
// IF NOT Private_TryCreateMember_AtLastKnownPos(gActivity.mPlayer, 150, 40, TRUE)
// bCreatedAllPeds = FALSE
// ENDIF
// ENDIF
// ENDIF
// ENDIF
// ENDIF
IF gActivity.mFriendA.eState = FRIEND_PICKUP
IF NOT DOES_ENTITY_EXIST(gActivity.mFriendA.hPed)
IF Util_IsPedInsideRange(PLAYER_PED_ID(), gActivity.mFriendA.vDoorstep, 100.0)
IF NOT Private_TryCreateFriend_AtDest(gActivity.mFriendA, TRUE)
bCreatedAllPeds = FALSE
ENDIF
ENDIF
ENDIF
ENDIF
IF gActivity.mFriendB.eState = FRIEND_PICKUP
IF NOT DOES_ENTITY_EXIST(gActivity.mFriendB.hPed)
IF Util_IsPedInsideRange(PLAYER_PED_ID(), gActivity.mFriendB.vDoorstep, 100.0)
IF NOT Private_TryCreateFriend_AtDest(gActivity.mFriendB, TRUE)
bCreatedAllPeds = FALSE
ENDIF
ENDIF
ENDIF
ENDIF
WAIT(0)
ENDWHILE
SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
// IF bNeedToLoadScene
// LOAD_SCENE(vDriveway)
// ENDIF
ENDIF
BREAK
CASE ACTIVITY_STATE_Journey
enumActivityLocation eJumpLocation
VECTOR vExactPos
VECTOR vJumpOffset
VECTOR vJumpPos
FLOAT fJumpRot
IF gActivity.iVisitedCount = 0
eJumpLocation = ALOC_cinema_vinewood
ELSE
eJumpLocation = MAX_ACTIVITY_LOCATIONS
ENDIF
// Let player select jump location
DEBUG_SelectJumpLocation(eJumpLocation)
IF eJumpLocation <> ALOC_suspendFriends
IF eJumpLocation <> MAX_ACTIVITY_LOCATIONS
// Jumping to an activity
vExactPos = GET_STATIC_BLIP_POSITION(g_ActivityLocations[eJumpLocation].sprite)
vJumpOffset = DEBUG_GetActivityLocJumpOffset(eJumpLocation)
ELSE
// Jumping to dropoff
vExactPos = gActivity.vDropoff
vJumpOffset = DEBUG_GetFriendLocJumpOffset(gActivity.eDropoffLoc)
ENDIF
IF vJumpOffset.x > 0.001 OR vJumpOffset.y > 0.001
fJumpRot = GET_HEADING_FROM_VECTOR_2D(-vJumpOffset.x, -vJumpOffset.y)
ELSE
fJumpRot = 0.0
ENDIF
vJumpPos = vExactPos + vJumpOffset
// Warp player to dest
IF NOT IS_ENTITY_AT_COORD(PLAYER_PED_ID(), vExactPos, <<20.0, 20.0, 20.0>>)
LOAD_SCENE(vExactPos)
SET_PED_COORDS_KEEP_VEHICLE(PLAYER_PED_ID(), vJumpPos)
SET_ENTITY_HEADING(PLAYER_PED_ID(), fJumpRot)
ELSE
SET_PED_COORDS_KEEP_VEHICLE(PLAYER_PED_ID(), vExactPos)
SET_ENTITY_HEADING(PLAYER_PED_ID(), GET_RANDOM_FLOAT_IN_RANGE(0.0, 360.0))
ENDIF
// If player is in car, make sure buddy is in car too
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
VEHICLE_INDEX tempPlayerVeh
tempPlayerVeh = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())
IF NOT IS_PED_INJURED(FRIEND_A_PED_ID())
IF NOT IS_ENTITY_DEAD(tempPlayerVeh)
IF NOT IS_PED_IN_VEHICLE(FRIEND_A_PED_ID(), tempPlayerVeh)
SET_PED_INTO_VEHICLE(FRIEND_A_PED_ID(), tempPlayerVeh, VS_ANY_PASSENGER)
ENDIF
ENDIF
ENDIF
IF NOT IS_PED_INJURED(FRIEND_B_PED_ID())
IF NOT IS_ENTITY_DEAD(tempPlayerVeh)
IF NOT IS_PED_IN_VEHICLE(FRIEND_B_PED_ID(), tempPlayerVeh)
SET_PED_INTO_VEHICLE(FRIEND_B_PED_ID(), tempPlayerVeh, VS_ANY_PASSENGER)
ENDIF
ENDIF
ENDIF
ENDIF
// If buddy hasn't made it, just warp into vicinity
IF NOT IS_PED_INJURED(FRIEND_A_PED_ID())
IF NOT IS_ENTITY_AT_ENTITY(FRIEND_A_PED_ID(), PLAYER_PED_ID(), <<10.0, 10.0, 10.0>>)
SET_ENTITY_COORDS(FRIEND_A_PED_ID(), GET_ENTITY_COORDS(PLAYER_PED_ID())+<<GET_RANDOM_FLOAT_IN_RANGE(-5,5),GET_RANDOM_FLOAT_IN_RANGE(-5,5),0>>)
ENDIF
ENDIF
IF NOT IS_PED_INJURED(FRIEND_B_PED_ID())
IF NOT IS_ENTITY_AT_ENTITY(FRIEND_B_PED_ID(), PLAYER_PED_ID(), <<10.0, 10.0, 10.0>>)
SET_ENTITY_COORDS(FRIEND_B_PED_ID(), GET_ENTITY_COORDS(PLAYER_PED_ID())+<<GET_RANDOM_FLOAT_IN_RANGE(-5,5),GET_RANDOM_FLOAT_IN_RANGE(-5,5),0>>)
ENDIF
ENDIF
ENDIF
BREAK
DEFAULT
SAVE_STRING_TO_DEBUG_FILE("SKIP gActivity.mState = ")
SAVE_STRING_TO_DEBUG_FILE(GetLabel_enumActivityState(gActivity.mState))
SAVE_NEWLINE_TO_DEBUG_FILE()
BREAK
ENDSWITCH
ENDIF
CLEAR_PRINTS()
HANG_UP_AND_PUT_AWAY_PHONE()
SET_GAMEPLAY_CAM_RELATIVE_HEADING(0.0)
WHILE IS_KEYBOARD_KEY_PRESSED(KEY_J)
WAIT(0)
ENDWHILE
ENDIF
IF IS_KEYBOARD_KEY_PRESSED(KEY_W)
IF (g_iDebugSelectedFriendConnDisplay > 0)
IF (g_savedGlobals.sFlow.isGameflowActive)
Set_Mission_Flow_Flag_State(FLOWFLAG_ALLOW_RANDOM_EVENTS, TRUE)
Set_Mission_Flow_Flag_State(FLOWFLAG_ALLOW_CINEMA_ACTIVITY, TRUE)
Set_Mission_Flow_Flag_State(FLOWFLAG_ALLOW_COMEDYCLUB_ACTIVITY, TRUE)
Set_Mission_Flow_Flag_State(FLOWFLAG_ALLOW_LIVEMUSIC_ACTIVITY, TRUE)
Execute_Code_ID(CID_ACTIVATE_MINIGAME_POST_ARM3_BLOCK)
Execute_Code_ID(CID_ACTIVATE_MINIGAME_GOLF)
Execute_Code_ID(CID_ACTIVATE_MINIGAME_DARTS2)
Execute_Code_ID(CID_ACTIVATE_MINIGAME_STRIPCLUB)
ENDIF
ENDIF
ENDIF
ENDPROC
#ENDIF
// *******************************************************************************************
// MISSION SPECIFIC FUNCTIONS AND PROCEDURES
// *******************************************************************************************
FUNC BOOL Private_IsAmbientLaunching(enumFriend eFriend)
IF bAddedInitialPeds = FALSE
enumCharacterList eChar = GET_CHAR_FROM_FRIEND(eFriend)
IF IS_PLAYER_PED_PLAYABLE(eChar)
SELECTOR_SLOTS_ENUM eSelectorSlot = GET_SELECTOR_SLOT_FROM_PLAYER_PED_ENUM(eChar)
PED_INDEX hSelectorPed = g_sPlayerPedRequest.sSelectorPeds.pedID[eSelectorSlot]
IF NOT IS_PED_INJURED(hSelectorPed)
RETURN TRUE
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
PROC INIT_VARS()
// Ensure bitfields are large enough
#IF IS_DEBUG_BUILD
IF ENUM_TO_INT(MAX_ACTIVITY_TYPES) >= 64
SCRIPT_ASSERT("MAX_ACTIVITY_TYPES >= 64, check that bitsAllowedActivities and bitsVisitedActivities can handle >= 64 bits")
ENDIF
IF ENUM_TO_INT(MAX_ACTIVITY_LOCATIONS) >= 64
SCRIPT_ASSERT("MAX_ACTIVITY_LOCATIONS >= 64, check that bitsVisitedLocations can handle >= 64 bits")
ENDIF
#ENDIF
// Initialise locations
Private_InitialiseFriendLocations(FALSE)
Private_InitialiseActivityLocations()
// Initialise members
Private_InitFriend(gActivity.mPlayer)
Private_InitFriend(gActivity.mFriendA)
Private_InitFriend(gActivity.mFriendB)
Private_InitSoldier(gActivity.mSoldiers[0], CHAR_MICHAEL)
Private_InitSoldier(gActivity.mSoldiers[1], CHAR_FRANKLIN)
Private_InitSoldier(gActivity.mSoldiers[2], CHAR_TREVOR)
// Init fail queues
Private_InitFailReasonQueue()
Private_InitTextMessageQueue()
//-- Initialise state vars
// System
gActivity.mState = ACTIVITY_STATE_Init
gActivity.mFailReason = FAF_NoFail
gActivity.bInitState = FALSE
gActivity.iCandidateID = NO_CANDIDATE_ID
gActivity.bIsCinemaEnabled = FALSE
gActivity.bIsGolfEnabled = FALSE
gActivity.bRestoreLocationBlips = FALSE
gActivity.bRestoreStripClub = FALSE
gActivity.bResumeFriendsAfterSquad = FALSE
gActivity.eGroupSpacing = FSPACING_NORMAL
gActivity.iLastHaircutChangeTime = GET_TIME_PLAYER_PED_LAST_CHANGED_HAIRDO(gActivity.mPlayer.eChar)
gActivity.iLastClothesChangeTime = GET_TIME_PLAYER_PED_LAST_CHANGED_CLOTHES(gActivity.mPlayer.eChar)
gActivity.iLastTattooChangeTime = GET_TIME_PLAYER_PED_LAST_GOT_TATTOO(gActivity.mPlayer.eChar)
gActivity.eLoadingActivityLoc = NO_ACTIVITY_LOCATION
gActivity.eLogFailCharA = NO_CHARACTER
gActivity.eLogFailCharB = NO_CHARACTER
gIsActivityInProgress = TRUE
g_bSupressAmbientPlayersForFriendActivity = TRUE // Disable ambient player spawning (so by the time player gets to friend, no ambient player should exist)
g_eRecentFriendChar = NO_CHARACTER
bAddedInitialPeds = FALSE
// General
gActivity.ePlayerChar = GET_CURRENT_PLAYER_PED_ENUM()
gActivity.bUpdateAfterSwitch = FALSE
gActivity.eQueuedFailTextMsg = NO_FRIEND_TEXT_MESSAGE
gActivity.eQueuedFailTextSender = NO_CHARACTER
gActivity.eQueuedFailTextReceiver = NO_CHARACTER
gActivity.mDialogue.eState = FDIALOGUE_NONE
gActivity.mDialogue.eStatePriority = FDIALOGUE_PRIORITY_IDLE
gActivity.mDialogue.iCounter = 0
gActivity.mDialogue.eDefaultState = FDIALOGUE_NONE
gActivity.mDialogue.eConvChar = NO_CHARACTER
gActivity.mDialogue.eConvPhrase = NO_FRIEND_ACTIVITY_PHRASE
gActivity.mDialogue.eChatChars[0] = NO_CHARACTER
gActivity.mDialogue.eChatChars[1] = NO_CHARACTER
gActivity.mDialogue.eChatChars[2] = NO_CHARACTER
CANCEL_TIMER(gActivity.mDialogue.mGeneralTimer)
RESTART_TIMER_NOW(gActivity.mDialogue.mChatTimer) //CANCEL_TIMER(gActivity.mDialogue.mChatTimer)
CANCEL_TIMER(gActivity.mDialogue.mSuggestTimer)
gActivity.mDialogue.bHasDonePickupIdleChat = FALSE
gActivity.mDialogue.iJourneyChatCounter = 0
gActivity.mAudio.eState = FAUDIO_IDLE
// Initialise activity vars
RESET_EXTENDED_BITS(gActivity.bitsAllowedActivities)
gActivity.iAllowedCount = 0
RESET_EXTENDED_BITS(gActivity.bitsSuggestedActivities)
RESET_EXTENDED_BITS(gActivity.bitsVisitedActivities)
RESET_EXTENDED_BITS(gActivity.bitsVisitedLocations)
gActivity.iVisitedCount = 0
gActivity.bTakeFriendHome = FALSE
gActivity.eDropoffLoc = NO_FRIEND_LOCATION
// gActivity.hDropoffScenarioBlock = NULL
gActivity.bIsDropoffRouteDisplayed = FALSE
gActivity.bIsRural = FALSE
// Initialise rejection data
gActivity.bIsZoneRejectionEnabled = TRUE
gActivity.eRecentRejectionZone = SP_MISSION_NONE
// Squad
// Private_InitHatedRelGroups() // BBUDDIES REMOVED
gActivity.eHotswapStage = SWAP_STATE_Wait
gActivity.bIsAnySwitchAvailable = FALSE
gActivity.iPlayerGroupFollowerCount = 0
ENDPROC
PROC PROCESS_INIT_STATE(enumFriendConnection eFriendConnection)
enumFriend friendID
enumFriendConnectionMode eConnectionMode = GET_CONNECTION_MODE(eFriendConnection)
BOOL bIsAmbientLaunching = FALSE
// BOOL bIsSquadLaunching = FALSE // BBUDDIES REMOVED
// BOOL bIsReplayLaunching = FALSE
IF eConnectionMode = FC_MODE_Ambient
bIsAmbientLaunching = TRUE
ENDIF
// IF eConnectionMode = FC_MODE_Squad // BBUDDIES REMOVED
// bIsSquadLaunching = TRUE
// ENDIF
//
// IF eConnectionMode = FC_MODE_ReplayGroup
// bIsReplayLaunching = TRUE
// ENDIF
//-- If replay system requested clear entities...
IF REPLAY_SYSTEM_HAS_REQUESTED_A_SCRIPT_CLEANUP()
Private_SetActivityFailReason(FAF_PlaybackAbort)
EXIT
//-- If player is dead/arrested...
ELIF NOT IS_PLAYER_PLAYING(PLAYER_ID())
Private_SetActivityFailReason(FAF_PlayerDeathArrest)
EXIT
//-- If connection has been cleared...
ELIF GET_CONNECTION_STATE(eFriendConnection) <> FC_STATE_Init
SCRIPT_ASSERT("Initialise FriendActivity - passed connection not in FC_STATE_Init state, abort")
Private_SetActivityFailReason(FAF_PlayerOnMission)
EXIT
//-- If connection doesn't involve player...
ELIF NOT GET_OTHER_FRIEND_FROM_CONNECTION(eFriendConnection, friendID)
SCRIPT_ASSERT("Initialise FriendActivity - passed connection does not involved current player, abort")
Private_SetActivityFailReason(FAF_PlayerOnMission)
EXIT
// ELIF bIsSquadLaunching OR bIsReplayLaunching // BBUDDIES REMOVED
//
// //-- If player has started non prep mission (and isn't on replay)...
// IF IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_FRIEND_ACTIVITY)
// AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_STORY_PREP)
// AND NOT bIsReplayLaunching
//
// Private_SetActivityFailReason(FAF_PlayerOnMission)
// EXIT
//
// ELSE
//
// //-- Add members --
// enumCharacterList ePlayerChar = GET_CURRENT_PLAYER_PED_ENUM()
// enumCharacterList eFriendChar = GET_CHAR_FROM_FRIEND(friendID)
//
// Private_AddSoldier(gActivity.mSoldiers[ePlayerChar], eConnectionMode)
// Private_AddSoldier(gActivity.mSoldiers[eFriendChar], eConnectionMode)
//
// Private_SetDialogueIdleState(gActivity.mDialogue, FDIALOGUE_SQUAD_IDLE)
// bAddedInitialPeds = TRUE
//
// //-- Update connection state --
// IF NOT ACTIVATE_CONNECTION(eFriendConnection, FC_MODE_Squad)
// SCRIPT_ASSERT("Couldn't activate connection on friend script init")
// Private_SetActivityFailReason(FAF_PlayerOnMission)
// EXIT
// ENDIF
//
// //-- Start squad --
// IF bIsReplayLaunching
// Private_SetActivityState(ACTIVITY_STATE_SquadReboot)
//
// ELIF IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_STORY_PREP)
// Private_SetActivityState(ACTIVITY_STATE_SquadMission)
//
// ELSE
// Private_SetActivityState(ACTIVITY_STATE_SquadRoaming)
// ENDIF
//
// ENDIF
//
ELIF (bIsAmbientLaunching = FALSE) OR Private_SetCurrentlyOnFriendMission(gActivity.iCandidateID)
//-- If player has started other mission...
IF IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_FRIEND_ACTIVITY)
AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_FRIEND_ACTIVITY)
AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_FRIEND_ACTIVITY_WITH_MG)
Private_SetActivityFailReason(FAF_PlayerOnMission)
EXIT
ELSE
//-- Add members --
Private_LoadFriendPickupResources()
enumCharacterList ePlayerChar = GET_CURRENT_PLAYER_PED_ENUM()
enumCharacterList eFriendChar = GET_CHAR_FROM_FRIEND(friendID)
enumFriendLocation ePickupLoc = FriendLoc_GetBestPickupLoc(ePlayerChar, eFriendChar, TRUE)
Private_AddFriend(gActivity.mPlayer, ePlayerChar, NO_FRIEND_LOCATION, -1)
Private_AddFriend(gActivity.mFriendA, eFriendChar, ePickupLoc, 0, bIsAmbientLaunching)
Private_SetDialogueIdleState(gActivity.mDialogue, FDIALOGUE_PICKUP_IDLE)
bAddedInitialPeds = TRUE
//-- Update connection state --
IF NOT ACTIVATE_CONNECTION(eFriendConnection, FC_MODE_Friend)
SCRIPT_ASSERT("Couldn't activate connection on friend script init")
Private_SetActivityFailReason(FAF_PlayerOnMission)
EXIT
ENDIF
// Cancel old queued text messages
Private_CancelCommsBetweenFriends(ePlayerChar, eFriendChar)
//-- Start hangout --
IF bIsAmbientLaunching = FALSE
Private_SetActivityState(ACTIVITY_STATE_Pickup)
ELSE
Private_SetActivityState(ACTIVITY_STATE_Journey)
ENDIF
ENDIF
ENDIF
ENDPROC
// *******************************************************************************************
// MAIN SCRIPT
// *******************************************************************************************
SCRIPT(enumFriendConnection paramFriendConnection)
IF HAS_FORCE_CLEANUP_OCCURRED(FORCE_CLEANUP_FLAG_PLAYER_KILLED_OR_ARRESTED|FORCE_CLEANUP_FLAG_SP_TO_MP|FORCE_CLEANUP_FLAG_MAGDEMO)
CPRINTLN(DEBUG_FRIENDS, "FriendActivity.sc - HAS_FORCE_CLEANUP_OCCURRED()")
IF GET_CAUSE_OF_MOST_RECENT_FORCE_CLEANUP() = FORCE_CLEANUP_FLAG_PLAYER_KILLED_OR_ARRESTED
FriendActivity_Failed(FAF_PlayerDeathArrest)
ELSE
FriendActivity_Failed(FAF_Multiplayer)
ENDIF
FriendActivity_Cleanup()
ENDIF
// Print out requested connection and mode
#IF IS_DEBUG_BUILD
TEXT_LABEL_63 tConn = GetLabel_enumFriendConnection(paramFriendConnection)
TEXT_LABEL_63 tMode = GetLabel_enumFriendConnectionMode(GET_CONNECTION_MODE(paramFriendConnection))
CPRINTLN(DEBUG_FRIENDS, "Initiating friend activity with ", tConn, " (Init mode: ", tMode, ")")
#ENDIF
// Reset all vars
INIT_VARS()
WAIT(0)
#IF IS_DEBUG_BUILD
Create_FriendActivity_Widget()
#ENDIF
WHILE gIsActivityInProgress
WAIT(0)
SWITCH gActivity.mState
CASE ACTIVITY_STATE_Init
PROCESS_INIT_STATE(paramFriendConnection)
IF gActivity.mFailReason <> FAF_NoFail
FriendActivity_Failed(gActivity.mFailReason)
ENDIF
BREAK
CASE ACTIVITY_STATE_Pickup
PROCESS_PICKUP_STATE()
IF gActivity.mFailReason <> FAF_NoFail
FriendActivity_Failed(gActivity.mFailReason)
ENDIF
BREAK
CASE ACTIVITY_STATE_Journey
IF gActivity.bInitState
gActivity.bInitState = FALSE
INIT_JOURNEY_STATE()
ENDIF
PROCESS_JOURNEY_STATE()
IF gActivity.mFailReason <> FAF_NoFail
FriendActivity_Failed(gActivity.mFailReason)
ENDIF
BREAK
CASE ACTIVITY_STATE_Minigame
IF PROCESS_MINIGAME_STATE()
END_MINIGAME_STATE()
ENDIF
BREAK
CASE ACTIVITY_STATE_Cinema
IF PROCESS_CINEMA_STATE()
END_CINEMA_STATE()
ENDIF
BREAK
CASE ACTIVITY_STATE_Bar
IF PROCESS_BAR_STATE()
END_MINIGAME_STATE()
ENDIF
BREAK
// CASE ACTIVITY_STATE_SquadReboot // BBUDDIES REMOVED
// PROCESS_SQUAD_REBOOT_STATE()
//
// IF gActivity.mFailReason <> FAF_NoFail
// FriendActivity_Failed(gActivity.mFailReason)
// ENDIF
// BREAK
//
// CASE ACTIVITY_STATE_SquadRoaming
// PROCESS_SQUAD_ROAMING_STATE()
//
// IF gActivity.mFailReason <> FAF_NoFail
// FriendActivity_Failed(gActivity.mFailReason)
// ENDIF
// BREAK
//
// CASE ACTIVITY_STATE_SquadMission
// IF gActivity.bInitState
// gActivity.bInitState = FALSE
// INIT_SQUAD_MISSION_STATE()
// ENDIF
//
// PROCESS_SQUAD_MISSION_STATE()
//
// IF gActivity.mFailReason <> FAF_NoFail
// FriendActivity_Failed(gActivity.mFailReason)
// ENDIF
// BREAK
CASE ACTIVITY_STATE_Trapped
IF gActivity.bInitState
gActivity.bInitState = FALSE
INIT_TRAPPED_STATE()
ENDIF
PROCESS_TRAPPED_STATE()
IF gActivity.mFailReason <> FAF_NoFail
FriendActivity_Failed(gActivity.mFailReason)
ENDIF
BREAK
CASE ACTIVITY_STATE_Dropoff
IF PROCESS_DROPOFF_STATE(TRUE)
FriendActivity_Passed()
ENDIF
BREAK
CASE ACTIVITY_STATE_DropoffEarly
IF PROCESS_DROPOFF_STATE(FALSE)
FriendActivity_Passed()
ENDIF
BREAK
// CASE ACTIVITY_STATE_DropoffSquad // BBUDDIES REMOVED
// IF PROCESS_DROPOFF_SQUAD_STATE()
// FriendActivity_Passed()
// ENDIF
// BREAK
DEFAULT
CPRINTLN(DEBUG_FRIENDS, "Unknown activity state: \"", GetLabel_enumActivityState(gActivity.mState), "\"")
SCRIPT_ASSERT("Unknown activity state")
BREAK
ENDSWITCH
#IF IS_DEBUG_BUILD
DEBUG_DisplayGeneralInfo()
Watch_FriendActivity_Widget()
FriendActivity_Debug_Options()
#ENDIF
ENDWHILE
FriendActivity_Cleanup()
ENDSCRIPT