mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-13 15:44:36 +00:00
player and ground cover
This commit is contained in:
parent
c6ec2fd6a1
commit
5d641929cf
5 changed files with 95 additions and 39 deletions
|
|
@ -678,6 +678,64 @@ public:
|
||||||
static bool _set##name##Data(void* obj, const char* index, const char* data) { static_cast<className*>(obj)->_set##name(_getStringTable()->insert(data), dAtoi(index)); return false;}\
|
static bool _set##name##Data(void* obj, const char* index, const char* data) { static_cast<className*>(obj)->_set##name(_getStringTable()->insert(data), dAtoi(index)); return false;}\
|
||||||
StringTableEntry get##name##File(const U32& idx) { return m##name##Asset[idx].notNull() ? m##name##Asset[idx]->getShapePath() : ""; }
|
StringTableEntry get##name##File(const U32& idx) { return m##name##Asset[idx].notNull() ? m##name##Asset[idx]->getShapePath() : ""; }
|
||||||
|
|
||||||
|
#define DECLARE_SHAPEASSET_ARRAY_NET_REFACTOR(className, name, max, mask) \
|
||||||
|
private: \
|
||||||
|
AssetPtr<ShapeAsset> m##name##Asset[max]; \
|
||||||
|
StringTableEntry m##name##File[max] = {StringTable->EmptyString() }; \
|
||||||
|
public: \
|
||||||
|
void _set##name(StringTableEntry _in, const U32& index){ \
|
||||||
|
if (m##name##Asset[index].getAssetId() == _in) \
|
||||||
|
return; \
|
||||||
|
if(get##name##File(index) == _in) \
|
||||||
|
return; \
|
||||||
|
if (_in == NULL || _in == StringTable->EmptyString()) \
|
||||||
|
{ \
|
||||||
|
m##name##Asset[index] = NULL; \
|
||||||
|
m##name##File[index] = ""; \
|
||||||
|
setMaskBits(mask); \
|
||||||
|
return; \
|
||||||
|
} \
|
||||||
|
if (!AssetDatabase.isDeclaredAsset(_in)) \
|
||||||
|
{ \
|
||||||
|
StringTableEntry shapeAssetId = StringTable->EmptyString(); \
|
||||||
|
AssetQuery query; \
|
||||||
|
S32 foundAssetcount = AssetDatabase.findAssetLooseFile(&query, _in); \
|
||||||
|
if (foundAssetcount != 0) \
|
||||||
|
{ \
|
||||||
|
shapeAssetId = query.mAssetList[0]; \
|
||||||
|
} \
|
||||||
|
else if (Torque::FS::IsFile(_in) || (_in[0] == '$' || _in[0] == '#')) \
|
||||||
|
{ \
|
||||||
|
shapeAssetId = ShapeAsset::getAssetIdByFilename(_in); \
|
||||||
|
if (shapeAssetId == ShapeAsset::smNoShapeAssetFallback) \
|
||||||
|
{ \
|
||||||
|
ShapeAsset* privateShape = new ShapeAsset(); \
|
||||||
|
privateShape->setShapeFile(_in); \
|
||||||
|
shapeAssetId = AssetDatabase.addPrivateAsset(privateShape); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
Con::warnf("%s::%s: Could not find asset for: %s using fallback", #className, #name, _in); \
|
||||||
|
shapeAssetId = ShapeAsset::smNoShapeAssetFallback; \
|
||||||
|
} \
|
||||||
|
m##name##Asset[index] = shapeAssetId; \
|
||||||
|
m##name##File[index] = _in; \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
m##name##Asset[index] = _in; \
|
||||||
|
m##name##File[index] = get##name##File(index); \
|
||||||
|
} \
|
||||||
|
setMaskBits(mask); \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
inline StringTableEntry _get##name##AssetId(const U32& index) const { return m##name##Asset[index].getAssetId(); } \
|
||||||
|
Resource<TSShape> get##name(const U32& index) { if (m##name##Asset[index].notNull()) return m##name##Asset[index]->getShapeResource(); else return NULL; } \
|
||||||
|
AssetPtr<ShapeAsset> get##name##Asset(const U32& index) { return m##name##Asset[index]; } \
|
||||||
|
static bool _set##name##Data(void* obj, const char* index, const char* data) { static_cast<className*>(obj)->_set##name(_getStringTable()->insert(data), dAtoi(index)); return false;}\
|
||||||
|
StringTableEntry get##name##File(const U32& idx) { return m##name##Asset[idx].notNull() ? m##name##Asset[idx]->getShapePath() : ""; }
|
||||||
|
|
||||||
#define INITPERSISTFIELD_SHAPEASSET_ARRAY_REFACTOR(name, arraySize, consoleClass, docs) \
|
#define INITPERSISTFIELD_SHAPEASSET_ARRAY_REFACTOR(name, arraySize, consoleClass, docs) \
|
||||||
addProtectedField(assetText(name, Asset), TypeShapeAssetPtrRefactor, Offset(m##name##Asset, consoleClass), _set##name##Data, &defaultProtectedGetFn, arraySize, assetDoc(name, asset docs.));\
|
addProtectedField(assetText(name, Asset), TypeShapeAssetPtrRefactor, Offset(m##name##Asset, consoleClass), _set##name##Data, &defaultProtectedGetFn, arraySize, assetDoc(name, asset docs.));\
|
||||||
addProtectedField(assetText(name, File), TypeFilename, Offset(m##name##File, consoleClass), _set##name##Data, &defaultProtectedGetFn, arraySize, assetDoc(name, asset docs.));
|
addProtectedField(assetText(name, File), TypeFilename, Offset(m##name##File, consoleClass), _set##name##Data, &defaultProtectedGetFn, arraySize, assetDoc(name, asset docs.));
|
||||||
|
|
|
||||||
|
|
@ -521,7 +521,7 @@ GroundCover::GroundCover()
|
||||||
mBillboardRects[i].point.set( 0.0f, 0.0f );
|
mBillboardRects[i].point.set( 0.0f, 0.0f );
|
||||||
mBillboardRects[i].extent.set( 1.0f, 1.0f );
|
mBillboardRects[i].extent.set( 1.0f, 1.0f );
|
||||||
|
|
||||||
INIT_ASSET_ARRAY(Shape, i);
|
mShapeAsset[i].registerRefreshNotify(this);
|
||||||
|
|
||||||
mShapeInstances[i] = NULL;
|
mShapeInstances[i] = NULL;
|
||||||
|
|
||||||
|
|
@ -563,8 +563,7 @@ void GroundCover::initPersistFields()
|
||||||
|
|
||||||
addField( "billboardUVs", TypeRectUV, Offset( mBillboardRects, GroundCover ), MAX_COVERTYPES, "Subset material UV coordinates for this cover billboard." );
|
addField( "billboardUVs", TypeRectUV, Offset( mBillboardRects, GroundCover ), MAX_COVERTYPES, "Subset material UV coordinates for this cover billboard." );
|
||||||
|
|
||||||
addField("shapeFilename", TypeFilename, Offset(mShapeName, GroundCover), MAX_COVERTYPES, "The cover shape filename. [Optional]", AbstractClassRep::FIELD_HideInInspectors);
|
INITPERSISTFIELD_SHAPEASSET_ARRAY_REFACTOR(Shape, MAX_COVERTYPES, GroundCover, "The cover shape. [Optional]");
|
||||||
INITPERSISTFIELD_SHAPEASSET_ARRAY(Shape, MAX_COVERTYPES, GroundCover, "The cover shape. [Optional]");
|
|
||||||
|
|
||||||
addField( "layer", TypeTerrainMaterialAssetId, Offset( mLayer, GroundCover ), MAX_COVERTYPES, "Terrain material assetId to limit coverage to, or blank to not limit." );
|
addField( "layer", TypeTerrainMaterialAssetId, Offset( mLayer, GroundCover ), MAX_COVERTYPES, "Terrain material assetId to limit coverage to, or blank to not limit." );
|
||||||
|
|
||||||
|
|
@ -767,10 +766,10 @@ U32 GroundCover::packUpdate( NetConnection *connection, U32 mask, BitStream *str
|
||||||
stream->write( mBillboardRects[i].point.y );
|
stream->write( mBillboardRects[i].point.y );
|
||||||
stream->write( mBillboardRects[i].extent.x );
|
stream->write( mBillboardRects[i].extent.x );
|
||||||
stream->write( mBillboardRects[i].extent.y );
|
stream->write( mBillboardRects[i].extent.y );
|
||||||
|
|
||||||
PACK_ASSET_ARRAY(connection, Shape, i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PACK_ASSET_ARRAY_REFACTOR(connection, Shape, MAX_COVERTYPES)
|
||||||
|
|
||||||
stream->writeFlag( mDebugRenderCells );
|
stream->writeFlag( mDebugRenderCells );
|
||||||
stream->writeFlag( mDebugNoBillboards );
|
stream->writeFlag( mDebugNoBillboards );
|
||||||
stream->writeFlag( mDebugNoShapes );
|
stream->writeFlag( mDebugNoShapes );
|
||||||
|
|
@ -838,10 +837,10 @@ void GroundCover::unpackUpdate( NetConnection *connection, BitStream *stream )
|
||||||
stream->read( &mBillboardRects[i].point.y );
|
stream->read( &mBillboardRects[i].point.y );
|
||||||
stream->read( &mBillboardRects[i].extent.x );
|
stream->read( &mBillboardRects[i].extent.x );
|
||||||
stream->read( &mBillboardRects[i].extent.y );
|
stream->read( &mBillboardRects[i].extent.y );
|
||||||
|
|
||||||
UNPACK_ASSET_ARRAY(connection, Shape, i);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UNPACK_ASSET_ARRAY_REFACTOR(connection, Shape, MAX_COVERTYPES)
|
||||||
|
|
||||||
mDebugRenderCells = stream->readFlag();
|
mDebugRenderCells = stream->readFlag();
|
||||||
mDebugNoBillboards = stream->readFlag();
|
mDebugNoBillboards = stream->readFlag();
|
||||||
mDebugNoShapes = stream->readFlag();
|
mDebugNoShapes = stream->readFlag();
|
||||||
|
|
@ -887,17 +886,17 @@ void GroundCover::_initShapes()
|
||||||
|
|
||||||
for ( S32 i=0; i < MAX_COVERTYPES; i++ )
|
for ( S32 i=0; i < MAX_COVERTYPES; i++ )
|
||||||
{
|
{
|
||||||
if ( mShapeAsset[i].isNull() || mShape[i] == nullptr)
|
if ( mShapeAsset[i].isNull() || getShape(i) == nullptr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ( isClientObject() && !mShape[i]->preloadMaterialList(mShape[i].getPath()) && NetConnection::filesWereDownloaded() )
|
if ( isClientObject() && !getShape(i)->preloadMaterialList(getShape(i).getPath()) && NetConnection::filesWereDownloaded() )
|
||||||
{
|
{
|
||||||
Con::warnf( "GroundCover::_initShapes() material preload failed for shape: %s", mShapeAssetId[i] );
|
Con::warnf( "GroundCover::_initShapes() material preload failed for shape: %s", _getShapeAssetId(i));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the shape instance.
|
// Create the shape instance.
|
||||||
mShapeInstances[i] = new TSShapeInstance(mShape[i], isClientObject() );
|
mShapeInstances[i] = new TSShapeInstance(getShape(i), isClientObject() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class GroundCover : public SceneObject
|
class GroundCover : public SceneObject, protected AssetPtrCallback
|
||||||
{
|
{
|
||||||
friend class GroundCoverShaderConstHandles;
|
friend class GroundCoverShaderConstHandles;
|
||||||
friend class GroundCoverCell;
|
friend class GroundCoverCell;
|
||||||
|
|
@ -341,8 +341,7 @@ protected:
|
||||||
RectF mBillboardRects[MAX_COVERTYPES];
|
RectF mBillboardRects[MAX_COVERTYPES];
|
||||||
|
|
||||||
/// The cover shape filenames.
|
/// The cover shape filenames.
|
||||||
DECLARE_SHAPEASSET_ARRAY(GroundCover, Shape, MAX_COVERTYPES, onShapeChanged);
|
DECLARE_SHAPEASSET_ARRAY_NET_REFACTOR(GroundCover, Shape, MAX_COVERTYPES, -1)
|
||||||
DECLARE_ASSET_ARRAY_NET_SETGET(GroundCover, Shape, -1);
|
|
||||||
|
|
||||||
/// The cover shape instances.
|
/// The cover shape instances.
|
||||||
TSShapeInstance* mShapeInstances[MAX_COVERTYPES];
|
TSShapeInstance* mShapeInstances[MAX_COVERTYPES];
|
||||||
|
|
@ -410,7 +409,8 @@ protected:
|
||||||
|
|
||||||
void _debugRender( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat );
|
void _debugRender( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat );
|
||||||
|
|
||||||
void onShapeChanged()
|
protected:
|
||||||
|
void onAssetRefreshed(AssetPtrBase* pAssetPtrBase) override
|
||||||
{
|
{
|
||||||
_initShapes();
|
_initShapes();
|
||||||
setMaskBits(U32(-1));
|
setMaskBits(U32(-1));
|
||||||
|
|
|
||||||
|
|
@ -297,7 +297,7 @@ PlayerData::PlayerData()
|
||||||
imageAnimPrefixFP = StringTable->EmptyString();
|
imageAnimPrefixFP = StringTable->EmptyString();
|
||||||
for (U32 i=0; i<ShapeBase::MaxMountedImages; ++i)
|
for (U32 i=0; i<ShapeBase::MaxMountedImages; ++i)
|
||||||
{
|
{
|
||||||
INIT_ASSET_ARRAY(ShapeFP, i);
|
mShapeFPAsset[i].registerRefreshNotify(this);
|
||||||
mCRCFP[i] = 0;
|
mCRCFP[i] = 0;
|
||||||
mValidShapeFP[i] = false;
|
mValidShapeFP[i] = false;
|
||||||
}
|
}
|
||||||
|
|
@ -607,26 +607,26 @@ bool PlayerData::preload(bool server, String &errorStr)
|
||||||
{
|
{
|
||||||
bool shapeError = false;
|
bool shapeError = false;
|
||||||
|
|
||||||
if (mShapeFPAssetId[i] != StringTable->EmptyString())
|
if (mShapeFPAsset[i].notNull())
|
||||||
{
|
{
|
||||||
if (!mShapeFP[i])
|
if (!getShapeFP(i))
|
||||||
{
|
{
|
||||||
errorStr = String::ToString("PlayerData: Couldn't load mounted image %d shape \"%s\"", i, mShapeFPAssetId[i]);
|
errorStr = String::ToString("PlayerData: Couldn't load mounted image %d shape \"%s\"", i, _getShapeFPAssetId(i));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!server && !mShapeFP[i]->preloadMaterialList(mShapeFP[i].getPath()) && NetConnection::filesWereDownloaded())
|
if (!server && !getShapeFP(i)->preloadMaterialList(getShapeFP(i).getPath()) && NetConnection::filesWereDownloaded())
|
||||||
shapeError = true;
|
shapeError = true;
|
||||||
|
|
||||||
if (computeCRC)
|
if (computeCRC)
|
||||||
{
|
{
|
||||||
Con::printf("Validation required for mounted image %d shape: %s", i, mShapeFPAssetId[i]);
|
Con::printf("Validation required for mounted image %d shape: %s", i, _getShapeFPAssetId(i));
|
||||||
|
|
||||||
Torque::FS::FileNodeRef fileRef = Torque::FS::GetFileNode(mShapeFP[i].getPath());
|
Torque::FS::FileNodeRef fileRef = Torque::FS::GetFileNode(getShapeFP(i).getPath());
|
||||||
|
|
||||||
if (!fileRef)
|
if (!fileRef)
|
||||||
{
|
{
|
||||||
errorStr = String::ToString("PlayerData: Mounted image %d loading failed, shape \"%s\" is not found.", i, mShapeFP[i].getPath().getFullPath().c_str());
|
errorStr = String::ToString("PlayerData: Mounted image %d loading failed, shape \"%s\" is not found.", i, getShapeFP(i).getPath().getFullPath().c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -634,7 +634,7 @@ bool PlayerData::preload(bool server, String &errorStr)
|
||||||
mCRCFP[i] = fileRef->getChecksum();
|
mCRCFP[i] = fileRef->getChecksum();
|
||||||
else if (mCRCFP[i] != fileRef->getChecksum())
|
else if (mCRCFP[i] != fileRef->getChecksum())
|
||||||
{
|
{
|
||||||
errorStr = String::ToString("PlayerData: Mounted image %d shape \"%s\" does not match version on server.", i, mShapeFPAssetId[i]);
|
errorStr = String::ToString("PlayerData: Mounted image %d shape \"%s\" does not match version on server.", i, _getShapeFPAssetId(i));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1134,13 +1134,8 @@ void PlayerData::initPersistFields()
|
||||||
|
|
||||||
// Mounted images arrays
|
// Mounted images arrays
|
||||||
addArray( "Mounted Images", ShapeBase::MaxMountedImages );
|
addArray( "Mounted Images", ShapeBase::MaxMountedImages );
|
||||||
addProtectedField("shapeNameFP", TypeShapeFilename, Offset(mShapeFPName, PlayerData), &_setShapeFPData, &defaultProtectedGetFn, ShapeBase::MaxMountedImages,
|
|
||||||
"@brief File name of this player's shape that will be used in conjunction with the corresponding mounted image.\n\n"
|
|
||||||
"These optional parameters correspond to each mounted image slot to indicate a shape that is rendered "
|
|
||||||
"in addition to the mounted image shape. Typically these are a player's arms (or arm) that is "
|
|
||||||
"animated along with the mounted image's state animation sequences.\n", AbstractClassRep::FIELD_HideInInspectors);
|
|
||||||
|
|
||||||
INITPERSISTFIELD_SHAPEASSET_ARRAY(ShapeFP, ShapeBase::MaxMountedImages, PlayerData, "@brief File name of this player's shape that will be used in conjunction with the corresponding mounted image.\n\n"
|
INITPERSISTFIELD_SHAPEASSET_ARRAY_REFACTOR(ShapeFP, ShapeBase::MaxMountedImages, PlayerData, "@brief File name of this player's shape that will be used in conjunction with the corresponding mounted image.\n\n"
|
||||||
"These optional parameters correspond to each mounted image slot to indicate a shape that is rendered "
|
"These optional parameters correspond to each mounted image slot to indicate a shape that is rendered "
|
||||||
"in addition to the mounted image shape. Typically these are a player's arms (or arm) that is "
|
"in addition to the mounted image shape. Typically these are a player's arms (or arm) that is "
|
||||||
"animated along with the mounted image's state animation sequences.\n");
|
"animated along with the mounted image's state animation sequences.\n");
|
||||||
|
|
@ -1340,14 +1335,14 @@ void PlayerData::packData(BitStream* stream)
|
||||||
stream->writeString(imageAnimPrefixFP);
|
stream->writeString(imageAnimPrefixFP);
|
||||||
for (U32 i=0; i<ShapeBase::MaxMountedImages; ++i)
|
for (U32 i=0; i<ShapeBase::MaxMountedImages; ++i)
|
||||||
{
|
{
|
||||||
PACKDATA_ASSET_ARRAY(ShapeFP, i);
|
|
||||||
|
|
||||||
// computeCRC is handled in ShapeBaseData
|
// computeCRC is handled in ShapeBaseData
|
||||||
if (computeCRC)
|
if (computeCRC)
|
||||||
{
|
{
|
||||||
stream->write(mCRCFP[i]);
|
stream->write(mCRCFP[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PACKDATA_ASSET_ARRAY_REFACTOR(ShapeFP, ShapeBase::MaxMountedImages)
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerData::unpackData(BitStream* stream)
|
void PlayerData::unpackData(BitStream* stream)
|
||||||
|
|
@ -1520,14 +1515,14 @@ void PlayerData::unpackData(BitStream* stream)
|
||||||
imageAnimPrefixFP = stream->readSTString();
|
imageAnimPrefixFP = stream->readSTString();
|
||||||
for (U32 i=0; i<ShapeBase::MaxMountedImages; ++i)
|
for (U32 i=0; i<ShapeBase::MaxMountedImages; ++i)
|
||||||
{
|
{
|
||||||
UNPACKDATA_ASSET_ARRAY(ShapeFP, i);
|
|
||||||
|
|
||||||
// computeCRC is handled in ShapeBaseData
|
// computeCRC is handled in ShapeBaseData
|
||||||
if (computeCRC)
|
if (computeCRC)
|
||||||
{
|
{
|
||||||
stream->read(&(mCRCFP[i]));
|
stream->read(&(mCRCFP[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UNPACKDATA_ASSET_ARRAY_REFACTOR(ShapeFP, ShapeBase::MaxMountedImages)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1863,9 +1858,9 @@ bool Player::onNewDataBlock( GameBaseData *dptr, bool reload )
|
||||||
{
|
{
|
||||||
for (U32 i=0; i<ShapeBase::MaxMountedImages; ++i)
|
for (U32 i=0; i<ShapeBase::MaxMountedImages; ++i)
|
||||||
{
|
{
|
||||||
if (bool(mDataBlock->mShapeFP[i]))
|
if (bool(mDataBlock->getShapeFP(i)))
|
||||||
{
|
{
|
||||||
mShapeFPInstance[i] = new TSShapeInstance(mDataBlock->mShapeFP[i], isClientObject());
|
mShapeFPInstance[i] = new TSShapeInstance(mDataBlock->getShapeFP(i), isClientObject());
|
||||||
|
|
||||||
mShapeFPInstance[i]->cloneMaterialList();
|
mShapeFPInstance[i]->cloneMaterialList();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ class OpenVRTrackedObject;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
struct PlayerData: public ShapeBaseData {
|
struct PlayerData: public ShapeBaseData /*protected AssetPtrCallback < already in shapebasedata. */ {
|
||||||
typedef ShapeBaseData Parent;
|
typedef ShapeBaseData Parent;
|
||||||
enum Constants {
|
enum Constants {
|
||||||
RecoverDelayBits = 7,
|
RecoverDelayBits = 7,
|
||||||
|
|
@ -82,8 +82,7 @@ struct PlayerData: public ShapeBaseData {
|
||||||
/// that we don't create a TSThread on the player if we don't
|
/// that we don't create a TSThread on the player if we don't
|
||||||
/// need to.
|
/// need to.
|
||||||
|
|
||||||
DECLARE_SHAPEASSET_ARRAY(PlayerData, ShapeFP, ShapeBase::MaxMountedImages, onShapeChanged); ///< Used to render with mounted images in first person [optional]
|
DECLARE_SHAPEASSET_ARRAY_REFACTOR(PlayerData, ShapeFP, ShapeBase::MaxMountedImages)
|
||||||
DECLARE_ASSET_ARRAY_SETGET(PlayerData, ShapeFP);
|
|
||||||
|
|
||||||
StringTableEntry imageAnimPrefixFP; ///< Passed along to mounted images to modify
|
StringTableEntry imageAnimPrefixFP; ///< Passed along to mounted images to modify
|
||||||
/// animation sequences played in first person. [optional]
|
/// animation sequences played in first person. [optional]
|
||||||
|
|
@ -391,6 +390,11 @@ struct PlayerData: public ShapeBaseData {
|
||||||
DECLARE_CALLBACK( void, onEnterMissionArea, ( Player* obj ) );
|
DECLARE_CALLBACK( void, onEnterMissionArea, ( Player* obj ) );
|
||||||
DECLARE_CALLBACK( void, onLeaveMissionArea, ( Player* obj ) );
|
DECLARE_CALLBACK( void, onLeaveMissionArea, ( Player* obj ) );
|
||||||
/// @}
|
/// @}
|
||||||
|
protected:
|
||||||
|
void onAssetRefreshed(AssetPtrBase* pAssetPtrBase) override
|
||||||
|
{
|
||||||
|
reloadOnLocalClient();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue