//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: 
//
// $NoKeywords: $
//
//=============================================================================//
#include "cbase.h"
#include "smoke_trail.h"
#include "dt_send.h"

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"

#define SMOKETRAIL_ENTITYNAME		"env_smoketrail"
#define SPORETRAIL_ENTITYNAME		"env_sporetrail"
#define SPOREEXPLOSION_ENTITYNAME	"env_sporeexplosion"

//-----------------------------------------------------------------------------
//Data table
//-----------------------------------------------------------------------------
IMPLEMENT_SERVERCLASS_ST(SmokeTrail, DT_SmokeTrail)
	SendPropFloat(SENDINFO(m_SpawnRate), 8, 0, 1, 1024),
	SendPropVector(SENDINFO(m_StartColor), 8, 0, 0, 1),
	SendPropVector(SENDINFO(m_EndColor), 8, 0, 0, 1),
	SendPropFloat(SENDINFO(m_ParticleLifetime), 16, SPROP_ROUNDUP, 0.1, 100),
	SendPropFloat(SENDINFO(m_StopEmitTime), 0, SPROP_NOSCALE),
	SendPropFloat(SENDINFO(m_MinSpeed), -1, SPROP_NOSCALE),
	SendPropFloat(SENDINFO(m_MaxSpeed), -1, SPROP_NOSCALE),
	SendPropFloat(SENDINFO(m_MinDirectedSpeed), -1, SPROP_NOSCALE),
	SendPropFloat(SENDINFO(m_MaxDirectedSpeed), -1, SPROP_NOSCALE),
	SendPropFloat(SENDINFO(m_StartSize), -1, SPROP_NOSCALE),
	SendPropFloat(SENDINFO(m_EndSize), -1, SPROP_NOSCALE),
	SendPropFloat(SENDINFO(m_SpawnRadius), -1, SPROP_NOSCALE),
	SendPropBool(SENDINFO(m_bEmit) ),
	SendPropInt(SENDINFO(m_nAttachment), 32 ),	
	SendPropFloat(SENDINFO(m_Opacity), -1, SPROP_NOSCALE),
END_SEND_TABLE()

LINK_ENTITY_TO_CLASS(env_smoketrail, SmokeTrail);

BEGIN_DATADESC( SmokeTrail )

	DEFINE_FIELD( m_StartColor, FIELD_VECTOR ),
	DEFINE_FIELD( m_EndColor, FIELD_VECTOR ),
	DEFINE_KEYFIELD( m_Opacity, FIELD_FLOAT, "opacity" ),
	DEFINE_KEYFIELD( m_SpawnRate, FIELD_FLOAT, "spawnrate" ),
	DEFINE_KEYFIELD( m_ParticleLifetime, FIELD_FLOAT, "lifetime" ),
	DEFINE_FIELD( m_StopEmitTime, FIELD_TIME ),
	DEFINE_KEYFIELD( m_MinSpeed, FIELD_FLOAT, "minspeed" ),
	DEFINE_KEYFIELD( m_MaxSpeed, FIELD_FLOAT, "maxspeed" ),
	DEFINE_KEYFIELD( m_MinDirectedSpeed, FIELD_FLOAT, "mindirectedspeed" ),
	DEFINE_KEYFIELD( m_MaxDirectedSpeed, FIELD_FLOAT, "maxdirectedspeed" ),
	DEFINE_KEYFIELD( m_StartSize, FIELD_FLOAT, "startsize" ),
	DEFINE_KEYFIELD( m_EndSize, FIELD_FLOAT, "endsize" ),
	DEFINE_KEYFIELD( m_SpawnRadius, FIELD_FLOAT, "spawnradius" ),
	DEFINE_FIELD( m_bEmit, FIELD_BOOLEAN ),
	DEFINE_FIELD( m_nAttachment, FIELD_INTEGER ),

END_DATADESC()


