Merge pull request #211 from Arkshine/fix/cvar-mapchange

Fix issue where at mapchange a cvar current value is overwritten by defined bounds where it should not
This commit is contained in:
Vincent Herbet 2015-02-20 15:50:49 +01:00
commit c4497ff17d
3 changed files with 35 additions and 43 deletions

View File

@ -155,7 +155,7 @@ void CvarManager::CreateCvarHook(void)
} }
CvarInfo* CvarManager::CreateCvar(const char* name, const char* value, const char* plugin, int pluginId, int flags, CvarInfo* CvarManager::CreateCvar(const char* name, const char* value, const char* plugin, int pluginId, int flags,
const char* helpText, bool hasMin, float min, bool hasMax, float max) const char* helpText)
{ {
cvar_t* var = nullptr; cvar_t* var = nullptr;
CvarInfo* info = nullptr; CvarInfo* info = nullptr;
@ -166,7 +166,7 @@ CvarInfo* CvarManager::CreateCvar(const char* name, const char* value, const cha
var = CVAR_GET_POINTER(name); var = CVAR_GET_POINTER(name);
// Whether it exists, we need to prepare a new entry. // Whether it exists, we need to prepare a new entry.
info = new CvarInfo(name, helpText, hasMin, min, hasMax, max, plugin, pluginId); info = new CvarInfo(name, helpText, plugin, pluginId);
if (var) if (var)
{ {
@ -385,20 +385,21 @@ bool CvarManager::BindCvar(CvarInfo* info, CvarBind::CvarType type, AMX* amx, ce
return true; return true;
} }
bool CvarManager::SetCvarMin(CvarInfo* info, bool set, float value, int pluginId) void CvarManager::SetCvarMin(CvarInfo* info, bool set, float value, int pluginId)
{ {
info->bound.hasMin = set; info->bound.hasMin = set;
info->bound.minPluginId = pluginId; info->bound.minPluginId = pluginId;
if (set) if (set)
{ {
if (info->bound.hasMax && value > info->bound.maxVal)
{
return false;
}
info->bound.minVal = value; info->bound.minVal = value;
// Current value is already in the allowed range.
if (info->var->value >= value)
{
return;
}
// Detour is disabled on map change. // Detour is disabled on map change.
if (m_HookDetour) if (m_HookDetour)
{ {
@ -408,24 +409,23 @@ bool CvarManager::SetCvarMin(CvarInfo* info, bool set, float value, int pluginId
// Update if needed. // Update if needed.
CVAR_SET_FLOAT(info->var->name, value); CVAR_SET_FLOAT(info->var->name, value);
} }
return true;
} }
bool CvarManager::SetCvarMax(CvarInfo* info, bool set, float value, int pluginId) void CvarManager::SetCvarMax(CvarInfo* info, bool set, float value, int pluginId)
{ {
info->bound.hasMax = set; info->bound.hasMax = set;
info->bound.maxPluginId = pluginId; info->bound.maxPluginId = pluginId;
if (set) if (set)
{ {
if (info->bound.hasMin && value < info->bound.minVal)
{
return false;
}
info->bound.maxVal = value; info->bound.maxVal = value;
// Current value is already in the allowed range.
if (info->var->value <= value)
{
return;
}
// Detour is disabled on map change. // Detour is disabled on map change.
if (m_HookDetour) if (m_HookDetour)
{ {
@ -435,8 +435,6 @@ bool CvarManager::SetCvarMax(CvarInfo* info, bool set, float value, int pluginId
// Update if needed. // Update if needed.
CVAR_SET_FLOAT(info->var->name, value); CVAR_SET_FLOAT(info->var->name, value);
} }
return true;
} }
size_t CvarManager::GetRegCvarsCount() size_t CvarManager::GetRegCvarsCount()

View File

@ -78,17 +78,12 @@ struct CvarBind
struct CvarBound struct CvarBound
{ {
CvarBound(bool hasMin_, float minVal_, bool hasMax_, float maxVal_, int minPluginId_, int maxPluginId_)
:
hasMin(hasMin_), minVal(minVal_),
hasMax(hasMax_), maxVal(maxVal_),
minPluginId(minPluginId_),
maxPluginId(maxPluginId_) {};
CvarBound() CvarBound()
: :
hasMin(false), minVal(0), hasMin(false), minVal(0),
hasMax(false), maxVal(0) {}; hasMax(false), maxVal(0),
minPluginId(-1),
maxPluginId(-1) {};
bool hasMin; bool hasMin;
float minVal; float minVal;
@ -103,13 +98,10 @@ typedef ke::Vector<CvarBind*> CvarsBind;
struct CvarInfo : public ke::InlineListNode<CvarInfo> struct CvarInfo : public ke::InlineListNode<CvarInfo>
{ {
CvarInfo(const char* name_, const char* helpText, CvarInfo(const char* name_, const char* helpText, const char* plugin_, int pluginId_)
bool hasMin_, float min_, bool hasMax_, float max_,
const char* plugin_, int pluginId_)
: :
name(name_), description(helpText), name(name_), description(helpText),
plugin(plugin_), pluginId(pluginId_), plugin(plugin_), pluginId(pluginId_), bound() {};
bound(hasMin_, min_, hasMax_, max_, pluginId_, pluginId_) {};
CvarInfo(const char* name_) CvarInfo(const char* name_)
: :
@ -150,19 +142,15 @@ class CvarManager
void CreateCvarHook(); void CreateCvarHook();
CvarInfo* CreateCvar(const char* name, const char* value, const char* plugin, int pluginId, CvarInfo* CreateCvar(const char* name, const char* value, const char* plugin, int pluginId, int flags = 0, const char* helpText = "");
int flags = 0, const char* helpText = "",
bool hasMin = false, float min = 0,
bool hasMax = false, float max = 0);
CvarInfo* 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);
AutoForward* HookCvarChange(cvar_t* var, AMX* amx, cell param, const char** callback); AutoForward* HookCvarChange(cvar_t* var, AMX* amx, cell param, const char** callback);
bool BindCvar(CvarInfo* info, CvarBind::CvarType type, AMX* amx, cell varofs, size_t varlen = 0); bool BindCvar(CvarInfo* info, CvarBind::CvarType type, AMX* amx, cell varofs, size_t varlen = 0);
bool SetCvarMin(CvarInfo* info, bool set, float value, int pluginId); void SetCvarMin(CvarInfo* info, bool set, float value, int pluginId);
bool SetCvarMax(CvarInfo* info, bool set, float value, int pluginId); void SetCvarMax(CvarInfo* info, bool set, float value, int pluginId);
size_t GetRegCvarsCount(); size_t GetRegCvarsCount();

View File

@ -40,18 +40,20 @@ static cell AMX_NATIVE_CALL create_cvar(AMX *amx, cell *params)
float minVal = amx_ctof(params[6]); float minVal = amx_ctof(params[6]);
float maxVal = amx_ctof(params[8]); float maxVal = amx_ctof(params[8]);
if (!g_CvarManager.SetCvarMin(info, hasMin, minVal, plugin->getId())) if (hasMax && minVal > maxVal)
{ {
LogError(amx, AMX_ERR_NATIVE, "The minimum value can not be above the maximum value"); LogError(amx, AMX_ERR_NATIVE, "The minimum value can not be above the maximum value");
return 0; return 0;
} }
else if (hasMin && maxVal < minVal)
if (!g_CvarManager.SetCvarMax(info, hasMax, maxVal, plugin->getId()))
{ {
LogError(amx, AMX_ERR_NATIVE, "The maximum value can not be below the minimum value"); LogError(amx, AMX_ERR_NATIVE, "The maximum value can not be below the minimum value");
return 0; return 0;
} }
g_CvarManager.SetCvarMin(info, hasMin, minVal, plugin->getId());
g_CvarManager.SetCvarMax(info, hasMax, maxVal, plugin->getId());
return reinterpret_cast<cell>(info->var); return reinterpret_cast<cell>(info->var);
} }
@ -498,20 +500,24 @@ static cell AMX_NATIVE_CALL set_pcvar_bounds(AMX *amx, cell *params)
{ {
case CvarBound_Lower: case CvarBound_Lower:
{ {
if (!g_CvarManager.SetCvarMin(info, set, value, pluginId)) if (set && info->bound.hasMax && value > info->bound.maxVal)
{ {
LogError(amx, AMX_ERR_NATIVE, "The minimum value can not be above the maximum value"); LogError(amx, AMX_ERR_NATIVE, "The minimum value can not be above the maximum value");
return 0; return 0;
} }
g_CvarManager.SetCvarMin(info, set, value, pluginId);
break; break;
} }
case CvarBound_Upper: case CvarBound_Upper:
{ {
if (!g_CvarManager.SetCvarMax(info, set, value, pluginId)) if (set && info->bound.hasMin && value < info->bound.minVal)
{ {
LogError(amx, AMX_ERR_NATIVE, "The maximum value can not be below the minimum value"); LogError(amx, AMX_ERR_NATIVE, "The maximum value can not be below the minimum value");
return 0; return 0;
} }
g_CvarManager.SetCvarMax(info, set, value, pluginId);
break; break;
} }
default: default: