OpenTTD Source: src/smallmap_gui.cpp Source File

OpenTTD Source 15.0-RC2

smallmap_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
10#include "stdafx.h"
11#include "core/backup_type.hpp"
12#include "clear_map.h"
13#include "industry.h"
14#include "station_map.h"
15#include "landscape.h"
16#include "tree_map.h"
17#include "viewport_func.h"
18#include "town.h"
19#include "tunnelbridge_map.h"
20#include "core/endian_func.hpp"
21#include "vehicle_base.h"
22#include "sound_func.h"
23#include "window_func.h"
24#include "company_base.h"
25#include "zoom_func.h"
26#include "strings_func.h"
27#include "blitter/factory.hpp"
28#include "linkgraph/linkgraph_gui.h"
29#include "timer/timer.h"
30#include "timer/timer_window.h"
31#include "smallmap_gui.h"
32
33#include "widgets/smallmap_widget.h"
34
35#include "table/strings.h"
36
37#include <bitset>
38
39#include "safeguards.h"
40
41 static int _smallmap_industry_count;
42 static int _smallmap_company_count;
43 static int _smallmap_cargo_count;
44
46 struct LegendAndColour {
47 PixelColour colour;
48 StringID legend;
49 IndustryType type;
50 uint8_t height;
51 CompanyID company;
52 bool show_on_map;
53 bool end;
54 bool col_break;
55};
56
58 static const uint8_t _linkstat_colours_in_legenda[] = {0, 1, 3, 5, 7, 9, 11};
59
60 static const int NUM_NO_COMPANY_ENTRIES = 4;
61
63#define MK(a, b) {a, b, IT_INVALID, 0, CompanyID::Invalid(), true, false, false}
64
66#define MC(col_break) {{}, STR_TINY_BLACK_HEIGHT, IT_INVALID, 0, CompanyID::Invalid(), true, false, col_break}
67
69#define MO(a, b) {a, b, IT_INVALID, 0, CompanyID::Invalid(), true, false, false}
70
72#define MOEND() {{}, STR_NULL, IT_INVALID, 0, OWNER_NONE, true, true, false}
73
75#define MKEND() {{}, STR_NULL, IT_INVALID, 0, CompanyID::Invalid(), true, true, false}
76
81#define MS(a, b) {a, b, IT_INVALID, 0, CompanyID::Invalid(), true, false, true}
82
84 static LegendAndColour _legend_land_contours[] = {
85 MK(PC_BLACK, STR_SMALLMAP_LEGENDA_ROADS),
86 MK(PC_GREY, STR_SMALLMAP_LEGENDA_RAILROADS),
87 MK(PC_LIGHT_BLUE, STR_SMALLMAP_LEGENDA_STATIONS_AIRPORTS_DOCKS),
88 MK(PC_DARK_RED, STR_SMALLMAP_LEGENDA_BUILDINGS_INDUSTRIES),
89 MK(PC_WHITE, STR_SMALLMAP_LEGENDA_VEHICLES),
90
91 /* Placeholders for the colours and heights of the legend.
92 * The following values are set at BuildLandLegend() based
93 * on each colour scheme and the maximum map height. */
94 MC(true),
95 MC(false),
96 MC(false),
97 MC(false),
98 MC(false),
99 MC(false),
100 MC(true),
101 MC(false),
102 MC(false),
103 MC(false),
104 MC(false),
105 MC(false),
106 MKEND()
107};
108
109static const LegendAndColour _legend_vehicles[] = {
110 MK(PC_RED, STR_SMALLMAP_LEGENDA_TRAINS),
111 MK(PC_YELLOW, STR_SMALLMAP_LEGENDA_ROAD_VEHICLES),
112 MK(PC_LIGHT_BLUE, STR_SMALLMAP_LEGENDA_SHIPS),
113 MK(PC_WHITE, STR_SMALLMAP_LEGENDA_AIRCRAFT),
114
115 MS(PC_BLACK, STR_SMALLMAP_LEGENDA_TRANSPORT_ROUTES),
116 MK(PC_DARK_RED, STR_SMALLMAP_LEGENDA_BUILDINGS_INDUSTRIES),
117 MKEND()
118};
119
120static const LegendAndColour _legend_routes[] = {
121 MK(PC_BLACK, STR_SMALLMAP_LEGENDA_ROADS),
122 MK(PC_GREY, STR_SMALLMAP_LEGENDA_RAILROADS),
123 MK(PC_DARK_RED, STR_SMALLMAP_LEGENDA_BUILDINGS_INDUSTRIES),
124
125 MS(PC_VERY_DARK_BROWN, STR_SMALLMAP_LEGENDA_RAILROAD_STATION),
126 MK(PC_ORANGE, STR_SMALLMAP_LEGENDA_TRUCK_LOADING_BAY),
127 MK(PC_YELLOW, STR_SMALLMAP_LEGENDA_BUS_STATION),
128 MK(PC_RED, STR_SMALLMAP_LEGENDA_AIRPORT_HELIPORT),
129 MK(PC_LIGHT_BLUE, STR_SMALLMAP_LEGENDA_DOCK),
130 MKEND()
131};
132
133static const LegendAndColour _legend_vegetation[] = {
134 MK(PC_ROUGH_LAND, STR_SMALLMAP_LEGENDA_ROUGH_LAND),
135 MK(PC_GRASS_LAND, STR_SMALLMAP_LEGENDA_GRASS_LAND),
136 MK(PC_BARE_LAND, STR_SMALLMAP_LEGENDA_BARE_LAND),
137 MK(PC_RAINFOREST, STR_SMALLMAP_LEGENDA_RAINFOREST),
138 MK(PC_FIELDS, STR_SMALLMAP_LEGENDA_FIELDS),
139 MK(PC_TREES, STR_SMALLMAP_LEGENDA_TREES),
140
141 MS(PC_GREEN, STR_SMALLMAP_LEGENDA_FOREST),
142 MK(PC_GREY, STR_SMALLMAP_LEGENDA_ROCKS),
143 MK(PC_ORANGE, STR_SMALLMAP_LEGENDA_DESERT),
144 MK(PC_LIGHT_BLUE, STR_SMALLMAP_LEGENDA_SNOW),
145 MK(PC_BLACK, STR_SMALLMAP_LEGENDA_TRANSPORT_ROUTES),
146 MK(PC_DARK_RED, STR_SMALLMAP_LEGENDA_BUILDINGS_INDUSTRIES),
147 MKEND()
148};
149
150static LegendAndColour _legend_land_owners[NUM_NO_COMPANY_ENTRIES + MAX_COMPANIES + 1] = {
151 MO(PC_WATER, STR_SMALLMAP_LEGENDA_WATER),
152 MO({}, STR_SMALLMAP_LEGENDA_NO_OWNER), // This colour will vary depending on settings.
153 MO(PC_DARK_RED, STR_SMALLMAP_LEGENDA_TOWNS),
154 MO(PC_DARK_GREY, STR_SMALLMAP_LEGENDA_INDUSTRIES),
155 /* The legend will be terminated the first time it is used. */
156 MOEND(),
157};
158
159#undef MK
160#undef MC
161#undef MS
162#undef MO
163#undef MOEND
164#undef MKEND
165
167 static LegendAndColour _legend_linkstats[NUM_CARGO + lengthof(_linkstat_colours_in_legenda) + 1];
172 static LegendAndColour _legend_from_industries[NUM_INDUSTRYTYPES + 1];
174 static uint _industry_to_list_pos[NUM_INDUSTRYTYPES];
176 static uint16_t _industry_to_name_string_width[NUM_INDUSTRYTYPES];
178 static bool _smallmap_show_heightmap = false;
180 static IndustryType _smallmap_industry_highlight = IT_INVALID;
182 static bool _smallmap_industry_highlight_state;
184 static TypedIndexContainer<std::array<uint32_t, MAX_COMPANIES>, CompanyID> _company_to_list_pos;
185
189 void BuildIndustriesLegend()
190{
191 uint j = 0;
192
193 /* Add each name */
194 for (IndustryType ind : _sorted_industry_types) {
195 const IndustrySpec *indsp = GetIndustrySpec(ind);
196 if (indsp->enabled) {
197 _legend_from_industries[j].legend = indsp->name;
198 _legend_from_industries[j].colour = indsp->map_colour;
199 _legend_from_industries[j].type = ind;
200 _legend_from_industries[j].show_on_map = true;
201 _legend_from_industries[j].col_break = false;
202 _legend_from_industries[j].end = false;
203
204 /* Store widget number for this industry type. */
205 _industry_to_list_pos[ind] = j;
206 j++;
207 }
208 }
209 /* Terminate the list */
210 _legend_from_industries[j].end = true;
211
212 /* Store number of enabled industries */
213 _smallmap_industry_count = j;
214}
215
219 void BuildLinkStatsLegend()
220{
221 /* Clear the legend */
222 std::fill(std::begin(_legend_linkstats), std::end(_legend_linkstats), LegendAndColour{});
223
224 uint i = 0;
225 for (; i < _sorted_cargo_specs.size(); ++i) {
226 const CargoSpec *cs = _sorted_cargo_specs[i];
227
228 _legend_linkstats[i].legend = cs->name;
229 _legend_linkstats[i].colour = cs->legend_colour;
230 _legend_linkstats[i].type = cs->Index();
231 _legend_linkstats[i].show_on_map = true;
232 }
233
234 _legend_linkstats[i].col_break = true;
235 _smallmap_cargo_count = i;
236
237 for (; i < _smallmap_cargo_count + lengthof(_linkstat_colours_in_legenda); ++i) {
238 _legend_linkstats[i].legend = STR_EMPTY;
239 _legend_linkstats[i].colour = LinkGraphOverlay::LINK_COLOURS[_settings_client.gui.linkgraph_colours][_linkstat_colours_in_legenda[i - _smallmap_cargo_count]];
240 _legend_linkstats[i].show_on_map = true;
241 }
242
243 _legend_linkstats[_smallmap_cargo_count].legend = STR_LINKGRAPH_LEGEND_UNUSED;
244 _legend_linkstats[i - 1].legend = STR_LINKGRAPH_LEGEND_OVERLOADED;
245 _legend_linkstats[(_smallmap_cargo_count + i - 1) / 2].legend = STR_LINKGRAPH_LEGEND_SATURATED;
246 _legend_linkstats[i].end = true;
247}
248
249static const LegendAndColour * const _legend_table[] = {
250 _legend_land_contours,
251 _legend_vehicles,
252 _legend_from_industries,
253 _legend_linkstats,
254 _legend_routes,
255 _legend_vegetation,
256 _legend_land_owners,
257};
258
259#define MKCOLOUR(x) TO_LE32(x)
260
261#define MKCOLOUR_XXXX(x) (MKCOLOUR(0x01010101) * (uint)(x.p))
262#define MKCOLOUR_0XX0(x) (MKCOLOUR(0x00010100) * (uint)(x.p))
263#define MKCOLOUR_X00X(x) (MKCOLOUR(0x01000001) * (uint)(x.p))
264
265#define MKCOLOUR_XYYX(x, y) (MKCOLOUR_X00X(x) | MKCOLOUR_0XX0(y))
266
267#define MKCOLOUR_0000 MKCOLOUR_XXXX(PixelColour{0x00})
268#define MKCOLOUR_F00F MKCOLOUR_X00X(PixelColour{0xFF})
269#define MKCOLOUR_FFFF MKCOLOUR_XXXX(PixelColour{0xFF})
270
271#include "table/heightmap_colours.h"
272
274 struct SmallMapColourScheme {
275 std::vector<uint32_t> height_colours;
276 std::span<const uint32_t> height_colours_base;
277 uint32_t default_colour;
278};
279
281 static SmallMapColourScheme _heightmap_schemes[] = {
282 {{}, _green_map_heights, MKCOLOUR_XXXX(PixelColour{0x54})},
283 {{}, _dark_green_map_heights, MKCOLOUR_XXXX(PixelColour{0x62})},
284 {{}, _violet_map_heights, MKCOLOUR_XXXX(PixelColour{0x81})},
285};
286
290 void BuildLandLegend()
291{
292 /* The smallmap window has never been initialized, so no need to change the legend. */
293 if (_heightmap_schemes[0].height_colours.empty()) return;
294
295 /*
296 * The general idea of this function is to fill the legend with an appropriate evenly spaced
297 * selection of height levels. All entries with STR_TINY_BLACK_HEIGHT are reserved for this.
298 * At the moment there are twelve of these.
299 *
300 * The table below defines up to which height level a particular delta in the legend should be
301 * used. One could opt for just dividing the maximum height and use that as delta, but that
302 * creates many "ugly" legend labels, e.g. once every 950 meter. As a result, this table will
303 * reduce the number of deltas to 7: every 100m, 200m, 300m, 500m, 750m, 1000m and 1250m. The
304 * deltas are closer together at the lower numbers because going from 12 entries to just 4, as
305 * would happen when replacing 200m and 300m by 250m, would mean the legend would be short and
306 * that might not be considered appropriate.
307 *
308 * The current method yields at least 7 legend entries and at most 12. It can be increased to
309 * 8 by adding a 150m and 400m option, but especially 150m creates ugly heights.
310 *
311 * It tries to evenly space the legend items over the two columns that are there for the legend.
312 */
313
314 /* Table for delta; if max_height is less than the first column, use the second column as value. */
315 uint deltas[][2] = { { 24, 2 }, { 48, 4 }, { 72, 6 }, { 120, 10 }, { 180, 15 }, { 240, 20 }, { MAX_TILE_HEIGHT + 1, 25 }};
316 uint i = 0;
317 for (; _settings_game.construction.map_height_limit >= deltas[i][0]; i++) {
318 /* Nothing to do here. */
319 }
320 uint delta = deltas[i][1];
321
322 int total_entries = (_settings_game.construction.map_height_limit / delta) + 1;
323 int rows = CeilDiv(total_entries, 2);
324 int j = 0;
325
326 for (i = 0; i < lengthof(_legend_land_contours) - 1 && j < total_entries; i++) {
327 if (_legend_land_contours[i].legend != STR_TINY_BLACK_HEIGHT) continue;
328
329 _legend_land_contours[i].col_break = j % rows == 0;
330 _legend_land_contours[i].end = false;
331 _legend_land_contours[i].height = j * delta;
332 _legend_land_contours[i].colour = PixelColour{static_cast<uint8_t>(_heightmap_schemes[_settings_client.gui.smallmap_land_colour].height_colours[_legend_land_contours[i].height])};
333 j++;
334 }
335 _legend_land_contours[i].end = true;
336}
337
341 void BuildOwnerLegend()
342{
343 _legend_land_owners[1].colour = PixelColour{static_cast<uint8_t>(_heightmap_schemes[_settings_client.gui.smallmap_land_colour].default_colour)};
344
345 int i = NUM_NO_COMPANY_ENTRIES;
346 for (const Company *c : Company::Iterate()) {
347 _legend_land_owners[i].colour = GetColourGradient(c->colour, SHADE_LIGHT);
348 _legend_land_owners[i].company = c->index;
349 _legend_land_owners[i].show_on_map = true;
350 _legend_land_owners[i].col_break = false;
351 _legend_land_owners[i].end = false;
352 _company_to_list_pos[c->index] = i;
353 i++;
354 }
355
356 /* Terminate the list */
357 _legend_land_owners[i].end = true;
358
359 /* Store maximum amount of owner legend entries. */
360 _smallmap_company_count = i;
361}
362
363 struct AndOr {
364 uint32_t mor;
365 uint32_t mand;
366};
367
368static inline uint32_t ApplyMask(uint32_t colour, const AndOr *mask)
369{
370 return (colour & mask->mand) | mask->mor;
371}
372
373
375 static const AndOr _smallmap_contours_andor[] = {
376 {MKCOLOUR_0000 , MKCOLOUR_FFFF}, // MP_CLEAR
377 {MKCOLOUR_0XX0(PC_GREY ), MKCOLOUR_F00F}, // MP_RAILWAY
378 {MKCOLOUR_0XX0(PC_BLACK ), MKCOLOUR_F00F}, // MP_ROAD
379 {MKCOLOUR_0XX0(PC_DARK_RED ), MKCOLOUR_F00F}, // MP_HOUSE
380 {MKCOLOUR_0000 , MKCOLOUR_FFFF}, // MP_TREES
381 {MKCOLOUR_XXXX(PC_LIGHT_BLUE), MKCOLOUR_0000}, // MP_STATION
382 {MKCOLOUR_XXXX(PC_WATER ), MKCOLOUR_0000}, // MP_WATER
383 {MKCOLOUR_0000 , MKCOLOUR_FFFF}, // MP_VOID
384 {MKCOLOUR_XXXX(PC_DARK_RED ), MKCOLOUR_0000}, // MP_INDUSTRY
385 {MKCOLOUR_0000 , MKCOLOUR_FFFF}, // MP_TUNNELBRIDGE
386 {MKCOLOUR_0XX0(PC_DARK_RED ), MKCOLOUR_F00F}, // MP_OBJECT
387 {MKCOLOUR_0XX0(PC_GREY ), MKCOLOUR_F00F},
388};
389
391 static const AndOr _smallmap_vehicles_andor[] = {
392 {MKCOLOUR_0000 , MKCOLOUR_FFFF}, // MP_CLEAR
393 {MKCOLOUR_0XX0(PC_BLACK ), MKCOLOUR_F00F}, // MP_RAILWAY
394 {MKCOLOUR_0XX0(PC_BLACK ), MKCOLOUR_F00F}, // MP_ROAD
395 {MKCOLOUR_0XX0(PC_DARK_RED ), MKCOLOUR_F00F}, // MP_HOUSE
396 {MKCOLOUR_0000 , MKCOLOUR_FFFF}, // MP_TREES
397 {MKCOLOUR_0XX0(PC_BLACK ), MKCOLOUR_F00F}, // MP_STATION
398 {MKCOLOUR_XXXX(PC_WATER ), MKCOLOUR_0000}, // MP_WATER
399 {MKCOLOUR_0000 , MKCOLOUR_FFFF}, // MP_VOID
400 {MKCOLOUR_XXXX(PC_DARK_RED ), MKCOLOUR_0000}, // MP_INDUSTRY
401 {MKCOLOUR_0000 , MKCOLOUR_FFFF}, // MP_TUNNELBRIDGE
402 {MKCOLOUR_0XX0(PC_DARK_RED ), MKCOLOUR_F00F}, // MP_OBJECT
403 {MKCOLOUR_0XX0(PC_BLACK ), MKCOLOUR_F00F},
404};
405
407 static const uint8_t _tiletype_importance[] = {
408 2, // MP_CLEAR
409 8, // MP_RAILWAY
410 7, // MP_ROAD
411 5, // MP_HOUSE
412 2, // MP_TREES
413 9, // MP_STATION
414 2, // MP_WATER
415 1, // MP_VOID
416 6, // MP_INDUSTRY
417 8, // MP_TUNNELBRIDGE
418 2, // MP_OBJECT
419 0,
420};
421
422
429 static inline uint32_t GetSmallMapContoursPixels(TileIndex tile, TileType t)
430{
431 const SmallMapColourScheme *cs = &_heightmap_schemes[_settings_client.gui.smallmap_land_colour];
432 return ApplyMask(cs->height_colours[TileHeight(tile)], &_smallmap_contours_andor[t]);
433}
434
442 static inline uint32_t GetSmallMapVehiclesPixels(TileIndex, TileType t)
443{
444 const SmallMapColourScheme *cs = &_heightmap_schemes[_settings_client.gui.smallmap_land_colour];
445 return ApplyMask(cs->default_colour, &_smallmap_vehicles_andor[t]);
446}
447
455 static inline uint32_t GetSmallMapIndustriesPixels(TileIndex tile, TileType t)
456{
457 const SmallMapColourScheme *cs = &_heightmap_schemes[_settings_client.gui.smallmap_land_colour];
458 return ApplyMask(_smallmap_show_heightmap ? cs->height_colours[TileHeight(tile)] : cs->default_colour, &_smallmap_vehicles_andor[t]);
459}
460
468 static inline uint32_t GetSmallMapRoutesPixels(TileIndex tile, TileType t)
469{
470 switch (t) {
471 case MP_STATION:
472 switch (GetStationType(tile)) {
473 case StationType::Rail: return MKCOLOUR_XXXX(PC_VERY_DARK_BROWN);
474 case StationType::Airport: return MKCOLOUR_XXXX(PC_RED);
475 case StationType::Truck: return MKCOLOUR_XXXX(PC_ORANGE);
476 case StationType::Bus: return MKCOLOUR_XXXX(PC_YELLOW);
477 case StationType::Dock: return MKCOLOUR_XXXX(PC_LIGHT_BLUE);
478 default: return MKCOLOUR_FFFF;
479 }
480
481 case MP_RAILWAY: {
482 AndOr andor = {
483 MKCOLOUR_0XX0(GetRailTypeInfo(GetRailType(tile))->map_colour),
484 _smallmap_contours_andor[t].mand
485 };
486
487 const SmallMapColourScheme *cs = &_heightmap_schemes[_settings_client.gui.smallmap_land_colour];
488 return ApplyMask(cs->default_colour, &andor);
489 }
490
491 case MP_ROAD: {
492 const RoadTypeInfo *rti = nullptr;
493 if (GetRoadTypeRoad(tile) != INVALID_ROADTYPE) {
494 rti = GetRoadTypeInfo(GetRoadTypeRoad(tile));
495 } else {
496 rti = GetRoadTypeInfo(GetRoadTypeTram(tile));
497 }
498 if (rti != nullptr) {
499 AndOr andor = {
500 MKCOLOUR_0XX0(rti->map_colour),
501 _smallmap_contours_andor[t].mand
502 };
503
504 const SmallMapColourScheme *cs = &_heightmap_schemes[_settings_client.gui.smallmap_land_colour];
505 return ApplyMask(cs->default_colour, &andor);
506 }
507 [[fallthrough]];
508 }
509
510 default:
511 /* Ground colour */
512 const SmallMapColourScheme *cs = &_heightmap_schemes[_settings_client.gui.smallmap_land_colour];
513 return ApplyMask(cs->default_colour, &_smallmap_contours_andor[t]);
514 }
515}
516
524 static inline uint32_t GetSmallMapLinkStatsPixels(TileIndex tile, TileType t)
525{
526 return _smallmap_show_heightmap ? GetSmallMapContoursPixels(tile, t) : GetSmallMapRoutesPixels(tile, t);
527}
528
529static const uint32_t _vegetation_clear_bits[] = {
530 MKCOLOUR_XXXX(PC_GRASS_LAND),
531 MKCOLOUR_XXXX(PC_ROUGH_LAND),
532 MKCOLOUR_XXXX(PC_GREY),
533 MKCOLOUR_XXXX(PC_FIELDS),
534 MKCOLOUR_XXXX(PC_LIGHT_BLUE),
535 MKCOLOUR_XXXX(PC_ORANGE),
536 MKCOLOUR_XXXX(PC_GRASS_LAND),
537 MKCOLOUR_XXXX(PC_GRASS_LAND),
538};
539
547 static inline uint32_t GetSmallMapVegetationPixels(TileIndex tile, TileType t)
548{
549 switch (t) {
550 case MP_CLEAR:
551 if (IsClearGround(tile, CLEAR_GRASS)) {
552 if (GetClearDensity(tile) < 3) return MKCOLOUR_XXXX(PC_BARE_LAND);
553 if (GetTropicZone(tile) == TROPICZONE_RAINFOREST) return MKCOLOUR_XXXX(PC_RAINFOREST);
554 }
555 return _vegetation_clear_bits[IsSnowTile(tile) ? CLEAR_SNOW : GetClearGround(tile)];
556
557 case MP_INDUSTRY:
558 return IsTileForestIndustry(tile) ? MKCOLOUR_XXXX(PC_GREEN) : MKCOLOUR_XXXX(PC_DARK_RED);
559
560 case MP_TREES:
561 if (GetTreeGround(tile) == TREE_GROUND_SNOW_DESERT || GetTreeGround(tile) == TREE_GROUND_ROUGH_SNOW) {
562 return (_settings_game.game_creation.landscape == LandscapeType::Arctic) ? MKCOLOUR_XYYX(PC_LIGHT_BLUE, PC_TREES) : MKCOLOUR_XYYX(PC_ORANGE, PC_TREES);
563 }
564 return (GetTropicZone(tile) == TROPICZONE_RAINFOREST) ? MKCOLOUR_XYYX(PC_RAINFOREST, PC_TREES) : MKCOLOUR_XYYX(PC_GRASS_LAND, PC_TREES);
565
566 default:
567 return ApplyMask(MKCOLOUR_XXXX(PC_GRASS_LAND), &_smallmap_vehicles_andor[t]);
568 }
569}
570
580uint32_t GetSmallMapOwnerPixels(TileIndex tile, TileType t, IncludeHeightmap include_heightmap)
581{
582 Owner o;
583
584 switch (t) {
585 case MP_VOID: return MKCOLOUR_XXXX(PC_BLACK);
586 case MP_INDUSTRY: return MKCOLOUR_XXXX(PC_DARK_GREY);
587 case MP_HOUSE: return MKCOLOUR_XXXX(PC_DARK_RED);
588 case MP_ROAD:
589 o = GetRoadOwner(tile, HasRoadTypeRoad(tile) ? RTT_ROAD : RTT_TRAM);
590 break;
591
592 default:
593 o = GetTileOwner(tile);
594 break;
595 }
596
597 if ((o < MAX_COMPANIES && !_legend_land_owners[_company_to_list_pos[o]].show_on_map) || o == OWNER_NONE || o == OWNER_WATER) {
598 if (t == MP_WATER) return MKCOLOUR_XXXX(PC_WATER);
599 const SmallMapColourScheme *cs = &_heightmap_schemes[_settings_client.gui.smallmap_land_colour];
600 return ((include_heightmap == IncludeHeightmap::IfEnabled && _smallmap_show_heightmap) || include_heightmap == IncludeHeightmap::Always)
601 ? cs->height_colours[TileHeight(tile)] : cs->default_colour;
602 } else if (o == OWNER_TOWN) {
603 return MKCOLOUR_XXXX(PC_DARK_RED);
604 }
605
606 return MKCOLOUR_XXXX(_legend_land_owners[_company_to_list_pos[o]].colour);
607}
608
610 static const PixelColour _vehicle_type_colours[6] = {
611 PC_RED, PC_YELLOW, PC_LIGHT_BLUE, PC_WHITE, PC_BLACK, PC_RED
612};
613
615 enum SmallMapType : uint8_t {
616 SMT_CONTOUR,
617 SMT_VEHICLES,
618 SMT_INDUSTRY,
619 SMT_LINKSTATS,
620 SMT_ROUTES,
621 SMT_VEGETATION,
622 SMT_OWNER,
623};
624 DECLARE_ENUM_AS_ADDABLE(SmallMapType)
625
626
627class SmallMapWindow : public Window {
628protected:
630 enum ZoomLevelChange : uint8_t {
631 ZLC_INITIALIZE,
632 ZLC_ZOOM_OUT,
633 ZLC_ZOOM_IN,
634 };
635
636 static SmallMapType map_type;
637 static bool show_towns;
638 static bool show_ind_names;
639 static int map_height_limit;
640
641 static const uint INDUSTRY_MIN_NUMBER_OF_COLUMNS = 2;
642
643 uint min_number_of_columns = 0;
644 uint min_number_of_fixed_rows = 0;
645 uint column_width = 0;
646 uint legend_width = 0;
647
648 int32_t scroll_x = 0;
649 int32_t scroll_y = 0;
650 int32_t subscroll = 0;
651 int zoom = 0;
652
653 std::unique_ptr<LinkGraphOverlay> overlay{};
654
656 static void BreakIndustryChainLink()
657 {
658 InvalidateWindowClassesData(WC_INDUSTRY_CARGOES, NUM_INDUSTRYTYPES);
659 }
660
661 static inline Point SmallmapRemapCoords(int x, int y)
662 {
663 Point pt;
664 pt.x = (y - x) * 2;
665 pt.y = y + x;
666 return pt;
667 }
668
675 static inline void DrawVertMapIndicator(int x, int y, int y2)
676 {
677 GfxFillRect(x, y, x, y + 3, PC_VERY_LIGHT_YELLOW);
678 GfxFillRect(x, y2 - 3, x, y2, PC_VERY_LIGHT_YELLOW);
679 }
680
687 static inline void DrawHorizMapIndicator(int x, int x2, int y)
688 {
689 GfxFillRect(x, y, x + 3, y, PC_VERY_LIGHT_YELLOW);
690 GfxFillRect(x2 - 3, y, x2, y, PC_VERY_LIGHT_YELLOW);
691 }
692
697 inline uint GetMinLegendWidth() const
698 {
699 return WidgetDimensions::scaled.framerect.left + this->min_number_of_columns * this->column_width;
700 }
701
706 inline uint GetNumberColumnsLegend(uint width) const
707 {
708 return width / this->column_width;
709 }
710
716 inline uint GetLegendHeight(uint num_columns) const
717 {
718 return WidgetDimensions::scaled.framerect.Vertical() +
719 this->GetNumberRowsLegend(num_columns) * GetCharacterHeight(FS_SMALL);
720 }
721
727 inline CompanyMask GetOverlayCompanyMask() const
728 {
729 return Company::IsValidID(_local_company) ? CompanyMask{}.Set(_local_company) : CompanyMask{}.Set();
730 }
731
733 const IntervalTimer<TimerWindow> blink_interval = {TIMER_BLINK_INTERVAL, [this](auto) {
734 Blink();
735 }};
736
738 const IntervalTimer<TimerWindow> refresh_interval = {std::chrono::milliseconds(930), [this](auto) {
739 ForceRefresh();
740 }};
741
745 void RebuildColourIndexIfNecessary()
746 {
747 /* Rebuild colour indices if necessary. */
748 if (SmallMapWindow::map_height_limit == _settings_game.construction.map_height_limit) return;
749
750 for (auto &heightmap_scheme : _heightmap_schemes) {
751 /* The heights go from 0 up to and including maximum. */
752 size_t heights = _settings_game.construction.map_height_limit + 1;
753 heightmap_scheme.height_colours.resize(heights);
754
755 for (size_t z = 0; z < heights; z++) {
756 size_t access_index = (heightmap_scheme.height_colours_base.size() * z) / heights;
757
758 /* Choose colour by mapping the range (0..max heightlevel) on the complete colour table. */
759 heightmap_scheme.height_colours[z] = heightmap_scheme.height_colours_base[access_index];
760 }
761 }
762
763 SmallMapWindow::map_height_limit = _settings_game.construction.map_height_limit;
764 BuildLandLegend();
765 }
766
775 uint GetNumberRowsLegend(uint columns) const
776 {
777 /* Reserve one column for link colours */
778 uint num_rows_linkstats = CeilDiv(_smallmap_cargo_count, columns - 1);
779 uint num_rows_others = CeilDiv(std::max(_smallmap_industry_count, _smallmap_company_count), columns);
780 return std::max({this->min_number_of_fixed_rows, num_rows_linkstats, num_rows_others});
781 }
782
794 void SelectLegendItem(int click_pos, LegendAndColour *legend, int end_legend_item, int begin_legend_item = 0)
795 {
796 if (_ctrl_pressed) {
797 /* Disable all, except the clicked one */
798 bool changes = false;
799 for (int i = begin_legend_item; i != end_legend_item; i++) {
800 bool new_state = (i == click_pos);
801 if (legend[i].show_on_map != new_state) {
802 changes = true;
803 legend[i].show_on_map = new_state;
804 }
805 }
806 if (!changes) {
807 /* Nothing changed? Then show all (again). */
808 for (int i = begin_legend_item; i != end_legend_item; i++) {
809 legend[i].show_on_map = true;
810 }
811 }
812 } else {
813 legend[click_pos].show_on_map = !legend[click_pos].show_on_map;
814 }
815
816 if (this->map_type == SMT_INDUSTRY) this->BreakIndustryChainLink();
817 }
818
823 void SwitchMapType(SmallMapType map_type)
824 {
825 this->RaiseWidget(WID_SM_CONTOUR + this->map_type);
826 this->map_type = map_type;
827 this->LowerWidget(WID_SM_CONTOUR + this->map_type);
828
829 this->SetupWidgetData();
830
831 if (map_type == SMT_LINKSTATS) this->overlay->SetDirty();
832 if (map_type != SMT_INDUSTRY) this->BreakIndustryChainLink();
833 this->ReInit();
834 }
835
843 void SetNewScroll(int sx, int sy, int sub)
844 {
845 const NWidgetBase *wi = this->GetWidget<NWidgetBase>(WID_SM_MAP);
846 Point hv = InverseRemapCoords(wi->current_x * ZOOM_BASE * TILE_SIZE / 2, wi->current_y * ZOOM_BASE * TILE_SIZE / 2);
847 hv.x *= this->zoom;
848 hv.y *= this->zoom;
849
850 if (sx < -hv.x) {
851 sx = -hv.x;
852 sub = 0;
853 }
854 if (sx > (int)(Map::MaxX() * TILE_SIZE) - hv.x) {
855 sx = Map::MaxX() * TILE_SIZE - hv.x;
856 sub = 0;
857 }
858 if (sy < -hv.y) {
859 sy = -hv.y;
860 sub = 0;
861 }
862 if (sy > (int)(Map::MaxY() * TILE_SIZE) - hv.y) {
863 sy = Map::MaxY() * TILE_SIZE - hv.y;
864 sub = 0;
865 }
866
867 this->scroll_x = sx;
868 this->scroll_y = sy;
869 this->subscroll = sub;
870 if (this->map_type == SMT_LINKSTATS) this->overlay->SetDirty();
871 }
872
876 void DrawMapIndicators() const
877 {
878 /* Find main viewport. */
879 const Viewport &vp = *GetMainWindow()->viewport;
880
881 Point upper_left_smallmap_coord = InverseRemapCoords2(vp.virtual_left, vp.virtual_top);
882 Point lower_right_smallmap_coord = InverseRemapCoords2(vp.virtual_left + vp.virtual_width - 1, vp.virtual_top + vp.virtual_height - 1);
883
884 Point upper_left = this->RemapTile(upper_left_smallmap_coord.x / (int)TILE_SIZE, upper_left_smallmap_coord.y / (int)TILE_SIZE);
885 upper_left.x -= this->subscroll;
886
887 Point lower_right = this->RemapTile(lower_right_smallmap_coord.x / (int)TILE_SIZE, lower_right_smallmap_coord.y / (int)TILE_SIZE);
888 lower_right.x -= this->subscroll;
889
890 SmallMapWindow::DrawVertMapIndicator(upper_left.x, upper_left.y, lower_right.y);
891 SmallMapWindow::DrawVertMapIndicator(lower_right.x, upper_left.y, lower_right.y);
892
893 SmallMapWindow::DrawHorizMapIndicator(upper_left.x, lower_right.x, upper_left.y);
894 SmallMapWindow::DrawHorizMapIndicator(upper_left.x, lower_right.x, lower_right.y);
895 }
896
910 void DrawSmallMapColumn(void *dst, uint xc, uint yc, int pitch, int reps, int start_pos, int end_pos, Blitter *blitter) const
911 {
912 void *dst_ptr_abs_end = blitter->MoveTo(_screen.dst_ptr, 0, _screen.height);
913 uint min_xy = _settings_game.construction.freeform_edges ? 1 : 0;
914
915 do {
916 /* Check if the tile (xc,yc) is within the map range */
917 if (xc >= Map::MaxX() || yc >= Map::MaxY()) continue;
918
919 /* Check if the dst pointer points to a pixel inside the screen buffer */
920 if (dst < _screen.dst_ptr) continue;
921 if (dst >= dst_ptr_abs_end) continue;
922
923 /* Construct tilearea covered by (xc, yc, xc + this->zoom, yc + this->zoom) such that it is within min_xy limits. */
924 TileArea ta;
925 if (min_xy == 1 && (xc == 0 || yc == 0)) {
926 if (this->zoom == 1) continue; // The tile area is empty, don't draw anything.
927
928 ta = TileArea(TileXY(std::max(min_xy, xc), std::max(min_xy, yc)), this->zoom - (xc == 0), this->zoom - (yc == 0));
929 } else {
930 ta = TileArea(TileXY(xc, yc), this->zoom, this->zoom);
931 }
932 ta.ClampToMap(); // Clamp to map boundaries (may contain MP_VOID tiles!).
933
934 uint32_t val = this->GetTileColours(ta);
935 uint8_t *val8 = (uint8_t *)&val;
936 int idx = std::max(0, -start_pos);
937 for (int pos = std::max(0, start_pos); pos < end_pos; pos++) {
938 blitter->SetPixel(dst, idx, 0, PixelColour{val8[idx]});
939 idx++;
940 }
941 /* Switch to next tile in the column */
942 } while (xc += this->zoom, yc += this->zoom, dst = blitter->MoveTo(dst, pitch, 0), --reps != 0);
943 }
944
950 void DrawVehicles(const DrawPixelInfo *dpi, Blitter *blitter) const
951 {
952 for (const Vehicle *v : Vehicle::Iterate()) {
953 if (v->type == VEH_EFFECT) continue;
954 if (v->vehstatus.Any({VehState::Hidden, VehState::Unclickable})) continue;
955
956 /* Remap into flat coordinates. */
957 Point pt = this->RemapTile(v->x_pos / (int)TILE_SIZE, v->y_pos / (int)TILE_SIZE);
958
959 int y = pt.y - dpi->top;
960 if (!IsInsideMM(y, 0, dpi->height)) continue; // y is out of bounds.
961
962 bool skip = false; // Default is to draw both pixels.
963 int x = pt.x - this->subscroll - 3 - dpi->left; // Offset X coordinate.
964 if (x < 0) {
965 /* if x+1 is 0, that means we're on the very left edge,
966 * and should thus only draw a single pixel */
967 if (++x != 0) continue;
968 skip = true;
969 } else if (x >= dpi->width - 1) {
970 /* Check if we're at the very right edge, and if so draw only a single pixel */
971 if (x != dpi->width - 1) continue;
972 skip = true;
973 }
974
975 /* Calculate pointer to pixel and the colour */
976 PixelColour colour = (this->map_type == SMT_VEHICLES) ? _vehicle_type_colours[v->type] : PC_WHITE;
977
978 /* And draw either one or two pixels depending on clipping */
979 blitter->SetPixel(dpi->dst_ptr, x, y, colour);
980 if (!skip) blitter->SetPixel(dpi->dst_ptr, x + 1, y, colour);
981 }
982 }
983
988 void DrawTowns(const DrawPixelInfo *dpi, const int vertical_padding) const
989 {
990 for (const Town *t : Town::Iterate()) {
991 /* Remap the town coordinate */
992 Point pt = this->RemapTile(TileX(t->xy), TileY(t->xy));
993 int x = pt.x - this->subscroll - (t->cache.sign.width_small >> 1);
994 int y = pt.y + vertical_padding;
995
996 /* Check if the town sign is within bounds */
997 if (x + t->cache.sign.width_small > dpi->left &&
998 x < dpi->left + dpi->width &&
999 y + GetCharacterHeight(FS_SMALL) > dpi->top &&
1000 y < dpi->top + dpi->height) {
1001 /* And draw it. */
1002 DrawString(x, x + t->cache.sign.width_small, y, GetString(STR_SMALLMAP_TOWN, t->index));
1003 }
1004 }
1005 }
1006
1011 void DrawIndustryNames(const DrawPixelInfo *dpi, const int vertical_padding) const
1012 {
1013 if (this->map_type != SMT_INDUSTRY) return;
1014
1015 for (const Industry *i : Industry::Iterate()) {
1016 const LegendAndColour &tbl = _legend_from_industries[_industry_to_list_pos[i->type]];
1017 if (!tbl.show_on_map) continue;
1018
1019 /* Industry names blink together with their blobs in the smallmap. */
1020 const bool is_blinking = i->type == _smallmap_industry_highlight && !_smallmap_industry_highlight_state;
1021 if (is_blinking) continue;
1022
1023 if (_industry_to_name_string_width[i->type] == 0) {
1024 _industry_to_name_string_width[i->type] = GetStringBoundingBox(tbl.legend, FS_SMALL).width;
1025 }
1026 const uint16_t &legend_text_width = _industry_to_name_string_width[i->type];
1027
1028 /* Remap the industry coordinate */
1029 const TileIndex &tile = i->location.GetCenterTile();
1030 const Point pt = this->RemapTile(TileX(tile), TileY(tile));
1031 const int x = pt.x - this->subscroll - (legend_text_width / 2);
1032 const int y = pt.y + vertical_padding;
1033
1034 /* Check if the industry name is within bounds */
1035 if (x + legend_text_width > dpi->left &&
1036 x < dpi->left + dpi->width &&
1037 y + GetCharacterHeight(FS_SMALL) > dpi->top &&
1038 y < dpi->top + dpi->height) {
1039
1040 /* And draw it. */
1041 DrawString(x, x + legend_text_width, y, tbl.legend, TC_WHITE, SA_LEFT, false, FS_SMALL);
1042 }
1043 }
1044 }
1045
1057 void DrawSmallMap(DrawPixelInfo *dpi) const
1058 {
1059 Blitter *blitter = BlitterFactory::GetCurrentBlitter();
1060 AutoRestoreBackup dpi_backup(_cur_dpi, dpi);
1061
1062 /* Clear it */
1063 GfxFillRect(dpi->left, dpi->top, dpi->left + dpi->width - 1, dpi->top + dpi->height - 1, PC_BLACK);
1064
1065 /* Which tile is displayed at (dpi->left, dpi->top)? */
1066 int dx;
1067 Point tile = this->PixelToTile(dpi->left, dpi->top, &dx);
1068 int tile_x = this->scroll_x / (int)TILE_SIZE + tile.x;
1069 int tile_y = this->scroll_y / (int)TILE_SIZE + tile.y;
1070
1071 void *ptr = blitter->MoveTo(dpi->dst_ptr, -dx - 4, 0);
1072 int x = - dx - 4;
1073 int y = 0;
1074
1075 for (;;) {
1076 /* Distance from left edge */
1077 if (x >= -3) {
1078 if (x >= dpi->width) break; // Exit the loop.
1079
1080 int end_pos = std::min(dpi->width, x + 4);
1081 int reps = (dpi->height - y + 1) / 2; // Number of lines.
1082 if (reps > 0) {
1083 this->DrawSmallMapColumn(ptr, tile_x, tile_y, dpi->pitch * 2, reps, x, end_pos, blitter);
1084 }
1085 }
1086
1087 if (y == 0) {
1088 tile_y += this->zoom;
1089 y++;
1090 ptr = blitter->MoveTo(ptr, 0, 1);
1091 } else {
1092 tile_x -= this->zoom;
1093 y--;
1094 ptr = blitter->MoveTo(ptr, 0, -1);
1095 }
1096 ptr = blitter->MoveTo(ptr, 2, 0);
1097 x += 2;
1098 }
1099
1100 /* Draw vehicles */
1101 if (this->map_type == SMT_CONTOUR || this->map_type == SMT_VEHICLES) this->DrawVehicles(dpi, blitter);
1102
1103 /* Draw link stat overlay */
1104 if (this->map_type == SMT_LINKSTATS) this->overlay->Draw(dpi);
1105
1106 const int map_labels_vertical_padding = ScaleGUITrad(2);
1107
1108 /* Draw town names */
1109 if (this->show_towns) this->DrawTowns(dpi, map_labels_vertical_padding);
1110
1111 /* Draw industry names */
1112 if (this->show_ind_names) this->DrawIndustryNames(dpi, map_labels_vertical_padding);
1113
1114 /* Draw map indicators */
1115 this->DrawMapIndicators();
1116 }
1117
1124 Point RemapTile(int tile_x, int tile_y) const
1125 {
1126 int x_offset = tile_x - this->scroll_x / (int)TILE_SIZE;
1127 int y_offset = tile_y - this->scroll_y / (int)TILE_SIZE;
1128
1129 if (this->zoom == 1) return SmallmapRemapCoords(x_offset, y_offset);
1130
1131 /* For negative offsets, round towards -inf. */
1132 if (x_offset < 0) x_offset -= this->zoom - 1;
1133 if (y_offset < 0) y_offset -= this->zoom - 1;
1134
1135 return SmallmapRemapCoords(x_offset / this->zoom, y_offset / this->zoom);
1136 }
1137
1148 Point PixelToTile(int px, int py, int *sub, bool add_sub = true) const
1149 {
1150 if (add_sub) px += this->subscroll; // Total horizontal offset.
1151
1152 /* For each two rows down, add a x and a y tile, and
1153 * For each four pixels to the right, move a tile to the right. */
1154 Point pt = {((py >> 1) - (px >> 2)) * this->zoom, ((py >> 1) + (px >> 2)) * this->zoom};
1155 px &= 3;
1156
1157 if (py & 1) { // Odd number of rows, handle the 2 pixel shift.
1158 if (px < 2) {
1159 pt.x += this->zoom;
1160 px += 2;
1161 } else {
1162 pt.y += this->zoom;
1163 px -= 2;
1164 }
1165 }
1166
1167 *sub = px;
1168 return pt;
1169 }
1170
1180 Point ComputeScroll(int tx, int ty, int x, int y, int *sub) const
1181 {
1182 assert(x >= 0 && y >= 0);
1183
1184 int new_sub;
1185 Point tile_xy = PixelToTile(x, y, &new_sub, false);
1186 tx -= tile_xy.x;
1187 ty -= tile_xy.y;
1188
1189 Point scroll;
1190 if (new_sub == 0) {
1191 *sub = 0;
1192 scroll.x = (tx + this->zoom) * TILE_SIZE;
1193 scroll.y = (ty - this->zoom) * TILE_SIZE;
1194 } else {
1195 *sub = 4 - new_sub;
1196 scroll.x = (tx + 2 * this->zoom) * TILE_SIZE;
1197 scroll.y = (ty - 2 * this->zoom) * TILE_SIZE;
1198 }
1199 return scroll;
1200 }
1201
1208 void SetZoomLevel(ZoomLevelChange change, const Point *zoom_pt)
1209 {
1210 static const int zoomlevels[] = {1, 2, 4, 6, 8}; // Available zoom levels. Bigger number means more zoom-out (further away).
1211 static const int MIN_ZOOM_INDEX = 0;
1212 static const int MAX_ZOOM_INDEX = lengthof(zoomlevels) - 1;
1213
1214 int new_index, cur_index, sub;
1215 Point tile;
1216 switch (change) {
1217 case ZLC_INITIALIZE:
1218 cur_index = - 1; // Definitely different from new_index.
1219 new_index = MIN_ZOOM_INDEX;
1220 tile.x = tile.y = 0;
1221 break;
1222
1223 case ZLC_ZOOM_IN:
1224 case ZLC_ZOOM_OUT:
1225 for (cur_index = MIN_ZOOM_INDEX; cur_index <= MAX_ZOOM_INDEX; cur_index++) {
1226 if (this->zoom == zoomlevels[cur_index]) break;
1227 }
1228 assert(cur_index <= MAX_ZOOM_INDEX);
1229
1230 tile = this->PixelToTile(zoom_pt->x, zoom_pt->y, &sub);
1231 new_index = Clamp(cur_index + ((change == ZLC_ZOOM_IN) ? -1 : 1), MIN_ZOOM_INDEX, MAX_ZOOM_INDEX);
1232 break;
1233
1234 default: NOT_REACHED();
1235 }
1236
1237 if (new_index != cur_index) {
1238 this->zoom = zoomlevels[new_index];
1239 if (cur_index >= 0) {
1240 Point new_tile = this->PixelToTile(zoom_pt->x, zoom_pt->y, &sub);
1241 this->SetNewScroll(this->scroll_x + (tile.x - new_tile.x) * TILE_SIZE,
1242 this->scroll_y + (tile.y - new_tile.y) * TILE_SIZE, sub);
1243 } else if (this->map_type == SMT_LINKSTATS) {
1244 this->overlay->SetDirty();
1245 }
1246 this->SetWidgetDisabledState(WID_SM_ZOOM_IN, this->zoom == zoomlevels[MIN_ZOOM_INDEX]);
1247 this->SetWidgetDisabledState(WID_SM_ZOOM_OUT, this->zoom == zoomlevels[MAX_ZOOM_INDEX]);
1248 this->SetDirty();
1249 }
1250 }
1251
1255 void SetOverlayCargoMask()
1256 {
1257 CargoTypes cargo_mask = 0;
1258 for (int i = 0; i != _smallmap_cargo_count; ++i) {
1259 if (_legend_linkstats[i].show_on_map) SetBit(cargo_mask, _legend_linkstats[i].type);
1260 }
1261 this->overlay->SetCargoMask(cargo_mask);
1262 }
1263
1267 void SetupWidgetData()
1268 {
1269 StringID legend_tooltip;
1270 StringID enable_all_tooltip;
1271 StringID disable_all_tooltip;
1272 int industry_names_select_plane;
1273 int select_buttons_plane;
1274 switch (this->map_type) {
1275 case SMT_INDUSTRY:
1276 legend_tooltip = STR_SMALLMAP_TOOLTIP_INDUSTRY_SELECTION;
1277 enable_all_tooltip = STR_SMALLMAP_TOOLTIP_ENABLE_ALL_INDUSTRIES;
1278 disable_all_tooltip = STR_SMALLMAP_TOOLTIP_DISABLE_ALL_INDUSTRIES;
1279 industry_names_select_plane = 0;
1280 select_buttons_plane = 0;
1281 break;
1282
1283 case SMT_OWNER:
1284 legend_tooltip = STR_SMALLMAP_TOOLTIP_COMPANY_SELECTION;
1285 enable_all_tooltip = STR_SMALLMAP_TOOLTIP_ENABLE_ALL_COMPANIES;
1286 disable_all_tooltip = STR_SMALLMAP_TOOLTIP_DISABLE_ALL_COMPANIES;
1287 industry_names_select_plane = SZSP_NONE;
1288 select_buttons_plane = 0;
1289 break;
1290
1291 case SMT_LINKSTATS:
1292 legend_tooltip = STR_SMALLMAP_TOOLTIP_CARGO_SELECTION;
1293 enable_all_tooltip = STR_SMALLMAP_TOOLTIP_ENABLE_ALL_CARGOS;
1294 disable_all_tooltip = STR_SMALLMAP_TOOLTIP_DISABLE_ALL_CARGOS;
1295 industry_names_select_plane = SZSP_NONE;
1296 select_buttons_plane = 0;
1297 break;
1298
1299 default:
1300 legend_tooltip = STR_NULL;
1301 enable_all_tooltip = STR_NULL;
1302 disable_all_tooltip = STR_NULL;
1303 industry_names_select_plane = SZSP_NONE;
1304 select_buttons_plane = 1;
1305 break;
1306 }
1307
1308 this->GetWidget<NWidgetCore>(WID_SM_LEGEND)->SetToolTip(legend_tooltip);
1309 this->GetWidget<NWidgetCore>(WID_SM_ENABLE_ALL)->SetStringTip(STR_SMALLMAP_ENABLE_ALL, enable_all_tooltip);
1310 this->GetWidget<NWidgetCore>(WID_SM_DISABLE_ALL)->SetStringTip(STR_SMALLMAP_DISABLE_ALL, disable_all_tooltip);
1311 this->GetWidget<NWidgetStacked>(WID_SM_SHOW_IND_NAMES_SEL)->SetDisplayedPlane(industry_names_select_plane);
1312 this->GetWidget<NWidgetStacked>(WID_SM_SELECT_BUTTONS)->SetDisplayedPlane(select_buttons_plane);
1313 }
1314
1320 uint32_t GetTileColours(const TileArea &ta) const
1321 {
1322 int importance = 0;
1323 TileIndex tile = INVALID_TILE; // Position of the most important tile.
1324 TileType et = MP_VOID; // Effective tile type at that position.
1325
1326 for (TileIndex ti : ta) {
1327 TileType ttype = GetTileType(ti);
1328
1329 switch (ttype) {
1330 case MP_TUNNELBRIDGE: {
1331 TransportType tt = GetTunnelBridgeTransportType(ti);
1332
1333 switch (tt) {
1334 case TRANSPORT_RAIL: ttype = MP_RAILWAY; break;
1335 case TRANSPORT_ROAD: ttype = MP_ROAD; break;
1336 default: ttype = MP_WATER; break;
1337 }
1338 break;
1339 }
1340
1341 case MP_INDUSTRY:
1342 /* Special handling of industries while in "Industries" smallmap view. */
1343 if (this->map_type == SMT_INDUSTRY) {
1344 /* If industry is allowed to be seen, use its colour on the map.
1345 * This has the highest priority above any value in _tiletype_importance. */
1346 IndustryType type = Industry::GetByTile(ti)->type;
1347 if (_legend_from_industries[_industry_to_list_pos[type]].show_on_map) {
1348 if (type == _smallmap_industry_highlight) {
1349 if (_smallmap_industry_highlight_state) return MKCOLOUR_XXXX(PC_WHITE);
1350 } else {
1351 return GetIndustrySpec(type)->map_colour.p * 0x01010101;
1352 }
1353 }
1354 /* Otherwise make it disappear */
1355 ttype = IsTileOnWater(ti) ? MP_WATER : MP_CLEAR;
1356 }
1357 break;
1358
1359 default:
1360 break;
1361 }
1362
1363 if (_tiletype_importance[ttype] > importance) {
1364 importance = _tiletype_importance[ttype];
1365 tile = ti;
1366 et = ttype;
1367 }
1368 }
1369
1370 switch (this->map_type) {
1371 case SMT_CONTOUR:
1372 return GetSmallMapContoursPixels(tile, et);
1373
1374 case SMT_VEHICLES:
1375 return GetSmallMapVehiclesPixels(tile, et);
1376
1377 case SMT_INDUSTRY:
1378 return GetSmallMapIndustriesPixels(tile, et);
1379
1380 case SMT_LINKSTATS:
1381 return GetSmallMapLinkStatsPixels(tile, et);
1382
1383 case SMT_ROUTES:
1384 return GetSmallMapRoutesPixels(tile, et);
1385
1386 case SMT_VEGETATION:
1387 return GetSmallMapVegetationPixels(tile, et);
1388
1389 case SMT_OWNER:
1390 return GetSmallMapOwnerPixels(tile, et, IncludeHeightmap::IfEnabled);
1391
1392 default: NOT_REACHED();
1393 }
1394 }
1395
1401 int GetPositionOnLegend(Point pt)
1402 {
1403 const NWidgetBase *wi = this->GetWidget<NWidgetBase>(WID_SM_LEGEND);
1404 uint line = (pt.y - wi->pos_y - WidgetDimensions::scaled.framerect.top) / GetCharacterHeight(FS_SMALL);
1405 uint columns = this->GetNumberColumnsLegend(wi->current_x);
1406 uint number_of_rows = this->GetNumberRowsLegend(columns);
1407 if (line >= number_of_rows) return -1;
1408
1409 bool rtl = _current_text_dir == TD_RTL;
1410 int x = pt.x - wi->pos_x;
1411 if (rtl) x = wi->current_x - x;
1412 uint column = (x - WidgetDimensions::scaled.framerect.left) / this->column_width;
1413
1414 return (column * number_of_rows) + line;
1415 }
1416
1418 void UpdateLinks()
1419 {
1420 if (this->map_type == SMT_LINKSTATS) {
1421 CompanyMask company_mask = this->GetOverlayCompanyMask();
1422 if (this->overlay->GetCompanyMask() != company_mask) {
1423 this->overlay->SetCompanyMask(company_mask);
1424 } else {
1425 this->overlay->SetDirty();
1426 }
1427 }
1428 }
1429
1431 void Blink()
1432 {
1433 if (_smallmap_industry_highlight == IT_INVALID) return;
1434
1435 _smallmap_industry_highlight_state = !_smallmap_industry_highlight_state;
1436
1437 this->UpdateLinks();
1438 this->SetDirty();
1439 }
1440
1442 void ForceRefresh()
1443 {
1444 if (_smallmap_industry_highlight != IT_INVALID) return;
1445
1446 this->UpdateLinks();
1447 this->SetDirty();
1448 }
1449
1450public:
1451 friend class NWidgetSmallmapDisplay;
1452
1453 SmallMapWindow(WindowDesc &desc, int window_number) : Window(desc)
1454 {
1455 _smallmap_industry_highlight = IT_INVALID;
1456 this->overlay = std::make_unique<LinkGraphOverlay>(this, WID_SM_MAP, 0, this->GetOverlayCompanyMask(), 1);
1457 this->CreateNestedTree();
1458 this->LowerWidget(WID_SM_CONTOUR + this->map_type);
1459
1460 this->RebuildColourIndexIfNecessary();
1461
1462 this->SetWidgetLoweredState(WID_SM_SHOW_HEIGHT, _smallmap_show_heightmap);
1463
1464 this->SetWidgetLoweredState(WID_SM_TOGGLETOWNNAME, this->show_towns);
1465 this->SetWidgetLoweredState(WID_SM_SHOW_IND_NAMES, this->show_ind_names);
1466
1467 this->SetupWidgetData();
1468 this->FinishInitNested(window_number);
1469
1470 this->SetZoomLevel(ZLC_INITIALIZE, nullptr);
1471 this->SmallMapCenterOnCurrentPos();
1472 this->SetOverlayCargoMask();
1473 }
1474
1478 void SmallMapCenterOnCurrentPos()
1479 {
1480 const Viewport &vp = *GetMainWindow()->viewport;
1481 Point viewport_center = InverseRemapCoords2(vp.virtual_left + vp.virtual_width / 2, vp.virtual_top + vp.virtual_height / 2);
1482
1483 int sub;
1484 const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_SM_MAP);
1485 Point sxy = this->ComputeScroll(viewport_center.x / (int)TILE_SIZE, viewport_center.y / (int)TILE_SIZE,
1486 std::max(0, (int)wid->current_x / 2 - 2), wid->current_y / 2, &sub);
1487 this->SetNewScroll(sxy.x, sxy.y, sub);
1488 this->SetDirty();
1489 }
1490
1496 Point GetStationMiddle(const Station *st) const
1497 {
1498 int x = CentreBounds(st->rect.left, st->rect.right, 0);
1499 int y = CentreBounds(st->rect.top, st->rect.bottom, 0);
1500 Point ret = this->RemapTile(x, y);
1501
1502 /* Same magic 3 as in DrawVehicles; that's where I got it from.
1503 * No idea what it is, but without it the result looks bad.
1504 */
1505 ret.x -= 3 + this->subscroll;
1506 return ret;
1507 }
1508
1509 void Close([[maybe_unused]] int data) override
1510 {
1511 this->BreakIndustryChainLink();
1512 this->Window::Close();
1513 }
1514
1515 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
1516 {
1517 switch (widget) {
1518 case WID_SM_CAPTION:
1519 return GetString(STR_SMALLMAP_CAPTION, STR_SMALLMAP_TYPE_CONTOURS + this->map_type);
1520
1521 default:
1522 return this->Window::GetWidgetString(widget, stringid);
1523 }
1524 }
1525
1526 void OnInit() override
1527 {
1528 uint min_width = 0;
1529 this->min_number_of_columns = INDUSTRY_MIN_NUMBER_OF_COLUMNS;
1530 this->min_number_of_fixed_rows = lengthof(_linkstat_colours_in_legenda);
1531 for (uint i = 0; i < lengthof(_legend_table); i++) {
1532 uint height = 0;
1533 uint num_columns = 1;
1534 for (const LegendAndColour *tbl = _legend_table[i]; !tbl->end; ++tbl) {
1535 std::string str;
1536 if (i == SMT_INDUSTRY) {
1537 str = GetString(STR_SMALLMAP_INDUSTRY, tbl->legend, IndustryPool::MAX_SIZE);
1538 } else if (i == SMT_LINKSTATS) {
1539 str = GetString(STR_SMALLMAP_LINKSTATS, tbl->legend);
1540 } else if (i == SMT_OWNER) {
1541 if (tbl->company != CompanyID::Invalid()) {
1542 if (!Company::IsValidID(tbl->company)) {
1543 /* Rebuild the owner legend. */
1544 BuildOwnerLegend();
1545 this->OnInit();
1546 return;
1547 }
1548 /* Non-fixed legend entries for the owner view. */
1549 str = GetString(STR_SMALLMAP_COMPANY, tbl->company);
1550 } else {
1551 str = GetString(tbl->legend);
1552 }
1553 } else {
1554 if (tbl->col_break) {
1555 this->min_number_of_fixed_rows = std::max(this->min_number_of_fixed_rows, height);
1556 height = 0;
1557 num_columns++;
1558 }
1559 height++;
1560 if (i == SMT_CONTOUR) {
1561 str = GetString(tbl->legend, tbl->height * TILE_HEIGHT_STEP);
1562 } else {
1563 str = GetString(tbl->legend);
1564 }
1565 }
1566 min_width = std::max(GetStringBoundingBox(str).width, min_width);
1567 }
1568 this->min_number_of_fixed_rows = std::max(this->min_number_of_fixed_rows, height);
1569 this->min_number_of_columns = std::max(this->min_number_of_columns, num_columns);
1570 }
1571
1572 /* Width of the legend blob. */
1573 this->legend_width = GetCharacterHeight(FS_SMALL) * 9 / 6;
1574
1575 /* The width of a column is the minimum width of all texts + the size of the blob + some spacing */
1576 this->column_width = min_width + WidgetDimensions::scaled.hsep_normal + this->legend_width + WidgetDimensions::scaled.framerect.Horizontal();
1577
1578 /* Cached string widths of industry names in the smallmap. Calculation is deferred to DrawIndustryNames(). */
1579 std::fill(std::begin(_industry_to_name_string_width), std::end(_industry_to_name_string_width), 0);
1580 }
1581
1582 void OnPaint() override
1583 {
1584 if (this->map_type == SMT_OWNER) {
1585 for (const LegendAndColour *tbl = _legend_table[this->map_type]; !tbl->end; ++tbl) {
1586 if (tbl->company != CompanyID::Invalid() && !Company::IsValidID(tbl->company)) {
1587 /* Rebuild the owner legend. */
1588 BuildOwnerLegend();
1589 this->InvalidateData(1);
1590 break;
1591 }
1592 }
1593 }
1594
1595 this->DrawWidgets();
1596 }
1597
1598 void DrawWidget(const Rect &r, WidgetID widget) const override
1599 {
1600 switch (widget) {
1601 case WID_SM_MAP: {
1602 Rect ir = r.Shrink(WidgetDimensions::scaled.bevel);
1603 DrawPixelInfo new_dpi;
1604 if (!FillDrawPixelInfo(&new_dpi, ir)) return;
1605 this->DrawSmallMap(&new_dpi);
1606 break;
1607 }
1608
1609 case WID_SM_LEGEND: {
1610 uint columns = this->GetNumberColumnsLegend(r.Width());
1611 uint number_of_rows = this->GetNumberRowsLegend(columns);
1612 bool rtl = _current_text_dir == TD_RTL;
1613 uint i = 0; // Row counter for industry legend.
1614 uint row_height = GetCharacterHeight(FS_SMALL);
1615 int padding = ScaleGUITrad(1);
1616
1617 Rect origin = r.WithWidth(this->column_width, rtl).Shrink(WidgetDimensions::scaled.framerect).WithHeight(row_height);
1618 Rect text = origin.Indent(this->legend_width + WidgetDimensions::scaled.hsep_normal, rtl);
1619 Rect icon = origin.WithWidth(this->legend_width, rtl).Shrink(0, padding, 0, 0);
1620
1621 StringID string = STR_NULL;
1622 switch (this->map_type) {
1623 case SMT_INDUSTRY:
1624 string = STR_SMALLMAP_INDUSTRY;
1625 break;
1626 case SMT_LINKSTATS:
1627 string = STR_SMALLMAP_LINKSTATS;
1628 break;
1629 case SMT_OWNER:
1630 string = STR_SMALLMAP_COMPANY;
1631 break;
1632 default:
1633 break;
1634 }
1635
1636 for (const LegendAndColour *tbl = _legend_table[this->map_type]; !tbl->end; ++tbl) {
1637 if (tbl->col_break || ((this->map_type == SMT_INDUSTRY || this->map_type == SMT_OWNER || this->map_type == SMT_LINKSTATS) && i++ >= number_of_rows)) {
1638 /* Column break needed, continue at top, COLUMN_WIDTH pixels
1639 * (one "row") to the right. */
1640 int x = rtl ? -(int)this->column_width : this->column_width;
1641 int y = origin.top - text.top;
1642 text = text.Translate(x, y);
1643 icon = icon.Translate(x, y);
1644 i = 1;
1645 }
1646
1647 PixelColour legend_colour = tbl->colour;
1648
1649 std::array<StringParameter, 2> params{};
1650 switch (this->map_type) {
1651 case SMT_INDUSTRY:
1652 /* Industry name must be formatted, since it's not in tiny font in the specs.
1653 * So, draw with a parameter and use the STR_SMALLMAP_INDUSTRY string, which is tiny font */
1654 params[0] = tbl->legend;
1655 params[1] = Industry::GetIndustryTypeCount(tbl->type);
1656 if (tbl->show_on_map && tbl->type == _smallmap_industry_highlight) {
1657 legend_colour = _smallmap_industry_highlight_state ? PC_WHITE : PC_BLACK;
1658 }
1659 [[fallthrough]];
1660
1661 case SMT_LINKSTATS:
1662 params[0] = tbl->legend;
1663 [[fallthrough]];
1664
1665 case SMT_OWNER:
1666 if (this->map_type != SMT_OWNER || tbl->company != CompanyID::Invalid()) {
1667 if (this->map_type == SMT_OWNER) params[0] = tbl->company;
1668 if (!tbl->show_on_map) {
1669 /* Simply draw the string, not the black border of the legend colour.
1670 * This will enforce the idea of the disabled item */
1671 DrawString(text, GetStringWithArgs(string, params), TC_GREY);
1672 } else {
1673 DrawString(text, GetStringWithArgs(string, params), TC_BLACK);
1674 GfxFillRect(icon, PC_BLACK); // Outer border of the legend colour
1675 }
1676 break;
1677 }
1678 [[fallthrough]];
1679
1680 default:
1681 /* Anything that is not an industry or a company is using normal process */
1682 GfxFillRect(icon, PC_BLACK);
1683 if (this->map_type == SMT_CONTOUR) {
1684 DrawString(text, GetString(tbl->legend, tbl->height * TILE_HEIGHT_STEP));
1685 } else {
1686 DrawString(text, tbl->legend);
1687 }
1688 break;
1689 }
1690 GfxFillRect(icon.Shrink(WidgetDimensions::scaled.bevel), legend_colour); // Legend colour
1691
1692 text = text.Translate(0, row_height);
1693 icon = icon.Translate(0, row_height);
1694 }
1695 }
1696 }
1697 }
1698
1699 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
1700 {
1701 switch (widget) {
1702 case WID_SM_MAP: { // Map window
1703 if (click_count > 0) this->mouse_capture_widget = widget;
1704
1705 const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_SM_MAP);
1706 Window *w = GetMainWindow();
1707 int sub;
1708 pt = this->PixelToTile(pt.x - wid->pos_x, pt.y - wid->pos_y, &sub);
1709 ScrollWindowTo(this->scroll_x + pt.x * TILE_SIZE, this->scroll_y + pt.y * TILE_SIZE, -1, w);
1710
1711 this->SetDirty();
1712 break;
1713 }
1714
1715 case WID_SM_ZOOM_IN:
1716 case WID_SM_ZOOM_OUT: {
1717 const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_SM_MAP);
1718 Point zoom_pt = { (int)wid->current_x / 2, (int)wid->current_y / 2};
1719 this->SetZoomLevel((widget == WID_SM_ZOOM_IN) ? ZLC_ZOOM_IN : ZLC_ZOOM_OUT, &zoom_pt);
1720 SndClickBeep();
1721 break;
1722 }
1723
1724 case WID_SM_CONTOUR: // Show land contours
1725 case WID_SM_VEHICLES: // Show vehicles
1726 case WID_SM_INDUSTRIES: // Show industries
1727 case WID_SM_LINKSTATS: // Show route map
1728 case WID_SM_ROUTES: // Show transport routes
1729 case WID_SM_VEGETATION: // Show vegetation
1730 case WID_SM_OWNERS: // Show land owners
1731 this->SwitchMapType((SmallMapType)(widget - WID_SM_CONTOUR));
1732 SndClickBeep();
1733 break;
1734
1735 case WID_SM_CENTERMAP: // Center the smallmap again
1736 this->SmallMapCenterOnCurrentPos();
1737 this->HandleButtonClick(WID_SM_CENTERMAP);
1738 break;
1739
1740 case WID_SM_TOGGLETOWNNAME: // Toggle town names
1741 this->show_towns = !this->show_towns;
1742 this->SetWidgetLoweredState(WID_SM_TOGGLETOWNNAME, this->show_towns);
1743
1744 this->SetDirty();
1745 SndClickBeep();
1746 break;
1747
1748 case WID_SM_SHOW_IND_NAMES: // Toggle industry names
1749 this->show_ind_names = !this->show_ind_names;
1750 this->SetWidgetLoweredState(WID_SM_SHOW_IND_NAMES, this->show_ind_names);
1751
1752 this->SetDirty();
1753 SndClickBeep();
1754 break;
1755
1756 case WID_SM_LEGEND: // Legend
1757 if (this->map_type == SMT_INDUSTRY || this->map_type == SMT_LINKSTATS || this->map_type == SMT_OWNER) {
1758 int click_pos = this->GetPositionOnLegend(pt);
1759 if (click_pos < 0) break;
1760
1761 /* If industry type small map*/
1762 if (this->map_type == SMT_INDUSTRY) {
1763 /* If click on industries label, find right industry type and enable/disable it. */
1764 if (click_pos < _smallmap_industry_count) {
1765 this->SelectLegendItem(click_pos, _legend_from_industries, _smallmap_industry_count);
1766 }
1767 } else if (this->map_type == SMT_LINKSTATS) {
1768 if (click_pos < _smallmap_cargo_count) {
1769 this->SelectLegendItem(click_pos, _legend_linkstats, _smallmap_cargo_count);
1770 this->SetOverlayCargoMask();
1771 }
1772 } else if (this->map_type == SMT_OWNER) {
1773 if (click_pos < _smallmap_company_count) {
1774 this->SelectLegendItem(click_pos, _legend_land_owners, _smallmap_company_count, NUM_NO_COMPANY_ENTRIES);
1775 }
1776 }
1777 this->SetDirty();
1778 }
1779 break;
1780
1781 case WID_SM_ENABLE_ALL:
1782 case WID_SM_DISABLE_ALL: {
1783 LegendAndColour *tbl = nullptr;
1784 switch (this->map_type) {
1785 case SMT_INDUSTRY:
1786 tbl = _legend_from_industries;
1787 this->BreakIndustryChainLink();
1788 break;
1789 case SMT_OWNER:
1790 tbl = &(_legend_land_owners[NUM_NO_COMPANY_ENTRIES]);
1791 break;
1792 case SMT_LINKSTATS:
1793 tbl = _legend_linkstats;
1794 break;
1795 default:
1796 NOT_REACHED();
1797 }
1798 for (;!tbl->end && tbl->legend != STR_LINKGRAPH_LEGEND_UNUSED; ++tbl) {
1799 tbl->show_on_map = (widget == WID_SM_ENABLE_ALL);
1800 }
1801 if (this->map_type == SMT_LINKSTATS) this->SetOverlayCargoMask();
1802 this->SetDirty();
1803 break;
1804 }
1805
1806 case WID_SM_SHOW_HEIGHT: // Enable/disable showing of heightmap.
1807 _smallmap_show_heightmap = !_smallmap_show_heightmap;
1808 this->SetWidgetLoweredState(WID_SM_SHOW_HEIGHT, _smallmap_show_heightmap);
1809 this->SetDirty();
1810 break;
1811 }
1812 }
1813
1822 void OnInvalidateData(int data = 0, bool gui_scope = true) override
1823 {
1824 if (!gui_scope) return;
1825
1826 switch (data) {
1827 case 1:
1828 /* The owner legend has already been rebuilt. */
1829 this->ReInit();
1830 break;
1831
1832 case 0: {
1833 extern std::bitset<NUM_INDUSTRYTYPES> _displayed_industries;
1834 if (this->map_type != SMT_INDUSTRY) this->SwitchMapType(SMT_INDUSTRY);
1835
1836 for (int i = 0; i != _smallmap_industry_count; i++) {
1837 _legend_from_industries[i].show_on_map = _displayed_industries.test(_legend_from_industries[i].type);
1838 }
1839 break;
1840 }
1841
1842 case 2:
1843 this->RebuildColourIndexIfNecessary();
1844 break;
1845
1846 default: NOT_REACHED();
1847 }
1848 this->SetDirty();
1849 }
1850
1851 bool OnRightClick(Point, WidgetID widget) override
1852 {
1853 if (widget != WID_SM_MAP || _scrolling_viewport) return false;
1854
1855 _scrolling_viewport = true;
1856 return true;
1857 }
1858
1859 void OnMouseWheel(int wheel, WidgetID widget) override
1860 {
1861 if (widget != WID_SM_MAP) return;
1862 if (_settings_client.gui.scrollwheel_scrolling != SWS_OFF) {
1863 const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_SM_MAP);
1864 int cursor_x = _cursor.pos.x - this->left - wid->pos_x;
1865 int cursor_y = _cursor.pos.y - this->top - wid->pos_y;
1866 Point pt = {cursor_x, cursor_y};
1867 this->SetZoomLevel((wheel < 0) ? ZLC_ZOOM_IN : ZLC_ZOOM_OUT, &pt);
1868 }
1869 }
1870
1871 void OnScroll(Point delta) override
1872 {
1873 if (_settings_client.gui.scroll_mode == VSM_VIEWPORT_RMB_FIXED || _settings_client.gui.scroll_mode == VSM_MAP_RMB_FIXED) _cursor.fix_at = true;
1874
1875 /* While tile is at (delta.x, delta.y)? */
1876 int sub;
1877 Point pt = this->PixelToTile(delta.x, delta.y, &sub);
1878 this->SetNewScroll(this->scroll_x + pt.x * TILE_SIZE, this->scroll_y + pt.y * TILE_SIZE, sub);
1879
1880 this->SetDirty();
1881 }
1882
1883 void OnMouseOver([[maybe_unused]] Point pt, WidgetID widget) override
1884 {
1885 IndustryType new_highlight = IT_INVALID;
1886 if (widget == WID_SM_LEGEND && this->map_type == SMT_INDUSTRY) {
1887 int industry_pos = GetPositionOnLegend(pt);
1888 if (industry_pos >= 0 && industry_pos < _smallmap_industry_count) {
1889 new_highlight = _legend_from_industries[industry_pos].type;
1890 }
1891 }
1892 if (new_highlight != _smallmap_industry_highlight) {
1893 _smallmap_industry_highlight = new_highlight;
1894 _smallmap_industry_highlight_state = true;
1895 this->SetDirty();
1896 }
1897 }
1898
1899};
1900
1901 SmallMapType SmallMapWindow::map_type = SMT_CONTOUR;
1902bool SmallMapWindow::show_towns = true;
1903bool SmallMapWindow::show_ind_names = false;
1904int SmallMapWindow::map_height_limit = -1;
1905
1914 class NWidgetSmallmapDisplay : public NWidgetContainer {
1915 const SmallMapWindow *smallmap_window = nullptr;
1916public:
1917 NWidgetSmallmapDisplay() : NWidgetContainer(NWID_VERTICAL) {}
1918
1919 void SetupSmallestSize(Window *w) override
1920 {
1921 assert(this->children.size() == 2);
1922 NWidgetBase *display = this->children.front().get();
1923 NWidgetBase *bar = this->children.back().get();
1924
1925 display->SetupSmallestSize(w);
1926 bar->SetupSmallestSize(w);
1927
1928 this->smallmap_window = dynamic_cast<SmallMapWindow *>(w);
1929 assert(this->smallmap_window != nullptr);
1930 this->smallest_x = std::max(display->smallest_x, bar->smallest_x + smallmap_window->GetMinLegendWidth());
1931 this->smallest_y = display->smallest_y + std::max(bar->smallest_y, smallmap_window->GetLegendHeight(smallmap_window->min_number_of_columns));
1932 this->fill_x = std::max(display->fill_x, bar->fill_x);
1933 this->fill_y = (display->fill_y == 0 && bar->fill_y == 0) ? 0 : std::min(display->fill_y, bar->fill_y);
1934 this->resize_x = std::max(display->resize_x, bar->resize_x);
1935 this->resize_y = std::min(display->resize_y, bar->resize_y);
1936 this->ApplyAspectRatio();
1937 }
1938
1939 void AssignSizePosition(SizingType sizing, int x, int y, uint given_width, uint given_height, bool rtl) override
1940 {
1941 this->pos_x = x;
1942 this->pos_y = y;
1943 this->current_x = given_width;
1944 this->current_y = given_height;
1945
1946 assert(this->children.size() == 2);
1947 NWidgetBase *display = this->children.front().get();
1948 NWidgetBase *bar = this->children.back().get();
1949
1950 if (sizing == ST_SMALLEST) {
1951 this->smallest_x = given_width;
1952 this->smallest_y = given_height;
1953 /* Make display and bar exactly equal to their minimal size. */
1954 display->AssignSizePosition(ST_SMALLEST, x, y, display->smallest_x, display->smallest_y, rtl);
1955 bar->AssignSizePosition(ST_SMALLEST, x, y + display->smallest_y, bar->smallest_x, bar->smallest_y, rtl);
1956 }
1957
1958 uint bar_height = std::max(bar->smallest_y, this->smallmap_window->GetLegendHeight(this->smallmap_window->GetNumberColumnsLegend(given_width - bar->smallest_x)));
1959 uint display_height = given_height - bar_height;
1960 display->AssignSizePosition(ST_RESIZE, x, y, given_width, display_height, rtl);
1961 bar->AssignSizePosition(ST_RESIZE, x, y + display_height, given_width, bar_height, rtl);
1962 }
1963};
1964
1966 static constexpr std::initializer_list<NWidgetPart> _nested_smallmap_display = {
1967 NWidget(WWT_PANEL, COLOUR_BROWN, WID_SM_MAP_BORDER),
1968 NWidget(WWT_INSET, COLOUR_BROWN, WID_SM_MAP), SetMinimalSize(346, 140), SetResize(1, 1), SetPadding(2, 2, 2, 2), EndContainer(),
1969 EndContainer(),
1970};
1971
1973 static constexpr std::initializer_list<NWidgetPart> _nested_smallmap_bar = {
1974 NWidget(WWT_PANEL, COLOUR_BROWN),
1975 NWidget(NWID_HORIZONTAL),
1976 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SM_LEGEND), SetResize(1, 1),
1977 NWidget(NWID_VERTICAL),
1978 /* Top button row. */
1979 NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
1980 NWidget(WWT_PUSHIMGBTN, COLOUR_BROWN, WID_SM_ZOOM_IN),
1981 SetSpriteTip(SPR_IMG_ZOOMIN, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN), SetFill(1, 1),
1982 NWidget(WWT_PUSHIMGBTN, COLOUR_BROWN, WID_SM_CENTERMAP),
1983 SetSpriteTip(SPR_IMG_SMALLMAP, STR_SMALLMAP_CENTER_TOOLTIP), SetFill(1, 1),
1984 NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_BLANK),
1985 SetSpriteTip(SPR_EMPTY), SetFill(1, 1),
1986 NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_CONTOUR),
1987 SetSpriteTip(SPR_IMG_SHOW_COUNTOURS, STR_SMALLMAP_TOOLTIP_SHOW_LAND_CONTOURS_ON_MAP), SetFill(1, 1),
1988 NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_VEHICLES),
1989 SetSpriteTip(SPR_IMG_SHOW_VEHICLES, STR_SMALLMAP_TOOLTIP_SHOW_VEHICLES_ON_MAP), SetFill(1, 1),
1990 NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_INDUSTRIES),
1991 SetSpriteTip(SPR_IMG_INDUSTRY, STR_SMALLMAP_TOOLTIP_SHOW_INDUSTRIES_ON_MAP), SetFill(1, 1),
1992 EndContainer(),
1993 /* Bottom button row. */
1994 NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
1995 NWidget(WWT_PUSHIMGBTN, COLOUR_BROWN, WID_SM_ZOOM_OUT),
1996 SetSpriteTip(SPR_IMG_ZOOMOUT, STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT), SetFill(1, 1),
1997 NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_TOGGLETOWNNAME),
1998 SetSpriteTip(SPR_IMG_TOWN, STR_SMALLMAP_TOOLTIP_TOGGLE_TOWN_NAMES_ON_OFF), SetFill(1, 1),
1999 NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_LINKSTATS),
2000 SetSpriteTip(SPR_IMG_CARGOFLOW, STR_SMALLMAP_TOOLTIP_SHOW_LINK_STATS_ON_MAP), SetFill(1, 1),
2001 NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_ROUTES),
2002 SetSpriteTip(SPR_IMG_SHOW_ROUTES, STR_SMALLMAP_TOOLTIP_SHOW_TRANSPORT_ROUTES_ON), SetFill(1, 1),
2003 NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_VEGETATION),
2004 SetSpriteTip(SPR_IMG_PLANTTREES, STR_SMALLMAP_TOOLTIP_SHOW_VEGETATION_ON_MAP), SetFill(1, 1),
2005 NWidget(WWT_IMGBTN, COLOUR_BROWN, WID_SM_OWNERS),
2006 SetSpriteTip(SPR_IMG_COMPANY_GENERAL, STR_SMALLMAP_TOOLTIP_SHOW_LAND_OWNERS_ON_MAP), SetFill(1, 1),
2007 EndContainer(),
2008 NWidget(NWID_SPACER), SetResize(0, 1),
2009 EndContainer(),
2010 EndContainer(),
2011 EndContainer(),
2012};
2013
2014static std::unique_ptr<NWidgetBase> SmallMapDisplay()
2015{
2016 std::unique_ptr<NWidgetBase> map_display = std::make_unique<NWidgetSmallmapDisplay>();
2017
2018 map_display = MakeNWidgets(_nested_smallmap_display, std::move(map_display));
2019 map_display = MakeNWidgets(_nested_smallmap_bar, std::move(map_display));
2020 return map_display;
2021}
2022
2023static constexpr std::initializer_list<NWidgetPart> _nested_smallmap_widgets = {
2024 NWidget(NWID_HORIZONTAL),
2025 NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
2026 NWidget(WWT_CAPTION, COLOUR_BROWN, WID_SM_CAPTION),
2027 NWidget(WWT_SHADEBOX, COLOUR_BROWN),
2028 NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
2029 NWidget(WWT_STICKYBOX, COLOUR_BROWN),
2030 EndContainer(),
2031 NWidgetFunction(SmallMapDisplay), // Smallmap display and legend bar + image buttons.
2032 /* Bottom button row and resize box. */
2033 NWidget(NWID_HORIZONTAL),
2034 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_SM_SELECT_BUTTONS),
2035 NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
2036 NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_SM_ENABLE_ALL), SetStringTip(STR_SMALLMAP_ENABLE_ALL),
2037 NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_SM_DISABLE_ALL), SetStringTip(STR_SMALLMAP_DISABLE_ALL),
2038 NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_SM_SHOW_HEIGHT), SetStringTip(STR_SMALLMAP_SHOW_HEIGHT, STR_SMALLMAP_TOOLTIP_SHOW_HEIGHT),
2039
2040 /* 'show industry names' button and container. Only shown for the industry map type. */
2041 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_SM_SHOW_IND_NAMES_SEL),
2042 NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_SM_SHOW_IND_NAMES), SetStringTip(STR_SMALLMAP_SHOW_INDUSTRY_NAMES, STR_SMALLMAP_TOOLTIP_SHOW_INDUSTRY_NAMES),
2043 EndContainer(),
2044
2045 NWidget(WWT_PANEL, COLOUR_BROWN), SetFill(1, 0), SetResize(1, 0),
2046 EndContainer(),
2047 EndContainer(),
2048 NWidget(WWT_PANEL, COLOUR_BROWN), SetFill(1, 0), SetResize(1, 0),
2049 EndContainer(),
2050 EndContainer(),
2051 NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
2052 EndContainer(),
2053};
2054
2055static WindowDesc _smallmap_desc(
2056 WDP_AUTO, "smallmap", 484, 314,
2057 WC_SMALLMAP, WC_NONE,
2058 {},
2059 _nested_smallmap_widgets
2060);
2061
2065 void ShowSmallMap()
2066{
2067 AllocateWindowDescFront<SmallMapWindow>(_smallmap_desc, 0);
2068}
2069
2078 bool ScrollMainWindowTo(int x, int y, int z, bool instant)
2079{
2080 bool res = ScrollWindowTo(x, y, z, GetMainWindow(), instant);
2081
2082 /* If a user scrolls to a tile (via what way what so ever) and already is on
2083 * that tile (e.g.: pressed twice), move the smallmap to that location,
2084 * so you directly see where you are on the smallmap. */
2085
2086 if (res) return res;
2087
2088 SmallMapWindow *w = dynamic_cast<SmallMapWindow*>(FindWindowById(WC_SMALLMAP, 0));
2089 if (w != nullptr) w->SmallMapCenterOnCurrentPos();
2090
2091 return res;
2092}
2093
2099 Point GetSmallMapStationMiddle(const Window *w, const Station *st)
2100{
2101 return static_cast<const SmallMapWindow *>(w)->GetStationMiddle(st);
2102}
backup_type.hpp
Class for backupping variables and making sure they are restored later.
SetBit
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
Definition bitmath_func.hpp:121
NUM_CARGO
static const CargoType NUM_CARGO
Maximum number of cargo types in a game.
Definition cargo_type.h:73
_sorted_cargo_specs
std::vector< const CargoSpec * > _sorted_cargo_specs
Cargo specifications sorted alphabetically by name.
Definition cargotype.cpp:190
BaseBitSet::Set
constexpr Timpl & Set()
Set all bits.
Definition base_bitset_type.hpp:40
BlitterFactory::GetCurrentBlitter
static Blitter * GetCurrentBlitter()
Get the current active blitter (always set by calling SelectBlitter).
Definition factory.hpp:136
Blitter
How all blitters should look like.
Definition base.hpp:29
Blitter::MoveTo
virtual void * MoveTo(void *video, int x, int y)=0
Move the destination pointer the requested amount x and y, keeping in mind any pitch and bpp of the r...
Blitter::SetPixel
virtual void SetPixel(void *video, int x, int y, PixelColour colour)=0
Draw a pixel with a given colour on the video-buffer.
CompanyMask
Definition company_type.h:43
IntervalTimer
An interval timer will fire every interval, and will continue to fire until it is deleted.
Definition timer.h:76
LinkGraphOverlay::LINK_COLOURS
static const PixelColour LINK_COLOURS[][12]
Colours for the various "load" states of links.
Definition linkgraph_gui.h:33
NWidgetBase
Baseclass for nested widgets.
Definition widget_type.h:136
NWidgetBase::SetupSmallestSize
virtual void SetupSmallestSize(Window *w)=0
Compute smallest size needed by the widget.
NWidgetBase::SetDirty
virtual void SetDirty(const Window *w) const
Mark the widget as 'dirty' (in need of repaint).
Definition widget.cpp:931
NWidgetBase::type
WidgetType type
Type of the widget / nested widget.
Definition widget_type.h:226
NWidgetBase::resize_x
uint resize_x
Horizontal resize step (0 means not resizable).
Definition widget_type.h:229
NWidgetBase::fill_x
uint fill_x
Horizontal fill stepsize (from initial size, 0 means not resizable).
Definition widget_type.h:227
NWidgetBase::smallest_x
uint smallest_x
Smallest horizontal size of the widget in a filled window.
Definition widget_type.h:234
NWidgetBase::current_x
uint current_x
Current horizontal size (after resizing).
Definition widget_type.h:237
NWidgetBase::pos_y
int pos_y
Vertical position of top-left corner of the widget in the window.
Definition widget_type.h:243
NWidgetBase::pos_x
int pos_x
Horizontal position of top-left corner of the widget in the window.
Definition widget_type.h:242
NWidgetBase::smallest_y
uint smallest_y
Smallest vertical size of the widget in a filled window.
Definition widget_type.h:235
NWidgetBase::AssignSizePosition
virtual void AssignSizePosition(SizingType sizing, int x, int y, uint given_width, uint given_height, bool rtl)=0
Assign size and position to the widget.
NWidgetBase::fill_y
uint fill_y
Vertical fill stepsize (from initial size, 0 means not resizable).
Definition widget_type.h:228
NWidgetBase::resize_y
uint resize_y
Vertical resize step (0 means not resizable).
Definition widget_type.h:230
NWidgetBase::padding
RectPadding padding
Padding added to the widget. Managed by parent container widget. (parent container may swap left and ...
Definition widget_type.h:245
NWidgetBase::current_y
uint current_y
Current vertical size (after resizing).
Definition widget_type.h:238
NWidgetContainer
Baseclass for container widgets.
Definition widget_type.h:471
NWidgetContainer::children
std::vector< std::unique_ptr< NWidgetBase > > children
Child widgets in container.
Definition widget_type.h:499
NWidgetSmallmapDisplay
Custom container class for displaying smallmap with a vertically resizing legend panel.
Definition smallmap_gui.cpp:1914
NWidgetSmallmapDisplay::AssignSizePosition
void AssignSizePosition(SizingType sizing, int x, int y, uint given_width, uint given_height, bool rtl) override
Assign size and position to the widget.
Definition smallmap_gui.cpp:1939
NWidgetSmallmapDisplay::SetupSmallestSize
void SetupSmallestSize(Window *w) override
Compute smallest size needed by the widget.
Definition smallmap_gui.cpp:1919
NWidgetSmallmapDisplay::smallmap_window
const SmallMapWindow * smallmap_window
Window manager instance.
Definition smallmap_gui.cpp:1915
RoadTypeInfo
Definition road.h:52
RoadTypeInfo::map_colour
PixelColour map_colour
Colour on mini-map.
Definition road.h:131
SmallMapWindow
Class managing the smallmap window.
Definition smallmap_gui.cpp:627
SmallMapWindow::SmallMapCenterOnCurrentPos
void SmallMapCenterOnCurrentPos()
Center the small map on the current center of the viewport.
Definition smallmap_gui.cpp:1478
SmallMapWindow::SetOverlayCargoMask
void SetOverlayCargoMask()
Set the link graph overlay cargo mask from the legend.
Definition smallmap_gui.cpp:1255
SmallMapWindow::Close
void Close(int data) override
Hide the window and all its child windows, and mark them for a later deletion.
Definition smallmap_gui.cpp:1509
SmallMapWindow::map_type
static SmallMapType map_type
Currently displayed legends.
Definition smallmap_gui.cpp:636
SmallMapWindow::GetNumberColumnsLegend
uint GetNumberColumnsLegend(uint width) const
Return number of columns that can be displayed in width pixels.
Definition smallmap_gui.cpp:706
SmallMapWindow::SelectLegendItem
void SelectLegendItem(int click_pos, LegendAndColour *legend, int end_legend_item, int begin_legend_item=0)
Select and toggle a legend item.
Definition smallmap_gui.cpp:794
SmallMapWindow::SwitchMapType
void SwitchMapType(SmallMapType map_type)
Select a new map type.
Definition smallmap_gui.cpp:823
SmallMapWindow::DrawSmallMap
void DrawSmallMap(DrawPixelInfo *dpi) const
Draws the small map.
Definition smallmap_gui.cpp:1057
SmallMapWindow::ComputeScroll
Point ComputeScroll(int tx, int ty, int x, int y, int *sub) const
Compute base parameters of the smallmap such that tile (tx, ty) starts at pixel (x,...
Definition smallmap_gui.cpp:1180
SmallMapWindow::GetStationMiddle
Point GetStationMiddle(const Station *st) const
Get the center of the given station as point on the screen in the smallmap window.
Definition smallmap_gui.cpp:1496
SmallMapWindow::ForceRefresh
void ForceRefresh()
Force a full refresh of the map.
Definition smallmap_gui.cpp:1442
SmallMapWindow::OnInvalidateData
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Definition smallmap_gui.cpp:1822
SmallMapWindow::GetMinLegendWidth
uint GetMinLegendWidth() const
Compute minimal required width of the legends.
Definition smallmap_gui.cpp:697
SmallMapWindow::show_towns
static bool show_towns
Display town names in the smallmap.
Definition smallmap_gui.cpp:637
SmallMapWindow::PixelToTile
Point PixelToTile(int px, int py, int *sub, bool add_sub=true) const
Determine the tile relative to the base tile of the smallmap, and the pixel position at that tile for...
Definition smallmap_gui.cpp:1148
SmallMapWindow::Blink
void Blink()
Blink the industries (if hover over an industry).
Definition smallmap_gui.cpp:1431
SmallMapWindow::DrawIndustryNames
void DrawIndustryNames(const DrawPixelInfo *dpi, const int vertical_padding) const
Adds industry names to the smallmap.
Definition smallmap_gui.cpp:1011
SmallMapWindow::DrawVertMapIndicator
static void DrawVertMapIndicator(int x, int y, int y2)
Draws vertical part of map indicator.
Definition smallmap_gui.cpp:675
SmallMapWindow::GetLegendHeight
uint GetLegendHeight(uint num_columns) const
Compute height given a number of columns.
Definition smallmap_gui.cpp:716
SmallMapWindow::min_number_of_columns
uint min_number_of_columns
Minimal number of columns in legends.
Definition smallmap_gui.cpp:643
SmallMapWindow::GetOverlayCompanyMask
CompanyMask GetOverlayCompanyMask() const
Get a bitmask for company links to be displayed.
Definition smallmap_gui.cpp:727
SmallMapWindow::GetTileColours
uint32_t GetTileColours(const TileArea &ta) const
Decide which colours to show to the user for a group of tiles.
Definition smallmap_gui.cpp:1320
SmallMapWindow::GetWidgetString
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
Definition smallmap_gui.cpp:1515
SmallMapWindow::DrawTowns
void DrawTowns(const DrawPixelInfo *dpi, const int vertical_padding) const
Adds town names to the smallmap.
Definition smallmap_gui.cpp:988
SmallMapWindow::OnPaint
void OnPaint() override
The window must be repainted.
Definition smallmap_gui.cpp:1582
SmallMapWindow::SetZoomLevel
void SetZoomLevel(ZoomLevelChange change, const Point *zoom_pt)
Initialize or change the zoom level.
Definition smallmap_gui.cpp:1208
SmallMapWindow::GetPositionOnLegend
int GetPositionOnLegend(Point pt)
Determines the mouse position on the legend.
Definition smallmap_gui.cpp:1401
SmallMapWindow::OnMouseWheel
void OnMouseWheel(int wheel, WidgetID widget) override
The mouse wheel has been turned.
Definition smallmap_gui.cpp:1859
SmallMapWindow::OnMouseOver
void OnMouseOver(Point pt, WidgetID widget) override
The mouse is currently moving over the window or has just moved outside of the window.
Definition smallmap_gui.cpp:1883
SmallMapWindow::ZoomLevelChange
ZoomLevelChange
Available kinds of zoomlevel changes.
Definition smallmap_gui.cpp:630
SmallMapWindow::ZLC_ZOOM_IN
@ ZLC_ZOOM_IN
Zoom in.
Definition smallmap_gui.cpp:633
SmallMapWindow::ZLC_ZOOM_OUT
@ ZLC_ZOOM_OUT
Zoom out.
Definition smallmap_gui.cpp:632
SmallMapWindow::ZLC_INITIALIZE
@ ZLC_INITIALIZE
Initialize zoom level.
Definition smallmap_gui.cpp:631
SmallMapWindow::SetupWidgetData
void SetupWidgetData()
Function to set up widgets depending on the information being shown on the smallmap.
Definition smallmap_gui.cpp:1267
SmallMapWindow::show_ind_names
static bool show_ind_names
Display industry names in the smallmap.
Definition smallmap_gui.cpp:638
SmallMapWindow::RebuildColourIndexIfNecessary
void RebuildColourIndexIfNecessary()
Rebuilds the colour indices used for fast access to the smallmap contour colours based on the heightl...
Definition smallmap_gui.cpp:745
SmallMapWindow::DrawSmallMapColumn
void DrawSmallMapColumn(void *dst, uint xc, uint yc, int pitch, int reps, int start_pos, int end_pos, Blitter *blitter) const
Draws one column of tiles of the small map in a certain mode onto the screen buffer,...
Definition smallmap_gui.cpp:910
SmallMapWindow::OnClick
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
Definition smallmap_gui.cpp:1699
SmallMapWindow::map_height_limit
static int map_height_limit
Currently used/cached map height limit.
Definition smallmap_gui.cpp:639
SmallMapWindow::RemapTile
Point RemapTile(int tile_x, int tile_y) const
Remap tile to location on this smallmap.
Definition smallmap_gui.cpp:1124
SmallMapWindow::DrawHorizMapIndicator
static void DrawHorizMapIndicator(int x, int x2, int y)
Draws horizontal part of map indicator.
Definition smallmap_gui.cpp:687
SmallMapWindow::OnInit
void OnInit() override
Notification that the nested widget tree gets initialized.
Definition smallmap_gui.cpp:1526
SmallMapWindow::UpdateLinks
void UpdateLinks()
Update all the links on the map.
Definition smallmap_gui.cpp:1418
SmallMapWindow::OnScroll
void OnScroll(Point delta) override
Handle the request for (viewport) scrolling.
Definition smallmap_gui.cpp:1871
SmallMapWindow::DrawWidget
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
Definition smallmap_gui.cpp:1598
SmallMapWindow::DrawMapIndicators
void DrawMapIndicators() const
Adds map indicators to the smallmap.
Definition smallmap_gui.cpp:876
SmallMapWindow::OnRightClick
bool OnRightClick(Point, WidgetID widget) override
A click with the right mouse button has been made on the window.
Definition smallmap_gui.cpp:1851
SmallMapWindow::SetNewScroll
void SetNewScroll(int sx, int sy, int sub)
Set new scroll_x, scroll_y, and subscroll values after limiting them such that the center of the smal...
Definition smallmap_gui.cpp:843
SmallMapWindow::GetNumberRowsLegend
uint GetNumberRowsLegend(uint columns) const
Get the number of rows in the legend from the number of columns.
Definition smallmap_gui.cpp:775
SmallMapWindow::DrawVehicles
void DrawVehicles(const DrawPixelInfo *dpi, Blitter *blitter) const
Adds vehicles to the smallmap.
Definition smallmap_gui.cpp:950
SmallMapWindow::BreakIndustryChainLink
static void BreakIndustryChainLink()
Notify the industry chain window to stop sending newly selected industries.
Definition smallmap_gui.cpp:656
TypedIndexContainer
A sort-of mixin that implements 'at(pos)' and 'operator[](pos)' only for a specific type.
Definition convertible_through_base.hpp:38
WidgetDimensions::framerect
RectPadding framerect
Standard padding inside many panels.
Definition window_gui.h:40
WidgetDimensions::scaled
static WidgetDimensions scaled
Widget dimensions scaled for current zoom level.
Definition window_gui.h:30
WidgetDimensions::hsep_normal
int hsep_normal
Normal horizontal spacing.
Definition window_gui.h:61
WidgetDimensions::bevel
RectPadding bevel
Bevel thickness, affected by "scaled bevels" game option.
Definition window_gui.h:38
clear_map.h
Map accessors for 'clear' tiles.
IsClearGround
bool IsClearGround(Tile t, ClearGround ct)
Set the type of clear tile.
Definition clear_map.h:59
CLEAR_GRASS
@ CLEAR_GRASS
0-3
Definition clear_map.h:20
CLEAR_SNOW
@ CLEAR_SNOW
0-3 (Not stored in map.)
Definition clear_map.h:24
GetClearGround
ClearGround GetClearGround(Tile t)
Get the type of clear tile.
Definition clear_map.h:47
IsSnowTile
bool IsSnowTile(Tile t)
Test if a tile is covered with snow.
Definition clear_map.h:35
GetClearDensity
uint GetClearDensity(Tile t)
Get the density of a non-field clear tile.
Definition clear_map.h:71
company_base.h
Definition of stuff that is very close to a company, like the company struct itself.
_local_company
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition company_cmd.cpp:55
OWNER_TOWN
static constexpr Owner OWNER_TOWN
A town owns the tile, or a town is expanding.
Definition company_type.h:25
OWNER_NONE
static constexpr Owner OWNER_NONE
The tile has no ownership.
Definition company_type.h:26
OWNER_WATER
static constexpr Owner OWNER_WATER
The tile/execution is done by "water".
Definition company_type.h:27
endian_func.hpp
Function to handling different endian machines.
DECLARE_ENUM_AS_ADDABLE
#define DECLARE_ENUM_AS_ADDABLE(EnumType)
Operator that allows this enumeration to be added to any other enumeration.
Definition enum_type.hpp:129
factory.hpp
Factory to 'query' all available blitters.
GetCharacterHeight
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
Definition fontcache.cpp:87
CentreBounds
int CentreBounds(int min, int max, int size)
Determine where to position a centred object.
Definition geometry_type.hpp:26
GetStringBoundingBox
Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition gfx.cpp:894
DrawString
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:665
_ctrl_pressed
bool _ctrl_pressed
Is Ctrl pressed?
Definition gfx.cpp:38
GfxFillRect
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:115
FillDrawPixelInfo
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:1565
FS_SMALL
@ FS_SMALL
Index of the small font in the font tables.
Definition gfx_type.h:250
SA_LEFT
@ SA_LEFT
Left align the text.
Definition gfx_type.h:388
NWidgetFunction
constexpr NWidgetPart NWidgetFunction(NWidgetFunctionType *func_ptr)
Obtain a nested widget (sub)tree from an external source.
Definition widget_type.h:1445
SetFill
constexpr NWidgetPart SetFill(uint16_t fill_x, uint16_t fill_y)
Widget part function for setting filling.
Definition widget_type.h:1219
SetSpriteTip
constexpr NWidgetPart SetSpriteTip(SpriteID sprite, StringID tip={})
Widget part function for setting the sprite and tooltip.
Definition widget_type.h:1251
SetPadding
constexpr NWidgetPart SetPadding(uint8_t top, uint8_t right, uint8_t bottom, uint8_t left)
Widget part function for setting additional space around a widget.
Definition widget_type.h:1332
SetStringTip
constexpr NWidgetPart SetStringTip(StringID string, StringID tip={})
Widget part function for setting the string and tooltip.
Definition widget_type.h:1240
SetMinimalSize
constexpr NWidgetPart SetMinimalSize(int16_t x, int16_t y)
Widget part function for setting the minimal size.
Definition widget_type.h:1156
MakeNWidgets
std::unique_ptr< NWidgetBase > MakeNWidgets(std::span< const NWidgetPart > nwid_parts, std::unique_ptr< NWidgetBase > &&container)
Construct a nested widget tree from an array of parts.
Definition widget.cpp:3374
EndContainer
constexpr NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME,...
Definition widget_type.h:1229
NWidget
constexpr NWidgetPart NWidget(WidgetType tp, Colours col, WidgetID idx=INVALID_WIDGET)
Widget part function for starting a new 'real' widget.
Definition widget_type.h:1424
SetResize
constexpr NWidgetPart SetResize(int16_t dx, int16_t dy)
Widget part function for setting the resize step.
Definition widget_type.h:1145
heightmap_colours.h
The colour tables for heightmaps.
_violet_map_heights
static const uint32_t _violet_map_heights[]
Height map colours for the violet colour scheme, ordered by height.
Definition heightmap_colours.h:235
_dark_green_map_heights
static const uint32_t _dark_green_map_heights[]
Height map colours for the dark green colour scheme, ordered by height.
Definition heightmap_colours.h:132
_green_map_heights
static const uint32_t _green_map_heights[]
Height map colours for the green colour scheme, ordered by height.
Definition heightmap_colours.h:13
industry.h
Base of all industries.
IsTileForestIndustry
bool IsTileForestIndustry(TileIndex tile)
Check whether the tile is a forest.
Definition industry_cmd.cpp:978
GetIndustrySpec
const IndustrySpec * GetIndustrySpec(IndustryType thistype)
Accessor for array _industry_specs.
Definition industry_cmd.cpp:126
_sorted_industry_types
std::array< IndustryType, NUM_INDUSTRYTYPES > _sorted_industry_types
Industry types sorted by name.
Definition industry_gui.cpp:235
_displayed_industries
std::bitset< NUM_INDUSTRYTYPES > _displayed_industries
Communication from the industry chain window to the smallmap window about what industries to display.
Definition industry_gui.cpp:62
NUM_INDUSTRYTYPES
static const IndustryType NUM_INDUSTRYTYPES
total number of industry types, new and old; limited to 240 because we need some special ids like IT_...
Definition industry_type.h:45
InverseRemapCoords2
Point InverseRemapCoords2(int x, int y, bool clamp_to_map, bool *clamped)
Map 2D viewport or smallmap coordinate to 3D world or tile coordinate.
Definition landscape.cpp:114
landscape.h
Functions related to OTTD's landscape.
InverseRemapCoords
Point InverseRemapCoords(int x, int y)
Map 2D viewport or smallmap coordinate to 3D world or tile coordinate.
Definition landscape.h:111
linkgraph_gui.h
Declaration of linkgraph overlay GUI.
TileXY
static TileIndex TileXY(uint x, uint y)
Returns the TileIndex of a coordinate.
Definition map_func.h:385
TileY
static uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition map_func.h:437
TileX
static uint TileX(TileIndex tile)
Get the X component of a tile.
Definition map_func.h:427
IsInsideMM
constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
Definition math_func.hpp:267
CeilDiv
constexpr uint CeilDiv(uint a, uint b)
Computes ceil(a / b) for non-negative a and b.
Definition math_func.hpp:310
Clamp
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition math_func.hpp:79
GetColourGradient
PixelColour GetColourGradient(Colours colour, ColourShade shade)
Get colour gradient palette index.
Definition palette.cpp:388
PC_TREES
static constexpr PixelColour PC_TREES
Green palette colour for trees.
Definition palette_func.h:124
PC_VERY_LIGHT_YELLOW
static constexpr PixelColour PC_VERY_LIGHT_YELLOW
Almost-white yellow palette colour.
Definition palette_func.h:111
PC_ROUGH_LAND
static constexpr PixelColour PC_ROUGH_LAND
Dark green palette colour for rough land.
Definition palette_func.h:119
PC_YELLOW
static constexpr PixelColour PC_YELLOW
Yellow palette colour.
Definition palette_func.h:109
PC_GREEN
static constexpr PixelColour PC_GREEN
Green palette colour.
Definition palette_func.h:113
PC_FIELDS
static constexpr PixelColour PC_FIELDS
Light brown palette colour for fields.
Definition palette_func.h:123
PC_DARK_RED
static constexpr PixelColour PC_DARK_RED
Dark red palette colour.
Definition palette_func.h:102
PC_WATER
static constexpr PixelColour PC_WATER
Dark blue palette colour for water.
Definition palette_func.h:125
PC_ORANGE
static constexpr PixelColour PC_ORANGE
Orange palette colour.
Definition palette_func.h:107
PC_GRASS_LAND
static constexpr PixelColour PC_GRASS_LAND
Dark green palette colour for grass land.
Definition palette_func.h:120
PC_BARE_LAND
static constexpr PixelColour PC_BARE_LAND
Brown palette colour for bare land.
Definition palette_func.h:121
PC_GREY
static constexpr PixelColour PC_GREY
Grey palette colour.
Definition palette_func.h:98
PC_RED
static constexpr PixelColour PC_RED
Red palette colour.
Definition palette_func.h:103
PC_DARK_GREY
static constexpr PixelColour PC_DARK_GREY
Dark grey palette colour.
Definition palette_func.h:97
PC_BLACK
static constexpr PixelColour PC_BLACK
Black palette colour.
Definition palette_func.h:96
PC_RAINFOREST
static constexpr PixelColour PC_RAINFOREST
Pale green palette colour for rainforest.
Definition palette_func.h:122
PC_WHITE
static constexpr PixelColour PC_WHITE
White palette colour.
Definition palette_func.h:99
PC_VERY_DARK_BROWN
static constexpr PixelColour PC_VERY_DARK_BROWN
Almost-black brown palette colour.
Definition palette_func.h:105
PC_LIGHT_BLUE
static constexpr PixelColour PC_LIGHT_BLUE
Light blue palette colour.
Definition palette_func.h:117
GetRailTypeInfo
const RailTypeInfo * GetRailTypeInfo(RailType railtype)
Returns a pointer to the Railtype information for a given railtype.
Definition rail.h:300
GetRailType
RailType GetRailType(Tile t)
Gets the rail type of the given tile.
Definition rail_map.h:115
GetRoadTypeInfo
const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
Definition road.h:215
GetRoadOwner
Owner GetRoadOwner(Tile t, RoadTramType rtt)
Get the owner of a specific road type.
Definition road_map.h:218
RTT_ROAD
@ RTT_ROAD
Road road type.
Definition road_type.h:38
RTT_TRAM
@ RTT_TRAM
Tram road type.
Definition road_type.h:39
INVALID_ROADTYPE
@ INVALID_ROADTYPE
flag for invalid roadtype
Definition road_type.h:28
safeguards.h
A number of safeguards to prevent using unsafe methods.
_settings_game
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
_settings_client
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:60
VSM_VIEWPORT_RMB_FIXED
@ VSM_VIEWPORT_RMB_FIXED
Viewport moves with mouse movement on holding right mouse button, cursor position is fixed.
Definition settings_type.h:148
VSM_MAP_RMB_FIXED
@ VSM_MAP_RMB_FIXED
Map moves with mouse movement on holding right mouse button, cursor position is fixed.
Definition settings_type.h:149
SWS_OFF
@ SWS_OFF
Scroll wheel has no effect.
Definition settings_type.h:159
MK
#define MK(a, b)
Macro for ordinary entry of LegendAndColour.
Definition smallmap_gui.cpp:63
ShowSmallMap
void ShowSmallMap()
Show the smallmap window.
Definition smallmap_gui.cpp:2065
_smallmap_vehicles_andor
static const AndOr _smallmap_vehicles_andor[]
Colour masks for "Vehicles", "Industry", and "Vegetation" modes.
Definition smallmap_gui.cpp:391
GetSmallMapLinkStatsPixels
static uint32_t GetSmallMapLinkStatsPixels(TileIndex tile, TileType t)
Return the colour a tile would be displayed with in the small map in mode "link stats".
Definition smallmap_gui.cpp:524
GetSmallMapContoursPixels
static uint32_t GetSmallMapContoursPixels(TileIndex tile, TileType t)
Return the colour a tile would be displayed with in the small map in mode "Contour".
Definition smallmap_gui.cpp:429
BuildLandLegend
void BuildLandLegend()
(Re)build the colour tables for the legends.
Definition smallmap_gui.cpp:290
_legend_from_industries
static LegendAndColour _legend_from_industries[NUM_INDUSTRYTYPES+1]
Allow room for all industries, plus a terminator entry This is required in order to have the industry...
Definition smallmap_gui.cpp:172
MS
#define MS(a, b)
Macro for break marker in arrays of LegendAndColour.
Definition smallmap_gui.cpp:81
MC
#define MC(col_break)
Macro for a height legend entry with configurable colour.
Definition smallmap_gui.cpp:66
_linkstat_colours_in_legenda
static const uint8_t _linkstat_colours_in_legenda[]
Link stat colours shown in legenda.
Definition smallmap_gui.cpp:58
_industry_to_list_pos
static uint _industry_to_list_pos[NUM_INDUSTRYTYPES]
For connecting industry type to position in industries list(small map legend)
Definition smallmap_gui.cpp:174
_tiletype_importance
static const uint8_t _tiletype_importance[]
Mapping of tile type to importance of the tile (higher number means more interesting to show).
Definition smallmap_gui.cpp:407
_smallmap_industry_highlight
static IndustryType _smallmap_industry_highlight
Highlight a specific industry type.
Definition smallmap_gui.cpp:180
BuildOwnerLegend
void BuildOwnerLegend()
Completes the array for the owned property legend.
Definition smallmap_gui.cpp:341
NUM_NO_COMPANY_ENTRIES
static const int NUM_NO_COMPANY_ENTRIES
Number of entries in the owner legend that are not companies.
Definition smallmap_gui.cpp:60
_smallmap_cargo_count
static int _smallmap_cargo_count
Number of cargos in the link stats legend.
Definition smallmap_gui.cpp:43
GetSmallMapOwnerPixels
uint32_t GetSmallMapOwnerPixels(TileIndex tile, TileType t, IncludeHeightmap include_heightmap)
Return the colour a tile would be displayed with in the small map in mode "Owner".
Definition smallmap_gui.cpp:580
_smallmap_company_count
static int _smallmap_company_count
Number of entries in the owner legend.
Definition smallmap_gui.cpp:42
_heightmap_schemes
static SmallMapColourScheme _heightmap_schemes[]
Available colour schemes for height maps.
Definition smallmap_gui.cpp:281
_nested_smallmap_display
static constexpr std::initializer_list< NWidgetPart > _nested_smallmap_display
Widget parts of the smallmap display.
Definition smallmap_gui.cpp:1966
_vehicle_type_colours
static const PixelColour _vehicle_type_colours[6]
Vehicle colours in SMT_VEHICLES mode.
Definition smallmap_gui.cpp:610
GetSmallMapVegetationPixels
static uint32_t GetSmallMapVegetationPixels(TileIndex tile, TileType t)
Return the colour a tile would be displayed with in the smallmap in mode "Vegetation".
Definition smallmap_gui.cpp:547
_nested_smallmap_bar
static constexpr std::initializer_list< NWidgetPart > _nested_smallmap_bar
Widget parts of the smallmap legend bar + image buttons.
Definition smallmap_gui.cpp:1973
GetSmallMapIndustriesPixels
static uint32_t GetSmallMapIndustriesPixels(TileIndex tile, TileType t)
Return the colour a tile would be displayed with in the small map in mode "Industries".
Definition smallmap_gui.cpp:455
_legend_land_contours
static LegendAndColour _legend_land_contours[]
Legend text giving the colours to look for on the minimap.
Definition smallmap_gui.cpp:84
_smallmap_show_heightmap
static bool _smallmap_show_heightmap
Show heightmap in industry and owner mode of smallmap window.
Definition smallmap_gui.cpp:178
SmallMapType
SmallMapType
Types of legends in the WID_SM_LEGEND widget.
Definition smallmap_gui.cpp:615
_smallmap_industry_count
static int _smallmap_industry_count
Number of used industries.
Definition smallmap_gui.cpp:41
_smallmap_industry_highlight_state
static bool _smallmap_industry_highlight_state
State of highlight blinking.
Definition smallmap_gui.cpp:182
BuildLinkStatsLegend
void BuildLinkStatsLegend()
Populate legend table for the link stat view.
Definition smallmap_gui.cpp:219
GetSmallMapRoutesPixels
static uint32_t GetSmallMapRoutesPixels(TileIndex tile, TileType t)
Return the colour a tile would be displayed with in the small map in mode "Routes".
Definition smallmap_gui.cpp:468
_industry_to_name_string_width
static uint16_t _industry_to_name_string_width[NUM_INDUSTRYTYPES]
The string bounding box width for each industry type in the smallmap.
Definition smallmap_gui.cpp:176
MKEND
#define MKEND()
Macro for end of list marker in arrays of LegendAndColour.
Definition smallmap_gui.cpp:75
GetSmallMapVehiclesPixels
static uint32_t GetSmallMapVehiclesPixels(TileIndex, TileType t)
Return the colour a tile would be displayed with in the small map in mode "Vehicles".
Definition smallmap_gui.cpp:442
ScrollMainWindowTo
bool ScrollMainWindowTo(int x, int y, int z, bool instant)
Scrolls the main window to given coordinates.
Definition smallmap_gui.cpp:2078
_company_to_list_pos
static TypedIndexContainer< std::array< uint32_t, MAX_COMPANIES >, CompanyID > _company_to_list_pos
For connecting company ID to position in owner list (small map legend)
Definition smallmap_gui.cpp:184
BuildIndustriesLegend
void BuildIndustriesLegend()
Fills an array for the industries legends.
Definition smallmap_gui.cpp:189
_smallmap_contours_andor
static const AndOr _smallmap_contours_andor[]
Colour masks for "Contour" and "Routes" modes.
Definition smallmap_gui.cpp:375
MOEND
#define MOEND()
Macro used for forcing a rebuild of the owner legend the first time it is used.
Definition smallmap_gui.cpp:72
_legend_linkstats
static LegendAndColour _legend_linkstats[NUM_CARGO+lengthof(_linkstat_colours_in_legenda)+1]
Legend entries for the link stats view.
Definition smallmap_gui.cpp:167
MO
#define MO(a, b)
Macro for non-company owned property entry of LegendAndColour.
Definition smallmap_gui.cpp:69
GetSmallMapStationMiddle
Point GetSmallMapStationMiddle(const Window *w, const Station *st)
Determine the middle of a station in the smallmap window.
Definition smallmap_gui.cpp:2099
smallmap_gui.h
Smallmap GUI functions.
IncludeHeightmap
IncludeHeightmap
Enum for how to include the heightmap pixels/colours in small map related functions.
Definition smallmap_gui.h:27
IncludeHeightmap::Always
@ Always
Always include the heightmap.
IncludeHeightmap::IfEnabled
@ IfEnabled
Only include the heightmap if its enabled in the gui by the player.
smallmap_widget.h
Types related to the smallmap widgets.
WID_SM_OWNERS
@ WID_SM_OWNERS
Button to select the owners view.
Definition smallmap_widget.h:28
WID_SM_VEHICLES
@ WID_SM_VEHICLES
Button to select the vehicles view.
Definition smallmap_widget.h:23
WID_SM_MAP_BORDER
@ WID_SM_MAP_BORDER
Border around the smallmap.
Definition smallmap_widget.h:16
WID_SM_CENTERMAP
@ WID_SM_CENTERMAP
Button to move smallmap center to main window center.
Definition smallmap_widget.h:29
WID_SM_VEGETATION
@ WID_SM_VEGETATION
Button to select the vegetation view.
Definition smallmap_widget.h:27
WID_SM_TOGGLETOWNNAME
@ WID_SM_TOGGLETOWNNAME
Toggle button to display town names.
Definition smallmap_widget.h:30
WID_SM_CONTOUR
@ WID_SM_CONTOUR
Button to select the contour view (height map).
Definition smallmap_widget.h:22
WID_SM_ENABLE_ALL
@ WID_SM_ENABLE_ALL
Button to enable display of all legend entries.
Definition smallmap_widget.h:32
WID_SM_SHOW_HEIGHT
@ WID_SM_SHOW_HEIGHT
Show heightmap toggle button.
Definition smallmap_widget.h:34
WID_SM_ZOOM_OUT
@ WID_SM_ZOOM_OUT
Button to zoom out one step.
Definition smallmap_widget.h:21
WID_SM_LEGEND
@ WID_SM_LEGEND
Bottom panel to display smallmap legends.
Definition smallmap_widget.h:18
WID_SM_ZOOM_IN
@ WID_SM_ZOOM_IN
Button to zoom in one step.
Definition smallmap_widget.h:20
WID_SM_MAP
@ WID_SM_MAP
Panel containing the smallmap.
Definition smallmap_widget.h:17
WID_SM_SHOW_IND_NAMES
@ WID_SM_SHOW_IND_NAMES
Show industry names toggle button.
Definition smallmap_widget.h:35
WID_SM_SELECT_BUTTONS
@ WID_SM_SELECT_BUTTONS
Selection widget for the buttons present in some smallmap modes.
Definition smallmap_widget.h:31
WID_SM_BLANK
@ WID_SM_BLANK
Empty button as placeholder.
Definition smallmap_widget.h:19
WID_SM_LINKSTATS
@ WID_SM_LINKSTATS
Button to select the link stats view.
Definition smallmap_widget.h:25
WID_SM_SHOW_IND_NAMES_SEL
@ WID_SM_SHOW_IND_NAMES_SEL
Container for the 'show industry names' button, which can be hidden.
Definition smallmap_widget.h:36
WID_SM_ROUTES
@ WID_SM_ROUTES
Button to select the routes view.
Definition smallmap_widget.h:26
WID_SM_INDUSTRIES
@ WID_SM_INDUSTRIES
Button to select the industries view.
Definition smallmap_widget.h:24
WID_SM_CAPTION
@ WID_SM_CAPTION
Caption of the window.
Definition smallmap_widget.h:15
WID_SM_DISABLE_ALL
@ WID_SM_DISABLE_ALL
Button to disable display of all legend entries.
Definition smallmap_widget.h:33
SndClickBeep
void SndClickBeep()
Play a beep sound for a click event if enabled in settings.
Definition sound.cpp:253
sound_func.h
Functions related to sound.
station_map.h
Maps accessors for stations.
GetStationType
StationType GetStationType(Tile t)
Get the station type of this tile.
Definition station_map.h:44
stdafx.h
Definition of base types and functions in a cross-platform compatible way.
lengthof
#define lengthof(array)
Return the length of an fixed size array.
Definition stdafx.h:271
GetStringWithArgs
void GetStringWithArgs(StringBuilder &builder, StringID string, StringParameters &args, uint case_index, bool game_script)
Get a parsed string with most special stringcodes replaced by the string parameters.
Definition strings.cpp:336
GetString
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
Definition strings.cpp:424
_current_text_dir
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition strings.cpp:56
strings_func.h
Functions related to OTTD's strings.
StringID
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
Definition strings_type.h:19
TD_RTL
@ TD_RTL
Text is written right-to-left by default.
Definition strings_type.h:27
AndOr
Definition smallmap_gui.cpp:363
AutoRestoreBackup
Class to backup a specific variable and restore it upon destruction of this object to prevent stack v...
Definition backup_type.hpp:150
BaseStation::rect
StationRect rect
NOSAVE: Station spread out rectangle maintained by StationRect::xxx() functions.
Definition base_station_base.h:84
CargoSpec
Specification of a cargo type.
Definition cargotype.h:74
CargoSpec::Index
CargoType Index() const
Determines index of this cargospec.
Definition cargotype.h:108
CargoSpec::name
StringID name
Name of this type of cargo.
Definition cargotype.h:91
ClientSettings::gui
GUISettings gui
settings related to the GUI
Definition settings_type.h:650
Company
Definition company_base.h:127
ConstructionSettings::freeform_edges
bool freeform_edges
allow terraforming the tiles at the map edges
Definition settings_type.h:423
ConstructionSettings::map_height_limit
uint8_t map_height_limit
the maximum allowed heightlevel
Definition settings_type.h:410
Coord2D< int >
Coord2D::y
T y
Y coordinate.
Definition geometry_type.hpp:35
Coord2D::x
T x
X coordinate.
Definition geometry_type.hpp:34
CursorVars::fix_at
bool fix_at
mouse is moving, but cursor is not (used for scrolling)
Definition gfx_type.h:128
CursorVars::pos
Point pos
logical mouse position
Definition gfx_type.h:125
DrawPixelInfo
Data about how and where to blit pixels.
Definition gfx_type.h:157
GUISettings::linkgraph_colours
uint8_t linkgraph_colours
linkgraph overlay colours
Definition settings_type.h:178
GUISettings::scroll_mode
uint8_t scroll_mode
viewport scroll mode
Definition settings_type.h:179
GUISettings::scrollwheel_scrolling
uint8_t scrollwheel_scrolling
scrolling using the scroll wheel?
Definition settings_type.h:203
GUISettings::smallmap_land_colour
uint8_t smallmap_land_colour
colour used for land and heightmap at the smallmap
Definition settings_type.h:177
GameCreationSettings::landscape
LandscapeType landscape
the landscape we're currently in
Definition settings_type.h:395
GameSettings::construction
ConstructionSettings construction
construction of things in-game
Definition settings_type.h:635
GameSettings::game_creation
GameCreationSettings game_creation
settings used during the creation of a game (map)
Definition settings_type.h:634
IndustrySpec
Defines the data structure for constructing industry.
Definition industrytype.h:103
IndustrySpec::name
StringID name
Displayed name of the industry.
Definition industrytype.h:123
IndustrySpec::enabled
bool enabled
entity still available (by default true).newgrf can disable it, though
Definition industrytype.h:133
IndustrySpec::map_colour
PixelColour map_colour
colour used for the small map
Definition industrytype.h:122
Industry
Defines the internal data of a functional industry.
Definition industry.h:62
Industry::type
IndustryType type
type of industry.
Definition industry.h:115
Industry::GetIndustryTypeCount
static uint16_t GetIndustryTypeCount(IndustryType type)
Get the count of industries for this type.
Definition industry.h:264
Industry::GetByTile
static Industry * GetByTile(TileIndex tile)
Get the industry of the given tile.
Definition industry.h:251
LegendAndColour
Structure for holding relevant data for legends in small map.
Definition smallmap_gui.cpp:46
LegendAndColour::colour
PixelColour colour
Colour of the item on the map.
Definition smallmap_gui.cpp:47
LegendAndColour::height
uint8_t height
Height in tiles. Only valid for height legend entries.
Definition smallmap_gui.cpp:50
LegendAndColour::legend
StringID legend
String corresponding to the coloured item.
Definition smallmap_gui.cpp:48
LegendAndColour::show_on_map
bool show_on_map
For filtering industries, if true, industry is shown on the map in colour.
Definition smallmap_gui.cpp:52
LegendAndColour::company
CompanyID company
Company to display. Only valid for company entries of the owner legend.
Definition smallmap_gui.cpp:51
LegendAndColour::end
bool end
This is the end of the list.
Definition smallmap_gui.cpp:53
LegendAndColour::col_break
bool col_break
Perform a column break and go further at the next column.
Definition smallmap_gui.cpp:54
LegendAndColour::type
IndustryType type
Type of industry. Only valid for industry entries.
Definition smallmap_gui.cpp:49
Map::MaxY
static uint MaxY()
Gets the maximum Y coordinate within the map, including MP_VOID.
Definition map_func.h:308
Map::MaxX
static uint MaxX()
Gets the maximum X coordinate within the map, including MP_VOID.
Definition map_func.h:299
OrthogonalTileArea
Represents the covered area of e.g.
Definition tilearea_type.h:18
OrthogonalTileArea::ClampToMap
void ClampToMap()
Clamp the tile area to map borders.
Definition tilearea.cpp:142
PixelColour
Colour for pixel/line drawing.
Definition gfx_type.h:405
PixelColour::p
uint8_t p
Palette index.
Definition gfx_type.h:406
PoolID< uint8_t, struct CompanyIDTag, 0xF, 0xFF >
Pool::PoolItem<&_company_pool >::Iterate
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Definition pool_type.hpp:436
Pool::PoolItem<&_company_pool >::IsValidID
static bool IsValidID(auto index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
Definition pool_type.hpp:376
Pool::MAX_SIZE
static constexpr size_t MAX_SIZE
Make template parameter accessible from outside.
Definition pool_type.hpp:135
RectPadding::Horizontal
constexpr uint Horizontal() const
Get total horizontal padding of RectPadding.
Definition geometry_type.hpp:89
RectPadding::Vertical
constexpr uint Vertical() const
Get total vertical padding of RectPadding.
Definition geometry_type.hpp:95
Rect
Specification of a rectangle with absolute coordinates of all edges.
Definition geometry_type.hpp:101
Rect::WithWidth
Rect WithWidth(int width, bool end) const
Copy Rect and set its width.
Definition geometry_type.hpp:211
Rect::Width
int Width() const
Get width of Rect.
Definition geometry_type.hpp:111
Rect::Shrink
Rect Shrink(int s) const
Copy and shrink Rect by s pixels.
Definition geometry_type.hpp:124
Rect::WithHeight
Rect WithHeight(int height, bool end=false) const
Copy Rect and set its height.
Definition geometry_type.hpp:237
Rect::Indent
Rect Indent(int indent, bool end) const
Copy Rect and indent it from its position.
Definition geometry_type.hpp:224
Rect::Translate
Rect Translate(int x, int y) const
Copy and translate Rect by x,y pixels.
Definition geometry_type.hpp:200
SmallMapColourScheme
Colour scheme of the smallmap.
Definition smallmap_gui.cpp:274
SmallMapColourScheme::height_colours
std::vector< uint32_t > height_colours
Cached colours for each level in a map.
Definition smallmap_gui.cpp:275
SmallMapColourScheme::default_colour
uint32_t default_colour
Default colour of the land.
Definition smallmap_gui.cpp:277
SmallMapColourScheme::height_colours_base
std::span< const uint32_t > height_colours_base
Base table for determining the colours.
Definition smallmap_gui.cpp:276
Station
Station data structure.
Definition station_base.h:500
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > >
Town
Town data structure.
Definition town.h:63
Vehicle
Vehicle data structure.
Definition vehicle_base.h:205
Viewport
Data structure for viewport, display of a part of the world.
Definition viewport_type.h:31
Viewport::virtual_top
int virtual_top
Virtual top coordinate.
Definition viewport_type.h:38
Viewport::virtual_left
int virtual_left
Virtual left coordinate.
Definition viewport_type.h:37
Viewport::virtual_width
int virtual_width
width << zoom
Definition viewport_type.h:39
Viewport::virtual_height
int virtual_height
height << zoom
Definition viewport_type.h:40
WindowDesc
High level window description.
Definition window_gui.h:168
Window
Data structure for an opened window.
Definition window_gui.h:274
Window::Close
virtual void Close(int data=0)
Hide the window and all its child windows, and mark them for a later deletion.
Definition window.cpp:1102
Window::viewport
std::unique_ptr< ViewportData > viewport
Pointer to viewport data, if present.
Definition window_gui.h:319
Window::GetWidgetString
virtual std::string GetWidgetString(WidgetID widget, StringID stringid) const
Get the raw string for a widget.
Definition window.cpp:504
TileHeight
static uint TileHeight(Tile tile)
Returns the height of a tile.
Definition tile_map.h:29
GetTileOwner
Owner GetTileOwner(Tile tile)
Returns the owner of a tile.
Definition tile_map.h:178
GetTropicZone
TropicZone GetTropicZone(Tile tile)
Get the tropic zone.
Definition tile_map.h:238
GetTileType
static TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
Definition tile_map.h:96
MAX_TILE_HEIGHT
static constexpr uint MAX_TILE_HEIGHT
Maximum allowed tile height.
Definition tile_type.h:24
TROPICZONE_RAINFOREST
@ TROPICZONE_RAINFOREST
Rainforest tile.
Definition tile_type.h:79
INVALID_TILE
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:95
TILE_SIZE
static constexpr uint TILE_SIZE
Tile size in world coordinates.
Definition tile_type.h:15
TileType
TileType
The different types of tiles.
Definition tile_type.h:47
MP_TREES
@ MP_TREES
Tile got trees.
Definition tile_type.h:52
MP_ROAD
@ MP_ROAD
A tile with road (or tram tracks)
Definition tile_type.h:50
MP_STATION
@ MP_STATION
A tile of a station.
Definition tile_type.h:53
MP_TUNNELBRIDGE
@ MP_TUNNELBRIDGE
Tunnel entry/exit and bridge heads.
Definition tile_type.h:57
MP_CLEAR
@ MP_CLEAR
A tile without any structures, i.e. grass, rocks, farm fields etc.
Definition tile_type.h:48
MP_HOUSE
@ MP_HOUSE
A house by a town.
Definition tile_type.h:51
MP_WATER
@ MP_WATER
Water tile.
Definition tile_type.h:54
MP_RAILWAY
@ MP_RAILWAY
A railway.
Definition tile_type.h:49
MP_INDUSTRY
@ MP_INDUSTRY
Part of an industry.
Definition tile_type.h:56
MP_VOID
@ MP_VOID
Invisible tiles at the SW and SE border.
Definition tile_type.h:55
TileArea
OrthogonalTileArea TileArea
Shorthand for the much more common orthogonal tile area.
Definition tilearea_type.h:102
timer.h
Definition of Interval and OneShot timers.
timer_window.h
Definition of the Window system.
TIMER_BLINK_INTERVAL
static constexpr std::chrono::milliseconds TIMER_BLINK_INTERVAL
Interval used by blinking interface elements.
Definition timer_window.h:36
town.h
Base of the town class.
TransportType
TransportType
Available types of transport.
Definition transport_type.h:17
TRANSPORT_RAIL
@ TRANSPORT_RAIL
Transport by train.
Definition transport_type.h:25
TRANSPORT_ROAD
@ TRANSPORT_ROAD
Transport by road vehicle.
Definition transport_type.h:26
tree_map.h
Map accessors for tree tiles.
GetTreeGround
TreeGround GetTreeGround(Tile t)
Returns the groundtype for tree tiles.
Definition tree_map.h:102
TREE_GROUND_ROUGH_SNOW
@ TREE_GROUND_ROUGH_SNOW
A snow tile that is rough underneath.
Definition tree_map.h:57
TREE_GROUND_SNOW_DESERT
@ TREE_GROUND_SNOW_DESERT
a desert or snow tile, depend on landscape
Definition tree_map.h:55
tunnelbridge_map.h
Functions that have tunnels and bridges in common.
GetTunnelBridgeTransportType
TransportType GetTunnelBridgeTransportType(Tile t)
Tunnel: Get the transport type of the tunnel (road or rail) Bridge: Get the transport type of the bri...
Definition tunnelbridge_map.h:39
vehicle_base.h
Base class for all vehicles.
VEH_EFFECT
@ VEH_EFFECT
Effect vehicle type (smoke, explosions, sparks, bubbles)
Definition vehicle_type.h:32
ScrollWindowTo
bool ScrollWindowTo(int x, int y, int z, Window *w, bool instant)
Scrolls the viewport in a window to a given location.
Definition viewport.cpp:2546
viewport_func.h
Functions related to (drawing on) viewports.
TILE_HEIGHT_STEP
static const int TILE_HEIGHT_STEP
One Z unit tile height difference is displayed as 50m.
Definition viewport_func.h:21
IsTileOnWater
bool IsTileOnWater(Tile t)
Tests if the tile was built on water.
Definition water_map.h:138
ScaleGUITrad
static RectPadding ScaleGUITrad(const RectPadding &r)
Scale a RectPadding to GUI zoom level.
Definition widget.cpp:49
WWT_PUSHTXTBTN
@ WWT_PUSHTXTBTN
Normal push-button (no toggle button) with text caption.
Definition widget_type.h:104
WWT_INSET
@ WWT_INSET
Pressed (inset) panel, most commonly used as combo box text area.
Definition widget_type.h:40
WWT_IMGBTN
@ WWT_IMGBTN
(Toggle) Button with image
Definition widget_type.h:41
WWT_PUSHIMGBTN
@ WWT_PUSHIMGBTN
Normal push-button (no toggle button) with image caption.
Definition widget_type.h:105
NWID_SPACER
@ NWID_SPACER
Invisible widget that takes some space.
Definition widget_type.h:70
NWID_HORIZONTAL
@ NWID_HORIZONTAL
Horizontal container.
Definition widget_type.h:66
WWT_TEXTBTN
@ WWT_TEXTBTN
(Toggle) Button with text
Definition widget_type.h:44
WWT_PANEL
@ WWT_PANEL
Simple depressed panel.
Definition widget_type.h:39
WWT_STICKYBOX
@ WWT_STICKYBOX
Sticky box (at top-right of a window, after WWT_DEFSIZEBOX)
Definition widget_type.h:57
WWT_SHADEBOX
@ WWT_SHADEBOX
Shade box (at top-right of a window, between WWT_DEBUGBOX and WWT_DEFSIZEBOX)
Definition widget_type.h:55
WWT_CAPTION
@ WWT_CAPTION
Window caption (window title between closebox and stickybox)
Definition widget_type.h:52
NWID_VERTICAL
@ NWID_VERTICAL
Vertical container.
Definition widget_type.h:68
WWT_CLOSEBOX
@ WWT_CLOSEBOX
Close box (at top-left of a window)
Definition widget_type.h:60
WWT_EMPTY
@ WWT_EMPTY
Empty widget, place holder to reserve space in widget tree.
Definition widget_type.h:37
WWT_RESIZEBOX
@ WWT_RESIZEBOX
Resize box (normally at bottom-right of a window)
Definition widget_type.h:59
WWT_DEFSIZEBOX
@ WWT_DEFSIZEBOX
Default window size box (at top-right of a window, between WWT_SHADEBOX and WWT_STICKYBOX)
Definition widget_type.h:56
NWID_SELECTION
@ NWID_SELECTION
Stacked widgets, only one visible at a time (eg in a panel with tabs).
Definition widget_type.h:71
SZSP_NONE
@ SZSP_NONE
Display plane with zero size in both directions (none filling and resizing).
Definition widget_type.h:506
EqualSize
@ EqualSize
Containers should keep all their (resizing) children equally large.
Definition widget_type.h:541
SizingType
SizingType
Different forms of sizing nested widgets, using NWidgetBase::AssignSizePosition()
Definition widget_type.h:112
ST_RESIZE
@ ST_RESIZE
Resize the nested widget tree.
Definition widget_type.h:114
ST_SMALLEST
@ ST_SMALLEST
Initialize nested widget tree to smallest size. Also updates current_x and current_y.
Definition widget_type.h:113
GetMainWindow
Window * GetMainWindow()
Get the main window, i.e.
Definition window.cpp:1180
_scrolling_viewport
bool _scrolling_viewport
A viewport is being scrolled with the mouse.
Definition window.cpp:93
FindWindowById
Window * FindWindowById(WindowClass cls, WindowNumber number)
Find a window by its class and window number.
Definition window.cpp:1151
InvalidateWindowClassesData
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:3311
window_func.h
Window functions not directly related to making/drawing windows.
WDP_AUTO
@ WDP_AUTO
Find a place automatically.
Definition window_gui.h:144
WidgetID
int WidgetID
Widget ID.
Definition window_type.h:20
WC_NONE
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
Definition window_type.h:50
WC_INDUSTRY_CARGOES
@ WC_INDUSTRY_CARGOES
Industry cargoes chain; Window numbers:
Definition window_type.h:520
WC_SMALLMAP
@ WC_SMALLMAP
Small map; Window numbers:
Definition window_type.h:109
zoom_func.h
Functions related to zooming.