OpenTTD Source: src/timetable_cmd.cpp Source File

OpenTTD Source 15.3

timetable_cmd.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
10#include "stdafx.h"
11#include "command_func.h"
12#include "company_func.h"
13#include "timer/timer_game_tick.h"
14#include "timer/timer_game_economy.h"
15#include "window_func.h"
16#include "vehicle_base.h"
17#include "timetable_cmd.h"
18#include "timetable.h"
19
20#include "table/strings.h"
21
22#include "safeguards.h"
23
29 TimerGameTick::TickCounter GetStartTickFromDate(TimerGameEconomy::Date start_date)
30{
31 /* Calculate the offset in ticks from the current date. */
32 TimerGameTick::Ticks tick_offset = (start_date - TimerGameEconomy::date).base() * Ticks::DAY_TICKS;
33
34 /* Compensate for the current date_fract. */
35 tick_offset -= TimerGameEconomy::date_fract;
36
37 /* Return the current tick plus the offset. */
38 return TimerGameTick::counter + tick_offset;
39}
40
46 TimerGameEconomy::Date GetDateFromStartTick(TimerGameTick::TickCounter start_tick)
47{
48 /* Calculate the offset in ticks from the current counter tick. */
49 TimerGameTick::Ticks tick_offset = start_tick - TimerGameTick::counter;
50
51 /* Compensate for the current date_fract. */
52 tick_offset += TimerGameEconomy::date_fract;
53
54 /* Return the current date plus the offset in days. */
55 return TimerGameEconomy::date + (tick_offset / Ticks::DAY_TICKS);
56}
57
66 static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint16_t val, ModifyTimetableFlags mtf, bool timetabled)
67{
68 Order *order = v->GetOrder(order_number);
69 assert(order != nullptr);
70 int total_delta = 0;
71 int timetable_delta = 0;
72
73 switch (mtf) {
74 case MTF_WAIT_TIME:
75 total_delta = val - order->GetWaitTime();
76 timetable_delta = (timetabled ? val : 0) - order->GetTimetabledWait();
77 order->SetWaitTime(val);
78 order->SetWaitTimetabled(timetabled);
79 break;
80
81 case MTF_TRAVEL_TIME:
82 total_delta = val - order->GetTravelTime();
83 timetable_delta = (timetabled ? val : 0) - order->GetTimetabledTravel();
84 order->SetTravelTime(val);
85 order->SetTravelTimetabled(timetabled);
86 break;
87
88 case MTF_TRAVEL_SPEED:
89 order->SetMaxSpeed(val);
90 break;
91
92 default:
93 NOT_REACHED();
94 }
95 v->orders->UpdateTotalDuration(total_delta);
96 v->orders->UpdateTimetableDuration(timetable_delta);
97
98 for (v = v->FirstShared(); v != nullptr; v = v->NextShared()) {
99 if (v->cur_real_order_index == order_number && v->current_order.Equals(*order)) {
100 switch (mtf) {
101 case MTF_WAIT_TIME:
102 v->current_order.SetWaitTime(val);
103 v->current_order.SetWaitTimetabled(timetabled);
104 break;
105
106 case MTF_TRAVEL_TIME:
107 v->current_order.SetTravelTime(val);
108 v->current_order.SetTravelTimetabled(timetabled);
109 break;
110
111 case MTF_TRAVEL_SPEED:
112 v->current_order.SetMaxSpeed(val);
113 break;
114
115 default:
116 NOT_REACHED();
117 }
118 }
119 SetWindowDirty(WC_VEHICLE_TIMETABLE, v->index);
120 }
121}
122
133 CommandCost CmdChangeTimetable(DoCommandFlags flags, VehicleID veh, VehicleOrderID order_number, ModifyTimetableFlags mtf, uint16_t data)
134{
135 Vehicle *v = Vehicle::GetIfValid(veh);
136 if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR;
137
138 CommandCost ret = CheckOwnership(v->owner);
139 if (ret.Failed()) return ret;
140
141 Order *order = v->GetOrder(order_number);
142 if (order == nullptr || order->IsType(OT_IMPLICIT)) return CMD_ERROR;
143
144 if (mtf >= MTF_END) return CMD_ERROR;
145
146 int wait_time = order->GetWaitTime();
147 int travel_time = order->GetTravelTime();
148 int max_speed = order->GetMaxSpeed();
149 switch (mtf) {
150 case MTF_WAIT_TIME:
151 wait_time = data;
152 break;
153
154 case MTF_TRAVEL_TIME:
155 travel_time = data;
156 break;
157
158 case MTF_TRAVEL_SPEED:
159 max_speed = data;
160 if (max_speed == 0) max_speed = UINT16_MAX; // Disable speed limit.
161 break;
162
163 default:
164 NOT_REACHED();
165 }
166
167 if (wait_time != order->GetWaitTime()) {
168 switch (order->GetType()) {
169 case OT_GOTO_STATION:
170 if (order->GetNonStopType().Test(OrderNonStopFlag::NoDestination)) return CommandCost(STR_ERROR_TIMETABLE_NOT_STOPPING_HERE);
171 break;
172
173 case OT_CONDITIONAL:
174 break;
175
176 default: return CommandCost(STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS);
177 }
178 }
179
180 if (travel_time != order->GetTravelTime() && order->IsType(OT_CONDITIONAL)) return CMD_ERROR;
181 if (max_speed != order->GetMaxSpeed() && (order->IsType(OT_CONDITIONAL) || v->type == VEH_AIRCRAFT)) return CMD_ERROR;
182
183 if (flags.Test(DoCommandFlag::Execute)) {
184 switch (mtf) {
185 case MTF_WAIT_TIME:
186 /* Set time if changing the value or confirming an estimated time as timetabled. */
187 if (wait_time != order->GetWaitTime() || (wait_time > 0 && !order->IsWaitTimetabled())) {
188 ChangeTimetable(v, order_number, wait_time, MTF_WAIT_TIME, wait_time > 0);
189 }
190 break;
191
192 case MTF_TRAVEL_TIME:
193 /* Set time if changing the value or confirming an estimated time as timetabled. */
194 if (travel_time != order->GetTravelTime() || (travel_time > 0 && !order->IsTravelTimetabled())) {
195 ChangeTimetable(v, order_number, travel_time, MTF_TRAVEL_TIME, travel_time > 0);
196 }
197 break;
198
199 case MTF_TRAVEL_SPEED:
200 if (max_speed != order->GetMaxSpeed()) {
201 ChangeTimetable(v, order_number, max_speed, MTF_TRAVEL_SPEED, max_speed != UINT16_MAX);
202 }
203 break;
204
205 default:
206 break;
207 }
208
209 /* Unbunching data is no longer valid for any vehicle in this shared order group. */
210 Vehicle *u = v->FirstShared();
211 for (; u != nullptr; u = u->NextShared()) {
212 u->ResetDepotUnbunching();
213 }
214 }
215
216 return CommandCost();
217}
218
228 CommandCost CmdBulkChangeTimetable(DoCommandFlags flags, VehicleID veh, ModifyTimetableFlags mtf, uint16_t data)
229{
230 Vehicle *v = Vehicle::GetIfValid(veh);
231 if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR;
232
233 CommandCost ret = CheckOwnership(v->owner);
234 if (ret.Failed()) return ret;
235
236 if (mtf >= MTF_END) return CMD_ERROR;
237
238 if (v->GetNumOrders() == 0) return CMD_ERROR;
239
240 if (flags.Test(DoCommandFlag::Execute)) {
241 for (VehicleOrderID order_number = 0; order_number < v->GetNumOrders(); order_number++) {
242 Order *order = v->GetOrder(order_number);
243 if (order == nullptr || order->IsType(OT_IMPLICIT)) continue;
244
245 Command<CMD_CHANGE_TIMETABLE>::Do(DoCommandFlag::Execute, v->index, order_number, mtf, data);
246 }
247 }
248
249 return CommandCost();
250}
251
259 CommandCost CmdSetVehicleOnTime(DoCommandFlags flags, VehicleID veh, bool apply_to_group)
260{
261 Vehicle *v = Vehicle::GetIfValid(veh);
262 if (v == nullptr || !v->IsPrimaryVehicle() || v->orders == nullptr) return CMD_ERROR;
263
264 /* A vehicle can't be late if its timetable hasn't started.
265 * If we're setting all vehicles in the group, we handle that below. */
266 if (!apply_to_group && !v->vehicle_flags.Test(VehicleFlag::TimetableStarted)) return CommandCost(STR_ERROR_TIMETABLE_NOT_STARTED);
267
268 CommandCost ret = CheckOwnership(v->owner);
269 if (ret.Failed()) return ret;
270
271 if (flags.Test(DoCommandFlag::Execute)) {
272 if (apply_to_group) {
273 TimerGameTick::Ticks most_late = 0;
274 for (Vehicle *u = v->FirstShared(); u != nullptr; u = u->NextShared()) {
275 /* A vehicle can't be late if its timetable hasn't started. */
276 if (!v->vehicle_flags.Test(VehicleFlag::TimetableStarted)) continue;
277
278 if (u->lateness_counter > most_late) {
279 most_late = u->lateness_counter;
280 }
281
282 /* Unbunching data is no longer valid. */
283 u->ResetDepotUnbunching();
284 }
285 if (most_late > 0) {
286 for (Vehicle *u = v->FirstShared(); u != nullptr; u = u->NextShared()) {
287 /* A vehicle can't be late if its timetable hasn't started. */
288 if (!v->vehicle_flags.Test(VehicleFlag::TimetableStarted)) continue;
289
290 u->lateness_counter -= most_late;
291 SetWindowDirty(WC_VEHICLE_TIMETABLE, u->index);
292 }
293 }
294 } else {
295 v->lateness_counter = 0;
296 /* Unbunching data is no longer valid. */
297 v->ResetDepotUnbunching();
298 SetWindowDirty(WC_VEHICLE_TIMETABLE, v->index);
299 }
300 }
301
302 return CommandCost();
303}
304
313 static bool VehicleTimetableSorter(Vehicle * const &a, Vehicle * const &b)
314{
315 VehicleOrderID a_order = a->cur_real_order_index;
316 VehicleOrderID b_order = b->cur_real_order_index;
317 int j = (int)b_order - (int)a_order;
318
319 /* Are we currently at an ordered station (un)loading? */
320 bool a_load = a->current_order.IsType(OT_LOADING) && a->current_order.GetNonStopType().Any();
321 bool b_load = b->current_order.IsType(OT_LOADING) && b->current_order.GetNonStopType().Any();
322
323 /* If the current order is not loading at the ordered station, decrease the order index by one since we have
324 * not yet arrived at the station (and thus the timetable entry; still in the travelling of the previous one).
325 * Since the ?_order variables are unsigned the -1 will flow under and place the vehicles going to order #0 at
326 * the begin of the list with vehicles arriving at #0. */
327 if (!a_load) a_order--;
328 if (!b_load) b_order--;
329
330 /* First check the order index that accounted for loading, then just the raw one. */
331 int i = (int)b_order - (int)a_order;
332 if (i != 0) return i < 0;
333 if (j != 0) return j < 0;
334
335 /* Look at the time we spent in this order; the higher, the closer to its destination. */
336 i = b->current_order_time - a->current_order_time;
337 if (i != 0) return i < 0;
338
339 /* If all else is equal, use some unique index to sort it the same way. */
340 return b->unitnumber < a->unitnumber;
341}
342
351 CommandCost CmdSetTimetableStart(DoCommandFlags flags, VehicleID veh_id, bool timetable_all, TimerGameTick::TickCounter start_tick)
352{
353 Vehicle *v = Vehicle::GetIfValid(veh_id);
354 if (v == nullptr || !v->IsPrimaryVehicle() || v->orders == nullptr) return CMD_ERROR;
355
356 CommandCost ret = CheckOwnership(v->owner);
357 if (ret.Failed()) return ret;
358
359 TimerGameTick::Ticks total_duration = v->orders->GetTimetableTotalDuration();
360
361 TimerGameEconomy::Date start_date = GetDateFromStartTick(start_tick);
362
363 /* Don't let a timetable start at an invalid date. */
364 if (start_date < 0 || start_date > EconomyTime::MAX_DATE) return CMD_ERROR;
365
366 /* Don't let a timetable start more than 15 years into the future... */
367 if (start_date - TimerGameEconomy::date > TimerGameEconomy::DateAtStartOfYear(MAX_TIMETABLE_START_YEARS)) return CMD_ERROR;
368 /* ...or 1 year in the past. */
369 if (TimerGameEconomy::date - start_date > EconomyTime::DAYS_IN_LEAP_YEAR) return CMD_ERROR;
370
371 /* If trying to distribute start dates over a shared order group, we need to know the total duration. */
372 if (timetable_all && !v->orders->IsCompleteTimetable()) return CommandCost(STR_ERROR_TIMETABLE_INCOMPLETE);
373
374 /* Don't allow invalid start dates for other vehicles in the shared order group. */
375 if (timetable_all && start_date + (total_duration / Ticks::DAY_TICKS) > EconomyTime::MAX_DATE) return CMD_ERROR;
376
377 if (flags.Test(DoCommandFlag::Execute)) {
378 std::vector<Vehicle *> vehs;
379
380 if (timetable_all) {
381 for (Vehicle *w = v->orders->GetFirstSharedVehicle(); w != nullptr; w = w->NextShared()) {
382 vehs.push_back(w);
383 }
384 } else {
385 vehs.push_back(v);
386 }
387
388 int num_vehs = (uint)vehs.size();
389
390 if (num_vehs >= 2) {
391 std::sort(vehs.begin(), vehs.end(), &VehicleTimetableSorter);
392 }
393
394 int idx = 0;
395
396 for (Vehicle *w : vehs) {
397 w->lateness_counter = 0;
398 w->vehicle_flags.Reset(VehicleFlag::TimetableStarted);
399 /* Do multiplication, then division to reduce rounding errors. */
400 w->timetable_start = start_tick + (idx * total_duration / num_vehs);
401
402 /* Unbunching data is no longer valid. */
403 v->ResetDepotUnbunching();
404
405 SetWindowDirty(WC_VEHICLE_TIMETABLE, w->index);
406 ++idx;
407 }
408
409 }
410
411 return CommandCost();
412}
413
414
425 CommandCost CmdAutofillTimetable(DoCommandFlags flags, VehicleID veh, bool autofill, bool preserve_wait_time)
426{
427 Vehicle *v = Vehicle::GetIfValid(veh);
428 if (v == nullptr || !v->IsPrimaryVehicle() || v->orders == nullptr) return CMD_ERROR;
429
430 CommandCost ret = CheckOwnership(v->owner);
431 if (ret.Failed()) return ret;
432
433 if (flags.Test(DoCommandFlag::Execute)) {
434 if (autofill) {
435 /* Start autofilling the timetable, which clears the
436 * "timetable has started" bit. Times are not cleared anymore, but are
437 * overwritten when the order is reached now. */
438 v->vehicle_flags.Set(VehicleFlag::AutofillTimetable);
439 v->vehicle_flags.Reset(VehicleFlag::TimetableStarted);
440
441 /* Overwrite waiting times only if they got longer */
442 if (preserve_wait_time) v->vehicle_flags.Set(VehicleFlag::AutofillPreserveWaitTime);
443
444 v->timetable_start = 0;
445 v->lateness_counter = 0;
446 } else {
447 v->vehicle_flags.Reset(VehicleFlag::AutofillTimetable);
448 v->vehicle_flags.Reset(VehicleFlag::AutofillPreserveWaitTime);
449 }
450
451 for (Vehicle *v2 = v->FirstShared(); v2 != nullptr; v2 = v2->NextShared()) {
452 if (v2 != v) {
453 /* Stop autofilling; only one vehicle at a time can perform autofill */
454 v2->vehicle_flags.Reset(VehicleFlag::AutofillTimetable);
455 v2->vehicle_flags.Reset(VehicleFlag::AutofillPreserveWaitTime);
456 }
457 SetWindowDirty(WC_VEHICLE_TIMETABLE, v2->index);
458 }
459 }
460
461 return CommandCost();
462}
463
469 void UpdateVehicleTimetable(Vehicle *v, bool travelling)
470{
471 TimerGameTick::Ticks time_taken = v->current_order_time;
472
473 v->current_order_time = 0;
474
475 if (v->current_order.IsType(OT_IMPLICIT)) return; // no timetabling of auto orders
476
477 if (v->cur_real_order_index >= v->GetNumOrders()) return;
478 Order *real_current_order = v->GetOrder(v->cur_real_order_index);
479 assert(real_current_order != nullptr);
480
481 VehicleOrderID first_manual_order = 0;
482 for (const Order &o : v->Orders()) {
483 if (!o.IsType(OT_IMPLICIT)) break;
484 ++first_manual_order;
485 }
486
487 bool just_started = false;
488
489 /* This vehicle is arriving at the first destination in the timetable. */
490 if (v->cur_real_order_index == first_manual_order && travelling) {
491 /* If the start date hasn't been set, or it was set automatically when
492 * the vehicle last arrived at the first destination, update it to the
493 * current time. Otherwise set the late counter appropriately to when
494 * the vehicle should have arrived. */
495 just_started = !v->vehicle_flags.Test(VehicleFlag::TimetableStarted);
496
497 if (v->timetable_start != 0) {
498 v->lateness_counter = TimerGameTick::counter - v->timetable_start;
499 v->timetable_start = 0;
500 }
501
502 v->vehicle_flags.Set(VehicleFlag::TimetableStarted);
503 SetWindowDirty(WC_VEHICLE_TIMETABLE, v->index);
504 }
505
506 if (!v->vehicle_flags.Test(VehicleFlag::TimetableStarted)) return;
507
508 bool autofilling = v->vehicle_flags.Test(VehicleFlag::AutofillTimetable);
509 bool remeasure_wait_time = !real_current_order->IsWaitTimetabled() ||
510 (autofilling && !v->vehicle_flags.Test(VehicleFlag::AutofillPreserveWaitTime));
511
512 if (travelling && remeasure_wait_time) {
513 /* We just finished travelling and want to remeasure the loading time,
514 * so do not apply any restrictions for the loading to finish. */
515 v->current_order.SetWaitTime(0);
516 }
517
518 if (just_started) return;
519
520 /* Before modifying waiting times, check whether we want to preserve bigger ones. */
521 if (!real_current_order->IsType(OT_CONDITIONAL) &&
522 (travelling || time_taken > real_current_order->GetWaitTime() || remeasure_wait_time)) {
523 /* Round up to the smallest unit of time commonly shown in the GUI (seconds) to avoid confusion.
524 * Players timetabling in Ticks can adjust later.
525 * For trains/aircraft multiple movement cycles are done in one
526 * tick. This makes it possible to leave the station and process
527 * e.g. a depot order in the same tick, causing it to not fill
528 * the timetable entry like is done for road vehicles/ships.
529 * Thus always make sure at least one tick is used between the
530 * processing of different orders when filling the timetable. */
531 uint time_to_set = CeilDiv(std::max(time_taken, 1), Ticks::TICKS_PER_SECOND) * Ticks::TICKS_PER_SECOND;
532
533 if (travelling && (autofilling || !real_current_order->IsTravelTimetabled())) {
534 ChangeTimetable(v, v->cur_real_order_index, time_to_set, MTF_TRAVEL_TIME, autofilling);
535 } else if (!travelling && (autofilling || !real_current_order->IsWaitTimetabled())) {
536 ChangeTimetable(v, v->cur_real_order_index, time_to_set, MTF_WAIT_TIME, autofilling);
537 }
538 }
539
540 if (v->cur_real_order_index == first_manual_order && travelling) {
541 /* If we just started we would have returned earlier and have not reached
542 * this code. So obviously, we have completed our round: So turn autofill
543 * off again. */
544 v->vehicle_flags.Reset(VehicleFlag::AutofillTimetable);
545 v->vehicle_flags.Reset(VehicleFlag::AutofillPreserveWaitTime);
546 }
547
548 if (autofilling) return;
549
550 TimerGameTick::Ticks timetabled = travelling ? real_current_order->GetTimetabledTravel() :
551 real_current_order->GetTimetabledWait();
552
553 /* Vehicles will wait at stations if they arrive early even if they are not
554 * timetabled to wait there, so make sure the lateness counter is updated
555 * when this happens. */
556 if (timetabled == 0 && (travelling || v->lateness_counter >= 0)) return;
557
558 v->lateness_counter -= (timetabled - time_taken);
559
560 /* When we are more late than this timetabled bit takes we (somewhat expensively)
561 * check how many ticks the (fully filled) timetable has. If a timetable cycle is
562 * shorter than the amount of ticks we are late we reduce the lateness by the
563 * length of a full cycle till lateness is less than the length of a timetable
564 * cycle. When the timetable isn't fully filled the cycle will be Ticks::INVALID_TICKS. */
565 if (v->lateness_counter > timetabled) {
566 TimerGameTick::Ticks cycle = v->orders->GetTimetableTotalDuration();
567 if (cycle != Ticks::INVALID_TICKS && v->lateness_counter > cycle) {
568 v->lateness_counter %= cycle;
569 }
570 }
571
572 for (v = v->FirstShared(); v != nullptr; v = v->NextShared()) {
573 SetWindowDirty(WC_VEHICLE_TIMETABLE, v->index);
574 }
575}
VehicleFlag::AutofillTimetable
@ AutofillTimetable
Whether the vehicle should fill in the timetable automatically.
VehicleFlag::TimetableStarted
@ TimetableStarted
Whether the vehicle has started running on the timetable yet.
VehicleFlag::AutofillPreserveWaitTime
@ AutofillPreserveWaitTime
Whether non-destructive auto-fill should preserve waiting times.
BaseBitSet::Test
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
Definition base_bitset_type.hpp:141
BaseBitSet::Reset
constexpr Timpl & Reset()
Reset all bits.
Definition base_bitset_type.hpp:83
BaseBitSet::Set
constexpr Timpl & Set()
Set all bits.
Definition base_bitset_type.hpp:40
BaseBitSet::Any
constexpr bool Any(const Timpl &other) const
Test if any of the given values are set.
Definition base_bitset_type.hpp:170
CommandCost
Common return value for all commands.
Definition command_type.h:24
CommandCost::Failed
bool Failed() const
Did this command fail?
Definition command_type.h:177
EnumBitSet
Enum-as-bit-set wrapper.
Definition enum_type.hpp:177
Ticks::DAY_TICKS
static constexpr TimerGameTick::Ticks DAY_TICKS
1 day is 74 ticks; TimerGameCalendar::date_fract used to be uint16_t and incremented by 885.
Definition timer_game_tick.h:75
Ticks::INVALID_TICKS
static constexpr TimerGameTick::Ticks INVALID_TICKS
Representation of an invalid number of ticks.
Definition timer_game_tick.h:68
Ticks::TICKS_PER_SECOND
static constexpr TimerGameTick::Ticks TICKS_PER_SECOND
Estimation of how many ticks fit in a single second.
Definition timer_game_tick.h:76
TimerGameConst< struct Economy >::MAX_DATE
static constexpr TimerGame< struct Economy >::Date MAX_DATE
The date of the last day of the max year.
Definition timer_game_common.h:187
TimerGameConst< struct Economy >::DAYS_IN_LEAP_YEAR
static constexpr int DAYS_IN_LEAP_YEAR
sometimes, you need one day more...
Definition timer_game_common.h:150
TimerGameEconomy::date
static Date date
Current date in days (day counter).
Definition timer_game_economy.h:38
TimerGameEconomy::date_fract
static DateFract date_fract
Fractional part of the day.
Definition timer_game_economy.h:39
TimerGameTick::TickCounter
uint64_t TickCounter
The type that the tick counter is stored in.
Definition timer_game_tick.h:25
TimerGameTick::counter
static TickCounter counter
Monotonic counter, in ticks, since start of game.
Definition timer_game_tick.h:60
TimerGameTick::Ticks
int32_t Ticks
The type to store ticks in.
Definition timer_game_tick.h:24
TimerGame< struct Economy >::DateAtStartOfYear
static constexpr Date DateAtStartOfYear(Year year)
Calculate the date of the first day of a given year.
Definition timer_game_common.h:88
command_func.h
Functions related to commands.
CMD_ERROR
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
Definition command_func.h:28
DoCommandFlag::Execute
@ Execute
execute the given command
CheckOwnership
CommandCost CheckOwnership(Owner owner, TileIndex tile)
Check whether the current owner owns something.
Definition company_cmd.cpp:381
company_func.h
Functions related to companies.
CeilDiv
constexpr uint CeilDiv(uint a, uint b)
Computes ceil(a / b) for non-negative a and b.
Definition math_func.hpp:310
OrderNonStopFlag::NoDestination
@ NoDestination
The vehicle will stop at any station it passes except the destination, aka via.
VehicleOrderID
uint8_t VehicleOrderID
The index of an order within its current vehicle (not pool related)
Definition order_type.h:18
ModifyTimetableFlags
ModifyTimetableFlags
Enumeration for the data to set in CmdChangeTimetable.
Definition order_type.h:186
MTF_TRAVEL_TIME
@ MTF_TRAVEL_TIME
Set travel time.
Definition order_type.h:188
MTF_WAIT_TIME
@ MTF_WAIT_TIME
Set wait time.
Definition order_type.h:187
MTF_TRAVEL_SPEED
@ MTF_TRAVEL_SPEED
Set max travel speed.
Definition order_type.h:189
safeguards.h
A number of safeguards to prevent using unsafe methods.
stdafx.h
Definition of base types and functions in a cross-platform compatible way.
BaseConsist::current_order_time
TimerGameTick::Ticks current_order_time
How many ticks have passed since this order started.
Definition base_consist.h:37
BaseConsist::cur_real_order_index
VehicleOrderID cur_real_order_index
The index to the current real (non-implicit) order.
Definition base_consist.h:47
BaseConsist::vehicle_flags
VehicleFlags vehicle_flags
Used for gradual loading and other miscellaneous things (.
Definition base_consist.h:50
BaseConsist::timetable_start
TimerGameTick::TickCounter timetable_start
At what tick of TimerGameTick::counter the vehicle should start its timetable.
Definition base_consist.h:39
BaseConsist::lateness_counter
TimerGameTick::Ticks lateness_counter
How many ticks late (or early if negative) this vehicle is.
Definition base_consist.h:38
BaseConsist::ResetDepotUnbunching
void ResetDepotUnbunching()
Resets all the data used for depot unbunching.
Definition base_consist.cpp:49
BaseVehicle::type
VehicleType type
Type of vehicle.
Definition vehicle_type.h:51
CommandHelper
Definition command_func.h:84
OrderList::IsCompleteTimetable
bool IsCompleteTimetable() const
Checks whether all orders of the list have a filled timetable.
Definition order_cmd.cpp:486
OrderList::UpdateTotalDuration
void UpdateTotalDuration(TimerGameTick::Ticks delta)
Must be called if an order's timetable is changed to update internal book keeping.
Definition order_base.h:445
OrderList::GetFirstSharedVehicle
Vehicle * GetFirstSharedVehicle() const
Get the first vehicle of this vehicle chain.
Definition order_base.h:397
OrderList::UpdateTimetableDuration
void UpdateTimetableDuration(TimerGameTick::Ticks delta)
Must be called if an order's timetable is changed to update internal book keeping.
Definition order_base.h:439
OrderList::GetTimetableTotalDuration
TimerGameTick::Ticks GetTimetableTotalDuration() const
Gets the total duration of the vehicles timetable or Ticks::INVALID_TICKS is the timetable is not com...
Definition order_base.h:421
Order
Definition order_base.h:33
Order::GetTimetabledTravel
uint16_t GetTimetabledTravel() const
Get the time in ticks a vehicle should take to reach the destination or 0 if it's not timetabled.
Definition order_base.h:196
Order::Equals
bool Equals(const Order &other) const
Does this order have the same type, flags and destination?
Definition order_cmd.cpp:158
Order::GetMaxSpeed
uint16_t GetMaxSpeed() const
Get the maxmimum speed in km-ish/h a vehicle is allowed to reach on the way to the destination.
Definition order_base.h:207
Order::SetTravelTimetabled
void SetTravelTimetabled(bool timetabled)
Set if the travel time is explicitly timetabled (unless the order is conditional).
Definition order_base.h:212
Order::IsType
bool IsType(OrderType type) const
Check whether this order is of the given type.
Definition order_base.h:66
Order::GetWaitTime
uint16_t GetWaitTime() const
Get the time in ticks a vehicle will probably wait at the destination (timetabled or not).
Definition order_base.h:198
Order::GetType
OrderType GetType() const
Get the type of order of this order.
Definition order_base.h:72
Order::SetWaitTime
void SetWaitTime(uint16_t time)
Set the time in ticks to wait at the destination.
Definition order_base.h:218
Order::IsWaitTimetabled
bool IsWaitTimetabled() const
Does this order have an explicit wait time set?
Definition order_base.h:189
Order::SetTravelTime
void SetTravelTime(uint16_t time)
Set the time in ticks to take for travelling to the destination.
Definition order_base.h:224
Order::SetWaitTimetabled
void SetWaitTimetabled(bool timetabled)
Set if the wait time is explicitly timetabled (unless the order is conditional).
Definition order_base.h:210
Order::IsTravelTimetabled
bool IsTravelTimetabled() const
Does this order have an explicit travel time set?
Definition order_base.h:191
Order::GetTimetabledWait
uint16_t GetTimetabledWait() const
Get the time in ticks a vehicle should wait at the destination or 0 if it's not timetabled.
Definition order_base.h:194
Order::GetTravelTime
uint16_t GetTravelTime() const
Get the time in ticks a vehicle will probably take to reach the destination (timetabled or not).
Definition order_base.h:200
Order::GetNonStopType
OrderNonStopFlags GetNonStopType() const
At which stations must we stop?
Definition order_base.h:146
Order::SetMaxSpeed
void SetMaxSpeed(uint16_t speed)
Set the maxmimum speed in km-ish/h a vehicle is allowed to reach on the way to the destination.
Definition order_base.h:231
PoolID< uint32_t, struct VehicleIDTag, 0xFF000, 0xFFFFF >
Pool::PoolItem::index
Tindex index
Index of this pool item.
Definition pool_type.hpp:286
Pool::PoolItem<&_vehicle_pool >::GetIfValid
static Titem * GetIfValid(auto index)
Returns Titem with given index.
Definition pool_type.hpp:398
StrongType::Typedef
Templated helper to make a type-safe 'typedef' representing a single POD value.
Definition strong_typedef_type.hpp:130
Vehicle
Vehicle data structure.
Definition vehicle_base.h:205
Vehicle::GetOrder
Order * GetOrder(int index) const
Returns order 'index' of a vehicle or nullptr when it doesn't exists.
Definition vehicle_base.h:890
Vehicle::GetNumOrders
VehicleOrderID GetNumOrders() const
Get the number of orders this vehicle has.
Definition vehicle_base.h:705
Vehicle::current_order
Order current_order
The current order (+ status, like: loading)
Definition vehicle_base.h:311
Vehicle::orders
OrderList * orders
Pointer to the order list for this vehicle.
Definition vehicle_base.h:314
Vehicle::NextShared
Vehicle * NextShared() const
Get the next vehicle of the shared vehicle chain.
Definition vehicle_base.h:681
Vehicle::IsPrimaryVehicle
virtual bool IsPrimaryVehicle() const
Whether this is the primary vehicle in the chain.
Definition vehicle_base.h:432
Vehicle::FirstShared
Vehicle * FirstShared() const
Get the first vehicle of this vehicle chain.
Definition vehicle_base.h:693
Vehicle::owner
Owner owner
Which company owns the vehicle?
Definition vehicle_base.h:270
Vehicle::unitnumber
UnitID unitnumber
unit number, for display purposes only
Definition vehicle_base.h:281
timer_game_economy.h
Definition of the game-economy-timer.
timer_game_tick.h
Definition of the tick-based game-timer.
timetable.h
Functions related to time tabling.
MAX_TIMETABLE_START_YEARS
static const TimerGameEconomy::Year MAX_TIMETABLE_START_YEARS
The maximum start date offset, in economy years.
Definition timetable.h:18
CmdSetVehicleOnTime
CommandCost CmdSetVehicleOnTime(DoCommandFlags flags, VehicleID veh, bool apply_to_group)
Clear the lateness counter to make the vehicle on time.
Definition timetable_cmd.cpp:259
CmdAutofillTimetable
CommandCost CmdAutofillTimetable(DoCommandFlags flags, VehicleID veh, bool autofill, bool preserve_wait_time)
Start or stop filling the timetable automatically from the time the vehicle actually takes to complet...
Definition timetable_cmd.cpp:425
UpdateVehicleTimetable
void UpdateVehicleTimetable(Vehicle *v, bool travelling)
Update the timetable for the vehicle.
Definition timetable_cmd.cpp:469
CmdSetTimetableStart
CommandCost CmdSetTimetableStart(DoCommandFlags flags, VehicleID veh_id, bool timetable_all, TimerGameTick::TickCounter start_tick)
Set the start date of the timetable.
Definition timetable_cmd.cpp:351
VehicleTimetableSorter
static bool VehicleTimetableSorter(Vehicle *const &a, Vehicle *const &b)
Order vehicles based on their timetable.
Definition timetable_cmd.cpp:313
CmdBulkChangeTimetable
CommandCost CmdBulkChangeTimetable(DoCommandFlags flags, VehicleID veh, ModifyTimetableFlags mtf, uint16_t data)
Change timetable data of all orders of a vehicle.
Definition timetable_cmd.cpp:228
ChangeTimetable
static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint16_t val, ModifyTimetableFlags mtf, bool timetabled)
Change/update a particular timetable entry.
Definition timetable_cmd.cpp:66
CmdChangeTimetable
CommandCost CmdChangeTimetable(DoCommandFlags flags, VehicleID veh, VehicleOrderID order_number, ModifyTimetableFlags mtf, uint16_t data)
Change timetable data of an order.
Definition timetable_cmd.cpp:133
GetStartTickFromDate
TimerGameTick::TickCounter GetStartTickFromDate(TimerGameEconomy::Date start_date)
Get the TimerGameTick::TickCounter tick of a given date.
Definition timetable_cmd.cpp:29
GetDateFromStartTick
TimerGameEconomy::Date GetDateFromStartTick(TimerGameTick::TickCounter start_tick)
Get a date from a given start tick of timetable.
Definition timetable_cmd.cpp:46
timetable_cmd.h
Command definitions related to timetables.
vehicle_base.h
Base class for all vehicles.
VEH_AIRCRAFT
@ VEH_AIRCRAFT
Aircraft vehicle type.
Definition vehicle_type.h:28
SetWindowDirty
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition window.cpp:3179
window_func.h
Window functions not directly related to making/drawing windows.
WC_VEHICLE_TIMETABLE
@ WC_VEHICLE_TIMETABLE
Vehicle timetable; Window numbers:
Definition window_type.h:229