summaryrefslogtreecommitdiff
path: root/game/server/tf/tf_obj_dispenser.h
blob: a43c814976bafc283625637771dee70101586342 (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
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Engineer's Dispenser
//
// $NoKeywords: $
//=============================================================================//

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

#include "tf_obj.h"
#include "triggers.h"

class CTFPlayer;

#define DISPENSER_MAX_HEALTH	150

#define DISPENSER_MINI_MAX_HEALTH	100
#define DISPENSER_MINI_MAX_LEVEL	1
#define DISPENSER_MINI_HEAL_RATE	10.0 
#define DISPENSER_MINI_AMMO_RATE	0.2 
#define DISPENSER_MINI_AMMO_THINK	0.5

#define SF_DISPENSER_IGNORE_LOS					(SF_BASEOBJ_INVULN<<1)
#define SF_DISPENSER_DONT_HEAL_DISGUISED_SPIES	(SF_BASEOBJ_INVULN<<2)	

// ------------------------------------------------------------------------ //
// Repair Trigger
// ------------------------------------------------------------------------ //
class CDispenserTouchTrigger : public CBaseTrigger
{
	DECLARE_CLASS( CDispenserTouchTrigger, CBaseTrigger );

public:
	CDispenserTouchTrigger() {}

	void Spawn( void )
	{
		BaseClass::Spawn();
		AddSpawnFlags( SF_TRIGGER_ALLOW_CLIENTS );
		InitTrigger();
	}

	virtual void StartTouch( CBaseEntity *pEntity )
	{
		if ( PassesTriggerFilters( pEntity ) )
		{
			CBaseEntity *pParent = GetOwnerEntity();

			if ( pParent )
			{
				pParent->StartTouch( pEntity );
			}
		}
	}

	virtual void EndTouch( CBaseEntity *pEntity )
	{
		if ( PassesTriggerFilters( pEntity ) )
		{
			CBaseEntity *pParent = GetOwnerEntity();

			if ( pParent )
			{
				pParent->EndTouch( pEntity );
			}
		}
	}
};

// Ground placed version
#define DISPENSER_MODEL_PLACEMENT		"models/buildables/dispenser_blueprint.mdl"
#define DISPENSER_MODEL_BUILDING		"models/buildables/dispenser.mdl"
#define DISPENSER_MODEL					"models/buildables/dispenser_light.mdl"
#define DISPENSER_MODEL_BUILDING_LVL2	"models/buildables/dispenser_lvl2.mdl"
#define DISPENSER_MODEL_LVL2			"models/buildables/dispenser_lvl2_light.mdl"
#define DISPENSER_MODEL_BUILDING_LVL3	"models/buildables/dispenser_lvl3.mdl"
#define DISPENSER_MODEL_LVL3			"models/buildables/dispenser_lvl3_light.mdl"

#ifdef STAGING_ONLY
// Mini models
#define MINI_DISPENSER_MODEL_PLACEMENT		"models/workshop/buildables/mini_dispenser/mini_dispenser.mdl"
#define MINI_DISPENSER_MODEL_BUILDING		"models/workshop/buildables/mini_dispenser/mini_dispenser.mdl"
#define MINI_DISPENSER_MODEL				"models/workshop/buildables/mini_dispenser/mini_dispenser.mdl"
#endif // STAGING_ONLY

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

public:
	DECLARE_SERVERCLASS();

	CObjectDispenser();
	~CObjectDispenser();

	static CObjectDispenser* Create(const Vector &vOrigin, const QAngle &vAngles);

	virtual void	Spawn() OVERRIDE;
	virtual void	FirstSpawn( void ) OVERRIDE;
	virtual void	GetControlPanelInfo( int nPanelIndex, const char *&pPanelName ) OVERRIDE;
	virtual void	Precache() OVERRIDE;

	virtual void	DetonateObject( void ) OVERRIDE;
	virtual void	DestroyObject( void ) OVERRIDE;		// Silent cleanup

	virtual void	OnGoActive( void );	
	virtual void	StartPlacement( CTFPlayer *pPlayer ) OVERRIDE;
	virtual bool	StartBuilding( CBaseEntity *pBuilder ) OVERRIDE;
	virtual void	SetStartBuildingModel( void ) OVERRIDE;
	virtual int		DrawDebugTextOverlays(void) OVERRIDE;
	virtual void	SetModel( const char *pModel ) OVERRIDE;
	virtual void	InitializeMapPlacedObject( void ) OVERRIDE;
	virtual bool	ShouldBeMiniBuilding( CTFPlayer* pPlayer ) OVERRIDE;

	virtual bool	IsUpgrading( void ) const OVERRIDE { return ( m_iState == DISPENSER_STATE_UPGRADING ); }
	virtual void	StartUpgrading( void ) OVERRIDE;
	virtual void	FinishUpgrading( void ) OVERRIDE;

	virtual int		DispenseMetal( CTFPlayer *pPlayer );
	virtual int		GetAvailableMetal( void ) const;

	virtual void RefillThink( void );
	virtual void DispenseThink( void );

	virtual void StartTouch( CBaseEntity *pOther ) OVERRIDE;
	virtual void Touch( CBaseEntity *pOther ) OVERRIDE;
	virtual void EndTouch( CBaseEntity *pOther ) OVERRIDE;

	virtual const char* GetBuildingModel( int iLevel );
	virtual const char* GetFinishedModel( int iLevel );
	virtual const char* GetPlacementModel();

	virtual int	ObjectCaps( void ) OVERRIDE { return (BaseClass::ObjectCaps() | FCAP_IMPULSE_USE); }

	virtual bool DispenseAmmo( CTFPlayer *pPlayer );

	virtual void DropSpellPickup() { /* DO NOTHING */ }
	virtual void DropDuckPickup() { /* DO NOTHING */ }
	virtual void DispenseSouls() { /* Do nothing */}

	virtual float GetHealRate() const;
	virtual void StartHealing( CBaseEntity *pOther );
	void StopHealing( CBaseEntity *pOther );

	void AddHealingTarget( CBaseEntity *pOther );
	bool RemoveHealingTarget( CBaseEntity *pOther );
	bool IsHealingTarget( CBaseEntity *pTarget );

	bool CouldHealTarget( CBaseEntity *pTarget );
	virtual float GetDispenserRadius( void );


	Vector GetHealOrigin( void );

	CUtlVector< EHANDLE >	m_hHealingTargets;

	virtual void	MakeMiniBuilding( CTFPlayer* pPlayer ) OVERRIDE;
	virtual void	MakeCarriedObject( CTFPlayer *pCarrier );

	virtual int		GetBaseHealth( void ) { return DISPENSER_MAX_HEALTH; }

	virtual int		GetMaxUpgradeLevel( void ) OVERRIDE;

	virtual int		GetMiniBuildingStartingHealth( void ) OVERRIDE { return DISPENSER_MINI_MAX_HEALTH; }

	CBaseEntity		*GetTouchTrigger() const { return m_hTouchTrigger; }
	void			DisableAmmoPickupSound() { m_bPlayAmmoPickupSound = false; }
	void			DisableGenerateMetalSound() { m_bUseGenerateMetalSound = false; }

private:
	virtual void PlayActiveSound();
	void ResetHealingTargets( void );

protected:

	// The regular and mini dispenser can be repaired
	virtual bool CanBeRepaired() const OVERRIDE { return true; }

	CNetworkVar( int, m_iState );
	CNetworkVar( int, m_iAmmoMetal );
	CNetworkVar( int, m_iMiniBombCounter );

	bool m_bUseGenerateMetalSound;

	// Entities currently being touched by this trigger
	CUtlVector< EHANDLE >	m_hTouchingEntities;

	float m_flNextAmmoDispense;

	bool m_bThrown;

	string_t m_iszCustomTouchTrigger;
	EHANDLE m_hTouchTrigger;

	DECLARE_DATADESC();

private:

	CountdownTimer m_spellTimer;
	CountdownTimer m_duckTimer;
	CountdownTimer m_soulTimer;

	float m_flPrevRadius;
	bool m_bPlayAmmoPickupSound;
};

inline int CObjectDispenser::GetAvailableMetal( void ) const
{
	return m_iAmmoMetal;
}


//------------------------------------------------------------------------------
class CObjectCartDispenser : public CObjectDispenser
{
	DECLARE_CLASS( CObjectCartDispenser, CObjectDispenser );

public:
	DECLARE_SERVERCLASS();
	DECLARE_DATADESC();

	CObjectCartDispenser();

	virtual void Spawn( void );
	virtual void OnGoActive( void );
	virtual void GetControlPanelInfo( int nPanelIndex, const char *&pPanelName );

	virtual int	DispenseMetal( CTFPlayer *pPlayer );
	virtual void DropSpellPickup();
	virtual void DropDuckPickup();
	virtual void DispenseSouls() OVERRIDE;

	virtual bool	CanBeUpgraded( CTFPlayer *pPlayer ){ return false; }
	virtual void	SetModel( const char *pModel );

	void InputFireHalloweenBonus( inputdata_t &inputdata );
	void InputSetDispenserLevel( inputdata_t &inputdata );
	void InputEnable( inputdata_t &inputdata );
	void InputDisable( inputdata_t &inputdata );
};

#endif // TF_OBJ_DISPENSER_H