From 9a8216dc0c0aeafcb0fee8249e2bbe94f0f99099 Mon Sep 17 00:00:00 2001 From: dP Date: Thu, 25 Mar 2021 01:40:30 +0300 Subject: [PATCH] Add building preview for road depot --- src/citymania/cm_highlight.cpp | 127 ++++++++++++++++++++++++---- src/citymania/cm_highlight_type.hpp | 14 ++- src/citymania/cm_station_gui.hpp | 1 + src/rail_gui.cpp | 2 +- src/road_gui.cpp | 8 +- 5 files changed, 129 insertions(+), 23 deletions(-) diff --git a/src/citymania/cm_highlight.cpp b/src/citymania/cm_highlight.cpp index c20d8e918f..9e74faf89f 100644 --- a/src/citymania/cm_highlight.cpp +++ b/src/citymania/cm_highlight.cpp @@ -47,6 +47,7 @@ extern int _selected_airport_index; extern byte _selected_airport_layout; extern DiagDirection _build_depot_direction; ///< Currently selected depot direction extern DiagDirection _road_station_picker_orientation; +extern DiagDirection _road_depot_orientation; extern uint32 _realtime_tick; extern void GetStationLayout(byte *layout, int numtracks, int plat_len, const StationSpec *statspec); @@ -141,6 +142,13 @@ ObjectTileHighlight ObjectTileHighlight::make_road_stop(SpriteID palette, RoadTy return oh; } +ObjectTileHighlight ObjectTileHighlight::make_road_depot(SpriteID palette, RoadType roadtype, DiagDirection ddir) { + auto oh = ObjectTileHighlight(Type::ROAD_DEPOT, palette); + oh.u.road.depot.roadtype = roadtype; + oh.u.road.depot.ddir = ddir; + return oh; +} + ObjectTileHighlight ObjectTileHighlight::make_airport_tile(SpriteID palette, StationGfx gfx) { auto oh = ObjectTileHighlight(Type::AIRPORT_TILE, palette); oh.u.airport_tile.gfx = gfx; @@ -196,6 +204,14 @@ ObjectHighlight ObjectHighlight::make_road_stop(TileIndex start_tile, TileIndex return oh; } +ObjectHighlight ObjectHighlight::make_road_depot(TileIndex tile, RoadType roadtype, DiagDirection orientation) { + auto oh = ObjectHighlight{ObjectHighlight::Type::ROAD_DEPOT}; + oh.tile = tile; + oh.ddir = orientation; + oh.roadtype = roadtype; + return oh; +} + ObjectHighlight ObjectHighlight::make_airport(TileIndex start_tile, int airport_type, byte airport_layout) { auto oh = ObjectHighlight{ObjectHighlight::Type::AIRPORT}; oh.tile = start_tile; @@ -329,6 +345,17 @@ void ObjectHighlight::UpdateTiles() { break; } + case Type::ROAD_DEPOT: { + auto palette = (CanBuild( + this->tile, + this->roadtype << 2 | this->ddir, + 0, + CMD_BUILD_ROAD_DEPOT + ) ? PALETTE_TINT_WHITE : PALETTE_TINT_RED_DEEP); + this->tiles.insert(std::make_pair(this->tile, ObjectTileHighlight::make_road_depot(palette, this->roadtype, this->ddir))); + break; + } + case Type::AIRPORT: { auto palette = (CanBuild( this->tile, @@ -514,6 +541,73 @@ void DrawRoadStop(SpriteID palette, const TileInfo *ti, RoadType roadtype, DiagD // DrawRoadCatenary(ti); } + +struct DrawRoadTileStruct { + uint16 image; + byte subcoord_x; + byte subcoord_y; +}; + +#include "../table/road_land.h" + +// copied from road_gui.cpp +static uint GetRoadSpriteOffset(Slope slope, RoadBits bits) +{ + if (slope != SLOPE_FLAT) { + switch (slope) { + case SLOPE_NE: return 11; + case SLOPE_SE: return 12; + case SLOPE_SW: return 13; + case SLOPE_NW: return 14; + default: NOT_REACHED(); + } + } else { + static const uint offsets[] = { + 0, 18, 17, 7, + 16, 0, 10, 5, + 15, 8, 1, 4, + 9, 3, 6, 2 + }; + return offsets[bits]; + } +} + + +void DrawRoadDepot(SpriteID palette, const TileInfo *ti, RoadType roadtype, DiagDirection orientation) { + const RoadTypeInfo* rti = GetRoadTypeInfo(roadtype); + int relocation = GetCustomRoadSprite(rti, INVALID_TILE, ROTSG_DEPOT); + bool default_gfx = relocation == 0; + if (default_gfx) { + if (HasBit(rti->flags, ROTF_CATENARY)) { + if (_loaded_newgrf_features.tram == TRAMWAY_REPLACE_DEPOT_WITH_TRACK && RoadTypeIsTram(roadtype) && !rti->UsesOverlay()) { + /* Sprites with track only work for default tram */ + relocation = SPR_TRAMWAY_DEPOT_WITH_TRACK - SPR_ROAD_DEPOT; + default_gfx = false; + } else { + /* Sprites without track are always better, if provided */ + relocation = SPR_TRAMWAY_DEPOT_NO_TRACK - SPR_ROAD_DEPOT; + } + } + } else { + relocation -= SPR_ROAD_DEPOT; + } + + const DrawTileSprites *dts = &_road_depot[orientation]; + AddSortableSpriteToDraw(dts->ground.sprite, palette, ti->x, ti->y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, ti->z); + + if (default_gfx) { + uint offset = GetRoadSpriteOffset(SLOPE_FLAT, DiagDirToRoadBits(orientation)); + if (rti->UsesOverlay()) { + SpriteID ground = GetCustomRoadSprite(rti, INVALID_TILE, ROTSG_OVERLAY); + if (ground != 0) AddSortableSpriteToDraw(ground + offset, palette, ti->x, ti->y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, ti->z); + } else if (RoadTypeIsTram(roadtype)) { + AddSortableSpriteToDraw(SPR_TRAMWAY_OVERLAY + offset, palette, ti->x, ti->y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, ti->z); + } + } + + DrawRailTileSeq(ti, dts, TO_INVALID, relocation, 0, palette); +} + #include "../table/station_land.h" void DrawAirportTile(SpriteID palette, const TileInfo *ti, StationGfx gfx) { @@ -708,6 +802,9 @@ void ObjectHighlight::Draw(const TileInfo *ti) { case ObjectTileHighlight::Type::ROAD_STOP: DrawRoadStop(oth.palette, ti, oth.u.road.stop.roadtype, oth.u.road.stop.ddir, oth.u.road.stop.is_truck); break; + case ObjectTileHighlight::Type::ROAD_DEPOT: + DrawRoadDepot(oth.palette, ti, oth.u.road.depot.roadtype, oth.u.road.depot.ddir); + break; case ObjectTileHighlight::Type::AIRPORT_TILE: DrawAirportTile(oth.palette, ti, oth.u.airport_tile.gfx); break; @@ -1042,25 +1139,10 @@ bool DrawTileSelection(const TileInfo *ti, const TileHighlightType &tht) { // if (_thd.drawstyle == CM_HT_BLUEPRINT_PLACE) return true; - // if ((_thd.drawstyle & HT_DRAG_MASK) == HT_RECT && _thd.outersize.x > 0) { if (_thd.select_proc == DDSP_BUILD_STATION || _thd.select_proc == DDSP_BUILD_BUSSTOP - || _thd.select_proc == DDSP_BUILD_TRUCKSTOP || _thd.select_proc == CM_DDSP_BUILD_AIRPORT) { - // station selector, handled by DrawTileZoning - return true; - } - - if (_thd.select_proc == CM_DDSP_BUILD_RAIL_DEPOT) { - // if ((_thd.drawstyle & HT_DRAG_MASK) == HT_RECT && IsInsideSelectedRectangle(ti->x, ti->y) - // && _cursor.sprite_seq[0].sprite == GetRailTypeInfo(_cur_railtype)->cursor.depot) { - // DrawTileSelectionRect(ti, _thd.make_square_red ? PALETTE_SEL_TILE_RED : PAL_NONE); - - // auto rti = GetRailTypeInfo(_cur_railtype); - // int depot_sprite = GetCustomRailSprite(rti, ti->tile, RTSG_DEPOT); - // auto relocation = depot_sprite != 0 ? depot_sprite - SPR_RAIL_DEPOT_SE_1 : rti->GetRailtypeSpriteOffset(); - // AddSortableSpriteToDraw(relocation, PALETTE_TINT_WHITE, ti->x, ti->y, 0x10, 0x10, 1, ti->z); - // AddSortableSpriteToDraw(SPR_RAIL_DEPOT_SE_1, PALETTE_TINT_WHITE, ti->x, ti->y, 0x10, 0x10, 1, ti->z); - // DrawTrainDepotSprite(r.left + 1 + ScaleGUITrad(31), r.bottom - ScaleGUITrad(31), widget - WID_BRAD_DEPOT_NE + DIAGDIR_NE, _cur_railtype); - // DrawTrainDepotSprite(ti, _cur_railtype, (DiagDirection)(_thd.drawstyle & HT_DIR_MASK)); + || _thd.select_proc == DDSP_BUILD_TRUCKSTOP || _thd.select_proc == CM_DDSP_BUILD_AIRPORT + || _thd.select_proc == CM_DDSP_BUILD_ROAD_DEPOT || _thd.select_proc == CM_DDSP_BUILD_RAIL_DEPOT) { + // handled by DrawTileZoning return true; } @@ -1110,6 +1192,15 @@ HighLightStyle UpdateTileSelection(HighLightStyle new_drawstyle) { // new_drawstyle = CM_HT_BLUEPRINT_PLACE; // } else if (_thd.make_square_red) { + } else if (_thd.select_proc == CM_DDSP_BUILD_ROAD_DEPOT) { + auto dir = _road_depot_orientation; + if (pt.x != -1) { + if (dir == DEPOTDIR_AUTO) { + dir = AddAutodetectionRotation(AutodetectRoadObjectDirection(tile, pt, _cur_roadtype)); + } + _thd.cm_new = ObjectHighlight::make_road_depot(tile, _cur_roadtype, dir); + } + new_drawstyle = HT_RECT; } else if (_thd.select_proc == CM_DDSP_BUILD_RAIL_DEPOT) { auto dir = _build_depot_direction; if (pt.x != -1) { diff --git a/src/citymania/cm_highlight_type.hpp b/src/citymania/cm_highlight_type.hpp index 9a86e2e247..79ca931c53 100644 --- a/src/citymania/cm_highlight_type.hpp +++ b/src/citymania/cm_highlight_type.hpp @@ -30,6 +30,7 @@ public: RAIL_BRIDGE_HEAD, RAIL_TUNNEL_HEAD, ROAD_STOP, + ROAD_DEPOT, AIRPORT_TILE, END, }; @@ -67,6 +68,10 @@ public: DiagDirection ddir; bool is_truck; } stop; + struct { + RoadType roadtype; + DiagDirection ddir; + } depot; } road; struct { StationGfx gfx; @@ -83,6 +88,7 @@ public: static ObjectTileHighlight make_rail_tunnel_head(SpriteID palette, DiagDirection ddir); static ObjectTileHighlight make_road_stop(SpriteID palette, RoadType roadtype, DiagDirection ddir, bool is_truck); + static ObjectTileHighlight make_road_depot(SpriteID palette, RoadType roadtype, DiagDirection ddir); static ObjectTileHighlight make_airport_tile(SpriteID palette, StationGfx gfx); }; @@ -109,6 +115,7 @@ public: RAIL_BRIDGE, RAIL_TUNNEL, ROAD_STOP, + ROAD_DEPOT, END, }; Type type; @@ -150,6 +157,9 @@ public: DiagDirection ddir; TileIndexDiffC other_end; } stop; + struct { + DiagDirection ddir; + } depot; } road; } u; Item(Type type, TileIndexDiffC tdiff) @@ -184,7 +194,8 @@ public: RAIL_DEPOT = 1, RAIL_STATION = 2, ROAD_STOP = 3, - AIRPORT = 4, + ROAD_DEPOT = 4, + AIRPORT = 5, // BLUEPRINT = 2, }; @@ -214,6 +225,7 @@ public: static ObjectHighlight make_rail_station(TileIndex start_tile, TileIndex end_tile, Axis axis); // static ObjectHighlight make_blueprint(TileIndex tile, sp blueprint); static ObjectHighlight make_road_stop(TileIndex start_tile, TileIndex end_tile, RoadType roadtype, DiagDirection orientation, bool is_truck); + static ObjectHighlight make_road_depot(TileIndex tile, RoadType roadtype, DiagDirection orientation); static ObjectHighlight make_airport(TileIndex start_tile, int airport_type, byte airport_layout); void Draw(const TileInfo *ti); diff --git a/src/citymania/cm_station_gui.hpp b/src/citymania/cm_station_gui.hpp index b199a42085..2befe59735 100644 --- a/src/citymania/cm_station_gui.hpp +++ b/src/citymania/cm_station_gui.hpp @@ -9,6 +9,7 @@ namespace citymania { +const DiagDirection DEPOTDIR_AUTO = DIAGDIR_END; const DiagDirection STATIONDIR_X = DIAGDIR_END; const DiagDirection STATIONDIR_Y = (DiagDirection)((uint)DIAGDIR_END + 1); const DiagDirection STATIONDIR_AUTO = (DiagDirection)((uint)DIAGDIR_END + 2); diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 2b81497e76..7e786b7e66 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -805,7 +805,7 @@ struct BuildRailToolbarWindow : Window { case WID_RAT_BUILD_DEPOT: ddir = _build_depot_direction; - if (ddir == DIAGDIR_NW + 1) { + if (ddir == citymania::DEPOTDIR_AUTO) { assert(_thd.cm.type == citymania::ObjectHighlight::Type::RAIL_DEPOT); ddir = _thd.cm.ddir; } diff --git a/src/road_gui.cpp b/src/road_gui.cpp index e399cf0304..3fe9de72cd 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -70,7 +70,7 @@ static RoadFlags _place_road_flag; /* CM static */ RoadType _cur_roadtype; -static DiagDirection _road_depot_orientation; +/* CM static */ DiagDirection _road_depot_orientation; DiagDirection _road_station_picker_orientation; void CcPlaySound_SPLAT_OTHER(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) @@ -449,6 +449,7 @@ struct BuildRoadToolbarWindow : Window { case WID_ROT_DEPOT: if (_game_mode == GM_EDITOR || !CanBuildVehicleInfrastructure(VEH_ROAD, GetRoadTramType(this->roadtype))) return; if (HandlePlacePushButton(this, WID_ROT_DEPOT, this->rti->cursor.depot, HT_RECT, CM_DDSP_BUILD_ROAD_DEPOT)) { + citymania::ResetRotateAutodetection(); ShowRoadDepotPicker(this); this->last_started_action = widget; } @@ -545,8 +546,9 @@ struct BuildRoadToolbarWindow : Window { case WID_ROT_DEPOT: ddir = _road_depot_orientation; - if (ddir == DIAGDIR_NW + 1) { - ddir = citymania::AutodetectRoadObjectDirection(tile, GetTileBelowCursor(), _cur_roadtype); + if (ddir == citymania::DEPOTDIR_AUTO) { + assert(_thd.cm.type == citymania::ObjectHighlight::Type::ROAD_DEPOT); + ddir = _thd.cm.ddir; } DoCommandP(tile, _cur_roadtype << 2 | ddir, 0, CMD_BUILD_ROAD_DEPOT | CMD_MSG(this->rti->strings.err_depot), CcRoadDepot);