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.
286 lines
6.5 KiB
286 lines
6.5 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//============================================================================= |
|
|
|
#include "cbase.h" |
|
#include "tf_weapon_bottle.h" |
|
#include "decals.h" |
|
|
|
// Client specific. |
|
#ifdef CLIENT_DLL |
|
#include "c_tf_player.h" |
|
// Server specific. |
|
#else |
|
#include "tf_player.h" |
|
#include "tf_fx.h" |
|
#include "tf_gamerules.h" |
|
#endif |
|
|
|
//============================================================================= |
|
// |
|
// Weapon Bottle tables. |
|
// |
|
IMPLEMENT_NETWORKCLASS_ALIASED( TFBottle, DT_TFWeaponBottle ) |
|
|
|
BEGIN_NETWORK_TABLE( CTFBottle, DT_TFWeaponBottle ) |
|
#if defined( CLIENT_DLL ) |
|
RecvPropBool( RECVINFO( m_bBroken ) ) |
|
#else |
|
SendPropBool( SENDINFO( m_bBroken ) ) |
|
#endif |
|
END_NETWORK_TABLE() |
|
|
|
BEGIN_PREDICTION_DATA( CTFBottle ) |
|
END_PREDICTION_DATA() |
|
|
|
LINK_ENTITY_TO_CLASS( tf_weapon_bottle, CTFBottle ); |
|
PRECACHE_WEAPON_REGISTER( tf_weapon_bottle ); |
|
|
|
//============================================================================= |
|
// |
|
// Weapon Stickbomb tables. |
|
// |
|
IMPLEMENT_NETWORKCLASS_ALIASED( TFStickBomb, DT_TFWeaponStickBomb ) |
|
|
|
#ifdef CLIENT_DLL |
|
void RecvProxy_Detonated( const CRecvProxyData *pData, void *pStruct, void *pOut ); |
|
#endif |
|
|
|
BEGIN_NETWORK_TABLE( CTFStickBomb, DT_TFWeaponStickBomb ) |
|
#if defined( CLIENT_DLL ) |
|
RecvPropInt( RECVINFO( m_iDetonated ), 0, RecvProxy_Detonated ) |
|
#else |
|
SendPropInt( SENDINFO( m_iDetonated ), 1, SPROP_UNSIGNED ) |
|
#endif |
|
END_NETWORK_TABLE() |
|
|
|
BEGIN_PREDICTION_DATA( CTFStickBomb ) |
|
END_PREDICTION_DATA() |
|
|
|
LINK_ENTITY_TO_CLASS( tf_weapon_stickbomb, CTFStickBomb ); |
|
PRECACHE_WEAPON_REGISTER( tf_weapon_stickbomb ); |
|
|
|
#ifdef STAGING_ONLY |
|
#define TF_WEAPON_STICKBOMB_NORMAL_MODEL "models/workshop/weapons/c_models/c_caber/c_caber.mdl" |
|
#define TF_WEAPON_STICKBOMB_BROKEN_MODEL "models/workshop/weapons/c_models/c_caber/c_caber_exploded.mdl" |
|
#else |
|
#define TF_WEAPON_STICKBOMB_NORMAL_MODEL "models/weapons/c_models/c_caber/c_caber.mdl" |
|
#define TF_WEAPON_STICKBOMB_BROKEN_MODEL "models/weapons/c_models/c_caber/c_caber_exploded.mdl" |
|
#endif |
|
|
|
//============================================================================= |
|
|
|
#define TF_BOTTLE_SWITCHGROUP 1 |
|
#define TF_BOTTLE_NOTBROKEN 0 |
|
#define TF_BOTTLE_BROKEN 1 |
|
|
|
//============================================================================= |
|
// |
|
// Weapon Bottle functions. |
|
// |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CTFBottle::CTFBottle() |
|
{ |
|
} |
|
|
|
void CTFBottle::WeaponReset( void ) |
|
{ |
|
BaseClass::WeaponReset(); |
|
|
|
m_bBroken = false; |
|
} |
|
|
|
bool CTFBottle::DefaultDeploy( char *szViewModel, char *szWeaponModel, int iActivity, char *szAnimExt ) |
|
{ |
|
bool bRet = BaseClass::DefaultDeploy( szViewModel, szWeaponModel, iActivity, szAnimExt ); |
|
|
|
if ( bRet ) |
|
{ |
|
SwitchBodyGroups(); |
|
} |
|
|
|
return bRet; |
|
} |
|
|
|
void CTFBottle::SwitchBodyGroups( void ) |
|
{ |
|
int iState = 0; |
|
|
|
if ( m_bBroken == true ) |
|
{ |
|
iState = 1; |
|
} |
|
|
|
SetBodygroup( TF_BOTTLE_SWITCHGROUP, iState ); |
|
|
|
CTFPlayer *pTFPlayer = ToTFPlayer( GetOwner() ); |
|
|
|
if ( pTFPlayer && pTFPlayer->GetActiveWeapon() == this ) |
|
{ |
|
if ( pTFPlayer->GetViewModel() ) |
|
{ |
|
pTFPlayer->GetViewModel()->SetBodygroup( TF_BOTTLE_SWITCHGROUP, iState ); |
|
} |
|
} |
|
} |
|
|
|
void CTFBottle::Smack( void ) |
|
{ |
|
BaseClass::Smack(); |
|
|
|
if ( ConnectedHit() && IsCurrentAttackACrit() ) |
|
{ |
|
m_bBroken = true; |
|
SwitchBodyGroups(); |
|
} |
|
} |
|
|
|
CTFStickBomb::CTFStickBomb() |
|
: CTFBottle() |
|
{ |
|
m_iDetonated = 0; |
|
} |
|
|
|
void CTFStickBomb::Precache( void ) |
|
{ |
|
BaseClass::Precache(); |
|
|
|
PrecacheModel( TF_WEAPON_STICKBOMB_NORMAL_MODEL ); |
|
PrecacheModel( TF_WEAPON_STICKBOMB_BROKEN_MODEL ); |
|
} |
|
|
|
void CTFStickBomb::Smack( void ) |
|
{ |
|
CTFWeaponBaseMelee::Smack(); |
|
|
|
// Stick bombs detonate once, on impact. |
|
if ( m_iDetonated == 0 && ConnectedHit() ) |
|
{ |
|
m_iDetonated = 1; |
|
m_bBroken = true; |
|
SwitchBodyGroups(); |
|
|
|
#ifdef GAME_DLL |
|
CTFPlayer *pTFPlayer = ToTFPlayer( GetOwner() ); |
|
if ( pTFPlayer ) |
|
{ |
|
Vector vecForward; |
|
AngleVectors( pTFPlayer->EyeAngles(), &vecForward ); |
|
Vector vecSwingStart = pTFPlayer->Weapon_ShootPosition(); |
|
Vector vecSwingEnd = vecSwingStart + vecForward * GetSwingRange(); |
|
|
|
Vector explosion = vecSwingStart; |
|
|
|
CPVSFilter filter( explosion ); |
|
|
|
// Halloween Spell |
|
int iHalloweenSpell = 0; |
|
int iCustomParticleIndex = INVALID_STRING_INDEX; |
|
if ( TF_IsHolidayActive( kHoliday_HalloweenOrFullMoon ) ) |
|
{ |
|
CALL_ATTRIB_HOOK_INT_ON_OTHER( this, iHalloweenSpell, halloween_pumpkin_explosions ); |
|
if ( iHalloweenSpell > 0 ) |
|
{ |
|
iCustomParticleIndex = GetParticleSystemIndex( "halloween_explosion" ); |
|
} |
|
} |
|
|
|
TE_TFExplosion( filter, 0.0f, explosion, Vector(0,0,1), TF_WEAPON_GRENADELAUNCHER, pTFPlayer->entindex(), -1, SPECIAL1, iCustomParticleIndex ); |
|
|
|
int dmgType = DMG_BLAST | DMG_USEDISTANCEMOD; |
|
if ( IsCurrentAttackACrit() ) |
|
dmgType |= DMG_CRITICAL; |
|
|
|
CTakeDamageInfo info( pTFPlayer, pTFPlayer, this, explosion, explosion, 75.0f, dmgType, TF_DMG_CUSTOM_STICKBOMB_EXPLOSION, &explosion ); |
|
CTFRadiusDamageInfo radiusinfo( &info, explosion, 100.f ); |
|
TFGameRules()->RadiusDamage( radiusinfo ); |
|
} |
|
#endif |
|
} |
|
} |
|
|
|
void CTFStickBomb::WeaponReset( void ) |
|
{ |
|
BaseClass::WeaponReset(); |
|
|
|
m_iDetonated = 0; |
|
|
|
SwitchBodyGroups(); |
|
} |
|
|
|
void CTFStickBomb::WeaponRegenerate( void ) |
|
{ |
|
BaseClass::WeaponRegenerate(); |
|
|
|
m_iDetonated = 0; |
|
|
|
SetContextThink( &CTFStickBomb::SwitchBodyGroups, gpGlobals->curtime + 0.01f, "SwitchBodyGroups" ); |
|
} |
|
|
|
void CTFStickBomb::SwitchBodyGroups( void ) |
|
{ |
|
#ifdef CLIENT_DLL |
|
if ( !GetViewmodelAttachment() ) |
|
return; |
|
|
|
if ( m_iDetonated == 1 ) |
|
{ |
|
GetViewmodelAttachment()->SetModel( TF_WEAPON_STICKBOMB_BROKEN_MODEL ); |
|
} |
|
else |
|
{ |
|
GetViewmodelAttachment()->SetModel( TF_WEAPON_STICKBOMB_NORMAL_MODEL ); |
|
} |
|
#endif |
|
} |
|
|
|
const char *CTFStickBomb::GetWorldModel( void ) const |
|
{ |
|
if ( m_iDetonated == 1 ) |
|
{ |
|
return TF_WEAPON_STICKBOMB_BROKEN_MODEL; |
|
} |
|
else |
|
{ |
|
return BaseClass::GetWorldModel(); |
|
} |
|
} |
|
|
|
#ifdef CLIENT_DLL |
|
int CTFStickBomb::GetWorldModelIndex( void ) |
|
{ |
|
if ( !modelinfo ) |
|
return BaseClass::GetWorldModelIndex(); |
|
|
|
if ( m_iDetonated == 1 ) |
|
{ |
|
m_iWorldModelIndex = modelinfo->GetModelIndex( TF_WEAPON_STICKBOMB_BROKEN_MODEL ); |
|
return m_iWorldModelIndex; |
|
} |
|
else |
|
{ |
|
m_iWorldModelIndex = modelinfo->GetModelIndex( TF_WEAPON_STICKBOMB_NORMAL_MODEL ); |
|
return m_iWorldModelIndex; |
|
} |
|
} |
|
#endif |
|
|
|
#ifdef CLIENT_DLL |
|
|
|
void RecvProxy_Detonated( const CRecvProxyData *pData, void *pStruct, void *pOut ) |
|
{ |
|
C_TFStickBomb* pBomb = (C_TFStickBomb*) pStruct; |
|
|
|
if ( pData->m_Value.m_Int != pBomb->GetDetonated() ) |
|
{ |
|
pBomb->SetDetonated( pData->m_Value.m_Int ); |
|
pBomb->SwitchBodyGroups(); |
|
} |
|
} |
|
|
|
#endif
|
|
|