//-----------------------------------------------------------------------------
// Purpose: 
// Output : 
//-----------------------------------------------------------------------------
SmokeTrail::SmokeTrail()
{
	m_SpawnRate = 10;
	m_StartColor.GetForModify().Init(0.5, 0.5, 0.5);
	m_EndColor.GetForModify().Init(0,0,0);
	m_ParticleLifetime = 5;
	m_StopEmitTime = 0; // Don't stop emitting particles
	m_MinSpeed = 2;
	m_MaxSpeed = 4;
	m_MinDirectedSpeed = m_MaxDirectedSpeed = 0;
	m_StartSize = 35;
	m_EndSize = 55;
	m_SpawnRadius = 2;
	m_bEmit = true;
	m_nAttachment	= 0;
	m_Opacity = 0.5f;
}


//-----------------------------------------------------------------------------
// Parse data from a map file
//-----------------------------------------------------------------------------
bool SmokeTrail::KeyValue( const char *szKeyName, const char *szValue ) 
{
	if ( FStrEq( szKeyName, "startcolor" ) )
	{
		color32 tmp;
		UTIL_StringToColor32( &tmp, szValue );
		m_StartColor.GetForModify().Init( tmp.r / 255.0f, tmp.g / 255.0f, tmp.b / 255.0f );
		return true;
	}

	if ( FStrEq( szKeyName, "endcolor" ) )
	{
		color32 tmp;
		UTIL_StringToColor32( &tmp, szValue );
		m_EndColor.GetForModify().Init( tmp.r / 255.0f, tmp.g / 255.0f, tmp.b / 255.0f );
		return true;
	}

	if ( FStrEq( szKeyName, "emittime" ) )
	{
		m_StopEmitTime = gpGlobals->curtime + atof( szValue );
		return true;
	}

	return BaseClass::KeyValue( szKeyName, szValue );
}


//-----------------------------------------------------------------------------
// Purpose :
// Input   :
// Output  :
//-----------------------------------------------------------------------------
void SmokeTrail::SetEmit(bool bVal)
{
	m_bEmit = bVal;
}


//-----------------------------------------------------------------------------
// Purpose: 
// Output : SmokeTrail*
//-----------------------------------------------------------------------------
SmokeTrail* SmokeTrail::CreateSmokeTrail()
{
	CBaseEntity *pEnt = CreateEntityByName(SMOKETRAIL_ENTITYNAME);
	if(pEnt)
	{
		SmokeTrail *pSmoke = dynamic_cast<SmokeTrail*>(pEnt);
		if(pSmoke)
		{
			pSmoke->Activate();
			return pSmoke;
		}
		else
		{
			UTIL_Remove(pEnt);
		}
	}

	return NULL;
}

//-----------------------------------------------------------------------------
// Purpose: Attach the smoke trail to an entity or point 
// Input  : index - entity that has the attachment
//			attachment - point to attach to
//-----------------------------------------------------------------------------
void SmokeTrail::FollowEntity( CBaseEntity *pEntity, const char *pAttachmentName )
{
	// For attachments
	if ( pAttachmentName && pEntity && pEntity->GetBaseAnimating() )
	{
		m_nAttachment = pEntity->GetBaseAnimating()->LookupAttachment( pAttachmentName );
	}
	else
	{
		m_nAttachment = 0;
	}

	BaseClass::FollowEntity( pEntity );
}


//==================================================
// RocketTrail
//==================================================

