summaryrefslogtreecommitdiff
path: root/game/server/tf/tf_obj.h
blob: ecde348d64974238da7ac72305ca5ffcb87273a0 (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
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
//========= 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 "ihasbuildpoints.h"
#include "iscorer.h"
#include "baseobject_shared.h"
#include "utlmap.h"
#include "props_shared.h"
#include "tf_achievementdata.h"
//#include "tf_player.h"

class CTFPlayer;
class CTFTeam;
class CRopeKeyframe;
class CVGuiScreen;
class KeyValues;
class CTFWrench;
class CTFAmmoPack;
class CObjectSapper;
struct animevent_t;

#define WRENCH_DMG_VS_SAPPER	65
#define OBJ_MAX_UPGRADE_LEVEL	3
#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

#define SF_BASEOBJ_INVULN	(1<<1)
#define LAST_SF_BASEOBJ		SF_BASEOBJ_INVULN

DECLARE_AUTO_LIST( IBaseObjectAutoList );

enum
{
	SHIELD_NONE = 0,
	SHIELD_NORMAL,	// 33% damage taken, no tracking
	SHIELD_MAX,		// 10% damage taken, tracking
};

#define SHIELD_NORMAL_VALUE		0.33f
#define SHIELD_MAX_VALUE		0.10f

// ------------------------------------------------------------------------ //
// Resupply object that's built by the player
// ------------------------------------------------------------------------ //
class CBaseObject : public CBaseCombatCharacter, public IHasBuildPoints, public IScorer, public IBaseObjectAutoList
{
	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 CTFPlayer *GetOwner( void );

	// Creation
	virtual void	Precache();
	virtual void	Spawn( void );
	virtual void	FirstSpawn( void );

	virtual bool	ShouldCollide( int collisionGroup, int contentsMask ) const;

	virtual void	SetBuilder( CTFPlayer *pBuilder );
	virtual void	SetType( int iObjectType );
	int				ObjectType( ) const;

	virtual int		BloodColor( void ) { return BLOOD_COLOR_MECH; }

	// Building
	virtual float	GetTotalTime( void );
	virtual void	StartPlacement( CTFPlayer *pPlayer );
	void			StopPlacement( void );
	bool			FindNearestBuildPoint( CBaseEntity *pEntity, CBasePlayer *pBuilder, float &flNearestPoint, Vector &vecNearestBuildPoint, bool bIgnoreChecks = false );
	bool			FindBuildPointOnPlayer( CTFPlayer *pTFPlayer, CBasePlayer *pBuilder, float &flNearestPoint, Vector &vecNearestBuildPoint );
	bool			VerifyCorner( const Vector &vBottomCenter, float xOffset, float yOffset );
	virtual float	GetNearbyObjectCheckRadius( void ) { return 30.0; }
	bool			UpdatePlacement( void );
	bool			UpdateAttachmentPlacement( CBaseObject *pObjectOverride = NULL );
	bool			IsValidPlacement( void ) const;
	
	virtual bool	IsPlacementPosValid( void );
	bool			FindSnapToBuildPos( CBaseObject *pObjectOverride = NULL );

	void			ReattachChildren( void );
	
	// I've finished building the specified object on the specified build point
	virtual int		FindObjectOnBuildPoint( CBaseObject *pObject );
	
	virtual bool	StartBuilding( CBaseEntity *pPlayer );
	virtual void	SetStartBuildingModel( void ) {}
	void			BuildingThink( void );
	void			SetControlPanelsActive( bool bState );
	virtual void	FinishedBuilding( void );
	bool			IsBuilding( void ) { return m_bBuilding; }
	bool			IsPlacing( void ) { return m_bPlacing; }
	virtual bool	IsUpgrading( void ) const { return false; }
	bool			MustBeBuiltOnAttachmentPoint( void ) const;
	bool			IsCarried( void ) const { return m_bCarried; }
	virtual void	OnEndBeingCarried( CBaseEntity *pBuilder ) {}

	// 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( CTFPlayer *pSender, const CCommand &args );

	// Damage
	void			SetHealth( float flHealth );
	float			GetHealth() { return m_flHealth; }
	virtual void	TraceAttack( const CTakeDamageInfo &info, const Vector &vecDir, trace_t *ptr, CDmgAccumulator *pAccumulator );
	virtual int		OnTakeDamage( const CTakeDamageInfo &info );
	bool			PassDamageOntoChildren( const CTakeDamageInfo &info, float *flDamageLeftOver );
	virtual bool	Construct( float flHealth );

	void			OnConstructionHit( CTFPlayer *pPlayer, CTFWrench *pWrench, Vector hitLoc );
	virtual float	GetConstructionMultiplier( void );

	// Destruction
	virtual void	DetonateObject( void );
	virtual bool	ShouldAutoRemove( void );
	virtual void	Explode( void );
	virtual void	Killed( const CTakeDamageInfo &info );
	virtual void	DestroyObject( void );		// Silent cleanup
	virtual bool	IsDying( void ) { return m_bDying; }
	void DestroyScreens( void );

	// Data
	virtual Class_T	Classify( void );
	virtual int		GetType( void ) const;
	virtual CTFPlayer *GetBuilder( void ) const;
	CTFTeam			*GetTFTeam( void ) { return (CTFTeam*)GetTeam(); };
	
	// ID functions
	virtual bool	IsAnUpgrade( void )			{ return false; }
	virtual bool	IsHostileUpgrade( void )	{ return false; }	// Attaches to enemy buildings

	// Inputs
	void			InputSetHealth( inputdata_t &inputdata );
	void			InputAddHealth( inputdata_t &inputdata );
	void			InputRemoveHealth( inputdata_t &inputdata );
	void			InputSetSolidToPlayer( inputdata_t &inputdata );
	void            InputSetBuilder( inputdata_t &inputdata );
	void			InputShow( inputdata_t &inputdata );
	void			InputHide( inputdata_t &inputdata );
	virtual void	InputEnable( inputdata_t &inputdata );
	virtual void	InputDisable( inputdata_t &inputdata );

	// Wrench hits
	virtual bool	InputWrenchHit( CTFPlayer *pPlayer, CTFWrench *pWrench, Vector hitLoc );
	virtual bool	OnWrenchHit( CTFPlayer *pPlayer, CTFWrench *pWrench, Vector hitLoc );
	virtual bool	CheckUpgradeOnHit( CTFPlayer *pPlayer );
	virtual bool	Command_Repair( CTFPlayer *pActivator, float flRepairMod );
	virtual void	DoWrenchHitEffect( Vector hitLoc, bool bRepairHit, bool bUpgradeHit );

	virtual bool	ShouldBeMiniBuilding( CTFPlayer* pPlayer );
	virtual void	MakeMiniBuilding( CTFPlayer* pPlayer );
	virtual void	MakeDisposableBuilding( CTFPlayer *pPlayer );

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

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

	// Sappers
	CObjectSapper*	GetSapper( void );
	bool			HasSapper( void );
	bool			IsPlasmaDisabled( void );
	void			OnAddSapper( void );
	void			OnRemoveSapper( void );

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

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

	// Disabling
	bool			IsDisabled( void ) { return m_bDisabled || m_bCarried; }
	virtual void	UpdateDisabledState( void );
	void			SetDisabled( bool bDisabled );
	virtual void	OnStartDisabled( void );
	virtual void	OnEndDisabled( void );
	void			SetPlasmaDisabled( float flDuration );

	// Animation
	virtual void	PlayStartupAnimation( void );

	Activity		GetActivity( ) const;
	void			SetActivity( Activity act );
	void			SetObjectSequence( int sequence );
	
	// Object points
	void			SpawnObjectPoints( void );

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

	virtual int		DrawDebugTextOverlays( void );

	void			RotateBuildAngles( void );

	virtual bool	ShouldPlayersAvoid( void );

	void			IncrementKills( void ) { m_iKills++; }
	int				GetKills() { return m_iKills; }

	void			IncrementAssists( void ) { m_iAssists++; }
	int				GetAssists() { return m_iAssists; }

	void			CreateObjectGibs( void );
	CTFAmmoPack*	CreateAmmoPack( const char *pchModel, int nMetal );
	virtual void	SetModel( const char *pModel );

	const char		*GetResponseRulesModifier( void );

	// Map Placed
	virtual void	Activate( void );
	virtual void	InitializeMapPlacedObject( void );

	bool			CannotDie() const { return m_bCannotDie; }
	void			SetCannotDie( bool bCannotDie ) { m_bCannotDie = bCannotDie; }

	// Upgrading
	virtual bool	CanBeUpgraded( CTFPlayer *pPlayer );
	virtual void	StartUpgrading( void );
	virtual void	FinishUpgrading( void );
	void			UpgradeThink( void );
	virtual int		GetUpgradeLevel( void ) const { return m_iUpgradeLevel; }
	int				GetUpgradeMetal( void ) const { return m_iUpgradeMetal; }
	int				GetHighestUpgradeLevel( void ) { return Min( (int)m_iHighestUpgradeLevel, GetMaxUpgradeLevel() ); }
	void			SetHighestUpgradeLevel( int nLevel ) { m_iHighestUpgradeLevel = Min( nLevel, GetMaxUpgradeLevel() ); }
	void			ApplyHealthUpgrade( void );
	virtual int		GetBaseHealth( void ) = 0;
	void			DoQuickBuild( bool bForceMax = false );
	bool			ShouldQuickBuild( void );
	void			DoReverseBuild( void );
	float			GetReversesBuildingConstructionSpeed( void );
	virtual int		GetMaxUpgradeLevel( void ) { return OBJ_MAX_UPGRADE_LEVEL; }

	// Carrying
	virtual void	MakeCarriedObject( CTFPlayer *pCarrier );
	virtual void	DropCarriedObject( CTFPlayer* pCarrier );

	void			ForceQuickBuild() { m_bForceQuickBuild = true; }

	virtual int		GetMiniBuildingStartingHealth( void ) { return 100; }

	virtual int		GetMaxHealthForCurrentLevel( void );
	bool			IsUsingReverseBuild( void ){ return ( GetReversesBuildingConstructionSpeed() != 0.0f ); }
	void			ResetPlacement( void );

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

	// IScorer interface
	virtual CBasePlayer *GetScorer( void ) { return ( CBasePlayer *)GetBuilder(); }
	virtual CBasePlayer *GetAssistant( void ) { return NULL; }

	// Achievement tracking
	// Achievement data storage
	CAchievementData	m_AchievementData;

	// 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); }
	CBaseEntity			*GetBuiltOnObject( void ){ return m_hBuiltOnEntity.Get(); }
	void				AttachObjectToObject( CBaseEntity *pEntity, int iPoint, Vector &vecOrigin );
	virtual void		DetachObjectFromObject( void );
	CBaseObject			*GetParentObject( void );
	CBaseEntity			*GetParentEntity( void );

	virtual void		SetObjectMode( int iVal ) { m_iObjectMode = iVal; }
	int					GetObjectMode( void ) const { return m_iObjectMode; }

	float				GetConstructionStartTime( void ) { return m_flConstructionStartTime; }

// IHasBuildPoints
	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();
	virtual CBaseEntity	*GetFirstFriendlyObjectOnMe( void );
	virtual CBaseObject *GetObjectOfTypeOnMe( int iObjectType );
	virtual void		RemoveAllObjects( void );

// IServerNetworkable.
	virtual int		UpdateTransmitState( void );
	virtual int		ShouldTransmit( const CCheckTransmitInfo *pInfo );
	virtual void	SetTransmit( CCheckTransmitInfo *pInfo, bool bAlways );
	
	bool			IsMiniBuilding( void ) const { return m_bMiniBuilding; }
	bool			IsDisposableBuilding( void ) const { return m_bDisposableBuilding; }

	virtual bool ShouldBlockNav() const OVERRIDE { return false; }

	bool			IsMapPlaced( void ){ return m_bWasMapPlaced; }

	virtual int	GetShieldLevel() { return SHIELD_NONE; }

	virtual bool CanBeRepaired() const { return !IsDisposableBuilding(); }
protected:

	virtual bool CanBeUpgraded() const { return !( IsDisposableBuilding() || IsMiniBuilding() ); }
	
	virtual int  GetUpgradeMetalRequired();

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

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

	virtual void DetermineAnimation( void );
	virtual void DeterminePlaybackRate( void );

	void UpdateDesiredBuildRotation( float flFrameTime );

	bool CalculatePlacementPos( void );
	bool EstimateValidBuildPos( void );

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

	//bool TestPositionForPlayerBlock( Vector vecBuildOrigin, CBasePlayer *pPlayer );
	//void RecursiveTestBuildSpace( int iNode, bool *bNodeClear, bool *bNodeVisited );

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( CTFPlayer,	m_hBuilder );

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

	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;

	// Map placed objects
	CNetworkVar( bool, m_bWasMapPlaced );

	float			GetCarryDeployTime() { return m_flCarryDeployTime; }

public:
	// Upgrade Level ( 1, 2, 3 )
	CNetworkVar( int, m_iUpgradeLevel );
	CNetworkVar( int, m_iUpgradeMetal );
	CNetworkVar( int, m_iUpgradeMetalRequired );
	CNetworkVar( int, m_iHighestUpgradeLevel );
	int m_nDefaultUpgradeLevel;
	float m_flUpgradeCompleteTime;			// Time when the upgrade animation will complete

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 );

	CNetworkVar( int , m_iObjectMode );

	// Disabled
	CNetworkVar( bool, m_bDisabled );

	// Building
	CNetworkVar( bool, m_bPlacing );					// True while the object's being placed
	CNetworkVar( bool, m_bBuilding );				// True while the object's still constructing itself

protected:
	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)
	float   m_flConstructionStartTime;

