sqwarmed/sdk_src/game/server/swarm/asw_bait.cpp

216 lines
5.1 KiB
C++

#include "cbase.h"
#include "asw_bait.h"
#include "soundent.h"
#include "te_effect_dispatch.h"
#include "IEffects.h"
#include "decals.h"
#include "asw_shareddefs.h"
#include "ai_senses.h"
#include "asw_gamerules.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#define BAIT_MODEL "models/swarm/Flare/flareweapon.mdl"
#define ASW_BAIT_LIFETIME 30.0f
LINK_ENTITY_TO_CLASS( asw_bait, CASW_Bait );
BEGIN_DATADESC( CASW_Bait )
DEFINE_FUNCTION( BaitTouch ),
DEFINE_FUNCTION( BaitThink ),
DEFINE_FIELD( m_flTimeBurnOut, FIELD_TIME ),
END_DATADESC()
// flares maintain a linked list of themselves, for quick checking for autoaim
CASW_Bait* g_pHeadFlare = NULL;
CASW_Bait::CASW_Bait()
{
m_lifeState = LIFE_ALIVE;
m_iHealth = 100;
m_nBounces = 0;
}
CASW_Bait::~CASW_Bait( void )
{
}
void CASW_Bait::Spawn( void )
{
Precache( );
SetModel( BAIT_MODEL );
UTIL_SetSize( this, Vector( -2, -2, -2 ), Vector( 2, 2, 2 ) );
SetSolid( SOLID_BBOX );
AddSolidFlags( FSOLID_NOT_SOLID );
SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE );
m_takedamage = DAMAGE_NO;
SetFriction( 0.6f );
m_flTimeBurnOut = gpGlobals->curtime + 30;
AddEffects( EF_NOSHADOW|EF_NORECEIVESHADOW );
AddFlag( FL_OBJECT );
SetCollisionGroup( ASW_COLLISION_GROUP_IGNORE_NPCS );
//CreateVPhysics();
// Tumble in air
QAngle vecAngVelocity( 0, random->RandomFloat ( -100, -500 ), 0 );
SetLocalAngularVelocity( vecAngVelocity );
SetTouch( &CASW_Bait::BaitTouch );
SetThink( &CASW_Bait::BaitThink );
// join the flares team so that aliens will hate us
ChangeFaction( FACTION_BAIT );
if ( ASW_BAIT_LIFETIME > 0 )
{
m_flTimeBurnOut = gpGlobals->curtime + ASW_BAIT_LIFETIME;
}
else
{
m_flTimeBurnOut = -1.0f;
}
SetNextThink( gpGlobals->curtime + 0.1f );
g_AI_SensedObjectsManager.AddEntity( this );
}
void CASW_Bait::BaitThink( void )
{
if ( m_flTimeBurnOut != -1.0f )
{
//Burned out
if ( m_flTimeBurnOut < gpGlobals->curtime )
{
UTIL_Remove( this );
return;
}
}
//Next update
SetNextThink( gpGlobals->curtime + 0.1f );
}
void CASW_Bait::Precache( void )
{
PrecacheModel( BAIT_MODEL );
BaseClass::Precache();
}
CASW_Bait* CASW_Bait::Bait_Create( const Vector &position, const QAngle &angles, const Vector &velocity, const AngularImpulse &angVelocity, CBaseEntity *pOwner )
{
CASW_Bait *pEnt = (CASW_Bait *)CreateEntityByName( "asw_bait" );
pEnt->SetAbsAngles( angles );
pEnt->Spawn();
pEnt->SetOwnerEntity( pOwner );
UTIL_SetOrigin( pEnt, position );
pEnt->SetAbsVelocity( velocity );
return pEnt;
}
void CASW_Bait::BaitTouch( CBaseEntity *pOther )
{
Assert( pOther );
if ( !pOther->IsSolid() )
return;
if ( pOther && pOther->m_takedamage )
{
Vector vecNewVelocity = GetAbsVelocity();
vecNewVelocity *= 0.1f;
SetAbsVelocity( vecNewVelocity );
SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE );
SetGravity(1.0f);
return;
}
else
{
// hit the world, check the material type here, see if the flare should stick.
trace_t tr;
tr = CBaseEntity::GetTouchTrace();
//Only do this on the first bounce
if ( m_nBounces == 0 )
{
surfacedata_t *pdata = physprops->GetSurfaceData( tr.surface.surfaceProps );
if ( pdata != NULL )
{
//Only embed into concrete and wood (jdw: too obscure for players?)
//if ( ( pdata->gameMaterial == 'C' ) || ( pdata->gameMaterial == 'W' ) )
{
Vector impactDir = ( tr.endpos - tr.startpos );
VectorNormalize( impactDir );
float surfDot = tr.plane.normal.Dot( impactDir );
//Do not stick to ceilings or on shallow impacts
if ( ( tr.plane.normal.z > -0.5f ) && ( surfDot < -0.9f ) )
{
RemoveSolidFlags( FSOLID_NOT_SOLID );
AddSolidFlags( FSOLID_TRIGGER );
LayFlat();
UTIL_SetOrigin( this, tr.endpos + ( tr.plane.normal * 2.0f ) );
SetAbsVelocity( vec3_origin );
SetMoveType( MOVETYPE_NONE );
SetTouch( NULL );
return;
}
}
}
}
// Change our flight characteristics
SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE );
SetGravity( UTIL_ScaleForGravity( 640 ) );
m_nBounces++;
//After the first bounce, smacking into whoever fired the flare is fair game
SetOwnerEntity( NULL );
// Slow down
Vector vecNewVelocity = GetAbsVelocity();
vecNewVelocity.x *= 0.8f;
vecNewVelocity.y *= 0.8f;
SetAbsVelocity( vecNewVelocity );
//Stopped?
if ( GetAbsVelocity().Length() < 64.0f )
{
LayFlat();
SetAbsVelocity( vec3_origin );
SetMoveType( MOVETYPE_NONE );
RemoveSolidFlags( FSOLID_NOT_SOLID );
AddSolidFlags( FSOLID_TRIGGER );
SetTouch( NULL );
}
}
}
void CASW_Bait::LayFlat()
{
return;
QAngle angFacing = GetAbsAngles();
if (angFacing[PITCH] > 0 && angFacing[PITCH] < 180.0f)
angFacing[PITCH] = 90;
else
angFacing[PITCH] = 270;
SetAbsAngles(angFacing);
//Msg("Laying flat to %f, %f, %f\n", angFacing[PITCH], angFacing[YAW], angFacing[ROLL]);
}