timetable_cmd.cpp

Go to the documentation of this file.
00001 /* $Id: timetable_cmd.cpp 14268 2008-09-07 22:04:39Z rubidium $ */
00002 
00005 #include "stdafx.h"
00006 #include "openttd.h"
00007 #include "variables.h"
00008 #include "command_func.h"
00009 #include "functions.h"
00010 #include "window_func.h"
00011 #include "vehicle_func.h"
00012 #include "vehicle_base.h"
00013 #include "settings_type.h"
00014 
00015 #include "table/strings.h"
00016 
00017 static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint16 time, bool is_journey)
00018 {
00019   Order *order = GetVehicleOrder(v, order_number);
00020 
00021   if (is_journey) {
00022     order->travel_time = time;
00023   } else {
00024     order->wait_time = time;
00025   }
00026 
00027   for (v = GetFirstVehicleFromSharedList(v); v != NULL; v = v->next_shared) {
00028     if (v->cur_order_index == order_number && HasBit(v->current_order.flags, OF_PART_OF_ORDERS)) {
00029       if (is_journey) {
00030         v->current_order.travel_time = time;
00031       } else {
00032         v->current_order.wait_time = time;
00033       }
00034     }
00035     InvalidateWindow(WC_VEHICLE_TIMETABLE, v->index);
00036   }
00037 }
00038 
00054 CommandCost CmdChangeTimetable(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
00055 {
00056   if (!_patches.timetabling) return CMD_ERROR;
00057 
00058   VehicleID veh = GB(p1, 0, 16);
00059   if (!IsValidVehicleID(veh)) return CMD_ERROR;
00060 
00061   Vehicle *v = GetVehicle(veh);
00062   if (!CheckOwnership(v->owner)) return CMD_ERROR;
00063 
00064   VehicleOrderID order_number = GB(p1, 16, 8);
00065   Order *order = GetVehicleOrder(v, order_number);
00066   if (order == NULL) return CMD_ERROR;
00067 
00068   bool packed_time = HasBit(p1, 25);
00069   bool is_journey = HasBit(p1, 24) || packed_time;
00070   if (!is_journey) {
00071     if (order->type != OT_GOTO_STATION) return_cmd_error(STR_TIMETABLE_ONLY_WAIT_AT_STATIONS);
00072     if (_patches.new_nonstop && (order->flags & OFB_NON_STOP)) return_cmd_error(STR_TIMETABLE_NOT_STOPPING_HERE);
00073   }
00074 
00075   if (flags & DC_EXEC) {
00076     ChangeTimetable(v, order_number, GB(p2, 0, 16), is_journey);
00077     if (packed_time) ChangeTimetable(v, order_number, GB(p2, 16, 16), false);
00078   }
00079 
00080   return CommandCost();
00081 }
00082 
00090 CommandCost CmdSetVehicleOnTime(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
00091 {
00092   if (!_patches.timetabling) return CMD_ERROR;
00093 
00094   VehicleID veh = GB(p1, 0, 16);
00095   if (!IsValidVehicleID(veh)) return CMD_ERROR;
00096 
00097   Vehicle *v = GetVehicle(veh);
00098   if (!CheckOwnership(v->owner)) return CMD_ERROR;
00099 
00100   if (flags & DC_EXEC) {
00101     v->lateness_counter = 0;
00102   }
00103 
00104   return CommandCost();
00105 }
00106 
00116 CommandCost CmdAutofillTimetable(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
00117 {
00118   if (!_patches.timetabling) return CMD_ERROR;
00119 
00120   VehicleID veh = GB(p1, 0, 16);
00121   if (!IsValidVehicleID(veh)) return CMD_ERROR;
00122 
00123   Vehicle *v = GetVehicle(veh);
00124   if (!CheckOwnership(v->owner)) return CMD_ERROR;
00125 
00126   if (flags & DC_EXEC) {
00127     if (p2 == 1) {
00128       /* Start autofilling the timetable, which clears all the current
00129        * timings and clears the "timetable has started" bit. */
00130       SetBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE);
00131       ClrBit(v->vehicle_flags, VF_TIMETABLE_STARTED);
00132 
00133       for (Order *order = GetVehicleOrder(v, 0); order != NULL; order = order->next) {
00134         order->wait_time = 0;
00135         order->travel_time = 0;
00136       }
00137 
00138       v->current_order.wait_time = 0;
00139       v->current_order.travel_time = 0;
00140     } else {
00141       ClrBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE);
00142     }
00143   }
00144 
00145   for (v = GetFirstVehicleFromSharedList(v); v != NULL; v = v->next_shared) {
00146     InvalidateWindow(WC_VEHICLE_TIMETABLE, v->index);
00147   }
00148 
00149   return CommandCost();
00150 }
00151 
00152 void UpdateVehicleTimetable(Vehicle *v, bool travelling)
00153 {
00154   uint timetabled = travelling ? v->current_order.travel_time : v->current_order.wait_time;
00155   uint time_taken = v->current_order_time;
00156 
00157   v->current_order_time = 0;
00158 
00159   if (!_patches.timetabling) return;
00160 
00161   /* Make sure the timetable only starts when the vehicle reaches the first
00162    * order, not when travelling from the depot to the first station. */
00163   if (v->cur_order_index == 0 && !HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED)) {
00164     SetBit(v->vehicle_flags, VF_TIMETABLE_STARTED);
00165     return;
00166   }
00167 
00168   if (!HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED)) return;
00169 
00170   if (HasBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE)) {
00171     if (timetabled == 0) {
00172       /* Round the time taken up to the nearest day, as this will avoid
00173        * confusion for people who are timetabling in days, and can be
00174        * adjusted later by people who aren't. */
00175       time_taken = (((time_taken - 1) / DAY_TICKS) + 1) * DAY_TICKS;
00176 
00177       ChangeTimetable(v, v->cur_order_index, time_taken, travelling);
00178       return;
00179     } else if (v->cur_order_index == 0) {
00180       /* Otherwise if we're at the beginning and it already has a value,
00181        * assume that autofill is finished and turn it off again. */
00182       ClrBit(v->vehicle_flags, VF_AUTOFILL_TIMETABLE);
00183     }
00184   }
00185 
00186   /* Vehicles will wait at stations if they arrive early even if they are not
00187    * timetabled to wait there, so make sure the lateness counter is updated
00188    * when this happens. */
00189   if (timetabled == 0 && (travelling || v->lateness_counter >= 0)) return;
00190 
00191   v->lateness_counter -= (timetabled - time_taken);
00192 
00193   for (v = GetFirstVehicleFromSharedList(v); v != NULL; v = v->next_shared) {
00194     InvalidateWindow(WC_VEHICLE_TIMETABLE, v->index);
00195   }
00196 }

Generated on Wed Oct 1 17:03:24 2008 for openttd by  doxygen 1.5.6