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
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: A base class for model-based doors. The exact movement required to
// open or close the door is not dictated by this class, only that
// the door has open, closed, opening, and closing states.
//
// Doors must satisfy these requirements:
//
// - Derived classes must support being opened by NPCs.
// - Never autoclose in the face of a player.
// - Never close into an NPC.
//
//=============================================================================//
#ifndef BASEPROPDOOR_H
#define BASEPROPDOOR_H
#ifdef _WIN32
#pragma once
#endif
#include "props.h"
#include "locksounds.h"
#include "entityoutput.h"
extern ConVar g_debug_doors;
struct opendata_t
{
Vector vecStandPos; // Where the NPC should stand.
Vector vecFaceDir; // What direction the NPC should face.
Activity eActivity; // What activity the NPC should play.
};
abstract_class CBasePropDoor : public CDynamicProp
{
public:
DECLARE_CLASS( CBasePropDoor, CDynamicProp );
DECLARE_SERVERCLASS();
CBasePropDoor( void );
void Spawn();
void Precache();
void Activate();
int ObjectCaps();
void HandleAnimEvent( animevent_t *pEvent );
// Base class services.
// Do not make the functions in this block virtual!!
// {
inline bool IsDoorOpen();
inline bool IsDoorAjar();
inline bool IsDoorOpening();
inline bool IsDoorClosed();
inline bool IsDoorClosing();
inline bool IsDoorLocked();
inline bool IsDoorBlocked() const;
inline bool IsNPCOpening(CAI_BaseNPC *pNPC);
inline bool IsPlayerOpening();
inline bool IsOpener(CBaseEntity *pEnt);
bool NPCOpenDoor(CAI_BaseNPC *pNPC);
bool TestCollision( const Ray_t &ray, unsigned int mask, trace_t& trace );
// }
// Implement these in your leaf class.
// {
virtual bool DoorCanClose( bool bAutoClose ) { return true; }
virtual bool DoorCanOpen( void ) { return true; }
virtual void GetNPCOpenData(CAI_BaseNPC *pNPC, opendata_t &opendata) = 0;
virtual float GetOpenInterval(void) = 0;
// }
protected:
enum DoorState_t
{
DOOR_STATE_CLOSED = 0,
DOOR_STATE_OPENING,
DOOR_STATE_OPEN,
DOOR_STATE_CLOSING,
DOOR_STATE_AJAR,
};
// dvs: FIXME: make these private
void DoorClose();
CBasePropDoor *GetMaster( void ) { return m_hMaster; }
bool HasSlaves( void ) { return ( m_hDoorList.Count() > 0 ); }
inline void SetDoorState( DoorState_t eDoorState );
float m_flAutoReturnDelay; // How many seconds to wait before automatically closing, -1 never closes automatically.
CUtlVector< CHandle< CBasePropDoor > > m_hDoorList; // List of doors linked to us
inline CBaseEntity *GetActivator();
private:
// Implement these in your leaf class.
// {
// Called when the door becomes fully open.
virtual void OnDoorOpened() {}
// Called when the door becomes fully closed.
virtual void OnDoorClosed() {}
// Called to tell the door to start opening.
virtual void BeginOpening(CBaseEntity *pOpenAwayFrom) = 0;
// Called to tell the door to start closing.
virtual void BeginClosing( void ) = 0;
// Called when blocked to tell the door to stop moving.
virtual void DoorStop( void ) = 0;
// Called when blocked to tell the door to continue moving.
virtual void DoorResume( void ) = 0;
// Called to send the door instantly to its spawn positions.
virtual void DoorTeleportToSpawnPosition() = 0;
// }
private:
// Main entry points for the door base behaviors.
// Do not make the functions in this block virtual!!
// {
bool DoorActivate();
void DoorOpen( CBaseEntity *pOpenAwayFrom );
void OpenIfUnlocked(CBaseEntity *pActivator, CBaseEntity *pOpenAwayFrom);
void DoorOpenMoveDone();
void DoorCloseMoveDone();
void DoorAutoCloseThink();
void Lock();
void Unlock();
void Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value);
void OnUse( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value );
inline bool WillAutoReturn() { return m_flAutoReturnDelay != -1; }
void StartBlocked(CBaseEntity *pOther);
void OnStartBlocked( CBaseEntity *pOther );
void MasterStartBlocked( CBaseEntity *pOther );
void Blocked(CBaseEntity *pOther);
void EndBlocked(void);
void OnEndBlocked( void );
void UpdateAreaPortals(bool bOpen);
// Input handlers
void InputClose(inputdata_t &inputdata);
void InputLock(inputdata_t &inputdata);
void InputOpen(inputdata_t &inputdata);
void InputOpenAwayFrom(inputdata_t &inputdata);
void InputToggle(inputdata_t &inputdata);
void InputUnlock(inputdata_t &inputdata);
void SetDoorBlocker( CBaseEntity *pBlocker );
void SetMaster( CBasePropDoor *pMaster ) { m_hMaster = pMaster; }
void CalcDoorSounds();
// }
int m_nHardwareType;
DoorState_t m_eDoorState; // Holds whether the door is open, closed, opening, or closing.
locksound_t m_ls; // The sounds the door plays when being locked, unlocked, etc.
EHANDLE m_hActivator;
bool m_bLocked; // True if the door is locked.
EHANDLE m_hBlocker; // Entity blocking the door currently
bool m_bFirstBlocked; // Marker for being the first door (in a group) to be blocked (needed for motion control)
bool m_bForceClosed; // True if this door must close no matter what.
string_t m_SoundMoving;
string_t m_SoundOpen;
string_t m_SoundClose;
// dvs: FIXME: can we remove m_flSpeed from CBaseEntity?
//float m_flSpeed; // Rotation speed when opening or closing in degrees per second.
DECLARE_DATADESC();
string_t m_SlaveName;
CHandle< CBasePropDoor > m_hMaster;
static void RegisterPrivateActivities();
// Outputs
COutputEvent m_OnBlockedClosing; // Triggered when the door becomes blocked while closing.
COutputEvent m_OnBlockedOpening; // Triggered when the door becomes blocked while opening.
COutputEvent m_OnUnblockedClosing; // Triggered when the door becomes unblocked while closing.
COutputEvent m_OnUnblockedOpening; // Triggered when the door becomes unblocked while opening.
COutputEvent m_OnFullyClosed; // Triggered when the door reaches the fully closed position.
COutputEvent m_OnFullyOpen; // Triggered when the door reaches the fully open position.
COutputEvent m_OnClose; // Triggered when the door is told to close.
COutputEvent m_OnOpen; // Triggered when the door is told to open.
COutputEvent m_OnLockedUse; // Triggered when the user tries to open a locked door.
};
void CBasePropDoor::SetDoorState( DoorState_t eDoorState )
{
m_eDoorState = eDoorState;
}
bool CBasePropDoor::IsDoorOpen()
{
return m_eDoorState == DOOR_STATE_OPEN;
}
bool CBasePropDoor::IsDoorAjar()
{
return ( m_eDoorState == DOOR_STATE_AJAR );
}
bool CBasePropDoor::IsDoorOpening()
{
return m_eDoorState == DOOR_STATE_OPENING;
}
bool CBasePropDoor::IsDoorClosed()
{
return m_eDoorState == DOOR_STATE_CLOSED;
}
bool CBasePropDoor::IsDoorClosing()
{
return m_eDoorState == DOOR_STATE_CLOSING;
}
bool CBasePropDoor::IsDoorLocked()
{
return m_bLocked;
}
CBaseEntity *CBasePropDoor::GetActivator()
{
return m_hActivator;
}
bool CBasePropDoor::IsDoorBlocked() const
{
return ( m_hBlocker != NULL );
}
bool CBasePropDoor::IsNPCOpening( CAI_BaseNPC *pNPC )
{
return ( pNPC == ( CAI_BaseNPC * )GetActivator() );
}
inline bool CBasePropDoor::IsPlayerOpening()
{
return ( GetActivator() && GetActivator()->IsPlayer() );
}
inline bool CBasePropDoor::IsOpener(CBaseEntity *pEnt)
{
return ( GetActivator() == pEnt );
}
#endif // BASEPROPDOOR_H
|