//Data table
IMPLEMENT_SERVERCLASS_ST(RocketTrail, DT_RocketTrail)
	SendPropFloat(SENDINFO(m_SpawnRate), 8, 0, 1, 1024),
	SendPropVector(SENDINFO(m_StartColor), 8, 0, 0, 1),
	SendPropVector(SENDINFO(m_EndColor), 8, 0, 0, 1),
	SendPropFloat(SENDINFO(m_ParticleLifetime), 16, SPROP_ROUNDUP, 0.1, 100),
	SendPropFloat(SENDINFO(m_StopEmitTime), 0, SPROP_NOSCALE),
	SendPropFloat(SENDINFO(m_MinSpeed), -1, SPROP_NOSCALE),
	SendPropFloat(SENDINFO(m_MaxSpeed), -1, SPROP_NOSCALE),
	SendPropFloat(SENDINFO(m_StartSize), -1, SPROP_NOSCALE),
	SendPropFloat(SENDINFO(m_EndSize), -1, SPROP_NOSCALE),
	SendPropFloat(SENDINFO(m_SpawnRadius), -1, SPROP_NOSCALE),
	SendPropBool(SENDINFO(m_bEmit)),
	SendPropInt(SENDINFO(m_nAttachment), 32 ),	
	SendPropFloat(SENDINFO(m_Opacity), -1, SPROP_NOSCALE),
	SendPropInt	(SENDINFO(m_bDamaged), 1, SPROP_UNSIGNED),
	SendPropFloat(SENDINFO(m_flFlareScale), -1, SPROP_NOSCALE),
END_SEND_TABLE()

LINK_ENTITY_TO_CLASS( env_rockettrail, RocketTrail );

BEGIN_DATADESC( RocketTrail )

	DEFINE_FIELD( m_StartColor, FIELD_VECTOR ),
	DEFINE_FIELD( m_EndColor, FIELD_VECTOR ),
	DEFINE_FIELD( m_Opacity, FIELD_FLOAT ),
	DEFINE_FIELD( m_SpawnRate, FIELD_FLOAT ),
	DEFINE_FIELD( m_ParticleLifetime, FIELD_FLOAT ),
	DEFINE_FIELD( m_StopEmitTime, FIELD_TIME ),
	DEFINE_FIELD( m_MinSpeed, FIELD_FLOAT ),
	DEFINE_FIELD( m_MaxSpeed, FIELD_FLOAT ),
	DEFINE_FIELD( m_StartSize, FIELD_FLOAT ),
	DEFINE_FIELD( m_EndSize, FIELD_FLOAT ),
	DEFINE_FIELD( m_SpawnRadius, FIELD_FLOAT ),
	DEFINE_FIELD( m_bEmit, FIELD_BOOLEAN ),
	DEFINE_FIELD( m_nAttachment, FIELD_INTEGER ),
	DEFINE_FIELD( m_bDamaged, FIELD_BOOLEAN ),
	DEFINE_FIELD( m_flFlareScale, FIELD_FLOAT ),

END_DATADESC()

//-----------------------------------------------------------------------------
// Purpose: 
// Output : 
//-----------------------------------------------------------------------------
RocketTrail::RocketTrail()
{
	m_SpawnRate = 10;
	m_StartColor.GetForModify().Init(0.5, 0.5, 0.5);
	m_EndColor.GetForModify().Init(0,0,0);
	m_ParticleLifetime = 5;
	m_StopEmitTime = 0; // Don't stop emitting particles
	m_MinSpeed = 2;
	m_MaxSpeed = 4;
	m_StartSize = 35;
	m_EndSize = 55;
	m_SpawnRadius = 2;
	m_bEmit = true;
	m_nAttachment	= 0;
	m_Opacity = 0.5f;
	m_flFlareScale = 1.5;
}

//------------------------------------------------------------------------------
// Purpose :
// Input   :
// Output  :
//------------------------------------------------------------------------------
void RocketTrail::SetEmit(bool bVal)
{
	m_bEmit = bVal;
}

//-----------------------------------------------------------------------------
// Purpose: 
// Output : SmokeTrail*
//-----------------------------------------------------------------------------
RocketTrail* RocketTrail::CreateRocketTrail()
{
	CBaseEntity *pEnt = CreateEntityByName( "env_rockettrail" );
	
	if( pEnt != NULL )
	{
		RocketTrail *pTrail = dynamic_cast<RocketTrail*>(pEnt);
		
		if( pTrail != NULL )
		{
			pTrail->Activate();
			return pTrail;
		}
		else
		{
			UTIL_Remove( pEnt );
		}
	}

	return NULL;
}

