mirror of https://github.com/OpenTTD/OpenTTD
Add: "Many random towns" button in scenario editor now prompts for the number of towns, with defaults based on new game settings (#14158)
parent
3eba97f67c
commit
2f020abe74
|
@ -231,7 +231,8 @@ void ChangeTownRating(Town *t, int add, int max, DoCommandFlags flags);
|
|||
HouseZone GetTownRadiusGroup(const Town *t, TileIndex tile);
|
||||
void SetTownRatingTestMode(bool mode);
|
||||
TownActions GetMaskOfTownActions(CompanyID cid, const Town *t);
|
||||
bool GenerateTowns(TownLayout layout);
|
||||
uint GetDefaultTownsForMapSize();
|
||||
bool GenerateTowns(TownLayout layout, std::optional<uint> number = std::nullopt);
|
||||
const CargoSpec *FindFirstCargoWithTownAcceptanceEffect(TownAcceptanceEffect effect);
|
||||
CargoArray GetAcceptedCargoOfHouse(const HouseSpec *hs);
|
||||
|
||||
|
|
|
@ -2372,19 +2372,39 @@ static Town *CreateRandomTown(uint attempts, uint32_t townnameparts, TownSize si
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
static const uint8_t _num_initial_towns[4] = {5, 11, 23, 46}; // very low, low, normal, high
|
||||
/**
|
||||
* Calculate the number of towns which should be on the map according to the current "town density" newgame setting and the map size.
|
||||
* If the number of towns is set to "custom", the function will always return that value instead.
|
||||
* @return The number of towns.
|
||||
*/
|
||||
uint GetDefaultTownsForMapSize()
|
||||
{
|
||||
static const uint8_t num_initial_towns[4] = {5, 11, 23, 46}; // very low, low, normal, high
|
||||
if (_settings_game.difficulty.number_towns == static_cast<uint>(CUSTOM_TOWN_NUMBER_DIFFICULTY)) {
|
||||
return _settings_newgame.game_creation.custom_town_number;
|
||||
}
|
||||
return Map::ScaleBySize(num_initial_towns[_settings_game.difficulty.number_towns]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a number of towns with a given layout.
|
||||
* This function is used by the Random Towns button in Scenario Editor as well as in world generation.
|
||||
* @param layout The road layout to build.
|
||||
* @param number The number of towns to create. std::nullopt means to use the game settings.
|
||||
* @return true if towns have been successfully created.
|
||||
*/
|
||||
bool GenerateTowns(TownLayout layout)
|
||||
bool GenerateTowns(TownLayout layout, std::optional<uint> number)
|
||||
{
|
||||
uint current_number = 0;
|
||||
uint difficulty = (_game_mode != GM_EDITOR) ? _settings_game.difficulty.number_towns : 0;
|
||||
uint total = (difficulty == (uint)CUSTOM_TOWN_NUMBER_DIFFICULTY) ? _settings_game.game_creation.custom_town_number : Map::ScaleBySize(_num_initial_towns[difficulty] + (Random() & 7));
|
||||
uint total;
|
||||
if (number.has_value()) {
|
||||
total = number.value();
|
||||
} else if (_settings_game.difficulty.number_towns == static_cast<uint>(CUSTOM_TOWN_NUMBER_DIFFICULTY)) {
|
||||
total = GetDefaultTownsForMapSize();
|
||||
} else {
|
||||
total = GetDefaultTownsForMapSize() + (Random() & 7);
|
||||
}
|
||||
|
||||
total = std::min<uint>(TownPool::MAX_SIZE, total);
|
||||
uint32_t townnameparts;
|
||||
TownNames town_names;
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "townname_func.h"
|
||||
#include "core/backup_type.hpp"
|
||||
#include "core/geometry_func.hpp"
|
||||
#include "core/string_consumer.hpp"
|
||||
#include "genworld.h"
|
||||
#include "fios.h"
|
||||
#include "stringfilter_type.h"
|
||||
|
@ -1249,16 +1250,10 @@ public:
|
|||
break;
|
||||
|
||||
case WID_TF_MANY_RANDOM_TOWNS: {
|
||||
Backup<bool> old_generating_world(_generating_world, true);
|
||||
UpdateNearestTownForRoadTiles(true);
|
||||
if (!GenerateTowns(this->town_layout)) {
|
||||
ShowErrorMessage(GetEncodedString(STR_ERROR_CAN_T_GENERATE_TOWN), GetEncodedString(STR_ERROR_NO_SPACE_FOR_TOWN), WL_INFO);
|
||||
}
|
||||
UpdateNearestTownForRoadTiles(false);
|
||||
old_generating_world.Restore();
|
||||
std::string default_town_number = fmt::format("{}", GetDefaultTownsForMapSize());
|
||||
ShowQueryString(default_town_number, STR_MAPGEN_NUMBER_OF_TOWNS, 5, this, CS_NUMERAL, {QueryStringFlag::AcceptUnchanged});
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_TF_LOAD_FROM_FILE:
|
||||
ShowSaveLoadDialog(FT_TOWN_DATA, SLO_LOAD);
|
||||
break;
|
||||
|
@ -1293,6 +1288,23 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
void OnQueryTextFinished(std::optional<std::string> str) override
|
||||
{
|
||||
/* Was 'cancel' pressed? */
|
||||
if (!str.has_value()) return;
|
||||
|
||||
auto value = ParseInteger(*str);
|
||||
if (!value.has_value()) return;
|
||||
|
||||
Backup<bool> old_generating_world(_generating_world, true);
|
||||
UpdateNearestTownForRoadTiles(true);
|
||||
if (!GenerateTowns(this->town_layout, value)) {
|
||||
ShowErrorMessage(GetEncodedString(STR_ERROR_CAN_T_GENERATE_TOWN), GetEncodedString(STR_ERROR_NO_SPACE_FOR_TOWN), WL_INFO);
|
||||
}
|
||||
UpdateNearestTownForRoadTiles(false);
|
||||
old_generating_world.Restore();
|
||||
}
|
||||
|
||||
void OnPlaceObject([[maybe_unused]] Point pt, TileIndex tile) override
|
||||
{
|
||||
this->ExecuteFoundTownCommand(tile, false, STR_ERROR_CAN_T_FOUND_TOWN_HERE, CcFoundTown);
|
||||
|
|
Loading…
Reference in New Issue