aboutsummaryrefslogtreecommitdiff
path: root/sp/src/game/server/func_break.h
blob: d423c9533895302e87b6f7f0db862d27299fdfe4 (plain) (blame)
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