Allow drive-through road stops to be one-way

This commit is contained in:
Jonathan G Rennison
2020-10-24 20:39:15 +01:00
parent 3fa92f5d8e
commit 3a75f13874
16 changed files with 333 additions and 50 deletions

View File

@@ -1080,11 +1080,6 @@ static CommandCost CheckFlatLandRoadStop(TileArea tile_area, DoCommandFlag flags
if (RoadTypeIsRoad(rt) && !HasPowerOnRoad(rt, road_rt)) return_cmd_error(STR_ERROR_NO_SUITABLE_ROAD);
if (GetDisallowedRoadDirections(cur_tile) != DRD_NONE && road_owner != OWNER_TOWN) {
CommandCost ret = CheckOwnership(road_owner);
if (ret.Failed()) return ret;
}
cost.AddCost(RoadBuildCost(road_rt) * (2 - num_pieces));
} else if (RoadTypeIsRoad(rt)) {
cost.AddCost(RoadBuildCost(rt) * 2);
@@ -2034,6 +2029,7 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
RoadType tram_rt = MayHaveRoad(cur_tile) ? GetRoadType(cur_tile, RTT_TRAM) : INVALID_ROADTYPE;
Owner road_owner = road_rt != INVALID_ROADTYPE ? GetRoadOwner(cur_tile, RTT_ROAD) : _current_company;
Owner tram_owner = tram_rt != INVALID_ROADTYPE ? GetRoadOwner(cur_tile, RTT_TRAM) : _current_company;
DisallowedRoadDirections drd = IsNormalRoadTile(cur_tile) ? GetDisallowedRoadDirections(cur_tile) : DRD_NONE;
if (IsTileType(cur_tile, MP_STATION) && IsRoadStop(cur_tile)) {
RemoveRoadStop(cur_tile, flags);
@@ -2071,6 +2067,7 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
UpdateCompanyRoadInfrastructure(tram_rt, tram_owner, 2);
MakeDriveThroughRoadStop(cur_tile, st->owner, road_owner, tram_owner, st->index, rs_type, road_rt, tram_rt, axis);
SetDriveThroughStopDisallowedRoadDirections(cur_tile, drd);
road_stop->MakeDriveThrough();
} else {
if (road_rt == INVALID_ROADTYPE && RoadTypeIsRoad(rt)) road_rt = rt;
@@ -2246,6 +2243,7 @@ CommandCost CmdRemoveRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, ui
RoadBits road_bits = ROAD_NONE;
RoadType road_type[] = { INVALID_ROADTYPE, INVALID_ROADTYPE };
Owner road_owner[] = { OWNER_NONE, OWNER_NONE };
DisallowedRoadDirections drd = DRD_NONE;
if (IsDriveThroughStopTile(cur_tile)) {
FOR_ALL_ROADTRAMTYPES(rtt) {
road_type[rtt] = GetRoadType(cur_tile, rtt);
@@ -2255,6 +2253,7 @@ CommandCost CmdRemoveRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, ui
if (!keep_drive_through_roads && road_owner[rtt] == _current_company) road_type[rtt] = INVALID_ROADTYPE;
}
road_bits = AxisToRoadBits(DiagDirToAxis(GetRoadStopDir(cur_tile)));
drd = GetDriveThroughStopDisallowedRoadDirections(cur_tile);
}
CommandCost ret = RemoveRoadStop(cur_tile, flags);
@@ -2269,6 +2268,7 @@ CommandCost CmdRemoveRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, ui
if ((flags & DC_EXEC) && (road_type[RTT_ROAD] != INVALID_ROADTYPE || road_type[RTT_TRAM] != INVALID_ROADTYPE)) {
MakeRoadNormal(cur_tile, road_bits, road_type[RTT_ROAD], road_type[RTT_TRAM], ClosestTownFromTile(cur_tile, UINT_MAX)->index,
road_owner[RTT_ROAD], road_owner[RTT_TRAM]);
if (drd != DRD_NONE) SetDisallowedRoadDirections(cur_tile, drd);
/* Update company infrastructure counts. */
int count = CountBits(road_bits);
@@ -3270,6 +3270,11 @@ draw_default_foundation:
uint sprite_offset = axis == AXIS_X ? 1 : 0;
DrawRoadOverlays(ti, PAL_NONE, road_rti, tram_rti, sprite_offset, sprite_offset);
DisallowedRoadDirections drd = GetDriveThroughStopDisallowedRoadDirections(ti->tile);
if (drd != DRD_NONE) {
DrawGroundSpriteAt(SPR_ONEWAY_BASE + drd - 1 + ((axis == AXIS_X) ? 0 : 3), PAL_NONE, 8, 8, 0);
}
} else {
/* Non-drivethrough road stops are only valid for roads. */
assert_tile(road_rt != INVALID_ROADTYPE && tram_rt == INVALID_ROADTYPE, ti->tile);
@@ -3460,23 +3465,24 @@ static void GetTileDesc_Station(TileIndex tile, TileDesc *td)
static TrackStatus GetTileTrackStatus_Station(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
{
TrackBits trackbits = TRACK_BIT_NONE;
TrackdirBits trackdirbits = TRACKDIR_BIT_NONE;
switch (mode) {
case TRANSPORT_RAIL:
if (HasStationRail(tile) && !IsStationTileBlocked(tile)) {
trackbits = TrackToTrackBits(GetRailStationTrack(tile));
trackdirbits = TrackToTrackdirBits(GetRailStationTrack(tile));
}
break;
case TRANSPORT_WATER:
/* buoy is coded as a station, it is always on open water */
if (IsBuoy(tile)) {
trackbits = TRACK_BIT_ALL;
TrackBits trackbits = TRACK_BIT_ALL;
/* remove tracks that connect NE map edge */
if (TileX(tile) == 0) trackbits &= ~(TRACK_BIT_X | TRACK_BIT_UPPER | TRACK_BIT_RIGHT);
/* remove tracks that connect NW map edge */
if (TileY(tile) == 0) trackbits &= ~(TRACK_BIT_Y | TRACK_BIT_LEFT | TRACK_BIT_UPPER);
trackdirbits = TrackBitsToTrackdirBits(trackbits);
}
break;
@@ -3492,7 +3498,13 @@ static TrackStatus GetTileTrackStatus_Station(TileIndex tile, TransportType mode
if (axis != DiagDirToAxis(side) || (IsStandardRoadStopTile(tile) && dir != side)) break;
}
trackbits = AxisToTrackBits(axis);
TrackBits trackbits = AxisToTrackBits(axis);
if (IsDriveThroughStopTile(tile)) {
const uint drd_to_multiplier[DRD_END] = { 0x101, 0x100, 0x1, 0x0 };
trackdirbits = (TrackdirBits)(trackbits * drd_to_multiplier[GetDriveThroughStopDisallowedRoadDirections(tile)]);
} else {
trackdirbits = TrackBitsToTrackdirBits(trackbits);
}
}
break;
@@ -3500,7 +3512,7 @@ static TrackStatus GetTileTrackStatus_Station(TileIndex tile, TransportType mode
break;
}
return CombineTrackStatus(TrackBitsToTrackdirBits(trackbits), TRACKDIR_BIT_NONE);
return CombineTrackStatus(trackdirbits, TRACKDIR_BIT_NONE);
}