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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef PROPS_SHARED_H
#define PROPS_SHARED_H
#ifdef _WIN32
#pragma once
#endif
#include "igamesystem.h"
#include <KeyValues.h>
// Phys prop spawnflags
#define SF_PHYSPROP_START_ASLEEP 0x000001
#define SF_PHYSPROP_DONT_TAKE_PHYSICS_DAMAGE 0x000002 // this prop can't be damaged by physics collisions
#define SF_PHYSPROP_DEBRIS 0x000004
#define SF_PHYSPROP_MOTIONDISABLED 0x000008 // motion disabled at startup (flag only valid in spawn - motion can be enabled via input)
#define SF_PHYSPROP_TOUCH 0x000010 // can be 'crashed through' by running player (plate glass)
#define SF_PHYSPROP_PRESSURE 0x000020 // can be broken by a player standing on it
#define SF_PHYSPROP_ENABLE_ON_PHYSCANNON 0x000040 // enable motion only if the player grabs it with the physcannon
#define SF_PHYSPROP_NO_ROTORWASH_PUSH 0x000080 // The rotorwash doesn't push these
#define SF_PHYSPROP_ENABLE_PICKUP_OUTPUT 0x000100 // If set, allow the player to +USE this for the purposes of generating an output
#define SF_PHYSPROP_PREVENT_PICKUP 0x000200 // If set, prevent +USE/Physcannon pickup of this prop
#define SF_PHYSPROP_PREVENT_PLAYER_TOUCH_ENABLE 0x000400 // If set, the player will not cause the object to enable its motion when bumped into
#define SF_PHYSPROP_HAS_ATTACHED_RAGDOLLS 0x000800 // Need to remove attached ragdolls on enable motion/etc
#define SF_PHYSPROP_FORCE_TOUCH_TRIGGERS 0x001000 // Override normal debris behavior and respond to triggers anyway
#define SF_PHYSPROP_FORCE_SERVER_SIDE 0x002000 // Force multiplayer physics object to be serverside
#define SF_PHYSPROP_RADIUS_PICKUP 0x004000 // For Xbox, makes small objects easier to pick up by allowing them to be found
#define SF_PHYSPROP_ALWAYS_PICK_UP 0x100000 // Physcannon can always pick this up, no matter what mass or constraints may apply.
#define SF_PHYSPROP_NO_COLLISIONS 0x200000 // Don't enable collisions on spawn
#define SF_PHYSPROP_IS_GIB 0x400000 // Limit # of active gibs
// Any barrel farther away than this is ignited rather than exploded.
#define PROP_EXPLOSION_IGNITE_RADIUS 32.0f
// ParsePropData returns
enum
{
PARSE_SUCCEEDED, // Parsed propdata. Prop must be a prop_physics.
PARSE_SUCCEEDED_ALLOWED_STATIC, // Parsed propdata. Prop allowed to be prop_physics or prop_dynamic/prop_static.
PARSE_FAILED_NO_DATA, // Parse failed, no propdata in model. Prop must be prop_dynamic/prop_static.
PARSE_FAILED_BAD_DATA, // Parse failed, found propdata but it had bad data.
};
// Propdata defined interactions
enum propdata_interactions_t
{
PROPINTER_PHYSGUN_WORLD_STICK, // "onworldimpact" "stick"
PROPINTER_PHYSGUN_FIRST_BREAK, // "onfirstimpact" "break"
PROPINTER_PHYSGUN_FIRST_PAINT, // "onfirstimpact" "paintsplat"
PROPINTER_PHYSGUN_FIRST_IMPALE, // "onfirstimpact" "impale"
PROPINTER_PHYSGUN_LAUNCH_SPIN_NONE, // "onlaunch" "spin_none"
PROPINTER_PHYSGUN_LAUNCH_SPIN_Z, // "onlaunch" "spin_zaxis"
PROPINTER_PHYSGUN_BREAK_EXPLODE, // "onbreak" "explode_fire"
PROPINTER_PHYSGUN_DAMAGE_NONE, // "damage" "none"
PROPINTER_FIRE_FLAMMABLE, // "flammable" "yes"
PROPINTER_FIRE_EXPLOSIVE_RESIST, // "explosive_resist" "yes"
PROPINTER_FIRE_IGNITE_HALFHEALTH, // "ignite" "halfhealth"
PROPINTER_PHYSGUN_CREATE_FLARE, // "onpickup" "create_flare"
PROPINTER_PHYSGUN_ALLOW_OVERHEAD, // "allow_overhead" "yes"
PROPINTER_WORLD_BLOODSPLAT, // "onworldimpact", "bloodsplat"
PROPINTER_PHYSGUN_NOTIFY_CHILDREN, // "onfirstimpact" cause attached flechettes to explode
// If we get more than 32 of these, we'll need a different system
PROPINTER_NUM_INTERACTIONS,
};
// Entities using COLLISION_GROUP_SPECIAL_PHYSICS should support this interface.
abstract_class IMultiplayerPhysics
{
public:
virtual int GetMultiplayerPhysicsMode() = 0;
virtual float GetMass() = 0;
virtual bool IsAsleep() = 0;
};
#define PHYSICS_MULTIPLAYER_AUTODETECT 0 // use multiplayer physics mode as defined in model prop data
#define PHYSICS_MULTIPLAYER_SOLID 1 // soild, pushes player away
#define PHYSICS_MULTIPLAYER_NON_SOLID 2 // nonsolid, but pushed by player
#define PHYSICS_MULTIPLAYER_CLIENTSIDE 3 // Clientside only, nonsolid
enum mp_break_t
{
MULTIPLAYER_BREAK_DEFAULT,
MULTIPLAYER_BREAK_SERVERSIDE,
MULTIPLAYER_BREAK_CLIENTSIDE,
MULTIPLAYER_BREAK_BOTH
};
enum PerformanceMode_t
{
PM_NORMAL,
PM_NO_GIBS,
PM_FULL_GIBS,
PM_REDUCED_GIBS,
};
//=============================================================================================================
// PROP DATA
//=============================================================================================================
//-----------------------------------------------------------------------------
// Purpose: Derive your entity from this if you want your entity to parse propdata
//-----------------------------------------------------------------------------
abstract_class IBreakableWithPropData
{
public:
// Damage modifiers
virtual void SetDmgModBullet( float flDmgMod ) = 0;
virtual void SetDmgModClub( float flDmgMod ) = 0;
virtual void SetDmgModExplosive( float flDmgMod ) = 0;
virtual float GetDmgModBullet( void ) = 0;
virtual float GetDmgModClub( void ) = 0;
virtual float GetDmgModExplosive( void ) = 0;
// Explosive
virtual void SetExplosiveRadius( float flRadius ) = 0;
virtual void SetExplosiveDamage( float flDamage ) = 0;
virtual float GetExplosiveRadius( void ) = 0;
virtual float GetExplosiveDamage( void ) = 0;
// Physics damage tables
virtual void SetPhysicsDamageTable( string_t iszTableName ) = 0;
virtual string_t GetPhysicsDamageTable( void ) = 0;
// Breakable chunks
virtual void SetBreakableModel( string_t iszModel ) = 0;
virtual string_t GetBreakableModel( void ) = 0;
virtual void SetBreakableSkin( int iSkin ) = 0;
virtual int GetBreakableSkin( void ) = 0;
virtual void SetBreakableCount( int iCount ) = 0;
virtual int GetBreakableCount( void ) = 0;
virtual void SetMaxBreakableSize( int iSize ) = 0;
virtual int GetMaxBreakableSize( void ) = 0;
// LOS blocking
virtual void SetPropDataBlocksLOS( bool bBlocksLOS ) = 0;
virtual void SetPropDataIsAIWalkable( bool bBlocksLOS ) = 0;
// Interactions
virtual void SetInteraction( propdata_interactions_t Interaction ) = 0;
virtual bool HasInteraction( propdata_interactions_t Interaction ) = 0;
// Multiplayer physics mode
virtual void SetPhysicsMode(int iMode) = 0;
virtual int GetPhysicsMode() = 0;
// Multiplayer breakable spawn behavior
virtual void SetMultiplayerBreakMode( mp_break_t mode ) = 0;
virtual mp_break_t GetMultiplayerBreakMode( void ) const = 0;
// Used for debugging
virtual void SetBasePropData( string_t iszBase ) = 0;
virtual string_t GetBasePropData( void ) = 0;
};
//-----------------------------------------------------------------------------
// Purpose: Gamesystem that parses the prop data file
//-----------------------------------------------------------------------------
class CPropData : public CAutoGameSystem
{
public:
CPropData( void );
// Inherited from IAutoServerSystem
virtual void LevelInitPreEntity( void );
virtual void LevelShutdownPostEntity( void );
// Read in the data from the prop data file
void ParsePropDataFile( void );
// Parse a keyvalues section into the prop
int ParsePropFromKV( CBaseEntity *pProp, KeyValues *pSection, KeyValues *pInteractionSection );
// Fill out a prop's with base data parsed from the propdata file
int ParsePropFromBase( CBaseEntity *pProp, const char *pszPropData );
// Get a random chunk in the specified breakable section
const char *GetRandomChunkModel( const char *pszBreakableSection, int iMaxSize = -1 );
protected:
KeyValues *m_pKVPropData;
bool m_bPropDataLoaded;
struct propdata_breakablechunk_t
{
string_t iszChunkType;
CUtlVector<string_t> iszChunkModels;
};
CUtlVector<propdata_breakablechunk_t> m_BreakableChunks;
};
extern CPropData g_PropDataSystem;
struct breakmodel_t
{
Vector offset;
char modelName[512];
char placementName[512];
float fadeTime;
float fadeMinDist;
float fadeMaxDist;
float health;
float burstScale;
int collisionGroup;
bool isRagdoll;
bool placementIsBone;
bool isMotionDisabled;
mp_break_t mpBreakMode;
};
struct breakablepropparams_t
{
breakablepropparams_t( const Vector &_origin, const QAngle &_angles, const Vector &_velocity, const AngularImpulse &_angularVelocity )
: origin(_origin), angles(_angles), velocity(_velocity), angularVelocity(_angularVelocity)
{
impactEnergyScale = 0;
defBurstScale = 0;
defCollisionGroup = COLLISION_GROUP_NONE;
nDefaultSkin = 0;
}
const Vector &origin;
const QAngle &angles;
const Vector &velocity;
const AngularImpulse &angularVelocity;
float impactEnergyScale;
float defBurstScale;
int defCollisionGroup;
int nDefaultSkin;
};
const char *GetMassEquivalent(float flMass);
int GetAutoMultiplayerPhysicsMode( Vector size, float mass );
void BreakModelList( CUtlVector<breakmodel_t> &list, int modelindex, float defBurstScale, int defCollisionGroup );
void PropBreakableCreateAll( int modelindex, IPhysicsObject *pPhysics, const breakablepropparams_t ¶ms, CBaseEntity *pEntity, int iPrecomputedBreakableCount, bool bIgnoreGibLImit, bool defaultLocation = true );
void PropBreakableCreateAll( int modelindex, IPhysicsObject *pPhysics, const Vector &origin, const QAngle &angles, const Vector &velocity, const AngularImpulse &angularVelocity, float impactEnergyScale, float burstScale, int collisionGroup, CBaseEntity *pEntity = NULL, bool defaultLocation = true );
// Player gibs.
void PrecacheGibsForModel( int iModel );
void BuildGibList( CUtlVector<breakmodel_t> &list, int modelindex, float defBurstScale, int defCollisionGroup );
CBaseEntity *CreateGibsFromList( CUtlVector<breakmodel_t> &list, int modelindex, IPhysicsObject *pPhysics, const breakablepropparams_t ¶ms, CBaseEntity *pEntity, int iPrecomputedBreakableCount, bool bIgnoreGibLImit, bool defaultLocation = true, CUtlVector<EHANDLE> *pGibList = NULL, bool bBurning = false );
#endif // PROPS_SHARED_H
|