diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index aa445eb..37e9f9c 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -477,6 +477,7 @@ static CommandCost CheckRoadSlope(Slope tileh, RoadBits *pieces, RoadBits existi * @param p1 bit 0..3 road pieces to build (RoadBits) * bit 4..5 road type * bit 6..7 disallowed directions to toggle + * bit 8 catenary * @param p2 the town that is building the road (0 if not applicable) * @param text unused * @return the cost of this operation or an error @@ -515,6 +516,7 @@ CommandCost CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 if (!IsValidRoadType(rt) || !ValParamRoadType(rt)) return CMD_ERROR; DisallowedRoadDirections toggle_drd = Extract(p1); + bool _catenary_button_clicked = HasBit(p1, 8); Slope tileh = GetTileSlope(tile); @@ -778,6 +780,7 @@ do_clear:; default: MakeRoadNormal(tile, pieces, RoadTypeToRoadTypes(rt), p2, company, company); + SetCatenary(tile, _catenary_button_clicked); break; } @@ -827,6 +830,7 @@ static bool CanConnectToRoad(TileIndex tile, RoadType rt, DiagDirection dir) * - p2 = (bit 6) - defines two different behaviors for this command: * - 0 = Build up to an obstacle. Do not build the first and last roadbits unless they can be connected to something, or if we are building a single tile * - 1 = Fail if an obstacle is found. Always take into account bit 0 and 1. This behavior is used for scripts + * - p2 = (bit 7) - catenary * @param text unused * @return the cost of this operation or an error */ @@ -886,8 +890,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); + bool _has_catenary = HasBit(p2, 7); + CommandCost ret = DoCommand(tile, drd << 6 | rt << 4 | bits | _has_catenary << 8 , 0, flags, CMD_BUILD_ROAD); if (ret.Failed()) { last_error = ret; if (last_error.GetErrorMessage() != STR_ERROR_ALREADY_BUILT) { @@ -1298,7 +1302,7 @@ static void DrawRoadBits(TileInfo *ti) return; } - if (tram != ROAD_NONE) DrawTramCatenary(ti, tram); + if (HasCatenary(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 +1392,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 (HasCatenary(ti->tile)) DrawTramCatenary(ti, GetCrossingRoadBits(ti->tile)); } if (HasCatenaryDrawn(GetRailType(ti->tile))) DrawCatenary(ti); break; diff --git a/src/road_gui.cpp b/src/road_gui.cpp index 92c660e..5392940 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -41,6 +41,7 @@ static void ShowRoadDepotPicker(Window *parent); static bool _remove_button_clicked; static bool _one_way_button_clicked; +static bool _catenary_button_clicked; /** * Define the values of the RoadFlags @@ -359,13 +360,15 @@ struct BuildRoadToolbarWindow : Window { */ void UpdateOptionWidgetStatus(RoadToolbarWidgets clicked_widget) { - /* The remove and the one way button state is driven + /* The remove and the one way / catenary buttons state is driven * by the other buttons so they don't act on themselves. - * Both are only valid if they are able to apply as options. */ + * They are only valid if they are able to apply as options. */ switch (clicked_widget) { case WID_ROT_REMOVE: this->RaiseWidget(WID_ROT_ONE_WAY); this->SetWidgetDirty(WID_ROT_ONE_WAY); + this->RaiseWidget(WID_ROT_CATENARY); + this->SetWidgetDirty(WID_ROT_CATENARY); break; case WID_ROT_ONE_WAY: @@ -373,6 +376,11 @@ struct BuildRoadToolbarWindow : Window { this->SetWidgetDirty(WID_ROT_REMOVE); break; + case WID_ROT_CATENARY: + this->RaiseWidget(WID_ROT_REMOVE); + this->SetWidgetDirty(WID_ROT_REMOVE); + break; + case WID_ROT_BUS_STATION: case WID_ROT_TRUCK_STATION: this->DisableWidget(WID_ROT_ONE_WAY); @@ -385,6 +393,7 @@ struct BuildRoadToolbarWindow : Window { this->SetWidgetsDisabledState(!this->IsWidgetLowered(clicked_widget), WID_ROT_REMOVE, WID_ROT_ONE_WAY, + WID_ROT_CATENARY, WIDGET_LIST_END); break; @@ -394,10 +403,12 @@ struct BuildRoadToolbarWindow : Window { this->SetWidgetsDisabledState(true, WID_ROT_REMOVE, WID_ROT_ONE_WAY, + WID_ROT_CATENARY, WIDGET_LIST_END); this->SetWidgetsLoweredState(false, WID_ROT_REMOVE, WID_ROT_ONE_WAY, + WID_ROT_CATENARY, WIDGET_LIST_END); break; } @@ -407,6 +418,7 @@ struct BuildRoadToolbarWindow : Window { { _remove_button_clicked = false; _one_way_button_clicked = false; + _catenary_button_clicked = false; switch (widget) { case WID_ROT_ROAD_X: HandlePlacePushButton(this, WID_ROT_ROAD_X, _road_type_infos[_cur_roadtype].cursor_nwse, HT_RECT); @@ -459,6 +471,13 @@ struct BuildRoadToolbarWindow : Window { SetSelectionRed(false); break; + case WID_ROT_CATENARY: + if (this->IsWidgetDisabled(WID_ROT_CATENARY)) return; + this->SetDirty(); + this->ToggleWidgetLoweredState(WID_ROT_CATENARY); + SetSelectionRed(false); + break; + case WID_ROT_BUILD_BRIDGE: HandlePlacePushButton(this, WID_ROT_BUILD_BRIDGE, SPR_CURSOR_BRIDGE, HT_RECT); this->last_started_action = widget; @@ -493,6 +512,7 @@ struct BuildRoadToolbarWindow : Window { { _remove_button_clicked = this->IsWidgetLowered(WID_ROT_REMOVE); _one_way_button_clicked = this->IsWidgetLowered(WID_ROT_ONE_WAY); + _catenary_button_clicked = this->IsWidgetLowered(WID_ROT_CATENARY); switch (this->last_started_action) { case WID_ROT_ROAD_X: _place_road_flag = RF_DIR_X; @@ -549,9 +569,11 @@ struct BuildRoadToolbarWindow : Window { this->SetWidgetsDisabledState(true, WID_ROT_REMOVE, WID_ROT_ONE_WAY, + WID_ROT_CATENARY, WIDGET_LIST_END); this->SetWidgetDirty(WID_ROT_REMOVE); this->SetWidgetDirty(WID_ROT_ONE_WAY); + this->SetWidgetDirty(WID_ROT_CATENARY); DeleteWindowById(WC_BUS_STATION, TRANSPORT_ROAD); DeleteWindowById(WC_TRUCK_STATION, TRANSPORT_ROAD); @@ -626,7 +648,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) | (_catenary_button_clicked << 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); @@ -738,6 +760,8 @@ static const NWidgetPart _nested_build_road_widgets[] = { NWidget(WWT_PANEL, COLOUR_DARK_GREEN, -1), SetMinimalSize(0, 22), SetFill(1, 1), EndContainer(), NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ONE_WAY), SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_ONE_WAY, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD), + NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_CATENARY), + SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_ONE_WAY, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD), NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_BRIDGE), SetFill(0, 1), SetMinimalSize(43, 22), SetDataTip(SPR_IMG_BRIDGE, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_BRIDGE), NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_TUNNEL), @@ -778,6 +802,8 @@ static const NWidgetPart _nested_build_tramway_widgets[] = { SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_TRUCK_BAY, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_CARGO_TRAM_STATION), NWidget(WWT_PANEL, COLOUR_DARK_GREEN, -1), SetMinimalSize(0, 22), SetFill(1, 1), EndContainer(), NWidget(WWT_EMPTY, COLOUR_DARK_GREEN, WID_ROT_ONE_WAY), SetMinimalSize(0, 0), + NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_CATENARY), + SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_ONE_WAY, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_ONE_WAY_ROAD), NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_BRIDGE), SetFill(0, 1), SetMinimalSize(43, 22), SetDataTip(SPR_IMG_BRIDGE, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_BRIDGE), NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_TUNNEL), diff --git a/src/road_map.h b/src/road_map.h index 6937302..6baa446 100644 --- a/src/road_map.h +++ b/src/road_map.h @@ -250,7 +250,10 @@ static inline bool HasTownOwnedRoad(TileIndex t) { return HasTileRoadType(t, ROADTYPE_ROAD) && IsRoadOwner(t, ROADTYPE_ROAD, OWNER_TOWN); } - +static inline bool HasCatenary(TileIndex t) +{ + return GB(_m[t].m1, 7, 1); +} /** Which directions are disallowed ? */ enum DisallowedRoadDirections { DRD_NONE, ///< None of the directions are disallowed @@ -286,6 +289,12 @@ static inline void SetDisallowedRoadDirections(TileIndex t, DisallowedRoadDirect SB(_m[t].m5, 4, 2, drd); } +static inline void SetCatenary(TileIndex t, bool b) +{ + assert(IsNormalRoad(t)); + SB(_m[t].m1, 7, 1, b ? 1 : 0); +} + /** * Get the road axis of a level crossing. * @param t The tile to query. diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index eb90c29..102fc15 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -2902,7 +2902,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 (HasCatenary(ti->tile)) DrawTramCatenary(ti, axis == AXIS_X ? ROAD_X : ROAD_Y); } if (IsRailWaypoint(ti->tile)) { diff --git a/src/widgets/road_widget.h b/src/widgets/road_widget.h index f022489..09fc0ed 100644 --- a/src/widgets/road_widget.h +++ b/src/widgets/road_widget.h @@ -23,6 +23,7 @@ enum RoadToolbarWidgets { WID_ROT_BUS_STATION, ///< Build bus station. WID_ROT_TRUCK_STATION, ///< Build truck station. WID_ROT_ONE_WAY, ///< Build one-way road. + WID_ROT_CATENARY, ///< Build catenary. WID_ROT_BUILD_BRIDGE, ///< Build bridge. WID_ROT_BUILD_TUNNEL, ///< Build tunnel. WID_ROT_REMOVE, ///< Remove road.