Просмотр исходного кода

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.

marauder2k7 3 лет назад
Родитель
Сommit
1c14dc5ec4
2 измененных файлов с 35 добавлено и 19 удалено
  1. 11 4
      Engine/source/T3D/shapeBase.h
  2. 24 15
      Engine/source/T3D/shapeImage.cpp

+ 11 - 4
Engine/source/T3D/shapeBase.h

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

+ 24 - 15
Engine/source/T3D/shapeImage.cpp

@@ -132,7 +132,7 @@ ShapeBaseImageData::StateData::StateData()
    loaded = IgnoreLoaded;
    spin = IgnoreSpin;
    recoil = NoRecoil;
-   sound = 0;
+   //sound = 0;
    emitter = NULL;
    shapeSequence = NULL;
    shapeSequenceScale = true;
@@ -256,7 +256,7 @@ ShapeBaseImageData::ShapeBaseImageData()
       stateShapeSequence[i] = 0;
       stateScaleShapeSequence[i] = false;
 
-      stateSound[i] = 0;
+      INIT_SOUNDASSET_ARRAY(stateSound, i);
       stateScript[i] = 0;
       stateEmitter[i] = 0;
       stateEmitterTime[i] = 0;
@@ -303,6 +303,7 @@ ShapeBaseImageData::ShapeBaseImageData()
    camShakeDuration = 1.5f;
    camShakeRadius = 3.0f;
    camShakeFalloff = 10.0f;
+   
 }
 
 ShapeBaseImageData::~ShapeBaseImageData()
@@ -368,7 +369,7 @@ bool ShapeBaseImageData::onAdd()
          s.shapeSequence = stateShapeSequence[i];
          s.shapeSequenceScale = stateScaleShapeSequence[i];
 
-         s.sound = stateSound[i];
+         _setstateSound(getstateSound(i),i);
          s.script = stateScript[i];
          s.emitter = stateEmitter[i];
          s.emitterTime = stateEmitterTime[i];
@@ -419,10 +420,14 @@ bool ShapeBaseImageData::preload(bool server, String &errorStr)
          if (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");
-               
-         String str;
-         if( !sfxResolve( &state[ i ].sound, str ) )
-            Con::errorf( ConsoleLogEntry::General, str.c_str() );
+
+         if (getstateSound(i) != StringTable->EmptyString())
+         {
+            _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,
          "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,
-         "Sound to play on entry to this state." );
+      INITPERSISTFIELD_SOUNDASSET_ARRAY(stateSound, MaxStates, ShapeBaseImageData, "State sound.");
+
       addField( "stateScript", TypeCaseString, Offset(stateScript, ShapeBaseImageData), MaxStates,
          "@brief Method to execute on entering this state.\n\n"
          "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->writeFlag(useRemainderDT);
@@ -1345,7 +1350,7 @@ void ShapeBaseImageData::unpackData(BitStream* stream)
          else
             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);
    }
-
    // 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++)      
          SFX_DELETE((*i));    
@@ -2764,12 +2770,15 @@ void ShapeBase::setImageState(U32 imageSlot, U32 newState,bool force)
    }  
 
    // Play sound
-   if( stateData.sound && isGhost() )
+   if( image.dataBlock->getstateSound(newState) && isGhost() )
    {
       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
    updateAnimThread(imageSlot, imageShapeIndex, lastState);
    for (U32 i=0; i<ShapeBaseImageData::MaxShapes; ++i)