//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_camera.sch" USING "commands_pad.sch" USING "commands_script.sch" USING "flow_public_core_override.sch" USING "common_packages.sch" USING "scrap_common.sch" // ***************************************************************************************** // ***************************************************************************************** // ***************************************************************************************** // // MISSION NAME : epsilonTract.sc // AUTHOR : Joanna Wright // DESCRIPTION : Collect all the time capsules in order. Clues are iven for each one. // // ***************************************************************************************** // ***************************************************************************************** // ***************************************************************************************** CONST_INT TIME_DELAY_FOR_TEXT_STOLE_CASH 300000 CONST_INT TIME_DELAY_FOR_TEXT_GOOD_EPSILONIST 16000 MISSION_STAGE eStage = STAGE_INITIALISE MODEL_NAMES eTractModel = PROP_TIME_CAPSULE_01 INT iCurrentLocToFind = 0 INT iTimer_DelayForPhoneText = 0 INT iphoneTextDelay = 0 INT iMessageStage = 0 SCALEFORM_INDEX siMessage BOOL bDisplayMessage = FALSE BOOL bMessageOnDisplay = FALSE INT iMessageTimer = 0 SCRAP_PICKUP_DATA tractPickup[MAX_TRACT_PICKUPS] STRING helpText[MAX_TRACT_PICKUPS] // =========================================================================================================== // Debug // =========================================================================================================== #IF IS_DEBUG_BUILD USING "shared_debug.sch" BOOL bDebug_PrintToTTY = TRUE VECTOR warpCoords[MAX_TRACT_PICKUPS] WIDGET_GROUP_ID widgetGroup BOOL bWarpToScrap[MAX_TRACT_PICKUPS] BOOL bMapAlltractPickup BOOL bCollectAlltractPickup BOOL bResetAllTractPickups BOOL bSimulateProgress[MAX_TRACT_PICKUPS] /// PURPOSE: Returns clue for the specified pickup /// PARAMS: /// iIndex - the index of the specified pickup FUNC STRING GET_TRACT_CLUE(INT iIndex) SWITCH iIndex CASE 0 RETURN "WE WORSHIP KRAM WHERE THE EARTH REACHES UP TO KRAFF." BREAK CASE 1 RETURN "Where the first of the fleet succumbed to the waves, there the message is seeded." BREAK CASE 2 RETURN "When they sail from the North, they will find this offering." BREAK CASE 3 RETURN "In the core of the mountain, where the blast is not felt, there you shall find it." BREAK CASE 4 RETURN "In the rubble of the old religion, will be the basis for the new." BREAK CASE 5 RETURN "Where the first fleet sailed, the new fleet will find its map." BREAK CASE 6 RETURN "What dwelling is worthy of Kram? He is humble, yet we exult him." BREAK CASE 7 RETURN "We are not dinosaurs, or plants, but a tree in the jet stream may hold Kram's true word." BREAK CASE 8 RETURN "The tallest obelisk of glass and steel holds no comparison to the word of Kram." BREAK CASE 9 RETURN "Where they discard their earthly prisons, there you may find the germ of a higher civilisation." BREAK ENDSWITCH RETURN "Invalid Pickup Index" ENDFUNC /// PURPOSE: Creates widgets to teleport Player to the locations, blip locations etc PROC SETUP_TRACT_WIDGETS() TEXT_LABEL_63 tlTemp INT iIndex = 0 widgetGroup = START_WIDGET_GROUP("Tract Locations") ADD_WIDGET_BOOL("Show all tract locations on map", bMapAlltractPickup) ADD_WIDGET_BOOL("Visit all tract locations", bCollectAlltractPickup) ADD_WIDGET_BOOL("Reset all tract locations", bResetAllTractPickups) START_WIDGET_GROUP("Positions") REPEAT MAX_TRACT_PICKUPS iIndex tlTemp = "Tract[" tlTemp += iIndex tlTemp += "]" START_WIDGET_GROUP(tlTemp) ADD_WIDGET_STRING(GET_TRACT_CLUE(iIndex)) ADD_WIDGET_BOOL("Simulate progress", bSimulateProgress[iIndex]) ADD_WIDGET_BOOL("bWarp", bWarpToScrap[iIndex]) STOP_WIDGET_GROUP() ENDREPEAT STOP_WIDGET_GROUP() STOP_WIDGET_GROUP() iIndex = 0 REPEAT MAX_TRACT_PICKUPS iIndex bSimulateProgress[iIndex] = FALSE ENDREPEAT ENDPROC /// PURPOSE: collects the correct amount of scraps in order to warp the Player to the specified scrap /// PARAMS: /// index - the index of the scrap you wish to collect next (the one you will warp to) PROC SORT_DEBUG_SCRAP_COUNTING(INT index) INT i = 0 IF DOES_PICKUP_EXIST(tractPickup[iCurrentLocToFind].pickup) AND NOT (iCurrentLocToFind = index) REMOVE_PICKUP(tractPickup[iCurrentLocToFind].pickup) ENDIF iCurrentLocToFind = index //set previous scraps to collected if not already REPEAT MAX_TRACT_PICKUPS i IF (i < iCurrentLocToFind) #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION,"if not packed stat: ", i) ENDIF #ENDIF IF NOT GET_PACKED_STAT_BOOL(INT_TO_ENUM(STATS_PACKED, (PACKSTAT_TRACT_START + i))) SET_PACKED_STAT_BOOL(INT_TO_ENUM(STATS_PACKED, (PACKSTAT_TRACT_START + i)), TRUE) STAT_INCREMENT(NUM_HIDDEN_PACKAGES_2, 1.0) ENDIF ELSE #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_AMBIENT,"if packed stat: ", i) ENDIF #ENDIF IF GET_PACKED_STAT_BOOL(INT_TO_ENUM(STATS_PACKED, (PACKSTAT_TRACT_START + i))) SET_PACKED_STAT_BOOL(INT_TO_ENUM(STATS_PACKED, (PACKSTAT_TRACT_START + i)), FALSE) STAT_DECREMENT(NUM_HIDDEN_PACKAGES_2, 1.0) ENDIF ENDIF ENDREPEAT ENDPROC /// PURPOSE: Sorts out the correct functionality depending on if any widgets are selected PROC MAINTAIN_TRACT_WIDGETS() IF NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR) INT iIndex INT ipackNum REPEAT MAX_TRACT_PICKUPS iIndex IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) IF bSimulateProgress[iIndex] SORT_DEBUG_SCRAP_COUNTING(iIndex) bSimulateProgress[iIndex] = FALSE ENDIF IF bWarpToScrap[iIndex] DO_PLAYER_MAP_WARP_WITH_LOAD(warpCoords[iIndex]) INTERIOR_INSTANCE_INDEX intIndex = GET_INTERIOR_AT_COORDS(warpCoords[iIndex]) IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "Eps Tract: Need an interior...") ENDIF IF IS_VALID_INTERIOR(intIndex) IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "Eps Tract: Loading interior") ENDIF PIN_INTERIOR_IN_MEMORY(intIndex) WHILE NOT IS_INTERIOR_READY(intIndex) WAIT(0) ENDWHILE WAIT(0) UNPIN_INTERIOR(intIndex) ENDIF IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) IF IS_PED_SWIMMING_UNDER_WATER(PLAYER_PED_ID()) //so player doesn't automatically collect it FORCE_PED_MOTION_STATE(PLAYER_PED_ID(), MS_DIVING_IDLE) ENDIF SET_ENTITY_FACING(PLAYER_PED_ID(), tractPickup[iIndex].vCoords) ENDIF bWarpToScrap[iIndex] = FALSE ENDIF ENDIF MAP_SCRAP_CHECK(bMapAlltractPickup, tractPickup[iIndex].blip, iIndex, MAX_TRACT_PICKUPS, SCRAP_TRACT, tractPickup[iIndex].vCoords) IF bCollectAllTractPickup ipackNum = PACKSTAT_TRACT_START + iIndex SET_PACKED_STAT_BOOL(INT_TO_ENUM(STATS_PACKED, ipackNum), TRUE) STAT_INCREMENT(NUM_HIDDEN_PACKAGES_2, 1.0) iCurrentLocToFind = MAX_TRACT_PICKUPS ENDIF IF bResetAllTractPickups ipackNum = PACKSTAT_TRACT_START + iIndex IF GET_PACKED_STAT_BOOL(INT_TO_ENUM(STATS_PACKED, ipackNum)) SET_PACKED_STAT_BOOL(INT_TO_ENUM(STATS_PACKED, ipackNum), FALSE) STAT_DECREMENT(NUM_HIDDEN_PACKAGES_2, 1.0) ENDIF IF NOT (iIndex = 0) SAFE_REMOVE_PICKUP(tractPickup[iIndex].pickup) ENDIF iCurrentLocToFind = 0 ENDIF ENDREPEAT bCollectAlltractPickup = FALSE bResetAllTractPickups = FALSE ENDIF ENDPROC #ENDIF // =========================================================================================================== // Script Cleanup // =========================================================================================================== PROC SCRIPT_CLEANUP() INT iIndex = 0 #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "STAGE_CLEANUP") ENDIF IF DOES_WIDGET_GROUP_EXIST(widgetGroup) DELETE_WIDGET_GROUP(widgetGroup) ENDIF #ENDIF REPEAT MAX_TRACT_PICKUPS iIndex SAFE_REMOVE_PICKUP(tractPickup[iIndex].pickup) ENDREPEAT TERMINATE_THIS_THREAD() ENDPROC PROC SCRIPT_PASSED() Set_Mission_Flow_Flag_State(FLOWFLAG_EPSILON_UNLOCKED_TRACT, TRUE) //Krant be praised, the Tract is complete! No material possessions can match the feeling of enlightened satisfaction that you must now be feeling. //Instead, expand your knowledge at our secret ~b~www.epsilonprogram.com~s~ page, yet remember if you know nothing, then you know everything. Kifflom! FIRE_EMAIL_INTO_DYNAMIC_THREAD(DYNAMIC_THREAD_EPSILON_TRACT, TRACT_DONE, FALSE) Remove_Script_From_Relaunch_List(LAUNCH_BIT_RC_AMB_EPSILON_TRACT) eStage = STAGE_CLEANUP ENDPROC PROC DO_INITIALISE() INT iScrap = 0 INT ipackNum #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "TRACT_STAGE_INITIALISE") ENDIF warpCoords[0] = << 505.1541, 5602.3984, 796.9146 >> warpCoords[1] = <<2722.8655, -1255.5728, -27.9673>> warpCoords[2] = <<22.9464, 7641.9365, 17.2828>> warpCoords[3] = << -256.9334, 4733.3311, 135.8996 >> warpCoords[4] = <<-772.4346, -681.6366, 28.8548>> warpCoords[5] = << -1606.3145, 5260.2427, 1.1005 >> warpCoords[6] = <<-1803.4014, 401.5742, 111.8039>> warpCoords[7] = <<486.3900, 5615.3789, 788.0875>> warpCoords[8] = << -75.0000, -816.0000, 325.3656 >> warpCoords[9] = <<-1720.9717, -188.5656, 57.2576>> #ENDIF //text sent depends on if Player stole the money in a previous mission IF g_savedGlobals.sRandomChars.g_bStoleEpsilonCash //Kifflom. Your past sin was great but Kram is not without mercy. To redeem yourself you must write the tract...WE WORSHIP KRAM WHERE THE EARTH REACHES UP TO KRAFF. helpText[0] = "TRACT_HINT1B" iphoneTextDelay = TIME_DELAY_FOR_TEXT_STOLE_CASH ELSE //Kifflom brother, you now truly one of us and are ready to write the tract...WE WORSHIP KRAM WHERE THE EARTH REACHES UP TO KRAFF. helpText[0] = "TRACT_HINT1" iphoneTextDelay = TIME_DELAY_FOR_TEXT_GOOD_EPSILONIST ENDIF tractPickup[0].vCoords = << 501.9415, 5604.4292, 796.9146 >> tractPickup[1].vCoords = <<2658.18, -1361.14, -21.63>> helpText[1] = "TRACT_HINT2" tractPickup[2].vCoords = <<24.7139, 7644.3340, 18.0792>> helpText[2] = "TRACT_HINT3" tractPickup[3].vCoords = << -263.55, 4729.60, 137.37 >> helpText[3] = "TRACT_HINT4" tractPickup[4].vCoords = <<-771.98, -685.22, 28.86>> helpText[4] = "TRACT_HINT5" tractPickup[5].vCoords = << -1605.03, 5256.55, 1.08 >> helpText[5] = "TRACT_HINT6" tractPickup[6].vCoords = <<-1804.5464, 403.9298, 112.1966>> helpText[6] = "TRACT_HINT7" tractPickup[7].vCoords = <<484.2701, 5617.1748, 787.4708>> helpText[7] = "TRACT_HINT8" tractPickup[8].vCoords = << -75.1004, -819.0673, 325.3656 >> helpText[8] = "TRACT_HINT9" tractPickup[9].vCoords = <<-1725.34, -189.95, 57.52>> helpText[9] = "TRACT_HINT10" iTimer_DelayForPhoneText = GET_GAME_TIMER() //set up which pickup the Player is looking for REPEAT MAX_TRACT_PICKUPS iScrap ipackNum = PACKSTAT_TRACT_START + iScrap IF GET_PACKED_STAT_BOOL(INT_TO_ENUM(STATS_PACKED, ipackNum)) iCurrentLocToFind++ ENDIF ENDREPEAT eStage = STAGE_PROCESS ENDPROC /// PURPOSE: sort looking at scrap if close PROC SORT_HEADTRACKING_FOR_TRACT(VECTOR coord) IF IS_ENTITY_IN_RANGE_COORDS(PLAYER_PED_ID(), coord, 7.0) TASK_LOOK_AT_COORD(PLAYER_PED_ID(), coord, 100, SLF_WHILE_NOT_IN_FOV, SLF_LOOKAT_LOW) ENDIF ENDPROC /// PURPOSE: Checks if Player has reached current location. If they have, print hint for next /// After a short time, sends the first clue via text. PROC DO_PROCESS() IF IS_ENTITY_ALIVE(PLAYER_PED_ID()) AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR) // Fix for B*2204893 and B*2204914 // If you walk towards a tract piece and start Director Mode *just* as you're about to touch it, when you come back from DM you collect // the pickup immediately as the screen fades in. The onscreen message then said "0/10 collected" - I think this was because the stat system // hadn't reset itself when you picked it up, so SET_PACKED_STAT_BOOL (which the message relies on) seemed to fail. // If we wait for the screen to be faded in, this appears to work though? -IG AND NOT IS_SCREEN_FADED_OUT() IF iCurrentLocToFind < MAX_TRACT_PICKUPS //send first text with delay if not sent already IF (iCurrentLocToFind = 0) IF NOT HAS_ONE_TIME_HELP_DISPLAYED(FHM_FIRST_TRACT_CLUE) AND (GET_GAME_TIMER() - iTimer_DelayForPhoneText > iphoneTextDelay) SEND_TEXT_MESSAGE_TO_CHARACTER_BUFFER(CHAR_MICHAEL, CHAR_MARNIE, helpText[0], TXTMSG_UNLOCKED) SET_ONE_TIME_HELP_MESSAGE_DISPLAYED(FHM_FIRST_TRACT_CLUE) iTimer_DelayForPhoneText = -1 //halt message sending, it's been sent #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "Epsilon Tract: Send text message for tract 0") ENDIF #ENDIF ENDIF ELIF iCurrentLocToFind < MAX_TRACT_PICKUPS IF NOT (iTimer_DelayForPhoneText = -1) IF (GET_GAME_TIMER() - iTimer_DelayForPhoneText > 15000) SEND_TEXT_MESSAGE_TO_CHARACTER_BUFFER(CHAR_MICHAEL, CHAR_MARNIE, helpText[iCurrentLocToFind], TXTMSG_UNLOCKED) iTimer_DelayForPhoneText = -1 //halt message sending, it's been sent #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "Epsilon Tract: Send text message for tract ", iCurrentLocToFind) ENDIF #ENDIF ENDIF ENDIF ENDIF IF tractPickup[iCurrentLocToFind].bActive // If the tract pickup has been collected IF HAS_PICKUP_BEEN_COLLECTED(tractPickup[iCurrentLocToFind].pickup) OR HAS_PLAYER_COLLECTED_PICKUP_IN_WATER_VEHICLE(tractPickup[iCurrentLocToFind].pickup) IF DOES_ENTITY_EXIST(PLAYER_PED_ID()) TASK_CLEAR_LOOK_AT(PLAYER_PED_ID()) ENDIF SAFE_REMOVE_PICKUP(tractPickup[iCurrentLocToFind].pickup) tractPickup[iCurrentLocToFind].bActive = FALSE SET_CONTROL_SHAKE(PLAYER_CONTROL, PICKUP_RUMBLE_DURATION, PICKUP_RUMBLE_FREQ) #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "Epsilon Tract: Picked up tract #", iCurrentLocToFind) ENDIF #ENDIF INT ipackNum = PACKSTAT_TRACT_START + iCurrentLocToFind SET_PACKED_STAT_BOOL(INT_TO_ENUM(STATS_PACKED, ipackNum), TRUE) STAT_INCREMENT(NUM_HIDDEN_PACKAGES_2, 1.0) #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY PRINT_SCRAP_NUMBER(iCurrentLocToFind) ENDIF #ENDIF bDisplayMessage = TRUE IF iCurrentLocToFind < MAX_TRACT_PICKUPS iCurrentLocToFind++ iTimer_DelayForPhoneText = GET_GAME_TIMER() //reset timer for message sending SET_AUTOSAVE_IGNORES_ON_MISSION_FLAG(TRUE) MAKE_AUTOSAVE_REQUEST() #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "Epsilon Tract: Incremented tract to #", iCurrentLocToFind) ENDIF #ENDIF ENDIF // The tract pickup hasn't been collected ELIF DOES_PICKUP_EXIST(tractPickup[iCurrentLocToFind].pickup) SORT_HEADTRACKING_FOR_TRACT(tractPickup[iCurrentLocToFind].vCoords) REMOVE_SCRAP_WHEN_OUT_OF_RANGE(tractPickup[iCurrentLocToFind].pickup, tractPickup[iCurrentLocToFind].bActive) ENDIF ELSE INT iScrap WHILE HAS_PLAYER_PICKED_UP_SCRAP(SCRAP_TRACT, iScrap) AND iScrap < MAX_TRACT_PICKUPS iScrap++ ENDWHILE // We need to create the tract pickup IF iScrap = iCurrentLocToFind CREATE_SCRAP_WHEN_IN_RANGE(tractPickup[iCurrentLocToFind], eTractModel) ENDIF ENDIF ELSE IF NOT bMessageOnDisplay AND NOT bDisplayMessage #IF IS_DEBUG_BUILD IF bDebug_PrintToTTY CPRINTLN(DEBUG_MISSION, "Tract pickups all collected. Mission pass") ENDIF #ENDIF SCRIPT_PASSED() ENDIF ENDIF UPDATE_DISPLAY_MESSAGE(bDisplayMessage, bMessageOnDisplay, iMessageTimer, SCRAP_TRACT, iMessageStage, siMessage, "TRACT_TITLE", "TRACT_COLLECT") ENDIF ENDPROC // =========================================================================================================== // Script Loop // =========================================================================================================== SCRIPT // Setup death/arrest callbacks IF HAS_FORCE_CLEANUP_OCCURRED(FORCE_CLEANUP_FLAG_DEBUG_MENU|FORCE_CLEANUP_FLAG_SP_TO_MP|FORCE_CLEANUP_FLAG_REPEAT_PLAY | FORCE_CLEANUP_FLAG_DIRECTOR) SCRIPT_CLEANUP() ENDIF // Stop multiple instances of the same script from running IF GET_NUMBER_OF_THREADS_RUNNING_THE_SCRIPT_WITH_THIS_HASH (HASH("epsilonTract")) > 1 CPRINTLN(DEBUG_MISSION, "Epsilon Tract is attempting to launch with an instance already active.") TERMINATE_THIS_THREAD() 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_TRACT) // Setup debug widgets #IF IS_DEBUG_BUILD SETUP_TRACT_WIDGETS() #ENDIF // Main loop WHILE (TRUE) // The wait must go here otherwise SPCID_RESET_EPSILON_TRACT won't reset flags in time... WAIT(0) SWITCH eStage CASE STAGE_INITIALISE DO_INITIALISE() BREAK CASE STAGE_PROCESS DO_PROCESS() BREAK CASE STAGE_CLEANUP SCRIPT_CLEANUP() BREAK ENDSWITCH #IF IS_DEBUG_BUILD MAINTAIN_TRACT_WIDGETS() #ENDIF ENDWHILE // Script should never reach here. Always terminate with cleanup function. ENDSCRIPT