initial
This commit is contained in:
484
game/server/BasePropDoor.h
Normal file
484
game/server/BasePropDoor.h
Normal file
@@ -0,0 +1,484 @@
|
||||
//========= Copyright <20> 1996-2005, 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"
|
||||
#include "entityblocker.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();
|
||||
|
||||
virtual bool IsAbleToCloseAreaPortals( void ) const;
|
||||
|
||||
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 IsDoorBlocked() const;
|
||||
inline bool IsNPCOpening(CAI_BaseNPC *pNPC);
|
||||
inline bool IsPlayerOpening();
|
||||
inline bool IsOpener(CBaseEntity *pEnt);
|
||||
|
||||
virtual bool IsDoorLocked() { return m_bLocked; }
|
||||
|
||||
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;
|
||||
|
||||
enum DoorExtent_t
|
||||
{
|
||||
DOOR_EXTENT_OPEN = 1,
|
||||
DOOR_EXTENT_CLOSED = 2,
|
||||
};
|
||||
virtual void ComputeDoorExtent( Extent *extent, unsigned int extentType ) = 0; // extent contains the volume encompassing by the door in the specified states
|
||||
// }
|
||||
|
||||
|
||||
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 );
|
||||
|
||||
virtual void CalcDoorSounds();
|
||||
|
||||
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();
|
||||
|
||||
int m_nHardwareType;
|
||||
|
||||
// Called when the door becomes fully closed.
|
||||
virtual void OnDoorClosed() {}
|
||||
private:
|
||||
|
||||
// Implement these in your leaf class.
|
||||
// {
|
||||
// Called when the door becomes fully open.
|
||||
virtual void OnDoorOpened() {}
|
||||
|
||||
// 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;
|
||||
// }
|
||||
|
||||
protected:
|
||||
void UpdateAreaPortals( bool bOpen );
|
||||
void DisableAreaPortalThink( void );
|
||||
virtual void Lock();
|
||||
virtual void Unlock();
|
||||
|
||||
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 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 );
|
||||
|
||||
// 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; }
|
||||
|
||||
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;
|
||||
|
||||
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)
|
||||
|
||||
protected:
|
||||
bool m_bLocked; // True if the door is locked.
|
||||
bool m_bForceClosed; // True if this door must close no matter what.
|
||||
|
||||
string_t m_SoundMoving;
|
||||
string_t m_SoundOpen;
|
||||
string_t m_SoundClose;
|
||||
|
||||
int m_nPhysicsMaterial;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===============================================
|
||||
// Rotating prop door
|
||||
//===============================================
|
||||
// Check directions for door movement
|
||||
enum doorCheck_e
|
||||
{
|
||||
DOOR_CHECK_FORWARD, // Door's forward opening direction
|
||||
DOOR_CHECK_BACKWARD, // Door's backward opening direction
|
||||
DOOR_CHECK_FULL, // Door's complete movement volume
|
||||
};
|
||||
|
||||
|
||||
enum PropDoorRotatingSpawnPos_t
|
||||
{
|
||||
DOOR_SPAWN_CLOSED = 0,
|
||||
DOOR_SPAWN_OPEN_FORWARD,
|
||||
DOOR_SPAWN_OPEN_BACK,
|
||||
DOOR_SPAWN_AJAR,
|
||||
};
|
||||
|
||||
enum PropDoorRotatingOpenDirection_e
|
||||
{
|
||||
DOOR_ROTATING_OPEN_BOTH_WAYS = 0,
|
||||
DOOR_ROTATING_OPEN_FORWARD,
|
||||
DOOR_ROTATING_OPEN_BACKWARD,
|
||||
};
|
||||
class CPropDoorRotating : public CBasePropDoor
|
||||
{
|
||||
DECLARE_CLASS( CPropDoorRotating, CBasePropDoor );
|
||||
|
||||
public:
|
||||
|
||||
~CPropDoorRotating();
|
||||
|
||||
int DrawDebugTextOverlays( void );
|
||||
|
||||
void Spawn( void );
|
||||
void MoveDone( void );
|
||||
void BeginOpening( CBaseEntity *pOpenAwayFrom );
|
||||
void BeginClosing( void );
|
||||
void OnRestore( void );
|
||||
|
||||
void DoorTeleportToSpawnPosition();
|
||||
|
||||
void GetNPCOpenData( CAI_BaseNPC *pNPC, opendata_t &opendata );
|
||||
|
||||
void DoorClose( void );
|
||||
bool DoorCanClose( bool bAutoClose );
|
||||
void DoorOpen( CBaseEntity *pOpenAwayFrom );
|
||||
|
||||
void OnDoorOpened();
|
||||
void OnDoorClosed();
|
||||
|
||||
void DoorResume( void );
|
||||
void DoorStop( void );
|
||||
|
||||
float GetOpenInterval();
|
||||
|
||||
bool OverridePropdata() { return true; }
|
||||
|
||||
void InputSetSpeed( inputdata_t &inputdata );
|
||||
|
||||
virtual void ComputeDoorExtent( Extent *extent, unsigned int extentType ); // extent contains the volume encompassing open + closed states
|
||||
|
||||
virtual int UpdateTransmitState() { return SetTransmitState( FL_EDICT_ALWAYS ); }
|
||||
|
||||
DECLARE_DATADESC();
|
||||
DECLARE_SERVERCLASS();
|
||||
|
||||
private:
|
||||
|
||||
bool IsHingeOnLeft();
|
||||
|
||||
void AngularMove( const QAngle &vecDestAngle, float flSpeed );
|
||||
void CalculateDoorVolume( QAngle closedAngles, QAngle openAngles, Vector *destMins, Vector *destMaxs );
|
||||
|
||||
bool CheckDoorClear( doorCheck_e state );
|
||||
|
||||
doorCheck_e GetOpenState( void );
|
||||
|
||||
void InputSetRotationDistance( inputdata_t &inputdata ); // Set the degree difference between open and closed
|
||||
void InputMoveToRotationDistance( inputdata_t &inputdata ); // Set the degree difference between open and closed and move to open
|
||||
|
||||
void CalcOpenAngles( void ); // Subroutine to setup the m_angRotation QAngles based on the m_flDistance variable
|
||||
|
||||
Vector m_vecAxis; // The axis of rotation.
|
||||
float m_flDistance; // How many degrees we rotate between open and closed.
|
||||
|
||||
PropDoorRotatingSpawnPos_t m_eSpawnPosition;
|
||||
PropDoorRotatingOpenDirection_e m_eOpenDirection;
|
||||
|
||||
QAngle m_angRotationAjar; // Angles to spawn at if we are set to spawn ajar.
|
||||
QAngle m_angRotationClosed; // Our angles when we are fully closed.
|
||||
QAngle m_angRotationOpenForward; // Our angles when we are fully open towards our forward vector.
|
||||
QAngle m_angRotationOpenBack; // Our angles when we are fully open away from our forward vector.
|
||||
|
||||
QAngle m_angGoal;
|
||||
|
||||
Vector m_vecForwardBoundsMin;
|
||||
Vector m_vecForwardBoundsMax;
|
||||
Vector m_vecBackBoundsMin;
|
||||
Vector m_vecBackBoundsMax;
|
||||
|
||||
COutputEvent m_OnRotationDone; // Triggered when we finish rotating.
|
||||
|
||||
CHandle<CEntityBlocker> m_hDoorBlocker;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
class CPropDoorRotatingBreakable : public CPropDoorRotating
|
||||
{
|
||||
DECLARE_CLASS( CPropDoorRotatingBreakable, CPropDoorRotating );
|
||||
|
||||
public:
|
||||
|
||||
DECLARE_DATADESC();
|
||||
|
||||
virtual void Spawn( void );
|
||||
virtual void Precache( void );
|
||||
virtual void UpdateOnRemove( void );
|
||||
void PrecacheBreakables( void );
|
||||
virtual int OnTakeDamage( const CTakeDamageInfo &info );
|
||||
virtual void Event_Killed( const CTakeDamageInfo &info );
|
||||
void InputSetRotationDistance( inputdata_t &inputdata );
|
||||
void InputSetUnbreakable( inputdata_t &inputdata );
|
||||
void InputSetBreakable( inputdata_t &inputdata );
|
||||
virtual bool IsAbleToCloseAreaPortals( void ) const;
|
||||
virtual int DrawDebugTextOverlays( void );
|
||||
bool IsBreakable( void ) { return m_bBreakable; }
|
||||
|
||||
virtual void Lock();
|
||||
virtual void Unlock();
|
||||
|
||||
virtual void OnDoorOpened( void )
|
||||
{
|
||||
UnblockNav();
|
||||
BaseClass::OnDoorOpened();
|
||||
}
|
||||
|
||||
virtual void OnDoorClosed( void )
|
||||
{
|
||||
BaseClass::OnDoorClosed();
|
||||
}
|
||||
|
||||
bool operator()( CNavArea *area ); // functor that blocks areas in our extent
|
||||
|
||||
static bool CalculateBlocked( bool *pResultByTeam, const Vector &vecMins, const Vector &vecMaxs );
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void UpdateBlocked( bool bBlocked );
|
||||
void BlockNav( void );
|
||||
void UnblockNav( void );
|
||||
|
||||
// void BlockNavArea( bool blocked )
|
||||
// {
|
||||
// /**
|
||||
// * MSB: I'm commenting this out, because we can't use BLOCKED for this,
|
||||
// * since *nothing* can path thru a blocked area - SurvivorBots, population
|
||||
// * algorithms, etc.
|
||||
// * However, something like "closed door" might be useful to flag here
|
||||
// * in the future.
|
||||
// *
|
||||
//
|
||||
// if ( blocked )
|
||||
// {
|
||||
// CNavArea *area = TheNavMesh->GetNavArea( WorldSpaceCenter() );
|
||||
// if ( area )
|
||||
// {
|
||||
// area->Block();
|
||||
// m_blockedNavAreaID = area->GetID();
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if ( m_blockedNavAreaID > 0 )
|
||||
// {
|
||||
// CNavArea *area = TheNavMesh->GetNavAreaByID( m_blockedNavAreaID );
|
||||
// if ( area )
|
||||
// {
|
||||
// area->UpdateBlocked( true ); // give it a chance to stay blocked by something else
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// */
|
||||
// }
|
||||
|
||||
int m_blockedNavAreaID;
|
||||
|
||||
bool m_bBreakable;
|
||||
bool m_isAbleToCloseAreaPortals;
|
||||
int m_currentDamageState;
|
||||
int m_blockedTeamNumber;
|
||||
bool m_isBlockingNav[MAX_NAV_TEAMS];
|
||||
CUtlVector< string_t > m_damageStates;
|
||||
};
|
||||
|
||||
#endif // BASEPROPDOOR_H
|
||||
Reference in New Issue
Block a user