1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Defines a class for objects that break after taking a certain amount
// of damage.
//
// $NoKeywords: $
//=============================================================================//
#ifndef FUNC_BREAK_H
#define FUNC_BREAK_H
#pragma once
#include "entityoutput.h"
#include "props.h"
typedef enum { expRandom = 0, expDirected, expUsePrecise} Explosions;
typedef enum { matGlass = 0, matWood, matMetal, matFlesh, matCinderBlock, matCeilingTile, matComputer, matUnbreakableGlass, matRocks, matWeb, matNone, matLastMaterial } Materials;
#define NUM_SHARDS 6 // this many shards spawned when breakable objects break;
// Spawnflags for func breakable
#define SF_BREAK_TRIGGER_ONLY 0x0001 // may only be broken by trigger
#define SF_BREAK_TOUCH 0x0002 // can be 'crashed through' by running player (plate glass)
#define SF_BREAK_PRESSURE 0x0004 // can be broken by a player standing on it
#define SF_BREAK_PHYSICS_BREAK_IMMEDIATELY 0x0200 // the first physics collision this breakable has will immediately break it
#define SF_BREAK_DONT_TAKE_PHYSICS_DAMAGE 0x0400 // this breakable doesn't take damage from physics collisions
#define SF_BREAK_NO_BULLET_PENETRATION 0x0800 // don't allow bullets to penetrate
// Spawnflags for func_pushable (it's also func_breakable, so don't collide with those flags)
#define SF_PUSH_BREAKABLE 0x0080
#define SF_PUSH_NO_USE 0x0100 // player cannot +use pickup this ent
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
class CBreakable : public CBaseEntity, public IBreakableWithPropData, public CDefaultPlayerPickupVPhysics
{
public:
DECLARE_CLASS( CBreakable, CBaseEntity );
// basic functions
virtual void Spawn( void );
void ParsePropData( void );
bool CreateVPhysics( void );
virtual void Precache( void );
virtual bool KeyValue( const char *szKeyName, const char *szValue );
virtual void VPhysicsCollision( int index, gamevcollisionevent_t *pEvent );
void BreakTouch( CBaseEntity *pOther );
void DamageSound( void );
void Break( CBaseEntity *pBreaker );
// Input handlers
void InputAddHealth( inputdata_t &inputdata );
void InputBreak( inputdata_t &inputdata );
void InputRemoveHealth( inputdata_t &inputdata );
void InputSetHealth( inputdata_t &inputdata );
void InputSetMass( inputdata_t &inputdata );
// breakables use an overridden takedamage
virtual int OnTakeDamage( const CTakeDamageInfo &info );
// To spark when hit
void TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator );
bool IsBreakable( void );
bool SparkWhenHit( void );
char const *DamageDecal( int bitsDamageType, int gameMaterial );
virtual void Die( void );
void ResetOnGroundFlags(void);
inline bool Explodable( void ) { return GetExplosiveRadius() > 0; }
Materials GetMaterialType( void ) { return m_Material; }
static void MaterialSoundRandom( int entindex, Materials soundMaterial, float volume );
static const char *MaterialSound( Materials precacheMaterial );
static const char *pSpawnObjects[];
int DrawDebugTextOverlays(void);
DECLARE_DATADESC();
public:
// IBreakableWithPropData
void SetDmgModBullet( float flDmgMod ) { m_flDmgModBullet = flDmgMod; }
void SetDmgModClub( float flDmgMod ) { m_flDmgModClub = flDmgMod; }
void SetDmgModExplosive( float flDmgMod ) { m_flDmgModExplosive = flDmgMod; }
float GetDmgModBullet( void ) { return m_flDmgModBullet; }
float GetDmgModClub( void ) { return m_flDmgModClub; }
float GetDmgModExplosive( void ) { return m_flDmgModExplosive; }
void SetExplosiveRadius( float flRadius ) { m_explodeRadius = flRadius; }
void SetExplosiveDamage( float flDamage ) { m_ExplosionMagnitude = flDamage; }
float GetExplosiveRadius( void ) { return m_explodeRadius; }
float GetExplosiveDamage( void ) { return m_ExplosionMagnitude; }
void SetPhysicsDamageTable( string_t iszTableName ) { m_iszPhysicsDamageTableName = iszTableName; }
string_t GetPhysicsDamageTable( void ) { return m_iszPhysicsDamageTableName; }
void SetBreakableModel( string_t iszModel ) { m_iszBreakableModel = iszModel; }
string_t GetBreakableModel( void ) { return m_iszBreakableModel; }
void SetBreakableSkin( int iSkin ) { m_iBreakableSkin = iSkin; }
int GetBreakableSkin( void ) { return m_iBreakableSkin; }
void SetBreakableCount( int iCount ) { m_iBreakableCount = iCount; }
int GetBreakableCount( void ) { return m_iBreakableCount; }
void SetMaxBreakableSize( int iSize ) { m_iMaxBreakableSize = iSize; }
int GetMaxBreakableSize( void ) { return m_iMaxBreakableSize; }
void SetPropDataBlocksLOS( bool bBlocksLOS ) { SetBlocksLOS( bBlocksLOS ); }
void SetPropDataIsAIWalkable( bool bBlocksLOS ) { SetAIWalkable( bBlocksLOS ); }
void SetBasePropData( string_t iszBase ) { m_iszBasePropData = iszBase; }
string_t GetBasePropData( void ) { return m_iszBasePropData; }
void SetInteraction( propdata_interactions_t Interaction ) { m_iInteractions |= (1 << Interaction); }
bool HasInteraction( propdata_interactions_t Interaction ) { return ( m_iInteractions & (1 << Interaction) ) != 0; }
void SetPhysicsMode(int iMode){}
int GetPhysicsMode() { return PHYSICS_MULTIPLAYER_SOLID; }
void SetMultiplayerBreakMode( mp_break_t mode ) {}
mp_break_t GetMultiplayerBreakMode( void ) const { return MULTIPLAYER_BREAK_DEFAULT; }
protected:
float m_angle;
Materials m_Material;
EHANDLE m_hBreaker; // The entity that broke us. Held as a data member because sometimes breaking is delayed.
private:
Explosions m_Explosion;
QAngle m_GibDir;
string_t m_iszGibModel;
string_t m_iszSpawnObject;
int m_ExplosionMagnitude;
float m_flPressureDelay; // Delay before breaking when destoyed by pressure
int m_iMinHealthDmg; // minimum damage attacker must have to cause damage
bool m_bTookPhysicsDamage;
string_t m_iszPropData;
string_t m_iszModelName;
protected:
bool UpdateHealth( int iNewHealth, CBaseEntity *pActivator );
float m_impactEnergyScale;
COutputEvent m_OnBreak;
COutputFloat m_OnHealthChanged;
// Prop data storage
float m_flDmgModBullet;
float m_flDmgModClub;
float m_flDmgModExplosive;
string_t m_iszPhysicsDamageTableName;
string_t m_iszBreakableModel;
int m_iBreakableSkin;
int m_iBreakableCount;
int m_iMaxBreakableSize;
string_t m_iszBasePropData;
int m_iInteractions;
PerformanceMode_t m_PerformanceMode;
float m_explodeRadius;
public:
// IPlayerPickupVPhysics
virtual void OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t reason );
virtual void OnPhysGunDrop( CBasePlayer *pPhysGunUser, PhysGunDrop_t Reason );
virtual CBasePlayer *HasPhysicsAttacker( float dt );
private:
CHandle<CBasePlayer> m_hPhysicsAttacker;
float m_flLastPhysicsInfluenceTime;
};
#endif // FUNC_BREAK_H
|