mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2026-07-17 16:19:41 +00:00
Codechange: make Trackdir a scoped enum and TrackdirBits an EnumBitSet (#15696)
This commit is contained in:
+5
-5
@@ -133,7 +133,7 @@ static TrackBits MaskWireBits(TileIndex t, TrackBits tracks)
|
||||
|
||||
if (!IsPlainRailTile(t)) return tracks;
|
||||
|
||||
TrackdirBits neighbour_tdb = TRACKDIR_BIT_NONE;
|
||||
TrackdirBits neighbour_tdb{};
|
||||
for (DiagDirection d = DiagDirection::Begin; d < DiagDirection::End; d++) {
|
||||
/* If the neighbour tile is either not electrified or has no tracks that can be reached
|
||||
* from this tile, mark all trackdirs that can be reached from the neighbour tile
|
||||
@@ -155,7 +155,7 @@ static TrackBits MaskWireBits(TileIndex t, TrackBits tracks)
|
||||
if (tracks == TRACK_BIT_CROSS || !TracksOverlap(tracks)) {
|
||||
/* If the tracks form either a diagonal crossing or don't overlap, both
|
||||
* trackdirs have to be marked to mask the corresponding track bit. */
|
||||
mask = static_cast<TrackBits>(~((neighbour_tdb & (neighbour_tdb >> 8)) & TRACK_BIT_ALL.base()));
|
||||
mask = static_cast<TrackBits>(~((neighbour_tdb.base() & (neighbour_tdb.base() >> 8)) & TRACK_BIT_ALL.base()));
|
||||
/* If that results in no masked tracks and it is not a diagonal crossing,
|
||||
* require only one marked trackdir to mask. */
|
||||
if (tracks != TRACK_BIT_CROSS && mask == TRACK_BIT_ALL) mask = TrackdirBitsToTrackBits(neighbour_tdb).Flip(TRACK_BIT_ALL);
|
||||
@@ -164,10 +164,10 @@ static TrackBits MaskWireBits(TileIndex t, TrackBits tracks)
|
||||
mask = TrackdirBitsToTrackBits(neighbour_tdb).Flip(TRACK_BIT_ALL);
|
||||
/* If that results in an empty set, require both trackdirs for diagonal track. */
|
||||
if (!tracks.Any(mask)) {
|
||||
if ((neighbour_tdb & TRACKDIR_BIT_X_NE) == 0 || (neighbour_tdb & TRACKDIR_BIT_X_SW) == 0) mask.Set(Track::X);
|
||||
if ((neighbour_tdb & TRACKDIR_BIT_Y_NW) == 0 || (neighbour_tdb & TRACKDIR_BIT_Y_SE) == 0) mask.Set(Track::Y);
|
||||
if (!neighbour_tdb.Test(Trackdir::X_NE) || !neighbour_tdb.Test(Trackdir::X_SW)) mask.Set(Track::X);
|
||||
if (!neighbour_tdb.Test(Trackdir::Y_NW) || !neighbour_tdb.Test(Trackdir::Y_SE)) mask.Set(Track::Y);
|
||||
/* If that still is not enough, require both trackdirs for any track. */
|
||||
if (!tracks.Any(mask)) mask = static_cast<TrackBits>(~((neighbour_tdb & (neighbour_tdb >> 8)) & TRACK_BIT_ALL.base()));
|
||||
if (!tracks.Any(mask)) mask = static_cast<TrackBits>(~((neighbour_tdb.base() & (neighbour_tdb.base() >> 8)) & TRACK_BIT_ALL.base()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ static const std::string_view trackdir_names[] = {
|
||||
*/
|
||||
std::string ValueStr(Trackdir td)
|
||||
{
|
||||
return fmt::format("{} ({})", to_underlying(td), ItemAt(td, trackdir_names, "UNK", INVALID_TRACKDIR, "INV"));
|
||||
return fmt::format("{} ({})", to_underlying(td), ItemAt(td, trackdir_names, "UNK", Trackdir::Invalid, "INV"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,7 +37,7 @@ std::string ValueStr(Trackdir td)
|
||||
*/
|
||||
std::string ValueStr(TrackdirBits td_bits)
|
||||
{
|
||||
return fmt::format("{} ({})", to_underlying(td_bits), ComposeName(td_bits, trackdir_names, "UNK", INVALID_TRACKDIR_BIT, "INV"));
|
||||
return fmt::format("{} ({})", td_bits.base(), ComposeName(td_bits, trackdir_names, "UNK", INVALID_TRACKDIR_BIT, "INV"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
+14
-38
@@ -58,34 +58,21 @@ inline std::string_view ItemAt(E idx, std::span<const std::string_view> names, s
|
||||
/**
|
||||
* Helper template function that returns compound bitfield name that is
|
||||
* concatenation of names of each set bit in the given value
|
||||
* or invalid_name when index == invalid_index
|
||||
* or unknown_name when index is out of bounds.
|
||||
* @param value The bitmask of values.
|
||||
* @param names Span of names to index.
|
||||
* @param unknown_name The default value when the index does not exist.
|
||||
* @param invalid_index The invalid value to consider.
|
||||
* @param invalid_name The value to output when the invalid value is given.
|
||||
* @return The composed name.
|
||||
*/
|
||||
template <typename E>
|
||||
inline std::string ComposeName(E value, std::span<const std::string_view> names, std::string_view unknown_name, E invalid_index, std::string_view invalid_name)
|
||||
template <typename Tbitset>
|
||||
inline std::string ComposeName(Tbitset value, std::span<const std::string_view> names, std::string_view unknown_name)
|
||||
{
|
||||
if (value.None()) return "<none>";
|
||||
|
||||
std::string out;
|
||||
if (value == invalid_index) {
|
||||
out = invalid_name;
|
||||
} else if (value == 0) {
|
||||
out = "<none>";
|
||||
} else {
|
||||
for (size_t i = 0; i < std::size(names); i++) {
|
||||
if ((value & (1 << i)) == 0) continue;
|
||||
out += (!out.empty() ? "+" : "");
|
||||
out += names[i];
|
||||
value &= ~static_cast<E>(1 << i);
|
||||
}
|
||||
if (value != 0) {
|
||||
out += (!out.empty() ? "+" : "");
|
||||
out += unknown_name;
|
||||
}
|
||||
for (auto index : value) {
|
||||
if (!out.empty()) out += "+";
|
||||
out += to_underlying(index) < std::size(names) ? names[to_underlying(index)] : unknown_name;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@@ -93,31 +80,20 @@ inline std::string ComposeName(E value, std::span<const std::string_view> names,
|
||||
/**
|
||||
* Helper template function that returns compound bitfield name that is
|
||||
* concatenation of names of each set bit in the given value
|
||||
* or invalid_name when value == invalid_index
|
||||
* or unknown_name when index is out of bounds.
|
||||
* @param value The bitmask of values.
|
||||
* @param names Span of names to index.
|
||||
* @param unknown_name The default value when the index does not exist.
|
||||
* @param invalid_value The invalid value to consider.
|
||||
* @param invalid_name The value to output when the invalid value is given.
|
||||
* @return The composed name.
|
||||
*/
|
||||
template <typename E>
|
||||
inline std::string ComposeName(E value, std::span<const std::string_view> names, std::string_view unknown_name)
|
||||
template <typename Tbitset>
|
||||
inline std::string ComposeName(Tbitset value, std::span<const std::string_view> names, std::string_view unknown_name, Tbitset invalid_value, std::string_view invalid_name)
|
||||
{
|
||||
std::string out;
|
||||
if (value.base() == 0) {
|
||||
out = "<none>";
|
||||
} else {
|
||||
for (size_t i = 0; i < std::size(names); ++i) {
|
||||
if (!value.Test(static_cast<E::EnumType>(i))) continue;
|
||||
out += (!out.empty() ? "+" : "");
|
||||
out += names[i];
|
||||
value.Reset(static_cast<E::EnumType>(i));
|
||||
}
|
||||
if (value.base() != 0) {
|
||||
out += (!out.empty() ? "+" : "");
|
||||
out += unknown_name;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
if (value == invalid_value) return std::string{invalid_name};
|
||||
return ComposeName(value, names, unknown_name);
|
||||
}
|
||||
|
||||
std::string ValueStr(Trackdir td);
|
||||
|
||||
@@ -75,9 +75,9 @@ struct CFollowTrackT {
|
||||
this->veh_owner = o;
|
||||
/* don't worry, all is inlined so compiler should remove unnecessary initializations */
|
||||
this->old_tile = INVALID_TILE;
|
||||
this->old_td = INVALID_TRACKDIR;
|
||||
this->old_td = Trackdir::Invalid;
|
||||
this->new_tile = INVALID_TILE;
|
||||
this->new_td_bits = TRACKDIR_BIT_NONE;
|
||||
this->new_td_bits.Reset();
|
||||
this->exitdir = DiagDirection::Invalid;
|
||||
this->is_station = false;
|
||||
this->is_bridge = false;
|
||||
@@ -134,7 +134,7 @@ struct CFollowTrackT {
|
||||
if (this->IsTram() && this->GetSingleTramBit(this->old_tile) != DiagDirection::Invalid) return true; // Skip the check for single tram bits
|
||||
const RoadTramType sub_mode = (IsRoadTT() && this->veh != nullptr) ? (this->IsTram() ? RoadTramType::Tram : RoadTramType::Road) : RoadTramType::Invalid;
|
||||
const TrackdirBits old_tile_valid_dirs = GetTileTrackStatus(this->old_tile, TT(), sub_mode).trackdirs;
|
||||
return (old_tile_valid_dirs & TrackdirToTrackdirBits(this->old_td)) != TRACKDIR_BIT_NONE;
|
||||
return old_tile_valid_dirs.Any(TrackdirToTrackdirBits(this->old_td));
|
||||
}());
|
||||
|
||||
this->exitdir = TrackdirToExitdir(this->old_td);
|
||||
@@ -143,7 +143,7 @@ struct CFollowTrackT {
|
||||
this->FollowTileExit();
|
||||
if (!this->QueryNewTileTrackStatus()) return TryReverse();
|
||||
this->new_td_bits &= DiagdirReachesTrackdirs(this->exitdir);
|
||||
if (this->new_td_bits == TRACKDIR_BIT_NONE || !this->CanEnterNewTile()) {
|
||||
if (this->new_td_bits.None() || !this->CanEnterNewTile()) {
|
||||
/* In case we can't enter the next tile, but are
|
||||
* a normal road vehicle, then we can actually
|
||||
* try to reverse as this is the end of the road.
|
||||
@@ -160,13 +160,13 @@ struct CFollowTrackT {
|
||||
/* CanEnterNewTile already set a reason.
|
||||
* Do NOT overwrite it (important for example for EC_RAIL_ROAD_TYPE).
|
||||
* Only set a reason if CanEnterNewTile was not called */
|
||||
if (this->new_td_bits == TRACKDIR_BIT_NONE) this->err = EC_NO_WAY;
|
||||
if (this->new_td_bits.None()) this->err = EC_NO_WAY;
|
||||
|
||||
return false;
|
||||
}
|
||||
if ((!IsRailTT() && !Allow90degTurns()) || (IsRailTT() && Rail90DegTurnDisallowed(GetTileRailType(this->old_tile), GetTileRailType(this->new_tile), !Allow90degTurns()))) {
|
||||
this->new_td_bits &= ~TrackdirCrossesTrackdirs(this->old_td);
|
||||
if (this->new_td_bits == TRACKDIR_BIT_NONE) {
|
||||
this->new_td_bits.Reset(TrackdirCrossesTrackdirs(this->old_td));
|
||||
if (this->new_td_bits.None()) {
|
||||
this->err = EC_90DEG;
|
||||
return false;
|
||||
}
|
||||
@@ -183,7 +183,7 @@ struct CFollowTrackT {
|
||||
TileIndexDiff diff = TileOffsByDiagDir(this->exitdir);
|
||||
for (TileIndex tile = this->new_tile - diff * this->tiles_skipped; tile != this->new_tile; tile += diff) {
|
||||
if (HasStationReservation(tile)) {
|
||||
this->new_td_bits = TRACKDIR_BIT_NONE;
|
||||
this->new_td_bits.Reset();
|
||||
this->err = EC_RESERVED;
|
||||
return false;
|
||||
}
|
||||
@@ -192,12 +192,12 @@ struct CFollowTrackT {
|
||||
|
||||
TrackBits reserved = GetReservedTrackbits(this->new_tile);
|
||||
/* Mask already reserved trackdirs. */
|
||||
this->new_td_bits &= ~TrackBitsToTrackdirBits(reserved);
|
||||
this->new_td_bits.Reset(TrackBitsToTrackdirBits(reserved));
|
||||
/* Mask out all trackdirs that conflict with the reservation. */
|
||||
for (Track t : TrackdirBitsToTrackBits(this->new_td_bits)) {
|
||||
if (TracksOverlap(reserved | t)) this->new_td_bits &= ~TrackToTrackdirBits(t);
|
||||
if (TracksOverlap(reserved | t)) this->new_td_bits.Reset(TrackToTrackdirBits(t));
|
||||
}
|
||||
if (this->new_td_bits == TRACKDIR_BIT_NONE) {
|
||||
if (this->new_td_bits.None()) {
|
||||
this->err = EC_RESERVED;
|
||||
return false;
|
||||
}
|
||||
@@ -255,7 +255,7 @@ protected:
|
||||
} else {
|
||||
this->new_td_bits = GetTileTrackStatus(this->new_tile, TT(), RoadTramType::Invalid).trackdirs;
|
||||
}
|
||||
return (this->new_td_bits != TRACKDIR_BIT_NONE);
|
||||
return this->new_td_bits.Any();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -457,7 +457,7 @@ protected:
|
||||
/* set new trackdir bits to all reachable trackdirs */
|
||||
QueryNewTileTrackStatus();
|
||||
this->new_td_bits &= DiagdirReachesTrackdirs(this->exitdir);
|
||||
if (this->new_td_bits != TRACKDIR_BIT_NONE) {
|
||||
if (this->new_td_bits.Any()) {
|
||||
/* we have some trackdirs reachable after reversal */
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -63,18 +63,18 @@ inline TrackdirBits GetTrackdirBitsForRoad(TileIndex tile, RoadTramType rtt)
|
||||
{
|
||||
TrackdirBits bits = GetTileTrackStatus(tile, TRANSPORT_ROAD, rtt).trackdirs;
|
||||
|
||||
if (rtt == RoadTramType::Tram && bits == TRACKDIR_BIT_NONE) {
|
||||
if (rtt == RoadTramType::Tram && bits.None()) {
|
||||
if (IsNormalRoadTile(tile)) {
|
||||
RoadBits rb = GetRoadBits(tile, RoadTramType::Tram);
|
||||
switch (rb.base()) {
|
||||
case RoadBits{RoadBit::NE}.base():
|
||||
case RoadBits{RoadBit::SW}.base():
|
||||
bits = TRACKDIR_BIT_X_NE | TRACKDIR_BIT_X_SW;
|
||||
bits = {Trackdir::X_NE, Trackdir::X_SW};
|
||||
break;
|
||||
|
||||
case RoadBits{RoadBit::NW}.base():
|
||||
case RoadBits{RoadBit::SE}.base():
|
||||
bits = TRACKDIR_BIT_Y_NW | TRACKDIR_BIT_Y_SE;
|
||||
bits = {Trackdir::Y_NW, Trackdir::Y_SE};
|
||||
break;
|
||||
|
||||
default: break;
|
||||
|
||||
@@ -153,7 +153,7 @@ public:
|
||||
tiles_to_check.pop_back();
|
||||
|
||||
const TrackdirBits valid_dirs = TrackBitsToTrackdirBits(GetWaterTracks(tile));
|
||||
if (valid_dirs == TRACKDIR_BIT_NONE) continue;
|
||||
if (valid_dirs.None()) continue;
|
||||
|
||||
WaterRegionPatchLabel &tile_patch = (*this->data.tile_patch_labels)[this->GetLocalIndex(tile)];
|
||||
if (tile_patch != INVALID_WATER_REGION_PATCH) continue;
|
||||
@@ -162,7 +162,7 @@ public:
|
||||
highest_assigned_label = current_label;
|
||||
increase_label = true;
|
||||
|
||||
for (const Trackdir dir : SetTrackdirBitIterator(valid_dirs)) {
|
||||
for (Trackdir dir : valid_dirs) {
|
||||
/* By using a TrackFollower we "play by the same rules" as the actual ship pathfinder */
|
||||
CFollowTrackWater ft;
|
||||
if (ft.Follow(tile, dir)) {
|
||||
|
||||
@@ -43,7 +43,7 @@ bool YapfShipCheckReverse(const Ship *v, Trackdir *trackdir);
|
||||
* @param trackdirs available trackdirs on the new tile (to choose from)
|
||||
* @param path_found [out] Whether a path has been found (true) or has been guessed (false)
|
||||
* @param path_cache Cache of a previously chosen path.
|
||||
* @return the best trackdir for next turn or INVALID_TRACKDIR if the path could not be found
|
||||
* @return the best trackdir for next turn or Trackdir::Invalid if the path could not be found
|
||||
*/
|
||||
Trackdir YapfRoadVehicleChooseTrack(const RoadVehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs, bool &path_found, RoadVehPathCache &path_cache);
|
||||
|
||||
|
||||
@@ -235,9 +235,8 @@ public:
|
||||
*/
|
||||
inline void AddMultipleNodes(Node *parent, const TrackFollower &tf)
|
||||
{
|
||||
bool is_choice = (KillFirstBit(tf.new_td_bits) != TRACKDIR_BIT_NONE);
|
||||
for (TrackdirBits rtds = tf.new_td_bits; rtds != TRACKDIR_BIT_NONE; rtds = KillFirstBit(rtds)) {
|
||||
Trackdir td = (Trackdir)FindFirstBit(rtds);
|
||||
bool is_choice = tf.new_td_bits.Count() > 1;
|
||||
for (Trackdir td : tf.new_td_bits) {
|
||||
Node &n = Yapf().CreateNewNode();
|
||||
n.Set(parent, tf.new_tile, td, is_choice);
|
||||
Yapf().AddNewNode(n, tf);
|
||||
|
||||
@@ -37,9 +37,8 @@ public:
|
||||
*/
|
||||
void SetOrigin(TileIndex tile, TrackdirBits trackdirs)
|
||||
{
|
||||
bool is_choice = (KillFirstBit(trackdirs) != TRACKDIR_BIT_NONE);
|
||||
for (TrackdirBits tdb = trackdirs; tdb != TRACKDIR_BIT_NONE; tdb = KillFirstBit(tdb)) {
|
||||
Trackdir td = (Trackdir)FindFirstBit(tdb);
|
||||
bool is_choice = trackdirs.Count() > 1;
|
||||
for (Trackdir td : trackdirs) {
|
||||
Node &node = Yapf().CreateNewNode();
|
||||
node.Set(nullptr, tile, td, is_choice);
|
||||
Yapf().AddStartupNode(node);
|
||||
@@ -72,14 +71,14 @@ public:
|
||||
* @param reverse_penalty The penalty for reversing.
|
||||
*/
|
||||
void SetOrigin(TileIndex forward_tile, Trackdir forward_td, TileIndex reverse_tile = INVALID_TILE,
|
||||
Trackdir reverse_td = INVALID_TRACKDIR, int reverse_penalty = 0)
|
||||
Trackdir reverse_td = Trackdir::Invalid, int reverse_penalty = 0)
|
||||
{
|
||||
if (forward_tile != INVALID_TILE && forward_td != INVALID_TRACKDIR) {
|
||||
if (forward_tile != INVALID_TILE && forward_td != Trackdir::Invalid) {
|
||||
Node &node = Yapf().CreateNewNode();
|
||||
node.Set(nullptr, forward_tile, forward_td, false);
|
||||
Yapf().AddStartupNode(node);
|
||||
}
|
||||
if (reverse_tile != INVALID_TILE && reverse_td != INVALID_TRACKDIR) {
|
||||
if (reverse_tile != INVALID_TILE && reverse_td != Trackdir::Invalid) {
|
||||
Node &node = Yapf().CreateNewNode();
|
||||
node.Set(nullptr, reverse_tile, reverse_td, false);
|
||||
node.cost = reverse_penalty;
|
||||
|
||||
@@ -35,7 +35,7 @@ protected:
|
||||
TileType tile_type;
|
||||
RailType rail_type;
|
||||
|
||||
TILE() : tile(INVALID_TILE), td(INVALID_TRACKDIR), tile_type(TileType::Void), rail_type(INVALID_RAILTYPE) { }
|
||||
TILE() : tile(INVALID_TILE), td(Trackdir::Invalid), tile_type(TileType::Void), rail_type(INVALID_RAILTYPE) { }
|
||||
|
||||
TILE(TileIndex tile, Trackdir td) : tile(tile), td(td), tile_type(GetTileType(tile)), rail_type(GetTileRailType(tile)) { }
|
||||
};
|
||||
@@ -106,7 +106,7 @@ public:
|
||||
assert(IsValidTrackdir(td2));
|
||||
int cost = 0;
|
||||
if (TrackFollower::Allow90degTurns()
|
||||
&& HasTrackdir(TrackdirCrossesTrackdirs(td1), td2)) {
|
||||
&& TrackdirCrossesTrackdirs(td1).Test(td2)) {
|
||||
/* 90-deg curve penalty */
|
||||
cost += Yapf().PfGetSettings().rail_curve90_penalty;
|
||||
} else if (td2 != NextTrackdir(td1)) {
|
||||
@@ -295,7 +295,7 @@ public:
|
||||
{
|
||||
assert(!n.flags_u.flags_s.target_seen);
|
||||
assert(follower->new_tile == n.key.tile);
|
||||
assert((HasTrackdir(follower->new_td_bits, n.key.td)));
|
||||
assert(follower->new_td_bits.Test(n.key.td));
|
||||
|
||||
/* Does the node have some parent node? */
|
||||
bool has_parent = (n.parent != nullptr);
|
||||
@@ -437,14 +437,14 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
|
||||
t = ft.new_tile;
|
||||
if (t == cur.tile || --max_tiles == 0) {
|
||||
/* We looped back on ourself or found another loop, bail out. */
|
||||
td = INVALID_TRACKDIR;
|
||||
td = Trackdir::Invalid;
|
||||
break;
|
||||
}
|
||||
if (KillFirstBit(ft.new_td_bits) != TRACKDIR_BIT_NONE) {
|
||||
if (ft.new_td_bits.Count() > 1) {
|
||||
/* We encountered a junction; it's going to be too complex to
|
||||
* handle this perfectly, so just bail out. There is no simple
|
||||
* free path, so try the other possibilities. */
|
||||
td = INVALID_TRACKDIR;
|
||||
td = Trackdir::Invalid;
|
||||
break;
|
||||
}
|
||||
td = RemoveFirstTrackdir(&ft.new_td_bits);
|
||||
@@ -455,7 +455,7 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
|
||||
/* In the case this platform is (possibly) occupied we add penalty so the
|
||||
* other platforms of this waypoint are evaluated as well, i.e. we assume
|
||||
* that there is a red signal in the waypoint when it's occupied. */
|
||||
if (td == INVALID_TRACKDIR ||
|
||||
if (td == Trackdir::Invalid ||
|
||||
!IsSafeWaitingPosition(v, t, td, true, _settings_game.pf.forbid_90_deg) ||
|
||||
!IsWaitingPositionFree(v, t, td, _settings_game.pf.forbid_90_deg)) {
|
||||
extra_cost += Yapf().PfGetSettings().rail_lastred_penalty;
|
||||
@@ -521,14 +521,14 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
|
||||
}
|
||||
|
||||
/* Check if the next tile is not a choice. */
|
||||
if (KillFirstBit(follower_local.new_td_bits) != TRACKDIR_BIT_NONE) {
|
||||
if (follower_local.new_td_bits.Count() > 1) {
|
||||
/* More than one segment will follow. Close this one. */
|
||||
end_segment_reason.Set(EndSegmentReason::ChoiceFollows);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Gather the next tile/trackdir/tile_type/rail_type. */
|
||||
TILE next(follower_local.new_tile, (Trackdir)FindFirstBit(follower_local.new_td_bits));
|
||||
TILE next(follower_local.new_tile, follower_local.new_td_bits.GetNthSetBit(0).value());
|
||||
|
||||
if (TrackFollower::DoTrackMasking() && IsTileType(next.tile, TileType::Railway)) {
|
||||
if (HasSignalOnTrackdir(next.tile, next.td) && IsPbsSignal(GetSignalType(next.tile, TrackdirToTrack(next.td)))) {
|
||||
|
||||
@@ -179,7 +179,7 @@ public:
|
||||
return IsRailDepotTile(tile);
|
||||
}
|
||||
|
||||
return (tile == this->dest_tile) && HasTrackdir(this->dest_trackdirs, td);
|
||||
return (tile == this->dest_tile) && this->dest_trackdirs.Test(td);
|
||||
}
|
||||
|
||||
/** @copydoc CYapfBaseT::PfCalcEstimateFunc */
|
||||
|
||||
@@ -23,7 +23,7 @@ struct CYapfNodeKeyExitDir {
|
||||
{
|
||||
this->tile = tile;
|
||||
this->td = td;
|
||||
this->exitdir = (this->td == INVALID_TRACKDIR) ? DiagDirection::Invalid : TrackdirToExitdir(this->td);
|
||||
this->exitdir = (this->td == Trackdir::Invalid) ? DiagDirection::Invalid : TrackdirToExitdir(this->td);
|
||||
}
|
||||
|
||||
inline int CalcHash() const
|
||||
@@ -47,7 +47,7 @@ struct CYapfNodeKeyExitDir {
|
||||
struct CYapfNodeKeyTrackDir : public CYapfNodeKeyExitDir {
|
||||
inline int CalcHash() const
|
||||
{
|
||||
return this->td | (this->tile.base() << 4);
|
||||
return to_underlying(this->td) | (this->tile.base() << 4);
|
||||
}
|
||||
|
||||
inline bool operator==(const CYapfNodeKeyTrackDir &other) const
|
||||
|
||||
@@ -32,7 +32,7 @@ struct CYapfRailSegmentKey {
|
||||
|
||||
inline void Set(const CYapfNodeKeyTrackDir &node_key)
|
||||
{
|
||||
this->value = (node_key.tile.base() << 4) | node_key.td;
|
||||
this->value = (node_key.tile.base() << 4) | to_underlying(node_key.td);
|
||||
}
|
||||
|
||||
inline int32_t CalcHash() const
|
||||
@@ -47,7 +47,7 @@ struct CYapfRailSegmentKey {
|
||||
|
||||
inline Trackdir GetTrackdir() const
|
||||
{
|
||||
return (Trackdir)(this->value & 0x0F);
|
||||
return static_cast<Trackdir>(this->value & 0x0F);
|
||||
}
|
||||
|
||||
inline bool operator==(const CYapfRailSegmentKey &other) const
|
||||
@@ -68,10 +68,10 @@ struct CYapfRailSegment {
|
||||
|
||||
CYapfRailSegmentKey key;
|
||||
TileIndex last_tile = INVALID_TILE;
|
||||
Trackdir last_td = INVALID_TRACKDIR;
|
||||
Trackdir last_td = Trackdir::Invalid;
|
||||
int cost = -1;
|
||||
TileIndex last_signal_tile = INVALID_TILE;
|
||||
Trackdir last_signal_td = INVALID_TRACKDIR;
|
||||
Trackdir last_signal_td = Trackdir::Invalid;
|
||||
EndSegmentReasons end_segment_reason{};
|
||||
CYapfRailSegment *hash_next = nullptr;
|
||||
|
||||
@@ -186,7 +186,7 @@ struct CYapfRailNode : CYapfNodeT<CYapfNodeKeyTrackDir, CYapfRailNode> {
|
||||
|
||||
if (!follower.Follow(cur, cur_td)) break;
|
||||
cur = follower.new_tile;
|
||||
assert(KillFirstBit(follower.new_td_bits) == TRACKDIR_BIT_NONE);
|
||||
assert(follower.new_td_bits.Count() == 1);
|
||||
cur_td = FindFirstTrackdir(follower.new_td_bits);
|
||||
}
|
||||
|
||||
|
||||
@@ -459,15 +459,15 @@ public:
|
||||
|
||||
/* set origin and destination nodes */
|
||||
PBSTileInfo origin = FollowTrainReservation(v);
|
||||
Yapf().SetOrigin(origin.tile, origin.trackdir, INVALID_TILE, INVALID_TRACKDIR, 1);
|
||||
Yapf().SetOrigin(origin.tile, origin.trackdir, INVALID_TILE, Trackdir::Invalid, 1);
|
||||
Yapf().SetTreatFirstRedTwoWaySignalAsEOL(true);
|
||||
Yapf().SetDestination(v);
|
||||
|
||||
/* find the best path */
|
||||
path_found = Yapf().FindPath(v);
|
||||
|
||||
/* if path not found - return INVALID_TRACKDIR */
|
||||
Trackdir next_trackdir = INVALID_TRACKDIR;
|
||||
/* if path not found - return Trackdir::Invalid */
|
||||
Trackdir next_trackdir = Trackdir::Invalid;
|
||||
Node *node = Yapf().GetBestNode();
|
||||
if (node != nullptr) {
|
||||
/* reserve till end of path */
|
||||
@@ -485,7 +485,7 @@ public:
|
||||
|
||||
/* If the best PF node has no parent, then there is no (valid) best next trackdir to return.
|
||||
* This occurs when the PF is called while the train is already at its destination. */
|
||||
if (prev == nullptr) return INVALID_TRACKDIR;
|
||||
if (prev == nullptr) return Trackdir::Invalid;
|
||||
|
||||
/* return trackdir from the best origin node (one of start nodes) */
|
||||
Node &best_next_node = *prev;
|
||||
@@ -600,7 +600,7 @@ Track YapfTrainChooseTrack(const Train *v, TileIndex tile, DiagDirection enterdi
|
||||
? CYapfRailNo90::stChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target, dest)
|
||||
: CYapfRail::stChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target, dest);
|
||||
|
||||
return (td_ret != INVALID_TRACKDIR) ? TrackdirToTrack(td_ret) : FindFirstTrack(tracks);
|
||||
return (td_ret != Trackdir::Invalid) ? TrackdirToTrack(td_ret) : FindFirstTrack(tracks);
|
||||
}
|
||||
|
||||
bool YapfTrainCheckReverse(const Train *v)
|
||||
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
this->end_tile = end_tile;
|
||||
|
||||
Node &node = Yapf().CreateNewNode();
|
||||
node.Set(nullptr, start_tile, INVALID_TRACKDIR, false);
|
||||
node.Set(nullptr, start_tile, Trackdir::Invalid, false);
|
||||
Yapf().AddStartupNode(node);
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ public:
|
||||
const TileIndex t = old_node.GetTile() + TileOffsByDiagDir(d);
|
||||
if (IsValidTile(t) && RiverFlowsDown(old_node.GetTile(), t)) {
|
||||
Node &node = Yapf().CreateNewNode();
|
||||
node.Set(&old_node, t, INVALID_TRACKDIR, true);
|
||||
node.Set(&old_node, t, Trackdir::Invalid, true);
|
||||
Yapf().AddNewNode(node, RiverBuilderFollower{});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,9 +145,9 @@ public:
|
||||
if (!follower_local.Follow(tile, trackdir)) break;
|
||||
|
||||
/* if there are more trackdirs available & reachable, we are at the end of segment */
|
||||
if (KillFirstBit(follower_local.new_td_bits) != TRACKDIR_BIT_NONE) break;
|
||||
if (follower_local.new_td_bits.Count() > 1) break;
|
||||
|
||||
Trackdir new_td = (Trackdir)FindFirstBit(follower_local.new_td_bits);
|
||||
Trackdir new_td = follower_local.new_td_bits.GetNthSetBit(0).value();
|
||||
|
||||
/* stop if RV is on simple loop with no junctions */
|
||||
if (follower_local.new_tile == n.key.tile && new_td == n.key.td) return false;
|
||||
@@ -284,7 +284,7 @@ public:
|
||||
(this->non_artic || IsDriveThroughStopTile(tile));
|
||||
}
|
||||
|
||||
return tile == this->dest_tile && HasTrackdir(this->dest_trackdirs, td);
|
||||
return tile == this->dest_tile && this->dest_trackdirs.Test(td);
|
||||
}
|
||||
|
||||
/** @copydoc CYapfBaseT::PfCalcEstimateFunc */
|
||||
@@ -365,8 +365,8 @@ public:
|
||||
/* find the best path */
|
||||
path_found = Yapf().FindPath(v);
|
||||
|
||||
/* if path not found - return INVALID_TRACKDIR */
|
||||
Trackdir next_trackdir = INVALID_TRACKDIR;
|
||||
/* if path not found - return Trackdir::Invalid */
|
||||
Trackdir next_trackdir = Trackdir::Invalid;
|
||||
Node *node = Yapf().GetBestNode();
|
||||
if (node != nullptr) {
|
||||
uint steps = 0;
|
||||
@@ -459,7 +459,7 @@ Trackdir YapfRoadVehicleChooseTrack(const RoadVehicle *v, TileIndex tile, DiagDi
|
||||
{
|
||||
Trackdir td_ret = CYapfRoad::stChooseRoadTrack(v, tile, enterdir, path_found, path_cache);
|
||||
|
||||
return (td_ret != INVALID_TRACKDIR) ? td_ret : (Trackdir)FindFirstBit(trackdirs);
|
||||
return (td_ret != Trackdir::Invalid) ? td_ret : trackdirs.GetNthSetBit(0).value();
|
||||
}
|
||||
|
||||
FindDepotData YapfRoadVehicleFindNearestDepot(const RoadVehicle *v, int max_distance)
|
||||
@@ -467,7 +467,7 @@ FindDepotData YapfRoadVehicleFindNearestDepot(const RoadVehicle *v, int max_dist
|
||||
TileIndex tile = v->tile;
|
||||
Trackdir trackdir = v->GetVehicleTrackdir();
|
||||
|
||||
if (!HasTrackdir(GetTrackdirBitsForRoad(tile, GetRoadTramType(v->roadtype)), trackdir)) {
|
||||
if (!GetTrackdirBitsForRoad(tile, GetRoadTramType(v->roadtype)).Test(trackdir)) {
|
||||
return FindDepotData();
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ public:
|
||||
|
||||
if (this->dest_station != StationID::Invalid()) return IsDockingTile(tile) && IsShipDestinationTile(tile, this->dest_station);
|
||||
|
||||
return tile == this->dest_tile && ((this->dest_trackdirs & TrackdirToTrackdirBits(td)) != TRACKDIR_BIT_NONE);
|
||||
return tile == this->dest_tile && this->dest_trackdirs.Any(TrackdirToTrackdirBits(td));
|
||||
}
|
||||
|
||||
/** @copydoc CYapfBaseT::PfCalcEstimateFunc */
|
||||
@@ -159,9 +159,7 @@ public:
|
||||
*/
|
||||
static Trackdir GetRandomTrackdir(TrackdirBits trackdirs)
|
||||
{
|
||||
const int strip_amount = RandomRange(CountBits(trackdirs));
|
||||
for (int s = 0; s < strip_amount; ++s) RemoveFirstTrackdir(&trackdirs);
|
||||
return FindFirstTrackdir(trackdirs);
|
||||
return trackdirs.GetNthSetBit(RandomRange(trackdirs.Count())).value_or(Trackdir::Invalid);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -176,11 +174,11 @@ public:
|
||||
TrackFollower follower{v};
|
||||
if (follower.Follow(tile, dir)) {
|
||||
TrackdirBits dirs = follower.new_td_bits;
|
||||
const TrackdirBits dirs_without_90_degree = dirs & ~TrackdirCrossesTrackdirs(dir);
|
||||
if (dirs_without_90_degree != TRACKDIR_BIT_NONE) dirs = dirs_without_90_degree;
|
||||
const TrackdirBits dirs_without_90_degree = dirs.Reset(TrackdirCrossesTrackdirs(dir));
|
||||
if (dirs_without_90_degree.Any()) dirs = dirs_without_90_degree;
|
||||
return { follower.new_tile, GetRandomTrackdir(dirs) };
|
||||
}
|
||||
return { follower.new_tile, INVALID_TRACKDIR };
|
||||
return { follower.new_tile, Trackdir::Invalid };
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -188,18 +186,18 @@ public:
|
||||
* @param v The ship to create the path for.
|
||||
* @param[in,out] path_cache Cache of the path for the ship.
|
||||
* @param path_length The length of the random path to create.
|
||||
* @return The next track direction to take, or \c INVALID_TRACKDIR when there is no option.
|
||||
* @return The next track direction to take, or \c Trackdir::Invalid when there is no option.
|
||||
*/
|
||||
static Trackdir CreateRandomPath(const Ship *v, ShipPathCache &path_cache, int path_length)
|
||||
{
|
||||
std::pair<TileIndex, Trackdir> tile_dir = { v->tile, v->GetVehicleTrackdir()};
|
||||
for (int i = 0; i < path_length; ++i) {
|
||||
tile_dir = GetRandomFollowUpTileTrackdir(v, tile_dir.first, tile_dir.second);
|
||||
if (tile_dir.second == INVALID_TRACKDIR) break;
|
||||
if (tile_dir.second == Trackdir::Invalid) break;
|
||||
path_cache.push_back(tile_dir.second);
|
||||
}
|
||||
|
||||
if (path_cache.empty()) return INVALID_TRACKDIR;
|
||||
if (path_cache.empty()) return Trackdir::Invalid;
|
||||
|
||||
/* Reverse the path so we can take from the end. */
|
||||
std::reverse(std::begin(path_cache), std::end(path_cache));
|
||||
@@ -266,11 +264,11 @@ public:
|
||||
}
|
||||
assert(node->GetTile() == v->tile);
|
||||
|
||||
/* Return INVALID_TRACKDIR to trigger a ship reversal if that is the best option. */
|
||||
/* Return Trackdir::Invalid to trigger a ship reversal if that is the best option. */
|
||||
best_origin_dir = node->GetTrackdir();
|
||||
if ((TrackdirToTrackdirBits(best_origin_dir) & forward_dirs) == TRACKDIR_BIT_NONE) {
|
||||
if (TrackdirToTrackdirBits(best_origin_dir).Any(forward_dirs)) {
|
||||
path_cache.clear();
|
||||
return INVALID_TRACKDIR;
|
||||
return Trackdir::Invalid;
|
||||
}
|
||||
|
||||
/* A empty path means we are already at the destination. The pathfinder shouldn't have been called at all.
|
||||
@@ -301,7 +299,7 @@ public:
|
||||
{
|
||||
bool path_found = false;
|
||||
ShipPathCache dummy_cache;
|
||||
Trackdir best_origin_dir = INVALID_TRACKDIR;
|
||||
Trackdir best_origin_dir = Trackdir::Invalid;
|
||||
|
||||
if (trackdir == nullptr) {
|
||||
/* The normal case, typically called when ships leave a dock. */
|
||||
@@ -314,8 +312,8 @@ public:
|
||||
/* This gets called when a ship suddenly can't move forward, e.g. due to terraforming. */
|
||||
const DiagDirection entry = ReverseDiagDir(VehicleExitDir(v->direction, v->state));
|
||||
const TrackdirBits reverse_dirs = DiagdirReachesTrackdirs(entry) & GetTileTrackStatus(v->tile, TRANSPORT_WATER, RoadTramType::Invalid, entry).trackdirs;
|
||||
(void)ChooseShipTrack(v, v->tile, TRACKDIR_BIT_NONE, reverse_dirs, path_found, dummy_cache, best_origin_dir);
|
||||
*trackdir = path_found && best_origin_dir != INVALID_TRACKDIR ? best_origin_dir : GetRandomTrackdir(reverse_dirs);
|
||||
(void)ChooseShipTrack(v, v->tile, {}, reverse_dirs, path_found, dummy_cache, best_origin_dir);
|
||||
*trackdir = path_found && best_origin_dir != Trackdir::Invalid ? best_origin_dir : GetRandomTrackdir(reverse_dirs);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -342,7 +340,7 @@ public:
|
||||
assert(IsValidTrackdir(td1));
|
||||
assert(IsValidTrackdir(td2));
|
||||
|
||||
if (HasTrackdir(TrackdirCrossesTrackdirs(td1), td2)) {
|
||||
if (TrackdirCrossesTrackdirs(td1).Test(td2)) {
|
||||
/* 90-deg curve penalty. */
|
||||
return Yapf().PfGetSettings().ship_curve90_penalty;
|
||||
} else if (td2 != NextTrackdir(td1)) {
|
||||
@@ -362,11 +360,11 @@ public:
|
||||
{
|
||||
const bool odd_x = TileX(tile) & 1;
|
||||
const bool odd_y = TileY(tile) & 1;
|
||||
if (td == TRACKDIR_X_NE) return odd_y;
|
||||
if (td == TRACKDIR_X_SW) return !odd_y;
|
||||
if (td == TRACKDIR_Y_NW) return odd_x;
|
||||
if (td == TRACKDIR_Y_SE) return !odd_x;
|
||||
return (odd_x ^ odd_y) ^ HasBit(TRACKDIR_BIT_RIGHT_N | TRACKDIR_BIT_LEFT_S | TRACKDIR_BIT_UPPER_W | TRACKDIR_BIT_LOWER_E, td);
|
||||
if (td == Trackdir::X_NE) return odd_y;
|
||||
if (td == Trackdir::X_SW) return !odd_y;
|
||||
if (td == Trackdir::Y_NW) return odd_x;
|
||||
if (td == Trackdir::Y_SE) return !odd_x;
|
||||
return (odd_x ^ odd_y) ^ TrackdirBits{Trackdir::Right_N, Trackdir::Left_S, Trackdir::Upper_W, Trackdir::Lower_E}.Test(td);
|
||||
}
|
||||
|
||||
/** @copydoc CYapfBaseT::PfCalcCostFunc */
|
||||
@@ -437,10 +435,10 @@ struct CYapfShip : CYapfT<CYapfShip_TypesT<CYapfShip>> {
|
||||
|
||||
Track YapfShipChooseTrack(const Ship *v, TileIndex tile, bool &path_found, ShipPathCache &path_cache)
|
||||
{
|
||||
Trackdir best_origin_dir = INVALID_TRACKDIR;
|
||||
Trackdir best_origin_dir = Trackdir::Invalid;
|
||||
const TrackdirBits origin_dirs = TrackdirToTrackdirBits(v->GetVehicleTrackdir());
|
||||
const Trackdir td_ret = CYapfShip::ChooseShipTrack(v, tile, origin_dirs, TRACKDIR_BIT_NONE, path_found, path_cache, best_origin_dir);
|
||||
return (td_ret != INVALID_TRACKDIR) ? TrackdirToTrack(td_ret) : Track::Invalid;
|
||||
const Trackdir td_ret = CYapfShip::ChooseShipTrack(v, tile, origin_dirs, {}, path_found, path_cache, best_origin_dir);
|
||||
return (td_ret != Trackdir::Invalid) ? TrackdirToTrack(td_ret) : Track::Invalid;
|
||||
}
|
||||
|
||||
bool YapfShipCheckReverse(const Ship *v, Trackdir *trackdir)
|
||||
|
||||
+5
-5
@@ -213,7 +213,7 @@ static PBSTileInfo FollowReservation(Owner o, RailTypes rts, TileIndex tile, Tra
|
||||
TrackdirBits reserved = ft.new_td_bits & TrackBitsToTrackdirBits(GetReservedTrackbits(ft.new_tile));
|
||||
|
||||
/* No reservation --> path end found */
|
||||
if (reserved == TRACKDIR_BIT_NONE) {
|
||||
if (reserved.None()) {
|
||||
if (ft.is_station) {
|
||||
/* Check skipped station tiles as well, maybe our reservation ends inside the station. */
|
||||
TileIndexDiff diff = TileOffsByDiagDir(ft.exitdir);
|
||||
@@ -410,10 +410,10 @@ bool IsSafeWaitingPosition(const Train *v, TileIndex tile, Trackdir trackdir, bo
|
||||
|
||||
/* Check for reachable tracks. */
|
||||
ft.new_td_bits &= DiagdirReachesTrackdirs(ft.exitdir);
|
||||
if (Rail90DegTurnDisallowed(GetTileRailType(ft.old_tile), GetTileRailType(ft.new_tile), forbid_90deg)) ft.new_td_bits &= ~TrackdirCrossesTrackdirs(trackdir);
|
||||
if (ft.new_td_bits == TRACKDIR_BIT_NONE) return include_line_end;
|
||||
if (Rail90DegTurnDisallowed(GetTileRailType(ft.old_tile), GetTileRailType(ft.new_tile), forbid_90deg)) ft.new_td_bits.Reset(TrackdirCrossesTrackdirs(trackdir));
|
||||
if (ft.new_td_bits.None()) return include_line_end;
|
||||
|
||||
if (ft.new_td_bits != TRACKDIR_BIT_NONE && KillFirstBit(ft.new_td_bits) == TRACKDIR_BIT_NONE) {
|
||||
if (ft.new_td_bits.Count() == 1) {
|
||||
Trackdir td = FindFirstTrackdir(ft.new_td_bits);
|
||||
/* PBS signal on next trackdir? Safe position. */
|
||||
if (HasPbsSignalOnTrackdir(ft.new_tile, td)) return true;
|
||||
@@ -456,7 +456,7 @@ bool IsWaitingPositionFree(const Train *v, TileIndex tile, Trackdir trackdir, bo
|
||||
|
||||
/* Check for reachable tracks. */
|
||||
ft.new_td_bits &= DiagdirReachesTrackdirs(ft.exitdir);
|
||||
if (Rail90DegTurnDisallowed(GetTileRailType(ft.old_tile), GetTileRailType(ft.new_tile), forbid_90deg)) ft.new_td_bits &= ~TrackdirCrossesTrackdirs(trackdir);
|
||||
if (Rail90DegTurnDisallowed(GetTileRailType(ft.old_tile), GetTileRailType(ft.new_tile), forbid_90deg)) ft.new_td_bits.Reset(TrackdirCrossesTrackdirs(trackdir));
|
||||
|
||||
return !HasReservedTracks(ft.new_tile, TrackdirBitsToTrackBits(ft.new_td_bits));
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ struct PBSTileInfo {
|
||||
/**
|
||||
* Create an empty PBSTileInfo.
|
||||
*/
|
||||
PBSTileInfo() : tile(INVALID_TILE), trackdir(INVALID_TRACKDIR), okay(false) {}
|
||||
PBSTileInfo() : tile(INVALID_TILE), trackdir(Trackdir::Invalid), okay(false) {}
|
||||
|
||||
/**
|
||||
* Create a PBSTileInfo with given tile, track direction and safe waiting position information.
|
||||
|
||||
+11
-11
@@ -849,8 +849,8 @@ static CommandCost ValidateAutoDrag(Trackdir *trackdir, TileIndex start, TileInd
|
||||
(trdx >= 0 && dx < 0) ||
|
||||
(trdy <= 0 && dy > 0) ||
|
||||
(trdy >= 0 && dy < 0)) {
|
||||
if (!HasBit(*trackdir, 3)) { // first direction is invalid, try the other
|
||||
SetBit(*trackdir, 3); // reverse the direction
|
||||
if (!HasBit(to_underlying(*trackdir), 3)) { // first direction is invalid, try the other
|
||||
*trackdir = ReverseTrackdir(*trackdir); // reverse the direction
|
||||
trdx = -trdx;
|
||||
trdy = -trdy;
|
||||
} else { // other direction is invalid too, invalid drag
|
||||
@@ -1215,13 +1215,13 @@ static bool AdvanceSignalAutoFill(TileIndex &tile, Trackdir &trackdir, bool remo
|
||||
trackdirbits &= TrackdirReachesTrackdirs(trackdir);
|
||||
|
||||
/* No track bits, must stop */
|
||||
if (trackdirbits == TRACKDIR_BIT_NONE) return false;
|
||||
if (trackdirbits.None()) return false;
|
||||
|
||||
/* Get the first track dir */
|
||||
trackdir = RemoveFirstTrackdir(&trackdirbits);
|
||||
|
||||
/* Any left? It's a junction so we stop */
|
||||
if (trackdirbits != TRACKDIR_BIT_NONE) return false;
|
||||
if (trackdirbits.Any()) return false;
|
||||
|
||||
switch (GetTileType(tile)) {
|
||||
case TileType::Railway:
|
||||
@@ -1319,7 +1319,7 @@ static CommandCost CmdSignalTrackHelper(DoCommandFlags flags, TileIndex tile, Ti
|
||||
int last_used_ctr = -signal_density; // to force signal at first tile
|
||||
int last_suitable_ctr = 0;
|
||||
TileIndex last_suitable_tile = INVALID_TILE;
|
||||
Trackdir last_suitable_trackdir = INVALID_TRACKDIR;
|
||||
Trackdir last_suitable_trackdir = Trackdir::Invalid;
|
||||
CommandCost last_error = CMD_ERROR;
|
||||
bool had_success = false;
|
||||
auto build_signal = [&](TileIndex tile, Trackdir trackdir, bool test_only) {
|
||||
@@ -2781,13 +2781,13 @@ static TrackStatus GetTileTrackStatus_Rail(TileIndex tile, TransportType mode, [
|
||||
case TrackBits{Track::Left}.base(): tb = Track::Right; break;
|
||||
case TrackBits{Track::Right}.base(): tb = Track::Left; break;
|
||||
}
|
||||
return {TrackBitsToTrackdirBits(tb), TRACKDIR_BIT_NONE};
|
||||
return {TrackBitsToTrackdirBits(tb), {}};
|
||||
}
|
||||
|
||||
if (mode != TRANSPORT_RAIL) return {};
|
||||
|
||||
TrackBits trackbits{};
|
||||
TrackdirBits red_signals = TRACKDIR_BIT_NONE;
|
||||
TrackdirBits red_signals{};
|
||||
|
||||
switch (GetRailTileType(tile)) {
|
||||
default: NOT_REACHED();
|
||||
@@ -2810,10 +2810,10 @@ static TrackStatus GetTileTrackStatus_Rail(TileIndex tile, TransportType mode, [
|
||||
if (!IsOnewaySignal(tile, Track::Upper) || (a & SignalOnTrack(Track::Upper)) == 0) b |= ~a & SignalOnTrack(Track::Upper);
|
||||
if (!IsOnewaySignal(tile, Track::Lower) || (a & SignalOnTrack(Track::Lower)) == 0) b |= ~a & SignalOnTrack(Track::Lower);
|
||||
|
||||
if ((b & 0x8) == 0) red_signals |= (TRACKDIR_BIT_LEFT_N | TRACKDIR_BIT_X_NE | TRACKDIR_BIT_Y_SE | TRACKDIR_BIT_UPPER_E);
|
||||
if ((b & 0x4) == 0) red_signals |= (TRACKDIR_BIT_LEFT_S | TRACKDIR_BIT_X_SW | TRACKDIR_BIT_Y_NW | TRACKDIR_BIT_UPPER_W);
|
||||
if ((b & 0x2) == 0) red_signals |= (TRACKDIR_BIT_RIGHT_N | TRACKDIR_BIT_LOWER_E);
|
||||
if ((b & 0x1) == 0) red_signals |= (TRACKDIR_BIT_RIGHT_S | TRACKDIR_BIT_LOWER_W);
|
||||
if ((b & 0x8) == 0) red_signals.Set({Trackdir::Left_N, Trackdir::X_NE, Trackdir::Y_SE, Trackdir::Upper_E});
|
||||
if ((b & 0x4) == 0) red_signals.Set({Trackdir::Left_S, Trackdir::X_SW, Trackdir::Y_NW, Trackdir::Upper_W});
|
||||
if ((b & 0x2) == 0) red_signals.Set({Trackdir::Right_N, Trackdir::Lower_E});
|
||||
if ((b & 0x1) == 0) red_signals.Set({Trackdir::Right_S, Trackdir::Lower_W});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
+6
-6
@@ -2141,8 +2141,8 @@ static const TrackBits _road_trackbits[16] = {
|
||||
/** @copydoc GetTileTrackStatusProc */
|
||||
static TrackStatus GetTileTrackStatus_Road(TileIndex tile, TransportType mode, RoadTramType sub_mode, DiagDirection side)
|
||||
{
|
||||
TrackdirBits trackdirbits = TRACKDIR_BIT_NONE;
|
||||
TrackdirBits red_signals = TRACKDIR_BIT_NONE; // crossing barred
|
||||
TrackdirBits trackdirbits{};
|
||||
TrackdirBits red_signals{}; // crossing barred
|
||||
switch (mode) {
|
||||
case TRANSPORT_RAIL:
|
||||
if (IsLevelCrossing(tile)) trackdirbits = TrackBitsToTrackdirBits(GetCrossingRailTrack(tile));
|
||||
@@ -2178,9 +2178,9 @@ static TrackStatus GetTileTrackStatus_Road(TileIndex tile, TransportType mode, R
|
||||
if (IsLevelCrossingTile(t) && IsCrossingBarred(t)) red_signals &= mask;
|
||||
};
|
||||
/* Check for blocked adjacent crossing to south, keep only southbound red signal trackdirs, allow northbound traffic */
|
||||
mask_red_signal_bits_if_crossing_barred(TileAddByDiagDir(tile, AxisToDiagDir(axis)), TRACKDIR_BIT_X_SW | TRACKDIR_BIT_Y_SE);
|
||||
mask_red_signal_bits_if_crossing_barred(TileAddByDiagDir(tile, AxisToDiagDir(axis)), {Trackdir::X_SW, Trackdir::Y_SE});
|
||||
/* Check for blocked adjacent crossing to north, keep only northbound red signal trackdirs, allow southbound traffic */
|
||||
mask_red_signal_bits_if_crossing_barred(TileAddByDiagDir(tile, ReverseDiagDir(AxisToDiagDir(axis))), TRACKDIR_BIT_X_NE | TRACKDIR_BIT_Y_NW);
|
||||
mask_red_signal_bits_if_crossing_barred(TileAddByDiagDir(tile, ReverseDiagDir(AxisToDiagDir(axis))), {Trackdir::X_NE, Trackdir::Y_NW});
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2286,7 +2286,7 @@ static void GetTileDesc_Road(TileIndex tile, TileDesc &td)
|
||||
* vehicle should be travelling in in order to enter the depot.
|
||||
*/
|
||||
static constexpr DiagDirectionIndexArray<Trackdir> _roadveh_enter_depot_dir{
|
||||
TRACKDIR_X_SW, TRACKDIR_Y_NW, TRACKDIR_X_NE, TRACKDIR_Y_SE
|
||||
Trackdir::X_SW, Trackdir::Y_NW, Trackdir::X_NE, Trackdir::Y_SE
|
||||
};
|
||||
|
||||
/** @copydoc VehicleEnterTileProc */
|
||||
@@ -2298,7 +2298,7 @@ static VehicleEnterTileStates VehicleEnterTile_Road(Vehicle *v, TileIndex tile,
|
||||
|
||||
RoadVehicle *rv = RoadVehicle::From(v);
|
||||
if (rv->frame == RVC_DEPOT_STOP_FRAME &&
|
||||
_roadveh_enter_depot_dir[GetRoadDepotDirection(tile)] == rv->state) {
|
||||
_roadveh_enter_depot_dir[GetRoadDepotDirection(tile)] == static_cast<Trackdir>(rv->state)) {
|
||||
rv->state = RVSB_IN_DEPOT;
|
||||
rv->vehstatus.Set(VehState::Hidden);
|
||||
rv->direction = ReverseDir(rv->direction);
|
||||
|
||||
+4
-4
@@ -47,9 +47,9 @@ enum RoadVehicleStates : uint8_t {
|
||||
|
||||
/* Bit sets of the above specified bits */
|
||||
RVSB_IN_ROAD_STOP = 1 << RVS_IN_ROAD_STOP, ///< The vehicle is in a road stop
|
||||
RVSB_IN_ROAD_STOP_END = RVSB_IN_ROAD_STOP + TRACKDIR_END,
|
||||
RVSB_IN_ROAD_STOP_END = RVSB_IN_ROAD_STOP + to_underlying(Trackdir::End),
|
||||
RVSB_IN_DT_ROAD_STOP = 1 << RVS_IN_DT_ROAD_STOP, ///< The vehicle is in a drive-through road stop
|
||||
RVSB_IN_DT_ROAD_STOP_END = RVSB_IN_DT_ROAD_STOP + TRACKDIR_END,
|
||||
RVSB_IN_DT_ROAD_STOP_END = RVSB_IN_DT_ROAD_STOP + to_underlying(Trackdir::End),
|
||||
|
||||
RVSB_DRIVE_SIDE = 1 << RVS_DRIVE_SIDE, ///< The vehicle is at the opposite side of the road
|
||||
|
||||
@@ -90,7 +90,7 @@ void GetRoadVehSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs
|
||||
|
||||
/** Element of the RoadVehPathCache. */
|
||||
struct RoadVehPathElement {
|
||||
Trackdir trackdir = INVALID_TRACKDIR; ///< Trackdir for this element.
|
||||
Trackdir trackdir = Trackdir::Invalid; ///< Trackdir for this element.
|
||||
TileIndex tile = INVALID_TILE; ///< Tile for this element.
|
||||
|
||||
constexpr RoadVehPathElement() {}
|
||||
@@ -307,7 +307,7 @@ protected: // These functions should not be called outside acceleration code.
|
||||
/* Check if this vehicle is in the same direction as the road under.
|
||||
* We already know it has either GVF_GOINGUP_BIT or GVF_GOINGDOWN_BIT set. */
|
||||
|
||||
if (rv->state <= RVSB_TRACKDIR_MASK && IsReversingRoadTrackdir((Trackdir)rv->state)) {
|
||||
if (rv->state <= RVSB_TRACKDIR_MASK && IsReversingRoadTrackdir(static_cast<Trackdir>(rv->state))) {
|
||||
/* If the first vehicle is reversing, this vehicle may be reversing too
|
||||
* (especially if this is the first, and maybe the only, vehicle).*/
|
||||
return true;
|
||||
|
||||
+46
-55
@@ -74,7 +74,7 @@ bool IsValidImageIndex<VehicleType::Road>(uint8_t image_index)
|
||||
|
||||
/** Track direction to use when reversing for each diagonal direction. */
|
||||
static constexpr DiagDirectionIndexArray<Trackdir> _road_reverse_table{
|
||||
TRACKDIR_RVREV_NE, TRACKDIR_RVREV_SE, TRACKDIR_RVREV_SW, TRACKDIR_RVREV_NW
|
||||
Trackdir::RvRev_NE, Trackdir::RvRev_SE, Trackdir::RvRev_SW, Trackdir::RvRev_NW
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -470,7 +470,7 @@ inline int RoadVehicle::GetCurrentMaxSpeed() const
|
||||
/* Limit speed to 50% while reversing, 75% in curves. */
|
||||
for (const RoadVehicle *u = this; u != nullptr; u = u->Next()) {
|
||||
if (_settings_game.vehicle.roadveh_acceleration_model == AM_REALISTIC) {
|
||||
if (this->state <= RVSB_TRACKDIR_MASK && IsReversingRoadTrackdir((Trackdir)this->state)) {
|
||||
if (this->state <= RVSB_TRACKDIR_MASK && IsReversingRoadTrackdir(static_cast<Trackdir>(this->state))) {
|
||||
max_speed = this->gcache.cached_max_track_speed / 2;
|
||||
break;
|
||||
} else if (!IsDiagonalDirection(u->direction)) {
|
||||
@@ -796,7 +796,7 @@ static bool CheckRoadBlockedForOvertaking(OvertakeData *od)
|
||||
TrackBits trackbits = TrackdirBitsToTrackBits(ts.trackdirs);
|
||||
|
||||
/* Track does not continue along overtaking direction || track has junction || levelcrossing is barred */
|
||||
if (!HasBit(ts.trackdirs, od->trackdir) || trackbits.Any({Track::Upper, Track::Lower, Track::Left, Track::Right}) || (ts.signals != TRACKDIR_BIT_NONE)) return true;
|
||||
if (!ts.trackdirs.Test(od->trackdir) || trackbits.Any({Track::Upper, Track::Lower, Track::Left, Track::Right}) || ts.signals.Any()) return true;
|
||||
|
||||
/* Are there more vehicles on the tile except the two vehicles involved in overtaking */
|
||||
return HasVehicleOnTile(od->tile, [&](const Vehicle *v) {
|
||||
@@ -824,7 +824,7 @@ static void RoadVehCheckOvertake(RoadVehicle *v, RoadVehicle *u)
|
||||
if (v->direction != u->direction || !IsDiagonalDirection(v->direction)) return;
|
||||
|
||||
/* Check if vehicle is in a road stop, depot, tunnel or bridge or not on a straight road */
|
||||
if (v->state >= RVSB_IN_ROAD_STOP || !IsStraightRoadTrackdir((Trackdir)(v->state & RVSB_TRACKDIR_MASK))) return;
|
||||
if (v->state >= RVSB_IN_ROAD_STOP || !IsStraightRoadTrackdir(static_cast<Trackdir>(v->state & RVSB_TRACKDIR_MASK))) return;
|
||||
|
||||
/* Can't overtake a vehicle that is moving faster than us. If the vehicle in front is
|
||||
* accelerating, take the maximum speed for the comparison, else the current speed.
|
||||
@@ -868,18 +868,9 @@ static void RoadZPosAffectSpeed(RoadVehicle *v, int old_z)
|
||||
}
|
||||
}
|
||||
|
||||
static int PickRandomBit(uint bits)
|
||||
{
|
||||
uint i;
|
||||
uint num = RandomRange(CountBits(bits));
|
||||
|
||||
for (i = 0; !(bits & 1) || (int)--num >= 0; bits >>= 1, i++) {}
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns direction to for a road vehicle to take or
|
||||
* INVALID_TRACKDIR if the direction is currently blocked
|
||||
* Trackdir::Invalid if the direction is currently blocked
|
||||
* @param v the Vehicle to do the pathfinding for
|
||||
* @param tile the where to start the pathfinding
|
||||
* @param enterdir the direction the vehicle enters the tile from
|
||||
@@ -891,36 +882,36 @@ static Trackdir RoadFindPathToDest(RoadVehicle *v, TileIndex tile, DiagDirection
|
||||
|
||||
TrackStatus ts = GetTileTrackStatus(tile, TRANSPORT_ROAD, GetRoadTramType(v->roadtype));
|
||||
|
||||
/* Replaces the given trackdir with INVALID_TRACKDIR when there is red signal for that trackdir. */
|
||||
/* Replaces the given trackdir with Trackdir::Invalid when there is red signal for that trackdir. */
|
||||
auto FilterRedSignal = [&ts](Trackdir trackdir) {
|
||||
if (HasBit(ts.signals, trackdir)) return INVALID_TRACKDIR;
|
||||
if (ts.signals.Test(trackdir)) return Trackdir::Invalid;
|
||||
return trackdir;
|
||||
};
|
||||
|
||||
if (IsTileType(tile, TileType::Road)) {
|
||||
if (IsRoadDepot(tile) && (!IsTileOwner(tile, v->owner) || GetRoadDepotDirection(tile) == enterdir)) {
|
||||
/* Road depot owned by another company or with the wrong orientation */
|
||||
ts.trackdirs = TRACKDIR_BIT_NONE;
|
||||
ts.trackdirs.Reset();
|
||||
}
|
||||
} else if (IsTileType(tile, TileType::Station) && IsBayRoadStopTile(tile)) {
|
||||
/* Standard road stop (drive-through stops are treated as normal road) */
|
||||
|
||||
if (!IsTileOwner(tile, v->owner) || GetBayRoadStopDir(tile) == enterdir || v->HasArticulatedPart()) {
|
||||
/* different station owner or wrong orientation or the vehicle has articulated parts */
|
||||
ts.trackdirs = TRACKDIR_BIT_NONE;
|
||||
ts.trackdirs.Reset();
|
||||
} else {
|
||||
/* Our station */
|
||||
RoadStopType rstype = v->IsBus() ? RoadStopType::Bus : RoadStopType::Truck;
|
||||
|
||||
if (GetRoadStopType(tile) != rstype) {
|
||||
/* Wrong station type */
|
||||
ts.trackdirs = TRACKDIR_BIT_NONE;
|
||||
ts.trackdirs.Reset();
|
||||
} else {
|
||||
/* Proper station type, check if there is free loading bay */
|
||||
if (!_settings_game.pf.roadveh_queue && IsBayRoadStopTile(tile) &&
|
||||
!RoadStop::GetByTile(tile, rstype)->HasFreeBay()) {
|
||||
/* Station is full and RV queuing is off */
|
||||
ts.trackdirs = TRACKDIR_BIT_NONE;
|
||||
ts.trackdirs.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -932,7 +923,7 @@ static Trackdir RoadFindPathToDest(RoadVehicle *v, TileIndex tile, DiagDirection
|
||||
|
||||
/* Remove tracks unreachable from the enter dir */
|
||||
ts.trackdirs &= DiagdirReachesTrackdirs(enterdir);
|
||||
if (ts.trackdirs == TRACKDIR_BIT_NONE) {
|
||||
if (ts.trackdirs.None()) {
|
||||
/* If vehicle expected a path, it no longer exists, so invalidate it. */
|
||||
if (!v->path.empty()) v->path.clear();
|
||||
/* No reachable tracks, so we'll reverse */
|
||||
@@ -959,16 +950,16 @@ static Trackdir RoadFindPathToDest(RoadVehicle *v, TileIndex tile, DiagDirection
|
||||
|
||||
if (v->dest_tile == INVALID_TILE) {
|
||||
/* We've got no destination, pick a random track */
|
||||
return FilterRedSignal(static_cast<Trackdir>(PickRandomBit(ts.trackdirs)));
|
||||
return FilterRedSignal(ts.trackdirs.GetNthSetBit(RandomRange(ts.trackdirs.Count())).value());
|
||||
}
|
||||
|
||||
/* Only one track to choose between? */
|
||||
if (KillFirstBit(ts.trackdirs) == TRACKDIR_BIT_NONE) {
|
||||
if (ts.trackdirs.Count() == 1) {
|
||||
if (!v->path.empty() && v->path.back().tile == tile) {
|
||||
/* Vehicle expected a choice here, invalidate its path. */
|
||||
v->path.clear();
|
||||
}
|
||||
return FilterRedSignal(static_cast<Trackdir>(FindFirstBit(ts.trackdirs)));
|
||||
return FilterRedSignal(ts.trackdirs.GetNthSetBit(0).value());
|
||||
}
|
||||
|
||||
/* Attempt to follow cached path. */
|
||||
@@ -979,7 +970,7 @@ static Trackdir RoadFindPathToDest(RoadVehicle *v, TileIndex tile, DiagDirection
|
||||
} else {
|
||||
Trackdir trackdir = v->path.back().trackdir;
|
||||
|
||||
if (HasBit(ts.trackdirs, trackdir)) {
|
||||
if (ts.trackdirs.Test(trackdir)) {
|
||||
v->path.pop_back();
|
||||
return FilterRedSignal(trackdir);
|
||||
}
|
||||
@@ -1013,7 +1004,7 @@ bool RoadVehLeaveDepot(RoadVehicle *v, bool first)
|
||||
v->direction = DiagDirToDir(dir);
|
||||
|
||||
Trackdir tdir = DiagDirToDiagTrackdir(dir);
|
||||
const RoadDriveEntry *rdp = _road_drive_data[GetRoadTramType(v->roadtype)][(to_underlying(_settings_game.vehicle.road_side) << RVS_DRIVE_SIDE) + tdir];
|
||||
const RoadDriveEntry *rdp = _road_drive_data[GetRoadTramType(v->roadtype)][(to_underlying(_settings_game.vehicle.road_side) << RVS_DRIVE_SIDE) + to_underlying(tdir)];
|
||||
|
||||
int x = TileX(v->tile) * TILE_SIZE + (rdp[RVC_DEPOT_START_FRAME].x & 0xF);
|
||||
int y = TileY(v->tile) * TILE_SIZE + (rdp[RVC_DEPOT_START_FRAME].y & 0xF);
|
||||
@@ -1037,7 +1028,7 @@ bool RoadVehLeaveDepot(RoadVehicle *v, bool first)
|
||||
}
|
||||
|
||||
v->vehstatus.Reset(VehState::Hidden);
|
||||
v->state = tdir;
|
||||
v->state = to_underlying(tdir);
|
||||
v->frame = RVC_DEPOT_START_FRAME;
|
||||
|
||||
v->x_pos = x;
|
||||
@@ -1070,10 +1061,10 @@ static Trackdir FollowPreviousRoadVehicle(const RoadVehicle *v, const RoadVehicl
|
||||
diag_dir = ReverseDiagDir(GetRoadDepotDirection(tile));
|
||||
}
|
||||
|
||||
if (diag_dir == DiagDirection::Invalid) return INVALID_TRACKDIR;
|
||||
if (diag_dir == DiagDirection::Invalid) return Trackdir::Invalid;
|
||||
dir = DiagDirToDiagTrackdir(diag_dir);
|
||||
} else {
|
||||
if (already_reversed && (prev->tile != tile || (prev_state < TRACKDIR_END && IsReversingRoadTrackdir(static_cast<Trackdir>(prev_state))))) {
|
||||
if (already_reversed && (prev->tile != tile || (static_cast<Trackdir>(prev_state) < Trackdir::End && IsReversingRoadTrackdir(static_cast<Trackdir>(prev_state))))) {
|
||||
/*
|
||||
* The vehicle has reversed, but did not go straight back.
|
||||
* It immediately turn onto another tile. This means that
|
||||
@@ -1093,18 +1084,18 @@ static Trackdir FollowPreviousRoadVehicle(const RoadVehicle *v, const RoadVehicl
|
||||
if (prev->tile != tile) {
|
||||
north = prev->tile < tile;
|
||||
} else {
|
||||
north = (prev_state == TRACKDIR_RVREV_NW || prev_state == TRACKDIR_RVREV_NE);
|
||||
north = static_cast<Trackdir>(prev_state) == Trackdir::RvRev_NW || static_cast<Trackdir>(prev_state) == Trackdir::RvRev_NE;
|
||||
}
|
||||
static const DiagDirectionIndexArray<Trackdir> reversed_turn_lookup[2] = {
|
||||
{ TRACKDIR_UPPER_W, TRACKDIR_RIGHT_N, TRACKDIR_LEFT_N, TRACKDIR_UPPER_E },
|
||||
{ TRACKDIR_RIGHT_S, TRACKDIR_LOWER_W, TRACKDIR_LOWER_E, TRACKDIR_LEFT_S }};
|
||||
{ Trackdir::Upper_W, Trackdir::Right_N, Trackdir::Left_N, Trackdir::Upper_E },
|
||||
{ Trackdir::Right_S, Trackdir::Lower_W, Trackdir::Lower_E, Trackdir::Left_S }};
|
||||
dir = reversed_turn_lookup[north ? 0 : 1][ReverseDiagDir(entry_dir)];
|
||||
} else if (HasBit(prev_state, RVS_IN_DT_ROAD_STOP)) {
|
||||
dir = (Trackdir)(prev_state & RVSB_ROAD_STOP_TRACKDIR_MASK);
|
||||
} else if (prev_state < TRACKDIR_END) {
|
||||
dir = (Trackdir)prev_state;
|
||||
dir = static_cast<Trackdir>(prev_state & RVSB_ROAD_STOP_TRACKDIR_MASK);
|
||||
} else if (static_cast<Trackdir>(prev_state) < Trackdir::End) {
|
||||
dir = static_cast<Trackdir>(prev_state);
|
||||
} else {
|
||||
return INVALID_TRACKDIR;
|
||||
return Trackdir::Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1119,10 +1110,10 @@ static Trackdir FollowPreviousRoadVehicle(const RoadVehicle *v, const RoadVehicl
|
||||
ROAD_X,
|
||||
ROAD_Y,
|
||||
};
|
||||
RoadBits required = required_roadbits[dir & 0x07];
|
||||
RoadBits required = required_roadbits[to_underlying(dir) & 0x07];
|
||||
|
||||
if (!required.Any(GetAnyRoadBits(tile, GetRoadTramType(v->roadtype), true))) {
|
||||
dir = INVALID_TRACKDIR;
|
||||
dir = Trackdir::Invalid;
|
||||
}
|
||||
|
||||
return dir;
|
||||
@@ -1153,7 +1144,7 @@ bool IndividualRoadVehicleController(RoadVehicle *v, const RoadVehicle *prev)
|
||||
/* If overtaking just aborts at a random moment, we can have a out-of-bound problem,
|
||||
* if the vehicle started a corner. To protect that, only allow an abort of
|
||||
* overtake if we are on straight roads */
|
||||
if (v->state < RVSB_IN_ROAD_STOP && IsStraightRoadTrackdir((Trackdir)v->state)) {
|
||||
if (v->state < RVSB_IN_ROAD_STOP && IsStraightRoadTrackdir(static_cast<Trackdir>(v->state))) {
|
||||
v->overtaking = 0;
|
||||
}
|
||||
}
|
||||
@@ -1215,7 +1206,7 @@ bool IndividualRoadVehicleController(RoadVehicle *v, const RoadVehicle *prev)
|
||||
dir = FollowPreviousRoadVehicle(v, prev, tile, diagdir, false);
|
||||
}
|
||||
|
||||
if (dir == INVALID_TRACKDIR) {
|
||||
if (dir == Trackdir::Invalid) {
|
||||
if (!v->IsFrontEngine()) FatalError("Disconnecting road vehicle.");
|
||||
v->cur_speed = 0;
|
||||
return false;
|
||||
@@ -1234,10 +1225,10 @@ again:
|
||||
RoadBit needed;
|
||||
switch (dir) {
|
||||
default: NOT_REACHED();
|
||||
case TRACKDIR_RVREV_NE: needed = RoadBit::SW; break;
|
||||
case TRACKDIR_RVREV_SE: needed = RoadBit::NW; break;
|
||||
case TRACKDIR_RVREV_SW: needed = RoadBit::NE; break;
|
||||
case TRACKDIR_RVREV_NW: needed = RoadBit::SE; break;
|
||||
case Trackdir::RvRev_NE: needed = RoadBit::SW; break;
|
||||
case Trackdir::RvRev_SE: needed = RoadBit::NW; break;
|
||||
case Trackdir::RvRev_SW: needed = RoadBit::NE; break;
|
||||
case Trackdir::RvRev_NW: needed = RoadBit::SE; break;
|
||||
}
|
||||
if ((v->Previous() != nullptr && v->Previous()->tile == tile) ||
|
||||
(v->IsFrontEngine() && IsNormalRoadTile(tile) && !HasRoadWorks(tile) &&
|
||||
@@ -1281,7 +1272,7 @@ again:
|
||||
}
|
||||
|
||||
/* Get position data for first frame on the new tile */
|
||||
const RoadDriveEntry *rdp = _road_drive_data[GetRoadTramType(v->roadtype)][(dir + (to_underlying(_settings_game.vehicle.road_side) << RVS_DRIVE_SIDE)) ^ v->overtaking];
|
||||
const RoadDriveEntry *rdp = _road_drive_data[GetRoadTramType(v->roadtype)][(to_underlying(dir) + (to_underlying(_settings_game.vehicle.road_side) << RVS_DRIVE_SIDE)) ^ v->overtaking];
|
||||
|
||||
int x = TileX(tile) * TILE_SIZE + rdp[start_frame].x;
|
||||
int y = TileY(tile) * TILE_SIZE + rdp[start_frame].y;
|
||||
@@ -1327,7 +1318,7 @@ again:
|
||||
RoadStop::IsDriveThroughRoadStopContinuation(v->tile, tile) &&
|
||||
v->tile != tile) {
|
||||
/* So, keep 'our' state */
|
||||
dir = (Trackdir)v->state;
|
||||
dir = static_cast<Trackdir>(v->state);
|
||||
} else if (IsStationRoadStop(v->tile)) {
|
||||
/* We're not continuing our drive through road stop, so leave. */
|
||||
RoadStop::GetByTile(v->tile, GetRoadStopType(v->tile))->Leave(v);
|
||||
@@ -1377,10 +1368,10 @@ again:
|
||||
turn_around_start_frame = RVC_START_FRAME_AFTER_LONG_TRAM;
|
||||
switch (static_cast<DiagDirection>(rd.x & 0x3)) {
|
||||
default: NOT_REACHED();
|
||||
case DiagDirection::NW: dir = TRACKDIR_RVREV_SE; break;
|
||||
case DiagDirection::NE: dir = TRACKDIR_RVREV_SW; break;
|
||||
case DiagDirection::SE: dir = TRACKDIR_RVREV_NW; break;
|
||||
case DiagDirection::SW: dir = TRACKDIR_RVREV_NE; break;
|
||||
case DiagDirection::NW: dir = Trackdir::RvRev_SE; break;
|
||||
case DiagDirection::NE: dir = Trackdir::RvRev_SW; break;
|
||||
case DiagDirection::SE: dir = Trackdir::RvRev_NW; break;
|
||||
case DiagDirection::SW: dir = Trackdir::RvRev_NE; break;
|
||||
}
|
||||
} else {
|
||||
if (v->IsFrontEngine()) {
|
||||
@@ -1391,12 +1382,12 @@ again:
|
||||
}
|
||||
}
|
||||
|
||||
if (dir == INVALID_TRACKDIR) {
|
||||
if (dir == Trackdir::Invalid) {
|
||||
v->cur_speed = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
const RoadDriveEntry *rdp = _road_drive_data[GetRoadTramType(v->roadtype)][(to_underlying(_settings_game.vehicle.road_side) << RVS_DRIVE_SIDE) + dir];
|
||||
const RoadDriveEntry *rdp = _road_drive_data[GetRoadTramType(v->roadtype)][(to_underlying(_settings_game.vehicle.road_side) << RVS_DRIVE_SIDE) + to_underlying(dir)];
|
||||
|
||||
int x = TileX(v->tile) * TILE_SIZE + rdp[turn_around_start_frame].x;
|
||||
int y = TileY(v->tile) * TILE_SIZE + rdp[turn_around_start_frame].y;
|
||||
@@ -1418,7 +1409,7 @@ again:
|
||||
return false;
|
||||
}
|
||||
|
||||
v->state = dir;
|
||||
v->state = to_underlying(dir);
|
||||
v->frame = turn_around_start_frame;
|
||||
|
||||
if (new_dir != v->direction) {
|
||||
@@ -1750,7 +1741,7 @@ void RoadVehicle::OnNewEconomyDay()
|
||||
|
||||
Trackdir RoadVehicle::GetVehicleTrackdir() const
|
||||
{
|
||||
if (this->vehstatus.Test(VehState::Crashed)) return INVALID_TRACKDIR;
|
||||
if (this->vehstatus.Test(VehState::Crashed)) return Trackdir::Invalid;
|
||||
|
||||
if (this->IsInDepot()) {
|
||||
/* We'll assume the road vehicle is facing outwards */
|
||||
@@ -1767,7 +1758,7 @@ Trackdir RoadVehicle::GetVehicleTrackdir() const
|
||||
|
||||
/* If vehicle's state is a valid track direction (vehicle is not turning around) return it,
|
||||
* otherwise transform it into a valid track direction */
|
||||
return (Trackdir)((IsReversingRoadTrackdir((Trackdir)this->state)) ? (this->state - 6) : this->state);
|
||||
return static_cast<Trackdir>(IsReversingRoadTrackdir(static_cast<Trackdir>(this->state)) ? (this->state - 6) : this->state);
|
||||
}
|
||||
|
||||
uint16_t RoadVehicle::GetMaxWeight() const
|
||||
|
||||
@@ -438,8 +438,8 @@ static void FixOwnerOfRailTrack(Tile t)
|
||||
/* try to find any connected rail */
|
||||
for (DiagDirection dd = DiagDirection::Begin; dd < DiagDirection::End; dd++) {
|
||||
TileIndex tt{t + TileOffsByDiagDir(dd)};
|
||||
if (GetTileTrackStatus(t, TRANSPORT_RAIL, RoadTramType::Invalid, dd).trackdirs != TRACKDIR_BIT_NONE &&
|
||||
GetTileTrackStatus(tt, TRANSPORT_RAIL, RoadTramType::Invalid, ReverseDiagDir(dd)).trackdirs != TRACKDIR_BIT_NONE &&
|
||||
if (GetTileTrackStatus(t, TRANSPORT_RAIL, RoadTramType::Invalid, dd).trackdirs.Any() &&
|
||||
GetTileTrackStatus(tt, TRANSPORT_RAIL, RoadTramType::Invalid, ReverseDiagDir(dd)).trackdirs.Any() &&
|
||||
Company::IsValidID(GetTileOwner(tt))) {
|
||||
SetTileOwner(t, GetTileOwner(tt));
|
||||
return;
|
||||
@@ -2681,7 +2681,7 @@ bool AfterLoadGame()
|
||||
|
||||
switch (v->type) {
|
||||
case VehicleType::Train: Train::From(v)->track = DiagDirToDiagTrack(vdir); break;
|
||||
case VehicleType::Road: RoadVehicle::From(v)->state = DiagDirToDiagTrackdir(vdir); RoadVehicle::From(v)->frame = frame; break;
|
||||
case VehicleType::Road: RoadVehicle::From(v)->state = to_underlying(DiagDirToDiagTrackdir(vdir)); RoadVehicle::From(v)->frame = frame; break;
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -402,11 +402,11 @@ static const int NUM_TRACK_DIRECTIONS = 3; ///< The number of directions you can
|
||||
* 2 it added.
|
||||
*/
|
||||
static const ScriptRailSignalData _possible_trackdirs[5][NUM_TRACK_DIRECTIONS] = {
|
||||
{{Track::Upper, TRACKDIR_UPPER_E, 0}, {Track::Y, TRACKDIR_Y_SE, 0}, {Track::Left, TRACKDIR_LEFT_S, 1}},
|
||||
{{Track::Right, TRACKDIR_RIGHT_S, 1}, {Track::X, TRACKDIR_X_SW, 1}, {Track::Upper, TRACKDIR_UPPER_W, 1}},
|
||||
{{Track::Invalid, INVALID_TRACKDIR, 0}, {Track::Invalid, INVALID_TRACKDIR, 0}, {Track::Invalid, INVALID_TRACKDIR, 0}},
|
||||
{{Track::Lower, TRACKDIR_LOWER_E, 0}, {Track::X, TRACKDIR_X_NE, 0}, {Track::Left, TRACKDIR_LEFT_N, 0}},
|
||||
{{Track::Right, TRACKDIR_RIGHT_N, 0}, {Track::Y, TRACKDIR_Y_NW, 1}, {Track::Lower, TRACKDIR_LOWER_W, 1}}
|
||||
{{Track::Upper, Trackdir::Upper_E, 0}, {Track::Y, Trackdir::Y_SE, 0}, {Track::Left, Trackdir::Left_S, 1}},
|
||||
{{Track::Right, Trackdir::Right_S, 1}, {Track::X, Trackdir::X_SW, 1}, {Track::Upper, Trackdir::Upper_W, 1}},
|
||||
{{Track::Invalid, Trackdir::Invalid, 0}, {Track::Invalid, Trackdir::Invalid, 0}, {Track::Invalid, Trackdir::Invalid, 0}},
|
||||
{{Track::Lower, Trackdir::Lower_E, 0}, {Track::X, Trackdir::X_NE, 0}, {Track::Left, Trackdir::Left_N, 0}},
|
||||
{{Track::Right, Trackdir::Right_N, 0}, {Track::Y, Trackdir::Y_NW, 1}, {Track::Lower, Trackdir::Lower_W, 1}}
|
||||
};
|
||||
|
||||
/* static */ ScriptRail::SignalType ScriptRail::GetSignalType(TileIndex tile, TileIndex front)
|
||||
|
||||
@@ -219,10 +219,10 @@
|
||||
if (!::IsValidTile(tile)) return false;
|
||||
|
||||
if (transport_type == TRANSPORT_ROAD) {
|
||||
return ::GetTileTrackStatus(tile, (::TransportType)transport_type, ::RoadTramType::Road).trackdirs != TRACKDIR_BIT_NONE ||
|
||||
::GetTileTrackStatus(tile, (::TransportType)transport_type, ::RoadTramType::Tram).trackdirs != TRACKDIR_BIT_NONE;
|
||||
return ::GetTileTrackStatus(tile, (::TransportType)transport_type, ::RoadTramType::Road).trackdirs.Any() ||
|
||||
::GetTileTrackStatus(tile, (::TransportType)transport_type, ::RoadTramType::Tram).trackdirs.Any();
|
||||
} else {
|
||||
return ::GetTileTrackStatus(tile, (::TransportType)transport_type, ::RoadTramType::Invalid).trackdirs != TRACKDIR_BIT_NONE;
|
||||
return ::GetTileTrackStatus(tile, (::TransportType)transport_type, ::RoadTramType::Invalid).trackdirs.Any();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ WaterClass GetEffectiveWaterClass(TileIndex tile);
|
||||
|
||||
/** Element of the ShipPathCache. */
|
||||
struct ShipPathElement {
|
||||
Trackdir trackdir = INVALID_TRACKDIR; ///< Trackdir for this element.
|
||||
Trackdir trackdir = Trackdir::Invalid; ///< Trackdir for this element.
|
||||
|
||||
constexpr ShipPathElement() {}
|
||||
constexpr ShipPathElement(Trackdir trackdir) : trackdir(trackdir) {}
|
||||
|
||||
+4
-4
@@ -287,7 +287,7 @@ void Ship::OnNewEconomyDay()
|
||||
|
||||
Trackdir Ship::GetVehicleTrackdir() const
|
||||
{
|
||||
if (this->vehstatus.Test(VehState::Crashed)) return INVALID_TRACKDIR;
|
||||
if (this->vehstatus.Test(VehState::Crashed)) return Trackdir::Invalid;
|
||||
|
||||
if (this->IsInDepot()) {
|
||||
/* We'll assume the ship is facing outwards */
|
||||
@@ -387,7 +387,7 @@ static bool CheckShipStayInDepot(Ship *v)
|
||||
return u->type == VehicleType::Ship && u->cur_speed != 0;
|
||||
})) return true;
|
||||
|
||||
assert(v->GetVehicleTrackdir() == TRACKDIR_X_NE || v->GetVehicleTrackdir() == TRACKDIR_Y_NW);
|
||||
assert(v->GetVehicleTrackdir() == Trackdir::X_NE || v->GetVehicleTrackdir() == Trackdir::Y_NW);
|
||||
v->direction = DiagDirToDir(TrackdirToExitdir(v->GetVehicleTrackdir()));
|
||||
if (CheckReverseShip(v)) v->direction = ReverseDir(v->direction);
|
||||
|
||||
@@ -716,9 +716,9 @@ static void ShipController(Ship *v)
|
||||
assert(diagdir != DiagDirection::Invalid);
|
||||
const TrackBits tracks = GetAvailShipTracks(gp.new_tile, diagdir);
|
||||
if (tracks.None()) {
|
||||
Trackdir trackdir = INVALID_TRACKDIR;
|
||||
Trackdir trackdir = Trackdir::Invalid;
|
||||
CheckReverseShip(v, &trackdir);
|
||||
if (trackdir == INVALID_TRACKDIR) return ReverseShip(v);
|
||||
if (trackdir == Trackdir::Invalid) return ReverseShip(v);
|
||||
return ReverseShipIntoTrackdir(v, trackdir);
|
||||
}
|
||||
|
||||
|
||||
+8
-8
@@ -39,12 +39,12 @@ static constexpr DiagDirectionIndexArray<TrackBits> _enterdir_to_trackbits{
|
||||
};
|
||||
|
||||
/** Accessible TrackdirBits from a given enter direction. */
|
||||
static constexpr DiagDirectionIndexArray<TrackdirBits> _enterdir_to_trackdirbits{
|
||||
TRACKDIR_BIT_X_SW | TRACKDIR_BIT_UPPER_W | TRACKDIR_BIT_RIGHT_S,
|
||||
TRACKDIR_BIT_Y_NW | TRACKDIR_BIT_LOWER_W | TRACKDIR_BIT_RIGHT_N,
|
||||
TRACKDIR_BIT_X_NE | TRACKDIR_BIT_LOWER_E | TRACKDIR_BIT_LEFT_N,
|
||||
TRACKDIR_BIT_Y_SE | TRACKDIR_BIT_UPPER_E | TRACKDIR_BIT_LEFT_S
|
||||
};
|
||||
static constexpr DiagDirectionIndexArray<TrackdirBits> _enterdir_to_trackdirbits{{{
|
||||
{Trackdir::X_SW, Trackdir::Upper_W, Trackdir::Right_S},
|
||||
{Trackdir::Y_NW, Trackdir::Lower_W, Trackdir::Right_N},
|
||||
{Trackdir::X_NE, Trackdir::Lower_E, Trackdir::Left_N},
|
||||
{Trackdir::Y_SE, Trackdir::Upper_E, Trackdir::Left_S},
|
||||
}}};
|
||||
|
||||
/**
|
||||
* Set containing 'items' items of 'tile and Tdir'
|
||||
@@ -320,7 +320,7 @@ static SigFlags ExploreSegment(Owner owner)
|
||||
Track track = TrackBitsToTrack(tracks_masked); // mask TRACK_BIT_X and Y too
|
||||
if (HasSignalOnTrack(tile, track)) { // now check whole track, not trackdir
|
||||
SignalType sig = GetSignalType(tile, track);
|
||||
Trackdir trackdir = static_cast<Trackdir>(FindFirstBit(TrackBitsToTrackdirBits(tracks) & _enterdir_to_trackdirbits[enterdir]));
|
||||
Trackdir trackdir = (TrackBitsToTrackdirBits(tracks) & _enterdir_to_trackdirbits[enterdir]).GetNthSetBit(0).value();
|
||||
Trackdir reversedir = ReverseTrackdir(trackdir);
|
||||
/* add (tile, reversetrackdir) to 'to-be-updated' set when there is
|
||||
* ANY conventional signal in REVERSE direction
|
||||
@@ -417,7 +417,7 @@ static SigFlags ExploreSegment(Owner owner)
|
||||
static void UpdateSignalsAroundSegment(SigFlags flags)
|
||||
{
|
||||
TileIndex tile = INVALID_TILE; // Stop GCC from complaining about a possibly uninitialized variable (issue #8280).
|
||||
Trackdir trackdir = INVALID_TRACKDIR;
|
||||
Trackdir trackdir = Trackdir::Invalid;
|
||||
|
||||
while (_tbuset.Get(&tile, &trackdir)) {
|
||||
assert(HasSignalOnTrackdir(tile, trackdir));
|
||||
|
||||
+2
-2
@@ -3731,7 +3731,7 @@ static TrackStatus GetTileTrackStatus_Station(TileIndex tile, TransportType mode
|
||||
break;
|
||||
}
|
||||
|
||||
return {TrackBitsToTrackdirBits(trackbits), TRACKDIR_BIT_NONE};
|
||||
return {TrackBitsToTrackdirBits(trackbits), {}};
|
||||
}
|
||||
|
||||
|
||||
@@ -3881,7 +3881,7 @@ static VehicleEnterTileStates VehicleEnterTile_Station(Vehicle *v, TileIndex til
|
||||
}
|
||||
} else if (v->type == VehicleType::Road) {
|
||||
RoadVehicle *rv = RoadVehicle::From(v);
|
||||
if (rv->state < RVSB_IN_ROAD_STOP && !IsReversingRoadTrackdir((Trackdir)rv->state) && rv->frame == 0) {
|
||||
if (rv->state < RVSB_IN_ROAD_STOP && !IsReversingRoadTrackdir(static_cast<Trackdir>(rv->state)) && rv->frame == 0) {
|
||||
if (IsStationRoadStop(tile) && rv->IsFrontEngine()) {
|
||||
/* Attempt to allocate a parking bay in a road stop */
|
||||
if (RoadStop::GetByTile(tile, GetRoadStopType(tile))->Enter(rv)) return {};
|
||||
|
||||
+66
-66
@@ -11,28 +11,28 @@
|
||||
* Maps a diagonal direction to the all trackdirs that are connected to any
|
||||
* track entering in this direction (including those making 90 degree turns).
|
||||
*/
|
||||
extern const DiagDirectionIndexArray<TrackdirBits> _exitdir_reaches_trackdirs{
|
||||
TRACKDIR_BIT_X_NE | TRACKDIR_BIT_LOWER_E | TRACKDIR_BIT_LEFT_N, // DiagDirection::NE
|
||||
TRACKDIR_BIT_Y_SE | TRACKDIR_BIT_LEFT_S | TRACKDIR_BIT_UPPER_E, // DiagDirection::SE
|
||||
TRACKDIR_BIT_X_SW | TRACKDIR_BIT_UPPER_W | TRACKDIR_BIT_RIGHT_S, // DiagDirection::SW
|
||||
TRACKDIR_BIT_Y_NW | TRACKDIR_BIT_RIGHT_N | TRACKDIR_BIT_LOWER_W // DiagDirection::NW
|
||||
};
|
||||
extern const DiagDirectionIndexArray<TrackdirBits> _exitdir_reaches_trackdirs{{{
|
||||
{Trackdir::X_NE, Trackdir::Lower_E, Trackdir::Left_N}, // DiagDirection::NE
|
||||
{Trackdir::Y_SE, Trackdir::Left_S, Trackdir::Upper_E}, // DiagDirection::SE
|
||||
{Trackdir::X_SW, Trackdir::Upper_W, Trackdir::Right_S}, // DiagDirection::SW
|
||||
{Trackdir::Y_NW, Trackdir::Right_N, Trackdir::Lower_W}, // DiagDirection::NW
|
||||
}}};
|
||||
|
||||
/** Next trackdir to use when moving to a new tile for each current trackdir. */
|
||||
extern const TrackdirIndexArray<Trackdir> _next_trackdir{
|
||||
TRACKDIR_X_NE, TRACKDIR_Y_SE, TRACKDIR_LOWER_E, TRACKDIR_UPPER_E, TRACKDIR_RIGHT_S, TRACKDIR_LEFT_S, INVALID_TRACKDIR, INVALID_TRACKDIR,
|
||||
TRACKDIR_X_SW, TRACKDIR_Y_NW, TRACKDIR_LOWER_W, TRACKDIR_UPPER_W, TRACKDIR_RIGHT_N, TRACKDIR_LEFT_N
|
||||
Trackdir::X_NE, Trackdir::Y_SE, Trackdir::Lower_E, Trackdir::Upper_E, Trackdir::Right_S, Trackdir::Left_S, Trackdir::Invalid, Trackdir::Invalid,
|
||||
Trackdir::X_SW, Trackdir::Y_NW, Trackdir::Lower_W, Trackdir::Upper_W, Trackdir::Right_N, Trackdir::Left_N
|
||||
};
|
||||
|
||||
/** Maps a trackdir to all trackdirs that make 90 deg turns with it. */
|
||||
extern const TrackIndexArray<TrackdirBits> _track_crosses_trackdirs{
|
||||
TRACKDIR_BIT_Y_SE | TRACKDIR_BIT_Y_NW, // TRACK_X
|
||||
TRACKDIR_BIT_X_NE | TRACKDIR_BIT_X_SW, // TRACK_Y
|
||||
TRACKDIR_BIT_RIGHT_N | TRACKDIR_BIT_RIGHT_S | TRACKDIR_BIT_LEFT_N | TRACKDIR_BIT_LEFT_S, // TRACK_UPPER
|
||||
TRACKDIR_BIT_RIGHT_N | TRACKDIR_BIT_RIGHT_S | TRACKDIR_BIT_LEFT_N | TRACKDIR_BIT_LEFT_S, // TRACK_LOWER
|
||||
TRACKDIR_BIT_UPPER_W | TRACKDIR_BIT_UPPER_E | TRACKDIR_BIT_LOWER_W | TRACKDIR_BIT_LOWER_E, // TRACK_LEFT
|
||||
TRACKDIR_BIT_UPPER_W | TRACKDIR_BIT_UPPER_E | TRACKDIR_BIT_LOWER_W | TRACKDIR_BIT_LOWER_E // TRACK_RIGHT
|
||||
};
|
||||
extern const TrackIndexArray<TrackdirBits> _track_crosses_trackdirs{{{
|
||||
{Trackdir::Y_SE, Trackdir::Y_NW}, // TRACK_X
|
||||
{Trackdir::X_NE, Trackdir::X_SW}, // TRACK_Y
|
||||
{Trackdir::Right_N, Trackdir::Right_S, Trackdir::Left_N, Trackdir::Left_S}, // TRACK_UPPER
|
||||
{Trackdir::Right_N, Trackdir::Right_S, Trackdir::Left_N, Trackdir::Left_S}, // TRACK_LOWER
|
||||
{Trackdir::Upper_W, Trackdir::Upper_E, Trackdir::Lower_W, Trackdir::Lower_E}, // TRACK_LEFT
|
||||
{Trackdir::Upper_W, Trackdir::Upper_E, Trackdir::Lower_W, Trackdir::Lower_E}, // TRACK_RIGHT
|
||||
}}};
|
||||
|
||||
/** Maps a track to all tracks that make 90 deg turns with it. */
|
||||
extern const TrackIndexArray<TrackBits> _track_crosses_tracks{
|
||||
@@ -52,37 +52,37 @@ extern const TrackdirIndexArray<DiagDirection> _trackdir_to_exitdir{
|
||||
|
||||
/** Maps a track and an (4-way) dir to the trackdir that represents the track with the exit in the given direction. */
|
||||
extern const TrackIndexArray<DiagDirectionIndexArray<Trackdir>> _track_exitdir_to_trackdir{{{
|
||||
{TRACKDIR_X_NE, INVALID_TRACKDIR, TRACKDIR_X_SW, INVALID_TRACKDIR},
|
||||
{INVALID_TRACKDIR, TRACKDIR_Y_SE, INVALID_TRACKDIR, TRACKDIR_Y_NW},
|
||||
{TRACKDIR_UPPER_E, INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_UPPER_W},
|
||||
{INVALID_TRACKDIR, TRACKDIR_LOWER_E, TRACKDIR_LOWER_W, INVALID_TRACKDIR},
|
||||
{INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_LEFT_S, TRACKDIR_LEFT_N},
|
||||
{TRACKDIR_RIGHT_N, TRACKDIR_RIGHT_S, INVALID_TRACKDIR, INVALID_TRACKDIR}
|
||||
{Trackdir::X_NE, Trackdir::Invalid, Trackdir::X_SW, Trackdir::Invalid},
|
||||
{Trackdir::Invalid, Trackdir::Y_SE, Trackdir::Invalid, Trackdir::Y_NW},
|
||||
{Trackdir::Upper_E, Trackdir::Invalid, Trackdir::Invalid, Trackdir::Upper_W},
|
||||
{Trackdir::Invalid, Trackdir::Lower_E, Trackdir::Lower_W, Trackdir::Invalid},
|
||||
{Trackdir::Invalid, Trackdir::Invalid, Trackdir::Left_S, Trackdir::Left_N},
|
||||
{Trackdir::Right_N, Trackdir::Right_S, Trackdir::Invalid, Trackdir::Invalid}
|
||||
}}};
|
||||
|
||||
/** Maps a track and an (4-way) dir to the trackdir that represents the track with the entry in the given direction. */
|
||||
extern const TrackIndexArray<DiagDirectionIndexArray<Trackdir>> _track_enterdir_to_trackdir{{{
|
||||
{TRACKDIR_X_NE, INVALID_TRACKDIR, TRACKDIR_X_SW, INVALID_TRACKDIR},
|
||||
{INVALID_TRACKDIR, TRACKDIR_Y_SE, INVALID_TRACKDIR, TRACKDIR_Y_NW},
|
||||
{INVALID_TRACKDIR, TRACKDIR_UPPER_E, TRACKDIR_UPPER_W, INVALID_TRACKDIR},
|
||||
{TRACKDIR_LOWER_E, INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_LOWER_W},
|
||||
{TRACKDIR_LEFT_N, TRACKDIR_LEFT_S, INVALID_TRACKDIR, INVALID_TRACKDIR},
|
||||
{INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_RIGHT_S, TRACKDIR_RIGHT_N}
|
||||
{Trackdir::X_NE, Trackdir::Invalid, Trackdir::X_SW, Trackdir::Invalid},
|
||||
{Trackdir::Invalid, Trackdir::Y_SE, Trackdir::Invalid, Trackdir::Y_NW},
|
||||
{Trackdir::Invalid, Trackdir::Upper_E, Trackdir::Upper_W, Trackdir::Invalid},
|
||||
{Trackdir::Lower_E, Trackdir::Invalid, Trackdir::Invalid, Trackdir::Lower_W},
|
||||
{Trackdir::Left_N, Trackdir::Left_S, Trackdir::Invalid, Trackdir::Invalid},
|
||||
{Trackdir::Invalid, Trackdir::Invalid, Trackdir::Right_S, Trackdir::Right_N}
|
||||
}}};
|
||||
|
||||
/** Maps a track and a full (8-way) direction to the trackdir that represents the track running in the given direction. */
|
||||
extern const TrackIndexArray<DirectionIndexArray<Trackdir>> _track_direction_to_trackdir{{{
|
||||
{INVALID_TRACKDIR, TRACKDIR_X_NE, INVALID_TRACKDIR, INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_X_SW, INVALID_TRACKDIR, INVALID_TRACKDIR},
|
||||
{INVALID_TRACKDIR, INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_Y_SE, INVALID_TRACKDIR, INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_Y_NW},
|
||||
{INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_UPPER_E, INVALID_TRACKDIR, INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_UPPER_W, INVALID_TRACKDIR},
|
||||
{INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_LOWER_E, INVALID_TRACKDIR, INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_LOWER_W, INVALID_TRACKDIR},
|
||||
{TRACKDIR_LEFT_N, INVALID_TRACKDIR, INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_LEFT_S, INVALID_TRACKDIR, INVALID_TRACKDIR, INVALID_TRACKDIR},
|
||||
{TRACKDIR_RIGHT_N, INVALID_TRACKDIR, INVALID_TRACKDIR, INVALID_TRACKDIR, TRACKDIR_RIGHT_S, INVALID_TRACKDIR, INVALID_TRACKDIR, INVALID_TRACKDIR}
|
||||
{Trackdir::Invalid, Trackdir::X_NE, Trackdir::Invalid, Trackdir::Invalid, Trackdir::Invalid, Trackdir::X_SW, Trackdir::Invalid, Trackdir::Invalid},
|
||||
{Trackdir::Invalid, Trackdir::Invalid, Trackdir::Invalid, Trackdir::Y_SE, Trackdir::Invalid, Trackdir::Invalid, Trackdir::Invalid, Trackdir::Y_NW},
|
||||
{Trackdir::Invalid, Trackdir::Invalid, Trackdir::Upper_E, Trackdir::Invalid, Trackdir::Invalid, Trackdir::Invalid, Trackdir::Upper_W, Trackdir::Invalid},
|
||||
{Trackdir::Invalid, Trackdir::Invalid, Trackdir::Lower_E, Trackdir::Invalid, Trackdir::Invalid, Trackdir::Invalid, Trackdir::Lower_W, Trackdir::Invalid},
|
||||
{Trackdir::Left_N, Trackdir::Invalid, Trackdir::Invalid, Trackdir::Invalid, Trackdir::Left_S, Trackdir::Invalid, Trackdir::Invalid, Trackdir::Invalid},
|
||||
{Trackdir::Right_N, Trackdir::Invalid, Trackdir::Invalid, Trackdir::Invalid, Trackdir::Right_S, Trackdir::Invalid, Trackdir::Invalid, Trackdir::Invalid}
|
||||
}}};
|
||||
|
||||
/** Maps a (4-way) direction to the diagonal trackdir that runs in that direction. */
|
||||
extern const DiagDirectionIndexArray<Trackdir> _dir_to_diag_trackdir{
|
||||
TRACKDIR_X_NE, TRACKDIR_Y_SE, TRACKDIR_X_SW, TRACKDIR_Y_NW,
|
||||
Trackdir::X_NE, Trackdir::Y_SE, Trackdir::X_SW, Trackdir::Y_NW,
|
||||
};
|
||||
|
||||
/** Maps a single horizontal/vertical trackbit that is in a specific tile corner. */
|
||||
@@ -91,35 +91,35 @@ extern const CornerIndexArray<TrackBits> _corner_to_trackbits{
|
||||
};
|
||||
|
||||
extern const TrackdirBits _uphill_trackdirs[] = {
|
||||
TRACKDIR_BIT_NONE , ///< 0 SLOPE_FLAT
|
||||
TRACKDIR_BIT_X_SW | TRACKDIR_BIT_Y_NW, ///< 1 SLOPE_W -> inclined for diagonal track
|
||||
TRACKDIR_BIT_X_SW | TRACKDIR_BIT_Y_SE, ///< 2 SLOPE_S -> inclined for diagonal track
|
||||
TRACKDIR_BIT_X_SW , ///< 3 SLOPE_SW
|
||||
TRACKDIR_BIT_X_NE | TRACKDIR_BIT_Y_SE, ///< 4 SLOPE_E -> inclined for diagonal track
|
||||
TRACKDIR_BIT_NONE , ///< 5 SLOPE_EW
|
||||
TRACKDIR_BIT_Y_SE , ///< 6 SLOPE_SE
|
||||
TRACKDIR_BIT_NONE , ///< 7 SLOPE_WSE -> leveled
|
||||
TRACKDIR_BIT_X_NE | TRACKDIR_BIT_Y_NW, ///< 8 SLOPE_N -> inclined for diagonal track
|
||||
TRACKDIR_BIT_Y_NW , ///< 9 SLOPE_NW
|
||||
TRACKDIR_BIT_NONE , ///< 10 SLOPE_NS
|
||||
TRACKDIR_BIT_NONE , ///< 11 SLOPE_NWS -> leveled
|
||||
TRACKDIR_BIT_X_NE , ///< 12 SLOPE_NE
|
||||
TRACKDIR_BIT_NONE , ///< 13 SLOPE_ENW -> leveled
|
||||
TRACKDIR_BIT_NONE , ///< 14 SLOPE_SEN -> leveled
|
||||
TRACKDIR_BIT_NONE , ///< 15 invalid
|
||||
TRACKDIR_BIT_NONE , ///< 16 invalid
|
||||
TRACKDIR_BIT_NONE , ///< 17 invalid
|
||||
TRACKDIR_BIT_NONE , ///< 18 invalid
|
||||
TRACKDIR_BIT_NONE , ///< 19 invalid
|
||||
TRACKDIR_BIT_NONE , ///< 20 invalid
|
||||
TRACKDIR_BIT_NONE , ///< 21 invalid
|
||||
TRACKDIR_BIT_NONE , ///< 22 invalid
|
||||
TRACKDIR_BIT_X_SW | TRACKDIR_BIT_Y_SE, ///< 23 SLOPE_STEEP_S -> inclined for diagonal track
|
||||
TRACKDIR_BIT_NONE , ///< 24 invalid
|
||||
TRACKDIR_BIT_NONE , ///< 25 invalid
|
||||
TRACKDIR_BIT_NONE , ///< 26 invalid
|
||||
TRACKDIR_BIT_X_SW | TRACKDIR_BIT_Y_NW, ///< 27 SLOPE_STEEP_W -> inclined for diagonal track
|
||||
TRACKDIR_BIT_NONE , ///< 28 invalid
|
||||
TRACKDIR_BIT_X_NE | TRACKDIR_BIT_Y_NW, ///< 29 SLOPE_STEEP_N -> inclined for diagonal track
|
||||
TRACKDIR_BIT_X_NE | TRACKDIR_BIT_Y_SE, ///< 30 SLOPE_STEEP_E -> inclined for diagonal track
|
||||
{}, // 0 SLOPE_FLAT
|
||||
{Trackdir::X_SW, Trackdir::Y_NW}, // 1 SLOPE_W -> inclined for diagonal track
|
||||
{Trackdir::X_SW, Trackdir::Y_SE}, // 2 SLOPE_S -> inclined for diagonal track
|
||||
{Trackdir::X_SW}, // 3 SLOPE_SW
|
||||
{Trackdir::X_NE, Trackdir::Y_SE}, // 4 SLOPE_E -> inclined for diagonal track
|
||||
{}, // 5 SLOPE_EW
|
||||
{Trackdir::Y_SE}, // 6 SLOPE_SE
|
||||
{}, // 7 SLOPE_WSE -> leveled
|
||||
{Trackdir::X_NE, Trackdir::Y_NW}, // 8 SLOPE_N -> inclined for diagonal track
|
||||
{Trackdir::Y_NW}, // 9 SLOPE_NW
|
||||
{}, // 10 SLOPE_NS
|
||||
{}, // 11 SLOPE_NWS -> leveled
|
||||
{Trackdir::X_NE}, // 12 SLOPE_NE
|
||||
{}, // 13 SLOPE_ENW -> leveled
|
||||
{}, // 14 SLOPE_SEN -> leveled
|
||||
{}, // 15 invalid
|
||||
{}, // 16 invalid
|
||||
{}, // 17 invalid
|
||||
{}, // 18 invalid
|
||||
{}, // 19 invalid
|
||||
{}, // 20 invalid
|
||||
{}, // 21 invalid
|
||||
{}, // 22 invalid
|
||||
{Trackdir::X_SW, Trackdir::Y_SE}, // 23 SLOPE_STEEP_S -> inclined for diagonal track
|
||||
{}, // 24 invalid
|
||||
{}, // 25 invalid
|
||||
{}, // 26 invalid
|
||||
{Trackdir::X_SW, Trackdir::Y_NW}, // 27 SLOPE_STEEP_W -> inclined for diagonal track
|
||||
{}, // 28 invalid
|
||||
{Trackdir::X_NE, Trackdir::Y_NW}, // 29 SLOPE_STEEP_N -> inclined for diagonal track
|
||||
{Trackdir::X_NE, Trackdir::Y_SE}, // 30 SLOPE_STEEP_E -> inclined for diagonal track
|
||||
};
|
||||
|
||||
+31
-47
@@ -10,13 +10,10 @@
|
||||
#ifndef TRACK_FUNC_H
|
||||
#define TRACK_FUNC_H
|
||||
|
||||
#include "core/bitmath_func.hpp"
|
||||
#include "track_type.h"
|
||||
#include "direction_func.h"
|
||||
#include "slope_func.h"
|
||||
|
||||
using SetTrackdirBitIterator = SetBitIterator<Trackdir, TrackdirBits>;
|
||||
|
||||
/**
|
||||
* Checks if a Track is valid.
|
||||
*
|
||||
@@ -38,7 +35,7 @@ inline bool IsValidTrack(Track track)
|
||||
*/
|
||||
inline bool IsValidTrackdirForRoadVehicle(Trackdir trackdir)
|
||||
{
|
||||
return trackdir < TRACKDIR_END;
|
||||
return trackdir < Trackdir::End;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,7 +47,7 @@ inline bool IsValidTrackdirForRoadVehicle(Trackdir trackdir)
|
||||
*/
|
||||
inline bool IsValidTrackdir(Trackdir trackdir)
|
||||
{
|
||||
return trackdir != INVALID_TRACKDIR && ((1 << trackdir & TRACKDIR_BIT_MASK) != TRACKDIR_BIT_NONE);
|
||||
return trackdir < Trackdir::End && TRACKDIR_BIT_MASK.Test(trackdir);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,7 +86,7 @@ inline TrackBits CornerToTrackBits(Corner corner)
|
||||
inline TrackdirBits TrackdirToTrackdirBits(Trackdir trackdir)
|
||||
{
|
||||
assert(IsValidTrackdir(trackdir));
|
||||
return static_cast<TrackdirBits>(1 << trackdir);
|
||||
return trackdir;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -121,8 +118,8 @@ inline Track RemoveFirstTrack(TrackBits *tracks)
|
||||
*
|
||||
* This function searches for the first bit in the TrackdirBits parameter,
|
||||
* remove this bit from the parameter and returns the fnound bit as
|
||||
* Trackdir value. It returns INVALID_TRACKDIR if the trackdirs is
|
||||
* TRACKDIR_BIT_NONE or INVALID_TRACKDIR_BIT. This is basically used in a
|
||||
* Trackdir value. It returns Trackdir::Invalid if the trackdirs is
|
||||
* empty or INVALID_TRACKDIR_BIT. This is basically used in a
|
||||
* while-loop to get all track-directions step by step until the value
|
||||
* reaches TRACKDIR_BIT_NONE.
|
||||
*
|
||||
@@ -132,13 +129,12 @@ inline Track RemoveFirstTrack(TrackBits *tracks)
|
||||
*/
|
||||
inline Trackdir RemoveFirstTrackdir(TrackdirBits *trackdirs)
|
||||
{
|
||||
if (*trackdirs != TRACKDIR_BIT_NONE && *trackdirs != INVALID_TRACKDIR_BIT) {
|
||||
assert((*trackdirs & ~TRACKDIR_BIT_MASK) == TRACKDIR_BIT_NONE);
|
||||
Trackdir first = (Trackdir)FindFirstBit(*trackdirs);
|
||||
ClrBit(*trackdirs, first);
|
||||
return first;
|
||||
}
|
||||
return INVALID_TRACKDIR;
|
||||
if (trackdirs->None() || *trackdirs == INVALID_TRACKDIR_BIT) return Trackdir::Invalid;
|
||||
|
||||
assert(!trackdirs->Any({Trackdir::RvRev_NE, Trackdir::RvRev_SE, Trackdir::RvRev_SW, Trackdir::RvRev_NW}));
|
||||
Trackdir first = trackdirs->GetNthSetBit(0).value();
|
||||
trackdirs->Reset(first);
|
||||
return first;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,21 +170,21 @@ inline Track TrackBitsToTrack(TrackBits tracks)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns first Trackdir from TrackdirBits or INVALID_TRACKDIR
|
||||
* Returns first Trackdir from TrackdirBits or Trackdir::Invalid
|
||||
*
|
||||
* This function returns the first Trackdir in the given TrackdirBits value or
|
||||
* INVALID_TRACKDIR if the value is TRACKDIR_BIT_NONE. The TrackdirBits must
|
||||
* Trackdir::Invalid if the value is empty. The TrackdirBits must
|
||||
* not be INVALID_TRACKDIR_BIT.
|
||||
*
|
||||
* @param trackdirs The TrackdirBits value
|
||||
* @return The first Trackdir from the TrackdirBits or INVALID_TRACKDIR on TRACKDIR_BIT_NONE.
|
||||
* @return The first Trackdir from the TrackdirBits or Trackdir::Invalid on empty.
|
||||
* @pre trackdirs must not be INVALID_TRACKDIR_BIT
|
||||
* @see RemoveFirstTrackdir
|
||||
*/
|
||||
inline Trackdir FindFirstTrackdir(TrackdirBits trackdirs)
|
||||
{
|
||||
assert((trackdirs & ~TRACKDIR_BIT_MASK) == TRACKDIR_BIT_NONE);
|
||||
return (trackdirs != TRACKDIR_BIT_NONE) ? (Trackdir)FindFirstBit(trackdirs) : INVALID_TRACKDIR;
|
||||
assert(!trackdirs.Any({Trackdir::RvRev_NE, Trackdir::RvRev_SE, Trackdir::RvRev_SW, Trackdir::RvRev_NW}));
|
||||
return trackdirs.GetNthSetBit(0).value_or(Trackdir::Invalid);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -219,12 +215,12 @@ inline Track TrackToOppositeTrack(Track t)
|
||||
*
|
||||
* @param trackdir The Trackdir value
|
||||
* @return The reverse trackdir
|
||||
* @pre trackdir must not be INVALID_TRACKDIR
|
||||
* @pre trackdir must not be Trackdir::Invalid
|
||||
*/
|
||||
inline Trackdir ReverseTrackdir(Trackdir trackdir)
|
||||
{
|
||||
assert(IsValidTrackdirForRoadVehicle(trackdir));
|
||||
return (Trackdir)(trackdir ^ 8);
|
||||
return static_cast<Trackdir>(to_underlying(trackdir) ^ 8);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -239,7 +235,7 @@ inline Trackdir ReverseTrackdir(Trackdir trackdir)
|
||||
inline Track TrackdirToTrack(Trackdir trackdir)
|
||||
{
|
||||
assert(IsValidTrackdir(trackdir));
|
||||
return static_cast<Track>(trackdir & 0x7);
|
||||
return static_cast<Track>(to_underlying(trackdir) & 0x7);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -256,7 +252,7 @@ inline Track TrackdirToTrack(Trackdir trackdir)
|
||||
inline Trackdir TrackToTrackdir(Track track)
|
||||
{
|
||||
assert(IsValidTrack(track));
|
||||
return (Trackdir)track;
|
||||
return static_cast<Trackdir>(track);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -271,7 +267,7 @@ inline Trackdir TrackToTrackdir(Track track)
|
||||
inline TrackdirBits TrackToTrackdirBits(Track track)
|
||||
{
|
||||
Trackdir td = TrackToTrackdir(track);
|
||||
return static_cast<TrackdirBits>(TrackdirToTrackdirBits(td) | TrackdirToTrackdirBits(ReverseTrackdir(td)));
|
||||
return TrackdirToTrackdirBits(td) | TrackdirToTrackdirBits(ReverseTrackdir(td));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -284,7 +280,7 @@ inline TrackdirBits TrackToTrackdirBits(Track track)
|
||||
*/
|
||||
inline TrackBits TrackdirBitsToTrackBits(TrackdirBits bits)
|
||||
{
|
||||
return static_cast<TrackBits>((bits | (bits >> 8)) & TRACK_BIT_ALL.base());
|
||||
return static_cast<TrackBits>((bits.base() | (bits.base() >> 8)) & TRACK_BIT_ALL.base());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -298,18 +294,6 @@ inline TrackdirBits TrackBitsToTrackdirBits(TrackBits bits)
|
||||
return static_cast<TrackdirBits>(bits.base() * 0x101);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a TrackdirBits has a given Trackdir.
|
||||
* @param trackdirs The trackdir bits.
|
||||
* @param trackdir The trackdir to check.
|
||||
* @return \c true iff \c trackdir is in \c trackdirs.
|
||||
*/
|
||||
inline bool HasTrackdir(TrackdirBits trackdirs, Trackdir trackdir)
|
||||
{
|
||||
assert(IsValidTrackdir(trackdir));
|
||||
return HasBit(trackdirs, trackdir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps a trackdir to the trackdir that you will end up on if you go straight
|
||||
* ahead.
|
||||
@@ -368,15 +352,15 @@ inline DiagDirection TrackdirToExitdir(Trackdir trackdir)
|
||||
* with the exit in the given direction.
|
||||
*
|
||||
* For the diagonal tracks the resulting track direction are clear for a given
|
||||
* DiagDirection. It either matches the direction or it returns INVALID_TRACKDIR,
|
||||
* DiagDirection. It either matches the direction or it returns Trackdir::Invalid,
|
||||
* as a Track::X cannot be applied with DIAG_SE.
|
||||
* For the straight tracks the resulting track direction will be the
|
||||
* direction which the DiagDirection is pointing. But this will be INVALID_TRACKDIR
|
||||
* direction which the DiagDirection is pointing. But this will be Trackdir::Invalid
|
||||
* if the DiagDirection is pointing 'away' the track.
|
||||
*
|
||||
* @param track The track to apply an direction on
|
||||
* @param diagdir The DiagDirection to apply on
|
||||
* @return The resulting track direction or INVALID_TRACKDIR if not possible.
|
||||
* @return The resulting track direction or Trackdir::Invalid if not possible.
|
||||
*/
|
||||
inline Trackdir TrackExitdirToTrackdir(Track track, DiagDirection diagdir)
|
||||
{
|
||||
@@ -391,17 +375,17 @@ inline Trackdir TrackExitdirToTrackdir(Track track, DiagDirection diagdir)
|
||||
* with the entry in the given direction.
|
||||
*
|
||||
* For the diagonal tracks the return value is clear, its either the matching
|
||||
* track direction or INVALID_TRACKDIR.
|
||||
* track direction or Trackdir::Invalid.
|
||||
* For the straight tracks this returns the track direction which results if
|
||||
* you follow the DiagDirection and then turn by 45 deg left or right on the
|
||||
* next tile. The new direction on the new track will be the returning Trackdir
|
||||
* value. If the parameters makes no sense like the track Track::Upper and the
|
||||
* direction DiagDirection::NE (target track cannot be reached) this function returns
|
||||
* INVALID_TRACKDIR.
|
||||
* Trackdir::Invalid.
|
||||
*
|
||||
* @param track The target track
|
||||
* @param diagdir The direction to "come from"
|
||||
* @return the resulting Trackdir or INVALID_TRACKDIR if not possible.
|
||||
* @return the resulting Trackdir or Trackdir::Invalid if not possible.
|
||||
*/
|
||||
inline Trackdir TrackEnterdirToTrackdir(Track track, DiagDirection diagdir)
|
||||
{
|
||||
@@ -584,7 +568,7 @@ inline bool TrackOverlapsTracks(TrackBits tracks, Track track)
|
||||
inline bool IsReversingRoadTrackdir(Trackdir dir)
|
||||
{
|
||||
assert(IsValidTrackdirForRoadVehicle(dir));
|
||||
return (dir & 0x07) >= 6;
|
||||
return (to_underlying(dir) & 0x07) >= 6;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -595,7 +579,7 @@ inline bool IsReversingRoadTrackdir(Trackdir dir)
|
||||
inline bool IsStraightRoadTrackdir(Trackdir dir)
|
||||
{
|
||||
assert(IsValidTrackdirForRoadVehicle(dir));
|
||||
return (dir & 0x06) == 0;
|
||||
return (to_underlying(dir) & 0x06) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -612,7 +596,7 @@ inline bool IsUphillTrackdir(Slope slope, Trackdir dir)
|
||||
{
|
||||
assert(IsValidTrackdirForRoadVehicle(dir));
|
||||
extern const TrackdirBits _uphill_trackdirs[];
|
||||
return HasBit(_uphill_trackdirs[RemoveHalftileSlope(slope)], dir);
|
||||
return _uphill_trackdirs[RemoveHalftileSlope(slope)].Test(dir);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+31
-48
@@ -60,63 +60,46 @@ static constexpr TrackBits TRACK_BIT_ALL = {Track::X, Track::Y, Track::Upper, Tr
|
||||
* reversing track dirs are not considered to be 'valid' except in a small
|
||||
* corner in the road vehicle controller.
|
||||
*/
|
||||
enum Trackdir : uint8_t {
|
||||
TRACKDIR_BEGIN = 0, ///< Used for iterations
|
||||
TRACKDIR_X_NE = 0, ///< X-axis and direction to north-east
|
||||
TRACKDIR_Y_SE = 1, ///< Y-axis and direction to south-east
|
||||
TRACKDIR_UPPER_E = 2, ///< Upper track and direction to east
|
||||
TRACKDIR_LOWER_E = 3, ///< Lower track and direction to east
|
||||
TRACKDIR_LEFT_S = 4, ///< Left track and direction to south
|
||||
TRACKDIR_RIGHT_S = 5, ///< Right track and direction to south
|
||||
TRACKDIR_RVREV_NE = 6, ///< (Road vehicle) reverse direction north-east
|
||||
TRACKDIR_RVREV_SE = 7, ///< (Road vehicle) reverse direction south-east
|
||||
TRACKDIR_X_SW = 8, ///< X-axis and direction to south-west
|
||||
TRACKDIR_Y_NW = 9, ///< Y-axis and direction to north-west
|
||||
TRACKDIR_UPPER_W = 10, ///< Upper track and direction to west
|
||||
TRACKDIR_LOWER_W = 11, ///< Lower track and direction to west
|
||||
TRACKDIR_LEFT_N = 12, ///< Left track and direction to north
|
||||
TRACKDIR_RIGHT_N = 13, ///< Right track and direction to north
|
||||
TRACKDIR_RVREV_SW = 14, ///< (Road vehicle) reverse direction south-west
|
||||
TRACKDIR_RVREV_NW = 15, ///< (Road vehicle) reverse direction north-west
|
||||
TRACKDIR_END, ///< Used for iterations
|
||||
INVALID_TRACKDIR = 0xFF, ///< Flag for an invalid trackdir
|
||||
};
|
||||
enum class Trackdir : uint8_t {
|
||||
X_NE = 0, ///< X-axis and direction to north-east
|
||||
Y_SE = 1, ///< Y-axis and direction to south-east
|
||||
Upper_E = 2, ///< Upper track and direction to east
|
||||
Lower_E = 3, ///< Lower track and direction to east
|
||||
Left_S = 4, ///< Left track and direction to south
|
||||
Right_S = 5, ///< Right track and direction to south
|
||||
RvRev_NE = 6, ///< (Road vehicle) reverse direction north-east
|
||||
RvRev_SE = 7, ///< (Road vehicle) reverse direction south-east
|
||||
X_SW = 8, ///< X-axis and direction to south-west
|
||||
Y_NW = 9, ///< Y-axis and direction to north-west
|
||||
Upper_W = 10, ///< Upper track and direction to west
|
||||
Lower_W = 11, ///< Lower track and direction to west
|
||||
Left_N = 12, ///< Left track and direction to north
|
||||
Right_N = 13, ///< Right track and direction to north
|
||||
RvRev_SW = 14, ///< (Road vehicle) reverse direction south-west
|
||||
RvRev_NW = 15, ///< (Road vehicle) reverse direction north-west
|
||||
|
||||
/** Allow incrementing of Trackdir variables */
|
||||
DECLARE_INCREMENT_DECREMENT_OPERATORS(Trackdir)
|
||||
End, ///< End marker
|
||||
Invalid = 0xFF, ///< Flag for an invalid trackdir
|
||||
};
|
||||
|
||||
/**
|
||||
* Array with \c Trackdir as index.
|
||||
* @tparam T the type contained within the array.
|
||||
*/
|
||||
template <typename T>
|
||||
using TrackdirIndexArray = EnumIndexArray<T, Trackdir, TRACKDIR_END>;
|
||||
using TrackdirIndexArray = EnumIndexArray<T, Trackdir, Trackdir::End>;
|
||||
|
||||
/**
|
||||
* Enumeration of bitmasks for the TrackDirs
|
||||
*
|
||||
* These are a combination of tracks and directions. Values are 0-5 in one
|
||||
* direction (corresponding to the Track enum) and 8-13 in the other direction.
|
||||
*/
|
||||
enum TrackdirBits : uint16_t {
|
||||
TRACKDIR_BIT_NONE = 0U, ///< No track build
|
||||
TRACKDIR_BIT_X_NE = 1U << TRACKDIR_X_NE, ///< Track x-axis, direction north-east
|
||||
TRACKDIR_BIT_Y_SE = 1U << TRACKDIR_Y_SE, ///< Track y-axis, direction south-east
|
||||
TRACKDIR_BIT_UPPER_E = 1U << TRACKDIR_UPPER_E, ///< Track upper, direction east
|
||||
TRACKDIR_BIT_LOWER_E = 1U << TRACKDIR_LOWER_E, ///< Track lower, direction east
|
||||
TRACKDIR_BIT_LEFT_S = 1U << TRACKDIR_LEFT_S, ///< Track left, direction south
|
||||
TRACKDIR_BIT_RIGHT_S = 1U << TRACKDIR_RIGHT_S, ///< Track right, direction south
|
||||
/* Again, note the two missing values here. This enables trackdir -> track conversion by doing (trackdir & 0xFF) */
|
||||
TRACKDIR_BIT_X_SW = 1U << TRACKDIR_X_SW, ///< Track x-axis, direction south-west
|
||||
TRACKDIR_BIT_Y_NW = 1U << TRACKDIR_Y_NW, ///< Track y-axis, direction north-west
|
||||
TRACKDIR_BIT_UPPER_W = 1U << TRACKDIR_UPPER_W, ///< Track upper, direction west
|
||||
TRACKDIR_BIT_LOWER_W = 1U << TRACKDIR_LOWER_W, ///< Track lower, direction west
|
||||
TRACKDIR_BIT_LEFT_N = 1U << TRACKDIR_LEFT_N, ///< Track left, direction north
|
||||
TRACKDIR_BIT_RIGHT_N = 1U << TRACKDIR_RIGHT_N, ///< Track right, direction north
|
||||
TRACKDIR_BIT_MASK = 0x3F3F, ///< Bitmask for bit-operations
|
||||
INVALID_TRACKDIR_BIT = 0xFFFF, ///< Flag for an invalid trackdirbit value
|
||||
/** Bitset of \c Trackdir elements. */
|
||||
using TrackdirBits = EnumBitSet<Trackdir, uint16_t>;
|
||||
|
||||
/** Bitset of valid non-road vehicle trackdirs/ */
|
||||
static constexpr TrackdirBits TRACKDIR_BIT_MASK{
|
||||
Trackdir::X_NE, Trackdir::Y_SE, Trackdir::Upper_E, Trackdir::Lower_E, Trackdir::Left_S, Trackdir::Right_S,
|
||||
Trackdir::X_SW, Trackdir::Y_NW, Trackdir::Upper_W, Trackdir::Lower_W, Trackdir::Left_N, Trackdir::Right_N,
|
||||
};
|
||||
DECLARE_ENUM_AS_BIT_SET(TrackdirBits)
|
||||
|
||||
/** Marker for an invalid TrackdirBits value. */
|
||||
static constexpr TrackdirBits INVALID_TRACKDIR_BIT{UINT16_MAX};
|
||||
|
||||
/** Track status of a tile. */
|
||||
struct TrackStatus {
|
||||
|
||||
+12
-12
@@ -2333,7 +2333,7 @@ static void CheckNextTrainTile(Train *consist)
|
||||
|
||||
if (!HasReservedTracks(ft.new_tile, TrackdirBitsToTrackBits(ft.new_td_bits))) {
|
||||
/* Next tile is not reserved. */
|
||||
if (KillFirstBit(ft.new_td_bits) == TRACKDIR_BIT_NONE) {
|
||||
if (ft.new_td_bits.Count() == 1) {
|
||||
if (HasPbsSignalOnTrackdir(ft.new_tile, FindFirstTrackdir(ft.new_td_bits))) {
|
||||
/* If the next tile is a PBS signal, try to make a reservation. */
|
||||
TrackBits tracks = TrackdirBitsToTrackBits(ft.new_td_bits);
|
||||
@@ -2499,7 +2499,7 @@ void FreeTrainTrackReservation(const Train *consist)
|
||||
tile = ft.new_tile;
|
||||
TrackdirBits bits = ft.new_td_bits & TrackBitsToTrackdirBits(GetReservedTrackbits(tile));
|
||||
td = RemoveFirstTrackdir(&bits);
|
||||
assert(bits == TRACKDIR_BIT_NONE);
|
||||
assert(bits.None());
|
||||
|
||||
if (!IsValidTrackdir(td)) break;
|
||||
|
||||
@@ -2573,19 +2573,19 @@ static PBSTileInfo ExtendTrainReservation(const Train *v, TrackBits *new_tracks,
|
||||
TileIndex tile = origin.tile;
|
||||
Trackdir cur_td = origin.trackdir;
|
||||
while (ft.Follow(tile, cur_td)) {
|
||||
if (KillFirstBit(ft.new_td_bits) == TRACKDIR_BIT_NONE) {
|
||||
if (ft.new_td_bits.Count() == 1) {
|
||||
/* Possible signal tile. */
|
||||
if (HasOnewaySignalBlockingTrackdir(ft.new_tile, FindFirstTrackdir(ft.new_td_bits))) break;
|
||||
}
|
||||
|
||||
if (Rail90DegTurnDisallowed(GetTileRailType(ft.old_tile), GetTileRailType(ft.new_tile))) {
|
||||
ft.new_td_bits &= ~TrackdirCrossesTrackdirs(ft.old_td);
|
||||
if (ft.new_td_bits == TRACKDIR_BIT_NONE) break;
|
||||
ft.new_td_bits.Reset(TrackdirCrossesTrackdirs(ft.old_td));
|
||||
if (ft.new_td_bits.None()) break;
|
||||
}
|
||||
|
||||
/* Station, depot or waypoint are a possible target. */
|
||||
bool target_seen = ft.is_station || (IsTileType(ft.new_tile, TileType::Railway) && !IsPlainRail(ft.new_tile));
|
||||
if (target_seen || KillFirstBit(ft.new_td_bits) != TRACKDIR_BIT_NONE) {
|
||||
if (target_seen || ft.new_td_bits.Count() > 1) {
|
||||
/* Choice found or possible target encountered.
|
||||
* On finding a possible target, we need to stop and let the pathfinder handle the
|
||||
* remaining path. This is because we don't know if this target is in one of our
|
||||
@@ -2645,10 +2645,10 @@ static PBSTileInfo ExtendTrainReservation(const Train *v, TrackBits *new_tracks,
|
||||
if (!ft.Follow(tile, cur_td)) break;
|
||||
|
||||
if (Rail90DegTurnDisallowed(GetTileRailType(ft.old_tile), GetTileRailType(ft.new_tile))) {
|
||||
ft.new_td_bits &= ~TrackdirCrossesTrackdirs(ft.old_td);
|
||||
assert(ft.new_td_bits != TRACKDIR_BIT_NONE);
|
||||
ft.new_td_bits.Reset(TrackdirCrossesTrackdirs(ft.old_td));
|
||||
assert(ft.new_td_bits.Any());
|
||||
}
|
||||
assert(KillFirstBit(ft.new_td_bits) == TRACKDIR_BIT_NONE);
|
||||
assert(ft.new_td_bits.Count() == 1);
|
||||
|
||||
tile = ft.new_tile;
|
||||
cur_td = FindFirstTrackdir(ft.new_td_bits);
|
||||
@@ -2808,7 +2808,7 @@ static Track ChooseTrainTrack(Train *consist, TileIndex tile, DiagDirection ente
|
||||
|
||||
const Train *moving_front = consist->GetMovingFront();
|
||||
|
||||
PBSTileInfo res_dest(tile, INVALID_TRACKDIR, false);
|
||||
PBSTileInfo res_dest(tile, Trackdir::Invalid, false);
|
||||
DiagDirection dest_enterdir = enterdir;
|
||||
if (do_track_reservation) {
|
||||
res_dest = ExtendTrainReservation(consist, &tracks, &dest_enterdir);
|
||||
@@ -3999,7 +3999,7 @@ static bool TrainCheckIfLineEnds(Train *moving_front, bool reverse)
|
||||
}
|
||||
|
||||
/* approaching red signal */
|
||||
if ((trackdirbits & red_signals) != 0) return TrainApproachingLineEnd(moving_front, true, reverse);
|
||||
if (trackdirbits.Any(red_signals)) return TrainApproachingLineEnd(moving_front, true, reverse);
|
||||
|
||||
/* approaching a rail/road crossing? then make it red */
|
||||
if (IsLevelCrossingTile(tile)) MaybeBarCrossingWithSound(tile);
|
||||
@@ -4298,7 +4298,7 @@ void Train::OnNewEconomyDay()
|
||||
*/
|
||||
Trackdir Train::GetVehicleTrackdir() const
|
||||
{
|
||||
if (this->vehstatus.Test(VehState::Crashed)) return INVALID_TRACKDIR;
|
||||
if (this->vehstatus.Test(VehState::Crashed)) return Trackdir::Invalid;
|
||||
|
||||
if (this->track == Track::Depot) {
|
||||
/* We'll assume the train is facing outwards */
|
||||
|
||||
@@ -1857,7 +1857,7 @@ static TrackStatus GetTileTrackStatus_TunnelBridge(TileIndex tile, TransportType
|
||||
|
||||
DiagDirection dir = GetTunnelBridgeDirection(tile);
|
||||
if (side != DiagDirection::Invalid && side != ReverseDiagDir(dir)) return {};
|
||||
return {TrackBitsToTrackdirBits(DiagDirToDiagTrack(dir)), TRACKDIR_BIT_NONE};
|
||||
return {TrackBitsToTrackdirBits(DiagDirToDiagTrack(dir)), {}};
|
||||
}
|
||||
|
||||
/** @copydoc ChangeTileOwnerProc */
|
||||
@@ -2017,7 +2017,7 @@ static VehicleEnterTileStates VehicleEnterTile_TunnelBridge(Vehicle *v, TileInde
|
||||
/* We're at the tunnel exit ?? */
|
||||
if (dir == ReverseDiagDir(vdir) && frame == TILE_SIZE - _tunnel_visibility_frame[dir] && z == 0) {
|
||||
rv->tile = tile;
|
||||
rv->state = DiagDirToDiagTrackdir(vdir);
|
||||
rv->state = to_underlying(DiagDirToDiagTrackdir(vdir));
|
||||
rv->frame = frame;
|
||||
rv->vehstatus.Reset(VehState::Hidden);
|
||||
return VehicleEnterTileState::EnteredWormhole;
|
||||
@@ -2073,7 +2073,7 @@ static VehicleEnterTileStates VehicleEnterTile_TunnelBridge(Vehicle *v, TileInde
|
||||
case VehicleType::Road: {
|
||||
RoadVehicle *rv = RoadVehicle::From(v);
|
||||
if (rv->state == RVSB_WORMHOLE) {
|
||||
rv->state = DiagDirToDiagTrackdir(vdir);
|
||||
rv->state = to_underlying(DiagDirToDiagTrackdir(vdir));
|
||||
rv->frame = 0;
|
||||
return VehicleEnterTileState::EnteredWormhole;
|
||||
}
|
||||
|
||||
+1
-1
@@ -599,7 +599,7 @@ public:
|
||||
* in depots), returns 0xFF.
|
||||
* @return the trackdir of the vehicle
|
||||
*/
|
||||
virtual Trackdir GetVehicleTrackdir() const { return INVALID_TRACKDIR; }
|
||||
virtual Trackdir GetVehicleTrackdir() const { return Trackdir::Invalid; }
|
||||
|
||||
/**
|
||||
* Gets the running cost of a vehicle that can be sent into string parameters for string processing.
|
||||
|
||||
+1
-1
@@ -1403,7 +1403,7 @@ static TrackStatus GetTileTrackStatus_Water(TileIndex tile, TransportType mode,
|
||||
/* NW border: remove tracks that connects NW tile edge */
|
||||
ts.Reset({Track::Y, Track::Left, Track::Upper});
|
||||
}
|
||||
return {TrackBitsToTrackdirBits(ts), TRACKDIR_BIT_NONE};
|
||||
return {TrackBitsToTrackdirBits(ts), {}};
|
||||
}
|
||||
|
||||
/** @copydoc ClickTileProc */
|
||||
|
||||
Reference in New Issue
Block a user