OpenTTD Source 20260512-master-g20b387b91f
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 "timer/timer.h"
65
66#include "table/strings.h"
67#include "table/town_land.h"
68
69#include "safeguards.h"
70
71/* Initialize the town-pool */
72TownPool _town_pool("Town");
74
75
76TownKdtree _town_kdtree{};
77
78void RebuildTownKdtree()
79{
80 std::vector<TownID> townids;
81 for (const Town *town : Town::Iterate()) {
82 townids.push_back(town->index);
83 }
84 _town_kdtree.Build(townids.begin(), townids.end());
85}
86
88static bool _generating_town = false;
89
99static bool TestTownOwnsBridge(TileIndex tile, const Town *t)
100{
101 if (!IsTileOwner(tile, OWNER_TOWN)) return false;
102
104 bool town_owned = IsTileType(adjacent, TileType::Road) && IsTileOwner(adjacent, OWNER_TOWN) && GetTownIndex(adjacent) == t->index;
105
106 if (!town_owned) {
107 /* Or other adjacent road */
109 town_owned = IsTileType(adjacent, TileType::Road) && IsTileOwner(adjacent, OWNER_TOWN) && GetTownIndex(adjacent) == t->index;
110 }
111
112 return town_owned;
113}
114
116{
117 if (CleaningPool()) return;
118
119 /* Delete town authority window
120 * and remove from list of sorted towns */
123
124#ifdef WITH_ASSERT
125 /* Check no industry is related to us. */
126 for (const Industry *i : Industry::Iterate()) {
127 assert(i->town != this);
128 }
129
130 /* ... and no object is related to us. */
131 for (const Object *o : Object::Iterate()) {
132 assert(o->town != this);
133 }
134
135 /* Check no tile is related to us. */
136 for (const auto tile : Map::Iterate()) {
137 switch (GetTileType(tile)) {
138 case TileType::House:
139 assert(GetTownIndex(tile) != this->index);
140 break;
141
142 case TileType::Road:
143 assert(!HasTownOwnedRoad(tile) || GetTownIndex(tile) != this->index);
144 break;
145
147 assert(!TestTownOwnsBridge(tile, this));
148 break;
149
150 default:
151 break;
152 }
153 }
154#endif /* WITH_ASSERT */
155
156 /* Clear the persistent storage list. */
157 for (auto &psa : this->psa_list) {
158 delete psa;
159 }
160 this->psa_list.clear();
161
162 Source src{this->index, SourceType::Town};
167}
168
169
175void Town::PostDestructor([[maybe_unused]] size_t index)
176{
177 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_REBUILD);
179
180 /* Give objects a new home! */
181 for (Object *o : Object::Iterate()) {
182 if (o->town == nullptr) o->town = CalcClosestTownFromTile(o->location.tile, UINT_MAX);
183 }
184}
185
191{
192 if (layout != TL_RANDOM) {
193 this->layout = layout;
194 return;
195 }
196
197 this->layout = static_cast<TownLayout>(TileHash(TileX(this->xy), TileY(this->xy)) % (NUM_TLS - 1));
198}
199
204/* static */ Town *Town::GetRandom()
205{
206 if (Town::GetNumItems() == 0) return nullptr;
207 int num = RandomRange((uint16_t)Town::GetNumItems());
208 size_t index = std::numeric_limits<size_t>::max();
209
210 while (num >= 0) {
211 num--;
212 index++;
213
214 /* Make sure we have a valid town */
215 while (!Town::IsValidID(index)) {
216 index++;
217 assert(index < Town::GetPoolSize());
218 }
219 }
220
221 return Town::Get(index);
222}
223
224void Town::FillCachedName() const
225{
226 this->cached_name = GetTownName(this);
227}
228
234{
235 return (_price[Price::ClearHouse] * this->removal_cost) >> 8;
236}
237
238static bool TryBuildTownHouse(Town *t, TileIndex tile, TownExpandModes modes);
239static Town *CreateRandomTown(uint attempts, uint32_t townnameparts, TownSize size, bool city, TownLayout layout);
240
241static void TownDrawHouseLift(const TileInfo *ti)
242{
243 AddChildSpriteScreen(SPR_LIFT, PAL_NONE, 14, 60 - GetLiftPosition(ti->tile));
244}
245
246typedef void TownDrawTileProc(const TileInfo *ti);
247static TownDrawTileProc * const _town_draw_tile_procs[1] = {
248 TownDrawHouseLift
249};
250
257{
259}
260
262static void DrawTile_Town(TileInfo *ti)
263{
264 HouseID house_id = GetHouseType(ti->tile);
265
266 if (house_id >= NEW_HOUSE_OFFSET) {
267 /* Houses don't necessarily need new graphics. If they don't have a
268 * spritegroup associated with them, then the sprite for the substitute
269 * house id is drawn instead. */
270 if (HouseSpec::Get(house_id)->grf_prop.HasSpriteGroups()) {
271 DrawNewHouseTile(ti, house_id);
272 return;
273 } else {
274 house_id = HouseSpec::Get(house_id)->grf_prop.subst_id;
275 }
276 }
277
278 /* Retrieve pointer to the draw town tile struct */
279 const DrawBuildingsTileStruct *dcts = &_town_draw_tile_data[house_id << 4 | TileHash2Bit(ti->x, ti->y) << 2 | GetHouseBuildingStage(ti->tile)];
280
282
283 DrawGroundSprite(dcts->ground.sprite, dcts->ground.pal);
284
285 /* If houses are invisible, do not draw the upper part */
286 if (IsInvisibilitySet(TO_HOUSES)) return;
287
288 /* Add a house on top of the ground? */
289 SpriteID image = dcts->building.sprite;
290 if (image != 0) {
291 AddSortableSpriteToDraw(image, dcts->building.pal, *ti, *dcts, IsTransparencySet(TO_HOUSES));
292
293 if (IsTransparencySet(TO_HOUSES)) return;
294 }
295
296 {
297 int proc = dcts->draw_proc - 1;
298
299 if (proc >= 0) _town_draw_tile_procs[proc](ti);
300 }
301}
302
305{
306 HouseID hid = GetHouseType(tile);
307
308 /* For NewGRF house tiles we might not be drawing a foundation. We need to
309 * account for this, as other structures should
310 * draw the wall of the foundation in this case.
311 */
312 if (hid >= NEW_HOUSE_OFFSET) {
313 const HouseSpec *hs = HouseSpec::Get(hid);
315 uint32_t callback_res = GetHouseCallback(CBID_HOUSE_DRAW_FOUNDATIONS, 0, 0, hid, Town::GetByTile(tile), tile);
316 if (callback_res != CALLBACK_FAILED && !ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DRAW_FOUNDATIONS, callback_res)) return FOUNDATION_NONE;
317 }
318 }
319 return FlatteningFoundation(tileh);
320}
321
329{
330 if (GetHouseType(tile) >= NEW_HOUSE_OFFSET) {
331 AnimateNewHouseTile(tile);
332 return;
333 }
334
335 if (TimerGameTick::counter & 3) return;
336
337 /* If the house is not one with a lift anymore, then stop this animating.
338 * Not exactly sure when this happens, but probably when a house changes.
339 * Before this was just a return...so it'd leak animated tiles..
340 * That bug seems to have been here since day 1?? */
341 if (!HouseSpec::Get(GetHouseType(tile))->building_flags.Test(BuildingFlag::IsAnimated)) {
342 DeleteAnimatedTile(tile);
343 return;
344 }
345
346 if (!LiftHasDestination(tile)) {
347 uint i;
348
349 /* Building has 6 floors, number 0 .. 6, where 1 is illegal.
350 * This is due to the fact that the first floor is, in the graphics,
351 * the height of 2 'normal' floors.
352 * Furthermore, there are 6 lift positions from floor N (incl) to floor N + 1 (excl) */
353 do {
354 i = RandomRange(7);
355 } while (i == 1 || i * 6 == GetLiftPosition(tile));
356
357 SetLiftDestination(tile, i);
358 }
359
360 int pos = GetLiftPosition(tile);
361 int dest = GetLiftDestination(tile) * 6;
362 pos += (pos < dest) ? 1 : -1;
363 SetLiftPosition(tile, pos);
364
365 if (pos == dest) {
366 HaltLift(tile);
367 DeleteAnimatedTile(tile);
368 }
369
371}
372
379static bool IsCloseToTown(TileIndex tile, uint dist)
380{
381 if (_town_kdtree.Count() == 0) return false;
382 Town *t = Town::Get(_town_kdtree.FindNearest(TileX(tile), TileY(tile)));
383 return DistanceManhattan(tile, t->xy) < dist;
384}
385
388{
389 Point pt = RemapCoords2(TileX(this->xy) * TILE_SIZE, TileY(this->xy) * TILE_SIZE);
390
391 if (this->cache.sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeTown(this->index));
392
393 std::string town_string;
394 if (this->larger_town) {
395 town_string = GetString(_settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_CITY_POP : STR_VIEWPORT_TOWN_CITY, this->index, this->cache.population);
396 } else {
397 town_string = GetString(_settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_POP : STR_TOWN_NAME, this->index, this->cache.population);
398 }
399
400 this->cache.sign.UpdatePosition(pt.x, pt.y - 24 * ZOOM_BASE,
401 town_string,
402 GetString(STR_TOWN_NAME, this->index, this->cache.population)
403);
404
405 _viewport_sign_kdtree.Insert(ViewportSignKdtreeItem::MakeTown(this->index));
406
408}
409
412{
413 for (Town *t : Town::Iterate()) {
414 t->UpdateVirtCoord();
415 }
416}
417
420{
421 for (Town *t : Town::Iterate()) {
422 t->cached_name.clear();
423 }
424}
425
431static void ChangePopulation(Town *t, int mod)
432{
433 t->cache.population += mod;
434 if (_generating_town) [[unlikely]] return;
435
436 InvalidateWindowData(WC_TOWN_VIEW, t->index); // Cargo requirements may appear/vanish for small populations
437 if (_settings_client.gui.population_in_label) t->UpdateVirtCoord();
438
439 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_POPULATION_CHANGE);
440}
441
447{
448 uint32_t pop = 0;
449 for (const Town *t : Town::Iterate()) pop += t->cache.population;
450 return pop;
451}
452
460static void RemoveNearbyStations(Town *t, TileIndex tile, BuildingFlags flags)
461{
462 for (StationList::iterator it = t->stations_near.begin(); it != t->stations_near.end(); /* incremented inside loop */) {
463 const Station *st = *it;
464
465 bool covers_area = st->TileIsInCatchment(tile);
466 if (flags.Any(BUILDING_2_TILES_Y)) covers_area |= st->TileIsInCatchment(tile + TileDiffXY(0, 1));
467 if (flags.Any(BUILDING_2_TILES_X)) covers_area |= st->TileIsInCatchment(tile + TileDiffXY(1, 0));
468 if (flags.Any(BUILDING_HAS_4_TILES)) covers_area |= st->TileIsInCatchment(tile + TileDiffXY(1, 1));
469
470 if (covers_area && !st->CatchmentCoversTown(t->index)) {
471 it = t->stations_near.erase(it);
472 } else {
473 ++it;
474 }
475 }
476}
477
483{
484 assert(IsTileType(tile, TileType::House));
485
486 /* Progress in construction stages */
488 if (GetHouseConstructionTick(tile) != 0) return;
489
490 TriggerHouseAnimation_ConstructionStageChanged(tile, false);
491
492 if (IsHouseCompleted(tile)) {
493 /* Now that construction is complete, we can add the population of the
494 * building to the town. */
495 ChangePopulation(Town::GetByTile(tile), HouseSpec::Get(GetHouseType(tile))->population);
496 ResetHouseAge(tile);
497 }
499}
500
506{
507 BuildingFlags flags = HouseSpec::Get(GetHouseType(tile))->building_flags;
508 if (flags.Any(BUILDING_HAS_1_TILE)) AdvanceSingleHouseConstruction(TileAddXY(tile, 0, 0));
509 if (flags.Any(BUILDING_2_TILES_Y)) AdvanceSingleHouseConstruction(TileAddXY(tile, 0, 1));
510 if (flags.Any(BUILDING_2_TILES_X)) AdvanceSingleHouseConstruction(TileAddXY(tile, 1, 0));
511 if (flags.Any(BUILDING_HAS_4_TILES)) AdvanceSingleHouseConstruction(TileAddXY(tile, 1, 1));
512}
513
522static void TownGenerateCargo(Town *t, CargoType cargo, uint amount, StationFinder &stations, bool affected_by_recession)
523{
524 if (amount == 0) return;
525
526 /* All production is halved during a recession (except for NewGRF-supplied town cargo). */
527 if (affected_by_recession && EconomyIsInRecession()) {
528 amount = (amount + 1) >> 1;
529 }
530
531 /* Scale by cargo scale setting. */
532 amount = ScaleByCargoScale(amount, true);
533 if (amount == 0) return;
534
535 /* Actually generate cargo and update town statistics. */
536 auto &supplied = t->GetOrCreateCargoSupplied(cargo);
537 supplied.history[THIS_MONTH].production += amount;
538 supplied.history[THIS_MONTH].transported += MoveGoodsToStation(cargo, amount, {t->index, SourceType::Town}, stations.GetStations());;
539}
540
548static void TownGenerateCargoOriginal(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
549{
550 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[tpe]) {
551 uint32_t r = Random();
552 if (GB(r, 0, 8) < rate) {
553 CargoType cargo_type = cs->Index();
554 uint amt = (GB(r, 0, 8) * cs->town_production_multiplier / TOWN_PRODUCTION_DIVISOR) / 8 + 1;
555
556 TownGenerateCargo(t, cargo_type, amt, stations, true);
557 }
558 }
559}
560
568static void TownGenerateCargoBinomial(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
569{
570 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[tpe]) {
571 CargoType cargo_type = cs->Index();
572 uint32_t r = Random();
573
574 /* Make a bitmask with up to 32 bits set, one for each potential pax. */
575 int genmax = (rate + 7) / 8;
576 uint32_t genmask = (genmax >= 32) ? 0xFFFFFFFF : ((1 << genmax) - 1);
577
578 /* Mask random value by potential pax and count number of actual pax. */
579 uint amt = CountBits(r & genmask) * cs->town_production_multiplier / TOWN_PRODUCTION_DIVISOR;
580
581 TownGenerateCargo(t, cargo_type, amt, stations, true);
582 }
583}
584
586static void TileLoop_Town(TileIndex tile)
587{
588 HouseID house_id = GetHouseType(tile);
589
590 /* NewHouseTileLoop returns false if Callback 21 succeeded, i.e. the house
591 * doesn't exist any more, so don't continue here. */
592 if (house_id >= NEW_HOUSE_OFFSET && !NewHouseTileLoop(tile)) return;
593
594 if (!IsHouseCompleted(tile)) {
595 /* Construction is not completed, so we advance a construction stage. */
597 return;
598 }
599
600 const HouseSpec *hs = HouseSpec::Get(house_id);
601
602 /* If the lift has a destination, it is already an animated tile. */
604 house_id < NEW_HOUSE_OFFSET &&
605 !LiftHasDestination(tile) &&
606 Chance16(1, 2)) {
607 AddAnimatedTile(tile);
608 }
609
610 Town *t = Town::GetByTile(tile);
611 uint32_t r = Random();
612
613 StationFinder stations(TileArea(tile, 1, 1));
614
616 for (uint i = 0; i < 256; i++) {
617 uint16_t callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, r, house_id, t, tile);
618
619 if (callback == CALLBACK_FAILED || callback == CALLBACK_HOUSEPRODCARGO_END) break;
620
621 CargoType cargo = GetCargoTranslation(GB(callback, 8, 7), hs->grf_prop.grffile);
622 if (!IsValidCargoType(cargo)) continue;
623
624 uint amt = GB(callback, 0, 8);
625 if (amt == 0) continue;
626
627 /* NewGRF-supplied town cargos are not affected by recessions. */
628 TownGenerateCargo(t, cargo, amt, stations, false);
629 }
630 } else {
631 switch (_settings_game.economy.town_cargogen_mode) {
632 case TCGM_ORIGINAL:
633 /* Original (quadratic) cargo generation algorithm */
636 break;
637
638 case TCGM_BITCOUNT:
639 /* Binomial distribution per tick, by a series of coin flips */
640 /* Reduce generation rate to a 1/4, using tile bits to spread out distribution.
641 * As tick counter is incremented by 256 between each call, we ignore the lower 8 bits. */
642 if (GB(TimerGameTick::counter, 8, 2) == GB(tile.base(), 0, 2)) {
645 }
646 break;
647
648 default:
649 NOT_REACHED();
650 }
651 }
652
654
655 if (hs->building_flags.Any(BUILDING_HAS_1_TILE) &&
657 CanDeleteHouse(tile) &&
658 GetHouseAge(tile) >= hs->minimum_life &&
659 --t->time_until_rebuild == 0) {
660 t->time_until_rebuild = GB(r, 16, 8) + 192;
661
662 ClearTownHouse(t, tile);
663
664 /* Rebuild with another house? */
665 if (GB(r, 24, 8) >= 12) {
666 /* If we are multi-tile houses, make sure to replace the house
667 * closest to city center. If we do not do this, houses tend to
668 * wander away from roads and other houses. */
669 if (hs->building_flags.Any(BUILDING_HAS_2_TILES)) {
670 /* House tiles are always the most north tile. Move the new
671 * house to the south if we are north of the city center. */
672 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
673 int x = Clamp(grid_pos.x, 0, 1);
674 int y = Clamp(grid_pos.y, 0, 1);
675
677 tile = TileAddXY(tile, x, y);
678 } else if (hs->building_flags.Test(BuildingFlag::Size1x2)) {
679 tile = TileAddXY(tile, 0, y);
680 } else if (hs->building_flags.Test(BuildingFlag::Size2x1)) {
681 tile = TileAddXY(tile, x, 0);
682 }
683 }
684
685 TownExpandModes modes{TownExpandMode::Buildings};
686 if (_settings_game.economy.allow_town_roads) modes.Set(TownExpandMode::Roads);
687
688 TryBuildTownHouse(t, tile, modes);
689 }
690 }
691}
692
694static CommandCost ClearTile_Town(TileIndex tile, DoCommandFlags flags)
695{
696 if (flags.Test(DoCommandFlag::Auto)) return CommandCost(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
697 if (!CanDeleteHouse(tile)) return CommandCost(STR_ERROR_BUILDING_IS_PROTECTED);
698
699 const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
700
702 cost.AddCost(hs->GetRemovalCost());
703
704 int rating = hs->remove_rating_decrease;
705 Town *t = Town::GetByTile(tile);
706
708 if (!_cheats.magic_bulldozer.value && !flags.Test(DoCommandFlag::NoTestTownRating)) {
709 /* NewGRFs can add indestructible houses. */
710 if (rating > RATING_MAXIMUM) {
711 return CommandCost(STR_ERROR_BUILDING_IS_PROTECTED);
712 }
713 /* If town authority controls removal, check the company's rating. */
714 if (rating > t->ratings[_current_company] && _settings_game.difficulty.town_council_tolerance != TOWN_COUNCIL_PERMISSIVE) {
715 return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index);
716 }
717 }
718 }
719
720 ChangeTownRating(t, -rating, RATING_HOUSE_MINIMUM, flags);
721 if (flags.Test(DoCommandFlag::Execute)) {
722 ClearTownHouse(t, tile);
723 }
724
725 return cost;
726}
727
729static void AddProducedCargo_Town(TileIndex tile, CargoArray &produced)
730{
731 HouseID house_id = GetHouseType(tile);
732 const HouseSpec *hs = HouseSpec::Get(house_id);
733 Town *t = Town::GetByTile(tile);
734
736 for (uint i = 0; i < 256; i++) {
737 uint16_t callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, 0, house_id, t, tile);
738
739 if (callback == CALLBACK_FAILED || callback == CALLBACK_HOUSEPRODCARGO_END) break;
740
741 CargoType cargo = GetCargoTranslation(GB(callback, 8, 7), hs->grf_prop.grffile);
742
743 if (!IsValidCargoType(cargo)) continue;
744 produced[cargo]++;
745 }
746 } else {
747 if (hs->population > 0) {
749 produced[cs->Index()]++;
750 }
751 }
752 if (hs->mail_generation > 0) {
754 produced[cs->Index()]++;
755 }
756 }
757 }
758}
759
767static void AddAcceptedCargoSetMask(CargoType cargo, uint amount, CargoArray &acceptance, CargoTypes &always_accepted)
768{
769 if (!IsValidCargoType(cargo) || amount == 0) return;
770 acceptance[cargo] += amount;
771 always_accepted.Set(cargo);
772}
773
783void AddAcceptedCargoOfHouse(TileIndex tile, HouseID house, const HouseSpec *hs, Town *t, CargoArray &acceptance, CargoTypes &always_accepted)
784{
785 CargoType accepts[lengthof(hs->accepts_cargo)];
786
787 /* Set the initial accepted cargo types */
788 for (uint8_t i = 0; i < lengthof(accepts); i++) {
789 accepts[i] = hs->accepts_cargo[i];
790 }
791
792 /* Check for custom accepted cargo types */
794 uint16_t callback = GetHouseCallback(CBID_HOUSE_ACCEPT_CARGO, 0, 0, house, t, tile, {}, tile == INVALID_TILE);
795 if (callback != CALLBACK_FAILED) {
796 /* Replace accepted cargo types with translated values from callback */
797 accepts[0] = GetCargoTranslation(GB(callback, 0, 5), hs->grf_prop.grffile);
798 accepts[1] = GetCargoTranslation(GB(callback, 5, 5), hs->grf_prop.grffile);
799 accepts[2] = GetCargoTranslation(GB(callback, 10, 5), hs->grf_prop.grffile);
800 }
801 }
802
803 /* Check for custom cargo acceptance */
805 uint16_t callback = GetHouseCallback(CBID_HOUSE_CARGO_ACCEPTANCE, 0, 0, house, t, tile, {}, tile == INVALID_TILE);
806 if (callback != CALLBACK_FAILED) {
807 AddAcceptedCargoSetMask(accepts[0], GB(callback, 0, 4), acceptance, always_accepted);
808 AddAcceptedCargoSetMask(accepts[1], GB(callback, 4, 4), acceptance, always_accepted);
809 if (_settings_game.game_creation.landscape != LandscapeType::Temperate && HasBit(callback, 12)) {
810 /* The 'S' bit indicates food instead of goods */
811 AddAcceptedCargoSetMask(GetCargoTypeByLabel(CT_FOOD), GB(callback, 8, 4), acceptance, always_accepted);
812 } else {
813 AddAcceptedCargoSetMask(accepts[2], GB(callback, 8, 4), acceptance, always_accepted);
814 }
815 return;
816 }
817 }
818
819 /* No custom acceptance, so fill in with the default values */
820 for (uint8_t i = 0; i < lengthof(accepts); i++) {
821 AddAcceptedCargoSetMask(accepts[i], hs->cargo_acceptance[i], acceptance, always_accepted);
822 }
823}
824
826static void AddAcceptedCargo_Town(TileIndex tile, CargoArray &acceptance, CargoTypes &always_accepted)
827{
828 HouseID house = GetHouseType(tile);
829 AddAcceptedCargoOfHouse(tile, house, HouseSpec::Get(house), Town::GetByTile(tile), acceptance, always_accepted);
830}
831
838{
839 CargoTypes always_accepted{};
840 CargoArray acceptance{};
841 AddAcceptedCargoOfHouse(INVALID_TILE, hs->Index(), hs, nullptr, acceptance, always_accepted);
842 return acceptance;
843}
844
846static void GetTileDesc_Town(TileIndex tile, TileDesc &td)
847{
848 const HouseID house = GetHouseType(tile);
849 const HouseSpec *hs = HouseSpec::Get(house);
850 bool house_completed = IsHouseCompleted(tile);
851
852 td.str = hs->building_name;
854
855 std::array<int32_t, 1> regs100;
856 uint16_t callback_res = GetHouseCallback(CBID_HOUSE_CUSTOM_NAME, house_completed ? 1 : 0, 0, house, Town::GetByTile(tile), tile, regs100);
857 if (callback_res != CALLBACK_FAILED && callback_res != 0x400) {
858 StringID new_name = STR_NULL;
859 if (callback_res == 0x40F) {
860 new_name = GetGRFStringID(hs->grf_prop.grfid, static_cast<GRFStringID>(regs100[0]));
861 } else if (callback_res > 0x400) {
863 } else {
864 new_name = GetGRFStringID(hs->grf_prop.grfid, GRFSTR_MISC_GRF_TEXT + callback_res);
865 }
866 if (new_name != STR_NULL && new_name != STR_UNDEFINED) {
867 td.str = new_name;
868 }
869 }
870
871 if (!house_completed) {
872 td.dparam = td.str;
873 td.str = STR_LAI_TOWN_INDUSTRY_DESCRIPTION_UNDER_CONSTRUCTION;
874 }
875
876 if (hs->grf_prop.HasGrfFile()) {
877 const GRFConfig *gc = GetGRFConfig(hs->grf_prop.grfid);
878 td.grf = gc->GetName();
879 }
880
881 td.owner[0] = OWNER_TOWN;
882}
883
884static bool GrowTown(Town *t, TownExpandModes modes);
885
890static void TownTickHandler(Town *t)
891{
893 TownExpandModes modes{TownExpandMode::Buildings};
894 if (_settings_game.economy.allow_town_roads) modes.Set(TownExpandMode::Roads);
895 int i = (int)t->grow_counter - 1;
896 if (i < 0) {
897 if (GrowTown(t, modes)) {
898 i = t->growth_rate;
899 } else {
900 /* If growth failed wait a bit before retrying */
901 i = std::min<uint16_t>(t->growth_rate, Ticks::TOWN_GROWTH_TICKS - 1);
902 }
903 }
904 t->grow_counter = i;
905 }
906}
907
910{
911 if (_game_mode == GM_EDITOR) return;
912
913 for (Town *t : Town::Iterate()) {
915 }
916}
917
924{
925 if (IsRoadDepotTile(tile) || IsBayRoadStopTile(tile)) return {};
926
927 return GetAnyRoadBits(tile, RoadTramType::Road, true);
928}
929
936{
937 RoadType best_rt = ROADTYPE_ROAD;
938 const RoadTypeInfo *best = nullptr;
939 const uint16_t assume_max_speed = 50;
940
942 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
943
944 /* Can town build this road. */
945 if (!rti->flags.Test(RoadTypeFlag::TownBuild)) continue;
946
947 /* Not yet introduced at this date. */
949
950 if (best != nullptr) {
951 if ((rti->max_speed == 0 ? assume_max_speed : rti->max_speed) < (best->max_speed == 0 ? assume_max_speed : best->max_speed)) continue;
952 }
953
954 best_rt = rt;
955 best = rti;
956 }
957
958 return best_rt;
959}
960
966{
967 const RoadTypeInfo *best = nullptr;
969 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
970
971 if (!rti->flags.Test(RoadTypeFlag::TownBuild)) continue; // Town can't build this road type.
972
973 if (best != nullptr && rti->introduction_date >= best->introduction_date) continue;
974 best = rti;
975 }
976
977 if (best == nullptr) return TimerGameCalendar::Date(INT32_MAX);
978 return best->introduction_date;
979}
980
986{
987 auto min_date = GetTownRoadTypeFirstIntroductionDate();
988 if (min_date <= TimerGameCalendar::date) return true;
989
990 if (min_date < INT32_MAX) {
992 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_YET),
993 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_YET_EXPLANATION, min_date),
995 } else {
997 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_AT_ALL),
998 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_AT_ALL_EXPLANATION), WL_CRITICAL);
999 }
1000 return false;
1001}
1002
1013static bool IsNeighbourRoadTile(TileIndex tile, const DiagDirection dir, uint dist_multi)
1014{
1015 if (!IsValidTile(tile)) return false;
1016
1017 /* Lookup table for the used diff values */
1018 const TileIndexDiff tid_lt[3] = {
1022 };
1023
1024 dist_multi = (dist_multi + 1) * 4;
1025 for (uint pos = 4; pos < dist_multi; pos++) {
1026 /* Go (pos / 4) tiles to the left or the right */
1027 TileIndexDiff cur = tid_lt[(pos & 1) ? 0 : 1] * (pos / 4);
1028
1029 /* Use the current tile as origin, or go one tile backwards */
1030 if (pos & 2) cur += tid_lt[2];
1031
1032 /* Test for roadbit parallel to dir and facing towards the middle axis */
1033 if (IsValidTile(tile + cur) &&
1034 GetTownRoadBits(TileAdd(tile, cur)).Any(DiagDirToRoadBits((pos & 2) ? dir : ReverseDiagDir(dir)))) return true;
1035 }
1036 return false;
1037}
1038
1048{
1049 if (DistanceFromEdge(tile) == 0) return false;
1050
1051 /* Prevent towns from building roads under bridges along the bridge. Looks silly. */
1052 if (IsBridgeAbove(tile) && GetBridgeAxis(tile) == DiagDirToAxis(dir)) return false;
1053
1054 /* Check if there already is a road at this point? */
1055 if (GetTownRoadBits(tile).None()) {
1056 /* No, try if we are able to build a road piece there.
1057 * If that fails clear the land, and if that fails exit.
1058 * This is to make sure that we can build a road here later. */
1060 if (Command<Commands::BuildRoad>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile, (dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? ROAD_Y : ROAD_X, rt, {}, t->index).Failed() &&
1061 Command<Commands::LandscapeClear>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile).Failed()) {
1062 return false;
1063 }
1064 }
1065
1066 Slope cur_slope = _settings_game.construction.build_on_slopes ? std::get<0>(GetFoundationSlope(tile)) : GetTileSlope(tile);
1067 bool ret = !IsNeighbourRoadTile(tile, dir, t->layout == TL_ORIGINAL ? 1 : 2);
1068 if (cur_slope == SLOPE_FLAT) return ret;
1069
1070 /* If the tile is not a slope in the right direction, then
1071 * maybe terraform some. */
1072 Slope desired_slope = (dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? SLOPE_NW : SLOPE_NE;
1073 if (desired_slope != cur_slope && ComplementSlope(desired_slope) != cur_slope) {
1074 if (Chance16(1, 8)) {
1075 CommandCost res = CMD_ERROR;
1076 if (!_generating_world && Chance16(1, 10)) {
1077 /* Note: Do not replace "^ SLOPE_ELEVATED" with ComplementSlope(). The slope might be steep. */
1078 res = std::get<0>(Command<Commands::TerraformLand>::Do({DoCommandFlag::Execute, DoCommandFlag::Auto, DoCommandFlag::NoWater},
1079 tile, Chance16(1, 16) ? cur_slope : cur_slope ^ SLOPE_ELEVATED, false));
1080 }
1081 if (res.Failed() && Chance16(1, 3)) {
1082 /* We can consider building on the slope, though. */
1083 return ret;
1084 }
1085 }
1086 return false;
1087 }
1088 return ret;
1089}
1090
1091static bool TerraformTownTile(TileIndex tile, Slope edges, bool dir)
1092{
1093 assert(tile < Map::Size());
1094
1095 CommandCost r = std::get<0>(Command<Commands::TerraformLand>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile, edges, dir));
1096 if (r.Failed() || r.GetCost() >= (_price[Price::Terraform] + 2) * 8) return false;
1097 Command<Commands::TerraformLand>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater, DoCommandFlag::Execute}, tile, edges, dir);
1098 return true;
1099}
1100
1101static void LevelTownLand(TileIndex tile)
1102{
1103 assert(tile < Map::Size());
1104
1105 /* Don't terraform if land is plain or if there's a house there. */
1106 if (IsTileType(tile, TileType::House)) return;
1107 Slope tileh = GetTileSlope(tile);
1108 if (tileh == SLOPE_FLAT) return;
1109
1110 /* First try up, then down */
1111 if (!TerraformTownTile(tile, ~tileh & SLOPE_ELEVATED, true)) {
1112 TerraformTownTile(tile, tileh & SLOPE_ELEVATED, false);
1113 }
1114}
1115
1125{
1126 /* align the grid to the downtown */
1127 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile); // Vector from downtown to the tile
1128 RoadBits rcmd{};
1129
1130 switch (t->layout) {
1131 default: NOT_REACHED();
1132
1133 case TL_2X2_GRID:
1134 if ((grid_pos.x % 3) == 0) rcmd.Set(ROAD_Y);
1135 if ((grid_pos.y % 3) == 0) rcmd.Set(ROAD_X);
1136 break;
1137
1138 case TL_3X3_GRID:
1139 if ((grid_pos.x % 4) == 0) rcmd.Set(ROAD_Y);
1140 if ((grid_pos.y % 4) == 0) rcmd.Set(ROAD_X);
1141 break;
1142 }
1143
1144 /* Optimise only X-junctions */
1145 if (rcmd != ROAD_ALL) return rcmd;
1146
1147 RoadBits rb_template;
1148
1149 switch (GetTileSlope(tile)) {
1150 default: rb_template = ROAD_ALL; break;
1151 case SLOPE_W: rb_template = {RoadBit::NW, RoadBit::SW}; break;
1152 case SLOPE_SW: rb_template = ROAD_Y | RoadBit::SW; break;
1153 case SLOPE_S: rb_template = {RoadBit::SW, RoadBit::SE}; break;
1154 case SLOPE_SE: rb_template = ROAD_X | RoadBit::SE; break;
1155 case SLOPE_E: rb_template = {RoadBit::SE, RoadBit::NE}; break;
1156 case SLOPE_NE: rb_template = ROAD_Y | RoadBit::NE; break;
1157 case SLOPE_N: rb_template = {RoadBit::NE, RoadBit::NW}; break;
1158 case SLOPE_NW: rb_template = ROAD_X | RoadBit::NW; break;
1159 case SLOPE_STEEP_W:
1160 case SLOPE_STEEP_S:
1161 case SLOPE_STEEP_E:
1162 case SLOPE_STEEP_N:
1163 rb_template = {};
1164 break;
1165 }
1166
1167 /* Stop if the template is compatible to the growth dir */
1168 if (DiagDirToRoadBits(ReverseDiagDir(dir)).Any(rb_template)) return rb_template;
1169 /* If not generate a straight road in the direction of the growth */
1171}
1172
1184static bool GrowTownWithExtraHouse(Town *t, TileIndex tile, TownExpandModes modes)
1185{
1186 /* We can't look further than that. */
1187 if (DistanceFromEdge(tile) == 0) return false;
1188
1189 uint counter = 0; // counts the house neighbour tiles
1190
1191 /* Check the tiles E,N,W and S of the current tile for houses */
1192 for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
1193 /* Count both void and house tiles for checking whether there
1194 * are enough houses in the area. This to make it likely that
1195 * houses get build up to the edge of the map. */
1196 switch (GetTileType(TileAddByDiagDir(tile, dir))) {
1197 case TileType::House:
1198 case TileType::Void:
1199 counter++;
1200 break;
1201
1202 default:
1203 break;
1204 }
1205
1206 /* If there are enough neighbours stop here */
1207 if (counter >= 3) {
1208 return TryBuildTownHouse(t, tile, modes);
1209 }
1210 }
1211 return false;
1212}
1213
1222static bool GrowTownWithRoad(const Town *t, TileIndex tile, RoadBits rcmd)
1223{
1225 return Command<Commands::BuildRoad>::Do({DoCommandFlag::Execute, DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile, rcmd, rt, {}, t->index).Succeeded();
1226}
1227
1237static bool CanRoadContinueIntoNextTile(const Town *t, const TileIndex tile, const DiagDirection road_dir)
1238{
1239 const TileIndexDiff delta = TileOffsByDiagDir(road_dir); // +1 tile in the direction of the road
1240 TileIndex next_tile = tile + delta; // The tile beyond which must be connectable to the target tile
1241 RoadBits rcmd = DiagDirToRoadBits(ReverseDiagDir(road_dir));
1243
1244 /* Before we try anything, make sure the tile is on the map and not the void. */
1245 if (!IsValidTile(next_tile)) return false;
1246
1247 /* If the next tile is a bridge or tunnel, allow if it's continuing in the same direction. */
1248 if (IsTileType(next_tile, TileType::TunnelBridge)) {
1249 return GetTunnelBridgeTransportType(next_tile) == TRANSPORT_ROAD && GetTunnelBridgeDirection(next_tile) == road_dir;
1250 }
1251
1252 /* If the next tile is a station, allow if it's a road station facing the proper direction. Otherwise return false. */
1253 if (IsTileType(next_tile, TileType::Station)) {
1254 /* If the next tile is a road station, allow if it can be entered by the new tunnel/bridge, otherwise disallow. */
1255 if (IsDriveThroughStopTile(next_tile)) return GetDriveThroughStopAxis(next_tile) == DiagDirToAxis(road_dir);
1256 if (IsBayRoadStopTile(next_tile)) return GetBayRoadStopDir(next_tile) == ReverseDiagDir(road_dir);
1257 return false;
1258 }
1259
1260 /* If the next tile is a road depot, allow if it's facing the right way. */
1261 if (IsTileType(next_tile, TileType::Road)) {
1262 return IsRoadDepot(next_tile) && GetRoadDepotDirection(next_tile) == ReverseDiagDir(road_dir);
1263 }
1264
1265 /* If the next tile is a railroad track, check if towns are allowed to build level crossings.
1266 * If level crossing are not allowed, reject the construction. Else allow DoCommand to determine if the rail track is buildable. */
1267 if (IsTileType(next_tile, TileType::Railway) && !_settings_game.economy.allow_town_level_crossings) return false;
1268
1269 /* If a road tile can be built, the construction is allowed. */
1270 return Command<Commands::BuildRoad>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, next_tile, rcmd, rt, {}, t->index).Succeeded();
1271}
1272
1283static bool GrowTownWithBridge(const Town *t, const TileIndex tile, const DiagDirection bridge_dir)
1284{
1285 assert(bridge_dir < DIAGDIR_END);
1286
1287 const Slope slope = GetTileSlope(tile);
1288
1289 /* Make sure the direction is compatible with the slope.
1290 * Well we check if the slope has an up bit set in the
1291 * reverse direction. */
1292 if (slope != SLOPE_FLAT && slope & InclinedSlope(bridge_dir)) return false;
1293
1294 /* Assure that the bridge is connectable to the start side */
1295 if (!GetTownRoadBits(TileAddByDiagDir(tile, ReverseDiagDir(bridge_dir))).Any(DiagDirToRoadBits(bridge_dir))) return false;
1296
1297 /* We are in the right direction */
1298 uint bridge_length = 0; // This value stores the length of the possible bridge
1299 TileIndex bridge_tile = tile; // Used to store the other waterside
1300
1301 const TileIndexDiff delta = TileOffsByDiagDir(bridge_dir);
1302
1303 /* To prevent really small towns from building disproportionately
1304 * long bridges, make the max a function of its population. */
1305 const uint TOWN_BRIDGE_LENGTH_CAP = 11;
1306 uint base_bridge_length = 5;
1307 uint max_bridge_length = std::min(t->cache.population / 1000 + base_bridge_length, TOWN_BRIDGE_LENGTH_CAP);
1308
1309 if (slope == SLOPE_FLAT) {
1310 /* Bridges starting on flat tiles are only allowed when crossing rivers, rails or one-way roads. */
1311 do {
1312 if (bridge_length++ >= base_bridge_length) {
1313 /* Allow to cross rivers, not big lakes, nor large amounts of rails or one-way roads. */
1314 return false;
1315 }
1316 bridge_tile += delta;
1317 } while (IsValidTile(bridge_tile) && ((IsWaterTile(bridge_tile) && !IsSea(bridge_tile)) || IsPlainRailTile(bridge_tile) || (IsNormalRoadTile(bridge_tile) && GetDisallowedRoadDirections(bridge_tile).Any())));
1318 } else {
1319 do {
1320 if (bridge_length++ >= max_bridge_length) {
1321 /* Ensure the bridge is not longer than the max allowed length. */
1322 return false;
1323 }
1324 bridge_tile += delta;
1325 } while (IsValidTile(bridge_tile) && (IsWaterTile(bridge_tile) || IsPlainRailTile(bridge_tile) || (IsNormalRoadTile(bridge_tile) && GetDisallowedRoadDirections(bridge_tile).Any())));
1326 }
1327
1328 /* Don't allow a bridge where the start and end tiles are adjacent with no span between. */
1329 if (bridge_length == 1) return false;
1330
1331 /* Make sure the road can be continued past the bridge. At this point, bridge_tile holds the end tile of the bridge. */
1332 if (!CanRoadContinueIntoNextTile(t, bridge_tile, bridge_dir)) return false;
1333
1334 /* If another parallel bridge exists nearby, this one would be redundant and shouldn't be built. We don't care about flat bridges. */
1335 if (slope != SLOPE_FLAT) {
1336 for (auto search : SpiralTileSequence(tile, bridge_length, 0, 0)) {
1337 /* Only consider bridge head tiles. */
1338 if (!IsBridgeTile(search)) continue;
1339
1340 /* Only consider road bridges. */
1341 if (GetTunnelBridgeTransportType(search) != TRANSPORT_ROAD) continue;
1342
1343 /* If the bridge is facing the same direction as the proposed bridge, we've found a redundant bridge. */
1344 if (GetTileSlope(search) & InclinedSlope(ReverseDiagDir(bridge_dir))) return false;
1345 }
1346 }
1347
1348 for (uint8_t times = 0; times <= 22; times++) {
1349 uint8_t bridge_type = RandomRange(MAX_BRIDGES - 1);
1350
1351 /* Can we actually build the bridge? */
1353 if (Command<Commands::BuildBridge>::Do(CommandFlagsToDCFlags(GetCommandFlags<Commands::BuildBridge>()), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, INVALID_RAILTYPE, rt).Succeeded()) {
1354 Command<Commands::BuildBridge>::Do(CommandFlagsToDCFlags(GetCommandFlags<Commands::BuildBridge>()).Set(DoCommandFlag::Execute), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, INVALID_RAILTYPE, rt);
1355 return true;
1356 }
1357 }
1358 /* Quit if it selecting an appropriate bridge type fails a large number of times. */
1359 return false;
1360}
1361
1372static bool GrowTownWithTunnel(const Town *t, const TileIndex tile, const DiagDirection tunnel_dir)
1373{
1374 assert(tunnel_dir < DIAGDIR_END);
1375
1376 Slope slope = GetTileSlope(tile);
1377
1378 /* Only consider building a tunnel if the starting tile is sloped properly. */
1379 if (slope != InclinedSlope(tunnel_dir)) return false;
1380
1381 /* Assure that the tunnel is connectable to the start side */
1382 if (!GetTownRoadBits(TileAddByDiagDir(tile, ReverseDiagDir(tunnel_dir))).Any(DiagDirToRoadBits(tunnel_dir))) return false;
1383
1384 const TileIndexDiff delta = TileOffsByDiagDir(tunnel_dir);
1385 int max_tunnel_length = 0;
1386
1387 /* There are two conditions for building tunnels: Under a mountain and under an obstruction. */
1388 if (CanRoadContinueIntoNextTile(t, tile, tunnel_dir)) {
1389 /* 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. */
1390 TileIndex slope_tile = tile;
1391 for (uint8_t tiles = 0; tiles < 4; tiles++) {
1392 if (!IsValidTile(slope_tile)) return false;
1393 slope = GetTileSlope(slope_tile);
1394 if (slope != InclinedSlope(tunnel_dir) && !IsSteepSlope(slope) && !IsSlopeWithOneCornerRaised(slope)) return false;
1395 slope_tile += delta;
1396 }
1397
1398 /* More population means longer tunnels, but make sure we can at least cover the smallest mountain which necessitates tunneling. */
1399 max_tunnel_length = (t->cache.population / 1000) + 7;
1400 } else {
1401 /* When tunneling under an obstruction, the length limit is 5, enough to tunnel under a four-track railway. */
1402 max_tunnel_length = 5;
1403 }
1404
1405 uint8_t tunnel_length = 0;
1406 TileIndex tunnel_tile = tile; // Iterator to store the other end tile of the tunnel.
1407
1408 /* Find the end tile of the tunnel for length and continuation checks. */
1409 do {
1410 if (tunnel_length++ >= max_tunnel_length) return false;
1411 tunnel_tile += delta;
1412 /* The tunnel ends when start and end tiles are the same height. */
1413 } while (IsValidTile(tunnel_tile) && GetTileZ(tile) != GetTileZ(tunnel_tile));
1414
1415 /* Don't allow a tunnel where the start and end tiles are adjacent. */
1416 if (tunnel_length == 1) return false;
1417
1418 /* Make sure the road can be continued past the tunnel. At this point, tunnel_tile holds the end tile of the tunnel. */
1419 if (!CanRoadContinueIntoNextTile(t, tunnel_tile, tunnel_dir)) return false;
1420
1421 /* Attempt to build the tunnel. Return false if it fails to let the town build a road instead. */
1423 if (Command<Commands::BuildTunnel>::Do(CommandFlagsToDCFlags(GetCommandFlags<Commands::BuildTunnel>()), tile, TRANSPORT_ROAD, INVALID_RAILTYPE, rt).Succeeded()) {
1425 return true;
1426 }
1427
1428 return false;
1429}
1430
1438{
1439 static const TileIndexDiffC tiles[] = { {-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1} };
1440 bool allow = false;
1441
1442 for (const auto &ptr : tiles) {
1443 TileIndex cur_tile = t + ToTileIndexDiff(ptr);
1444 if (!IsValidTile(cur_tile)) continue;
1445
1446 if (!(IsTileType(cur_tile, TileType::Road) || IsAnyRoadStopTile(cur_tile))) continue;
1447 allow = true;
1448
1449 RoadType road_rt = GetRoadTypeRoad(cur_tile);
1450 if (road_rt != INVALID_ROADTYPE && !GetRoadTypeInfo(road_rt)->flags.Test(RoadTypeFlag::NoHouses)) return true;
1451 }
1452
1453 /* If no road was found surrounding the tile we can allow building the house since there is
1454 * nothing which forbids it, if a road was found but the execution reached this point, then
1455 * all the found roads don't allow houses to be built */
1456 return !allow;
1457}
1458
1464{
1465 if (!IsTileType(tile, TileType::Road)) return true;
1466
1467 /* Allow extending on roadtypes which can be built by town, or if the road type matches the type the town will build. */
1468 RoadType rt = GetRoadTypeRoad(tile);
1470}
1471
1477static inline bool TownAllowedToBuildRoads(TownExpandModes modes)
1478{
1479 return modes.Test(TownExpandMode::Roads);
1480}
1481
1488
1508static TownGrowthResult GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection target_dir, Town *t1, TownExpandModes modes)
1509{
1510 RoadBits rcmd{}; // RoadBits for the road construction command
1511 TileIndex tile = *tile_ptr; // The main tile on which we base our growth
1512
1513 assert(tile < Map::Size());
1514
1515 if (cur_rb.None()) {
1516 /* Tile has no road.
1517 * We will return TownGrowthResult::SearchStopped to say that this is the last iteration. */
1518
1520 if (!_settings_game.economy.allow_town_level_crossings && IsTileType(tile, TileType::Railway)) return TownGrowthResult::SearchStopped;
1521
1522 /* Remove hills etc */
1523 if (!_settings_game.construction.build_on_slopes || Chance16(1, 6)) LevelTownLand(tile);
1524
1525 /* Is a road allowed here? */
1526 switch (t1->layout) {
1527 default: NOT_REACHED();
1528
1529 case TL_3X3_GRID:
1530 case TL_2X2_GRID:
1531 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1532 if (rcmd.None()) return TownGrowthResult::SearchStopped;
1533 break;
1534
1535 case TL_BETTER_ROADS:
1536 case TL_ORIGINAL:
1537 if (!IsRoadAllowedHere(t1, tile, target_dir)) return TownGrowthResult::SearchStopped;
1538
1539 DiagDirection source_dir = ReverseDiagDir(target_dir);
1540
1541 if (Chance16(1, 4)) {
1542 /* Randomize a new target dir */
1543 do target_dir = RandomDiagDir(); while (target_dir == source_dir);
1544 }
1545
1546 if (!IsRoadAllowedHere(t1, TileAddByDiagDir(tile, target_dir), target_dir)) {
1547 /* A road is not allowed to continue the randomized road,
1548 * return if the road we're trying to build is curved. */
1549 if (target_dir != ReverseDiagDir(source_dir)) return TownGrowthResult::SearchStopped;
1550
1551 /* Return if neither side of the new road is a house */
1555 }
1556
1557 /* That means that the road is only allowed if there is a house
1558 * at any side of the new road. */
1559 }
1560
1561 rcmd = DiagDirToRoadBits(target_dir) | DiagDirToRoadBits(source_dir);
1562 break;
1563 }
1564
1565 } else if (target_dir < DIAGDIR_END && !cur_rb.Any(DiagDirToRoadBits(ReverseDiagDir(target_dir)))) {
1567
1569
1570 /* Continue building on a partial road.
1571 * Should be always OK, so we only generate
1572 * the fitting RoadBits */
1573 switch (t1->layout) {
1574 default: NOT_REACHED();
1575
1576 case TL_3X3_GRID:
1577 case TL_2X2_GRID:
1578 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1579 break;
1580
1581 case TL_BETTER_ROADS:
1582 case TL_ORIGINAL:
1583 rcmd = DiagDirToRoadBits(ReverseDiagDir(target_dir));
1584 break;
1585 }
1586 } else {
1587 bool allow_house = true; // Value which decides if we want to construct a house
1588
1589 /* Reached a tunnel/bridge? Then continue at the other side of it, unless
1590 * it is the starting tile. Half the time, we stay on this side then.*/
1592 if (GetTunnelBridgeTransportType(tile) == TRANSPORT_ROAD && (target_dir != DIAGDIR_END || Chance16(1, 2))) {
1593 *tile_ptr = GetOtherTunnelBridgeEnd(tile);
1594 }
1596 }
1597
1598 /* Possibly extend the road in a direction.
1599 * Randomize a direction and if it has a road, bail out. */
1600 target_dir = RandomDiagDir();
1601 RoadBits target_rb = DiagDirToRoadBits(target_dir);
1602 TileIndex house_tile; // position of a possible house
1603
1604 if (cur_rb.Any(target_rb)) {
1605 /* If it's a road turn possibly build a house in a corner.
1606 * Use intersection with straight road as an indicator
1607 * that we randomised corner house position.
1608 * A turn (and we check for that later) always has only
1609 * one common bit with a straight road so it has the same
1610 * chance to be chosen as the house on the side of a road.
1611 */
1612 if ((cur_rb & ROAD_X) != target_rb) return TownGrowthResult::Continue;
1613
1614 /* Check whether it is a turn and if so determine
1615 * position of the corner tile */
1616 switch (cur_rb.base()) {
1617 case ROAD_N.base():
1618 house_tile = TileAddByDir(tile, DIR_S);
1619 break;
1620 case ROAD_S.base():
1621 house_tile = TileAddByDir(tile, DIR_N);
1622 break;
1623 case ROAD_E.base():
1624 house_tile = TileAddByDir(tile, DIR_W);
1625 break;
1626 case ROAD_W.base():
1627 house_tile = TileAddByDir(tile, DIR_E);
1628 break;
1629 default:
1630 return TownGrowthResult::Continue; // not a turn
1631 }
1632 target_dir = DIAGDIR_END;
1633 } else {
1634 house_tile = TileAddByDiagDir(tile, target_dir);
1635 }
1636
1637 /* Don't walk into water. */
1638 if (HasTileWaterGround(house_tile)) return TownGrowthResult::Continue;
1639
1640 if (!IsValidTile(house_tile)) return TownGrowthResult::Continue;
1641
1643
1644 if (target_dir != DIAGDIR_END && TownAllowedToBuildRoads(modes)) {
1645 switch (t1->layout) {
1646 default: NOT_REACHED();
1647
1648 case TL_3X3_GRID: // Use 2x2 grid afterwards!
1649 if (GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir), modes)) {
1651 }
1652 [[fallthrough]];
1653
1654 case TL_2X2_GRID:
1655 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1656 allow_house = !rcmd.Any(target_rb);
1657 break;
1658
1659 case TL_BETTER_ROADS: // Use original afterwards!
1660 if (GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir), modes)) {
1662 }
1663 [[fallthrough]];
1664
1665 case TL_ORIGINAL:
1666 /* Allow a house at the edge. 60% chance or
1667 * always ok if no road allowed. */
1668 rcmd = target_rb;
1669 allow_house = (!IsRoadAllowedHere(t1, house_tile, target_dir) || Chance16(6, 10));
1670 break;
1671 }
1672 }
1673
1674 allow_house &= RoadTypesAllowHouseHere(house_tile);
1675
1676 if (allow_house) {
1677 /* Build a house, but not if there already is a house there. */
1678 if (!IsTileType(house_tile, TileType::House)) {
1679 /* Level the land if possible */
1680 if (Chance16(1, 6)) LevelTownLand(house_tile);
1681
1682 /* And build a house.
1683 * Set result to -1 if we managed to build it. */
1684 if (TryBuildTownHouse(t1, house_tile, modes)) {
1686 }
1687 }
1688 return result;
1689 }
1690
1691 if (!TownCanGrowRoad(tile)) return result;
1692 }
1693
1694 /* Return if a water tile */
1696
1697 /* Make the roads look nicer */
1698 rcmd = CleanUpRoadBits(tile, rcmd);
1699 if (rcmd.None()) return TownGrowthResult::SearchStopped;
1700
1701 /* Only use the target direction for bridges and tunnels to ensure they're connected.
1702 * The target_dir is as computed previously according to town layout, so
1703 * it will match it perfectly. */
1704 if (GrowTownWithBridge(t1, tile, target_dir)) {
1706 }
1707 if (GrowTownWithTunnel(t1, tile, target_dir)) {
1709 }
1710
1711 if (GrowTownWithRoad(t1, tile, rcmd)) {
1713 }
1715}
1716
1725static bool CanFollowRoad(TileIndex tile, DiagDirection dir, TownExpandModes modes)
1726{
1727 TileIndex target_tile = tile + TileOffsByDiagDir(dir);
1728 if (!IsValidTile(target_tile)) return false;
1729 if (HasTileWaterGround(target_tile)) return false;
1730
1731 RoadBits target_rb = GetTownRoadBits(target_tile);
1732 if (TownAllowedToBuildRoads(modes)) {
1733 /* Check whether a road connection exists or can be build. */
1734 switch (GetTileType(target_tile)) {
1735 case TileType::Road:
1736 return target_rb.Any();
1737
1738 case TileType::Station:
1739 return IsDriveThroughStopTile(target_tile);
1740
1742 return GetTunnelBridgeTransportType(target_tile) == TRANSPORT_ROAD;
1743
1744 case TileType::House:
1745 case TileType::Industry:
1746 case TileType::Object:
1747 return false;
1748
1749 default:
1750 /* Checked for void and water earlier */
1751 return true;
1752 }
1753 } else {
1754 /* Check whether a road connection already exists,
1755 * and it leads somewhere else. */
1757 return target_rb.Any(back_rb) && target_rb.Reset(back_rb).Any();
1758 }
1759}
1760
1768static bool GrowTownAtRoad(Town *t, TileIndex tile, TownExpandModes modes)
1769{
1770 /* Special case.
1771 * @see GrowTownInTile Check the else if
1772 */
1773 DiagDirection target_dir = DIAGDIR_END; // The direction in which we want to extend the town
1774
1775 assert(tile < Map::Size());
1776
1777 /* Number of times to search.
1778 * Better roads, 2X2 and 3X3 grid grow quite fast so we give
1779 * them a little handicap. */
1780 int iterations;
1781 switch (t->layout) {
1782 case TL_BETTER_ROADS:
1783 iterations = 10 + t->cache.num_houses * 2 / 9;
1784 break;
1785
1786 case TL_3X3_GRID:
1787 case TL_2X2_GRID:
1788 iterations = 10 + t->cache.num_houses * 1 / 9;
1789 break;
1790
1791 default:
1792 iterations = 10 + t->cache.num_houses * 4 / 9;
1793 break;
1794 }
1795
1796 do {
1797 RoadBits cur_rb = GetTownRoadBits(tile); // The RoadBits of the current tile
1798
1799 /* Try to grow the town from this point */
1800 switch (GrowTownInTile(&tile, cur_rb, target_dir, t, modes)) {
1802 return true;
1804 iterations = 0;
1805 break;
1806 default:
1807 break;
1808 };
1809
1810 /* Exclude the source position from the bitmask
1811 * and return if no more road blocks available */
1812 if (IsValidDiagDirection(target_dir)) cur_rb.Reset(DiagDirToRoadBits(ReverseDiagDir(target_dir)));
1813 if (cur_rb.None()) return false;
1814
1816 /* Only build in the direction away from the tunnel or bridge. */
1817 target_dir = ReverseDiagDir(GetTunnelBridgeDirection(tile));
1818 } else {
1819 /* Select a random bit from the blockmask, walk a step
1820 * and continue the search from there. */
1821 do {
1822 if (cur_rb.None()) return false;
1823 RoadBits target_bits;
1824 do {
1825 target_dir = RandomDiagDir();
1826 target_bits = DiagDirToRoadBits(target_dir);
1827 } while (!cur_rb.Any(target_bits));
1828 cur_rb.Reset(target_bits);
1829 } while (!CanFollowRoad(tile, target_dir, modes));
1830 }
1831 tile = TileAddByDiagDir(tile, target_dir);
1832
1834 /* Don't allow building over roads of other cities */
1835 if (IsRoadOwner(tile, RoadTramType::Road, OWNER_TOWN) && Town::GetByTile(tile) != t) {
1836 return false;
1837 } else if (IsRoadOwner(tile, RoadTramType::Road, OWNER_NONE) && _game_mode == GM_EDITOR) {
1838 /* If we are in the SE, and this road-piece has no town owner yet, it just found an
1839 * owner :) (happy happy happy road now) */
1841 SetTownIndex(tile, t->index);
1842 }
1843 }
1844
1845 /* Max number of times is checked. */
1846 } while (--iterations >= 0);
1847
1848 return false;
1849}
1850
1859{
1860 uint32_t r = Random();
1861 uint a = GB(r, 0, 2);
1862 uint b = GB(r, 8, 2);
1863 if (a == b) b ^= 2;
1864 return static_cast<RoadBits>((RoadBits{RoadBit::NW}.base() << a) + (RoadBits{RoadBit::NW}.base() << b));
1865}
1866
1873static bool GrowTown(Town *t, TownExpandModes modes)
1874{
1875 static const TileIndexDiffC _town_coord_mod[] = {
1876 {-1, 0},
1877 { 1, 1},
1878 { 1, -1},
1879 {-1, -1},
1880 {-1, 0},
1881 { 0, 2},
1882 { 2, 0},
1883 { 0, -2},
1884 {-1, -1},
1885 {-2, 2},
1886 { 2, 2},
1887 { 2, -2},
1888 { 0, 0}
1889 };
1890
1891 /* Current "company" is a town */
1893
1894 TileIndex tile = t->xy; // The tile we are working with ATM
1895
1896 /* Find a road that we can base the construction on. */
1897 for (const auto &ptr : _town_coord_mod) {
1898 if (GetTownRoadBits(tile).Any()) {
1899 bool success = GrowTownAtRoad(t, tile, modes);
1900 return success;
1901 }
1902 tile = TileAdd(tile, ToTileIndexDiff(ptr));
1903 }
1904
1905 /* No road available, try to build a random road block by
1906 * clearing some land and then building a road there. */
1907 if (TownAllowedToBuildRoads(modes)) {
1908 tile = t->xy;
1909 for (const auto &ptr : _town_coord_mod) {
1910 /* Only work with plain land that not already has a house */
1911 if (!IsTileType(tile, TileType::House) && IsTileFlat(tile)) {
1912 if (Command<Commands::LandscapeClear>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile).Succeeded()) {
1914 Command<Commands::BuildRoad>::Do({DoCommandFlag::Execute, DoCommandFlag::Auto}, tile, GenRandomRoadBits(), rt, {}, t->index);
1915 return true;
1916 }
1917 }
1918 tile = TileAdd(tile, ToTileIndexDiff(ptr));
1919 }
1920 }
1921
1922 return false;
1923}
1924
1930{
1931 static const std::array<std::array<uint32_t, NUM_HOUSE_ZONES>, 23> _town_squared_town_zone_radius_data = {{
1932 { 4, 0, 0, 0, 0}, // 0
1933 { 16, 0, 0, 0, 0},
1934 { 25, 0, 0, 0, 0},
1935 { 36, 0, 0, 0, 0},
1936 { 49, 0, 4, 0, 0},
1937 { 64, 0, 4, 0, 0}, // 20
1938 { 64, 0, 9, 0, 1},
1939 { 64, 0, 9, 0, 4},
1940 { 64, 0, 16, 0, 4},
1941 { 81, 0, 16, 0, 4},
1942 { 81, 0, 16, 0, 4}, // 40
1943 { 81, 0, 25, 0, 9},
1944 { 81, 36, 25, 0, 9},
1945 { 81, 36, 25, 16, 9},
1946 { 81, 49, 0, 25, 9},
1947 { 81, 64, 0, 25, 9}, // 60
1948 { 81, 64, 0, 36, 9},
1949 { 81, 64, 0, 36, 16},
1950 {100, 81, 0, 49, 16},
1951 {100, 81, 0, 49, 25},
1952 {121, 81, 0, 49, 25}, // 80
1953 {121, 81, 0, 49, 25},
1954 {121, 81, 0, 49, 36}, // 88
1955 }};
1956
1957 if (t->cache.num_houses < std::size(_town_squared_town_zone_radius_data) * 4) {
1958 t->cache.squared_town_zone_radius = _town_squared_town_zone_radius_data[t->cache.num_houses / 4];
1959 } else {
1960 int mass = t->cache.num_houses / 8;
1961 /* Actually we are proportional to sqrt() but that's right because we are covering an area.
1962 * The offsets are to make sure the radii do not decrease in size when going from the table
1963 * to the calculated value.*/
1969 }
1970}
1971
1977{
1979 uint32_t production = ScaleByCargoScale(t->cache.population >> 3, true);
1980 if (production == 0) continue;
1981
1982 auto &supplied = t->GetOrCreateCargoSupplied(cs->Index());
1983 supplied.history[LAST_MONTH].production = production;
1984 }
1985
1987 uint32_t production = ScaleByCargoScale(t->cache.population >> 4, true);
1988 if (production == 0) continue;
1989
1990 auto &supplied = t->GetOrCreateCargoSupplied(cs->Index());
1991 supplied.history[LAST_MONTH].production = production;
1992 }
1993}
1994
1995static void UpdateTownGrowthRate(Town *t);
1996static void UpdateTownGrowth(Town *t);
1997
2009static void DoCreateTown(Town *t, TileIndex tile, uint32_t townnameparts, TownSize size, bool city, TownLayout layout, bool manual)
2010{
2011 AutoRestoreBackup backup(_generating_town, true);
2012
2013 t->xy = tile;
2014 t->cache.num_houses = 0;
2015 t->time_until_rebuild = 10;
2017 t->flags.Reset();
2018 t->cache.population = 0;
2020 /* Spread growth across ticks so even if there are many
2021 * similar towns they're unlikely to grow all in one tick */
2022 t->grow_counter = t->index % Ticks::TOWN_GROWTH_TICKS;
2023 t->growth_rate = TownTicksToGameTicks(250);
2024 t->show_zone = false;
2025
2026 _town_kdtree.Insert(t->index);
2027
2028 /* Set the default cargo requirement for town growth */
2029 switch (_settings_game.game_creation.landscape) {
2032 break;
2033
2037 break;
2038
2039 default:
2040 break;
2041 }
2042
2043 t->fund_buildings_months = 0;
2044
2045 t->ratings.fill(RATING_INITIAL);
2046
2047 t->have_ratings = {};
2048 t->exclusivity = CompanyID::Invalid();
2049 t->exclusive_counter = 0;
2050 t->statues = {};
2051
2052 {
2053 TownNameParams tnp(_settings_game.game_creation.town_name);
2054 t->townnamegrfid = tnp.grfid;
2055 t->townnametype = tnp.type;
2056 }
2057 t->townnameparts = townnameparts;
2058
2059 t->InitializeLayout(layout);
2060
2061 t->larger_town = city;
2062
2063 int x = (int)size * 16 + 3;
2064 if (size == TSZ_RANDOM) x = (Random() & 0xF) + 8;
2065 /* Don't create huge cities when founding town in-game */
2066 if (city && (!manual || _game_mode == GM_EDITOR)) x *= _settings_game.economy.initial_city_size;
2067
2068 t->cache.num_houses += x;
2070
2071 int i = x * 4;
2072 do {
2074 } while (--i);
2075
2076 t->UpdateVirtCoord();
2077 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_REBUILD);
2078
2079 t->cache.num_houses -= x;
2084}
2085
2092static CommandCost TownCanBePlacedHere(TileIndex tile, bool check_surrounding)
2093{
2094 /* Check if too close to the edge of map */
2095 if (DistanceFromEdge(tile) < 12) {
2096 return CommandCost(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP);
2097 }
2098
2099 /* Check distance to all other towns. */
2100 if (IsCloseToTown(tile, _settings_game.economy.town_min_distance)) {
2101 return CommandCost(STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN);
2102 }
2103
2104 /* Can only build on clear flat areas, possibly with trees. */
2105 if ((!IsTileType(tile, TileType::Clear) && !IsTileType(tile, TileType::Trees)) || !IsTileFlat(tile)) {
2106 return CommandCost(STR_ERROR_SITE_UNSUITABLE);
2107 }
2108
2109 /* We might want to make sure the town has enough room. */
2110 if (check_surrounding) {
2111 constexpr uint SEARCH_DIAMETER = 5; // Center tile of town + 2 tile radius.
2112 /* Half of the tiles in the search must be valid for the town to build upon. */
2113 constexpr uint VALID_TILE_GOAL = (SEARCH_DIAMETER * SEARCH_DIAMETER) / 2;
2114 uint counter = 0;
2115 int town_height = GetTileZ(tile);
2116 for (TileIndex t : SpiralTileSequence(tile, SEARCH_DIAMETER)) {
2117 if (counter == VALID_TILE_GOAL) break;
2118
2119 switch (GetTileType(t)) {
2120 case TileType::Clear:
2121 /* Don't allow rough tiles, as they are likely wetlands. */
2122 if (GetClearGround(t) == ClearGround::Rough) continue;
2123 break;
2124
2125 case TileType::Trees:
2126 /* Don't allow rough trees, as they are likely wetlands. */
2127 if (GetTreeGround(t) == TreeGround::Rough) continue;
2128 break;
2129
2130 default:
2131 continue;
2132 }
2133
2134 bool elevation_similar = (GetTileMaxZ(t) <= town_height + 1) && (GetTileZ(t) >= town_height - 1);
2135 if (elevation_similar) counter++;
2136 }
2137
2138 if (counter < VALID_TILE_GOAL) return CommandCost(STR_ERROR_SITE_UNSUITABLE);
2139 }
2140
2142}
2143
2149static bool IsUniqueTownName(const std::string &name)
2150{
2151 for (const Town *t : Town::Iterate()) {
2152 if (!t->name.empty() && t->name == name) return false;
2153 }
2154
2155 return true;
2156}
2157
2170std::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)
2171{
2172 TownNameParams par(_settings_game.game_creation.town_name);
2173
2174 if (size >= TSZ_END) return { CMD_ERROR, 0, TownID::Invalid() };
2175 if (layout >= NUM_TLS) return { CMD_ERROR, 0, TownID::Invalid() };
2176
2177 /* Some things are allowed only in the scenario editor and for game scripts. */
2178 if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY) {
2179 if (_settings_game.economy.found_town == TF_FORBIDDEN) return { CMD_ERROR, 0, TownID::Invalid() };
2180 if (size == TSZ_LARGE) return { CMD_ERROR, 0, TownID::Invalid() };
2181 if (random_location) return { CMD_ERROR, 0, TownID::Invalid() };
2182 if (_settings_game.economy.found_town != TF_CUSTOM_LAYOUT && layout != _settings_game.economy.town_layout) {
2183 return { CMD_ERROR, 0, TownID::Invalid() };
2184 }
2185 } else if (_current_company == OWNER_DEITY && random_location) {
2186 /* Random parameter is not allowed for Game Scripts. */
2187 return { CMD_ERROR, 0, TownID::Invalid() };
2188 }
2189
2190 if (text.empty()) {
2191 /* If supplied name is empty, townnameparts has to generate unique automatic name */
2192 if (!VerifyTownName(townnameparts, &par)) return { CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE), 0, TownID::Invalid() };
2193 } else {
2194 /* If name is not empty, it has to be unique custom name */
2195 if (Utf8StringLength(text) >= MAX_LENGTH_TOWN_NAME_CHARS) return { CMD_ERROR, 0, TownID::Invalid() };
2196 if (!IsUniqueTownName(text)) return { CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE), 0, TownID::Invalid() };
2197 }
2198
2199 /* Allocate town struct */
2200 if (!Town::CanAllocateItem()) return { CommandCost(STR_ERROR_TOO_MANY_TOWNS), 0, TownID::Invalid() };
2201
2202 if (!random_location) {
2203 CommandCost ret = TownCanBePlacedHere(tile, false);
2204 if (ret.Failed()) return { ret, 0, TownID::Invalid() };
2205 }
2206
2207 static const uint8_t price_mult[][TSZ_RANDOM + 1] = {{ 15, 25, 40, 25 }, { 20, 35, 55, 35 }};
2208 /* multidimensional arrays have to have defined length of non-first dimension */
2209 static_assert(lengthof(price_mult[0]) == 4);
2210
2212 uint8_t mult = price_mult[city][size];
2213
2214 cost.MultiplyCost(mult);
2215
2216 /* Create the town */
2217 TownID new_town = TownID::Invalid();
2218 if (flags.Test(DoCommandFlag::Execute)) {
2219 if (cost.GetCost() > GetAvailableMoneyForCommand()) {
2220 return { CommandCost(ExpensesType::Other), cost.GetCost(), TownID::Invalid() };
2221 }
2222
2223 Backup<bool> old_generating_world(_generating_world, true);
2225 Town *t;
2226 if (random_location) {
2227 t = CreateRandomTown(20, townnameparts, size, city, layout);
2228 } else {
2229 t = Town::Create(tile);
2230 DoCreateTown(t, tile, townnameparts, size, city, layout, true);
2231 }
2232
2234 old_generating_world.Restore();
2235
2236 if (t == nullptr) return { CommandCost(STR_ERROR_NO_SPACE_FOR_TOWN), 0, TownID::Invalid() };
2237
2238 new_town = t->index;
2239
2240 if (!text.empty()) {
2241 t->name = text;
2242 t->UpdateVirtCoord();
2243 }
2244
2245 if (_game_mode != GM_EDITOR) {
2246 /* 't' can't be nullptr since 'random' is false outside scenedit */
2247 assert(!random_location);
2248
2250 AddTileNewsItem(GetEncodedString(STR_NEWS_NEW_TOWN_UNSPONSORED, t->index), NewsType::IndustryOpen, tile);
2251 } else {
2252 std::string company_name = GetString(STR_COMPANY_NAME, _current_company);
2253 AddTileNewsItem(GetEncodedString(STR_NEWS_NEW_TOWN, company_name, t->index), NewsType::IndustryOpen, tile);
2254 }
2255 AI::BroadcastNewEvent(new ScriptEventTownFounded(t->index));
2256 Game::NewEvent(new ScriptEventTownFounded(t->index));
2257 }
2258 }
2259 return { cost, 0, new_town };
2260}
2261
2272{
2273 switch (layout) {
2274 case TL_2X2_GRID: return TileXY(TileX(tile) - TileX(tile) % 3, TileY(tile) - TileY(tile) % 3);
2275 case TL_3X3_GRID: return TileXY(TileX(tile) & ~3, TileY(tile) & ~3);
2276 default: return tile;
2277 }
2278}
2279
2290{
2291 switch (layout) {
2292 case TL_2X2_GRID: return TileX(tile) % 3 == 0 && TileY(tile) % 3 == 0;
2293 case TL_3X3_GRID: return TileX(tile) % 4 == 0 && TileY(tile) % 4 == 0;
2294 default: return true;
2295 }
2296}
2297
2311{
2312 for (auto coast : SpiralTileSequence(tile, 40)) {
2313 /* Find nearest land tile */
2314 if (!IsTileType(coast, TileType::Clear)) continue;
2315
2316 TileIndex furthest = INVALID_TILE;
2317 uint max_dist = 0;
2318 for (auto test : SpiralTileSequence(coast, 10)) {
2319 if (!IsTileType(test, TileType::Clear) || !IsTileFlat(test) || !IsTileAlignedToGrid(test, layout)) continue;
2320 if (TownCanBePlacedHere(test, true).Failed()) continue;
2321
2322 uint dist = GetClosestWaterDistance(test, true);
2323 if (dist > max_dist) {
2324 furthest = test;
2325 max_dist = dist;
2326 }
2327 }
2328 return furthest;
2329 }
2330
2331 /* if we get here just give up */
2332 return INVALID_TILE;
2333}
2334
2340{
2341 switch (_settings_game.game_creation.landscape) {
2346 default: NOT_REACHED();
2347 }
2348}
2349
2359static Town *CreateRandomTown(uint attempts, uint32_t townnameparts, TownSize size, bool city, TownLayout layout)
2360{
2361 assert(_game_mode == GM_EDITOR || _generating_world); // These are the preconditions for Commands::DeleteTown
2362
2363 if (!Town::CanAllocateItem()) return nullptr;
2364
2365 do {
2366 /* Generate a tile index not too close from the edge */
2367 TileIndex tile = AlignTileToGrid(RandomTile(), layout);
2368
2369 /* If we tried to place the town on water, find a suitable land tile nearby.
2370 * Otherwise, evaluate the land tile. */
2371 if (IsTileType(tile, TileType::Water)) {
2372 tile = FindNearestGoodCoastalTownSpot(tile, layout);
2373 if (tile == INVALID_TILE) continue;
2374 } else if (TownCanBePlacedHere(tile, true).Failed()) continue;
2375
2376 /* Allocate a town struct */
2377 Town *t = Town::Create(tile);
2378
2379 DoCreateTown(t, tile, townnameparts, size, city, layout, false);
2380
2381 /* if the population is still 0 at the point, then the
2382 * placement is so bad it couldn't grow at all */
2383 if (t->cache.population > 0) return t;
2384
2386 [[maybe_unused]] CommandCost rc = Command<Commands::DeleteTown>::Do(DoCommandFlag::Execute, t->index);
2387 assert(rc.Succeeded());
2388
2389 /* We already know that we can allocate a single town when
2390 * entering this function. However, we create and delete
2391 * a town which "resets" the allocation checks. As such we
2392 * need to check again when assertions are enabled. */
2393 assert(Town::CanAllocateItem());
2394 } while (--attempts != 0);
2395
2396 return nullptr;
2397}
2398
2405{
2406 static const uint8_t num_initial_towns[4] = {5, 11, 23, 46}; // very low, low, normal, high
2407 if (_settings_game.difficulty.number_towns == static_cast<uint>(CUSTOM_TOWN_NUMBER_DIFFICULTY)) {
2408 return _settings_newgame.game_creation.custom_town_number;
2409 }
2410 return Map::ScaleBySize(num_initial_towns[_settings_game.difficulty.number_towns]);
2411}
2412
2420bool GenerateTowns(TownLayout layout, std::optional<uint> number)
2421{
2422 uint current_number = 0;
2423 uint total;
2424 if (number.has_value()) {
2425 total = number.value();
2426 } else if (_settings_game.difficulty.number_towns == static_cast<uint>(CUSTOM_TOWN_NUMBER_DIFFICULTY)) {
2427 total = GetDefaultTownsForMapSize();
2428 } else {
2429 total = Map::ScaleByLandProportion(GetDefaultTownsForMapSize() + (Random() & 7));
2430 }
2431
2432 total = Clamp<uint>(total, 1, TownPool::MAX_SIZE);
2433 uint32_t townnameparts;
2434 TownNames town_names;
2435
2437
2438 /* Pre-populate the town names list with the names of any towns already on the map */
2439 for (const Town *town : Town::Iterate()) {
2440 town_names.insert(town->GetCachedName());
2441 }
2442
2443 /* Randomised offset for city status. This means with e.g. 1-in-4 towns being cities, a map with 10 towns
2444 * may have 2 or 3 cities, instead of always 3. */
2445 uint city_random_offset = _settings_game.economy.larger_towns == 0 ? 0 : (Random() % _settings_game.economy.larger_towns);
2446
2447 /* First attempt will be made at creating the suggested number of towns.
2448 * Note that this is really a suggested value, not a required one.
2449 * We would not like the system to lock up just because the user wanted 100 cities on a 64*64 map, would we? */
2450 do {
2451 bool city = (_settings_game.economy.larger_towns != 0 && ((city_random_offset + current_number) % _settings_game.economy.larger_towns) == 0);
2453 /* Get a unique name for the town. */
2454 if (!GenerateTownName(_random, &townnameparts, &town_names)) continue;
2455 /* try 20 times to create a random-sized town for the first loop. */
2456 if (CreateRandomTown(20, townnameparts, TSZ_RANDOM, city, layout) != nullptr) current_number++; // If creation was successful, raise a flag.
2457 } while (--total);
2458
2459 town_names.clear();
2460
2461 /* Build the town k-d tree again to make sure it's well balanced */
2462 RebuildTownKdtree();
2463
2464 if (current_number != 0) return true;
2465
2466 /* If current_number is still zero at this point, it means that not a single town has been created.
2467 * So give it a last try, but now more aggressive */
2468 if (GenerateTownName(_random, &townnameparts) &&
2469 CreateRandomTown(10000, townnameparts, TSZ_RANDOM, _settings_game.economy.larger_towns != 0, layout) != nullptr) {
2470 return true;
2471 }
2472
2473 /* If there are no towns at all and we are generating new game, bail out */
2474 if (Town::GetNumItems() == 0 && _game_mode != GM_EDITOR) {
2475 ShowErrorMessage(GetEncodedString(STR_ERROR_COULD_NOT_CREATE_TOWN), {}, WL_CRITICAL);
2476 }
2477
2478 return false; // we are still without a town? we failed, simply
2479}
2480
2481
2489{
2490 uint dist = DistanceSquare(tile, t->xy);
2491
2492 if (t->fund_buildings_months != 0 && dist <= 25) return HouseZone::TownCentre;
2493
2494 HouseZone smallest = HouseZone::TownEdge;
2495 for (HouseZone i : HZ_ZONE_ALL) {
2496 if (dist < t->cache.squared_town_zone_radius[to_underlying(i)]) smallest = i;
2497 }
2498
2499 return smallest;
2500}
2501
2513static inline void ClearMakeHouseTile(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool is_protected)
2514{
2515 [[maybe_unused]] CommandCost cc = Command<Commands::LandscapeClear>::Do({DoCommandFlag::Execute, DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile);
2516 assert(cc.Succeeded());
2517
2518 IncreaseBuildingCount(t, type);
2519 MakeHouseTile(tile, t->index, counter, stage, type, random_bits, is_protected);
2520 if (HouseSpec::Get(type)->building_flags.Test(BuildingFlag::IsAnimated)) AddAnimatedTile(tile, false);
2521
2522 MarkTileDirtyByTile(tile);
2523}
2524
2525
2537static void MakeTownHouse(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool is_protected)
2538{
2539 BuildingFlags size = HouseSpec::Get(type)->building_flags;
2540
2541 ClearMakeHouseTile(tile, t, counter, stage, type, random_bits, is_protected);
2542 if (size.Any(BUILDING_2_TILES_Y)) ClearMakeHouseTile(tile + TileDiffXY(0, 1), t, counter, stage, ++type, random_bits, is_protected);
2543 if (size.Any(BUILDING_2_TILES_X)) ClearMakeHouseTile(tile + TileDiffXY(1, 0), t, counter, stage, ++type, random_bits, is_protected);
2544 if (size.Any(BUILDING_HAS_4_TILES)) ClearMakeHouseTile(tile + TileDiffXY(1, 1), t, counter, stage, ++type, random_bits, is_protected);
2545
2546 ForAllStationsAroundTiles(TileArea(tile, size.Any(BUILDING_2_TILES_X) ? 2 : 1, size.Any(BUILDING_2_TILES_Y) ? 2 : 1), [t](Station *st, TileIndex) {
2547 t->stations_near.insert(st);
2548 return true;
2549 });
2550}
2551
2552
2559static inline bool CanBuildHouseHere(TileIndex tile, bool noslope)
2560{
2561 /* cannot build on these slopes... */
2562 Slope slope = GetTileSlope(tile);
2563 if ((noslope && slope != SLOPE_FLAT) || IsSteepSlope(slope)) return false;
2564
2565 /* at least one RoadTypes allow building the house here? */
2566 if (!RoadTypesAllowHouseHere(tile)) return false;
2567
2568 /* building under a bridge? */
2569 if (IsBridgeAbove(tile)) return false;
2570
2571 /* can we clear the land? */
2572 return Command<Commands::LandscapeClear>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile).Succeeded();
2573}
2574
2575
2584static inline bool CheckBuildHouseSameZ(TileIndex tile, int z, bool noslope)
2585{
2586 if (!CanBuildHouseHere(tile, noslope)) return false;
2587
2588 /* if building on slopes is allowed, there will be flattening foundation (to tile max z) */
2589 if (GetTileMaxZ(tile) != z) return false;
2590
2591 return true;
2592}
2593
2594
2603static bool CheckFree2x2Area(TileIndex tile, int z, bool noslope)
2604{
2605 /* we need to check this tile too because we can be at different tile now */
2606 if (!CheckBuildHouseSameZ(tile, z, noslope)) return false;
2607
2608 for (DiagDirection d = DIAGDIR_SE; d < DIAGDIR_END; d++) {
2609 tile += TileOffsByDiagDir(d);
2610 if (!CheckBuildHouseSameZ(tile, z, noslope)) return false;
2611 }
2612
2613 return true;
2614}
2615
2616
2625static inline bool TownLayoutAllowsHouseHere(Town *t, TileIndex tile, TownExpandModes modes)
2626{
2627 if (!modes.Test(TownExpandMode::Buildings)) return false;
2628
2629 /* Allow towns everywhere when we don't build roads */
2630 if (!TownAllowedToBuildRoads(modes)) return true;
2631
2632 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
2633
2634 switch (t->layout) {
2635 case TL_2X2_GRID:
2636 if ((grid_pos.x % 3) == 0 || (grid_pos.y % 3) == 0) return false;
2637 break;
2638
2639 case TL_3X3_GRID:
2640 if ((grid_pos.x % 4) == 0 || (grid_pos.y % 4) == 0) return false;
2641 break;
2642
2643 default:
2644 break;
2645 }
2646
2647 return true;
2648}
2649
2650
2659static inline bool TownLayoutAllows2x2HouseHere(Town *t, TileIndex tile, TownExpandModes modes)
2660{
2661 if (!modes.Test(TownExpandMode::Buildings)) return false;
2662
2663 /* Allow towns everywhere when we don't build roads */
2664 if (!TownAllowedToBuildRoads(modes)) return true;
2665
2666 /* Compute relative position of tile. (Positive offsets are towards north) */
2667 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
2668
2669 switch (t->layout) {
2670 case TL_2X2_GRID:
2671 grid_pos.x %= 3;
2672 grid_pos.y %= 3;
2673 if ((grid_pos.x != 2 && grid_pos.x != -1) ||
2674 (grid_pos.y != 2 && grid_pos.y != -1)) return false;
2675 break;
2676
2677 case TL_3X3_GRID:
2678 if ((grid_pos.x & 3) < 2 || (grid_pos.y & 3) < 2) return false;
2679 break;
2680
2681 default:
2682 break;
2683 }
2684
2685 return true;
2686}
2687
2688
2700static bool CheckTownBuild2House(TileIndex *tile, Town *t, int maxz, bool noslope, DiagDirection second, TownExpandModes modes)
2701{
2702 /* 'tile' is already checked in BuildTownHouse() - CanBuildHouseHere() and slope test */
2703
2704 TileIndex tile2 = *tile + TileOffsByDiagDir(second);
2705 if (TownLayoutAllowsHouseHere(t, tile2, modes) && CheckBuildHouseSameZ(tile2, maxz, noslope)) return true;
2706
2707 tile2 = *tile + TileOffsByDiagDir(ReverseDiagDir(second));
2708 if (TownLayoutAllowsHouseHere(t, tile2, modes) && CheckBuildHouseSameZ(tile2, maxz, noslope)) {
2709 *tile = tile2;
2710 return true;
2711 }
2712
2713 return false;
2714}
2715
2716
2727static bool CheckTownBuild2x2House(TileIndex *tile, Town *t, int maxz, bool noslope, TownExpandModes modes)
2728{
2729 TileIndex tile2 = *tile;
2730
2731 for (DiagDirection d = DIAGDIR_SE;; d++) { // 'd' goes through DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_END
2732 if (TownLayoutAllows2x2HouseHere(t, tile2, modes) && CheckFree2x2Area(tile2, maxz, noslope)) {
2733 *tile = tile2;
2734 return true;
2735 }
2736 if (d == DIAGDIR_END) break;
2737 tile2 += TileOffsByDiagDir(ReverseDiagDir(d)); // go clockwise
2738 }
2739
2740 return false;
2741}
2742
2753static void BuildTownHouse(Town *t, TileIndex tile, const HouseSpec *hs, HouseID house, uint8_t random_bits, bool house_completed, bool is_protected)
2754{
2755 /* build the house */
2756 t->cache.num_houses++;
2757
2758 uint8_t construction_counter = 0;
2759 uint8_t construction_stage = 0;
2760
2761 if (_generating_world || _game_mode == GM_EDITOR || house_completed) {
2762 uint32_t construction_random = Random();
2763
2764 construction_stage = TOWN_HOUSE_COMPLETED;
2765 if (_generating_world && !hs->extra_flags.Test(HouseExtraFlag::BuildingIsHistorical) && Chance16(1, 7)) construction_stage = GB(construction_random, 0, 2);
2766
2767 if (construction_stage == TOWN_HOUSE_COMPLETED) {
2769 } else {
2770 construction_counter = GB(construction_random, 2, 2);
2771 }
2772 }
2773
2774 MakeTownHouse(tile, t, construction_counter, construction_stage, house, random_bits, is_protected);
2777
2778 BuildingFlags size = hs->building_flags;
2779
2780 TriggerHouseAnimation_ConstructionStageChanged(tile, true);
2781 if (size.Any(BUILDING_2_TILES_Y)) TriggerHouseAnimation_ConstructionStageChanged(tile + TileDiffXY(0, 1), true);
2782 if (size.Any(BUILDING_2_TILES_X)) TriggerHouseAnimation_ConstructionStageChanged(tile + TileDiffXY(1, 0), true);
2783 if (size.Any(BUILDING_HAS_4_TILES)) TriggerHouseAnimation_ConstructionStageChanged(tile + TileDiffXY(1, 1), true);
2784}
2785
2793static bool TryBuildTownHouse(Town *t, TileIndex tile, TownExpandModes modes)
2794{
2795 /* forbidden building here by town layout */
2796 if (!TownLayoutAllowsHouseHere(t, tile, modes)) return false;
2797
2798 /* no house allowed at all, bail out */
2799 if (!CanBuildHouseHere(tile, false)) return false;
2800
2801 Slope slope = GetTileSlope(tile);
2802 int maxz = GetTileMaxZ(tile);
2803
2804 /* Get the town zone type of the current tile, as well as the climate.
2805 * This will allow to easily compare with the specs of the new house to build */
2806 HouseZones zones = GetTownRadiusGroup(t, tile);
2807
2808 switch (_settings_game.game_creation.landscape) {
2813 }
2814
2815 /* bits 0-4 are used
2816 * bits 11-15 are used
2817 * bits 5-10 are not used. */
2818 static std::vector<std::pair<HouseID, uint>> probs;
2819 probs.clear();
2820
2821 uint probability_max = 0;
2822
2823 /* Generate a list of all possible houses that can be built. */
2824 for (const auto &hs : HouseSpec::Specs()) {
2825 /* Verify that the candidate house spec matches the current tile status */
2826 if (!hs.building_availability.All(zones) || !hs.enabled || hs.grf_prop.override_id != INVALID_HOUSE_ID) continue;
2827
2828 /* Don't let these counters overflow. Global counters are 32bit, there will never be that many houses. */
2829 if (hs.class_id != HOUSE_NO_CLASS) {
2830 /* id_count is always <= class_count, so it doesn't need to be checked */
2831 if (t->cache.building_counts.class_count[hs.class_id] == UINT16_MAX) continue;
2832 } else {
2833 /* If the house has no class, check id_count instead */
2834 if (t->cache.building_counts.id_count[hs.Index()] == UINT16_MAX) continue;
2835 }
2836
2837 uint cur_prob = hs.probability;
2838 probability_max += cur_prob;
2839 probs.emplace_back(hs.Index(), cur_prob);
2840 }
2841
2842 TileIndex base_tile = tile;
2843
2844 while (probability_max > 0) {
2845 /* Building a multitile building can change the location of tile.
2846 * The building would still be built partially on that tile, but
2847 * its northern tile would be elsewhere. However, if the callback
2848 * fails we would be basing further work from the changed tile.
2849 * So a next 1x1 tile building could be built on the wrong tile. */
2850 tile = base_tile;
2851
2852 uint r = RandomRange(probability_max);
2853 uint i;
2854 for (i = 0; i < probs.size(); i++) {
2855 if (probs[i].second > r) break;
2856 r -= probs[i].second;
2857 }
2858
2859 HouseID house = probs[i].first;
2860 probability_max -= probs[i].second;
2861
2862 /* remove tested house from the set */
2863 probs[i] = probs.back();
2864 probs.pop_back();
2865
2866 const HouseSpec *hs = HouseSpec::Get(house);
2867
2868 if (!_generating_world && _game_mode != GM_EDITOR && hs->extra_flags.Test(HouseExtraFlag::BuildingIsHistorical)) {
2869 continue;
2870 }
2871
2873
2874 /* Special houses that there can be only one of. */
2875 TownFlags oneof{};
2876
2878 oneof.Set(TownFlag::HasChurch);
2881 }
2882
2883 if (t->flags.Any(oneof)) continue;
2884
2885 /* Make sure there is no slope? */
2886 bool noslope = hs->building_flags.Test(BuildingFlag::NotSloped);
2887 if (noslope && slope != SLOPE_FLAT) continue;
2888
2890 if (!CheckTownBuild2x2House(&tile, t, maxz, noslope, modes)) continue;
2891 } else if (hs->building_flags.Test(BuildingFlag::Size2x1)) {
2892 if (!CheckTownBuild2House(&tile, t, maxz, noslope, DIAGDIR_SW, modes)) continue;
2893 } else if (hs->building_flags.Test(BuildingFlag::Size1x2)) {
2894 if (!CheckTownBuild2House(&tile, t, maxz, noslope, DIAGDIR_SE, modes)) continue;
2895 } else {
2896 /* 1x1 house checks are already done */
2897 }
2898
2899 uint8_t random_bits = Random();
2900
2902 uint16_t callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile, {}, true, random_bits);
2903 if (callback_res != CALLBACK_FAILED && !Convert8bitBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_ALLOW_CONSTRUCTION, callback_res)) continue;
2904 }
2905
2906 /* Special houses that there can be only one of. */
2907 t->flags.Set(oneof);
2908
2909 BuildTownHouse(t, tile, hs, house, random_bits, false, hs->extra_flags.Test(HouseExtraFlag::BuildingIsProtected));
2910
2911 return true;
2912 }
2913
2914 return false;
2915}
2916
2926CommandCost CmdPlaceHouse(DoCommandFlags flags, TileIndex tile, HouseID house, bool is_protected, bool replace)
2927{
2928 if (_game_mode != GM_EDITOR && _settings_game.economy.place_houses == PlaceHouses::Forbidden) return CMD_ERROR;
2929
2930 if (Town::GetNumItems() == 0) return CommandCost(STR_ERROR_MUST_FOUND_TOWN_FIRST);
2931
2932 if (static_cast<size_t>(house) >= HouseSpec::Specs().size()) return CMD_ERROR;
2933 const HouseSpec *hs = HouseSpec::Get(house);
2934 if (!hs->enabled) return CMD_ERROR;
2935
2936 int maxz = GetTileMaxZ(tile);
2937
2938 /* Check each tile of a multi-tile house. */
2939 TileArea ta(tile, 1, 1);
2940 if (hs->building_flags.Test(BuildingFlag::Size2x2)) ta.Add(TileAddXY(tile, 1, 1));
2943
2944 for (const TileIndex subtile : ta) {
2945 /* Houses cannot be built on steep slopes. */
2946 Slope slope = GetTileSlope(subtile);
2947 if (IsSteepSlope(slope)) return CommandCost(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
2948
2949 /* Houses cannot be built under bridges. */
2950 if (IsBridgeAbove(subtile)) return CommandCost(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
2951
2952 /* Make sure there is no slope? */
2953 bool noslope = hs->building_flags.Test(BuildingFlag::NotSloped);
2954 if (noslope && slope != SLOPE_FLAT) return CommandCost(STR_ERROR_FLAT_LAND_REQUIRED);
2955
2956 /* All tiles of a multi-tile house must have the same z-level. */
2957 if (GetTileMaxZ(subtile) != maxz) return CommandCost(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
2958
2959 /* We might be replacing an existing house, otherwise check if we can clear land. */
2960 if (!(replace && GetTileType(subtile) == TileType::House)) {
2961 CommandCost cost = Command<Commands::LandscapeClear>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, subtile);
2962 if (!cost.Succeeded()) return cost;
2963 }
2964 }
2965
2966 if (flags.Test(DoCommandFlag::Execute)) {
2967 /* If replacing, clear any existing houses first. */
2968 if (replace) {
2969 for (const TileIndex &subtile : ta) {
2970 if (GetTileType(subtile) == TileType::House) ClearTownHouse(Town::GetByTile(subtile), subtile);
2971 }
2972 }
2973
2974 Town *t = ClosestTownFromTile(tile, UINT_MAX);
2975 bool house_completed = _settings_game.economy.place_houses == PlaceHouses::AllowedConstructed;
2976 BuildTownHouse(t, tile, hs, house, Random(), house_completed, is_protected);
2977 }
2978
2979 return CommandCost();
2980}
2981
2993CommandCost CmdPlaceHouseArea(DoCommandFlags flags, TileIndex tile, TileIndex start_tile, HouseID house, bool is_protected, bool replace, bool diagonal)
2994{
2995 if (start_tile >= Map::Size()) return CMD_ERROR;
2996
2997 if (_game_mode != GM_EDITOR && _settings_game.economy.place_houses == PlaceHouses::Forbidden) return CMD_ERROR;
2998
2999 if (Town::GetNumItems() == 0) return CommandCost(STR_ERROR_MUST_FOUND_TOWN_FIRST);
3000
3001 if (static_cast<size_t>(house) >= HouseSpec::Specs().size()) return CMD_ERROR;
3002 const HouseSpec *hs = HouseSpec::Get(house);
3003 if (!hs->enabled) return CMD_ERROR;
3004
3005 /* Only allow placing an area of 1x1 houses. */
3007
3008 /* Use the built object limit to rate limit house placement. */
3010 int limit = (c == nullptr ? INT32_MAX : GB(c->build_object_limit, 16, 16));
3011
3012 CommandCost last_error = CMD_ERROR;
3013 bool had_success = false;
3014
3015 std::unique_ptr<TileIterator> iter = TileIterator::Create(tile, start_tile, diagonal);
3016 for (; *iter != INVALID_TILE; ++(*iter)) {
3017 TileIndex t = *iter;
3018 CommandCost ret = Command<Commands::PlaceHouse>::Do(DoCommandFlags{flags}.Reset(DoCommandFlag::Execute), t, house, is_protected, replace);
3019
3020 /* If we've reached the limit, stop building (or testing). */
3021 if (c != nullptr && limit-- <= 0) break;
3022
3023 if (ret.Failed()) {
3024 last_error = std::move(ret);
3025 continue;
3026 }
3027
3028 if (flags.Test(DoCommandFlag::Execute)) Command<Commands::PlaceHouse>::Do(flags, t, house, is_protected, replace);
3029 had_success = true;
3030 }
3031
3032 return had_success ? CommandCost{} : last_error;
3033}
3034
3041static void DoClearTownHouseHelper(TileIndex tile, Town *t, HouseID house)
3042{
3043 assert(IsTileType(tile, TileType::House));
3044 DecreaseBuildingCount(t, house);
3045 DoClearSquare(tile);
3046
3048}
3049
3058{
3059 if (house >= 3) { // house id 0,1,2 MUST be single tile houses, or this code breaks.
3060 if (HouseSpec::Get(house - 1)->building_flags.Test(BuildingFlag::Size2x1)) {
3061 house--;
3062 return TileDiffXY(-1, 0);
3063 } else if (HouseSpec::Get(house - 1)->building_flags.Any(BUILDING_2_TILES_Y)) {
3064 house--;
3065 return TileDiffXY(0, -1);
3066 } else if (HouseSpec::Get(house - 2)->building_flags.Any(BUILDING_HAS_4_TILES)) {
3067 house -= 2;
3068 return TileDiffXY(-1, 0);
3069 } else if (HouseSpec::Get(house - 3)->building_flags.Any(BUILDING_HAS_4_TILES)) {
3070 house -= 3;
3071 return TileDiffXY(-1, -1);
3072 }
3073 }
3074 return TileDiffXY(0, 0);
3075}
3076
3083{
3084 assert(IsTileType(tile, TileType::House));
3085
3086 HouseID house = GetHouseType(tile);
3087
3088 /* The northernmost tile of the house is the main house. */
3089 tile += GetHouseNorthPart(house);
3090
3091 const HouseSpec *hs = HouseSpec::Get(house);
3092
3093 /* Remove population from the town if the house is finished. */
3094 if (IsHouseCompleted(tile)) {
3096 }
3097
3098 t->cache.num_houses--;
3099
3100 /* Clear flags for houses that only may exist once/town. */
3105 }
3106
3107 /* Do the actual clearing of tiles */
3108 DoClearTownHouseHelper(tile, t, house);
3109 if (hs->building_flags.Any(BUILDING_2_TILES_Y)) DoClearTownHouseHelper(tile + TileDiffXY(0, 1), t, ++house);
3110 if (hs->building_flags.Any(BUILDING_2_TILES_X)) DoClearTownHouseHelper(tile + TileDiffXY(1, 0), t, ++house);
3111 if (hs->building_flags.Any(BUILDING_HAS_4_TILES)) DoClearTownHouseHelper(tile + TileDiffXY(1, 1), t, ++house);
3112
3114
3116}
3117
3125CommandCost CmdRenameTown(DoCommandFlags flags, TownID town_id, const std::string &text)
3126{
3127 Town *t = Town::GetIfValid(town_id);
3128 if (t == nullptr) return CMD_ERROR;
3129
3130 bool reset = text.empty();
3131
3132 if (!reset) {
3134 if (!IsUniqueTownName(text)) return CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE);
3135 }
3136
3137 if (flags.Test(DoCommandFlag::Execute)) {
3138 t->cached_name.clear();
3139 if (reset) {
3140 t->name.clear();
3141 } else {
3142 t->name = text;
3143 }
3144
3145 t->UpdateVirtCoord();
3146 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_RESORT);
3147 ClearAllStationCachedNames();
3148 ClearAllIndustryCachedNames();
3150 }
3151 return CommandCost();
3152}
3153
3160{
3161 for (const CargoSpec *cs : CargoSpec::Iterate()) {
3162 if (cs->town_acceptance_effect == effect) return cs;
3163 }
3164 return nullptr;
3165}
3166
3175CommandCost CmdTownCargoGoal(DoCommandFlags flags, TownID town_id, TownAcceptanceEffect tae, uint32_t goal)
3176{
3177 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3178
3179 if (tae < TownAcceptanceEffect::Begin || tae >= TownAcceptanceEffect::End) return CMD_ERROR;
3180
3181 Town *t = Town::GetIfValid(town_id);
3182 if (t == nullptr) return CMD_ERROR;
3183
3184 /* Validate if there is a cargo which is the requested TownEffect */
3186 if (cargo == nullptr) return CMD_ERROR;
3187
3188 if (flags.Test(DoCommandFlag::Execute)) {
3189 t->goal[tae] = goal;
3192 }
3193
3194 return CommandCost();
3195}
3196
3204CommandCost CmdTownSetText(DoCommandFlags flags, TownID town_id, const EncodedString &text)
3205{
3206 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3207 Town *t = Town::GetIfValid(town_id);
3208 if (t == nullptr) return CMD_ERROR;
3209
3210 if (flags.Test(DoCommandFlag::Execute)) {
3211 t->text.clear();
3212 if (!text.empty()) t->text = text;
3214 }
3215
3216 return CommandCost();
3217}
3218
3226CommandCost CmdTownGrowthRate(DoCommandFlags flags, TownID town_id, uint16_t growth_rate)
3227{
3228 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3229
3230 Town *t = Town::GetIfValid(town_id);
3231 if (t == nullptr) return CMD_ERROR;
3232
3233 if (flags.Test(DoCommandFlag::Execute)) {
3234 if (growth_rate == 0) {
3235 /* Just clear the flag, UpdateTownGrowth will determine a proper growth rate */
3237 } else {
3238 uint old_rate = t->growth_rate;
3239 if (t->grow_counter >= old_rate) {
3240 /* This also catches old_rate == 0 */
3241 t->grow_counter = growth_rate;
3242 } else {
3243 /* Scale grow_counter, so half finished houses stay half finished */
3244 t->grow_counter = t->grow_counter * growth_rate / old_rate;
3245 }
3246 t->growth_rate = growth_rate;
3248 }
3251 }
3252
3253 return CommandCost();
3254}
3255
3264CommandCost CmdTownRating(DoCommandFlags flags, TownID town_id, CompanyID company_id, int16_t rating)
3265{
3266 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3267
3268 Town *t = Town::GetIfValid(town_id);
3269 if (t == nullptr) return CMD_ERROR;
3270
3271 if (!Company::IsValidID(company_id)) return CMD_ERROR;
3272
3273 int16_t new_rating = Clamp(rating, RATING_MINIMUM, RATING_MAXIMUM);
3274 if (flags.Test(DoCommandFlag::Execute)) {
3275 t->ratings[company_id] = new_rating;
3277 }
3278
3279 return CommandCost();
3280}
3281
3290CommandCost CmdExpandTown(DoCommandFlags flags, TownID town_id, uint32_t grow_amount, TownExpandModes modes)
3291{
3292 if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY) return CMD_ERROR;
3293 if (modes.None()) return CMD_ERROR;
3294 Town *t = Town::GetIfValid(town_id);
3295 if (t == nullptr) return CMD_ERROR;
3296
3297 if (flags.Test(DoCommandFlag::Execute)) {
3298 /* The more houses, the faster we grow */
3299 if (grow_amount == 0) {
3300 uint amount = RandomRange(ClampTo<uint16_t>(t->cache.num_houses / 10)) + 3;
3301 t->cache.num_houses += amount;
3303
3304 uint n = amount * 10;
3305 do GrowTown(t, modes); while (--n);
3306
3307 t->cache.num_houses -= amount;
3308 } else {
3309 for (; grow_amount > 0; grow_amount--) {
3310 /* Try several times to grow, as we are really suppose to grow */
3311 for (uint i = 0; i < 25; i++) if (GrowTown(t, modes)) break;
3312 }
3313 }
3315
3317 }
3318
3319 return CommandCost();
3320}
3321
3328CommandCost CmdDeleteTown(DoCommandFlags flags, TownID town_id)
3329{
3330 if (_game_mode != GM_EDITOR && !_generating_world) return CMD_ERROR;
3331 Town *t = Town::GetIfValid(town_id);
3332 if (t == nullptr) return CMD_ERROR;
3333
3334 /* Stations refer to towns. */
3335 for (const Station *st : Station::Iterate()) {
3336 if (st->town == t) {
3337 /* Non-oil rig stations are always a problem. */
3338 if (!st->facilities.Test(StationFacility::Airport) || st->airport.type != AT_OILRIG) return CMD_ERROR;
3339 /* We can only automatically delete oil rigs *if* there's no vehicle on them. */
3340 CommandCost ret = Command<Commands::LandscapeClear>::Do(flags, st->airport.tile);
3341 if (ret.Failed()) return ret;
3342 }
3343 }
3344
3345 /* Waypoints refer to towns. */
3346 for (const Waypoint *wp : Waypoint::Iterate()) {
3347 if (wp->town == t) return CMD_ERROR;
3348 }
3349
3350 /* Depots refer to towns. */
3351 for (const Depot *d : Depot::Iterate()) {
3352 if (d->town == t) return CMD_ERROR;
3353 }
3354
3355 /* Check all tiles for town ownership. First check for bridge tiles, as
3356 * these do not directly have an owner so we need to check adjacent
3357 * tiles. This won't work correctly in the same loop if the adjacent
3358 * tile was already deleted earlier in the loop. */
3359 for (const auto current_tile : Map::Iterate()) {
3360 if (IsTileType(current_tile, TileType::TunnelBridge) && TestTownOwnsBridge(current_tile, t)) {
3361 CommandCost ret = Command<Commands::LandscapeClear>::Do(flags, current_tile);
3362 if (ret.Failed()) return ret;
3363 }
3364 }
3365
3366 /* Check all remaining tiles for town ownership. */
3367 for (const auto current_tile : Map::Iterate()) {
3368 bool try_clear = false;
3369 switch (GetTileType(current_tile)) {
3370 case TileType::Road:
3371 try_clear = HasTownOwnedRoad(current_tile) && GetTownIndex(current_tile) == t->index;
3372 break;
3373
3374 case TileType::House:
3375 try_clear = GetTownIndex(current_tile) == t->index;
3376 break;
3377
3378 case TileType::Industry:
3379 try_clear = Industry::GetByTile(current_tile)->town == t;
3380 break;
3381
3382 case TileType::Object:
3383 if (Town::GetNumItems() == 1) {
3384 /* No towns will be left, remove it! */
3385 try_clear = true;
3386 } else {
3387 Object *o = Object::GetByTile(current_tile);
3388 if (o->town == t) {
3389 if (o->type == OBJECT_STATUE) {
3390 /* Statue... always remove. */
3391 try_clear = true;
3392 } else {
3393 /* Tell to find a new town. */
3394 if (flags.Test(DoCommandFlag::Execute)) o->town = nullptr;
3395 }
3396 }
3397 }
3398 break;
3399
3400 default:
3401 break;
3402 }
3403 if (try_clear) {
3404 CommandCost ret = Command<Commands::LandscapeClear>::Do(flags, current_tile);
3405 if (ret.Failed()) return ret;
3406 }
3407 }
3408
3409 /* The town destructor will delete the other things related to the town. */
3410 if (flags.Test(DoCommandFlag::Execute)) {
3411 _town_kdtree.Remove(t->index);
3412 if (t->cache.sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeTown(t->index));
3413 delete t;
3414 }
3415
3416 return CommandCost();
3417}
3418
3425{
3430 static const uint8_t town_action_costs[] = {
3431 2, 4, 9, 35, 48, 53, 117, 175
3432 };
3433 static_assert(std::size(town_action_costs) == to_underlying(TownAction::End));
3434
3435 assert(to_underlying(action) < std::size(town_action_costs));
3436 return town_action_costs[to_underlying(action)];
3437}
3438
3445static CommandCost TownActionAdvertiseSmall(Town *t, DoCommandFlags flags)
3446{
3447 if (flags.Test(DoCommandFlag::Execute)) {
3449 }
3450 return CommandCost();
3451}
3452
3459static CommandCost TownActionAdvertiseMedium(Town *t, DoCommandFlags flags)
3460{
3461 if (flags.Test(DoCommandFlag::Execute)) {
3463 }
3464 return CommandCost();
3465}
3466
3473static CommandCost TownActionAdvertiseLarge(Town *t, DoCommandFlags flags)
3474{
3475 if (flags.Test(DoCommandFlag::Execute)) {
3477 }
3478 return CommandCost();
3479}
3480
3487static CommandCost TownActionRoadRebuild(Town *t, DoCommandFlags flags)
3488{
3489 /* Check if the company is allowed to fund new roads. */
3490 if (!_settings_game.economy.fund_roads) return CMD_ERROR;
3491
3492 if (flags.Test(DoCommandFlag::Execute)) {
3493 t->road_build_months = 6;
3494
3495 std::string company_name = GetString(STR_COMPANY_NAME, _current_company);
3496
3498 GetEncodedString(TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_ROAD_REBUILDING_MINUTES : STR_NEWS_ROAD_REBUILDING_MONTHS, t->index, company_name),
3499 NewsType::General, NewsStyle::Normal, {}, t->index);
3500 AI::BroadcastNewEvent(new ScriptEventRoadReconstruction(_current_company, t->index));
3501 Game::NewEvent(new ScriptEventRoadReconstruction(_current_company, t->index));
3502 }
3503 return CommandCost();
3504}
3505
3511static bool CheckClearTile(TileIndex tile)
3512{
3514 return Command<Commands::LandscapeClear>::Do({}, tile).Succeeded();
3515}
3516
3524static CommandCost TownActionBuildStatue(Town *t, DoCommandFlags flags)
3525{
3526 if (!Object::CanAllocateItem()) return CommandCost(STR_ERROR_TOO_MANY_OBJECTS);
3527
3528 static const int STATUE_NUMBER_INNER_TILES = 25; // Number of tiles int the center of the city, where we try to protect houses.
3529
3530 TileIndex best_position = INVALID_TILE;
3531 uint tile_count = 0;
3532 for (auto tile : SpiralTileSequence(t->xy, 9)) {
3533 tile_count++;
3534
3535 /* Statues can be build on slopes, just like houses. Only the steep slopes is a no go. */
3536 if (IsSteepSlope(GetTileSlope(tile))) continue;
3537 /* Don't build statues under bridges. */
3538 if (IsBridgeAbove(tile)) continue;
3539
3540 /* A clear-able open space is always preferred. */
3541 if ((IsTileType(tile, TileType::Clear) || IsTileType(tile, TileType::Trees)) && CheckClearTile(tile)) {
3542 best_position = tile;
3543 break;
3544 }
3545
3546 bool house = IsTileType(tile, TileType::House);
3547
3548 /* Searching inside the inner circle. */
3549 if (tile_count <= STATUE_NUMBER_INNER_TILES) {
3550 /* Save first house in inner circle. */
3551 if (house && best_position == INVALID_TILE && CheckClearTile(tile)) {
3552 best_position = tile;
3553 }
3554
3555 /* If we have reached the end of the inner circle, and have a saved house, terminate the search. */
3556 if (tile_count == STATUE_NUMBER_INNER_TILES && best_position != INVALID_TILE) break;
3557 }
3558
3559 /* Searching outside the circle, just pick the first possible spot. */
3560 if (!house || !CheckClearTile(tile)) continue;
3561 best_position = tile;
3562 break;
3563 }
3564 if (best_position == INVALID_TILE) return CommandCost(STR_ERROR_STATUE_NO_SUITABLE_PLACE);
3565
3566 if (flags.Test(DoCommandFlag::Execute)) {
3568 Command<Commands::LandscapeClear>::Do(DoCommandFlag::Execute, best_position);
3569 cur_company.Restore();
3570 BuildObject(OBJECT_STATUE, best_position, _current_company, t);
3571 t->statues.Set(_current_company); // Once found and built, "inform" the Town.
3572 MarkTileDirtyByTile(best_position);
3573 }
3574 return CommandCost();
3575}
3576
3583static CommandCost TownActionFundBuildings(Town *t, DoCommandFlags flags)
3584{
3585 /* Check if it's allowed to buy the rights */
3586 if (!_settings_game.economy.fund_buildings) return CMD_ERROR;
3587
3588 if (flags.Test(DoCommandFlag::Execute)) {
3589 /* And grow for 3 months */
3590 t->fund_buildings_months = 3;
3591
3592 /* Enable growth (also checking GameScript's opinion) */
3594
3595 /* Build a new house, but add a small delay to make sure
3596 * that spamming funding doesn't let town grow any faster
3597 * than 1 house per 2 * TOWN_GROWTH_TICKS ticks.
3598 * Also emulate original behaviour when town was only growing in
3599 * TOWN_GROWTH_TICKS intervals, to make sure that it's not too
3600 * tick-perfect and gives player some time window where they can
3601 * spam funding with the exact same efficiency.
3602 */
3604
3605 SetWindowDirty(WC_TOWN_VIEW, t->index);
3606 }
3607 return CommandCost();
3608}
3609
3616static CommandCost TownActionBuyRights(Town *t, DoCommandFlags flags)
3617{
3618 /* Check if it's allowed to buy the rights */
3619 if (!_settings_game.economy.exclusive_rights) return CMD_ERROR;
3620 if (t->exclusivity != CompanyID::Invalid()) return CMD_ERROR;
3621
3622 if (flags.Test(DoCommandFlag::Execute)) {
3623 t->exclusive_counter = 12;
3625
3627
3629
3630 /* Spawn news message */
3631 auto cni = std::make_unique<CompanyNewsInformation>(STR_NEWS_EXCLUSIVE_RIGHTS_TITLE, Company::Get(_current_company));
3632 EncodedString message = GetEncodedString(TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MINUTES : STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MONTHS, t->index, cni->company_name);
3633 AddNewsItem(std::move(message),
3634 NewsType::General, NewsStyle::Company, {}, t->index, {}, std::move(cni));
3635 AI::BroadcastNewEvent(new ScriptEventExclusiveTransportRights(_current_company, t->index));
3636 Game::NewEvent(new ScriptEventExclusiveTransportRights(_current_company, t->index));
3637 }
3638 return CommandCost();
3639}
3640
3647static CommandCost TownActionBribe(Town *t, DoCommandFlags flags)
3648{
3649 if (flags.Test(DoCommandFlag::Execute)) {
3650 if (Chance16(1, 14)) {
3651 /* set as unwanted for 6 months */
3652 t->unwanted[_current_company] = 6;
3653
3654 /* set all close by station ratings to 0 */
3655 for (Station *st : Station::Iterate()) {
3656 if (st->town == t && st->owner == _current_company) {
3657 for (GoodsEntry &ge : st->goods) ge.rating = 0;
3658 }
3659 }
3660
3661 /* only show error message to the executing player. All errors are handled command.c
3662 * but this is special, because it can only 'fail' on a DoCommandFlag::Execute */
3663 if (IsLocalCompany()) ShowErrorMessage(GetEncodedString(STR_ERROR_BRIBE_FAILED), {}, WL_INFO);
3664
3665 /* decrease by a lot!
3666 * ChangeTownRating is only for stuff in demolishing. Bribe failure should
3667 * be independent of any cheat settings
3668 */
3669 if (t->ratings[_current_company] > RATING_BRIBE_DOWN_TO) {
3670 t->ratings[_current_company] = RATING_BRIBE_DOWN_TO;
3672 }
3673 } else {
3674 ChangeTownRating(t, RATING_BRIBE_UP_STEP, RATING_BRIBE_MAXIMUM, DoCommandFlag::Execute);
3675 if (t->exclusivity != _current_company && t->exclusivity != CompanyID::Invalid()) {
3676 t->exclusivity = CompanyID::Invalid();
3677 t->exclusive_counter = 0;
3678 }
3679 }
3680 }
3681 return CommandCost();
3682}
3683
3684typedef CommandCost TownActionProc(Town *t, DoCommandFlags flags);
3685static TownActionProc * const _town_action_proc[] = {
3694};
3695static_assert(std::size(_town_action_proc) == to_underlying(TownAction::End));
3696
3703TownActions GetMaskOfTownActions(CompanyID cid, const Town *t)
3704{
3705 TownActions buttons{};
3706
3707 /* Spectators and unwanted have no options */
3708 if (cid != COMPANY_SPECTATOR && !(_settings_game.economy.bribe && t->unwanted[cid])) {
3709
3710 /* Actions worth more than this are not able to be performed */
3711 Money avail = GetAvailableMoney(cid);
3712
3713 /* Check the action bits for validity and
3714 * if they are valid add them */
3715 for (TownAction cur = {}; cur != TownAction::End; ++cur) {
3716
3717 /* Is the company prohibited from bribing ? */
3718 if (cur == TownAction::Bribe) {
3719 /* Company can't bribe if setting is disabled */
3720 if (!_settings_game.economy.bribe) continue;
3721 /* Company can bribe if another company has exclusive transport rights,
3722 * or its standing with the town is less than outstanding. */
3723 if (t->ratings[cid] >= RATING_BRIBE_MAXIMUM) {
3724 if (t->exclusivity == _current_company) continue;
3725 if (t->exclusive_counter == 0) continue;
3726 }
3727 }
3728
3729 /* Is the company not able to buy exclusive rights ? */
3730 if (cur == TownAction::BuyRights && (!_settings_game.economy.exclusive_rights || t->exclusive_counter != 0)) continue;
3731
3732 /* Is the company not able to fund buildings ? */
3733 if (cur == TownAction::FundBuildings && !_settings_game.economy.fund_buildings) continue;
3734
3735 /* Is the company not able to fund local road reconstruction? */
3736 if (cur == TownAction::RoadRebuild && !_settings_game.economy.fund_roads) continue;
3737
3738 /* Is the company not able to build a statue ? */
3739 if (cur == TownAction::BuildStatue && t->statues.Test(cid)) continue;
3740
3741 if (avail >= GetTownActionCost(cur) * _price[Price::TownAction] >> 8) {
3742 buttons.Set(cur);
3743 }
3744 }
3745 }
3746
3747 return buttons;
3748}
3749
3759CommandCost CmdDoTownAction(DoCommandFlags flags, TownID town_id, TownAction action)
3760{
3761 Town *t = Town::GetIfValid(town_id);
3762 if (t == nullptr || to_underlying(action) >= std::size(_town_action_proc)) return CMD_ERROR;
3763
3764 if (!GetMaskOfTownActions(_current_company, t).Test(action)) return CMD_ERROR;
3765
3767
3768 CommandCost ret = _town_action_proc[to_underlying(action)](t, flags);
3769 if (ret.Failed()) return ret;
3770
3771 if (flags.Test(DoCommandFlag::Execute)) {
3773 }
3774
3775 return cost;
3776}
3777
3778template <typename Func>
3779static void ForAllStationsNearTown(Town *t, Func func)
3780{
3781 /* Ideally the search radius should be close to the actual town zone 0 radius.
3782 * The true radius is not stored or calculated anywhere, only the squared radius. */
3783 /* The efficiency of this search might be improved for large towns and many stations on the map,
3784 * by using an integer square root approximation giving a value not less than the true square root. */
3786 ForAllStationsRadius(t->xy, search_radius, [&](const Station * st) {
3787 if (DistanceSquare(st->xy, t->xy) <= t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownEdge)]) {
3788 func(st);
3789 }
3790 });
3791}
3792
3797static void UpdateTownRating(Town *t)
3798{
3799 /* Increase company ratings if they're low */
3800 for (const Company *c : Company::Iterate()) {
3801 if (t->ratings[c->index] < RATING_GROWTH_MAXIMUM) {
3802 t->ratings[c->index] = std::min((int)RATING_GROWTH_MAXIMUM, t->ratings[c->index] + RATING_GROWTH_UP_STEP);
3803 }
3804 }
3805
3806 ForAllStationsNearTown(t, [&](const Station *st) {
3807 if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
3808 if (Company::IsValidID(st->owner)) {
3809 int new_rating = t->ratings[st->owner] + RATING_STATION_UP_STEP;
3810 t->ratings[st->owner] = std::min<int>(new_rating, INT16_MAX); // do not let it overflow
3811 }
3812 } else {
3813 if (Company::IsValidID(st->owner)) {
3814 int new_rating = t->ratings[st->owner] + RATING_STATION_DOWN_STEP;
3815 t->ratings[st->owner] = std::max(new_rating, INT16_MIN);
3816 }
3817 }
3818 });
3819
3820 /* clamp all ratings to valid values */
3821 for (auto it = t->ratings.begin(); it != t->ratings.end(); ++it) {
3822 *it = Clamp(*it, RATING_MINIMUM, RATING_MAXIMUM);
3823 }
3824
3826}
3827
3828
3835static void UpdateTownGrowCounter(Town *t, uint16_t prev_growth_rate)
3836{
3837 if (t->growth_rate == TOWN_GROWTH_RATE_NONE) return;
3838 if (prev_growth_rate == TOWN_GROWTH_RATE_NONE) {
3839 t->grow_counter = std::min<uint16_t>(t->growth_rate, t->grow_counter);
3840 return;
3841 }
3842 t->grow_counter = RoundDivSU((uint32_t)t->grow_counter * (t->growth_rate + 1), prev_growth_rate + 1);
3843}
3844
3851{
3852 int n = 0;
3853 ForAllStationsNearTown(t, [&](const Station * st) {
3854 if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
3855 n++;
3856 }
3857 });
3858 return n;
3859}
3860
3868{
3874 static const uint16_t _grow_count_values[2][6] = {
3875 { 120, 120, 120, 100, 80, 60 }, // Fund new buildings has been activated
3876 { 320, 420, 300, 220, 160, 100 } // Normal values
3877 };
3878
3879 int n = CountActiveStations(t);
3880 uint16_t m = _grow_count_values[t->fund_buildings_months != 0 ? 0 : 1][std::min(n, 5)];
3881
3882 uint growth_multiplier = _settings_game.economy.town_growth_rate != 0 ? _settings_game.economy.town_growth_rate - 1 : 1;
3883
3884 m >>= growth_multiplier;
3885 if (t->larger_town) m /= 2;
3886
3887 return TownTicksToGameTicks(m / (t->cache.num_houses / 50 + 1));
3888}
3889
3895{
3896 if (t->flags.Test(TownFlag::CustomGrowth)) return;
3897 uint old_rate = t->growth_rate;
3899 UpdateTownGrowCounter(t, old_rate);
3900 SetWindowDirty(WC_TOWN_VIEW, t->index);
3901}
3902
3907static void UpdateTownGrowth(Town *t)
3908{
3910
3912 SetWindowDirty(WC_TOWN_VIEW, t->index);
3913
3914 if (_settings_game.economy.town_growth_rate == 0 && t->fund_buildings_months == 0) return;
3915
3916 if (t->fund_buildings_months == 0) {
3917 /* Check if all goals are reached for this town to grow (given we are not funding it) */
3919 switch (t->goal[i]) {
3920 case TOWN_GROWTH_WINTER:
3921 if (TileHeight(t->xy) >= GetSnowLine() && t->received[i].old_act == 0 && t->cache.population > 90) return;
3922 break;
3923 case TOWN_GROWTH_DESERT:
3924 if (GetTropicZone(t->xy) == TropicZone::Desert && t->received[i].old_act == 0 && t->cache.population > 60) return;
3925 break;
3926 default:
3927 if (t->goal[i] > t->received[i].old_act) return;
3928 break;
3929 }
3930 }
3931 }
3932
3935 SetWindowDirty(WC_TOWN_VIEW, t->index);
3936 return;
3937 }
3938
3939 if (t->fund_buildings_months == 0 && CountActiveStations(t) == 0 && !Chance16(1, 12)) return;
3940
3942 SetWindowDirty(WC_TOWN_VIEW, t->index);
3943}
3944
3952{
3953 /* The required rating is hardcoded to RATING_VERYPOOR (see below), not the authority attitude setting, so we can bail out like this. */
3954 if (_settings_game.difficulty.town_council_tolerance == TOWN_COUNCIL_PERMISSIVE) return CommandCost();
3955
3957
3958 Town *t = ClosestTownFromTile(tile, _settings_game.economy.dist_local_authority);
3959 if (t == nullptr) return CommandCost();
3960
3961 if (t->ratings[_current_company] > RATING_VERYPOOR) return CommandCost();
3962
3963 return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index);
3964}
3965
3975{
3976 if (Town::GetNumItems() == 0) return nullptr;
3977
3978 TownID tid = _town_kdtree.FindNearest(TileX(tile), TileY(tile));
3979 Town *town = Town::Get(tid);
3980 if (DistanceManhattan(tile, town->xy) < threshold) return town;
3981 return nullptr;
3982}
3983
3992Town *ClosestTownFromTile(TileIndex tile, uint threshold)
3993{
3994 switch (GetTileType(tile)) {
3995 case TileType::Road:
3996 if (IsRoadDepot(tile)) return CalcClosestTownFromTile(tile, threshold);
3997
3998 if (!HasTownOwnedRoad(tile)) {
3999 TownID tid = GetTownIndex(tile);
4000
4001 if (tid == TownID::Invalid()) {
4002 /* in the case we are generating "many random towns", this value may be TownID::Invalid() */
4003 if (_generating_world) return CalcClosestTownFromTile(tile, threshold);
4004 assert(Town::GetNumItems() == 0);
4005 return nullptr;
4006 }
4007
4008 assert(Town::IsValidID(tid));
4009 Town *town = Town::Get(tid);
4010
4011 if (DistanceManhattan(tile, town->xy) >= threshold) town = nullptr;
4012
4013 return town;
4014 }
4015 [[fallthrough]];
4016
4017 case TileType::House:
4018 return Town::GetByTile(tile);
4019
4020 default:
4021 return CalcClosestTownFromTile(tile, threshold);
4022 }
4023}
4024
4025static bool _town_rating_test = false;
4026static std::map<const Town *, int> _town_test_ratings;
4027
4034{
4035 static int ref_count = 0; // Number of times test-mode is switched on.
4036 if (mode) {
4037 if (ref_count == 0) {
4038 _town_test_ratings.clear();
4039 }
4040 ref_count++;
4041 } else {
4042 assert(ref_count > 0);
4043 ref_count--;
4044 }
4045 _town_rating_test = !(ref_count == 0);
4046}
4047
4053static int GetRating(const Town *t)
4054{
4055 if (_town_rating_test) {
4056 auto it = _town_test_ratings.find(t);
4057 if (it != _town_test_ratings.end()) {
4058 return it->second;
4059 }
4060 }
4061 return t->ratings[_current_company];
4062}
4063
4071void ChangeTownRating(Town *t, int add, int max, DoCommandFlags flags)
4072{
4073 /* if magic_bulldozer cheat is active, town doesn't penalize for removing stuff */
4074 if (t == nullptr || flags.Test(DoCommandFlag::NoModifyTownRating) ||
4076 (_cheats.magic_bulldozer.value && add < 0)) {
4077 return;
4078 }
4079
4080 int rating = GetRating(t);
4081 if (add < 0) {
4082 if (rating > max) {
4083 rating += add;
4084 if (rating < max) rating = max;
4085 }
4086 } else {
4087 if (rating < max) {
4088 rating += add;
4089 if (rating > max) rating = max;
4090 }
4091 }
4092 if (_town_rating_test) {
4093 _town_test_ratings[t] = rating;
4094 } else {
4096 t->ratings[_current_company] = rating;
4098 }
4099}
4100
4109{
4110 /* if magic_bulldozer cheat is active, town doesn't restrict your destructive actions */
4111 if (t == nullptr || !Company::IsValidID(_current_company) ||
4112 _cheats.magic_bulldozer.value || flags.Test(DoCommandFlag::NoTestTownRating)) {
4113 return CommandCost();
4114 }
4115
4116 /* minimum rating needed to be allowed to remove stuff */
4117 static const int needed_rating[][to_underlying(TownRatingCheckType::End)] = {
4118 /* RoadRemove, TunnelBridgeRemove */
4123 };
4124
4125 /* check if you're allowed to remove the road/bridge/tunnel
4126 * owned by a town no removal if rating is lower than ... depends now on
4127 * difficulty setting. Minimum town rating selected by difficulty level
4128 */
4129 int needed = needed_rating[_settings_game.difficulty.town_council_tolerance][to_underlying(type)];
4130
4131 if (GetRating(t) < needed) {
4132 return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index);
4133 }
4134
4135 return CommandCost();
4136}
4137
4143template <>
4144Town::SuppliedHistory SumHistory(std::span<const Town::SuppliedHistory> history)
4145{
4146 uint64_t production = std::accumulate(std::begin(history), std::end(history), 0, [](uint64_t r, const auto &s) { return r + s.production; });
4147 uint64_t transported = std::accumulate(std::begin(history), std::end(history), 0, [](uint64_t r, const auto &s) { return r + s.transported; });
4148 auto count = std::size(history);
4149 return {.production = ClampTo<uint32_t>(production / count), .transported = ClampTo<uint32_t>(transported / count)};
4150}
4151
4157template <>
4158Town::AcceptedHistory SumHistory(std::span<const Town::AcceptedHistory> history)
4159{
4160 uint64_t accepted = std::accumulate(std::begin(history), std::end(history), 0, [](uint64_t r, const auto &s) { return r + s.accepted; });
4161 auto count = std::size(history);
4162 return {.accepted = ClampTo<uint32_t>(accepted / count)};
4163}
4164
4166static const IntervalTimer<TimerGameEconomy> _economy_towns_monthly({TimerGameEconomy::Trigger::Month, TimerGameEconomy::Priority::Town}, [](auto)
4167{
4168 for (Town *t : Town::Iterate()) {
4169 /* Check for active town actions and decrement their counters. */
4170 if (t->road_build_months != 0) t->road_build_months--;
4171 if (t->fund_buildings_months != 0) t->fund_buildings_months--;
4172
4173 if (t->exclusive_counter != 0) {
4174 if (--t->exclusive_counter == 0) t->exclusivity = CompanyID::Invalid();
4175 }
4176
4177 /* Check for active failed bribe cooloff periods and decrement them. */
4178 for (const Company *c : Company::Iterate()) {
4179 if (t->unwanted[c->index] > 0) t->unwanted[c->index]--;
4180 }
4181
4182 UpdateValidHistory(t->valid_history, HISTORY_YEAR, TimerGameEconomy::month);
4183
4184 /* Update cargo statistics. */
4185 for (auto &s : t->supplied) RotateHistory(s.history, t->valid_history, HISTORY_YEAR, TimerGameEconomy::month);
4186 for (auto &a : t->accepted) RotateHistory(a.history, t->valid_history, HISTORY_YEAR, TimerGameEconomy::month);
4187 for (auto &received : t->received) received.NewMonth();
4188
4191
4192 SetWindowDirty(WC_TOWN_VIEW, t->index);
4193 }
4194});
4195
4196static const IntervalTimer<TimerGameEconomy> _economy_towns_yearly({TimerGameEconomy::Trigger::Year, TimerGameEconomy::Priority::Town}, [](auto)
4197{
4198 /* Increment house ages */
4199 for (const auto t : Map::Iterate()) {
4200 if (!IsTileType(t, TileType::House)) continue;
4202 }
4203});
4204
4206static CommandCost TerraformTile_Town(TileIndex tile, DoCommandFlags flags, int z_new, Slope tileh_new)
4207{
4208 if (AutoslopeEnabled()) {
4209 HouseID house = GetHouseType(tile);
4210 GetHouseNorthPart(house); // modifies house to the ID of the north tile
4211 const HouseSpec *hs = HouseSpec::Get(house);
4212
4213 /* Here we differ from TTDP by checking BuildingFlag::NotSloped */
4214 if (!hs->building_flags.Test(BuildingFlag::NotSloped) && !IsSteepSlope(tileh_new) &&
4215 (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) {
4216 bool allow_terraform = true;
4217
4218 /* Call the autosloping callback per tile, not for the whole building at once. */
4219 house = GetHouseType(tile);
4220 hs = HouseSpec::Get(house);
4222 /* If the callback fails, allow autoslope. */
4223 uint16_t res = GetHouseCallback(CBID_HOUSE_AUTOSLOPE, 0, 0, house, Town::GetByTile(tile), tile);
4224 if (res != CALLBACK_FAILED && ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_AUTOSLOPE, res)) allow_terraform = false;
4225 }
4226
4228 }
4229 }
4230
4231 return Command<Commands::LandscapeClear>::Do(flags, tile);
4232}
4233
4235extern const TileTypeProcs _tile_type_town_procs = {
4236 .draw_tile_proc = DrawTile_Town,
4237 .get_slope_pixel_z_proc = [](TileIndex tile, uint, uint, bool) { return GetTileMaxPixelZ(tile); },
4238 .clear_tile_proc = ClearTile_Town,
4239 .add_accepted_cargo_proc = AddAcceptedCargo_Town,
4240 .get_tile_desc_proc = GetTileDesc_Town,
4241 .animate_tile_proc = AnimateTile_Town,
4242 .tile_loop_proc = TileLoop_Town,
4243 .add_produced_cargo_proc = AddProducedCargo_Town,
4244 .get_foundation_proc = GetFoundation_Town,
4245 .terraform_tile_proc = TerraformTile_Town,
4246};
4247
4248std::span<const DrawBuildingsTileStruct> GetTownDrawTileData()
4249{
4250 return _town_draw_tile_data;
4251}
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
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
@ Begin
Used for iteration.
Definition cargotype.h:23
@ 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:240
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.
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:140
RoadTypeFlags flags
Bit mask of road type flags.
Definition road.h:101
uint16_t max_speed
Maximum speed for vehicles travelling on this road type.
Definition road.h:116
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.
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
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.
@ DIR_N
North.
@ DIR_S
South.
@ DIR_W
West.
@ DIR_E
East.
@ DIAGDIRDIFF_90RIGHT
90 degrees right
@ DIAGDIRDIFF_90LEFT
90 degrees left
DiagDirection
Enumeration for diagonal directions.
@ DIAGDIR_NW
Northwest.
@ DIAGDIR_SE
Southeast.
@ DIAGDIR_END
Used for iterations.
@ DIAGDIR_BEGIN
Used for iterations.
@ DIAGDIR_SW
Southwest.
Prices _price
Prices and also the fractional part.
Definition economy.cpp:106
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
Functions related to errors.
@ WL_CRITICAL
Critical errors, the MessageBox is shown in all cases.
Definition error.h:27
@ WL_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.
@ GWP_TOWN
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:1554
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_height_override)
Mark a tile given by its index dirty for repaint.
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:93
@ BuildingIsProtected
towns and AI will not remove this house, while human players will be able to
Definition house.h:94
@ 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
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:57
@ TownOuterSuburb
Outer suburbs; roads with pavement.
Definition house.h:60
@ ClimateSubarcticAboveSnow
Building can appear in sub-arctic climate above the snow line.
Definition house.h:65
@ ClimateSubarcticBelowSnow
Building can appear in sub-arctic climate below the snow line.
Definition house.h:67
@ TownInnerSuburb
Inner suburbs; roads with pavement and trees.
Definition house.h:61
@ TownOutskirt
Outskirts of a town; roads without pavement.
Definition house.h:59
@ TownEdge
Edge of the town; roads without pavement.
Definition house.h:58
@ TownCentre
Centre of town; roads with pavement and streetlights.
Definition house.h:62
@ ClimateTemperate
Building can appear in temperate climate.
Definition house.h:66
@ ClimateToyland
Building can appear in toyland climate.
Definition house.h:69
@ ClimateSubtropic
Building can appear in subtropical climate.
Definition house.h:68
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:98
@ Houses
Houses feature.
Definition newgrf.h:80
@ 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.
void ErrorUnknownCallbackResult(uint32_t grfid, uint16_t cbid, uint16_t cb_res)
Record that a NewGRF returned an unknown/invalid callback result.
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.
GRFConfig * GetGRFConfig(uint32_t 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(uint32_t 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:919
@ 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
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:32
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:183
const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
Definition road.h:215
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:96
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:576
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:72
static constexpr RoadBits ROAD_X
Full road along the x-axis (south-west + north-east).
Definition road_type.h:66
EnumBitSet< RoadBit, uint8_t > RoadBits
Bitset of RoadBit elements.
Definition road_type.h:64
static constexpr RoadBits ROAD_E
Road at the two eastern edges.
Definition road_type.h:70
@ SW
South-west part.
Definition road_type.h:58
@ NW
North-west part.
Definition road_type.h:57
@ NE
North-east part.
Definition road_type.h:60
@ SE
South-east part.
Definition road_type.h:59
static constexpr RoadBits ROAD_ALL
Full 4-way crossing.
Definition road_type.h:74
static constexpr RoadBits ROAD_Y
Full road along the y-axis (north-west + south-east).
Definition road_type.h:67
static constexpr RoadBits ROAD_N
Road at the two northern edges.
Definition road_type.h:69
RoadType
The different roadtypes we support.
Definition road_type.h:23
@ INVALID_ROADTYPE
flag for invalid roadtype
Definition road_type.h:28
@ ROADTYPE_ROAD
Basic road type.
Definition road_type.h:25
static constexpr RoadBits ROAD_S
Road at the two southern edges.
Definition road_type.h:71
@ Road
Road type.
Definition road_type.h:38
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:160
bool IsSlopeWithOneCornerRaised(Slope s)
Tests if a specific slope has exactly one corner raised.
Definition slope_func.h:88
static constexpr bool IsSteepSlope(Slope s)
Checks if a slope is steep.
Definition slope_func.h:36
Foundation FlatteningFoundation(Slope s)
Returns the foundation needed to flatten a slope.
Definition slope_func.h:369
Slope InclinedSlope(DiagDirection dir)
Returns the slope that is inclined in a specific direction.
Definition slope_func.h:256
Slope ComplementSlope(Slope s)
Return the complement of a slope.
Definition slope_func.h:76
Slope
Enumeration for the slope-type.
Definition slope_type.h:47
@ SLOPE_W
the west corner of the tile is raised
Definition slope_type.h:49
@ SLOPE_ELEVATED
bit mask containing all 'simple' slopes
Definition slope_type.h:60
@ SLOPE_E
the east corner of the tile is raised
Definition slope_type.h:51
@ SLOPE_S
the south corner of the tile is raised
Definition slope_type.h:50
@ SLOPE_N
the north corner of the tile is raised
Definition slope_type.h:52
@ SLOPE_SW
south and west corner are raised
Definition slope_type.h:55
@ SLOPE_FLAT
a flat tile
Definition slope_type.h:48
@ SLOPE_STEEP_W
a steep slope falling to east (from west)
Definition slope_type.h:65
@ SLOPE_NE
north and east corner are raised
Definition slope_type.h:57
@ SLOPE_STEEP_E
a steep slope falling to west (from east)
Definition slope_type.h:67
@ SLOPE_SE
south and east corner are raised
Definition slope_type.h:56
@ SLOPE_NW
north and west corner are raised
Definition slope_type.h:54
@ SLOPE_STEEP_N
a steep slope falling to south (from north)
Definition slope_type.h:68
@ SLOPE_STEEP_S
a steep slope falling to north (from south)
Definition slope_type.h:66
Foundation
Enumeration for Foundations.
Definition slope_type.h:92
@ FOUNDATION_LEVELED
The tile is leveled up to a flat slope.
Definition slope_type.h:94
@ FOUNDATION_NONE
The tile has no foundation, the slope remains unchanged.
Definition slope_type.h:93
@ 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:271
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.
uint32_t 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:117
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:75
static EnumIndexArray< std::vector< const CargoSpec * >, TownProductionEffect, TownProductionEffect::End > town_production_cargoes
List of cargo specs for each Town Product Effect.
Definition cargotype.h:195
static IterateWrapper Iterate(size_t from=0)
Returns an iterable ensemble of all valid CargoSpec.
Definition cargotype.h:192
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.
const struct GRFFile * grffile
grf file that introduced this entity
uint32_t grfid
grfid 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:110
SubstituteGRFFileProps grf_prop
Properties related the the grf file.
Definition house.h:116
uint8_t removal_cost
cost multiplier for removing it
Definition house.h:105
uint8_t mail_generation
mail generation multiplier (tile based, as the acceptances below)
Definition house.h:108
bool enabled
the house is available to build (true by default, but can be disabled by newgrf)
Definition house.h:113
Money GetRemovalCost() const
Get the cost for removing this house.
Definition town_cmd.cpp:233
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:111
TimerGameCalendar::Year max_year
last year it can be built
Definition house.h:103
HouseCallbackMasks callback_mask
Bitmask of house callbacks that have to be called.
Definition house.h:117
uint16_t remove_rating_decrease
rating decrease if removed
Definition house.h:107
uint8_t population
population (Zero on other tiles in multi tile house.)
Definition house.h:104
HouseExtraFlags extra_flags
some more flags
Definition house.h:120
uint8_t cargo_acceptance[HOUSE_NUM_ACCEPTS]
acceptance level for the cargo slots
Definition house.h:109
HouseID Index() const
Gets the index of this spec.
StringID building_name
building name
Definition house.h:106
uint8_t minimum_life
The minimum number of years this house will survive before the town rebuilds it.
Definition house.h:124
static std::vector< HouseSpec > & Specs()
Get a reference to all HouseSpecs.
Defines the internal data of a functional industry.
Definition industry.h:62
Town * town
Nearest town.
Definition industry.h:107
static Industry * GetByTile(TileIndex tile)
Get the industry of the given tile.
Definition industry.h:251
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 Town * Get(auto index)
static bool CanAllocateItem(size_t n=1)
static bool IsValidID(auto index)
static T * Create(Targs &&... args)
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:39
std::optional< std::string > grf
newGRF used for the tile contents
Definition tile_cmd.h:50
StringID str
Description of the tile.
Definition tile_cmd.h:40
std::array< Owner, 4 > owner
Name of the owner(s).
Definition tile_cmd.h:42
uint64_t dparam
Parameter of the str string.
Definition tile_cmd.h:41
std::optional< bool > town_can_upgrade
Whether the town can upgrade this house during town growth.
Definition tile_cmd.h:57
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:33
Slope tileh
Slope of the tile.
Definition tile_cmd.h:34
TileIndex tile
Tile index.
Definition tile_cmd.h:35
Set of callback functions for performing tile operations of a given tile type.
Definition tile_cmd.h:213
uint32_t population
Current population of people.
Definition town.h:53
uint32_t num_houses
Amount of houses.
Definition town.h:52
TrackedViewportSign sign
Location of name sign, UpdateVirtCoord updates this.
Definition town.h:54
BuildingCounts< uint16_t > building_counts
The number of each type of building in the town.
Definition town.h:57
std::array< uint32_t, NUM_HOUSE_ZONES > squared_town_zone_radius
UpdateTownRadius updates this given the house count.
Definition town.h:56
Struct holding parameters used to generate town name.
uint16_t type
town name style
uint32_t grfid
newgrf ID (0 if not used)
Individual data point for accepted cargo history.
Definition town.h:110
Town data structure.
Definition town.h:63
EncodedString text
General text with additional information.
Definition town.h:136
bool larger_town
if this is a larger town and should grow more quickly
Definition town.h:198
CompanyMask statues
which companies have a statue?
Definition town.h:81
uint16_t time_until_rebuild
time until we rebuild a house
Definition town.h:190
std::string cached_name
NOSAVE: Cache of the resolved name of the town, if not using a custom town name.
Definition town.h:74
TileIndex xy
town center tile
Definition town.h:64
uint8_t fund_buildings_months
fund buildings program in action?
Definition town.h:195
TownLayout layout
town specific road layout
Definition town.h:199
static Town * GetRandom()
Return a random valid town.
Definition town_cmd.cpp:204
std::string name
Custom town name. If empty, the town was not renamed and uses the generated name.
Definition town.h:73
Town(TownID index, TileIndex tile=INVALID_TILE)
Creates a new town.
Definition town.h:210
uint16_t grow_counter
counter to count when to grow, value is smaller than or equal to growth_rate
Definition town.h:192
uint32_t townnameparts
Custom town name. If empty, the town was not renamed and uses the generated name.
Definition town.h:72
TownFlags flags
See TownFlags.
Definition town.h:77
TownCache cache
Container for all cacheable data.
Definition town.h:66
TypedIndexContainer< std::array< uint8_t, MAX_COMPANIES >, CompanyID > unwanted
how many months companies aren't wanted by towns (bribe)
Definition town.h:85
CompanyID exclusivity
which company has exclusivity
Definition town.h:86
void InitializeLayout(TownLayout layout)
Assign the town layout.
Definition town_cmd.cpp:190
bool show_zone
NOSAVE: mark town to show the local authority zone in the viewports.
Definition town.h:201
uint8_t exclusive_counter
months till the exclusivity expires
Definition town.h:87
void UpdateVirtCoord()
Resize the sign (label) of the town after it changes population.
Definition town_cmd.cpp:387
EnumIndexArray< TransportedCargoStat< uint16_t >, TownAcceptanceEffect, TownAcceptanceEffect::End > received
Cargo statistics about received cargotypes.
Definition town.h:132
CompanyMask have_ratings
which companies have a rating
Definition town.h:84
~Town()
Destroy the town.
Definition town_cmd.cpp:115
TypedIndexContainer< std::array< int16_t, MAX_COMPANIES >, CompanyID > ratings
ratings of each company for this town
Definition town.h:88
uint16_t growth_rate
town growth rate
Definition town.h:193
uint32_t townnamegrfid
Custom town name. If empty, the town was not renamed and uses the generated name.
Definition town.h:70
StationList stations_near
NOSAVE: List of nearby stations.
Definition town.h:188
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:175
uint8_t road_build_months
fund road reconstruction in action?
Definition town.h:196
EnumIndexArray< uint32_t, TownAcceptanceEffect, TownAcceptanceEffect::End > goal
Amount of cargo required for the town to grow.
Definition town.h:133
uint16_t townnametype
Custom town name. If empty, the town was not renamed and uses the generated name.
Definition town.h:71
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:119
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:273
@ End
End marker.
Definition town.h:276
static const uint TOWN_GROWTH_DESERT
The town needs the cargo for growth when on desert (any amount).
Definition town.h:33
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:296
@ RoadRebuild
Rebuild the roads.
Definition town.h:300
@ Bribe
Try to bribe the council.
Definition town.h:304
@ End
End marker.
Definition town.h:305
@ BuildStatue
Build a statue.
Definition town.h:301
@ BuyRights
Buy exclusive transport rights.
Definition town.h:303
@ FundBuildings
Fund new buildings.
Definition town.h:302
@ 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:826
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 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(WC_TOWN_VIEW, t->index);} })
Economy monthly timer for towns.
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:88
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:586
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:729
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:568
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:505
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:446
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:694
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:548
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:431
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:837
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:767
static DiagDirection RandomDiagDir()
Return a random direction.
Definition town_cmd.cpp:256
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:460
uint8_t GetTownActionCost(TownAction action)
Get cost factors for a TownAction.
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:419
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:304
static TimerGameCalendar::Date GetTownRoadTypeFirstIntroductionDate()
Get the calendar date of the earliest town-buildable road type.
Definition town_cmd.cpp:965
static void AnimateTile_Town(TileIndex tile)
Tile callback function signature for animating a tile.
Definition town_cmd.cpp:328
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:935
static RoadBits GetTownRoadBits(TileIndex tile)
Return the RoadBits of a tile, ignoring depot and bay road stops.
Definition town_cmd.cpp:923
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:846
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:99
void OnTick_Town()
Iterate through all towns and call their tick handler.
Definition town_cmd.cpp:909
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:985
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:482
static void TownTickHandler(Town *t)
Handle the town tick for a single town, by growing the town if desired.
Definition town_cmd.cpp:890
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:783
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:379
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:522
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:262
void UpdateAllTownVirtCoords()
Update the virtual coords needed to draw the town sign for all towns.
Definition town_cmd.cpp:411
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
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
bool IsHouseProtected(Tile t)
Check if the house is protected from removal by towns.
Definition town_map.h:82
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:53
static constexpr int RATING_INITIAL
initial rating
Definition town_type.h:45
static constexpr int RATING_ROAD_NEEDED_HOSTILE
"Hostile"
Definition town_type.h:71
@ TCGM_BITCOUNT
Bit-counted algorithm (normal distribution from individual house population).
Definition town_type.h:118
@ TCGM_ORIGINAL
Original algorithm (quadratic cargo by population).
Definition town_type.h:117
static constexpr int RATING_ROAD_NEEDED_NEUTRAL
"Neutral"
Definition town_type.h:70
TownLayout
Town Layouts.
Definition town_type.h:84
@ TL_3X3_GRID
Geometric 3x3 grid algorithm.
Definition town_type.h:89
@ TL_ORIGINAL
Original algorithm (min. 1 distance between roads).
Definition town_type.h:86
@ TL_2X2_GRID
Geometric 2x2 grid algorithm.
Definition town_type.h:88
@ TL_RANDOM
Random town layout.
Definition town_type.h:91
@ TL_BETTER_ROADS
Extended original algorithm (min. 2 distance between roads).
Definition town_type.h:87
@ NUM_TLS
Number of town layouts.
Definition town_type.h:93
static constexpr int RATING_TUNNEL_BRIDGE_NEEDED_LENIENT
rating needed, "Lenient" difficulty settings
Definition town_type.h:61
@ TF_CUSTOM_LAYOUT
Allowed, with custom town layout.
Definition town_type.h:110
@ TF_FORBIDDEN
Forbidden.
Definition town_type.h:108
static constexpr int RATING_TUNNEL_BRIDGE_NEEDED_HOSTILE
"Hostile"
Definition town_type.h:63
static constexpr int RATING_TUNNEL_BRIDGE_NEEDED_PERMISSIVE
"Permissive" (local authority disabled)
Definition town_type.h:64
static constexpr int RATING_STATION_DOWN_STEP
... but loses for badly serviced stations
Definition town_type.h:56
static constexpr int RATING_TUNNEL_BRIDGE_NEEDED_NEUTRAL
"Neutral"
Definition town_type.h:62
static constexpr int RATING_ROAD_NEEDED_LENIENT
rating needed, "Lenient" difficulty settings
Definition town_type.h:69
static constexpr int RATING_STATION_UP_STEP
when a town grows, company gains reputation for all well serviced stations ...
Definition town_type.h:55
TownSize
Supported initial town sizes.
Definition town_type.h:21
@ TSZ_RANDOM
Random size, bigger than small, smaller than large.
Definition town_type.h:25
@ TSZ_END
Number of available town sizes.
Definition town_type.h:27
@ TSZ_LARGE
Large town.
Definition town_type.h:24
static const uint MAX_LENGTH_TOWN_NAME_CHARS
The maximum length of a town name in characters including '\0'.
Definition town_type.h:122
@ Roads
Allow town to place roads.
Definition town_type.h:100
@ Buildings
Allow town to place buildings.
Definition town_type.h:99
static constexpr int RATING_ROAD_NEEDED_PERMISSIVE
"Permissive" (local authority disabled)
Definition town_type.h:72
static constexpr int RATING_GROWTH_MAXIMUM
... up to RATING_MEDIOCRE
Definition town_type.h:54
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...
@ TO_HOUSES
town buildings
@ TRANSPORT_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:658
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:820
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:1209
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting).
Definition window.cpp:3230
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:3322
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting).
Definition window.cpp:3200
Window functions not directly related to making/drawing windows.
@ WC_TOWN_AUTHORITY
Town authority; Window numbers:
@ WC_STATION_VIEW
Station view; Window numbers:
@ WC_TOWN_VIEW
Town view; Window numbers:
@ WC_TOWN_DIRECTORY
Town directory; Window numbers:
@ WC_TOWN_CARGO_GRAPH
Town cargo history graph; Window numbers: