OpenTTD Source 20260311-master-g511d3794ce
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 cur_company.Restore();
693}
694
696static CommandCost ClearTile_Town(TileIndex tile, DoCommandFlags flags)
697{
698 if (flags.Test(DoCommandFlag::Auto)) return CommandCost(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
699 if (!CanDeleteHouse(tile)) return CommandCost(STR_ERROR_BUILDING_IS_PROTECTED);
700
701 const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
702
704 cost.AddCost(hs->GetRemovalCost());
705
706 int rating = hs->remove_rating_decrease;
707 Town *t = Town::GetByTile(tile);
708
710 if (!_cheats.magic_bulldozer.value && !flags.Test(DoCommandFlag::NoTestTownRating)) {
711 /* NewGRFs can add indestructible houses. */
712 if (rating > RATING_MAXIMUM) {
713 return CommandCost(STR_ERROR_BUILDING_IS_PROTECTED);
714 }
715 /* If town authority controls removal, check the company's rating. */
716 if (rating > t->ratings[_current_company] && _settings_game.difficulty.town_council_tolerance != TOWN_COUNCIL_PERMISSIVE) {
717 return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index);
718 }
719 }
720 }
721
722 ChangeTownRating(t, -rating, RATING_HOUSE_MINIMUM, flags);
723 if (flags.Test(DoCommandFlag::Execute)) {
724 ClearTownHouse(t, tile);
725 }
726
727 return cost;
728}
729
731static void AddProducedCargo_Town(TileIndex tile, CargoArray &produced)
732{
733 HouseID house_id = GetHouseType(tile);
734 const HouseSpec *hs = HouseSpec::Get(house_id);
735 Town *t = Town::GetByTile(tile);
736
738 for (uint i = 0; i < 256; i++) {
739 uint16_t callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, 0, house_id, t, tile);
740
741 if (callback == CALLBACK_FAILED || callback == CALLBACK_HOUSEPRODCARGO_END) break;
742
743 CargoType cargo = GetCargoTranslation(GB(callback, 8, 7), hs->grf_prop.grffile);
744
745 if (!IsValidCargoType(cargo)) continue;
746 produced[cargo]++;
747 }
748 } else {
749 if (hs->population > 0) {
751 produced[cs->Index()]++;
752 }
753 }
754 if (hs->mail_generation > 0) {
756 produced[cs->Index()]++;
757 }
758 }
759 }
760}
761
769static void AddAcceptedCargoSetMask(CargoType cargo, uint amount, CargoArray &acceptance, CargoTypes &always_accepted)
770{
771 if (!IsValidCargoType(cargo) || amount == 0) return;
772 acceptance[cargo] += amount;
773 SetBit(always_accepted, cargo);
774}
775
785void AddAcceptedCargoOfHouse(TileIndex tile, HouseID house, const HouseSpec *hs, Town *t, CargoArray &acceptance, CargoTypes &always_accepted)
786{
787 CargoType accepts[lengthof(hs->accepts_cargo)];
788
789 /* Set the initial accepted cargo types */
790 for (uint8_t i = 0; i < lengthof(accepts); i++) {
791 accepts[i] = hs->accepts_cargo[i];
792 }
793
794 /* Check for custom accepted cargo types */
796 uint16_t callback = GetHouseCallback(CBID_HOUSE_ACCEPT_CARGO, 0, 0, house, t, tile, {}, tile == INVALID_TILE);
797 if (callback != CALLBACK_FAILED) {
798 /* Replace accepted cargo types with translated values from callback */
799 accepts[0] = GetCargoTranslation(GB(callback, 0, 5), hs->grf_prop.grffile);
800 accepts[1] = GetCargoTranslation(GB(callback, 5, 5), hs->grf_prop.grffile);
801 accepts[2] = GetCargoTranslation(GB(callback, 10, 5), hs->grf_prop.grffile);
802 }
803 }
804
805 /* Check for custom cargo acceptance */
807 uint16_t callback = GetHouseCallback(CBID_HOUSE_CARGO_ACCEPTANCE, 0, 0, house, t, tile, {}, tile == INVALID_TILE);
808 if (callback != CALLBACK_FAILED) {
809 AddAcceptedCargoSetMask(accepts[0], GB(callback, 0, 4), acceptance, always_accepted);
810 AddAcceptedCargoSetMask(accepts[1], GB(callback, 4, 4), acceptance, always_accepted);
811 if (_settings_game.game_creation.landscape != LandscapeType::Temperate && HasBit(callback, 12)) {
812 /* The 'S' bit indicates food instead of goods */
813 AddAcceptedCargoSetMask(GetCargoTypeByLabel(CT_FOOD), GB(callback, 8, 4), acceptance, always_accepted);
814 } else {
815 AddAcceptedCargoSetMask(accepts[2], GB(callback, 8, 4), acceptance, always_accepted);
816 }
817 return;
818 }
819 }
820
821 /* No custom acceptance, so fill in with the default values */
822 for (uint8_t i = 0; i < lengthof(accepts); i++) {
823 AddAcceptedCargoSetMask(accepts[i], hs->cargo_acceptance[i], acceptance, always_accepted);
824 }
825}
826
828static void AddAcceptedCargo_Town(TileIndex tile, CargoArray &acceptance, CargoTypes &always_accepted)
829{
830 HouseID house = GetHouseType(tile);
831 AddAcceptedCargoOfHouse(tile, house, HouseSpec::Get(house), Town::GetByTile(tile), acceptance, always_accepted);
832}
833
840{
841 CargoTypes always_accepted{};
842 CargoArray acceptance{};
843 AddAcceptedCargoOfHouse(INVALID_TILE, hs->Index(), hs, nullptr, acceptance, always_accepted);
844 return acceptance;
845}
846
848static void GetTileDesc_Town(TileIndex tile, TileDesc &td)
849{
850 const HouseID house = GetHouseType(tile);
851 const HouseSpec *hs = HouseSpec::Get(house);
852 bool house_completed = IsHouseCompleted(tile);
853
854 td.str = hs->building_name;
856
857 std::array<int32_t, 1> regs100;
858 uint16_t callback_res = GetHouseCallback(CBID_HOUSE_CUSTOM_NAME, house_completed ? 1 : 0, 0, house, Town::GetByTile(tile), tile, regs100);
859 if (callback_res != CALLBACK_FAILED && callback_res != 0x400) {
860 StringID new_name = STR_NULL;
861 if (callback_res == 0x40F) {
862 new_name = GetGRFStringID(hs->grf_prop.grfid, static_cast<GRFStringID>(regs100[0]));
863 } else if (callback_res > 0x400) {
865 } else {
866 new_name = GetGRFStringID(hs->grf_prop.grfid, GRFSTR_MISC_GRF_TEXT + callback_res);
867 }
868 if (new_name != STR_NULL && new_name != STR_UNDEFINED) {
869 td.str = new_name;
870 }
871 }
872
873 if (!house_completed) {
874 td.dparam = td.str;
875 td.str = STR_LAI_TOWN_INDUSTRY_DESCRIPTION_UNDER_CONSTRUCTION;
876 }
877
878 if (hs->grf_prop.HasGrfFile()) {
879 const GRFConfig *gc = GetGRFConfig(hs->grf_prop.grfid);
880 td.grf = gc->GetName();
881 }
882
883 td.owner[0] = OWNER_TOWN;
884}
885
886static bool GrowTown(Town *t, TownExpandModes modes);
887
892static void TownTickHandler(Town *t)
893{
895 TownExpandModes modes{TownExpandMode::Buildings};
896 if (_settings_game.economy.allow_town_roads) modes.Set(TownExpandMode::Roads);
897 int i = (int)t->grow_counter - 1;
898 if (i < 0) {
899 if (GrowTown(t, modes)) {
900 i = t->growth_rate;
901 } else {
902 /* If growth failed wait a bit before retrying */
903 i = std::min<uint16_t>(t->growth_rate, Ticks::TOWN_GROWTH_TICKS - 1);
904 }
905 }
906 t->grow_counter = i;
907 }
908}
909
912{
913 if (_game_mode == GM_EDITOR) return;
914
915 for (Town *t : Town::Iterate()) {
917 }
918}
919
926{
927 if (IsRoadDepotTile(tile) || IsBayRoadStopTile(tile)) return ROAD_NONE;
928
929 return GetAnyRoadBits(tile, RTT_ROAD, true);
930}
931
938{
939 RoadType best_rt = ROADTYPE_ROAD;
940 const RoadTypeInfo *best = nullptr;
941 const uint16_t assume_max_speed = 50;
942
944 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
945
946 /* Can town build this road. */
947 if (!rti->flags.Test(RoadTypeFlag::TownBuild)) continue;
948
949 /* Not yet introduced at this date. */
951
952 if (best != nullptr) {
953 if ((rti->max_speed == 0 ? assume_max_speed : rti->max_speed) < (best->max_speed == 0 ? assume_max_speed : best->max_speed)) continue;
954 }
955
956 best_rt = rt;
957 best = rti;
958 }
959
960 return best_rt;
961}
962
967static TimerGameCalendar::Date GetTownRoadTypeFirstIntroductionDate()
968{
969 const RoadTypeInfo *best = nullptr;
971 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
972
973 if (!rti->flags.Test(RoadTypeFlag::TownBuild)) continue; // Town can't build this road type.
974
975 if (best != nullptr && rti->introduction_date >= best->introduction_date) continue;
976 best = rti;
977 }
978
979 if (best == nullptr) return TimerGameCalendar::Date(INT32_MAX);
980 return best->introduction_date;
981}
982
988{
989 auto min_date = GetTownRoadTypeFirstIntroductionDate();
990 if (min_date <= TimerGameCalendar::date) return true;
991
992 if (min_date < INT32_MAX) {
994 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_YET),
995 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_YET_EXPLANATION, min_date),
997 } else {
999 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_AT_ALL),
1000 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_AT_ALL_EXPLANATION), WL_CRITICAL);
1001 }
1002 return false;
1003}
1004
1015static bool IsNeighbourRoadTile(TileIndex tile, const DiagDirection dir, uint dist_multi)
1016{
1017 if (!IsValidTile(tile)) return false;
1018
1019 /* Lookup table for the used diff values */
1020 const TileIndexDiff tid_lt[3] = {
1024 };
1025
1026 dist_multi = (dist_multi + 1) * 4;
1027 for (uint pos = 4; pos < dist_multi; pos++) {
1028 /* Go (pos / 4) tiles to the left or the right */
1029 TileIndexDiff cur = tid_lt[(pos & 1) ? 0 : 1] * (pos / 4);
1030
1031 /* Use the current tile as origin, or go one tile backwards */
1032 if (pos & 2) cur += tid_lt[2];
1033
1034 /* Test for roadbit parallel to dir and facing towards the middle axis */
1035 if (IsValidTile(tile + cur) &&
1036 GetTownRoadBits(TileAdd(tile, cur)) & DiagDirToRoadBits((pos & 2) ? dir : ReverseDiagDir(dir))) return true;
1037 }
1038 return false;
1039}
1040
1050{
1051 if (DistanceFromEdge(tile) == 0) return false;
1052
1053 /* Prevent towns from building roads under bridges along the bridge. Looks silly. */
1054 if (IsBridgeAbove(tile) && GetBridgeAxis(tile) == DiagDirToAxis(dir)) return false;
1055
1056 /* Check if there already is a road at this point? */
1057 if (GetTownRoadBits(tile) == ROAD_NONE) {
1058 /* No, try if we are able to build a road piece there.
1059 * If that fails clear the land, and if that fails exit.
1060 * This is to make sure that we can build a road here later. */
1062 if (Command<Commands::BuildRoad>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile, (dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? ROAD_Y : ROAD_X, rt, DRD_NONE, t->index).Failed() &&
1063 Command<Commands::LandscapeClear>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile).Failed()) {
1064 return false;
1065 }
1066 }
1067
1068 Slope cur_slope = _settings_game.construction.build_on_slopes ? std::get<0>(GetFoundationSlope(tile)) : GetTileSlope(tile);
1069 bool ret = !IsNeighbourRoadTile(tile, dir, t->layout == TL_ORIGINAL ? 1 : 2);
1070 if (cur_slope == SLOPE_FLAT) return ret;
1071
1072 /* If the tile is not a slope in the right direction, then
1073 * maybe terraform some. */
1074 Slope desired_slope = (dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? SLOPE_NW : SLOPE_NE;
1075 if (desired_slope != cur_slope && ComplementSlope(desired_slope) != cur_slope) {
1076 if (Chance16(1, 8)) {
1077 CommandCost res = CMD_ERROR;
1078 if (!_generating_world && Chance16(1, 10)) {
1079 /* Note: Do not replace "^ SLOPE_ELEVATED" with ComplementSlope(). The slope might be steep. */
1080 res = std::get<0>(Command<Commands::TerraformLand>::Do({DoCommandFlag::Execute, DoCommandFlag::Auto, DoCommandFlag::NoWater},
1081 tile, Chance16(1, 16) ? cur_slope : cur_slope ^ SLOPE_ELEVATED, false));
1082 }
1083 if (res.Failed() && Chance16(1, 3)) {
1084 /* We can consider building on the slope, though. */
1085 return ret;
1086 }
1087 }
1088 return false;
1089 }
1090 return ret;
1091}
1092
1093static bool TerraformTownTile(TileIndex tile, Slope edges, bool dir)
1094{
1095 assert(tile < Map::Size());
1096
1097 CommandCost r = std::get<0>(Command<Commands::TerraformLand>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile, edges, dir));
1098 if (r.Failed() || r.GetCost() >= (_price[Price::Terraform] + 2) * 8) return false;
1099 Command<Commands::TerraformLand>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater, DoCommandFlag::Execute}, tile, edges, dir);
1100 return true;
1101}
1102
1103static void LevelTownLand(TileIndex tile)
1104{
1105 assert(tile < Map::Size());
1106
1107 /* Don't terraform if land is plain or if there's a house there. */
1108 if (IsTileType(tile, TileType::House)) return;
1109 Slope tileh = GetTileSlope(tile);
1110 if (tileh == SLOPE_FLAT) return;
1111
1112 /* First try up, then down */
1113 if (!TerraformTownTile(tile, ~tileh & SLOPE_ELEVATED, true)) {
1114 TerraformTownTile(tile, tileh & SLOPE_ELEVATED, false);
1115 }
1116}
1117
1127{
1128 /* align the grid to the downtown */
1129 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile); // Vector from downtown to the tile
1130 RoadBits rcmd = ROAD_NONE;
1131
1132 switch (t->layout) {
1133 default: NOT_REACHED();
1134
1135 case TL_2X2_GRID:
1136 if ((grid_pos.x % 3) == 0) rcmd |= ROAD_Y;
1137 if ((grid_pos.y % 3) == 0) rcmd |= ROAD_X;
1138 break;
1139
1140 case TL_3X3_GRID:
1141 if ((grid_pos.x % 4) == 0) rcmd |= ROAD_Y;
1142 if ((grid_pos.y % 4) == 0) rcmd |= ROAD_X;
1143 break;
1144 }
1145
1146 /* Optimise only X-junctions */
1147 if (rcmd != ROAD_ALL) return rcmd;
1148
1149 RoadBits rb_template;
1150
1151 switch (GetTileSlope(tile)) {
1152 default: rb_template = ROAD_ALL; break;
1153 case SLOPE_W: rb_template = ROAD_NW | ROAD_SW; break;
1154 case SLOPE_SW: rb_template = ROAD_Y | ROAD_SW; break;
1155 case SLOPE_S: rb_template = ROAD_SW | ROAD_SE; break;
1156 case SLOPE_SE: rb_template = ROAD_X | ROAD_SE; break;
1157 case SLOPE_E: rb_template = ROAD_SE | ROAD_NE; break;
1158 case SLOPE_NE: rb_template = ROAD_Y | ROAD_NE; break;
1159 case SLOPE_N: rb_template = ROAD_NE | ROAD_NW; break;
1160 case SLOPE_NW: rb_template = ROAD_X | ROAD_NW; break;
1161 case SLOPE_STEEP_W:
1162 case SLOPE_STEEP_S:
1163 case SLOPE_STEEP_E:
1164 case SLOPE_STEEP_N:
1165 rb_template = ROAD_NONE;
1166 break;
1167 }
1168
1169 /* Stop if the template is compatible to the growth dir */
1170 if (DiagDirToRoadBits(ReverseDiagDir(dir)) & rb_template) return rb_template;
1171 /* If not generate a straight road in the direction of the growth */
1173}
1174
1186static bool GrowTownWithExtraHouse(Town *t, TileIndex tile, TownExpandModes modes)
1187{
1188 /* We can't look further than that. */
1189 if (DistanceFromEdge(tile) == 0) return false;
1190
1191 uint counter = 0; // counts the house neighbour tiles
1192
1193 /* Check the tiles E,N,W and S of the current tile for houses */
1194 for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
1195 /* Count both void and house tiles for checking whether there
1196 * are enough houses in the area. This to make it likely that
1197 * houses get build up to the edge of the map. */
1198 switch (GetTileType(TileAddByDiagDir(tile, dir))) {
1199 case TileType::House:
1200 case TileType::Void:
1201 counter++;
1202 break;
1203
1204 default:
1205 break;
1206 }
1207
1208 /* If there are enough neighbours stop here */
1209 if (counter >= 3) {
1210 return TryBuildTownHouse(t, tile, modes);
1211 }
1212 }
1213 return false;
1214}
1215
1224static bool GrowTownWithRoad(const Town *t, TileIndex tile, RoadBits rcmd)
1225{
1227 return Command<Commands::BuildRoad>::Do({DoCommandFlag::Execute, DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile, rcmd, rt, DRD_NONE, t->index).Succeeded();
1228}
1229
1239static bool CanRoadContinueIntoNextTile(const Town *t, const TileIndex tile, const DiagDirection road_dir)
1240{
1241 const TileIndexDiff delta = TileOffsByDiagDir(road_dir); // +1 tile in the direction of the road
1242 TileIndex next_tile = tile + delta; // The tile beyond which must be connectable to the target tile
1243 RoadBits rcmd = DiagDirToRoadBits(ReverseDiagDir(road_dir));
1245
1246 /* Before we try anything, make sure the tile is on the map and not the void. */
1247 if (!IsValidTile(next_tile)) return false;
1248
1249 /* If the next tile is a bridge or tunnel, allow if it's continuing in the same direction. */
1250 if (IsTileType(next_tile, TileType::TunnelBridge)) {
1251 return GetTunnelBridgeTransportType(next_tile) == TRANSPORT_ROAD && GetTunnelBridgeDirection(next_tile) == road_dir;
1252 }
1253
1254 /* If the next tile is a station, allow if it's a road station facing the proper direction. Otherwise return false. */
1255 if (IsTileType(next_tile, TileType::Station)) {
1256 /* If the next tile is a road station, allow if it can be entered by the new tunnel/bridge, otherwise disallow. */
1257 if (IsDriveThroughStopTile(next_tile)) return GetDriveThroughStopAxis(next_tile) == DiagDirToAxis(road_dir);
1258 if (IsBayRoadStopTile(next_tile)) return GetBayRoadStopDir(next_tile) == ReverseDiagDir(road_dir);
1259 return false;
1260 }
1261
1262 /* If the next tile is a road depot, allow if it's facing the right way. */
1263 if (IsTileType(next_tile, TileType::Road)) {
1264 return IsRoadDepot(next_tile) && GetRoadDepotDirection(next_tile) == ReverseDiagDir(road_dir);
1265 }
1266
1267 /* If the next tile is a railroad track, check if towns are allowed to build level crossings.
1268 * If level crossing are not allowed, reject the construction. Else allow DoCommand to determine if the rail track is buildable. */
1269 if (IsTileType(next_tile, TileType::Railway) && !_settings_game.economy.allow_town_level_crossings) return false;
1270
1271 /* If a road tile can be built, the construction is allowed. */
1272 return Command<Commands::BuildRoad>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, next_tile, rcmd, rt, DRD_NONE, t->index).Succeeded();
1273}
1274
1285static bool GrowTownWithBridge(const Town *t, const TileIndex tile, const DiagDirection bridge_dir)
1286{
1287 assert(bridge_dir < DIAGDIR_END);
1288
1289 const Slope slope = GetTileSlope(tile);
1290
1291 /* Make sure the direction is compatible with the slope.
1292 * Well we check if the slope has an up bit set in the
1293 * reverse direction. */
1294 if (slope != SLOPE_FLAT && slope & InclinedSlope(bridge_dir)) return false;
1295
1296 /* Assure that the bridge is connectable to the start side */
1297 if (!(GetTownRoadBits(TileAddByDiagDir(tile, ReverseDiagDir(bridge_dir))) & DiagDirToRoadBits(bridge_dir))) return false;
1298
1299 /* We are in the right direction */
1300 uint bridge_length = 0; // This value stores the length of the possible bridge
1301 TileIndex bridge_tile = tile; // Used to store the other waterside
1302
1303 const TileIndexDiff delta = TileOffsByDiagDir(bridge_dir);
1304
1305 /* To prevent really small towns from building disproportionately
1306 * long bridges, make the max a function of its population. */
1307 const uint TOWN_BRIDGE_LENGTH_CAP = 11;
1308 uint base_bridge_length = 5;
1309 uint max_bridge_length = std::min(t->cache.population / 1000 + base_bridge_length, TOWN_BRIDGE_LENGTH_CAP);
1310
1311 if (slope == SLOPE_FLAT) {
1312 /* Bridges starting on flat tiles are only allowed when crossing rivers, rails or one-way roads. */
1313 do {
1314 if (bridge_length++ >= base_bridge_length) {
1315 /* Allow to cross rivers, not big lakes, nor large amounts of rails or one-way roads. */
1316 return false;
1317 }
1318 bridge_tile += delta;
1319 } while (IsValidTile(bridge_tile) && ((IsWaterTile(bridge_tile) && !IsSea(bridge_tile)) || IsPlainRailTile(bridge_tile) || (IsNormalRoadTile(bridge_tile) && GetDisallowedRoadDirections(bridge_tile) != DRD_NONE)));
1320 } else {
1321 do {
1322 if (bridge_length++ >= max_bridge_length) {
1323 /* Ensure the bridge is not longer than the max allowed length. */
1324 return false;
1325 }
1326 bridge_tile += delta;
1327 } while (IsValidTile(bridge_tile) && (IsWaterTile(bridge_tile) || IsPlainRailTile(bridge_tile) || (IsNormalRoadTile(bridge_tile) && GetDisallowedRoadDirections(bridge_tile) != DRD_NONE)));
1328 }
1329
1330 /* Don't allow a bridge where the start and end tiles are adjacent with no span between. */
1331 if (bridge_length == 1) return false;
1332
1333 /* Make sure the road can be continued past the bridge. At this point, bridge_tile holds the end tile of the bridge. */
1334 if (!CanRoadContinueIntoNextTile(t, bridge_tile, bridge_dir)) return false;
1335
1336 /* If another parallel bridge exists nearby, this one would be redundant and shouldn't be built. We don't care about flat bridges. */
1337 if (slope != SLOPE_FLAT) {
1338 for (auto search : SpiralTileSequence(tile, bridge_length, 0, 0)) {
1339 /* Only consider bridge head tiles. */
1340 if (!IsBridgeTile(search)) continue;
1341
1342 /* Only consider road bridges. */
1343 if (GetTunnelBridgeTransportType(search) != TRANSPORT_ROAD) continue;
1344
1345 /* If the bridge is facing the same direction as the proposed bridge, we've found a redundant bridge. */
1346 if (GetTileSlope(search) & InclinedSlope(ReverseDiagDir(bridge_dir))) return false;
1347 }
1348 }
1349
1350 for (uint8_t times = 0; times <= 22; times++) {
1351 uint8_t bridge_type = RandomRange(MAX_BRIDGES - 1);
1352
1353 /* Can we actually build the bridge? */
1355 if (Command<Commands::BuildBridge>::Do(CommandFlagsToDCFlags(GetCommandFlags<Commands::BuildBridge>()), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, rt).Succeeded()) {
1356 Command<Commands::BuildBridge>::Do(CommandFlagsToDCFlags(GetCommandFlags<Commands::BuildBridge>()).Set(DoCommandFlag::Execute), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, rt);
1357 return true;
1358 }
1359 }
1360 /* Quit if it selecting an appropriate bridge type fails a large number of times. */
1361 return false;
1362}
1363
1374static bool GrowTownWithTunnel(const Town *t, const TileIndex tile, const DiagDirection tunnel_dir)
1375{
1376 assert(tunnel_dir < DIAGDIR_END);
1377
1378 Slope slope = GetTileSlope(tile);
1379
1380 /* Only consider building a tunnel if the starting tile is sloped properly. */
1381 if (slope != InclinedSlope(tunnel_dir)) return false;
1382
1383 /* Assure that the tunnel is connectable to the start side */
1384 if (!(GetTownRoadBits(TileAddByDiagDir(tile, ReverseDiagDir(tunnel_dir))) & DiagDirToRoadBits(tunnel_dir))) return false;
1385
1386 const TileIndexDiff delta = TileOffsByDiagDir(tunnel_dir);
1387 int max_tunnel_length = 0;
1388
1389 /* There are two conditions for building tunnels: Under a mountain and under an obstruction. */
1390 if (CanRoadContinueIntoNextTile(t, tile, tunnel_dir)) {
1391 /* 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. */
1392 TileIndex slope_tile = tile;
1393 for (uint8_t tiles = 0; tiles < 4; tiles++) {
1394 if (!IsValidTile(slope_tile)) return false;
1395 slope = GetTileSlope(slope_tile);
1396 if (slope != InclinedSlope(tunnel_dir) && !IsSteepSlope(slope) && !IsSlopeWithOneCornerRaised(slope)) return false;
1397 slope_tile += delta;
1398 }
1399
1400 /* More population means longer tunnels, but make sure we can at least cover the smallest mountain which necessitates tunneling. */
1401 max_tunnel_length = (t->cache.population / 1000) + 7;
1402 } else {
1403 /* When tunneling under an obstruction, the length limit is 5, enough to tunnel under a four-track railway. */
1404 max_tunnel_length = 5;
1405 }
1406
1407 uint8_t tunnel_length = 0;
1408 TileIndex tunnel_tile = tile; // Iterator to store the other end tile of the tunnel.
1409
1410 /* Find the end tile of the tunnel for length and continuation checks. */
1411 do {
1412 if (tunnel_length++ >= max_tunnel_length) return false;
1413 tunnel_tile += delta;
1414 /* The tunnel ends when start and end tiles are the same height. */
1415 } while (IsValidTile(tunnel_tile) && GetTileZ(tile) != GetTileZ(tunnel_tile));
1416
1417 /* Don't allow a tunnel where the start and end tiles are adjacent. */
1418 if (tunnel_length == 1) return false;
1419
1420 /* Make sure the road can be continued past the tunnel. At this point, tunnel_tile holds the end tile of the tunnel. */
1421 if (!CanRoadContinueIntoNextTile(t, tunnel_tile, tunnel_dir)) return false;
1422
1423 /* Attempt to build the tunnel. Return false if it fails to let the town build a road instead. */
1425 if (Command<Commands::BuildTunnel>::Do(CommandFlagsToDCFlags(GetCommandFlags<Commands::BuildTunnel>()), tile, TRANSPORT_ROAD, rt).Succeeded()) {
1426 Command<Commands::BuildTunnel>::Do(CommandFlagsToDCFlags(GetCommandFlags<Commands::BuildTunnel>()).Set(DoCommandFlag::Execute), tile, TRANSPORT_ROAD, rt);
1427 return true;
1428 }
1429
1430 return false;
1431}
1432
1440{
1441 static const TileIndexDiffC tiles[] = { {-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1} };
1442 bool allow = false;
1443
1444 for (const auto &ptr : tiles) {
1445 TileIndex cur_tile = t + ToTileIndexDiff(ptr);
1446 if (!IsValidTile(cur_tile)) continue;
1447
1448 if (!(IsTileType(cur_tile, TileType::Road) || IsAnyRoadStopTile(cur_tile))) continue;
1449 allow = true;
1450
1451 RoadType road_rt = GetRoadTypeRoad(cur_tile);
1452 if (road_rt != INVALID_ROADTYPE && !GetRoadTypeInfo(road_rt)->flags.Test(RoadTypeFlag::NoHouses)) return true;
1453 }
1454
1455 /* If no road was found surrounding the tile we can allow building the house since there is
1456 * nothing which forbids it, if a road was found but the execution reached this point, then
1457 * all the found roads don't allow houses to be built */
1458 return !allow;
1459}
1460
1466{
1467 if (!IsTileType(tile, TileType::Road)) return true;
1468
1469 /* Allow extending on roadtypes which can be built by town, or if the road type matches the type the town will build. */
1470 RoadType rt = GetRoadTypeRoad(tile);
1472}
1473
1479static inline bool TownAllowedToBuildRoads(TownExpandModes modes)
1480{
1481 return modes.Test(TownExpandMode::Roads);
1482}
1483
1490
1510static TownGrowthResult GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection target_dir, Town *t1, TownExpandModes modes)
1511{
1512 RoadBits rcmd = ROAD_NONE; // RoadBits for the road construction command
1513 TileIndex tile = *tile_ptr; // The main tile on which we base our growth
1514
1515 assert(tile < Map::Size());
1516
1517 if (cur_rb == ROAD_NONE) {
1518 /* Tile has no road.
1519 * We will return TownGrowthResult::SearchStopped to say that this is the last iteration. */
1520
1522 if (!_settings_game.economy.allow_town_level_crossings && IsTileType(tile, TileType::Railway)) return TownGrowthResult::SearchStopped;
1523
1524 /* Remove hills etc */
1525 if (!_settings_game.construction.build_on_slopes || Chance16(1, 6)) LevelTownLand(tile);
1526
1527 /* Is a road allowed here? */
1528 switch (t1->layout) {
1529 default: NOT_REACHED();
1530
1531 case TL_3X3_GRID:
1532 case TL_2X2_GRID:
1533 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1534 if (rcmd == ROAD_NONE) return TownGrowthResult::SearchStopped;
1535 break;
1536
1537 case TL_BETTER_ROADS:
1538 case TL_ORIGINAL:
1539 if (!IsRoadAllowedHere(t1, tile, target_dir)) return TownGrowthResult::SearchStopped;
1540
1541 DiagDirection source_dir = ReverseDiagDir(target_dir);
1542
1543 if (Chance16(1, 4)) {
1544 /* Randomize a new target dir */
1545 do target_dir = RandomDiagDir(); while (target_dir == source_dir);
1546 }
1547
1548 if (!IsRoadAllowedHere(t1, TileAddByDiagDir(tile, target_dir), target_dir)) {
1549 /* A road is not allowed to continue the randomized road,
1550 * return if the road we're trying to build is curved. */
1551 if (target_dir != ReverseDiagDir(source_dir)) return TownGrowthResult::SearchStopped;
1552
1553 /* Return if neither side of the new road is a house */
1557 }
1558
1559 /* That means that the road is only allowed if there is a house
1560 * at any side of the new road. */
1561 }
1562
1563 rcmd = DiagDirToRoadBits(target_dir) | DiagDirToRoadBits(source_dir);
1564 break;
1565 }
1566
1567 } else if (target_dir < DIAGDIR_END && !(cur_rb & DiagDirToRoadBits(ReverseDiagDir(target_dir)))) {
1569
1571
1572 /* Continue building on a partial road.
1573 * Should be always OK, so we only generate
1574 * the fitting RoadBits */
1575 switch (t1->layout) {
1576 default: NOT_REACHED();
1577
1578 case TL_3X3_GRID:
1579 case TL_2X2_GRID:
1580 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1581 break;
1582
1583 case TL_BETTER_ROADS:
1584 case TL_ORIGINAL:
1585 rcmd = DiagDirToRoadBits(ReverseDiagDir(target_dir));
1586 break;
1587 }
1588 } else {
1589 bool allow_house = true; // Value which decides if we want to construct a house
1590
1591 /* Reached a tunnel/bridge? Then continue at the other side of it, unless
1592 * it is the starting tile. Half the time, we stay on this side then.*/
1594 if (GetTunnelBridgeTransportType(tile) == TRANSPORT_ROAD && (target_dir != DIAGDIR_END || Chance16(1, 2))) {
1595 *tile_ptr = GetOtherTunnelBridgeEnd(tile);
1596 }
1598 }
1599
1600 /* Possibly extend the road in a direction.
1601 * Randomize a direction and if it has a road, bail out. */
1602 target_dir = RandomDiagDir();
1603 RoadBits target_rb = DiagDirToRoadBits(target_dir);
1604 TileIndex house_tile; // position of a possible house
1605
1606 if (cur_rb & target_rb) {
1607 /* If it's a road turn possibly build a house in a corner.
1608 * Use intersection with straight road as an indicator
1609 * that we randomised corner house position.
1610 * A turn (and we check for that later) always has only
1611 * one common bit with a straight road so it has the same
1612 * chance to be chosen as the house on the side of a road.
1613 */
1614 if ((cur_rb & ROAD_X) != target_rb) return TownGrowthResult::Continue;
1615
1616 /* Check whether it is a turn and if so determine
1617 * position of the corner tile */
1618 switch (cur_rb) {
1619 case ROAD_N:
1620 house_tile = TileAddByDir(tile, DIR_S);
1621 break;
1622 case ROAD_S:
1623 house_tile = TileAddByDir(tile, DIR_N);
1624 break;
1625 case ROAD_E:
1626 house_tile = TileAddByDir(tile, DIR_W);
1627 break;
1628 case ROAD_W:
1629 house_tile = TileAddByDir(tile, DIR_E);
1630 break;
1631 default:
1632 return TownGrowthResult::Continue; // not a turn
1633 }
1634 target_dir = DIAGDIR_END;
1635 } else {
1636 house_tile = TileAddByDiagDir(tile, target_dir);
1637 }
1638
1639 /* Don't walk into water. */
1640 if (HasTileWaterGround(house_tile)) return TownGrowthResult::Continue;
1641
1642 if (!IsValidTile(house_tile)) return TownGrowthResult::Continue;
1643
1645
1646 if (target_dir != DIAGDIR_END && TownAllowedToBuildRoads(modes)) {
1647 switch (t1->layout) {
1648 default: NOT_REACHED();
1649
1650 case TL_3X3_GRID: // Use 2x2 grid afterwards!
1651 if (GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir), modes)) {
1653 }
1654 [[fallthrough]];
1655
1656 case TL_2X2_GRID:
1657 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1658 allow_house = (rcmd & target_rb) == ROAD_NONE;
1659 break;
1660
1661 case TL_BETTER_ROADS: // Use original afterwards!
1662 if (GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir), modes)) {
1664 }
1665 [[fallthrough]];
1666
1667 case TL_ORIGINAL:
1668 /* Allow a house at the edge. 60% chance or
1669 * always ok if no road allowed. */
1670 rcmd = target_rb;
1671 allow_house = (!IsRoadAllowedHere(t1, house_tile, target_dir) || Chance16(6, 10));
1672 break;
1673 }
1674 }
1675
1676 allow_house &= RoadTypesAllowHouseHere(house_tile);
1677
1678 if (allow_house) {
1679 /* Build a house, but not if there already is a house there. */
1680 if (!IsTileType(house_tile, TileType::House)) {
1681 /* Level the land if possible */
1682 if (Chance16(1, 6)) LevelTownLand(house_tile);
1683
1684 /* And build a house.
1685 * Set result to -1 if we managed to build it. */
1686 if (TryBuildTownHouse(t1, house_tile, modes)) {
1688 }
1689 }
1690 return result;
1691 }
1692
1693 if (!TownCanGrowRoad(tile)) return result;
1694 }
1695
1696 /* Return if a water tile */
1698
1699 /* Make the roads look nicer */
1700 rcmd = CleanUpRoadBits(tile, rcmd);
1701 if (rcmd == ROAD_NONE) return TownGrowthResult::SearchStopped;
1702
1703 /* Only use the target direction for bridges and tunnels to ensure they're connected.
1704 * The target_dir is as computed previously according to town layout, so
1705 * it will match it perfectly. */
1706 if (GrowTownWithBridge(t1, tile, target_dir)) {
1708 }
1709 if (GrowTownWithTunnel(t1, tile, target_dir)) {
1711 }
1712
1713 if (GrowTownWithRoad(t1, tile, rcmd)) {
1715 }
1717}
1718
1727static bool CanFollowRoad(TileIndex tile, DiagDirection dir, TownExpandModes modes)
1728{
1729 TileIndex target_tile = tile + TileOffsByDiagDir(dir);
1730 if (!IsValidTile(target_tile)) return false;
1731 if (HasTileWaterGround(target_tile)) return false;
1732
1733 RoadBits target_rb = GetTownRoadBits(target_tile);
1734 if (TownAllowedToBuildRoads(modes)) {
1735 /* Check whether a road connection exists or can be build. */
1736 switch (GetTileType(target_tile)) {
1737 case TileType::Road:
1738 return target_rb != ROAD_NONE;
1739
1740 case TileType::Station:
1741 return IsDriveThroughStopTile(target_tile);
1742
1744 return GetTunnelBridgeTransportType(target_tile) == TRANSPORT_ROAD;
1745
1746 case TileType::House:
1747 case TileType::Industry:
1748 case TileType::Object:
1749 return false;
1750
1751 default:
1752 /* Checked for void and water earlier */
1753 return true;
1754 }
1755 } else {
1756 /* Check whether a road connection already exists,
1757 * and it leads somewhere else. */
1759 return (target_rb & back_rb) != 0 && (target_rb & ~back_rb) != 0;
1760 }
1761}
1762
1770static bool GrowTownAtRoad(Town *t, TileIndex tile, TownExpandModes modes)
1771{
1772 /* Special case.
1773 * @see GrowTownInTile Check the else if
1774 */
1775 DiagDirection target_dir = DIAGDIR_END; // The direction in which we want to extend the town
1776
1777 assert(tile < Map::Size());
1778
1779 /* Number of times to search.
1780 * Better roads, 2X2 and 3X3 grid grow quite fast so we give
1781 * them a little handicap. */
1782 int iterations;
1783 switch (t->layout) {
1784 case TL_BETTER_ROADS:
1785 iterations = 10 + t->cache.num_houses * 2 / 9;
1786 break;
1787
1788 case TL_3X3_GRID:
1789 case TL_2X2_GRID:
1790 iterations = 10 + t->cache.num_houses * 1 / 9;
1791 break;
1792
1793 default:
1794 iterations = 10 + t->cache.num_houses * 4 / 9;
1795 break;
1796 }
1797
1798 do {
1799 RoadBits cur_rb = GetTownRoadBits(tile); // The RoadBits of the current tile
1800
1801 /* Try to grow the town from this point */
1802 switch (GrowTownInTile(&tile, cur_rb, target_dir, t, modes)) {
1804 return true;
1806 iterations = 0;
1807 break;
1808 default:
1809 break;
1810 };
1811
1812 /* Exclude the source position from the bitmask
1813 * and return if no more road blocks available */
1814 if (IsValidDiagDirection(target_dir)) cur_rb &= ~DiagDirToRoadBits(ReverseDiagDir(target_dir));
1815 if (cur_rb == ROAD_NONE) return false;
1816
1818 /* Only build in the direction away from the tunnel or bridge. */
1819 target_dir = ReverseDiagDir(GetTunnelBridgeDirection(tile));
1820 } else {
1821 /* Select a random bit from the blockmask, walk a step
1822 * and continue the search from there. */
1823 do {
1824 if (cur_rb == ROAD_NONE) return false;
1825 RoadBits target_bits;
1826 do {
1827 target_dir = RandomDiagDir();
1828 target_bits = DiagDirToRoadBits(target_dir);
1829 } while (!(cur_rb & target_bits));
1830 cur_rb &= ~target_bits;
1831 } while (!CanFollowRoad(tile, target_dir, modes));
1832 }
1833 tile = TileAddByDiagDir(tile, target_dir);
1834
1835 if (IsTileType(tile, TileType::Road) && !IsRoadDepot(tile) && HasTileRoadType(tile, RTT_ROAD)) {
1836 /* Don't allow building over roads of other cities */
1837 if (IsRoadOwner(tile, RTT_ROAD, OWNER_TOWN) && Town::GetByTile(tile) != t) {
1838 return false;
1839 } else if (IsRoadOwner(tile, RTT_ROAD, OWNER_NONE) && _game_mode == GM_EDITOR) {
1840 /* If we are in the SE, and this road-piece has no town owner yet, it just found an
1841 * owner :) (happy happy happy road now) */
1843 SetTownIndex(tile, t->index);
1844 }
1845 }
1846
1847 /* Max number of times is checked. */
1848 } while (--iterations >= 0);
1849
1850 return false;
1851}
1852
1861{
1862 uint32_t r = Random();
1863 uint a = GB(r, 0, 2);
1864 uint b = GB(r, 8, 2);
1865 if (a == b) b ^= 2;
1866 return (RoadBits)((ROAD_NW << a) + (ROAD_NW << b));
1867}
1868
1875static bool GrowTown(Town *t, TownExpandModes modes)
1876{
1877 static const TileIndexDiffC _town_coord_mod[] = {
1878 {-1, 0},
1879 { 1, 1},
1880 { 1, -1},
1881 {-1, -1},
1882 {-1, 0},
1883 { 0, 2},
1884 { 2, 0},
1885 { 0, -2},
1886 {-1, -1},
1887 {-2, 2},
1888 { 2, 2},
1889 { 2, -2},
1890 { 0, 0}
1891 };
1892
1893 /* Current "company" is a town */
1895
1896 TileIndex tile = t->xy; // The tile we are working with ATM
1897
1898 /* Find a road that we can base the construction on. */
1899 for (const auto &ptr : _town_coord_mod) {
1900 if (GetTownRoadBits(tile) != ROAD_NONE) {
1901 bool success = GrowTownAtRoad(t, tile, modes);
1902 cur_company.Restore();
1903 return success;
1904 }
1905 tile = TileAdd(tile, ToTileIndexDiff(ptr));
1906 }
1907
1908 /* No road available, try to build a random road block by
1909 * clearing some land and then building a road there. */
1910 if (TownAllowedToBuildRoads(modes)) {
1911 tile = t->xy;
1912 for (const auto &ptr : _town_coord_mod) {
1913 /* Only work with plain land that not already has a house */
1914 if (!IsTileType(tile, TileType::House) && IsTileFlat(tile)) {
1915 if (Command<Commands::LandscapeClear>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile).Succeeded()) {
1917 Command<Commands::BuildRoad>::Do({DoCommandFlag::Execute, DoCommandFlag::Auto}, tile, GenRandomRoadBits(), rt, DRD_NONE, t->index);
1918 cur_company.Restore();
1919 return true;
1920 }
1921 }
1922 tile = TileAdd(tile, ToTileIndexDiff(ptr));
1923 }
1924 }
1925
1926 cur_company.Restore();
1927 return false;
1928}
1929
1935{
1936 static const std::array<std::array<uint32_t, NUM_HOUSE_ZONES>, 23> _town_squared_town_zone_radius_data = {{
1937 { 4, 0, 0, 0, 0}, // 0
1938 { 16, 0, 0, 0, 0},
1939 { 25, 0, 0, 0, 0},
1940 { 36, 0, 0, 0, 0},
1941 { 49, 0, 4, 0, 0},
1942 { 64, 0, 4, 0, 0}, // 20
1943 { 64, 0, 9, 0, 1},
1944 { 64, 0, 9, 0, 4},
1945 { 64, 0, 16, 0, 4},
1946 { 81, 0, 16, 0, 4},
1947 { 81, 0, 16, 0, 4}, // 40
1948 { 81, 0, 25, 0, 9},
1949 { 81, 36, 25, 0, 9},
1950 { 81, 36, 25, 16, 9},
1951 { 81, 49, 0, 25, 9},
1952 { 81, 64, 0, 25, 9}, // 60
1953 { 81, 64, 0, 36, 9},
1954 { 81, 64, 0, 36, 16},
1955 {100, 81, 0, 49, 16},
1956 {100, 81, 0, 49, 25},
1957 {121, 81, 0, 49, 25}, // 80
1958 {121, 81, 0, 49, 25},
1959 {121, 81, 0, 49, 36}, // 88
1960 }};
1961
1962 if (t->cache.num_houses < std::size(_town_squared_town_zone_radius_data) * 4) {
1963 t->cache.squared_town_zone_radius = _town_squared_town_zone_radius_data[t->cache.num_houses / 4];
1964 } else {
1965 int mass = t->cache.num_houses / 8;
1966 /* Actually we are proportional to sqrt() but that's right because we are covering an area.
1967 * The offsets are to make sure the radii do not decrease in size when going from the table
1968 * to the calculated value.*/
1974 }
1975}
1976
1982{
1984 uint32_t production = ScaleByCargoScale(t->cache.population >> 3, true);
1985 if (production == 0) continue;
1986
1987 auto &supplied = t->GetOrCreateCargoSupplied(cs->Index());
1988 supplied.history[LAST_MONTH].production = production;
1989 }
1990
1992 uint32_t production = ScaleByCargoScale(t->cache.population >> 4, true);
1993 if (production == 0) continue;
1994
1995 auto &supplied = t->GetOrCreateCargoSupplied(cs->Index());
1996 supplied.history[LAST_MONTH].production = production;
1997 }
1998}
1999
2000static void UpdateTownGrowthRate(Town *t);
2001static void UpdateTownGrowth(Town *t);
2002
2014static void DoCreateTown(Town *t, TileIndex tile, uint32_t townnameparts, TownSize size, bool city, TownLayout layout, bool manual)
2015{
2016 AutoRestoreBackup backup(_generating_town, true);
2017
2018 t->xy = tile;
2019 t->cache.num_houses = 0;
2020 t->time_until_rebuild = 10;
2022 t->flags.Reset();
2023 t->cache.population = 0;
2025 /* Spread growth across ticks so even if there are many
2026 * similar towns they're unlikely to grow all in one tick */
2027 t->grow_counter = t->index % Ticks::TOWN_GROWTH_TICKS;
2028 t->growth_rate = TownTicksToGameTicks(250);
2029 t->show_zone = false;
2030
2031 _town_kdtree.Insert(t->index);
2032
2033 /* Set the default cargo requirement for town growth */
2034 switch (_settings_game.game_creation.landscape) {
2037 break;
2038
2042 break;
2043
2044 default:
2045 break;
2046 }
2047
2048 t->fund_buildings_months = 0;
2049
2050 for (uint i = 0; i != MAX_COMPANIES; i++) t->ratings[i] = RATING_INITIAL;
2051
2052 t->have_ratings = {};
2053 t->exclusivity = CompanyID::Invalid();
2054 t->exclusive_counter = 0;
2055 t->statues = {};
2056
2057 {
2058 TownNameParams tnp(_settings_game.game_creation.town_name);
2059 t->townnamegrfid = tnp.grfid;
2060 t->townnametype = tnp.type;
2061 }
2062 t->townnameparts = townnameparts;
2063
2064 t->InitializeLayout(layout);
2065
2066 t->larger_town = city;
2067
2068 int x = (int)size * 16 + 3;
2069 if (size == TSZ_RANDOM) x = (Random() & 0xF) + 8;
2070 /* Don't create huge cities when founding town in-game */
2071 if (city && (!manual || _game_mode == GM_EDITOR)) x *= _settings_game.economy.initial_city_size;
2072
2073 t->cache.num_houses += x;
2075
2076 int i = x * 4;
2077 do {
2079 } while (--i);
2080
2081 t->UpdateVirtCoord();
2082 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_REBUILD);
2083
2084 t->cache.num_houses -= x;
2089}
2090
2097static CommandCost TownCanBePlacedHere(TileIndex tile, bool check_surrounding)
2098{
2099 /* Check if too close to the edge of map */
2100 if (DistanceFromEdge(tile) < 12) {
2101 return CommandCost(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP);
2102 }
2103
2104 /* Check distance to all other towns. */
2105 if (IsCloseToTown(tile, _settings_game.economy.town_min_distance)) {
2106 return CommandCost(STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN);
2107 }
2108
2109 /* Can only build on clear flat areas, possibly with trees. */
2110 if ((!IsTileType(tile, TileType::Clear) && !IsTileType(tile, TileType::Trees)) || !IsTileFlat(tile)) {
2111 return CommandCost(STR_ERROR_SITE_UNSUITABLE);
2112 }
2113
2114 /* We might want to make sure the town has enough room. */
2115 if (check_surrounding) {
2116 constexpr uint SEARCH_DIAMETER = 5; // Center tile of town + 2 tile radius.
2117 /* Half of the tiles in the search must be valid for the town to build upon. */
2118 constexpr uint VALID_TILE_GOAL = (SEARCH_DIAMETER * SEARCH_DIAMETER) / 2;
2119 uint counter = 0;
2120 int town_height = GetTileZ(tile);
2121 for (TileIndex t : SpiralTileSequence(tile, SEARCH_DIAMETER)) {
2122 if (counter == VALID_TILE_GOAL) break;
2123
2124 switch (GetTileType(t)) {
2125 case TileType::Clear:
2126 /* Don't allow rough tiles, as they are likely wetlands. */
2127 if (GetClearGround(t) == ClearGround::Rough) continue;
2128 break;
2129
2130 case TileType::Trees:
2131 /* Don't allow rough trees, as they are likely wetlands. */
2132 if (GetTreeGround(t) == TreeGround::Rough) continue;
2133 break;
2134
2135 default:
2136 continue;
2137 }
2138
2139 bool elevation_similar = (GetTileMaxZ(t) <= town_height + 1) && (GetTileZ(t) >= town_height - 1);
2140 if (elevation_similar) counter++;
2141 }
2142
2143 if (counter < VALID_TILE_GOAL) return CommandCost(STR_ERROR_SITE_UNSUITABLE);
2144 }
2145
2147}
2148
2154static bool IsUniqueTownName(const std::string &name)
2155{
2156 for (const Town *t : Town::Iterate()) {
2157 if (!t->name.empty() && t->name == name) return false;
2158 }
2159
2160 return true;
2161}
2162
2175std::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)
2176{
2177 TownNameParams par(_settings_game.game_creation.town_name);
2178
2179 if (size >= TSZ_END) return { CMD_ERROR, 0, TownID::Invalid() };
2180 if (layout >= NUM_TLS) return { CMD_ERROR, 0, TownID::Invalid() };
2181
2182 /* Some things are allowed only in the scenario editor and for game scripts. */
2183 if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY) {
2184 if (_settings_game.economy.found_town == TF_FORBIDDEN) return { CMD_ERROR, 0, TownID::Invalid() };
2185 if (size == TSZ_LARGE) return { CMD_ERROR, 0, TownID::Invalid() };
2186 if (random_location) return { CMD_ERROR, 0, TownID::Invalid() };
2187 if (_settings_game.economy.found_town != TF_CUSTOM_LAYOUT && layout != _settings_game.economy.town_layout) {
2188 return { CMD_ERROR, 0, TownID::Invalid() };
2189 }
2190 } else if (_current_company == OWNER_DEITY && random_location) {
2191 /* Random parameter is not allowed for Game Scripts. */
2192 return { CMD_ERROR, 0, TownID::Invalid() };
2193 }
2194
2195 if (text.empty()) {
2196 /* If supplied name is empty, townnameparts has to generate unique automatic name */
2197 if (!VerifyTownName(townnameparts, &par)) return { CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE), 0, TownID::Invalid() };
2198 } else {
2199 /* If name is not empty, it has to be unique custom name */
2200 if (Utf8StringLength(text) >= MAX_LENGTH_TOWN_NAME_CHARS) return { CMD_ERROR, 0, TownID::Invalid() };
2201 if (!IsUniqueTownName(text)) return { CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE), 0, TownID::Invalid() };
2202 }
2203
2204 /* Allocate town struct */
2205 if (!Town::CanAllocateItem()) return { CommandCost(STR_ERROR_TOO_MANY_TOWNS), 0, TownID::Invalid() };
2206
2207 if (!random_location) {
2208 CommandCost ret = TownCanBePlacedHere(tile, false);
2209 if (ret.Failed()) return { ret, 0, TownID::Invalid() };
2210 }
2211
2212 static const uint8_t price_mult[][TSZ_RANDOM + 1] = {{ 15, 25, 40, 25 }, { 20, 35, 55, 35 }};
2213 /* multidimensional arrays have to have defined length of non-first dimension */
2214 static_assert(lengthof(price_mult[0]) == 4);
2215
2217 uint8_t mult = price_mult[city][size];
2218
2219 cost.MultiplyCost(mult);
2220
2221 /* Create the town */
2222 TownID new_town = TownID::Invalid();
2223 if (flags.Test(DoCommandFlag::Execute)) {
2224 if (cost.GetCost() > GetAvailableMoneyForCommand()) {
2225 return { CommandCost(EXPENSES_OTHER), cost.GetCost(), TownID::Invalid() };
2226 }
2227
2228 Backup<bool> old_generating_world(_generating_world, true);
2230 Town *t;
2231 if (random_location) {
2232 t = CreateRandomTown(20, townnameparts, size, city, layout);
2233 } else {
2234 t = Town::Create(tile);
2235 DoCreateTown(t, tile, townnameparts, size, city, layout, true);
2236 }
2237
2239 old_generating_world.Restore();
2240
2241 if (t == nullptr) return { CommandCost(STR_ERROR_NO_SPACE_FOR_TOWN), 0, TownID::Invalid() };
2242
2243 new_town = t->index;
2244
2245 if (!text.empty()) {
2246 t->name = text;
2247 t->UpdateVirtCoord();
2248 }
2249
2250 if (_game_mode != GM_EDITOR) {
2251 /* 't' can't be nullptr since 'random' is false outside scenedit */
2252 assert(!random_location);
2253
2255 AddTileNewsItem(GetEncodedString(STR_NEWS_NEW_TOWN_UNSPONSORED, t->index), NewsType::IndustryOpen, tile);
2256 } else {
2257 std::string company_name = GetString(STR_COMPANY_NAME, _current_company);
2258 AddTileNewsItem(GetEncodedString(STR_NEWS_NEW_TOWN, company_name, t->index), NewsType::IndustryOpen, tile);
2259 }
2260 AI::BroadcastNewEvent(new ScriptEventTownFounded(t->index));
2261 Game::NewEvent(new ScriptEventTownFounded(t->index));
2262 }
2263 }
2264 return { cost, 0, new_town };
2265}
2266
2277{
2278 switch (layout) {
2279 case TL_2X2_GRID: return TileXY(TileX(tile) - TileX(tile) % 3, TileY(tile) - TileY(tile) % 3);
2280 case TL_3X3_GRID: return TileXY(TileX(tile) & ~3, TileY(tile) & ~3);
2281 default: return tile;
2282 }
2283}
2284
2295{
2296 switch (layout) {
2297 case TL_2X2_GRID: return TileX(tile) % 3 == 0 && TileY(tile) % 3 == 0;
2298 case TL_3X3_GRID: return TileX(tile) % 4 == 0 && TileY(tile) % 4 == 0;
2299 default: return true;
2300 }
2301}
2302
2316{
2317 for (auto coast : SpiralTileSequence(tile, 40)) {
2318 /* Find nearest land tile */
2319 if (!IsTileType(coast, TileType::Clear)) continue;
2320
2321 TileIndex furthest = INVALID_TILE;
2322 uint max_dist = 0;
2323 for (auto test : SpiralTileSequence(coast, 10)) {
2324 if (!IsTileType(test, TileType::Clear) || !IsTileFlat(test) || !IsTileAlignedToGrid(test, layout)) continue;
2325 if (TownCanBePlacedHere(test, true).Failed()) continue;
2326
2327 uint dist = GetClosestWaterDistance(test, true);
2328 if (dist > max_dist) {
2329 furthest = test;
2330 max_dist = dist;
2331 }
2332 }
2333 return furthest;
2334 }
2335
2336 /* if we get here just give up */
2337 return INVALID_TILE;
2338}
2339
2345{
2346 switch (_settings_game.game_creation.landscape) {
2351 default: NOT_REACHED();
2352 }
2353}
2354
2364static Town *CreateRandomTown(uint attempts, uint32_t townnameparts, TownSize size, bool city, TownLayout layout)
2365{
2366 assert(_game_mode == GM_EDITOR || _generating_world); // These are the preconditions for Commands::DeleteTown
2367
2368 if (!Town::CanAllocateItem()) return nullptr;
2369
2370 do {
2371 /* Generate a tile index not too close from the edge */
2372 TileIndex tile = AlignTileToGrid(RandomTile(), layout);
2373
2374 /* If we tried to place the town on water, find a suitable land tile nearby.
2375 * Otherwise, evaluate the land tile. */
2376 if (IsTileType(tile, TileType::Water)) {
2377 tile = FindNearestGoodCoastalTownSpot(tile, layout);
2378 if (tile == INVALID_TILE) continue;
2379 } else if (TownCanBePlacedHere(tile, true).Failed()) continue;
2380
2381 /* Allocate a town struct */
2382 Town *t = Town::Create(tile);
2383
2384 DoCreateTown(t, tile, townnameparts, size, city, layout, false);
2385
2386 /* if the population is still 0 at the point, then the
2387 * placement is so bad it couldn't grow at all */
2388 if (t->cache.population > 0) return t;
2389
2391 [[maybe_unused]] CommandCost rc = Command<Commands::DeleteTown>::Do(DoCommandFlag::Execute, t->index);
2392 cur_company.Restore();
2393 assert(rc.Succeeded());
2394
2395 /* We already know that we can allocate a single town when
2396 * entering this function. However, we create and delete
2397 * a town which "resets" the allocation checks. As such we
2398 * need to check again when assertions are enabled. */
2399 assert(Town::CanAllocateItem());
2400 } while (--attempts != 0);
2401
2402 return nullptr;
2403}
2404
2411{
2412 static const uint8_t num_initial_towns[4] = {5, 11, 23, 46}; // very low, low, normal, high
2413 if (_settings_game.difficulty.number_towns == static_cast<uint>(CUSTOM_TOWN_NUMBER_DIFFICULTY)) {
2414 return _settings_newgame.game_creation.custom_town_number;
2415 }
2416 return Map::ScaleBySize(num_initial_towns[_settings_game.difficulty.number_towns]);
2417}
2418
2426bool GenerateTowns(TownLayout layout, std::optional<uint> number)
2427{
2428 uint current_number = 0;
2429 uint total;
2430 if (number.has_value()) {
2431 total = number.value();
2432 } else if (_settings_game.difficulty.number_towns == static_cast<uint>(CUSTOM_TOWN_NUMBER_DIFFICULTY)) {
2433 total = GetDefaultTownsForMapSize();
2434 } else {
2435 total = Map::ScaleByLandProportion(GetDefaultTownsForMapSize() + (Random() & 7));
2436 }
2437
2438 total = Clamp<uint>(total, 1, TownPool::MAX_SIZE);
2439 uint32_t townnameparts;
2440 TownNames town_names;
2441
2443
2444 /* Pre-populate the town names list with the names of any towns already on the map */
2445 for (const Town *town : Town::Iterate()) {
2446 town_names.insert(town->GetCachedName());
2447 }
2448
2449 /* Randomised offset for city status. This means with e.g. 1-in-4 towns being cities, a map with 10 towns
2450 * may have 2 or 3 cities, instead of always 3. */
2451 uint city_random_offset = _settings_game.economy.larger_towns == 0 ? 0 : (Random() % _settings_game.economy.larger_towns);
2452
2453 /* First attempt will be made at creating the suggested number of towns.
2454 * Note that this is really a suggested value, not a required one.
2455 * We would not like the system to lock up just because the user wanted 100 cities on a 64*64 map, would we? */
2456 do {
2457 bool city = (_settings_game.economy.larger_towns != 0 && ((city_random_offset + current_number) % _settings_game.economy.larger_towns) == 0);
2459 /* Get a unique name for the town. */
2460 if (!GenerateTownName(_random, &townnameparts, &town_names)) continue;
2461 /* try 20 times to create a random-sized town for the first loop. */
2462 if (CreateRandomTown(20, townnameparts, TSZ_RANDOM, city, layout) != nullptr) current_number++; // If creation was successful, raise a flag.
2463 } while (--total);
2464
2465 town_names.clear();
2466
2467 /* Build the town k-d tree again to make sure it's well balanced */
2468 RebuildTownKdtree();
2469
2470 if (current_number != 0) return true;
2471
2472 /* If current_number is still zero at this point, it means that not a single town has been created.
2473 * So give it a last try, but now more aggressive */
2474 if (GenerateTownName(_random, &townnameparts) &&
2475 CreateRandomTown(10000, townnameparts, TSZ_RANDOM, _settings_game.economy.larger_towns != 0, layout) != nullptr) {
2476 return true;
2477 }
2478
2479 /* If there are no towns at all and we are generating new game, bail out */
2480 if (Town::GetNumItems() == 0 && _game_mode != GM_EDITOR) {
2481 ShowErrorMessage(GetEncodedString(STR_ERROR_COULD_NOT_CREATE_TOWN), {}, WL_CRITICAL);
2482 }
2483
2484 return false; // we are still without a town? we failed, simply
2485}
2486
2487
2495{
2496 uint dist = DistanceSquare(tile, t->xy);
2497
2498 if (t->fund_buildings_months != 0 && dist <= 25) return HouseZone::TownCentre;
2499
2500 HouseZone smallest = HouseZone::TownEdge;
2501 for (HouseZone i : HZ_ZONE_ALL) {
2502 if (dist < t->cache.squared_town_zone_radius[to_underlying(i)]) smallest = i;
2503 }
2504
2505 return smallest;
2506}
2507
2519static inline void ClearMakeHouseTile(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool is_protected)
2520{
2521 [[maybe_unused]] CommandCost cc = Command<Commands::LandscapeClear>::Do({DoCommandFlag::Execute, DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile);
2522 assert(cc.Succeeded());
2523
2524 IncreaseBuildingCount(t, type);
2525 MakeHouseTile(tile, t->index, counter, stage, type, random_bits, is_protected);
2526 if (HouseSpec::Get(type)->building_flags.Test(BuildingFlag::IsAnimated)) AddAnimatedTile(tile, false);
2527
2528 MarkTileDirtyByTile(tile);
2529}
2530
2531
2543static void MakeTownHouse(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool is_protected)
2544{
2545 BuildingFlags size = HouseSpec::Get(type)->building_flags;
2546
2547 ClearMakeHouseTile(tile, t, counter, stage, type, random_bits, is_protected);
2548 if (size.Any(BUILDING_2_TILES_Y)) ClearMakeHouseTile(tile + TileDiffXY(0, 1), t, counter, stage, ++type, random_bits, is_protected);
2549 if (size.Any(BUILDING_2_TILES_X)) ClearMakeHouseTile(tile + TileDiffXY(1, 0), t, counter, stage, ++type, random_bits, is_protected);
2550 if (size.Any(BUILDING_HAS_4_TILES)) ClearMakeHouseTile(tile + TileDiffXY(1, 1), t, counter, stage, ++type, random_bits, is_protected);
2551
2552 ForAllStationsAroundTiles(TileArea(tile, size.Any(BUILDING_2_TILES_X) ? 2 : 1, size.Any(BUILDING_2_TILES_Y) ? 2 : 1), [t](Station *st, TileIndex) {
2553 t->stations_near.insert(st);
2554 return true;
2555 });
2556}
2557
2558
2565static inline bool CanBuildHouseHere(TileIndex tile, bool noslope)
2566{
2567 /* cannot build on these slopes... */
2568 Slope slope = GetTileSlope(tile);
2569 if ((noslope && slope != SLOPE_FLAT) || IsSteepSlope(slope)) return false;
2570
2571 /* at least one RoadTypes allow building the house here? */
2572 if (!RoadTypesAllowHouseHere(tile)) return false;
2573
2574 /* building under a bridge? */
2575 if (IsBridgeAbove(tile)) return false;
2576
2577 /* can we clear the land? */
2578 return Command<Commands::LandscapeClear>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile).Succeeded();
2579}
2580
2581
2590static inline bool CheckBuildHouseSameZ(TileIndex tile, int z, bool noslope)
2591{
2592 if (!CanBuildHouseHere(tile, noslope)) return false;
2593
2594 /* if building on slopes is allowed, there will be flattening foundation (to tile max z) */
2595 if (GetTileMaxZ(tile) != z) return false;
2596
2597 return true;
2598}
2599
2600
2609static bool CheckFree2x2Area(TileIndex tile, int z, bool noslope)
2610{
2611 /* we need to check this tile too because we can be at different tile now */
2612 if (!CheckBuildHouseSameZ(tile, z, noslope)) return false;
2613
2614 for (DiagDirection d = DIAGDIR_SE; d < DIAGDIR_END; d++) {
2615 tile += TileOffsByDiagDir(d);
2616 if (!CheckBuildHouseSameZ(tile, z, noslope)) return false;
2617 }
2618
2619 return true;
2620}
2621
2622
2631static inline bool TownLayoutAllowsHouseHere(Town *t, TileIndex tile, TownExpandModes modes)
2632{
2633 if (!modes.Test(TownExpandMode::Buildings)) return false;
2634
2635 /* Allow towns everywhere when we don't build roads */
2636 if (!TownAllowedToBuildRoads(modes)) return true;
2637
2638 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
2639
2640 switch (t->layout) {
2641 case TL_2X2_GRID:
2642 if ((grid_pos.x % 3) == 0 || (grid_pos.y % 3) == 0) return false;
2643 break;
2644
2645 case TL_3X3_GRID:
2646 if ((grid_pos.x % 4) == 0 || (grid_pos.y % 4) == 0) return false;
2647 break;
2648
2649 default:
2650 break;
2651 }
2652
2653 return true;
2654}
2655
2656
2665static inline bool TownLayoutAllows2x2HouseHere(Town *t, TileIndex tile, TownExpandModes modes)
2666{
2667 if (!modes.Test(TownExpandMode::Buildings)) return false;
2668
2669 /* Allow towns everywhere when we don't build roads */
2670 if (!TownAllowedToBuildRoads(modes)) return true;
2671
2672 /* Compute relative position of tile. (Positive offsets are towards north) */
2673 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
2674
2675 switch (t->layout) {
2676 case TL_2X2_GRID:
2677 grid_pos.x %= 3;
2678 grid_pos.y %= 3;
2679 if ((grid_pos.x != 2 && grid_pos.x != -1) ||
2680 (grid_pos.y != 2 && grid_pos.y != -1)) return false;
2681 break;
2682
2683 case TL_3X3_GRID:
2684 if ((grid_pos.x & 3) < 2 || (grid_pos.y & 3) < 2) return false;
2685 break;
2686
2687 default:
2688 break;
2689 }
2690
2691 return true;
2692}
2693
2694
2706static bool CheckTownBuild2House(TileIndex *tile, Town *t, int maxz, bool noslope, DiagDirection second, TownExpandModes modes)
2707{
2708 /* 'tile' is already checked in BuildTownHouse() - CanBuildHouseHere() and slope test */
2709
2710 TileIndex tile2 = *tile + TileOffsByDiagDir(second);
2711 if (TownLayoutAllowsHouseHere(t, tile2, modes) && CheckBuildHouseSameZ(tile2, maxz, noslope)) return true;
2712
2713 tile2 = *tile + TileOffsByDiagDir(ReverseDiagDir(second));
2714 if (TownLayoutAllowsHouseHere(t, tile2, modes) && CheckBuildHouseSameZ(tile2, maxz, noslope)) {
2715 *tile = tile2;
2716 return true;
2717 }
2718
2719 return false;
2720}
2721
2722
2733static bool CheckTownBuild2x2House(TileIndex *tile, Town *t, int maxz, bool noslope, TownExpandModes modes)
2734{
2735 TileIndex tile2 = *tile;
2736
2737 for (DiagDirection d = DIAGDIR_SE;; d++) { // 'd' goes through DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_END
2738 if (TownLayoutAllows2x2HouseHere(t, tile2, modes) && CheckFree2x2Area(tile2, maxz, noslope)) {
2739 *tile = tile2;
2740 return true;
2741 }
2742 if (d == DIAGDIR_END) break;
2743 tile2 += TileOffsByDiagDir(ReverseDiagDir(d)); // go clockwise
2744 }
2745
2746 return false;
2747}
2748
2759static void BuildTownHouse(Town *t, TileIndex tile, const HouseSpec *hs, HouseID house, uint8_t random_bits, bool house_completed, bool is_protected)
2760{
2761 /* build the house */
2762 t->cache.num_houses++;
2763
2764 uint8_t construction_counter = 0;
2765 uint8_t construction_stage = 0;
2766
2767 if (_generating_world || _game_mode == GM_EDITOR || house_completed) {
2768 uint32_t construction_random = Random();
2769
2770 construction_stage = TOWN_HOUSE_COMPLETED;
2771 if (_generating_world && !hs->extra_flags.Test(HouseExtraFlag::BuildingIsHistorical) && Chance16(1, 7)) construction_stage = GB(construction_random, 0, 2);
2772
2773 if (construction_stage == TOWN_HOUSE_COMPLETED) {
2775 } else {
2776 construction_counter = GB(construction_random, 2, 2);
2777 }
2778 }
2779
2780 MakeTownHouse(tile, t, construction_counter, construction_stage, house, random_bits, is_protected);
2783
2784 BuildingFlags size = hs->building_flags;
2785
2786 TriggerHouseAnimation_ConstructionStageChanged(tile, true);
2787 if (size.Any(BUILDING_2_TILES_Y)) TriggerHouseAnimation_ConstructionStageChanged(tile + TileDiffXY(0, 1), true);
2788 if (size.Any(BUILDING_2_TILES_X)) TriggerHouseAnimation_ConstructionStageChanged(tile + TileDiffXY(1, 0), true);
2789 if (size.Any(BUILDING_HAS_4_TILES)) TriggerHouseAnimation_ConstructionStageChanged(tile + TileDiffXY(1, 1), true);
2790}
2791
2799static bool TryBuildTownHouse(Town *t, TileIndex tile, TownExpandModes modes)
2800{
2801 /* forbidden building here by town layout */
2802 if (!TownLayoutAllowsHouseHere(t, tile, modes)) return false;
2803
2804 /* no house allowed at all, bail out */
2805 if (!CanBuildHouseHere(tile, false)) return false;
2806
2807 Slope slope = GetTileSlope(tile);
2808 int maxz = GetTileMaxZ(tile);
2809
2810 /* Get the town zone type of the current tile, as well as the climate.
2811 * This will allow to easily compare with the specs of the new house to build */
2812 HouseZones zones = GetTownRadiusGroup(t, tile);
2813
2814 switch (_settings_game.game_creation.landscape) {
2819 }
2820
2821 /* bits 0-4 are used
2822 * bits 11-15 are used
2823 * bits 5-10 are not used. */
2824 static std::vector<std::pair<HouseID, uint>> probs;
2825 probs.clear();
2826
2827 uint probability_max = 0;
2828
2829 /* Generate a list of all possible houses that can be built. */
2830 for (const auto &hs : HouseSpec::Specs()) {
2831 /* Verify that the candidate house spec matches the current tile status */
2832 if (!hs.building_availability.All(zones) || !hs.enabled || hs.grf_prop.override_id != INVALID_HOUSE_ID) continue;
2833
2834 /* Don't let these counters overflow. Global counters are 32bit, there will never be that many houses. */
2835 if (hs.class_id != HOUSE_NO_CLASS) {
2836 /* id_count is always <= class_count, so it doesn't need to be checked */
2837 if (t->cache.building_counts.class_count[hs.class_id] == UINT16_MAX) continue;
2838 } else {
2839 /* If the house has no class, check id_count instead */
2840 if (t->cache.building_counts.id_count[hs.Index()] == UINT16_MAX) continue;
2841 }
2842
2843 uint cur_prob = hs.probability;
2844 probability_max += cur_prob;
2845 probs.emplace_back(hs.Index(), cur_prob);
2846 }
2847
2848 TileIndex base_tile = tile;
2849
2850 while (probability_max > 0) {
2851 /* Building a multitile building can change the location of tile.
2852 * The building would still be built partially on that tile, but
2853 * its northern tile would be elsewhere. However, if the callback
2854 * fails we would be basing further work from the changed tile.
2855 * So a next 1x1 tile building could be built on the wrong tile. */
2856 tile = base_tile;
2857
2858 uint r = RandomRange(probability_max);
2859 uint i;
2860 for (i = 0; i < probs.size(); i++) {
2861 if (probs[i].second > r) break;
2862 r -= probs[i].second;
2863 }
2864
2865 HouseID house = probs[i].first;
2866 probability_max -= probs[i].second;
2867
2868 /* remove tested house from the set */
2869 probs[i] = probs.back();
2870 probs.pop_back();
2871
2872 const HouseSpec *hs = HouseSpec::Get(house);
2873
2874 if (!_generating_world && _game_mode != GM_EDITOR && hs->extra_flags.Test(HouseExtraFlag::BuildingIsHistorical)) {
2875 continue;
2876 }
2877
2879
2880 /* Special houses that there can be only one of. */
2881 TownFlags oneof{};
2882
2884 oneof.Set(TownFlag::HasChurch);
2887 }
2888
2889 if (t->flags.Any(oneof)) continue;
2890
2891 /* Make sure there is no slope? */
2892 bool noslope = hs->building_flags.Test(BuildingFlag::NotSloped);
2893 if (noslope && slope != SLOPE_FLAT) continue;
2894
2896 if (!CheckTownBuild2x2House(&tile, t, maxz, noslope, modes)) continue;
2897 } else if (hs->building_flags.Test(BuildingFlag::Size2x1)) {
2898 if (!CheckTownBuild2House(&tile, t, maxz, noslope, DIAGDIR_SW, modes)) continue;
2899 } else if (hs->building_flags.Test(BuildingFlag::Size1x2)) {
2900 if (!CheckTownBuild2House(&tile, t, maxz, noslope, DIAGDIR_SE, modes)) continue;
2901 } else {
2902 /* 1x1 house checks are already done */
2903 }
2904
2905 uint8_t random_bits = Random();
2906
2908 uint16_t callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile, {}, true, random_bits);
2909 if (callback_res != CALLBACK_FAILED && !Convert8bitBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_ALLOW_CONSTRUCTION, callback_res)) continue;
2910 }
2911
2912 /* Special houses that there can be only one of. */
2913 t->flags.Set(oneof);
2914
2915 BuildTownHouse(t, tile, hs, house, random_bits, false, hs->extra_flags.Test(HouseExtraFlag::BuildingIsProtected));
2916
2917 return true;
2918 }
2919
2920 return false;
2921}
2922
2932CommandCost CmdPlaceHouse(DoCommandFlags flags, TileIndex tile, HouseID house, bool is_protected, bool replace)
2933{
2934 if (_game_mode != GM_EDITOR && _settings_game.economy.place_houses == PlaceHouses::Forbidden) return CMD_ERROR;
2935
2936 if (Town::GetNumItems() == 0) return CommandCost(STR_ERROR_MUST_FOUND_TOWN_FIRST);
2937
2938 if (static_cast<size_t>(house) >= HouseSpec::Specs().size()) return CMD_ERROR;
2939 const HouseSpec *hs = HouseSpec::Get(house);
2940 if (!hs->enabled) return CMD_ERROR;
2941
2942 int maxz = GetTileMaxZ(tile);
2943
2944 /* Check each tile of a multi-tile house. */
2945 TileArea ta(tile, 1, 1);
2946 if (hs->building_flags.Test(BuildingFlag::Size2x2)) ta.Add(TileAddXY(tile, 1, 1));
2949
2950 for (const TileIndex subtile : ta) {
2951 /* Houses cannot be built on steep slopes. */
2952 Slope slope = GetTileSlope(subtile);
2953 if (IsSteepSlope(slope)) return CommandCost(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
2954
2955 /* Houses cannot be built under bridges. */
2956 if (IsBridgeAbove(subtile)) return CommandCost(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
2957
2958 /* Make sure there is no slope? */
2959 bool noslope = hs->building_flags.Test(BuildingFlag::NotSloped);
2960 if (noslope && slope != SLOPE_FLAT) return CommandCost(STR_ERROR_FLAT_LAND_REQUIRED);
2961
2962 /* All tiles of a multi-tile house must have the same z-level. */
2963 if (GetTileMaxZ(subtile) != maxz) return CommandCost(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
2964
2965 /* We might be replacing an existing house, otherwise check if we can clear land. */
2966 if (!(replace && GetTileType(subtile) == TileType::House)) {
2967 CommandCost cost = Command<Commands::LandscapeClear>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, subtile);
2968 if (!cost.Succeeded()) return cost;
2969 }
2970 }
2971
2972 if (flags.Test(DoCommandFlag::Execute)) {
2973 /* If replacing, clear any existing houses first. */
2974 if (replace) {
2975 for (const TileIndex &subtile : ta) {
2976 if (GetTileType(subtile) == TileType::House) ClearTownHouse(Town::GetByTile(subtile), subtile);
2977 }
2978 }
2979
2980 Town *t = ClosestTownFromTile(tile, UINT_MAX);
2981 bool house_completed = _settings_game.economy.place_houses == PlaceHouses::AllowedConstructed;
2982 BuildTownHouse(t, tile, hs, house, Random(), house_completed, is_protected);
2983 }
2984
2985 return CommandCost();
2986}
2987
2999CommandCost CmdPlaceHouseArea(DoCommandFlags flags, TileIndex tile, TileIndex start_tile, HouseID house, bool is_protected, bool replace, bool diagonal)
3000{
3001 if (start_tile >= Map::Size()) return CMD_ERROR;
3002
3003 if (_game_mode != GM_EDITOR && _settings_game.economy.place_houses == PlaceHouses::Forbidden) return CMD_ERROR;
3004
3005 if (Town::GetNumItems() == 0) return CommandCost(STR_ERROR_MUST_FOUND_TOWN_FIRST);
3006
3007 if (static_cast<size_t>(house) >= HouseSpec::Specs().size()) return CMD_ERROR;
3008 const HouseSpec *hs = HouseSpec::Get(house);
3009 if (!hs->enabled) return CMD_ERROR;
3010
3011 /* Only allow placing an area of 1x1 houses. */
3013
3014 /* Use the built object limit to rate limit house placement. */
3016 int limit = (c == nullptr ? INT32_MAX : GB(c->build_object_limit, 16, 16));
3017
3018 CommandCost last_error = CMD_ERROR;
3019 bool had_success = false;
3020
3021 std::unique_ptr<TileIterator> iter = TileIterator::Create(tile, start_tile, diagonal);
3022 for (; *iter != INVALID_TILE; ++(*iter)) {
3023 TileIndex t = *iter;
3024 CommandCost ret = Command<Commands::PlaceHouse>::Do(DoCommandFlags{flags}.Reset(DoCommandFlag::Execute), t, house, is_protected, replace);
3025
3026 /* If we've reached the limit, stop building (or testing). */
3027 if (c != nullptr && limit-- <= 0) break;
3028
3029 if (ret.Failed()) {
3030 last_error = std::move(ret);
3031 continue;
3032 }
3033
3034 if (flags.Test(DoCommandFlag::Execute)) Command<Commands::PlaceHouse>::Do(flags, t, house, is_protected, replace);
3035 had_success = true;
3036 }
3037
3038 return had_success ? CommandCost{} : last_error;
3039}
3040
3047static void DoClearTownHouseHelper(TileIndex tile, Town *t, HouseID house)
3048{
3049 assert(IsTileType(tile, TileType::House));
3050 DecreaseBuildingCount(t, house);
3051 DoClearSquare(tile);
3052
3053 DeleteNewGRFInspectWindow(GSF_HOUSES, tile.base());
3054}
3055
3064{
3065 if (house >= 3) { // house id 0,1,2 MUST be single tile houses, or this code breaks.
3066 if (HouseSpec::Get(house - 1)->building_flags.Test(BuildingFlag::Size2x1)) {
3067 house--;
3068 return TileDiffXY(-1, 0);
3069 } else if (HouseSpec::Get(house - 1)->building_flags.Any(BUILDING_2_TILES_Y)) {
3070 house--;
3071 return TileDiffXY(0, -1);
3072 } else if (HouseSpec::Get(house - 2)->building_flags.Any(BUILDING_HAS_4_TILES)) {
3073 house -= 2;
3074 return TileDiffXY(-1, 0);
3075 } else if (HouseSpec::Get(house - 3)->building_flags.Any(BUILDING_HAS_4_TILES)) {
3076 house -= 3;
3077 return TileDiffXY(-1, -1);
3078 }
3079 }
3080 return TileDiffXY(0, 0);
3081}
3082
3089{
3090 assert(IsTileType(tile, TileType::House));
3091
3092 HouseID house = GetHouseType(tile);
3093
3094 /* The northernmost tile of the house is the main house. */
3095 tile += GetHouseNorthPart(house);
3096
3097 const HouseSpec *hs = HouseSpec::Get(house);
3098
3099 /* Remove population from the town if the house is finished. */
3100 if (IsHouseCompleted(tile)) {
3102 }
3103
3104 t->cache.num_houses--;
3105
3106 /* Clear flags for houses that only may exist once/town. */
3111 }
3112
3113 /* Do the actual clearing of tiles */
3114 DoClearTownHouseHelper(tile, t, house);
3115 if (hs->building_flags.Any(BUILDING_2_TILES_Y)) DoClearTownHouseHelper(tile + TileDiffXY(0, 1), t, ++house);
3116 if (hs->building_flags.Any(BUILDING_2_TILES_X)) DoClearTownHouseHelper(tile + TileDiffXY(1, 0), t, ++house);
3117 if (hs->building_flags.Any(BUILDING_HAS_4_TILES)) DoClearTownHouseHelper(tile + TileDiffXY(1, 1), t, ++house);
3118
3120
3122}
3123
3131CommandCost CmdRenameTown(DoCommandFlags flags, TownID town_id, const std::string &text)
3132{
3133 Town *t = Town::GetIfValid(town_id);
3134 if (t == nullptr) return CMD_ERROR;
3135
3136 bool reset = text.empty();
3137
3138 if (!reset) {
3140 if (!IsUniqueTownName(text)) return CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE);
3141 }
3142
3143 if (flags.Test(DoCommandFlag::Execute)) {
3144 t->cached_name.clear();
3145 if (reset) {
3146 t->name.clear();
3147 } else {
3148 t->name = text;
3149 }
3150
3151 t->UpdateVirtCoord();
3152 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_RESORT);
3153 ClearAllStationCachedNames();
3154 ClearAllIndustryCachedNames();
3156 }
3157 return CommandCost();
3158}
3159
3166{
3167 for (const CargoSpec *cs : CargoSpec::Iterate()) {
3168 if (cs->town_acceptance_effect == effect) return cs;
3169 }
3170 return nullptr;
3171}
3172
3181CommandCost CmdTownCargoGoal(DoCommandFlags flags, TownID town_id, TownAcceptanceEffect tae, uint32_t goal)
3182{
3183 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3184
3185 if (tae < TAE_BEGIN || tae >= TAE_END) return CMD_ERROR;
3186
3187 Town *t = Town::GetIfValid(town_id);
3188 if (t == nullptr) return CMD_ERROR;
3189
3190 /* Validate if there is a cargo which is the requested TownEffect */
3192 if (cargo == nullptr) return CMD_ERROR;
3193
3194 if (flags.Test(DoCommandFlag::Execute)) {
3195 t->goal[tae] = goal;
3198 }
3199
3200 return CommandCost();
3201}
3202
3210CommandCost CmdTownSetText(DoCommandFlags flags, TownID town_id, const EncodedString &text)
3211{
3212 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3213 Town *t = Town::GetIfValid(town_id);
3214 if (t == nullptr) return CMD_ERROR;
3215
3216 if (flags.Test(DoCommandFlag::Execute)) {
3217 t->text.clear();
3218 if (!text.empty()) t->text = text;
3220 }
3221
3222 return CommandCost();
3223}
3224
3232CommandCost CmdTownGrowthRate(DoCommandFlags flags, TownID town_id, uint16_t growth_rate)
3233{
3234 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3235
3236 Town *t = Town::GetIfValid(town_id);
3237 if (t == nullptr) return CMD_ERROR;
3238
3239 if (flags.Test(DoCommandFlag::Execute)) {
3240 if (growth_rate == 0) {
3241 /* Just clear the flag, UpdateTownGrowth will determine a proper growth rate */
3243 } else {
3244 uint old_rate = t->growth_rate;
3245 if (t->grow_counter >= old_rate) {
3246 /* This also catches old_rate == 0 */
3247 t->grow_counter = growth_rate;
3248 } else {
3249 /* Scale grow_counter, so half finished houses stay half finished */
3250 t->grow_counter = t->grow_counter * growth_rate / old_rate;
3251 }
3252 t->growth_rate = growth_rate;
3254 }
3257 }
3258
3259 return CommandCost();
3260}
3261
3270CommandCost CmdTownRating(DoCommandFlags flags, TownID town_id, CompanyID company_id, int16_t rating)
3271{
3272 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3273
3274 Town *t = Town::GetIfValid(town_id);
3275 if (t == nullptr) return CMD_ERROR;
3276
3277 if (!Company::IsValidID(company_id)) return CMD_ERROR;
3278
3279 int16_t new_rating = Clamp(rating, RATING_MINIMUM, RATING_MAXIMUM);
3280 if (flags.Test(DoCommandFlag::Execute)) {
3281 t->ratings[company_id] = new_rating;
3283 }
3284
3285 return CommandCost();
3286}
3287
3296CommandCost CmdExpandTown(DoCommandFlags flags, TownID town_id, uint32_t grow_amount, TownExpandModes modes)
3297{
3298 if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY) return CMD_ERROR;
3299 if (modes.None()) return CMD_ERROR;
3300 Town *t = Town::GetIfValid(town_id);
3301 if (t == nullptr) return CMD_ERROR;
3302
3303 if (flags.Test(DoCommandFlag::Execute)) {
3304 /* The more houses, the faster we grow */
3305 if (grow_amount == 0) {
3306 uint amount = RandomRange(ClampTo<uint16_t>(t->cache.num_houses / 10)) + 3;
3307 t->cache.num_houses += amount;
3309
3310 uint n = amount * 10;
3311 do GrowTown(t, modes); while (--n);
3312
3313 t->cache.num_houses -= amount;
3314 } else {
3315 for (; grow_amount > 0; grow_amount--) {
3316 /* Try several times to grow, as we are really suppose to grow */
3317 for (uint i = 0; i < 25; i++) if (GrowTown(t, modes)) break;
3318 }
3319 }
3321
3323 }
3324
3325 return CommandCost();
3326}
3327
3334CommandCost CmdDeleteTown(DoCommandFlags flags, TownID town_id)
3335{
3336 if (_game_mode != GM_EDITOR && !_generating_world) return CMD_ERROR;
3337 Town *t = Town::GetIfValid(town_id);
3338 if (t == nullptr) return CMD_ERROR;
3339
3340 /* Stations refer to towns. */
3341 for (const Station *st : Station::Iterate()) {
3342 if (st->town == t) {
3343 /* Non-oil rig stations are always a problem. */
3344 if (!st->facilities.Test(StationFacility::Airport) || st->airport.type != AT_OILRIG) return CMD_ERROR;
3345 /* We can only automatically delete oil rigs *if* there's no vehicle on them. */
3346 CommandCost ret = Command<Commands::LandscapeClear>::Do(flags, st->airport.tile);
3347 if (ret.Failed()) return ret;
3348 }
3349 }
3350
3351 /* Waypoints refer to towns. */
3352 for (const Waypoint *wp : Waypoint::Iterate()) {
3353 if (wp->town == t) return CMD_ERROR;
3354 }
3355
3356 /* Depots refer to towns. */
3357 for (const Depot *d : Depot::Iterate()) {
3358 if (d->town == t) return CMD_ERROR;
3359 }
3360
3361 /* Check all tiles for town ownership. First check for bridge tiles, as
3362 * these do not directly have an owner so we need to check adjacent
3363 * tiles. This won't work correctly in the same loop if the adjacent
3364 * tile was already deleted earlier in the loop. */
3365 for (const auto current_tile : Map::Iterate()) {
3366 if (IsTileType(current_tile, TileType::TunnelBridge) && TestTownOwnsBridge(current_tile, t)) {
3367 CommandCost ret = Command<Commands::LandscapeClear>::Do(flags, current_tile);
3368 if (ret.Failed()) return ret;
3369 }
3370 }
3371
3372 /* Check all remaining tiles for town ownership. */
3373 for (const auto current_tile : Map::Iterate()) {
3374 bool try_clear = false;
3375 switch (GetTileType(current_tile)) {
3376 case TileType::Road:
3377 try_clear = HasTownOwnedRoad(current_tile) && GetTownIndex(current_tile) == t->index;
3378 break;
3379
3380 case TileType::House:
3381 try_clear = GetTownIndex(current_tile) == t->index;
3382 break;
3383
3384 case TileType::Industry:
3385 try_clear = Industry::GetByTile(current_tile)->town == t;
3386 break;
3387
3388 case TileType::Object:
3389 if (Town::GetNumItems() == 1) {
3390 /* No towns will be left, remove it! */
3391 try_clear = true;
3392 } else {
3393 Object *o = Object::GetByTile(current_tile);
3394 if (o->town == t) {
3395 if (o->type == OBJECT_STATUE) {
3396 /* Statue... always remove. */
3397 try_clear = true;
3398 } else {
3399 /* Tell to find a new town. */
3400 if (flags.Test(DoCommandFlag::Execute)) o->town = nullptr;
3401 }
3402 }
3403 }
3404 break;
3405
3406 default:
3407 break;
3408 }
3409 if (try_clear) {
3410 CommandCost ret = Command<Commands::LandscapeClear>::Do(flags, current_tile);
3411 if (ret.Failed()) return ret;
3412 }
3413 }
3414
3415 /* The town destructor will delete the other things related to the town. */
3416 if (flags.Test(DoCommandFlag::Execute)) {
3417 _town_kdtree.Remove(t->index);
3418 if (t->cache.sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeTown(t->index));
3419 delete t;
3420 }
3421
3422 return CommandCost();
3423}
3424
3431{
3436 static const uint8_t town_action_costs[] = {
3437 2, 4, 9, 35, 48, 53, 117, 175
3438 };
3439 static_assert(std::size(town_action_costs) == to_underlying(TownAction::End));
3440
3441 assert(to_underlying(action) < std::size(town_action_costs));
3442 return town_action_costs[to_underlying(action)];
3443}
3444
3451static CommandCost TownActionAdvertiseSmall(Town *t, DoCommandFlags flags)
3452{
3453 if (flags.Test(DoCommandFlag::Execute)) {
3455 }
3456 return CommandCost();
3457}
3458
3465static CommandCost TownActionAdvertiseMedium(Town *t, DoCommandFlags flags)
3466{
3467 if (flags.Test(DoCommandFlag::Execute)) {
3469 }
3470 return CommandCost();
3471}
3472
3479static CommandCost TownActionAdvertiseLarge(Town *t, DoCommandFlags flags)
3480{
3481 if (flags.Test(DoCommandFlag::Execute)) {
3483 }
3484 return CommandCost();
3485}
3486
3493static CommandCost TownActionRoadRebuild(Town *t, DoCommandFlags flags)
3494{
3495 /* Check if the company is allowed to fund new roads. */
3496 if (!_settings_game.economy.fund_roads) return CMD_ERROR;
3497
3498 if (flags.Test(DoCommandFlag::Execute)) {
3499 t->road_build_months = 6;
3500
3501 std::string company_name = GetString(STR_COMPANY_NAME, _current_company);
3502
3504 GetEncodedString(TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_ROAD_REBUILDING_MINUTES : STR_NEWS_ROAD_REBUILDING_MONTHS, t->index, company_name),
3505 NewsType::General, NewsStyle::Normal, {}, t->index);
3506 AI::BroadcastNewEvent(new ScriptEventRoadReconstruction(_current_company, t->index));
3507 Game::NewEvent(new ScriptEventRoadReconstruction(_current_company, t->index));
3508 }
3509 return CommandCost();
3510}
3511
3517static bool CheckClearTile(TileIndex tile)
3518{
3520 CommandCost r = Command<Commands::LandscapeClear>::Do({}, tile);
3521 cur_company.Restore();
3522 return r.Succeeded();
3523}
3524
3532static CommandCost TownActionBuildStatue(Town *t, DoCommandFlags flags)
3533{
3534 if (!Object::CanAllocateItem()) return CommandCost(STR_ERROR_TOO_MANY_OBJECTS);
3535
3536 static const int STATUE_NUMBER_INNER_TILES = 25; // Number of tiles int the center of the city, where we try to protect houses.
3537
3538 TileIndex best_position = INVALID_TILE;
3539 uint tile_count = 0;
3540 for (auto tile : SpiralTileSequence(t->xy, 9)) {
3541 tile_count++;
3542
3543 /* Statues can be build on slopes, just like houses. Only the steep slopes is a no go. */
3544 if (IsSteepSlope(GetTileSlope(tile))) continue;
3545 /* Don't build statues under bridges. */
3546 if (IsBridgeAbove(tile)) continue;
3547
3548 /* A clear-able open space is always preferred. */
3549 if ((IsTileType(tile, TileType::Clear) || IsTileType(tile, TileType::Trees)) && CheckClearTile(tile)) {
3550 best_position = tile;
3551 break;
3552 }
3553
3554 bool house = IsTileType(tile, TileType::House);
3555
3556 /* Searching inside the inner circle. */
3557 if (tile_count <= STATUE_NUMBER_INNER_TILES) {
3558 /* Save first house in inner circle. */
3559 if (house && best_position == INVALID_TILE && CheckClearTile(tile)) {
3560 best_position = tile;
3561 }
3562
3563 /* If we have reached the end of the inner circle, and have a saved house, terminate the search. */
3564 if (tile_count == STATUE_NUMBER_INNER_TILES && best_position != INVALID_TILE) break;
3565 }
3566
3567 /* Searching outside the circle, just pick the first possible spot. */
3568 if (!house || !CheckClearTile(tile)) continue;
3569 best_position = tile;
3570 break;
3571 }
3572 if (best_position == INVALID_TILE) return CommandCost(STR_ERROR_STATUE_NO_SUITABLE_PLACE);
3573
3574 if (flags.Test(DoCommandFlag::Execute)) {
3576 Command<Commands::LandscapeClear>::Do(DoCommandFlag::Execute, best_position);
3577 cur_company.Restore();
3578 BuildObject(OBJECT_STATUE, best_position, _current_company, t);
3579 t->statues.Set(_current_company); // Once found and built, "inform" the Town.
3580 MarkTileDirtyByTile(best_position);
3581 }
3582 return CommandCost();
3583}
3584
3591static CommandCost TownActionFundBuildings(Town *t, DoCommandFlags flags)
3592{
3593 /* Check if it's allowed to buy the rights */
3594 if (!_settings_game.economy.fund_buildings) return CMD_ERROR;
3595
3596 if (flags.Test(DoCommandFlag::Execute)) {
3597 /* And grow for 3 months */
3598 t->fund_buildings_months = 3;
3599
3600 /* Enable growth (also checking GameScript's opinion) */
3602
3603 /* Build a new house, but add a small delay to make sure
3604 * that spamming funding doesn't let town grow any faster
3605 * than 1 house per 2 * TOWN_GROWTH_TICKS ticks.
3606 * Also emulate original behaviour when town was only growing in
3607 * TOWN_GROWTH_TICKS intervals, to make sure that it's not too
3608 * tick-perfect and gives player some time window where they can
3609 * spam funding with the exact same efficiency.
3610 */
3612
3613 SetWindowDirty(WC_TOWN_VIEW, t->index);
3614 }
3615 return CommandCost();
3616}
3617
3624static CommandCost TownActionBuyRights(Town *t, DoCommandFlags flags)
3625{
3626 /* Check if it's allowed to buy the rights */
3627 if (!_settings_game.economy.exclusive_rights) return CMD_ERROR;
3628 if (t->exclusivity != CompanyID::Invalid()) return CMD_ERROR;
3629
3630 if (flags.Test(DoCommandFlag::Execute)) {
3631 t->exclusive_counter = 12;
3633
3635
3637
3638 /* Spawn news message */
3639 auto cni = std::make_unique<CompanyNewsInformation>(STR_NEWS_EXCLUSIVE_RIGHTS_TITLE, Company::Get(_current_company));
3640 EncodedString message = GetEncodedString(TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MINUTES : STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MONTHS, t->index, cni->company_name);
3641 AddNewsItem(std::move(message),
3642 NewsType::General, NewsStyle::Company, {}, t->index, {}, std::move(cni));
3643 AI::BroadcastNewEvent(new ScriptEventExclusiveTransportRights(_current_company, t->index));
3644 Game::NewEvent(new ScriptEventExclusiveTransportRights(_current_company, t->index));
3645 }
3646 return CommandCost();
3647}
3648
3655static CommandCost TownActionBribe(Town *t, DoCommandFlags flags)
3656{
3657 if (flags.Test(DoCommandFlag::Execute)) {
3658 if (Chance16(1, 14)) {
3659 /* set as unwanted for 6 months */
3660 t->unwanted[_current_company] = 6;
3661
3662 /* set all close by station ratings to 0 */
3663 for (Station *st : Station::Iterate()) {
3664 if (st->town == t && st->owner == _current_company) {
3665 for (GoodsEntry &ge : st->goods) ge.rating = 0;
3666 }
3667 }
3668
3669 /* only show error message to the executing player. All errors are handled command.c
3670 * but this is special, because it can only 'fail' on a DoCommandFlag::Execute */
3671 if (IsLocalCompany()) ShowErrorMessage(GetEncodedString(STR_ERROR_BRIBE_FAILED), {}, WL_INFO);
3672
3673 /* decrease by a lot!
3674 * ChangeTownRating is only for stuff in demolishing. Bribe failure should
3675 * be independent of any cheat settings
3676 */
3677 if (t->ratings[_current_company] > RATING_BRIBE_DOWN_TO) {
3678 t->ratings[_current_company] = RATING_BRIBE_DOWN_TO;
3680 }
3681 } else {
3682 ChangeTownRating(t, RATING_BRIBE_UP_STEP, RATING_BRIBE_MAXIMUM, DoCommandFlag::Execute);
3683 if (t->exclusivity != _current_company && t->exclusivity != CompanyID::Invalid()) {
3684 t->exclusivity = CompanyID::Invalid();
3685 t->exclusive_counter = 0;
3686 }
3687 }
3688 }
3689 return CommandCost();
3690}
3691
3692typedef CommandCost TownActionProc(Town *t, DoCommandFlags flags);
3693static TownActionProc * const _town_action_proc[] = {
3702};
3703static_assert(std::size(_town_action_proc) == to_underlying(TownAction::End));
3704
3711TownActions GetMaskOfTownActions(CompanyID cid, const Town *t)
3712{
3713 TownActions buttons{};
3714
3715 /* Spectators and unwanted have no options */
3716 if (cid != COMPANY_SPECTATOR && !(_settings_game.economy.bribe && t->unwanted[cid])) {
3717
3718 /* Actions worth more than this are not able to be performed */
3719 Money avail = GetAvailableMoney(cid);
3720
3721 /* Check the action bits for validity and
3722 * if they are valid add them */
3723 for (TownAction cur = {}; cur != TownAction::End; ++cur) {
3724
3725 /* Is the company prohibited from bribing ? */
3726 if (cur == TownAction::Bribe) {
3727 /* Company can't bribe if setting is disabled */
3728 if (!_settings_game.economy.bribe) continue;
3729 /* Company can bribe if another company has exclusive transport rights,
3730 * or its standing with the town is less than outstanding. */
3731 if (t->ratings[cid] >= RATING_BRIBE_MAXIMUM) {
3732 if (t->exclusivity == _current_company) continue;
3733 if (t->exclusive_counter == 0) continue;
3734 }
3735 }
3736
3737 /* Is the company not able to buy exclusive rights ? */
3738 if (cur == TownAction::BuyRights && (!_settings_game.economy.exclusive_rights || t->exclusive_counter != 0)) continue;
3739
3740 /* Is the company not able to fund buildings ? */
3741 if (cur == TownAction::FundBuildings && !_settings_game.economy.fund_buildings) continue;
3742
3743 /* Is the company not able to fund local road reconstruction? */
3744 if (cur == TownAction::RoadRebuild && !_settings_game.economy.fund_roads) continue;
3745
3746 /* Is the company not able to build a statue ? */
3747 if (cur == TownAction::BuildStatue && t->statues.Test(cid)) continue;
3748
3749 if (avail >= GetTownActionCost(cur) * _price[Price::TownAction] >> 8) {
3750 buttons.Set(cur);
3751 }
3752 }
3753 }
3754
3755 return buttons;
3756}
3757
3767CommandCost CmdDoTownAction(DoCommandFlags flags, TownID town_id, TownAction action)
3768{
3769 Town *t = Town::GetIfValid(town_id);
3770 if (t == nullptr || to_underlying(action) >= std::size(_town_action_proc)) return CMD_ERROR;
3771
3772 if (!GetMaskOfTownActions(_current_company, t).Test(action)) return CMD_ERROR;
3773
3775
3776 CommandCost ret = _town_action_proc[to_underlying(action)](t, flags);
3777 if (ret.Failed()) return ret;
3778
3779 if (flags.Test(DoCommandFlag::Execute)) {
3781 }
3782
3783 return cost;
3784}
3785
3786template <typename Func>
3787static void ForAllStationsNearTown(Town *t, Func func)
3788{
3789 /* Ideally the search radius should be close to the actual town zone 0 radius.
3790 * The true radius is not stored or calculated anywhere, only the squared radius. */
3791 /* The efficiency of this search might be improved for large towns and many stations on the map,
3792 * by using an integer square root approximation giving a value not less than the true square root. */
3794 ForAllStationsRadius(t->xy, search_radius, [&](const Station * st) {
3795 if (DistanceSquare(st->xy, t->xy) <= t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownEdge)]) {
3796 func(st);
3797 }
3798 });
3799}
3800
3805static void UpdateTownRating(Town *t)
3806{
3807 /* Increase company ratings if they're low */
3808 for (const Company *c : Company::Iterate()) {
3809 if (t->ratings[c->index] < RATING_GROWTH_MAXIMUM) {
3810 t->ratings[c->index] = std::min((int)RATING_GROWTH_MAXIMUM, t->ratings[c->index] + RATING_GROWTH_UP_STEP);
3811 }
3812 }
3813
3814 ForAllStationsNearTown(t, [&](const Station *st) {
3815 if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
3816 if (Company::IsValidID(st->owner)) {
3817 int new_rating = t->ratings[st->owner] + RATING_STATION_UP_STEP;
3818 t->ratings[st->owner] = std::min<int>(new_rating, INT16_MAX); // do not let it overflow
3819 }
3820 } else {
3821 if (Company::IsValidID(st->owner)) {
3822 int new_rating = t->ratings[st->owner] + RATING_STATION_DOWN_STEP;
3823 t->ratings[st->owner] = std::max(new_rating, INT16_MIN);
3824 }
3825 }
3826 });
3827
3828 /* clamp all ratings to valid values */
3829 for (uint i = 0; i < MAX_COMPANIES; i++) {
3830 t->ratings[i] = Clamp(t->ratings[i], RATING_MINIMUM, RATING_MAXIMUM);
3831 }
3832
3834}
3835
3836
3843static void UpdateTownGrowCounter(Town *t, uint16_t prev_growth_rate)
3844{
3845 if (t->growth_rate == TOWN_GROWTH_RATE_NONE) return;
3846 if (prev_growth_rate == TOWN_GROWTH_RATE_NONE) {
3847 t->grow_counter = std::min<uint16_t>(t->growth_rate, t->grow_counter);
3848 return;
3849 }
3850 t->grow_counter = RoundDivSU((uint32_t)t->grow_counter * (t->growth_rate + 1), prev_growth_rate + 1);
3851}
3852
3859{
3860 int n = 0;
3861 ForAllStationsNearTown(t, [&](const Station * st) {
3862 if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
3863 n++;
3864 }
3865 });
3866 return n;
3867}
3868
3876{
3882 static const uint16_t _grow_count_values[2][6] = {
3883 { 120, 120, 120, 100, 80, 60 }, // Fund new buildings has been activated
3884 { 320, 420, 300, 220, 160, 100 } // Normal values
3885 };
3886
3887 int n = CountActiveStations(t);
3888 uint16_t m = _grow_count_values[t->fund_buildings_months != 0 ? 0 : 1][std::min(n, 5)];
3889
3890 uint growth_multiplier = _settings_game.economy.town_growth_rate != 0 ? _settings_game.economy.town_growth_rate - 1 : 1;
3891
3892 m >>= growth_multiplier;
3893 if (t->larger_town) m /= 2;
3894
3895 return TownTicksToGameTicks(m / (t->cache.num_houses / 50 + 1));
3896}
3897
3903{
3904 if (t->flags.Test(TownFlag::CustomGrowth)) return;
3905 uint old_rate = t->growth_rate;
3907 UpdateTownGrowCounter(t, old_rate);
3908 SetWindowDirty(WC_TOWN_VIEW, t->index);
3909}
3910
3915static void UpdateTownGrowth(Town *t)
3916{
3918
3920 SetWindowDirty(WC_TOWN_VIEW, t->index);
3921
3922 if (_settings_game.economy.town_growth_rate == 0 && t->fund_buildings_months == 0) return;
3923
3924 if (t->fund_buildings_months == 0) {
3925 /* Check if all goals are reached for this town to grow (given we are not funding it) */
3926 for (int i = TAE_BEGIN; i < TAE_END; i++) {
3927 switch (t->goal[i]) {
3928 case TOWN_GROWTH_WINTER:
3929 if (TileHeight(t->xy) >= GetSnowLine() && t->received[i].old_act == 0 && t->cache.population > 90) return;
3930 break;
3931 case TOWN_GROWTH_DESERT:
3932 if (GetTropicZone(t->xy) == TROPICZONE_DESERT && t->received[i].old_act == 0 && t->cache.population > 60) return;
3933 break;
3934 default:
3935 if (t->goal[i] > t->received[i].old_act) return;
3936 break;
3937 }
3938 }
3939 }
3940
3943 SetWindowDirty(WC_TOWN_VIEW, t->index);
3944 return;
3945 }
3946
3947 if (t->fund_buildings_months == 0 && CountActiveStations(t) == 0 && !Chance16(1, 12)) return;
3948
3950 SetWindowDirty(WC_TOWN_VIEW, t->index);
3951}
3952
3960{
3961 /* The required rating is hardcoded to RATING_VERYPOOR (see below), not the authority attitude setting, so we can bail out like this. */
3962 if (_settings_game.difficulty.town_council_tolerance == TOWN_COUNCIL_PERMISSIVE) return CommandCost();
3963
3965
3966 Town *t = ClosestTownFromTile(tile, _settings_game.economy.dist_local_authority);
3967 if (t == nullptr) return CommandCost();
3968
3969 if (t->ratings[_current_company] > RATING_VERYPOOR) return CommandCost();
3970
3971 return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index);
3972}
3973
3983{
3984 if (Town::GetNumItems() == 0) return nullptr;
3985
3986 TownID tid = _town_kdtree.FindNearest(TileX(tile), TileY(tile));
3987 Town *town = Town::Get(tid);
3988 if (DistanceManhattan(tile, town->xy) < threshold) return town;
3989 return nullptr;
3990}
3991
4000Town *ClosestTownFromTile(TileIndex tile, uint threshold)
4001{
4002 switch (GetTileType(tile)) {
4003 case TileType::Road:
4004 if (IsRoadDepot(tile)) return CalcClosestTownFromTile(tile, threshold);
4005
4006 if (!HasTownOwnedRoad(tile)) {
4007 TownID tid = GetTownIndex(tile);
4008
4009 if (tid == TownID::Invalid()) {
4010 /* in the case we are generating "many random towns", this value may be TownID::Invalid() */
4011 if (_generating_world) return CalcClosestTownFromTile(tile, threshold);
4012 assert(Town::GetNumItems() == 0);
4013 return nullptr;
4014 }
4015
4016 assert(Town::IsValidID(tid));
4017 Town *town = Town::Get(tid);
4018
4019 if (DistanceManhattan(tile, town->xy) >= threshold) town = nullptr;
4020
4021 return town;
4022 }
4023 [[fallthrough]];
4024
4025 case TileType::House:
4026 return Town::GetByTile(tile);
4027
4028 default:
4029 return CalcClosestTownFromTile(tile, threshold);
4030 }
4031}
4032
4033static bool _town_rating_test = false;
4034static std::map<const Town *, int> _town_test_ratings;
4035
4042{
4043 static int ref_count = 0; // Number of times test-mode is switched on.
4044 if (mode) {
4045 if (ref_count == 0) {
4046 _town_test_ratings.clear();
4047 }
4048 ref_count++;
4049 } else {
4050 assert(ref_count > 0);
4051 ref_count--;
4052 }
4053 _town_rating_test = !(ref_count == 0);
4054}
4055
4061static int GetRating(const Town *t)
4062{
4063 if (_town_rating_test) {
4064 auto it = _town_test_ratings.find(t);
4065 if (it != _town_test_ratings.end()) {
4066 return it->second;
4067 }
4068 }
4069 return t->ratings[_current_company];
4070}
4071
4079void ChangeTownRating(Town *t, int add, int max, DoCommandFlags flags)
4080{
4081 /* if magic_bulldozer cheat is active, town doesn't penalize for removing stuff */
4082 if (t == nullptr || flags.Test(DoCommandFlag::NoModifyTownRating) ||
4084 (_cheats.magic_bulldozer.value && add < 0)) {
4085 return;
4086 }
4087
4088 int rating = GetRating(t);
4089 if (add < 0) {
4090 if (rating > max) {
4091 rating += add;
4092 if (rating < max) rating = max;
4093 }
4094 } else {
4095 if (rating < max) {
4096 rating += add;
4097 if (rating > max) rating = max;
4098 }
4099 }
4100 if (_town_rating_test) {
4101 _town_test_ratings[t] = rating;
4102 } else {
4104 t->ratings[_current_company] = rating;
4106 }
4107}
4108
4117{
4118 /* if magic_bulldozer cheat is active, town doesn't restrict your destructive actions */
4119 if (t == nullptr || !Company::IsValidID(_current_company) ||
4120 _cheats.magic_bulldozer.value || flags.Test(DoCommandFlag::NoTestTownRating)) {
4121 return CommandCost();
4122 }
4123
4124 /* minimum rating needed to be allowed to remove stuff */
4125 static const int needed_rating[][to_underlying(TownRatingCheckType::End)] = {
4126 /* RoadRemove, TunnelBridgeRemove */
4131 };
4132
4133 /* check if you're allowed to remove the road/bridge/tunnel
4134 * owned by a town no removal if rating is lower than ... depends now on
4135 * difficulty setting. Minimum town rating selected by difficulty level
4136 */
4137 int needed = needed_rating[_settings_game.difficulty.town_council_tolerance][to_underlying(type)];
4138
4139 if (GetRating(t) < needed) {
4140 return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index);
4141 }
4142
4143 return CommandCost();
4144}
4145
4146template <>
4147Town::SuppliedHistory SumHistory(std::span<const Town::SuppliedHistory> history)
4148{
4149 uint64_t production = std::accumulate(std::begin(history), std::end(history), 0, [](uint64_t r, const auto &s) { return r + s.production; });
4150 uint64_t transported = std::accumulate(std::begin(history), std::end(history), 0, [](uint64_t r, const auto &s) { return r + s.transported; });
4151 auto count = std::size(history);
4152 return {.production = ClampTo<uint32_t>(production / count), .transported = ClampTo<uint32_t>(transported / count)};
4153}
4154
4155static const IntervalTimer<TimerGameEconomy> _economy_towns_monthly({TimerGameEconomy::Trigger::Month, TimerGameEconomy::Priority::Town}, [](auto)
4156{
4157 for (Town *t : Town::Iterate()) {
4158 /* Check for active town actions and decrement their counters. */
4159 if (t->road_build_months != 0) t->road_build_months--;
4160 if (t->fund_buildings_months != 0) t->fund_buildings_months--;
4161
4162 if (t->exclusive_counter != 0) {
4163 if (--t->exclusive_counter == 0) t->exclusivity = CompanyID::Invalid();
4164 }
4165
4166 /* Check for active failed bribe cooloff periods and decrement them. */
4167 for (const Company *c : Company::Iterate()) {
4168 if (t->unwanted[c->index] > 0) t->unwanted[c->index]--;
4169 }
4170
4171 UpdateValidHistory(t->valid_history, HISTORY_YEAR, TimerGameEconomy::month);
4172
4173 /* Update cargo statistics. */
4174 for (auto &s : t->supplied) RotateHistory(s.history, t->valid_history, HISTORY_YEAR, TimerGameEconomy::month);
4175 for (auto &received : t->received) received.NewMonth();
4176
4179
4180 SetWindowDirty(WC_TOWN_VIEW, t->index);
4181 }
4182});
4183
4184static const IntervalTimer<TimerGameEconomy> _economy_towns_yearly({TimerGameEconomy::Trigger::Year, TimerGameEconomy::Priority::Town}, [](auto)
4185{
4186 /* Increment house ages */
4187 for (const auto t : Map::Iterate()) {
4188 if (!IsTileType(t, TileType::House)) continue;
4190 }
4191});
4192
4194static CommandCost TerraformTile_Town(TileIndex tile, DoCommandFlags flags, int z_new, Slope tileh_new)
4195{
4196 if (AutoslopeEnabled()) {
4197 HouseID house = GetHouseType(tile);
4198 GetHouseNorthPart(house); // modifies house to the ID of the north tile
4199 const HouseSpec *hs = HouseSpec::Get(house);
4200
4201 /* Here we differ from TTDP by checking BuildingFlag::NotSloped */
4202 if (!hs->building_flags.Test(BuildingFlag::NotSloped) && !IsSteepSlope(tileh_new) &&
4203 (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) {
4204 bool allow_terraform = true;
4205
4206 /* Call the autosloping callback per tile, not for the whole building at once. */
4207 house = GetHouseType(tile);
4208 hs = HouseSpec::Get(house);
4210 /* If the callback fails, allow autoslope. */
4211 uint16_t res = GetHouseCallback(CBID_HOUSE_AUTOSLOPE, 0, 0, house, Town::GetByTile(tile), tile);
4212 if (res != CALLBACK_FAILED && ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_AUTOSLOPE, res)) allow_terraform = false;
4213 }
4214
4215 if (allow_terraform) return CommandCost(EXPENSES_CONSTRUCTION, _price[Price::BuildFoundation]);
4216 }
4217 }
4218
4219 return Command<Commands::LandscapeClear>::Do(flags, tile);
4220}
4221
4223extern const TileTypeProcs _tile_type_town_procs = {
4224 .draw_tile_proc = DrawTile_Town,
4225 .get_slope_pixel_z_proc = [](TileIndex tile, uint, uint, bool) { return GetTileMaxPixelZ(tile); },
4226 .clear_tile_proc = ClearTile_Town,
4227 .add_accepted_cargo_proc = AddAcceptedCargo_Town,
4228 .get_tile_desc_proc = GetTileDesc_Town,
4229 .animate_tile_proc = AnimateTile_Town,
4230 .tile_loop_proc = TileLoop_Town,
4231 .add_produced_cargo_proc = AddProducedCargo_Town,
4232 .get_foundation_proc = GetFoundation_Town,
4233 .terraform_tile_proc = TerraformTile_Town,
4234};
4235
4236std::span<const DrawBuildingsTileStruct> GetTownDrawTileData()
4237{
4238 return _town_draw_tile_data;
4239}
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!
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 T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
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
uint8_t CargoType
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:21
bool IsValidCargoType(CargoType cargo)
Test whether cargo type is not INVALID_CARGO.
Definition cargo_type.h:108
TownProductionEffect
Town effect when producing cargo.
Definition cargotype.h:35
@ TPE_PASSENGERS
Cargo behaves passenger-like for production.
Definition cargotype.h:37
@ TPE_MAIL
Cargo behaves mail-like for production.
Definition cargotype.h:38
TownAcceptanceEffect
Town growth effect when delivering cargo.
Definition cargotype.h:22
@ TAE_END
End of town effects.
Definition cargotype.h:30
@ TAE_FOOD
Cargo behaves food/fizzy-drinks-like.
Definition cargotype.h:29
@ TAE_WATER
Cargo behaves water-like.
Definition cargotype.h:28
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:255
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is 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.
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.
@ EXPENSES_CONSTRUCTION
Construction costs.
@ EXPENSES_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.
@ GSF_FAKE_TOWNS
Fake town GrfSpecFeature for NewGRF debugging (parent scope).
Definition newgrf.h:97
@ 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.
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.
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:914
@ 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
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 RTT_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
RoadBits
Enumeration for the road parts on a tile.
Definition road_type.h:56
@ ROAD_SW
South-west part.
Definition road_type.h:59
@ ROAD_ALL
Full 4-way crossing.
Definition road_type.h:70
@ ROAD_NONE
No road-part is build.
Definition road_type.h:57
@ ROAD_E
Road at the two eastern edges.
Definition road_type.h:66
@ ROAD_NE
North-east part.
Definition road_type.h:61
@ ROAD_N
Road at the two northern edges.
Definition road_type.h:65
@ ROAD_SE
South-east part.
Definition road_type.h:60
@ ROAD_Y
Full road along the y-axis (north-west + south-east).
Definition road_type.h:63
@ ROAD_S
Road at the two southern edges.
Definition road_type.h:67
@ ROAD_W
Road at the two western edges.
Definition road_type.h:68
@ ROAD_NW
North-west part.
Definition road_type.h:58
@ ROAD_X
Full road along the x-axis (south-west + north-east).
Definition road_type.h:62
@ RTT_ROAD
Road road type.
Definition road_type.h:38
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
@ DRD_NONE
None of the directions are disallowed.
Definition road_type.h:78
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:115
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:74
static IterateWrapper Iterate(size_t from=0)
Returns an iterable ensemble of all valid CargoSpec.
Definition cargotype.h:191
static std::array< std::vector< const CargoSpec * >, NUM_TPE > town_production_cargoes
List of cargo specs for each Town Product Effect.
Definition cargotype.h:25
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:23
ObjectType type
Type of the object.
Definition object_base.h:24
Town * town
Town the object is built in.
Definition object_base.h:25
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:38
std::optional< std::string > grf
newGRF used for the tile contents
Definition tile_cmd.h:49
StringID str
Description of the tile.
Definition tile_cmd.h:39
std::array< Owner, 4 > owner
Name of the owner(s).
Definition tile_cmd.h:41
uint64_t dparam
Parameter of the str string.
Definition tile_cmd.h:40
std::optional< bool > town_can_upgrade
Whether the town can upgrade this house during town growth.
Definition tile_cmd.h:56
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:32
Slope tileh
Slope of the tile.
Definition tile_cmd.h:33
TileIndex tile
Tile index.
Definition tile_cmd.h:34
Set of callback functions for performing tile operations of a given tile type.
Definition tile_cmd.h:212
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)
Town data structure.
Definition town.h:63
EncodedString text
General text with additional information.
Definition town.h:116
bool larger_town
if this is a larger town and should grow more quickly
Definition town.h:152
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:144
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:149
TownLayout layout
town specific road layout
Definition town.h:153
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:164
uint16_t grow_counter
counter to count when to grow, value is smaller than or equal to growth_rate
Definition town.h:146
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:155
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
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:147
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:142
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:150
uint16_t townnametype
Custom town name. If empty, the town was not renamed and uses the generated name.
Definition town.h:71
std::array< TransportedCargoStat< uint16_t >, NUM_TAE > received
Cargo statistics about received cargotypes.
Definition town.h:112
std::array< uint32_t, NUM_TAE > goal
Amount of cargo required for the town to grow.
Definition town.h:113
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
@ TROPICZONE_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:227
@ End
End marker.
Definition town.h:230
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:250
@ RoadRebuild
Rebuild the roads.
Definition town.h:254
@ Bribe
Try to bribe the council.
Definition town.h:258
@ End
End marker.
Definition town.h:259
@ BuildStatue
Build a statue.
Definition town.h:255
@ BuyRights
Buy exclusive transport rights.
Definition town.h:257
@ FundBuildings
Fund new buildings.
Definition town.h:256
@ 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:828
static CommandCost TownActionAdvertiseSmall(Town *t, DoCommandFlags flags)
Perform the "small advertising campaign" town action.
static CommandCost TerraformTile_Town(TileIndex tile, DoCommandFlags flags, int z_new, Slope tileh_new)
Tile callback function signature of the terraforming callback.
static CommandCost TownActionFundBuildings(Town *t, DoCommandFlags flags)
Perform the "fund new buildings" town action.
static bool IsTileAlignedToGrid(TileIndex tile, TownLayout layout)
Towns must all be placed on the same grid or when they eventually interpenetrate their road networks ...
static CommandCost TownActionBuildStatue(Town *t, DoCommandFlags flags)
Perform a 9x9 tiles circular search from the center of the town in order to find a free tile to place...
static CommandCost TownActionBribe(Town *t, DoCommandFlags flags)
Perform the "bribe" town action.
TileIndexDiff GetHouseNorthPart(HouseID &house)
Determines if a given HouseID is part of a multitile house.
static int GetRating(const Town *t)
Get the rating of a town for the _current_company.
uint GetDefaultTownsForMapSize()
Calculate the number of towns which should be on the map according to the current "town density" newg...
void ClearTownHouse(Town *t, TileIndex tile)
Clear a town house.
static uint GetNormalGrowthRate(Town *t)
Calculates town growth rate in normal conditions (custom growth rate not set).
TownActions GetMaskOfTownActions(CompanyID cid, const Town *t)
Get a list of available town authority actions.
static CommandCost TownActionBuyRights(Town *t, DoCommandFlags flags)
Perform the "buy exclusive transport rights" town action.
static bool GrowTownWithBridge(const Town *t, const TileIndex tile, const DiagDirection bridge_dir)
Grows the town with a bridge.
const CargoSpec * FindFirstCargoWithTownAcceptanceEffect(TownAcceptanceEffect effect)
Determines the first cargo with a certain town effect.
static TileIndex FindNearestGoodCoastalTownSpot(TileIndex tile, TownLayout layout)
Given a spot on the map (presumed to be a water tile), find a good coastal spot to build a city.
Town * ClosestTownFromTile(TileIndex tile, uint threshold)
Return the town closest (in distance or ownership) to a given tile, within a given threshold.
static bool IsRoadAllowedHere(Town *t, TileIndex tile, DiagDirection dir)
Check if a Road is allowed on a given tile.
TownGrowthResult
The possible states of town growth.
@ Continue
The town hasn't grown yet, but try again.
@ Succeed
The town has grown.
@ SearchStopped
There is a reason not to try growing the town now.
static bool CanRoadContinueIntoNextTile(const Town *t, const TileIndex tile, const DiagDirection road_dir)
Checks if a town road can be continued into the next tile.
static bool TryBuildTownHouse(Town *t, TileIndex tile, TownExpandModes modes)
Tries to build a house at this tile.
static void UpdateTownGrowCounter(Town *t, uint16_t prev_growth_rate)
Updates town grow counter after growth rate change.
static int CountActiveStations(Town *t)
Calculates amount of active stations in the range of town (HZB_TOWN_EDGE).
static bool IsNeighbourRoadTile(TileIndex tile, const DiagDirection dir, uint dist_multi)
Check for parallel road inside a given distance.
static bool _generating_town
Set if a town is being generated.
Definition town_cmd.cpp: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:731
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:696
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
CargoArray GetAcceptedCargoOfHouse(const HouseSpec *hs)
Get accepted cargo of a house prototype.
Definition town_cmd.cpp:839
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:769
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:967
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:937
static RoadBits GetTownRoadBits(TileIndex tile)
Return the RoadBits of a tile, ignoring depot and bay road stops.
Definition town_cmd.cpp:925
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:848
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:911
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:987
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:892
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:785
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:3229
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:3321
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting).
Definition window.cpp:3199
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: