1
0
Fork 0

Compare commits

...

5 Commits

Author SHA1 Message Date
SamuXarick c17cc1c630
Merge 3c56c0fe2e into 67e56391c7 2025-07-14 22:25:02 +00:00
Peter Nelson 67e56391c7
Fix #8167: No error sub-message when trying to clear protected buildings. (#14444) 2025-07-14 23:23:15 +01:00
Peter Nelson e015e3ecc3
Codefix 3fde611012: AirportMovingDataFlag should be `enum class` (#14435)
`AirportMovingDataFlag` was changed to use `enum class` naming style, but wasn't actually changed to be `enum class`.
2025-07-14 23:22:51 +01:00
Henry Wilson 8330957a4d Codechange: Remove manual memory management from IcuStringIterator 2025-07-14 23:55:24 +02:00
SamuXarick 3c56c0fe2e Add: [Script] Default button in query string to reset an integer setting 2025-06-08 23:15:20 +01:00
8 changed files with 64 additions and 21 deletions

View File

@ -44,7 +44,7 @@ enum AirportTypes : uint8_t {
};
/** Flags for airport movement data. */
enum AirportMovingDataFlag : uint8_t {
enum class AirportMovingDataFlag : uint8_t {
NoSpeedClamp, ///< No speed restrictions.
Takeoff, ///< Takeoff movement.
SlowTurn, ///< Turn slowly (mostly used in the air).

View File

@ -325,7 +325,7 @@ struct GSConfigWindow : public Window {
}
} else if (!bool_item && !config_item.complete_labels) {
/* Display a query box so users can enter a custom value. */
ShowQueryString(GetString(STR_JUST_INT, old_val), STR_CONFIG_SETTING_QUERY_CAPTION, INT32_DIGITS_WITH_SIGN_AND_TERMINATION, this, CS_NUMERAL_SIGNED, {});
ShowQueryString(GetString(STR_JUST_INT, old_val), STR_CONFIG_SETTING_QUERY_CAPTION, INT32_DIGITS_WITH_SIGN_AND_TERMINATION, this, CS_NUMERAL_SIGNED, QueryStringFlag::EnableDefault);
}
this->SetDirty();
break;
@ -347,10 +347,17 @@ struct GSConfigWindow : public Window {
void OnQueryTextFinished(std::optional<std::string> str) override
{
/* The user pressed cancel */
if (!str.has_value()) return;
auto value = ParseInteger<int32_t>(*str, 10, true);
if (!value.has_value()) return;
this->SetValue(*value);
if (!str->empty()) {
auto value = ParseInteger<int32_t>(*str, 10, true);
if (!value.has_value()) return;
this->SetValue(*value);
} else {
this->SetDefaultValue();
}
}
void OnDropdownSelect(WidgetID widget, int index, int) override
@ -419,6 +426,14 @@ private:
this->gs_config->SetSetting(config_item.name, value);
this->SetDirty();
}
void SetDefaultValue()
{
const ScriptConfigItem &config_item = *this->visible_settings[this->clicked_row];
if (_game_mode == GM_NORMAL && !config_item.flags.Test(ScriptConfigFlag::InGame)) return;
this->gs_config->ResetSetting(config_item.name);
this->SetDirty();
}
};
/** Open the GS config window. */

View File

@ -5001,6 +5001,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}Flat lan
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Land sloped in wrong direction
STR_ERROR_CAN_T_DO_THIS :{WHITE}Can't do this...
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Building must be demolished first
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}... building is protected
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Can't clear this area...
STR_ERROR_SITE_UNSUITABLE :{WHITE}... site unsuitable
STR_ERROR_ALREADY_BUILT :{WHITE}... already built

View File

