590 lines
21 KiB
C++
590 lines
21 KiB
C++
|
|
/*
|
|
*
|
|
* Sexy boiler plate
|
|
*
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "../public/tier1/utlstring.h"
|
|
#include "../public/tier1/utlvector.h"
|
|
|
|
#define FCVAR_NONE 0
|
|
|
|
// Command to ConVars and ConCommands
|
|
// ConVar Systems
|
|
#define FCVAR_UNREGISTERED \
|
|
(1 << 0) // If this is set, don't add to linked list, etc.
|
|
#define FCVAR_DEVELOPMENTONLY \
|
|
(1 << 1) // Hidden in released products. Flag is removed automatically if
|
|
// ALLOW_DEVELOPMENT_CVARS is defined.
|
|
#define FCVAR_GAMEDLL (1 << 2) // defined by the game DLL
|
|
#define FCVAR_CLIENTDLL (1 << 3) // defined by the client DLL
|
|
#define FCVAR_HIDDEN \
|
|
(1 << 4) // Hidden. Doesn't appear in find or autocomplete. Like
|
|
// DEVELOPMENTONLY, but can't be compiled out.
|
|
// ConVar only
|
|
#define FCVAR_PROTECTED \
|
|
(1 << 5) // It's a server cvar, but we don't send the data since it's a
|
|
// password, etc. Sends 1 if it's not bland/zero, 0 otherwise as
|
|
// value
|
|
#define FCVAR_SPONLY \
|
|
(1 << 6) // This cvar cannot be changed by clients connected to a
|
|
// multiplayer server.
|
|
#define FCVAR_ARCHIVE (1 << 7) // set to cause it to be saved to vars.rc
|
|
#define FCVAR_NOTIFY (1 << 8) // notifies players when changed
|
|
#define FCVAR_USERINFO (1 << 9) // changes the client's info string
|
|
#define FCVAR_CHEAT \
|
|
(1 << 14) // Only useable in singleplayer / debug / multiplayer & sv_cheats
|
|
#define FCVAR_PRINTABLEONLY \
|
|
(1 << 10) // This cvar's string cannot contain unprintable characters (
|
|
// e.g., used for player name etc ).
|
|
#define FCVAR_UNLOGGED \
|
|
(1 << 11) // If this is a FCVAR_SERVER, don't log changes to the log file /
|
|
// console if we are creating a log
|
|
#define FCVAR_NEVER_AS_STRING (1 << 12) // never try to print that cvar
|
|
// It's a ConVar that's shared between the client and the server.
|
|
// At signon, the values of all such ConVars are sent from the server to the
|
|
// client (skipped for local
|
|
// client, of course )
|
|
// If a change is requested it must come from the console (i.e., no remote
|
|
// client changes) If a value is changed while a server is active, it's
|
|
// replicated to all connected clients
|
|
#define FCVAR_REPLICATED \
|
|
(1 << 13) // server setting enforced on clients, TODO rename to FCAR_SERVER
|
|
// at some time
|
|
#define FCVAR_DEMO (1 << 16) // record this cvar when starting a demo file
|
|
#define FCVAR_DONTRECORD (1 << 17) // don't record these command in demofiles
|
|
#define FCVAR_RELOAD_MATERIALS \
|
|
(1 << 20) // If this cvar changes, it forces a material reload
|
|
#define FCVAR_RELOAD_TEXTURES \
|
|
(1 << 21) // If this cvar changes, if forces a texture reload
|
|
|
|
#define FCVAR_NOT_CONNECTED \
|
|
(1 << 22) // cvar cannot be changed by a client that is connected to a
|
|
// server
|
|
#define FCVAR_MATERIAL_SYSTEM_THREAD \
|
|
(1 << 23) // Indicates this cvar is read from the material system thread
|
|
#define FCVAR_ARCHIVE_XBOX (1 << 24) // cvar written to config.cfg on the Xbox
|
|
#define FCVAR_ACCESSIBLE_FROM_THREADS \
|
|
(1 << 25) // used as a debugging tool necessary to check material system
|
|
// thread convars
|
|
#define FCVAR_SERVER_CAN_EXECUTE \
|
|
(1 \
|
|
<< 28) // the server is allowed to execute this command on clients via
|
|
// ClientCommand/NET_StringCmd/CBaseClientState::ProcessStringCmd.
|
|
#define FCVAR_SERVER_CANNOT_QUERY \
|
|
(1 \
|
|
<< 29) // If this is set, then the server is not allowed to query this
|
|
// cvar's value (via IServerPluginHelpers::StartQueryCvarValue).
|
|
#define FCVAR_CLIENTCMD_CAN_EXECUTE \
|
|
(1 << 30) // IVEngineClient::ClientCmd is allowed to execute this command.
|
|
// Note: IVEngineClient::ClientCmd_Unrestricted can run any
|
|
// client command.
|
|
#define FCVAR_MATERIAL_THREAD_MASK \
|
|
(FCVAR_RELOAD_MATERIALS | FCVAR_RELOAD_TEXTURES | \
|
|
FCVAR_MATERIAL_SYSTEM_THREAD)
|
|
|
|
class CCommand;
|
|
//-----------------------------------------------------------------------------
|
|
// Called when a ConCommand needs to execute
|
|
//-----------------------------------------------------------------------------
|
|
using FnCommandCallbackVoid_t = void (*)(void);
|
|
using FnCommandCallback_t = void (*)(const CCommand& command);
|
|
|
|
constexpr int COMMAND_COMPLETION_MAXITEMS = 64;
|
|
constexpr int COMMAND_COMPLETION_ITEM_LENGTH = 64;
|
|
|
|
// Returns 0 to COMMAND_COMPLETION_MAXITEMS worth of completion strings
|
|
using FnCommandCompletionCallback = int (*)(
|
|
const char* partial,
|
|
char commands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH]);
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: The base console invoked command/cvar interface
|
|
//-----------------------------------------------------------------------------
|
|
class ConCommandBase {
|
|
friend class CCvar;
|
|
friend class ConVar;
|
|
friend class ConCommand;
|
|
friend void ConVar_PublishToVXConsole();
|
|
// FIXME: Remove when ConVar changes are done
|
|
friend class CDefaultCvar;
|
|
|
|
public:
|
|
ConCommandBase() {
|
|
m_bRegistered = false;
|
|
m_pszName = NULL;
|
|
m_pszHelpString = NULL;
|
|
|
|
m_nFlags = 0;
|
|
m_pNext = NULL;
|
|
}
|
|
ConCommandBase(const char* pName, const char* pHelpString = 0,
|
|
int flags = 0) {
|
|
CreateBase(pName, pHelpString, flags);
|
|
}
|
|
virtual ~ConCommandBase() {}
|
|
|
|
virtual bool IsCommand() const { return true; }
|
|
|
|
// Check flag
|
|
virtual bool IsFlagSet(int flag) const {
|
|
return (flag & m_nFlags) ? true : false;
|
|
}
|
|
// Set flag
|
|
virtual void AddFlags(int flags) { m_nFlags |= flags; };
|
|
|
|
// Return name of cvar
|
|
virtual const char* GetName() const { return m_pszName; }
|
|
|
|
// Return help text for cvar
|
|
virtual const char* GetHelpText() const { return m_pszHelpString; }
|
|
|
|
virtual bool IsRegistered(void) const { return m_bRegistered; };
|
|
|
|
// Returns the DLL identifier
|
|
virtual void* GetDLLIdentifier() const { return 0; };
|
|
|
|
protected:
|
|
virtual void CreateBase(const char* pName, const char* pHelpString = 0,
|
|
int flags = 0) {
|
|
m_bRegistered = false;
|
|
m_pszName = pName;
|
|
m_pszHelpString = pHelpString ? pHelpString : "";
|
|
m_nFlags = flags;
|
|
}
|
|
|
|
// Used internally by OneTimeInit to initialize/shutdown
|
|
virtual void Init(){};
|
|
|
|
// Internal copy routine ( uses new operator from correct module )
|
|
char* CopyString(const char* from) {
|
|
int len = strlen(from);
|
|
char* to;
|
|
|
|
if (len <= 0) {
|
|
to = new char[1];
|
|
to[0] = 0;
|
|
} else {
|
|
to = new char[len + 1];
|
|
strncpy(to, from, len + 1);
|
|
}
|
|
return to;
|
|
}
|
|
|
|
private:
|
|
// Next ConVar in chain, (linked list)
|
|
ConCommandBase* m_pNext;
|
|
|
|
// Has the cvar been added to the global list?
|
|
bool m_bRegistered;
|
|
|
|
// Static data
|
|
const char* m_pszName;
|
|
const char* m_pszHelpString;
|
|
|
|
// ConVar flags
|
|
int m_nFlags;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Command tokenizer
|
|
//-----------------------------------------------------------------------------
|
|
class CCommand {
|
|
public:
|
|
int ArgC() const { return m_nArgc; }
|
|
const char** ArgV() const {
|
|
return m_nArgc ? (const char**)m_ppArgv : NULL;
|
|
}
|
|
const char* ArgS() const {
|
|
return m_nArgv0Size ? &m_pArgSBuffer[m_nArgv0Size] : "";
|
|
} // All args that occur after the 0th arg, in string form
|
|
const char* GetCommandString() const {
|
|
return m_nArgc ? m_pArgSBuffer : "";
|
|
} // The entire command in string form, including the 0th arg
|
|
const char* operator[](int nIndex) const {
|
|
return Arg(nIndex);
|
|
} // Gets at arguments
|
|
const char* Arg(int nIndex) const { // Gets at arguments
|
|
if (nIndex < 0 || nIndex >= m_nArgc) return "";
|
|
return m_ppArgv[nIndex];
|
|
}
|
|
|
|
static int MaxCommandLength() { return COMMAND_MAX_LENGTH - 1; }
|
|
|
|
private:
|
|
static constexpr int COMMAND_MAX_ARGC = 64;
|
|
static constexpr int COMMAND_MAX_LENGTH = 512;
|
|
|
|
int m_nArgc;
|
|
int m_nArgv0Size;
|
|
char m_pArgSBuffer[COMMAND_MAX_LENGTH];
|
|
char m_pArgvBuffer[COMMAND_MAX_LENGTH];
|
|
const char* m_ppArgv[COMMAND_MAX_ARGC];
|
|
};
|
|
|
|
// Purpose: The console invoked command
|
|
class ConCommand : public ConCommandBase {
|
|
friend class CCvar;
|
|
|
|
public:
|
|
ConCommand(const char* pName, FnCommandCallbackVoid_t callback,
|
|
const char* pHelpString = 0, int flags = 0,
|
|
FnCommandCompletionCallback completionFunc = 0) {
|
|
m_fnCommandCallbackV1 = callback;
|
|
m_bUsingNewCommandCallback = false;
|
|
m_bUsingCommandCallbackInterface = false;
|
|
m_fnCompletionCallback =
|
|
completionFunc ? completionFunc
|
|
: [](const char* partial,
|
|
char commands[COMMAND_COMPLETION_MAXITEMS]
|
|
[COMMAND_COMPLETION_ITEM_LENGTH]) {
|
|
return 0;
|
|
};
|
|
m_bHasCompletionCallback = completionFunc != 0 ? true : false;
|
|
ConCommandBase::CreateBase(pName, pHelpString, flags);
|
|
}
|
|
ConCommand(const char* pName, FnCommandCallback_t callback,
|
|
const char* pHelpString = 0, int flags = 0,
|
|
FnCommandCompletionCallback completionFunc = 0) {
|
|
m_fnCommandCallback = callback;
|
|
m_bUsingNewCommandCallback = true;
|
|
m_fnCompletionCallback =
|
|
completionFunc ? completionFunc
|
|
: [](const char* partial,
|
|
char commands[COMMAND_COMPLETION_MAXITEMS]
|
|
[COMMAND_COMPLETION_ITEM_LENGTH]) {
|
|
return 0;
|
|
};
|
|
m_bHasCompletionCallback = completionFunc != 0 ? true : false;
|
|
m_bUsingCommandCallbackInterface = false;
|
|
ConCommandBase::CreateBase(pName, pHelpString, flags);
|
|
}
|
|
|
|
virtual ~ConCommand() {}
|
|
virtual bool IsCommand() const { return true; }
|
|
virtual int AutoCompleteSuggest(const char* partial,
|
|
CUtlVector<CUtlString>& commands) {
|
|
if (!m_fnCompletionCallback) return 0;
|
|
|
|
// char
|
|
// rgpchCommands[COMMAND_COMPLETION_MAXITEMS][COMMAND_COMPLETION_ITEM_LENGTH];
|
|
/*int ret = (m_fnCompletionCallback)(partial, rgpchCommands);
|
|
for (int i = 0 ; i < ret; i++) {
|
|
CUtlString str = rgpchCommands[i];
|
|
commands.AddToTail(str);
|
|
}
|
|
return ret;*/
|
|
return 0;
|
|
};
|
|
virtual bool CanAutoComplete() { return m_bHasCompletionCallback; }
|
|
|
|
// Invoke the function
|
|
virtual void Dispatch(const CCommand& command) {
|
|
if (m_bUsingNewCommandCallback) {
|
|
if (m_fnCommandCallback) {
|
|
(*m_fnCommandCallback)(command);
|
|
return;
|
|
}
|
|
} else if (m_fnCommandCallbackV1) {
|
|
(*m_fnCommandCallbackV1)();
|
|
return;
|
|
}
|
|
// Command without callback!!!
|
|
// TODO: log with a logger ofc
|
|
// assert(0, "Encountered ConCommand '%s' without a callback!\n",
|
|
// GetName() );
|
|
}
|
|
|
|
private:
|
|
// NOTE: To maintain backward compat, we have to be very careful:
|
|
// All public virtual methods must appear in the same order always
|
|
// since engine code will be calling into this code, which *does not match*
|
|
// in the mod code; it's using slightly different, but compatible versions
|
|
// of this class. Also: Be very careful about adding new fields to this
|
|
// class. Those fields will not exist in the version of this class that is
|
|
// instanced in mod code.
|
|
|
|
// Call this function when executing the command
|
|
union {
|
|
FnCommandCallbackVoid_t m_fnCommandCallbackV1;
|
|
FnCommandCallback_t m_fnCommandCallback;
|
|
};
|
|
|
|
FnCommandCompletionCallback m_fnCompletionCallback = 0;
|
|
|
|
// TODO: wtf is this shit
|
|
bool m_bHasCompletionCallback = 1;
|
|
bool m_bUsingNewCommandCallback = 1;
|
|
bool m_bUsingCommandCallbackInterface = false;
|
|
};
|
|
|
|
// A console variable
|
|
//-----------------------------------------------------------------------------
|
|
// Abstract interface for ConVars
|
|
//-----------------------------------------------------------------------------
|
|
class IConVar {
|
|
public:
|
|
// Value set
|
|
virtual void SetValue(const char* pValue) = 0;
|
|
virtual void SetValue(float flValue) = 0;
|
|
virtual void SetValue(int nValue) = 0;
|
|
|
|
// Return name of command
|
|
virtual const char* GetName(void) const = 0;
|
|
|
|
// Accessors.. not as efficient as using GetState()/GetInfo()
|
|
// if you call these methods multiple times on the same IConVar
|
|
virtual bool IsFlagSet(int nFlag) const = 0;
|
|
};
|
|
using FnChangeCallback_t = void (*)(IConVar* var, const char* pOldValue,
|
|
float flOldValue);
|
|
class ConVar : public ConCommandBase, public IConVar {
|
|
friend class CCvar;
|
|
friend class ConVarRef;
|
|
|
|
public:
|
|
ConVar(const char* pName, const char* pDefaultValue, int flags = 0) {
|
|
Create(pName, pDefaultValue, flags);
|
|
}
|
|
ConVar(const char* pName, const char* pDefaultValue, int flags,
|
|
const char* pHelpString) {
|
|
Create(pName, pDefaultValue, flags, pHelpString);
|
|
}
|
|
ConVar(const char* pName, const char* pDefaultValue, int flags,
|
|
const char* pHelpString, bool bMin, float fMin, bool bMax,
|
|
float fMax) {
|
|
Create(pName, pDefaultValue, flags, pHelpString, bMin, fMin, bMax,
|
|
fMax);
|
|
}
|
|
ConVar(const char* pName, const char* pDefaultValue, int flags,
|
|
const char* pHelpString, FnChangeCallback_t callback) {
|
|
Create(pName, pDefaultValue, flags, pHelpString, false, 0.0, false, 0.0,
|
|
callback);
|
|
}
|
|
|
|
ConVar(const char* pName, const char* pDefaultValue, int flags,
|
|
const char* pHelpString, bool bMin, float fMin, bool bMax,
|
|
float fMax, FnChangeCallback_t callback) {
|
|
Create(pName, pDefaultValue, flags, pHelpString, bMin, fMin, bMax, fMax,
|
|
callback);
|
|
}
|
|
|
|
virtual ~ConVar() { delete[] m_pszString; }
|
|
|
|
virtual bool IsFlagSet(int flag) const {
|
|
return (flag & m_pParent->m_nFlags) ? true : false;
|
|
}
|
|
virtual const char* GetHelpText() const {
|
|
return m_pParent->m_pszHelpString;
|
|
}
|
|
virtual bool IsRegistered() const { return m_pParent->m_bRegistered; }
|
|
virtual const char* GetName() const { return m_pParent->m_pszName; }
|
|
virtual void AddFlags(int flags) { m_pParent->m_nFlags |= flags; }
|
|
virtual bool IsCommand() const { return false; }
|
|
|
|
// Install a change callback (there shouldn't already be one....)
|
|
void InstallChangeCallback(FnChangeCallback_t callback) {
|
|
// Assert(!m_pParent->m_fnChangeCallback || !callback);
|
|
m_pParent->m_fnChangeCallback = callback;
|
|
if (m_pParent->m_fnChangeCallback) // Call it immediately to set the
|
|
// initial value...
|
|
m_pParent->m_fnChangeCallback(this, m_pszString, m_fValue);
|
|
}
|
|
|
|
// Retrieve value
|
|
inline float GetFloat() const { return m_pParent->m_fValue; }
|
|
inline int GetInt() const { return m_pParent->m_nValue; }
|
|
inline bool GetBool() const { return !!GetInt(); }
|
|
inline char const* GetString() const {
|
|
if (m_nFlags & FCVAR_NEVER_AS_STRING) return "FCVAR_NEVER_AS_STRING";
|
|
return (m_pParent->m_pszString) ? m_pParent->m_pszString : "";
|
|
}
|
|
|
|
// These just call into the IConCommandBaseAccessor to check flags and set
|
|
// the var (which ends up calling InternalSetValue).
|
|
virtual void SetValue(const char* value) {
|
|
m_pParent->InternalSetValue(value);
|
|
}
|
|
virtual void SetValue(float value) {
|
|
m_pParent->InternalSetFloatValue(value);
|
|
}
|
|
virtual void SetValue(int value) { m_pParent->InternalSetIntValue(value); }
|
|
|
|
// Reset to default value
|
|
void Revert() { m_pParent->SetValue(m_pParent->m_pszDefaultValue); }
|
|
|
|
// True if it has a min/max setting
|
|
bool GetMin(float& minVal) const {
|
|
minVal = m_pParent->m_fMinVal;
|
|
return m_pParent->m_bHasMin;
|
|
}
|
|
bool GetMax(float& maxVal) const {
|
|
maxVal = m_pParent->m_fMaxVal;
|
|
return m_pParent->m_bHasMax;
|
|
}
|
|
const char* GetDefault() const { return m_pParent->m_pszDefaultValue; }
|
|
void SetDefault(const char* pszDefault) {
|
|
m_pszDefaultValue = pszDefault ? pszDefault : "";
|
|
}
|
|
|
|
private:
|
|
// Called by CCvar when the value of a var is changing.
|
|
virtual void InternalSetValue(const char* in) {
|
|
// Save the old value and get the new one
|
|
float old_value = m_fValue;
|
|
float new_value = in ? atof(in) : 0;
|
|
|
|
// Get the changed string
|
|
const char* str = in;
|
|
if (ClampValue(new_value)) {
|
|
char tmp[32];
|
|
snprintf(tmp, sizeof(tmp), "%f", new_value);
|
|
str = tmp;
|
|
}
|
|
|
|
// Redetermine value
|
|
this->m_fValue = new_value;
|
|
this->m_nValue = static_cast<int>(new_value);
|
|
|
|
if (!(m_nFlags & FCVAR_NEVER_AS_STRING))
|
|
this->ChangeStringValue(str, old_value);
|
|
}
|
|
// For CVARs marked FCVAR_NEVER_AS_STRING
|
|
virtual void InternalSetFloatValue(float new_value) {
|
|
if (new_value == this->m_fValue) // No need to do anything if its equal
|
|
return;
|
|
|
|
this->ClampValue(new_value); // clamp
|
|
|
|
// Redetermine value
|
|
float old_value = this->m_fValue;
|
|
this->m_fValue = new_value;
|
|
this->m_nValue = static_cast<int>(this->m_fValue);
|
|
|
|
if (!(m_nFlags & FCVAR_NEVER_AS_STRING)) {
|
|
char tmp[32];
|
|
snprintf(tmp, sizeof(tmp), "%f", m_fValue);
|
|
ChangeStringValue(tmp, old_value);
|
|
}
|
|
}
|
|
virtual void InternalSetIntValue(int new_value) {
|
|
if (new_value == this->m_nValue) // see above
|
|
return;
|
|
|
|
float froat = static_cast<float>(new_value); // du u rike to froat
|
|
if (this->ClampValue(froat)) { // My guess is to prevent casting float
|
|
// to int while keeping use of the clamp
|
|
new_value = static_cast<int>(froat);
|
|
}
|
|
|
|
// Redetermine value
|
|
float old_value = this->m_fValue;
|
|
this->m_fValue = froat;
|
|
this->m_nValue = new_value;
|
|
|
|
if (!(m_nFlags & FCVAR_NEVER_AS_STRING)) {
|
|
char tmp[32];
|
|
snprintf(tmp, sizeof(tmp), "%d", this->m_nValue);
|
|
ChangeStringValue(tmp, old_value);
|
|
}
|
|
}
|
|
|
|
virtual bool ClampValue(float& value) {
|
|
if (m_bHasMin && (value < m_fMinVal)) {
|
|
value = m_fMinVal;
|
|
return true;
|
|
}
|
|
if (m_bHasMax && (value > m_fMaxVal)) {
|
|
value = m_fMaxVal;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
virtual void ChangeStringValue(const char* to_set, float old_value) {
|
|
// Save old value
|
|
std::string old_str =
|
|
std::string(this->m_pszString,
|
|
this->m_StringLength); // HUNGARIAN NOTATION REEEEEEE
|
|
if (to_set) {
|
|
// Reallocate if needed
|
|
int len = strlen(to_set) + 1;
|
|
if (len > this->m_StringLength) {
|
|
delete[] this->m_pszString;
|
|
this->m_pszString = new char[len];
|
|
this->m_StringLength = len;
|
|
}
|
|
// Copy new value to string
|
|
memcpy(this->m_pszString, to_set, len);
|
|
} else
|
|
*this->m_pszString = 0;
|
|
|
|
// If nothing has changed, don't do the callbacks.
|
|
if (old_str != m_pszString)
|
|
// Invoke any necessary callback function
|
|
if (m_fnChangeCallback)
|
|
m_fnChangeCallback(this, old_str.c_str(), old_value);
|
|
}
|
|
|
|
virtual void Create(const char* pName, const char* pDefaultValue,
|
|
int flags = 0, const char* pHelpString = 0,
|
|
bool bMin = false, float fMin = 0.0, bool bMax = false,
|
|
float fMax = false, FnChangeCallback_t callback = 0) {
|
|
m_pParent = this;
|
|
|
|
// Name should be static data
|
|
SetDefault(pDefaultValue);
|
|
|
|
m_StringLength = strlen(m_pszDefaultValue) + 1;
|
|
m_pszString = new char[m_StringLength];
|
|
memcpy(m_pszString, m_pszDefaultValue, m_StringLength);
|
|
|
|
m_bHasMin = bMin;
|
|
m_fMinVal = fMin;
|
|
m_bHasMax = bMax;
|
|
m_fMaxVal = fMax;
|
|
|
|
m_fnChangeCallback = callback;
|
|
|
|
m_fValue = (float)atof(m_pszString);
|
|
m_nValue =
|
|
atoi(m_pszString); // dont convert from float to int and lose bits
|
|
|
|
ConCommandBase::CreateBase(pName, pHelpString, flags);
|
|
}
|
|
|
|
// Used internally by OneTimeInit to initialize.
|
|
virtual void Init() { ConCommandBase::Init(); }
|
|
int GetFlags() { return m_pParent->m_nFlags; }
|
|
|
|
private:
|
|
// This either points to "this" or it points to the original declaration of
|
|
// a ConVar. This allows ConVars to exist in separate modules, and they all
|
|
// use the first one to be declared. m_pParent->m_pParent must equal
|
|
// m_pParent (ie: m_pParent must be the root, or original, ConVar).
|
|
ConVar* m_pParent;
|
|
|
|
// Static data
|
|
const char* m_pszDefaultValue;
|
|
|
|
// Value
|
|
// Dynamically allocated
|
|
char* m_pszString;
|
|
int m_StringLength;
|
|
|
|
// Values
|
|
float m_fValue;
|
|
int m_nValue;
|
|
|
|
// Min/Max values
|
|
bool m_bHasMin;
|
|
float m_fMinVal;
|
|
bool m_bHasMax;
|
|
float m_fMaxVal;
|
|
|
|
// Call this function when ConVar changes
|
|
FnChangeCallback_t m_fnChangeCallback;
|
|
};
|