OpenTTD Source 20260311-master-g511d3794ce
train_gui.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
9
10#include "stdafx.h"
11#include "window_gui.h"
12#include "command_func.h"
13#include "train.h"
14#include "strings_func.h"
15#include "vehicle_func.h"
16#include "zoom_func.h"
17#include "train_cmd.h"
18
19#include "table/strings.h"
20
21#include "safeguards.h"
22
29void CcBuildWagon(Commands, const CommandCost &result, VehicleID new_veh_id, uint, uint16_t, CargoArray, TileIndex tile, EngineID, bool, CargoType, ClientID)
30{
31 if (result.Failed()) return;
32
33 /* find a locomotive in the depot. */
34 const Vehicle *found = nullptr;
35 /* The non-deterministic order returned from VehiclesOnTile() does not
36 * matter here as there must only be one locomotive for anything to happen. */
37 for (const Vehicle *v : VehiclesOnTile(tile)) {
38 if (v->type != VEH_TRAIN) continue;
39
40 const Train *t = Train::From(v);
41 if (t->IsFrontEngine() && t->IsStoppedInDepot()) {
42 if (found != nullptr) return; // must be exactly one.
43 found = t;
44 }
45 }
46
47 /* if we found a loco, */
48 if (found != nullptr) {
49 found = found->Last();
50 /* put the new wagon at the end of the loco. */
51 Command<Commands::MoveRailVehicle>::Post(found->tile, new_veh_id, found->index, false);
53 }
54}
55
65static int HighlightDragPosition(int px, int max_width, int y, VehicleID selection, bool chain)
66{
67 bool rtl = _current_text_dir == TD_RTL;
68
69 assert(selection != VehicleID::Invalid());
70 int dragged_width = 0;
71 for (Train *t = Train::Get(selection); t != nullptr; t = chain ? t->Next() : (t->HasArticulatedPart() ? t->GetNextArticulatedPart() : nullptr)) {
72 dragged_width += t->GetDisplayImageWidth(nullptr);
73 }
74
75 int drag_hlight_left = rtl ? std::max(px - dragged_width + 1, 0) : px;
76 int drag_hlight_right = rtl ? px : std::min(px + dragged_width, max_width) - 1;
77 int drag_hlight_width = std::max(drag_hlight_right - drag_hlight_left + 1, 0);
78
79 if (drag_hlight_width > 0) {
80 int height = ScaleSpriteTrad(12);
81 int top = y - height / 2;
82 Rect r = {drag_hlight_left, top, drag_hlight_right, top + height - 1};
83 /* Sprite-scaling is used here as the area is from sprite size */
84 GfxFillRect(r.Shrink(ScaleSpriteTrad(1)), GetColourGradient(COLOUR_GREY, SHADE_LIGHTEST));
85 }
86
87 return drag_hlight_width;
88}
89
99void DrawTrainImage(const Train *v, const Rect &r, VehicleID selection, EngineImageType image_type, int skip, VehicleID drag_dest)
100{
101 bool rtl = _current_text_dir == TD_RTL;
102 Direction dir = rtl ? DIR_E : DIR_W;
103
104 DrawPixelInfo tmp_dpi;
105 /* Position of highlight box */
106 int highlight_l = 0;
107 int highlight_r = 0;
108 int max_width = r.Width();
109
110 if (!FillDrawPixelInfo(&tmp_dpi, r)) return;
111
112 {
113 AutoRestoreBackup dpi_backup(_cur_dpi, &tmp_dpi);
114
115 bool do_overlays = ShowCargoIconOverlay();
116 /* List of overlays, only used if cargo icon overlays are enabled. */
117 static std::vector<CargoIconOverlay> overlays;
118
119 int px = rtl ? max_width + skip : -skip;
120 int y = r.Height() / 2;
121 bool sel_articulated = false;
122 bool dragging = (drag_dest != VehicleID::Invalid());
123 bool drag_at_end_of_train = (drag_dest == v->index); // Head index is used to mark dragging at end of train.
124 for (; v != nullptr && (rtl ? px > 0 : px < max_width); v = v->Next()) {
125 if (dragging && !drag_at_end_of_train && drag_dest == v->index) {
126 /* Highlight the drag-and-drop destination inside the train. */
127 int drag_hlight_width = HighlightDragPosition(px, max_width, y, selection, _cursor.vehchain);
128 px += rtl ? -drag_hlight_width : drag_hlight_width;
129 }
130
131 Point offset;
132 int width = Train::From(v)->GetDisplayImageWidth(&offset);
133
134 if (rtl ? px + width > 0 : px - width < max_width) {
137 v->GetImage(dir, image_type, &seq);
138 seq.Draw(px + (rtl ? -offset.x : offset.x), y + offset.y, pal, v->vehstatus.Test(VehState::Crashed));
139 }
140
141 if (!v->IsArticulatedPart()) sel_articulated = false;
142
143 if (v->index == selection) {
144 /* Set the highlight position */
145 highlight_l = rtl ? px - width : px;
146 highlight_r = rtl ? px - 1 : px + width - 1;
147 sel_articulated = true;
148 } else if ((_cursor.vehchain && highlight_r != 0) || sel_articulated) {
149 if (rtl) {
150 highlight_l -= width;
151 } else {
152 highlight_r += width;
153 }
154 }
155
156 if (do_overlays) AddCargoIconOverlay(overlays, px, width, v);
157 px += rtl ? -width : width;
158 }
159
160 if (do_overlays) {
161 DrawCargoIconOverlays(overlays, y);
162 overlays.clear();
163 }
164
165 if (dragging && drag_at_end_of_train) {
166 /* Highlight the drag-and-drop destination at the end of the train. */
167 HighlightDragPosition(px, max_width, y, selection, _cursor.vehchain);
168 }
169 }
170
171 if (highlight_l != highlight_r) {
172 /* Draw the highlight. Now done after drawing all the engines, as
173 * the next engine after the highlight could overlap it. */
174 int height = ScaleSpriteTrad(12);
175 Rect hr = {highlight_l, 0, highlight_r, height - 1};
176 DrawFrameRect(hr.Translate(r.left, CentreBounds(r.top, r.bottom, height)).Expand(WidgetDimensions::scaled.bevel), COLOUR_WHITE, FrameFlag::BorderOnly);
177 }
178}
179
184 uint capacity;
185 uint amount;
186 StationID source;
187
193 inline bool operator == (const CargoSummaryItem &other) const
194 {
195 return !(this->cargo != other.cargo);
196 }
197};
198
199static const uint TRAIN_DETAILS_MIN_INDENT = 32;
200static const uint TRAIN_DETAILS_MAX_INDENT = 72;
201
203typedef std::vector<CargoSummaryItem> CargoSummary;
206
215static void TrainDetailsCargoTab(const CargoSummaryItem *item, int left, int right, int y)
216{
217 std::string str;
218 if (!IsValidCargoType(item->cargo)) {
219 str = GetString(STR_QUANTITY_N_A);
220 } else if (item->amount == 0) {
221 str = GetString(STR_VEHICLE_DETAILS_CARGO_EMPTY);
222 } else if (FreightWagonMult(item->cargo) > 1) {
223 str = GetString(STR_VEHICLE_DETAILS_CARGO_FROM_MULT, item->cargo, item->amount, item->source, _settings_game.vehicle.freight_trains);
224 } else {
225 str = GetString(STR_VEHICLE_DETAILS_CARGO_FROM, item->cargo, item->amount, item->source);
226 }
227 DrawString(left, right, y, str, TC_LIGHT_BLUE);
228}
229
238static void TrainDetailsInfoTab(const Vehicle *v, int left, int right, int y)
239{
240 std::string str;
241 if (RailVehInfo(v->engine_type)->railveh_type == RAILVEH_WAGON) {
242 str = GetString(STR_VEHICLE_DETAILS_TRAIN_WAGON_VALUE, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails), v->value);
243 } else {
244 str = GetString(STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE, PackEngineNameDParam(v->engine_type, EngineNameContext::VehicleDetails), v->build_year, v->value);
245 }
246 DrawString(left, right, y, str);
247}
248
257static void TrainDetailsCapacityTab(const CargoSummaryItem *item, int left, int right, int y)
258{
259 std::string str;
260 if (!IsValidCargoType(item->cargo)) {
261 /* Draw subtype only */
262 str = GetString(STR_VEHICLE_INFO_NO_CAPACITY, item->subtype);
263 } else if (FreightWagonMult(item->cargo) > 1) {
264 str = GetString(STR_VEHICLE_INFO_CAPACITY_MULT, item->cargo, item->capacity, item->subtype, _settings_game.vehicle.freight_trains);
265 } else {
266 str = GetString(STR_VEHICLE_INFO_CAPACITY, item->cargo, item->capacity, item->subtype);
267 }
268 DrawString(left, right, y, str);
269}
270
277{
278 summary.clear();
279 do {
280 if (!v->GetEngine()->CanCarryCargo()) continue;
281
282 CargoSummaryItem new_item;
283 new_item.cargo = v->cargo_cap > 0 ? v->cargo_type : INVALID_CARGO;
284 new_item.subtype = GetCargoSubtypeText(v);
285 if (!IsValidCargoType(new_item.cargo) && new_item.subtype == STR_EMPTY) continue;
286
287 auto item = std::ranges::find(summary, new_item);
288 if (item == std::end(summary)) {
289 item = summary.emplace(std::end(summary));
290 item->cargo = new_item.cargo;
291 item->subtype = new_item.subtype;
292 item->capacity = 0;
293 item->amount = 0;
294 item->source = StationID::Invalid();
295 }
296
297 item->capacity += v->cargo_cap;
298 item->amount += v->cargo.StoredCount();
299 if (item->source == StationID::Invalid()) item->source = v->cargo.GetFirstStation();
300 } while ((v = v->Next()) != nullptr && v->IsArticulatedPart());
301}
302
309{
310 uint length = 0;
311
312 do {
313 length += v->GetDisplayImageWidth();
314 } while ((v = v->Next()) != nullptr && v->IsArticulatedPart());
315
316 return length;
317}
318
326{
327 int num = 0;
328
329 if (det_tab == TDW_TAB_TOTALS) { // Total cargo tab
330 CargoArray max_cargo{};
331 for (const Vehicle *v = Vehicle::Get(veh_id); v != nullptr; v = v->Next()) {
332 max_cargo[v->cargo_type] += v->cargo_cap;
333 }
334
335 num = max_cargo.GetCount();
336 num += 2; // needs two more because the first line is the description string and the last is the feeder share
337 } else {
338 for (const Train *v = Train::Get(veh_id); v != nullptr; v = v->GetNextVehicle()) {
340 num += std::max(1u, (unsigned)_cargo_summary.size());
341
342 uint length = GetLengthOfArticulatedVehicle(v);
343 if (length > (uint)ScaleSpriteTrad(TRAIN_DETAILS_MAX_INDENT)) num++;
344 }
345 }
346
347 return num;
348}
349
359void DrawTrainDetails(const Train *v, const Rect &r, int vscroll_pos, uint16_t vscroll_cap, TrainDetailsWindowTabs det_tab)
360{
361 bool rtl = _current_text_dir == TD_RTL;
362 int line_height = r.Height();
363 int sprite_y_offset = line_height / 2;
364 int text_y_offset = (line_height - GetCharacterHeight(FS_NORMAL)) / 2;
365
366 /* draw the first 3 details tabs */
367 if (det_tab != TDW_TAB_TOTALS) {
368 Direction dir = rtl ? DIR_E : DIR_W;
369 int x = rtl ? r.right : r.left;
370 for (; v != nullptr && vscroll_pos > -vscroll_cap; v = v->GetNextVehicle()) {
372
373 /* Draw sprites */
374 uint dx = 0;
375 int px = x;
376 const Train *u = v;
377 do {
378 Point offset;
379 int width = u->GetDisplayImageWidth(&offset);
380 if (vscroll_pos <= 0 && vscroll_pos > -vscroll_cap) {
381 int pitch = 0;
382 const Engine *e = Engine::Get(v->engine_type);
383 if (e->GetGRF() != nullptr) {
385 }
388 u->GetImage(dir, EIT_IN_DETAILS, &seq);
389 seq.Draw(px + (rtl ? -offset.x : offset.x), r.top - line_height * vscroll_pos + sprite_y_offset + pitch, pal, v->vehstatus.Test(VehState::Crashed));
390 }
391 px += rtl ? -width : width;
392 dx += width;
393 u = u->Next();
394 } while (u != nullptr && u->IsArticulatedPart());
395
396 bool separate_sprite_row = (dx > (uint)ScaleSpriteTrad(TRAIN_DETAILS_MAX_INDENT));
397 if (separate_sprite_row) {
398 vscroll_pos--;
399 dx = 0;
400 }
401
402 int sprite_width = std::max<int>(dx, ScaleSpriteTrad(TRAIN_DETAILS_MIN_INDENT)) + WidgetDimensions::scaled.hsep_normal;
403 Rect dr = r.Indent(sprite_width, rtl);
404 uint num_lines = std::max(1u, (unsigned)_cargo_summary.size());
405 for (uint i = 0; i < num_lines; i++) {
406 if (vscroll_pos <= 0 && vscroll_pos > -vscroll_cap) {
407 int py = r.top - line_height * vscroll_pos + text_y_offset;
408 if (i > 0 || separate_sprite_row) {
409 if (vscroll_pos != 0) GfxFillRect(r.WithY(py - WidgetDimensions::scaled.matrix.top - 1, py - WidgetDimensions::scaled.matrix.top), GetColourGradient(COLOUR_GREY, SHADE_LIGHT));
410 }
411 switch (det_tab) {
412 case TDW_TAB_CARGO:
413 if (i < _cargo_summary.size()) {
414 TrainDetailsCargoTab(&_cargo_summary[i], dr.left, dr.right, py);
415 } else {
416 DrawString(dr.left, dr.right, py, STR_QUANTITY_N_A, TC_LIGHT_BLUE);
417 }
418 break;
419
420 case TDW_TAB_INFO:
421 if (i == 0) TrainDetailsInfoTab(v, dr.left, dr.right, py);
422 break;
423
424 case TDW_TAB_CAPACITY:
425 if (i < _cargo_summary.size()) {
426 TrainDetailsCapacityTab(&_cargo_summary[i], dr.left, dr.right, py);
427 } else {
428 DrawString(dr.left, dr.right, py, GetString(STR_VEHICLE_INFO_NO_CAPACITY, STR_EMPTY));
429 }
430 break;
431
432 default: NOT_REACHED();
433 }
434 }
435 vscroll_pos--;
436 }
437 }
438 } else {
439 int y = r.top;
440 CargoArray act_cargo{};
441 CargoArray max_cargo{};
442 Money feeder_share = 0;
443
444 for (const Vehicle *u = v; u != nullptr; u = u->Next()) {
445 act_cargo[u->cargo_type] += u->cargo.StoredCount();
446 max_cargo[u->cargo_type] += u->cargo_cap;
447 feeder_share += u->cargo.GetFeederShare();
448 }
449
450 /* draw total cargo tab */
451 DrawString(r.left, r.right, y + text_y_offset, STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_TEXT);
452 y += line_height;
453
454 /* Indent the total cargo capacity details */
455 Rect ir = r.Indent(WidgetDimensions::scaled.hsep_indent, rtl);
456 for (const CargoSpec *cs : _sorted_cargo_specs) {
457 CargoType cargo_type = cs->Index();
458 if (max_cargo[cargo_type] > 0 && --vscroll_pos < 0 && vscroll_pos > -vscroll_cap) {
459 std::string str;
460 if (FreightWagonMult(cargo_type) > 1) {
461 str = GetString(STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY_MULT, cargo_type, act_cargo[cargo_type], cargo_type, max_cargo[cargo_type], _settings_game.vehicle.freight_trains);
462 } else {
463 str = GetString(STR_VEHICLE_DETAILS_TRAIN_TOTAL_CAPACITY, cargo_type, act_cargo[cargo_type], cargo_type, max_cargo[cargo_type]);
464 }
465 DrawString(ir.left, ir.right, y + text_y_offset, str);
466 y += line_height;
467 }
468 }
469 DrawString(r.left, r.right, y + text_y_offset, GetString(STR_VEHICLE_INFO_FEEDER_CARGO_VALUE, feeder_share));
470 }
471}
uint8_t CargoType
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:21
bool IsValidCargoType(CargoType cargo)
Test whether cargo type is not INVALID_CARGO.
Definition cargo_type.h:108
std::vector< const CargoSpec * > _sorted_cargo_specs
Cargo specifications sorted alphabetically by name.
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
Common return value for all commands.
bool Failed() const
Did this command fail?
const GRFFile * GetGRF() const
Retrieve the NewGRF the engine is tied to.
bool CanCarryCargo() const
Determines whether an engine can carry something.
Definition engine.cpp:171
StationID GetFirstStation() const
Returns the first station of the first cargo packet in this list.
uint StoredCount() const
Returns sum of cargo on board the vehicle (ie not only reserved).
Iterate over all vehicles on a tile.
static WidgetDimensions scaled
Widget dimensions scaled for current zoom level.
Definition window_gui.h:30
Functions related to commands.
Commands
List of commands.
Direction
Defines the 8 directions on the map.
@ DIR_W
West.
@ DIR_E
East.
PoolID< uint16_t, struct EngineIDTag, 64000, 0xFFFF > EngineID
Unique identification number of an engine.
Definition engine_type.h:26
uint64_t PackEngineNameDParam(EngineID engine_id, EngineNameContext context, uint32_t extra_data=0)
Combine an engine ID and a name context to an engine name StringParameter.
@ VehicleDetails
Name is shown in the vehicle details GUI.
@ RAILVEH_WAGON
simple wagon, not motorized
Definition engine_type.h:34
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
Definition fontcache.cpp:87
int CentreBounds(int min, int max, int size)
Determine where to position a centred object.
int DrawString(int left, int right, int top, std::string_view str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly truncated to make it fit in its allocated space.
Definition gfx.cpp:669
void GfxFillRect(int left, int top, int right, int bottom, const std::variant< PixelColour, PaletteID > &colour, FillRectMode mode)
Applies a certain FillRectMode-operation to a rectangle [left, right] x [top, bottom] on the screen.
Definition gfx.cpp:116
bool FillDrawPixelInfo(DrawPixelInfo *n, int left, int top, int width, int height)
Set up a clipping area for only drawing into a certain area.
Definition gfx.cpp:1573
@ FS_NORMAL
Index of the normal font in the font tables.
Definition gfx_type.h:249
uint32_t PaletteID
The number of the palette.
Definition gfx_type.h:18
#define Rect
Macro that prevents name conflicts between included headers.
#define Point
Macro that prevents name conflicts between included headers.
ClientID
'Unique' identifier to be given to clients
PixelColour GetColourGradient(Colours colour, ColourShade shade)
Get colour gradient palette index.
Definition palette.cpp:393
A number of safeguards to prevent using unsafe methods.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
static const PaletteID PALETTE_CRASH
Recolour sprite greying of crashed vehicles.
Definition sprites.h:1619
Definition of base types and functions in a cross-platform compatible way.
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
Definition strings.cpp:424
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition strings.cpp:56
Functions related to OTTD's strings.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
@ TD_RTL
Text is written right-to-left by default.
Class to backup a specific variable and restore it upon destruction of this object to prevent stack v...
Class for storing amounts of cargo.
Definition cargo_type.h:115
uint GetCount() const
Get the amount of cargos that have an amount.
Definition cargo_type.h:130
Specification of a cargo type.
Definition cargotype.h:74
Helper struct for the cargo details information.
StringID subtype
STR_EMPTY if none.
bool operator==(const CargoSummaryItem &other) const
Used by std::find() and similar functions.
uint amount
Amount that is carried.
uint capacity
Amount that can be carried.
StationID source
One of the source stations.
CargoType cargo
The cargo that is carried.
T y
Y coordinate.
T x
X coordinate.
Data about how and where to blit pixels.
Definition gfx_type.h:157
int traininfo_vehicle_pitch
Vertical offset for drawing train images in depot GUI and vehicle details.
Definition newgrf.h:157
static Vehicle * Get(auto index)
int Width() const
Get width of Rect.
Rect Shrink(int s) const
Copy and shrink Rect by s pixels.
Rect Indent(int indent, bool end) const
Copy Rect and indent it from its position.
int Height() const
Get height of Rect.
Rect WithY(int new_top, int new_bottom) const
Create a new Rect, replacing the top and bottom coordiates.
Rect Translate(int x, int y) const
Copy and translate Rect by x,y pixels.
Rect Expand(int s) const
Copy and expand Rect by s pixels.
T * Next() const
Get next vehicle in the chain.
static Train * From(Vehicle *v)
T * GetNextVehicle() const
Get the next real (non-articulated part) vehicle in the consist.
'Train' is either a loco or a wagon.
Definition train.h:97
void GetImage(Direction direction, EngineImageType image_type, VehicleSpriteSeq *result) const override
Get the sprite to display the train.
int GetDisplayImageWidth(Point *offset=nullptr) const
Get the width of a train vehicle image in the GUI.
Sprite sequence for a vehicle part.
void Draw(int x, int y, PaletteID default_pal, bool force_pal) const
Draw the sprite sequence.
Definition vehicle.cpp:151
Vehicle data structure.
EngineID engine_type
The type of engine used for this vehicle.
const Engine * GetEngine() const
Retrieves the engine of the vehicle.
Definition vehicle.cpp:747
bool IsStoppedInDepot() const
Check whether the vehicle is in the depot and stopped.
VehicleCargoList cargo
The cargo this vehicle is carrying.
uint16_t cargo_cap
total capacity
Vehicle * Last()
Get the last vehicle of this vehicle chain.
VehStates vehstatus
Status.
bool IsArticulatedPart() const
Check if the vehicle is an articulated part of an engine.
CargoType cargo_type
type of cargo this vehicle is carrying
Money value
Value of the vehicle.
bool IsFrontEngine() const
Check if the vehicle is a front engine.
TileIndex tile
Current tile index.
TimerGameCalendar::Year build_year
Year the vehicle has been built.
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > > TileIndex
The index/ID of a Tile.
Definition tile_type.h:92
Base for the train class.
uint8_t FreightWagonMult(CargoType cargo)
Return the cargo weight multiplier to use for a rail vehicle.
Definition train_cmd.cpp:68
Command definitions related to trains.
void DrawTrainImage(const Train *v, const Rect &r, VehicleID selection, EngineImageType image_type, int skip, VehicleID drag_dest)
Draws an image of a whole train.
Definition train_gui.cpp:99
static int HighlightDragPosition(int px, int max_width, int y, VehicleID selection, bool chain)
Highlight the position where a rail vehicle is dragged over by drawing a light gray background.
Definition train_gui.cpp:65
static void TrainDetailsInfoTab(const Vehicle *v, int left, int right, int y)
Draw the details info tab for the given vehicle at the given position.
static void TrainDetailsCapacityTab(const CargoSummaryItem *item, int left, int right, int y)
Draw the details capacity tab for the given vehicle at the given position.
static uint GetLengthOfArticulatedVehicle(const Train *v)
Get the length of an articulated vehicle.
void DrawTrainDetails(const Train *v, const Rect &r, int vscroll_pos, uint16_t vscroll_cap, TrainDetailsWindowTabs det_tab)
Draw the details for the given vehicle at the given position.
static void GetCargoSummaryOfArticulatedVehicle(const Train *v, CargoSummary &summary)
Collects the cargo transported.
static const uint TRAIN_DETAILS_MAX_INDENT
Maximum indent level in the train details window; wider than this and we start on a new line.
std::vector< CargoSummaryItem > CargoSummary
Container for the cargo summary information.
int GetTrainDetailsWndVScroll(VehicleID veh_id, TrainDetailsWindowTabs det_tab)
Determines the number of lines in the train details window.
void CcBuildWagon(Commands, const CommandCost &result, VehicleID new_veh_id, uint, uint16_t, CargoArray, TileIndex tile, EngineID, bool, CargoType, ClientID)
Callback for building wagons.
Definition train_gui.cpp:29
static CargoSummary _cargo_summary
Reused container of cargo details.
static const uint TRAIN_DETAILS_MIN_INDENT
Minimum indent level in the train details window.
static void TrainDetailsCargoTab(const CargoSummaryItem *item, int left, int right, int y)
Draw the details cargo tab for the given vehicle at the given position.
PaletteID GetVehiclePalette(const Vehicle *v)
Get the colour map for a vehicle.
Definition vehicle.cpp:2174
@ Crashed
Vehicle is crashed.
Functions related to vehicles.
StringID GetCargoSubtypeText(const Vehicle *v)
Get the cargo subtype text from NewGRF for the vehicle details window.
void DrawCargoIconOverlays(std::span< const CargoIconOverlay > overlays, int y)
Draw a list of cargo icon overlays.
void AddCargoIconOverlay(std::vector< CargoIconOverlay > &overlays, int x, int width, const Vehicle *v)
Add a cargo icon to the list of overlays.
bool ShowCargoIconOverlay()
Test if cargo icon overlays should be drawn.
TrainDetailsWindowTabs
The tabs in the train details window.
Definition vehicle_gui.h:25
@ TDW_TAB_CAPACITY
Tab with cargo capacity of the vehicles.
Definition vehicle_gui.h:28
@ TDW_TAB_TOTALS
Tab with sum of total cargo transported.
Definition vehicle_gui.h:29
@ TDW_TAB_INFO
Tab with name and value of the vehicles.
Definition vehicle_gui.h:27
@ TDW_TAB_CARGO
Tab with cargo carried by the vehicles.
Definition vehicle_gui.h:26
EngineImageType
Visualisation contexts of vehicles and engines.
@ EIT_IN_DETAILS
Vehicle drawn in vehicle details, refit window, ...
PoolID< uint32_t, struct VehicleIDTag, 0xFF000, 0xFFFFF > VehicleID
The type all our vehicle IDs have.
@ VEH_TRAIN
Train vehicle type.
void DrawFrameRect(int left, int top, int right, int bottom, Colours colour, FrameFlags flags)
Draw frame rectangle.
Definition widget.cpp:291
void InvalidateWindowClassesData(WindowClass cls, int data, bool gui_scope)
Mark window data of all windows of a given class as invalid (in need of re-computing) Note that by de...
Definition window.cpp:3339
Functions, definitions and such used only by the GUI.
@ BorderOnly
Draw border only, no background.
Definition window_gui.h:26
@ WC_TRAINS_LIST
Trains list; Window numbers:
Functions related to zooming.
int ScaleSpriteTrad(int value)
Scale traditional pixel dimensions to GUI zoom level, for drawing sprites.
Definition zoom_func.h:107