mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-09-01 23:19:18 +00:00
upload "kind" alien swarm
This commit is contained in:
@@ -0,0 +1,465 @@
|
||||
#include "cbase.h"
|
||||
#include "asw_aoegrenade_projectile.h"
|
||||
#include "asw_marine.h"
|
||||
#include "Sprite.h"
|
||||
#include "SpriteTrail.h"
|
||||
#include "soundent.h"
|
||||
#include "te_effect_dispatch.h"
|
||||
#include "IEffects.h"
|
||||
#include "decals.h"
|
||||
#include "asw_shareddefs.h"
|
||||
#include "particle_parse.h"
|
||||
#include "triggers.h"
|
||||
#include "world.h"
|
||||
#include "asw_game_resource.h"
|
||||
#include "asw_marine_resource.h"
|
||||
|
||||
// memdbgon must be the last include file in a .cpp file!!!
|
||||
#include "tier0/memdbgon.h"
|
||||
|
||||
|
||||
#define AOEGREN_MODEL "models/items/Mine/mine.mdl"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: SendProxy that converts the AOEGren list UtlVector to entindices
|
||||
//-----------------------------------------------------------------------------
|
||||
void SendProxy_AOEGrenList( const SendProp *pProp, const void *pStruct, const void *pData, DVariant *pOut, int iElement, int objectID )
|
||||
{
|
||||
CASW_AOEGrenade_Projectile *pAOEGren = (CASW_AOEGrenade_Projectile*)pStruct;
|
||||
|
||||
// If this assertion fails, then SendProxyArrayLength_AOEGrenArray must have failed.
|
||||
Assert( iElement < pAOEGren->m_hAOETargets.Count() );
|
||||
|
||||
CBaseEntity *pEnt = pAOEGren->m_hAOETargets[iElement].Get();
|
||||
EHANDLE hOther = pEnt;
|
||||
|
||||
SendProxy_EHandleToInt( pProp, pStruct, &hOther, pOut, iElement, objectID );
|
||||
}
|
||||
|
||||
int SendProxyArrayLength_AOEGrenArray( const void *pStruct, int objectID )
|
||||
{
|
||||
CASW_AOEGrenade_Projectile *pAOEGren = (CASW_AOEGrenade_Projectile*)pStruct;
|
||||
return pAOEGren->m_hAOETargets.Count();
|
||||
}
|
||||
|
||||
|
||||
class CASW_AOEGrenade_TouchTrigger : public CBaseTrigger
|
||||
{
|
||||
DECLARE_CLASS( CASW_AOEGrenade_TouchTrigger, CBaseTrigger );
|
||||
|
||||
public:
|
||||
CASW_AOEGrenade_TouchTrigger() {}
|
||||
|
||||
void Spawn( void )
|
||||
{
|
||||
BaseClass::Spawn();
|
||||
// SF_TRIGGER_ONLY_PLAYER_ALLY_NPCS means "only marines" in ASW
|
||||
AddSpawnFlags( SF_TRIGGER_ONLY_PLAYER_ALLY_NPCS );
|
||||
InitTrigger();
|
||||
}
|
||||
|
||||
virtual void StartTouch( CBaseEntity *pEntity )
|
||||
{
|
||||
CASW_AOEGrenade_Projectile *pParent = dynamic_cast<CASW_AOEGrenade_Projectile *>(GetOwnerEntity());
|
||||
|
||||
if ( pParent )
|
||||
{
|
||||
pParent->StartTouch( pEntity );
|
||||
}
|
||||
}
|
||||
|
||||
virtual void EndTouch( CBaseEntity *pEntity )
|
||||
{
|
||||
CASW_AOEGrenade_Projectile *pParent = dynamic_cast<CASW_AOEGrenade_Projectile *>(GetOwnerEntity());
|
||||
|
||||
if ( pParent )
|
||||
{
|
||||
pParent->EndTouch( pEntity );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
LINK_ENTITY_TO_CLASS( asw_aoegrenade_touch_trigger, CASW_AOEGrenade_TouchTrigger );
|
||||
|
||||
BEGIN_DATADESC( CASW_AOEGrenade_Projectile )
|
||||
DEFINE_FUNCTION( AOEGrenadeTouch ),
|
||||
DEFINE_FUNCTION( AOEGrenadeThink ),
|
||||
|
||||
// Fields
|
||||
DEFINE_FIELD( m_pMainGlow, FIELD_EHANDLE ),
|
||||
DEFINE_FIELD( m_pGlowTrail, FIELD_EHANDLE ),
|
||||
DEFINE_FIELD( m_flTimeBurnOut, FIELD_TIME ),
|
||||
DEFINE_FIELD( m_flTimePulse, FIELD_TIME ),
|
||||
DEFINE_FIELD( m_flLastDoAOE, FIELD_TIME ),
|
||||
DEFINE_FIELD( m_flScale, FIELD_FLOAT ),
|
||||
DEFINE_FIELD( m_nBounces, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( m_flDuration, FIELD_FLOAT ),
|
||||
DEFINE_FIELD( m_bFading, FIELD_BOOLEAN ),
|
||||
DEFINE_FIELD( m_bSettled, FIELD_BOOLEAN ),
|
||||
END_DATADESC()
|
||||
|
||||
IMPLEMENT_SERVERCLASS_ST( CASW_AOEGrenade_Projectile, DT_ASW_AOEGrenade_Projectile )
|
||||
SendPropArray2(
|
||||
SendProxyArrayLength_AOEGrenArray,
|
||||
SendPropInt( "aoegren_array_element", 0, SIZEOF_IGNORE, NUM_NETWORKED_EHANDLE_BITS, SPROP_UNSIGNED, SendProxy_AOEGrenList),
|
||||
MAX_PLAYERS,
|
||||
0,
|
||||
"aoetarget_array"
|
||||
),
|
||||
|
||||
SendPropFloat( SENDINFO( m_flTimeBurnOut ), 0, SPROP_NOSCALE ),
|
||||
//SendPropFloat( SENDINFO( m_flTimePulse ), 0, SPROP_NOSCALE ),
|
||||
SendPropFloat( SENDINFO( m_flScale ), 0, SPROP_NOSCALE ),
|
||||
SendPropBool( SENDINFO( m_bSettled ) ),
|
||||
SendPropFloat( SENDINFO( m_flRadius ), 0, SPROP_NOSCALE ),
|
||||
END_SEND_TABLE()
|
||||
|
||||
|
||||
// aoegrenades maintain a linked list of themselves, for quick checking for autoaim
|
||||
CASW_AOEGrenade_Projectile* g_pHeadAOEGrenade = NULL;
|
||||
|
||||
CASW_AOEGrenade_Projectile::CASW_AOEGrenade_Projectile()
|
||||
{
|
||||
m_flScale = 1.0f;
|
||||
m_flNextDamage = gpGlobals->curtime;
|
||||
m_lifeState = LIFE_ALIVE;
|
||||
m_iHealth = 100;
|
||||
m_flDuration = 20.0f;
|
||||
m_flRadius = 128.0f;
|
||||
|
||||
SetModelName( MAKE_STRING( AOEGREN_MODEL ) );
|
||||
}
|
||||
|
||||
CASW_AOEGrenade_Projectile::~CASW_AOEGrenade_Projectile( void )
|
||||
{
|
||||
if ( m_hTouchTrigger.Get() )
|
||||
{
|
||||
UTIL_Remove( m_hTouchTrigger );
|
||||
}
|
||||
|
||||
int iSize = m_hAOETargets.Count();
|
||||
for ( int i = iSize - 1; i >= 0; i-- )
|
||||
{
|
||||
EHANDLE hEntity = m_hAOETargets[i];
|
||||
StopAOE( hEntity.Get() );
|
||||
}
|
||||
}
|
||||
|
||||
int CASW_AOEGrenade_Projectile::Restore( IRestore &restore )
|
||||
{
|
||||
int result = BaseClass::Restore( restore );
|
||||
return result;
|
||||
}
|
||||
|
||||
void CASW_AOEGrenade_Projectile::Spawn( void )
|
||||
{
|
||||
Precache( );
|
||||
|
||||
SetModel( GetModelName().ToCStr() );
|
||||
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_iDamage = 0;
|
||||
m_takedamage = DAMAGE_NO;
|
||||
|
||||
SetFriction( 0.6f );
|
||||
SetGravity( UTIL_ScaleForGravity( GetGrenadeGravity() ) );
|
||||
m_flTimeBurnOut = gpGlobals->curtime + GetBurnDuration();
|
||||
m_flTimePulse = -1;
|
||||
|
||||
AddEffects( EF_NOSHADOW|EF_NORECEIVESHADOW );
|
||||
AddFlag( FL_OBJECT );
|
||||
SetCollisionGroup( ASW_COLLISION_GROUP_IGNORE_NPCS );
|
||||
|
||||
// Tumble in air
|
||||
QAngle vecAngVelocity( 0, random->RandomFloat ( -100, -500 ), 0 );
|
||||
SetLocalAngularVelocity( vecAngVelocity );
|
||||
|
||||
SetTouch( &CASW_AOEGrenade_Projectile::AOEGrenadeTouch );
|
||||
|
||||
SetThink( &CASW_AOEGrenade_Projectile::AOEGrenadeThink );
|
||||
SetNextThink( gpGlobals->curtime + 0.1f );
|
||||
}
|
||||
|
||||
void CASW_AOEGrenade_Projectile::Precache( void )
|
||||
{
|
||||
PrecacheModel( GetModelName().ToCStr() );
|
||||
|
||||
PrecacheScriptSound( "ASW_BuffGrenade.GrenadeActivate" );
|
||||
PrecacheScriptSound( "ASW_BuffGrenade.ActiveLoop" );
|
||||
PrecacheScriptSound( "ASW_BuffGrenade.StartBuff" );
|
||||
PrecacheScriptSound( "ASW_BuffGrenade.BuffLoop" );
|
||||
|
||||
PrecacheModel( "swarm/sprites/whiteglow1.vmt" );
|
||||
PrecacheModel( "swarm/sprites/greylaser1.vmt" );
|
||||
|
||||
BaseClass::Precache();
|
||||
}
|
||||
|
||||
const Vector& CASW_AOEGrenade_Projectile::GetEffectOrigin()
|
||||
{
|
||||
static Vector s_vecEffectPos;
|
||||
Vector forward, right, up;
|
||||
AngleVectors(GetAbsAngles(), &forward, &right, &up);
|
||||
s_vecEffectPos = GetAbsOrigin() + up * 5;
|
||||
return s_vecEffectPos;
|
||||
}
|
||||
|
||||
|
||||
unsigned int CASW_AOEGrenade_Projectile::PhysicsSolidMaskForEntity( void ) const
|
||||
{
|
||||
return MASK_NPCSOLID;
|
||||
}
|
||||
|
||||
void CASW_AOEGrenade_Projectile::AOEGrenadeTouch( CBaseEntity *pOther )
|
||||
{
|
||||
Assert( pOther );
|
||||
if ( !pOther->IsSolid() )
|
||||
return;
|
||||
|
||||
// don't touch npcs
|
||||
if ( pOther->IsNPC() )
|
||||
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() < 128.0f )
|
||||
{
|
||||
LayFlat();
|
||||
SetAbsVelocity( vec3_origin );
|
||||
SetMoveType( MOVETYPE_NONE );
|
||||
//RemoveSolidFlags( FSOLID_NOT_SOLID );
|
||||
//AddSolidFlags( FSOLID_TRIGGER );
|
||||
//SetTouch( &CASW_Flare_Projectile::FlareBurnTouch );
|
||||
m_hTouchTrigger = CBaseEntity::Create( "asw_aoegrenade_touch_trigger", GetAbsOrigin(), vec3_angle, this );
|
||||
int radius = GetEffectRadius();
|
||||
UTIL_SetSize( m_hTouchTrigger.Get(), Vector(-radius,-radius,-radius), Vector(radius,radius,radius) );
|
||||
m_hTouchTrigger->SetSolid( SOLID_BBOX );
|
||||
|
||||
// call StartTouch() on all marines in radius
|
||||
CASW_Game_Resource *pGameResource = ASWGameResource();
|
||||
for (int i=0;i<pGameResource->GetMaxMarineResources();i++)
|
||||
{
|
||||
CASW_Marine_Resource *pMR = pGameResource->GetMarineResource(i);
|
||||
if (!pMR)
|
||||
continue;
|
||||
CASW_Marine *pMarine = pMR->GetMarineEntity();
|
||||
if (!pMarine)
|
||||
continue;
|
||||
|
||||
if( GetDistanceToEntity( pMarine ) < m_flRadius )
|
||||
{
|
||||
CBaseEntity *pEntity = pMarine;
|
||||
StartTouch( pEntity );
|
||||
}
|
||||
}
|
||||
|
||||
//NDebugOverlay::Box( GetAbsOrigin(), Vector(-radius,-radius,-radius), Vector(radius,radius,radius), 0, 0, 255, 200, 5.5 );
|
||||
|
||||
Assert( m_hTouchTrigger.Get() );
|
||||
|
||||
m_bSettled = true;
|
||||
}
|
||||
}
|
||||
|
||||
void CASW_AOEGrenade_Projectile::AOEGrenadeThink( void )
|
||||
{
|
||||
if ( m_flTimeBurnOut != -1.0f )
|
||||
{
|
||||
//Burned out
|
||||
if ( m_flTimeBurnOut < gpGlobals->curtime )
|
||||
{
|
||||
OnBurnout();
|
||||
UTIL_Remove( this );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//Act differently underwater
|
||||
if ( GetWaterLevel() > 1 )
|
||||
{
|
||||
UTIL_Bubbles( GetEffectOrigin() + Vector( -2, -2, -2 ), GetEffectOrigin() + Vector( 2, 2, 2 ), 1 );
|
||||
}
|
||||
|
||||
if ( !m_bSettled && GetAbsVelocity().Length() < 128.0f && GetGroundEntity() )
|
||||
{
|
||||
AOEGrenadeTouch( GetGroundEntity() );
|
||||
}
|
||||
|
||||
GiveEffectToEntitesInRadius();
|
||||
|
||||
//Next update
|
||||
SetNextThink( gpGlobals->curtime + 0.1f );
|
||||
}
|
||||
|
||||
void CASW_AOEGrenade_Projectile::GiveEffectToEntitesInRadius( void )
|
||||
{
|
||||
bool bDoAOE = ( gpGlobals->curtime > m_flLastDoAOE + GetDoAOEDelayTime() );
|
||||
|
||||
// for each player in touching list
|
||||
int iSize = m_hTouchingEntities.Count();
|
||||
for ( int i = iSize-1; i >= 0; i-- )
|
||||
{
|
||||
EHANDLE hEntity = m_hTouchingEntities[i];
|
||||
|
||||
CBaseEntity *pEntity = hEntity.Get();
|
||||
if ( !pEntity )
|
||||
continue;
|
||||
|
||||
if ( !IsAOETarget( pEntity ) )
|
||||
{
|
||||
// if they're on the list, but we aren't buffing them, do so
|
||||
StartAOE( pEntity );
|
||||
}
|
||||
|
||||
if ( bDoAOE )
|
||||
{
|
||||
DoAOE( pEntity );
|
||||
}
|
||||
}
|
||||
|
||||
if ( bDoAOE )
|
||||
{
|
||||
m_flLastDoAOE = gpGlobals->curtime;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CASW_AOEGrenade_Projectile::StartTouch( CBaseEntity *pEntity )
|
||||
{
|
||||
if ( !ShouldTouchEntity( pEntity ) )
|
||||
return;
|
||||
|
||||
// add to touching entities
|
||||
EHANDLE hEntity = pEntity;
|
||||
if( m_hTouchingEntities.Find( hEntity ) == -1 )
|
||||
{
|
||||
m_hTouchingEntities.AddToTail( hEntity );
|
||||
|
||||
// try to start healing them
|
||||
StartAOE( pEntity );
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CASW_AOEGrenade_Projectile::EndTouch( CBaseEntity *pEntity )
|
||||
{
|
||||
// remove from touching entities
|
||||
EHANDLE hEntity = pEntity;
|
||||
m_hTouchingEntities.FindAndRemove( hEntity );
|
||||
|
||||
// remove from healing list
|
||||
StopAOE( pEntity );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Add the buff to this target
|
||||
//-----------------------------------------------------------------------------
|
||||
void CASW_AOEGrenade_Projectile::StartAOE( CBaseEntity *pEntity )
|
||||
{
|
||||
AddAOETarget( pEntity );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Stop healing this target
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CASW_AOEGrenade_Projectile::StopAOE( CBaseEntity *pEntity )
|
||||
{
|
||||
bool bFound = false;
|
||||
|
||||
EHANDLE hEntity = pEntity;
|
||||
bFound = m_hAOETargets.FindAndRemove( hEntity );
|
||||
NetworkStateChanged();
|
||||
|
||||
return bFound;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CASW_AOEGrenade_Projectile::AddAOETarget( CBaseEntity *pEntity )
|
||||
{
|
||||
Assert( pEntity );
|
||||
// add to tail
|
||||
EHANDLE hEntity = pEntity;
|
||||
m_hAOETargets.AddToTail( hEntity );
|
||||
NetworkStateChanged();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
//-----------------------------------------------------------------------------
|
||||
void CASW_AOEGrenade_Projectile::RemoveAOETarget( CBaseEntity *pEntity )
|
||||
{
|
||||
Assert( pEntity );
|
||||
// remove
|
||||
EHANDLE hEntity = pEntity;
|
||||
m_hAOETargets.FindAndRemove( hEntity );
|
||||
NetworkStateChanged();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Are we buffing this target already
|
||||
//-----------------------------------------------------------------------------
|
||||
bool CASW_AOEGrenade_Projectile::IsAOETarget( CBaseEntity *pEntity )
|
||||
{
|
||||
Assert( pEntity );
|
||||
EHANDLE hEntity = pEntity;
|
||||
return m_hAOETargets.HasElement( hEntity );
|
||||
}
|
||||
|
||||
void CASW_AOEGrenade_Projectile::LayFlat()
|
||||
{
|
||||
QAngle angFacing = GetAbsAngles();
|
||||
//if (angFacing[PITCH] > 0 && angFacing[PITCH] < 180.0f)
|
||||
angFacing[PITCH] = 0; //90
|
||||
//else
|
||||
// angFacing[PITCH] = 270;
|
||||
SetAbsAngles(angFacing);
|
||||
//Msg("Laying flat to %f, %f, %f\n", angFacing[PITCH], angFacing[YAW], angFacing[ROLL]);
|
||||
}
|
||||
|
||||
//extern ConVar asw_aoegrenade_autoaim_radius;
|
||||
void CASW_AOEGrenade_Projectile::DrawDebugGeometryOverlays()
|
||||
{
|
||||
/*
|
||||
// draw arrows showing the extent of our autoaim
|
||||
for (int i=0;i<360;i+=45)
|
||||
{
|
||||
float flBaseSize = 10;
|
||||
float flHeight = asw_aoegrenade_autoaim_radius.GetFloat();
|
||||
|
||||
Vector vBasePos = GetAbsOrigin() + Vector( 0, 0, 5 );
|
||||
QAngle angles( 0, 0, 0 );
|
||||
Vector vForward, vRight, vUp;
|
||||
angles[YAW] = i;
|
||||
AngleVectors( angles, &vForward, &vRight, &vUp );
|
||||
NDebugOverlay::Triangle( vBasePos+vRight*flBaseSize/2, vBasePos-vRight*flBaseSize/2, vBasePos+vForward*flHeight, 0, 255, 0, 255, false, 10 );
|
||||
}
|
||||
*/
|
||||
BaseClass::DrawDebugGeometryOverlays();
|
||||
}
|
||||
Reference in New Issue
Block a user