The beast is ready for a look over.

Can't have a soundAsset inside a struct. If we could this might work better.
PrevState needs to be kept track of for clearing looping sounds before the next state is loaded in. This might cause issues when switching weapons.
This commit is contained in:
marauder2k7 2021-09-29 12:36:02 +01:00
parent d700ea4878
commit 1c14dc5ec4
2 changed files with 35 additions and 19 deletions

View file

@ -73,6 +73,7 @@
// Need full definition visible for SimObjectPtr<ParticleEmitter> // Need full definition visible for SimObjectPtr<ParticleEmitter>
#include "T3D/fx/particleEmitter.h" #include "T3D/fx/particleEmitter.h"
#include "T3D/assets/SoundAsset.h"
class GFXCubemap; class GFXCubemap;
class TSShapeInstance; class TSShapeInstance;
@ -259,11 +260,12 @@ struct ShapeBaseImageData: public GameBaseData {
/// the imageSlot. /// the imageSlot.
ParticleEmitterData* emitter; ///< A particle emitter; this emitter will emit as long as the gun is in this ParticleEmitterData* emitter; ///< A particle emitter; this emitter will emit as long as the gun is in this
/// this state. /// this state.
SFXTrack* sound;
//SFXTrack* sound;
F32 emitterTime; ///< F32 emitterTime; ///<
S32 emitterNode[MaxShapes]; ///< Node ID on the shape to emit from S32 emitterNode[MaxShapes]; ///< Node ID on the shape to emit from
//DECLARE_SOUNDASSET(StateData, Sound);
}; };
/// @name State Data /// @name State Data
/// Individual state data used to initialize struct array /// Individual state data used to initialize struct array
/// @{ /// @{
@ -321,7 +323,10 @@ struct ShapeBaseImageData: public GameBaseData {
bool stateIgnoreLoadedForReady [MaxStates]; bool stateIgnoreLoadedForReady [MaxStates];
SFXTrack* stateSound [MaxStates]; DECLARE_SOUNDASSET_ARRAY(ShapeBaseImageData, stateSound, MaxStates);
DECLARE_SOUNDASSET_ARRAY_SETGET(ShapeBaseImageData, stateSound);
//SFXTrack* stateSound [MaxStates];
const char* stateScript [MaxStates]; const char* stateScript [MaxStates];
ParticleEmitterData* stateEmitter [MaxStates]; ParticleEmitterData* stateEmitter [MaxStates];
@ -662,7 +667,7 @@ public:
DECLARE_CALLBACK( void, onCollision, ( ShapeBase* obj, SceneObject* collObj, VectorF vec, F32 len ) ); DECLARE_CALLBACK( void, onCollision, ( ShapeBase* obj, SceneObject* collObj, VectorF vec, F32 len ) );
DECLARE_CALLBACK( void, onDamage, ( ShapeBase* obj, F32 delta ) ); DECLARE_CALLBACK( void, onDamage, ( ShapeBase* obj, F32 delta ) );
DECLARE_CALLBACK( void, onTrigger, ( ShapeBase* obj, S32 index, bool state ) ); DECLARE_CALLBACK( void, onTrigger, ( ShapeBase* obj, S32 index, bool state ) );
DECLARE_CALLBACK(void, onEndSequence, (ShapeBase* obj, S32 slot, const char* name)); DECLARE_CALLBACK( void, onEndSequence, (ShapeBase* obj, S32 slot, const char* name));
DECLARE_CALLBACK( void, onForceUncloak, ( ShapeBase* obj, const char* reason ) ); DECLARE_CALLBACK( void, onForceUncloak, ( ShapeBase* obj, const char* reason ) );
/// @} /// @}
struct TextureTagRemapping struct TextureTagRemapping
@ -1070,6 +1075,8 @@ protected:
/// @param imageSlot Image slot id /// @param imageSlot Image slot id
/// @param state State id /// @param state State id
/// @param force Force image to state or let it finish then change /// @param force Force image to state or let it finish then change
U32 prevState = 0;
void setImageState(U32 imageSlot, U32 state, bool force = false); void setImageState(U32 imageSlot, U32 state, bool force = false);
void updateAnimThread(U32 imageSlot, S32 imageShapeIndex, ShapeBaseImageData::StateData* lastState=NULL); void updateAnimThread(U32 imageSlot, S32 imageShapeIndex, ShapeBaseImageData::StateData* lastState=NULL);

View file

@ -132,7 +132,7 @@ ShapeBaseImageData::StateData::StateData()
loaded = IgnoreLoaded; loaded = IgnoreLoaded;
spin = IgnoreSpin; spin = IgnoreSpin;
recoil = NoRecoil; recoil = NoRecoil;
sound = 0; //sound = 0;
emitter = NULL; emitter = NULL;
shapeSequence = NULL; shapeSequence = NULL;
shapeSequenceScale = true; shapeSequenceScale = true;
@ -256,7 +256,7 @@ ShapeBaseImageData::ShapeBaseImageData()
stateShapeSequence[i] = 0; stateShapeSequence[i] = 0;
stateScaleShapeSequence[i] = false; stateScaleShapeSequence[i] = false;
stateSound[i] = 0; INIT_SOUNDASSET_ARRAY(stateSound, i);
stateScript[i] = 0; stateScript[i] = 0;
stateEmitter[i] = 0; stateEmitter[i] = 0;
stateEmitterTime[i] = 0; stateEmitterTime[i] = 0;
@ -303,6 +303,7 @@ ShapeBaseImageData::ShapeBaseImageData()
camShakeDuration = 1.5f; camShakeDuration = 1.5f;
camShakeRadius = 3.0f; camShakeRadius = 3.0f;
camShakeFalloff = 10.0f; camShakeFalloff = 10.0f;
} }
ShapeBaseImageData::~ShapeBaseImageData() ShapeBaseImageData::~ShapeBaseImageData()
@ -368,7 +369,7 @@ bool ShapeBaseImageData::onAdd()
s.shapeSequence = stateShapeSequence[i]; s.shapeSequence = stateShapeSequence[i];
s.shapeSequenceScale = stateScaleShapeSequence[i]; s.shapeSequenceScale = stateScaleShapeSequence[i];
s.sound = stateSound[i]; _setstateSound(getstateSound(i),i);
s.script = stateScript[i]; s.script = stateScript[i];
s.emitter = stateEmitter[i]; s.emitter = stateEmitter[i];
s.emitterTime = stateEmitterTime[i]; s.emitterTime = stateEmitterTime[i];
@ -420,9 +421,13 @@ bool ShapeBaseImageData::preload(bool server, String &errorStr)
if (!Sim::findObject(SimObjectId((uintptr_t)state[i].emitter), state[i].emitter)) if (!Sim::findObject(SimObjectId((uintptr_t)state[i].emitter), state[i].emitter))
Con::errorf(ConsoleLogEntry::General, "Error, unable to load emitter for image datablock"); Con::errorf(ConsoleLogEntry::General, "Error, unable to load emitter for image datablock");
String str; if (getstateSound(i) != StringTable->EmptyString())
if( !sfxResolve( &state[ i ].sound, str ) ) {
Con::errorf( ConsoleLogEntry::General, str.c_str() ); _setstateSound(getstateSound(i), i);
if (!getstateSoundProfile(i))
Con::errorf("ShapeBaseImageData::preload() - Could not find profile for asset %s on state %d", getstateSound(i), i);
}
} }
} }
@ -922,8 +927,8 @@ void ShapeBaseImageData::initPersistFields()
addField( "stateScaleShapeSequence", TypeBool, Offset(stateScaleShapeSequence, ShapeBaseImageData), MaxStates, addField( "stateScaleShapeSequence", TypeBool, Offset(stateScaleShapeSequence, ShapeBaseImageData), MaxStates,
"Indicates if the sequence to be played on the mounting shape should be scaled to the length of the state." ); "Indicates if the sequence to be played on the mounting shape should be scaled to the length of the state." );
addField( "stateSound", TypeSFXTrackName, Offset(stateSound, ShapeBaseImageData), MaxStates, INITPERSISTFIELD_SOUNDASSET_ARRAY(stateSound, MaxStates, ShapeBaseImageData, "State sound.");
"Sound to play on entry to this state." );
addField( "stateScript", TypeCaseString, Offset(stateScript, ShapeBaseImageData), MaxStates, addField( "stateScript", TypeCaseString, Offset(stateScript, ShapeBaseImageData), MaxStates,
"@brief Method to execute on entering this state.\n\n" "@brief Method to execute on entering this state.\n\n"
"Scoped to this image class name, then ShapeBaseImageData. The script " "Scoped to this image class name, then ShapeBaseImageData. The script "
@ -1140,7 +1145,7 @@ void ShapeBaseImageData::packData(BitStream* stream)
} }
} }
sfxWrite( stream, s.sound ); PACKDATA_SOUNDASSET_ARRAY(stateSound, i);
} }
stream->write(maxConcurrentSounds); stream->write(maxConcurrentSounds);
stream->writeFlag(useRemainderDT); stream->writeFlag(useRemainderDT);
@ -1345,7 +1350,7 @@ void ShapeBaseImageData::unpackData(BitStream* stream)
else else
s.emitter = 0; s.emitter = 0;
sfxRead( stream, &s.sound ); UNPACKDATA_SOUNDASSET_ARRAY(stateSound, i);
} }
} }
@ -2753,9 +2758,10 @@ void ShapeBase::setImageState(U32 imageSlot, U32 newState,bool force)
{ {
onImageStateAnimation(imageSlot, stateData.shapeSequence, stateData.direction, stateData.shapeSequenceScale, stateData.timeoutValue); onImageStateAnimation(imageSlot, stateData.shapeSequence, stateData.direction, stateData.shapeSequenceScale, stateData.timeoutValue);
} }
// Delete any loooping sounds that were in the previous state. // Delete any loooping sounds that were in the previous state.
if (lastState->sound && lastState->sound->getDescription()->mIsLooping) // this is the crazy bit =/ needs to know prev state in order to stop sounds.
// lastState does not return an id for the prev state so we keep track of it.
if (image.dataBlock->getstateSound(prevState) && image.dataBlock->getstateSoundProfile(prevState)->getDescription()->mIsLooping)
{ {
for(Vector<SFXSource*>::iterator i = image.mSoundSources.begin(); i != image.mSoundSources.end(); i++) for(Vector<SFXSource*>::iterator i = image.mSoundSources.begin(); i != image.mSoundSources.end(); i++)
SFX_DELETE((*i)); SFX_DELETE((*i));
@ -2764,12 +2770,15 @@ void ShapeBase::setImageState(U32 imageSlot, U32 newState,bool force)
} }
// Play sound // Play sound
if( stateData.sound && isGhost() ) if( image.dataBlock->getstateSound(newState) && isGhost() )
{ {
const Point3F& velocity = getVelocity(); const Point3F& velocity = getVelocity();
image.addSoundSource(SFX->createSource( stateData.sound, &getRenderTransform(), &velocity )); image.addSoundSource(SFX->createSource(image.dataBlock->getstateSoundProfile(newState), &getRenderTransform(), &velocity ));
} }
/// update our prevState.
prevState = newState;
// Play animation // Play animation
updateAnimThread(imageSlot, imageShapeIndex, lastState); updateAnimThread(imageSlot, imageShapeIndex, lastState);
for (U32 i=0; i<ShapeBaseImageData::MaxShapes; ++i) for (U32 i=0; i<ShapeBaseImageData::MaxShapes; ++i)