1301 lines
51 KiB
Python
Executable File
1301 lines
51 KiB
Python
Executable File
|
|
|
|
//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 "commands_script.sch"
|
|
USING "script_clock.sch"
|
|
USING "script_player.sch"
|
|
USING "randomChar_private.sch"
|
|
USING "blip_control_public.sch"
|
|
USING "flow_public_core.sch"
|
|
USING "RC_Setup_public.sch"
|
|
|
|
// *****************************************************************************************
|
|
// *****************************************************************************************
|
|
// *****************************************************************************************
|
|
//
|
|
// MISSION NAME : RandomChar_Controller.sc
|
|
// AUTHOR : Keith
|
|
// MAINTAINED : Andrew Minghella
|
|
// DESCRIPTION : The Random Character Controller - ensures Random Characters
|
|
// are allowed to activate at appropriate times.
|
|
//
|
|
// *****************************************************************************************
|
|
// *****************************************************************************************
|
|
// *****************************************************************************************
|
|
|
|
CONST_INT MAX_FRAMES_TO_PROCESS_MISSIONS 60
|
|
CONST_INT MAX_RC_BLIPS 20
|
|
|
|
INT iCurrentMissionFrame
|
|
INT iRCMission, iBit, iBitset
|
|
BOOL bRCBlipActive[MAX_RC_BLIPS]
|
|
STATIC_BLIP_NAME_ENUM eRCBlips[MAX_RC_BLIPS]
|
|
BOOL bRCBlipsTurnedOff
|
|
TIMEOFDAY eTonya1HelpTime = INVALID_TIMEOFDAY
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
g_eRC_MissionIDs eRCMissionToDebug = NO_RC_MISSION // Set this to print debug info for a particular RC mission only
|
|
#ENDIF
|
|
|
|
// -----------------------DEBUG FUNCTIONS ---------------------------------------------
|
|
#IF IS_DEBUG_BUILD
|
|
BOOL bOutputStates, bCompleteAll, bUnlockSpecificRC
|
|
|
|
/// PURPOSE:
|
|
/// Prints specified debug string if the RC mission being processed is the one specifed in eRCMissionToDebug
|
|
/// PARAMS:
|
|
/// eRCMission - the rc mission being processed
|
|
/// sDebugString - the string to print
|
|
PROC RC_CONTROLLER_DEBUG_PRINT(g_eRC_MissionIDs eRCMission, STRING sDebugString)
|
|
IF eRCMissionToDebug <> NO_RC_MISSION
|
|
AND eRCMission = eRCMissionToDebug
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, sDebugString)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Creates RC Controller debug widgets
|
|
PROC Setup_RC_Debug_Widgets()
|
|
START_WIDGET_GROUP("Random Character Controller")
|
|
ADD_WIDGET_BOOL("Output states", bOutputStates)
|
|
ADD_WIDGET_BOOL("Complete All", bCompleteAll)
|
|
ADD_WIDGET_BOOL("Unlock Barry 4", bUnlockSpecificRC)
|
|
STOP_WIDGET_GROUP()
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Maintains the RC Controller debug widgets
|
|
PROC Maintain_RC_Debug_Widgets()
|
|
IF bOutputStates
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "Random Character States")
|
|
INT iMission
|
|
g_eRC_MissionIDs eRCMission
|
|
g_structRCMissionsStatic sRCMissionDetails
|
|
TEXT_LABEL_23 tlMissionName
|
|
|
|
REPEAT MAX_RC_MISSIONS iMission
|
|
eRCMission = INT_TO_ENUM(g_eRC_MissionIDs, iMission)
|
|
Retrieve_Random_Character_Static_Mission_Details(eRCMission, sRCMissionDetails)
|
|
|
|
tlMissionName = "'"
|
|
tlMissionName += sRCMissionDetails.rcScriptName
|
|
tlMissionName += "':"
|
|
WHILE GET_LENGTH_OF_LITERAL_STRING(tlMissionName) < 20
|
|
tlMissionName+=" "
|
|
ENDWHILE
|
|
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "RC Mission ", tlMissionName, ": ",
|
|
PICK_STRING(IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcFlags, ENUM_TO_INT(RC_FLAG_ACTIVATED)), "[Activated]", "[---------]"),
|
|
PICK_STRING(IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcFlags, ENUM_TO_INT(RC_FLAG_READY_TO_PLAY)), "[Ready To Play]", "[-------------]"),
|
|
PICK_STRING(IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED)), "[Completed]", "[---------]"),
|
|
PICK_STRING(IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcFlags, ENUM_TO_INT(RC_FLAG_ACTIVATED_IN_FLOW)),"[Available In Flow]", "[-----------------]"))
|
|
ENDREPEAT
|
|
bOutputStates = FALSE
|
|
|
|
ENDIF
|
|
|
|
IF bCompleteAll = TRUE
|
|
// debug for completing all RCs
|
|
// Can skip flow to after all story missions and use this too
|
|
// so all repeatable missions are available
|
|
INT iMission
|
|
FOR iMission = 0 TO ENUM_TO_INT(MAX_RC_MISSIONS)-1
|
|
Activate_RC_Mission(INT_TO_ENUM(g_eRC_MissionIDs, iMission), TRUE)
|
|
ENDFOR
|
|
|
|
bCompleteAll = FALSE
|
|
ENDIF
|
|
|
|
IF bUnlockSpecificRC = TRUE
|
|
// sets certain RCs as complete so we can force one to unloc
|
|
Activate_RC_Mission(RC_BARRY_1, TRUE)
|
|
Activate_RC_Mission(RC_BARRY_2, TRUE)
|
|
Activate_RC_Mission(RC_BARRY_3, TRUE)
|
|
Activate_RC_Mission(RC_BARRY_3A, TRUE)
|
|
Activate_RC_Mission(RC_BARRY_3C, TRUE)
|
|
Execute_Code_ID(CID_BARRY4_TEXT_RECEIVED)
|
|
bUnlockSpecificRC = FALSE
|
|
ENDIF
|
|
ENDPROC
|
|
#ENDIF
|
|
|
|
// -------------------FUNCTIONS---------------------------------------------------------
|
|
|
|
/// PURPOSE: Determines if the controller is allowed to run
|
|
FUNC BOOL Is_Controller_Safe_To_Run()
|
|
|
|
// Debug suspend checks
|
|
#IF IS_DEBUG_BUILD
|
|
|
|
IF NOT g_savedGlobals.sFlow.isGameflowActive
|
|
AND NOT g_bRandomCharsAvailableInDebug
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF g_flowUnsaved.bUpdatingGameflow
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
IF g_disable_for_smoketest
|
|
RETURN FALSE
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
// No issues found so assume it is safe to run
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
// ===========================================================================================================
|
|
// Initialise
|
|
// ===========================================================================================================
|
|
|
|
/// PURPOSE:
|
|
/// Intialises the default Random Character mission blip states
|
|
PROC Initialise_Random_Character_Mission_Blips()
|
|
|
|
// A pool of blips have been setup for all RC missions.
|
|
// When an RC mission requires a blip, it must request one from the pool.
|
|
eRCBlips[0] = STATIC_BLIP_RANDOMCHAR_00
|
|
eRCBlips[1] = STATIC_BLIP_RANDOMCHAR_01
|
|
eRCBlips[2] = STATIC_BLIP_RANDOMCHAR_02
|
|
eRCBlips[3] = STATIC_BLIP_RANDOMCHAR_03
|
|
eRCBlips[4] = STATIC_BLIP_RANDOMCHAR_04
|
|
eRCBlips[5] = STATIC_BLIP_RANDOMCHAR_05
|
|
eRCBlips[6] = STATIC_BLIP_RANDOMCHAR_06
|
|
eRCBlips[7] = STATIC_BLIP_RANDOMCHAR_07
|
|
eRCBlips[8] = STATIC_BLIP_RANDOMCHAR_08
|
|
eRCBlips[9] = STATIC_BLIP_RANDOMCHAR_09
|
|
eRCBlips[10] = STATIC_BLIP_RANDOMCHAR_10
|
|
eRCBlips[11] = STATIC_BLIP_RANDOMCHAR_11
|
|
eRCBlips[12] = STATIC_BLIP_RANDOMCHAR_12
|
|
eRCBlips[13] = STATIC_BLIP_RANDOMCHAR_13
|
|
eRCBlips[14] = STATIC_BLIP_RANDOMCHAR_14
|
|
eRCBlips[15] = STATIC_BLIP_RANDOMCHAR_15
|
|
eRCBlips[16] = STATIC_BLIP_RANDOMCHAR_16
|
|
eRCBlips[17] = STATIC_BLIP_RANDOMCHAR_17
|
|
eRCBlips[18] = STATIC_BLIP_RANDOMCHAR_18
|
|
eRCBlips[19] = STATIC_BLIP_RANDOMCHAR_19
|
|
|
|
INT iBlip
|
|
REPEAT MAX_RC_BLIPS iBlip
|
|
bRCBlipActive[iBlip] = FALSE
|
|
SET_STATIC_BLIP_ACTIVE_STATE(eRCBlips[iBlip], FALSE)
|
|
SET_STATIC_BLIP_MISSION_LAUNCH_LEVEL_LOCKED(eRCBlips[iBlip],MISSION_TYPE_RANDOM_CHAR)
|
|
SET_STATIC_BLIP_CATEGORY(eRCBlips[iBlip], STATIC_BLIP_CATEGORY_RANDOMCHAR)
|
|
SET_STATIC_BLIP_LONG_RANGE(eRCBlips[iBlip])
|
|
SET_STATIC_BLIP_COLOUR(eRCBlips[iBlip], BLIP_COLOUR_DEFAULT)
|
|
SET_STATIC_BLIP_ICON(eRCBlips[iBlip], RADAR_TRACE_RANDOM_CHARACTER)
|
|
RESET_STATIC_BLIP_CHARACTER_VISIBILITY(eRCBlips[iBlip])
|
|
ENDREPEAT
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Checks to see if there are any free Random Character mission blip indexes
|
|
/// PARAMS:
|
|
/// iBlipIndex - the available blip index
|
|
/// RETURNS:
|
|
/// Returns TRUE if a valid index was found or already set
|
|
FUNC BOOL Setup_Random_Character_Mission_Blip_Index(INT &iBlipIndex)
|
|
|
|
// Already using a valid blip index
|
|
IF iBlipIndex <> -1
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
// Attempt to find a free blip
|
|
INT iBlip
|
|
REPEAT MAX_RC_BLIPS iBlip
|
|
IF NOT bRCBlipActive[iBlip]
|
|
iBlipIndex = iBlip
|
|
bRCBlipActive[iBlip] = TRUE
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "Setup_Random_Character_Mission_Blip_Index - Using index[", iBlipIndex, "].")
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
// Unable to find a valid blip index from the pool
|
|
SCRIPT_ASSERT("Ran out of RC mission blips. Tell Andy Minghella.")
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Frees up the specified Random Character mission blip index
|
|
/// PARAMS:
|
|
/// iBlipIndex - the blip index you want to clear
|
|
PROC Clear_Random_Character_Mission_Blip_Index(INT &iBlipIndex)
|
|
|
|
IF iBlipIndex > -1 AND iBlipIndex < MAX_RC_BLIPS
|
|
bRCBlipActive[iBlipIndex] = FALSE
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "Clear_Random_Character_Mission_Blip_Index - Clearing index[", iBlipIndex, "].")
|
|
ENDIF
|
|
iBlipIndex = -1
|
|
ENDPROC
|
|
|
|
// ===========================================================================================================
|
|
// Process
|
|
// ===========================================================================================================
|
|
|
|
/// PURPOSE:
|
|
/// Returns TRUE the mission isn't available during Exile and Michael and Trevor are currently exiled
|
|
FUNC BOOL IS_MISSION_BLOCKED_DUE_TO_EXILE(BOOL bIsBlocked)
|
|
|
|
IF bIsBlocked
|
|
IF GET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_MICHAEL_TREVOR_EXILE_STARTED)
|
|
AND NOT GET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_MICHAEL_TREVOR_EXILE_FINISHED)
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Returns true if the current time of day is within the specified range
|
|
/// PARAMS:
|
|
/// iStartTime - start of range
|
|
/// iEndTime - end of range
|
|
/// RETURNS:
|
|
/// BOOL: true if in range, false otherwise
|
|
FUNC BOOL IS_CURRENT_TIME_IN_RANGE(INT iStartTime, INT iEndTime)
|
|
|
|
// Check the current time is valid
|
|
INT iCurrentTime = ((GET_TIMEOFDAY_HOUR(GET_CURRENT_TIMEOFDAY())*100) + GET_TIMEOFDAY_MINUTE(GET_CURRENT_TIMEOFDAY()))
|
|
|
|
// AM->PM
|
|
IF iEndTime > iStartTime
|
|
|
|
IF iCurrentTime < iStartTime
|
|
OR iCurrentTime > iEndTime
|
|
RETURN FALSE
|
|
ENDIF
|
|
// PM->AM
|
|
ELSE
|
|
IF iCurrentTime < iStartTime
|
|
AND iCurrentTime > iEndTime
|
|
RETURN FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Return blip origin for area mission
|
|
FUNC VECTOR GET_ORIGIN_FOR_AREA_MISSION(g_eRC_MissionIDs eRCMission)
|
|
|
|
// Weed Stash
|
|
IF eRCMission = RC_BARRY_3A RETURN << 1161.31, -1326.52, 34.23 >>
|
|
ELIF eRCMission = RC_BARRY_3C RETURN << -533.15, -1691.25, 18.21 >>
|
|
|
|
// Celebrity Theft
|
|
ELIF eRCMission = RC_NIGEL_1A RETURN << -565.80, 293.14, 90.80 >>
|
|
ELIF eRCMission = RC_NIGEL_1B RETURN << -1036.65, 363.59, 79.82 >>
|
|
ELIF eRCMission = RC_NIGEL_1C RETURN << -620.37, -264.39, 37.81 >>
|
|
ELIF eRCMission = RC_NIGEL_1D RETURN << -1115.96, 31.42, 53.80 >>
|
|
|
|
// Photo Ops
|
|
ELIF eRCMission = RC_PAPARAZZO_3A RETURN << 305.52, 157.19, 102.94 >>
|
|
ELIF eRCMission = RC_PAPARAZZO_3B RETURN << 1040.96, -534.42, 60.17 >>
|
|
ENDIF
|
|
|
|
SCRIPT_ASSERT("RandomChar_Controller: Invalid mission passed to GET_ORIGIN_FOR_AREA_MISSION()")
|
|
RETURN <<0,0,0>>
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Return blip origin for area mission
|
|
FUNC FLOAT GET_RADIUS_FOR_AREA_MISSION(g_eRC_MissionIDs eRCMission)
|
|
|
|
// Weed Stash
|
|
IF eRCMission = RC_BARRY_3A
|
|
OR eRCMission = RC_BARRY_3C
|
|
RETURN 250.0
|
|
|
|
// Celebrity Theft
|
|
ELIF eRCMission = RC_NIGEL_1A RETURN 35.0
|
|
ELIF eRCMission = RC_NIGEL_1B RETURN 37.5
|
|
ELIF eRCMission = RC_NIGEL_1C RETURN 45.0
|
|
ELIF eRCMission = RC_NIGEL_1D RETURN 150.0
|
|
|
|
// Photo Op
|
|
ELIF eRCMission = RC_PAPARAZZO_3A
|
|
OR eRCMission = RC_PAPARAZZO_3B
|
|
RETURN 90.0
|
|
ENDIF
|
|
|
|
SCRIPT_ASSERT("RandomChar_Controller: Invalid mission passed to GET_RADIUS_FOR_AREA_MISSION()")
|
|
RETURN 250.0
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Is the blip for this mission represented by an area?
|
|
FUNC BOOL IS_AREA_MISSION(g_eRC_MissionIDs eRCMission)
|
|
|
|
IF eRCMission = RC_BARRY_3A
|
|
OR eRCMission = RC_BARRY_3C
|
|
OR eRCMission = RC_NIGEL_1A
|
|
OR eRCMission = RC_NIGEL_1B
|
|
OR eRCMission = RC_NIGEL_1C
|
|
OR eRCMission = RC_NIGEL_1D
|
|
OR eRCMission = RC_PAPARAZZO_3A
|
|
OR eRCMission = RC_PAPARAZZO_3B
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Set RC blip name once character has been discovered
|
|
FUNC BOOL IS_RAMPAGE_MISSION(g_eRC_MissionIDs eRCMission)
|
|
|
|
IF eRCMission = RC_RAMPAGE_1
|
|
OR eRCMission = RC_RAMPAGE_2
|
|
OR eRCMission = RC_RAMPAGE_3
|
|
OR eRCMission = RC_RAMPAGE_4
|
|
OR eRCMission = RC_RAMPAGE_5
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
FUNC BOOL DOES_RAMPAGE_MISSION_NEED_A_CHECKMARK(g_eRC_MissionIDs eRCMission)
|
|
|
|
IF NOT IS_RAMPAGE_MISSION(eRCMission)
|
|
RETURN FALSE
|
|
ENDIF
|
|
|
|
INT iFirstRCPercentIndex = ENUM_TO_INT(CP_OJ_RAM1)
|
|
INT i = ENUM_TO_INT(eRCMission) - ENUM_TO_INT(RC_RAMPAGE_1)
|
|
|
|
IF (GET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_ALL_RAMPAGES_UNLOCKED) = TRUE)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF (g_savedGlobals.sRampageData.playerData[i].iMedalIndex >= ENUM_TO_INT(RAMPAGE_BRONZE))
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
IF IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED))
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN HAS_THIS_SCRIPT_BEEN_REGISTERED_IN_COMPLETION_PERCENTAGE_TOTAL(INT_TO_ENUM(enumCompletionPercentageEntries, iFirstRCPercentIndex + i), FALSE)
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Do multiple RC's exist at the same mission trigger
|
|
FUNC BOOL ARE_MULTIPLE_MISSIONS_AVAILABLE_AT_SAME_LOCATE(g_eRC_MissionIDs eRCMission)
|
|
|
|
IF eRCMission = RC_BARRY_1
|
|
OR eRCMission = RC_BARRY_2
|
|
|
|
// Both missions have been activated
|
|
IF IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[RC_BARRY_1].rcFlags, ENUM_TO_INT(RC_FLAG_ACTIVATED))
|
|
AND IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[RC_BARRY_2].rcFlags, ENUM_TO_INT(RC_FLAG_ACTIVATED))
|
|
|
|
// Both missions haven't yet been completed
|
|
IF NOT IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[RC_BARRY_1].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED))
|
|
AND NOT IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[RC_BARRY_2].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED))
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Has a RCM just completed at the same location as another RC trigger?
|
|
FUNC BOOL HAS_MISSION_JUST_COMPLETED_AT_SAME_LOCATE(g_eRC_MissionIDs eRCMission)
|
|
|
|
IF eRCMission = RC_BARRY_1
|
|
IF IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[RC_BARRY_2].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED))
|
|
AND g_RandomChars[RC_BARRY_2].rcLeaveAreaCheck = TRUE
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
ELIF eRCMission = RC_BARRY_2
|
|
IF IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[RC_BARRY_1].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED))
|
|
AND g_RandomChars[RC_BARRY_1].rcLeaveAreaCheck = TRUE
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Set RC blip name once character has been discovered
|
|
PROC SET_BLIP_NAME_AND_COLOUR_FOR_RC_MISSION(STATIC_BLIP_NAME_ENUM name, g_eRC_MissionIDs eRCMission)
|
|
|
|
// Set blip colour
|
|
SET_STATIC_BLIP_COLOUR(name, BLIP_COLOUR_DEFAULT)
|
|
|
|
// Blip name
|
|
IF eRCMission = RC_ABIGAIL_2
|
|
SET_STATIC_BLIP_NAME(name, "B_ABI")
|
|
|
|
ELIF eRCMission = RC_BARRY_1
|
|
OR eRCMission = RC_BARRY_2
|
|
OR eRCMission = RC_BARRY_3
|
|
OR eRCMission = RC_BARRY_4
|
|
|
|
// Barry is blipped by name if any Barry missions have been completed
|
|
IF IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[RC_BARRY_1].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED))
|
|
OR IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[RC_BARRY_2].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED))
|
|
OR IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[RC_BARRY_3].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED))
|
|
SET_STATIC_BLIP_NAME(name, "B_BAR")
|
|
ELSE
|
|
SET_STATIC_BLIP_NAME(name, "BLIP_66")
|
|
SET_STATIC_BLIP_ICON(name, RADAR_TRACE_RANDOM_CHARACTER)
|
|
ENDIF
|
|
|
|
ELIF eRCMission = RC_BARRY_3A
|
|
OR eRCMission = RC_BARRY_3C
|
|
SET_STATIC_BLIP_NAME(name, "B_STA")
|
|
|
|
ELIF eRCMission = RC_DREYFUSS_1
|
|
SET_STATIC_BLIP_NAME(name, "B_DRE")
|
|
|
|
ELIF eRCMission = RC_EPSILON_2
|
|
OR eRCMission = RC_EPSILON_3
|
|
OR eRCMission = RC_EPSILON_4
|
|
OR eRCMission = RC_EPSILON_5
|
|
OR eRCMission = RC_EPSILON_6
|
|
OR eRCMission = RC_EPSILON_7
|
|
OR eRCMission = RC_EPSILON_8
|
|
SET_STATIC_BLIP_NAME(name, "B_EPS")
|
|
|
|
ELIF eRCMission = RC_EXTREME_2
|
|
OR eRCMission = RC_EXTREME_3
|
|
OR eRCMission = RC_EXTREME_4
|
|
SET_STATIC_BLIP_NAME(name, "B_EXT")
|
|
|
|
ELIF eRCMission = RC_FANATIC_1
|
|
OR eRCMission = RC_FANATIC_2
|
|
OR eRCMission = RC_FANATIC_3
|
|
|
|
// Mary-Ann is blipped by name if any Fanatic missions have been completed
|
|
IF IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[RC_FANATIC_1].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED))
|
|
OR IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[RC_FANATIC_2].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED))
|
|
OR IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[RC_FANATIC_3].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED))
|
|
SET_STATIC_BLIP_NAME(name, "B_FAN")
|
|
ELSE
|
|
SET_STATIC_BLIP_NAME(name, "BLIP_66")
|
|
SET_STATIC_BLIP_ICON(name, RADAR_TRACE_RANDOM_CHARACTER)
|
|
ENDIF
|
|
|
|
ELIF eRCMission = RC_HUNTING_2
|
|
SET_STATIC_BLIP_NAME(name, "B_HUN")
|
|
|
|
ELIF eRCMission = RC_JOSH_2
|
|
OR eRCMission = RC_JOSH_3
|
|
OR eRCMission = RC_JOSH_4
|
|
SET_STATIC_BLIP_NAME(name, "B_JOS")
|
|
|
|
ELIF eRCMission = RC_MINUTE_2
|
|
OR eRCMission = RC_MINUTE_3
|
|
SET_STATIC_BLIP_NAME(name, "B_MIN")
|
|
|
|
ELIF eRCMission = RC_NIGEL_1A
|
|
OR eRCMission = RC_NIGEL_1B
|
|
OR eRCMission = RC_NIGEL_1C
|
|
OR eRCMission = RC_NIGEL_1D
|
|
SET_STATIC_BLIP_NAME(name, "B_CEL")
|
|
|
|
ELIF eRCMission = RC_NIGEL_2
|
|
OR eRCMission = RC_NIGEL_3
|
|
SET_STATIC_BLIP_NAME(name, "B_NIG")
|
|
|
|
ELIF eRCMission = RC_OMEGA_2
|
|
SET_STATIC_BLIP_NAME(name, "B_OME")
|
|
|
|
ELIF eRCMission = RC_PAPARAZZO_2
|
|
OR eRCMission = RC_PAPARAZZO_3
|
|
OR eRCMission = RC_PAPARAZZO_4
|
|
SET_STATIC_BLIP_NAME(name, "B_PAP")
|
|
|
|
ELIF eRCMission = RC_PAPARAZZO_3A
|
|
OR eRCMission = RC_PAPARAZZO_3B
|
|
SET_STATIC_BLIP_NAME(name, "B_PHO")
|
|
|
|
ELIF eRCMission = RC_RAMPAGE_1
|
|
SET_STATIC_BLIP_NAME(name, "BLIP_66")
|
|
|
|
ELIF eRCMission = RC_RAMPAGE_2
|
|
OR eRCMission = RC_RAMPAGE_3
|
|
OR eRCMission = RC_RAMPAGE_4
|
|
OR eRCMission = RC_RAMPAGE_5
|
|
SET_STATIC_BLIP_NAME(name, "BLIP_84")
|
|
|
|
ELIF eRCMission = RC_TONYA_2
|
|
OR eRCMission = RC_TONYA_3
|
|
OR eRCMission = RC_TONYA_4
|
|
OR eRCMission = RC_TONYA_5
|
|
SET_STATIC_BLIP_NAME(name, "B_TON")
|
|
ELSE
|
|
SET_STATIC_BLIP_NAME(name, "BLIP_66")
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Checks for the moment at which the player reveals RC mission locations in the FOW,
|
|
/// saves these results, and alters RC blip range settings appropriately. Optimised to
|
|
/// check 1 RC per frame and save results into an extendable bitset.
|
|
PROC UPDATE_RC_REVEALED_IN_FOW_CHECKS()
|
|
|
|
//Step through one RC mission per frame and precalculate which bit and bitset to query for FOW visiblity.
|
|
iRCMission++
|
|
iBit++
|
|
IF iRCMission >= ENUM_TO_INT(MAX_RC_MISSIONS)
|
|
iRCMission = 0
|
|
iBit = 0
|
|
iBitset = 0
|
|
ELIF iBit > 31
|
|
iBit = 0
|
|
iBitset++
|
|
//Check we haven't overrun the number of bitsets we have.
|
|
#IF IS_DEBUG_BUILD
|
|
IF iBitset >= RC_MAX_FOW_VISIBLE_BITSETS
|
|
SCRIPT_ASSERT("UPDATE_RC_VISIBLE_IN_FOW_CHECKS: Not enough bitsets to track FOW state of all RC missions. Increase RC_MAX_FOW_VISIBLE_BITSETS.")
|
|
ENDIF
|
|
#ENDIF
|
|
ENDIF
|
|
|
|
//CDEBUG3LN(DEBUG_RANDOM_CHAR, "<FOW-VIS> Mission:", iRCMission, " Bit:", iBit, " Bitset:", iBitset)
|
|
g_eRC_MissionIDs eRCMission = INT_TO_ENUM(g_eRC_MissionIDs, iRCMission)
|
|
|
|
// Rampages 2-5 are not affected by the fog of war
|
|
IF NOT IS_RAMPAGE_MISSION(eRCMission) OR eRCMission = RC_RAMPAGE_1
|
|
|
|
// Every frame check one RC mission to see if it has been revealed on the map.
|
|
IF NOT IS_BIT_SET(g_savedGlobals.sRandomChars.g_iVisibleInFOWBitset[iBitset], iBit)
|
|
|
|
CDEBUG3LN(DEBUG_RANDOM_CHAR, "<FOW-VIS> Checking if ", GET_RC_MISSION_DISPLAY_STRING_FROM_ID(eRCMission), " has been revealed in the FOW.")
|
|
|
|
g_structRCMissionsStatic sRCMissionDetails
|
|
Retrieve_Random_Character_Static_Mission_Details(eRCMission, sRCMissionDetails)
|
|
|
|
// Automatically reveal Tonya 1.
|
|
IF eRCMission = RC_TONYA_1
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "<FOW-VIS> Flagging ", GET_RC_MISSION_DISPLAY_STRING_FROM_ID(eRCMission), " as having been revealed in the FOW.")
|
|
SET_BIT(g_savedGlobals.sRandomChars.g_iVisibleInFOWBitset[iBitset], iBit)
|
|
|
|
// Query the FOW state to see if this RC has been revealed yet.
|
|
ELIF GET_MINIMAP_FOW_COORDINATE_IS_REVEALED(sRCMissionDetails.rcCoords)
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "<FOW-VIS> Flagging ", GET_RC_MISSION_DISPLAY_STRING_FROM_ID(eRCMission), " as having been revealed in the FOW.")
|
|
SET_BIT(g_savedGlobals.sRandomChars.g_iVisibleInFOWBitset[iBitset], iBit)
|
|
|
|
// If the RC hasn't been revealed and it's blip is long range then make it short range for now.
|
|
ELIF g_RandomChars[eRCMission].rcBlipIndex != -1
|
|
IF bRCBlipActive[g_RandomChars[eRCMission].rcBlipIndex]
|
|
IF IS_BIT_SET(g_GameBlips[eRCBlips[g_RandomChars[eRCMission].rcBlipIndex]].iSetting, STATIC_BLIP_SETTING_RADAR_LONG)
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "<FOW-VIS> Setting blip short range for ", GET_RC_MISSION_DISPLAY_STRING_FROM_ID(eRCMission), ".")
|
|
SET_STATIC_BLIP_SHORT_RANGE(eRCBlips[g_RandomChars[eRCMission].rcBlipIndex])
|
|
//SET_STATIC_BLIP_VISIBLE_STATE(eRCBlips[g_RandomChars[eRCMission].rcBlipIndex], FALSE)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
//If the RC has been revealed and it's blip is short range then make it long range from now on.
|
|
ELIF g_RandomChars[eRCMission].rcBlipIndex != -1
|
|
IF bRCBlipActive[g_RandomChars[eRCMission].rcBlipIndex]
|
|
IF NOT IS_BIT_SET(g_GameBlips[eRCBlips[g_RandomChars[eRCMission].rcBlipIndex]].iSetting, STATIC_BLIP_SETTING_RADAR_LONG)
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "<FOW-VIS> Setting blip long range for ", GET_RC_MISSION_DISPLAY_STRING_FROM_ID(eRCMission), ".")
|
|
SET_STATIC_BLIP_LONG_RANGE(eRCBlips[g_RandomChars[eRCMission].rcBlipIndex])
|
|
//SET_STATIC_BLIP_VISIBLE_STATE(eRCBlips[g_RandomChars[eRCMission].rcBlipIndex], TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
|
|
PROC UPDATE_BEVERLY_UNLOCK_WILDLIFE_PHOTOGRAPHY()
|
|
IF IS_LAST_GEN_PLAYER()
|
|
IF NOT GET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_BEVERLY_SENT_WILDLIFE_TEXT)
|
|
IF IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[RC_PAPARAZZO_1].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED))
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "Paparazzo 1 completed and the player is from last-gen. Queueing Beverly text for Wildlife Photography.")
|
|
#IF IS_FINAL_BUILD
|
|
REGISTER_TEXT_MESSAGE_FROM_CHARACTER_TO_PLAYER(TEXT_PAP1_WILDLIFE_UNLOCK, CT_AMBIENT, BIT_FRANKLIN, CHAR_BEVERLY, 60000, 10000, VID_BLANK, CID_PAPARAZZO1_SEND_WILDLIFE_EMAIL)
|
|
#ENDIF
|
|
#IF IS_DEBUG_BUILD
|
|
IF NOT g_flowUnsaved.bUpdatingGameflow
|
|
IF NOT IS_BIT_SET(g_iDebugLaunchBlockCommunication, BIT_DBG_LNCH_COMM_BLOCK_WILDLIFE_PHOTO)
|
|
REGISTER_TEXT_MESSAGE_FROM_CHARACTER_TO_PLAYER(TEXT_PAP1_WILDLIFE_UNLOCK, CT_AMBIENT, BIT_FRANKLIN, CHAR_BEVERLY, 60000, 10000, VID_BLANK, CID_PAPARAZZO1_SEND_WILDLIFE_EMAIL)
|
|
ENDIF
|
|
ENDIF
|
|
CLEAR_BIT(g_iDebugLaunchBlockCommunication, BIT_DBG_LNCH_COMM_BLOCK_WILDLIFE_PHOTO)
|
|
#ENDIF
|
|
SET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_BEVERLY_SENT_WILDLIFE_TEXT, TRUE)
|
|
ENDIF
|
|
ELSE
|
|
// Check for Beverly being dead. If he is remove his text and jump straight to the Tourist Board email.
|
|
IF NOT GET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_WILDLIFE_PHOTOGRAPHY_UNLOCKED)
|
|
IF IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[RC_PAPARAZZO_4].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED))
|
|
IF IS_COMMUNICATION_REGISTERED(TEXT_PAP1_WILDLIFE_UNLOCK)
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "Beverly text for Wildlife Photography queued after Beverly has died.")
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "Skipping directly to the Los Santos Tourist Board email.")
|
|
CANCEL_COMMUNICATION(TEXT_PAP1_WILDLIFE_UNLOCK)
|
|
Execute_Code_ID(CID_PAPARAZZO1_SEND_WILDLIFE_EMAIL, 0)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Handles making sure the help displays after passing Josh 1.
|
|
PROC Do_Josh1_For_Sale_Signs_Help()
|
|
|
|
IF NOT HAS_ONE_TIME_HELP_DISPLAYED(FHM_JOSH1_FOR_SALE)
|
|
IF IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[RC_JOSH_1].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED))
|
|
IF GET_FLOW_HELP_MESSAGE_STATUS("FS_HELP1") = FHS_EXPIRED
|
|
ADD_HELP_TO_FLOW_QUEUE("FS_HELP1", FHP_MEDIUM, 0, 2000)
|
|
|
|
ELIF GET_FLOW_HELP_MESSAGE_STATUS("FS_HELP1") = FHS_DISPLAYED
|
|
SET_ONE_TIME_HELP_MESSAGE_DISPLAYED(FHM_JOSH1_FOR_SALE)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Reminder help text when first entering an area blip for one of the Barry stash missions
|
|
PROC Do_Barry3_Reminder_Help()
|
|
|
|
// Reminder help text
|
|
IF IS_PLAYER_PLAYING(PLAYER_ID())
|
|
IF NOT HAS_ONE_TIME_HELP_DISPLAYED(FHM_BARRY3_REMINDER_HELP)
|
|
|
|
IF IS_RC_MISSION_AVAILABLE(RC_BARRY_3A) AND GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), GET_ORIGIN_FOR_AREA_MISSION(RC_BARRY_3A)) < GET_RADIUS_FOR_AREA_MISSION(RC_BARRY_3A)
|
|
OR IS_RC_MISSION_AVAILABLE(RC_BARRY_3C) AND GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), GET_ORIGIN_FOR_AREA_MISSION(RC_BARRY_3C)) < GET_RADIUS_FOR_AREA_MISSION(RC_BARRY_3C)
|
|
|
|
// Areas where you can find vehicles with a hidden stash are marked on the map. Search them to find vehicles for Barry.
|
|
IF GET_FLOW_HELP_MESSAGE_STATUS("BARSTASH2") = FHS_EXPIRED
|
|
ADD_HELP_TO_FLOW_QUEUE("BARSTASH2", FHP_MEDIUM, 0, 2000, DEFAULT_HELP_TEXT_TIME, BIT_FRANKLIN)
|
|
|
|
ELIF GET_FLOW_HELP_MESSAGE_STATUS("BARSTASH2") = FHS_DISPLAYED
|
|
SET_ONE_TIME_HELP_MESSAGE_DISPLAYED(FHM_BARRY3_REMINDER_HELP)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
/// PURPOSE:
|
|
/// Reminder the player that they need to do Tonya1 to progress the gameflow. Keeps displaying
|
|
/// if Tonya1 isn't completed after Family1.
|
|
PROC Do_Tonya1_Reminder_Help()
|
|
IF NOT HAS_ONE_TIME_HELP_DISPLAYED(FHM_RC_TONYA1_REMINDER)
|
|
|
|
IF IS_PLAYER_PLAYING(PLAYER_ID())
|
|
IF GET_MISSION_COMPLETE_STATE(SP_MISSION_FAMILY_1)
|
|
IF NOT GET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_RES_AND_RCS_UNLOCKED)
|
|
IF eTonya1HelpTime = INVALID_TIMEOFDAY
|
|
eTonya1HelpTime = GET_CURRENT_TIMEOFDAY()
|
|
ADD_TIME_TO_TIMEOFDAY(eTonya1HelpTime, 0, 5)
|
|
ELIF IS_NOW_AFTER_TIMEOFDAY(eTonya1HelpTime)
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "Attempting to display Tonya1 blip reminder this frame.")
|
|
|
|
BOOL bFoundBlip = FALSE
|
|
|
|
INT iBlipIndex
|
|
g_structRCMissionsStatic sRCMissionDetails
|
|
FOR iBlipIndex = ENUM_TO_INT(STATIC_BLIP_RANDOMCHAR_00) TO ENUM_TO_INT(STATIC_BLIP_RANDOMCHAR_19)
|
|
STATIC_BLIP_NAME_ENUM eRCBlip = INT_TO_ENUM(STATIC_BLIP_NAME_ENUM, iBlipIndex)
|
|
Retrieve_Random_Character_Static_Mission_Details(RC_TONYA_1, sRCMissionDetails)
|
|
IF ARE_VECTORS_EQUAL(sRCMissionDetails.rcCoords, GET_STATIC_BLIP_POSITION(eRCBlip))
|
|
IF DOES_BLIP_EXIST(g_GameBlips[eRCBlip].biBlip)
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "Found Tonya1 blip. Displaying reminder.")
|
|
|
|
//Found Tonya blip. Display help and flash blip.
|
|
SET_BLIP_FLASHES(g_GameBlips[eRCBlip].biBlip, TRUE)
|
|
SET_BLIP_FLASH_TIMER(g_GameBlips[eRCBlip].biBlip, 10000)
|
|
SWITCH GET_CURRENT_PLAYER_PED_ENUM()
|
|
CASE CHAR_FRANKLIN ADD_HELP_TO_FLOW_QUEUE("AM_H_RCFS", FHP_HIGH, 0, 1000) BREAK
|
|
CASE CHAR_MICHAEL ADD_HELP_TO_FLOW_QUEUE("AM_H_RCFS_M", FHP_HIGH, 0, 1000) BREAK
|
|
ENDSWITCH
|
|
|
|
//Display help again in 5 game hours.
|
|
eTonya1HelpTime = GET_CURRENT_TIMEOFDAY()
|
|
ADD_TIME_TO_TIMEOFDAY(eTonya1HelpTime, 0, 0, 8)
|
|
bFoundBlip = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDFOR
|
|
|
|
//Blip not found this pass. Try again in 5 game minutes.
|
|
IF NOT bFoundBlip
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "Couldn't find Tonya1 blip. Delaying next attempt for 5 in-game minutes.")
|
|
eTonya1HelpTime = GET_CURRENT_TIMEOFDAY()
|
|
ADD_TIME_TO_TIMEOFDAY(eTonya1HelpTime, 0, 5)
|
|
ENDIF
|
|
|
|
ENDIF
|
|
ELSE
|
|
SET_ONE_TIME_HELP_MESSAGE_DISPLAYED(FHM_RC_TONYA1_REMINDER)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Updates the flags and blip state for the specified Random Character mission
|
|
/// PARAMS:
|
|
/// eRCMission - the RC mission we are processing
|
|
PROC Process_Random_Character_Mission_State(g_eRC_MissionIDs eRCMission)
|
|
|
|
IF (eRCMission = NO_RC_MISSION)
|
|
SCRIPT_ASSERT("ERROR: Process_Random_Character_Mission_State has been passed an illegal Random Character mission ID")
|
|
EXIT
|
|
ENDIF
|
|
|
|
// Grab the mission details
|
|
g_structRCMissionsStatic sRCMissionDetails
|
|
Retrieve_Random_Character_Static_Mission_Details(eRCMission, sRCMissionDetails)
|
|
|
|
//----- -----Mission flags--------------------------------------
|
|
// Clear the global force update flag seeing as we are now processing the mission
|
|
g_RandomChars[eRCMission].rcForceStateUpdate = FALSE
|
|
|
|
IF NOT IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcFlags, ENUM_TO_INT(RC_FLAG_ACTIVATED_IN_FLOW))
|
|
IF NOT sRCMissionDetails.rcMustBeActivatedInFlow
|
|
SET_BIT(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcFlags, ENUM_TO_INT(RC_FLAG_ACTIVATED_IN_FLOW))
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcFlags, ENUM_TO_INT(RC_FLAG_ACTIVATED))
|
|
AND NOT IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED))
|
|
|
|
// Set time delay when first activated
|
|
IF NOT g_savedGlobals.sRandomChars.savedRC[eRCMission].rcTimeReqSet
|
|
|
|
// Set the time
|
|
TIMEOFDAY sStartTime = GET_CURRENT_TIMEOFDAY()
|
|
ADD_TIME_TO_TIMEOFDAY(sStartTime, 0, 0, sRCMissionDetails.rcHoursToWaitReq, 0, 0, 0)
|
|
|
|
// Last One mission unlocks a random time after 100% complete
|
|
IF eRCMission = RC_THELASTONE
|
|
|
|
// Unlocks between 3 and 10 hours
|
|
INT iRandomHours = GET_RANDOM_INT_IN_RANGE(3, 11)
|
|
iRandomHours *= 30 //B*1589468 get real hours
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "The Last One RCM unlocking after ", iRandomHours, " hours")
|
|
ADD_TIME_TO_TIMEOFDAY(sStartTime, 0, 0, iRandomHours, 0, 0, 0)
|
|
ENDIF
|
|
#IF IS_DEBUG_BUILD
|
|
TEXT_LABEL_63 tlTime = TIMEOFDAY_TO_TEXT_LABEL(sStartTime)
|
|
TEXT_LABEL_7 tlName = GET_RC_MISSION_NAME_LABEL(eRCMission)
|
|
CPRINTLN(DEBUG_RANDOM_CHAR,"RC Mission ",tlName," set to start on ",tlTime)
|
|
#ENDIF
|
|
g_savedGlobals.sRandomChars.savedRC[eRCMission].rcTimeReq = sStartTime
|
|
g_savedGlobals.sRandomChars.savedRC[eRCMission].rcTimeReqSet = TRUE
|
|
ENDIF
|
|
|
|
IF IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcFlags, ENUM_TO_INT(RC_FLAG_ACTIVATED_IN_FLOW))
|
|
IF NOT IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcFlags, ENUM_TO_INT(RC_FLAG_READY_TO_PLAY))
|
|
|
|
// Set ready to play and then check for any fail conditions
|
|
BOOL bReadyToPlay = TRUE
|
|
|
|
// Check flow flag state
|
|
IF sRCMissionDetails.rcFlowFlagReq <> FLOWFLAG_NONE
|
|
IF NOT Get_Mission_Flow_Flag_State(sRCMissionDetails.rcFlowFlagReq)
|
|
#IF IS_DEBUG_BUILD RC_CONTROLLER_DEBUG_PRINT(eRCMission, "Get_Mission_Flow_Flag_State = FALSE, set bReadyToPlay as FALSE") #ENDIF
|
|
bReadyToPlay = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Check whether mission is blocked due to a specific story mission
|
|
IF Random_Character_Blocked_Due_To_Mission(eRCMission)
|
|
#IF IS_DEBUG_BUILD RC_CONTROLLER_DEBUG_PRINT(eRCMission, "Random_Character_Blocked_Due_To_Mission, set bReadyToPlay as FALSE") #ENDIF
|
|
bReadyToPlay = FALSE
|
|
ENDIF
|
|
|
|
// Check whether mission is blocked due to being wanted
|
|
IF Random_Character_Blocked_Due_To_Wanted_Level(eRCMission)
|
|
#IF IS_DEBUG_BUILD RC_CONTROLLER_DEBUG_PRINT(eRCMission, "Random_Character_Blocked_Due_To_Wanted_Level, set bReadyToPlay as FALSE") #ENDIF
|
|
bReadyToPlay = FALSE
|
|
ENDIF
|
|
|
|
// Check whether mission is blocked due to Michael and Trevor
|
|
IF IS_MISSION_BLOCKED_DUE_TO_EXILE(sRCMissionDetails.bBlockedInExile)
|
|
#IF IS_DEBUG_BUILD RC_CONTROLLER_DEBUG_PRINT(eRCMission, "IS_MISSION_BLOCKED_DUE_TO_EXILE, set bReadyToPlay as FALSE") #ENDIF
|
|
bReadyToPlay = FALSE
|
|
ENDIF
|
|
|
|
// Check the time delay requirement
|
|
IF sRCMissionDetails.rcHoursToWaitReq > 0 AND bReadyToPlay
|
|
IF NOT IS_NOW_AFTER_TIMEOFDAY(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcTimeReq)
|
|
//Check if the time left to wait is not absurdly large (> 2 weeks in-game)
|
|
INT iSec, iMinute, iHour, iDays,iMonths, iYears
|
|
GET_DIFFERENCE_BETWEEN_NOW_AND_TIMEOFDAY(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcTimeReq,iSec, iMinute,iHour,iDays,iMonths,iYears)
|
|
IF (iYears>0) OR (iMonths > 0) OR (iDays > 10)
|
|
TEXT_LABEL_63 strTod
|
|
TEXT_LABEL_7 strRCM = GET_RC_MISSION_NAME_LABEL(INT_TO_ENUM(g_eRC_MissionIDs,eRCMission))
|
|
#IF IS_DEBUG_BUILD
|
|
GET_TIMEOFDAY_STRING(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcTimeReq,strTod,TRUE,TRUE)
|
|
PRINT_TIMEOFDAY(GET_CURRENT_TIMEOFDAY(),debug_random_char)
|
|
#ENDIF
|
|
|
|
CERRORLN(DEBUG_RANDOM_CHAR,"See bug 2135359: Time till random char mission '",
|
|
strRCM ,"' is very long (over 10 days), supposed to start on ",
|
|
strTod," resetting to current + wait time (",sRCMissionDetails.rcHoursToWaitReq,")")
|
|
g_savedGlobals.sRandomChars.savedRC[eRCMission].rcTimeReq = GET_CURRENT_TIMEOFDAY()
|
|
ADD_TIME_TO_TIMEOFDAY(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcTimeReq, 0, 0, sRCMissionDetails.rcHoursToWaitReq, 0, 0, 0)
|
|
ENDIF
|
|
#IF IS_DEBUG_BUILD RC_CONTROLLER_DEBUG_PRINT(eRCMission, "IS_NOW_AFTER_TIMEOFDAY, set bReadyToPlay as FALSE") #ENDIF
|
|
bReadyToPlay = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Check the current time is valid
|
|
IF NOT IS_CURRENT_TIME_IN_RANGE(sRCMissionDetails.rcStartTime, sRCMissionDetails.rcEndTime)
|
|
#IF IS_DEBUG_BUILD RC_CONTROLLER_DEBUG_PRINT(eRCMission, "Time of day outside restrictions, set bReadyToPlay as FALSE") #ENDIF
|
|
bReadyToPlay = FALSE
|
|
ENDIF
|
|
|
|
// Mark as Ready To Play if no issues found
|
|
IF bReadyToPlay
|
|
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "RC mission ", sRCMissionDetails.rcScriptName, " is ready to launch.")
|
|
|
|
SET_BIT(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcFlags, ENUM_TO_INT(RC_FLAG_READY_TO_PLAY))
|
|
g_RandomChars[eRCMission].rcIsRunning = FALSE
|
|
g_RandomChars[eRCMission].rcFailed = FALSE
|
|
g_RandomChars[eRCMission].rcPassed = FALSE
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF g_eDebugLaunchingToRCMission = eRCMission
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "Leave area check for RC mission ", sRCMissionDetails.rcScriptName, " was skipped due to debug launch.")
|
|
ELSE
|
|
#ENDIF
|
|
|
|
// Special cases
|
|
IF eRCMission = RC_MRS_PHILIPS_1
|
|
|
|
// We want it to appear when player gets control at the end of the game.
|
|
g_RandomChars[eRCMission].rcLeaveAreaCheck = FALSE
|
|
REACTIVATE_NAMED_WORLD_BRAINS_WAITING_TILL_OUT_OF_RANGE("launcher_MrsPhilips")
|
|
|
|
ELIF eRCMission = RC_TONYA_1
|
|
|
|
// We want it to appear as soon as we finish Armenian 2 to encourage the player to trigger it immediately.
|
|
g_RandomChars[eRCMission].rcLeaveAreaCheck = FALSE
|
|
REACTIVATE_NAMED_WORLD_BRAINS_WAITING_TILL_OUT_OF_RANGE("launcher_Tonya")
|
|
ELSE
|
|
// Fix for bug #324493 - Force player to leave area before activating the blip
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "Leave area flag set for RC mission ", sRCMissionDetails.rcScriptName, ".")
|
|
g_RandomChars[eRCMission].rcLeaveAreaCheck = TRUE
|
|
ENDIF
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
ENDIF
|
|
#ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Check some runtime flags
|
|
IF IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcFlags, ENUM_TO_INT(RC_FLAG_READY_TO_PLAY))
|
|
AND NOT IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED))
|
|
|
|
BOOL bOkToLaunch = TRUE
|
|
|
|
// Check whether mission is blocked due to a specific story mission
|
|
IF Random_Character_Blocked_Due_To_Mission(eRCMission)
|
|
#IF IS_DEBUG_BUILD RC_CONTROLLER_DEBUG_PRINT(eRCMission, "Random_Character_Blocked_Due_To_Mission, set bReadyToPlay as FALSE") #ENDIF
|
|
bOkToLaunch = FALSE
|
|
ENDIF
|
|
|
|
// Check for wanted update
|
|
IF Random_Character_Blocked_Due_To_Wanted_Level(eRCMission)
|
|
bOkToLaunch = FALSE
|
|
ENDIF
|
|
|
|
// Check for Exile flag update...
|
|
IF IS_MISSION_BLOCKED_DUE_TO_EXILE(sRCMissionDetails.bBlockedInExile)
|
|
bOkToLaunch = FALSE
|
|
ENDIF
|
|
|
|
// Still ok?
|
|
IF bOkToLaunch
|
|
|
|
// Are we still within the required time of day?
|
|
IF NOT IS_CURRENT_TIME_IN_RANGE(sRCMissionDetails.rcStartTime, sRCMissionDetails.rcEndTime)
|
|
#IF IS_DEBUG_BUILD RC_CONTROLLER_DEBUG_PRINT(eRCMission, "Time of day outside restrictions, set bOkToLaunch as FALSE") #ENDIF
|
|
bOkToLaunch = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Mission no longer ready as either blocked by exile or gone past TOD restriction...
|
|
IF NOT bOkToLaunch
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "RC mission ", sRCMissionDetails.rcScriptName, " is no longer ready to play.")
|
|
CLEAR_BIT(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcFlags, ENUM_TO_INT(RC_FLAG_READY_TO_PLAY))
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// RC Missions set the rcIsAwaitingTrigger flag to TRUE when waiting for the player
|
|
// to trigger the created ped.
|
|
// To keep things clean we have made this a reset flag, which means that it will only
|
|
// stay TRUE for the frame that it was set. With this in mind, we can set the appropriate
|
|
// blip state and force a mission update the following frame.
|
|
BOOL bReadyToTrigger = TRUE // Should always display unless still in range and no longer triggerable
|
|
IF g_RandomChars[eRCMission].rcIsAwaitingTrigger
|
|
|
|
// We reach this point every frame that the character is ready to trigger,
|
|
// as well as the first frame after the mission has cleaned up.
|
|
g_RandomChars[eRCMission].rcForceStateUpdate = TRUE
|
|
g_RandomChars[eRCMission].rcIsAwaitingTrigger = FALSE
|
|
g_RandomChars[eRCMission].rcLeaveAreaCheck = TRUE
|
|
ELSE
|
|
IF g_RandomChars[eRCMission].rcLeaveAreaCheck
|
|
|
|
// RCM strands can now have different brain activation ranges
|
|
FLOAT fRCActivationRange
|
|
IF sRCMissionDetails.rcStrandID = RCS_ABIGAIL
|
|
OR sRCMissionDetails.rcStrandID = RCS_DREYFUSS
|
|
OR sRCMissionDetails.rcStrandID = RCS_EPSILON
|
|
OR sRCMissionDetails.rcStrandID = RCS_MRS_PHILIPS
|
|
OR sRCMissionDetails.rcStrandID = RCS_THELASTONE
|
|
OR sRCMissionDetails.rcStrandID = RCS_TONYA
|
|
fRCActivationRange = RC_BRAIN_ACTIVATION_RANGE_NORMAL
|
|
ELSE
|
|
fRCActivationRange = RC_BRAIN_ACTIVATION_RANGE_EXTRA
|
|
ENDIF
|
|
|
|
// Don't do this check if a replay is being processed- to prevent this being reset whilst things for replay load (player warp etc)
|
|
IF NOT IS_REPLAY_BEING_PROCESSED()
|
|
AND (GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE), sRCMissionDetails.rcCoords, FALSE) > fRCActivationRange)
|
|
// If the blips are appearing too soon then we need to add some sort of timer here.
|
|
// We would also need to tie the timer into the 'is rc mission safe to run' checks.
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "Player left area for RC mission ", sRCMissionDetails.rcScriptName)
|
|
g_RandomChars[eRCMission].rcLeaveAreaCheck = FALSE
|
|
ELSE
|
|
// Still waiting for player to leave so not safe to trigger
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "RC mission ", sRCMissionDetails.rcScriptName, " is waiting for player to leave the area.")
|
|
// Below IF statement - fixes B*2204739 - Random Char controller was waiting for the player to leave, but the door was unlocked and quicksaves allowed
|
|
IF eRCMission = RC_EPSILON_2
|
|
AND g_savedGlobals.sBuildingData.eDoorState[DOORNAME_EPSILON2_STORAGE_ROOM] <> DOORSTATE_LOCKED
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "Locking Epsilon 2 storeroom door...")
|
|
SET_DOOR_STATE(DOORNAME_EPSILON2_STORAGE_ROOM, DOORSTATE_LOCKED)
|
|
ENDIF
|
|
bReadyToTrigger = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// ----------------Mission blips--------------------------------------------------------
|
|
g_eRC_BlipState eBlipState = RC_BLIP_TURNED_OFF
|
|
IF bReadyToTrigger
|
|
AND NOT (IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED)))
|
|
AND (IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcFlags, ENUM_TO_INT(RC_FLAG_ACTIVATED)))
|
|
AND (IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcFlags, ENUM_TO_INT(RC_FLAG_ACTIVATED_IN_FLOW)))
|
|
AND (IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcFlags, ENUM_TO_INT(RC_FLAG_READY_TO_PLAY)))
|
|
|
|
// B*1306406 - Don't display first Tonya blip until Armenian 2 results screen has finished
|
|
IF eRCMission = RC_TONYA_1 AND IS_RESULT_SCREEN_DISPLAYING()
|
|
ELSE
|
|
eBlipState = RC_BLIP_READY_TO_TRIGGER
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Only process if the state has changed
|
|
IF g_RandomChars[eRCMission].rcBlipState <> eBlipState
|
|
|
|
// Make sure we have a valid blip index from the pool
|
|
IF Setup_Random_Character_Mission_Blip_Index(g_RandomChars[eRCMission].rcBlipIndex)
|
|
|
|
// Ignore in the event that the RC mission doesn't have a defined blip (e.g. Tonya 3&4)
|
|
IF ARE_VECTORS_EQUAL(sRCMissionDetails.rcCoords, <<0,0,0>>)
|
|
|
|
ELSE
|
|
STATIC_BLIP_NAME_ENUM eBlip = eRCBlips[g_RandomChars[eRCMission].rcBlipIndex]
|
|
|
|
IF eBlipState = RC_BLIP_TURNED_OFF
|
|
|
|
// Turn off the blip and free up the blip index
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "RC_BLIP_TURNED_OFF ", GET_RC_MISSION_DISPLAY_STRING_FROM_ID(eRCMission))
|
|
SET_STATIC_BLIP_ACTIVE_STATE(eBlip, FALSE)
|
|
SET_STATIC_BLIP_HAS_CHECKMARK(eBlip, FALSE)
|
|
Clear_Random_Character_Mission_Blip_Index(g_RandomChars[eRCMission].rcBlipIndex)
|
|
|
|
ELIF eBlipState = RC_BLIP_READY_TO_TRIGGER
|
|
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "RC_BLIP_READY_TO_TRIGGER ", GET_RC_MISSION_DISPLAY_STRING_FROM_ID(eRCMission))
|
|
|
|
// Area blips for Barry weed stash and Nigel theft missions
|
|
IF IS_AREA_MISSION(eRCMission)
|
|
SET_STATIC_BLIP_AS_AREA_BLIP(eBlip, TRUE)
|
|
SET_STATIC_BLIP_POSITION(eBlip, GET_ORIGIN_FOR_AREA_MISSION(eRCMission))
|
|
SET_STATIC_BLIP_RADIUS(eBlip, GET_RADIUS_FOR_AREA_MISSION(eRCMission))
|
|
ELSE
|
|
SET_STATIC_BLIP_AS_AREA_BLIP(eBlip, FALSE)
|
|
SET_STATIC_BLIP_ICON(eBlip, sRCMissionDetails.rcBlipSprite)
|
|
SET_STATIC_BLIP_POSITION(eBlip, sRCMissionDetails.rcCoords)
|
|
ENDIF
|
|
|
|
// Set blip name based on character name
|
|
SET_BLIP_NAME_AND_COLOUR_FOR_RC_MISSION(eBlip, eRCMission)
|
|
|
|
|
|
// Set up the blip states that are specific to this mission, this includes
|
|
// character visibility, icon, colour, position etc.
|
|
RESET_STATIC_BLIP_CHARACTER_VISIBILITY(eBlip)
|
|
|
|
IF IS_MISSION_TRIGGERABLE_BY_CHARACTER(sRCMissionDetails.rcPlayableChars, CHAR_FRANKLIN)
|
|
SET_STATIC_BLIP_CHARACTER_VISIBILITY(eBlip, TRUE, CHAR_FRANKLIN)
|
|
ENDIF
|
|
|
|
IF IS_MISSION_TRIGGERABLE_BY_CHARACTER(sRCMissionDetails.rcPlayableChars, CHAR_MICHAEL)
|
|
SET_STATIC_BLIP_CHARACTER_VISIBILITY(eBlip, TRUE, CHAR_MICHAEL)
|
|
ENDIF
|
|
|
|
IF IS_MISSION_TRIGGERABLE_BY_CHARACTER(sRCMissionDetails.rcPlayableChars, CHAR_TREVOR)
|
|
SET_STATIC_BLIP_CHARACTER_VISIBILITY(eBlip, TRUE, CHAR_TREVOR)
|
|
ENDIF
|
|
|
|
// B*1566342: Rampage 2-5 are short range
|
|
IF IS_RAMPAGE_MISSION(eRCMission) AND eRCMission <> RC_RAMPAGE_1
|
|
SET_STATIC_BLIP_SHORT_RANGE(eBlip)
|
|
ENDIF
|
|
|
|
// B*1565201: Rampage Blips Should have a tick mark if completed
|
|
IF IS_RAMPAGE_MISSION(eRCMission)
|
|
IF DOES_RAMPAGE_MISSION_NEED_A_CHECKMARK(eRCMission)
|
|
SET_STATIC_BLIP_HAS_CHECKMARK(eBlip, TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Set category and activate.
|
|
IF eRCMission = RC_TONYA_1
|
|
SET_STATIC_BLIP_CATEGORY(eBlip, STATIC_BLIP_CATEGORY_MISSION) //Tonya 1 blip should behave like a mission blip.
|
|
ELSE
|
|
SET_STATIC_BLIP_CATEGORY(eBlip, STATIC_BLIP_CATEGORY_RANDOMCHAR)
|
|
ENDIF
|
|
SET_STATIC_BLIP_ACTIVE_STATE(eBlip, TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Update the stored state so we only perform blip updates once
|
|
g_RandomChars[eRCMission].rcBlipState = eBlipState
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Display blip help text if we haven't done so already
|
|
IF NOT IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcFlags, ENUM_TO_INT(RC_FLAG_BLIP_HELP_DISPLAYED))
|
|
|
|
// No help text for this mission
|
|
IF GET_HASH_KEY(sRCMissionDetails.rcBlipHelp) = GET_HASH_KEY("")
|
|
SET_BIT(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcFlags, ENUM_TO_INT(RC_FLAG_BLIP_HELP_DISPLAYED))
|
|
ELSE
|
|
// RCM ready to trigger...
|
|
IF eBlipState = RC_BLIP_READY_TO_TRIGGER
|
|
IF Is_Mission_Triggerable_By_Character(sRCMissionDetails.rcPlayableChars, GET_CURRENT_PLAYER_PED_ENUM())
|
|
|
|
// Prevent from triggering if timetable scene or player switch is in progress
|
|
IF NOT Is_Player_Timetable_Scene_In_Progress()
|
|
AND NOT IS_PLAYER_SWITCH_IN_PROGRESS()
|
|
|
|
// Help message isn't already onscreen
|
|
IF NOT IS_HELP_MESSAGE_BEING_DISPLAYED()
|
|
|
|
// Flash Tonya 1 blip
|
|
IF eRCMission = RC_TONYA_1
|
|
IF IS_STATIC_BLIP_CURRENTLY_VISIBLE_TO_SYSTEM(STATIC_BLIP_RANDOMCHAR_00)
|
|
IF IS_STATIC_BLIP_CURRENTLY_VISIBLE(STATIC_BLIP_RANDOMCHAR_00)
|
|
ADD_HELP_TO_FLOW_QUEUE(sRCMissionDetails.rcBlipHelp, FHP_MEDIUM, 0, FLOW_HELP_NEVER_EXPIRES, DEFAULT_HELP_TEXT_TIME, sRCMissionDetails.rcPlayableChars)
|
|
EXECUTE_CODE_ID(CID_FLASH_RANDOM_CHAR_BLIPS, 1000)
|
|
SET_BIT(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcFlags, ENUM_TO_INT(RC_FLAG_BLIP_HELP_DISPLAYED))
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Area sub-mission help text delayed by 5 seconds (afeter text/email is received)
|
|
ELIF (eRCMission = RC_BARRY_3A OR eRCMission = RC_NIGEL_1A OR eRCMission = RC_PAPARAZZO_3A)
|
|
|
|
ADD_HELP_TO_FLOW_QUEUE(sRCMissionDetails.rcBlipHelp, FHP_MEDIUM, 5000, FLOW_HELP_NEVER_EXPIRES, DEFAULT_HELP_TEXT_TIME, sRCMissionDetails.rcPlayableChars)
|
|
SET_BIT(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcFlags, ENUM_TO_INT(RC_FLAG_BLIP_HELP_DISPLAYED))
|
|
|
|
// Otherwise display help text as soon as possible
|
|
ELSE
|
|
ADD_HELP_TO_FLOW_QUEUE(sRCMissionDetails.rcBlipHelp, FHP_MEDIUM, 0, FLOW_HELP_NEVER_EXPIRES, DEFAULT_HELP_TEXT_TIME, sRCMissionDetails.rcPlayableChars)
|
|
SET_BIT(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcFlags, ENUM_TO_INT(RC_FLAG_BLIP_HELP_DISPLAYED))
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Check for being near RCM blip as an incorrect character
|
|
IF IS_PLAYER_PLAYING(PLAYER_ID())
|
|
IF NOT HAS_ONE_TIME_HELP_DISPLAYED(FHM_NEAR_FIRST_RCM_AS_WRONG_CHAR)
|
|
|
|
// Make sure this mission hasn't already been completed
|
|
IF IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcFlags, ENUM_TO_INT(RC_FLAG_READY_TO_PLAY))
|
|
AND NOT IS_BIT_SET(g_savedGlobals.sRandomChars.savedRC[eRCMission].rcFlags, ENUM_TO_INT(RC_FLAG_COMPLETED))
|
|
|
|
|
|
IF NOT IS_MISSION_TRIGGERABLE_BY_CHARACTER(sRCMissionDetails.rcPlayableChars, GET_CURRENT_PLAYER_PED_ENUM())
|
|
AND NOT IS_AREA_MISSION(eRCMission)
|
|
AND NOT IS_RAMPAGE_MISSION(eRCMission)
|
|
AND NOT ARE_MULTIPLE_MISSIONS_AVAILABLE_AT_SAME_LOCATE(eRCMission)
|
|
AND NOT HAS_MISSION_JUST_COMPLETED_AT_SAME_LOCATE(eRCMission)
|
|
AND NOT g_RandomChars[eRCMission].rcLeaveAreaCheck
|
|
|
|
IF VDIST2(sRCMissionDetails.rcCoords, GET_ENTITY_COORDS(PLAYER_PED_ID())) < 81
|
|
STRING strHelp = ""
|
|
IF IS_BIT_SET(sRCMissionDetails.rcPlayableChars, ENUM_TO_INT(CHAR_FRANKLIN))
|
|
strHelp = "TRIG_RC_F"
|
|
ELIF IS_BIT_SET(sRCMissionDetails.rcPlayableChars, ENUM_TO_INT(CHAR_MICHAEL))
|
|
strHelp = "TRIG_RC_M"
|
|
ELSE
|
|
strHelp = "TRIG_RC_T"
|
|
ENDIF
|
|
|
|
IF NOT IS_STRING_NULL_OR_EMPTY(strHelp)
|
|
SWITCH GET_FLOW_HELP_MESSAGE_STATUS(strHelp)
|
|
CASE FHS_EXPIRED
|
|
ADD_HELP_TO_FLOW_QUEUE(strHelp, FHP_MEDIUM, 0, 1000, DEFAULT_HELP_TEXT_TIME, GET_CURRENT_PLAYER_PED_BIT())
|
|
BREAK
|
|
CASE FHS_DISPLAYED
|
|
SET_ONE_TIME_HELP_MESSAGE_DISPLAYED(FHM_NEAR_FIRST_RCM_AS_WRONG_CHAR)
|
|
g_txtFlowHelpLastDisplayed = ""
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Turns off all Random Character mission blips
|
|
PROC Turn_Off_Random_Character_Mission_Blips()
|
|
|
|
g_eRC_MissionIDs eRCMission
|
|
|
|
INT iBlip
|
|
REPEAT MAX_RC_BLIPS iBlip
|
|
SET_STATIC_BLIP_ACTIVE_STATE(eRCBlips[iBlip], FALSE)
|
|
bRCBlipActive[iBlip] = FALSE
|
|
ENDREPEAT
|
|
|
|
INT iMission
|
|
REPEAT MAX_RC_MISSIONS iMission
|
|
eRCMission = INT_TO_ENUM(g_eRC_MissionIDs, iMission)
|
|
IF g_RandomChars[eRCMission].rcBlipIndex <> -1
|
|
SET_STATIC_BLIP_ACTIVE_STATE(eRCBlips[g_RandomChars[eRCMission].rcBlipIndex], FALSE)
|
|
Clear_Random_Character_Mission_Blip_Index(g_RandomChars[eRCMission].rcBlipIndex)
|
|
ENDIF
|
|
g_RandomChars[eRCMission].rcBlipState = RC_BLIP_TURNED_OFF
|
|
ENDREPEAT
|
|
|
|
bRCBlipsTurnedOff = TRUE
|
|
ENDPROC
|
|
|
|
|
|
// ===========================================================================================================
|
|
// Cleanup
|
|
// ===========================================================================================================
|
|
|
|
/// PURPOSE:
|
|
/// Ensures script gets a chance to cleanup under specific circumstances (ie: moving from SP to MP)
|
|
PROC Script_Cleanup()
|
|
Turn_Off_Random_Character_Mission_Blips()
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "RandomChar_controller cleaned up.")
|
|
TERMINATE_THIS_THREAD()
|
|
ENDPROC
|
|
|
|
// ===========================================================================================================
|
|
// Script Loop
|
|
// ===========================================================================================================
|
|
|
|
SCRIPT
|
|
// 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_MAGDEMO))
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "RandomChar_controller.sc has been forced to cleanup (SP to MP)")
|
|
Script_Cleanup()
|
|
ENDIF
|
|
|
|
#IF IS_DEBUG_BUILD Setup_RC_Debug_Widgets() #ENDIF
|
|
|
|
// Initialise RC missions + blips
|
|
Initialise_Random_Character_Dynamic_Mission_Details()
|
|
Initialise_Random_Character_Mission_Blips()
|
|
|
|
WHILE (TRUE)
|
|
|
|
WAIT(0)
|
|
|
|
// We have gone on mission
|
|
IF IS_CURRENTLY_ON_MISSION_TO_TYPE(MISSION_TYPE_RANDOM_CHAR)
|
|
OR g_bPlayerLockedInToTrigger
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "RandomChar_controller cleaning up as we have gone on mission...")
|
|
Script_Cleanup()
|
|
ENDIF
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
Maintain_RC_Debug_Widgets()
|
|
#ENDIF
|
|
|
|
IF Is_Controller_Safe_To_Run()
|
|
|
|
// Allow the blips when controller is safe to run
|
|
bRCBlipsTurnedOff = FALSE
|
|
|
|
// Update the frame that we are processing
|
|
iCurrentMissionFrame = (iCurrentMissionFrame+1) % MAX_FRAMES_TO_PROCESS_MISSIONS
|
|
|
|
INT iMission
|
|
REPEAT MAX_RC_MISSIONS iMission
|
|
|
|
// Only perform an update if this mission matches the current frame or has global update flag set
|
|
IF (iMission % MAX_FRAMES_TO_PROCESS_MISSIONS) = iCurrentMissionFrame
|
|
OR g_RandomChars[iMission].rcForceStateUpdate
|
|
Process_Random_Character_Mission_State(INT_TO_ENUM(g_eRC_MissionIDs, iMission))
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
UPDATE_RC_REVEALED_IN_FOW_CHECKS()
|
|
UPDATE_BEVERLY_UNLOCK_WILDLIFE_PHOTOGRAPHY()
|
|
|
|
// Mission help text
|
|
Do_Barry3_Reminder_Help()
|
|
Do_Josh1_For_Sale_Signs_Help()
|
|
Do_Tonya1_Reminder_Help()
|
|
ELSE
|
|
// Controller not safe to run so turn off all blips
|
|
IF NOT bRCBlipsTurnedOff
|
|
Turn_Off_Random_Character_Mission_Blips()
|
|
ENDIF
|
|
ENDIF
|
|
ENDWHILE
|
|
|
|
// Script should never reach here. Always terminate with cleanup function.
|
|
ENDSCRIPT
|