////////////////////////////////////////////////////////////////////////////////////////// // // // SCRIPT NAME : epsDesert.sc // // AUTHOR : Sam Hackett // // DESCRIPTION : Monitors the player to see when he has // // run x miles in the desert. // // // ////////////////////////////////////////////////////////////////////////////////////////// //Compile out Title Update changes to header functions. //Must be before includes. //CONST_INT USE_TU_CHANGES 0 // Removed by Kenneth R. // Includes USING "rage_builtins.sch" USING "globals.sch" USING "commands_entity.sch" USING "commands_hud.sch" USING "commands_object.sch" USING "commands_script.sch" USING "commands_streaming.sch" USING "commands_zone.sch" USING "CompletionPercentage_public.sch" USING "flow_public_core.sch" USING "player_ped_public.sch" USING "script_player.sch" USING "flow_public_game.sch" USING "RC_Helper_Functions.sch" USING "script_conversion.sch" // Constants PED_COMP_NAME_ENUM EPSILON_OUTFIT = OUTFIT_P0_EPSILON_WITH_MEDAL CONST_FLOAT DEBUG_INFO_X 0.8 CONST_FLOAT DEBUG_INFO_Y 0.3 CONST_FLOAT METRES_PER_MILE 1609.0 CONST_FLOAT METRES_PER_TENTH_MILE 160.9 CONST_INT TARGET_MILES 5 CONST_FLOAT MINIMUM_CHAT_DELAY 120000.0 CONST_FLOAT MAXIMUM_CHAT_DELAY 240000.0 PED_INDEX pedMarnie PED_INDEX pedJimmy PED_INDEX pedTom structPedsForConversation ConvStruct BOOL bGotMarnie BOOL bGotJimmy BOOL bGotTom INT iConvTimer FLOAT fNewThreshold // Enums ENUM DESERT_STAGE_ENUM STAGE_INITIALISE = 0, STAGE_PROCESS, STAGE_CLEANUP ENDENUM // Variables DESERT_STAGE_ENUM eStage = STAGE_INITIALISE FLOAT DISTANCE_TO_RUN = METRES_PER_MILE * TARGET_MILES //FEET_PER_MILE * 50 BOOL bDisplayDebugInfo = FALSE BOOL bForceOutfitOn = FALSE BOOL bForceOutfitOff = FALSE BOOL bAddMile = FALSE VECTOR vPreviousPos FLOAT fMessageMiles = 0.0 VECTOR vAbandonmentPos BOOL bInZone = FALSE BOOL bDoKifflom = FALSE BOOL bDoChatter = FALSE BOOL bDoCrisCall = FALSE BOOL bDoAbandonmentWarning = TRUE BOOL bDoAbandonmentReset = TRUE INT iKifflomTimes = -1 INT iKifflomCount = 0 INT iKifflomDelay INT iKifflomTimer FLOAT fChatterDelay INT iLastChatterTime #IF IS_DEBUG_BUILD USING "shared_debug.sch" WIDGET_GROUP_ID widgetGroup BOOL bDebug_PrintToTTY = TRUE /// PURPOSE: /// Initialises the widgets for the script PROC SETUP_DESERT_WIDGETS() widgetGroup = START_WIDGET_GROUP("Epsilon desert ambient") ADD_WIDGET_FLOAT_SLIDER("Distance run (metres)", g_savedGlobals.sAmbient.fDistRunInDesert, 0.0, DISTANCE_TO_RUN, 0.1) ADD_WIDGET_FLOAT_READ_ONLY("Target distance (metres)", DISTANCE_TO_RUN) ADD_WIDGET_BOOL("Is player inside zone? (Don't try changing this)", bInZone) ADD_WIDGET_BOOL("Enable on-screen progress info", bDisplayDebugInfo) ADD_WIDGET_BOOL("Force outfit on", bForceOutfitOn) ADD_WIDGET_BOOL("Force outfit off", bForceOutfitOff) ADD_WIDGET_STRING("Tick this to add just under 1 mile to Michael's total - walk forward ~15 meters to trigger the next progress message") ADD_WIDGET_BOOL("Add just under 0.1 miles to total run distance", bAddMile) ADD_WIDGET_BOOL("Force Michael to play CULT_TALK (only works if player is inside the zone)", bDoChatter) STOP_WIDGET_GROUP() ENDPROC /// PURPOSE: /// Cleans up the widgets for the script PROC CLEANUP_DESERT_WIDGETS() IF DOES_WIDGET_GROUP_EXIST(widgetGroup) DELETE_WIDGET_GROUP(widgetGroup) ENDIF ENDPROC #ENDIF FUNC BOOL IN_DIRECTOR_MODE_OR_TRANSITION() IF IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR) RETURN TRUE ELIF IS_SCREEN_FADED_OUT() // If the screen is faded out, we might be transitioning out of Director Mode in the few frames before it teleports the player back to the old position CPRINTLN(DEBUG_MISSION, "EpsDesert.sc - not in Director Mode, but the screen is faded out, pretending we are anyway...") RETURN TRUE ENDIF RETURN FALSE ENDFUNC /// PURPOSE: /// Tries to grab Marnie from the 32 closest peds around the player when called /// RETURNS: /// True if found Marnie FUNC BOOL GrabMarnie() INT cnt INT i PED_INDEX tmpArray[32] IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) cnt = GET_PED_NEARBY_PEDS(PLAYER_PED_ID(), tmpArray) ENDIF REPEAT cnt i IF IS_ENTITY_ALIVE(tmpArray[i]) IF (GET_ENTITY_MODEL(tmpArray[i]) = GET_NPC_PED_MODEL(CHAR_MARNIE)) #IF IS_DEBUG_BUILD CPRINTLN(DEBUG_AMBIENT, "Eps Robes: - Marnie get!") #ENDIF pedMarnie = tmpArray[i] IF NOT IS_ENTITY_A_MISSION_ENTITY(pedMarnie) SET_ENTITY_AS_MISSION_ENTITY(pedMarnie) ENDIF SET_PED_MONEY(pedMarnie, 0) SET_PED_CAN_BE_TARGETTED(pedMarnie, FALSE) SET_PED_NAME_DEBUG(pedMarnie, "POSTMARNIE") SET_PED_RELATIONSHIP_GROUP_HASH(pedMarnie, RELGROUPHASH_PLAYER) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(pedMarnie, FALSE) ADD_PED_FOR_DIALOGUE(ConvStruct, 4, pedMarnie, "MARNIE", TRUE) RETURN TRUE ENDIF ENDIF ENDREPEAT RETURN FALSE ENDFUNC /// PURPOSE: /// Tries to grab Jimmy from the 32 closest peds around the player when called /// RETURNS: /// True if found Jimmy FUNC BOOL GrabJimmy() INT cnt INT i PED_INDEX tmpArray[32] IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) cnt = GET_PED_NEARBY_PEDS(PLAYER_PED_ID(), tmpArray) ENDIF REPEAT cnt i IF IS_ENTITY_ALIVE(tmpArray[i]) IF (GET_ENTITY_MODEL(tmpArray[i]) = GET_NPC_PED_MODEL(CHAR_JIMMY_BOSTON)) #IF IS_DEBUG_BUILD CPRINTLN(DEBUG_AMBIENT, "Eps Robes: - Jimmy get!") #ENDIF pedJimmy = tmpArray[i] IF NOT IS_ENTITY_A_MISSION_ENTITY(pedJimmy) SET_ENTITY_AS_MISSION_ENTITY(pedJimmy) ENDIF SET_PED_MONEY(pedJimmy, 0) SET_PED_CAN_BE_TARGETTED(pedJimmy, FALSE) SET_PED_NAME_DEBUG(pedJimmy, "POSTJIMMY") SET_PED_RELATIONSHIP_GROUP_HASH(pedJimmy, RELGROUPHASH_PLAYER) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(pedJimmy, FALSE) ADD_PED_FOR_DIALOGUE(ConvStruct, 3, pedJimmy, "JIMMYBOSTON", TRUE) RETURN TRUE ENDIF ENDIF ENDREPEAT RETURN FALSE ENDFUNC /// PURPOSE: /// Tries to grab Tom from the 32 closest peds around the player when called /// RETURNS: /// True if found Tom FUNC BOOL GrabTom() INT cnt INT i PED_INDEX tmpArray[32] IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) cnt = GET_PED_NEARBY_PEDS(PLAYER_PED_ID(), tmpArray) ENDIF REPEAT cnt i IF IS_ENTITY_ALIVE(tmpArray[i]) IF (GET_ENTITY_MODEL(tmpArray[i]) = IG_TOMEPSILON) #IF IS_DEBUG_BUILD CPRINTLN(DEBUG_AMBIENT, "Eps Robes: - Tom get!") #ENDIF pedTom = tmpArray[i] IF NOT IS_ENTITY_A_MISSION_ENTITY(pedTom) SET_ENTITY_AS_MISSION_ENTITY(pedTom) ENDIF SET_PED_MONEY(pedTom, 0) SET_PED_CAN_BE_TARGETTED(pedTom, FALSE) SET_PED_NAME_DEBUG(pedTom, "POSTTOM") SET_PED_RELATIONSHIP_GROUP_HASH(pedTom, RELGROUPHASH_PLAYER) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(pedTom, FALSE) ADD_PED_FOR_DIALOGUE(ConvStruct, 5, pedTom, "TOM", TRUE) RETURN TRUE ENDIF ENDIF ENDREPEAT RETURN FALSE ENDFUNC /// PURPOSE: Sets up the ambient desert script PROC DO_INITIALISE() #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "STAGE_INITIALISE") ENDIF #ENDIF IF g_savedGlobals.sAmbient.fDistRunInDesert < DISTANCE_TO_RUN bGotMarnie = GrabMarnie() bGotJimmy = GrabJimmy() bGotTom = GrabTom() IF IS_PLAYER_PLAYING(PLAYER_ID()) IF DOES_ENTITY_EXIST(PLAYER_PED_ID()) IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID()) vPreviousPos = GET_ENTITY_COORDS(PLAYER_PED_ID()) ENDIF ENDIF fMessageMiles = g_savedGlobals.sAmbient.fDistRunInDesert / METRES_PER_TENTH_MILE fNewThreshold = (METRES_PER_MILE*TARGET_MILES) eStage = STAGE_PROCESS fChatterDelay = GET_RANDOM_FLOAT_IN_RANGE(MINIMUM_CHAT_DELAY, MAXIMUM_CHAT_DELAY) iLastChatterTime = GET_GAME_TIMER() #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_AMBIENT, "STAGE_PROCESS") ENDIF #ENDIF ENDIF ELSE eStage = STAGE_CLEANUP ENDIF ENDPROC /// PURPOSE: /// Occasional Epsilonism chatter while Michael is doing his desert run PROC HANDLE_CHATTER() IF NOT IS_CURRENTLY_ON_MISSION_OF_ANY_TYPE() AND NOT IS_ENTITY_DEAD(PLAYER_PED_ID()) AND NOT IS_PED_INJURED(PLAYER_PED_ID()) AND NOT IS_AMBIENT_SPEECH_PLAYING(PLAYER_PED_ID()) IF bDoChatter = TRUE IF IS_PED_WALKING(PLAYER_PED_ID()) // This will only sound right if Michael's walking OR IS_PED_STILL(PLAYER_PED_ID()) PLAY_PED_AMBIENT_SPEECH(PLAYER_PED_ID(), "CULT_TALK", SPEECH_PARAMS_FORCE_FRONTEND) fChatterDelay = GET_RANDOM_FLOAT_IN_RANGE(MINIMUM_CHAT_DELAY, MAXIMUM_CHAT_DELAY) iLastChatterTime = GET_GAME_TIMER() bDoChatter = FALSE #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EpsDesert.sc - played Michael cult talk") ENDIF #ENDIF ENDIF ELSE IF (GET_GAME_TIMER() - iLastChatterTime) > fChatterDelay bDoChatter = TRUE // Do a bit of chatter ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: /// Handle Michael's "kifflom" speech as he sprints in the desert PROC HANDLE_CHANTS() IF NOT IS_CURRENTLY_ON_MISSION_OF_ANY_TYPE() AND NOT IS_ENTITY_DEAD(PLAYER_PED_ID()) AND NOT IS_PED_INJURED(PLAYER_PED_ID()) AND NOT IS_AMBIENT_SPEECH_PLAYING(PLAYER_PED_ID()) IF bDoKifflom = TRUE // This should be -1 the first time we enter this function, then won't do anything until we start another chant IF iKifflomTimes = -1 iKifflomTimes = GET_RANDOM_INT_IN_RANGE(2, 5) iKifflomTimer = GET_GAME_TIMER() iKifflomDelay = GET_RANDOM_INT_IN_RANGE(500, 750) ENDIF // Play a Kifflom if the count is less than the times we want IF iKifflomCount < iKifflomTimes IF NOT IS_AMBIENT_SPEECH_PLAYING(PLAYER_PED_ID()) // Check the delay before trying to play a Kifflom, to make it sound more natural IF (GET_GAME_TIMER() - iKifflomTimer) >= iKifflomDelay IF IS_PED_SPRINTING(PLAYER_PED_ID()) PLAY_PED_AMBIENT_SPEECH(PLAYER_PED_ID(), "KIFFLOM_SPRINTING", SPEECH_PARAMS_FORCE_FRONTEND) ELSE PLAY_PED_AMBIENT_SPEECH(PLAYER_PED_ID(), "KIFFLOM_RUNNING", SPEECH_PARAMS_FORCE_FRONTEND) ENDIF iKifflomCount++ iKifflomDelay = GET_RANDOM_INT_IN_RANGE(500, 750) // Get a new delay #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EpsDesert: Mike Ambient speech") ENDIF #ENDIF ELSE #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EpsDesert: Delaying Kifflom by ", iKifflomDelay, "ms...") ENDIF #ENDIF ENDIF ELSE iKifflomTimer = GET_GAME_TIMER() // Continually reset the timer while previous Kifflom is playing ENDIF ELSE // Otherwise, we've played the amount we want, stop the chant and reset vars iKifflomCount = 0 iKifflomTimes = -1 bDoKifflom = FALSE ENDIF ENDIF ENDIF ENDPROC PROC HANDLE_RESET_INFO() // Epsilon pilgrimage abandoned. Come back another time to try again. IF bDoAbandonmentReset PRINT_HELP("EPSDES_WARN2") bDoAbandonmentReset = FALSE ENDIF ENDPROC PROC HANDLE_RESET_WARNING() // If you do not return to the desert, your Epsilonism pilgrimage will be abandoned. IF bDoAbandonmentWarning IF NOT IS_HELP_MESSAGE_BEING_DISPLAYED() PRINT_HELP("EPSDES_WARN") bDoAbandonmentWarning = FALSE ENDIF ENDIF ENDPROC PROC RESET_PROGRESS() g_savedGlobals.sAmbient.fDistRunInDesert = 0 fMessageMiles = 0 fNewThreshold = (METRES_PER_MILE*TARGET_MILES) ENDPROC VECTOR vNewPlayerPos STRING sZoneName /// PURPOSE: /// Add conditions for considering whether the player is in a valid robe area (including special cases) /// RETURNS: /// TRUE if in area, FALSE otherwise FUNC BOOL IS_PLAYER_IN_AREA() sZoneName = GET_NAME_OF_ZONE(vNewPlayerPos) IF ARE_STRINGS_EQUAL(sZoneName, "DESRT") OR ARE_STRINGS_EQUAL(sZoneName, "SENORA") OR ARE_STRINGS_EQUAL(sZoneName, "HARMO") OR ARE_STRINGS_EQUAL(sZoneName, "RTRAK") OR ARE_STRINGS_EQUAL(sZoneName, "SANDY") OR ARE_STRINGS_EQUAL(sZoneName, "Zancudo") OR ARE_STRINGS_EQUAL(sZoneName, "Alamo") OR ARE_STRINGS_EQUAL(sZoneName, "Jail") OR ARE_STRINGS_EQUAL(sZoneName, "zQ_UAR") OR ARE_STRINGS_EQUAL(sZoneName, "COSI") RETURN TRUE ENDIF RETURN FALSE ENDFUNC /// PURPOSE: Monitors how far player has run within valid areas PROC DO_PROCESS() FLOAT fDist PED_INDEX hPlayer IF g_savedGlobals.sAmbient.fDistRunInDesert < DISTANCE_TO_RUN IF bInZone = FALSE IF NOT IS_VECTOR_ZERO(vAbandonmentPos) AND NOT IN_DIRECTOR_MODE_OR_TRANSITION() // Fix for B*2193487 IF VDIST(vAbandonmentPos, GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE)) >= 10.0 RESET_PROGRESS() vAbandonmentPos = <<0,0,0>> HANDLE_RESET_INFO() BEGIN_TEXT_COMMAND_THEFEED_POST("EPSDES_WIPE") END_TEXT_COMMAND_THEFEED_POST_TICKER(FALSE) ELSE HANDLE_RESET_WARNING() ENDIF ENDIF ENDIF IF bGotMarnie IF IS_ENTITY_ALIVE(pedMarnie) // If the player is <=3m from Marnie, play one of his ambient lines, with an 8sec delay between them IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() AND NOT IS_PED_FLEEING(pedMarnie) AND NOT IS_PED_RAGDOLL(pedMarnie) AND NOT IS_PED_PRONE(pedMarnie) AND NOT IS_PED_INJURED(pedMarnie) IF GET_DISTANCE_BETWEEN_ENTITIES(pedMarnie, PLAYER_PED_ID()) <= 3.0 IF (GET_GAME_TIMER() - iConvTimer) > 8000 IF CREATE_CONVERSATION(ConvStruct, "EPSDAUD", "EPSD_FOLLOW", CONV_PRIORITY_MEDIUM) iConvTimer = GET_GAME_TIMER() ENDIF ENDIF ENDIF ENDIF IF GET_DISTANCE_BETWEEN_ENTITIES(pedMarnie, PLAYER_PED_ID()) > 150.0 SAFE_RELEASE_PED(pedMarnie) // Marnie won't be alive after this, it'll set the bool to false the frame after ENDIF ELSE SAFE_RELEASE_PED(pedMarnie) // In case she still exists but is dead - no point holding onto the ped index anymore bGotMarnie = FALSE ENDIF ENDIF IF bGotJimmy IF IS_ENTITY_ALIVE(pedJimmy) // If the player is <=3m from Jimmy, play one of his ambient lines, with an 8sec delay between them IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() AND NOT IS_PED_FLEEING(pedJimmy) AND NOT IS_PED_RAGDOLL(pedJimmy) AND NOT IS_PED_PRONE(pedJimmy) AND NOT IS_PED_INJURED(pedJimmy) IF GET_DISTANCE_BETWEEN_ENTITIES(pedJimmy, PLAYER_PED_ID()) <= 3.0 IF (GET_GAME_TIMER() - iConvTimer) > 8000 IF CREATE_CONVERSATION(ConvStruct, "EPSDAUD", "EPSD_FOLJIM", CONV_PRIORITY_MEDIUM) iConvTimer = GET_GAME_TIMER() ENDIF ENDIF ENDIF ENDIF IF GET_DISTANCE_BETWEEN_ENTITIES(pedJimmy, PLAYER_PED_ID()) > 150.0 SAFE_RELEASE_PED(pedJimmy) // Jimmy won't be alive after this, it'll set the bool to false the frame after ENDIF ELSE SAFE_RELEASE_PED(pedJimmy) // In case he still exists but is dead - no point holding onto the ped index anymore bGotJimmy = FALSE ENDIF ENDIF IF bGotTom IF IS_ENTITY_ALIVE(pedTom) // If the player is <=3m from Tom, play one of his ambient lines, with an 8sec delay between them IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() AND NOT IS_PED_FLEEING(pedTom) AND NOT IS_PED_RAGDOLL(pedTom) AND NOT IS_PED_PRONE(pedTom) AND NOT IS_PED_INJURED(pedTom) IF GET_DISTANCE_BETWEEN_ENTITIES(pedTom, PLAYER_PED_ID()) <= 3.0 IF (GET_GAME_TIMER() - iConvTimer) > 8000 IF CREATE_CONVERSATION(ConvStruct, "EPSDAUD", "EPSD_TOMFOL", CONV_PRIORITY_MEDIUM) iConvTimer = GET_GAME_TIMER() ENDIF ENDIF ENDIF ENDIF IF GET_DISTANCE_BETWEEN_ENTITIES(pedTom, PLAYER_PED_ID()) > 150.0 SAFE_RELEASE_PED(pedTom) // Tom won't be alive after this, it'll set the bool to false the frame after ENDIF ELSE SAFE_RELEASE_PED(pedTom) // In case he still exists but is dead - no point holding onto the ped index anymore bGotTom = FALSE ENDIF ENDIF IF IS_PED_THE_CURRENT_PLAYER_PED(CHAR_MICHAEL) IF IS_PLAYER_PLAYING(PLAYER_ID()) HANDLE_CHANTS() IF DOES_ENTITY_EXIST(PLAYER_PED_ID()) IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID()) vNewPlayerPos = GET_ENTITY_COORDS(PLAYER_PED_ID()) fDist = GET_DISTANCE_BETWEEN_COORDS(vPreviousPos, vNewPlayerPos) vPreviousPos = vNewPlayerPos ENDIF ENDIF IF IS_PED_ON_FOOT(PLAYER_PED_ID()) AND NOT IS_PED_FALLING(PLAYER_PED_ID()) AND NOT IS_PED_SWIMMING(PLAYER_PED_ID()) AND NOT IS_PED_ON_VEHICLE(PLAYER_PED_ID()) AND NOT IS_PED_RAGDOLL(PLAYER_PED_ID()) AND NOT IS_PED_PRONE(PLAYER_PED_ID()) AND NOT IS_PED_GETTING_UP(PLAYER_PED_ID()) IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<3155.104004,4091.060303,7.974625>>, <<-322.830872,2861.711914,250.525055>>, 2250.0) //IF IS_ENTITY_AT_COORD(PLAYER_PED_ID(), << 1658.4313, 3410.6929, 35.7253 >>, <<2500,2500,2500>>) IF IS_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_OUTFIT, EPSILON_OUTFIT) // PRINTSTRING("::::: ZONE: ") // Temp // PRINTSTRING(sZoneName) // PRINTSTRING("\n") IF IS_PLAYER_IN_AREA() AND NOT IN_DIRECTOR_MODE_OR_TRANSITION() // Fix for B*2193487 // Update notification text to tell player they're inside the zone IF bInZone = FALSE BEGIN_TEXT_COMMAND_THEFEED_POST("EPSDES_IN") END_TEXT_COMMAND_THEFEED_POST_TICKER(FALSE) bInZone = TRUE ENDIF HANDLE_CHATTER() // Only do the cult chatter if the player is in the area IF fDist > 0.01 IF fDist > 0.4 fDist = 0.4 ENDIF g_savedGlobals.sAmbient.fDistRunInDesert += fDist IF DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM() IF g_savedGlobals.sAmbient.fDistRunInDesert >= 8000.0 g_savedGlobals.sAmbient.fDistRunInDesert = DISTANCE_TO_RUN ENDIF ENDIF IF g_savedGlobals.sAmbient.fDistRunInDesert < (METRES_PER_MILE * TARGET_MILES) AND ((METRES_PER_MILE*TARGET_MILES) - g_savedGlobals.sAmbient.fDistRunInDesert) < (fNewThreshold - METRES_PER_TENTH_MILE) IF DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM() FLOAT fTemp = CONVERT_METERS_TO_KILOMETERS(g_savedGlobals.sAmbient.fDistRunInDesert) fMessageMiles = fTemp ELSE FLOAT fTemp = (g_savedGlobals.sAmbient.fDistRunInDesert/METRES_PER_TENTH_MILE) INT iMiles = FLOOR(fTemp) FLOAT fTemp2 = TO_FLOAT(iMiles) fTemp2 = fTemp2/10 fMessageMiles = fTemp2 ENDIF fNewThreshold = (METRES_PER_MILE*TARGET_MILES)-g_savedGlobals.sAmbient.fDistRunInDesert // If we're running metric, ignore the final 45m and skip to the goal now IF DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM() IF fMessageMiles >= 7.95 g_savedGlobals.sAmbient.fDistRunInDesert = DISTANCE_TO_RUN EXIT ENDIF ENDIF // "You have walked x miles in the desert in your robes." BEGIN_TEXT_COMMAND_THEFEED_POST("EPSDES_01") ADD_TEXT_COMPONENT_FLOAT(fMessageMiles, 1) END_TEXT_COMMAND_THEFEED_POST_TICKER(FALSE) bDoKifflom = TRUE MAKE_AUTOSAVE_REQUEST() // Autosave progress now //Disabled for now as conflicts with mile notifications - will need to add a delay for each one FLOAT fPenultimateCallDist IF DOES_CURRENT_LANGUAGE_USE_METRIC_SYSTEM() fPenultimateCallDist = 6.4 ELSE fPenultimateCallDist = 4.0 ENDIF IF fMessageMiles >= fPenultimateCallDist IF NOT bDoCrisCall #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_AMBIENT, "Eps Desert: Hit 4 miles/6.4 km, schedule a call...") ENDIF #ENDIF WHILE NOT REGISTER_CALL_FROM_CHARACTER_TO_PLAYER(CALL_EPSILON_DESERT_NEAR, CT_AMBIENT, BIT_MICHAEL, CHAR_CRIS, 6, 10000, 30000) WAIT(0) ENDWHILE bDoCrisCall = TRUE ENDIF ENDIF //SWITCH fMessageMiles /* CASE 1 #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "Eps Desert: Hit 1 mile, send a text...") ENDIF WHILE REGISTER_TEXT_MESSAGE_FROM_CHARACTER_TO_PLAYER(CT_AMBIENT, BIT_MICHAEL, CHAR_MARNIE, "EPSDES_MARNIE",TXTMSG_UNLOCKED,TXTMSG_CRITICAL,500) = -1 WAIT(0) ENDWHILE #ENDIF BREAK CASE 2 #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "Eps Desert: Hit 2 miles, send a text...") ENDIF WHILE REGISTER_TEXT_MESSAGE_FROM_CHARACTER_TO_PLAYER(CT_AMBIENT, BIT_MICHAEL, CHAR_JIMMY_BOSTON, "EPSDES_JIMMY",TXTMSG_UNLOCKED,TXTMSG_CRITICAL,500) = -1 WAIT(0) ENDWHILE #ENDIF BREAK CASE 3 #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "Eps Desert: Hit 3 miles, schedule a call...") ENDIF WHILE REGISTER_CALL_FROM_CHARACTER_TO_PLAYER(CT_AMBIENT, BIT_MICHAEL, CHAR_TREVOR, 2, 500,"EPSDAUD","EPSD_TREV","NONE","NONE") = -1 WAIT(0) ENDWHILE #ENDIF BREAK */ // CASE 4 // #IF IS_DEBUG_BUILD // IF bDebug_PrintToTTY // CPRINTLN(DEBUG_AMBIENT, "Eps Desert: Hit 4 miles, schedule a call...") // ENDIF // #ENDIF // WHILE NOT REGISTER_CALL_FROM_CHARACTER_TO_PLAYER(CALL_EPSILON_DESERT_NEAR, CT_AMBIENT, BIT_MICHAEL, CHAR_CRIS, 6, 10000, 30000) // WAIT(0) // ENDWHILE // // BREAK // ENDSWITCH ELSE #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_AMBIENT, "EpsDesert: ", ((METRES_PER_MILE*TARGET_MILES) - g_savedGlobals.sAmbient.fDistRunInDesert), " > ", (fNewThreshold - METRES_PER_TENTH_MILE), " (fNewThreshold - METRES_PER_TENTH_MILE)") ENDIF #ENDIF ENDIF ENDIF ELIF IN_DIRECTOR_MODE_OR_TRANSITION() // Fix for B*2193487 // Do nothing - player is in Director Mode and this script shouldn't count anything ELSE // Player is inside the locate but not inside the correct map zone IF bInZone = TRUE #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EpsDesert: Player inside locate but NOT in a correct map zone") ENDIF #ENDIF BEGIN_TEXT_COMMAND_THEFEED_POST("EPSDES_OUT") END_TEXT_COMMAND_THEFEED_POST_TICKER(FALSE) vAbandonmentPos = GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE) bInZone = FALSE ENDIF ENDIF ELSE // #IF IS_DEBUG_BUILD // IF bDebug_PrintToTTY // CPRINTLN(DEBUG_MISSION, "EpsDesert: Player's outfit is not the Epsilon one") // ENDIF // #ENDIF ENDIF ELSE // Player is not inside the locate at all, definitely not in range IF bInZone = TRUE AND NOT IN_DIRECTOR_MODE_OR_TRANSITION() // Fix for B*2193487 #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY VECTOR vTemp = GET_PLAYER_COORDS(PLAYER_ID()) CPRINTLN(DEBUG_MISSION, "EpsDesert: Player is not inside main locate, pos: ", vTemp) ENDIF #ENDIF BEGIN_TEXT_COMMAND_THEFEED_POST("EPSDES_OUT") END_TEXT_COMMAND_THEFEED_POST_TICKER(FALSE) vAbandonmentPos = GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE) bInZone = FALSE ENDIF ENDIF ELSE // #IF IS_DEBUG_BUILD // IF bDebug_PrintToTTY // CPRINTLN(DEBUG_MISSION, "EpsDesert: One of the conditions not valid to count miles...") // ENDIF // #ENDIF // Notification checks - the miles aren't being counted here because one of the conditions isn't true (e.g. player might be in a car) // but the player would probably appreciate being told anyway IF IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<3155.104004,4091.060303,7.974625>>, <<-322.830872,2861.711914,250.525055>>, 2250.0) IF NOT IS_PLAYER_IN_AREA() // Player is inside the locate but not inside the correct map zone IF bInZone = TRUE AND NOT IN_DIRECTOR_MODE_OR_TRANSITION() // Fix for B*2193487 #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EpsDesert: Player is inside main locate, but not correct map zone (2)") ENDIF #ENDIF BEGIN_TEXT_COMMAND_THEFEED_POST("EPSDES_OUT") END_TEXT_COMMAND_THEFEED_POST_TICKER(FALSE) vAbandonmentPos = GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE) bInZone = FALSE ENDIF ELSE // Update notification text to tell player they're inside the zone IF bInZone = FALSE AND NOT IN_DIRECTOR_MODE_OR_TRANSITION() // Fix for B*2193487 BEGIN_TEXT_COMMAND_THEFEED_POST("EPSDES_IN") END_TEXT_COMMAND_THEFEED_POST_TICKER(FALSE) bInZone = TRUE ENDIF ENDIF ELSE // Player is not inside the locate at all, definitely not in range IF bInZone = TRUE AND NOT IN_DIRECTOR_MODE_OR_TRANSITION() // Fix for B*2193487 #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EpsDesert: Player is not inside main locate (2)") ENDIF #ENDIF BEGIN_TEXT_COMMAND_THEFEED_POST("EPSDES_OUT") END_TEXT_COMMAND_THEFEED_POST_TICKER(FALSE) vAbandonmentPos = GET_ENTITY_COORDS(PLAYER_PED_ID(), FALSE) bInZone = FALSE ENDIF ENDIF ENDIF IF bForceOutfitOn hPlayer = PLAYER_PED_ID() SET_PED_COMP_ITEM_CURRENT_SP(hPlayer, COMP_TYPE_OUTFIT, EPSILON_OUTFIT, FALSE) bForceOutfitOn = FALSE ENDIF IF bForceOutfitOff hPlayer = PLAYER_PED_ID() SET_PED_COMP_ITEM_CURRENT_SP(hPlayer, COMP_TYPE_OUTFIT, OUTFIT_P0_DEFAULT) bForceOutfitOff = FALSE ENDIF IF bAddMile g_savedGlobals.sAmbient.fDistRunInDesert += (METRES_PER_TENTH_MILE - 5) bAddMile = FALSE ENDIF ELSE IF DOES_ENTITY_EXIST(PLAYER_PED_ID()) IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID()) // Reset the stored previous pos because the player may have warped and we don't want that to count vPreviousPos = GET_ENTITY_COORDS(PLAYER_PED_ID()) ENDIF ENDIF IF NOT IS_PLAYER_PLAYING(PLAYER_ID()) #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "EpsDesert: Player is no longer playing!") ENDIF #ENDIF ENDIF ENDIF IF bDisplayDebugInfo DISPLAY_TEXT_WITH_FLOAT(DEBUG_INFO_X, DEBUG_INFO_Y, "EPSDES_D0", DISTANCE_TO_RUN - g_savedGlobals.sAmbient.fDistRunInDesert, 1) //DISPLAY_TEXT_WITH_NUMBER(0.1, 0.3, "EPSDES_D1", iMessageMiles) DISPLAY_TEXT_WITH_FLOAT(0.1, 0.4, "EPSDES_D2", fMessageMiles, 1) ENDIF ENDIF ELSE // "You have walked 5 miles in the desert and completed the Epsilonist trial." BEGIN_TEXT_COMMAND_THEFEED_POST("EPSDES_02") END_TEXT_COMMAND_THEFEED_POST_TICKER(TRUE) // Ambient passed music MISSION_FLOW_PLAY_END_OF_MISSION_MUSIC(TRUE) // Cris sends Michael a congratulatory text message // Don't use CT_END_OF_MISSION for this communication as that blocks // switching and a number of other things until it is sent! -BenR WHILE NOT REGISTER_CALL_FROM_CHARACTER_TO_PLAYER(CALL_EPSILON_DESERT_DONE, CT_AMBIENT, BIT_MICHAEL, CHAR_CRIS, 6, 10000, 30000) WAIT(0) ENDWHILE eStage = STAGE_CLEANUP ENDIF ENDPROC /// PURPOSE: Cleans up any assets that were created PROC CLEANUP_SCRIPT() #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "STAGE_CLEANUP") ENDIF #ENDIF // Register completion stats when completing normally or via debug IF g_savedGlobals.sAmbient.fDistRunInDesert >= DISTANCE_TO_RUN OR GET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_EPSILON_DESERT_DONE) = TRUE MAKE_AUTOSAVE_REQUEST() // Autosave now // Set the flow flag so the Epsilon Random Character mission can be started Set_Mission_Flow_Flag_State(FLOWFLAG_EPSILON_DESERT_DONE, TRUE) //Set epsilon step stat INT iCurrent STAT_GET_INT(NUM_EPSILON_STEP,iCurrent) IF iCurrent < 19 STAT_SET_INT(NUM_EPSILON_STEP,19) SET_ACHIEVEMENT_PROGRESS_SAFE(ENUM_TO_INT(ACH20),19) CPRINTLN(debug_dan,"Epsilon progress:",19) ENDIF // No longer require the script to be relaunched when loading from a savegame. Remove_Script_From_Relaunch_List(LAUNCH_BIT_RC_AMB_EPSILON_DESERT) // Flag completion to the 100% system REGISTER_SCRIPT_IN_COMPLETION_PERCENTAGE_TOTAL ( CP_RAND_C_EPS7 ) ENDIF #IF IS_DEBUG_BUILD CLEANUP_DESERT_WIDGETS() #ENDIF TERMINATE_THIS_THREAD() ENDPROC SCRIPT // Setup callback IF HAS_FORCE_CLEANUP_OCCURRED(FORCE_CLEANUP_FLAG_DEBUG_MENU|FORCE_CLEANUP_FLAG_SP_TO_MP|FORCE_CLEANUP_FLAG_DIRECTOR) CLEANUP_SCRIPT() ENDIF // Register the script so that it can be relaunched when loading from a savegame. Register_Script_To_Relaunch_List(LAUNCH_BIT_RC_AMB_EPSILON_DESERT) #IF IS_DEBUG_BUILD SETUP_DESERT_WIDGETS() #ENDIF // Main loop WHILE TRUE WAIT(0) // Immediately cleanup if this script has been completed via debug IF GET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_EPSILON_DESERT_DONE) = TRUE CLEANUP_SCRIPT() ENDIF // State handler SWITCH eStage CASE STAGE_INITIALISE DO_INITIALISE() BREAK CASE STAGE_PROCESS DO_PROCESS() BREAK CASE STAGE_CLEANUP CLEANUP_SCRIPT() BREAK ENDSWITCH ENDWHILE ENDSCRIPT