diff options
Diffstat (limited to 'game/server/tf/entity_bird.cpp')
| -rw-r--r-- | game/server/tf/entity_bird.cpp | 179 |
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(); +} + + |