Files
2025-09-29 00:52:08 +02:00

1464 lines
46 KiB
Scheme
Executable File

//
// script_MISC.sch
//
// common misc procedures/functions used in the game.
USING "globals.sch"
USING "script_buttons.sch" // temp until script_buttons.sch is included in other scripts instead of script_misc.sch
USING "script_maths.sch"
USING "commands_apps.sch"
USING "commands_dlc.sch"
USING "commands_cutscene.sch"
USING "commands_recording.sch"
USING "Achievements_enum.sch"
USING "commands_savemigration.sch"
/// PURPOSE: For use with g_savedGlobals.sShopData.iContentChecks_Game
CONST_INT NCU_SPECIAL_EDITION 0
CONST_INT NCU_COLLECTORS_EDITION 1
CONST_INT NCU_SOCIAL_CLUB 2
CONST_INT NCU_BLIMP 3
#IF IS_JAPANESE_BUILD
CONST_INT NCU_JAPANESE_SPECIAL_EDITION 4
#ENDIF
CONST_INT NCU_XMAS 5
CONST_INT NCU_NG_PREORDER 6
CONST_INT NCU_CG_TO_NG 7
CONST_INT NCU_HEISTS 8
CONST_INT ci_STAT_COLLECTOR_EDITION_CHECKED 0
CONST_INT ci_STAT_COLLECTOR_EDITION_UNLOCKED 1
// Note, the DLC hash can be found in the setup2.xml files within each dlc pack.
// ie //gta5_dlc/mpPacks/mpBusiness2/build/dev/setup2.xml
FUNC BOOL IS_MP_BUSINESS_2_PACK_PRESENT()
RETURN (IS_DLC_PRESENT(HASH("mpBusiness2")))
ENDFUNC
FUNC BOOL IS_MP_BUSINESS_PACK_PRESENT()
RETURN (IS_DLC_PRESENT(HASH("MPBusiness DLC")))
ENDFUNC
FUNC BOOL IS_MP_VALENTINES_PACK_PRESENT()
RETURN (IS_DLC_PRESENT(HASH("MPValentines DLC")))
ENDFUNC
FUNC BOOL IS_MP_HIPSTER_PACK_PRESENT()
RETURN (IS_DLC_PRESENT(HASH("MPHipster DLC")))
ENDFUNC
FUNC BOOL IS_MP_PILOT_SCHOOL_PACK_PRESENT()
RETURN (IS_DLC_PRESENT(HASH("mpPilot")))
ENDFUNC
FUNC BOOL IS_MP_LTS_PACK_PRESENT()
RETURN (IS_DLC_PRESENT(HASH("mpLTS")))
ENDFUNC
FUNC BOOL IS_MP_INDEPENDENCE_PACK_PRESENT()
RETURN (IS_DLC_PRESENT(HASH("mpIndependence")))
ENDFUNC
#IF FEATURE_SP_DLC_SELECTION
FUNC BOOL IS_DLC_CLF_PRESENT()
RETURN (IS_DLC_PRESENT(HASH("dlc_agentTrevor")))
ENDFUNC
#ENDIF
#IF FEATURE_ARMY
FUNC BOOL IS_MP_ARMY_PACK_PRESENT()
RETURN (IS_DLC_PRESENT(HASH("mpArmy")))
ENDFUNC
#ENDIF
FUNC BOOL IS_MP_CHRISTMAS2_PACK_PRESENT()
RETURN (IS_DLC_PRESENT(HASH("mpChristmas2")))
ENDFUNC
FUNC BOOL IS_MP_HEIST_PACK_PRESENT()
RETURN (IS_DLC_PRESENT(HASH("mpHeist")))
ENDFUNC
FUNC BOOL IS_MP_LUXE_PACK_PRESENT()
RETURN (IS_DLC_PRESENT(HASH("mpLuxe")))
ENDFUNC
FUNC BOOL IS_MP_HALLOWEEN_PACK_PRESENT()
RETURN (IS_DLC_PRESENT(HASH("mpHalloween")))
ENDFUNC
FUNC BOOL IS_MP_LOWRIDER_PACK_PRESENT()
RETURN (IS_DLC_PRESENT(HASH("mpLowrider")))
ENDFUNC
FUNC BOOL IS_MP_LOWRIDER2_PACK_PRESENT()
RETURN (IS_DLC_PRESENT(HASH("mpLowrider2")))
ENDFUNC
FUNC BOOL IS_MP_APARTMENT_PACK_PRESENT()
RETURN (IS_DLC_PRESENT(HASH("mpApartment")))
ENDFUNC
FUNC BOOL IS_MP_VALENTINES_2016_PACK_PRESENT()
//gta5_dlc/mpPacks/mpValentines2/build/dev_ng/setup2.xml
RETURN (IS_DLC_PRESENT(HASH("mpValentines2")))
ENDFUNC
FUNC BOOL IS_MP_JANUARY_2016_PACK_PRESENT()
//gta5_dlc/mpPacks/mpJanuary2016/build/dev_ng/setup2.xml
RETURN (IS_DLC_PRESENT(HASH("mpJanuary2016")))
ENDFUNC
FUNC BOOL IS_MP_EXECUTIVE_PACK_PRESENT()
//gta5_dlc/mpPacks/mpExecutive/build/dev_ng/setup2.xml
RETURN (IS_DLC_PRESENT(HASH("mpExecutive")))
ENDFUNC
FUNC BOOL IS_MP_STUNT_PACK_PRESENT()
//gta5_dlc/mpPacks/mpStunt/build/dev_ng/setup2.xml
RETURN (IS_DLC_PRESENT(HASH("mpStunt")))
ENDFUNC
FUNC BOOL IS_MP_BIKER_PACK_PRESENT()
//gta5_dlc/mpPacks/mpBiker/build/dev_ng/setup2.xml
RETURN (IS_DLC_PRESENT(HASH("mpBiker")))
ENDFUNC
FUNC BOOL IS_MP_IMPORT_EXPORT_PACK_PRESENT()
//gta5_dlc/mpPacks/mpImportExport/build/dev_ng/setup2.xml
RETURN (IS_DLC_PRESENT(HASH("mpImportExport")))
ENDFUNC
FUNC BOOL IS_MP_GUNRUNNING_PACK_PRESENT()
//gta5_dlc/mpPacks/mpGunrunning/build/dev_ng/setup2.xml
RETURN (IS_DLC_PRESENT(HASH("mpGunRunning")))
ENDFUNC
FUNC BOOL IS_MP_SMUGGLER_PACK_PRESENT()
//gta5_dlc/mpPacks/mpSmuggler/build/dev_ng/setup2.xml
RETURN (IS_DLC_PRESENT(HASH("mpSmuggler")))
ENDFUNC
FUNC BOOL IS_MP_CHRISTMAS_2017_PACK_PRESENT()
//gta5_dlc/mpPacks/mpChristmas2017/build/dev_ng/setup2.xml
RETURN (IS_DLC_PRESENT(HASH("mpChristmas2017")))
ENDFUNC
FUNC BOOL IS_MP_ARENA_WARS()
//gta5_dlc/mpPacks/mpChristmas2018/
RETURN (IS_DLC_PRESENT(HASH("mpChristmas2018")))
ENDFUNC
FUNC BOOL IS_MP_SUMMER_2020()
//gta5_dlc/mpPacks/mpSum/
RETURN (IS_DLC_PRESENT(HASH("mpSum")))
ENDFUNC
FUNC BOOL IS_MP_TUNER_PACK_PRESENT()
//gta5_dlc/mpPacks/mpTuner/
RETURN (IS_DLC_PRESENT(HASH("mpTuner")))
ENDFUNC
FUNC BOOL IS_MP_FIXER_PACK_PRESENT()
//gta5_dlc/mpPacks/mpSecurity/
RETURN (IS_DLC_PRESENT(HASH("mpSecurity")))
ENDFUNC
FUNC BOOL IS_MP_SUMMER_2022_PACK_PRESENT()
//gta5_dlc/mpPacks/mpSum2/
RETURN (IS_DLC_PRESENT(HASH("mpSum2")))
ENDFUNC
//EPPT_NONE
//EPPT_STANDALONE
//EPPT_BUNDLED_WITH_GREAT_WHITE
//EPPT_BUNDLED_WITH_WHALE
//EPPT_BUNDLED_WITH_MEGALODON
//Does the player have the premium access, i.e. the product built into the disc?
FUNC BOOL HAS_MP_CRIMINAL_ENTERPRISE_PREMIUM_ACCESS()
#IF IS_DEBUG_BUILD
IF g_bForce_PREMIUM_true
RETURN TRUE
ENDIF
IF g_bForce_PREMIUM_false
RETURN FALSE
ENDIF
#ENDIF
//INFO: Retrieves the type of pack, if any, which grants the user access to the premium pack content
SWITCH GET_USER_PREMIUM_ACCESS()
CASE EPPT_STANDALONE
CASE EPPT_BUNDLED_WITH_GREAT_WHITE
CASE EPPT_BUNDLED_WITH_WHALE
CASE EPPT_BUNDLED_WITH_MEGALODON
RETURN TRUE
ENDSWITCH
RETURN FALSE
ENDFUNC
//Does the player have the starter access, i.e. the product from the store?
FUNC BOOL HAS_MP_CRIMINAL_ENTERPRISE_STARTER_ACCESS()
#IF IS_DEBUG_BUILD
IF g_bForce_STARTER_true
RETURN TRUE
ENDIF
IF g_bForce_STARTER_false
RETURN FALSE
ENDIF
#ENDIF
//INFO: Retrieves the type of pack, if any, which grants the user access to the starter pack content
SWITCH GET_USER_STARTER_ACCESS()
CASE EPPT_STANDALONE
CASE EPPT_BUNDLED_WITH_GREAT_WHITE
CASE EPPT_BUNDLED_WITH_WHALE
CASE EPPT_BUNDLED_WITH_MEGALODON
RETURN TRUE
ENDSWITCH
RETURN FALSE
ENDFUNC
FUNC BOOL HAS_MP_CRIMINAL_ENTERPRISE_PREMIUM_OR_STARTER_ACCESS()
RETURN HAS_MP_CRIMINAL_ENTERPRISE_PREMIUM_ACCESS() OR HAS_MP_CRIMINAL_ENTERPRISE_STARTER_ACCESS()
ENDFUNC
PROC SCRIPT_BLOCK_ACCESS_TO_MULTIPLAYER(BOOL bSet)
#IF IS_DEBUG_BUILD
DEBUG_PRINTCALLSTACK()
IF bSet
PRINTLN("<<<SCRIPT_BLOCK_ACCESS_TO_MULTIPLAYER = TRUE >>> ")
ELSE
PRINTLN("<<<SCRIPT_BLOCK_ACCESS_TO_MULTIPLAYER = FALSE >>> ")
ENDIF
#ENDIF
g_b_ScriptMPBlock = bSet
ENDPROC
FUNC BOOL HAS_SCRIPT_BLOCKED_MULTIPLAYER_ACCESS()
RETURN g_b_ScriptMPBlock
ENDFUNC
FUNC BOOL SCRIPT_NETWORK_CAN_ACCESS_MULTIPLAYER(MULTIPLAYER_ACCESS_CODE& nAccessCode)
IF HAS_SCRIPT_BLOCKED_MULTIPLAYER_ACCESS()
nAccessCode = ACCESS_DENIED_MULTIPLAYER_DISABLED
RETURN TRUE
ENDIF
RETURN NETWORK_CAN_ACCESS_MULTIPLAYER(nAccessCode)
ENDFUNC
FUNC BOOL SYSTEM_IS_MP_AVAILABLE()
IF IS_PLAYSTATION_PLATFORM()
IF NOT NETWORK_IS_NP_AVAILABLE()
IF NETWORK_GET_NP_UNAVAILABLE_REASON() = REASON_AGE
// PRINTLN("SYSTEM_IS_MP_AVAILABLE = FALSE: NETWORK_GET_NP_UNAVAILABLE_REASON() = REASON_AGE")
RETURN FALSE
ENDIF
IF NETWORK_GET_NP_UNAVAILABLE_REASON() = REASON_GAME_UPDATE
// PRINTLN("SYSTEM_IS_MP_AVAILABLE = FALSE: NETWORK_GET_NP_UNAVAILABLE_REASON() = REASON_GAME_UPDATE")
RETURN FALSE
ENDIF
IF NETWORK_GET_NP_UNAVAILABLE_REASON() = REASON_SYSTEM_UPDATE
// PRINTLN("SYSTEM_IS_MP_AVAILABLE = FALSE: NETWORK_GET_NP_UNAVAILABLE_REASON() = REASON_SYSTEM_UPDATE")
RETURN FALSE
ENDIF
IF NETWORK_GET_NP_UNAVAILABLE_REASON() = REASON_CONNECTION
// PRINTLN("SYSTEM_IS_MP_AVAILABLE = FALSE: NETWORK_GET_NP_UNAVAILABLE_REASON() = REASON_SYSTEM_UPDATE")
RETURN FALSE
ENDIF
ENDIF
ENDIF
RETURN TRUE
ENDFUNC
// SP Independence checks - piggy back on free save data bitset
FUNC BOOL IS_INDEPENDENCE_CONTENT_AVAILABLE_IN_SP()
RETURN IS_BIT_SET(g_savedGlobals.sPlayerData.sInfo.iUnlockedCarMods[4], 31)
ENDFUNC
PROC SET_INDEPENDENCE_CONTENT_AVAILABLE_IN_SP()
IF NOT IS_BIT_SET(g_savedGlobals.sPlayerData.sInfo.iUnlockedCarMods[4], 31)
PRINTLN("SET_INDEPENDENCE_CONTENT_AVAILABLE_IN_SP - All items now available")
SET_BIT(g_savedGlobals.sPlayerData.sInfo.iUnlockedCarMods[4], 31)
ENDIF
ENDPROC
FUNC BOOL IS_GTA_ONLINE_AVAILABLE(BOOL SkipCheckingSystemChecks = FALSE)
//Old version to be compiled into SP scripts. They
//don't use this check directly anyway.
#IF NOT USE_TU_CHANGES
MULTIPLAYER_ACCESS_CODE nAccessCode
#if USE_CLF_DLC
IF SCRIPT_NETWORK_CAN_ACCESS_MULTIPLAYER(nAccessCode)
AND g_savedGlobalsClifford.sFlow.missionSavedData[SP_MISSION_CLF_TRAIN].completed
RETURN TRUE
ENDIF
#IF IS_DEBUG_BUILD
IF g_savedGlobalsClifford.sFlow.missionSavedData[SP_MISSION_CLF_TRAIN].completed = FALSE
AND GET_COMMANDLINE_PARAM_EXISTS("sc_noPrologueCheckForMP") = TRUE
RETURN TRUE
ENDIF
#ENDIF
#endif
#if USE_NRM_DLC
IF SCRIPT_NETWORK_CAN_ACCESS_MULTIPLAYER(nAccessCode)
AND g_savedGlobalsnorman.sFlow.missionSavedData[SP_MISSION_NRM_SUR_START].completed
RETURN TRUE
ENDIF
#IF IS_DEBUG_BUILD
IF g_savedGlobalsnorman.sFlow.missionSavedData[SP_MISSION_NRM_SUR_START].completed = FALSE
AND GET_COMMANDLINE_PARAM_EXISTS("sc_noPrologueCheckForMP") = TRUE
RETURN TRUE
ENDIF
#ENDIF
#endif
#if not USE_CLF_DLC
#if not USE_NRM_DLC
IF SCRIPT_NETWORK_CAN_ACCESS_MULTIPLAYER(nAccessCode)
AND g_savedGlobals.sFlow.missionSavedData[SP_MISSION_PROLOGUE].completed
RETURN TRUE
ENDIF
#IF IS_DEBUG_BUILD
IF g_savedGlobals.sFlow.missionSavedData[SP_MISSION_PROLOGUE].completed = FALSE
AND GET_COMMANDLINE_PARAM_EXISTS("sc_noPrologueCheckForMP") = TRUE
RETURN TRUE
ENDIF
#ENDIF
#endif
#endif
#ENDIF
// [AG] - This does nothing but it stops an unreference variable compiler error in clifford
IF (SkipCheckingSystemChecks = TRUE)
ENDIF
//New version for all other scripts.
#IF USE_TU_CHANGES
MULTIPLAYER_ACCESS_CODE nAccessCode
IF SkipCheckingSystemChecks = FALSE
IF SYSTEM_IS_MP_AVAILABLE() = FALSE
RETURN FALSE
ENDIF
ENDIF
IF SCRIPT_NETWORK_CAN_ACCESS_MULTIPLAYER(nAccessCode)
#IF NOT FEATURE_GEN9_STANDALONE
AND GET_PROFILE_SETTING(PROLOGUE_COMPLETE) = 1
#ENDIF
RETURN TRUE
ENDIF
IF NOT SCRIPT_NETWORK_CAN_ACCESS_MULTIPLAYER(nAccessCode)
IF nAccessCode = ACCESS_DENIED_NOT_SIGNED_IN
// display alert, show sign in ui
RETURN TRUE
ELIF nAccessCode = ACCESS_DENIED_NOT_SIGNED_ONLINE
// display alert, show sign in ui
RETURN TRUE
ELIF nAccessCode = ACCESS_DENIED_NO_ONLINE_PRIVILEGE
// display alert
RETURN TRUE
ELIF nAccessCode = ACCESS_DENIED_NO_SCS_PRIVILEGE
// display alert
RETURN TRUE
ELIF nAccessCode = ACCESS_DENIED_NO_TUNABLES
// display alert
RETURN TRUE
ELIF nAccessCode = ACCESS_DENIED_NO_BACKGROUND_SCRIPT
// display alert
RETURN TRUE
ELIF nAccessCode = ACCESS_DENIED_MULTIPLAYER_DISABLED
RETURN TRUE
ENDIF
ENDIF
#IF IS_DEBUG_BUILD
IF GET_COMMANDLINE_PARAM_EXISTS("sc_noPrologueCheckForMP") = TRUE
RETURN TRUE
ENDIF
#ENDIF
#ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL IS_LAST_GEN_PLAYER()
#IF IS_DEBUG_BUILD
IF g_bForce_IS_LAST_GEN_PLAYER_true
RETURN TRUE
ENDIF
IF g_bForce_IS_LAST_GEN_PLAYER_false
RETURN FALSE
ENDIF
#ENDIF
//Debug override.
#IF IS_DEBUG_BUILD
IF g_bLastGenPlayer
OR GET_COMMANDLINE_PARAM_EXISTS("sc_isLastGenPlayer")
RETURN TRUE
ENDIF
#ENDIF
//MP stat migration local result.
#IF USE_TU_CHANGES
//this is set if the player has last gen
IF g_i_Private_IsPlayerFromLastGen = LAST_GEN_STATUS_IS_LAST_GEN
RETURN TRUE
ELIF g_i_Private_IsPlayerFromLastGen = LAST_GEN_STATUS_IS_NOT_LAST_GEN
RETURN FALSE
ENDIF
#ENDIF
//SCAdmin automatic awarding of content.
IF NETWORK_IS_SIGNED_IN()
IF NETWORK_HAS_VALID_ROS_CREDENTIALS()
IF NETWORK_HAS_ROS_PRIVILEGE_PLAYED_LAST_GEN()
CPRINTLN(DEBUG_LASTGEN, "[LASTGEN] SCAdmin has remotely awarded this player last-gen status.")
#IF USE_FINAL_PRINTS
PRINTLN_FINAL("[LASTGEN] SCAdmin has remotely awarded this player last-gen status.")
#ENDIF
INT iCurrentSpecialContentBitset
STAT_GET_INT(SP_UNLOCK_EXCLUS_CONTENT, iCurrentSpecialContentBitset)
SET_BIT(iCurrentSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_PS3_SPECIAL)
SET_BIT(iCurrentSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_360_SPECIAL)
SET_BIT(iCurrentSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_STAT_STORED_SPECIAL)
SET_BIT(g_iPlayerHasLastGenSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_PS3_SPECIAL)
SET_BIT(g_iPlayerHasLastGenSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_360_SPECIAL)
SET_BIT(g_iPlayerHasLastGenSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_STAT_STORED_SPECIAL)
STAT_SET_INT(SP_UNLOCK_EXCLUS_CONTENT, iCurrentSpecialContentBitset)
CPRINTLN(DEBUG_LASTGEN, "[LASTGEN] SCAdmin has remotely awarded this player last-gen status. SP_UNLOCK_EXCLUS_CONTENT setting all Special bits ", iCurrentSpecialContentBitset, " ")
#IF USE_FINAL_PRINTS
PRINTLN_FINAL("[LASTGEN] SCAdmin has remotely awarded this player last-gen status. SP_UNLOCK_EXCLUS_CONTENT setting all Special bits ", iCurrentSpecialContentBitset, " ")
#ENDIF
// Try and write this out to profile settings to make this change permanent.
IF ARE_PROFILE_SETTINGS_VALID()
iCurrentSpecialContentBitset = GET_PROFILE_SETTING(GAMER_HAS_SPECIALEDITION_CONTENT)
SET_BIT(iCurrentSpecialContentBitset, BIT_IS_LAST_GEN)
SET_HAS_SPECIALEDITION_CONTENT(iCurrentSpecialContentBitset)
CPRINTLN(DEBUG_LASTGEN, "Sucessfully wrote SCAdmin last-gen status to profile settings.")
#IF USE_FINAL_PRINTS
PRINTLN_FINAL("[LASTGEN] Sucessfully wrote SCAdmin last-gen status to profile settings.")
#ENDIF
ENDIF
RETURN TRUE
ENDIF
ENDIF
ENDIF
//Stat migration cached result in console profile.
IF ARE_PROFILE_SETTINGS_VALID()
IF IS_BIT_SET(GET_PROFILE_SETTING(GAMER_HAS_SPECIALEDITION_CONTENT), BIT_IS_LAST_GEN)
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL IS_GEN_8_PLAYER()
#IF IS_DEBUG_BUILD
IF GET_COMMANDLINE_PARAM_EXISTS("sc_IsGen8Player")
RETURN TRUE
ENDIF
#ENDIF
RETURN SAVEMIGRATION_MP_IS_PLATFORM_GENERATION(SAVEMIGRATION_PLATFORM_GEN8)
ENDFUNC
FUNC BOOL IS_LAST_GEN_GTAO_CHARACTERS()
#IF IS_DEBUG_BUILD
IF GET_COMMANDLINE_PARAM_EXISTS("sc_isLastGenGTAOCharacters")
RETURN TRUE
ENDIF
#ENDIF
#IF USE_TU_CHANGES
IF g_i_Private_AreCharactersLastGen = LAST_GEN_STATUS_IS_LAST_GEN
RETURN TRUE
ENDIF
#ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL IS_SPECIAL_EDITION_GAME()
// TODO 2104695: SE content unlocked for all players in both SP and MP (Japanese build too). However any
// of this content that is unlocked through shops will cost $0 if HAS_LAST_GEN_PLAYER_GOT_SPECIAL_EDITION()
// is TRUE or some in game money if not.
RETURN TRUE
ENDFUNC
FUNC BOOL IS_COLLECTORS_EDITION_GAME()
// TODO 2104695: CE content unlocked for all players in both SP and MP (Japanese build too). However any
// of this content that is unlocked through shops will cost $0 if HAS_LAST_GEN_PLAYER_GOT_COLLECTORS_EDITION()
// is TRUE or some in game money if not.
RETURN TRUE
ENDFUNC
FUNC BOOL HAS_LAST_GEN_PLAYER_GOT_SPECIAL_EDITION()
//Debug override.
#IF IS_DEBUG_BUILD
IF g_bLastGenSpecialEditionPlayer
RETURN TRUE
ENDIF
#ENDIF
//SP local result.
IF IS_BIT_SET(g_iPlayerHasLastGenSpecialContentBitset,BIT_LAST_GEN_SPECIAL_CONTENT_STAT_STORED_SPECIAL)
IF IS_BIT_SET(g_iPlayerHasLastGenSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_PS3_SPECIAL)
OR IS_BIT_SET(g_iPlayerHasLastGenSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_360_SPECIAL)
#IF IS_DEBUG_BUILD
IF IS_BIT_SET(g_iPlayerHasLastGenSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_PS3_SPECIAL)
CPRINTLN(DEBUG_LASTGEN, "[LASTGEN] HAS_LAST_GEN_PLAYER_GOT_SPECIAL_EDITION = TRUE global PS3_SPECIAL due to new SP_UNLOCK_EXCLUS_CONTENT = ", g_iPlayerHasLastGenSpecialContentBitset, " ")
ENDIF
IF IS_BIT_SET(g_iPlayerHasLastGenSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_360_SPECIAL)
CPRINTLN(DEBUG_LASTGEN, "[LASTGEN] HAS_LAST_GEN_PLAYER_GOT_SPECIAL_EDITION = TRUE global 360_SPECIAL due to new SP_UNLOCK_EXCLUS_CONTENT = ", g_iPlayerHasLastGenSpecialContentBitset, " ")
ENDIF
#ENDIF
RETURN TRUE
ELSE
CPRINTLN(DEBUG_LASTGEN, "[LASTGEN] HAS_LAST_GEN_PLAYER_GOT_SPECIAL_EDITION = FALSE global due to new SP_UNLOCK_EXCLUS_CONTENT = ", g_iPlayerHasLastGenSpecialContentBitset, " ")
RETURN FALSE
ENDIF
ENDIF
INT iStatSpecialContentBitset
IF STAT_GET_INT(SP_UNLOCK_EXCLUS_CONTENT, iStatSpecialContentBitset)
IF IS_BIT_SET(iStatSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_STAT_STORED_SPECIAL)
IF IS_BIT_SET(iStatSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_PS3_SPECIAL)
OR IS_BIT_SET(iStatSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_360_SPECIAL)
#IF IS_DEBUG_BUILD
IF IS_BIT_SET(iStatSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_PS3_SPECIAL)
CPRINTLN(DEBUG_LASTGEN, "HAS_LAST_GEN_PLAYER_GOT_SPECIAL_EDITION = TRUE PS3_SPECIAL due to new SP_UNLOCK_EXCLUS_CONTENT = ", iStatSpecialContentBitset, " ")
ENDIF
IF IS_BIT_SET(iStatSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_360_SPECIAL)
CPRINTLN(DEBUG_LASTGEN, "HAS_LAST_GEN_PLAYER_GOT_SPECIAL_EDITION = TRUE 360_SPECIAL due to new SP_UNLOCK_EXCLUS_CONTENT = ", iStatSpecialContentBitset, " ")
ENDIF
#ENDIF
RETURN TRUE
ELSE
CPRINTLN(DEBUG_LASTGEN, "HAS_LAST_GEN_PLAYER_GOT_SPECIAL_EDITION = FALSE due to new SP_UNLOCK_EXCLUS_CONTENT = ", iStatSpecialContentBitset, " ")
//Don't go on to check the profile settings.
RETURN FALSE
ENDIF
ENDIF
ENDIF
//MP stats saved result.
IF STAT_SLOT_IS_LOADED(0)
IF platformUpgradeLBCheck.bComplete
INT iStatValue
STATSENUM MainstatBody = INT_TO_ENUM(STATSENUM, MPPLY_PLAT_UP_LB_CHECK)
IF STAT_GET_INT(MainstatBody, iStatValue)
IF IS_BIT_SET(iStatValue, ENUM_TO_INT(PLATFORM_UPGRADE_LB_HAS_SPECIAL))
RETURN TRUE
ENDIF
ENDIF
ENDIF
ENDIF
//Profile settings saved result.
IF ARE_PROFILE_SETTINGS_VALID()
INT iProfileSpecialContentBitset = GET_PROFILE_SETTING(GAMER_HAS_SPECIALEDITION_CONTENT)
IF IS_BIT_SET(iProfileSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_PS3_SPECIAL)
OR IS_BIT_SET(iProfileSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_360_SPECIAL)
RETURN TRUE
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL HAS_LAST_GEN_PLAYER_GOT_COLLECTORS_EDITION()
//Debug override.
#IF IS_DEBUG_BUILD
IF g_bLastGenCollectorEditionPlayer
RETURN TRUE
ENDIF
#ENDIF
//SP local result.
IF IS_BIT_SET(g_iPlayerHasLastGenSpecialContentBitset,BIT_LAST_GEN_SPECIAL_CONTENT_STAT_STORED_COLLECTOR)
IF IS_BIT_SET(g_iPlayerHasLastGenSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_PS3_COLLECTORS)
OR IS_BIT_SET(g_iPlayerHasLastGenSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_360_COLLECTORS)
#IF IS_DEBUG_BUILD
IF IS_BIT_SET(g_iPlayerHasLastGenSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_PS3_COLLECTORS)
CPRINTLN(DEBUG_LASTGEN, "[LASTGEN] HAS_LAST_GEN_PLAYER_GOT_COLLECTORS_EDITION = TRUE global PS3_COLLECTORS due to new SP_UNLOCK_EXCLUS_CONTENT = ", g_iPlayerHasLastGenSpecialContentBitset, " ")
ENDIF
IF IS_BIT_SET(g_iPlayerHasLastGenSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_360_COLLECTORS)
CPRINTLN(DEBUG_LASTGEN, "[LASTGEN] HAS_LAST_GEN_PLAYER_GOT_COLLECTORS_EDITION = TRUE global 360_COLLECTORS due to new SP_UNLOCK_EXCLUS_CONTENT = ", g_iPlayerHasLastGenSpecialContentBitset, " ")
ENDIF
#ENDIF
RETURN TRUE
ELSE
CPRINTLN(DEBUG_LASTGEN, "[LASTGEN] HAS_LAST_GEN_PLAYER_GOT_COLLECTORS_EDITION = FALSE global due to new SP_UNLOCK_EXCLUS_CONTENT = ", g_iPlayerHasLastGenSpecialContentBitset, " ")
RETURN FALSE
ENDIF
ENDIF
INT iStatSpecialContentBitset
IF STAT_GET_INT(SP_UNLOCK_EXCLUS_CONTENT, iStatSpecialContentBitset)
IF IS_BIT_SET(iStatSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_STAT_STORED_COLLECTOR)
IF IS_BIT_SET(iStatSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_PS3_COLLECTORS)
OR IS_BIT_SET(iStatSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_360_COLLECTORS)
#IF IS_DEBUG_BUILD
IF IS_BIT_SET(iStatSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_PS3_COLLECTORS)
CPRINTLN(DEBUG_LASTGEN, "[LASTGEN] HAS_LAST_GEN_PLAYER_GOT_COLLECTORS_EDITION = TRUE PS3_COLLECTORS due to new SP_UNLOCK_EXCLUS_CONTENT = ", iStatSpecialContentBitset, " ")
ENDIF
IF IS_BIT_SET(iStatSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_360_COLLECTORS)
CPRINTLN(DEBUG_LASTGEN, "[LASTGEN] HAS_LAST_GEN_PLAYER_GOT_COLLECTORS_EDITION = TRUE 360_COLLECTORS due to new SP_UNLOCK_EXCLUS_CONTENT = ", iStatSpecialContentBitset, " ")
ENDIF
#ENDIF
RETURN TRUE
ELSE
CPRINTLN(DEBUG_LASTGEN, "HAS_LAST_GEN_PLAYER_GOT_COLLECTORS_EDITION = FALSE due to new SP_UNLOCK_EXCLUS_CONTENT = ", iStatSpecialContentBitset, " ")
//Don't go on to check the profile settings.
RETURN FALSE
ENDIF
ENDIF
ENDIF
//MP stats saved result.
IF STAT_SLOT_IS_LOADED(0)
IF platformUpgradeLBCheck.bComplete
INT iStatValue
STATSENUM MainstatBody = INT_TO_ENUM(STATSENUM, MPPLY_PLAT_UP_LB_CHECK)
IF STAT_GET_INT(MainstatBody, iStatValue)
IF IS_BIT_SET(iStatValue, ENUM_TO_INT(PLATFORM_UPGRADE_LB_HAS_COLLECT))
RETURN TRUE
ENDIF
ENDIF
ENDIF
ENDIF
//Profile settings saved result.
IF ARE_PROFILE_SETTINGS_VALID()
INT iProfileSpecialContentBitset = GET_PROFILE_SETTING(GAMER_HAS_SPECIALEDITION_CONTENT)
IF IS_BIT_SET(iProfileSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_PS3_COLLECTORS)
OR IS_BIT_SET(iProfileSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_360_COLLECTORS)
RETURN TRUE
ENDIF
ENDIF
//SCAdmin automatic awarding of content. The ROS command doesn't detemine special or collector's
//edition so we award collector's as it includes a tiny bit more content.
IF NETWORK_IS_SIGNED_IN()
IF NETWORK_HAS_VALID_ROS_CREDENTIALS()
IF NETWORK_HAS_ROS_PRIVILEGE_SPECIAL_EDITION_CONTENT()
CPRINTLN(DEBUG_LASTGEN, "[LASTGEN] SCAdmin has remotely awarded this player last-gen collector's edition.")
#IF USE_FINAL_PRINTS
PRINTLN_FINAL("[LASTGEN] SCAdmin has remotely awarded this player last-gen collector's edition.")
#ENDIF
INT iCurrentSpecialContentBitset
STAT_GET_INT(SP_UNLOCK_EXCLUS_CONTENT, iCurrentSpecialContentBitset)
SET_BIT(iCurrentSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_PS3_COLLECTORS)
SET_BIT(iCurrentSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_360_COLLECTORS)
SET_BIT(iCurrentSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_STAT_STORED_COLLECTOR)
SET_BIT(g_iPlayerHasLastGenSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_PS3_COLLECTORS)
SET_BIT(g_iPlayerHasLastGenSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_360_COLLECTORS)
SET_BIT(g_iPlayerHasLastGenSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_STAT_STORED_COLLECTOR)
STAT_SET_INT(SP_UNLOCK_EXCLUS_CONTENT, iCurrentSpecialContentBitset)
CPRINTLN(DEBUG_LASTGEN, "[LASTGEN] SCAdmin has remotely awarded this player last-gen collector's edition.. SP_UNLOCK_EXCLUS_CONTENT setting all Special bits ", iCurrentSpecialContentBitset, " ")
#IF USE_FINAL_PRINTS
PRINTLN_FINAL("[LASTGEN] SCAdmin has remotely awarded this player last-gen collector's edition.. SP_UNLOCK_EXCLUS_CONTENT setting all Special bits ", iCurrentSpecialContentBitset, " ")
#ENDIF
// Try and write this out to profile settings to make this change permanent.
IF ARE_PROFILE_SETTINGS_VALID()
iCurrentSpecialContentBitset = GET_PROFILE_SETTING(GAMER_HAS_SPECIALEDITION_CONTENT)
SET_BIT(iCurrentSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_PS3_COLLECTORS)
SET_BIT(iCurrentSpecialContentBitset, BIT_LAST_GEN_SPECIAL_CONTENT_360_COLLECTORS)
SET_HAS_SPECIALEDITION_CONTENT(iCurrentSpecialContentBitset)
CPRINTLN(DEBUG_LASTGEN, "[LASTGEN] Sucessfully wrote SCAdmin last-gen collector's edition to profile settings.")
#IF USE_FINAL_PRINTS
PRINTLN_FINAL("[LASTGEN] Sucessfully wrote SCAdmin last-gen collector's edition to profile settings.")
#ENDIF
ENDIF
RETURN TRUE
ENDIF
ENDIF
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL IS_PREORDER_GAME()
#IF IS_DEBUG_BUILD
IF g_bPreorderGame
RETURN TRUE
ENDIF
#ENDIF
IF IS_DLC_PRESENT(HASH("dlc_atomicblimp"))
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL IS_NEXT_GEN_PREORDER_GAME()
#IF IS_DEBUG_BUILD
IF g_bPreorderGameNextGen
OR GET_COMMANDLINE_PARAM_EXISTS("isPreorderPlayerNG")
RETURN TRUE
ENDIF
#ENDIF
IF IS_DLC_PRESENT(HASH("spPreorder")) // Pack name taken from TODO 2021487.
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL IS_JAPANESE_SPECIAL_EDITION_GAME()
#IF IS_JAPANESE_BUILD
RETURN TRUE
#ENDIF
#IF NOT IS_JAPANESE_BUILD
RETURN FALSE
#ENDIF
ENDFUNC
FUNC BOOL IS_GAME_LINKED_TO_SOCIAL_CLUB(BOOL bCheckForPreviousLink = FALSE, BOOL bCheckForOnlinePrivileges = FALSE)
IF bCheckForPreviousLink
#if USE_CLF_DLC
IF IS_BIT_SET(g_savedGlobalsClifford.sShopData.iContentChecks_Game, NCU_SOCIAL_CLUB)
RETURN TRUE
ENDIF
#endif
#if not USE_CLF_DLC
IF IS_BIT_SET(g_savedGlobals.sShopData.iContentChecks_Game, NCU_SOCIAL_CLUB)
RETURN TRUE
ENDIF
#endif
ENDIF
#IF USE_TU_CHANGES
IF NETWORK_HAS_SOCIAL_CLUB_ACCOUNT()
IF NOT bCheckForOnlinePrivileges OR NETWORK_IS_SIGNED_ONLINE()
IF NOT IS_PS3_VERSION() AND NOT IS_PLAYSTATION_PLATFORM()
RETURN TRUE
ENDIF
ENDIF
ENDIF
#ENDIF
IF bCheckForOnlinePrivileges
IF NETWORK_HAS_AGE_RESTRICTIONS()
RETURN FALSE
ENDIF
ENDIF
IF NETWORK_HAS_SOCIAL_CLUB_ACCOUNT()
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE: Requests a particular model to be suppressed for a given time, default time is 1 minute
PROC SET_MODEL_IS_SUPPRESSED_FOR_DURATION(MODEL_NAMES eModel, BOOL bVehicle, BOOL bSuppressed, INT iTimeMS = 60000)
BOOL bStateUpdated = FALSE
INT i
REPEAT COUNT_OF(g_eAmbientModelSuppress) i
IF bSuppressed
// Not set
IF g_eAmbientModelSuppress[i] = DUMMY_MODEL_FOR_SCRIPT AND NOT bStateUpdated
g_eAmbientModelSuppress[i] = eModel
g_bAmbientModelSuppressVehicle[i] = bVehicle
g_iAmbientModelSuppressTimer[i] = GET_GAME_TIMER()+iTimeMS
g_bAmbientModelSuppressActive = TRUE
bStateUpdated = TRUE
#IF IS_DEBUG_BUILD
PRINTLN("SET_MODEL_IS_SUPPRESSED_FOR_DURATION - Suppressing model ", GET_MODEL_NAME_FOR_DEBUG(g_eAmbientModelSuppress[i]))
#ENDIF
// Already set
ELIF g_eAmbientModelSuppress[i] = eModel
g_eAmbientModelSuppress[i] = eModel
g_bAmbientModelSuppressVehicle[i] = bVehicle
g_iAmbientModelSuppressTimer[i] = GET_GAME_TIMER()+iTimeMS
g_bAmbientModelSuppressActive = TRUE
bStateUpdated = TRUE
ENDIF
ELSE
// Clear
IF g_eAmbientModelSuppress[i] = eModel
g_eAmbientModelSuppress[i] = DUMMY_MODEL_FOR_SCRIPT
bStateUpdated = TRUE
#IF IS_DEBUG_BUILD
PRINTLN("SET_MODEL_IS_SUPPRESSED_FOR_DURATION - No longer suppressing model ", GET_MODEL_NAME_FOR_DEBUG(eModel))
#ENDIF
ENDIF
ENDIF
ENDREPEAT
IF bStateUpdated
IF bVehicle
SET_VEHICLE_MODEL_IS_SUPPRESSED(eModel, bSuppressed)
ELSE
SET_PED_MODEL_IS_SUPPRESSED(eModel, bSuppressed)
ENDIF
ELSE
IF bSuppressed
#IF IS_DEBUG_BUILD
SCRIPT_ASSERT("SET_MODEL_IS_SUPPRESSED_FOR_DURATION - Already suppressing 10 models, update count")
#ENDIF
ENDIF
ENDIF
ENDPROC
// PURPOSE: Rounds a screen X or Y coord to the nearest pixel. Useful for avoiding
// visualised rounding errors when drawing moving HUD elements.
FUNC FLOAT ROUND_SCREEN_COORD_TO_NEAREST_PIXEL(FLOAT fScreenCoord, BOOL bXCoord)
//Get screen resolution.
INT iScreenX
INT iScreenY
GET_SCREEN_RESOLUTION(iScreenX,iScreenY)
//Get pixel increments as a ratio of the screen height/width.
FLOAT fIncrement
IF bXCoord
fIncrement = 1.0/TO_FLOAT(iScreenX)
ELSE
fIncrement = 1.0/TO_FLOAT(iScreenY)
ENDIF
//Round to nearest increment and return.
RETURN (fScreenCoord - (fScreenCoord % fIncrement))
ENDFUNC
//INFO: This seems a little strange but the compiler doesnt like
// if ped_index = entity_index
//PARAM NOTES:
//PURPOSE: If you need to compare a ped, object or vehicle index against an entity index you will need to convert it. More Info..
FUNC ENTITY_INDEX CONVERT_TO_ENTITY_INDEX (ENTITY_INDEX EntIndex)
RETURN INT_TO_NATIVE ( ENTITY_INDEX, NATIVE_TO_INT (EntIndex))
ENDFUNC
/// PURPOSE:
/// Estimates the time position in a recording that would place the car closest to a given coord. The more iterations specified, the more accurate the result.
/// @author - Alan L
FUNC FLOAT GET_CLOSEST_TIME_POSITION_IN_RECORDING_TO_POINT(VECTOR vPoint, INT iRecordingNumber, STRING sRecordingName = NULL, INT iIterations = 10)
RECORDING_ID recordingID = GET_VEHICLE_RECORDING_ID(iRecordingNumber, sRecordingName)
FLOAT fRecordingDuration = GET_TOTAL_DURATION_OF_VEHICLE_RECORDING_ID(recordingID)
FLOAT fSeek = fRecordingDuration / 2.0
FLOAT fRange = fRecordingDuration / 2.0
INT i
FOR i = 0 TO iIterations
IF (VDIST2(vPoint, GET_POSITION_OF_VEHICLE_RECORDING_ID_AT_TIME(recordingID, CLAMP(fSeek - fRange, 0.0, fRecordingDuration)))
< VDIST2(vPoint, GET_POSITION_OF_VEHICLE_RECORDING_ID_AT_TIME(recordingID, CLAMP(fSeek + fRange, 0.0, fRecordingDuration))))
fRange /= 2.0
fSeek -= fRange
ENDIF
IF (VDIST2(vPoint, GET_POSITION_OF_VEHICLE_RECORDING_ID_AT_TIME(recordingID, CLAMP(fSeek - fRange, 0.0, fRecordingDuration)))
> VDIST2(vPoint, GET_POSITION_OF_VEHICLE_RECORDING_ID_AT_TIME(recordingID, CLAMP(fSeek + fRange, 0.0, fRecordingDuration))))
fRange /= 2.0
fSeek += fRange
ENDIF
ENDFOR
RETURN fSeek
ENDFUNC
func bool is_timer_met(int &start_time, int time)
int current_time
current_time = get_game_timer()
if ((current_time - start_time) > time)
return true
endif
return false
endfunc
func bool is_player_zooming_with_sniper_rifle()
weapon_type player_weapon
if get_current_ped_weapon(player_ped_id(), player_weapon)
if get_weapontype_group(player_weapon) = weapongroup_sniper
if is_first_person_aim_cam_active()
// or is_player_free_aiming(player_id())
// or (get_script_task_status(player_ped_id(), script_task_aim_gun_scripted) = performing_task)
// or (get_script_task_status(player_ped_id(), script_task_aim_gun_at_coord) = performing_task)
// or (get_script_task_status(player_ped_id(), script_task_aim_gun_at_entity) = performing_task)
if get_allow_movement_while_zoomed()
#if is_debug_build
printstring("aiming with NEW zoom aim controls")
printnl()
#endif
if is_control_pressed(player_control, input_sniper_zoom_in_secondary)
or is_control_pressed(player_control, input_sniper_zoom_out_secondary)
#if is_debug_build
printstring("zooming active")
printnl()
#endif
return true
endif
else
#if is_debug_build
printstring("aiming with OLD zoom aim controls")
printnl()
#endif
if is_control_pressed(player_control, input_sniper_zoom)
or is_control_pressed(player_control, input_sniper_zoom_in_only)
or is_control_pressed(player_control, input_sniper_zoom_out_only)
#if is_debug_build
printstring("zooming active")
printnl()
#endif
return true
endif
endif
endif
endif
endif
return false
endfunc
/// PURPOSE: renders help text for the new sniper rifle zoom controls. The system will print the help once there
/// is no other help text rendering. It will cleanup the help text the frame the player begins to aim
/// with the sniper rifle.
///
/// PARAMS:
/// sniper_rifle_controls_help_text_system_status - pass this into the function. Make sure you initialise it to 0 when the mission starts or you perform a z skip etc
/// zoom_time - the caches the game time the first frame the function is called
/// allow_d_pad_zoom_help_text - controls the d pad help text from rendering. NEW SYSTEM
/// allow_r_stick_zoom_help_text - controls the r pad help text from renderin. OLD SYSTEM
/// start_time_of_help_text - the time you want the help text to render from. e.g. 15s from the frame the functions is called.
proc sniper_rifle_controls_help_text_system(int &sniper_rifle_controls_help_text_system_status, int &zoom_time, bool allow_d_pad_zoom_help_text = true, bool allow_r_stick_zoom_help_text = false, int start_time_of_help_text = 15000)
switch sniper_rifle_controls_help_text_system_status
case 0
zoom_time = get_game_timer()
sniper_rifle_controls_help_text_system_status++
break
case 1
if not is_player_zooming_with_sniper_rifle()
if is_timer_met(zoom_time, start_time_of_help_text)
if not is_help_message_being_displayed()
if get_allow_movement_while_zoomed()
if allow_d_pad_zoom_help_text
print_help("SNIPE_HLP0")
endif
sniper_rifle_controls_help_text_system_status++
else
if allow_r_stick_zoom_help_text
print_help("SNIPE_HLP1")
endif
sniper_rifle_controls_help_text_system_status++
endif
endif
endif
else
sniper_rifle_controls_help_text_system_status = 3
endif
break
case 2
if is_player_zooming_with_sniper_rifle()
if is_this_help_message_being_displayed("SNIPE_HLP0")
clear_help()
elif is_this_help_message_being_displayed("SNIPE_HLP1")
clear_help()
endif
sniper_rifle_controls_help_text_system_status++
endif
break
case 3
break
endswitch
endproc
PROC Pad_Plate_To_8_Characters(TEXT_LABEL & tl)
INT iL1 = GET_LENGTH_OF_LITERAL_STRING(tl)
if (iL1 < 8)
TEXT_LABEL_15 tlTemp, tlTemp2
tlTemp = tl
INT i, iDif = ABSI(8 - iL1)
REPEAT iDif/2 i
tlTemp2 = " "
tlTemp2 += tlTemp
tlTemp2 += " "
tlTemp =tlTemp2
ENDREPEAT
IF iDif % 2 = 1
tlTemp += " "
ENDIF
tl = tlTemp
ENDIF
ENDPROC
func bool Are_Plates_Equal(TEXT_LABEL_15 tl1, TEXT_LABEL_15 tl2)
INT iL1 = GET_LENGTH_OF_LITERAL_STRING(tl1)
INT iL2 = GET_LENGTH_OF_LITERAL_STRING(tl2)
//Just compare equal length strings
IF il1 = il2
RETURN ARE_STRINGS_EQUAL(tl1,tl2)
ENDIF
INT i, iDif = ABSI(iL2 - iL1)
TEXT_LABEL_15 tlTemp, tlTemp2
IF il1<il2 //pad the 1st TL until they're equal
tlTemp = tl1
ELSE
tlTemp = tl2
ENDIF
REPEAT iDif/2 i
tlTemp2 = " "
tlTemp2 += tlTemp
tlTemp2 += " "
tlTemp =tlTemp2
ENDREPEAT
IF iDif % 2 = 1
tlTemp += " "
ENDIF
//Compare the padded string with the original one
IF il1<il2
RETURN ARE_STRINGS_EQUAL(tltemp,tl2)
ELSE
RETURN ARE_STRINGS_EQUAL(tlTemp, tl1)
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL IS_WEATHER_SAFE_FOR_SP()
INT iPrevWeather, iNextWeather
FLOAT fInterp
GET_CURR_WEATHER_STATE(iPrevWeather, iNextWeather, fInterp)
SWITCH iPrevWeather
CASE HASH("SNOW")
CASE HASH("SNOWLIGHT")
CASE HASH("NEUTRAL")
CASE HASH("BLIZZARD")
//CASE HASH("UNDERWATER_DEEP") Can be on in SP if the player is very deep underwater. May occur with quicksave?
RETURN FALSE
BREAK
ENDSWITCH
SWITCH iNextWeather
CASE HASH("SNOW")
CASE HASH("SNOWLIGHT")
CASE HASH("NEUTRAL")
CASE HASH("BLIZZARD")
//CASE HASH("UNDERWATER_DEEP")
RETURN FALSE
BREAK
ENDSWITCH
RETURN TRUE
ENDFUNC
/// PURPOSE:
/// Sets the multihead blinders on safely (with PC checks and logging)
/// PARAMS:
/// bEnable - TRUE for activating, FALSE for deactivating
/// bInstant - Instant on
/// bExtraCheck - Add extra boolean checks here - ex: has_this_script_activated_blinders()
/// RETURNS:
/// TRUE if the desired change has been applied, false otherwise
FUNC BOOL SET_MULTIHEAD_SAFE(BOOL bEnable, BOOL bInstant = FALSE, BOOL bExtraCheck = TRUE, BOOL bFullscreenMovie = FALSE)
BOOL bReturn=FALSE
IF IS_PC_VERSION()
IF (IS_MULTIHEAD_FADE_UP() <> bEnable)
AND bExtraCheck
SET_CUTSCENE_MULTIHEAD_FADE(bEnable,bInstant,TRUE,bFullscreenMovie)
bReturn = TRUE
CDEBUG1LN(debug_system,"Multihead blinders set to ",bEnable, " by ", GET_THIS_SCRIPT_NAME())
ENDIF
ENDIF
RETURN bReturn
ENDFUNC
/// PURPOSE:
/// Sets the acievement progress ony if it's higher than the previous. Used for XBone and Steam achievements
/// PARAMS:
/// AchId - INT value of the achievement (ENUM_TO_INT(ACH10))
/// Prog - INT value for progress
/// RETURNS:
/// The value of SET_ACHIEVEMENT_PROGRESS if the new value can be set, FALSE otherwise
FUNC BOOL SET_ACHIEVEMENT_PROGRESS_SAFE(INT AchId, INT Prog)
IF AchID < 0
CASSERTLN(DEBUG_ACHIEVEMENT,"Tried setting a negative achievement ID (",AchID," ",Prog,"), send to Dan H")
RETURN FALSE
ENDIF
IF AchID > ENUM_TO_INT(ACHIEVEMENT_COUNT)
CASSERTLN(DEBUG_ACHIEVEMENT,"Tried setting a negative achievement ID (",AchID," ",Prog,"), send to Dan H")
RETURN FALSE
ENDIF
IF Prog <= 0 OR Prog >100
CPRINTLN(DEBUG_ACHIEVEMENT,"Attempted to set an invalid progress (",Prog,") for achievement ",AchID)
RETURN FALSE
ENDIF
INT iCurrent = GET_ACHIEVEMENT_PROGRESS(AchID)
//Only set the new value if it's higher than the old one.
IF Prog > iCurrent
CPRINTLN(DEBUG_ACHIEVEMENT,"Setting new achievement progress for ID ",AchID," from ",iCurrent," to ",Prog)
RETURN SET_ACHIEVEMENT_PROGRESS(AchID,Prog)
ELSE
CPRINTLN(DEBUG_ACHIEVEMENT,"Didn't set a new achievement progress for ID ",AchID,": current: ",iCurrent," higher than: ",Prog)
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Gets if is a PC version, if yes, get if City Density option for PC users is set to full
/// Allows random events/chars to load which would hve been blocked on consoles due to memory constraints
/// RETURNS:
/// BOOL Yes or No
FUNC BOOL IS_HIGH_MEMORY_PC()
IF IS_PC_VERSION()
IF GET_CITY_DENSITY() = 1.0
CPRINTLN(DEBUG_GOLF,"Return TRUE, GET_CITY_DENSITY() = ",GET_CITY_DENSITY())
RETURN TRUE
ENDIF
CPRINTLN(DEBUG_GOLF,"Return FALSE, GET_CITY_DENSITY() = ",GET_CITY_DENSITY())
ENDIF
RETURN FALSE
ENDFUNC
///NOTE: If a recording is in progress then we must give player functionality to stop.
PROC DISABLE_REPLAY_RECORDING_UI_THIS_FRAME()
#IF USE_REPLAY_RECORDING_TRIGGERS
#IF IS_DEBUG_BUILD
IF IS_STRING_NULL_OR_EMPTY(g_sSelectorUI.tlDisableReplayFeedScript)
OR NOT ARE_STRINGS_EQUAL(GET_THIS_SCRIPT_NAME(), g_sSelectorUI.tlDisableReplayFeedScript)
//DEBUG_PRINTCALLSTACK()
//PRINTSTRING("\n DISABLE_REPLAY_RECORDING_UI_THIS_FRAME() called by '")PRINTSTRING(GET_THIS_SCRIPT_NAME())PRINTSTRING("'")PRINTNL()
g_sSelectorUI.tlDisableReplayFeedScript = GET_THIS_SCRIPT_NAME()
ENDIF
#ENDIF
g_sSelectorUI.bReplayFeedDisabledThisFrame = TRUE
#ENDIF
ENDPROC
/// PURPOSE:
/// Script wrapper to combine REPLAY_PREVENT_RECORDING_THIS_FRAME() and DISABLE_REPLAY_RECORDING_UI_THIS_FRAME()
PROC REPLAY_PREVENT_RECORDING_AND_UI_THIS_FRAME()
#IF USE_REPLAY_RECORDING_TRIGGERS
REPLAY_PREVENT_RECORDING_THIS_FRAME()
DISABLE_REPLAY_RECORDING_UI_THIS_FRAME()
#IF IS_DEBUG_BUILD
IF GET_COMMANDLINE_PARAM_EXISTS("RecBlockIndicator")
SET_TEXT_SCALE(0.3,0.3)
SET_TEXT_COLOUR(255,0,0,255)
DISPLAY_TEXT_WITH_LITERAL_STRING(0.8,0.1,"STRING","Replay rec. Disabled")
SET_TEXT_SCALE(1,1)
SET_TEXT_COLOUR(255,255,255,255)
ENDIF
#ENDIF
#ENDIF
ENDPROC
/// PURPOSE:
/// Waits until a debug key is pressed. Works as a makeshift Break
#IF IS_DEBUG_BUILD
PROC DEBUG_WAIT_UNTIL_KEYPRESS(KEY_NUMBER key, KEYBOARD_MODIFIER modKey = KEYBOARD_MODIFIER_NONE)
CPRINTLN(debug_system, "Wait breakpoint reached via:")
DEBUG_PRINTCALLSTACK()
WHILE NOT IS_DEBUG_KEY_JUST_PRESSED(key, modKey, "Waiting until keypress")
Wait(0)
ENDWHILE
ENDPROC
#ENDIF
/// PURPOSE: Default fade times for flash fading local entites
CONST_INT FLASH_FADE_DEFAULT_FADE_DURATION_MS 3000
CONST_INT FLASH_FADE_DEFAULT_FLASH_SPEED_MS 500
STRUCT FLASH_FADE_STRUCT
FLOAT fCurrentFlashFadeTime
BOOL bFinished = FALSE
ENDSTRUCT
/// PURPOSE:
/// Resets the flash fade time
/// PARAMS:
/// fFlashFadeTimeMS - the time used by the flash fade that needs reseting
PROC FLASH_FADE_RESET(FLASH_FADE_STRUCT &sFlashFade)
sFlashFade.bFinished = FALSE
sFlashFade.fCurrentFlashFadeTime = 0.0
ENDPROC
/// PURPOSE:
/// Checks if the flash fade has finished its last flash
/// PARAMS:
/// sFlashFade - the flash fade to check
/// RETURNS:
/// TRUE if the flash fade has finished
FUNC BOOL FLASH_FADE_HAS_FINISHED(FLASH_FADE_STRUCT &sFlashFade)
RETURN sFlashFade.bFinished
ENDFUNC
/// PURPOSE:
/// Gets an alpha in the range 0.0 - 1.0 in the range of 0 - 255
/// PARAMS:
/// fAlpha - alpha to convert
/// RETURNS:
/// Converted aplha in RGBA (0 - 255)
FUNC INT CONVERT_NORMALISED_ALPHA_TO_RGBA(FLOAT fAlpha)
RETURN ROUND(fAlpha * 255)
ENDFUNC
/// PURPOSE:
/// Updates the flash fadde and returns the current alpha
/// PARAMS:
/// sFlashFade -
/// RETURNS:
/// The alpha the entity/object should be given according to the flash progress
FUNC INT FLASH_FADE_UPDATE_ALPHA(FLASH_FADE_STRUCT &sFlashFade,
INT iFadeDurationMS = FLASH_FADE_DEFAULT_FADE_DURATION_MS,
INT iFlashDurationMS = FLASH_FADE_DEFAULT_FLASH_SPEED_MS)
// Increment time in milliseconds
sFlashFade.fCurrentFlashFadeTime += GET_FRAME_TIME()
FLOAT fNewAlpha = SIN((sFlashFade.fCurrentFlashFadeTime * 1000) + iFlashDurationMS)
BOOL bShouldFinish = sFlashFade.fCurrentFlashFadeTime >= iFadeDurationMS
// If we exceed the time make sure we fade out
IF bShouldFinish
// Make sure go negative to fade
fNewAlpha = ABSF(fNewAlpha) * -1
ENDIF
fNewAlpha = (fNewAlpha - -1.0) * 0.5// Map sin flash so it never goes negative
INT iNewAlpha = CONVERT_NORMALISED_ALPHA_TO_RGBA(fNewAlpha)
// Here we will hit 0 alpha so we can finally finish
IF bShouldFinish AND iNewAlpha = 0
sFlashFade.bFinished = TRUE
ENDIF
RETURN iNewAlpha
ENDFUNC
/// PURPOSE:
/// Flash fade a non-networked entity, this should be called until it returns true
/// PARAMS:
/// sFlashFade - fade instance
/// eiEntityToFade - the entity to flash fade
/// fFadeDurationMS - how long the overally flash fade effect lasts
/// fFlashDurationMS - how long each flash is
/// bUseSmoothAlpha - if should use smooth alpha, doesn't work for peds/vehicles
/// RETURNS:
/// TRUE when the flash fade has finished and will continue to do so unless reset
FUNC BOOL FLASH_FADE_ENTITY(FLASH_FADE_STRUCT &sFlashFade, ENTITY_INDEX &eiEntityToFade,
INT iFadeDurationMS = FLASH_FADE_DEFAULT_FADE_DURATION_MS,
INT iFlashDurationMS = FLASH_FADE_DEFAULT_FLASH_SPEED_MS,
BOOL bUseSmoothAlpha = TRUE,
BOOL bSkipEntExistCheck = FALSE)
IF sFlashFade.bFinished
RETURN TRUE
ENDIF
IF NOT DOES_ENTITY_EXIST(eiEntityToFade) AND NOT bSkipEntExistCheck
SCRIPT_ASSERT("FLASH_FADE_ENTITY - Entity does not exist!")
RETURN TRUE
ENDIF
INT iNewAlpha = FLASH_FADE_UPDATE_ALPHA(sFlashFade, iFadeDurationMS, iFlashDurationMS)
SET_ENTITY_ALPHA(eiEntityToFade, iNewAlpha, bUseSmoothAlpha)
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Flash fade a non-networked object
/// PARAMS:
/// sFlashFade - fade instance
/// objObjectToFade - the entity to flash fade
/// fFadeDurationMS - how long the overally flash fade effect lasts
/// fFlashDurationMS - how long each flash is
/// bUseSmoothAlpha - if should use smooth alpha, doesn't work for peds/vehicles
/// RETURNS:
/// TRUE when the flash fade has finished and will continue to do so unless reset
FUNC BOOL FLASH_FADE_OBJECT(FLASH_FADE_STRUCT &sFlashFade, OBJECT_INDEX &objObjectToFade,
INT iFadeDurationMS = FLASH_FADE_DEFAULT_FADE_DURATION_MS,
INT iFlashDurationMS = FLASH_FADE_DEFAULT_FLASH_SPEED_MS,
BOOL bUseSmoothAlpha = TRUE)
IF sFlashFade.bFinished
RETURN TRUE
ENDIF
IF NOT DOES_ENTITY_EXIST(objObjectToFade)
SCRIPT_ASSERT("FLASH_FADE_OBJECT - Entity does not exist!")
RETURN TRUE
ENDIF
INT iNewAlpha = FLASH_FADE_UPDATE_ALPHA(sFlashFade, iFadeDurationMS, iFlashDurationMS)
SET_ENTITY_ALPHA(objObjectToFade, iNewAlpha, bUseSmoothAlpha)
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Flash fade a non-networked vehicle
/// PARAMS:
/// sFlashFade - fade instance
/// vehVehicleToFade - the vehicle to flash fade
/// fFadeDurationMS - how long the overally flash fade effect lasts
/// fFlashDurationMS - how long each flash is
/// bUseSmoothAlpha - if should use smooth alpha, doesn't work for peds/vehicles
/// RETURNS:
/// TRUE when the flash fade has finished and will continue to do so unless reset
FUNC BOOL FLASH_FADE_VEHICLE(FLASH_FADE_STRUCT &sFlashFade, VEHICLE_INDEX &vehVehicleToFade, INT iFadeDurationMS = FLASH_FADE_DEFAULT_FADE_DURATION_MS, INT iFlashDurationMS = FLASH_FADE_DEFAULT_FLASH_SPEED_MS)
IF sFlashFade.bFinished
RETURN TRUE
ENDIF
IF NOT DOES_ENTITY_EXIST(vehVehicleToFade)
SCRIPT_ASSERT("FLASH_FADE_OBJECT - Vehicle does not exist!")
RETURN TRUE
ENDIF
INT iNewAlpha = FLASH_FADE_UPDATE_ALPHA(sFlashFade, iFadeDurationMS, iFlashDurationMS)
SET_ENTITY_ALPHA(vehVehicleToFade, iNewAlpha, FALSE)
RETURN FALSE
ENDFUNC