Cvars: Add get|set_pcvar_bounds natives

This commit is contained in:
Arkshine 2015-01-23 16:45:28 +01:00
parent a05d0df50e
commit 8ebb7be36d
4 changed files with 143 additions and 34 deletions

View File

@ -207,7 +207,7 @@ cvar_t* CvarManager::CreateCvar(const char* name, const char* value, const char*
return info->var; return info->var;
} }
cvar_t* CvarManager::FindCvar(const char* name) CvarInfo* CvarManager::FindCvar(const char* name)
{ {
cvar_t* var = nullptr; cvar_t* var = nullptr;
CvarInfo* info = nullptr; CvarInfo* info = nullptr;
@ -215,7 +215,7 @@ cvar_t* CvarManager::FindCvar(const char* name)
// Do we have already cvar in cache? // Do we have already cvar in cache?
if (CacheLookup(name, &info)) if (CacheLookup(name, &info))
{ {
return info->var; return info;
} }
// Cvar doesn't exist. // Cvar doesn't exist.
@ -232,7 +232,7 @@ cvar_t* CvarManager::FindCvar(const char* name)
m_Cvars.append(info); m_Cvars.append(info);
m_Cache.insert(name, info); m_Cache.insert(name, info);
return var; return info;
} }
CvarInfo* CvarManager::FindCvar(size_t index) CvarInfo* CvarManager::FindCvar(size_t index)

View File

@ -17,6 +17,12 @@
class CDetour; class CDetour;
enum CvarBounds
{
CvarBound_Upper = 0,
CvarBound_Lower
};
struct Forward struct Forward
{ {
enum fwdstate enum fwdstate
@ -102,7 +108,8 @@ class CvarManager
int flags = 0, const char* helpText = "", int flags = 0, const char* helpText = "",
bool hasMin = false, float min = 0, bool hasMin = false, float min = 0,
bool hasMax = false, float max = 0); bool hasMax = false, float max = 0);
cvar_t* FindCvar(const char* name);
CvarInfo* FindCvar(const char* name);
CvarInfo* FindCvar(size_t index); CvarInfo* FindCvar(size_t index);
bool CacheLookup(const char* name, CvarInfo** info); bool CacheLookup(const char* name, CvarInfo** info);

View File

