OpenTTD Source: src/town_cmd.cpp Source File

OpenTTD Source 15.3

town_cmd.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
10#include "stdafx.h"
11#include "misc/history_type.hpp"
12#include "misc/history_func.hpp"
13#include "road.h"
14#include "road_internal.h" /* Cleaning up road bits */
15#include "road_cmd.h"
16#include "landscape.h"
17#include "viewport_func.h"
18#include "viewport_kdtree.h"
19#include "command_func.h"
20#include "company_func.h"
21#include "industry.h"
22#include "station_base.h"
23#include "waypoint_base.h"
24#include "station_kdtree.h"
25#include "company_base.h"
26#include "news_func.h"
27#include "error.h"
28#include "object.h"
29#include "genworld.h"
30#include "newgrf_debug.h"
31#include "newgrf_house.h"
32#include "newgrf_text.h"
33#include "autoslope.h"
34#include "tunnelbridge_map.h"
35#include "strings_func.h"
36#include "window_func.h"
37#include "string_func.h"
38#include "newgrf_cargo.h"
39#include "cheat_type.h"
40#include "animated_tile_func.h"
41#include "subsidy_func.h"
42#include "core/pool_func.hpp"
43#include "town.h"
44#include "town_kdtree.h"
45#include "townname_func.h"
46#include "core/random_func.hpp"
47#include "core/backup_type.hpp"
48#include "depot_base.h"
49#include "object_map.h"
50#include "object_base.h"
51#include "ai/ai.hpp"
52#include "game/game.hpp"
53#include "town_cmd.h"
54#include "landscape_cmd.h"
55#include "road_cmd.h"
56#include "terraform_cmd.h"
57#include "tunnelbridge_cmd.h"
58#include "clear_map.h"
59#include "tree_map.h"
60#include "map_func.h"
61#include "timer/timer.h"
62#include "timer/timer_game_calendar.h"
63#include "timer/timer_game_economy.h"
64#include "timer/timer_game_tick.h"
65
66#include "table/strings.h"
67#include "table/town_land.h"
68
69#include "safeguards.h"
70
71/* Initialize the town-pool */
72 TownPool _town_pool("Town");
73 INSTANTIATE_POOL_METHODS(Town)
74
75
76 TownKdtree _town_kdtree{};
77
78void RebuildTownKdtree()
79{
80 std::vector<TownID> townids;
81 for (const Town *town : Town::Iterate()) {
82 townids.push_back(town->index);
83 }
84 _town_kdtree.Build(townids.begin(), townids.end());
85}
86
88 static bool _generating_town = false;
89
99 static bool TestTownOwnsBridge(TileIndex tile, const Town *t)
100{
101 if (!IsTileOwner(tile, OWNER_TOWN)) return false;
102
103 TileIndex adjacent = tile + TileOffsByDiagDir(ReverseDiagDir(GetTunnelBridgeDirection(tile)));
104 bool town_owned = IsTileType(adjacent, MP_ROAD) && IsTileOwner(adjacent, OWNER_TOWN) && GetTownIndex(adjacent) == t->index;
105
106 if (!town_owned) {
107 /* Or other adjacent road */
108 adjacent = tile + TileOffsByDiagDir(ReverseDiagDir(GetTunnelBridgeDirection(GetOtherTunnelBridgeEnd(tile))));
109 town_owned = IsTileType(adjacent, MP_ROAD) && IsTileOwner(adjacent, OWNER_TOWN) && GetTownIndex(adjacent) == t->index;
110 }
111
112 return town_owned;
113}
114
115Town::~Town()
116{
117 if (CleaningPool()) return;
118
119 /* Delete town authority window
120 * and remove from list of sorted towns */
121 CloseWindowById(WC_TOWN_VIEW, this->index);
122 CloseWindowById(WC_TOWN_CARGO_GRAPH, this->index);
123
124#ifdef WITH_ASSERT
125 /* Check no industry is related to us. */
126 for (const Industry *i : Industry::Iterate()) {
127 assert(i->town != this);
128 }
129
130 /* ... and no object is related to us. */
131 for (const Object *o : Object::Iterate()) {
132 assert(o->town != this);
133 }
134
135 /* Check no tile is related to us. */
136 for (const auto tile : Map::Iterate()) {
137 switch (GetTileType(tile)) {
138 case MP_HOUSE:
139 assert(GetTownIndex(tile) != this->index);
140 break;
141
142 case MP_ROAD:
143 assert(!HasTownOwnedRoad(tile) || GetTownIndex(tile) != this->index);
144 break;
145
146 case MP_TUNNELBRIDGE:
147 assert(!TestTownOwnsBridge(tile, this));
148 break;
149
150 default:
151 break;
152 }
153 }
154#endif /* WITH_ASSERT */
155
156 /* Clear the persistent storage list. */
157 for (auto &psa : this->psa_list) {
158 delete psa;
159 }
160 this->psa_list.clear();
161
162 Source src{this->index, SourceType::Town};
163 DeleteSubsidyWith(src);
164 DeleteNewGRFInspectWindow(GSF_FAKE_TOWNS, this->index);
165 CargoPacket::InvalidateAllFrom(src);
166 MarkWholeScreenDirty();
167}
168
169
174 void Town::PostDestructor(size_t)
175{
176 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_REBUILD);
177 UpdateNearestTownForRoadTiles(false);
178
179 /* Give objects a new home! */
180 for (Object *o : Object::Iterate()) {
181 if (o->town == nullptr) o->town = CalcClosestTownFromTile(o->location.tile, UINT_MAX);
182 }
183}
184
189 void Town::InitializeLayout(TownLayout layout)
190{
191 if (layout != TL_RANDOM) {
192 this->layout = layout;
193 return;
194 }
195
196 this->layout = static_cast<TownLayout>(TileHash(TileX(this->xy), TileY(this->xy)) % (NUM_TLS - 1));
197}
198
203/* static */ Town *Town::GetRandom()
204{
205 if (Town::GetNumItems() == 0) return nullptr;
206 int num = RandomRange((uint16_t)Town::GetNumItems());
207 size_t index = std::numeric_limits<size_t>::max();
208
209 while (num >= 0) {
210 num--;
211 index++;
212
213 /* Make sure we have a valid town */
214 while (!Town::IsValidID(index)) {
215 index++;
216 assert(index < Town::GetPoolSize());
217 }
218 }
219
220 return Town::Get(index);
221}
222
223void Town::FillCachedName() const
224{
225 this->cached_name = GetTownName(this);
226}
227
232 Money HouseSpec::GetRemovalCost() const
233{
234 return (_price[PR_CLEAR_HOUSE] * this->removal_cost) >> 8;
235}
236
237static bool TryBuildTownHouse(Town *t, TileIndex tile, TownExpandModes modes);
238static Town *CreateRandomTown(uint attempts, uint32_t townnameparts, TownSize size, bool city, TownLayout layout);
239
240static void TownDrawHouseLift(const TileInfo *ti)
241{
242 AddChildSpriteScreen(SPR_LIFT, PAL_NONE, 14, 60 - GetLiftPosition(ti->tile));
243}
244
245typedef void TownDrawTileProc(const TileInfo *ti);
246static TownDrawTileProc * const _town_draw_tile_procs[1] = {
247 TownDrawHouseLift
248};
249
255 static inline DiagDirection RandomDiagDir()
256{
257 return (DiagDirection)(RandomRange(DIAGDIR_END));
258}
259
264 static void DrawTile_Town(TileInfo *ti)
265{
266 HouseID house_id = GetHouseType(ti->tile);
267
268 if (house_id >= NEW_HOUSE_OFFSET) {
269 /* Houses don't necessarily need new graphics. If they don't have a
270 * spritegroup associated with them, then the sprite for the substitute
271 * house id is drawn instead. */
272 if (HouseSpec::Get(house_id)->grf_prop.HasSpriteGroups()) {
273 DrawNewHouseTile(ti, house_id);
274 return;
275 } else {
276 house_id = HouseSpec::Get(house_id)->grf_prop.subst_id;
277 }
278 }
279
280 /* Retrieve pointer to the draw town tile struct */
281 const DrawBuildingsTileStruct *dcts = &_town_draw_tile_data[house_id << 4 | TileHash2Bit(ti->x, ti->y) << 2 | GetHouseBuildingStage(ti->tile)];
282
283 if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
284
285 DrawGroundSprite(dcts->ground.sprite, dcts->ground.pal);
286
287 /* If houses are invisible, do not draw the upper part */
288 if (IsInvisibilitySet(TO_HOUSES)) return;
289
290 /* Add a house on top of the ground? */
291 SpriteID image = dcts->building.sprite;
292 if (image != 0) {
293 AddSortableSpriteToDraw(image, dcts->building.pal, *ti, *dcts, IsTransparencySet(TO_HOUSES));
294
295 if (IsTransparencySet(TO_HOUSES)) return;
296 }
297
298 {
299 int proc = dcts->draw_proc - 1;
300
301 if (proc >= 0) _town_draw_tile_procs[proc](ti);
302 }
303}
304
305static int GetSlopePixelZ_Town(TileIndex tile, uint, uint, bool)
306{
307 return GetTileMaxPixelZ(tile);
308}
309
315 static Foundation GetFoundation_Town(TileIndex tile, Slope tileh)
316{
317 HouseID hid = GetHouseType(tile);
318
319 /* For NewGRF house tiles we might not be drawing a foundation. We need to
320 * account for this, as other structures should
321 * draw the wall of the foundation in this case.
322 */
323 if (hid >= NEW_HOUSE_OFFSET) {
324 const HouseSpec *hs = HouseSpec::Get(hid);
325 if (hs->callback_mask.Test(HouseCallbackMask::DrawFoundations)) {
326 uint32_t callback_res = GetHouseCallback(CBID_HOUSE_DRAW_FOUNDATIONS, 0, 0, hid, Town::GetByTile(tile), tile);
327 if (callback_res != CALLBACK_FAILED && !ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DRAW_FOUNDATIONS, callback_res)) return FOUNDATION_NONE;
328 }
329 }
330 return FlatteningFoundation(tileh);
331}
332
339 static void AnimateTile_Town(TileIndex tile)
340{
341 if (GetHouseType(tile) >= NEW_HOUSE_OFFSET) {
342 AnimateNewHouseTile(tile);
343 return;
344 }
345
346 if (TimerGameTick::counter & 3) return;
347
348 /* If the house is not one with a lift anymore, then stop this animating.
349 * Not exactly sure when this happens, but probably when a house changes.
350 * Before this was just a return...so it'd leak animated tiles..
351 * That bug seems to have been here since day 1?? */
352 if (!HouseSpec::Get(GetHouseType(tile))->building_flags.Test(BuildingFlag::IsAnimated)) {
353 DeleteAnimatedTile(tile);
354 return;
355 }
356
357 if (!LiftHasDestination(tile)) {
358 uint i;
359
360 /* Building has 6 floors, number 0 .. 6, where 1 is illegal.
361 * This is due to the fact that the first floor is, in the graphics,
362 * the height of 2 'normal' floors.
363 * Furthermore, there are 6 lift positions from floor N (incl) to floor N + 1 (excl) */
364 do {
365 i = RandomRange(7);
366 } while (i == 1 || i * 6 == GetLiftPosition(tile));
367
368 SetLiftDestination(tile, i);
369 }
370
371 int pos = GetLiftPosition(tile);
372 int dest = GetLiftDestination(tile) * 6;
373 pos += (pos < dest) ? 1 : -1;
374 SetLiftPosition(tile, pos);
375
376 if (pos == dest) {
377 HaltLift(tile);
378 DeleteAnimatedTile(tile);
379 }
380
381 MarkTileDirtyByTile(tile);
382}
383
390 static bool IsCloseToTown(TileIndex tile, uint dist)
391{
392 if (_town_kdtree.Count() == 0) return false;
393 Town *t = Town::Get(_town_kdtree.FindNearest(TileX(tile), TileY(tile)));
394 return DistanceManhattan(tile, t->xy) < dist;
395}
396
398 void Town::UpdateVirtCoord()
399{
400 Point pt = RemapCoords2(TileX(this->xy) * TILE_SIZE, TileY(this->xy) * TILE_SIZE);
401
402 if (this->cache.sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeTown(this->index));
403
404 std::string town_string;
405 if (this->larger_town) {
406 town_string = GetString(_settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_CITY_POP : STR_VIEWPORT_TOWN_CITY, this->index, this->cache.population);
407 } else {
408 town_string = GetString(_settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_POP : STR_TOWN_NAME, this->index, this->cache.population);
409 }
410
411 this->cache.sign.UpdatePosition(pt.x, pt.y - 24 * ZOOM_BASE,
412 town_string,
413 GetString(STR_TOWN_NAME, this->index, this->cache.population)
414);
415
416 _viewport_sign_kdtree.Insert(ViewportSignKdtreeItem::MakeTown(this->index));
417
418 SetWindowDirty(WC_TOWN_VIEW, this->index);
419}
420
422 void UpdateAllTownVirtCoords()
423{
424 for (Town *t : Town::Iterate()) {
425 t->UpdateVirtCoord();
426 }
427}
428
430 void ClearAllTownCachedNames()
431{
432 for (Town *t : Town::Iterate()) {
433 t->cached_name.clear();
434 }
435}
436
442 static void ChangePopulation(Town *t, int mod)
443{
444 t->cache.population += mod;
445 if (_generating_town) [[unlikely]] return;
446
447 InvalidateWindowData(WC_TOWN_VIEW, t->index); // Cargo requirements may appear/vanish for small populations
448 if (_settings_client.gui.population_in_label) t->UpdateVirtCoord();
449
450 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_POPULATION_CHANGE);
451}
452
457uint32_t GetWorldPopulation()
458{
459 uint32_t pop = 0;
460 for (const Town *t : Town::Iterate()) pop += t->cache.population;
461 return pop;
462}
463
471 static void RemoveNearbyStations(Town *t, TileIndex tile, BuildingFlags flags)
472{
473 for (StationList::iterator it = t->stations_near.begin(); it != t->stations_near.end(); /* incremented inside loop */) {
474 const Station *st = *it;
475
476 bool covers_area = st->TileIsInCatchment(tile);
477 if (flags.Any(BUILDING_2_TILES_Y)) covers_area |= st->TileIsInCatchment(tile + TileDiffXY(0, 1));
478 if (flags.Any(BUILDING_2_TILES_X)) covers_area |= st->TileIsInCatchment(tile + TileDiffXY(1, 0));
479 if (flags.Any(BUILDING_HAS_4_TILES)) covers_area |= st->TileIsInCatchment(tile + TileDiffXY(1, 1));
480
481 if (covers_area && !st->CatchmentCoversTown(t->index)) {
482 it = t->stations_near.erase(it);
483 } else {
484 ++it;
485 }
486 }
487}
488
493 static void AdvanceSingleHouseConstruction(TileIndex tile)
494{
495 assert(IsTileType(tile, MP_HOUSE));
496
497 /* Progress in construction stages */
498 IncHouseConstructionTick(tile);
499 if (GetHouseConstructionTick(tile) != 0) return;
500
501 TriggerHouseAnimation_ConstructionStageChanged(tile, false);
502
503 if (IsHouseCompleted(tile)) {
504 /* Now that construction is complete, we can add the population of the
505 * building to the town. */
506 ChangePopulation(Town::GetByTile(tile), HouseSpec::Get(GetHouseType(tile))->population);
507 ResetHouseAge(tile);
508 }
509 MarkTileDirtyByTile(tile);
510}
511
516 static void AdvanceHouseConstruction(TileIndex tile)
517{
518 BuildingFlags flags = HouseSpec::Get(GetHouseType(tile))->building_flags;
519 if (flags.Any(BUILDING_HAS_1_TILE)) AdvanceSingleHouseConstruction(TileAddXY(tile, 0, 0));
520 if (flags.Any(BUILDING_2_TILES_Y)) AdvanceSingleHouseConstruction(TileAddXY(tile, 0, 1));
521 if (flags.Any(BUILDING_2_TILES_X)) AdvanceSingleHouseConstruction(TileAddXY(tile, 1, 0));
522 if (flags.Any(BUILDING_HAS_4_TILES)) AdvanceSingleHouseConstruction(TileAddXY(tile, 1, 1));
523}
524
533 static void TownGenerateCargo(Town *t, CargoType cargo, uint amount, StationFinder &stations, bool affected_by_recession)
534{
535 if (amount == 0) return;
536
537 /* All production is halved during a recession (except for NewGRF-supplied town cargo). */
538 if (affected_by_recession && EconomyIsInRecession()) {
539 amount = (amount + 1) >> 1;
540 }
541
542 /* Scale by cargo scale setting. */
543 amount = ScaleByCargoScale(amount, true);
544 if (amount == 0) return;
545
546 /* Actually generate cargo and update town statistics. */
547 auto &supplied = t->GetOrCreateCargoSupplied(cargo);
548 supplied.history[THIS_MONTH].production += amount;
549 supplied.history[THIS_MONTH].transported += MoveGoodsToStation(cargo, amount, {t->index, SourceType::Town}, stations.GetStations());;
550}
551
559 static void TownGenerateCargoOriginal(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
560{
561 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[tpe]) {
562 uint32_t r = Random();
563 if (GB(r, 0, 8) < rate) {
564 CargoType cargo_type = cs->Index();
565 uint amt = (GB(r, 0, 8) * cs->town_production_multiplier / TOWN_PRODUCTION_DIVISOR) / 8 + 1;
566
567 TownGenerateCargo(t, cargo_type, amt, stations, true);
568 }
569 }
570}
571
579 static void TownGenerateCargoBinomial(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
580{
581 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[tpe]) {
582 CargoType cargo_type = cs->Index();
583 uint32_t r = Random();
584
585 /* Make a bitmask with up to 32 bits set, one for each potential pax. */
586 int genmax = (rate + 7) / 8;
587 uint32_t genmask = (genmax >= 32) ? 0xFFFFFFFF : ((1 << genmax) - 1);
588
589 /* Mask random value by potential pax and count number of actual pax. */
590 uint amt = CountBits(r & genmask) * cs->town_production_multiplier / TOWN_PRODUCTION_DIVISOR;
591
592 TownGenerateCargo(t, cargo_type, amt, stations, true);
593 }
594}
595
602 static void TileLoop_Town(TileIndex tile)
603{
604 HouseID house_id = GetHouseType(tile);
605
606 /* NewHouseTileLoop returns false if Callback 21 succeeded, i.e. the house
607 * doesn't exist any more, so don't continue here. */
608 if (house_id >= NEW_HOUSE_OFFSET && !NewHouseTileLoop(tile)) return;
609
610 if (!IsHouseCompleted(tile)) {
611 /* Construction is not completed, so we advance a construction stage. */
612 AdvanceHouseConstruction(tile);
613 return;
614 }
615
616 const HouseSpec *hs = HouseSpec::Get(house_id);
617
618 /* If the lift has a destination, it is already an animated tile. */
619 if (hs->building_flags.Test(BuildingFlag::IsAnimated) &&
620 house_id < NEW_HOUSE_OFFSET &&
621 !LiftHasDestination(tile) &&
622 Chance16(1, 2)) {
623 AddAnimatedTile(tile);
624 }
625
626 Town *t = Town::GetByTile(tile);
627 uint32_t r = Random();
628
629 StationFinder stations(TileArea(tile, 1, 1));
630
631 if (hs->callback_mask.Test(HouseCallbackMask::ProduceCargo)) {
632 for (uint i = 0; i < 256; i++) {
633 uint16_t callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, r, house_id, t, tile);
634
635 if (callback == CALLBACK_FAILED || callback == CALLBACK_HOUSEPRODCARGO_END) break;
636
637 CargoType cargo = GetCargoTranslation(GB(callback, 8, 7), hs->grf_prop.grffile);
638 if (!IsValidCargoType(cargo)) continue;
639
640 uint amt = GB(callback, 0, 8);
641 if (amt == 0) continue;
642
643 /* NewGRF-supplied town cargos are not affected by recessions. */
644 TownGenerateCargo(t, cargo, amt, stations, false);
645 }
646 } else {
647 switch (_settings_game.economy.town_cargogen_mode) {
648 case TCGM_ORIGINAL:
649 /* Original (quadratic) cargo generation algorithm */
650 TownGenerateCargoOriginal(t, TPE_PASSENGERS, hs->population, stations);
651 TownGenerateCargoOriginal(t, TPE_MAIL, hs->mail_generation, stations);
652 break;
653
654 case TCGM_BITCOUNT:
655 /* Binomial distribution per tick, by a series of coin flips */
656 /* Reduce generation rate to a 1/4, using tile bits to spread out distribution.
657 * As tick counter is incremented by 256 between each call, we ignore the lower 8 bits. */
658 if (GB(TimerGameTick::counter, 8, 2) == GB(tile.base(), 0, 2)) {
659 TownGenerateCargoBinomial(t, TPE_PASSENGERS, hs->population, stations);
660 TownGenerateCargoBinomial(t, TPE_MAIL, hs->mail_generation, stations);
661 }
662 break;
663
664 default:
665 NOT_REACHED();
666 }
667 }
668
669 Backup<CompanyID> cur_company(_current_company, OWNER_TOWN);
670
671 if (hs->building_flags.Any(BUILDING_HAS_1_TILE) &&
672 t->flags.Test(TownFlag::IsGrowing) &&
673 CanDeleteHouse(tile) &&
674 GetHouseAge(tile) >= hs->minimum_life &&
675 --t->time_until_rebuild == 0) {
676 t->time_until_rebuild = GB(r, 16, 8) + 192;
677
678 ClearTownHouse(t, tile);
679
680 /* Rebuild with another house? */
681 if (GB(r, 24, 8) >= 12) {
682 /* If we are multi-tile houses, make sure to replace the house
683 * closest to city center. If we do not do this, houses tend to
684 * wander away from roads and other houses. */
685 if (hs->building_flags.Any(BUILDING_HAS_2_TILES)) {
686 /* House tiles are always the most north tile. Move the new
687 * house to the south if we are north of the city center. */
688 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
689 int x = Clamp(grid_pos.x, 0, 1);
690 int y = Clamp(grid_pos.y, 0, 1);
691
692 if (hs->building_flags.Test(BuildingFlag::Size2x2)) {
693 tile = TileAddXY(tile, x, y);
694 } else if (hs->building_flags.Test(BuildingFlag::Size1x2)) {
695 tile = TileAddXY(tile, 0, y);
696 } else if (hs->building_flags.Test(BuildingFlag::Size2x1)) {
697 tile = TileAddXY(tile, x, 0);
698 }
699 }
700
701 TownExpandModes modes{TownExpandMode::Buildings};
702 if (_settings_game.economy.allow_town_roads) modes.Set(TownExpandMode::Roads);
703
704 TryBuildTownHouse(t, tile, modes);
705 }
706 }
707
708 cur_company.Restore();
709}
710
717 static CommandCost ClearTile_Town(TileIndex tile, DoCommandFlags flags)
718{
719 if (flags.Test(DoCommandFlag::Auto)) return CommandCost(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
720 if (!CanDeleteHouse(tile)) return CommandCost(STR_ERROR_BUILDING_IS_PROTECTED);
721
722 const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
723
724 CommandCost cost(EXPENSES_CONSTRUCTION);
725 cost.AddCost(hs->GetRemovalCost());
726
727 int rating = hs->remove_rating_decrease;
728 Town *t = Town::GetByTile(tile);
729
730 if (Company::IsValidID(_current_company)) {
731 if (!_cheats.magic_bulldozer.value && !flags.Test(DoCommandFlag::NoTestTownRating)) {
732 /* NewGRFs can add indestructible houses. */
733 if (rating > RATING_MAXIMUM) {
734 return CommandCost(STR_ERROR_BUILDING_IS_PROTECTED);
735 }
736 /* If town authority controls removal, check the company's rating. */
737 if (rating > t->ratings[_current_company] && _settings_game.difficulty.town_council_tolerance != TOWN_COUNCIL_PERMISSIVE) {
738 return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index);
739 }
740 }
741 }
742
743 ChangeTownRating(t, -rating, RATING_HOUSE_MINIMUM, flags);
744 if (flags.Test(DoCommandFlag::Execute)) {
745 ClearTownHouse(t, tile);
746 }
747
748 return cost;
749}
750
751static void AddProducedCargo_Town(TileIndex tile, CargoArray &produced)
752{
753 HouseID house_id = GetHouseType(tile);
754 const HouseSpec *hs = HouseSpec::Get(house_id);
755 Town *t = Town::GetByTile(tile);
756
757 if (hs->callback_mask.Test(HouseCallbackMask::ProduceCargo)) {
758 for (uint i = 0; i < 256; i++) {
759 uint16_t callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, 0, house_id, t, tile);
760
761 if (callback == CALLBACK_FAILED || callback == CALLBACK_HOUSEPRODCARGO_END) break;
762
763 CargoType cargo = GetCargoTranslation(GB(callback, 8, 7), hs->grf_prop.grffile);
764
765 if (!IsValidCargoType(cargo)) continue;
766 produced[cargo]++;
767 }
768 } else {
769 if (hs->population > 0) {
770 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_PASSENGERS]) {
771 produced[cs->Index()]++;
772 }
773 }
774 if (hs->mail_generation > 0) {
775 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_MAIL]) {
776 produced[cs->Index()]++;
777 }
778 }
779 }
780}
781
789 static void AddAcceptedCargoSetMask(CargoType cargo, uint amount, CargoArray &acceptance, CargoTypes &always_accepted)
790{
791 if (!IsValidCargoType(cargo) || amount == 0) return;
792 acceptance[cargo] += amount;
793 SetBit(always_accepted, cargo);
794}
795
805 void AddAcceptedCargoOfHouse(TileIndex tile, HouseID house, const HouseSpec *hs, Town *t, CargoArray &acceptance, CargoTypes &always_accepted)
806{
807 CargoType accepts[lengthof(hs->accepts_cargo)];
808
809 /* Set the initial accepted cargo types */
810 for (uint8_t i = 0; i < lengthof(accepts); i++) {
811 accepts[i] = hs->accepts_cargo[i];
812 }
813
814 /* Check for custom accepted cargo types */
815 if (hs->callback_mask.Test(HouseCallbackMask::AcceptCargo)) {
816 uint16_t callback = GetHouseCallback(CBID_HOUSE_ACCEPT_CARGO, 0, 0, house, t, tile, {}, tile == INVALID_TILE);
817 if (callback != CALLBACK_FAILED) {
818 /* Replace accepted cargo types with translated values from callback */
819 accepts[0] = GetCargoTranslation(GB(callback, 0, 5), hs->grf_prop.grffile);
820 accepts[1] = GetCargoTranslation(GB(callback, 5, 5), hs->grf_prop.grffile);
821 accepts[2] = GetCargoTranslation(GB(callback, 10, 5), hs->grf_prop.grffile);
822 }
823 }
824
825 /* Check for custom cargo acceptance */
826 if (hs->callback_mask.Test(HouseCallbackMask::CargoAcceptance)) {
827 uint16_t callback = GetHouseCallback(CBID_HOUSE_CARGO_ACCEPTANCE, 0, 0, house, t, tile, {}, tile == INVALID_TILE);
828 if (callback != CALLBACK_FAILED) {
829 AddAcceptedCargoSetMask(accepts[0], GB(callback, 0, 4), acceptance, always_accepted);
830 AddAcceptedCargoSetMask(accepts[1], GB(callback, 4, 4), acceptance, always_accepted);
831 if (_settings_game.game_creation.landscape != LandscapeType::Temperate && HasBit(callback, 12)) {
832 /* The 'S' bit indicates food instead of goods */
833 AddAcceptedCargoSetMask(GetCargoTypeByLabel(CT_FOOD), GB(callback, 8, 4), acceptance, always_accepted);
834 } else {
835 AddAcceptedCargoSetMask(accepts[2], GB(callback, 8, 4), acceptance, always_accepted);
836 }
837 return;
838 }
839 }
840
841 /* No custom acceptance, so fill in with the default values */
842 for (uint8_t i = 0; i < lengthof(accepts); i++) {
843 AddAcceptedCargoSetMask(accepts[i], hs->cargo_acceptance[i], acceptance, always_accepted);
844 }
845}
846
847static void AddAcceptedCargo_Town(TileIndex tile, CargoArray &acceptance, CargoTypes &always_accepted)
848{
849 HouseID house = GetHouseType(tile);
850 AddAcceptedCargoOfHouse(tile, house, HouseSpec::Get(house), Town::GetByTile(tile), acceptance, always_accepted);
851}
852
858 CargoArray GetAcceptedCargoOfHouse(const HouseSpec *hs)
859{
860 CargoTypes always_accepted{};
861 CargoArray acceptance{};
862 AddAcceptedCargoOfHouse(INVALID_TILE, hs->Index(), hs, nullptr, acceptance, always_accepted);
863 return acceptance;
864}
865
866static void GetTileDesc_Town(TileIndex tile, TileDesc &td)
867{
868 const HouseID house = GetHouseType(tile);
869 const HouseSpec *hs = HouseSpec::Get(house);
870 bool house_completed = IsHouseCompleted(tile);
871
872 td.str = hs->building_name;
873 td.town_can_upgrade = !IsHouseProtected(tile);
874
875 std::array<int32_t, 1> regs100;
876 uint16_t callback_res = GetHouseCallback(CBID_HOUSE_CUSTOM_NAME, house_completed ? 1 : 0, 0, house, Town::GetByTile(tile), tile, regs100);
877 if (callback_res != CALLBACK_FAILED && callback_res != 0x400) {
878 StringID new_name = STR_NULL;
879 if (callback_res == 0x40F) {
880 new_name = GetGRFStringID(hs->grf_prop.grfid, static_cast<GRFStringID>(regs100[0]));
881 } else if (callback_res > 0x400) {
882 ErrorUnknownCallbackResult(hs->grf_prop.grfid, CBID_HOUSE_CUSTOM_NAME, callback_res);
883 } else {
884 new_name = GetGRFStringID(hs->grf_prop.grfid, GRFSTR_MISC_GRF_TEXT + callback_res);
885 }
886 if (new_name != STR_NULL && new_name != STR_UNDEFINED) {
887 td.str = new_name;
888 }
889 }
890
891 if (!house_completed) {
892 td.dparam = td.str;
893 td.str = STR_LAI_TOWN_INDUSTRY_DESCRIPTION_UNDER_CONSTRUCTION;
894 }
895
896 if (hs->grf_prop.HasGrfFile()) {
897 const GRFConfig *gc = GetGRFConfig(hs->grf_prop.grfid);
898 td.grf = gc->GetName();
899 }
900
901 td.owner[0] = OWNER_TOWN;
902}
903
904static TrackStatus GetTileTrackStatus_Town(TileIndex, TransportType, uint, DiagDirection)
905{
906 /* not used */
907 return 0;
908}
909
910static void ChangeTileOwner_Town(TileIndex, Owner, Owner)
911{
912 /* not used */
913}
914
915static bool GrowTown(Town *t, TownExpandModes modes);
916
921 static void TownTickHandler(Town *t)
922{
923 if (t->flags.Test(TownFlag::IsGrowing)) {
924 TownExpandModes modes{TownExpandMode::Buildings};
925 if (_settings_game.economy.allow_town_roads) modes.Set(TownExpandMode::Roads);
926 int i = (int)t->grow_counter - 1;
927 if (i < 0) {
928 if (GrowTown(t, modes)) {
929 i = t->growth_rate;
930 } else {
931 /* If growth failed wait a bit before retrying */
932 i = std::min<uint16_t>(t->growth_rate, Ticks::TOWN_GROWTH_TICKS - 1);
933 }
934 }
935 t->grow_counter = i;
936 }
937}
938
940 void OnTick_Town()
941{
942 if (_game_mode == GM_EDITOR) return;
943
944 for (Town *t : Town::Iterate()) {
945 TownTickHandler(t);
946 }
947}
948
954 static RoadBits GetTownRoadBits(TileIndex tile)
955{
956 if (IsRoadDepotTile(tile) || IsBayRoadStopTile(tile)) return ROAD_NONE;
957
958 return GetAnyRoadBits(tile, RTT_ROAD, true);
959}
960
965 RoadType GetTownRoadType()
966{
967 RoadType best_rt = ROADTYPE_ROAD;
968 const RoadTypeInfo *best = nullptr;
969 const uint16_t assume_max_speed = 50;
970
971 for (RoadType rt : GetMaskForRoadTramType(RTT_ROAD)) {
972 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
973
974 /* Can town build this road. */
975 if (!rti->flags.Test(RoadTypeFlag::TownBuild)) continue;
976
977 /* Not yet introduced at this date. */
978 if (IsInsideMM(rti->introduction_date, 0, CalendarTime::MAX_DATE.base()) && rti->introduction_date > TimerGameCalendar::date) continue;
979
980 if (best != nullptr) {
981 if ((rti->max_speed == 0 ? assume_max_speed : rti->max_speed) < (best->max_speed == 0 ? assume_max_speed : best->max_speed)) continue;
982 }
983
984 best_rt = rt;
985 best = rti;
986 }
987
988 return best_rt;
989}
990
995 static TimerGameCalendar::Date GetTownRoadTypeFirstIntroductionDate()
996{
997 const RoadTypeInfo *best = nullptr;
998 for (RoadType rt : GetMaskForRoadTramType(RTT_ROAD)) {
999 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
1000
1001 if (!rti->flags.Test(RoadTypeFlag::TownBuild)) continue; // Town can't build this road type.
1002
1003 if (best != nullptr && rti->introduction_date >= best->introduction_date) continue;
1004 best = rti;
1005 }
1006
1007 if (best == nullptr) return TimerGameCalendar::Date(INT32_MAX);
1008 return best->introduction_date;
1009}
1010
1015 bool CheckTownRoadTypes()
1016{
1017 auto min_date = GetTownRoadTypeFirstIntroductionDate();
1018 if (min_date <= TimerGameCalendar::date) return true;
1019
1020 if (min_date < INT32_MAX) {
1021 ShowErrorMessage(
1022 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_YET),
1023 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_YET_EXPLANATION, min_date),
1024 WL_CRITICAL);
1025 } else {
1026 ShowErrorMessage(
1027 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_AT_ALL),
1028 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_AT_ALL_EXPLANATION), WL_CRITICAL);
1029 }
1030 return false;
1031}
1032
1043 static bool IsNeighbourRoadTile(TileIndex tile, const DiagDirection dir, uint dist_multi)
1044{
1045 if (!IsValidTile(tile)) return false;
1046
1047 /* Lookup table for the used diff values */
1048 const TileIndexDiff tid_lt[3] = {
1049 TileOffsByDiagDir(ChangeDiagDir(dir, DIAGDIRDIFF_90RIGHT)),
1050 TileOffsByDiagDir(ChangeDiagDir(dir, DIAGDIRDIFF_90LEFT)),
1051 TileOffsByDiagDir(ReverseDiagDir(dir)),
1052 };
1053
1054 dist_multi = (dist_multi + 1) * 4;
1055 for (uint pos = 4; pos < dist_multi; pos++) {
1056 /* Go (pos / 4) tiles to the left or the right */
1057 TileIndexDiff cur = tid_lt[(pos & 1) ? 0 : 1] * (pos / 4);
1058
1059 /* Use the current tile as origin, or go one tile backwards */
1060 if (pos & 2) cur += tid_lt[2];
1061
1062 /* Test for roadbit parallel to dir and facing towards the middle axis */
1063 if (IsValidTile(tile + cur) &&
1064 GetTownRoadBits(TileAdd(tile, cur)) & DiagDirToRoadBits((pos & 2) ? dir : ReverseDiagDir(dir))) return true;
1065 }
1066 return false;
1067}
1068
1077 static bool IsRoadAllowedHere(Town *t, TileIndex tile, DiagDirection dir)
1078{
1079 if (DistanceFromEdge(tile) == 0) return false;
1080
1081 /* Prevent towns from building roads under bridges along the bridge. Looks silly. */
1082 if (IsBridgeAbove(tile) && GetBridgeAxis(tile) == DiagDirToAxis(dir)) return false;
1083
1084 /* Check if there already is a road at this point? */
1085 if (GetTownRoadBits(tile) == ROAD_NONE) {
1086 /* No, try if we are able to build a road piece there.
1087 * If that fails clear the land, and if that fails exit.
1088 * This is to make sure that we can build a road here later. */
1089 RoadType rt = GetTownRoadType();
1090 if (Command<CMD_BUILD_ROAD>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile, (dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? ROAD_Y : ROAD_X, rt, DRD_NONE, t->index).Failed() &&
1091 Command<CMD_LANDSCAPE_CLEAR>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile).Failed()) {
1092 return false;
1093 }
1094 }
1095
1096 Slope cur_slope = _settings_game.construction.build_on_slopes ? std::get<0>(GetFoundationSlope(tile)) : GetTileSlope(tile);
1097 bool ret = !IsNeighbourRoadTile(tile, dir, t->layout == TL_ORIGINAL ? 1 : 2);
1098 if (cur_slope == SLOPE_FLAT) return ret;
1099
1100 /* If the tile is not a slope in the right direction, then
1101 * maybe terraform some. */
1102 Slope desired_slope = (dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? SLOPE_NW : SLOPE_NE;
1103 if (desired_slope != cur_slope && ComplementSlope(desired_slope) != cur_slope) {
1104 if (Chance16(1, 8)) {
1105 CommandCost res = CMD_ERROR;
1106 if (!_generating_world && Chance16(1, 10)) {
1107 /* Note: Do not replace "^ SLOPE_ELEVATED" with ComplementSlope(). The slope might be steep. */
1108 res = std::get<0>(Command<CMD_TERRAFORM_LAND>::Do({DoCommandFlag::Execute, DoCommandFlag::Auto, DoCommandFlag::NoWater},
1109 tile, Chance16(1, 16) ? cur_slope : cur_slope ^ SLOPE_ELEVATED, false));
1110 }
1111 if (res.Failed() && Chance16(1, 3)) {
1112 /* We can consider building on the slope, though. */
1113 return ret;
1114 }
1115 }
1116 return false;
1117 }
1118 return ret;
1119}
1120
1121static bool TerraformTownTile(TileIndex tile, Slope edges, bool dir)
1122{
1123 assert(tile < Map::Size());
1124
1125 CommandCost r = std::get<0>(Command<CMD_TERRAFORM_LAND>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile, edges, dir));
1126 if (r.Failed() || r.GetCost() >= (_price[PR_TERRAFORM] + 2) * 8) return false;
1127 Command<CMD_TERRAFORM_LAND>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater, DoCommandFlag::Execute}, tile, edges, dir);
1128 return true;
1129}
1130
1131static void LevelTownLand(TileIndex tile)
1132{
1133 assert(tile < Map::Size());
1134
1135 /* Don't terraform if land is plain or if there's a house there. */
1136 if (IsTileType(tile, MP_HOUSE)) return;
1137 Slope tileh = GetTileSlope(tile);
1138 if (tileh == SLOPE_FLAT) return;
1139
1140 /* First try up, then down */
1141 if (!TerraformTownTile(tile, ~tileh & SLOPE_ELEVATED, true)) {
1142 TerraformTownTile(tile, tileh & SLOPE_ELEVATED, false);
1143 }
1144}
1145
1154 static RoadBits GetTownRoadGridElement(Town *t, TileIndex tile, DiagDirection dir)
1155{
1156 /* align the grid to the downtown */
1157 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile); // Vector from downtown to the tile
1158 RoadBits rcmd = ROAD_NONE;
1159
1160 switch (t->layout) {
1161 default: NOT_REACHED();
1162
1163 case TL_2X2_GRID:
1164 if ((grid_pos.x % 3) == 0) rcmd |= ROAD_Y;
1165 if ((grid_pos.y % 3) == 0) rcmd |= ROAD_X;
1166 break;
1167
1168 case TL_3X3_GRID:
1169 if ((grid_pos.x % 4) == 0) rcmd |= ROAD_Y;
1170 if ((grid_pos.y % 4) == 0) rcmd |= ROAD_X;
1171 break;
1172 }
1173
1174 /* Optimise only X-junctions */
1175 if (rcmd != ROAD_ALL) return rcmd;
1176
1177 RoadBits rb_template;
1178
1179 switch (GetTileSlope(tile)) {
1180 default: rb_template = ROAD_ALL; break;
1181 case SLOPE_W: rb_template = ROAD_NW | ROAD_SW; break;
1182 case SLOPE_SW: rb_template = ROAD_Y | ROAD_SW; break;
1183 case SLOPE_S: rb_template = ROAD_SW | ROAD_SE; break;
1184 case SLOPE_SE: rb_template = ROAD_X | ROAD_SE; break;
1185 case SLOPE_E: rb_template = ROAD_SE | ROAD_NE; break;
1186 case SLOPE_NE: rb_template = ROAD_Y | ROAD_NE; break;
1187 case SLOPE_N: rb_template = ROAD_NE | ROAD_NW; break;
1188 case SLOPE_NW: rb_template = ROAD_X | ROAD_NW; break;
1189 case SLOPE_STEEP_W:
1190 case SLOPE_STEEP_S:
1191 case SLOPE_STEEP_E:
1192 case SLOPE_STEEP_N:
1193 rb_template = ROAD_NONE;
1194 break;
1195 }
1196
1197 /* Stop if the template is compatible to the growth dir */
1198 if (DiagDirToRoadBits(ReverseDiagDir(dir)) & rb_template) return rb_template;
1199 /* If not generate a straight road in the direction of the growth */
1200 return DiagDirToRoadBits(dir) | DiagDirToRoadBits(ReverseDiagDir(dir));
1201}
1202
1213 static bool GrowTownWithExtraHouse(Town *t, TileIndex tile, TownExpandModes modes)
1214{
1215 /* We can't look further than that. */
1216 if (DistanceFromEdge(tile) == 0) return false;
1217
1218 uint counter = 0; // counts the house neighbour tiles
1219
1220 /* Check the tiles E,N,W and S of the current tile for houses */
1221 for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
1222 /* Count both void and house tiles for checking whether there
1223 * are enough houses in the area. This to make it likely that
1224 * houses get build up to the edge of the map. */
1225 switch (GetTileType(TileAddByDiagDir(tile, dir))) {
1226 case MP_HOUSE:
1227 case MP_VOID:
1228 counter++;
1229 break;
1230
1231 default:
1232 break;
1233 }
1234
1235 /* If there are enough neighbours stop here */
1236 if (counter >= 3) {
1237 return TryBuildTownHouse(t, tile, modes);
1238 }
1239 }
1240 return false;
1241}
1242
1251 static bool GrowTownWithRoad(const Town *t, TileIndex tile, RoadBits rcmd)
1252{
1253 RoadType rt = GetTownRoadType();
1254 return Command<CMD_BUILD_ROAD>::Do({DoCommandFlag::Execute, DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile, rcmd, rt, DRD_NONE, t->index).Succeeded();
1255}
1256
1266 static bool CanRoadContinueIntoNextTile(const Town *t, const TileIndex tile, const DiagDirection road_dir)
1267{
1268 const TileIndexDiff delta = TileOffsByDiagDir(road_dir); // +1 tile in the direction of the road
1269 TileIndex next_tile = tile + delta; // The tile beyond which must be connectable to the target tile
1270 RoadBits rcmd = DiagDirToRoadBits(ReverseDiagDir(road_dir));
1271 RoadType rt = GetTownRoadType();
1272
1273 /* Before we try anything, make sure the tile is on the map and not the void. */
1274 if (!IsValidTile(next_tile)) return false;
1275
1276 /* If the next tile is a bridge or tunnel, allow if it's continuing in the same direction. */
1277 if (IsTileType(next_tile, MP_TUNNELBRIDGE)) {
1278 return GetTunnelBridgeTransportType(next_tile) == TRANSPORT_ROAD && GetTunnelBridgeDirection(next_tile) == road_dir;
1279 }
1280
1281 /* If the next tile is a station, allow if it's a road station facing the proper direction. Otherwise return false. */
1282 if (IsTileType(next_tile, MP_STATION)) {
1283 /* If the next tile is a road station, allow if it can be entered by the new tunnel/bridge, otherwise disallow. */
1284 if (IsDriveThroughStopTile(next_tile)) return GetDriveThroughStopAxis(next_tile) == DiagDirToAxis(road_dir);
1285 if (IsBayRoadStopTile(next_tile)) return GetBayRoadStopDir(next_tile) == ReverseDiagDir(road_dir);
1286 return false;
1287 }
1288
1289 /* If the next tile is a road depot, allow if it's facing the right way. */
1290 if (IsTileType(next_tile, MP_ROAD)) {
1291 return IsRoadDepot(next_tile) && GetRoadDepotDirection(next_tile) == ReverseDiagDir(road_dir);
1292 }
1293
1294 /* If the next tile is a railroad track, check if towns are allowed to build level crossings.
1295 * If level crossing are not allowed, reject the construction. Else allow DoCommand to determine if the rail track is buildable. */
1296 if (IsTileType(next_tile, MP_RAILWAY) && !_settings_game.economy.allow_town_level_crossings) return false;
1297
1298 /* If a road tile can be built, the construction is allowed. */
1299 return Command<CMD_BUILD_ROAD>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, next_tile, rcmd, rt, DRD_NONE, t->index).Succeeded();
1300}
1301
1312 static bool GrowTownWithBridge(const Town *t, const TileIndex tile, const DiagDirection bridge_dir)
1313{
1314 assert(bridge_dir < DIAGDIR_END);
1315
1316 const Slope slope = GetTileSlope(tile);
1317
1318 /* Make sure the direction is compatible with the slope.
1319 * Well we check if the slope has an up bit set in the
1320 * reverse direction. */
1321 if (slope != SLOPE_FLAT && slope & InclinedSlope(bridge_dir)) return false;
1322
1323 /* Assure that the bridge is connectable to the start side */
1324 if (!(GetTownRoadBits(TileAddByDiagDir(tile, ReverseDiagDir(bridge_dir))) & DiagDirToRoadBits(bridge_dir))) return false;
1325
1326 /* We are in the right direction */
1327 uint bridge_length = 0; // This value stores the length of the possible bridge
1328 TileIndex bridge_tile = tile; // Used to store the other waterside
1329
1330 const TileIndexDiff delta = TileOffsByDiagDir(bridge_dir);
1331
1332 /* To prevent really small towns from building disproportionately
1333 * long bridges, make the max a function of its population. */
1334 const uint TOWN_BRIDGE_LENGTH_CAP = 11;
1335 uint base_bridge_length = 5;
1336 uint max_bridge_length = std::min(t->cache.population / 1000 + base_bridge_length, TOWN_BRIDGE_LENGTH_CAP);
1337
1338 if (slope == SLOPE_FLAT) {
1339 /* Bridges starting on flat tiles are only allowed when crossing rivers, rails or one-way roads. */
1340 do {
1341 if (bridge_length++ >= base_bridge_length) {
1342 /* Allow to cross rivers, not big lakes, nor large amounts of rails or one-way roads. */
1343 return false;
1344 }
1345 bridge_tile += delta;
1346 } while (IsValidTile(bridge_tile) && ((IsWaterTile(bridge_tile) && !IsSea(bridge_tile)) || IsPlainRailTile(bridge_tile) || (IsNormalRoadTile(bridge_tile) && GetDisallowedRoadDirections(bridge_tile) != DRD_NONE)));
1347 } else {
1348 do {
1349 if (bridge_length++ >= max_bridge_length) {
1350 /* Ensure the bridge is not longer than the max allowed length. */
1351 return false;
1352 }
1353 bridge_tile += delta;
1354 } while (IsValidTile(bridge_tile) && (IsWaterTile(bridge_tile) || IsPlainRailTile(bridge_tile) || (IsNormalRoadTile(bridge_tile) && GetDisallowedRoadDirections(bridge_tile) != DRD_NONE)));
1355 }
1356
1357 /* Don't allow a bridge where the start and end tiles are adjacent with no span between. */
1358 if (bridge_length == 1) return false;
1359
1360 /* Make sure the road can be continued past the bridge. At this point, bridge_tile holds the end tile of the bridge. */
1361 if (!CanRoadContinueIntoNextTile(t, bridge_tile, bridge_dir)) return false;
1362
1363 /* If another parallel bridge exists nearby, this one would be redundant and shouldn't be built. We don't care about flat bridges. */
1364 if (slope != SLOPE_FLAT) {
1365 for (auto search : SpiralTileSequence(tile, bridge_length, 0, 0)) {
1366 /* Only consider bridge head tiles. */
1367 if (!IsBridgeTile(search)) continue;
1368
1369 /* Only consider road bridges. */
1370 if (GetTunnelBridgeTransportType(search) != TRANSPORT_ROAD) continue;
1371
1372 /* If the bridge is facing the same direction as the proposed bridge, we've found a redundant bridge. */
1373 if (GetTileSlope(search) & InclinedSlope(ReverseDiagDir(bridge_dir))) return false;
1374 }
1375 }
1376
1377 for (uint8_t times = 0; times <= 22; times++) {
1378 uint8_t bridge_type = RandomRange(MAX_BRIDGES - 1);
1379
1380 /* Can we actually build the bridge? */
1381 RoadType rt = GetTownRoadType();
1382 if (Command<CMD_BUILD_BRIDGE>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_BRIDGE>()), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, rt).Succeeded()) {
1383 Command<CMD_BUILD_BRIDGE>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_BRIDGE>()).Set(DoCommandFlag::Execute), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, rt);
1384 return true;
1385 }
1386 }
1387 /* Quit if it selecting an appropriate bridge type fails a large number of times. */
1388 return false;
1389}
1390
1401 static bool GrowTownWithTunnel(const Town *t, const TileIndex tile, const DiagDirection tunnel_dir)
1402{
1403 assert(tunnel_dir < DIAGDIR_END);
1404
1405 Slope slope = GetTileSlope(tile);
1406
1407 /* Only consider building a tunnel if the starting tile is sloped properly. */
1408 if (slope != InclinedSlope(tunnel_dir)) return false;
1409
1410 /* Assure that the tunnel is connectable to the start side */
1411 if (!(GetTownRoadBits(TileAddByDiagDir(tile, ReverseDiagDir(tunnel_dir))) & DiagDirToRoadBits(tunnel_dir))) return false;
1412
1413 const TileIndexDiff delta = TileOffsByDiagDir(tunnel_dir);
1414 int max_tunnel_length = 0;
1415
1416 /* There are two conditions for building tunnels: Under a mountain and under an obstruction. */
1417 if (CanRoadContinueIntoNextTile(t, tile, tunnel_dir)) {
1418 /* Only tunnel under a mountain if the slope is continuous for at least 4 tiles. We want tunneling to be a last resort for large hills. */
1419 TileIndex slope_tile = tile;
1420 for (uint8_t tiles = 0; tiles < 4; tiles++) {
1421 if (!IsValidTile(slope_tile)) return false;
1422 slope = GetTileSlope(slope_tile);
1423 if (slope != InclinedSlope(tunnel_dir) && !IsSteepSlope(slope) && !IsSlopeWithOneCornerRaised(slope)) return false;
1424 slope_tile += delta;
1425 }
1426
1427 /* More population means longer tunnels, but make sure we can at least cover the smallest mountain which necessitates tunneling. */
1428 max_tunnel_length = (t->cache.population / 1000) + 7;
1429 } else {
1430 /* When tunneling under an obstruction, the length limit is 5, enough to tunnel under a four-track railway. */
1431 max_tunnel_length = 5;
1432 }
1433
1434 uint8_t tunnel_length = 0;
1435 TileIndex tunnel_tile = tile; // Iterator to store the other end tile of the tunnel.
1436
1437 /* Find the end tile of the tunnel for length and continuation checks. */
1438 do {
1439 if (tunnel_length++ >= max_tunnel_length) return false;
1440 tunnel_tile += delta;
1441 /* The tunnel ends when start and end tiles are the same height. */
1442 } while (IsValidTile(tunnel_tile) && GetTileZ(tile) != GetTileZ(tunnel_tile));
1443
1444 /* Don't allow a tunnel where the start and end tiles are adjacent. */
1445 if (tunnel_length == 1) return false;
1446
1447 /* Make sure the road can be continued past the tunnel. At this point, tunnel_tile holds the end tile of the tunnel. */
1448 if (!CanRoadContinueIntoNextTile(t, tunnel_tile, tunnel_dir)) return false;
1449
1450 /* Attempt to build the tunnel. Return false if it fails to let the town build a road instead. */
1451 RoadType rt = GetTownRoadType();
1452 if (Command<CMD_BUILD_TUNNEL>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_TUNNEL>()), tile, TRANSPORT_ROAD, rt).Succeeded()) {
1453 Command<CMD_BUILD_TUNNEL>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_TUNNEL>()).Set(DoCommandFlag::Execute), tile, TRANSPORT_ROAD, rt);
1454 return true;
1455 }
1456
1457 return false;
1458}
1459
1466 static inline bool RoadTypesAllowHouseHere(TileIndex t)
1467{
1468 static const TileIndexDiffC tiles[] = { {-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1} };
1469 bool allow = false;
1470
1471 for (const auto &ptr : tiles) {
1472 TileIndex cur_tile = t + ToTileIndexDiff(ptr);
1473 if (!IsValidTile(cur_tile)) continue;
1474
1475 if (!(IsTileType(cur_tile, MP_ROAD) || IsAnyRoadStopTile(cur_tile))) continue;
1476 allow = true;
1477
1478 RoadType road_rt = GetRoadTypeRoad(cur_tile);
1479 if (road_rt != INVALID_ROADTYPE && !GetRoadTypeInfo(road_rt)->flags.Test(RoadTypeFlag::NoHouses)) return true;
1480 }
1481
1482 /* If no road was found surrounding the tile we can allow building the house since there is
1483 * nothing which forbids it, if a road was found but the execution reached this point, then
1484 * all the found roads don't allow houses to be built */
1485 return !allow;
1486}
1487
1492 static bool TownCanGrowRoad(TileIndex tile)
1493{
1494 if (!IsTileType(tile, MP_ROAD)) return true;
1495
1496 /* Allow extending on roadtypes which can be built by town, or if the road type matches the type the town will build. */
1497 RoadType rt = GetRoadTypeRoad(tile);
1498 return GetRoadTypeInfo(rt)->flags.Test(RoadTypeFlag::TownBuild) || GetTownRoadType() == rt;
1499}
1500
1505 static inline bool TownAllowedToBuildRoads(TownExpandModes modes)
1506{
1507 return modes.Test(TownExpandMode::Roads);
1508}
1509
1510/* The possible states of town growth. */
1511enum class TownGrowthResult {
1512 Succeed,
1513 SearchStopped,
1514 Continue,
1515};
1516
1535 static TownGrowthResult GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection target_dir, Town *t1, TownExpandModes modes)
1536{
1537 RoadBits rcmd = ROAD_NONE; // RoadBits for the road construction command
1538 TileIndex tile = *tile_ptr; // The main tile on which we base our growth
1539
1540 assert(tile < Map::Size());
1541
1542 if (cur_rb == ROAD_NONE) {
1543 /* Tile has no road.
1544 * We will return TownGrowthResult::SearchStopped to say that this is the last iteration. */
1545
1546 if (!TownAllowedToBuildRoads(modes)) return TownGrowthResult::SearchStopped;
1547 if (!_settings_game.economy.allow_town_level_crossings && IsTileType(tile, MP_RAILWAY)) return TownGrowthResult::SearchStopped;
1548
1549 /* Remove hills etc */
1550 if (!_settings_game.construction.build_on_slopes || Chance16(1, 6)) LevelTownLand(tile);
1551
1552 /* Is a road allowed here? */
1553 switch (t1->layout) {
1554 default: NOT_REACHED();
1555
1556 case TL_3X3_GRID:
1557 case TL_2X2_GRID:
1558 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1559 if (rcmd == ROAD_NONE) return TownGrowthResult::SearchStopped;
1560 break;
1561
1562 case TL_BETTER_ROADS:
1563 case TL_ORIGINAL:
1564 if (!IsRoadAllowedHere(t1, tile, target_dir)) return TownGrowthResult::SearchStopped;
1565
1566 DiagDirection source_dir = ReverseDiagDir(target_dir);
1567
1568 if (Chance16(1, 4)) {
1569 /* Randomize a new target dir */
1570 do target_dir = RandomDiagDir(); while (target_dir == source_dir);
1571 }
1572
1573 if (!IsRoadAllowedHere(t1, TileAddByDiagDir(tile, target_dir), target_dir)) {
1574 /* A road is not allowed to continue the randomized road,
1575 * return if the road we're trying to build is curved. */
1576 if (target_dir != ReverseDiagDir(source_dir)) return TownGrowthResult::SearchStopped;
1577
1578 /* Return if neither side of the new road is a house */
1579 if (!IsTileType(TileAddByDiagDir(tile, ChangeDiagDir(target_dir, DIAGDIRDIFF_90RIGHT)), MP_HOUSE) &&
1580 !IsTileType(TileAddByDiagDir(tile, ChangeDiagDir(target_dir, DIAGDIRDIFF_90LEFT)), MP_HOUSE)) {
1581 return TownGrowthResult::SearchStopped;
1582 }
1583
1584 /* That means that the road is only allowed if there is a house
1585 * at any side of the new road. */
1586 }
1587
1588 rcmd = DiagDirToRoadBits(target_dir) | DiagDirToRoadBits(source_dir);
1589 break;
1590 }
1591
1592 } else if (target_dir < DIAGDIR_END && !(cur_rb & DiagDirToRoadBits(ReverseDiagDir(target_dir)))) {
1593 if (!TownCanGrowRoad(tile)) return TownGrowthResult::Continue;
1594
1595 if (!TownAllowedToBuildRoads(modes)) return TownGrowthResult::SearchStopped;
1596
1597 /* Continue building on a partial road.
1598 * Should be always OK, so we only generate
1599 * the fitting RoadBits */
1600 switch (t1->layout) {
1601 default: NOT_REACHED();
1602
1603 case TL_3X3_GRID:
1604 case TL_2X2_GRID:
1605 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1606 break;
1607
1608 case TL_BETTER_ROADS:
1609 case TL_ORIGINAL:
1610 rcmd = DiagDirToRoadBits(ReverseDiagDir(target_dir));
1611 break;
1612 }
1613 } else {
1614 bool allow_house = true; // Value which decides if we want to construct a house
1615
1616 /* Reached a tunnel/bridge? Then continue at the other side of it, unless
1617 * it is the starting tile. Half the time, we stay on this side then.*/
1618 if (IsTileType(tile, MP_TUNNELBRIDGE)) {
1619 if (GetTunnelBridgeTransportType(tile) == TRANSPORT_ROAD && (target_dir != DIAGDIR_END || Chance16(1, 2))) {
1620 *tile_ptr = GetOtherTunnelBridgeEnd(tile);
1621 }
1622 return TownGrowthResult::Continue;
1623 }
1624
1625 /* Possibly extend the road in a direction.
1626 * Randomize a direction and if it has a road, bail out. */
1627 target_dir = RandomDiagDir();
1628 RoadBits target_rb = DiagDirToRoadBits(target_dir);
1629 TileIndex house_tile; // position of a possible house
1630
1631 if (cur_rb & target_rb) {
1632 /* If it's a road turn possibly build a house in a corner.
1633 * Use intersection with straight road as an indicator
1634 * that we randomised corner house position.
1635 * A turn (and we check for that later) always has only
1636 * one common bit with a straight road so it has the same
1637 * chance to be chosen as the house on the side of a road.
1638 */
1639 if ((cur_rb & ROAD_X) != target_rb) return TownGrowthResult::Continue;
1640
1641 /* Check whether it is a turn and if so determine
1642 * position of the corner tile */
1643 switch (cur_rb) {
1644 case ROAD_N:
1645 house_tile = TileAddByDir(tile, DIR_S);
1646 break;
1647 case ROAD_S:
1648 house_tile = TileAddByDir(tile, DIR_N);
1649 break;
1650 case ROAD_E:
1651 house_tile = TileAddByDir(tile, DIR_W);
1652 break;
1653 case ROAD_W:
1654 house_tile = TileAddByDir(tile, DIR_E);
1655 break;
1656 default:
1657 return TownGrowthResult::Continue; // not a turn
1658 }
1659 target_dir = DIAGDIR_END;
1660 } else {
1661 house_tile = TileAddByDiagDir(tile, target_dir);
1662 }
1663
1664 /* Don't walk into water. */
1665 if (HasTileWaterGround(house_tile)) return TownGrowthResult::Continue;
1666
1667 if (!IsValidTile(house_tile)) return TownGrowthResult::Continue;
1668
1669 TownGrowthResult result = TownGrowthResult::Continue;
1670
1671 if (target_dir != DIAGDIR_END && TownAllowedToBuildRoads(modes)) {
1672 switch (t1->layout) {
1673 default: NOT_REACHED();
1674
1675 case TL_3X3_GRID: // Use 2x2 grid afterwards!
1676 if (GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir), modes)) {
1677 result = TownGrowthResult::Succeed;
1678 }
1679 [[fallthrough]];
1680
1681 case TL_2X2_GRID:
1682 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1683 allow_house = (rcmd & target_rb) == ROAD_NONE;
1684 break;
1685
1686 case TL_BETTER_ROADS: // Use original afterwards!
1687 if (GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir), modes)) {
1688 result = TownGrowthResult::Succeed;
1689 }
1690 [[fallthrough]];
1691
1692 case TL_ORIGINAL:
1693 /* Allow a house at the edge. 60% chance or
1694 * always ok if no road allowed. */
1695 rcmd = target_rb;
1696 allow_house = (!IsRoadAllowedHere(t1, house_tile, target_dir) || Chance16(6, 10));
1697 break;
1698 }
1699 }
1700
1701 allow_house &= RoadTypesAllowHouseHere(house_tile);
1702
1703 if (allow_house) {
1704 /* Build a house, but not if there already is a house there. */
1705 if (!IsTileType(house_tile, MP_HOUSE)) {
1706 /* Level the land if possible */
1707 if (Chance16(1, 6)) LevelTownLand(house_tile);
1708
1709 /* And build a house.
1710 * Set result to -1 if we managed to build it. */
1711 if (TryBuildTownHouse(t1, house_tile, modes)) {
1712 result = TownGrowthResult::Succeed;
1713 }
1714 }
1715 return result;
1716 }
1717
1718 if (!TownCanGrowRoad(tile)) return result;
1719 }
1720
1721 /* Return if a water tile */
1722 if (HasTileWaterGround(tile)) return TownGrowthResult::SearchStopped;
1723
1724 /* Make the roads look nicer */
1725 rcmd = CleanUpRoadBits(tile, rcmd);
1726 if (rcmd == ROAD_NONE) return TownGrowthResult::SearchStopped;
1727
1728 /* Only use the target direction for bridges and tunnels to ensure they're connected.
1729 * The target_dir is as computed previously according to town layout, so
1730 * it will match it perfectly. */
1731 if (GrowTownWithBridge(t1, tile, target_dir)) {
1732 return TownGrowthResult::Succeed;
1733 }
1734 if (GrowTownWithTunnel(t1, tile, target_dir)) {
1735 return TownGrowthResult::Succeed;
1736 }
1737
1738 if (GrowTownWithRoad(t1, tile, rcmd)) {
1739 return TownGrowthResult::Succeed;
1740 }
1741 return TownGrowthResult::SearchStopped;
1742}
1743
1751 static bool CanFollowRoad(TileIndex tile, DiagDirection dir, TownExpandModes modes)
1752{
1753 TileIndex target_tile = tile + TileOffsByDiagDir(dir);
1754 if (!IsValidTile(target_tile)) return false;
1755 if (HasTileWaterGround(target_tile)) return false;
1756
1757 RoadBits target_rb = GetTownRoadBits(target_tile);
1758 if (TownAllowedToBuildRoads(modes)) {
1759 /* Check whether a road connection exists or can be build. */
1760 switch (GetTileType(target_tile)) {
1761 case MP_ROAD:
1762 return target_rb != ROAD_NONE;
1763
1764 case MP_STATION:
1765 return IsDriveThroughStopTile(target_tile);
1766
1767 case MP_TUNNELBRIDGE:
1768 return GetTunnelBridgeTransportType(target_tile) == TRANSPORT_ROAD;
1769
1770 case MP_HOUSE:
1771 case MP_INDUSTRY:
1772 case MP_OBJECT:
1773 return false;
1774
1775 default:
1776 /* Checked for void and water earlier */
1777 return true;
1778 }
1779 } else {
1780 /* Check whether a road connection already exists,
1781 * and it leads somewhere else. */
1782 RoadBits back_rb = DiagDirToRoadBits(ReverseDiagDir(dir));
1783 return (target_rb & back_rb) != 0 && (target_rb & ~back_rb) != 0;
1784 }
1785}
1786
1793 static bool GrowTownAtRoad(Town *t, TileIndex tile, TownExpandModes modes)
1794{
1795 /* Special case.
1796 * @see GrowTownInTile Check the else if
1797 */
1798 DiagDirection target_dir = DIAGDIR_END; // The direction in which we want to extend the town
1799
1800 assert(tile < Map::Size());
1801
1802 /* Number of times to search.
1803 * Better roads, 2X2 and 3X3 grid grow quite fast so we give
1804 * them a little handicap. */
1805 int iterations;
1806 switch (t->layout) {
1807 case TL_BETTER_ROADS:
1808 iterations = 10 + t->cache.num_houses * 2 / 9;
1809 break;
1810
1811 case TL_3X3_GRID:
1812 case TL_2X2_GRID:
1813 iterations = 10 + t->cache.num_houses * 1 / 9;
1814 break;
1815
1816 default:
1817 iterations = 10 + t->cache.num_houses * 4 / 9;
1818 break;
1819 }
1820
1821 do {
1822 RoadBits cur_rb = GetTownRoadBits(tile); // The RoadBits of the current tile
1823
1824 /* Try to grow the town from this point */
1825 switch (GrowTownInTile(&tile, cur_rb, target_dir, t, modes)) {
1826 case TownGrowthResult::Succeed:
1827 return true;
1828 case TownGrowthResult::SearchStopped:
1829 iterations = 0;
1830 break;
1831 default:
1832 break;
1833 };
1834
1835 /* Exclude the source position from the bitmask
1836 * and return if no more road blocks available */
1837 if (IsValidDiagDirection(target_dir)) cur_rb &= ~DiagDirToRoadBits(ReverseDiagDir(target_dir));
1838 if (cur_rb == ROAD_NONE) return false;
1839
1840 if (IsTileType(tile, MP_TUNNELBRIDGE)) {
1841 /* Only build in the direction away from the tunnel or bridge. */
1842 target_dir = ReverseDiagDir(GetTunnelBridgeDirection(tile));
1843 } else {
1844 /* Select a random bit from the blockmask, walk a step
1845 * and continue the search from there. */
1846 do {
1847 if (cur_rb == ROAD_NONE) return false;
1848 RoadBits target_bits;
1849 do {
1850 target_dir = RandomDiagDir();
1851 target_bits = DiagDirToRoadBits(target_dir);
1852 } while (!(cur_rb & target_bits));
1853 cur_rb &= ~target_bits;
1854 } while (!CanFollowRoad(tile, target_dir, modes));
1855 }
1856 tile = TileAddByDiagDir(tile, target_dir);
1857
1858 if (IsTileType(tile, MP_ROAD) && !IsRoadDepot(tile) && HasTileRoadType(tile, RTT_ROAD)) {
1859 /* Don't allow building over roads of other cities */
1860 if (IsRoadOwner(tile, RTT_ROAD, OWNER_TOWN) && Town::GetByTile(tile) != t) {
1861 return false;
1862 } else if (IsRoadOwner(tile, RTT_ROAD, OWNER_NONE) && _game_mode == GM_EDITOR) {
1863 /* If we are in the SE, and this road-piece has no town owner yet, it just found an
1864 * owner :) (happy happy happy road now) */
1865 SetRoadOwner(tile, RTT_ROAD, OWNER_TOWN);
1866 SetTownIndex(tile, t->index);
1867 }
1868 }
1869
1870 /* Max number of times is checked. */
1871 } while (--iterations >= 0);
1872
1873 return false;
1874}
1875
1883 static RoadBits GenRandomRoadBits()
1884{
1885 uint32_t r = Random();
1886 uint a = GB(r, 0, 2);
1887 uint b = GB(r, 8, 2);
1888 if (a == b) b ^= 2;
1889 return (RoadBits)((ROAD_NW << a) + (ROAD_NW << b));
1890}
1891
1897 static bool GrowTown(Town *t, TownExpandModes modes)
1898{
1899 static const TileIndexDiffC _town_coord_mod[] = {
1900 {-1, 0},
1901 { 1, 1},
1902 { 1, -1},
1903 {-1, -1},
1904 {-1, 0},
1905 { 0, 2},
1906 { 2, 0},
1907 { 0, -2},
1908 {-1, -1},
1909 {-2, 2},
1910 { 2, 2},
1911 { 2, -2},
1912 { 0, 0}
1913 };
1914
1915 /* Current "company" is a town */
1916 Backup<CompanyID> cur_company(_current_company, OWNER_TOWN);
1917
1918 TileIndex tile = t->xy; // The tile we are working with ATM
1919
1920 /* Find a road that we can base the construction on. */
1921 for (const auto &ptr : _town_coord_mod) {
1922 if (GetTownRoadBits(tile) != ROAD_NONE) {
1923 bool success = GrowTownAtRoad(t, tile, modes);
1924 cur_company.Restore();
1925 return success;
1926 }
1927 tile = TileAdd(tile, ToTileIndexDiff(ptr));
1928 }
1929
1930 /* No road available, try to build a random road block by
1931 * clearing some land and then building a road there. */
1932 if (TownAllowedToBuildRoads(modes)) {
1933 tile = t->xy;
1934 for (const auto &ptr : _town_coord_mod) {
1935 /* Only work with plain land that not already has a house */
1936 if (!IsTileType(tile, MP_HOUSE) && IsTileFlat(tile)) {
1937 if (Command<CMD_LANDSCAPE_CLEAR>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile).Succeeded()) {
1938 RoadType rt = GetTownRoadType();
1939 Command<CMD_BUILD_ROAD>::Do({DoCommandFlag::Execute, DoCommandFlag::Auto}, tile, GenRandomRoadBits(), rt, DRD_NONE, t->index);
1940 cur_company.Restore();
1941 return true;
1942 }
1943 }
1944 tile = TileAdd(tile, ToTileIndexDiff(ptr));
1945 }
1946 }
1947
1948 cur_company.Restore();
1949 return false;
1950}
1951
1956 void UpdateTownRadius(Town *t)
1957{
1958 static const std::array<std::array<uint32_t, NUM_HOUSE_ZONES>, 23> _town_squared_town_zone_radius_data = {{
1959 { 4, 0, 0, 0, 0}, // 0
1960 { 16, 0, 0, 0, 0},
1961 { 25, 0, 0, 0, 0},
1962 { 36, 0, 0, 0, 0},
1963 { 49, 0, 4, 0, 0},
1964 { 64, 0, 4, 0, 0}, // 20
1965 { 64, 0, 9, 0, 1},
1966 { 64, 0, 9, 0, 4},
1967 { 64, 0, 16, 0, 4},
1968 { 81, 0, 16, 0, 4},
1969 { 81, 0, 16, 0, 4}, // 40
1970 { 81, 0, 25, 0, 9},
1971 { 81, 36, 25, 0, 9},
1972 { 81, 36, 25, 16, 9},
1973 { 81, 49, 0, 25, 9},
1974 { 81, 64, 0, 25, 9}, // 60
1975 { 81, 64, 0, 36, 9},
1976 { 81, 64, 0, 36, 16},
1977 {100, 81, 0, 49, 16},
1978 {100, 81, 0, 49, 25},
1979 {121, 81, 0, 49, 25}, // 80
1980 {121, 81, 0, 49, 25},
1981 {121, 81, 0, 49, 36}, // 88
1982 }};
1983
1984 if (t->cache.num_houses < std::size(_town_squared_town_zone_radius_data) * 4) {
1985 t->cache.squared_town_zone_radius = _town_squared_town_zone_radius_data[t->cache.num_houses / 4];
1986 } else {
1987 int mass = t->cache.num_houses / 8;
1988 /* Actually we are proportional to sqrt() but that's right because we are covering an area.
1989 * The offsets are to make sure the radii do not decrease in size when going from the table
1990 * to the calculated value.*/
1991 t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownEdge)] = mass * 15 - 40;
1992 t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownOutskirt)] = mass * 9 - 15;
1993 t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownOuterSuburb)] = 0;
1994 t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownInnerSuburb)] = mass * 5 - 5;
1995 t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownCentre)] = mass * 3 + 5;
1996 }
1997}
1998
2003 void UpdateTownMaxPass(Town *t)
2004{
2005 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_PASSENGERS]) {
2006 uint32_t production = ScaleByCargoScale(t->cache.population >> 3, true);
2007 if (production == 0) continue;
2008
2009 auto &supplied = t->GetOrCreateCargoSupplied(cs->Index());
2010 supplied.history[LAST_MONTH].production = production;
2011 }
2012
2013 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_MAIL]) {
2014 uint32_t production = ScaleByCargoScale(t->cache.population >> 4, true);
2015 if (production == 0) continue;
2016
2017 auto &supplied = t->GetOrCreateCargoSupplied(cs->Index());
2018 supplied.history[LAST_MONTH].production = production;
2019 }
2020}
2021
2022static void UpdateTownGrowthRate(Town *t);
2023static void UpdateTownGrowth(Town *t);
2024
2036 static void DoCreateTown(Town *t, TileIndex tile, uint32_t townnameparts, TownSize size, bool city, TownLayout layout, bool manual)
2037{
2038 AutoRestoreBackup backup(_generating_town, true);
2039
2040 t->xy = tile;
2041 t->cache.num_houses = 0;
2042 t->time_until_rebuild = 10;
2043 UpdateTownRadius(t);
2044 t->flags.Reset();
2045 t->cache.population = 0;
2046 InitializeBuildingCounts(t);
2047 /* Spread growth across ticks so even if there are many
2048 * similar towns they're unlikely to grow all in one tick */
2049 t->grow_counter = t->index % Ticks::TOWN_GROWTH_TICKS;
2050 t->growth_rate = TownTicksToGameTicks(250);
2051 t->show_zone = false;
2052
2053 _town_kdtree.Insert(t->index);
2054
2055 /* Set the default cargo requirement for town growth */
2056 switch (_settings_game.game_creation.landscape) {
2057 case LandscapeType::Arctic:
2058 if (FindFirstCargoWithTownAcceptanceEffect(TAE_FOOD) != nullptr) t->goal[TAE_FOOD] = TOWN_GROWTH_WINTER;
2059 break;
2060
2061 case LandscapeType::Tropic:
2062 if (FindFirstCargoWithTownAcceptanceEffect(TAE_FOOD) != nullptr) t->goal[TAE_FOOD] = TOWN_GROWTH_DESERT;
2063 if (FindFirstCargoWithTownAcceptanceEffect(TAE_WATER) != nullptr) t->goal[TAE_WATER] = TOWN_GROWTH_DESERT;
2064 break;
2065
2066 default:
2067 break;
2068 }
2069
2070 t->fund_buildings_months = 0;
2071
2072 for (uint i = 0; i != MAX_COMPANIES; i++) t->ratings[i] = RATING_INITIAL;
2073
2074 t->have_ratings = {};
2075 t->exclusivity = CompanyID::Invalid();
2076 t->exclusive_counter = 0;
2077 t->statues = {};
2078
2079 {
2080 TownNameParams tnp(_settings_game.game_creation.town_name);
2081 t->townnamegrfid = tnp.grfid;
2082 t->townnametype = tnp.type;
2083 }
2084 t->townnameparts = townnameparts;
2085
2086 t->InitializeLayout(layout);
2087
2088 t->larger_town = city;
2089
2090 int x = (int)size * 16 + 3;
2091 if (size == TSZ_RANDOM) x = (Random() & 0xF) + 8;
2092 /* Don't create huge cities when founding town in-game */
2093 if (city && (!manual || _game_mode == GM_EDITOR)) x *= _settings_game.economy.initial_city_size;
2094
2095 t->cache.num_houses += x;
2096 UpdateTownRadius(t);
2097
2098 int i = x * 4;
2099 do {
2100 GrowTown(t, {TownExpandMode::Buildings, TownExpandMode::Roads});
2101 } while (--i);
2102
2103 t->UpdateVirtCoord();
2104 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_REBUILD);
2105
2106 t->cache.num_houses -= x;
2107 UpdateTownRadius(t);
2108 UpdateTownGrowthRate(t);
2109 UpdateTownMaxPass(t);
2110 UpdateAirportsNoise();
2111}
2112
2119 static CommandCost TownCanBePlacedHere(TileIndex tile, bool check_surrounding)
2120{
2121 /* Check if too close to the edge of map */
2122 if (DistanceFromEdge(tile) < 12) {
2123 return CommandCost(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB);
2124 }
2125
2126 /* Check distance to all other towns. */
2127 if (IsCloseToTown(tile, 20)) {
2128 return CommandCost(STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN);
2129 }
2130
2131 /* Can only build on clear flat areas, possibly with trees. */
2132 if ((!IsTileType(tile, MP_CLEAR) && !IsTileType(tile, MP_TREES)) || !IsTileFlat(tile)) {
2133 return CommandCost(STR_ERROR_SITE_UNSUITABLE);
2134 }
2135
2136 /* We might want to make sure the town has enough room. */
2137 if (check_surrounding) {
2138 constexpr uint SEARCH_DIAMETER = 5; // Center tile of town + 2 tile radius.
2139 /* Half of the tiles in the search must be valid for the town to build upon. */
2140 constexpr uint VALID_TILE_GOAL = (SEARCH_DIAMETER * SEARCH_DIAMETER) / 2;
2141 uint counter = 0;
2142 int town_height = GetTileZ(tile);
2143 for (TileIndex t : SpiralTileSequence(tile, SEARCH_DIAMETER)) {
2144 if (counter == VALID_TILE_GOAL) break;
2145
2146 switch (GetTileType(t)) {
2147 case MP_CLEAR:
2148 /* Don't allow rough tiles, as they are likely wetlands. */
2149 if (GetClearGround(t) == CLEAR_ROUGH) continue;
2150 break;
2151
2152 case MP_TREES:
2153 /* Don't allow rough trees, as they are likely wetlands. */
2154 if (GetTreeGround(t) == TREE_GROUND_ROUGH) continue;
2155 break;
2156
2157 default:
2158 continue;
2159 }
2160
2161 bool elevation_similar = (GetTileMaxZ(t) <= town_height + 1) && (GetTileZ(t) >= town_height - 1);
2162 if (elevation_similar) counter++;
2163 }
2164
2165 if (counter < VALID_TILE_GOAL) return CommandCost(STR_ERROR_SITE_UNSUITABLE);
2166 }
2167
2168 return CommandCost(EXPENSES_OTHER);
2169}
2170
2176 static bool IsUniqueTownName(const std::string &name)
2177{
2178 for (const Town *t : Town::Iterate()) {
2179 if (!t->name.empty() && t->name == name) return false;
2180 }
2181
2182 return true;
2183}
2184
2197std::tuple<CommandCost, Money, TownID> CmdFoundTown(DoCommandFlags flags, TileIndex tile, TownSize size, bool city, TownLayout layout, bool random_location, uint32_t townnameparts, const std::string &text)
2198{
2199 TownNameParams par(_settings_game.game_creation.town_name);
2200
2201 if (size >= TSZ_END) return { CMD_ERROR, 0, TownID::Invalid() };
2202 if (layout >= NUM_TLS) return { CMD_ERROR, 0, TownID::Invalid() };
2203
2204 /* Some things are allowed only in the scenario editor and for game scripts. */
2205 if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY) {
2206 if (_settings_game.economy.found_town == TF_FORBIDDEN) return { CMD_ERROR, 0, TownID::Invalid() };
2207 if (size == TSZ_LARGE) return { CMD_ERROR, 0, TownID::Invalid() };
2208 if (random_location) return { CMD_ERROR, 0, TownID::Invalid() };
2209 if (_settings_game.economy.found_town != TF_CUSTOM_LAYOUT && layout != _settings_game.economy.town_layout) {
2210 return { CMD_ERROR, 0, TownID::Invalid() };
2211 }
2212 } else if (_current_company == OWNER_DEITY && random_location) {
2213 /* Random parameter is not allowed for Game Scripts. */
2214 return { CMD_ERROR, 0, TownID::Invalid() };
2215 }
2216
2217 if (text.empty()) {
2218 /* If supplied name is empty, townnameparts has to generate unique automatic name */
2219 if (!VerifyTownName(townnameparts, &par)) return { CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE), 0, TownID::Invalid() };
2220 } else {
2221 /* If name is not empty, it has to be unique custom name */
2222 if (Utf8StringLength(text) >= MAX_LENGTH_TOWN_NAME_CHARS) return { CMD_ERROR, 0, TownID::Invalid() };
2223 if (!IsUniqueTownName(text)) return { CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE), 0, TownID::Invalid() };
2224 }
2225
2226 /* Allocate town struct */
2227 if (!Town::CanAllocateItem()) return { CommandCost(STR_ERROR_TOO_MANY_TOWNS), 0, TownID::Invalid() };
2228
2229 if (!random_location) {
2230 CommandCost ret = TownCanBePlacedHere(tile, false);
2231 if (ret.Failed()) return { ret, 0, TownID::Invalid() };
2232 }
2233
2234 static const uint8_t price_mult[][TSZ_RANDOM + 1] = {{ 15, 25, 40, 25 }, { 20, 35, 55, 35 }};
2235 /* multidimensional arrays have to have defined length of non-first dimension */
2236 static_assert(lengthof(price_mult[0]) == 4);
2237
2238 CommandCost cost(EXPENSES_OTHER, _price[PR_BUILD_TOWN]);
2239 uint8_t mult = price_mult[city][size];
2240
2241 cost.MultiplyCost(mult);
2242
2243 /* Create the town */
2244 TownID new_town = TownID::Invalid();
2245 if (flags.Test(DoCommandFlag::Execute)) {
2246 if (cost.GetCost() > GetAvailableMoneyForCommand()) {
2247 return { CommandCost(EXPENSES_OTHER), cost.GetCost(), TownID::Invalid() };
2248 }
2249
2250 Backup<bool> old_generating_world(_generating_world, true);
2251 UpdateNearestTownForRoadTiles(true);
2252 Town *t;
2253 if (random_location) {
2254 t = CreateRandomTown(20, townnameparts, size, city, layout);
2255 } else {
2256 t = new Town(tile);
2257 DoCreateTown(t, tile, townnameparts, size, city, layout, true);
2258 }
2259
2260 UpdateNearestTownForRoadTiles(false);
2261 old_generating_world.Restore();
2262
2263 if (t == nullptr) return { CommandCost(STR_ERROR_NO_SPACE_FOR_TOWN), 0, TownID::Invalid() };
2264
2265 new_town = t->index;
2266
2267 if (!text.empty()) {
2268 t->name = text;
2269 t->UpdateVirtCoord();
2270 }
2271
2272 if (_game_mode != GM_EDITOR) {
2273 /* 't' can't be nullptr since 'random' is false outside scenedit */
2274 assert(!random_location);
2275
2276 if (_current_company == OWNER_DEITY) {
2277 AddTileNewsItem(GetEncodedString(STR_NEWS_NEW_TOWN_UNSPONSORED, t->index), NewsType::IndustryOpen, tile);
2278 } else {
2279 std::string company_name = GetString(STR_COMPANY_NAME, _current_company);
2280 AddTileNewsItem(GetEncodedString(STR_NEWS_NEW_TOWN, company_name, t->index), NewsType::IndustryOpen, tile);
2281 }
2282 AI::BroadcastNewEvent(new ScriptEventTownFounded(t->index));
2283 Game::NewEvent(new ScriptEventTownFounded(t->index));
2284 }
2285 }
2286 return { cost, 0, new_town };
2287}
2288
2298 static TileIndex AlignTileToGrid(TileIndex tile, TownLayout layout)
2299{
2300 switch (layout) {
2301 case TL_2X2_GRID: return TileXY(TileX(tile) - TileX(tile) % 3, TileY(tile) - TileY(tile) % 3);
2302 case TL_3X3_GRID: return TileXY(TileX(tile) & ~3, TileY(tile) & ~3);
2303 default: return tile;
2304 }
2305}
2306
2316 static bool IsTileAlignedToGrid(TileIndex tile, TownLayout layout)
2317{
2318 switch (layout) {
2319 case TL_2X2_GRID: return TileX(tile) % 3 == 0 && TileY(tile) % 3 == 0;
2320 case TL_3X3_GRID: return TileX(tile) % 4 == 0 && TileY(tile) % 4 == 0;
2321 default: return true;
2322 }
2323}
2324
2337 static TileIndex FindNearestGoodCoastalTownSpot(TileIndex tile, TownLayout layout)
2338{
2339 for (auto coast : SpiralTileSequence(tile, 40)) {
2340 /* Find nearest land tile */
2341 if (!IsTileType(coast, MP_CLEAR)) continue;
2342
2343 TileIndex furthest = INVALID_TILE;
2344 uint max_dist = 0;
2345 for (auto test : SpiralTileSequence(coast, 10)) {
2346 if (!IsTileType(test, MP_CLEAR) || !IsTileFlat(test) || !IsTileAlignedToGrid(test, layout)) continue;
2347 if (TownCanBePlacedHere(test, true).Failed()) continue;
2348
2349 uint dist = GetClosestWaterDistance(test, true);
2350 if (dist > max_dist) {
2351 furthest = test;
2352 max_dist = dist;
2353 }
2354 }
2355 return furthest;
2356 }
2357
2358 /* if we get here just give up */
2359 return INVALID_TILE;
2360}
2361
2366 HouseZones GetClimateMaskForLandscape()
2367{
2368 switch (_settings_game.game_creation.landscape) {
2369 case LandscapeType::Temperate: return HouseZone::ClimateTemperate;
2370 case LandscapeType::Arctic: return {HouseZone::ClimateSubarcticAboveSnow, HouseZone::ClimateSubarcticBelowSnow};
2371 case LandscapeType::Tropic: return HouseZone::ClimateSubtropic;
2372 case LandscapeType::Toyland: return HouseZone::ClimateToyland;
2373 default: NOT_REACHED();
2374 }
2375}
2376
2386 static Town *CreateRandomTown(uint attempts, uint32_t townnameparts, TownSize size, bool city, TownLayout layout)
2387{
2388 assert(_game_mode == GM_EDITOR || _generating_world); // These are the preconditions for CMD_DELETE_TOWN
2389
2390 if (!Town::CanAllocateItem()) return nullptr;
2391
2392 do {
2393 /* Generate a tile index not too close from the edge */
2394 TileIndex tile = AlignTileToGrid(RandomTile(), layout);
2395
2396 /* If we tried to place the town on water, find a suitable land tile nearby.
2397 * Otherwise, evaluate the land tile. */
2398 if (IsTileType(tile, MP_WATER)) {
2399 tile = FindNearestGoodCoastalTownSpot(tile, layout);
2400 if (tile == INVALID_TILE) continue;
2401 } else if (TownCanBePlacedHere(tile, true).Failed()) continue;
2402
2403 /* Allocate a town struct */
2404 Town *t = new Town(tile);
2405
2406 DoCreateTown(t, tile, townnameparts, size, city, layout, false);
2407
2408 /* if the population is still 0 at the point, then the
2409 * placement is so bad it couldn't grow at all */
2410 if (t->cache.population > 0) return t;
2411
2412 Backup<CompanyID> cur_company(_current_company, OWNER_TOWN);
2413 [[maybe_unused]] CommandCost rc = Command<CMD_DELETE_TOWN>::Do(DoCommandFlag::Execute, t->index);
2414 cur_company.Restore();
2415 assert(rc.Succeeded());
2416
2417 /* We already know that we can allocate a single town when
2418 * entering this function. However, we create and delete
2419 * a town which "resets" the allocation checks. As such we
2420 * need to check again when assertions are enabled. */
2421 assert(Town::CanAllocateItem());
2422 } while (--attempts != 0);
2423
2424 return nullptr;
2425}
2426
2432uint GetDefaultTownsForMapSize()
2433{
2434 static const uint8_t num_initial_towns[4] = {5, 11, 23, 46}; // very low, low, normal, high
2435 if (_settings_game.difficulty.number_towns == static_cast<uint>(CUSTOM_TOWN_NUMBER_DIFFICULTY)) {
2436 return _settings_newgame.game_creation.custom_town_number;
2437 }
2438 return Map::ScaleBySize(num_initial_towns[_settings_game.difficulty.number_towns]);
2439}
2440
2448 bool GenerateTowns(TownLayout layout, std::optional<uint> number)
2449{
2450 uint current_number = 0;
2451 uint total;
2452 if (number.has_value()) {
2453 total = number.value();
2454 } else if (_settings_game.difficulty.number_towns == static_cast<uint>(CUSTOM_TOWN_NUMBER_DIFFICULTY)) {
2455 total = GetDefaultTownsForMapSize();
2456 } else {
2457 total = Map::ScaleByLandProportion(GetDefaultTownsForMapSize() + (Random() & 7));
2458 }
2459
2460 total = Clamp<uint>(total, 1, TownPool::MAX_SIZE);
2461 uint32_t townnameparts;
2462 TownNames town_names;
2463
2464 SetGeneratingWorldProgress(GWP_TOWN, total);
2465
2466 /* Pre-populate the town names list with the names of any towns already on the map */
2467 for (const Town *town : Town::Iterate()) {
2468 town_names.insert(town->GetCachedName());
2469 }
2470
2471 /* Randomised offset for city status. This means with e.g. 1-in-4 towns being cities, a map with 10 towns
2472 * may have 2 or 3 cities, instead of always 3. */
2473 uint city_random_offset = _settings_game.economy.larger_towns == 0 ? 0 : (Random() % _settings_game.economy.larger_towns);
2474
2475 /* First attempt will be made at creating the suggested number of towns.
2476 * Note that this is really a suggested value, not a required one.
2477 * We would not like the system to lock up just because the user wanted 100 cities on a 64*64 map, would we? */
2478 do {
2479 bool city = (_settings_game.economy.larger_towns != 0 && ((city_random_offset + current_number) % _settings_game.economy.larger_towns) == 0);
2480 IncreaseGeneratingWorldProgress(GWP_TOWN);
2481 /* Get a unique name for the town. */
2482 if (!GenerateTownName(_random, &townnameparts, &town_names)) continue;
2483 /* try 20 times to create a random-sized town for the first loop. */
2484 if (CreateRandomTown(20, townnameparts, TSZ_RANDOM, city, layout) != nullptr) current_number++; // If creation was successful, raise a flag.
2485 } while (--total);
2486
2487 town_names.clear();
2488
2489 /* Build the town k-d tree again to make sure it's well balanced */
2490 RebuildTownKdtree();
2491
2492 if (current_number != 0) return true;
2493
2494 /* If current_number is still zero at this point, it means that not a single town has been created.
2495 * So give it a last try, but now more aggressive */
2496 if (GenerateTownName(_random, &townnameparts) &&
2497 CreateRandomTown(10000, townnameparts, TSZ_RANDOM, _settings_game.economy.larger_towns != 0, layout) != nullptr) {
2498 return true;
2499 }
2500
2501 /* If there are no towns at all and we are generating new game, bail out */
2502 if (Town::GetNumItems() == 0 && _game_mode != GM_EDITOR) {
2503 ShowErrorMessage(GetEncodedString(STR_ERROR_COULD_NOT_CREATE_TOWN), {}, WL_CRITICAL);
2504 }
2505
2506 return false; // we are still without a town? we failed, simply
2507}
2508
2509
2516 HouseZone GetTownRadiusGroup(const Town *t, TileIndex tile)
2517{
2518 uint dist = DistanceSquare(tile, t->xy);
2519
2520 if (t->fund_buildings_months != 0 && dist <= 25) return HouseZone::TownCentre;
2521
2522 HouseZone smallest = HouseZone::TownEdge;
2523 for (HouseZone i : HZ_ZONE_ALL) {
2524 if (dist < t->cache.squared_town_zone_radius[to_underlying(i)]) smallest = i;
2525 }
2526
2527 return smallest;
2528}
2529
2541 static inline void ClearMakeHouseTile(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool is_protected)
2542{
2543 [[maybe_unused]] CommandCost cc = Command<CMD_LANDSCAPE_CLEAR>::Do({DoCommandFlag::Execute, DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile);
2544 assert(cc.Succeeded());
2545
2546 IncreaseBuildingCount(t, type);
2547 MakeHouseTile(tile, t->index, counter, stage, type, random_bits, is_protected);
2548 if (HouseSpec::Get(type)->building_flags.Test(BuildingFlag::IsAnimated)) AddAnimatedTile(tile, false);
2549
2550 MarkTileDirtyByTile(tile);
2551}
2552
2553
2565 static void MakeTownHouse(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool is_protected)
2566{
2567 BuildingFlags size = HouseSpec::Get(type)->building_flags;
2568
2569 ClearMakeHouseTile(tile, t, counter, stage, type, random_bits, is_protected);
2570 if (size.Any(BUILDING_2_TILES_Y)) ClearMakeHouseTile(tile + TileDiffXY(0, 1), t, counter, stage, ++type, random_bits, is_protected);
2571 if (size.Any(BUILDING_2_TILES_X)) ClearMakeHouseTile(tile + TileDiffXY(1, 0), t, counter, stage, ++type, random_bits, is_protected);
2572 if (size.Any(BUILDING_HAS_4_TILES)) ClearMakeHouseTile(tile + TileDiffXY(1, 1), t, counter, stage, ++type, random_bits, is_protected);
2573
2574 ForAllStationsAroundTiles(TileArea(tile, size.Any(BUILDING_2_TILES_X) ? 2 : 1, size.Any(BUILDING_2_TILES_Y) ? 2 : 1), [t](Station *st, TileIndex) {
2575 t->stations_near.insert(st);
2576 return true;
2577 });
2578}
2579
2580
2587 static inline bool CanBuildHouseHere(TileIndex tile, bool noslope)
2588{
2589 /* cannot build on these slopes... */
2590 Slope slope = GetTileSlope(tile);
2591 if ((noslope && slope != SLOPE_FLAT) || IsSteepSlope(slope)) return false;
2592
2593 /* at least one RoadTypes allow building the house here? */
2594 if (!RoadTypesAllowHouseHere(tile)) return false;
2595
2596 /* building under a bridge? */
2597 if (IsBridgeAbove(tile)) return false;
2598
2599 /* can we clear the land? */
2600 return Command<CMD_LANDSCAPE_CLEAR>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile).Succeeded();
2601}
2602
2603
2612 static inline bool CheckBuildHouseSameZ(TileIndex tile, int z, bool noslope)
2613{
2614 if (!CanBuildHouseHere(tile, noslope)) return false;
2615
2616 /* if building on slopes is allowed, there will be flattening foundation (to tile max z) */
2617 if (GetTileMaxZ(tile) != z) return false;
2618
2619 return true;
2620}
2621
2622
2631 static bool CheckFree2x2Area(TileIndex tile, int z, bool noslope)
2632{
2633 /* we need to check this tile too because we can be at different tile now */
2634 if (!CheckBuildHouseSameZ(tile, z, noslope)) return false;
2635
2636 for (DiagDirection d = DIAGDIR_SE; d < DIAGDIR_END; d++) {
2637 tile += TileOffsByDiagDir(d);
2638 if (!CheckBuildHouseSameZ(tile, z, noslope)) return false;
2639 }
2640
2641 return true;
2642}
2643
2644
2652 static inline bool TownLayoutAllowsHouseHere(Town *t, TileIndex tile, TownExpandModes modes)
2653{
2654 if (!modes.Test(TownExpandMode::Buildings)) return false;
2655
2656 /* Allow towns everywhere when we don't build roads */
2657 if (!TownAllowedToBuildRoads(modes)) return true;
2658
2659 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
2660
2661 switch (t->layout) {
2662 case TL_2X2_GRID:
2663 if ((grid_pos.x % 3) == 0 || (grid_pos.y % 3) == 0) return false;
2664 break;
2665
2666 case TL_3X3_GRID:
2667 if ((grid_pos.x % 4) == 0 || (grid_pos.y % 4) == 0) return false;
2668 break;
2669
2670 default:
2671 break;
2672 }
2673
2674 return true;
2675}
2676
2677
2685 static inline bool TownLayoutAllows2x2HouseHere(Town *t, TileIndex tile, TownExpandModes modes)
2686{
2687 if (!modes.Test(TownExpandMode::Buildings)) return false;
2688
2689 /* Allow towns everywhere when we don't build roads */
2690 if (!TownAllowedToBuildRoads(modes)) return true;
2691
2692 /* Compute relative position of tile. (Positive offsets are towards north) */
2693 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
2694
2695 switch (t->layout) {
2696 case TL_2X2_GRID:
2697 grid_pos.x %= 3;
2698 grid_pos.y %= 3;
2699 if ((grid_pos.x != 2 && grid_pos.x != -1) ||
2700 (grid_pos.y != 2 && grid_pos.y != -1)) return false;
2701 break;
2702
2703 case TL_3X3_GRID:
2704 if ((grid_pos.x & 3) < 2 || (grid_pos.y & 3) < 2) return false;
2705 break;
2706
2707 default:
2708 break;
2709 }
2710
2711 return true;
2712}
2713
2714
2724 static bool CheckTownBuild2House(TileIndex *tile, Town *t, int maxz, bool noslope, DiagDirection second, TownExpandModes modes)
2725{
2726 /* 'tile' is already checked in BuildTownHouse() - CanBuildHouseHere() and slope test */
2727
2728 TileIndex tile2 = *tile + TileOffsByDiagDir(second);
2729 if (TownLayoutAllowsHouseHere(t, tile2, modes) && CheckBuildHouseSameZ(tile2, maxz, noslope)) return true;
2730
2731 tile2 = *tile + TileOffsByDiagDir(ReverseDiagDir(second));
2732 if (TownLayoutAllowsHouseHere(t, tile2, modes) && CheckBuildHouseSameZ(tile2, maxz, noslope)) {
2733 *tile = tile2;
2734 return true;
2735 }
2736
2737 return false;
2738}
2739
2740
2749 static bool CheckTownBuild2x2House(TileIndex *tile, Town *t, int maxz, bool noslope, TownExpandModes modes)
2750{
2751 TileIndex tile2 = *tile;
2752
2753 for (DiagDirection d = DIAGDIR_SE;; d++) { // 'd' goes through DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_END
2754 if (TownLayoutAllows2x2HouseHere(t, tile2, modes) && CheckFree2x2Area(tile2, maxz, noslope)) {
2755 *tile = tile2;
2756 return true;
2757 }
2758 if (d == DIAGDIR_END) break;
2759 tile2 += TileOffsByDiagDir(ReverseDiagDir(d)); // go clockwise
2760 }
2761
2762 return false;
2763}
2764
2775 static void BuildTownHouse(Town *t, TileIndex tile, const HouseSpec *hs, HouseID house, uint8_t random_bits, bool house_completed, bool is_protected)
2776{
2777 /* build the house */
2778 t->cache.num_houses++;
2779
2780 uint8_t construction_counter = 0;
2781 uint8_t construction_stage = 0;
2782
2783 if (_generating_world || _game_mode == GM_EDITOR || house_completed) {
2784 uint32_t construction_random = Random();
2785
2786 construction_stage = TOWN_HOUSE_COMPLETED;
2787 if (_generating_world && !hs->extra_flags.Test(HouseExtraFlag::BuildingIsHistorical) && Chance16(1, 7)) construction_stage = GB(construction_random, 0, 2);
2788
2789 if (construction_stage == TOWN_HOUSE_COMPLETED) {
2790 ChangePopulation(t, hs->population);
2791 } else {
2792 construction_counter = GB(construction_random, 2, 2);
2793 }
2794 }
2795
2796 MakeTownHouse(tile, t, construction_counter, construction_stage, house, random_bits, is_protected);
2797 UpdateTownRadius(t);
2798 UpdateTownGrowthRate(t);
2799
2800 BuildingFlags size = hs->building_flags;
2801
2802 TriggerHouseAnimation_ConstructionStageChanged(tile, true);
2803 if (size.Any(BUILDING_2_TILES_Y)) TriggerHouseAnimation_ConstructionStageChanged(tile + TileDiffXY(0, 1), true);
2804 if (size.Any(BUILDING_2_TILES_X)) TriggerHouseAnimation_ConstructionStageChanged(tile + TileDiffXY(1, 0), true);
2805 if (size.Any(BUILDING_HAS_4_TILES)) TriggerHouseAnimation_ConstructionStageChanged(tile + TileDiffXY(1, 1), true);
2806}
2807
2814 static bool TryBuildTownHouse(Town *t, TileIndex tile, TownExpandModes modes)
2815{
2816 /* forbidden building here by town layout */
2817 if (!TownLayoutAllowsHouseHere(t, tile, modes)) return false;
2818
2819 /* no house allowed at all, bail out */
2820 if (!CanBuildHouseHere(tile, false)) return false;
2821
2822 Slope slope = GetTileSlope(tile);
2823 int maxz = GetTileMaxZ(tile);
2824
2825 /* Get the town zone type of the current tile, as well as the climate.
2826 * This will allow to easily compare with the specs of the new house to build */
2827 HouseZones zones = GetTownRadiusGroup(t, tile);
2828
2829 switch (_settings_game.game_creation.landscape) {
2830 case LandscapeType::Temperate: zones.Set(HouseZone::ClimateTemperate); break;
2831 case LandscapeType::Arctic: zones.Set(maxz > HighestSnowLine() ? HouseZone::ClimateSubarcticAboveSnow : HouseZone::ClimateSubarcticBelowSnow); break;
2832 case LandscapeType::Tropic: zones.Set(HouseZone::ClimateSubtropic); break;
2833 case LandscapeType::Toyland: zones.Set(HouseZone::ClimateToyland); break;
2834 }
2835
2836 /* bits 0-4 are used
2837 * bits 11-15 are used
2838 * bits 5-10 are not used. */
2839 static std::vector<std::pair<HouseID, uint>> probs;
2840 probs.clear();
2841
2842 uint probability_max = 0;
2843
2844 /* Generate a list of all possible houses that can be built. */
2845 for (const auto &hs : HouseSpec::Specs()) {
2846 /* Verify that the candidate house spec matches the current tile status */
2847 if (!hs.building_availability.All(zones) || !hs.enabled || hs.grf_prop.override_id != INVALID_HOUSE_ID) continue;
2848
2849 /* Don't let these counters overflow. Global counters are 32bit, there will never be that many houses. */
2850 if (hs.class_id != HOUSE_NO_CLASS) {
2851 /* id_count is always <= class_count, so it doesn't need to be checked */
2852 if (t->cache.building_counts.class_count[hs.class_id] == UINT16_MAX) continue;
2853 } else {
2854 /* If the house has no class, check id_count instead */
2855 if (t->cache.building_counts.id_count[hs.Index()] == UINT16_MAX) continue;
2856 }
2857
2858 uint cur_prob = hs.probability;
2859 probability_max += cur_prob;
2860 probs.emplace_back(hs.Index(), cur_prob);
2861 }
2862
2863 TileIndex base_tile = tile;
2864
2865 while (probability_max > 0) {
2866 /* Building a multitile building can change the location of tile.
2867 * The building would still be built partially on that tile, but
2868 * its northern tile would be elsewhere. However, if the callback
2869 * fails we would be basing further work from the changed tile.
2870 * So a next 1x1 tile building could be built on the wrong tile. */
2871 tile = base_tile;
2872
2873 uint r = RandomRange(probability_max);
2874 uint i;
2875 for (i = 0; i < probs.size(); i++) {
2876 if (probs[i].second > r) break;
2877 r -= probs[i].second;
2878 }
2879
2880 HouseID house = probs[i].first;
2881 probability_max -= probs[i].second;
2882
2883 /* remove tested house from the set */
2884 probs[i] = probs.back();
2885 probs.pop_back();
2886
2887 const HouseSpec *hs = HouseSpec::Get(house);
2888
2889 if (!_generating_world && _game_mode != GM_EDITOR && hs->extra_flags.Test(HouseExtraFlag::BuildingIsHistorical)) {
2890 continue;
2891 }
2892
2893 if (TimerGameCalendar::year < hs->min_year || TimerGameCalendar::year > hs->max_year) continue;
2894
2895 /* Special houses that there can be only one of. */
2896 TownFlags oneof{};
2897
2898 if (hs->building_flags.Test(BuildingFlag::IsChurch)) {
2899 oneof.Set(TownFlag::HasChurch);
2900 } else if (hs->building_flags.Test(BuildingFlag::IsStadium)) {
2901 oneof.Set(TownFlag::HasStadium);
2902 }
2903
2904 if (t->flags.Any(oneof)) continue;
2905
2906 /* Make sure there is no slope? */
2907 bool noslope = hs->building_flags.Test(BuildingFlag::NotSloped);
2908 if (noslope && slope != SLOPE_FLAT) continue;
2909
2910 if (hs->building_flags.Test(BuildingFlag::Size2x2)) {
2911 if (!CheckTownBuild2x2House(&tile, t, maxz, noslope, modes)) continue;
2912 } else if (hs->building_flags.Test(BuildingFlag::Size2x1)) {
2913 if (!CheckTownBuild2House(&tile, t, maxz, noslope, DIAGDIR_SW, modes)) continue;
2914 } else if (hs->building_flags.Test(BuildingFlag::Size1x2)) {
2915 if (!CheckTownBuild2House(&tile, t, maxz, noslope, DIAGDIR_SE, modes)) continue;
2916 } else {
2917 /* 1x1 house checks are already done */
2918 }
2919
2920 uint8_t random_bits = Random();
2921
2922 if (hs->callback_mask.Test(HouseCallbackMask::AllowConstruction)) {
2923 uint16_t callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile, {}, true, random_bits);
2924 if (callback_res != CALLBACK_FAILED && !Convert8bitBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_ALLOW_CONSTRUCTION, callback_res)) continue;
2925 }
2926
2927 /* Special houses that there can be only one of. */
2928 t->flags.Set(oneof);
2929
2930 BuildTownHouse(t, tile, hs, house, random_bits, false, hs->extra_flags.Test(HouseExtraFlag::BuildingIsProtected));
2931
2932 return true;
2933 }
2934
2935 return false;
2936}
2937
2947 CommandCost CmdPlaceHouse(DoCommandFlags flags, TileIndex tile, HouseID house, bool is_protected, bool replace)
2948{
2949 if (_game_mode != GM_EDITOR && _settings_game.economy.place_houses == PH_FORBIDDEN) return CMD_ERROR;
2950
2951 if (Town::GetNumItems() == 0) return CommandCost(STR_ERROR_MUST_FOUND_TOWN_FIRST);
2952
2953 if (static_cast<size_t>(house) >= HouseSpec::Specs().size()) return CMD_ERROR;
2954 const HouseSpec *hs = HouseSpec::Get(house);
2955 if (!hs->enabled) return CMD_ERROR;
2956
2957 int maxz = GetTileMaxZ(tile);
2958
2959 /* Check each tile of a multi-tile house. */
2960 TileArea ta(tile, 1, 1);
2961 if (hs->building_flags.Test(BuildingFlag::Size2x2)) ta.Add(TileAddXY(tile, 1, 1));
2962 if (hs->building_flags.Test(BuildingFlag::Size2x1)) ta.Add(TileAddByDiagDir(tile, DIAGDIR_SW));
2963 if (hs->building_flags.Test(BuildingFlag::Size1x2)) ta.Add(TileAddByDiagDir(tile, DIAGDIR_SE));
2964
2965 for (const TileIndex subtile : ta) {
2966 /* Houses cannot be built on steep slopes. */
2967 Slope slope = GetTileSlope(subtile);
2968 if (IsSteepSlope(slope)) return CommandCost(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
2969
2970 /* Houses cannot be built under bridges. */
2971 if (IsBridgeAbove(subtile)) return CommandCost(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
2972
2973 /* Make sure there is no slope? */
2974 bool noslope = hs->building_flags.Test(BuildingFlag::NotSloped);
2975 if (noslope && slope != SLOPE_FLAT) return CommandCost(STR_ERROR_FLAT_LAND_REQUIRED);
2976
2977 /* All tiles of a multi-tile house must have the same z-level. */
2978 if (GetTileMaxZ(subtile) != maxz) return CommandCost(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
2979
2980 /* We might be replacing an existing house, otherwise check if we can clear land. */
2981 if (!(replace && GetTileType(subtile) == MP_HOUSE)) {
2982 CommandCost cost = Command<CMD_LANDSCAPE_CLEAR>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, subtile);
2983 if (!cost.Succeeded()) return cost;
2984 }
2985 }
2986
2987 if (flags.Test(DoCommandFlag::Execute)) {
2988 /* If replacing, clear any existing houses first. */
2989 if (replace) {
2990 for (const TileIndex &subtile : ta) {
2991 if (GetTileType(subtile) == MP_HOUSE) ClearTownHouse(Town::GetByTile(subtile), subtile);
2992 }
2993 }
2994
2995 Town *t = ClosestTownFromTile(tile, UINT_MAX);
2996 bool house_completed = _settings_game.economy.place_houses == PH_ALLOWED_CONSTRUCTED;
2997 BuildTownHouse(t, tile, hs, house, Random(), house_completed, is_protected);
2998 }
2999
3000 return CommandCost();
3001}
3002
3009 static void DoClearTownHouseHelper(TileIndex tile, Town *t, HouseID house)
3010{
3011 assert(IsTileType(tile, MP_HOUSE));
3012 DecreaseBuildingCount(t, house);
3013 DoClearSquare(tile);
3014
3015 DeleteNewGRFInspectWindow(GSF_HOUSES, tile.base());
3016}
3017
3025 TileIndexDiff GetHouseNorthPart(HouseID &house)
3026{
3027 if (house >= 3) { // house id 0,1,2 MUST be single tile houses, or this code breaks.
3028 if (HouseSpec::Get(house - 1)->building_flags.Test(BuildingFlag::Size2x1)) {
3029 house--;
3030 return TileDiffXY(-1, 0);
3031 } else if (HouseSpec::Get(house - 1)->building_flags.Any(BUILDING_2_TILES_Y)) {
3032 house--;
3033 return TileDiffXY(0, -1);
3034 } else if (HouseSpec::Get(house - 2)->building_flags.Any(BUILDING_HAS_4_TILES)) {
3035 house -= 2;
3036 return TileDiffXY(-1, 0);
3037 } else if (HouseSpec::Get(house - 3)->building_flags.Any(BUILDING_HAS_4_TILES)) {
3038 house -= 3;
3039 return TileDiffXY(-1, -1);
3040 }
3041 }
3042 return TileDiffXY(0, 0);
3043}
3044
3050 void ClearTownHouse(Town *t, TileIndex tile)
3051{
3052 assert(IsTileType(tile, MP_HOUSE));
3053
3054 HouseID house = GetHouseType(tile);
3055
3056 /* The northernmost tile of the house is the main house. */
3057 tile += GetHouseNorthPart(house);
3058
3059 const HouseSpec *hs = HouseSpec::Get(house);
3060
3061 /* Remove population from the town if the house is finished. */
3062 if (IsHouseCompleted(tile)) {
3063 ChangePopulation(t, -hs->population);
3064 }
3065
3066 t->cache.num_houses--;
3067
3068 /* Clear flags for houses that only may exist once/town. */
3069 if (hs->building_flags.Test(BuildingFlag::IsChurch)) {
3070 t->flags.Reset(TownFlag::HasChurch);
3071 } else if (hs->building_flags.Test(BuildingFlag::IsStadium)) {
3072 t->flags.Reset(TownFlag::HasStadium);
3073 }
3074
3075 /* Do the actual clearing of tiles */
3076 DoClearTownHouseHelper(tile, t, house);
3077 if (hs->building_flags.Any(BUILDING_2_TILES_Y)) DoClearTownHouseHelper(tile + TileDiffXY(0, 1), t, ++house);
3078 if (hs->building_flags.Any(BUILDING_2_TILES_X)) DoClearTownHouseHelper(tile + TileDiffXY(1, 0), t, ++house);
3079 if (hs->building_flags.Any(BUILDING_HAS_4_TILES)) DoClearTownHouseHelper(tile + TileDiffXY(1, 1), t, ++house);
3080
3081 RemoveNearbyStations(t, tile, hs->building_flags);
3082
3083 UpdateTownRadius(t);
3084}
3085
3093 CommandCost CmdRenameTown(DoCommandFlags flags, TownID town_id, const std::string &text)
3094{
3095 Town *t = Town::GetIfValid(town_id);
3096 if (t == nullptr) return CMD_ERROR;
3097
3098 bool reset = text.empty();
3099
3100 if (!reset) {
3101 if (Utf8StringLength(text) >= MAX_LENGTH_TOWN_NAME_CHARS) return CMD_ERROR;
3102 if (!IsUniqueTownName(text)) return CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE);
3103 }
3104
3105 if (flags.Test(DoCommandFlag::Execute)) {
3106 t->cached_name.clear();
3107 if (reset) {
3108 t->name.clear();
3109 } else {
3110 t->name = text;
3111 }
3112
3113 t->UpdateVirtCoord();
3114 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_RESORT);
3115 ClearAllStationCachedNames();
3116 ClearAllIndustryCachedNames();
3117 UpdateAllStationVirtCoords();
3118 }
3119 return CommandCost();
3120}
3121
3127 const CargoSpec *FindFirstCargoWithTownAcceptanceEffect(TownAcceptanceEffect effect)
3128{
3129 for (const CargoSpec *cs : CargoSpec::Iterate()) {
3130 if (cs->town_acceptance_effect == effect) return cs;
3131 }
3132 return nullptr;
3133}
3134
3143 CommandCost CmdTownCargoGoal(DoCommandFlags flags, TownID town_id, TownAcceptanceEffect tae, uint32_t goal)
3144{
3145 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3146
3147 if (tae < TAE_BEGIN || tae >= TAE_END) return CMD_ERROR;
3148
3149 Town *t = Town::GetIfValid(town_id);
3150 if (t == nullptr) return CMD_ERROR;
3151
3152 /* Validate if there is a cargo which is the requested TownEffect */
3153 const CargoSpec *cargo = FindFirstCargoWithTownAcceptanceEffect(tae);
3154 if (cargo == nullptr) return CMD_ERROR;
3155
3156 if (flags.Test(DoCommandFlag::Execute)) {
3157 t->goal[tae] = goal;
3158 UpdateTownGrowth(t);
3159 InvalidateWindowData(WC_TOWN_VIEW, town_id);
3160 }
3161
3162 return CommandCost();
3163}
3164
3172 CommandCost CmdTownSetText(DoCommandFlags flags, TownID town_id, const EncodedString &text)
3173{
3174 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3175 Town *t = Town::GetIfValid(town_id);
3176 if (t == nullptr) return CMD_ERROR;
3177
3178 if (flags.Test(DoCommandFlag::Execute)) {
3179 t->text.clear();
3180 if (!text.empty()) t->text = text;
3181 InvalidateWindowData(WC_TOWN_VIEW, town_id);
3182 }
3183
3184 return CommandCost();
3185}
3186
3194 CommandCost CmdTownGrowthRate(DoCommandFlags flags, TownID town_id, uint16_t growth_rate)
3195{
3196 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3197
3198 Town *t = Town::GetIfValid(town_id);
3199 if (t == nullptr) return CMD_ERROR;
3200
3201 if (flags.Test(DoCommandFlag::Execute)) {
3202 if (growth_rate == 0) {
3203 /* Just clear the flag, UpdateTownGrowth will determine a proper growth rate */
3204 t->flags.Reset(TownFlag::CustomGrowth);
3205 } else {
3206 uint old_rate = t->growth_rate;
3207 if (t->grow_counter >= old_rate) {
3208 /* This also catches old_rate == 0 */
3209 t->grow_counter = growth_rate;
3210 } else {
3211 /* Scale grow_counter, so half finished houses stay half finished */
3212 t->grow_counter = t->grow_counter * growth_rate / old_rate;
3213 }
3214 t->growth_rate = growth_rate;
3215 t->flags.Set(TownFlag::CustomGrowth);
3216 }
3217 UpdateTownGrowth(t);
3218 InvalidateWindowData(WC_TOWN_VIEW, town_id);
3219 }
3220
3221 return CommandCost();
3222}
3223
3232 CommandCost CmdTownRating(DoCommandFlags flags, TownID town_id, CompanyID company_id, int16_t rating)
3233{
3234 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3235
3236 Town *t = Town::GetIfValid(town_id);
3237 if (t == nullptr) return CMD_ERROR;
3238
3239 if (!Company::IsValidID(company_id)) return CMD_ERROR;
3240
3241 int16_t new_rating = Clamp(rating, RATING_MINIMUM, RATING_MAXIMUM);
3242 if (flags.Test(DoCommandFlag::Execute)) {
3243 t->ratings[company_id] = new_rating;
3244 InvalidateWindowData(WC_TOWN_AUTHORITY, town_id);
3245 }
3246
3247 return CommandCost();
3248}
3249
3257 CommandCost CmdExpandTown(DoCommandFlags flags, TownID town_id, uint32_t grow_amount, TownExpandModes modes)
3258{
3259 if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY) return CMD_ERROR;
3260 if (modes.None()) return CMD_ERROR;
3261 Town *t = Town::GetIfValid(town_id);
3262 if (t == nullptr) return CMD_ERROR;
3263
3264 if (flags.Test(DoCommandFlag::Execute)) {
3265 /* The more houses, the faster we grow */
3266 if (grow_amount == 0) {
3267 uint amount = RandomRange(ClampTo<uint16_t>(t->cache.num_houses / 10)) + 3;
3268 t->cache.num_houses += amount;
3269 UpdateTownRadius(t);
3270
3271 uint n = amount * 10;
3272 do GrowTown(t, modes); while (--n);
3273
3274 t->cache.num_houses -= amount;
3275 } else {
3276 for (; grow_amount > 0; grow_amount--) {
3277 /* Try several times to grow, as we are really suppose to grow */
3278 for (uint i = 0; i < 25; i++) if (GrowTown(t, modes)) break;
3279 }
3280 }
3281 UpdateTownRadius(t);
3282
3283 UpdateTownMaxPass(t);
3284 }
3285
3286 return CommandCost();
3287}
3288
3295 CommandCost CmdDeleteTown(DoCommandFlags flags, TownID town_id)
3296{
3297 if (_game_mode != GM_EDITOR && !_generating_world) return CMD_ERROR;
3298 Town *t = Town::GetIfValid(town_id);
3299 if (t == nullptr) return CMD_ERROR;
3300
3301 /* Stations refer to towns. */
3302 for (const Station *st : Station::Iterate()) {
3303 if (st->town == t) {
3304 /* Non-oil rig stations are always a problem. */
3305 if (!st->facilities.Test(StationFacility::Airport) || st->airport.type != AT_OILRIG) return CMD_ERROR;
3306 /* We can only automatically delete oil rigs *if* there's no vehicle on them. */
3307 CommandCost ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, st->airport.tile);
3308 if (ret.Failed()) return ret;
3309 }
3310 }
3311
3312 /* Waypoints refer to towns. */
3313 for (const Waypoint *wp : Waypoint::Iterate()) {
3314 if (wp->town == t) return CMD_ERROR;
3315 }
3316
3317 /* Depots refer to towns. */
3318 for (const Depot *d : Depot::Iterate()) {
3319 if (d->town == t) return CMD_ERROR;
3320 }
3321
3322 /* Check all tiles for town ownership. First check for bridge tiles, as
3323 * these do not directly have an owner so we need to check adjacent
3324 * tiles. This won't work correctly in the same loop if the adjacent
3325 * tile was already deleted earlier in the loop. */
3326 for (const auto current_tile : Map::Iterate()) {
3327 if (IsTileType(current_tile, MP_TUNNELBRIDGE) && TestTownOwnsBridge(current_tile, t)) {
3328 CommandCost ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, current_tile);
3329 if (ret.Failed()) return ret;
3330 }
3331 }
3332
3333 /* Check all remaining tiles for town ownership. */
3334 for (const auto current_tile : Map::Iterate()) {
3335 bool try_clear = false;
3336 switch (GetTileType(current_tile)) {
3337 case MP_ROAD:
3338 try_clear = HasTownOwnedRoad(current_tile) && GetTownIndex(current_tile) == t->index;
3339 break;
3340
3341 case MP_HOUSE:
3342 try_clear = GetTownIndex(current_tile) == t->index;
3343 break;
3344
3345 case MP_INDUSTRY:
3346 try_clear = Industry::GetByTile(current_tile)->town == t;
3347 break;
3348
3349 case MP_OBJECT:
3350 if (Town::GetNumItems() == 1) {
3351 /* No towns will be left, remove it! */
3352 try_clear = true;
3353 } else {
3354 Object *o = Object::GetByTile(current_tile);
3355 if (o->town == t) {
3356 if (o->type == OBJECT_STATUE) {
3357 /* Statue... always remove. */
3358 try_clear = true;
3359 } else {
3360 /* Tell to find a new town. */
3361 if (flags.Test(DoCommandFlag::Execute)) o->town = nullptr;
3362 }
3363 }
3364 }
3365 break;
3366
3367 default:
3368 break;
3369 }
3370 if (try_clear) {
3371 CommandCost ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, current_tile);
3372 if (ret.Failed()) return ret;
3373 }
3374 }
3375
3376 /* The town destructor will delete the other things related to the town. */
3377 if (flags.Test(DoCommandFlag::Execute)) {
3378 _town_kdtree.Remove(t->index);
3379 if (t->cache.sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeTown(t->index));
3380 delete t;
3381 }
3382
3383 return CommandCost();
3384}
3385
3391uint8_t GetTownActionCost(TownAction action)
3392{
3397 static const uint8_t town_action_costs[] = {
3398 2, 4, 9, 35, 48, 53, 117, 175
3399 };
3400 static_assert(std::size(town_action_costs) == to_underlying(TownAction::End));
3401
3402 assert(to_underlying(action) < std::size(town_action_costs));
3403 return town_action_costs[to_underlying(action)];
3404}
3405
3412 static CommandCost TownActionAdvertiseSmall(Town *t, DoCommandFlags flags)
3413{
3414 if (flags.Test(DoCommandFlag::Execute)) {
3415 ModifyStationRatingAround(t->xy, _current_company, 0x40, 10);
3416 }
3417 return CommandCost();
3418}
3419
3426 static CommandCost TownActionAdvertiseMedium(Town *t, DoCommandFlags flags)
3427{
3428 if (flags.Test(DoCommandFlag::Execute)) {
3429 ModifyStationRatingAround(t->xy, _current_company, 0x70, 15);
3430 }
3431 return CommandCost();
3432}
3433
3440 static CommandCost TownActionAdvertiseLarge(Town *t, DoCommandFlags flags)
3441{
3442 if (flags.Test(DoCommandFlag::Execute)) {
3443 ModifyStationRatingAround(t->xy, _current_company, 0xA0, 20);
3444 }
3445 return CommandCost();
3446}
3447
3454 static CommandCost TownActionRoadRebuild(Town *t, DoCommandFlags flags)
3455{
3456 /* Check if the company is allowed to fund new roads. */
3457 if (!_settings_game.economy.fund_roads) return CMD_ERROR;
3458
3459 if (flags.Test(DoCommandFlag::Execute)) {
3460 t->road_build_months = 6;
3461
3462 std::string company_name = GetString(STR_COMPANY_NAME, _current_company);
3463
3464 AddNewsItem(
3465 GetEncodedString(TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_ROAD_REBUILDING_MINUTES : STR_NEWS_ROAD_REBUILDING_MONTHS, t->index, company_name),
3466 NewsType::General, NewsStyle::Normal, {}, t->index);
3467 AI::BroadcastNewEvent(new ScriptEventRoadReconstruction(_current_company, t->index));
3468 Game::NewEvent(new ScriptEventRoadReconstruction(_current_company, t->index));
3469 }
3470 return CommandCost();
3471}
3472
3478 static bool CheckClearTile(TileIndex tile)
3479{
3480 Backup<CompanyID> cur_company(_current_company, OWNER_NONE);
3481 CommandCost r = Command<CMD_LANDSCAPE_CLEAR>::Do({}, tile);
3482 cur_company.Restore();
3483 return r.Succeeded();
3484}
3485
3493 static CommandCost TownActionBuildStatue(Town *t, DoCommandFlags flags)
3494{
3495 if (!Object::CanAllocateItem()) return CommandCost(STR_ERROR_TOO_MANY_OBJECTS);
3496
3497 static const int STATUE_NUMBER_INNER_TILES = 25; // Number of tiles int the center of the city, where we try to protect houses.
3498
3499 TileIndex best_position = INVALID_TILE;
3500 uint tile_count = 0;
3501 for (auto tile : SpiralTileSequence(t->xy, 9)) {
3502 tile_count++;
3503
3504 /* Statues can be build on slopes, just like houses. Only the steep slopes is a no go. */
3505 if (IsSteepSlope(GetTileSlope(tile))) continue;
3506 /* Don't build statues under bridges. */
3507 if (IsBridgeAbove(tile)) continue;
3508
3509 /* A clear-able open space is always preferred. */
3510 if ((IsTileType(tile, MP_CLEAR) || IsTileType(tile, MP_TREES)) && CheckClearTile(tile)) {
3511 best_position = tile;
3512 break;
3513 }
3514
3515 bool house = IsTileType(tile, MP_HOUSE);
3516
3517 /* Searching inside the inner circle. */
3518 if (tile_count <= STATUE_NUMBER_INNER_TILES) {
3519 /* Save first house in inner circle. */
3520 if (house && best_position == INVALID_TILE && CheckClearTile(tile)) {
3521 best_position = tile;
3522 }
3523
3524 /* If we have reached the end of the inner circle, and have a saved house, terminate the search. */
3525 if (tile_count == STATUE_NUMBER_INNER_TILES && best_position != INVALID_TILE) break;
3526 }
3527
3528 /* Searching outside the circle, just pick the first possible spot. */
3529 if (!house || !CheckClearTile(tile)) continue;
3530 best_position = tile;
3531 break;
3532 }
3533 if (best_position == INVALID_TILE) return CommandCost(STR_ERROR_STATUE_NO_SUITABLE_PLACE);
3534
3535 if (flags.Test(DoCommandFlag::Execute)) {
3536 Backup<CompanyID> cur_company(_current_company, OWNER_NONE);
3537 Command<CMD_LANDSCAPE_CLEAR>::Do(DoCommandFlag::Execute, best_position);
3538 cur_company.Restore();
3539 BuildObject(OBJECT_STATUE, best_position, _current_company, t);
3540 t->statues.Set(_current_company); // Once found and built, "inform" the Town.
3541 MarkTileDirtyByTile(best_position);
3542 }
3543 return CommandCost();
3544}
3545
3552 static CommandCost TownActionFundBuildings(Town *t, DoCommandFlags flags)
3553{
3554 /* Check if it's allowed to buy the rights */
3555 if (!_settings_game.economy.fund_buildings) return CMD_ERROR;
3556
3557 if (flags.Test(DoCommandFlag::Execute)) {
3558 /* And grow for 3 months */
3559 t->fund_buildings_months = 3;
3560
3561 /* Enable growth (also checking GameScript's opinion) */
3562 UpdateTownGrowth(t);
3563
3564 /* Build a new house, but add a small delay to make sure
3565 * that spamming funding doesn't let town grow any faster
3566 * than 1 house per 2 * TOWN_GROWTH_TICKS ticks.
3567 * Also emulate original behaviour when town was only growing in
3568 * TOWN_GROWTH_TICKS intervals, to make sure that it's not too
3569 * tick-perfect and gives player some time window where they can
3570 * spam funding with the exact same efficiency.
3571 */
3572 t->grow_counter = std::min<uint16_t>(t->grow_counter, 2 * Ticks::TOWN_GROWTH_TICKS - (t->growth_rate - t->grow_counter) % Ticks::TOWN_GROWTH_TICKS);
3573
3574 SetWindowDirty(WC_TOWN_VIEW, t->index);
3575 }
3576 return CommandCost();
3577}
3578
3585 static CommandCost TownActionBuyRights(Town *t, DoCommandFlags flags)
3586{
3587 /* Check if it's allowed to buy the rights */
3588 if (!_settings_game.economy.exclusive_rights) return CMD_ERROR;
3589 if (t->exclusivity != CompanyID::Invalid()) return CMD_ERROR;
3590
3591 if (flags.Test(DoCommandFlag::Execute)) {
3592 t->exclusive_counter = 12;
3593 t->exclusivity = _current_company;
3594
3595 ModifyStationRatingAround(t->xy, _current_company, 130, 17);
3596
3597 SetWindowClassesDirty(WC_STATION_VIEW);
3598
3599 /* Spawn news message */
3600 auto cni = std::make_unique<CompanyNewsInformation>(STR_NEWS_EXCLUSIVE_RIGHTS_TITLE, Company::Get(_current_company));
3601 EncodedString message = GetEncodedString(TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MINUTES : STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MONTHS, t->index, cni->company_name);
3602 AddNewsItem(std::move(message),
3603 NewsType::General, NewsStyle::Company, {}, t->index, {}, std::move(cni));
3604 AI::BroadcastNewEvent(new ScriptEventExclusiveTransportRights(_current_company, t->index));
3605 Game::NewEvent(new ScriptEventExclusiveTransportRights(_current_company, t->index));
3606 }
3607 return CommandCost();
3608}
3609
3616 static CommandCost TownActionBribe(Town *t, DoCommandFlags flags)
3617{
3618 if (flags.Test(DoCommandFlag::Execute)) {
3619 if (Chance16(1, 14)) {
3620 /* set as unwanted for 6 months */
3621 t->unwanted[_current_company] = 6;
3622
3623 /* set all close by station ratings to 0 */
3624 for (Station *st : Station::Iterate()) {
3625 if (st->town == t && st->owner == _current_company) {
3626 for (GoodsEntry &ge : st->goods) ge.rating = 0;
3627 }
3628 }
3629
3630 /* only show error message to the executing player. All errors are handled command.c
3631 * but this is special, because it can only 'fail' on a DoCommandFlag::Execute */
3632 if (IsLocalCompany()) ShowErrorMessage(GetEncodedString(STR_ERROR_BRIBE_FAILED), {}, WL_INFO);
3633
3634 /* decrease by a lot!
3635 * ChangeTownRating is only for stuff in demolishing. Bribe failure should
3636 * be independent of any cheat settings
3637 */
3638 if (t->ratings[_current_company] > RATING_BRIBE_DOWN_TO) {
3639 t->ratings[_current_company] = RATING_BRIBE_DOWN_TO;
3640 SetWindowDirty(WC_TOWN_AUTHORITY, t->index);
3641 }
3642 } else {
3643 ChangeTownRating(t, RATING_BRIBE_UP_STEP, RATING_BRIBE_MAXIMUM, DoCommandFlag::Execute);
3644 if (t->exclusivity != _current_company && t->exclusivity != CompanyID::Invalid()) {
3645 t->exclusivity = CompanyID::Invalid();
3646 t->exclusive_counter = 0;
3647 }
3648 }
3649 }
3650 return CommandCost();
3651}
3652
3653typedef CommandCost TownActionProc(Town *t, DoCommandFlags flags);
3654static TownActionProc * const _town_action_proc[] = {
3655 TownActionAdvertiseSmall,
3656 TownActionAdvertiseMedium,
3657 TownActionAdvertiseLarge,
3658 TownActionRoadRebuild,
3659 TownActionBuildStatue,
3660 TownActionFundBuildings,
3661 TownActionBuyRights,
3662 TownActionBribe
3663};
3664static_assert(std::size(_town_action_proc) == to_underlying(TownAction::End));
3665
3672 TownActions GetMaskOfTownActions(CompanyID cid, const Town *t)
3673{
3674 TownActions buttons{};
3675
3676 /* Spectators and unwanted have no options */
3677 if (cid != COMPANY_SPECTATOR && !(_settings_game.economy.bribe && t->unwanted[cid])) {
3678
3679 /* Actions worth more than this are not able to be performed */
3680 Money avail = GetAvailableMoney(cid);
3681
3682 /* Check the action bits for validity and
3683 * if they are valid add them */
3684 for (TownAction cur = {}; cur != TownAction::End; ++cur) {
3685
3686 /* Is the company prohibited from bribing ? */
3687 if (cur == TownAction::Bribe) {
3688 /* Company can't bribe if setting is disabled */
3689 if (!_settings_game.economy.bribe) continue;
3690 /* Company can bribe if another company has exclusive transport rights,
3691 * or its standing with the town is less than outstanding. */
3692 if (t->ratings[cid] >= RATING_BRIBE_MAXIMUM) {
3693 if (t->exclusivity == _current_company) continue;
3694 if (t->exclusive_counter == 0) continue;
3695 }
3696 }
3697
3698 /* Is the company not able to buy exclusive rights ? */
3699 if (cur == TownAction::BuyRights && (!_settings_game.economy.exclusive_rights || t->exclusive_counter != 0)) continue;
3700
3701 /* Is the company not able to fund buildings ? */
3702 if (cur == TownAction::FundBuildings && !_settings_game.economy.fund_buildings) continue;
3703
3704 /* Is the company not able to fund local road reconstruction? */
3705 if (cur == TownAction::RoadRebuild && !_settings_game.economy.fund_roads) continue;
3706
3707 /* Is the company not able to build a statue ? */
3708 if (cur == TownAction::BuildStatue && t->statues.Test(cid)) continue;
3709
3710 if (avail >= GetTownActionCost(cur) * _price[PR_TOWN_ACTION] >> 8) {
3711 buttons.Set(cur);
3712 }
3713 }
3714 }
3715
3716 return buttons;
3717}
3718
3728 CommandCost CmdDoTownAction(DoCommandFlags flags, TownID town_id, TownAction action)
3729{
3730 Town *t = Town::GetIfValid(town_id);
3731 if (t == nullptr || to_underlying(action) >= std::size(_town_action_proc)) return CMD_ERROR;
3732
3733 if (!GetMaskOfTownActions(_current_company, t).Test(action)) return CMD_ERROR;
3734
3735 CommandCost cost(EXPENSES_OTHER, _price[PR_TOWN_ACTION] * GetTownActionCost(action) >> 8);
3736
3737 CommandCost ret = _town_action_proc[to_underlying(action)](t, flags);
3738 if (ret.Failed()) return ret;
3739
3740 if (flags.Test(DoCommandFlag::Execute)) {
3741 SetWindowDirty(WC_TOWN_AUTHORITY, town_id);
3742 }
3743
3744 return cost;
3745}
3746
3747template <typename Func>
3748static void ForAllStationsNearTown(Town *t, Func func)
3749{
3750 /* Ideally the search radius should be close to the actual town zone 0 radius.
3751 * The true radius is not stored or calculated anywhere, only the squared radius. */
3752 /* The efficiency of this search might be improved for large towns and many stations on the map,
3753 * by using an integer square root approximation giving a value not less than the true square root. */
3754 uint search_radius = t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownEdge)] / 2;
3755 ForAllStationsRadius(t->xy, search_radius, [&](const Station * st) {
3756 if (DistanceSquare(st->xy, t->xy) <= t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownEdge)]) {
3757 func(st);
3758 }
3759 });
3760}
3761
3766 static void UpdateTownRating(Town *t)
3767{
3768 /* Increase company ratings if they're low */
3769 for (const Company *c : Company::Iterate()) {
3770 if (t->ratings[c->index] < RATING_GROWTH_MAXIMUM) {
3771 t->ratings[c->index] = std::min((int)RATING_GROWTH_MAXIMUM, t->ratings[c->index] + RATING_GROWTH_UP_STEP);
3772 }
3773 }
3774
3775 ForAllStationsNearTown(t, [&](const Station *st) {
3776 if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
3777 if (Company::IsValidID(st->owner)) {
3778 int new_rating = t->ratings[st->owner] + RATING_STATION_UP_STEP;
3779 t->ratings[st->owner] = std::min<int>(new_rating, INT16_MAX); // do not let it overflow
3780 }
3781 } else {
3782 if (Company::IsValidID(st->owner)) {
3783 int new_rating = t->ratings[st->owner] + RATING_STATION_DOWN_STEP;
3784 t->ratings[st->owner] = std::max(new_rating, INT16_MIN);
3785 }
3786 }
3787 });
3788
3789 /* clamp all ratings to valid values */
3790 for (uint i = 0; i < MAX_COMPANIES; i++) {
3791 t->ratings[i] = Clamp(t->ratings[i], RATING_MINIMUM, RATING_MAXIMUM);
3792 }
3793
3794 SetWindowDirty(WC_TOWN_AUTHORITY, t->index);
3795}
3796
3797
3804 static void UpdateTownGrowCounter(Town *t, uint16_t prev_growth_rate)
3805{
3806 if (t->growth_rate == TOWN_GROWTH_RATE_NONE) return;
3807 if (prev_growth_rate == TOWN_GROWTH_RATE_NONE) {
3808 t->grow_counter = std::min<uint16_t>(t->growth_rate, t->grow_counter);
3809 return;
3810 }
3811 t->grow_counter = RoundDivSU((uint32_t)t->grow_counter * (t->growth_rate + 1), prev_growth_rate + 1);
3812}
3813
3819 static int CountActiveStations(Town *t)
3820{
3821 int n = 0;
3822 ForAllStationsNearTown(t, [&](const Station * st) {
3823 if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
3824 n++;
3825 }
3826 });
3827 return n;
3828}
3829
3836 static uint GetNormalGrowthRate(Town *t)
3837{
3843 static const uint16_t _grow_count_values[2][6] = {
3844 { 120, 120, 120, 100, 80, 60 }, // Fund new buildings has been activated
3845 { 320, 420, 300, 220, 160, 100 } // Normal values
3846 };
3847
3848 int n = CountActiveStations(t);
3849 uint16_t m = _grow_count_values[t->fund_buildings_months != 0 ? 0 : 1][std::min(n, 5)];
3850
3851 uint growth_multiplier = _settings_game.economy.town_growth_rate != 0 ? _settings_game.economy.town_growth_rate - 1 : 1;
3852
3853 m >>= growth_multiplier;
3854 if (t->larger_town) m /= 2;
3855
3856 return TownTicksToGameTicks(m / (t->cache.num_houses / 50 + 1));
3857}
3858
3863 static void UpdateTownGrowthRate(Town *t)
3864{
3865 if (t->flags.Test(TownFlag::CustomGrowth)) return;
3866 uint old_rate = t->growth_rate;
3867 t->growth_rate = GetNormalGrowthRate(t);
3868 UpdateTownGrowCounter(t, old_rate);
3869 SetWindowDirty(WC_TOWN_VIEW, t->index);
3870}
3871
3876 static void UpdateTownGrowth(Town *t)
3877{
3878 UpdateTownGrowthRate(t);
3879
3880 t->flags.Reset(TownFlag::IsGrowing);
3881 SetWindowDirty(WC_TOWN_VIEW, t->index);
3882
3883 if (_settings_game.economy.town_growth_rate == 0 && t->fund_buildings_months == 0) return;
3884
3885 if (t->fund_buildings_months == 0) {
3886 /* Check if all goals are reached for this town to grow (given we are not funding it) */
3887 for (int i = TAE_BEGIN; i < TAE_END; i++) {
3888 switch (t->goal[i]) {
3889 case TOWN_GROWTH_WINTER:
3890 if (TileHeight(t->xy) >= GetSnowLine() && t->received[i].old_act == 0 && t->cache.population > 90) return;
3891 break;
3892 case TOWN_GROWTH_DESERT:
3893 if (GetTropicZone(t->xy) == TROPICZONE_DESERT && t->received[i].old_act == 0 && t->cache.population > 60) return;
3894 break;
3895 default:
3896 if (t->goal[i] > t->received[i].old_act) return;
3897 break;
3898 }
3899 }
3900 }
3901
3902 if (t->flags.Test(TownFlag::CustomGrowth)) {
3903 if (t->growth_rate != TOWN_GROWTH_RATE_NONE) t->flags.Set(TownFlag::IsGrowing);
3904 SetWindowDirty(WC_TOWN_VIEW, t->index);
3905 return;
3906 }
3907
3908 if (t->fund_buildings_months == 0 && CountActiveStations(t) == 0 && !Chance16(1, 12)) return;
3909
3910 t->flags.Set(TownFlag::IsGrowing);
3911 SetWindowDirty(WC_TOWN_VIEW, t->index);
3912}
3913
3920 CommandCost CheckIfAuthorityAllowsNewStation(TileIndex tile, DoCommandFlags flags)
3921{
3922 /* The required rating is hardcoded to RATING_VERYPOOR (see below), not the authority attitude setting, so we can bail out like this. */
3923 if (_settings_game.difficulty.town_council_tolerance == TOWN_COUNCIL_PERMISSIVE) return CommandCost();
3924
3925 if (!Company::IsValidID(_current_company) || flags.Test(DoCommandFlag::NoTestTownRating)) return CommandCost();
3926
3927 Town *t = ClosestTownFromTile(tile, _settings_game.economy.dist_local_authority);
3928 if (t == nullptr) return CommandCost();
3929
3930 if (t->ratings[_current_company] > RATING_VERYPOOR) return CommandCost();
3931
3932 return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index);
3933}
3934
3943 Town *CalcClosestTownFromTile(TileIndex tile, uint threshold)
3944{
3945 if (Town::GetNumItems() == 0) return nullptr;
3946
3947 TownID tid = _town_kdtree.FindNearest(TileX(tile), TileY(tile));
3948 Town *town = Town::Get(tid);
3949 if (DistanceManhattan(tile, town->xy) < threshold) return town;
3950 return nullptr;
3951}
3952
3961 Town *ClosestTownFromTile(TileIndex tile, uint threshold)
3962{
3963 switch (GetTileType(tile)) {
3964 case MP_ROAD:
3965 if (IsRoadDepot(tile)) return CalcClosestTownFromTile(tile, threshold);
3966
3967 if (!HasTownOwnedRoad(tile)) {
3968 TownID tid = GetTownIndex(tile);
3969
3970 if (tid == TownID::Invalid()) {
3971 /* in the case we are generating "many random towns", this value may be TownID::Invalid() */
3972 if (_generating_world) return CalcClosestTownFromTile(tile, threshold);
3973 assert(Town::GetNumItems() == 0);
3974 return nullptr;
3975 }
3976
3977 assert(Town::IsValidID(tid));
3978 Town *town = Town::Get(tid);
3979
3980 if (DistanceManhattan(tile, town->xy) >= threshold) town = nullptr;
3981
3982 return town;
3983 }
3984 [[fallthrough]];
3985
3986 case MP_HOUSE:
3987 return Town::GetByTile(tile);
3988
3989 default:
3990 return CalcClosestTownFromTile(tile, threshold);
3991 }
3992}
3993
3994 static bool _town_rating_test = false;
3995 static std::map<const Town *, int> _town_test_ratings;
3996
4002 void SetTownRatingTestMode(bool mode)
4003{
4004 static int ref_count = 0; // Number of times test-mode is switched on.
4005 if (mode) {
4006 if (ref_count == 0) {
4007 _town_test_ratings.clear();
4008 }
4009 ref_count++;
4010 } else {
4011 assert(ref_count > 0);
4012 ref_count--;
4013 }
4014 _town_rating_test = !(ref_count == 0);
4015}
4016
4022 static int GetRating(const Town *t)
4023{
4024 if (_town_rating_test) {
4025 auto it = _town_test_ratings.find(t);
4026 if (it != _town_test_ratings.end()) {
4027 return it->second;
4028 }
4029 }
4030 return t->ratings[_current_company];
4031}
4032
4040 void ChangeTownRating(Town *t, int add, int max, DoCommandFlags flags)
4041{
4042 /* if magic_bulldozer cheat is active, town doesn't penalize for removing stuff */
4043 if (t == nullptr || flags.Test(DoCommandFlag::NoModifyTownRating) ||
4044 !Company::IsValidID(_current_company) ||
4045 (_cheats.magic_bulldozer.value && add < 0)) {
4046 return;
4047 }
4048
4049 int rating = GetRating(t);
4050 if (add < 0) {
4051 if (rating > max) {
4052 rating += add;
4053 if (rating < max) rating = max;
4054 }
4055 } else {
4056 if (rating < max) {
4057 rating += add;
4058 if (rating > max) rating = max;
4059 }
4060 }
4061 if (_town_rating_test) {
4062 _town_test_ratings[t] = rating;
4063 } else {
4064 t->have_ratings.Set(_current_company);
4065 t->ratings[_current_company] = rating;
4066 SetWindowDirty(WC_TOWN_AUTHORITY, t->index);
4067 }
4068}
4069
4077 CommandCost CheckforTownRating(DoCommandFlags flags, Town *t, TownRatingCheckType type)
4078{
4079 /* if magic_bulldozer cheat is active, town doesn't restrict your destructive actions */
4080 if (t == nullptr || !Company::IsValidID(_current_company) ||
4081 _cheats.magic_bulldozer.value || flags.Test(DoCommandFlag::NoTestTownRating)) {
4082 return CommandCost();
4083 }
4084
4085 /* minimum rating needed to be allowed to remove stuff */
4086 static const int needed_rating[][to_underlying(TownRatingCheckType::End)] = {
4087 /* RoadRemove, TunnelBridgeRemove */
4088 { RATING_ROAD_NEEDED_LENIENT, RATING_TUNNEL_BRIDGE_NEEDED_LENIENT}, // Lenient
4089 { RATING_ROAD_NEEDED_NEUTRAL, RATING_TUNNEL_BRIDGE_NEEDED_NEUTRAL}, // Neutral
4090 { RATING_ROAD_NEEDED_HOSTILE, RATING_TUNNEL_BRIDGE_NEEDED_HOSTILE}, // Hostile
4091 { RATING_ROAD_NEEDED_PERMISSIVE, RATING_TUNNEL_BRIDGE_NEEDED_PERMISSIVE}, // Permissive
4092 };
4093
4094 /* check if you're allowed to remove the road/bridge/tunnel
4095 * owned by a town no removal if rating is lower than ... depends now on
4096 * difficulty setting. Minimum town rating selected by difficulty level
4097 */
4098 int needed = needed_rating[_settings_game.difficulty.town_council_tolerance][to_underlying(type)];
4099
4100 if (GetRating(t) < needed) {
4101 return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index);
4102 }
4103
4104 return CommandCost();
4105}
4106
4107template <>
4108 Town::SuppliedHistory SumHistory(std::span<const Town::SuppliedHistory> history)
4109{
4110 uint64_t production = std::accumulate(std::begin(history), std::end(history), 0, [](uint64_t r, const auto &s) { return r + s.production; });
4111 uint64_t transported = std::accumulate(std::begin(history), std::end(history), 0, [](uint64_t r, const auto &s) { return r + s.transported; });
4112 auto count = std::size(history);
4113 return {.production = ClampTo<uint32_t>(production / count), .transported = ClampTo<uint32_t>(transported / count)};
4114}
4115
4116static const IntervalTimer<TimerGameEconomy> _economy_towns_monthly({TimerGameEconomy::MONTH, TimerGameEconomy::Priority::TOWN}, [](auto)
4117{
4118 for (Town *t : Town::Iterate()) {
4119 /* Check for active town actions and decrement their counters. */
4120 if (t->road_build_months != 0) t->road_build_months--;
4121 if (t->fund_buildings_months != 0) t->fund_buildings_months--;
4122
4123 if (t->exclusive_counter != 0) {
4124 if (--t->exclusive_counter == 0) t->exclusivity = CompanyID::Invalid();
4125 }
4126
4127 /* Check for active failed bribe cooloff periods and decrement them. */
4128 for (const Company *c : Company::Iterate()) {
4129 if (t->unwanted[c->index] > 0) t->unwanted[c->index]--;
4130 }
4131
4132 UpdateValidHistory(t->valid_history, HISTORY_YEAR, TimerGameEconomy::month);
4133
4134 /* Update cargo statistics. */
4135 for (auto &s : t->supplied) RotateHistory(s.history, t->valid_history, HISTORY_YEAR, TimerGameEconomy::month);
4136 for (auto &received : t->received) received.NewMonth();
4137
4138 UpdateTownGrowth(t);
4139 UpdateTownRating(t);
4140
4141 SetWindowDirty(WC_TOWN_VIEW, t->index);
4142 }
4143});
4144
4145static const IntervalTimer<TimerGameEconomy> _economy_towns_yearly({TimerGameEconomy::YEAR, TimerGameEconomy::Priority::TOWN}, [](auto)
4146{
4147 /* Increment house ages */
4148 for (const auto t : Map::Iterate()) {
4149 if (!IsTileType(t, MP_HOUSE)) continue;
4150 IncrementHouseAge(t);
4151 }
4152});
4153
4154static CommandCost TerraformTile_Town(TileIndex tile, DoCommandFlags flags, int z_new, Slope tileh_new)
4155{
4156 if (AutoslopeEnabled()) {
4157 HouseID house = GetHouseType(tile);
4158 GetHouseNorthPart(house); // modifies house to the ID of the north tile
4159 const HouseSpec *hs = HouseSpec::Get(house);
4160
4161 /* Here we differ from TTDP by checking BuildingFlag::NotSloped */
4162 if (!hs->building_flags.Test(BuildingFlag::NotSloped) && !IsSteepSlope(tileh_new) &&
4163 (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) {
4164 bool allow_terraform = true;
4165
4166 /* Call the autosloping callback per tile, not for the whole building at once. */
4167 house = GetHouseType(tile);
4168 hs = HouseSpec::Get(house);
4169 if (hs->callback_mask.Test(HouseCallbackMask::Autoslope)) {
4170 /* If the callback fails, allow autoslope. */
4171 uint16_t res = GetHouseCallback(CBID_HOUSE_AUTOSLOPE, 0, 0, house, Town::GetByTile(tile), tile);
4172 if (res != CALLBACK_FAILED && ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_AUTOSLOPE, res)) allow_terraform = false;
4173 }
4174
4175 if (allow_terraform) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
4176 }
4177 }
4178
4179 return Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
4180}
4181
4183extern const TileTypeProcs _tile_type_town_procs = {
4184 DrawTile_Town, // draw_tile_proc
4185 GetSlopePixelZ_Town, // get_slope_z_proc
4186 ClearTile_Town, // clear_tile_proc
4187 AddAcceptedCargo_Town, // add_accepted_cargo_proc
4188 GetTileDesc_Town, // get_tile_desc_proc
4189 GetTileTrackStatus_Town, // get_tile_track_status_proc
4190 nullptr, // click_tile_proc
4191 AnimateTile_Town, // animate_tile_proc
4192 TileLoop_Town, // tile_loop_proc
4193 ChangeTileOwner_Town, // change_tile_owner_proc
4194 AddProducedCargo_Town, // add_produced_cargo_proc
4195 nullptr, // vehicle_enter_tile_proc
4196 GetFoundation_Town, // get_foundation_proc
4197 TerraformTile_Town, // terraform_tile_proc
4198 nullptr, // check_build_above_proc
4199};
4200
4201std::span<const DrawBuildingsTileStruct> GetTownDrawTileData()
4202{
4203 return _town_draw_tile_data;
4204}
ai.hpp
Base functions for all AIs.
AT_OILRIG
@ AT_OILRIG
Oilrig airport.
Definition airport.h:38
AddAnimatedTile
void AddAnimatedTile(TileIndex tile, bool mark_dirty)
Add the given tile to the animated tile table (if it does not exist yet).
Definition animated_tile.cpp:56
DeleteAnimatedTile
void DeleteAnimatedTile(TileIndex tile, bool immediate)
Stops animation on the given tile.
Definition animated_tile.cpp:27
animated_tile_func.h
Tile animation!
autoslope.h
Functions related to autoslope.
AutoslopeEnabled
bool AutoslopeEnabled()
Tests if autoslope is enabled for _current_company.
Definition autoslope.h:65
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
CountBits
constexpr uint CountBits(T value)
Counts the number of set bits in a variable.
Definition bitmath_func.hpp:238
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
MAX_BRIDGES
static const uint MAX_BRIDGES
Maximal number of available bridge specs.
Definition bridge.h:18
IsBridgeTile
bool IsBridgeTile(Tile t)
checks if there is a bridge on this tile
Definition bridge_map.h:35
IsBridgeAbove
bool IsBridgeAbove(Tile t)
checks if a bridge is set above the ground of this tile
Definition bridge_map.h:45
GetBridgeAxis
Axis GetBridgeAxis(Tile t)
Get the axis of the bridge that goes over the tile.
Definition bridge_map.h:68
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
TownProductionEffect
TownProductionEffect
Town effect when producing cargo.
Definition cargotype.h:35
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
TAE_FOOD
@ TAE_FOOD
Cargo behaves food/fizzy-drinks-like.
Definition cargotype.h:29
TAE_WATER
@ TAE_WATER
Cargo behaves water-like.
Definition cargotype.h:28
_cheats
Cheats _cheats
All the cheats.
Definition cheat.cpp:16
cheat_type.h
Types related to cheating.
AI::BroadcastNewEvent
static void BroadcastNewEvent(ScriptEvent *event, CompanyID skip_company=CompanyID::Invalid())
Broadcast a new event to all active AIs.
Definition ai_core.cpp:255
BaseBitSet::All
constexpr bool All(const Timpl &other) const
Test if all of the values are set.
Definition base_bitset_type.hpp:151
BaseBitSet::Test
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
Definition base_bitset_type.hpp:141
BaseBitSet::None
constexpr bool None() const
Test if none of the values are set.
Definition base_bitset_type.hpp:188
BaseBitSet::Reset
constexpr Timpl & Reset()
Reset all bits.
Definition base_bitset_type.hpp:83
BaseBitSet::Set
constexpr Timpl & Set()
Set all bits.
Definition base_bitset_type.hpp:40
BaseBitSet::Any
constexpr bool Any(const Timpl &other) const
Test if any of the given values are set.
Definition base_bitset_type.hpp:170
CommandCost
Common return value for all commands.
Definition command_type.h:24
CommandCost::Succeeded
bool Succeeded() const
Did this command succeed?
Definition command_type.h:168
CommandCost::AddCost
void AddCost(const Money &cost)
Adds the given cost to the cost of the command.
Definition command_type.h:98
CommandCost::GetCost
Money GetCost() const
The costs as made up to this moment.
Definition command_type.h:118
CommandCost::Failed
bool Failed() const
Did this command fail?
Definition command_type.h:177
CommandCost::MultiplyCost
void MultiplyCost(int factor)
Multiplies the cost of the command by the given factor.
Definition command_type.h:109
EncodedString
Container for an encoded string, created by GetEncodedString.
Definition strings_type.h:98
EnumBitSet
Enum-as-bit-set wrapper.
Definition enum_type.hpp:177
Game::NewEvent
static void NewEvent(class ScriptEvent *event)
Queue a new event for a Game Script.
Definition game_core.cpp:136
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::Build
void Build(It begin, It end)
Clear and rebuild the tree from a new sequence of elements,.
Definition kdtree.hpp:360
Kdtree::Count
size_t Count() const
Get number of elements stored in tree.
Definition kdtree.hpp:428
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::FindNearest
T FindNearest(CoordT x, CoordT y) const
Find the element closest to given coordinate, in Manhattan distance.
Definition kdtree.hpp:439
OverflowSafeInt< int64_t >
RoadTypeInfo
Definition road.h:52
RoadTypeInfo::introduction_date
TimerGameCalendar::Date introduction_date
Introduction date.
Definition road.h:140
RoadTypeInfo::flags
RoadTypeFlags flags
Bit mask of road type flags.
Definition road.h:101
RoadTypeInfo::max_speed
uint16_t max_speed
Maximum speed for vehicles travelling on this road type.
Definition road.h:116
SpiralTileSequence
Generate TileIndices around a center tile or tile area, with increasing distance.
Definition tilearea_type.h:316
StationFinder
Structure contains cached list of stations nearby.
Definition station_type.h:137
StationFinder::GetStations
const StationList & GetStations()
Run a tile loop to find stations around a tile, on demand.
Definition station_cmd.cpp:4559
Ticks::TOWN_GROWTH_TICKS
static constexpr TimerGameTick::Ticks TOWN_GROWTH_TICKS
Cycle duration for towns trying to grow (this originates from the size of the town array in TTD).
Definition timer_game_tick.h:83
TimerGameCalendar::date
static Date date
Current date in days (day counter).
Definition timer_game_calendar.h:33
TimerGameCalendar::year
static Year year
Current year, starting at 0.
Definition timer_game_calendar.h:31
TimerGameConst< struct Calendar >::MAX_DATE
static constexpr TimerGame< struct Calendar >::Date MAX_DATE
The date of the last day of the max year.
Definition timer_game_common.h:187
TimerGameEconomy
Timer that is increased every 27ms, and counts towards economy time units, expressed in days / months...
Definition timer_game_economy.h:32
TimerGameEconomy::month
static Month month
Current month (0..11).
Definition timer_game_economy.h:37
TimerGameEconomy::UsingWallclockUnits
static bool UsingWallclockUnits(bool newgame=false)
Check if we are using wallclock units.
Definition timer_game_economy.cpp:98
TimerGameTick::counter
static TickCounter counter
Monotonic counter, in ticks, since start of game.
Definition timer_game_tick.h:60
clear_map.h
Map accessors for 'clear' tiles.
CLEAR_ROUGH
@ CLEAR_ROUGH
3
Definition clear_map.h:21
GetClearGround
ClearGround GetClearGround(Tile t)
Get the type of clear tile.
Definition clear_map.h:47
CommandCostWithParam
CommandCost CommandCostWithParam(StringID str, uint64_t value)
Return an error status, with string and parameter.
Definition command.cpp:417
command_func.h
Functions related to commands.
CommandFlagsToDCFlags
static constexpr DoCommandFlags CommandFlagsToDCFlags(CommandFlags cmd_flags)
Extracts the DC flags needed for DoCommand from the flags returned by GetCommandFlags.
Definition command_func.h:49
CMD_ERROR
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
Definition command_func.h:28
DoCommandFlag::Auto
@ Auto
don't allow building on structures
DoCommandFlag::NoModifyTownRating
@ NoModifyTownRating
do not change town rating
DoCommandFlag::NoWater
@ NoWater
don't allow building on water
DoCommandFlag::Execute
@ Execute
execute the given command
DoCommandFlag::NoTestTownRating
@ NoTestTownRating
town rating does not disallow you from building
company_base.h
Definition of stuff that is very close to a company, like the company struct itself.
GetAvailableMoneyForCommand
Money GetAvailableMoneyForCommand()
This functions returns the money which can be used to execute a command.
Definition company_cmd.cpp:252
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
_current_company
CompanyID _current_company
Company currently doing an action.
Definition company_cmd.cpp:56
company_func.h
Functions related to companies.
IsLocalCompany
bool IsLocalCompany()
Is the current company the local company?
Definition company_func.h:47
OWNER_DEITY
static constexpr Owner OWNER_DEITY
The object is owned by a superuser / goal script.
Definition company_type.h:28
COMPANY_SPECTATOR
static constexpr CompanyID COMPANY_SPECTATOR
The client is spectating.
Definition company_type.h:21
OWNER_TOWN
static constexpr Owner OWNER_TOWN
A town owns the tile, or a town is expanding.
Definition company_type.h:25
OWNER_NONE
static constexpr Owner OWNER_NONE
The tile has no ownership.
Definition company_type.h:26
depot_base.h
Base for all depots (except hangars)
ReverseDiagDir
DiagDirection ReverseDiagDir(DiagDirection d)
Returns the reverse direction of the given DiagDirection.
Definition direction_func.h:118
IsValidDiagDirection
bool IsValidDiagDirection(DiagDirection d)
Checks if an integer value is a valid DiagDirection.
Definition direction_func.h:21
ChangeDiagDir
DiagDirection ChangeDiagDir(DiagDirection d, DiagDirDiff delta)
Applies a difference on a DiagDirection.
Definition direction_func.h:149
DiagDirToAxis
Axis DiagDirToAxis(DiagDirection d)
Convert a DiagDirection to the axis.
Definition direction_func.h:214
DIR_N
@ DIR_N
North.
Definition direction_type.h:26
DIR_S
@ DIR_S
South.
Definition direction_type.h:30
DIR_W
@ DIR_W
West.
Definition direction_type.h:32
DIR_E
@ DIR_E
East.
Definition direction_type.h:28
DIAGDIRDIFF_90RIGHT
@ DIAGDIRDIFF_90RIGHT
90 degrees right
Definition direction_type.h:105
DIAGDIRDIFF_90LEFT
@ DIAGDIRDIFF_90LEFT
90 degrees left
Definition direction_type.h:107
DiagDirection
DiagDirection
Enumeration for diagonal directions.
Definition direction_type.h:78
DIAGDIR_NW
@ DIAGDIR_NW
Northwest.
Definition direction_type.h:83
DIAGDIR_SE
@ DIAGDIR_SE
Southeast.
Definition direction_type.h:81
DIAGDIR_END
@ DIAGDIR_END
Used for iterations.
Definition direction_type.h:84
DIAGDIR_BEGIN
@ DIAGDIR_BEGIN
Used for iterations.
Definition direction_type.h:79
DIAGDIR_SW
@ DIAGDIR_SW
Southwest.
Definition direction_type.h:82
EconomyIsInRecession
bool EconomyIsInRecession()
Is the economy in recession?
Definition economy_func.h:50
ScaleByCargoScale
uint ScaleByCargoScale(uint num, bool town)
Scale a number by the cargo scale setting.
Definition economy_func.h:78
EXPENSES_CONSTRUCTION
@ EXPENSES_CONSTRUCTION
Construction costs.
Definition economy_type.h:179
EXPENSES_OTHER
@ EXPENSES_OTHER
Other expenses.
Definition economy_type.h:191
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_CRITICAL
@ WL_CRITICAL
Critical errors, the MessageBox is shown in all cases.
Definition error.h:27
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
game.hpp
Base functions for all Games.
_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.
IncreaseGeneratingWorldProgress
void IncreaseGeneratingWorldProgress(GenWorldProgress cls)
Increases the current stage of the world generation with one.
Definition genworld_gui.cpp:1539
GWP_TOWN
@ GWP_TOWN
Generate towns.
Definition genworld.h:66
SetGeneratingWorldProgress
void SetGeneratingWorldProgress(GenWorldProgress cls, uint total)
Set the total of a stage of the world generation.
Definition genworld_gui.cpp:1525
SpriteID
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition gfx_type.h:17
GetSnowLine
uint8_t GetSnowLine()
Get the current snow line, either variable or static.
Definition landscape.cpp:606
HighestSnowLine
uint8_t HighestSnowLine()
Get the highest possible snow line height, either variable or static.
Definition landscape.cpp:619
MarkWholeScreenDirty
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
Definition gfx.cpp:1549
MarkTileDirtyByTile
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_height_override)
Mark a tile given by its index dirty for repaint.
Definition viewport.cpp:2128
UpdateValidHistory
void UpdateValidHistory(ValidHistoryMask &valid_history, const HistoryRange &hr, uint cur_month)
Update mask of valid records for a historical data.
Definition history.cpp:25
history_func.hpp
Functions for storing historical data.
RotateHistory
void RotateHistory(HistoryData< T > &history, ValidHistoryMask valid_history, const HistoryRange &hr, uint cur_month)
Rotate historical data.
Definition history_func.hpp:41
history_type.hpp
Types for storing historical data.
HouseExtraFlag::BuildingIsHistorical
@ BuildingIsHistorical
this house will only appear during town generation in random games, thus the historical
HouseExtraFlag::BuildingIsProtected
@ BuildingIsProtected
towns and AI will not remove this house, while human players will be able to
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
HouseZone::ClimateSubarcticAboveSnow
@ ClimateSubarcticAboveSnow
Building can appear in sub-arctic climate above the snow line.
HouseZone::ClimateSubarcticBelowSnow
@ ClimateSubarcticBelowSnow
Building can appear in sub-arctic climate below the snow line.
HouseZone::ClimateTemperate
@ ClimateTemperate
Building can appear in temperate climate.
HouseZone::ClimateToyland
@ ClimateToyland
Building can appear in toyland climate.
HouseZone::ClimateSubtropic
@ ClimateSubtropic
Building can appear in subtropical climate.
HouseID
uint16_t HouseID
OpenTTD ID of house types.
Definition house_type.h:15
industry.h
Base of all industries.
DrawFoundation
void DrawFoundation(TileInfo *ti, Foundation f)
Draw foundation f at tile ti.
Definition landscape.cpp:429
GetFoundationSlope
std::tuple< Slope, int > GetFoundationSlope(TileIndex tile)
Get slope of a tile on top of a (possible) foundation If a tile does not have a foundation,...
Definition landscape.cpp:386
landscape.h
Functions related to OTTD's landscape.
RemapCoords2
Point RemapCoords2(int x, int y)
Map 3D world or tile coordinate to equivalent 2D coordinate as used in the viewports and smallmap.
Definition landscape.h:97
landscape_cmd.h
Command definitions related to landscape (slopes etc.).
BorderFlag::Random
@ Random
Randomise borders.
DistanceSquare
uint DistanceSquare(TileIndex t0, TileIndex t1)
Gets the 'Square' distance between the two given tiles.
Definition map.cpp:186
DistanceFromEdge
uint DistanceFromEdge(TileIndex tile)
Param the minimum distance to an edge.
Definition map.cpp:229
DistanceManhattan
uint DistanceManhattan(TileIndex t0, TileIndex t1)
Gets the Manhattan distance between the two given tiles.
Definition map.cpp:169
GetClosestWaterDistance
uint GetClosestWaterDistance(TileIndex tile, bool water)
Finds the distance for the closest tile with water/land given a tile.
Definition map.cpp:263
map_func.h
Functions related to maps.
TileAddXY
TileIndex TileAddXY(TileIndex tile, int x, int y)
Adds a given offset to a tile.
Definition map_func.h:483
TileAddByDir
TileIndex TileAddByDir(TileIndex tile, Direction dir)
Adds a Direction to a tile.
Definition map_func.h:612
ToTileIndexDiff
TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc)
Return the offset between two tiles from a TileIndexDiffC struct.
Definition map_func.h:453
TileAddByDiagDir
TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir)
Adds a DiagDir to a tile.
Definition map_func.h:624
TileDiffXY
TileIndexDiff TileDiffXY(int x, int y)
Calculates an offset for the given coordinate(-offset).
Definition map_func.h:401
TileXY
static TileIndex TileXY(uint x, uint y)
Returns the TileIndex of a coordinate.
Definition map_func.h:385
TileY
static uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition map_func.h:438
TileX
static uint TileX(TileIndex tile)
Get the X component of a tile.
Definition map_func.h:428
TileAdd
constexpr TileIndex TileAdd(TileIndex tile, TileIndexDiff offset)
Adds a given offset to a tile.
Definition map_func.h:470
RandomTile
#define RandomTile()
Get a valid random tile.
Definition map_func.h:665
TileOffsByDiagDir
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition map_func.h:583
TileIndexToTileIndexDiffC
TileIndexDiffC TileIndexToTileIndexDiffC(TileIndex tile_a, TileIndex tile_b)
Returns the diff between two tiles.
Definition map_func.h:544
TileIndexDiff
int32_t TileIndexDiff
An offset value between two tiles.
Definition map_type.h:23
IsInsideMM
constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
Definition math_func.hpp:267
RoundDivSU
constexpr int RoundDivSU(int a, uint b)
Computes round(a / b) for signed a and unsigned b.
Definition math_func.hpp:332
Clamp
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition math_func.hpp:79
GSF_FAKE_TOWNS
@ GSF_FAKE_TOWNS
Fake town GrfSpecFeature for NewGRF debugging (parent scope)
Definition newgrf.h:94
CBID_HOUSE_DRAW_FOUNDATIONS
@ CBID_HOUSE_DRAW_FOUNDATIONS
Called to determine the type (if any) of foundation to draw for house tile.
Definition newgrf_callbacks.h:229
CBID_HOUSE_CARGO_ACCEPTANCE
@ CBID_HOUSE_CARGO_ACCEPTANCE
Called to decide how much cargo a town building can accept.
Definition newgrf_callbacks.h:80
CBID_HOUSE_AUTOSLOPE
@ CBID_HOUSE_AUTOSLOPE
Called to determine if one can alter the ground below a house tile.
Definition newgrf_callbacks.h:232
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_ALLOW_CONSTRUCTION
@ CBID_HOUSE_ALLOW_CONSTRUCTION
Determine whether the house can be built on the specified tile.
Definition newgrf_callbacks.h:56
CBID_HOUSE_ACCEPT_CARGO
@ CBID_HOUSE_ACCEPT_CARGO
Called to determine which cargoes a town building should accept.
Definition newgrf_callbacks.h:116
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::AllowConstruction
@ AllowConstruction
decide whether the house can be built on a given tile
HouseCallbackMask::AcceptCargo
@ AcceptCargo
decides accepted types
HouseCallbackMask::CargoAcceptance
@ CargoAcceptance
decides amount of cargo acceptance
HouseCallbackMask::DrawFoundations
@ DrawFoundations
decides if default foundations need to be drawn
HouseCallbackMask::ProduceCargo
@ ProduceCargo
custom cargo production
HouseCallbackMask::Autoslope
@ Autoslope
decides allowance of autosloping
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
Convert8bitBooleanCallback
bool Convert8bitBooleanCallback(const GRFFile *grffile, uint16_t cbid, uint16_t cb_res)
Converts a callback result into a boolean.
Definition newgrf_commons.cpp:562
ConvertBooleanCallback
bool ConvertBooleanCallback(const GRFFile *grffile, uint16_t cbid, uint16_t cb_res)
Converts a callback result into a boolean.
Definition newgrf_commons.cpp:543
GetGRFConfig
GRFConfig * GetGRFConfig(uint32_t grfid, uint32_t mask)
Retrieve a NewGRF from the current config by its grfid.
Definition newgrf_config.cpp:622
newgrf_debug.h
Functions/types related to NewGRF debugging.
DeleteNewGRFInspectWindow
void DeleteNewGRFInspectWindow(GrfSpecFeature feature, uint index)
Delete inspect window for a given feature and index.
Definition newgrf_debug_gui.cpp:726
DecreaseBuildingCount
void DecreaseBuildingCount(Town *t, HouseID house_id)
DecreaseBuildingCount() Decrease the number of a building when it is deleted.
Definition newgrf_house.cpp:210
IncreaseBuildingCount
void IncreaseBuildingCount(Town *t, HouseID house_id)
IncreaseBuildingCount() Increase the count of a building when it has been added by a town.
Definition newgrf_house.cpp:191
InitializeBuildingCounts
void InitializeBuildingCounts()
Initialise global building counts and all town building counts.
Definition newgrf_house.cpp:164
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
news_func.h
Functions related to news.
AddNewsItem
void AddNewsItem(EncodedString &&headline, NewsType type, NewsStyle style, NewsFlags flags, NewsReference ref1={}, NewsReference ref2={}, std::unique_ptr< NewsAllocatedData > &&data=nullptr, AdviceType advice_type=AdviceType::Invalid)
Add a new newsitem to be shown.
Definition news_gui.cpp:900
NewsType::General
@ General
General news (from towns)
NewsType::IndustryOpen
@ IndustryOpen
Opening of industries.
NewsStyle::Company
@ Company
Company news item. (Newspaper with face)
NewsStyle::Normal
@ Normal
Normal news item. (Newspaper with text only)
object.h
Functions related to objects.
BuildObject
void BuildObject(ObjectType type, TileIndex tile, CompanyID owner=OWNER_NONE, struct Town *town=nullptr, uint8_t view=0)
Actually build the object.
Definition object_cmd.cpp:88
object_base.h
Base for all objects.
object_map.h
Map accessors for object tiles.
OBJECT_STATUE
static const ObjectType OBJECT_STATUE
Statue in towns.
Definition object_type.h:20
pool_func.hpp
Some methods of Pool are placed here in order to reduce compilation time and binary size.
INSTANTIATE_POOL_METHODS
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don't get linker errors.
Definition pool_func.hpp:210
IsPlainRailTile
static bool IsPlainRailTile(Tile t)
Checks whether the tile is a rail tile or rail tile with signals.
Definition rail_map.h:60
_random
Randomizer _random
Random used in the game state calculations.
Definition random_func.cpp:36
random_func.hpp
Pseudo random number generator.
RandomRange
uint32_t RandomRange(uint32_t limit, const std::source_location location=std::source_location::current())
Pick a random number between 0 and limit - 1, inclusive.
Definition random_func.hpp:88
Chance16
bool Chance16(const uint32_t a, const uint32_t b, const std::source_location location=std::source_location::current())
Flips a coin with given probability.
Definition random_func.hpp:134
CleanUpRoadBits
RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb)
Clean up unnecessary RoadBits of a planned tile.
Definition road.cpp:59
road.h
Road specific functions.
RoadTypeFlag::NoHouses
@ NoHouses
Bit number for setting this roadtype as not house friendly.
RoadTypeFlag::TownBuild
@ TownBuild
Bit number for allowing towns to build this roadtype.
GetMaskForRoadTramType
RoadTypes GetMaskForRoadTramType(RoadTramType rtt)
Get the mask for road types of the given RoadTramType.
Definition road.h:183
GetRoadTypeInfo
const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
Definition road.h:215
UpdateNearestTownForRoadTiles
void UpdateNearestTownForRoadTiles(bool invalidate)
Updates cached nearest town for all road tiles.
Definition road_cmd.cpp:1944
road_cmd.h
Road related functions.
DiagDirToRoadBits
RoadBits DiagDirToRoadBits(DiagDirection d)
Create the road-part which belongs to the given DiagDirection.
Definition road_func.h:96
road_internal.h
Functions used internally by the roads.
GetAnyRoadBits
RoadBits GetAnyRoadBits(Tile tile, RoadTramType rtt, bool straight_tunnel_bridge_entrance)
Returns the RoadBits on an arbitrary tile Special behaviour:
Definition road_map.cpp:54
SetRoadOwner
void SetRoadOwner(Tile t, RoadTramType rtt, Owner o)
Set the owner of a specific road type.
Definition road_map.h:235
HasTownOwnedRoad
bool HasTownOwnedRoad(Tile t)
Checks if given tile has town owned road.
Definition road_map.h:264
IsRoadDepotTile
static bool IsRoadDepotTile(Tile t)
Return whether a tile is a road depot tile.
Definition road_map.h:100
GetDisallowedRoadDirections
DisallowedRoadDirections GetDisallowedRoadDirections(Tile t)
Gets the disallowed directions.
Definition road_map.h:285
HasTileRoadType
bool HasTileRoadType(Tile t, RoadTramType rtt)
Check if a tile has a road or a tram road type.
Definition road_map.h:195
GetRoadDepotDirection
DiagDirection GetRoadDepotDirection(Tile t)
Get the direction of the exit of a road depot.
Definition road_map.h:550
IsRoadDepot
static bool IsRoadDepot(Tile t)
Return whether a tile is a road depot.
Definition road_map.h:90
IsNormalRoadTile
static bool IsNormalRoadTile(Tile t)
Return whether a tile is a normal road tile.
Definition road_map.h:58
IsRoadOwner
bool IsRoadOwner(Tile t, RoadTramType rtt, Owner o)
Check if a specific road type is owned by an owner.
Definition road_map.h:252
RoadBits
RoadBits
Enumeration for the road parts on a tile.
Definition road_type.h:56
ROAD_SW
@ ROAD_SW
South-west part.
Definition road_type.h:59
ROAD_ALL
@ ROAD_ALL
Full 4-way crossing.
Definition road_type.h:70
ROAD_NONE
@ ROAD_NONE
No road-part is build.
Definition road_type.h:57
ROAD_E
@ ROAD_E
Road at the two eastern edges.
Definition road_type.h:66
ROAD_NE
@ ROAD_NE
North-east part.
Definition road_type.h:61
ROAD_N
@ ROAD_N
Road at the two northern edges.
Definition road_type.h:65
ROAD_SE
@ ROAD_SE
South-east part.
Definition road_type.h:60
ROAD_Y
@ ROAD_Y
Full road along the y-axis (north-west + south-east)
Definition road_type.h:63
ROAD_S
@ ROAD_S
Road at the two southern edges.
Definition road_type.h:67
ROAD_W
@ ROAD_W
Road at the two western edges.
Definition road_type.h:68
ROAD_NW
@ ROAD_NW
North-west part.
Definition road_type.h:58
ROAD_X
@ ROAD_X
Full road along the x-axis (south-west + north-east)
Definition road_type.h:62
RTT_ROAD
@ RTT_ROAD
Road road type.
Definition road_type.h:38
RoadType
RoadType
The different roadtypes we support.
Definition road_type.h:23
INVALID_ROADTYPE
@ INVALID_ROADTYPE
flag for invalid roadtype
Definition road_type.h:28
ROADTYPE_ROAD
@ ROADTYPE_ROAD
Basic road type.
Definition road_type.h:25
DRD_NONE
@ DRD_NONE
None of the directions are disallowed.
Definition road_type.h:78
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_newgame
GameSettings _settings_newgame
Game settings for new games (updated from the intro screen).
Definition settings.cpp:62
_settings_client
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:60
GetSlopeMaxZ
static constexpr int GetSlopeMaxZ(Slope s)
Returns the height of the highest corner of a slope relative to TileZ (= minimal height)
Definition slope_func.h:160
IsSlopeWithOneCornerRaised
bool IsSlopeWithOneCornerRaised(Slope s)
Tests if a specific slope has exactly one corner raised.
Definition slope_func.h:88
IsSteepSlope
static constexpr bool IsSteepSlope(Slope s)
Checks if a slope is steep.
Definition slope_func.h:36
FlatteningFoundation
Foundation FlatteningFoundation(Slope s)
Returns the foundation needed to flatten a slope.
Definition slope_func.h:369
InclinedSlope
Slope InclinedSlope(DiagDirection dir)
Returns the slope that is inclined in a specific direction.
Definition slope_func.h:256
ComplementSlope
Slope ComplementSlope(Slope s)
Return the complement of a slope.
Definition slope_func.h:76
Slope
Slope
Enumeration for the slope-type.
Definition slope_type.h:48
SLOPE_W
@ SLOPE_W
the west corner of the tile is raised
Definition slope_type.h:50
SLOPE_ELEVATED
@ SLOPE_ELEVATED
bit mask containing all 'simple' slopes
Definition slope_type.h:61
SLOPE_E
@ SLOPE_E
the east corner of the tile is raised
Definition slope_type.h:52
SLOPE_S
@ SLOPE_S
the south corner of the tile is raised
Definition slope_type.h:51
SLOPE_N
@ SLOPE_N
the north corner of the tile is raised
Definition slope_type.h:53
SLOPE_SW
@ SLOPE_SW
south and west corner are raised
Definition slope_type.h:56
SLOPE_FLAT
@ SLOPE_FLAT
a flat tile
Definition slope_type.h:49
SLOPE_STEEP_W
@ SLOPE_STEEP_W
a steep slope falling to east (from west)
Definition slope_type.h:66
SLOPE_NE
@ SLOPE_NE
north and east corner are raised
Definition slope_type.h:58
SLOPE_STEEP_E
@ SLOPE_STEEP_E
a steep slope falling to west (from east)
Definition slope_type.h:68
SLOPE_SE
@ SLOPE_SE
south and east corner are raised
Definition slope_type.h:57
SLOPE_NW
@ SLOPE_NW
north and west corner are raised
Definition slope_type.h:55
SLOPE_STEEP_N
@ SLOPE_STEEP_N
a steep slope falling to south (from north)
Definition slope_type.h:69
SLOPE_STEEP_S
@ SLOPE_STEEP_S
a steep slope falling to north (from south)
Definition slope_type.h:67
Foundation
Foundation
Enumeration for Foundations.
Definition slope_type.h:93
FOUNDATION_LEVELED
@ FOUNDATION_LEVELED
The tile is leveled up to a flat slope.
Definition slope_type.h:95
FOUNDATION_NONE
@ FOUNDATION_NONE
The tile has no foundation, the slope remains unchanged.
Definition slope_type.h:94
SourceType::Town
@ Town
Source/destination is a town.
station_base.h
Base classes/functions for stations.
ForAllStationsAroundTiles
void ForAllStationsAroundTiles(const TileArea &ta, Func func)
Call a function on all stations that have any part of the requested area within their catchment.
Definition station_base.h:645
UpdateAllStationVirtCoords
void UpdateAllStationVirtCoords()
Update the virtual coords needed to draw the station sign for all stations.
Definition station_cmd.cpp:464
UpdateAirportsNoise
void UpdateAirportsNoise()
Recalculate the noise generated by the airports of each town.
Definition station_cmd.cpp:2604
ModifyStationRatingAround
void ModifyStationRatingAround(TileIndex tile, Owner owner, int amount, uint radius)
Forcibly modify station ratings near a given tile.
Definition station_cmd.cpp:4388
station_kdtree.h
Declarations for accessing the k-d tree of stations.
ForAllStationsRadius
void ForAllStationsRadius(TileIndex center, uint radius, Func func)
Call a function on all stations whose sign is within a radius of a center tile.
Definition station_kdtree.h:34
IsBayRoadStopTile
bool IsBayRoadStopTile(Tile t)
Is tile t a bay (non-drive through) road stop station?
Definition station_map.h:266
IsDriveThroughStopTile
bool IsDriveThroughStopTile(Tile t)
Is tile t a drive through road stop station or waypoint?
Definition station_map.h:276
GetDriveThroughStopAxis
Axis GetDriveThroughStopAxis(Tile t)
Gets the axis of the drive through stop.
Definition station_map.h:356
GetBayRoadStopDir
DiagDirection GetBayRoadStopDir(Tile t)
Gets the direction the bay road stop entrance points towards.
Definition station_map.h:344
IsAnyRoadStopTile
bool IsAnyRoadStopTile(Tile t)
Is tile t a road stop station?
Definition station_map.h:256
StationFacility::Airport
@ Airport
Station with an airport.
stdafx.h
Definition of base types and functions in a cross-platform compatible way.
lengthof
#define lengthof(array)
Return the length of an fixed size array.
Definition stdafx.h:271
Utf8StringLength
size_t Utf8StringLength(std::string_view str)
Get the length of an UTF-8 encoded string in number of characters and thus not the number of bytes th...
Definition string.cpp:349
string_func.h
Functions related to low-level strings.
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
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
AutoRestoreBackup
Class to backup a specific variable and restore it upon destruction of this object to prevent stack v...
Definition backup_type.hpp:150
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
BaseStation::owner
Owner owner
The owner of this station.
Definition base_station_base.h:68
CargoArray
Class for storing amounts of cargo.
Definition cargo_type.h:111
CargoPacket::InvalidateAllFrom
static void InvalidateAllFrom(Source src)
Invalidates (sets source_id to INVALID_SOURCE) all cargo packets from given source.
Definition cargopacket.cpp:132
CargoSpec
Specification of a cargo type.
Definition cargotype.h:74
CargoSpec::Iterate
static IterateWrapper Iterate(size_t from=0)
Returns an iterable ensemble of all valid CargoSpec.
Definition cargotype.h:192
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
Cheat::value
bool value
tells if the bool cheat is active or not
Definition cheat_type.h:18
Cheats::magic_bulldozer
Cheat magic_bulldozer
dynamite industries, objects
Definition cheat_type.h:27
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
ConstructionSettings::build_on_slopes
bool build_on_slopes
allow building on slopes
Definition settings_type.h:411
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
Depot
Definition depot_base.h:20
DifficultySettings::number_towns
uint8_t number_towns
the amount of towns
Definition settings_type.h:127
DifficultySettings::town_council_tolerance
uint8_t town_council_tolerance
minimum required town ratings to be allowed to demolish stuff
Definition settings_type.h:142
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::place_houses
PlaceHouses place_houses
players are allowed to place town houses.
Definition settings_type.h:559
EconomySettings::exclusive_rights
bool exclusive_rights
allow buying exclusive rights
Definition settings_type.h:546
EconomySettings::initial_city_size
uint8_t initial_city_size
multiplier for the initial size of the cities compared to towns
Definition settings_type.h:554
EconomySettings::town_layout
TownLayout town_layout
select town layout,
Definition settings_type.h:555
EconomySettings::allow_town_level_crossings
bool allow_town_level_crossings
towns are allowed to build level crossings
Definition settings_type.h:562
EconomySettings::town_growth_rate
uint8_t town_growth_rate
town growth rate
Definition settings_type.h:552
EconomySettings::allow_town_roads
bool allow_town_roads
towns are allowed to build roads (always allowed when generating world / in SE)
Definition settings_type.h:557
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
EconomySettings::town_cargogen_mode
TownCargoGenMode town_cargogen_mode
algorithm for generating cargo from houses,
Definition settings_type.h:556
EconomySettings::dist_local_authority
uint8_t dist_local_authority
distance for town local authority, default 20
Definition settings_type.h:545
EconomySettings::larger_towns
uint8_t larger_towns
the number of cities to build. These start off larger and grow twice as fast
Definition settings_type.h:553
GRFConfig
Information about GRF, used in the game and (part of it) in savegames.
Definition newgrf_config.h:158
GRFConfig::GetName
std::string GetName() const
Get the name of this grf.
Definition newgrf_config.cpp:85
GRFFilePropsBase::grffile
const struct GRFFile * grffile
grf file that introduced this entity
Definition newgrf_commons.h:318
GRFFilePropsBase::grfid
uint32_t grfid
grfid that introduced this entity.
Definition newgrf_commons.h:317
GRFFilePropsBase::HasGrfFile
bool HasGrfFile() const
Test if this entity was introduced by NewGRF.
Definition newgrf_commons.h:326
GUISettings::population_in_label
bool population_in_label
show the population of a town in its label?
Definition settings_type.h:201
GameCreationSettings::custom_town_number
uint16_t custom_town_number
manually entered number of towns
Definition settings_type.h:398
GameCreationSettings::landscape
LandscapeType landscape
the landscape we're currently in
Definition settings_type.h:395
GameCreationSettings::town_name
uint8_t town_name
the town name generator used for town names
Definition settings_type.h:394
GameSettings::economy
EconomySettings economy
settings to change the economy
Definition settings_type.h:642
GameSettings::construction
ConstructionSettings construction
construction of things in-game
Definition settings_type.h:635
GameSettings::difficulty
DifficultySettings difficulty
settings related to the difficulty
Definition settings_type.h:633
GameSettings::game_creation
GameCreationSettings game_creation
settings used during the creation of a game (map)
Definition settings_type.h:634
GoodsEntry
Stores station stats for a single cargo.
Definition station_base.h:167
HouseSpec
Definition house.h:98
HouseSpec::accepts_cargo
CargoType accepts_cargo[HOUSE_NUM_ACCEPTS]
input cargo slots
Definition house.h:108
HouseSpec::grf_prop
SubstituteGRFFileProps grf_prop
Properties related the the grf file.
Definition house.h:114
HouseSpec::probability
uint8_t probability
Relative probability of appearing (16 is the standard value)
Definition house.h:117
HouseSpec::removal_cost
uint8_t removal_cost
cost multiplier for removing it
Definition house.h:103
HouseSpec::mail_generation
uint8_t mail_generation
mail generation multiplier (tile based, as the acceptances below)
Definition house.h:106
HouseSpec::enabled
bool enabled
the house is available to build (true by default, but can be disabled by newgrf)
Definition house.h:111
HouseSpec::GetRemovalCost
Money GetRemovalCost() const
Get the cost for removing this house.
Definition town_cmd.cpp:232
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::remove_rating_decrease
uint16_t remove_rating_decrease
rating decrease if removed
Definition house.h:105
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::cargo_acceptance
uint8_t cargo_acceptance[HOUSE_NUM_ACCEPTS]
acceptance level for the cargo slots
Definition house.h:107
HouseSpec::Index
HouseID Index() const
Gets the index of this spec.
Definition newgrf_house.cpp:60
HouseSpec::class_id
HouseClassID class_id
defines the class this house has (not grf file based)
Definition house.h:119
HouseSpec::building_name
StringID building_name
building name
Definition house.h:104
HouseSpec::minimum_life
uint8_t minimum_life
The minimum number of years this house will survive before the town rebuilds it.
Definition house.h:122
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
Industry
Defines the internal data of a functional industry.
Definition industry.h:62
Industry::town
Town * town
Nearest town.
Definition industry.h:107
Industry::GetByTile
static Industry * GetByTile(TileIndex tile)
Get the industry of the given tile.
Definition industry.h:251
Map
Size related data of the map.
Definition map_func.h:206
Map::ScaleBySize
static uint ScaleBySize(uint n)
Scales the given value by the map size, where the given value is for a 256 by 256 map.
Definition map_func.h:340
Map::Iterate
static IterateWrapper Iterate()
Returns an iterable ensemble of all Tiles.
Definition map_func.h:375
Map::ScaleByLandProportion
static uint ScaleByLandProportion(uint n)
Scales the given value by the number of water tiles.
Definition map_func.h:318
Map::Size
static uint Size()
Get the size of the map.
Definition map_func.h:290
Object
An object, such as transmitter, on the map.
Definition object_base.h:23
Object::type
ObjectType type
Type of the object.
Definition object_base.h:24
Object::town
Town * town
Town the object is built in.
Definition object_base.h:25
Object::GetByTile
static Object * GetByTile(TileIndex tile)
Get the object associated with a tile.
Definition object_cmd.cpp:55
OrthogonalTileArea
Represents the covered area of e.g.
Definition tilearea_type.h:18
OrthogonalTileArea::Add
void Add(TileIndex to_add)
Add a single tile to a tile area; enlarge if needed.
Definition tilearea.cpp:43
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
PoolID< uint8_t, struct CompanyIDTag, 0xF, 0xFF >
Pool::PoolItem<&_industry_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 >::GetPoolSize
static size_t GetPoolSize()
Returns first unused index.
Definition pool_type.hpp:408
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<&_town_pool >::CanAllocateItem
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
Definition pool_type.hpp:357
Pool::PoolItem<&_town_pool >::IsValidID
static bool IsValidID(auto index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
Definition pool_type.hpp:376
Pool::PoolItem<&_town_pool >::CleaningPool
static bool CleaningPool()
Returns current state of pool cleaning - yes or no.
Definition pool_type.hpp:366
Pool::PoolItem<&_town_pool >::GetIfValid
static Titem * GetIfValid(auto index)
Returns Titem with given index.
Definition pool_type.hpp:398
Pool
Base class for all pools.
Definition pool_type.hpp:133
Pool::MAX_SIZE
static constexpr size_t MAX_SIZE
Make template parameter accessible from outside.
Definition pool_type.hpp:135
Source
A location from where cargo can come from (or go to).
Definition source_type.h:32
SpecializedStation< Station, false >::Iterate
static Pool::IterateWrapper< Station > Iterate(size_t from=0)
Returns an iterable ensemble of all valid stations of type T.
Definition base_station_base.h:299
Station
Station data structure.
Definition station_base.h:520
Station::CatchmentCoversTown
bool CatchmentCoversTown(TownID t) const
Test if the given town ID is covered by our catchment area.
Definition station.cpp:452
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > >
SubstituteGRFFileProps::override_id
uint16_t override_id
id of the entity been replaced by
Definition newgrf_commons.h:469
TileDesc
Tile description for the 'land area information' tool.
Definition tile_cmd.h:36
TileDesc::grf
std::optional< std::string > grf
newGRF used for the tile contents
Definition tile_cmd.h:47
TileDesc::str
StringID str
Description of the tile.
Definition tile_cmd.h:37
TileDesc::owner
std::array< Owner, 4 > owner
Name of the owner(s)
Definition tile_cmd.h:39
TileDesc::dparam
uint64_t dparam
Parameter of the str string.
Definition tile_cmd.h:38
TileDesc::town_can_upgrade
std::optional< bool > town_can_upgrade
Whether the town can upgrade this house during town growth.
Definition tile_cmd.h:54
TileIndexDiffC
A pair-construct of a TileIndexDiff.
Definition map_type.h:31
TileIndexDiffC::x
int16_t x
The x value of the coordinate.
Definition map_type.h:32
TileIndexDiffC::y
int16_t y
The y value of the coordinate.
Definition map_type.h:33
TileInfo
Tile information, used while rendering the tile.
Definition tile_cmd.h:30
TileInfo::tileh
Slope tileh
Slope of the tile.
Definition tile_cmd.h:31
TileInfo::tile
TileIndex tile
Tile index.
Definition tile_cmd.h:32
TileTypeProcs
Set of callback functions for performing tile operations of a given tile type.
Definition tile_cmd.h:152
TownCache::population
uint32_t population
Current population of people.
Definition town.h:53
TownCache::num_houses
uint32_t num_houses
Amount of houses.
Definition town.h:52
TownCache::sign
TrackedViewportSign sign
Location of name sign, UpdateVirtCoord updates this.
Definition town.h:54
TownCache::building_counts
BuildingCounts< uint16_t > building_counts
The number of each type of building in the town.
Definition town.h:57
TownCache::squared_town_zone_radius
std::array< uint32_t, NUM_HOUSE_ZONES > squared_town_zone_radius
UpdateTownRadius updates this given the house count.
Definition town.h:56
TownNameParams
Struct holding parameters used to generate town name.
Definition townname_type.h:26
TownNameParams::type
uint16_t type
town name style
Definition townname_type.h:28
TownNameParams::grfid
uint32_t grfid
newgrf ID (0 if not used)
Definition townname_type.h:27
Town::SuppliedHistory
Definition town.h:88
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::statues
CompanyMask statues
which companies have a statue?
Definition town.h:79
Town::time_until_rebuild
uint16_t time_until_rebuild
time until we rebuild a house
Definition town.h:142
Town::cached_name
std::string cached_name
NOSAVE: Cache of the resolved name of the town, if not using a custom town name.
Definition town.h:73
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::layout
TownLayout layout
town specific road layout
Definition town.h:151
Town::GetRandom
static Town * GetRandom()
Return a random valid town.
Definition town_cmd.cpp:203
Town::name
std::string name
Custom town name. If empty, the town was not renamed and uses the generated name.
Definition town.h:72
Town::grow_counter
uint16_t grow_counter
counter to count when to grow, value is smaller than or equal to growth_rate
Definition town.h:144
Town::flags
TownFlags flags
See TownFlags.
Definition town.h:75
Town::cache
TownCache cache
Container for all cacheable data.
Definition town.h:66
Town::unwanted
TypedIndexContainer< std::array< uint8_t, MAX_COMPANIES >, CompanyID > unwanted
how many months companies aren't wanted by towns (bribe)
Definition town.h:83
Town::exclusivity
CompanyID exclusivity
which company has exclusivity
Definition town.h:84
Town::valid_history
ValidHistoryMask valid_history
Mask of valid history records.
Definition town.h:112
Town::InitializeLayout
void InitializeLayout(TownLayout layout)
Assign the town layout.
Definition town_cmd.cpp:189
Town::show_zone
bool show_zone
NOSAVE: mark town to show the local authority zone in the viewports.
Definition town.h:153
Town::exclusive_counter
uint8_t exclusive_counter
months till the exclusivity expires
Definition town.h:85
Town::UpdateVirtCoord
void UpdateVirtCoord()
Resize the sign (label) of the town after it changes population.
Definition town_cmd.cpp:398
Town::have_ratings
CompanyMask have_ratings
which companies have a rating
Definition town.h:82
Town::~Town
~Town()
Destroy the town.
Definition town_cmd.cpp:115
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::stations_near
StationList stations_near
NOSAVE: List of nearby stations.
Definition town.h:140
Town::PostDestructor
static void PostDestructor(size_t index)
Invalidating of the "nearest town cache" has to be done after removing item from the pool.
Definition town_cmd.cpp:174
Town::road_build_months
uint8_t road_build_months
fund road reconstruction in action?
Definition town.h:148
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
TrackedViewportSign::UpdatePosition
void UpdatePosition(int center, int top, std::string_view str, std::string_view str_small={})
Update the position of the viewport sign.
Definition viewport_type.h:69
TrackedViewportSign::kdtree_valid
bool kdtree_valid
Are the sign data valid for use with the _viewport_sign_kdtree?
Definition viewport_type.h:61
Waypoint
Representation of a waypoint.
Definition waypoint_base.h:23
DeleteSubsidyWith
void DeleteSubsidyWith(Source source)
Delete the subsidies associated with a given cargo source type and id.
Definition subsidy.cpp:119
subsidy_func.h
Functions related to subsidies.
terraform_cmd.h
Command definitions related to terraforming.
IsTileFlat
bool IsTileFlat(TileIndex tile, int *h)
Check if a given tile is flat.
Definition tile_map.cpp:95
GetTileMaxZ
int GetTileMaxZ(TileIndex t)
Get top height of the tile inside the map.
Definition tile_map.cpp:136
GetTileZ
int GetTileZ(TileIndex tile)
Get bottom height of the tile.
Definition tile_map.cpp:116
IsTileType
static bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition tile_map.h:150
TileHash
uint TileHash(uint x, uint y)
Calculate a hash value from a tile position.
Definition tile_map.h:324
TileHeight
static uint TileHeight(Tile tile)
Returns the height of a tile.
Definition tile_map.h:29
IsTileOwner
bool IsTileOwner(Tile tile, Owner owner)
Checks if a tile belongs to the given owner.
Definition tile_map.h:214
GetTileMaxPixelZ
int GetTileMaxPixelZ(TileIndex tile)
Get top height of the tile.
Definition tile_map.h:312
IsValidTile
bool IsValidTile(Tile tile)
Checks if a tile is valid.
Definition tile_map.h:161
TileHash2Bit
uint TileHash2Bit(uint x, uint y)
Get the last two bits of the TileHash from a tile position.
Definition tile_map.h:342
GetTropicZone
TropicZone GetTropicZone(Tile tile)
Get the tropic zone.
Definition tile_map.h:238
GetTileSlope
Slope GetTileSlope(TileIndex tile)
Return the slope of a given tile inside the map.
Definition tile_map.h:279
GetTileType
static TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
Definition tile_map.h:96
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_SIZE
static constexpr uint TILE_SIZE
Tile size in world coordinates.
Definition tile_type.h:15
MP_TREES
@ MP_TREES
Tile got trees.
Definition tile_type.h:52
MP_ROAD
@ MP_ROAD
A tile with road (or tram tracks)
Definition tile_type.h:50
MP_STATION
@ MP_STATION
A tile of a station.
Definition tile_type.h:53
MP_TUNNELBRIDGE
@ MP_TUNNELBRIDGE
Tunnel entry/exit and bridge heads.
Definition tile_type.h:57
MP_CLEAR
@ MP_CLEAR
A tile without any structures, i.e. grass, rocks, farm fields etc.
Definition tile_type.h:48
MP_HOUSE
@ MP_HOUSE
A house by a town.
Definition tile_type.h:51
MP_WATER
@ MP_WATER
Water tile.
Definition tile_type.h:54
MP_RAILWAY
@ MP_RAILWAY
A railway.
Definition tile_type.h:49
MP_INDUSTRY
@ MP_INDUSTRY
Part of an industry.
Definition tile_type.h:56
MP_VOID
@ MP_VOID
Invisible tiles at the SW and SE border.
Definition tile_type.h:55
MP_OBJECT
@ MP_OBJECT
Contains objects such as transmitters and owned land.
Definition tile_type.h:58
TileArea
OrthogonalTileArea TileArea
Shorthand for the much more common orthogonal tile area.
Definition tilearea_type.h:102
timer.h
Definition of Interval and OneShot timers.
timer_game_calendar.h
Definition of the game-calendar-timer.
timer_game_economy.h
Definition of the game-economy-timer.
timer_game_tick.h
Definition of the tick-based game-timer.
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
TownRatingCheckType
TownRatingCheckType
Action types that a company must ask permission for to a town authority.
Definition town.h:224
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
CUSTOM_TOWN_NUMBER_DIFFICULTY
static const uint CUSTOM_TOWN_NUMBER_DIFFICULTY
value for custom town number in difficulty settings
Definition town.h:29
CalcClosestTownFromTile
Town * CalcClosestTownFromTile(TileIndex tile, uint threshold=UINT_MAX)
Return the town closest to the given tile within threshold.
Definition town_cmd.cpp:3943
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::BuildStatue
@ BuildStatue
Build a statue.
TownAction::BuyRights
@ BuyRights
Buy exclusive transport rights.
TownAction::FundBuildings
@ FundBuildings
Fund new buildings.
TownFlag::HasChurch
@ HasChurch
There can be only one church by town.
TownFlag::CustomGrowth
@ CustomGrowth
Growth rate is controlled by GS.
TownFlag::HasStadium
@ HasStadium
There can be only one stadium by town.
TownFlag::IsGrowing
@ IsGrowing
Conditions for town growth are met. Grow according to Town::growth_rate.
TOWN_GROWTH_RATE_NONE
static const uint16_t TOWN_GROWTH_RATE_NONE
Special value for Town::growth_rate to disable town growth.
Definition town.h:34
RoadTypesAllowHouseHere
static bool RoadTypesAllowHouseHere(TileIndex t)
Checks whether at least one surrounding road allows to build a house here.
Definition town_cmd.cpp:1466
CheckFree2x2Area
static bool CheckFree2x2Area(TileIndex tile, int z, bool noslope)
Checks if a house of size 2x2 can be built at this tile.
Definition town_cmd.cpp:2631
CmdFoundTown
std::tuple< CommandCost, Money, TownID > CmdFoundTown(DoCommandFlags flags, TileIndex tile, TownSize size, bool city, TownLayout layout, bool random_location, uint32_t townnameparts, const std::string &text)
Create a new town.
Definition town_cmd.cpp:2197
ChangeTownRating
void ChangeTownRating(Town *t, int add, int max, DoCommandFlags flags)
Changes town rating of the current company.
Definition town_cmd.cpp:4040
GetClimateMaskForLandscape
HouseZones GetClimateMaskForLandscape()
Get the HouseZones climate mask for the current landscape type.
Definition town_cmd.cpp:2366
GrowTownAtRoad
static bool GrowTownAtRoad(Town *t, TileIndex tile, TownExpandModes modes)
Try to grow a town at a given road tile.
Definition town_cmd.cpp:1793
TownActionAdvertiseSmall
static CommandCost TownActionAdvertiseSmall(Town *t, DoCommandFlags flags)
Perform the "small advertising campaign" town action.
Definition town_cmd.cpp:3412
TownActionFundBuildings
static CommandCost TownActionFundBuildings(Town *t, DoCommandFlags flags)
Perform the "fund new buildings" town action.
Definition town_cmd.cpp:3552
IsTileAlignedToGrid
static bool IsTileAlignedToGrid(TileIndex tile, TownLayout layout)
Towns must all be placed on the same grid or when they eventually interpenetrate their road networks ...
Definition town_cmd.cpp:2316
TownActionBuildStatue
static CommandCost TownActionBuildStatue(Town *t, DoCommandFlags flags)
Perform a 9x9 tiles circular search from the center of the town in order to find a free tile to place...
Definition town_cmd.cpp:3493
TownActionBribe
static CommandCost TownActionBribe(Town *t, DoCommandFlags flags)
Perform the "bribe" town action.
Definition town_cmd.cpp:3616
GetHouseNorthPart
TileIndexDiff GetHouseNorthPart(HouseID &house)
Determines if a given HouseID is part of a multitile house.
Definition town_cmd.cpp:3025
GetRating
static int GetRating(const Town *t)
Get the rating of a town for the _current_company.
Definition town_cmd.cpp:4022
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
ClearTownHouse
void ClearTownHouse(Town *t, TileIndex tile)
Clear a town house.
Definition town_cmd.cpp:3050
GetNormalGrowthRate
static uint GetNormalGrowthRate(Town *t)
Calculates town growth rate in normal conditions (custom growth rate not set).
Definition town_cmd.cpp:3836
GetMaskOfTownActions
TownActions GetMaskOfTownActions(CompanyID cid, const Town *t)
Get a list of available town authority actions.
Definition town_cmd.cpp:3672
TownActionBuyRights
static CommandCost TownActionBuyRights(Town *t, DoCommandFlags flags)
Perform the "buy exclusive transport rights" town action.
Definition town_cmd.cpp:3585
GrowTownWithBridge
static bool GrowTownWithBridge(const Town *t, const TileIndex tile, const DiagDirection bridge_dir)
Grows the town with a bridge.
Definition town_cmd.cpp:1312
FindFirstCargoWithTownAcceptanceEffect
const CargoSpec * FindFirstCargoWithTownAcceptanceEffect(TownAcceptanceEffect effect)
Determines the first cargo with a certain town effect.
Definition town_cmd.cpp:3127
FindNearestGoodCoastalTownSpot
static TileIndex FindNearestGoodCoastalTownSpot(TileIndex tile, TownLayout layout)
Given a spot on the map (presumed to be a water tile), find a good coastal spot to build a city.
Definition town_cmd.cpp:2337
ClosestTownFromTile
Town * ClosestTownFromTile(TileIndex tile, uint threshold)
Return the town closest (in distance or ownership) to a given tile, within a given threshold.
Definition town_cmd.cpp:3961
IsRoadAllowedHere
static bool IsRoadAllowedHere(Town *t, TileIndex tile, DiagDirection dir)
Check if a Road is allowed on a given tile.
Definition town_cmd.cpp:1077
CanRoadContinueIntoNextTile
static bool CanRoadContinueIntoNextTile(const Town *t, const TileIndex tile, const DiagDirection road_dir)
Checks if a town road can be continued into the next tile.
Definition town_cmd.cpp:1266
TryBuildTownHouse
static bool TryBuildTownHouse(Town *t, TileIndex tile, TownExpandModes modes)
Tries to build a house at this tile.
Definition town_cmd.cpp:2814
UpdateTownGrowCounter
static void UpdateTownGrowCounter(Town *t, uint16_t prev_growth_rate)
Updates town grow counter after growth rate change.
Definition town_cmd.cpp:3804
CountActiveStations
static int CountActiveStations(Town *t)
Calculates amount of active stations in the range of town (HZB_TOWN_EDGE).
Definition town_cmd.cpp:3819
IsNeighbourRoadTile
static bool IsNeighbourRoadTile(TileIndex tile, const DiagDirection dir, uint dist_multi)
Check for parallel road inside a given distance.
Definition town_cmd.cpp:1043
_generating_town
static bool _generating_town
Set if a town is being generated.
Definition town_cmd.cpp:88
MakeTownHouse
static void MakeTownHouse(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool is_protected)
Write house information into the map.
Definition town_cmd.cpp:2565
CheckTownBuild2x2House
static bool CheckTownBuild2x2House(TileIndex *tile, Town *t, int maxz, bool noslope, TownExpandModes modes)
Checks if a 1x2 or 2x1 building is allowed here, accounting for road layout and tile heights.
Definition town_cmd.cpp:2749
TileLoop_Town
static void TileLoop_Town(TileIndex tile)
Tile callback function.
Definition town_cmd.cpp:602
CanBuildHouseHere
static bool CanBuildHouseHere(TileIndex tile, bool noslope)
Check if a house can be built here, based on slope, whether there's a bridge above,...
Definition town_cmd.cpp:2587
TownLayoutAllowsHouseHere
static bool TownLayoutAllowsHouseHere(Town *t, TileIndex tile, TownExpandModes modes)
Checks if the current town layout allows building here.
Definition town_cmd.cpp:2652
GenerateTowns
bool GenerateTowns(TownLayout layout, std::optional< uint > number)
Generate a number of towns with a given layout.
Definition town_cmd.cpp:2448
GrowTownWithRoad
static bool GrowTownWithRoad(const Town *t, TileIndex tile, RoadBits rcmd)
Grows the town with a road piece.
Definition town_cmd.cpp:1251
CmdDoTownAction
CommandCost CmdDoTownAction(DoCommandFlags flags, TownID town_id, TownAction action)
Do a town action.
Definition town_cmd.cpp:3728
TownGenerateCargoBinomial
static void TownGenerateCargoBinomial(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
Generate cargo for a house using the binomial algorithm.
Definition town_cmd.cpp:579
UpdateTownRating
static void UpdateTownRating(Town *t)
Monthly callback to update town and station ratings.
Definition town_cmd.cpp:3766
TownLayoutAllows2x2HouseHere
static bool TownLayoutAllows2x2HouseHere(Town *t, TileIndex tile, TownExpandModes modes)
Checks if the current town layout allows a 2x2 building here.
Definition town_cmd.cpp:2685
AdvanceHouseConstruction
static void AdvanceHouseConstruction(TileIndex tile)
Increase the construction stage of a house.
Definition town_cmd.cpp:516
TownCanGrowRoad
static bool TownCanGrowRoad(TileIndex tile)
Test if town can grow road onto a specific tile.
Definition town_cmd.cpp:1492
GetWorldPopulation
uint32_t GetWorldPopulation()
Get the total population, the sum of all towns in the world.
Definition town_cmd.cpp:457
GrowTownWithTunnel
static bool GrowTownWithTunnel(const Town *t, const TileIndex tile, const DiagDirection tunnel_dir)
Grows the town with a tunnel.
Definition town_cmd.cpp:1401
_town_test_ratings
static std::map< const Town *, int > _town_test_ratings
Map of towns to modified ratings, while in town rating test-mode.
Definition town_cmd.cpp:3995
ClearTile_Town
static CommandCost ClearTile_Town(TileIndex tile, DoCommandFlags flags)
Callback function to clear a house tile.
Definition town_cmd.cpp:717
CheckClearTile
static bool CheckClearTile(TileIndex tile)
Check whether the land can be cleared.
Definition town_cmd.cpp:3478
TownActionAdvertiseMedium
static CommandCost TownActionAdvertiseMedium(Town *t, DoCommandFlags flags)
Perform the "medium advertising campaign" town action.
Definition town_cmd.cpp:3426
TownGenerateCargoOriginal
static void TownGenerateCargoOriginal(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
Generate cargo for a house using the original algorithm.
Definition town_cmd.cpp:559
ClearMakeHouseTile
static void ClearMakeHouseTile(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool is_protected)
Clears tile and builds a house or house part.
Definition town_cmd.cpp:2541
UpdateTownMaxPass
void UpdateTownMaxPass(Town *t)
Update the maximum amount of monthly passengers and mail for a town, based on its population.
Definition town_cmd.cpp:2003
ChangePopulation
static void ChangePopulation(Town *t, int mod)
Change the town's population as recorded in the town cache, town label, and town directory.
Definition town_cmd.cpp:442
GetAcceptedCargoOfHouse
CargoArray GetAcceptedCargoOfHouse(const HouseSpec *hs)
Get accepted cargo of a house prototype.
Definition town_cmd.cpp:858
AddAcceptedCargoSetMask
static void AddAcceptedCargoSetMask(CargoType cargo, uint amount, CargoArray &acceptance, CargoTypes &always_accepted)
Fill cargo acceptance array and always_accepted mask, if cargo type is valid.
Definition town_cmd.cpp:789
RandomDiagDir
static DiagDirection RandomDiagDir()
Return a random direction.
Definition town_cmd.cpp:255
AlignTileToGrid
static TileIndex AlignTileToGrid(TileIndex tile, TownLayout layout)
Towns must all be placed on the same grid or when they eventually interpenetrate their road networks ...
Definition town_cmd.cpp:2298
CreateRandomTown
static Town * CreateRandomTown(uint attempts, uint32_t townnameparts, TownSize size, bool city, TownLayout layout)
Create a random town somewhere in the world.
Definition town_cmd.cpp:2386
RemoveNearbyStations
static void RemoveNearbyStations(Town *t, TileIndex tile, BuildingFlags flags)
Remove stations from nearby station list if a town is no longer in the catchment area of each.
Definition town_cmd.cpp:471
GetTownActionCost
uint8_t GetTownActionCost(TownAction action)
Get cost factors for a TownAction.
Definition town_cmd.cpp:3391
CmdTownSetText
CommandCost CmdTownSetText(DoCommandFlags flags, TownID town_id, const EncodedString &text)
Set a custom text in the Town window.
Definition town_cmd.cpp:3172
CalcClosestTownFromTile
Town * CalcClosestTownFromTile(TileIndex tile, uint threshold)
Return the town closest to the given tile within threshold.
Definition town_cmd.cpp:3943
CmdTownGrowthRate
CommandCost CmdTownGrowthRate(DoCommandFlags flags, TownID town_id, uint16_t growth_rate)
Change the growth rate of the town.
Definition town_cmd.cpp:3194
GrowTownInTile
static TownGrowthResult GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection target_dir, Town *t1, TownExpandModes modes)
Grows the given town.
Definition town_cmd.cpp:1535
TownActionRoadRebuild
static CommandCost TownActionRoadRebuild(Town *t, DoCommandFlags flags)
Perform the "local road reconstruction" town action.
Definition town_cmd.cpp:3454
ClearAllTownCachedNames
void ClearAllTownCachedNames()
Clear the cached_name of all towns.
Definition town_cmd.cpp:430
CmdDeleteTown
CommandCost CmdDeleteTown(DoCommandFlags flags, TownID town_id)
Delete a town (scenario editor or worldgen only).
Definition town_cmd.cpp:3295
GetFoundation_Town
static Foundation GetFoundation_Town(TileIndex tile, Slope tileh)
Get the foundation for a house.
Definition town_cmd.cpp:315
GetTownRoadTypeFirstIntroductionDate
static TimerGameCalendar::Date GetTownRoadTypeFirstIntroductionDate()
Get the calendar date of the earliest town-buildable road type.
Definition town_cmd.cpp:995
AnimateTile_Town
static void AnimateTile_Town(TileIndex tile)
Animate a tile for a town.
Definition town_cmd.cpp:339
CmdPlaceHouse
CommandCost CmdPlaceHouse(DoCommandFlags flags, TileIndex tile, HouseID house, bool is_protected, bool replace)
Place an individual house.
Definition town_cmd.cpp:2947
_tile_type_town_procs
const TileTypeProcs _tile_type_town_procs
Tile callback functions for a town.
Definition landscape.cpp:55
GetTownRoadType
RoadType GetTownRoadType()
Get the road type that towns should build at this current moment.
Definition town_cmd.cpp:965
GetTownRoadBits
static RoadBits GetTownRoadBits(TileIndex tile)
Return the RoadBits of a tile, ignoring depot and bay road stops.
Definition town_cmd.cpp:954
CmdRenameTown
CommandCost CmdRenameTown(DoCommandFlags flags, TownID town_id, const std::string &text)
Rename a town (server-only).
Definition town_cmd.cpp:3093
CmdTownCargoGoal
CommandCost CmdTownCargoGoal(DoCommandFlags flags, TownID town_id, TownAcceptanceEffect tae, uint32_t goal)
Change the cargo goal of a town.
Definition town_cmd.cpp:3143
DoCreateTown
static void DoCreateTown(Town *t, TileIndex tile, uint32_t townnameparts, TownSize size, bool city, TownLayout layout, bool manual)
Actually create a town.
Definition town_cmd.cpp:2036
CheckforTownRating
CommandCost CheckforTownRating(DoCommandFlags flags, Town *t, TownRatingCheckType type)
Does the town authority allow the (destructive) action of the current company?
Definition town_cmd.cpp:4077
GetTownRadiusGroup
HouseZone GetTownRadiusGroup(const Town *t, TileIndex tile)
Returns the bit corresponding to the town zone of the specified tile.
Definition town_cmd.cpp:2516
CheckTownBuild2House
static bool CheckTownBuild2House(TileIndex *tile, Town *t, int maxz, bool noslope, DiagDirection second, TownExpandModes modes)
Checks if a 1x2 or 2x1 building is allowed here, accounting for road layout and tile heights.
Definition town_cmd.cpp:2724
TownCanBePlacedHere
static CommandCost TownCanBePlacedHere(TileIndex tile, bool check_surrounding)
Check if it's possible to place a town on a given tile.
Definition town_cmd.cpp:2119
TestTownOwnsBridge
static bool TestTownOwnsBridge(TileIndex tile, const Town *t)
Check if a town 'owns' a bridge.
Definition town_cmd.cpp:99
OnTick_Town
void OnTick_Town()
Iterate through all towns and call their tick handler.
Definition town_cmd.cpp:940
TownActionAdvertiseLarge
static CommandCost TownActionAdvertiseLarge(Town *t, DoCommandFlags flags)
Perform the "large advertising campaign" town action.
Definition town_cmd.cpp:3440
CheckTownRoadTypes
bool CheckTownRoadTypes()
Check if towns are able to build road.
Definition town_cmd.cpp:1015
GrowTown
static bool GrowTown(Town *t, TownExpandModes modes)
Grow the town.
Definition town_cmd.cpp:1897
UpdateTownGrowthRate
static void UpdateTownGrowthRate(Town *t)
Updates town growth rate.
Definition town_cmd.cpp:3863
GetTownRoadGridElement
static RoadBits GetTownRoadGridElement(Town *t, TileIndex tile, DiagDirection dir)
Generate the RoadBits of a grid tile.
Definition town_cmd.cpp:1154
AdvanceSingleHouseConstruction
static void AdvanceSingleHouseConstruction(TileIndex tile)
Helper function for house construction stage progression.
Definition town_cmd.cpp:493
TownTickHandler
static void TownTickHandler(Town *t)
Handle the town tick for a single town, by growing the town if desired.
Definition town_cmd.cpp:921
SetTownRatingTestMode
void SetTownRatingTestMode(bool mode)
Switch the town rating to test-mode, to allow commands to be tested without affecting current ratings...
Definition town_cmd.cpp:4002
_town_rating_test
static bool _town_rating_test
If true, town rating is in test-mode.
Definition town_cmd.cpp:3994
CmdTownRating
CommandCost CmdTownRating(DoCommandFlags flags, TownID town_id, CompanyID company_id, int16_t rating)
Change the rating of a company in a town.
Definition town_cmd.cpp:3232
UpdateTownRadius
void UpdateTownRadius(Town *t)
Update the cached town zone radii of a town, based on the number of houses.
Definition town_cmd.cpp:1956
GrowTownWithExtraHouse
static bool GrowTownWithExtraHouse(Town *t, TileIndex tile, TownExpandModes modes)
Grows the town with an extra house.
Definition town_cmd.cpp:1213
AddAcceptedCargoOfHouse
void AddAcceptedCargoOfHouse(TileIndex tile, HouseID house, const HouseSpec *hs, Town *t, CargoArray &acceptance, CargoTypes &always_accepted)
Determine accepted cargo for a house.
Definition town_cmd.cpp:805
TownAllowedToBuildRoads
static bool TownAllowedToBuildRoads(TownExpandModes modes)
Check if the town is allowed to build roads.
Definition town_cmd.cpp:1505
CmdExpandTown
CommandCost CmdExpandTown(DoCommandFlags flags, TownID town_id, uint32_t grow_amount, TownExpandModes modes)
Expand a town (scenario editor only).
Definition town_cmd.cpp:3257
IsCloseToTown
static bool IsCloseToTown(TileIndex tile, uint dist)
Determines if a town is close to a tile.
Definition town_cmd.cpp:390
UpdateTownGrowth
static void UpdateTownGrowth(Town *t)
Updates town growth state (whether it is growing or not).
Definition town_cmd.cpp:3876
DoClearTownHouseHelper
static void DoClearTownHouseHelper(TileIndex tile, Town *t, HouseID house)
Update data structures when a house is removed.
Definition town_cmd.cpp:3009
GenRandomRoadBits
static RoadBits GenRandomRoadBits()
Generate a random road block.
Definition town_cmd.cpp:1883
CheckBuildHouseSameZ
static bool CheckBuildHouseSameZ(TileIndex tile, int z, bool noslope)
Check if a tile where we want to build a multi-tile house has an appropriate max Z.
Definition town_cmd.cpp:2612
CheckIfAuthorityAllowsNewStation
CommandCost CheckIfAuthorityAllowsNewStation(TileIndex tile, DoCommandFlags flags)
Checks whether the local authority allows construction of a new station (rail, road,...
Definition town_cmd.cpp:3920
CanFollowRoad
static bool CanFollowRoad(TileIndex tile, DiagDirection dir, TownExpandModes modes)
Checks whether a road can be followed or is a dead end, that can not be extended to the next tile.
Definition town_cmd.cpp:1751
BuildTownHouse
static void BuildTownHouse(Town *t, TileIndex tile, const HouseSpec *hs, HouseID house, uint8_t random_bits, bool house_completed, bool is_protected)
Build a house at this tile.
Definition town_cmd.cpp:2775
TownGenerateCargo
static void TownGenerateCargo(Town *t, CargoType cargo, uint amount, StationFinder &stations, bool affected_by_recession)
Generate cargo for a house, scaled by the current economy scale.
Definition town_cmd.cpp:533
IsUniqueTownName
static bool IsUniqueTownName(const std::string &name)
Verifies this custom name is unique.
Definition town_cmd.cpp:2176
DrawTile_Town
static void DrawTile_Town(TileInfo *ti)
Draw a house and its tile.
Definition town_cmd.cpp:264
UpdateAllTownVirtCoords
void UpdateAllTownVirtCoords()
Update the virtual coords needed to draw the town sign for all towns.
Definition town_cmd.cpp:422
town_cmd.h
Command definitions related to towns.
town_kdtree.h
Declarations for accessing the k-d tree of towns.
town_land.h
Sprites to use and how to display them for town tiles.
_town_draw_tile_data
static const DrawBuildingsTileStruct _town_draw_tile_data[]
structure of houses graphics
Definition town_land.h:27
IncrementHouseAge
void IncrementHouseAge(Tile t)
Increments the age of the house.
Definition town_map.h:259
HaltLift
void HaltLift(Tile t)
Stop the lift of this animated house from moving.
Definition town_map.h:137
GetHouseType
HouseID GetHouseType(Tile t)
Get the type of this house, which is an index into the house spec array.
Definition town_map.h:60
ResetHouseAge
void ResetHouseAge(Tile t)
Sets the age of the house to zero.
Definition town_map.h:248
MakeHouseTile
void MakeHouseTile(Tile t, TownID tid, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool house_protected)
Make the tile a house.
Definition town_map.h:375
IncHouseConstructionTick
void IncHouseConstructionTick(Tile t)
Sets the increment stage of a house It is working with the whole counter + stage 5 bits,...
Definition town_map.h:230
GetLiftPosition
uint8_t GetLiftPosition(Tile t)
Get the position of the lift on this animated house.
Definition town_map.h:147
SetLiftDestination
void SetLiftDestination(Tile t, uint8_t dest)
Set the new destination of the lift for this animated house, and activate the LiftHasDestination bit.
Definition town_map.h:115
GetHouseAge
TimerGameCalendar::Year GetHouseAge(Tile t)
Get the age of the house.
Definition town_map.h:271
SetLiftPosition
void SetLiftPosition(Tile t, uint8_t pos)
Set the position of the lift on this animated house.
Definition town_map.h:157
GetLiftDestination
uint8_t GetLiftDestination(Tile t)
Get the current destination for this lift.
Definition town_map.h:126
GetHouseBuildingStage
uint8_t GetHouseBuildingStage(Tile t)
House Construction Scheme.
Definition town_map.h:205
GetTownIndex
TownID GetTownIndex(Tile t)
Get the index of which town this house/street is attached to.
Definition town_map.h:23
SetTownIndex
void SetTownIndex(Tile t, TownID index)
Set the town index for a road or house tile.
Definition town_map.h:35
LiftHasDestination
bool LiftHasDestination(Tile t)
Check if the lift of this animated house has a destination.
Definition town_map.h:104
IsHouseCompleted
bool IsHouseCompleted(Tile t)
Get the completion of this house.
Definition town_map.h:167
IsHouseProtected
bool IsHouseProtected(Tile t)
Check if the house is protected from removal by towns.
Definition town_map.h:82
GetHouseConstructionTick
uint8_t GetHouseConstructionTick(Tile t)
Gets the construction stage of a house.
Definition town_map.h:217
RATING_GROWTH_UP_STEP
static constexpr int RATING_GROWTH_UP_STEP
when a town grows, all companies have rating increased a bit ...
Definition town_type.h:53
RATING_INITIAL
static constexpr int RATING_INITIAL
initial rating
Definition town_type.h:45
RATING_ROAD_NEEDED_HOSTILE
static constexpr int RATING_ROAD_NEEDED_HOSTILE
"Hostile"
Definition town_type.h:71
TCGM_BITCOUNT
@ TCGM_BITCOUNT
Bit-counted algorithm (normal distribution from individual house population)
Definition town_type.h:115
TCGM_ORIGINAL
@ TCGM_ORIGINAL
Original algorithm (quadratic cargo by population)
Definition town_type.h:114
RATING_ROAD_NEEDED_NEUTRAL
static constexpr int RATING_ROAD_NEEDED_NEUTRAL
"Neutral"
Definition town_type.h:70
TownLayout
TownLayout
Town Layouts.
Definition town_type.h:81
TL_3X3_GRID
@ TL_3X3_GRID
Geometric 3x3 grid algorithm.
Definition town_type.h:86
TL_ORIGINAL
@ TL_ORIGINAL
Original algorithm (min. 1 distance between roads)
Definition town_type.h:83
TL_2X2_GRID
@ TL_2X2_GRID
Geometric 2x2 grid algorithm.
Definition town_type.h:85
TL_RANDOM
@ TL_RANDOM
Random town layout.
Definition town_type.h:88
TL_BETTER_ROADS
@ TL_BETTER_ROADS
Extended original algorithm (min. 2 distance between roads)
Definition town_type.h:84
NUM_TLS
@ NUM_TLS
Number of town layouts.
Definition town_type.h:90
RATING_TUNNEL_BRIDGE_NEEDED_LENIENT
static constexpr int RATING_TUNNEL_BRIDGE_NEEDED_LENIENT
rating needed, "Lenient" difficulty settings
Definition town_type.h:61
TF_CUSTOM_LAYOUT
@ TF_CUSTOM_LAYOUT
Allowed, with custom town layout.
Definition town_type.h:107
TF_FORBIDDEN
@ TF_FORBIDDEN
Forbidden.
Definition town_type.h:105
RATING_TUNNEL_BRIDGE_NEEDED_HOSTILE
static constexpr int RATING_TUNNEL_BRIDGE_NEEDED_HOSTILE
"Hostile"
Definition town_type.h:63
RATING_TUNNEL_BRIDGE_NEEDED_PERMISSIVE
static constexpr int RATING_TUNNEL_BRIDGE_NEEDED_PERMISSIVE
"Permissive" (local authority disabled)
Definition town_type.h:64
RATING_TUNNEL_BRIDGE_NEEDED_NEUTRAL
static constexpr int RATING_TUNNEL_BRIDGE_NEEDED_NEUTRAL
"Neutral"
Definition town_type.h:62
RATING_ROAD_NEEDED_LENIENT
static constexpr int RATING_ROAD_NEEDED_LENIENT
rating needed, "Lenient" difficulty settings
Definition town_type.h:69
TownSize
TownSize
Supported initial town sizes.
Definition town_type.h:21
TSZ_RANDOM
@ TSZ_RANDOM
Random size, bigger than small, smaller than large.
Definition town_type.h:25
TSZ_END
@ TSZ_END
Number of available town sizes.
Definition town_type.h:27
TSZ_LARGE
@ TSZ_LARGE
Large town.
Definition town_type.h:24
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.
RATING_ROAD_NEEDED_PERMISSIVE
static constexpr int RATING_ROAD_NEEDED_PERMISSIVE
"Permissive" (local authority disabled)
Definition town_type.h:72
RATING_GROWTH_MAXIMUM
static constexpr int RATING_GROWTH_MAXIMUM
... up to RATING_MEDIOCRE
Definition town_type.h:54
VerifyTownName
bool VerifyTownName(uint32_t r, const TownNameParams *par, TownNames *town_names)
Verifies the town name is valid and unique.
Definition townname.cpp:103
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.
IsTransparencySet
bool IsTransparencySet(TransparencyOption to)
Check if the transparency option bit is set and if we aren't in the game menu (there's never transpar...
Definition transparency.h:50
IsInvisibilitySet
bool IsInvisibilitySet(TransparencyOption to)
Check if the invisibility option bit is set and if we aren't in the game menu (there's never transpar...
Definition transparency.h:61
TO_HOUSES
@ TO_HOUSES
town buildings
Definition transparency.h:26
TransportType
TransportType
Available types of transport.
Definition transport_type.h:17
TRANSPORT_ROAD
@ TRANSPORT_ROAD
Transport by road vehicle.
Definition transport_type.h:26
tree_map.h
Map accessors for tree tiles.
GetTreeGround
TreeGround GetTreeGround(Tile t)
Returns the groundtype for tree tiles.
Definition tree_map.h:102
TREE_GROUND_ROUGH
@ TREE_GROUND_ROUGH
some rough tile
Definition tree_map.h:54
tunnelbridge_cmd.h
Command definitions related to tunnels and bridges.
tunnelbridge_map.h
Functions that have tunnels and bridges in common.
GetTunnelBridgeDirection
DiagDirection GetTunnelBridgeDirection(Tile t)
Get the direction pointing to the other end.
Definition tunnelbridge_map.h:26
GetTunnelBridgeTransportType
TransportType GetTunnelBridgeTransportType(Tile t)
Tunnel: Get the transport type of the tunnel (road or rail) Bridge: Get the transport type of the bri...
Definition tunnelbridge_map.h:39
GetOtherTunnelBridgeEnd
TileIndex GetOtherTunnelBridgeEnd(Tile t)
Determines type of the wormhole and returns its other end.
Definition tunnelbridge_map.h:78
AddSortableSpriteToDraw
void AddSortableSpriteToDraw(SpriteID image, PaletteID pal, int x, int y, int z, const SpriteBounds &bounds, bool transparent, const SubSprite *sub)
Draw a (transparent) sprite at given coordinates with a given bounding box.
Definition viewport.cpp:663
AddChildSpriteScreen
void AddChildSpriteScreen(SpriteID image, PaletteID pal, int x, int y, bool transparent, const SubSprite *sub, bool scale, bool relative)
Add a child sprite to a parent sprite.
Definition viewport.cpp:824
DrawGroundSprite
void DrawGroundSprite(SpriteID image, PaletteID pal, const SubSprite *sub, int extra_offs_x, int extra_offs_y)
Draws a ground sprite for the current tile.
Definition viewport.cpp:579
viewport_func.h
Functions related to (drawing on) viewports.
HasTileWaterGround
bool HasTileWaterGround(Tile t)
Checks whether the tile has water at the ground.
Definition water_map.h:352
IsWaterTile
bool IsWaterTile(Tile t)
Is it a water tile with plain water?
Definition water_map.h:192
IsSea
bool IsSea(Tile t)
Is it a sea water tile?
Definition water_map.h:160
waypoint_base.h
Base of waypoints.
CloseWindowById
void CloseWindowById(WindowClass cls, WindowNumber number, bool force, int data)
Close a window by its class and window number (if it is open).
Definition window.cpp:1195
SetWindowClassesDirty
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition window.cpp:3205
InvalidateWindowData
void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool gui_scope)
Mark window data of the window of a given class and specific window number as invalid (in need of re-...
Definition window.cpp:3297
SetWindowDirty
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition window.cpp:3179
window_func.h
Window functions not directly related to making/drawing windows.
WC_TOWN_AUTHORITY
@ WC_TOWN_AUTHORITY
Town authority; Window numbers:
Definition window_type.h:199
WC_STATION_VIEW
@ WC_STATION_VIEW
Station view; Window numbers:
Definition window_type.h:350
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
WC_TOWN_CARGO_GRAPH
@ WC_TOWN_CARGO_GRAPH
Town cargo history graph; Window numbers:
Definition window_type.h:592