Add setting to control RV re-routing on road layout change

Default to road removal only
This is due to poor performance with many RVs when town growth is
continually adding to the road layout
This commit is contained in:
Jonathan G Rennison
2020-07-02 17:47:26 +01:00
parent 903b0fdd39
commit d5ada6a14b
8 changed files with 66 additions and 26 deletions

View File

@@ -1939,6 +1939,12 @@ STR_CONFIG_SETTING_SHARING :{ORANGE}Infrast
STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_NPF :NPF
STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Recommended) STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Recommended)
STR_CONFIG_SETTING_REROUTE_RV_ON_LAYOUT_CHANGE :Re-route road vehicles when road layout changes: {STRING2}
STR_CONFIG_SETTING_REROUTE_RV_ON_LAYOUT_CHANGE_HELPTEXT :Whether to re-route all road vehicles on the map when the road layout is changed.{}This can improve road vehicle responsiveness to a changing roa dlayout at the expense of performance.{}Note that if this is set to "Yes", town growth can trigger re-routing of road vehicles which may cause slow-downs on large maps.
STR_CONFIG_SETTING_REROUTE_RV_ON_LAYOUT_CHANGE_NO :No
STR_CONFIG_SETTING_REROUTE_RV_ON_LAYOUT_CHANGE_REMOVE_ONLY :Road removal only
STR_CONFIG_SETTING_REROUTE_RV_ON_LAYOUT_CHANGE_YES :Yes
STR_CONFIG_SETTING_PATHFINDER_FOR_TRAINS :Pathfinder for trains: {STRING2} STR_CONFIG_SETTING_PATHFINDER_FOR_TRAINS :Pathfinder for trains: {STRING2}
STR_CONFIG_SETTING_PATHFINDER_FOR_TRAINS_HELPTEXT :Path finder to use for trains STR_CONFIG_SETTING_PATHFINDER_FOR_TRAINS_HELPTEXT :Path finder to use for trains
STR_CONFIG_SETTING_PATHFINDER_FOR_ROAD_VEHICLES :Pathfinder for road vehicles: {STRING2} STR_CONFIG_SETTING_PATHFINDER_FOR_ROAD_VEHICLES :Pathfinder for road vehicles: {STRING2}

View File

