1
0
Fork 0

Codechange: split GetRoadDir as bays have DiagDir and drive throughs have Axis

pull/13029/head
Rubidium 2024-10-22 23:25:07 +02:00 committed by rubidium42
parent d6aa09f96a
commit c9819f8957
11 changed files with 100 additions and 56 deletions

View File

@ -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.
*

View File

@ -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));

View File

@ -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 {

View File

@ -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;

View File

@ -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<const RoadVehicle *> 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);

View File

@ -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) */

View File

@ -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)

View File

@ -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]);
}

View File

@ -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<DiagDirection>(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<Axis>(GetStationGfx(t) - GFX_TRUCK_BUS_DRIVETHROUGH_OFFSET);
}
/**

View File

@ -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. */

View File

@ -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;