diff --git a/src/table/unmovable_land.h b/src/table/unmovable_land.h index 780b96ec22..5acc8ca113 100644 --- a/src/table/unmovable_land.h +++ b/src/table/unmovable_land.h @@ -125,9 +125,9 @@ static const DrawTileSprites _unmovable_hq[] = { /** Specification of the original unmovable structures. */ static const UnmovableSpec _original_unmovable[] = { - { STR_LAI_UNMOVABLE_DESCRIPTION_TRANSMITTER, 0x11, 1, 1 }, - { STR_LAI_UNMOVABLE_DESCRIPTION_LIGHTHOUSE, 0x11, 1, 1 }, - { STR_TOWN_BUILDING_NAME_STATUE_1, 0x11, 1, 1 }, - { STR_LAI_UNMOVABLE_DESCRIPTION_COMPANY_OWNED_LAND, 0x11, 10, 2 }, - { STR_LAI_UNMOVABLE_DESCRIPTION_COMPANY_HEADQUARTERS, 0x22, 1, 1 }, + { STR_LAI_UNMOVABLE_DESCRIPTION_TRANSMITTER, 0x11, 1, 1, OBJECT_FLAG_CANNOT_REMOVE | OBJECT_FLAG_REQUIRE_FLAT }, + { STR_LAI_UNMOVABLE_DESCRIPTION_LIGHTHOUSE, 0x11, 1, 1, OBJECT_FLAG_CANNOT_REMOVE | OBJECT_FLAG_REQUIRE_FLAT }, + { STR_TOWN_BUILDING_NAME_STATUE_1, 0x11, 1, 1, OBJECT_FLAG_CANNOT_REMOVE }, + { STR_LAI_UNMOVABLE_DESCRIPTION_COMPANY_OWNED_LAND, 0x11, 10, 2, OBJECT_FLAG_AUTOREMOVE | OBJECT_FLAG_CLEAR_INCOME | OBJECT_FLAG_HAS_NO_FOUNDATION | OBJECT_FLAG_ALLOW_UNDER_BRIDGE }, + { STR_LAI_UNMOVABLE_DESCRIPTION_COMPANY_HEADQUARTERS, 0x22, 1, 1, OBJECT_FLAG_CANNOT_REMOVE }, }; diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 29e178bc99..0437e9ea54 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -16,7 +16,7 @@ #include "stdafx.h" #include "rail_map.h" #include "landscape.h" -#include "unmovable_map.h" +#include "unmovable.h" #include "viewport_func.h" #include "cmd_helper.h" #include "command_func.h" @@ -395,9 +395,11 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u if (z_start < GetBridgeHeight(tile)) goto not_valid_below; break; - case MP_UNMOVABLE: - if (!IsOwnedLand(tile)) goto not_valid_below; + case MP_UNMOVABLE: { + const UnmovableSpec *spec = UnmovableSpec::GetByTile(tile); + if ((spec->flags & OBJECT_FLAG_ALLOW_UNDER_BRIDGE) == 0) goto not_valid_below; break; + } case MP_CLEAR: break; diff --git a/src/unmovable.h b/src/unmovable.h index 8f3431e660..366889a7db 100644 --- a/src/unmovable.h +++ b/src/unmovable.h @@ -36,12 +36,33 @@ void UpdateCompanyHQ(Company *c, uint score); void BuildUnmovable(UnmovableType type, TileIndex tile, CompanyID owner = OWNER_NONE, uint index = 0); +/** Various object behaviours. */ +enum ObjectFlags { + OBJECT_FLAG_NONE = 0, ///< Just nothing. + OBJECT_FLAG_ONLY_IN_SCENEDIT = 1 << 0, ///< Object can only be constructed in the scenario editor. + OBJECT_FLAG_CANNOT_REMOVE = 1 << 1, ///< Object can not be removed. + OBJECT_FLAG_AUTOREMOVE = 1 << 2, ///< Object get automatically removed (like "owned land"). + OBJECT_FLAG_BUILT_ON_WATER = 1 << 3, ///< Object can be built on water (not required). + OBJECT_FLAG_CLEAR_INCOME = 1 << 4, ///< When object is cleared a positive income is generated instead of a cost. + OBJECT_FLAG_HAS_NO_FOUNDATION = 1 << 5, ///< Do not display foundations when on a slope. + OBJECT_FLAG_ANIMATION = 1 << 6, ///< Object has animated tiles. + OBJECT_FLAG_ONLY_IN_GAME = 1 << 7, ///< Object can only be built in game. + OBJECT_FLAG_2CC_COLOUR = 1 << 8, ///< Object wants 2CC colour mapping. + OBJECT_FLAG_NOT_ON_LAND = 1 << 9, ///< Object can not be on land, implicitly sets #OBJECT_FLAG_BUILT_ON_WATER. + OBJECT_FLAG_DRAW_WATER = 1 << 10, ///< Object wants to be drawn on water. + OBJECT_FLAG_ALLOW_UNDER_BRIDGE = 1 << 11, ///< Object can built under a bridge. + OBJECT_FLAG_REQUIRE_FLAT = 1 << 12, ///< Object can only be build of flat land, i.e. not on foundations! +}; +DECLARE_ENUM_AS_BIT_SET(ObjectFlags) + + /** An (unmovable) object that isn't use for transport, industries or houses. */ struct UnmovableSpec { StringID name; ///< The name for this object. uint8 size; ///< The size of this objects; low nibble for X, high nibble for Y. uint8 build_cost_multiplier; ///< Build cost multiplier per tile. uint8 clear_cost_multiplier; ///< Clear cost multiplier per tile. + ObjectFlags flags; ///< Flags/settings related to the object. /** * Get the cost for building a structure of this type. diff --git a/src/unmovable_cmd.cpp b/src/unmovable_cmd.cpp index b2868fe0be..652b31422c 100644 --- a/src/unmovable_cmd.cpp +++ b/src/unmovable_cmd.cpp @@ -245,7 +245,8 @@ static Foundation GetFoundation_Unmovable(TileIndex tile, Slope tileh); static void DrawTile_Unmovable(TileInfo *ti) { UnmovableType type = GetUnmovableType(ti->tile); - if (type != UNMOVABLE_OWNED_LAND) DrawFoundation(ti, GetFoundation_Unmovable(ti->tile, ti->tileh)); + const UnmovableSpec *spec = UnmovableSpec::Get(type); + if ((spec->flags & OBJECT_FLAG_HAS_NO_FOUNDATION) == 0) DrawFoundation(ti, GetFoundation_Unmovable(ti->tile, ti->tileh)); const DrawTileSprites *dts = NULL; Owner to = GetTileOwner(ti->tile); @@ -258,7 +259,19 @@ static void DrawTile_Unmovable(TileInfo *ti) dts = &_unmovables[type]; } - DrawGroundSprite(dts->ground.sprite, palette); + if (spec->flags & OBJECT_FLAG_HAS_NO_FOUNDATION) { + /* If an object has no foundation, but tries to draw a (flat) ground + * type... we have to be nice and convert that for them. */ + switch (dts->ground.sprite) { + case SPR_FLAT_BARE_LAND: DrawClearLandTile(ti, 0); break; + case SPR_FLAT_1_THIRD_GRASS_TILE: DrawClearLandTile(ti, 1); break; + case SPR_FLAT_2_THIRD_GRASS_TILE: DrawClearLandTile(ti, 2); break; + case SPR_FLAT_GRASS_TILE: DrawClearLandTile(ti, 3); break; + default: DrawGroundSprite(dts->ground.sprite, palette); break; + } + } else { + DrawGroundSprite(dts->ground.sprite, palette); + } if (!IsInvisibilitySet(TO_STRUCTURES)) { const DrawTileSeqStruct *dtss; @@ -273,7 +286,7 @@ static void DrawTile_Unmovable(TileInfo *ti) } } - if (type == UNMOVABLE_OWNED_LAND) DrawBridgeMiddle(ti); + if (spec->flags & OBJECT_FLAG_ALLOW_UNDER_BRIDGE) DrawBridgeMiddle(ti); } static uint GetSlopeZ_Unmovable(TileIndex tile, uint x, uint y) @@ -537,13 +550,19 @@ static void ChangeTileOwner_Unmovable(TileIndex tile, Owner old_owner, Owner new static CommandCost TerraformTile_Unmovable(TileIndex tile, DoCommandFlag flags, uint z_new, Slope tileh_new) { - /* Owned land remains unsold */ - if (IsOwnedLand(tile)) { - CommandCost ret = CheckTileOwnership(tile); - if (ret.Succeeded()) return CommandCost(); + UnmovableType type = GetUnmovableType(tile); + const UnmovableSpec *spec = UnmovableSpec::Get(type); + + if (spec->flags & OBJECT_FLAG_REQUIRE_FLAT) { + /* If a flat tile is required by the object, then terraforming is never good. */ + return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); } - if (AutoslopeEnabled() && (IsStatue(tile) || IsCompanyHQ(tile))) { + if (IsOwnedLand(tile)) { + /* Owned land remains unsold */ + CommandCost ret = CheckTileOwnership(tile); + if (ret.Succeeded()) return CommandCost(); + } else if (AutoslopeEnabled()) { if (!IsSteepSlope(tileh_new) && (z_new + GetSlopeMaxZ(tileh_new) == GetTileMaxZ(tile))) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]); }