- diff --git a/src/bridge_gui.cpp b/src/bridge_gui.cpp
- index 797ead1..67e8329 100644
- --- a/src/bridge_gui.cpp
- +++ b/src/bridge_gui.cpp
- @@ -36,6 +36,8 @@ static BridgeType _last_railbridge_type = 0;
- /** The type of the last built road bridge */
- static BridgeType _last_roadbridge_type = 0;
- +uint8 _bridge_cur_road_subtype = 0;
- +
- /**
- * Carriage for the data we need if we want to build a bridge
- */
- @@ -117,7 +119,10 @@ private:
- case TRANSPORT_ROAD: _last_roadbridge_type = this->bridges->Get(i)->index; break;
- default: break;
- }
- - DoCommandP(this->end_tile, this->start_tile, this->type | this->bridges->Get(i)->index,
- + // Alberth: It's hacky, but it ensures your bits are preserved (shifting 17 times in a value with width 8 is undefined behavior)
- + uint32 w = _bridge_cur_road_subtype;
- + w <<= 17;
- + DoCommandP(this->end_tile, this->start_tile, this->type | this->bridges->Get(i)->index | w,
- CMD_BUILD_BRIDGE | CMD_MSG(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE), CcBuildBridge);
- }
- @@ -358,10 +363,12 @@ static WindowDesc _build_bridge_desc(
- * @param transport_type The transport type
- * @param road_rail_type The road/rail type
- */
- -void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transport_type, byte road_rail_type)
- +void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transport_type, byte road_rail_type, uint8 cur_road_subtype)
- {
- DeleteWindowByClass(WC_BUILD_BRIDGE);
- + _bridge_cur_road_subtype = cur_road_subtype;
- +
- /* Data type for the bridge.
- * Bit 16,15 = transport type,
- * 14..8 = road/rail types,
- diff --git a/src/bridge_map.h b/src/bridge_map.h
- index 74c6974..4e7984e 100644
- --- a/src/bridge_map.h
- +++ b/src/bridge_map.h
- @@ -148,12 +148,16 @@ static inline void MakeBridgeRamp(TileIndex t, Owner o, BridgeType bridgetype, D
- * @param d the direction this ramp must be facing
- * @param r the road type of the bridge
- */
- -static inline void MakeRoadBridgeRamp(TileIndex t, Owner o, Owner owner_road, Owner owner_tram, BridgeType bridgetype, DiagDirection d, RoadTypes r)
- +static inline void MakeRoadBridgeRamp(TileIndex t, Owner o, Owner owner_road, Owner owner_tram, BridgeType bridgetype, DiagDirection d, RoadTypes r, uint8 cur_road_subtype)
- {
- MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_ROAD, 0);
- SetRoadOwner(t, ROADTYPE_ROAD, owner_road);
- if (owner_tram != OWNER_TOWN) SetRoadOwner(t, ROADTYPE_TRAM, owner_tram);
- SetRoadTypes(t, r);
- + printf("!! Unfinished split between road and tram subtypes in MakeRoadBridgeRamp !! \n");
- + // !! should split before calling this, and pass appropriate road and tram subtypes based on existing / new subtypes for the tile
- + SetRoadSubtype(t, cur_road_subtype);
- + SetTramSubtype(t, cur_road_subtype);
- }
- /**
- diff --git a/src/gui.h b/src/gui.h
- index 39f1ea6..97ee592 100644
- --- a/src/gui.h
- +++ b/src/gui.h
- @@ -61,7 +61,7 @@ void ShowExtraViewPortWindow(TileIndex tile = INVALID_TILE);
- void ShowExtraViewPortWindowForTileUnderCursor();
- /* bridge_gui.cpp */
- -void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transport_type, byte bridge_type);
- +void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transport_type, byte bridge_type, uint8 cur_road_subtype = 0);
- void ShowBuildIndustryWindow();
- void ShowFoundTownWindow();
- diff --git a/src/lang/english.txt b/src/lang/english.txt
- index 0bd430b..b02e251 100644
- --- a/src/lang/english.txt
- +++ b/src/lang/english.txt
- @@ -439,8 +439,13 @@ STR_RAIL_MENU_MAGLEV_CONSTRUCTION :Maglev construc
- ############ range ends here
- ############ range for road construction menu starts
- -STR_ROAD_MENU_ROAD_CONSTRUCTION :Road construction
- -STR_ROAD_MENU_TRAM_CONSTRUCTION :Tramway construction
- +STR_ROAD_MENU_ROAD_CONSTRUCTION :(Deprecated)
- +STR_ROAD_MENU_TRAM_CONSTRUCTION :(Deprecated)
- +STR_ROAD_MENU_ROAD_CONSTRUCTION_0 :Road construction 0
- +STR_ROAD_MENU_ROAD_CONSTRUCTION_1 :Road construction 1
- +STR_ROAD_MENU_TRAM_CONSTRUCTION_0 :Tramway construction 0
- +STR_ROAD_MENU_TRAM_CONSTRUCTION_1 :Tramway construction 1
- +STR_ROAD_MENU_TRAM_CONSTRUCTION_2 :Tramway construction 2
- ############ range ends here
- ############ range for waterways construction menu starts
- diff --git a/src/pathfinder/follow_track.hpp b/src/pathfinder/follow_track.hpp
- index 9f19b02..59c7777 100644
- --- a/src/pathfinder/follow_track.hpp
- +++ b/src/pathfinder/follow_track.hpp
- @@ -102,6 +102,7 @@ struct CFollowTrackT
- assert(IsTram()); // this function shouldn't be called in other cases
- if (IsNormalRoadTile(tile)) {
- + return INVALID_DIAGDIR;
- RoadBits rb = GetRoadBits(tile, ROADTYPE_TRAM);
- switch (rb) {
- case ROAD_NW: return DIAGDIR_NW;
- diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp
- index 2010f9b..68fd2de 100644
- --- a/src/rail_cmd.cpp
- +++ b/src/rail_cmd.cpp
- @@ -33,6 +33,7 @@
- #include "strings_func.h"
- #include "company_gui.h"
- #include "object_map.h"
- +#include "road_type.h"
- #include "table/strings.h"
- #include "table/railtypes.h"
- @@ -636,6 +637,7 @@ CommandCost CmdRemoveSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1,
- owner = GetTileOwner(tile);
- Company::Get(owner)->infrastructure.rail[GetRailType(tile)] -= LEVELCROSSING_TRACKBIT_FACTOR;
- DirtyCompanyInfrastructureWindows(owner);
- + // !! needs subtype detection for crossings
- MakeRoadNormal(tile, GetCrossingRoadBits(tile), GetRoadTypes(tile), GetTownIndex(tile), GetRoadOwner(tile, ROADTYPE_ROAD), GetRoadOwner(tile, ROADTYPE_TRAM));
- DeleteNewGRFInspectWindow(GSF_RAILTYPES, tile);
- }
- diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp
- index aa445eb..b566d44 100644
- --- a/src/road_cmd.cpp
- +++ b/src/road_cmd.cpp
- @@ -326,7 +326,7 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec
- if (present == ROAD_NONE) {
- RoadTypes rts = GetRoadTypes(tile) & ComplementRoadTypes(RoadTypeToRoadTypes(rt));
- - if (rts == ROADTYPES_NONE) {
- + if (!HasRoadType(rt) && !HasTramType(rt)) {
- /* Includes MarkTileDirtyByTile() */
- DoClearSquare(tile);
- } else {
- @@ -374,7 +374,7 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec
- }
- Track railtrack = GetCrossingRailTrack(tile);
- - RoadTypes rts = GetRoadTypes(tile) & ComplementRoadTypes(RoadTypeToRoadTypes(rt));
- + //RoadTypes rts = GetRoadTypes(tile) & ComplementRoadTypes(RoadTypeToRoadTypes(rt));
- if (rts == ROADTYPES_NONE) {
- TrackBits tracks = GetCrossingRailBits(tile);
- bool reserved = HasCrossingReservation(tile);
- @@ -515,6 +515,7 @@ CommandCost CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
- if (!IsValidRoadType(rt) || !ValParamRoadType(rt)) return CMD_ERROR;
- DisallowedRoadDirections toggle_drd = Extract<DisallowedRoadDirections, 6, 2>(p1);
- + uint8 cur_road_subtype = GB(p1, 8, 8);
- Slope tileh = GetTileSlope(tile);
- @@ -749,6 +750,8 @@ do_clear:;
- if (rt == ROADTYPE_ROAD) SetTownIndex(tile, p2);
- }
- if (rtt != ROAD_TILE_CROSSING) SetRoadBits(tile, existing | pieces, rt);
- + SetRoadSubtype(tile, cur_road_subtype);
- + SetTramSubtype(tile, cur_road_subtype);
- break;
- }
- @@ -759,6 +762,8 @@ do_clear:;
- SetRoadTypes(tile, GetRoadTypes(tile) | RoadTypeToRoadTypes(rt));
- SetRoadOwner(other_end, rt, company);
- SetRoadOwner(tile, rt, company);
- + //SetBridgeRoadTramCatenary(other_end, _catenary_flag);
- + //SetBridgeRoadTramCatenary(tile, _catenary_flag);
- /* Mark tiles dirty that have been repaved */
- if (IsBridge(tile)) {
- @@ -777,7 +782,15 @@ do_clear:;
- break;
- default:
- - MakeRoadNormal(tile, pieces, RoadTypeToRoadTypes(rt), p2, company, company);
- + uint8 road_subtype = 0;
- + uint8 tram_subtype = 0;
- + if (rt == ROADTYPE_ROAD) {
- + road_subtype = cur_road_subtype;
- + }
- + if (rt == ROADTYPE_TRAM) {
- + tram_subtype = cur_road_subtype;
- + }
- + MakeRoadNormal(tile, pieces, RoadTypeToRoadTypes(rt), p2, company, company, road_subtype, tram_subtype);
- break;
- }
- @@ -794,7 +807,6 @@ do_clear:;
- SetDisallowedRoadDirections(tile, IsStraightRoad(existing) ?
- GetDisallowedRoadDirections(tile) ^ toggle_drd : DRD_NONE);
- }
- -
- MarkTileDirtyByTile(tile);
- }
- return cost;
- @@ -886,8 +898,8 @@ CommandCost CmdBuildLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32 p
- if (tile == end_tile && !HasBit(p2, 1)) bits &= DiagDirToRoadBits(ReverseDiagDir(dir));
- if (tile == start_tile && HasBit(p2, 0)) bits &= DiagDirToRoadBits(dir);
- }
- -
- - CommandCost ret = DoCommand(tile, drd << 6 | rt << 4 | bits, 0, flags, CMD_BUILD_ROAD);
- + uint8 _cur_road_subtype = GB(p2, 7, 8);
- + CommandCost ret = DoCommand(tile, drd << 6 | rt << 4 | bits | _cur_road_subtype << 8 , 0, flags, CMD_BUILD_ROAD);
- if (ret.Failed()) {
- last_error = ret;
- if (last_error.GetErrorMessage() != STR_ERROR_ALREADY_BUILT) {
- @@ -1298,7 +1310,7 @@ static void DrawRoadBits(TileInfo *ti)
- return;
- }
- - if (tram != ROAD_NONE) DrawTramCatenary(ti, tram);
- + if (RoadTileHasCatenary(ti->tile)) DrawTramCatenary(ti, tram);
- /* Return if full detail is disabled, or we are zoomed fully out. */
- if (!HasBit(_display_opt, DO_FULL_DETAIL) || _cur_dpi->zoom > ZOOM_LVL_DETAIL) return;
- @@ -1388,7 +1400,7 @@ static void DrawTile_Road(TileInfo *ti)
- if (HasTileRoadType(ti->tile, ROADTYPE_TRAM)) {
- DrawGroundSprite(SPR_TRAMWAY_OVERLAY + (GetCrossingRoadAxis(ti->tile) ^ 1), pal);
- - DrawTramCatenary(ti, GetCrossingRoadBits(ti->tile));
- + if (RoadTileHasCatenary(ti->tile)) DrawTramCatenary(ti, GetCrossingRoadBits(ti->tile));
- }
- if (HasCatenaryDrawn(GetRailType(ti->tile))) DrawCatenary(ti);
- break;
- @@ -1623,6 +1635,21 @@ static TrackStatus GetTileTrackStatus_Road(TileIndex tile, TransportType mode, u
- RoadType rt = (RoadType)FindFirstBit(sub_mode);
- RoadBits bits = GetRoadBits(tile, rt);
- + // subtype not sub_mode
- + uint8 road_subtype = GetRoadSubtype(tile);
- + uint8 tram_subtype = GetTramSubtype(tile);
- + // !! ROADTYPES is a bitmask afaict, testing '==' with it is a bad solution?
- + if (sub_mode == ROADTYPES_ROAD) {
- + // road
- + printf("GetTileTrackStatus_Road: road_subtype = %d \n", road_subtype);
- + if (road_subtype != 0) break;
- + }
- + if (sub_mode == ROADTYPES_TRAM) {
- + // tram
- + printf("GetTileTrackStatus_Road: tram_subtype = %d \n", tram_subtype);
- + if (tram_subtype != 0) break;
- + }
- +
- /* no roadbit at this side of tile, return 0 */
- if (side != INVALID_DIAGDIR && (DiagDirToRoadBits(side) & bits) == 0) break;
- @@ -1757,6 +1784,7 @@ static VehicleEnterTileStatus VehicleEnter_Road(Vehicle *v, TileIndex tile, int
- default: break;
- }
- +
- return VETSB_CONTINUE;
- }
- diff --git a/src/road_gui.cpp b/src/road_gui.cpp
- index 92c660e..d989048 100644
- --- a/src/road_gui.cpp
- +++ b/src/road_gui.cpp
- @@ -60,6 +60,7 @@ DECLARE_ENUM_AS_BIT_SET(RoadFlags)
- static RoadFlags _place_road_flag;
- static RoadType _cur_roadtype;
- +uint8 _cur_road_subtype;
- static DiagDirection _road_depot_orientation;
- static DiagDirection _road_station_picker_orientation;
- @@ -231,6 +232,7 @@ static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, u
- ddir -= DIAGDIR_END; // Adjust picker result to actual direction.
- }
- p2 |= ddir << 6; // Set the DiagDirecion into p2 bits 6 and 7.
- + SB(p2, 9, 1, _cur_road_subtype); // !! set _cur_road_subtype into p2 bit 9, only works whilst valid subtype values are 0-1
- TileArea ta(start_tile, end_tile);
- CommandContainer cmdcont = { ta.tile, (uint32)(ta.w | ta.h << 8), p2, cmd, CcRoadStop, "" };
- @@ -535,7 +537,7 @@ struct BuildRoadToolbarWindow : Window {
- break;
- case WID_ROT_BUILD_TUNNEL:
- - DoCommandP(tile, RoadTypeToRoadTypes(_cur_roadtype) | (TRANSPORT_ROAD << 8), 0,
- + DoCommandP(tile, RoadTypeToRoadTypes(_cur_roadtype) | (TRANSPORT_ROAD << 8), _cur_road_subtype,
- CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRoadTunnel);
- break;
- @@ -610,7 +612,8 @@ struct BuildRoadToolbarWindow : Window {
- default: NOT_REACHED();
- case DDSP_BUILD_BRIDGE:
- if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
- - ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_ROAD, RoadTypeToRoadTypes(_cur_roadtype));
- + printf("OnPlaceMouseUp: _cur_road_subtype: %d \n", _cur_road_subtype);
- + ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_ROAD, RoadTypeToRoadTypes(_cur_roadtype), _cur_road_subtype);
- break;
- case DDSP_DEMOLISH_AREA:
- @@ -626,7 +629,7 @@ struct BuildRoadToolbarWindow : Window {
- * not the 3rd bit set) */
- _place_road_flag = (RoadFlags)((_place_road_flag & RF_DIR_Y) ? (_place_road_flag & 0x07) : (_place_road_flag >> 3));
- - DoCommandP(start_tile, end_tile, _place_road_flag | (_cur_roadtype << 3) | (_one_way_button_clicked << 5),
- + DoCommandP(start_tile, end_tile, _place_road_flag | (_cur_roadtype << 3) | (_one_way_button_clicked << 5) | (_cur_road_subtype << 7),
- _remove_button_clicked ?
- CMD_REMOVE_LONG_ROAD | CMD_MSG(_road_type_infos[_cur_roadtype].err_remove_road) :
- CMD_BUILD_LONG_ROAD | CMD_MSG(_road_type_infos[_cur_roadtype].err_build_road), CcPlaySound1D);
- @@ -657,7 +660,7 @@ struct BuildRoadToolbarWindow : Window {
- virtual void OnPlacePresize(Point pt, TileIndex tile)
- {
- - DoCommand(tile, RoadTypeToRoadTypes(_cur_roadtype) | (TRANSPORT_ROAD << 8), 0, DC_AUTO, CMD_BUILD_TUNNEL);
- + DoCommand(tile, RoadTypeToRoadTypes(_cur_roadtype) | (TRANSPORT_ROAD << 8), _cur_road_subtype, DC_AUTO, CMD_BUILD_TUNNEL);
- VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile);
- }
- @@ -802,10 +805,11 @@ static WindowDesc _build_tramway_desc(
- *
- * @return newly opened road toolbar, or NULL if the toolbar could not be opened.
- */
- -Window *ShowBuildRoadToolbar(RoadType roadtype)
- +Window *ShowBuildRoadToolbar(RoadType roadtype, uint8 road_subtype)
- {
- if (!Company::IsValidID(_local_company)) return NULL;
- _cur_roadtype = roadtype;
- + _cur_road_subtype = road_subtype;
- DeleteWindowByClass(WC_BUILD_TOOLBAR);
- return AllocateWindowDescFront<BuildRoadToolbarWindow>(roadtype == ROADTYPE_ROAD ? &_build_road_desc : &_build_tramway_desc, TRANSPORT_ROAD);
- diff --git a/src/road_gui.h b/src/road_gui.h
- index c56443c..1802e11 100644
- --- a/src/road_gui.h
- +++ b/src/road_gui.h
- @@ -16,7 +16,7 @@
- #include "tile_type.h"
- #include "direction_type.h"
- -struct Window *ShowBuildRoadToolbar(RoadType roadtype);
- +struct Window *ShowBuildRoadToolbar(RoadType roadtype, uint8 road_subtype = 0);
- struct Window *ShowBuildRoadScenToolbar();
- void ConnectRoadToStructure(TileIndex tile, DiagDirection direction);
- diff --git a/src/road_internal.h b/src/road_internal.h
- index c8cae84..0b7532b 100644
- --- a/src/road_internal.h
- +++ b/src/road_internal.h
- @@ -13,6 +13,7 @@
- #define ROAD_INTERNAL_H
- #include "tile_cmd.h"
- +#include "road_map.h"
- #include "road_type.h"
- RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb);
- @@ -21,4 +22,11 @@ CommandCost CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, R
- void DrawTramCatenary(const TileInfo *ti, RoadBits tram);
- +static inline bool RoadTileHasCatenary(const TileIndex tile) {
- + uint8 road_subtype = GetRoadSubtype(tile);
- + uint8 tram_subtype = GetTramSubtype(tile);
- + return (RoadSubtypeHasCatenary(road_subtype) || TramSubtypeHasCatenary(tram_subtype));
- +}
- +
- +
- #endif /* ROAD_INTERNAL_H */
- diff --git a/src/road_map.h b/src/road_map.h
- index 6937302..663517a 100644
- --- a/src/road_map.h
- +++ b/src/road_map.h
- @@ -286,6 +286,30 @@ static inline void SetDisallowedRoadDirections(TileIndex t, DisallowedRoadDirect
- SB(_m[t].m5, 4, 2, drd);
- }
- +static inline void SetRoadSubtype(TileIndex t, uint8 subtype)
- +{
- + assert(IsTileType(t, MP_ROAD) || IsTileType(t, MP_STATION) || IsTileType(t, MP_TUNNELBRIDGE));
- + //assert(subtype <= 3); // we're only using 2 bits here, only 4 subtypes permitted
- + SB(_m[t].m4, 4, 4, subtype);
- +}
- +
- +static inline void SetTramSubtype(TileIndex t, uint8 subtype)
- +{
- + assert(IsTileType(t, MP_ROAD) || IsTileType(t, MP_STATION) || IsTileType(t, MP_TUNNELBRIDGE));
- + //assert(subtype <= 3); // we're only using 2 bits here, only 4 subtypes permitted
- + SB(_m[t].m4, 0, 4, subtype);
- +}
- +
- +static inline uint8 GetRoadSubtype(TileIndex t)
- +{
- + return GB(_m[t].m4, 4, 4);
- +}
- +
- +static inline uint8 GetTramSubtype(TileIndex t)
- +{
- + return GB(_m[t].m4, 0, 4);
- +}
- +
- /**
- * Get the road axis of a level crossing.
- * @param t The tile to query.
- @@ -550,7 +574,7 @@ RoadBits GetAnyRoadBits(TileIndex tile, RoadType rt, bool straight_tunnel_bridge
- * @param road New owner of road.
- * @param tram New owner of tram tracks.
- */
- -static inline void MakeRoadNormal(TileIndex t, RoadBits bits, RoadTypes rot, TownID town, Owner road, Owner tram)
- +static inline void MakeRoadNormal(TileIndex t, RoadBits bits, RoadTypes rot, TownID town, Owner road, Owner tram, uint8 road_subtype = 0, uint8 tram_subtype = 0)
- {
- SetTileType(t, MP_ROAD);
- SetTileOwner(t, road);
- @@ -561,6 +585,8 @@ static inline void MakeRoadNormal(TileIndex t, RoadBits bits, RoadTypes rot, Tow
- SB(_me[t].m6, 2, 4, 0);
- _me[t].m7 = rot << 6;
- SetRoadOwner(t, ROADTYPE_TRAM, tram);
- + SetRoadSubtype(t, road_subtype);
- + SetTramSubtype(t, tram_subtype);
- }
- /**
- diff --git a/src/road_type.h b/src/road_type.h
- index 5251a53..40b961e 100644
- --- a/src/road_type.h
- +++ b/src/road_type.h
- @@ -29,22 +29,42 @@ enum RoadType {
- DECLARE_POSTFIX_INCREMENT(RoadType)
- template <> struct EnumPropsT<RoadType> : MakeEnumPropsT<RoadType, byte, ROADTYPE_BEGIN, ROADTYPE_END, INVALID_ROADTYPE, 2> {};
- -/**
- - * The different roadtypes we support, but then a bitmask of them
- - * @note currently only roadtypes with ROADTYPE_ROAD and ROADTYPE_TRAM are supported.
- - */
- +// RoadTypes, with ability to get road type, tram type, or look up roadtype given subtype
- enum RoadTypes {
- - ROADTYPES_NONE = 0, ///< No roadtypes
- - ROADTYPES_ROAD = 1 << ROADTYPE_ROAD, ///< Road
- - ROADTYPES_TRAM = 1 << ROADTYPE_TRAM, ///< Trams
- - ROADTYPES_ALL = ROADTYPES_ROAD | ROADTYPES_TRAM, ///< Road + trams
- - ROADTYPES_END, ///< Used for iterations?
- - INVALID_ROADTYPES = 0xFF, ///< Invalid roadtypes
- + ROADTYPES_ROAD_BASE = 0,
- + ROADTYPES_ROAD_LENGTH = 4, ///< Number of bit
- + ROADTYPES_INVALID_ROAD = 0x7, ///< Road-type denoting 'no road'.
- +
- + ROADTYPES_TRAM_BASE = 4, ///< Start bit of the tram types.
- + ROADTYPES_TRAM_LENGTH = 4, ///< Number of bits for the tram types.
- + ROADTYPES_INVALID_TRAM = 0x7, ///< Tram-type denoting 'no tram'.
- };
- -DECLARE_ENUM_AS_BIT_SET(RoadTypes)
- -template <> struct EnumPropsT<RoadTypes> : MakeEnumPropsT<RoadTypes, byte, ROADTYPES_NONE, ROADTYPES_END, INVALID_ROADTYPES, 2> {};
- -typedef SimpleTinyEnumT<RoadTypes, byte> RoadTypesByte;
- +static inline uint8 GetRoadType(RoadTypes rt) {
- + return GB(rt, ROADTYPES_ROAD_BASE, ROADTYPES_ROAD_LENGTH);
- +}
- +
- +static inline uint8 GetTramType(RoadTypes rt) {
- + return GB(rt, ROADTYPES_TRAM_BASE, ROADTYPES_TRAM_LENGTH);
- +}
- +
- +static inline RoadTypes SetRoadType(RoadTypes rt, uint8 road_type) {
- + assert((road_type & ((1 << ROADTYPES_ROAD_LENGTH) - 1)) == road_type);
- + return (RoadTypes)SB(rt, ROADTYPES_ROAD_BASE, ROADTYPES_ROAD_LENGTH, road_type);
- +}
- +
- +static inline RoadTypes SetTramType(RoadTypes rt, uint8 tram_type) {
- + assert((tram_type & ((1 << ROADTYPES_TRAM_LENGTH) - 1)) == tram_type);
- + return (RoadTypes)SB(rt, ROADTYPES_TRAM_BASE, ROADTYPES_TRAM_LENGTH, tram_type);
- +}
- +
- +static inline bool HasRoadType(rt) {
- + return GetRoadType(rt) != ROADTYPES_ROAD_INVALID;
- +}
- +
- +static inline bool HasTramType(rt) {
- + return GetTramType(rt) != ROADTYPES_TRAM_INVALID;
- +}
- /**
- * Enumeration for the road parts on a tile.
- @@ -73,4 +93,19 @@ enum RoadBits {
- DECLARE_ENUM_AS_BIT_SET(RoadBits)
- template <> struct EnumPropsT<RoadBits> : MakeEnumPropsT<RoadBits, byte, ROAD_NONE, ROAD_END, ROAD_NONE, 4> {};
- +static inline bool RoadSubtypeHasCatenary(uint8 subtype) {
- + if (subtype == 1) {
- + return true;
- + } else {
- + return false;
- + }
- +}
- +static inline bool TramSubtypeHasCatenary(uint8 subtype) {
- + if (subtype == 1) {
- + return true;
- + } else {
- + return false;
- + }
- +}
- +
- #endif /* ROAD_TYPE_H */
- diff --git a/src/roadveh.h b/src/roadveh.h
- index 5b265f0..ed2f409 100644
- --- a/src/roadveh.h
- +++ b/src/roadveh.h
- @@ -95,7 +95,8 @@ struct RoadVehicle FINAL : public GroundVehicle<RoadVehicle, VEH_ROAD> {
- byte reverse_ctr;
- RoadType roadtype;
- - RoadTypes compatible_roadtypes;
- + uint8 subtype;
- + uint16 compatible_roadtypes; // first 8 bits are RoadTypes, next bits are subtype
- /** We don't want GCC to zero our struct! It already is zeroed and has an index! */
- RoadVehicle() : GroundVehicleBase() {}
- diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp
- index 35c671d..7149bd5 100644
- --- a/src/roadveh_cmd.cpp
- +++ b/src/roadveh_cmd.cpp
- @@ -1208,7 +1208,7 @@ again:
- }
- if ((v->Previous() != NULL && v->Previous()->tile == tile) ||
- (v->IsFrontEngine() && IsNormalRoadTile(tile) && !HasRoadWorks(tile) &&
- - (needed & GetRoadBits(tile, ROADTYPE_TRAM)) != ROAD_NONE)) {
- + (needed & GetRoadBits(tile, ROADTYPE_TRAM)) != ROAD_NONE) && (GetTramSubtype(tile) == 0)) {
- /*
- * Taking the 'big' corner for trams only happens when:
- * - The previous vehicle in this (articulated) tram chain is
- diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp
- index eb90c29..1109193 100644
- --- a/src/station_cmd.cpp
- +++ b/src/station_cmd.cpp
- @@ -1759,6 +1759,11 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
- bool reuse = (station_to_join != NEW_STATION);
- if (!reuse) station_to_join = INVALID_STATION;
- bool distant_join = (station_to_join != INVALID_STATION);
- + bool catenary_flag = HasBit(p2, 9); // the setting from the selected roadtype
- + bool cur_tile_catenary_flag = catenary_flag; // used to set catenary flag on any given tile
- + printf("CmdBuildRoadStop called %d ", tile);
- + printf("catenary_flag %d ", catenary_flag);
- + printf("\n");
- uint8 width = (uint8)GB(p1, 0, 8);
- uint8 lenght = (uint8)GB(p1, 8, 8);
- @@ -1815,6 +1820,12 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
- /* Check every tile in the area. */
- TILE_AREA_LOOP(cur_tile, roadstop_area) {
- RoadTypes cur_rts = GetRoadTypes(cur_tile);
- + // don't remove existing catenary if present
- + if (RoadTileHasCatenary(cur_tile)) {
- + cur_tile_catenary_flag = true;
- + } else {
- + cur_tile_catenary_flag = catenary_flag;
- + }
- Owner road_owner = HasBit(cur_rts, ROADTYPE_ROAD) ? GetRoadOwner(cur_tile, ROADTYPE_ROAD) : _current_company;
- Owner tram_owner = HasBit(cur_rts, ROADTYPE_TRAM) ? GetRoadOwner(cur_tile, ROADTYPE_TRAM) : _current_company;
- @@ -1851,7 +1862,7 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
- }
- }
- - MakeDriveThroughRoadStop(cur_tile, st->owner, road_owner, tram_owner, st->index, rs_type, rts | cur_rts, axis);
- + MakeDriveThroughRoadStop(cur_tile, st->owner, road_owner, tram_owner, st->index, rs_type, rts | cur_rts, axis, cur_tile_catenary_flag);
- road_stop->MakeDriveThrough();
- } else {
- /* Non-drive-through stop never overbuild and always count as two road bits. */
- @@ -2013,6 +2024,7 @@ CommandCost CmdRemoveRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, ui
- uint8 width = (uint8)GB(p1, 0, 8);
- uint8 height = (uint8)GB(p1, 8, 8);
- bool keep_drive_through_roads = !HasBit(p2, 1);
- + bool keep_catenary = false;
- /* Check for incorrect width / height. */
- if (width == 0 || height == 0) return CMD_ERROR;
- @@ -2030,6 +2042,11 @@ CommandCost CmdRemoveRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, ui
- TILE_AREA_LOOP(cur_tile, roadstop_area) {
- /* Make sure the specified tile is a road stop of the correct type */
- if (!IsTileType(cur_tile, MP_STATION) || !IsRoadStop(cur_tile) || (uint32)GetRoadStopType(cur_tile) != GB(p2, 0, 1)) continue;
- + if (RoadTileHasCatenary(cur_tile)) {
- + keep_catenary = true;
- + } else {
- + keep_catenary = false;
- + }
- /* Save information on to-be-restored roads before the stop is removed. */
- RoadTypes rts = ROADTYPES_NONE;
- @@ -2057,7 +2074,7 @@ CommandCost CmdRemoveRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, ui
- /* Restore roads. */
- if ((flags & DC_EXEC) && rts != ROADTYPES_NONE) {
- MakeRoadNormal(cur_tile, road_bits, rts, ClosestTownFromTile(cur_tile, UINT_MAX)->index,
- - road_owner[ROADTYPE_ROAD], road_owner[ROADTYPE_TRAM]);
- + road_owner[ROADTYPE_ROAD], road_owner[ROADTYPE_TRAM], keep_catenary);
- /* Update company infrastructure counts. */
- RoadType rt;
- @@ -2902,7 +2919,7 @@ draw_default_foundation:
- if (HasBit(roadtypes, ROADTYPE_TRAM)) {
- Axis axis = GetRoadStopDir(ti->tile) == DIAGDIR_NE ? AXIS_X : AXIS_Y;
- DrawGroundSprite((HasBit(roadtypes, ROADTYPE_ROAD) ? SPR_TRAMWAY_OVERLAY : SPR_TRAMWAY_TRAM) + (axis ^ 1), PAL_NONE);
- - DrawTramCatenary(ti, axis == AXIS_X ? ROAD_X : ROAD_Y);
- + if (HasRoadTramCatenary(ti->tile)) DrawTramCatenary(ti, axis == AXIS_X ? ROAD_X : ROAD_Y);
- }
- if (IsRailWaypoint(ti->tile)) {
- diff --git a/src/station_map.h b/src/station_map.h
- index 7ca9bd7..8a101ad 100644
- --- a/src/station_map.h
- +++ b/src/station_map.h
- @@ -521,6 +521,17 @@ static inline byte GetStationTileRandomBits(TileIndex t)
- return GB(_m[t].m3, 4, 4);
- }
- +static inline void SetRoadTramCatenary(TileIndex t, bool b)
- +{
- + assert(IsTileType(t, MP_STATION));
- + SB(_m[t].m1, 7, 1, b ? 1 : 0);
- +}
- +
- +static inline bool HasRoadTramCatenary(TileIndex t)
- +{
- + return GB(_m[t].m1, 7, 1);
- +}
- +
- /**
- * Make the given tile a station tile.
- * @param t the tile to make a station tile
- @@ -604,12 +615,13 @@ static inline void MakeRoadStop(TileIndex t, Owner o, StationID sid, RoadStopTyp
- * @param rt the roadtypes on this tile
- * @param a the direction of the roadstop
- */
- -static inline void MakeDriveThroughRoadStop(TileIndex t, Owner station, Owner road, Owner tram, StationID sid, RoadStopType rst, RoadTypes rt, Axis a)
- +static inline void MakeDriveThroughRoadStop(TileIndex t, Owner station, Owner road, Owner tram, StationID sid, RoadStopType rst, RoadTypes rt, Axis a, bool catenary_flag)
- {
- MakeStation(t, station, sid, (rst == ROADSTOP_BUS ? STATION_BUS : STATION_TRUCK), GFX_TRUCK_BUS_DRIVETHROUGH_OFFSET + a);
- SetRoadTypes(t, rt);
- SetRoadOwner(t, ROADTYPE_ROAD, road);
- SetRoadOwner(t, ROADTYPE_TRAM, tram);
- + SetRoadTramCatenary(t, catenary_flag);
- }
- /**
- diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp
- index 45d751d..c62c395 100644
- --- a/src/toolbar_gui.cpp
- +++ b/src/toolbar_gui.cpp
- @@ -891,7 +891,8 @@ static CallBackFunction ToolbarBuildRoadClick(Window *w)
- DropDownList *list = new DropDownList();
- /* Road is always visible and available. */
- - *list->Append() = new DropDownListStringItem(STR_ROAD_MENU_ROAD_CONSTRUCTION, ROADTYPE_ROAD, false);
- + *list->Append() = new DropDownListStringItem(STR_ROAD_MENU_ROAD_CONSTRUCTION_0, 0, false);
- + *list->Append() = new DropDownListStringItem(STR_ROAD_MENU_ROAD_CONSTRUCTION_1, 1, false);
- /* Tram is only visible when there will be a tram, and available when that has been introduced. */
- Engine *e;
- @@ -899,7 +900,9 @@ static CallBackFunction ToolbarBuildRoadClick(Window *w)
- if (!HasBit(e->info.climates, _settings_game.game_creation.landscape)) continue;
- if (!HasBit(e->info.misc_flags, EF_ROAD_TRAM)) continue;
- - *list->Append() = new DropDownListStringItem(STR_ROAD_MENU_TRAM_CONSTRUCTION, ROADTYPE_TRAM, !HasBit(c->avail_roadtypes, ROADTYPE_TRAM));
- + *list->Append() = new DropDownListStringItem(STR_ROAD_MENU_TRAM_CONSTRUCTION_0, 2, !HasBit(c->avail_roadtypes, ROADTYPE_TRAM));
- + *list->Append() = new DropDownListStringItem(STR_ROAD_MENU_TRAM_CONSTRUCTION_1, 3, !HasBit(c->avail_roadtypes, ROADTYPE_TRAM));
- + *list->Append() = new DropDownListStringItem(STR_ROAD_MENU_TRAM_CONSTRUCTION_2, 4, !HasBit(c->avail_roadtypes, ROADTYPE_TRAM));
- break;
- }
- ShowDropDownList(w, list, _last_built_roadtype, WID_TN_ROADS, 140, true, true);
- @@ -915,8 +918,24 @@ static CallBackFunction ToolbarBuildRoadClick(Window *w)
- */
- static CallBackFunction MenuClickBuildRoad(int index)
- {
- - _last_built_roadtype = (RoadType)index;
- - ShowBuildRoadToolbar(_last_built_roadtype);
- + uint8 _last_built_road_subtype = 0;
- + if (index == 0) {
- + _last_built_roadtype = (RoadType)ROADTYPE_ROAD;
- + _last_built_road_subtype = 0;
- + } else if (index == 1) {
- + _last_built_roadtype = (RoadType)ROADTYPE_ROAD;
- + _last_built_road_subtype = 1;
- + } else if (index == 2) {
- + _last_built_roadtype = (RoadType)ROADTYPE_TRAM;
- + _last_built_road_subtype = 0;
- + } else if (index == 3) {
- + _last_built_roadtype = (RoadType)ROADTYPE_TRAM;
- + _last_built_road_subtype = 1;
- + } else if (index == 4) {
- + _last_built_roadtype = (RoadType)ROADTYPE_TRAM;
- + _last_built_road_subtype = 2;
- + }
- + ShowBuildRoadToolbar(_last_built_roadtype, _last_built_road_subtype);
- return CBF_NONE;
- }
- diff --git a/src/tunnel_map.h b/src/tunnel_map.h
- index e200a12..d9c24dd 100644
- --- a/src/tunnel_map.h
- +++ b/src/tunnel_map.h
- @@ -48,7 +48,7 @@ bool IsTunnelInWayDir(TileIndex tile, int z, DiagDirection dir);
- * @param d the direction facing out of the tunnel
- * @param r the road type used in the tunnel
- */
- -static inline void MakeRoadTunnel(TileIndex t, Owner o, DiagDirection d, RoadTypes r)
- +static inline void MakeRoadTunnel(TileIndex t, Owner o, DiagDirection d, RoadTypes r, uint8 cur_road_subtype)
- {
- SetTileType(t, MP_TUNNELBRIDGE);
- SetTileOwner(t, o);
- @@ -61,6 +61,10 @@ static inline void MakeRoadTunnel(TileIndex t, Owner o, DiagDirection d, RoadTyp
- SetRoadOwner(t, ROADTYPE_ROAD, o);
- if (o != OWNER_TOWN) SetRoadOwner(t, ROADTYPE_TRAM, o);
- SetRoadTypes(t, r);
- + printf("!! Unfinished split between road and tram subtypes in MakeRoadTunnel !! \n");
- + // !! should split before calling this, and pass appropriate road and tram subtypes based on existing / new subtypes for the tile
- + SetRoadSubtype(t, cur_road_subtype);
- + SetTramSubtype(t, cur_road_subtype);
- }
- /**
- diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp
- index 5f2534b..4160cb5 100644
- --- a/src/tunnelbridge_cmd.cpp
- +++ b/src/tunnelbridge_cmd.cpp
- @@ -40,6 +40,7 @@
- #include "object_base.h"
- #include "water.h"
- #include "company_gui.h"
- +#include "road_internal.h"
- #include "table/strings.h"
- #include "table/bridge_land.h"
- @@ -515,8 +516,9 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u
- }
- Owner owner_road = HasBit(prev_roadtypes, ROADTYPE_ROAD) ? GetRoadOwner(tile_start, ROADTYPE_ROAD) : company;
- Owner owner_tram = HasBit(prev_roadtypes, ROADTYPE_TRAM) ? GetRoadOwner(tile_start, ROADTYPE_TRAM) : company;
- - MakeRoadBridgeRamp(tile_start, owner, owner_road, owner_tram, bridge_type, dir, roadtypes);
- - MakeRoadBridgeRamp(tile_end, owner, owner_road, owner_tram, bridge_type, ReverseDiagDir(dir), roadtypes);
- + uint8 cur_road_subtype = GB(p2, 17, 8);
- + MakeRoadBridgeRamp(tile_start, owner, owner_road, owner_tram, bridge_type, dir, roadtypes, cur_road_subtype);
- + MakeRoadBridgeRamp(tile_end, owner, owner_road, owner_tram, bridge_type, ReverseDiagDir(dir), roadtypes, cur_road_subtype);
- break;
- }
- @@ -589,6 +591,8 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1,
- RailType railtype = INVALID_RAILTYPE;
- RoadTypes rts = ROADTYPES_NONE;
- _build_tunnel_endtile = 0;
- + uint8 _build_tunnel_cur_road_subtype = GB(p2, 0, 8);
- +
- switch (transport_type) {
- case TRANSPORT_RAIL:
- railtype = Extract<RailType, 0, 4>(p1);
- @@ -731,8 +735,8 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1,
- c->infrastructure.road[rt] += num_pieces * 2; // A full diagonal road has two road bits.
- }
- }
- - MakeRoadTunnel(start_tile, company, direction, rts);
- - MakeRoadTunnel(end_tile, company, ReverseDiagDir(direction), rts);
- + MakeRoadTunnel(start_tile, company, direction, rts, _build_tunnel_cur_road_subtype);
- + MakeRoadTunnel(end_tile, company, ReverseDiagDir(direction), rts, _build_tunnel_cur_road_subtype);
- }
- DirtyCompanyInfrastructureWindows(company);
- }
- @@ -1087,7 +1091,7 @@ static void DrawBridgePillars(const PalSpriteID *psid, const TileInfo *ti, Axis
- * @param overlay do we want to still see the road?
- * @param head are we drawing bridge head?
- */
- -static void DrawBridgeTramBits(int x, int y, int z, int offset, bool overlay, bool head)
- +static void DrawBridgeTramBits(int x, int y, int z, int offset, bool overlay, bool head, bool has_catenary)
- {
- static const SpriteID tram_offsets[2][6] = { { 107, 108, 109, 110, 111, 112 }, { 4, 5, 15, 16, 17, 18 } };
- static const SpriteID back_offsets[6] = { 95, 96, 99, 102, 100, 101 };
- @@ -1107,7 +1111,7 @@ static void DrawBridgeTramBits(int x, int y, int z, int offset, bool overlay, bo
- }
- /* Do not draw catenary if it is set invisible */
- - if (!IsInvisibilitySet(TO_CATENARY)) {
- + if (has_catenary && !IsInvisibilitySet(TO_CATENARY)) {
- AddSortableSpriteToDraw(SPR_TRAMWAY_BASE + back_offsets[offset], PAL_NONE,
- x, y, size_x[offset], size_y[offset], 0x28, z,
- IsTransparencySet(TO_CATENARY));
- @@ -1118,7 +1122,7 @@ static void DrawBridgeTramBits(int x, int y, int z, int offset, bool overlay, bo
- StartSpriteCombine();
- /* For sloped sprites the bounding box needs to be higher, as the pylons stop on a higher point */
- - if (!IsInvisibilitySet(TO_CATENARY)) {
- + if (has_catenary && !IsInvisibilitySet(TO_CATENARY)) {
- AddSortableSpriteToDraw(SPR_TRAMWAY_BASE + front_offsets[offset], PAL_NONE,
- x, y, size_x[offset] + front_bb_offset_x[offset], size_y[offset] + front_bb_offset_y[offset], 0x28, z,
- IsTransparencySet(TO_CATENARY), front_bb_offset_x[offset], front_bb_offset_y[offset]);
- @@ -1193,7 +1197,7 @@ static void DrawTile_TunnelBridge(TileInfo *ti)
- DrawGroundSprite(SPR_TRAMWAY_BASE + tunnel_sprites[rts - ROADTYPES_TRAM][tunnelbridge_direction], PAL_NONE);
- /* Do not draw wires if they are invisible */
- - if (!IsInvisibilitySet(TO_CATENARY)) {
- + if (RoadTileHasCatenary(ti->tile) && !IsInvisibilitySet(TO_CATENARY)) {
- catenary = true;
- StartSpriteCombine();
- AddSortableSpriteToDraw(SPR_TRAMWAY_TUNNEL_WIRES + tunnelbridge_direction, PAL_NONE, ti->x, ti->y, BB_data[10], BB_data[11], TILE_HEIGHT, ti->z, IsTransparencySet(TO_CATENARY), BB_data[8], BB_data[9], BB_Z_SEPARATOR);
- @@ -1303,7 +1307,7 @@ static void DrawTile_TunnelBridge(TileInfo *ti)
- offset += 2;
- }
- /* DrawBridgeTramBits() calls EndSpriteCombine() and StartSpriteCombine() */
- - DrawBridgeTramBits(ti->x, ti->y, z, offset, HasBit(rts, ROADTYPE_ROAD), true);
- + DrawBridgeTramBits(ti->x, ti->y, z, offset, HasBit(rts, ROADTYPE_ROAD), true, RoadTileHasCatenary(ti->tile));
- }
- EndSpriteCombine();
- } else if (transport_type == TRANSPORT_RAIL) {
- @@ -1466,7 +1470,7 @@ void DrawBridgeMiddle(const TileInfo *ti)
- if (HasBit(rts, ROADTYPE_TRAM)) {
- /* DrawBridgeTramBits() calls EndSpriteCombine() and StartSpriteCombine() */
- - DrawBridgeTramBits(x, y, bridge_z, axis ^ 1, HasBit(rts, ROADTYPE_ROAD), false);
- + DrawBridgeTramBits(x, y, bridge_z, axis ^ 1, HasBit(rts, ROADTYPE_ROAD), false, RoadTileHasCatenary(ti->tile));
- } else {
- EndSpriteCombine();
- StartSpriteCombine();