Exposed EmitSound_t and related constants to VScript and added hooks for modifying an entity's emitted sounds on both the server and client

This commit is contained in:
Blixibon 2021-09-19 14:52:18 -05:00
parent 55e75529bb
commit 62f4d6f872
8 changed files with 204 additions and 3 deletions

View File

@ -429,7 +429,8 @@ BEGIN_RECV_TABLE_NOBASE( C_BaseEntity, DT_AnimTimeMustBeFirst )
END_RECV_TABLE() END_RECV_TABLE()
#ifdef MAPBASE_VSCRIPT #ifdef MAPBASE_VSCRIPT
ScriptHook_t CBaseEntity::g_Hook_UpdateOnRemove; ScriptHook_t C_BaseEntity::g_Hook_UpdateOnRemove;
ScriptHook_t C_BaseEntity::g_Hook_ModifyEmitSoundParams;
#endif #endif
BEGIN_ENT_SCRIPTDESC_ROOT( C_BaseEntity, "Root class of all client-side entities" ) BEGIN_ENT_SCRIPTDESC_ROOT( C_BaseEntity, "Root class of all client-side entities" )
@ -555,7 +556,11 @@ BEGIN_ENT_SCRIPTDESC_ROOT( C_BaseEntity, "Root class of all client-side entities
DEFINE_SCRIPTFUNC_NAMED( ScriptSetContextThink, "SetContextThink", "Set a think function on this entity." ) DEFINE_SCRIPTFUNC_NAMED( ScriptSetContextThink, "SetContextThink", "Set a think function on this entity." )
DEFINE_SIMPLE_SCRIPTHOOK( CBaseEntity::g_Hook_UpdateOnRemove, "UpdateOnRemove", FIELD_VOID, "Called when the entity is being removed." ) DEFINE_SIMPLE_SCRIPTHOOK( C_BaseEntity::g_Hook_UpdateOnRemove, "UpdateOnRemove", FIELD_VOID, "Called when the entity is being removed." )
BEGIN_SCRIPTHOOK( C_BaseEntity::g_Hook_ModifyEmitSoundParams, "ModifyEmitSoundParams", FIELD_VOID, "Called every time a sound is emitted on this entity, allowing for its parameters to be modified." )
DEFINE_SCRIPTHOOK_PARAM( "params", FIELD_HSCRIPT )
END_SCRIPTHOOK()
#endif // MAPBASE_VSCRIPT #endif // MAPBASE_VSCRIPT

View File

@ -296,6 +296,7 @@ public:
CScriptScope m_ScriptScope; CScriptScope m_ScriptScope;
static ScriptHook_t g_Hook_UpdateOnRemove; static ScriptHook_t g_Hook_UpdateOnRemove;
static ScriptHook_t g_Hook_ModifyEmitSoundParams;
#endif #endif
// IClientUnknown overrides. // IClientUnknown overrides.

View File

@ -2242,6 +2242,8 @@ ScriptHook_t CBaseEntity::g_Hook_FireBullets;
ScriptHook_t CBaseEntity::g_Hook_OnDeath; ScriptHook_t CBaseEntity::g_Hook_OnDeath;
ScriptHook_t CBaseEntity::g_Hook_OnKilledOther; ScriptHook_t CBaseEntity::g_Hook_OnKilledOther;
ScriptHook_t CBaseEntity::g_Hook_HandleInteraction; ScriptHook_t CBaseEntity::g_Hook_HandleInteraction;
ScriptHook_t CBaseEntity::g_Hook_ModifyEmitSoundParams;
ScriptHook_t CBaseEntity::g_Hook_ModifySentenceParams;
#endif #endif
BEGIN_ENT_SCRIPTDESC_ROOT( CBaseEntity, "Root class of all server-side entities" ) BEGIN_ENT_SCRIPTDESC_ROOT( CBaseEntity, "Root class of all server-side entities" )
@ -2518,6 +2520,14 @@ BEGIN_ENT_SCRIPTDESC_ROOT( CBaseEntity, "Root class of all server-side entities"
//DEFINE_SCRIPTHOOK_PARAM( "data", FIELD_VARIANT ) //DEFINE_SCRIPTHOOK_PARAM( "data", FIELD_VARIANT )
DEFINE_SCRIPTHOOK_PARAM( "sourceEnt", FIELD_HSCRIPT ) DEFINE_SCRIPTHOOK_PARAM( "sourceEnt", FIELD_HSCRIPT )
END_SCRIPTHOOK() END_SCRIPTHOOK()
BEGIN_SCRIPTHOOK( CBaseEntity::g_Hook_ModifyEmitSoundParams, "ModifyEmitSoundParams", FIELD_VOID, "Called every time a sound is emitted on this entity, allowing for its parameters to be modified." )
DEFINE_SCRIPTHOOK_PARAM( "params", FIELD_HSCRIPT )
END_SCRIPTHOOK()
BEGIN_SCRIPTHOOK( CBaseEntity::g_Hook_ModifySentenceParams, "ModifySentenceParams", FIELD_VOID, "Called every time a sentence is emitted on this entity, allowing for its parameters to be modified." )
DEFINE_SCRIPTHOOK_PARAM( "params", FIELD_HSCRIPT )
END_SCRIPTHOOK()
#endif #endif
END_SCRIPTDESC(); END_SCRIPTDESC();

View File

@ -1537,6 +1537,12 @@ public:
void GenderExpandString( char const *in, char *out, int maxlen ); void GenderExpandString( char const *in, char *out, int maxlen );
virtual void ModifyEmitSoundParams( EmitSound_t &params ); virtual void ModifyEmitSoundParams( EmitSound_t &params );
#ifdef MAPBASE
// Same as above, but for sentences
// (which don't actually have EmitSound_t params)
virtual void ModifySentenceParams( int &iSentenceIndex, int &iChannel, float &flVolume, soundlevel_t &iSoundlevel, int &iFlags, int &iPitch,
const Vector **pOrigin, const Vector **pDirection, bool &bUpdatePositions, float &soundtime, int &iSpecialDSP, int &iSpeakerIndex );
#endif
static float GetSoundDuration( const char *soundname, char const *actormodel ); static float GetSoundDuration( const char *soundname, char const *actormodel );
@ -2155,6 +2161,8 @@ public:
static ScriptHook_t g_Hook_OnDeath; static ScriptHook_t g_Hook_OnDeath;
static ScriptHook_t g_Hook_OnKilledOther; static ScriptHook_t g_Hook_OnKilledOther;
static ScriptHook_t g_Hook_HandleInteraction; static ScriptHook_t g_Hook_HandleInteraction;
static ScriptHook_t g_Hook_ModifyEmitSoundParams;
static ScriptHook_t g_Hook_ModifySentenceParams;
#endif #endif
string_t m_iszVScripts; string_t m_iszVScripts;

View File

@ -1451,6 +1451,13 @@ void CBaseEntity::EmitSentenceByIndex( IRecipientFilter& filter, int iEntIndex,
if ( bSwallowed ) if ( bSwallowed )
return; return;
CBaseEntity *pEntity = UTIL_EntityByIndex( iEntIndex );
if ( pEntity )
{
pEntity->ModifySentenceParams( iSentenceIndex, iChannel, flVolume, iSoundlevel, iFlags, iPitch,
&pOrigin, &pDirection, bUpdatePositions, soundtime, iSpecialDSP, iSpeakerIndex );
}
enginesound->EmitSentenceByIndex( filter, iEntIndex, iChannel, iSentenceIndex, enginesound->EmitSentenceByIndex( filter, iEntIndex, iChannel, iSentenceIndex,
flVolume, iSoundlevel, iFlags, iPitch * GetSoundPitchScale(), iSpecialDSP, pOrigin, pDirection, &soundOrigins, bUpdatePositions, soundtime, iSpeakerIndex ); flVolume, iSoundlevel, iFlags, iPitch * GetSoundPitchScale(), iSpecialDSP, pOrigin, pDirection, &soundOrigins, bUpdatePositions, soundtime, iSpeakerIndex );
} }

View File

@ -327,9 +327,71 @@ void RegisterSharedScriptConstants()
ScriptRegisterConstantNamed( g_pScriptVM, Vector( ROPE_GRAVITY ), "ROPE_GRAVITY", "Default rope gravity vector." ); ScriptRegisterConstantNamed( g_pScriptVM, Vector( ROPE_GRAVITY ), "ROPE_GRAVITY", "Default rope gravity vector." );
//
// Sounds
//
ScriptRegisterConstant( g_pScriptVM, CHAN_REPLACE, "The sound channel used when playing sounds through console commands." );
ScriptRegisterConstant( g_pScriptVM, CHAN_AUTO, "The default generic sound channel." );
ScriptRegisterConstant( g_pScriptVM, CHAN_WEAPON, "The sound channel for player and NPC weapons." );
ScriptRegisterConstant( g_pScriptVM, CHAN_VOICE, "The sound channel used for dialogue, voice lines, etc." );
ScriptRegisterConstant( g_pScriptVM, CHAN_ITEM, "The sound channel used for generic physics impact sounds, health/suit chargers, +use sounds." );
ScriptRegisterConstant( g_pScriptVM, CHAN_BODY, "The sound channel used for clothing, ragdoll impacts, footsteps, knocking/pounding/punching etc." );
ScriptRegisterConstant( g_pScriptVM, CHAN_STREAM, "The sound channel for sounds that can be delayed by an async load, i.e. aren't responses to particular events." );
ScriptRegisterConstant( g_pScriptVM, CHAN_STATIC, "The sound channel for constant/background sound that doesn't require any reaction." );
ScriptRegisterConstant( g_pScriptVM, CHAN_VOICE2, "An additional sound channel for voices. Used in TF2 for the announcer." );
ScriptRegisterConstant( g_pScriptVM, CHAN_VOICE_BASE, "The sound channel used for network voice data (online voice communications)." );
ScriptRegisterConstant( g_pScriptVM, VOL_NORM, "The standard volume value." );
ScriptRegisterConstant( g_pScriptVM, PITCH_NORM, "The standard pitch value." );
ScriptRegisterConstant( g_pScriptVM, PITCH_LOW, "The standard low pitch value." );
ScriptRegisterConstant( g_pScriptVM, PITCH_HIGH, "The standard high pitch value." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_NONE, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_20dB, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_25dB, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_30dB, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_35dB, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_40dB, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_45dB, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_50dB, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_55dB, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_IDLE, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_60dB, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_65dB, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_STATIC, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_70dB, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_NORM, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_75dB, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_80dB, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_TALKING, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_85dB, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_90dB, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_95dB, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_100dB, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_105dB, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_110dB, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_120dB, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_130dB, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_GUNFIRE, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_140dB, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_150dB, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SNDLVL_180dB, "A standard value used for a sound's sound level." );
ScriptRegisterConstant( g_pScriptVM, SND_CHANGE_VOL, "Indicates a sound is a volume change to an already-playing sound." );
ScriptRegisterConstant( g_pScriptVM, SND_CHANGE_PITCH, "Indicates a sound is a pitch change to an already-playing sound." );
ScriptRegisterConstant( g_pScriptVM, SND_STOP, "Indicates a sound is stopping an already-playing sound." );
ScriptRegisterConstant( g_pScriptVM, SND_SPAWNING, "Indicates a sound is spawning, used in some cases for ambients. Not networked." );
ScriptRegisterConstant( g_pScriptVM, SND_DELAY, "Indicates a sound has an initial delay." );
ScriptRegisterConstant( g_pScriptVM, SND_STOP_LOOPING, "Stops all looping sounds on an entity." );
ScriptRegisterConstant( g_pScriptVM, SND_SPEAKER, "Indicates a sound is being played again by a microphone through a speaker." );
ScriptRegisterConstant( g_pScriptVM, SND_SHOULDPAUSE, "Forces a sound to pause if the game is paused." );
ScriptRegisterConstant( g_pScriptVM, SND_IGNORE_PHONEMES, "Prevents the entity emitting this sound from using its phonemes (no lip-syncing)." );
ScriptRegisterConstant( g_pScriptVM, SND_IGNORE_NAME, "Used to change all sounds emitted by an entity, regardless of name." );
ScriptRegisterConstant( g_pScriptVM, SND_DO_NOT_OVERWRITE_EXISTING_ON_CHANNEL, "Prevents a sound from interrupting other sounds on a channel (if the channel supports interruption)." );
#ifdef GAME_DLL #ifdef GAME_DLL
// //
// Sound Types, Contexts, and Channels // AI Sounds
// (QueryHearSound hook can use these) // (QueryHearSound hook can use these)
// //
ScriptRegisterConstant( g_pScriptVM, SOUND_NONE, "Sound type used in QueryHearSound hooks, etc." ); ScriptRegisterConstant( g_pScriptVM, SOUND_NONE, "Sound type used in QueryHearSound hooks, etc." );

View File

@ -560,6 +560,52 @@ bool CAnimEventTInstanceHelper::Set( void *p, const char *pszKey, ScriptVariant_
return true; return true;
} }
//-----------------------------------------------------------------------------
// EmitSound_t
//-----------------------------------------------------------------------------
BEGIN_SCRIPTDESC_ROOT_NAMED( ScriptEmitSound_t, "EmitSound_t", "Handle for accessing EmitSound_t info." )
DEFINE_SCRIPT_CONSTRUCTOR()
DEFINE_SCRIPTFUNC( GetChannel, "Gets the sound's channel." )
DEFINE_SCRIPTFUNC( SetChannel, "Gets the sound's channel." )
DEFINE_SCRIPTFUNC( GetSoundName, "Gets the sound's file path or soundscript name." )
DEFINE_SCRIPTFUNC( SetSoundName, "Sets the sound's file path or soundscript name." )
DEFINE_SCRIPTFUNC( GetVolume, "Gets the sound's volume. (Note that this may not apply to soundscripts)" )
DEFINE_SCRIPTFUNC( SetVolume, "Sets the sound's volume. (Note that this may not apply to soundscripts)" )
DEFINE_SCRIPTFUNC( GetSoundLevel, "Gets the sound's level in decibels. (Note that this may not apply to soundscripts)" )
DEFINE_SCRIPTFUNC( SetSoundLevel, "Sets the sound's level in decibels. (Note that this may not apply to soundscripts)" )
DEFINE_SCRIPTFUNC( GetFlags, "Gets the sound's flags. See the 'SND_' set of constants for more information." )
DEFINE_SCRIPTFUNC( SetFlags, "Sets the sound's flags. See the 'SND_' set of constants for more information." )
DEFINE_SCRIPTFUNC( GetSpecialDSP, "Gets the sound's special DSP setting." )
DEFINE_SCRIPTFUNC( SetSpecialDSP, "Sets the sound's special DSP setting." )
DEFINE_SCRIPTFUNC( GetOrigin, "Gets the sound's origin override." )
DEFINE_SCRIPTFUNC( SetOrigin, "Sets the sound's origin override." )
DEFINE_SCRIPTFUNC( GetSoundTime, "Gets the time the sound will begin, relative to Time()." )
DEFINE_SCRIPTFUNC( SetSoundTime, "Sets the time the sound will begin, relative to Time()." )
DEFINE_SCRIPTFUNC( GetEmitCloseCaption, "Gets whether or not the sound will emit closed captioning/subtitles." )
DEFINE_SCRIPTFUNC( SetEmitCloseCaption, "Sets whether or not the sound will emit closed captioning/subtitles." )
DEFINE_SCRIPTFUNC( GetWarnOnMissingCloseCaption, "Gets whether or not the sound will send a message to the console if there is no corresponding closed captioning token." )
DEFINE_SCRIPTFUNC( SetWarnOnMissingCloseCaption, "Sets whether or not the sound will send a message to the console if there is no corresponding closed captioning token." )
DEFINE_SCRIPTFUNC( GetWarnOnDirectWaveReference, "Gets whether or not the sound will send a message to the console if it references a direct sound file instead of a soundscript." )
DEFINE_SCRIPTFUNC( SetWarnOnDirectWaveReference, "Sets whether or not the sound will send a message to the console if it references a direct sound file instead of a soundscript." )
DEFINE_SCRIPTFUNC( GetSpeakerEntity, "Gets the sound's original source if it is being transmitted by a microphone." )
DEFINE_SCRIPTFUNC( SetSpeakerEntity, "Sets the sound's original source if it is being transmitted by a microphone." )
DEFINE_SCRIPTFUNC( GetSoundScriptHandle, "Gets the sound's script handle." )
DEFINE_SCRIPTFUNC( SetSoundScriptHandle, "Sets the sound's script handle." )
END_SCRIPTDESC();
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -744,6 +790,21 @@ static HSCRIPT ScriptCreateRope( HSCRIPT hStart, HSCRIPT hEnd, int iStartAttachm
return ToHScript( pRope ); return ToHScript( pRope );
} }
static void EmitSoundParamsOn( HSCRIPT hParams, HSCRIPT hEnt )
{
CBaseEntity *pEnt = ToEnt( hEnt );
if (!pEnt)
return;
ScriptEmitSound_t *pParams = (ScriptEmitSound_t*)g_pScriptVM->GetInstanceValue( hParams, GetScriptDescForClass( ScriptEmitSound_t ) );
if (!pParams)
return;
CPASAttenuationFilter filter( pEnt, pParams->m_pSoundName );
CBaseEntity::EmitSound( filter, pEnt->entindex(), *pParams );
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Simple particle effect dispatch // Simple particle effect dispatch
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -909,6 +970,8 @@ void RegisterSharedScriptFunctions()
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCreateRope, "CreateRope", "Creates a single rope between two entities. Can optionally follow specific attachments." ); ScriptRegisterFunctionNamed( g_pScriptVM, ScriptCreateRope, "CreateRope", "Creates a single rope between two entities. Can optionally follow specific attachments." );
ScriptRegisterFunction( g_pScriptVM, EmitSoundParamsOn, "Play EmitSound_t params on an entity." );
ScriptRegisterFunctionNamed( g_pScriptVM, ScriptMatcherMatch, "Matcher_Match", "Compares a string to a query using Mapbase's matcher system, supporting wildcards, RS matchers, etc." ); ScriptRegisterFunctionNamed( g_pScriptVM, ScriptMatcherMatch, "Matcher_Match", "Compares a string to a query using Mapbase's matcher system, supporting wildcards, RS matchers, etc." );
ScriptRegisterFunction( g_pScriptVM, Matcher_NamesMatch, "Compares a string to a query using Mapbase's matcher system using wildcards only." ); ScriptRegisterFunction( g_pScriptVM, Matcher_NamesMatch, "Compares a string to a query using Mapbase's matcher system using wildcards only." );
ScriptRegisterFunction( g_pScriptVM, AppearsToBeANumber, "Checks if the given string appears to be a number." ); ScriptRegisterFunction( g_pScriptVM, AppearsToBeANumber, "Checks if the given string appears to be a number." );