protected:
	// Carried
	CNetworkVar( bool, m_bCarried );
	CNetworkVar( bool, m_bCarryDeploy );

	CNetworkVar( bool, m_bMiniBuilding );
	CNetworkVar( bool, m_bDisposableBuilding );

	float m_flPlasmaDisableTime;
	CNetworkVar( bool, m_bPlasmaDisable );

private:
	int			m_iHealthOnPickup;
	float	m_flCarryDeployTime;

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

	// Sapper on me
	CNetworkVar( bool, m_bHasSapper );

	// Build points
	CUtlVector<BuildPoint_t>	m_BuildPoints;

	// Maps player ent index to repair expire time
	struct constructor_t
	{
		float flHitTime; // Time this constructor last hit me
		float flValue;	 // Speed value of this constructor. Defaults to 1.0, but some constructors are worth more.
	};
	CUtlMap<int, constructor_t>	m_ConstructorList;

	// Result of last placement test
	bool		m_bPlacementOK;				// last placement state

	CNetworkVar( int, m_iKills );
	CNetworkVar( int, m_iAssists );

	CNetworkVar( int, m_iDesiredBuildRotations );		// Number of times we've rotated, used to calc final rotation
	float m_flCurrentBuildRotation;

	// Gibs.
	CUtlVector<breakmodel_t>	m_aGibs;

	CNetworkVar( bool, m_bServerOverridePlacement );

	// for ACHIEVEMENT_TF_ENGINEER_TANK_DAMAGE
	int		m_iLifetimeDamage;

	bool	m_bCannotDie;
	bool	m_bQuickBuild;

	// used when calculating the placement position
	Vector	m_vecBuildForward;
	float	m_flBuildDistance;

	bool	m_bForceQuickBuild;
};

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

#endif // TF_OBJ_H