Merge branch 'master' into jgrpp-nrt
Merge NRT feature # Conflicts: # docs/landscape.html # docs/landscape_grid.html # src/bridge_map.h # src/build_vehicle_gui.cpp # src/company_base.h # src/company_cmd.cpp # src/misc_gui.cpp # src/newgrf.cpp # src/newgrf_engine.cpp # src/pathfinder/follow_track.hpp # src/pathfinder/npf/npf.cpp # src/road_cmd.cpp # src/road_func.h # src/road_gui.cpp # src/road_map.h # src/road_type.h # src/roadveh_cmd.cpp # src/saveload/afterload.cpp # src/saveload/company_sl.cpp # src/script/api/script_bridge.cpp # src/table/newgrf_debug_data.h # src/tile_cmd.h # src/town_cmd.cpp # src/tunnel_map.h # src/tunnelbridge_cmd.cpp
This commit is contained in:
@@ -33,7 +33,7 @@ struct CFollowTrackT
|
||||
enum ErrorCode {
|
||||
EC_NONE,
|
||||
EC_OWNER,
|
||||
EC_RAIL_TYPE,
|
||||
EC_RAIL_ROAD_TYPE,
|
||||
EC_90DEG,
|
||||
EC_NO_WAY,
|
||||
EC_RESERVED,
|
||||
@@ -61,6 +61,7 @@ struct CFollowTrackT
|
||||
|
||||
inline CFollowTrackT(Owner o, RailTypes railtype_override = INVALID_RAILTYPES, CPerformanceTimer *pPerf = nullptr)
|
||||
{
|
||||
assert(IsRailTT());
|
||||
m_veh = nullptr;
|
||||
Init(o, railtype_override, pPerf);
|
||||
}
|
||||
@@ -93,7 +94,7 @@ struct CFollowTrackT
|
||||
inline static TransportType TT() { return Ttr_type_; }
|
||||
inline static bool IsWaterTT() { return TT() == TRANSPORT_WATER; }
|
||||
inline static bool IsRailTT() { return TT() == TRANSPORT_RAIL; }
|
||||
inline bool IsTram() { return IsRoadTT() && HasBit(RoadVehicle::From(m_veh)->compatible_roadtypes, ROADTYPE_TRAM); }
|
||||
inline bool IsTram() { return IsRoadTT() && RoadTypeIsTram(RoadVehicle::From(m_veh)->roadtype); }
|
||||
inline static bool IsRoadTT() { return TT() == TRANSPORT_ROAD; }
|
||||
inline static bool Allow90degTurns() { return T90deg_turns_allowed_; }
|
||||
inline static bool DoTrackMasking() { return Tmask_reserved_tracks; }
|
||||
@@ -105,7 +106,7 @@ struct CFollowTrackT
|
||||
|
||||
const bool is_bridge = IsRoadCustomBridgeHeadTile(tile);
|
||||
if (is_bridge || IsNormalRoadTile(tile)) {
|
||||
RoadBits rb = is_bridge ? GetCustomBridgeHeadRoadBits(tile, ROADTYPE_TRAM) : GetRoadBits(tile, ROADTYPE_TRAM);
|
||||
RoadBits rb = is_bridge ? GetCustomBridgeHeadRoadBits(tile, RTT_TRAM) : GetRoadBits(tile, RTT_TRAM);
|
||||
switch (rb) {
|
||||
case ROAD_NW: return DIAGDIR_NW;
|
||||
case ROAD_SW: return DIAGDIR_SW;
|
||||
@@ -128,7 +129,7 @@ struct CFollowTrackT
|
||||
m_err = EC_NONE;
|
||||
assert_tile(
|
||||
((TrackStatusToTrackdirBits(
|
||||
GetTileTrackStatus(m_old_tile, TT(), (IsRoadTT() && m_veh != nullptr) ? RoadVehicle::From(m_veh)->compatible_roadtypes : 0)
|
||||
GetTileTrackStatus(m_old_tile, TT(), (IsRoadTT() && m_veh != nullptr) ? (this->IsTram() ? RTT_TRAM : RTT_ROAD) : 0)
|
||||
) & TrackdirToTrackdirBits(m_old_td)) != 0) ||
|
||||
(IsTram() && GetSingleTramBit(m_old_tile) != INVALID_DIAGDIR), // Disable the assertion for single tram bits
|
||||
m_old_tile
|
||||
@@ -154,7 +155,7 @@ struct CFollowTrackT
|
||||
if (IsRoadTT() && !IsTram() && TryReverse()) return true;
|
||||
|
||||
/* CanEnterNewTile already set a reason.
|
||||
* Do NOT overwrite it (important for example for EC_RAIL_TYPE).
|
||||
* Do NOT overwrite it (important for example for EC_RAIL_ROAD_TYPE).
|
||||
* Only set a reason if CanEnterNewTile was not called */
|
||||
if (m_new_td_bits == TRACKDIR_BIT_NONE) m_err = EC_NO_WAY;
|
||||
|
||||
@@ -244,7 +245,7 @@ protected:
|
||||
if (IsRailTT() && IsPlainRailTile(m_new_tile)) {
|
||||
m_new_td_bits = (TrackdirBits)(GetTrackBits(m_new_tile) * 0x101);
|
||||
} else {
|
||||
m_new_td_bits = TrackStatusToTrackdirBits(GetTileTrackStatus(m_new_tile, TT(), IsRoadTT() ? RoadVehicle::From(m_veh)->compatible_roadtypes : 0));
|
||||
m_new_td_bits = TrackStatusToTrackdirBits(GetTileTrackStatus(m_new_tile, TT(), IsRoadTT() ? (this->IsTram() ? RTT_TRAM : RTT_ROAD) : 0));
|
||||
|
||||
if (IsTram() && m_new_td_bits == TRACKDIR_BIT_NONE) {
|
||||
/* GetTileTrackStatus() returns 0 for single tram bits.
|
||||
@@ -358,7 +359,18 @@ protected:
|
||||
RailType rail_type = GetTileRailTypeByEntryDir(m_new_tile, m_exitdir);
|
||||
if (!HasBit(m_railtypes, rail_type)) {
|
||||
/* incompatible rail type */
|
||||
m_err = EC_RAIL_TYPE;
|
||||
m_err = EC_RAIL_ROAD_TYPE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* road transport is possible only on compatible road types */
|
||||
if (IsRoadTT()) {
|
||||
const RoadVehicle *v = RoadVehicle::From(m_veh);
|
||||
RoadType roadtype = GetRoadType(m_new_tile, GetRoadTramType(v->roadtype));
|
||||
if (!HasBit(v->compatible_roadtypes, roadtype)) {
|
||||
/* incompatible road type */
|
||||
m_err = EC_RAIL_ROAD_TYPE;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -380,7 +392,7 @@ protected:
|
||||
return false;
|
||||
}
|
||||
if (!m_is_bridge && IsRoadTT() && IsRoadCustomBridgeHeadTile(m_new_tile)) {
|
||||
if (!(DiagDirToRoadBits(ReverseDiagDir(m_exitdir)) & GetCustomBridgeHeadRoadBits(m_new_tile, IsTram() ? ROADTYPE_TRAM : ROADTYPE_ROAD))) {
|
||||
if (!(DiagDirToRoadBits(ReverseDiagDir(m_exitdir)) & GetCustomBridgeHeadRoadBits(m_new_tile, IsTram() ? RTT_TRAM : RTT_ROAD))) {
|
||||
m_err = EC_NO_WAY;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ struct AyStarUserData {
|
||||
TransportType type;
|
||||
RailTypes railtypes;
|
||||
RoadTypes roadtypes;
|
||||
uint subtype;
|
||||
};
|
||||
|
||||
/** Indices into AyStarNode.userdata[] */
|
||||
@@ -726,7 +727,7 @@ static DiagDirection GetDepotDirection(TileIndex tile, TransportType type)
|
||||
static DiagDirection GetSingleTramBit(TileIndex tile)
|
||||
{
|
||||
if (IsNormalRoadTile(tile)) {
|
||||
RoadBits rb = GetRoadBits(tile, ROADTYPE_TRAM);
|
||||
RoadBits rb = GetRoadBits(tile, RTT_TRAM);
|
||||
switch (rb) {
|
||||
case ROAD_NW: return DIAGDIR_NW;
|
||||
case ROAD_SW: return DIAGDIR_SW;
|
||||
@@ -754,7 +755,7 @@ static DiagDirection GetTileSingleEntry(TileIndex tile, TransportType type, uint
|
||||
|
||||
if (type == TRANSPORT_ROAD) {
|
||||
if (IsStandardRoadStopTile(tile)) return GetRoadStopDir(tile);
|
||||
if (HasBit(subtype, ROADTYPE_TRAM)) return GetSingleTramBit(tile);
|
||||
if ((RoadTramType)subtype == RTT_TRAM) return GetSingleTramBit(tile);
|
||||
}
|
||||
|
||||
return INVALID_DIAGDIR;
|
||||
@@ -792,13 +793,24 @@ static bool CanEnterTile(TileIndex tile, DiagDirection dir, AyStarUserData *user
|
||||
if (!CanEnterTileOwnerCheck(user->owner, tile, dir)) return false;
|
||||
|
||||
/* check correct rail type (mono, maglev, etc) */
|
||||
if (user->type == TRANSPORT_RAIL) {
|
||||
RailType rail_type = GetTileRailTypeByEntryDir(tile, dir);
|
||||
if (!HasBit(user->railtypes, rail_type)) return false;
|
||||
switch (user->type) {
|
||||
case TRANSPORT_RAIL: {
|
||||
RailType rail_type = GetTileRailTypeByEntryDir(tile, dir);
|
||||
if (!HasBit(user->railtypes, rail_type)) return false;
|
||||
break;
|
||||
}
|
||||
|
||||
case TRANSPORT_ROAD: {
|
||||
RoadType road_type = GetRoadType(tile, (RoadTramType)user->subtype);
|
||||
if (!HasBit(user->roadtypes, road_type)) return false;
|
||||
break;
|
||||
}
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
/* Depots, standard roadstops and single tram bits can only be entered from one direction */
|
||||
DiagDirection single_entry = GetTileSingleEntry(tile, user->type, user->roadtypes);
|
||||
DiagDirection single_entry = GetTileSingleEntry(tile, user->type, user->subtype);
|
||||
if (single_entry != INVALID_DIAGDIR && single_entry != ReverseDiagDir(dir)) return false;
|
||||
|
||||
return true;
|
||||
@@ -820,7 +832,7 @@ static TrackdirBits GetDriveableTrackdirBits(TileIndex dst_tile, TileIndex src_t
|
||||
{
|
||||
TrackdirBits trackdirbits = TrackStatusToTrackdirBits(GetTileTrackStatus(dst_tile, type, subtype));
|
||||
|
||||
if (trackdirbits == TRACKDIR_BIT_NONE && type == TRANSPORT_ROAD && HasBit(subtype, ROADTYPE_TRAM)) {
|
||||
if (trackdirbits == TRACKDIR_BIT_NONE && type == TRANSPORT_ROAD && (RoadTramType)subtype == RTT_TRAM) {
|
||||
/* GetTileTrackStatus() returns 0 for single tram bits.
|
||||
* As we cannot change it there (easily) without breaking something, change it here */
|
||||
switch (GetSingleTramBit(dst_tile)) {
|
||||
@@ -870,7 +882,7 @@ static void NPFFollowTrack(AyStar *aystar, OpenListNode *current)
|
||||
|
||||
/* Information about the vehicle: TransportType (road/rail/water) and SubType (compatible rail/road types) */
|
||||
TransportType type = user->type;
|
||||
uint subtype = user->roadtypes;
|
||||
uint subtype = user->subtype;
|
||||
|
||||
/* Initialize to 0, so we can jump out (return) somewhere an have no neighbours */
|
||||
aystar->num_neighbours = 0;
|
||||
@@ -901,11 +913,11 @@ static void NPFFollowTrack(AyStar *aystar, OpenListNode *current)
|
||||
/* We leave src_tile in src_exitdir and reach dst_tile */
|
||||
dst_tile = AddTileIndexDiffCWrap(src_tile, TileIndexDiffCByDiagDir(src_exitdir));
|
||||
|
||||
if (dst_tile != INVALID_TILE && !CanEnterTile(dst_tile, src_exitdir, user)) dst_tile = INVALID_TILE;
|
||||
if (dst_tile != INVALID_TILE && IsNormalRoadTile(dst_tile) && !CanEnterTile(dst_tile, src_exitdir, user)) dst_tile = INVALID_TILE;
|
||||
|
||||
if (dst_tile == INVALID_TILE) {
|
||||
/* We cannot enter the next tile. Road vehicles can reverse, others reach dead end */
|
||||
if (type != TRANSPORT_ROAD || HasBit(subtype, ROADTYPE_TRAM)) return;
|
||||
if (type != TRANSPORT_ROAD || (RoadTramType)subtype == RTT_TRAM) return;
|
||||
|
||||
dst_tile = src_tile;
|
||||
src_trackdir = ReverseTrackdir(src_trackdir);
|
||||
@@ -915,7 +927,7 @@ static void NPFFollowTrack(AyStar *aystar, OpenListNode *current)
|
||||
|
||||
if (trackdirbits == TRACKDIR_BIT_NONE) {
|
||||
/* We cannot enter the next tile. Road vehicles can reverse, others reach dead end */
|
||||
if (type != TRANSPORT_ROAD || HasBit(subtype, ROADTYPE_TRAM)) return;
|
||||
if (type != TRANSPORT_ROAD || (RoadTramType)subtype == RTT_TRAM) return;
|
||||
|
||||
dst_tile = src_tile;
|
||||
src_trackdir = ReverseTrackdir(src_trackdir);
|
||||
@@ -1127,7 +1139,7 @@ FindDepotData NPFRoadVehicleFindNearestDepot(const RoadVehicle *v, int max_penal
|
||||
{
|
||||
Trackdir trackdir = v->GetVehicleTrackdir();
|
||||
|
||||
AyStarUserData user = { v->owner, TRANSPORT_ROAD, RAILTYPES_NONE, v->compatible_roadtypes };
|
||||
AyStarUserData user = { v->owner, TRANSPORT_ROAD, RAILTYPES_NONE, v->compatible_roadtypes, GetRoadTramType(v->roadtype) };
|
||||
NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, false, INVALID_TILE, INVALID_TRACKDIR, false, nullptr, &user, 0, max_penalty);
|
||||
|
||||
if (ftd.best_bird_dist != 0) return FindDepotData();
|
||||
@@ -1147,7 +1159,7 @@ Trackdir NPFRoadVehicleChooseTrack(const RoadVehicle *v, TileIndex tile, DiagDir
|
||||
NPFFillWithOrderData(&fstd, v);
|
||||
Trackdir trackdir = DiagDirToDiagTrackdir(enterdir);
|
||||
|
||||
AyStarUserData user = { v->owner, TRANSPORT_ROAD, RAILTYPES_NONE, v->compatible_roadtypes };
|
||||
AyStarUserData user = { v->owner, TRANSPORT_ROAD, RAILTYPES_NONE, v->compatible_roadtypes, GetRoadTramType(v->roadtype) };
|
||||
NPFFoundTargetData ftd = NPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, true, &fstd, &user);
|
||||
|
||||
assert(ftd.best_trackdir != INVALID_TRACKDIR);
|
||||
@@ -1170,7 +1182,7 @@ Track NPFShipChooseTrack(const Ship *v, bool &path_found)
|
||||
|
||||
NPFFillWithOrderData(&fstd, v);
|
||||
|
||||
AyStarUserData user = { v->owner, TRANSPORT_WATER, RAILTYPES_NONE, ROADTYPES_NONE };
|
||||
AyStarUserData user = { v->owner, TRANSPORT_WATER, RAILTYPES_NONE, ROADTYPES_NONE, 0 };
|
||||
NPFFoundTargetData ftd = NPFRouteToStationOrTile(v->tile, trackdir, true, &fstd, &user);
|
||||
|
||||
/* If ftd.best_bird_dist is 0, we found our target and ftd.best_trackdir contains
|
||||
@@ -1194,7 +1206,7 @@ bool NPFShipCheckReverse(const Ship *v)
|
||||
assert(trackdir != INVALID_TRACKDIR);
|
||||
assert(trackdir_rev != INVALID_TRACKDIR);
|
||||
|
||||
AyStarUserData user = { v->owner, TRANSPORT_WATER, RAILTYPES_NONE, ROADTYPES_NONE };
|
||||
AyStarUserData user = { v->owner, TRANSPORT_WATER, RAILTYPES_NONE, ROADTYPES_NONE, 0 };
|
||||
ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, false, v->tile, trackdir_rev, false, &fstd, &user);
|
||||
/* If we didn't find anything, just keep on going straight ahead, otherwise take the reverse flag */
|
||||
return ftd.best_bird_dist == 0 && NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE);
|
||||
@@ -1212,7 +1224,7 @@ FindDepotData NPFTrainFindNearestDepot(const Train *v, int max_penalty)
|
||||
fstd.reserve_path = false;
|
||||
|
||||
assert(trackdir != INVALID_TRACKDIR);
|
||||
AyStarUserData user = { v->owner, TRANSPORT_RAIL, v->compatible_railtypes, ROADTYPES_NONE };
|
||||
AyStarUserData user = { v->owner, TRANSPORT_RAIL, v->compatible_railtypes, ROADTYPES_NONE, 0 };
|
||||
NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, false, last->tile, trackdir_rev, false, &fstd, &user, NPF_INFINITE_PENALTY, max_penalty);
|
||||
if (ftd.best_bird_dist != 0) return FindDepotData();
|
||||
|
||||
@@ -1241,7 +1253,7 @@ bool NPFTrainFindNearestSafeTile(const Train *v, TileIndex tile, Trackdir trackd
|
||||
|
||||
/* perform a breadth first search. Target is nullptr,
|
||||
* since we are just looking for any safe tile...*/
|
||||
AyStarUserData user = { v->owner, TRANSPORT_RAIL, railtypes, ROADTYPES_NONE };
|
||||
AyStarUserData user = { v->owner, TRANSPORT_RAIL, railtypes, ROADTYPES_NONE, 0 };
|
||||
return NPFRouteInternal(&start1, true, nullptr, false, &fstd, NPFFindSafeTile, NPFCalcZero, &user, 0, true).res_okay;
|
||||
}
|
||||
|
||||
@@ -1258,7 +1270,7 @@ bool NPFTrainCheckReverse(const Train *v)
|
||||
assert(trackdir != INVALID_TRACKDIR);
|
||||
assert(trackdir_rev != INVALID_TRACKDIR);
|
||||
|
||||
AyStarUserData user = { v->owner, TRANSPORT_RAIL, v->compatible_railtypes, ROADTYPES_NONE };
|
||||
AyStarUserData user = { v->owner, TRANSPORT_RAIL, v->compatible_railtypes, ROADTYPES_NONE, 0 };
|
||||
ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, false, last->tile, trackdir_rev, false, &fstd, &user);
|
||||
/* If we didn't find anything, just keep on going straight ahead, otherwise take the reverse flag */
|
||||
return ftd.best_bird_dist == 0 && NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE);
|
||||
@@ -1272,7 +1284,7 @@ Track NPFTrainChooseTrack(const Train *v, bool &path_found, bool reserve_track,
|
||||
PBSTileInfo origin = FollowTrainReservation(v);
|
||||
assert(IsValidTrackdir(origin.trackdir));
|
||||
|
||||
AyStarUserData user = { v->owner, TRANSPORT_RAIL, v->compatible_railtypes, ROADTYPES_NONE };
|
||||
AyStarUserData user = { v->owner, TRANSPORT_RAIL, v->compatible_railtypes, ROADTYPES_NONE, 0 };
|
||||
NPFFoundTargetData ftd = NPFRouteToStationOrTile(origin.tile, origin.trackdir, true, &fstd, &user);
|
||||
|
||||
if (target != nullptr) {
|
||||
|
||||
@@ -652,7 +652,7 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th
|
||||
if (!tf_local.Follow(cur.tile, cur.td)) {
|
||||
assert(tf_local.m_err != TrackFollower::EC_NONE);
|
||||
/* Can't move to the next tile (EOL?). */
|
||||
if (tf_local.m_err == TrackFollower::EC_RAIL_TYPE) {
|
||||
if (tf_local.m_err == TrackFollower::EC_RAIL_ROAD_TYPE) {
|
||||
end_segment_reason |= ESRB_RAIL_TYPE;
|
||||
} else {
|
||||
end_segment_reason |= ESRB_DEAD_END;
|
||||
|
||||
@@ -263,7 +263,7 @@ public:
|
||||
} else {
|
||||
m_dest_station = INVALID_STATION;
|
||||
m_destTile = v->dest_tile;
|
||||
m_destTrackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_ROAD, v->compatible_roadtypes));
|
||||
m_destTrackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_ROAD, GetRoadTramType(v->roadtype)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,7 +386,7 @@ public:
|
||||
/* our source tile will be the next vehicle tile (should be the given one) */
|
||||
TileIndex src_tile = tile;
|
||||
/* get available trackdirs on the start tile */
|
||||
TrackdirBits src_trackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_ROAD, v->compatible_roadtypes));
|
||||
TrackdirBits src_trackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_ROAD, GetRoadTramType(v->roadtype)));
|
||||
/* select reachable trackdirs only */
|
||||
src_trackdirs &= DiagdirReachesTrackdirs(enterdir);
|
||||
|
||||
@@ -485,7 +485,7 @@ public:
|
||||
/* set origin (tile, trackdir) */
|
||||
TileIndex src_tile = v->tile;
|
||||
Trackdir src_td = v->GetVehicleTrackdir();
|
||||
if (!HasTrackdir(TrackStatusToTrackdirBits(GetTileTrackStatus(src_tile, TRANSPORT_ROAD, v->compatible_roadtypes)), src_td)) {
|
||||
if (!HasTrackdir(TrackStatusToTrackdirBits(GetTileTrackStatus(src_tile, TRANSPORT_ROAD, this->IsTram() ? RTT_TRAM : RTT_ROAD)), src_td)) {
|
||||
/* sometimes the roadveh is not on the road (it resides on non-existing track)
|
||||
* how should we handle that situation? */
|
||||
return false;
|
||||
@@ -565,7 +565,7 @@ FindDepotData YapfRoadVehicleFindNearestDepot(const RoadVehicle *v, int max_dist
|
||||
{
|
||||
TileIndex tile = v->tile;
|
||||
Trackdir trackdir = v->GetVehicleTrackdir();
|
||||
if (!HasTrackdir(TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_ROAD, v->compatible_roadtypes)), trackdir)) {
|
||||
if (!HasTrackdir(TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_ROAD, GetRoadTramType(v->roadtype))), trackdir)) {
|
||||
return FindDepotData();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user