//-----------------------------------------------------------------------------
// Purpose: Attach the smoke trail to an entity or point 
// Input  : index - entity that has the attachment
//			attachment - point to attach to
//-----------------------------------------------------------------------------
void RocketTrail::FollowEntity( CBaseEntity *pEntity, const char *pAttachmentName )
{
	// For attachments
	if ( pAttachmentName && pEntity && pEntity->GetBaseAnimating() )
	{
		m_nAttachment = pEntity->GetBaseAnimating()->LookupAttachment( pAttachmentName );
	}
	else
	{
		m_nAttachment = 0;
	}

	BaseClass::FollowEntity( pEntity );
}

//==================================================
// SporeTrail
//==================================================

IMPLEMENT_SERVERCLASS_ST( SporeTrail, DT_SporeTrail )
	SendPropFloat	(SENDINFO(m_flSpawnRate), 8, 0, 1, 1024),
	SendPropVector	(SENDINFO(m_vecEndColor), 8, 0, 0, 1),
	SendPropFloat	(SENDINFO(m_flParticleLifetime), 16, SPROP_ROUNDUP, 0.1, 100),
	SendPropFloat	(SENDINFO(m_flStartSize), -1, SPROP_NOSCALE),
	SendPropFloat	(SENDINFO(m_flEndSize), -1, SPROP_NOSCALE),
	SendPropFloat	(SENDINFO(m_flSpawnRadius), -1, SPROP_NOSCALE),
	SendPropBool	(SENDINFO(m_bEmit)),
END_SEND_TABLE()

LINK_ENTITY_TO_CLASS(env_sporetrail, SporeTrail);

BEGIN_DATADESC( SporeTrail )

	DEFINE_FIELD( m_vecEndColor, FIELD_VECTOR ),
	DEFINE_FIELD( m_flSpawnRate, FIELD_FLOAT ),
	DEFINE_FIELD( m_flParticleLifetime, FIELD_FLOAT ),
	DEFINE_FIELD( m_flStartSize, FIELD_FLOAT ),
	DEFINE_FIELD( m_flEndSize, FIELD_FLOAT ),
	DEFINE_FIELD( m_flSpawnRadius, FIELD_FLOAT ),
	DEFINE_FIELD( m_bEmit, FIELD_BOOLEAN ),

END_DATADESC()

SporeTrail::SporeTrail( void )
{
	m_vecEndColor.GetForModify().Init();

	m_flSpawnRate			= 100.0f;
	m_flParticleLifetime	= 1.0f;
	m_flStartSize			= 1.0f;
	m_flEndSize				= 0.0f;
	m_flSpawnRadius			= 16.0f;
	SetRenderColor( 255, 255, 255, 255 );
}

//-----------------------------------------------------------------------------
// Purpose: 
// Output : SporeTrail*
//-----------------------------------------------------------------------------
SporeTrail* SporeTrail::CreateSporeTrail()
{
	CBaseEntity *pEnt = CreateEntityByName( SPORETRAIL_ENTITYNAME );
	
	if(pEnt)
	{
		SporeTrail *pSpore = dynamic_cast<SporeTrail*>(pEnt);
		
		if ( pSpore )
		{
			pSpore->Activate();
			return pSpore;
		}
		else
		{
			UTIL_Remove( pEnt );
		}
	}

	return NULL;
}

//==================================================
// SporeExplosion
//==================================================

IMPLEMENT_SERVERCLASS_ST( SporeExplosion, DT_SporeExplosion )
	SendPropFloat	(SENDINFO(m_flSpawnRate), 8, 0, 1, 1024),
	SendPropFloat	(SENDINFO(m_flParticleLifetime), 16, SPROP_ROUNDUP, 0.1, 100),
	SendPropFloat	(SENDINFO(m_flStartSize), -1, SPROP_NOSCALE),
	SendPropFloat	(SENDINFO(m_flEndSize), -1, SPROP_NOSCALE),
	SendPropFloat	(SENDINFO(m_flSpawnRadius), -1, SPROP_NOSCALE),
