mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-23 06:36:54 +00:00
275 lines
7.0 KiB
C++
275 lines
7.0 KiB
C++
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose: Things thrown from the hand
|
|
//
|
|
//=============================================================================//
|
|
|
|
#include "cbase.h"
|
|
#include "player.h"
|
|
#include "ammodef.h"
|
|
#include "gamerules.h"
|
|
#include "grenade_brickbat.h"
|
|
#include "weapon_brickbat.h"
|
|
#include "soundent.h"
|
|
#include "decals.h"
|
|
#include "IEffects.h"
|
|
#include "engine/IEngineSound.h"
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
// Global Savedata for changelevel trigger
|
|
BEGIN_DATADESC( CGrenade_Brickbat )
|
|
|
|
DEFINE_FIELD( m_nType, FIELD_INTEGER ),
|
|
DEFINE_FIELD( m_bExplodes, FIELD_BOOLEAN ),
|
|
DEFINE_FIELD( m_bBounceToFlat, FIELD_BOOLEAN ),
|
|
|
|
// Function Pointers
|
|
DEFINE_FUNCTION( BrickbatTouch ),
|
|
DEFINE_FUNCTION( BrickbatThink ),
|
|
|
|
END_DATADESC()
|
|
|
|
LINK_ENTITY_TO_CLASS( brickbat, CGrenade_Brickbat );
|
|
|
|
void CGrenade_Brickbat::Spawn( void )
|
|
{
|
|
SetCollisionGroup( COLLISION_GROUP_PROJECTILE );
|
|
SetTouch( BrickbatTouch );
|
|
SetThink( BrickbatThink );
|
|
SetNextThink( gpGlobals->curtime + 0.1f );
|
|
|
|
m_takedamage = DAMAGE_YES;
|
|
m_iHealth = 1;
|
|
|
|
SetGravity( 1.0 );
|
|
SetSequence( 1 );
|
|
|
|
CreateVPhysics();
|
|
}
|
|
|
|
bool CGrenade_Brickbat::CreateVPhysics()
|
|
{
|
|
VPhysicsInitNormal( SOLID_VPHYSICS, 0, false );
|
|
IPhysicsObject *pPhysics = VPhysicsGetObject();
|
|
if ( pPhysics )
|
|
{
|
|
// we want world touches
|
|
unsigned int flags = pPhysics->GetCallbackFlags();
|
|
pPhysics->SetCallbackFlags( flags | CALLBACK_GLOBAL_TOUCH_STATIC );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
// Input :
|
|
// Output :
|
|
//-----------------------------------------------------------------------------
|
|
void CGrenade_Brickbat::BrickbatTouch( CBaseEntity *pOther )
|
|
{
|
|
// -----------------------------------------------------------
|
|
// Might be physically simulated so get my velocity manually
|
|
// -----------------------------------------------------------
|
|
Vector vVelocity;
|
|
GetVelocity(&vVelocity,NULL);
|
|
|
|
// -----------------------------------
|
|
// Do damage if we moving fairly fast
|
|
// -----------------------------------
|
|
if (vVelocity.Length() > 100)
|
|
{
|
|
if (GetThrower())
|
|
{
|
|
trace_t tr;
|
|
tr = CBaseEntity::GetTouchTrace( );
|
|
ClearMultiDamage( );
|
|
Vector forward;
|
|
AngleVectors( GetLocalAngles(), &forward );
|
|
|
|
CTakeDamageInfo info( this, GetThrower(), m_flDamage, DMG_CRUSH );
|
|
CalculateMeleeDamageForce( &info, forward, tr.endpos );
|
|
pOther->DispatchTraceAttack( info, forward, &tr );
|
|
ApplyMultiDamage();
|
|
}
|
|
// If this thrown item explodes, blow it up
|
|
if (m_bExplodes)
|
|
{
|
|
Detonate();
|
|
return;
|
|
}
|
|
}
|
|
else if (pOther->GetFlags() & FL_CLIENT)
|
|
{
|
|
SpawnBrickbatWeapon();
|
|
return;
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Purpose : Brickbat grenade turns back into a brickbat weapon
|
|
// Input :
|
|
// Output :
|
|
//------------------------------------------------------------------------------
|
|
void CGrenade_Brickbat::SpawnBrickbatWeapon( void )
|
|
{
|
|
CWeaponBrickbat *pBrickbat = (CWeaponBrickbat*)CBaseEntity::CreateNoSpawn(
|
|
"weapon_brickbat", GetLocalOrigin(), GetLocalAngles(), NULL );
|
|
// Spawn after we set the ammo type so the correct model is used
|
|
if (pBrickbat)
|
|
{
|
|
pBrickbat->m_iCurrentAmmoType = m_nType;
|
|
pBrickbat->Spawn();
|
|
VPhysicsDestroyObject();
|
|
SetThink(NULL);
|
|
UTIL_Remove(this);
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Purpose :
|
|
// Input :
|
|
// Output :
|
|
//------------------------------------------------------------------------------
|
|
void CGrenade_Brickbat::BrickbatThink( void )
|
|
{
|
|
// -----------------------------------------------------------
|
|
// Might be physically simulated so get my velocity manually
|
|
// -----------------------------------------------------------
|
|
Vector vVelocity;
|
|
AngularImpulse vAngVel;
|
|
GetVelocity(&vVelocity,&vAngVel);
|
|
|
|
// See if I can lose my owner (has dropper moved out of way?)
|
|
// Want do this so owner can throw the brickbat
|
|
if (GetOwnerEntity())
|
|
{
|
|
trace_t tr;
|
|
Vector vUpABit = GetAbsOrigin();
|
|
vUpABit.z += 5.0;
|
|
|
|
CBaseEntity* saveOwner = GetOwnerEntity();
|
|
SetOwnerEntity( NULL );
|
|
UTIL_TraceEntity( this, GetAbsOrigin(), vUpABit, MASK_SOLID, &tr );
|
|
if ( tr.startsolid || tr.fraction != 1.0 )
|
|
{
|
|
SetOwnerEntity( saveOwner );
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
// Make sure we're not resting on a living thing's bounding box
|
|
// ---------------------------------------------------------------
|
|
if (vVelocity.Length() < 0.01)
|
|
{
|
|
trace_t tr;
|
|
UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() - Vector(0,0,10), MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );
|
|
|
|
if ( tr.fraction < 1.0 && tr.m_pEnt)
|
|
{
|
|
CBaseEntity *pEntity = tr.m_pEnt;
|
|
if (pEntity->GetFlags() & (FL_CLIENT | FL_NPC))
|
|
{
|
|
// --------------------
|
|
// Bounce me off
|
|
// --------------------
|
|
Vector vNewVel;
|
|
vNewVel.y = 100;
|
|
vNewVel.x = random->RandomInt(-100,100);
|
|
vNewVel.z = random->RandomInt(-100,100);
|
|
|
|
// If physically simulated
|
|
IPhysicsObject *pPhysicsObject = VPhysicsGetObject();
|
|
if ( pPhysicsObject )
|
|
{
|
|
pPhysicsObject->AddVelocity( &vNewVel, &vAngVel );
|
|
}
|
|
// Otherwise
|
|
else
|
|
{
|
|
SetAbsVelocity( vNewVel );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (vVelocity.Length() < 0.01)
|
|
{
|
|
SpawnBrickbatWeapon();
|
|
}
|
|
SetNextThink( gpGlobals->curtime + 0.1f );
|
|
}
|
|
|
|
//=====================================================================
|
|
// > Rock
|
|
//=====================================================================
|
|
class CGrenadeRockBB : public CGrenade_Brickbat
|
|
{
|
|
public:
|
|
DECLARE_CLASS( CGrenadeRockBB, CGrenade_Brickbat );
|
|
|
|
void Spawn(void)
|
|
{
|
|
m_nType = BRICKBAT_ROCK;
|
|
SetModel( "models/props_junk/Rock001a.mdl" );
|
|
BaseClass::Spawn();
|
|
}
|
|
void Precache( void )
|
|
{
|
|
PrecacheModel("models/props_junk/Rock001a.mdl");
|
|
BaseClass::Precache();
|
|
}
|
|
};
|
|
LINK_ENTITY_TO_CLASS( grenade_rockbb, CGrenadeRockBB );
|
|
PRECACHE_REGISTER(grenade_rockbb);
|
|
|
|
|
|
//=====================================================================
|
|
// > BeerBottle
|
|
//=====================================================================
|
|
class CGrenadeBottle : public CGrenade_Brickbat
|
|
{
|
|
public:
|
|
DECLARE_CLASS( CGrenadeBottle, CGrenade_Brickbat );
|
|
|
|
void Spawn(void)
|
|
{
|
|
m_nType = BRICKBAT_BOTTLE;
|
|
m_bExplodes = true;
|
|
SetModel( "models/weapons/w_bb_bottle.mdl" );
|
|
BaseClass::Spawn();
|
|
}
|
|
void Precache( void );
|
|
void Detonate( void );
|
|
};
|
|
|
|
void CGrenadeBottle::Precache( void )
|
|
{
|
|
PrecacheModel("models/weapons/w_bb_bottle.mdl");
|
|
|
|
PrecacheScriptSound( "GrenadeBottle.Detonate" );
|
|
|
|
BaseClass::Precache();
|
|
}
|
|
|
|
void CGrenadeBottle::Detonate( void )
|
|
{
|
|
trace_t trace;
|
|
|
|
UTIL_TraceLine ( GetAbsOrigin(), GetAbsOrigin() + GetAbsVelocity(), MASK_SOLID, this, COLLISION_GROUP_NONE, &trace);
|
|
UTIL_DecalTrace( &trace, "BeerSplash" );
|
|
|
|
EmitSound( "GrenadeBottle.Detonate" );
|
|
|
|
CSoundEnt::InsertSound(SOUND_COMBAT, GetAbsOrigin(), 400, 0.5);
|
|
|
|
UTIL_Remove( this );
|
|
}
|
|
|
|
LINK_ENTITY_TO_CLASS( grenade_beerbottle, CGrenadeBottle );
|
|
PRECACHE_REGISTER(grenade_beerbottle);
|
|
|
|
|