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

222 lines
6.0 KiB
C++
Raw Normal View History

2024-08-29 19:18:30 -04:00
#include "cbase.h"
#include "asw_mine.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"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
#define ASW_MINE_MODEL "models/items/Mine/mine.mdl"
#define ASW_MINE_EXPLODE_TIME 0.6f
ConVar asw_debug_mine("asw_debug_mine", "0", FCVAR_CHEAT, "Turn on debug messages for Incendiary Mines");
LINK_ENTITY_TO_CLASS( asw_mine, CASW_Mine );
BEGIN_DATADESC( CASW_Mine )
DEFINE_FUNCTION( MineTouch ),
DEFINE_FUNCTION( MineThink ),
DEFINE_FIELD( m_bPrimed, FIELD_BOOLEAN ),
DEFINE_FIELD( m_bMineTriggered, FIELD_BOOLEAN ),
DEFINE_FIELD( m_fForcePrimeTime, FIELD_FLOAT ),
END_DATADESC()
IMPLEMENT_SERVERCLASS_ST( CASW_Mine, DT_ASW_Mine )
SendPropBool( SENDINFO( m_bMineTriggered ) ),
END_SEND_TABLE()
CASW_Mine::CASW_Mine()
{
m_flDurationScale = 1.0f;
m_iExtraFires = 0;
}
CASW_Mine::~CASW_Mine( void )
{
}
void CASW_Mine::Spawn( void )
{
Precache( );
SetModel( ASW_MINE_MODEL );
SetSolid( SOLID_BBOX );
AddSolidFlags( FSOLID_NOT_SOLID || FSOLID_TRIGGER);
SetMoveType( MOVETYPE_FLYGRAVITY );
m_takedamage = DAMAGE_NO;
m_bPrimed = false;
AddEffects( EF_NOSHADOW|EF_NORECEIVESHADOW );
m_fForcePrimeTime = gpGlobals->curtime + 5.0f;
SetThink( &CASW_Mine::MineThink );
SetNextThink( gpGlobals->curtime + 0.1f );
SetTouch( &CASW_Mine::MineTouch );
}
unsigned int CASW_Mine::PhysicsSolidMaskForEntity( void ) const
{
return MASK_NPCSOLID;
}
void CASW_Mine::MineThink( void )
{
if (m_bMineTriggered)
{
Explode();
}
// if we've stopped moving, prime ourselves
else if (!m_bPrimed && (GetAbsVelocity().Length() < 1.0f || gpGlobals->curtime > m_fForcePrimeTime))
{
Prime();
}
else
{
SetNextThink( gpGlobals->curtime + 0.1f );
}
}
void CASW_Mine::Explode()
{
if (asw_debug_mine.GetBool())
Msg("OMG MINE ASPLODE!\n");
CASW_Firewall_Piece* pFirewall = (CASW_Firewall_Piece *)CreateEntityByName( "asw_firewall_piece" );
if (pFirewall)
{
pFirewall->SetAbsAngles( GetAbsAngles() );
if (GetOwnerEntity())
Msg("Creating firewall with owner %s\n", GetOwnerEntity()->GetClassname());
pFirewall->SetOwnerEntity(GetOwnerEntity());
pFirewall->SetAbsOrigin( GetAbsOrigin() );
CASW_Marine *pMarine = dynamic_cast<CASW_Marine*>(GetOwnerEntity());
if (!pMarine)
{
pFirewall->SetSideFire( 3 + m_iExtraFires , 3+ m_iExtraFires );
}
else
{
int iSideFires = MarineSkills()->GetSkillBasedValueByMarine(pMarine, ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_MINES_FIRES) + m_iExtraFires;
float fDuration = MarineSkills()->GetSkillBasedValueByMarine(pMarine, ASW_MARINE_SKILL_GRENADES, ASW_MARINE_SUBSKILL_GRENADE_MINES_DURATION);
pFirewall->SetSideFire(iSideFires,iSideFires);
pFirewall->SetDuration(fDuration * m_flDurationScale);
}
pFirewall->m_hCreatorWeapon = m_hCreatorWeapon;
pFirewall->Spawn();
pFirewall->SetAbsVelocity( vec3_origin );
}
EmitSound("ASW_Mine.Explode");
UTIL_Remove( this );
}
void CASW_Mine::Precache( void )
{
PrecacheModel( ASW_MINE_MODEL );
PrecacheScriptSound("ASW_Mine.Lay");
PrecacheScriptSound("ASW_Mine.Flash");
PrecacheScriptSound("ASW_Mine.Explode");
BaseClass::Precache();
}
CASW_Mine* CASW_Mine::ASW_Mine_Create( const Vector &position, const QAngle &angles, const Vector &velocity, const AngularImpulse &angVelocity, CBaseEntity *pOwner, CBaseEntity *pCreatorWeapon )
{
CASW_Mine *pMine = (CASW_Mine*)CreateEntityByName( "asw_mine" );
pMine->SetAbsAngles( angles );
pMine->Spawn();
pMine->SetOwnerEntity( pOwner );
UTIL_SetOrigin( pMine, position );
pMine->SetAbsVelocity( velocity );
pMine->m_hCreatorWeapon.Set( pCreatorWeapon );
return pMine;
}
void CASW_Mine::MineTouch( CBaseEntity *pOther )
{
Assert( pOther );
if (pOther->entindex() != 0 && asw_debug_mine.GetBool())
Msg("Touched by %s\n", pOther->GetClassname());
if (!m_bMineTriggered && m_bPrimed)
{
// if other is an alien, trigger the mine
if (ValidMineTarget(pOther))
{
// Ensure clear path to the target
trace_t tr;
UTIL_TraceLine( GetAbsOrigin(), pOther->WorldSpaceCenter(), MASK_SHOT, this, COLLISION_GROUP_NONE, &tr );
if ( tr.fraction >= 1.0f || tr.m_pEnt == pOther )
{
if (asw_debug_mine.GetBool())
Msg("Mine triggered!\n");
m_bMineTriggered = true;
EmitSound("ASW_Mine.Flash");
SetNextThink( gpGlobals->curtime + ASW_MINE_EXPLODE_TIME );
}
}
}
// Slow down
Vector vecNewVelocity = GetAbsVelocity();
vecNewVelocity.x *= 0.8f;
vecNewVelocity.y *= 0.8f;
SetAbsVelocity( vecNewVelocity );
}
// set the mine up for exploding
void CASW_Mine::Prime()
{
if (asw_debug_mine.GetBool())
Msg("Mine primed!\n");
EmitSound("ASW_Mine.Lay");
SetSolid( SOLID_BBOX );
float boxWidth = 150;
UTIL_SetSize(this, Vector(-boxWidth,-boxWidth,-boxWidth),Vector(boxWidth,boxWidth,boxWidth * 2));
SetCollisionGroup( ASW_COLLISION_GROUP_PASSABLE );
CollisionProp()->UseTriggerBounds( true, 24 );
AddSolidFlags(FSOLID_TRIGGER);
AddSolidFlags(FSOLID_NOT_SOLID);
SetTouch( &CASW_Mine::MineTouch );
m_bPrimed = true;
// attach to whatever we're standing on
CBaseEntity *pGround = GetGroundEntity();
if ( pGround && !pGround->IsWorld() )
{
if (asw_debug_mine.GetBool())
Msg( "Parenting mine to %s\n", GetGroundEntity()->GetClassname() );
SetParent( GetGroundEntity() );
SetMoveType( MOVETYPE_NONE );
}
}
bool CASW_Mine::ValidMineTarget(CBaseEntity *pOther)
{
CASW_Marine* pMarine = CASW_Marine::AsMarine( pOther );
if (pMarine)
return false;
CAI_BaseNPC* pNPC = dynamic_cast<CAI_BaseNPC*>(pOther);
if (pNPC)
return true;
return false;
}
void CASW_Mine::StopLoopingSounds()
{
BaseClass::StopLoopingSounds();
}