summaryrefslogtreecommitdiff
path: root/game/server/tf2/tf_obj.h
blob: b53002d46d6ad03d6f0492693183300147f50a05 (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
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
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Base Object built by a player
//
// $NoKeywords: $
//=============================================================================//

#ifndef TF_OBJ_H
#define TF_OBJ_H
#ifdef _WIN32
#pragma once
#endif

#include "baseentity.h"
#include "tf_func_resource.h"
#include "ihasbuildpoints.h"
#include "baseobject_shared.h"
#include "info_vehicle_bay.h"

class CBaseTFPlayer;
class CTFTeam;
class CRopeKeyframe;
class CBaseTechnology;
class CGrenadeObjectSapper;
class CObjectPowerPack;
class CVGuiScreen;
class CResourceZone;
class KeyValues;
class CObjectBuffStation;
struct animevent_t;

#define OBJECT_REPAIR_RATE		10			// Health healed per second while repairing

// Construction
#define OBJECT_CONSTRUCTION_INTERVAL			0.1
#define OBJECT_CONSTRUCTION_STARTINGHEALTH		0.1


extern ConVar object_verbose;
extern ConVar obj_child_range_factor;

#if defined( _DEBUG )
#define TRACE_OBJECT( str )										\
if ( object_verbose.GetInt() )									\
{																\
	Msg( "%s", str );					\
}																
#else
#define TRACE_OBJECT( string )
#endif


// ------------------------------------------------------------------------ //
// Resupply object that's built by the player
// ------------------------------------------------------------------------ //
class CBaseObject : public CBaseCombatCharacter, public IHasBuildPoints
{
	DECLARE_CLASS( CBaseObject, CBaseCombatCharacter );
public:
	CBaseObject();

	virtual void	UpdateOnRemove( void );

	DECLARE_SERVERCLASS();
	DECLARE_DATADESC();

	virtual bool	IsBaseObject( void ) const { return true; }

	virtual void	BaseObjectThink( void );
	virtual void	LostPowerThink( void );
	virtual CBaseTFPlayer *GetOwner( void );

	// Creation
	virtual void	Precache();
	virtual void	Spawn( void );
	virtual void	Activate( void );
	void			InitializeMapPlacedObject( void );

	virtual void	SetBuilder( CBaseTFPlayer *pBuilder, bool moveobjects = false );
	virtual void	SetupTeamModel( void ) { return; }
	virtual void	SetType( int iObjectType );
	int				ObjectType( ) const;

	virtual int		BloodColor( void ) { return BLOOD_COLOR_MECH; }

	// Building
	virtual float	GetTotalTime( void );
	virtual void	StartPlacement( CBaseTFPlayer *pPlayer );
	void			StopPlacement( void );
	bool			FindNearestBuildPoint( CBaseEntity *pEntity, Vector vecBuildOrigin, float &flNearestPoint, Vector &vecNearestBuildPoint );
	virtual bool	CalculatePlacement( CBaseTFPlayer *pPlayer );
	bool			CheckBuildPoint( Vector vecPoint, Vector &vecTrace, Vector *vecOutPoint=NULL );
	bool			VerifyCorner( const Vector &vBottomCenter, float xOffset, float yOffset );
	virtual bool	CheckBuildOrigin( CBaseTFPlayer *pPlayer, const Vector &vecBuildOrigin, bool bSnappedToPoint = false );
	void			AttemptToFindPower( void );
	void			AttemptToFindBuffStation( void );
	void			AttemptToActivateBuffStation( void );
	virtual float	GetNearbyObjectCheckRadius( void ) { return 30.0; }
	bool			UpdatePlacement( CBaseTFPlayer *pPlayer );
	virtual bool	ShouldAttachToParent( void ) { return true; }
	void			SetVehicleBay( CVGuiScreenVehicleBay *pBay ) { m_hVehicleBay = pBay; }

	// Sort of a hack for walkers - vehicles are pre-rotated by 90 degrees and walkers need to undo this.
	virtual void	AdjustInitialBuildAngles();
	
	// Exit points for mounted vehicles....
	virtual void	GetExitPoint( CBaseEntity *pPlayer, int nBuildPoint, Vector *pExitPoint, QAngle *pAngles );

	// I've finished building the specified object on the specified build point
	virtual int		FindObjectOnBuildPoint( CBaseObject *pObject );

	// This gives an object a chance to prevent itself from being built when the user clicks the 
	// attack button during placement. Barbed wire uses this to change which object the barbed wire 
	// is attached to.
	virtual bool PreStartBuilding();
	
	virtual bool	StartBuilding( CBaseEntity *pPlayer );
	void			BuildingThink( void );
	void			SetControlPanelsActive( bool bState );
	virtual void	FinishedBuilding( void );
	bool			IsBuilding( void ) { return m_bBuilding; };
	bool			IsPlacing( void ) { return m_bPlacing; };
	bool			MustBeBuiltInResourceZone( void ) const;
	bool			MustBeBuiltInConstructionYard( void ) const;
	virtual bool	MustNotBeBuiltInConstructionYard( void ) const;
	bool			MustBeBuiltOnAttachmentPoint( void ) const;

	void			AlignToGround( Vector vecOrigin );

	// Returns information about the various control panels
	virtual void 	GetControlPanelInfo( int nPanelIndex, const char *&pPanelName );
	virtual void	GetControlPanelClassName( int nPanelIndex, const char *&pPanelName );

	// Client commands sent by clicking on various panels....
	// NOTE: pArg->Argv(0) == pCmd, pArg->Argv(1) == the first argument
	virtual bool	ClientCommand( CBaseTFPlayer *pSender, const CCommand &args );

	// Damage
	void			SetHealth( float flHealth );
	virtual void	TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr );
	virtual int		OnTakeDamage( const CTakeDamageInfo &info );
	bool			PassDamageOntoChildren( const CTakeDamageInfo &info, float *flDamageLeftOver );
	virtual float	GetRepairTime( void );
	virtual bool	UpdateRepair( float flRepairTime );
	virtual bool	Repair( float flHealth );

	// Powerups
	virtual bool	CanPowerupEver( int iPowerup );
	virtual bool	CanPowerupNow( int iPowerup );
	virtual void	PowerupStart( int iPowerup, float flAmount, CBaseEntity *pAttacker, CDamageModifier *pDamageModifier );
	virtual	void	PowerupEnd( int iPowerup );

	// Destruction
	virtual bool	ShouldAutoRemove( void );
	virtual void	Killed( void );
	virtual void	DestroyObject( void );		// Silent cleanup
	virtual bool	IsDying( void ) { return m_bDying; }

	// Data
	virtual Class_T	Classify( void );
	virtual int		GetType( void );
	virtual CBaseTFPlayer *GetBuilder( void );
	virtual CBaseTFPlayer *GetOriginalBuilder( void );
	CTFTeam			*GetTFTeam( void ) { return (CTFTeam*)GetTeam(); };
	
	// ID functions
	virtual bool	IsAnUpgrade( void )			{ return false; }
	virtual bool	IsAVehicle( void )			{ return false; }
	virtual bool	IsSentrygun()				{ return false; }
	virtual bool	WantsCoverFromSentryGun()	{ return false; }
	virtual bool	WantsCover()				{ return false; }

	// Inputs
	void			InputSetHealth( inputdata_t &inputdata );
	void			InputAddHealth( inputdata_t &inputdata );
	void			InputRemoveHealth( inputdata_t &inputdata );
	void			InputSetMinDisabledHealth( inputdata_t &inputdata );
	void			InputSetSolidToPlayer( inputdata_t &inputdata );

	// Pickup
	virtual int		ObjectCaps( void );
	virtual void	Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
	virtual void	PickupObject( void );
	virtual bool	CanBeRemovedBy( CBaseTFPlayer *pPlayer );
	virtual bool	CanBeRotatedBy( CBaseTFPlayer *pPlayer );

	virtual void	ChangeTeam( int iTeamNum ) OVERRIDE;			// Assign this entity to a team.

	virtual void	ChangeBuilder( CBaseTFPlayer *pNewBuilder, bool moveobjects );
	virtual const char *GetWeaponClassnameForObject( void );
	virtual void	AddItemsNeededForObject( CBaseTFPlayer *pNewOwner );

	// Objects that are damaged/disabled can return false here when checked for being available
	virtual bool	ComputeEMPDamageState( void ) { return true; }

	// Handling object inactive
	virtual bool	ShouldBeActive( void );

	// Technology
	virtual void	GainedNewTechnology( CBaseTechnology *pTechnology );

	// Sappers
	bool			HasSapper( void );
	bool			HasSapperFromPlayer( CBaseTFPlayer *pPlayer );
	void			AddSapper( CGrenadeObjectSapper *pSapper );
	void			RemoveSapper( CGrenadeObjectSapper *pSapper );

	// Called when the builder rotates this object...
	virtual void	ObjectMoved( );

	// Minibase stuff
	virtual bool	WasMapPlaced( void );
	virtual CRopeKeyframe *ConnectCableTo( CBaseObject *pObject, int iLocalAttachment, int iTargetAttachment );
	virtual bool	HasCableTo( CBaseObject *pObject );
	virtual int		GetCableAttachment( void );

	// Returns the object flags
	int				GetObjectFlags() const { return m_fObjectFlags; }
	void			SetObjectFlags( int flags ) { m_fObjectFlags = flags; }

	CResourceZone	*GetResourceZone() { return m_hResourceZone.Get(); }
	int				RopeCount() const { return m_aRopes.Count(); }

	// Power handling (Human objects need power to operate)
	bool				IsPowered( void );
	void				SetPowerPack( CObjectPowerPack *pPack );
	CObjectPowerPack	*GetPowerPack( void ) { return m_hPowerPack; };

	void			AttemptToGoActive( void );
	virtual void	OnGoActive( void );
	virtual void	OnGoInactive( void );

	// Buffed objects (objects that connect to a medic's buff station)
	bool			IsHookedAndBuffed( void );
	virtual bool	CanBeHookedToBuffStation( void );
	void			SetBuffStation( CObjectBuffStation *pBuffStation, bool bPlacing );
	CObjectBuffStation *GetBuffStation( void );

	virtual void	BuffStationActivate( void );
	virtual void	BuffStationDeactivate( void );

	// Deterioration
	void			StartDeteriorating( void );
	void			StopDeteriorating( void );
	bool			IsDeteriorating( void ) { return m_bDeteriorating; };
	void			DeterioratingThink( void );

	// Disabling
	void			SetDisabled( bool bDisabled );
	bool			IsDisabled( void ) { return m_bDisabled; }

	// Animation
	virtual void	PlayStartupAnimation( void );

	Activity		GetActivity( ) const;
	void			SetActivity( Activity act );
	void			SetObjectSequence( int sequence );
	
	virtual void	OnActivityChanged( Activity act );

	// Object points
	void			SpawnObjectPoints( void );

	// Derive to customize an object's attached version
	virtual	void	SetupAttachedVersion( void ) { return; }
	virtual void	SetupUnattachedVersion( void ) { return; }

	QAngle			ConvertAbsAnglesToLocal( QAngle vecLocalAngles );

public:
	// VulnerablePoints
	void				CreateVulnerablePoints( void );
	void				AddVulnerablePoint( const char* szHitboxName, float Multiplier );
	float				FindVulnerablePointMultiplier( int nGroup, int nBox ); 		

	// Build points
	CUtlVector<VulnerablePoint_t>	m_VulnerablePoints;

	virtual bool TestHitboxes( const Ray_t &ray, unsigned int fContentsMask, trace_t& tr );

public:
	// Client/Server shared build point code
	void				CreateBuildPoints( void );
	void				AddAndParseBuildPoint( int iAttachmentNumber, KeyValues *pkvBuildPoint );
	virtual int			AddBuildPoint( int iAttachmentNum );
	virtual void		AddValidObjectToBuildPoint( int iPoint, int iObjectType );
	virtual CBaseObject *GetBuildPointObject( int iPoint );
	bool				IsBuiltOnAttachment( void ) { return (m_hBuiltOnEntity.Get() != NULL); }
	void				AttachObjectToObject( const CBaseEntity *pEntity, int iPoint, Vector &vecOrigin );
	void				DetachObjectFromObject( void );
	CBaseObject			*GetParentObject( void );
	void				SetBuildPointPassenger( int iPoint, int iPassenger );
	int					GetBuildPointPassenger( int iPoint ) const;

	virtual float		GetSapperAttachTime( void );

// IHasBuildPoints
public:
	virtual int			GetNumBuildPoints( void ) const;
	virtual bool		GetBuildPoint( int iPoint, Vector &vecOrigin, QAngle &vecAngles );
	virtual int			GetBuildPointAttachmentIndex( int iPoint ) const;
	virtual bool		CanBuildObjectOnBuildPoint( int iPoint, int iObjectType );
	virtual void		SetObjectOnBuildPoint( int iPoint, CBaseObject *pObject );
	virtual float		GetMaxSnapDistance( int iBuildPoint );
	virtual bool		ShouldCheckForMovement( void ) { return true; }
	virtual int			GetNumObjectsOnMe( void );
	virtual CBaseEntity	*GetFirstObjectOnMe( void );
	virtual CBaseObject *GetObjectOfTypeOnMe( int iObjectType );
	virtual void		RemoveAllObjects( void );


// IServerNetworkable.
public:

	virtual int		ShouldTransmit( const CCheckTransmitInfo *pInfo );
	virtual void	SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways );


