diff options
| author | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
|---|---|---|
| committer | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
| commit | 39ed87570bdb2f86969d4be821c94b722dc71179 (patch) | |
| tree | abc53757f75f40c80278e87650ea92808274aa59 /mp/src/game/server/env_effectsscript.cpp | |
| download | source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip | |
First version of the SOurce SDK 2013
Diffstat (limited to 'mp/src/game/server/env_effectsscript.cpp')
| -rw-r--r-- | mp/src/game/server/env_effectsscript.cpp | 542 |
1 files changed, 542 insertions, 0 deletions
diff --git a/mp/src/game/server/env_effectsscript.cpp b/mp/src/game/server/env_effectsscript.cpp new file mode 100644 index 00000000..a1d8621e --- /dev/null +++ b/mp/src/game/server/env_effectsscript.cpp @@ -0,0 +1,542 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#include "cbase.h"
+#include "baseanimating.h"
+#include "Sprite.h"
+#include "SpriteTrail.h"
+#include <ctype.h>
+#include "animation.h"
+#include "eventlist.h"
+#include "npcevent.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+enum EffectType
+{
+ EFFECT_TYPE_TRAIL = 1,
+ EFFECT_TYPE_SPRITE
+};
+
+
+bool g_bUnget = false;
+unsigned char *buffer;
+char name[ 256 ];
+const char *currenttoken;
+int tokencount;
+char token[ 1204 ];
+
+class CEffectScriptElement
+{
+public:
+
+ CEffectScriptElement();
+
+ char m_szEffectName[128];
+ CHandle<CSpriteTrail> m_pTrail;
+ CHandle<CSprite> m_pSprite;
+ int m_iType;
+ int m_iRenderType;
+
+ int m_iR;
+ int m_iG;
+ int m_iB;
+ int m_iA;
+
+ char m_szAttachment[128];
+ char m_szMaterial[128];
+
+ float m_flScale;
+ float m_flFadeTime;
+ float m_flTextureRes;
+
+ bool m_bStopFollowOnKill;
+
+ bool IsActive( void ) { return m_bActive; }
+ void Activate( void ) { m_bActive = true; }
+ void Deactivate( void ) { m_bActive = false; }
+private:
+
+ bool m_bActive;
+};
+
+CEffectScriptElement::CEffectScriptElement()
+{
+ m_pTrail = NULL;
+ m_pSprite = NULL;
+ m_iType = 0;
+
+ Deactivate();
+ m_iRenderType = kRenderTransAdd;
+
+ m_iR = 255;
+ m_iG = 0;
+ m_iB = 0;
+ m_iA = 255;
+
+ m_flScale = 1.0f;
+ m_flFadeTime = 1.0f;
+ m_flTextureRes = -1.0f;
+ m_bStopFollowOnKill = false;
+}
+
+
+//-----------------------------------------------------------------------------
+// An entity which emits other entities at points
+//-----------------------------------------------------------------------------
+class CEnvEffectsScript : public CBaseAnimating
+{
+public:
+ DECLARE_CLASS( CEnvEffectsScript, CBaseAnimating );
+ DECLARE_DATADESC();
+
+ virtual void Precache();
+ virtual void Spawn();
+ virtual int UpdateTransmitState();
+
+ void InputSetSequence( inputdata_t &inputdata );
+ void ParseScriptFile( void );
+ void LoadFromBuffer( const char *scriptfile, const char *buffer );
+
+ virtual void Think( void );
+
+ void ParseNewEffect( void );
+
+ const char *GetScriptFile( void )
+ {
+ return STRING( m_iszScriptName );
+ }
+
+ void HandleAnimEvent ( animevent_t *pEvent );
+ void TrailEffectEvent( CEffectScriptElement *pEffect );
+ void SpriteEffectEvent( CEffectScriptElement *pEffect );
+
+ CEffectScriptElement *GetScriptElementByName( const char *pName );
+
+private:
+
+ string_t m_iszScriptName;
+
+ CUtlVector< CEffectScriptElement > m_ScriptElements;
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+ bool IsRootCommand( void )
+ {
+ if ( !Q_stricmp( token, "effect" ) )
+ return true;
+
+ return false;
+ }
+};
+
+inline bool ParseToken( void )
+{
+ if ( g_bUnget )
+ {
+ g_bUnget = false;
+ return true;
+ }
+
+ currenttoken = engine->ParseFile( currenttoken, token, sizeof( token ) );
+ tokencount++;
+ return currenttoken != NULL ? true : false;
+}
+
+inline void Unget()
+{
+ g_bUnget = true;
+}
+
+inline bool TokenWaiting( void )
+{
+
+ const char *p = currenttoken;
+ while ( *p && *p!='\n')
+ {
+ // Special handler for // comment blocks
+ if ( *p == '/' && *(p+1) == '/' )
+ return false;
+
+ if ( !V_isspace( *p ) || V_isalnum( *p ) )
+ return true;
+
+ p++;
+ }
+
+ return false;
+}
+
+
+//-----------------------------------------------------------------------------
+// Save/load
+//-----------------------------------------------------------------------------
+BEGIN_DATADESC( CEnvEffectsScript )
+ // Inputs
+ DEFINE_INPUTFUNC( FIELD_STRING, "SetSequence", InputSetSequence ),
+ DEFINE_KEYFIELD( m_iszScriptName, FIELD_STRING, "scriptfile" ),
+ // DEFINE_FIELD( m_ScriptElements, CUtlVector < CEffectScriptElement > ),
+
+ DEFINE_FUNCTION( Think ),
+
+END_DATADESC()
+
+LINK_ENTITY_TO_CLASS( env_effectscript, CEnvEffectsScript );
+
+//-----------------------------------------------------------------------------
+// Should we transmit it to the client?
+//-----------------------------------------------------------------------------
+int CEnvEffectsScript::UpdateTransmitState()
+{
+ return SetTransmitState( FL_EDICT_ALWAYS );
+}
+
+//-----------------------------------------------------------------------------
+// Precache
+//-----------------------------------------------------------------------------
+void CEnvEffectsScript::Precache()
+{
+ BaseClass::Precache();
+ PrecacheModel( STRING( GetModelName() ) );
+
+ if ( m_iszScriptName != NULL_STRING )
+ ParseScriptFile();
+ else
+ Warning( "CEnvEffectsScript with no script!\n" );
+}
+
+//-----------------------------------------------------------------------------
+// Spawn
+//-----------------------------------------------------------------------------
+void CEnvEffectsScript::Spawn()
+{
+ Precache();
+ BaseClass::Spawn();
+
+ // We need a model for its animation sequences even though we don't render it
+ SetModel( STRING( GetModelName() ) );
+
+ AddEffects( EF_NODRAW );
+
+ SetThink( &CEnvEffectsScript::Think );
+ SetNextThink( gpGlobals->curtime + 0.1f );
+}
+
+void CEnvEffectsScript::Think( void )
+{
+ StudioFrameAdvance();
+ DispatchAnimEvents( this );
+
+ SetNextThink( gpGlobals->curtime + 0.1f );
+}
+
+void CEnvEffectsScript::TrailEffectEvent( CEffectScriptElement *pEffect )
+{
+ if ( pEffect->IsActive() == false )
+ {
+ //Only one type of this effect active at a time.
+ if ( pEffect->m_pTrail == NULL )
+ {
+ pEffect->m_pTrail = CSpriteTrail::SpriteTrailCreate( pEffect->m_szMaterial, GetAbsOrigin(), true );
+ pEffect->m_pTrail->FollowEntity( this );
+ pEffect->m_pTrail->SetTransparency( pEffect->m_iRenderType, pEffect->m_iR, pEffect->m_iG, pEffect->m_iB, pEffect->m_iA, kRenderFxNone );
+ pEffect->m_pTrail->SetStartWidth( pEffect->m_flScale );
+ if ( pEffect->m_flTextureRes < 0.0f )
+ {
+ pEffect->m_pTrail->SetTextureResolution( 1.0f / ( 16.0f * pEffect->m_flScale ) );
+ }
+ else
+ {
+ pEffect->m_pTrail->SetTextureResolution( pEffect->m_flTextureRes );
+ }
+ pEffect->m_pTrail->SetLifeTime( pEffect->m_flFadeTime );
+ pEffect->m_pTrail->TurnOn();
+ pEffect->m_pTrail->SetAttachment( this, LookupAttachment( pEffect->m_szAttachment ) );
+
+ pEffect->Activate();
+ }
+ }
+}
+
+void CEnvEffectsScript::SpriteEffectEvent( CEffectScriptElement *pEffect )
+{
+ if ( pEffect->IsActive() == false )
+ {
+ //Only one type of this effect active at a time.
+ if ( pEffect->m_pSprite == NULL )
+ {
+ pEffect->m_pSprite = CSprite::SpriteCreate( pEffect->m_szMaterial, GetAbsOrigin(), true );
+ pEffect->m_pSprite->FollowEntity( this );
+ pEffect->m_pSprite->SetTransparency( pEffect->m_iRenderType, pEffect->m_iR, pEffect->m_iG, pEffect->m_iB, pEffect->m_iA, kRenderFxNone );
+ pEffect->m_pSprite->SetScale( pEffect->m_flScale );
+ pEffect->m_pSprite->TurnOn();
+ pEffect->m_pSprite->SetAttachment( this, LookupAttachment( pEffect->m_szAttachment ) );
+
+ pEffect->Activate();
+ }
+ }
+}
+
+void CEnvEffectsScript::HandleAnimEvent ( animevent_t *pEvent )
+{
+ if ( pEvent->event == AE_START_SCRIPTED_EFFECT )
+ {
+ CEffectScriptElement *pCurrent = GetScriptElementByName( pEvent->options );
+
+ if ( pCurrent )
+ {
+ if ( pCurrent->m_iType == EFFECT_TYPE_TRAIL )
+ TrailEffectEvent( pCurrent );
+ else if ( pCurrent->m_iType == EFFECT_TYPE_SPRITE )
+ SpriteEffectEvent( pCurrent );
+ }
+
+ return;
+ }
+
+ if ( pEvent->event == AE_STOP_SCRIPTED_EFFECT )
+ {
+ CEffectScriptElement *pCurrent = GetScriptElementByName( pEvent->options );
+
+ if ( pCurrent && pCurrent->IsActive() )
+ {
+ pCurrent->Deactivate();
+
+ if ( pCurrent->m_iType == EFFECT_TYPE_TRAIL )
+ {
+ if ( pCurrent->m_bStopFollowOnKill == true )
+ {
+ Vector vOrigin;
+ GetAttachment( pCurrent->m_pTrail->m_nAttachment, vOrigin );
+
+ pCurrent->m_pTrail->StopFollowingEntity();
+
+ pCurrent->m_pTrail->m_hAttachedToEntity = NULL;
+ pCurrent->m_pTrail->m_nAttachment = 0;
+
+ pCurrent->m_pTrail->SetAbsOrigin( vOrigin);
+ }
+
+ pCurrent->m_pTrail->FadeAndDie( pCurrent->m_flFadeTime );
+ pCurrent->m_pTrail = NULL;
+ }
+
+ else if ( pCurrent->m_iType == EFFECT_TYPE_SPRITE )
+ {
+ if ( pCurrent->m_bStopFollowOnKill == true )
+ {
+ Vector vOrigin;
+ GetAttachment( pCurrent->m_pSprite->m_nAttachment, vOrigin );
+
+ pCurrent->m_pSprite->StopFollowingEntity();
+
+ pCurrent->m_pSprite->m_hAttachedToEntity = NULL;
+ pCurrent->m_pSprite->m_nAttachment = 0;
+
+ pCurrent->m_pSprite->SetAbsOrigin( vOrigin);
+ }
+
+ pCurrent->m_pSprite->FadeAndDie( pCurrent->m_flFadeTime );
+ pCurrent->m_pSprite = NULL;
+ }
+ }
+ return;
+ }
+
+ BaseClass::HandleAnimEvent( pEvent );
+}
+//-----------------------------------------------------------------------------
+// Purpose: Input that sets the sequence of the entity
+//-----------------------------------------------------------------------------
+void CEnvEffectsScript::InputSetSequence( inputdata_t &inputdata )
+{
+ if ( inputdata.value.StringID() != NULL_STRING )
+ {
+ int nSequence = LookupSequence( STRING( inputdata.value.StringID() ) );
+ if ( nSequence != ACT_INVALID )
+ {
+ SetSequence( nSequence );
+ ResetSequenceInfo();
+ SetCycle( 0.0f );
+ m_flPlaybackRate = 1.0f;
+ }
+ }
+}
+
+void CEnvEffectsScript::ParseScriptFile( void )
+{
+ int length = 0;
+ m_ScriptElements.RemoveAll();
+ const char *pScriptName = GetScriptFile();
+
+ //Reset everything.
+ g_bUnget = false;
+ currenttoken = NULL;
+ tokencount = 0;
+ memset( token, 0, 1204 );
+ memset( name, 0, 256 );
+
+
+ unsigned char *buffer = (unsigned char *)UTIL_LoadFileForMe( pScriptName, &length );
+ if ( length <= 0 || !buffer )
+ {
+ DevMsg( 1, "CEnvEffectsScript: failed to load %s\n", pScriptName );
+ return;
+ }
+
+ currenttoken = (const char *)buffer;
+ LoadFromBuffer( pScriptName, (const char *)buffer );
+
+ UTIL_FreeFile( buffer );
+}
+
+void CEnvEffectsScript::LoadFromBuffer( const char *scriptfile, const char *buffer )
+{
+ while ( 1 )
+ {
+ ParseToken();
+
+ if ( !token[0] )
+ {
+ break;
+ }
+
+ if ( !Q_stricmp( token, "effect" ) )
+ {
+ ParseNewEffect();
+ }
+ else
+ {
+ Warning( "CEnvEffectsScript: Unknown entry type '%s'\n", token );
+ break;
+ }
+ }
+}
+
+void CEnvEffectsScript::ParseNewEffect( void )
+{
+ //Add a new effect to the list.
+ CEffectScriptElement NewElement;
+
+ // Effect Group Name
+ ParseToken();
+ Q_strncpy( NewElement.m_szEffectName, token, sizeof( NewElement.m_szEffectName ) );
+
+ while ( 1 )
+ {
+ ParseToken();
+
+ // Oops, part of next definition
+ if( IsRootCommand() )
+ {
+ Unget();
+ break;
+ }
+
+ if ( !Q_stricmp( token, "{" ) )
+ {
+ while ( 1 )
+ {
+ ParseToken();
+ if ( !Q_stricmp( token, "}" ) )
+ break;
+
+ if ( !Q_stricmp( token, "type" ) )
+ {
+ ParseToken();
+
+ if ( !Q_stricmp( token, "trail" ) )
+ NewElement.m_iType = EFFECT_TYPE_TRAIL;
+ else if ( !Q_stricmp( token, "sprite" ) )
+ NewElement.m_iType = EFFECT_TYPE_SPRITE;
+
+ continue;
+ }
+
+ if ( !Q_stricmp( token, "material" ) )
+ {
+ ParseToken();
+ Q_strncpy( NewElement.m_szMaterial, token, sizeof( NewElement.m_szMaterial ) );
+ PrecacheModel( NewElement.m_szMaterial );
+
+ continue;
+ }
+
+ if ( !Q_stricmp( token, "attachment" ) )
+ {
+ ParseToken();
+ Q_strncpy( NewElement.m_szAttachment, token, sizeof( NewElement.m_szAttachment ) );
+
+ continue;
+ }
+
+ if ( !Q_stricmp( token, "color" ) )
+ {
+ ParseToken();
+ sscanf( token, "%i %i %i %i", &NewElement.m_iR, &NewElement.m_iG, &NewElement.m_iB, &NewElement.m_iA );
+
+ continue;
+ }
+
+ if ( !Q_stricmp( token, "scale" ) )
+ {
+ ParseToken();
+
+ NewElement.m_flScale = atof( token );
+ continue;
+ }
+
+ if ( !Q_stricmp( token, "texturescale" ) )
+ {
+ ParseToken();
+
+ float flTextureScale = atof( token );
+ NewElement.m_flTextureRes = (flTextureScale > 0.0f) ? 1.0f / flTextureScale : 0.0f;
+ continue;
+ }
+
+ if ( !Q_stricmp( token, "fadetime" ) )
+ {
+ ParseToken();
+
+ NewElement.m_flFadeTime = atof( token );
+ continue;
+ }
+
+ if ( !Q_stricmp( token, "stopfollowonkill" ) )
+ {
+ ParseToken();
+
+ NewElement.m_bStopFollowOnKill = !!atoi( token );
+ continue;
+ }
+
+ }
+ break;
+ }
+ }
+
+ m_ScriptElements.AddToTail( NewElement );
+}
+
+CEffectScriptElement *CEnvEffectsScript::GetScriptElementByName( const char *pName )
+{
+ for ( int i = 0; i < m_ScriptElements.Count(); i++ )
+ {
+ CEffectScriptElement *pCurrent = &m_ScriptElements.Element( i );
+
+ if ( pCurrent && !Q_stricmp( pCurrent->m_szEffectName, pName ) )
+ {
+ return pCurrent;
+ }
+ }
+
+ return NULL;
+}
|