diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index aa445eb..819bc1d 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_flag = HasBit(p1, 8); Slope tileh = GetTileSlope(tile); @@ -759,6 +761,8 @@ do_clear:; SetRoadTypes(tile, GetRoadTypes(tile) | RoadTypeToRoadTypes(rt)); SetRoadOwner(other_end, rt, company); SetRoadOwner(tile, rt, company); + SetCatenary(other_end, _catenary_flag); + SetCatenary(tile, _catenary_flag); /* Mark tiles dirty that have been repaved */ if (IsBridge(tile)) { @@ -794,7 +798,7 @@ do_clear:; SetDisallowedRoadDirections(tile, IsStraightRoad(existing) ? GetDisallowedRoadDirections(tile) ^ toggle_drd : DRD_NONE); } - + SetCatenary(tile, _catenary_flag); MarkTileDirtyByTile(tile); } return cost; @@ -827,6 +831,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 +891,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 +1303,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 +1393,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..982e85c 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; +bool _catenary_flag; static DiagDirection _road_depot_orientation; static DiagDirection _road_station_picker_orientation; @@ -626,7 +627,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_flag << 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); @@ -802,10 +803,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, bool catenary_flag) { if (!Company::IsValidID(_local_company)) return NULL; _cur_roadtype = roadtype; + _catenary_flag = catenary_flag; DeleteWindowByClass(WC_BUILD_TOOLBAR); return AllocateWindowDescFront(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..dd61ce9 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, bool catenary_flag = false); struct Window *ShowBuildRoadScenToolbar(); void ConnectRoadToStructure(TileIndex tile, DiagDirection direction); 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/toolbar_gui.cpp b/src/toolbar_gui.cpp index 45d751d..0f28fbd 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, false); + *list->Append() = new DropDownListStringItem(STR_ROAD_MENU_ROAD_CONSTRUCTION, 1, false); /* Tram is only visible when there will be a tram, and available when that has been introduced. */ Engine *e; @@ -899,7 +900,8 @@ 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, 2, !HasBit(c->avail_roadtypes, ROADTYPE_TRAM)); + *list->Append() = new DropDownListStringItem(STR_ROAD_MENU_TRAM_CONSTRUCTION, 3, !HasBit(c->avail_roadtypes, ROADTYPE_TRAM)); break; } ShowDropDownList(w, list, _last_built_roadtype, WID_TN_ROADS, 140, true, true); @@ -915,8 +917,19 @@ static CallBackFunction ToolbarBuildRoadClick(Window *w) */ static CallBackFunction MenuClickBuildRoad(int index) { - _last_built_roadtype = (RoadType)index; - ShowBuildRoadToolbar(_last_built_roadtype); + bool _catenary_flag = false; + if (index == 0) { + _last_built_roadtype = (RoadType)ROADTYPE_ROAD; + } else if (index == 1) { + _last_built_roadtype = (RoadType)ROADTYPE_ROAD; + _catenary_flag = true; + } else if (index == 2) { + _last_built_roadtype = (RoadType)ROADTYPE_TRAM; + } else if (index == 3) { + _last_built_roadtype = (RoadType)ROADTYPE_TRAM; + _catenary_flag = true; + } + ShowBuildRoadToolbar(_last_built_roadtype, _catenary_flag); return CBF_NONE; } diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 5f2534b..cdd576b 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -1087,7 +1087,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 +1107,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 +1118,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 +1193,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 (HasCatenary(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 +1303,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, HasCatenary(ti->tile)); } EndSpriteCombine(); } else if (transport_type == TRANSPORT_RAIL) { @@ -1466,7 +1466,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, HasCatenary(ti->tile)); } else { EndSpriteCombine(); StartSpriteCombine();