From c9819f8957ee6dcdce10526ef340263f4bd1a2e4 Mon Sep 17 00:00:00 2001 From: Rubidium Date: Tue, 22 Oct 2024 23:25:07 +0200 Subject: [PATCH] Codechange: split GetRoadDir as bays have DiagDir and drive throughs have Axis --- src/autoslope.h | 23 +++++++++++++++++++- src/pathfinder/follow_track.hpp | 6 +++--- src/road_cmd.cpp | 6 +++--- src/road_map.cpp | 4 ++-- src/roadstop.cpp | 38 ++++++++++++++++++++++----------- src/roadveh_cmd.cpp | 4 ++-- src/script/api/script_road.cpp | 8 ++++--- src/station_cmd.cpp | 34 ++++++++++++++--------------- src/station_map.h | 27 ++++++++++++++--------- src/town_cmd.cpp | 4 +++- src/waypoint_cmd.cpp | 2 +- 11 files changed, 100 insertions(+), 56 deletions(-) diff --git a/src/autoslope.h b/src/autoslope.h index 4e054d85c4..1c66604425 100644 --- a/src/autoslope.h +++ b/src/autoslope.h @@ -16,7 +16,7 @@ /** * Autoslope check for tiles with an entrance on an edge. - * E.g. depots and non-drive-through-road-stops. + * E.g. depots and bay road-stops. * * The test succeeds if the slope is not steep and at least one corner of the entrance edge is on the TileMaxZ() level. * @@ -34,6 +34,27 @@ inline bool AutoslopeCheckForEntranceEdge(TileIndex tile, int z_new, Slope tileh return ((tileh_new == SLOPE_FLAT) || CanBuildDepotByTileh(entrance, tileh_new)); } +/** + * Autoslope check for tiles with something built along an axis. + * E.g. railway stations and drive through road stops. + * + * The test succeeds if the slope is not steep and at least one corner at either of the entrance edges is on the TileMaxZ() level. + * + * @note The test does not check if autoslope is enabled at all. + * + * @param tile The tile. + * @param z_new New TileZ. + * @param tileh_new New TileSlope. + * @param axis The axis. + * @return true iff terraforming is allowed. + */ +inline bool AutoslopeCheckForAxis(TileIndex tile, int z_new, Slope tileh_new, Axis axis) +{ + DiagDirection direction = AxisToDiagDir(axis); + return AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, direction) && + AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, ReverseDiagDir(direction)); +} + /** * Tests if autoslope is enabled for _current_company. * diff --git a/src/pathfinder/follow_track.hpp b/src/pathfinder/follow_track.hpp index d384568b62..5948bd4546 100644 --- a/src/pathfinder/follow_track.hpp +++ b/src/pathfinder/follow_track.hpp @@ -250,7 +250,7 @@ protected: { /* road stop can be left at one direction only unless it's a drive-through stop */ if (IsRoadTT() && IsBayRoadStopTile(m_old_tile)) { - DiagDirection exitdir = GetRoadStopDir(m_old_tile); + DiagDirection exitdir = GetBayRoadStopDir(m_old_tile); if (exitdir != m_exitdir) { m_err = EC_NO_WAY; return false; @@ -282,7 +282,7 @@ protected: { if (IsRoadTT() && IsBayRoadStopTile(m_new_tile)) { /* road stop can be entered from one direction only unless it's a drive-through stop */ - DiagDirection exitdir = GetRoadStopDir(m_new_tile); + DiagDirection exitdir = GetBayRoadStopDir(m_new_tile); if (ReverseDiagDir(exitdir) != m_exitdir) { m_err = EC_NO_WAY; return false; @@ -404,7 +404,7 @@ protected: /* Single tram bits and standard road stops cause reversing. */ if (IsRoadTT() && ((IsTram() && GetSingleTramBit(m_old_tile) == ReverseDiagDir(m_exitdir)) || - (IsBayRoadStopTile(m_old_tile) && GetRoadStopDir(m_old_tile) == ReverseDiagDir(m_exitdir)))) { + (IsBayRoadStopTile(m_old_tile) && GetBayRoadStopDir(m_old_tile) == ReverseDiagDir(m_exitdir)))) { /* reverse */ m_new_tile = m_old_tile; m_new_td_bits = TrackdirToTrackdirBits(ReverseTrackdir(m_old_td)); diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index e4489c8621..486b6ef3c2 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -791,7 +791,7 @@ CommandCost CmdBuildRoad(DoCommandFlag flags, TileIndex tile, RoadBits pieces, R if ((GetAnyRoadBits(tile, rtt) & pieces) == pieces) return_cmd_error(STR_ERROR_ALREADY_BUILT); if (!IsDriveThroughStopTile(tile)) goto do_clear; - RoadBits curbits = AxisToRoadBits(DiagDirToAxis(GetRoadStopDir(tile))); + RoadBits curbits = AxisToRoadBits(GetDriveThroughStopAxis(tile)); if (pieces & ~curbits) goto do_clear; pieces = curbits; // we need to pay for both roadbits @@ -1463,10 +1463,10 @@ void DrawRoadCatenary(const TileInfo *ti) } else if (IsTileType(ti->tile, MP_STATION)) { if (IsAnyRoadStop(ti->tile)) { if (IsDriveThroughStopTile(ti->tile)) { - Axis axis = GetRoadStopDir(ti->tile) == DIAGDIR_NE ? AXIS_X : AXIS_Y; + Axis axis = GetDriveThroughStopAxis(ti->tile); tram = road = (axis == AXIS_X ? ROAD_X : ROAD_Y); } else { - tram = road = DiagDirToRoadBits(GetRoadStopDir(ti->tile)); + tram = road = DiagDirToRoadBits(GetBayRoadStopDir(ti->tile)); } } } else { diff --git a/src/road_map.cpp b/src/road_map.cpp index 66fe49010f..cc822a2c5f 100644 --- a/src/road_map.cpp +++ b/src/road_map.cpp @@ -45,8 +45,8 @@ RoadBits GetAnyRoadBits(Tile tile, RoadTramType rtt, bool straight_tunnel_bridge case MP_STATION: if (!IsAnyRoadStopTile(tile)) return ROAD_NONE; - if (IsDriveThroughStopTile(tile)) return (GetRoadStopDir(tile) == DIAGDIR_NE) ? ROAD_X : ROAD_Y; - return DiagDirToRoadBits(GetRoadStopDir(tile)); + if (IsDriveThroughStopTile(tile)) return AxisToRoadBits(GetDriveThroughStopAxis(tile)); + return DiagDirToRoadBits(GetBayRoadStopDir(tile)); case MP_TUNNELBRIDGE: if (GetTunnelBridgeTransportType(tile) != TRANSPORT_ROAD) return ROAD_NONE; diff --git a/src/roadstop.cpp b/src/roadstop.cpp index 2e4f441973..7fa254ccfa 100644 --- a/src/roadstop.cpp +++ b/src/roadstop.cpp @@ -64,9 +64,8 @@ void RoadStop::MakeDriveThrough() assert(this->east == nullptr && this->west == nullptr); RoadStopType rst = GetRoadStopType(this->xy); - DiagDirection dir = GetRoadStopDir(this->xy); - /* Use absolute so we always go towards the northern tile */ - TileIndexDiff offset = abs(TileOffsByDiagDir(dir)); + Axis axis = GetDriveThroughStopAxis(this->xy); + TileIndexDiff offset = TileOffsByAxis(axis); /* Information about the tile north of us */ TileIndex north_tile = this->xy - offset; @@ -132,9 +131,8 @@ void RoadStop::ClearDriveThrough() assert(this->east != nullptr && this->west != nullptr); RoadStopType rst = GetRoadStopType(this->xy); - DiagDirection dir = GetRoadStopDir(this->xy); - /* Use absolute so we always go towards the northern tile */ - TileIndexDiff offset = abs(TileOffsByDiagDir(dir)); + Axis axis = GetDriveThroughStopAxis(this->xy); + TileIndexDiff offset = TileOffsByAxis(axis); /* Information about the tile north of us */ TileIndex north_tile = this->xy - offset; @@ -307,8 +305,8 @@ void RoadStop::Entry::Enter(const RoadVehicle *rv) return IsTileType(next, MP_STATION) && GetStationIndex(next) == GetStationIndex(rs) && GetStationType(next) == GetStationType(rs) && - GetRoadStopDir(next) == GetRoadStopDir(rs) && - IsDriveThroughStopTile(next); + IsDriveThroughStopTile(next) && + GetDriveThroughStopAxis(next) == GetDriveThroughStopAxis(rs); } typedef std::list RVList; ///< A list of road vehicles @@ -344,6 +342,21 @@ Vehicle *FindVehiclesInRoadStop(Vehicle *v, void *data) return nullptr; } +/** + * Get the DiagDirection for entering the drive through stop from the given 'side' (east or west) on the given axis. + * @param east Enter from the east when true or from the west when false. + * @param axis The axis of the drive through stop. + * @return The DiagDirection the vehicles far when entering 'our' side of the drive through stop. + */ +static DiagDirection GetEntryDirection(bool east, Axis axis) +{ + switch (axis) { + case AXIS_X: return east ? DIAGDIR_NE : DIAGDIR_SW; + case AXIS_Y: return east ? DIAGDIR_SE : DIAGDIR_NW; + default: NOT_REACHED(); + } +} + /** * Rebuild, from scratch, the vehicles and other metadata on this stop. * @param rs the roadstop this entry is part of @@ -353,14 +366,14 @@ void RoadStop::Entry::Rebuild(const RoadStop *rs, int side) { assert(HasBit(rs->status, RSSFB_BASE_ENTRY)); - DiagDirection dir = GetRoadStopDir(rs->xy); + Axis axis = GetDriveThroughStopAxis(rs->xy); if (side == -1) side = (rs->east == this); RoadStopEntryRebuilderHelper rserh; - rserh.dir = side ? dir : ReverseDiagDir(dir); + rserh.dir = GetEntryDirection(side, axis); this->length = 0; - TileIndexDiff offset = abs(TileOffsByDiagDir(dir)); + TileIndexDiff offset = TileOffsByAxis(axis); for (TileIndex tile = rs->xy; IsDriveThroughRoadStopContinuation(rs->xy, tile); tile += offset) { this->length += TILE_SIZE; FindVehicleOnPos(tile, &rserh, FindVehiclesInRoadStop); @@ -382,7 +395,8 @@ void RoadStop::Entry::CheckIntegrity(const RoadStop *rs) const if (!HasBit(rs->status, RSSFB_BASE_ENTRY)) return; /* The tile 'before' the road stop must not be part of this 'line' */ - assert(!IsDriveThroughRoadStopContinuation(rs->xy, rs->xy - abs(TileOffsByDiagDir(GetRoadStopDir(rs->xy))))); + assert(IsDriveThroughStopTile(rs->xy)); + assert(!IsDriveThroughRoadStopContinuation(rs->xy, rs->xy - TileOffsByAxis(GetDriveThroughStopAxis(rs->xy)))); Entry temp; temp.Rebuild(rs, rs->east == this); diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 957dda01ca..c3b977b32a 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -897,7 +897,7 @@ static Trackdir RoadFindPathToDest(RoadVehicle *v, TileIndex tile, DiagDirection } else if (IsTileType(tile, MP_STATION) && IsBayRoadStopTile(tile)) { /* Standard road stop (drive-through stops are treated as normal road) */ - if (!IsTileOwner(tile, v->owner) || GetRoadStopDir(tile) == enterdir || v->HasArticulatedPart()) { + if (!IsTileOwner(tile, v->owner) || GetBayRoadStopDir(tile) == enterdir || v->HasArticulatedPart()) { /* different station owner or wrong orientation or the vehicle has articulated parts */ trackdirs = TRACKDIR_BIT_NONE; } else { @@ -1746,7 +1746,7 @@ Trackdir RoadVehicle::GetVehicleTrackdir() const if (IsBayRoadStopTile(this->tile)) { /* We'll assume the road vehicle is facing outwards */ - return DiagDirToDiagTrackdir(GetRoadStopDir(this->tile)); // Road vehicle in a station + return DiagDirToDiagTrackdir(GetBayRoadStopDir(this->tile)); // Road vehicle in a station } /* Drive through road stops / wormholes (tunnels) */ diff --git a/src/script/api/script_road.cpp b/src/script/api/script_road.cpp index 25b7fc2631..a53d6ba31d 100644 --- a/src/script/api/script_road.cpp +++ b/src/script/api/script_road.cpp @@ -442,7 +442,7 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD case MP_STATION: if (::IsDriveThroughStopTile(neighbour_tile)) { - return (::DiagDirToAxis(neighbour) == ::DiagDirToAxis(::GetRoadStopDir(neighbour_tile))); + return ::DiagDirToAxis(neighbour) == ::GetDriveThroughStopAxis(neighbour_tile); } return false; @@ -478,14 +478,16 @@ static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagD { if (!IsRoadStationTile(station)) return INVALID_TILE; - return station + ::TileOffsByDiagDir(::GetRoadStopDir(station)); + if (::IsBayRoadStopTile(station)) return station + ::TileOffsByDiagDir(::GetBayRoadStopDir(station)); + + return station - ::TileOffsByAxis(::GetDriveThroughStopAxis(station)); } /* static */ TileIndex ScriptRoad::GetDriveThroughBackTile(TileIndex station) { if (!IsDriveThroughRoadStationTile(station)) return INVALID_TILE; - return station + ::TileOffsByDiagDir(::ReverseDiagDir(::GetRoadStopDir(station))); + return station + ::TileOffsByAxis(::GetDriveThroughStopAxis(station)); } /* static */ bool ScriptRoad::_BuildRoadInternal(TileIndex start, TileIndex end, bool one_way, bool full) diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 832f75eade..28e3e7c9d8 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -987,7 +987,7 @@ CommandCost CheckFlatLandRoadStop(TileIndex cur_tile, int &allowed_z, DoCommandF return ClearTile_Station(cur_tile, DC_AUTO); // Get error message. } /* Drive-through station in the wrong direction. */ - if (is_drive_through && IsDriveThroughStopTile(cur_tile) && DiagDirToAxis(GetRoadStopDir(cur_tile)) != axis) { + if (is_drive_through && IsDriveThroughStopTile(cur_tile) && GetDriveThroughStopAxis(cur_tile) != axis) { return_cmd_error(STR_ERROR_DRIVE_THROUGH_DIRECTION); } StationID st = GetStationIndex(cur_tile); @@ -2344,7 +2344,7 @@ static CommandCost RemoveGenericRoadStop(DoCommandFlag flags, const TileArea &ro /* If we don't want to preserve our roads then restore only roads of others. */ if (remove_road && road_owner[rtt] == _current_company) road_type[rtt] = INVALID_ROADTYPE; } - road_bits = AxisToRoadBits(DiagDirToAxis(GetRoadStopDir(cur_tile))); + road_bits = AxisToRoadBits(GetDriveThroughStopAxis(cur_tile)); } CommandCost ret; @@ -3269,7 +3269,7 @@ draw_default_foundation: } } } else if (IsRoadWaypointTile(ti->tile)) { - RoadBits bits = GetRoadStopDir(ti->tile) == DIAGDIR_NE ? ROAD_X : ROAD_Y; + RoadBits bits = AxisToRoadBits(GetDriveThroughStopAxis(ti->tile)); RoadType road_rt = GetRoadTypeRoad(ti->tile); RoadType tram_rt = GetRoadTypeTram(ti->tile); RoadBits road = (road_rt != INVALID_ROADTYPE) ? bits : ROAD_NONE; @@ -3339,7 +3339,6 @@ draw_default_foundation: const RoadTypeInfo *road_rti = road_rt == INVALID_ROADTYPE ? nullptr : GetRoadTypeInfo(road_rt); const RoadTypeInfo *tram_rti = tram_rt == INVALID_ROADTYPE ? nullptr : GetRoadTypeInfo(tram_rt); - Axis axis = GetRoadStopDir(ti->tile) == DIAGDIR_NE ? AXIS_X : AXIS_Y; StationGfx view = GetStationGfx(ti->tile); StationType type = GetStationType(ti->tile); @@ -3374,7 +3373,7 @@ draw_default_foundation: if (IsDriveThroughStopTile(ti->tile)) { if (type != STATION_ROADWAYPOINT && (stopspec == nullptr || (stop_draw_mode & ROADSTOP_DRAW_MODE_OVERLAY) != 0)) { - uint sprite_offset = axis == AXIS_X ? 1 : 0; + uint sprite_offset = GetDriveThroughStopAxis(ti->tile) == AXIS_X ? 1 : 0; DrawRoadOverlays(ti, PAL_NONE, road_rti, tram_rti, sprite_offset, sprite_offset); } } else { @@ -3599,14 +3598,15 @@ static TrackStatus GetTileTrackStatus_Station(TileIndex tile, TransportType mode RoadTramType rtt = (RoadTramType)sub_mode; if (!HasTileRoadType(tile, rtt)) break; - DiagDirection dir = GetRoadStopDir(tile); - Axis axis = DiagDirToAxis(dir); - - if (side != INVALID_DIAGDIR) { - if (axis != DiagDirToAxis(side) || (IsBayRoadStopTile(tile) && dir != side)) break; + if (IsBayRoadStopTile(tile)) { + DiagDirection dir = GetBayRoadStopDir(tile); + if (side != INVALID_DIAGDIR && dir != side) break; + trackbits = DiagDirToDiagTrackBits(dir); + } else { + Axis axis = GetDriveThroughStopAxis(tile); + if (side != INVALID_DIAGDIR && axis != DiagDirToAxis(side)) break; + trackbits = AxisToTrackBits(axis); } - - trackbits = AxisToTrackBits(axis); } break; @@ -4754,9 +4754,7 @@ static CommandCost TerraformTile_Station(TileIndex tile, DoCommandFlag flags, in switch (GetStationType(tile)) { case STATION_WAYPOINT: case STATION_RAIL: { - DiagDirection direction = AxisToDiagDir(GetRailStationAxis(tile)); - if (!AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, direction)) break; - if (!AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, ReverseDiagDir(direction))) break; + if (!AutoslopeCheckForAxis(tile, z_new, tileh_new, GetRailStationAxis(tile))) break; return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]); } @@ -4765,10 +4763,10 @@ static CommandCost TerraformTile_Station(TileIndex tile, DoCommandFlag flags, in case STATION_TRUCK: case STATION_BUS: { - DiagDirection direction = GetRoadStopDir(tile); - if (!AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, direction)) break; if (IsDriveThroughStopTile(tile)) { - if (!AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, ReverseDiagDir(direction))) break; + if (!AutoslopeCheckForAxis(tile, z_new, tileh_new, GetDriveThroughStopAxis(tile))) break; + } else { + if (!AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, GetBayRoadStopDir(tile))) break; } return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]); } diff --git a/src/station_map.h b/src/station_map.h index b4dad48986..2adf690d7c 100644 --- a/src/station_map.h +++ b/src/station_map.h @@ -336,20 +336,27 @@ inline StationGfx GetAirportGfx(Tile t) } /** - * Gets the direction the road stop entrance points towards. + * Gets the direction the bay road stop entrance points towards. * @param t the tile of the road stop - * @pre IsAnyRoadStopTile(t) + * @pre IsBayRoadStopTile(t) * @return the direction of the entrance */ -inline DiagDirection GetRoadStopDir(Tile t) +inline DiagDirection GetBayRoadStopDir(Tile t) { - StationGfx gfx = GetStationGfx(t); - assert(IsAnyRoadStopTile(t)); - if (gfx < GFX_TRUCK_BUS_DRIVETHROUGH_OFFSET) { - return (DiagDirection)(gfx); - } else { - return (DiagDirection)(gfx - GFX_TRUCK_BUS_DRIVETHROUGH_OFFSET); - } + assert(IsBayRoadStopTile(t)); + return static_cast(GetStationGfx(t)); +} + +/** + * Gets the axis of the drive through stop. + * @param t the tile of the road stop + * @pre IsDriveThroughStopTile(t) + * @return the axis the drive through is in + */ +inline Axis GetDriveThroughStopAxis(Tile t) +{ + assert(IsDriveThroughStopTile(t)); + return static_cast(GetStationGfx(t) - GFX_TRUCK_BUS_DRIVETHROUGH_OFFSET); } /** diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index a81522a362..c938b85e2d 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -1252,7 +1252,9 @@ static bool CanRoadContinueIntoNextTile(const Town *t, const TileIndex tile, con /* If the next tile is a station, allow if it's a road station facing the proper direction. Otherwise return false. */ if (IsTileType(next_tile, MP_STATION)) { /* If the next tile is a road station, allow if it can be entered by the new tunnel/bridge, otherwise disallow. */ - return IsAnyRoadStop(next_tile) && (GetRoadStopDir(next_tile) == ReverseDiagDir(road_dir) || (IsDriveThroughStopTile(next_tile) && GetRoadStopDir(next_tile) == road_dir)); + if (IsDriveThroughStopTile(next_tile)) return GetDriveThroughStopAxis(next_tile) == DiagDirToAxis(road_dir); + if (IsBayRoadStopTile(next_tile)) return GetBayRoadStopDir(next_tile) == ReverseDiagDir(road_dir); + return false; } /* If the next tile is a road depot, allow if it's facing the right way. */ diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp index e5d7c40561..40b6f32ee6 100644 --- a/src/waypoint_cmd.cpp +++ b/src/waypoint_cmd.cpp @@ -123,7 +123,7 @@ Axis GetAxisForNewRailWaypoint(TileIndex tile) Axis GetAxisForNewRoadWaypoint(TileIndex tile) { /* The axis for existing road waypoints is easy. */ - if (IsRoadWaypointTile(tile)) return DiagDirToAxis(GetRoadStopDir(tile)); + if (IsRoadWaypointTile(tile)) return GetDriveThroughStopAxis(tile); /* Non-plain road type, no valid axis for waypoints. */ if (!IsNormalRoadTile(tile)) return INVALID_AXIS;