Add road tile cached one way state, one way road section detection
This commit is contained in:
294
src/road_cmd.cpp
294
src/road_cmd.cpp
@@ -38,6 +38,7 @@
|
||||
#include "company_gui.h"
|
||||
#include "road_func.h"
|
||||
#include "roadstop_base.h"
|
||||
#include "scope.h"
|
||||
|
||||
#include "table/strings.h"
|
||||
#include "table/roadtypes.h"
|
||||
@@ -187,6 +188,229 @@ bool RoadVehiclesAreBuilt()
|
||||
return !RoadVehicle::Iterate().empty();
|
||||
}
|
||||
|
||||
static DisallowedRoadDirections GetOneWayRoadTileDisallowedRoadDirections(TileIndex tile)
|
||||
{
|
||||
if (IsNormalRoadTile(tile)) return GetDisallowedRoadDirections(tile);
|
||||
if (IsDriveThroughStopTile(tile)) return GetDriveThroughStopDisallowedRoadDirections(tile);
|
||||
return DRD_NONE;
|
||||
}
|
||||
|
||||
static DiagDirection OneWaySideJunctionRoadRoadBitsToDiagDir(RoadBits bits)
|
||||
{
|
||||
/*
|
||||
* Drive on left missing bit:
|
||||
* ROAD_SE (bit 2) -> DIAGDIR_NE (0)
|
||||
* ROAD_SW (bit 1) -> DIAGDIR_SE (1)
|
||||
* ROAD_NW (bit 0) -> DIAGDIR_SW (2)
|
||||
* ROAD_NE (bit 3) -> DIAGDIR_NW (3)
|
||||
*/
|
||||
uint8 bit = FIND_FIRST_BIT(bits ^ ROAD_ALL);
|
||||
bit ^= 3;
|
||||
return (DiagDirection)((bit + 3 + (_settings_game.vehicle.road_side * 2)) % 4);
|
||||
}
|
||||
|
||||
inline bool IsOneWaySideJunctionRoadDRDsPresent(TileIndex tile, DiagDirection dir)
|
||||
{
|
||||
const DisallowedRoadDirections diagdir_to_drd[DIAGDIR_END] = { DRD_NORTHBOUND, DRD_NORTHBOUND, DRD_SOUTHBOUND, DRD_SOUTHBOUND };
|
||||
|
||||
TileIndexDiffC ti = TileIndexDiffCByDiagDir(dir);
|
||||
TileIndex ahead = AddTileIndexDiffCWrap(tile, ti);
|
||||
if (ahead == INVALID_TILE || GetOneWayRoadTileDisallowedRoadDirections(ahead) != diagdir_to_drd[dir]) return false;
|
||||
TileIndex behind = AddTileIndexDiffCWrap(tile, { (int16)(-ti.x), (int16)(-ti.y) });
|
||||
if (behind == INVALID_TILE || GetOneWayRoadTileDisallowedRoadDirections(behind) != diagdir_to_drd[dir]) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static btree::btree_set<TileIndex> _road_cache_one_way_state_pending_tiles;
|
||||
static btree::btree_set<TileIndex> _road_cache_one_way_state_pending_interpolate_tiles;
|
||||
static bool _defer_update_road_cache_one_way_state = false;
|
||||
bool _mark_tile_dirty_on_road_cache_one_way_state_update = false;
|
||||
|
||||
static void UpdateTileRoadCachedOneWayState(TileIndex tile)
|
||||
{
|
||||
if (unlikely(_mark_tile_dirty_on_road_cache_one_way_state_update)) MarkTileGroundDirtyByTile(tile, VMDF_NOT_MAP_MODE);
|
||||
|
||||
DisallowedRoadDirections drd = GetOneWayRoadTileDisallowedRoadDirections(tile);
|
||||
if (drd != DRD_NONE) {
|
||||
SetRoadCachedOneWayState(tile, (RoadCachedOneWayState)drd);
|
||||
return;
|
||||
}
|
||||
if (IsNormalRoadTile(tile)) {
|
||||
RoadBits bits = GetRoadBits(tile, RTT_ROAD);
|
||||
if (HasExactlyOneBit(bits ^ ROAD_ALL)) {
|
||||
DiagDirection dir = OneWaySideJunctionRoadRoadBitsToDiagDir(bits);
|
||||
if (IsOneWaySideJunctionRoadDRDsPresent(tile, dir)) {
|
||||
DiagDirection side_dir = (DiagDirection)((dir + 3 + (_settings_game.vehicle.road_side * 2)) % 4);
|
||||
TileIndexDiffC ti = TileIndexDiffCByDiagDir(side_dir);
|
||||
TileIndex side = AddTileIndexDiffCWrap(tile, ti);
|
||||
|
||||
const DisallowedRoadDirections diagdir_to_drd[DIAGDIR_END] = { DRD_SOUTHBOUND, DRD_SOUTHBOUND, DRD_NORTHBOUND, DRD_NORTHBOUND };
|
||||
SetRoadCachedOneWayState(tile, (GetOneWayRoadTileDisallowedRoadDirections(side) & diagdir_to_drd[side_dir]) ? RCOWS_SIDE_JUNCTION_NO_EXIT : RCOWS_SIDE_JUNCTION);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!IsTileType(tile, MP_STATION)) _road_cache_one_way_state_pending_interpolate_tiles.insert(tile);
|
||||
SetRoadCachedOneWayState(tile, RCOWS_NORMAL);
|
||||
}
|
||||
|
||||
/* Do not re-order, see: RoadCachedOneWayState */
|
||||
enum InterpolateRoadResult {
|
||||
IRR_NONE,
|
||||
IRR_OUT,
|
||||
IRR_IN
|
||||
};
|
||||
|
||||
static TileIndex InterpolateRoadFollowTileStep(TileIndex tile, uint8 bit)
|
||||
{
|
||||
DiagDirection outgoing = (DiagDirection)(bit ^ 3);
|
||||
if (IsTileType(tile, MP_TUNNELBRIDGE) && GetTunnelBridgeDirection(tile) == outgoing) {
|
||||
return GetOtherTunnelBridgeEnd(tile);
|
||||
}
|
||||
TileIndexDiffC ti = TileIndexDiffCByDiagDir(outgoing);
|
||||
TileIndex next = AddTileIndexDiffCWrap(tile, ti);
|
||||
if (next == INVALID_TILE) return INVALID_TILE;
|
||||
if (IsTileType(next, MP_TUNNELBRIDGE) && GetTunnelBridgeDirection(next) == ReverseDiagDir(outgoing)) {
|
||||
return INVALID_TILE;
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
static InterpolateRoadResult InterpolateRoadFollowRoadBit(TileIndex tile, uint8 bit)
|
||||
{
|
||||
const TileIndex start = tile;
|
||||
do {
|
||||
TileIndex next = InterpolateRoadFollowTileStep(tile, bit);
|
||||
if (next == INVALID_TILE) return IRR_NONE;
|
||||
DisallowedRoadDirections drd = GetOneWayRoadTileDisallowedRoadDirections(next);
|
||||
if (drd == DRD_BOTH) return IRR_NONE;
|
||||
if (drd != DRD_NONE) {
|
||||
const DisallowedRoadDirections outgoing_drd_by_exit_bit[4] = { DRD_SOUTHBOUND, DRD_SOUTHBOUND, DRD_NORTHBOUND, DRD_NORTHBOUND };
|
||||
return outgoing_drd_by_exit_bit[bit] == drd ? IRR_OUT : IRR_IN;
|
||||
}
|
||||
if (IsTileType(next, MP_STATION)) return IRR_NONE;
|
||||
RoadBits incoming = (RoadBits)(1 << (bit ^ 2));
|
||||
RoadBits rb = GetAnyRoadBits(next, RTT_ROAD, true);
|
||||
if ((incoming & rb) == 0) return IRR_NONE;
|
||||
RoadBits remaining = rb & ~incoming;
|
||||
if (!HasExactlyOneBit(remaining)) return IRR_NONE;
|
||||
tile = next;
|
||||
bit = FIND_FIRST_BIT(remaining);
|
||||
} while (tile != start);
|
||||
return IRR_NONE;
|
||||
}
|
||||
|
||||
static void InterpolateRoadFollowRoadBitSetState(TileIndex tile, uint8 bit, InterpolateRoadResult irr)
|
||||
{
|
||||
const TileIndex start = tile;
|
||||
do {
|
||||
if (irr == IRR_NONE) {
|
||||
SetRoadCachedOneWayState(tile, RCOWS_NORMAL);
|
||||
} else {
|
||||
uint8 inbit = FIND_FIRST_BIT(GetAnyRoadBits(tile, RTT_ROAD, true) & ~(1 << bit));
|
||||
/* inbit bit piece Outgoing Trackdir IRR_IN case
|
||||
*
|
||||
* 0 1 ROAD_W TRACKDIR_LEFT_S RCOWS_NON_JUNCTION_A
|
||||
* 0 2 ROAD_Y TRACKDIR_Y_SE RCOWS_NON_JUNCTION_A
|
||||
* 0 3 ROAD_N TRACKDIR_UPPER_E RCOWS_NON_JUNCTION_A
|
||||
*
|
||||
* 1 0 ROAD_W TRACKDIR_LEFT_N RCOWS_NON_JUNCTION_B
|
||||
* 1 2 ROAD_S TRACKDIR_LOWER_E RCOWS_NON_JUNCTION_A
|
||||
* 1 3 ROAD_X TRACKDIR_X_NE RCOWS_NON_JUNCTION_A
|
||||
*
|
||||
* 2 0 ROAD_Y TRACKDIR_Y_NW RCOWS_NON_JUNCTION_B
|
||||
* 2 1 ROAD_S TRACKDIR_LOWER_W RCOWS_NON_JUNCTION_B
|
||||
* 2 3 ROAD_E TRACKDIR_RIGHT_N RCOWS_NON_JUNCTION_B
|
||||
*
|
||||
* 3 0 ROAD_N TRACKDIR_UPPER_W RCOWS_NON_JUNCTION_B
|
||||
* 3 1 ROAD_X TRACKDIR_X_SW RCOWS_NON_JUNCTION_B
|
||||
* 3 2 ROAD_E TRACKDIR_RIGHT_S RCOWS_NON_JUNCTION_A
|
||||
*/
|
||||
|
||||
const uint16 bits_to_rcows = 0x3B10;
|
||||
SetRoadCachedOneWayState(tile, (RoadCachedOneWayState)(irr ^ (HasBit(bits_to_rcows, (inbit << 2) | bit) ? 0 : 3)));
|
||||
}
|
||||
_road_cache_one_way_state_pending_interpolate_tiles.erase(tile);
|
||||
if (unlikely(_mark_tile_dirty_on_road_cache_one_way_state_update)) MarkTileGroundDirtyByTile(tile, VMDF_NOT_MAP_MODE);
|
||||
TileIndex next = InterpolateRoadFollowTileStep(tile, bit);
|
||||
if (next == INVALID_TILE) return;
|
||||
DisallowedRoadDirections drd = GetOneWayRoadTileDisallowedRoadDirections(next);
|
||||
if (drd != DRD_NONE) {
|
||||
return;
|
||||
}
|
||||
if (IsTileType(next, MP_STATION)) return;
|
||||
RoadBits incoming = (RoadBits)(1 << (bit ^ 2));
|
||||
RoadBits rb = GetAnyRoadBits(next, RTT_ROAD, true);
|
||||
if ((incoming & rb) == 0) return;
|
||||
RoadBits remaining = rb & ~incoming;
|
||||
if (!HasExactlyOneBit(remaining)) return;
|
||||
tile = next;
|
||||
bit = FIND_FIRST_BIT(remaining);
|
||||
} while (tile != start);
|
||||
}
|
||||
|
||||
static void InterpolateRoadCachedOneWayStates()
|
||||
{
|
||||
while (!_road_cache_one_way_state_pending_interpolate_tiles.empty()) {
|
||||
auto iter = _road_cache_one_way_state_pending_interpolate_tiles.begin();
|
||||
TileIndex tile = *iter;
|
||||
_road_cache_one_way_state_pending_interpolate_tiles.erase(iter);
|
||||
|
||||
const RoadBits bits = GetAnyRoadBits(tile, RTT_ROAD, true);
|
||||
if (CountBits(bits) != 2) continue;
|
||||
|
||||
uint8 first_bit = FIND_FIRST_BIT(bits);
|
||||
uint8 second_bit = FIND_FIRST_BIT(KillFirstBit(bits));
|
||||
InterpolateRoadResult first_irr = InterpolateRoadFollowRoadBit(tile, first_bit);
|
||||
InterpolateRoadResult second_irr = first_irr;
|
||||
if (first_irr != IRR_NONE) {
|
||||
second_irr = InterpolateRoadFollowRoadBit(tile, second_bit);
|
||||
if (second_irr == IRR_NONE || second_irr == first_irr) first_irr = second_irr = IRR_NONE;
|
||||
}
|
||||
InterpolateRoadFollowRoadBitSetState(tile, first_bit, first_irr);
|
||||
InterpolateRoadFollowRoadBitSetState(tile, second_bit, second_irr);
|
||||
}
|
||||
}
|
||||
|
||||
void RecalculateRoadCachedOneWayStates()
|
||||
{
|
||||
for (TileIndex tile = 0; tile != MapSize(); tile++) {
|
||||
if (MayHaveRoad(tile)) UpdateTileRoadCachedOneWayState(tile);
|
||||
}
|
||||
InterpolateRoadCachedOneWayStates();
|
||||
}
|
||||
|
||||
void UpdateRoadCachedOneWayStatesAroundTile(TileIndex tile)
|
||||
{
|
||||
if (_generating_world) return;
|
||||
|
||||
auto check_tile = [](TileIndex t) {
|
||||
if (_defer_update_road_cache_one_way_state) {
|
||||
_road_cache_one_way_state_pending_tiles.insert(t);
|
||||
} else if (MayHaveRoad(t)) {
|
||||
UpdateTileRoadCachedOneWayState(t);
|
||||
}
|
||||
};
|
||||
check_tile(tile);
|
||||
uint x_offset = TileXY(1, 0);
|
||||
if (tile >= x_offset) check_tile(tile - x_offset);
|
||||
if (tile + x_offset < MapSize()) check_tile(tile + x_offset);
|
||||
uint y_offset = TileXY(0, 1);
|
||||
if (tile >= y_offset) check_tile(tile - y_offset);
|
||||
if (tile + y_offset < MapSize()) check_tile(tile + y_offset);
|
||||
if (!_defer_update_road_cache_one_way_state) InterpolateRoadCachedOneWayStates();
|
||||
}
|
||||
|
||||
void FlushDeferredUpdateRoadCachedOneWayStates()
|
||||
{
|
||||
_defer_update_road_cache_one_way_state = false;
|
||||
for (TileIndex t : _road_cache_one_way_state_pending_tiles) {
|
||||
if (MayHaveRoad(t)) UpdateTileRoadCachedOneWayState(t);
|
||||
}
|
||||
_road_cache_one_way_state_pending_tiles.clear();
|
||||
InterpolateRoadCachedOneWayStates();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update road infrastructure counts for a company.
|
||||
* @param rt Road type to update count of.
|
||||
@@ -470,6 +694,10 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec
|
||||
|
||||
/* Todo: Change this to be more fine-grained if necessary */
|
||||
NotifyRoadLayoutChanged(false);
|
||||
if (rtt == RTT_ROAD) {
|
||||
UpdateRoadCachedOneWayStatesAroundTile(tile);
|
||||
UpdateRoadCachedOneWayStatesAroundTile(other_end);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
assert_tile(IsDriveThroughStopTile(tile), tile);
|
||||
@@ -480,6 +708,9 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec
|
||||
SetRoadType(tile, rtt, INVALID_ROADTYPE);
|
||||
MarkTileDirtyByTile(tile);
|
||||
NotifyRoadLayoutChanged(false);
|
||||
if (rtt == RTT_ROAD) {
|
||||
UpdateRoadCachedOneWayStatesAroundTile(tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
return cost;
|
||||
@@ -558,6 +789,9 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec
|
||||
SetRoadBits(tile, present, rtt);
|
||||
MarkTileDirtyByTile(tile);
|
||||
}
|
||||
if (rtt == RTT_ROAD) {
|
||||
UpdateRoadCachedOneWayStatesAroundTile(tile);
|
||||
}
|
||||
}
|
||||
|
||||
CommandCost cost(EXPENSES_CONSTRUCTION, CountBits(pieces) * RoadClearCost(existing_rt));
|
||||
@@ -596,6 +830,9 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec
|
||||
}
|
||||
MarkTileDirtyByTile(tile);
|
||||
YapfNotifyTrackLayoutChange(tile, railtrack);
|
||||
if (rtt == RTT_ROAD) {
|
||||
UpdateRoadCachedOneWayStatesAroundTile(tile);
|
||||
}
|
||||
}
|
||||
return CommandCost(EXPENSES_CONSTRUCTION, RoadClearCost(existing_rt) * 2);
|
||||
}
|
||||
@@ -771,6 +1008,7 @@ CommandCost CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
||||
SetDisallowedRoadDirections(tile, dis_new);
|
||||
MarkTileDirtyByTile(tile);
|
||||
NotifyRoadLayoutChanged(CountBits(dis_existing) > CountBits(dis_new));
|
||||
UpdateRoadCachedOneWayStatesAroundTile(tile);
|
||||
}
|
||||
return CommandCost();
|
||||
}
|
||||
@@ -866,6 +1104,9 @@ CommandCost CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
||||
SetCrossingReservation(tile, reserved);
|
||||
UpdateLevelCrossing(tile, false);
|
||||
if (RoadLayoutChangeNotificationEnabled(true)) NotifyRoadLayoutChangedIfTileNonLeaf(tile, rtt, GetCrossingRoadBits(tile));
|
||||
if (rtt == RTT_ROAD) {
|
||||
UpdateRoadCachedOneWayStatesAroundTile(tile);
|
||||
}
|
||||
MarkTileDirtyByTile(tile);
|
||||
}
|
||||
return CommandCost(EXPENSES_CONSTRUCTION, 2 * RoadBuildCost(rt));
|
||||
@@ -897,6 +1138,7 @@ CommandCost CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
||||
rs->ChangeDriveThroughDisallowedRoadDirections(dis_new);
|
||||
MarkTileDirtyByTile(tile);
|
||||
NotifyRoadLayoutChanged(CountBits(dis_existing) > CountBits(dis_new));
|
||||
UpdateRoadCachedOneWayStatesAroundTile(tile);
|
||||
}
|
||||
return CommandCost();
|
||||
}
|
||||
@@ -1028,6 +1270,10 @@ CommandCost CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
||||
|
||||
AddRoadTunnelBridgeInfrastructure(tile, other_end);
|
||||
NotifyRoadLayoutChanged(true);
|
||||
if (rtt == RTT_ROAD) {
|
||||
UpdateRoadCachedOneWayStatesAroundTile(tile);
|
||||
UpdateRoadCachedOneWayStatesAroundTile(other_end);
|
||||
}
|
||||
DirtyAllCompanyInfrastructureWindows();
|
||||
}
|
||||
|
||||
@@ -1144,6 +1390,9 @@ do_clear:;
|
||||
MarkTileDirtyByTile(other_end);
|
||||
MarkTileDirtyByTile(tile);
|
||||
}
|
||||
if (rtt == RTT_ROAD) {
|
||||
UpdateRoadCachedOneWayStatesAroundTile(other_end);
|
||||
}
|
||||
NotifyRoadLayoutChanged(true);
|
||||
break;
|
||||
}
|
||||
@@ -1171,6 +1420,9 @@ do_clear:;
|
||||
SetDisallowedRoadDirections(tile, IsStraightRoad(existing) ?
|
||||
GetDisallowedRoadDirections(tile) ^ toggle_drd : DRD_NONE);
|
||||
}
|
||||
if (rtt == RTT_ROAD) {
|
||||
UpdateRoadCachedOneWayStatesAroundTile(tile);
|
||||
}
|
||||
|
||||
MarkTileDirtyByTile(tile);
|
||||
}
|
||||
@@ -1252,6 +1504,11 @@ CommandCost CmdBuildLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32 p
|
||||
bool had_success = false;
|
||||
bool is_ai = HasBit(p2, 11);
|
||||
|
||||
_defer_update_road_cache_one_way_state = true;
|
||||
auto guard = scope_guard([]() {
|
||||
FlushDeferredUpdateRoadCachedOneWayStates();
|
||||
});
|
||||
|
||||
/* Start tile is the first tile clicked by the user. */
|
||||
for (;;) {
|
||||
RoadBits bits = AxisToRoadBits(axis);
|
||||
@@ -1335,6 +1592,11 @@ CommandCost CmdRemoveLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32
|
||||
p2 ^= IsInsideMM(p2 & 3, 1, 3) ? 3 : 0;
|
||||
}
|
||||
|
||||
_defer_update_road_cache_one_way_state = true;
|
||||
auto guard = scope_guard([]() {
|
||||
FlushDeferredUpdateRoadCachedOneWayStates();
|
||||
});
|
||||
|
||||
Money money = GetAvailableMoneyForCommand();
|
||||
TileIndex tile = start_tile;
|
||||
CommandCost last_error = CMD_ERROR;
|
||||
@@ -2258,16 +2520,40 @@ static TrackStatus GetTileTrackStatus_Road(TileIndex tile, TransportType mode, u
|
||||
switch (GetRoadTileType(tile)) {
|
||||
case ROAD_TILE_NORMAL: {
|
||||
const uint drd_to_multiplier[DRD_END] = { 0x101, 0x100, 0x1, 0x0 };
|
||||
const TrackdirBits left_turns = TRACKDIR_BIT_LOWER_W | TRACKDIR_BIT_LEFT_N | TRACKDIR_BIT_UPPER_E | TRACKDIR_BIT_RIGHT_S;
|
||||
const TrackdirBits right_turns = TRACKDIR_BIT_LOWER_E | TRACKDIR_BIT_LEFT_S | TRACKDIR_BIT_UPPER_W | TRACKDIR_BIT_RIGHT_N;
|
||||
const TrackdirBits no_exit_turns[4] = {
|
||||
TRACKDIR_BIT_RIGHT_S | TRACKDIR_BIT_LOWER_E, // ROAD_NW
|
||||
TRACKDIR_BIT_RIGHT_N | TRACKDIR_BIT_UPPER_E, // ROAD_SW
|
||||
TRACKDIR_BIT_LEFT_N | TRACKDIR_BIT_UPPER_W, // ROAD_SE
|
||||
TRACKDIR_BIT_LEFT_S | TRACKDIR_BIT_LOWER_W // ROAD_NE
|
||||
};
|
||||
|
||||
RoadBits bits = GetRoadBits(tile, rtt);
|
||||
|
||||
/* no roadbit at this side of tile, return 0 */
|
||||
if (side != INVALID_DIAGDIR && (DiagDirToRoadBits(side) & bits) == 0) break;
|
||||
|
||||
uint multiplier = drd_to_multiplier[(rtt == RTT_TRAM) ? DRD_NONE : GetDisallowedRoadDirections(tile)];
|
||||
if (!HasRoadWorks(tile)) trackdirbits = (TrackdirBits)(_road_trackbits[bits] * multiplier);
|
||||
if (!HasRoadWorks(tile)) {
|
||||
RoadCachedOneWayState rcows = (rtt == RTT_TRAM) ? RCOWS_NORMAL : GetRoadCachedOneWayState(tile);
|
||||
switch (rcows) {
|
||||
case RCOWS_NORMAL:
|
||||
case RCOWS_NON_JUNCTION_A:
|
||||
case RCOWS_NON_JUNCTION_B:
|
||||
case RCOWS_NO_ACCESS:
|
||||
trackdirbits = (TrackdirBits)(_road_trackbits[bits] * drd_to_multiplier[(DisallowedRoadDirections)rcows]);
|
||||
break;
|
||||
|
||||
extern TrackdirBits MaskOneWaySideJunctionRoad(TileIndex tile, RoadBits bits);
|
||||
if (rtt == RTT_ROAD && HasExactlyOneBit(bits ^ ROAD_ALL)) trackdirbits &= MaskOneWaySideJunctionRoad(tile, bits);
|
||||
case RCOWS_SIDE_JUNCTION:
|
||||
case RCOWS_SIDE_JUNCTION_NO_EXIT:
|
||||
trackdirbits = (TrackdirBits)((_road_trackbits[bits] * 0x101) & ~(_settings_game.vehicle.road_side ? left_turns : right_turns));
|
||||
if (rcows == RCOWS_SIDE_JUNCTION_NO_EXIT) trackdirbits &= ~no_exit_turns[FIND_FIRST_BIT(bits ^ ROAD_ALL) & 3];
|
||||
break;
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user