@ -106,6 +106,16 @@ void ScriptConfig::ResetSettings()
this->settings.clear();
}
void ScriptConfig::ResetSetting(std::string_view name)
{
if (this->info == nullptr) return;
const ScriptConfigItem *config_item = this->info->GetConfigItem(name);
if (config_item == nullptr) return;
this->settings.erase(std::string{name});
}
void ScriptConfig::ResetEditableSettings(bool yet_to_start)
{
if (this->info == nullptr) return ResetSettings();

View File

@ -129,6 +129,11 @@ public:
*/
void ResetSettings();
/**
* Reset a setting to its default value.
*/
void ResetSetting(std::string_view name);
/**
* Reset only editable and visible settings to their default value.
*/

View File

@ -470,7 +470,7 @@ struct ScriptSettingsWindow : public Window {
}
} else if (!bool_item && !config_item.complete_labels) {
/* Display a query box so users can enter a custom value. */
ShowQueryString(GetString(STR_JUST_INT, old_val), STR_CONFIG_SETTING_QUERY_CAPTION, INT32_DIGITS_WITH_SIGN_AND_TERMINATION, this, CS_NUMERAL_SIGNED, {});
ShowQueryString(GetString(STR_JUST_INT, old_val), STR_CONFIG_SETTING_QUERY_CAPTION, INT32_DIGITS_WITH_SIGN_AND_TERMINATION, this, CS_NUMERAL_SIGNED, QueryStringFlag::EnableDefault);
}
this->SetDirty();
break;
@ -485,10 +485,17 @@ struct ScriptSettingsWindow : public Window {
void OnQueryTextFinished(std::optional<std::string> str) override
{
/* The user pressed cancel */
if (!str.has_value()) return;
auto value = ParseInteger<int32_t>(*str, 10, true);
if (!value.has_value()) return;
this->SetValue(*value);
if (!str->empty()) {
auto value = ParseInteger<int32_t>(*str, 10, true);
if (!value.has_value()) return;
this->SetValue(*value);
} else {
this->SetDefaultValue();
}
}
void OnDropdownSelect(WidgetID widget, int index, int) override
@ -552,6 +559,14 @@ private:
this->script_config->SetSetting(config_item.name, value);
this->SetDirty();
}
void SetDefaultValue()
{
const ScriptConfigItem &config_item = *this->visible_settings[this->clicked_row];
if (_game_mode == GM_NORMAL && ((this->slot == OWNER_DEITY) || Company::IsValidID(this->slot)) && !config_item.flags.Test(ScriptConfigFlag::InGame)) return;
this->script_config->ResetSetting(config_item.name);
this->SetDirty();
}
};
/** Widgets for the Script settings window. */

View File

@ -607,28 +607,25 @@ bool ConvertHexToBytes(std::string_view hex, std::span<uint8_t> bytes)
/** String iterator using ICU as a backend. */
class IcuStringIterator : public StringIterator
{
icu::BreakIterator *char_itr; ///< ICU iterator for characters.
icu::BreakIterator *word_itr; ///< ICU iterator for words.
std::unique_ptr<icu::BreakIterator> char_itr; ///< ICU iterator for characters.
std::unique_ptr<icu::BreakIterator> word_itr; ///< ICU iterator for words.
std::vector<UChar> utf16_str; ///< UTF-16 copy of the string.
std::vector<size_t> utf16_to_utf8; ///< Mapping from UTF-16 code point position to index in the UTF-8 source string.
public:
IcuStringIterator() : char_itr(nullptr), word_itr(nullptr)
IcuStringIterator()
{
UErrorCode status = U_ZERO_ERROR;
this->char_itr = icu::BreakIterator::createCharacterInstance(icu::Locale(_current_language != nullptr ? _current_language->isocode : "en"), status);
this->word_itr = icu::BreakIterator::createWordInstance(icu::Locale(_current_language != nullptr ? _current_language->isocode : "en"), status);
auto locale = icu::Locale(_current_language != nullptr ? _current_language->isocode : "en");
this->char_itr.reset(icu::BreakIterator::createCharacterInstance(locale, status));
this->word_itr.reset(icu::BreakIterator::createWordInstance(locale, status));
this->utf16_str.push_back('\0');
this->utf16_to_utf8.push_back(0);
}
~IcuStringIterator() override
{
delete this->char_itr;
delete this->word_itr;
}
~IcuStringIterator() override = default;
void SetString(std::string_view s) override
{

View File

@ -710,7 +710,7 @@ static void TileLoop_Town(TileIndex tile)
static CommandCost ClearTile_Town(TileIndex tile, DoCommandFlags flags)
{
if (flags.Test(DoCommandFlag::Auto)) return CommandCost(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
if (!CanDeleteHouse(tile)) return CMD_ERROR;
if (!CanDeleteHouse(tile)) return CommandCost(STR_ERROR_BUILDING_IS_PROTECTED);
const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
@ -724,7 +724,7 @@ static CommandCost ClearTile_Town(TileIndex tile, DoCommandFlags flags)
if (!_cheats.magic_bulldozer.value && !flags.Test(DoCommandFlag::NoTestTownRating)) {
/* NewGRFs can add indestructible houses. */
if (rating > RATING_MAXIMUM) {
return CommandCost(CMD_ERROR);
return CommandCost(STR_ERROR_BUILDING_IS_PROTECTED);
}
/* If town authority controls removal, check the company's rating. */
if (rating > t->ratings[_current_company] && _settings_game.difficulty.town_council_tolerance != TOWN_COUNCIL_PERMISSIVE) {