Map out entity structures more

More types and improvements for base entity classes.
This commit is contained in:
Kawe Mazidjatari 2023-08-27 00:20:23 +02:00
parent 8b45e1a4e5
commit ea2c71242e
10 changed files with 590 additions and 12 deletions

View File

@ -55,9 +55,13 @@ add_sources( SOURCE_GROUP "Server"
"server/basecombatcharacter.h"
"server/baseentity.cpp"
"server/baseentity.h"
"server/cbase.cpp"
"server/cbase.h"
"server/detour_impl.h"
"server/entitylist.cpp"
"server/entitylist.h"
"server/entityoutput.cpp"
"server/entityoutput.h"
"server/gameinterface.cpp"
"server/gameinterface.h"
"server/movehelper_server.cpp"
@ -71,6 +75,8 @@ add_sources( SOURCE_GROUP "Server"
"server/playerlocaldata.h"
"server/util_server.cpp"
"server/util_server.h"
"server/variant_t.cpp"
"server/variant_t.h"
"server/vscript_server.cpp"
"server/vscript_server.h"
)

View File

@ -14,7 +14,7 @@
class CBaseAnimatingOverlay : public CBaseAnimating
{
char gap_11E4[8];
char gap_11E4[8]; // Redundant???
int m_maxOverlays;
char gap_11f4[4];
CAnimationLayer m_AnimOverlay;

View File

@ -17,9 +17,28 @@
#include "public/iserverentity.h"
#include "engine/gl_model_private.h"
#include "game/shared/collisionproperty.h"
#include "game/shared/shareddefs.h"
#include "networkproperty.h"
#include "entitylist.h"
#include "entityoutput.h"
//-----------------------------------------------------------------------------
typedef void (CBaseEntity::* BASEPTR)(void);
typedef void (CBaseEntity::* ENTITYFUNCPTR)(CBaseEntity* pOther);
typedef void (CBaseEntity::* USEPTR)(CBaseEntity* pActivator, CBaseEntity* pCaller, USE_TYPE useType, float value);
//-----------------------------------------------------------------------------
// Purpose: think contexts
//-----------------------------------------------------------------------------
struct thinkfunc_t
{
BASEPTR m_pfnThink;
bool m_fireBeforeBaseThink;
string_t m_iszContext;
int m_nNextThinkTick;
int m_nLastThinkTick;
};
class CBaseEntity : public IServerEntity
{
@ -35,10 +54,10 @@ public:
string_t GetModelName(void) const; // Virtual in-engine!
inline edict_t GetEdict(void) { return NetworkProp()->GetEdict(); }
inline string_t GetName(void) const { return m_iName; }
inline string_t GetEntityName(void) const { return m_iName; }
protected:
char m_RefEHandle[4];
CBaseHandle m_RefEHandle;
char gap_c[4];
void* m_collideable;
void* m_networkable;
@ -51,14 +70,14 @@ protected:
string_t m_ModelName;
int m_entIndex;
char gap_74[8]; // Aligns properly in IDA and generated code after setting from 4 to 8.
const char* m_iClassname;
string_t* m_iClassname;
float m_flAnimTime;
float m_flSimulationTime;
int m_creationTick;
int m_nLastThinkTick;
int m_PredictableID;
int touchStamp;
char m_aThinkFunctions[32];
CUtlVector<thinkfunc_t> m_aThinkFunctions;
float m_entitySpawnTime;
int m_spawner;
bool m_wantsDamageCallbacks;
@ -68,7 +87,7 @@ protected:
int m_fEffects;
bool m_thinkNextFrame;
char gap_cd[3];
__int64 m_target;
string_t m_target;
int m_networkedFlags;
char m_nRenderFX;
char m_nRenderMode;
@ -159,7 +178,7 @@ protected:
Vector3D m_angAbsRotation;
Vector3D m_vecVelocity;
char gap_474[4];
__int64 m_iParent;
string_t m_iParent;
int m_iHammerID;
float m_flSpeed;
int m_iMaxHealth;
@ -179,9 +198,9 @@ protected:
float m_lastTitanFootstepDamageTime;
float m_flMaxspeed;
int m_visibilityFlags;
char m_OnUser1[40];
char m_OnDeath[40];
char m_OnDestroy[40];
COutputEvent m_OnUser1;
COutputEvent m_OnDeath;
COutputEvent m_OnDestroy;
int m_cellWidth;
int m_cellBits;
int m_cellX;
@ -208,7 +227,7 @@ protected:
float m_entityFadeDist;
int m_dissolveEffectEntityHandle;
float m_fadeDist;
__int64 m_iSignifierName;
string_t m_iSignifierName;
int m_collectedInvalidateFlags;
bool m_collectingInvalidateFlags;
char gap_5d5[3];
@ -222,7 +241,7 @@ protected:
void* m_pTimedOverlay;
char m_ScriptScope[32];
char m_hScriptInstance[8];
__int64 m_iszScriptId;
string_t m_iszScriptId;
int m_bossPlayer;
int m_usableType;
int m_usablePriority;

View File

@ -0,0 +1,6 @@
//=============================================================================//
//
// Purpose:
//
//=============================================================================//
#include "cbase.h"

View File

@ -0,0 +1,5 @@
#ifndef CBASE_H
#define CBASE_H
#endif // CBASE_H

View File

@ -0,0 +1,6 @@
//=============================================================================//
//
// Purpose:
//
//=============================================================================//
#include "entityoutput.h"

View File

@ -0,0 +1,70 @@
#ifndef ENTITYOUTPUT_H
#define ENTITYOUTPUT_H
#include "variant_t.h"
#define EVENT_FIRE_ALWAYS -1
class CBaseEntity;
//-----------------------------------------------------------------------------
// Purpose: A COutputEvent consists of an array of these CEventActions.
// Each CEventAction holds the information to fire a single input in
// a target entity, after a specific delay.
//-----------------------------------------------------------------------------
class CEventAction
{
public:
int m_type;
char gap_4[4];
string_t m_iTarget; // name of the entity(s) to cause the action in
string_t m_iTargetInput; // the name of the action to fire
string_t m_iParameter; // parameter to send, 0 if none
int m_scriptEnt;
char gap_24[4];
char m_scriptFunc[16];
float m_flDelay; // the number of seconds to wait before firing the action
int m_nTimesToFire; // The number of times to fire this event, or EVENT_FIRE_ALWAYS.
int m_iIDStamp; // unique identifier stamp
//static int s_iNextIDStamp; !TODO[ AMOS ]: If found, make this a ptr and link it to the one in the game engine!
CEventAction* m_pNext;
};
//-----------------------------------------------------------------------------
// Purpose: Stores a list of connections to other entities, for data/commands to be
// communicated along.
//-----------------------------------------------------------------------------
class CBaseEntityOutput
{
public:
virtual ~CBaseEntityOutput() {};
virtual int Save(/*ISave*/ __int64 /*save*/) {return 1; /*!!! IMPLEMENTATION IN ENGINE !!!*/}
virtual int Restore(/*IRestore*/ __int64 /*restore*/, int /*elementCount*/) { return 1; /*!!! IMPLEMENTATION IN ENGINE !!!*/ }
protected:
variant_t m_Value;
CEventAction* m_ActionList;
//DECLARE_SIMPLE_DATADESC();
CBaseEntityOutput() {} // this class cannot be created, only it's children
private:
CBaseEntityOutput(CBaseEntityOutput&); // protect from accidental copying
};
//-----------------------------------------------------------------------------
// Purpose: parameterless entity event
//-----------------------------------------------------------------------------
class COutputEvent : public CBaseEntityOutput
{
public:
};
#endif // ENTITYOUTPUT_H

View File

@ -0,0 +1,332 @@
////////////////////////// variant_t implementation //////////////////////////
#include "entityoutput.h"
#include "baseentity.h"
//-----------------------------------------------------------------------------
// Purpose: All types must be able to display as strings for debugging purposes.
// Output : Returns a pointer to the string that represents this value.
//
// NOTE: The returned pointer should not be stored by the caller as
// subsequent calls to this function will overwrite the contents
// of the buffer!
//-----------------------------------------------------------------------------
const char* variant_t::ToString(void) const
{
static char szBuf[512];
switch (fieldType)
{
case FIELD_STRING:
{
return(STRING(iszVal));
}
case FIELD_BOOLEAN:
{
if (bVal == 0)
{
Q_strncpy(szBuf, "false", sizeof(szBuf));
}
else
{
Q_strncpy(szBuf, "true", sizeof(szBuf));
}
return(szBuf);
}
case FIELD_INTEGER:
{
Q_snprintf(szBuf, sizeof(szBuf), "%i", iVal);
return(szBuf);
}
case FIELD_FLOAT:
{
Q_snprintf(szBuf, sizeof(szBuf), "%g", flVal);
return(szBuf);
}
case FIELD_COLOR32:
{
Q_snprintf(szBuf, sizeof(szBuf), "%d %d %d %d", (int)rgbaVal.r, (int)rgbaVal.g, (int)rgbaVal.b, (int)rgbaVal.a);
return(szBuf);
}
case FIELD_VECTOR:
{
Q_snprintf(szBuf, sizeof(szBuf), "[%g %g %g]", (double)vecVal[0], (double)vecVal[1], (double)vecVal[2]);
return(szBuf);
}
case FIELD_VOID:
{
szBuf[0] = '\0';
return(szBuf);
}
case FIELD_EHANDLE:
{
const char* pszName = (Entity()) ? STRING(Entity()->GetEntityName()) : "<<null entity>>";
Q_strncpy(szBuf, pszName, 512);
return (szBuf);
}
}
return("No conversion to string");
}
//-----------------------------------------------------------------------------
// Purpose: sets the entity
//-----------------------------------------------------------------------------
void variant_t::SetEntity(CBaseEntity* val)
{
eVal = val;
fieldType = FIELD_EHANDLE;
}
// BUGBUG: Add support for function pointer save/restore to variants
// BUGBUG: Must pass datamap_t to read/write fields
//void variant_t::Set(fieldtype_t ftype, void* data)
//{
// fieldType = ftype;
//
// switch (ftype)
// {
// case FIELD_BOOLEAN: bVal = *((bool*)data); break;
// case FIELD_CHARACTER: iVal = *((char*)data); break;
// case FIELD_SHORT: iVal = *((short*)data); break;
// case FIELD_INTEGER: iVal = *((int*)data); break;
// case FIELD_STRING: iszVal = *((string_t*)data); break;
// case FIELD_FLOAT: flVal = *((float*)data); break;
// case FIELD_COLOR32: rgbaVal = *((color32*)data); break;
//
// case FIELD_VECTOR:
// case FIELD_POSITION_VECTOR:
// {
// vecVal[0] = ((float*)data)[0];
// vecVal[1] = ((float*)data)[1];
// vecVal[2] = ((float*)data)[2];
// break;
// }
//
// case FIELD_EHANDLE: eVal = *((EHANDLE*)data); break;
// case FIELD_CLASSPTR: eVal = *((CBaseEntity**)data); break;
// case FIELD_VOID:
// default:
// iVal = 0; fieldType = FIELD_VOID;
// break;
// }
//}
//-----------------------------------------------------------------------------
// Purpose: Copies the value in the variant into a block of memory
// Input : *data - the block to write into
//-----------------------------------------------------------------------------
void variant_t::SetOther(void* data)
{
switch (fieldType)
{
case FIELD_BOOLEAN: *((bool*)data) = bVal != 0; break;
case FIELD_CHARACTER: *((char*)data) = (char)iVal; break;
case FIELD_SHORT: *((short*)data) = (short)iVal; break;
case FIELD_INTEGER: *((int*)data) = iVal; break;
case FIELD_STRING: *((string_t*)data) = iszVal; break;
case FIELD_FLOAT: *((float*)data) = flVal; break;
case FIELD_COLOR32: *((color32*)data) = rgbaVal; break;
case FIELD_VECTOR:
case FIELD_POSITION_VECTOR:
{
((float*)data)[0] = vecVal[0];
((float*)data)[1] = vecVal[1];
((float*)data)[2] = vecVal[2];
break;
}
case FIELD_EHANDLE: *((EHANDLE*)data) = eVal; break;
case FIELD_CLASSPTR: *((CBaseEntity**)data) = eVal; break;
}
}
//-----------------------------------------------------------------------------
// Purpose: Converts the variant to a new type. This function defines which I/O
// types can be automatically converted between. Connections that require
// an unsupported conversion will cause an error message at runtime.
// Input : newType - the type to convert to
// Output : Returns true on success, false if the conversion is not legal
//-----------------------------------------------------------------------------
//bool variant_t::Convert(fieldtype_t newType)
//{
// if (newType == fieldType)
// {
// return true;
// }
//
// //
// // Converting to a null value is easy.
// //
// if (newType == FIELD_VOID)
// {
// Set(FIELD_VOID, NULL);
// return true;
// }
//
// //
// // FIELD_INPUT accepts the variant type directly.
// //
// if (newType == FIELD_INPUT)
// {
// return true;
// }
//
// switch (fieldType)
// {
// case FIELD_INTEGER:
// {
// switch (newType)
// {
// case FIELD_FLOAT:
// {
// SetFloat((float)iVal);
// return true;
// }
//
// case FIELD_BOOLEAN:
// {
// SetBool(iVal != 0);
// return true;
// }
// }
// break;
// }
//
// case FIELD_FLOAT:
// {
// switch (newType)
// {
// case FIELD_INTEGER:
// {
// SetInt((int)flVal);
// return true;
// }
//
// case FIELD_BOOLEAN:
// {
// SetBool(flVal != 0);
// return true;
// }
// }
// break;
// }
//
// //
// // Everyone must convert from FIELD_STRING if possible, since
// // parameter overrides are always passed as strings.
// //
// case FIELD_STRING:
// {
// switch (newType)
// {
// case FIELD_INTEGER:
// {
// if (iszVal != NULL_STRING)
// {
// SetInt(atoi(STRING(iszVal)));
// }
// else
// {
// SetInt(0);
// }
// return true;
// }
//
// case FIELD_FLOAT:
// {
// if (iszVal != NULL_STRING)
// {
// SetFloat(atof(STRING(iszVal)));
// }
// else
// {
// SetFloat(0);
// }
// return true;
// }
//
// case FIELD_BOOLEAN:
// {
// if (iszVal != NULL_STRING)
// {
// SetBool(atoi(STRING(iszVal)) != 0);
// }
// else
// {
// SetBool(false);
// }
// return true;
// }
//
// case FIELD_VECTOR:
// {
// ::Vector3D tmpVec = vec3_origin;
// if (sscanf(STRING(iszVal), "[%f %f %f]", &tmpVec[0], &tmpVec[1], &tmpVec[2]) == 0)
// {
// // Try sucking out 3 floats with no []s
// sscanf(STRING(iszVal), "%f %f %f", &tmpVec[0], &tmpVec[1], &tmpVec[2]);
// }
// SetVector3D(tmpVec);
// return true;
// }
//
// case FIELD_COLOR32:
// {
// int nRed = 0;
// int nGreen = 0;
// int nBlue = 0;
// int nAlpha = 255;
//
// sscanf(STRING(iszVal), "%d %d %d %d", &nRed, &nGreen, &nBlue, &nAlpha);
// SetColor32(nRed, nGreen, nBlue, nAlpha);
// return true;
// }
//
// case FIELD_EHANDLE:
// {
// // convert the string to an entity by locating it by classname
// CBaseEntity* ent = NULL;
// if (iszVal != NULL_STRING)
// {
// // FIXME: do we need to pass an activator in here?
// ent = gEntList.FindEntityByName(NULL, iszVal);
// }
// SetEntity(ent);
// return true;
// }
// }
//
// break;
// }
//
// case FIELD_EHANDLE:
// {
// switch (newType)
// {
// case FIELD_STRING:
// {
// // take the entities targetname as the string
// string_t iszStr = NULL_STRING;
// if (eVal != NULL)
// {
// SetString(eVal->GetEntityName());
// }
// return true;
// }
// }
// break;
// }
// }
//
// // invalid conversion
// return false;
//}

View File

@ -0,0 +1,127 @@
//====== Copyright <20> 1996-2005, Valve Corporation, All rights reserved. =======//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef VARIANT_T_H
#define VARIANT_T_H
#ifdef _WIN32
#pragma once
#endif
#include "tier1/string_t.h"
#include "mathlib/vmatrix.h"
#include "mathlib/color.h"
#include "game/shared/ehandle.h"
#include "datamap.h"
// Microsoft headers define these for '_variant_t'
// undefine them to prevent clashes with our struct.
#if defined variant_t
#undef variant_t
#endif variant_t
class CBaseEntity;
//-----------------------------------------------------------------------------
// A variant class for passing data in entity input/output connections.
//-----------------------------------------------------------------------------
class variant_t
{
public:
// constructor
variant_t() : fieldType(FIELD_VOID), iVal(0) {}
inline bool Bool( void ) const { return( fieldType == FIELD_BOOLEAN ) ? bVal : false; }
inline const char *String( void ) const { return( fieldType == FIELD_STRING ) ? STRING(iszVal) : ToString(); }
inline string_t StringID( void ) const { return( fieldType == FIELD_STRING ) ? iszVal : NULL_STRING; }
inline int Int( void ) const { return( fieldType == FIELD_INTEGER ) ? iVal : 0; }
inline float Float( void ) const { return( fieldType == FIELD_FLOAT ) ? flVal : 0; }
inline const CHandle<CBaseEntity> &Entity( void ) const;
inline color32 Color32( void ) const { return rgbaVal; }
inline void Vector3D( ::Vector3D &vec ) const;
fieldtype_t FieldType( void ) { return fieldType; }
void SetBool( bool b ) { bVal = b; fieldType = FIELD_BOOLEAN; }
void SetString( string_t str ) { iszVal = str, fieldType = FIELD_STRING; }
void SetInt( int val ) { iVal = val, fieldType = FIELD_INTEGER; }
void SetFloat( float val ) { flVal = val, fieldType = FIELD_FLOAT; }
void SetEntity( CBaseEntity *val );
void SetVector3D( const ::Vector3D &val ) { vecVal[0] = val[ 0 ]; vecVal[ 1 ] = val[ 1 ]; vecVal[ 2 ] = val[ 2 ]; fieldType = FIELD_VECTOR; }
void SetPositionVector3D( const ::Vector3D &val ) { vecVal[ 0 ] = val[ 0 ]; vecVal[ 1 ] = val[ 1 ]; vecVal[ 2 ] = val[ 2 ]; fieldType = FIELD_POSITION_VECTOR; }
void SetColor32( color32 val ) { rgbaVal = val; fieldType = FIELD_COLOR32; }
void SetColor32( int r, int g, int b, int a ) { rgbaVal.r = (byte)r; rgbaVal.g = (byte)g; rgbaVal.b = (byte)b; rgbaVal.a = (byte)a; fieldType = FIELD_COLOR32; }
void Set( fieldtype_t ftype, void *data );
void SetOther( void *data );
bool Convert( fieldtype_t newType );
// !TODO[AMOS]: If found, make this a ptrand link it to the one in the game engine!
//static typedescription_t m_SaveBool[];
//static typedescription_t m_SaveInt[];
//static typedescription_t m_SaveFloat[];
//static typedescription_t m_SaveEHandle[];
//static typedescription_t m_SaveString[];
//static typedescription_t m_SaveColor[];
//static typedescription_t m_SaveVector[];
//static typedescription_t m_SavePositionVector[];
//static typedescription_t m_SaveVMatrix[];
//static typedescription_t m_SaveVMatrixWorldspace[];
//static typedescription_t m_SaveMatrix3x4Worldspace[];
protected:
//-------------------------------------------------------------------------
// Returns a string representation of the value without modifying the variant.
//-------------------------------------------------------------------------
const char *ToString( void ) const;
friend class CVariantSaveDataOps;
private:
union
{
bool bVal;
string_t iszVal;
int iVal;
float flVal;
float vecVal[3];
color32 rgbaVal;
};
CHandle<CBaseEntity> eVal; // this can't be in the union because it has a constructor.
fieldtype_t fieldType;
};
//-----------------------------------------------------------------------------
// Purpose: Returns this variant as a vector.
//-----------------------------------------------------------------------------
inline void variant_t::Vector3D( ::Vector3D &vec ) const
{
if (( fieldType == FIELD_VECTOR ) || ( fieldType == FIELD_POSITION_VECTOR ))
{
vec[ 0 ] = vecVal[ 0 ];
vec[ 1 ] = vecVal[ 1 ];
vec[ 2 ] = vecVal[ 2 ];
}
else
{
vec = vec3_origin;
}
}
//-----------------------------------------------------------------------------
// Purpose: Returns this variant as an EHANDLE.
//-----------------------------------------------------------------------------
inline const CHandle<CBaseEntity> &variant_t::Entity( void ) const
{
if ( fieldType == FIELD_EHANDLE )
return eVal;
static const CHandle<CBaseEntity> hNull( INVALID_EHANDLE );
return( hNull );
}
#endif // VARIANT_T_H

View File

@ -39,5 +39,12 @@
#define HITGROUP_GEAR 8 // alerts NPC, but doesn't do damage or bleed (1/100th damage)
#define HITGROUP_COUNT 9
typedef enum // !TODO[ AMOS ]: Confirm this!
{
USE_OFF = 0,
USE_ON = 1,
USE_SET = 2,
USE_TOGGLE = 3
} USE_TYPE;
#endif // SHAREDDEFS_H