Add setting to enable multiple churches/stadiums in scenario editor

See: #177
pull/182/head
Jonathan G Rennison 4 years ago
parent 3dfbeb07f6
commit b7118b60fe

@ -2001,6 +2001,9 @@ STR_CONFIG_OCCUPANCY_SMOOTHNESS_HELPTEXT :0% sets the mea
STR_CONFIG_SETTING_ADVANCE_ORDER_ON_CLONE :Advance order after cloning/copying/sharing: {STRING2}
STR_CONFIG_SETTING_ADVANCE_ORDER_ON_CLONE_HELPTEXT :After cloning a vehicle or copying/sharing orders from an existing vehicle.{}For trains, road vehicles and ships: if the vehicle is in a depot which is in the order list, skip to the order which follows one of the orders for that depot.{}For aircraft: if the aircraft is in a hangar and the associated airport is in the order list, skip to one of the orders for that airport.
STR_CONFIG_SETTING_SCENARIO_MULTIPLE_BUILDINGS :Allow multiple churches/stadiums: {STRING2}
STR_CONFIG_SETTING_SCENARIO_MULTIPLE_BUILDINGS_HELPTEXT :Allow manually adding churches and stadiums when there is already one present in the town.
# Config errors
STR_CONFIG_ERROR :{WHITE}Error with the configuration file...
STR_CONFIG_ERROR_ARRAY :{WHITE}... error in array '{RAW_STRING}'

@ -3773,6 +3773,13 @@ bool AfterLoadGame()
_settings_game.game_creation.generation_unique_id = _interactive_random.Next(UINT32_MAX-1) + 1; /* Generates between [1;UINT32_MAX] */
}
if (SlXvIsFeatureMissing(XSLFI_TOWN_MULTI_BUILDING)) {
for (Town *t : Town::Iterate()) {
t->church_count = HasBit(t->flags, 1) ? 1 : 0;
t->stadium_count = HasBit(t->flags, 2) ? 1 : 0;
}
}
/* This needs to be done after conversion. */
RebuildViewportKdtree();
ViewportMapBuildTunnelCache();

@ -124,6 +124,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
{ XSLFI_STATION_GOODS_EXTRA, XSCF_NULL, 1, 1, "station_goods_extra", nullptr, nullptr, nullptr },
{ XSLFI_DOCKING_CACHE_VER, XSCF_IGNORABLE_ALL, 1, 1, "docking_cache_ver", nullptr, nullptr, nullptr },
{ XSLFI_EXTRA_CHEATS, XSCF_NULL, 1, 1, "extra_cheats", nullptr, nullptr, "CHTX" },
{ XSLFI_TOWN_MULTI_BUILDING, XSCF_NULL, 1, 1, "town_multi_building", nullptr, nullptr, nullptr },
{ XSLFI_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr },// This is the end marker
};