View File

@ -130,4 +130,49 @@ class CAnimEventTInstanceHelper : public IScriptInstanceHelper
bool Set( void *p, const char *pszKey, ScriptVariant_t &variant ); bool Set( void *p, const char *pszKey, ScriptVariant_t &variant );
}; };
//-----------------------------------------------------------------------------
// Exposes EmitSound_t to VScript
//-----------------------------------------------------------------------------
struct ScriptEmitSound_t : public EmitSound_t
{
int GetChannel() { return m_nChannel; }
void SetChannel( int nChannel ) { m_nChannel = nChannel; }
const char *GetSoundName() { return m_pSoundName; }
void SetSoundName( const char *pSoundName ) { m_pSoundName = pSoundName; }
float GetVolume() { return m_flVolume; }
void SetVolume( float flVolume ) { m_flVolume = flVolume; }
int GetSoundLevel() { return m_SoundLevel; }
void SetSoundLevel( int iSoundLevel ) { m_SoundLevel = (soundlevel_t)iSoundLevel; }
int GetFlags() { return m_nFlags; }
void SetFlags( int nFlags ) { m_nFlags = nFlags; }
int GetSpecialDSP() { return m_nSpecialDSP; }
void SetSpecialDSP( int nSpecialDSP ) { m_nSpecialDSP = nSpecialDSP; }
ScriptVariant_t GetOrigin() { return m_pOrigin ? *m_pOrigin : ScriptVariant_t(); }
void SetOrigin( ScriptVariant_t origin ) { m_pOrigin = origin.m_pVector; }
float GetSoundTime() { return m_flSoundTime; }
void SetSoundTime( float flSoundTime ) { m_flSoundTime = flSoundTime; }
float GetEmitCloseCaption() { return m_bEmitCloseCaption; }
void SetEmitCloseCaption( bool bEmitCloseCaption ) { m_bEmitCloseCaption = bEmitCloseCaption; }
float GetWarnOnMissingCloseCaption() { return m_bWarnOnMissingCloseCaption; }
void SetWarnOnMissingCloseCaption( bool bWarnOnMissingCloseCaption ) { m_bWarnOnMissingCloseCaption = bWarnOnMissingCloseCaption; }
float GetWarnOnDirectWaveReference() { return m_bWarnOnDirectWaveReference; }
void SetWarnOnDirectWaveReference( bool bWarnOnDirectWaveReference ) { m_bWarnOnDirectWaveReference = bWarnOnDirectWaveReference; }
int GetSpeakerEntity() { return m_nSpeakerEntity; }
void SetSpeakerEntity( int nSpeakerEntity ) { m_nSpeakerEntity = nSpeakerEntity; }
int GetSoundScriptHandle() { return m_hSoundScriptHandle; }
void SetSoundScriptHandle( int hSoundScriptHandle ) { m_hSoundScriptHandle = hSoundScriptHandle; }
};
#endif #endif