Change GetNextStoppingStation to return per-cargo result(s).
This commit is contained in:
@@ -1287,7 +1287,7 @@ void PrepareUnload(Vehicle *front_v)
|
|||||||
assert(CargoPayment::CanAllocateItem());
|
assert(CargoPayment::CanAllocateItem());
|
||||||
front_v->cargo_payment = new CargoPayment(front_v);
|
front_v->cargo_payment = new CargoPayment(front_v);
|
||||||
|
|
||||||
StationIDStack next_station = front_v->GetNextStoppingStation();
|
CargoStationIDStackSet next_station = front_v->GetNextStoppingStation();
|
||||||
if (front_v->orders.list == NULL || (front_v->current_order.GetUnloadType() & OUFB_NO_UNLOAD) == 0) {
|
if (front_v->orders.list == NULL || (front_v->current_order.GetUnloadType() & OUFB_NO_UNLOAD) == 0) {
|
||||||
Station *st = Station::Get(front_v->last_station_visited);
|
Station *st = Station::Get(front_v->last_station_visited);
|
||||||
for (Vehicle *v = front_v; v != NULL; v = v->Next()) {
|
for (Vehicle *v = front_v; v != NULL; v = v->Next()) {
|
||||||
@@ -1296,7 +1296,7 @@ void PrepareUnload(Vehicle *front_v)
|
|||||||
if (v->cargo_cap > 0 && v->cargo.TotalCount() > 0) {
|
if (v->cargo_cap > 0 && v->cargo.TotalCount() > 0) {
|
||||||
v->cargo.Stage(
|
v->cargo.Stage(
|
||||||
HasBit(ge->status, GoodsEntry::GES_ACCEPTANCE),
|
HasBit(ge->status, GoodsEntry::GES_ACCEPTANCE),
|
||||||
front_v->last_station_visited, next_station,
|
front_v->last_station_visited, next_station.Get(v->cargo_type),
|
||||||
GetUnloadType(v), ge,
|
GetUnloadType(v), ge,
|
||||||
front_v->cargo_payment);
|
front_v->cargo_payment);
|
||||||
if (v->cargo.UnloadCount() > 0) SetBit(v->vehicle_flags, VF_CARGO_UNLOADING);
|
if (v->cargo.UnloadCount() > 0) SetBit(v->vehicle_flags, VF_CARGO_UNLOADING);
|
||||||
@@ -1450,7 +1450,7 @@ struct FinalizeRefitAction
|
|||||||
{
|
{
|
||||||
CargoArray &consist_capleft; ///< Capacities left in the consist.
|
CargoArray &consist_capleft; ///< Capacities left in the consist.
|
||||||
Station *st; ///< Station to reserve cargo from.
|
Station *st; ///< Station to reserve cargo from.
|
||||||
StationIDStack &next_station; ///< Next hops to reserve cargo for.
|
const CargoStationIDStackSet &next_station; ///< Next hops to reserve cargo for.
|
||||||
bool do_reserve; ///< If the vehicle should reserve.
|
bool do_reserve; ///< If the vehicle should reserve.
|
||||||
Vehicle *cargo_type_loading; ///< Non-null if vehicle should reserve if the cargo type of the vehicle is a cargo-specific full-load order using this pointer
|
Vehicle *cargo_type_loading; ///< Non-null if vehicle should reserve if the cargo type of the vehicle is a cargo-specific full-load order using this pointer
|
||||||
|
|
||||||
@@ -1460,8 +1460,9 @@ struct FinalizeRefitAction
|
|||||||
* @param st Station to reserve cargo from.
|
* @param st Station to reserve cargo from.
|
||||||
* @param next_station Next hops to reserve cargo for.
|
* @param next_station Next hops to reserve cargo for.
|
||||||
* @param do_reserve If we should reserve cargo or just add up the capacities.
|
* @param do_reserve If we should reserve cargo or just add up the capacities.
|
||||||
|
* @param cargo_type_loading Non-null if vehicle should reserve if the cargo type of the vehicle is a cargo-specific full-load order using this pointer
|
||||||
*/
|
*/
|
||||||
FinalizeRefitAction(CargoArray &consist_capleft, Station *st, StationIDStack &next_station, bool do_reserve, Vehicle *cargo_type_loading) :
|
FinalizeRefitAction(CargoArray &consist_capleft, Station *st, const CargoStationIDStackSet &next_station, bool do_reserve, Vehicle *cargo_type_loading) :
|
||||||
consist_capleft(consist_capleft), st(st), next_station(next_station), do_reserve(do_reserve), cargo_type_loading(cargo_type_loading) {}
|
consist_capleft(consist_capleft), st(st), next_station(next_station), do_reserve(do_reserve), cargo_type_loading(cargo_type_loading) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1474,7 +1475,7 @@ struct FinalizeRefitAction
|
|||||||
{
|
{
|
||||||
if (this->do_reserve || (cargo_type_loading == NULL || (cargo_type_loading->current_order.GetCargoLoadTypeRaw(v->cargo_type) & OLFB_FULL_LOAD))) {
|
if (this->do_reserve || (cargo_type_loading == NULL || (cargo_type_loading->current_order.GetCargoLoadTypeRaw(v->cargo_type) & OLFB_FULL_LOAD))) {
|
||||||
this->st->goods[v->cargo_type].cargo.Reserve(v->cargo_cap - v->cargo.RemainingCount(),
|
this->st->goods[v->cargo_type].cargo.Reserve(v->cargo_cap - v->cargo.RemainingCount(),
|
||||||
&v->cargo, st->xy, this->next_station);
|
&v->cargo, st->xy, this->next_station.Get(v->cargo_type));
|
||||||
}
|
}
|
||||||
this->consist_capleft[v->cargo_type] += v->cargo_cap - v->cargo.RemainingCount();
|
this->consist_capleft[v->cargo_type] += v->cargo_cap - v->cargo.RemainingCount();
|
||||||
return true;
|
return true;
|
||||||
@@ -1489,7 +1490,7 @@ struct FinalizeRefitAction
|
|||||||
* @param next_station Possible next stations the vehicle can travel to.
|
* @param next_station Possible next stations the vehicle can travel to.
|
||||||
* @param new_cid Target cargo for refit.
|
* @param new_cid Target cargo for refit.
|
||||||
*/
|
*/
|
||||||
static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station *st, StationIDStack next_station, CargoID new_cid)
|
static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station *st, CargoStationIDStackSet next_station, CargoID new_cid)
|
||||||
{
|
{
|
||||||
Vehicle *v_start = v->GetFirstEnginePart();
|
Vehicle *v_start = v->GetFirstEnginePart();
|
||||||
if (!IterateVehicleParts(v_start, IsEmptyAction())) return;
|
if (!IterateVehicleParts(v_start, IsEmptyAction())) return;
|
||||||
@@ -1507,7 +1508,7 @@ static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station
|
|||||||
CargoID cid;
|
CargoID cid;
|
||||||
new_cid = v_start->cargo_type;
|
new_cid = v_start->cargo_type;
|
||||||
FOR_EACH_SET_CARGO_ID(cid, refit_mask) {
|
FOR_EACH_SET_CARGO_ID(cid, refit_mask) {
|
||||||
if (st->goods[cid].cargo.HasCargoFor(next_station)) {
|
if (st->goods[cid].cargo.HasCargoFor(next_station.Get(cid))) {
|
||||||
/* Try to find out if auto-refitting would succeed. In case the refit is allowed,
|
/* Try to find out if auto-refitting would succeed. In case the refit is allowed,
|
||||||
* the returned refit capacity will be greater than zero. */
|
* the returned refit capacity will be greater than zero. */
|
||||||
DoCommand(v_start->tile, v_start->index, cid | 1U << 6 | 0xFF << 8 | 1U << 16, DC_QUERY_COST, GetCmdRefitVeh(v_start)); // Auto-refit and only this vehicle including artic parts.
|
DoCommand(v_start->tile, v_start->index, cid | 1U << 6 | 0xFF << 8 | 1U << 16, DC_QUERY_COST, GetCmdRefitVeh(v_start)); // Auto-refit and only this vehicle including artic parts.
|
||||||
@@ -1547,10 +1548,10 @@ static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station
|
|||||||
|
|
||||||
struct ReserveCargoAction {
|
struct ReserveCargoAction {
|
||||||
Station *st;
|
Station *st;
|
||||||
StationIDStack *next_station;
|
const CargoStationIDStackSet &next_station;
|
||||||
Vehicle *cargo_type_loading;
|
Vehicle *cargo_type_loading;
|
||||||
|
|
||||||
ReserveCargoAction(Station *st, StationIDStack *next_station, Vehicle *cargo_type_loading) :
|
ReserveCargoAction(Station *st, const CargoStationIDStackSet &next_station, Vehicle *cargo_type_loading) :
|
||||||
st(st), next_station(next_station), cargo_type_loading(cargo_type_loading) {}
|
st(st), next_station(next_station), cargo_type_loading(cargo_type_loading) {}
|
||||||
|
|
||||||
bool operator()(Vehicle *v)
|
bool operator()(Vehicle *v)
|
||||||
@@ -1558,7 +1559,7 @@ struct ReserveCargoAction {
|
|||||||
if (cargo_type_loading != NULL && !(cargo_type_loading->current_order.GetCargoLoadTypeRaw(v->cargo_type) & OLFB_FULL_LOAD)) return true;
|
if (cargo_type_loading != NULL && !(cargo_type_loading->current_order.GetCargoLoadTypeRaw(v->cargo_type) & OLFB_FULL_LOAD)) return true;
|
||||||
if (v->cargo_cap > v->cargo.RemainingCount()) {
|
if (v->cargo_cap > v->cargo.RemainingCount()) {
|
||||||
st->goods[v->cargo_type].cargo.Reserve(v->cargo_cap - v->cargo.RemainingCount(),
|
st->goods[v->cargo_type].cargo.Reserve(v->cargo_cap - v->cargo.RemainingCount(),
|
||||||
&v->cargo, st->xy, *next_station);
|
&v->cargo, st->xy, next_station.Get(v->cargo_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -1575,7 +1576,7 @@ struct ReserveCargoAction {
|
|||||||
* @param next_station Station(s) the vehicle will stop at next.
|
* @param next_station Station(s) the vehicle will stop at next.
|
||||||
* @param cargo_type_loading check cargo-specific loading type
|
* @param cargo_type_loading check cargo-specific loading type
|
||||||
*/
|
*/
|
||||||
static void ReserveConsist(Station *st, Vehicle *u, CargoArray *consist_capleft, StationIDStack *next_station, bool cargo_type_loading)
|
static void ReserveConsist(Station *st, Vehicle *u, CargoArray *consist_capleft, const CargoStationIDStackSet &next_station, bool cargo_type_loading)
|
||||||
{
|
{
|
||||||
/* If there is a cargo payment not all vehicles of the consist have tried to do the refit.
|
/* If there is a cargo payment not all vehicles of the consist have tried to do the refit.
|
||||||
* In that case, only reserve if it's a fixed refit and the equivalent of "articulated chain"
|
* In that case, only reserve if it's a fixed refit and the equivalent of "articulated chain"
|
||||||
@@ -1631,24 +1632,26 @@ static void LoadUnloadVehicle(Vehicle *front)
|
|||||||
StationID last_visited = front->last_station_visited;
|
StationID last_visited = front->last_station_visited;
|
||||||
Station *st = Station::Get(last_visited);
|
Station *st = Station::Get(last_visited);
|
||||||
|
|
||||||
StationIDStack next_station = front->GetNextStoppingStation();
|
CargoStationIDStackSet next_station = front->GetNextStoppingStation();
|
||||||
|
|
||||||
bool use_autorefit = front->current_order.IsRefit() && front->current_order.GetRefitCargo() == CT_AUTO_REFIT;
|
bool use_autorefit = front->current_order.IsRefit() && front->current_order.GetRefitCargo() == CT_AUTO_REFIT;
|
||||||
CargoArray consist_capleft;
|
CargoArray consist_capleft;
|
||||||
|
bool should_reserve_consist = false;
|
||||||
|
bool reserve_consist_cargo_type_loading = false;
|
||||||
if (_settings_game.order.improved_load && use_autorefit) {
|
if (_settings_game.order.improved_load && use_autorefit) {
|
||||||
if (front->cargo_payment == NULL) {
|
if (front->cargo_payment == NULL) should_reserve_consist = true;
|
||||||
ReserveConsist(st, front,
|
|
||||||
(use_autorefit && front->load_unload_ticks != 0) ? &consist_capleft : NULL,
|
|
||||||
&next_station,
|
|
||||||
false);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if ((front->current_order.GetLoadType() & OLFB_FULL_LOAD) || (front->current_order.GetLoadType() == OLFB_CARGO_TYPE_LOAD)) {
|
if ((front->current_order.GetLoadType() & OLFB_FULL_LOAD) || (front->current_order.GetLoadType() == OLFB_CARGO_TYPE_LOAD)) {
|
||||||
ReserveConsist(st, front,
|
should_reserve_consist = true;
|
||||||
(use_autorefit && front->load_unload_ticks != 0) ? &consist_capleft : NULL,
|
reserve_consist_cargo_type_loading = (front->current_order.GetLoadType() == OLFB_CARGO_TYPE_LOAD);
|
||||||
&next_station,
|
|
||||||
(front->current_order.GetLoadType() == OLFB_CARGO_TYPE_LOAD));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (should_reserve_consist) {
|
||||||
|
ReserveConsist(st, front,
|
||||||
|
(use_autorefit && front->load_unload_ticks != 0) ? &consist_capleft : NULL,
|
||||||
|
next_station,
|
||||||
|
reserve_consist_cargo_type_loading);
|
||||||
|
}
|
||||||
|
|
||||||
/* We have not waited enough time till the next round of loading/unloading */
|
/* We have not waited enough time till the next round of loading/unloading */
|
||||||
if (front->load_unload_ticks != 0) return;
|
if (front->load_unload_ticks != 0) return;
|
||||||
@@ -1797,7 +1800,7 @@ static void LoadUnloadVehicle(Vehicle *front)
|
|||||||
if (_settings_game.order.gradual_loading) cap_left = min(cap_left, load_amount);
|
if (_settings_game.order.gradual_loading) cap_left = min(cap_left, load_amount);
|
||||||
if (v->cargo.StoredCount() == 0) TriggerVehicle(v, VEHICLE_TRIGGER_NEW_CARGO);
|
if (v->cargo.StoredCount() == 0) TriggerVehicle(v, VEHICLE_TRIGGER_NEW_CARGO);
|
||||||
|
|
||||||
uint loaded = ge->cargo.Load(cap_left, &v->cargo, st->xy, next_station);
|
uint loaded = ge->cargo.Load(cap_left, &v->cargo, st->xy, next_station.Get(v->cargo_type));
|
||||||
if (v->cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0) {
|
if (v->cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0) {
|
||||||
/* Remember if there are reservations left so that we don't stop
|
/* Remember if there are reservations left so that we don't stop
|
||||||
* loading before they're loaded. */
|
* loading before they're loaded. */
|
||||||
|
@@ -21,6 +21,8 @@
|
|||||||
#include "vehicle_type.h"
|
#include "vehicle_type.h"
|
||||||
#include "date_type.h"
|
#include "date_type.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
typedef Pool<Order, OrderID, 256, 64000> OrderPool;
|
typedef Pool<Order, OrderID, 256, 64000> OrderPool;
|
||||||
typedef Pool<OrderList, OrderListID, 128, 64000> OrderListPool;
|
typedef Pool<OrderList, OrderListID, 128, 64000> OrderListPool;
|
||||||
extern OrderPool _order_pool;
|
extern OrderPool _order_pool;
|
||||||
@@ -325,6 +327,35 @@ public:
|
|||||||
void InsertOrder(Vehicle *v, Order *new_o, VehicleOrderID sel_ord);
|
void InsertOrder(Vehicle *v, Order *new_o, VehicleOrderID sel_ord);
|
||||||
void DeleteOrder(Vehicle *v, VehicleOrderID sel_ord);
|
void DeleteOrder(Vehicle *v, VehicleOrderID sel_ord);
|
||||||
|
|
||||||
|
struct CargoMaskedStationIDStack {
|
||||||
|
uint32 cargo_mask;
|
||||||
|
StationIDStack station;
|
||||||
|
|
||||||
|
CargoMaskedStationIDStack(uint32 cargo_mask, StationIDStack station)
|
||||||
|
: cargo_mask(cargo_mask), station(station) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CargoStationIDStackSet {
|
||||||
|
private:
|
||||||
|
CargoMaskedStationIDStack first;
|
||||||
|
std::vector<CargoMaskedStationIDStack> more;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CargoStationIDStackSet()
|
||||||
|
: first(~0, INVALID_STATION) {}
|
||||||
|
|
||||||
|
const StationIDStack& Get(CargoID cargo) const
|
||||||
|
{
|
||||||
|
if (HasBit(first.cargo_mask, cargo)) return first.station;
|
||||||
|
for (size_t i = 0; i < more.size(); i++) {
|
||||||
|
if (HasBit(more[i].cargo_mask, cargo)) return more[i].station;
|
||||||
|
}
|
||||||
|
NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FillNextStoppingStation(const Vehicle *v, const OrderList *o, const Order *first = NULL, uint hops = 0);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shared order list linking together the linked list of orders and the list
|
* Shared order list linking together the linked list of orders and the list
|
||||||
* of vehicles sharing this order list.
|
* of vehicles sharing this order list.
|
||||||
@@ -397,7 +428,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
inline VehicleOrderID GetNumManualOrders() const { return this->num_manual_orders; }
|
inline VehicleOrderID GetNumManualOrders() const { return this->num_manual_orders; }
|
||||||
|
|
||||||
StationIDStack GetNextStoppingStation(const Vehicle *v, const Order *first = NULL, uint hops = 0) const;
|
CargoMaskedStationIDStack GetNextStoppingStation(const Vehicle *v, uint32 cargo_mask, const Order *first = NULL, uint hops = 0) const;
|
||||||
const Order *GetNextDecisionNode(const Order *next, uint hops) const;
|
const Order *GetNextDecisionNode(const Order *next, uint hops) const;
|
||||||
|
|
||||||
void InsertOrderAt(Order *new_order, int index);
|
void InsertOrderAt(Order *new_order, int index);
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
#include "timetable.h"
|
#include "timetable.h"
|
||||||
#include "vehicle_func.h"
|
#include "vehicle_func.h"
|
||||||
#include "depot_base.h"
|
#include "depot_base.h"
|
||||||
|
#include "core/bitmath_func.hpp"
|
||||||
#include "core/pool_func.hpp"
|
#include "core/pool_func.hpp"
|
||||||
#include "core/random_func.hpp"
|
#include "core/random_func.hpp"
|
||||||
#include "aircraft.h"
|
#include "aircraft.h"
|
||||||
@@ -290,6 +291,19 @@ void Order::AssignOrder(const Order &other)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CargoStationIDStackSet::FillNextStoppingStation(const Vehicle *v, const OrderList *o, const Order *first, uint hops)
|
||||||
|
{
|
||||||
|
this->more.clear();
|
||||||
|
this->first = o->GetNextStoppingStation(v, ~0, first, hops);
|
||||||
|
if (this->first.cargo_mask != (uint32) ~0) {
|
||||||
|
uint32 have_cargoes = this->first.cargo_mask;
|
||||||
|
do {
|
||||||
|
this->more.push_back(o->GetNextStoppingStation(v, ~have_cargoes, first, hops));
|
||||||
|
have_cargoes |= this->more.back().cargo_mask;
|
||||||
|
} while (have_cargoes != (uint32) ~0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recomputes everything.
|
* Recomputes everything.
|
||||||
* @param chain first order in the chain
|
* @param chain first order in the chain
|
||||||
@@ -401,21 +415,26 @@ const Order *OrderList::GetNextDecisionNode(const Order *next, uint hops) const
|
|||||||
/**
|
/**
|
||||||
* Recursively determine the next deterministic station to stop at.
|
* Recursively determine the next deterministic station to stop at.
|
||||||
* @param v The vehicle we're looking at.
|
* @param v The vehicle we're looking at.
|
||||||
|
* @param uint32 cargo_mask Bit-set of the cargo IDs of interest.
|
||||||
* @param first Order to start searching at or NULL to start at cur_implicit_order_index + 1.
|
* @param first Order to start searching at or NULL to start at cur_implicit_order_index + 1.
|
||||||
* @param hops Number of orders we have already looked at.
|
* @param hops Number of orders we have already looked at.
|
||||||
* @return Next stoppping station or INVALID_STATION.
|
* @return A CargoMaskedStationIDStack of the cargo mask the result is valid for, and the next stoppping station or INVALID_STATION.
|
||||||
* @pre The vehicle is currently loading and v->last_station_visited is meaningful.
|
* @pre The vehicle is currently loading and v->last_station_visited is meaningful.
|
||||||
* @note This function may draw a random number. Don't use it from the GUI.
|
* @note This function may draw a random number. Don't use it from the GUI.
|
||||||
*/
|
*/
|
||||||
StationIDStack OrderList::GetNextStoppingStation(const Vehicle *v, const Order *first, uint hops) const
|
CargoMaskedStationIDStack OrderList::GetNextStoppingStation(const Vehicle *v, uint32 cargo_mask, const Order *first, uint hops) const
|
||||||
{
|
{
|
||||||
|
assert(cargo_mask != 0);
|
||||||
|
CargoID first_cargo_id = FindFirstBit(cargo_mask);
|
||||||
|
uint32 other_cargo_mask = cargo_mask;
|
||||||
|
ClrBit(other_cargo_mask, first_cargo_id);
|
||||||
|
|
||||||
const Order *next = first;
|
const Order *next = first;
|
||||||
if (first == NULL) {
|
if (first == NULL) {
|
||||||
next = this->GetOrderAt(v->cur_implicit_order_index);
|
next = this->GetOrderAt(v->cur_implicit_order_index);
|
||||||
if (next == NULL) {
|
if (next == NULL) {
|
||||||
next = this->GetFirstOrder();
|
next = this->GetFirstOrder();
|
||||||
if (next == NULL) return INVALID_STATION;
|
if (next == NULL) return CargoMaskedStationIDStack(cargo_mask, INVALID_STATION);
|
||||||
} else {
|
} else {
|
||||||
/* GetNext never returns NULL if there is a valid station in the list.
|
/* GetNext never returns NULL if there is a valid station in the list.
|
||||||
* As the given "next" is already valid and a station in the list, we
|
* As the given "next" is already valid and a station in the list, we
|
||||||
@@ -440,23 +459,54 @@ StationIDStack OrderList::GetNextStoppingStation(const Vehicle *v, const Order *
|
|||||||
} else if (skip_to == NULL || skip_to == first) {
|
} else if (skip_to == NULL || skip_to == first) {
|
||||||
next = (advance == first) ? NULL : advance;
|
next = (advance == first) ? NULL : advance;
|
||||||
} else {
|
} else {
|
||||||
StationIDStack st1 = this->GetNextStoppingStation(v, skip_to, hops);
|
CargoMaskedStationIDStack st1 = this->GetNextStoppingStation(v, cargo_mask, skip_to, hops);
|
||||||
StationIDStack st2 = this->GetNextStoppingStation(v, advance, hops);
|
cargo_mask &= st1.cargo_mask;
|
||||||
while (!st2.IsEmpty()) st1.Push(st2.Pop());
|
CargoMaskedStationIDStack st2 = this->GetNextStoppingStation(v, cargo_mask, advance, hops);
|
||||||
|
st1.cargo_mask &= st2.cargo_mask;
|
||||||
|
while (!st2.station.IsEmpty()) st1.station.Push(st2.station.Pop());
|
||||||
return st1;
|
return st1;
|
||||||
}
|
}
|
||||||
++hops;
|
++hops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (next == NULL) return CargoMaskedStationIDStack(cargo_mask, INVALID_STATION);
|
||||||
|
|
||||||
|
if ((next->IsType(OT_GOTO_STATION) || next->IsType(OT_IMPLICIT)) && (next->GetUnloadType() == OUFB_CARGO_TYPE_UNLOAD || next->GetLoadType() == OLFB_CARGO_TYPE_LOAD)) {
|
||||||
|
/* This is a cargo-specific load/unload order.
|
||||||
|
* If the first cargo is both a no-load and no-unload order, skip it.
|
||||||
|
* Drop cargoes which don't match the first one. */
|
||||||
|
bool should_drop = next->GetCargoLoadType(first_cargo_id) & OLFB_NO_LOAD && next->GetCargoUnloadType(first_cargo_id) & OUFB_NO_UNLOAD;
|
||||||
|
CargoID cargo;
|
||||||
|
FOR_EACH_SET_BIT(cargo, other_cargo_mask) {
|
||||||
|
if (should_drop != (next->GetCargoLoadType(cargo) & OLFB_NO_LOAD && next->GetCargoUnloadType(cargo) & OUFB_NO_UNLOAD)) {
|
||||||
|
ClrBit(cargo_mask, cargo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
other_cargo_mask &= cargo_mask;
|
||||||
|
if (should_drop) continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* Don't return a next stop if the vehicle has to unload everything. */
|
/* Don't return a next stop if the vehicle has to unload everything. */
|
||||||
if (next == NULL || ((next->IsType(OT_GOTO_STATION) || next->IsType(OT_IMPLICIT)) &&
|
if ((next->IsType(OT_GOTO_STATION) || next->IsType(OT_IMPLICIT)) &&
|
||||||
next->GetDestination() == v->last_station_visited &&
|
next->GetDestination() == v->last_station_visited) {
|
||||||
(next->GetUnloadType() & (OUFB_TRANSFER | OUFB_UNLOAD)) != 0)) {
|
bool invalid = ((next->GetCargoUnloadType(first_cargo_id) & (OUFB_TRANSFER | OUFB_UNLOAD)) != 0);
|
||||||
return INVALID_STATION;
|
if (next->GetUnloadType() == OUFB_CARGO_TYPE_UNLOAD) {
|
||||||
|
/* This is a cargo-specific load/unload order.
|
||||||
|
* Don't return a next stop if first cargo has transfer or unload set.
|
||||||
|
* Drop cargoes which don't match the first one. */
|
||||||
|
CargoID cargo;
|
||||||
|
FOR_EACH_SET_BIT(cargo, other_cargo_mask) {
|
||||||
|
if (invalid != ((next->GetCargoUnloadType(cargo) & (OUFB_TRANSFER | OUFB_UNLOAD)) != 0)) {
|
||||||
|
ClrBit(cargo_mask, cargo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
other_cargo_mask &= cargo_mask;
|
||||||
|
}
|
||||||
|
if (invalid) return CargoMaskedStationIDStack(cargo_mask, INVALID_STATION);
|
||||||
}
|
}
|
||||||
} while (next->IsType(OT_GOTO_DEPOT) || next->GetDestination() == v->last_station_visited);
|
} while (next->IsType(OT_GOTO_DEPOT) || next->GetDestination() == v->last_station_visited);
|
||||||
|
|
||||||
return next->GetDestination();
|
return CargoMaskedStationIDStack(cargo_mask, next->GetDestination());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -639,9 +639,11 @@ public:
|
|||||||
* Get the next station the vehicle will stop at.
|
* Get the next station the vehicle will stop at.
|
||||||
* @return ID of the next station the vehicle will stop at or INVALID_STATION.
|
* @return ID of the next station the vehicle will stop at or INVALID_STATION.
|
||||||
*/
|
*/
|
||||||
inline StationIDStack GetNextStoppingStation() const
|
inline CargoStationIDStackSet GetNextStoppingStation() const
|
||||||
{
|
{
|
||||||
return (this->orders.list == NULL) ? INVALID_STATION : this->orders.list->GetNextStoppingStation(this);
|
CargoStationIDStackSet set;
|
||||||
|
if (this->orders.list != NULL) set.FillNextStoppingStation(this, this->orders.list);
|
||||||
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResetRefitCaps();
|
void ResetRefitCaps();
|
||||||
|
Reference in New Issue
Block a user