Timetable: Implement autofill/automate for taken conditional orders.

Fix wrong timetable values being set after using skip or send to depot.
Add timetabled flag for conditional order branch taken travel time.
This commit is contained in:
Jonathan G Rennison
2017-12-18 01:26:27 +00:00
parent 102c55bc57
commit 218085c535
16 changed files with 187 additions and 34 deletions

View File

@@ -375,8 +375,10 @@ void OrderList::Initialize(Order *chain, Vehicle *v)
for (Order *o = this->first; o != NULL; o = o->next) {
++this->num_orders;
if (!o->IsType(OT_IMPLICIT)) ++this->num_manual_orders;
this->timetable_duration += o->GetTimetabledWait() + o->GetTimetabledTravel();
this->total_duration += o->GetWaitTime() + o->GetTravelTime();
if (!o->IsType(OT_CONDITIONAL)) {
this->timetable_duration += o->GetTimetabledWait() + o->GetTimetabledTravel();
this->total_duration += o->GetWaitTime() + o->GetTravelTime();
}
}
for (Vehicle *u = this->first_shared->PreviousShared(); u != NULL; u = u->PreviousShared()) {
@@ -427,6 +429,24 @@ Order *OrderList::GetOrderAt(int index) const
return order;
}
/**
* Get the index of an order of the order chain, or INVALID_VEH_ORDER_ID.
* @param order order to get the index of.
* @return the position index of the given order, or INVALID_VEH_ORDER_ID.
*/
VehicleOrderID OrderList::GetIndexOfOrder(const Order *order) const
{
VehicleOrderID index = 0;
const Order *o = this->first;
while (o != nullptr) {
if (o == order) return index;
index++;
o = o->next;
}
return INVALID_VEH_ORDER_ID;
}
/**
* Get the next order which will make the given vehicle stop at a station
* or refit at a depot or evaluate a non-trivial condition.
@@ -580,8 +600,10 @@ void OrderList::InsertOrderAt(Order *new_order, int index)
}
++this->num_orders;
if (!new_order->IsType(OT_IMPLICIT)) ++this->num_manual_orders;
this->timetable_duration += new_order->GetTimetabledWait() + new_order->GetTimetabledTravel();
this->total_duration += new_order->GetWaitTime() + new_order->GetTravelTime();
if (!new_order->IsType(OT_CONDITIONAL)) {
this->timetable_duration += new_order->GetTimetabledWait() + new_order->GetTimetabledTravel();
this->total_duration += new_order->GetWaitTime() + new_order->GetTravelTime();
}
/* We can visit oil rigs and buoys that are not our own. They will be shown in
* the list of stations. So, we need to invalidate that window if needed. */
@@ -613,8 +635,10 @@ void OrderList::DeleteOrderAt(int index)
}
--this->num_orders;
if (!to_remove->IsType(OT_IMPLICIT)) --this->num_manual_orders;
this->timetable_duration -= (to_remove->GetTimetabledWait() + to_remove->GetTimetabledTravel());
this->total_duration -= (to_remove->GetWaitTime() + to_remove->GetTravelTime());
if (!to_remove->IsType(OT_CONDITIONAL)) {
this->timetable_duration -= (to_remove->GetTimetabledWait() + to_remove->GetTimetabledTravel());
this->total_duration -= (to_remove->GetWaitTime() + to_remove->GetTravelTime());
}
delete to_remove;
}
@@ -716,8 +740,10 @@ void OrderList::DebugCheckSanity() const
for (const Order *o = this->first; o != NULL; o = o->next) {
++check_num_orders;
if (!o->IsType(OT_IMPLICIT)) ++check_num_manual_orders;
check_timetable_duration += o->GetTimetabledWait() + o->GetTimetabledTravel();
check_total_duration += o->GetWaitTime() + o->GetTravelTime();
if (!o->IsType(OT_CONDITIONAL)) {
check_timetable_duration += o->GetTimetabledWait() + o->GetTimetabledTravel();
check_total_duration += o->GetWaitTime() + o->GetTravelTime();
}
}
assert_msg(this->num_orders == check_num_orders, "%u, %u", this->num_orders, check_num_orders);
assert_msg(this->num_manual_orders == check_num_manual_orders, "%u, %u", this->num_manual_orders, check_num_manual_orders);
@@ -1103,6 +1129,13 @@ void InsertOrder(Vehicle *v, Order *new_o, VehicleOrderID sel_ord)
u->cur_implicit_order_index = cur;
}
}
if (sel_ord <= u->cur_timetable_order_index) {
uint cur = u->cur_timetable_order_index + 1;
/* Check if we don't go out of bound */
if (cur < u->GetNumOrders()) {
u->cur_timetable_order_index = cur;
}
}
/* Update any possible open window of the vehicle */
InvalidateVehicleOrder(u, INVALID_VEH_ORDER_ID | (sel_ord << 8));
}
@@ -1245,6 +1278,12 @@ void DeleteOrder(Vehicle *v, VehicleOrderID sel_ord)
}
}
if (sel_ord < u->cur_timetable_order_index) {
u->cur_timetable_order_index--;
} else if (sel_ord == u->cur_timetable_order_index) {
u->cur_timetable_order_index = INVALID_VEH_ORDER_ID;
}
/* Update any possible open window of the vehicle */
InvalidateVehicleOrder(u, sel_ord | (INVALID_VEH_ORDER_ID << 8));
}
@@ -1296,6 +1335,7 @@ CommandCost CmdSkipToOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
v->cur_implicit_order_index = v->cur_real_order_index = sel_ord;
v->UpdateRealOrderIndex();
v->cur_timetable_order_index = INVALID_VEH_ORDER_ID;
InvalidateVehicleOrder(v, VIWD_MODIFY_ORDERS);
@@ -1384,6 +1424,8 @@ CommandCost CmdMoveOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
u->cur_implicit_order_index++;
}
u->cur_timetable_order_index = INVALID_VEH_ORDER_ID;
assert(v->orders.list == u->orders.list);
/* Update any possible open window of the vehicle */
InvalidateVehicleOrder(u, moving_order | (target_order << 8));
@@ -2169,6 +2211,7 @@ void DeleteVehicleOrders(Vehicle *v, bool keep_orderlist, bool reset_order_indic
if (reset_order_indices) {
v->cur_implicit_order_index = v->cur_real_order_index = 0;
v->cur_timetable_order_index = INVALID_VEH_ORDER_ID;
if (v->current_order.IsType(OT_LOADING)) {
CancelLoadingDueToDeletedOrder(v);
}
@@ -2408,7 +2451,7 @@ bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth, bool
UpdateVehicleTimetable(v, false);
v->cur_implicit_order_index = v->cur_real_order_index = next_order;
v->UpdateRealOrderIndex();
v->current_order_time += v->GetOrder(v->cur_real_order_index)->GetTimetabledTravel();
v->cur_timetable_order_index = v->GetIndexOfOrder(order);
/* Disable creation of implicit orders.
* When inserting them we do not know that we would have to make the conditional orders point to them. */
@@ -2417,6 +2460,7 @@ bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth, bool
SetBit(gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS);
}
} else {
v->cur_timetable_order_index = INVALID_VEH_ORDER_ID;
UpdateVehicleTimetable(v, true);
v->IncrementRealOrderIndex();
}