Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Index: src/vehicle_base.h
- ===================================================================
- --- src/vehicle_base.h (revision 25615)
- +++ src/vehicle_base.h (working copy)
- @@ -44,6 +44,7 @@
- VF_TIMETABLE_STARTED, ///< Whether the vehicle has started running on the timetable yet.
- VF_AUTOFILL_TIMETABLE, ///< Whether the vehicle should fill in the timetable automatically.
- VF_AUTOFILL_PRES_WAIT_TIME, ///< Whether non-destructive auto-fill should preserve waiting times
- + VF_AUTOMATE_TIMETABLE, ///< Whether the vehicle should manage the timetable automatically.
- VF_STOP_LOADING, ///< Don't load anymore during the next load cycle.
- VF_PATHFINDER_LOST, ///< Vehicle's pathfinder is lost.
- VF_SERVINT_IS_CUSTOM, ///< Service interval is custom.
- @@ -133,6 +134,10 @@
- Vehicle *next_shared; ///< pointer to the next vehicle that shares the order
- Vehicle *previous_shared; ///< NOSAVE: pointer to the previous vehicle in the shared order chain
- +
- + Vehicle *ahead_separation;
- + Vehicle *behind_separation;
- +
- public:
- friend const SaveLoad *GetVehicleDescription(VehicleType vt); ///< So we can use private/protected variables in the saveload code
- friend void FixOldVehicles();
- @@ -154,6 +159,12 @@
- CargoPayment *cargo_payment; ///< The cargo payment we're currently in
- + /* Used for timetabling. */
- + uint32 current_order_time; ///< How many ticks have passed since this order started.
- + uint32 current_loading_time; ///< How long loading took. Less than current_order_time if vehicle is early.
- + int32 lateness_counter; ///< How many ticks late (or early if negative) this vehicle is.
- + Date timetable_start; ///< When the vehicle is supposed to start the timetable.
- +
- Rect coord; ///< NOSAVE: Graphical bounding box of the vehicle, i.e. what to redraw on moves.
- Vehicle *hash_viewport_next; ///< NOSAVE: Next vehicle in the visual location hash.
- @@ -565,6 +576,37 @@
- */
- inline Order *GetFirstOrder() const { return (this->orders.list == NULL) ? NULL : this->orders.list->GetFirstOrder(); }
- + /**
- + * Get the vehicle ahead on track.
- + * @return the vehicle ahead on track or NULL when there isn't one.
- + */
- + inline Vehicle *AheadSeparation() const { return this->ahead_separation; }
- +
- + /**
- + * Get the vehicle behind on track.
- + * @return the vehicle behind on track or NULL when there isn't one.
- + */
- + inline Vehicle *BehindSeparation() const { return this->behind_separation; }
- +
- + /**
- + * Clears a vehicle's separation status, removing it from any chain.
- + */
- + void ClearSeparation();
- +
- + /**
- + * Adds this vehicle to a shared vehicle separation chain.
- + * @param v_other a vehicle of the separation chain
- + * @pre !this->IsOrderListShared()
- + */
- + void InitSeparation();
- +
- + /**
- + * Adds this vehicle behind another in a separation chain.
- + * @param v_other a vehicle of the separation chain.
- + * @pre !this->IsOrderListShared()
- + */
- + void AddToSeparationBehind(Vehicle *v_other);
- +
- void AddToShared(Vehicle *shared_chain);
- void RemoveFromShared();
- @@ -634,6 +676,18 @@
- this->profit_this_year = src->profit_this_year;
- this->profit_last_year = src->profit_last_year;
- +
- + this->current_order_time = src->current_order_time;
- + this->current_loading_time = src->current_loading_time;
- + this->lateness_counter = src->lateness_counter;
- + this->timetable_start = src->timetable_start;
- +
- + if (HasBit(src->vehicle_flags, VF_TIMETABLE_STARTED)) SetBit(this->vehicle_flags, VF_TIMETABLE_STARTED);
- + if (HasBit(src->vehicle_flags, VF_AUTOFILL_TIMETABLE)) SetBit(this->vehicle_flags, VF_AUTOFILL_TIMETABLE);
- + if (HasBit(src->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME)) SetBit(this->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME);
- +
- + this->service_interval = src->service_interval;
- +
- }
- Index: src/vehicle_cmd.cpp
- ===================================================================
- --- src/vehicle_cmd.cpp (revision 25615)
- +++ src/vehicle_cmd.cpp (working copy)
- @@ -572,6 +572,9 @@
- if (flags & DC_EXEC) {
- if (v->IsStoppedInDepot() && (flags & DC_AUTOREPLACE) == 0) DeleteVehicleNews(p1, STR_NEWS_TRAIN_IS_WAITING + v->type);
- + if (_settings_game.order.timetable_separation) v->ClearSeparation();
- + if (_settings_game.order.timetable_separation) ClrBit(v->vehicle_flags, VF_TIMETABLE_STARTED);
- +
- v->vehstatus ^= VS_STOPPED;
- if (v->type != VEH_TRAIN) v->cur_speed = 0; // trains can stop 'slowly'
- v->MarkDirty();
- Index: src/table/settings.ini
- ===================================================================
- --- src/table/settings.ini (revision 25615)
- +++ src/table/settings.ini (working copy)
- @@ -1060,6 +1060,20 @@
- from = 67
- to = 158
- +[SDT_BOOL]
- +base = GameSettings
- +var = order.timetable_automated
- +from = TIMESEP_SV
- +def = 1
- +str = STR_CONFIG_SETTING_TIMETABLE_AUTOMATED
- +
- +[SDT_BOOL]
- +base = GameSettings
- +var = order.timetable_separation
- +from = TIMESEP_SV
- +def = 1
- +str = STR_CONFIG_SETTING_TIMETABLE_SEPARATION
- +
- [SDT_VAR]
- base = GameSettings
- var = vehicle.plane_speed
- Index: src/settings_type.h
- ===================================================================
- --- src/settings_type.h (revision 25615)
- +++ src/settings_type.h (working copy)
- @@ -436,6 +436,8 @@
- bool gradual_loading; ///< load vehicles gradually
- bool selectgoods; ///< only send the goods to station if a train has been there
- bool no_servicing_if_no_breakdowns; ///< don't send vehicles to depot when breakdowns are disabled
- + bool timetable_automated; ///< whether to automatically manage timetables
- + bool timetable_separation; ///< whether to perform automatic separation based on timetable
- bool serviceathelipad; ///< service helicopters at helipads automatically (no need to send to depot)
- };
- Index: src/lang/english.txt
- ===================================================================
- --- src/lang/english.txt (revision 25615)
- +++ src/lang/english.txt (working copy)
- @@ -1354,8 +1354,10 @@
- STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS_HELPTEXT :Enable usage of the advanced vehicle lists for grouping vehicles
- STR_CONFIG_SETTING_LOADING_INDICATORS :Use loading indicators: {STRING2}
- STR_CONFIG_SETTING_LOADING_INDICATORS_HELPTEXT :Select whether loading indicators are displayed above loading or unloading vehicles
- +STR_CONFIG_SETTING_TIMETABLE_AUTOMATED :Automatically manage timetables: {STRING2}
- STR_CONFIG_SETTING_TIMETABLE_IN_TICKS :Show timetable in ticks rather than days: {STRING2}
- STR_CONFIG_SETTING_TIMETABLE_IN_TICKS_HELPTEXT :Show travel times in time tables in game ticks instead of days
- +STR_CONFIG_SETTING_TIMETABLE_SEPARATION :Use timetable to ensure vehicle separation: {STRING2}
- STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE :Show arrival and departure in timetables: {STRING2}
- STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE_HELPTEXT :Display anticipated arrival and departure times in timetables
- STR_CONFIG_SETTING_QUICKGOTO :Quick creation of vehicle orders: {STRING2}
- @@ -3845,6 +3847,9 @@
- STR_TIMETABLE_AUTOFILL :{BLACK}Autofill
- STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}Fill the timetable automatically with the values from the next journey (Ctrl+Click to try to keep waiting times)
- +STR_TIMETABLE_AUTOMATE :{BLACK}Automate
- +STR_TIMETABLE_AUTOMATE_TOOLTIP :{BLACK}Manage the timetables automatically by updating the values for each journey
- +
- STR_TIMETABLE_EXPECTED :{BLACK}Expected
- STR_TIMETABLE_SCHEDULED :{BLACK}Scheduled
- STR_TIMETABLE_EXPECTED_TOOLTIP :{BLACK}Switch between expected and scheduled
- Index: src/timetable_cmd.cpp
- ===================================================================
- --- src/timetable_cmd.cpp (revision 25615)
- +++ src/timetable_cmd.cpp (working copy)
- @@ -15,6 +15,7 @@
- #include "date_func.h"
- #include "window_func.h"
- #include "vehicle_base.h"
- +#include "settings_type.h"
- #include "cmd_helper.h"
- #include "core/sort_func.hpp"
- @@ -339,6 +340,164 @@
- }
- /**
- + * Start or stop automatic management of timetables.
- + * @param tile Not used.
- + * @param flags Operation to perform.
- + * @param p1 Vehicle index.
- + * @param p2 Various bitstuffed elements
- + * - p2 = (bit 0) - Set to 1 to enable, 0 to disable automation.
- + * - p2 = (bit 1) - Ctrl was pressed. Used when disabling to keep times.
- + * @param text unused
- + * @return the cost of this operation or an error
- + */
- +
- +CommandCost CmdAutomateTimetable(TileIndex index, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
- +{
- + if (!_settings_game.order.timetable_automated) return CMD_ERROR;
- +
- + VehicleID veh = GB(p1, 0, 16);
- +
- + Vehicle *v = Vehicle::GetIfValid(veh);
- + if (v == NULL || !v->IsPrimaryVehicle()) return CMD_ERROR;
- +
- + CommandCost ret = CheckOwnership(v->owner);
- + if (ret.Failed()) return ret;
- +
- + if (flags & DC_EXEC) {
- + for (Vehicle *v2 = v->FirstShared(); v2 != NULL; v2 = v2->NextShared()) {
- + if (HasBit(p2, 0)) {
- + /* Automated timetable. Set flags and clear current times. */
- + SetBit(v2->vehicle_flags, VF_AUTOMATE_TIMETABLE);
- + ClrBit(v2->vehicle_flags, VF_AUTOFILL_TIMETABLE);
- + ClrBit(v2->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME);
- + ClrBit(v2->vehicle_flags, VF_TIMETABLE_STARTED);
- + v2->timetable_start = 0;
- + v2->lateness_counter = 0;
- + v2->current_loading_time = 0;
- + v2->ClearSeparation();
- + } else {
- + /* De-automate timetable. Clear flags. */
- + ClrBit(v2->vehicle_flags, VF_AUTOMATE_TIMETABLE);
- + ClrBit(v2->vehicle_flags, VF_AUTOFILL_TIMETABLE);
- + ClrBit(v2->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME);
- + v2->ClearSeparation();
- + if (!HasBit(p2, 1)) {
- + /* Ctrl wasn't pressed, so clear all timetabled times. */
- + SetBit(v2->vehicle_flags, VF_TIMETABLE_STARTED);
- + v2->timetable_start = 0;
- + v2->lateness_counter = 0;
- + v2->current_loading_time = 0;
- + OrderList *orders = v2->orders.list;
- + if (orders != NULL) {
- + for (int i = 0; i < orders->GetNumOrders(); i++) {
- + ChangeTimetable(v2, i, 0, MTF_WAIT_TIME);
- + ChangeTimetable(v2, i, 0, MTF_TRAVEL_TIME);
- + }
- + }
- + }
- + }
- + SetWindowDirty(WC_VEHICLE_TIMETABLE, v2->index);
- + }
- + }
- +
- + return CommandCost();
- +}
- +
- +int TimeToFinishOrder(Vehicle *v, int n)
- +{
- + int left;
- + Order *order = v->GetOrder(n);
- + assert(order != NULL);
- + if ((v->cur_real_order_index == n) && (v->last_station_visited == order->GetDestination())) {
- + if (order->wait_time == 0) return -1;
- + if (v->current_loading_time > 0) {
- + left = order->wait_time - v->current_order_time;
- + } else {
- + left = order->wait_time;
- + }
- + if (left < 0) left = 0;
- + } else {
- + left = order->travel_time;
- + if (v->cur_real_order_index == n) left -= v->current_order_time;
- + if (order->travel_time == 0 || order->wait_time == 0) return -1;
- + if (left < 0) left = 0;
- + left += order->wait_time;
- + }
- + return left;
- +}
- +
- +int SeparationBetween(Vehicle *v1, Vehicle *v2)
- +{
- + if (v1 == v2) return -1;
- + int separation = 0;
- + int time;
- + int n = v1->cur_real_order_index;
- + while (n != v2->cur_real_order_index) {
- + time = TimeToFinishOrder(v1, n);
- + if (time == -1) return -1;
- + separation += time;
- + n++;
- + if (n >= v1->GetNumOrders()) n = 0;
- + }
- + int time1 = TimeToFinishOrder(v1, n);
- + int time2 = TimeToFinishOrder(v2, n);
- + if (time1 == -1 || time2 == -1) return -1;
- + time = time1 - time2;
- + if (time < 0) {
- + for (n = 0; n < v1->GetNumOrders(); n++) {
- + Order *order = v1->GetOrder(n);
- + if (order->travel_time == 0 || order->wait_time == 0) return -1;
- + time += order->travel_time + order->wait_time;
- + }
- + }
- + separation += time;
- + assert(separation >= 0);
- + if (separation == 0) return -1;
- + return separation;
- +}
- +
- +void UpdateSeparationOrder(Vehicle *v_start)
- +{
- + /* First check if we have a vehicle ahead, and if not search for one. */
- + if (v_start->AheadSeparation() == NULL) {
- + v_start->InitSeparation();
- + }
- + if (v_start->AheadSeparation() == NULL) {
- + return;
- + }
- + /* Switch positions if necessary. */
- + int swaps = 0;
- + bool done = false;
- + while (!done) {
- + done = true;
- + int min_sep = SeparationBetween(v_start, v_start->AheadSeparation());
- + Vehicle *v = v_start;
- + do {
- + if (v != v_start) {
- + int tmp_sep = SeparationBetween(v_start, v);
- + if (tmp_sep < min_sep && tmp_sep != -1) {
- + swaps++;
- + if (swaps >= 50) {
- + return;
- + }
- + done = false;
- + v_start->ClearSeparation();
- + v_start->AddToSeparationBehind(v);
- + break;
- + }
- + }
- + int separation_ahead = SeparationBetween(v, v->AheadSeparation());
- + int separation_behind = SeparationBetween(v->BehindSeparation(), v);
- + v->lateness_counter = (separation_ahead - separation_behind) / 2;
- + if (separation_ahead == -1 || separation_behind == -1) v->lateness_counter = 0;
- + v = v->AheadSeparation();
- + } while (v != v_start);
- + }
- +}
- +
- +
- +
- +/**
- * Update the timetable for the vehicle.
- * @param v The vehicle to update the timetable for.
- * @param travelling Whether we just travelled or waited at a station.
- @@ -346,9 +505,12 @@
- void UpdateVehicleTimetable(Vehicle *v, bool travelling)
- {
- uint timetabled = travelling ? v->current_order.travel_time : v->current_order.wait_time;
- + if (!travelling) v->current_loading_time++; // +1 because this time is one tick behind
- uint time_taken = v->current_order_time;
- + uint time_loading = v->current_loading_time;
- v->current_order_time = 0;
- + v->current_loading_time = 0;
- if (v->current_order.IsType(OT_IMPLICIT)) return; // no timetabling of auto orders
- @@ -359,6 +521,18 @@
- bool just_started = false;
- + /* Start automated timetables at first opportunity */
- + if (!HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED) && HasBit(v->vehicle_flags, VF_AUTOMATE_TIMETABLE)) {
- + if (_settings_game.order.timetable_separation) v->ClearSeparation();
- + SetBit(v->vehicle_flags, VF_TIMETABLE_STARTED);
- + v->lateness_counter = 0;
- + if (_settings_game.order.timetable_separation) UpdateSeparationOrder(v);
- + for (v = v->FirstShared(); v != NULL; v = v->NextShared()) {
- + SetWindowDirty(WC_VEHICLE_TIMETABLE, v->index);
- + }
- + return;
- + }
- +
- /* This vehicle is arriving at the first destination in the timetable. */
- if (v->cur_real_order_index == first_manual_order && travelling) {
- /* If the start date hasn't been set, or it was set automatically when
- @@ -415,12 +589,60 @@
- if (just_started) return;
- + /* Update the timetable to gradually shift order times towards the actual travel times. */
- + if (timetabled != 0 && HasBit(v->vehicle_flags, VF_AUTOMATE_TIMETABLE)) {
- + int32 new_time;
- + if (travelling) {
- + new_time = time_taken;
- + } else {
- + new_time = time_loading;
- + }
- +
- + /* Check for too large a difference from expected time, and if so don't average. */
- + if (!(new_time > (int32)timetabled * 2 || new_time < (int32)timetabled / 2)) {
- + int arrival_error = timetabled - new_time;
- + /* Compute running average, with sign conversion to avoid negative overflow. */
- + new_time = ((int32)timetabled * 4 + new_time + 2) / 5;
- + /* Use arrival_error to finetune order ticks. */
- + if (arrival_error < 0) new_time++;
- + if (arrival_error > 0) new_time--;
- + } else if (new_time > (int32)timetabled * 10 && travelling) {
- + /* Possible jam, clear time and restart timetable for all vehicles.
- + * Otherwise we risk trains blocking 1-lane stations for long times. */
- + ChangeTimetable(v, v->cur_real_order_index, 0, travelling ? MTF_TRAVEL_TIME : MTF_WAIT_TIME);
- + for (Vehicle *v2 = v->FirstShared(); v2 != NULL; v2 = v2->NextShared()) {
- + if (_settings_game.order.timetable_separation) v2->ClearSeparation();
- + ClrBit(v2->vehicle_flags, VF_TIMETABLE_STARTED);
- + SetWindowDirty(WC_VEHICLE_TIMETABLE, v2->index);
- + }
- + return;
- + }
- +
- + if (new_time < 1) new_time = 1;
- + if (new_time != (int32)timetabled)
- + ChangeTimetable(v, v->cur_real_order_index, new_time, travelling ? MTF_TRAVEL_TIME : MTF_WAIT_TIME);
- + } else if (timetabled == 0 && HasBit(v->vehicle_flags, VF_AUTOMATE_TIMETABLE)) {
- + /* Add times for orders that are not yet timetabled, even while not autofilling */
- + if (travelling)
- + ChangeTimetable(v, v->cur_real_order_index, time_taken, travelling ? MTF_TRAVEL_TIME : MTF_WAIT_TIME);
- + else
- + ChangeTimetable(v, v->cur_real_order_index, time_loading, travelling ? MTF_TRAVEL_TIME : MTF_WAIT_TIME);
- + }
- +
- /* 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
- * when this happens. */
- if (timetabled == 0 && (travelling || v->lateness_counter >= 0)) return;
- - v->lateness_counter -= (timetabled - time_taken);
- + if (_settings_game.order.timetable_separation && HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED)) {
- + v->current_order_time = time_taken;
- + v->current_loading_time = time_loading;
- + UpdateSeparationOrder(v);
- + v->current_order_time = 0;
- + v->current_loading_time = 0;
- + } else {
- + v->lateness_counter -= (timetabled - time_taken);
- + }
- /* When we are more late than this timetabled bit takes we (somewhat expensively)
- * check how many ticks the (fully filled) timetable has. If a timetable cycle is
- Index: src/widgets/timetable_widget.h
- ===================================================================
- --- src/widgets/timetable_widget.h (revision 25615)
- +++ src/widgets/timetable_widget.h (working copy)
- @@ -25,9 +25,11 @@
- WID_VT_CLEAR_TIME, ///< Clear time button.
- WID_VT_RESET_LATENESS, ///< Reset lateness button.
- WID_VT_AUTOFILL, ///< Autofill button.
- + WID_VT_AUTOMATE, ///< Automate button.
- WID_VT_EXPECTED, ///< Toggle between expected and scheduled arrivals.
- WID_VT_SHARED_ORDER_LIST, ///< Show the shared order list.
- WID_VT_ARRIVAL_DEPARTURE_SELECTION, ///< Disable/hide the arrival departure panel.
- + WID_VT_AUTO_SELECTION, ///< Disable/hide the automate button.
- WID_VT_EXPECTED_SELECTION, ///< Disable/hide the expected selection button.
- WID_VT_CHANGE_SPEED, ///< Change speed limit button.
- WID_VT_CLEAR_SPEED, ///< Clear speed limit button.
- Index: src/command.cpp
- ===================================================================
- --- src/command.cpp (revision 25615)
- +++ src/command.cpp (working copy)
- @@ -188,6 +188,7 @@
- CommandProc CmdChangeTimetable;
- CommandProc CmdSetVehicleOnTime;
- CommandProc CmdAutofillTimetable;
- +CommandProc CmdAutomateTimetable;
- CommandProc CmdSetTimetableStart;
- CommandProc CmdOpenCloseAirport;
- @@ -341,6 +342,7 @@
- DEF_CMD(CmdChangeTimetable, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_CHANGE_TIMETABLE
- DEF_CMD(CmdSetVehicleOnTime, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SET_VEHICLE_ON_TIME
- DEF_CMD(CmdAutofillTimetable, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_AUTOFILL_TIMETABLE
- + DEF_CMD(CmdAutomateTimetable, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_AUTOMATE_TIMETABLE]
- DEF_CMD(CmdSetTimetableStart, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SET_TIMETABLE_START
- DEF_CMD(CmdOpenCloseAirport, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_OPEN_CLOSE_AIRPORT
- Index: src/settings_gui.cpp
- ===================================================================
- --- src/settings_gui.cpp (revision 25615)
- +++ src/settings_gui.cpp (working copy)
- @@ -1685,6 +1685,8 @@
- SettingEntry("vehicle.max_ships"),
- SettingEntry("vehicle.plane_speed"),
- SettingEntry("vehicle.plane_crashes"),
- + SettingEntry("order.timetable_automated"),
- + SettingEntry("order.timetable_separation"),
- SettingEntry("vehicle.dynamic_engines"),
- SettingEntry("vehicle.roadveh_acceleration_model"),
- SettingEntry("vehicle.roadveh_slope_steepness"),
- Index: src/command_type.h
- ===================================================================
- --- src/command_type.h (revision 25615)
- +++ src/command_type.h (working copy)
- @@ -309,6 +309,7 @@
- CMD_CHANGE_TIMETABLE, ///< change the timetable for a vehicle
- CMD_SET_VEHICLE_ON_TIME, ///< set the vehicle on time feature (timetable)
- CMD_AUTOFILL_TIMETABLE, ///< autofill the timetable
- + CMD_AUTOMATE_TIMETABLE, ///< automate the timetable
- CMD_SET_TIMETABLE_START, ///< set the date that a timetable should start
- CMD_OPEN_CLOSE_AIRPORT, ///< open/close an airport to incoming aircraft
- Index: src/timetable_gui.cpp
- ===================================================================
- --- src/timetable_gui.cpp (revision 25615)
- +++ src/timetable_gui.cpp (working copy)
- @@ -331,6 +331,7 @@
- this->EnableWidget(WID_VT_START_DATE);
- this->EnableWidget(WID_VT_RESET_LATENESS);
- this->EnableWidget(WID_VT_AUTOFILL);
- + this->EnableWidget(WID_VT_AUTOMATE);
- } else {
- this->DisableWidget(WID_VT_START_DATE);
- this->DisableWidget(WID_VT_CHANGE_TIME);
- @@ -339,10 +340,17 @@
- this->DisableWidget(WID_VT_CLEAR_SPEED);
- this->DisableWidget(WID_VT_RESET_LATENESS);
- this->DisableWidget(WID_VT_AUTOFILL);
- + this->DisableWidget(WID_VT_AUTOMATE);
- this->DisableWidget(WID_VT_SHARED_ORDER_LIST);
- }
- this->SetWidgetLoweredState(WID_VT_AUTOFILL, HasBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE));
- + this->SetWidgetLoweredState(WID_VT_AUTOMATE, HasBit(v->vehicle_flags, VF_AUTOMATE_TIMETABLE));
- + this->SetWidgetDisabledState(WID_VT_START_DATE, _settings_game.order.timetable_separation);
- + this->SetWidgetDisabledState(WID_VT_AUTOMATE, !_settings_game.order.timetable_automated);
- + this->SetWidgetDisabledState(WID_VT_CHANGE_TIME, HasBit(v->vehicle_flags, VF_AUTOMATE_TIMETABLE));
- + this->SetWidgetDisabledState(WID_VT_AUTOFILL, HasBit(v->vehicle_flags, VF_AUTOMATE_TIMETABLE));
- + this->SetWidgetDisabledState(WID_VT_CLEAR_TIME, HasBit(v->vehicle_flags, VF_AUTOMATE_TIMETABLE));
- this->DrawWidgets();
- }
- @@ -596,6 +604,14 @@
- break;
- }
- + case WID_VT_AUTOMATE: {
- + uint32 p2 = 0;
- + if (!HasBit(v->vehicle_flags, VF_AUTOMATE_TIMETABLE)) SetBit(p2, 0);
- + if (!_ctrl_pressed) SetBit(p2, 1);
- + DoCommandP(0, v->index, p2, CMD_AUTOMATE_TIMETABLE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE));
- + break;
- + }
- +
- case WID_VT_EXPECTED:
- this->show_expected = !this->show_expected;
- break;
- @@ -640,6 +656,7 @@
- void UpdateSelectionStates()
- {
- this->GetWidget<NWidgetStacked>(WID_VT_ARRIVAL_DEPARTURE_SELECTION)->SetDisplayedPlane(_settings_client.gui.timetable_arrival_departure ? 0 : SZSP_NONE);
- + // this->GetWidget<NWidgetStacked>(TTV_AUTO_SELECTION)->SetDisplayedPlane(!_settings_game.order.timetable_automated ? 0 : 1);
- this->GetWidget<NWidgetStacked>(WID_VT_EXPECTED_SELECTION)->SetDisplayedPlane(_settings_client.gui.timetable_arrival_departure ? 0 : 1);
- }
- };
- @@ -677,6 +694,7 @@
- EndContainer(),
- NWidget(NWID_VERTICAL, NC_EQUALSIZE),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_AUTOFILL), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_TIMETABLE_AUTOFILL, STR_TIMETABLE_AUTOFILL_TOOLTIP),
- + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_AUTOMATE), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_TIMETABLE_AUTOMATE, STR_TIMETABLE_AUTOMATE_TOOLTIP),
- NWidget(NWID_SELECTION, INVALID_COLOUR, WID_VT_EXPECTED_SELECTION),
- NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VT_EXPECTED), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_BLACK_STRING, STR_TIMETABLE_EXPECTED_TOOLTIP),
- NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), SetFill(1, 1), EndContainer(),
- @@ -685,6 +703,7 @@
- EndContainer(),
- NWidget(NWID_VERTICAL, NC_EQUALSIZE),
- NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VT_SHARED_ORDER_LIST), SetFill(0, 1), SetDataTip(SPR_SHARED_ORDERS_ICON, STR_ORDERS_VEH_WITH_SHARED_ORDERS_LIST_TOOLTIP),
- + NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), SetFill(1, 1), EndContainer(),
- NWidget(WWT_RESIZEBOX, COLOUR_GREY), SetFill(0, 1),
- EndContainer(),
- EndContainer(),
- Index: src/saveload/saveload.h
- ===================================================================
- --- src/saveload/saveload.h (revision 25615)
- +++ src/saveload/saveload.h (working copy)
- @@ -545,6 +545,9 @@
- bool SaveloadCrashWithMissingNewGRFs();
- +/* Hack to change savegame version in only one place. Rmv and correct if trunk. */
- +const int TIMESEP_SV = 164;
- +
- extern char _savegame_format[8];
- extern bool _do_autosave;
- Index: src/saveload/vehicle_sl.cpp
- ===================================================================
- --- src/saveload/vehicle_sl.cpp (revision 25615)
- +++ src/saveload/vehicle_sl.cpp (working copy)
- @@ -688,6 +688,9 @@
- SLE_CONDVAR(Vehicle, random_bits, SLE_UINT8, 2, SL_MAX_VERSION),
- SLE_CONDVAR(Vehicle, waiting_triggers, SLE_UINT8, 2, SL_MAX_VERSION),
- + SLE_CONDREF(Vehicle, ahead_separation, REF_VEHICLE, TIMESEP_SV, SL_MAX_VERSION),
- + SLE_CONDREF(Vehicle, behind_separation, REF_VEHICLE, TIMESEP_SV, SL_MAX_VERSION),
- +
- SLE_CONDREF(Vehicle, next_shared, REF_VEHICLE, 2, SL_MAX_VERSION),
- SLE_CONDNULL(2, 2, 68),
- SLE_CONDNULL(4, 69, 100),
- @@ -695,6 +698,7 @@
- SLE_CONDVAR(Vehicle, group_id, SLE_UINT16, 60, SL_MAX_VERSION),
- SLE_CONDVAR(Vehicle, current_order_time, SLE_UINT32, 67, SL_MAX_VERSION),
- + SLE_CONDVAR(Vehicle, current_loading_time, SLE_UINT32, TIMESEP_SV, SL_MAX_VERSION),
- SLE_CONDVAR(Vehicle, lateness_counter, SLE_INT32, 67, SL_MAX_VERSION),
- SLE_CONDNULL(10, 2, 143), // old reserved space
- Index: src/order_cmd.cpp
- ===================================================================
- --- src/order_cmd.cpp (revision 25615)
- +++ src/order_cmd.cpp (working copy)
- @@ -1176,6 +1176,9 @@
- v->UpdateRealOrderIndex();
- InvalidateVehicleOrder(v, VIWD_MODIFY_ORDERS);
- +
- + if (_settings_game.order.timetable_separation) v->ClearSeparation();
- + if (_settings_game.order.timetable_separation) ClrBit(v->vehicle_flags, VF_TIMETABLE_STARTED);
- }
- /* We have an aircraft/ship, they have a mini-schedule, so update them all */
- @@ -1624,6 +1627,13 @@
- /* Link this vehicle in the shared-list */
- dst->AddToShared(src);
- + /* Set automation bit if target has it. */
- + if (HasBit(src->vehicle_flags, VF_AUTOMATE_TIMETABLE))
- + SetBit(dst->vehicle_flags, VF_AUTOMATE_TIMETABLE);
- +
- + if (_settings_game.order.timetable_separation) dst->ClearSeparation();
- + if (_settings_game.order.timetable_separation) ClrBit(dst->vehicle_flags, VF_TIMETABLE_STARTED);
- +
- InvalidateVehicleOrder(dst, VIWD_REMOVE_ALL_ORDERS);
- InvalidateVehicleOrder(src, VIWD_MODIFY_ORDERS);
- Index: src/vehicle.cpp
- ===================================================================
- --- src/vehicle.cpp (revision 25615)
- +++ src/vehicle.cpp (working copy)
- @@ -205,6 +205,9 @@
- MarkSingleVehicleDirty(v);
- }
- + if (_settings_game.order.timetable_separation) this->ClearSeparation();
- + if (_settings_game.order.timetable_separation) ClrBit(this->vehicle_flags, VF_TIMETABLE_STARTED);
- +
- /* Dirty some windows */
- InvalidateWindowClassesData(GetWindowClassForVehicleType(this->type), 0);
- SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
- @@ -2268,6 +2271,10 @@
- case OT_LOADING: {
- uint wait_time = max(this->current_order.wait_time - this->lateness_counter, 0);
- + /* Save time just loading took since that is what goes into the timetable */
- + if (!HasBit(this->vehicle_flags, VF_LOADING_FINISHED))
- + this->current_loading_time = this->current_order_time;
- +
- /* 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;
- @@ -2344,6 +2351,8 @@
- if (flags & DC_EXEC) {
- this->current_order.SetDepotOrderType(ODTF_MANUAL);
- this->current_order.SetDepotActionType(halt_in_depot ? ODATF_SERVICE_ONLY : ODATFB_HALT);
- + if (_settings_game.order.timetable_separation) this->ClearSeparation();
- + if (_settings_game.order.timetable_separation) ClrBit(this->vehicle_flags, VF_TIMETABLE_STARTED);
- SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, WID_VV_START_STOP);
- }
- return CommandCost();
- @@ -2380,6 +2389,9 @@
- SetBit(gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS);
- }
- + if (_settings_game.order.timetable_separation) this->ClearSeparation();
- + if (_settings_game.order.timetable_separation) ClrBit(this->vehicle_flags, VF_TIMETABLE_STARTED);
- +
- this->dest_tile = location;
- this->current_order.MakeGoToDepot(destination, ODTF_MANUAL);
- if (!(command & DEPOT_SERVICE)) this->current_order.SetDepotActionType(ODATFB_HALT);
- @@ -2632,6 +2644,55 @@
- }
- }
- +void Vehicle::ClearSeparation()
- +{
- + if (this->ahead_separation == NULL && this->behind_separation == NULL) return;
- +
- + assert(this->ahead_separation != NULL);
- + assert(this->behind_separation != NULL);
- +
- + this->ahead_separation->behind_separation = this->behind_separation;
- + this->behind_separation->ahead_separation = this->ahead_separation;
- +
- + this->ahead_separation = NULL;
- + this->behind_separation = NULL;
- +
- + SetWindowDirty(WC_VEHICLE_TIMETABLE, this->index);
- +}
- +
- +void Vehicle::InitSeparation()
- +{
- + assert(this->ahead_separation == NULL && this->behind_separation == NULL);
- + Vehicle *best_match = this;
- + int lowest_separation;
- + for (Vehicle *v_other = this->FirstShared(); v_other != NULL; v_other = v_other->NextShared()) {
- + if ((HasBit(v_other->vehicle_flags, VF_TIMETABLE_STARTED)) && v_other != this) {
- + if (best_match == this) {
- + best_match = v_other;
- + lowest_separation = 0; // TODO call SeparationBetween() here
- + } else {
- + int temp_sep = 0; // TODO call SeparationBetween() here
- + if (temp_sep < lowest_separation && temp_sep != -1) {
- + best_match = v_other;
- + lowest_separation = temp_sep;
- + }
- + }
- + }
- + }
- + this->AddToSeparationBehind(best_match);
- +}
- +
- +void Vehicle::AddToSeparationBehind(Vehicle *v_other)
- +{
- + if (v_other->ahead_separation == NULL) v_other->ahead_separation = v_other;
- + if (v_other->behind_separation == NULL) v_other->behind_separation = v_other;
- +
- + this->ahead_separation = v_other;
- + v_other->behind_separation->ahead_separation = this;
- + this->behind_separation = v_other->behind_separation;
- + v_other->behind_separation = this;
- +}
- +
- /**
- * Adds this vehicle to a shared vehicle chain.
- * @param shared_chain a vehicle of the chain with shared vehicles.
- @@ -2689,6 +2750,9 @@
- this->next_shared = NULL;
- this->previous_shared = NULL;
- +
- + if (_settings_game.order.timetable_separation) this->ClearSeparation();
- + if (_settings_game.order.timetable_separation) ClrBit(this->vehicle_flags, VF_TIMETABLE_STARTED);
- }
- void VehiclesYearlyLoop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement