/***
*
* Copyright ( c ) 1996 - 2002 , Valve LLC . All rights reserved .
*
* This product contains software technology licensed from Id
* Software , Inc . ( " Id Technology " ) . Id Technology ( c ) 1996 Id Software , Inc .
* All Rights Reserved .
*
* Use , distribution , and modification of this source code and / or resulting
* object code is restricted to non - commercial enhancements to products from
* Valve LLC . All other use , distribution , or modification is prohibited
* without written permission from Valve LLC .
*
* * * */
# pragma once
# ifndef CBASE_H
# define CBASE_H
/*
Class Hierachy
CBaseEntity
CPointEntity
CBasePlayerAmmo
CBaseDelay
CBaseAnimating
CBasePlayerItem
CBasePlayerWeapon
CBaseToggle
CBaseButton
CBaseDoor
CBaseTrigger
CBasePlatTrain
CBaseMonster
CCycler
CBasePlayer
CCineMonster
*/
# define MAX_PATH_SIZE 10 // max number of nodes available for a path.
// These are caps bits to indicate what an object's capabilities (currently used for save/restore and level transitions)
# define FCAP_CUSTOMSAVE 0x00000001
# define FCAP_ACROSS_TRANSITION 0x00000002 // should transfer between transitions
# define FCAP_MUST_SPAWN 0x00000004 // Spawn after restore
# define FCAP_DONT_SAVE 0x80000000 // Don't save this
# define FCAP_IMPULSE_USE 0x00000008 // can be used by the player
# define FCAP_CONTINUOUS_USE 0x00000010 // can be used by the player
# define FCAP_ONOFF_USE 0x00000020 // can be used by the player
# define FCAP_DIRECTIONAL_USE 0x00000040 // Player sends +/- 1 when using (currently only tracktrains)
# define FCAP_MASTER 0x00000080 // Can be used to "master" other entities (like multisource)
// LRC: no longer used
# define FCAP_ONLYDIRECT_USE 0x00000100 //LRC - can't use this entity through a wall.
// UNDONE: This will ignore transition volumes (trigger_transition), but not the PVS!!!
# define FCAP_FORCE_TRANSITION 0x00000080 // ALWAYS goes across transitions
# include "saverestore.h"
# include "schedule.h"
# ifndef MONSTEREVENT_H
# include "monsterevent.h"
# endif
// C functions for external declarations that call the appropriate C++ methods
# include "exportdef.h"
extern " C " EXPORT int GetEntityAPI ( DLL_FUNCTIONS * pFunctionTable , int interfaceVersion ) ;
extern " C " EXPORT int GetEntityAPI2 ( DLL_FUNCTIONS * pFunctionTable , int * interfaceVersion ) ;
extern int DispatchSpawn ( edict_t * pent ) ;
extern void DispatchKeyValue ( edict_t * pentKeyvalue , KeyValueData * pkvd ) ;
extern void DispatchTouch ( edict_t * pentTouched , edict_t * pentOther ) ;
extern void DispatchUse ( edict_t * pentUsed , edict_t * pentOther ) ;
extern void DispatchThink ( edict_t * pent ) ;
extern void DispatchBlocked ( edict_t * pentBlocked , edict_t * pentOther ) ;
extern void DispatchSave ( edict_t * pent , SAVERESTOREDATA * pSaveData ) ;
extern int DispatchRestore ( edict_t * pent , SAVERESTOREDATA * pSaveData , int globalEntity ) ;
extern void DispatchObjectCollsionBox ( edict_t * pent ) ;
extern void SaveWriteFields ( SAVERESTOREDATA * pSaveData , const char * pname , void * pBaseData , TYPEDESCRIPTION * pFields , int fieldCount ) ;
extern void SaveReadFields ( SAVERESTOREDATA * pSaveData , const char * pname , void * pBaseData , TYPEDESCRIPTION * pFields , int fieldCount ) ;
extern void SaveGlobalState ( SAVERESTOREDATA * pSaveData ) ;
extern void RestoreGlobalState ( SAVERESTOREDATA * pSaveData ) ;
extern void ResetGlobalState ( void ) ;
//extern CBaseEntity *g_pDesiredList; //LRC- handles DesiredVel, for movewith
//LRC- added USE_SAME, USE_NOT, and USE_KILL
typedef enum
{
USE_OFF = 0 ,
USE_ON = 1 ,
USE_SET = 2 ,
USE_TOGGLE = 3 ,
USE_KILL = 4 ,
// special signals, never actually get sent:
USE_SAME = 5 ,
USE_NOT = 6 ,
} USE_TYPE ;
extern const char * GetStringForUseType ( USE_TYPE useType ) ;
extern void FireTargets ( const char * targetName , CBaseEntity * pActivator , CBaseEntity * pCaller , USE_TYPE useType , float value ) ;
typedef void ( CBaseEntity : : * BASEPTR ) ( void ) ;
typedef void ( CBaseEntity : : * ENTITYFUNCPTR ) ( CBaseEntity * pOther ) ;
typedef void ( CBaseEntity : : * USEPTR ) ( CBaseEntity * pActivator , CBaseEntity * pCaller , USE_TYPE useType , float value ) ;
// For CLASSIFY
# define CLASS_NONE 0
# define CLASS_MACHINE 1
# define CLASS_PLAYER 2
# define CLASS_HUMAN_PASSIVE 3
# define CLASS_HUMAN_MILITARY 4
# define CLASS_ALIEN_MILITARY 5
# define CLASS_ALIEN_PASSIVE 6
# define CLASS_ALIEN_MONSTER 7
# define CLASS_ALIEN_PREY 8
# define CLASS_ALIEN_PREDATOR 9
# define CLASS_INSECT 10
# define CLASS_PLAYER_ALLY 11
# define CLASS_PLAYER_BIOWEAPON 12 // hornets and snarks.launched by players
# define CLASS_ALIEN_BIOWEAPON 13 // hornets and snarks.launched by the alien menace
# define CLASS_FACTION_A 14 //LRC - very simple new classes, for use with Behaves As
# define CLASS_FACTION_B 15
# define CLASS_FACTION_C 16
# define CLASS_BARNACLE 99 // special because no one pays attention to it, and it eats a wide cross-section of creatures.
class CBaseEntity ;
class CBaseMonster ;
class CBasePlayerItem ;
class CSquadMonster ;
class CThinker ;
# define SF_NORESPAWN ( 1 << 30 ) // !!!set this bit on guns and stuff that should never respawn.
//
// EHANDLE. Safe way to point to CBaseEntities who may die between frames
//
class EHANDLE
{
private :
edict_t * m_pent ;
int m_serialnumber ;
public :
edict_t * Get ( void ) ;
edict_t * Set ( edict_t * pent ) ;
operator int ( ) ;
operator CBaseEntity * ( ) ;
CBaseEntity * operator = ( CBaseEntity * pEntity ) ;
CBaseEntity * operator - > ( ) ;
} ;
//
// Base Entity. All entity types derive from this
//
class CBaseEntity
{
public :
// Constructor. Set engine to use C/C++ callback functions
// pointers to engine data
entvars_t * pev ; // Don't need to save/restore this pointer, the engine resets it
// path corners
CBaseEntity * m_pGoalEnt ; // path corner we are heading towards
CBaseEntity * m_pLink ; // used for temporary link-list operations.
CBaseEntity * m_pMoveWith ; // LRC- the entity I move with.
int m_MoveWith ; //LRC- Name of that entity
CBaseEntity * m_pChildMoveWith ; //LRC- one of the entities that's moving with me.
CBaseEntity * m_pSiblingMoveWith ; //LRC- another entity that's Moving With the same ent as me. (linked list.)
Vector m_vecMoveWithOffset ; // LRC- Position I should be in relative to m_pMoveWith->pev->origin.
Vector m_vecRotWithOffset ; // LRC- Angles I should be facing relative to m_pMoveWith->pev->angles.
CBaseEntity * m_pAssistLink ; // LRC- link to the next entity which needs to be Assisted before physics are applied.
Vector m_vecPostAssistVel ; // LRC
Vector m_vecPostAssistAVel ; // LRC
float m_fNextThink ; // LRC - for SetNextThink and SetPhysThink. Marks the time when a think will be performed - not necessarily the same as pev->nextthink!
float m_fPevNextThink ; // LRC - always set equal to pev->nextthink, so that we can tell when the latter gets changed by the @#$^¬! engine.
int m_iLFlags ; // LRC- a new set of flags. (pev->spawnflags and pev->flags are full...)
virtual void DesiredAction ( void ) { } ; // LRC - for postponing stuff until PostThink time, not as a think.
int m_iStyle ; // LRC - almost anything can have a lightstyle these days...
Vector m_vecSpawnOffset ; // LRC- To fix things which (for example) MoveWith a door which Starts Open.
BOOL m_activated ; // LRC- moved here from func_train. Signifies that an entity has already been
// activated. (and hence doesn't need reactivating.)
//LRC - decent mechanisms for setting think times!
// this should have been done a long time ago, but MoveWith finally forced me.
virtual void SetNextThink ( float delay ) { SetNextThink ( delay , FALSE ) ; }
virtual void SetNextThink ( float delay , BOOL correctSpeed ) ;
virtual void AbsoluteNextThink ( float time ) { AbsoluteNextThink ( time , FALSE ) ; }
virtual void AbsoluteNextThink ( float time , BOOL correctSpeed ) ;
void SetEternalThink ( ) ;
// this is called by an entity which is starting to move, and will reach
// its destination after the given wait.
// Its think function should be called at that time, to make it stop moving.
// void SetPhysThink( float delay );
// this is called by an entity which is movingWith another entity.
// it signifies that the other entity is starting to move and will reach its
// destination after the given wait.
// This entity will need to think at that time (so that physics gets
// processed correctly), but the Think function shouldn't actually get
// called; the parent will intervene to make it stop.
// void SetMWPhysThink( float delay );
// this is called by an entity which is starting to move, and wants its children
// to follow it.
// void SetChildrenThink( float delay );
//LRC use this instead of "SetThink( NULL )" or "pev->nextthink = -1".
void DontThink ( void ) ;
//LRC similar, but called by the parent when a think needs to be aborted.
// void DontMWThink( void );
virtual void ThinkCorrection ( void ) ;
//LRC - loci
virtual Vector CalcPosition ( CBaseEntity * pLocus ) { return pev - > origin ; }
virtual Vector CalcVelocity ( CBaseEntity * pLocus ) { return pev - > velocity ; }
virtual float CalcRatio ( CBaseEntity * pLocus ) { return 0 ; }
//LRC - aliases
virtual BOOL IsAlias ( void ) { return FALSE ; }
// initialization functions
virtual void Spawn ( void ) { return ; }
virtual void Precache ( void ) { return ; }
virtual void KeyValue ( KeyValueData * pkvd )
{
//LRC - MoveWith for all!
if ( FStrEq ( pkvd - > szKeyName , " movewith " ) )
{
m_MoveWith = ALLOC_STRING ( pkvd - > szValue ) ;
pkvd - > fHandled = TRUE ;
}
else if ( FStrEq ( pkvd - > szKeyName , " skill " ) )
{
m_iLFlags = atoi ( pkvd - > szValue ) ;
pkvd - > fHandled = TRUE ;
}
else if ( FStrEq ( pkvd - > szKeyName , " style " ) )
{
m_iStyle = atoi ( pkvd - > szValue ) ;
pkvd - > fHandled = TRUE ;
}
else pkvd - > fHandled = FALSE ;
}
virtual int Save ( CSave & save ) ;
virtual int Restore ( CRestore & restore ) ;
//LRC - if I MoveWith something, then only cross transitions if the MoveWith entity does too.
virtual int ObjectCaps ( void ) { return m_pMoveWith ? m_pMoveWith - > ObjectCaps ( ) & FCAP_ACROSS_TRANSITION : FCAP_ACROSS_TRANSITION ; }
virtual void Activate ( void ) ; //LRC
void InitMoveWith ( void ) ; //LRC - called by Activate() to set up moveWith values
virtual void PostSpawn ( void ) { } //LRC - called by Activate() to handle entity-specific initialisation.
// (mostly setting positions, for MoveWith support)
// Setup the object->object collision box (pev->mins / pev->maxs is the object->world collision box)
virtual void SetObjectCollisionBox ( void ) ;
// Classify - returns the type of group (e.g., "alien monster", or "human military" so that monsters
// on the same side won't attack each other, even if they have different classnames.
virtual int Classify ( void ) { return CLASS_NONE ; } ;
virtual void DeathNotice ( entvars_t * pevChild ) { } // monster maker children use this to tell the monster maker that they have died.
// LRC- this supports a global concept of "entities with states", so that state_watchers and
// mastership (mastery? masterhood?) can work universally.
virtual STATE GetState ( void ) { return STATE_OFF ; } ;
// For team-specific doors in multiplayer, etc: a master's state depends on who wants to know.
virtual STATE GetState ( CBaseEntity * pEnt ) { return GetState ( ) ; } ;
static TYPEDESCRIPTION m_SaveData [ ] ;
virtual void TraceAttack ( entvars_t * pevAttacker , float flDamage , Vector vecDir , TraceResult * ptr , int bitsDamageType ) ;
virtual int TakeDamage ( entvars_t * pevInflictor , entvars_t * pevAttacker , float flDamage , int bitsDamageType ) ;
virtual int TakeHealth ( float flHealth , int bitsDamageType ) ;
virtual void Killed ( entvars_t * pevAttacker , int iGib ) ;
virtual int BloodColor ( void ) { return DONT_BLEED ; }
virtual void TraceBleed ( float flDamage , Vector vecDir , TraceResult * ptr , int bitsDamageType ) ;
//LRC- superceded by GetState ( pActivator ).
// virtual BOOL IsTriggered( CBaseEntity *pActivator ) {return TRUE;}
virtual CBaseMonster * MyMonsterPointer ( void ) { return NULL ; }
virtual CSquadMonster * MySquadMonsterPointer ( void ) { return NULL ; }
virtual int GetToggleState ( void ) { return TS_AT_TOP ; }
virtual void AddPoints ( int score , BOOL bAllowNegativeScore ) { }
virtual void AddPointsToTeam ( int score , BOOL bAllowNegativeScore ) { }
virtual BOOL AddPlayerItem ( CBasePlayerItem * pItem ) { return 0 ; }
virtual BOOL RemovePlayerItem ( CBasePlayerItem * pItem ) { return 0 ; }
virtual int GiveAmmo ( int iAmount , const char * szName , int iMax ) { return - 1 ; } ;
virtual float GetDelay ( void ) { return 0 ; }
virtual int IsMoving ( void ) { return pev - > velocity ! = g_vecZero ; }
virtual void OverrideReset ( void ) { }
virtual int DamageDecal ( int bitsDamageType ) ;
// This is ONLY used by the node graph to test movement through a door
virtual void SetToggleState ( int state ) { }
virtual void StartSneaking ( void ) { }
virtual void StopSneaking ( void ) { }
virtual BOOL OnControls ( entvars_t * pev ) { return FALSE ; }
virtual BOOL IsSneaking ( void ) { return FALSE ; }
virtual BOOL IsAlive ( void ) { return ( pev - > deadflag = = DEAD_NO ) & & pev - > health > 0 ; }
virtual BOOL IsBSPModel ( void ) { return pev - > solid = = SOLID_BSP | | pev - > movetype = = MOVETYPE_PUSHSTEP ; }
virtual BOOL ReflectGauss ( void ) { return ( IsBSPModel ( ) & & ! pev - > takedamage ) ; }
virtual BOOL HasTarget ( string_t targetname ) { return FStrEq ( STRING ( targetname ) , STRING ( pev - > target ) ) ; }
virtual BOOL IsInWorld ( void ) ;
virtual BOOL IsPlayer ( void ) { return FALSE ; }
virtual BOOL IsNetClient ( void ) { return FALSE ; }
virtual const char * TeamID ( void ) { return " " ; }
//virtual void SetActivator( CBaseEntity *pActivator ) {}
virtual CBaseEntity * GetNextTarget ( void ) ;
// fundamental callbacks
void ( CBaseEntity : : * m_pfnThink ) ( void ) ;
void ( CBaseEntity : : * m_pfnTouch ) ( CBaseEntity * pOther ) ;
void ( CBaseEntity : : * m_pfnUse ) ( CBaseEntity * pActivator , CBaseEntity * pCaller , USE_TYPE useType , float value ) ;
void ( CBaseEntity : : * m_pfnBlocked ) ( CBaseEntity * pOther ) ;
virtual void Think ( void ) { if ( m_pfnThink ) ( this - > * m_pfnThink ) ( ) ; }
virtual void Touch ( CBaseEntity * pOther ) { if ( m_pfnTouch ) ( this - > * m_pfnTouch ) ( pOther ) ; }
virtual void Use ( CBaseEntity * pActivator , CBaseEntity * pCaller , USE_TYPE useType , float value )
{
if ( m_pfnUse )
( this - > * m_pfnUse ) ( pActivator , pCaller , useType , value ) ;
}
virtual void Blocked ( CBaseEntity * pOther ) { if ( m_pfnBlocked ) ( this - > * m_pfnBlocked ) ( pOther ) ; } ;
// allow engine to allocate instance data
void * operator new ( size_t stAllocateBlock , entvars_t * pev )
{
return ( void * ) ALLOC_PRIVATE ( ENT ( pev ) , stAllocateBlock ) ;
} ;
// don't use this.
# if _MSC_VER >= 1200 // only build this code if MSVC++ 6.0 or higher
void operator delete ( void * pMem , entvars_t * pev )
{
pev - > flags | = FL_KILLME ;
} ;
# endif
virtual void UpdateOnRemove ( void ) ;
// common member functions
void EXPORT SUB_Remove ( void ) ;
void EXPORT SUB_DoNothing ( void ) ;
void EXPORT SUB_StartFadeOut ( void ) ;
void EXPORT SUB_FadeOut ( void ) ;
void EXPORT SUB_CallUseToggle ( void ) // a think function used at spawn time. Don't apply the moveWith fix to it.
{ this - > Use ( this , this , USE_TOGGLE , 0 ) ; }
int ShouldToggle ( USE_TYPE useType , BOOL currentState ) ;
int ShouldToggle ( USE_TYPE useType ) ; //LRC this version uses GetState()
void FireBullets ( ULONG cShots , Vector vecSrc , Vector vecDirShooting , Vector vecSpread , float flDistance , int iBulletType , int iTracerFreq = 4 , int iDamage = 0 , entvars_t * pevAttacker = NULL ) ;
Vector FireBulletsPlayer ( ULONG cShots , Vector vecSrc , Vector vecDirShooting , Vector vecSpread , float flDistance , int iBulletType , int iTracerFreq = 4 , int iDamage = 0 , entvars_t * pevAttacker = NULL , int shared_rand = 0 ) ;
virtual CBaseEntity * Respawn ( void ) { return NULL ; }
void SUB_UseTargets ( CBaseEntity * pActivator , USE_TYPE useType , float value ) ;
// Do the bounding boxes of these two intersect?
int Intersects ( CBaseEntity * pOther ) ;
void MakeDormant ( void ) ;
int IsDormant ( void ) ;
BOOL IsLockedByMaster ( void ) { return FALSE ; }
static CBaseEntity * Instance ( edict_t * pent )
{
if ( ! pent )
pent = ENT ( 0 ) ;
CBaseEntity * pEnt = ( CBaseEntity * ) GET_PRIVATE ( pent ) ;
return pEnt ;
}
static CBaseEntity * Instance ( entvars_t * pev ) { return Instance ( ENT ( pev ) ) ; }
static CBaseEntity * Instance ( int eoffset ) { return Instance ( ENT ( eoffset ) ) ; }
CBaseMonster * GetMonsterPointer ( entvars_t * pevMonster )
{
CBaseEntity * pEntity = Instance ( pevMonster ) ;
if ( pEntity )
return pEntity - > MyMonsterPointer ( ) ;
return NULL ;
}
CBaseMonster * GetMonsterPointer ( edict_t * pentMonster )
{
CBaseEntity * pEntity = Instance ( pentMonster ) ;
if ( pEntity )
return pEntity - > MyMonsterPointer ( ) ;
return NULL ;
}
// Ugly code to lookup all functions to make sure they are exported when set.
# if _DEBUG
void FunctionCheck ( void * pFunction , char * name )
{
if ( pFunction & & ! NAME_FOR_FUNCTION ( pFunction ) )
ALERT ( at_error , " No EXPORT: %s:%s (%08lx) \n " , STRING ( pev - > classname ) , name , ( size_t ) pFunction ) ;
}
BASEPTR ThinkSet ( BASEPTR func , char * name )
{
m_pfnThink = func ;
FunctionCheck ( ( void * ) * ( ( int * ) ( ( char * ) this + ( offsetof ( CBaseEntity , m_pfnThink ) ) ) ) , name ) ;
return func ;
}
ENTITYFUNCPTR TouchSet ( ENTITYFUNCPTR func , char * name )
{
m_pfnTouch = func ;
FunctionCheck ( ( void * ) * ( ( int * ) ( ( char * ) this + ( offsetof ( CBaseEntity , m_pfnTouch ) ) ) ) , name ) ;
return func ;
}
USEPTR UseSet ( USEPTR func , char * name )
{
m_pfnUse = func ;
FunctionCheck ( ( void * ) * ( ( int * ) ( ( char * ) this + ( offsetof ( CBaseEntity , m_pfnUse ) ) ) ) , name ) ;
return func ;
}
ENTITYFUNCPTR BlockedSet ( ENTITYFUNCPTR func , char * name )
{
m_pfnBlocked = func ;
FunctionCheck ( ( void * ) * ( ( int * ) ( ( char * ) this + ( offsetof ( CBaseEntity , m_pfnBlocked ) ) ) ) , name ) ;
return func ;
}
# endif
// virtual functions used by a few classes
// used by monsters that are created by the MonsterMaker
virtual void UpdateOwner ( void ) { return ; } ;
static CBaseEntity * Create ( const char * szName , const Vector & vecOrigin , const Vector & vecAngles , edict_t * pentOwner = NULL ) ;
virtual BOOL FBecomeProne ( void ) { return FALSE ; } ;
edict_t * edict ( ) { return ENT ( pev ) ; } ;
EOFFSET eoffset ( ) { return OFFSET ( pev ) ; } ;
int entindex ( ) { return ENTINDEX ( edict ( ) ) ; } ;
virtual Vector Center ( ) { return ( pev - > absmax + pev - > absmin ) * 0.5 ; } ; // center point of entity
virtual Vector EyePosition ( ) { return pev - > origin + pev - > view_ofs ; } ; // position of eyes
virtual Vector EarPosition ( ) { return pev - > origin + pev - > view_ofs ; } ; // position of ears
virtual Vector BodyTarget ( const Vector & posSrc ) { return Center ( ) ; } ; // position to shoot at
virtual int Illumination ( ) { return GETENTITYILLUM ( ENT ( pev ) ) ; } ;
virtual BOOL FVisible ( CBaseEntity * pEntity ) ;
virtual BOOL FVisible ( const Vector & vecOrigin ) ;
//We use this variables to store each ammo count.
int ammo_9mm ;
int ammo_357 ;
int ammo_50ae ;
int ammo_buckshot ;
int ammo_9mmar ;
// Special stuff for grenades and satchels.
float m_flStartThrow ;
float m_flReleaseThrow ;
int m_chargeReady ;
int m_fInAttack ;
enum EGON_FIRESTATE { FIRE_OFF , FIRE_CHARGE } ;
int m_fireState ;
} ;
//LRC- moved here from player.cpp. I'd put it in util.h with its friends, but it needs CBaseEntity to be declared.
inline BOOL FNullEnt ( CBaseEntity * ent ) { return ent = = NULL | | FNullEnt ( ent - > edict ( ) ) ; }
// Ugly technique to override base member functions
// Normally it's illegal to cast a pointer to a member function of a derived class to a pointer to a
// member function of a base class. static_cast is a sleezy way around that problem.
# if _DEBUG
# define SetThink( a ) ThinkSet( static_cast <void (CBaseEntity::*)(void)> (a), #a )
# define SetTouch( a ) TouchSet( static_cast <void (CBaseEntity::*)(CBaseEntity *)> (a), #a )
# define SetUse( a ) UseSet( static_cast <void (CBaseEntity::*)( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )> (a), #a )
# define SetBlocked( a ) BlockedSet( static_cast <void (CBaseEntity::*)(CBaseEntity *)> (a), #a )
# define ResetThink() SetThink(NULL)
# else
# define SetThink( a ) m_pfnThink = static_cast <void (CBaseEntity::*)(void)> (a)
# define SetTouch( a ) m_pfnTouch = static_cast <void (CBaseEntity::*)(CBaseEntity *)> (a)
# define SetUse( a ) m_pfnUse = static_cast <void (CBaseEntity::*)( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )> (a)
# define SetBlocked( a ) m_pfnBlocked = static_cast <void (CBaseEntity::*)(CBaseEntity *)> (a)
# define ResetThink( ) m_pfnThink = static_cast <void (CBaseEntity::*)(void)> (NULL)
# define ResetTouch( ) m_pfnTouch = static_cast <void (CBaseEntity::*)(CBaseEntity *)> (NULL)
# define ResetUse( ) m_pfnUse = static_cast <void (CBaseEntity::*)( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )> (NULL)
# define ResetBlocked( ) m_pfnBlocked = static_cast <void (CBaseEntity::*)(CBaseEntity *)> (NULL)
# endif
class CPointEntity : public CBaseEntity
{
public :
void Spawn ( void ) ;
virtual int ObjectCaps ( void ) { return CBaseEntity : : ObjectCaps ( ) & ~ FCAP_ACROSS_TRANSITION ; }
private :
} ;
typedef struct locksounds // sounds that doors and buttons make when locked/unlocked
{
string_t sLockedSound ; // sound a door makes when it's locked
string_t sLockedSentence ; // sentence group played when door is locked
string_t sUnlockedSound ; // sound a door makes when it's unlocked
string_t sUnlockedSentence ; // sentence group played when door is unlocked
int iLockedSentence ; // which sentence in sentence group to play next
int iUnlockedSentence ; // which sentence in sentence group to play next
float flwaitSound ; // time delay between playing consecutive 'locked/unlocked' sounds
float flwaitSentence ; // time delay between playing consecutive sentences
BYTE bEOFLocked ; // true if hit end of list of locked sentences
BYTE bEOFUnlocked ; // true if hit end of list of unlocked sentences
} locksound_t ;
void PlayLockSounds ( entvars_t * pev , locksound_t * pls , int flocked , int fbutton ) ;
//
// MultiSouce
//
# define MAX_MULTI_TARGETS 16 // maximum number of targets a single multi_manager entity may be assigned.
# define MS_MAX_TARGETS 32
class CMultiSource : public CPointEntity
{
public :
void Spawn ( ) ;
void KeyValue ( KeyValueData * pkvd ) ;
void Use ( CBaseEntity * pActivator , CBaseEntity * pCaller , USE_TYPE useType , float value ) ;
STATE GetState ( void ) ;
void EXPORT Register ( void ) ;
virtual int Save ( CSave & save ) ;
virtual int Restore ( CRestore & restore ) ;
static TYPEDESCRIPTION m_SaveData [ ] ;
EHANDLE m_rgEntities [ MS_MAX_TARGETS ] ;
int m_rgTriggered [ MS_MAX_TARGETS ] ;
int m_iTotal ;
string_t m_globalstate ;
} ;
//
// generic Delay entity.
//
class CBaseDelay : public CBaseEntity
{
public :
float m_flDelay ;
string_t m_iszKillTarget ;
EHANDLE m_hActivator ; //LRC - moved here from CBaseToggle
virtual void KeyValue ( KeyValueData * pkvd ) ;
virtual int Save ( CSave & save ) ;
virtual int Restore ( CRestore & restore ) ;
static TYPEDESCRIPTION m_SaveData [ ] ;
// common member functions
void SUB_UseTargets ( CBaseEntity * pActivator , USE_TYPE useType , float value ) ;
void EXPORT DelayThink ( void ) ;
} ;
class CBaseAnimating : public CBaseDelay
{
public :
virtual int Save ( CSave & save ) ;
virtual int Restore ( CRestore & restore ) ;
static TYPEDESCRIPTION m_SaveData [ ] ;
// Basic Monster Animation functions
float StudioFrameAdvance ( float flInterval = 0.0 ) ; // accumulate animation frame time from last time called until now
int GetSequenceFlags ( void ) ;
int LookupActivity ( int activity ) ;
int LookupActivityHeaviest ( int activity ) ;
int LookupSequence ( const char * label ) ;
void ResetSequenceInfo ( ) ;
void DispatchAnimEvents ( float flFutureInterval = 0.1 ) ; // Handle events that have happend since last time called up until X seconds into the future
virtual void HandleAnimEvent ( MonsterEvent_t * pEvent ) { return ; } ;
float SetBoneController ( int iController , float flValue ) ;
void InitBoneControllers ( void ) ;
float SetBlending ( int iBlender , float flValue ) ;
void GetBonePosition ( int iBone , Vector & origin , Vector & angles ) ;
void GetAutomovement ( Vector & origin , Vector & angles , float flInterval = 0.1 ) ;
int FindTransition ( int iEndingSequence , int iGoalSequence , int * piDir ) ;
void GetAttachment ( int iAttachment , Vector & origin , Vector & angles ) ;
void SetBodygroup ( int iGroup , int iValue ) ;
int GetBodygroup ( int iGroup ) ;
//LRC
int GetBoneCount ( void ) ;
void SetBones ( float ( * data ) [ 3 ] , int datasize ) ;
int ExtractBbox ( int sequence , float * mins , float * maxs ) ;
void SetSequenceBox ( void ) ;
// animation needs
float m_flFrameRate ; // computed FPS for current sequence
float m_flGroundSpeed ; // computed linear movement rate for current sequence
float m_flLastEventCheck ; // last time the event list was checked
BOOL m_fSequenceFinished ; // flag set when StudioAdvanceFrame moves across a frame boundry
BOOL m_fSequenceLoops ; // true if the sequence loops
} ;
//
// generic Toggle entity.
//
# define SF_ITEM_USE_ONLY 256 // ITEM_USE_ONLY = BUTTON_USE_ONLY = DOOR_USE_ONLY!!!
class CBaseToggle : public CBaseAnimating
{
public :
void KeyValue ( KeyValueData * pkvd ) ;
TOGGLE_STATE m_toggle_state ;
float m_flActivateFinished ; //like attack_finished, but for doors
float m_flMoveDistance ; // how far a door should slide or rotate
float m_flWait ;
float m_flLip ;
float m_flTWidth ; // for plats
float m_flTLength ; // for plats
Vector m_vecPosition1 ;
Vector m_vecPosition2 ;
Vector m_vecAngle1 ;
Vector m_vecAngle2 ;
int m_cTriggersLeft ; // trigger_counter only, # of activations remaining
float m_flHeight ;
void ( CBaseToggle : : * m_pfnCallWhenMoveDone ) ( void ) ;
Vector m_vecFinalDest ;
float m_flLinearMoveSpeed ; // LRC- allows a LinearMove to be delayed until a think.
float m_flAngularMoveSpeed ; // LRC
Vector m_vecFinalAngle ;
int m_bitsDamageInflict ; // DMG_ damage type that the door or tigger does
virtual int Save ( CSave & save ) ;
virtual int Restore ( CRestore & restore ) ;
static TYPEDESCRIPTION m_SaveData [ ] ;
virtual int GetToggleState ( void ) { return m_toggle_state ; }
// LRC- overridden because toggling entities have general rules governing their states.
virtual STATE GetState ( void ) ;
virtual float GetDelay ( void ) { return m_flWait ; }
// common member functions
void LinearMove ( Vector vecInput , float flSpeed ) ;
//void LinearMove( Vector vecInput, float flSpeed, BOOL bNow );
void EXPORT LinearMoveNow ( void ) ; //LRC- think function that lets us guarantee a LinearMove gets done as a think.
void EXPORT LinearMoveDone ( void ) ;
void EXPORT LinearMoveDoneNow ( void ) ; //LRC
// void EXPORT LinearMoveFinalDone( void );
void AngularMove ( Vector vecDestAngle , float flSpeed ) ;
void EXPORT AngularMoveNow ( void ) ; //LRC- think function that lets us guarantee an AngularMove gets done as a think.
void EXPORT AngularMoveDone ( void ) ;
void EXPORT AngularMoveDoneNow ( void ) ;
BOOL IsLockedByMaster ( void ) ;
static float AxisValue ( int flags , const Vector & angles ) ;
static void AxisDir ( entvars_t * pev ) ;
static float AxisDelta ( int flags , const Vector & angle1 , const Vector & angle2 ) ;
string_t m_sMaster ; // If this button has a master switch, this is the targetname.
// A master switch must be of the multisource type. If all
// of the switches in the multisource have been triggered, then
// the button will be allowed to operate. Otherwise, it will be
// deactivated.
} ;
# define SetMoveDone( a ) m_pfnCallWhenMoveDone = static_cast <void (CBaseToggle::*)(void)> (a)
// people gib if their health is <= this at the time of death
# define GIB_HEALTH_VALUE -30
# define ROUTE_SIZE 8 // how many waypoints a monster can store at one time
# define MAX_OLD_ENEMIES 4 // how many old enemies to remember
# define bits_CAP_DUCK ( 1 << 0 ) // crouch
# define bits_CAP_JUMP ( 1 << 1 ) // jump/leap
# define bits_CAP_STRAFE ( 1 << 2 ) // strafe ( walk/run sideways)
# define bits_CAP_SQUAD ( 1 << 3 ) // can form squads
# define bits_CAP_SWIM ( 1 << 4 ) // proficiently navigate in water
# define bits_CAP_CLIMB ( 1 << 5 ) // climb ladders/ropes
# define bits_CAP_USE ( 1 << 6 ) // open doors/push buttons/pull levers
# define bits_CAP_HEAR ( 1 << 7 ) // can hear forced sounds
# define bits_CAP_AUTO_DOORS ( 1 << 8 ) // can trigger auto doors
# define bits_CAP_OPEN_DOORS ( 1 << 9 ) // can open manual doors
# define bits_CAP_TURN_HEAD ( 1 << 10) // can turn head, always bone controller 0
# define bits_CAP_RANGE_ATTACK1 ( 1 << 11) // can do a range attack 1
# define bits_CAP_RANGE_ATTACK2 ( 1 << 12) // can do a range attack 2
# define bits_CAP_MELEE_ATTACK1 ( 1 << 13) // can do a melee attack 1
# define bits_CAP_MELEE_ATTACK2 ( 1 << 14) // can do a melee attack 2
# define bits_CAP_FLY ( 1 << 15) // can fly, move all around
# define bits_CAP_DOORS_GROUP (bits_CAP_USE | bits_CAP_AUTO_DOORS | bits_CAP_OPEN_DOORS)
// used by suit voice to indicate damage sustained and repaired type to player
// instant damage
# define DMG_GENERIC 0 // generic damage was done
# define DMG_CRUSH (1 << 0) // crushed by falling or moving object
# define DMG_BULLET (1 << 1) // shot
# define DMG_SLASH (1 << 2) // cut, clawed, stabbed
# define DMG_BURN (1 << 3) // heat burned
# define DMG_FREEZE (1 << 4) // frozen
# define DMG_FALL (1 << 5) // fell too far
# define DMG_BLAST (1 << 6) // explosive blast damage
# define DMG_CLUB (1 << 7) // crowbar, punch, headbutt
# define DMG_SHOCK (1 << 8) // electric shock
# define DMG_SONIC (1 << 9) // sound pulse shockwave
# define DMG_ENERGYBEAM (1 << 10) // laser or other high energy beam
# define DMG_NEVERGIB (1 << 12) // with this bit OR'd in, no damage type will be able to gib victims upon death
# define DMG_ALWAYSGIB (1 << 13) // with this bit OR'd in, any damage type can be made to gib victims upon death.
# define DMG_DROWN (1 << 14) // Drowning
// time-based damage
# define DMG_TIMEBASED (~(0x3fff)) // mask for time-based damage
# define DMG_PARALYZE (1 << 15) // slows affected creature down
# define DMG_NERVEGAS (1 << 16) // nerve toxins, very bad
# define DMG_POISON (1 << 17) // blood poisioning
# define DMG_RADIATION (1 << 18) // radiation exposure
# define DMG_DROWNRECOVER (1 << 19) // drowning recovery
# define DMG_ACID (1 << 20) // toxic chemicals or acid burns
# define DMG_SLOWBURN (1 << 21) // in an oven
# define DMG_SLOWFREEZE (1 << 22) // in a subzero freezer
# define DMG_MORTAR (1 << 23) // Hit by air raid (done to distinguish grenade from mortar)
# define DMG_SPEAR (1 << 24)
// these are the damage types that are allowed to gib corpses
# define DMG_GIB_CORPSE ( DMG_CRUSH | DMG_FALL | DMG_BLAST | DMG_SONIC | DMG_CLUB )
// these are the damage types that have client hud art
# define DMG_SHOWNHUD (DMG_POISON | DMG_ACID | DMG_FREEZE | DMG_SLOWFREEZE | DMG_DROWN | DMG_BURN | DMG_SLOWBURN | DMG_NERVEGAS | DMG_RADIATION | DMG_SHOCK)
// NOTE: tweak these values based on gameplay feedback:
# define PARALYZE_DURATION 2 // number of 2 second intervals to take damage
# define PARALYZE_DAMAGE 1.0 // damage to take each 2 second interval
# define NERVEGAS_DURATION 2
# define NERVEGAS_DAMAGE 5.0
# define POISON_DURATION 5
# define POISON_DAMAGE 2.0
# define RADIATION_DURATION 2
# define RADIATION_DAMAGE 1.0
# define ACID_DURATION 2
# define ACID_DAMAGE 5.0
# define SLOWBURN_DURATION 2
# define SLOWBURN_DAMAGE 1.0
# define SLOWFREEZE_DURATION 2
# define SLOWFREEZE_DAMAGE 1.0
# define itbd_Paralyze 0
# define itbd_NerveGas 1
# define itbd_Poison 2
# define itbd_Radiation 3
# define itbd_DrownRecover 4
# define itbd_Acid 5
# define itbd_SlowBurn 6
# define itbd_SlowFreeze 7
# define CDMG_TIMEBASED 8
// when calling KILLED(), a value that governs gib behavior is expected to be
// one of these three values
# define GIB_NORMAL 0 // gib if entity was overkilled
# define GIB_NEVER 1 // never gib, no matter how much death damage is done ( freezing, etc )
# define GIB_ALWAYS 2 // always gib ( Houndeye Shock, Barnacle Bite )
class CBaseMonster ;
class CCineMonster ;
class CSound ;
# include "basemonster.h"
const char * ButtonSound ( int sound ) ; // get string of button sound number
//
// Generic Button
//
class CBaseButton : public CBaseToggle
{
public :
void Spawn ( void ) ;
virtual void PostSpawn ( void ) ; //LRC
virtual void Precache ( void ) ;
void RotSpawn ( void ) ;
virtual void KeyValue ( KeyValueData * pkvd ) ;
void ButtonActivate ( ) ;
void SparkSoundCache ( void ) ;
void EXPORT ButtonShot ( void ) ;
void EXPORT ButtonTouch ( CBaseEntity * pOther ) ;
void EXPORT ButtonSpark ( void ) ;
void EXPORT TriggerAndWait ( void ) ;
void EXPORT ButtonReturn ( void ) ;
void EXPORT ButtonBackHome ( void ) ;
void EXPORT ButtonUse_IgnorePlayer ( CBaseEntity * pActivator , CBaseEntity * pCaller , USE_TYPE useType , float value ) ;
void EXPORT ButtonUse ( CBaseEntity * pActivator , CBaseEntity * pCaller , USE_TYPE useType , float value ) ;
virtual int TakeDamage ( entvars_t * pevInflictor , entvars_t * pevAttacker , float flDamage , int bitsDamageType ) ;
virtual int Save ( CSave & save ) ;
virtual int Restore ( CRestore & restore ) ;
enum BUTTON_CODE { BUTTON_NOTHING , BUTTON_ACTIVATE , BUTTON_RETURN } ;
BUTTON_CODE ButtonResponseToTouch ( void ) ;
static TYPEDESCRIPTION m_SaveData [ ] ;
virtual int ObjectCaps ( void ) ;
BOOL m_fStayPushed ; // button stays pushed in until touched again?
BOOL m_fRotating ; // a rotating button? default is a sliding button.
string_t m_strChangeTarget ; // if this field is not null, this is an index into the engine string array.
// when this button is touched, it's target entity's TARGET field will be set
// to the button's ChangeTarget. This allows you to make a func_train switch paths, etc.
locksound_t m_ls ; // door lock sounds
BYTE m_bLockedSound ; // ordinals from entity selection
BYTE m_bLockedSentence ;
BYTE m_bUnlockedSound ;
BYTE m_bUnlockedSentence ;
int m_sounds ;
} ;
//
// Weapons
//
# define BAD_WEAPON 0x00007FFF
//
// Converts a entvars_t * to a class pointer
// It will allocate the class and entity if necessary
//
template < class T > T * GetClassPtr ( T * a )
{
entvars_t * pev = ( entvars_t * ) a ;
// allocate entity if necessary
if ( pev = = NULL )
pev = VARS ( CREATE_ENTITY ( ) ) ;
// get the private data
a = ( T * ) GET_PRIVATE ( ENT ( pev ) ) ;
if ( a = = NULL )
{
// allocate private data
a = new ( pev ) T ;
a - > pev = pev ;
}
return a ;
}
/*
bit_PUSHBRUSH_DATA | bit_TOGGLE_DATA
bit_MONSTER_DATA
bit_DELAY_DATA
bit_TOGGLE_DATA | bit_DELAY_DATA | bit_MONSTER_DATA
bit_PLAYER_DATA | bit_MONSTER_DATA
bit_MONSTER_DATA | CYCLER_DATA
bit_LIGHT_DATA
path_corner_data
bit_MONSTER_DATA | wildcard_data
bit_MONSTER_DATA | bit_GROUP_DATA
boid_flock_data
boid_data
CYCLER_DATA
bit_ITEM_DATA
bit_ITEM_DATA | func_hud_data
bit_TOGGLE_DATA | bit_ITEM_DATA
EOFFSET
env_sound_data
env_sound_data
push_trigger_data
*/
# define TRACER_FREQ 4 // Tracers fire every 4 bullets
typedef struct _SelAmmo
{
BYTE Ammo1Type ;
BYTE Ammo1 ;
BYTE Ammo2Type ;
BYTE Ammo2 ;
} SelAmmo ;
//LRC- much as I hate to add new globals, I can't see how to read data from the World entity.
extern BOOL g_startSuit ;
//LRC- moved here from alias.cpp so that util functions can use these defs.
class CBaseAlias : public CPointEntity
{
public :
BOOL IsAlias ( void ) { return TRUE ; } ;
virtual CBaseEntity * FollowAlias ( CBaseEntity * pFrom ) { return NULL ; } ;
virtual void ChangeValue ( int iszValue ) { ALERT ( at_error , " %s entities cannot change value! " , STRING ( pev - > classname ) ) ; }
virtual void ChangeValue ( CBaseEntity * pValue ) { ChangeValue ( pValue - > pev - > targetname ) ; }
virtual void FlushChanges ( void ) { } ;
virtual int Save ( CSave & save ) ;
virtual int Restore ( CRestore & restore ) ;
static TYPEDESCRIPTION m_SaveData [ ] ;
CBaseAlias * m_pNextAlias ;
} ;
class CInfoGroup : public CPointEntity
{
public :
void KeyValue ( KeyValueData * pkvd ) ;
void Use ( CBaseEntity * pActivator , CBaseEntity * pCaller , USE_TYPE useType , float value ) ;
int GetMember ( const char * szMemberName ) ;
virtual int Save ( CSave & save ) ;
virtual int Restore ( CRestore & restore ) ;
static TYPEDESCRIPTION m_SaveData [ ] ;
int m_cMembers ;
int m_iszMemberName [ MAX_MULTI_TARGETS ] ;
int m_iszMemberValue [ MAX_MULTI_TARGETS ] ;
int m_iszDefaultMember ;
} ;
class CMultiAlias : public CBaseAlias
{
public :
void KeyValue ( KeyValueData * pkvd ) ;
virtual int Save ( CSave & save ) ;
virtual int Restore ( CRestore & restore ) ;
static TYPEDESCRIPTION m_SaveData [ ] ;
CBaseEntity * FollowAlias ( CBaseEntity * pFrom ) ;
int m_cTargets ;
int m_iszTargets [ MAX_MULTI_TARGETS ] ;
int m_iTotalValue ;
int m_iValues [ MAX_MULTI_TARGETS ] ;
int m_iMode ;
} ;
// this moved here from world.cpp, to allow classes to be derived from it
//=======================
// CWorld
//
// This spawns first when each level begins.
//=======================
class CWorld : public CBaseEntity
{
public :
void Spawn ( void ) ;
void Precache ( void ) ;
void KeyValue ( KeyValueData * pkvd ) ;
CBaseAlias * m_pFirstAlias ;
} ;
extern CWorld * g_pWorld ;
# endif