OpenTTD
vehicle_gui.cpp
Go to the documentation of this file.
1 /* $Id: vehicle_gui.cpp 27895 2017-08-20 08:28:05Z alberth $ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * 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.
6  * 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.
7  * 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 <http://www.gnu.org/licenses/>.
8  */
9 
12 #include "stdafx.h"
13 #include "debug.h"
14 #include "company_func.h"
15 #include "gui.h"
16 #include "textbuf_gui.h"
17 #include "command_func.h"
18 #include "vehicle_gui_base.h"
19 #include "viewport_func.h"
20 #include "newgrf_text.h"
21 #include "newgrf_debug.h"
22 #include "roadveh.h"
23 #include "train.h"
24 #include "aircraft.h"
25 #include "depot_map.h"
26 #include "group_gui.h"
27 #include "strings_func.h"
28 #include "vehicle_func.h"
29 #include "autoreplace_gui.h"
30 #include "string_func.h"
31 #include "widgets/dropdown_func.h"
32 #include "timetable.h"
33 #include "articulated_vehicles.h"
34 #include "spritecache.h"
35 #include "core/geometry_func.hpp"
36 #include "company_base.h"
37 #include "engine_func.h"
38 #include "station_base.h"
39 #include "tilehighlight_func.h"
40 #include "zoom_func.h"
41 
42 #include "safeguards.h"
43 
44 
45 Sorting _sorting;
46 
60 
61 GUIVehicleList::SortFunction * const BaseVehicleListWindow::vehicle_sorter_funcs[] = {
75 };
76 
77 const StringID BaseVehicleListWindow::vehicle_sorter_names[] = {
78  STR_SORT_BY_NUMBER,
79  STR_SORT_BY_NAME,
80  STR_SORT_BY_AGE,
81  STR_SORT_BY_PROFIT_THIS_YEAR,
82  STR_SORT_BY_PROFIT_LAST_YEAR,
83  STR_SORT_BY_TOTAL_CAPACITY_PER_CARGOTYPE,
84  STR_SORT_BY_RELIABILITY,
85  STR_SORT_BY_MAX_SPEED,
86  STR_SORT_BY_MODEL,
87  STR_SORT_BY_VALUE,
88  STR_SORT_BY_LENGTH,
89  STR_SORT_BY_LIFE_TIME,
90  STR_SORT_BY_TIMETABLE_DELAY,
92 };
93 
94 const StringID BaseVehicleListWindow::vehicle_depot_name[] = {
95  STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT,
96  STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT,
97  STR_VEHICLE_LIST_SEND_SHIP_TO_DEPOT,
98  STR_VEHICLE_LIST_SEND_AIRCRAFT_TO_HANGAR
99 };
100 
107 {
108  uint unitnumber = 0;
109  for (const Vehicle **v = vehicles.Begin(); v != vehicles.End(); v++) {
110  unitnumber = max<uint>(unitnumber, (*v)->unitnumber);
111  }
112 
113  if (unitnumber >= 10000) return 5;
114  if (unitnumber >= 1000) return 4;
115  if (unitnumber >= 100) return 3;
116 
117  /*
118  * When the smallest unit number is less than 10, it is
119  * quite likely that it will expand to become more than
120  * 10 quite soon.
121  */
122  return 2;
123 }
124 
125 void BaseVehicleListWindow::BuildVehicleList()
126 {
127  if (!this->vehicles.NeedRebuild()) return;
128 
129  DEBUG(misc, 3, "Building vehicle list type %d for company %d given index %d", this->vli.type, this->vli.company, this->vli.index);
130 
131  GenerateVehicleSortList(&this->vehicles, this->vli);
132 
134 
135  this->vehicles.RebuildDone();
136  this->vscroll->SetCount(this->vehicles.Length());
137 }
138 
145 Dimension BaseVehicleListWindow::GetActionDropdownSize(bool show_autoreplace, bool show_group)
146 {
147  Dimension d = {0, 0};
148 
149  if (show_autoreplace) d = maxdim(d, GetStringBoundingBox(STR_VEHICLE_LIST_REPLACE_VEHICLES));
150  d = maxdim(d, GetStringBoundingBox(STR_VEHICLE_LIST_SEND_FOR_SERVICING));
151  d = maxdim(d, GetStringBoundingBox(this->vehicle_depot_name[this->vli.vtype]));
152 
153  if (show_group) {
154  d = maxdim(d, GetStringBoundingBox(STR_GROUP_ADD_SHARED_VEHICLE));
155  d = maxdim(d, GetStringBoundingBox(STR_GROUP_REMOVE_ALL_VEHICLES));
156  }
157 
158  return d;
159 }
160 
167 DropDownList *BaseVehicleListWindow::BuildActionDropdownList(bool show_autoreplace, bool show_group)
168 {
169  DropDownList *list = new DropDownList();
170 
171  if (show_autoreplace) *list->Append() = new DropDownListStringItem(STR_VEHICLE_LIST_REPLACE_VEHICLES, ADI_REPLACE, false);
172  *list->Append() = new DropDownListStringItem(STR_VEHICLE_LIST_SEND_FOR_SERVICING, ADI_SERVICE, false);
173  *list->Append() = new DropDownListStringItem(this->vehicle_depot_name[this->vli.vtype], ADI_DEPOT, false);
174 
175  if (show_group) {
176  *list->Append() = new DropDownListStringItem(STR_GROUP_ADD_SHARED_VEHICLE, ADI_ADD_SHARED, false);
177  *list->Append() = new DropDownListStringItem(STR_GROUP_REMOVE_ALL_VEHICLES, ADI_REMOVE_ALL, false);
178  }
179 
180  return list;
181 }
182 
183 /* cached values for VehicleNameSorter to spare many GetString() calls */
184 static const Vehicle *_last_vehicle[2] = { NULL, NULL };
185 
186 void BaseVehicleListWindow::SortVehicleList()
187 {
188  if (this->vehicles.Sort()) return;
189 
190  /* invalidate cached values for name sorter - vehicle names could change */
191  _last_vehicle[0] = _last_vehicle[1] = NULL;
192 }
193 
194 void DepotSortList(VehicleList *list)
195 {
196  if (list->Length() < 2) return;
197  QSortT(list->Begin(), list->Length(), &VehicleNumberSorter);
198 }
199 
201 static void DrawVehicleProfitButton(const Vehicle *v, int x, int y)
202 {
203  SpriteID spr;
204 
205  /* draw profit-based coloured icons */
206  if (v->age <= VEHICLE_PROFIT_MIN_AGE) {
207  spr = SPR_PROFIT_NA;
208  } else if (v->GetDisplayProfitLastYear() < 0) {
209  spr = SPR_PROFIT_NEGATIVE;
211  spr = SPR_PROFIT_SOME;
212  } else {
213  spr = SPR_PROFIT_LOT;
214  }
215  DrawSprite(spr, PAL_NONE, x, y);
216 }
217 
219 static const uint MAX_REFIT_CYCLE = 256;
220 
230 byte GetBestFittingSubType(Vehicle *v_from, Vehicle *v_for, CargoID dest_cargo_type)
231 {
232  v_from = v_from->GetFirstEnginePart();
233  v_for = v_for->GetFirstEnginePart();
234 
235  /* Create a list of subtypes used by the various parts of v_for */
236  static SmallVector<StringID, 4> subtypes;
237  subtypes.Clear();
238  for (; v_from != NULL; v_from = v_from->HasArticulatedPart() ? v_from->GetNextArticulatedPart() : NULL) {
239  const Engine *e_from = v_from->GetEngine();
240  if (!e_from->CanCarryCargo() || !HasBit(e_from->info.callback_mask, CBM_VEHICLE_CARGO_SUFFIX)) continue;
241  subtypes.Include(GetCargoSubtypeText(v_from));
242  }
243 
244  byte ret_refit_cyc = 0;
245  bool success = false;
246  if (subtypes.Length() > 0) {
247  /* Check whether any articulated part is refittable to 'dest_cargo_type' with a subtype listed in 'subtypes' */
248  for (Vehicle *v = v_for; v != NULL; v = v->HasArticulatedPart() ? v->GetNextArticulatedPart() : NULL) {
249  const Engine *e = v->GetEngine();
250  if (!e->CanCarryCargo() || !HasBit(e->info.callback_mask, CBM_VEHICLE_CARGO_SUFFIX)) continue;
251  if (!HasBit(e->info.refit_mask, dest_cargo_type) && v->cargo_type != dest_cargo_type) continue;
252 
253  CargoID old_cargo_type = v->cargo_type;
254  byte old_cargo_subtype = v->cargo_subtype;
255 
256  /* Set the 'destination' cargo */
257  v->cargo_type = dest_cargo_type;
258 
259  /* Cycle through the refits */
260  for (uint refit_cyc = 0; refit_cyc < MAX_REFIT_CYCLE; refit_cyc++) {
261  v->cargo_subtype = refit_cyc;
262 
263  /* Make sure we don't pick up anything cached. */
264  v->First()->InvalidateNewGRFCache();
265  v->InvalidateNewGRFCache();
266 
267  StringID subtype = GetCargoSubtypeText(v);
268  if (subtype == STR_EMPTY) break;
269 
270  if (!subtypes.Contains(subtype)) continue;
271 
272  /* We found something matching. */
273  ret_refit_cyc = refit_cyc;
274  success = true;
275  break;
276  }
277 
278  /* Reset the vehicle's cargo type */
279  v->cargo_type = old_cargo_type;
280  v->cargo_subtype = old_cargo_subtype;
281 
282  /* Make sure we don't taint the vehicle. */
283  v->First()->InvalidateNewGRFCache();
284  v->InvalidateNewGRFCache();
285 
286  if (success) break;
287  }
288  }
289 
290  return ret_refit_cyc;
291 }
292 
294 struct RefitOption {
296  byte subtype;
298 
304  inline bool operator != (const RefitOption &other) const
305  {
306  return other.cargo != this->cargo || other.string != this->string;
307  }
308 
314  inline bool operator == (const RefitOption &other) const
315  {
316  return other.cargo == this->cargo && other.string == this->string;
317  }
318 };
319 
321 
331 static void DrawVehicleRefitWindow(const SubtypeList list[NUM_CARGO], const int sel[2], uint pos, uint rows, uint delta, const Rect &r)
332 {
333  uint y = r.top + WD_MATRIX_TOP;
334  uint current = 0;
335 
336  bool rtl = _current_text_dir == TD_RTL;
337  uint iconwidth = max(GetSpriteSize(SPR_CIRCLE_FOLDED).width, GetSpriteSize(SPR_CIRCLE_UNFOLDED).width);
338  uint iconheight = GetSpriteSize(SPR_CIRCLE_FOLDED).height;
339  int linecolour = _colour_gradient[COLOUR_ORANGE][4];
340 
341  int iconleft = rtl ? r.right - WD_MATRIX_RIGHT - iconwidth : r.left + WD_MATRIX_LEFT;
342  int iconcenter = rtl ? r.right - WD_MATRIX_RIGHT - iconwidth / 2 : r.left + WD_MATRIX_LEFT + iconwidth / 2;
343  int iconinner = rtl ? r.right - WD_MATRIX_RIGHT - iconwidth : r.left + WD_MATRIX_LEFT + iconwidth;
344 
345  int textleft = r.left + WD_MATRIX_LEFT + (rtl ? 0 : iconwidth + 4);
346  int textright = r.right - WD_MATRIX_RIGHT - (rtl ? iconwidth + 4 : 0);
347 
348  /* Draw the list of subtypes for each cargo, and find the selected refit option (by its position). */
349  for (uint i = 0; current < pos + rows && i < NUM_CARGO; i++) {
350  for (uint j = 0; current < pos + rows && j < list[i].Length(); j++) {
351  const RefitOption &refit = list[i][j];
352 
353  /* Hide subtypes if sel[0] does not match */
354  if (sel[0] != (int)i && refit.subtype != 0xFF) continue;
355 
356  /* Refit options with a position smaller than pos don't have to be drawn. */
357  if (current < pos) {
358  current++;
359  continue;
360  }
361 
362  if (list[i].Length() > 1) {
363  if (refit.subtype != 0xFF) {
364  /* Draw tree lines */
365  int ycenter = y + FONT_HEIGHT_NORMAL / 2;
366  GfxDrawLine(iconcenter, y - WD_MATRIX_TOP, iconcenter, j == list[i].Length() - 1 ? ycenter : y - WD_MATRIX_TOP + delta - 1, linecolour);
367  GfxDrawLine(iconcenter, ycenter, iconinner, ycenter, linecolour);
368  } else {
369  /* Draw expand/collapse icon */
370  DrawSprite(sel[0] == (int)i ? SPR_CIRCLE_UNFOLDED : SPR_CIRCLE_FOLDED, PAL_NONE, iconleft, y + (FONT_HEIGHT_NORMAL - iconheight) / 2);
371  }
372  }
373 
374  TextColour colour = (sel[0] == (int)i && (uint)sel[1] == j) ? TC_WHITE : TC_BLACK;
375  /* Get the cargo name. */
376  SetDParam(0, CargoSpec::Get(refit.cargo)->name);
377  SetDParam(1, refit.string);
378  DrawString(textleft, textright, y, STR_JUST_STRING_STRING, colour);
379 
380  y += delta;
381  current++;
382  }
383  }
384 }
385 
387 struct RefitWindow : public Window {
388  int sel[2];
399  int click_x;
401  uint8 num_vehicles;
402  bool auto_refit;
403 
408  {
409  for (uint i = 0; i < NUM_CARGO; i++) this->list[i].Clear();
410  Vehicle *v = Vehicle::Get(this->window_number);
411 
412  /* Check only the selected vehicles. */
413  VehicleSet vehicles_to_refit;
414  GetVehicleSet(vehicles_to_refit, Vehicle::Get(this->selected_vehicle), this->num_vehicles);
415 
416  do {
417  if (v->type == VEH_TRAIN && !vehicles_to_refit.Contains(v->index)) continue;
418  const Engine *e = v->GetEngine();
419  uint32 cmask = e->info.refit_mask;
420  byte callback_mask = e->info.callback_mask;
421 
422  /* Skip this engine if it does not carry anything */
423  if (!e->CanCarryCargo()) continue;
424  /* Skip this engine if we build the list for auto-refitting and engine doesn't allow it. */
425  if (this->auto_refit && !HasBit(e->info.misc_flags, EF_AUTO_REFIT)) continue;
426 
427  /* Loop through all cargoes in the refit mask */
428  int current_index = 0;
429  const CargoSpec *cs;
431  CargoID cid = cs->Index();
432  /* Skip cargo type if it's not listed */
433  if (!HasBit(cmask, cid)) {
434  current_index++;
435  continue;
436  }
437 
438  bool first_vehicle = this->list[current_index].Length() == 0;
439  if (first_vehicle) {
440  /* Keeping the current subtype is always an option. It also serves as the option in case of no subtypes */
441  RefitOption *option = this->list[current_index].Append();
442  option->cargo = cid;
443  option->subtype = 0xFF;
444  option->string = STR_EMPTY;
445  }
446 
447  /* Check the vehicle's callback mask for cargo suffixes.
448  * This is not supported for ordered refits, since subtypes only have a meaning
449  * for a specific vehicle at a specific point in time, which conflicts with shared orders,
450  * autoreplace, autorenew, clone, order restoration, ... */
451  if (this->order == INVALID_VEH_ORDER_ID && HasBit(callback_mask, CBM_VEHICLE_CARGO_SUFFIX)) {
452  /* Make a note of the original cargo type. It has to be
453  * changed to test the cargo & subtype... */
454  CargoID temp_cargo = v->cargo_type;
455  byte temp_subtype = v->cargo_subtype;
456 
457  v->cargo_type = cid;
458 
459  for (uint refit_cyc = 0; refit_cyc < MAX_REFIT_CYCLE; refit_cyc++) {
460  v->cargo_subtype = refit_cyc;
461 
462  /* Make sure we don't pick up anything cached. */
465 
466  StringID subtype = GetCargoSubtypeText(v);
467 
468  if (first_vehicle) {
469  /* Append new subtype (don't add duplicates though) */
470  if (subtype == STR_EMPTY) break;
471 
472  RefitOption option;
473  option.cargo = cid;
474  option.subtype = refit_cyc;
475  option.string = subtype;
476  this->list[current_index].Include(option);
477  } else {
478  /* Intersect the subtypes of earlier vehicles with the subtypes of this vehicle */
479  if (subtype == STR_EMPTY) {
480  /* No more subtypes for this vehicle, delete all subtypes >= refit_cyc */
481  SubtypeList &l = this->list[current_index];
482  /* 0xFF item is in front, other subtypes are sorted. So just truncate the list in the right spot */
483  for (uint i = 1; i < l.Length(); i++) {
484  if (l[i].subtype >= refit_cyc) {
485  l.Resize(i);
486  break;
487  }
488  }
489  break;
490  } else {
491  /* Check whether the subtype matches with the subtype of earlier vehicles. */
492  uint pos = 1;
493  SubtypeList &l = this->list[current_index];
494  while (pos < l.Length() && l[pos].subtype != refit_cyc) pos++;
495  if (pos < l.Length() && l[pos].string != subtype) {
496  /* String mismatch, remove item keeping the order */
497  l.ErasePreservingOrder(pos);
498  }
499  }
500  }
501  }
502 
503  /* Reset the vehicle's cargo type */
504  v->cargo_type = temp_cargo;
505  v->cargo_subtype = temp_subtype;
506 
507  /* And make sure we haven't tainted the cache */
510  }
511  current_index++;
512  }
513  } while (v->IsGroundVehicle() && (v = v->Next()) != NULL);
514  }
515 
520  {
521  uint scroll_row = 0;
522  uint row = 0;
523 
524  for (uint i = 0; i < NUM_CARGO; i++) {
525  for (uint j = 0; j < this->list[i].Length(); j++) {
526  const RefitOption &refit = this->list[i][j];
527 
528  /* Hide subtypes if sel[0] does not match */
529  if (this->sel[0] != (int)i && refit.subtype != 0xFF) continue;
530 
531  if (this->sel[0] == (int)i && (uint)this->sel[1] == j) scroll_row = row;
532 
533  row++;
534  }
535  }
536 
537  this->vscroll->SetCount(row);
538  if (scroll_row < row) this->vscroll->ScrollTowards(scroll_row);
539  }
540 
545  void SetSelection(uint click_row)
546  {
547  uint row = 0;
548 
549  for (uint i = 0; i < NUM_CARGO; i++) {
550  for (uint j = 0; j < this->list[i].Length(); j++) {
551  const RefitOption &refit = this->list[i][j];
552 
553  /* Hide subtypes if sel[0] does not match */
554  if (this->sel[0] != (int)i && refit.subtype != 0xFF) continue;
555 
556  if (row == click_row) {
557  this->sel[0] = i;
558  this->sel[1] = j;
559  return;
560  }
561 
562  row++;
563  }
564  }
565 
566  this->sel[0] = -1;
567  this->sel[1] = 0;
568  }
569 
575  {
576  if (this->sel[0] < 0) return NULL;
577 
578  SubtypeList &l = this->list[this->sel[0]];
579  if ((uint)this->sel[1] >= l.Length()) return NULL;
580 
581  return &l[this->sel[1]];
582  }
583 
584  RefitWindow(WindowDesc *desc, const Vehicle *v, VehicleOrderID order, bool auto_refit) : Window(desc)
585  {
586  this->sel[0] = -1;
587  this->sel[1] = 0;
588  this->auto_refit = auto_refit;
589  this->order = order;
590  this->CreateNestedTree();
591 
592  this->vscroll = this->GetScrollbar(WID_VR_SCROLLBAR);
593  this->hscroll = (v->IsGroundVehicle() ? this->GetScrollbar(WID_VR_HSCROLLBAR) : NULL);
594  this->GetWidget<NWidgetCore>(WID_VR_SELECT_HEADER)->tool_tip = STR_REFIT_TRAIN_LIST_TOOLTIP + v->type;
595  this->GetWidget<NWidgetCore>(WID_VR_MATRIX)->tool_tip = STR_REFIT_TRAIN_LIST_TOOLTIP + v->type;
596  NWidgetCore *nwi = this->GetWidget<NWidgetCore>(WID_VR_REFIT);
597  nwi->widget_data = STR_REFIT_TRAIN_REFIT_BUTTON + v->type;
598  nwi->tool_tip = STR_REFIT_TRAIN_REFIT_TOOLTIP + v->type;
599  this->GetWidget<NWidgetStacked>(WID_VR_SHOW_HSCROLLBAR)->SetDisplayedPlane(v->IsGroundVehicle() ? 0 : SZSP_HORIZONTAL);
600  this->GetWidget<NWidgetCore>(WID_VR_VEHICLE_PANEL_DISPLAY)->tool_tip = (v->type == VEH_TRAIN) ? STR_REFIT_SELECT_VEHICLES_TOOLTIP : STR_NULL;
601 
602  this->FinishInitNested(v->index);
603  this->owner = v->owner;
604 
605  this->SetWidgetDisabledState(WID_VR_REFIT, this->sel[0] < 0);
606  }
607 
608  virtual void OnInit()
609  {
610  if (this->cargo != NULL) {
611  /* Store the RefitOption currently in use. */
612  RefitOption current_refit_option = *(this->cargo);
613 
614  /* Rebuild the refit list */
615  this->BuildRefitList();
616  this->sel[0] = -1;
617  this->sel[1] = 0;
618  this->cargo = NULL;
619  for (uint i = 0; this->cargo == NULL && i < NUM_CARGO; i++) {
620  for (uint j = 0; j < list[i].Length(); j++) {
621  if (list[i][j] == current_refit_option) {
622  this->sel[0] = i;
623  this->sel[1] = j;
624  this->cargo = &list[i][j];
625  break;
626  }
627  }
628  }
629 
630  this->SetWidgetDisabledState(WID_VR_REFIT, this->sel[0] < 0);
631  this->RefreshScrollbar();
632  } else {
633  /* Rebuild the refit list */
635  }
636  }
637 
638  virtual void OnPaint()
639  {
640  /* Determine amount of items for scroller. */
641  if (this->hscroll != NULL) this->hscroll->SetCount(this->vehicle_width);
642 
643  /* Calculate sprite position. */
644  NWidgetCore *vehicle_panel_display = this->GetWidget<NWidgetCore>(WID_VR_VEHICLE_PANEL_DISPLAY);
645  int sprite_width = max(0, ((int)vehicle_panel_display->current_x - this->vehicle_width) / 2);
646  this->sprite_left = vehicle_panel_display->pos_x;
647  this->sprite_right = vehicle_panel_display->pos_x + vehicle_panel_display->current_x - 1;
648  if (_current_text_dir == TD_RTL) {
649  this->sprite_right -= sprite_width;
650  this->vehicle_margin = vehicle_panel_display->current_x - sprite_right;
651  } else {
652  this->sprite_left += sprite_width;
653  this->vehicle_margin = sprite_left;
654  }
655 
656  this->DrawWidgets();
657  }
658 
659  virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
660  {
661  switch (widget) {
662  case WID_VR_MATRIX:
664  size->height = resize->height * 8;
665  break;
666 
668  size->height = ScaleGUITrad(GetVehicleHeight(Vehicle::Get(this->window_number)->type));
669  break;
670 
671  case WID_VR_INFO:
672  size->width = WD_FRAMERECT_LEFT + this->information_width + WD_FRAMERECT_RIGHT;
673  break;
674  }
675  }
676 
677  virtual void SetStringParameters(int widget) const
678  {
679  if (widget == WID_VR_CAPTION) SetDParam(0, Vehicle::Get(this->window_number)->index);
680  }
681 
689  {
690  assert(_current_company == _local_company);
691  Vehicle *v = Vehicle::Get(this->window_number);
692  CommandCost cost = DoCommand(v->tile, this->selected_vehicle, option->cargo | (int)this->auto_refit << 6 | option->subtype << 8 |
693  this->num_vehicles << 16, DC_QUERY_COST, GetCmdRefitVeh(v->type));
694 
695  if (cost.Failed()) return INVALID_STRING_ID;
696 
697  SetDParam(0, option->cargo);
699 
700  Money money = cost.GetCost();
702  SetDParam(2, CT_MAIL);
704  if (this->order != INVALID_VEH_ORDER_ID) {
705  /* No predictable cost */
706  return STR_PURCHASE_INFO_AIRCRAFT_CAPACITY;
707  } else if (money <= 0) {
708  SetDParam(4, -money);
709  return STR_REFIT_NEW_CAPACITY_INCOME_FROM_AIRCRAFT_REFIT;
710  } else {
711  SetDParam(4, money);
712  return STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT;
713  }
714  } else {
715  if (this->order != INVALID_VEH_ORDER_ID) {
716  /* No predictable cost */
717  SetDParam(2, STR_EMPTY);
718  return STR_PURCHASE_INFO_CAPACITY;
719  } else if (money <= 0) {
720  SetDParam(2, -money);
721  return STR_REFIT_NEW_CAPACITY_INCOME_FROM_REFIT;
722  } else {
723  SetDParam(2, money);
724  return STR_REFIT_NEW_CAPACITY_COST_OF_REFIT;
725  }
726  }
727  }
728 
729  virtual void DrawWidget(const Rect &r, int widget) const
730  {
731  switch (widget) {
733  Vehicle *v = Vehicle::Get(this->window_number);
734  DrawVehicleImage(v, this->sprite_left + WD_FRAMERECT_LEFT, this->sprite_right - WD_FRAMERECT_RIGHT,
735  r.top + WD_FRAMERECT_TOP, INVALID_VEHICLE, EIT_IN_DETAILS, this->hscroll != NULL ? this->hscroll->GetPosition() : 0);
736 
737  /* Highlight selected vehicles. */
738  if (this->order != INVALID_VEH_ORDER_ID) break;
739  int x = 0;
740  switch (v->type) {
741  case VEH_TRAIN: {
742  VehicleSet vehicles_to_refit;
743  GetVehicleSet(vehicles_to_refit, Vehicle::Get(this->selected_vehicle), this->num_vehicles);
744 
745  int left = INT32_MIN;
746  int width = 0;
747 
748  for (Train *u = Train::From(v); u != NULL; u = u->Next()) {
749  /* Start checking. */
750  if (vehicles_to_refit.Contains(u->index) && left == INT32_MIN) {
751  left = x - this->hscroll->GetPosition() + r.left + this->vehicle_margin;
752  width = 0;
753  }
754 
755  /* Draw a selection. */
756  if ((!vehicles_to_refit.Contains(u->index) || u->Next() == NULL) && left != INT32_MIN) {
757  if (u->Next() == NULL && vehicles_to_refit.Contains(u->index)) {
758  int current_width = u->GetDisplayImageWidth();
759  width += current_width;
760  x += current_width;
761  }
762 
763  int right = Clamp(left + width, 0, r.right);
764  left = max(0, left);
765 
766  if (_current_text_dir == TD_RTL) {
767  right = this->GetWidget<NWidgetCore>(WID_VR_VEHICLE_PANEL_DISPLAY)->current_x - left;
768  left = right - width;
769  }
770 
771  if (left != right) {
772  DrawFrameRect(left, r.top + WD_FRAMERECT_TOP, right, r.top + WD_FRAMERECT_TOP + ScaleGUITrad(14) - 1, COLOUR_WHITE, FR_BORDERONLY);
773  }
774 
775  left = INT32_MIN;
776  }
777 
778  int current_width = u->GetDisplayImageWidth();
779  width += current_width;
780  x += current_width;
781  }
782  break;
783  }
784 
785  default: break;
786  }
787  break;
788  }
789 
790  case WID_VR_MATRIX:
791  DrawVehicleRefitWindow(this->list, this->sel, this->vscroll->GetPosition(), this->vscroll->GetCapacity(), this->resize.step_height, r);
792  break;
793 
794  case WID_VR_INFO:
795  if (this->cargo != NULL) {
796  StringID string = this->GetCapacityString(this->cargo);
797  if (string != INVALID_STRING_ID) {
799  r.top + WD_FRAMERECT_TOP, r.bottom - WD_FRAMERECT_BOTTOM, string);
800  }
801  }
802  break;
803  }
804  }
805 
811  virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
812  {
813  switch (data) {
814  case VIWD_AUTOREPLACE: // Autoreplace replaced the vehicle; selected_vehicle became invalid.
815  case VIWD_CONSIST_CHANGED: { // The consist has changed; rebuild the entire list.
816  /* Clear the selection. */
817  Vehicle *v = Vehicle::Get(this->window_number);
818  this->selected_vehicle = v->index;
819  this->num_vehicles = UINT8_MAX;
820  }
821  FALLTHROUGH;
822 
823  case 2: { // The vehicle selection has changed; rebuild the entire list.
824  if (!gui_scope) break;
825  this->BuildRefitList();
826 
827  /* The vehicle width has changed too. */
828  this->vehicle_width = GetVehicleWidth(Vehicle::Get(this->window_number), EIT_IN_DETAILS);
829  uint max_width = 0;
830 
831  /* Check the width of all cargo information strings. */
832  for (uint i = 0; i < NUM_CARGO; i++) {
833  for (uint j = 0; j < this->list[i].Length(); j++) {
834  StringID string = this->GetCapacityString(&list[i][j]);
835  if (string != INVALID_STRING_ID) {
836  Dimension dim = GetStringBoundingBox(string);
837  max_width = max(dim.width, max_width);
838  }
839  }
840  }
841 
842  if (this->information_width < max_width) {
843  this->information_width = max_width;
844  this->ReInit();
845  }
846  }
847  FALLTHROUGH;
848 
849  case 1: // A new cargo has been selected.
850  if (!gui_scope) break;
851  this->cargo = GetRefitOption();
852  this->RefreshScrollbar();
853  break;
854  }
855  }
856 
857  int GetClickPosition(int click_x)
858  {
859  const NWidgetCore *matrix_widget = this->GetWidget<NWidgetCore>(WID_VR_VEHICLE_PANEL_DISPLAY);
860  if (_current_text_dir == TD_RTL) click_x = matrix_widget->current_x - click_x;
861  click_x -= this->vehicle_margin;
862  if (this->hscroll != NULL) click_x += this->hscroll->GetPosition();
863 
864  return click_x;
865  }
866 
867  void SetSelectedVehicles(int drag_x)
868  {
869  drag_x = GetClickPosition(drag_x);
870 
871  int left_x = min(this->click_x, drag_x);
872  int right_x = max(this->click_x, drag_x);
873  this->num_vehicles = 0;
874 
875  Vehicle *v = Vehicle::Get(this->window_number);
876  /* Find the vehicle part that was clicked. */
877  switch (v->type) {
878  case VEH_TRAIN: {
879  /* Don't select anything if we are not clicking in the vehicle. */
880  if (left_x >= 0) {
881  const Train *u = Train::From(v);
882  bool start_counting = false;
883  for (; u != NULL; u = u->Next()) {
884  int current_width = u->GetDisplayImageWidth();
885  left_x -= current_width;
886  right_x -= current_width;
887 
888  if (left_x < 0 && !start_counting) {
889  this->selected_vehicle = u->index;
890  start_counting = true;
891 
892  /* Count the first vehicle, even if articulated part */
893  this->num_vehicles++;
894  } else if (start_counting && !u->IsArticulatedPart()) {
895  /* Do not count articulated parts */
896  this->num_vehicles++;
897  }
898 
899  if (right_x < 0) break;
900  }
901  }
902 
903  /* If the selection is not correct, clear it. */
904  if (this->num_vehicles != 0) {
905  if (_ctrl_pressed) this->num_vehicles = UINT8_MAX;
906  break;
907  }
908  }
909  FALLTHROUGH;
910 
911  default:
912  /* Clear the selection. */
913  this->selected_vehicle = v->index;
914  this->num_vehicles = UINT8_MAX;
915  break;
916  }
917  }
918 
919  virtual void OnClick(Point pt, int widget, int click_count)
920  {
921  switch (widget) {
922  case WID_VR_VEHICLE_PANEL_DISPLAY: { // Vehicle image.
923  if (this->order != INVALID_VEH_ORDER_ID) break;
924  NWidgetBase *nwi = this->GetWidget<NWidgetBase>(WID_VR_VEHICLE_PANEL_DISPLAY);
925  this->click_x = GetClickPosition(pt.x - nwi->pos_x);
926  this->SetSelectedVehicles(pt.x - nwi->pos_x);
928  if (!_ctrl_pressed) {
929  SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this);
930  } else {
931  /* The vehicle selection has changed. */
932  this->InvalidateData(2);
933  }
934  break;
935  }
936 
937  case WID_VR_MATRIX: { // listbox
938  this->SetSelection(this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_VR_MATRIX));
939  this->SetWidgetDisabledState(WID_VR_REFIT, this->sel[0] < 0);
940  this->InvalidateData(1);
941 
942  if (click_count == 1) break;
943  }
944  FALLTHROUGH;
945 
946  case WID_VR_REFIT: // refit button
947  if (this->cargo != NULL) {
948  const Vehicle *v = Vehicle::Get(this->window_number);
949 
950  if (this->order == INVALID_VEH_ORDER_ID) {
951  bool delete_window = this->selected_vehicle == v->index && this->num_vehicles == UINT8_MAX;
952  if (DoCommandP(v->tile, this->selected_vehicle, this->cargo->cargo | this->cargo->subtype << 8 | this->num_vehicles << 16, GetCmdRefitVeh(v)) && delete_window) delete this;
953  } else {
954  if (DoCommandP(v->tile, v->index, this->cargo->cargo | this->order << 16, CMD_ORDER_REFIT)) delete this;
955  }
956  }
957  break;
958  }
959  }
960 
961  virtual void OnMouseDrag(Point pt, int widget)
962  {
963  switch (widget) {
964  case WID_VR_VEHICLE_PANEL_DISPLAY: { // Vehicle image.
965  if (this->order != INVALID_VEH_ORDER_ID) break;
966  NWidgetBase *nwi = this->GetWidget<NWidgetBase>(WID_VR_VEHICLE_PANEL_DISPLAY);
967  this->SetSelectedVehicles(pt.x - nwi->pos_x);
969  break;
970  }
971  }
972  }
973 
974  virtual void OnDragDrop(Point pt, int widget)
975  {
976  switch (widget) {
977  case WID_VR_VEHICLE_PANEL_DISPLAY: { // Vehicle image.
978  if (this->order != INVALID_VEH_ORDER_ID) break;
979  NWidgetBase *nwi = this->GetWidget<NWidgetBase>(WID_VR_VEHICLE_PANEL_DISPLAY);
980  this->SetSelectedVehicles(pt.x - nwi->pos_x);
981  this->InvalidateData(2);
982  break;
983  }
984  }
985  }
986 
987  virtual void OnResize()
988  {
989  this->vehicle_width = GetVehicleWidth(Vehicle::Get(this->window_number), EIT_IN_DETAILS);
990  this->vscroll->SetCapacityFromWidget(this, WID_VR_MATRIX);
991  if (this->hscroll != NULL) this->hscroll->SetCapacityFromWidget(this, WID_VR_VEHICLE_PANEL_DISPLAY);
992  }
993 };
994 
995 static const NWidgetPart _nested_vehicle_refit_widgets[] = {
997  NWidget(WWT_CLOSEBOX, COLOUR_GREY),
998  NWidget(WWT_CAPTION, COLOUR_GREY, WID_VR_CAPTION), SetDataTip(STR_REFIT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
999  NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
1000  EndContainer(),
1001  /* Vehicle display + scrollbar. */
1004  NWidget(NWID_SELECTION, INVALID_COLOUR, WID_VR_SHOW_HSCROLLBAR),
1005  NWidget(NWID_HSCROLLBAR, COLOUR_GREY, WID_VR_HSCROLLBAR),
1006  EndContainer(),
1007  EndContainer(),
1008  NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_VR_SELECT_HEADER), SetDataTip(STR_REFIT_TITLE, STR_NULL), SetResize(1, 0),
1009  /* Matrix + scrollbar. */
1011  NWidget(WWT_MATRIX, COLOUR_GREY, WID_VR_MATRIX), SetMinimalSize(228, 112), SetResize(1, 14), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_NULL), SetScrollbar(WID_VR_SCROLLBAR),
1012  NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_VR_SCROLLBAR),
1013  EndContainer(),
1016  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VR_REFIT), SetFill(1, 0), SetResize(1, 0),
1017  NWidget(WWT_RESIZEBOX, COLOUR_GREY),
1018  EndContainer(),
1019 };
1020 
1021 static WindowDesc _vehicle_refit_desc(
1022  WDP_AUTO, "view_vehicle_refit", 240, 174,
1025  _nested_vehicle_refit_widgets, lengthof(_nested_vehicle_refit_widgets)
1026 );
1027 
1035 void ShowVehicleRefitWindow(const Vehicle *v, VehicleOrderID order, Window *parent, bool auto_refit)
1036 {
1038  RefitWindow *w = new RefitWindow(&_vehicle_refit_desc, v, order, auto_refit);
1039  w->parent = parent;
1040 }
1041 
1043 uint ShowRefitOptionsList(int left, int right, int y, EngineID engine)
1044 {
1045  /* List of cargo types of this engine */
1046  uint32 cmask = GetUnionOfArticulatedRefitMasks(engine, false);
1047  /* List of cargo types available in this climate */
1048  uint32 lmask = _cargo_mask;
1049 
1050  /* Draw nothing if the engine is not refittable */
1051  if (HasAtMostOneBit(cmask)) return y;
1052 
1053  if (cmask == lmask) {
1054  /* Engine can be refitted to all types in this climate */
1055  SetDParam(0, STR_PURCHASE_INFO_ALL_TYPES);
1056  } else {
1057  /* Check if we are able to refit to more cargo types and unable to. If
1058  * so, invert the cargo types to list those that we can't refit to. */
1059  if (CountBits(cmask ^ lmask) < CountBits(cmask) && CountBits(cmask ^ lmask) <= 7) {
1060  cmask ^= lmask;
1061  SetDParam(0, STR_PURCHASE_INFO_ALL_BUT);
1062  } else {
1063  SetDParam(0, STR_JUST_CARGO_LIST);
1064  }
1065  SetDParam(1, cmask);
1066  }
1067 
1068  return DrawStringMultiLine(left, right, y, INT32_MAX, STR_PURCHASE_INFO_REFITTABLE_TO);
1069 }
1070 
1073 {
1074  if (HasBit(EngInfo(v->engine_type)->callback_mask, CBM_VEHICLE_CARGO_SUFFIX)) {
1075  uint16 cb = GetVehicleCallback(CBID_VEHICLE_CARGO_SUFFIX, 0, 0, v->engine_type, v);
1076  if (cb != CALLBACK_FAILED) {
1078  if (cb >= 0x400 || (v->GetGRF()->grf_version < 8 && cb == 0xFF)) cb = CALLBACK_FAILED;
1079  }
1080  if (cb != CALLBACK_FAILED) {
1081  return GetGRFStringID(v->GetGRFID(), 0xD000 + cb);
1082  }
1083  }
1084  return STR_EMPTY;
1085 }
1086 
1088 static int CDECL VehicleNumberSorter(const Vehicle * const *a, const Vehicle * const *b)
1089 {
1090  return (*a)->unitnumber - (*b)->unitnumber;
1091 }
1092 
1094 static int CDECL VehicleNameSorter(const Vehicle * const *a, const Vehicle * const *b)
1095 {
1096  static char last_name[2][64];
1097 
1098  if (*a != _last_vehicle[0]) {
1099  _last_vehicle[0] = *a;
1100  SetDParam(0, (*a)->index);
1101  GetString(last_name[0], STR_VEHICLE_NAME, lastof(last_name[0]));
1102  }
1103 
1104  if (*b != _last_vehicle[1]) {
1105  _last_vehicle[1] = *b;
1106  SetDParam(0, (*b)->index);
1107  GetString(last_name[1], STR_VEHICLE_NAME, lastof(last_name[1]));
1108  }
1109 
1110  int r = strnatcmp(last_name[0], last_name[1]); // Sort by name (natural sorting).
1111  return (r != 0) ? r : VehicleNumberSorter(a, b);
1112 }
1113 
1115 static int CDECL VehicleAgeSorter(const Vehicle * const *a, const Vehicle * const *b)
1116 {
1117  int r = (*a)->age - (*b)->age;
1118  return (r != 0) ? r : VehicleNumberSorter(a, b);
1119 }
1120 
1122 static int CDECL VehicleProfitThisYearSorter(const Vehicle * const *a, const Vehicle * const *b)
1123 {
1124  int r = ClampToI32((*a)->GetDisplayProfitThisYear() - (*b)->GetDisplayProfitThisYear());
1125  return (r != 0) ? r : VehicleNumberSorter(a, b);
1126 }
1127 
1129 static int CDECL VehicleProfitLastYearSorter(const Vehicle * const *a, const Vehicle * const *b)
1130 {
1131  int r = ClampToI32((*a)->GetDisplayProfitLastYear() - (*b)->GetDisplayProfitLastYear());
1132  return (r != 0) ? r : VehicleNumberSorter(a, b);
1133 }
1134 
1136 static int CDECL VehicleCargoSorter(const Vehicle * const *a, const Vehicle * const *b)
1137 {
1138  const Vehicle *v;
1139  CargoArray diff;
1140 
1141  /* Append the cargo of the connected waggons */
1142  for (v = *a; v != NULL; v = v->Next()) diff[v->cargo_type] += v->cargo_cap;
1143  for (v = *b; v != NULL; v = v->Next()) diff[v->cargo_type] -= v->cargo_cap;
1144 
1145  int r = 0;
1146  for (CargoID i = 0; i < NUM_CARGO; i++) {
1147  r = diff[i];
1148  if (r != 0) break;
1149  }
1150 
1151  return (r != 0) ? r : VehicleNumberSorter(a, b);
1152 }
1153 
1155 static int CDECL VehicleReliabilitySorter(const Vehicle * const *a, const Vehicle * const *b)
1156 {
1157  int r = (*a)->reliability - (*b)->reliability;
1158  return (r != 0) ? r : VehicleNumberSorter(a, b);
1159 }
1160 
1162 static int CDECL VehicleMaxSpeedSorter(const Vehicle * const *a, const Vehicle * const *b)
1163 {
1164  int r = (*a)->vcache.cached_max_speed - (*b)->vcache.cached_max_speed;
1165  return (r != 0) ? r : VehicleNumberSorter(a, b);
1166 }
1167 
1169 static int CDECL VehicleModelSorter(const Vehicle * const *a, const Vehicle * const *b)
1170 {
1171  int r = (*a)->engine_type - (*b)->engine_type;
1172  return (r != 0) ? r : VehicleNumberSorter(a, b);
1173 }
1174 
1176 static int CDECL VehicleValueSorter(const Vehicle * const *a, const Vehicle * const *b)
1177 {
1178  const Vehicle *u;
1179  Money diff = 0;
1180 
1181  for (u = *a; u != NULL; u = u->Next()) diff += u->value;
1182  for (u = *b; u != NULL; u = u->Next()) diff -= u->value;
1183 
1184  int r = ClampToI32(diff);
1185  return (r != 0) ? r : VehicleNumberSorter(a, b);
1186 }
1187 
1189 static int CDECL VehicleLengthSorter(const Vehicle * const *a, const Vehicle * const *b)
1190 {
1191  int r = (*a)->GetGroundVehicleCache()->cached_total_length - (*b)->GetGroundVehicleCache()->cached_total_length;
1192  return (r != 0) ? r : VehicleNumberSorter(a, b);
1193 }
1194 
1196 static int CDECL VehicleTimeToLiveSorter(const Vehicle * const *a, const Vehicle * const *b)
1197 {
1198  int r = ClampToI32(((*a)->max_age - (*a)->age) - ((*b)->max_age - (*b)->age));
1199  return (r != 0) ? r : VehicleNumberSorter(a, b);
1200 }
1201 
1203 static int CDECL VehicleTimetableDelaySorter(const Vehicle * const *a, const Vehicle * const *b)
1204 {
1205  int r = (*a)->lateness_counter - (*b)->lateness_counter;
1206  return (r != 0) ? r : VehicleNumberSorter(a, b);
1207 }
1208 
1209 void InitializeGUI()
1210 {
1211  MemSetT(&_sorting, 0);
1212 }
1213 
1220 static inline void ChangeVehicleWindow(WindowClass window_class, VehicleID from_index, VehicleID to_index)
1221 {
1222  Window *w = FindWindowById(window_class, from_index);
1223  if (w != NULL) {
1224  /* Update window_number */
1225  w->window_number = to_index;
1226  if (w->viewport != NULL) w->viewport->follow_vehicle = to_index;
1227 
1228  /* Update vehicle drag data */
1229  if (_thd.window_class == window_class && _thd.window_number == (WindowNumber)from_index) {
1230  _thd.window_number = to_index;
1231  }
1232 
1233  /* Notify the window. */
1234  w->InvalidateData(VIWD_AUTOREPLACE, false);
1235  }
1236 }
1237 
1243 void ChangeVehicleViewWindow(VehicleID from_index, VehicleID to_index)
1244 {
1245  ChangeVehicleWindow(WC_VEHICLE_VIEW, from_index, to_index);
1246  ChangeVehicleWindow(WC_VEHICLE_ORDERS, from_index, to_index);
1247  ChangeVehicleWindow(WC_VEHICLE_REFIT, from_index, to_index);
1248  ChangeVehicleWindow(WC_VEHICLE_DETAILS, from_index, to_index);
1249  ChangeVehicleWindow(WC_VEHICLE_TIMETABLE, from_index, to_index);
1250 }
1251 
1252 static const NWidgetPart _nested_vehicle_list[] = {
1254  NWidget(WWT_CLOSEBOX, COLOUR_GREY),
1255  NWidget(WWT_CAPTION, COLOUR_GREY, WID_VL_CAPTION),
1256  NWidget(WWT_SHADEBOX, COLOUR_GREY),
1257  NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
1258  NWidget(WWT_STICKYBOX, COLOUR_GREY),
1259  EndContainer(),
1260 
1262  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VL_SORT_ORDER), SetMinimalSize(81, 12), SetFill(0, 1), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
1263  NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_VL_SORT_BY_PULLDOWN), SetMinimalSize(167, 12), SetFill(0, 1), SetDataTip(0x0, STR_TOOLTIP_SORT_CRITERIA),
1264  NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(12, 12), SetFill(1, 1), SetResize(1, 0),
1265  EndContainer(),
1266  EndContainer(),
1267 
1269  NWidget(WWT_MATRIX, COLOUR_GREY, WID_VL_LIST), SetMinimalSize(248, 0), SetFill(1, 0), SetResize(1, 1), SetMatrixDataTip(1, 0, STR_NULL), SetScrollbar(WID_VL_SCROLLBAR),
1270  NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_VL_SCROLLBAR),
1271  EndContainer(),
1272 
1274  NWidget(NWID_SELECTION, INVALID_COLOUR, WID_VL_HIDE_BUTTONS),
1276  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VL_AVAILABLE_VEHICLES), SetMinimalSize(106, 12), SetFill(0, 1),
1277  SetDataTip(STR_BLACK_STRING, STR_VEHICLE_LIST_AVAILABLE_ENGINES_TOOLTIP),
1278  NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(0, 12), SetResize(1, 0), SetFill(1, 1), EndContainer(),
1280  SetDataTip(STR_VEHICLE_LIST_MANAGE_LIST, STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP),
1281  NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VL_STOP_ALL), SetMinimalSize(12, 12), SetFill(0, 1),
1282  SetDataTip(SPR_FLAG_VEH_STOPPED, STR_VEHICLE_LIST_MASS_STOP_LIST_TOOLTIP),
1283  NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VL_START_ALL), SetMinimalSize(12, 12), SetFill(0, 1),
1284  SetDataTip(SPR_FLAG_VEH_RUNNING, STR_VEHICLE_LIST_MASS_START_LIST_TOOLTIP),
1285  EndContainer(),
1286  /* Widget to be shown for other companies hiding the previous 5 widgets. */
1287  NWidget(WWT_PANEL, COLOUR_GREY), SetFill(1, 1), SetResize(1, 0), EndContainer(),
1288  EndContainer(),
1289  NWidget(WWT_RESIZEBOX, COLOUR_GREY),
1290  EndContainer(),
1291 };
1292 
1293 static void DrawSmallOrderList(const Vehicle *v, int left, int right, int y, VehicleOrderID start = 0)
1294 {
1295  const Order *order = v->GetOrder(start);
1296  if (order == NULL) return;
1297 
1298  bool rtl = _current_text_dir == TD_RTL;
1299  int l_offset = rtl ? 0 : ScaleGUITrad(6);
1300  int r_offset = rtl ? ScaleGUITrad(6) : 0;
1301  int i = 0;
1302  VehicleOrderID oid = start;
1303 
1304  do {
1305  if (oid == v->cur_real_order_index) DrawString(left, right, y, STR_TINY_RIGHT_ARROW, TC_BLACK);
1306 
1307  if (order->IsType(OT_GOTO_STATION)) {
1308  SetDParam(0, order->GetDestination());
1309  DrawString(left + l_offset, right - r_offset, y, STR_TINY_BLACK_STATION);
1310 
1311  y += FONT_HEIGHT_SMALL;
1312  if (++i == 4) break;
1313  }
1314 
1315  oid++;
1316  order = order->next;
1317  if (order == NULL) {
1318  order = v->orders.list->GetFirstOrder();
1319  oid = 0;
1320  }
1321  } while (oid != start);
1322 }
1323 
1333 void DrawVehicleImage(const Vehicle *v, int left, int right, int y, VehicleID selection, EngineImageType image_type, int skip)
1334 {
1335  switch (v->type) {
1336  case VEH_TRAIN: DrawTrainImage(Train::From(v), left, right, y, selection, image_type, skip); break;
1337  case VEH_ROAD: DrawRoadVehImage(v, left, right, y, selection, image_type, skip); break;
1338  case VEH_SHIP: DrawShipImage(v, left, right, y, selection, image_type); break;
1339  case VEH_AIRCRAFT: DrawAircraftImage(v, left, right, y, selection, image_type); break;
1340  default: NOT_REACHED();
1341  }
1342 }
1343 
1350 uint GetVehicleListHeight(VehicleType type, uint divisor)
1351 {
1352  /* Name + vehicle + profit */
1353  uint base = ScaleGUITrad(GetVehicleHeight(type)) + 2 * FONT_HEIGHT_SMALL;
1354  /* Drawing of the 4 small orders + profit*/
1355  if (type >= VEH_SHIP) base = max(base, 5U * FONT_HEIGHT_SMALL);
1356 
1357  if (divisor == 1) return base;
1358 
1359  /* Make sure the height is dividable by divisor */
1360  uint rem = base % divisor;
1361  return base + (rem == 0 ? 0 : divisor - rem);
1362 }
1363 
1370 void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int line_height, const Rect &r) const
1371 {
1372  int left = r.left + WD_MATRIX_LEFT;
1373  int right = r.right - WD_MATRIX_RIGHT;
1374  int width = right - left;
1375  bool rtl = _current_text_dir == TD_RTL;
1376 
1377  int text_offset = max<int>(GetSpriteSize(SPR_PROFIT_LOT).width, GetDigitWidth() * this->unitnumber_digits) + WD_FRAMERECT_RIGHT;
1378  int text_left = left + (rtl ? 0 : text_offset);
1379  int text_right = right - (rtl ? text_offset : 0);
1380 
1381  bool show_orderlist = this->vli.vtype >= VEH_SHIP;
1382  int orderlist_left = left + (rtl ? 0 : max(ScaleGUITrad(100) + text_offset, width / 2));
1383  int orderlist_right = right - (rtl ? max(ScaleGUITrad(100) + text_offset, width / 2) : 0);
1384 
1385  int image_left = (rtl && show_orderlist) ? orderlist_right : text_left;
1386  int image_right = (!rtl && show_orderlist) ? orderlist_left : text_right;
1387 
1388  int vehicle_button_x = rtl ? right - GetSpriteSize(SPR_PROFIT_LOT).width : left;
1389 
1390  int y = r.top;
1391  uint max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->vehicles.Length());
1392  for (uint i = this->vscroll->GetPosition(); i < max; ++i) {
1393  const Vehicle *v = this->vehicles[i];
1394  StringID str;
1395 
1398 
1399  DrawVehicleImage(v, image_left, image_right, y + FONT_HEIGHT_SMALL - 1, selected_vehicle, EIT_IN_LIST, 0);
1400  DrawString(text_left, text_right, y + line_height - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM - 1, STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR);
1401 
1402  if (v->name != NULL) {
1403  /* The vehicle got a name so we will print it */
1404  SetDParam(0, v->index);
1405  DrawString(text_left, text_right, y, STR_TINY_BLACK_VEHICLE);
1406  } else if (v->group_id != DEFAULT_GROUP) {
1407  /* The vehicle has no name, but is member of a group, so print group name */
1408  SetDParam(0, v->group_id);
1409  DrawString(text_left, text_right, y, STR_TINY_GROUP, TC_BLACK);
1410  }
1411 
1412  if (show_orderlist) DrawSmallOrderList(v, orderlist_left, orderlist_right, y, v->cur_real_order_index);
1413 
1414  if (v->IsChainInDepot()) {
1415  str = STR_BLUE_COMMA;
1416  } else {
1417  str = (v->age > v->max_age - DAYS_IN_LEAP_YEAR) ? STR_RED_COMMA : STR_BLACK_COMMA;
1418  }
1419 
1420  SetDParam(0, v->unitnumber);
1421  DrawString(left, right, y + 2, str);
1422 
1423  DrawVehicleProfitButton(v, vehicle_button_x, y + FONT_HEIGHT_NORMAL + 3);
1424 
1425  y += line_height;
1426  }
1427 }
1428 
1439 private:
1444  };
1445 
1446 public:
1448  {
1449  /* Set up sorting. Make the window-specific _sorting variable
1450  * point to the correct global _sorting struct so we are freed
1451  * from having conditionals during window operation */
1452  switch (this->vli.vtype) {
1453  case VEH_TRAIN: this->sorting = &_sorting.train; break;
1454  case VEH_ROAD: this->sorting = &_sorting.roadveh; break;
1455  case VEH_SHIP: this->sorting = &_sorting.ship; break;
1456  case VEH_AIRCRAFT: this->sorting = &_sorting.aircraft; break;
1457  default: NOT_REACHED();
1458  }
1459 
1460  this->CreateNestedTree();
1461 
1462  this->vscroll = this->GetScrollbar(WID_VL_SCROLLBAR);
1463 
1464  this->vehicles.SetListing(*this->sorting);
1465  this->vehicles.ForceRebuild();
1466  this->vehicles.NeedResort();
1467  this->BuildVehicleList();
1468  this->SortVehicleList();
1469 
1470  /* Set up the window widgets */
1471  this->GetWidget<NWidgetCore>(WID_VL_LIST)->tool_tip = STR_VEHICLE_LIST_TRAIN_LIST_TOOLTIP + this->vli.vtype;
1472 
1473  if (this->vli.type == VL_SHARED_ORDERS) {
1474  this->GetWidget<NWidgetCore>(WID_VL_CAPTION)->widget_data = STR_VEHICLE_LIST_SHARED_ORDERS_LIST_CAPTION;
1475  } else {
1476  this->GetWidget<NWidgetCore>(WID_VL_CAPTION)->widget_data = STR_VEHICLE_LIST_TRAIN_CAPTION + this->vli.vtype;
1477  }
1478 
1479  this->FinishInitNested(window_number);
1480  if (this->vli.company != OWNER_NONE) this->owner = this->vli.company;
1481  }
1482 
1484  {
1485  *this->sorting = this->vehicles.GetListing();
1486  }
1487 
1488  virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
1489  {
1490  switch (widget) {
1491  case WID_VL_LIST:
1492  resize->height = GetVehicleListHeight(this->vli.vtype, 1);
1493 
1494  switch (this->vli.vtype) {
1495  case VEH_TRAIN:
1496  case VEH_ROAD:
1497  size->height = 6 * resize->height;
1498  break;
1499  case VEH_SHIP:
1500  case VEH_AIRCRAFT:
1501  size->height = 4 * resize->height;
1502  break;
1503  default: NOT_REACHED();
1504  }
1505  break;
1506 
1507  case WID_VL_SORT_ORDER: {
1508  Dimension d = GetStringBoundingBox(this->GetWidget<NWidgetCore>(widget)->widget_data);
1509  d.width += padding.width + Window::SortButtonWidth() * 2; // Doubled since the string is centred and it also looks better.
1510  d.height += padding.height;
1511  *size = maxdim(*size, d);
1512  break;
1513  }
1514 
1516  Dimension d = this->GetActionDropdownSize(this->vli.type == VL_STANDARD, false);
1517  d.height += padding.height;
1518  d.width += padding.width;
1519  *size = maxdim(*size, d);
1520  break;
1521  }
1522  }
1523  }
1524 
1525  virtual void SetStringParameters(int widget) const
1526  {
1527  switch (widget) {
1529  SetDParam(0, STR_VEHICLE_LIST_AVAILABLE_TRAINS + this->vli.vtype);
1530  break;
1531 
1532  case WID_VL_CAPTION: {
1533  switch (this->vli.type) {
1534  case VL_SHARED_ORDERS: // Shared Orders
1535  if (this->vehicles.Length() == 0) {
1536  /* We can't open this window without vehicles using this order
1537  * and we should close the window when deleting the order. */
1538  NOT_REACHED();
1539  }
1540  SetDParam(0, this->vscroll->GetCount());
1541  break;
1542 
1543  case VL_STANDARD: // Company Name
1544  SetDParam(0, STR_COMPANY_NAME);
1545  SetDParam(1, this->vli.index);
1546  SetDParam(3, this->vscroll->GetCount());
1547  break;
1548 
1549  case VL_STATION_LIST: // Station/Waypoint Name
1550  SetDParam(0, Station::IsExpected(BaseStation::Get(this->vli.index)) ? STR_STATION_NAME : STR_WAYPOINT_NAME);
1551  SetDParam(1, this->vli.index);
1552  SetDParam(3, this->vscroll->GetCount());
1553  break;
1554 
1555  case VL_DEPOT_LIST:
1556  SetDParam(0, STR_DEPOT_CAPTION);
1557  SetDParam(1, this->vli.vtype);
1558  SetDParam(2, this->vli.index);
1559  SetDParam(3, this->vscroll->GetCount());
1560  break;
1561  default: NOT_REACHED();
1562  }
1563  break;
1564  }
1565  }
1566  }
1567 
1568  virtual void DrawWidget(const Rect &r, int widget) const
1569  {
1570  switch (widget) {
1571  case WID_VL_SORT_ORDER:
1572  /* draw arrow pointing up/down for ascending/descending sorting */
1573  this->DrawSortButtonState(widget, this->vehicles.IsDescSortOrder() ? SBS_DOWN : SBS_UP);
1574  break;
1575 
1576  case WID_VL_LIST:
1578  break;
1579  }
1580  }
1581 
1582  virtual void OnPaint()
1583  {
1584  this->BuildVehicleList();
1585  this->SortVehicleList();
1586 
1587  if (this->vehicles.Length() == 0 && this->IsWidgetLowered(WID_VL_MANAGE_VEHICLES_DROPDOWN)) {
1588  HideDropDownMenu(this);
1589  }
1590 
1591  /* Hide the widgets that we will not use in this window
1592  * Some windows contains actions only fit for the owner */
1593  int plane_to_show = (this->owner == _local_company) ? BP_SHOW_BUTTONS : BP_HIDE_BUTTONS;
1594  NWidgetStacked *nwi = this->GetWidget<NWidgetStacked>(WID_VL_HIDE_BUTTONS);
1595  if (plane_to_show != nwi->shown_plane) {
1596  nwi->SetDisplayedPlane(plane_to_show);
1597  nwi->SetDirty(this);
1598  }
1599  if (this->owner == _local_company) {
1600  this->SetWidgetDisabledState(WID_VL_AVAILABLE_VEHICLES, this->vli.type != VL_STANDARD);
1601  this->SetWidgetsDisabledState(this->vehicles.Length() == 0,
1605  WIDGET_LIST_END);
1606  }
1607 
1608  /* Set text of sort by dropdown widget. */
1609  this->GetWidget<NWidgetCore>(WID_VL_SORT_BY_PULLDOWN)->widget_data = this->vehicle_sorter_names[this->vehicles.SortType()];
1610 
1611  this->DrawWidgets();
1612  }
1613 
1614  virtual void OnClick(Point pt, int widget, int click_count)
1615  {
1616  switch (widget) {
1617  case WID_VL_SORT_ORDER: // Flip sorting method ascending/descending
1618  this->vehicles.ToggleSortOrder();
1619  this->SetDirty();
1620  break;
1621 
1622  case WID_VL_SORT_BY_PULLDOWN:// Select sorting criteria dropdown menu
1623  ShowDropDownMenu(this, this->vehicle_sorter_names, this->vehicles.SortType(), WID_VL_SORT_BY_PULLDOWN, 0,
1624  (this->vli.vtype == VEH_TRAIN || this->vli.vtype == VEH_ROAD) ? 0 : (1 << 10));
1625  return;
1626 
1627  case WID_VL_LIST: { // Matrix to show vehicles
1628  uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_VL_LIST);
1629  if (id_v >= this->vehicles.Length()) return; // click out of list bound
1630 
1631  const Vehicle *v = this->vehicles[id_v];
1633  break;
1634  }
1635 
1637  ShowBuildVehicleWindow(INVALID_TILE, this->vli.vtype);
1638  break;
1639 
1641  DropDownList *list = this->BuildActionDropdownList(VehicleListIdentifier::UnPack(this->window_number).type == VL_STANDARD, false);
1643  break;
1644  }
1645 
1646  case WID_VL_STOP_ALL:
1647  case WID_VL_START_ALL:
1648  DoCommandP(0, (1 << 1) | (widget == WID_VL_START_ALL ? (1 << 0) : 0), this->window_number, CMD_MASS_START_STOP);
1649  break;
1650  }
1651  }
1652 
1653  virtual void OnDropdownSelect(int widget, int index)
1654  {
1655  switch (widget) {
1657  this->vehicles.SetSortType(index);
1658  break;
1660  assert(this->vehicles.Length() != 0);
1661 
1662  switch (index) {
1663  case ADI_REPLACE: // Replace window
1665  break;
1666  case ADI_SERVICE: // Send for servicing
1667  case ADI_DEPOT: // Send to Depots
1668  DoCommandP(0, DEPOT_MASS_SEND | (index == ADI_SERVICE ? DEPOT_SERVICE : (DepotCommand)0), this->window_number, GetCmdSendToDepot(this->vli.vtype));
1669  break;
1670 
1671  default: NOT_REACHED();
1672  }
1673  break;
1674  default: NOT_REACHED();
1675  }
1676  this->SetDirty();
1677  }
1678 
1679  virtual void OnTick()
1680  {
1681  if (_pause_mode != PM_UNPAUSED) return;
1682  if (this->vehicles.NeedResort()) {
1683  StationID station = (this->vli.type == VL_STATION_LIST) ? this->vli.index : INVALID_STATION;
1684 
1685  DEBUG(misc, 3, "Periodic resort %d list company %d at station %d", this->vli.vtype, this->owner, station);
1686  this->SetDirty();
1687  }
1688  }
1689 
1690  virtual void OnResize()
1691  {
1692  this->vscroll->SetCapacityFromWidget(this, WID_VL_LIST);
1693  }
1694 
1700  virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
1701  {
1702  if (!gui_scope && HasBit(data, 31) && this->vli.type == VL_SHARED_ORDERS) {
1703  /* Needs to be done in command-scope, so everything stays valid */
1704  this->vli.index = GB(data, 0, 20);
1705  this->window_number = this->vli.Pack();
1706  this->vehicles.ForceRebuild();
1707  return;
1708  }
1709 
1710  if (data == 0) {
1711  /* This needs to be done in command-scope to enforce rebuilding before resorting invalid data */
1712  this->vehicles.ForceRebuild();
1713  } else {
1714  this->vehicles.ForceResort();
1715  }
1716  }
1717 };
1718 
1719 static WindowDesc _vehicle_list_other_desc(
1720  WDP_AUTO, "list_vehicles", 260, 246,
1722  0,
1723  _nested_vehicle_list, lengthof(_nested_vehicle_list)
1724 );
1725 
1726 static WindowDesc _vehicle_list_train_desc(
1727  WDP_AUTO, "list_vehicles_train", 325, 246,
1729  0,
1730  _nested_vehicle_list, lengthof(_nested_vehicle_list)
1731 );
1732 
1733 static void ShowVehicleListWindowLocal(CompanyID company, VehicleListType vlt, VehicleType vehicle_type, uint32 unique_number)
1734 {
1735  if (!Company::IsValidID(company) && company != OWNER_NONE) return;
1736 
1737  WindowNumber num = VehicleListIdentifier(vlt, vehicle_type, company, unique_number).Pack();
1738  if (vehicle_type == VEH_TRAIN) {
1739  AllocateWindowDescFront<VehicleListWindow>(&_vehicle_list_train_desc, num);
1740  } else {
1741  _vehicle_list_other_desc.cls = GetWindowClassForVehicleType(vehicle_type);
1742  AllocateWindowDescFront<VehicleListWindow>(&_vehicle_list_other_desc, num);
1743  }
1744 }
1745 
1746 void ShowVehicleListWindow(CompanyID company, VehicleType vehicle_type)
1747 {
1748  /* If _settings_client.gui.advanced_vehicle_list > 1, display the Advanced list
1749  * if _settings_client.gui.advanced_vehicle_list == 1, display Advanced list only for local company
1750  * if _ctrl_pressed, do the opposite action (Advanced list x Normal list)
1751  */
1752 
1753  if ((_settings_client.gui.advanced_vehicle_list > (uint)(company != _local_company)) != _ctrl_pressed) {
1754  ShowCompanyGroup(company, vehicle_type);
1755  } else {
1756  ShowVehicleListWindowLocal(company, VL_STANDARD, vehicle_type, company);
1757  }
1758 }
1759 
1760 void ShowVehicleListWindow(const Vehicle *v)
1761 {
1762  ShowVehicleListWindowLocal(v->owner, VL_SHARED_ORDERS, v->type, v->FirstShared()->index);
1763 }
1764 
1765 void ShowVehicleListWindow(CompanyID company, VehicleType vehicle_type, StationID station)
1766 {
1767  ShowVehicleListWindowLocal(company, VL_STATION_LIST, vehicle_type, station);
1768 }
1769 
1770 void ShowVehicleListWindow(CompanyID company, VehicleType vehicle_type, TileIndex depot_tile)
1771 {
1772  uint16 depot_airport_index;
1773 
1774  if (vehicle_type == VEH_AIRCRAFT) {
1775  depot_airport_index = GetStationIndex(depot_tile);
1776  } else {
1777  depot_airport_index = GetDepotIndex(depot_tile);
1778  }
1779  ShowVehicleListWindowLocal(company, VL_DEPOT_LIST, vehicle_type, depot_airport_index);
1780 }
1781 
1782 
1783 /* Unified vehicle GUI - Vehicle Details Window */
1784 
1789 
1793  NWidget(WWT_CLOSEBOX, COLOUR_GREY),
1794  NWidget(WWT_CAPTION, COLOUR_GREY, WID_VD_CAPTION), SetDataTip(STR_VEHICLE_DETAILS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1795  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VD_RENAME_VEHICLE), SetMinimalSize(40, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_VEHICLE_NAME_BUTTON, STR_NULL /* filled in later */),
1796  NWidget(WWT_SHADEBOX, COLOUR_GREY),
1797  NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
1798  NWidget(WWT_STICKYBOX, COLOUR_GREY),
1799  EndContainer(),
1800  NWidget(WWT_PANEL, COLOUR_GREY, WID_VD_TOP_DETAILS), SetMinimalSize(405, 42), SetResize(1, 0), EndContainer(),
1801  NWidget(WWT_PANEL, COLOUR_GREY, WID_VD_MIDDLE_DETAILS), SetMinimalSize(405, 45), SetResize(1, 0), EndContainer(),
1804  SetDataTip(AWV_DECREASE, STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP),
1806  SetDataTip(AWV_INCREASE, STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP),
1808  SetDataTip(STR_EMPTY, STR_SERVICE_INTERVAL_DROPDOWN_TOOLTIP),
1809  NWidget(WWT_PANEL, COLOUR_GREY, WID_VD_SERVICING_INTERVAL), SetFill(1, 1), SetResize(1, 0), EndContainer(),
1810  NWidget(WWT_RESIZEBOX, COLOUR_GREY),
1811  EndContainer(),
1812 };
1813 
1817  NWidget(WWT_CLOSEBOX, COLOUR_GREY),
1818  NWidget(WWT_CAPTION, COLOUR_GREY, WID_VD_CAPTION), SetDataTip(STR_VEHICLE_DETAILS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1819  NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_VD_RENAME_VEHICLE), SetMinimalSize(40, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_VEHICLE_NAME_BUTTON, STR_NULL /* filled in later */),
1820  NWidget(WWT_SHADEBOX, COLOUR_GREY),
1821  NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
1822  NWidget(WWT_STICKYBOX, COLOUR_GREY),
1823  EndContainer(),
1824  NWidget(WWT_PANEL, COLOUR_GREY, WID_VD_TOP_DETAILS), SetResize(1, 0), SetMinimalSize(405, 42), EndContainer(),
1826  NWidget(WWT_MATRIX, COLOUR_GREY, WID_VD_MATRIX), SetResize(1, 1), SetMinimalSize(393, 45), SetMatrixDataTip(1, 0, STR_NULL), SetFill(1, 0), SetScrollbar(WID_VD_SCROLLBAR),
1827  NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_VD_SCROLLBAR),
1828  EndContainer(),
1831  SetDataTip(AWV_DECREASE, STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP),
1833  SetDataTip(AWV_INCREASE, STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP),
1835  SetDataTip(STR_EMPTY, STR_SERVICE_INTERVAL_DROPDOWN_TOOLTIP),
1836  NWidget(WWT_PANEL, COLOUR_GREY, WID_VD_SERVICING_INTERVAL), SetFill(1, 1), SetResize(1, 0), EndContainer(),
1837  EndContainer(),
1840  SetDataTip(STR_VEHICLE_DETAIL_TAB_CARGO, STR_VEHICLE_DETAILS_TRAIN_CARGO_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
1842  SetDataTip(STR_VEHICLE_DETAIL_TAB_INFORMATION, STR_VEHICLE_DETAILS_TRAIN_INFORMATION_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
1844  SetDataTip(STR_VEHICLE_DETAIL_TAB_CAPACITIES, STR_VEHICLE_DETAILS_TRAIN_CAPACITIES_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
1846  SetDataTip(STR_VEHICLE_DETAIL_TAB_TOTAL_CARGO, STR_VEHICLE_DETAILS_TRAIN_TOTAL_CARGO_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
1847  NWidget(WWT_RESIZEBOX, COLOUR_GREY),
1848  EndContainer(),
1849 };
1850 
1851 
1852 extern int GetTrainDetailsWndVScroll(VehicleID veh_id, TrainDetailsWindowTabs det_tab);
1853 extern void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_pos, uint16 vscroll_cap, TrainDetailsWindowTabs det_tab);
1854 extern void DrawRoadVehDetails(const Vehicle *v, int left, int right, int y);
1855 extern void DrawShipDetails(const Vehicle *v, int left, int right, int y);
1856 extern void DrawAircraftDetails(const Aircraft *v, int left, int right, int y);
1857 
1858 static StringID _service_interval_dropdown[] = {
1859  STR_VEHICLE_DETAILS_DEFAULT,
1860  STR_VEHICLE_DETAILS_DAYS,
1861  STR_VEHICLE_DETAILS_PERCENT,
1863 };
1864 
1868  Scrollbar *vscroll;
1869 
1872  {
1873  const Vehicle *v = Vehicle::Get(window_number);
1874 
1875  this->CreateNestedTree();
1876  this->vscroll = (v->type == VEH_TRAIN ? this->GetScrollbar(WID_VD_SCROLLBAR) : NULL);
1877  this->FinishInitNested(window_number);
1878 
1879  this->GetWidget<NWidgetCore>(WID_VD_RENAME_VEHICLE)->tool_tip = STR_VEHICLE_DETAILS_TRAIN_RENAME + v->type;
1880 
1881  this->owner = v->owner;
1882  this->tab = TDW_TAB_CARGO;
1883  }
1884 
1890  virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
1891  {
1892  if (data == VIWD_AUTOREPLACE) {
1893  /* Autoreplace replaced the vehicle.
1894  * Nothing to do for this window. */
1895  return;
1896  }
1897  if (!gui_scope) return;
1898  const Vehicle *v = Vehicle::Get(this->window_number);
1899  if (v->type == VEH_ROAD) {
1900  const NWidgetBase *nwid_info = this->GetWidget<NWidgetBase>(WID_VD_MIDDLE_DETAILS);
1901  uint aimed_height = this->GetRoadVehDetailsHeight(v);
1902  /* If the number of articulated parts changes, the size of the window must change too. */
1903  if (aimed_height != nwid_info->current_y) {
1904  this->ReInit();
1905  }
1906  }
1907  }
1908 
1915  {
1916  uint desired_height;
1917  if (v->HasArticulatedPart()) {
1918  /* An articulated RV has its text drawn under the sprite instead of after it, hence 15 pixels extra. */
1919  desired_height = WD_FRAMERECT_TOP + ScaleGUITrad(15) + 3 * FONT_HEIGHT_NORMAL + 2 + WD_FRAMERECT_BOTTOM;
1920  /* Add space for the cargo amount for each part. */
1921  for (const Vehicle *u = v; u != NULL; u = u->Next()) {
1922  if (u->cargo_cap != 0) desired_height += FONT_HEIGHT_NORMAL + 1;
1923  }
1924  } else {
1925  desired_height = WD_FRAMERECT_TOP + 4 * FONT_HEIGHT_NORMAL + 3 + WD_FRAMERECT_BOTTOM;
1926  }
1927  return desired_height;
1928  }
1929 
1930  virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
1931  {
1932  switch (widget) {
1933  case WID_VD_TOP_DETAILS: {
1934  Dimension dim = { 0, 0 };
1936 
1937  for (uint i = 0; i < 4; i++) SetDParamMaxValue(i, INT16_MAX);
1938  static const StringID info_strings[] = {
1939  STR_VEHICLE_INFO_MAX_SPEED,
1940  STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED,
1941  STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE,
1942  STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR,
1943  STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS
1944  };
1945  for (uint i = 0; i < lengthof(info_strings); i++) {
1946  dim = maxdim(dim, GetStringBoundingBox(info_strings[i]));
1947  }
1948  SetDParam(0, STR_VEHICLE_INFO_AGE);
1949  dim = maxdim(dim, GetStringBoundingBox(STR_VEHICLE_INFO_AGE_RUNNING_COST_YR));
1950  size->width = dim.width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
1951  break;
1952  }
1953 
1954  case WID_VD_MIDDLE_DETAILS: {
1955  const Vehicle *v = Vehicle::Get(this->window_number);
1956  switch (v->type) {
1957  case VEH_ROAD:
1958  size->height = this->GetRoadVehDetailsHeight(v);
1959  break;
1960 
1961  case VEH_SHIP:
1962  size->height = WD_FRAMERECT_TOP + 4 * FONT_HEIGHT_NORMAL + 3 + WD_FRAMERECT_BOTTOM;
1963  break;
1964 
1965  case VEH_AIRCRAFT:
1966  size->height = WD_FRAMERECT_TOP + 5 * FONT_HEIGHT_NORMAL + 4 + WD_FRAMERECT_BOTTOM;
1967  break;
1968 
1969  default:
1970  NOT_REACHED(); // Train uses WID_VD_MATRIX instead.
1971  }
1972  break;
1973  }
1974 
1975  case WID_VD_MATRIX:
1977  size->height = 4 * resize->height;
1978  break;
1979 
1981  StringID *strs = _service_interval_dropdown;
1982  while (*strs != INVALID_STRING_ID) {
1983  *size = maxdim(*size, GetStringBoundingBox(*strs++));
1984  }
1985  size->width += padding.width;
1987  break;
1988  }
1989 
1991  SetDParamMaxValue(0, MAX_SERVINT_DAYS); // Roughly the maximum interval
1992  SetDParamMaxValue(1, MAX_YEAR * DAYS_IN_YEAR); // Roughly the maximum year
1993  size->width = max(GetStringBoundingBox(STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT).width, GetStringBoundingBox(STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS).width) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
1995  break;
1996  }
1997  }
1998 
2000  static bool IsVehicleServiceIntervalEnabled(const VehicleType vehicle_type, CompanyID company_id)
2001  {
2002  const VehicleDefaultSettings *vds = &Company::Get(company_id)->settings.vehicle;
2003  switch (vehicle_type) {
2004  default: NOT_REACHED();
2005  case VEH_TRAIN: return vds->servint_trains != 0;
2006  case VEH_ROAD: return vds->servint_roadveh != 0;
2007  case VEH_SHIP: return vds->servint_ships != 0;
2008  case VEH_AIRCRAFT: return vds->servint_aircraft != 0;
2009  }
2010  }
2011 
2023  static void DrawVehicleDetails(const Vehicle *v, int left, int right, int y, int vscroll_pos, uint vscroll_cap, TrainDetailsWindowTabs det_tab)
2024  {
2025  switch (v->type) {
2026  case VEH_TRAIN: DrawTrainDetails(Train::From(v), left, right, y, vscroll_pos, vscroll_cap, det_tab); break;
2027  case VEH_ROAD: DrawRoadVehDetails(v, left, right, y); break;
2028  case VEH_SHIP: DrawShipDetails(v, left, right, y); break;
2029  case VEH_AIRCRAFT: DrawAircraftDetails(Aircraft::From(v), left, right, y); break;
2030  default: NOT_REACHED();
2031  }
2032  }
2033 
2034  virtual void SetStringParameters(int widget) const
2035  {
2036  if (widget == WID_VD_CAPTION) SetDParam(0, Vehicle::Get(this->window_number)->index);
2037  }
2038 
2039  virtual void DrawWidget(const Rect &r, int widget) const
2040  {
2041  const Vehicle *v = Vehicle::Get(this->window_number);
2042 
2043  switch (widget) {
2044  case WID_VD_TOP_DETAILS: {
2045  int y = r.top + WD_FRAMERECT_TOP;
2046 
2047  /* Draw running cost */
2048  SetDParam(1, v->age / DAYS_IN_LEAP_YEAR);
2049  SetDParam(0, (v->age + DAYS_IN_YEAR < v->max_age) ? STR_VEHICLE_INFO_AGE : STR_VEHICLE_INFO_AGE_RED);
2052  DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_VEHICLE_INFO_AGE_RUNNING_COST_YR);
2053  y += FONT_HEIGHT_NORMAL;
2054 
2055  /* Draw max speed */
2056  StringID string;
2057  if (v->type == VEH_TRAIN ||
2058  (v->type == VEH_ROAD && _settings_game.vehicle.roadveh_acceleration_model != AM_ORIGINAL)) {
2059  const GroundVehicleCache *gcache = v->GetGroundVehicleCache();
2060  SetDParam(2, v->GetDisplayMaxSpeed());
2061  SetDParam(1, gcache->cached_power);
2062  SetDParam(0, gcache->cached_weight);
2063  SetDParam(3, gcache->cached_max_te / 1000);
2064  if (v->type == VEH_TRAIN && (_settings_game.vehicle.train_acceleration_model == AM_ORIGINAL ||
2065  GetRailTypeInfo(Train::From(v)->railtype)->acceleration_type == 2)) {
2066  string = STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED;
2067  } else {
2068  string = STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE;
2069  }
2070  } else {
2071  SetDParam(0, v->GetDisplayMaxSpeed());
2072  if (v->type == VEH_AIRCRAFT) {
2074  if (Aircraft::From(v)->GetRange() > 0) {
2075  SetDParam(2, Aircraft::From(v)->GetRange());
2076  string = STR_VEHICLE_INFO_MAX_SPEED_TYPE_RANGE;
2077  } else {
2078  string = STR_VEHICLE_INFO_MAX_SPEED_TYPE;
2079  }
2080  } else {
2081  string = STR_VEHICLE_INFO_MAX_SPEED;
2082  }
2083  }
2084  DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, string);
2085  y += FONT_HEIGHT_NORMAL;
2086 
2087  /* Draw profit */
2090  DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR);
2091  y += FONT_HEIGHT_NORMAL;
2092 
2093  /* Draw breakdown & reliability */
2096  DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS);
2097  break;
2098  }
2099 
2100  case WID_VD_MATRIX:
2101  /* For trains only. */
2102  DrawVehicleDetails(v, r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, r.top + WD_MATRIX_TOP, this->vscroll->GetPosition(), this->vscroll->GetCapacity(), this->tab);
2103  break;
2104 
2105  case WID_VD_MIDDLE_DETAILS: {
2106  /* For other vehicles, at the place of the matrix. */
2107  bool rtl = _current_text_dir == TD_RTL;
2109 
2110  uint text_left = r.left + (rtl ? 0 : sprite_width);
2111  uint text_right = r.right - (rtl ? sprite_width : 0);
2112 
2113  /* Articulated road vehicles use a complete line. */
2114  if (v->type == VEH_ROAD && v->HasArticulatedPart()) {
2115  DrawVehicleImage(v, r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, INVALID_VEHICLE, EIT_IN_DETAILS, 0);
2116  } else {
2117  uint sprite_left = rtl ? text_right : r.left;
2118  uint sprite_right = rtl ? r.right : text_left;
2119 
2120  DrawVehicleImage(v, sprite_left + WD_FRAMERECT_LEFT, sprite_right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, INVALID_VEHICLE, EIT_IN_DETAILS, 0);
2121  }
2122  DrawVehicleDetails(v, text_left + WD_FRAMERECT_LEFT, text_right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, 0, 0, this->tab);
2123  break;
2124  }
2125 
2127  /* Draw service interval text */
2128  SetDParam(0, v->GetServiceInterval());
2130  DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + (r.bottom - r.top + 1 - FONT_HEIGHT_NORMAL) / 2,
2131  v->ServiceIntervalIsPercent() ? STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT : STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS);
2132  break;
2133  }
2134  }
2135 
2137  virtual void OnPaint()
2138  {
2139  const Vehicle *v = Vehicle::Get(this->window_number);
2140 
2142 
2143  if (v->type == VEH_TRAIN) {
2144  this->DisableWidget(this->tab + WID_VD_DETAILS_CARGO_CARRIED);
2145  this->vscroll->SetCount(GetTrainDetailsWndVScroll(v->index, this->tab));
2146  }
2147 
2148  /* Disable service-scroller when interval is set to disabled */
2149  this->SetWidgetsDisabledState(!IsVehicleServiceIntervalEnabled(v->type, v->owner),
2152  WIDGET_LIST_END);
2153 
2154  StringID str = v->ServiceIntervalIsCustom() ?
2155  (v->ServiceIntervalIsPercent() ? STR_VEHICLE_DETAILS_PERCENT : STR_VEHICLE_DETAILS_DAYS) :
2156  STR_VEHICLE_DETAILS_DEFAULT;
2157  this->GetWidget<NWidgetCore>(WID_VD_SERVICE_INTERVAL_DROPDOWN)->widget_data = str;
2158 
2159  this->DrawWidgets();
2160  }
2161 
2162  virtual void OnClick(Point pt, int widget, int click_count)
2163  {
2164  switch (widget) {
2165  case WID_VD_RENAME_VEHICLE: { // rename
2166  const Vehicle *v = Vehicle::Get(this->window_number);
2167  SetDParam(0, v->index);
2168  ShowQueryString(STR_VEHICLE_NAME, STR_QUERY_RENAME_TRAIN_CAPTION + v->type,
2170  break;
2171  }
2172 
2173  case WID_VD_INCREASE_SERVICING_INTERVAL: // increase int
2174  case WID_VD_DECREASE_SERVICING_INTERVAL: { // decrease int
2175  int mod = _ctrl_pressed ? 5 : 10;
2176  const Vehicle *v = Vehicle::Get(this->window_number);
2177 
2178  mod = (widget == WID_VD_DECREASE_SERVICING_INTERVAL) ? -mod : mod;
2179  mod = GetServiceIntervalClamped(mod + v->GetServiceInterval(), v->ServiceIntervalIsPercent());
2180  if (mod == v->GetServiceInterval()) return;
2181 
2182  DoCommandP(v->tile, v->index, mod | (1 << 16) | (v->ServiceIntervalIsPercent() << 17), CMD_CHANGE_SERVICE_INT | CMD_MSG(STR_ERROR_CAN_T_CHANGE_SERVICING));
2183  break;
2184  }
2185 
2187  const Vehicle *v = Vehicle::Get(this->window_number);
2188  ShowDropDownMenu(this, _service_interval_dropdown, v->ServiceIntervalIsCustom() ? (v->ServiceIntervalIsPercent() ? 2 : 1) : 0, widget, 0, 0);
2189  break;
2190  }
2191 
2196  this->SetWidgetsDisabledState(false,
2201  widget,
2202  WIDGET_LIST_END);
2203 
2204  this->tab = (TrainDetailsWindowTabs)(widget - WID_VD_DETAILS_CARGO_CARRIED);
2205  this->SetDirty();
2206  break;
2207  }
2208  }
2209 
2210  virtual void OnDropdownSelect(int widget, int index)
2211  {
2212  switch (widget) {
2214  const Vehicle *v = Vehicle::Get(this->window_number);
2215  bool iscustom = index != 0;
2216  bool ispercent = iscustom ? (index == 2) : Company::Get(v->owner)->settings.vehicle.servint_ispercent;
2217  uint16 interval = GetServiceIntervalClamped(v->GetServiceInterval(), ispercent);
2218  DoCommandP(v->tile, v->index, interval | (iscustom << 16) | (ispercent << 17), CMD_CHANGE_SERVICE_INT | CMD_MSG(STR_ERROR_CAN_T_CHANGE_SERVICING));
2219  break;
2220  }
2221  }
2222  }
2223 
2224  virtual void OnQueryTextFinished(char *str)
2225  {
2226  if (str == NULL) return;
2227 
2228  DoCommandP(0, this->window_number, 0, CMD_RENAME_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_RENAME_TRAIN + Vehicle::Get(this->window_number)->type), NULL, str);
2229  }
2230 
2231  virtual void OnResize()
2232  {
2233  NWidgetCore *nwi = this->GetWidget<NWidgetCore>(WID_VD_MATRIX);
2234  if (nwi != NULL) {
2235  this->vscroll->SetCapacityFromWidget(this, WID_VD_MATRIX);
2236  }
2237  }
2238 };
2239 
2242  WDP_AUTO, "view_vehicle_details_train", 405, 178,
2244  0,
2245  _nested_train_vehicle_details_widgets, lengthof(_nested_train_vehicle_details_widgets)
2246 );
2247 
2250  WDP_AUTO, "view_vehicle_details", 405, 113,
2252  0,
2253  _nested_nontrain_vehicle_details_widgets, lengthof(_nested_nontrain_vehicle_details_widgets)
2254 );
2255 
2257 static void ShowVehicleDetailsWindow(const Vehicle *v)
2258 {
2261  AllocateWindowDescFront<VehicleDetailsWindow>((v->type == VEH_TRAIN) ? &_train_vehicle_details_desc : &_nontrain_vehicle_details_desc, v->index);
2262 }
2263 
2264 
2265 /* Unified vehicle GUI - Vehicle View Window */
2266 
2270  NWidget(WWT_CLOSEBOX, COLOUR_GREY),
2271  NWidget(WWT_CAPTION, COLOUR_GREY, WID_VV_CAPTION), SetDataTip(STR_VEHICLE_VIEW_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
2272  NWidget(WWT_DEBUGBOX, COLOUR_GREY),
2273  NWidget(WWT_SHADEBOX, COLOUR_GREY),
2274  NWidget(WWT_DEFSIZEBOX, COLOUR_GREY),
2275  NWidget(WWT_STICKYBOX, COLOUR_GREY),
2276  EndContainer(),
2278  NWidget(WWT_PANEL, COLOUR_GREY),
2279  NWidget(WWT_INSET, COLOUR_GREY), SetPadding(2, 2, 2, 2),
2280  NWidget(NWID_VIEWPORT, INVALID_COLOUR, WID_VV_VIEWPORT), SetMinimalSize(226, 84), SetResize(1, 1), SetPadding(1, 1, 1, 1),
2281  EndContainer(),
2282  EndContainer(),
2284  NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VV_CENTER_MAIN_VIEW), SetMinimalSize(18, 18), SetDataTip(SPR_CENTRE_VIEW_VEHICLE, 0x0 /* filled later */),
2286  NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VV_GOTO_DEPOT), SetMinimalSize(18, 18), SetDataTip(0x0 /* filled later */, 0x0 /* filled later */),
2287  NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VV_CLONE), SetMinimalSize(18, 18), SetDataTip(0x0 /* filled later */, 0x0 /* filled later */),
2288  EndContainer(),
2289  /* For trains only, 'ignore signal' button. */
2291  SetDataTip(SPR_IGNORE_SIGNALS, STR_VEHICLE_VIEW_TRAIN_IGNORE_SIGNAL_TOOLTIP),
2293  NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VV_REFIT), SetMinimalSize(18, 18), SetDataTip(SPR_REFIT_VEHICLE, 0x0 /* filled later */),
2294  NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VV_TURN_AROUND), SetMinimalSize(18, 18),
2295  SetDataTip(SPR_FORCE_VEHICLE_TURN, STR_VEHICLE_VIEW_ROAD_VEHICLE_REVERSE_TOOLTIP),
2296  EndContainer(),
2297  NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VV_SHOW_ORDERS), SetMinimalSize(18, 18), SetDataTip(SPR_SHOW_ORDERS, 0x0 /* filled later */),
2298  NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_VV_SHOW_DETAILS), SetMinimalSize(18, 18), SetDataTip(SPR_SHOW_VEHICLE_DETAILS, 0x0 /* filled later */),
2299  NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(18, 0), SetResize(0, 1), EndContainer(),
2300  EndContainer(),
2301  EndContainer(),
2304  NWidget(WWT_RESIZEBOX, COLOUR_GREY),
2305  EndContainer(),
2306 };
2307 
2310  WDP_AUTO, "view_vehicle", 250, 116,
2312  0,
2313  _nested_vehicle_view_widgets, lengthof(_nested_vehicle_view_widgets)
2314 );
2315 
2321  WDP_AUTO, "view_vehicle_train", 250, 134,
2323  0,
2324  _nested_vehicle_view_widgets, lengthof(_nested_vehicle_view_widgets)
2325 );
2326 
2327 
2328 /* Just to make sure, nobody has changed the vehicle type constants, as we are
2329  using them for array indexing in a number of places here. */
2330 assert_compile(VEH_TRAIN == 0);
2331 assert_compile(VEH_ROAD == 1);
2332 assert_compile(VEH_SHIP == 2);
2333 assert_compile(VEH_AIRCRAFT == 3);
2334 
2339  ZOOM_LVL_SHIP,
2341 };
2342 
2343 /* Constants for geometry of vehicle view viewport */
2344 static const int VV_INITIAL_VIEWPORT_WIDTH = 226;
2345 static const int VV_INITIAL_VIEWPORT_HEIGHT = 84;
2346 static const int VV_INITIAL_VIEWPORT_HEIGHT_TRAIN = 102;
2347 
2350  VCT_CMD_START_STOP = 0,
2351  VCT_CMD_CLONE_VEH,
2352  VCT_CMD_TURN_AROUND,
2353 };
2354 
2356 static const uint32 _vehicle_command_translation_table[][4] = {
2357  { // VCT_CMD_START_STOP
2358  CMD_START_STOP_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_STOP_START_TRAIN),
2359  CMD_START_STOP_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_STOP_START_ROAD_VEHICLE),
2360  CMD_START_STOP_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_STOP_START_SHIP),
2361  CMD_START_STOP_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_STOP_START_AIRCRAFT)
2362  },
2363  { // VCT_CMD_CLONE_VEH
2364  CMD_CLONE_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_BUY_TRAIN),
2365  CMD_CLONE_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_BUY_ROAD_VEHICLE),
2366  CMD_CLONE_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_BUY_SHIP),
2367  CMD_CLONE_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_BUY_AIRCRAFT)
2368  },
2369  { // VCT_CMD_TURN_AROUND
2370  CMD_REVERSE_TRAIN_DIRECTION | CMD_MSG(STR_ERROR_CAN_T_REVERSE_DIRECTION_TRAIN),
2371  CMD_TURN_ROADVEH | CMD_MSG(STR_ERROR_CAN_T_MAKE_ROAD_VEHICLE_TURN),
2372  0xffffffff, // invalid for ships
2373  0xffffffff // invalid for aircrafts
2374  },
2375 };
2376 
2384 void CcStartStopVehicle(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
2385 {
2386  if (result.Failed()) return;
2387 
2388  const Vehicle *v = Vehicle::GetIfValid(p1);
2389  if (v == NULL || !v->IsPrimaryVehicle() || v->owner != _local_company) return;
2390 
2391  StringID msg = (v->vehstatus & VS_STOPPED) ? STR_VEHICLE_COMMAND_STOPPED : STR_VEHICLE_COMMAND_STARTED;
2392  Point pt = RemapCoords(v->x_pos, v->y_pos, v->z_pos);
2393  AddTextEffect(msg, pt.x, pt.y, DAY_TICKS, TE_RISING);
2394 }
2395 
2401 void StartStopVehicle(const Vehicle *v, bool texteffect)
2402 {
2403  assert(v->IsPrimaryVehicle());
2404  DoCommandP(v->tile, v->index, 0, _vehicle_command_translation_table[VCT_CMD_START_STOP][v->type], texteffect ? CcStartStopVehicle : NULL);
2405 }
2406 
2408 static bool IsVehicleRefitable(const Vehicle *v)
2409 {
2410  if (!v->IsStoppedInDepot()) return false;
2411 
2412  do {
2413  if (IsEngineRefittable(v->engine_type)) return true;
2414  } while (v->IsGroundVehicle() && (v = v->Next()) != NULL);
2415 
2416  return false;
2417 }
2418 
2421 private:
2426 
2429 
2430  SEL_DC_BASEPLANE = SEL_DC_GOTO_DEPOT,
2431  SEL_RT_BASEPLANE = SEL_RT_REFIT,
2432  };
2433 
2439  {
2440  switch (plane) {
2441  case SEL_DC_GOTO_DEPOT:
2442  case SEL_DC_CLONE:
2443  this->GetWidget<NWidgetStacked>(WID_VV_SELECT_DEPOT_CLONE)->SetDisplayedPlane(plane - SEL_DC_BASEPLANE);
2444  break;
2445 
2446  case SEL_RT_REFIT:
2447  case SEL_RT_TURN_AROUND:
2448  this->GetWidget<NWidgetStacked>(WID_VV_SELECT_REFIT_TURN)->SetDisplayedPlane(plane - SEL_RT_BASEPLANE);
2449  break;
2450 
2451  default:
2452  NOT_REACHED();
2453  }
2454  }
2455 
2456 public:
2458  {
2459  this->flags |= WF_DISABLE_VP_SCROLL;
2460  this->CreateNestedTree();
2461 
2462  /* Sprites for the 'send to depot' button indexed by vehicle type. */
2463  static const SpriteID vehicle_view_goto_depot_sprites[] = {
2464  SPR_SEND_TRAIN_TODEPOT,
2465  SPR_SEND_ROADVEH_TODEPOT,
2466  SPR_SEND_SHIP_TODEPOT,
2467  SPR_SEND_AIRCRAFT_TODEPOT,
2468  };
2469  const Vehicle *v = Vehicle::Get(window_number);
2470  this->GetWidget<NWidgetCore>(WID_VV_GOTO_DEPOT)->widget_data = vehicle_view_goto_depot_sprites[v->type];
2471 
2472  /* Sprites for the 'clone vehicle' button indexed by vehicle type. */
2473  static const SpriteID vehicle_view_clone_sprites[] = {
2475  SPR_CLONE_ROADVEH,
2476  SPR_CLONE_SHIP,
2477  SPR_CLONE_AIRCRAFT,
2478  };
2479  this->GetWidget<NWidgetCore>(WID_VV_CLONE)->widget_data = vehicle_view_clone_sprites[v->type];
2480 
2481  switch (v->type) {
2482  case VEH_TRAIN:
2483  this->GetWidget<NWidgetCore>(WID_VV_TURN_AROUND)->tool_tip = STR_VEHICLE_VIEW_TRAIN_REVERSE_TOOLTIP;
2484  break;
2485 
2486  case VEH_ROAD:
2487  break;
2488 
2489  case VEH_SHIP:
2490  case VEH_AIRCRAFT:
2491  this->SelectPlane(SEL_RT_REFIT);
2492  break;
2493 
2494  default: NOT_REACHED();
2495  }
2496  this->FinishInitNested(window_number);
2497  this->owner = v->owner;
2498  this->GetWidget<NWidgetViewport>(WID_VV_VIEWPORT)->InitializeViewport(this, this->window_number | (1 << 31), _vehicle_view_zoom_levels[v->type]);
2499 
2500  this->GetWidget<NWidgetCore>(WID_VV_START_STOP)->tool_tip = STR_VEHICLE_VIEW_TRAIN_STATE_START_STOP_TOOLTIP + v->type;
2501  this->GetWidget<NWidgetCore>(WID_VV_CENTER_MAIN_VIEW)->tool_tip = STR_VEHICLE_VIEW_TRAIN_LOCATION_TOOLTIP + v->type;
2502  this->GetWidget<NWidgetCore>(WID_VV_REFIT)->tool_tip = STR_VEHICLE_VIEW_TRAIN_REFIT_TOOLTIP + v->type;
2503  this->GetWidget<NWidgetCore>(WID_VV_GOTO_DEPOT)->tool_tip = STR_VEHICLE_VIEW_TRAIN_SEND_TO_DEPOT_TOOLTIP + v->type;
2504  this->GetWidget<NWidgetCore>(WID_VV_SHOW_ORDERS)->tool_tip = STR_VEHICLE_VIEW_TRAIN_ORDERS_TOOLTIP + v->type;
2505  this->GetWidget<NWidgetCore>(WID_VV_SHOW_DETAILS)->tool_tip = STR_VEHICLE_VIEW_TRAIN_SHOW_DETAILS_TOOLTIP + v->type;
2506  this->GetWidget<NWidgetCore>(WID_VV_CLONE)->tool_tip = STR_VEHICLE_VIEW_CLONE_TRAIN_INFO + v->type;
2507  }
2508 
2510  {
2515  }
2516 
2517  virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
2518  {
2519  const Vehicle *v = Vehicle::Get(this->window_number);
2520  switch (widget) {
2521  case WID_VV_START_STOP:
2522  size->height = max(size->height, max(GetSpriteSize(SPR_FLAG_VEH_STOPPED).height, GetSpriteSize(SPR_FLAG_VEH_RUNNING).height) + WD_IMGBTN_TOP + WD_IMGBTN_BOTTOM);
2523  break;
2524 
2525  case WID_VV_FORCE_PROCEED:
2526  if (v->type != VEH_TRAIN) {
2527  size->height = 0;
2528  size->width = 0;
2529  }
2530  break;
2531 
2532  case WID_VV_VIEWPORT:
2533  size->width = VV_INITIAL_VIEWPORT_WIDTH;
2534  size->height = (v->type == VEH_TRAIN) ? VV_INITIAL_VIEWPORT_HEIGHT_TRAIN : VV_INITIAL_VIEWPORT_HEIGHT;
2535  break;
2536  }
2537  }
2538 
2539  virtual void OnPaint()
2540  {
2541  const Vehicle *v = Vehicle::Get(this->window_number);
2542  bool is_localcompany = v->owner == _local_company;
2543  bool refitable_and_stopped_in_depot = IsVehicleRefitable(v);
2544 
2545  this->SetWidgetDisabledState(WID_VV_GOTO_DEPOT, !is_localcompany);
2546  this->SetWidgetDisabledState(WID_VV_REFIT, !refitable_and_stopped_in_depot || !is_localcompany);
2547  this->SetWidgetDisabledState(WID_VV_CLONE, !is_localcompany);
2548 
2549  if (v->type == VEH_TRAIN) {
2551  this->SetWidgetDisabledState(WID_VV_FORCE_PROCEED, !is_localcompany);
2552  this->SetWidgetDisabledState(WID_VV_TURN_AROUND, !is_localcompany);
2553  }
2554 
2555  this->DrawWidgets();
2556  }
2557 
2558  virtual void SetStringParameters(int widget) const
2559  {
2560  if (widget != WID_VV_CAPTION) return;
2561 
2562  const Vehicle *v = Vehicle::Get(this->window_number);
2563  SetDParam(0, v->index);
2564  }
2565 
2566  virtual void DrawWidget(const Rect &r, int widget) const
2567  {
2568  if (widget != WID_VV_START_STOP) return;
2569 
2570  const Vehicle *v = Vehicle::Get(this->window_number);
2571  StringID str;
2572  if (v->vehstatus & VS_CRASHED) {
2573  str = STR_VEHICLE_STATUS_CRASHED;
2574  } else if (v->type != VEH_AIRCRAFT && v->breakdown_ctr == 1) { // check for aircraft necessary?
2575  str = STR_VEHICLE_STATUS_BROKEN_DOWN;
2576  } else if (v->vehstatus & VS_STOPPED) {
2577  if (v->type == VEH_TRAIN) {
2578  if (v->cur_speed == 0) {
2579  if (Train::From(v)->gcache.cached_power == 0) {
2580  str = STR_VEHICLE_STATUS_TRAIN_NO_POWER;
2581  } else {
2582  str = STR_VEHICLE_STATUS_STOPPED;
2583  }
2584  } else {
2585  SetDParam(0, v->GetDisplaySpeed());
2586  str = STR_VEHICLE_STATUS_TRAIN_STOPPING_VEL;
2587  }
2588  } else { // no train
2589  str = STR_VEHICLE_STATUS_STOPPED;
2590  }
2591  } else if (v->type == VEH_TRAIN && HasBit(Train::From(v)->flags, VRF_TRAIN_STUCK) && !v->current_order.IsType(OT_LOADING)) {
2592  str = STR_VEHICLE_STATUS_TRAIN_STUCK;
2593  } else if (v->type == VEH_AIRCRAFT && HasBit(Aircraft::From(v)->flags, VAF_DEST_TOO_FAR) && !v->current_order.IsType(OT_LOADING)) {
2594  str = STR_VEHICLE_STATUS_AIRCRAFT_TOO_FAR;
2595  } else { // vehicle is in a "normal" state, show current order
2596  switch (v->current_order.GetType()) {
2597  case OT_GOTO_STATION: {
2599  SetDParam(1, v->GetDisplaySpeed());
2600  str = STR_VEHICLE_STATUS_HEADING_FOR_STATION_VEL;
2601  break;
2602  }
2603 
2604  case OT_GOTO_DEPOT: {
2605  SetDParam(0, v->type);
2607  SetDParam(2, v->GetDisplaySpeed());
2609  /* This case *only* happens when multiple nearest depot orders
2610  * follow each other (including an order list only one order: a
2611  * nearest depot order) and there are no reachable depots.
2612  * It is primarily to guard for the case that there is no
2613  * depot with index 0, which would be used as fallback for
2614  * evaluating the string in the status bar. */
2615  str = STR_EMPTY;
2616  } else if (v->current_order.GetDepotActionType() & ODATFB_HALT) {
2617  str = STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_VEL;
2618  } else {
2619  str = STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_SERVICE_VEL;
2620  }
2621  break;
2622  }
2623 
2624  case OT_LOADING:
2625  str = STR_VEHICLE_STATUS_LOADING_UNLOADING;
2626  break;
2627 
2628  case OT_GOTO_WAYPOINT: {
2629  assert(v->type == VEH_TRAIN || v->type == VEH_SHIP);
2631  str = STR_VEHICLE_STATUS_HEADING_FOR_WAYPOINT_VEL;
2632  SetDParam(1, v->GetDisplaySpeed());
2633  break;
2634  }
2635 
2636  case OT_LEAVESTATION:
2637  if (v->type != VEH_AIRCRAFT) {
2638  str = STR_VEHICLE_STATUS_LEAVING;
2639  break;
2640  }
2641  FALLTHROUGH;
2642  default:
2643  if (v->GetNumManualOrders() == 0) {
2644  str = STR_VEHICLE_STATUS_NO_ORDERS_VEL;
2645  SetDParam(0, v->GetDisplaySpeed());
2646  } else {
2647  str = STR_EMPTY;
2648  }
2649  break;
2650  }
2651  }
2652 
2653  /* Draw the flag plus orders. */
2654  bool rtl = (_current_text_dir == TD_RTL);
2655  uint text_offset = max(GetSpriteSize(SPR_FLAG_VEH_STOPPED).width, GetSpriteSize(SPR_FLAG_VEH_RUNNING).width) + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT;
2656  int text_left = r.left + (rtl ? (uint)WD_FRAMERECT_LEFT : text_offset);
2657  int text_right = r.right - (rtl ? text_offset : (uint)WD_FRAMERECT_RIGHT);
2658  int image_left = (rtl ? text_right + 1 : r.left) + WD_IMGBTN_LEFT;
2659  int image = ((v->vehstatus & VS_STOPPED) != 0) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING;
2660  int lowered = this->IsWidgetLowered(WID_VV_START_STOP) ? 1 : 0;
2661  DrawSprite(image, PAL_NONE, image_left + lowered, r.top + WD_IMGBTN_TOP + lowered);
2662  DrawString(text_left + lowered, text_right + lowered, r.top + WD_FRAMERECT_TOP + lowered, str, TC_FROMSTRING, SA_HOR_CENTER);
2663  }
2664 
2665  virtual void OnClick(Point pt, int widget, int click_count)
2666  {
2667  const Vehicle *v = Vehicle::Get(this->window_number);
2668 
2669  switch (widget) {
2670  case WID_VV_START_STOP: // start stop
2671  if (_ctrl_pressed) {
2672  /* Scroll to current order destination */
2673  TileIndex tile = v->current_order.GetLocation(v);
2674  if (tile != INVALID_TILE) ScrollMainWindowToTile(tile);
2675  } else {
2676  /* Start/Stop */
2677  StartStopVehicle(v, false);
2678  }
2679  break;
2680  case WID_VV_CENTER_MAIN_VIEW: {// center main view
2681  const Window *mainwindow = FindWindowById(WC_MAIN_WINDOW, 0);
2682  /* code to allow the main window to 'follow' the vehicle if the ctrl key is pressed */
2683  if (_ctrl_pressed && mainwindow->viewport->zoom <= ZOOM_LVL_OUT_4X) {
2684  mainwindow->viewport->follow_vehicle = v->index;
2685  } else {
2686  ScrollMainWindowTo(v->x_pos, v->y_pos, v->z_pos);
2687  }
2688  break;
2689  }
2690 
2691  case WID_VV_GOTO_DEPOT: // goto hangar
2692  DoCommandP(v->tile, v->index | (_ctrl_pressed ? DEPOT_SERVICE : 0U), 0, GetCmdSendToDepot(v));
2693  break;
2694  case WID_VV_REFIT: // refit
2696  break;
2697  case WID_VV_SHOW_ORDERS: // show orders
2698  if (_ctrl_pressed) {
2700  } else {
2701  ShowOrdersWindow(v);
2702  }
2703  break;
2704  case WID_VV_SHOW_DETAILS: // show details
2706  break;
2707  case WID_VV_CLONE: // clone vehicle
2708  /* Suppress the vehicle GUI when share-cloning.
2709  * There is no point to it except for starting the vehicle.
2710  * For starting the vehicle the player has to open the depot GUI, which is
2711  * most likely already open, but is also visible in the vehicle viewport. */
2712  DoCommandP(v->tile, v->index, _ctrl_pressed ? 1 : 0,
2713  _vehicle_command_translation_table[VCT_CMD_CLONE_VEH][v->type],
2714  _ctrl_pressed ? NULL : CcCloneVehicle);
2715  break;
2716  case WID_VV_TURN_AROUND: // turn around
2717  assert(v->IsGroundVehicle());
2718  DoCommandP(v->tile, v->index, 0,
2719  _vehicle_command_translation_table[VCT_CMD_TURN_AROUND][v->type]);
2720  break;
2721  case WID_VV_FORCE_PROCEED: // force proceed
2722  assert(v->type == VEH_TRAIN);
2723  DoCommandP(v->tile, v->index, 0, CMD_FORCE_TRAIN_PROCEED | CMD_MSG(STR_ERROR_CAN_T_MAKE_TRAIN_PASS_SIGNAL));
2724  break;
2725  }
2726  }
2727 
2728  virtual void OnResize()
2729  {
2730  if (this->viewport != NULL) {
2731  NWidgetViewport *nvp = this->GetWidget<NWidgetViewport>(WID_VV_VIEWPORT);
2732  nvp->UpdateViewportCoordinates(this);
2733  }
2734  }
2735 
2736  virtual void OnTick()
2737  {
2738  const Vehicle *v = Vehicle::Get(this->window_number);
2739  bool veh_stopped = v->IsStoppedInDepot();
2740 
2741  /* Widget WID_VV_GOTO_DEPOT must be hidden if the vehicle is already stopped in depot.
2742  * Widget WID_VV_CLONE_VEH should then be shown, since cloning is allowed only while in depot and stopped.
2743  */
2744  PlaneSelections plane = veh_stopped ? SEL_DC_CLONE : SEL_DC_GOTO_DEPOT;
2745  NWidgetStacked *nwi = this->GetWidget<NWidgetStacked>(WID_VV_SELECT_DEPOT_CLONE); // Selection widget 'send to depot' / 'clone'.
2746  if (nwi->shown_plane + SEL_DC_BASEPLANE != plane) {
2747  this->SelectPlane(plane);
2749  }
2750  /* The same system applies to widget WID_VV_REFIT_VEH and VVW_WIDGET_TURN_AROUND.*/
2751  if (v->IsGroundVehicle()) {
2752  PlaneSelections plane = veh_stopped ? SEL_RT_REFIT : SEL_RT_TURN_AROUND;
2753  NWidgetStacked *nwi = this->GetWidget<NWidgetStacked>(WID_VV_SELECT_REFIT_TURN);
2754  if (nwi->shown_plane + SEL_RT_BASEPLANE != plane) {
2755  this->SelectPlane(plane);
2757  }
2758  }
2759  }
2760 
2766  virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
2767  {
2768  if (data == VIWD_AUTOREPLACE) {
2769  /* Autoreplace replaced the vehicle.
2770  * Nothing to do for this window. */
2771  return;
2772  }
2773  }
2774 
2775  virtual bool IsNewGRFInspectable() const
2776  {
2778  }
2779 
2780  virtual void ShowNewGRFInspectWindow() const
2781  {
2783  }
2784 };
2785 
2786 
2789 {
2790  AllocateWindowDescFront<VehicleViewWindow>((v->type == VEH_TRAIN) ? &_train_view_desc : &_vehicle_view_desc, v->index);
2791 }
2792 
2798 bool VehicleClicked(const Vehicle *v)
2799 {
2800  assert(v != NULL);
2801  if (!(_thd.place_mode & HT_VEHICLE)) return false;
2802 
2803  v = v->First();
2804  if (!v->IsPrimaryVehicle()) return false;
2805 
2806  return _thd.GetCallbackWnd()->OnVehicleSelect(v);
2807 }
2808 
2809 void StopGlobalFollowVehicle(const Vehicle *v)
2810 {
2812  if (w != NULL && w->viewport->follow_vehicle == v->index) {
2813  ScrollMainWindowTo(v->x_pos, v->y_pos, v->z_pos, true); // lock the main view on the vehicle's last position
2815  }
2816 }
2817 
2818 
2826 void CcBuildPrimaryVehicle(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
2827 {
2828  if (result.Failed()) return;
2829 
2830  const Vehicle *v = Vehicle::Get(_new_vehicle_id);
2832 }
2833 
2840 {
2841  switch (v->type) {
2842  case VEH_TRAIN:
2843  return Train::From(v)->GetDisplayImageWidth();
2844 
2845  case VEH_ROAD:
2847 
2848  default:
2849  bool rtl = _current_text_dir == TD_RTL;
2850  VehicleSpriteSeq seq;
2851  v->GetImage(rtl ? DIR_E : DIR_W, image_type, &seq);
2852  Rect rec;
2853  seq.GetBounds(&rec);
2854  return UnScaleGUI(rec.right - rec.left + 1);
2855  }
2856 }
2857 
2863 int GetVehicleWidth(const Vehicle *v, EngineImageType image_type)
2864 {
2865  if (v->type == VEH_TRAIN || v->type == VEH_ROAD) {
2866  int vehicle_width = 0;
2867  for (const Vehicle *u = v; u != NULL; u = u->Next()) {
2868  vehicle_width += GetSingleVehicleWidth(u, image_type);
2869  }
2870  return vehicle_width;
2871  } else {
2872  return GetSingleVehicleWidth(v, image_type);
2873  }
2874 }
2875 
2882 {
2883  bool rtl = _current_text_dir == TD_RTL;
2884 
2885  _cursor.sprite_count = 0;
2886  int total_width = 0;
2887  for (; v != NULL; v = v->HasArticulatedPart() ? v->GetNextArticulatedPart() : NULL) {
2888  if (total_width >= 2 * (int)VEHICLEINFO_FULL_VEHICLE_WIDTH) break;
2889 
2891  VehicleSpriteSeq seq;
2892  v->GetImage(rtl ? DIR_E : DIR_W, image_type, &seq);
2893 
2894  if (_cursor.sprite_count + seq.count > lengthof(_cursor.sprite_seq)) break;
2895 
2896  for (uint i = 0; i < seq.count; ++i) {
2897  PaletteID pal2 = (v->vehstatus & VS_CRASHED) || !seq.seq[i].pal ? pal : seq.seq[i].pal;
2898  _cursor.sprite_seq[_cursor.sprite_count].sprite = seq.seq[i].sprite;
2899  _cursor.sprite_seq[_cursor.sprite_count].pal = pal2;
2900  _cursor.sprite_pos[_cursor.sprite_count].x = rtl ? -total_width : total_width;
2901  _cursor.sprite_pos[_cursor.sprite_count].y = 0;
2902  _cursor.sprite_count++;
2903  }
2904 
2905  total_width += GetSingleVehicleWidth(v, image_type);
2906  }
2907 
2908  int offs = ((int)VEHICLEINFO_FULL_VEHICLE_WIDTH - total_width) / 2;
2909  if (rtl) offs = -offs;
2910  for (uint i = 0; i < _cursor.sprite_count; ++i) {
2911  _cursor.sprite_pos[i].x += offs;
2912  }
2913 
2914  UpdateCursorSize();
2915 }
Nested widget containing a viewport.
Definition: widget_type.h:81
static const uint32 _vehicle_command_translation_table[][4]
Command codes for the shared buttons indexed by VehicleCommandTranslation and vehicle type...
Functions related to OTTD&#39;s strings.
Road vehicle states.
void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_pos, uint16 vscroll_cap, TrainDetailsWindowTabs det_tab)
Draw the details for the given vehicle at the given position.
Definition: train_gui.cpp:356
VehicleSettings vehicle
options for vehicles
virtual void OnTick()
Called once per (game) tick.
Functions/types related to NewGRF debugging.
Date max_age
Maximum age.
Definition: vehicle_base.h:259
CargoID cargo
Cargo to refit to.
uint32 PaletteID
The number of the palette.
Definition: gfx_type.h:20
Default zoom level for the aircraft view.
Definition: zoom_type.h:39
WindowNumber window_number
The WindowNumber of the window that is responsible for the selection mode.
Vehicle is stopped by the player.
Definition: vehicle_base.h:33
Normal push-button (no toggle button) with image caption.
Definition: widget_type.h:105
void RebuildDone()
Notify the sortlist that the rebuild is done.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition: settings.cpp:77
DropDownList * BuildActionDropdownList(bool show_autoreplace, bool show_group)
Display the Action dropdown window.
Definition of stuff that is very close to a company, like the company struct itself.
static Titem * GetIfValid(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:257
Money value
Value of the vehicle.
Definition: vehicle_base.h:241
virtual void OnInvalidateData(int data=0, bool gui_scope=true)
Some data on this window has become invalid.
Default settings for vehicles.
uint32 widget_data
Data of the widget.
Definition: widget_type.h:305
static const RailtypeInfo * GetRailTypeInfo(RailType railtype)
Returns a pointer to the Railtype information for a given railtype.
Definition: rail.h:296
static const int DAYS_IN_YEAR
days per year
Definition: date_type.h:31
void ChangeVehicleViewWindow(VehicleID from_index, VehicleID to_index)
Report a change in vehicle IDs (due to autoreplace) to affected vehicle windows.
virtual void OnQueryTextFinished(char *str)
The query window opened from this window has closed.
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
CompanyID company
The company associated with this list.
Definition: vehiclelist.h:34
PlaneSelections
Display planes available in the vehicle view window.
Horizontally center the text.
Definition: gfx_func.h:99
The information about a vehicle list.
Definition: vehiclelist.h:31
ResizeInfo resize
Resize information.
Definition: window_gui.h:317
virtual void OnPaint()
The window must be repainted.
void ScrollTowards(int position)
Scroll towards the given position; if the item is visible nothing happens, otherwise it will be shown...
Definition: widget_type.h:731
static NWidgetPart SetResize(int16 dx, int16 dy)
Widget part function for setting the resize step.
Definition: widget_type.h:930
Window(WindowDesc *desc)
Empty constructor, initialization has been moved to InitNested() called from the constructor of the d...
Definition: window.cpp:1843
static const int VEHICLE_PROFIT_MIN_AGE
Only vehicles older than this have a meaningful profit.
Definition: vehicle_func.h:29
static int CDECL VehicleNumberSorter(const Vehicle *const *a, const Vehicle *const *b)
Sort vehicles by their number.
void SetWidgetDisabledState(byte widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
Definition: window_gui.h:387
static int CDECL VehicleProfitThisYearSorter(const Vehicle *const *a, const Vehicle *const *b)
Sort vehicles by this year profit.
Offset at right of a matrix cell.
Definition: window_gui.h:79
A normal unpaused game.
Definition: openttd.h:58
virtual void SetStringParameters(int widget) const
Initialize string parameters for a widget.
virtual void SetStringParameters(int widget) const
Initialize string parameters for a widget.
void SetWidgetLoweredState(byte widget_index, bool lowered_stat)
Sets the lowered/raised status of a widget.
Definition: window_gui.h:448
Money GetDisplayProfitThisYear() const
Gets the profit vehicle had this year.
Definition: vehicle_base.h:567
static int UnScaleGUI(int value)
Short-hand to apply GUI zoom level.
Definition: zoom_func.h:72
static WindowDesc _vehicle_view_desc(WDP_AUTO, "view_vehicle", 250, 116, WC_VEHICLE_VIEW, WC_NONE, 0, _nested_vehicle_view_widgets, lengthof(_nested_vehicle_view_widgets))
Vehicle view window descriptor for all vehicles but trains.
void DrawShipImage(const Vehicle *v, int left, int right, int y, VehicleID selection, EngineImageType image_type)
Draws an image of a ship.
Definition: ship_gui.cpp:34
Window * parent
Parent window.
Definition: window_gui.h:332
High level window description.
Definition: window_gui.h:168
Functions related to the autoreplace GUIs.
East.
Vehicle * GetFirstEnginePart()
Get the first part of an articulated engine.
Definition: vehicle_base.h:920
uint16 GetServiceIntervalClamped(uint interval, bool ispercent)
Clamp the service interval to the correct min/max.
Definition: order_cmd.cpp:1954
rename a whole vehicle
Definition: command_type.h:243
int sprite_right
Right position of the vehicle sprite.
WindowFlags flags
Window flags.
Definition: window_gui.h:305
StringID tool_tip
Tooltip of the widget.
Definition: widget_type.h:306
int left
x position of left edge of the window
Definition: window_gui.h:312
StringID GetAircraftTypeText() const
Get the name of the aircraft type for display purposes.
Definition: engine.cpp:470
Functions related to time tabling.
void DrawAircraftDetails(const Aircraft *v, int left, int right, int y)
Draw the details for the given vehicle at the given position.
bool VehicleClicked(const Vehicle *v)
Dispatch a "vehicle selected" event if any window waits for it.
void ErasePreservingOrder(uint pos, uint count=1)
Remove items from the vector while preserving the order of other items.
void DrawWidgets() const
Paint all widgets of a window.
Definition: widget.cpp:604
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:246
bool CanCarryCargo() const
Determines whether an engine can carry something.
Definition: engine.cpp:173
virtual void SetStringParameters(int widget) const
Initialize string parameters for a widget.
void DrawVehicleImage(const Vehicle *v, int left, int right, int y, VehicleID selection, EngineImageType image_type, int skip)
Draws an image of a vehicle chain.
static Point RemapCoords(int x, int y, int z)
Map 3D world or tile coordinate to equivalent 2D coordinate as used in the viewports and smallmap...
Definition: landscape.h:83
Header with question about the cargo to carry.
Show details of this vehicle.
Scrollbar data structure.
Definition: widget_type.h:589
Vehicle composition was changed.
Definition: vehicle_gui.h:36
Stacked widgets, widgets all occupying the same space in the window.
Definition: widget_type.h:405
Base for the train class.
Point sprite_pos[16]
relative position of individual sprites
Definition: gfx_type.h:131
virtual void DrawWidget(const Rect &r, int widget) const
Draw the contents of a nested widget.
void SetWidgetDirty(byte widget_index) const
Invalidate a widget, i.e.
Definition: window.cpp:577
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
Update size and resize step of a widget in the window.
static const VehicleOrderID INVALID_VEH_ORDER_ID
Invalid vehicle order index (sentinel)
Definition: order_type.h:23
Offset at top to draw the frame rectangular area.
Definition: window_gui.h:64
virtual void OnDropdownSelect(int widget, int index)
A dropdown option associated to this window has been selected.
Default zoom level for the ship view.
Definition: zoom_type.h:40
Sort order.
void UpdateViewportCoordinates(Window *w)
Update the position and size of the viewport (after eg a resize).
Definition: widget.cpp:1936
Functions related to debugging.
virtual void OnDragDrop(Point pt, int widget)
A dragged &#39;object&#39; has been released.
Horizontal container.
Definition: widget_type.h:75
Window * FindWindowById(WindowClass cls, WindowNumber number)
Find a window by its class and window number.
Definition: window.cpp:1105
change the server interval of a vehicle
Definition: command_type.h:231
static void DrawVehicleProfitButton(const Vehicle *v, int x, int y)
draw the vehicle profit button in the vehicle list window.
byte _colour_gradient[COLOUR_END][8]
All 16 colour gradients 8 colours per gradient from darkest (0) to lightest (7)
Definition: gfx.cpp:53
Arrow to the right or in case of RTL to the left.
Definition: widget_type.h:38
Arrow to the left or in case of RTL to the right.
Definition: widget_type.h:37
uint16 cur_speed
current speed
Definition: vehicle_base.h:293
query cost only, don&#39;t build.
Definition: command_type.h:344
void CDECL SetWidgetsDisabledState(bool disab_stat, int widgets,...)
Sets the enabled/disabled status of a list of widgets.
Definition: window.cpp:516
NewGRF debug box (at top-right of a window, between WWT_CAPTION and WWT_SHADEBOX) ...
Definition: widget_type.h:63
uint sprite_count
number of sprites to draw
Definition: gfx_type.h:132
void ShowQueryString(StringID str, StringID caption, uint maxsize, Window *parent, CharSetFilter afilter, QueryStringFlags flags)
Show a query popup window with a textbox in it.
Definition: misc_gui.cpp:1065
static int ScaleGUITrad(int value)
Scale traditional pixel dimensions to GUI zoom level.
Definition: zoom_func.h:82
Tab with cargo capacity of the vehicles.
Definition: vehicle_gui.h:28
bool IsStoppedInDepot() const
Check whether the vehicle is in the depot and stopped.
Definition: vehicle_base.h:517
uint16 _returned_refit_capacity
Stores the capacity after a refit operation.
Definition: vehicle.cpp:86
#define FOR_ALL_SORTED_CARGOSPECS(var)
Loop header for iterating over cargoes, sorted by name.
Definition: cargotype.h:166
Specification of a cargo type.
Definition: cargotype.h:56
GUIVehicleList vehicles
The list of vehicles.
OrderList * list
Pointer to the order list for this vehicle.
Definition: vehicle_base.h:321
static WindowDesc _train_vehicle_details_desc(WDP_AUTO, "view_vehicle_details_train", 405, 178, WC_VEHICLE_DETAILS, WC_VEHICLE_VIEW, 0, _nested_train_vehicle_details_widgets, lengthof(_nested_train_vehicle_details_widgets))
Vehicle details window descriptor.
Clone this vehicle.
Default zoom level for the road vehicle view.
Definition: zoom_type.h:42
Functions related to vehicles.
Aircraft, helicopters, rotors and their shadows belong to this class.
Definition: aircraft.h:74
static int CDECL VehicleReliabilitySorter(const Vehicle *const *a, const Vehicle *const *b)
Sort vehicles by their reliability.
Resize box (normally at bottom-right of a window)
Definition: widget_type.h:68
Pressed (inset) panel, most commonly used as combo box text area.
Definition: widget_type.h:51
Manage vehicles dropdown list.
virtual void OnClick(Point pt, int widget, int click_count)
A click with the left mouse button has been made on the window.
Sort by dropdown list.
Show carried cargo per part of the train.
Vehicle data structure.
Definition: vehicle_base.h:212
Caption of window.
static bool IsExpected(const BaseStation *st)
Helper for checking whether the given station is of this type.
void Clear()
Remove all items from the list.
Scrollbar * vscroll
The main scrollbar.
virtual void ShowNewGRFInspectWindow() const
Show the NewGRF inspection window.
const T * Begin() const
Get the pointer to the first item (const)
Start or stop this vehicle, and show information about the current state.
Tindex index
Index of this pool item.
Definition: pool_type.hpp:147
Normal push-button (no toggle button) with custom drawing.
Definition: widget_type.h:103
virtual void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const
Gets the sprite to show for the given direction.
Definition: vehicle_base.h:443
static const int DAY_TICKS
1 day is 74 ticks; _date_fract used to be uint16 and incremented by 885.
Definition: date_type.h:30
Close box (at top-left of a window)
Definition: widget_type.h:69
Offset at top of a matrix cell.
Definition: window_gui.h:80
PaletteID GetVehiclePalette(const Vehicle *v)
Get the colour map for a vehicle.
Definition: vehicle.cpp:1954
Rename this vehicle.
bool NeedResort()
Check if a resort is needed next loop If used the resort timer will decrease every call till 0...
bool GenerateVehicleSortList(VehicleList *list, const VehicleListIdentifier &vli)
Generate a list of vehicles based on window type.
Base for aircraft.
static NWidgetPart SetMinimalTextLines(uint8 lines, uint8 spacing, FontSize size=FS_NORMAL)
Widget part function for setting the minimal text lines.
Definition: widget_type.h:965
#define lastof(x)
Get the last element of an fixed size array.
Definition: depend.cpp:50
Horizontal scrollbar or the vehicle display.
void ReInit(int rx=0, int ry=0)
Re-initialize a window, and optionally change its size.
Definition: window.cpp:970
Show the orders of this vehicle.
StringID GetGRFStringID(uint32 grfid, StringID stringid)
Returns the index for this stringid associated with its grfID.
static int CDECL VehicleTimeToLiveSorter(const Vehicle *const *a, const Vehicle *const *b)
Sort vehicles by the time they can still live.
void RefreshScrollbar()
Refresh scrollbar after selection changed.
Money GetCost() const
The costs as made up to this moment.
Definition: command_type.h:84
Stuff related to the text buffer GUI.
WindowClass
Window classes.
Definition: window_type.h:39
byte GetDigitWidth(FontSize size)
Return the maximum width of single digit.
Definition: gfx.cpp:1161
void DisableWidget(byte widget_index)
Sets a widget to disabled.
Definition: window_gui.h:397
virtual void DrawWidget(const Rect &r, int widget) const
Draw the contents of a nested widget.
List of the vehicles.
Invalid window.
Definition: window_type.h:684
Common return value for all commands.
Definition: command_type.h:25
uint32 cached_power
Total power of the consist (valid only for the first engine).
virtual void OnClick(Point pt, int widget, int click_count)
A click with the left mouse button has been made on the window.
GrfSpecFeature GetGrfSpecFeature(TileIndex tile)
Get the GrfSpecFeature associated with the tile.
Determine the cargo "suffixes" for each refit possibility of a cargo.
static const VehicleID INVALID_VEHICLE
Constant representing a non-existing vehicle.
Definition: vehicle_type.h:57
static T max(const T a, const T b)
Returns the maximum of two values.
Definition: math_func.hpp:26
uint8 advanced_vehicle_list
use the "advanced" vehicle list
Definition: settings_type.h:94
byte vehstatus
Status.
Definition: vehicle_base.h:317
EngineImageType
Visualisation contexts of vehicles and engines.
Definition: vehicle_type.h:87
WindowClass cls
Class of the window,.
Definition: window_gui.h:177
Cached, frequently calculated values.
Nested widget to display a viewport in a window.
Definition: widget_type.h:575
TileIndex GetLocation(const Vehicle *v, bool airport=false) const
Returns a tile somewhat representing the order destination (not suitable for pathfinding).
Definition: order_cmd.cpp:670
Common string list item.
Definition: dropdown_type.h:41
Option to refit a vehicle chain.
static Train * From(Vehicle *v)
Converts a Vehicle to SpecializedVehicle with type checking.
Display &#39;goto depot&#39; button in WID_VV_SELECT_DEPOT_CLONE stacked widget.
const T * End() const
Get the pointer behind the last valid item (const)
void CreateNestedTree(bool fill_nested=true)
Perform the first part of the initialization of a nested widget tree.
Definition: window.cpp:1804
const Engine * GetEngine() const
Retrieves the engine of the vehicle.
Definition: vehicle.cpp:743
void SetListing(Listing l)
Import sort conditions.
Window * GetCallbackWnd()
Get the window that started the current highlighting.
Definition: viewport.cpp:2341
StringID name
Name of this type of cargo.
Definition: cargotype.h:71
Display &#39;clone vehicle&#39; button in WID_VV_SELECT_DEPOT_CLONE stacked widget.
bool NeedRebuild() const
Check if a rebuild is needed.
HighLightStyle place_mode
Method which is used to place the selection.
OrderDepotActionFlags GetDepotActionType() const
What are we going to do when in the depot.
Definition: order_base.h:139
static const ZoomLevel _vehicle_view_zoom_levels[]
Zoom levels for vehicle views indexed by vehicle type.
virtual bool OnVehicleSelect(const struct Vehicle *v)
The user clicked on a vehicle while HT_VEHICLE has been set.
Definition: window_gui.h:743
Display with a representation of the vehicle to refit.
DepotCommand
Flags to add to p1 for goto depot commands.
Definition: vehicle_type.h:67
virtual void OnPaint()
Repaint vehicle details window.
uint16 servint_ships
service interval for ships
void DrawFrameRect(int left, int top, int right, int bottom, Colours colour, FrameFlags flags)
Draw frame rectangle.
Definition: widget.cpp:177
T * Append(uint to_add=1)
Append an item and return it.
Order * next
Pointer to next order. If NULL, end of list.
Definition: order_base.h:51
Vehicle * FirstShared() const
Get the first vehicle of this vehicle chain.
Definition: vehicle_base.h:676
void SetCount(int num)
Sets the number of elements in the list.
Definition: widget_type.h:670
CompanyByte _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition: company_cmd.cpp:46
virtual void OnResize()
Called after the window got resized.
Partial widget specification to allow NWidgets to be written nested.
Definition: widget_type.h:910
Functions related to (drawing on) viewports.
start or stop a vehicle
Definition: command_type.h:310
void ForceRebuild()
Force that a rebuild is needed.
StringID string
GRF-local String to display for the cargo.
void DrawAircraftImage(const Vehicle *v, int left, int right, int y, VehicleID selection, EngineImageType image_type)
Draws an image of an aircraft.
bool IsEngineRefittable(EngineID engine)
Check if an engine is refittable.
Definition: engine.cpp:1102
void Resize(uint num_items)
Set the size of the vector, effectively truncating items from the end or appending uninitialised ones...
Data structure for an opened window.
Definition: window_gui.h:271
byte breakdown_ctr
Counter for managing breakdown events.
Definition: vehicle_base.h:263
bool _ctrl_pressed
Is Ctrl pressed?
Definition: gfx.cpp:36
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition: window.cpp:1820
static NWidgetPart SetMatrixDataTip(uint8 cols, uint8 rows, StringID tip)
Widget part function for setting the data and tooltip of WWT_MATRIX widgets.
Definition: widget_type.h:1032
virtual void SetStringParameters(int widget) const
Initialize string parameters for a widget.
Autoreplace replaced the vehicle.
Definition: vehicle_gui.h:37
static NWidgetPart SetPadding(uint8 top, uint8 right, uint8 bottom, uint8 left)
Widget part function for setting additional space around a widget.
Definition: widget_type.h:1046
Vehicle drawn in vehicle details, refit window, ...
Definition: vehicle_type.h:90
dragging items in the depot windows
uint16 cargo_cap
total capacity
Definition: vehicle_base.h:307
Bottom offset of image in the button.
Definition: window_gui.h:43
Header of Action 04 "universal holder" structure and functions.
Main window; Window numbers:
Definition: window_type.h:46
enable the &#39;Default&#39; button ("\0" is returned)
Definition: textbuf_gui.h:23
Vehicle orders; Window numbers:
Definition: window_type.h:207
proceed a train to pass a red signal
Definition: command_type.h:222
virtual void OnClick(Point pt, int widget, int click_count)
A click with the left mouse button has been made on the window.
Aircraft vehicle type.
Definition: vehicle_type.h:27
virtual int GetDisplayMaxSpeed() const
Gets the maximum speed in km-ish/h that can be sent into SetDParam for string processing.
Definition: vehicle_base.h:487
Money GetDisplayRunningCost() const
Gets the running cost of a vehicle that can be sent into SetDParam for string processing.
Definition: vehicle_base.h:561
Map related accessors for depots.
static int CDECL VehicleCargoSorter(const Vehicle *const *a, const Vehicle *const *b)
Sort vehicles by their cargo.
void SelectPlane(PlaneSelections plane)
Display a plane in the window.
Functions related to low-level strings.
Zoomed 4 times out.
Definition: zoom_type.h:26
Vehicle is crashed.
Definition: vehicle_base.h:39
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
Update size and resize step of a widget in the window.
byte GetBestFittingSubType(Vehicle *v_from, Vehicle *v_for, CargoID dest_cargo_type)
Get the best fitting subtype when &#39;cloning&#39;/&#39;replacing&#39; v_from with v_for.
virtual void OnMouseDrag(Point pt, int widget)
An &#39;object&#39; is being dragged at the provided position, highlight the target if possible.
uint GetRoadVehDetailsHeight(const Vehicle *v)
Gets the desired height for the road vehicle details panel.
virtual bool IsPrimaryVehicle() const
Whether this is the primary vehicle in the chain.
Definition: vehicle_base.h:434
Window manager class for viewing a vehicle.
Scrollbar * hscroll
Only used for long vehicles.
static const uint MAX_LENGTH_VEHICLE_NAME_CHARS
The maximum length of a vehicle name in characters including &#39;\0&#39;.
Definition: vehicle_type.h:75
Offset at bottom of a matrix cell.
Definition: window_gui.h:81
virtual void OnInvalidateData(int data=0, bool gui_scope=true)
Some data on this window has become invalid.
UnitID unitnumber
unit number, for display purposes only
Definition: vehicle_base.h:291
#define FONT_HEIGHT_SMALL
Height of characters in the small (FS_SMALL) font.
Definition: gfx_func.h:177
CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags)
Shorthand for calling the long DoCommand with a container.
Definition: command.cpp:436
void DrawVehicleListItems(VehicleID selected_vehicle, int line_height, const Rect &r) const
Draw all the vehicle list items.
Default window size box (at top-right of a window, between WWT_SHADEBOX and WWT_STICKYBOX) ...
Definition: widget_type.h:65
byte cargo_subtype
Used for livery refits (NewGRF variations)
Definition: vehicle_base.h:306
uint Length() const
Get the number of items in the list.
bool operator!=(const MultiMapIterator< Tmap_iter1, Tlist_iter1, Tkey, Tvalue1, Tcompare > &iter1, const MultiMapIterator< Tmap_iter2, Tlist_iter2, Tkey, Tvalue2, Tcompare > &iter2)
Inverse of operator==().
Definition: multimap.hpp:222
int GetScrolledRowFromWidget(int clickpos, const Window *const w, int widget, int padding=0, int line_height=-1) const
Compute the row of a scrolled widget that a user clicked in.
Definition: widget.cpp:1959
static int CDECL VehicleMaxSpeedSorter(const Vehicle *const *a, const Vehicle *const *b)
Sort vehicles by their max speed.
This window is used for construction; close it whenever changing company.
Definition: window_gui.h:210
West.
bool IsWidgetLowered(byte widget_index) const
Gets the lowered state of a widget.
Definition: window_gui.h:488
void CcCloneVehicle(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
This is the Callback method after the cloning attempt of a vehicle.
Definition: depot_gui.cpp:121
Listing GetListing() const
Export current sort conditions.
bool Contains(const T &item) const
Tests whether a item is present in the vector.
static bool IsVehicleServiceIntervalEnabled(const VehicleType vehicle_type, CompanyID company_id)
Checks whether service interval is enabled for the vehicle.
Turn this vehicle around.
int GetSingleVehicleWidth(const Vehicle *v, EngineImageType image_type)
Get the width of a vehicle (part) in pixels.
virtual void DrawWidget(const Rect &r, int widget) const
Draw the contents of a nested widget.
Functions related to engines.
GroundVehicleCache * GetGroundVehicleCache()
Access the ground vehicle cache of the vehicle.
Definition: vehicle.cpp:2797
VehicleType
Available vehicle types.
Definition: vehicle_type.h:21
Scrollbar for the refit options.
uint current_y
Current vertical size (after resizing).
Definition: widget_type.h:175
void DrawRoadVehDetails(const Vehicle *v, int left, int right, int y)
Draw the details for the given vehicle at the given position.
Definition: roadveh_gui.cpp:32
uint32 index
A vehicle list type specific index.
Definition: vehiclelist.h:35
virtual void OnDropdownSelect(int widget, int index)
A dropdown option associated to this window has been selected.
Sort descending.
Definition: window_gui.h:227
uint32 VehicleID
The type all our vehicle IDs have.
Definition: vehicle_type.h:18
void ShowVehicleRefitWindow(const Vehicle *v, VehicleOrderID order, Window *parent, bool auto_refit)
Show the refit window for a vehicle.
bool IsType(OrderType type) const
Check whether this order is of the given type.
Definition: order_base.h:63
static void ChangeVehicleWindow(WindowClass window_class, VehicleID from_index, VehicleID to_index)
Assign a vehicle window a new vehicle.
Options to refit to.
Viewport widget.
#define FONT_HEIGHT_NORMAL
Height of characters in the normal (FS_NORMAL) font.
Definition: gfx_func.h:180
static NWidgetPart SetDataTip(uint32 data, StringID tip)
Widget part function for setting the data and tooltip.
Definition: widget_type.h:1014
Simple vector template class, with automatic delete.
T * Next() const
Get next vehicle in the chain.
byte callback_mask
Bitmask of vehicle callbacks that have to be called.
Definition: engine_type.h:143
Selection widget between &#39;goto depot&#39;, and &#39;clone vehicle&#39; buttons.
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:76
Display plane with zero size vertically, and filling and resizing horizontally.
Definition: widget_type.h:389
static NWidgetPart SetMinimalSize(int16 x, int16 y)
Widget part function for setting the minimal size.
Definition: widget_type.h:947
Definition of base types and functions in a cross-platform compatible way.
Show suffix after cargo name.
Decrease the servicing interval.
Tells that it&#39;s a mass send to depot command (type in VLW flag)
Definition: vehicle_type.h:69
the length of the string is counted in characters
Definition: textbuf_gui.h:24
void DrawTrainImage(const Train *v, int left, int right, int y, VehicleID selection, EngineImageType image_type, int skip, VehicleID drag_dest)
Draws an image of a whole train.
Definition: train_gui.cpp:94
virtual void OnInvalidateData(int data=0, bool gui_scope=true)
Some data on this window has become invalid.
Force this vehicle to pass a signal at danger.
void ShowCompanyGroup(CompanyID company, VehicleType vehicle_type)
Show the group window for the given company and vehicle type.
Definition: group_gui.cpp:955
bool IsArticulatedPart() const
Check if the vehicle is an articulated part of an engine.
Definition: vehicle_base.h:891
A number of safeguards to prevent using unsafe methods.
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
Definition: gfx_type.h:247
Normal push-button (no toggle button) with text caption.
Definition: widget_type.h:104
Geometry functions.
Vehicle refit; Window numbers:
Definition: window_type.h:201
Simple depressed panel.
Definition: widget_type.h:50
Selection widget for the horizontal scrollbar.
SmallVector< RefitOption, 32 > SubtypeList
List of refit subtypes associated to a cargo.
void StartStopVehicle(const Vehicle *v, bool texteffect)
Executes CMD_START_STOP_VEHICLE for given vehicle.
bool operator==(const MultiMapIterator< Tmap_iter1, Tlist_iter1, Tkey, Tvalue1, Tcompare > &iter1, const MultiMapIterator< Tmap_iter2, Tlist_iter2, Tkey, Tvalue2, Tcompare > &iter2)
Compare two MultiMap iterators.
Definition: multimap.hpp:205
CargoID cargo_type
type of cargo this vehicle is carrying
Definition: vehicle_base.h:305
void DrawSortButtonState(int widget, SortButtonState state) const
Draw a sort button&#39;s up or down arrow symbol.
Definition: widget.cpp:638
Horizontal scrollbar.
Definition: widget_type.h:83
uint step_height
Step-size of height resize changes.
Definition: window_gui.h:220
Scrollbar for the list.
const Scrollbar * GetScrollbar(uint widnum) const
Return the Scrollbar to a widget index.
Definition: window.cpp:307
uint16 GetRange() const
Get the range of this aircraft.
Definition: aircraft.h:133
static int CDECL VehicleTimetableDelaySorter(const Vehicle *const *a, const Vehicle *const *b)
Sort vehicles by the timetable delay.
Vehicle view; Window numbers:
Definition: window_type.h:334
Offset at left of a matrix cell.
Definition: window_gui.h:78
VehicleOrderID order
If not INVALID_VEH_ORDER_ID, selection is part of a refit order (rather than execute directly)...
byte subtype
Subcargo to use.
byte misc_flags
Miscellaneous flags.
Definition: engine_type.h:142
Order * GetFirstOrder() const
Get the first order of the order chain.
Definition: order_base.h:290
static VehicleListIdentifier UnPack(uint32 data)
Decode a packed vehicle list identifier into a new one.
Definition: vehiclelist.cpp:55
TileIndex tile
Current tile index.
Definition: vehicle_base.h:230
TrainDetailsWindowTabs tab
For train vehicles: which tab is displayed.
static int CDECL VehicleNameSorter(const Vehicle *const *a, const Vehicle *const *b)
Sort vehicles by their name.
void DrawShipDetails(const Vehicle *v, int left, int right, int y)
Draw the details for the given vehicle at the given position.
Definition: ship_gui.cpp:66
static NWidgetPart NWidget(WidgetType tp, Colours col, int16 idx=-1)
Widget part function for starting a new &#39;real&#39; widget.
Definition: widget_type.h:1114
The tile has no ownership.
Definition: company_type.h:27
bool HasArticulatedPart() const
Check if an engine has an articulated part.
Definition: vehicle_base.h:900
Vehicle timetable; Window numbers:
Definition: window_type.h:219
Offset at bottom to draw the frame rectangular area.
Definition: window_gui.h:65
Baseclass for nested widgets.
Definition: widget_type.h:126
int DrawString(int left, int right, int top, const char *str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly truncated to make it fit in its allocated space.
Definition: gfx.cpp:499
void ShowVehicleViewWindow(const Vehicle *v)
Shows the vehicle view window of the given vehicle.
int GetVehicleWidth(const Vehicle *v, EngineImageType image_type)
Get the width of a vehicle (including all parts of the consist) in pixels.
Increase the servicing interval.
Service the vehicle and then halt it.
Definition: order_type.h:110
void DrawRoadVehImage(const Vehicle *v, int left, int right, int y, VehicleID selection, EngineImageType image_type, int skip)
Draws an image of a road vehicle chain.
Sprite sequence for a vehicle part.
Definition: vehicle_base.h:130
bool DoCommandP(const CommandContainer *container, bool my_cmd)
Shortcut for the long DoCommandP when having a container with the data.
Definition: command.cpp:527
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:42
Start all button.
PauseModeByte _pause_mode
The current pause mode.
Definition: gfx.cpp:48
Road vehicle type.
Definition: vehicle_type.h:25
Grid of rows and columns.
Definition: widget_type.h:59
VehicleID follow_vehicle
VehicleID to follow if following a vehicle, INVALID_VEHICLE otherwise.
Definition: window_gui.h:259
static T min(const T a, const T b)
Returns the minimum of two values.
Definition: math_func.hpp:42
uint pos_x
Horizontal position of top-left corner of the widget in the window.
Definition: widget_type.h:177
static const NWidgetPart _nested_train_vehicle_details_widgets[]
Train details widgets.
Default zoom level for the train view.
Definition: zoom_type.h:41
Right offset of the image in the button.
Definition: window_gui.h:41
byte breakdowns_since_last_service
Counter for the amount of breakdowns.
Definition: vehicle_base.h:265
uint16 reliability
Reliability.
Definition: vehicle_base.h:261
void SetSortType(uint8 n_type)
Set the sorttype of the list.
bool Sort(SortFunction *compare)
Sort the list.
static int CDECL VehicleModelSorter(const Vehicle *const *a, const Vehicle *const *b)
Sort vehicles by model.
static int SortButtonWidth()
Get width of up/down arrow of sort button state.
Definition: widget.cpp:658
Functions to cache sprites in memory.
uint32 StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:18
int GetDisplayImageWidth(Point *offset=NULL) const
Get the width of a road vehicle image in the GUI.
Definition: roadveh_cmd.cpp:91
Vehicle * First() const
Get the first vehicle of this vehicle chain.
Definition: vehicle_base.h:595
Class for managing the vehicle details window.
bool Failed() const
Did this command fail?
Definition: command_type.h:161
Tab with cargo carried by the vehicles.
Definition: vehicle_gui.h:26
Show all parts of the train with their description.
int GetDisplayImageWidth(Point *offset=NULL) const
Get the width of a train vehicle image in the GUI.
Definition: train_cmd.cpp:455
virtual void OnInvalidateData(int data=0, bool gui_scope=true)
Some data on this window has become invalid.
bool auto_refit
Select cargo for auto-refitting.
static DepotID GetDepotIndex(TileIndex t)
Get the index of which depot is attached to the tile.
Definition: depot_map.h:54
Draw border only, no background.
Definition: window_gui.h:30
static const int WIDGET_LIST_END
indicate the end of widgets&#39; list for vararg functions
Definition: widget_type.h:22
virtual void OnResize()
Called after the window got resized.
Details for non-trains.
virtual void OnTick()
Called once per (game) tick.
int vehicle_width
Width of the vehicle being drawn.
static const SpriteID SPR_CLONE_TRAIN
Clone vehicles stuff.
Definition: sprites.h:102
Ship vehicle type.
Definition: vehicle_type.h:26
static T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition: math_func.hpp:139
Functions/classes shared between the different vehicle list GUIs.
virtual void OnResize()
Called after the window got resized.
static const NWidgetPart _nested_vehicle_view_widgets[]
Vehicle view widgets.
void SetDirty() const
Mark entire window as dirty (in need of re-paint)
Definition: window.cpp:959
int sprite_left
Left position of the vehicle sprite.
#define DEBUG(name, level,...)
Output a line of debugging information.
Definition: debug.h:39
&#39;Train&#39; is either a loco or a wagon.
Definition: train.h:88
VehicleDetailsWindow(WindowDesc *desc, WindowNumber window_number)
Initialize a newly created vehicle details window.
Dimension GetStringBoundingBox(const char *str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition: gfx.cpp:699
virtual void DrawWidget(const Rect &r, int widget) const
Draw the contents of a nested widget.
Maximal number of cargo types in a game.
Definition: cargo_type.h:66
void ForceResort()
Force a resort next Sort call Reset the resort timer if used too.
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
No window, redirects to WC_MAIN_WINDOW.
Definition: window_type.h:40
void DeleteWindowById(WindowClass cls, WindowNumber number, bool force)
Delete a window by its class and window number (if it is open).
Definition: window.cpp:1137
PalSpriteID sprite_seq[16]
current image of cursor
Definition: gfx_type.h:130
static int CDECL VehicleProfitLastYearSorter(const Vehicle *const *a, const Vehicle *const *b)
Sort vehicles by last year profit.
char * name
Name of vehicle.
Definition: base_consist.h:20
Selection widget between &#39;refit&#39; and &#39;turn around&#39; buttons.
Open the refit window.
ZoomLevel
All zoom levels we know.
Definition: zoom_type.h:21
static const GroupID DEFAULT_GROUP
Ungrouped vehicles are in this group.
Definition: group_type.h:19
The vehicle will leave the depot right after arrival (serivce only)
Definition: vehicle_type.h:68
static WindowDesc _nontrain_vehicle_details_desc(WDP_AUTO, "view_vehicle_details", 405, 113, WC_VEHICLE_DETAILS, WC_VEHICLE_VIEW, 0, _nested_nontrain_vehicle_details_widgets, lengthof(_nested_nontrain_vehicle_details_widgets))
Vehicle details window descriptor for other vehicles than a train.
static int32 ClampToI32(const int64 a)
Reduce a signed 64-bit int to a signed 32-bit one.
Definition: math_func.hpp:203
Functions related to companies.
uint GetUnitNumberDigits(VehicleList &vehicles)
Get the number of digits the biggest unit number of a set of vehicles has.
Window for the (old) vehicle listing.
virtual void OnPaint()
The window must be repainted.
static StationID GetStationIndex(TileIndex t)
Get StationID from a tile.
Definition: station_map.h:29
Vehicle drawn in vehicle list, group list, ...
Definition: vehicle_type.h:91
bool IsNewGRFInspectable(GrfSpecFeature feature, uint index)
Can we inspect the data given a certain feature and index.
void SetObjectToPlaceWnd(CursorID icon, PaletteID pal, HighLightStyle mode, Window *w)
Change the cursor and mouse click/drag handling to a mode for performing special operations like tile...
Definition: viewport.cpp:3151
bool ScrollMainWindowTo(int x, int y, int z, bool instant)
Scrolls the main window to given coordinates.
TrainDetailsWindowTabs
The tabs in the train details window.
Definition: vehicle_gui.h:25
Functions related to articulated vehicles.
void ErrorUnknownCallbackResult(uint32 grfid, uint16 cbid, uint16 cb_res)
Record that a NewGRF returned an unknown/invalid callback result.
Class for storing amounts of cargo.
Definition: cargo_type.h:74
Automatic refitting is allowed.
Definition: engine_type.h:158
Both numeric and alphabetic and spaces and stuff.
Definition: string_type.h:27
StringID GetCapacityString(RefitOption *option) const
Gets the StringID to use for displaying capacity.
Display &#39;turn around&#39; button in WID_VV_SELECT_REFIT_TURN stacked widget.
bool IsGroundVehicle() const
Check if the vehicle is a ground vehicle.
Definition: vehicle_base.h:472
Train can&#39;t get a path reservation.
Definition: train.h:34
GUISettings gui
settings related to the GUI
void SetSelection(uint click_row)
Select a row.
void SetMouseCursorVehicle(const Vehicle *v, EngineImageType image_type)
Set the mouse cursor to look like a vehicle.
DestinationID GetDestination() const
Gets the destination of this order.
Definition: order_base.h:96
void ShowTimetableWindow(const Vehicle *v)
Show the timetable for a given vehicle.
Window caption (window title between closebox and stickybox)
Definition: widget_type.h:61
int strnatcmp(const char *s1, const char *s2, bool ignore_garbage_at_front)
Compares two strings using case insensitive natural sort.
Definition: string.cpp:569
VehicleCommandTranslation
Command indices for the _vehicle_command_translation_table.
Center the main view on this vehicle.
uint32 SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition: gfx_type.h:19
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
Update size and resize step of a widget in the window.
void UpdateCursorSize()
Update cursor dimension.
Definition: gfx.cpp:1530
uint16 EngineID
Unique identification number of an engine.
Definition: engine_type.h:22
static CargoSpec * Get(size_t index)
Retrieve cargo details for the given cargo ID.
Definition: cargotype.h:118
CompanyByte _current_company
Company currently doing an action.
Definition: company_cmd.cpp:47
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:80
static const PaletteID PALETTE_CRASH
Recolour sprite greying of crashed vehicles.
Definition: sprites.h:1569
uint32 Pack() const
Pack a VehicleListIdentifier in a single uint32.
Definition: vehiclelist.cpp:23
RefitOption * cargo
Refit option selected by sel.
Available vehicles.
uint16 servint_trains
service interval for trains
Vehicle * Next() const
Get the next vehicle of this vehicle.
Definition: vehicle_base.h:582
static WindowDesc _train_view_desc(WDP_AUTO, "view_vehicle_train", 250, 134, WC_VEHICLE_VIEW, WC_NONE, 0, _nested_vehicle_view_widgets, lengthof(_nested_vehicle_view_widgets))
Vehicle view window descriptor for trains.
Date date_of_last_service
Last date the vehicle had a service at a depot.
Definition: vehicle_base.h:260
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition: strings.cpp:52
void ToggleSortOrder()
Toggle the sort order Since that is the worst condition for the sort function reverse the list here...
List of details for trains.
virtual void ShowNewGRFInspectWindow() const
Show the NewGRF inspection window.
Definition: window_gui.h:794
Sort ascending.
Definition: window_gui.h:226
Panel with generic details.
static bool HasAtMostOneBit(T value)
Test whether value has at most 1 bit set.
void GetVehicleSet(VehicleSet &set, Vehicle *v, uint8 num_vehicles)
Calculates the set of vehicles that will be affected by a given selection.
Definition: vehicle.cpp:2860
Send the vehicle to the nearest depot.
Definition: order_type.h:111
void SetDParamMaxValue(uint n, uint64 max_value, uint min_count, FontSize size)
Set DParam n to some number that is suitable for string size computations.
Definition: strings.cpp:105
Caption of window.
Tab with sum of total cargo transported.
Definition: vehicle_gui.h:29
Display &#39;refit&#39; button in WID_VV_SELECT_REFIT_TURN stacked widget.
Order this vehicle to go to the depot.
Next destination is too far away.
Definition: aircraft.h:41
Top offset of image in the button.
Definition: window_gui.h:42
VehicleListType type
The type of vehicle list.
Definition: vehiclelist.h:32
void ShowReplaceGroupVehicleWindow(GroupID id_g, VehicleType vehicletype)
Show the autoreplace configuration window for a particular group.
Vertical container.
Definition: widget_type.h:77
OwnerByte owner
Which company owns the vehicle?
Definition: vehicle_base.h:273
int CDECL SortFunction(const T *, const T *)
Signature of sort function.
Definition: sortlist_type.h:52
turn a train around
Definition: command_type.h:223
Vehicle * GetNextArticulatedPart() const
Get the next part of an articulated engine.
Definition: vehicle_base.h:910
void CcBuildPrimaryVehicle(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
This is the Callback method after the construction attempt of a primary vehicle.
static NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME, WWT_INSET, or WWT_PANEL).
Definition: widget_type.h:999
static uint GB(const T x, const uint8 s, const uint8 n)
Fetch n bits from x, started at bit s.
Trains list; Window numbers:
Definition: window_type.h:303
Functions related to zooming.
uint information_width
Width required for correctly displaying all cargoes in the information panel.
VehicleListType
Vehicle List type flags.
Definition: vehiclelist.h:21
Information about the servicing interval.
int shown_plane
Plane being displayed (for NWID_SELECTION only).
Definition: widget_type.h:420
uint current_x
Current horizontal size (after resizing).
Definition: widget_type.h:174
static void ShowVehicleDetailsWindow(const Vehicle *v)
Shows the vehicle details window of the given vehicle.
int GetTrainDetailsWndVScroll(VehicleID veh_id, TrainDetailsWindowTabs det_tab)
Determines the number of lines in the train details window.
Definition: train_gui.cpp:313
static const Money VEHICLE_PROFIT_THRESHOLD
Threshold for a vehicle to be considered making good profit.
Definition: vehicle_func.h:30
change the refit information of an order (for "goto depot" )
Definition: command_type.h:270
bool Include(const T &item)
Tests whether a item is present in the vector, and appends it to the end if not.
uint16 _returned_mail_refit_capacity
Stores the mail capacity after a refit operation (Aircraft only).
Definition: vehicle.cpp:87
uint16 servint_aircraft
service interval for aircraft
Refit cargo window.
uint32 _cargo_mask
Bitmask of cargo types available.
Definition: cargotype.cpp:31
Show the capacity and carried cargo amounts aggregated per cargo of the train.
static uint GetVehicleHeight(VehicleType type)
Get the height of a single vehicle in the GUIs.
Definition: vehicle_gui.h:62
static uint ToPercent16(uint i)
Converts a "fract" value 0..65535 to "percent" value 0..100.
Definition: math_func.hpp:300
static const NWidgetPart _nested_nontrain_vehicle_details_widgets[]
Vehicle details widgets (other than train).
int32 z_pos
z coordinate.
Definition: vehicle_base.h:270
bool ScrollMainWindowToTile(TileIndex tile, bool instant)
Scrolls the viewport of the main window to a given location.
Definition: viewport.cpp:2268
VehicleListIdentifier vli
Identifier of the vehicle list we want to currently show.
Vehicle details; Window numbers:
Definition: window_type.h:195
Scrollbar for train details.
static uint CountBits(T value)
Counts the number of set bits in a variable.
Bottom offset of the dropdown widget string.
Definition: window_gui.h:137
Functions/definitions that have something to do with groups.
Functions related to commands.
Caption of window.
Coordinates of a point in 2D.
clone a vehicle
Definition: command_type.h:309
int click_x
Position of the first click while dragging.
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
Definition: gfx.cpp:768
CargoID Index() const
Determines index of this cargospec.
Definition: cargotype.h:89
void SetDisplayedPlane(int plane)
Select which plane to show (for NWID_SELECTION only).
Definition: widget.cpp:1084
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-NULL) Titem.
Definition: pool_type.hpp:235
uint32 GetGRFID() const
Retrieve the GRF ID of the NewGRF the vehicle is tied to.
Definition: vehicle.cpp:763
uint8 train_acceleration_model
realistic acceleration for trains
void CcStartStopVehicle(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2)
This is the Callback method after attempting to start/stop a vehicle.
Make the text effect slowly go upwards.
Definition: texteff.hpp:23
Ignore next signal, after the signal ignore being stuck.
Definition: train.h:42
Drop down list.
Definition: widget_type.h:70
Normal push-button (no toggle button) with arrow caption.
Definition: widget_type.h:106
uint16 GetCapacity() const
Gets the number of visible elements of the scrollbar.
Definition: widget_type.h:622
static WindowClass GetWindowClassForVehicleType(VehicleType vt)
Get WindowClass for vehicle list of given vehicle type.
Definition: vehicle_gui.h:85
virtual void OnResize()
Called after the window got resized.
start/stop all vehicles (in a depot)
Definition: command_type.h:311
Window does not do autoscroll,.
Definition: window_gui.h:241
static int CDECL VehicleValueSorter(const Vehicle *const *a, const Vehicle *const *b)
Sort vehicles by their value.
Order * GetOrder(int index) const
Returns order &#39;index&#39; of a vehicle or NULL when it doesn&#39;t exists.
Definition: vehicle_base.h:859
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
Definition: strings_type.h:19
Owner owner
The owner of the content shown in this window. Company colour is acquired from this variable...
Definition: window_gui.h:319
uint16 GetVehicleCallback(CallbackID callback, uint32 param1, uint32 param2, EngineID engine, const Vehicle *v)
Evaluate a newgrf callback for vehicles.
uint8 num_vehicles
Number of selected vehicles.
virtual bool IsNewGRFInspectable() const
Is the data related to this window NewGRF inspectable?
uint8 roadveh_acceleration_model
realistic acceleration for road vehicles
vehicle is accepted as target as well (bitmask)
Offset at right to draw the frame rectangular area.
Definition: window_gui.h:63
EngineID engine_type
The type of engine used for this vehicle.
Definition: vehicle_base.h:288
ZoomLevel zoom
The zoom level of the viewport.
Definition: viewport_type.h:35
Sticky box (at top-right of a window, after WWT_DEFSIZEBOX)
Definition: widget_type.h:66
void BuildRefitList()
Collects all (cargo, subcargo) refit options of a vehicle chain.
int width
width of the window (number of pixels to the right in x direction)
Definition: window_gui.h:314
virtual void OnClick(Point pt, int widget, int click_count)
A click with the left mouse button has been made on the window.
uint GetVehicleListHeight(VehicleType type, uint divisor)
Get the height of a vehicle in the vehicle list GUIs.
static void DrawVehicleRefitWindow(const SubtypeList list[NUM_CARGO], const int sel[2], uint pos, uint rows, uint delta, const Rect &r)
Draw the list of available refit options for a consist and highlight the selected refit option (if an...
int32 x_pos
x coordinate.
Definition: vehicle_base.h:268
byte VehicleOrderID
The index of an order within its current vehicle (not pool related)
Definition: order_type.h:17
static NWidgetPart SetFill(uint fill_x, uint fill_y)
Widget part function for setting filling.
Definition: widget_type.h:983
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
virtual void OnInit()
Notification that the nested widget tree gets initialized.
Show the capacity of all train parts.
Information about the currently selected refit option.
static const TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition: tile_type.h:85
Perform the refit.
const GRFFile * GetGRF() const
Retrieve the NewGRF the vehicle is tied to.
Definition: vehicle.cpp:753
bool IsDescSortOrder() const
Check if the sort order is descending.
#define CMD_MSG(x)
Used to combine a StringID with the command.
Definition: command_type.h:366
static bool IsVehicleRefitable(const Vehicle *v)
Checks whether the vehicle may be refitted at the moment.
int32 WindowNumber
Number to differentiate different windows of the same class.
Definition: window_type.h:695
virtual int GetDisplaySpeed() const
Gets the speed in km-ish/h that can be sent into SetDParam for string processing. ...
Definition: vehicle_base.h:481
WindowClass window_class
Window class.
Definition: window_gui.h:306
uint16 servint_roadveh
service interval for road vehicles
OrderType GetType() const
Get the type of order of this order.
Definition: order_base.h:69
void SetCapacityFromWidget(Window *w, int widget, int padding=0)
Set capacity of visible elements from the size and resize properties of a widget. ...
Definition: widget.cpp:1973
Specification of a rectangle with absolute coordinates of all edges.
Vertical scrollbar.
Definition: widget_type.h:84
WindowClass window_class
The WindowClass of the window that is responsible for the selection mode.
byte CargoID
Cargo slots to indicate a cargo type within a game.
Definition: cargo_type.h:22
int32 y_pos
y coordinate.
Definition: vehicle_base.h:269
byte unitnumber_digits
The number of digits of the highest unit number.
Text is written right-to-left by default.
Definition: strings_type.h:26
WindowNumber window_number
Window number within the window class.
Definition: window_gui.h:307
ButtonPlanes
Enumeration of planes of the button row at the bottom.
uint32 cached_max_te
Maximum tractive effort of consist (valid only for the first engine).
Functions related to tile highlights.
Owner
Enum for all companies/owners.
Definition: company_type.h:20
virtual bool IsChainInDepot() const
Check whether the whole vehicle chain is in the depot.
Definition: vehicle_base.h:511
uint ShowRefitOptionsList(int left, int right, int y, EngineID engine)
Display list of cargo types of the engine, for the purchase information window.
StringID GetCargoSubtypeText(const Vehicle *v)
Get the cargo subtype text from NewGRF for the vehicle details window.
static const uint MAX_REFIT_CYCLE
Maximum number of refit cycles we try, to prevent infinite loops.
Find a place automatically.
Definition: window_gui.h:156
Dimension GetActionDropdownSize(bool show_autoreplace, bool show_group)
Compute the size for the Action dropdown.
union Vehicle::@46 orders
The orders currently assigned to the vehicle.
SpriteID sprite
The &#39;real&#39; sprite.
Definition: gfx_type.h:25
Dropdown to select default/days/percent service interval.
Stacked widgets, only one visible at a time (eg in a panel with tabs).
Definition: widget_type.h:80
ViewportData * viewport
Pointer to viewport data, if present.
Definition: window_gui.h:321
GUI functions that shouldn&#39;t be here.
Listing * sorting
Pointer to the vehicle type related sorting.
static const CursorID SPR_CURSOR_MOUSE
Cursor sprite numbers.
Definition: sprites.h:1349
Base classes/functions for stations.
uint32 GetUnionOfArticulatedRefitMasks(EngineID engine, bool include_initial_cargo_type)
Ors the refit_masks of all articulated parts.
static void QSortT(T *base, uint num, int(CDECL *comparator)(const T *, const T *), bool desc=false)
Type safe qsort()
Definition: sort_func.hpp:28
Caption of window.
static int CDECL VehicleAgeSorter(const Vehicle *const *a, const Vehicle *const *b)
Sort vehicles by their age.
virtual void SetDirty(const Window *w) const
Mark the widget as &#39;dirty&#39; (in need of repaint).
Definition: widget.cpp:775
Left offset of the image in the button.
Definition: window_gui.h:40
VehicleType vtype
The vehicle type associated with this list.
Definition: vehiclelist.h:33
Date age
Age in days.
Definition: vehicle_base.h:258
RefitOption * GetRefitOption()
Gets the RefitOption placed in the selected index.
static NWidgetPart SetScrollbar(int index)
Attach a scrollbar to a widget.
Definition: widget_type.h:1095
static int CDECL VehicleLengthSorter(const Vehicle *const *a, const Vehicle *const *b)
Sort vehicles by their length.
VehicleOrderID cur_real_order_index
The index to the current real (non-implicit) order.
Definition: base_consist.h:29
VehicleTypeByte type
Type of vehicle.
Definition: vehicle_type.h:54
Dimensions (a width and height) of a rectangle in 2D.
Offset at left to draw the frame rectangular area.
Definition: window_gui.h:62
static const Year MAX_YEAR
MAX_YEAR, nicely rounded value of the number of years that can be encoded in a single 32 bits date...
Definition: date_type.h:94
Shade box (at top-right of a window, between WWT_DEBUGBOX and WWT_DEFSIZEBOX)
Definition: widget_type.h:64
uint32 cached_weight
Total weight of the consist (valid only for the first engine).
void InvalidateNewGRFCache()
Invalidates cached NewGRF variables.
Definition: vehicle_base.h:452
Money GetDisplayProfitLastYear() const
Gets the profit vehicle had last year.
Definition: vehicle_base.h:573
void GetBounds(Rect *bounds) const
Determine shared bounds of all sprites.
Definition: vehicle.cpp:99
uint vehicle_margin
Margin to use while selecting vehicles when the vehicle image is centered.
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
Draw a sprite, not in a viewport.
Definition: gfx.cpp:833
turn a road vehicle around
Definition: command_type.h:253
Order current_order
The current order (+ status, like: loading)
Definition: vehicle_base.h:318
VehicleID selected_vehicle
First vehicle in the current selection.
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
Update size and resize step of a widget in the window.
void InvalidateData(int data=0, bool gui_scope=true)
Mark this window&#39;s data as invalid (in need of re-computing)
Definition: window.cpp:3161
Top offset of the dropdown widget string.
Definition: window_gui.h:136
Selection to hide the buttons.
GroupID group_id
Index of group Pool array.
Definition: vehicle_base.h:326
static const int DAYS_IN_LEAP_YEAR
sometimes, you need one day more...
Definition: date_type.h:32
int height
Height of the window (number of pixels down in y direction)
Definition: window_gui.h:315
int DrawStringMultiLine(int left, int right, int top, int bottom, const char *str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly over multiple lines.
Definition: gfx.cpp:620
virtual void OnInvalidateData(int data=0, bool gui_scope=true)
Some data on this window has become invalid.
Definition: window_gui.h:728
(Toggle) Button with text
Definition: widget_type.h:55
virtual void OnPaint()
The window must be repainted.
static void MemSetT(T *ptr, byte value, size_t num=1)
Type-safe version of memset().
Definition: mem_func.hpp:51
VehicleOrderID GetNumManualOrders() const
Get the number of manually added orders this vehicle has.
Definition: vehicle_base.h:694
uint16 GetPosition() const
Gets the position of the first visible element in the list.
Definition: widget_type.h:631
Train vehicle type.
Definition: vehicle_type.h:24
Tab with name and value of the vehicles.
Definition: vehicle_gui.h:27
uint8 SortType() const
Get the sorttype of the list.
Definition: sortlist_type.h:97
static void SetDParam(uint n, uint64 v)
Set a string parameter v at index n in the global string parameter array.
Definition: strings_func.h:201
Base class for a &#39;real&#39; widget.
Definition: widget_type.h:284
static void DrawVehicleDetails(const Vehicle *v, int left, int right, int y, int vscroll_pos, uint vscroll_cap, TrainDetailsWindowTabs det_tab)
Draw the details for the given vehicle at the position of the Details windows.
static const GroupID ALL_GROUP
All vehicles are in this group.
Definition: group_type.h:18
PaletteID pal
The palette (use PAL_NONE) if not needed)
Definition: gfx_type.h:26
Stop all button.