1
0
mirror of https://github.com/OpenTTD/OpenTTD synced 2026-01-23 04:04:09 +01:00

Feature: Allow placing an area of 1x1 houses (#14708)

This commit is contained in:
Tyler Trahan
2026-01-08 15:43:50 -05:00
committed by GitHub
parent e97213e7e2
commit 09a8b1cf5c
6 changed files with 81 additions and 2 deletions

View File

@@ -3000,6 +3000,59 @@ CommandCost CmdPlaceHouse(DoCommandFlags flags, TileIndex tile, HouseID house, b
return CommandCost();
}
/**
* Construct multiple houses in an area
* @param flags Type of operation.
* @param tile End tile of area dragging.
* @param start_tile Start tile of area dragging.
* @param HouseID The HouseID of the house spec.
* @param is_protected Whether the house is protected from the town upgrading it.
* @param replace Whether we can replace existing houses.
* @param diagonal Whether to use the Diagonal or Orthogonal tile iterator.
* @return Empty cost or an error.
*/
CommandCost CmdPlaceHouseArea(DoCommandFlags flags, TileIndex tile, TileIndex start_tile, HouseID house, bool is_protected, bool replace, bool diagonal)
{
if (start_tile >= Map::Size()) return CMD_ERROR;
if (_game_mode != GM_EDITOR && _settings_game.economy.place_houses == PH_FORBIDDEN) return CMD_ERROR;
if (Town::GetNumItems() == 0) return CommandCost(STR_ERROR_MUST_FOUND_TOWN_FIRST);
if (static_cast<size_t>(house) >= HouseSpec::Specs().size()) return CMD_ERROR;
const HouseSpec *hs = HouseSpec::Get(house);
if (!hs->enabled) return CMD_ERROR;
/* Only allow placing an area of 1x1 houses. */
if (!hs->building_flags.Test(BuildingFlag::Size1x1)) return CMD_ERROR;
/* Use the built object limit to rate limit house placement. */
const Company *c = Company::GetIfValid(_current_company);
int limit = (c == nullptr ? INT32_MAX : GB(c->build_object_limit, 16, 16));
CommandCost last_error = CMD_ERROR;
bool had_success = false;
std::unique_ptr<TileIterator> iter = TileIterator::Create(tile, start_tile, diagonal);
for (; *iter != INVALID_TILE; ++(*iter)) {
TileIndex t = *iter;
CommandCost ret = Command<CMD_PLACE_HOUSE>::Do(DoCommandFlags{flags}.Reset(DoCommandFlag::Execute), t, house, is_protected, replace);
/* If we've reached the limit, stop building (or testing). */
if (c != nullptr && limit-- <= 0) break;
if (ret.Failed()) {
last_error = std::move(ret);
continue;
}
if (flags.Test(DoCommandFlag::Execute)) Command<CMD_PLACE_HOUSE>::Do(flags, t, house, is_protected, replace);
had_success = true;
}
return had_success ? CommandCost{} : last_error;
}
/**
* Update data structures when a house is removed
* @param tile Tile of the house