mirror of https://github.com/OpenTTD/OpenTTD
Change: Use enum/bitset to track which script configuration items are defined. (#14150)
Removes magic numbers, and simplifies compatibility. It is no longer necessary to provide values which won't be used.pull/14156/head
parent
b20b56d5fc
commit
13fcc0900e
|
@ -83,10 +83,21 @@ bool ScriptInfo::GetSettings()
|
||||||
return this->engine->CallMethod(this->SQ_instance, "GetSettings", nullptr, MAX_GET_SETTING_OPS);
|
return this->engine->CallMethod(this->SQ_instance, "GetSettings", nullptr, MAX_GET_SETTING_OPS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class ScriptConfigItemKey : uint8_t {
|
||||||
|
Name,
|
||||||
|
Description,
|
||||||
|
MinValue,
|
||||||
|
MaxValue,
|
||||||
|
MediumValue,
|
||||||
|
DefaultValue,
|
||||||
|
Flags,
|
||||||
|
};
|
||||||
|
using ScriptConfigItemKeys = EnumBitSet<ScriptConfigItemKey, uint8_t>;
|
||||||
|
|
||||||
SQInteger ScriptInfo::AddSetting(HSQUIRRELVM vm)
|
SQInteger ScriptInfo::AddSetting(HSQUIRRELVM vm)
|
||||||
{
|
{
|
||||||
ScriptConfigItem config;
|
ScriptConfigItem config;
|
||||||
uint items = 0;
|
ScriptConfigItemKeys present{};
|
||||||
|
|
||||||
int medium_value = INT32_MIN;
|
int medium_value = INT32_MIN;
|
||||||
|
|
||||||
|
@ -106,40 +117,38 @@ SQInteger ScriptInfo::AddSetting(HSQUIRRELVM vm)
|
||||||
auto replace_with_underscore = [](auto c) { return c == '=' || c == ','; };
|
auto replace_with_underscore = [](auto c) { return c == '=' || c == ','; };
|
||||||
config.name = StrMakeValid(sqvalue);
|
config.name = StrMakeValid(sqvalue);
|
||||||
std::replace_if(config.name.begin(), config.name.end(), replace_with_underscore, '_');
|
std::replace_if(config.name.begin(), config.name.end(), replace_with_underscore, '_');
|
||||||
items |= 0x001;
|
present.Set(ScriptConfigItemKey::Name);
|
||||||
} else if (key == "description") {
|
} else if (key == "description") {
|
||||||
const SQChar *sqdescription;
|
const SQChar *sqdescription;
|
||||||
if (SQ_FAILED(sq_getstring(vm, -1, &sqdescription))) return SQ_ERROR;
|
if (SQ_FAILED(sq_getstring(vm, -1, &sqdescription))) return SQ_ERROR;
|
||||||
config.description = StrMakeValid(sqdescription);
|
config.description = StrMakeValid(sqdescription);
|
||||||
items |= 0x002;
|
present.Set(ScriptConfigItemKey::Description);
|
||||||
} else if (key == "min_value") {
|
} else if (key == "min_value") {
|
||||||
SQInteger res;
|
SQInteger res;
|
||||||
if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
|
if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
|
||||||
config.min_value = ClampTo<int32_t>(res);
|
config.min_value = ClampTo<int32_t>(res);
|
||||||
items |= 0x004;
|
present.Set(ScriptConfigItemKey::MinValue);
|
||||||
} else if (key == "max_value") {
|
} else if (key == "max_value") {
|
||||||
SQInteger res;
|
SQInteger res;
|
||||||
if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
|
if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
|
||||||
config.max_value = ClampTo<int32_t>(res);
|
config.max_value = ClampTo<int32_t>(res);
|
||||||
items |= 0x008;
|
present.Set(ScriptConfigItemKey::MaxValue);
|
||||||
} else if (key == "easy_value") {
|
} else if (key == "easy_value") {
|
||||||
/* No longer parsed. */
|
/* No longer parsed. */
|
||||||
items |= 0x010;
|
|
||||||
} else if (key == "medium_value") {
|
} else if (key == "medium_value") {
|
||||||
SQInteger res;
|
SQInteger res;
|
||||||
if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
|
if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
|
||||||
medium_value = ClampTo<int32_t>(res);
|
medium_value = ClampTo<int32_t>(res);
|
||||||
items |= 0x020;
|
present.Set(ScriptConfigItemKey::MediumValue);
|
||||||
} else if (key == "hard_value") {
|
} else if (key == "hard_value") {
|
||||||
/* No longer parsed. */
|
/* No longer parsed. */
|
||||||
items |= 0x040;
|
|
||||||
} else if (key == "custom_value") {
|
} else if (key == "custom_value") {
|
||||||
/* No longer parsed. */
|
/* No longer parsed. */
|
||||||
} else if (key == "default_value") {
|
} else if (key == "default_value") {
|
||||||
SQInteger res;
|
SQInteger res;
|
||||||
if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
|
if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
|
||||||
config.default_value = ClampTo<int32_t>(res);
|
config.default_value = ClampTo<int32_t>(res);
|
||||||
items |= 0x080;
|
present.Set(ScriptConfigItemKey::DefaultValue);
|
||||||
} else if (key == "random_deviation") {
|
} else if (key == "random_deviation") {
|
||||||
/* No longer parsed. */
|
/* No longer parsed. */
|
||||||
} else if (key == "step_size") {
|
} else if (key == "step_size") {
|
||||||
|
@ -149,8 +158,8 @@ SQInteger ScriptInfo::AddSetting(HSQUIRRELVM vm)
|
||||||
} else if (key == "flags") {
|
} else if (key == "flags") {
|
||||||
SQInteger res;
|
SQInteger res;
|
||||||
if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
|
if (SQ_FAILED(sq_getinteger(vm, -1, &res))) return SQ_ERROR;
|
||||||
config.flags = (ScriptConfigFlags)res;
|
config.flags = static_cast<ScriptConfigFlags>(res);
|
||||||
items |= 0x100;
|
present.Set(ScriptConfigItemKey::Flags);
|
||||||
} else {
|
} else {
|
||||||
this->engine->ThrowError(fmt::format("unknown setting property '{}'", key));
|
this->engine->ThrowError(fmt::format("unknown setting property '{}'", key));
|
||||||
return SQ_ERROR;
|
return SQ_ERROR;
|
||||||
|
@ -163,23 +172,22 @@ SQInteger ScriptInfo::AddSetting(HSQUIRRELVM vm)
|
||||||
/* Check if default_value is set. Although required, this was changed with
|
/* Check if default_value is set. Although required, this was changed with
|
||||||
* 14.0, and as such, older AIs don't use it yet. So we convert the older
|
* 14.0, and as such, older AIs don't use it yet. So we convert the older
|
||||||
* values into a default_value. */
|
* values into a default_value. */
|
||||||
if ((items & 0x080) == 0) {
|
if (!present.Test(ScriptConfigItemKey::DefaultValue)) {
|
||||||
/* Easy/medium/hard should all three be defined. */
|
/* Easy/medium/hard should all three be defined. */
|
||||||
if ((items & 0x010) == 0 || (items & 0x020) == 0 || (items & 0x040) == 0) {
|
if (!present.Test(ScriptConfigItemKey::MediumValue)) {
|
||||||
this->engine->ThrowError("please define all properties of a setting (min/max not allowed for booleans)");
|
this->engine->ThrowError("please define all properties of a setting (min/max not allowed for booleans)");
|
||||||
return SQ_ERROR;
|
return SQ_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
config.default_value = medium_value;
|
config.default_value = medium_value;
|
||||||
items |= 0x080;
|
present.Set(ScriptConfigItemKey::DefaultValue);
|
||||||
} else {
|
|
||||||
/* For compatibility, also act like the default sets the easy/medium/hard. */
|
|
||||||
items |= 0x010 | 0x020 | 0x040;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure all properties are defined */
|
/* Make sure all required properties are defined */
|
||||||
uint mask = config.flags.Test(ScriptConfigFlag::Boolean) ? 0x1F3 : 0x1FF;
|
ScriptConfigItemKeys required = {ScriptConfigItemKey::Name, ScriptConfigItemKey::Description, ScriptConfigItemKey::DefaultValue, ScriptConfigItemKey::Flags};
|
||||||
if (items != mask) {
|
if (!config.flags.Test(ScriptConfigFlag::Boolean)) required.Set({ScriptConfigItemKey::MinValue, ScriptConfigItemKey::MaxValue});
|
||||||
|
|
||||||
|
if (!present.All(required)) {
|
||||||
this->engine->ThrowError("please define all properties of a setting (min/max not allowed for booleans)");
|
this->engine->ThrowError("please define all properties of a setting (min/max not allowed for booleans)");
|
||||||
return SQ_ERROR;
|
return SQ_ERROR;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue