summaryrefslogtreecommitdiff
path: root/game/server/tf/entity_bird.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'game/server/tf/entity_bird.cpp')
-rw-r--r--game/server/tf/entity_bird.cpp179
1 files changed, 179 insertions, 0 deletions
diff --git a/game/server/tf/entity_bird.cpp b/game/server/tf/entity_bird.cpp
new file mode 100644
index 0000000..b2d21b9
--- /dev/null
+++ b/game/server/tf/entity_bird.cpp
@@ -0,0 +1,179 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+//=============================================================================//
+#include "cbase.h"
+#include "tf_gamerules.h"
+#include "entity_bird.h"
+#include "KeyValues.h"
+#include "filesystem.h"
+#include "tf_fx.h"
+
+LINK_ENTITY_TO_CLASS( entity_bird, CEntityBird );
+
+#define ENTITYBIRD_MODEL "models/props_forest/bird.mdl"
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CEntityBird::Spawn( void )
+{
+ Precache();
+ BaseClass::Spawn();
+
+ SetMoveType( MOVETYPE_NONE );
+ SetSolid( SOLID_BBOX );
+ SetModel( ENTITYBIRD_MODEL );
+ SetSize( -Vector(8,8,0), Vector(8,8,16) );
+ SetSequence(0);
+ m_takedamage = DAMAGE_YES;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CEntityBird::Precache( void )
+{
+ BaseClass::Precache();
+
+ // We deliberately allow late precaches here. It'll cause a hitch, but it'll ensure
+ // we don't load the model on any map that doesn't have birds, and we'll make sure
+ // we don't accidentally keep loading it after the birds are supposed to go away.
+
+ bool bAllowPrecache = CBaseEntity::IsPrecacheAllowed();
+ CBaseEntity::SetAllowPrecache( true );
+ PrecacheModel( ENTITYBIRD_MODEL );
+ CBaseEntity::SetAllowPrecache( bAllowPrecache );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CEntityBird::Touch( CBaseEntity *pOther )
+{
+ BaseClass::Touch( pOther );
+
+ // If we're touched by anything, we pop!
+ Explode();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+int CEntityBird::OnTakeDamage( const CTakeDamageInfo &info )
+{
+ Explode();
+ return 1;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CEntityBird::Explode( void )
+{
+ Vector vecOrigin = WorldSpaceCenter();
+ CPVSFilter filter( vecOrigin );
+ TE_TFExplosion( filter, 0.0f, vecOrigin, Vector(0,0,1), TF_WEAPON_NONE, 0 );
+
+ UTIL_Remove( this );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Spawn random birds at locations on certain maps.
+//-----------------------------------------------------------------------------
+void CEntityBird::SpawnRandomBirds( void )
+{
+ const char *pszMapName = STRING( gpGlobals->mapname );
+ if ( !pszMapName || !pszMapName[0] )
+ return;
+
+ KeyValues *pFileKV = new KeyValues( "birds" );
+ if ( !pFileKV->LoadFromFile( g_pFullFileSystem, "scripts/birds.txt", "MOD" ) )
+ return;
+
+ // Build a list of birds in the map already, and make sure we don't spawn any on those spots again
+ CUtlVector<Vector> vecExistingBirds;
+ CBaseEntity *pBird = gEntList.FindEntityByClassname( NULL, "entity_bird" );
+ while( pBird )
+ {
+ vecExistingBirds.AddToTail( pBird->GetAbsOrigin() );
+ pBird = gEntList.FindEntityByClassname( pBird, "entity_bird" );
+ }
+
+ // See if we have an entry for this map
+ KeyValues *pMapKV = pFileKV->FindKey( pszMapName );
+ if ( pMapKV )
+ {
+ CUtlVector<Vector> vecLocations;
+
+ KeyValues *pkvLoc = pMapKV->GetFirstSubKey();
+ while ( pkvLoc )
+ {
+ const char *pszLocation = pkvLoc->GetString();
+ int iIdx = vecLocations.AddToTail();
+ UTIL_StringToVector( vecLocations[iIdx].Base(), pszLocation );
+ pkvLoc = pkvLoc->GetNextKey();
+ }
+
+ if ( vecLocations.Count() )
+ {
+ //int iLocation = RandomInt(0,vecLocations.Count()-1);
+ for ( int i = 0; i < vecLocations.Count(); i++ )
+ {
+ bool bExists = false;
+ // Make sure there isn't a bird here already
+ FOR_EACH_VEC( vecExistingBirds, iBird )
+ {
+ if ( vecLocations[i].DistToSqr(vecExistingBirds[iBird]) < (32*32) )
+ {
+ bExists = true;
+ break;
+ }
+ }
+
+ if ( !bExists )
+ {
+ CBaseEntity::Create( "entity_bird", vecLocations[i], QAngle(0,RandomFloat(0,360),0) );
+ }
+ }
+ }
+ }
+
+ pFileKV->deleteThis();
+}
+
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+#define ENTITY_FLYING_BIRD_SPEED_MIN 200
+#define ENTITY_FLYING_BIRD_SPEED_MAX 500
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void SpawnClientsideFlyingBird( Vector &vecSpawn )
+{
+ float flyAngle = RandomFloat( -M_PI, M_PI );
+ float flyAngleRate = RandomFloat( -1.5f, 1.5f );
+ float accelZ = RandomFloat( 0.5f, 2.0f );
+ float speed = RandomFloat( ENTITY_FLYING_BIRD_SPEED_MIN, ENTITY_FLYING_BIRD_SPEED_MAX );
+ float flGlideTime = RandomFloat( 0.25f, 1.0f );
+
+ bool bAllowPrecache = CBaseEntity::IsPrecacheAllowed();
+ CBaseEntity::SetAllowPrecache( true );
+ CBaseEntity::PrecacheModel( "models/props_forest/dove.mdl" );
+ CBaseEntity::SetAllowPrecache( bAllowPrecache );
+
+ CPVSFilter filter( vecSpawn );
+ UserMessageBegin( filter, "SpawnFlyingBird" );
+ WRITE_VEC3COORD( vecSpawn );
+ WRITE_FLOAT( flyAngle );
+ WRITE_FLOAT( flyAngleRate );
+ WRITE_FLOAT( accelZ );
+ WRITE_FLOAT( speed );
+ WRITE_FLOAT( flGlideTime );
+ MessageEnd();
+}
+
+