OpenTTD Source 20260731-master-g77ba2b244a
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
9
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 "script/api/script_event_types.hpp"
62#include "timer/timer.h"
66
67#include "table/strings.h"
68#include "table/town_land.h"
69
70#include "safeguards.h"
71
72/* Initialize the town-pool */
73TownPool _town_pool("Town");
75
76
77TownKdtree _town_kdtree{};
78
79void RebuildTownKdtree()
80{
81 std::vector<TownID> townids;
82 for (const Town *town : Town::Iterate()) {
83 townids.push_back(town->index);
84 }
85 _town_kdtree.Build(townids.begin(), townids.end());
86}
87
89static bool _generating_town = false;
90
100static bool TestTownOwnsBridge(TileIndex tile, const Town *t)
101{
102 if (!IsTileOwner(tile, OWNER_TOWN)) return false;
103
105 bool town_owned = IsTileType(adjacent, TileType::Road) && IsTileOwner(adjacent, OWNER_TOWN) && GetTownIndex(adjacent) == t->index;
106
107 if (!town_owned) {
108 /* Or other adjacent road */
110 town_owned = IsTileType(adjacent, TileType::Road) && IsTileOwner(adjacent, OWNER_TOWN) && GetTownIndex(adjacent) == t->index;
111 }
112
113 return town_owned;
114}
115
117{
118 if (CleaningPool()) return;
119
120 /* Delete town authority window
121 * and remove from list of sorted towns */
122 CloseWindowById(WindowClass::TownView, this->index);
123 CloseWindowById(WindowClass::TownCargoGraph, this->index);
124
125#ifdef WITH_ASSERT
126 /* Check no industry is related to us. */
127 for (const Industry *i : Industry::Iterate()) {
128 assert(i->town != this);
129 }
130
131 /* ... and no object is related to us. */
132 for (const Object *o : Object::Iterate()) {
133 assert(o->town != this);
134 }
135
136 /* Check no tile is related to us. */
137 for (const auto tile : Map::Iterate()) {
138 switch (GetTileType(tile)) {
139 case TileType::House:
140 assert(GetTownIndex(tile) != this->index);
141 break;
142
143 case TileType::Road:
144 assert(!HasTownOwnedRoad(tile) || GetTownIndex(tile) != this->index);
145 break;
146
148 assert(!TestTownOwnsBridge(tile, this));
149 break;
150
151 default:
152 break;
153 }
154 }
155#endif /* WITH_ASSERT */
156
157 /* Clear the persistent storage list. */
158 for (auto &psa : this->psa_list) {
159 delete psa;
160 }
161 this->psa_list.clear();
162
163 Source src{this->index, SourceType::Town};
168}
169
170
176void Town::PostDestructor([[maybe_unused]] size_t index)
177{
178 InvalidateWindowData(WindowClass::TownDirectory, 0, TDIWD_FORCE_REBUILD);
180
181 /* Give objects a new home! */
182 for (Object *o : Object::Iterate()) {
183 if (o->town == nullptr) o->town = CalcClosestTownFromTile(o->location.tile, UINT_MAX);
184 }
185}
186
192{
193 if (layout != TownLayout::Random) {
194 this->layout = layout;
195 return;
196 }
197
198 this->layout = static_cast<TownLayout>(TileHash(TileX(this->xy), TileY(this->xy)) % (to_underlying(TownLayout::End) - 1));
199}
200
205/* static */ Town *Town::GetRandom()
206{
207 if (Town::GetNumItems() == 0) return nullptr;
208 int num = RandomRange((uint16_t)Town::GetNumItems());
209 size_t index = std::numeric_limits<size_t>::max();
210
211 while (num >= 0) {
212 num--;
213 index++;
214
215 /* Make sure we have a valid town */
216 while (!Town::IsValidID(index)) {
217 index++;
218 assert(index < Town::GetPoolSize());
219 }
220 }
221
222 return Town::Get(index);
223}
224
225void Town::FillCachedName() const
226{
227 this->cached_name = GetTownName(this);
228}
229
235{
236 return (_price[Price::ClearHouse] * this->removal_cost) >> 8;
237}
238
239static bool TryBuildTownHouse(Town *t, TileIndex tile, TownExpandModes modes);
240static Town *CreateRandomTown(uint attempts, uint32_t townnameparts, TownSize size, bool city, TownLayout layout);
241
242static void TownDrawHouseLift(const TileInfo *ti)
243{
244 AddChildSpriteScreen(SPR_LIFT, PAL_NONE, 14, 60 - GetLiftPosition(ti->tile));
245}
246
247typedef void TownDrawTileProc(const TileInfo *ti);
248static TownDrawTileProc * const _town_draw_tile_procs[1] = {
249 TownDrawHouseLift
250};
251
258{
260}
261
263static void DrawTile_Town(TileInfo *ti)
264{
265 HouseID house_id = GetHouseType(ti->tile);
266
267 if (house_id >= NEW_HOUSE_OFFSET) {
268 /* Houses don't necessarily need new graphics. If they don't have a
269 * spritegroup associated with them, then the sprite for the substitute
270 * house id is drawn instead. */
271 if (HouseSpec::Get(house_id)->grf_prop.HasSpriteGroups()) {
272 DrawNewHouseTile(ti, house_id);
273 return;
274 } else {
275 house_id = HouseSpec::Get(house_id)->grf_prop.subst_id;
276 }
277 }
278
279 /* Retrieve pointer to the draw town tile struct */
280 const DrawBuildingsTileStruct *dcts = &_town_draw_tile_data[house_id << 4 | TileHash2Bit(ti->x, ti->y) << 2 | GetHouseBuildingStage(ti->tile)];
281
283
284 DrawGroundSprite(dcts->ground.sprite, dcts->ground.pal);
285
286 /* If houses are invisible, do not draw the upper part */
288
289 /* Add a house on top of the ground? */
290 SpriteID image = dcts->building.sprite;
291 if (image != 0) {
292 AddSortableSpriteToDraw(image, dcts->building.pal, *ti, *dcts, IsTransparencySet(TransparencyOption::Houses));
293
295 }
296
297 {
298 int proc = dcts->draw_proc - 1;
299
300 if (proc >= 0) _town_draw_tile_procs[proc](ti);
301 }
302}
303
306{
307 HouseID hid = GetHouseType(tile);
308
309 /* For NewGRF house tiles we might not be drawing a foundation. We need to
310 * account for this, as other structures should
311 * draw the wall of the foundation in this case.
312 */
313 if (hid >= NEW_HOUSE_OFFSET) {
314 const HouseSpec *hs = HouseSpec::Get(hid);
316 uint32_t callback_res = GetHouseCallback(CBID_HOUSE_DRAW_FOUNDATIONS, 0, 0, hid, Town::GetByTile(tile), tile);
318 }
319 }
320 return FlatteningFoundation(tileh);
321}
322
330{
331 if (GetHouseType(tile) >= NEW_HOUSE_OFFSET) {
332 AnimateNewHouseTile(tile);
333 return;
334 }
335
336 if (TimerGameTick::counter & 3) return;
337
338 /* If the house is not one with a lift anymore, then stop this animating.
339 * Not exactly sure when this happens, but probably when a house changes.
340 * Before this was just a return...so it'd leak animated tiles..
341 * That bug seems to have been here since day 1?? */
342 if (!HouseSpec::Get(GetHouseType(tile))->building_flags.Test(BuildingFlag::IsAnimated)) {
343 DeleteAnimatedTile(tile);
344 return;
345 }
346
347 if (!LiftHasDestination(tile)) {
348 uint i;
349
350 /* Building has 6 floors, number 0 .. 6, where 1 is illegal.
351 * This is due to the fact that the first floor is, in the graphics,
352 * the height of 2 'normal' floors.
353 * Furthermore, there are 6 lift positions from floor N (incl) to floor N + 1 (excl) */
354 do {
355 i = RandomRange(7);
356 } while (i == 1 || i * 6 == GetLiftPosition(tile));
357
358 SetLiftDestination(tile, i);
359 }
360
361 int pos = GetLiftPosition(tile);
362 int dest = GetLiftDestination(tile) * 6;
363 pos += (pos < dest) ? 1 : -1;
364 SetLiftPosition(tile, pos);
365
366 if (pos == dest) {
367 HaltLift(tile);
368 DeleteAnimatedTile(tile);
369 }
370
372}
373
380static bool IsCloseToTown(TileIndex tile, uint dist)
381{
382 if (_town_kdtree.Count() == 0) return false;
383 Town *t = Town::Get(_town_kdtree.FindNearest(TileX(tile), TileY(tile)));
384 return DistanceManhattan(tile, t->xy) < dist;
385}
386
389{
390 Point pt = RemapCoords2(TileX(this->xy) * TILE_SIZE, TileY(this->xy) * TILE_SIZE);
391
392 if (this->cache.sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeTown(this->index));
393
394 std::string town_string;
395 if (this->larger_town) {
396 town_string = GetString(_settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_CITY_POP : STR_VIEWPORT_TOWN_CITY, this->index, this->cache.population);
397 } else {
398 town_string = GetString(_settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_POP : STR_TOWN_NAME, this->index, this->cache.population);
399 }
400
401 this->cache.sign.UpdatePosition(pt.x, pt.y - 24 * ZOOM_BASE,
402 town_string,
403 GetString(STR_TOWN_NAME, this->index, this->cache.population)
404);
405
406 _viewport_sign_kdtree.Insert(ViewportSignKdtreeItem::MakeTown(this->index));
407
408 SetWindowDirty(WindowClass::TownView, this->index);
409}
410
413{
414 for (Town *t : Town::Iterate()) {
415 t->UpdateVirtCoord();
416 }
417}
418
421{
422 for (Town *t : Town::Iterate()) {
423 t->cached_name.clear();
424 }
425}
426
432static void ChangePopulation(Town *t, int mod)
433{
434 t->cache.population += mod;
435 if (_generating_town) [[unlikely]] return;
436
437 InvalidateWindowData(WindowClass::TownView, t->index); // Cargo requirements may appear/vanish for small populations
438 if (_settings_client.gui.population_in_label) t->UpdateVirtCoord();
439
440 InvalidateWindowData(WindowClass::TownDirectory, 0, TDIWD_POPULATION_CHANGE);
441}
442
448{
449 uint32_t pop = 0;
450 for (const Town *t : Town::Iterate()) pop += t->cache.population;
451 return pop;
452}
453
462{
463 for (StationList::iterator it = t->stations_near.begin(); it != t->stations_near.end(); /* incremented inside loop */) {
464 const Station *st = *it;
465
466 bool covers_area = st->TileIsInCatchment(tile);
467 if (flags.Any(BUILDING_2_TILES_Y)) covers_area |= st->TileIsInCatchment(tile + TileDiffXY(0, 1));
468 if (flags.Any(BUILDING_2_TILES_X)) covers_area |= st->TileIsInCatchment(tile + TileDiffXY(1, 0));
469 if (flags.Any(BUILDING_HAS_4_TILES)) covers_area |= st->TileIsInCatchment(tile + TileDiffXY(1, 1));
470
471 if (covers_area && !st->CatchmentCoversTown(t->index)) {
472 it = t->stations_near.erase(it);
473 } else {
474 ++it;
475 }
476 }
477}
478
484{
485 assert(IsTileType(tile, TileType::House));
486
487 /* Progress in construction stages */
489 if (GetHouseConstructionTick(tile) != 0) return;
490
491 TriggerHouseAnimation_ConstructionStageChanged(tile, false);
492
493 if (IsHouseCompleted(tile)) {
494 /* Now that construction is complete, we can add the population of the
495 * building to the town. */
496 ChangePopulation(Town::GetByTile(tile), HouseSpec::Get(GetHouseType(tile))->population);
497 ResetHouseAge(tile);
498 }
500}
501
507{
509 if (flags.Any(BUILDING_HAS_1_TILE)) AdvanceSingleHouseConstruction(TileAddXY(tile, 0, 0));
510 if (flags.Any(BUILDING_2_TILES_Y)) AdvanceSingleHouseConstruction(TileAddXY(tile, 0, 1));
511 if (flags.Any(BUILDING_2_TILES_X)) AdvanceSingleHouseConstruction(TileAddXY(tile, 1, 0));
512 if (flags.Any(BUILDING_HAS_4_TILES)) AdvanceSingleHouseConstruction(TileAddXY(tile, 1, 1));
513}
514
523static void TownGenerateCargo(Town *t, CargoType cargo, uint amount, StationFinder &stations, bool affected_by_recession)
524{
525 if (amount == 0) return;
526
527 /* All production is halved during a recession (except for NewGRF-supplied town cargo). */
528 if (affected_by_recession && EconomyIsInRecession()) {
529 amount = (amount + 1) >> 1;
530 }
531
532 /* Scale by cargo scale setting. */
533 amount = ScaleByCargoScale(amount, true);
534 if (amount == 0) return;
535
536 /* Actually generate cargo and update town statistics. */
537 auto &supplied = t->GetOrCreateCargoSupplied(cargo);
538 supplied.history[THIS_MONTH].production += amount;
539 supplied.history[THIS_MONTH].transported += MoveGoodsToStation(cargo, amount, {t->index, SourceType::Town}, stations.GetStations());;
540}
541
549static void TownGenerateCargoOriginal(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
550{
551 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[tpe]) {
552 uint32_t r = Random();
553 if (GB(r, 0, 8) < rate) {
554 CargoType cargo_type = cs->Index();
555 uint amt = (GB(r, 0, 8) * cs->town_production_multiplier / TOWN_PRODUCTION_DIVISOR) / 8 + 1;
556
557 TownGenerateCargo(t, cargo_type, amt, stations, true);
558 }
559 }
560}
561
569static void TownGenerateCargoBinomial(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
570{
571 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[tpe]) {
572 CargoType cargo_type = cs->Index();
573 uint32_t r = Random();
574
575 /* Make a bitmask with up to 32 bits set, one for each potential pax. */
576 int genmax = (rate + 7) / 8;
577 uint32_t genmask = (genmax >= 32) ? 0xFFFFFFFF : ((1 << genmax) - 1);
578
579 /* Mask random value by potential pax and count number of actual pax. */
580 uint amt = CountBits(r & genmask) * cs->town_production_multiplier / TOWN_PRODUCTION_DIVISOR;
581
582 TownGenerateCargo(t, cargo_type, amt, stations, true);
583 }
584}
585
587static void TileLoop_Town(TileIndex tile)
588{
589 HouseID house_id = GetHouseType(tile);
590
591 /* NewHouseTileLoop returns false if Callback 21 succeeded, i.e. the house
592 * doesn't exist any more, so don't continue here. */
593 if (house_id >= NEW_HOUSE_OFFSET && !NewHouseTileLoop(tile)) return;
594
595 if (!IsHouseCompleted(tile)) {
596 /* Construction is not completed, so we advance a construction stage. */
598 return;
599 }
600
601 const HouseSpec *hs = HouseSpec::Get(house_id);
602
603 /* If the lift has a destination, it is already an animated tile. */
605 house_id < NEW_HOUSE_OFFSET &&
606 !LiftHasDestination(tile) &&
607 Chance16(1, 2)) {
608 AddAnimatedTile(tile);
609 }
610
611 Town *t = Town::GetByTile(tile);
612 uint32_t r = Random();
613
614 StationFinder stations(TileArea(tile, 1, 1));
615
617 for (uint i = 0; i < 256; i++) {
618 uint16_t callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, r, house_id, t, tile);
619
620 if (callback == CALLBACK_FAILED || callback == CALLBACK_HOUSEPRODCARGO_END) break;
621
622 CargoType cargo = GetCargoTranslation(GB(callback, 8, 7), hs->grf_prop.grffile);
623 if (!IsValidCargoType(cargo)) continue;
624
625 uint amt = GB(callback, 0, 8);
626 if (amt == 0) continue;
627
628 /* NewGRF-supplied town cargos are not affected by recessions. */
629 TownGenerateCargo(t, cargo, amt, stations, false);
630 }
631 } else {
632 switch (_settings_game.economy.town_cargogen_mode) {
634 /* Original (quadratic) cargo generation algorithm */
637 break;
638
640 /* Binomial distribution per tick, by a series of coin flips */
641 /* Reduce generation rate to a 1/4, using tile bits to spread out distribution.
642 * As tick counter is incremented by 256 between each call, we ignore the lower 8 bits. */
643 if (GB(TimerGameTick::counter, 8, 2) == GB(tile.base(), 0, 2)) {
646 }
647 break;
648
649 default:
650 NOT_REACHED();
651 }
652 }
653
655
656 if (hs->building_flags.Any(BUILDING_HAS_1_TILE) &&
658 CanDeleteHouse(tile) &&
659 GetHouseAge(tile) >= hs->minimum_life &&
660 --t->time_until_rebuild == 0) {
661 t->time_until_rebuild = GB(r, 16, 8) + 192;
662
663 ClearTownHouse(t, tile);
664
665 /* Rebuild with another house? */
666 if (GB(r, 24, 8) >= 12) {
667 /* If we are multi-tile houses, make sure to replace the house
668 * closest to city center. If we do not do this, houses tend to
669 * wander away from roads and other houses. */
670 if (hs->building_flags.Any(BUILDING_HAS_2_TILES)) {
671 /* House tiles are always the most north tile. Move the new
672 * house to the south if we are north of the city center. */
673 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
674 int x = Clamp(grid_pos.x, 0, 1);
675 int y = Clamp(grid_pos.y, 0, 1);
676
678 tile = TileAddXY(tile, x, y);
679 } else if (hs->building_flags.Test(BuildingFlag::Size1x2)) {
680 tile = TileAddXY(tile, 0, y);
681 } else if (hs->building_flags.Test(BuildingFlag::Size2x1)) {
682 tile = TileAddXY(tile, x, 0);
683 }
684 }
685
687 if (_settings_game.economy.allow_town_roads) modes.Set(TownExpandMode::Roads);
688
689 TryBuildTownHouse(t, tile, modes);
690 }
691 }
692}
693
696{
697 if (flags.Test(DoCommandFlag::Auto)) return CommandCost(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
698 if (!CanDeleteHouse(tile)) return CommandCost(STR_ERROR_BUILDING_IS_PROTECTED);
699
700 const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
701
703 cost.AddCost(hs->GetRemovalCost());
704
705 int rating = hs->remove_rating_decrease;
706 Town *t = Town::GetByTile(tile);
707
709 if (!_cheats.magic_bulldozer.value && !flags.Test(DoCommandFlag::NoTestTownRating)) {
710 /* NewGRFs can add indestructible houses. */
711 if (rating > RATING_MAXIMUM) {
712 return CommandCost(STR_ERROR_BUILDING_IS_PROTECTED);
713 }
714 /* If town authority controls removal, check the company's rating. */
715 if (rating > t->ratings[_current_company] && _settings_game.difficulty.town_council_tolerance != TOWN_COUNCIL_PERMISSIVE) {
716 return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index);
717 }
718 }
719 }
720
721 ChangeTownRating(t, -rating, RATING_HOUSE_MINIMUM, flags);
722 if (flags.Test(DoCommandFlag::Execute)) {
723 ClearTownHouse(t, tile);
724 }
725
726 return cost;
727}
728
730static void AddProducedCargo_Town(TileIndex tile, CargoArray &produced)
731{
732 HouseID house_id = GetHouseType(tile);
733 const HouseSpec *hs = HouseSpec::Get(house_id);
734 Town *t = Town::GetByTile(tile);
735
737 for (uint i = 0; i < 256; i++) {
738 uint16_t callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, 0, house_id, t, tile);
739
740 if (callback == CALLBACK_FAILED || callback == CALLBACK_HOUSEPRODCARGO_END) break;
741
742 CargoType cargo = GetCargoTranslation(GB(callback, 8, 7), hs->grf_prop.grffile);
743
744 if (!IsValidCargoType(cargo)) continue;
745 produced[cargo]++;
746 }
747 } else {
748 if (hs->population > 0) {
750 produced[cs->Index()]++;
751 }
752 }
753 if (hs->mail_generation > 0) {
755 produced[cs->Index()]++;
756 }
757 }
758 }
759}
760
768static void AddAcceptedCargoSetMask(CargoType cargo, uint amount, CargoArray &acceptance, CargoTypes &always_accepted)
769{
770 if (!IsValidCargoType(cargo) || amount == 0) return;
771 acceptance[cargo] += amount;
772 always_accepted.Set(cargo);
773}
774
784void AddAcceptedCargoOfHouse(TileIndex tile, HouseID house, const HouseSpec *hs, Town *t, CargoArray &acceptance, CargoTypes &always_accepted)
785{
786 CargoType accepts[lengthof(hs->accepts_cargo)];
787
788 /* Set the initial accepted cargo types */
789 for (uint8_t i = 0; i < lengthof(accepts); i++) {
790 accepts[i] = hs->accepts_cargo[i];
791 }
792
793 /* Check for custom accepted cargo types */
795 uint16_t callback = GetHouseCallback(CBID_HOUSE_ACCEPT_CARGO, 0, 0, house, t, tile, {}, tile == INVALID_TILE);
796 if (callback != CALLBACK_FAILED) {
797 /* Replace accepted cargo types with translated values from callback */
798 accepts[0] = GetCargoTranslation(GB(callback, 0, 5), hs->grf_prop.grffile);
799 accepts[1] = GetCargoTranslation(GB(callback, 5, 5), hs->grf_prop.grffile);
800 accepts[2] = GetCargoTranslation(GB(callback, 10, 5), hs->grf_prop.grffile);
801 }
802 }
803
804 /* Check for custom cargo acceptance */
806 uint16_t callback = GetHouseCallback(CBID_HOUSE_CARGO_ACCEPTANCE, 0, 0, house, t, tile, {}, tile == INVALID_TILE);
807 if (callback != CALLBACK_FAILED) {
808 AddAcceptedCargoSetMask(accepts[0], GB(callback, 0, 4), acceptance, always_accepted);
809 AddAcceptedCargoSetMask(accepts[1], GB(callback, 4, 4), acceptance, always_accepted);
810 if (_settings_game.game_creation.landscape != LandscapeType::Temperate && HasBit(callback, 12)) {
811 /* The 'S' bit indicates food instead of goods */
812 AddAcceptedCargoSetMask(GetCargoTypeByLabel(CT_FOOD), GB(callback, 8, 4), acceptance, always_accepted);
813 } else {
814 AddAcceptedCargoSetMask(accepts[2], GB(callback, 8, 4), acceptance, always_accepted);
815 }
816 return;
817 }
818 }
819
820 /* No custom acceptance, so fill in with the default values */
821 for (uint8_t i = 0; i < lengthof(accepts); i++) {
822 AddAcceptedCargoSetMask(accepts[i], hs->cargo_acceptance[i], acceptance, always_accepted);
823 }
824}
825
827static void AddAcceptedCargo_Town(TileIndex tile, CargoArray &acceptance, CargoTypes &always_accepted)
828{
829 HouseID house = GetHouseType(tile);
830 AddAcceptedCargoOfHouse(tile, house, HouseSpec::Get(house), Town::GetByTile(tile), acceptance, always_accepted);
831}
832
839{
840 CargoTypes always_accepted{};
841 CargoArray acceptance{};
842 AddAcceptedCargoOfHouse(INVALID_TILE, hs->Index(), hs, nullptr, acceptance, always_accepted);
843 return acceptance;
844}
845
847static void GetTileDesc_Town(TileIndex tile, TileDesc &td)
848{
849 const HouseID house = GetHouseType(tile);
850 const HouseSpec *hs = HouseSpec::Get(house);
851 bool house_completed = IsHouseCompleted(tile);
852
853 td.str = hs->building_name;
854
855 /* Show if a player has protected the house, or if the house property is set for protection.
856 * Note that houses also have a callback which overrides their property (player choice is always respected),
857 * but it's impossible to know the possible results of the callback in runtime so it's not evaluated here. */
859
860 std::array<int32_t, 1> regs100;
861 uint16_t callback_res = GetHouseCallback(CBID_HOUSE_CUSTOM_NAME, house_completed ? 1 : 0, 0, house, Town::GetByTile(tile), tile, regs100);
862 if (callback_res != CALLBACK_FAILED && callback_res != 0x400) {
863 StringID new_name = STR_NULL;
864 if (callback_res == 0x40F) {
865 new_name = GetGRFStringID(hs->grf_prop.grfid, static_cast<GRFStringID>(regs100[0]));
866 } else if (callback_res > 0x400) {
868 } else {
869 new_name = GetGRFStringID(hs->grf_prop.grfid, GRFSTR_MISC_GRF_TEXT + callback_res);
870 }
871 if (new_name != STR_NULL && new_name != STR_UNDEFINED) {
872 td.str = new_name;
873 }
874 }
875
876 if (!house_completed) {
877 td.dparam = td.str.base();
878 td.str = STR_LAI_TOWN_INDUSTRY_DESCRIPTION_UNDER_CONSTRUCTION;
879 }
880
881 if (hs->grf_prop.HasGrfFile()) {
882 const GRFConfig *gc = GetGRFConfig(hs->grf_prop.grfid);
883 td.grf = gc->GetName();
884 }
885
886 td.owner[0] = OWNER_TOWN;
887}
888
889static bool GrowTown(Town *t, TownExpandModes modes);
890
895static void TownTickHandler(Town *t)
896{
899 if (_settings_game.economy.allow_town_roads) modes.Set(TownExpandMode::Roads);
900 int i = (int)t->grow_counter - 1;
901 if (i < 0) {
902 if (GrowTown(t, modes)) {
903 i = t->growth_rate;
904 } else {
905 /* If growth failed wait a bit before retrying */
906 i = std::min<uint16_t>(t->growth_rate, Ticks::TOWN_GROWTH_TICKS - 1);
907 }
908 }
909 t->grow_counter = i;
910 }
911}
912
915{
916 if (_game_mode == GameMode::Editor) return;
917
918 for (Town *t : Town::Iterate()) {
920 }
921}
922
929{
930 if (IsRoadDepotTile(tile) || IsBayRoadStopTile(tile)) return {};
931
932 return GetAnyRoadBits(tile, RoadTramType::Road, true);
933}
934
941{
942 RoadType best_rt = ROADTYPE_ROAD;
943 const RoadTypeInfo *best = nullptr;
944 const uint16_t assume_max_speed = 50;
945
947 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
948
949 /* Can town build this road. */
950 if (!rti->flags.Test(RoadTypeFlag::TownBuild)) continue;
951
952 /* Not yet introduced at this date. */
954
955 if (best != nullptr) {
956 if ((rti->max_speed == 0 ? assume_max_speed : rti->max_speed) < (best->max_speed == 0 ? assume_max_speed : best->max_speed)) continue;
957 }
958
959 best_rt = rt;
960 best = rti;
961 }
962
963 return best_rt;
964}
965
971{
972 const RoadTypeInfo *best = nullptr;
974 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
975
976 if (!rti->flags.Test(RoadTypeFlag::TownBuild)) continue; // Town can't build this road type.
977
978 if (best != nullptr && rti->introduction_date >= best->introduction_date) continue;
979 best = rti;
980 }
981
982 if (best == nullptr) return TimerGameCalendar::Date(INT32_MAX);
983 return best->introduction_date;
984}
985
991{
992 auto min_date = GetTownRoadTypeFirstIntroductionDate();
993 if (min_date <= TimerGameCalendar::date) return true;
994
995 if (min_date < INT32_MAX) {
997 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_YET),
998 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_YET_EXPLANATION, min_date),
1000 } else {
1002 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_AT_ALL),
1003 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_AT_ALL_EXPLANATION), WarningLevel::Critical);
1004 }
1005 return false;
1006}
1007
1018static bool IsNeighbourRoadTile(TileIndex tile, const DiagDirection dir, uint dist_multi)
1019{
1020 if (!IsValidTile(tile)) return false;
1021
1022 /* Lookup table for the used diff values */
1023 const TileIndexDiff tid_lt[3] = {
1027 };
1028
1029 dist_multi = (dist_multi + 1) * 4;
1030 for (uint pos = 4; pos < dist_multi; pos++) {
1031 /* Go (pos / 4) tiles to the left or the right */
1032 TileIndexDiff cur = tid_lt[(pos & 1) ? 0 : 1] * (pos / 4);
1033
1034 /* Use the current tile as origin, or go one tile backwards */
1035 if (pos & 2) cur += tid_lt[2];
1036
1037 /* Test for roadbit parallel to dir and facing towards the middle axis */
1038 if (IsValidTile(tile + cur) &&
1039 GetTownRoadBits(TileAdd(tile, cur)).Any(DiagDirToRoadBits((pos & 2) ? dir : ReverseDiagDir(dir)))) return true;
1040 }
1041 return false;
1042}
1043
1053{
1054 if (DistanceFromEdge(tile) == 0) return false;
1055
1056 /* Prevent towns from building roads under bridges along the bridge. Looks silly. */
1057 if (IsBridgeAbove(tile) && GetBridgeAxis(tile) == DiagDirToAxis(dir)) return false;
1058
1059 /* Check if there already is a road at this point? */
1060 if (GetTownRoadBits(tile).None()) {
1061 /* No, try if we are able to build a road piece there.
1062 * If that fails clear the land, and if that fails exit.
1063 * This is to make sure that we can build a road here later. */
1065 if (Command<Commands::BuildRoad>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile, (dir == DiagDirection::NW || dir == DiagDirection::SE) ? ROAD_Y : ROAD_X, rt, {}, t->index).Failed() &&
1066 Command<Commands::LandscapeClear>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile).Failed()) {
1067 return false;
1068 }
1069 }
1070
1071 Slope cur_slope = _settings_game.construction.build_on_slopes ? std::get<Slope>(GetFoundationSlope(tile)) : GetTileSlope(tile);
1072 bool ret = !IsNeighbourRoadTile(tile, dir, t->layout == TownLayout::Original ? 1 : 2);
1073 if (cur_slope == SLOPE_FLAT) return ret;
1074
1075 /* If the tile is not a slope in the right direction, then
1076 * maybe terraform some. */
1077 Slope desired_slope = (dir == DiagDirection::NW || dir == DiagDirection::SE) ? SLOPE_NW : SLOPE_NE;
1078 if (desired_slope != cur_slope && ComplementSlope(desired_slope) != cur_slope) {
1079 if (Chance16(1, 8)) {
1080 CommandCost res = CMD_ERROR;
1081 if (!_generating_world && Chance16(1, 10)) {
1082 res = ExtractCommandCost(Command<Commands::TerraformLand>::Do({DoCommandFlag::Execute, DoCommandFlag::Auto, DoCommandFlag::NoWater},
1083 tile, Chance16(1, 16) ? cur_slope : ComplementSlope(RemoveSteepSlope(RemoveHalftileSlope(cur_slope))), false));
1084 }
1085 if (res.Failed() && Chance16(1, 3)) {
1086 /* We can consider building on the slope, though. */
1087 return ret;
1088 }
1089 }
1090 return false;
1091 }
1092 return ret;
1093}
1094
1095static bool TerraformTownTile(TileIndex tile, Slope edges, bool dir)
1096{
1097 assert(tile < Map::Size());
1098
1099 CommandCost r = ExtractCommandCost(Command<Commands::TerraformLand>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile, edges, dir));
1100 if (r.Failed() || r.GetCost() >= (_price[Price::Terraform] + 2) * 8) return false;
1101 Command<Commands::TerraformLand>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater, DoCommandFlag::Execute}, tile, edges, dir);
1102 return true;
1103}
1104
1105static void LevelTownLand(TileIndex tile)
1106{
1107 assert(tile < Map::Size());
1108
1109 /* Don't terraform if land is plain or if there's a house there. */
1110 if (IsTileType(tile, TileType::House)) return;
1111 Slope tileh = GetTileSlope(tile);
1112 if (tileh == SLOPE_FLAT) return;
1113
1114 /* First try up, then down */
1115 if (!TerraformTownTile(tile, ~tileh & SLOPE_ELEVATED, true)) {
1116 TerraformTownTile(tile, tileh & SLOPE_ELEVATED, false);
1117 }
1118}
1119
1129{
1130 /* align the grid to the downtown */
1131 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile); // Vector from downtown to the tile
1132 RoadBits rcmd{};
1133
1134 switch (t->layout) {
1135 default: NOT_REACHED();
1136
1138 if ((grid_pos.x % 3) == 0) rcmd.Set(ROAD_Y);
1139 if ((grid_pos.y % 3) == 0) rcmd.Set(ROAD_X);
1140 break;
1141
1143 if ((grid_pos.x % 4) == 0) rcmd.Set(ROAD_Y);
1144 if ((grid_pos.y % 4) == 0) rcmd.Set(ROAD_X);
1145 break;
1146 }
1147
1148 /* Optimise only X-junctions */
1149 if (rcmd != ROAD_ALL) return rcmd;
1150
1151 RoadBits rb_template;
1152
1153 switch (GetTileSlope(tile)) {
1154 default: rb_template = ROAD_ALL; break;
1155 case SLOPE_W: rb_template = {RoadBit::NW, RoadBit::SW}; break;
1156 case SLOPE_SW: rb_template = ROAD_Y | RoadBit::SW; break;
1157 case SLOPE_S: rb_template = {RoadBit::SW, RoadBit::SE}; break;
1158 case SLOPE_SE: rb_template = ROAD_X | RoadBit::SE; break;
1159 case SLOPE_E: rb_template = {RoadBit::SE, RoadBit::NE}; break;
1160 case SLOPE_NE: rb_template = ROAD_Y | RoadBit::NE; break;
1161 case SLOPE_N: rb_template = {RoadBit::NE, RoadBit::NW}; break;
1162 case SLOPE_NW: rb_template = ROAD_X | RoadBit::NW; break;
1163 case SLOPE_STEEP_W:
1164 case SLOPE_STEEP_S:
1165 case SLOPE_STEEP_E:
1166 case SLOPE_STEEP_N:
1167 rb_template = {};
1168 break;
1169 }
1170
1171 /* Stop if the template is compatible to the growth dir */
1172 if (DiagDirToRoadBits(ReverseDiagDir(dir)).Any(rb_template)) return rb_template;
1173 /* If not generate a straight road in the direction of the growth */
1175}
1176
1189{
1190 /* We can't look further than that. */
1191 if (DistanceFromEdge(tile) == 0) return false;
1192
1193 uint counter = 0; // counts the house neighbour tiles
1194
1195 /* Check the tiles E,N,W and S of the current tile for houses */
1197 /* Count both void and house tiles for checking whether there
1198 * are enough houses in the area. This to make it likely that
1199 * houses get build up to the edge of the map. */
1200 switch (GetTileType(TileAddByDiagDir(tile, dir))) {
1201 case TileType::House:
1202 case TileType::Void:
1203 counter++;
1204 break;
1205
1206 default:
1207 break;
1208 }
1209
1210 /* If there are enough neighbours stop here */
1211 if (counter >= 3) {
1212 return TryBuildTownHouse(t, tile, modes);
1213 }
1214 }
1215 return false;
1216}
1217
1226static bool GrowTownWithRoad(const Town *t, TileIndex tile, RoadBits rcmd)
1227{
1229 return Command<Commands::BuildRoad>::Do({DoCommandFlag::Execute, DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile, rcmd, rt, {}, t->index).Succeeded();
1230}
1231
1241static bool CanRoadContinueIntoNextTile(const Town *t, const TileIndex tile, const DiagDirection road_dir)
1242{
1243 const TileIndexDiff delta = TileOffsByDiagDir(road_dir); // +1 tile in the direction of the road
1244 TileIndex next_tile = tile + delta; // The tile beyond which must be connectable to the target tile
1245 RoadBits rcmd = DiagDirToRoadBits(ReverseDiagDir(road_dir));
1247
1248 /* Before we try anything, make sure the tile is on the map and not the void. */
1249 if (!IsValidTile(next_tile)) return false;
1250
1251 /* If the next tile is a bridge or tunnel, allow if it's continuing in the same direction. */
1252 if (IsTileType(next_tile, TileType::TunnelBridge)) {
1253 return GetTunnelBridgeTransportType(next_tile) == TransportType::Road && GetTunnelBridgeDirection(next_tile) == road_dir;
1254 }
1255
1256 /* If the next tile is a station, allow if it's a road station facing the proper direction. Otherwise return false. */
1257 if (IsTileType(next_tile, TileType::Station)) {
1258 /* If the next tile is a road station, allow if it can be entered by the new tunnel/bridge, otherwise disallow. */
1259 if (IsDriveThroughStopTile(next_tile)) return GetDriveThroughStopAxis(next_tile) == DiagDirToAxis(road_dir);
1260 if (IsBayRoadStopTile(next_tile)) return GetBayRoadStopDir(next_tile) == ReverseDiagDir(road_dir);
1261 return false;
1262 }
1263
1264 /* If the next tile is a road depot, allow if it's facing the right way. */
1265 if (IsTileType(next_tile, TileType::Road)) {
1266 return IsRoadDepot(next_tile) && GetRoadDepotDirection(next_tile) == ReverseDiagDir(road_dir);
1267 }
1268
1269 /* If the next tile is a railroad track, check if towns are allowed to build level crossings.
1270 * If level crossing are not allowed, reject the construction. Else allow DoCommand to determine if the rail track is buildable. */
1271 if (IsTileType(next_tile, TileType::Railway) && !_settings_game.economy.allow_town_level_crossings) return false;
1272
1273 /* If a road tile can be built, the construction is allowed. */
1274 return Command<Commands::BuildRoad>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, next_tile, rcmd, rt, {}, t->index).Succeeded();
1275}
1276
1287static bool GrowTownWithBridge(const Town *t, const TileIndex tile, const DiagDirection bridge_dir)
1288{
1289 assert(bridge_dir < DiagDirection::End);
1290
1291 const Slope slope = GetTileSlope(tile);
1292
1293 /* Make sure the direction is compatible with the slope.
1294 * Well we check if the slope has an up bit set in the
1295 * reverse direction. */
1296 if (slope != SLOPE_FLAT && slope & InclinedSlope(bridge_dir)) return false;
1297
1298 /* Assure that the bridge is connectable to the start side */
1299 if (!GetTownRoadBits(TileAddByDiagDir(tile, ReverseDiagDir(bridge_dir))).Any(DiagDirToRoadBits(bridge_dir))) return false;
1300
1301 /* We are in the right direction */
1302 uint bridge_length = 0; // This value stores the length of the possible bridge
1303 TileIndex bridge_tile = tile; // Used to store the other waterside
1304
1305 const TileIndexDiff delta = TileOffsByDiagDir(bridge_dir);
1306
1307 /* To prevent really small towns from building disproportionately
1308 * long bridges, make the max a function of its population. */
1309 const uint TOWN_BRIDGE_LENGTH_CAP = 11;
1310 uint base_bridge_length = 5;
1311 uint max_bridge_length = std::min(t->cache.population / 1000 + base_bridge_length, TOWN_BRIDGE_LENGTH_CAP);
1312
1313 if (slope == SLOPE_FLAT) {
1314 /* Bridges starting on flat tiles are only allowed when crossing rivers, rails or one-way roads. */
1315 do {
1316 if (bridge_length++ >= base_bridge_length) {
1317 /* Allow to cross rivers, not big lakes, nor large amounts of rails or one-way roads. */
1318 return false;
1319 }
1320 bridge_tile += delta;
1321 } while (IsValidTile(bridge_tile) && ((IsWaterTile(bridge_tile) && !IsSea(bridge_tile)) || IsPlainRailTile(bridge_tile) || (IsNormalRoadTile(bridge_tile) && GetDisallowedRoadDirections(bridge_tile).Any())));
1322 } else {
1323 do {
1324 if (bridge_length++ >= max_bridge_length) {
1325 /* Ensure the bridge is not longer than the max allowed length. */
1326 return false;
1327 }
1328 bridge_tile += delta;
1329 } while (IsValidTile(bridge_tile) && (IsWaterTile(bridge_tile) || IsPlainRailTile(bridge_tile) || (IsNormalRoadTile(bridge_tile) && GetDisallowedRoadDirections(bridge_tile).Any())));
1330 }
1331
1332 /* Don't allow a bridge where the start and end tiles are adjacent with no span between. */
1333 if (bridge_length == 1) return false;
1334
1335 /* Make sure the road can be continued past the bridge. At this point, bridge_tile holds the end tile of the bridge. */
1336 if (!CanRoadContinueIntoNextTile(t, bridge_tile, bridge_dir)) return false;
1337
1338 /* If another parallel bridge exists nearby, this one would be redundant and shouldn't be built. We don't care about flat bridges. */
1339 if (slope != SLOPE_FLAT) {
1340 for (auto search : SpiralTileSequence(tile, bridge_length, 0, 0)) {
1341 /* Only consider bridge head tiles. */
1342 if (!IsBridgeTile(search)) continue;
1343
1344 /* Only consider road bridges. */
1345 if (GetTunnelBridgeTransportType(search) != TransportType::Road) continue;
1346
1347 /* If the bridge is facing the same direction as the proposed bridge, we've found a redundant bridge. */
1348 if (GetTileSlope(search) & InclinedSlope(ReverseDiagDir(bridge_dir))) return false;
1349 }
1350 }
1351
1352 for (uint8_t times = 0; times <= 22; times++) {
1353 uint8_t bridge_type = RandomRange(MAX_BRIDGES - 1);
1354
1355 /* Can we actually build the bridge? */
1357 if (Command<Commands::BuildBridge>::Do(CommandFlagsToDCFlags(GetCommandFlags<Commands::BuildBridge>()), tile, bridge_tile, TransportType::Road, bridge_type, INVALID_RAILTYPE, rt).Succeeded()) {
1358 Command<Commands::BuildBridge>::Do(CommandFlagsToDCFlags(GetCommandFlags<Commands::BuildBridge>()).Set(DoCommandFlag::Execute), tile, bridge_tile, TransportType::Road, bridge_type, INVALID_RAILTYPE, rt);
1359 return true;
1360 }
1361 }
1362 /* Quit if it selecting an appropriate bridge type fails a large number of times. */
1363 return false;
1364}
1365
1376static bool GrowTownWithTunnel(const Town *t, const TileIndex tile, const DiagDirection tunnel_dir)
1377{
1378 assert(tunnel_dir < DiagDirection::End);
1379
1380 Slope slope = GetTileSlope(tile);
1381
1382 /* Only consider building a tunnel if the starting tile is sloped properly. */
1383 if (slope != InclinedSlope(tunnel_dir)) return false;
1384
1385 /* Assure that the tunnel is connectable to the start side */
1386 if (!GetTownRoadBits(TileAddByDiagDir(tile, ReverseDiagDir(tunnel_dir))).Any(DiagDirToRoadBits(tunnel_dir))) return false;
1387
1388 const TileIndexDiff delta = TileOffsByDiagDir(tunnel_dir);
1389 int max_tunnel_length = 0;
1390
1391 /* There are two conditions for building tunnels: Under a mountain and under an obstruction. */
1392 if (CanRoadContinueIntoNextTile(t, tile, tunnel_dir)) {
1393 /* 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. */
1394 TileIndex slope_tile = tile;
1395 for (uint8_t tiles = 0; tiles < 4; tiles++) {
1396 if (!IsValidTile(slope_tile)) return false;
1397 slope = GetTileSlope(slope_tile);
1398 if (slope != InclinedSlope(tunnel_dir) && !IsSteepSlope(slope) && !IsSlopeWithOneCornerRaised(slope)) return false;
1399 slope_tile += delta;
1400 }
1401
1402 /* More population means longer tunnels, but make sure we can at least cover the smallest mountain which necessitates tunneling. */
1403 max_tunnel_length = (t->cache.population / 1000) + 7;
1404 } else {
1405 /* When tunneling under an obstruction, the length limit is 5, enough to tunnel under a four-track railway. */
1406 max_tunnel_length = 5;
1407 }
1408
1409 uint8_t tunnel_length = 0;
1410 TileIndex tunnel_tile = tile; // Iterator to store the other end tile of the tunnel.
1411
1412 /* Find the end tile of the tunnel for length and continuation checks. */
1413 do {
1414 if (tunnel_length++ >= max_tunnel_length) return false;
1415 tunnel_tile += delta;
1416 /* The tunnel ends when start and end tiles are the same height. */
1417 } while (IsValidTile(tunnel_tile) && GetTileZ(tile) != GetTileZ(tunnel_tile));
1418
1419 /* Don't allow a tunnel where the start and end tiles are adjacent. */
1420 if (tunnel_length == 1) return false;
1421
1422 /* Make sure the road can be continued past the tunnel. At this point, tunnel_tile holds the end tile of the tunnel. */
1423 if (!CanRoadContinueIntoNextTile(t, tunnel_tile, tunnel_dir)) return false;
1424
1425 /* Attempt to build the tunnel. Return false if it fails to let the town build a road instead. */
1427 if (Command<Commands::BuildTunnel>::Do(CommandFlagsToDCFlags(GetCommandFlags<Commands::BuildTunnel>()), tile, TransportType::Road, INVALID_RAILTYPE, rt).Succeeded()) {
1429 return true;
1430 }
1431
1432 return false;
1433}
1434
1442{
1443 static const TileIndexDiffC tiles[] = { {-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1} };
1444 bool allow = false;
1445
1446 for (const auto &ptr : tiles) {
1447 TileIndex cur_tile = t + ToTileIndexDiff(ptr);
1448 if (!IsValidTile(cur_tile)) continue;
1449
1450 if (!(IsTileType(cur_tile, TileType::Road) || IsAnyRoadStopTile(cur_tile))) continue;
1451 allow = true;
1452
1453 RoadType road_rt = GetRoadTypeRoad(cur_tile);
1454 if (road_rt != INVALID_ROADTYPE && !GetRoadTypeInfo(road_rt)->flags.Test(RoadTypeFlag::NoHouses)) return true;
1455 }
1456
1457 /* If no road was found surrounding the tile we can allow building the house since there is
1458 * nothing which forbids it, if a road was found but the execution reached this point, then
1459 * all the found roads don't allow houses to be built */
1460 return !allow;
1461}
1462
1468{
1469 if (!IsTileType(tile, TileType::Road)) return true;
1470
1471 /* Allow extending on roadtypes which can be built by town, or if the road type matches the type the town will build. */
1472 RoadType rt = GetRoadTypeRoad(tile);
1474}
1475
1482{
1483 return modes.Test(TownExpandMode::Roads);
1484}
1485
1492
1512static TownGrowthResult GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection target_dir, Town *t1, TownExpandModes modes)
1513{
1514 RoadBits rcmd{}; // RoadBits for the road construction command
1515 TileIndex tile = *tile_ptr; // The main tile on which we base our growth
1516
1517 assert(tile < Map::Size());
1518
1519 if (cur_rb.None()) {
1520 /* Tile has no road.
1521 * We will return TownGrowthResult::SearchStopped to say that this is the last iteration. */
1522
1524 if (!_settings_game.economy.allow_town_level_crossings && IsTileType(tile, TileType::Railway)) return TownGrowthResult::SearchStopped;
1525
1526 /* Remove hills etc */
1527 if (!_settings_game.construction.build_on_slopes || Chance16(1, 6)) LevelTownLand(tile);
1528
1529 /* Is a road allowed here? */
1530 switch (t1->layout) {
1531 default: NOT_REACHED();
1532
1535 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1536 if (rcmd.None()) return TownGrowthResult::SearchStopped;
1537 break;
1538
1541 if (!IsRoadAllowedHere(t1, tile, target_dir)) return TownGrowthResult::SearchStopped;
1542
1543 DiagDirection source_dir = ReverseDiagDir(target_dir);
1544
1545 if (Chance16(1, 4)) {
1546 /* Randomize a new target dir */
1547 do target_dir = RandomDiagDir(); while (target_dir == source_dir);
1548 }
1549
1550 if (!IsRoadAllowedHere(t1, TileAddByDiagDir(tile, target_dir), target_dir)) {
1551 /* A road is not allowed to continue the randomized road,
1552 * return if the road we're trying to build is curved. */
1553 if (target_dir != ReverseDiagDir(source_dir)) return TownGrowthResult::SearchStopped;
1554
1555 /* Return if neither side of the new road is a house */
1559 }
1560
1561 /* That means that the road is only allowed if there is a house
1562 * at any side of the new road. */
1563 }
1564
1565 rcmd = DiagDirToRoadBits(target_dir) | DiagDirToRoadBits(source_dir);
1566 break;
1567 }
1568
1569 } else if (target_dir < DiagDirection::End && !cur_rb.Any(DiagDirToRoadBits(ReverseDiagDir(target_dir)))) {
1571
1573
1574 /* Continue building on a partial road.
1575 * Should be always OK, so we only generate
1576 * the fitting RoadBits */
1577 switch (t1->layout) {
1578 default: NOT_REACHED();
1579
1582 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1583 break;
1584
1587 rcmd = DiagDirToRoadBits(ReverseDiagDir(target_dir));
1588 break;
1589 }
1590 } else {
1591 bool allow_house = true; // Value which decides if we want to construct a house
1592
1593 /* Reached a tunnel/bridge? Then continue at the other side of it, unless
1594 * it is the starting tile. Half the time, we stay on this side then.*/
1596 if (GetTunnelBridgeTransportType(tile) == TransportType::Road && (target_dir != DiagDirection::End || Chance16(1, 2))) {
1597 *tile_ptr = GetOtherTunnelBridgeEnd(tile);
1598 }
1600 }
1601
1602 /* Possibly extend the road in a direction.
1603 * Randomize a direction and if it has a road, bail out. */
1604 target_dir = RandomDiagDir();
1605 RoadBits target_rb = DiagDirToRoadBits(target_dir);
1606 TileIndex house_tile; // position of a possible house
1607
1608 if (cur_rb.Any(target_rb)) {
1609 /* If it's a road turn possibly build a house in a corner.
1610 * Use intersection with straight road as an indicator
1611 * that we randomised corner house position.
1612 * A turn (and we check for that later) always has only
1613 * one common bit with a straight road so it has the same
1614 * chance to be chosen as the house on the side of a road.
1615 */
1616 if ((cur_rb & ROAD_X) != target_rb) return TownGrowthResult::Continue;
1617
1618 /* Check whether it is a turn and if so determine
1619 * position of the corner tile */
1620 switch (cur_rb.base()) {
1621 case ROAD_N.base():
1622 house_tile = TileAddByDir(tile, Direction::S);
1623 break;
1624 case ROAD_S.base():
1625 house_tile = TileAddByDir(tile, Direction::N);
1626 break;
1627 case ROAD_E.base():
1628 house_tile = TileAddByDir(tile, Direction::W);
1629 break;
1630 case ROAD_W.base():
1631 house_tile = TileAddByDir(tile, Direction::E);
1632 break;
1633 default:
1634 return TownGrowthResult::Continue; // not a turn
1635 }
1636 target_dir = DiagDirection::End;
1637 } else {
1638 house_tile = TileAddByDiagDir(tile, target_dir);
1639 }
1640
1641 /* Don't walk into water. */
1642 if (HasTileWaterGround(house_tile)) return TownGrowthResult::Continue;
1643
1644 if (!IsValidTile(house_tile)) return TownGrowthResult::Continue;
1645
1647
1648 if (target_dir != DiagDirection::End && TownAllowedToBuildRoads(modes)) {
1649 switch (t1->layout) {
1650 default: NOT_REACHED();
1651
1652 case TownLayout::Grid3x3: // Use 2x2 grid afterwards!
1653 if (GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir), modes)) {
1655 }
1656 [[fallthrough]];
1657
1659 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1660 allow_house = !rcmd.Any(target_rb);
1661 break;
1662
1663 case TownLayout::BetterRoads: // Use original afterwards!
1664 if (GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir), modes)) {
1666 }
1667 [[fallthrough]];
1668
1670 /* Allow a house at the edge. 60% chance or
1671 * always ok if no road allowed. */
1672 rcmd = target_rb;
1673 allow_house = (!IsRoadAllowedHere(t1, house_tile, target_dir) || Chance16(6, 10));
1674 break;
1675 }
1676 }
1677
1678 allow_house &= RoadTypesAllowHouseHere(house_tile);
1679
1680 if (allow_house) {
1681 /* Build a house, but not if there already is a house there. */
1682 if (!IsTileType(house_tile, TileType::House)) {
1683 /* Level the land if possible */
1684 if (Chance16(1, 6)) LevelTownLand(house_tile);
1685
1686 /* And build a house.
1687 * Set result to -1 if we managed to build it. */
1688 if (TryBuildTownHouse(t1, house_tile, modes)) {
1690 }
1691 }
1692 return result;
1693 }
1694
1695 if (!TownCanGrowRoad(tile)) return result;
1696 }
1697
1698 /* Return if a water tile */
1700
1701 /* Make the roads look nicer */
1702 rcmd = CleanUpRoadBits(tile, rcmd);
1703 if (rcmd.None()) return TownGrowthResult::SearchStopped;
1704
1705 /* Only use the target direction for bridges and tunnels to ensure they're connected.
1706 * The target_dir is as computed previously according to town layout, so
1707 * it will match it perfectly. */
1708 if (GrowTownWithBridge(t1, tile, target_dir)) {
1710 }
1711 if (GrowTownWithTunnel(t1, tile, target_dir)) {
1713 }
1714
1715 if (GrowTownWithRoad(t1, tile, rcmd)) {
1717 }
1719}
1720
1730{
1731 TileIndex target_tile = tile + TileOffsByDiagDir(dir);
1732 if (!IsValidTile(target_tile)) return false;
1733 if (HasTileWaterGround(target_tile)) return false;
1734
1735 RoadBits target_rb = GetTownRoadBits(target_tile);
1736 if (TownAllowedToBuildRoads(modes)) {
1737 /* Check whether a road connection exists or can be build. */
1738 switch (GetTileType(target_tile)) {
1739 case TileType::Road:
1740 return target_rb.Any();
1741
1742 case TileType::Station:
1743 return IsDriveThroughStopTile(target_tile);
1744
1747
1748 case TileType::House:
1749 case TileType::Industry:
1750 case TileType::Object:
1751 return false;
1752
1753 default:
1754 /* Checked for void and water earlier */
1755 return true;
1756 }
1757 } else {
1758 /* Check whether a road connection already exists,
1759 * and it leads somewhere else. */
1761 return target_rb.Any(back_rb) && target_rb.Reset(back_rb).Any();
1762 }
1763}
1764
1772static bool GrowTownAtRoad(Town *t, TileIndex tile, TownExpandModes modes)
1773{
1774 /* Special case.
1775 * @see GrowTownInTile Check the else if
1776 */
1777 DiagDirection target_dir = DiagDirection::End; // The direction in which we want to extend the town
1778
1779 assert(tile < Map::Size());
1780
1781 /* Number of times to search.
1782 * Better roads, 2X2 and 3X3 grid grow quite fast so we give
1783 * them a little handicap. */
1784 int iterations;
1785 switch (t->layout) {
1787 iterations = 10 + t->cache.num_houses * 2 / 9;
1788 break;
1789
1792 iterations = 10 + t->cache.num_houses * 1 / 9;
1793 break;
1794
1795 default:
1796 iterations = 10 + t->cache.num_houses * 4 / 9;
1797 break;
1798 }
1799
1800 do {
1801 RoadBits cur_rb = GetTownRoadBits(tile); // The RoadBits of the current tile
1802
1803 /* Try to grow the town from this point */
1804 switch (GrowTownInTile(&tile, cur_rb, target_dir, t, modes)) {
1806 return true;
1808 iterations = 0;
1809 break;
1810 default:
1811 break;
1812 };
1813
1814 /* Exclude the source position from the bitmask
1815 * and return if no more road blocks available */
1816 if (IsValidDiagDirection(target_dir)) cur_rb.Reset(DiagDirToRoadBits(ReverseDiagDir(target_dir)));
1817 if (cur_rb.None()) return false;
1818
1820 /* Only build in the direction away from the tunnel or bridge. */
1821 target_dir = ReverseDiagDir(GetTunnelBridgeDirection(tile));
1822 } else {
1823 /* Select a random bit from the blockmask, walk a step
1824 * and continue the search from there. */
1825 do {
1826 if (cur_rb.None()) return false;
1827 RoadBits target_bits;
1828 do {
1829 target_dir = RandomDiagDir();
1830 target_bits = DiagDirToRoadBits(target_dir);
1831 } while (!cur_rb.Any(target_bits));
1832 cur_rb.Reset(target_bits);
1833 } while (!CanFollowRoad(tile, target_dir, modes));
1834 }
1835 tile = TileAddByDiagDir(tile, target_dir);
1836
1838 /* Don't allow building over roads of other cities */
1839 if (IsRoadOwner(tile, RoadTramType::Road, OWNER_TOWN) && Town::GetByTile(tile) != t) {
1840 return false;
1841 } else if (IsRoadOwner(tile, RoadTramType::Road, OWNER_NONE) && _game_mode == GameMode::Editor) {
1842 /* If we are in the SE, and this road-piece has no town owner yet, it just found an
1843 * owner :) (happy happy happy road now) */
1845 SetTownIndex(tile, t->index);
1846 }
1847 }
1848
1849 /* Max number of times is checked. */
1850 } while (--iterations >= 0);
1851
1852 return false;
1853}
1854
1863{
1864 uint32_t r = Random();
1865 uint a = GB(r, 0, 2);
1866 uint b = GB(r, 8, 2);
1867 if (a == b) b ^= 2;
1868 return static_cast<RoadBits>((RoadBits{RoadBit::NW}.base() << a) + (RoadBits{RoadBit::NW}.base() << b));
1869}
1870
1877static bool GrowTown(Town *t, TownExpandModes modes)
1878{
1879 static const TileIndexDiffC _town_coord_mod[] = {
1880 {-1, 0},
1881 { 1, 1},
1882 { 1, -1},
1883 {-1, -1},
1884 {-1, 0},
1885 { 0, 2},
1886 { 2, 0},
1887 { 0, -2},
1888 {-1, -1},
1889 {-2, 2},
1890 { 2, 2},
1891 { 2, -2},
1892 { 0, 0}
1893 };
1894
1895 /* Current "company" is a town */
1897
1898 TileIndex tile = t->xy; // The tile we are working with ATM
1899
1900 /* Find a road that we can base the construction on. */
1901 for (const auto &ptr : _town_coord_mod) {
1902 if (GetTownRoadBits(tile).Any()) {
1903 bool success = GrowTownAtRoad(t, tile, modes);
1904 return success;
1905 }
1906 tile = TileAdd(tile, ToTileIndexDiff(ptr));
1907 }
1908
1909 /* No road available, try to build a random road block by
1910 * clearing some land and then building a road there. */
1911 if (TownAllowedToBuildRoads(modes)) {
1912 tile = t->xy;
1913 for (const auto &ptr : _town_coord_mod) {
1914 /* Only work with plain land that not already has a house */
1915 if (!IsTileType(tile, TileType::House) && IsTileFlat(tile)) {
1916 if (Command<Commands::LandscapeClear>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile).Succeeded()) {
1918 Command<Commands::BuildRoad>::Do({DoCommandFlag::Execute, DoCommandFlag::Auto}, tile, GenRandomRoadBits(), rt, {}, t->index);
1919 return true;
1920 }
1921 }
1922 tile = TileAdd(tile, ToTileIndexDiff(ptr));
1923 }
1924 }
1925
1926 return false;
1927}
1928
1934{
1935 static const std::array<std::array<uint32_t, NUM_HOUSE_ZONES>, 23> _town_squared_town_zone_radius_data = {{
1936 { 4, 0, 0, 0, 0}, // 0
1937 { 16, 0, 0, 0, 0},
1938 { 25, 0, 0, 0, 0},
1939 { 36, 0, 0, 0, 0},
1940 { 49, 0, 4, 0, 0},
1941 { 64, 0, 4, 0, 0}, // 20
1942 { 64, 0, 9, 0, 1},
1943 { 64, 0, 9, 0, 4},
1944 { 64, 0, 16, 0, 4},
1945 { 81, 0, 16, 0, 4},
1946 { 81, 0, 16, 0, 4}, // 40
1947 { 81, 0, 25, 0, 9},
1948 { 81, 36, 25, 0, 9},
1949 { 81, 36, 25, 16, 9},
1950 { 81, 49, 0, 25, 9},
1951 { 81, 64, 0, 25, 9}, // 60
1952 { 81, 64, 0, 36, 9},
1953 { 81, 64, 0, 36, 16},
1954 {100, 81, 0, 49, 16},
1955 {100, 81, 0, 49, 25},
1956 {121, 81, 0, 49, 25}, // 80
1957 {121, 81, 0, 49, 25},
1958 {121, 81, 0, 49, 36}, // 88
1959 }};
1960
1961 if (t->cache.num_houses < std::size(_town_squared_town_zone_radius_data) * 4) {
1962 t->cache.squared_town_zone_radius = _town_squared_town_zone_radius_data[t->cache.num_houses / 4];
1963 } else {
1964 int mass = t->cache.num_houses / 8;
1965 /* Actually we are proportional to sqrt() but that's right because we are covering an area.
1966 * The offsets are to make sure the radii do not decrease in size when going from the table
1967 * to the calculated value.*/
1973 }
1974}
1975
1981{
1983 uint32_t production = ScaleByCargoScale(t->cache.population >> 3, true);
1984 if (production == 0) continue;
1985
1986 auto &supplied = t->GetOrCreateCargoSupplied(cs->Index());
1987 supplied.history[LAST_MONTH].production = production;
1988 }
1989
1991 uint32_t production = ScaleByCargoScale(t->cache.population >> 4, true);
1992 if (production == 0) continue;
1993
1994 auto &supplied = t->GetOrCreateCargoSupplied(cs->Index());
1995 supplied.history[LAST_MONTH].production = production;
1996 }
1997}
1998
1999static void UpdateTownGrowthRate(Town *t);
2000static void UpdateTownGrowth(Town *t);
2001
2013static void DoCreateTown(Town *t, TileIndex tile, uint32_t townnameparts, TownSize size, bool city, TownLayout layout, bool manual)
2014{
2015 AutoRestoreBackup backup(_generating_town, true);
2016
2017 t->xy = tile;
2018 t->cache.num_houses = 0;
2019 t->time_until_rebuild = 10;
2021 t->flags.Reset();
2022 t->cache.population = 0;
2024 /* Spread growth across ticks so even if there are many
2025 * similar towns they're unlikely to grow all in one tick */
2026 t->grow_counter = t->index % Ticks::TOWN_GROWTH_TICKS;
2027 t->growth_rate = TownTicksToGameTicks(250);
2028 t->show_zone = false;
2029
2030 _town_kdtree.Insert(t->index);
2031
2032 /* Set the default cargo requirement for town growth */
2033 switch (_settings_game.game_creation.landscape) {
2036 break;
2037
2041 break;
2042
2043 default:
2044 break;
2045 }
2046
2047 t->fund_buildings_months = 0;
2048
2049 t->ratings.fill(RATING_INITIAL);
2050
2051 t->have_ratings = {};
2052 t->exclusivity = CompanyID::Invalid();
2053 t->exclusive_counter = 0;
2054 t->statues = {};
2055
2056 {
2057 TownNameParams tnp(_settings_game.game_creation.town_name);
2058 t->townnamegrfid = tnp.grfid;
2059 t->townnametype = tnp.type;
2060 }
2061 t->townnameparts = townnameparts;
2062
2063 t->InitializeLayout(layout);
2064
2065 t->larger_town = city;
2066
2067 int x = to_underlying(size) * 16 + 3;
2068 if (size == TownSize::Random) x = (Random() & 0xF) + 8;
2069 /* Don't create huge cities when founding town in-game */
2070 if (city && (!manual || _game_mode == GameMode::Editor)) x *= _settings_game.economy.initial_city_size;
2071
2072 t->cache.num_houses += x;
2074
2075 int i = x * 4;
2076 do {
2078 } while (--i);
2079
2080 t->UpdateVirtCoord();
2081 InvalidateWindowData(WindowClass::TownDirectory, 0, TDIWD_FORCE_REBUILD);
2082
2083 t->cache.num_houses -= x;
2088}
2089
2096static CommandCost TownCanBePlacedHere(TileIndex tile, bool check_surrounding)
2097{
2098 /* Check if too close to the edge of map */
2099 if (DistanceFromEdge(tile) < 12) {
2100 return CommandCost(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP);
2101 }
2102
2103 /* Check distance to all other towns. */
2104 if (IsCloseToTown(tile, _settings_game.economy.town_min_distance)) {
2105 return CommandCost(STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN);
2106 }
2107
2108 /* Can only build on clear flat areas, possibly with trees. */
2109 if ((!IsTileType(tile, TileType::Clear) && !IsTileType(tile, TileType::Trees)) || !IsTileFlat(tile)) {
2110 return CommandCost(STR_ERROR_SITE_UNSUITABLE);
2111 }
2112
2113 /* We might want to make sure the town has enough room. */
2114 if (check_surrounding) {
2115 constexpr uint SEARCH_DIAMETER = 5; // Center tile of town + 2 tile radius.
2116 /* Half of the tiles in the search must be valid for the town to build upon. */
2117 constexpr uint VALID_TILE_GOAL = (SEARCH_DIAMETER * SEARCH_DIAMETER) / 2;
2118 uint counter = 0;
2119 int town_height = GetTileZ(tile);
2120 for (TileIndex t : SpiralTileSequence(tile, SEARCH_DIAMETER)) {
2121 if (counter == VALID_TILE_GOAL) break;
2122
2123 switch (GetTileType(t)) {
2124 case TileType::Clear:
2125 /* Don't allow rough tiles, as they are likely wetlands. */
2126 if (GetClearGround(t) == ClearGround::Rough) continue;
2127 break;
2128
2129 case TileType::Trees:
2130 /* Don't allow rough trees, as they are likely wetlands. */
2131 if (GetTreeGround(t) == TreeGround::Rough) continue;
2132 break;
2133
2134 default:
2135 continue;
2136 }
2137
2138 bool elevation_similar = (GetTileMaxZ(t) <= town_height + 1) && (GetTileZ(t) >= town_height - 1);
2139 if (elevation_similar) counter++;
2140 }
2141
2142 if (counter < VALID_TILE_GOAL) return CommandCost(STR_ERROR_SITE_UNSUITABLE);
2143 }
2144
2146}
2147
2153static bool IsUniqueTownName(const std::string &name)
2154{
2155 for (const Town *t : Town::Iterate()) {
2156 if (!t->name.empty() && t->name == name) return false;
2157 }
2158
2159 return true;
2160}
2161
2174std::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)
2175{
2176 TownNameParams par(_settings_game.game_creation.town_name);
2177
2178 if (size >= TownSize::End) return { CMD_ERROR, 0, TownID::Invalid() };
2179 if (layout >= TownLayout::End) return { CMD_ERROR, 0, TownID::Invalid() };
2180
2181 /* Some things are allowed only in the scenario editor and for game scripts. */
2182 if (_game_mode != GameMode::Editor && _current_company != OWNER_DEITY) {
2183 if (_settings_game.economy.found_town == TownFounding::Forbidden) return { CMD_ERROR, 0, TownID::Invalid() };
2184 if (size == TownSize::Large) return { CMD_ERROR, 0, TownID::Invalid() };
2185 if (random_location) return { CMD_ERROR, 0, TownID::Invalid() };
2186 if (_settings_game.economy.found_town != TownFounding::CustomLayout && layout != _settings_game.economy.town_layout) {
2187 return { CMD_ERROR, 0, TownID::Invalid() };
2188 }
2189 } else if (_current_company == OWNER_DEITY && random_location) {
2190 /* Random parameter is not allowed for Game Scripts. */
2191 return { CMD_ERROR, 0, TownID::Invalid() };
2192 }
2193
2194 if (text.empty()) {
2195 /* If supplied name is empty, townnameparts has to generate unique automatic name */
2196 if (!VerifyTownName(townnameparts, &par)) return { CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE), 0, TownID::Invalid() };
2197 } else {
2198 /* If name is not empty, it has to be unique custom name */
2199 if (Utf8StringLength(text) >= MAX_LENGTH_TOWN_NAME_CHARS) return { CMD_ERROR, 0, TownID::Invalid() };
2200 if (!IsUniqueTownName(text)) return { CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE), 0, TownID::Invalid() };
2201 }
2202
2203 /* Allocate town struct */
2204 if (!Town::CanAllocateItem()) return { CommandCost(STR_ERROR_TOO_MANY_TOWNS), 0, TownID::Invalid() };
2205
2206 if (!random_location) {
2207 CommandCost ret = TownCanBePlacedHere(tile, false);
2208 if (ret.Failed()) return { ret, 0, TownID::Invalid() };
2209 }
2210
2211 static const EnumIndexArray<uint8_t, TownSize, TownSize::End> town_price_mult = {15, 25, 40, 25};
2212 static const EnumIndexArray<uint8_t, TownSize, TownSize::End> city_price_mult = {20, 35, 55, 35};
2213
2215 uint8_t mult = city ? city_price_mult[size] : town_price_mult[size];
2216
2217 cost.MultiplyCost(mult);
2218
2219 /* Create the town */
2220 TownID new_town = TownID::Invalid();
2221 if (flags.Test(DoCommandFlag::Execute)) {
2222 if (cost.GetCost() > GetAvailableMoneyForCommand()) {
2223 return { CommandCost(ExpensesType::Other), cost.GetCost(), TownID::Invalid() };
2224 }
2225
2226 Backup<bool> old_generating_world(_generating_world, true);
2228 Town *t;
2229 if (random_location) {
2230 t = CreateRandomTown(20, townnameparts, size, city, layout);
2231 } else {
2232 t = Town::Create(tile);
2233 DoCreateTown(t, tile, townnameparts, size, city, layout, true);
2234 }
2235
2237 old_generating_world.Restore();
2238
2239 if (t == nullptr) return { CommandCost(STR_ERROR_NO_SPACE_FOR_TOWN), 0, TownID::Invalid() };
2240
2241 new_town = t->index;
2242
2243 if (!text.empty()) {
2244 t->name = text;
2245 t->UpdateVirtCoord();
2246 }
2247
2248 if (_game_mode != GameMode::Editor) {
2249 /* 't' can't be nullptr since 'random' is false outside scenedit */
2250 assert(!random_location);
2251
2253 AddTileNewsItem(GetEncodedString(STR_NEWS_NEW_TOWN_UNSPONSORED, t->index), NewsType::IndustryOpen, tile);
2254 } else {
2255 std::string company_name = GetString(STR_COMPANY_NAME, _current_company);
2256 AddTileNewsItem(GetEncodedString(STR_NEWS_NEW_TOWN, company_name, t->index), NewsType::IndustryOpen, tile);
2257 }
2258 AI::BroadcastNewEvent(new ScriptEventTownFounded(t->index));
2259 Game::NewEvent(new ScriptEventTownFounded(t->index));
2260 }
2261 }
2262 return { cost, 0, new_town };
2263}
2264
2275{
2276 switch (layout) {
2277 case TownLayout::Grid2x2: return TileXY(TileX(tile) - TileX(tile) % 3, TileY(tile) - TileY(tile) % 3);
2278 case TownLayout::Grid3x3: return TileXY(TileX(tile) & ~3, TileY(tile) & ~3);
2279 default: return tile;
2280 }
2281}
2282
2293{
2294 switch (layout) {
2295 case TownLayout::Grid2x2: return TileX(tile) % 3 == 0 && TileY(tile) % 3 == 0;
2296 case TownLayout::Grid3x3: return TileX(tile) % 4 == 0 && TileY(tile) % 4 == 0;
2297 default: return true;
2298 }
2299}
2300
2314{
2315 for (auto coast : SpiralTileSequence(tile, 40)) {
2316 /* Find nearest land tile */
2317 if (!IsTileType(coast, TileType::Clear)) continue;
2318
2319 TileIndex furthest = INVALID_TILE;
2320 uint max_dist = 0;
2321 for (auto test : SpiralTileSequence(coast, 10)) {
2322 if (!IsTileType(test, TileType::Clear) || !IsTileFlat(test) || !IsTileAlignedToGrid(test, layout)) continue;
2323 if (TownCanBePlacedHere(test, true).Failed()) continue;
2324
2325 uint dist = GetClosestWaterDistance(test, true);
2326 if (dist > max_dist) {
2327 furthest = test;
2328 max_dist = dist;
2329 }
2330 }
2331 return furthest;
2332 }
2333
2334 /* if we get here just give up */
2335 return INVALID_TILE;
2336}
2337
2352
2362static Town *CreateRandomTown(uint attempts, uint32_t townnameparts, TownSize size, bool city, TownLayout layout)
2363{
2364 assert(_game_mode == GameMode::Editor || _generating_world); // These are the preconditions for Commands::DeleteTown
2365
2366 if (!Town::CanAllocateItem()) return nullptr;
2367
2368 do {
2369 /* Generate a tile index not too close from the edge */
2370 TileIndex tile = AlignTileToGrid(RandomTile(), layout);
2371
2372 /* If we tried to place the town on water, find a suitable land tile nearby.
2373 * Otherwise, evaluate the land tile. */
2374 if (IsTileType(tile, TileType::Water)) {
2375 tile = FindNearestGoodCoastalTownSpot(tile, layout);
2376 if (tile == INVALID_TILE) continue;
2377 } else if (TownCanBePlacedHere(tile, true).Failed()) continue;
2378
2379 /* Allocate a town struct */
2380 Town *t = Town::Create(tile);
2381
2382 DoCreateTown(t, tile, townnameparts, size, city, layout, false);
2383
2384 /* if the population is still 0 at the point, then the
2385 * placement is so bad it couldn't grow at all */
2386 if (t->cache.population > 0) return t;
2387
2389 [[maybe_unused]] CommandCost rc = Command<Commands::DeleteTown>::Do(DoCommandFlag::Execute, t->index);
2390 assert(rc.Succeeded());
2391
2392 /* We already know that we can allocate a single town when
2393 * entering this function. However, we create and delete
2394 * a town which "resets" the allocation checks. As such we
2395 * need to check again when assertions are enabled. */
2396 assert(Town::CanAllocateItem());
2397 } while (--attempts != 0);
2398
2399 return nullptr;
2400}
2401
2408{
2409 static const uint8_t num_initial_towns[4] = {5, 11, 23, 46}; // very low, low, normal, high
2410 if (_settings_game.difficulty.number_towns == static_cast<uint>(CUSTOM_TOWN_NUMBER_DIFFICULTY)) {
2411 return _settings_newgame.game_creation.custom_town_number;
2412 }
2413 return Map::ScaleBySize(num_initial_towns[_settings_game.difficulty.number_towns]);
2414}
2415
2423bool GenerateTowns(TownLayout layout, std::optional<uint> number)
2424{
2425 uint current_number = 0;
2426 uint total;
2427 if (number.has_value()) {
2428 total = number.value();
2429 } else if (_settings_game.difficulty.number_towns == static_cast<uint>(CUSTOM_TOWN_NUMBER_DIFFICULTY)) {
2430 total = GetDefaultTownsForMapSize();
2431 } else {
2432 total = Map::ScaleByLandProportion(GetDefaultTownsForMapSize() + (Random() & 7));
2433 }
2434
2435 total = Clamp<uint>(total, 1, TownPool::MAX_SIZE);
2436 uint32_t townnameparts;
2437 TownNames town_names;
2438
2440
2441 /* Pre-populate the town names list with the names of any towns already on the map */
2442 for (const Town *town : Town::Iterate()) {
2443 town_names.insert(town->GetCachedName());
2444 }
2445
2446 /* Randomised offset for city status. This means with e.g. 1-in-4 towns being cities, a map with 10 towns
2447 * may have 2 or 3 cities, instead of always 3. */
2448 uint city_random_offset = _settings_game.economy.larger_towns == 0 ? 0 : (Random() % _settings_game.economy.larger_towns);
2449
2450 /* First attempt will be made at creating the suggested number of towns.
2451 * Note that this is really a suggested value, not a required one.
2452 * We would not like the system to lock up just because the user wanted 100 cities on a 64*64 map, would we? */
2453 do {
2454 bool city = (_settings_game.economy.larger_towns != 0 && ((city_random_offset + current_number) % _settings_game.economy.larger_towns) == 0);
2456 /* Get a unique name for the town. */
2457 if (!GenerateTownName(_random, &townnameparts, &town_names)) continue;
2458 /* try 20 times to create a random-sized town for the first loop. */
2459 if (CreateRandomTown(20, townnameparts, TownSize::Random, city, layout) != nullptr) current_number++; // If creation was successful, raise a flag.
2460 } while (--total);
2461
2462 town_names.clear();
2463
2464 /* Build the town k-d tree again to make sure it's well balanced */
2465 RebuildTownKdtree();
2466
2467 if (current_number != 0) return true;
2468
2469 /* If current_number is still zero at this point, it means that not a single town has been created.
2470 * So give it a last try, but now more aggressive */
2471 if (GenerateTownName(_random, &townnameparts) &&
2472 CreateRandomTown(10000, townnameparts, TownSize::Random, _settings_game.economy.larger_towns != 0, layout) != nullptr) {
2473 return true;
2474 }
2475
2476 /* If there are no towns at all and we are generating new game, bail out */
2477 if (Town::GetNumItems() == 0 && _game_mode != GameMode::Editor) {
2478 ShowErrorMessage(GetEncodedString(STR_ERROR_COULD_NOT_CREATE_TOWN), {}, WarningLevel::Critical);
2479 }
2480
2481 return false; // we are still without a town? we failed, simply
2482}
2483
2484
2492{
2493 uint dist = DistanceSquare(tile, t->xy);
2494
2495 if (t->fund_buildings_months != 0 && dist <= 25) return HouseZone::TownCentre;
2496
2497 HouseZone smallest = HouseZone::TownEdge;
2498 for (HouseZone i : HZ_ZONE_ALL) {
2499 if (dist < t->cache.squared_town_zone_radius[to_underlying(i)]) smallest = i;
2500 }
2501
2502 return smallest;
2503}
2504
2516static inline void ClearMakeHouseTile(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool is_protected)
2517{
2518 [[maybe_unused]] CommandCost cc = Command<Commands::LandscapeClear>::Do({DoCommandFlag::Execute, DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile);
2519 assert(cc.Succeeded());
2520
2521 IncreaseBuildingCount(t, type);
2522 MakeHouseTile(tile, t->index, counter, stage, type, random_bits, is_protected);
2523 if (HouseSpec::Get(type)->building_flags.Test(BuildingFlag::IsAnimated)) AddAnimatedTile(tile, false);
2524
2525 MarkTileDirtyByTile(tile);
2526}
2527
2528
2540static void MakeTownHouse(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool is_protected)
2541{
2543
2544 ClearMakeHouseTile(tile, t, counter, stage, type, random_bits, is_protected);
2545 if (size.Any(BUILDING_2_TILES_Y)) ClearMakeHouseTile(tile + TileDiffXY(0, 1), t, counter, stage, ++type, random_bits, is_protected);
2546 if (size.Any(BUILDING_2_TILES_X)) ClearMakeHouseTile(tile + TileDiffXY(1, 0), t, counter, stage, ++type, random_bits, is_protected);
2547 if (size.Any(BUILDING_HAS_4_TILES)) ClearMakeHouseTile(tile + TileDiffXY(1, 1), t, counter, stage, ++type, random_bits, is_protected);
2548
2549 ForAllStationsAroundTiles(TileArea(tile, size.Any(BUILDING_2_TILES_X) ? 2 : 1, size.Any(BUILDING_2_TILES_Y) ? 2 : 1), [t](Station *st, TileIndex) {
2550 t->stations_near.insert(st);
2551 return true;
2552 });
2553}
2554
2555
2562static inline bool CanBuildHouseHere(TileIndex tile, bool noslope)
2563{
2564 /* cannot build on these slopes... */
2565 Slope slope = GetTileSlope(tile);
2566 if ((noslope && slope != SLOPE_FLAT) || IsSteepSlope(slope)) return false;
2567
2568 /* at least one RoadTypes allow building the house here? */
2569 if (!RoadTypesAllowHouseHere(tile)) return false;
2570
2571 /* building under a bridge? */
2572 if (IsBridgeAbove(tile)) return false;
2573
2574 /* can we clear the land? */
2575 return Command<Commands::LandscapeClear>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile).Succeeded();
2576}
2577
2578
2587static inline bool CheckBuildHouseSameZ(TileIndex tile, int z, bool noslope)
2588{
2589 if (!CanBuildHouseHere(tile, noslope)) return false;
2590
2591 /* if building on slopes is allowed, there will be flattening foundation (to tile max z) */
2592 if (GetTileMaxZ(tile) != z) return false;
2593
2594 return true;
2595}
2596
2597
2606static bool CheckFree2x2Area(TileIndex tile, int z, bool noslope)
2607{
2608 /* we need to check this tile too because we can be at different tile now */
2609 if (!CheckBuildHouseSameZ(tile, z, noslope)) return false;
2610
2612 tile += TileOffsByDiagDir(d);
2613 if (!CheckBuildHouseSameZ(tile, z, noslope)) return false;
2614 }
2615
2616 return true;
2617}
2618
2619
2628static inline bool TownLayoutAllowsHouseHere(Town *t, TileIndex tile, TownExpandModes modes)
2629{
2630 if (!modes.Test(TownExpandMode::Buildings)) return false;
2631
2632 /* Allow towns everywhere when we don't build roads */
2633 if (!TownAllowedToBuildRoads(modes)) return true;
2634
2635 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
2636
2637 switch (t->layout) {
2639 if ((grid_pos.x % 3) == 0 || (grid_pos.y % 3) == 0) return false;
2640 break;
2641
2643 if ((grid_pos.x % 4) == 0 || (grid_pos.y % 4) == 0) return false;
2644 break;
2645
2646 default:
2647 break;
2648 }
2649
2650 return true;
2651}
2652
2653
2663{
2664 if (!modes.Test(TownExpandMode::Buildings)) return false;
2665
2666 /* Allow towns everywhere when we don't build roads */
2667 if (!TownAllowedToBuildRoads(modes)) return true;
2668
2669 /* Compute relative position of tile. (Positive offsets are towards north) */
2670 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
2671
2672 switch (t->layout) {
2674 grid_pos.x %= 3;
2675 grid_pos.y %= 3;
2676 if ((grid_pos.x != 2 && grid_pos.x != -1) ||
2677 (grid_pos.y != 2 && grid_pos.y != -1)) return false;
2678 break;
2679
2681 if ((grid_pos.x & 3) < 2 || (grid_pos.y & 3) < 2) return false;
2682 break;
2683
2684 default:
2685 break;
2686 }
2687
2688 return true;
2689}
2690
2691
2703static bool CheckTownBuild2House(TileIndex *tile, Town *t, int maxz, bool noslope, DiagDirection second, TownExpandModes modes)
2704{
2705 /* 'tile' is already checked in BuildTownHouse() - CanBuildHouseHere() and slope test */
2706
2707 TileIndex tile2 = *tile + TileOffsByDiagDir(second);
2708 if (TownLayoutAllowsHouseHere(t, tile2, modes) && CheckBuildHouseSameZ(tile2, maxz, noslope)) return true;
2709
2710 tile2 = *tile + TileOffsByDiagDir(ReverseDiagDir(second));
2711 if (TownLayoutAllowsHouseHere(t, tile2, modes) && CheckBuildHouseSameZ(tile2, maxz, noslope)) {
2712 *tile = tile2;
2713 return true;
2714 }
2715
2716 return false;
2717}
2718
2719
2730static bool CheckTownBuild2x2House(TileIndex *tile, Town *t, int maxz, bool noslope, TownExpandModes modes)
2731{
2732 TileIndex tile2 = *tile;
2733
2734 for (DiagDirection d = DiagDirection::SE;; d++) { // 'd' goes through DiagDirection::SE, DiagDirection::SW, DiagDirection::NW, DiagDirection::End
2735 if (TownLayoutAllows2x2HouseHere(t, tile2, modes) && CheckFree2x2Area(tile2, maxz, noslope)) {
2736 *tile = tile2;
2737 return true;
2738 }
2739 if (d == DiagDirection::End) break;
2740 tile2 += TileOffsByDiagDir(ReverseDiagDir(d)); // go clockwise
2741 }
2742
2743 return false;
2744}
2745
2756static void BuildTownHouse(Town *t, TileIndex tile, const HouseSpec *hs, HouseID house, uint8_t random_bits, bool house_completed, bool is_protected)
2757{
2758 /* build the house */
2759 t->cache.num_houses++;
2760
2761 uint8_t construction_counter = 0;
2762 uint8_t construction_stage = 0;
2763
2764 if (_generating_world || _game_mode == GameMode::Editor || house_completed) {
2765 uint32_t construction_random = Random();
2766
2767 construction_stage = TOWN_HOUSE_COMPLETED;
2768 if (_generating_world && !hs->extra_flags.Test(HouseExtraFlag::BuildingIsHistorical) && Chance16(1, 7)) construction_stage = GB(construction_random, 0, 2);
2769
2770 if (construction_stage == TOWN_HOUSE_COMPLETED) {
2772 } else {
2773 construction_counter = GB(construction_random, 2, 2);
2774 }
2775 }
2776
2777 MakeTownHouse(tile, t, construction_counter, construction_stage, house, random_bits, is_protected);
2780
2781 BuildingFlags size = hs->building_flags;
2782
2783 TriggerHouseAnimation_ConstructionStageChanged(tile, true);
2784 if (size.Any(BUILDING_2_TILES_Y)) TriggerHouseAnimation_ConstructionStageChanged(tile + TileDiffXY(0, 1), true);
2785 if (size.Any(BUILDING_2_TILES_X)) TriggerHouseAnimation_ConstructionStageChanged(tile + TileDiffXY(1, 0), true);
2786 if (size.Any(BUILDING_HAS_4_TILES)) TriggerHouseAnimation_ConstructionStageChanged(tile + TileDiffXY(1, 1), true);
2787}
2788
2797{
2798 /* forbidden building here by town layout */
2799 if (!TownLayoutAllowsHouseHere(t, tile, modes)) return false;
2800
2801 /* no house allowed at all, bail out */
2802 if (!CanBuildHouseHere(tile, false)) return false;
2803
2804 Slope slope = GetTileSlope(tile);
2805 int maxz = GetTileMaxZ(tile);
2806
2807 /* Get the town zone type of the current tile, as well as the climate.
2808 * This will allow to easily compare with the specs of the new house to build */
2809 HouseZones zones = GetTownRadiusGroup(t, tile);
2810
2811 switch (_settings_game.game_creation.landscape) {
2816 }
2817
2818 /* bits 0-4 are used
2819 * bits 11-15 are used
2820 * bits 5-10 are not used. */
2821 static std::vector<std::pair<HouseID, uint>> probs;
2822 probs.clear();
2823
2824 uint probability_max = 0;
2825
2826 /* Generate a list of all possible houses that can be built. */
2827 for (const auto &hs : HouseSpec::Specs()) {
2828 /* Verify that the candidate house spec matches the current tile status */
2829 if (!hs.building_availability.All(zones) || !hs.enabled || hs.grf_prop.override_id != INVALID_HOUSE_ID) continue;
2830
2831 /* Don't let these counters overflow. Global counters are 32bit, there will never be that many houses. */
2832 if (hs.class_id != HOUSE_NO_CLASS) {
2833 /* id_count is always <= class_count, so it doesn't need to be checked */
2834 if (t->cache.building_counts.class_count[hs.class_id] == UINT16_MAX) continue;
2835 } else {
2836 /* If the house has no class, check id_count instead */
2837 if (t->cache.building_counts.id_count[hs.Index()] == UINT16_MAX) continue;
2838 }
2839
2840 uint cur_prob = hs.probability;
2841 probability_max += cur_prob;
2842 probs.emplace_back(hs.Index(), cur_prob);
2843 }
2844
2845 TileIndex base_tile = tile;
2846
2847 while (probability_max > 0) {
2848 /* Building a multitile building can change the location of tile.
2849 * The building would still be built partially on that tile, but
2850 * its northern tile would be elsewhere. However, if the callback
2851 * fails we would be basing further work from the changed tile.
2852 * So a next 1x1 tile building could be built on the wrong tile. */
2853 tile = base_tile;
2854
2855 uint r = RandomRange(probability_max);
2856 uint i;
2857 for (i = 0; i < probs.size(); i++) {
2858 if (probs[i].second > r) break;
2859 r -= probs[i].second;
2860 }
2861
2862 HouseID house = probs[i].first;
2863 probability_max -= probs[i].second;
2864
2865 /* remove tested house from the set */
2866 probs[i] = probs.back();
2867 probs.pop_back();
2868
2869 const HouseSpec *hs = HouseSpec::Get(house);
2870
2872 continue;
2873 }
2874
2876
2877 /* Special houses that there can be only one of. */
2878 TownFlags oneof{};
2879
2881 oneof.Set(TownFlag::HasChurch);
2884 }
2885
2886 if (t->flags.Any(oneof)) continue;
2887
2888 /* Make sure there is no slope? */
2889 bool noslope = hs->building_flags.Test(BuildingFlag::NotSloped);
2890 if (noslope && slope != SLOPE_FLAT) continue;
2891
2893 if (!CheckTownBuild2x2House(&tile, t, maxz, noslope, modes)) continue;
2894 } else if (hs->building_flags.Test(BuildingFlag::Size2x1)) {
2895 if (!CheckTownBuild2House(&tile, t, maxz, noslope, DiagDirection::SW, modes)) continue;
2896 } else if (hs->building_flags.Test(BuildingFlag::Size1x2)) {
2897 if (!CheckTownBuild2House(&tile, t, maxz, noslope, DiagDirection::SE, modes)) continue;
2898 } else {
2899 /* 1x1 house checks are already done */
2900 }
2901
2902 uint8_t random_bits = Random();
2903
2905 uint16_t callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile, {}, true, random_bits);
2906 if (callback_res != CALLBACK_FAILED && !Convert8bitBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_ALLOW_CONSTRUCTION, callback_res)) continue;
2907 }
2908
2909 /* Special houses that there can be only one of. */
2910 t->flags.Set(oneof);
2911
2912 BuildTownHouse(t, tile, hs, house, random_bits, false, false);
2913
2914 return true;
2915 }
2916
2917 return false;
2918}
2919
2929CommandCost CmdPlaceHouse(DoCommandFlags flags, TileIndex tile, HouseID house, bool is_protected, bool replace)
2930{
2931 if (_game_mode != GameMode::Editor && _settings_game.economy.place_houses == PlaceHouses::Forbidden) return CMD_ERROR;
2932
2933 if (Town::GetNumItems() == 0) return CommandCost(STR_ERROR_MUST_FOUND_TOWN_FIRST);
2934
2935 if (static_cast<size_t>(house) >= HouseSpec::Specs().size()) return CMD_ERROR;
2936 const HouseSpec *hs = HouseSpec::Get(house);
2937 if (!hs->enabled) return CMD_ERROR;
2938
2939 int maxz = GetTileMaxZ(tile);
2940
2941 /* Check each tile of a multi-tile house. */
2942 TileArea ta(tile, 1, 1);
2943 if (hs->building_flags.Test(BuildingFlag::Size2x2)) ta.Add(TileAddXY(tile, 1, 1));
2946
2947 for (const TileIndex subtile : ta) {
2948 /* Houses cannot be built on steep slopes. */
2949 Slope slope = GetTileSlope(subtile);
2950 if (IsSteepSlope(slope)) return CommandCost(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
2951
2952 /* Houses cannot be built under bridges. */
2953 if (IsBridgeAbove(subtile)) return CommandCost(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
2954
2955 /* Make sure there is no slope? */
2956 bool noslope = hs->building_flags.Test(BuildingFlag::NotSloped);
2957 if (noslope && slope != SLOPE_FLAT) return CommandCost(STR_ERROR_FLAT_LAND_REQUIRED);
2958
2959 /* All tiles of a multi-tile house must have the same z-level. */
2960 if (GetTileMaxZ(subtile) != maxz) return CommandCost(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
2961
2962 /* We might be replacing an existing house, otherwise check if we can clear land. */
2963 if (!(replace && GetTileType(subtile) == TileType::House)) {
2964 CommandCost cost = Command<Commands::LandscapeClear>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, subtile);
2965 if (!cost.Succeeded()) return cost;
2966 }
2967 }
2968
2969 if (flags.Test(DoCommandFlag::Execute)) {
2970 /* If replacing, clear any existing houses first. */
2971 if (replace) {
2972 for (const TileIndex &subtile : ta) {
2973 if (GetTileType(subtile) == TileType::House) ClearTownHouse(Town::GetByTile(subtile), subtile);
2974 }
2975 }
2976
2977 Town *t = ClosestTownFromTile(tile, UINT_MAX);
2978 bool house_completed = _settings_game.economy.place_houses == PlaceHouses::AllowedConstructed;
2979 BuildTownHouse(t, tile, hs, house, Random(), house_completed, is_protected);
2980 }
2981
2982 return CommandCost();
2983}
2984
2996CommandCost CmdPlaceHouseArea(DoCommandFlags flags, TileIndex tile, TileIndex start_tile, HouseID house, bool is_protected, bool replace, bool diagonal)
2997{
2998 if (start_tile >= Map::Size()) return CMD_ERROR;
2999
3000 if (_game_mode != GameMode::Editor && _settings_game.economy.place_houses == PlaceHouses::Forbidden) return CMD_ERROR;
3001
3002 if (Town::GetNumItems() == 0) return CommandCost(STR_ERROR_MUST_FOUND_TOWN_FIRST);
3003
3004 if (static_cast<size_t>(house) >= HouseSpec::Specs().size()) return CMD_ERROR;
3005 const HouseSpec *hs = HouseSpec::Get(house);
3006 if (!hs->enabled) return CMD_ERROR;
3007
3008 /* Only allow placing an area of 1x1 houses. */
3010
3011 /* Use the built object limit to rate limit house placement. */
3013 int limit = (c == nullptr ? INT32_MAX : GB(c->build_object_limit, 16, 16));
3014
3015 CommandCost last_error = CMD_ERROR;
3016 bool had_success = false;
3017
3018 std::unique_ptr<TileIterator> iter = TileIterator::Create(tile, start_tile, diagonal);
3019 for (; *iter != INVALID_TILE; ++(*iter)) {
3020 TileIndex t = *iter;
3021 CommandCost ret = Command<Commands::PlaceHouse>::Do(DoCommandFlags{flags}.Reset(DoCommandFlag::Execute), t, house, is_protected, replace);
3022
3023 /* If we've reached the limit, stop building (or testing). */
3024 if (c != nullptr && limit-- <= 0) break;
3025
3026 if (ret.Failed()) {
3027 last_error = std::move(ret);
3028 continue;
3029 }
3030
3031 if (flags.Test(DoCommandFlag::Execute)) Command<Commands::PlaceHouse>::Do(flags, t, house, is_protected, replace);
3032 had_success = true;
3033 }
3034
3035 return had_success ? CommandCost{} : last_error;
3036}
3037
3044static void DoClearTownHouseHelper(TileIndex tile, Town *t, HouseID house)
3045{
3046 assert(IsTileType(tile, TileType::House));
3047 DecreaseBuildingCount(t, house);
3048 DoClearSquare(tile);
3049
3051}
3052
3061{
3062 if (house >= 3) { // house id 0,1,2 MUST be single tile houses, or this code breaks.
3063 if (HouseSpec::Get(house - 1)->building_flags.Test(BuildingFlag::Size2x1)) {
3064 house--;
3065 return TileDiffXY(-1, 0);
3066 } else if (HouseSpec::Get(house - 1)->building_flags.Any(BUILDING_2_TILES_Y)) {
3067 house--;
3068 return TileDiffXY(0, -1);
3069 } else if (HouseSpec::Get(house - 2)->building_flags.Any(BUILDING_HAS_4_TILES)) {
3070 house -= 2;
3071 return TileDiffXY(-1, 0);
3072 } else if (HouseSpec::Get(house - 3)->building_flags.Any(BUILDING_HAS_4_TILES)) {
3073 house -= 3;
3074 return TileDiffXY(-1, -1);
3075 }
3076 }
3077 return TileDiffXY(0, 0);
3078}
3079
3086{
3087 assert(IsTileType(tile, TileType::House));
3088
3089 HouseID house = GetHouseType(tile);
3090
3091 /* The northernmost tile of the house is the main house. */
3092 tile += GetHouseNorthPart(house);
3093
3094 const HouseSpec *hs = HouseSpec::Get(house);
3095
3096 /* Remove population from the town if the house is finished. */
3097 if (IsHouseCompleted(tile)) {
3099 }
3100
3101 t->cache.num_houses--;
3102
3103 /* Clear flags for houses that only may exist once/town. */
3108 }
3109
3110 /* Do the actual clearing of tiles */
3111 DoClearTownHouseHelper(tile, t, house);
3112 if (hs->building_flags.Any(BUILDING_2_TILES_Y)) DoClearTownHouseHelper(tile + TileDiffXY(0, 1), t, ++house);
3113 if (hs->building_flags.Any(BUILDING_2_TILES_X)) DoClearTownHouseHelper(tile + TileDiffXY(1, 0), t, ++house);
3114 if (hs->building_flags.Any(BUILDING_HAS_4_TILES)) DoClearTownHouseHelper(tile + TileDiffXY(1, 1), t, ++house);
3115
3117
3119}
3120
3128CommandCost CmdRenameTown(DoCommandFlags flags, TownID town_id, const std::string &text)
3129{
3130 Town *t = Town::GetIfValid(town_id);
3131 if (t == nullptr) return CMD_ERROR;
3132
3133 bool reset = text.empty();
3134
3135 if (!reset) {
3137 if (!IsUniqueTownName(text)) return CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE);
3138 }
3139
3140 if (flags.Test(DoCommandFlag::Execute)) {
3141 t->cached_name.clear();
3142 if (reset) {
3143 t->name.clear();
3144 } else {
3145 t->name = text;
3146 }
3147
3148 t->UpdateVirtCoord();
3149 InvalidateWindowData(WindowClass::TownDirectory, 0, TDIWD_FORCE_RESORT);
3150 ClearAllStationCachedNames();
3151 ClearAllIndustryCachedNames();
3153 }
3154 return CommandCost();
3155}
3156
3163{
3164 for (const CargoSpec *cs : CargoSpec::Iterate()) {
3165 if (cs->town_acceptance_effect == effect) return cs;
3166 }
3167 return nullptr;
3168}
3169
3178CommandCost CmdTownCargoGoal(DoCommandFlags flags, TownID town_id, TownAcceptanceEffect tae, uint32_t goal)
3179{
3180 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3181
3182 if (tae < TownAcceptanceEffect::Begin || tae >= TownAcceptanceEffect::End) return CMD_ERROR;
3183
3184 Town *t = Town::GetIfValid(town_id);
3185 if (t == nullptr) return CMD_ERROR;
3186
3187 /* Validate if there is a cargo which is the requested TownEffect */
3189 if (cargo == nullptr) return CMD_ERROR;
3190
3191 if (flags.Test(DoCommandFlag::Execute)) {
3192 t->goal[tae] = goal;
3194 InvalidateWindowData(WindowClass::TownView, town_id);
3195 }
3196
3197 return CommandCost();
3198}
3199
3207CommandCost CmdTownSetText(DoCommandFlags flags, TownID town_id, const EncodedString &text)
3208{
3209 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3210 Town *t = Town::GetIfValid(town_id);
3211 if (t == nullptr) return CMD_ERROR;
3212
3213 if (flags.Test(DoCommandFlag::Execute)) {
3214 t->text.clear();
3215 if (!text.empty()) t->text = text;
3216 InvalidateWindowData(WindowClass::TownView, town_id);
3217 }
3218
3219 return CommandCost();
3220}
3221
3229CommandCost CmdTownGrowthRate(DoCommandFlags flags, TownID town_id, uint16_t growth_rate)
3230{
3231 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3232
3233 Town *t = Town::GetIfValid(town_id);
3234 if (t == nullptr) return CMD_ERROR;
3235
3236 if (flags.Test(DoCommandFlag::Execute)) {
3237 if (growth_rate == 0) {
3238 /* Just clear the flag, UpdateTownGrowth will determine a proper growth rate */
3240 } else {
3241 uint old_rate = t->growth_rate;
3242 if (t->grow_counter >= old_rate) {
3243 /* This also catches old_rate == 0 */
3244 t->grow_counter = growth_rate;
3245 } else {
3246 /* Scale grow_counter, so half finished houses stay half finished */
3247 t->grow_counter = t->grow_counter * growth_rate / old_rate;
3248 }
3249 t->growth_rate = growth_rate;
3251 }
3253 InvalidateWindowData(WindowClass::TownView, town_id);
3254 }
3255
3256 return CommandCost();
3257}
3258
3267CommandCost CmdTownRating(DoCommandFlags flags, TownID town_id, CompanyID company_id, int16_t rating)
3268{
3269 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3270
3271 Town *t = Town::GetIfValid(town_id);
3272 if (t == nullptr) return CMD_ERROR;
3273
3274 if (!Company::IsValidID(company_id)) return CMD_ERROR;
3275
3276 int16_t new_rating = Clamp(rating, RATING_MINIMUM, RATING_MAXIMUM);
3277 if (flags.Test(DoCommandFlag::Execute)) {
3278 t->ratings[company_id] = new_rating;
3279 InvalidateWindowData(WindowClass::TownAuthority, town_id);
3280 }
3281
3282 return CommandCost();
3283}
3284
3293CommandCost CmdExpandTown(DoCommandFlags flags, TownID town_id, uint32_t grow_amount, TownExpandModes modes)
3294{
3295 if (_game_mode != GameMode::Editor && _current_company != OWNER_DEITY) return CMD_ERROR;
3296 if (modes.None()) return CMD_ERROR;
3297 Town *t = Town::GetIfValid(town_id);
3298 if (t == nullptr) return CMD_ERROR;
3299
3300 if (flags.Test(DoCommandFlag::Execute)) {
3301 /* The more houses, the faster we grow */
3302 if (grow_amount == 0) {
3303 uint amount = RandomRange(ClampTo<uint16_t>(t->cache.num_houses / 10)) + 3;
3304 t->cache.num_houses += amount;
3306
3307 uint n = amount * 10;
3308 do GrowTown(t, modes); while (--n);
3309
3310 t->cache.num_houses -= amount;
3311 } else {
3312 for (; grow_amount > 0; grow_amount--) {
3313 /* Try several times to grow, as we are really suppose to grow */
3314 for (uint i = 0; i < 25; i++) if (GrowTown(t, modes)) break;
3315 }
3316 }
3318
3320 }
3321
3322 return CommandCost();
3323}
3324
3332{
3333 if (_game_mode != GameMode::Editor && !_generating_world) return CMD_ERROR;
3334 Town *t = Town::GetIfValid(town_id);
3335 if (t == nullptr) return CMD_ERROR;
3336
3337 /* Stations refer to towns. */
3338 for (const Station *st : Station::Iterate()) {
3339 if (st->town == t) {
3340 /* Non-oil rig stations are always a problem. */
3341 if (!st->facilities.Test(StationFacility::Airport) || st->airport.type != AT_OILRIG) return CMD_ERROR;
3342 /* We can only automatically delete oil rigs *if* there's no vehicle on them. */
3343 CommandCost ret = Command<Commands::LandscapeClear>::Do(flags, st->airport.tile);
3344 if (ret.Failed()) return ret;
3345 }
3346 }
3347
3348 /* Waypoints refer to towns. */
3349 for (const Waypoint *wp : Waypoint::Iterate()) {
3350 if (wp->town == t) return CMD_ERROR;
3351 }
3352
3353 /* Depots refer to towns. */
3354 for (const Depot *d : Depot::Iterate()) {
3355 if (d->town == t) return CMD_ERROR;
3356 }
3357
3358 /* Check all tiles for town ownership. First check for bridge tiles, as
3359 * these do not directly have an owner so we need to check adjacent
3360 * tiles. This won't work correctly in the same loop if the adjacent
3361 * tile was already deleted earlier in the loop. */
3362 for (const auto current_tile : Map::Iterate()) {
3363 if (IsTileType(current_tile, TileType::TunnelBridge) && TestTownOwnsBridge(current_tile, t)) {
3364 CommandCost ret = Command<Commands::LandscapeClear>::Do(flags, current_tile);
3365 if (ret.Failed()) return ret;
3366 }
3367 }
3368
3369 /* Check all remaining tiles for town ownership. */
3370 for (const auto current_tile : Map::Iterate()) {
3371 bool try_clear = false;
3372 switch (GetTileType(current_tile)) {
3373 case TileType::Road:
3374 try_clear = HasTownOwnedRoad(current_tile) && GetTownIndex(current_tile) == t->index;
3375 break;
3376
3377 case TileType::House:
3378 try_clear = GetTownIndex(current_tile) == t->index;
3379 break;
3380
3381 case TileType::Industry:
3382 try_clear = Industry::GetByTile(current_tile)->town == t;
3383 break;
3384
3385 case TileType::Object:
3386 if (Town::GetNumItems() == 1) {
3387 /* No towns will be left, remove it! */
3388 try_clear = true;
3389 } else {
3390 Object *o = Object::GetByTile(current_tile);
3391 if (o->town == t) {
3392 if (o->type == OBJECT_STATUE) {
3393 /* Statue... always remove. */
3394 try_clear = true;
3395 } else {
3396 /* Tell to find a new town. */
3397 if (flags.Test(DoCommandFlag::Execute)) o->town = nullptr;
3398 }
3399 }
3400 }
3401 break;
3402
3403 default:
3404 break;
3405 }
3406 if (try_clear) {
3407 CommandCost ret = Command<Commands::LandscapeClear>::Do(flags, current_tile);
3408 if (ret.Failed()) return ret;
3409 }
3410 }
3411
3412 /* The town destructor will delete the other things related to the town. */
3413 if (flags.Test(DoCommandFlag::Execute)) {
3414 _town_kdtree.Remove(t->index);
3415 if (t->cache.sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeTown(t->index));
3416 delete t;
3417 }
3418
3419 return CommandCost();
3420}
3421
3428{
3433 static const uint8_t town_action_costs[] = {
3434 2, 4, 9, 35, 48, 53, 117, 175
3435 };
3436 static_assert(std::size(town_action_costs) == to_underlying(TownAction::End));
3437
3438 assert(to_underlying(action) < std::size(town_action_costs));
3439 return town_action_costs[to_underlying(action)];
3440}
3441
3449{
3450 if (flags.Test(DoCommandFlag::Execute)) {
3452 }
3453 return CommandCost();
3454}
3455
3463{
3464 if (flags.Test(DoCommandFlag::Execute)) {
3466 }
3467 return CommandCost();
3468}
3469
3477{
3478 if (flags.Test(DoCommandFlag::Execute)) {
3480 }
3481 return CommandCost();
3482}
3483
3491{
3492 /* Check if the company is allowed to fund new roads. */
3493 if (!_settings_game.economy.fund_roads) return CMD_ERROR;
3494
3495 if (flags.Test(DoCommandFlag::Execute)) {
3496 t->road_build_months = 6;
3497
3498 std::string company_name = GetString(STR_COMPANY_NAME, _current_company);
3499
3501 GetEncodedString(TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_ROAD_REBUILDING_MINUTES : STR_NEWS_ROAD_REBUILDING_MONTHS, t->index, company_name),
3502 NewsType::General, NewsStyle::Normal, {}, t->index);
3503 AI::BroadcastNewEvent(new ScriptEventRoadReconstruction(_current_company, t->index));
3504 Game::NewEvent(new ScriptEventRoadReconstruction(_current_company, t->index));
3505 }
3506 return CommandCost();
3507}
3508
3514static bool CheckClearTile(TileIndex tile)
3515{
3517 return Command<Commands::LandscapeClear>::Do({}, tile).Succeeded();
3518}
3519
3528{
3529 if (!Object::CanAllocateItem()) return CommandCost(STR_ERROR_TOO_MANY_OBJECTS);
3530
3531 static const int STATUE_NUMBER_INNER_TILES = 25; // Number of tiles int the center of the city, where we try to protect houses.
3532
3533 TileIndex best_position = INVALID_TILE;
3534 uint tile_count = 0;
3535 for (auto tile : SpiralTileSequence(t->xy, 9)) {
3536 tile_count++;
3537
3538 /* Statues can be build on slopes, just like houses. Only the steep slopes is a no go. */
3539 if (IsSteepSlope(GetTileSlope(tile))) continue;
3540 /* Don't build statues under bridges. */
3541 if (IsBridgeAbove(tile)) continue;
3542
3543 /* A clear-able open space is always preferred. */
3544 if ((IsTileType(tile, TileType::Clear) || IsTileType(tile, TileType::Trees)) && CheckClearTile(tile)) {
3545 best_position = tile;
3546 break;
3547 }
3548
3549 bool house = IsTileType(tile, TileType::House);
3550
3551 /* Searching inside the inner circle. */
3552 if (tile_count <= STATUE_NUMBER_INNER_TILES) {
3553 /* Save first house in inner circle. */
3554 if (house && best_position == INVALID_TILE && CheckClearTile(tile)) {
3555 best_position = tile;
3556 }
3557
3558 /* If we have reached the end of the inner circle, and have a saved house, terminate the search. */
3559 if (tile_count == STATUE_NUMBER_INNER_TILES && best_position != INVALID_TILE) break;
3560 }
3561
3562 /* Searching outside the circle, just pick the first possible spot. */
3563 if (!house || !CheckClearTile(tile)) continue;
3564 best_position = tile;
3565 break;
3566 }
3567 if (best_position == INVALID_TILE) return CommandCost(STR_ERROR_STATUE_NO_SUITABLE_PLACE);
3568
3569 if (flags.Test(DoCommandFlag::Execute)) {
3571 Command<Commands::LandscapeClear>::Do(DoCommandFlag::Execute, best_position);
3572 cur_company.Restore();
3573 BuildObject(OBJECT_STATUE, best_position, _current_company, t);
3574 t->statues.Set(_current_company); // Once found and built, "inform" the Town.
3575 MarkTileDirtyByTile(best_position);
3576 }
3577 return CommandCost();
3578}
3579
3587{
3588 /* Check if it's allowed to buy the rights */
3589 if (!_settings_game.economy.fund_buildings) return CMD_ERROR;
3590
3591 if (flags.Test(DoCommandFlag::Execute)) {
3592 /* And grow for 3 months */
3593 t->fund_buildings_months = 3;
3594
3595 /* Enable growth (also checking GameScript's opinion) */
3597
3598 /* Build a new house, but add a small delay to make sure
3599 * that spamming funding doesn't let town grow any faster
3600 * than 1 house per 2 * TOWN_GROWTH_TICKS ticks.
3601 * Also emulate original behaviour when town was only growing in
3602 * TOWN_GROWTH_TICKS intervals, to make sure that it's not too
3603 * tick-perfect and gives player some time window where they can
3604 * spam funding with the exact same efficiency.
3605 */
3607
3608 SetWindowDirty(WindowClass::TownView, t->index);
3609 }
3610 return CommandCost();
3611}
3612
3620{
3621 /* Check if it's allowed to buy the rights */
3622 if (!_settings_game.economy.exclusive_rights) return CMD_ERROR;
3623 if (t->exclusivity != CompanyID::Invalid()) return CMD_ERROR;
3624
3625 if (flags.Test(DoCommandFlag::Execute)) {
3626 t->exclusive_counter = 12;
3628
3630
3631 SetWindowClassesDirty(WindowClass::StationView);
3632
3633 /* Spawn news message */
3634 auto cni = std::make_unique<CompanyNewsInformation>(STR_NEWS_EXCLUSIVE_RIGHTS_TITLE, Company::Get(_current_company));
3635 EncodedString message = GetEncodedString(TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MINUTES : STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MONTHS, t->index, cni->company_name);
3636 AddNewsItem(std::move(message),
3637 NewsType::General, NewsStyle::Company, {}, t->index, {}, std::move(cni));
3638 AI::BroadcastNewEvent(new ScriptEventExclusiveTransportRights(_current_company, t->index));
3639 Game::NewEvent(new ScriptEventExclusiveTransportRights(_current_company, t->index));
3640 }
3641 return CommandCost();
3642}
3643
3651{
3652 if (flags.Test(DoCommandFlag::Execute)) {
3653 if (Chance16(1, 14)) {
3654 /* set as unwanted for 6 months */
3655 t->unwanted[_current_company] = 6;
3656
3657 /* set all close by station ratings to 0 */
3658 for (Station *st : Station::Iterate()) {
3659 if (st->town == t && st->owner == _current_company) {
3660 for (GoodsEntry &ge : st->goods) ge.rating = 0;
3661 }
3662 }
3663
3664 /* only show error message to the executing player. All errors are handled command.c
3665 * but this is special, because it can only 'fail' on a DoCommandFlag::Execute */
3666 if (IsLocalCompany()) ShowErrorMessage(GetEncodedString(STR_ERROR_BRIBE_FAILED), {}, WarningLevel::Info);
3667
3668 /* decrease by a lot!
3669 * ChangeTownRating is only for stuff in demolishing. Bribe failure should
3670 * be independent of any cheat settings
3671 */
3672 if (t->ratings[_current_company] > RATING_BRIBE_DOWN_TO) {
3673 t->ratings[_current_company] = RATING_BRIBE_DOWN_TO;
3674 SetWindowDirty(WindowClass::TownAuthority, t->index);
3675 }
3676 } else {
3677 ChangeTownRating(t, RATING_BRIBE_UP_STEP, RATING_BRIBE_MAXIMUM, DoCommandFlag::Execute);
3678 if (t->exclusivity != _current_company && t->exclusivity != CompanyID::Invalid()) {
3679 t->exclusivity = CompanyID::Invalid();
3680 t->exclusive_counter = 0;
3681 }
3682 }
3683 }
3684 return CommandCost();
3685}
3686
3687typedef CommandCost TownActionProc(Town *t, DoCommandFlags flags);
3688static TownActionProc * const _town_action_proc[] = {
3697};
3698static_assert(std::size(_town_action_proc) == to_underlying(TownAction::End));
3699
3706TownActions GetMaskOfTownActions(CompanyID cid, const Town *t)
3707{
3708 TownActions buttons{};
3709
3710 /* Spectators and unwanted have no options */
3711 if (cid != COMPANY_SPECTATOR && !(_settings_game.economy.bribe && t->unwanted[cid])) {
3712
3713 /* Actions worth more than this are not able to be performed */
3714 Money avail = GetAvailableMoney(cid);
3715
3716 /* Check the action bits for validity and
3717 * if they are valid add them */
3718 for (TownAction cur : EnumRange(TownAction::End)) {
3719
3720 /* Is the company prohibited from bribing ? */
3721 if (cur == TownAction::Bribe) {
3722 /* Company can't bribe if setting is disabled */
3723 if (!_settings_game.economy.bribe) continue;
3724 /* Company can bribe if another company has exclusive transport rights,
3725 * or its standing with the town is less than outstanding. */
3726 if (t->ratings[cid] >= RATING_BRIBE_MAXIMUM) {
3727 if (t->exclusivity == _current_company) continue;
3728 if (t->exclusive_counter == 0) continue;
3729 }
3730 }
3731
3732 /* Is the company not able to buy exclusive rights ? */
3733 if (cur == TownAction::BuyRights && (!_settings_game.economy.exclusive_rights || t->exclusive_counter != 0)) continue;
3734
3735 /* Is the company not able to fund buildings ? */
3736 if (cur == TownAction::FundBuildings && !_settings_game.economy.fund_buildings) continue;
3737
3738 /* Is the company not able to fund local road reconstruction? */
3739 if (cur == TownAction::RoadRebuild && !_settings_game.economy.fund_roads) continue;
3740
3741 /* Is the company not able to build a statue ? */
3742 if (cur == TownAction::BuildStatue && t->statues.Test(cid)) continue;
3743
3744 if (avail >= GetTownActionCost(cur) * _price[Price::TownAction] >> 8) {
3745 buttons.Set(cur);
3746 }
3747 }
3748 }
3749
3750 return buttons;
3751}
3752
3763{
3764 Town *t = Town::GetIfValid(town_id);
3765 if (t == nullptr || to_underlying(action) >= std::size(_town_action_proc)) return CMD_ERROR;
3766
3767 if (!GetMaskOfTownActions(_current_company, t).Test(action)) return CMD_ERROR;
3768
3770
3771 CommandCost ret = _town_action_proc[to_underlying(action)](t, flags);
3772 if (ret.Failed()) return ret;
3773
3774 if (flags.Test(DoCommandFlag::Execute)) {
3775 SetWindowDirty(WindowClass::TownAuthority, town_id);
3776 }
3777
3778 return cost;
3779}
3780
3781template <typename Func>
3782static void ForAllStationsNearTown(Town *t, Func func)
3783{
3784 /* Ideally the search radius should be close to the actual town zone 0 radius.
3785 * The true radius is not stored or calculated anywhere, only the squared radius. */
3786 /* The efficiency of this search might be improved for large towns and many stations on the map,
3787 * by using an integer square root approximation giving a value not less than the true square root. */
3789 ForAllStationsRadius(t->xy, search_radius, [&](const Station * st) {
3790 if (DistanceSquare(st->xy, t->xy) <= t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownEdge)]) {
3791 func(st);
3792 }
3793 });
3794}
3795
3800static void UpdateTownRating(Town *t)
3801{
3802 /* Increase company ratings if they're low */
3803 for (const Company *c : Company::Iterate()) {
3804 if (t->ratings[c->index] < RATING_GROWTH_MAXIMUM) {
3805 t->ratings[c->index] = std::min((int)RATING_GROWTH_MAXIMUM, t->ratings[c->index] + RATING_GROWTH_UP_STEP);
3806 }
3807 }
3808
3809 ForAllStationsNearTown(t, [&](const Station *st) {
3810 if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
3811 if (Company::IsValidID(st->owner)) {
3812 int new_rating = t->ratings[st->owner] + RATING_STATION_UP_STEP;
3813 t->ratings[st->owner] = std::min<int>(new_rating, INT16_MAX); // do not let it overflow
3814 }
3815 } else {
3816 if (Company::IsValidID(st->owner)) {
3817 int new_rating = t->ratings[st->owner] + RATING_STATION_DOWN_STEP;
3818 t->ratings[st->owner] = std::max(new_rating, INT16_MIN);
3819 }
3820 }
3821 });
3822
3823 /* clamp all ratings to valid values */
3824 for (auto it = t->ratings.begin(); it != t->ratings.end(); ++it) {
3825 *it = Clamp(*it, RATING_MINIMUM, RATING_MAXIMUM);
3826 }
3827
3828 SetWindowDirty(WindowClass::TownAuthority, t->index);
3829}
3830
3831
3838static void UpdateTownGrowCounter(Town *t, uint16_t prev_growth_rate)
3839{
3840 if (t->growth_rate == TOWN_GROWTH_RATE_NONE) return;
3841 if (prev_growth_rate == TOWN_GROWTH_RATE_NONE) {
3842 t->grow_counter = std::min<uint16_t>(t->growth_rate, t->grow_counter);
3843 return;
3844 }
3845 t->grow_counter = RoundDivSU((uint32_t)t->grow_counter * (t->growth_rate + 1), prev_growth_rate + 1);
3846}
3847
3854{
3855 int n = 0;
3856 ForAllStationsNearTown(t, [&](const Station * st) {
3857 if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
3858 n++;
3859 }
3860 });
3861 return n;
3862}
3863
3871{
3877 static const uint16_t _grow_count_values[2][6] = {
3878 { 120, 120, 120, 100, 80, 60 }, // Fund new buildings has been activated
3879 { 320, 420, 300, 220, 160, 100 } // Normal values
3880 };
3881
3882 int n = CountActiveStations(t);
3883 uint16_t m = _grow_count_values[t->fund_buildings_months != 0 ? 0 : 1][std::min(n, 5)];
3884
3885 uint growth_multiplier = _settings_game.economy.town_growth_rate != 0 ? _settings_game.economy.town_growth_rate - 1 : 1;
3886
3887 m >>= growth_multiplier;
3888 if (t->larger_town) m /= 2;
3889
3890 return TownTicksToGameTicks(m / (t->cache.num_houses / 50 + 1));
3891}
3892
3898{
3899 if (t->flags.Test(TownFlag::CustomGrowth)) return;
3900 uint old_rate = t->growth_rate;
3902 UpdateTownGrowCounter(t, old_rate);
3903 SetWindowDirty(WindowClass::TownView, t->index);
3904}
3905
3910static void UpdateTownGrowth(Town *t)
3911{
3913
3915 SetWindowDirty(WindowClass::TownView, t->index);
3916
3917 if (_settings_game.economy.town_growth_rate == 0 && t->fund_buildings_months == 0) return;
3918
3919 if (t->fund_buildings_months == 0) {
3920 /* Check if all goals are reached for this town to grow (given we are not funding it) */
3922 switch (t->goal[i]) {
3923 case TOWN_GROWTH_WINTER:
3924 if (TileHeight(t->xy) >= GetSnowLine() && t->received[i].old_act == 0 && t->cache.population > 90) return;
3925 break;
3926 case TOWN_GROWTH_DESERT:
3927 if (GetTropicZone(t->xy) == TropicZone::Desert && t->received[i].old_act == 0 && t->cache.population > 60) return;
3928 break;
3929 default:
3930 if (t->goal[i] > t->received[i].old_act) return;
3931 break;
3932 }
3933 }
3934 }
3935
3938 SetWindowDirty(WindowClass::TownView, t->index);
3939 return;
3940 }
3941
3942 if (t->fund_buildings_months == 0 && CountActiveStations(t) == 0 && !Chance16(1, 12)) return;
3943
3945 SetWindowDirty(WindowClass::TownView, t->index);
3946}
3947
3955{
3956 /* The required rating is hardcoded to RATING_VERYPOOR (see below), not the authority attitude setting, so we can bail out like this. */
3957 if (_settings_game.difficulty.town_council_tolerance == TOWN_COUNCIL_PERMISSIVE) return CommandCost();
3958
3960
3961 Town *t = ClosestTownFromTile(tile, _settings_game.economy.dist_local_authority);
3962 if (t == nullptr) return CommandCost();
3963
3964 if (t->ratings[_current_company] > RATING_VERYPOOR) return CommandCost();
3965
3966 return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index);
3967}
3968
3978{
3979 if (Town::GetNumItems() == 0) return nullptr;
3980
3981 TownID tid = _town_kdtree.FindNearest(TileX(tile), TileY(tile));
3982 Town *town = Town::Get(tid);
3983 if (DistanceManhattan(tile, town->xy) < threshold) return town;
3984 return nullptr;
3985}
3986
3995Town *ClosestTownFromTile(TileIndex tile, uint threshold)
3996{
3997 switch (GetTileType(tile)) {
3998 case TileType::Road:
3999 if (IsRoadDepot(tile)) return CalcClosestTownFromTile(tile, threshold);
4000
4001 if (!HasTownOwnedRoad(tile)) {
4002 TownID tid = GetTownIndex(tile);
4003
4004 if (tid == TownID::Invalid()) {
4005 /* in the case we are generating "many random towns", this value may be TownID::Invalid() */
4006 if (_generating_world) return CalcClosestTownFromTile(tile, threshold);
4007 assert(Town::GetNumItems() == 0);
4008 return nullptr;
4009 }
4010
4011 assert(Town::IsValidID(tid));
4012 Town *town = Town::Get(tid);
4013
4014 if (DistanceManhattan(tile, town->xy) >= threshold) town = nullptr;
4015
4016 return town;
4017 }
4018 [[fallthrough]];
4019
4020 case TileType::House:
4021 return Town::GetByTile(tile);
4022
4023 default:
4024 return CalcClosestTownFromTile(tile, threshold);
4025 }
4026}
4027
4028static bool _town_rating_test = false;
4029static std::map<const Town *, int> _town_test_ratings;
4030
4037{
4038 static int ref_count = 0; // Number of times test-mode is switched on.
4039 if (mode) {
4040 if (ref_count == 0) {
4041 _town_test_ratings.clear();
4042 }
4043 ref_count++;
4044 } else {
4045 assert(ref_count > 0);
4046 ref_count--;
4047 }
4048 _town_rating_test = !(ref_count == 0);
4049}
4050
4056static int GetRating(const Town *t)
4057{
4058 if (_town_rating_test) {
4059 auto it = _town_test_ratings.find(t);
4060 if (it != _town_test_ratings.end()) {
4061 return it->second;
4062 }
4063 }
4064 return t->ratings[_current_company];
4065}
4066
4074void ChangeTownRating(Town *t, int add, int max, DoCommandFlags flags)
4075{
4076 /* if magic_bulldozer cheat is active, town doesn't penalize for removing stuff */
4077 if (t == nullptr || flags.Test(DoCommandFlag::NoModifyTownRating) ||
4079 (_cheats.magic_bulldozer.value && add < 0)) {
4080 return;
4081 }
4082
4083 int rating = GetRating(t);
4084 if (add < 0) {
4085 if (rating > max) {
4086 rating += add;
4087 if (rating < max) rating = max;
4088 }
4089 } else {
4090 if (rating < max) {
4091 rating += add;
4092 if (rating > max) rating = max;
4093 }
4094 }
4095 if (_town_rating_test) {
4096 _town_test_ratings[t] = rating;
4097 } else {
4099 t->ratings[_current_company] = rating;
4100 SetWindowDirty(WindowClass::TownAuthority, t->index);
4101 }
4102}
4103
4112{
4113 /* if magic_bulldozer cheat is active, town doesn't restrict your destructive actions */
4114 if (t == nullptr || !Company::IsValidID(_current_company) ||
4115 _cheats.magic_bulldozer.value || flags.Test(DoCommandFlag::NoTestTownRating)) {
4116 return CommandCost();
4117 }
4118
4119 /* minimum rating needed to be allowed to remove stuff */
4120 static const int needed_rating[][to_underlying(TownRatingCheckType::End)] = {
4121 /* RoadRemove, TunnelBridgeRemove */
4126 };
4127
4128 /* check if you're allowed to remove the road/bridge/tunnel
4129 * owned by a town no removal if rating is lower than ... depends now on
4130 * difficulty setting. Minimum town rating selected by difficulty level
4131 */
4132 int needed = needed_rating[_settings_game.difficulty.town_council_tolerance][to_underlying(type)];
4133
4134 if (GetRating(t) < needed) {
4135 return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index);
4136 }
4137
4138 return CommandCost();
4139}
4140
4146template <>
4147Town::SuppliedHistory SumHistory(std::span<const Town::SuppliedHistory> history)
4148{
4149 uint64_t production = std::accumulate(std::begin(history), std::end(history), 0, [](uint64_t r, const auto &s) { return r + s.production; });
4150 uint64_t transported = std::accumulate(std::begin(history), std::end(history), 0, [](uint64_t r, const auto &s) { return r + s.transported; });
4151 auto count = std::size(history);
4152 return {.production = ClampTo<uint32_t>(production / count), .transported = ClampTo<uint32_t>(transported / count)};
4153}
4154
4160template <>
4161Town::AcceptedHistory SumHistory(std::span<const Town::AcceptedHistory> history)
4162{
4163 uint64_t accepted = std::accumulate(std::begin(history), std::end(history), 0, [](uint64_t r, const auto &s) { return r + s.accepted; });
4164 auto count = std::size(history);
4165 return {.accepted = ClampTo<uint32_t>(accepted / count)};
4166}
4167
4169static const IntervalTimer<TimerGameEconomy> _economy_towns_monthly({TimerGameEconomy::Trigger::Month, TimerGameEconomy::Priority::Town}, [](auto)
4170{
4171 for (Town *t : Town::Iterate()) {
4172 /* Check for active town actions and decrement their counters. */
4173 if (t->road_build_months != 0) t->road_build_months--;
4174 if (t->fund_buildings_months != 0) t->fund_buildings_months--;
4175
4176 if (t->exclusive_counter != 0) {
4177 if (--t->exclusive_counter == 0) t->exclusivity = CompanyID::Invalid();
4178 }
4179
4180 /* Check for active failed bribe cooloff periods and decrement them. */
4181 for (const Company *c : Company::Iterate()) {
4182 if (t->unwanted[c->index] > 0) t->unwanted[c->index]--;
4183 }
4184
4185 UpdateValidHistory(t->valid_history, HISTORY_YEAR, TimerGameEconomy::month);
4186
4187 /* Update cargo statistics. */
4188 for (auto &s : t->supplied) RotateHistory(s.history, t->valid_history, HISTORY_YEAR, TimerGameEconomy::month);
4189 for (auto &a : t->accepted) RotateHistory(a.history, t->valid_history, HISTORY_YEAR, TimerGameEconomy::month);
4190 for (auto &received : t->received) received.NewMonth();
4191
4194
4195 SetWindowDirty(WindowClass::TownView, t->index);
4196 }
4197});
4198
4199static const IntervalTimer<TimerGameEconomy> _economy_towns_yearly({TimerGameEconomy::Trigger::Year, TimerGameEconomy::Priority::Town}, [](auto)
4200{
4201 /* Increment house ages */
4202 for (const auto t : Map::Iterate()) {
4203 if (!IsTileType(t, TileType::House)) continue;
4205 }
4206});
4207
4209static CommandCost TerraformTile_Town(TileIndex tile, DoCommandFlags flags, int z_new, Slope tileh_new)
4210{
4211 if (AutoslopeEnabled()) {
4212 HouseID house = GetHouseType(tile);
4213 GetHouseNorthPart(house); // modifies house to the ID of the north tile
4214 const HouseSpec *hs = HouseSpec::Get(house);
4215
4216 /* Here we differ from TTDP by checking BuildingFlag::NotSloped */
4217 if (!hs->building_flags.Test(BuildingFlag::NotSloped) && !IsSteepSlope(tileh_new) &&
4218 (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) {
4219 bool allow_terraform = true;
4220
4221 /* Call the autosloping callback per tile, not for the whole building at once. */
4222 house = GetHouseType(tile);
4223 hs = HouseSpec::Get(house);
4225 /* If the callback fails, allow autoslope. */
4226 uint16_t res = GetHouseCallback(CBID_HOUSE_AUTOSLOPE, 0, 0, house, Town::GetByTile(tile), tile);
4227 if (res != CALLBACK_FAILED && ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_AUTOSLOPE, res)) allow_terraform = false;
4228 }
4229
4231 }
4232 }
4233
4234 return Command<Commands::LandscapeClear>::Do(flags, tile);
4235}
4236
4238extern const TileTypeProcs _tile_type_town_procs = {
4239 .draw_tile_proc = DrawTile_Town,
4240 .get_slope_pixel_z_proc = [](TileIndex tile, uint, uint, bool) { return GetTileMaxPixelZ(tile); },
4241 .clear_tile_proc = ClearTile_Town,
4242 .add_accepted_cargo_proc = AddAcceptedCargo_Town,
4243 .get_tile_desc_proc = GetTileDesc_Town,
4244 .animate_tile_proc = AnimateTile_Town,
4245 .tile_loop_proc = TileLoop_Town,
4246 .add_produced_cargo_proc = AddProducedCargo_Town,
4247 .get_foundation_proc = GetFoundation_Town,
4248 .terraform_tile_proc = TerraformTile_Town,
4249};
4250
4251std::span<const DrawBuildingsTileStruct> GetTownDrawTileData()
4252{
4253 return _town_draw_tile_data;
4254}
Base functions for all AIs.
@ AT_OILRIG
Oilrig airport.
Definition airport.h:38
void AddAnimatedTile(TileIndex tile, bool mark_dirty)
Add the given tile to the animated tile table (if it does not exist yet).
void DeleteAnimatedTile(TileIndex tile, bool immediate)
Stops animation on the given tile.
Tile animation!
@ None
Tile is not animated.
Functions related to autoslope.
bool AutoslopeEnabled()
Tests if autoslope is enabled for _current_company.
Definition autoslope.h:65
Class for backupping variables and making sure they are restored later.
static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
constexpr uint CountBits(T value)
Counts the number of set bits in a variable.
constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
static const uint MAX_BRIDGES
Maximal number of available bridge specs.
Definition bridge.h:18
bool IsBridgeTile(Tile t)
checks if there is a bridge on this tile
Definition bridge_map.h:35
bool IsBridgeAbove(Tile t)
checks if a bridge is set above the ground of this tile
Definition bridge_map.h:45
Axis GetBridgeAxis(Tile t)
Get the axis of the bridge that goes over the tile.
Definition bridge_map.h:68
bool IsValidCargoType(CargoType cargo)
Test whether cargo type is not INVALID_CARGO.
Definition cargo_type.h:110
EnumBitSet< CargoType, uint64_t > CargoTypes
Bitset of CargoType elements.
Definition cargo_type.h:113
CargoType
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:22
TownProductionEffect
Town effect when producing cargo.
Definition cargotype.h:36
@ Mail
Cargo behaves mail-like for production.
Definition cargotype.h:39
@ Passengers
Cargo behaves passenger-like for production.
Definition cargotype.h:38
TownAcceptanceEffect
Town growth effect when delivering cargo.
Definition cargotype.h:22
@ Food
Cargo behaves food/fizzy-drinks-like.
Definition cargotype.h:29
@ Water
Cargo behaves water-like.
Definition cargotype.h:28
@ End
End of town effects.
Definition cargotype.h:30
Cheats _cheats
All the cheats.
Definition cheat.cpp:16
Types related to cheating.
static void BroadcastNewEvent(ScriptEvent *event, CompanyID skip_company=CompanyID::Invalid())
Broadcast a new event to all active AIs.
Definition ai_core.cpp:250
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
constexpr Tstorage base() const noexcept
Retrieve the raw value behind this bit set.
constexpr bool None() const
Test if none of the values are set.
constexpr Timpl & Reset()
Reset all bits.
constexpr Timpl & Set()
Set all bits.
constexpr bool Any(const Timpl &other) const
Test if any of the given values are set.
Common return value for all commands.
bool Succeeded() const
Did this command succeed?
void AddCost(const Money &cost)
Adds the given cost to the cost of the command.
Money GetCost() const
The costs as made up to this moment.
bool Failed() const
Did this command fail?
void MultiplyCost(int factor)
Multiplies the cost of the command by the given factor.
Container for an encoded string, created by GetEncodedString.
Iterate a range of enum values.
static void NewEvent(class ScriptEvent *event)
Queue a new event for the game script.
An interval timer will fire every interval, and will continue to fire until it is deleted.
Definition timer.h:76
TimerGameCalendar::Date introduction_date
Introduction date.
Definition road.h:142
RoadTypeFlags flags
Bit mask of road type flags.
Definition road.h:103
uint16_t max_speed
Maximum speed for vehicles travelling on this road type.
Definition road.h:118
Generate TileIndices around a center tile or tile area, with increasing distance.
Structure contains cached list of stations nearby.
const StationList & GetStations()
Run a tile loop to find stations around a tile, on demand.
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).
static std::unique_ptr< TileIterator > Create(TileIndex corner1, TileIndex corner2, bool diagonal)
Create either an OrthogonalTileIterator or DiagonalTileIterator given the diagonal parameter.
Definition tilearea.cpp:292
static Date date
Current date in days (day counter).
static Year year
Current year, starting at 0.
static constexpr TimerGame< struct Calendar >::Date MAX_DATE
static Month month
Current month (0..11).
static bool UsingWallclockUnits(bool newgame=false)
Check if we are using wallclock units.
static TickCounter counter
Monotonic counter, in ticks, since start of game.
StrongType::Typedef< int32_t, DateTag< struct Calendar >, StrongType::Compare, StrongType::Integer > Date
Map accessors for 'clear' tiles.
@ Rough
Rough mounds (3).
Definition clear_map.h:23
ClearGround GetClearGround(Tile t)
Get the type of clear tile.
Definition clear_map.h:52
CommandFlags GetCommandFlags(Commands cmd)
Get the command flags associated with the given command.
Definition command.cpp:113
CommandCost CommandCostWithParam(StringID str, uint64_t value)
Return an error status, with string and parameter.
Definition command.cpp:416
Functions related to commands.
CommandCost & ExtractCommandCost(Tret &ret)
Extract the CommandCost from a command proc result.
static constexpr DoCommandFlags CommandFlagsToDCFlags(CommandFlags cmd_flags)
Extracts the DC flags needed for DoCommand from the flags returned by GetCommandFlags.
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
@ Auto
don't allow building on structures
@ NoModifyTownRating
do not change town rating
@ NoWater
don't allow building on water
@ Execute
execute the given command
@ NoTestTownRating
town rating does not disallow you from building
EnumBitSet< DoCommandFlag, uint16_t > DoCommandFlags
Bitset of DoCommandFlag elements.
Definition of stuff that is very close to a company, like the company struct itself.
Money GetAvailableMoneyForCommand()
This functions returns the money which can be used to execute a command.
Money GetAvailableMoney(CompanyID company)
Get the amount of money that a company has available, or INT64_MAX if there is no such valid company.
CompanyID _current_company
Company currently doing an action.
Functions related to companies.
bool IsLocalCompany()
Is the current company the local company?
static constexpr Owner OWNER_DEITY
The object is owned by a superuser / goal script.
static constexpr CompanyID COMPANY_SPECTATOR
The client is spectating.
static constexpr Owner OWNER_TOWN
A town owns the tile, or a town is expanding.
static constexpr Owner OWNER_NONE
The tile has no ownership.
Base for all depots (except hangars).
DiagDirection ReverseDiagDir(DiagDirection d)
Returns the reverse direction of the given DiagDirection.
bool IsValidDiagDirection(DiagDirection d)
Checks if an integer value is a valid DiagDirection.
DiagDirection ChangeDiagDir(DiagDirection d, DiagDirDiff delta)
Applies a difference on a DiagDirection.
Axis DiagDirToAxis(DiagDirection d)
Convert a DiagDirection to the axis.
@ Left90
90 degrees left
@ Right90
90 degrees right
DiagDirection
Enumeration for diagonal directions.
@ SW
Southwest.
@ NW
Northwest.
@ End
Used for iterations.
@ SE
Southeast.
Prices _price
Prices and also the fractional part.
Definition economy.cpp:107
bool EconomyIsInRecession()
Is the economy in recession?
uint ScaleByCargoScale(uint num, bool town)
Scale a number by the cargo scale setting.
@ Construction
Construction costs.
@ Other
Other expenses.
@ Terraform
Price for terraforming land, e.g. rising, lowering and flattening.
@ BuildFoundation
Price for building foundation under other constructions e.g. roads, rails, depots,...
@ TownAction
Price for interaction with local authorities.
@ ClearHouse
Price for destroying houses and other town buildings.
@ BuildTown
Price for funding new towns and cities.
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23).
Definition enum_type.hpp:21
EnumClassIndexContainer< std::array< T, to_underlying(N)>, Index > EnumIndexArray
A typedef for EnumClassIndexContainer using std::array as the backing container type.
Functions related to errors.
@ Critical
Critical errors, the MessageBox is shown in all cases.
Definition error.h:27
@ Info
Used for DoCommand-like (and some non-fatal AI GUI) errors/information.
Definition error.h:24
void ShowErrorMessage(EncodedString &&summary_msg, int x, int y, CommandCost &cc)
Display an error message in a window.
Base functions for all Games.
bool _generating_world
Whether we are generating the map or not.
Definition genworld.cpp:74
Functions related to world/map generation.
void IncreaseGeneratingWorldProgress(GenWorldProgress cls)
Increases the current stage of the world generation with one.
@ Towns
Generate towns.
Definition genworld.h:64
void SetGeneratingWorldProgress(GenWorldProgress cls, uint total)
Set the total of a stage of the world generation.
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition gfx_type.h:17
uint8_t GetSnowLine()
Get the current snow line, either variable or static.
uint8_t HighestSnowLine()
Get the highest possible snow line height, either variable or static.
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
Definition gfx.cpp:1553
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_height_override)
Mark a tile given by its index dirty for repaint.
static const SpriteID SPR_LIFT
Definition sprites.h:1151
void UpdateValidHistory(ValidHistoryMask &valid_history, const HistoryRange &hr, uint cur_month)
Update mask of valid records for a historical data.
Definition history.cpp:25
Functions for storing historical data.
void RotateHistory(HistoryData< T > &history, ValidHistoryMask valid_history, const HistoryRange &hr, uint cur_month)
Rotate historical data.
Types for storing historical data.
@ BuildingIsHistorical
this house will only appear during town generation in random games, thus the historical
Definition house.h:97
@ BuildingIsProtected
towns and AI will not remove this house, while human players will be able to
Definition house.h:98
@ Size1x1
The building is a single tile.
Definition house.h:39
@ Size2x2
The building is 2x2 tiles.
Definition house.h:43
@ IsAnimated
The building uses animation.
Definition house.h:44
@ NotSloped
The building can only be built on flat land; when not set foundations are placed.
Definition house.h:40
@ Size2x1
The building is 2x1 tiles, i.e. wider on the X-axis.
Definition house.h:41
@ IsChurch
The building functions as a church, i.e. only one can be built in a town.
Definition house.h:45
@ IsStadium
The building functions as a stadium, i.e. only one can be built in a town.
Definition house.h:46
@ Size1x2
The building is 1x2 tiles, i.e. wider on the Y-axis.
Definition house.h:42
static const HouseID NEW_HOUSE_OFFSET
Offset for new houses.
Definition house.h:28
EnumBitSet< BuildingFlag, uint8_t > BuildingFlags
Bitset of BuildingFlag elements.
Definition house.h:50
EnumBitSet< HouseZone, uint16_t > HouseZones
Bitset of HouseZone elements.
Definition house.h:75
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
Concentric rings of zoning around the centre of a town.
Definition house.h:59
@ TownOuterSuburb
Outer suburbs; roads with pavement.
Definition house.h:62
@ ClimateSubarcticAboveSnow
Building can appear in sub-arctic climate above the snow line.
Definition house.h:67
@ ClimateSubarcticBelowSnow
Building can appear in sub-arctic climate below the snow line.
Definition house.h:69
@ TownInnerSuburb
Inner suburbs; roads with pavement and trees.
Definition house.h:63
@ TownOutskirt
Outskirts of a town; roads without pavement.
Definition house.h:61
@ TownEdge
Edge of the town; roads without pavement.
Definition house.h:60
@ TownCentre
Centre of town; roads with pavement and streetlights.
Definition house.h:64
@ ClimateTemperate
Building can appear in temperate climate.
Definition house.h:68
@ ClimateToyland
Building can appear in toyland climate.
Definition house.h:71
@ ClimateSubtropic
Building can appear in subtropical climate.
Definition house.h:70
uint16_t HouseID
OpenTTD ID of house types.
Definition house_type.h:15
Base of all industries.
void DrawFoundation(TileInfo *ti, Foundation f)
Draw foundation f at tile ti.
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,...
const TileTypeProcs _tile_type_town_procs
TileTypeProcs definitions for TileType::Town tiles.
Definition landscape.cpp:55
Functions related to OTTD's landscape.
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
Command definitions related to landscape (slopes etc.).
@ Arctic
Landscape with snow levels.
@ Toyland
Landscape with funky industries and vehicles.
@ Tropic
Landscape with distinct rainforests and deserts,.
@ Temperate
Base landscape.
#define Point
Macro that prevents name conflicts between included headers.
uint DistanceSquare(TileIndex t0, TileIndex t1)
Gets the 'Square' distance between the two given tiles.
Definition map.cpp:186
uint DistanceFromEdge(TileIndex tile)
Param the minimum distance to an edge.
Definition map.cpp:229
uint DistanceManhattan(TileIndex t0, TileIndex t1)
Gets the Manhattan distance between the two given tiles.
Definition map.cpp:169
uint GetClosestWaterDistance(TileIndex tile, bool water)
Finds the distance for the closest tile with water/land given a tile.
Definition map.cpp:263
Functions related to maps.
TileIndex TileAddXY(TileIndex tile, int x, int y)
Adds a given offset to a tile.
Definition map_func.h:474
TileIndex TileAddByDir(TileIndex tile, Direction dir)
Adds a Direction to a tile.
Definition map_func.h:603
TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc)
Return the offset between two tiles from a TileIndexDiffC struct.
Definition map_func.h:444
TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir)
Adds a DiagDir to a tile.
Definition map_func.h:615
TileIndexDiff TileDiffXY(int x, int y)
Calculates an offset for the given coordinate(-offset).
Definition map_func.h:392
static TileIndex TileXY(uint x, uint y)
Returns the TileIndex of a coordinate.
Definition map_func.h:376
static uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition map_func.h:429
static uint TileX(TileIndex tile)
Get the X component of a tile.
Definition map_func.h:419
constexpr TileIndex TileAdd(TileIndex tile, TileIndexDiff offset)
Adds a given offset to a tile.
Definition map_func.h:461
#define RandomTile()
Get a valid random tile.
Definition map_func.h:656
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition map_func.h:574
TileIndexDiffC TileIndexToTileIndexDiffC(TileIndex tile_a, TileIndex tile_b)
Returns the diff between two tiles.
Definition map_func.h:535
int32_t TileIndexDiff
An offset value between two tiles.
Definition map_type.h:23
constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
constexpr int RoundDivSU(int a, uint b)
Computes round(a / b) for signed a and unsigned b.
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition math_func.hpp:79
constexpr To ClampTo(From value)
Clamp the given value down to lie within the requested type.
@ FakeTowns
Fake town GrfSpecFeature for NewGRF debugging (parent scope).
Definition newgrf.h:104
@ Houses
Houses feature.
Definition newgrf.h:86
@ CBID_HOUSE_DRAW_FOUNDATIONS
Called to determine the type (if any) of foundation to draw for house tile.
@ CBID_HOUSE_CARGO_ACCEPTANCE
Called to decide how much cargo a town building can accept.
@ CBID_HOUSE_AUTOSLOPE
Called to determine if one can alter the ground below a house tile.
@ CBID_HOUSE_CUSTOM_NAME
Called on the Get Tile Description for an house tile.
@ CBID_HOUSE_ALLOW_CONSTRUCTION
Determine whether the house can be built on the specified tile.
@ CBID_HOUSE_ACCEPT_CARGO
Called to determine which cargoes a town building should accept.
@ CBID_HOUSE_PRODUCE_CARGO
Called to determine how much cargo a town building produces.
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
@ AllowConstruction
decide whether the house can be built on a given tile
@ AcceptCargo
decides accepted types
@ CargoAcceptance
decides amount of cargo acceptance
@ DrawFoundations
decides if default foundations need to be drawn
@ ProduceCargo
custom cargo production
@ Autoslope
decides allowance of autosloping
static const uint CALLBACK_HOUSEPRODCARGO_END
Sentinel indicating that the loop for CBID_HOUSE_PRODUCE_CARGO has ended.
CargoType GetCargoTranslation(uint8_t cargo, const GRFFile *grffile, bool usebit)
Translate a GRF-local cargo slot/bitnum into a CargoType.
Cargo support for NewGRFs.
bool Convert8bitBooleanCallback(const GRFFile *grffile, uint16_t cbid, uint16_t cb_res)
Converts a callback result into a boolean.
bool ConvertBooleanCallback(const GRFFile *grffile, uint16_t cbid, uint16_t cb_res)
Converts a callback result into a boolean.
void ErrorUnknownCallbackResult(GrfID grfid, uint16_t cbid, uint16_t cb_res)
Record that a NewGRF returned an unknown/invalid callback result.
GRFConfig * GetGRFConfig(GrfID grfid, uint32_t mask)
Retrieve a NewGRF from the current config by its grfid.
@ Any
Use first found.
Functions/types related to NewGRF debugging.
void DeleteNewGRFInspectWindow(GrfSpecFeature feature, uint index)
Delete inspect window for a given feature and index.
void DecreaseBuildingCount(Town *t, HouseID house_id)
DecreaseBuildingCount() Decrease the number of a building when it is deleted.
void IncreaseBuildingCount(Town *t, HouseID house_id)
IncreaseBuildingCount() Increase the count of a building when it has been added by a town.
uint16_t GetHouseCallback(CallbackID callback, uint32_t param1, uint32_t param2, HouseID house_id, Town *town, TileIndex tile, std::span< int32_t > regs100, bool not_yet_constructed, uint8_t initial_random_bits, CargoTypes watched_cargo_triggers, int view)
Get the result of a house callback.
void InitializeBuildingCounts()
Initialise global building counts and all town building counts.
Functions related to NewGRF houses.
StringID GetGRFStringID(GrfID grfid, GRFStringID stringid)
Returns the index for this stringid associated with its grfID.
Header of Action 04 "universal holder" structure and functions.
StrongType::Typedef< uint32_t, struct GRFStringIDTag, StrongType::Compare, StrongType::Integer > GRFStringID
Type for GRF-internal string IDs.
static constexpr GRFStringID GRFSTR_MISC_GRF_TEXT
Miscellaneous GRF text range.
Functions related to news.
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:917
@ General
General news (from towns).
Definition news_type.h:45
@ IndustryOpen
Opening of industries.
Definition news_type.h:35
@ Company
Company news item. (Newspaper with face).
Definition news_type.h:82
@ Normal
Normal news item. (Newspaper with text only).
Definition news_type.h:80
Functions related to objects.
void BuildObject(ObjectType type, TileIndex tile, CompanyID owner=OWNER_NONE, struct Town *town=nullptr, uint8_t view=0)
Actually build the object.
Base for all objects.
Map accessors for object tiles.
static const ObjectType OBJECT_STATUE
Statue in towns.
Definition object_type.h:20
@ Editor
In the scenario editor.
Definition openttd.h:21
Some methods of Pool are placed here in order to reduce compilation time and binary size.
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don't get linker errors.
static bool IsPlainRailTile(Tile t)
Checks whether the tile is a rail tile or rail tile with signals.
Definition rail_map.h:60
@ INVALID_RAILTYPE
Flag for invalid railtype.
Definition rail_type.h:33
Randomizer _random
Random used in the game state calculations.
Pseudo random number generator.
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.
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.
RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb)
Clean up unnecessary RoadBits of a planned tile.
Definition road.cpp:59
Road specific functions.
@ NoHouses
Bit number for setting this roadtype as not house friendly.
Definition road.h:27
@ TownBuild
Bit number for allowing towns to build this roadtype.
Definition road.h:29
RoadTypes GetMaskForRoadTramType(RoadTramType rtt)
Get the mask for road types of the given RoadTramType.
Definition road.h:185
const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
Definition road.h:217
void UpdateNearestTownForRoadTiles(bool invalidate)
Updates cached nearest town for all road tiles.
Road related functions.
RoadBits DiagDirToRoadBits(DiagDirection d)
Create the road-part which belongs to the given DiagDirection.
Definition road_func.h:78
Functions used internally by the roads.
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
void SetRoadOwner(Tile t, RoadTramType rtt, Owner o)
Set the owner of a specific road type.
Definition road_map.h:261
bool HasTownOwnedRoad(Tile t)
Checks if given tile has town owned road.
Definition road_map.h:290
RoadType GetRoadTypeRoad(Tile t)
Get the road type for RoadTramType being RoadTramType::Road.
Definition road_map.h:152
static bool IsRoadDepotTile(Tile t)
Return whether a tile is a road depot tile.
Definition road_map.h:100
DisallowedRoadDirections GetDisallowedRoadDirections(Tile t)
Gets the disallowed directions.
Definition road_map.h:311
bool HasTileRoadType(Tile t, RoadTramType rtt)
Check if a tile has a road or a tram road type.
Definition road_map.h:221
DiagDirection GetRoadDepotDirection(Tile t)
Get the direction of the exit of a road depot.
Definition road_map.h:565
static bool IsRoadDepot(Tile t)
Return whether a tile is a road depot.
Definition road_map.h:90
static bool IsNormalRoadTile(Tile t)
Return whether a tile is a normal road tile.
Definition road_map.h:58
bool IsRoadOwner(Tile t, RoadTramType rtt, Owner o)
Check if a specific road type is owned by an owner.
Definition road_map.h:278
static constexpr RoadBits ROAD_W
Road at the two western edges.
Definition road_type.h:73
static constexpr RoadBits ROAD_X
Full road along the x-axis (south-west + north-east).
Definition road_type.h:67
EnumBitSet< RoadBit, uint8_t > RoadBits
Bitset of RoadBit elements.
Definition road_type.h:65
static constexpr RoadBits ROAD_E
Road at the two eastern edges.
Definition road_type.h:71
@ SW
South-west part.
Definition road_type.h:59
@ NW
North-west part.
Definition road_type.h:58
@ NE
North-east part.
Definition road_type.h:61
@ SE
South-east part.
Definition road_type.h:60
static constexpr RoadBits ROAD_ALL
Full 4-way crossing.
Definition road_type.h:75
static constexpr RoadBits ROAD_Y
Full road along the y-axis (north-west + south-east).
Definition road_type.h:68
static constexpr RoadBits ROAD_N
Road at the two northern edges.
Definition road_type.h:70
RoadType
The different roadtypes we support.
Definition road_type.h:24
@ INVALID_ROADTYPE
flag for invalid roadtype
Definition road_type.h:29
@ ROADTYPE_ROAD
Basic road type.
Definition road_type.h:26
static constexpr RoadBits ROAD_S
Road at the two southern edges.
Definition road_type.h:72
@ Road
Road type.
Definition road_type.h:39
A number of safeguards to prevent using unsafe methods.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
GameSettings _settings_newgame
Game settings for new games (updated from the intro screen).
Definition settings.cpp:62
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:60
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:170
static constexpr Slope RemoveHalftileSlope(Slope s)
Removes a halftile slope from a slope.
Definition slope_func.h:70
bool IsSlopeWithOneCornerRaised(Slope s)
Tests if a specific slope has exactly one corner raised.
Definition slope_func.h:98
static constexpr bool IsSteepSlope(Slope s)
Checks if a slope is steep.
Definition slope_func.h:36
static constexpr Slope RemoveSteepSlope(Slope s)
Removes a steep flag from a slope.
Definition slope_func.h:46
Foundation FlatteningFoundation(Slope s)
Returns the foundation needed to flatten a slope.
Definition slope_func.h:377
Slope InclinedSlope(DiagDirection dir)
Returns the slope that is inclined in a specific direction.
Definition slope_func.h:266
Slope ComplementSlope(Slope s)
Return the complement of a slope.
Definition slope_func.h:86
Slope
Enumeration for the slope-type.
Definition slope_type.h:53
@ SLOPE_W
the west corner of the tile is raised
Definition slope_type.h:55
@ SLOPE_ELEVATED
bit mask containing all 'simple' slopes
Definition slope_type.h:66
@ SLOPE_E
the east corner of the tile is raised
Definition slope_type.h:57
@ SLOPE_S
the south corner of the tile is raised
Definition slope_type.h:56
@ SLOPE_N
the north corner of the tile is raised
Definition slope_type.h:58
@ SLOPE_SW
south and west corner are raised
Definition slope_type.h:61
@ SLOPE_FLAT
a flat tile
Definition slope_type.h:54
@ SLOPE_STEEP_W
a steep slope falling to east (from west)
Definition slope_type.h:71
@ SLOPE_NE
north and east corner are raised
Definition slope_type.h:63
@ SLOPE_STEEP_E
a steep slope falling to west (from east)
Definition slope_type.h:73
@ SLOPE_SE
south and east corner are raised
Definition slope_type.h:62
@ SLOPE_NW
north and west corner are raised
Definition slope_type.h:60
@ SLOPE_STEEP_N
a steep slope falling to south (from north)
Definition slope_type.h:74
@ SLOPE_STEEP_S
a steep slope falling to north (from south)
Definition slope_type.h:72
Foundation
Enumeration for Foundations.
Definition slope_type.h:119
@ Leveled
The tile is leveled up to a flat slope.
Definition slope_type.h:121
@ None
The tile has no foundation, the slope remains unchanged.
Definition slope_type.h:120
@ Town
Source/destination is a town.
Definition source_type.h:22
Base classes/functions for stations.
void ForAllStationsAroundTiles(const TileArea &ta, Func func)
Call a function on all stations that have any part of the requested area within their catchment.
void UpdateAllStationVirtCoords()
Update the virtual coords needed to draw the station sign for all stations.
void UpdateAirportsNoise()
Recalculate the noise generated by the airports of each town.
void ModifyStationRatingAround(TileIndex tile, Owner owner, int amount, uint radius)
Forcibly modify station ratings near a given tile.
Declarations for accessing the k-d tree of stations.
void ForAllStationsRadius(TileIndex center, uint radius, Func func)
Call a function on all stations whose sign is within a radius of a center tile.
bool IsBayRoadStopTile(Tile t)
Is tile t a bay (non-drive through) road stop station?
bool IsDriveThroughStopTile(Tile t)
Is tile t a drive through road stop station or waypoint?
Axis GetDriveThroughStopAxis(Tile t)
Gets the axis of the drive through stop.
DiagDirection GetBayRoadStopDir(Tile t)
Gets the direction the bay road stop entrance points towards.
bool IsAnyRoadStopTile(Tile t)
Is tile t a road stop station?
@ Airport
Station with an airport.
Definition of base types and functions in a cross-platform compatible way.
#define lengthof(array)
Return the length of an fixed size array.
Definition stdafx.h:261
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:351
Functions related to low-level strings.
EncodedString GetEncodedString(StringID str)
Encode a string with no parameters into an encoded string.
Definition strings.cpp:90
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
Definition strings.cpp:424
Functions related to OTTD's strings.
StrongType::Typedef< uint32_t, struct StringIDTag, StrongType::Compare, StrongType::Integer > StringID
Numeric value that represents a string, independent of the selected language.
Class to backup a specific variable and restore it upon destruction of this object to prevent stack v...
Class to backup a specific variable and restore it later.
void Restore()
Restore the variable.
Owner owner
The owner of this station.
Class for storing amounts of cargo.
Definition cargo_type.h:118
static void InvalidateAllFrom(Source src)
Invalidates (sets source_id to INVALID_SOURCE) all cargo packets from given source.
Specification of a cargo type.
Definition cargotype.h:77
static EnumIndexArray< std::vector< const CargoSpec * >, TownProductionEffect, TownProductionEffect::End > town_production_cargoes
List of cargo specs for each Town Product Effect.
Definition cargotype.h:197
static IterateWrapper Iterate(size_t from=0)
Returns an iterable ensemble of all valid CargoSpec.
Definition cargotype.h:194
uint32_t build_object_limit
Amount of tiles we can (still) build objects on (times 65536). Also applies to buying land and placin...
T y
Y coordinate.
T x
X coordinate.
T x
X coordinate.
T y
Y coordinate.
This structure is the same for both Industries and Houses.
Definition sprite.h:90
uint8_t draw_proc
This allows to specify a special drawing procedure.
Definition sprite.h:93
Information about GRF, used in the game and (part of it) in savegames.
std::string GetName() const
Get the name of this grf.
GrfID grfid
grfid that introduced this entity.
const struct GRFFile * grffile
grf file that introduced this entity
bool HasGrfFile() const
Test if this entity was introduced by NewGRF.
Stores station stats for a single cargo.
uint8_t rating
Station rating for this cargo.
CargoType accepts_cargo[HOUSE_NUM_ACCEPTS]
input cargo slots
Definition house.h:116
SubstituteGRFFileProps grf_prop
Properties related the the grf file.
Definition house.h:122
uint8_t removal_cost
cost multiplier for removing it
Definition house.h:111
uint8_t mail_generation
mail generation multiplier (tile based, as the acceptances below)
Definition house.h:114
bool enabled
the house is available to build (true by default, but can be disabled by newgrf)
Definition house.h:119
Money GetRemovalCost() const
Get the cost for removing this house.
Definition town_cmd.cpp:234
static HouseSpec * Get(size_t house_id)
Get the spec for a house ID.
BuildingFlags building_flags
some flags that describe the house (size, stadium etc...)
Definition house.h:117
TimerGameCalendar::Year max_year
last year it can be built
Definition house.h:109
HouseCallbackMasks callback_mask
Bitmask of house callbacks that have to be called.
Definition house.h:123
uint16_t remove_rating_decrease
rating decrease if removed
Definition house.h:113
uint8_t population
population (Zero on other tiles in multi tile house.)
Definition house.h:110
HouseExtraFlags extra_flags
some more flags
Definition house.h:126
uint8_t cargo_acceptance[HOUSE_NUM_ACCEPTS]
acceptance level for the cargo slots
Definition house.h:115
HouseID Index() const
Gets the index of this spec.
StringID building_name
building name
Definition house.h:112
uint8_t minimum_life
The minimum number of years this house will survive before the town rebuilds it.
Definition house.h:130
static std::vector< HouseSpec > & Specs()
Get a reference to all HouseSpecs.
Defines the internal data of a functional industry.
Definition industry.h:64
Town * town
Nearest town.
Definition industry.h:109
static Industry * GetByTile(TileIndex tile)
Get the industry of the given tile.
Definition industry.h:253
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:331
static IterateWrapper Iterate()
Returns an iterable ensemble of all Tiles.
Definition map_func.h:366
static uint ScaleByLandProportion(uint n)
Scales the given value by the number of water tiles.
Definition map_func.h:308
static uint Size()
Get the size of the map.
Definition map_func.h:280
An object, such as transmitter, on the map.
Definition object_base.h:24
ObjectType type
Type of the object.
Definition object_base.h:25
Town * town
Town the object is built in.
Definition object_base.h:26
static Object * GetByTile(TileIndex tile)
Get the object associated with a tile.
void Add(TileIndex to_add)
Add a single tile to a tile area; enlarge if needed.
Definition tilearea.cpp:43
SpriteID sprite
The 'real' sprite.
Definition gfx_type.h:23
PaletteID pal
The palette (use PAL_NONE) if not needed).
Definition gfx_type.h:24
static Pool::IterateWrapper< Town > Iterate(size_t from=0)
static T * Create(Targs &&... args)
static Town * Get(auto index)
static bool CanAllocateItem(size_t n=1)
static bool IsValidID(auto index)
static Company * GetIfValid(auto index)
static constexpr size_t MAX_SIZE
A location from where cargo can come from (or go to).
Definition source_type.h:32
static Pool::IterateWrapper< Station > Iterate(size_t from=0)
Station data structure.
bool CatchmentCoversTown(TownID t) const
Test if the given town ID is covered by our catchment area.
Definition station.cpp:455
uint16_t subst_id
The id of the entity to replace.
Tile description for the 'land area information' tool.
Definition tile_cmd.h:40
std::optional< std::string > grf
newGRF used for the tile contents
Definition tile_cmd.h:51
StringID str
Description of the tile.
Definition tile_cmd.h:41
std::array< Owner, 4 > owner
Name of the owner(s).
Definition tile_cmd.h:43
uint64_t dparam
Parameter of the str string.
Definition tile_cmd.h:42
std::optional< bool > town_can_upgrade
Whether the town can upgrade this house during town growth.
Definition tile_cmd.h:58
A pair-construct of a TileIndexDiff.
Definition map_type.h:31
int16_t x
The x value of the coordinate.
Definition map_type.h:32
int16_t y
The y value of the coordinate.
Definition map_type.h:33
Tile information, used while rendering the tile.
Definition tile_cmd.h:34
Slope tileh
Slope of the tile.
Definition tile_cmd.h:35
TileIndex tile
Tile index.
Definition tile_cmd.h:36
Set of callback functions for performing tile operations of a given tile type.
Definition tile_cmd.h:214
uint32_t population
Current population of people.
Definition town.h:54
uint32_t num_houses
Amount of houses.
Definition town.h:53
TrackedViewportSign sign
Location of name sign, UpdateVirtCoord updates this.
Definition town.h:55
BuildingCounts< uint16_t > building_counts
The number of each type of building in the town.
Definition town.h:58
std::array< uint32_t, NUM_HOUSE_ZONES > squared_town_zone_radius
UpdateTownRadius updates this given the house count.
Definition town.h:57
Struct holding parameters used to generate town name.
GrfID grfid
newgrf ID (0 if not used)
uint16_t type
town name style
Individual data point for accepted cargo history.
Definition town.h:111
Town data structure.
Definition town.h:64
EncodedString text
General text with additional information.
Definition town.h:137
bool larger_town
if this is a larger town and should grow more quickly
Definition town.h:199
CompanyMask statues
which companies have a statue?
Definition town.h:82
uint16_t time_until_rebuild
time until we rebuild a house
Definition town.h:191
std::string cached_name
NOSAVE: Cache of the resolved name of the town, if not using a custom town name.
Definition town.h:75
TileIndex xy
town center tile
Definition town.h:65
uint8_t fund_buildings_months
fund buildings program in action?
Definition town.h:196
TownLayout layout
town specific road layout
Definition town.h:200
static Town * GetRandom()
Return a random valid town.
Definition town_cmd.cpp:205
std::string name
Custom town name. If empty, the town was not renamed and uses the generated name.
Definition town.h:74
Town(TownID index, TileIndex tile=INVALID_TILE)
Creates a new town.
Definition town.h:211
GrfID townnamegrfid
NewGRF id that contains the name. O is not used.
Definition town.h:71
uint16_t grow_counter
counter to count when to grow, value is smaller than or equal to growth_rate
Definition town.h:193
uint32_t townnameparts
Random number that give unique town name when passed to generator.
Definition town.h:73
TownFlags flags
See TownFlags.
Definition town.h:78
TownCache cache
Container for all cacheable data.
Definition town.h:67
TypedIndexContainer< std::array< uint8_t, MAX_COMPANIES >, CompanyID > unwanted
how many months companies aren't wanted by towns (bribe)
Definition town.h:86
CompanyID exclusivity
which company has exclusivity
Definition town.h:87
void InitializeLayout(TownLayout layout)
Assign the town layout.
Definition town_cmd.cpp:191
bool show_zone
NOSAVE: mark town to show the local authority zone in the viewports.
Definition town.h:202
uint8_t exclusive_counter
months till the exclusivity expires
Definition town.h:88
void UpdateVirtCoord()
Resize the sign (label) of the town after it changes population.
Definition town_cmd.cpp:388
EnumIndexArray< TransportedCargoStat< uint16_t >, TownAcceptanceEffect, TownAcceptanceEffect::End > received
Cargo statistics about received cargotypes.
Definition town.h:133
CompanyMask have_ratings
which companies have a rating
Definition town.h:85
~Town()
Destroy the town.
Definition town_cmd.cpp:116
TypedIndexContainer< std::array< int16_t, MAX_COMPANIES >, CompanyID > ratings
ratings of each company for this town
Definition town.h:89
uint16_t growth_rate
town growth rate
Definition town.h:194
StationList stations_near
NOSAVE: List of nearby stations.
Definition town.h:189
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:176
uint8_t road_build_months
fund road reconstruction in action?
Definition town.h:197
EnumIndexArray< uint32_t, TownAcceptanceEffect, TownAcceptanceEffect::End > goal
Amount of cargo required for the town to grow.
Definition town.h:134
uint16_t townnametype
The style of the name.
Definition town.h:72
bool kdtree_valid
Are the sign data valid for use with the _viewport_sign_kdtree?
Representation of a waypoint.
void DeleteSubsidyWith(Source source)
Delete the subsidies associated with a given cargo source type and id.
Definition subsidy.cpp:120
Functions related to subsidies.
Command definitions related to terraforming.
bool IsTileFlat(TileIndex tile, int *h)
Check if a given tile is flat.
Definition tile_map.cpp:94
int GetTileMaxZ(TileIndex t)
Get top height of the tile inside the map.
Definition tile_map.cpp:135
int GetTileZ(TileIndex tile)
Get bottom height of the tile.
Definition tile_map.cpp:115
static bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition tile_map.h:150
uint TileHash(uint x, uint y)
Calculate a hash value from a tile position.
Definition tile_map.h:324
static uint TileHeight(Tile tile)
Returns the height of a tile.
Definition tile_map.h:29
bool IsTileOwner(Tile tile, Owner owner)
Checks if a tile belongs to the given owner.
Definition tile_map.h:214
int GetTileMaxPixelZ(TileIndex tile)
Get top height of the tile.
Definition tile_map.h:312
bool IsValidTile(Tile tile)
Checks if a tile is valid.
Definition tile_map.h:161
uint TileHash2Bit(uint x, uint y)
Get the last two bits of the TileHash from a tile position.
Definition tile_map.h:342
TropicZone GetTropicZone(Tile tile)
Get the tropic zone.
Definition tile_map.h:238
Slope GetTileSlope(TileIndex tile)
Return the slope of a given tile inside the map.
Definition tile_map.h:279
static TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
Definition tile_map.h:96
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > > TileIndex
The index/ID of a Tile.
Definition tile_type.h:92
@ Desert
Tile is desert.
Definition tile_type.h:83
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:100
static constexpr uint TILE_SIZE
Tile size in world coordinates.
Definition tile_type.h:15
@ TunnelBridge
Tunnel entry/exit and bridge heads.
Definition tile_type.h:58
@ Water
Water tile.
Definition tile_type.h:55
@ Station
A tile of a station or airport.
Definition tile_type.h:54
@ Object
Contains objects such as transmitters and owned land.
Definition tile_type.h:59
@ Industry
Part of an industry.
Definition tile_type.h:57
@ Railway
A tile with railway.
Definition tile_type.h:50
@ Void
Invisible tiles at the SW and SE border.
Definition tile_type.h:56
@ Trees
Tile with one or more trees.
Definition tile_type.h:53
@ House
A house by a town.
Definition tile_type.h:52
@ Road
A tile with road and/or tram tracks.
Definition tile_type.h:51
@ Clear
A tile without any structures, i.e. grass, rocks, farm fields etc.
Definition tile_type.h:49
OrthogonalTileArea TileArea
Shorthand for the much more common orthogonal tile area.
Definition of Interval and OneShot timers.
Definition of the game-calendar-timer.
Definition of the game-economy-timer.
Definition of the tick-based game-timer.
Base of the town class.
static const uint TOWN_GROWTH_WINTER
The town only needs this cargo in the winter (any amount).
Definition town.h:32
TownRatingCheckType
Action types that a company must ask permission for to a town authority.
Definition town.h:274
@ End
End marker.
Definition town.h:277
EnumBitSet< TownFlag, uint8_t > TownFlags
Bitset of TownFlag elements.
Definition town.h:49
static const uint TOWN_GROWTH_DESERT
The town needs the cargo for growth when on desert (any amount).
Definition town.h:33
EnumBitSet< TownAction, uint8_t > TownActions
Bitset of TownAction elements.
Definition town.h:310
static const uint CUSTOM_TOWN_NUMBER_DIFFICULTY
value for custom town number in difficulty settings
Definition town.h:29
Town * CalcClosestTownFromTile(TileIndex tile, uint threshold=UINT_MAX)
Return the town closest to the given tile within threshold.
TownAction
Town actions of a company.
Definition town.h:297
@ RoadRebuild
Rebuild the roads.
Definition town.h:301
@ Bribe
Try to bribe the council.
Definition town.h:305
@ End
End marker.
Definition town.h:306
@ BuildStatue
Build a statue.
Definition town.h:302
@ BuyRights
Buy exclusive transport rights.
Definition town.h:304
@ FundBuildings
Fund new buildings.
Definition town.h:303
@ HasChurch
There can be only one church by town.
Definition town.h:43
@ CustomGrowth
Growth rate is controlled by GS.
Definition town.h:45
@ HasStadium
There can be only one stadium by town.
Definition town.h:44
@ IsGrowing
Conditions for town growth are met. Grow according to Town::growth_rate.
Definition town.h:42
static const uint16_t TOWN_GROWTH_RATE_NONE
Special value for Town::growth_rate to disable town growth.
Definition town.h:34
static bool RoadTypesAllowHouseHere(TileIndex t)
Checks whether at least one surrounding road allows to build a house here.
static bool CheckFree2x2Area(TileIndex tile, int z, bool noslope)
Checks if a house of size 2x2 can be built at this tile.
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.
void ChangeTownRating(Town *t, int add, int max, DoCommandFlags flags)
Changes town rating of the current company.
HouseZones GetClimateMaskForLandscape()
Get the HouseZones climate mask for the current landscape type.
static bool GrowTownAtRoad(Town *t, TileIndex tile, TownExpandModes modes)
Try to grow a town at a given road tile.
static void AddAcceptedCargo_Town(TileIndex tile, CargoArray &acceptance, CargoTypes &always_accepted)
Tile callback function signature for obtaining cargo acceptance of a tile.
Definition town_cmd.cpp:827
static CommandCost TownActionAdvertiseSmall(Town *t, DoCommandFlags flags)
Perform the "small advertising campaign" town action.
static CommandCost TerraformTile_Town(TileIndex tile, DoCommandFlags flags, int z_new, Slope tileh_new)
Tile callback function signature of the terraforming callback.
static CommandCost TownActionFundBuildings(Town *t, DoCommandFlags flags)
Perform the "fund new buildings" town action.
static bool IsTileAlignedToGrid(TileIndex tile, TownLayout layout)
Towns must all be placed on the same grid or when they eventually interpenetrate their road networks ...
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...
static CommandCost TownActionBribe(Town *t, DoCommandFlags flags)
Perform the "bribe" town action.
TileIndexDiff GetHouseNorthPart(HouseID &house)
Determines if a given HouseID is part of a multitile house.
static int GetRating(const Town *t)
Get the rating of a town for the _current_company.
uint GetDefaultTownsForMapSize()
Calculate the number of towns which should be on the map according to the current "town density" newg...
void ClearTownHouse(Town *t, TileIndex tile)
Clear a town house.
static uint GetNormalGrowthRate(Town *t)
Calculates town growth rate in normal conditions (custom growth rate not set).
TownActions GetMaskOfTownActions(CompanyID cid, const Town *t)
Get a list of available town authority actions.
static CommandCost TownActionBuyRights(Town *t, DoCommandFlags flags)
Perform the "buy exclusive transport rights" town action.
static bool GrowTownWithBridge(const Town *t, const TileIndex tile, const DiagDirection bridge_dir)
Grows the town with a bridge.
const CargoSpec * FindFirstCargoWithTownAcceptanceEffect(TownAcceptanceEffect effect)
Determines the first cargo with a certain town effect.
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.
Town * ClosestTownFromTile(TileIndex tile, uint threshold)
Return the town closest (in distance or ownership) to a given tile, within a given threshold.
static bool IsRoadAllowedHere(Town *t, TileIndex tile, DiagDirection dir)
Check if a Road is allowed on a given tile.
TownGrowthResult
The possible states of town growth.
@ Continue
The town hasn't grown yet, but try again.
@ Succeed
The town has grown.
@ SearchStopped
There is a reason not to try growing the town now.
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.
static bool TryBuildTownHouse(Town *t, TileIndex tile, TownExpandModes modes)
Tries to build a house at this tile.
static void UpdateTownGrowCounter(Town *t, uint16_t prev_growth_rate)
Updates town grow counter after growth rate change.
static int CountActiveStations(Town *t)
Calculates amount of active stations in the range of town (HZB_TOWN_EDGE).
static bool IsNeighbourRoadTile(TileIndex tile, const DiagDirection dir, uint dist_multi)
Check for parallel road inside a given distance.
static bool _generating_town
Set if a town is being generated.
Definition town_cmd.cpp:89
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.
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.
static void TileLoop_Town(TileIndex tile)
Tile callback function signature for running periodic tile updates.
Definition town_cmd.cpp:587
static bool CanBuildHouseHere(TileIndex tile, bool noslope)
Check if a house can be built here, based on slope, whether there's a bridge above,...
static void AddProducedCargo_Town(TileIndex tile, CargoArray &produced)
Tile callback function signature for obtaining the produced cargo of a tile.
Definition town_cmd.cpp:730
static bool TownLayoutAllowsHouseHere(Town *t, TileIndex tile, TownExpandModes modes)
Checks if the current town layout allows building here.
bool GenerateTowns(TownLayout layout, std::optional< uint > number)
Generate a number of towns with a given layout.
static bool GrowTownWithRoad(const Town *t, TileIndex tile, RoadBits rcmd)
Grows the town with a road piece.
CommandCost CmdDoTownAction(DoCommandFlags flags, TownID town_id, TownAction action)
Do a town action.
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:569
static void UpdateTownRating(Town *t)
Monthly callback to update town and station ratings.
static bool TownLayoutAllows2x2HouseHere(Town *t, TileIndex tile, TownExpandModes modes)
Checks if the current town layout allows a 2x2 building here.
static void AdvanceHouseConstruction(TileIndex tile)
Increase the construction stage of a house.
Definition town_cmd.cpp:506
static bool TownCanGrowRoad(TileIndex tile)
Test if town can grow road onto a specific tile.
uint32_t GetWorldPopulation()
Get the total population, the sum of all towns in the world.
Definition town_cmd.cpp:447
static bool GrowTownWithTunnel(const Town *t, const TileIndex tile, const DiagDirection tunnel_dir)
Grows the town with a tunnel.
static std::map< const Town *, int > _town_test_ratings
Map of towns to modified ratings, while in town rating test-mode.
static CommandCost ClearTile_Town(TileIndex tile, DoCommandFlags flags)
Tile callback function signature for clearing a tile.
Definition town_cmd.cpp:695
static bool CheckClearTile(TileIndex tile)
Check whether the land can be cleared.
static CommandCost TownActionAdvertiseMedium(Town *t, DoCommandFlags flags)
Perform the "medium advertising campaign" town action.
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:549
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.
void UpdateTownMaxPass(Town *t)
Update the maximum amount of monthly passengers and mail for a town, based on its population.
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:432
Town::SuppliedHistory SumHistory(std::span< const Town::SuppliedHistory > history)
Sum history for town supplied cargo.
CargoArray GetAcceptedCargoOfHouse(const HouseSpec *hs)
Get accepted cargo of a house prototype.
Definition town_cmd.cpp:838
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:768
static DiagDirection RandomDiagDir()
Return a random direction.
Definition town_cmd.cpp:257
static TileIndex AlignTileToGrid(TileIndex tile, TownLayout layout)
Towns must all be placed on the same grid or when they eventually interpenetrate their road networks ...
static Town * CreateRandomTown(uint attempts, uint32_t townnameparts, TownSize size, bool city, TownLayout layout)
Create a random town somewhere in the world.
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:461
uint8_t GetTownActionCost(TownAction action)
Get cost factors for a TownAction.
static const IntervalTimer< TimerGameEconomy > _economy_towns_monthly({TimerGameEconomy::Trigger::Month, TimerGameEconomy::Priority::Town}, [](auto) { for(Town *t :Town::Iterate()) { if(t->road_build_months !=0) t->road_build_months--;if(t->fund_buildings_months !=0) t->fund_buildings_months--;if(t->exclusive_counter !=0) { if(--t->exclusive_counter==0) t->exclusivity=CompanyID::Invalid();} for(const Company *c :Company::Iterate()) { if(t->unwanted[c->index] > 0) t->unwanted[c->index]--;} UpdateValidHistory(t->valid_history, HISTORY_YEAR, TimerGameEconomy::month);for(auto &s :t->supplied) RotateHistory(s.history, t->valid_history, HISTORY_YEAR, TimerGameEconomy::month);for(auto &a :t->accepted) RotateHistory(a.history, t->valid_history, HISTORY_YEAR, TimerGameEconomy::month);for(auto &received :t->received) received.NewMonth();UpdateTownGrowth(t);UpdateTownRating(t);SetWindowDirty(WindowClass::TownView, t->index);} })
Economy monthly timer for towns.
CommandCost CmdTownSetText(DoCommandFlags flags, TownID town_id, const EncodedString &text)
Set a custom text in the Town window.
Town * CalcClosestTownFromTile(TileIndex tile, uint threshold)
Return the town closest to the given tile within threshold.
CommandCost CmdTownGrowthRate(DoCommandFlags flags, TownID town_id, uint16_t growth_rate)
Change the growth rate of the town.
static TownGrowthResult GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection target_dir, Town *t1, TownExpandModes modes)
Grows the given town.
static CommandCost TownActionRoadRebuild(Town *t, DoCommandFlags flags)
Perform the "local road reconstruction" town action.
void ClearAllTownCachedNames()
Clear the cached_name of all towns.
Definition town_cmd.cpp:420
CommandCost CmdDeleteTown(DoCommandFlags flags, TownID town_id)
Delete a town (scenario editor or worldgen only).
static Foundation GetFoundation_Town(TileIndex tile, Slope tileh)
Tile callback function signature for getting the foundation of a tile.
Definition town_cmd.cpp:305
static TimerGameCalendar::Date GetTownRoadTypeFirstIntroductionDate()
Get the calendar date of the earliest town-buildable road type.
Definition town_cmd.cpp:970
static void AnimateTile_Town(TileIndex tile)
Tile callback function signature for animating a tile.
Definition town_cmd.cpp:329
CommandCost CmdPlaceHouse(DoCommandFlags flags, TileIndex tile, HouseID house, bool is_protected, bool replace)
Place an individual house.
RoadType GetTownRoadType()
Get the road type that towns should build at this current moment.
Definition town_cmd.cpp:940
static RoadBits GetTownRoadBits(TileIndex tile)
Return the RoadBits of a tile, ignoring depot and bay road stops.
Definition town_cmd.cpp:928
CommandCost CmdRenameTown(DoCommandFlags flags, TownID town_id, const std::string &text)
Rename a town (server-only).
CommandCost CmdTownCargoGoal(DoCommandFlags flags, TownID town_id, TownAcceptanceEffect tae, uint32_t goal)
Change the cargo goal of a town.
static void GetTileDesc_Town(TileIndex tile, TileDesc &td)
Tile callback function signature for obtaining a tile description.
Definition town_cmd.cpp:847
static void DoCreateTown(Town *t, TileIndex tile, uint32_t townnameparts, TownSize size, bool city, TownLayout layout, bool manual)
Actually create a town.
CommandCost CheckforTownRating(DoCommandFlags flags, Town *t, TownRatingCheckType type)
Does the town authority allow the (destructive) action of the current company?
HouseZone GetTownRadiusGroup(const Town *t, TileIndex tile)
Returns the bit corresponding to the town zone of the specified tile.
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.
static CommandCost TownCanBePlacedHere(TileIndex tile, bool check_surrounding)
Check if it's possible to place a town on a given tile.
static bool TestTownOwnsBridge(TileIndex tile, const Town *t)
Check if a town 'owns' a bridge.
Definition town_cmd.cpp:100
void OnTick_Town()
Iterate through all towns and call their tick handler.
Definition town_cmd.cpp:914
static CommandCost TownActionAdvertiseLarge(Town *t, DoCommandFlags flags)
Perform the "large advertising campaign" town action.
bool CheckTownRoadTypes()
Check if towns are able to build road.
Definition town_cmd.cpp:990
static bool GrowTown(Town *t, TownExpandModes modes)
Grow the town.
static void UpdateTownGrowthRate(Town *t)
Updates town growth rate.
static RoadBits GetTownRoadGridElement(Town *t, TileIndex tile, DiagDirection dir)
Generate the RoadBits of a grid tile.
static void AdvanceSingleHouseConstruction(TileIndex tile)
Helper function for house construction stage progression.
Definition town_cmd.cpp:483
static void TownTickHandler(Town *t)
Handle the town tick for a single town, by growing the town if desired.
Definition town_cmd.cpp:895
void SetTownRatingTestMode(bool mode)
Switch the town rating to test-mode, to allow commands to be tested without affecting current ratings...
static bool _town_rating_test
If true, town rating is in test-mode.
CommandCost CmdTownRating(DoCommandFlags flags, TownID town_id, CompanyID company_id, int16_t rating)
Change the rating of a company in a town.
void UpdateTownRadius(Town *t)
Update the cached town zone radii of a town, based on the number of houses.
static bool GrowTownWithExtraHouse(Town *t, TileIndex tile, TownExpandModes modes)
Grows the town with an extra house.
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:784
static bool TownAllowedToBuildRoads(TownExpandModes modes)
Check if the town is allowed to build roads.
CommandCost CmdExpandTown(DoCommandFlags flags, TownID town_id, uint32_t grow_amount, TownExpandModes modes)
Expand a town (scenario editor only).
static bool IsCloseToTown(TileIndex tile, uint dist)
Determines if a town is close to a tile.
Definition town_cmd.cpp:380
static void UpdateTownGrowth(Town *t)
Updates town growth state (whether it is growing or not).
static void DoClearTownHouseHelper(TileIndex tile, Town *t, HouseID house)
Update data structures when a house is removed.
static RoadBits GenRandomRoadBits()
Generate a random road block.
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.
CommandCost CheckIfAuthorityAllowsNewStation(TileIndex tile, DoCommandFlags flags)
Checks whether the local authority allows construction of a new station (rail, road,...
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.
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.
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:523
static bool IsUniqueTownName(const std::string &name)
Verifies this custom name is unique.
static void DrawTile_Town(TileInfo *ti)
Tile callback function signature for drawing a tile and its contents to the screen.
Definition town_cmd.cpp:263
void UpdateAllTownVirtCoords()
Update the virtual coords needed to draw the town sign for all towns.
Definition town_cmd.cpp:412
CommandCost CmdPlaceHouseArea(DoCommandFlags flags, TileIndex tile, TileIndex start_tile, HouseID house, bool is_protected, bool replace, bool diagonal)
Construct multiple houses in an area.
Command definitions related to towns.
Declarations for accessing the k-d tree of towns.
Sprites to use and how to display them for town tiles.
static const DrawBuildingsTileStruct _town_draw_tile_data[]
structure of houses graphics
Definition town_land.h:27
void IncrementHouseAge(Tile t)
Increments the age of the house.
Definition town_map.h:259
void HaltLift(Tile t)
Stop the lift of this animated house from moving.
Definition town_map.h:137
HouseID GetHouseType(Tile t)
Get the type of this house, which is an index into the house spec array.
Definition town_map.h:60
void ResetHouseAge(Tile t)
Sets the age of the house to zero.
Definition town_map.h:248
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
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
uint8_t GetLiftPosition(Tile t)
Get the position of the lift on this animated house.
Definition town_map.h:147
bool IsHousePlayerProtected(Tile t)
Check if a house is protected by a player from removal by towns.
Definition town_map.h:82
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
TimerGameCalendar::Year GetHouseAge(Tile t)
Get the age of the house.
Definition town_map.h:271
void SetLiftPosition(Tile t, uint8_t pos)
Set the position of the lift on this animated house.
Definition town_map.h:157
uint8_t GetLiftDestination(Tile t)
Get the current destination for this lift.
Definition town_map.h:126
uint8_t GetHouseBuildingStage(Tile t)
House Construction Scheme.
Definition town_map.h:205
TownID GetTownIndex(Tile t)
Get the index of which town this house/street is attached to.
Definition town_map.h:23
void SetTownIndex(Tile t, TownID index)
Set the town index for a road or house tile.
Definition town_map.h:35
bool LiftHasDestination(Tile t)
Check if the lift of this animated house has a destination.
Definition town_map.h:104
bool IsHouseCompleted(Tile t)
Get the completion of this house.
Definition town_map.h:167
uint8_t GetHouseConstructionTick(Tile t)
Gets the construction stage of a house.
Definition town_map.h:217
static constexpr int RATING_GROWTH_UP_STEP
when a town grows, all companies have rating increased a bit ...
Definition town_type.h:52
static constexpr int RATING_INITIAL
initial rating
Definition town_type.h:44
static constexpr int RATING_ROAD_NEEDED_HOSTILE
"Hostile"
Definition town_type.h:70
@ Original
Original algorithm (quadratic cargo by population).
Definition town_type.h:112
@ Bitcount
Bit-counted algorithm (normal distribution from individual house population).
Definition town_type.h:113
static constexpr int RATING_ROAD_NEEDED_NEUTRAL
"Neutral"
Definition town_type.h:69
TownLayout
Town Layouts.
Definition town_type.h:83
@ Original
Original algorithm (min. 1 distance between roads).
Definition town_type.h:84
@ Random
Random town layout.
Definition town_type.h:89
@ BetterRoads
Extended original algorithm (min. 2 distance between roads).
Definition town_type.h:85
@ End
Number of town layouts.
Definition town_type.h:91
@ Grid2x2
Geometric 2x2 grid algorithm.
Definition town_type.h:86
@ Grid3x3
Geometric 3x3 grid algorithm.
Definition town_type.h:87
static constexpr int RATING_TUNNEL_BRIDGE_NEEDED_LENIENT
rating needed, "Lenient" difficulty settings
Definition town_type.h:60
@ CustomLayout
Allowed, with custom town layout.
Definition town_type.h:107
@ Forbidden
Forbidden.
Definition town_type.h:105
static constexpr int RATING_TUNNEL_BRIDGE_NEEDED_HOSTILE
"Hostile"
Definition town_type.h:62
static constexpr int RATING_TUNNEL_BRIDGE_NEEDED_PERMISSIVE
"Permissive" (local authority disabled)
Definition town_type.h:63
static constexpr int RATING_STATION_DOWN_STEP
... but loses for badly serviced stations
Definition town_type.h:55
static constexpr int RATING_TUNNEL_BRIDGE_NEEDED_NEUTRAL
"Neutral"
Definition town_type.h:61
static constexpr int RATING_ROAD_NEEDED_LENIENT
rating needed, "Lenient" difficulty settings
Definition town_type.h:68
static constexpr int RATING_STATION_UP_STEP
when a town grows, company gains reputation for all well serviced stations ...
Definition town_type.h:54
TownSize
Supported initial town sizes.
Definition town_type.h:21
@ Large
Large town.
Definition town_type.h:24
@ Random
Random size, bigger than small, smaller than large.
Definition town_type.h:25
@ End
Number of available town sizes.
Definition town_type.h:27
static const uint MAX_LENGTH_TOWN_NAME_CHARS
The maximum length of a town name in characters including '\0'.
Definition town_type.h:116
@ Roads
Allow town to place roads.
Definition town_type.h:97
@ Buildings
Allow town to place buildings.
Definition town_type.h:96
EnumBitSet< TownExpandMode, uint8_t > TownExpandModes
Bitset of TownExpandMode elements.
Definition town_type.h:101
static constexpr int RATING_ROAD_NEEDED_PERMISSIVE
"Permissive" (local authority disabled)
Definition town_type.h:71
static constexpr int RATING_GROWTH_MAXIMUM
... up to RATING_MEDIOCRE
Definition town_type.h:53
bool VerifyTownName(uint32_t r, const TownNameParams *par, TownNames *town_names)
Verifies the town name is valid and unique.
Definition townname.cpp:103
bool GenerateTownName(Randomizer &randomizer, uint32_t *townnameparts, TownNames *town_names)
Generates valid town name.
Definition townname.cpp:136
Town name generator stuff.
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...
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...
@ Houses
town buildings
@ Road
Transport by road vehicle.
Map accessors for tree tiles.
TreeGround GetTreeGround(Tile t)
Returns the groundtype for tree tiles.
Definition tree_map.h:102
@ Rough
Rough land.
Definition tree_map.h:54
Command definitions related to tunnels and bridges.
Functions that have tunnels and bridges in common.
DiagDirection GetTunnelBridgeDirection(Tile t)
Get the direction pointing to the other end.
TransportType GetTunnelBridgeTransportType(Tile t)
Tunnel: Get the transport type of the tunnel (road or rail) Bridge: Get the transport type of the bri...
TileIndex GetOtherTunnelBridgeEnd(Tile t)
Determines type of the wormhole and returns its other end.
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:664
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:826
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
Functions related to (drawing on) viewports.
Declarations for accessing the k-d tree of viewports.
bool HasTileWaterGround(Tile t)
Checks whether the tile has water at the ground.
Definition water_map.h:353
bool IsWaterTile(Tile t)
Is it a water tile with plain water?
Definition water_map.h:192
bool IsSea(Tile t)
Is it a sea water tile?
Definition water_map.h:160
Base of waypoints.
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:1204
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting).
Definition window.cpp:3226
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:3318
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting).
Definition window.cpp:3196
Window functions not directly related to making/drawing windows.