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

803 lines
27 KiB
Scheme
Executable File

//- commands headers -//
//- script headers -//
//- public headers -//
USING "locates_public.sch"
USING "shop_public.sch"
USING "friendActivity_public.sch"
//- private headers -//
USING "friendActivity_system_private.sch"
#IF IS_DEBUG_BUILD
//- debug headers -//
#ENDIF
//---------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------
//-- Friend activity - Journey state private functions and data types
// sam.hackett@rockstarleeds.com
//---------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------
//-- Journey - Debug
//---------------------------------------------------------------------------------------------------
#IF IS_DEBUG_BUILD
PROC DEBUG_DisplayJourneyInfo()
DEBUG_DisplayFriendInfo(gActivity.mFriendA, 0)
DEBUG_DisplayFriendInfo(gActivity.mFriendB, 2)
// DEBUG_DisplayGlobalFriendIDs(20)
INT iLine = CONST_iActivityDebugPrintLine
// Print activity locations
enumActivityLocation eLoc
REPEAT MAX_ACTIVITY_LOCATIONS eLoc
STATIC_BLIP_NAME_ENUM activitySprite = g_ActivityLocations[eLoc].sprite
IF IS_BIT_SET(g_GameBlips[activitySprite].iSetting, STATIC_BLIP_SETTING_ACTIVE)
IF DrawFriendLiteralString(GetLabel_enumActivityLocation(eLoc), iLine, HUD_COLOUR_YELLOWLIGHT)
VECTOR vEndPoint = GET_STATIC_BLIP_POSITION(g_ActivityLocations[eLoc].sprite)
DRAW_DEBUG_TEXT(GetLabel_enumActivityLocation(eLoc), vEndPoint, 255, 255, 0, 255)
iLine++
ENDIF
ENDIF
ENDREPEAT
// Print dropoff
IF gActivity.iVisitedCount > 0
IF DrawFriendLiteralString("Dropoff", iLine, HUD_COLOUR_REDLIGHT)
DRAW_DEBUG_TEXT("Dropoff", gActivity.vDropoff, 255, 64, 0, 255)
ENDIF
ENDIF
ENDPROC
#ENDIF
//---------------------------------------------------------------------------------------------------
//-- Journey - Scenario blocking
//---------------------------------------------------------------------------------------------------
//PROC Private_SetDropffScenarioBlocking()
// IF gActivity.eDropoffLoc < MAX_FRIEND_LOCATIONS
// IF gActivity.hDropoffScenarioBlock = NULL
//
// FLOAT fHalfSize = CONST_fScenarioBlockingBoxSize/2.0
// VECTOR vHalfSize = <<fHalfSize, fHalfSize, fHalfSize>>
// VECTOR vLocPos = FriendLoc_GetCoord(gActivity.eDropoffLoc)
//
// VECTOR vMin = vLocPos - vHalfSize
// VECTOR vMax = vLocPos + vHalfSize
//
// gActivity.hDropoffScenarioBlock = ADD_SCENARIO_BLOCKING_AREA(vMin, vMax)
// SET_PED_PATHS_IN_AREA(vMin, vMax, FALSE)
//
// ENDIF
// ENDIF
//ENDPROC
//
//PROC Private_ClearDropoffScenarioBlocking()
// IF gActivity.eDropoffLoc < MAX_FRIEND_LOCATIONS
// IF gActivity.hDropoffScenarioBlock <> NULL
//
// FLOAT fHalfSize = CONST_fScenarioBlockingBoxSize/2.0
// VECTOR vHalfSize = <<fHalfSize, fHalfSize, fHalfSize>>
// VECTOR vLocPos = FriendLoc_GetCoord(gActivity.eDropoffLoc)
//
// VECTOR vMin = vLocPos - vHalfSize
// VECTOR vMax = vLocPos + vHalfSize
//
// SET_PED_PATHS_BACK_TO_ORIGINAL(vMin, vMax)
// REMOVE_SCENARIO_BLOCKING_AREA(gActivity.hDropoffScenarioBlock)
// gActivity.hDropoffScenarioBlock = NULL
//
// ENDIF
// ENDIF
//ENDPROC
//---------------------------------------------------------------------------------------------------
//-- Journey - Main monitors
//---------------------------------------------------------------------------------------------------
FUNC BOOL Journey_IsPlayerAtDropoff()
// Should start stopping for dropoff?
IF gActivity.bStoppingForDropoff = FALSE
IF DOES_BLIP_EXIST(gActivity.hDropoffBlip)
AND gActivity.eDropoffLoc < MAX_FRIEND_LOCATIONS
// Get adjusted dropoff pos for onfoot/incar
VECTOR vDropoffPos = gActivity.vDropoff
IF Private_GetAdjustedDropoffPos(gActivity.eDropoffLoc, vDropoffPos)
SET_BLIP_COORDS(gActivity.hDropoffBlip, vDropoffPos)
ENDIF
// Check if dropoff is triggered
IF CAN_PLAYER_START_CUTSCENE()
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), vDropoffPos, g_vAnyMeansLocate, TRUE)
gActivity.bStoppingForDropoff = TRUE
ENDIF
ELSE
IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), vDropoffPos, g_vOnFootLocate, TRUE)
gActivity.bStoppingForDropoff = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
// If finished stopping for dropoff...
IF gActivity.bStoppingForDropoff
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
OR BRING_VEHICLE_TO_HALT_AND_DISABLE_VEH_CONTROLS(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), 10.0, 8)
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL Journey_TryStartBarActivity()
// Should start stopping for bar?
IF gActivity.eStoppingForBarLoc = NO_ACTIVITY_LOCATION
IF CAN_PLAYER_START_CUTSCENE()
// For each enabled location...
enumActivityLocation eLoc
REPEAT MAX_ACTIVITY_LOCATIONS eLoc
IF g_ActivityLocations[eLoc].type = ATYPE_bar
IF NOT IS_EXTENDED_BIT_SET(gActivity.bitsVisitedLocations, ENUM_TO_INT(eLoc))
IF canStartActivity(eLoc)
// If in area and cutscene can start
IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), GET_STATIC_BLIP_POSITION(g_ActivityLocations[eLoc].sprite), g_vAnyMeansLocate, TRUE, TRUE, TM_ANY)//TM_ON_FOOT)
gActivity.eStoppingForBarLoc = eLoc
ENDIF
ENDIF
ENDIF
ENDIF
ENDREPEAT
ENDIF
ENDIF
// If finished stopping for bar...
IF gActivity.eStoppingForBarLoc != NO_ACTIVITY_LOCATION
IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
OR BRING_VEHICLE_TO_HALT_AND_DISABLE_VEH_CONTROLS(GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID()), 5.0, 8)
startActivity(gActivity.eStoppingForBarLoc)
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
//---------------------------------------------------------------------------------------------------
//-- Journey - Main
//---------------------------------------------------------------------------------------------------
FUNC enumActivityType Journey_GetRandomActivityType(structBits64 bitsAllowedActivities, INT iAllowedCount)
// Randomly choose one of the available types
IF iAllowedCount > 0
INT iNthAvailableType = GET_RANDOM_INT_IN_RANGE(0, iAllowedCount)
INT iType
REPEAT MAX_ACTIVITY_TYPES iType
IF IS_EXTENDED_BIT_SET(bitsAllowedActivities, iType)
IF iNthAvailableType > 0
iNthAvailableType--
ELSE
RETURN INT_TO_ENUM(enumActivityType, iType)
ENDIF
ENDIF
ENDREPEAT
ENDIF
RETURN NO_ACTIVITY_TYPE
ENDFUNC
PROC INIT_JOURNEY_STATE()
CPRINTLN(DEBUG_FRIENDS, "INIT_JOURNEY_STATE()")
// Reset vars
gActivity.eNearestActivityLoc = NO_ACTIVITY_LOCATION
gActivity.bMovedCarForMinigame = FALSE
Private_ReleaseFriendPickupResources()
// Backup blips if haven't already
IF gActivity.bRestoreLocationBlips = FALSE
Private_BackupLocationBlips()
gActivity.bRestoreLocationBlips = TRUE
ENDIF
Private_ClearChatResumption(gActivity.mDialogue)
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.eStoppingForBarLoc = NO_ACTIVITY_LOCATION
gActivity.bStoppingForDropoff = FALSE
// Enable zone rejection
Private_SetZoneRejection(TRUE)
// Allow debug drawing
#IF IS_DEBUG_BUILD
SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(TRUE)
#ENDIF
// Reset tennis launcher (it may have shut itself down before friend activity started)
RESET_MINI_GAME_TENNIS_LAUNCHERS()
// Lock strip club for Amanda/Jimmy
IF (gActivity.mFriendA.eChar = CHAR_AMANDA OR gActivity.mFriendB.eChar = CHAR_AMANDA)
IF GET_MISSION_FLOW_BITSET_BIT_STATE(FLOWBITSET_MINIGAME_ACTIVE, ENUM_TO_INT(MINIGAME_STRIPCLUB)) = TRUE
SET_MISSION_FLOW_BITSET_BIT_STATE(FLOWBITSET_MINIGAME_ACTIVE, ENUM_TO_INT(MINIGAME_STRIPCLUB), FALSE)
gActivity.bRestoreStripClub = TRUE
ENDIF
ELIF (gActivity.mFriendA.eChar = CHAR_JIMMY OR gActivity.mFriendB.eChar = CHAR_JIMMY)
IF (gActivity.mFriendA.eChar = CHAR_MICHAEL OR gActivity.mFriendB.eChar = CHAR_MICHAEL OR gActivity.mPlayer.eChar = CHAR_MICHAEL)
OR (gActivity.mFriendA.eChar = CHAR_TREVOR OR gActivity.mFriendB.eChar = CHAR_TREVOR OR gActivity.mPlayer.eChar = CHAR_TREVOR)
IF GET_MISSION_FLOW_BITSET_BIT_STATE(FLOWBITSET_MINIGAME_ACTIVE, ENUM_TO_INT(MINIGAME_STRIPCLUB)) = TRUE
SET_MISSION_FLOW_BITSET_BIT_STATE(FLOWBITSET_MINIGAME_ACTIVE, ENUM_TO_INT(MINIGAME_STRIPCLUB), FALSE)
gActivity.bRestoreStripClub = TRUE
ENDIF
ENDIF
ENDIF
// Setup dropoff point
IF gActivity.iVisitedCount = 0
gActivity.eDropoffLoc = NO_FRIEND_LOCATION
gActivity.vDropoff = <<0.0, 0.0, 0.0>>
ELSE
gActivity.eDropoffLoc = FriendLoc_GetBestDropoffLoc(gActivity.mPlayer.eChar, gActivity.mFriendA.eChar, TRUE)
gActivity.vDropoff = FriendLoc_GetCoord(gActivity.eDropoffLoc)
ENDIF
// Calc if drunk
// BOOL bIsDrunk = FALSE
// IF (g_ePreviousActivityLoc < MAX_ACTIVITY_LOCATIONS AND g_ActivityLocations[g_ePreviousActivityLoc].type = ATYPE_bar)
// OR (NOT IS_PED_INJURED(PLAYER_PED_ID()) AND Is_Ped_Drunk(PLAYER_PED_ID()))
// bIsDrunk = TRUE
// ENDIF
// Set default dialogue state
Private_SetDialogueIdleState(gActivity.mDialogue, FDIALOGUE_JOURNEY_IDLE)
// Start dialogue
IF NOT gActivity.bResumeFriendsAfterSquad
IF gActivity.iVisitedCount > 0
IF g_ActivityLocations[g_ePreviousActivityLoc].type = ATYPE_bar//bIsDrunk
Private_SetDialogueState(gActivity.mDialogue, FDIALOGUE_DRUNK)
ELSE
Private_SetDialogueState(gActivity.mDialogue, FDIALOGUE_RESULT)
ENDIF
ENDIF
ELSE
Private_EndDialogueState(gActivity.mDialogue)
gActivity.bResumeFriendsAfterSquad = FALSE
ENDIF
ENDPROC
PROC PROCESS_JOURNEY_STATE()
Private_ClearActivityFailReason()
//-- If replay (as in playback) system requested clear entities...
IF REPLAY_SYSTEM_HAS_REQUESTED_A_SCRIPT_CLEANUP()
Private_ClearObjective()
Private_SetActivityFailReason(FAF_PlaybackAbort)
EXIT
//-- Check if replay (as in retry failed mission) has been initiated
ELIF IS_REPLAY_BEING_PROCESSED()
Private_ClearObjective()
IF GET_MISSION_FLOW_SAFE_TO_CLEANUP()
Private_SetActivityFailReason(FAF_RetryAbort)
ENDIF
//-- Check if player is dead
ELIF NOT IS_PLAYER_PLAYING(PLAYER_ID())
Private_ClearObjective()
// Private_ClearDropoffScenarioBlocking()
Private_SetActivityFailReason(FAF_PlayerDeathArrest)
//-- If player has started prep mission...
ELIF IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_STORY_PREP) // BBUDDIES REPLACED
IF IS_NEW_LOAD_SCENE_ACTIVE()
NEW_LOAD_SCENE_STOP()
ENDIF
Private_ClearObjective()
// Private_ClearDropoffScenarioBlocking()
Private_SetDialogueState(gActivity.mDialogue, FDIALOGUE_SQUAD)
Private_SetDialogueIdleState(gActivity.mDialogue, FDIALOGUE_SQUAD_IDLE)
gActivity.eLogFailCharA = NO_CHARACTER
gActivity.eLogFailCharB = NO_CHARACTER
Private_RejectMembersForMission(FALSE, FAP_REJECTION_OK, TRUE)
Private_SetActivityState(ACTIVITY_STATE_Trapped)
// //-- If player has started prep mission...
// ELIF IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_STORY_PREP) // BBUDDIES REMOVED
//
// IF IS_NEW_LOAD_SCENE_ACTIVE()
// NEW_LOAD_SCENE_STOP()
// ENDIF
//
// Private_ClearObjective()
//// Private_ClearDropoffScenarioBlocking()
//
// SET_SQUAD_MISSION_TO_CURRENT_ZONE()
// Private_TransferMembersToSquad()
// Private_SetActivityState(ACTIVITY_STATE_SquadMission)
// //-- If player has called soldiers...
// ELIF ARE_ANY_SQUAD_CONNECTIONS_PENDING_OR_ACTIVE() // BBUDDIES REMOVED
//
// Private_ClearObjective()
//// Private_ClearDropoffScenarioBlocking()
//
// Private_TransferMembersToSquad()
// Private_SetActivityState(ACTIVITY_STATE_SquadRoaming)
//-- If knockout scene has started...
ELIF IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_GRIEFING)
Private_ClearObjective()
// Private_ClearDropoffScenarioBlocking()
Private_DeleteMembersForGriefing()
Private_SetActivityFailReason(FAF_PlayerOnMission)
//-- If player has started story mission...
ELIF 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_ClearObjective()
// Private_ClearDropoffScenarioBlocking()
Private_RejectMembersForMission(FALSE)
Private_SetActivityFailReason(FAF_PlayerOnMission)
//-- Check if minigame has started
ELIF g_eCurrentActivityLoc <> NO_ACTIVITY_LOCATION
IF IS_NEW_LOAD_SCENE_ACTIVE()
NEW_LOAD_SCENE_STOP()
ENDIF
IF g_eCurrentActivityLoc < MAX_ACTIVITY_LOCATIONS
enumActivityType eActivityType = g_ActivityLocations[g_eCurrentActivityLoc].type
IF eActivityType = ATYPE_bar
OR eActivityType = ATYPE_golf
OR eActivityType = ATYPE_stripclub
OR eActivityType = ATYPE_suspend
STOP_SCRIPTED_CONVERSATION(TRUE)
ELSE
STOP_SCRIPTED_CONVERSATION(FALSE)
ENDIF
ELSE
STOP_SCRIPTED_CONVERSATION(FALSE)
ENDIF
Private_ClearObjective()
// Private_ClearDropoffScenarioBlocking()
Private_SetActivityState(ACTIVITY_STATE_Minigame)
//-- Check if bar has started
ELIF Journey_TryStartBarActivity()
IF IS_NEW_LOAD_SCENE_ACTIVE()
NEW_LOAD_SCENE_STOP()
ENDIF
STOP_SCRIPTED_CONVERSATION(TRUE)
Private_ClearObjective()
// Private_ClearDropoffScenarioBlocking()
Private_SetActivityState(ACTIVITY_STATE_Bar)
//-- Check if player is at dropoff
ELIF Journey_IsPlayerAtDropoff()
IF IS_NEW_LOAD_SCENE_ACTIVE()
NEW_LOAD_SCENE_STOP()
ENDIF
STOP_SCRIPTED_CONVERSATION(TRUE)
Private_ClearObjective()
// Private_SetDropffScenarioBlocking()
Private_SetActivityState(ACTIVITY_STATE_Dropoff)
EXIT
//-- Waiting to get mission flag...
ELIF NOT Private_SetCurrentlyOnFriendMission(gActivity.iCandidateID)
DISABLE_SELECTOR_THIS_FRAME()
EXIT
ELIF Private_RequestFriendText()
//-- Process activity members
BOOL bAddedAmbFriend = Private_ProcessAddFriends(TRUE)
Private_ProcessMembers()
Private_ProcessRemoveMembers()
Private_ProcessSystem()
// Private_SetDropffScenarioBlocking()
#IF IS_DEBUG_BUILD
DEBUG_DisplayJourneyInfo()
#ENDIF
// Make player get directly into correct seat, so friends aren't waiting for him to shuffle
IF NOT IS_PED_INJURED(PLAYER_PED_ID())
SET_PED_RESET_FLAG(PLAYER_PED_ID(), PRF_ForcePlayerToEnterVehicleThroughDirectDoorOnly, TRUE)
ENDIF
IF g_sVehicleGenNSData.bInGarage = TRUE
// Release player vehicle on entering a garage
IF gActivity.hPlayerVehicle <> NULL
IF DOES_ENTITY_EXIST(gActivity.hPlayerVehicle)
IF DOES_ENTITY_BELONG_TO_THIS_SCRIPT(gActivity.hPlayerVehicle, FALSE)
CPRINTLN(DEBUG_FRIENDS, "<*<*<*<*<*<*<*<*<*FRIEND CAR RELEASED*>*>*>*>*>*>*>*> - (for garage)")
SET_VEHICLE_AS_NO_LONGER_NEEDED(gActivity.hPlayerVehicle)
ENDIF
gActivity.hPlayerVehicle = NULL
ENDIF
ENDIF
ELSE
// Update last vehicle player used while in journey state
IF IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID())
VEHICLE_INDEX hCurrentVehicle = GET_VEHICLE_PED_IS_IN(PLAYER_PED_ID())
IF gActivity.hPlayerVehicle <> hCurrentVehicle
CPRINTLN(DEBUG_FRIENDS, "(*(*(*(*(*(*(*(*(*FRIEND CAR CHANGED*)*)*)*)*)*)*)*)")
IF DOES_ENTITY_EXIST(gActivity.hPlayerVehicle)
IF DOES_ENTITY_BELONG_TO_THIS_SCRIPT(gActivity.hPlayerVehicle, FALSE)
SET_VEHICLE_AS_NO_LONGER_NEEDED(gActivity.hPlayerVehicle)
ENDIF
gActivity.hPlayerVehicle = NULL
ENDIF
// Store new vehicle
gActivity.hPlayerVehicle = hCurrentVehicle
// If vehicle is owned by one of the friends, set that as thier vehicle
IF gActivity.mFriendA.eState != FRIEND_NULL
IF IS_VEHICLE_A_PLAYER_PERSONAL_VEHICLE(hCurrentVehicle, gActivity.mFriendA.eChar)
CPRINTLN(DEBUG_FRIENDS, "Car is owned by friend A, setting as his car")
gActivity.mFriendA.hCar = hCurrentVehicle
ENDIF
ENDIF
IF gActivity.mFriendB.eState != FRIEND_NULL
IF IS_VEHICLE_A_PLAYER_PERSONAL_VEHICLE(hCurrentVehicle, gActivity.mFriendB.eChar)
CPRINTLN(DEBUG_FRIENDS, "Car is owned by friend B, setting as his car")
gActivity.mFriendB.hCar = hCurrentVehicle
ENDIF
ENDIF
ENDIF
ENDIF
// Always try to own players journey vehicle
IF DOES_ENTITY_EXIST(gActivity.hPlayerVehicle)
IF NOT DOES_ENTITY_BELONG_TO_THIS_SCRIPT(gActivity.hPlayerVehicle, FALSE)
CPRINTLN(DEBUG_FRIENDS, "(*(*(*(*(*(*(*(*(*FRIEND CAR GRABBED*)*)*)*)*)*)*)*)")
SET_ENTITY_AS_MISSION_ENTITY(gActivity.hPlayerVehicle, TRUE, TRUE)
ENDIF
ENDIF
ENDIF
// Change follow dist based on if player is normal/in interior/in fight
Private_UpdateFriendGroupSpacing()
// If visited club, close it when possible
IF gActivity.bRestoreStripClub = FALSE
IF IS_EXTENDED_BIT_SET(gActivity.bitsVisitedLocations, ENUM_TO_INT(ALOC_stripclub_southCentral))
IF Util_IsPedOutsideRange(PLAYER_PED_ID(), GET_STATIC_BLIP_POSITION(STATIC_BLIP_MINIGAME_STRIPCLUB), 200.0)//300.0)
IF (IS_PED_INJURED(gActivity.mFriendA.hPed) OR GET_INTERIOR_FROM_ENTITY(gActivity.mFriendA.hPed) = NULL)
AND (IS_PED_INJURED(gActivity.mFriendB.hPed) OR GET_INTERIOR_FROM_ENTITY(gActivity.mFriendB.hPed) = NULL)
CPRINTLN(DEBUG_FRIENDS, "Lock strip club - has been visited, is far enough away to lock it, and no alive friends are stuck inside")
SET_MISSION_FLOW_BITSET_BIT_STATE(FLOWBITSET_MINIGAME_ACTIVE, ENUM_TO_INT(MINIGAME_STRIPCLUB), FALSE)
gActivity.bRestoreStripClub = TRUE
ENDIF
ENDIF
ENDIF
ENDIF
// Stream Load
// enumActivityLocation eDesiredLoc = NO_ACTIVITY_LOCATION
// vector vLoadPos = <<0, 0, 0>>
//
// IF (gActivity.eNearestActivityLoc < MAX_ACTIVITY_LOCATIONS)
// eDesiredLoc = gActivity.eNearestActivityLoc
// vLoadPos = GET_STATIC_BLIP_POSITION(g_ActivityLocations[gActivity.eNearestActivityLoc].sprite)
// ENDIF
//
// IF gActivity.eDropoffLoc <> NO_FRIEND_LOCATION
// FLOAT dropoffDistSq
// FLOAT activityDistSq
//
// dropoffDistSq = VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), gActivity.vDropoff)
// activityDistSq = VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), vLoadPos)
//
// IF (dropoffDistSq < activityDistSq) OR (eDesiredLoc >= MAX_ACTIVITY_LOCATIONS)
// eDesiredLoc = ALOC_suspendFriends
// vLoadPos = gActivity.vDropoff
// ENDIF
// ENDIF
//
// IF gActivity.eLoadingActivityLoc <> eDesiredLoc
// IF (eDesiredLoc < MAX_ACTIVITY_LOCATIONS)
// IF IS_NEW_LOAD_SCENE_ACTIVE()
// NEW_LOAD_SCENE_STOP()
// ENDIF
//
// IF NEW_LOAD_SCENE_START_SPHERE(vLoadPos, 20.0)//, NEWLOADSCENE_FLAG_REQUIRE_COLLISION)
// gActivity.eLoadingActivityLoc = eDesiredLoc
//
// IF eDesiredLoc = ALOC_suspendFriends
// CPRINTLN(DEBUG_FRIENDS, "Started New Load Scene - Drop Off Position:", vLoadPos, " Dist:", GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), vLoadPos))
// ELSE
// CPRINTLN(DEBUG_FRIENDS, "Started New Load Scene - Activity:", GetLabel_enumActivityLocation(gActivity.eLoadingActivityLoc), " Position:", vLoadPos, " Dist:", GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), vLoadPos))
// ENDIF
// ENDIF
// ENDIF
// ENDIF
//-- Update objective
IF NOT Private_AreAnyMembersValid() // Are friends failed
Private_ClearObjective()
IF Private_AreAllMembersRemoved()
Private_SetActivityFailReason(FAF_MemberFail)
ENDIF
ELIF (gActivity.mFriendA.eState = FRIEND_LOST OR gActivity.mFriendA.eState = FRIEND_FAIL_LOST OR gActivity.mFriendA.eState = FRIEND_PLUMMET) // Are any friends lost
OR (gActivity.mFriendB.eState = FRIEND_LOST OR gActivity.mFriendB.eState = FRIEND_FAIL_LOST OR gActivity.mFriendB.eState = FRIEND_PLUMMET)
Private_DisplayObjective_Lost()
// STOP_SCRIPTED_CONVERSATION(FALSE)
ELSE // Visiting activities
// Keep objective up to date
Private_DisplayObjective_Activities(bAddedAmbFriend)
ENDIF
// // If calling -> do answerphone
// IF IS_CALLING_CONTACT(gActivity.buddyChar)
// PRIVATE_Friend_DoAnswerPhone(gActivity.convPedsVoicemail, gActivity.buddyChar)
// ENDIF
ENDIF
ENDPROC
FUNC BOOL PROCESS_MINIGAME_STATE()
// Is minigame running...
IF (g_eCurrentActivityLoc <> NO_ACTIVITY_LOCATION)
#IF IS_DEBUG_BUILD
DrawFriendLiteralString(GetLabel_enumActivityLocation(g_eCurrentActivityLoc), CONST_iActivityDebugPrintLineTop, HUD_COLOUR_BLUE)
#ENDIF
IF NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_FRIEND_ACTIVITY_WITH_MG)
g_OnMissionState = MISSION_TYPE_FRIEND_ACTIVITY_WITH_MG
ENDIF
// Pause chat timer
IF IS_TIMER_STARTED(gActivity.mDialogue.mChatTimer) AND NOT IS_TIMER_PAUSED(gActivity.mDialogue.mChatTimer)
PAUSE_TIMER(gActivity.mDialogue.mChatTimer)
ENDIF
// Strip club tries to respot car during minigame
IF gActivity.bMovedCarForMinigame = FALSE
IF g_eCurrentActivityLoc = ALOC_stripclub_southCentral
OR g_eCurrentActivityLoc = ALOC_golf_countryClub
OR g_eCurrentActivityLoc = ALOC_tennis_beachCourt
OR g_eCurrentActivityLoc = ALOC_tennis_chumashHotel
OR g_eCurrentActivityLoc = ALOC_tennis_LSUCourt1
OR g_eCurrentActivityLoc = ALOC_tennis_michaelHouse
OR g_eCurrentActivityLoc = ALOC_tennis_richmanHotel1
OR g_eCurrentActivityLoc = ALOC_tennis_vespucciHotel
OR g_eCurrentActivityLoc = ALOC_tennis_vinewoodhotel1
OR g_eCurrentActivityLoc = ALOC_tennis_weazelCourt1
IF Private_RespotVehicleForActivity(gActivity.hPlayerVehicle, g_eCurrentActivityLoc, TRUE, TRUE)
gActivity.bMovedCarForMinigame = TRUE
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDIF
RETURN TRUE
ENDFUNC
PROC END_MINIGAME_STATE()
// Change the mission state back to friend activity.
g_OnMissionState = MISSION_TYPE_FRIEND_ACTIVITY
// Unpause chat timer
IF IS_TIMER_STARTED(gActivity.mDialogue.mChatTimer) AND IS_TIMER_PAUSED(gActivity.mDialogue.mChatTimer)
UNPAUSE_TIMER(gActivity.mDialogue.mChatTimer)
ENDIF
// Reset suggestion timer
RESTART_TIMER_NOW(gActivity.mDialogue.mSuggestTimer)
// Clear dialogue state
Private_EndDialogueState(gActivity.mDialogue)
// If was just suspended -> Set to journey state
IF g_ePreviousActivityLoc = ALOC_suspendFriends
Private_EndDialogueState(gActivity.mDialogue)
Private_SetDialogueState(gActivity.mDialogue, FDIALOGUE_JOURNEY_IDLE)
Private_SetActivityState(ACTIVITY_STATE_Journey)
ELSE
// Add to list of visited locations
SET_EXTENDED_BIT(gActivity.bitsVisitedActivities, ENUM_TO_INT(g_ActivityLocations[g_ePreviousActivityLoc].type))
SET_EXTENDED_BIT(gActivity.bitsVisitedLocations, ENUM_TO_INT(g_ePreviousActivityLoc))
gActivity.iVisitedCount++
IF gActivity.iVisitedCount >= CONST_iMaxVisitedLocations
AND g_ePreviousActivityLoc <> ALOC_stripclub_southCentral
gActivity.bTakeFriendHome = TRUE
ENDIF
// Update like stat
IF g_ePreviousActivityResult = AR_playerWon
OR g_ePreviousActivityResult = AR_playerDraw
OR g_ePreviousActivityResult = AR_buddyA_won
OR g_ePreviousActivityResult = AR_buddyB_won
// Don't allow like stats to increase forever (in case player is going/in out of strip club continually)
IF gActivity.iVisitedCount < CONST_iMaxVisitedLocations
// Apply like value
IF gActivity.mFriendA.eState <> FRIEND_NULL
UPDATE_FRIEND_LIKE(gActivity.mPlayer.eChar, gActivity.mFriendA.eChar, FriendLike_DID_UNSUGGESTED_ACTIVITY)
ENDIF
IF gActivity.mFriendB.eState <> FRIEND_NULL
UPDATE_FRIEND_LIKE(gActivity.mPlayer.eChar, gActivity.mFriendB.eChar, FriendLike_DID_UNSUGGESTED_ACTIVITY)
ENDIF
ENDIF
ENDIF
// Update 100% stat
SWITCH g_ActivityLocations[g_ePreviousActivityLoc].type
CASE ATYPE_bar REGISTER_SCRIPT_IN_COMPLETION_PERCENTAGE_TOTAL(CP_FR_BAR) BREAK
CASE ATYPE_cinema REGISTER_SCRIPT_IN_COMPLETION_PERCENTAGE_TOTAL(CP_FR_CIN) BREAK
CASE ATYPE_darts REGISTER_SCRIPT_IN_COMPLETION_PERCENTAGE_TOTAL(CP_FR_DAR) BREAK
CASE ATYPE_golf REGISTER_SCRIPT_IN_COMPLETION_PERCENTAGE_TOTAL(CP_FR_GOL) BREAK
CASE ATYPE_stripclub REGISTER_SCRIPT_IN_COMPLETION_PERCENTAGE_TOTAL(CP_FR_STR) BREAK
CASE ATYPE_tennis REGISTER_SCRIPT_IN_COMPLETION_PERCENTAGE_TOTAL(CP_FR_TEN) BREAK
ENDSWITCH
// Respot car (unless strip club, which tries to respot during minigame - or bar which respots at start of scene)
IF g_ePreviousActivityLoc < MAX_ACTIVITY_LOCATIONS
AND g_ActivityLocations[g_ePreviousActivityLoc].type <> ATYPE_stripclub
AND g_ActivityLocations[g_ePreviousActivityLoc].type <> ATYPE_golf
AND g_ActivityLocations[g_ePreviousActivityLoc].type <> ATYPE_bar
AND g_ActivityLocations[g_ePreviousActivityLoc].type <> ATYPE_tennis
Private_RespotVehicleForActivity(gActivity.hPlayerVehicle, g_ePreviousActivityLoc)
ENDIF
// Set ending positions
IF g_ePreviousActivityLoc < MAX_ACTIVITY_LOCATIONS
AND g_ActivityLocations[g_ePreviousActivityLoc].type = ATYPE_cinema
//-- Early dropoff --
IF GET_RANDOM_INT_IN_RANGE(0, 100) < 10
CPRINTLN(DEBUG_FRIENDS, "Activity done - Trigger early ending")
Private_SetActivityState(ACTIVITY_STATE_DropoffEarly)
ELSE
Private_SetActivityState(ACTIVITY_STATE_Cinema)
ENDIF
ELSE
// Wait a short time then fade in (obsolete, cinema handles this itself now, nothing else needs it)
// SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
// WAIT(DEFAULT_FADE_TIME)
// SET_PLAYER_CONTROL(PLAYER_ID(), TRUE)
// DO_SCREEN_FADE_IN(DEFAULT_FADE_TIME_LONG)
// Have any been attacked
IF g_ePreviousActivityResult = AR_buddyA_attacked
Private_SetFriendAttacked(gActivity.mFriendA)
Private_SetFriendWander(gActivity.mFriendB)
ELIF g_ePreviousActivityResult = AR_buddyB_attacked
Private_SetFriendAttacked(gActivity.mFriendB)
Private_SetFriendWander(gActivity.mFriendA)
ELIF g_ePreviousActivityResult = AR_buddyAll_attacked
Private_SetFriendAttacked(gActivity.mFriendA)
Private_SetFriendAttacked(gActivity.mFriendB)
// Display ped blips when coming out of strip club
ELIF g_ePreviousActivityLoc = ALOC_stripclub_southCentral
Private_UpdateFriendPedBlip(gActivity.mFriendA, TRUE)
Private_UpdateFriendPedBlip(gActivity.mFriendB, TRUE)
ENDIF
// Re-init all the ped attribs (and clear damage flags)
Private_SetFriendAttribs(gActivity.mPlayer, gActivity.convPedsDefault, TRUE)
Private_SetFriendAttribs(gActivity.mFriendA, gActivity.convPedsDefault)
Private_SetFriendAttribs(gActivity.mFriendB, gActivity.convPedsDefault)
//-- Return to journey state --
Private_SetActivityState(ACTIVITY_STATE_Journey)
ENDIF
ENDIF
ENDPROC