@@ -467,7 +467,7 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec
DirtyAllCompanyInfrastructureWindows(); DirtyAllCompanyInfrastructureWindows();
/* Todo: Change this to be more fine-grained if necessary */ /* Todo: Change this to be more fine-grained if necessary */
NotifyRoadLayoutChanged(); NotifyRoadLayoutChanged(false);
} }
} else { } else {
assert_tile(IsDriveThroughStopTile(tile), tile); assert_tile(IsDriveThroughStopTile(tile), tile);
@@ -477,7 +477,7 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec
UpdateCompanyRoadInfrastructure(existing_rt, GetRoadOwner(tile, rtt), -2); UpdateCompanyRoadInfrastructure(existing_rt, GetRoadOwner(tile, rtt), -2);
SetRoadType(tile, rtt, INVALID_ROADTYPE); SetRoadType(tile, rtt, INVALID_ROADTYPE);
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile);
NotifyRoadLayoutChanged(); NotifyRoadLayoutChanged(false);
} }
} }
return cost; return cost;
@@ -530,7 +530,7 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec
} }
} }
NotifyRoadLayoutChangedIfTileNonLeaf(tile, rtt, present | pieces); if (RoadLayoutChangeNotificationEnabled(false)) NotifyRoadLayoutChangedIfTileNonLeaf(tile, rtt, present | pieces);
UpdateCompanyRoadInfrastructure(existing_rt, GetRoadOwner(tile, rtt), -(int)CountBits(pieces)); UpdateCompanyRoadInfrastructure(existing_rt, GetRoadOwner(tile, rtt), -(int)CountBits(pieces));
if (present == ROAD_NONE) { if (present == ROAD_NONE) {
@@ -575,7 +575,7 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec
UpdateCompanyRoadInfrastructure(existing_rt, GetRoadOwner(tile, rtt), -2); UpdateCompanyRoadInfrastructure(existing_rt, GetRoadOwner(tile, rtt), -2);
Track railtrack = GetCrossingRailTrack(tile); Track railtrack = GetCrossingRailTrack(tile);
NotifyRoadLayoutChangedIfTileNonLeaf(tile, rtt, GetCrossingRoadBits(tile)); if (RoadLayoutChangeNotificationEnabled(false)) NotifyRoadLayoutChangedIfTileNonLeaf(tile, rtt, GetCrossingRoadBits(tile));
if (GetRoadType(tile, OtherRoadTramType(rtt)) == INVALID_ROADTYPE) { if (GetRoadType(tile, OtherRoadTramType(rtt)) == INVALID_ROADTYPE) {
TrackBits tracks = GetCrossingRailBits(tile); TrackBits tracks = GetCrossingRailBits(tile);
bool reserved = HasCrossingReservation(tile); bool reserved = HasCrossingReservation(tile);
@@ -860,7 +860,7 @@ CommandCost CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
MakeRoadCrossing(tile, company, company, GetTileOwner(tile), roaddir, GetRailType(tile), rtt == RTT_ROAD ? rt : INVALID_ROADTYPE, (rtt == RTT_TRAM) ? rt : INVALID_ROADTYPE, p2); MakeRoadCrossing(tile, company, company, GetTileOwner(tile), roaddir, GetRailType(tile), rtt == RTT_ROAD ? rt : INVALID_ROADTYPE, (rtt == RTT_TRAM) ? rt : INVALID_ROADTYPE, p2);
SetCrossingReservation(tile, reserved); SetCrossingReservation(tile, reserved);
UpdateLevelCrossing(tile, false); UpdateLevelCrossing(tile, false);
NotifyRoadLayoutChangedIfTileNonLeaf(tile, rtt, GetCrossingRoadBits(tile)); if (RoadLayoutChangeNotificationEnabled(true)) NotifyRoadLayoutChangedIfTileNonLeaf(tile, rtt, GetCrossingRoadBits(tile));
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile);
} }
return CommandCost(EXPENSES_CONSTRUCTION, 2 * RoadBuildCost(rt)); return CommandCost(EXPENSES_CONSTRUCTION, 2 * RoadBuildCost(rt));
@@ -991,7 +991,7 @@ CommandCost CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
MarkBridgeDirty(tile); MarkBridgeDirty(tile);
AddRoadTunnelBridgeInfrastructure(tile, other_end); AddRoadTunnelBridgeInfrastructure(tile, other_end);
NotifyRoadLayoutChanged(); NotifyRoadLayoutChanged(true);
DirtyAllCompanyInfrastructureWindows(); DirtyAllCompanyInfrastructureWindows();
} }
@@ -1089,7 +1089,7 @@ do_clear:;
if (rtt == RTT_ROAD) SetTownIndex(tile, p2); if (rtt == RTT_ROAD) SetTownIndex(tile, p2);
} }
if (rttype != ROAD_TILE_CROSSING) SetRoadBits(tile, existing | pieces, rtt); if (rttype != ROAD_TILE_CROSSING) SetRoadBits(tile, existing | pieces, rtt);
NotifyRoadLayoutChangedIfTileNonLeaf(tile, rtt, existing | pieces); if (RoadLayoutChangeNotificationEnabled(true)) NotifyRoadLayoutChangedIfTileNonLeaf(tile, rtt, existing | pieces);
break; break;
} }
@@ -1108,7 +1108,7 @@ do_clear:;
MarkTileDirtyByTile(other_end); MarkTileDirtyByTile(other_end);
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile);
} }
NotifyRoadLayoutChanged(); NotifyRoadLayoutChanged(true);
break; break;
} }
@@ -1116,13 +1116,13 @@ do_clear:;
assert_tile(IsDriveThroughStopTile(tile), tile); assert_tile(IsDriveThroughStopTile(tile), tile);
SetRoadType(tile, rtt, rt); SetRoadType(tile, rtt, rt);
SetRoadOwner(tile, rtt, company); SetRoadOwner(tile, rtt, company);
NotifyRoadLayoutChanged(); NotifyRoadLayoutChanged(true);
break; break;
} }
default: default:
MakeRoadNormal(tile, pieces, (rtt == RTT_ROAD) ? rt : INVALID_ROADTYPE, (rtt == RTT_TRAM) ? rt : INVALID_ROADTYPE, p2, company, company); MakeRoadNormal(tile, pieces, (rtt == RTT_ROAD) ? rt : INVALID_ROADTYPE, (rtt == RTT_TRAM) ? rt : INVALID_ROADTYPE, p2, company, company);
NotifyRoadLayoutChangedIfTileNonLeaf(tile, rtt, pieces); if (RoadLayoutChangeNotificationEnabled(true)) NotifyRoadLayoutChangedIfTileNonLeaf(tile, rtt, pieces);
break; break;
} }
@@ -1387,7 +1387,7 @@ CommandCost CmdBuildRoadDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, ui
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile);
MakeDefaultName(dep); MakeDefaultName(dep);
NotifyRoadLayoutChanged(); NotifyRoadLayoutChanged(true);
} }
cost.AddCost(_price[PR_BUILD_DEPOT_ROAD]); cost.AddCost(_price[PR_BUILD_DEPOT_ROAD]);
return cost; return cost;
@@ -1416,7 +1416,7 @@ static CommandCost RemoveRoadDepot(TileIndex tile, DoCommandFlag flags)
delete Depot::GetByTile(tile); delete Depot::GetByTile(tile);
DoClearSquare(tile); DoClearSquare(tile);
NotifyRoadLayoutChanged(); NotifyRoadLayoutChanged(false);
} }
return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_DEPOT_ROAD]); return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_DEPOT_ROAD]);