protected:
	// Clean off the object of offensive material, returns true if it found anything
	bool RemoveEnemyAttachments( CBaseEntity *pActivator );
	void RemoveAnalyzer( CBaseEntity *pRemovingEntity );
	void RemoveAllSappers( CBaseEntity *pRemovingEntity );

	void GiveNamedTechnology( CBaseTFPlayer *pRecipient, const char *techname );

	// Show/hide vgui screens.
	bool ShowVGUIScreen( int panelIndex, bool bShow );

private:
	void DetermineAnimation( void );

	// Spawns the various control panels
	void SpawnControlPanels();

	// Purpose: Spawn any objects specified inside the mdl
	void SpawnEntityOnBuildPoint( const char *pEntityName, int iAttachmentNumber );

	// Various commands sent by control panels
	void DismantleCommand( CBaseTFPlayer *pSender );
	void YawCommand( CBaseTFPlayer *pSender, float flYaw );
	void TakeControlCommand( CBaseTFPlayer *pSender );

protected:
	enum OBJSOLIDTYPE
	{
		SOLID_TO_PLAYER_USE_DEFAULT = 0,
		SOLID_TO_PLAYER_YES,
		SOLID_TO_PLAYER_NO,
	};

	bool		IsSolidToPlayers( void ) const;

	// object flags....
	CNetworkVar( int, m_fObjectFlags );
	CNetworkHandle( CBaseTFPlayer,	m_hBuilder );

	// Zone we're in (valid only for objects that sit in zones)
	CNetworkHandle( CResourceZone, m_hResourceZone );

	// Combat Objects
	char	*m_szAmmoName;		// Ammo used by players to build me

	// Cables
	CUtlVector< CHandle<CRopeKeyframe> > m_aRopes;

	// Placement
	Vector			m_vecBuildOrigin;
	Vector			m_vecBuildMins;
	Vector			m_vecBuildMaxs;
	CNetworkHandle( CBaseEntity, m_hBuiltOnEntity );
	int				m_iBuiltOnPoint;

	bool	m_bInvulnerable;
	bool	m_bCantDie;
	float	m_flRepairMultiplier;
	bool	m_bDying;

	// Outputs
	COutputEvent m_OnDestroyed;
	COutputEvent m_OnDamaged;
	COutputEvent m_OnRepaired;

	COutputEvent m_OnBecomingDisabled;
	COutputEvent m_OnBecomingReenabled;

	COutputFloat m_OnObjectHealthChanged;

	// Control panel
	typedef CHandle<CVGuiScreen>	ScreenHandle_t;
	CUtlVector<ScreenHandle_t>	m_hScreens;

