CBreakable/definitions
Serverside
func_break.h
#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
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;
};
func_break.cpp
BEGIN_DATADESC( CBreakable )
DEFINE_FIELD( m_Material, FIELD_INTEGER ),
DEFINE_KEYFIELD( m_Explosion, FIELD_INTEGER, "explosion" ),
DEFINE_KEYFIELD( m_GibDir, FIELD_VECTOR, "gibdir" ),
DEFINE_FIELD( m_hBreaker, FIELD_EHANDLE ),
// Don't need to save/restore these because we precache after restore
//DEFINE_FIELD( m_idShard, FIELD_INTEGER ),
DEFINE_FIELD( m_angle, FIELD_FLOAT ),
DEFINE_FIELD( m_iszGibModel, FIELD_STRING ),
DEFINE_FIELD( m_iszSpawnObject, FIELD_STRING ),
DEFINE_KEYFIELD( m_ExplosionMagnitude, FIELD_INTEGER, "explodemagnitude" ),
DEFINE_KEYFIELD( m_flPressureDelay, FIELD_FLOAT, "PressureDelay" ),
DEFINE_KEYFIELD( m_iMinHealthDmg, FIELD_INTEGER, "minhealthdmg" ),
DEFINE_FIELD( m_bTookPhysicsDamage, FIELD_BOOLEAN ),
DEFINE_FIELD( m_iszPropData, FIELD_STRING ),
DEFINE_INPUT( m_impactEnergyScale, FIELD_FLOAT, "physdamagescale" ),
DEFINE_KEYFIELD( m_PerformanceMode, FIELD_INTEGER, "PerformanceMode" ),
DEFINE_INPUTFUNC( FIELD_VOID, "Break", InputBreak ),
DEFINE_INPUTFUNC( FIELD_INTEGER, "SetHealth", InputSetHealth ),
DEFINE_INPUTFUNC( FIELD_INTEGER, "AddHealth", InputAddHealth ),
DEFINE_INPUTFUNC( FIELD_INTEGER, "RemoveHealth", InputRemoveHealth ),
DEFINE_INPUTFUNC( FIELD_FLOAT, "SetMass", InputSetMass ),
// Function Pointers
DEFINE_ENTITYFUNC( BreakTouch ),
DEFINE_THINKFUNC( Die ),
// Outputs
DEFINE_OUTPUT(m_OnBreak, "OnBreak"),
DEFINE_OUTPUT(m_OnHealthChanged, "OnHealthChanged"),
DEFINE_FIELD( m_flDmgModBullet, FIELD_FLOAT ),
DEFINE_FIELD( m_flDmgModClub, FIELD_FLOAT ),
DEFINE_FIELD( m_flDmgModExplosive, FIELD_FLOAT ),
DEFINE_FIELD( m_iszPhysicsDamageTableName, FIELD_STRING ),
DEFINE_FIELD( m_iszBreakableModel, FIELD_STRING ),
DEFINE_FIELD( m_iBreakableSkin, FIELD_INTEGER ),
DEFINE_FIELD( m_iBreakableCount, FIELD_INTEGER ),
DEFINE_FIELD( m_iMaxBreakableSize, FIELD_INTEGER ),
DEFINE_FIELD( m_iszBasePropData, FIELD_STRING ),
DEFINE_FIELD( m_iInteractions, FIELD_INTEGER ),
DEFINE_FIELD( m_explodeRadius, FIELD_FLOAT ),
DEFINE_FIELD( m_iszModelName, FIELD_STRING ),
// Physics Influence
DEFINE_FIELD( m_hPhysicsAttacker, FIELD_EHANDLE ),
DEFINE_FIELD( m_flLastPhysicsInfluenceTime, FIELD_TIME ),
END_DATADESC()