@ -73,11 +73,11 @@ static cell AMX_NATIVE_CALL cvar_exists(AMX *amx, cell *params)
static cell AMX_NATIVE_CALL get_cvar_pointer(AMX *amx, cell *params) static cell AMX_NATIVE_CALL get_cvar_pointer(AMX *amx, cell *params)
{ {
int len; int len;
char *name = get_amxstring(amx, params[1], 0, len); const char *name = get_amxstring(amx, params[1], 0, len);
cvar_t *ptr = g_CvarManager.FindCvar(name); CvarInfo* info = g_CvarManager.FindCvar(name);
return reinterpret_cast<cell>(ptr); return reinterpret_cast<cell>(info ? info->var : 0);
} }
// hook_cvar_change(cvarHandle, const callback[]) // hook_cvar_change(cvarHandle, const callback[])
@ -141,9 +141,9 @@ static cell AMX_NATIVE_CALL get_cvar_flags(AMX *amx, cell *params)
int ilen; int ilen;
char* sCvar = get_amxstring(amx, params[1], 0, ilen); char* sCvar = get_amxstring(amx, params[1], 0, ilen);
cvar_t* pCvar = g_CvarManager.FindCvar(sCvar); CvarInfo* info = g_CvarManager.FindCvar(sCvar);
return pCvar ? pCvar->flags : 0; return info ? info->var->flags : 0;
} }
// get_cvar_float(const cvarname[]) // get_cvar_float(const cvarname[])
@ -152,9 +152,9 @@ static cell AMX_NATIVE_CALL get_cvar_float(AMX *amx, cell *params)
int length; int length;
const char* name = get_amxstring(amx, params[1], 0, length); const char* name = get_amxstring(amx, params[1], 0, length);
cvar_t* var = g_CvarManager.FindCvar(name); CvarInfo* info = g_CvarManager.FindCvar(name);
return var ? amx_ftoc(var->value) : 0; return info ? amx_ftoc(info->var->value) : 0;
} }
// get_cvar_num(const cvarname[]) // get_cvar_num(const cvarname[])
@ -163,9 +163,9 @@ static cell AMX_NATIVE_CALL get_cvar_num(AMX *amx, cell *params)
int length; int length;
const char* name = get_amxstring(amx, params[1], 0, length); const char* name = get_amxstring(amx, params[1], 0, length);
cvar_t* var = g_CvarManager.FindCvar(name); CvarInfo* info = g_CvarManager.FindCvar(name);
return var ? (int)var->value : 0; return info ? (int)info->var->value : 0;
} }
// get_cvar_string(const cvarname[], output[], iLen) // get_cvar_string(const cvarname[], output[], iLen)
@ -174,10 +174,10 @@ static cell AMX_NATIVE_CALL get_cvar_string(AMX *amx, cell *params)
int length; int length;
const char* name = get_amxstring(amx, params[1], 0, length); const char* name = get_amxstring(amx, params[1], 0, length);
cvar_t* var = g_CvarManager.FindCvar(name); CvarInfo* info = g_CvarManager.FindCvar(name);
const char *value = var ? var->string : ""; const char *value = info ? info->var->string : "";
length = var ? strlen(value) : 0; length = info ? strlen(value) : 0;
return set_amxstring_utf8(amx, params[2], value, length, params[3] + 1); // + EOS return set_amxstring_utf8(amx, params[2], value, length, params[3] + 1); // + EOS
} }
@ -186,16 +186,16 @@ static cell AMX_NATIVE_CALL get_cvar_string(AMX *amx, cell *params)
static cell AMX_NATIVE_CALL set_cvar_flags(AMX *amx, cell *params) static cell AMX_NATIVE_CALL set_cvar_flags(AMX *amx, cell *params)
{ {
int ilen; int ilen;
char* sCvar = get_amxstring(amx, params[1], 0, ilen); const char* sCvar = get_amxstring(amx, params[1], 0, ilen);
if (!strcmp(sCvar, "amx_version") || !strcmp(sCvar, "amxmodx_version") || !strcmp(sCvar, "fun_version") || !strcmp(sCvar, "sv_cheats")) if (!strcmp(sCvar, "amx_version") || !strcmp(sCvar, "amxmodx_version") || !strcmp(sCvar, "fun_version") || !strcmp(sCvar, "sv_cheats"))
return 0; return 0;
cvar_t* pCvar = g_CvarManager.FindCvar(sCvar); CvarInfo* info = g_CvarManager.FindCvar(sCvar);
if (pCvar) if (info)
{ {
pCvar->flags |= (int)(params[2]); info->var->flags |= (int)(params[2]);
return 1; return 1;
} }
@ -208,12 +208,12 @@ static cell AMX_NATIVE_CALL set_cvar_float(AMX *amx, cell *params)
int length; int length;
const char* name = get_amxstring(amx, params[1], 0, length); const char* name = get_amxstring(amx, params[1], 0, length);
cvar_t* var = g_CvarManager.FindCvar(name); CvarInfo* info = g_CvarManager.FindCvar(name);
if (var) if (info)
{ {
UTIL_Format(CVarTempBuffer, sizeof(CVarTempBuffer) - 1, "%f", amx_ctof(params[2])); UTIL_Format(CVarTempBuffer, sizeof(CVarTempBuffer) - 1, "%f", amx_ctof(params[2]));
CVAR_DIRECTSET(var, &CVarTempBuffer[0]); CVAR_DIRECTSET(info->var, &CVarTempBuffer[0]);
} }
return 1; return 1;
@ -226,12 +226,12 @@ static cell AMX_NATIVE_CALL set_cvar_num(AMX *amx, cell *params)
const char* name = get_amxstring(amx, params[1], 0, length); const char* name = get_amxstring(amx, params[1], 0, length);
int value = params[2]; int value = params[2];
cvar_t* var = g_CvarManager.FindCvar(name); CvarInfo* info = g_CvarManager.FindCvar(name);
if (var) if (info)
{ {
UTIL_Format(CVarTempBuffer, sizeof(CVarTempBuffer) - 1, "%d", value); UTIL_Format(CVarTempBuffer, sizeof(CVarTempBuffer) - 1, "%d", value);
CVAR_DIRECTSET(var, &CVarTempBuffer[0]); CVAR_DIRECTSET(info->var, &CVarTempBuffer[0]);
} }
return 1; return 1;
@ -243,11 +243,11 @@ static cell AMX_NATIVE_CALL set_cvar_string(AMX *amx, cell *params)
int length; int length;
const char* name = get_amxstring(amx, params[1], 0, length); const char* name = get_amxstring(amx, params[1], 0, length);
cvar_t* var = g_CvarManager.FindCvar(name); CvarInfo* info = g_CvarManager.FindCvar(name);
if (var) if (info)
{ {
CVAR_DIRECTSET(var, get_amxstring(amx, params[2], 1, length)); CVAR_DIRECTSET(info->var, get_amxstring(amx, params[2], 1, length));
} }
return 1; return 1;
@ -305,6 +305,41 @@ static cell AMX_NATIVE_CALL get_pcvar_string(AMX *amx, cell *params)
return set_amxstring_utf8(amx, params[2], ptr->string ? ptr->string : "", ptr->string ? strlen(ptr->string) : 0, params[3] + 1); // EOS return set_amxstring_utf8(amx, params[2], ptr->string ? ptr->string : "", ptr->string ? strlen(ptr->string) : 0, params[3] + 1); // EOS
} }
// get_pcvar_bounds(pcvar, CvarBounds:type, &Float:value)
static cell AMX_NATIVE_CALL get_pcvar_bounds(AMX *amx, cell *params)
{
cvar_t *ptr = reinterpret_cast<cvar_t *>(params[1]);
CvarInfo* info = nullptr;
if (!ptr || !(info = g_CvarManager.FindCvar(ptr->name)))
{
LogError(amx, AMX_ERR_NATIVE, "Invalid CVAR pointer");
return 0;
}
bool hasBound = false;
float bound;
switch (params[2])
{
case CvarBound_Lower:
hasBound = info->hasMin;
bound = info->minVal;
break;
case CvarBound_Upper:
hasBound = info->hasMax;
bound = info->maxVal;
break;
default:
LogError(amx, AMX_ERR_NATIVE, "Invalid CvarBounds value: %d", params[2]);
return 0;
}
*get_amxaddr(amx, params[3]) = amx_ftoc(bound);
return hasBound;
}
// set_pcvar_flags(pcvar, flags) // set_pcvar_flags(pcvar, flags)
static cell AMX_NATIVE_CALL set_pcvar_flags(AMX *amx, cell *params) static cell AMX_NATIVE_CALL set_pcvar_flags(AMX *amx, cell *params)
{ {
@ -369,6 +404,38 @@ static cell AMX_NATIVE_CALL set_pcvar_string(AMX *amx, cell *params)
return 1; return 1;
} }
// set_pcvar_bounds(pcvar, CvarBounds:type, bool:set, Float:value = 0.0)
static cell AMX_NATIVE_CALL set_pcvar_bounds(AMX *amx, cell *params)
{
cvar_t *ptr = reinterpret_cast<cvar_t *>(params[1]);
CvarInfo* info = nullptr;
if (!ptr || !(info = g_CvarManager.FindCvar(ptr->name)))
{
LogError(amx, AMX_ERR_NATIVE, "Invalid CVAR pointer");
return 0;
}
bool set = params[3] > 0 ? true : false;
switch (params[2])
{
case CvarBound_Lower:
info->hasMin = set;
info->minVal = set ? amx_ctof(params[4]) : 0;
break;
case CvarBound_Upper:
info->hasMax = set;
info->maxVal = set ? amx_ctof(params[4]) : 0;
break;
default:
LogError(amx, AMX_ERR_NATIVE, "Invalid CvarBounds value: %d", params[2]);
return 0;
}
return 1;
}
// remove_cvar_flags(const cvar[], flags=-1) // remove_cvar_flags(const cvar[], flags=-1)
static cell AMX_NATIVE_CALL remove_cvar_flags(AMX *amx, cell *params) static cell AMX_NATIVE_CALL remove_cvar_flags(AMX *amx, cell *params)
{ {
@ -378,11 +445,11 @@ static cell AMX_NATIVE_CALL remove_cvar_flags(AMX *amx, cell *params)
if (!strcmp(sCvar, "amx_version") || !strcmp(sCvar, "amxmodx_version") || !strcmp(sCvar, "fun_version") || !strcmp(sCvar, "sv_cheats")) if (!strcmp(sCvar, "amx_version") || !strcmp(sCvar, "amxmodx_version") || !strcmp(sCvar, "fun_version") || !strcmp(sCvar, "sv_cheats"))
return 0; return 0;
cvar_t* pCvar = g_CvarManager.FindCvar(sCvar); CvarInfo* info = g_CvarManager.FindCvar(sCvar);
if (pCvar) if (info)
{ {
pCvar->flags &= ~((int)(params[2])); info->var->flags &= ~((int)(params[2]));
return 1; return 1;
} }
@ -536,11 +603,13 @@ AMX_NATIVE_INFO g_CvarNatives[] =
{"get_pcvar_float", get_pcvar_float}, {"get_pcvar_float", get_pcvar_float},
{"get_pcvar_num", get_pcvar_num}, {"get_pcvar_num", get_pcvar_num},
{"get_pcvar_string", get_pcvar_string}, {"get_pcvar_string", get_pcvar_string},
{"get_pcvar_bounds", get_pcvar_bounds},
{"set_pcvar_flags", set_pcvar_flags}, {"set_pcvar_flags", set_pcvar_flags},
{"set_pcvar_float", set_pcvar_float}, {"set_pcvar_float", set_pcvar_float},
{"set_pcvar_string", set_pcvar_string},
{"set_pcvar_num", set_pcvar_num}, {"set_pcvar_num", set_pcvar_num},
{"set_pcvar_string", set_pcvar_string},
{"set_pcvar_bounds", set_pcvar_bounds},
{"remove_cvar_flags", remove_cvar_flags}, {"remove_cvar_flags", remove_cvar_flags},

View File

@ -13,7 +13,7 @@
#define _cvars_included #define _cvars_included
/** /**
* CVAR flags for register_cvar() * CVAR flags for create_cvar()
*/ */
#define FCVAR_NONE 0 /* No flags */ #define FCVAR_NONE 0 /* No flags */
#define FCVAR_ARCHIVE 1 /* Set to cause it to be saved to vars.rc */ #define FCVAR_ARCHIVE 1 /* Set to cause it to be saved to vars.rc */
@ -361,6 +361,39 @@ native get_pcvar_string(pcvar, string[], maxlen);
*/ */
native set_pcvar_string(pcvar, const string[]); native set_pcvar_string(pcvar, const string[]);
/**
* Cvar bound values used with get/set_pcvar_bounds()
*/
enum CvarBounds
{
CvarBound_Upper = 0,
CvarBound_Lower
};
/**
* Retrieves the specified bound of a cvar.
*
* @param pcvar Pointer to cvar
* @param type Type of bound to retrieve, CvarBound_Lower or CvarBound_Upper
* @param value By-reference cell to store the specified floating point bound value
*
* @return True if the cvar has the specified bound set, false otherwise.
* @error If an invalid cvar pointer or CvarBounds value, an error is thrown.
*/
native bool:get_pcvar_bounds(pcvar, CvarBounds:type, &Float:value);
/**
* Sets the specified bound of a cvar.
*
* @param pcvar Pointer to cvar
* @param type Type of bound to set, CvarBound_Lower or CvarBound_Upper
* @param set If set to true, cvar will use specified bound. If false, bound will be removed
* @param value Floating point value to use as the specified bound
*
* @error If an invalid cvar pointer or CvarBounds value, an error is thrown.
*/
native set_pcvar_bounds(pcvar, CvarBounds:type, bool:set, Float:value = 0.0);
/** /**
* Returns the number of plugin-registered cvars. * Returns the number of plugin-registered cvars.
* *