private:
	// Make sure we pick up changes to these.
	IMPLEMENT_NETWORK_VAR_FOR_DERIVED( m_iHealth );
	IMPLEMENT_NETWORK_VAR_FOR_DERIVED( m_takedamage );

	Activity	m_Activity;

	CNetworkVar( int, m_iObjectType );


	// True if players shouldn't do collision avoidance, but should just collide exactly with the object.
	OBJSOLIDTYPE	m_SolidToPlayers;
	void		SetSolidToPlayers( OBJSOLIDTYPE stp, bool force = false );

	// True if this was a map placed object, not a player built one
	bool	m_bWasMapPlaced;

	// Disabled
	CNetworkVar( bool, m_bDisabled );

	// Vehicle bays
	CHandle<CVGuiScreenVehicleBay>	m_hVehicleBay;

	// Building
	CNetworkVar( bool, m_bPlacing );					// True while the object's being placed
	CNetworkVar( bool, m_bBuilding );				// True while the object's still constructing itself
	float	m_flConstructionTimeLeft;	// Current time left in construction
	float	m_flTotalConstructionTime;	// Total construction time (the value of GetTotalTime() at the time construction 
										// started, ie, incase you teleport out of a construction yard)

	CNetworkVar( float, m_flPercentageConstructed );	// Used to send to client
	float	m_flHealth;					// Health during construction. Needed a float due to small increases in health.

	// Repair capping
	float	m_flLastRepairTime;
	float	m_flNextRepairMultiplier;
	float	m_flRepairedSinceLastTime;

	// Sappers on me
	CNetworkVar( bool, m_bHasSapper );
	typedef CHandle<CGrenadeObjectSapper>	SapperHandle;
	CUtlVector< SapperHandle >	m_hSappers;

	// Power handling (Human objects need power to operate)
	CHandle< CObjectPowerPack >	m_hPowerPack;

	// Buff Station
	CHandle< CObjectBuffStation >	m_hBuffStation;
	bool							m_bBuffActivated;

	// Deterioration
	CNetworkVar( bool, m_bDeteriorating );
	float	m_flStartedDeterioratingAt;
	CHandle<CBaseTFPlayer>	m_hOriginalBuilder;

	// Build points
	CUtlVector<BuildPoint_t>	m_BuildPoints;

	// Store the last time I took damage from an enemy. Use this to know whether to drop resources
	// when I die, because I only want to drop resources if I was "destroyed" by an enemy, not if I deteriorated.
	float	m_flLastRealDamage;

	// Amount of resources the player who built me paid for me
	int		m_iAmountPlayerPaidForMe;

	// Attack notification sounds
	string_t	m_iszUnderAttackSound;

	// If non-zero then if health gets below this amount, the object becomes disabled
	float		m_flMinDisableHealth;

	// If not NULL, then when going disabled, swith to this model
	string_t	m_iszDisabledModel;
	string_t	m_iszEnabledModel;
};

inline bool	CBaseObject::CanBeHookedToBuffStation( void )
{ 
	return false; 
}

inline CObjectBuffStation *CBaseObject::GetBuffStation( void )
{
	return m_hBuffStation.Get(); 
}

inline void	CBaseObject::BuffStationActivate( void )
{ 
	m_bBuffActivated = true; 
}

inline void	CBaseObject::BuffStationDeactivate( void )
{ 
	m_bBuffActivated = false; 
}

extern short g_sModelIndexFireball;		// holds the index for the fireball


#endif // TF_OBJ_H