View File

@@ -14,6 +14,7 @@
#include "road.h" #include "road.h"
#include "economy_func.h" #include "economy_func.h"
#include "transparency.h" #include "transparency.h"
#include "settings_type.h"
/** /**
* Whether the given roadtype is valid. * Whether the given roadtype is valid.
@@ -160,11 +161,21 @@ void UpdateCompanyRoadInfrastructure(RoadType rt, Owner o, int count);
struct TileInfo; struct TileInfo;
void DrawRoadOverlays(const TileInfo *ti, PaletteID pal, const RoadTypeInfo *road_rti, const RoadTypeInfo *tram_rit, uint road_offset, uint tram_offset); void DrawRoadOverlays(const TileInfo *ti, PaletteID pal, const RoadTypeInfo *road_rti, const RoadTypeInfo *tram_rit, uint road_offset, uint tram_offset);
inline bool RoadLayoutChangeNotificationEnabled(bool added)
{
return _settings_game.pf.reroute_rv_on_layout_change >= (added ? 2 : 1);
}
inline void NotifyRoadLayoutChanged() inline void NotifyRoadLayoutChanged()
{ {
_road_layout_change_counter++; _road_layout_change_counter++;
} }
inline void NotifyRoadLayoutChanged(bool added)
{
if (RoadLayoutChangeNotificationEnabled(added)) NotifyRoadLayoutChanged();
}
void NotifyRoadLayoutChangedIfTileNonLeaf(TileIndex tile, RoadTramType rtt, RoadBits present_bits); void NotifyRoadLayoutChangedIfTileNonLeaf(TileIndex tile, RoadTramType rtt, RoadBits present_bits);
void NotifyRoadLayoutChangedIfSimpleTunnelBridgeNonLeaf(TileIndex start, TileIndex end, DiagDirection start_dir, RoadTramType rtt); void NotifyRoadLayoutChangedIfSimpleTunnelBridgeNonLeaf(TileIndex start, TileIndex end, DiagDirection start_dir, RoadTramType rtt);

View File

@@ -1826,6 +1826,7 @@ static SettingsContainer &GetSettingsTree()
routing->Add(new SettingEntry("pf.forbid_90_deg")); routing->Add(new SettingEntry("pf.forbid_90_deg"));
routing->Add(new SettingEntry("pf.pathfinder_for_roadvehs")); routing->Add(new SettingEntry("pf.pathfinder_for_roadvehs"));
routing->Add(new SettingEntry("pf.pathfinder_for_ships")); routing->Add(new SettingEntry("pf.pathfinder_for_ships"));
routing->Add(new SettingEntry("pf.reroute_rv_on_layout_change"));
} }
vehicles->Add(new SettingEntry("order.no_servicing_if_no_breakdowns")); vehicles->Add(new SettingEntry("order.no_servicing_if_no_breakdowns"));

View File

@@ -495,6 +495,7 @@ struct PathfinderSettings {
bool roadveh_queue; ///< buggy road vehicle queueing bool roadveh_queue; ///< buggy road vehicle queueing
bool forbid_90_deg; ///< forbid trains to make 90 deg turns bool forbid_90_deg; ///< forbid trains to make 90 deg turns
uint8 reroute_rv_on_layout_change; ///< whether to re-route road vehicles when the layout changes
bool reverse_at_signals; ///< whether to reverse at signals at all bool reverse_at_signals; ///< whether to reverse at signals at all
byte wait_oneway_signal; ///< waitingtime in days before a oneway signal byte wait_oneway_signal; ///< waitingtime in days before a oneway signal

View File

@@ -2078,7 +2078,7 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
MarkTileDirtyByTile(cur_tile); MarkTileDirtyByTile(cur_tile);
} }
ZoningMarkDirtyStationCoverageArea(st); ZoningMarkDirtyStationCoverageArea(st);
NotifyRoadLayoutChanged(); NotifyRoadLayoutChanged(true);
} }
if (st != nullptr) { if (st != nullptr) {
@@ -2196,7 +2196,7 @@ static CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags)
for (const RoadStop *rs = st->bus_stops; rs != nullptr; rs = rs->next) st->bus_station.Add(rs->xy); for (const RoadStop *rs = st->bus_stops; rs != nullptr; rs = rs->next) st->bus_station.Add(rs->xy);
} }
NotifyRoadLayoutChanged(); NotifyRoadLayoutChanged(false);
} }
return CommandCost(EXPENSES_CONSTRUCTION, _price[is_truck ? PR_CLEAR_STATION_TRUCK : PR_CLEAR_STATION_BUS]); return CommandCost(EXPENSES_CONSTRUCTION, _price[is_truck ? PR_CLEAR_STATION_TRUCK : PR_CLEAR_STATION_BUS]);

View File

@@ -1293,6 +1293,21 @@ var = pf.roadveh_queue
def = true def = true
cat = SC_EXPERT cat = SC_EXPERT
[SDT_VAR]
base = GameSettings
var = pf.reroute_rv_on_layout_change
type = SLE_UINT8
guiflags = SGF_MULTISTRING
def = 1
min = 0
max = 2
interval = 1
str = STR_CONFIG_SETTING_REROUTE_RV_ON_LAYOUT_CHANGE
strhelp = STR_CONFIG_SETTING_REROUTE_RV_ON_LAYOUT_CHANGE_HELPTEXT
strval = STR_CONFIG_SETTING_REROUTE_RV_ON_LAYOUT_CHANGE_NO
cat = SC_ADVANCED
patxname = ""pf.reroute_rv_on_layout_change""
[SDT_BOOL] [SDT_BOOL]
base = GameSettings base = GameSettings
var = pf.new_pathfinding_all var = pf.new_pathfinding_all

View File

@@ -648,11 +648,13 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u
make_bridge_ramp(tile_start, dir); make_bridge_ramp(tile_start, dir);
make_bridge_ramp(tile_end, ReverseDiagDir(dir)); make_bridge_ramp(tile_end, ReverseDiagDir(dir));
AddRoadTunnelBridgeInfrastructure(tile_start, tile_end); AddRoadTunnelBridgeInfrastructure(tile_start, tile_end);
if (RoadLayoutChangeNotificationEnabled(true)) {
if (IsRoadCustomBridgeHead(tile_start) || IsRoadCustomBridgeHead(tile_end)) { if (IsRoadCustomBridgeHead(tile_start) || IsRoadCustomBridgeHead(tile_end)) {
NotifyRoadLayoutChanged(); NotifyRoadLayoutChanged();
} else { } else {
NotifyRoadLayoutChangedIfSimpleTunnelBridgeNonLeaf(tile_start, tile_end, dir, GetRoadTramType(roadtype)); NotifyRoadLayoutChangedIfSimpleTunnelBridgeNonLeaf(tile_start, tile_end, dir, GetRoadTramType(roadtype));
} }
}
break; break;
} }
@@ -1011,7 +1013,7 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1,
YapfNotifyTrackLayoutChange(start_tile, DiagDirToDiagTrack(direction)); YapfNotifyTrackLayoutChange(start_tile, DiagDirToDiagTrack(direction));
} else { } else {
if (c != nullptr) c->infrastructure.road[roadtype] += num_pieces * 2; // A full diagonal road has two road bits. if (c != nullptr) c->infrastructure.road[roadtype] += num_pieces * 2; // A full diagonal road has two road bits.
NotifyRoadLayoutChangedIfSimpleTunnelBridgeNonLeaf(start_tile, end_tile, direction, GetRoadTramType(roadtype)); if (RoadLayoutChangeNotificationEnabled(true)) NotifyRoadLayoutChangedIfSimpleTunnelBridgeNonLeaf(start_tile, end_tile, direction, GetRoadTramType(roadtype));
RoadType road_rt = RoadTypeIsRoad(roadtype) ? roadtype : INVALID_ROADTYPE; RoadType road_rt = RoadTypeIsRoad(roadtype) ? roadtype : INVALID_ROADTYPE;
RoadType tram_rt = RoadTypeIsTram(roadtype) ? roadtype : INVALID_ROADTYPE; RoadType tram_rt = RoadTypeIsTram(roadtype) ? roadtype : INVALID_ROADTYPE;
MakeRoadTunnel(start_tile, company, t->index, direction, road_rt, tram_rt); MakeRoadTunnel(start_tile, company, t->index, direction, road_rt, tram_rt);
@@ -1148,8 +1150,10 @@ static CommandCost DoClearTunnel(TileIndex tile, DoCommandFlag flags)
/* A full diagonal road tile has two road bits. */ /* A full diagonal road tile has two road bits. */
UpdateCompanyRoadInfrastructure(GetRoadTypeRoad(tile), GetRoadOwner(tile, RTT_ROAD), -(int)(len * 2 * TUNNELBRIDGE_TRACKBIT_FACTOR)); UpdateCompanyRoadInfrastructure(GetRoadTypeRoad(tile), GetRoadOwner(tile, RTT_ROAD), -(int)(len * 2 * TUNNELBRIDGE_TRACKBIT_FACTOR));
UpdateCompanyRoadInfrastructure(GetRoadTypeTram(tile), GetRoadOwner(tile, RTT_TRAM), -(int)(len * 2 * TUNNELBRIDGE_TRACKBIT_FACTOR)); UpdateCompanyRoadInfrastructure(GetRoadTypeTram(tile), GetRoadOwner(tile, RTT_TRAM), -(int)(len * 2 * TUNNELBRIDGE_TRACKBIT_FACTOR));
if (RoadLayoutChangeNotificationEnabled(false)) {
NotifyRoadLayoutChangedIfSimpleTunnelBridgeNonLeaf(tile, endtile, GetTunnelBridgeDirection(tile), RTT_ROAD); NotifyRoadLayoutChangedIfSimpleTunnelBridgeNonLeaf(tile, endtile, GetTunnelBridgeDirection(tile), RTT_ROAD);
NotifyRoadLayoutChangedIfSimpleTunnelBridgeNonLeaf(tile, endtile, GetTunnelBridgeDirection(tile), RTT_TRAM); NotifyRoadLayoutChangedIfSimpleTunnelBridgeNonLeaf(tile, endtile, GetTunnelBridgeDirection(tile), RTT_TRAM);
}
delete Tunnel::GetByTile(tile); delete Tunnel::GetByTile(tile);
@@ -1246,12 +1250,14 @@ static CommandCost DoClearBridge(TileIndex tile, DoCommandFlag flags)
SubtractRailTunnelBridgeInfrastructure(tile, endtile); SubtractRailTunnelBridgeInfrastructure(tile, endtile);
} else if (GetTunnelBridgeTransportType(tile) == TRANSPORT_ROAD) { } else if (GetTunnelBridgeTransportType(tile) == TRANSPORT_ROAD) {
SubtractRoadTunnelBridgeInfrastructure(tile, endtile); SubtractRoadTunnelBridgeInfrastructure(tile, endtile);
if (RoadLayoutChangeNotificationEnabled(false)) {
if (IsRoadCustomBridgeHead(tile) || IsRoadCustomBridgeHead(endtile)) { if (IsRoadCustomBridgeHead(tile) || IsRoadCustomBridgeHead(endtile)) {
NotifyRoadLayoutChanged(); NotifyRoadLayoutChanged();
} else { } else {
if (HasRoadTypeRoad(tile)) NotifyRoadLayoutChangedIfSimpleTunnelBridgeNonLeaf(tile, endtile, direction, RTT_ROAD); if (HasRoadTypeRoad(tile)) NotifyRoadLayoutChangedIfSimpleTunnelBridgeNonLeaf(tile, endtile, direction, RTT_ROAD);
if (HasRoadTypeTram(tile)) NotifyRoadLayoutChangedIfSimpleTunnelBridgeNonLeaf(tile, endtile, direction, RTT_TRAM); if (HasRoadTypeTram(tile)) NotifyRoadLayoutChangedIfSimpleTunnelBridgeNonLeaf(tile, endtile, direction, RTT_TRAM);
} }
}
} else { // Aqueduct } else { // Aqueduct
if (Company::IsValidID(owner)) Company::Get(owner)->infrastructure.water -= len * TUNNELBRIDGE_TRACKBIT_FACTOR; if (Company::IsValidID(owner)) Company::Get(owner)->infrastructure.water -= len * TUNNELBRIDGE_TRACKBIT_FACTOR;
removetile = IsDockingTile(tile); removetile = IsDockingTile(tile);