// ***************************************************************************************** // ***************************************************************************************** // // FILE NAME : RC_Asset_public.sch // AUTHOR : Aaron Gandaa // DESCRIPTION : Helper Stuff for loading stuff // // ***************************************************************************************** // ***************************************************************************************** //---------------------- // INCLUDES //---------------------- USING "rage_builtins.sch" USING "globals.sch" USING "commands_entity.sch" USING "script_player.sch" USING "script_ped.sch" USING "commands_weapon.sch" USING "commands_streaming.sch" //---------------------- // ENUM //---------------------- ENUM eAssetType ASSET_NULL, ASSET_ACTIONMODE, ASSET_ANIMDICT, ASSET_ANIMSET, ASSET_AUDIOBANK, ASSET_AUDIOSTREAM, ASSET_MODEL, ASSET_PTFX, ASSET_TEXT, ASSET_TEXDICT, ASSET_VEHREC, ASSET_WAYREC, ASSET_WEAPON ENDENUM //---------------------- // STRUCTS //---------------------- STRUCT ASSET_REQUEST eAssetType assetType MODEL_NAMES modelName WEAPON_TYPE weaponType STRING sAssetName STRING sString // secondary string used for soundsets INT iValue // used for vehicle recordings INT iTimeOut ENDSTRUCT STRUCT ASSET_REQUESTER ASSET_REQUEST request[16] INT iRequestedFlag = 0 INT iLoadedFlag = 0 INT iRequestCounter = 0 INT iNextRequestTime = 0 BOOL bHasTimedOut = FALSE ENDSTRUCT //---------------------- // FUNCTIONS //---------------------- /// PURPOSE: /// Resets the asset request to default values /// PARAMS: /// ar - asset request PROC _CLEAR_ASSET_REQUEST(ASSET_REQUEST &ar) ar.assetType = ASSET_NULL ar.modelName = DUMMY_MODEL_FOR_SCRIPT ar.weaponType = WEAPONTYPE_INVALID ar.sAssetName = NULL ar.sString = NULL ar.iValue = 0 ENDPROC /// PURPOSE: /// Resets the asset requester to default values /// PARAMS: /// ar - asset requester PROC CLEAR_ASSET_REQUESTER(ASSET_REQUESTER &ar) INT i ar.iLoadedFlag = 0 ar.iRequestedFlag = 0 ar.iRequestCounter = 0 REPEAT COUNT_OF(ar.request) i _CLEAR_ASSET_REQUEST(ar.request[i]) ENDREPEAT ENDPROC /// PURPOSE: /// Used internally to set the request on each slot and set up the timeout time /// PARAMS: /// ar - asset requester /// iSlot - slot to request PROC _FINALIZE_ASSET_REQUEST(ASSET_REQUESTER &ar, INT iSlot) ar.request[iSlot].iTimeOut = GET_GAME_TIMER() + 10000 SET_BIT(ar.iRequestedFlag, iSlot) ENDPROC /// PURPOSE: /// Adds an request for a model /// PARAMS: /// ar - asset requester /// iSlot - slot to request /// mdl - model /// RETURNS: /// True if the slot is requested FUNC BOOL ADD_ASSET_REQUEST_FOR_MODEL(ASSET_REQUESTER &ar, INT iSlot, MODEL_NAMES mdl) // check that asset hasn't been loaded already IF IS_BIT_SET(ar.iRequestedFlag, iSlot) OR IS_BIT_SET(ar.iLoadedFlag, iSlot) RETURN TRUE ENDIF IF (mdl = DUMMY_MODEL_FOR_SCRIPT) RETURN FALSE ENDIF // mark asset as requested and fill in data _CLEAR_ASSET_REQUEST(ar.request[iSlot]) ar.request[iSlot].assetType = ASSET_MODEL ar.request[iSlot].modelName = mdl RETURN TRUE ENDFUNC /// PURPOSE: /// Adds an request for an asset with a string name /// PARAMS: /// ar - asset requester /// iSlot - slot to request /// type - asset type /// str - name of object /// str2 - subname of object (mainly used for sound sets) /// RETURNS: /// True if the slot is requested FUNC BOOL ADD_ASSET_REQUEST_FROM_STRING(ASSET_REQUESTER &ar, INT iSlot, eAssetType type, STRING str, STRING str2 = NULL) // check that asset hasn't been loaded already IF IS_BIT_SET(ar.iRequestedFlag, iSlot) OR IS_BIT_SET(ar.iLoadedFlag, iSlot) RETURN TRUE ENDIF IF IS_STRING_NULL_OR_EMPTY(str) RETURN FALSE ENDIF // request asset SWITCH (type) CASE ASSET_ACTIONMODE REQUEST_ACTION_MODE_ASSET(str) BREAK CASE ASSET_ANIMDICT REQUEST_ANIM_DICT(str) BREAK CASE ASSET_ANIMSET REQUEST_ANIM_SET(str) BREAK CASE ASSET_AUDIOBANK REQUEST_SCRIPT_AUDIO_BANK(str) BREAK CASE ASSET_AUDIOSTREAM LOAD_STREAM(str, str2) BREAK CASE ASSET_TEXDICT REQUEST_STREAMED_TEXTURE_DICT(str, FALSE) BREAK CASE ASSET_WAYREC REQUEST_WAYPOINT_RECORDING(str) BREAK DEFAULT SCRIPT_ASSERT("You need to use the specified asset request command for these") RETURN FALSE ENDSWITCH // mark asset as requested and fill in data _CLEAR_ASSET_REQUEST(ar.request[iSlot]) ar.request[iSlot].assetType = type ar.request[iSlot].sAssetName = str ar.request[iSlot].sString = str2 RETURN TRUE ENDFUNC /// PURPOSE: /// Adds an request for an text asset /// PARAMS: /// ar - asset requester /// iSlot - slot to request /// str - name of object /// slot - text block slot /// RETURNS: /// True if the slot is requested FUNC BOOL ADD_ASSET_REQUEST_FOR_PTFX(ASSET_REQUESTER &ar, INT iSlot) // check that asset hasn't been loaded already IF IS_BIT_SET(ar.iRequestedFlag, iSlot) OR IS_BIT_SET(ar.iLoadedFlag, iSlot) RETURN TRUE ENDIF // mark asset as requested and fill in data _CLEAR_ASSET_REQUEST(ar.request[iSlot]) ar.request[iSlot].assetType = ASSET_PTFX ar.request[iSlot].sAssetName = "script" RETURN TRUE ENDFUNC /// PURPOSE: /// Adds an request for an text asset /// PARAMS: /// ar - asset requester /// iSlot - slot to request /// str - name of object /// slot - text block slot /// RETURNS: /// True if the slot is requested FUNC BOOL ADD_ASSET_REQUEST_FOR_TEXT(ASSET_REQUESTER &ar, INT iSlot, STRING str, TEXT_BLOCK_SLOTS slot) // check that asset hasn't been loaded already IF IS_BIT_SET(ar.iRequestedFlag, iSlot) OR IS_BIT_SET(ar.iLoadedFlag, iSlot) RETURN TRUE ENDIF // mark asset as requested and fill in data _CLEAR_ASSET_REQUEST(ar.request[iSlot]) ar.request[iSlot].assetType = ASSET_TEXT ar.request[iSlot].sAssetName = str ar.request[iSlot].iValue = ENUM_TO_INT(slot) RETURN TRUE ENDFUNC /// PURPOSE: /// Adds an request for an vehicle recording /// PARAMS: /// ar - asset requester /// iSlot - slot to request /// str - name of object /// num - number of recording /// RETURNS: /// True if the slot is requested FUNC BOOL ADD_ASSET_REQUEST_FOR_VEHICLE_REC(ASSET_REQUESTER &ar, INT iSlot, STRING str, INT num) // check that asset hasn't been loaded already IF IS_BIT_SET(ar.iRequestedFlag, iSlot) OR IS_BIT_SET(ar.iLoadedFlag, iSlot) RETURN TRUE ENDIF // mark asset as requested and fill in data _CLEAR_ASSET_REQUEST(ar.request[iSlot]) ar.request[iSlot].assetType = ASSET_VEHREC ar.request[iSlot].sAssetName = str ar.request[iSlot].iValue = num RETURN TRUE ENDFUNC /// PURPOSE: /// Adds an request for an weapon /// PARAMS: /// ar - asset requester /// iSlot - slot to request /// mdl - weapontype /// RETURNS: /// True if the slot is requested FUNC BOOL ADD_ASSET_REQUEST_FOR_WEAPON(ASSET_REQUESTER &ar, INT iSlot, WEAPON_TYPE mdl) // check that asset hasn't been loaded already IF IS_BIT_SET(ar.iRequestedFlag, iSlot) OR IS_BIT_SET(ar.iLoadedFlag, iSlot) RETURN TRUE ENDIF // mark asset as requested and fill in data _CLEAR_ASSET_REQUEST(ar.request[iSlot]) ar.request[iSlot].assetType = ASSET_WEAPON ar.request[iSlot].weaponType = mdl RETURN TRUE ENDFUNC /// PURPOSE: /// Called internally by the asset requester to start loading /// PARAMS: /// ar - /// iSlot - /// RETURNS: /// FUNC BOOL _START_ASSET_REQUEST(ASSET_REQUESTER &ar, INT iSlot) // check that asset hasn't been loaded already IF IS_BIT_SET(ar.iRequestedFlag, iSlot) OR IS_BIT_SET(ar.iLoadedFlag, iSlot) RETURN TRUE ENDIF // request asset SWITCH (ar.request[iSlot].assetType) CASE ASSET_ACTIONMODE REQUEST_ACTION_MODE_ASSET(ar.request[iSlot].sAssetName) BREAK CASE ASSET_ANIMDICT REQUEST_ANIM_DICT(ar.request[iSlot].sAssetName) BREAK CASE ASSET_ANIMSET REQUEST_ANIM_SET(ar.request[iSlot].sAssetName) BREAK CASE ASSET_AUDIOBANK REQUEST_SCRIPT_AUDIO_BANK(ar.request[iSlot].sAssetName) BREAK CASE ASSET_AUDIOSTREAM LOAD_STREAM(ar.request[iSlot].sAssetName, ar.request[iSlot].sString) BREAK CASE ASSET_MODEL REQUEST_MODEL(ar.request[iSlot].modelName) BREAK CASE ASSET_PTFX REQUEST_PTFX_ASSET() BREAK CASE ASSET_TEXT REQUEST_ADDITIONAL_TEXT(ar.request[iSlot].sAssetName, (INT_TO_ENUM(TEXT_BLOCK_SLOTS, ar.request[iSlot].iValue))) BREAK CASE ASSET_TEXDICT REQUEST_STREAMED_TEXTURE_DICT(ar.request[iSlot].sAssetName, FALSE) BREAK CASE ASSET_VEHREC REQUEST_VEHICLE_RECORDING(ar.request[iSlot].iValue, ar.request[iSlot].sAssetName) BREAK CASE ASSET_WAYREC REQUEST_WAYPOINT_RECORDING(ar.request[iSlot].sAssetName) BREAK CASE ASSET_WEAPON REQUEST_WEAPON_ASSET(ar.request[iSlot].weaponType) BREAK DEFAULT RETURN FALSE ENDSWITCH // debug SWITCH (ar.request[iSlot].assetType) CASE ASSET_MODEL CPRINTLN(DEBUG_MISSION, "[ASSET REQUESTER] - MODEL:", GET_MODEL_NAME_FOR_DEBUG(ar.request[iSlot].modelName), " HAS BEEN REQUESTED") BREAK CASE ASSET_PTFX CPRINTLN(DEBUG_MISSION, "[ASSET REQUESTER] - PTFX HAS BEEN REQUESTED") BREAK CASE ASSET_TEXT CPRINTLN(DEBUG_MISSION, "[ASSET REQUESTER] - TEXT:", ar.request[iSlot].sAssetName, " HAS BEEN REQUESTED") BREAK CASE ASSET_WEAPON CPRINTLN(DEBUG_MISSION, "[ASSET REQUESTER] - WEAPON:", GET_WEAPON_NAME(ar.request[iSlot].weaponType), " HAS BEEN REQUESTED") BREAK DEFAULT CPRINTLN(DEBUG_MISSION, "[ASSET REQUESTER] - ASSET:", ar.request[iSlot].sAssetName, " HAS BEEN REQUESTED") BREAK ENDSWITCH ar.bHasTimedOut = FALSE ar.request[iSlot].iTimeOut = GET_GAME_TIMER() + 10000 SET_BIT(ar.iRequestedFlag, iSlot) RETURN TRUE ENDFUNC FUNC BOOL _HAS_ASSET_REQUEST_LOADED(ASSET_REQUESTER &ar, INT iSlot) IF IS_BIT_SET(ar.iLoadedFlag, iSlot) RETURN TRUE ENDIF IF (ar.request[iSlot].assetType = ASSET_NULL) RETURN TRUE ENDIF IF NOT IS_BIT_SET(ar.iRequestedFlag, iSlot) RETURN FALSE ENDIF // check for time out - mark it as true anyways so that we can break out IF (GET_GAME_TIMER() > ar.request[iSlot].iTimeOut) ar.bHasTimedOut = TRUE //SCRIPT_ASSERT("ASSET REQUESTER HAS TIMED OUT") RETURN TRUE ENDIF // request asset SWITCH (ar.request[iSlot].assetType) CASE ASSET_NULL RETURN TRUE CASE ASSET_ACTIONMODE IF NOT HAS_ACTION_MODE_ASSET_LOADED(ar.request[iSlot].sAssetName) RETURN FALSE ENDIF BREAK CASE ASSET_ANIMDICT IF NOT HAS_ANIM_DICT_LOADED(ar.request[iSlot].sAssetName) RETURN FALSE ENDIF BREAK CASE ASSET_ANIMSET IF NOT HAS_ANIM_SET_LOADED(ar.request[iSlot].sAssetName) RETURN FALSE ENDIF BREAK CASE ASSET_AUDIOBANK IF NOT REQUEST_SCRIPT_AUDIO_BANK(ar.request[iSlot].sAssetName) RETURN FALSE ENDIF BREAK CASE ASSET_AUDIOSTREAM IF NOT LOAD_STREAM(ar.request[iSlot].sAssetName) RETURN FALSE ENDIF BREAK CASE ASSET_MODEL IF NOT HAS_MODEL_LOADED(ar.request[iSlot].modelName) RETURN FALSE ENDIF BREAK CASE ASSET_PTFX IF NOT HAS_PTFX_ASSET_LOADED() RETURN FALSE ENDIF BREAK CASE ASSET_TEXT IF NOT HAS_ADDITIONAL_TEXT_LOADED(INT_TO_ENUM(TEXT_BLOCK_SLOTS, ar.request[iSlot].iValue)) RETURN FALSE ENDIF BREAK CASE ASSET_TEXDICT IF NOT HAS_STREAMED_TEXTURE_DICT_LOADED(ar.request[iSlot].sAssetName) RETURN FALSE ENDIF BREAK CASE ASSET_VEHREC IF NOT HAS_VEHICLE_RECORDING_BEEN_LOADED(ar.request[iSlot].iValue, ar.request[iSlot].sAssetName) RETURN FALSE ENDIF BREAK CASE ASSET_WAYREC IF NOT GET_IS_WAYPOINT_RECORDING_LOADED(ar.request[iSlot].sAssetName) RETURN FALSE ENDIF BREAK CASE ASSET_WEAPON IF NOT HAS_WEAPON_ASSET_LOADED(ar.request[iSlot].weaponType) RETURN FALSE ENDIF BREAK DEFAULT SCRIPT_ASSERT("You need to use the specified asset request command for this") RETURN FALSE ENDSWITCH // mark asset as loaded SET_BIT(ar.iLoadedFlag, iSlot) // debug SWITCH (ar.request[iSlot].assetType) CASE ASSET_MODEL CPRINTLN(DEBUG_MISSION, "[ASSET REQUESTER] - MODEL:", GET_MODEL_NAME_FOR_DEBUG(ar.request[iSlot].modelName), " HAS LOADED") BREAK CASE ASSET_PTFX CPRINTLN(DEBUG_MISSION, "[ASSET REQUESTER] - PTFX HAS LOADED") BREAK CASE ASSET_TEXT CPRINTLN(DEBUG_MISSION, "[ASSET REQUESTER] - TEXT:", ar.request[iSlot].sAssetName, " HAS LOADED IN SLOT:", ar.request[iSlot].iValue) BREAK CASE ASSET_WEAPON CPRINTLN(DEBUG_MISSION, "[ASSET REQUESTER] - WEAPON:", GET_WEAPON_NAME(ar.request[iSlot].weaponType), " HAS LOADED") BREAK DEFAULT CPRINTLN(DEBUG_MISSION, "[ASSET REQUESTER] - ASSET:", ar.request[iSlot].sAssetName, " HAS LOADED") BREAK ENDSWITCH RETURN TRUE ENDFUNC /// PURPOSE: /// Runs the Asset Requester - Call this every frame /// PARAMS: /// ar - requester reference /// RETURNS: /// Returns TRUE - If all items have been loaded or timed out FUNC BOOL HAVE_ASSET_REQUESTS_LOADED(ASSET_REQUESTER &ar) INT i, cnt IF (GET_GAME_TIMER() > ar.iNextRequestTime) OR (ar.iNextRequestTime = 0) IF (ar.iRequestCounter < COUNT_OF(ar.request)) _START_ASSET_REQUEST(ar, ar.iRequestCounter) ar.iRequestCounter ++ ENDIF ar.iNextRequestTime = GET_GAME_TIMER() + 32 ENDIF REPEAT COUNT_OF(ar.request) i IF _HAS_ASSET_REQUEST_LOADED(ar, i) cnt ++ ENDIF ENDREPEAT RETURN cnt = COUNT_OF(ar.request) ENDFUNC /// PURPOSE: /// Runs the Asset Requester - Call this every frame /// PARAMS: /// ar - requester reference /// RETURNS: /// Returns TRUE - If all items have been loaded or timed out FUNC BOOL HAVE_ASSET_REQUESTS_TIMED_OUT(ASSET_REQUESTER &ar) RETURN ar.bHasTimedOut ENDFUNC /// PURPOSE: /// Called internally by the asset requester to start unloading and marking things as not needed /// PARAMS: /// ar - requester reference /// iSlot - slot /// RETURNS: /// true if it could FUNC BOOL _UNLOAD_ASSET_FROM_REQUESTER(ASSET_REQUESTER &ar, INT iSlot) // check that asset hasn't been loaded already IF NOT IS_BIT_SET(ar.iLoadedFlag, iSlot) OR (ar.request[iSlot].assetType = ASSET_NULL) RETURN TRUE ENDIF // request asset SWITCH (ar.request[iSlot].assetType) CASE ASSET_ACTIONMODE IF HAS_ACTION_MODE_ASSET_LOADED(ar.request[iSlot].sAssetName) REMOVE_ACTION_MODE_ASSET(ar.request[iSlot].sAssetName) ENDIF BREAK CASE ASSET_ANIMDICT IF HAS_ANIM_DICT_LOADED(ar.request[iSlot].sAssetName) REMOVE_ANIM_DICT(ar.request[iSlot].sAssetName) ENDIF BREAK CASE ASSET_ANIMSET IF HAS_ANIM_SET_LOADED(ar.request[iSlot].sAssetName) REMOVE_ANIM_SET(ar.request[iSlot].sAssetName) ENDIF BREAK CASE ASSET_AUDIOBANK RELEASE_SCRIPT_AUDIO_BANK() BREAK CASE ASSET_AUDIOSTREAM //LOAD_STREAM(ar.request[iSlot].sAssetName, ar.request[iSlot].sString) BREAK CASE ASSET_MODEL IF HAS_MODEL_LOADED(ar.request[iSlot].modelName) SET_MODEL_AS_NO_LONGER_NEEDED(ar.request[iSlot].modelName) ENDIF BREAK CASE ASSET_PTFX IF HAS_PTFX_ASSET_LOADED() REMOVE_PTFX_ASSET() ENDIF BREAK CASE ASSET_TEXT IF HAS_ADDITIONAL_TEXT_LOADED(INT_TO_ENUM(TEXT_BLOCK_SLOTS, ar.request[iSlot].iValue)) CLEAR_ADDITIONAL_TEXT(INT_TO_ENUM(TEXT_BLOCK_SLOTS, ar.request[iSlot].iValue), FALSE) ENDIF BREAK CASE ASSET_TEXDICT IF HAS_STREAMED_TEXTURE_DICT_LOADED(ar.request[iSlot].sAssetName) SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED(ar.request[iSlot].sAssetName) ENDIF BREAK CASE ASSET_VEHREC IF HAS_VEHICLE_RECORDING_BEEN_LOADED(ar.request[iSlot].iValue, ar.request[iSlot].sAssetName) REMOVE_VEHICLE_RECORDING(ar.request[iSlot].iValue, ar.request[iSlot].sAssetName) ENDIF BREAK CASE ASSET_WAYREC IF GET_IS_WAYPOINT_RECORDING_LOADED(ar.request[iSlot].sAssetName) REMOVE_WAYPOINT_RECORDING(ar.request[iSlot].sAssetName) ENDIF BREAK CASE ASSET_WEAPON IF HAS_WEAPON_ASSET_LOADED(ar.request[iSlot].weaponType) REMOVE_WEAPON_ASSET(ar.request[iSlot].weaponType) ENDIF BREAK DEFAULT RETURN FALSE ENDSWITCH // debug SWITCH (ar.request[iSlot].assetType) CASE ASSET_MODEL CPRINTLN(DEBUG_MISSION, "[ASSET REQUESTER] - MODEL:", GET_MODEL_NAME_FOR_DEBUG(ar.request[iSlot].modelName), " HAS UNLOADED") BREAK CASE ASSET_PTFX CPRINTLN(DEBUG_MISSION, "[ASSET REQUESTER] - PTFX HAS UNLOADED") BREAK CASE ASSET_TEXT CPRINTLN(DEBUG_MISSION, "[ASSET REQUESTER] - TEXT:", ar.request[iSlot].sAssetName, " HAS UNLOADED") BREAK CASE ASSET_WEAPON CPRINTLN(DEBUG_MISSION, "[ASSET REQUESTER] - WEAPON:", GET_WEAPON_NAME(ar.request[iSlot].weaponType), " HAS UNLOADED") BREAK DEFAULT CPRINTLN(DEBUG_MISSION, "[ASSET REQUESTER] - ASSET:", ar.request[iSlot].sAssetName, " HAS UNLOADED") BREAK ENDSWITCH _CLEAR_ASSET_REQUEST(ar.request[iSlot]) RETURN TRUE ENDFUNC PROC UNLOAD_REQUESTED_ASSETS(ASSET_REQUESTER &ar) INT i REPEAT COUNT_OF(ar.request) i _UNLOAD_ASSET_FROM_REQUESTER(ar, i) ENDREPEAT ENDPROC