diff options
author | fonsinchen <fonsinchen@openttd.org> | 2014-05-01 14:49:16 +0000 |
---|---|---|
committer | fonsinchen <fonsinchen@openttd.org> | 2014-05-01 14:49:16 +0000 |
commit | 3ee31a8f893dbbedf89de9b3ecf44a71a48c6666 (patch) | |
tree | ee4d710aacfd15a4d76f1f0da1c22879fdb09126 /src | |
parent | c915d9fa55e8bb42b33c56b94c5a5e0ff446d7da (diff) | |
download | openttd-3ee31a8f893dbbedf89de9b3ecf44a71a48c6666.tar.xz |
(svn r26547) -Codechange: Collect order travel and wait times independent of timetables
Diffstat (limited to 'src')
-rw-r--r-- | src/economy.cpp | 2 | ||||
-rw-r--r-- | src/order_base.h | 80 | ||||
-rw-r--r-- | src/order_cmd.cpp | 21 | ||||
-rw-r--r-- | src/order_gui.cpp | 4 | ||||
-rw-r--r-- | src/saveload/order_sl.cpp | 4 | ||||
-rw-r--r-- | src/saveload/saveload.cpp | 3 | ||||
-rw-r--r-- | src/timetable_cmd.cpp | 101 | ||||
-rw-r--r-- | src/timetable_gui.cpp | 16 | ||||
-rw-r--r-- | src/vehicle.cpp | 2 |
9 files changed, 150 insertions, 83 deletions
diff --git a/src/economy.cpp b/src/economy.cpp index ea82ed84b..f3178f43b 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -1675,7 +1675,7 @@ static void LoadUnloadVehicle(Vehicle *front) /* We loaded less cargo than possible for all cargo types and it's not full * load and we're not supposed to wait any longer: stop loading. */ if (!anything_unloaded && full_load_amount == 0 && reservation_left == 0 && !(front->current_order.GetLoadType() & OLFB_FULL_LOAD) && - front->current_order_time >= (uint)max(front->current_order.GetWaitTime() - front->lateness_counter, 0)) { + front->current_order_time >= (uint)max(front->current_order.GetTimetabledWait() - front->lateness_counter, 0)) { SetBit(front->vehicle_flags, VF_STOP_LOADING); } } else { diff --git a/src/order_base.h b/src/order_base.h index b1f83b1c5..a67cf69bb 100644 --- a/src/order_base.h +++ b/src/order_base.h @@ -126,17 +126,17 @@ public: void SetRefit(CargoID cargo); /** How must the consist be loaded? */ - inline OrderLoadFlags GetLoadType() const { return (OrderLoadFlags)GB(this->flags, 4, 4); } + inline OrderLoadFlags GetLoadType() const { return (OrderLoadFlags)GB(this->flags, 4, 3); } /** How must the consist be unloaded? */ - inline OrderUnloadFlags GetUnloadType() const { return (OrderUnloadFlags)GB(this->flags, 0, 4); } + inline OrderUnloadFlags GetUnloadType() const { return (OrderUnloadFlags)GB(this->flags, 0, 3); } /** At which stations must we stop? */ inline OrderNonStopFlags GetNonStopType() const { return (OrderNonStopFlags)GB(this->type, 6, 2); } /** Where must we stop at the platform? */ inline OrderStopLocation GetStopLocation() const { return (OrderStopLocation)GB(this->type, 4, 2); } /** What caused us going to the depot? */ - inline OrderDepotTypeFlags GetDepotOrderType() const { return (OrderDepotTypeFlags)GB(this->flags, 0, 4); } + inline OrderDepotTypeFlags GetDepotOrderType() const { return (OrderDepotTypeFlags)GB(this->flags, 0, 3); } /** What are we going to do when in the depot. */ - inline OrderDepotActionFlags GetDepotActionType() const { return (OrderDepotActionFlags)GB(this->flags, 4, 4); } + inline OrderDepotActionFlags GetDepotActionType() const { return (OrderDepotActionFlags)GB(this->flags, 4, 3); } /** What variable do we have to compare? */ inline OrderConditionVariable GetConditionVariable() const { return (OrderConditionVariable)GB(this->dest, 11, 5); } /** What is the comparator to use? */ @@ -147,17 +147,17 @@ public: inline uint16 GetConditionValue() const { return GB(this->dest, 0, 11); } /** Set how the consist must be loaded. */ - inline void SetLoadType(OrderLoadFlags load_type) { SB(this->flags, 4, 4, load_type); } + inline void SetLoadType(OrderLoadFlags load_type) { SB(this->flags, 4, 3, load_type); } /** Set how the consist must be unloaded. */ - inline void SetUnloadType(OrderUnloadFlags unload_type) { SB(this->flags, 0, 4, unload_type); } + inline void SetUnloadType(OrderUnloadFlags unload_type) { SB(this->flags, 0, 3, unload_type); } /** Set whether we must stop at stations or not. */ inline void SetNonStopType(OrderNonStopFlags non_stop_type) { SB(this->type, 6, 2, non_stop_type); } /** Set where we must stop at the platform. */ inline void SetStopLocation(OrderStopLocation stop_location) { SB(this->type, 4, 2, stop_location); } /** Set the cause to go to the depot. */ - inline void SetDepotOrderType(OrderDepotTypeFlags depot_order_type) { SB(this->flags, 0, 4, depot_order_type); } + inline void SetDepotOrderType(OrderDepotTypeFlags depot_order_type) { SB(this->flags, 0, 3, depot_order_type); } /** Set what we are going to do in the depot. */ - inline void SetDepotActionType(OrderDepotActionFlags depot_service_type) { SB(this->flags, 4, 4, depot_service_type); } + inline void SetDepotActionType(OrderDepotActionFlags depot_service_type) { SB(this->flags, 4, 3, depot_service_type); } /** Set variable we have to compare. */ inline void SetConditionVariable(OrderConditionVariable condition_variable) { SB(this->dest, 11, 5, condition_variable); } /** Set the comparator to use. */ @@ -167,9 +167,23 @@ public: /** Set the value to base the skip on. */ inline void SetConditionValue(uint16 value) { SB(this->dest, 0, 11, value); } - /** Get the time in ticks a vehicle should wait at the destination. */ + /* As conditional orders write their "skip to" order all over the flags, we cannot check the + * flags to find out if timetabling is enabled. However, as conditional orders are never + * autofilled we can be sure that any non-zero values for their wait_time and travel_time are + * explicitly set (but travel_time is actually unused for conditionals). */ + + /** Does this order have an explicit wait time set? */ + inline bool IsWaitTimetabled() const { return this->IsType(OT_CONDITIONAL) ? this->wait_time > 0 : HasBit(this->flags, 3); } + /** Does this order have an explicit travel time set? */ + inline bool IsTravelTimetabled() const { return this->IsType(OT_CONDITIONAL) ? this->travel_time > 0 : HasBit(this->flags, 7); } + + /** Get the time in ticks a vehicle should wait at the destination or 0 if it's not timetabled. */ + inline uint16 GetTimetabledWait() const { return this->IsWaitTimetabled() ? this->wait_time : 0; } + /** Get the time in ticks a vehicle should take to reach the destination or 0 if it's not timetabled. */ + inline uint16 GetTimetabledTravel() const { return this->IsTravelTimetabled() ? this->travel_time : 0; } + /** Get the time in ticks a vehicle will probably wait at the destination (timetabled or not). */ inline uint16 GetWaitTime() const { return this->wait_time; } - /** Get the time in ticks a vehicle should take to reach the destination. */ + /** Get the time in ticks a vehicle will probably take to reach the destination (timetabled or not). */ inline uint16 GetTravelTime() const { return this->travel_time; } /** @@ -179,9 +193,21 @@ public: */ inline uint16 GetMaxSpeed() const { return this->max_speed; } - /** Set the time in ticks a vehicle should wait at the destination. */ - inline void SetWaitTime(uint16 time) { this->wait_time = time; } - /** Set the time in ticks a vehicle should take to reach the destination. */ + /** Set if the wait time is explicitly timetabled (unless the order is conditional). */ + inline void SetWaitTimetabled(bool timetabled) { if (!this->IsType(OT_CONDITIONAL)) SB(this->flags, 3, 1, timetabled ? 1 : 0); } + /** Set if the travel time is explicitly timetabled (unless the order is conditional). */ + inline void SetTravelTimetabled(bool timetabled) { if (!this->IsType(OT_CONDITIONAL)) SB(this->flags, 7, 1, timetabled ? 1 : 0); } + + /** + * Set the time in ticks to wait at the destination. + * @param time Time to set as wait time. + */ + inline void SetWaitTime(uint16 time) { this->wait_time = time; } + + /** + * Set the time in ticks to take for travelling to the destination. + * @param time Time to set as travel time. + */ inline void SetTravelTime(uint16 time) { this->travel_time = time; } /** @@ -197,11 +223,14 @@ public: TileIndex GetLocation(const Vehicle *v, bool airport = false) const; - /** Checks if this order has travel_time and if needed wait_time set. */ + /** Checks if travel_time and wait_time apply to this order and if they are timetabled. */ inline bool IsCompletelyTimetabled() const { - if (this->travel_time == 0 && !this->IsType(OT_CONDITIONAL)) return false; - if (this->wait_time == 0 && this->IsType(OT_GOTO_STATION) && !(this->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION)) return false; + if (!this->IsTravelTimetabled() && !this->IsType(OT_CONDITIONAL)) return false; + if (!this->IsWaitTimetabled() && this->IsType(OT_GOTO_STATION) && + !(this->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION)) { + return false; + } return true; } @@ -233,13 +262,14 @@ private: uint num_vehicles; ///< NOSAVE: Number of vehicles that share this order list. Vehicle *first_shared; ///< NOSAVE: pointer to the first vehicle in the shared order chain. - Ticks timetable_duration; ///< NOSAVE: Total duration of the order list + Ticks timetable_duration; ///< NOSAVE: Total timetabled duration of the order list. + Ticks total_duration; ///< NOSAVE: Total (timetabled or not) duration of the order list. public: /** Default constructor producing an invalid order list. */ OrderList(VehicleOrderID num_orders = INVALID_VEH_ORDER_ID) : first(NULL), num_orders(num_orders), num_manual_orders(0), num_vehicles(0), first_shared(NULL), - timetable_duration(0) { } + timetable_duration(0), total_duration(0) { } /** * Create an order list with the given order chain for the given vehicle. @@ -340,10 +370,22 @@ public: inline Ticks GetTimetableDurationIncomplete() const { return this->timetable_duration; } /** + * Gets the known duration of the vehicles orders, timetabled or not. + * @return known order duration. + */ + inline Ticks GetTotalDuration() const { return this->total_duration; } + + /** * Must be called if an order's timetable is changed to update internal book keeping. * @param delta By how many ticks has the timetable duration changed */ - void UpdateOrderTimetable(Ticks delta) { this->timetable_duration += delta; } + void UpdateTimetableDuration(Ticks delta) { this->timetable_duration += delta; } + + /** + * Must be called if an order's timetable is changed to update internal book keeping. + * @param delta By how many ticks has the total duration changed + */ + void UpdateTotalDuration(Ticks delta) { this->total_duration += delta; } void FreeChain(bool keep_orderlist = false); diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 1b74416da..9aff6cde4 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -297,11 +297,13 @@ void OrderList::Initialize(Order *chain, Vehicle *v) this->num_manual_orders = 0; this->num_vehicles = 1; this->timetable_duration = 0; + this->total_duration = 0; 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->GetWaitTime() + o->GetTravelTime(); + 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()) { @@ -476,7 +478,8 @@ 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->GetWaitTime() + new_order->GetTravelTime(); + 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. */ @@ -508,7 +511,8 @@ void OrderList::DeleteOrderAt(int index) } --this->num_orders; if (!to_remove->IsType(OT_IMPLICIT)) --this->num_manual_orders; - this->timetable_duration -= (to_remove->GetWaitTime() + to_remove->GetTravelTime()); + this->timetable_duration -= (to_remove->GetTimetabledWait() + to_remove->GetTimetabledTravel()); + this->total_duration -= (to_remove->GetWaitTime() + to_remove->GetTravelTime()); delete to_remove; } @@ -603,26 +607,29 @@ void OrderList::DebugCheckSanity() const VehicleOrderID check_num_manual_orders = 0; uint check_num_vehicles = 0; Ticks check_timetable_duration = 0; + Ticks check_total_duration = 0; DEBUG(misc, 6, "Checking OrderList %hu for sanity...", this->index); 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->GetWaitTime() + o->GetTravelTime(); + check_timetable_duration += o->GetTimetabledWait() + o->GetTimetabledTravel(); + check_total_duration += o->GetWaitTime() + o->GetTravelTime(); } assert(this->num_orders == check_num_orders); assert(this->num_manual_orders == check_num_manual_orders); assert(this->timetable_duration == check_timetable_duration); + assert(this->total_duration == check_total_duration); for (const Vehicle *v = this->first_shared; v != NULL; v = v->NextShared()) { ++check_num_vehicles; assert(v->orders.list == this); } assert(this->num_vehicles == check_num_vehicles); - DEBUG(misc, 6, "... detected %u orders (%u manual), %u vehicles, %i ticks", + DEBUG(misc, 6, "... detected %u orders (%u manual), %u vehicles, %i timetabled, %i total", (uint)this->num_orders, (uint)this->num_manual_orders, - this->num_vehicles, this->timetable_duration); + this->num_vehicles, this->timetable_duration, this->total_duration); } /** @@ -2081,7 +2088,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)->GetTravelTime(); + v->current_order_time += v->GetOrder(v->cur_real_order_index)->GetTimetabledTravel(); /* Disable creation of implicit orders. * When inserting them we do not know that we would have to make the conditional orders point to them. */ diff --git a/src/order_gui.cpp b/src/order_gui.cpp index d5e5c5a2d..2a3007080 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -266,7 +266,7 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int if (timetable) { SetDParam(3, STR_EMPTY); - if (order->GetWaitTime() > 0) { + if (order->IsWaitTimetabled()) { SetDParam(5, STR_TIMETABLE_STAY_FOR); SetTimetableParams(6, 7, order->GetWaitTime()); } @@ -334,7 +334,7 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int SetDParam(4, value); } - if (timetable && order->GetWaitTime() > 0) { + if (timetable && order->IsWaitTimetabled()) { SetDParam(5, STR_TIMETABLE_AND_TRAVEL_FOR); SetTimetableParams(6, 7, order->GetWaitTime()); } else { diff --git a/src/saveload/order_sl.cpp b/src/saveload/order_sl.cpp index 40f83f832..63701ffa0 100644 --- a/src/saveload/order_sl.cpp +++ b/src/saveload/order_sl.cpp @@ -186,6 +186,10 @@ static void Load_ORDR() while ((index = SlIterateArray()) != -1) { Order *order = new (index) Order(); SlObject(order, GetOrderDescription()); + if (IsSavegameVersionBefore(190)) { + order->SetTravelTimetabled(order->GetTravelTime() > 0); + order->SetWaitTimetabled(order->GetWaitTime() > 0); + } } } } diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index 647423ada..a9c71c1e7 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -257,8 +257,9 @@ * 187 25899 * 188 26169 1.4.x * 189 26450 + * 190 ????? */ -extern const uint16 SAVEGAME_VERSION = 189; ///< Current savegame version of OpenTTD. +extern const uint16 SAVEGAME_VERSION = 190; ///< Current savegame version of OpenTTD. SavegameType _savegame_type; ///< type of savegame we are loading 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 diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index 42c7de33f..cd0125255 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -78,9 +78,9 @@ static bool CanDetermineTimeTaken(const Order *order, bool travelling) /* Current order is conditional */ if (order->IsType(OT_CONDITIONAL) || order->IsType(OT_IMPLICIT)) return false; /* No travel time and we have not already finished travelling */ - if (travelling && order->GetTravelTime() == 0) return false; + if (travelling && !order->IsTravelTimetabled()) return false; /* No wait time but we are loading at this timetabled station */ - if (!travelling && order->GetWaitTime() == 0 && order->IsType(OT_GOTO_STATION) && + if (!travelling && !order->IsWaitTimetabled() && order->IsType(OT_GOTO_STATION) && !(order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION)) { return false; } @@ -121,12 +121,12 @@ static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID if (!order->IsType(OT_IMPLICIT)) { if (travelling || i != start) { if (!CanDetermineTimeTaken(order, true)) return; - sum += order->GetTravelTime(); + sum += order->GetTimetabledTravel(); table[i].arrival = sum; } if (!CanDetermineTimeTaken(order, false)) return; - sum += order->GetWaitTime(); + sum += order->GetTimetabledWait(); table[i].departure = sum; } @@ -143,7 +143,7 @@ static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID * travelling part of the first order. */ if (!travelling) { if (!CanDetermineTimeTaken(order, true)) return; - sum += order->GetTravelTime(); + sum += order->GetTimetabledTravel(); table[i].arrival = sum; } } @@ -401,12 +401,12 @@ struct TimetableWindow : Window { } else if (order->IsType(OT_IMPLICIT)) { string = STR_TIMETABLE_NOT_TIMETABLEABLE; colour = ((i == selected) ? TC_SILVER : TC_GREY) | TC_NO_SHADE; - } else if (order->GetTravelTime() == 0) { + } else if (!order->IsTravelTimetabled()) { string = order->GetMaxSpeed() != UINT16_MAX ? STR_TIMETABLE_TRAVEL_NOT_TIMETABLED_SPEED : STR_TIMETABLE_TRAVEL_NOT_TIMETABLED; } else { - SetTimetableParams(0, 1, order->GetTravelTime()); + SetTimetableParams(0, 1, order->GetTimetabledTravel()); string = order->GetMaxSpeed() != UINT16_MAX ? STR_TIMETABLE_TRAVEL_FOR_SPEED : STR_TIMETABLE_TRAVEL_FOR; } @@ -546,7 +546,7 @@ struct TimetableWindow : Window { StringID current = STR_EMPTY; if (order != NULL) { - uint time = (selected % 2 == 1) ? order->GetTravelTime() : order->GetWaitTime(); + uint time = (selected % 2 == 1) ? order->GetTimetabledTravel() : order->GetTimetabledWait(); if (!_settings_client.gui.timetable_in_ticks) time /= DAY_TICKS; if (time != 0) { diff --git a/src/vehicle.cpp b/src/vehicle.cpp index cc781b48d..edfbee499 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -2137,7 +2137,7 @@ void Vehicle::HandleLoading(bool mode) { switch (this->current_order.GetType()) { case OT_LOADING: { - uint wait_time = max(this->current_order.GetWaitTime() - this->lateness_counter, 0); + uint wait_time = max(this->current_order.GetTimetabledWait() - this->lateness_counter, 0); /* Not the first call for this tick, or still loading */ if (mode || !HasBit(this->vehicle_flags, VF_LOADING_FINISHED) || this->current_order_time < wait_time) return; |