END_SEND_TABLE()

LINK_ENTITY_TO_CLASS( env_sporeexplosion, SporeExplosion );

BEGIN_DATADESC( SporeExplosion )

	DEFINE_FIELD( m_flSpawnRate, FIELD_FLOAT ),
	DEFINE_FIELD( m_flParticleLifetime, FIELD_FLOAT ),
	DEFINE_FIELD( m_flStartSize, FIELD_FLOAT ),
	DEFINE_FIELD( m_flEndSize, FIELD_FLOAT ),
	DEFINE_FIELD( m_flSpawnRadius, FIELD_FLOAT ),
	DEFINE_FIELD( m_bEmit, FIELD_BOOLEAN ),

END_DATADESC()

SporeExplosion::SporeExplosion( void )
{
	m_flSpawnRate			= 100.0f;
	m_flParticleLifetime	= 1.0f;
	m_flStartSize			= 1.0f;
	m_flEndSize				= 0.0f;
	m_flSpawnRadius			= 16.0f;
	SetRenderColor( 255, 255, 255, 255 );
}

//-----------------------------------------------------------------------------
// Purpose: 
// Output : SporeExplosion*
//-----------------------------------------------------------------------------
SporeExplosion *SporeExplosion::CreateSporeExplosion()
{
	CBaseEntity *pEnt = CreateEntityByName( SPOREEXPLOSION_ENTITYNAME );
	
	if ( pEnt )
	{
		SporeExplosion *pSpore = dynamic_cast<SporeExplosion*>(pEnt);
		
		if ( pSpore )
		{
			pSpore->Activate();
			return pSpore;
		}
		else
		{
			UTIL_Remove( pEnt );
		}
	}

	return NULL;
}

BEGIN_DATADESC( CFireTrail )

	DEFINE_FIELD( m_flLifetime, FIELD_FLOAT ),
	DEFINE_FIELD( m_nAttachment, FIELD_INTEGER ),

END_DATADESC()

IMPLEMENT_SERVERCLASS_ST( CFireTrail, DT_FireTrail )
	SendPropInt( SENDINFO( m_nAttachment ), 32 ),
	SendPropFloat( SENDINFO( m_flLifetime ), 0, SPROP_NOSCALE ),
END_SEND_TABLE()

LINK_ENTITY_TO_CLASS( env_fire_trail, CFireTrail );

//-----------------------------------------------------------------------------
// Purpose: Attach the smoke trail to an entity or point 
// Input  : index - entity that has the attachment
//			attachment - point to attach to
//-----------------------------------------------------------------------------
void CFireTrail::FollowEntity( CBaseEntity *pEntity, const char *pAttachmentName )
{
	// For attachments
	if ( pAttachmentName && pEntity && pEntity->GetBaseAnimating() )
	{
		m_nAttachment = pEntity->GetBaseAnimating()->LookupAttachment( pAttachmentName );
	}
	else
	{
		m_nAttachment = 0;
	}

	BaseClass::FollowEntity( pEntity );
}

//-----------------------------------------------------------------------------
// Purpose: Create and return a new fire trail entity
//-----------------------------------------------------------------------------
CFireTrail *CFireTrail::CreateFireTrail( void )
{
	CBaseEntity *pEnt = CreateEntityByName( "env_fire_trail" );
	
	if ( pEnt )
	{
		CFireTrail *pTrail = dynamic_cast<CFireTrail*>(pEnt);
		
		if ( pTrail )
		{
			pTrail->Activate();
			return pTrail;
		}
		else
		{
			UTIL_Remove( pEnt );
		}
	}

	return NULL;	
}
