From 80b01d3505ecd0a910e362b9a07c569945070ea9 Mon Sep 17 00:00:00 2001 From: Arkshine Date: Thu, 19 Feb 2015 15:21:00 +0100 Subject: [PATCH] Fix issue where at mapchange a cvar current value is overwritten by defined bounds where it should not --- amxmodx/CvarManager.cpp | 34 ++++++++++++++++------------------ amxmodx/CvarManager.h | 28 ++++++++-------------------- amxmodx/cvars.cpp | 16 +++++++++++----- 3 files changed, 35 insertions(+), 43 deletions(-) diff --git a/amxmodx/CvarManager.cpp b/amxmodx/CvarManager.cpp index 250e12ae..5075fea7 100644 --- a/amxmodx/CvarManager.cpp +++ b/amxmodx/CvarManager.cpp @@ -155,7 +155,7 @@ void CvarManager::CreateCvarHook(void) } 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; CvarInfo* info = nullptr; @@ -166,7 +166,7 @@ CvarInfo* CvarManager::CreateCvar(const char* name, const char* value, const cha var = CVAR_GET_POINTER(name); // 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) { @@ -385,20 +385,21 @@ bool CvarManager::BindCvar(CvarInfo* info, CvarBind::CvarType type, AMX* amx, ce 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.minPluginId = pluginId; if (set) { - if (info->bound.hasMax && value > info->bound.maxVal) - { - return false; - } - info->bound.minVal = value; + // Current value is already in the allowed range. + if (info->var->value >= value) + { + return; + } + // Detour is disabled on map change. if (m_HookDetour) { @@ -408,24 +409,23 @@ bool CvarManager::SetCvarMin(CvarInfo* info, bool set, float value, int pluginId // Update if needed. 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.maxPluginId = pluginId; if (set) { - if (info->bound.hasMin && value < info->bound.minVal) - { - return false; - } - info->bound.maxVal = value; + // Current value is already in the allowed range. + if (info->var->value <= value) + { + return; + } + // Detour is disabled on map change. if (m_HookDetour) { @@ -435,8 +435,6 @@ bool CvarManager::SetCvarMax(CvarInfo* info, bool set, float value, int pluginId // Update if needed. CVAR_SET_FLOAT(info->var->name, value); } - - return true; } size_t CvarManager::GetRegCvarsCount() diff --git a/amxmodx/CvarManager.h b/amxmodx/CvarManager.h index 9c67f436..40e3431d 100644 --- a/amxmodx/CvarManager.h +++ b/amxmodx/CvarManager.h @@ -78,17 +78,12 @@ struct CvarBind 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() : hasMin(false), minVal(0), - hasMax(false), maxVal(0) {}; + hasMax(false), maxVal(0), + minPluginId(-1), + maxPluginId(-1) {}; bool hasMin; float minVal; @@ -103,13 +98,10 @@ typedef ke::Vector CvarsBind; struct CvarInfo : public ke::InlineListNode { - CvarInfo(const char* name_, const char* helpText, - bool hasMin_, float min_, bool hasMax_, float max_, - const char* plugin_, int pluginId_) + CvarInfo(const char* name_, const char* helpText, const char* plugin_, int pluginId_) : name(name_), description(helpText), - plugin(plugin_), pluginId(pluginId_), - bound(hasMin_, min_, hasMax_, max_, pluginId_, pluginId_) {}; + plugin(plugin_), pluginId(pluginId_), bound() {}; CvarInfo(const char* name_) : @@ -150,19 +142,15 @@ class CvarManager void CreateCvarHook(); - CvarInfo* CreateCvar(const char* name, const char* value, const char* plugin, int pluginId, - int flags = 0, const char* helpText = "", - bool hasMin = false, float min = 0, - bool hasMax = false, float max = 0); - + CvarInfo* CreateCvar(const char* name, const char* value, const char* plugin, int pluginId, int flags = 0, const char* helpText = ""); CvarInfo* FindCvar(const char* name); CvarInfo* FindCvar(size_t index); bool CacheLookup(const char* name, CvarInfo** info); 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 SetCvarMin(CvarInfo* info, bool set, float value, int pluginId); - bool SetCvarMax(CvarInfo* info, bool set, float value, int pluginId); + void SetCvarMin(CvarInfo* info, bool set, float value, int pluginId); + void SetCvarMax(CvarInfo* info, bool set, float value, int pluginId); size_t GetRegCvarsCount(); diff --git a/amxmodx/cvars.cpp b/amxmodx/cvars.cpp index c3d43690..b3f52f5e 100644 --- a/amxmodx/cvars.cpp +++ b/amxmodx/cvars.cpp @@ -40,18 +40,20 @@ static cell AMX_NATIVE_CALL create_cvar(AMX *amx, cell *params) float minVal = amx_ctof(params[6]); 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"); return 0; } - - if (!g_CvarManager.SetCvarMax(info, hasMax, maxVal, plugin->getId())) + else if (hasMin && maxVal < minVal) { LogError(amx, AMX_ERR_NATIVE, "The maximum value can not be below the minimum value"); return 0; } + g_CvarManager.SetCvarMin(info, hasMin, minVal, plugin->getId()); + g_CvarManager.SetCvarMax(info, hasMax, maxVal, plugin->getId()); + return reinterpret_cast(info->var); } @@ -498,20 +500,24 @@ static cell AMX_NATIVE_CALL set_pcvar_bounds(AMX *amx, cell *params) { 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"); return 0; } + + g_CvarManager.SetCvarMin(info, set, value, pluginId); break; } 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"); return 0; } + + g_CvarManager.SetCvarMax(info, set, value, pluginId); break; } default: