Feature: [Linkgraph] Prioritize faster routes for passengers, mail and express cargo
Passengers usually prefer fast paths to short paths.
Average travel times of links are updated in real-time for use in Dijkstra's algorithm,
and newer travel times weigh more, just like capacities.
(cherry picked from commit 977604ef08
)
This commit is contained in:

committed by
Jonathan G Rennison

parent
1518c2fa1e
commit
a43a1902bb
@@ -39,6 +39,7 @@ inline void LinkGraph::BaseEdge::Init()
|
|||||||
{
|
{
|
||||||
this->capacity = 0;
|
this->capacity = 0;
|
||||||
this->usage = 0;
|
this->usage = 0;
|
||||||
|
this->travel_time_sum = 0;
|
||||||
this->last_unrestricted_update = INVALID_DATE;
|
this->last_unrestricted_update = INVALID_DATE;
|
||||||
this->last_restricted_update = INVALID_DATE;
|
this->last_restricted_update = INVALID_DATE;
|
||||||
this->last_aircraft_update = INVALID_DATE;
|
this->last_aircraft_update = INVALID_DATE;
|
||||||
@@ -75,6 +76,7 @@ void LinkGraph::Compress()
|
|||||||
if (edge.capacity > 0) {
|
if (edge.capacity > 0) {
|
||||||
edge.capacity = std::max(1U, edge.capacity / 2);
|
edge.capacity = std::max(1U, edge.capacity / 2);
|
||||||
edge.usage /= 2;
|
edge.usage /= 2;
|
||||||
|
edge.travel_time_sum = std::max(1ULL, edge.travel_time_sum / 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,9 +104,11 @@ void LinkGraph::Merge(LinkGraph *other)
|
|||||||
backward = other->edges[node2][node1];
|
backward = other->edges[node2][node1];
|
||||||
forward.capacity = LinkGraph::Scale(forward.capacity, age, other_age);
|
forward.capacity = LinkGraph::Scale(forward.capacity, age, other_age);
|
||||||
forward.usage = LinkGraph::Scale(forward.usage, age, other_age);
|
forward.usage = LinkGraph::Scale(forward.usage, age, other_age);
|
||||||
|
forward.travel_time_sum = LinkGraph::Scale(forward.travel_time_sum, age, other_age);
|
||||||
if (forward.next_edge != INVALID_NODE) forward.next_edge += first;
|
if (forward.next_edge != INVALID_NODE) forward.next_edge += first;
|
||||||
backward.capacity = LinkGraph::Scale(backward.capacity, age, other_age);
|
backward.capacity = LinkGraph::Scale(backward.capacity, age, other_age);
|
||||||
backward.usage = LinkGraph::Scale(backward.usage, age, other_age);
|
backward.usage = LinkGraph::Scale(backward.usage, age, other_age);
|
||||||
|
backward.travel_time_sum = LinkGraph::Scale(backward.travel_time_sum, age, other_age);
|
||||||
if (backward.next_edge != INVALID_NODE) backward.next_edge += first;
|
if (backward.next_edge != INVALID_NODE) backward.next_edge += first;
|
||||||
}
|
}
|
||||||
BaseEdge &new_start = this->edges[new_node][new_node];
|
BaseEdge &new_start = this->edges[new_node][new_node];
|
||||||
@@ -190,13 +194,14 @@ NodeID LinkGraph::AddNode(const Station *st)
|
|||||||
* @param usage Usage to be added.
|
* @param usage Usage to be added.
|
||||||
* @param mode Update mode to be used.
|
* @param mode Update mode to be used.
|
||||||
*/
|
*/
|
||||||
void LinkGraph::Node::AddEdge(NodeID to, uint capacity, uint usage, EdgeUpdateMode mode)
|
void LinkGraph::Node::AddEdge(NodeID to, uint capacity, uint usage, uint32 travel_time, EdgeUpdateMode mode)
|
||||||
{
|
{
|
||||||
assert(this->index != to);
|
assert(this->index != to);
|
||||||
BaseEdge &edge = this->edges[to];
|
BaseEdge &edge = this->edges[to];
|
||||||
BaseEdge &first = this->edges[this->index];
|
BaseEdge &first = this->edges[this->index];
|
||||||
edge.capacity = capacity;
|
edge.capacity = capacity;
|
||||||
edge.usage = usage;
|
edge.usage = usage;
|
||||||
|
edge.travel_time_sum = travel_time * capacity;
|
||||||
edge.next_edge = first.next_edge;
|
edge.next_edge = first.next_edge;
|
||||||
first.next_edge = to;
|
first.next_edge = to;
|
||||||
if (mode & EUM_UNRESTRICTED) edge.last_unrestricted_update = _date;
|
if (mode & EUM_UNRESTRICTED) edge.last_unrestricted_update = _date;
|
||||||
@@ -211,14 +216,14 @@ void LinkGraph::Node::AddEdge(NodeID to, uint capacity, uint usage, EdgeUpdateMo
|
|||||||
* @param usage Usage to be added.
|
* @param usage Usage to be added.
|
||||||
* @param mode Update mode to be used.
|
* @param mode Update mode to be used.
|
||||||
*/
|
*/
|
||||||
void LinkGraph::Node::UpdateEdge(NodeID to, uint capacity, uint usage, EdgeUpdateMode mode)
|
void LinkGraph::Node::UpdateEdge(NodeID to, uint capacity, uint usage, uint32 travel_time, EdgeUpdateMode mode)
|
||||||
{
|
{
|
||||||
assert(capacity > 0);
|
assert(capacity > 0);
|
||||||
assert(usage <= capacity);
|
assert(usage <= capacity);
|
||||||
if (this->edges[to].capacity == 0) {
|
if (this->edges[to].capacity == 0) {
|
||||||
this->AddEdge(to, capacity, usage, mode);
|
this->AddEdge(to, capacity, usage, travel_time, mode);
|
||||||
} else {
|
} else {
|
||||||
(*this)[to].Update(capacity, usage, mode);
|
(*this)[to].Update(capacity, usage, travel_time, mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -235,6 +240,7 @@ void LinkGraph::Node::RemoveEdge(NodeID to)
|
|||||||
edge.last_restricted_update = INVALID_DATE;
|
edge.last_restricted_update = INVALID_DATE;
|
||||||
edge.last_aircraft_update = INVALID_DATE;
|
edge.last_aircraft_update = INVALID_DATE;
|
||||||
edge.usage = 0;
|
edge.usage = 0;
|
||||||
|
edge.travel_time_sum = 0;
|
||||||
|
|
||||||
NodeID prev = this->index;
|
NodeID prev = this->index;
|
||||||
NodeID next = this->edges[this->index].next_edge;
|
NodeID next = this->edges[this->index].next_edge;
|
||||||
@@ -253,23 +259,39 @@ void LinkGraph::Node::RemoveEdge(NodeID to)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Update an edge. If mode contains UM_REFRESH refresh the edge to have at
|
* Update an edge. If mode contains UM_REFRESH refresh the edge to have at
|
||||||
* least the given capacity and usage, otherwise add the capacity and usage.
|
* least the given capacity and usage, otherwise add the capacity, usage and travel time.
|
||||||
* In any case set the respective update timestamp(s), according to the given
|
* In any case set the respective update timestamp(s), according to the given
|
||||||
* mode.
|
* mode.
|
||||||
* @param capacity Capacity to be added/updated.
|
* @param capacity Capacity to be added/updated.
|
||||||
* @param usage Usage to be added.
|
* @param usage Usage to be added.
|
||||||
|
* @param travel_time Travel time to be added, in ticks.
|
||||||
* @param mode Update mode to be applied.
|
* @param mode Update mode to be applied.
|
||||||
*/
|
*/
|
||||||
void LinkGraph::Edge::Update(uint capacity, uint usage, EdgeUpdateMode mode)
|
void LinkGraph::Edge::Update(uint capacity, uint usage, uint32 travel_time, EdgeUpdateMode mode)
|
||||||
{
|
{
|
||||||
assert(this->edge.capacity > 0);
|
assert(this->edge.capacity > 0);
|
||||||
assert(capacity >= usage);
|
assert(capacity >= usage);
|
||||||
|
|
||||||
if (mode & EUM_INCREASE) {
|
if (mode & EUM_INCREASE) {
|
||||||
|
if (this->edge.travel_time_sum == 0) {
|
||||||
|
this->edge.travel_time_sum = (this->edge.capacity + capacity) * travel_time;
|
||||||
|
} else if (travel_time == 0) {
|
||||||
|
this->edge.travel_time_sum += this->edge.travel_time_sum / this->edge.capacity * capacity;
|
||||||
|
} else {
|
||||||
|
this->edge.travel_time_sum += travel_time * capacity;
|
||||||
|
}
|
||||||
this->edge.capacity += capacity;
|
this->edge.capacity += capacity;
|
||||||
this->edge.usage += usage;
|
this->edge.usage += usage;
|
||||||
} else if (mode & EUM_REFRESH) {
|
} else if (mode & EUM_REFRESH) {
|
||||||
|
/* If travel time is not provided, we scale the stored time based on
|
||||||
|
* the capacity increase. */
|
||||||
|
if (capacity > this->edge.capacity && travel_time == 0) {
|
||||||
|
this->edge.travel_time_sum = this->edge.travel_time_sum / this->edge.capacity * capacity;
|
||||||
|
this->edge.capacity = capacity;
|
||||||
|
} else {
|
||||||
this->edge.capacity = std::max(this->edge.capacity, capacity);
|
this->edge.capacity = std::max(this->edge.capacity, capacity);
|
||||||
|
this->edge.travel_time_sum = std::max<uint64>(this->edge.travel_time_sum, travel_time * capacity);
|
||||||
|
}
|
||||||
this->edge.usage = std::max(this->edge.usage, usage);
|
this->edge.usage = std::max(this->edge.usage, usage);
|
||||||
}
|
}
|
||||||
if (mode & EUM_UNRESTRICTED) this->edge.last_unrestricted_update = _date;
|
if (mode & EUM_UNRESTRICTED) this->edge.last_unrestricted_update = _date;
|
||||||
|
@@ -70,6 +70,7 @@ public:
|
|||||||
struct BaseEdge {
|
struct BaseEdge {
|
||||||
uint capacity; ///< Capacity of the link.
|
uint capacity; ///< Capacity of the link.
|
||||||
uint usage; ///< Usage of the link.
|
uint usage; ///< Usage of the link.
|
||||||
|
uint64 travel_time_sum; ///< Sum of the travel times of the link, in ticks.
|
||||||
Date last_unrestricted_update; ///< When the unrestricted part of the link was last updated.
|
Date last_unrestricted_update; ///< When the unrestricted part of the link was last updated.
|
||||||
Date last_restricted_update; ///< When the restricted part of the link was last updated.
|
Date last_restricted_update; ///< When the restricted part of the link was last updated.
|
||||||
Date last_aircraft_update; ///< When aircraft capacity of the link was last updated.
|
Date last_aircraft_update; ///< When aircraft capacity of the link was last updated.
|
||||||
@@ -106,6 +107,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
uint Usage() const { return this->edge.usage; }
|
uint Usage() const { return this->edge.usage; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get edge's average travel time.
|
||||||
|
* @return Travel time, in ticks.
|
||||||
|
*/
|
||||||
|
uint32 TravelTime() const { return this->edge.travel_time_sum / this->edge.capacity; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the date of the last update to the edge's unrestricted capacity.
|
* Get the date of the last update to the edge's unrestricted capacity.
|
||||||
* @return Last update.
|
* @return Last update.
|
||||||
@@ -311,7 +318,7 @@ public:
|
|||||||
* @param edge Edge to be wrapped.
|
* @param edge Edge to be wrapped.
|
||||||
*/
|
*/
|
||||||
Edge(BaseEdge &edge) : EdgeWrapper<BaseEdge>(edge) {}
|
Edge(BaseEdge &edge) : EdgeWrapper<BaseEdge>(edge) {}
|
||||||
void Update(uint capacity, uint usage, EdgeUpdateMode mode);
|
void Update(uint capacity, uint usage, uint32 time, EdgeUpdateMode mode);
|
||||||
void Restrict() { this->edge.last_unrestricted_update = INVALID_DATE; }
|
void Restrict() { this->edge.last_unrestricted_update = INVALID_DATE; }
|
||||||
void Release() { this->edge.last_restricted_update = INVALID_DATE; }
|
void Release() { this->edge.last_restricted_update = INVALID_DATE; }
|
||||||
void ClearAircraft() { this->edge.last_aircraft_update = INVALID_DATE; }
|
void ClearAircraft() { this->edge.last_aircraft_update = INVALID_DATE; }
|
||||||
@@ -445,8 +452,8 @@ public:
|
|||||||
this->node.demand = demand;
|
this->node.demand = demand;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddEdge(NodeID to, uint capacity, uint usage, EdgeUpdateMode mode);
|
void AddEdge(NodeID to, uint capacity, uint usage, uint32 time, EdgeUpdateMode mode);
|
||||||
void UpdateEdge(NodeID to, uint capacity, uint usage, EdgeUpdateMode mode);
|
void UpdateEdge(NodeID to, uint capacity, uint usage, uint32 time, EdgeUpdateMode mode);
|
||||||
void RemoveEdge(NodeID to);
|
void RemoveEdge(NodeID to);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -310,16 +310,33 @@ void MultiCommodityFlow::Dijkstra(NodeID source_node, PathVector &paths)
|
|||||||
capacity /= 100;
|
capacity /= 100;
|
||||||
if (capacity == 0) capacity = 1;
|
if (capacity == 0) capacity = 1;
|
||||||
}
|
}
|
||||||
/* punish in-between stops a little */
|
/* Prioritize the fastest route for passengers, mail and express cargo,
|
||||||
uint distance = DistanceMaxPlusManhattan(this->job[from].XY(), this->job[to].XY()) + 1;
|
* and the shortest route for other classes of cargo.
|
||||||
|
* In-between stops are punished with a 1 tile or 1 day penalty. */
|
||||||
|
bool express = IsCargoInClass(this->job.Cargo(), CC_PASSENGERS) ||
|
||||||
|
IsCargoInClass(this->job.Cargo(), CC_MAIL) ||
|
||||||
|
IsCargoInClass(this->job.Cargo(), CC_EXPRESS);
|
||||||
|
|
||||||
|
auto calculate_distance = [&]() {
|
||||||
|
return DistanceMaxPlusManhattan(this->job[from].XY(), this->job[to].XY()) + 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
uint distance_anno;
|
||||||
|
if (express) {
|
||||||
|
/* Compute a default travel time from the distance and an average speed of 1 tile/day. */
|
||||||
|
distance_anno = (edge.TravelTime() != 0) ? edge.TravelTime() + DAY_TICKS : calculate_distance() * DAY_TICKS;
|
||||||
|
} else {
|
||||||
|
distance_anno = calculate_distance();
|
||||||
|
}
|
||||||
|
|
||||||
if (edge.LastAircraftUpdate() != INVALID_DATE && aircraft_link_scale > 100) {
|
if (edge.LastAircraftUpdate() != INVALID_DATE && aircraft_link_scale > 100) {
|
||||||
distance *= aircraft_link_scale;
|
distance_anno *= aircraft_link_scale;
|
||||||
distance /= 100;
|
distance_anno /= 100;
|
||||||
}
|
}
|
||||||
Tannotation *dest = static_cast<Tannotation *>(paths[to]);
|
Tannotation *dest = static_cast<Tannotation *>(paths[to]);
|
||||||
if (dest->IsBetter(source, capacity, capacity - edge.Flow(), distance)) {
|
if (dest->IsBetter(source, capacity, capacity - edge.Flow(), distance_anno)) {
|
||||||
if (dest->GetAnnosSetFlag()) annos.erase(AnnoSetItem<Tannotation>(dest));
|
if (dest->GetAnnosSetFlag()) annos.erase(AnnoSetItem<Tannotation>(dest));
|
||||||
dest->Fork(source, capacity, capacity - edge.Flow(), distance);
|
dest->Fork(source, capacity, capacity - edge.Flow(), distance_anno);
|
||||||
dest->UpdateAnnotation();
|
dest->UpdateAnnotation();
|
||||||
annos.insert(AnnoSetItem<Tannotation>(dest));
|
annos.insert(AnnoSetItem<Tannotation>(dest));
|
||||||
dest->SetAnnosSetFlag(true);
|
dest->SetAnnosSetFlag(true);
|
||||||
|
@@ -249,6 +249,12 @@ void LinkRefresher::RefreshStats(const Order *cur, const Order *next, uint8 flag
|
|||||||
/* A link is at least partly restricted if a vehicle can't load at its source. */
|
/* A link is at least partly restricted if a vehicle can't load at its source. */
|
||||||
EdgeUpdateMode restricted_mode = (cur->GetCargoLoadType(c) & OLFB_NO_LOAD) == 0 ?
|
EdgeUpdateMode restricted_mode = (cur->GetCargoLoadType(c) & OLFB_NO_LOAD) == 0 ?
|
||||||
EUM_UNRESTRICTED : EUM_RESTRICTED;
|
EUM_UNRESTRICTED : EUM_RESTRICTED;
|
||||||
|
Station *st_to = Station::GetIfValid(next_station);
|
||||||
|
/* This estimates the travel time of the link as the time needed
|
||||||
|
* to travel between the stations at half the max speed of the consist.
|
||||||
|
* The result is in tiles/tick (= 2048 km-ish/h). */
|
||||||
|
uint32 time_estimate = (st_to != nullptr) ?
|
||||||
|
DistanceManhattan(st->xy, st_to->xy) * 4096U / this->vehicle->GetDisplayMaxSpeed() : 0;
|
||||||
|
|
||||||
if (HasBit(flags, AIRCRAFT)) restricted_mode |= EUM_AIRCRAFT;
|
if (HasBit(flags, AIRCRAFT)) restricted_mode |= EUM_AIRCRAFT;
|
||||||
|
|
||||||
@@ -264,15 +270,15 @@ void LinkRefresher::RefreshStats(const Order *cur, const Order *next, uint8 flag
|
|||||||
uint effective_capacity = cargo_quantity * this->vehicle->load_unload_ticks;
|
uint effective_capacity = cargo_quantity * this->vehicle->load_unload_ticks;
|
||||||
if (effective_capacity > (uint)this->vehicle->orders->GetTotalDuration()) {
|
if (effective_capacity > (uint)this->vehicle->orders->GetTotalDuration()) {
|
||||||
IncreaseStats(st, c, next_station, effective_capacity /
|
IncreaseStats(st, c, next_station, effective_capacity /
|
||||||
this->vehicle->orders->GetTotalDuration(), 0,
|
this->vehicle->orders->GetTotalDuration(), 0, 0,
|
||||||
EUM_INCREASE | restricted_mode);
|
EUM_INCREASE | restricted_mode);
|
||||||
} else if (RandomRange(this->vehicle->orders->GetTotalDuration()) < effective_capacity) {
|
} else if (RandomRange(this->vehicle->orders->GetTotalDuration()) < effective_capacity) {
|
||||||
IncreaseStats(st, c, next_station, 1, 0, EUM_INCREASE | restricted_mode);
|
IncreaseStats(st, c, next_station, 1, 0, 0, EUM_INCREASE | restricted_mode);
|
||||||
} else {
|
} else {
|
||||||
IncreaseStats(st, c, next_station, cargo_quantity, 0, EUM_REFRESH | restricted_mode);
|
IncreaseStats(st, c, next_station, cargo_quantity, 0, time_estimate, EUM_REFRESH | restricted_mode);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
IncreaseStats(st, c, next_station, cargo_quantity, 0, EUM_REFRESH | restricted_mode);
|
IncreaseStats(st, c, next_station, cargo_quantity, 0, time_estimate, EUM_REFRESH | restricted_mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -178,6 +178,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
|
|||||||
{ XSLFI_TOWN_SETTING_OVERRIDE, XSCF_NULL, 1, 1, "town_setting_override", nullptr, nullptr, nullptr },
|
{ XSLFI_TOWN_SETTING_OVERRIDE, XSCF_NULL, 1, 1, "town_setting_override", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_SCRIPT_INT64, XSCF_NULL, 1, 1, "script_int64", nullptr, nullptr, nullptr },
|
{ XSLFI_SCRIPT_INT64, XSCF_NULL, 1, 1, "script_int64", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_U64_TICK_COUNTER, XSCF_NULL, 1, 1, "u64_tick_counter", nullptr, nullptr, nullptr },
|
{ XSLFI_U64_TICK_COUNTER, XSCF_NULL, 1, 1, "u64_tick_counter", nullptr, nullptr, nullptr },
|
||||||
|
{ XSLFI_LINKGRAPH_TRAVEL_TIME, XSCF_NULL, 1, 1, "linkgraph_travel_time", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr },// This is the end marker
|
{ XSLFI_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr },// This is the end marker
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -132,6 +132,7 @@ enum SlXvFeatureIndex {
|
|||||||
|
|
||||||
XSLFI_SCRIPT_INT64, ///< See: SLV_SCRIPT_INT64
|
XSLFI_SCRIPT_INT64, ///< See: SLV_SCRIPT_INT64
|
||||||
XSLFI_U64_TICK_COUNTER, ///< See: SLV_U64_TICK_COUNTER
|
XSLFI_U64_TICK_COUNTER, ///< See: SLV_U64_TICK_COUNTER
|
||||||
|
XSLFI_LINKGRAPH_TRAVEL_TIME, ///< See: SLV_LINKGRAPH_TRAVEL_TIME
|
||||||
|
|
||||||
XSLFI_RIFF_HEADER_60_BIT, ///< Size field in RIFF chunk header is 60 bit
|
XSLFI_RIFF_HEADER_60_BIT, ///< Size field in RIFF chunk header is 60 bit
|
||||||
XSLFI_HEIGHT_8_BIT, ///< Map tile height is 8 bit instead of 4 bit, but savegame version may be before this became true in trunk
|
XSLFI_HEIGHT_8_BIT, ///< Map tile height is 8 bit instead of 4 bit, but savegame version may be before this became true in trunk
|
||||||
|
@@ -126,6 +126,7 @@ static const SaveLoad _edge_desc[] = {
|
|||||||
SLE_CONDNULL(4, SL_MIN_VERSION, SLV_191), // distance
|
SLE_CONDNULL(4, SL_MIN_VERSION, SLV_191), // distance
|
||||||
SLE_VAR(Edge, capacity, SLE_UINT32),
|
SLE_VAR(Edge, capacity, SLE_UINT32),
|
||||||
SLE_VAR(Edge, usage, SLE_UINT32),
|
SLE_VAR(Edge, usage, SLE_UINT32),
|
||||||
|
SLE_CONDVAR_X(Edge, travel_time_sum, SLE_UINT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_TRAVEL_TIME)),
|
||||||
SLE_VAR(Edge, last_unrestricted_update, SLE_INT32),
|
SLE_VAR(Edge, last_unrestricted_update, SLE_INT32),
|
||||||
SLE_CONDVAR(Edge, last_restricted_update, SLE_INT32, SLV_187, SL_MAX_VERSION),
|
SLE_CONDVAR(Edge, last_restricted_update, SLE_INT32, SLV_187, SL_MAX_VERSION),
|
||||||
SLE_CONDVAR_X(Edge, last_aircraft_update, SLE_INT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_AIRCRAFT)),
|
SLE_CONDVAR_X(Edge, last_aircraft_update, SLE_INT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_LINKGRAPH_AIRCRAFT)),
|
||||||
|
@@ -33,7 +33,7 @@ public:
|
|||||||
inline static const SaveLoad description[] = {
|
inline static const SaveLoad description[] = {
|
||||||
SLE_VAR(Edge, capacity, SLE_UINT32),
|
SLE_VAR(Edge, capacity, SLE_UINT32),
|
||||||
SLE_VAR(Edge, usage, SLE_UINT32),
|
SLE_VAR(Edge, usage, SLE_UINT32),
|
||||||
//SLE_CONDVAR(Edge, travel_time_sum, SLE_UINT64, SLV_LINKGRAPH_TRAVEL_TIME, SL_MAX_VERSION),
|
SLE_CONDVAR(Edge, travel_time_sum, SLE_UINT64, SLV_LINKGRAPH_TRAVEL_TIME, SL_MAX_VERSION),
|
||||||
SLE_VAR(Edge, last_unrestricted_update, SLE_INT32),
|
SLE_VAR(Edge, last_unrestricted_update, SLE_INT32),
|
||||||
SLE_CONDVAR(Edge, last_restricted_update, SLE_INT32, SLV_187, SL_MAX_VERSION),
|
SLE_CONDVAR(Edge, last_restricted_update, SLE_INT32, SLV_187, SL_MAX_VERSION),
|
||||||
SLE_VAR(Edge, next_edge, SLE_UINT16),
|
SLE_VAR(Edge, next_edge, SLE_UINT16),
|
||||||
|
@@ -4499,7 +4499,7 @@ void DeleteStaleLinks(Station *from)
|
|||||||
* @param usage Usage to add to link stat.
|
* @param usage Usage to add to link stat.
|
||||||
* @param mode Update mode to be applied.
|
* @param mode Update mode to be applied.
|
||||||
*/
|
*/
|
||||||
void IncreaseStats(Station *st, CargoID cargo, StationID next_station_id, uint capacity, uint usage, EdgeUpdateMode mode)
|
void IncreaseStats(Station *st, CargoID cargo, StationID next_station_id, uint capacity, uint usage, uint32 time, EdgeUpdateMode mode)
|
||||||
{
|
{
|
||||||
GoodsEntry &ge1 = st->goods[cargo];
|
GoodsEntry &ge1 = st->goods[cargo];
|
||||||
Station *st2 = Station::Get(next_station_id);
|
Station *st2 = Station::Get(next_station_id);
|
||||||
@@ -4541,7 +4541,7 @@ void IncreaseStats(Station *st, CargoID cargo, StationID next_station_id, uint c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (lg != nullptr) {
|
if (lg != nullptr) {
|
||||||
(*lg)[ge1.node].UpdateEdge(ge2.node, capacity, usage, mode);
|
(*lg)[ge1.node].UpdateEdge(ge2.node, capacity, usage, time, mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -52,8 +52,8 @@ void UpdateAirportsNoise();
|
|||||||
|
|
||||||
bool SplitGroundSpriteForOverlay(const TileInfo *ti, SpriteID *ground, RailTrackOffset *overlay_offset);
|
bool SplitGroundSpriteForOverlay(const TileInfo *ti, SpriteID *ground, RailTrackOffset *overlay_offset);
|
||||||
|
|
||||||
void IncreaseStats(Station *st, const Vehicle *v, StationID next_station_id);
|
void IncreaseStats(Station *st, const Vehicle *v, StationID next_station_id, uint32 time);
|
||||||
void IncreaseStats(Station *st, CargoID cargo, StationID next_station_id, uint capacity, uint usage, EdgeUpdateMode mode);
|
void IncreaseStats(Station *st, CargoID cargo, StationID next_station_id, uint capacity, uint usage, uint32 time, EdgeUpdateMode mode);
|
||||||
void RerouteCargo(Station *st, CargoID c, StationID avoid, StationID avoid2);
|
void RerouteCargo(Station *st, CargoID c, StationID avoid, StationID avoid2);
|
||||||
void RerouteCargoFromSource(Station *st, CargoID c, StationID source, StationID avoid, StationID avoid2);
|
void RerouteCargoFromSource(Station *st, CargoID c, StationID source, StationID avoid, StationID avoid2);
|
||||||
|
|
||||||
|
@@ -3140,6 +3140,7 @@ void Vehicle::DeleteUnreachedImplicitOrders()
|
|||||||
*/
|
*/
|
||||||
static void VehicleIncreaseStats(const Vehicle *front)
|
static void VehicleIncreaseStats(const Vehicle *front)
|
||||||
{
|
{
|
||||||
|
uint32 travel_time = front->current_order_time;
|
||||||
for (const Vehicle *v = front; v != nullptr; v = v->Next()) {
|
for (const Vehicle *v = front; v != nullptr; v = v->Next()) {
|
||||||
StationID last_loading_station = HasBit(front->vehicle_flags, VF_LAST_LOAD_ST_SEP) ? v->last_loading_station : front->last_loading_station;
|
StationID last_loading_station = HasBit(front->vehicle_flags, VF_LAST_LOAD_ST_SEP) ? v->last_loading_station : front->last_loading_station;
|
||||||
if (v->refit_cap > 0 &&
|
if (v->refit_cap > 0 &&
|
||||||
@@ -3156,7 +3157,7 @@ static void VehicleIncreaseStats(const Vehicle *front)
|
|||||||
EdgeUpdateMode restricted_mode = EUM_INCREASE;
|
EdgeUpdateMode restricted_mode = EUM_INCREASE;
|
||||||
if (v->type == VEH_AIRCRAFT) restricted_mode |= EUM_AIRCRAFT;
|
if (v->type == VEH_AIRCRAFT) restricted_mode |= EUM_AIRCRAFT;
|
||||||
IncreaseStats(Station::Get(last_loading_station), v->cargo_type, front->last_station_visited, v->refit_cap,
|
IncreaseStats(Station::Get(last_loading_station), v->cargo_type, front->last_station_visited, v->refit_cap,
|
||||||
std::min<uint>(v->refit_cap, v->cargo.StoredCount()), restricted_mode);
|
std::min<uint>(v->refit_cap, v->cargo.StoredCount()), travel_time, restricted_mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user