//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_script.sch" USING "email_public.sch" USING "comms_control_private.sch" // ***************************************************************************************** // ***************************************************************************************** // ***************************************************************************************** // // MISSION NAME : email_controller.sch // AUTHOR : Ak // DESCRIPTION : Watcher script for email functionality // // ***************************************************************************************** // ***************************************************************************************** // ***************************************************************************************** // =========================================================================================================== // Cleanup // =========================================================================================================== // PURPOSE: Ensures that the script gets a chance to cleanup under specific circumstances (ie: moving from SP to MP) // PROC Script_Cleanup() CPRINTLN(DEBUG_EMAIL, "Cleaning up email controller.") TERMINATE_THIS_THREAD() ENDPROC SCRIPT CPRINTLN(DEBUG_EMAIL, "Email controller started.") // This script needs to cleanup only when the game moves from SP to MP. IF (HAS_FORCE_CLEANUP_OCCURRED(FORCE_CLEANUP_FLAG_SP_TO_MP|FORCE_CLEANUP_FLAG_MAGDEMO)) CPRINTLN(DEBUG_EMAIL, "The email controller was forced to clean up. Flag: ", GET_CAUSE_OF_MOST_RECENT_FORCE_CLEANUP()) Script_Cleanup() ENDIF INT delays[TOTAL_EMAIL_THREADS_IN_GAME] INITIALISE_EMAIL_SYSTEM_CONTENT() LOAD_EMAIL_SYSTEM_STATE() g_bDebugEmailDisplay = FALSE TIMEOFDAY todCurrent = GET_CURRENT_TIMEOFDAY() TIMEOFDAY todLast = GET_CURRENT_TIMEOFDAY() INT delay_stride = 2000 //BEGIN_EMAIL_THREAD(CULT_CAR_STEAL_CHAIN) //PROGRESS_EMAIL_THREAD(ENUM_TO_INT(CULT_CAR_STEAL_CHAIN)) //JUMP_EMAIL_THREAD_TO_STAGE(CULT_CAR_STEAL_CHAIN, CULT3,TRUE) /* //Test spam all the emails BEGIN_EMAIL_THREAD(CULT_CAR_STEAL_CHAIN) BEGIN_EMAIL_THREAD(CULT_MAIL_ORDER) BEGIN_EMAIL_THREAD(ASS_THREAD_HOTEL) BEGIN_EMAIL_THREAD(ASS_THREAD_MULTI) BEGIN_EMAIL_THREAD(ASS_THREAD_VICE) BEGIN_EMAIL_THREAD(ASS_THREAD_CONSTRUCTION) BEGIN_EMAIL_THREAD(HEIST_THREAD_BANK_MIKE) BEGIN_EMAIL_THREAD(HEIST_THREAD_BANK_FRAN) BEGIN_EMAIL_THREAD(HEIST_THREAD_BANK_TREV) BEGIN_EMAIL_THREAD(STOCKMARKET_TUTORIAL) BEGIN_EMAIL_THREAD(LSC_MOD_UNLOCKS) BEGIN_EMAIL_THREAD(WEAPON_STOCK_1) BEGIN_EMAIL_THREAD(WEAPON_STOCK_2) BEGIN_EMAIL_THREAD(WEAPON_STOCK_3) BEGIN_EMAIL_THREAD(WEAPON_STOCK_4) BEGIN_EMAIL_THREAD(WEAPON_STOCK_5) BEGIN_EMAIL_THREAD(WEAPON_STOCK_6) BEGIN_EMAIL_THREAD(WEAPON_STOCK_7) BEGIN_EMAIL_THREAD(WEAPON_STOCK_8) BEGIN_EMAIL_THREAD(PROPERTY_DMAIL_HELIPAD) BEGIN_EMAIL_THREAD(PROPERTY_DMAIL_MARINA) BEGIN_EMAIL_THREAD(PROPERTY_DMAIL_HANGAR) BEGIN_EMAIL_THREAD(BIGSCOREPC_BAD_HACKER) BEGIN_EMAIL_THREAD(BIGSCOREPC_MED_HACKER) BEGIN_EMAIL_THREAD(BIGSCOREPC_GOOD_HACKER) BEGIN_EMAIL_THREAD(OFFROAD_UNLOCK) BEGIN_EMAIL_THREAD(WEAPON_STOCK_9) BEGIN_EMAIL_THREAD(SEARACE_UNLOCK_MIKE) BEGIN_EMAIL_THREAD(SEARACE_UNLOCK_FRANK) BEGIN_EMAIL_THREAD(SEARACE_UNLOCK_TREV) BEGIN_EMAIL_THREAD(PROPERTY_EMAIL_FRAMES_MIKE) BEGIN_EMAIL_THREAD(PROPERTY_EMAIL_FRAMES_FRANK) BEGIN_EMAIL_THREAD(PROPERTY_EMAIL_FRAMES_TREV) BEGIN_EMAIL_THREAD(BAIL_BONDS) BEGIN_EMAIL_THREAD(EPSILON_TRACT) BEGIN_EMAIL_THREAD(CARSTEAL2_REWARD) BEGIN_EMAIL_THREAD(DRFRIEDLANDER_EMAIL_A1) BEGIN_EMAIL_THREAD(DRFRIEDLANDER_EMAIL_END) BEGIN_EMAIL_THREAD(TRACEY_EMAIL_EXILE) BEGIN_EMAIL_THREAD(DAVE_EMAIL_FBI1) BEGIN_EMAIL_THREAD(AMANDA_EMAIL_FAM6) BEGIN_EMAIL_THREAD(MERRYWETHER_EMAIL_EG) BEGIN_EMAIL_THREAD(DAVE_EMAIL_EG) BEGIN_EMAIL_THREAD(RON_EMAIL_EG) BEGIN_EMAIL_THREAD(TANISHA_EMAIL_NG) BEGIN_EMAIL_THREAD(DENISE_EMAIL_FNH) BEGIN_EMAIL_THREAD(LAMAR_EMAIL_FNK0) BEGIN_EMAIL_THREAD(LAMAR_EMAIL_EGKT) BEGIN_EMAIL_THREAD(LAMAR_EMAIL_EGKM) BEGIN_EMAIL_THREAD(LAMAR_EMAIL_EGSB) BEGIN_EMAIL_THREAD(AMANDA_EMAIL_EGKM) BEGIN_EMAIL_THREAD(TREVOR_EMAIL_EGKM) BEGIN_EMAIL_THREAD(MICHAEL_EMAIL_EGKT) BEGIN_EMAIL_THREAD(MICHAEL_EMAIL_EGSB) BEGIN_EMAIL_THREAD(BRAD_EMAIL_TRV1) BEGIN_EMAIL_THREAD(BRAD_EMAIL_FIB1) BEGIN_EMAIL_THREAD(BRAD_EMAIL_MIC1) BEGIN_EMAIL_THREAD(RON_EMAIL_FAM4) BEGIN_EMAIL_THREAD(JIMMY_EMAIL_FAM4) BEGIN_EMAIL_THREAD(PATRICIA_EMAIL_MIC4) BEGIN_EMAIL_THREAD(DAVE_EMAIL_EGBB) BEGIN_EMAIL_THREAD(REHO_BMS_EMAIL) BEGIN_EMAIL_THREAD(CATH_NS_EMAIL) BEGIN_EMAIL_THREAD(CULT_DONATE500) BEGIN_EMAIL_THREAD(CULT_DONATE5000) BEGIN_EMAIL_THREAD(NIGEL_CELEB_EMAIL) BEGIN_EMAIL_THREAD(PROPERTY_DMAIL_GARAGE) BEGIN_EMAIL_THREAD(RON_EMAIL_CULT) BEGIN_EMAIL_THREAD(PRO_BAR_HOOKIES_M) BEGIN_EMAIL_THREAD(PRO_BAR_HOOKIES_F) BEGIN_EMAIL_THREAD(PRO_TOWING_IMPOUND_F) BEGIN_EMAIL_THREAD(PRO_SONAR_COLLECTIONS_M) BEGIN_EMAIL_THREAD(PRO_SONAR_COLLECTIONS_T) BEGIN_EMAIL_THREAD(PRO_SONAR_COLLECTIONS_F) BEGIN_EMAIL_THREAD(PRO_CAR_MOD_SHOP_F) BEGIN_EMAIL_THREAD(PRO_CINEMA_VINEWOOD_M) BEGIN_EMAIL_THREAD(PRO_CINEMA_DOWNTOWN_M) BEGIN_EMAIL_THREAD(PRO_CAR_SCRAP_YARD_M) BEGIN_EMAIL_THREAD(PRO_CAR_SCRAP_YARD_T) BEGIN_EMAIL_THREAD(PRO_CAR_SCRAP_YARD_F) BEGIN_EMAIL_THREAD(PRO_WEED_SHOP_F) BEGIN_EMAIL_THREAD(PRO_BAR_TEQUILALA_M) BEGIN_EMAIL_THREAD(PRO_BAR_TEQUILALA_T) BEGIN_EMAIL_THREAD(PRO_BAR_TEQUILALA_F) BEGIN_EMAIL_THREAD(PRO_BAR_PITCHERS_M) BEGIN_EMAIL_THREAD(PRO_BAR_PITCHERS_T) BEGIN_EMAIL_THREAD(PRO_BAR_PITCHERS_F) BEGIN_EMAIL_THREAD(PRO_BAR_HEN_HOUSE_M) BEGIN_EMAIL_THREAD(PRO_BAR_HEN_HOUSE_T) BEGIN_EMAIL_THREAD(PRO_BAR_HEN_HOUSE_F) BEGIN_EMAIL_THREAD(CULT_DONATE_10000) BEGIN_EMAIL_THREAD(BITH_AA_EMAIL_M) BEGIN_EMAIL_THREAD(BITH_AA_EMAIL_T) BEGIN_EMAIL_THREAD(BITH_AA_EMAIL_F) BEGIN_EMAIL_THREAD(VEHSITE_DMAILS_BIKE) BEGIN_EMAIL_THREAD(VEHSITE_DMAILS_AUTO) BEGIN_EMAIL_THREAD(HUSH_SMUSH_SPAM) BEGIN_EMAIL_THREAD(HUSH_SMUSH_FOXYMAMA) BEGIN_EMAIL_THREAD(HUSH_SMUSH_ALTAREGO) BEGIN_EMAIL_THREAD(HUSH_SMUSH_BADKITTY) BEGIN_EMAIL_THREAD(HUSH_SMUSH_7YEARBITCH) BEGIN_EMAIL_THREAD(HUSH_SMUSH_FROGGY) BEGIN_EMAIL_THREAD(HUSH_SMUSH_MISSCUDDLES) BEGIN_EMAIL_THREAD(CATH_NS_T_EMAIL) BEGIN_EMAIL_THREAD(CATH_NS_M_EMAIL) BEGIN_EMAIL_THREAD(CATH_NS_F_EMAIL) */ //Test of dynamic emails //Bailbonds test /* SENT_BAIL_BOND_EMAILTEST(BBI_QUARRY, FALSE) SENT_BAIL_BOND_EMAILTEST(BBI_FARM, FALSE) SENT_BAIL_BOND_EMAILTEST(BBI_MOUNTAIN, FALSE) SENT_BAIL_BOND_EMAILTEST(BBI_HOBO, FALSE) */ //TEST_DYNAMIC_THREAD /* FIRE_EMAIL_INTO_DYNAMIC_THREAD(TEST_DYNAMIC_THREAD, CULT1) FIRE_EMAIL_INTO_DYNAMIC_THREAD(TEST_DYNAMIC_THREAD, CULT2) FIRE_EMAIL_INTO_DYNAMIC_THREAD(TEST_DYNAMIC_THREAD, CULT3) FIRE_EMAIL_INTO_DYNAMIC_THREAD(TEST_DYNAMIC_THREAD, CULTINITIAL) FIRE_EMAIL_INTO_DYNAMIC_THREAD(TEST_DYNAMIC_THREAD, CULT1) FIRE_EMAIL_INTO_DYNAMIC_THREAD(TEST_DYNAMIC_THREAD, CULT2) FIRE_EMAIL_INTO_DYNAMIC_THREAD(TEST_DYNAMIC_THREAD, CULT3) FIRE_EMAIL_INTO_DYNAMIC_THREAD(TEST_DYNAMIC_THREAD, CULT1) FIRE_EMAIL_INTO_DYNAMIC_THREAD(TEST_DYNAMIC_THREAD, CULT2) FIRE_EMAIL_INTO_DYNAMIC_THREAD(TEST_DYNAMIC_THREAD, CULT3) FIRE_EMAIL_INTO_DYNAMIC_THREAD(TEST_DYNAMIC_THREAD, CULTINITIAL) FIRE_EMAIL_INTO_DYNAMIC_THREAD(TEST_DYNAMIC_THREAD, CULT1) FIRE_EMAIL_INTO_DYNAMIC_THREAD(TEST_DYNAMIC_THREAD, CULT2) FIRE_EMAIL_INTO_DYNAMIC_THREAD(TEST_DYNAMIC_THREAD, CULT3) OVERRIDE_CONTENT_FOR_DYNAMIC_THREAD(TEST_DYNAMIC_THREAD, "TEST1") ADD_CONTENT_FOR_DYNAMIC_THREAD_SUBSTRING(TEST_DYNAMIC_THREAD, "TEST2") */ //SCRIPT_ASSERT("Dynamic email test!") g_bEmailSystemUpdated = TRUE //SEND_DYNAMIC_EMAIL_FOR_PROPERTY_PURCHASE( VEHGEN_WEB_CAR_MICHAEL ) //SEND_DYNAMIC_EMAIL_FOR_PROPERTY_PURCHASE( VEHGEN_WEB_CAR_FRANKLIN ) //SEND_DYNAMIC_EMAIL_FOR_PROPERTY_PURCHASE( VEHGEN_WEB_CAR_TREVOR ) BOOL bTryDynamicRelease = TRUE WHILE TRUE INT i = 0 //If the bailbond thread is active and we're past that point release it from the dynamic registers IF bTryDynamicRelease IF IS_BIT_SET(g_savedGlobals.sBailBondData.iLauncherBitFlags, ENUM_TO_INT(MAX_BAILBOND_IDS)-1) CPRINTLN(DEBUG_EMAIL, "Releasing DYNAMIC_THREAD_BAIL_BONDS due to being past that point in the game.") RELEASE_DYNAMIC_THREAD_HOLD_ON_BUFFER(DYNAMIC_THREAD_BAIL_BONDS) bTryDynamicRelease = FALSE ENDIF ENDIF //for each active //check for delay progress //fire next step if nessessary IF NOT g_bEmailSystemPaused //if the email system update is not paused AND GET_GAME_TIMER() > g_iGlobalWaitTime REPEAT TOTAL_EMAIL_THREADS_IN_GAME i //active and not over and not blocking until a response IF g_AllEmailThreads[i].bActive AND (NOT g_AllEmailThreads[i].bEnded) AND (NOT g_AllEmailThreads[i].bBLockedUntilResponse) CDEBUG2LN(DEBUG_EMAIL, "Updating email thread ", i, "'s delay status. Time left until thread update is ", g_AllEmailThreads[i].iDelay - delays[i], "ms.") delays[i] += delay_stride IF delays[i] > g_AllEmailThreads[i].iDelay CDEBUG1LN(DEBUG_EMAIL, "Found email thread ", i, " needs updating. Running communication safety checks.") IF PRIVATE_Is_Safe_To_Start_Communication(7, CHAR_BLANK_ENTRY, CPR_MEDIUM) PROGRESS_EMAIL_THREAD(i) delays[i] = 0 g_bEmailSystemUpdated = TRUE ENDIF ENDIF ENDIF WAIT(0) ENDREPEAT //Maintain the dynamic email queue //check for dynamic emails pending //todLast = todCurrent todCurrent = GET_CURRENT_TIMEOFDAY() INT hdiff = 0 INT dummy = 0 INT k = 0 GET_DIFFERENCE_BETWEEN_TIMEOFDAYS(todCurrent, todLast, dummy, dummy, hdiff, dummy, dummy, dummy) IF hdiff < 0 hdiff *= -1 ENDIF IF hdiff > 0 AND (g_Cellphone.PhoneDS = PDS_AWAY) // todLast = todCurrent IF g_iDynamicEmailsPending > 0 CDEBUG3LN(DEBUG_EMAIL, "Detected hour change of ", hdiff, " and controller has ", g_iDynamicEmailsPending, " pending dynamic emails.") INT iTodo = g_iDynamicEmailsPending INT j = 0 //They could be anywhere in the list. //For each instance of j WHILE iTodo != 0 IF g_DynamicEmailsPending[j].RegIDOfTarget != 0 AND j < MAX_DYNAMIC_EMAILS_PENDING AND g_DynamicEmailsPending[j].bNotSent //Process the timer. g_DynamicEmailsPending[j].iInGameHoursBeforeTrigger -= hdiff CDEBUG1LN(DEBUG_EMAIL, "Pending dynamic email has ", g_DynamicEmailsPending[j].iInGameHoursBeforeTrigger," hours before trigger.") BOOL bPurged = FALSE //if the thread this is based on is still in the buffers BOOL bInBuffers = FALSE BOOL bFoundOrDone = FALSE INT iDTBuffer = 0//threads CDEBUG1LN(DEBUG_EMAIL, "Looking for thread with ID : ", g_DynamicEmailsPending[j].RegIDOfTarget, ".") WHILE !bFoundOrDone IF g_DynamicEmailThreadBuffers[iDTBuffer].registrationID != g_DynamicEmailsPending[j].RegIDOfTarget ++iDTBuffer //keep looking ELSE //target still in the buffer, this is still valid bInBuffers = TRUE bFoundOrDone = TRUE ENDIF IF iDTBuffer = DYNAMIC_EMAIL_THREAD_BUFFERS //not in buffers at all. Clear this one bFoundOrDone = TRUE g_DynamicEmailsPending[j].RegIDOfTarget = 0 bPurged = TRUE ENDIF ENDWHILE IF !bInBuffers CDEBUG1LN(DEBUG_EMAIL, "Pending dynamic email ", j," was not in buffers.") bPurged = TRUE g_DynamicEmailsPending[j].bNotSent = FALSE ELSE //If it is still in the buffers check if the timer is 0 or less //If so fire and purge it IF g_DynamicEmailsPending[j].iInGameHoursBeforeTrigger < 1 CDEBUG1LN(DEBUG_EMAIL, "About to send pending dynamic email. bOverrideContent: ", PICK_STRING(g_DynamicEmailsPending[j].bOverrideContent, "TRUE", "FALSE"), " iOverrideAdditional:", g_DynamicEmailsPending[j].iOverrideAdditional, ".") IF PRIVATE_Is_Safe_To_Start_Communication(7, NO_CHARACTER, CPR_MEDIUM) BOOL bAboutToOverride = FALSE IF (g_DynamicEmailsPending[j].bOverrideContent) OR (g_DynamicEmailsPending[j].iOverrideAdditional > 0) bAboutToOverride = TRUE ENDIF IF FIRE_EMAIL_INTO_DYNAMIC_THREAD(g_DynamicEmailsPending[j].eTargetThread, g_DynamicEmailsPending[j].eEmailID,bAboutToOverride) BOOL noSubstrings = TRUE IF g_DynamicEmailsPending[j].iOverrideAdditional > 0 noSubstrings = FALSE ENDIF IF g_DynamicEmailsPending[j].bOverrideContent OVERRIDE_CONTENT_FOR_DYNAMIC_THREAD(g_DynamicEmailsPending[j].eTargetThread, g_DynamicEmailsPending[j].content,noSubstrings) ENDIF IF (g_DynamicEmailsPending[j].iOverrideAdditional > 0) k = 0 REPEAT g_DynamicEmailsPending[j].iOverrideAdditional k ADD_CONTENT_FOR_DYNAMIC_THREAD_SUBSTRING(g_DynamicEmailsPending[j].eTargetThread, g_DynamicEmailsPending[j].additional[k]) ENDREPEAT ENDIF IF bAboutToOverride AND NOT noSubstrings PUSH_FEEDIFICATION_OF_DYNAMIC_THREAD(g_DynamicEmailsPending[j].eTargetThread) ENDIF RELEASE_DYNAMIC_THREAD_HOLD_ON_BUFFER(g_DynamicEmailsPending[j].eTargetThread) ENDIF //purge it g_DynamicEmailsPending[j].RegIDOfTarget = 0 g_DynamicEmailsPending[j].bOverrideContent = FALSE g_DynamicEmailsPending[j].iInGameHoursBeforeTrigger = 0 bPurged = TRUE g_DynamicEmailsPending[j].bNotSent = FALSE ENDIF ENDIF ENDIF //remember to clear this from the list if it's been sent or purged IF bPurged --g_iDynamicEmailsPending CDEBUG1LN(DEBUG_EMAIL, "Now ", g_iDynamicEmailsPending, " dynamic emails left still pending.") ENDIF --iTodo ENDIF ++j IF j = MAX_DYNAMIC_EMAILS_PENDING //list fully processed failsafe iTodo = 0 ENDIF WAIT(0) ENDWHILE ENDIF ENDIF ENDIF CDEBUG3LN(DEBUG_EMAIL, "Sleeping controller at point A for ", delay_stride, " milliseconds.") WAIT(delay_stride) g_iUnreadEmailsSP0 = 0 g_iUnreadEmailsSP1 = 0 g_iUnreadEmailsSP2 = 0 INT t = g_Inboxes[EMAILER_MICHAEL_DE_SANTO].iTotalMails IF t > MAX_INBOX_LOGGED_MAILS_THREADS t = MAX_INBOX_LOGGED_MAILS_THREADS ENDIF CDEBUG3LN(DEBUG_EMAIL, "Updating unread emails. StartP0:", g_iUnreadEmailsSP0, " StartP1:", g_iUnreadEmailsSP1, " StartP2:", g_iUnreadEmailsSP2, ".") REPEAT t i IF NOT g_Inboxes[EMAILER_MICHAEL_DE_SANTO].HasBeenViewed[i] ++g_iUnreadEmailsSP0 ENDIF ENDREPEAT t = g_Inboxes[EMAILER_FRANKLIN].iTotalMails IF t > MAX_INBOX_LOGGED_MAILS_THREADS t = MAX_INBOX_LOGGED_MAILS_THREADS ENDIF REPEAT t i IF NOT g_Inboxes[EMAILER_FRANKLIN].HasBeenViewed[i] ++g_iUnreadEmailsSP1 ENDIF ENDREPEAT t = g_Inboxes[EMAILER_TREVOR_PHILIPS].iTotalMails IF t > MAX_INBOX_LOGGED_MAILS_THREADS t = MAX_INBOX_LOGGED_MAILS_THREADS ENDIF REPEAT t i IF NOT g_Inboxes[EMAILER_TREVOR_PHILIPS].HasBeenViewed[i] ++g_iUnreadEmailsSP2 ENDIF ENDREPEAT CDEBUG3LN(DEBUG_EMAIL, "Sleeping controller at point B for ", delay_stride, " milliseconds.") WAIT(delay_stride) ENDWHILE ENDSCRIPT