Modified source engine (2017) developed by valve and leaked in 2020. Not for commercial purporses
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.
 
 
 
 
 
 

256 lines
6.4 KiB

#include "cbase.h"
#include "Sprite.h"
#include "SpriteTrail.h"
#include "soundent.h"
#include "te_effect_dispatch.h"
#include "IEffects.h"
#include "weapon_flaregun.h"
#include "decals.h"
#include "ai_basenpc.h"
#include "asw_marine.h"
#include "asw_firewall_piece.h"
#include "asw_marine_skills.h"
#include "asw_player.h"
#include "asw_marine_speech.h"
#include "asw_t75.h"
#include "world.h"
#include "asw_gamerules.h"
#include "asw_util_shared.h"
#include "asw_marine.h"
#include "asw_marine_resource.h"
#include "asw_fx_shared.h"
#include "asw_achievements.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#define ASW_T75_MODEL "models/swarmprops/miscdeco/bridgeexplosivesmesh.mdl"
#define ASW_MINE_EXPLODE_TIME 0.6f
BEGIN_DATADESC( CASW_T75 )
//DEFINE_FUNCTION( TouchT75 ),
//DEFINE_FUNCTION( CountdownThink ),
DEFINE_FIELD( m_bArmed, FIELD_BOOLEAN ),
DEFINE_FIELD( m_flDamage, FIELD_FLOAT ),
DEFINE_FIELD( m_flDamageRadius, FIELD_FLOAT ),
END_DATADESC()
IMPLEMENT_SERVERCLASS_ST( CASW_T75, DT_ASW_T75 )
SendPropBool( SENDINFO( m_bArmed ) ),
SendPropBool(SENDINFO(m_bIsInUse)),
SendPropFloat(SENDINFO(m_flArmProgress)),
END_SEND_TABLE()
LINK_ENTITY_TO_CLASS( asw_t75, CASW_T75 );
CASW_T75::CASW_T75()
{
m_bIsInUse = false;
m_flArmProgress = 0;
m_bArmed = false;
}
CASW_T75::~CASW_T75( void )
{
}
void CASW_T75::Spawn( void )
{
Precache();
SetModel( ASW_T75_MODEL );
SetSolid( SOLID_BBOX );
AddSolidFlags( FSOLID_NOT_SOLID || FSOLID_TRIGGER);
SetMoveType( MOVETYPE_FLYGRAVITY );
m_takedamage = DAMAGE_NO;
// check for attaching to elevators
trace_t tr;
UTIL_TraceLine( GetAbsOrigin() + Vector(0, 0, 2),
GetAbsOrigin() - Vector(0, 0, 32), MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );
if ( tr.fraction < 1.0f && tr.m_pEnt && !tr.m_pEnt->IsWorld() && !tr.m_pEnt->IsNPC() )
{
SetParent( tr.m_pEnt );
}
m_flDamage = 600.0f;
m_flDamageRadius = 250.0f;
AddEffects( EF_NOSHADOW|EF_NORECEIVESHADOW );
SetTouch( &CASW_T75::TouchT75 );
}
void CASW_T75::TouchT75( CBaseEntity *pOther )
{
// Slow down
Vector vecNewVelocity = GetAbsVelocity();
vecNewVelocity.x *= 0.8f;
vecNewVelocity.y *= 0.8f;
SetAbsVelocity( vecNewVelocity );
}
void CASW_T75::Arm()
{
m_bArmed = true;
}
extern ConVar asw_medal_explosive_kills;
void CASW_T75::Explode()
{
m_takedamage = DAMAGE_NO;
Vector vecForward = GetAbsVelocity();
VectorNormalize(vecForward);
trace_t tr;
UTIL_TraceLine ( GetAbsOrigin(), GetAbsOrigin() + 60*vecForward, MASK_SHOT,
this, COLLISION_GROUP_NONE, &tr);
EmitSound( "ASW_T75.Explode" );
EmitSound( "ASWGrenade.Incendiary" );
// throw out some flames
CEffectData data;
data.m_vOrigin = GetAbsOrigin();
DispatchEffect( "ASWFireBurst", data );
if ((tr.m_pEnt != GetWorldEntity()) || (tr.hitbox != 0))
{
// non-world needs smaller decals
if( tr.m_pEnt && !tr.m_pEnt->IsNPC() )
{
UTIL_DecalTrace( &tr, "SmallScorch" );
}
}
else
{
UTIL_DecalTrace( &tr, "Scorch" );
}
UTIL_ASW_ScreenShake( GetAbsOrigin(), 25.0, 150.0, 1.0, 750, SHAKE_START );
UTIL_ASW_GrenadeExplosion( GetAbsOrigin(), m_flDamageRadius );
int iPreExplosionKills = 0;
CASW_Marine *pMarine = dynamic_cast<CASW_Marine*>(GetOwnerEntity());
if (pMarine && pMarine->GetMarineResource())
iPreExplosionKills = pMarine->GetMarineResource()->m_iAliensKilled;
ASWGameRules()->RadiusDamage ( CTakeDamageInfo( this, GetOwnerEntity(), m_flDamage, DMG_BLAST ), GetAbsOrigin(), m_flDamageRadius, CLASS_NONE, NULL );
if (pMarine && pMarine->GetMarineResource())
{
int iKilledByExplosion = pMarine->GetMarineResource()->m_iAliensKilled - iPreExplosionKills;
if (iKilledByExplosion > pMarine->GetMarineResource()->m_iSingleGrenadeKills)
{
pMarine->GetMarineResource()->m_iSingleGrenadeKills = iKilledByExplosion;
if ( iKilledByExplosion > asw_medal_explosive_kills.GetInt() && pMarine->GetCommander() && pMarine->IsInhabited() )
{
pMarine->GetCommander()->AwardAchievement( ACHIEVEMENT_ASW_GRENADE_MULTI_KILL );
}
}
// count as a shot fired
pMarine->GetMarineResource()->UsedWeapon(NULL, 1);
pMarine->OnWeaponFired( m_hCreatorWeapon.Get(), 1 );
}
UTIL_Remove( this );
}
void CASW_T75::Precache( void )
{
PrecacheModel( ASW_T75_MODEL );
PrecacheScriptSound( "ASW_T75.Explode" );
PrecacheScriptSound( "ASW_T75.CountdownBeep" );
BaseClass::Precache();
}
CASW_T75* CASW_T75::ASW_T75_Create( const Vector &position, const QAngle &angles, const Vector &velocity, const AngularImpulse &angVelocity, CBaseEntity *pOwner, CBaseEntity *pCreatorWeapon /*= NULL */ )
{
CASW_T75 *pEnt = (CASW_T75*)CreateEntityByName( "asw_t75" );
pEnt->SetAbsAngles( angles );
pEnt->Spawn();
pEnt->SetOwnerEntity( pOwner );
UTIL_SetOrigin( pEnt, position );
pEnt->SetAbsVelocity( velocity );
pEnt->m_hCreatorWeapon.Set( pCreatorWeapon );
return pEnt;
}
bool CASW_T75::IsUsable(CBaseEntity *pUser)
{
return (pUser && pUser->GetAbsOrigin().DistTo(GetAbsOrigin()) < ASW_MARINE_USE_RADIUS); // near enough?
}
// player has used this item
void CASW_T75::ActivateUseIcon( CASW_Marine* pMarine, int nHoldType )
{
if ( !m_bIsInUse && !m_bArmed )
{
pMarine->StartUsing( this );
pMarine->GetMarineSpeech()->Chatter( CHATTER_USE );
}
}
#define T75_ARM_TIME 3.0f
void CASW_T75::MarineUsing(CASW_Marine* pMarine, float deltatime)
{
if ( m_bIsInUse && !m_bArmed.Get() && pMarine )
{
float fSetupAmount = (deltatime * (1.0f/T75_ARM_TIME));
m_flArmProgress += fSetupAmount;
if (m_flArmProgress >= 1.0f)
{
m_flArmProgress = 1.0f;
pMarine->StopUsing();
m_bArmed = true;
pMarine->GetMarineSpeech()->Chatter(CHATTER_MINE_DEPLOYED); // TODO: Chatter for T75 being armed
// set detonate time
m_iCountdown = 6;
SetThink( &CASW_T75::CountdownThink );
SetNextThink( gpGlobals->curtime + 0.1f );
}
}
}
void CASW_T75::MarineStartedUsing(CASW_Marine* pMarine)
{
m_bIsInUse = true;
}
void CASW_T75::MarineStoppedUsing(CASW_Marine* pMarine)
{
m_bIsInUse = false;
}
void CASW_T75::CountdownThink()
{
m_iCountdown--;
if ( m_iCountdown <= 0 )
{
Explode();
return;
}
EmitSound( "ASW_T75.CountdownBeep" );
Vector vecPos = WorldSpaceCenter();
CPASFilter filter( GetAbsOrigin() );
UserMessageBegin( filter, "ASWDamageNumber" );
WRITE_SHORT( m_iCountdown );
WRITE_SHORT( DAMAGE_FLAG_T75 );
WRITE_SHORT( entindex() );
WRITE_FLOAT( vecPos.x );
WRITE_FLOAT( vecPos.y );
WRITE_FLOAT( vecPos.z );
MessageEnd();
SetNextThink( gpGlobals->curtime + 1.0f );
}