//Compile out Title Update changes to header functions. //Must be before includes. //CONST_INT USE_TU_CHANGES 0 // Removed by Kenneth R. USING "cutscene_public.sch" USING "RC_launcher_public.sch" USING "RC_Setup_public.sch" USING "initial_scenes_Epsilon.sch" // ***************************************************************************************** // SCRIPT NAME : launcher_Epsilon.sc // // AUTHOR : David Roberts / Andrew Minghella // // DESCRIPTION : Launcher script that determines which RC mission scene to setup. // This launcher script should be attached to appropriate world point. // // If multiple missions share same coord or are within close proximity, // we should just add one world point, and adjust the tolerance float. // ***************************************************************************************** ENUM EPS_CONV_STATE EPS_CONV_WAITING, EPS_CONV_DOLINE, EPS_CONV_SPEAKING ENDENUM ENUM EPS6_WANDER_STATE WANDER_INIT, WANDER_GOTO, WANDER_NOWGOINGTO, WANDER_IDLEANIM, WANDER_IDLEFINISH ENDENUM // ------------Variables---------------------- // Constants CONST_FLOAT WORLD_POINT_COORD_TOLERANCE 5.0 CONST_FLOAT HELP_TEXT_RESET_DISTANCE 25.0 SCENARIO_BLOCKING_INDEX mScenarioBlocker INT iCutsceneLoadRequestID = NULL_OFFMISSION_CUTSCENE_REQUEST EPS_CONV_STATE EpsConv = EPS_CONV_WAITING structPedsForConversation ConvStruct INT iConvTimer BOOL bDoConv = FALSE // Prevent Epsilon 4 conversation from looping BOOL bStorageRoomLocked = FALSE // Epsilon 2 storage room blocked when in a vehicle BLIP_INDEX biLeadIn // Blip for lead-in sequence SEQUENCE_INDEX siEps3Flee // Epsilon 4 detector things SCALEFORM_INDEX si_DetectorScaleform INT rt_ID INT iPhaseTimer INT iDetectorSndID EPS6_WANDER_STATE Eps6Wander = WANDER_INIT INT iWanderStage = 0 VECTOR vTomCoords[3] //-------------------Debug Functions------------------------ #IF IS_DEBUG_BUILD USING "shared_debug.sch" WIDGET_GROUP_ID m_WidgetGroup BOOL m_bGivePlayerCash = FALSE /// PURPOSE: /// Creates debug widgets for this mission /// PARAMS: /// eRCMissionToLaunch - which mission we want the widgets for PROC SETUP_DEBUG_WIDGETS(g_eRC_MissionIDs& eRCMissionToLaunch) TEXT_LABEL_63 money = "Give Player $" SWITCH eRCMissionToLaunch // Deliver $500 CASE RC_EPSILON_2 START_WIDGET_GROUP("Random Character: Epsilon 2") money += EPSILON_2_CASH_AMOUNT ADD_WIDGET_BOOL(money, m_bGivePlayerCash) STOP_WIDGET_GROUP() BREAK // Deliver $5000 CASE RC_EPSILON_3 START_WIDGET_GROUP("Random Character: Epsilon 3") money += EPSILON_3_CASH_AMOUNT ADD_WIDGET_BOOL(money, m_bGivePlayerCash) STOP_WIDGET_GROUP() BREAK // Deliver $10000 CASE RC_EPSILON_8 START_WIDGET_GROUP("Random Character: Epsilon 8") money += EPSILON_8_CASH_AMOUNT ADD_WIDGET_BOOL(money, m_bGivePlayerCash) STOP_WIDGET_GROUP() BREAK ENDSWITCH ENDPROC /// PURPOSE: /// Monitors for widgets being used to give player cash. /// PARAMS: /// eRCMissionToLaunch - which mission's widgets to monitor PROC UPDATE_DEBUG_WIDGETS(g_eRC_MissionIDs& eRCMissionToLaunch) IF m_bGivePlayerCash SWITCH eRCMissionToLaunch CASE RC_EPSILON_2 CREDIT_BANK_ACCOUNT(CHAR_MICHAEL, BAAC_DEFAULT_DEBUG, EPSILON_2_CASH_AMOUNT) BREAK CASE RC_EPSILON_3 CREDIT_BANK_ACCOUNT(CHAR_MICHAEL, BAAC_DEFAULT_DEBUG, EPSILON_3_CASH_AMOUNT) BREAK CASE RC_EPSILON_8 CREDIT_BANK_ACCOUNT(CHAR_MICHAEL, BAAC_DEFAULT_DEBUG, EPSILON_8_CASH_AMOUNT) BREAK ENDSWITCH m_bGivePlayerCash = FALSE ENDIF ENDPROC /// PURPOSE: /// Removes the debug widgets PROC CLEANUP_DEBUG_WIDGETS() IF DOES_WIDGET_GROUP_EXIST(m_WidgetGroup) DELETE_WIDGET_GROUP(m_WidgetGroup) ENDIF ENDPROC /// PURPOSE: Helper function that determines whether mission needs cash in order to launch FUNC BOOL Does_Mission_Require_Cash(g_eRC_MissionIDs& eRCMissionToLaunch) // Epsilon 2&3 require cash donations IF (eRCMissionToLaunch = RC_EPSILON_2) OR (eRCMissionToLaunch = RC_EPSILON_3) OR (eRCMissionToLaunch = RC_EPSILON_8) RETURN TRUE ELSE RETURN FALSE ENDIF ENDFUNC /// PURPOSE: Put player into outfit or give money if on autoplay PROC HANDLE_RC_RESTRICTIONS_ON_AUTOPLAY(g_eRC_MissionIDs& eRCMissionToLaunch) IF g_bFlowAutoplayInProgress SWITCH eRCMissionToLaunch // Michael needs to wear the Epsilon robes CASE RC_EPSILON_7 SET_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_OUTFIT, OUTFIT_P0_EPSILON) BREAK // Michael needs $ CASE RC_EPSILON_8 SET_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_OUTFIT, OUTFIT_P0_EPSILON) CREDIT_BANK_ACCOUNT(CHAR_MICHAEL, BAAC_UNLOGGED_SMALL_ACTION, EPSILON_8_CASH_AMOUNT) BREAK ENDSWITCH ENDIF ENDPROC #ENDIF // ----------Functions ------------------------- /// PURPOSE: /// Does any necessary cleanup and terminates the launcher's thread. /// PARAMS: /// sData - launcher data struct /// bCleanupEntities - do we want to cleanup the entities in the launcher struct PROC Script_Cleanup(g_structRCScriptArgs& sData, BOOL bCleanupEntities=TRUE) // Clear scene entities created by RC launcher IF bCleanupEntities PRINT_LAUNCHER_DEBUG("Cleaning up launcher script entities [TERMINATING]") RC_CleanupSceneEntities(sData, FALSE) ENDIF // Remove lead-in blip IF DOES_BLIP_EXIST(biLeadIn) REMOVE_BLIP(biLeadIn) ENDIF // Clear any cutscene requests with controller. IF iCutsceneLoadRequestID != NULL_OFFMISSION_CUTSCENE_REQUEST PRINT_LAUNCHER_DEBUG("SCRIPT TERMINATING: Ending off-mission cutscene request") END_OFFMISSION_CUTSCENE_REQUEST(iCutsceneLoadRequestID) ENDIF // Remove scenario blocking areas IF sData.eMissionID = RC_EPSILON_4 OR sData.eMissionID = RC_EPSILON_7 OR sData.eMissionID = RC_EPSILON_8 REMOVE_SCENARIO_BLOCKING_AREA(mScenarioBlocker) ENDIF // Cleanup debug functions #IF IS_DEBUG_BUILD CLEANUP_DEBUG_WIDGETS() #ENDIF // Unload launcher animation dictionary REMOVE_LAUNCHER_ANIM_DICT(sData.sAnims) // mission specific cleanup SWITCH sData.eMissionID CASE RC_EPSILON_1 //cleanup hill sfx (ocurs when player is far enough away to not hear the cleanup) SET_AMBIENT_ZONE_STATE("AZ_EPSILONISM_01_HILLS", FALSE) BREAK CASE RC_EPSILON_6 // this is the detector anim set used by the cultist in Epsilon 6 REMOVE_ANIM_DICT("rcmepsilonism6") BREAK ENDSWITCH // Stop launcher conversation STRING sConversationRoot SWITCH sData.eMissionID CASE RC_EPSILON_3 sConversationRoot = "EP3_RCM_L2" BREAK CASE RC_EPSILON_4 // this mission uses 2 conversations, so cleanup both RC_STOP_LAUNCHER_DIALOGUE("EPS4_AMBM") sConversationRoot = "EPS4_AMBJ" BREAK CASE RC_EPSILON_8 // this mission uses 2 conversations, so cleanup both RC_STOP_LAUNCHER_DIALOGUE("EPS8_AMB1") sConversationRoot = "EPS8_AMB2" BREAK ENDSWITCH RC_STOP_LAUNCHER_DIALOGUE(sConversationRoot) //B*1574385 - Force update to blip in RandChar Controller if mission wasn't launched IF bCleanupEntities SET_RC_AWAITING_TRIGGER(sData.eMissionID) ENDIF //B* 2089222 - Unblock quicksaving g_QuickSaveDisabledByScript = FALSE RC_LAUNCHER_END() // Kill the thread PRINT_LAUNCHER_DEBUG("SCRIPT TERMINATED") TERMINATE_THIS_THREAD() ENDPROC /// PURPOSE: Display relevant help text for specified Epsilon mission PROC Display_Help_Text(g_eRC_MissionIDs& eRCMissionToLaunch, BOOL& bDisplayHelp) IF bDisplayHelp SWITCH eRCMissionToLaunch CASE RC_EPSILON_7 PRINT_LAUNCHER_DEBUG("Need to wear robes to launch Epsilon 7...") PRINT_HELP_WITH_STRING("BADSUIT_HELP", "OUTFIT_P0_11") bDisplayHelp = FALSE BREAK CASE RC_EPSILON_8 PRINT_LAUNCHER_DEBUG("Need robes and $ to launch Epsilon 8...") PRINT_HELP_WITH_STRING_AND_NUMBER("NOCASH_HELP", "OUTFIT_P0_11", EPSILON_8_CASH_AMOUNT) bDisplayHelp = FALSE BREAK DEFAULT PRINT_LAUNCHER_DEBUG("Tried to show help text for invalid mission") BREAK ENDSWITCH ENDIF ENDPROC /// PURPOSE: Check to see whether we need to display the help text again... PROC Monitor_Help_Text(g_structRCScriptArgs& sData, BOOL& bDisplayHelp) // Help text has been recently displayed IF NOT bDisplayHelp // Reset call to display help text when player walks out of activation range IF IS_PLAYER_PLAYING(PLAYER_ID()) IF NOT IS_PED_INJURED(PLAYER_PED_ID()) IF (GET_DISTANCE_BETWEEN_COORDS(GET_ENTITY_COORDS(PLAYER_PED_ID()), sData.triggerLocate[0]) > HELP_TEXT_RESET_DISTANCE) PRINT_LAUNCHER_DEBUG("Resetting help text flag as player has moved out of range...") bDisplayHelp = TRUE ENDIF ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: /// Manages locking and unlocking the storage room for Epsilon 2 /// Also blocks quicksaving when in front of it PROC DO_EPS2_DOOR_UPDATE() IF IS_PLAYER_PLAYING(PLAYER_ID()) IF IS_PED_ON_FOOT(PLAYER_PED_ID()) IF bStorageRoomLocked SET_DOOR_STATE(DOORNAME_EPSILON2_STORAGE_ROOM, DOORSTATE_UNLOCKED) bStorageRoomLocked = FALSE ENDIF ELSE IF NOT bStorageRoomLocked SET_DOOR_STATE(DOORNAME_EPSILON2_STORAGE_ROOM, DOORSTATE_LOCKED) bStorageRoomLocked = TRUE ENDIF ENDIF ENDIF //Block quicksaving IF IS_ENTITY_IN_ANGLED_AREA( PLAYER_PED_ID(), <<244.966919,374.669586,104.457909>>, <<239.611908,360.304504,107.752342>>, 9.062500) g_QuickSaveDisabledByScript = TRUE ELSE g_QuickSaveDisabledByScript = FALSE ENDIF ENDPROC PROC SET_UP_EPS4_DETECTOR_SCREEN() 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(GET_WEAPONTYPE_MODEL(WEAPONTYPE_DIGISCANNER)) IF IS_NAMED_RENDERTARGET_REGISTERED("digiscanner") rt_ID = GET_NAMED_RENDERTARGET_RENDER_ID("digiscanner") ENDIF iDetectorSndID = GET_SOUND_ID() iPhaseTimer = GET_GAME_TIMER() 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) IF (GET_GAME_TIMER() - iPhaseTimer) > 1250 PLAY_SOUND_FROM_COORD(iDetectorSndID, "IDLE_BEEP_NPC", <<1827.06, 4700.52, 39.16>>, "EPSILONISM_04_SOUNDSET") iPhaseTimer = GET_GAME_TIMER() ENDIF ENDPROC /// PURPOSE: /// Does the initial scene conversation for Epsilon 4 PROC DO_EPS4_AMB() SWITCH EpsConv CASE EPS_CONV_WAITING EpsConv = EPS_CONV_DOLINE BREAK CASE EPS_CONV_DOLINE IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), <<1826.45, 4699.58, 38.15>>) <= 25.0 AND bDoConv = FALSE IF CREATE_CONVERSATION(ConvStruct, "EPS4AUD", "EPS4_AMBJ", CONV_PRIORITY_HIGH) EpsConv = EPS_CONV_SPEAKING bDoConv = TRUE ENDIF ENDIF BREAK CASE EPS_CONV_SPEAKING IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() EpsConv = EPS_CONV_WAITING ELIF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), <<1826.45, 4699.58, 38.15>>) >= 28.0 KILL_ANY_CONVERSATION() EpsConv = EPS_CONV_WAITING ENDIF BREAK ENDSWITCH ENDPROC /// PURPOSE: /// State machine to handle Tom wandering around at the start of Eps 6 PROC DO_EPS6_TOM(g_structRCScriptArgs &sData) IF IS_ENTITY_ALIVE(sData.pedID[0]) SWITCH Eps6Wander CASE WANDER_INIT iWanderStage = 0 vTomCoords[0] = <<-2887.15, 3197.88, 10.17>> vTomCoords[1] = <<-2888.92, 3203.76, 10.60>> vTomCoords[2] = <<-2895.37, 3199.37, 10.03>> REQUEST_ANIM_DICT("rcmepsilonism6") IF HAS_ANIM_DICT_LOADED("rcmepsilonism6") TASK_PLAY_ANIM(sData.pedID[0], "rcmepsilonism6", "cultist_upperstatic", DEFAULT, DEFAULT, -1, AF_UPPERBODY|AF_SECONDARY|AF_LOOPING) Eps6Wander = WANDER_GOTO PRINT_LAUNCHER_DEBUG("Initialised Eps 6 Tom state machine") ENDIF BREAK CASE WANDER_GOTO IF NOT IsPedPerformingTask(sData.pedID[0], SCRIPT_TASK_FOLLOW_NAV_MESH_TO_COORD) TASK_FOLLOW_NAV_MESH_TO_COORD(sData.pedID[0], vTomCoords[iWanderStage], PEDMOVEBLENDRATIO_WALK, DEFAULT_TIME_BEFORE_WARP) PRINT_LAUNCHER_DEBUG("Eps 6: Nav tasking Tom...") Eps6Wander = WANDER_NOWGOINGTO ENDIF BREAK CASE WANDER_NOWGOINGTO IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(sData.pedID[0], vTomCoords[iWanderStage]) <= 1.2 Eps6Wander = WANDER_IDLEANIM PRINT_LAUNCHER_DEBUG("Eps 6: Tom at coord; do idle anim") ENDIF BREAK CASE WANDER_IDLEANIM CLEAR_PED_TASKS(sData.pedID[0]) TASK_PLAY_ANIM(sData.pedID[0], "rcmepsilonism6", "cultist_idle_a", FAST_BLEND_IN, REALLY_SLOW_BLEND_OUT, -1, AF_FORCE_START) FORCE_PED_AI_AND_ANIMATION_UPDATE(sData.pedID[0]) Eps6Wander = WANDER_IDLEFINISH PRINT_LAUNCHER_DEBUG("Eps 6: Done Tom idle anim") BREAK CASE WANDER_IDLEFINISH IF IS_ENTITY_PLAYING_ANIM(sData.pedID[0], "rcmepsilonism6", "cultist_idle_a") IF GET_ENTITY_ANIM_CURRENT_TIME(sData.pedID[0], "rcmepsilonism6", "cultist_idle_a") >=0.98 IF iWanderStage >= 2 iWanderStage = 0 ELSE iWanderStage++ ENDIF TASK_PLAY_ANIM(sData.pedID[0], "rcmepsilonism6", "cultist_upperstatic", FAST_BLEND_IN, DEFAULT, -1, AF_UPPERBODY|AF_SECONDARY|AF_LOOPING) FORCE_PED_AI_AND_ANIMATION_UPDATE(sData.pedID[0]) Eps6Wander = WANDER_GOTO PRINT_LAUNCHER_DEBUG("Eps 6: Tom idle anim >0.98") ENDIF ELSE IF iWanderStage >= 2 iWanderStage = 0 ELSE iWanderStage++ ENDIF TASK_PLAY_ANIM(sData.pedID[0], "rcmepsilonism6", "cultist_upperstatic", DEFAULT, DEFAULT, -1, AF_UPPERBODY|AF_SECONDARY|AF_LOOPING) Eps6Wander = WANDER_GOTO PRINT_LAUNCHER_DEBUG("Eps 6: Tom idle anim not playing") ENDIF BREAK ENDSWITCH ENDIF ENDPROC /// PURPOSE: /// Guards say Kifflom to Michael at the mansion - Epsilon 8 PROC DO_EPS8_KIFFLOM() SWITCH EpsConv CASE EPS_CONV_WAITING IF (GET_GAME_TIMER() - iConvTimer) > 20000 //1 min delay between each Kifflom EpsConv = EPS_CONV_DOLINE ENDIF BREAK CASE EPS_CONV_DOLINE IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), <<-726.45, 33.33, 43.23>>) < 9 //Guy at the East entrance IF CREATE_CONVERSATION(ConvStruct, "EPS8AU", "EPS8_AMB1", CONV_PRIORITY_MEDIUM) //Kifflom. EpsConv = EPS_CONV_SPEAKING ENDIF ENDIF IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(), <<-666.55, 49.19, 42.08>>) < 9 //Guy at the West entrance IF CREATE_CONVERSATION(ConvStruct, "EPS8AU", "EPS8_AMB2", CONV_PRIORITY_MEDIUM) //Kifflom Zondar. EpsConv = EPS_CONV_SPEAKING ENDIF ENDIF BREAK CASE EPS_CONV_SPEAKING IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() iConvTimer = GET_GAME_TIMER() EpsConv = EPS_CONV_WAITING ENDIF BREAK ENDSWITCH ENDPROC /// PURPOSE: /// Guards kick off if player interferes with the initial scene - Epsilon 8 PROC DO_EPS8_KICK_OFF() SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_HATE,relgroupEpsilon8,RELGROUPHASH_PLAYER) IF GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(),<<-726.45, 33.33, 43.23>>) <= GET_DISTANCE_BETWEEN_ENTITY_AND_COORD(PLAYER_PED_ID(),<<-666.55, 49.19, 42.08>>) CREATE_CONVERSATION(ConvStruct, "EPS8AU", "EPS8_AMA1", CONV_PRIORITY_HIGH) //Protect the apocalype funds! ELSE CREATE_CONVERSATION(ConvStruct, "EPS8AU", "EPS8_AMA2", CONV_PRIORITY_HIGH) //Cleanse the unbeliever! ENDIF ENDPROC /// PURPOSE: /// Creates the initial scene FUNC BOOL LOAD_INITIAL_SCENE(g_structRCScriptArgs& sData) // Setup the correct initial scene SWITCH sData.eMissionID CASE RC_EPSILON_1 IF NOT SetupScene_EPSILON_1(sData) RETURN FALSE ENDIF BREAK CASE RC_EPSILON_2 IF NOT SetupScene_EPSILON_2(sData) RETURN FALSE ENDIF BREAK CASE RC_EPSILON_3 IF NOT SetupScene_EPSILON_3(sData) RETURN FALSE ENDIF BREAK CASE RC_EPSILON_4 IF NOT SetupScene_EPSILON_4(sData) RETURN FALSE ENDIF BREAK CASE RC_EPSILON_5 IF NOT SetupScene_EPSILON_5(sData) RETURN FALSE ENDIF BREAK CASE RC_EPSILON_6 IF NOT SetupScene_EPSILON_6(sData) RETURN FALSE ENDIF BREAK CASE RC_EPSILON_7 IF NOT SetupScene_EPSILON_7(sData) RETURN FALSE ENDIF BREAK CASE RC_EPSILON_8 IF NOT SetupScene_EPSILON_8(sData) RETURN FALSE ENDIF BREAK ENDSWITCH // Setup scenario blockers IF sData.eMissionID = RC_EPSILON_4 mScenarioBlocker = Eps4_Scenario_Blocker() ELIF sData.eMissionID = RC_EPSILON_7 mScenarioBlocker = Eps7_Scenario_Blocker() CLEAR_AREA_OF_PEDS(<<538.45, 3079.61, 39.27>>, 75.0) ELIF sData.eMissionID = RC_EPSILON_8 mScenarioBlocker = Eps8_Scenario_Blocker() ENDIF // Scene creation successful PRINT_LAUNCHER_DEBUG("Created initial scene") RETURN TRUE ENDFUNC /// PURPOSE: Does the player meet the requirements of this specific RCM FUNC BOOL IS_RC_SPECIFIC_RESTRICTION_MET(g_eRC_MissionIDs& eRCMissionToLaunch) SWITCH eRCMissionToLaunch // Michael needs to wear the Epsilon robes CASE RC_EPSILON_7 RETURN IS_PLAYER_IN_CORRECT_OUTFIT(eRCMissionToLaunch) BREAK // Michael needs $ CASE RC_EPSILON_8 IF IS_REPEAT_PLAY_ACTIVE() SET_PED_COMP_ITEM_AVAILABLE_SP(PLAYER_ZERO, COMP_TYPE_OUTFIT, OUTFIT_P0_EPSILON_WITH_MEDAL,TRUE) SET_PED_COMP_ITEM_ACQUIRED_SP(PLAYER_ZERO, COMP_TYPE_OUTFIT, OUTFIT_P0_EPSILON_WITH_MEDAL,TRUE) SET_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_OUTFIT, OUTFIT_P0_EPSILON_WITH_MEDAL,FALSE) CREDIT_BANK_ACCOUNT(CHAR_MICHAEL, BAAC_UNLOGGED_SMALL_ACTION, EPSILON_8_CASH_AMOUNT) ENDIF IF (GET_TOTAL_CASH(CHAR_MICHAEL) >= EPSILON_8_CASH_AMOUNT) OR (g_savedGlobals.sRandomChars.g_bFinalEpsilonPayment = TRUE) RETURN IS_PLAYER_IN_CORRECT_OUTFIT(eRCMissionToLaunch) ELSE RETURN FALSE ENDIF BREAK ENDSWITCH RETURN TRUE ENDFUNC /// PURPOSE: /// Main script loops /// PARAMS: /// in_coords - world point co-ords SCRIPT(coords_struct in_coords) // Launcher priority for streaming requests SET_THIS_IS_A_TRIGGER_SCRIPT(TRUE) RC_LAUNCHER_START() g_structRCScriptArgs sRCLauncherData // Scene information to pass to mission script VECTOR vInCoords = <<0,0,0>> // Stores world point location BOOL bDisplayHelp = TRUE // Whether we need to prompt help text //Reset all basic values of the data, so each scene has to set them up correctly RC_Reset_LauncherData(sRCLauncherData) // Update world point vInCoords = in_coords.vec_coord[0] // Determine which RC mission we are attempting to launch (currently done on a launcher by launcher basis) g_eRC_MissionIDs eRCMissions[8] eRCMissions[0] = RC_EPSILON_1 eRCMissions[1] = RC_EPSILON_2 eRCMissions[2] = RC_EPSILON_3 eRCMissions[3] = RC_EPSILON_4 eRCMissions[4] = RC_EPSILON_5 eRCMissions[5] = RC_EPSILON_6 eRCMissions[6] = RC_EPSILON_7 eRCMissions[7] = RC_EPSILON_8 // 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|FORCE_CLEANUP_FLAG_REPEAT_PLAY)) PRINT_LAUNCHER_DEBUG("Force cleanup [TERMINATING]") // Ensure candidate id is released in the event that the player has died // or been arrested prior to mission launch IF sRCLauncherData.eMissionID <> NO_RC_MISSION IF (g_RandomChars[sRCLauncherData.eMissionID].rcMissionCandidateID <> NO_CANDIDATE_ID) PRINT_LAUNCHER_DEBUG("Relinquishing candidate id...") Mission_Over(g_RandomChars[sRCLauncherData.eMissionID].rcMissionCandidateID) ENDIF ENDIF // Standard cleanup Script_Cleanup(sRCLauncherData) ENDIF // Pick which mission activated us IF NOT (DETERMINE_RC_TO_LAUNCH(eRCMissions, sRCLauncherData, vInCoords, WORLD_POINT_COORD_TOLERANCE)) RC_LAUNCHER_END() PRINT_LAUNCHER_DEBUG("SCRIPT TERMINATED") TERMINATE_THIS_THREAD() // B* 1510945 - don't call cleanup if nothing has been setup yet ENDIF // Check with the Random Character Controller to see if this script is allowed to launch IF NOT CAN_RC_LAUNCH(sRCLauncherData.eMissionID) RC_LAUNCHER_END() PRINT_LAUNCHER_DEBUG("SCRIPT TERMINATED") TERMINATE_THIS_THREAD() // B* 1510945 - don't call cleanup if nothing has been setup yet ENDIF // Halt launcher as we are incorrect character IF Random_Character_Blocked_Due_To_Character(sRCLauncherData.eMissionID) RC_LAUNCHER_END() PRINT_LAUNCHER_DEBUG("SCRIPT TERMINATED") TERMINATE_THIS_THREAD() // B* 1510945 - don't call cleanup if nothing has been setup yet ENDIF // The script is allowed to launch so set up the initial scene WHILE NOT LOAD_INITIAL_SCENE(sRCLauncherData) WAIT(0) IF NOT IS_WORLD_POINT_WITHIN_BRAIN_ACTIVATION_RANGE() PRINT_LAUNCHER_DEBUG("Player out of range [TERMINATING]") Script_Cleanup(sRCLauncherData) ENDIF ENDWHILE // Clears area of non-mission entities and blood decals CLEAR_AREA(vInCoords, sRCLauncherData.activationRange, TRUE) IF sRCLauncherData.eMissionID = RC_EPSILON_3 ADD_PED_FOR_DIALOGUE(ConvStruct, 3, sRCLauncherData.pedID[0], "MARNIE") ENDIF IF sRCLauncherData.eMissionID = RC_EPSILON_4 ADD_PED_FOR_DIALOGUE(ConvStruct, 4, sRCLauncherData.pedID[0], "MARNIE") ADD_PED_FOR_DIALOGUE(ConvStruct, 5, sRCLauncherData.pedID[1], "JIMMYBOSTON") iConvTimer = GET_GAME_TIMER() SET_UP_EPS4_DETECTOR_SCREEN() ENDIF IF sRCLauncherData.eMissionID = RC_EPSILON_5 ADD_PED_FOR_DIALOGUE(ConvStruct, 4, sRCLauncherData.pedID[0], "MARNIE") ENDIF IF sRCLauncherData.eMissionID = RC_EPSILON_8 ADD_PED_FOR_DIALOGUE(ConvStruct, 4, sRCLauncherData.pedID[0], "EPSGUARD5") ADD_PED_FOR_DIALOGUE(ConvStruct, 5, sRCLauncherData.pedID[1], "EPSGUARD6") ENDIF #IF IS_DEBUG_BUILD // Setup debug cash functions for Epsilon 2,3&8 IF Does_Mission_Require_Cash(sRCLauncherData.eMissionID) SETUP_DEBUG_WIDGETS(sRCLauncherData.eMissionID) ENDIF // Handle outfit/cash on autoplay HANDLE_RC_RESTRICTIONS_ON_AUTOPLAY(sRCLauncherData.eMissionID) #ENDIF // Loop to check conditions - should script terminate? or is player close enough to trigger mission? WHILE (TRUE) WAIT(0) // Is the player still in activation range? IF NOT IS_RC_FINE_AND_IN_RANGE(sRCLauncherData) // For B*900468: Security attack player if he interferes with Epsilon 8 initial scene IF sRCLauncherData.eMissionID = RC_EPSILON_8 AND (IS_WORLD_POINT_WITHIN_BRAIN_ACTIVATION_RANGE()) PRINT_LAUNCHER_DEBUG("Epsilon 8 kicking off! [TERMINATING]") MAKE_ALL_INITIAL_SCENE_PEDS_ATTACK_PLAYER(sRCLauncherData) DO_EPS8_KICK_OFF() ENDIF IF sRCLauncherData.eMissionID = RC_EPSILON_6 SET_VEHICLE_GEN_AVAILABLE(VEHGEN_EPSILON6_PLANE, TRUE) // Reenable the vehicle gen ENDIF Script_Cleanup(sRCLauncherData) ENDIF // Mission specific updates IF sRCLauncherData.eMissionID = RC_EPSILON_2 DO_EPS2_DOOR_UPDATE() IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<237.925980,360.299164,103.651520>>, <<244.689896,357.827728,107.322365>>, 4.75) SET_PED_MAX_MOVE_BLEND_RATIO(PLAYER_PED_ID(), PEDMOVEBLENDRATIO_WALK) ENDIF ELIF sRCLauncherData.eMissionID = RC_EPSILON_3 IF IS_ENTITY_ALIVE(sRCLauncherData.pedID[0]) IF NOT IS_PED_FLEEING(sRCLauncherData.pedID[0]) AND NOT IS_PED_RAGDOLL(sRCLauncherData.pedID[0]) PLAY_LAUNCHER_AMBIENT_DIALOGUE(sRCLauncherData, vInCoords, "EPS3AUD", "EP3_AMB", 3, "MARNIE", 500) ENDIF IF HAS_PLAYER_THREATENED_PED(sRCLauncherData.pedID[0]) IF HAS_ANIM_DICT_LOADED("rcmepsilonism3") OPEN_SEQUENCE_TASK(siEps3Flee) TASK_PLAY_ANIM(NULL, "rcmepsilonism3", "outro") TASK_SMART_FLEE_PED(NULL, PLAYER_PED_ID(), 200, -1) CLOSE_SEQUENCE_TASK(siEps3Flee) TASK_PERFORM_SEQUENCE(sRCLauncherData.pedID[0], siEps3Flee) ELSE TASK_SMART_FLEE_PED(sRCLauncherData.pedID[0], PLAYER_PED_ID(), 200, -1) ENDIF SET_PED_KEEP_TASK(sRCLauncherData.pedID[0], TRUE) SET_PED_AS_NO_LONGER_NEEDED(sRCLauncherData.pedID[0]) Script_Cleanup(sRCLauncherData) ENDIF ENDIF ELIF sRCLauncherData.eMissionID = RC_EPSILON_4 IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY() PRINT_LAUNCHER_DEBUG("Can request assets for cutscene entity in Eps 4") SET_CUTSCENE_PED_PROP_VARIATION("Jimmy_Boston", ANCHOR_EYES, 0) ENDIF FORCE_NOT_FOUND_SCREEN_ON_DETECTOR() IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<1826.621216,4698.734375,41.368622>>, <<1831.157593,4680.191406,32.426258>>, 16.50) IF NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID()) IF NOT IsPedPerformingTask(PLAYER_PED_ID(), SCRIPT_TASK_FOLLOW_NAV_MESH_TO_COORD) SET_PLAYER_CONTROL(PLAYER_ID(), FALSE, SPC_LEAVE_CAMERA_CONTROL_ON) TASK_FOLLOW_NAV_MESH_TO_COORD(PLAYER_PED_ID(), <<1827.34, 4697.22, 38.02>>, PEDMOVEBLENDRATIO_WALK, DEFAULT_TIME_BEFORE_WARP, DEFAULT_NAVMESH_RADIUS, ENAV_NO_STOPPING) ENDIF ENDIF ENDIF DO_EPS4_AMB() ELIF sRCLauncherData.eMissionID = RC_EPSILON_5 IF IS_ENTITY_ALIVE(sRCLauncherData.pedID[0]) IF NOT IS_PED_FLEEING(sRCLauncherData.pedID[0]) AND NOT IS_PED_RAGDOLL(sRCLauncherData.pedID[0]) IF PLAY_LAUNCHER_FULL_CONVERSATION(sRCLauncherData, vInCoords, "EPS5AUD", "EP5_AMB", 4, "MARNIE", 1500) PRINT_LAUNCHER_DEBUG("Triggered Mary Ann Eps 5 conv") ENDIF ENDIF IF HAS_PLAYER_THREATENED_PED(sRCLauncherData.pedID[0]) IF IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() PRINT_LAUNCHER_DEBUG("Killed Eps 5 conversation (threat)") KILL_ANY_CONVERSATION() ENDIF TASK_SMART_FLEE_PED(sRCLauncherData.pedID[0], PLAYER_PED_ID(), 200, -1) SET_PED_KEEP_TASK(sRCLauncherData.pedID[0], TRUE) SET_PED_AS_NO_LONGER_NEEDED(sRCLauncherData.pedID[0]) Script_Cleanup(sRCLauncherData) ENDIF ENDIF ELIF sRCLauncherData.eMissionID = RC_EPSILON_6 DO_EPS6_TOM(sRCLauncherData) ELIF sRCLauncherData.eMissionID = RC_EPSILON_7 IF CAN_REQUEST_ASSETS_FOR_CUTSCENE_ENTITY() PRINT_LAUNCHER_DEBUG("Can request assets for cutscene entity in Eps 7") SET_CUTSCENE_PED_PROP_VARIATION("Jimmy_Boston", ANCHOR_EYES, 0) ENDIF ELIF sRCLauncherData.eMissionID = RC_EPSILON_8 DO_EPS8_KIFFLOM() ENDIF //Update launcher blip + preload intro SET_RC_AWAITING_TRIGGER(sRCLauncherData.eMissionID) MANAGE_PRELOADING_RC_CUTSCENE(iCutsceneLoadRequestID, sRCLauncherData.sIntroCutscene, vInCoords) // Check whether help text needs to be reset Monitor_Help_Text(sRCLauncherData, bDisplayHelp) // Monitor debug functions for Epsilon 2,3&8 #IF IS_DEBUG_BUILD IF Does_Mission_Require_Cash(sRCLauncherData.eMissionID) UPDATE_DEBUG_WIDGETS(sRCLauncherData.eMissionID) ENDIF #ENDIF // Is the player close enough to start the mission off IF ARE_RC_TRIGGER_CONDITIONS_MET(sRCLauncherData) IF NOT IS_RC_SPECIFIC_RESTRICTION_MET(sRCLauncherData.eMissionID) Display_Help_Text(sRCLauncherData.eMissionID, bDisplayHelp) ELSE // Create mission blip that persists for lead-in scene // Original will be removed when RC controller shuts down IF DOES_RC_MISSION_HAVE_LEAD_IN(sRCLauncherData.eMissionID) CREATE_BLIP_FOR_LEAD_IN(sRCLauncherData.eMissionID, biLeadIn) ENDIF // Launch the mission script IF NOT LAUNCH_RC_MISSION(sRCLauncherData) Script_Cleanup(sRCLauncherData) ENDIF // Waits in a loop until we can terminate the launcher - flagged from mission at the moment IF IS_RC_LAUNCHER_SAFE_TO_TERMINATE(sRCLauncherData.eMissionID) // No need to clean up entities as these should be owned by the mission script Script_Cleanup(sRCLauncherData, FALSE) ENDIF ENDIF ENDIF ENDWHILE // Script should never reach here. Always terminate with cleanup function. ENDSCRIPT