@ -81,6 +81,7 @@ enum SlXvFeatureIndex {
XSLFI_STATION_GOODS_EXTRA, ///< Extra station goods entry statuses
XSLFI_DOCKING_CACHE_VER, ///< Multiple docks - docking tile cache version
XSLFI_EXTRA_CHEATS, ///< Extra cheats
XSLFI_TOWN_MULTI_BUILDING, ///< Allow multiple stadium/church buildings in a single town
XSLFI_RIFF_HEADER_60_BIT, ///< Size field in RIFF chunk header is 60 bit
XSLFI_HEIGHT_8_BIT, ///< Map tile height is 8 bit instead of 4 bit, but savegame version may be before this became true in trunk

@ -130,6 +130,7 @@ static const SaveLoad _town_desc[] = {
SLE_CONDSTR(Town, name, SLE_STR | SLF_ALLOW_CONTROL, 0, SLV_84, SL_MAX_VERSION),
SLE_VAR(Town, flags, SLE_UINT8),
SLE_CONDVAR_X(Town, church_count, SLE_UINT8, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_SPRINGPP)),
SLE_CONDVAR(Town, statues, SLE_FILE_U8 | SLE_VAR_U16, SL_MIN_VERSION, SLV_104),
SLE_CONDVAR(Town, statues, SLE_UINT16, SLV_104, SL_MAX_VERSION),

@ -2011,6 +2011,7 @@ static SettingsContainer &GetSettingsTree()
if (_game_mode != GM_NORMAL) {
SettingsPage *scenario = main->Add(new SettingsPage(STR_CONFIG_SETTING_SCENARIO_EDITOR));
{
scenario->Add(new SettingEntry("scenario.multiple_buildings"));
}
}

@ -661,6 +661,7 @@ struct DebugSettings {
/** Scenario editor settings. */
struct ScenarioSettings {
bool multiple_buildings; ///< allow manually adding more than one church/stadium
};
/** All settings together for the game. */

@ -5327,6 +5327,13 @@ str = STR_CONFIG_SETTING_NEWS_GENERAL_INFORMATION
strhelp = STR_CONFIG_SETTING_NEWS_GENERAL_INFORMATION_HELPTEXT
strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF
[SDTC_BOOL]
var = scenario.multiple_buildings
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
def = false
str = STR_CONFIG_SETTING_SCENARIO_MULTIPLE_BUILDINGS
strhelp = STR_CONFIG_SETTING_SCENARIO_MULTIPLE_BUILDINGS_HELPTEXT
[SDTC_VAR]
var = gui.network_chat_box_width_pct
type = SLE_UINT16

@ -65,6 +65,8 @@ struct Town : TownPool::PoolItem<&_town_pool> {
mutable std::string cached_name; ///< NOSAVE: Cache of the resolved name of the town, if not using a custom town name
byte flags; ///< See #TownFlags.
byte church_count; ///< Number of church buildings in the town.
byte stadium_count; ///< Number of stadium buildings in the town.
uint16 noise_reached; ///< level of noise that all the airports are generating
@ -209,8 +211,8 @@ enum TownDirectoryInvalidateWindowData {
*/
enum TownFlags {
TOWN_IS_GROWING = 0, ///< Conditions for town growth are met. Grow according to Town::growth_rate.
TOWN_HAS_CHURCH = 1, ///< There can be only one church by town.
TOWN_HAS_STADIUM = 2, ///< There can be only one stadium by town.
// TOWN_HAS_CHURCH = 1, ///< There can be only one church per town. Replaced by church_count.
// TOWN_HAS_STADIUM = 2, ///< There can be only one stadium per town. Replaced by stadium_count.
TOWN_CUSTOM_GROWTH = 3, ///< Growth rate is controlled by GS.
};

@ -2605,7 +2605,7 @@ static TileIndex FindPlaceForTownHouseAroundTile(TileIndex tile, Town *t, HouseI
* @param t the town
* @return success if house can be built, error message otherwise
*/
static CommandCost CheckCanBuildHouse(HouseID house, const Town *t)
static CommandCost CheckCanBuildHouse(HouseID house, const Town *t, bool manual)
{
const HouseSpec *hs = HouseSpec::Get(house);
@ -2618,9 +2618,9 @@ static CommandCost CheckCanBuildHouse(HouseID house, const Town *t)
/* Special houses that there can be only one of. */
if (hs->building_flags & BUILDING_IS_CHURCH) {
if (HasBit(t->flags, TOWN_HAS_CHURCH)) return_cmd_error(STR_ERROR_ONLY_ONE_BUILDING_ALLOWED_PER_TOWN);
if (t->church_count >= ((manual && _settings_client.scenario.multiple_buildings) ? 255 : 1)) return_cmd_error(STR_ERROR_ONLY_ONE_BUILDING_ALLOWED_PER_TOWN);
} else if (hs->building_flags & BUILDING_IS_STADIUM) {
if (HasBit(t->flags, TOWN_HAS_STADIUM)) return_cmd_error(STR_ERROR_ONLY_ONE_BUILDING_ALLOWED_PER_TOWN);
if (t->stadium_count >= ((manual && _settings_client.scenario.multiple_buildings) ? 255 : 1)) return_cmd_error(STR_ERROR_ONLY_ONE_BUILDING_ALLOWED_PER_TOWN);
}
return CommandCost();
@ -2642,9 +2642,9 @@ static void DoBuildHouse(Town *t, TileIndex tile, HouseID house, byte random_bit
/* Special houses that there can be only one of. */
if (hs->building_flags & BUILDING_IS_CHURCH) {
SetBit(t->flags, TOWN_HAS_CHURCH);
t->church_count++;
} else if (hs->building_flags & BUILDING_IS_STADIUM) {
SetBit(t->flags, TOWN_HAS_STADIUM);
t->stadium_count++;
}
byte construction_counter = 0;
@ -2696,9 +2696,11 @@ CommandCost CmdBuildHouse(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
int max_z = GetTileMaxZ(tile);
bool above_snowline = (_settings_game.game_creation.landscape == LT_ARCTIC) && (max_z > HighestSnowLine());
bool manual = (_game_mode == GM_EDITOR);
CommandCost ret = IsHouseTypeAllowed(house, above_snowline, TryGetTownRadiusGroup(t, tile));
if (ret.Succeeded()) ret = IsAnotherHouseTypeAllowedInTown(t, house);
if (ret.Succeeded()) ret = CheckCanBuildHouse(house, t);
if (ret.Succeeded()) ret = CheckCanBuildHouse(house, t, manual);
if (ret.Succeeded()) {
/* While placing a house manually, try only at exact position and ignore the layout */
const HouseSpec *hs = HouseSpec::Get(house);
@ -2777,7 +2779,7 @@ static bool BuildTownHouse(Town *t, TileIndex tile)
houses[i] = houses[num];
probs[i] = probs[num];
CommandCost ret = CheckCanBuildHouse(house, t);
CommandCost ret = CheckCanBuildHouse(house, t, false);
if (ret.Failed()) continue;
tile = FindPlaceForTownHouseAroundTile(tile, t, house);
@ -2858,9 +2860,9 @@ void ClearTownHouse(Town *t, TileIndex tile)
/* Clear flags for houses that only may exist once/town. */
if (hs->building_flags & BUILDING_IS_CHURCH) {
ClrBit(t->flags, TOWN_HAS_CHURCH);
t->church_count--;
} else if (hs->building_flags & BUILDING_IS_STADIUM) {
ClrBit(t->flags, TOWN_HAS_STADIUM);
t->stadium_count--;
}
/* Do the actual clearing of tiles */

Loading…
Cancel
Save