2022-12-17 13:32:43 +01:00
|
|
|
/***
|
2013-08-30 13:34:05 -07:00
|
|
|
*
|
|
|
|
* Copyright (c) 1996-2001, 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.
|
|
|
|
*
|
|
|
|
****/
|
2021-11-18 19:48:34 +01:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2013-08-30 13:34:05 -07:00
|
|
|
/*
|
|
|
|
|
|
|
|
Class Hierachy
|
|
|
|
|
|
|
|
CBaseEntity
|
|
|
|
CBaseDelay
|
|
|
|
CBaseToggle
|
|
|
|
CBaseItem
|
|
|
|
CBaseMonster
|
|
|
|
CBaseCycler
|
|
|
|
CBasePlayer
|
|
|
|
CBaseGroup
|
|
|
|
*/
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
#define MAX_PATH_SIZE 10 // max number of nodes available for a path.
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
// These are caps bits to indicate what an object's capabilities (currently used for save/restore and level transitions)
|
2021-11-28 16:54:48 +01:00
|
|
|
#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)
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
// UNDONE: This will ignore transition volumes (trigger_transition), but not the PVS!!!
|
2021-11-28 16:54:48 +01:00
|
|
|
#define FCAP_FORCE_TRANSITION 0x00000080 // ALWAYS goes across transitions
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-18 20:33:58 +01:00
|
|
|
#include "Platform.h"
|
2013-08-30 13:34:05 -07:00
|
|
|
#include "saverestore.h"
|
|
|
|
#include "schedule.h"
|
|
|
|
#include "monsterevent.h"
|
|
|
|
|
2018-09-03 10:47:51 +02:00
|
|
|
// C functions for external declarations that call the appropriate C++ methods
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2018-09-03 10:47:51 +02:00
|
|
|
#define EXPORT DLLEXPORT
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
extern "C" DLLEXPORT int GetEntityAPI(DLL_FUNCTIONS* pFunctionTable, int interfaceVersion);
|
|
|
|
extern "C" DLLEXPORT int GetEntityAPI2(DLL_FUNCTIONS* pFunctionTable, int* interfaceVersion);
|
|
|
|
extern "C" DLLEXPORT int GetNewDLLFunctions(NEW_DLL_FUNCTIONS* pFunctionTable, int* interfaceVersion);
|
|
|
|
|
2021-11-28 20:40:56 +01:00
|
|
|
/**
|
|
|
|
* @brief HACKHACK -- this is a hack to keep the node graph entity from "touching" things (like triggers)
|
|
|
|
* while it builds the graph
|
|
|
|
*/
|
|
|
|
inline bool gTouchDisabled = false;
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
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);
|
2021-03-05 20:54:33 +01:00
|
|
|
extern void ResetGlobalState();
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
USE_OFF = 0,
|
|
|
|
USE_ON = 1,
|
|
|
|
USE_SET = 2,
|
|
|
|
USE_TOGGLE = 3
|
|
|
|
} USE_TYPE;
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
extern void FireTargets(const char* targetName, CBaseEntity* pActivator, CBaseEntity* pCaller, USE_TYPE useType, float value);
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-03-05 20:54:33 +01:00
|
|
|
typedef void (CBaseEntity::*BASEPTR)();
|
2021-11-28 16:54:48 +01:00
|
|
|
typedef void (CBaseEntity::*ENTITYFUNCPTR)(CBaseEntity* pOther);
|
|
|
|
typedef void (CBaseEntity::*USEPTR)(CBaseEntity* pActivator, CBaseEntity* pCaller, USE_TYPE useType, float value);
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
// For CLASSIFY
|
2021-11-28 16:54:48 +01:00
|
|
|
#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_BARNACLE 99 // special because no one pays attention to it, and it eats a wide cross-section of creatures.
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2024-08-28 15:17:52 +02:00
|
|
|
#define CLASS_VEHICLE 14
|
|
|
|
|
2013-08-30 13:34:05 -07:00
|
|
|
class CBaseEntity;
|
2024-08-28 16:59:46 +02:00
|
|
|
class CBaseToggle;
|
2013-08-30 13:34:05 -07:00
|
|
|
class CBaseMonster;
|
|
|
|
class CBasePlayerItem;
|
|
|
|
class CSquadMonster;
|
|
|
|
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
#define SF_NORESPAWN (1 << 30) // !!!set this bit on guns and stuff that should never respawn.
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
//
|
|
|
|
// EHANDLE. Safe way to point to CBaseEntities who may die between frames
|
|
|
|
//
|
|
|
|
class EHANDLE
|
|
|
|
{
|
|
|
|
private:
|
2021-11-28 16:54:48 +01:00
|
|
|
edict_t* m_pent;
|
|
|
|
int m_serialnumber;
|
|
|
|
|
2013-08-30 13:34:05 -07:00
|
|
|
public:
|
2021-11-28 16:54:48 +01:00
|
|
|
edict_t* Get();
|
|
|
|
edict_t* Set(edict_t* pent);
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
operator CBaseEntity*();
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
CBaseEntity* operator=(CBaseEntity* pEntity);
|
|
|
|
CBaseEntity* operator->();
|
2013-08-30 13:34:05 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// Base Entity. All entity types derive from this
|
|
|
|
//
|
2021-11-28 16:54:48 +01:00
|
|
|
class CBaseEntity
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
// Constructor. Set engine to use C/C++ callback functions
|
|
|
|
// pointers to engine data
|
2021-11-28 16:54:48 +01:00
|
|
|
entvars_t* pev; // Don't need to save/restore this pointer, the engine resets it
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
// path corners
|
2021-11-28 16:54:48 +01:00
|
|
|
CBaseEntity* m_pGoalEnt; // path corner we are heading towards
|
|
|
|
CBaseEntity* m_pLink; // used for temporary link-list operations.
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2022-03-28 12:37:15 +02:00
|
|
|
/**
|
|
|
|
* @brief Entity flags sent to the client in ::AddToFullPack
|
|
|
|
*/
|
|
|
|
byte m_EFlags = 0;
|
|
|
|
|
2021-03-05 19:11:52 +01:00
|
|
|
virtual ~CBaseEntity() {}
|
|
|
|
|
2013-08-30 13:34:05 -07:00
|
|
|
// initialization functions
|
2021-11-28 16:54:48 +01:00
|
|
|
virtual void Spawn() {}
|
|
|
|
virtual void Precache() {}
|
|
|
|
virtual bool KeyValue(KeyValueData* pkvd) { return false; }
|
|
|
|
virtual bool Save(CSave& save);
|
|
|
|
virtual bool Restore(CRestore& restore);
|
|
|
|
virtual int ObjectCaps() { return FCAP_ACROSS_TRANSITION; }
|
|
|
|
virtual void Activate() {}
|
|
|
|
|
2013-08-30 13:34:05 -07:00
|
|
|
// Setup the object->object collision box (pev->mins / pev->maxs is the object->world collision box)
|
2021-11-28 16:54:48 +01:00
|
|
|
virtual void SetObjectCollisionBox();
|
|
|
|
|
|
|
|
// Classify - returns the type of group (i.e, "houndeye", or "human military" so that monsters with different classnames
|
|
|
|
// still realize that they are teammates. (overridden for monsters that form groups)
|
|
|
|
virtual int Classify() { return CLASS_NONE; }
|
|
|
|
virtual void DeathNotice(entvars_t* pevChild) {} // monster maker children use this to tell the monster maker that they have died.
|
|
|
|
|
|
|
|
|
|
|
|
static TYPEDESCRIPTION m_SaveData[];
|
|
|
|
|
|
|
|
virtual void TraceAttack(entvars_t* pevAttacker, float flDamage, Vector vecDir, TraceResult* ptr, int bitsDamageType);
|
|
|
|
virtual bool TakeDamage(entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType);
|
|
|
|
virtual bool TakeHealth(float flHealth, int bitsDamageType);
|
|
|
|
virtual void Killed(entvars_t* pevAttacker, int iGib);
|
|
|
|
virtual int BloodColor() { return DONT_BLEED; }
|
|
|
|
virtual void TraceBleed(float flDamage, Vector vecDir, TraceResult* ptr, int bitsDamageType);
|
|
|
|
virtual bool IsTriggered(CBaseEntity* pActivator) { return true; }
|
2024-08-28 16:59:46 +02:00
|
|
|
virtual CBaseToggle* MyTogglePointer() { return NULL; }
|
2021-11-28 16:54:48 +01:00
|
|
|
virtual CBaseMonster* MyMonsterPointer() { return NULL; }
|
|
|
|
virtual CSquadMonster* MySquadMonsterPointer() { return NULL; }
|
|
|
|
virtual int GetToggleState() { 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() { return 0; }
|
|
|
|
virtual bool IsMoving() { return pev->velocity != g_vecZero; }
|
|
|
|
virtual void OverrideReset() {}
|
|
|
|
virtual int DamageDecal(int bitsDamageType);
|
2013-08-30 13:34:05 -07:00
|
|
|
// This is ONLY used by the node graph to test movement through a door
|
2021-11-28 16:54:48 +01:00
|
|
|
virtual void SetToggleState(int state) {}
|
|
|
|
virtual void StartSneaking() {}
|
|
|
|
virtual void StopSneaking() {}
|
|
|
|
virtual bool OnControls(entvars_t* pev) { return false; }
|
|
|
|
virtual bool IsSneaking() { return false; }
|
|
|
|
virtual bool IsAlive() { return (pev->deadflag == DEAD_NO) && pev->health > 0; }
|
|
|
|
virtual bool IsBSPModel() { return pev->solid == SOLID_BSP || pev->movetype == MOVETYPE_PUSHSTEP; }
|
|
|
|
virtual bool ReflectGauss() { return (IsBSPModel() && !pev->takedamage); }
|
2021-12-03 19:31:04 -05:00
|
|
|
virtual bool HasTarget(string_t targetname) { return FStrEq(STRING(targetname), STRING(pev->target)); }
|
2021-11-28 16:54:48 +01:00
|
|
|
virtual bool IsInWorld();
|
|
|
|
virtual bool IsPlayer() { return false; }
|
|
|
|
virtual bool IsNetClient() { return false; }
|
|
|
|
virtual const char* TeamID() { return ""; }
|
|
|
|
|
|
|
|
|
|
|
|
// virtual void SetActivator( CBaseEntity *pActivator ) {}
|
|
|
|
virtual CBaseEntity* GetNextTarget();
|
|
|
|
|
2013-08-30 13:34:05 -07:00
|
|
|
// fundamental callbacks
|
2021-11-29 20:31:17 +01:00
|
|
|
void (CBaseEntity::*m_pfnThink)();
|
|
|
|
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);
|
2021-11-28 16:54:48 +01:00
|
|
|
|
|
|
|
virtual void Think()
|
|
|
|
{
|
|
|
|
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);
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
void* operator new(size_t stAllocateBlock)
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
2021-11-20 15:54:00 +01:00
|
|
|
//Allocate zero-initialized memory.
|
|
|
|
auto memory = ::operator new(stAllocateBlock);
|
|
|
|
std::memset(memory, 0, stAllocateBlock);
|
|
|
|
return memory;
|
|
|
|
}
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-20 15:54:00 +01:00
|
|
|
//Don't call delete on entities directly, tell the engine to delete it instead.
|
2021-11-28 16:54:48 +01:00
|
|
|
void operator delete(void* pMem)
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
2021-11-20 15:54:00 +01:00
|
|
|
::operator delete(pMem);
|
|
|
|
}
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-03-05 20:54:33 +01:00
|
|
|
void UpdateOnRemove();
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
// common member functions
|
2021-03-05 20:54:33 +01:00
|
|
|
void EXPORT SUB_Remove();
|
|
|
|
void EXPORT SUB_DoNothing();
|
2021-11-28 16:54:48 +01:00
|
|
|
void EXPORT SUB_StartFadeOut();
|
|
|
|
void EXPORT SUB_FadeOut();
|
|
|
|
void EXPORT SUB_CallUseToggle() { this->Use(this, this, USE_TOGGLE, 0); }
|
|
|
|
bool ShouldToggle(USE_TYPE useType, bool currentState);
|
|
|
|
void FireBullets(unsigned int cShots, Vector vecSrc, Vector vecDirShooting, Vector vecSpread, float flDistance, int iBulletType, int iTracerFreq = 4, int iDamage = 0, entvars_t* pevAttacker = NULL);
|
|
|
|
Vector FireBulletsPlayer(unsigned int 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);
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
virtual CBaseEntity* Respawn() { return NULL; }
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
void SUB_UseTargets(CBaseEntity* pActivator, USE_TYPE useType, float value);
|
2013-08-30 13:34:05 -07:00
|
|
|
// Do the bounding boxes of these two intersect?
|
2021-11-28 16:54:48 +01:00
|
|
|
bool Intersects(CBaseEntity* pOther);
|
|
|
|
void MakeDormant();
|
|
|
|
bool IsDormant();
|
|
|
|
bool IsLockedByMaster() { return false; }
|
|
|
|
|
2022-10-07 16:31:04 +02:00
|
|
|
static CBaseEntity* Instance(edict_t* pent);
|
2021-03-05 19:13:40 +01:00
|
|
|
|
2022-10-07 16:31:04 +02:00
|
|
|
static CBaseEntity* Instance(entvars_t* pev);
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
CBaseMonster* GetMonsterPointer(entvars_t* pevMonster)
|
|
|
|
{
|
|
|
|
CBaseEntity* pEntity = Instance(pevMonster);
|
|
|
|
if (pEntity)
|
2013-08-30 13:34:05 -07:00
|
|
|
return pEntity->MyMonsterPointer();
|
|
|
|
return NULL;
|
|
|
|
}
|
2021-11-28 16:54:48 +01:00
|
|
|
CBaseMonster* GetMonsterPointer(edict_t* pentMonster)
|
|
|
|
{
|
|
|
|
CBaseEntity* pEntity = Instance(pentMonster);
|
|
|
|
if (pEntity)
|
2013-08-30 13:34:05 -07:00
|
|
|
return pEntity->MyMonsterPointer();
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Ugly code to lookup all functions to make sure they are exported when set.
|
|
|
|
#ifdef _DEBUG
|
2021-11-28 16:54:48 +01:00
|
|
|
void FunctionCheck(void* pFunction, const char* name)
|
|
|
|
{
|
|
|
|
if (pFunction && !NAME_FOR_FUNCTION((uint32)pFunction))
|
|
|
|
ALERT(at_error, "No EXPORT: %s:%s (%08lx)\n", STRING(pev->classname), name, (uint32)pFunction);
|
2013-08-30 13:34:05 -07:00
|
|
|
}
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
BASEPTR ThinkSet(BASEPTR func, const char* name)
|
|
|
|
{
|
|
|
|
m_pfnThink = func;
|
|
|
|
FunctionCheck((void*)*((int*)((char*)this + (offsetof(CBaseEntity, m_pfnThink)))), name);
|
2013-08-30 13:34:05 -07:00
|
|
|
return func;
|
|
|
|
}
|
2021-11-28 16:54:48 +01:00
|
|
|
ENTITYFUNCPTR TouchSet(ENTITYFUNCPTR func, const char* name)
|
|
|
|
{
|
|
|
|
m_pfnTouch = func;
|
|
|
|
FunctionCheck((void*)*((int*)((char*)this + (offsetof(CBaseEntity, m_pfnTouch)))), name);
|
2013-08-30 13:34:05 -07:00
|
|
|
return func;
|
|
|
|
}
|
2021-11-28 16:54:48 +01:00
|
|
|
USEPTR UseSet(USEPTR func, const char* name)
|
|
|
|
{
|
|
|
|
m_pfnUse = func;
|
|
|
|
FunctionCheck((void*)*((int*)((char*)this + (offsetof(CBaseEntity, m_pfnUse)))), name);
|
2013-08-30 13:34:05 -07:00
|
|
|
return func;
|
|
|
|
}
|
2021-11-28 16:54:48 +01:00
|
|
|
ENTITYFUNCPTR BlockedSet(ENTITYFUNCPTR func, const char* name)
|
|
|
|
{
|
|
|
|
m_pfnBlocked = func;
|
|
|
|
FunctionCheck((void*)*((int*)((char*)this + (offsetof(CBaseEntity, m_pfnBlocked)))), name);
|
2013-08-30 13:34:05 -07:00
|
|
|
return func;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
// virtual functions used by a few classes
|
2021-11-28 16:54:48 +01:00
|
|
|
|
2013-08-30 13:34:05 -07:00
|
|
|
// used by monsters that are created by the MonsterMaker
|
2021-11-28 16:54:48 +01:00
|
|
|
virtual void UpdateOwner() {}
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
|
|
|
|
//
|
2021-11-28 16:54:48 +01:00
|
|
|
static CBaseEntity* Create(const char* szName, const Vector& vecOrigin, const Vector& vecAngles, edict_t* pentOwner = NULL);
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
virtual bool FBecomeProne() { return false; }
|
|
|
|
edict_t* edict() { return ENT(pev); }
|
|
|
|
int entindex() { return ENTINDEX(edict()); }
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
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
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
virtual int Illumination() { return GETENTITYILLUM(ENT(pev)); }
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
virtual bool FVisible(CBaseEntity* pEntity);
|
|
|
|
virtual bool FVisible(const Vector& vecOrigin);
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
//We use this variables to store each ammo count.
|
|
|
|
int ammo_9mm;
|
|
|
|
int ammo_357;
|
|
|
|
int ammo_bolts;
|
|
|
|
int ammo_buckshot;
|
|
|
|
int ammo_rockets;
|
|
|
|
int ammo_uranium;
|
|
|
|
int ammo_hornets;
|
|
|
|
int ammo_argrens;
|
|
|
|
//Special stuff for grenades and satchels.
|
|
|
|
float m_flStartThrow;
|
|
|
|
float m_flReleaseThrow;
|
|
|
|
int m_chargeReady;
|
|
|
|
int m_fInAttack;
|
|
|
|
|
|
|
|
int m_fireState;
|
|
|
|
};
|
|
|
|
|
2021-03-16 21:41:30 +01:00
|
|
|
inline bool FNullEnt(CBaseEntity* ent) { return (ent == NULL) || FNullEnt(ent->edict()); }
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
|
|
|
|
// Ugly technique to override base member functions
|
2021-11-28 16:54:48 +01:00
|
|
|
// Normally it's illegal to cast a pointer to a member function of a derived class to a pointer to a
|
2013-08-30 13:34:05 -07:00
|
|
|
// member function of a base class. static_cast is a sleezy way around that problem.
|
|
|
|
|
|
|
|
#ifdef _DEBUG
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
#define SetThink(a) ThinkSet(static_cast<void (CBaseEntity::*)()>(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)
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
#else
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
#define SetThink(a) m_pfnThink = static_cast<void (CBaseEntity::*)()>(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)
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
class CPointEntity : public CBaseEntity
|
|
|
|
{
|
|
|
|
public:
|
2021-11-28 16:54:48 +01:00
|
|
|
void Spawn() override;
|
2021-11-29 20:31:17 +01:00
|
|
|
int ObjectCaps() override { return CBaseEntity::ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
|
2021-11-28 16:54:48 +01:00
|
|
|
|
2013-08-30 13:34:05 -07:00
|
|
|
private:
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
typedef struct locksounds // sounds that doors and buttons make when locked/unlocked
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
2021-11-28 16:54:48 +01:00
|
|
|
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
|
2013-08-30 13:34:05 -07:00
|
|
|
} locksound_t;
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
void PlayLockSounds(entvars_t* pev, locksound_t* pls, bool flocked, bool fbutton);
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
//
|
|
|
|
// MultiSouce
|
|
|
|
//
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
#define MAX_MULTI_TARGETS 16 // maximum number of targets a single multi_manager entity may be assigned.
|
2013-08-30 13:34:05 -07:00
|
|
|
#define MS_MAX_TARGETS 32
|
|
|
|
|
|
|
|
class CMultiSource : public CPointEntity
|
|
|
|
{
|
|
|
|
public:
|
2021-11-28 16:54:48 +01:00
|
|
|
void Spawn() override;
|
|
|
|
bool KeyValue(KeyValueData* pkvd) override;
|
|
|
|
void Use(CBaseEntity* pActivator, CBaseEntity* pCaller, USE_TYPE useType, float value) override;
|
|
|
|
int ObjectCaps() override { return (CPointEntity::ObjectCaps() | FCAP_MASTER); }
|
|
|
|
bool IsTriggered(CBaseEntity* pActivator) override;
|
2021-03-05 20:54:33 +01:00
|
|
|
void EXPORT Register();
|
2021-11-28 16:54:48 +01:00
|
|
|
bool Save(CSave& save) override;
|
|
|
|
bool Restore(CRestore& restore) override;
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
static TYPEDESCRIPTION m_SaveData[];
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
EHANDLE m_rgEntities[MS_MAX_TARGETS];
|
|
|
|
int m_rgTriggered[MS_MAX_TARGETS];
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
int m_iTotal;
|
|
|
|
string_t m_globalstate;
|
2013-08-30 13:34:05 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// generic Delay entity.
|
|
|
|
//
|
|
|
|
class CBaseDelay : public CBaseEntity
|
|
|
|
{
|
|
|
|
public:
|
2021-11-28 16:54:48 +01:00
|
|
|
float m_flDelay;
|
|
|
|
int m_iszKillTarget;
|
|
|
|
|
|
|
|
bool KeyValue(KeyValueData* pkvd) override;
|
|
|
|
bool Save(CSave& save) override;
|
|
|
|
bool Restore(CRestore& restore) override;
|
|
|
|
|
|
|
|
static TYPEDESCRIPTION m_SaveData[];
|
2013-08-30 13:34:05 -07:00
|
|
|
// common member functions
|
2021-11-28 16:54:48 +01:00
|
|
|
void SUB_UseTargets(CBaseEntity* pActivator, USE_TYPE useType, float value);
|
2021-03-05 20:54:33 +01:00
|
|
|
void EXPORT DelayThink();
|
2013-08-30 13:34:05 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class CBaseAnimating : public CBaseDelay
|
|
|
|
{
|
|
|
|
public:
|
2021-11-28 16:54:48 +01:00
|
|
|
bool Save(CSave& save) override;
|
|
|
|
bool Restore(CRestore& restore) override;
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
static TYPEDESCRIPTION m_SaveData[];
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
// Basic Monster Animation functions
|
2021-11-28 16:54:48 +01:00
|
|
|
float StudioFrameAdvance(float flInterval = 0.0); // accumulate animation frame time from last time called until now
|
|
|
|
int GetSequenceFlags();
|
|
|
|
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) {}
|
|
|
|
float SetBoneController(int iController, float flValue);
|
|
|
|
void InitBoneControllers();
|
|
|
|
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);
|
|
|
|
bool ExtractBbox(int sequence, float* mins, float* maxs);
|
2021-03-05 20:54:33 +01:00
|
|
|
void SetSequenceBox();
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
// animation needs
|
2021-11-28 16:54:48 +01:00
|
|
|
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
|
2013-08-30 13:34:05 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// generic Toggle entity.
|
|
|
|
//
|
2021-11-28 16:54:48 +01:00
|
|
|
#define SF_ITEM_USE_ONLY 256 // ITEM_USE_ONLY = BUTTON_USE_ONLY = DOOR_USE_ONLY!!!
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
class CBaseToggle : public CBaseAnimating
|
|
|
|
{
|
|
|
|
public:
|
2021-11-28 16:54:48 +01:00
|
|
|
bool KeyValue(KeyValueData* pkvd) override;
|
|
|
|
|
|
|
|
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;
|
|
|
|
EHANDLE m_hActivator;
|
2021-03-05 20:54:33 +01:00
|
|
|
void (CBaseToggle::*m_pfnCallWhenMoveDone)();
|
2021-11-28 16:54:48 +01:00
|
|
|
Vector m_vecFinalDest;
|
|
|
|
Vector m_vecFinalAngle;
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
int m_bitsDamageInflict; // DMG_ damage type that the door or tigger does
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
bool Save(CSave& save) override;
|
|
|
|
bool Restore(CRestore& restore) override;
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
static TYPEDESCRIPTION m_SaveData[];
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
int GetToggleState() override { return m_toggle_state; }
|
|
|
|
float GetDelay() override { return m_flWait; }
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
// common member functions
|
2021-11-28 16:54:48 +01:00
|
|
|
void LinearMove(Vector vecDest, float flSpeed);
|
2021-03-05 20:54:33 +01:00
|
|
|
void EXPORT LinearMoveDone();
|
2021-11-28 16:54:48 +01:00
|
|
|
void AngularMove(Vector vecDestAngle, float flSpeed);
|
2021-03-05 20:54:33 +01:00
|
|
|
void EXPORT AngularMoveDone();
|
2021-11-19 14:31:11 +01:00
|
|
|
bool IsLockedByMaster();
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2024-08-28 16:59:46 +02:00
|
|
|
virtual CBaseToggle* MyTogglePointer() { return this; }
|
|
|
|
|
|
|
|
// monsters use this, but so could buttons for instance
|
|
|
|
virtual void PlaySentence(const char* pszSentence, float duration, float volume, float attenuation);
|
|
|
|
virtual void PlayScriptedSentence(const char* pszSentence, float duration, float volume, float attenuation, bool bConcurrent, CBaseEntity* pListener);
|
|
|
|
virtual void SentenceStop();
|
|
|
|
virtual bool IsAllowedToSpeak() { return false; }
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
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);
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
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.
|
2024-08-28 16:59:46 +02:00
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual void PlaySentenceCore(const char* pszSentence, float duration, float volume, float attenuation);
|
2013-08-30 13:34:05 -07:00
|
|
|
};
|
2021-11-28 16:54:48 +01:00
|
|
|
#define SetMoveDone(a) m_pfnCallWhenMoveDone = static_cast<void (CBaseToggle::*)()>(a)
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
|
|
|
|
// people gib if their health is <= this at the time of death
|
2021-11-28 16:54:48 +01:00
|
|
|
#define GIB_HEALTH_VALUE -30
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
#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
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
#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
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
#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
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
#define bits_CAP_FLY (1 << 15) // can fly, move all around
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
#define bits_CAP_DOORS_GROUP (bits_CAP_USE | bits_CAP_AUTO_DOORS | bits_CAP_OPEN_DOORS)
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
// when calling KILLED(), a value that governs gib behavior is expected to be
|
2013-08-30 13:34:05 -07:00
|
|
|
// one of these three values
|
2021-11-28 16:54:48 +01:00
|
|
|
#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 )
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
class CBaseMonster;
|
|
|
|
class CCineMonster;
|
|
|
|
class CSound;
|
|
|
|
|
|
|
|
#include "basemonster.h"
|
|
|
|
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
const char* ButtonSound(int sound); // get string of button sound number
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// Generic Button
|
|
|
|
//
|
|
|
|
class CBaseButton : public CBaseToggle
|
|
|
|
{
|
|
|
|
public:
|
2021-03-05 23:07:22 +01:00
|
|
|
void Spawn() override;
|
|
|
|
void Precache() override;
|
2021-03-05 20:54:33 +01:00
|
|
|
void RotSpawn();
|
2021-11-28 16:54:48 +01:00
|
|
|
bool KeyValue(KeyValueData* pkvd) override;
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
void ButtonActivate();
|
2021-03-05 20:54:33 +01:00
|
|
|
void SparkSoundCache();
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-03-05 20:54:33 +01:00
|
|
|
void EXPORT ButtonShot();
|
2021-11-28 16:54:48 +01:00
|
|
|
void EXPORT ButtonTouch(CBaseEntity* pOther);
|
|
|
|
void EXPORT ButtonSpark();
|
2021-03-05 20:54:33 +01:00
|
|
|
void EXPORT TriggerAndWait();
|
|
|
|
void EXPORT ButtonReturn();
|
|
|
|
void EXPORT ButtonBackHome();
|
2021-11-28 16:54:48 +01:00
|
|
|
void EXPORT ButtonUse(CBaseEntity* pActivator, CBaseEntity* pCaller, USE_TYPE useType, float value);
|
|
|
|
bool TakeDamage(entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType) override;
|
|
|
|
bool Save(CSave& save) override;
|
|
|
|
bool Restore(CRestore& restore) override;
|
|
|
|
|
|
|
|
enum BUTTON_CODE
|
|
|
|
{
|
|
|
|
BUTTON_NOTHING,
|
|
|
|
BUTTON_ACTIVATE,
|
|
|
|
BUTTON_RETURN
|
|
|
|
};
|
|
|
|
BUTTON_CODE ButtonResponseToTouch();
|
|
|
|
|
|
|
|
static TYPEDESCRIPTION m_SaveData[];
|
2013-08-30 13:34:05 -07:00
|
|
|
// Buttons that don't take damage can be IMPULSE used
|
2021-11-28 16:54:48 +01:00
|
|
|
int ObjectCaps() override { return (CBaseToggle::ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | (pev->takedamage ? 0 : FCAP_IMPULSE_USE); }
|
2024-08-28 16:59:46 +02:00
|
|
|
virtual bool IsAllowedToSpeak() { return true; }
|
2021-11-28 16:54:48 +01:00
|
|
|
|
|
|
|
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;
|
2013-08-30 13:34:05 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
//
|
2021-11-28 16:54:48 +01:00
|
|
|
// Weapons
|
2013-08-30 13:34:05 -07:00
|
|
|
//
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
#define BAD_WEAPON 0x00007FFF
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
//
|
|
|
|
// Converts a entvars_t * to a class pointer
|
|
|
|
// It will allocate the class and entity if necessary
|
|
|
|
//
|
2021-11-28 16:54:48 +01:00
|
|
|
template <class T>
|
|
|
|
T* GetClassPtr(T* a)
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
2021-11-28 16:54:48 +01:00
|
|
|
entvars_t* pev = (entvars_t*)a;
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
// allocate entity if necessary
|
|
|
|
if (pev == NULL)
|
|
|
|
pev = VARS(CREATE_ENTITY());
|
|
|
|
|
|
|
|
// get the private data
|
2021-11-28 16:54:48 +01:00
|
|
|
a = (T*)GET_PRIVATE(ENT(pev));
|
2013-08-30 13:34:05 -07:00
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
if (a == NULL)
|
2013-08-30 13:34:05 -07:00
|
|
|
{
|
2021-11-28 16:54:48 +01:00
|
|
|
// allocate private data
|
2021-11-20 15:54:00 +01:00
|
|
|
a = new T;
|
|
|
|
|
|
|
|
//Replicate the ALLOC_PRIVATE engine function's behavior.
|
|
|
|
pev->pContainingEntity->pvPrivateData = a;
|
|
|
|
|
2013-08-30 13:34:05 -07:00
|
|
|
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
|
|
|
|
*/
|
|
|
|
|
2021-11-28 16:54:48 +01:00
|
|
|
#define TRACER_FREQ 4 // Tracers fire every 4 bullets
|
2013-08-30 13:34:05 -07:00
|
|
|
|
|
|
|
// 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:
|
2022-10-07 16:31:04 +02:00
|
|
|
CWorld();
|
|
|
|
~CWorld();
|
|
|
|
|
2021-03-05 23:07:22 +01:00
|
|
|
void Spawn() override;
|
|
|
|
void Precache() override;
|
2021-11-28 16:54:48 +01:00
|
|
|
bool KeyValue(KeyValueData* pkvd) override;
|
2022-10-07 16:31:04 +02:00
|
|
|
|
2023-02-02 13:17:24 +01:00
|
|
|
static inline CWorld* World = nullptr;
|
2013-08-30 13:34:05 -07:00
|
|
|
};
|
2021-11-28 20:40:56 +01:00
|
|
|
|
2022-10-07 16:31:04 +02:00
|
|
|
inline DLL_GLOBAL edict_t* g_pBodyQueueHead = nullptr;
|
|
|
|
|
|
|
|
inline CBaseEntity* CBaseEntity::Instance(edict_t* pent)
|
|
|
|
{
|
|
|
|
if (!pent)
|
2023-02-02 13:17:24 +01:00
|
|
|
return CWorld::World;
|
2022-10-07 16:31:04 +02:00
|
|
|
return (CBaseEntity*)GET_PRIVATE(pent);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline CBaseEntity* CBaseEntity::Instance(entvars_t* pev)
|
|
|
|
{
|
|
|
|
if (!pev)
|
2023-02-02 13:17:24 +01:00
|
|
|
return CWorld::World;
|
2022-10-07 16:31:04 +02:00
|
|
|
|
|
|
|
return Instance(ENT(pev));
|
|
|
|
}
|