////////////////////////////////////////////////////////////////////////////////////////// // // // SCRIPT NAME : social_public.sch // // AUTHOR : Kenneth Ross // // DESCRIPTION : Contains all the public funtions related to the social // // integration. // // // ////////////////////////////////////////////////////////////////////////////////////////// USING "rage_builtins.sch" USING "globals.sch" USING "commands_apps.sch" USING "commands_stats.sch" USING "net_stat_system.sch" USING "vehicle_public.sch" #if not USE_CLF_DLC #if not USE_NRM_DLC USING "heist_private.sch" #ENDIF #ENDIF USING "finance_modifiers_public.sch" /// PURPOSE: Returns TRUE if we have received at least 1 event from the car app FUNC BOOL HAS_PLAYER_USED_CAR_APP() IF (g_savedGlobals.sSocialData.bCarAppUsed) RETURN TRUE ENDIF #IF IS_DEBUG_BUILD IF g_bDebugAppScreenOverride RETURN g_bDebugLosSantosCustomsPlayedStatusOverride ENDIF #ENDIF RETURN FALSE ENDFUNC /// PURPOSE: Returns TRUE if we have received at least 1 event from the dog app FUNC BOOL HAS_PLAYER_USED_CHOP_APP() IF (g_savedGlobals.sSocialData.bDogAppUsed) RETURN TRUE ENDIF #IF IS_DEBUG_BUILD IF g_bDebugAppScreenOverride RETURN g_bDebugChopPlayedStatusOverride ENDIF #ENDIF RETURN FALSE ENDFUNC /// PURPOSE: Training level refers to the amount of tricks that chop can perform. /// Tricks include beg, paw, and sit. FUNC INT GET_CHOP_TRAINING_LEVEL_FROM_APP() #IF IS_DEBUG_BUILD IF g_bUnlockAllChopTricks RETURN 4 ENDIF #ENDIF RETURN g_savedGlobals.sSocialData.sDogAppData.iTrainingLevel ENDFUNC /// PURPOSE: Returns Chop's current collar in the app. FUNC INT GET_CHOP_COLLAR_FROM_APP() RETURN g_savedGlobals.sSocialData.sDogAppData.iCollar ENDFUNC /// PURPOSE: Chop will either be GOOD, MEDIUM, or BAD. FUNC CHOP_BEHAVIOUR_ENUM GET_CHOP_BEHAVIOUR_FROM_APP() IF g_savedGlobals.sSocialData.sDogAppData.bAppDataReceived IF g_savedGlobals.sSocialData.sDogAppData.fHappiness > 66 RETURN CHOP_BEHAVIOUR_GOOD ELIF g_savedGlobals.sSocialData.sDogAppData.fHappiness > 33 RETURN CHOP_BEHAVIOUR_MEDIUM ELSE RETURN CHOP_BEHAVIOUR_BAD ENDIF ENDIF #IF IS_DEBUG_BUILD IF g_bDebugAppScreenOverride IF g_bDebugChopPlayedStatusOverride IF g_bDebugChopGoodStatusOverride RETURN CHOP_BEHAVIOUR_GOOD ELSE RETURN CHOP_BEHAVIOUR_MEDIUM ENDIF ENDIF ENDIF #ENDIF RETURN CHOP_BEHAVIOUR_BAD ENDFUNC /// PURPOSE: Clears CarApp data for previous order PROC SET_CAR_APP_ORDER_HAS_BEEN_PROCESSED(SOCIAL_CAR_APP_ORDER_DATA &sCarAppOrder, enumCharacterList ePed) PRINTLN("social_controller: SET_CAR_APP_ORDER_HAS_BEEN_PROCESSED - requesting car data to be deleted") sCarAppOrder.bOrderPending = FALSE sCarAppOrder.bOrderReceivedOnBoot = FALSE IF NETWORK_IS_GAME_IN_PROGRESS() g_savedMPGlobalsNew.g_savedMPGlobals[GET_SAVE_GAME_ARRAY_SLOT()].MpSavedCarApp.bDeleteCarData = TRUE g_savedMPGlobalsNew.g_savedMPGlobals[GET_SAVE_GAME_ARRAY_SLOT()].MpSavedCarApp.bCarAppPlateSet = TRUE g_savedMPGlobalsNew.g_savedMPGlobals[GET_SAVE_GAME_ARRAY_SLOT()].MpSavedCarApp.iCarAppPlateBack = sCarAppOrder.iPlateBack_pending g_savedMPGlobalsNew.g_savedMPGlobals[GET_SAVE_GAME_ARRAY_SLOT()].MpSavedCarApp.tlCarAppPlateText = sCarAppOrder.tlPlateText_pending g_savedMPGlobalsNew.g_savedMPGlobals[GET_SAVE_GAME_ARRAY_SLOT()].MpSavedCarApp.iOrderCount++ ELSE g_savedGlobals.sSocialData.bDeleteCarData = TRUE g_savedGlobals.sSocialData.iOrderToDelete = ENUM_TO_INT(ePed) g_savedGlobals.sSocialData.bCarAppPlateSet = TRUE g_savedGlobals.sSocialData.iCarAppPlateBack = sCarAppOrder.iPlateBack_pending g_savedGlobals.sSocialData.tlCarAppPlateText = sCarAppOrder.tlPlateText_pending IF ePed = CHAR_MICHAEL OR ePed = CHAR_FRANKLIN OR ePed = CHAR_TREVOR g_savedGlobals.sSocialData.bFirstOrderProcessed[ePed] = TRUE g_savedGlobals.sSocialData.iOrderCount[ePed]++ STAT_INCREMENT(SP_CAR_APP_ORDER_COUNT, 1) ENDIF ENDIF ENDPROC /// PURPOSE: Clears CarApp data for previous order PROC SET_CAR_APP_ORDER_HAS_BEEN_CANCELLED(SOCIAL_CAR_APP_ORDER_DATA &sCarAppOrder) PRINTLN("social_controller: SET_CAR_APP_ORDER_HAS_BEEN_CANCELLED - requesting car data to be deleted") sCarAppOrder.bOrderPending = FALSE sCarAppOrder.bOrderReceivedOnBoot = FALSE IF NETWORK_IS_GAME_IN_PROGRESS() g_savedMPGlobalsNew.g_savedMPGlobals[GET_SAVE_GAME_ARRAY_SLOT()].MpSavedCarApp.bDeleteCarData = TRUE ELSE BAWSAQ_INCREMENT_MODIFIER(BSMF_SM_MONB) g_savedGlobals.sSocialData.bDeleteCarData = TRUE ENDIF ENDPROC /// PURPOSE: Nukes the app data as if we have just started a new game PROC RESET_ALL_STORED_APP_DATA() g_bResetSocialController = TRUE SocialDataSaved sTempData g_savedGlobals.sSocialData = sTempData g_savedGlobals.sSocialData.sCarAppData[CHAR_FRANKLIN].eModel = BUFFALO2 g_savedGlobals.sSocialData.bPlayerUnlockedInApp[CHAR_FRANKLIN] = TRUE g_savedGlobals.sSocialData.sCarAppData[CHAR_MICHAEL].eModel = TAILGATER g_savedGlobals.sSocialData.sCarAppData[CHAR_TREVOR].eModel = BODHI2 g_savedGlobals.sSocialData.sDogAppData.iCollar = 4 ENDPROC /// PURPOSE: Display a feed message as a single player Facebook post is sent. PROC SHOW_FACEBOOK_FEED_MESSAGE(STRING paramMessageLabel) IF NOT IS_STRING_NULL_OR_EMPTY(paramMessageLabel) BEGIN_TEXT_COMMAND_THEFEED_POST("FB_TITLE") ADD_TEXT_COMPONENT_SUBSTRING_TEXT_LABEL(paramMessageLabel) END_TEXT_COMMAND_THEFEED_POST_MESSAGETEXT("CHAR_FACEBOOK", "CHAR_FACEBOOK", TRUE, TEXT_ICON_BLANK, "") ENDIF ENDPROC /// PURPOSE: Display a feed message as a single player Facebook milestone post is sent. PROC SHOW_FACEBOOK_MILESTONE_FEED_MESSAGE(MILESTONE_ID paramFacebookMilestone) STRING strMessageLabel SWITCH paramFacebookMilestone CASE FACEBOOK_MILESTONE_CHECKLIST strMessageLabel = "FB_HUND_PERC" BREAK CASE FACEBOOK_MILESTONE_OVERVIEW strMessageLabel = "FB_STORY" BREAK CASE FACEBOOK_MILESTONE_VEHICLES strMessageLabel = "FB_VEHICLES" BREAK CASE FACEBOOK_MILESTONE_PROPERTIES strMessageLabel = "FB_PROPERTIES" BREAK CASE FACEBOOK_MILESTONE_PSYCH strMessageLabel = "FB_PSYCH" BREAK CASE FACEBOOK_MILESTONE_MAPREVEAL strMessageLabel = "FB_MAPREV" BREAK ENDSWITCH SHOW_FACEBOOK_FEED_MESSAGE(strMessageLabel) ENDPROC /// PURPOSE: Trigger a facebook post and display a feed message as a single player heist is passed. #IF NOT USE_SP_DLC PROC MAKE_FACEBOOK_HEIST_COMPLETE_POST(INT paramHeistID) IF NETWORK_IS_SIGNED_IN() IF FACEBOOK_CAN_POST_TO_FACEBOOK() INT iTotalTake INT iHeistChoice SWITCH paramHeistID CASE HEIST_JEWEL IF NOT IS_BIT_SET(g_savedGlobals.sSocialData.iFacebookPostsMadeBitset, ENUM_TO_INT(FBPOST_FIRST_HEIST)) iHeistChoice = g_savedGlobals.sFlow.controls.intIDs[Get_Heist_Choice_FlowInt_For_Heist(HEIST_JEWEL)] iTotalTake = g_savedGlobals.sHeistData.sEndScreenData[HEIST_JEWEL].iPlayerTake[CHAR_MICHAEL] iTotalTake += g_savedGlobals.sHeistData.sEndScreenData[HEIST_JEWEL].iPlayerTake[CHAR_FRANKLIN] SWITCH iHeistChoice CASE HEIST_CHOICE_JEWEL_STEALTH FACEBOOK_POST_COMPLETED_HEIST("JH2A", iTotalTake, 0) BREAK CASE HEIST_CHOICE_JEWEL_HIGH_IMPACT FACEBOOK_POST_COMPLETED_HEIST("JH2B", iTotalTake, 0) BREAK ENDSWITCH SHOW_FACEBOOK_FEED_MESSAGE("FB_J_HEIST") SET_BIT(g_savedGlobals.sSocialData.iFacebookPostsMadeBitset, ENUM_TO_INT(FBPOST_FIRST_HEIST)) ENDIF BREAK CASE HEIST_FINALE IF NOT IS_BIT_SET(g_savedGlobals.sSocialData.iFacebookPostsMadeBitset, ENUM_TO_INT(FBPOST_FINAL_HEIST)) iHeistChoice = g_savedGlobals.sFlow.controls.intIDs[Get_Heist_Choice_FlowInt_For_Heist(HEIST_FINALE)] iTotalTake = g_savedGlobals.sHeistData.sEndScreenData[HEIST_FINALE].iPlayerTake[CHAR_MICHAEL] iTotalTake += g_savedGlobals.sHeistData.sEndScreenData[HEIST_FINALE].iPlayerTake[CHAR_FRANKLIN] iTotalTake += g_savedGlobals.sHeistData.sEndScreenData[HEIST_FINALE].iPlayerTake[CHAR_TREVOR] SWITCH iHeistChoice CASE HEIST_CHOICE_FINALE_TRAFFCONT FACEBOOK_POST_COMPLETED_HEIST("FH2A", iTotalTake, 0) BREAK CASE HEIST_CHOICE_FINALE_HELI FACEBOOK_POST_COMPLETED_HEIST("FH2B", iTotalTake, 0) BREAK ENDSWITCH SHOW_FACEBOOK_FEED_MESSAGE("FB_BS_HEIST") SET_BIT(g_savedGlobals.sSocialData.iFacebookPostsMadeBitset, ENUM_TO_INT(FBPOST_FINAL_HEIST)) ENDIF BREAK ENDSWITCH ENDIF ENDIF ENDPROC #ENDIF /// PURPOSE: Check for the moment a new facebook account is linked /// and pop up a feed message to give the player some feedback. PROC MAINTAIN_FACEBOOK_ACCOUNT_LINKED_FEED() IF NOT IS_BIT_SET(g_savedGlobals.sSocialData.iFacebookPostsMadeBitset, ENUM_TO_INT(FBPOST_ACCOUNT_LINKED)) IF NETWORK_IS_SIGNED_IN() IF FACEBOOK_CAN_POST_TO_FACEBOOK() SHOW_FACEBOOK_FEED_MESSAGE("FB_NEW_ACC") SET_BIT(g_savedGlobals.sSocialData.iFacebookPostsMadeBitset, ENUM_TO_INT(FBPOST_ACCOUNT_LINKED)) ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: Check if the player has driven every vehicle in the game and post a Facebook /// message the first time the result is TRUE. PROC MAINTAIN_FACEBOOK_ALL_VEHICLES_DRIVEN_CHECKS() IF NETWORK_IS_SIGNED_IN() IF FACEBOOK_CAN_POST_TO_FACEBOOK() IF GET_PROFILE_SETTING(FACEBOOK_POSTED_ALL_VEHICLES_DRIVEN) != 1 IF GET_PLAYER_HAS_DRIVEN_ALL_VEHICLES() FACEBOOK_POST_COMPLETED_MILESTONE(FACEBOOK_MILESTONE_VEHICLES) SHOW_FACEBOOK_MILESTONE_FEED_MESSAGE(FACEBOOK_MILESTONE_VEHICLES) SET_HAS_POSTED_ALL_VEHICLES_DRIVEN() ENDIF ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: Check if the player has fully discovered the whole of the GTA V map. /// NOTES: We are now checking for 98% reveal not 100% due to B*1571171 PROC MAINTAIN_FACEBOOK_MAP_REVEALED_CHECKS() IF NETWORK_IS_SIGNED_IN() IF NOT IS_BIT_SET(g_savedGlobals.sSocialData.iFacebookPostsMadeBitset, ENUM_TO_INT(FBPOST_MAP_REVEALED)) IF FACEBOOK_CAN_POST_TO_FACEBOOK() IF GET_MINIMAP_FOW_DISCOVERY_RATIO() >= 0.975 FACEBOOK_POST_COMPLETED_MILESTONE(FACEBOOK_MILESTONE_MAPREVEAL) SHOW_FACEBOOK_MILESTONE_FEED_MESSAGE(FACEBOOK_MILESTONE_MAPREVEAL) SET_BIT(g_savedGlobals.sSocialData.iFacebookPostsMadeBitset, ENUM_TO_INT(FBPOST_MAP_REVEALED)) ENDIF ENDIF ENDIF ENDIF ENDPROC /// PURPOSE: Checks if required state should trigger facebook post PROC TRIGGER_CHARACTER_FACEBOOK_POST_UPDATES() // Only trigger the facebook update if flag is set from creator and we haven't already triggered the update IF g_bPostCharacterFacebookUpdate AND g_iCharacterFacebookUpdateState = MP_CHARACTER_FACEBOOK_POST_NULL IF NOT HAS_ENTERED_OFFLINE_SAVE_FM() PRINTLN("TRIGGER_CHARACTER_FACEBOOK_POST_UPDATES - Post char headshot to facebook: g_iCharacterFacebookUpdateState = MP_CHARACTER_FACEBOOK_POST_VALIDATE") g_iCharacterFacebookUpdateState = MP_CHARACTER_FACEBOOK_POST_VALIDATE ENDIF ENDIF ENDPROC /// PURPOSE: Performs basic checks that we are in a situation safe to post feed FUNC BOOL IS_SAFE_TO_POST_CHARACTER_FACEBOOK_FEED_MESSAGE(INT iSlot = -1) IF g_SkipFmTutorials RETURN TRUE ENDIF IF HAS_ENTERED_GAME_WITH_REDUCED_CONTENT_DUE_TO_CLOUD() RETURN TRUE ENDIF IF HAS_ENTERED_OFFLINE_SAVE_FM() RETURN FALSE ENDIF RETURN GET_MP_BOOL_CHARACTER_STAT(MP_STAT_FM_INTRO_MISS_DONE, iSlot) ENDFUNC /// PURPOSE: Post our new character as we transition into GTA Online at start of MP PROC RUN_CHARACTER_FACEBOOK_POST_UPDATES() IF g_bPostCharacterFacebookUpdate SWITCH g_iCharacterFacebookUpdateState CASE MP_CHARACTER_FACEBOOK_POST_NULL // Do nothing, waiting for state to be changed from headshot logic PRINTLN("RUN_CHARACTER_FACEBOOK_POST_UPDATES - MP_CHARACTER_FACEBOOK_POST_NULL. In NULL state but the flag g_bPostCharacterFacebookUpdate is set to TRUE ") BREAK CASE MP_CHARACTER_FACEBOOK_POST_VALIDATE IF FACEBOOK_CAN_POST_TO_FACEBOOK() PRINTLN("RUN_CHARACTER_FACEBOOK_POST_UPDATES - FACEBOOK_CAN_POST_TO_FACEBOOK() = TRUE. Post to Facebook") g_iCharacterFacebookUpdateState = MP_CHARACTER_FACEBOOK_POST_BEGIN ELSE PRINTLN("RUN_CHARACTER_FACEBOOK_POST_UPDATES - FACEBOOK_CAN_POST_TO_FACEBOOK() = FALSE. Stop any posts") g_bPostCharacterFacebookUpdate = FALSE g_iCharacterFacebookUpdateState = MP_CHARACTER_FACEBOOK_POST_NULL ENDIF BREAK CASE MP_CHARACTER_FACEBOOK_POST_BEGIN IF FACEBOOK_HAS_POST_COMPLETED() IF FACEBOOK_POST_CREATE_CHARACTER() PRINTLN("RUN_CHARACTER_FACEBOOK_POST_UPDATES - FACEBOOK_POST_CREATE_CHARACTER() = TRUE. Wait for success") g_iCharacterFacebookUpdateState = MP_CHARACTER_FACEBOOK_POST_COMPLETE #IF IS_DEBUG_BUILD ELSE IF GET_GAME_TIMER() % 1500 < 75 PRINTLN("RUN_CHARACTER_FACEBOOK_POST_UPDATES - FACEBOOK_POST_CREATE_CHARACTER() = FALSE. Waiting (MP_CHARACTER_FACEBOOK_POST_BEGIN)") ENDIF #ENDIF ENDIF #IF IS_DEBUG_BUILD ELSE IF GET_GAME_TIMER() % 1500 < 75 PRINTLN("RUN_CHARACTER_FACEBOOK_POST_UPDATES - FACEBOOK_HAS_POST_COMPLETED() = FALSE. Waiting (MP_CHARACTER_FACEBOOK_POST_BEGIN)") ENDIF #ENDIF ENDIF BREAK CASE MP_CHARACTER_FACEBOOK_POST_COMPLETE IF FACEBOOK_HAS_POST_COMPLETED() IF FACEBOOK_DID_POST_SUCCEED() PRINTLN("RUN_CHARACTER_FACEBOOK_POST_UPDATES - FACEBOOK_DID_POST_SUCCEED() = TRUE. Finished") g_iCharacterFacebookUpdateState = MP_CHARACTER_FACEBOOK_FEED_MESSAGE ELSE PRINTLN("RUN_CHARACTER_FACEBOOK_POST_UPDATES - FACEBOOK_DID_POST_SUCCEED() = FALSE. Retry. Attempts: ", g_iNumberOfCharacterFacebookAttempts) g_iNumberOfCharacterFacebookAttempts++ // Check if we have reached the maximum number of posts IF g_iNumberOfCharacterFacebookAttempts >= ciMAX_CHAR_FACEBOOK_POST_ATTEMPTS //...yes, reset our attempts and move to idle state (re-triggered if leave and re-enter) PRINTLN("RUN_CHARACTER_FACEBOOK_POST_UPDATES - FACEBOOK_DID_POST_SUCCEED() = FALSE. Max attempts hit. Stop posting") g_iNumberOfCharacterFacebookAttempts = 0 g_iCharacterFacebookUpdateState = MP_CHARACTER_FACEBOOK_POST_NULL ELSE //...no, get network time and wait for delay to be complete PRINTLN("RUN_CHARACTER_FACEBOOK_POST_UPDATES - FACEBOOK_DID_POST_SUCCEED() = FALSE. Delay before retrying post (", GET_CLOUD_TIME_AS_INT(), ")") g_timeForNextCharacterFacebookPost = GET_NETWORK_TIME() g_iCharacterFacebookUpdateState = MP_CHARACTER_FACEBOOK_REPOST_DELAY ENDIF ENDIF #IF IS_DEBUG_BUILD ELSE IF GET_GAME_TIMER() % 1500 < 75 PRINTLN("RUN_CHARACTER_FACEBOOK_POST_UPDATES - FACEBOOK_HAS_POST_COMPLETED() = FALSE. Waiting (MP_CHARACTER_FACEBOOK_POST_COMPLETE)") ENDIF #ENDIF ENDIF BREAK CASE MP_CHARACTER_FACEBOOK_REPOST_DELAY // Wait until the timer has completed before attempting another post IF ABSI(GET_TIME_DIFFERENCE(g_timeForNextCharacterFacebookPost, GET_NETWORK_TIME())) > (ciMAX_CHAR_FACEBOOK_POST_DELAY * g_iNumberOfCharacterFacebookAttempts) PRINTLN("RUN_CHARACTER_FACEBOOK_POST_UPDATES - MP_CHARACTER_FACEBOOK_REPOST_DELAY. Delay is over. Retry post (", GET_CLOUD_TIME_AS_INT(), ")") g_bPostCharacterFacebookUpdate = TRUE g_iCharacterFacebookUpdateState = MP_CHARACTER_FACEBOOK_POST_VALIDATE #IF IS_DEBUG_BUILD ELSE IF GET_GAME_TIMER() % 1500 < 75 PRINTLN("RUN_CHARACTER_FACEBOOK_POST_UPDATES - MP_CHARACTER_FACEBOOK_REPOST_DELAY waiting for timer to be complete") ENDIF #ENDIF ENDIF BREAK CASE MP_CHARACTER_FACEBOOK_FEED_MESSAGE IF NOT IS_TRANSITION_ACTIVE() AND IS_SAFE_TO_POST_CHARACTER_FACEBOOK_FEED_MESSAGE() // Post to feed ticker SHOW_FACEBOOK_FEED_MESSAGE("FB_NEW_CHAR") g_bPostCharacterFacebookUpdate = FALSE g_iCharacterFacebookUpdateState = MP_CHARACTER_FACEBOOK_POST_NULL PRINTLN("RUN_CHARACTER_FACEBOOK_POST_UPDATES - HOW_FACEBOOK_FEED_MESSAGE(FB_NEW_CHAR)") #IF IS_DEBUG_BUILD ELSE IF GET_GAME_TIMER() % 1500 < 75 PRINTLN("RUN_CHARACTER_FACEBOOK_POST_UPDATES - IS_TRANSITION_ACTIVE() = TRUE. Waiting (MP_CHARACTER_FACEBOOK_FEED_MESSAGE)") ENDIF #ENDIF ENDIF BREAK DEFAULT PRINTLN("RUN_CHARACTER_FACEBOOK_POST_UPDATES - State unknown, ", g_iCharacterFacebookUpdateState, " EXIT") SCRIPT_ASSERT("RUN_CHARACTER_FACEBOOK_POST_UPDATES - Reached an unknown state. Stop attempting to post to Facebook") g_bPostCharacterFacebookUpdate = FALSE g_iCharacterFacebookUpdateState = MP_CHARACTER_FACEBOOK_POST_NULL BREAK ENDSWITCH ENDIF ENDPROC #IF USE_MULTI_NUMBER_PLATE_SETUP_IN_MP FUNC BOOL ADD_NUMBER_PLATE_TEXT_TO_PLAYERS_SC_ACCOUNT(STRING sPlateText) INT iSlot INT iArrayOfPlateDigits[8] INT iPlateIndex INT iStrLen = GET_LENGTH_OF_LITERAL_STRING(sPlateText) REPEAT COUNT_OF(g_tlPlateTextForSCAccount) iSlot IF IS_STRING_NULL_OR_EMPTY(g_tlPlateTextForSCAccount[iSlot]) PRINTLN("[PURCHASED PLATES] ADD_NUMBER_PLATE_TEXT_TO_PLAYERS_SC_ACCOUNT - Queueing up plate ", sPlateText) g_tlPlateTextForSCAccount[iSlot] = sPlateText g_bAddSCPlateToMPList[iSlot] = NETWORK_IS_GAME_IN_PROGRESS() g_bAddPlateTextToSC = TRUE g_bRebuildSCPlateList = TRUE // Since we take 100k from the player we need to ensure the plate gets // added to the SC account. Store the plate in packed stats until we // confirm that it's been added to the SC account. IF NETWORK_IS_GAME_IN_PROGRESS() REPEAT 8 iPlateIndex IF iPlateIndex < iStrLen iArrayOfPlateDigits[iPlateIndex] = GET_VEHICLE_NUMBER_PLATE_CHAR_AS_INT(GET_CHARACTER_FROM_AUDIO_CONVERSATION_FILENAME(sPlateText, iPlateIndex, iPlateIndex+1)) ELSE iArrayOfPlateDigits[iPlateIndex] = GET_VEHICLE_NUMBER_PLATE_CHAR_AS_INT("") ENDIF ENDREPEAT SET_PACKED_STAT_INT(PACKED_MP_SC_PLATE_0, iArrayOfPlateDigits[0]) SET_PACKED_STAT_INT(PACKED_MP_SC_PLATE_1, iArrayOfPlateDigits[1]) SET_PACKED_STAT_INT(PACKED_MP_SC_PLATE_2, iArrayOfPlateDigits[2]) SET_PACKED_STAT_INT(PACKED_MP_SC_PLATE_3, iArrayOfPlateDigits[3]) SET_PACKED_STAT_INT(PACKED_MP_SC_PLATE_4, iArrayOfPlateDigits[4]) SET_PACKED_STAT_INT(PACKED_MP_SC_PLATE_5, iArrayOfPlateDigits[5]) SET_PACKED_STAT_INT(PACKED_MP_SC_PLATE_6, iArrayOfPlateDigits[6]) SET_PACKED_STAT_INT(PACKED_MP_SC_PLATE_7, iArrayOfPlateDigits[7]) SET_PACKED_STAT_BOOL(PACKED_MP_STAT_SC_PLATE_STORED, TRUE) ENDIF RETURN TRUE ENDIF ENDREPEAT PRINTLN("[PURCHASED PLATES] ADD_NUMBER_PLATE_TEXT_TO_PLAYERS_SC_ACCOUNT - No free slots!") REPEAT COUNT_OF(g_tlPlateTextForSCAccount) iSlot PRINTLN("...", g_tlPlateTextForSCAccount[iSlot]) ENDREPEAT SCRIPT_ASSERT("[PURCHASED PLATES] ADD_NUMBER_PLATE_TEXT_TO_PLAYERS_SC_ACCOUNT - No free slots!") RETURN FALSE ENDFUNC FUNC BOOL IS_NUMBER_PLATE_TEXT_IN_MP_PLAYERS_CACHED_SC_LIST(STRING sPlateText) INT iPurchasedPlate INT iPurhcasedPlateCount = COUNT_OF(g_tlPlateTextFromSCAccount) REPEAT iPurhcasedPlateCount iPurchasedPlate IF NOT IS_STRING_NULL_OR_EMPTY(g_tlPlateTextFromSCAccount[iPurchasedPlate]) IF GET_HASH_KEY(sPlateText) = GET_HASH_KEY(g_tlPlateTextFromSCAccount[iPurchasedPlate]) AND (g_bPlateTextFromSCAccountInMPList[iPurchasedPlate] OR iPurchasedPlate = 0) RETURN TRUE ENDIF ENDIF ENDREPEAT RETURN FALSE ENDFUNC FUNC BOOL IS_NUMBER_PLATE_TEXT_IN_CACHED_SC_LIST(STRING sPlateText) INT iPurchasedPlate INT iPurhcasedPlateCount = COUNT_OF(g_tlPlateTextFromSCAccount) REPEAT iPurhcasedPlateCount iPurchasedPlate IF NOT IS_STRING_NULL_OR_EMPTY(g_tlPlateTextFromSCAccount[iPurchasedPlate]) IF GET_HASH_KEY(sPlateText) = GET_HASH_KEY(g_tlPlateTextFromSCAccount[iPurchasedPlate]) RETURN TRUE ENDIF ENDIF ENDREPEAT RETURN FALSE ENDFUNC FUNC BOOL IS_PLAYERS_SC_NUMBER_PLATES_READY() RETURN g_bInitialSCPlateListGrabbedMP ENDFUNC #ENDIF