4258 lines
143 KiB
Python
Executable File
4258 lines
143 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 "cutscene_public.sch"
|
|
USING "commands_cutscene.sch"
|
|
USING "commands_entity.sch"
|
|
USING "commands_script.sch"
|
|
USING "script_player.sch"
|
|
USING "randomChar_public.sch"
|
|
USING "dialogue_public.sch"
|
|
USING "script_player.sch"
|
|
USING "shared_hud_displays.sch"
|
|
USING "CompletionPercentage_public.sch"
|
|
USING "randomChar_public.sch"
|
|
USING "RC_Helper_Functions.sch"
|
|
USING "RC_Threat_public.sch"
|
|
USING "RC_Area_public.sch"
|
|
USING "initial_scenes_epsilon.sch"
|
|
USING "commands_recording.sch"
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
USING "select_mission_stage.sch"
|
|
#ENDIF
|
|
|
|
// *****************************************************************************************
|
|
// *****************************************************************************************
|
|
// *****************************************************************************************
|
|
//
|
|
// MISSION NAME : Epsilon4.sc
|
|
// AUTHOR : Sam Hackett (originally)/Ian Gander (July '12 onwards)
|
|
// DESCRIPTION : Track down a "space" rock using a detector
|
|
//
|
|
// *****************************************************************************************
|
|
// *****************************************************************************************
|
|
// *****************************************************************************************
|
|
|
|
|
|
|
|
//*******************************************************************************************************************
|
|
//******************************************************************************************************************* RC VARIABLES
|
|
|
|
// Scene entities from mission launcher
|
|
g_structRCScriptArgs sRCLauncherDataLocal
|
|
CONST_INT ID_MARNIE 0
|
|
CONST_INT ID_JIMMY 1
|
|
|
|
//*******************************************************************************************************************
|
|
//******************************************************************************************************************* POSITIONS
|
|
|
|
VECTOR vPos_WoodsCentre = << 1813.2936, 4698.7852, 38.9553 >>//<< 1812.0585, 4697.6284, 39.0981 >>
|
|
|
|
VECTOR vPos_PlayerReset = << 1827.1781, 4698.1138, 38.1653 >>
|
|
FLOAT fRot_PlayerReset = 187.4554
|
|
|
|
VECTOR vPos_Epsilonian1 = << 1811.9602, 4697.0708, 39.1076 >>
|
|
FLOAT fRot_Epsilonian1 = 330.5137
|
|
|
|
VECTOR vPos_Epsilonian2 = << 1814.0197, 4697.0508, 38.9678 >>
|
|
FLOAT fRot_Epsilonian2 = 24.0044
|
|
|
|
//VECTOR vPos_PlayerFinalScene = << 1860.4711, 4657.4482, 36.3283 >>
|
|
//FLOAT fRot_PlayerFinalScene = 177.3919
|
|
|
|
|
|
CONST_FLOAT fFindRange 6.2 //4.0//2.5
|
|
CONST_FLOAT fNearRange 9.0 //6.0//5.0//30.0//5.0//11.0//10.0//5.5
|
|
CONST_FLOAT fCloseDialogRange 20.0
|
|
|
|
CONST_FLOAT CAPSULE_SIZE 0.965
|
|
|
|
CONST_INT MAX_JGOOD_LINES 8
|
|
CONST_INT MAX_JBAD_LINES 8
|
|
|
|
CONST_INT MAX_MGOOD_LINES 8
|
|
CONST_INT MAX_MBAD_LINES 8
|
|
|
|
CONST_INT MAX_PGOOD_LINES 11
|
|
CONST_INT MAX_PBAD_LINES 12
|
|
|
|
|
|
WEAPON_TYPE weapon_Detector = WEAPONTYPE_DIGISCANNER
|
|
MODEL_NAMES model_Detector = GET_WEAPONTYPE_MODEL(weapon_Detector)
|
|
|
|
//STRING NO_RECENT_ANIM = "noAnim"
|
|
STRING EMPTY_STRING = "empty"
|
|
|
|
//1812.13, 4636.73, 37.78
|
|
|
|
//*******************************************************************************************************************
|
|
//******************************************************************************************************************* DATATYPES
|
|
|
|
//-- Rock
|
|
|
|
STRUCT ROCK_DATA
|
|
MODEL_NAMES model
|
|
OBJECT_INDEX hObject
|
|
|
|
VECTOR vPos
|
|
VECTOR vRot
|
|
|
|
VECTOR vCamPos
|
|
VECTOR vCamRot
|
|
FLOAT fCamFov
|
|
|
|
VECTOR vEpsPos
|
|
// FLOAT fEpsRot
|
|
|
|
FLOAT fMeanderFactor0
|
|
FLOAT fMeanderFactor1
|
|
FLOAT fMeanderAmplitude
|
|
FLOAT fStraightZone
|
|
FLOAT fHotAngle
|
|
|
|
FLOAT fMeterRange
|
|
FLOAT fPostSceneRot
|
|
|
|
VECTOR vAngledArea1
|
|
VECTOR vAngledArea2
|
|
FLOAT fAngledAreaWidth
|
|
|
|
VECTOR vWarpCarPos
|
|
FLOAT fWarpCarRot
|
|
|
|
STRING sChat1Dialogue
|
|
STRING sChat2Dialogue
|
|
STRING sReturn1Dialogue
|
|
STRING sReturn2Dialogue
|
|
STRING sHintGoodDialogue
|
|
STRING sHintBadDialogue
|
|
STRING SHintCloseDialogue
|
|
|
|
ENDSTRUCT
|
|
|
|
STRUCT DETECTOR
|
|
|
|
ENTITY_INDEX hObj
|
|
BOOL bIsOnTarget
|
|
|
|
INT hSndHum
|
|
INT hSndBeep
|
|
INT hSndFound
|
|
INT hSndScan
|
|
|
|
BOOL bIsFoundSoundOn
|
|
BOOL bIsScanSoundOn
|
|
|
|
FLOAT fMeanderFactor0
|
|
FLOAT fMeanderFactor1
|
|
FLOAT fMeanderAmplitude
|
|
FLOAT fStraightZone
|
|
FLOAT fHotAngle
|
|
|
|
BOOL bLockSettings
|
|
|
|
STRING sRecentAnim
|
|
|
|
ENDSTRUCT
|
|
|
|
|
|
//-- Anim markers
|
|
|
|
ENUM ANIM_MARKER_TYPE
|
|
ANIM_MARKER_FORAGE,
|
|
|
|
ANIM_MARKER_DUMMY_JIMMY,
|
|
ANIM_MARKER_DUMMY_PISS,
|
|
ANIM_MARKER_DUMMY_DANCE
|
|
ENDENUM
|
|
|
|
STRUCT ANIM_MARKER
|
|
VECTOR vPos
|
|
FLOAT fRot
|
|
ANIM_MARKER_TYPE type
|
|
BOOL bIsInUse
|
|
ENDSTRUCT
|
|
|
|
//-- Eps characters
|
|
|
|
ENUM EPS_STATE
|
|
EPS_ST_NULL = 0,
|
|
EPS_ST_MOVE,
|
|
EPS_ST_MARKER,
|
|
EPS_ST_IDLE,
|
|
EPS_ST_FOLLOW,
|
|
EPS_ST_CATCHUP
|
|
ENDENUM
|
|
|
|
ENUM STATE_MODE
|
|
SETUP_STATE,
|
|
UPDATE_STATE
|
|
ENDENUM
|
|
|
|
STRUCT EPS_DATA
|
|
PED_INDEX hPed
|
|
EPS_STATE state
|
|
STATE_MODE mode
|
|
INT iAnimMarker
|
|
VECTOR vPlayerStartPos
|
|
BOOL bNotUsingNavmeshMove = FALSE
|
|
ENDSTRUCT
|
|
|
|
//*******************************************************************************************************************
|
|
//******************************************************************************************************************* VARIABLES
|
|
|
|
SCENARIO_BLOCKING_INDEX mScenarioBlocker
|
|
SCENARIO_BLOCKING_INDEX mScenarioBlockerPicnic
|
|
|
|
BLIP_INDEX g_hBlip
|
|
|
|
SCALEFORM_INDEX si_DetectorScaleform
|
|
INT rt_ID
|
|
|
|
SEQUENCE_INDEX seq
|
|
|
|
structPedsForConversation pedsForConversation
|
|
|
|
BOOL bDonePushIn = FALSE
|
|
BOOL bLeadInPlayed = FALSE
|
|
BOOL bLeadInConvo = FALSE
|
|
BOOL bIsPlayerOnTarget = FALSE
|
|
BOOL bIsPlayerAtRock = FALSE
|
|
BOOL bHasPlayerFoundRock = FALSE
|
|
BOOL bIsPlayerInWoods = TRUE
|
|
BOOL bAudDoneChat1 = FALSE
|
|
BOOL bAudDoneChat2 = FALSE
|
|
BOOL bAudDoneChatAll = FALSE
|
|
BOOL bAudDoneClose = FALSE
|
|
BOOL bAudDoneReturn1 = FALSE
|
|
BOOL bAudDoneReturn2 = FALSE
|
|
BOOL bObjDoneHunt = FALSE
|
|
BOOL bObjDoneExamine = FALSE
|
|
BOOL bObjDoneReturnWoods = FALSE
|
|
//BOOL bPlayerSkippedScene = FALSE
|
|
//BOOL bCapsuleResized = FALSE
|
|
BOOL bPlayerUsedAim = FALSE
|
|
|
|
BOOL bFollowerDoingIdle = FALSE
|
|
|
|
BOOL bLockAimPitch = FALSE
|
|
|
|
BOOL bStillOnTarget = FALSE
|
|
|
|
INT iCurrentRock = 0
|
|
|
|
INT iPhaseTimer = 0
|
|
INT iBeepOffTimer = 0
|
|
INT iSupressHintAudioTimer = 0
|
|
INT iSupressPickupAudioTimer = 0
|
|
INT iHintTimer
|
|
INT iFoundWaitTimer
|
|
|
|
GRASS_CULL_SPHERE_HANDLE grassCull
|
|
|
|
CONST_FLOAT DIALOGUE_DIST 30.0
|
|
PED_INDEX hPrimaryBuddy
|
|
|
|
VEHICLE_INDEX Eps_Vehicle
|
|
|
|
CONST_INT ROCK_MAX 4
|
|
ROCK_DATA rockArray[ROCK_MAX]
|
|
INT iRockCount = 0
|
|
|
|
INT iMidtroDelay
|
|
|
|
CONST_INT ANIM_MARKER_MAX 11
|
|
ANIM_MARKER animMarkerArray[ANIM_MARKER_MAX]
|
|
INT iAnimMarkerCount = 0
|
|
|
|
CONST_INT EPSILONIAN_MAX 2
|
|
EPS_DATA epsilonianArray[EPSILONIAN_MAX]
|
|
BOOL epsKnockedOver = FALSE
|
|
PED_INDEX epsPedKnockedOver
|
|
|
|
DETECTOR gDetector
|
|
FLOAT fReading
|
|
CONST_INT LVL3_DISTANCE 80
|
|
CONST_INT LVL2_DISTANCE 50
|
|
OBJECT_INDEX DetectorCopy
|
|
|
|
TEST_POLY g_polyPlayArea
|
|
TEST_POLY g_polyFailArea
|
|
|
|
INT iTutorialLine = 0
|
|
INT iTutorialTimer = 0
|
|
|
|
INT iCurrentMaxGoodLines = 0
|
|
INT iCurrentMaxBadLines = 0
|
|
|
|
INT iSaidGoodLines = 0
|
|
INT iSaidBadLines = 0
|
|
|
|
INT iSaidOnTargetLines = 0
|
|
|
|
INT iNonFollowerCloseLines = 0
|
|
INT iNonFollowerCloseLines1 = 0 // Used when both characters are wandering around during the third object and I need to keep track of two sets of lines...
|
|
INT iNonFollowerCloseLinesTimer = 0
|
|
|
|
//INT g_hMarker_MarnieInitial
|
|
//INT g_hMarker_JimmyInitial
|
|
|
|
//INT g_hDummyMarker_Jimmy
|
|
|
|
INT iFollowIdleTimer
|
|
INT iFollowMessingAroundTimer
|
|
|
|
INT iAimPromptLines = 0
|
|
INT iAimPromptTimer
|
|
|
|
INT g_hDummyMarker_Piss
|
|
INT g_hDummyMarker_Dance
|
|
INT g_hDummyMarker_MarnieIntroForage
|
|
|
|
INT g_hMarker_MarnieAngry
|
|
|
|
INT iNavBlockerBush1 = -1
|
|
INT iNavBlockerBush2 = -1
|
|
INT iNavBlockerBush3 = -1
|
|
|
|
FLOAT fHintFov = 30.0
|
|
FLOAT fHintFollow = 0.35
|
|
FLOAT fHintPitchOrbit = 0.000
|
|
FLOAT fHintSide = 0.02
|
|
FLOAT fHintVert = -0.050
|
|
|
|
//*******************************************************************************************************************
|
|
//******************************************************************************************************************* WIDGETS
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
|
|
USING "shared_debug.sch"
|
|
WIDGET_GROUP_ID widgetGroup
|
|
|
|
BOOL g_DEBUG_DisplayInfo = FALSE
|
|
BOOL bDebug_PrintToTTY = TRUE
|
|
BOOL bDebug_VerboseDetector = FALSE
|
|
|
|
PROC SETUP_EPS4_WIDGETS()
|
|
widgetGroup = START_WIDGET_GROUP("Epsilon 4 widgets")
|
|
ADD_WIDGET_FLOAT_SLIDER("Meander factor", gDetector.fMeanderFactor0, 0.0, 500.0, 1.0)
|
|
ADD_WIDGET_FLOAT_SLIDER("Meander factor", gDetector.fMeanderFactor1, 0.0, 500.0, 1.0)
|
|
ADD_WIDGET_FLOAT_SLIDER("Meander amplitude", gDetector.fMeanderAmplitude, -100.0, 100.0, 1.0)
|
|
ADD_WIDGET_FLOAT_SLIDER("Striaght zone", gDetector.fStraightZone, 0.0, 100.0, 1.0)
|
|
ADD_WIDGET_FLOAT_SLIDER("Hot angle", gDetector.fHotAngle, 0.0, 1.0, 1.0)
|
|
ADD_WIDGET_BOOL("Show info", g_DEBUG_DisplayInfo)
|
|
ADD_WIDGET_BOOL("Lock detector meander settings", gDetector.bLockSettings)
|
|
ADD_WIDGET_BOOL("TTY Toggle - Print Mission Debug Info", bDebug_PrintToTTY)
|
|
ADD_WIDGET_BOOL("Verbose detector debug output (requires TTY Toggle to be on)", bDebug_VerboseDetector)
|
|
STOP_WIDGET_GROUP()
|
|
ENDPROC
|
|
|
|
PROC CLEANUP_EPS4_WIDGETS()
|
|
IF DOES_WIDGET_GROUP_EXIST(widgetGroup)
|
|
DELETE_WIDGET_GROUP(widgetGroup)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
#ENDIF
|
|
|
|
|
|
// ===========================================================================================================
|
|
// Debug prints
|
|
// ===========================================================================================================
|
|
|
|
/// PURPOSE: Print a string to the console
|
|
PROC DEBUG_PRINTSTRING(STRING s)
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDebug_PrintToTTY
|
|
CPRINTLN(DEBUG_MISSION, s)
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
// Stop release compile error
|
|
s = s
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Print a string with a float to the console
|
|
PROC DEBUG_PRINTSF(STRING s, FLOAT f)
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDebug_PrintToTTY
|
|
CPRINTLN(DEBUG_MISSION, s, f)
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
// Stop release compile error
|
|
s = s
|
|
f = f
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Print a string with an int to the console
|
|
PROC DEBUG_PRINTSI(STRING s, INT i)
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDebug_PrintToTTY
|
|
CPRINTLN(DEBUG_MISSION, s, i)
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
// Stop release compile error
|
|
s = s
|
|
i = i
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Print a string with an int to the console
|
|
PROC DEBUG_PRINTBOOL(BOOL b)
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDebug_PrintToTTY
|
|
CPRINTLN(DEBUG_MISSION, b)
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
// Stop release compile error
|
|
b = b
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE: Print a string with an int to the console
|
|
PROC DEBUG_PRINTVECTOR(STRING s, VECTOR v)
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDebug_PrintToTTY
|
|
CPRINTLN(DEBUG_MISSION, s, v)
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
// Stop release compile error
|
|
s = S
|
|
v = v
|
|
|
|
ENDPROC
|
|
|
|
//*******************************************************************************************************************
|
|
//******************************************************************************************************************* ASSET FUNCTIONS
|
|
|
|
/// PURPOSE:
|
|
/// Request and check whether all text we want are loaded
|
|
/// RETURNS:
|
|
/// True when all the text has loaded, False otherwise
|
|
FUNC BOOL LOAD_TEXT()
|
|
// Request
|
|
REQUEST_ADDITIONAL_TEXT("EPS4", MISSION_TEXT_SLOT)
|
|
|
|
// Check
|
|
IF HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT)
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Request and check whether all models we want are loaded
|
|
/// RETURNS:
|
|
/// True when all models are loaded, False otherwise
|
|
FUNC BOOL LOAD_MODELS()
|
|
// Request
|
|
INT i
|
|
REPEAT iRockCount i
|
|
REQUEST_MODEL(rockArray[i].model)
|
|
ENDREPEAT
|
|
REQUEST_MODEL(model_Detector)
|
|
REQUEST_MODEL(Bison)
|
|
|
|
// Check
|
|
REPEAT iRockCount i
|
|
IF NOT HAS_MODEL_LOADED(rockArray[i].model)
|
|
RETURN FALSE
|
|
ENDIF
|
|
ENDREPEAT
|
|
|
|
IF NOT HAS_MODEL_LOADED(model_Detector)
|
|
OR NOT HAS_MODEL_LOADED(Bison)
|
|
RETURN FALSE
|
|
ENDIF
|
|
RETURN TRUE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Request and check for the animations being loaded
|
|
/// RETURNS:
|
|
/// True when all anims are loaded, False otherwise
|
|
FUNC BOOL LOAD_ANIMS()
|
|
// Request
|
|
REQUEST_ANIM_DICT("rcm_epsilonism4")
|
|
REQUEST_ANIM_DICT("rcm_epsilonism4leadinout")
|
|
|
|
// Check
|
|
IF HAS_ANIM_DICT_LOADED("rcm_epsilonism4")
|
|
AND HAS_ANIM_DICT_LOADED("rcm_epsilonism4leadinout")
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Request and check for all assets we wish to use for this mission
|
|
/// RETURNS:
|
|
/// True when all assets are loaded in, False otherwise
|
|
FUNC BOOL LOAD_ASSETS()
|
|
|
|
IF LOAD_TEXT()
|
|
AND LOAD_MODELS()
|
|
AND LOAD_ANIMS()
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Release all requested anims
|
|
PROC RELEASE_ANIMS()
|
|
REMOVE_ANIM_DICT("rcm_epsilonism4")
|
|
REMOVE_ANIM_DICT("rcm_epsilonism4leadinout")
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Set up basic fields for the rock data
|
|
/// PARAMS:
|
|
/// sSceneDialogue - The dialogue string for the scripted scene
|
|
/// model - The model to be used for the 'rock'
|
|
/// vPos - The coords of the rock
|
|
/// vRot - The rotation of the rock
|
|
PROC ADD_ROCK(MODEL_NAMES model, VECTOR vPos, VECTOR vRot)
|
|
|
|
IF iRockCount >= ROCK_MAX
|
|
SCRIPT_ASSERT("ADD_ROCK: Rock array full\n")
|
|
ENDIF
|
|
|
|
INT idx = iRockCount
|
|
iRockCount++
|
|
|
|
rockArray[idx].model = model
|
|
rockArray[idx].vPos = vPos
|
|
rockArray[idx].vRot = vRot
|
|
|
|
rockArray[idx].fMeterRange = 150.0
|
|
rockArray[idx].fPostSceneRot = -1.0
|
|
|
|
rockArray[idx].sChat1Dialogue = EMPTY_STRING
|
|
rockArray[idx].sChat2Dialogue = EMPTY_STRING
|
|
rockArray[idx].sReturn1Dialogue = EMPTY_STRING
|
|
rockArray[idx].sReturn2Dialogue = EMPTY_STRING
|
|
rockArray[idx].sHintGoodDialogue = EMPTY_STRING
|
|
rockArray[idx].sHintBadDialogue = EMPTY_STRING
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Set up camera values for the scripted cutscene for the current rock
|
|
/// PARAMS:
|
|
/// vCamPos - The camera position
|
|
/// vCamRot - The camera rotation
|
|
/// fCamFov - The camera FOV
|
|
PROC SETUP_ROCK_CAM(VECTOR vCamPos, VECTOR vCamRot, FLOAT fCamFov = 50.0)
|
|
|
|
INT idx = iRockCount - 1
|
|
IF idx < 0
|
|
SCRIPT_ASSERT("SETUP_ROCK_CAM: Can't setup rock before adding one\n")
|
|
ENDIF
|
|
|
|
rockArray[idx].vCamPos = vCamPos
|
|
rockArray[idx].vCamRot = vCamRot
|
|
rockArray[idx].fCamFov = fCamFov
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Set up the position the Epsilonists will walk to during the scripted cutscene
|
|
/// PARAMS:
|
|
/// vEpsPos - The coords the Epsilonist will walk to
|
|
PROC SETUP_ROCK_EPS(VECTOR vEpsPos)
|
|
|
|
INT idx = iRockCount - 1
|
|
IF idx < 0
|
|
SCRIPT_ASSERT("SETUP_ROCK_EPS: Can't setup rock before adding one\n")
|
|
ENDIF
|
|
|
|
rockArray[idx].vEpsPos = vEpsPos
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Set up the meander values for the detector
|
|
/// PARAMS:
|
|
/// fMeanderFactor0 - Meander factor value 1
|
|
/// fMeanderFactor1 - Meander factor value 2
|
|
/// fMeanderAmplitude - Meander factor amplitude
|
|
PROC SETUP_ROCK_MEANDER_PATH(FLOAT fMeanderFactor0, FLOAT fMeanderFactor1, FLOAT fMeanderAmplitude)
|
|
|
|
INT idx = iRockCount - 1
|
|
IF idx < 0
|
|
SCRIPT_ASSERT("SETUP_ROCK_MEANDER_PATH: Can't setup rock before adding one\n")
|
|
ENDIF
|
|
|
|
rockArray[idx].fMeanderFactor0 = fMeanderFactor0
|
|
rockArray[idx].fMeanderFactor1 = fMeanderFactor1
|
|
rockArray[idx].fMeanderAmplitude = fMeanderAmplitude
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Set up various detector params for the given rock
|
|
/// PARAMS:
|
|
/// fStraightZone - The straight zone value
|
|
/// fMeterRange - The meter range value
|
|
/// fHotAngle - The hot angle for the detector
|
|
PROC SETUP_ROCK_DETECTION_PARAMS(FLOAT fStraightZone, FLOAT fMeterRange, FLOAT fHotAngle)
|
|
|
|
INT idx = iRockCount - 1
|
|
IF idx < 0
|
|
SCRIPT_ASSERT("SETUP_ROCK_DETECTION_PARAMS: Can't setup rock before adding one\n")
|
|
ENDIF
|
|
|
|
rockArray[idx].fStraightZone = fStraightZone
|
|
rockArray[idx].fMeterRange = fMeterRange
|
|
rockArray[idx].fHotAngle = fHotAngle
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Sets the range for the meter
|
|
/// PARAMS:
|
|
/// fMeterRange - The range we wish to set
|
|
PROC SETUP_ROCK_METER_RANGE(FLOAT fMeterRange)
|
|
|
|
INT idx = iRockCount - 1
|
|
IF idx < 0
|
|
SCRIPT_ASSERT("SETUP_ROCK_METER_RANGE: Can't setup rock before adding one\n")
|
|
ENDIF
|
|
|
|
rockArray[idx].fMeterRange = fMeterRange
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Set up the rotation to be used after the scripted rock cutscene
|
|
/// PARAMS:
|
|
/// fRot - The rotation we wish to set
|
|
PROC SETUP_ROCK_POST_SCENE_ROT(FLOAT fRot)
|
|
|
|
INT idx = iRockCount - 1
|
|
IF idx < 0
|
|
SCRIPT_ASSERT("SETUP_ROCK_POST_SCENE_ROT: Can't setup rock before adding one\n")
|
|
ENDIF
|
|
|
|
rockArray[idx].fPostSceneRot = fRot
|
|
|
|
ENDPROC
|
|
|
|
PROC SETUP_ROCK_AREA(VECTOR vAngledArea1, VECTOR vAngledArea2, FLOAT fAreaWidth)
|
|
|
|
INT idx = iRockCount - 1
|
|
IF idx < 0
|
|
SCRIPT_ASSERT("SETUP_ROCK_AREA: Can't setup rock before adding one\n")
|
|
ENDIF
|
|
|
|
rockArray[idx].vAngledArea1 = vAngledArea1
|
|
rockArray[idx].vAngledArea1 = vAngledArea2
|
|
rockArray[idx].fAngledAreaWidth = fAreaWidth
|
|
|
|
ENDPROC
|
|
/// PURPOSE:
|
|
/// Sets up the location for a car in case needed for the cutscene mode switch
|
|
/// PARAMS:
|
|
/// vPos - The pos of the theoretical car
|
|
/// fRot - The heading of the theoretical car
|
|
PROC SETUP_ROCK_WARP_CAR(VECTOR vPos, FLOAT fRot)
|
|
|
|
INT idx = iRockCount - 1
|
|
IF idx < 0
|
|
SCRIPT_ASSERT("SETUP_ROCK_WARP_CAR: Can't setup rock before adding one\n")
|
|
ENDIF
|
|
|
|
rockArray[idx].vWarpCarPos = vPos
|
|
rockArray[idx].fWarpCarRot = fRot
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Adds dialogue for misc chat while trying to find a certain rock
|
|
/// PARAMS:
|
|
/// sChat1 - First dialogue branch
|
|
/// sChat2 - Second dialogue branch
|
|
PROC SETUP_ROCK_CHAT_DIALOGUE(STRING sChat1, STRING sChat2)
|
|
|
|
INT idx = iRockCount - 1
|
|
IF idx < 0
|
|
SCRIPT_ASSERT("SETUP_ROCK_CHAT_DIALOGUE: Can't setup rock before adding one\n")
|
|
ENDIF
|
|
|
|
rockArray[idx].sChat1Dialogue = sChat1
|
|
rockArray[idx].sChat2Dialogue = sChat2
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Adds dialogue for coming back to the rock path
|
|
/// PARAMS:
|
|
/// sReturn1 - First dialogue branch
|
|
/// sReturn2 - Second dialogue branch
|
|
PROC SETUP_ROCK_RETURN_DIALOGUE(STRING sReturn1, STRING sReturn2)
|
|
|
|
INT idx = iRockCount - 1
|
|
IF idx < 0
|
|
SCRIPT_ASSERT("SETUP_ROCK_RETURN_DIALOGUE: Can't setup rock before adding one\n")
|
|
ENDIF
|
|
|
|
rockArray[idx].sReturn1Dialogue = sReturn1
|
|
rockArray[idx].sReturn2Dialogue = sReturn2
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Adds hint dialogue for current rock being set up
|
|
/// PARAMS:
|
|
/// sGood - The dialogue string for being on track
|
|
/// sBad - The dialogue string for being off the track
|
|
PROC SETUP_ROCK_HINT_DIALOGUE(STRING sGood, STRING sBad)
|
|
|
|
INT idx = iRockCount - 1
|
|
IF idx < 0
|
|
SCRIPT_ASSERT("SETUP_ROCK_HINT_DIALOGUE: Can't setup rock before adding one\n")
|
|
ENDIF
|
|
|
|
rockArray[idx].sHintGoodDialogue = sGood
|
|
rockArray[idx].sHintBadDialogue = sBad
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Adds 'player is close' dialogue for current rock being set up
|
|
/// PARAMS:
|
|
/// sClose - The dialogue string for being close
|
|
PROC SETUP_ROCK_CLOSE_DIALOGUE(STRING sClose)
|
|
|
|
INT idx = iRockCount - 1
|
|
IF idx < 0
|
|
SCRIPT_ASSERT("SETUP_ROCK_CLOSE_DIALOGUE: Can't setup rock before adding one\n")
|
|
ENDIF
|
|
|
|
rockArray[idx].SHintCloseDialogue = sClose
|
|
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Add an animation marker for the Epsilonists to use
|
|
/// PARAMS:
|
|
/// vPos - The coords of the marker
|
|
/// fRot - The heading for the marker (for alignment)
|
|
/// type - What type of marker it is, to set the correct anims
|
|
/// RETURNS:
|
|
/// The int index number of the new marker
|
|
FUNC INT ADD_ANIM_MARKER(VECTOR vPos, FLOAT fRot, ANIM_MARKER_TYPE type)
|
|
|
|
IF iAnimMarkerCount >= ANIM_MARKER_MAX
|
|
SCRIPT_ASSERT("ADD_ANIM_MARKER: Marker array full\n")
|
|
ENDIF
|
|
|
|
INT idx = iAnimMarkerCount
|
|
iAnimMarkerCount++
|
|
|
|
animMarkerArray[idx].vPos = vPos
|
|
animMarkerArray[idx].fRot = fRot
|
|
animMarkerArray[idx].type = type
|
|
animMarkerArray[idx].bIsInUse = FALSE
|
|
|
|
RETURN idx
|
|
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Initialise the data for the rocks and cameras the mission will use
|
|
PROC INIT_DATA()
|
|
|
|
// TV set
|
|
ADD_ROCK(PROP_TV_TEST, << 1751.65, 4676.77, 43.03 >>, <<-2.33, 0.99, 91.36>>)//<< 1834.2987, 4760.5972, 37.9177 >>, 344.5698)
|
|
|
|
SETUP_ROCK_CAM(<< 1755.4631, 4678.6196, 44.1477 >>, << -9.5251, -0.0000, 122.2955 >>, 50.8320)
|
|
SETUP_ROCK_EPS(<<3,-4.5,0>>)
|
|
SETUP_ROCK_WARP_CAR(<< 1689.9510, 4762.6133, 40.9216 >>, 272.5499)
|
|
SETUP_ROCK_AREA(<<1779.514038,4691.447266,39.345768>>, <<1744.224976,4674.646484,46.848289>>, 16.5)
|
|
|
|
SETUP_ROCK_CHAT_DIALOGUE("EPS4_JCHAT1", EMPTY_STRING)//"EPS4_JCHAT2")
|
|
SETUP_ROCK_HINT_DIALOGUE("EPS4_JGOOD", "EPS4_JBAD")
|
|
SETUP_ROCK_RETURN_DIALOGUE("EPS4_JRET1", "EPS4_JRET2")
|
|
SETUP_ROCK_CLOSE_DIALOGUE("EPS4_JCLOSE")
|
|
|
|
//SETUP_ROCK_MEANDER_PATH(113.0, 0.0, 47.0) // Meander settings
|
|
SETUP_ROCK_MEANDER_PATH(0, 0, 0)
|
|
SETUP_ROCK_DETECTION_PARAMS(30.0, 115.0, 0.9)
|
|
|
|
// Old car battery
|
|
ADD_ROCK(PROP_BATTERY_01, << 1756.68, 4832.28, 39.43 >>, <<90.00, 13.21, 78.57>>)//<< 1773.8232, 4792.0288, 38.8912 >>, 127.1792)//178.0357)
|
|
|
|
SETUP_ROCK_CAM(<< 1758.0319, 4826.5605, 41.4590 >>, << -11.6785, -0.0000, 6.5381 >>, 34.3083)//<< 1773.5450, 4796.3384, 40.3945 >>, << -5.3621, -0.0000, -174.0904 >>, 34.3083)//<< 1773.4720, 4796.6479, 40.0057 >>, << -6.5347, 0.0000, -173.2800 >>, 45.0000)//<< 1770.4829, 4792.7202, 40.0238 >>, << -5.4930, 0.0000, -103.2162 >>, 50.8700)//<< 1755.5587, 4787.6787, 41.4211 >>, << -6.6573, 0.0000, -103.4049 >>, 30.2965)
|
|
SETUP_ROCK_EPS(<<2,4,0>>)
|
|
SETUP_ROCK_WARP_CAR(<< 1690.2666, 4769.9937, 40.9216 >>, 269.3043)
|
|
SETUP_ROCK_AREA(<<1750.065308,4833.117188,36.870258>>, <<1763.223755,4831.822266,43.542503>>, 13.75)
|
|
|
|
SETUP_ROCK_CHAT_DIALOGUE("EPS4_MCHAT1", "EPS4_MCHAT2")
|
|
SETUP_ROCK_HINT_DIALOGUE("EPS4_MGOOD", "EPS4_MBAD")
|
|
SETUP_ROCK_RETURN_DIALOGUE("EPS4_MRET1", "EPS4_MRET2")
|
|
SETUP_ROCK_CLOSE_DIALOGUE("EPS4_MCLOSE")
|
|
|
|
//SETUP_ROCK_MEANDER_PATH(307.5, 77.5, 24.0)
|
|
SETUP_ROCK_MEANDER_PATH(0, 0, 0)
|
|
SETUP_ROCK_DETECTION_PARAMS(30.0, 195.0, 0.9)
|
|
|
|
// Old boot
|
|
ADD_ROCK(PROP_OLD_BOOT, << 1847.8630, 4756.0591, 36.71 >>, <<-70.53, 75.48, 132.44>>)//<< 1874.7458, 4722.8452, 37.3642 >>, 76.8130)//<< 1869.2849, 4654.1274, 36.5388 >>, 304.6996)//<< 1876.32, 4725.66, 37.73 >>, -34.33)
|
|
|
|
SETUP_ROCK_CAM(<< 1829.3098, 4756.1582, 42.4876 >>, << -23.5614, -0.0000, -92.2873 >>, 50.0000)//<< 1851.8960, 4753.5889, 38.3750 >>, << -11.3477, -0.0000, 47.3156 >>, 59.2875)//<< 1841.6384, 4756.7441, 39.5189 >>, << -18.2638, -0.0000, -95.7327 >>, 59.2875)
|
|
SETUP_ROCK_EPS(<<7.5, -7.5, 0>>)//<<6.5, -2.4, 0>>)//(<<5.625, -1.875, 0>>)//(<<4.5, -1.5, 0>>)
|
|
SETUP_ROCK_WARP_CAR(<< 1689.7749, 4777.7695, 40.9216 >>, 267.4597)
|
|
SETUP_ROCK_AREA(<<1856.217773,4755.223145,34.671692>>, <<1841.114258,4755.488770,41.434017>>, 13.75)
|
|
|
|
SETUP_ROCK_CHAT_DIALOGUE("EPS4_PCHAT1", "EPS4_PCHAT2")
|
|
SETUP_ROCK_HINT_DIALOGUE("EPS4_PGOOD", "EPS4_PBAD")
|
|
SETUP_ROCK_RETURN_DIALOGUE(EMPTY_STRING, "EPS4_PRET2")
|
|
SETUP_ROCK_CLOSE_DIALOGUE("EPS4_PCLOSE")
|
|
|
|
//SETUP_ROCK_MEANDER_PATH(206.5, 58.5, 25.0)
|
|
SETUP_ROCK_MEANDER_PATH(0, 0, 0)
|
|
SETUP_ROCK_DETECTION_PARAMS(20.5, 155.0, 0.9)
|
|
|
|
|
|
// Add Jimmy + Marnie animation markers
|
|
ADD_ANIM_MARKER(<< 1820.1013, 4701.0986, 38.5450 >>, 280.7432, ANIM_MARKER_FORAGE)
|
|
ADD_ANIM_MARKER(<< 1803.0437, 4700.2441, 39.3123 >>, 72.1396, ANIM_MARKER_FORAGE) // Was originally Marnie initial marker
|
|
ADD_ANIM_MARKER(<< 1820.4816, 4672.5347, 35.6368 >>, 253.4126, ANIM_MARKER_FORAGE) // Was originally Jimmy initial marker
|
|
|
|
ADD_ANIM_MARKER(<< 1819.8701, 4694.0303, 38.4080 >>, 231.2265, ANIM_MARKER_FORAGE)
|
|
ADD_ANIM_MARKER(<< 1807.1217, 4684.4185, 38.5566 >>, 150.6129, ANIM_MARKER_FORAGE)
|
|
ADD_ANIM_MARKER(<< 1791.0580, 4689.4028, 40.5128 >>, 103.4073, ANIM_MARKER_FORAGE)
|
|
|
|
ADD_ANIM_MARKER(<< 1872.6261, 4718.8271, 37.2889 >>, 210.8288, ANIM_MARKER_DUMMY_JIMMY)
|
|
|
|
// g_hDummyMarker_Piss = ADD_ANIM_MARKER(<< 1875.7924, 4718.6582, 37.7000 >>, 179.1472, ANIM_MARKER_DUMMY_PISS)
|
|
g_hDummyMarker_Piss = ADD_ANIM_MARKER(<< 1764.0890, 4665.8794, 42.3031 >>, 281.6336, ANIM_MARKER_DUMMY_PISS)
|
|
g_hDummyMarker_MarnieIntroForage = ADD_ANIM_MARKER(<< 1814.27, 4651.32, 37.58 >>, 173.1089, ANIM_MARKER_FORAGE)
|
|
|
|
g_hDummyMarker_Dance = ADD_ANIM_MARKER(<< 1846.5121, 4705.6143, 38.1214 >>, 25.7591, ANIM_MARKER_DUMMY_DANCE)//<< 1877.3870, 4692.0205, 38.8601 >>, 62.9845, ANIM_MARKER_DUMMY_DANCE)
|
|
|
|
g_hMarker_MarnieAngry = ADD_ANIM_MARKER(<< 1790.4141, 4722.8970, 37.8533 >>, 221.4777, ANIM_MARKER_FORAGE)
|
|
|
|
OPEN_TEST_POLY(g_polyPlayArea)
|
|
ADD_TEST_POLY_VERT(g_polyPlayArea, << 1897.42, 4596.51, 36.40 >>)
|
|
ADD_TEST_POLY_VERT(g_polyPlayArea, << 1912.20, 4676.93, 39.44 >>)
|
|
ADD_TEST_POLY_VERT(g_polyPlayArea, << 1886.09, 4733.68, 39.48 >>)
|
|
ADD_TEST_POLY_VERT(g_polyPlayArea, << 1800.24, 4820.64, 40.96 >>)
|
|
ADD_TEST_POLY_VERT(g_polyPlayArea, << 1796.5560, 4893.5410, 40.4741 >>)
|
|
ADD_TEST_POLY_VERT(g_polyPlayArea, << 1782.6514, 4916.3325, 41.4418 >>)
|
|
ADD_TEST_POLY_VERT(g_polyPlayArea, << 1746.5521, 4942.3618, 42.8677 >>)
|
|
ADD_TEST_POLY_VERT(g_polyPlayArea, << 1702.5366, 4893.8237, 36.7751 >>)
|
|
ADD_TEST_POLY_VERT(g_polyPlayArea, << 1707.2734, 4814.8096, 40.9407 >>)
|
|
ADD_TEST_POLY_VERT(g_polyPlayArea, << 1729.46, 4655.21, 42.61 >>)
|
|
ADD_TEST_POLY_VERT(g_polyPlayArea, << 1772.0504, 4602.1426, 36.4570 >>)
|
|
CLOSE_TEST_POLY(g_polyPlayArea)
|
|
|
|
COPY_EXPANDED_POLY(g_polyFailArea, g_polyPlayArea, 20)
|
|
|
|
ENDPROC
|
|
|
|
|
|
|
|
//*******************************************************************************************************************
|
|
//******************************************************************************************************************* MISSION STAGE DATATYPES
|
|
|
|
ENUM MISSION_STAGE
|
|
MS_NULL = -1,
|
|
|
|
MS_LEADIN,
|
|
MS_INTRO,
|
|
MS_FINDROCK,
|
|
MS_ROCKSCENE,
|
|
MS_WAITTOPASS,
|
|
|
|
MS_PASSED,
|
|
MS_FAILED
|
|
ENDENUM
|
|
|
|
CONST_INT CP_INTRO 0
|
|
CONST_INT CP_FINDROCKA 1
|
|
CONST_INT CP_ROCKSCENEA 2
|
|
CONST_INT CP_FINDROCKB 3
|
|
CONST_INT CP_ROCKSCENEB 4
|
|
CONST_INT CP_FINDROCKC 5
|
|
CONST_INT CP_ROCKSCENEC 6
|
|
CONST_INT MAX_CP 7
|
|
CONST_INT MAX_SKIP_OPTIONS 8
|
|
|
|
ENUM STAGE_SECTION
|
|
SECTION_SETUP = 0,
|
|
SECTION_RUNNING,
|
|
SECTION_FADEOUT,
|
|
SECTION_CLEANUP,
|
|
SECTION_SKIP
|
|
ENDENUM
|
|
|
|
ENUM FAIL_REASON
|
|
FAIL_REASON_DEFAULT,
|
|
FAIL_REASON_PLAYER_DEAD,
|
|
FAIL_REASON_MARNIE_DEAD,
|
|
FAIL_REASON_JIMMY_DEAD,
|
|
FAIL_REASON_MARNIE_INJURED,
|
|
FAIL_REASON_JIMMY_INJURED,
|
|
FAIL_REASON_MARNIE_THREATENED,
|
|
FAIL_REASON_JIMMY_THREATENED,
|
|
FAIL_REASON_LEFT_AREA
|
|
ENDENUM
|
|
|
|
STRUCT MISSION_DATA
|
|
MISSION_STAGE stage
|
|
STAGE_SECTION section
|
|
INT iEvent
|
|
|
|
// A stage can store what stage should be next, then run through it's exit section. At the end of the exit section it will switch to this stage.
|
|
BOOL bSyncForSkip
|
|
BOOL bRequestJSkip
|
|
BOOL bRequestPSkip
|
|
BOOL bRequestCpSkip
|
|
INT queueCpSkip
|
|
|
|
MISSION_STAGE queueNextStage
|
|
|
|
// When the mission goes to fail-state, it should set this so the right message can be displayed
|
|
FAIL_REASON failReason
|
|
|
|
ENDSTRUCT
|
|
|
|
|
|
MISSION_DATA g_mission
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
MissionStageMenuTextStruct zSkipMenu[MAX_SKIP_OPTIONS]
|
|
#ENDIF
|
|
|
|
//*******************************************************************************************************************
|
|
//******************************************************************************************************************* MISSION STAGE FUNCTIONS
|
|
/// PURPOSE:
|
|
/// Initialise the mission data and bools
|
|
PROC INIT_MISSION_DATA()
|
|
g_mission.bRequestJSkip = FALSE
|
|
g_mission.bRequestPSkip = FALSE
|
|
g_mission.bRequestCpSkip = FALSE
|
|
g_mission.bSyncForSkip = FALSE
|
|
g_mission.queueNextStage = MS_NULL
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
zSkipMenu[CP_INTRO].sTxtLabel = "Intro"
|
|
zSkipMenu[CP_FINDROCKA].sTxtLabel = "Find rock A"
|
|
zSkipMenu[CP_ROCKSCENEA].sTxtLabel = "Rock scene A"
|
|
zSkipMenu[CP_FINDROCKB].sTxtLabel = "Find rock B"
|
|
zSkipMenu[CP_ROCKSCENEB].sTxtLabel = "Rock scene B"
|
|
zSkipMenu[CP_FINDROCKC].sTxtLabel = "Find rock C"
|
|
zSkipMenu[CP_ROCKSCENEC].sTxtLabel = "Rock scene C"
|
|
zSkipMenu[7].sTxtLabel = "Toggle Aim Camera pitch lock"
|
|
|
|
INT i
|
|
REPEAT MAX_CP i
|
|
zSkipMenu[i].bSelectable = TRUE
|
|
ENDREPEAT
|
|
#ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Queue a mission stage skip to be executed later
|
|
/// PARAMS:
|
|
/// newStage - The stage we want to skip to
|
|
PROC QUEUE_MISSION_STAGE(MISSION_STAGE newStage)
|
|
g_mission.queueNextStage = newStage
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Queue a skip to the given checkpoint to be executed later
|
|
/// PARAMS:
|
|
/// iCheckpoint - The checkpoint we want to skip to
|
|
PROC QUEUE_CP_SKIP(INT iCheckpoint)
|
|
g_mission.queueCpSkip = iCheckpoint
|
|
g_mission.bRequestCpSkip = TRUE
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Change the mission stage to the stored requested stage
|
|
PROC CHANGE_MISSION_STAGE()
|
|
|
|
// Handle skips
|
|
IF g_mission.bRequestJSkip OR g_mission.bRequestPSkip OR g_mission.bRequestCpSkip
|
|
g_mission.bSyncForSkip = TRUE
|
|
IF g_mission.queueNextStage = MS_INTRO
|
|
DEBUG_PRINTSTRING("Sync for skip is TRUE and Intro is queued!")
|
|
ENDIF
|
|
ELSE
|
|
g_mission.bSyncForSkip = FALSE
|
|
ENDIF
|
|
|
|
IF g_mission.bRequestCpSkip
|
|
SWITCH (g_mission.queueCpSkip)
|
|
CASE CP_INTRO
|
|
g_mission.queueNextStage = MS_INTRO
|
|
BREAK
|
|
|
|
CASE CP_FINDROCKA
|
|
g_mission.queueNextStage = MS_FINDROCK
|
|
iCurrentRock = 0
|
|
BREAK
|
|
|
|
CASE CP_ROCKSCENEA
|
|
g_mission.queueNextStage = MS_ROCKSCENE
|
|
iCurrentRock = 0
|
|
BREAK
|
|
|
|
CASE CP_FINDROCKB
|
|
g_mission.queueNextStage = MS_FINDROCK
|
|
iCurrentRock = 1
|
|
BREAK
|
|
|
|
CASE CP_ROCKSCENEB
|
|
g_mission.queueNextStage = MS_ROCKSCENE
|
|
iCurrentRock = 1
|
|
BREAK
|
|
|
|
CASE CP_FINDROCKC
|
|
g_mission.queueNextStage = MS_FINDROCK
|
|
iCurrentRock = 2
|
|
BREAK
|
|
|
|
CASE CP_ROCKSCENEC
|
|
g_mission.queueNextStage = MS_ROCKSCENE
|
|
iCurrentRock = 2
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
ENDIF
|
|
|
|
g_mission.bRequestJSkip = FALSE
|
|
g_mission.bRequestPSkip = FALSE
|
|
g_mission.bRequestCpSkip = FALSE
|
|
|
|
// Change stage
|
|
|
|
g_mission.stage = g_mission.queueNextStage
|
|
g_mission.section = SECTION_SETUP
|
|
g_mission.iEvent = 0
|
|
|
|
ENDPROC
|
|
|
|
|
|
//*******************************************************************************************************************
|
|
//******************************************************************************************************************* EPS FUNCTIONS
|
|
/// PURPOSE:
|
|
/// Create the Epsilonist we want and set default behaviours, or grab an existing ped index and reset their flags
|
|
/// PARAMS:
|
|
/// eps - The Epsilonist we want
|
|
/// vPos - The position we want to create the Epsilonist at
|
|
/// fRot - The heading of the Epsilonist
|
|
/// hPed - An existing ped index we want to cast as the Epsilonist, if desired
|
|
/// model - The model we want to use for the Epsilonist
|
|
/// RETURNS:
|
|
/// True if the ped exists and is uninjured, False if not
|
|
FUNC BOOL CREATE_EPS(EPS_DATA& eps, VECTOR vPos, FLOAT fRot, PED_INDEX hPed = NULL, MODEL_NAMES model = DUMMY_MODEL_FOR_SCRIPT)
|
|
|
|
IF hPed <> NULL
|
|
eps.hPed = hPed
|
|
DEBUG_PRINTSTRING("*** Epsilonist exists, grabbing ped index")
|
|
ELSE
|
|
eps.hPed = CREATE_PED(PEDTYPE_CIVFEMALE, model, vPos, fRot)
|
|
DEBUG_PRINTSTRING("*** Epsilonist does not exist, creating new")
|
|
ENDIF
|
|
|
|
IF IS_PED_UNINJURED(eps.hPed)
|
|
//SET_ENTITY_CAN_BE_DAMAGED(eps.hPed, FALSE)
|
|
SET_PED_CONFIG_FLAG(eps.hPed, PCF_KeepRelationshipGroupAfterCleanUp, TRUE)
|
|
SET_PED_RELATIONSHIP_GROUP_HASH(eps.hPed, RELGROUPHASH_PLAYER)
|
|
SET_ENTITY_ONLY_DAMAGED_BY_PLAYER(eps.hPed, TRUE)
|
|
SET_PED_CAN_BE_TARGETTED(eps.hPed, FALSE)
|
|
SET_PED_CAN_RAGDOLL_FROM_PLAYER_IMPACT(eps.hPed, TRUE)
|
|
|
|
//TASK_STAND_STILL(eps.hPed, -1)
|
|
SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(eps.hPed, TRUE)
|
|
SET_PED_KEEP_TASK(eps.hPed, TRUE)
|
|
|
|
eps.state = EPS_ST_IDLE
|
|
eps.mode = SETUP_STATE
|
|
eps.iAnimMarker = -1
|
|
|
|
//SET_ENTITY_COORDS(eps.hPed, vPos)
|
|
//SET_ENTITY_HEADING(eps.hPed, fRot)
|
|
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Check for whether the given Epsilonist has been threatened by anyone
|
|
/// PARAMS:
|
|
/// eps - The Epsilonist we want to check
|
|
/// RETURNS:
|
|
/// True if threatened, False otherwise
|
|
FUNC BOOL IS_EPS_THREATENED(EPS_DATA& eps)
|
|
IF IS_ANYONE_SHOOTING_NEAR_PED(eps.hPed)
|
|
RETURN TRUE
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Remove the given Epsilonist from the world
|
|
/// PARAMS:
|
|
/// eps - The Epsilonist we want to delete
|
|
PROC DELETE_EPS(EPS_DATA& eps)
|
|
eps.state = EPS_ST_NULL
|
|
eps.mode = SETUP_STATE
|
|
SAFE_DELETE_PED(eps.hPed)
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Set the passed-in Epsilonist to move around the area going to various destinations randomly, or to the passed in destination
|
|
/// PARAMS:
|
|
/// eps - The Epsilonist we want to move
|
|
/// hDestinationMarker - The (optional) destination we want the Epsilonist to move to
|
|
/// bNoNavmesh - Uses TASK_GO_TO_COORD instead which doesn't use navmesh - much faster, used for Marnie exiting the intro
|
|
PROC SET_EPS_MOVE(EPS_DATA& eps, INT hDestinationMarker = -1)
|
|
IF IS_PED_UNINJURED(eps.hPed)
|
|
eps.state = EPS_ST_MOVE
|
|
eps.mode = SETUP_STATE
|
|
|
|
//CLEAR_PED_TASKS(eps.hPed)
|
|
|
|
IF eps.iAnimMarker <> -1
|
|
animMarkerArray[eps.iAnimMarker].bIsInUse = FALSE
|
|
ENDIF
|
|
|
|
eps.iAnimMarker = hDestinationMarker
|
|
ELSE
|
|
eps.state = EPS_ST_NULL
|
|
eps.mode = SETUP_STATE
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Set the passed in Epsilonists as idle and remove them from the player's group
|
|
/// PARAMS:
|
|
/// eps - The Epsilonist ped
|
|
/// bClearTasksImmediately - Whether we want to clear tasks immediately rather than... not immediately
|
|
PROC SET_EPS_IDLE(EPS_DATA& eps, BOOL bClearTasksImmediately = TRUE)
|
|
IF IS_PED_UNINJURED(eps.hPed)
|
|
eps.state = EPS_ST_IDLE
|
|
eps.mode = SETUP_STATE
|
|
|
|
IF bClearTasksImmediately
|
|
CLEAR_PED_TASKS_IMMEDIATELY(eps.hPed)
|
|
ELSE
|
|
CLEAR_PED_TASKS(eps.hPed)
|
|
ENDIF
|
|
|
|
IF eps.iAnimMarker <> -1
|
|
animMarkerArray[eps.iAnimMarker].bIsInUse = FALSE
|
|
eps.iAnimMarker = -1
|
|
ENDIF
|
|
|
|
IF IS_PED_IN_GROUP(eps.hPed)
|
|
REMOVE_PED_FROM_GROUP(eps.hPed)
|
|
ENDIF
|
|
ELSE
|
|
eps.state = EPS_ST_NULL
|
|
eps.mode = SETUP_STATE
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Immediately warp the given Epsilonist to the given marker
|
|
/// PARAMS:
|
|
/// eps - The Epsilonist
|
|
/// hMarker - The marker ID we want to warp to
|
|
PROC SET_EPS_WARP_TO_MARKER(EPS_DATA& eps, INT hMarker)
|
|
|
|
IF IS_PED_UNINJURED(eps.hPed)
|
|
IF eps.state = EPS_ST_MARKER
|
|
animMarkerArray[hMarker].bIsInUse = FALSE
|
|
ENDIF
|
|
|
|
//CLEAR_PED_TASKS(eps.hPed)
|
|
|
|
eps.state = EPS_ST_MARKER
|
|
eps.mode = SETUP_STATE
|
|
|
|
animMarkerArray[hMarker].bIsInUse = TRUE
|
|
eps.iAnimMarker = hMarker
|
|
|
|
IF IS_PED_IN_GROUP(eps.hPed)
|
|
REMOVE_PED_FROM_GROUP(eps.hPed)
|
|
ENDIF
|
|
|
|
CLEAR_PED_TASKS_IMMEDIATELY(eps.hPed)
|
|
SET_ENTITY_COORDS(eps.hPed, animMarkerArray[hMarker].vPos)
|
|
SET_ENTITY_HEADING(eps.hPed, animMarkerArray[hMarker].fRot)
|
|
ELSE
|
|
eps.state = EPS_ST_NULL
|
|
eps.mode = SETUP_STATE
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Set the given Epsilonist to follow the player around
|
|
/// PARAMS:
|
|
/// eps - The Epsilonist
|
|
/// bTurnToFacePed - Whether want the ped to always try and face the player when they stop moving
|
|
PROC SET_EPS_FOLLOW(EPS_DATA& eps, BOOL bTurnToFacePed = TRUE)
|
|
IF IS_PED_UNINJURED(eps.hPed) AND IS_PED_UNINJURED(PLAYER_PED_ID())
|
|
eps.state = EPS_ST_FOLLOW
|
|
eps.mode = SETUP_STATE
|
|
|
|
//CLEAR_PED_TASKS(eps.hPed)
|
|
|
|
TASK_LOOK_AT_ENTITY(eps.hPed, PLAYER_PED_ID(), -1)
|
|
IF bTurnToFacePed
|
|
TASK_TURN_PED_TO_FACE_ENTITY(eps.hPed, PLAYER_PED_ID())
|
|
ENDIF
|
|
|
|
eps.vPlayerStartPos = GET_ENTITY_COORDS(PLAYER_PED_ID())
|
|
ELSE
|
|
eps.state = EPS_ST_NULL
|
|
eps.mode = SETUP_STATE
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
PROC CHECK_FOR_KNOCKDOWN(PED_INDEX epsPed)
|
|
IF IS_PED_UNINJURED(epsPed)
|
|
AND IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
IF epsKnockedOver = FALSE
|
|
IF IS_ENTITY_TOUCHING_ENTITY(PLAYER_PED_ID(), epsPed)
|
|
AND IS_PED_RAGDOLL(epsPed)
|
|
DEBUG_PRINTSTRING("Player knocked Eps over!")
|
|
epsKnockedOver = TRUE
|
|
epsPedKnockedOver = epsPed // Store which ped got knocked over
|
|
CLEAR_PED_TASKS(epsPed)
|
|
ENDIF
|
|
ELSE
|
|
IF IS_PED_UNINJURED(epsPedKnockedOver)
|
|
IF IS_PED_GETTING_UP(epsPedKnockedOver)
|
|
OR IS_PED_ON_FOOT(epsPedKnockedOver)
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
AND NOT IS_MESSAGE_BEING_DISPLAYED()
|
|
IF epsPedKnockedOver = epsilonianArray[ID_JIMMY].hPed
|
|
IF CREATE_CONVERSATION(pedsForConversation, "EPS4AUD", "EPS4_JKNOCK", CONV_PRIORITY_MEDIUM)
|
|
epsKnockedOver = FALSE
|
|
epsPedKnockedOver = NULL
|
|
ENDIF
|
|
ELSE
|
|
IF CREATE_CONVERSATION(pedsForConversation, "EPS4AUD", "EPS4_MKNOCK", CONV_PRIORITY_MEDIUM)
|
|
epsKnockedOver = FALSE
|
|
epsPedKnockedOver = NULL
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Continually update and check the given Epsilonists behaviour every frame
|
|
/// PARAMS:
|
|
/// eps - The Epsilonist
|
|
PROC UPDATE_EPS(EPS_DATA& eps)
|
|
|
|
IF IS_PED_UNINJURED(eps.hPed) AND IS_PED_IN_GROUP(eps.hPed)
|
|
IF eps.state <> EPS_ST_FOLLOW
|
|
AND eps.state <> EPS_ST_CATCHUP
|
|
REMOVE_PED_FROM_GROUP(eps.hPed)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
CHECK_FOR_KNOCKDOWN(eps.hPed)
|
|
|
|
SWITCH (eps.state)
|
|
CASE EPS_ST_NULL
|
|
BREAK
|
|
|
|
CASE EPS_ST_IDLE
|
|
BREAK
|
|
|
|
CASE EPS_ST_MOVE
|
|
IF NOT IS_PED_UNINJURED(eps.hPed)
|
|
eps.state = EPS_ST_NULL
|
|
eps.mode = SETUP_STATE
|
|
|
|
ELIF eps.mode = SETUP_STATE
|
|
// Try to find a marker to go to (a different one to the previous one)
|
|
INT iRandMarker
|
|
iRandMarker = GET_RANDOM_INT_IN_RANGE(0, iAnimMarkerCount)
|
|
|
|
WHILE eps.iAnimMarker = -1
|
|
IF animMarkerArray[iRandMarker].bIsInUse = FALSE
|
|
IF animMarkerArray[iRandMarker].type = ANIM_MARKER_FORAGE
|
|
IF NOT IS_ENTITY_AT_COORD(eps.hPed, animMarkerArray[iRandMarker].vPos, <<3,3,3>>)
|
|
DEBUG_PRINTSI("Telling ped to go to marker: ", iRandMarker)
|
|
animMarkerArray[iRandMarker].bIsInUse = TRUE
|
|
eps.iAnimMarker = iRandMarker
|
|
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
iRandMarker = (iRandMarker + 1) % iAnimMarkerCount
|
|
ENDWHILE
|
|
|
|
// Go to new marker
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(eps.hPed, animMarkerArray[eps.iAnimMarker].vPos, PEDMOVE_WALK, DEFAULT_TIME_NEVER_WARP, DEFAULT_NAVMESH_RADIUS, ENAV_NO_STOPPING|ENAV_GO_FAR_AS_POSSIBLE_IF_TARGET_NAVMESH_NOT_LOADED)
|
|
eps.mode = UPDATE_STATE
|
|
|
|
ELIF eps.mode = UPDATE_STATE
|
|
IF NOT eps.bNotUsingNavmeshMove
|
|
IF GET_SCRIPT_TASK_STATUS(eps.hPed, SCRIPT_TASK_FOLLOW_NAV_MESH_TO_COORD) = FINISHED_TASK
|
|
DEBUG_PRINTSTRING("Eps reached marker! (follow nav to coord)")
|
|
eps.state = EPS_ST_MARKER
|
|
eps.mode = SETUP_STATE
|
|
ENDIF
|
|
ELSE
|
|
IF GET_SCRIPT_TASK_STATUS(eps.hPed, SCRIPT_TASK_GO_STRAIGHT_TO_COORD) = FINISHED_TASK
|
|
DEBUG_PRINTSTRING("Eps reached marker! (go straight to coord)")
|
|
eps.bNotUsingNavmeshMove = FALSE
|
|
eps.state = EPS_ST_MARKER
|
|
eps.mode = SETUP_STATE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE EPS_ST_MARKER
|
|
IF NOT IS_PED_UNINJURED(eps.hPed)
|
|
eps.state = EPS_ST_NULL
|
|
eps.mode = SETUP_STATE
|
|
|
|
ELIF eps.mode = SETUP_STATE
|
|
DEBUG_PRINTSI("Telling ped do sequence for marker: ", eps.iAnimMarker)
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
|
|
IF animMarkerArray[eps.iAnimMarker].type = ANIM_MARKER_FORAGE
|
|
|
|
IF eps.hPed = epsilonianArray[ID_JIMMY].hPed
|
|
TASK_PLAY_ANIM(null, "rcm_epsilonism4", "eps_4_ig_1_jimmy_lookaround_entry_jb", SLOW_BLEND_IN, SLOW_BLEND_OUT)
|
|
TASK_PLAY_ANIM(null, "rcm_epsilonism4", "eps_4_ig_1_jimmy_lookaround_idle_a_jb", DEFAULT, SLOW_BLEND_OUT)
|
|
TASK_PLAY_ANIM(null, "rcm_epsilonism4", "eps_4_ig_1_jimmy_lookaround_exit_jb", SLOW_BLEND_IN, SLOW_BLEND_OUT)
|
|
ELSE
|
|
TASK_PLAY_ANIM(null, "rcm_epsilonism4", "eps_4_ig_1_marnie_lookaround_entry_marnie", SLOW_BLEND_IN, SLOW_BLEND_OUT)
|
|
TASK_PLAY_ANIM(null, "rcm_epsilonism4", "eps_4_ig_1_marnie_lookaround_idle_a_marnie", DEFAULT, SLOW_BLEND_OUT)
|
|
TASK_PLAY_ANIM(null, "rcm_epsilonism4", "eps_4_ig_1_marnie_lookaround_exit_marnie", SLOW_BLEND_IN, SLOW_BLEND_OUT)
|
|
ENDIF
|
|
|
|
ELIF animMarkerArray[eps.iAnimMarker].type = ANIM_MARKER_DUMMY_PISS
|
|
TASK_ACHIEVE_HEADING(null, animMarkerArray[eps.iAnimMarker].fRot)
|
|
TASK_PLAY_ANIM(null, "rcm_epsilonism4", "peeing")
|
|
|
|
ELIF animMarkerArray[eps.iAnimMarker].type = ANIM_MARKER_DUMMY_DANCE
|
|
TASK_PLAY_ANIM(null, "rcm_epsilonism4", "hippy_a", NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_LOOPING)
|
|
|
|
ELIF animMarkerArray[eps.iAnimMarker].type = ANIM_MARKER_DUMMY_JIMMY
|
|
TASK_PLAY_ANIM(null, "rcm_epsilonism4", "eps_4_ig_1_jimmy_lookaround_entry_jb", SLOW_BLEND_IN, SLOW_BLEND_OUT)
|
|
TASK_PLAY_ANIM(null, "rcm_epsilonism4", "eps_4_ig_1_jimmy_lookaround_idle_a_jb", DEFAULT, SLOW_BLEND_OUT)
|
|
TASK_PLAY_ANIM(null, "rcm_epsilonism4", "eps_4_ig_1_jimmy_lookaround_exit_jb", SLOW_BLEND_IN, SLOW_BLEND_OUT)
|
|
ENDIF
|
|
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(eps.hPed, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
|
|
eps.mode = UPDATE_STATE
|
|
|
|
ELIF eps.mode = UPDATE_STATE
|
|
IF GET_SCRIPT_TASK_STATUS(eps.hPed, SCRIPT_TASK_PERFORM_SEQUENCE) = FINISHED_TASK
|
|
animMarkerArray[eps.iAnimMarker].bIsInUse = FALSE
|
|
eps.iAnimMarker = -1
|
|
|
|
eps.state = EPS_ST_MOVE
|
|
eps.mode = SETUP_STATE
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE EPS_ST_FOLLOW
|
|
IF NOT IS_PED_UNINJURED(eps.hPed)
|
|
eps.state = EPS_ST_NULL
|
|
eps.mode = SETUP_STATE
|
|
|
|
ELIF eps.mode = SETUP_STATE
|
|
IF NOT IS_ENTITY_AT_COORD(PLAYER_PED_ID(), eps.vPlayerStartPos, <<1,1,1>>)//<<1.5,1.5,1.5>>)//<<3,3,3>>)//
|
|
OR iCurrentRock > 0
|
|
IF NOT IS_PED_IN_GROUP(eps.hPed)
|
|
CLEAR_PED_TASKS(eps.hPed)
|
|
SET_PED_AS_GROUP_MEMBER(eps.hPed, PLAYER_GROUP_ID())
|
|
SET_PED_CONFIG_FLAG(eps.hPed,PCF_DontEnterVehiclesInPlayersGroup, TRUE)
|
|
ENDIF
|
|
|
|
iFollowIdleTimer = GET_GAME_TIMER()
|
|
|
|
IF iCurrentRock = 0
|
|
SET_GROUP_FORMATION(PLAYER_GROUP_ID(), FORMATION_LOOSE)//FORMATION_LINE_ABREAST)//FORMATION_LOOSE)//
|
|
ELSE
|
|
SET_GROUP_FORMATION(PLAYER_GROUP_ID(), FORMATION_LOOSE)
|
|
ENDIF
|
|
SET_GROUP_FORMATION_SPACING(PLAYER_GROUP_ID(), 4.0)//4.5)//5.0)//6.0//4.0)//3.0)//2.5)//2.2)//1.8) //1.375)//1.5)//2.2)//1.25)
|
|
eps.mode = UPDATE_STATE
|
|
ENDIF
|
|
|
|
ELIF eps.mode = UPDATE_STATE
|
|
|
|
IF NOT IS_PED_IN_GROUP(eps.hPed)
|
|
eps.state = EPS_ST_CATCHUP
|
|
eps.mode = SETUP_STATE
|
|
ENDIF
|
|
|
|
// If the follower isn't currently moving, wait a few seconds and then do an idle anim
|
|
IF IS_PED_STILL(eps.hPed)
|
|
// If the ped isn't doing the idle, keep checking if the time has passed and then do it
|
|
IF NOT bFollowerDoingIdle
|
|
IF GET_GAME_TIMER() - iFollowIdleTimer > 6000
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
IF eps.hPed = epsilonianArray[ID_JIMMY].hPed
|
|
TASK_PLAY_ANIM(null, "rcm_epsilonism4", "eps_4_ig_1_jimmy_lookaround_entry_jb", SLOW_BLEND_IN, SLOW_BLEND_OUT)
|
|
TASK_PLAY_ANIM(null, "rcm_epsilonism4", "eps_4_ig_1_jimmy_lookaround_idle_a_jb", DEFAULT, SLOW_BLEND_OUT)
|
|
TASK_PLAY_ANIM(null, "rcm_epsilonism4", "eps_4_ig_1_jimmy_lookaround_exit_jb", SLOW_BLEND_IN, SLOW_BLEND_OUT)
|
|
ELSE
|
|
TASK_PLAY_ANIM(null, "rcm_epsilonism4", "eps_4_ig_1_marnie_lookaround_entry_marnie", SLOW_BLEND_IN, SLOW_BLEND_OUT)
|
|
TASK_PLAY_ANIM(null, "rcm_epsilonism4", "eps_4_ig_1_marnie_lookaround_idle_a_marnie", DEFAULT, SLOW_BLEND_OUT)
|
|
TASK_PLAY_ANIM(null, "rcm_epsilonism4", "eps_4_ig_1_marnie_lookaround_exit_marnie", SLOW_BLEND_IN, SLOW_BLEND_OUT)
|
|
ENDIF
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(eps.hPed, seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
AND NOT IS_MESSAGE_BEING_DISPLAYED()
|
|
IF eps.hPed = epsilonianArray[ID_JIMMY].hPed
|
|
CREATE_CONVERSATION(pedsForConversation, "EPS4AUD", "EPS4_DAWDJ", CONV_PRIORITY_MEDIUM)
|
|
ELSE
|
|
CREATE_CONVERSATION(pedsForConversation, "EPS4AUD", "EPS4_DAWDM", CONV_PRIORITY_MEDIUM)
|
|
ENDIF
|
|
ENDIF
|
|
bFollowerDoingIdle = TRUE
|
|
ENDIF
|
|
ELSE
|
|
// Otherwise, if they're doing it, keep resetting the timer, and keep checking if they're not doing it to reset the bool
|
|
iFollowIdleTimer = GET_GAME_TIMER()
|
|
IF NOT IsPedPerformingTask(eps.hPed, SCRIPT_TASK_PERFORM_SEQUENCE)
|
|
bFollowerDoingIdle = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
iFollowIdleTimer = GET_GAME_TIMER()
|
|
bFollowerDoingIdle = FALSE
|
|
ENDIF
|
|
|
|
// Check for player "messing around" and make the following Eps comment on it
|
|
IF IS_PED_SPRINTING(PLAYER_PED_ID())
|
|
OR IS_PED_JUMPING(PLAYER_PED_ID())
|
|
IF GET_GAME_TIMER() - iFollowMessingAroundTimer > 7500
|
|
AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
AND NOT IS_MESSAGE_BEING_DISPLAYED()
|
|
AND NOT bIsPlayerAtRock
|
|
IF eps.hPed = epsilonianArray[ID_JIMMY].hPed
|
|
IF CREATE_CONVERSATION(pedsForConversation, "EPS4AUD", "EPS4_MESSJ", CONV_PRIORITY_MEDIUM)
|
|
iFollowMessingAroundTimer = GET_GAME_TIMER()
|
|
ENDIF
|
|
ELSE
|
|
IF CREATE_CONVERSATION(pedsForConversation, "EPS4AUD", "EPS4_MESSM", CONV_PRIORITY_MEDIUM)
|
|
iFollowMessingAroundTimer = GET_GAME_TIMER()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// If the player hasn't aimed the detector for a while, make the follower comment on it
|
|
IF (GET_GAME_TIMER() - iAimPromptTimer) > 15000 // 15 secs?
|
|
IF iAimPromptLines < 4 // Both characters only have 4 lines, so we can hard-code this to a number
|
|
AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
AND NOT IS_MESSAGE_BEING_DISPLAYED()
|
|
AND NOT bIsPlayerAtRock
|
|
AND NOT IS_PLAYER_IN_FIRST_PERSON_CAMERA()
|
|
IF eps.hPed = epsilonianArray[ID_JIMMY].hPed
|
|
IF CREATE_CONVERSATION(pedsForConversation, "EPS4AUD", "EPS4_PROMPTJ", CONV_PRIORITY_MEDIUM)
|
|
iAimPromptTimer = GET_GAME_TIMER()
|
|
iAimPromptLines++
|
|
ENDIF
|
|
ELSE
|
|
IF CREATE_CONVERSATION(pedsForConversation, "EPS4AUD", "EPS4_PROMPTM", CONV_PRIORITY_MEDIUM)
|
|
iAimPromptTimer = GET_GAME_TIMER()
|
|
iAimPromptLines++
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
CASE EPS_ST_CATCHUP
|
|
IF NOT IS_PED_UNINJURED(eps.hPed)
|
|
eps.state = EPS_ST_NULL
|
|
eps.mode = SETUP_STATE
|
|
|
|
ELIF eps.mode = SETUP_STATE
|
|
TASK_GO_TO_ENTITY(eps.hPed, PLAYER_PED_ID(), DEFAULT_TIME_BEFORE_WARP, 4.5)
|
|
eps.mode = UPDATE_STATE
|
|
|
|
ELIF eps.mode = UPDATE_STATE
|
|
// DISPLAY_TEXT(0.1, 0.1, "CATCHUP")
|
|
SET_PED_AS_GROUP_MEMBER(eps.hPed, PLAYER_GROUP_ID())
|
|
IF IS_PED_IN_GROUP(eps.hPed)
|
|
eps.state = EPS_ST_FOLLOW
|
|
eps.mode = SETUP_STATE
|
|
ENDIF
|
|
ENDIF
|
|
BREAK
|
|
|
|
DEFAULT
|
|
SCRIPT_ASSERT("UPDATE_EPS(): State not supported\n")
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
ENDPROC
|
|
|
|
|
|
//*******************************************************************************************************************
|
|
//******************************************************************************************************************* ROCK FUNCTIONS
|
|
/// PURPOSE:
|
|
/// Create the given rock in the world
|
|
/// PARAMS:
|
|
/// rock - The rock we want to create
|
|
PROC CREATE_ROCK(ROCK_DATA& rock)
|
|
|
|
VECTOR vPos = rock.vPos
|
|
DEBUG_PRINTVECTOR("Rock created at: ", rock.vPos)
|
|
rock.hObject = CREATE_OBJECT_NO_OFFSET(rock.model, vPos)
|
|
|
|
IF DOES_ENTITY_EXIST(rock.hObject)
|
|
SET_ENTITY_ROTATION(rock.hObject, rock.vRot, EULER_XYZ)
|
|
DEBUG_PRINTVECTOR("Rock rot vector: ", GET_ENTITY_ROTATION(rock.hObject, EULER_XYZ))
|
|
DEBUG_PRINTVECTOR("Rock actual position: ", GET_ENTITY_COORDS(rock.hObject, FALSE))
|
|
SET_ENTITY_CAN_BE_DAMAGED(rock.hObject, FALSE)
|
|
FREEZE_ENTITY_POSITION(rock.hObject, TRUE)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Delete all the rocks in the mission
|
|
PROC DELETE_ALL_ROCKS()
|
|
INT i
|
|
REPEAT iRockCount i
|
|
SAFE_DELETE_OBJECT(rockArray[i].hObject)
|
|
ENDREPEAT
|
|
ENDPROC
|
|
|
|
//*******************************************************************************************************************
|
|
//******************************************************************************************************************* DETECTOR FUNCTIONS
|
|
|
|
CONST_FLOAT CONST_fDefaultHotAngle 0.9200
|
|
|
|
/// PURPOSE:
|
|
/// Initialise various detector variables
|
|
PROC INIT_DETECTOR()
|
|
gDetector.hSndHum = GET_SOUND_ID()
|
|
gDetector.hSndBeep = GET_SOUND_ID()
|
|
gDetector.hSndFound = GET_SOUND_ID()
|
|
gDetector.hSndScan = GET_SOUND_ID()
|
|
|
|
gDetector.fHotAngle = CONST_fDefaultHotAngle
|
|
gDetector.bLockSettings = FALSE
|
|
gDetector.sRecentAnim = "NO_RECENT_ANIM"
|
|
|
|
si_DetectorScaleform = REQUEST_SCALEFORM_MOVIE("digiscanner")
|
|
|
|
WHILE NOT HAS_SCALEFORM_MOVIE_LOADED(si_DetectorScaleform)
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
IF NOT IS_NAMED_RENDERTARGET_REGISTERED("digiscanner")
|
|
REGISTER_NAMED_RENDERTARGET("digiscanner")
|
|
ENDIF
|
|
|
|
LINK_NAMED_RENDERTARGET(model_Detector)
|
|
|
|
IF IS_NAMED_RENDERTARGET_REGISTERED("digiscanner")
|
|
rt_ID = GET_NAMED_RENDERTARGET_RENDER_ID("digiscanner")
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Turn the detector on
|
|
/// PARAMS:
|
|
/// fMeanderFactor0 - An override for the first meander factor
|
|
/// fMeanderFactor1 - An override for the second meander factor
|
|
/// fMeanderAmplitude - An override for the meader amplitude
|
|
/// fStraightZone - An override for the straight zone
|
|
/// fHotAngle - An override for the detector hot angle
|
|
PROC START_DETECTOR(FLOAT fMeanderFactor0 = 50.0, FLOAT fMeanderFactor1 = 70.0, FLOAT fMeanderAmplitude = 25.0, FLOAT fStraightZone = 30.0, FLOAT fHotAngle = CONST_fDefaultHotAngle)
|
|
|
|
// Play hum sound
|
|
PLAY_SOUND_FROM_ENTITY(gDetector.hSndHum, "DEVICE", PLAYER_PED_ID(), "EPSILONISM_04_SOUNDSET")
|
|
|
|
// Calculate meander factor
|
|
IF gDetector.bLockSettings = FALSE
|
|
gDetector.fMeanderFactor0 = fMeanderFactor0
|
|
gDetector.fMeanderFactor1 = fMeanderFactor1
|
|
gDetector.fMeanderAmplitude = fMeanderAmplitude
|
|
gDetector.fStraightZone = fStraightZone
|
|
gDetector.fHotAngle = fHotAngle
|
|
ENDIF
|
|
|
|
gDetector.bIsFoundSoundOn = FALSE
|
|
gDetector.bIsScanSoundOn = FALSE
|
|
gDetector.sRecentAnim = "NO_RECENT_ANIM"
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Turn off the detector and prevent it reacting to the rock
|
|
PROC STOP_DETECTOR()
|
|
|
|
// Stop hum sound
|
|
STOP_SOUND(gDetector.hSndHum)
|
|
|
|
// Stop other sounds
|
|
STOP_SOUND(gDetector.hSndBeep)
|
|
STOP_SOUND(gDetector.hSndFound)
|
|
STOP_SOUND(gDetector.hSndScan)
|
|
|
|
gDetector.bIsFoundSoundOn = FALSE
|
|
gDetector.bIsScanSoundOn = FALSE
|
|
|
|
ENDPROC
|
|
|
|
PROC FORCE_NOT_FOUND_SCREEN_ON_DETECTOR()
|
|
BEGIN_SCALEFORM_MOVIE_METHOD(si_DetectorScaleform, "SET_COLOUR")
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(255) //BarsR
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(10) //BarsG
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(10) //BarsB
|
|
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(255) //LightsR
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(10) //LightsG
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(10) //LightsB
|
|
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(255) //WrongWayR
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(10) //WrongWayG
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(10) //WrongWayB
|
|
END_SCALEFORM_MOVIE_METHOD()
|
|
|
|
BEGIN_SCALEFORM_MOVIE_METHOD(si_DetectorScaleform, "SET_DISTANCE")
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_FLOAT(10.0)
|
|
END_SCALEFORM_MOVIE_METHOD()
|
|
|
|
SET_TEXT_RENDER_ID(rt_ID)
|
|
DRAW_SCALEFORM_MOVIE(si_DetectorScaleform, 0.100, 0.24000, 0.2100,0.51000, 100,100,100,255)
|
|
|
|
ENDPROC
|
|
|
|
PROC FORCE_FOUND_SCREEN_ON_DETECTOR()
|
|
|
|
BEGIN_SCALEFORM_MOVIE_METHOD(si_DetectorScaleform, "SET_COLOUR")
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(67) //BarsR
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(200) //BarsG
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(255) //BarsB
|
|
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(255) //LightsR
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(209) //LightsG
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(67) //LightsB
|
|
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(255) //WrongWayR
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(0) //WrongWayG
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(0) //WrongWayB
|
|
END_SCALEFORM_MOVIE_METHOD()
|
|
|
|
BEGIN_SCALEFORM_MOVIE_METHOD(si_DetectorScaleform, "SET_DISTANCE")
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_FLOAT(100.0)
|
|
END_SCALEFORM_MOVIE_METHOD()
|
|
|
|
SET_TEXT_RENDER_ID(rt_ID)
|
|
DRAW_SCALEFORM_MOVIE(si_DetectorScaleform, 0.100, 0.24000, 0.2100,0.51000, 100,100,100,255)
|
|
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Called every frame to update the detector while the player is searching for a rock
|
|
/// PARAMS:
|
|
/// rock - The rock the player is currently searching for
|
|
PROC UPDATE_DETECTOR(ROCK_DATA& rock)
|
|
|
|
CONST_FLOAT fBeepMinDist 6.5//3.0
|
|
CONST_FLOAT fBeepRange 40.0
|
|
|
|
//-- Calc dist, and if facing the target
|
|
|
|
// Calc dist
|
|
FLOAT fDist = VDIST(rock.vPos, GET_ENTITY_COORDS(PLAYER_PED_ID()))
|
|
|
|
// Get distorted-angle forward-vector
|
|
VECTOR vPlayerForward = GET_ENTITY_FORWARD_VECTOR(PLAYER_PED_ID())
|
|
VECTOR vDistortedForward
|
|
|
|
IF fDist > gDetector.fStraightZone
|
|
FLOAT fDistortionAngle = 0.0
|
|
|
|
IF gDetector.fMeanderFactor0 > 0.0
|
|
fDistortionAngle += SIN((fDist-gDetector.fStraightZone) * (360.0 / gDetector.fMeanderFactor0)) * gDetector.fMeanderAmplitude
|
|
ENDIF
|
|
IF gDetector.fMeanderFactor1 > 0.0
|
|
fDistortionAngle += SIN((fDist-gDetector.fStraightZone) * (360.0 / gDetector.fMeanderFactor1)) * (gDetector.fMeanderAmplitude * -0.7)
|
|
ENDIF
|
|
|
|
vDistortedForward.x = (vPlayerForward.x * COS(fDistortionAngle)) - (vPlayerForward.y * SIN(fDistortionAngle))
|
|
vDistortedForward.y = (vPlayerForward.y * COS(fDistortionAngle)) + (vPlayerForward.x * SIN(fDistortionAngle))
|
|
ELSE
|
|
vDistortedForward = vPlayerForward
|
|
ENDIF
|
|
|
|
// Get other useful vectors
|
|
VECTOR vPlayerToRock1 = rock.vPos - GET_ENTITY_COORDS(PLAYER_PED_ID()) // Is rock ahead of player? (180 degrees)
|
|
VECTOR vPlayerToRock2 = rock.vPos - GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(PLAYER_PED_ID(), <<0,-5,0>>) // Is rock in cone? (starting cone slightly behind player)
|
|
|
|
// Calc is-in-front
|
|
BOOL bIsInFrontOfPlayer = vPlayerToRock1.x*vDistortedForward.x + vPlayerToRock1.y*vDistortedForward.y > 0.0
|
|
FLOAT fAngle = 1.0 - (GET_ANGLE_BETWEEN_2D_VECTORS(vDistortedForward.x, vDistortedForward.y, vPlayerToRock2.x, vPlayerToRock2.y) / 180.0)
|
|
// Adjust the hot angle depending on distance to the artefact
|
|
if fDist >= 10
|
|
gDetector.fHotAngle = CONST_fDefaultHotAngle
|
|
ELSE
|
|
gDetector.fHotAngle = 0.95
|
|
ENDIF
|
|
BOOL bOnTarget = (fAngle > gDetector.fHotAngle) AND bIsInFrontOfPlayer
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
IF g_DEBUG_DisplayInfo
|
|
DRAW_RECT_FROM_CORNER(0.03, 0.18, 0.3, (0.2 + (0.05*4)) - 0.18, 0,0,0, 100)
|
|
|
|
TEXT_LABEL_63 sDebugStr
|
|
|
|
// sDebugStr = "Meander phase dist 0: "
|
|
// sDebugStr += GET_STRING_FROM_FLOAT(gDetector.fMeanderFactor0)
|
|
// SET_TEXT_SCALE(0.7, 0.6)
|
|
// DISPLAY_TEXT_WITH_LITERAL_STRING(0.05, (0.2 + (0.05*1)), "STRING", sDebugStr)
|
|
//
|
|
// sDebugStr = "Meander phase dist 1: "
|
|
// sDebugStr += GET_STRING_FROM_FLOAT(gDetector.fMeanderFactor1)
|
|
// SET_TEXT_SCALE(0.7, 0.6)
|
|
// DISPLAY_TEXT_WITH_LITERAL_STRING(0.05, (0.2 + (0.05*2)), "STRING", sDebugStr)
|
|
//
|
|
// sDebugStr = "Meander amplitude: "
|
|
// sDebugStr += GET_STRING_FROM_FLOAT(gDetector.fMeanderAmplitude)
|
|
// SET_TEXT_SCALE(0.7, 0.6)
|
|
// DISPLAY_TEXT_WITH_LITERAL_STRING(0.05, (0.2 + (0.05*0)), "STRING", sDebugStr)
|
|
|
|
sDebugStr = "Dist to target: "
|
|
sDebugStr += GET_STRING_FROM_FLOAT(VDIST(GET_ENTITY_COORDS(PLAYER_PED_ID()), rock.vPos))
|
|
SET_TEXT_SCALE(0.7, 0.6)
|
|
DISPLAY_TEXT_WITH_LITERAL_STRING(0.05, (0.2 + (0.05*3)), "STRING", sDebugStr)
|
|
|
|
sDebugStr = "Current angle: "
|
|
sDebugStr += GET_STRING_FROM_FLOAT(fAngle)
|
|
SET_TEXT_SCALE(0.7, 0.6)
|
|
DISPLAY_TEXT_WITH_LITERAL_STRING(0.05, (0.2 + (0.05*0)), "STRING", sDebugStr)
|
|
|
|
// VECTOR vRockPos
|
|
// vRockPos = GET_ENTITY_COORDS(rockArray[0].hObject, FALSE)
|
|
// sDebugStr = "rock 0 z: "
|
|
// sDebugStr += GET_STRING_FROM_FLOAT(vRockPos.z)
|
|
// SET_TEXT_SCALE(0.7, 0.6)
|
|
// DISPLAY_TEXT_WITH_LITERAL_STRING(0.05, (0.2 + (0.05*3)), "STRING", sDebugStr)
|
|
//
|
|
// vRockPos = GET_ENTITY_COORDS(rockArray[1].hObject, FALSE)
|
|
// sDebugStr = "rock 1 z: "
|
|
// sDebugStr += GET_STRING_FROM_FLOAT(vRockPos.z)
|
|
// SET_TEXT_SCALE(0.7, 0.6)
|
|
// DISPLAY_TEXT_WITH_LITERAL_STRING(0.05, (0.2 + (0.05*4)), "STRING", sDebugStr)
|
|
//
|
|
// vRockPos = GET_ENTITY_COORDS(rockArray[2].hObject, FALSE)
|
|
// sDebugStr = "rock 2 z: "
|
|
// sDebugStr += GET_STRING_FROM_FLOAT(vRockPos.z)
|
|
// SET_TEXT_SCALE(0.7, 0.6)
|
|
// DISPLAY_TEXT_WITH_LITERAL_STRING(0.05, (0.2 + (0.05*5)), "STRING", sDebugStr)
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
gDetector.bIsOnTarget = bOnTarget
|
|
|
|
//-- Manage radar beep
|
|
|
|
IF gDetector.bIsFoundSoundOn = TRUE
|
|
SET_CONTROL_SHAKE(PLAYER_CONTROL, 200, 150)
|
|
|
|
IF fDist > fBeepMinDist
|
|
OR bOnTarget = FALSE
|
|
STOP_SOUND(gDetector.hSndFound)
|
|
gDetector.bIsFoundSoundOn = FALSE
|
|
iPhaseTimer = 0
|
|
ENDIF
|
|
|
|
ELIF iPhaseTimer < GET_GAME_TIMER()
|
|
|
|
IF fDist <= fBeepMinDist AND bOnTarget
|
|
STOP_SOUND(gDetector.hSndBeep)
|
|
PLAY_SOUND_FROM_ENTITY(gDetector.hSndFound, "CONTINUAL_BEEP", PLAYER_PED_ID(), "EPSILONISM_04_SOUNDSET")
|
|
gDetector.bIsFoundSoundOn = TRUE
|
|
ELSE
|
|
// Set cycle length
|
|
FLOAT fBeepDist = fDist - (fBeepMinDist + 2.5)
|
|
IF fBeepDist < 0
|
|
fBeepDist = 0
|
|
ENDIF
|
|
|
|
INT iInterval = 125 + ROUND( (fBeepDist / fBeepRange) * (1250.0 - 125.0) )
|
|
|
|
IF iInterval > 1250
|
|
iInterval = 1250
|
|
ENDIF
|
|
|
|
iPhaseTimer = GET_GAME_TIMER() + iInterval
|
|
|
|
iInterval /= 3
|
|
IF iInterval < 100
|
|
iInterval = 100
|
|
ENDIF
|
|
|
|
iBeepOffTimer = GET_GAME_TIMER() + iInterval
|
|
|
|
// Play beep + shake pad
|
|
PLAY_SOUND_FROM_ENTITY(gDetector.hSndBeep, "IDLE_BEEP", PLAYER_PED_ID(), "EPSILONISM_04_SOUNDSET")
|
|
|
|
IF bOnTarget
|
|
SET_CONTROL_SHAKE(PLAYER_CONTROL, 200, 150)
|
|
ELSE
|
|
SET_CONTROL_SHAKE(PLAYER_CONTROL, 200, 100)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Stop beep sound
|
|
IF iBeepOffTimer > 0
|
|
AND GET_GAME_TIMER() > iBeepOffTimer
|
|
STOP_SOUND(gDetector.hSndBeep)
|
|
iBeepOffTimer = 0
|
|
ENDIF
|
|
|
|
//-- Manage on-target sound
|
|
IF IS_AIM_CAM_ACTIVE()
|
|
IF gDetector.bIsScanSoundOn = FALSE
|
|
PLAY_SOUND_FROM_ENTITY(gDetector.hSndScan, "SCAN", PLAYER_PED_ID(), "EPSILONISM_04_SOUNDSET")
|
|
gDetector.bIsScanSoundOn = TRUE
|
|
ELSE
|
|
IF bOnTarget
|
|
SET_VARIABLE_ON_SOUND(gDetector.hSndScan, "IsOnTarget", 1.0)
|
|
ELSE
|
|
SET_VARIABLE_ON_SOUND(gDetector.hSndScan, "IsOnTarget", 0.0)
|
|
ENDIF
|
|
ENDIF
|
|
iAimPromptTimer = GET_GAME_TIMER() // Keep resetting this timer while the player is aiming
|
|
ELSE
|
|
IF gDetector.bIsScanSoundOn = TRUE
|
|
STOP_SOUND(gDetector.hSndScan)
|
|
gDetector.bIsScanSoundOn = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
//-- Manage proximity meter
|
|
|
|
IF NOT DOES_ENTITY_EXIST(gDetector.hObj)
|
|
gDetector.hObj = GET_CURRENT_PED_WEAPON_ENTITY_INDEX(PLAYER_PED_ID())
|
|
ELSE
|
|
FLOAT fProx = (fDist - fBeepMinDist) / (rock.fMeterRange - fBeepMinDist) // Normalise for range
|
|
IF fProx < 0.0
|
|
fProx = 0.0
|
|
ELIF fProx > 1.0
|
|
fProx = 1.0
|
|
ENDIF
|
|
|
|
IF gDetector.bIsOnTarget
|
|
fReading = 100 - (fProx * 100.0)
|
|
ELSE
|
|
fReading = 100 - (fProx * 100.0)
|
|
fReading = fReading*-1.0
|
|
ENDIF
|
|
|
|
// IF IS_AIM_CAM_ACTIVE()
|
|
// DRAW_SCALEFORM_MOVIE_FULLSCREEN(si_DetectorScaleform, 100, 100, 100, 255)
|
|
// ENDIF
|
|
|
|
IF NOT gDetector.bIsOnTarget
|
|
BEGIN_SCALEFORM_MOVIE_METHOD(si_DetectorScaleform, "SET_COLOUR")
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(255) //BarsR
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(10) //BarsG
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(10) //BarsB
|
|
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(255) //LightsR
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(10) //LightsG
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(10) //LightsB
|
|
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(255) //WrongWayR
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(10) //WrongWayG
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(10) //WrongWayB
|
|
END_SCALEFORM_MOVIE_METHOD()
|
|
ELSE
|
|
BEGIN_SCALEFORM_MOVIE_METHOD(si_DetectorScaleform, "SET_COLOUR")
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(67) //BarsR
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(200) //BarsG
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(255) //BarsB
|
|
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(255) //LightsR
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(209) //LightsG
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(67) //LightsB
|
|
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(255) //WrongWayR
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(0) //WrongWayG
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_INT(0) //WrongWayB
|
|
END_SCALEFORM_MOVIE_METHOD()
|
|
ENDIF
|
|
|
|
// Cap the reading value so the last bar doesn't get filled until you're very close
|
|
IF fReading >= 95.0
|
|
AND fReading <= 99.8
|
|
fReading = 94.9
|
|
ELIF fReading <= -95.0
|
|
AND fReading >= -99.8
|
|
fReading = -94.9
|
|
ENDIF
|
|
|
|
// If the player is at the find range for the object, force the distance bar to full just in case it's not
|
|
IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), rockArray[iCurrentRock].vPos, << fFindRange,fFindRange,2.0 >>, FALSE, FALSE, TM_ON_FOOT)
|
|
fReading = 100.0
|
|
ENDIF
|
|
|
|
BEGIN_SCALEFORM_MOVIE_METHOD(si_DetectorScaleform, "SET_DISTANCE")
|
|
SCALEFORM_MOVIE_METHOD_ADD_PARAM_FLOAT(fReading)
|
|
END_SCALEFORM_MOVIE_METHOD()
|
|
|
|
SET_TEXT_RENDER_ID(rt_ID)
|
|
DRAW_SCALEFORM_MOVIE(si_DetectorScaleform, 0.100, 0.24000, 0.2100,0.51000, 100,100,100,255)
|
|
|
|
// This is the old meter in the corner of the screen, from before the scaleform for the detector was created
|
|
// Technically it's not needed anymore, but let's keep it around just in case it's handy for debug,
|
|
// or if the scaleform breaks in a future build or something
|
|
// IF IS_AIM_CAM_ACTIVE()
|
|
// //PRINTFLOAT(fReading) PRINTNL()
|
|
// IF bOnTarget
|
|
// DRAW_TIMER_HUD(100 + (900 - CEIL(fProx * 900.0)), 1000, "EPS4_B0")
|
|
// ELSE
|
|
// DRAW_TIMER_HUD(0, 1000, "EPS4_B0")
|
|
// ENDIF
|
|
// ENDIF
|
|
ENDIF
|
|
|
|
//-- Manage player body anims
|
|
|
|
IF IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_AIM)
|
|
// Player is using device -> start body anim, and pause on first frame
|
|
SET_PED_MAX_MOVE_BLEND_RATIO(PLAYER_PED_ID(), PEDMOVEBLENDRATIO_WALK)
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_JUMP)
|
|
IF bLockAimPitch
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH(15)
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_LOOK_UD)
|
|
ENDIF
|
|
bPlayerUsedAim = TRUE
|
|
ELSE
|
|
IF IS_PLAYER_IN_FIRST_PERSON_CAMERA()
|
|
bPlayerUsedAim = TRUE
|
|
ENDIF
|
|
// Player not using device -> kill body anim
|
|
// IF IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), "rcm_epsilonism4", "detector_pulls_forwards_loop")
|
|
// STOP_ANIM_TASK(PLAYER_PED_ID(), "rcm_epsilonism4", "detector_pulls_forwards_loop", WALK_BLEND_OUT)
|
|
// ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
//PROC ATTEMPT_GRAB_DETECTOR()
|
|
// gDetector.hObj = GET_CURRENT_PED_WEAPON_ENTITY_INDEX(PLAYER_PED_ID())
|
|
// gDetector.sRecentAnim = NO_RECENT_ANIM
|
|
//
|
|
//// IF DOES_ENTITY_EXIST(gDetector.hObj)
|
|
//// PLAY_ENTITY_ANIM(gDetector.hObj, "detector_level1_prop", "rcm_epsilonism4", INSTANT_BLEND_IN, TRUE, FALSE, FALSE)
|
|
//// gDetector.sRecentAnim = detector_level1_prop
|
|
//// ENDIF
|
|
//ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// Checks if the detector exists in the world
|
|
/// RETURNS:
|
|
/// True if the detector exists, False otherwise
|
|
FUNC BOOL DOES_DETECTOR_EXIST()
|
|
IF DOES_ENTITY_EXIST(gDetector.hObj)
|
|
RETURN TRUE
|
|
ENDIF
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
FUNC BOOL CHECK_FAIL_CONDITIONS_DURING_CUTSCENE()
|
|
IF IS_ENTITY_DEAD(PLAYER_PED_ID())
|
|
QUEUE_MISSION_STAGE(MS_FAILED)
|
|
g_mission.failReason = FAIL_REASON_PLAYER_DEAD
|
|
g_mission.section = SECTION_CLEANUP
|
|
RETURN TRUE
|
|
|
|
ELIF IS_ENTITY_DEAD(epsilonianArray[ID_MARNIE].hPed)
|
|
IF iCurrentRock < 2 // Only check this if we're not on the final cutscene - otherwise when we delete the ped, this will trigger and fail the mission!
|
|
QUEUE_MISSION_STAGE(MS_FAILED)
|
|
g_mission.failReason = FAIL_REASON_MARNIE_DEAD
|
|
g_mission.section = SECTION_CLEANUP
|
|
DEBUG_PRINTSTRING("Mission failed: Marnie dead")
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
ELIF IS_ENTITY_DEAD(epsilonianArray[ID_JIMMY].hPed)
|
|
IF iCurrentRock < 2 // Only check this if we're not on the final cutscene - otherwise when we delete the ped, this will trigger and fail the mission!
|
|
QUEUE_MISSION_STAGE(MS_FAILED)
|
|
g_mission.failReason = FAIL_REASON_JIMMY_DEAD
|
|
g_mission.section = SECTION_CLEANUP
|
|
DEBUG_PRINTSTRING("Mission failed: Jimmy dead")
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
ELIF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(epsilonianArray[ID_MARNIE].hPed, PLAYER_PED_ID(), TRUE)
|
|
AND HAS_ENTITY_BEEN_DAMAGED_BY_WEAPON(epsilonianArray[ID_MARNIE].hPed, WEAPONTYPE_INVALID, GENERALWEAPON_TYPE_ANYWEAPON)
|
|
QUEUE_MISSION_STAGE(MS_FAILED)
|
|
g_mission.failReason = FAIL_REASON_MARNIE_INJURED
|
|
g_mission.section = SECTION_CLEANUP
|
|
DEBUG_PRINTSTRING("Mission failed: Marnie injured")
|
|
RETURN TRUE
|
|
|
|
ELIF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(epsilonianArray[ID_JIMMY].hPed, PLAYER_PED_ID(), TRUE)
|
|
AND HAS_ENTITY_BEEN_DAMAGED_BY_WEAPON(epsilonianArray[ID_JIMMY].hPed, WEAPONTYPE_INVALID, GENERALWEAPON_TYPE_ANYWEAPON)
|
|
QUEUE_MISSION_STAGE(MS_FAILED)
|
|
g_mission.failReason = FAIL_REASON_JIMMY_INJURED
|
|
g_mission.section = SECTION_CLEANUP
|
|
DEBUG_PRINTSTRING("Mission failed: Jimmy injured")
|
|
RETURN TRUE
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
ENDFUNC
|
|
|
|
/// PURPOSE:
|
|
/// Update the animations on the player and detector depending on the direction the player is currently facing
|
|
/// PARAMS:
|
|
/// bIsPlayerFacingTarget - Whether the player is facing the rock or not
|
|
PROC UPDATE_PLAYER_AND_DETECTOR_ANIMS(BOOL bIsPlayerFacingTarget)
|
|
|
|
//-- Player body anims
|
|
|
|
// IF IS_AIM_CAM_ACTIVE()
|
|
//
|
|
// // Player is using device -> start body anim, and pause on first frame
|
|
// IF NOT IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), "rcm_epsilonism4", "detector_pulls_forwards_loop")
|
|
// TASK_PLAY_ANIM(PLAYER_PED_ID(), "rcm_epsilonism4", "detector_pulls_forwards_loop", 2, -2, -1, AF_SECONDARY|AF_UPPERBODY|AF_LOOPING)//|AF_DELAY_BLEND_WHEN_FINISHED)
|
|
// ELSE
|
|
// SET_ENTITY_ANIM_CURRENT_TIME(PLAYER_PED_ID(), "rcm_epsilonism4", "detector_pulls_forwards_loop", 0.0)
|
|
// SET_ENTITY_ANIM_SPEED(PLAYER_PED_ID(), "rcm_epsilonism4", "detector_pulls_forwards_loop", 0.0)
|
|
// ENDIF
|
|
//
|
|
// ELSE
|
|
//
|
|
// // Player not using device -> kill body anim
|
|
// IF IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), "rcm_epsilonism4", "detector_pulls_forwards_loop")
|
|
// STOP_ANIM_TASK(PLAYER_PED_ID(), "rcm_epsilonism4", "detector_pulls_forwards_loop", WALK_BLEND_OUT)
|
|
// ENDIF
|
|
//
|
|
// ENDIF
|
|
|
|
// Stop player from being able to autovault things
|
|
//SET_PED_RESET_FLAG(PLAYER_PED_ID(), PRF_DisablePlayerAutoVaulting, TRUE)
|
|
|
|
//-- Detector anims
|
|
|
|
IF bIsPlayerFacingTarget = TRUE
|
|
|
|
// Player is facing target -> Keep running random anims on the detector
|
|
IF DOES_DETECTOR_EXIST()
|
|
// If there is no anim runnning on the detector, start one
|
|
IF ARE_STRINGS_EQUAL(gDetector.sRecentAnim, "NO_RECENT_ANIM")
|
|
OR NOT IS_ENTITY_PLAYING_ANIM(gDetector.hObj, "rcm_epsilonism4", gDetector.sRecentAnim)
|
|
OR GET_ENTITY_ANIM_CURRENT_TIME(gDetector.hObj, "rcm_epsilonism4", gDetector.sRecentAnim) >= 0.98
|
|
// Choose one of the detector reaction anims based on distance to the target
|
|
|
|
IF fReading > LVL3_DISTANCE
|
|
gDetector.sRecentAnim = "detector_level3_prop"
|
|
ELIF fReading > LVL2_DISTANCE
|
|
gDetector.sRecentAnim = "detector_level2_prop"
|
|
ELSE
|
|
gDetector.sRecentAnim = "detector_level1_prop"
|
|
ENDIF
|
|
|
|
// Play the anim (no looping)
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDebug_VerboseDetector
|
|
DEBUG_PRINTSF("fReading: ", fReading)
|
|
DEBUG_PRINTSTRING("PLAY_ENTITY_ANIM: ")
|
|
DEBUG_PRINTSTRING(gDetector.sRecentAnim)
|
|
DEBUG_PRINTSI("Time: ", GET_GAME_TIMER())
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
PLAY_ENTITY_ANIM(gDetector.hObj, gDetector.sRecentAnim, "rcm_epsilonism4", FAST_BLEND_IN, FALSE, FALSE, FALSE)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
// Player is facing away -> Stop any detector anims
|
|
IF DOES_DETECTOR_EXIST()
|
|
// Check if an animation is currently playing, it will need to be stopped
|
|
IF NOT ARE_STRINGS_EQUAL(gDetector.sRecentAnim, "NO_RECENT_ANIM")
|
|
IF IS_ENTITY_PLAYING_ANIM(gDetector.hObj, "rcm_epsilonism4", gDetector.sRecentAnim, ANIM_SCRIPT)
|
|
IF GET_ENTITY_ANIM_CURRENT_TIME(gDetector.hObj, "rcm_epsilonism4", gDetector.sRecentAnim) <= 0.05
|
|
|
|
// Stop the anim
|
|
#IF IS_DEBUG_BUILD
|
|
IF bDebug_VerboseDetector
|
|
DEBUG_PRINTSTRING("STOP_ENTITY_ANIM:")
|
|
DEBUG_PRINTSTRING(gDetector.sRecentAnim)
|
|
DEBUG_PRINTSI("Time: ", GET_GAME_TIMER())
|
|
DEBUG_PRINTSTRING("IS_ENTITY_PLAYING_ANIM: ")
|
|
DEBUG_PRINTBOOL(IS_ENTITY_PLAYING_ANIM(gDetector.hObj, "rcm_epsilonism4", gDetector.sRecentAnim, ANIM_SCRIPT))
|
|
DEBUG_PRINTSTRING("HAS_ENTITY_ANIM_FINISHED: ")
|
|
DEBUG_PRINTBOOL(HAS_ENTITY_ANIM_FINISHED(gDetector.hObj, "rcm_epsilonism4", gDetector.sRecentAnim, ANIM_SCRIPT))
|
|
ENDIF
|
|
#ENDIF
|
|
|
|
STOP_ENTITY_ANIM(gDetector.hObj, gDetector.sRecentAnim, "rcm_epsilonism4", SLOW_BLEND_OUT)
|
|
gDetector.sRecentAnim = "NO_RECENT_ANIM"
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
FUNC BOOL DO_MICHAEL_EXIT()
|
|
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Michael")
|
|
IF iCurrentRock >= 2
|
|
DEBUG_PRINTSTRING("*** Forcing Michael's move state (end cutscene)")
|
|
FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_IDLE, FALSE, FAUS_CUTSCENE_EXIT)
|
|
RETURN TRUE
|
|
ELSE
|
|
DEBUG_PRINTSTRING("*** Forcing Michael's move state")
|
|
IF GET_PEDS_CURRENT_WEAPON(PLAYER_PED_ID()) != weapon_Detector
|
|
GIVE_WEAPON_TO_PED(PLAYER_PED_ID(), weapon_Detector, INFINITE_AMMO, TRUE)
|
|
ENDIF
|
|
FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_IDLE, FALSE, FAUS_CUTSCENE_EXIT)
|
|
RETURN TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
RETURN FALSE
|
|
|
|
ENDFUNC
|
|
|
|
PROC DO_DETECTOR_EXIT()
|
|
|
|
IF IS_ENTITY_ALIVE(DetectorCopy)
|
|
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Artefact_Detector")
|
|
IF iCurrentRock < 2
|
|
DEBUG_PRINTSTRING("*** Detector exit")
|
|
GIVE_WEAPON_OBJECT_TO_PED(DetectorCopy, PLAYER_PED_ID())
|
|
SAFE_DELETE_OBJECT(DetectorCopy)
|
|
IF NOT DOES_ENTITY_EXIST(gDetector.hObj)
|
|
DEBUG_PRINTSTRING("*** Recreating gDetector.hObj after cutscene...")
|
|
gDetector.hObj = GET_CURRENT_PED_WEAPON_ENTITY_INDEX(PLAYER_PED_ID())
|
|
ENDIF
|
|
ELSE
|
|
DEBUG_PRINTSTRING("*** Detector exit (end cutscene)")
|
|
SAFE_DELETE_OBJECT(DetectorCopy)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
SEQUENCE_INDEX seqExit
|
|
|
|
PROC DO_MARNIE_INTRO_EXIT()
|
|
|
|
IF IS_ENTITY_ALIVE(epsilonianArray[ID_MARNIE].hPed)
|
|
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Marnie")
|
|
SET_EPS_MOVE(epsilonianArray[ID_MARNIE], g_hDummyMarker_MarnieIntroForage)
|
|
epsilonianArray[ID_MARNIE].state = EPS_ST_MOVE
|
|
epsilonianArray[ID_MARNIE].mode = UPDATE_STATE
|
|
|
|
IF epsilonianArray[ID_MARNIE].iAnimMarker <> -1
|
|
animMarkerArray[epsilonianArray[ID_MARNIE].iAnimMarker].bIsInUse = FALSE
|
|
ENDIF
|
|
|
|
epsilonianArray[ID_MARNIE].iAnimMarkeR = g_hDummyMarker_MarnieIntroForage
|
|
TASK_GO_STRAIGHT_TO_COORD(epsilonianArray[ID_MARNIE].hPed, animMarkerArray[epsilonianArray[ID_MARNIE].iAnimMarker].vPos, PEDMOVE_WALK, DEFAULT_TIME_NEVER_WARP)
|
|
FORCE_PED_MOTION_STATE(epsilonianArray[ID_MARNIE].hPed, MS_ON_FOOT_WALK, FALSE, FAUS_CUTSCENE_EXIT, TRUE)
|
|
epsilonianArray[ID_MARNIE].bNotUsingNavmeshMove = TRUE
|
|
DEBUG_PRINTSTRING("Done Marnie intro exit state")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
PROC DO_MARNIE_EXIT()
|
|
IF IS_ENTITY_ALIVE(epsilonianArray[ID_MARNIE].hPed)
|
|
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Marnie")
|
|
IF iCurrentRock >= 2
|
|
IF IS_ENTITY_ALIVE(sRCLauncherDataLocal.pedID[ID_MARNIE])
|
|
AND IS_VEHICLE_OK(Eps_Vehicle)
|
|
OPEN_SEQUENCE_TASK(seqExit)
|
|
//TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sRCLauncherDataLocal.pedID[ID_MARNIE], <<0, 4, 0>>), PEDMOVEBLENDRATIO_WALK, DEFAULT, DEFAULT, ENAV_NO_STOPPING|ENAV_GO_FAR_AS_POSSIBLE_IF_TARGET_NAVMESH_NOT_LOADED)
|
|
TASK_WARP_PED_INTO_VEHICLE(NULL, Eps_Vehicle, VS_DRIVER)
|
|
//TASK_ENTER_VEHICLE(NULL, Eps_Vehicle, DEFAULT, VS_DRIVER, PEDMOVEBLENDRATIO_WALK, ECF_WARP_IF_DOOR_IS_BLOCKED|ECF_RESUME_IF_INTERRUPTED)
|
|
//TASK_PAUSE(NULL, 4500)
|
|
TASK_VEHICLE_DRIVE_TO_COORD(NULL, Eps_Vehicle, <<1743.33, 4962.18, 45.16>>, 20, DRIVINGSTYLE_NORMAL, BISON, DRIVINGMODE_AVOIDCARS_STOPFORPEDS_OBEYLIGHTS, 5, -1)
|
|
TASK_VEHICLE_DRIVE_WANDER(NULL, Eps_Vehicle, 30, DRIVINGMODE_STOPFORCARS_STRICT)
|
|
CLOSE_SEQUENCE_TASK(seqExit)
|
|
TASK_PERFORM_SEQUENCE(sRCLauncherDataLocal.pedID[ID_MARNIE], seqExit)
|
|
CLEAR_SEQUENCE_TASK(seqExit)
|
|
DEBUG_PRINTSTRING("Did Marnie pass exit")
|
|
ENDIF
|
|
ELSE
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(sRCLauncherDataLocal.pedID[ID_MARNIE], GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sRCLauncherDataLocal.pedID[ID_MARNIE], <<0, 7, 0>>), PEDMOVEBLENDRATIO_WALK, DEFAULT, DEFAULT, ENAV_NO_STOPPING|ENAV_GO_FAR_AS_POSSIBLE_IF_TARGET_NAVMESH_NOT_LOADED)
|
|
DEBUG_PRINTSTRING("Did Marnie regular exit")
|
|
ENDIF
|
|
FORCE_PED_MOTION_STATE(epsilonianArray[ID_MARNIE].hPed, MS_ON_FOOT_WALK, FALSE, FAUS_CUTSCENE_EXIT)
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
PROC DO_JIMMY_INTRO_EXIT()
|
|
IF IS_ENTITY_ALIVE(epsilonianArray[ID_JIMMY].hPed)
|
|
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Jimmy_Boston")
|
|
FLOAT fZ
|
|
GET_GROUND_Z_FOR_3D_COORD(<<1829.80, 4693.48, 38.50>>, fZ)
|
|
SET_ENTITY_COORDS(epsilonianArray[ID_JIMMY].hPed, <<1829.80, 4693.48, fZ>>)
|
|
//FORCE_PED_MOTION_STATE(epsilonianArray[ID_MARNIE].hPed, MS_ON_FOOT_IDLE, FALSE, FAUS_CUTSCENE_EXIT, TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
PROC DO_JIMMY_EXIT()
|
|
IF IS_ENTITY_ALIVE(epsilonianArray[ID_JIMMY].hPed)
|
|
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Jimmy_Boston")
|
|
IF iCurrentRock >= 2
|
|
IF IS_ENTITY_ALIVE(sRCLauncherDataLocal.pedID[ID_JIMMY])
|
|
AND IS_VEHICLE_OK(Eps_Vehicle)
|
|
OPEN_SEQUENCE_TASK(seqExit)
|
|
//TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, GET_OFFSET_FROM_ENTITY_IN_WORLD_COORDS(sRCLauncherDataLocal.pedID[ID_JIMMY], <<0, 2, 0>>), PEDMOVEBLENDRATIO_WALK, DEFAULT, DEFAULT, ENAV_NO_STOPPING|ENAV_GO_FAR_AS_POSSIBLE_IF_TARGET_NAVMESH_NOT_LOADED)
|
|
TASK_WARP_PED_INTO_VEHICLE(NULL, Eps_Vehicle, VS_FRONT_RIGHT)
|
|
//TASK_ENTER_VEHICLE(NULL, Eps_Vehicle, DEFAULT, VS_FRONT_RIGHT, PEDMOVEBLENDRATIO_WALK, ECF_WARP_IF_DOOR_IS_BLOCKED|ECF_RESUME_IF_INTERRUPTED)
|
|
CLOSE_SEQUENCE_TASK(seqExit)
|
|
TASK_PERFORM_SEQUENCE(sRCLauncherDataLocal.pedID[ID_JIMMY], seqExit)
|
|
CLEAR_SEQUENCE_TASK(seqExit)
|
|
DEBUG_PRINTSTRING("Did Jimmy pass exit")
|
|
ENDIF
|
|
ELSE
|
|
TASK_GO_STRAIGHT_TO_COORD(sRCLauncherDataLocal.pedID[ID_JIMMY], <<1764.0890, 4665.8794, 42.3031>>, PEDMOVEBLENDRATIO_WALK)
|
|
DEBUG_PRINTSTRING("Did Jimmy regular exit")
|
|
ENDIF
|
|
FORCE_PED_MOTION_STATE(epsilonianArray[ID_JIMMY].hPed, MS_ON_FOOT_WALK, FALSE, FAUS_CUTSCENE_EXIT)
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
// ===========================================================================================================
|
|
// Termination
|
|
// ===========================================================================================================
|
|
|
|
// -----------------------------------------------------------------------------------------------------------
|
|
// Script Cleanup
|
|
// -----------------------------------------------------------------------------------------------------------
|
|
/// PURPOSE:
|
|
/// Clean up text in the script
|
|
PROC Script_TextCleanup()
|
|
// Could this be included in normal clean up?
|
|
STOP_SCRIPTED_CONVERSATION(FALSE)
|
|
CLEAR_PRINTS()
|
|
IF IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("EPS4_T0")
|
|
OR IS_THIS_HELP_MESSAGE_BEING_DISPLAYED("EPS4_T1")
|
|
CLEAR_HELP(TRUE)
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
/// PURPOSE:
|
|
/// General script cleanup function
|
|
PROC Script_Cleanup()
|
|
|
|
// Ensure launcher is cleaned up
|
|
RC_CLEANUP_LAUNCHER()
|
|
|
|
// If the mission was triggered then additional mission cleanup will be required.
|
|
IF (Random_Character_Cleanup_If_Triggered())
|
|
DEBUG_PRINTSTRING("...Random Character Script was triggered so additional cleanup required") PRINTNL()
|
|
ENDIF
|
|
|
|
// Cleanup scene entities created by the RC launcher
|
|
//RC_CleanupSceneEntities(sRCLauncherDataLocal, FALSE)
|
|
|
|
IF IS_PED_UNINJURED(PLAYER_PED_ID())
|
|
// Remove gadget
|
|
REMOVE_WEAPON_FROM_PED(PLAYER_PED_ID(), weapon_Detector)
|
|
SET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_UNARMED, TRUE)
|
|
CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
SET_PED_CAPSULE(PLAYER_PED_ID(), 0)
|
|
ENDIF
|
|
|
|
IF IS_NEW_LOAD_SCENE_ACTIVE()
|
|
NEW_LOAD_SCENE_STOP()
|
|
ENDIF
|
|
|
|
REMOVE_GRASS_CULL_SPHERE(grassCull)
|
|
|
|
IF IS_ENTITY_ALIVE(epsilonianArray[ID_MARNIE].hPed)
|
|
AND IS_ENTITY_ALIVE(epsilonianArray[ID_JIMMY].hPed)
|
|
IF IS_PED_IN_GROUP(epsilonianArray[ID_MARNIE].hPed)
|
|
REMOVE_PED_FROM_GROUP(epsilonianArray[ID_MARNIE].hPed)
|
|
ELIF IS_PED_IN_GROUP(epsilonianArray[ID_JIMMY].hPed)
|
|
REMOVE_PED_FROM_GROUP(epsilonianArray[ID_JIMMY].hPed)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SAFE_RELEASE_PED(epsilonianArray[ID_MARNIE].hPed, TRUE, TRUE)
|
|
SAFE_RELEASE_PED(epsilonianArray[ID_JIMMY].hPed, TRUE, TRUE)
|
|
|
|
RELEASE_NAMED_RENDERTARGET("digiscanner")
|
|
|
|
REMOVE_SCENARIO_BLOCKING_AREA(mScenarioBlocker)
|
|
REMOVE_SCENARIO_BLOCKING_AREA(mScenarioBlockerPicnic)
|
|
REMOVE_NAVMESH_BLOCKING_OBJECT(iNavBlockerBush1)
|
|
REMOVE_NAVMESH_BLOCKING_OBJECT(iNavBlockerBush2)
|
|
REMOVE_NAVMESH_BLOCKING_OBJECT(iNavBlockerBush3)
|
|
|
|
IF IS_AUDIO_SCENE_ACTIVE("EPSILONISM_04_MIX")
|
|
DEBUG_PRINTSTRING("Stopping dynamic mix EPSILONISM_04_MIX")
|
|
STOP_AUDIO_SCENE("EPSILONISM_04_MIX")
|
|
ENDIF
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
CLEANUP_EPS4_WIDGETS()
|
|
#ENDIF
|
|
|
|
TERMINATE_THIS_THREAD()
|
|
ENDPROC
|
|
|
|
// -----------------------------------------------------------------------------------------------------------
|
|
// Script Pass
|
|
// -----------------------------------------------------------------------------------------------------------
|
|
|
|
PROC Script_Passed()
|
|
|
|
HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_WEAPON_ICON)
|
|
|
|
IF bPlayerUsedAim = FALSE
|
|
INFORM_STAT_SYSTEM_OF_BOOL_STAT_HAPPENED(EP4_ARTIFACT_DETECTOR_USED)
|
|
ENDIF
|
|
|
|
STOP_DETECTOR()
|
|
Script_TextCleanup()
|
|
DISABLE_CELLPHONE(FALSE)
|
|
ADD_CONTACT_TO_PHONEBOOK(CHAR_JIMMY_BOSTON, MICHAEL_BOOK)
|
|
|
|
Random_Character_Passed(CP_RAND_C_EPS4)
|
|
|
|
// Reset donations - pity the fool who has donated more than asked for before this point..
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "Resetting donation to Epsilon Program for new mission request.")
|
|
g_savedGlobals.sRandomChars.g_iCurrentEpsilonPayment = 0
|
|
|
|
IF NOT IS_REPEAT_PLAY_ACTIVE()
|
|
WHILE NOT REGISTER_EMAIL_FROM_CHARACTER_TO_PLAYER(EMAIL_EPSILON4_DONATE, CT_AMBIENT, BIT_MICHAEL, CHAR_MARNIE, 30000, 10000)
|
|
WAIT(0)
|
|
ENDWHILE
|
|
CPRINTLN(DEBUG_RANDOM_CHAR, "Queued $10,000 donation reminder email")
|
|
ENDIF
|
|
|
|
// Wait 1 second before doing the holster animation, then do it, then clean up the script
|
|
REQUEST_ANIM_DICT("weapons@holster_1h")
|
|
WHILE GET_PEDS_CURRENT_WEAPON(PLAYER_PED_ID()) = weapon_Detector
|
|
WAIT(0)
|
|
HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_WEAPON_ICON)
|
|
IF HAS_ANIM_DICT_LOADED("weapons@holster_1h")
|
|
IF NOT IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), "weapons@holster_1h", "holster")
|
|
TASK_PLAY_ANIM(PLAYER_PED_ID(), "weapons@holster_1h", "holster")
|
|
ELSE
|
|
IF GET_ENTITY_ANIM_CURRENT_TIME(PLAYER_PED_ID(), "weapons@holster_1h", "holster") >= 0.5
|
|
SET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_UNARMED, TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDWHILE
|
|
|
|
//Set epsilon step stat
|
|
INT iCurrent
|
|
STAT_GET_INT(NUM_EPSILON_STEP,iCurrent)
|
|
IF iCurrent < 12
|
|
STAT_SET_INT(NUM_EPSILON_STEP,12)
|
|
SET_ACHIEVEMENT_PROGRESS_SAFE(ENUM_TO_INT(ACH20),12)
|
|
CPRINTLN(debug_dan,"Epsilon progress:",12)
|
|
ENDIF
|
|
|
|
Script_Cleanup()
|
|
|
|
ENDPROC
|
|
|
|
//*******************************************************************************************************************
|
|
//*******************************************************************************************************************
|
|
|
|
PROC STAGE_LEADIN()
|
|
|
|
// Disable controls and exit current vehicle
|
|
RC_PLAYER_TRIGGER_SCENE_LOCK_IN()
|
|
|
|
IF g_mission.bSyncForSkip = TRUE
|
|
RC_START_Z_SKIP()
|
|
DEBUG_PRINTSTRING("SKIP: Doing sync for leadin skip")
|
|
RC_END_Z_SKIP()
|
|
g_mission.bSyncForSkip = FALSE
|
|
ENDIF
|
|
|
|
IF g_mission.section = SECTION_SETUP
|
|
|
|
iPhaseTimer = GET_GAME_TIMER()
|
|
|
|
IF NOT IS_REPEAT_PLAY_ACTIVE()
|
|
AND IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<1826.621216,4698.734375,41.368622>>, <<1831.157593,4680.191406,32.426258>>, 16.50)
|
|
DEBUG_PRINTSTRING("Doing setup for leadin")
|
|
ADD_PED_FOR_DIALOGUE(pedsForConversation, 4, sRCLauncherDataLocal.pedID[ID_MARNIE], "MARNIE")
|
|
IF LOAD_ANIMS() // Loops here until anims are loaded
|
|
g_mission.section = SECTION_RUNNING
|
|
ENDIF
|
|
ELSE
|
|
DEBUG_PRINTSTRING("Skipping setup for leadin (repeat play/wrong area)")
|
|
g_mission.section = SECTION_RUNNING
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF g_mission.section = SECTION_RUNNING
|
|
|
|
IF (GET_GAME_TIMER() - iPhaseTimer) > 1250
|
|
PLAY_SOUND_FROM_COORD(-1, "IDLE_BEEP_NPC", <<1827.06, 4700.52, 39.16>>, "EPSILONISM_04_SOUNDSET")
|
|
iPhaseTimer = GET_GAME_TIMER()
|
|
ENDIF
|
|
|
|
IF NOT IS_REPEAT_PLAY_ACTIVE() // Don't do the leadin if we're on a repeat-play, just go into the cutscene
|
|
AND IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<1826.621216,4698.734375,41.368622>>, <<1831.157593,4680.191406,32.426258>>, 16.50)
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), sRCLauncherDataLocal.pedID[ID_MARNIE]) >= 3.0
|
|
IF NOT IS_GAMEPLAY_HINT_ACTIVE()
|
|
IF NOT bDonePushIn
|
|
IF IS_ENTITY_ALIVE(sRCLauncherDataLocal.pedID[ID_MARNIE])
|
|
SET_GAMEPLAY_ENTITY_HINT(sRCLauncherDataLocal.pedID[ID_MARNIE], <<0,0,0.2>>, TRUE, 30000)
|
|
SET_GAMEPLAY_HINT_FOV(fHintFov)
|
|
SET_GAMEPLAY_HINT_FOLLOW_DISTANCE_SCALAR(fHintFollow)
|
|
SET_GAMEPLAY_HINT_BASE_ORBIT_PITCH_OFFSET(fHintPitchOrbit)
|
|
SET_GAMEPLAY_HINT_CAMERA_RELATIVE_SIDE_OFFSET(fHintSide)
|
|
SET_GAMEPLAY_HINT_CAMERA_RELATIVE_VERTICAL_OFFSET(fHintVert)
|
|
SET_GAMEPLAY_HINT_CAMERA_BLEND_TO_FOLLOW_PED_MEDIUM_VIEW_MODE(TRUE)
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
OPEN_SEQUENCE_TASK(seq)
|
|
TASK_LOOK_AT_ENTITY(NULL, sRCLauncherDataLocal.pedID[ID_MARNIE], 15000)
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(NULL, <<1827.34, 4697.22, 38.02>>, PEDMOVEBLENDRATIO_WALK, DEFAULT_TIME_BEFORE_WARP, DEFAULT_NAVMESH_RADIUS, ENAV_NO_STOPPING)
|
|
TASK_TURN_PED_TO_FACE_ENTITY(NULL, sRCLauncherDataLocal.pedID[ID_MARNIE])
|
|
CLOSE_SEQUENCE_TASK(seq)
|
|
TASK_PERFORM_SEQUENCE(PLAYER_PED_ID(), seq)
|
|
CLEAR_SEQUENCE_TASK(seq)
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
|
|
ENDIF
|
|
bDonePushIn = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
STOP_GAMEPLAY_HINT_BEING_CANCELLED_THIS_UPDATE(TRUE)
|
|
ENDIF
|
|
ELSE
|
|
bDonePushIn = TRUE // Stop trying to do the push in
|
|
ENDIF
|
|
IF NOT bLeadInPlayed
|
|
IF IS_PED_UNINJURED(sRCLauncherDataLocal.pedID[ID_MARNIE])
|
|
AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
TASK_LOOK_AT_ENTITY(sRCLauncherDataLocal.pedID[ID_MARNIE], PLAYER_PED_ID(), -1, SLF_WIDEST_PITCH_LIMIT|SLF_WIDEST_YAW_LIMIT)
|
|
TASK_PLAY_ANIM(sRCLauncherDataLocal.pedID[ID_MARNIE], "rcm_epsilonism4leadinout", "ep_4_rcm_leadin_marnie",NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_HOLD_LAST_FRAME) // Marnie
|
|
REMOVE_CUTSCENE()
|
|
REQUEST_CUTSCENE_WITH_PLAYBACK_LIST("EP_4_RCM_CONCAT", CS_SECTION_2)
|
|
DEBUG_PRINTSTRING("Done Marnie leadin anim - request concat cutscene")
|
|
bLeadInPlayed = TRUE
|
|
ENDIF
|
|
ELSE
|
|
IF IS_PED_UNINJURED(sRCLauncherDataLocal.pedID[ID_MARNIE])
|
|
IF IS_ENTITY_PLAYING_ANIM(sRCLauncherDataLocal.pedID[ID_MARNIE], "rcm_epsilonism4leadinout", "ep_4_rcm_leadin_marnie")
|
|
IF GET_ENTITY_ANIM_CURRENT_TIME(sRCLauncherDataLocal.pedID[ID_MARNIE], "rcm_epsilonism4leadinout", "ep_4_rcm_leadin_marnie") > 0.25
|
|
IF NOT bLeadInConvo
|
|
IF CREATE_CONVERSATION(pedsForConversation, "EPS4AUD", "ESP4_RCL", CONV_PRIORITY_HIGH)
|
|
DEBUG_PRINTSTRING("Leadin convo done")
|
|
bLeadInConvo = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
IF GET_ENTITY_ANIM_CURRENT_TIME(sRCLauncherDataLocal.pedID[ID_MARNIE], "rcm_epsilonism4leadinout", "ep_4_rcm_leadin_marnie") > 0.95
|
|
DEBUG_PRINTSTRING("Leadin done, launch cutscene")
|
|
QUEUE_MISSION_STAGE(MS_INTRO)
|
|
g_mission.section = SECTION_CLEANUP
|
|
ENDIF
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), sRCLauncherDataLocal.pedID[ID_MARNIE]) <= 1.5
|
|
// Stop the player if they get too close
|
|
SET_PLAYER_CONTROL(PLAYER_ID(), FALSE)
|
|
CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
DEBUG_PRINTSTRING("Replay in progress/wrong area, skipping leadin")
|
|
QUEUE_MISSION_STAGE(MS_INTRO)
|
|
g_mission.section = SECTION_CLEANUP
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF g_mission.section = SECTION_CLEANUP
|
|
DEBUG_PRINTSTRING("Doing leadin cleanup and progressing")
|
|
CHANGE_MISSION_STAGE()
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
//STAGE: INTRO
|
|
/// PURPOSE:
|
|
/// Main loop for the intro stage
|
|
PROC STAGE_INTRO()
|
|
|
|
IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY()
|
|
DEBUG_PRINTSTRING("Can request assets for cutscene entity in Eps 4")
|
|
SET_CUTSCENE_PED_PROP_VARIATION("Jimmy_Boston", ANCHOR_EYES, 0)
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED_SAFE("Michael", PLAYER_PED_ID())
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF g_mission.bSyncForSkip = TRUE
|
|
RC_START_Z_SKIP()
|
|
|
|
REMOVE_CUTSCENE()
|
|
DEBUG_PRINTSTRING("SKIP: Doing sync for intro skip")
|
|
IF NOT IS_REPEAT_PLAY_ACTIVE()
|
|
RC_END_Z_SKIP()
|
|
ENDIF
|
|
g_mission.bSyncForSkip = FALSE
|
|
ENDIF
|
|
|
|
|
|
IF g_mission.section = SECTION_SETUP
|
|
|
|
// b* 2363991 - moved to inside SECTION_SETUP
|
|
IF NOT IS_CUTSCENE_ACTIVE()
|
|
REQUEST_CUTSCENE("ep_4_rcm_concat")
|
|
ENDIF
|
|
|
|
// Load/start cutscene
|
|
DEBUG_PRINTSTRING("In Intro setup, waiting for cutscene to be ready...")
|
|
IF RC_IS_CUTSCENE_OK_TO_START()
|
|
|
|
DEBUG_PRINTSTRING("Starting intro cutscene...")
|
|
|
|
IF IS_PED_UNINJURED(PLAYER_PED_ID())
|
|
REGISTER_ENTITY_FOR_CUTSCENE(PLAYER_PED_ID(), "Michael", CU_ANIMATE_EXISTING_SCRIPT_ENTITY) // Player
|
|
ENDIF
|
|
|
|
IF IS_PED_UNINJURED(sRCLauncherDataLocal.pedID[ID_MARNIE])
|
|
REGISTER_ENTITY_FOR_CUTSCENE(sRCLauncherDataLocal.pedID[ID_MARNIE], "Marnie", CU_ANIMATE_EXISTING_SCRIPT_ENTITY) // Marnie
|
|
ENDIF
|
|
|
|
IF IS_PED_UNINJURED(sRCLauncherDataLocal.pedID[ID_JIMMY])
|
|
FREEZE_ENTITY_POSITION(sRCLauncherDataLocal.pedID[ID_JIMMY], FALSE)
|
|
IF IS_ENTITY_ALIVE(GET_CURRENT_PED_WEAPON_ENTITY_INDEX(sRCLauncherDataLocal.pedID[ID_JIMMY]))
|
|
DetectorCopy = CREATE_WEAPON_OBJECT_FROM_PED_WEAPON_WITH_COMPONENTS(sRCLauncherDataLocal.pedID[ID_JIMMY], WEAPONTYPE_DIGISCANNER)
|
|
REGISTER_ENTITY_FOR_CUTSCENE(DetectorCopy, "Artefact_Detector", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
|
|
ENDIF
|
|
REGISTER_ENTITY_FOR_CUTSCENE(sRCLauncherDataLocal.pedID[ID_JIMMY], "Jimmy_Boston", CU_ANIMATE_EXISTING_SCRIPT_ENTITY) // Jimmy
|
|
ENDIF
|
|
|
|
IF IS_PED_UNINJURED(PLAYER_PED_ID())
|
|
REGISTER_ENTITY_FOR_CUTSCENE(PLAYER_PED_ID(), "Michael", CU_ANIMATE_EXISTING_SCRIPT_ENTITY) // Jimmy
|
|
ENDIF
|
|
|
|
TRIGGER_MUSIC_EVENT("EPS4_START")
|
|
|
|
// Ensure lead-in blip is cleaned up...
|
|
RC_CLEANUP_LAUNCHER()
|
|
|
|
REPLAY_START_EVENT(REPLAY_IMPORTANCE_LOW)
|
|
|
|
// Start cutscene
|
|
START_CUTSCENE()
|
|
WAIT(0)
|
|
STOP_GAMEPLAY_HINT()
|
|
RC_END_Z_SKIP(TRUE, TRUE, FALSE)
|
|
RESOLVE_VEHICLES_INSIDE_ANGLED_AREA_WITH_SIZE_LIMIT(<<1833.393188,4703.848633,32.502178>>, <<1819.368286,4693.412598,43.891628>>, 18.0,
|
|
<< 1816.55, 4683.33, 37.75 >>, 339.76, GET_DEFAULT_ALLOWABLE_VEHICLE_SIZE_VECTOR())
|
|
RC_START_CUTSCENE_MODE(<<1812, 4697, 39.1>>, TRUE, FALSE, DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT)
|
|
|
|
WHILE NOT LOAD_ASSETS()
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
DEBUG_PRINTSTRING("Loaded all assets! Moving to intro run loop...")
|
|
|
|
g_mission.section = SECTION_RUNNING
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF g_mission.section = SECTION_RUNNING
|
|
|
|
FORCE_NOT_FOUND_SCREEN_ON_DETECTOR()
|
|
|
|
IF g_mission.bRequestJSkip
|
|
STOP_CUTSCENE()
|
|
QUEUE_MISSION_STAGE(MS_FINDROCK)
|
|
g_mission.section = SECTION_CLEANUP
|
|
|
|
ELIF g_mission.bRequestCpSkip
|
|
STOP_CUTSCENE()
|
|
g_mission.section = SECTION_CLEANUP
|
|
|
|
// b* 2363991 - changed to is cutscene playing not ACTIVE
|
|
ELIF NOT IS_CUTSCENE_PLAYING() // IS_CUTSCENE_ACTIVE() // Wait for cutscene to end
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
QUEUE_MISSION_STAGE(MS_FINDROCK)
|
|
g_mission.section = SECTION_CLEANUP
|
|
ENDIF
|
|
|
|
IF WAS_CUTSCENE_SKIPPED()
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
ENDIF
|
|
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Michael")
|
|
DEBUG_PRINTSTRING("*** Forcing Michael's move state")
|
|
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), <<1827.1611, 4698.6445, 38.0940>>, 184.1384)
|
|
GIVE_WEAPON_TO_PED(PLAYER_PED_ID(), weapon_Detector, INFINITE_AMMO, TRUE)
|
|
//FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_ON_FOOT_IDLE, FALSE, FAUS_DEFAULT)
|
|
//FORCE_PED_AI_AND_ANIMATION_UPDATE(PLAYER_PED_ID())
|
|
//SET_GAMEPLAY_CAM_RELATIVE_PITCH()
|
|
//SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF CAN_SET_EXIT_STATE_FOR_CAMERA()
|
|
REPLAY_STOP_EVENT()
|
|
DEBUG_PRINTSTRING("*** Teleport Mike")
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
SAFE_TELEPORT_ENTITY(PLAYER_PED_ID(), <<1827.1611, 4698.6445, 38.0940>>, 184.1384)
|
|
ENDIF
|
|
|
|
DO_MARNIE_INTRO_EXIT()
|
|
DO_JIMMY_INTRO_EXIT()
|
|
|
|
IF IS_ENTITY_ALIVE(DetectorCopy)
|
|
IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Artefact_Detector")
|
|
GIVE_WEAPON_OBJECT_TO_PED(DetectorCopy, PLAYER_PED_ID())
|
|
SAFE_DELETE_OBJECT(DetectorCopy)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Jimmy_Boston")
|
|
// IF IS_ENTITY_ALIVE(epsilonianArray[ID_JIMMY].hPed)
|
|
// SET_ENTITY_COORDS(epsilonianArray[ID_JIMMY].hPed, << 1825.0122, 4697.2227, 38.17 >>)
|
|
// SET_ENTITY_HEADING(epsilonianArray[ID_JIMMY].hPed, 234.0331)
|
|
// ENDIF
|
|
// ENDIF
|
|
// IF CAN_SET_EXIT_STATE_FOR_REGISTERED_ENTITY("Marnie")
|
|
// IF IS_ENTITY_ALIVE(epsilonianArray[ID_MARNIE].hPed)
|
|
// SET_ENTITY_COORDS(epsilonianArray[ID_MARNIE].hPed, << 1825.0122, 4697.2227, 38.17 >>)
|
|
// SET_ENTITY_HEADING(epsilonianArray[ID_MARNIE].hPed, 234.0331)
|
|
// ENDIF
|
|
// ENDIF
|
|
ENDIF
|
|
|
|
IF g_mission.section = SECTION_CLEANUP
|
|
|
|
DEBUG_PRINTSTRING("Doing intro cleanup and progressing")
|
|
|
|
IF NOT IS_CUTSCENE_PLAYING()
|
|
iCurrentRock = 0
|
|
RC_END_CUTSCENE_MODE(TRUE, FALSE)
|
|
RC_SET_ENTITY_PROOFS_FOR_CUTSCENE(sRCLauncherDataLocal, FALSE)
|
|
CHANGE_MISSION_STAGE()
|
|
ENDIF
|
|
ENDIF
|
|
ENDPROC
|
|
|
|
|
|
//*******************************************************************************************************************
|
|
//*******************************************************************************************************************
|
|
/// PURPOSE:
|
|
/// Main loop for the Find Rock stages of the mission
|
|
PROC STAGE_FINDROCK()
|
|
|
|
SET_ALL_RANDOM_PEDS_FLEE_THIS_FRAME(PLAYER_ID())
|
|
|
|
INT iEps
|
|
|
|
IF g_mission.bSyncForSkip = TRUE
|
|
RC_START_Z_SKIP()
|
|
WAIT(0)
|
|
|
|
WHILE NOT LOAD_ASSETS()
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
IF IS_CUTSCENE_ACTIVE()
|
|
STOP_CUTSCENE_IMMEDIATELY()
|
|
REMOVE_CUTSCENE()
|
|
ENDIF
|
|
|
|
WHILE IS_CUTSCENE_ACTIVE()
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
IF IS_REPLAY_BEING_SET_UP()
|
|
END_REPLAY_SETUP()
|
|
ENDIF
|
|
|
|
IF iCurrentRock = 0
|
|
IF NOT IS_REPLAY_BEING_SET_UP()
|
|
SET_ENTITY_COORDS(PLAYER_PED_ID(), vPos_PlayerReset)
|
|
SET_ENTITY_HEADING(PLAYER_PED_ID(), fRot_PlayerReset)
|
|
ENDIF
|
|
|
|
SET_EPS_IDLE(epsilonianArray[ID_JIMMY], TRUE)
|
|
SET_EPS_IDLE(epsilonianArray[ID_MARNIE], TRUE)
|
|
|
|
// Got to do this here for the skip in case we don't watch the intro
|
|
IF IS_PED_UNINJURED(epsilonianArray[ID_JIMMY].hPed)
|
|
FREEZE_ENTITY_POSITION(sRCLauncherDataLocal.pedID[ID_JIMMY], FALSE)
|
|
SET_ENTITY_COORDS(epsilonianArray[ID_JIMMY].hPed, << 1829.75, 4693.50, 38.51 >>)
|
|
SET_ENTITY_HEADING(epsilonianArray[ID_JIMMY].hPed, 27.46)
|
|
FLOAT groundZ
|
|
VECTOR vTemp = GET_ENTITY_COORDS(epsilonianArray[ID_JIMMY].hPed)
|
|
GET_GROUND_Z_FOR_3D_COORD(<< 1829.75, 4693.50, 38.51 >>, groundZ)
|
|
SET_ENTITY_COORDS(epsilonianArray[ID_JIMMY].hPed, <<vTemp.x, vTemp.y, groundZ>>)
|
|
|
|
DEBUG_PRINTSTRING("Setting Jimmy position (0)")
|
|
//TASK_FOLLOW_NAV_MESH_TO_COORD(epsilonianArray[ID_JIMMY].hPed, << 1826.2458, 4696.5059, 38.1187 >>, PEDMOVE_WALK, DEFAULT_TIME_BEFORE_WARP)
|
|
ENDIF
|
|
IF IS_PED_UNINJURED(epsilonianArray[ID_MARNIE].hPed)
|
|
SET_ENTITY_COORDS(epsilonianArray[ID_MARNIE].hPed, << 1827.32, 4692.59, 38.53 >>)
|
|
SET_ENTITY_HEADING(epsilonianArray[ID_MARNIE].hPed, 171.22)
|
|
DEBUG_PRINTSTRING("Setting Marnie position (0)")
|
|
ENDIF
|
|
ELIF iCurrentRock = 1
|
|
SET_ENTITY_COORDS(PLAYER_PED_ID(), <<1754.6337, 4675.7886, 42.9068>>)
|
|
SET_ENTITY_HEADING(PLAYER_PED_ID(), 293.2275)
|
|
|
|
IF IS_PED_UNINJURED(epsilonianArray[ID_JIMMY].hPed)
|
|
SET_ENTITY_COORDS(epsilonianArray[ID_JIMMY].hPed, <<1758.5857, 4670.0854, 42.6276 >>)
|
|
SET_ENTITY_HEADING(epsilonianArray[ID_JIMMY].hPed, 262.4368)
|
|
DEBUG_PRINTSTRING("Setting Jimmy position (1)")
|
|
ENDIF
|
|
|
|
IF IS_PED_UNINJURED(epsilonianArray[ID_MARNIE].hPed)
|
|
SET_ENTITY_COORDS(epsilonianArray[ID_MARNIE].hPed, << 1759.9169, 4683.5840, 42.7266 >>)
|
|
SET_ENTITY_HEADING(epsilonianArray[ID_MARNIE].hPed, 148.3211)
|
|
DEBUG_PRINTSTRING("Setting Marnie position (1)")
|
|
ENDIF
|
|
|
|
ELIF iCurrentRock = 2
|
|
SET_ENTITY_COORDS(PLAYER_PED_ID(), <<1758.4542, 4829.4307, 39.7290>>)
|
|
SET_ENTITY_HEADING(PLAYER_PED_ID(), 168.2012)
|
|
|
|
IF IS_PED_UNINJURED(epsilonianArray[ID_MARNIE].hPed)
|
|
SET_ENTITY_COORDS(epsilonianArray[ID_MARNIE].hPed, << 1755.0052, 4827.3291, 40.0736 >>)
|
|
SET_ENTITY_HEADING(epsilonianArray[ID_MARNIE].hPed, 169.6486)
|
|
DEBUG_PRINTSTRING("Setting Marnie position (2)")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
WAIT(750)
|
|
RC_END_Z_SKIP()
|
|
g_mission.bSyncForSkip = FALSE
|
|
ENDIF
|
|
|
|
IF g_mission.section = SECTION_SETUP
|
|
|
|
DEBUG_PRINTSI("Doing setup for FindRock section:", iCurrentRock)
|
|
|
|
// Clear buddy tasks and state immediately
|
|
SET_EPS_IDLE(epsilonianArray[ID_JIMMY], FALSE)
|
|
//SET_EPS_IDLE(epsilonianArray[ID_MARNIE], FALSE)
|
|
|
|
bFollowerDoingIdle = FALSE
|
|
bStillOnTarget = FALSE
|
|
epsKnockedOver = FALSE
|
|
iFoundWaitTimer = -1
|
|
iNonFollowerCloseLines = 0
|
|
iNonFollowerCloseLines1 = 0
|
|
iNonFollowerCloseLinesTimer = GET_GAME_TIMER()
|
|
iFollowMessingAroundTimer = GET_GAME_TIMER()
|
|
iAimPromptLines = 0
|
|
|
|
// IF IS_PED_UNINJURED(PLAYER_PED_ID())
|
|
// // Reset the player capsule
|
|
// SET_PED_CAPSULE(PLAYER_PED_ID(), 0)
|
|
// bCapsuleResized = FALSE
|
|
// ENDIF
|
|
|
|
// Set initial positions/actions for player/buddies for each stage
|
|
IF iCurrentRock = 0
|
|
IF IS_PED_UNINJURED(PLAYER_PED_ID())
|
|
IF GET_PEDS_CURRENT_WEAPON(PLAYER_PED_ID()) != weapon_Detector
|
|
GIVE_WEAPON_TO_PED(PLAYER_PED_ID(), weapon_Detector, INFINITE_AMMO, TRUE)
|
|
ENDIF
|
|
DISABLE_CELLPHONE(TRUE)
|
|
ENDIF
|
|
IF IS_PED_UNINJURED(epsilonianArray[ID_JIMMY].hPed)
|
|
REMOVE_WEAPON_FROM_PED(epsilonianArray[ID_JIMMY].hPed, weapon_Detector) // Make sure Jimmy definitely doesn't have the detector
|
|
TASK_FOLLOW_NAV_MESH_TO_COORD(epsilonianArray[ID_JIMMY].hPed, << 1826.2458, 4696.5059, 38.1187 >>, PEDMOVE_WALK, DEFAULT_TIME_BEFORE_WARP, 0.1)
|
|
ENDIF
|
|
|
|
SET_EPS_FOLLOW(epsilonianArray[ID_JIMMY], TRUE)
|
|
//SET_EPS_MOVE(epsilonianArray[ID_MARNIE])
|
|
// SET_GAMEPLAY_CAM_RELATIVE_HEADING(45)
|
|
// SET_GAMEPLAY_CAM_RELATIVE_PITCH(-15)
|
|
|
|
iCurrentMaxGoodLines = MAX_JGOOD_LINES
|
|
iCurrentMaxBadLines = MAX_JBAD_LINES
|
|
|
|
iSaidBadLines = 0
|
|
iSaidGoodLines = 0
|
|
|
|
WHILE IS_CUTSCENE_ACTIVE()
|
|
WAIT(0)
|
|
// Need to wait for the cutscene to completely finish before requesting the next one
|
|
ENDWHILE
|
|
|
|
ELIF iCurrentRock = 1
|
|
IF IS_PED_UNINJURED(PLAYER_PED_ID())
|
|
IF GET_PEDS_CURRENT_WEAPON(PLAYER_PED_ID()) != weapon_Detector
|
|
GIVE_WEAPON_TO_PED(PLAYER_PED_ID(), weapon_Detector, INFINITE_AMMO, TRUE)
|
|
DISABLE_CELLPHONE(TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SET_EPS_FOLLOW(epsilonianArray[ID_MARNIE], FALSE)
|
|
SET_EPS_MOVE(epsilonianArray[ID_JIMMY], g_hDummyMarker_Piss)
|
|
|
|
iCurrentMaxGoodLines = MAX_MGOOD_LINES
|
|
iCurrentMaxBadLines = MAX_MBAD_LINES
|
|
|
|
iSaidBadLines = 0
|
|
iSaidGoodLines = 0
|
|
|
|
WHILE IS_CUTSCENE_ACTIVE()
|
|
WAIT(0)
|
|
// Need to wait for the cutscene to completely finish before requesting the next one
|
|
ENDWHILE
|
|
|
|
ELIF iCurrentRock = 2
|
|
IF IS_PED_UNINJURED(PLAYER_PED_ID())
|
|
IF GET_PEDS_CURRENT_WEAPON(PLAYER_PED_ID()) != weapon_Detector
|
|
GIVE_WEAPON_TO_PED(PLAYER_PED_ID(), weapon_Detector, INFINITE_AMMO, TRUE)
|
|
DISABLE_CELLPHONE(TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SET_EPS_MOVE(epsilonianArray[ID_MARNIE], g_hMarker_MarnieAngry)
|
|
SET_EPS_WARP_TO_MARKER(epsilonianArray[ID_JIMMY], g_hDummyMarker_Dance)
|
|
|
|
iCurrentMaxGoodLines = MAX_PGOOD_LINES
|
|
iCurrentMaxBadLines = MAX_PBAD_LINES
|
|
|
|
iSaidBadLines = 0
|
|
iSaidGoodLines = 0
|
|
|
|
WHILE IS_CUTSCENE_ACTIVE()
|
|
WAIT(0)
|
|
// Need to wait for the cutscene to completely finish before requesting the next one
|
|
ENDWHILE
|
|
|
|
ENDIF
|
|
|
|
// Setup dialogue participants
|
|
ADD_PED_FOR_DIALOGUE(pedsForConversation, 0, PLAYER_PED_ID(), "MICHAEL")
|
|
ADD_PED_FOR_DIALOGUE(pedsForConversation, 5, epsilonianArray[ID_JIMMY].hPed, "JIMMYBOSTON")
|
|
ADD_PED_FOR_DIALOGUE(pedsForConversation, 4, epsilonianArray[ID_MARNIE].hPed, "MARNIE")
|
|
|
|
IF iCurrentRock = 0
|
|
hPrimaryBuddy = epsilonianArray[ID_JIMMY].hPed
|
|
ELSE
|
|
hPrimaryBuddy = epsilonianArray[ID_MARNIE].hPed
|
|
ENDIF
|
|
|
|
// Switch on detector
|
|
START_DETECTOR(rockArray[iCurrentRock].fMeanderFactor0,
|
|
rockArray[iCurrentRock].fMeanderFactor1,
|
|
rockArray[iCurrentRock].fMeanderAmplitude,
|
|
rockArray[iCurrentRock].fStraightZone,
|
|
rockArray[iCurrentRock].fHotAngle)
|
|
|
|
// Reset all vars
|
|
bIsPlayerOnTarget = FALSE
|
|
bIsPlayerAtRock = FALSE
|
|
bHasPlayerFoundRock = FALSE
|
|
bIsPlayerInWoods = TRUE
|
|
bAudDoneChat1 = FALSE
|
|
bAudDoneChat2 = FALSE
|
|
bAudDoneChatAll = FALSE
|
|
bAudDoneClose = FALSE
|
|
bAudDoneReturn1 = FALSE
|
|
bAudDoneReturn2 = FALSE
|
|
bObjDoneHunt = FALSE
|
|
bObjDoneExamine = FALSE
|
|
bObjDoneReturnWoods = FALSE
|
|
|
|
iTutorialLine = 0
|
|
iTutorialTimer = 0
|
|
|
|
CLEAR_HELP(TRUE)
|
|
iHintTimer = GET_GAME_TIMER()
|
|
iTutorialTimer = GET_GAME_TIMER() + 1000
|
|
|
|
DEBUG_PRINTSI("Finished setup, moving to run loop for rock #:", iCurrentRock)
|
|
|
|
g_mission.section = SECTION_RUNNING
|
|
|
|
ENDIF
|
|
|
|
IF g_mission.section = SECTION_RUNNING
|
|
|
|
//-- Check for deaths
|
|
IF IS_ENTITY_DEAD(PLAYER_PED_ID())
|
|
QUEUE_MISSION_STAGE(MS_FAILED)
|
|
g_mission.failReason = FAIL_REASON_PLAYER_DEAD
|
|
g_mission.section = SECTION_CLEANUP
|
|
|
|
ELIF IS_ENTITY_DEAD(epsilonianArray[ID_MARNIE].hPed)
|
|
QUEUE_MISSION_STAGE(MS_FAILED)
|
|
g_mission.failReason = FAIL_REASON_MARNIE_DEAD
|
|
g_mission.section = SECTION_CLEANUP
|
|
|
|
ELIF IS_ENTITY_DEAD(epsilonianArray[ID_JIMMY].hPed)
|
|
QUEUE_MISSION_STAGE(MS_FAILED)
|
|
g_mission.failReason = FAIL_REASON_JIMMY_DEAD
|
|
g_mission.section = SECTION_CLEANUP
|
|
|
|
ELIF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(epsilonianArray[ID_MARNIE].hPed, PLAYER_PED_ID(), TRUE)
|
|
AND HAS_ENTITY_BEEN_DAMAGED_BY_WEAPON(epsilonianArray[ID_MARNIE].hPed, WEAPONTYPE_INVALID, GENERALWEAPON_TYPE_ANYWEAPON)
|
|
QUEUE_MISSION_STAGE(MS_FAILED)
|
|
g_mission.failReason = FAIL_REASON_MARNIE_INJURED
|
|
g_mission.section = SECTION_CLEANUP
|
|
|
|
ELIF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(epsilonianArray[ID_JIMMY].hPed, PLAYER_PED_ID(), TRUE)
|
|
AND HAS_ENTITY_BEEN_DAMAGED_BY_WEAPON(epsilonianArray[ID_JIMMY].hPed, WEAPONTYPE_INVALID, GENERALWEAPON_TYPE_ANYWEAPON)
|
|
QUEUE_MISSION_STAGE(MS_FAILED)
|
|
g_mission.failReason = FAIL_REASON_JIMMY_INJURED
|
|
g_mission.section = SECTION_CLEANUP
|
|
|
|
ELIF IS_EPS_THREATENED(epsilonianArray[ID_MARNIE])
|
|
QUEUE_MISSION_STAGE(MS_FAILED)
|
|
g_mission.failReason = FAIL_REASON_MARNIE_THREATENED
|
|
g_mission.section = SECTION_CLEANUP
|
|
|
|
ELIF IS_EPS_THREATENED(epsilonianArray[ID_JIMMY])
|
|
QUEUE_MISSION_STAGE(MS_FAILED)
|
|
g_mission.failReason = FAIL_REASON_JIMMY_THREATENED
|
|
g_mission.section = SECTION_CLEANUP
|
|
|
|
ELIF NOT IS_POINT_IN_POLY_2D(g_polyFailArea, GET_ENTITY_COORDS(PLAYER_PED_ID()))
|
|
QUEUE_MISSION_STAGE(MS_FAILED)
|
|
g_mission.failReason = FAIL_REASON_LEFT_AREA
|
|
g_mission.section = SECTION_CLEANUP
|
|
|
|
ELIF g_mission.bRequestCpSkip
|
|
g_mission.section = SECTION_CLEANUP
|
|
|
|
ELIF g_mission.bRequestJSkip
|
|
QUEUE_MISSION_STAGE(MS_ROCKSCENE)
|
|
g_mission.section = SECTION_CLEANUP
|
|
|
|
ELIF g_mission.bRequestPSkip
|
|
IF iCurrentRock = 0
|
|
QUEUE_MISSION_STAGE(MS_INTRO)
|
|
DEBUG_PRINTSTRING("P skipping to intro...")
|
|
ELSE
|
|
iCurrentRock--
|
|
QUEUE_MISSION_STAGE(MS_ROCKSCENE)
|
|
ENDIF
|
|
g_mission.section = SECTION_CLEANUP
|
|
|
|
ELSE
|
|
// Update the epsilonians
|
|
REPEAT EPSILONIAN_MAX iEps
|
|
UPDATE_EPS(epsilonianArray[iEps])
|
|
ENDREPEAT
|
|
|
|
// Start preloading the cutscene when < the default cutscene load distance
|
|
IF DOES_ENTITY_EXIST(rockArray[iCurrentRock].hObject)
|
|
IF iCurrentRock = 0
|
|
if GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), rockArray[iCurrentRock].hObject) < DEFAULT_CUTSCENE_LOAD_DIST
|
|
IF NOT HAS_CUTSCENE_LOADED()
|
|
REQUEST_CUTSCENE("EPS_4_MCS_1")
|
|
DEBUG_PRINTSTRING("Requesting midtro now")
|
|
ENDIF
|
|
ELIF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), rockArray[iCurrentRock].hObject) > DEFAULT_CUTSCENE_UNLOAD_DIST
|
|
IF HAS_CUTSCENE_LOADED()
|
|
DEBUG_PRINTSTRING("Player moved away - unloading midtro")
|
|
REMOVE_CUTSCENE()
|
|
ENDIF
|
|
ENDIF
|
|
ELIF iCurrentRock = 1
|
|
if GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), rockArray[iCurrentRock].hObject) < DEFAULT_CUTSCENE_LOAD_DIST
|
|
IF NOT HAS_CUTSCENE_LOADED()
|
|
REQUEST_CUTSCENE("EPS_4_MCS_2")
|
|
DEBUG_PRINTSTRING("Requesting midtro now")
|
|
ENDIF
|
|
ELIF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), rockArray[iCurrentRock].hObject) > DEFAULT_CUTSCENE_UNLOAD_DIST
|
|
IF HAS_CUTSCENE_LOADED()
|
|
DEBUG_PRINTSTRING("Player moved away - unloading midtro")
|
|
REMOVE_CUTSCENE()
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
if GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), rockArray[iCurrentRock].hObject) < DEFAULT_CUTSCENE_LOAD_DIST
|
|
IF NOT HAS_CUTSCENE_LOADED()
|
|
REQUEST_CUTSCENE("EPS_4_MCS_3")
|
|
DEBUG_PRINTSTRING("Requesting midtro now")
|
|
ENDIF
|
|
ELIF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), rockArray[iCurrentRock].hObject) > DEFAULT_CUTSCENE_UNLOAD_DIST
|
|
IF HAS_CUTSCENE_LOADED()
|
|
DEBUG_PRINTSTRING("Player moved away - unloading midtro")
|
|
REMOVE_CUTSCENE()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY()
|
|
DEBUG_PRINTSTRING("Trying to set player component variation")
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED_SAFE("Michael", PLAYER_PED_ID())
|
|
ENDIF
|
|
IF iCurrentRock = 0
|
|
OR iCurrentRock = 2
|
|
DEBUG_PRINTSTRING("Trying to set Jimmy prop variation")
|
|
SET_CUTSCENE_PED_PROP_VARIATION("Jimmy_Boston", ANCHOR_EYES, 0)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Hide the ammo counter, as the detector doesn't need it (#736243)
|
|
HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_WEAPON_ICON)
|
|
// Disable the player from bringing up the weapon wheel so they're stuck with the detector
|
|
// May need to look into this again for the PC version to disable the shortcut keys!! (#1022647)
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_SELECT_WEAPON)
|
|
|
|
// Keep checking the Mike is holding the detector in case he puts it away when falling, etc
|
|
IF IS_PED_UNINJURED(PLAYER_PED_ID())
|
|
IF GET_PEDS_CURRENT_WEAPON(PLAYER_PED_ID()) != weapon_Detector
|
|
GIVE_WEAPON_TO_PED(PLAYER_PED_ID(), weapon_Detector, INFINITE_AMMO, TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
// Update the detector
|
|
UPDATE_DETECTOR(rockArray[iCurrentRock])
|
|
|
|
// Update help
|
|
IF iCurrentRock = 0
|
|
IF iTutorialLine = 0
|
|
IF iTutorialTimer < GET_GAME_TIMER()
|
|
IF NOT IS_PLAYER_IN_FIRST_PERSON_CAMERA()
|
|
PRINT_HELP_FOREVER("EPS4_T0") // "Hold ~INPUT_AIM~ to use the detector."
|
|
iTutorialTimer = GET_GAME_TIMER() + DEFAULT_GOD_TEXT_TIME
|
|
iTutorialLine++
|
|
iAimPromptTimer = GET_GAME_TIMER() // Reset this again to stop it happening until the first prompts are over
|
|
ELSE
|
|
// Player is in first person camera - skip the first bit of help text
|
|
iTutorialLine = 2
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ELIF iTutorialLine = 1
|
|
IF IS_CONTROL_JUST_PRESSED(PLAYER_CONTROL, INPUT_AIM)
|
|
OR iTutorialTimer < GET_GAME_TIMER()
|
|
CLEAR_HELP(TRUE)
|
|
iTutorialTimer = GET_GAME_TIMER() + 1000
|
|
iTutorialLine++
|
|
iAimPromptTimer = GET_GAME_TIMER() // Reset this again to stop it happening until the first prompts are over
|
|
ENDIF
|
|
|
|
ELIF iTutorialLine = 2
|
|
IF iTutorialTimer < GET_GAME_TIMER()
|
|
PRINT_HELP_FOREVER("EPS4_T1") // "The detector's proximity meter shows how far away the artifact is."
|
|
iTutorialTimer = GET_GAME_TIMER() + DEFAULT_GOD_TEXT_TIME
|
|
iTutorialLine++
|
|
iAimPromptTimer = GET_GAME_TIMER() // Reset this again to stop it happening until the first prompts are over
|
|
ENDIF
|
|
|
|
ELIF iTutorialLine = 3
|
|
IF iTutorialTimer < GET_GAME_TIMER()
|
|
CLEAR_HELP(TRUE)
|
|
iTutorialTimer = GET_GAME_TIMER() + 1000
|
|
iTutorialLine++
|
|
iAimPromptTimer = GET_GAME_TIMER() // Reset this again to stop it happening until the first prompts are over
|
|
ENDIF
|
|
|
|
ELIF iTutorialLine = 4
|
|
IF iTutorialTimer < GET_GAME_TIMER()
|
|
PRINT_HELP_FOREVER("EPS4_T2") // "When facing toward the artifact, the detector's screen will turn blue."
|
|
iTutorialTimer = GET_GAME_TIMER() + DEFAULT_GOD_TEXT_TIME
|
|
iTutorialLine++
|
|
iAimPromptTimer = GET_GAME_TIMER() // Reset this again to stop it happening until the first prompts are over
|
|
ENDIF
|
|
|
|
ELIF iTutorialLine = 5
|
|
IF iTutorialTimer < GET_GAME_TIMER()
|
|
CLEAR_HELP(TRUE)
|
|
iTutorialTimer = GET_GAME_TIMER() + 1000
|
|
iTutorialLine++
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Update anims
|
|
UPDATE_PLAYER_AND_DETECTOR_ANIMS(gDetector.bIsOnTarget)
|
|
|
|
//-- Monitor objectives
|
|
|
|
// Player is in woods
|
|
IF bIsPlayerInWoods = TRUE
|
|
|
|
SAFE_REMOVE_BLIP(g_hBlip)
|
|
|
|
IF NOT IS_POINT_IN_POLY_2D(g_polyPlayArea, GET_ENTITY_COORDS(PLAYER_PED_ID()))
|
|
bIsPlayerInWoods = FALSE
|
|
STOP_SCRIPTED_CONVERSATION(FALSE)
|
|
CLEAR_PRINTS()
|
|
|
|
ELIF bObjDoneExamine = FALSE AND bHasPlayerFoundRock
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
iHintTimer = GET_GAME_TIMER()
|
|
bObjDoneExamine = TRUE
|
|
ENDIF
|
|
|
|
ELIF bAudDoneChat1 = FALSE
|
|
IF ARE_STRINGS_EQUAL(rockArray[iCurrentRock].sChat1Dialogue, EMPTY_STRING)
|
|
OR CREATE_CONVERSATION(pedsForConversation, "EPS4AUD", rockArray[iCurrentRock].sChat1Dialogue, CONV_PRIORITY_MEDIUM)
|
|
// We need the empty string check above to skip over the 1st chat in case it doesn't exist, but we don't want
|
|
// the ped to look at Mike if there's no conversation being played, hence this extra check
|
|
IF NOT ARE_STRINGS_EQUAL(rockArray[iCurrentRock].sChat1Dialogue, EMPTY_STRING)
|
|
IF IS_ENTITY_ALIVE(hPrimaryBuddy)
|
|
TASK_LOOK_AT_ENTITY(hPrimaryBuddy, PLAYER_PED_ID(), 10000)
|
|
ENDIF
|
|
ENDIF
|
|
iAimPromptTimer = GET_GAME_TIMER() // Reset this again to stop it happening until the first prompts are over
|
|
bAudDoneChat1 = TRUE
|
|
ENDIF
|
|
|
|
ELIF bObjDoneHunt = FALSE
|
|
IF iCurrentRock = 0
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
PRINT_NOW("EPS4_A2", DEFAULT_GOD_TEXT_TIME, 0) // Find the artefact
|
|
iHintTimer = GET_GAME_TIMER()
|
|
bObjDoneHunt = TRUE
|
|
ENDIF
|
|
ELSE
|
|
bObjDoneHunt = TRUE // Don't repeat goal if not on first artefact
|
|
ENDIF
|
|
|
|
ELIF bAudDoneChat2 = FALSE
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
AND (GET_GAME_TIMER() - iHintTimer) >= DEFAULT_GOD_TEXT_TIME
|
|
IF ARE_STRINGS_EQUAL(rockArray[iCurrentRock].sChat2Dialogue, EMPTY_STRING)
|
|
OR NOT IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), hPrimaryBuddy, <<DIALOGUE_DIST,DIALOGUE_DIST,DIALOGUE_DIST>>)
|
|
OR CREATE_CONVERSATION(pedsForConversation, "EPS4AUD", rockArray[iCurrentRock].sChat2Dialogue, CONV_PRIORITY_MEDIUM)
|
|
// We need the empty string check above to skip over the 2nd chat in case it doesn't exist, but we don't want
|
|
// the ped to look at Mike if there's no conversation being played, hence this extra check
|
|
IF NOT ARE_STRINGS_EQUAL(rockArray[iCurrentRock].sChat2Dialogue, EMPTY_STRING)
|
|
IF IS_ENTITY_ALIVE(hPrimaryBuddy)
|
|
TASK_LOOK_AT_ENTITY(hPrimaryBuddy, PLAYER_PED_ID(), 5000)
|
|
ENDIF
|
|
ENDIF
|
|
bAudDoneChat2 = TRUE
|
|
iAimPromptTimer = GET_GAME_TIMER() // Reset this again to stop it happening until the first prompts are over
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ELIF bAudDoneChatAll = FALSE
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
bAudDoneChatAll = TRUE
|
|
iSupressHintAudioTimer = GET_GAME_TIMER()
|
|
iSupressPickupAudioTimer = 0
|
|
ENDIF
|
|
|
|
ELIF bHasPlayerFoundRock = FALSE
|
|
AND NOT IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), rockArray[iCurrentRock].vPos, fNearRange)
|
|
// If we're close enough to do the close dialogue, fire it once - otherwise, keep doing the Good/Bad dialogue
|
|
IF IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), rockArray[iCurrentRock].vPos, fCloseDialogRange)
|
|
IF NOT bAudDoneClose
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
IF CREATE_CONVERSATION(pedsForConversation, "EPS4AUD", rockArray[iCurrentRock].SHintCloseDialogue, CONV_PRIORITY_MEDIUM)
|
|
IF IS_ENTITY_ALIVE(hPrimaryBuddy)
|
|
TASK_LOOK_AT_ENTITY(hPrimaryBuddy, PLAYER_PED_ID(), 5000)
|
|
ENDIF
|
|
REPLAY_RECORD_BACK_FOR_TIME(3.0, 5.0, REPLAY_IMPORTANCE_LOWEST)
|
|
bAudDoneClose = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
// Tutorial dialogue
|
|
IF IS_AIM_CAM_ACTIVE()
|
|
IF IS_ENTITY_IN_RANGE_ENTITY(PLAYER_PED_ID(), hPrimaryBuddy, DIALOGUE_DIST)
|
|
OR iCurrentRock = 2
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() AND ((GET_GAME_TIMER() - iSupressHintAudioTimer) > 15000)
|
|
IF bIsPlayerOnTarget
|
|
IF bStillOnTarget = FALSE
|
|
IF iSaidGoodLines < iCurrentMaxGoodLines
|
|
IF ARE_STRINGS_EQUAL(rockArray[iCurrentRock].sHintGoodDialogue, EMPTY_STRING)
|
|
OR CREATE_CONVERSATION(pedsForConversation, "EPS4AUD", rockArray[iCurrentRock].sHintGoodDialogue, CONV_PRIORITY_MEDIUM)
|
|
IF IS_PED_UNINJURED(hPrimaryBuddy)
|
|
TASK_LOOK_AT_ENTITY(hPrimaryBuddy, PLAYER_PED_ID(), 3000)
|
|
ENDIF
|
|
iSupressHintAudioTimer = GET_GAME_TIMER()
|
|
iSaidGoodLines++
|
|
// We want Michael to mumble to himself if he carries on being on target, but only for the last artefact
|
|
IF iCurrentRock = 2
|
|
bStillOnTarget = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
IF iSaidOnTargetLines < 12 // We can hard-code this since this will only be used for artefact 3
|
|
IF ARE_STRINGS_EQUAL(rockArray[iCurrentRock].sHintGoodDialogue, EMPTY_STRING)
|
|
OR CREATE_CONVERSATION(pedsForConversation, "EPS4AUD", "EPS4_HASSIG", CONV_PRIORITY_MEDIUM)
|
|
iSupressHintAudioTimer = GET_GAME_TIMER()
|
|
iSaidOnTargetLines++
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
IF iSaidbadLines < iCurrentMaxBadLines
|
|
IF ARE_STRINGS_EQUAL(rockArray[iCurrentRock].sHintBadDialogue, EMPTY_STRING)
|
|
OR CREATE_CONVERSATION(pedsForConversation, "EPS4AUD", rockArray[iCurrentRock].sHintBadDialogue, CONV_PRIORITY_MEDIUM)
|
|
IF IS_PED_UNINJURED(hPrimaryBuddy)
|
|
TASK_LOOK_AT_ENTITY(hPrimaryBuddy, PLAYER_PED_ID(), 3000)
|
|
ENDIF
|
|
iSupressHintAudioTimer = GET_GAME_TIMER()
|
|
iSaidBadLines++
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ELIF bIsPlayerOnTarget <> gDetector.bIsOnTarget
|
|
bIsPlayerOnTarget = gDetector.bIsOnTarget
|
|
// Don't reset bStillOnTarget to whatever gDetector.bIsOnTarget is at all times - we only set it true for rock 3,
|
|
// and only after we've had at least one "NOW you're on target" lines
|
|
IF gDetector.bIsOnTarget = FALSE
|
|
bStillOnTarget = FALSE
|
|
ENDIF
|
|
IF bIsPlayerOnTarget
|
|
IF iSupressPickupAudioTimer < GET_GAME_TIMER()
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
STOP_SCRIPTED_CONVERSATION(TRUE)
|
|
ENDIF
|
|
iSupressHintAudioTimer = GET_GAME_TIMER() - 7500
|
|
iSupressPickupAudioTimer = GET_GAME_TIMER()
|
|
ENDIF
|
|
ELSE
|
|
iSupressHintAudioTimer = GET_GAME_TIMER() - 7500
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
iSupressHintAudioTimer = GET_GAME_TIMER() - 5000
|
|
ENDIF
|
|
ENDIF
|
|
|
|
//Handle dialogue from the non-buddy ped if the player walks towards them
|
|
IF iCurrentRock = 0
|
|
IF iNonFollowerCloseLines < 5
|
|
IF (GET_GAME_TIMER() - iNonFollowerCloseLinesTimer) > 7500
|
|
AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
AND NOT IS_MESSAGE_BEING_DISPLAYED()
|
|
IF IS_ENTITY_ALIVE(epsilonianArray[ID_MARNIE].hPed)
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(epsilonianArray[ID_MARNIE].hPed, PLAYER_PED_ID()) < 4
|
|
IF CREATE_CONVERSATION(pedsForConversation, "EPS4AUD", "EPS4_NEARM", CONV_PRIORITY_LOW)
|
|
iNonFollowerCloseLines++
|
|
iNonFollowerCloseLinesTimer = GET_GAME_TIMER()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELIF iCurrentRock = 1
|
|
IF iNonFollowerCloseLines < 4
|
|
IF (GET_GAME_TIMER() - iNonFollowerCloseLinesTimer) > 7500
|
|
AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
AND NOT IS_MESSAGE_BEING_DISPLAYED()
|
|
IF IS_ENTITY_ALIVE(epsilonianArray[ID_JIMMY].hPed)
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(epsilonianArray[ID_JIMMY].hPed, PLAYER_PED_ID()) < 4
|
|
IF CREATE_CONVERSATION(pedsForConversation, "EPS4AUD", "EPS4_NEARJ", CONV_PRIORITY_LOW)
|
|
iNonFollowerCloseLines++
|
|
iNonFollowerCloseLinesTimer = GET_GAME_TIMER()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE // Must be the third rock
|
|
IF iNonFollowerCloseLines < 3 // Track Jimmy's near lines
|
|
IF (GET_GAME_TIMER() - iNonFollowerCloseLinesTimer) > 7500
|
|
AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
AND NOT IS_MESSAGE_BEING_DISPLAYED()
|
|
IF IS_ENTITY_ALIVE(epsilonianArray[ID_JIMMY].hPed)
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(epsilonianArray[ID_JIMMY].hPed, PLAYER_PED_ID()) < 4
|
|
IF CREATE_CONVERSATION(pedsForConversation, "EPS4AUD", "EPS4_NEARJP", CONV_PRIORITY_LOW)
|
|
iNonFollowerCloseLines++
|
|
iNonFollowerCloseLinesTimer = GET_GAME_TIMER()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF iNonFollowerCloseLines1 < 4 // Track Marnie's near lines
|
|
IF (GET_GAME_TIMER() - iNonFollowerCloseLinesTimer) > 7500
|
|
AND NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
AND NOT IS_MESSAGE_BEING_DISPLAYED()
|
|
IF IS_ENTITY_ALIVE(epsilonianArray[ID_MARNIE].hPed)
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(epsilonianArray[ID_MARNIE].hPed, PLAYER_PED_ID()) < 4
|
|
IF CREATE_CONVERSATION(pedsForConversation, "EPS4AUD", "EPS4_NEARMP", CONV_PRIORITY_LOW)
|
|
iNonFollowerCloseLines1++
|
|
iNonFollowerCloseLinesTimer = GET_GAME_TIMER()
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Detect if found rock / near rock / far from rock
|
|
IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), rockArray[iCurrentRock].vPos, << fFindRange,fFindRange,2.0 >>, FALSE, FALSE, TM_ON_FOOT)
|
|
IF iFoundWaitTimer = -1
|
|
iFoundWaitTimer = GET_GAME_TIMER()
|
|
ELIF (GET_GAME_TIMER() - iFoundWaitTimer) >= 1500
|
|
//FORCE_FOUND_SCREEN_ON_DETECTOR()
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
KILL_ANY_CONVERSATION()
|
|
ENDIF
|
|
iMidtroDelay = GET_GAME_TIMER()
|
|
QUEUE_MISSION_STAGE(MS_ROCKSCENE)
|
|
g_mission.section = SECTION_CLEANUP
|
|
ENDIF
|
|
|
|
ELIF bIsPlayerAtRock = FALSE
|
|
IF gDetector.bIsFoundSoundOn //IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), rockArray[iCurrentRock].vPos, fNearRange)
|
|
// SET_GAMEPLAY_COORD_HINT(rockArray[iCurrentRock].vPos + <<0,0,1>>, -1)
|
|
bIsPlayerAtRock = TRUE
|
|
bHasPlayerFoundRock = TRUE
|
|
|
|
ENDIF
|
|
ELSE
|
|
// If player moves away from rock after finding it, go back to previous state (but leave the blip)
|
|
IF NOT IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), rockArray[iCurrentRock].vPos, fNearRange+2)
|
|
// STOP_GAMEPLAY_HINT()
|
|
bIsPlayerAtRock = FALSE
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Player has strayed from woods
|
|
ELSE
|
|
|
|
IF NOT DOES_BLIP_EXIST(g_hBlip)
|
|
g_hBlip = CREATE_COORD_BLIP(vPos_WoodsCentre, BLIPPRIORITY_MED, FALSE)
|
|
ENDIF
|
|
|
|
bIsPlayerOnTarget = gDetector.bIsOnTarget
|
|
|
|
IF IS_POINT_IN_POLY_2D(g_polyPlayArea, GET_ENTITY_COORDS(PLAYER_PED_ID()))
|
|
bIsPlayerInWoods = TRUE
|
|
STOP_SCRIPTED_CONVERSATION(FALSE)
|
|
CLEAR_PRINTS()
|
|
|
|
ELIF bObjDoneReturnWoods = FALSE
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
PRINT_NOW("EPS4_A1", DEFAULT_GOD_TEXT_TIME, 0) // Go back to the woods
|
|
iHintTimer = GET_GAME_TIMER()
|
|
bObjDoneReturnWoods = TRUE
|
|
ENDIF
|
|
|
|
ELIF bAudDoneReturn1 = FALSE
|
|
IF iCurrentRock < 2
|
|
IF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), hPrimaryBuddy, <<DIALOGUE_DIST,DIALOGUE_DIST,DIALOGUE_DIST>>)
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
AND NOT IS_MESSAGE_BEING_DISPLAYED()
|
|
IF ARE_STRINGS_EQUAL(rockArray[iCurrentRock].sReturn1Dialogue, EMPTY_STRING)
|
|
OR CREATE_CONVERSATION(pedsForConversation, "EPS4AUD", rockArray[iCurrentRock].sReturn1Dialogue, CONV_PRIORITY_MEDIUM)
|
|
bAudDoneReturn1 = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
AND NOT IS_MESSAGE_BEING_DISPLAYED()
|
|
IF ARE_STRINGS_EQUAL(rockArray[iCurrentRock].sReturn1Dialogue, EMPTY_STRING)
|
|
OR CREATE_CONVERSATION(pedsForConversation, "EPS4AUD", rockArray[iCurrentRock].sReturn1Dialogue, CONV_PRIORITY_MEDIUM)
|
|
bAudDoneReturn1 = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ELIF bAudDoneReturn2 = FALSE
|
|
IF iCurrentRock < 2
|
|
IF IS_ENTITY_AT_ENTITY(PLAYER_PED_ID(), hPrimaryBuddy, <<DIALOGUE_DIST,DIALOGUE_DIST,DIALOGUE_DIST>>)
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
AND (GET_GAME_TIMER() - iHintTimer) >= DEFAULT_GOD_TEXT_TIME
|
|
AND NOT IS_MESSAGE_BEING_DISPLAYED()
|
|
IF ARE_STRINGS_EQUAL(rockArray[iCurrentRock].sReturn2Dialogue, EMPTY_STRING)
|
|
OR CREATE_CONVERSATION(pedsForConversation, "EPS4AUD", rockArray[iCurrentRock].sReturn2Dialogue, CONV_PRIORITY_MEDIUM)
|
|
bAudDoneReturn2 = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ELSE
|
|
IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
AND (GET_GAME_TIMER() - iHintTimer) >= DEFAULT_GOD_TEXT_TIME
|
|
AND NOT IS_MESSAGE_BEING_DISPLAYED()
|
|
IF ARE_STRINGS_EQUAL(rockArray[iCurrentRock].sReturn2Dialogue, EMPTY_STRING)
|
|
OR CREATE_CONVERSATION(pedsForConversation, "EPS4AUD", rockArray[iCurrentRock].sReturn2Dialogue, CONV_PRIORITY_MEDIUM)
|
|
bAudDoneReturn2 = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF g_mission.section = SECTION_CLEANUP
|
|
|
|
// Hide the ammo counter, as the detector doesn't need it (#736243)
|
|
HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_WEAPON_ICON)
|
|
|
|
DEBUG_PRINTSTRING("In cleanup for FindRock")
|
|
|
|
IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED()
|
|
STOP_SCRIPTED_CONVERSATION(TRUE)
|
|
ENDIF
|
|
|
|
UPDATE_PLAYER_AND_DETECTOR_ANIMS(TRUE)
|
|
FORCE_FOUND_SCREEN_ON_DETECTOR()
|
|
SET_CONTROL_SHAKE(PLAYER_CONTROL, 200, 150)
|
|
|
|
IF (GET_GAME_TIMER() - iMidtroDelay) > 750
|
|
// Disable detector
|
|
STOP_DETECTOR()
|
|
|
|
REPLAY_RECORD_BACK_FOR_TIME(5.0, 5.0, REPLAY_IMPORTANCE_LOWEST)
|
|
|
|
REPLAY_RECORD_BACK_FOR_TIME(3.0)
|
|
|
|
// Clear tasks
|
|
CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
SET_EPS_IDLE(epsilonianArray[ID_JIMMY], FALSE)
|
|
SET_EPS_IDLE(epsilonianArray[ID_MARNIE], FALSE)
|
|
|
|
CHANGE_MISSION_STAGE()
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
|
|
//*******************************************************************************************************************
|
|
//*******************************************************************************************************************
|
|
/// PURPOSE:
|
|
/// Main loop for the rock scripted cutscenes during the mission
|
|
PROC STAGE_ROCKSCENE()
|
|
|
|
// Hide the ammo counter, as the detector doesn't need it (#736243)
|
|
HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_WEAPON_ICON)
|
|
|
|
IF g_mission.bSyncForSkip = TRUE
|
|
RC_START_Z_SKIP()
|
|
|
|
REMOVE_CUTSCENE()
|
|
|
|
IF iCurrentRock = 0
|
|
RC_REQUEST_MID_MISSION_CUTSCENE("EPS_4_MCS_1")
|
|
ELIF iCurrentRock = 1
|
|
RC_REQUEST_MID_MISSION_CUTSCENE("EPS_4_MCS_2")
|
|
ELSE
|
|
RC_REQUEST_MID_MISSION_CUTSCENE("EPS_4_MCS_3")
|
|
ENDIF
|
|
|
|
IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY()
|
|
DEBUG_PRINTSTRING("Trying to set player component variation")
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED_SAFE("Michael", PLAYER_PED_ID())
|
|
ENDIF
|
|
IF iCurrentRock = 0
|
|
OR iCurrentRock = 2
|
|
DEBUG_PRINTSTRING("Trying to set Jimmy prop variation")
|
|
SET_CUTSCENE_PED_PROP_VARIATION("Jimmy_Boston", ANCHOR_EYES, 0)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
DEBUG_PRINTSTRING("SKIP: Doing sync for cutscene skip")
|
|
|
|
RC_END_Z_SKIP()
|
|
g_mission.bSyncForSkip = FALSE
|
|
ENDIF
|
|
|
|
IF g_mission.section = SECTION_SETUP
|
|
|
|
DEBUG_PRINTSI("Doing setup for RockScene:", iCurrentRock)
|
|
|
|
UPDATE_PLAYER_AND_DETECTOR_ANIMS(TRUE)
|
|
FORCE_FOUND_SCREEN_ON_DETECTOR()
|
|
|
|
SET_CONTROL_SHAKE(PLAYER_CONTROL, 200, 150)
|
|
|
|
// IF IS_PED_UNINJURED(PLAYER_PED_ID())
|
|
// // Reset the capsule during the cutscenes so the Epsilonists aren't affected by it (#709181)
|
|
// SET_PED_CAPSULE(PLAYER_PED_ID(), 0)
|
|
// bCapsuleResized = FALSE
|
|
// ENDIF
|
|
|
|
IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY()
|
|
DEBUG_PRINTSTRING("Trying to set player component variation")
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
SET_CUTSCENE_PED_COMPONENT_VARIATION_FROM_PED_SAFE("Michael", PLAYER_PED_ID())
|
|
ENDIF
|
|
IF iCurrentRock = 0
|
|
OR iCurrentRock = 2
|
|
DEBUG_PRINTSTRING("Trying to set Jimmy prop variation")
|
|
SET_CUTSCENE_PED_PROP_VARIATION("Jimmy_Boston", ANCHOR_EYES, 0)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF NOT IS_VEHICLE_OK(Eps_Vehicle)
|
|
Eps_Vehicle = CREATE_VEHICLE(Bison, <<1851.57, 4772.12, 39.80>>, 31.35)
|
|
SET_VEHICLE_COLOURS(Eps_Vehicle, 157, 157)
|
|
SET_VEHICLE_EXTRA_COLOURS(Eps_Vehicle, 5, 157)
|
|
SET_VEHICLE_ON_GROUND_PROPERLY(Eps_Vehicle)
|
|
ENDIF
|
|
|
|
// Clear buddy tasks and state immediately
|
|
SET_EPS_IDLE(epsilonianArray[ID_JIMMY])
|
|
SET_EPS_IDLE(epsilonianArray[ID_MARNIE])
|
|
|
|
IF IS_PED_UNINJURED(PLAYER_PED_ID())
|
|
// Final check to make sure the cutscene is ok to start
|
|
WHILE NOT RC_IS_CUTSCENE_OK_TO_START()
|
|
DEBUG_PRINTSTRING("Waiting for cutscene to be OK to start...")
|
|
// Hide the ammo counter, as the detector doesn't need it (#736243)
|
|
HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_WEAPON_ICON)
|
|
UPDATE_PLAYER_AND_DETECTOR_ANIMS(TRUE)
|
|
FORCE_FOUND_SCREEN_ON_DETECTOR()
|
|
SET_CONTROL_SHAKE(PLAYER_CONTROL, 200, 150)
|
|
// Request cutscene again using the RC version to 1) make sure it definitely gets loaded, and 2) to stop the player moving
|
|
IF iCurrentRock = 0
|
|
RC_REQUEST_MID_MISSION_CUTSCENE("EPS_4_MCS_1")
|
|
ELIF iCurrentRock = 1
|
|
RC_REQUEST_MID_MISSION_CUTSCENE("EPS_4_MCS_2")
|
|
ELSE
|
|
RC_REQUEST_MID_MISSION_CUTSCENE("EPS_4_MCS_3")
|
|
ENDIF
|
|
WAIT(0)
|
|
ENDWHILE
|
|
SET_PLAYER_FORCED_AIM(PLAYER_ID(), TRUE)
|
|
|
|
INT iTimer = GET_GAME_TIMER()
|
|
WHILE (GET_GAME_TIMER() - iTimer) < 500
|
|
DEBUG_PRINTSTRING("Doing 500ms pause")
|
|
// Hide the ammo counter, as the detector doesn't need it (#736243)
|
|
HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_WEAPON_ICON)
|
|
SET_PLAYER_FORCED_AIM(PLAYER_ID(), TRUE)
|
|
UPDATE_PLAYER_AND_DETECTOR_ANIMS(TRUE)
|
|
FORCE_FOUND_SCREEN_ON_DETECTOR()
|
|
SET_CONTROL_SHAKE(PLAYER_CONTROL, 200, 150)
|
|
WAIT(0)
|
|
ENDWHILE
|
|
|
|
// Setup cutscene gumph here
|
|
IF iCurrentRock = 0
|
|
|
|
IF IS_ENTITY_ALIVE(epsilonianArray[ID_JIMMY].hPed)
|
|
REGISTER_ENTITY_FOR_CUTSCENE(epsilonianArray[ID_JIMMY].hPed, "Jimmy_Boston", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
|
|
ENDIF
|
|
IF IS_ENTITY_ALIVE(epsilonianArray[ID_MARNIE].hPed)
|
|
REGISTER_ENTITY_FOR_CUTSCENE(epsilonianArray[ID_MARNIE].hPed, "Marnie", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
|
|
ENDIF
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
REGISTER_ENTITY_FOR_CUTSCENE(PLAYER_PED_ID(), "Michael", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
|
|
ENDIF
|
|
IF IS_ENTITY_ALIVE(gDetector.hObj)
|
|
DetectorCopy = CREATE_WEAPON_OBJECT_FROM_PED_WEAPON_WITH_COMPONENTS(PLAYER_PED_ID(), WEAPONTYPE_DIGISCANNER)
|
|
REGISTER_ENTITY_FOR_CUTSCENE(DetectorCopy, "Artefact_Detector", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
|
|
ENDIF
|
|
IF IS_ENTITY_ALIVE(rockArray[iCurrentRock].hObject)
|
|
REGISTER_ENTITY_FOR_CUTSCENE(rockArray[iCurrentRock].hObject, "EPS_TV", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
|
|
ENDIF
|
|
|
|
ELIF iCurrentRock = 1
|
|
|
|
IF IS_ENTITY_ALIVE(epsilonianArray[ID_MARNIE].hPed)
|
|
epsilonianArray[ID_MARNIE].bNotUsingNavmeshMove = FALSE
|
|
REGISTER_ENTITY_FOR_CUTSCENE(epsilonianArray[ID_MARNIE].hPed, "Marnie", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
|
|
ENDIF
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
REGISTER_ENTITY_FOR_CUTSCENE(PLAYER_PED_ID(), "Michael", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
|
|
ENDIF
|
|
IF IS_ENTITY_ALIVE(gDetector.hObj)
|
|
DetectorCopy = CREATE_WEAPON_OBJECT_FROM_PED_WEAPON_WITH_COMPONENTS(PLAYER_PED_ID(), WEAPONTYPE_DIGISCANNER)
|
|
REGISTER_ENTITY_FOR_CUTSCENE(DetectorCopy, "Artefact_Detector", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
|
|
ENDIF
|
|
IF IS_ENTITY_ALIVE(rockArray[iCurrentRock].hObject)
|
|
REGISTER_ENTITY_FOR_CUTSCENE(rockArray[iCurrentRock].hObject, "EPS_Battery", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
|
|
ENDIF
|
|
|
|
ELSE
|
|
|
|
IF IS_ENTITY_ALIVE(epsilonianArray[ID_JIMMY].hPed)
|
|
REGISTER_ENTITY_FOR_CUTSCENE(epsilonianArray[ID_JIMMY].hPed, "Jimmy_Boston", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
|
|
ENDIF
|
|
IF IS_ENTITY_ALIVE(epsilonianArray[ID_MARNIE].hPed)
|
|
REGISTER_ENTITY_FOR_CUTSCENE(epsilonianArray[ID_MARNIE].hPed, "Marnie", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
|
|
ENDIF
|
|
IF IS_ENTITY_ALIVE(gDetector.hObj)
|
|
DetectorCopy = CREATE_WEAPON_OBJECT_FROM_PED_WEAPON_WITH_COMPONENTS(PLAYER_PED_ID(), WEAPONTYPE_DIGISCANNER)
|
|
REGISTER_ENTITY_FOR_CUTSCENE(DetectorCopy, "Artefact_Detector", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
|
|
ENDIF
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
REGISTER_ENTITY_FOR_CUTSCENE(PLAYER_PED_ID(), "Michael", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
|
|
ENDIF
|
|
IF IS_ENTITY_ALIVE(rockArray[iCurrentRock].hObject)
|
|
REGISTER_ENTITY_FOR_CUTSCENE(rockArray[iCurrentRock].hObject, "Old_Boot", CU_ANIMATE_EXISTING_SCRIPT_ENTITY)
|
|
ENDIF
|
|
|
|
|
|
ENDIF
|
|
|
|
// Start cutscene
|
|
START_CUTSCENE()
|
|
|
|
REPLAY_START_EVENT(REPLAY_IMPORTANCE_LOW)
|
|
|
|
// Got to do this instead of wait(0) like other missions so we can call HIDE_HUD_COMPONENT_THIS_FRAME
|
|
iTimer = GET_GAME_TIMER()
|
|
WHILE (GET_GAME_TIMER() - iTimer) < 1
|
|
HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_WEAPON_ICON)
|
|
WAIT(0)
|
|
REPLAY_CHECK_FOR_EVENT_THIS_FRAME("SF_Epsilon4")
|
|
ENDWHILE
|
|
|
|
// Don't want Mike to have the detector after the last cutscene
|
|
IF iCurrentRock >= 2
|
|
IF IS_ENTITY_ALIVE(PLAYER_PED_ID())
|
|
GIVE_WEAPON_TO_PED(PLAYER_PED_ID(), WEAPONTYPE_UNARMED, INFINITE_AMMO, TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
SET_PLAYER_FORCED_AIM(PLAYER_ID(), FALSE)
|
|
RESOLVE_VEHICLES_INSIDE_ANGLED_AREA_WITH_SIZE_LIMIT(rockArray[iCurrentRock].vAngledArea1, rockArray[iCurrentRock].vAngledArea2, rockArray[iCurrentRock].fAngledAreaWidth,
|
|
rockArray[iCurrentRock].vWarpCarPos, rockArray[iCurrentRock].fWarpCarRot, GET_DEFAULT_ALLOWABLE_VEHICLE_SIZE_VECTOR())
|
|
RC_START_CUTSCENE_MODE(rockArray[iCurrentRock].vPos, TRUE, FALSE,
|
|
DEFAULT, DEFAULT, DEFAULT, DEFAULT, FALSE)
|
|
|
|
ENDIF
|
|
|
|
DEBUG_PRINTSI("Finished setup, moving to run loop for RockScene #:", iCurrentRock)
|
|
|
|
g_mission.section = SECTION_RUNNING
|
|
|
|
ENDIF
|
|
|
|
IF g_mission.section = SECTION_RUNNING
|
|
|
|
//-- Check for deaths
|
|
IF CHECK_FAIL_CONDITIONS_DURING_CUTSCENE()
|
|
|
|
ELIF g_mission.bRequestCpSkip
|
|
g_mission.section = SECTION_CLEANUP
|
|
|
|
ELIF g_mission.bRequestJSkip
|
|
IF (iCurrentRock < iRockCount-1)
|
|
QUEUE_MISSION_STAGE(MS_FINDROCK)
|
|
ELSE
|
|
QUEUE_MISSION_STAGE(MS_PASSED)
|
|
ENDIF
|
|
|
|
g_mission.section = SECTION_CLEANUP
|
|
iCurrentRock++
|
|
|
|
ELIF g_mission.bRequestPSkip
|
|
QUEUE_MISSION_STAGE(MS_FINDROCK)
|
|
g_mission.section = SECTION_CLEANUP
|
|
|
|
ELSE
|
|
|
|
// Timeout + skip checks
|
|
// IF IS_CUTSCENE_SKIP_BUTTON_JUST_PRESSED_WITH_DELAY()
|
|
//// bPlayerSkippedScene = TRUE
|
|
// g_mission.iEvent = -1
|
|
// ENDIF
|
|
|
|
IF iCurrentRock >= 2
|
|
IF IS_CUTSCENE_PLAYING()
|
|
IF GET_CUTSCENE_TIME() > 17000
|
|
IF NOT IS_NEW_LOAD_SCENE_ACTIVE()
|
|
NEW_LOAD_SCENE_START(<<1847.4722, 4756.1572, 36.6968>>, GET_HEADING_AS_VECTOR(271.4718), 145.0)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
// Run events
|
|
IF g_mission.iEvent = 0
|
|
|
|
FORCE_FOUND_SCREEN_ON_DETECTOR()
|
|
|
|
// Keep spamming for the blend
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
|
|
IF WAS_CUTSCENE_SKIPPED()
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
g_mission.iEvent = 1
|
|
ENDIF
|
|
|
|
DO_DETECTOR_EXIT()
|
|
|
|
IF iCurrentRock >= 2
|
|
|
|
DO_MARNIE_EXIT()
|
|
|
|
DO_JIMMY_EXIT()
|
|
|
|
ELIF iCurrentRock = 1
|
|
|
|
IF DO_MICHAEL_EXIT()
|
|
g_mission.iEvent = 1
|
|
ENDIF
|
|
|
|
DO_MARNIE_EXIT()
|
|
ELSE
|
|
|
|
IF DO_MICHAEL_EXIT()
|
|
g_mission.iEvent = 1
|
|
ENDIF
|
|
|
|
DO_MARNIE_EXIT()
|
|
|
|
DO_JIMMY_EXIT()
|
|
ENDIF
|
|
|
|
IF NOT IS_CUTSCENE_ACTIVE()
|
|
g_mission.iEvent = -1
|
|
DEBUG_PRINTSTRING("Cutscene not active, setting event -1")
|
|
ENDIF
|
|
ENDIF
|
|
|
|
IF g_mission.iEvent = 1
|
|
|
|
FORCE_NOT_FOUND_SCREEN_ON_DETECTOR()
|
|
|
|
DO_MICHAEL_EXIT()
|
|
|
|
DO_DETECTOR_EXIT()
|
|
|
|
IF iCurrentRock >= 2
|
|
|
|
DO_MARNIE_EXIT()
|
|
|
|
DO_JIMMY_EXIT()
|
|
|
|
ELIF iCurrentRock = 1
|
|
DO_MARNIE_EXIT()
|
|
ELSE
|
|
DO_MARNIE_EXIT()
|
|
|
|
DO_JIMMY_EXIT()
|
|
|
|
ENDIF
|
|
|
|
IF WAS_CUTSCENE_SKIPPED()
|
|
SET_GAMEPLAY_CAM_RELATIVE_PITCH()
|
|
SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
ENDIF
|
|
|
|
IF NOT IS_CUTSCENE_ACTIVE()
|
|
g_mission.iEvent = -1
|
|
DEBUG_PRINTSTRING("Cutscene not active, setting event -1")
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
// If complete...
|
|
IF g_mission.iEvent = -1
|
|
|
|
DEBUG_PRINTSTRING("Doing event -1...")
|
|
|
|
IF (iCurrentRock < iRockCount-1)
|
|
QUEUE_MISSION_STAGE(MS_FINDROCK)
|
|
ELSE
|
|
QUEUE_MISSION_STAGE(MS_WAITTOPASS)
|
|
ENDIF
|
|
|
|
IF iCurrentRock >= 2
|
|
TRIGGER_MUSIC_EVENT("EPS4_STOP")
|
|
SAFE_DELETE_OBJECT(rockArray[iCurrentRock].hObject)
|
|
ENDIF
|
|
|
|
g_mission.section = SECTION_CLEANUP
|
|
iCurrentRock++
|
|
DEBUG_PRINTSI("END CUTSCENE: iCurrentRock = ", iCurrentRock)
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
ENDIF
|
|
|
|
IF g_mission.section = SECTION_CLEANUP
|
|
REPLAY_STOP_EVENT()
|
|
DEBUG_PRINTSTRING("Doing cleanup for RockScene")
|
|
|
|
// IF IS_PED_UNINJURED(PLAYER_PED_ID())
|
|
// // Reset player in right direction
|
|
// IF (iCurrentRock < iRockCount)
|
|
// CLEAR_PED_TASKS_IMMEDIATELY(PLAYER_PED_ID())
|
|
// IF rockArray[iCurrentRock].fPostSceneRot >= 0.0
|
|
// SET_ENTITY_HEADING(PLAYER_PED_ID(), rockArray[iCurrentRock].fPostSceneRot)
|
|
// ENDIF
|
|
// ELSE
|
|
// CLEAR_PED_TASKS(PLAYER_PED_ID())
|
|
// ENDIF
|
|
//
|
|
// // Stop looking at the object
|
|
// TASK_CLEAR_LOOK_AT(PLAYER_PED_ID())
|
|
// ENDIF
|
|
|
|
// End custcene
|
|
// SET_GAMEPLAY_CAM_RELATIVE_HEADING()
|
|
RC_END_CUTSCENE_MODE(TRUE, FALSE)
|
|
|
|
// Change state
|
|
CHANGE_MISSION_STAGE()
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
PROC STAGE_Passwait()
|
|
|
|
SWITCH g_mission.section
|
|
|
|
CASE SECTION_SETUP
|
|
REQUEST_ANIM_DICT("weapons@holster_1h")
|
|
WHILE GET_PEDS_CURRENT_WEAPON(PLAYER_PED_ID()) = weapon_Detector
|
|
WAIT(0)
|
|
HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_WEAPON_ICON)
|
|
IF HAS_ANIM_DICT_LOADED("weapons@holster_1h")
|
|
IF NOT IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), "weapons@holster_1h", "holster")
|
|
TASK_PLAY_ANIM(PLAYER_PED_ID(), "weapons@holster_1h", "holster")
|
|
ELSE
|
|
IF GET_ENTITY_ANIM_CURRENT_TIME(PLAYER_PED_ID(), "weapons@holster_1h", "holster") >= 0.5
|
|
SET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_UNARMED, TRUE)
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDWHILE
|
|
HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_WEAPON_ICON)
|
|
REMOVE_WEAPON_FROM_PED(PLAYER_PED_ID(), weapon_Detector)
|
|
g_mission.section = SECTION_RUNNING
|
|
BREAK
|
|
|
|
CASE SECTION_RUNNING
|
|
|
|
HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_WEAPON_ICON)
|
|
|
|
//-- Check for deaths
|
|
IF IS_ENTITY_DEAD(PLAYER_PED_ID())
|
|
QUEUE_MISSION_STAGE(MS_FAILED)
|
|
g_mission.failReason = FAIL_REASON_PLAYER_DEAD
|
|
g_mission.section = SECTION_CLEANUP
|
|
|
|
ELIF IS_ENTITY_DEAD(epsilonianArray[ID_MARNIE].hPed)
|
|
QUEUE_MISSION_STAGE(MS_FAILED)
|
|
g_mission.failReason = FAIL_REASON_MARNIE_DEAD
|
|
g_mission.section = SECTION_CLEANUP
|
|
|
|
ELIF IS_ENTITY_DEAD(epsilonianArray[ID_JIMMY].hPed)
|
|
QUEUE_MISSION_STAGE(MS_FAILED)
|
|
g_mission.failReason = FAIL_REASON_JIMMY_DEAD
|
|
g_mission.section = SECTION_CLEANUP
|
|
|
|
ELIF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(epsilonianArray[ID_MARNIE].hPed, PLAYER_PED_ID(), TRUE)
|
|
AND HAS_ENTITY_BEEN_DAMAGED_BY_WEAPON(epsilonianArray[ID_MARNIE].hPed, WEAPONTYPE_INVALID, GENERALWEAPON_TYPE_ANYWEAPON)
|
|
QUEUE_MISSION_STAGE(MS_FAILED)
|
|
g_mission.failReason = FAIL_REASON_MARNIE_INJURED
|
|
g_mission.section = SECTION_CLEANUP
|
|
|
|
ELIF HAS_ENTITY_BEEN_DAMAGED_BY_ENTITY(epsilonianArray[ID_JIMMY].hPed, PLAYER_PED_ID(), TRUE)
|
|
AND HAS_ENTITY_BEEN_DAMAGED_BY_WEAPON(epsilonianArray[ID_JIMMY].hPed, WEAPONTYPE_INVALID, GENERALWEAPON_TYPE_ANYWEAPON)
|
|
QUEUE_MISSION_STAGE(MS_FAILED)
|
|
g_mission.failReason = FAIL_REASON_JIMMY_INJURED
|
|
g_mission.section = SECTION_CLEANUP
|
|
|
|
ELIF IS_EPS_THREATENED(epsilonianArray[ID_MARNIE])
|
|
QUEUE_MISSION_STAGE(MS_FAILED)
|
|
g_mission.failReason = FAIL_REASON_MARNIE_THREATENED
|
|
g_mission.section = SECTION_CLEANUP
|
|
|
|
ELIF IS_EPS_THREATENED(epsilonianArray[ID_JIMMY])
|
|
QUEUE_MISSION_STAGE(MS_FAILED)
|
|
g_mission.failReason = FAIL_REASON_JIMMY_THREATENED
|
|
g_mission.section = SECTION_CLEANUP
|
|
|
|
ELIF IS_ENTITY_ALIVE(epsilonianArray[ID_MARNIE].hPed)
|
|
IF GET_DISTANCE_BETWEEN_ENTITIES(PLAYER_PED_ID(), epsilonianArray[ID_MARNIE].hPed) >= 50
|
|
IF IS_NEW_LOAD_SCENE_ACTIVE()
|
|
NEW_LOAD_SCENE_STOP()
|
|
ENDIF
|
|
QUEUE_MISSION_STAGE(MS_PASSED)
|
|
g_mission.section = SECTION_CLEANUP
|
|
ENDIF
|
|
ENDIF
|
|
|
|
BREAK
|
|
|
|
CASE SECTION_CLEANUP
|
|
HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_WEAPON_ICON)
|
|
CHANGE_MISSION_STAGE()
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
ENDPROC
|
|
|
|
//*******************************************************************************************************************
|
|
//******************************************************************************************************************* STAGE: FailFade
|
|
/// PURPOSE:
|
|
/// Main stage for mission failure
|
|
PROC STAGE_FailFade()
|
|
|
|
SWITCH g_mission.section
|
|
|
|
CASE SECTION_SETUP
|
|
Script_TextCleanup()
|
|
|
|
TRIGGER_MUSIC_EVENT("EPS_FAIL")
|
|
|
|
// convert reason to string
|
|
STRING sFailType
|
|
sFailType = EMPTY_STRING
|
|
|
|
SWITCH (g_mission.failReason)
|
|
CASE FAIL_REASON_LEFT_AREA
|
|
sFailType = "EPS4_X1"
|
|
BREAK
|
|
|
|
CASE FAIL_REASON_MARNIE_DEAD
|
|
sFailType = "EPS4_X2"
|
|
BREAK
|
|
|
|
CASE FAIL_REASON_JIMMY_DEAD
|
|
sFailType = "EPS4_X3"
|
|
BREAK
|
|
|
|
CASE FAIL_REASON_MARNIE_INJURED
|
|
sFailType = "EPS4_X4"
|
|
BREAK
|
|
|
|
CASE FAIL_REASON_JIMMY_INJURED
|
|
sFailType = "EPS4_X5"
|
|
BREAK
|
|
|
|
CASE FAIL_REASON_MARNIE_THREATENED
|
|
sFailType = "EPS4_X7"
|
|
BREAK
|
|
|
|
CASE FAIL_REASON_JIMMY_THREATENED
|
|
sFailType = "EPS4_X8"
|
|
BREAK
|
|
|
|
DEFAULT
|
|
// no fail reason
|
|
BREAK
|
|
ENDSWITCH
|
|
|
|
IF ARE_STRINGS_EQUAL(sFailType, EMPTY_STRING)
|
|
Random_Character_Failed()
|
|
ELSE
|
|
Random_Character_Failed_With_Reason(sFailType)
|
|
ENDIF
|
|
|
|
g_mission.section = SECTION_RUNNING
|
|
BREAK
|
|
|
|
CASE SECTION_RUNNING
|
|
IF GET_MISSION_FLOW_SAFE_TO_CLEANUP()
|
|
|
|
// Do a check here to see if we need to warp the player at all
|
|
// (only set the fail warp locations if we can't leave the player where he was)
|
|
//MISSION_FLOW_SET_FAIL_WARP_LOCATION(<< 1831.4000, 4663.7002, 33.3069 >>, 2.1870)
|
|
//SET_REPLAY_DECLINED_VEHICLE_WARP_LOCATION(<< 1826.57, 4665.27, 34.74 >>, 113.53)
|
|
|
|
|
|
// delete everything here!
|
|
DELETE_ALL_ROCKS()
|
|
DELETE_EPS(epsilonianArray[ID_MARNIE])
|
|
DELETE_EPS(epsilonianArray[ID_JIMMY])
|
|
|
|
|
|
Script_Cleanup()
|
|
ELSE
|
|
// not finished fading out
|
|
// you may want to handle dialogue etc here.
|
|
ENDIF
|
|
BREAK
|
|
ENDSWITCH
|
|
ENDPROC
|
|
|
|
// ===========================================================================================================
|
|
// DEBUG FUNCTIONS
|
|
// ===========================================================================================================
|
|
|
|
#IF IS_DEBUG_BUILD
|
|
|
|
/// PURPOSE: Check for Forced Pass or Fail
|
|
|
|
PROC DEBUG_Check_Debug_Keys()
|
|
|
|
IF g_mission.section = SECTION_RUNNING
|
|
|
|
INT iMenuSelection
|
|
|
|
// Mission is running, so reset sync-for-skip flag
|
|
g_mission.bSyncForSkip = FALSE
|
|
|
|
// Check for Pass
|
|
IF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_S))
|
|
WAIT_FOR_CUTSCENE_TO_STOP()
|
|
TRIGGER_MUSIC_EVENT("EPS4_STOP")
|
|
Script_Passed()
|
|
|
|
// Check for Fail
|
|
ELIF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_F))
|
|
WAIT_FOR_CUTSCENE_TO_STOP()
|
|
QUEUE_MISSION_STAGE(MS_FAILED)
|
|
g_mission.failReason = FAIL_REASON_DEFAULT
|
|
g_mission.section = SECTION_CLEANUP
|
|
|
|
// Check for J skip
|
|
ELIF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_J))
|
|
g_mission.bRequestJSkip = TRUE
|
|
|
|
// Check for P skip
|
|
ELIF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_P))
|
|
g_mission.bRequestPSkip = TRUE
|
|
|
|
// Check for Z skip
|
|
ELIF LAUNCH_MISSION_STAGE_MENU(zSkipMenu, iMenuSelection, iMenuSelection)
|
|
IF iMenuSelection < 7
|
|
g_mission.queueCpSkip = iMenuSelection
|
|
g_mission.bRequestCpSkip = TRUE
|
|
ELSE
|
|
IF bLockAimPitch
|
|
bLockAimPitch = FALSE
|
|
ELSE
|
|
bLockAimPitch = TRUE
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
ENDIF
|
|
|
|
ENDPROC
|
|
|
|
#ENDIF
|
|
|
|
// ===========================================================================================================
|
|
// Script Loop
|
|
// ===========================================================================================================
|
|
|
|
SCRIPT(g_structRCScriptArgs sRCLauncherDataIn)
|
|
|
|
sRCLauncherDataLocal = sRCLauncherDataIn
|
|
RC_TakeEntityOwnership(sRCLauncherDataLocal)
|
|
|
|
SET_MISSION_FLAG(TRUE)
|
|
|
|
// Setup callback when player is killed, arrested or goes to multiplayer
|
|
IF (HAS_FORCE_CLEANUP_OCCURRED(DEFAULT_FORCE_CLEANUP_FLAGS|FORCE_CLEANUP_FLAG_DEBUG_MENU))
|
|
PRINT_LAUNCHER_DEBUG("Force cleanup [TERMINATING]")
|
|
Random_Character_Failed()
|
|
Script_Cleanup()
|
|
ENDIF
|
|
|
|
IF Is_Replay_In_Progress() // Set up the initial scene for replays
|
|
OR IS_REPEAT_PLAY_ACTIVE()
|
|
g_bSceneAutoTrigger = TRUE
|
|
eInitialSceneStage = IS_REQUEST_SCENE
|
|
WHILE NOT SetupScene_EPSILON_4(sRCLauncherDataLocal)
|
|
WAIT(0)
|
|
ENDWHILE
|
|
g_bSceneAutoTrigger = FALSE
|
|
ENDIF
|
|
|
|
mScenarioBlocker = Eps4_Scenario_Blocker()
|
|
mScenarioBlockerPicnic = ADD_SCENARIO_BLOCKING_AREA_FROM_POSITION_AND_RADIUS(<<1855.08, 4755.85, 36.81>>, 25.0)
|
|
|
|
iNavBlockerBush1 = ADD_NAVMESH_BLOCKING_OBJECT(<<1815.39, 4698.00, 38.87>>, <<3.5,3.5,3>>, 0)
|
|
iNavBlockerBush2 = ADD_NAVMESH_BLOCKING_OBJECT(<<1824.12, 4701.39, 38.29>>, <<2.5, 2.5, 2.5>>, 0)
|
|
iNavBlockerBush3 = ADD_NAVMESH_BLOCKING_OBJECT(<<1801.28, 4700.25, 39.42>>, <<2,2,2>>, 0)
|
|
|
|
IF NOT IS_AUDIO_SCENE_ACTIVE("EPSILONISM_04_MIX")
|
|
DEBUG_PRINTSTRING("Starting dynamic mix EPSILONISM_04_MIX")
|
|
START_AUDIO_SCENE("EPSILONISM_04_MIX")
|
|
ENDIF
|
|
|
|
//** Mission initialisation ***************
|
|
#IF IS_DEBUG_BUILD
|
|
SETUP_EPS4_WIDGETS()
|
|
#ENDIF
|
|
|
|
REGISTER_SCRIPT_WITH_AUDIO()
|
|
SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_LIKE, RELGROUPHASH_PLAYER, RELGROUPHASH_PLAYER)
|
|
SET_WANTED_LEVEL_MULTIPLIER(0.5)
|
|
|
|
grassCull = SET_GRASS_CULL_SPHERE(<< 1751.65, 4676.77, 43.03 >>, 1.5)
|
|
|
|
// Disable controls and exit current vehicle
|
|
RC_PLAYER_TRIGGER_SCENE_LOCK_IN()
|
|
|
|
INIT_DATA()
|
|
INIT_MISSION_DATA()
|
|
g_mission.stage = MS_LEADIN
|
|
|
|
//-- Setup world
|
|
INIT_DETECTOR()
|
|
|
|
INT i
|
|
REPEAT iRockCount i
|
|
CREATE_ROCK(rockArray[i])
|
|
ENDREPEAT
|
|
|
|
CREATE_EPS(epsilonianArray[ID_MARNIE], vPos_Epsilonian1, fRot_Epsilonian1, sRCLauncherDataLocal.pedID[ID_MARNIE])
|
|
CREATE_EPS(epsilonianArray[ID_JIMMY], vPos_Epsilonian2, fRot_Epsilonian2, sRCLauncherDataLocal.pedID[ID_JIMMY])
|
|
|
|
//-- Z-Skips / Replay check points
|
|
IF Is_Replay_In_Progress()
|
|
IF GET_REPLAY_MID_MISSION_STAGE() = 0
|
|
START_REPLAY_SETUP(vPos_PlayerReset, fRot_PlayerReset)
|
|
QUEUE_CP_SKIP(CP_FINDROCKA)
|
|
RC_SET_ENTITY_PROOFS_FOR_CUTSCENE(sRCLauncherDataLocal, FALSE)
|
|
CHANGE_MISSION_STAGE()
|
|
DEBUG_PRINTSTRING("Done replay setup")
|
|
ELSE
|
|
SCRIPT_ASSERT("Replay in progress: Unknown checkpoint selected")
|
|
ENDIF
|
|
ELIF IS_REPEAT_PLAY_ACTIVE()
|
|
START_REPLAY_SETUP(vPos_PlayerReset, fRot_PlayerReset)
|
|
QUEUE_CP_SKIP(CP_INTRO)
|
|
RC_SET_ENTITY_PROOFS_FOR_CUTSCENE(sRCLauncherDataLocal, TRUE)
|
|
CHANGE_MISSION_STAGE()
|
|
ENDIF
|
|
|
|
ADD_CONTACT_TO_PHONEBOOK(CHAR_MARNIE, MICHAEL_BOOK, FALSE)
|
|
|
|
//-- Mission loop *************************
|
|
WHILE(TRUE)
|
|
|
|
REPLAY_CHECK_FOR_EVENT_THIS_FRAME("SF_Epsilon4")
|
|
|
|
UPDATE_MISSION_NAME_DISPLAYING(sRCLauncherDataLocal.sIntroCutscene)
|
|
|
|
//DISPLAY_POLY2(g_polyPlayArea) // play area = red
|
|
//DISPLAY_POLY(g_polyFailArea, 100, 100, 255) // fail area = blue
|
|
|
|
SET_PLAYER_MAY_NOT_ENTER_ANY_VEHICLE(PLAYER_ID())
|
|
|
|
IF IS_PLAYER_IN_FIRST_PERSON_CAMERA()
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_SPRINT)
|
|
ENDIF
|
|
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_SPECIAL_ABILITY)
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_DUCK)
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_COVER)
|
|
|
|
IF IS_PED_UNINJURED(PLAYER_PED_ID())
|
|
IF GET_PEDS_CURRENT_WEAPON(PLAYER_PED_ID()) = weapon_Detector
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_ATTACK)
|
|
DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_ATTACK2)
|
|
ENDIF
|
|
ENDIF
|
|
|
|
SWITCH (g_mission.stage)
|
|
|
|
CASE MS_LEADIN
|
|
STAGE_LEADIN()
|
|
BREAK
|
|
|
|
CASE MS_INTRO
|
|
STAGE_INTRO()
|
|
BREAK
|
|
|
|
CASE MS_FINDROCK
|
|
STAGE_FINDROCK()
|
|
BREAK
|
|
|
|
CASE MS_ROCKSCENE
|
|
STAGE_ROCKSCENE()
|
|
BREAK
|
|
|
|
CASE MS_WAITTOPASS
|
|
STAGE_PASSWAIT()
|
|
BREAK
|
|
|
|
CASE MS_PASSED
|
|
Script_Passed()
|
|
BREAK
|
|
|
|
CASE MS_FAILED
|
|
STAGE_FailFade()
|
|
BREAK
|
|
|
|
ENDSWITCH
|
|
|
|
WAIT(0)
|
|
|
|
// Check debug completion/failure
|
|
#IF IS_DEBUG_BUILD
|
|
DEBUG_Check_Debug_Keys()
|
|
#ENDIF
|
|
ENDWHILE
|
|
|
|
SCRIPT_ASSERT("Script should never reach here. Always terminate with cleanup function.")
|
|
ENDSCRIPT
|
|
|