OpenTTD Source: src/town_gui.cpp Source File

OpenTTD Source 15.3

town_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 "town.h"
12#include "viewport_func.h"
13#include "error.h"
14#include "gui.h"
15#include "house.h"
16#include "newgrf_cargo.h"
17#include "newgrf_house.h"
18#include "newgrf_text.h"
19#include "picker_gui.h"
20#include "command_func.h"
21#include "company_func.h"
22#include "company_base.h"
23#include "company_gui.h"
24#include "network/network.h"
25#include "string_func.h"
26#include "strings_func.h"
27#include "sound_func.h"
28#include "tilehighlight_func.h"
29#include "sortlist_type.h"
30#include "road_cmd.h"
31#include "landscape.h"
32#include "querystring_gui.h"
33#include "window_func.h"
34#include "townname_func.h"
35#include "core/backup_type.hpp"
36#include "core/geometry_func.hpp"
37#include "core/string_consumer.hpp"
38#include "genworld.h"
39#include "fios.h"
40#include "stringfilter_type.h"
41#include "dropdown_func.h"
42#include "town_kdtree.h"
43#include "town_cmd.h"
44#include "timer/timer.h"
45#include "timer/timer_game_calendar.h"
46#include "timer/timer_window.h"
47#include "zoom_func.h"
48#include "hotkeys.h"
49#include "graph_gui.h"
50
51#include "widgets/town_widget.h"
52
53#include "table/strings.h"
54
55#include "safeguards.h"
56
57 TownKdtree _town_local_authority_kdtree{};
58
59typedef GUIList<const Town*, const bool &> GUITownList;
60
61static constexpr std::initializer_list<NWidgetPart> _nested_town_authority_widgets = {
62 NWidget(NWID_HORIZONTAL),
63 NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
64 NWidget(WWT_CAPTION, COLOUR_BROWN, WID_TA_CAPTION),
65 NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_TA_ZONE_BUTTON), SetMinimalSize(50, 0), SetStringTip(STR_LOCAL_AUTHORITY_ZONE, STR_LOCAL_AUTHORITY_ZONE_TOOLTIP),
66 NWidget(WWT_SHADEBOX, COLOUR_BROWN),
67 NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
68 NWidget(WWT_STICKYBOX, COLOUR_BROWN),
69 EndContainer(),
70 NWidget(WWT_PANEL, COLOUR_BROWN, WID_TA_RATING_INFO), SetMinimalSize(317, 92), SetResize(1, 1), EndContainer(),
71 NWidget(WWT_PANEL, COLOUR_BROWN, WID_TA_COMMAND_LIST), SetMinimalSize(317, 52), SetResize(1, 0), SetToolTip(STR_LOCAL_AUTHORITY_ACTIONS_TOOLTIP), EndContainer(),
72 NWidget(WWT_PANEL, COLOUR_BROWN, WID_TA_ACTION_INFO), SetMinimalSize(317, 52), SetResize(1, 0), EndContainer(),
73 NWidget(NWID_HORIZONTAL),
74 NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TA_EXECUTE), SetMinimalSize(317, 12), SetResize(1, 0), SetFill(1, 0), SetStringTip(STR_LOCAL_AUTHORITY_DO_IT_BUTTON, STR_LOCAL_AUTHORITY_DO_IT_TOOLTIP),
75 NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
76 EndContainer()
77};
78
80 struct TownAuthorityWindow : Window {
81private:
82 Town *town = nullptr;
83 TownAction sel_action = TownAction::End;
84 TownActions displayed_actions_on_previous_painting{};
85 TownActions enabled_actions{};
86 TownActions available_actions{};
87 std::array<StringID, to_underlying(TownAction::End)> action_tooltips{};
88
89 Dimension icon_size{};
90 Dimension exclusive_size{};
91
97 static TownActions GetEnabledActions()
98 {
99 TownActions enabled{};
100 enabled.Set();
101
102 if (!_settings_game.economy.fund_roads) enabled.Reset(TownAction::RoadRebuild);
103 if (!_settings_game.economy.fund_buildings) enabled.Reset(TownAction::FundBuildings);
104 if (!_settings_game.economy.exclusive_rights) enabled.Reset(TownAction::BuyRights);
105 if (!_settings_game.economy.bribe) enabled.Reset(TownAction::Bribe);
106
107 return enabled;
108 }
109
110public:
111 TownAuthorityWindow(WindowDesc &desc, WindowNumber window_number) : Window(desc)
112 {
113 this->town = Town::Get(window_number);
114 this->enabled_actions = GetEnabledActions();
115
116 auto realtime = TimerGameEconomy::UsingWallclockUnits();
117 this->action_tooltips[0] = STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING;
118 this->action_tooltips[1] = STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING;
119 this->action_tooltips[2] = STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING;
120 this->action_tooltips[3] = realtime ? STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION_MINUTES : STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION_MONTHS;
121 this->action_tooltips[4] = STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY;
122 this->action_tooltips[5] = STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS;
123 this->action_tooltips[6] = realtime ? STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT_MINUTES : STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT_MONTHS;
124 this->action_tooltips[7] = STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE;
125
126 this->InitNested(window_number);
127 }
128
129 void OnInit() override
130 {
131 this->icon_size = GetSpriteSize(SPR_COMPANY_ICON);
132 this->exclusive_size = GetSpriteSize(SPR_EXCLUSIVE_TRANSPORT);
133 }
134
135 void OnPaint() override
136 {
137 this->available_actions = GetMaskOfTownActions(_local_company, this->town);
138 if (this->available_actions != displayed_actions_on_previous_painting) this->SetDirty();
139 displayed_actions_on_previous_painting = this->available_actions;
140
141 this->SetWidgetLoweredState(WID_TA_ZONE_BUTTON, this->town->show_zone);
142 this->SetWidgetDisabledState(WID_TA_EXECUTE, (this->sel_action == TownAction::End) || !this->available_actions.Test(this->sel_action));
143
144 this->DrawWidgets();
145 if (!this->IsShaded())
146 {
147 this->DrawRatings();
148 this->DrawActions();
149 }
150 }
151
152 StringID GetRatingString(int rating) const
153 {
154 if (rating > RATING_EXCELLENT) return STR_CARGO_RATING_OUTSTANDING;
155 if (rating > RATING_VERYGOOD) return STR_CARGO_RATING_EXCELLENT;
156 if (rating > RATING_GOOD) return STR_CARGO_RATING_VERY_GOOD;
157 if (rating > RATING_MEDIOCRE) return STR_CARGO_RATING_GOOD;
158 if (rating > RATING_POOR) return STR_CARGO_RATING_MEDIOCRE;
159 if (rating > RATING_VERYPOOR) return STR_CARGO_RATING_POOR;
160 if (rating > RATING_APPALLING) return STR_CARGO_RATING_VERY_POOR;
161 return STR_CARGO_RATING_APPALLING;
162 }
163
165 void DrawRatings()
166 {
167 Rect r = this->GetWidget<NWidgetBase>(WID_TA_RATING_INFO)->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect);
168
169 int text_y_offset = (this->resize.step_height - GetCharacterHeight(FS_NORMAL)) / 2;
170 int icon_y_offset = (this->resize.step_height - this->icon_size.height) / 2;
171 int exclusive_y_offset = (this->resize.step_height - this->exclusive_size.height) / 2;
172
173 DrawString(r.left, r.right, r.top + text_y_offset, STR_LOCAL_AUTHORITY_COMPANY_RATINGS);
174 r.top += this->resize.step_height;
175
176 bool rtl = _current_text_dir == TD_RTL;
177 Rect icon = r.WithWidth(this->icon_size.width, rtl);
178 Rect exclusive = r.Indent(this->icon_size.width + WidgetDimensions::scaled.hsep_normal, rtl).WithWidth(this->exclusive_size.width, rtl);
179 Rect text = r.Indent(this->icon_size.width + WidgetDimensions::scaled.hsep_normal + this->exclusive_size.width + WidgetDimensions::scaled.hsep_normal, rtl);
180
181 /* Draw list of companies */
182 for (const Company *c : Company::Iterate()) {
183 if ((this->town->have_ratings.Test(c->index) || this->town->exclusivity == c->index)) {
184 DrawCompanyIcon(c->index, icon.left, text.top + icon_y_offset);
185
186 if (this->town->exclusivity == c->index) {
187 DrawSprite(SPR_EXCLUSIVE_TRANSPORT, GetCompanyPalette(c->index), exclusive.left, text.top + exclusive_y_offset);
188 }
189
190 int rating = this->town->ratings[c->index];
191 DrawString(text.left, text.right, text.top + text_y_offset, GetString(STR_LOCAL_AUTHORITY_COMPANY_RATING, c->index, c->index, GetRatingString(rating)));
192 text.top += this->resize.step_height;
193 }
194 }
195
196 text.bottom = text.top - 1;
197 if (text.bottom > r.bottom) {
198 /* If the company list is too big to fit, mark ourself dirty and draw again. */
199 ResizeWindow(this, 0, text.bottom - r.bottom, false);
200 }
201 }
202
204 void DrawActions()
205 {
206 Rect r = this->GetWidget<NWidgetBase>(WID_TA_COMMAND_LIST)->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect);
207
208 DrawString(r, STR_LOCAL_AUTHORITY_ACTIONS_TITLE);
209 r.top += GetCharacterHeight(FS_NORMAL);
210
211 /* Draw list of actions */
212 for (TownAction i = {}; i != TownAction::End; ++i) {
213 /* Don't show actions if disabled in settings. */
214 if (!this->enabled_actions.Test(i)) continue;
215
216 /* Set colour of action based on ability to execute and if selected. */
217 TextColour action_colour = TC_GREY | TC_NO_SHADE;
218 if (this->available_actions.Test(i)) action_colour = TC_ORANGE;
219 if (this->sel_action == i) action_colour = TC_WHITE;
220
221 DrawString(r, STR_LOCAL_AUTHORITY_ACTION_SMALL_ADVERTISING_CAMPAIGN + to_underlying(i), action_colour);
222 r.top += GetCharacterHeight(FS_NORMAL);
223 }
224 }
225
226 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
227 {
228 if (widget == WID_TA_CAPTION) return GetString(STR_LOCAL_AUTHORITY_CAPTION, this->window_number);
229
230 return this->Window::GetWidgetString(widget, stringid);
231 }
232
233 void DrawWidget(const Rect &r, WidgetID widget) const override
234 {
235 switch (widget) {
236 case WID_TA_ACTION_INFO:
237 if (this->sel_action != TownAction::End) {
238 Money action_cost = _price[PR_TOWN_ACTION] * GetTownActionCost(this->sel_action) >> 8;
239 bool affordable = Company::IsValidID(_local_company) && action_cost < GetAvailableMoney(_local_company);
240
241 DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.framerect),
242 GetString(this->action_tooltips[to_underlying(this->sel_action)], action_cost),
243 affordable ? TC_YELLOW : TC_RED);
244 }
245 break;
246 }
247 }
248
249 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
250 {
251 switch (widget) {
252 case WID_TA_ACTION_INFO: {
253 assert(size.width > padding.width && size.height > padding.height);
254 Dimension d = {0, 0};
255 for (TownAction i = {}; i != TownAction::End; ++i) {
256 Money price = _price[PR_TOWN_ACTION] * GetTownActionCost(i) >> 8;
257 d = maxdim(d, GetStringMultiLineBoundingBox(GetString(this->action_tooltips[to_underlying(i)], price), size));
258 }
259 d.width += padding.width;
260 d.height += padding.height;
261 size = maxdim(size, d);
262 break;
263 }
264
265 case WID_TA_COMMAND_LIST:
266 size.height = (to_underlying(TownAction::End) + 1) * GetCharacterHeight(FS_NORMAL) + padding.height;
267 size.width = GetStringBoundingBox(STR_LOCAL_AUTHORITY_ACTIONS_TITLE).width;
268 for (TownAction i = {}; i != TownAction::End; ++i) {
269 size.width = std::max(size.width, GetStringBoundingBox(STR_LOCAL_AUTHORITY_ACTION_SMALL_ADVERTISING_CAMPAIGN + to_underlying(i)).width + padding.width);
270 }
271 size.width += padding.width;
272 break;
273
274 case WID_TA_RATING_INFO:
275 fill.height = resize.height = std::max({this->icon_size.height + WidgetDimensions::scaled.vsep_normal, this->exclusive_size.height + WidgetDimensions::scaled.vsep_normal, (uint)GetCharacterHeight(FS_NORMAL)});
276 size.height = 9 * resize.height + padding.height;
277 break;
278 }
279 }
280
281 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
282 {
283 switch (widget) {
284 case WID_TA_ZONE_BUTTON: {
285 bool new_show_state = !this->town->show_zone;
286 TownID index = this->town->index;
287
288 new_show_state ? _town_local_authority_kdtree.Insert(index) : _town_local_authority_kdtree.Remove(index);
289
290 this->town->show_zone = new_show_state;
291 this->SetWidgetLoweredState(widget, new_show_state);
292 SndClickBeep();
293 MarkWholeScreenDirty();
294 break;
295 }
296
297 case WID_TA_COMMAND_LIST: {
298 int y = this->GetRowFromWidget(pt.y, WID_TA_COMMAND_LIST, 1, GetCharacterHeight(FS_NORMAL)) - 1;
299
300 auto action = this->enabled_actions.GetNthSetBit(y);
301 if (!action.has_value()) break;
302
303 this->sel_action = *action;
304 this->SetDirty();
305
306 /* When double-clicking, continue */
307 if (click_count == 1 || !this->available_actions.Test(this->sel_action)) break;
308 [[fallthrough]];
309 }
310
311 case WID_TA_EXECUTE:
312 Command<CMD_DO_TOWN_ACTION>::Post(STR_ERROR_CAN_T_DO_THIS, this->town->xy, static_cast<TownID>(this->window_number), this->sel_action);
313 break;
314 }
315 }
316
318 const IntervalTimer<TimerWindow> redraw_interval = {std::chrono::seconds(3), [this](auto) {
319 this->SetDirty();
320 }};
321
322 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
323 {
324 if (!gui_scope) return;
325
326 this->enabled_actions = this->GetEnabledActions();
327 if (!this->enabled_actions.Test(this->sel_action)) {
328 this->sel_action = TownAction::End;
329 }
330 }
331};
332
333static WindowDesc _town_authority_desc(
334 WDP_AUTO, "view_town_authority", 317, 222,
335 WC_TOWN_AUTHORITY, WC_NONE,
336 {},
337 _nested_town_authority_widgets
338);
339
340static void ShowTownAuthorityWindow(uint town)
341{
342 AllocateWindowDescFront<TownAuthorityWindow>(_town_authority_desc, town);
343}
344
345
346/* Town view window. */
347 struct TownViewWindow : Window {
348private:
349 Town *town = nullptr;
350
351public:
352 static const int WID_TV_HEIGHT_NORMAL = 150;
353
354 TownViewWindow(WindowDesc &desc, WindowNumber window_number) : Window(desc)
355 {
356 this->CreateNestedTree();
357
358 this->town = Town::Get(window_number);
359
360 this->FinishInitNested(window_number);
361
362 this->flags.Set(WindowFlag::DisableVpScroll);
363 NWidgetViewport *nvp = this->GetWidget<NWidgetViewport>(WID_TV_VIEWPORT);
364 nvp->InitializeViewport(this, this->town->xy, ScaleZoomGUI(ZoomLevel::Town));
365
366 /* disable renaming town in network games if you are not the server */
367 this->SetWidgetDisabledState(WID_TV_CHANGE_NAME, _networking && !_network_server);
368 }
369
370 void Close([[maybe_unused]] int data = 0) override
371 {
372 SetViewportCatchmentTown(Town::Get(this->window_number), false);
373 this->Window::Close();
374 }
375
376 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
377 {
378 if (widget == WID_TV_CAPTION) return GetString(this->town->larger_town ? STR_TOWN_VIEW_CITY_CAPTION : STR_TOWN_VIEW_TOWN_CAPTION, this->town->index);
379
380 return this->Window::GetWidgetString(widget, stringid);
381 }
382
383 void OnPaint() override
384 {
385 extern const Town *_viewport_highlight_town;
386 this->SetWidgetLoweredState(WID_TV_CATCHMENT, _viewport_highlight_town == this->town);
387
388 this->DrawWidgets();
389 }
390
391 void DrawWidget(const Rect &r, WidgetID widget) const override
392 {
393 if (widget != WID_TV_INFO) return;
394
395 Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
396
397 DrawString(tr, GetString(STR_TOWN_VIEW_POPULATION_HOUSES, this->town->cache.population, this->town->cache.num_houses));
398 tr.top += GetCharacterHeight(FS_NORMAL);
399
400 StringID str_last_period = TimerGameEconomy::UsingWallclockUnits() ? STR_TOWN_VIEW_CARGO_LAST_MINUTE_MAX : STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX;
401
402 for (auto tpe : {TPE_PASSENGERS, TPE_MAIL}) {
403 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[tpe]) {
404 CargoType cargo_type = cs->Index();
405 auto it = this->town->GetCargoSupplied(cargo_type);
406 if (it == std::end(this->town->supplied)) {
407 DrawString(tr, GetString(str_last_period, 1ULL << cargo_type, 0, 0));
408 } else {
409 DrawString(tr, GetString(str_last_period, 1ULL << cargo_type, it->history[LAST_MONTH].transported, it->history[LAST_MONTH].production));
410 }
411 tr.top += GetCharacterHeight(FS_NORMAL);
412 }
413 }
414
415 bool first = true;
416 for (int i = TAE_BEGIN; i < TAE_END; i++) {
417 if (this->town->goal[i] == 0) continue;
418 if (this->town->goal[i] == TOWN_GROWTH_WINTER && (TileHeight(this->town->xy) < LowestSnowLine() || this->town->cache.population <= 90)) continue;
419 if (this->town->goal[i] == TOWN_GROWTH_DESERT && (GetTropicZone(this->town->xy) != TROPICZONE_DESERT || this->town->cache.population <= 60)) continue;
420
421 if (first) {
422 DrawString(tr, STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH);
423 tr.top += GetCharacterHeight(FS_NORMAL);
424 first = false;
425 }
426
427 bool rtl = _current_text_dir == TD_RTL;
428
429 const CargoSpec *cargo = FindFirstCargoWithTownAcceptanceEffect((TownAcceptanceEffect)i);
430 assert(cargo != nullptr);
431
432 StringID string;
433
434 if (this->town->goal[i] == TOWN_GROWTH_DESERT || this->town->goal[i] == TOWN_GROWTH_WINTER) {
435 /* For 'original' gameplay, don't show the amount required (you need 1 or more ..) */
436 string = STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_DELIVERED_GENERAL;
437 if (this->town->received[i].old_act == 0) {
438 string = STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL;
439
440 if (this->town->goal[i] == TOWN_GROWTH_WINTER && TileHeight(this->town->xy) < GetSnowLine()) {
441 string = STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER;
442 }
443 }
444
445 DrawString(tr.Indent(20, rtl), GetString(string, cargo->name));
446 } else {
447 string = STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_DELIVERED;
448 if (this->town->received[i].old_act < this->town->goal[i]) {
449 string = STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED;
450 }
451 DrawString(tr.Indent(20, rtl), GetString(string, cargo->Index(), this->town->received[i].old_act, cargo->Index(), this->town->goal[i]));
452 }
453 tr.top += GetCharacterHeight(FS_NORMAL);
454 }
455
456 if (this->town->flags.Test(TownFlag::IsGrowing)) {
457 DrawString(tr, GetString(this->town->fund_buildings_months == 0 ? STR_TOWN_VIEW_TOWN_GROWS_EVERY : STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED, RoundDivSU(this->town->growth_rate + 1, Ticks::DAY_TICKS)));
458 tr.top += GetCharacterHeight(FS_NORMAL);
459 } else {
460 DrawString(tr, STR_TOWN_VIEW_TOWN_GROW_STOPPED);
461 tr.top += GetCharacterHeight(FS_NORMAL);
462 }
463
464 /* only show the town noise, if the noise option is activated. */
465 if (_settings_game.economy.station_noise_level) {
466 DrawString(tr, GetString(STR_TOWN_VIEW_NOISE_IN_TOWN, this->town->noise_reached, this->town->MaxTownNoise()));
467 tr.top += GetCharacterHeight(FS_NORMAL);
468 }
469
470 if (!this->town->text.empty()) {
471 tr.top = DrawStringMultiLine(tr, this->town->text.GetDecodedString(), TC_BLACK);
472 }
473 }
474
475 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
476 {
477 switch (widget) {
478 case WID_TV_CENTER_VIEW: // scroll to location
479 if (_ctrl_pressed) {
480 ShowExtraViewportWindow(this->town->xy);
481 } else {
482 ScrollMainWindowToTile(this->town->xy);
483 }
484 break;
485
486 case WID_TV_SHOW_AUTHORITY: // town authority
487 ShowTownAuthorityWindow(this->window_number);
488 break;
489
490 case WID_TV_CHANGE_NAME: // rename
491 ShowQueryString(GetString(STR_TOWN_NAME, this->window_number), STR_TOWN_VIEW_RENAME_TOWN_BUTTON, MAX_LENGTH_TOWN_NAME_CHARS, this, CS_ALPHANUMERAL, {QueryStringFlag::EnableDefault, QueryStringFlag::LengthIsInChars});
492 break;
493
494 case WID_TV_CATCHMENT:
495 SetViewportCatchmentTown(Town::Get(this->window_number), !this->IsWidgetLowered(WID_TV_CATCHMENT));
496 break;
497
498 case WID_TV_EXPAND: // expand town - only available on Scenario editor
499 Command<CMD_EXPAND_TOWN>::Post(STR_ERROR_CAN_T_EXPAND_TOWN, static_cast<TownID>(this->window_number), 0, {TownExpandMode::Buildings, TownExpandMode::Roads});
500 break;
501
502 case WID_TV_EXPAND_BUILDINGS: // expand buildings of town - only available on Scenario editor
503 Command<CMD_EXPAND_TOWN>::Post(STR_ERROR_CAN_T_EXPAND_TOWN, static_cast<TownID>(this->window_number), 0, {TownExpandMode::Buildings});
504 break;
505
506 case WID_TV_EXPAND_ROADS: // expand roads of town - only available on Scenario editor
507 Command<CMD_EXPAND_TOWN>::Post(STR_ERROR_CAN_T_EXPAND_TOWN, static_cast<TownID>(this->window_number), 0, {TownExpandMode::Roads});
508 break;
509
510 case WID_TV_DELETE: // delete town - only available on Scenario editor
511 Command<CMD_DELETE_TOWN>::Post(STR_ERROR_TOWN_CAN_T_DELETE, static_cast<TownID>(this->window_number));
512 break;
513
514 case WID_TV_GRAPH: {
515 ShowTownCargoGraph(this->window_number);
516 break;
517 }
518 }
519 }
520
521 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
522 {
523 switch (widget) {
524 case WID_TV_INFO:
525 size.height = GetDesiredInfoHeight(size.width) + padding.height;
526 break;
527 }
528 }
529
534 uint GetDesiredInfoHeight(int width) const
535 {
536 uint aimed_height = static_cast<uint>(1 + CargoSpec::town_production_cargoes[TPE_PASSENGERS].size() + CargoSpec::town_production_cargoes[TPE_MAIL].size()) * GetCharacterHeight(FS_NORMAL);
537
538 bool first = true;
539 for (int i = TAE_BEGIN; i < TAE_END; i++) {
540 if (this->town->goal[i] == 0) continue;
541 if (this->town->goal[i] == TOWN_GROWTH_WINTER && (TileHeight(this->town->xy) < LowestSnowLine() || this->town->cache.population <= 90)) continue;
542 if (this->town->goal[i] == TOWN_GROWTH_DESERT && (GetTropicZone(this->town->xy) != TROPICZONE_DESERT || this->town->cache.population <= 60)) continue;
543
544 if (first) {
545 aimed_height += GetCharacterHeight(FS_NORMAL);
546 first = false;
547 }
548 aimed_height += GetCharacterHeight(FS_NORMAL);
549 }
550 aimed_height += GetCharacterHeight(FS_NORMAL);
551
552 if (_settings_game.economy.station_noise_level) aimed_height += GetCharacterHeight(FS_NORMAL);
553
554 if (!this->town->text.empty()) {
555 aimed_height += GetStringHeight(this->town->text.GetDecodedString(), width - WidgetDimensions::scaled.framerect.Horizontal());
556 }
557
558 return aimed_height;
559 }
560
561 void ResizeWindowAsNeeded()
562 {
563 const NWidgetBase *nwid_info = this->GetWidget<NWidgetBase>(WID_TV_INFO);
564 uint aimed_height = GetDesiredInfoHeight(nwid_info->current_x);
565 if (aimed_height > nwid_info->current_y || (aimed_height < nwid_info->current_y && nwid_info->current_y > nwid_info->smallest_y)) {
566 this->ReInit();
567 }
568 }
569
570 void OnResize() override
571 {
572 if (this->viewport != nullptr) {
573 NWidgetViewport *nvp = this->GetWidget<NWidgetViewport>(WID_TV_VIEWPORT);
574 nvp->UpdateViewportCoordinates(this);
575
576 ScrollWindowToTile(this->town->xy, this, true); // Re-center viewport.
577 }
578 }
579
580 void OnMouseWheel(int wheel, WidgetID widget) override
581 {
582 if (widget != WID_TV_VIEWPORT) return;
583 if (_settings_client.gui.scrollwheel_scrolling != SWS_OFF) {
584 DoZoomInOutWindow(wheel < 0 ? ZOOM_IN : ZOOM_OUT, this);
585 }
586 }
587
593 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
594 {
595 if (!gui_scope) return;
596 /* Called when setting station noise or required cargoes have changed, in order to resize the window */
597 this->SetDirty(); // refresh display for current size. This will allow to avoid glitches when downgrading
598 this->ResizeWindowAsNeeded();
599 }
600
601 void OnQueryTextFinished(std::optional<std::string> str) override
602 {
603 if (!str.has_value()) return;
604
605 Command<CMD_RENAME_TOWN>::Post(STR_ERROR_CAN_T_RENAME_TOWN, static_cast<TownID>(this->window_number), *str);
606 }
607
608 const IntervalTimer<TimerGameCalendar> daily_interval = {{TimerGameCalendar::DAY, TimerGameCalendar::Priority::NONE}, [this](auto) {
609 /* Refresh after possible snowline change */
610 this->SetDirty();
611 }};
612};
613
614static constexpr std::initializer_list<NWidgetPart> _nested_town_game_view_widgets = {
615 NWidget(NWID_HORIZONTAL),
616 NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
617 NWidget(WWT_PUSHIMGBTN, COLOUR_BROWN, WID_TV_CHANGE_NAME), SetAspect(WidgetDimensions::ASPECT_RENAME), SetSpriteTip(SPR_RENAME, STR_TOWN_VIEW_RENAME_TOOLTIP),
618 NWidget(WWT_CAPTION, COLOUR_BROWN, WID_TV_CAPTION),
619 NWidget(WWT_PUSHIMGBTN, COLOUR_BROWN, WID_TV_CENTER_VIEW), SetAspect(WidgetDimensions::ASPECT_LOCATION), SetSpriteTip(SPR_GOTO_LOCATION, STR_TOWN_VIEW_CENTER_TOOLTIP),
620 NWidget(WWT_SHADEBOX, COLOUR_BROWN),
621 NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
622 NWidget(WWT_STICKYBOX, COLOUR_BROWN),
623 EndContainer(),
624 NWidget(WWT_PANEL, COLOUR_BROWN),
625 NWidget(WWT_INSET, COLOUR_BROWN), SetPadding(2, 2, 2, 2),
626 NWidget(NWID_VIEWPORT, INVALID_COLOUR, WID_TV_VIEWPORT), SetMinimalSize(254, 86), SetFill(1, 0), SetResize(1, 1),
627 EndContainer(),
628 EndContainer(),
629 NWidget(WWT_PANEL, COLOUR_BROWN, WID_TV_INFO), SetMinimalSize(260, 32), SetResize(1, 0), SetFill(1, 0), EndContainer(),
630 NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
631 NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_SHOW_AUTHORITY), SetMinimalSize(80, 12), SetFill(1, 1), SetResize(1, 0), SetStringTip(STR_TOWN_VIEW_LOCAL_AUTHORITY_BUTTON, STR_TOWN_VIEW_LOCAL_AUTHORITY_TOOLTIP),
632 NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_TV_CATCHMENT), SetMinimalSize(40, 12), SetFill(1, 1), SetResize(1, 0), SetStringTip(STR_BUTTON_CATCHMENT, STR_TOOLTIP_CATCHMENT),
633 NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_GRAPH), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_TOWN_VIEW_CARGO_GRAPH, STR_TOWN_VIEW_CARGO_GRAPH_TOOLTIP),
634 NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
635 EndContainer(),
636};
637
638static WindowDesc _town_game_view_desc(
639 WDP_AUTO, "view_town", 260, TownViewWindow::WID_TV_HEIGHT_NORMAL,
640 WC_TOWN_VIEW, WC_NONE,
641 {},
642 _nested_town_game_view_widgets
643);
644
645static constexpr std::initializer_list<NWidgetPart> _nested_town_editor_view_widgets = {
646 NWidget(NWID_HORIZONTAL),
647 NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
648 NWidget(WWT_PUSHIMGBTN, COLOUR_BROWN, WID_TV_CHANGE_NAME), SetAspect(WidgetDimensions::ASPECT_RENAME), SetSpriteTip(SPR_RENAME, STR_TOWN_VIEW_RENAME_TOOLTIP),
649 NWidget(WWT_CAPTION, COLOUR_BROWN, WID_TV_CAPTION), SetToolTip(STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
650 NWidget(WWT_PUSHIMGBTN, COLOUR_BROWN, WID_TV_CENTER_VIEW), SetAspect(WidgetDimensions::ASPECT_LOCATION), SetSpriteTip(SPR_GOTO_LOCATION, STR_TOWN_VIEW_CENTER_TOOLTIP),
651 NWidget(WWT_SHADEBOX, COLOUR_BROWN),
652 NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
653 NWidget(WWT_STICKYBOX, COLOUR_BROWN),
654 EndContainer(),
655 NWidget(WWT_PANEL, COLOUR_BROWN),
656 NWidget(WWT_INSET, COLOUR_BROWN), SetPadding(2, 2, 2, 2),
657 NWidget(NWID_VIEWPORT, INVALID_COLOUR, WID_TV_VIEWPORT), SetMinimalSize(254, 86), SetFill(1, 1), SetResize(1, 1),
658 EndContainer(),
659 EndContainer(),
660 NWidget(WWT_PANEL, COLOUR_BROWN, WID_TV_INFO), SetMinimalSize(260, 32), SetResize(1, 0), SetFill(1, 0), EndContainer(),
661 NWidget(NWID_HORIZONTAL),
662 NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_EXPAND), SetFill(1, 1), SetResize(1, 0), SetStringTip(STR_TOWN_VIEW_EXPAND_BUTTON, STR_TOWN_VIEW_EXPAND_TOOLTIP),
663 NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_EXPAND_BUILDINGS), SetFill(1, 1), SetResize(1, 0), SetStringTip(STR_TOWN_VIEW_EXPAND_BUILDINGS_BUTTON, STR_TOWN_VIEW_EXPAND_BUILDINGS_TOOLTIP),
664 NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_EXPAND_ROADS), SetFill(1, 1), SetResize(1, 0), SetStringTip(STR_TOWN_VIEW_EXPAND_ROADS_BUTTON, STR_TOWN_VIEW_EXPAND_ROADS_TOOLTIP),
665 EndContainer(),
666 NWidget(NWID_HORIZONTAL),
667 NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_DELETE), SetFill(1, 1), SetResize(1, 0), SetStringTip(STR_TOWN_VIEW_DELETE_BUTTON, STR_TOWN_VIEW_DELETE_TOOLTIP),
668 NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_TV_CATCHMENT), SetFill(1, 1), SetResize(1, 0), SetStringTip(STR_BUTTON_CATCHMENT, STR_TOOLTIP_CATCHMENT),
669 NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
670 EndContainer(),
671};
672
673static WindowDesc _town_editor_view_desc(
674 WDP_AUTO, "view_town_scen", 260, TownViewWindow::WID_TV_HEIGHT_NORMAL,
675 WC_TOWN_VIEW, WC_NONE,
676 {},
677 _nested_town_editor_view_widgets
678);
679
680void ShowTownViewWindow(TownID town)
681{
682 if (_game_mode == GM_EDITOR) {
683 AllocateWindowDescFront<TownViewWindow>(_town_editor_view_desc, town);
684 } else {
685 AllocateWindowDescFront<TownViewWindow>(_town_game_view_desc, town);
686 }
687}
688
689static constexpr std::initializer_list<NWidgetPart> _nested_town_directory_widgets = {
690 NWidget(NWID_HORIZONTAL),
691 NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
692 NWidget(WWT_CAPTION, COLOUR_BROWN, WID_TD_CAPTION),
693 NWidget(WWT_SHADEBOX, COLOUR_BROWN),
694 NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
695 NWidget(WWT_STICKYBOX, COLOUR_BROWN),
696 EndContainer(),
697 NWidget(NWID_HORIZONTAL),
698 NWidget(NWID_VERTICAL),
699 NWidget(NWID_HORIZONTAL),
700 NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_TD_SORT_ORDER), SetStringTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
701 NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_TD_SORT_CRITERIA), SetToolTip(STR_TOOLTIP_SORT_CRITERIA),
702 NWidget(WWT_EDITBOX, COLOUR_BROWN, WID_TD_FILTER), SetFill(1, 0), SetResize(1, 0), SetStringTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
703 EndContainer(),
704 NWidget(WWT_PANEL, COLOUR_BROWN, WID_TD_LIST), SetToolTip(STR_TOWN_DIRECTORY_LIST_TOOLTIP),
705 SetFill(1, 0), SetResize(1, 1), SetScrollbar(WID_TD_SCROLLBAR), EndContainer(),
706 NWidget(WWT_PANEL, COLOUR_BROWN),
707 NWidget(WWT_TEXT, INVALID_COLOUR, WID_TD_WORLD_POPULATION), SetPadding(2, 0, 2, 2), SetFill(1, 0), SetResize(1, 0),
708 EndContainer(),
709 EndContainer(),
710 NWidget(NWID_VERTICAL),
711 NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_TD_SCROLLBAR),
712 NWidget(WWT_RESIZEBOX, COLOUR_BROWN),
713 EndContainer(),
714 EndContainer(),
715};
716
718 struct TownDirectoryWindow : public Window {
719private:
720 /* Runtime saved values */
721 static Listing last_sorting;
722
723 /* Constants for sorting towns */
724 static inline const StringID sorter_names[] = {
725 STR_SORT_BY_NAME,
726 STR_SORT_BY_POPULATION,
727 STR_SORT_BY_RATING,
728 };
729 static const std::initializer_list<GUITownList::SortFunction * const> sorter_funcs;
730
731 StringFilter string_filter{};
732 QueryString townname_editbox;
733
734 GUITownList towns{TownDirectoryWindow::last_sorting.order};
735
736 Scrollbar *vscroll = nullptr;
737
738 void BuildSortTownList()
739 {
740 if (this->towns.NeedRebuild()) {
741 this->towns.clear();
742 this->towns.reserve(Town::GetNumItems());
743
744 for (const Town *t : Town::Iterate()) {
745 if (this->string_filter.IsEmpty()) {
746 this->towns.push_back(t);
747 continue;
748 }
749 this->string_filter.ResetState();
750 this->string_filter.AddLine(t->GetCachedName());
751 if (this->string_filter.GetState()) this->towns.push_back(t);
752 }
753
754 this->towns.RebuildDone();
755 this->vscroll->SetCount(this->towns.size()); // Update scrollbar as well.
756 }
757 /* Always sort the towns. */
758 this->towns.Sort();
759 this->SetWidgetDirty(WID_TD_LIST); // Force repaint of the displayed towns.
760 }
761
763 static bool TownNameSorter(const Town * const &a, const Town * const &b, const bool &)
764 {
765 return StrNaturalCompare(a->GetCachedName(), b->GetCachedName()) < 0; // Sort by name (natural sorting).
766 }
767
769 static bool TownPopulationSorter(const Town * const &a, const Town * const &b, const bool &order)
770 {
771 uint32_t a_population = a->cache.population;
772 uint32_t b_population = b->cache.population;
773 if (a_population == b_population) return TownDirectoryWindow::TownNameSorter(a, b, order);
774 return a_population < b_population;
775 }
776
778 static bool TownRatingSorter(const Town * const &a, const Town * const &b, const bool &order)
779 {
780 bool before = !order; // Value to get 'a' before 'b'.
781
782 /* Towns without rating are always after towns with rating. */
783 if (a->have_ratings.Test(_local_company)) {
784 if (b->have_ratings.Test(_local_company)) {
785 int16_t a_rating = a->ratings[_local_company];
786 int16_t b_rating = b->ratings[_local_company];
787 if (a_rating == b_rating) return TownDirectoryWindow::TownNameSorter(a, b, order);
788 return a_rating < b_rating;
789 }
790 return before;
791 }
792 if (b->have_ratings.Test(_local_company)) return !before;
793
794 /* Sort unrated towns always on ascending town name. */
795 if (before) return TownDirectoryWindow::TownNameSorter(a, b, order);
796 return TownDirectoryWindow::TownNameSorter(b, a, order);
797 }
798
799public:
800 TownDirectoryWindow(WindowDesc &desc) : Window(desc), townname_editbox(MAX_LENGTH_TOWN_NAME_CHARS * MAX_CHAR_LENGTH, MAX_LENGTH_TOWN_NAME_CHARS)
801 {
802 this->CreateNestedTree();
803
804 this->vscroll = this->GetScrollbar(WID_TD_SCROLLBAR);
805
806 this->towns.SetListing(this->last_sorting);
807 this->towns.SetSortFuncs(TownDirectoryWindow::sorter_funcs);
808 this->towns.ForceRebuild();
809 this->BuildSortTownList();
810
811 this->FinishInitNested(0);
812
813 this->querystrings[WID_TD_FILTER] = &this->townname_editbox;
814 this->townname_editbox.cancel_button = QueryString::ACTION_CLEAR;
815 }
816
817 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
818 {
819 switch (widget) {
820 case WID_TD_CAPTION:
821 return GetString(STR_TOWN_DIRECTORY_CAPTION, this->vscroll->GetCount(), Town::GetNumItems());
822
823 case WID_TD_WORLD_POPULATION:
824 return GetString(STR_TOWN_POPULATION, GetWorldPopulation());
825
826 case WID_TD_SORT_CRITERIA:
827 return GetString(TownDirectoryWindow::sorter_names[this->towns.SortType()]);
828
829 default:
830 return this->Window::GetWidgetString(widget, stringid);
831 }
832 }
833
839 static std::string GetTownString(const Town *t, uint64_t population)
840 {
841 return GetString(t->larger_town ? STR_TOWN_DIRECTORY_CITY : STR_TOWN_DIRECTORY_TOWN, t->index, population);
842 }
843
844 void DrawWidget(const Rect &r, WidgetID widget) const override
845 {
846 switch (widget) {
847 case WID_TD_SORT_ORDER:
848 this->DrawSortButtonState(widget, this->towns.IsDescSortOrder() ? SBS_DOWN : SBS_UP);
849 break;
850
851 case WID_TD_LIST: {
852 Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
853 if (this->towns.empty()) { // No towns available.
854 DrawString(tr, STR_TOWN_DIRECTORY_NONE);
855 break;
856 }
857
858 /* At least one town available. */
859 bool rtl = _current_text_dir == TD_RTL;
860 Dimension icon_size = GetSpriteSize(SPR_TOWN_RATING_GOOD);
861 int icon_x = tr.WithWidth(icon_size.width, rtl).left;
862 tr = tr.Indent(icon_size.width + WidgetDimensions::scaled.hsep_normal, rtl);
863
864 auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->towns);
865 for (auto it = first; it != last; ++it) {
866 const Town *t = *it;
867 assert(t->xy != INVALID_TILE);
868
869 /* Draw rating icon. */
870 if (_game_mode == GM_EDITOR || !t->have_ratings.Test(_local_company)) {
871 DrawSprite(SPR_TOWN_RATING_NA, PAL_NONE, icon_x, tr.top + (this->resize.step_height - icon_size.height) / 2);
872 } else {
873 SpriteID icon = SPR_TOWN_RATING_APPALLING;
874 if (t->ratings[_local_company] > RATING_VERYPOOR) icon = SPR_TOWN_RATING_MEDIOCRE;
875 if (t->ratings[_local_company] > RATING_GOOD) icon = SPR_TOWN_RATING_GOOD;
876 DrawSprite(icon, PAL_NONE, icon_x, tr.top + (this->resize.step_height - icon_size.height) / 2);
877 }
878
879 DrawString(tr.left, tr.right, tr.top + (this->resize.step_height - GetCharacterHeight(FS_NORMAL)) / 2, GetTownString(t, t->cache.population));
880
881 tr.top += this->resize.step_height;
882 }
883 break;
884 }
885 }
886 }
887
888 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
889 {
890 switch (widget) {
891 case WID_TD_SORT_ORDER: {
892 Dimension d = GetStringBoundingBox(this->GetWidget<NWidgetCore>(widget)->GetString());
893 d.width += padding.width + Window::SortButtonWidth() * 2; // Doubled since the string is centred and it also looks better.
894 d.height += padding.height;
895 size = maxdim(size, d);
896 break;
897 }
898 case WID_TD_SORT_CRITERIA: {
899 Dimension d = GetStringListBoundingBox(TownDirectoryWindow::sorter_names);
900 d.width += padding.width;
901 d.height += padding.height;
902 size = maxdim(size, d);
903 break;
904 }
905 case WID_TD_LIST: {
906 Dimension d = GetStringBoundingBox(STR_TOWN_DIRECTORY_NONE);
907 uint64_t max_value = GetParamMaxDigits(8);
908 for (uint i = 0; i < this->towns.size(); i++) {
909 const Town *t = this->towns[i];
910
911 assert(t != nullptr);
912
913 d = maxdim(d, GetStringBoundingBox(GetTownString(t, max_value)));
914 }
915 Dimension icon_size = GetSpriteSize(SPR_TOWN_RATING_GOOD);
916 d.width += icon_size.width + 2;
917 d.height = std::max(d.height, icon_size.height);
918 fill.height = resize.height = d.height;
919 d.height *= 5;
920 d.width += padding.width;
921 d.height += padding.height;
922 size = maxdim(size, d);
923 break;
924 }
925 case WID_TD_WORLD_POPULATION: {
926 Dimension d = GetStringBoundingBox(GetString(STR_TOWN_POPULATION, GetParamMaxDigits(10)));
927 d.width += padding.width;
928 d.height += padding.height;
929 size = maxdim(size, d);
930 break;
931 }
932 }
933 }
934
935 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
936 {
937 switch (widget) {
938 case WID_TD_SORT_ORDER: // Click on sort order button
939 if (this->towns.SortType() != 2) { // A different sort than by rating.
940 this->towns.ToggleSortOrder();
941 this->last_sorting = this->towns.GetListing(); // Store new sorting order.
942 } else {
943 /* Some parts are always sorted ascending on name. */
944 this->last_sorting.order = !this->last_sorting.order;
945 this->towns.SetListing(this->last_sorting);
946 this->towns.ForceResort();
947 this->towns.Sort();
948 }
949 this->SetDirty();
950 break;
951
952 case WID_TD_SORT_CRITERIA: // Click on sort criteria dropdown
953 ShowDropDownMenu(this, TownDirectoryWindow::sorter_names, this->towns.SortType(), WID_TD_SORT_CRITERIA, 0, 0);
954 break;
955
956 case WID_TD_LIST: { // Click on Town Matrix
957 auto it = this->vscroll->GetScrolledItemFromWidget(this->towns, pt.y, this, WID_TD_LIST, WidgetDimensions::scaled.framerect.top);
958 if (it == this->towns.end()) return; // click out of town bounds
959
960 const Town *t = *it;
961 assert(t != nullptr);
962 if (_ctrl_pressed) {
963 ShowExtraViewportWindow(t->xy);
964 } else {
965 ScrollMainWindowToTile(t->xy);
966 }
967 break;
968 }
969 }
970 }
971
972 void OnDropdownSelect(WidgetID widget, int index, int) override
973 {
974 if (widget != WID_TD_SORT_CRITERIA) return;
975
976 if (this->towns.SortType() != index) {
977 this->towns.SetSortType(index);
978 this->last_sorting = this->towns.GetListing(); // Store new sorting order.
979 this->BuildSortTownList();
980 }
981 }
982
983 void OnPaint() override
984 {
985 if (this->towns.NeedRebuild()) this->BuildSortTownList();
986 this->DrawWidgets();
987 }
988
990 const IntervalTimer<TimerWindow> rebuild_interval = {std::chrono::seconds(3), [this](auto) {
991 this->BuildSortTownList();
992 this->SetDirty();
993 }};
994
995 void OnResize() override
996 {
997 this->vscroll->SetCapacityFromWidget(this, WID_TD_LIST, WidgetDimensions::scaled.framerect.Vertical());
998 }
999
1000 void OnEditboxChanged(WidgetID wid) override
1001 {
1002 if (wid == WID_TD_FILTER) {
1003 this->string_filter.SetFilterTerm(this->townname_editbox.text.GetText());
1004 this->InvalidateData(TDIWD_FORCE_REBUILD);
1005 }
1006 }
1007
1013 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
1014 {
1015 switch (data) {
1016 case TDIWD_FORCE_REBUILD:
1017 /* This needs to be done in command-scope to enforce rebuilding before resorting invalid data */
1018 this->towns.ForceRebuild();
1019 break;
1020
1021 case TDIWD_POPULATION_CHANGE:
1022 if (this->towns.SortType() == 1) this->towns.ForceResort();
1023 break;
1024
1025 default:
1026 this->towns.ForceResort();
1027 }
1028 }
1029
1030 static inline HotkeyList hotkeys {"towndirectory", {
1031 Hotkey('F', "focus_filter_box", WID_TD_FILTER),
1032 }};
1033};
1034
1035 Listing TownDirectoryWindow::last_sorting = {false, 0};
1036
1038 const std::initializer_list<GUITownList::SortFunction * const> TownDirectoryWindow::sorter_funcs = {
1039 &TownNameSorter,
1040 &TownPopulationSorter,
1041 &TownRatingSorter,
1042};
1043
1044static WindowDesc _town_directory_desc(
1045 WDP_AUTO, "list_towns", 208, 202,
1046 WC_TOWN_DIRECTORY, WC_NONE,
1047 {},
1048 _nested_town_directory_widgets,
1049 &TownDirectoryWindow::hotkeys
1050);
1051
1052void ShowTownDirectory()
1053{
1054 if (BringWindowToFrontById(WC_TOWN_DIRECTORY, 0)) return;
1055 new TownDirectoryWindow(_town_directory_desc);
1056}
1057
1058void CcFoundTown(Commands, const CommandCost &result, TileIndex tile)
1059{
1060 if (result.Failed()) return;
1061
1062 if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, tile);
1063 if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace();
1064}
1065
1066void CcFoundRandomTown(Commands, const CommandCost &result, Money, TownID town_id)
1067{
1068 if (result.Succeeded()) ScrollMainWindowToTile(Town::Get(town_id)->xy);
1069}
1070
1071static constexpr std::initializer_list<NWidgetPart> _nested_found_town_widgets = {
1072 NWidget(NWID_HORIZONTAL),
1073 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
1074 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_FOUND_TOWN_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1075 NWidget(WWT_SHADEBOX, COLOUR_DARK_GREEN),
1076 NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
1077 EndContainer(),
1078 /* Construct new town(s) buttons. */
1079 NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
1080 NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0), SetPadding(WidgetDimensions::unscaled.picker),
1081 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_NEW_TOWN), SetStringTip(STR_FOUND_TOWN_NEW_TOWN_BUTTON, STR_FOUND_TOWN_NEW_TOWN_TOOLTIP), SetFill(1, 0),
1082 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_TF_TOWN_ACTION_SEL),
1083 NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0),
1084 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TF_RANDOM_TOWN), SetStringTip(STR_FOUND_TOWN_RANDOM_TOWN_BUTTON, STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP), SetFill(1, 0),
1085 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TF_MANY_RANDOM_TOWNS), SetStringTip(STR_FOUND_TOWN_MANY_RANDOM_TOWNS, STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP), SetFill(1, 0),
1086 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TF_LOAD_FROM_FILE), SetStringTip(STR_FOUND_TOWN_LOAD_FROM_FILE, STR_FOUND_TOWN_LOAD_FROM_FILE_TOOLTIP), SetFill(1, 0),
1087 EndContainer(),
1088 EndContainer(),
1089
1090 /* Town name selection. */
1091 NWidget(WWT_LABEL, INVALID_COLOUR), SetStringTip(STR_FOUND_TOWN_NAME_TITLE),
1092 NWidget(WWT_EDITBOX, COLOUR_GREY, WID_TF_TOWN_NAME_EDITBOX), SetStringTip(STR_FOUND_TOWN_NAME_EDITOR_TITLE, STR_FOUND_TOWN_NAME_EDITOR_TOOLTIP), SetFill(1, 0),
1093 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TF_TOWN_NAME_RANDOM), SetStringTip(STR_FOUND_TOWN_NAME_RANDOM_BUTTON, STR_FOUND_TOWN_NAME_RANDOM_TOOLTIP), SetFill(1, 0),
1094
1095 /* Town size selection. */
1096 NWidget(WWT_LABEL, INVALID_COLOUR), SetStringTip(STR_FOUND_TOWN_INITIAL_SIZE_TITLE),
1097 NWidget(NWID_VERTICAL),
1098 NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
1099 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_SIZE_SMALL), SetStringTip(STR_FOUND_TOWN_INITIAL_SIZE_SMALL_BUTTON, STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP), SetFill(1, 0),
1100 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_SIZE_MEDIUM), SetStringTip(STR_FOUND_TOWN_INITIAL_SIZE_MEDIUM_BUTTON, STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP), SetFill(1, 0),
1101 EndContainer(),
1102 NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
1103 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_TF_SIZE_SEL),
1104 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_SIZE_LARGE), SetStringTip(STR_FOUND_TOWN_INITIAL_SIZE_LARGE_BUTTON, STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP), SetFill(1, 0),
1105 EndContainer(),
1106 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_SIZE_RANDOM), SetStringTip(STR_FOUND_TOWN_SIZE_RANDOM, STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP), SetFill(1, 0),
1107 EndContainer(),
1108 EndContainer(),
1109 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_CITY), SetStringTip(STR_FOUND_TOWN_CITY, STR_FOUND_TOWN_CITY_TOOLTIP), SetFill(1, 0),
1110
1111 /* Town roads selection. */
1112 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_TF_ROAD_LAYOUT_SEL),
1113 NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0),
1114 NWidget(WWT_LABEL, INVALID_COLOUR), SetStringTip(STR_FOUND_TOWN_ROAD_LAYOUT),
1115 NWidget(NWID_VERTICAL),
1116 NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
1117 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_LAYOUT_ORIGINAL), SetStringTip(STR_FOUND_TOWN_SELECT_LAYOUT_ORIGINAL, STR_FOUND_TOWN_SELECT_LAYOUT_TOOLTIP), SetFill(1, 0),
1118 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_LAYOUT_BETTER), SetStringTip(STR_FOUND_TOWN_SELECT_LAYOUT_BETTER_ROADS, STR_FOUND_TOWN_SELECT_LAYOUT_TOOLTIP), SetFill(1, 0),
1119 EndContainer(),
1120 NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
1121 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_LAYOUT_GRID2), SetStringTip(STR_FOUND_TOWN_SELECT_LAYOUT_2X2_GRID, STR_FOUND_TOWN_SELECT_LAYOUT_TOOLTIP), SetFill(1, 0),
1122 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_LAYOUT_GRID3), SetStringTip(STR_FOUND_TOWN_SELECT_LAYOUT_3X3_GRID, STR_FOUND_TOWN_SELECT_LAYOUT_TOOLTIP), SetFill(1, 0),
1123 EndContainer(),
1124 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_LAYOUT_RANDOM), SetStringTip(STR_FOUND_TOWN_SELECT_LAYOUT_RANDOM, STR_FOUND_TOWN_SELECT_LAYOUT_TOOLTIP), SetFill(1, 0),
1125 EndContainer(),
1126 EndContainer(),
1127 EndContainer(),
1128
1129 /* Town expansion selection. */
1130 NWidget(NWID_SELECTION, INVALID_COLOUR, WID_TF_TOWN_EXPAND_SEL),
1131 NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0),
1132 NWidget(WWT_LABEL, INVALID_COLOUR), SetStringTip(STR_FOUND_TOWN_EXPAND_MODE),
1133 NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_TF_EXPAND_ALL_TOWNS), SetStringTip(STR_FOUND_TOWN_EXPAND_ALL_TOWNS, STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP), SetFill(1, 0),
1134 NWidget(NWID_HORIZONTAL, NWidContainerFlag::EqualSize),
1135 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_EXPAND_BUILDINGS), SetStringTip(STR_FOUND_TOWN_EXPAND_BUILDINGS, STR_FOUND_TOWN_EXPAND_BUILDINGS_TOOLTIP), SetFill(1, 0),
1136 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_TF_EXPAND_ROADS), SetStringTip(STR_FOUND_TOWN_EXPAND_ROADS, STR_FOUND_TOWN_EXPAND_ROADS_TOOLTIP), SetFill(1, 0),
1137 EndContainer(),
1138 EndContainer(),
1139 EndContainer(),
1140 EndContainer(),
1141 EndContainer(),
1142};
1143
1145 struct FoundTownWindow : Window {
1146private:
1147 TownSize town_size = TSZ_MEDIUM;
1148 TownLayout town_layout{};
1149 bool city = false;
1150 QueryString townname_editbox;
1151 bool townnamevalid = false;
1152 uint32_t townnameparts = 0;
1153 TownNameParams params;
1154 static inline TownExpandModes expand_modes{TownExpandMode::Buildings, TownExpandMode::Roads};
1155
1156public:
1157 FoundTownWindow(WindowDesc &desc, WindowNumber window_number) :
1158 Window(desc),
1159 town_layout(_settings_game.economy.town_layout),
1160 townname_editbox(MAX_LENGTH_TOWN_NAME_CHARS * MAX_CHAR_LENGTH, MAX_LENGTH_TOWN_NAME_CHARS),
1161 params(_settings_game.game_creation.town_name)
1162 {
1163 this->InitNested(window_number);
1164 this->querystrings[WID_TF_TOWN_NAME_EDITBOX] = &this->townname_editbox;
1165 this->RandomTownName();
1166 this->UpdateButtons(true);
1167 }
1168
1169 void OnInit() override
1170 {
1171 if (_game_mode == GM_EDITOR) return;
1172
1173 this->GetWidget<NWidgetStacked>(WID_TF_TOWN_ACTION_SEL)->SetDisplayedPlane(SZSP_HORIZONTAL);
1174 this->GetWidget<NWidgetStacked>(WID_TF_TOWN_EXPAND_SEL)->SetDisplayedPlane(SZSP_HORIZONTAL);
1175 this->GetWidget<NWidgetStacked>(WID_TF_SIZE_SEL)->SetDisplayedPlane(SZSP_VERTICAL);
1176 if (_settings_game.economy.found_town != TF_CUSTOM_LAYOUT) {
1177 this->GetWidget<NWidgetStacked>(WID_TF_ROAD_LAYOUT_SEL)->SetDisplayedPlane(SZSP_HORIZONTAL);
1178 } else {
1179 this->GetWidget<NWidgetStacked>(WID_TF_ROAD_LAYOUT_SEL)->SetDisplayedPlane(0);
1180 }
1181 }
1182
1183 void RandomTownName()
1184 {
1185 this->townnamevalid = GenerateTownName(_interactive_random, &this->townnameparts);
1186
1187 if (!this->townnamevalid) {
1188 this->townname_editbox.text.DeleteAll();
1189 } else {
1190 this->townname_editbox.text.Assign(GetTownName(&this->params, this->townnameparts));
1191 }
1192 UpdateOSKOriginalText(this, WID_TF_TOWN_NAME_EDITBOX);
1193
1194 this->SetWidgetDirty(WID_TF_TOWN_NAME_EDITBOX);
1195 }
1196
1197 void UpdateButtons(bool check_availability)
1198 {
1199 if (check_availability && _game_mode != GM_EDITOR) {
1200 if (_settings_game.economy.found_town != TF_CUSTOM_LAYOUT) this->town_layout = _settings_game.economy.town_layout;
1201 this->ReInit();
1202 }
1203
1204 for (WidgetID i = WID_TF_SIZE_SMALL; i <= WID_TF_SIZE_RANDOM; i++) {
1205 this->SetWidgetLoweredState(i, i == WID_TF_SIZE_SMALL + this->town_size);
1206 }
1207
1208 this->SetWidgetLoweredState(WID_TF_CITY, this->city);
1209
1210 for (WidgetID i = WID_TF_LAYOUT_ORIGINAL; i <= WID_TF_LAYOUT_RANDOM; i++) {
1211 this->SetWidgetLoweredState(i, i == WID_TF_LAYOUT_ORIGINAL + this->town_layout);
1212 }
1213
1214 this->SetWidgetLoweredState(WID_TF_EXPAND_BUILDINGS, FoundTownWindow::expand_modes.Test(TownExpandMode::Buildings));
1215 this->SetWidgetLoweredState(WID_TF_EXPAND_ROADS, FoundTownWindow::expand_modes.Test(TownExpandMode::Roads));
1216
1217 this->SetDirty();
1218 }
1219
1220 template <typename Tcallback>
1221 void ExecuteFoundTownCommand(TileIndex tile, bool random, StringID errstr, Tcallback cc)
1222 {
1223 std::string name;
1224
1225 if (!this->townnamevalid) {
1226 name = this->townname_editbox.text.GetText();
1227 } else {
1228 /* If user changed the name, send it */
1229 std::string original_name = GetTownName(&this->params, this->townnameparts);
1230 if (original_name != this->townname_editbox.text.GetText()) name = this->townname_editbox.text.GetText();
1231 }
1232
1233 bool success = Command<CMD_FOUND_TOWN>::Post(errstr, cc,
1234 tile, this->town_size, this->city, this->town_layout, random, townnameparts, name);
1235
1236 /* Rerandomise name, if success and no cost-estimation. */
1237 if (success && !_shift_pressed) this->RandomTownName();
1238 }
1239
1240 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
1241 {
1242 switch (widget) {
1243 case WID_TF_NEW_TOWN:
1244 HandlePlacePushButton(this, WID_TF_NEW_TOWN, SPR_CURSOR_TOWN, HT_RECT);
1245 break;
1246
1247 case WID_TF_RANDOM_TOWN:
1248 this->ExecuteFoundTownCommand(TileIndex{}, true, STR_ERROR_CAN_T_GENERATE_TOWN, CcFoundRandomTown);
1249 break;
1250
1251 case WID_TF_TOWN_NAME_RANDOM:
1252 this->RandomTownName();
1253 this->SetFocusedWidget(WID_TF_TOWN_NAME_EDITBOX);
1254 break;
1255
1256 case WID_TF_MANY_RANDOM_TOWNS: {
1257 std::string default_town_number = fmt::format("{}", GetDefaultTownsForMapSize());
1258 ShowQueryString(default_town_number, STR_MAPGEN_NUMBER_OF_TOWNS, 5, this, CS_NUMERAL, {QueryStringFlag::AcceptUnchanged});
1259 break;
1260 }
1261 case WID_TF_LOAD_FROM_FILE:
1262 ShowSaveLoadDialog(FT_TOWN_DATA, SLO_LOAD);
1263 break;
1264
1265 case WID_TF_EXPAND_ALL_TOWNS:
1266 for (Town *t : Town::Iterate()) {
1267 Command<CMD_EXPAND_TOWN>::Do(DoCommandFlag::Execute, t->index, 0, FoundTownWindow::expand_modes);
1268 }
1269 break;
1270
1271 case WID_TF_SIZE_SMALL: case WID_TF_SIZE_MEDIUM: case WID_TF_SIZE_LARGE: case WID_TF_SIZE_RANDOM:
1272 this->town_size = (TownSize)(widget - WID_TF_SIZE_SMALL);
1273 this->UpdateButtons(false);
1274 break;
1275
1276 case WID_TF_CITY:
1277 this->city ^= true;
1278 this->SetWidgetLoweredState(WID_TF_CITY, this->city);
1279 this->SetDirty();
1280 break;
1281
1282 case WID_TF_EXPAND_BUILDINGS:
1283 FoundTownWindow::expand_modes.Flip(TownExpandMode::Buildings);
1284 this->UpdateButtons(false);
1285 break;
1286
1287 case WID_TF_EXPAND_ROADS:
1288 FoundTownWindow::expand_modes.Flip(TownExpandMode::Roads);
1289 this->UpdateButtons(false);
1290 break;
1291
1292 case WID_TF_LAYOUT_ORIGINAL: case WID_TF_LAYOUT_BETTER: case WID_TF_LAYOUT_GRID2:
1293 case WID_TF_LAYOUT_GRID3: case WID_TF_LAYOUT_RANDOM:
1294 this->town_layout = (TownLayout)(widget - WID_TF_LAYOUT_ORIGINAL);
1295
1296 /* If we are in the editor, sync the settings of the current game to the chosen layout,
1297 * so that importing towns from file uses the selected layout. */
1298 if (_game_mode == GM_EDITOR) _settings_game.economy.town_layout = this->town_layout;
1299
1300 this->UpdateButtons(false);
1301 break;
1302 }
1303 }
1304
1305 void OnQueryTextFinished(std::optional<std::string> str) override
1306 {
1307 /* Was 'cancel' pressed? */
1308 if (!str.has_value()) return;
1309
1310 auto value = ParseInteger(*str, 10, true);
1311 if (!value.has_value()) return;
1312
1313 Backup<bool> old_generating_world(_generating_world, true);
1314 UpdateNearestTownForRoadTiles(true);
1315 if (!GenerateTowns(this->town_layout, value)) {
1316 ShowErrorMessage(GetEncodedString(STR_ERROR_CAN_T_GENERATE_TOWN), GetEncodedString(STR_ERROR_NO_SPACE_FOR_TOWN), WL_INFO);
1317 }
1318 UpdateNearestTownForRoadTiles(false);
1319 old_generating_world.Restore();
1320 }
1321
1322 void OnPlaceObject([[maybe_unused]] Point pt, TileIndex tile) override
1323 {
1324 this->ExecuteFoundTownCommand(tile, false, STR_ERROR_CAN_T_FOUND_TOWN_HERE, CcFoundTown);
1325 }
1326
1327 void OnPlaceObjectAbort() override
1328 {
1329 this->RaiseButtons();
1330 this->UpdateButtons(false);
1331 }
1332
1338 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
1339 {
1340 if (!gui_scope) return;
1341 this->UpdateButtons(true);
1342 }
1343};
1344
1345static WindowDesc _found_town_desc(
1346 WDP_AUTO, "build_town", 160, 162,
1347 WC_FOUND_TOWN, WC_NONE,
1348 WindowDefaultFlag::Construction,
1349 _nested_found_town_widgets
1350);
1351
1352void ShowFoundTownWindow()
1353{
1354 if (_game_mode != GM_EDITOR && !Company::IsValidID(_local_company)) return;
1355 AllocateWindowDescFront<FoundTownWindow>(_found_town_desc, 0);
1356}
1357
1358void InitializeTownGui()
1359{
1360 _town_local_authority_kdtree.Clear();
1361}
1362
1370 void DrawHouseInGUI(int x, int y, HouseID house_id, int view)
1371{
1372 auto draw = [](int x, int y, HouseID house_id, int view) {
1373 if (house_id >= NEW_HOUSE_OFFSET) {
1374 /* Houses don't necessarily need new graphics. If they don't have a
1375 * spritegroup associated with them, then the sprite for the substitute
1376 * house id is drawn instead. */
1377 const HouseSpec *spec = HouseSpec::Get(house_id);
1378 if (spec->grf_prop.HasSpriteGroups()) {
1379 DrawNewHouseTileInGUI(x, y, spec, house_id, view);
1380 return;
1381 } else {
1382 house_id = HouseSpec::Get(house_id)->grf_prop.subst_id;
1383 }
1384 }
1385
1386 /* Retrieve data from the draw town tile struct */
1387 const DrawBuildingsTileStruct &dcts = GetTownDrawTileData()[house_id << 4 | view << 2 | TOWN_HOUSE_COMPLETED];
1388 DrawSprite(dcts.ground.sprite, dcts.ground.pal, x, y);
1389
1390 /* Add a house on top of the ground? */
1391 if (dcts.building.sprite != 0) {
1392 Point pt = RemapCoords(dcts.origin.x, dcts.origin.y, dcts.origin.z);
1393 DrawSprite(dcts.building.sprite, dcts.building.pal, x + UnScaleGUI(pt.x), y + UnScaleGUI(pt.y));
1394 }
1395 };
1396
1397 /* Houses can have 1x1, 1x2, 2x1 and 2x2 layouts which are individual HouseIDs. For the GUI we need
1398 * draw all of the tiles with appropriate positions. */
1399 int x_delta = ScaleSpriteTrad(TILE_PIXELS);
1400 int y_delta = ScaleSpriteTrad(TILE_PIXELS / 2);
1401
1402 const HouseSpec *hs = HouseSpec::Get(house_id);
1403 if (hs->building_flags.Test(BuildingFlag::Size2x2)) {
1404 draw(x, y - y_delta - y_delta, house_id, view); // North corner.
1405 draw(x + x_delta, y - y_delta, house_id + 1, view); // West corner.
1406 draw(x - x_delta, y - y_delta, house_id + 2, view); // East corner.
1407 draw(x, y, house_id + 3, view); // South corner.
1408 } else if (hs->building_flags.Test(BuildingFlag::Size2x1)) {
1409 draw(x + x_delta / 2, y - y_delta, house_id, view); // North east tile.
1410 draw(x - x_delta / 2, y, house_id + 1, view); // South west tile.
1411 } else if (hs->building_flags.Test(BuildingFlag::Size1x2)) {
1412 draw(x - x_delta / 2, y - y_delta, house_id, view); // North west tile.
1413 draw(x + x_delta / 2, y, house_id + 1, view); // South east tile.
1414 } else {
1415 draw(x, y, house_id, view);
1416 }
1417}
1418
1424 static StringID GetHouseName(const HouseSpec *hs)
1425{
1426 std::array<int32_t, 1> regs100;
1427 uint16_t callback_res = GetHouseCallback(CBID_HOUSE_CUSTOM_NAME, 1, 0, hs->Index(), nullptr, INVALID_TILE, regs100, true);
1428 if (callback_res != CALLBACK_FAILED && callback_res != 0x400) {
1429 StringID new_name = STR_NULL;
1430 if (callback_res == 0x40F) {
1431 new_name = GetGRFStringID(hs->grf_prop.grffile->grfid, static_cast<GRFStringID>(regs100[0]));
1432 } else if (callback_res > 0x400) {
1433 ErrorUnknownCallbackResult(hs->grf_prop.grffile->grfid, CBID_HOUSE_CUSTOM_NAME, callback_res);
1434 } else {
1435 new_name = GetGRFStringID(hs->grf_prop.grffile->grfid, GRFSTR_MISC_GRF_TEXT + callback_res);
1436 }
1437 if (new_name != STR_NULL && new_name != STR_UNDEFINED) {
1438 return new_name;
1439 }
1440 }
1441
1442 return hs->building_name;
1443}
1444
1445 class HousePickerCallbacks : public PickerCallbacks {
1446public:
1447 HousePickerCallbacks() : PickerCallbacks("fav_houses") {}
1448
1452 void SetClimateMask()
1453 {
1454 this->climate_mask = GetClimateMaskForLandscape();
1455
1456 /* In some cases, not all 'classes' (house zones) have distinct houses, so we need to disable those.
1457 * As we need to check all types, and this cannot change with the picker window open, pre-calculate it.
1458 * This loop calls GetTypeName() instead of directly checking properties so that there is no discrepancy. */
1459 this->class_mask = 0;
1460
1461 int num_classes = this->GetClassCount();
1462 for (int cls_id = 0; cls_id < num_classes; ++cls_id) {
1463 int num_types = this->GetTypeCount(cls_id);
1464 for (int id = 0; id < num_types; ++id) {
1465 if (this->GetTypeName(cls_id, id) != INVALID_STRING_ID) {
1466 SetBit(this->class_mask, cls_id);
1467 break;
1468 }
1469 }
1470 }
1471 }
1472
1473 HouseZones climate_mask{};
1474 uint8_t class_mask = 0;
1475
1476 static inline int sel_class;
1477 static inline int sel_type;
1478 static inline int sel_view;
1479
1480 /* Houses do not have classes like NewGRFClass. We'll make up fake classes based on town zone
1481 * availability instead. */
1482 static inline const std::array<StringID, NUM_HOUSE_ZONES> zone_names = {
1483 STR_HOUSE_PICKER_CLASS_ZONE1,
1484 STR_HOUSE_PICKER_CLASS_ZONE2,
1485 STR_HOUSE_PICKER_CLASS_ZONE3,
1486 STR_HOUSE_PICKER_CLASS_ZONE4,
1487 STR_HOUSE_PICKER_CLASS_ZONE5,
1488 };
1489
1490 GrfSpecFeature GetFeature() const override { return GSF_HOUSES; }
1491
1492 StringID GetClassTooltip() const override { return STR_PICKER_HOUSE_CLASS_TOOLTIP; }
1493 StringID GetTypeTooltip() const override { return STR_PICKER_HOUSE_TYPE_TOOLTIP; }
1494 bool IsActive() const override { return true; }
1495
1496 bool HasClassChoice() const override { return true; }
1497 int GetClassCount() const override { return static_cast<int>(zone_names.size()); }
1498
1499 void Close([[maybe_unused]] int data) override { ResetObjectToPlace(); }
1500
1501 int GetSelectedClass() const override { return HousePickerCallbacks::sel_class; }
1502 void SetSelectedClass(int cls_id) const override { HousePickerCallbacks::sel_class = cls_id; }
1503
1504 StringID GetClassName(int id) const override
1505 {
1506 if (id >= GetClassCount()) return INVALID_STRING_ID;
1507 if (!HasBit(this->class_mask, id)) return INVALID_STRING_ID;
1508 return zone_names[id];
1509 }
1510
1511 int GetTypeCount(int cls_id) const override
1512 {
1513 if (cls_id < GetClassCount()) return static_cast<int>(HouseSpec::Specs().size());
1514 return 0;
1515 }
1516
1517 PickerItem GetPickerItem(int cls_id, int id) const override
1518 {
1519 const auto *spec = HouseSpec::Get(id);
1520 if (!spec->grf_prop.HasGrfFile()) return {0, spec->Index(), cls_id, id};
1521 return {spec->grf_prop.grfid, spec->grf_prop.local_id, cls_id, id};
1522 }
1523
1524 int GetSelectedType() const override { return sel_type; }
1525 void SetSelectedType(int id) const override { sel_type = id; }
1526
1527 static HouseZone GetHouseZoneFromClassId(int cls_id) { return static_cast<HouseZone>(to_underlying(HouseZone::TownEdge) + cls_id); }
1528 static int GetClassIdFromHouseZone(HouseZones zones) { return FindFirstBit((zones & HZ_ZONE_ALL).base()) - to_underlying(HouseZone::TownEdge); }
1529
1530 StringID GetTypeName(int cls_id, int id) const override
1531 {
1532 const HouseSpec *spec = HouseSpec::Get(id);
1533 if (spec == nullptr) return INVALID_STRING_ID;
1534 if (!spec->enabled) return INVALID_STRING_ID;
1535 if (!spec->building_availability.Any(climate_mask)) return INVALID_STRING_ID;
1536 if (!spec->building_availability.Test(GetHouseZoneFromClassId(cls_id))) return INVALID_STRING_ID;
1537 for (int i = 0; i < cls_id; i++) {
1538 /* Don't include if it's already included in an earlier zone. */
1539 if (spec->building_availability.Test(GetHouseZoneFromClassId(i))) return INVALID_STRING_ID;
1540 }
1541
1542 return GetHouseName(spec);
1543 }
1544
1545 std::span<const BadgeID> GetTypeBadges(int cls_id, int id) const override
1546 {
1547 const auto *spec = HouseSpec::Get(id);
1548 if (spec == nullptr) return {};
1549 if (!spec->enabled) return {};
1550 if (!spec->building_availability.Any(climate_mask)) return {};
1551 if (!spec->building_availability.Test(GetHouseZoneFromClassId(cls_id))) return {};
1552 for (int i = 0; i < cls_id; i++) {
1553 /* Don't include if it's already included in an earlier zone. */
1554 if (spec->building_availability.Test(GetHouseZoneFromClassId(i))) return {};
1555 }
1556
1557 return spec->badges;
1558 }
1559
1560 bool IsTypeAvailable(int, int id) const override
1561 {
1562 const HouseSpec *hs = HouseSpec::Get(id);
1563 return hs->enabled;
1564 }
1565
1566 void DrawType(int x, int y, int, int id) const override
1567 {
1568 DrawHouseInGUI(x, y, id, HousePickerCallbacks::sel_view);
1569 }
1570
1571 void FillUsedItems(std::set<PickerItem> &items) override
1572 {
1573 auto id_count = GetBuildingHouseIDCounts();
1574 for (auto it = id_count.begin(); it != id_count.end(); ++it) {
1575 if (*it == 0) continue;
1576 HouseID house = static_cast<HouseID>(std::distance(id_count.begin(), it));
1577 const HouseSpec *hs = HouseSpec::Get(house);
1578 int class_index = GetClassIdFromHouseZone(hs->building_availability);
1579 items.insert({0, house, class_index, house});
1580 }
1581 }
1582
1583 std::set<PickerItem> UpdateSavedItems(const std::set<PickerItem> &src) override
1584 {
1585 if (src.empty()) return src;
1586
1587 const auto &specs = HouseSpec::Specs();
1588 std::set<PickerItem> dst;
1589 for (const auto &item : src) {
1590 if (item.grfid == 0) {
1591 const HouseSpec *hs = HouseSpec::Get(item.local_id);
1592 if (hs == nullptr) continue;
1593 int class_index = GetClassIdFromHouseZone(hs->building_availability);
1594 dst.emplace(item.grfid, item.local_id, class_index, item.local_id);
1595 } else {
1596 /* Search for spec by grfid and local index. */
1597 auto it = std::ranges::find_if(specs, [&item](const HouseSpec &spec) { return spec.grf_prop.grfid == item.grfid && spec.grf_prop.local_id == item.local_id; });
1598 if (it == specs.end()) {
1599 /* Not preset, hide from UI. */
1600 dst.emplace(item.grfid, item.local_id, -1, -1);
1601 } else {
1602 int class_index = GetClassIdFromHouseZone(it->building_availability);
1603 dst.emplace(item.grfid, item.local_id, class_index, it->Index());
1604 }
1605 }
1606 }
1607
1608 return dst;
1609 }
1610
1611 static HousePickerCallbacks instance;
1612};
1613/* static */ HousePickerCallbacks HousePickerCallbacks::instance;
1614
1620 static CargoTypes GetProducedCargoOfHouse(const HouseSpec *hs)
1621{
1622 CargoTypes produced{};
1623 if (hs->callback_mask.Test(HouseCallbackMask::ProduceCargo)) {
1624 for (uint i = 0; i < 256; i++) {
1625 uint16_t callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, 0, hs->Index(), nullptr, INVALID_TILE, {}, true);
1626
1627 if (callback == CALLBACK_FAILED || callback == CALLBACK_HOUSEPRODCARGO_END) break;
1628
1629 CargoType cargo = GetCargoTranslation(GB(callback, 8, 7), hs->grf_prop.grffile);
1630 if (!IsValidCargoType(cargo)) continue;
1631
1632 uint amt = GB(callback, 0, 8);
1633 if (amt == 0) continue;
1634
1635 SetBit(produced, cargo);
1636 }
1637 } else {
1638 /* Cargo is not controlled by NewGRF, town production effect is used instead. */
1639 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_PASSENGERS]) SetBit(produced, cs->Index());
1640 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_MAIL]) SetBit(produced, cs->Index());
1641 }
1642 return produced;
1643}
1644
1645 struct BuildHouseWindow : public PickerWindow {
1646 std::string house_info{};
1647 static inline bool house_protected;
1648 static inline bool replace;
1649
1650 BuildHouseWindow(WindowDesc &desc, Window *parent) : PickerWindow(desc, parent, 0, HousePickerCallbacks::instance)
1651 {
1652 HousePickerCallbacks::instance.SetClimateMask();
1653 this->ConstructWindow();
1654 }
1655
1656 void UpdateSelectSize(const HouseSpec *spec)
1657 {
1658 if (spec == nullptr) {
1659 SetTileSelectSize(1, 1);
1660 ResetObjectToPlace();
1661 } else {
1662 SetObjectToPlaceWnd(SPR_CURSOR_TOWN, PAL_NONE, HT_RECT | HT_DIAGONAL, this);
1663 if (spec->building_flags.Test(BuildingFlag::Size2x2)) {
1664 SetTileSelectSize(2, 2);
1665 } else if (spec->building_flags.Test(BuildingFlag::Size2x1)) {
1666 SetTileSelectSize(2, 1);
1667 } else if (spec->building_flags.Test(BuildingFlag::Size1x2)) {
1668 SetTileSelectSize(1, 2);
1669 } else if (spec->building_flags.Test(BuildingFlag::Size1x1)) {
1670 SetTileSelectSize(1, 1);
1671 }
1672 }
1673 }
1674
1681 static std::string GetHouseYear(TimerGameCalendar::Year min_year, TimerGameCalendar::Year max_year)
1682 {
1683 if (min_year == CalendarTime::MIN_YEAR) {
1684 if (max_year == CalendarTime::MAX_YEAR) {
1685 return GetString(STR_HOUSE_PICKER_YEARS_ANY);
1686 }
1687 return GetString(STR_HOUSE_PICKER_YEARS_UNTIL, max_year);
1688 }
1689 if (max_year == CalendarTime::MAX_YEAR) {
1690 return GetString(STR_HOUSE_PICKER_YEARS_FROM, min_year);
1691 }
1692 return GetString(STR_HOUSE_PICKER_YEARS, min_year, max_year);
1693 }
1694
1700 static std::string GetHouseInformation(const HouseSpec *hs)
1701 {
1702 std::stringstream line;
1703
1704 line << GetString(STR_HOUSE_PICKER_NAME, GetHouseName(hs));
1705 line << "\n";
1706
1707 line << GetString(STR_HOUSE_PICKER_POPULATION, hs->population);
1708 line << "\n";
1709
1710 line << GetHouseYear(hs->min_year, hs->max_year);
1711 line << "\n";
1712
1713 uint8_t size = 0;
1714 if (hs->building_flags.Test(BuildingFlag::Size1x1)) size = 0x11;
1715 if (hs->building_flags.Test(BuildingFlag::Size2x1)) size = 0x21;
1716 if (hs->building_flags.Test(BuildingFlag::Size1x2)) size = 0x12;
1717 if (hs->building_flags.Test(BuildingFlag::Size2x2)) size = 0x22;
1718 line << GetString(STR_HOUSE_PICKER_SIZE, GB(size, 0, 4), GB(size, 4, 4));
1719
1720 auto cargo_string = BuildCargoAcceptanceString(GetAcceptedCargoOfHouse(hs), STR_HOUSE_PICKER_CARGO_ACCEPTED);
1721 if (cargo_string.has_value()) {
1722 line << "\n";
1723 line << *cargo_string;
1724 }
1725
1726 CargoTypes produced = GetProducedCargoOfHouse(hs);
1727 if (produced != 0) {
1728 line << "\n";
1729 line << GetString(STR_HOUSE_PICKER_CARGO_PRODUCED, produced);
1730 }
1731
1732 return line.str();
1733 }
1734
1735 void OnInit() override
1736 {
1737 this->InvalidateData(PICKER_INVALIDATION_ALL);
1738 this->PickerWindow::OnInit();
1739 }
1740
1741 void DrawWidget(const Rect &r, WidgetID widget) const override
1742 {
1743 if (widget == WID_BH_INFO) {
1744 if (!this->house_info.empty()) DrawStringMultiLine(r, this->house_info);
1745 } else {
1746 this->PickerWindow::DrawWidget(r, widget);
1747 }
1748 }
1749
1750 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
1751 {
1752 switch (widget) {
1753 case WID_BH_PROTECT_TOGGLE:
1754 BuildHouseWindow::house_protected = !BuildHouseWindow::house_protected;
1755 this->SetWidgetLoweredState(WID_BH_PROTECT_TOGGLE, BuildHouseWindow::house_protected);
1756
1757 SndClickBeep();
1758 this->SetDirty();
1759 break;
1760
1761 case WID_BH_REPLACE_TOGGLE:
1762 BuildHouseWindow::replace = !BuildHouseWindow::replace;
1763 this->SetWidgetLoweredState(WID_BH_REPLACE_TOGGLE, BuildHouseWindow::replace);
1764
1765 SndClickBeep();
1766 this->SetDirty();
1767 break;
1768
1769 default:
1770 this->PickerWindow::OnClick(pt, widget, click_count);
1771 break;
1772 }
1773 }
1774
1775 void OnInvalidateData(int data = 0, bool gui_scope = true) override
1776 {
1777 this->PickerWindow::OnInvalidateData(data, gui_scope);
1778 if (!gui_scope) return;
1779
1780 const HouseSpec *spec = HouseSpec::Get(HousePickerCallbacks::sel_type);
1781
1782 PickerInvalidations pi(data);
1783 if (pi.Test(PickerInvalidation::Position)) {
1784 UpdateSelectSize(spec);
1785 this->house_info = spec->enabled ? GetHouseInformation(spec) : "";
1786 }
1787
1788 /* If house spec already has the protected flag, handle it automatically and disable the buttons. */
1789 bool hasflag = spec->extra_flags.Test(HouseExtraFlag::BuildingIsProtected);
1790 if (hasflag) BuildHouseWindow::house_protected = true;
1791
1792 this->SetWidgetLoweredState(WID_BH_PROTECT_TOGGLE, BuildHouseWindow::house_protected);
1793 this->SetWidgetLoweredState(WID_BH_REPLACE_TOGGLE, BuildHouseWindow::replace);
1794
1795 this->SetWidgetDisabledState(WID_BH_PROTECT_TOGGLE, hasflag);
1796 }
1797
1798 void OnPlaceObject([[maybe_unused]] Point pt, TileIndex tile) override
1799 {
1800 const HouseSpec *spec = HouseSpec::Get(HousePickerCallbacks::sel_type);
1801 Command<CMD_PLACE_HOUSE>::Post(STR_ERROR_CAN_T_BUILD_HOUSE, CcPlaySound_CONSTRUCTION_OTHER, tile, spec->Index(), BuildHouseWindow::house_protected, BuildHouseWindow::replace);
1802 }
1803
1804 const IntervalTimer<TimerWindow> view_refresh_interval = {std::chrono::milliseconds(2500), [this](auto) {
1805 /* There are four different 'views' that are random based on house tile position. As this is not
1806 * user-controllable, instead we automatically cycle through them. */
1807 HousePickerCallbacks::sel_view = (HousePickerCallbacks::sel_view + 1) % 4;
1808 this->SetDirty();
1809 }};
1810
1811 static inline HotkeyList hotkeys{"buildhouse", {
1812 Hotkey('F', "focus_filter_box", PCWHK_FOCUS_FILTER_BOX),
1813 }};
1814};
1815
1817 static constexpr std::initializer_list<NWidgetPart> _nested_build_house_widgets = {
1818 NWidget(NWID_HORIZONTAL),
1819 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
1820 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_HOUSE_PICKER_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1821 NWidget(WWT_SHADEBOX, COLOUR_DARK_GREEN),
1822 NWidget(WWT_DEFSIZEBOX, COLOUR_DARK_GREEN),
1823 NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
1824 EndContainer(),
1825 NWidget(NWID_HORIZONTAL),
1826 NWidget(NWID_VERTICAL),
1827 NWidgetFunction(MakePickerClassWidgets),
1828 NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
1829 NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_picker, 0), SetPadding(WidgetDimensions::unscaled.picker),
1830 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_BH_INFO), SetFill(1, 1), SetMinimalTextLines(10, 0),
1831 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BH_PROTECT_TOGGLE), SetMinimalSize(60, 12), SetStringTip(STR_HOUSE_PICKER_PROTECT, STR_HOUSE_PICKER_PROTECT_TOOLTIP),
1832 NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_BH_REPLACE_TOGGLE), SetMinimalSize(60, 12), SetStringTip(STR_HOUSE_PICKER_REPLACE, STR_HOUSE_PICKER_REPLACE_TOOLTIP),
1833 EndContainer(),
1834 EndContainer(),
1835 EndContainer(),
1836 NWidgetFunction(MakePickerTypeWidgets),
1837 EndContainer(),
1838};
1839
1840static WindowDesc _build_house_desc(
1841 WDP_AUTO, "build_house", 0, 0,
1842 WC_BUILD_HOUSE, WC_BUILD_TOOLBAR,
1843 WindowDefaultFlag::Construction,
1844 _nested_build_house_widgets,
1845 &BuildHouseWindow::hotkeys
1846);
1847
1848void ShowBuildHousePicker(Window *parent)
1849{
1850 if (BringWindowToFrontById(WC_BUILD_HOUSE, 0)) return;
1851 new BuildHouseWindow(_build_house_desc, parent);
1852}
backup_type.hpp
Class for backupping variables and making sure they are restored later.
GB
static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
Definition bitmath_func.hpp:32
SetBit
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
Definition bitmath_func.hpp:121
FindFirstBit
constexpr uint8_t FindFirstBit(T x)
Search the first set bit in a value.
Definition bitmath_func.hpp:189
HasBit
constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
Definition bitmath_func.hpp:103
CargoType
uint8_t CargoType
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:21
IsValidCargoType
bool IsValidCargoType(CargoType cargo)
Test whether cargo type is not INVALID_CARGO.
Definition cargo_type.h:104
BuildCargoAcceptanceString
std::optional< std::string > BuildCargoAcceptanceString(const CargoArray &acceptance, StringID label)
Build comma-separated cargo acceptance string.
Definition cargotype.cpp:267
TPE_PASSENGERS
@ TPE_PASSENGERS
Cargo behaves passenger-like for production.
Definition cargotype.h:37
TPE_MAIL
@ TPE_MAIL
Cargo behaves mail-like for production.
Definition cargotype.h:38
TownAcceptanceEffect
TownAcceptanceEffect
Town growth effect when delivering cargo.
Definition cargotype.h:22
TAE_END
@ TAE_END
End of town effects.
Definition cargotype.h:30
BaseBitSet::Test
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
Definition base_bitset_type.hpp:141
BaseBitSet::Flip
constexpr Timpl & Flip(Tvalue_type value)
Flip the value-th bit.
Definition base_bitset_type.hpp:116
BaseBitSet::Set
constexpr Timpl & Set()
Set all bits.
Definition base_bitset_type.hpp:40
BaseBitSet::Any
constexpr bool Any(const Timpl &other) const
Test if any of the given values are set.
Definition base_bitset_type.hpp:170
BaseBitSet::GetNthSetBit
std::optional< Tvalue_type > GetNthSetBit(uint n) const
Get the value of the Nth set bit.
Definition base_bitset_type.hpp:247
CommandCost
Common return value for all commands.
Definition command_type.h:24
CommandCost::Succeeded
bool Succeeded() const
Did this command succeed?
Definition command_type.h:168
CommandCost::Failed
bool Failed() const
Did this command fail?
Definition command_type.h:177
EncodedString::GetDecodedString
std::string GetDecodedString() const
Decode the encoded string.
Definition strings.cpp:207
EnumBitSet< TownAction, uint8_t >
GUIList
List template of 'things' T to sort in a GUI.
Definition sortlist_type.h:43
GUIList::RebuildDone
void RebuildDone()
Notify the sortlist that the rebuild is done.
Definition sortlist_type.h:405
GUIList::SetListing
void SetListing(Listing l)
Import sort conditions.
Definition sortlist_type.h:148
GUIList::IsDescSortOrder
bool IsDescSortOrder() const
Check if the sort order is descending.
Definition sortlist_type.h:242
GUIList::ToggleSortOrder
void ToggleSortOrder()
Toggle the sort order Since that is the worst condition for the sort function reverse the list here.
Definition sortlist_type.h:252
GUIList::NeedRebuild
bool NeedRebuild() const
Check if a rebuild is needed.
Definition sortlist_type.h:387
GUIList::ForceRebuild
void ForceRebuild()
Force that a rebuild is needed.
Definition sortlist_type.h:395
GUIList::Sort
bool Sort(Comp compare)
Sort the list.
Definition sortlist_type.h:266
GUIList::ForceResort
void ForceResort()
Force a resort next Sort call Reset the resort timer if used too.
Definition sortlist_type.h:232
GUIList::SortType
uint8_t SortType() const
Get the sorttype of the list.
Definition sortlist_type.h:110
GUIList::GetListing
Listing GetListing() const
Export current sort conditions.
Definition sortlist_type.h:134
GUIList::SetSortFuncs
void SetSortFuncs(std::span< SortFunction *const > n_funcs)
Hand the sort function pointers to the GUIList.
Definition sortlist_type.h:293
GUIList::SetSortType
void SetSortType(uint8_t n_type)
Set the sorttype of the list.
Definition sortlist_type.h:120
HousePickerCallbacks
Definition town_gui.cpp:1445
HousePickerCallbacks::GetPickerItem
PickerItem GetPickerItem(int cls_id, int id) const override
Get data about an item.
Definition town_gui.cpp:1517
HousePickerCallbacks::IsActive
bool IsActive() const override
Should picker class/type selection be enabled?
Definition town_gui.cpp:1494
HousePickerCallbacks::SetClimateMask
void SetClimateMask()
Set climate mask for filtering buildings from current landscape.
Definition town_gui.cpp:1452
HousePickerCallbacks::SetSelectedClass
void SetSelectedClass(int cls_id) const override
Set the selected class.
Definition town_gui.cpp:1502
HousePickerCallbacks::GetClassTooltip
StringID GetClassTooltip() const override
Get the tooltip string for the class list.
Definition town_gui.cpp:1492
HousePickerCallbacks::GetTypeBadges
std::span< const BadgeID > GetTypeBadges(int cls_id, int id) const override
Get the item of a type.
Definition town_gui.cpp:1545
HousePickerCallbacks::DrawType
void DrawType(int x, int y, int, int id) const override
Draw preview image of an item.
Definition town_gui.cpp:1566
HousePickerCallbacks::sel_view
static int sel_view
Currently selected 'view'. This is not controllable as its based on random data.
Definition town_gui.cpp:1478
HousePickerCallbacks::GetClassCount
int GetClassCount() const override
Get the number of classes.
Definition town_gui.cpp:1497
HousePickerCallbacks::FillUsedItems
void FillUsedItems(std::set< PickerItem > &items) override
Fill a set with all items that are used by the current player.
Definition town_gui.cpp:1571
HousePickerCallbacks::sel_type
static int sel_type
Currently selected HouseID.
Definition town_gui.cpp:1477
HousePickerCallbacks::GetSelectedClass
int GetSelectedClass() const override
Get the index of the selected class.
Definition town_gui.cpp:1501
HousePickerCallbacks::UpdateSavedItems
std::set< PickerItem > UpdateSavedItems(const std::set< PickerItem > &src) override
Update link between grfid/localidx and class_index/index in saved items.
Definition town_gui.cpp:1583
HousePickerCallbacks::GetTypeTooltip
StringID GetTypeTooltip() const override
Get the tooltip string for the type grid.
Definition town_gui.cpp:1493
HousePickerCallbacks::SetSelectedType
void SetSelectedType(int id) const override
Set the selected type.
Definition town_gui.cpp:1525
HousePickerCallbacks::GetTypeName
StringID GetTypeName(int cls_id, int id) const override
Get the item of a type.
Definition town_gui.cpp:1530
HousePickerCallbacks::GetSelectedType
int GetSelectedType() const override
Get the selected type.
Definition town_gui.cpp:1524
HousePickerCallbacks::IsTypeAvailable
bool IsTypeAvailable(int, int id) const override
Test if an item is currently buildable.
Definition town_gui.cpp:1560
HousePickerCallbacks::HasClassChoice
bool HasClassChoice() const override
Are there multiple classes to chose from?
Definition town_gui.cpp:1496
HousePickerCallbacks::class_mask
uint8_t class_mask
Mask of available 'classes'.
Definition town_gui.cpp:1474
HousePickerCallbacks::GetTypeCount
int GetTypeCount(int cls_id) const override
Get the number of types in a class.
Definition town_gui.cpp:1511
HousePickerCallbacks::GetClassName
StringID GetClassName(int id) const override
Get the name of a class.
Definition town_gui.cpp:1504
HousePickerCallbacks::sel_class
static int sel_class
Currently selected 'class'.
Definition town_gui.cpp:1476
IntervalTimer
An interval timer will fire every interval, and will continue to fire until it is deleted.
Definition timer.h:76
Kdtree
K-dimensional tree, specialised for 2-dimensional space.
Definition kdtree.hpp:33
Kdtree::Insert
void Insert(const T &element)
Insert a single element in the tree.
Definition kdtree.hpp:396
Kdtree::Remove
void Remove(const T &element)
Remove a single element from the tree, if it exists.
Definition kdtree.hpp:415
Kdtree::Clear
void Clear()
Clear the tree.
Definition kdtree.hpp:375
NWidgetBase
Baseclass for nested widgets.
Definition widget_type.h:137
NWidgetBase::current_x
uint current_x
Current horizontal size (after resizing).
Definition widget_type.h:238
NWidgetBase::smallest_y
uint smallest_y
Smallest vertical size of the widget in a filled window.
Definition widget_type.h:236
NWidgetBase::current_y
uint current_y
Current vertical size (after resizing).
Definition widget_type.h:239
NWidgetViewport
Nested widget to display a viewport in a window.
Definition widget_type.h:697
NWidgetViewport::UpdateViewportCoordinates
void UpdateViewportCoordinates(Window *w)
Update the position and size of the viewport (after eg a resize).
Definition widget.cpp:2430
NWidgetViewport::InitializeViewport
void InitializeViewport(Window *w, std::variant< TileIndex, VehicleID > focus, ZoomLevel zoom)
Initialize the viewport of the window.
Definition widget.cpp:2421
OverflowSafeInt< int64_t >
PickerCallbacks
Class for PickerClassWindow to collect information and retain state.
Definition picker_gui.h:39
PickerWindow
Definition picker_gui.h:157
PickerWindow::DrawWidget
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
Definition picker_gui.cpp:308
PickerWindow::PickerInvalidation::Position
@ Position
Update scroll positions.
PickerWindow::PCWHK_FOCUS_FILTER_BOX
@ PCWHK_FOCUS_FILTER_BOX
Focus the edit box for editing the filter string.
Definition picker_gui.h:205
PickerWindow::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 picker_gui.cpp:375
PickerWindow::OnInvalidateData
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Definition picker_gui.cpp:492
PickerWindow::OnInit
void OnInit() override
Notification that the nested widget tree gets initialized.
Definition picker_gui.cpp:251
Scrollbar
Scrollbar data structure.
Definition widget_type.h:711
Scrollbar::SetCount
void SetCount(size_t num)
Sets the number of elements in the list.
Definition widget_type.h:795
Scrollbar::GetScrolledItemFromWidget
auto GetScrolledItemFromWidget(Tcontainer &container, int clickpos, const Window *const w, WidgetID widget, int padding=0, int line_height=-1) const
Return an iterator pointing to the element of a scrolled widget that a user clicked in.
Definition widget_type.h:894
Scrollbar::SetCapacityFromWidget
void SetCapacityFromWidget(Window *w, WidgetID widget, int padding=0)
Set capacity of visible elements from the size and resize properties of a widget.
Definition widget.cpp:2527
Scrollbar::GetCount
size_type GetCount() const
Gets the number of elements in the list.
Definition widget_type.h:737
Scrollbar::GetVisibleRangeIterators
auto GetVisibleRangeIterators(Tcontainer &container) const
Get a pair of iterators for the range of visible elements in a container.
Definition widget_type.h:875
Ticks::DAY_TICKS
static constexpr TimerGameTick::Ticks DAY_TICKS
1 day is 74 ticks; TimerGameCalendar::date_fract used to be uint16_t and incremented by 885.
Definition timer_game_tick.h:75
TimerGameConst< struct Calendar >::MIN_YEAR
static constexpr TimerGame< struct Calendar >::Year MIN_YEAR
The absolute minimum year in OTTD.
Definition timer_game_common.h:176
TimerGameConst< struct Calendar >::MAX_YEAR
static constexpr TimerGame< struct Calendar >::Year MAX_YEAR
MAX_YEAR, nicely rounded value of the number of years that can be encoded in a single 32 bits date,...
Definition timer_game_common.h:173
TimerGameEconomy::UsingWallclockUnits
static bool UsingWallclockUnits(bool newgame=false)
Check if we are using wallclock units.
Definition timer_game_economy.cpp:98
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::vsep_normal
int vsep_normal
Normal vertical spacing.
Definition window_gui.h:58
WidgetDimensions::unscaled
static const WidgetDimensions unscaled
Unscaled widget dimensions.
Definition window_gui.h:93
WidgetDimensions::hsep_normal
int hsep_normal
Normal horizontal spacing.
Definition window_gui.h:61
command_func.h
Functions related to commands.
DoCommandFlag::Execute
@ Execute
execute the given command
Commands
Commands
List of commands.
Definition command_type.h:196
company_base.h
Definition of stuff that is very close to a company, like the company struct itself.
DrawCompanyIcon
void DrawCompanyIcon(CompanyID c, int x, int y)
Draw the icon of a company.
Definition company_cmd.cpp:175
GetCompanyPalette
PaletteID GetCompanyPalette(CompanyID company)
Get the palette for recolouring with a company colour.
Definition company_cmd.cpp:164
GetAvailableMoney
Money GetAvailableMoney(CompanyID company)
Get the amount of money that a company has available, or INT64_MAX if there is no such valid company.
Definition company_cmd.cpp:238
_local_company
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition company_cmd.cpp:55
company_func.h
Functions related to companies.
company_gui.h
GUI Functions related to companies.
ShowDropDownMenu
void ShowDropDownMenu(Window *w, std::span< const StringID > strings, int selected, WidgetID button, uint32_t disabled_mask, uint32_t hidden_mask, uint width)
Show a dropdown menu window near a widget of the parent window.
Definition dropdown.cpp:458
dropdown_func.h
Functions related to the drop down widget.
to_underlying
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23)
Definition enum_type.hpp:17
error.h
Functions related to errors.
WL_INFO
@ WL_INFO
Used for DoCommand-like (and some non-fatal AI GUI) errors/information.
Definition error.h:24
ShowErrorMessage
void ShowErrorMessage(EncodedString &&summary_msg, int x, int y, CommandCost &cc)
Display an error message in a window.
Definition error_gui.cpp:296
SLO_LOAD
@ SLO_LOAD
File is being loaded.
Definition fileio_type.h:54
FT_TOWN_DATA
@ FT_TOWN_DATA
town data file
Definition fileio_type.h:22
fios.h
Declarations for savegames operations.
ShowSaveLoadDialog
void ShowSaveLoadDialog(AbstractFileType abstract_filetype, SaveLoadOperation fop)
Launch save/load dialog in the given mode.
Definition fios_gui.cpp:1000
GetCharacterHeight
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
Definition fontcache.cpp:87
_generating_world
bool _generating_world
Whether we are generating the map or not.
Definition genworld.cpp:74
genworld.h
Functions related to world/map generation.
maxdim
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
Definition geometry_func.cpp:22
geometry_func.hpp
Geometry functions.
GetStringHeight
int GetStringHeight(std::string_view str, int maxw, FontSize fontsize)
Calculates height of string (in pixels).
Definition gfx.cpp:715
GetSpriteSize
Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
Get the size of a sprite.
Definition gfx.cpp:968
_shift_pressed
bool _shift_pressed
Is Shift pressed?
Definition gfx.cpp:39
GetStringBoundingBox
Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition gfx.cpp:897
GetStringListBoundingBox
Dimension GetStringListBoundingBox(std::span< const StringID > list, FontSize fontsize)
Get maximum dimension of a list of strings.
Definition gfx.cpp:935
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:668
_ctrl_pressed
bool _ctrl_pressed
Is Ctrl pressed?
Definition gfx.cpp:38
DrawSprite
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
Draw a sprite, not in a viewport.
Definition gfx.cpp:1034
GetStringMultiLineBoundingBox
Dimension GetStringMultiLineBoundingBox(StringID str, const Dimension &suggestion)
Calculate string bounding box for multi-line strings.
Definition gfx.cpp:751
DrawStringMultiLine
int DrawStringMultiLine(int left, int right, int top, int bottom, std::string_view str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly over multiple lines.
Definition gfx.cpp:785
SpriteID
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition gfx_type.h:17
FS_NORMAL
@ FS_NORMAL
Index of the normal font in the font tables.
Definition gfx_type.h:249
TextColour
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
Definition gfx_type.h:307
TC_NO_SHADE
@ TC_NO_SHADE
Do not add shading to this text colour.
Definition gfx_type.h:331
graph_gui.h
Graph GUI functions.
NWidgetFunction
constexpr NWidgetPart NWidgetFunction(NWidgetFunctionType *func_ptr)
Obtain a nested widget (sub)tree from an external source.
Definition widget_type.h:1448
SetFill
constexpr NWidgetPart SetFill(uint16_t fill_x, uint16_t fill_y)
Widget part function for setting filling.
Definition widget_type.h:1222
SetSpriteTip
constexpr NWidgetPart SetSpriteTip(SpriteID sprite, StringID tip={})
Widget part function for setting the sprite and tooltip.
Definition widget_type.h:1254
SetPIP
constexpr NWidgetPart SetPIP(uint8_t pre, uint8_t inter, uint8_t post)
Widget part function for setting a pre/inter/post spaces.
Definition widget_type.h:1378
SetScrollbar
constexpr NWidgetPart SetScrollbar(WidgetID index)
Attach a scrollbar to a widget.
Definition widget_type.h:1402
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:1335
SetStringTip
constexpr NWidgetPart SetStringTip(StringID string, StringID tip={})
Widget part function for setting the string and tooltip.
Definition widget_type.h:1243
SetAspect
constexpr NWidgetPart SetAspect(float ratio, AspectFlags flags=AspectFlag::ResizeX)
Widget part function for setting the aspect ratio.
Definition widget_type.h:1413
SetMinimalSize
constexpr NWidgetPart SetMinimalSize(int16_t x, int16_t y)
Widget part function for setting the minimal size.
Definition widget_type.h:1159
SetToolTip
constexpr NWidgetPart SetToolTip(StringID tip)
Widget part function for setting tooltip and clearing the widget data.
Definition widget_type.h:1321
EndContainer
constexpr NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME,...
Definition widget_type.h:1232
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:1427
SetMinimalTextLines
constexpr NWidgetPart SetMinimalTextLines(uint8_t lines, uint8_t spacing, FontSize size=FS_NORMAL)
Widget part function for setting the minimal text lines.
Definition widget_type.h:1190
SetResize
constexpr NWidgetPart SetResize(int16_t dx, int16_t dy)
Widget part function for setting the resize step.
Definition widget_type.h:1148
LowestSnowLine
uint8_t LowestSnowLine()
Get the lowest possible snow line height, either variable or static.
Definition landscape.cpp:629
GetSnowLine
uint8_t GetSnowLine()
Get the current snow line, either variable or static.
Definition landscape.cpp:606
Window::SetDirty
void SetDirty() const
Mark entire window as dirty (in need of re-paint)
Definition window.cpp:968
MarkWholeScreenDirty
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
Definition gfx.cpp:1549
gui.h
GUI functions that shouldn't be here.
ShowExtraViewportWindow
void ShowExtraViewportWindow(TileIndex tile=INVALID_TILE)
Show a new Extra Viewport window.
Definition viewport_gui.cpp:159
hotkeys.h
Hotkey related functions.
house.h
definition of HouseSpec and accessors
HouseExtraFlag::BuildingIsProtected
@ BuildingIsProtected
towns and AI will not remove this house, while human players will be able to
GetClimateMaskForLandscape
HouseZones GetClimateMaskForLandscape()
Get the HouseZones climate mask for the current landscape type.
Definition town_cmd.cpp:2366
NEW_HOUSE_OFFSET
static const HouseID NEW_HOUSE_OFFSET
Offset for new houses.
Definition house.h:28
TOWN_HOUSE_COMPLETED
static const uint8_t TOWN_HOUSE_COMPLETED
Simple value that indicates the house has reached the final stage of construction.
Definition house.h:25
HouseZone
HouseZone
Definition house.h:55
HouseID
uint16_t HouseID
OpenTTD ID of house types.
Definition house_type.h:15
landscape.h
Functions related to OTTD's landscape.
RemapCoords
Point RemapCoords(int x, int y, int z)
Map 3D world or tile coordinate to equivalent 2D coordinate as used in the viewports and smallmap.
Definition landscape.h:81
DoZoomInOutWindow
bool DoZoomInOutWindow(ZoomStateChange how, Window *w)
Zooms a viewport in a window in or out.
Definition main_gui.cpp:93
HandlePlacePushButton
bool HandlePlacePushButton(Window *w, WidgetID widget, CursorID cursor, HighLightStyle mode)
This code is shared for the majority of the pushbuttons.
Definition main_gui.cpp:63
RoundDivSU
constexpr int RoundDivSU(int a, uint b)
Computes round(a / b) for signed a and unsigned b.
Definition math_func.hpp:332
ShowQueryString
void ShowQueryString(std::string_view str, StringID caption, uint maxsize, Window *parent, CharSetFilter afilter, QueryStringFlags flags)
Show a query popup window with a textbox in it.
Definition misc_gui.cpp:1064
_networking
bool _networking
are we in networking mode?
Definition network.cpp:67
_network_server
bool _network_server
network-server is active
Definition network.cpp:68
network.h
Basic functions/variables used all over the place.
GrfSpecFeature
GrfSpecFeature
Definition newgrf.h:68
CBID_HOUSE_CUSTOM_NAME
@ CBID_HOUSE_CUSTOM_NAME
Called on the Get Tile Description for an house tile.
Definition newgrf_callbacks.h:226
CBID_HOUSE_PRODUCE_CARGO
@ CBID_HOUSE_PRODUCE_CARGO
Called to determine how much cargo a town building produces.
Definition newgrf_callbacks.h:131
CALLBACK_FAILED
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
Definition newgrf_callbacks.h:439
HouseCallbackMask::ProduceCargo
@ ProduceCargo
custom cargo production
CALLBACK_HOUSEPRODCARGO_END
static const uint CALLBACK_HOUSEPRODCARGO_END
Sentinel indicating that the loop for CBID_HOUSE_PRODUCE_CARGO has ended.
Definition newgrf_callbacks.h:440
GetCargoTranslation
CargoType GetCargoTranslation(uint8_t cargo, const GRFFile *grffile, bool usebit)
Translate a GRF-local cargo slot/bitnum into a CargoType.
Definition newgrf_cargo.cpp:80
newgrf_cargo.h
Cargo support for NewGRFs.
ErrorUnknownCallbackResult
void ErrorUnknownCallbackResult(uint32_t grfid, uint16_t cbid, uint16_t cb_res)
Record that a NewGRF returned an unknown/invalid callback result.
Definition newgrf_commons.cpp:517
GetBuildingHouseIDCounts
std::span< const uint > GetBuildingHouseIDCounts()
Get read-only span of total HouseID building counts.
Definition newgrf_house.cpp:180
DrawNewHouseTileInGUI
void DrawNewHouseTileInGUI(int x, int y, const HouseSpec *spec, HouseID house_id, int view)
Draw representation of a house tile for GUI purposes.
Definition newgrf_house.cpp:524
newgrf_house.h
Functions related to NewGRF houses.
GetGRFStringID
StringID GetGRFStringID(uint32_t grfid, GRFStringID stringid)
Returns the index for this stringid associated with its grfID.
Definition newgrf_text.cpp:580
newgrf_text.h
Header of Action 04 "universal holder" structure and functions.
GRFSTR_MISC_GRF_TEXT
static constexpr GRFStringID GRFSTR_MISC_GRF_TEXT
Miscellaneous GRF text range.
Definition newgrf_text_type.h:18
UpdateOSKOriginalText
void UpdateOSKOriginalText(const Window *parent, WidgetID button)
Updates the original text of the OSK so when the 'parent' changes the original and you press on cance...
Definition osk_gui.cpp:406
MakePickerClassWidgets
std::unique_ptr< NWidgetBase > MakePickerClassWidgets()
Create nested widgets for the class picker widgets.
Definition picker_gui.cpp:745
MakePickerTypeWidgets
std::unique_ptr< NWidgetBase > MakePickerTypeWidgets()
Create nested widgets for the type picker widgets.
Definition picker_gui.cpp:768
picker_gui.h
Functions/types etc.
querystring_gui.h
Base for the GUIs that have an edit box in them.
_interactive_random
Randomizer _interactive_random
Random used everywhere else, where it does not (directly) influence the game state.
Definition random_func.cpp:36
UpdateNearestTownForRoadTiles
void UpdateNearestTownForRoadTiles(bool invalidate)
Updates cached nearest town for all road tiles.
Definition road_cmd.cpp:1944
road_cmd.h
Road related functions.
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
SWS_OFF
@ SWS_OFF
Scroll wheel has no effect.
Definition settings_type.h:159
sortlist_type.h
Base types for having sorted lists in GUIs.
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.
SND_1F_CONSTRUCTION_OTHER
@ SND_1F_CONSTRUCTION_OTHER
29 == 0x1D Construction: other (non-water, non-rail, non-bridge)
Definition sound_type.h:76
stdafx.h
Definition of base types and functions in a cross-platform compatible way.
StrNaturalCompare
int StrNaturalCompare(std::string_view s1, std::string_view s2, bool ignore_garbage_at_front)
Compares two strings using case insensitive natural sort.
Definition string.cpp:427
string_consumer.hpp
Parse strings.
ParseInteger
static std::optional< T > ParseInteger(std::string_view arg, int base=10, bool clamp=false)
Change a string into its number representation.
Definition string_consumer.hpp:917
string_func.h
Functions related to low-level strings.
CS_NUMERAL
@ CS_NUMERAL
Only numeric ones.
Definition string_type.h:26
CS_ALPHANUMERAL
@ CS_ALPHANUMERAL
Both numeric and alphabetic and spaces and stuff.
Definition string_type.h:25
stringfilter_type.h
Searching and filtering using a stringterm.
GetEncodedString
EncodedString GetEncodedString(StringID str)
Encode a string with no parameters into an encoded string.
Definition strings.cpp:90
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
GetParamMaxDigits
uint64_t GetParamMaxDigits(uint count, FontSize size)
Get some number that is suitable for string size computations.
Definition strings.cpp:218
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
INVALID_STRING_ID
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
Definition strings_type.h:20
TD_RTL
@ TD_RTL
Text is written right-to-left by default.
Definition strings_type.h:27
MAX_CHAR_LENGTH
static const int MAX_CHAR_LENGTH
Max. length of UTF-8 encoded unicode character.
Definition strings_type.h:21
Backup
Class to backup a specific variable and restore it later.
Definition backup_type.hpp:21
Backup::Restore
void Restore()
Restore the variable.
Definition backup_type.hpp:110
BuildHouseWindow
Definition town_gui.cpp:1645
BuildHouseWindow::GetHouseYear
static std::string GetHouseYear(TimerGameCalendar::Year min_year, TimerGameCalendar::Year max_year)
Get a date range string for house availability year.
Definition town_gui.cpp:1681
BuildHouseWindow::OnPlaceObject
void OnPlaceObject(Point pt, TileIndex tile) override
The user clicked some place on the map when a tile highlight mode has been set.
Definition town_gui.cpp:1798
BuildHouseWindow::DrawWidget
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
Definition town_gui.cpp:1741
BuildHouseWindow::GetHouseInformation
static std::string GetHouseInformation(const HouseSpec *hs)
Get information string for a house.
Definition town_gui.cpp:1700
BuildHouseWindow::OnInvalidateData
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Definition town_gui.cpp:1775
BuildHouseWindow::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 town_gui.cpp:1750
BuildHouseWindow::OnInit
void OnInit() override
Notification that the nested widget tree gets initialized.
Definition town_gui.cpp:1735
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
CargoSpec::town_production_cargoes
static std::array< std::vector< const CargoSpec * >, NUM_TPE > town_production_cargoes
List of cargo specs for each Town Product Effect.
Definition cargotype.h:25
ClientSettings::sound
SoundSettings sound
sound effect settings
Definition settings_type.h:653
ClientSettings::gui
GUISettings gui
settings related to the GUI
Definition settings_type.h:650
CommandHelper
Definition command_func.h:84
Company
Definition company_base.h:127
Coord2D< int >
Coord2D::y
T y
Y coordinate.
Definition geometry_type.hpp:35
Coord2D::x
T x
X coordinate.
Definition geometry_type.hpp:34
Coord3D::x
T x
X coordinate.
Definition geometry_type.hpp:44
Coord3D::y
T y
Y coordinate.
Definition geometry_type.hpp:45
Coord3D::z
T z
Z coordinate.
Definition geometry_type.hpp:46
Dimension
Dimensions (a width and height) of a rectangle in 2D.
Definition geometry_type.hpp:56
DrawBuildingsTileStruct
This structure is the same for both Industries and Houses.
Definition sprite.h:81
EconomySettings::bribe
bool bribe
enable bribing the local authority
Definition settings_type.h:542
EconomySettings::found_town
TownFounding found_town
town founding.
Definition settings_type.h:558
EconomySettings::exclusive_rights
bool exclusive_rights
allow buying exclusive rights
Definition settings_type.h:546
EconomySettings::town_layout
TownLayout town_layout
select town layout,
Definition settings_type.h:555
EconomySettings::station_noise_level
bool station_noise_level
build new airports when the town noise level is still within accepted limits
Definition settings_type.h:560
EconomySettings::fund_buildings
bool fund_buildings
allow funding new buildings
Definition settings_type.h:547
EconomySettings::fund_roads
bool fund_roads
allow funding local road reconstruction
Definition settings_type.h:548
FoundTownWindow
Found a town window class.
Definition town_gui.cpp:1145
FoundTownWindow::townnameparts
uint32_t townnameparts
Generated town name.
Definition town_gui.cpp:1152
FoundTownWindow::town_layout
TownLayout town_layout
Selected town layout.
Definition town_gui.cpp:1148
FoundTownWindow::OnPlaceObject
void OnPlaceObject(Point pt, TileIndex tile) override
The user clicked some place on the map when a tile highlight mode has been set.
Definition town_gui.cpp:1322
FoundTownWindow::townname_editbox
QueryString townname_editbox
Townname editbox.
Definition town_gui.cpp:1150
FoundTownWindow::OnInvalidateData
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Definition town_gui.cpp:1338
FoundTownWindow::OnInit
void OnInit() override
Notification that the nested widget tree gets initialized.
Definition town_gui.cpp:1169
FoundTownWindow::town_size
TownSize town_size
Selected town size.
Definition town_gui.cpp:1147
FoundTownWindow::townnamevalid
bool townnamevalid
Is generated town name valid?
Definition town_gui.cpp:1151
FoundTownWindow::params
TownNameParams params
Town name parameters.
Definition town_gui.cpp:1153
FoundTownWindow::OnQueryTextFinished
void OnQueryTextFinished(std::optional< std::string > str) override
The query window opened from this window has closed.
Definition town_gui.cpp:1305
FoundTownWindow::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 town_gui.cpp:1240
FoundTownWindow::OnPlaceObjectAbort
void OnPlaceObjectAbort() override
The user cancelled a tile highlight mode that has been set.
Definition town_gui.cpp:1327
FoundTownWindow::city
bool city
Are we building a city?
Definition town_gui.cpp:1149
GRFFilePropsBase::grffile
const struct GRFFile * grffile
grf file that introduced this entity
Definition newgrf_commons.h:318
GRFFilePropsBase::local_id
uint16_t local_id
id defined by the grf file for this entity
Definition newgrf_commons.h:316
GRFFilePropsBase::grfid
uint32_t grfid
grfid that introduced this entity.
Definition newgrf_commons.h:317
GUISettings::persistent_buildingtools
bool persistent_buildingtools
keep the building tools active after usage
Definition settings_type.h:225
GUISettings::scrollwheel_scrolling
uint8_t scrollwheel_scrolling
scrolling using the scroll wheel?
Definition settings_type.h:203
GameSettings::economy
EconomySettings economy
settings to change the economy
Definition settings_type.h:642
HotkeyList
List of hotkeys for a window.
Definition hotkeys.h:37
Hotkey
All data for a single hotkey.
Definition hotkeys.h:21
HouseSpec
Definition house.h:98
HouseSpec::grf_prop
SubstituteGRFFileProps grf_prop
Properties related the the grf file.
Definition house.h:114
HouseSpec::enabled
bool enabled
the house is available to build (true by default, but can be disabled by newgrf)
Definition house.h:111
HouseSpec::Get
static HouseSpec * Get(size_t house_id)
Get the spec for a house ID.
Definition newgrf_house.cpp:70
HouseSpec::building_flags
BuildingFlags building_flags
some flags that describe the house (size, stadium etc...)
Definition house.h:109
HouseSpec::max_year
TimerGameCalendar::Year max_year
last year it can be built
Definition house.h:101
HouseSpec::callback_mask
HouseCallbackMasks callback_mask
Bitmask of house callbacks that have to be called.
Definition house.h:115
HouseSpec::population
uint8_t population
population (Zero on other tiles in multi tile house.)
Definition house.h:102
HouseSpec::extra_flags
HouseExtraFlags extra_flags
some more flags
Definition house.h:118
HouseSpec::min_year
TimerGameCalendar::Year min_year
introduction year of the house
Definition house.h:100
HouseSpec::Index
HouseID Index() const
Gets the index of this spec.
Definition newgrf_house.cpp:60
HouseSpec::building_name
StringID building_name
building name
Definition house.h:104
HouseSpec::building_availability
HouseZones building_availability
where can it be built (climates, zones)
Definition house.h:110
HouseSpec::Specs
static std::vector< HouseSpec > & Specs()
Get a reference to all HouseSpecs.
Definition newgrf_house.cpp:51
Listing
Data structure describing how to show the list (what sort direction and criteria).
Definition sortlist_type.h:26
Listing::order
bool order
Ascending/descending.
Definition sortlist_type.h:27
PalSpriteID::sprite
SpriteID sprite
The 'real' sprite.
Definition gfx_type.h:23
PalSpriteID::pal
PaletteID pal
The palette (use PAL_NONE) if not needed)
Definition gfx_type.h:24
PickerItem
Definition picker_gui.h:25
PoolID< uint16_t, struct TownIDTag, 64000, 0xFFFF >
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<&_town_pool >::Get
static Titem * Get(auto index)
Returns Titem with given index.
Definition pool_type.hpp:387
Pool::PoolItem<&_town_pool >::GetNumItems
static size_t GetNumItems()
Returns number of valid items in the pool.
Definition pool_type.hpp:417
Pool::PoolItem::index
Tindex index
Index of this pool item.
Definition pool_type.hpp:286
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
QueryString
Data stored about a string that can be modified in the GUI.
Definition querystring_gui.h:20
QueryString::cancel_button
int cancel_button
Widget button of parent window to simulate when pressing CANCEL in OSK.
Definition querystring_gui.h:28
QueryString::ACTION_CLEAR
static const int ACTION_CLEAR
Clear editbox.
Definition querystring_gui.h:24
RectPadding::Horizontal
constexpr uint Horizontal() const
Get total horizontal padding of RectPadding.
Definition geometry_type.hpp:89
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::Shrink
Rect Shrink(int s) const
Copy and shrink Rect by s pixels.
Definition geometry_type.hpp:124
Rect::Indent
Rect Indent(int indent, bool end) const
Copy Rect and indent it from its position.
Definition geometry_type.hpp:224
ResizeInfo::step_height
uint step_height
Step-size of height resize changes.
Definition window_gui.h:213
SoundSettings::confirm
bool confirm
Play sound effect on successful constructions or other actions.
Definition settings_type.h:275
SpriteBounds::origin
Coord3D< int8_t > origin
Position of northern corner within tile.
Definition sprite.h:19
StandardGRFFileProps::HasSpriteGroups
bool HasSpriteGroups() const
Check whether the entity has sprite groups.
Definition newgrf_commons.h:385
StringFilter
String filter and state.
Definition stringfilter_type.h:30
StringFilter::IsEmpty
bool IsEmpty() const
Check whether any filter words were entered.
Definition stringfilter_type.h:57
StringFilter::SetFilterTerm
void SetFilterTerm(std::string_view str)
Set the term to filter on.
Definition stringfilter.cpp:29
StringFilter::ResetState
void ResetState()
Reset the matching state to process a new item.
Definition stringfilter.cpp:80
StringFilter::GetState
bool GetState() const
Get the matching state of the current item.
Definition stringfilter_type.h:67
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > >
Textbuf::DeleteAll
void DeleteAll()
Delete every character in the textbuffer.
Definition textbuf.cpp:112
Textbuf::GetText
std::string_view GetText() const
Get the current text.
Definition textbuf.cpp:284
Textbuf::Assign
void Assign(std::string_view text)
Copy a string into the textbuffer.
Definition textbuf.cpp:420
TownAuthorityWindow
Town authority window.
Definition town_gui.cpp:80
TownAuthorityWindow::OnInvalidateData
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Definition town_gui.cpp:322
TownAuthorityWindow::DrawActions
void DrawActions()
Draws the contents of the actions panel.
Definition town_gui.cpp:204
TownAuthorityWindow::icon_size
Dimension icon_size
Dimensions of company icon.
Definition town_gui.cpp:89
TownAuthorityWindow::OnInit
void OnInit() override
Notification that the nested widget tree gets initialized.
Definition town_gui.cpp:129
TownAuthorityWindow::DrawWidget
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
Definition town_gui.cpp:233
TownAuthorityWindow::UpdateWidgetSize
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
Definition town_gui.cpp:249
TownAuthorityWindow::town
Town * town
Town being displayed.
Definition town_gui.cpp:82
TownAuthorityWindow::enabled_actions
TownActions enabled_actions
Actions that are enabled in settings.
Definition town_gui.cpp:85
TownAuthorityWindow::sel_action
TownAction sel_action
Currently selected town action, TownAction::End means no action selected.
Definition town_gui.cpp:83
TownAuthorityWindow::available_actions
TownActions available_actions
Actions that are available to execute for the current company.
Definition town_gui.cpp:86
TownAuthorityWindow::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 town_gui.cpp:281
TownAuthorityWindow::DrawRatings
void DrawRatings()
Draw the contents of the ratings panel.
Definition town_gui.cpp:165
TownAuthorityWindow::redraw_interval
const IntervalTimer< TimerWindow > redraw_interval
Redraw the whole window on a regular interval.
Definition town_gui.cpp:318
TownAuthorityWindow::exclusive_size
Dimension exclusive_size
Dimensions of exclusive icon.
Definition town_gui.cpp:90
TownAuthorityWindow::GetWidgetString
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
Definition town_gui.cpp:226
TownAuthorityWindow::GetEnabledActions
static TownActions GetEnabledActions()
Gets all town authority actions enabled in settings.
Definition town_gui.cpp:97
TownAuthorityWindow::OnPaint
void OnPaint() override
The window must be repainted.
Definition town_gui.cpp:135
TownAuthorityWindow::displayed_actions_on_previous_painting
TownActions displayed_actions_on_previous_painting
Actions that were available on the previous call to OnPaint()
Definition town_gui.cpp:84
TownCache::population
uint32_t population
Current population of people.
Definition town.h:53
TownDirectoryWindow
Town directory window class.
Definition town_gui.cpp:718
TownDirectoryWindow::sorter_funcs
static const std::initializer_list< GUITownList::SortFunction *const > sorter_funcs
Available town directory sorting functions.
Definition town_gui.cpp:1038
TownDirectoryWindow::DrawWidget
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
Definition town_gui.cpp:844
TownDirectoryWindow::TownPopulationSorter
static bool TownPopulationSorter(const Town *const &a, const Town *const &b, const bool &order)
Sort by population (default descending, as big towns are of the most interest).
Definition town_gui.cpp:769
TownDirectoryWindow::townname_editbox
QueryString townname_editbox
Filter editbox.
Definition town_gui.cpp:732
TownDirectoryWindow::OnEditboxChanged
void OnEditboxChanged(WidgetID wid) override
The text in an editbox has been edited.
Definition town_gui.cpp:1000
TownDirectoryWindow::TownRatingSorter
static bool TownRatingSorter(const Town *const &a, const Town *const &b, const bool &order)
Sort by town rating.
Definition town_gui.cpp:778
TownDirectoryWindow::OnResize
void OnResize() override
Called after the window got resized.
Definition town_gui.cpp:995
TownDirectoryWindow::string_filter
StringFilter string_filter
Filter for towns.
Definition town_gui.cpp:731
TownDirectoryWindow::OnInvalidateData
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Definition town_gui.cpp:1013
TownDirectoryWindow::rebuild_interval
const IntervalTimer< TimerWindow > rebuild_interval
Redraw the whole window on a regular interval.
Definition town_gui.cpp:990
TownDirectoryWindow::OnPaint
void OnPaint() override
The window must be repainted.
Definition town_gui.cpp:983
TownDirectoryWindow::OnDropdownSelect
void OnDropdownSelect(WidgetID widget, int index, int) override
A dropdown option associated to this window has been selected.
Definition town_gui.cpp:972
TownDirectoryWindow::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 town_gui.cpp:935
TownDirectoryWindow::GetTownString
static std::string GetTownString(const Town *t, uint64_t population)
Get the string to draw the town name.
Definition town_gui.cpp:839
TownDirectoryWindow::TownNameSorter
static bool TownNameSorter(const Town *const &a, const Town *const &b, const bool &)
Sort by town name.
Definition town_gui.cpp:763
TownDirectoryWindow::UpdateWidgetSize
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
Definition town_gui.cpp:888
TownDirectoryWindow::GetWidgetString
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
Definition town_gui.cpp:817
TownNameParams
Struct holding parameters used to generate town name.
Definition townname_type.h:26
TownViewWindow
Definition town_gui.cpp:347
TownViewWindow::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 town_gui.cpp:475
TownViewWindow::town
Town * town
Town displayed by the window.
Definition town_gui.cpp:349
TownViewWindow::OnInvalidateData
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Definition town_gui.cpp:593
TownViewWindow::OnMouseWheel
void OnMouseWheel(int wheel, WidgetID widget) override
The mouse wheel has been turned.
Definition town_gui.cpp:580
TownViewWindow::UpdateWidgetSize
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
Definition town_gui.cpp:521
TownViewWindow::DrawWidget
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
Definition town_gui.cpp:391
TownViewWindow::GetDesiredInfoHeight
uint GetDesiredInfoHeight(int width) const
Gets the desired height for the information panel.
Definition town_gui.cpp:534
TownViewWindow::GetWidgetString
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
Definition town_gui.cpp:376
TownViewWindow::Close
void Close(int data=0) override
Hide the window and all its child windows, and mark them for a later deletion.
Definition town_gui.cpp:370
TownViewWindow::OnPaint
void OnPaint() override
The window must be repainted.
Definition town_gui.cpp:383
TownViewWindow::OnQueryTextFinished
void OnQueryTextFinished(std::optional< std::string > str) override
The query window opened from this window has closed.
Definition town_gui.cpp:601
TownViewWindow::OnResize
void OnResize() override
Called after the window got resized.
Definition town_gui.cpp:570
Town
Town data structure.
Definition town.h:63
Town::text
EncodedString text
General text with additional information.
Definition town.h:114
Town::larger_town
bool larger_town
if this is a larger town and should grow more quickly
Definition town.h:150
Town::xy
TileIndex xy
town center tile
Definition town.h:64
Town::fund_buildings_months
uint8_t fund_buildings_months
fund buildings program in action?
Definition town.h:147
Town::noise_reached
uint16_t noise_reached
level of noise that all the airports are generating
Definition town.h:77
Town::supplied
SuppliedCargoes supplied
Cargo statistics about supplied cargo.
Definition town.h:109
Town::flags
TownFlags flags
See TownFlags.
Definition town.h:75
Town::cache
TownCache cache
Container for all cacheable data.
Definition town.h:66
Town::exclusivity
CompanyID exclusivity
which company has exclusivity
Definition town.h:84
Town::show_zone
bool show_zone
NOSAVE: mark town to show the local authority zone in the viewports.
Definition town.h:153
Town::have_ratings
CompanyMask have_ratings
which companies have a rating
Definition town.h:82
Town::ratings
TypedIndexContainer< std::array< int16_t, MAX_COMPANIES >, CompanyID > ratings
ratings of each company for this town
Definition town.h:86
Town::growth_rate
uint16_t growth_rate
town growth rate
Definition town.h:145
Town::received
std::array< TransportedCargoStat< uint16_t >, NUM_TAE > received
Cargo statistics about received cargotypes.
Definition town.h:110
Town::goal
std::array< uint32_t, NUM_TAE > goal
Amount of cargo required for the town to grow.
Definition town.h:111
WindowDesc
High level window description.
Definition window_gui.h:168
WindowNumber
Number to differentiate different windows of the same class.
Definition window_type.h:760
Window
Data structure for an opened window.
Definition window_gui.h:274
Window::ReInit
void ReInit(int rx=0, int ry=0, bool reposition=false)
Re-initialize a window, and optionally change its size.
Definition window.cpp:980
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:1104
Window::SortButtonWidth
static int SortButtonWidth()
Get width of up/down arrow of sort button state.
Definition widget.cpp:833
Window::FinishInitNested
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition window.cpp:1809
Window::querystrings
std::map< WidgetID, QueryString * > querystrings
QueryString associated to WWT_EDITBOX widgets.
Definition window_gui.h:321
Window::DrawWidgets
void DrawWidgets() const
Paint all widgets of a window.
Definition widget.cpp:784
Window::InvalidateData
void InvalidateData(int data=0, bool gui_scope=true)
Mark this window's data as invalid (in need of re-computing)
Definition window.cpp:3237
Window::parent
Window * parent
Parent window.
Definition window_gui.h:329
Window::SetWidgetDirty
void SetWidgetDirty(WidgetID widget_index) const
Invalidate a widget, i.e.
Definition window.cpp:558
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:506
Window::DrawSortButtonState
void DrawSortButtonState(WidgetID widget, SortButtonState state) const
Draw a sort button's up or down arrow symbol.
Definition widget.cpp:816
Window::resize
ResizeInfo resize
Resize information.
Definition window_gui.h:315
Window::CreateNestedTree
void CreateNestedTree()
Perform the first part of the initialization of a nested widget tree.
Definition window.cpp:1799
Window::SetFocusedWidget
bool SetFocusedWidget(WidgetID widget_index)
Set focus within this window to the given widget.
Definition window.cpp:487
Window::IsWidgetLowered
bool IsWidgetLowered(WidgetID widget_index) const
Gets the lowered state of a widget.
Definition window_gui.h:492
Window::RaiseButtons
void RaiseButtons(bool autoraise=false)
Raise the buttons of the window.
Definition window.cpp:532
Window::SetWidgetLoweredState
void SetWidgetLoweredState(WidgetID widget_index, bool lowered_stat)
Sets the lowered/raised status of a widget.
Definition window_gui.h:442
Window::IsShaded
bool IsShaded() const
Is window shaded currently?
Definition window_gui.h:560
Window::GetRowFromWidget
int GetRowFromWidget(int clickpos, WidgetID widget, int padding, int line_height=-1) const
Compute the row of a widget that a user clicked in.
Definition window.cpp:212
Window::InitNested
void InitNested(WindowNumber number=0)
Perform complete initialization of the Window with nested widgets, to allow use.
Definition window.cpp:1823
Window::flags
WindowFlags flags
Window flags.
Definition window_gui.h:301
Window::GetScrollbar
const Scrollbar * GetScrollbar(WidgetID widnum) const
Return the Scrollbar to a widget index.
Definition window.cpp:315
Window::SetWidgetDisabledState
void SetWidgetDisabledState(WidgetID widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
Definition window_gui.h:382
Window::Iterate
AllWindows< false > Iterate
Iterate all windows in whatever order is easiest.
Definition window_gui.h:933
Window::width
int width
width of the window (number of pixels to the right in x direction)
Definition window_gui.h:312
Window::window_number
WindowNumber window_number
Window number within the window class.
Definition window_gui.h:303
QueryStringFlag::AcceptUnchanged
@ AcceptUnchanged
return success even when the text didn't change
QueryStringFlag::EnableDefault
@ EnableDefault
enable the 'Default' button ("\0" is returned)
QueryStringFlag::LengthIsInChars
@ LengthIsInChars
the length of the string is counted in characters
TileHeight
static uint TileHeight(Tile tile)
Returns the height of a tile.
Definition tile_map.h:29
GetTropicZone
TropicZone GetTropicZone(Tile tile)
Get the tropic zone.
Definition tile_map.h:238
TROPICZONE_DESERT
@ TROPICZONE_DESERT
Tile is desert.
Definition tile_type.h:78
INVALID_TILE
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:95
TILE_PIXELS
static constexpr uint TILE_PIXELS
Pixel distance between tile columns/rows in ZOOM_BASE.
Definition tile_type.h:17
tilehighlight_func.h
Functions related to tile highlights.
ResetObjectToPlace
void ResetObjectToPlace()
Reset the cursor and mouse mode handling back to default (normal cursor, only clicking in windows).
Definition viewport.cpp:3573
SetObjectToPlaceWnd
void SetObjectToPlaceWnd(CursorID icon, PaletteID pal, HighLightStyle mode, Window *w)
Change the cursor and mouse click/drag handling to a mode for performing special operations like tile...
Definition viewport.cpp:3510
HT_DIAGONAL
@ HT_DIAGONAL
Also allow 'diagonal rectangles'. Only usable in combination with HT_RECT or HT_POINT.
Definition tilehighlight_type.h:28
HT_RECT
@ HT_RECT
rectangle (stations, depots, ...)
Definition tilehighlight_type.h:21
timer.h
Definition of Interval and OneShot timers.
timer_game_calendar.h
Definition of the game-calendar-timer.
timer_window.h
Definition of the Window system.
town.h
Base of the town class.
TOWN_GROWTH_WINTER
static const uint TOWN_GROWTH_WINTER
The town only needs this cargo in the winter (any amount)
Definition town.h:32
GetDefaultTownsForMapSize
uint GetDefaultTownsForMapSize()
Calculate the number of towns which should be on the map according to the current "town density" newg...
Definition town_cmd.cpp:2432
GetMaskOfTownActions
TownActions GetMaskOfTownActions(CompanyID cid, const Town *t)
Get a list of available town authority actions.
Definition town_cmd.cpp:3672
FindFirstCargoWithTownAcceptanceEffect
const CargoSpec * FindFirstCargoWithTownAcceptanceEffect(TownAcceptanceEffect effect)
Determines the first cargo with a certain town effect.
Definition town_cmd.cpp:3127
TOWN_GROWTH_DESERT
static const uint TOWN_GROWTH_DESERT
The town needs the cargo for growth when on desert (any amount)
Definition town.h:33
GenerateTowns
bool GenerateTowns(TownLayout layout, std::optional< uint > number=std::nullopt)
Generate a number of towns with a given layout.
Definition town_cmd.cpp:2448
GetWorldPopulation
uint32_t GetWorldPopulation()
Get the total population, the sum of all towns in the world.
Definition town_cmd.cpp:457
GetAcceptedCargoOfHouse
CargoArray GetAcceptedCargoOfHouse(const HouseSpec *hs)
Get accepted cargo of a house prototype.
Definition town_cmd.cpp:858
GetTownActionCost
uint8_t GetTownActionCost(TownAction action)
Get cost factors for a TownAction.
Definition town_cmd.cpp:3391
TownAction
TownAction
Town actions of a company.
Definition town.h:247
TownAction::RoadRebuild
@ RoadRebuild
Rebuild the roads.
TownAction::Bribe
@ Bribe
Try to bribe the council.
TownAction::BuyRights
@ BuyRights
Buy exclusive transport rights.
TownAction::FundBuildings
@ FundBuildings
Fund new buildings.
TownFlag::IsGrowing
@ IsGrowing
Conditions for town growth are met. Grow according to Town::growth_rate.
town_cmd.h
Command definitions related to towns.
DrawHouseInGUI
void DrawHouseInGUI(int x, int y, HouseID house_id, int view)
Draw a house that does not exist.
Definition town_gui.cpp:1370
GetHouseName
static StringID GetHouseName(const HouseSpec *hs)
Get name for a prototype house.
Definition town_gui.cpp:1424
GetProducedCargoOfHouse
static CargoTypes GetProducedCargoOfHouse(const HouseSpec *hs)
Get the cargo types produced by a house.
Definition town_gui.cpp:1620
_nested_build_house_widgets
static constexpr std::initializer_list< NWidgetPart > _nested_build_house_widgets
Nested widget definition for the build NewGRF rail waypoint window.
Definition town_gui.cpp:1817
town_kdtree.h
Declarations for accessing the k-d tree of towns.
TownLayout
TownLayout
Town Layouts.
Definition town_type.h:81
TF_CUSTOM_LAYOUT
@ TF_CUSTOM_LAYOUT
Allowed, with custom town layout.
Definition town_type.h:107
TownSize
TownSize
Supported initial town sizes.
Definition town_type.h:21
TSZ_MEDIUM
@ TSZ_MEDIUM
Medium town.
Definition town_type.h:23
MAX_LENGTH_TOWN_NAME_CHARS
static const uint MAX_LENGTH_TOWN_NAME_CHARS
The maximum length of a town name in characters including '\0'.
Definition town_type.h:119
TownExpandMode::Roads
@ Roads
Allow town to place roads.
TownExpandMode::Buildings
@ Buildings
Allow town to place buildings.
town_widget.h
Types related to the town widgets.
WID_TA_EXECUTE
@ WID_TA_EXECUTE
Do-it button.
Definition town_widget.h:32
WID_TA_ACTION_INFO
@ WID_TA_ACTION_INFO
Additional information about the action.
Definition town_widget.h:31
WID_TA_RATING_INFO
@ WID_TA_RATING_INFO
Overview with ratings for each company.
Definition town_widget.h:28
WID_TA_CAPTION
@ WID_TA_CAPTION
Caption of window.
Definition town_widget.h:26
WID_TA_ZONE_BUTTON
@ WID_TA_ZONE_BUTTON
Turn on/off showing local authority zone.
Definition town_widget.h:27
WID_TA_COMMAND_LIST
@ WID_TA_COMMAND_LIST
List of commands for the player.
Definition town_widget.h:29
WID_TV_VIEWPORT
@ WID_TV_VIEWPORT
View of the center of the town.
Definition town_widget.h:38
WID_TV_EXPAND_BUILDINGS
@ WID_TV_EXPAND_BUILDINGS
Expand number of buildings this town (scenario editor only).
Definition town_widget.h:45
WID_TV_INFO
@ WID_TV_INFO
General information about the town.
Definition town_widget.h:39
WID_TV_EXPAND
@ WID_TV_EXPAND
Expand this town (scenario editor only).
Definition town_widget.h:44
WID_TV_CATCHMENT
@ WID_TV_CATCHMENT
Toggle catchment area highlight.
Definition town_widget.h:43
WID_TV_SHOW_AUTHORITY
@ WID_TV_SHOW_AUTHORITY
Show the town authority window.
Definition town_widget.h:41
WID_TV_CHANGE_NAME
@ WID_TV_CHANGE_NAME
Change the name of this town.
Definition town_widget.h:42
WID_TV_CENTER_VIEW
@ WID_TV_CENTER_VIEW
Center the main view on this town.
Definition town_widget.h:40
WID_TV_DELETE
@ WID_TV_DELETE
Delete this town (scenario editor only).
Definition town_widget.h:47
WID_TV_EXPAND_ROADS
@ WID_TV_EXPAND_ROADS
Expand roads of this town (scenario editor only).
Definition town_widget.h:46
WID_TV_CAPTION
@ WID_TV_CAPTION
Caption of window.
Definition town_widget.h:37
WID_TF_LAYOUT_RANDOM
@ WID_TF_LAYOUT_RANDOM
Selection for a randomly chosen town layout.
Definition town_widget.h:72
WID_TF_LOAD_FROM_FILE
@ WID_TF_LOAD_FROM_FILE
Load town data from file.
Definition town_widget.h:57
WID_TF_SIZE_SEL
@ WID_TF_SIZE_SEL
Container of town size buttons.
Definition town_widget.h:61
WID_TF_SIZE_LARGE
@ WID_TF_SIZE_LARGE
Selection for a large town.
Definition town_widget.h:64
WID_TF_NEW_TOWN
@ WID_TF_NEW_TOWN
Create a new town.
Definition town_widget.h:53
WID_TF_EXPAND_ALL_TOWNS
@ WID_TF_EXPAND_ALL_TOWNS
Make all towns grow slightly.
Definition town_widget.h:58
WID_TF_MANY_RANDOM_TOWNS
@ WID_TF_MANY_RANDOM_TOWNS
Randomly place many towns.
Definition town_widget.h:56
WID_TF_SIZE_SMALL
@ WID_TF_SIZE_SMALL
Selection for a small town.
Definition town_widget.h:62
WID_TF_EXPAND_BUILDINGS
@ WID_TF_EXPAND_BUILDINGS
Expand buildings toggle.
Definition town_widget.h:74
WID_TF_LAYOUT_GRID2
@ WID_TF_LAYOUT_GRID2
Selection for the 2x2 grid town layout.
Definition town_widget.h:70
WID_TF_LAYOUT_ORIGINAL
@ WID_TF_LAYOUT_ORIGINAL
Selection for the original town layout.
Definition town_widget.h:68
WID_TF_SIZE_RANDOM
@ WID_TF_SIZE_RANDOM
Selection for a randomly sized town.
Definition town_widget.h:65
WID_TF_TOWN_NAME_EDITBOX
@ WID_TF_TOWN_NAME_EDITBOX
Editor for the town name.
Definition town_widget.h:59
WID_TF_TOWN_ACTION_SEL
@ WID_TF_TOWN_ACTION_SEL
Container of town action buttons.
Definition town_widget.h:54
WID_TF_SIZE_MEDIUM
@ WID_TF_SIZE_MEDIUM
Selection for a medium town.
Definition town_widget.h:63
WID_TF_TOWN_EXPAND_SEL
@ WID_TF_TOWN_EXPAND_SEL
Container of town expansion buttons.
Definition town_widget.h:73
WID_TF_EXPAND_ROADS
@ WID_TF_EXPAND_ROADS
Expand roads toggle.
Definition town_widget.h:75
WID_TF_CITY
@ WID_TF_CITY
Selection for the town's city state.
Definition town_widget.h:66
WID_TF_RANDOM_TOWN
@ WID_TF_RANDOM_TOWN
Randomly place a town.
Definition town_widget.h:55
WID_TF_LAYOUT_BETTER
@ WID_TF_LAYOUT_BETTER
Selection for the better town layout.
Definition town_widget.h:69
WID_TF_ROAD_LAYOUT_SEL
@ WID_TF_ROAD_LAYOUT_SEL
Container of town road layout buttons.
Definition town_widget.h:67
WID_TF_LAYOUT_GRID3
@ WID_TF_LAYOUT_GRID3
Selection for the 3x3 grid town layout.
Definition town_widget.h:71
WID_TF_TOWN_NAME_RANDOM
@ WID_TF_TOWN_NAME_RANDOM
Generate a random town name.
Definition town_widget.h:60
WID_TD_LIST
@ WID_TD_LIST
List of towns.
Definition town_widget.h:19
WID_TD_CAPTION
@ WID_TD_CAPTION
Caption of the window.
Definition town_widget.h:15
WID_TD_FILTER
@ WID_TD_FILTER
Filter of name.
Definition town_widget.h:18
WID_TD_SORT_ORDER
@ WID_TD_SORT_ORDER
Direction of sort dropdown.
Definition town_widget.h:16
WID_TD_WORLD_POPULATION
@ WID_TD_WORLD_POPULATION
The world's population.
Definition town_widget.h:21
WID_TD_SCROLLBAR
@ WID_TD_SCROLLBAR
Scrollbar for the town list.
Definition town_widget.h:20
WID_TD_SORT_CRITERIA
@ WID_TD_SORT_CRITERIA
Criteria of sort dropdown.
Definition town_widget.h:17
WID_BH_REPLACE_TOGGLE
@ WID_BH_REPLACE_TOGGLE
Button to toggle replacing existing houses.
Definition town_widget.h:82
WID_BH_PROTECT_TOGGLE
@ WID_BH_PROTECT_TOGGLE
Button to toggle protecting the next house built.
Definition town_widget.h:81
WID_BH_INFO
@ WID_BH_INFO
Information panel of selected house.
Definition town_widget.h:80
GenerateTownName
bool GenerateTownName(Randomizer &randomizer, uint32_t *townnameparts, TownNames *town_names)
Generates valid town name.
Definition townname.cpp:136
townname_func.h
Town name generator stuff.
ScrollWindowToTile
bool ScrollWindowToTile(TileIndex tile, Window *w, bool instant)
Scrolls the viewport in a window to a given location.
Definition viewport.cpp:2581
SetTileSelectSize
void SetTileSelectSize(int w, int h)
Highlight w by h tiles at the cursor.
Definition viewport.cpp:2619
ScrollMainWindowToTile
bool ScrollMainWindowToTile(TileIndex tile, bool instant)
Scrolls the viewport of the main window to a given location.
Definition viewport.cpp:2592
SetViewportCatchmentTown
void SetViewportCatchmentTown(const Town *t, bool sel)
Select or deselect town for coverage area highlight.
Definition viewport.cpp:3805
_viewport_highlight_town
const Town * _viewport_highlight_town
Currently selected town for coverage area highlight.
Definition viewport.cpp:1015
viewport_func.h
Functions related to (drawing on) viewports.
ZOOM_IN
@ ZOOM_IN
Zoom in (get more detailed view).
Definition viewport_type.h:81
ZOOM_OUT
@ ZOOM_OUT
Zoom out (get helicopter view).
Definition viewport_type.h:82
WWT_PUSHTXTBTN
@ WWT_PUSHTXTBTN
Normal push-button (no toggle button) with text caption.
Definition widget_type.h:105
WWT_INSET
@ WWT_INSET
Pressed (inset) panel, most commonly used as combo box text area.
Definition widget_type.h:40
WWT_PUSHIMGBTN
@ WWT_PUSHIMGBTN
Normal push-button (no toggle button) with image caption.
Definition widget_type.h:106
WWT_LABEL
@ WWT_LABEL
Centered label.
Definition widget_type.h:48
WWT_EDITBOX
@ WWT_EDITBOX
a textbox for typing
Definition widget_type.h:62
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_VSCROLLBAR
@ NWID_VSCROLLBAR
Vertical scrollbar.
Definition widget_type.h:76
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_VIEWPORT
@ NWID_VIEWPORT
Nested widget containing a viewport.
Definition widget_type.h:73
WWT_DROPDOWN
@ WWT_DROPDOWN
Drop down list.
Definition widget_type.h:61
WWT_TEXT
@ WWT_TEXT
Pure simple text.
Definition widget_type.h:49
NWID_SELECTION
@ NWID_SELECTION
Stacked widgets, only one visible at a time (eg in a panel with tabs).
Definition widget_type.h:71
SZSP_HORIZONTAL
@ SZSP_HORIZONTAL
Display plane with zero size vertically, and filling and resizing horizontally.
Definition widget_type.h:508
SZSP_VERTICAL
@ SZSP_VERTICAL
Display plane with zero size horizontally, and filling and resizing vertically.
Definition widget_type.h:507
EqualSize
@ EqualSize
Containers should keep all their (resizing) children equally large.
Definition widget_type.h:544
ResizeWindow
void ResizeWindow(Window *w, int delta_x, int delta_y, bool clamp_to_screen, bool schedule_resize)
Resize the window.
Definition window.cpp:2099
BringWindowToFrontById
Window * BringWindowToFrontById(WindowClass cls, WindowNumber number)
Find a window and make it the relative top-window on the screen.
Definition window.cpp:1278
window_func.h
Window functions not directly related to making/drawing windows.
WindowDefaultFlag::Construction
@ Construction
This window is used for construction; close it whenever changing company.
WindowFlag::DisableVpScroll
@ DisableVpScroll
Window does not do autoscroll,.
SBS_DOWN
@ SBS_DOWN
Sort ascending.
Definition window_gui.h:219
SBS_UP
@ SBS_UP
Sort descending.
Definition window_gui.h:220
WDP_AUTO
@ WDP_AUTO
Find a place automatically.
Definition window_gui.h:144
WidgetID
int WidgetID
Widget ID.
Definition window_type.h:20
WC_TOWN_AUTHORITY
@ WC_TOWN_AUTHORITY
Town authority; Window numbers:
Definition window_type.h:199
WC_FOUND_TOWN
@ WC_FOUND_TOWN
Found a town; Window numbers:
Definition window_type.h:440
WC_BUILD_HOUSE
@ WC_BUILD_HOUSE
Build house; Window numbers:
Definition window_type.h:387
WC_BUILD_TOOLBAR
@ WC_BUILD_TOOLBAR
Build toolbar; Window numbers:
Definition window_type.h:78
WC_NONE
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
Definition window_type.h:50
WC_TOWN_VIEW
@ WC_TOWN_VIEW
Town view; Window numbers:
Definition window_type.h:338
WC_TOWN_DIRECTORY
@ WC_TOWN_DIRECTORY
Town directory; Window numbers:
Definition window_type.h:259
zoom_func.h
Functions related to zooming.
ScaleSpriteTrad
int ScaleSpriteTrad(int value)
Scale traditional pixel dimensions to GUI zoom level, for drawing sprites.
Definition zoom_func.h:107
ScaleZoomGUI
ZoomLevel ScaleZoomGUI(ZoomLevel value)
Scale zoom level relative to GUI zoom.
Definition zoom_func.h:87
UnScaleGUI
int UnScaleGUI(int value)
Short-hand to apply GUI zoom level.
Definition zoom_func.h:77
ZoomLevel::Town
@ Town
Default zoom level for the town view.