|
|
//========= 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);
|