You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
216 lines
4.9 KiB
216 lines
4.9 KiB
1 year ago
|
#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]);
|
||
|
}
|