mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-06-18 19:19:29 +01:00
Add: Allow separate expansion of town buildings and roads in scenario editor. (#14341)
This commit is contained in:
parent
6b5cde463a
commit
ecafbf884e
@ -501,7 +501,7 @@ void LoadTownData()
|
||||
|
||||
do {
|
||||
uint before = t->cache.num_houses;
|
||||
Command<CMD_EXPAND_TOWN>::Post(t->index, HOUSES_TO_GROW);
|
||||
Command<CMD_EXPAND_TOWN>::Post(t->index, HOUSES_TO_GROW, {TownExpandMode::Buildings, TownExpandMode::Roads});
|
||||
if (t->cache.num_houses <= before) fail_limit--;
|
||||
} while (fail_limit > 0 && try_limit-- > 0 && t->cache.population < population);
|
||||
}
|
||||
|
@ -3073,6 +3073,12 @@ STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP :{BLACK}Select t
|
||||
STR_FOUND_TOWN_CITY :{BLACK}City
|
||||
STR_FOUND_TOWN_CITY_TOOLTIP :{BLACK}Cities grow faster than regular towns{}Depending on settings, they are bigger when founded
|
||||
|
||||
STR_FOUND_TOWN_EXPAND_MODE :{YELLOW}Town expansion:
|
||||
STR_FOUND_TOWN_EXPAND_BUILDINGS :Buildings
|
||||
STR_FOUND_TOWN_EXPAND_BUILDINGS_TOOLTIP :Increase buildings of towns
|
||||
STR_FOUND_TOWN_EXPAND_ROADS :Roads
|
||||
STR_FOUND_TOWN_EXPAND_ROADS_TOOLTIP :Increase roads of towns
|
||||
|
||||
STR_FOUND_TOWN_ROAD_LAYOUT :{YELLOW}Town road layout:
|
||||
STR_FOUND_TOWN_SELECT_LAYOUT_TOOLTIP :{BLACK}Select road layout used for this town
|
||||
STR_FOUND_TOWN_SELECT_LAYOUT_ORIGINAL :{BLACK}Original
|
||||
@ -3696,6 +3702,10 @@ STR_TOWN_VIEW_RENAME_TOOLTIP :{BLACK}Change t
|
||||
|
||||
STR_TOWN_VIEW_EXPAND_BUTTON :{BLACK}Expand
|
||||
STR_TOWN_VIEW_EXPAND_TOOLTIP :{BLACK}Increase size of town
|
||||
STR_TOWN_VIEW_EXPAND_BUILDINGS_BUTTON :{BLACK}Expand buildings
|
||||
STR_TOWN_VIEW_EXPAND_BUILDINGS_TOOLTIP :{BLACK}Increase buildings of town
|
||||
STR_TOWN_VIEW_EXPAND_ROADS_BUTTON :{BLACK}Expand roads
|
||||
STR_TOWN_VIEW_EXPAND_ROADS_TOOLTIP :{BLACK}Increase roads of town
|
||||
STR_TOWN_VIEW_DELETE_BUTTON :{BLACK}Delete
|
||||
STR_TOWN_VIEW_DELETE_TOOLTIP :{BLACK}Delete this town completely
|
||||
|
||||
|
@ -278,7 +278,7 @@
|
||||
|
||||
houses = std::min<SQInteger>(houses, UINT32_MAX);
|
||||
|
||||
return ScriptObject::Command<CMD_EXPAND_TOWN>::Do(town_id, houses);
|
||||
return ScriptObject::Command<CMD_EXPAND_TOWN>::Do(town_id, houses, {TownExpandMode::Buildings, TownExpandMode::Roads});
|
||||
}
|
||||
|
||||
/* static */ bool ScriptTown::FoundTown(TileIndex tile, TownSize size, bool city, RoadLayout layout, Text *name)
|
||||
|
@ -228,7 +228,7 @@ Money HouseSpec::GetRemovalCost() const
|
||||
return (_price[PR_CLEAR_HOUSE] * this->removal_cost) >> 8;
|
||||
}
|
||||
|
||||
static bool TryBuildTownHouse(Town *t, TileIndex tile);
|
||||
static bool TryBuildTownHouse(Town *t, TileIndex tile, TownExpandModes modes);
|
||||
static Town *CreateRandomTown(uint attempts, uint32_t townnameparts, TownSize size, bool city, TownLayout layout);
|
||||
|
||||
static void TownDrawHouseLift(const TileInfo *ti)
|
||||
@ -691,7 +691,10 @@ static void TileLoop_Town(TileIndex tile)
|
||||
}
|
||||
}
|
||||
|
||||
TryBuildTownHouse(t, tile);
|
||||
TownExpandModes modes{TownExpandMode::Buildings};
|
||||
if (_settings_game.economy.allow_town_roads) modes.Set(TownExpandMode::Roads);
|
||||
|
||||
TryBuildTownHouse(t, tile, modes);
|
||||
}
|
||||
}
|
||||
|
||||
@ -902,7 +905,7 @@ static void ChangeTileOwner_Town(TileIndex, Owner, Owner)
|
||||
/* not used */
|
||||
}
|
||||
|
||||
static bool GrowTown(Town *t);
|
||||
static bool GrowTown(Town *t, TownExpandModes modes);
|
||||
|
||||
/**
|
||||
* Handle the town tick for a single town, by growing the town if desired.
|
||||
@ -911,9 +914,11 @@ static bool GrowTown(Town *t);
|
||||
static void TownTickHandler(Town *t)
|
||||
{
|
||||
if (HasBit(t->flags, TOWN_IS_GROWING)) {
|
||||
TownExpandModes modes{TownExpandMode::Buildings};
|
||||
if (_settings_game.economy.allow_town_roads) modes.Set(TownExpandMode::Roads);
|
||||
int i = (int)t->grow_counter - 1;
|
||||
if (i < 0) {
|
||||
if (GrowTown(t)) {
|
||||
if (GrowTown(t, modes)) {
|
||||
i = t->growth_rate;
|
||||
} else {
|
||||
/* If growth failed wait a bit before retrying */
|
||||
@ -1204,7 +1209,7 @@ static RoadBits GetTownRoadGridElement(Town *t, TileIndex tile, DiagDirection di
|
||||
* @param tile The target tile for the extra house.
|
||||
* @return true if an extra house has been added.
|
||||
*/
|
||||
static bool GrowTownWithExtraHouse(Town *t, TileIndex tile)
|
||||
static bool GrowTownWithExtraHouse(Town *t, TileIndex tile, TownExpandModes modes)
|
||||
{
|
||||
/* We can't look further than that. */
|
||||
if (DistanceFromEdge(tile) == 0) return false;
|
||||
@ -1228,7 +1233,7 @@ static bool GrowTownWithExtraHouse(Town *t, TileIndex tile)
|
||||
|
||||
/* If there are enough neighbours stop here */
|
||||
if (counter >= 3) {
|
||||
return TryBuildTownHouse(t, tile);
|
||||
return TryBuildTownHouse(t, tile, modes);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@ -1498,9 +1503,9 @@ static bool TownCanGrowRoad(TileIndex tile)
|
||||
* Check if the town is allowed to build roads.
|
||||
* @return true If the town is allowed to build roads.
|
||||
*/
|
||||
static inline bool TownAllowedToBuildRoads()
|
||||
static inline bool TownAllowedToBuildRoads(TownExpandModes modes)
|
||||
{
|
||||
return _settings_game.economy.allow_town_roads || _generating_world || _game_mode == GM_EDITOR;
|
||||
return modes.Test(TownExpandMode::Roads);
|
||||
}
|
||||
|
||||
/* The possible states of town growth. */
|
||||
@ -1528,7 +1533,7 @@ enum class TownGrowthResult {
|
||||
* @param t1 The current town
|
||||
* @return Result so far.
|
||||
*/
|
||||
static TownGrowthResult GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection target_dir, Town *t1)
|
||||
static TownGrowthResult GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection target_dir, Town *t1, TownExpandModes modes)
|
||||
{
|
||||
RoadBits rcmd = ROAD_NONE; // RoadBits for the road construction command
|
||||
TileIndex tile = *tile_ptr; // The main tile on which we base our growth
|
||||
@ -1539,7 +1544,7 @@ static TownGrowthResult GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, Dia
|
||||
/* Tile has no road.
|
||||
* We will return TownGrowthResult::SearchStopped to say that this is the last iteration. */
|
||||
|
||||
if (!TownAllowedToBuildRoads()) return TownGrowthResult::SearchStopped;
|
||||
if (!TownAllowedToBuildRoads(modes)) return TownGrowthResult::SearchStopped;
|
||||
if (!_settings_game.economy.allow_town_level_crossings && IsTileType(tile, MP_RAILWAY)) return TownGrowthResult::SearchStopped;
|
||||
|
||||
/* Remove hills etc */
|
||||
@ -1588,7 +1593,7 @@ static TownGrowthResult GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, Dia
|
||||
} else if (target_dir < DIAGDIR_END && !(cur_rb & DiagDirToRoadBits(ReverseDiagDir(target_dir)))) {
|
||||
if (!TownCanGrowRoad(tile)) return TownGrowthResult::Continue;
|
||||
|
||||
if (!TownAllowedToBuildRoads()) return TownGrowthResult::SearchStopped;
|
||||
if (!TownAllowedToBuildRoads(modes)) return TownGrowthResult::SearchStopped;
|
||||
|
||||
/* Continue building on a partial road.
|
||||
* Should be always OK, so we only generate
|
||||
@ -1664,12 +1669,12 @@ static TownGrowthResult GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, Dia
|
||||
|
||||
TownGrowthResult result = TownGrowthResult::Continue;
|
||||
|
||||
if (target_dir != DIAGDIR_END && TownAllowedToBuildRoads()) {
|
||||
if (target_dir != DIAGDIR_END && TownAllowedToBuildRoads(modes)) {
|
||||
switch (t1->layout) {
|
||||
default: NOT_REACHED();
|
||||
|
||||
case TL_3X3_GRID: // Use 2x2 grid afterwards!
|
||||
if (GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir))) {
|
||||
if (GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir), modes)) {
|
||||
result = TownGrowthResult::Succeed;
|
||||
}
|
||||
[[fallthrough]];
|
||||
@ -1680,7 +1685,7 @@ static TownGrowthResult GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, Dia
|
||||
break;
|
||||
|
||||
case TL_BETTER_ROADS: // Use original afterwards!
|
||||
if (GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir))) {
|
||||
if (GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir), modes)) {
|
||||
result = TownGrowthResult::Succeed;
|
||||
}
|
||||
[[fallthrough]];
|
||||
@ -1704,7 +1709,7 @@ static TownGrowthResult GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, Dia
|
||||
|
||||
/* And build a house.
|
||||
* Set result to -1 if we managed to build it. */
|
||||
if (TryBuildTownHouse(t1, house_tile)) {
|
||||
if (TryBuildTownHouse(t1, house_tile, modes)) {
|
||||
result = TownGrowthResult::Succeed;
|
||||
}
|
||||
}
|
||||
@ -1744,14 +1749,14 @@ static TownGrowthResult GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, Dia
|
||||
* @param dir Direction for road to follow or build.
|
||||
* @return true If road is or can be connected in the specified direction.
|
||||
*/
|
||||
static bool CanFollowRoad(TileIndex tile, DiagDirection dir)
|
||||
static bool CanFollowRoad(TileIndex tile, DiagDirection dir, TownExpandModes modes)
|
||||
{
|
||||
TileIndex target_tile = tile + TileOffsByDiagDir(dir);
|
||||
if (!IsValidTile(target_tile)) return false;
|
||||
if (HasTileWaterGround(target_tile)) return false;
|
||||
|
||||
RoadBits target_rb = GetTownRoadBits(target_tile);
|
||||
if (TownAllowedToBuildRoads()) {
|
||||
if (TownAllowedToBuildRoads(modes)) {
|
||||
/* Check whether a road connection exists or can be build. */
|
||||
switch (GetTileType(target_tile)) {
|
||||
case MP_ROAD:
|
||||
@ -1786,7 +1791,7 @@ static bool CanFollowRoad(TileIndex tile, DiagDirection dir)
|
||||
* @param tile The road tile to try growing from.
|
||||
* @return true if we successfully expanded the town.
|
||||
*/
|
||||
static bool GrowTownAtRoad(Town *t, TileIndex tile)
|
||||
static bool GrowTownAtRoad(Town *t, TileIndex tile, TownExpandModes modes)
|
||||
{
|
||||
/* Special case.
|
||||
* @see GrowTownInTile Check the else if
|
||||
@ -1818,7 +1823,7 @@ static bool GrowTownAtRoad(Town *t, TileIndex tile)
|
||||
RoadBits cur_rb = GetTownRoadBits(tile); // The RoadBits of the current tile
|
||||
|
||||
/* Try to grow the town from this point */
|
||||
switch (GrowTownInTile(&tile, cur_rb, target_dir, t)) {
|
||||
switch (GrowTownInTile(&tile, cur_rb, target_dir, t, modes)) {
|
||||
case TownGrowthResult::Succeed:
|
||||
return true;
|
||||
case TownGrowthResult::SearchStopped:
|
||||
@ -1847,7 +1852,7 @@ static bool GrowTownAtRoad(Town *t, TileIndex tile)
|
||||
target_bits = DiagDirToRoadBits(target_dir);
|
||||
} while (!(cur_rb & target_bits));
|
||||
cur_rb &= ~target_bits;
|
||||
} while (!CanFollowRoad(tile, target_dir));
|
||||
} while (!CanFollowRoad(tile, target_dir, modes));
|
||||
}
|
||||
tile = TileAddByDiagDir(tile, target_dir);
|
||||
|
||||
@ -1890,7 +1895,7 @@ static RoadBits GenRandomRoadBits()
|
||||
* @param t The town to grow
|
||||
* @return true if we successfully grew the town with a road or house.
|
||||
*/
|
||||
static bool GrowTown(Town *t)
|
||||
static bool GrowTown(Town *t, TownExpandModes modes)
|
||||
{
|
||||
static const TileIndexDiffC _town_coord_mod[] = {
|
||||
{-1, 0},
|
||||
@ -1916,7 +1921,7 @@ static bool GrowTown(Town *t)
|
||||
/* Find a road that we can base the construction on. */
|
||||
for (const auto &ptr : _town_coord_mod) {
|
||||
if (GetTownRoadBits(tile) != ROAD_NONE) {
|
||||
bool success = GrowTownAtRoad(t, tile);
|
||||
bool success = GrowTownAtRoad(t, tile, modes);
|
||||
cur_company.Restore();
|
||||
return success;
|
||||
}
|
||||
@ -1925,7 +1930,7 @@ static bool GrowTown(Town *t)
|
||||
|
||||
/* No road available, try to build a random road block by
|
||||
* clearing some land and then building a road there. */
|
||||
if (TownAllowedToBuildRoads()) {
|
||||
if (TownAllowedToBuildRoads(modes)) {
|
||||
tile = t->xy;
|
||||
for (const auto &ptr : _town_coord_mod) {
|
||||
/* Only work with plain land that not already has a house */
|
||||
@ -2084,7 +2089,7 @@ static void DoCreateTown(Town *t, TileIndex tile, uint32_t townnameparts, TownSi
|
||||
|
||||
int i = x * 4;
|
||||
do {
|
||||
GrowTown(t);
|
||||
GrowTown(t, {TownExpandMode::Buildings, TownExpandMode::Roads});
|
||||
} while (--i);
|
||||
|
||||
t->UpdateVirtCoord();
|
||||
@ -2605,10 +2610,12 @@ static bool CheckFree2x2Area(TileIndex tile, int z, bool noslope)
|
||||
* @return true iff town layout allows building here.
|
||||
* @note see layouts
|
||||
*/
|
||||
static inline bool TownLayoutAllowsHouseHere(Town *t, TileIndex tile)
|
||||
static inline bool TownLayoutAllowsHouseHere(Town *t, TileIndex tile, TownExpandModes modes)
|
||||
{
|
||||
if (!modes.Test(TownExpandMode::Buildings)) return false;
|
||||
|
||||
/* Allow towns everywhere when we don't build roads */
|
||||
if (!TownAllowedToBuildRoads()) return true;
|
||||
if (!TownAllowedToBuildRoads(modes)) return true;
|
||||
|
||||
TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
|
||||
|
||||
@ -2636,10 +2643,12 @@ static inline bool TownLayoutAllowsHouseHere(Town *t, TileIndex tile)
|
||||
* @return true iff town layout allows a 2x2 building here.
|
||||
* @note see layouts
|
||||
*/
|
||||
static inline bool TownLayoutAllows2x2HouseHere(Town *t, TileIndex tile)
|
||||
static inline bool TownLayoutAllows2x2HouseHere(Town *t, TileIndex tile, TownExpandModes modes)
|
||||
{
|
||||
if (!modes.Test(TownExpandMode::Buildings)) return false;
|
||||
|
||||
/* Allow towns everywhere when we don't build roads */
|
||||
if (!TownAllowedToBuildRoads()) return true;
|
||||
if (!TownAllowedToBuildRoads(modes)) return true;
|
||||
|
||||
/* Compute relative position of tile. (Positive offsets are towards north) */
|
||||
TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
|
||||
@ -2673,15 +2682,15 @@ static inline bool TownLayoutAllows2x2HouseHere(Town *t, TileIndex tile)
|
||||
* @param noslope Are foundations disallowed for this house?
|
||||
* @param second The diagdir from the first tile to the second tile.
|
||||
*/
|
||||
static bool CheckTownBuild2House(TileIndex *tile, Town *t, int maxz, bool noslope, DiagDirection second)
|
||||
static bool CheckTownBuild2House(TileIndex *tile, Town *t, int maxz, bool noslope, DiagDirection second, TownExpandModes modes)
|
||||
{
|
||||
/* 'tile' is already checked in BuildTownHouse() - CanBuildHouseHere() and slope test */
|
||||
|
||||
TileIndex tile2 = *tile + TileOffsByDiagDir(second);
|
||||
if (TownLayoutAllowsHouseHere(t, tile2) && CheckBuildHouseSameZ(tile2, maxz, noslope)) return true;
|
||||
if (TownLayoutAllowsHouseHere(t, tile2, modes) && CheckBuildHouseSameZ(tile2, maxz, noslope)) return true;
|
||||
|
||||
tile2 = *tile + TileOffsByDiagDir(ReverseDiagDir(second));
|
||||
if (TownLayoutAllowsHouseHere(t, tile2) && CheckBuildHouseSameZ(tile2, maxz, noslope)) {
|
||||
if (TownLayoutAllowsHouseHere(t, tile2, modes) && CheckBuildHouseSameZ(tile2, maxz, noslope)) {
|
||||
*tile = tile2;
|
||||
return true;
|
||||
}
|
||||
@ -2698,12 +2707,12 @@ static bool CheckTownBuild2House(TileIndex *tile, Town *t, int maxz, bool noslop
|
||||
* @param maxz The maximum Z level, since all tiles must have the same height.
|
||||
* @param noslope Are foundations disallowed for this house?
|
||||
*/
|
||||
static bool CheckTownBuild2x2House(TileIndex *tile, Town *t, int maxz, bool noslope)
|
||||
static bool CheckTownBuild2x2House(TileIndex *tile, Town *t, int maxz, bool noslope, TownExpandModes modes)
|
||||
{
|
||||
TileIndex tile2 = *tile;
|
||||
|
||||
for (DiagDirection d = DIAGDIR_SE;; d++) { // 'd' goes through DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_END
|
||||
if (TownLayoutAllows2x2HouseHere(t, tile2) && CheckFree2x2Area(tile2, maxz, noslope)) {
|
||||
if (TownLayoutAllows2x2HouseHere(t, tile2, modes) && CheckFree2x2Area(tile2, maxz, noslope)) {
|
||||
*tile = tile2;
|
||||
return true;
|
||||
}
|
||||
@ -2763,10 +2772,10 @@ static void BuildTownHouse(Town *t, TileIndex tile, const HouseSpec *hs, HouseID
|
||||
* @param tile The tile to try building on.
|
||||
* @return false iff no house can be built on this tile.
|
||||
*/
|
||||
static bool TryBuildTownHouse(Town *t, TileIndex tile)
|
||||
static bool TryBuildTownHouse(Town *t, TileIndex tile, TownExpandModes modes)
|
||||
{
|
||||
/* forbidden building here by town layout */
|
||||
if (!TownLayoutAllowsHouseHere(t, tile)) return false;
|
||||
if (!TownLayoutAllowsHouseHere(t, tile, modes)) return false;
|
||||
|
||||
/* no house allowed at all, bail out */
|
||||
if (!CanBuildHouseHere(tile, false)) return false;
|
||||
@ -2860,11 +2869,11 @@ static bool TryBuildTownHouse(Town *t, TileIndex tile)
|
||||
if (noslope && slope != SLOPE_FLAT) continue;
|
||||
|
||||
if (hs->building_flags.Test(BuildingFlag::Size2x2)) {
|
||||
if (!CheckTownBuild2x2House(&tile, t, maxz, noslope)) continue;
|
||||
if (!CheckTownBuild2x2House(&tile, t, maxz, noslope, modes)) continue;
|
||||
} else if (hs->building_flags.Test(BuildingFlag::Size2x1)) {
|
||||
if (!CheckTownBuild2House(&tile, t, maxz, noslope, DIAGDIR_SW)) continue;
|
||||
if (!CheckTownBuild2House(&tile, t, maxz, noslope, DIAGDIR_SW, modes)) continue;
|
||||
} else if (hs->building_flags.Test(BuildingFlag::Size1x2)) {
|
||||
if (!CheckTownBuild2House(&tile, t, maxz, noslope, DIAGDIR_SE)) continue;
|
||||
if (!CheckTownBuild2House(&tile, t, maxz, noslope, DIAGDIR_SE, modes)) continue;
|
||||
} else {
|
||||
/* 1x1 house checks are already done */
|
||||
}
|
||||
@ -3199,9 +3208,10 @@ CommandCost CmdTownRating(DoCommandFlags flags, TownID town_id, CompanyID compan
|
||||
* @param grow_amount Amount to grow, or 0 to grow a random size up to the current amount of houses.
|
||||
* @return Empty cost or an error.
|
||||
*/
|
||||
CommandCost CmdExpandTown(DoCommandFlags flags, TownID town_id, uint32_t grow_amount)
|
||||
CommandCost CmdExpandTown(DoCommandFlags flags, TownID town_id, uint32_t grow_amount, TownExpandModes modes)
|
||||
{
|
||||
if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY) return CMD_ERROR;
|
||||
if (modes.None()) return CMD_ERROR;
|
||||
Town *t = Town::GetIfValid(town_id);
|
||||
if (t == nullptr) return CMD_ERROR;
|
||||
|
||||
@ -3213,13 +3223,13 @@ CommandCost CmdExpandTown(DoCommandFlags flags, TownID town_id, uint32_t grow_am
|
||||
UpdateTownRadius(t);
|
||||
|
||||
uint n = amount * 10;
|
||||
do GrowTown(t); while (--n);
|
||||
do GrowTown(t, modes); while (--n);
|
||||
|
||||
t->cache.num_houses -= amount;
|
||||
} else {
|
||||
for (; grow_amount > 0; grow_amount--) {
|
||||
/* Try several times to grow, as we are really suppose to grow */
|
||||
for (uint i = 0; i < 25; i++) if (GrowTown(t)) break;
|
||||
for (uint i = 0; i < 25; i++) if (GrowTown(t, modes)) break;
|
||||
}
|
||||
}
|
||||
UpdateTownRadius(t);
|
||||
|
@ -25,7 +25,7 @@ CommandCost CmdTownGrowthRate(DoCommandFlags flags, TownID town_id, uint16_t gro
|
||||
CommandCost CmdTownRating(DoCommandFlags flags, TownID town_id, CompanyID company_id, int16_t rating);
|
||||
CommandCost CmdTownCargoGoal(DoCommandFlags flags, TownID town_id, TownAcceptanceEffect tae, uint32_t goal);
|
||||
CommandCost CmdTownSetText(DoCommandFlags flags, TownID town_id, const EncodedString &text);
|
||||
CommandCost CmdExpandTown(DoCommandFlags flags, TownID town_id, uint32_t grow_amount);
|
||||
CommandCost CmdExpandTown(DoCommandFlags flags, TownID town_id, uint32_t grow_amount, TownExpandModes modes);
|
||||
CommandCost CmdDeleteTown(DoCommandFlags flags, TownID town_id);
|
||||
CommandCost CmdPlaceHouse(DoCommandFlags flags, TileIndex tile, HouseID house, bool house_protected);
|
||||
|
||||
|
@ -488,10 +488,17 @@ public:
|
||||
SetViewportCatchmentTown(Town::Get(this->window_number), !this->IsWidgetLowered(WID_TV_CATCHMENT));
|
||||
break;
|
||||
|
||||
case WID_TV_EXPAND: { // expand town - only available on Scenario editor
|
||||
Command<CMD_EXPAND_TOWN>::Post(STR_ERROR_CAN_T_EXPAND_TOWN, static_cast<TownID>(this->window_number), 0);
|
||||
case WID_TV_EXPAND: // expand town - only available on Scenario editor
|
||||
Command<CMD_EXPAND_TOWN>::Post(STR_ERROR_CAN_T_EXPAND_TOWN, static_cast<TownID>(this->window_number), 0, {TownExpandMode::Buildings, TownExpandMode::Roads});
|
||||
break;
|
||||
|
||||
case WID_TV_EXPAND_BUILDINGS: // expand buildings of town - only available on Scenario editor
|
||||
Command<CMD_EXPAND_TOWN>::Post(STR_ERROR_CAN_T_EXPAND_TOWN, static_cast<TownID>(this->window_number), 0, {TownExpandMode::Buildings});
|
||||
break;
|
||||
|
||||
case WID_TV_EXPAND_ROADS: // expand roads of town - only available on Scenario editor
|
||||
Command<CMD_EXPAND_TOWN>::Post(STR_ERROR_CAN_T_EXPAND_TOWN, static_cast<TownID>(this->window_number), 0, {TownExpandMode::Roads});
|
||||
break;
|
||||
}
|
||||
|
||||
case WID_TV_DELETE: // delete town - only available on Scenario editor
|
||||
Command<CMD_DELETE_TOWN>::Post(STR_ERROR_TOWN_CAN_T_DELETE, static_cast<TownID>(this->window_number));
|
||||
@ -638,10 +645,14 @@ static constexpr NWidgetPart _nested_town_editor_view_widgets[] = {
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
NWidget(WWT_PANEL, COLOUR_BROWN, WID_TV_INFO), SetMinimalSize(260, 32), SetResize(1, 0), SetFill(1, 0), EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_EXPAND), SetMinimalSize(80, 12), SetFill(1, 1), SetResize(1, 0), SetStringTip(STR_TOWN_VIEW_EXPAND_BUTTON, STR_TOWN_VIEW_EXPAND_TOOLTIP),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_DELETE), SetMinimalSize(80, 12), SetFill(1, 1), SetResize(1, 0), SetStringTip(STR_TOWN_VIEW_DELETE_BUTTON, STR_TOWN_VIEW_DELETE_TOOLTIP),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_TV_CATCHMENT), SetMinimalSize(40, 12), SetFill(1, 1), SetResize(1, 0), SetStringTip(STR_BUTTON_CATCHMENT, STR_TOOLTIP_CATCHMENT),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_EXPAND), SetFill(1, 1), SetResize(1, 0), SetStringTip(STR_TOWN_VIEW_EXPAND_BUTTON, STR_TOWN_VIEW_EXPAND_TOOLTIP),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_EXPAND_BUILDINGS), SetFill(1, 1), SetResize(1, 0), SetStringTip(STR_TOWN_VIEW_EXPAND_BUILDINGS_BUTTON, STR_TOWN_VIEW_EXPAND_BUILDINGS_TOOLTIP),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_EXPAND_ROADS), SetFill(1, 1), SetResize(1, 0), SetStringTip(STR_TOWN_VIEW_EXPAND_ROADS_BUTTON, STR_TOWN_VIEW_EXPAND_ROADS_TOOLTIP),
|
||||
EndContainer(),
|
||||
NWidget(NWID_HORIZONTAL),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_DELETE), SetFill(1, 1), SetResize(1, 0), SetStringTip(STR_TOWN_VIEW_DELETE_BUTTON, STR_TOWN_VIEW_DELETE_TOOLTIP),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_TV_CATCHMENT), SetFill(1, 1), SetResize(1, 0), SetStringTip(STR_BUTTON_CATCHMENT, STR_TOOLTIP_CATCHMENT),
|
||||
NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
|
||||
EndContainer(),
|
||||
};
|
||||
@ -1078,7 +1089,6 @@ static constexpr NWidgetPart _nested_found_town_widgets[] = {
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TF_RANDOM_TOWN), SetStringTip(STR_FOUND_TOWN_RANDOM_TOWN_BUTTON, STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP), SetFill(1, 0),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TF_MANY_RANDOM_TOWNS), SetStringTip(STR_FOUND_TOWN_MANY_RANDOM_TOWNS, STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP), SetFill(1, 0),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TF_LOAD_FROM_FILE), SetStringTip(STR_FOUND_TOWN_LOAD_FROM_FILE, STR_FOUND_TOWN_LOAD_FROM_FILE_TOOLTIP), SetFill(1, 0),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TF_EXPAND_ALL_TOWNS), SetStringTip(STR_FOUND_TOWN_EXPAND_ALL_TOWNS, STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP), SetFill(1, 0),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
|
||||
@ -1120,6 +1130,18 @@ static constexpr NWidgetPart _nested_found_town_widgets[] = {
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
|
||||
/* Town expansion selection. */
|
||||
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_TF_TOWN_EXPAND_SEL),
|
||||
NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0),
|
||||
NWidget(WWT_LABEL, INVALID_COLOUR), SetStringTip(STR_FOUND_TOWN_EXPAND_MODE),
|
||||
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TF_EXPAND_ALL_TOWNS), SetStringTip(STR_FOUND_TOWN_EXPAND_ALL_TOWNS, STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP), SetFill(1, 0),
|
||||
NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_EXPAND_BUILDINGS), SetStringTip(STR_FOUND_TOWN_EXPAND_BUILDINGS, STR_FOUND_TOWN_EXPAND_BUILDINGS_TOOLTIP), SetFill(1, 0),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_EXPAND_ROADS), SetStringTip(STR_FOUND_TOWN_EXPAND_ROADS, STR_FOUND_TOWN_EXPAND_ROADS_TOOLTIP), SetFill(1, 0),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
};
|
||||
@ -1134,6 +1156,7 @@ private:
|
||||
bool townnamevalid = false; ///< Is generated town name valid?
|
||||
uint32_t townnameparts = 0; ///< Generated town name
|
||||
TownNameParams params; ///< Town name parameters
|
||||
static inline TownExpandModes expand_modes{TownExpandMode::Buildings, TownExpandMode::Roads};
|
||||
|
||||
public:
|
||||
FoundTownWindow(WindowDesc &desc, WindowNumber window_number) :
|
||||
@ -1153,6 +1176,7 @@ public:
|
||||
if (_game_mode == GM_EDITOR) return;
|
||||
|
||||
this->GetWidget<NWidgetStacked>(WID_TF_TOWN_ACTION_SEL)->SetDisplayedPlane(SZSP_HORIZONTAL);
|
||||
this->GetWidget<NWidgetStacked>(WID_TF_TOWN_EXPAND_SEL)->SetDisplayedPlane(SZSP_HORIZONTAL);
|
||||
this->GetWidget<NWidgetStacked>(WID_TF_SIZE_SEL)->SetDisplayedPlane(SZSP_VERTICAL);
|
||||
if (_settings_game.economy.found_town != TF_CUSTOM_LAYOUT) {
|
||||
this->GetWidget<NWidgetStacked>(WID_TF_ROAD_LAYOUT_SEL)->SetDisplayedPlane(SZSP_HORIZONTAL);
|
||||
@ -1192,6 +1216,9 @@ public:
|
||||
this->SetWidgetLoweredState(i, i == WID_TF_LAYOUT_ORIGINAL + this->town_layout);
|
||||
}
|
||||
|
||||
this->SetWidgetLoweredState(WID_TF_EXPAND_BUILDINGS, FoundTownWindow::expand_modes.Test(TownExpandMode::Buildings));
|
||||
this->SetWidgetLoweredState(WID_TF_EXPAND_ROADS, FoundTownWindow::expand_modes.Test(TownExpandMode::Roads));
|
||||
|
||||
this->SetDirty();
|
||||
}
|
||||
|
||||
@ -1242,7 +1269,7 @@ public:
|
||||
|
||||
case WID_TF_EXPAND_ALL_TOWNS:
|
||||
for (Town *t : Town::Iterate()) {
|
||||
Command<CMD_EXPAND_TOWN>::Do(DoCommandFlag::Execute, t->index, 0);
|
||||
Command<CMD_EXPAND_TOWN>::Do(DoCommandFlag::Execute, t->index, 0, FoundTownWindow::expand_modes);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1257,6 +1284,16 @@ public:
|
||||
this->SetDirty();
|
||||
break;
|
||||
|
||||
case WID_TF_EXPAND_BUILDINGS:
|
||||
FoundTownWindow::expand_modes.Flip(TownExpandMode::Buildings);
|
||||
this->UpdateButtons(false);
|
||||
break;
|
||||
|
||||
case WID_TF_EXPAND_ROADS:
|
||||
FoundTownWindow::expand_modes.Flip(TownExpandMode::Roads);
|
||||
this->UpdateButtons(false);
|
||||
break;
|
||||
|
||||
case WID_TF_LAYOUT_ORIGINAL: case WID_TF_LAYOUT_BETTER: case WID_TF_LAYOUT_GRID2:
|
||||
case WID_TF_LAYOUT_GRID3: case WID_TF_LAYOUT_RANDOM:
|
||||
this->town_layout = (TownLayout)(widget - WID_TF_LAYOUT_ORIGINAL);
|
||||
|
@ -91,6 +91,14 @@ enum TownLayout : uint8_t {
|
||||
};
|
||||
DECLARE_ENUM_AS_ADDABLE(TownLayout)
|
||||
|
||||
/** Options for growing towns. */
|
||||
enum class TownExpandMode : uint8_t {
|
||||
Buildings, ///< Allow town to place buildings.
|
||||
Roads, ///< Allow town to place roads.
|
||||
};
|
||||
|
||||
using TownExpandModes = EnumBitSet<TownExpandMode, uint8_t>;
|
||||
|
||||
/** Town founding setting values. It needs to be 8bits, because we save and load it as such */
|
||||
enum TownFounding : uint8_t {
|
||||
TF_BEGIN = 0, ///< Used for iterations and limit testing
|
||||
|
@ -42,6 +42,8 @@ enum TownViewWidgets : WidgetID {
|
||||
WID_TV_CHANGE_NAME, ///< Change the name of this town.
|
||||
WID_TV_CATCHMENT, ///< Toggle catchment area highlight.
|
||||
WID_TV_EXPAND, ///< Expand this town (scenario editor only).
|
||||
WID_TV_EXPAND_BUILDINGS, ///< Expand number of buildings this town (scenario editor only).
|
||||
WID_TV_EXPAND_ROADS, ///< Expand roads of this town (scenario editor only).
|
||||
WID_TV_DELETE, ///< Delete this town (scenario editor only).
|
||||
};
|
||||
|
||||
@ -67,6 +69,9 @@ enum TownFoundingWidgets : WidgetID {
|
||||
WID_TF_LAYOUT_GRID2, ///< Selection for the 2x2 grid town layout.
|
||||
WID_TF_LAYOUT_GRID3, ///< Selection for the 3x3 grid town layout.
|
||||
WID_TF_LAYOUT_RANDOM, ///< Selection for a randomly chosen town layout.
|
||||
WID_TF_TOWN_EXPAND_SEL, ///< Container of town expansion buttons.
|
||||
WID_TF_EXPAND_BUILDINGS, ///< Expand buildings toggle.
|
||||
WID_TF_EXPAND_ROADS, ///< Expand roads toggle.
|
||||
};
|
||||
|
||||
/** Widgets of the #BuildHouseWindow class. */
|
||||
|
Loading…
Reference in New Issue
Block a user