mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-06 06:15:04 +00:00
Feature: Prevent towns from upgrading individually-placed houses (#13270)
This commit is contained in:
parent
1ed685b5c1
commit
521b860394
@ -721,7 +721,8 @@
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<li>m3 bits 6..5 : free</li>
|
||||
<li>m3 bit 6 : free</li>
|
||||
<li>m3 bit 5 : The house is protected from the town upgrading it</li>
|
||||
<li>m3 bits 4..0 : triggers activated <a href="#newhouses">(newhouses)</a></li>
|
||||
<li>m4 : free</li>
|
||||
<li>m5 : see m3 bit 7</li>
|
||||
|
@ -156,7 +156,7 @@ the array so you can quickly see what is used and what is not.
|
||||
<td class="caption">finished house</td>
|
||||
<td class="bits" rowspan=2><span class="used" title="House random bits">XXXX XXXX</span></td>
|
||||
<td class="bits" rowspan=2><span class="pool" title="Town index on pool">XXXX XXXX XXXX XXXX</span></td>
|
||||
<td class="bits"><span class="used" title="House is complete/in construction (see m5)">1</span><span class="free">OO</span><span class="usable" title="Activated triggers (bits 2..4 don't have a meaning)">X XX</span><span class="used" title="Activated triggers (bits 2..4 don't have a meaning)">XX</span></td>
|
||||
<td class="bits"><span class="used" title="House is complete/in construction (see m5)">1</span><span class="free">O</span><span class="used" title="The house is protected from the town upgrading it.">X</span><span class="usable" title="Activated triggers (bits 2..4 don't have a meaning)">X XX</span><span class="used" title="Activated triggers (bits 2..4 don't have a meaning)">XX</span></td>
|
||||
<td class="bits" rowspan=2><span class="free">OOOO OOOO</span></td>
|
||||
<td class="bits"><span class="used" title="Age in years, clamped at 255">XXXX XXXX</span></td>
|
||||
<td class="bits" rowspan=2><span class="abuse" title="Newhouses activated: periodic processing time remaining; if not, lift position for houses 04 and 05">XXXX XX</span><span class="used" title="Animated tile state">XX</span></td>
|
||||
@ -165,7 +165,7 @@ the array so you can quickly see what is used and what is not.
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="caption">house under construction</td>
|
||||
<td class="bits"><span class="used" title="House is complete/in construction (see m5)">O</span><span class="used" title="House type (m4 + m3[6])">X</span><span class="free">O</span><span class="usable" title="Activated triggers (bits 2..4 don't have a meaning)">X XX</span><span class="used" title="Activated triggers (bits 2..4 don't have a meaning)">XX</span></td>
|
||||
<td class="bits"><span class="used" title="House is complete/in construction (see m5)">O</span><span class="used" title="House type (m4 + m3[6])">X</span><span class="used" title="The house is protected from the town upgrading it.">X</span><span class="usable" title="Activated triggers (bits 2..4 don't have a meaning)">X XX</span><span class="used" title="Activated triggers (bits 2..4 don't have a meaning)">XX</span></td>
|
||||
<td class="bits"><span class="free">OOO</span><span class="used" title="Construction stage">X X</span><span class="used" title="Construction counter">XXX</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -2866,6 +2866,11 @@ STR_HOUSE_PICKER_CLASS_ZONE3 :Outer Suburbs
|
||||
STR_HOUSE_PICKER_CLASS_ZONE4 :Inner Suburbs
|
||||
STR_HOUSE_PICKER_CLASS_ZONE5 :Town centre
|
||||
|
||||
STR_HOUSE_PICKER_PROTECT_TITLE :Prevent upgrades
|
||||
STR_HOUSE_PICKER_PROTECT_TOOLTIP :Choose whether this house will be protected from replacement as the town grows
|
||||
STR_HOUSE_PICKER_PROTECT_OFF :Off
|
||||
STR_HOUSE_PICKER_PROTECT_ON :On
|
||||
|
||||
STR_STATION_CLASS_DFLT :Default
|
||||
STR_STATION_CLASS_DFLT_STATION :Default station
|
||||
STR_STATION_CLASS_DFLT_ROADSTOP :Default road stop
|
||||
@ -3142,6 +3147,8 @@ STR_LANG_AREA_INFORMATION_TRAM_TYPE :{BLACK}Tram typ
|
||||
STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Rail speed limit: {LTBLUE}{VELOCITY}
|
||||
STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Road speed limit: {LTBLUE}{VELOCITY}
|
||||
STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT :{BLACK}Tram speed limit: {LTBLUE}{VELOCITY}
|
||||
STR_LAND_AREA_INFORMATION_TOWN_CAN_UPGRADE :{BLACK}Town can upgrade: {LTBLUE}Yes
|
||||
STR_LAND_AREA_INFORMATION_TOWN_CANNOT_UPGRADE :{BLACK}Town can upgrade: {LTBLUE}No
|
||||
|
||||
# Description of land area of different tiles
|
||||
STR_LAI_CLEAR_DESCRIPTION_ROCKS :Rocks
|
||||
|
@ -168,6 +168,7 @@ public:
|
||||
td.road_speed = 0;
|
||||
td.tramtype = STR_NULL;
|
||||
td.tram_speed = 0;
|
||||
td.town_can_upgrade = std::nullopt;
|
||||
|
||||
td.grf = nullptr;
|
||||
|
||||
@ -300,6 +301,11 @@ public:
|
||||
this->landinfo_data.push_back(GetString(STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT));
|
||||
}
|
||||
|
||||
/* Tile protection status */
|
||||
if (td.town_can_upgrade.has_value()) {
|
||||
this->landinfo_data.push_back(GetString(td.town_can_upgrade.value() ? STR_LAND_AREA_INFORMATION_TOWN_CAN_UPGRADE : STR_LAND_AREA_INFORMATION_TOWN_CANNOT_UPGRADE));
|
||||
}
|
||||
|
||||
/* NewGRF name */
|
||||
if (td.grf != nullptr) {
|
||||
SetDParamStr(0, td.grf);
|
||||
|
@ -622,7 +622,7 @@ bool CanDeleteHouse(TileIndex tile)
|
||||
uint16_t callback_res = GetHouseCallback(CBID_HOUSE_DENY_DESTRUCTION, 0, 0, GetHouseType(tile), Town::GetByTile(tile), tile);
|
||||
return (callback_res == CALLBACK_FAILED || !ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DENY_DESTRUCTION, callback_res));
|
||||
} else {
|
||||
return !hs->extra_flags.Test(HouseExtraFlag::BuildingIsProtected);
|
||||
return !IsHouseProtected(tile);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1548,6 +1548,16 @@ bool AfterLoadGame()
|
||||
}
|
||||
}
|
||||
|
||||
if (IsSavegameVersionBefore(SLV_PROTECT_PLACED_HOUSES)) {
|
||||
for (auto t : Map::Iterate()) {
|
||||
if (IsTileType(t, MP_HOUSE)) {
|
||||
/* We now store house protection status in the map. Set this based on the house spec flags. */
|
||||
const HouseSpec *hs = HouseSpec::Get(GetHouseType(t));
|
||||
SetHouseProtected(t, hs->extra_flags.Test(HouseExtraFlag::BuildingIsProtected));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check and update house and town values */
|
||||
UpdateHousesAndTowns();
|
||||
|
||||
|
@ -398,6 +398,7 @@ enum SaveLoadVersion : uint16_t {
|
||||
SLV_COMPANY_INAUGURATED_PERIOD_V2, ///< 349 PR#13448 Fix savegame storage for company inaugurated year in wallclock mode.
|
||||
|
||||
SLV_ENCODED_STRING_FORMAT, ///< 350 PR#13499 Encoded String format changed.
|
||||
SLV_PROTECT_PLACED_HOUSES, ///< 351 PR#13270 Houses individually placed by players can be protected from town/AI removal.
|
||||
|
||||
SL_MAX_VERSION, ///< Highest possible saveload version
|
||||
};
|
||||
|
@ -67,6 +67,7 @@ struct TileDesc {
|
||||
uint16_t road_speed; ///< Speed limit of road (bridges and track)
|
||||
StringID tramtype; ///< Type of tram on the tile.
|
||||
uint16_t tram_speed; ///< Speed limit of tram (bridges and track)
|
||||
std::optional<bool> town_can_upgrade; ///< Whether the town can upgrade this house during town growth.
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -872,6 +872,7 @@ static void GetTileDesc_Town(TileIndex tile, TileDesc *td)
|
||||
bool house_completed = IsHouseCompleted(tile);
|
||||
|
||||
td->str = hs->building_name;
|
||||
td->town_can_upgrade = !IsHouseProtected(tile);
|
||||
|
||||
uint16_t callback_res = GetHouseCallback(CBID_HOUSE_CUSTOM_NAME, house_completed ? 1 : 0, 0, house, Town::GetByTile(tile), tile);
|
||||
if (callback_res != CALLBACK_FAILED && callback_res != 0x400) {
|
||||
@ -2503,15 +2504,16 @@ HouseZonesBits GetTownRadiusGroup(const Town *t, TileIndex tile)
|
||||
* @param stage The current construction stage of the house.
|
||||
* @param type The type of house.
|
||||
* @param random_bits Random bits for newgrf houses to use.
|
||||
* @param is_protected Whether the house is protected from the town upgrading it.
|
||||
* @pre The house can be built here.
|
||||
*/
|
||||
static inline void ClearMakeHouseTile(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits)
|
||||
static inline void ClearMakeHouseTile(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool is_protected)
|
||||
{
|
||||
[[maybe_unused]] CommandCost cc = Command<CMD_LANDSCAPE_CLEAR>::Do(DC_EXEC | DC_AUTO | DC_NO_WATER, tile);
|
||||
assert(cc.Succeeded());
|
||||
|
||||
IncreaseBuildingCount(t, type);
|
||||
MakeHouseTile(tile, t->index, counter, stage, type, random_bits);
|
||||
MakeHouseTile(tile, t->index, counter, stage, type, random_bits, is_protected);
|
||||
if (HouseSpec::Get(type)->building_flags.Test(BuildingFlag::IsAnimated)) AddAnimatedTile(tile, false);
|
||||
|
||||
MarkTileDirtyByTile(tile);
|
||||
@ -2526,16 +2528,17 @@ static inline void ClearMakeHouseTile(TileIndex tile, Town *t, uint8_t counter,
|
||||
* @param stage The current construction stage.
|
||||
* @param The type of house.
|
||||
* @param random_bits Random bits for newgrf houses to use.
|
||||
* @param is_protected Whether the house is protected from the town upgrading it.
|
||||
* @pre The house can be built here.
|
||||
*/
|
||||
static void MakeTownHouse(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits)
|
||||
static void MakeTownHouse(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool is_protected)
|
||||
{
|
||||
BuildingFlags size = HouseSpec::Get(type)->building_flags;
|
||||
|
||||
ClearMakeHouseTile(tile, t, counter, stage, type, random_bits);
|
||||
if (size.Any(BUILDING_2_TILES_Y)) ClearMakeHouseTile(tile + TileDiffXY(0, 1), t, counter, stage, ++type, random_bits);
|
||||
if (size.Any(BUILDING_2_TILES_X)) ClearMakeHouseTile(tile + TileDiffXY(1, 0), t, counter, stage, ++type, random_bits);
|
||||
if (size.Any(BUILDING_HAS_4_TILES)) ClearMakeHouseTile(tile + TileDiffXY(1, 1), t, counter, stage, ++type, random_bits);
|
||||
ClearMakeHouseTile(tile, t, counter, stage, type, random_bits, is_protected);
|
||||
if (size.Any(BUILDING_2_TILES_Y)) ClearMakeHouseTile(tile + TileDiffXY(0, 1), t, counter, stage, ++type, random_bits, is_protected);
|
||||
if (size.Any(BUILDING_2_TILES_X)) ClearMakeHouseTile(tile + TileDiffXY(1, 0), t, counter, stage, ++type, random_bits, is_protected);
|
||||
if (size.Any(BUILDING_HAS_4_TILES)) ClearMakeHouseTile(tile + TileDiffXY(1, 1), t, counter, stage, ++type, random_bits, is_protected);
|
||||
|
||||
ForAllStationsAroundTiles(TileArea(tile, size.Any(BUILDING_2_TILES_X) ? 2 : 1, size.Any(BUILDING_2_TILES_Y) ? 2 : 1), [t](Station *st, TileIndex) {
|
||||
t->stations_near.insert(st);
|
||||
@ -2732,8 +2735,9 @@ static bool CheckTownBuild2x2House(TileIndex *tile, Town *t, int maxz, bool nosl
|
||||
* @param house The @a HouseID of the house.
|
||||
* @param random_bits The random data to be associated with the house.
|
||||
* @param house_completed Should the house be placed already complete, instead of under construction?
|
||||
* @param is_protected Whether the house is protected from the town upgrading it.
|
||||
*/
|
||||
static void BuildTownHouse(Town *t, TileIndex tile, const HouseSpec *hs, HouseID house, uint8_t random_bits, bool house_completed)
|
||||
static void BuildTownHouse(Town *t, TileIndex tile, const HouseSpec *hs, HouseID house, uint8_t random_bits, bool house_completed, bool is_protected)
|
||||
{
|
||||
/* build the house */
|
||||
t->cache.num_houses++;
|
||||
@ -2754,7 +2758,7 @@ static void BuildTownHouse(Town *t, TileIndex tile, const HouseSpec *hs, HouseID
|
||||
}
|
||||
}
|
||||
|
||||
MakeTownHouse(tile, t, construction_counter, construction_stage, house, random_bits);
|
||||
MakeTownHouse(tile, t, construction_counter, construction_stage, house, random_bits, is_protected);
|
||||
UpdateTownRadius(t);
|
||||
UpdateTownGrowthRate(t);
|
||||
}
|
||||
@ -2880,7 +2884,7 @@ static bool TryBuildTownHouse(Town *t, TileIndex tile)
|
||||
/* Special houses that there can be only one of. */
|
||||
t->flags |= oneof;
|
||||
|
||||
BuildTownHouse(t, tile, hs, house, random_bits, false);
|
||||
BuildTownHouse(t, tile, hs, house, random_bits, false, hs->extra_flags.Test(HouseExtraFlag::BuildingIsProtected));
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -2888,7 +2892,15 @@ static bool TryBuildTownHouse(Town *t, TileIndex tile)
|
||||
return false;
|
||||
}
|
||||
|
||||
CommandCost CmdPlaceHouse(DoCommandFlag flags, TileIndex tile, HouseID house)
|
||||
/**
|
||||
* Place an individual house.
|
||||
* @param flags Type of operation.
|
||||
* @param tile Tile on which to place the house.
|
||||
* @param HouseID The HouseID of the house spec.
|
||||
* @param is_protected Whether the house is protected from the town upgrading it.
|
||||
* @return Empty cost or an error.
|
||||
*/
|
||||
CommandCost CmdPlaceHouse(DoCommandFlag flags, TileIndex tile, HouseID house, bool is_protected)
|
||||
{
|
||||
if (_game_mode != GM_EDITOR && _settings_game.economy.place_houses == PH_FORBIDDEN) return CMD_ERROR;
|
||||
|
||||
@ -2932,7 +2944,7 @@ CommandCost CmdPlaceHouse(DoCommandFlag flags, TileIndex tile, HouseID house)
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
bool house_completed = _settings_game.economy.place_houses == PH_ALLOWED_CONSTRUCTED;
|
||||
BuildTownHouse(t, tile, hs, house, Random(), house_completed);
|
||||
BuildTownHouse(t, tile, hs, house, Random(), house_completed, is_protected);
|
||||
}
|
||||
|
||||
return CommandCost();
|
||||
|
@ -26,7 +26,7 @@ CommandCost CmdTownCargoGoal(DoCommandFlag flags, TownID town_id, TownAcceptance
|
||||
CommandCost CmdTownSetText(DoCommandFlag flags, TownID town_id, const std::string &text);
|
||||
CommandCost CmdExpandTown(DoCommandFlag flags, TownID town_id, uint32_t grow_amount);
|
||||
CommandCost CmdDeleteTown(DoCommandFlag flags, TownID town_id);
|
||||
CommandCost CmdPlaceHouse(DoCommandFlag flags, TileIndex tile, HouseID house);
|
||||
CommandCost CmdPlaceHouse(DoCommandFlag flags, TileIndex tile, HouseID house, bool house_protected);
|
||||
|
||||
DEF_CMD_TRAIT(CMD_FOUND_TOWN, CmdFoundTown, CMD_DEITY | CMD_NO_TEST, CMDT_LANDSCAPE_CONSTRUCTION) // founding random town can fail only in exec run
|
||||
DEF_CMD_TRAIT(CMD_RENAME_TOWN, CmdRenameTown, CMD_DEITY | CMD_SERVER, CMDT_OTHER_MANAGEMENT)
|
||||
|
@ -1627,6 +1627,7 @@ public:
|
||||
|
||||
struct BuildHouseWindow : public PickerWindow {
|
||||
std::string house_info;
|
||||
bool house_protected;
|
||||
|
||||
BuildHouseWindow(WindowDesc &desc, Window *parent) : PickerWindow(desc, parent, 0, HousePickerCallbacks::instance)
|
||||
{
|
||||
@ -1680,7 +1681,7 @@ struct BuildHouseWindow : public PickerWindow {
|
||||
|
||||
/**
|
||||
* Get information string for a house.
|
||||
* @param hs HosueSpec to get information string for.
|
||||
* @param hs HouseSpec to get information string for.
|
||||
* @return Formatted string with information for house.
|
||||
*/
|
||||
static std::string GetHouseInformation(const HouseSpec *hs)
|
||||
@ -1714,6 +1715,14 @@ struct BuildHouseWindow : public PickerWindow {
|
||||
return line.str();
|
||||
}
|
||||
|
||||
void OnInit() override
|
||||
{
|
||||
this->SetWidgetLoweredState(WID_BH_PROTECT_OFF, !this->house_protected);
|
||||
this->SetWidgetLoweredState(WID_BH_PROTECT_ON, this->house_protected);
|
||||
|
||||
this->PickerWindow::OnInit();
|
||||
}
|
||||
|
||||
void DrawWidget(const Rect &r, WidgetID widget) const override
|
||||
{
|
||||
if (widget == WID_BH_INFO) {
|
||||
@ -1723,22 +1732,52 @@ struct BuildHouseWindow : public PickerWindow {
|
||||
}
|
||||
}
|
||||
|
||||
void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_BH_PROTECT_OFF:
|
||||
case WID_BH_PROTECT_ON:
|
||||
this->house_protected = (widget == WID_BH_PROTECT_ON);
|
||||
this->SetWidgetLoweredState(WID_BH_PROTECT_OFF, !this->house_protected);
|
||||
this->SetWidgetLoweredState(WID_BH_PROTECT_ON, this->house_protected);
|
||||
|
||||
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
|
||||
this->SetDirty();
|
||||
break;
|
||||
|
||||
default:
|
||||
this->PickerWindow::OnClick(pt, widget, click_count);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnInvalidateData(int data = 0, bool gui_scope = true) override
|
||||
{
|
||||
this->PickerWindow::OnInvalidateData(data, gui_scope);
|
||||
if (!gui_scope) return;
|
||||
|
||||
const HouseSpec *spec = HouseSpec::Get(HousePickerCallbacks::sel_type);
|
||||
|
||||
if ((data & PickerWindow::PFI_POSITION) != 0) {
|
||||
const HouseSpec *spec = HouseSpec::Get(HousePickerCallbacks::sel_type);
|
||||
UpdateSelectSize(spec);
|
||||
this->house_info = GetHouseInformation(spec);
|
||||
}
|
||||
|
||||
/* If house spec already has the protected flag, handle it automatically and disable the buttons. */
|
||||
bool hasflag = spec->extra_flags.Test(HouseExtraFlag::BuildingIsProtected);
|
||||
if (hasflag) this->house_protected = true;
|
||||
|
||||
this->SetWidgetLoweredState(WID_BH_PROTECT_OFF, !this->house_protected);
|
||||
this->SetWidgetLoweredState(WID_BH_PROTECT_ON, this->house_protected);
|
||||
|
||||
this->SetWidgetDisabledState(WID_BH_PROTECT_OFF, hasflag);
|
||||
this->SetWidgetDisabledState(WID_BH_PROTECT_ON, hasflag);
|
||||
}
|
||||
|
||||
void OnPlaceObject([[maybe_unused]] Point pt, TileIndex tile) override
|
||||
{
|
||||
const HouseSpec *spec = HouseSpec::Get(HousePickerCallbacks::sel_type);
|
||||
Command<CMD_PLACE_HOUSE>::Post(STR_ERROR_CAN_T_BUILD_HOUSE, CcPlaySound_CONSTRUCTION_OTHER, tile, spec->Index());
|
||||
Command<CMD_PLACE_HOUSE>::Post(STR_ERROR_CAN_T_BUILD_HOUSE, CcPlaySound_CONSTRUCTION_OTHER, tile, spec->Index(), this->house_protected);
|
||||
}
|
||||
|
||||
IntervalTimer<TimerWindow> view_refresh_interval = {std::chrono::milliseconds(2500), [this](auto) {
|
||||
@ -1768,8 +1807,14 @@ static constexpr NWidgetPart _nested_build_house_widgets[] = {
|
||||
NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
|
||||
NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_picker, 0), SetPadding(WidgetDimensions::unscaled.picker),
|
||||
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_BH_INFO), SetFill(1, 1), SetMinimalTextLines(10, 0),
|
||||
NWidget(WWT_LABEL, INVALID_COLOUR), SetStringTip(STR_HOUSE_PICKER_PROTECT_TITLE, STR_NULL), SetFill(1, 0),
|
||||
NWidget(NWID_HORIZONTAL), SetPIPRatio(1, 0, 1),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BH_PROTECT_OFF), SetMinimalSize(60, 12), SetStringTip(STR_HOUSE_PICKER_PROTECT_OFF, STR_HOUSE_PICKER_PROTECT_TOOLTIP),
|
||||
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BH_PROTECT_ON), SetMinimalSize(60, 12), SetStringTip(STR_HOUSE_PICKER_PROTECT_ON, STR_HOUSE_PICKER_PROTECT_TOOLTIP),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
EndContainer(),
|
||||
|
||||
EndContainer(),
|
||||
NWidgetFunction(MakePickerTypeWidgets),
|
||||
EndContainer(),
|
||||
|
@ -74,6 +74,28 @@ inline void SetHouseType(Tile t, HouseID house_id)
|
||||
SB(t.m8(), 0, 12, house_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the house is protected from removal by towns.
|
||||
* @param t The tile.
|
||||
* @return If the house is protected from the town upgrading it.
|
||||
*/
|
||||
inline bool IsHouseProtected(Tile t)
|
||||
{
|
||||
assert(IsTileType(t, MP_HOUSE));
|
||||
return HasBit(t.m3(), 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a house as protected from removal by towns.
|
||||
* @param t The tile.
|
||||
* @param house_protected Whether the house is protected from the town upgrading it.
|
||||
*/
|
||||
inline void SetHouseProtected(Tile t, bool house_protected)
|
||||
{
|
||||
assert(IsTileType(t, MP_HOUSE));
|
||||
SB(t.m3(), 5, 1, house_protected ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the lift of this animated house has a destination
|
||||
* @param t the tile
|
||||
@ -347,9 +369,10 @@ inline void DecHouseProcessingTime(Tile t)
|
||||
* @param stage of construction (used for drawing)
|
||||
* @param type of house. Index into house specs array
|
||||
* @param random_bits required for newgrf houses
|
||||
* @param house_protected Whether the house is protected from the town upgrading it.
|
||||
* @pre IsTileType(t, MP_CLEAR)
|
||||
*/
|
||||
inline void MakeHouseTile(Tile t, TownID tid, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits)
|
||||
inline void MakeHouseTile(Tile t, TownID tid, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool house_protected)
|
||||
{
|
||||
assert(IsTileType(t, MP_CLEAR));
|
||||
|
||||
@ -360,6 +383,7 @@ inline void MakeHouseTile(Tile t, TownID tid, uint8_t counter, uint8_t stage, Ho
|
||||
SetHouseType(t, type);
|
||||
SetHouseCompleted(t, stage == TOWN_HOUSE_COMPLETED);
|
||||
t.m5() = IsHouseCompleted(t) ? 0 : (stage << 3 | counter);
|
||||
SetHouseProtected(t, house_protected);
|
||||
SetAnimationFrame(t, 0);
|
||||
SetHouseProcessingTime(t, HouseSpec::Get(type)->processing_time);
|
||||
}
|
||||
|
@ -72,6 +72,8 @@ enum TownFoundingWidgets : WidgetID {
|
||||
/** Widgets of the #BuildHouseWindow class. */
|
||||
enum BuildHouseWidgets : WidgetID {
|
||||
WID_BH_INFO, ///< Information panel of selected house.
|
||||
WID_BH_PROTECT_OFF, ///< Button to protect the next house built.
|
||||
WID_BH_PROTECT_ON, ///< Button to not protect the next house built.
|
||||
};
|
||||
|
||||
#endif /* WIDGETS_TOWN_WIDGET_H */
|
||||
|
Loading…
Reference in New Issue
Block a user