00001
00002
00005 #include "stdafx.h"
00006 #include "command_func.h"
00007 #include "functions.h"
00008 #include "window_func.h"
00009 #include "vehicle_base.h"
00010 #include "settings_type.h"
00011
00012 #include "table/strings.h"
00013
00014 static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint16 time, bool is_journey)
00015 {
00016 Order *order = GetVehicleOrder(v, order_number);
00017 int delta;
00018
00019 if (is_journey) {
00020 delta = time - order->travel_time;
00021 order->travel_time = time;
00022 } else {
00023 delta = time - order->wait_time;
00024 order->wait_time = time;
00025 }
00026 v->orders.list->UpdateOrderTimetable(delta);
00027
00028 for (v = v->FirstShared(); v != NULL; v = v->NextShared()) {
00029 if (v->cur_order_index == order_number && v->current_order.Equals(*order)) {
00030 if (is_journey) {
00031 v->current_order.travel_time = time;
00032 } else {
00033 v->current_order.wait_time = time;
00034 }
00035 }
00036 InvalidateWindow(WC_VEHICLE_TIMETABLE, v->index);
00037 }
00038 }
00039
00055 CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
00056 {
00057 if (!_settings_game.order.timetabling) return CMD_ERROR;
00058
00059 VehicleID veh = GB(p1, 0, 16);
00060 if (!IsValidVehicleID(veh)) return CMD_ERROR;
00061
00062 Vehicle *v = GetVehicle(veh);
00063 if (!CheckOwnership(v->owner)) return CMD_ERROR;
00064
00065 VehicleOrderID order_number = GB(p1, 16, 8);
00066 Order *order = GetVehicleOrder(v, order_number);
00067 if (order == NULL) return CMD_ERROR;
00068
00069 bool packed_time = HasBit(p1, 25);
00070 bool is_journey = HasBit(p1, 24) || packed_time;
00071
00072 int wait_time = order->wait_time;
00073 int travel_time = order->travel_time;
00074 if (packed_time) {
00075 travel_time = GB(p2, 0, 16);
00076 wait_time = GB(p2, 16, 16);;
00077 } else if (is_journey) {
00078 travel_time = GB(p2, 0, 16);
00079 } else {
00080 wait_time = GB(p2, 0, 16);
00081 }
00082
00083 if (wait_time != order->wait_time) {
00084 switch (order->GetType()) {
00085 case OT_GOTO_STATION:
00086 if (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION) return_cmd_error(STR_TIMETABLE_NOT_STOPPING_HERE);
00087 break;
00088
00089 case OT_CONDITIONAL:
00090 break;
00091
00092 default: return_cmd_error(STR_TIMETABLE_ONLY_WAIT_AT_STATIONS);
00093 }
00094 }
00095
00096 if (travel_time != order->travel_time && order->IsType(OT_CONDITIONAL)) return CMD_ERROR;
00097
00098 if (flags & DC_EXEC) {
00099 if (wait_time != order->wait_time) ChangeTimetable(v, order_number, wait_time, false);
00100 if (travel_time != order->travel_time) ChangeTimetable(v, order_number, travel_time, true);
00101 }
00102
00103 return CommandCost();
00104 }
00105
00113 CommandCost CmdSetVehicleOnTime(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
00114 {
00115 if (!_settings_game.order.timetabling) return CMD_ERROR;
00116
00117 VehicleID veh = GB(p1, 0, 16);
00118 if (!IsValidVehicleID(veh)) return CMD_ERROR;
00119
00120 Vehicle *v = GetVehicle(veh);
00121 if (!CheckOwnership(v->owner)) return CMD_ERROR;
00122
00123 if (flags & DC_EXEC) {
00124 v->lateness_counter = 0;
00125 }
00126
00127 return CommandCost();
00128 }
00129
00141 CommandCost CmdAutofillTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
00142 {
00143 if (!_settings_game.order.timetabling) return CMD_ERROR;
00144
00145 VehicleID veh = GB(p1, 0, 16);
00146 if (!IsValidVehicleID(veh)) return CMD_ERROR;
00147
00148 Vehicle *v = GetVehicle(veh);
00149 if (!CheckOwnership(v->owner)) return CMD_ERROR;
00150
00151 if (flags & DC_EXEC) {
00152 if (HasBit(p2, 0)) {
00153
00154
00155
00156 SetBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE);
00157 ClrBit(v->vehicle_flags, VF_TIMETABLE_STARTED);
00158
00159
00160 if (HasBit(p2, 1)) SetBit(v->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME);
00161
00162 v->lateness_counter = 0;
00163 } else {
00164 ClrBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE);
00165 ClrBit(v->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME);
00166 }
00167 }
00168
00169 for (Vehicle *v2 = v->FirstShared(); v2 != NULL; v2 = v2->NextShared()) {
00170 if (v2 != v) {
00171
00172 ClrBit(v2->vehicle_flags, VF_AUTOFILL_TIMETABLE);
00173 ClrBit(v2->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME);
00174 }
00175 InvalidateWindow(WC_VEHICLE_TIMETABLE, v2->index);
00176 }
00177
00178 return CommandCost();
00179 }
00180
00181 void UpdateVehicleTimetable(Vehicle *v, bool travelling)
00182 {
00183 uint timetabled = travelling ? v->current_order.travel_time : v->current_order.wait_time;
00184 uint time_taken = v->current_order_time;
00185
00186 v->current_order_time = 0;
00187
00188 if (!_settings_game.order.timetabling) return;
00189
00190 bool just_started = false;
00191
00192
00193
00194 if (v->cur_order_index == 0 && !HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED)) {
00195 SetBit(v->vehicle_flags, VF_TIMETABLE_STARTED);
00196 just_started = true;
00197 }
00198
00199 if (!HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED)) return;
00200
00201 if (HasBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE)) {
00202 if (travelling && !HasBit(v->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME)) {
00203
00204 v->current_order.wait_time = 0;
00205 }
00206
00207 if (just_started) return;
00208
00209
00210
00211 if (!v->current_order.IsType(OT_CONDITIONAL) && (travelling || time_taken > v->current_order.wait_time)) {
00212
00213
00214
00215 time_taken = (((time_taken - 1) / DAY_TICKS) + 1) * DAY_TICKS;
00216
00217 ChangeTimetable(v, v->cur_order_index, time_taken, travelling);
00218 }
00219
00220 if (v->cur_order_index == 0 && travelling) {
00221
00222
00223
00224 ClrBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE);
00225 ClrBit(v->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME);
00226 }
00227 return;
00228 }
00229
00230 if (just_started) return;
00231
00232
00233
00234
00235 if (timetabled == 0 && (travelling || v->lateness_counter >= 0)) return;
00236
00237 v->lateness_counter -= (timetabled - time_taken);
00238
00239 for (v = v->FirstShared(); v != NULL; v = v->NextShared()) {
00240 InvalidateWindow(WC_VEHICLE_TIMETABLE, v->index);
00241 }
00242 }