//Compile out Title Update changes to header functions. //Must be before includes. //CONST_INT USE_TU_CHANGES 0 // Removed by Kenneth R. USING "rage_builtins.sch" USING "globals.sch" USING "commands_camera.sch" USING "commands_pad.sch" USING "commands_script.sch" USING "friendutil_private.sch" USING "flow_public_core.sch" USING "pb_prostitute_stats.sch" USING "script_usecontext.sch" USING "selector_public.sch" // ***************************************************************************************** // ***************************************************************************************** // ***************************************************************************************** // // MISSION NAME : shrinkLetter.sc // AUTHOR : // DESCRIPTION : Test script which generates the shrink letter displayed at the // end of the game after the end credits. // // ***************************************************************************************** // ***************************************************************************************** // ***************************************************************************************** // Constants CONST_INT TOTAL_MONEY_SPENT 1000000 // Money spent or saved CONST_INT STRIP_CLUB_DANCES 3 // Strip club - number of lap dances CONST_INT STRIP_CLUB_MONEY_SPENT 100 // Strip club - cash spent CONST_INT STOCKMARKET_TIME_SPENT 120000 // Stockmarket - time spent CONST_INT TOTAL_PEDS_KILLED 100 // Number of innocent peds killed CONST_INT TOTAL_VEHICLES_STOLEN 100 // Number of vehicles stolen CONST_INT FITNESS_LEVEL_FRANKLIN 50 // Fitness (Stamina, Strength, Lung Capacity) CONST_INT FITNESS_LEVEL_MICHAEL 50 CONST_INT FITNESS_LEVEL_TREVOR 50 CONST_INT TOTAL_STRANGERS_MET 10 // Number of RC's and RE's completed // Enums ENUM STAGE_LETTER SS_SETUP, SS_INIT, SS_UPDATE, SS_CLEANUP ENDENUM STAGE_LETTER eLetterStage = SS_SETUP // Structs STRUCT STRUCT_PSYCH_DATA INT iIntro TEXT_LABEL_3 tl3storychoice TEXT_LABEL_3 tl3mostplayedchar TEXT_LABEL_7 tl3moneyspent TEXT_LABEL_3 tl3stripclubs TEXT_LABEL_3 tl3prostitute TEXT_LABEL_3 tl3family TEXT_LABEL_3 tl3stockmarket TEXT_LABEL_3 tl3killpeds TEXT_LABEL_3 tl3stolenvehicles TEXT_LABEL_3 tl3yoga TEXT_LABEL_3 tl3fitness TEXT_LABEL_3 tl3strangers TEXT_LABEL_3 tl3collectables INT iSummary ENDSTRUCT // Variables SCALEFORM_INDEX siLetter STRUCT_PSYCH_DATA sUploadData INT iCloudLoadStage BOOL bCloudSuccess SIMPLE_USE_CONTEXT ucInstructions // Debug #IF IS_DEBUG_BUILD WIDGET_GROUP_ID widgetGroup BOOL bKilledMichael BOOL bKilledTrevor BOOL bPlayedFranklin BOOL bPlayedMichael BOOL bPlayedTrevor BOOL bSpentCash BOOL bStripClubs BOOL bProstitutes BOOL bMichaelFamily BOOL bStockMarket BOOL bKilledPeds BOOL bStoleVehicles BOOL bYoga BOOL bFitness BOOL bRandomChar BOOL bCollectables BOOL bUseDebug BOOL bUseScaleform BOOL bGenerateLetter #ENDIF /// PURPOSE: /// Returns randomised introduction line FUNC TEXT_LABEL_15 GET_SHRINK_INTRO(STRUCT_PSYCH_DATA &sPsychData) TEXT_LABEL_15 returnStr = "INTRO_" INT randInt = GET_RANDOM_INT_IN_RANGE(1,21) sPsychData.iIntro = randInt returnStr += randInt RETURN returnStr ENDFUNC /// PURPOSE: /// Returns line dependant on whether the player killed Michael, Trevor or saved both FUNC TEXT_LABEL_15 GET_SHRINK_STORY_CHOICE(STRUCT_PSYCH_DATA &sPsychData) TEXT_LABEL_15 returnStr = "STORY_" INT randInt // Debug choice #IF IS_DEBUG_BUILD IF bUseDebug IF bKilledMichael sPsychData.tl3storychoice = "M" returnStr += "M" randInt = GET_RANDOM_INT_IN_RANGE(1,11) ELIF bKilledTrevor sPsychData.tl3storychoice = "T" returnStr += "T" randInt = GET_RANDOM_INT_IN_RANGE(1,10) ELSE sPsychData.tl3storychoice = "B" returnStr += "B" randInt = GET_RANDOM_INT_IN_RANGE(1,11) ENDIF sPsychData.tl3storychoice += randInt returnStr += randInt RETURN returnStr ENDIF #ENDIF // Gameflow choice IF GET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_MICHAEL_KILLED) sPsychData.tl3storychoice = "M" returnStr += "M" randInt = GET_RANDOM_INT_IN_RANGE(1,11) ELIF GET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_TREVOR_KILLED) sPsychData.tl3storychoice = "T" returnStr += "T" randInt = GET_RANDOM_INT_IN_RANGE(1,10) ELSE sPsychData.tl3storychoice = "B" returnStr += "B" randInt = GET_RANDOM_INT_IN_RANGE(1,11) ENDIF sPsychData.tl3storychoice += randInt returnStr += randInt RETURN returnStr ENDFUNC /// PURPOSE: /// Returns line associated with most played character FUNC TEXT_LABEL_15 GET_SHRINK_MOST_PLAYED_CHAR(STRUCT_PSYCH_DATA &sPsychData) TEXT_LABEL_15 returnStr = "CHAR_" INT randInt // Debug choice #IF IS_DEBUG_BUILD IF bUseDebug IF bPlayedMichael sPsychData.tl3mostplayedchar = "M" returnStr += "M" randInt = GET_RANDOM_INT_IN_RANGE(1,13) ELIF bPlayedFranklin sPsychData.tl3mostplayedchar = "F" returnStr += "F" randInt = GET_RANDOM_INT_IN_RANGE(1,13) ELSE sPsychData.tl3mostplayedchar = "T" returnStr += "T" randInt = GET_RANDOM_INT_IN_RANGE(1,12) ENDIF returnStr += randInt RETURN returnStr ENDIF #ENDIF // Work out most played character enumCharacterList eMostPlayedChar = CHAR_MICHAEL INT iTempTime INT iMaxTime = 0 // Get Michael's playtime... STAT_GET_INT(SP0_TOTAL_PLAYING_TIME, iMaxTime, 0) // Get Franklin's play time and check if it's larger... STAT_GET_INT(SP1_TOTAL_PLAYING_TIME, iTempTime, 1) IF iTempTime > iMaxTime iMaxTime = iTempTime eMostPlayedChar = CHAR_FRANKLIN ENDIF // Check if Trevor's playtime is longest... STAT_GET_INT(SP2_TOTAL_PLAYING_TIME, iTempTime, 2) IF iTempTime > iMaxTime iMaxTime = iTempTime eMostPlayedChar = CHAR_TREVOR ENDIF // Build text based on most played char IF eMostPlayedChar = CHAR_MICHAEL sPsychData.tl3mostplayedchar = "M" returnStr += "M" randInt = GET_RANDOM_INT_IN_RANGE(1,13) ELIF eMostPlayedChar = CHAR_FRANKLIN sPsychData.tl3mostplayedchar = "F" returnStr += "F" randInt = GET_RANDOM_INT_IN_RANGE(1,13) ELSE sPsychData.tl3mostplayedchar = "T" returnStr += "T" randInt = GET_RANDOM_INT_IN_RANGE(1,12) ENDIF sPsychData.tl3mostplayedchar += randInt returnStr += randInt RETURN returnStr ENDFUNC /// PURPOSE: /// Returns line associated with spending or saving money FUNC TEXT_LABEL_15 GET_SHRINK_MONEY_SPENT(STRUCT_PSYCH_DATA &sPsychData) TEXT_LABEL_15 returnStr = "CASH_" INT randInt // Debug choice #IF IS_DEBUG_BUILD IF bUseDebug IF bSpentCash sPsychData.tl3moneyspent = "SP" returnStr += "SP" randInt = GET_RANDOM_INT_IN_RANGE(1,14) ELSE sPsychData.tl3moneyspent = "SA" returnStr += "SA" randInt = GET_RANDOM_INT_IN_RANGE(1,13) ENDIF sPsychData.tl3moneyspent += randInt returnStr += randInt RETURN returnStr ENDIF #ENDIF // Get total amount of cash spent by all characters INT iTempCash, iTotalCash STAT_GET_INT(SP0_MONEY_TOTAL_SPENT, iTempCash, 0) iTotalCash += iTempCash STAT_GET_INT(SP1_MONEY_TOTAL_SPENT, iTempCash, 1) iTotalCash += iTempCash STAT_GET_INT(SP2_MONEY_TOTAL_SPENT, iTempCash, 2) iTotalCash += iTempCash // Player has spent over 1 million IF iTotalCash >= TOTAL_MONEY_SPENT sPsychData.tl3moneyspent = "SP" returnStr += "SP" randInt = GET_RANDOM_INT_IN_RANGE(1,14) ELSE sPsychData.tl3moneyspent = "SA" returnStr += "SA" randInt = GET_RANDOM_INT_IN_RANGE(1,13) ENDIF // Cloud data sPsychData.tl3moneyspent += randInt // Return suitable text returnStr += randInt RETURN returnStr ENDFUNC /// PURPOSE: /// Returns line associated with whether player frequented strip clubs FUNC TEXT_LABEL_15 GET_SHRINK_VISITED_STRIP_CLUBS(STRUCT_PSYCH_DATA &sPsychData) TEXT_LABEL_15 returnStr = "STRIP_" INT randInt // Debug choice #IF IS_DEBUG_BUILD IF bUseDebug IF bStripClubs sPsychData.tl3stripclubs = "Y" returnStr += "Y" randInt = GET_RANDOM_INT_IN_RANGE(1,13) ELSE sPsychData.tl3stripclubs = "N" returnStr += "N" randInt = GET_RANDOM_INT_IN_RANGE(1,12) ENDIF sPsychData.tl3stripclubs += randInt returnStr += randInt RETURN returnStr ENDIF #ENDIF // Get total amount of lap dances... INT iTempDances, iTotalDances STAT_GET_INT(SP0_LAP_DANCED_BOUGHT, iTempDances, 0) iTotalDances += iTempDances STAT_GET_INT(SP1_LAP_DANCED_BOUGHT, iTempDances, 1) iTotalDances += iTempDances STAT_GET_INT(SP2_LAP_DANCED_BOUGHT, iTempDances, 2) iTotalDances += iTempDances // ...or money spent in strip clubs by all characters INT iTempCash, iTotalCash STAT_GET_INT(SP0_MONEY_SPENT_IN_STRIP_CLUBS, iTempCash, 0) iTotalCash += iTempCash STAT_GET_INT(SP1_MONEY_SPENT_IN_STRIP_CLUBS, iTempCash, 1) iTotalCash += iTempCash STAT_GET_INT(SP2_MONEY_SPENT_IN_STRIP_CLUBS, iTempCash, 2) iTotalCash += iTempCash // Player has had 3 or more dances or spent over $100 in a strip club IF iTotalDances >= STRIP_CLUB_DANCES OR iTotalCash >= STRIP_CLUB_MONEY_SPENT sPsychData.tl3stripclubs = "Y" returnStr += "Y" randInt = GET_RANDOM_INT_IN_RANGE(1,13) ELSE sPsychData.tl3stripclubs = "N" returnStr += "N" randInt = GET_RANDOM_INT_IN_RANGE(1,12) ENDIF // Cloud data sPsychData.tl3stripclubs += randInt // Return suitable text returnStr += randInt RETURN returnStr ENDFUNC /// PURPOSE: /// Returns line associated with whether player used prostitutes FUNC TEXT_LABEL_15 GET_SHRINK_USED_PROSTITUTES(STRUCT_PSYCH_DATA &sPsychData) TEXT_LABEL_15 returnStr = "PROS_" INT randInt // Debug choice #IF IS_DEBUG_BUILD IF bUseDebug IF bProstitutes sPsychData.tl3prostitute = "Y" returnStr += "Y" randInt = GET_RANDOM_INT_IN_RANGE(1,13) ELSE sPsychData.tl3prostitute = "N" returnStr += "N" randInt = GET_RANDOM_INT_IN_RANGE(1,12) ENDIF sPsychData.tl3prostitute += randInt returnStr += randInt RETURN returnStr ENDIF #ENDIF IF GET_NUM_PROSTITUTE_SERVICES_SOLICITED_BY_PLAYER(CHAR_FRANKLIN) > 0 OR GET_NUM_PROSTITUTE_SERVICES_SOLICITED_BY_PLAYER(CHAR_MICHAEL) > 0 OR GET_NUM_PROSTITUTE_SERVICES_SOLICITED_BY_PLAYER(CHAR_TREVOR) > 0 sPsychData.tl3prostitute = "Y" returnStr += "Y" ELSE sPsychData.tl3prostitute = "N" returnStr += "N" ENDIF randInt = GET_RANDOM_INT_IN_RANGE(1,13) sPsychData.tl3prostitute += randInt returnStr += randInt RETURN returnStr ENDFUNC /// PURPOSE: /// Returns line whether Michael has paid any attention to his family FUNC TEXT_LABEL_15 GET_SHRINK_FAMILY_ATTENTION(STRUCT_PSYCH_DATA &sPsychData) TEXT_LABEL_15 returnStr = "FAMILY_" INT randInt // Debug choice #IF IS_DEBUG_BUILD IF bUseDebug IF bMichaelFamily sPsychData.tl3family = "Y" returnStr += "Y" randInt = GET_RANDOM_INT_IN_RANGE(1,13) ELSE sPsychData.tl3family = "N" returnStr += "N" randInt = GET_RANDOM_INT_IN_RANGE(1,12) ENDIF sPsychData.tl3family += randInt returnStr += randInt RETURN returnStr ENDIF #ENDIF IF HAS_CONNECTION_BEEN_PLAYED(FC_MICHAEL_AMANDA) AND HAS_CONNECTION_BEEN_PLAYED(FC_MICHAEL_JIMMY) sPsychData.tl3family = "Y" returnStr += "Y" ELSE sPsychData.tl3family = "N" returnStr += "N" ENDIF randInt = GET_RANDOM_INT_IN_RANGE(1,13) sPsychData.tl3family += randInt returnStr += randInt RETURN returnStr ENDFUNC /// PURPOSE: /// Returns line whether any attention was paid to the stockmarket FUNC TEXT_LABEL_15 GET_SHRINK_PLAYED_STOCKMARKET(STRUCT_PSYCH_DATA &sPsychData) TEXT_LABEL_15 returnStr = "STOCK_" INT randInt // Debug choice #IF IS_DEBUG_BUILD IF bUseDebug IF bStockMarket sPsychData.tl3stockmarket = "Y" returnStr += "Y" ELSE sPsychData.tl3stockmarket = "N" returnStr += "N" ENDIF randInt = GET_RANDOM_INT_IN_RANGE(1,13) sPsychData.tl3stockmarket += randInt returnStr += randInt RETURN returnStr ENDIF #ENDIF // Get total amount of time spent on stockmarket INT iTime STAT_GET_INT(TIME_SPENT_ON_STOCKMARKET, iTime, 0) // Player has spent over x minutes in the stockmarket IF iTime >= STOCKMARKET_TIME_SPENT sPsychData.tl3stockmarket = "Y" returnStr += "Y" ELSE sPsychData.tl3stockmarket = "N" returnStr += "N" ENDIF randInt = GET_RANDOM_INT_IN_RANGE(1,13) sPsychData.tl3stockmarket += randInt returnStr += randInt RETURN returnStr ENDFUNC /// PURPOSE: /// Returns line whether player killed a lot of peds FUNC TEXT_LABEL_15 GET_SHRINK_KILLED_PEDS(STRUCT_PSYCH_DATA &sPsychData) TEXT_LABEL_15 returnStr = "PEDS_" INT randInt // Debug choice #IF IS_DEBUG_BUILD IF bUseDebug IF bKilledPeds sPsychData.tl3killpeds = "Y" returnStr += "Y" ELSE sPsychData.tl3killpeds = "N" returnStr += "N" ENDIF randInt = GET_RANDOM_INT_IN_RANGE(1,13) sPsychData.tl3killpeds += randInt returnStr += randInt RETURN returnStr ENDIF #ENDIF // Get number of innocent peds killed by all characters INT iTempPeds, iTotalPeds STAT_GET_INT(SP0_KILLS_INNOCENTS, iTempPeds, 0) iTotalPeds += iTempPeds STAT_GET_INT(SP1_KILLS_INNOCENTS, iTempPeds, 1) iTotalPeds += iTempPeds STAT_GET_INT(SP2_KILLS_INNOCENTS, iTempPeds, 2) iTotalPeds += iTempPeds // Player has killed over threshold amount of innocent peds IF iTotalPeds >= TOTAL_PEDS_KILLED sPsychData.tl3killpeds = "Y" returnStr += "Y" ELSE sPsychData.tl3killpeds = "N" returnStr += "N" ENDIF randInt = GET_RANDOM_INT_IN_RANGE(1,13) sPsychData.tl3killpeds += randInt returnStr += randInt RETURN returnStr ENDFUNC /// PURPOSE: /// Returns line whether player stole a lot of vehicles FUNC TEXT_LABEL_15 GET_SHRINK_STOLE_VEHICLES(STRUCT_PSYCH_DATA &sPsychData) TEXT_LABEL_15 returnStr = "VEHS_" INT randInt // Debug choice #IF IS_DEBUG_BUILD IF bUseDebug IF bStoleVehicles sPsychData.tl3stolenvehicles = "Y" returnStr += "Y" ELSE sPsychData.tl3stolenvehicles = "N" returnStr += "N" ENDIF randInt = GET_RANDOM_INT_IN_RANGE(1,13) sPsychData.tl3stolenvehicles += randInt returnStr += randInt RETURN returnStr ENDIF #ENDIF // Get number of vehicles stolen by all characters INT iTempVehicles, iTotalVehicles // Michael STAT_GET_INT(SP0_NUMBER_STOLEN_COP_VEHICLE, iTempVehicles, 0) iTotalVehicles += iTempVehicles STAT_GET_INT(SP0_NUMBER_STOLEN_CARS, iTempVehicles, 0) iTotalVehicles += iTempVehicles STAT_GET_INT(SP0_NUMBER_STOLEN_BIKES, iTempVehicles, 0) iTotalVehicles += iTempVehicles STAT_GET_INT(SP0_NUMBER_STOLEN_BOATS, iTempVehicles, 0) iTotalVehicles += iTempVehicles STAT_GET_INT(SP0_NUMBER_STOLEN_HELIS, iTempVehicles, 0) iTotalVehicles += iTempVehicles STAT_GET_INT(SP0_NUMBER_STOLEN_QUADBIKES, iTempVehicles, 0) iTotalVehicles += iTempVehicles STAT_GET_INT(SP0_NUMBER_STOLEN_BICYCLES, iTempVehicles, 0) iTotalVehicles += iTempVehicles // Franklin STAT_GET_INT(SP1_NUMBER_STOLEN_COP_VEHICLE, iTempVehicles, 1) iTotalVehicles += iTempVehicles STAT_GET_INT(SP1_NUMBER_STOLEN_CARS, iTempVehicles, 1) iTotalVehicles += iTempVehicles STAT_GET_INT(SP1_NUMBER_STOLEN_BIKES, iTempVehicles, 1) iTotalVehicles += iTempVehicles STAT_GET_INT(SP1_NUMBER_STOLEN_BOATS, iTempVehicles, 1) iTotalVehicles += iTempVehicles STAT_GET_INT(SP1_NUMBER_STOLEN_HELIS, iTempVehicles, 1) iTotalVehicles += iTempVehicles STAT_GET_INT(SP1_NUMBER_STOLEN_QUADBIKES, iTempVehicles, 1) iTotalVehicles += iTempVehicles STAT_GET_INT(SP1_NUMBER_STOLEN_BICYCLES, iTempVehicles, 1) iTotalVehicles += iTempVehicles // Trevor STAT_GET_INT(SP2_NUMBER_STOLEN_COP_VEHICLE, iTempVehicles, 2) iTotalVehicles += iTempVehicles STAT_GET_INT(SP2_NUMBER_STOLEN_CARS, iTempVehicles, 2) iTotalVehicles += iTempVehicles STAT_GET_INT(SP2_NUMBER_STOLEN_BIKES, iTempVehicles, 2) iTotalVehicles += iTempVehicles STAT_GET_INT(SP2_NUMBER_STOLEN_BOATS, iTempVehicles, 2) iTotalVehicles += iTempVehicles STAT_GET_INT(SP2_NUMBER_STOLEN_HELIS, iTempVehicles, 2) iTotalVehicles += iTempVehicles STAT_GET_INT(SP2_NUMBER_STOLEN_QUADBIKES, iTempVehicles, 2) iTotalVehicles += iTempVehicles STAT_GET_INT(SP2_NUMBER_STOLEN_BICYCLES, iTempVehicles, 2) iTotalVehicles += iTempVehicles // Player has stolen over threshold amount of vehicles IF iTotalVehicles >= TOTAL_VEHICLES_STOLEN sPsychData.tl3stolenvehicles = "Y" returnStr += "Y" ELSE sPsychData.tl3stolenvehicles = "N" returnStr += "N" ENDIF randInt = GET_RANDOM_INT_IN_RANGE(1,13) sPsychData.tl3stolenvehicles += randInt returnStr += randInt RETURN returnStr ENDFUNC /// PURPOSE: /// Returns line whether player was active in yoga FUNC TEXT_LABEL_15 GET_SHRINK_PERFORMED_YOGA(STRUCT_PSYCH_DATA &sPsychData) TEXT_LABEL_15 returnStr = "YOGA_" INT randInt // Debug choice #IF IS_DEBUG_BUILD IF bUseDebug IF bYoga sPsychData.tl3yoga = "Y" returnStr += "Y" ELSE sPsychData.tl3yoga = "N" returnStr += "N" ENDIF randInt = GET_RANDOM_INT_IN_RANGE(1,13) sPsychData.tl3yoga += randInt returnStr += randInt RETURN returnStr ENDIF #ENDIF // Has the player completed the Yoga minigame? IF HAS_THIS_SCRIPT_BEEN_REGISTERED_IN_COMPLETION_PERCENTAGE_TOTAL(CP_YOGA) sPsychData.tl3yoga = "Y" returnStr += "Y" ELSE sPsychData.tl3yoga = "N" returnStr += "N" ENDIF randInt = GET_RANDOM_INT_IN_RANGE(1,13) sPsychData.tl3yoga += randInt returnStr += randInt RETURN returnStr ENDFUNC /// PURPOSE: /// Returns line whether player was generally fit and active FUNC TEXT_LABEL_15 GET_SHRINK_FITNESS(STRUCT_PSYCH_DATA &sPsychData) TEXT_LABEL_15 returnStr = "FIT_" INT randInt // Debug choice #IF IS_DEBUG_BUILD IF bUseDebug IF bFitness sPsychData.tl3fitness = "Y" returnStr += "Y" randInt = GET_RANDOM_INT_IN_RANGE(1,11) ELSE sPsychData.tl3fitness = "N" returnStr += "N" randInt = GET_RANDOM_INT_IN_RANGE(1,13) ENDIF sPsychData.tl3fitness = randInt returnStr += randInt RETURN returnStr ENDIF #ENDIF // All player fitness levels are above set amounts IF GET_SP_PLAYER_PED_STAT_VALUE(CHAR_FRANKLIN, PS_STAMINA) > FITNESS_LEVEL_FRANKLIN // Franklin AND GET_SP_PLAYER_PED_STAT_VALUE(CHAR_FRANKLIN, PS_STRENGTH) > FITNESS_LEVEL_FRANKLIN AND GET_SP_PLAYER_PED_STAT_VALUE(CHAR_FRANKLIN, PS_LUNG_CAPACITY) > FITNESS_LEVEL_FRANKLIN AND GET_SP_PLAYER_PED_STAT_VALUE(CHAR_MICHAEL, PS_STAMINA) > FITNESS_LEVEL_MICHAEL // Michael AND GET_SP_PLAYER_PED_STAT_VALUE(CHAR_MICHAEL, PS_STRENGTH) > FITNESS_LEVEL_MICHAEL AND GET_SP_PLAYER_PED_STAT_VALUE(CHAR_MICHAEL, PS_LUNG_CAPACITY) > FITNESS_LEVEL_MICHAEL AND GET_SP_PLAYER_PED_STAT_VALUE(CHAR_TREVOR, PS_STAMINA) > FITNESS_LEVEL_TREVOR // Trevor AND GET_SP_PLAYER_PED_STAT_VALUE(CHAR_TREVOR, PS_STRENGTH) > FITNESS_LEVEL_TREVOR AND GET_SP_PLAYER_PED_STAT_VALUE(CHAR_TREVOR, PS_LUNG_CAPACITY) > FITNESS_LEVEL_TREVOR sPsychData.tl3fitness = "Y" returnStr += "Y" ELSE sPsychData.tl3fitness = "N" returnStr += "N" ENDIF randInt = GET_RANDOM_INT_IN_RANGE(1,11) sPsychData.tl3fitness += randInt returnStr += randInt RETURN returnStr ENDFUNC /// PURPOSE: /// Returns line whether player engaged in random chars/events FUNC TEXT_LABEL_15 GET_SHRINK_RANDOM_CHARS(STRUCT_PSYCH_DATA &sPsychData) TEXT_LABEL_15 returnStr = "RAND_" INT randInt // Debug choice #IF IS_DEBUG_BUILD IF bUseDebug IF bRandomChar sPsychData.tl3strangers = "Y" returnStr += "Y" ELSE sPsychData.tl3strangers = "N" returnStr += "N" ENDIF randInt = GET_RANDOM_INT_IN_RANGE(1,13) returnStr += randInt RETURN returnStr ENDIF #ENDIF // Get total number of completed RCM's and RE's INT iCompletedRC, iCompletedRE, iTotal STAT_GET_INT(NUM_RNDPEOPLE_COMPLETED, iCompletedRC) STAT_GET_INT(NUM_RNDEVENTS_COMPLETED, iCompletedRE) iTotal = iCompletedRC + iCompletedRE // Player has completed over x Random Events and Random Character missions IF (iTotal > TOTAL_STRANGERS_MET) sPsychData.tl3strangers = "Y" returnStr += "Y" ELSE sPsychData.tl3strangers = "N" returnStr += "N" ENDIF randInt = GET_RANDOM_INT_IN_RANGE(1,13) sPsychData.tl3strangers += randInt returnStr += randInt RETURN returnStr ENDFUNC /// PURPOSE: /// Returns line whether player was generally fit and active FUNC TEXT_LABEL_15 GET_SHRINK_COLLECTABLES(STRUCT_PSYCH_DATA &sPsychData) TEXT_LABEL_15 returnStr = "COLLECT_" INT randInt // Debug choice #IF IS_DEBUG_BUILD IF bUseDebug IF bCollectables sPsychData.tl3collectables = "Y" returnStr += "Y" randInt = GET_RANDOM_INT_IN_RANGE(1,11) ELSE sPsychData.tl3collectables = "N" returnStr += "N" randInt = GET_RANDOM_INT_IN_RANGE(1,12) ENDIF sPsychData.tl3collectables += randInt returnStr += randInt RETURN returnStr ENDIF #ENDIF // Check collectables IF GET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_DIVING_SCRAPS_DONE) // Submarine parts OR GET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_EPSILON_UNLOCKED_TRACT) // Epsilon tract OR GET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_LETTER_SCRAPS_DONE) // Dreyfuss letter OR GET_MISSION_FLOW_FLAG_STATE(FLOWFLAG_SPACESHIP_PARTS_DONE) // Omega spaceship sPsychData.tl3collectables = "Y" returnStr += "Y" randInt = GET_RANDOM_INT_IN_RANGE(1,11) ELSE sPsychData.tl3collectables = "N" returnStr += "N" randInt = GET_RANDOM_INT_IN_RANGE(1,12) ENDIF sPsychData.tl3collectables += randInt returnStr += randInt RETURN returnStr ENDFUNC /// PURPOSE: /// Returns randomised summary FUNC TEXT_LABEL_15 GET_SHRINK_SUMMARY(STRUCT_PSYCH_DATA &sPsychData) TEXT_LABEL_15 returnStr = "SUMMARY_" INT randInt = GET_RANDOM_INT_IN_RANGE(1,24) sPsychData.iSummary = randInt returnStr += randInt RETURN returnStr ENDFUNC /// PURPOSE: /// Saves psychology report to a given path for the cloud dats /// PARAMS: /// iLoadStage - the switching stage /// bSuccess - was it a sucess /// sPsychData - Cloud data FUNC BOOL SAVE_OUT_PSYCH_DATA(INT &iLoadStage, BOOL &bSuccess, STRUCT_PSYCH_DATA &sPsychData) // The cloud is down... get out of here! IF IS_CLOUD_DOWN_CLOUD_LOADER() CPRINTLN(DEBUG_MISSION, "SAVE_OUT_PSYCH_DATA - NOT IS_CLOUD_DOWN_CLOUD_LOADER()") RETURN TRUE ENDIF //Vars needed DATAFILE_DICT dfdMainDict SWITCH iLoadStage // Deal with setup CASE 0 IF IS_SCRIPT_UCG_REQUEST_IN_PROGRESS() RETURN FALSE ENDIF CLEANUP_DATA_FILE() iLoadStage++ BREAK //Initilise the data file CASE 1 //SET UP THE DATA FILE DATAFILE_CREATE() //Get a handel on the top level dictionay dfdMainDict = DATAFILE_GET_FILE_DICT() //Add an INT DATADICT_SET_INT (dfdMainDict, "in", sPsychData.iIntro) DATADICT_SET_STRING (dfdMainDict, "st", sPsychData.tl3storychoice) DATADICT_SET_STRING (dfdMainDict, "mp", sPsychData.tl3mostplayedchar) DATADICT_SET_STRING (dfdMainDict, "ms", sPsychData.tl3moneyspent) DATADICT_SET_STRING (dfdMainDict, "sc", sPsychData.tl3stripclubs) DATADICT_SET_STRING (dfdMainDict, "pr", sPsychData.tl3prostitute) DATADICT_SET_STRING (dfdMainDict, "fa", sPsychData.tl3family) DATADICT_SET_STRING (dfdMainDict, "sm", sPsychData.tl3stockmarket) DATADICT_SET_STRING (dfdMainDict, "kp", sPsychData.tl3killpeds) DATADICT_SET_STRING (dfdMainDict, "sv", sPsychData.tl3stolenvehicles) DATADICT_SET_STRING (dfdMainDict, "yo", sPsychData.tl3yoga) DATADICT_SET_STRING (dfdMainDict, "fi", sPsychData.tl3fitness) DATADICT_SET_STRING (dfdMainDict, "rc", sPsychData.tl3strangers) DATADICT_SET_STRING (dfdMainDict, "co", sPsychData.tl3collectables) DATADICT_SET_INT (dfdMainDict, "su", sPsychData.iSummary) DATAFILE_START_SAVE_TO_CLOUD("gta5/psych/index.json") iLoadStage++ BREAK CASE 2 // Wait for it to finish IF PROCESS_SAVE_FILE_TO_CLOUD(bSuccess) CPRINTLN(DEBUG_MISSION, "iIntro = ", sPsychData.iIntro) CPRINTLN(DEBUG_MISSION, "tl3storychoice = ", sPsychData.tl3storychoice) CPRINTLN(DEBUG_MISSION, "tl3mostplayedchar = ", sPsychData.tl3mostplayedchar) CPRINTLN(DEBUG_MISSION, "tl3moneyspent = ", sPsychData.tl3moneyspent) CPRINTLN(DEBUG_MISSION, "tl3stripclubs = ", sPsychData.tl3stripclubs) CPRINTLN(DEBUG_MISSION, "tl3prostitute = ", sPsychData.tl3prostitute) CPRINTLN(DEBUG_MISSION, "tl3family = ", sPsychData.tl3family) CPRINTLN(DEBUG_MISSION, "tl3stockmarket = ", sPsychData.tl3stockmarket) CPRINTLN(DEBUG_MISSION, "tl3killpeds = ", sPsychData.tl3killpeds) CPRINTLN(DEBUG_MISSION, "tl3stolenvehicles = ", sPsychData.tl3stolenvehicles) CPRINTLN(DEBUG_MISSION, "tl3yoga = ", sPsychData.tl3yoga) CPRINTLN(DEBUG_MISSION, "tl3fitness = ", sPsychData.tl3fitness) CPRINTLN(DEBUG_MISSION, "tl3strangers = ", sPsychData.tl3strangers) CPRINTLN(DEBUG_MISSION, "tl3collectables = ", sPsychData.tl3collectables) CPRINTLN(DEBUG_MISSION, "iSummary = ", sPsychData.iSummary) CPRINTLN(DEBUG_MISSION, "SAVE_OUT_PSYCH_DATA - Success!") RETURN TRUE ENDIF BREAK ENDSWITCH // Not done yet pal RETURN FALSE ENDFUNC #IF IS_DEBUG_BUILD PROC CREATE_SHRINK_WIDGETS() IF NOT DOES_WIDGET_GROUP_EXIST(widgetGroup) widgetGroup = START_WIDGET_GROUP("Shrink Letter") ADD_WIDGET_STRING("Letter Variables") ADD_WIDGET_BOOL("Killed Michael", bKilledMichael) ADD_WIDGET_BOOL("Killed Trevor", bKilledTrevor) ADD_WIDGET_BOOL("Most Played - Franklin", bPlayedFranklin) ADD_WIDGET_BOOL("Most Played - Michael", bPlayedMichael) ADD_WIDGET_BOOL("Most Played - Trevor", bPlayedTrevor) ADD_WIDGET_BOOL("Spent Money", bSpentCash) ADD_WIDGET_BOOL("Strip Clubs", bStripClubs) ADD_WIDGET_BOOL("Prostitutes", bProstitutes) ADD_WIDGET_BOOL("Family", bMichaelFamily) ADD_WIDGET_BOOL("Stockmarket", bStockMarket) ADD_WIDGET_BOOL("Killed Peds", bKilledPeds) ADD_WIDGET_BOOL("Stole Vehicles", bStoleVehicles) ADD_WIDGET_BOOL("Yoga", bYoga) ADD_WIDGET_BOOL("Fitness", bFitness) ADD_WIDGET_BOOL("Random Characters", bRandomChar) ADD_WIDGET_BOOL("Collectables", bCollectables) ADD_WIDGET_STRING("Create Content") ADD_WIDGET_BOOL("Use Debug Settings", bUseDebug) ADD_WIDGET_BOOL("Use Scaleform", bUseScaleform) ADD_WIDGET_BOOL("Generate Letter", bGenerateLetter) STOP_WIDGET_GROUP() ENDIF ENDPROC PROC UPDATE_SHRINK_WIDGETS() IF bGenerateLetter IF bUseScaleform // Create letter CPRINTLN(DEBUG_MISSION, "Shrink Letter: Generating scaleform...") eLetterStage = SS_INIT ELSE // Output TTY CPRINTLN(DEBUG_MISSION, "Shrink Letter: Generating TTY...") TEXT_LABEL_15 str str = GET_SHRINK_INTRO(sUploadData) CPRINTLN(DEBUG_MISSION, GET_STRING_FROM_TEXT_FILE(str)) str = GET_SHRINK_STORY_CHOICE(sUploadData) CPRINTLN(DEBUG_MISSION, GET_STRING_FROM_TEXT_FILE(str)) str = GET_SHRINK_MOST_PLAYED_CHAR(sUploadData) CPRINTLN(DEBUG_MISSION, GET_STRING_FROM_TEXT_FILE(str)) str = GET_SHRINK_MONEY_SPENT(sUploadData) CPRINTLN(DEBUG_MISSION, GET_STRING_FROM_TEXT_FILE(str)) str = GET_SHRINK_VISITED_STRIP_CLUBS(sUploadData) CPRINTLN(DEBUG_MISSION, GET_STRING_FROM_TEXT_FILE(str)) str = GET_SHRINK_USED_PROSTITUTES(sUploadData) CPRINTLN(DEBUG_MISSION, GET_STRING_FROM_TEXT_FILE(str)) str = GET_SHRINK_FAMILY_ATTENTION(sUploadData) CPRINTLN(DEBUG_MISSION, GET_STRING_FROM_TEXT_FILE(str)) str = GET_SHRINK_PLAYED_STOCKMARKET(sUploadData) CPRINTLN(DEBUG_MISSION, GET_STRING_FROM_TEXT_FILE(str)) str = GET_SHRINK_KILLED_PEDS(sUploadData) CPRINTLN(DEBUG_MISSION, GET_STRING_FROM_TEXT_FILE(str)) str = GET_SHRINK_STOLE_VEHICLES(sUploadData) CPRINTLN(DEBUG_MISSION, GET_STRING_FROM_TEXT_FILE(str)) str = GET_SHRINK_PERFORMED_YOGA(sUploadData) CPRINTLN(DEBUG_MISSION, GET_STRING_FROM_TEXT_FILE(str)) str = GET_SHRINK_FITNESS(sUploadData) CPRINTLN(DEBUG_MISSION, GET_STRING_FROM_TEXT_FILE(str)) str = GET_SHRINK_RANDOM_CHARS(sUploadData) CPRINTLN(DEBUG_MISSION, GET_STRING_FROM_TEXT_FILE(str)) str = GET_SHRINK_COLLECTABLES(sUploadData) CPRINTLN(DEBUG_MISSION, GET_STRING_FROM_TEXT_FILE(str)) str = GET_SHRINK_SUMMARY(sUploadData) CPRINTLN(DEBUG_MISSION, GET_STRING_FROM_TEXT_FILE(str)) ENDIF // Reset widget flag bGenerateLetter = FALSE ENDIF ENDPROC PROC CLEANUP_SHRINK_WIDGETS() IF DOES_WIDGET_GROUP_EXIST(widgetGroup) DELETE_WIDGET_GROUP(widgetGroup) ENDIF ENDPROC #ENDIF PROC SCRIPT_CLEANUP() CPRINTLN(DEBUG_MISSION, "Shrink Letter: Cleanup") #IF IS_DEBUG_BUILD CLEANUP_SHRINK_WIDGETS() #ENDIF IF IS_SCREEN_FADED_OUT() DO_SCREEN_FADE_IN(0) ENDIF TERMINATE_THIS_THREAD() ENDPROC #IF IS_DEBUG_BUILD PROC CHECK_DEBUG_KEYS() IF (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_S)) OR (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_F)) OR (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_J)) OR (IS_KEYBOARD_KEY_JUST_PRESSED(KEY_P)) SCRIPT_CLEANUP() ENDIF ENDPROC #ENDIF /// PURPOSE: /// Disables access to pause menu and hides HUD elements whilst shrink letter is onscreen PROC HIDE_UI_AND_DISABLE_CONTROLS_FOR_LETTER() DISABLE_CONTROL_ACTION(FRONTEND_CONTROL, INPUT_FRONTEND_PAUSE) HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_AREA_NAME) HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_AREA_NAME) HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_VEHICLE_NAME) HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_DISTRICT_NAME) HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_STREET_NAME) DISABLE_CELLPHONE_THIS_FRAME_ONLY() ENDPROC SCRIPT CPRINTLN(DEBUG_MISSION, "Shrink Letter: Init") IF HAS_FORCE_CLEANUP_OCCURRED(FORCE_CLEANUP_FLAG_DEBUG_MENU|FORCE_CLEANUP_FLAG_SP_TO_MP) CPRINTLN(DEBUG_MISSION, "Shrink Letter: Force Clenaup") SCRIPT_CLEANUP() ENDIF #IF IS_DEBUG_BUILD CREATE_SHRINK_WIDGETS() #ENDIF // Load shrink report text REQUEST_ADDITIONAL_TEXT("REPORT", MISSION_TEXT_SLOT) WHILE NOT HAS_ADDITIONAL_TEXT_LOADED(MISSION_TEXT_SLOT) WAIT(0) ENDWHILE WHILE (TRUE) #IF IS_DEBUG_BUILD UPDATE_SHRINK_WIDGETS() CHECK_DEBUG_KEYS() #ENDIF SWITCH eLetterStage CASE SS_SETUP // Dummy state where player can update the debug widget BREAK CASE SS_INIT // Prepare for letter SET_SCRIPTS_SAFE_FOR_CUTSCENE(TRUE) SET_PLAYER_CONTROL(PLAYER_ID(), FALSE) DISPLAY_RADAR(FALSE) DISPLAY_HUD(FALSE) // Load shrink letter siLetter = REQUEST_SCALEFORM_MOVIE("PSYCHOLOGY_REPORT") WHILE (NOT HAS_SCALEFORM_MOVIE_LOADED(siLetter)) HIDE_UI_AND_DISABLE_CONTROLS_FOR_LETTER() WAIT(0) ENDWHILE // Load shrink report text REQUEST_ADDITIONAL_TEXT("REPORT", MINIGAME_TEXT_SLOT) WHILE NOT HAS_ADDITIONAL_TEXT_LOADED(MINIGAME_TEXT_SLOT) HIDE_UI_AND_DISABLE_CONTROLS_FOR_LETTER() WAIT(0) ENDWHILE // Add gamertag BEGIN_SCALEFORM_MOVIE_METHOD(siLetter, "SET_PLAYER_NAME") // B*2023149 - seperate "patient:" from gamertag BEGIN_TEXT_COMMAND_SCALEFORM_STRING("STRING") ADD_TEXT_COMPONENT_SUBSTRING_TEXT_LABEL("PATIENT") CPRINTLN(DEBUG_MISSION, "Shrink Letter: set PATIENT string ") END_TEXT_COMMAND_SCALEFORM_STRING() // insert the gamertag BEGIN_TEXT_COMMAND_SCALEFORM_STRING("GAMERTAG") IF NETWORK_IS_SIGNED_IN() ADD_TEXT_COMPONENT_SUBSTRING_PLAYER_NAME(GET_PLAYER_NAME(PLAYER_ID())) CPRINTLN(DEBUG_MISSION, "Shrink Letter: set GAMERTAG string using player gamertag") ELSE ADD_TEXT_COMPONENT_SUBSTRING_TEXT_LABEL("ACCNA_MIKE") CPRINTLN(DEBUG_MISSION, "Shrink Letter: set GAMERTAG string using ACCNA_MIKE for player name - not signed in") ENDIF END_TEXT_COMMAND_SCALEFORM_STRING() END_SCALEFORM_MOVIE_METHOD() // Holds individual line of shrink letter TEXT_LABEL_15 str // Build shrink letter BEGIN_SCALEFORM_MOVIE_METHOD(siLetter, "SET_LETTER_TEXT") // From the office of Dr Isiah Friedlander... SCALEFORM_MOVIE_METHOD_ADD_PARAM_STRING("HEADER_1") SCALEFORM_MOVIE_METHOD_ADD_PARAM_STRING("HEADER_2") str = GET_SHRINK_INTRO(sUploadData) SCALEFORM_MOVIE_METHOD_ADD_PARAM_STRING(str) str = GET_SHRINK_STORY_CHOICE(sUploadData) SCALEFORM_MOVIE_METHOD_ADD_PARAM_STRING(str) str = GET_SHRINK_MOST_PLAYED_CHAR(sUploadData) SCALEFORM_MOVIE_METHOD_ADD_PARAM_STRING(str) str = GET_SHRINK_MONEY_SPENT(sUploadData) SCALEFORM_MOVIE_METHOD_ADD_PARAM_STRING(str) str = GET_SHRINK_VISITED_STRIP_CLUBS(sUploadData) SCALEFORM_MOVIE_METHOD_ADD_PARAM_STRING(str) str = GET_SHRINK_USED_PROSTITUTES(sUploadData) SCALEFORM_MOVIE_METHOD_ADD_PARAM_STRING(str) str = GET_SHRINK_FAMILY_ATTENTION(sUploadData) SCALEFORM_MOVIE_METHOD_ADD_PARAM_STRING(str) str = GET_SHRINK_PLAYED_STOCKMARKET(sUploadData) SCALEFORM_MOVIE_METHOD_ADD_PARAM_STRING(str) str = GET_SHRINK_KILLED_PEDS(sUploadData) SCALEFORM_MOVIE_METHOD_ADD_PARAM_STRING(str) str = GET_SHRINK_STOLE_VEHICLES(sUploadData) SCALEFORM_MOVIE_METHOD_ADD_PARAM_STRING(str) str = GET_SHRINK_PERFORMED_YOGA(sUploadData) SCALEFORM_MOVIE_METHOD_ADD_PARAM_STRING(str) str = GET_SHRINK_FITNESS(sUploadData) SCALEFORM_MOVIE_METHOD_ADD_PARAM_STRING(str) str = GET_SHRINK_RANDOM_CHARS(sUploadData) SCALEFORM_MOVIE_METHOD_ADD_PARAM_STRING(str) str = GET_SHRINK_COLLECTABLES(sUploadData) SCALEFORM_MOVIE_METHOD_ADD_PARAM_STRING(str) str = GET_SHRINK_SUMMARY(sUploadData) SCALEFORM_MOVIE_METHOD_ADD_PARAM_STRING(str) END_SCALEFORM_MOVIE_METHOD() // Upload data to the cloud! WHILE NOT SAVE_OUT_PSYCH_DATA(iCloudLoadStage, bCloudSuccess, sUploadData) HIDE_UI_AND_DISABLE_CONTROLS_FOR_LETTER() WAIT(0) ENDWHILE CLEANUP_SIMPLE_USE_CONTEXT(ucInstructions) INIT_SIMPLE_USE_CONTEXT(ucInstructions, FALSE, FALSE, FALSE, TRUE) ADD_SIMPLE_USE_CONTEXT_INPUT(ucInstructions, "CONTINUE", FRONTEND_CONTROL, INPUT_FRONTEND_ACCEPT) SET_SIMPLE_USE_CONTEXT_FULLSCREEN(ucInstructions) SET_SIMPLE_USE_CONTEXT_MINIGAME_ATTACHED(ucInstructions) // Fade screen back in for letter IF IS_SCREEN_FADED_OUT() IF NOT IS_SCREEN_FADING_IN() HIDE_UI_AND_DISABLE_CONTROLS_FOR_LETTER() DO_SCREEN_FADE_IN(DEFAULT_FADE_TIME) ENDIF WHILE NOT IS_SCREEN_FADED_IN() HIDE_UI_AND_DISABLE_CONTROLS_FOR_LETTER() SET_SCRIPT_GFX_DRAW_ORDER(GFX_ORDER_BEFORE_HUD) DRAW_SCALEFORM_MOVIE_FULLSCREEN(siLetter, 255,255,255,255) WAIT(0) ENDWHILE ENDIF // Prevent flicker HIDE_UI_AND_DISABLE_CONTROLS_FOR_LETTER() SET_SCRIPT_GFX_DRAW_ORDER(GFX_ORDER_BEFORE_HUD) DRAW_SCALEFORM_MOVIE_FULLSCREEN(siLetter, 255,255,255,255) eLetterStage = SS_UPDATE BREAK CASE SS_UPDATE // Render shrink letter SET_SCRIPT_GFX_DRAW_ORDER(GFX_ORDER_BEFORE_HUD) DRAW_SCALEFORM_MOVIE_FULLSCREEN(siLetter, 255,255,255,255) UPDATE_SIMPLE_USE_CONTEXT(ucInstructions) // Wait for user input IF IS_CONTROL_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_ACCEPT) eLetterStage = SS_CLEANUP ENDIF BREAK CASE SS_CLEANUP // Remove continue button CLEANUP_SIMPLE_USE_CONTEXT(ucInstructions) // Fade back out DO_SCREEN_FADE_OUT(3000) WHILE IS_SCREEN_FADING_OUT() DRAW_SCALEFORM_MOVIE_FULLSCREEN(siLetter, 255,255,255,255) HIDE_UI_AND_DISABLE_CONTROLS_FOR_LETTER() WAIT(0) ENDWHILE // Cleanup SET_SCALEFORM_MOVIE_AS_NO_LONGER_NEEDED(siLetter) // Restore control SET_SCRIPTS_SAFE_FOR_CUTSCENE(FALSE) SET_PLAYER_CONTROL(PLAYER_ID(), TRUE) DISPLAY_RADAR(TRUE) DISPLAY_HUD(TRUE) CPRINTLN(DEBUG_MISSION, "Shrink Letter: Cleanup") SCRIPT_CLEANUP() BREAK ENDSWITCH IF eLetterStage <> SS_SETUP HIDE_UI_AND_DISABLE_CONTROLS_FOR_LETTER() ENDIF WAIT(0) ENDWHILE // Script should never reach here. Always terminate with cleanup function. ENDSCRIPT