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

630 lines
17 KiB
XML
Executable File

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