// // 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("<<>> ") ELSE PRINTLN("<<>> ") 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 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