Files
gtav-src/script/dev_ng/singleplayer/include/public/social_public.sch
T
2025-09-29 00:52:08 +02:00

577 lines
20 KiB
Scheme
Executable File

//////////////////////////////////////////////////////////////////////////////////////////
// //
// 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