summaryrefslogtreecommitdiff
path: root/src/timetable_cmd.cpp
diff options
context:
space:
mode:
authorfonsinchen <fonsinchen@openttd.org>2014-05-01 14:49:16 +0000
committerfonsinchen <fonsinchen@openttd.org>2014-05-01 14:49:16 +0000
commit3ee31a8f893dbbedf89de9b3ecf44a71a48c6666 (patch)
treeee4d710aacfd15a4d76f1f0da1c22879fdb09126 /src/timetable_cmd.cpp
parentc915d9fa55e8bb42b33c56b94c5a5e0ff446d7da (diff)
downloadopenttd-3ee31a8f893dbbedf89de9b3ecf44a71a48c6666.tar.xz
(svn r26547) -Codechange: Collect order travel and wait times independent of timetables
Diffstat (limited to 'src/timetable_cmd.cpp')
-rw-r--r--src/timetable_cmd.cpp101
1 files changed, 57 insertions, 44 deletions
diff --git a/src/timetable_cmd.cpp b/src/timetable_cmd.cpp
index a0f797bea..34990e3f6 100644
--- a/src/timetable_cmd.cpp
+++ b/src/timetable_cmd.cpp
@@ -28,21 +28,27 @@
* @param order_number The index of the timetable in the order list.
* @param val The new data of the timetable entry.
* @param mtf Which part of the timetable entry to change.
+ * @param timetabled If the new value is explicitly timetabled.
*/
-static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint16 val, ModifyTimetableFlags mtf)
+static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint16 val, ModifyTimetableFlags mtf, bool timetabled)
{
Order *order = v->GetOrder(order_number);
- int delta = 0;
+ int total_delta = 0;
+ int timetable_delta = 0;
switch (mtf) {
case MTF_WAIT_TIME:
- delta = val - order->GetWaitTime();
+ total_delta = val - order->GetWaitTime();
+ timetable_delta = (timetabled ? val : 0) - order->GetTimetabledWait();
order->SetWaitTime(val);
+ order->SetWaitTimetabled(timetabled);
break;
case MTF_TRAVEL_TIME:
- delta = val - order->GetTravelTime();
+ total_delta = val - order->GetTravelTime();
+ timetable_delta = (timetabled ? val : 0) - order->GetTimetabledTravel();
order->SetTravelTime(val);
+ order->SetTravelTimetabled(timetabled);
break;
case MTF_TRAVEL_SPEED:
@@ -52,17 +58,20 @@ static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint16 val,
default:
NOT_REACHED();
}
- v->orders.list->UpdateOrderTimetable(delta);
+ v->orders.list->UpdateTotalDuration(total_delta);
+ v->orders.list->UpdateTimetableDuration(timetable_delta);
for (v = v->FirstShared(); v != NULL; v = v->NextShared()) {
if (v->cur_real_order_index == order_number && v->current_order.Equals(*order)) {
switch (mtf) {
case MTF_WAIT_TIME:
v->current_order.SetWaitTime(val);
+ v->current_order.SetWaitTimetabled(timetabled);
break;
case MTF_TRAVEL_TIME:
v->current_order.SetTravelTime(val);
+ v->current_order.SetTravelTimetabled(timetabled);
break;
case MTF_TRAVEL_SPEED:
@@ -107,8 +116,8 @@ CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, u
ModifyTimetableFlags mtf = Extract<ModifyTimetableFlags, 28, 2>(p1);
if (mtf >= MTF_END) return CMD_ERROR;
- int wait_time = order->GetWaitTime();
- int travel_time = order->GetTravelTime();
+ int wait_time = order->GetTimetabledWait();
+ int travel_time = order->GetTimetabledTravel();
int max_speed = order->GetMaxSpeed();
switch (mtf) {
case MTF_WAIT_TIME:
@@ -128,7 +137,7 @@ CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, u
NOT_REACHED();
}
- if (wait_time != order->GetWaitTime()) {
+ if (wait_time != order->GetTimetabledWait()) {
switch (order->GetType()) {
case OT_GOTO_STATION:
if (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) return_cmd_error(STR_ERROR_TIMETABLE_NOT_STOPPING_HERE);
@@ -141,13 +150,13 @@ CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, u
}
}
- if (travel_time != order->GetTravelTime() && order->IsType(OT_CONDITIONAL)) return CMD_ERROR;
+ if (travel_time != order->GetTimetabledTravel() && order->IsType(OT_CONDITIONAL)) return CMD_ERROR;
if (max_speed != order->GetMaxSpeed() && (order->IsType(OT_CONDITIONAL) || v->type == VEH_AIRCRAFT)) return CMD_ERROR;
if (flags & DC_EXEC) {
- if (wait_time != order->GetWaitTime()) ChangeTimetable(v, order_number, wait_time, MTF_WAIT_TIME);
- if (travel_time != order->GetTravelTime()) ChangeTimetable(v, order_number, travel_time, MTF_TRAVEL_TIME);
- if (max_speed != order->GetMaxSpeed()) ChangeTimetable(v, order_number, max_speed, MTF_TRAVEL_SPEED);
+ if (wait_time != order->GetTimetabledWait()) ChangeTimetable(v, order_number, wait_time, MTF_WAIT_TIME, wait_time > 0);
+ if (travel_time != order->GetTimetabledTravel()) ChangeTimetable(v, order_number, travel_time, MTF_TRAVEL_TIME, travel_time > 0);
+ if (max_speed != order->GetMaxSpeed()) ChangeTimetable(v, order_number, max_speed, MTF_TRAVEL_SPEED, max_speed != UINT16_MAX);
}
return CommandCost();
@@ -347,7 +356,6 @@ CommandCost CmdAutofillTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1,
*/
void UpdateVehicleTimetable(Vehicle *v, bool travelling)
{
- uint timetabled = travelling ? v->current_order.GetTravelTime() : v->current_order.GetWaitTime();
uint time_taken = v->current_order_time;
v->current_order_time = 0;
@@ -380,42 +388,47 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling)
if (!HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED)) return;
- if (HasBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE)) {
- if (travelling && !HasBit(v->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME)) {
- /* Need to clear that now as otherwise we are not able to reduce the wait time */
- v->current_order.SetWaitTime(0);
- }
+ bool autofilling = HasBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE);
+ if (travelling && !HasBit(v->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME)) {
+ /* Need to clear that now as otherwise we are not able to reduce the wait time */
+ v->current_order.SetWaitTime(0);
+ }
- if (just_started) return;
-
- /* Modify station waiting time only if our new value is larger (this is
- * always the case when we cleared the timetable). */
- if (!v->current_order.IsType(OT_CONDITIONAL) && (travelling || time_taken > v->current_order.GetWaitTime())) {
- /* Round the time taken up to the nearest day, as this will avoid
- * confusion for people who are timetabling in days, and can be
- * adjusted later by people who aren't.
- * For trains/aircraft multiple movement cycles are done in one
- * tick. This makes it possible to leave the station and process
- * e.g. a depot order in the same tick, causing it to not fill
- * the timetable entry like is done for road vehicles/ships.
- * Thus always make sure at least one tick is used between the
- * processing of different orders when filling the timetable. */
- time_taken = CeilDiv(max(time_taken, 1U), DAY_TICKS) * DAY_TICKS;
-
- ChangeTimetable(v, v->cur_real_order_index, time_taken, travelling ? MTF_TRAVEL_TIME : MTF_WAIT_TIME);
- }
+ if (just_started) return;
- if (v->cur_real_order_index == first_manual_order && travelling) {
- /* If we just started we would have returned earlier and have not reached
- * this code. So obviously, we have completed our round: So turn autofill
- * off again. */
- ClrBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE);
- ClrBit(v->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME);
+ /* Modify station waiting time only if our new value is larger (this is
+ * always the case when we cleared the timetable). */
+ if (!v->current_order.IsType(OT_CONDITIONAL) && (travelling || time_taken > v->current_order.GetWaitTime())) {
+ /* Round the time taken up to the nearest day, as this will avoid
+ * confusion for people who are timetabling in days, and can be
+ * adjusted later by people who aren't.
+ * For trains/aircraft multiple movement cycles are done in one
+ * tick. This makes it possible to leave the station and process
+ * e.g. a depot order in the same tick, causing it to not fill
+ * the timetable entry like is done for road vehicles/ships.
+ * Thus always make sure at least one tick is used between the
+ * processing of different orders when filling the timetable. */
+ uint time_to_set = CeilDiv(max(time_taken, 1U), DAY_TICKS) * DAY_TICKS;
+
+ if (travelling && (autofilling || !v->current_order.IsTravelTimetabled())) {
+ ChangeTimetable(v, v->cur_real_order_index, time_to_set, MTF_TRAVEL_TIME, autofilling);
+ } else if (!travelling && (autofilling || !v->current_order.IsWaitTimetabled())) {
+ ChangeTimetable(v, v->cur_real_order_index, time_to_set, MTF_WAIT_TIME, autofilling);
}
- return;
}
- if (just_started) return;
+ if (v->cur_real_order_index == first_manual_order && travelling) {
+ /* If we just started we would have returned earlier and have not reached
+ * this code. So obviously, we have completed our round: So turn autofill
+ * off again. */
+ ClrBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE);
+ ClrBit(v->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME);
+ }
+
+ if (autofilling) return;
+
+ uint timetabled = travelling ? v->current_order.GetTimetabledTravel() :
+ v->current_order.GetTimetabledWait();
/* Vehicles will wait at stations if they arrive early even if they are not
* timetabled to wait there, so make sure the lateness counter is updated