This repository has been archived on 2024-06-13. You can view files and clone it, but cannot push or open issues or pull requests.
2020-08-04 13:13:01 -04:00

258 lines
8.0 KiB
C++

//========= 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 "entityoutput.h"
#include "locksounds.h"
#include "props.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