diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 74fb319399..16215e7f8d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -91,6 +91,7 @@ add_files( bridge_gui.cpp bridge_map.cpp bridge_map.h + bridge_type.h build_vehicle_gui.cpp cachecheck.cpp cargo_type.h diff --git a/src/bridge.h b/src/bridge.h index c9e7200698..e11ff244b5 100644 --- a/src/bridge.h +++ b/src/bridge.h @@ -13,34 +13,25 @@ #include "gfx_type.h" #include "tile_cmd.h" #include "timer/timer_game_calendar.h" - -/** - * This enum is related to the definition of bridge pieces, - * which is used to determine the proper sprite table to use - * while drawing a given bridge part. - */ -enum BridgePieces : uint8_t { - BRIDGE_PIECE_NORTH = 0, - BRIDGE_PIECE_SOUTH, - BRIDGE_PIECE_INNER_NORTH, - BRIDGE_PIECE_INNER_SOUTH, - BRIDGE_PIECE_MIDDLE_ODD, - BRIDGE_PIECE_MIDDLE_EVEN, - BRIDGE_PIECE_HEAD, - NUM_BRIDGE_PIECES, -}; - -DECLARE_INCREMENT_DECREMENT_OPERATORS(BridgePieces) +#include "bridge_type.h" static const uint MAX_BRIDGES = 13; ///< Maximal number of available bridge specs. constexpr uint SPRITES_PER_BRIDGE_PIECE = 32; ///< Number of sprites there are per bridge piece. -typedef uint BridgeType; ///< Bridge spec number. +/* Container for Bridge pillar flags for each axis of each bridge middle piece. */ +using BridgeMiddlePillarFlags = std::array, NUM_BRIDGE_MIDDLE_PIECES>; /** * Struct containing information about a single bridge type */ struct BridgeSpec { + /** Internal flags about each BridgeSpec. */ + enum class ControlFlag : uint8_t { + CustomPillarFlags, ///< Bridge has set custom pillar flags. + InvalidPillarFlags, ///< Bridge pillar flags are not valid, i.e. only the tile layout has been modified. + }; + using ControlFlags = EnumBitSet; + TimerGameCalendar::Year avail_year; ///< the year where it becomes available uint8_t min_length; ///< the minimum length (not counting start and end tile) uint16_t max_length; ///< the maximum length (not counting start and end tile) @@ -52,6 +43,8 @@ struct BridgeSpec { StringID transport_name[2]; ///< description of the bridge, when built for road or rail std::vector> sprite_table; ///< table of sprites for drawing the bridge uint8_t flags; ///< bit 0 set: disable drawing of far pillars. + ControlFlags ctrl_flags{}; ///< control flags + BridgeMiddlePillarFlags pillar_flags{}; ///< bridge pillar flags. }; extern BridgeSpec _bridge[MAX_BRIDGES]; diff --git a/src/bridge_type.h b/src/bridge_type.h new file mode 100644 index 0000000000..a01ec835dc --- /dev/null +++ b/src/bridge_type.h @@ -0,0 +1,58 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file bridge_type.h Header file for bridge types. */ + +#ifndef BRIDGE_TYPE_H +#define BRIDGE_TYPE_H + +#include "core/enum_type.hpp" + +using BridgeType = uint; ///< Bridge spec number. + +/** + * This enum is related to the definition of bridge pieces, + * which is used to determine the proper sprite table to use + * while drawing a given bridge part. + */ +enum BridgePieces : uint8_t { + BRIDGE_PIECE_NORTH = 0, + BRIDGE_PIECE_SOUTH, + BRIDGE_PIECE_INNER_NORTH, + BRIDGE_PIECE_INNER_SOUTH, + BRIDGE_PIECE_MIDDLE_ODD, + BRIDGE_PIECE_MIDDLE_EVEN, + BRIDGE_PIECE_HEAD, + NUM_BRIDGE_PIECES, +}; + +DECLARE_INCREMENT_DECREMENT_OPERATORS(BridgePieces) + +/** Number of bridge middles pieces. This is all bridge pieces except BRIDGE_PIECE_HEAD. */ +static constexpr uint NUM_BRIDGE_MIDDLE_PIECES = NUM_BRIDGE_PIECES - 1; + +/** Obstructed bridge pillars information. */ +enum class BridgePillarFlag : uint8_t { + /* Corners are in the same order as Corner enum. */ + CornerW = 0, ///< West corner is obstructed. + CornerS = 1, ///< South corner is obstructed. + CornerE = 2, ///< East corner is obstructed. + CornerN = 3, ///< North corner is obstructed. + /* Edges are in the same order as DiagDirection enum. */ + EdgeNE = 4, //< Northeast edge is obstructed. + EdgeSE = 5, //< Southeast edge is obstructed. + EdgeSW = 6, //< Southwest edge is obstructed. + EdgeNW = 7, //< Northwest edge is obstructed. +}; +using BridgePillarFlags = EnumBitSet; + +static constexpr BridgePillarFlags BRIDGEPILLARFLAGS_ALL{ + BridgePillarFlag::CornerW, BridgePillarFlag::CornerS, BridgePillarFlag::CornerE, BridgePillarFlag::CornerN, + BridgePillarFlag::EdgeNE, BridgePillarFlag::EdgeSE, BridgePillarFlag::EdgeSW, BridgePillarFlag::EdgeNW, +}; + +#endif /* BRIDGE_TYPE_H */ diff --git a/src/newgrf/newgrf_act0_bridges.cpp b/src/newgrf/newgrf_act0_bridges.cpp index 949da3937d..e91e75d3ee 100644 --- a/src/newgrf/newgrf_act0_bridges.cpp +++ b/src/newgrf/newgrf_act0_bridges.cpp @@ -93,6 +93,7 @@ static ChangeInfoResult BridgeChangeInfo(uint first, uint last, int prop, ByteRe MapSpriteMappingRecolour(&bridge->sprite_table[tableid][sprite]); } } + if (!bridge->ctrl_flags.Test(BridgeSpec::ControlFlag::CustomPillarFlags)) bridge->ctrl_flags.Set(BridgeSpec::ControlFlag::InvalidPillarFlags); break; } @@ -120,6 +121,21 @@ static ChangeInfoResult BridgeChangeInfo(uint first, uint last, int prop, ByteRe bridge->price = buf.ReadWord(); break; + case 0x15: { // Pillar information for each bridge piece. + uint16_t tiles = buf.ReadExtendedByte(); + for (uint j = 0; j != tiles; ++j) { + if (j < std::size(bridge->pillar_flags)) { + bridge->pillar_flags[j][AXIS_X] = BridgePillarFlags{buf.ReadByte()}; + bridge->pillar_flags[j][AXIS_Y] = BridgePillarFlags{buf.ReadByte()}; + } else { + buf.ReadWord(); + } + } + bridge->ctrl_flags.Reset(BridgeSpec::ControlFlag::InvalidPillarFlags); + bridge->ctrl_flags.Set(BridgeSpec::ControlFlag::CustomPillarFlags); + break; + } + default: ret = CIR_UNKNOWN; break; diff --git a/src/table/bridge_land.h b/src/table/bridge_land.h index 7bf13bb106..c72a5a34f0 100644 --- a/src/table/bridge_land.h +++ b/src/table/bridge_land.h @@ -745,8 +745,42 @@ static const std::span> _bridge_sprite_table[ * @param nrl description of the rail bridge in query tool * @param nrd description of the road bridge in query tool */ -#define MBR(y, mnl, mxl, p, mxs, spr, plt, dsc, nrl, nrd) \ - {TimerGameCalendar::Year{y}, mnl, mxl, p, mxs, spr, plt, dsc, { nrl, nrd }, {}, 0} +#define MBR(y, mnl, mxl, p, mxs, spr, plt, dsc, nrl, nrd, pillars) \ + {TimerGameCalendar::Year{y}, mnl, mxl, p, mxs, spr, plt, dsc, { nrl, nrd }, {}, 0, {}, pillars} + +static constexpr BridgePillarFlags BRIDGEPILLARFLAGS_ALL_CORNERS = { + BridgePillarFlag::CornerW, BridgePillarFlag::CornerS, BridgePillarFlag::CornerE, BridgePillarFlag::CornerN +}; + +/** Pillar flags for bridges which have pillars on the all corners on each piece. */ +static const BridgeMiddlePillarFlags ALL_PILLARS = {{ + {{BRIDGEPILLARFLAGS_ALL_CORNERS, BRIDGEPILLARFLAGS_ALL_CORNERS}}, + {{BRIDGEPILLARFLAGS_ALL_CORNERS, BRIDGEPILLARFLAGS_ALL_CORNERS}}, + {{BRIDGEPILLARFLAGS_ALL_CORNERS, BRIDGEPILLARFLAGS_ALL_CORNERS}}, + {{BRIDGEPILLARFLAGS_ALL_CORNERS, BRIDGEPILLARFLAGS_ALL_CORNERS}}, + {{BRIDGEPILLARFLAGS_ALL_CORNERS, BRIDGEPILLARFLAGS_ALL_CORNERS}}, + {{BRIDGEPILLARFLAGS_ALL_CORNERS, BRIDGEPILLARFLAGS_ALL_CORNERS}}, +}}; + +/** Pillar flags for suspension style bridges. */ +static const BridgeMiddlePillarFlags SUSPENSION_PILLARS = {{ + {{{BridgePillarFlag::CornerW, BridgePillarFlag::CornerS}, {BridgePillarFlag::CornerS, BridgePillarFlag::CornerE}}}, + {{{BridgePillarFlag::CornerE, BridgePillarFlag::CornerN}, {BridgePillarFlag::CornerW, BridgePillarFlag::CornerN}}}, + {{{BridgePillarFlag::CornerE, BridgePillarFlag::CornerN}, {BridgePillarFlag::CornerW, BridgePillarFlag::CornerN}}}, + {{{BridgePillarFlag::CornerW, BridgePillarFlag::CornerS}, {BridgePillarFlag::CornerS, BridgePillarFlag::CornerE}}}, + {{BRIDGEPILLARFLAGS_ALL_CORNERS, BRIDGEPILLARFLAGS_ALL_CORNERS}}, + {{{}, {}}}, +}}; + +/** Pillar flags for cantilever style bridges. */ +static const BridgeMiddlePillarFlags CANTILEVER_PILLARS = {{ + {{{}, {}}}, + {{{BridgePillarFlag::CornerE, BridgePillarFlag::CornerN}, {BridgePillarFlag::CornerW, BridgePillarFlag::CornerN}}}, + {{{BridgePillarFlag::CornerE, BridgePillarFlag::CornerN}, {BridgePillarFlag::CornerW, BridgePillarFlag::CornerN}}}, + {{{BridgePillarFlag::CornerE, BridgePillarFlag::CornerN}, {BridgePillarFlag::CornerW, BridgePillarFlag::CornerN}}}, + {{{BridgePillarFlag::CornerE, BridgePillarFlag::CornerN}, {BridgePillarFlag::CornerW, BridgePillarFlag::CornerN}}}, + {{{BridgePillarFlag::CornerE, BridgePillarFlag::CornerN}, {BridgePillarFlag::CornerW, BridgePillarFlag::CornerN}}}, +}}; const BridgeSpec _orig_bridge[] = { /* @@ -760,43 +794,43 @@ const BridgeSpec _orig_bridge[] = { string with description name on rail name on road | | | | */ MBR( 0, 0, 0xFFFF, 80, 32, 0xA24, PAL_NONE, - STR_BRIDGE_NAME_WOODEN, STR_LAI_BRIDGE_DESCRIPTION_RAIL_WOODEN, STR_LAI_BRIDGE_DESCRIPTION_ROAD_WOODEN), + STR_BRIDGE_NAME_WOODEN, STR_LAI_BRIDGE_DESCRIPTION_RAIL_WOODEN, STR_LAI_BRIDGE_DESCRIPTION_ROAD_WOODEN, ALL_PILLARS), MBR( 0, 0, 2, 112, 48, 0xA26, PALETTE_TO_STRUCT_RED, - STR_BRIDGE_NAME_CONCRETE, STR_LAI_BRIDGE_DESCRIPTION_RAIL_CONCRETE, STR_LAI_BRIDGE_DESCRIPTION_ROAD_CONCRETE), + STR_BRIDGE_NAME_CONCRETE, STR_LAI_BRIDGE_DESCRIPTION_RAIL_CONCRETE, STR_LAI_BRIDGE_DESCRIPTION_ROAD_CONCRETE, ALL_PILLARS), MBR(1930, 0, 5, 144, 64, 0xA25, PAL_NONE, - STR_BRIDGE_NAME_GIRDER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_GIRDER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_GIRDER_STEEL), + STR_BRIDGE_NAME_GIRDER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_GIRDER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_GIRDER_STEEL, ALL_PILLARS), MBR( 0, 2, 10, 168, 80, 0xA22, PALETTE_TO_STRUCT_CONCRETE, - STR_BRIDGE_NAME_SUSPENSION_CONCRETE, STR_LAI_BRIDGE_DESCRIPTION_RAIL_SUSPENSION_CONCRETE, STR_LAI_BRIDGE_DESCRIPTION_ROAD_SUSPENSION_CONCRETE), + STR_BRIDGE_NAME_SUSPENSION_CONCRETE, STR_LAI_BRIDGE_DESCRIPTION_RAIL_SUSPENSION_CONCRETE, STR_LAI_BRIDGE_DESCRIPTION_ROAD_SUSPENSION_CONCRETE, SUSPENSION_PILLARS), MBR(1930, 3, 0xFFFF, 185, 96, 0xA22, PAL_NONE, - STR_BRIDGE_NAME_SUSPENSION_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_SUSPENSION_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_SUSPENSION_STEEL), + STR_BRIDGE_NAME_SUSPENSION_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_SUSPENSION_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_SUSPENSION_STEEL, SUSPENSION_PILLARS), MBR(1930, 3, 0xFFFF, 192, 112, 0xA22, PALETTE_TO_STRUCT_YELLOW, - STR_BRIDGE_NAME_SUSPENSION_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_SUSPENSION_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_SUSPENSION_STEEL), + STR_BRIDGE_NAME_SUSPENSION_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_SUSPENSION_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_SUSPENSION_STEEL, SUSPENSION_PILLARS), MBR(1930, 3, 7, 224, 160, 0xA23, PAL_NONE, - STR_BRIDGE_NAME_CANTILEVER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_CANTILEVER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_CANTILEVER_STEEL), + STR_BRIDGE_NAME_CANTILEVER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_CANTILEVER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_CANTILEVER_STEEL, CANTILEVER_PILLARS), MBR(1930, 3, 8, 232, 208, 0xA23, PALETTE_TO_STRUCT_BROWN, - STR_BRIDGE_NAME_CANTILEVER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_CANTILEVER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_CANTILEVER_STEEL), + STR_BRIDGE_NAME_CANTILEVER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_CANTILEVER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_CANTILEVER_STEEL, CANTILEVER_PILLARS), MBR(1930, 3, 9, 248, 240, 0xA23, PALETTE_TO_STRUCT_RED, - STR_BRIDGE_NAME_CANTILEVER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_CANTILEVER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_CANTILEVER_STEEL), + STR_BRIDGE_NAME_CANTILEVER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_CANTILEVER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_CANTILEVER_STEEL, CANTILEVER_PILLARS), MBR(1930, 0, 2, 240, 256, 0xA27, PAL_NONE, - STR_BRIDGE_NAME_GIRDER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_GIRDER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_GIRDER_STEEL), + STR_BRIDGE_NAME_GIRDER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_GIRDER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_GIRDER_STEEL, ALL_PILLARS), MBR(1995, 2, 0xFFFF, 255, 320, 0xA28, PAL_NONE, - STR_BRIDGE_NAME_TUBULAR_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_TUBULAR_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_TUBULAR_STEEL), + STR_BRIDGE_NAME_TUBULAR_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_TUBULAR_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_TUBULAR_STEEL, CANTILEVER_PILLARS), MBR(2005, 2, 0xFFFF, 380, 512, 0xA28, PALETTE_TO_STRUCT_YELLOW, - STR_BRIDGE_NAME_TUBULAR_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_TUBULAR_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_TUBULAR_STEEL), + STR_BRIDGE_NAME_TUBULAR_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_TUBULAR_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_TUBULAR_STEEL, CANTILEVER_PILLARS), MBR(2010, 2, 0xFFFF, 510, 608, 0xA28, PALETTE_TO_STRUCT_CONCRETE, - STR_BRIDGE_TUBULAR_SILICON, STR_LAI_BRIDGE_DESCRIPTION_RAIL_TUBULAR_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_TUBULAR_STEEL) + STR_BRIDGE_TUBULAR_SILICON, STR_LAI_BRIDGE_DESCRIPTION_RAIL_TUBULAR_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_TUBULAR_STEEL, CANTILEVER_PILLARS), }; #undef MBR