OpenTTD Source 20250818-master-g1850ad1aa2
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 <http://www.gnu.org/licenses/>.
6 */
7
10#include "stdafx.h"
11#include "misc/history_type.hpp"
12#include "misc/history_func.hpp"
13#include "road.h"
14#include "road_internal.h" /* Cleaning up road bits */
15#include "road_cmd.h"
16#include "landscape.h"
17#include "viewport_func.h"
18#include "viewport_kdtree.h"
19#include "command_func.h"
20#include "company_func.h"
21#include "industry.h"
22#include "station_base.h"
23#include "waypoint_base.h"
24#include "station_kdtree.h"
25#include "company_base.h"
26#include "news_func.h"
27#include "error.h"
28#include "object.h"
29#include "genworld.h"
30#include "newgrf_debug.h"
31#include "newgrf_house.h"
32#include "newgrf_text.h"
33#include "autoslope.h"
34#include "tunnelbridge_map.h"
35#include "strings_func.h"
36#include "window_func.h"
37#include "string_func.h"
38#include "newgrf_cargo.h"
39#include "cheat_type.h"
40#include "animated_tile_func.h"
41#include "subsidy_func.h"
42#include "core/pool_func.hpp"
43#include "town.h"
44#include "town_kdtree.h"
45#include "townname_func.h"
46#include "core/random_func.hpp"
47#include "core/backup_type.hpp"
48#include "depot_base.h"
49#include "object_map.h"
50#include "object_base.h"
51#include "ai/ai.hpp"
52#include "game/game.hpp"
53#include "town_cmd.h"
54#include "landscape_cmd.h"
55#include "road_cmd.h"
56#include "terraform_cmd.h"
57#include "tunnelbridge_cmd.h"
58#include "timer/timer.h"
62
63#include "table/strings.h"
64#include "table/town_land.h"
65
66#include "safeguards.h"
67
68/* Initialize the town-pool */
69TownPool _town_pool("Town");
71
72
73TownKdtree _town_kdtree{};
74
75void RebuildTownKdtree()
76{
77 std::vector<TownID> townids;
78 for (const Town *town : Town::Iterate()) {
79 townids.push_back(town->index);
80 }
81 _town_kdtree.Build(townids.begin(), townids.end());
82}
83
85static bool _generating_town = false;
86
96static bool TestTownOwnsBridge(TileIndex tile, const Town *t)
97{
98 if (!IsTileOwner(tile, OWNER_TOWN)) return false;
99
101 bool town_owned = IsTileType(adjacent, MP_ROAD) && IsTileOwner(adjacent, OWNER_TOWN) && GetTownIndex(adjacent) == t->index;
102
103 if (!town_owned) {
104 /* Or other adjacent road */
106 town_owned = IsTileType(adjacent, MP_ROAD) && IsTileOwner(adjacent, OWNER_TOWN) && GetTownIndex(adjacent) == t->index;
107 }
108
109 return town_owned;
110}
111
113{
114 if (CleaningPool()) return;
115
116 /* Delete town authority window
117 * and remove from list of sorted towns */
120
121#ifdef WITH_ASSERT
122 /* Check no industry is related to us. */
123 for (const Industry *i : Industry::Iterate()) {
124 assert(i->town != this);
125 }
126
127 /* ... and no object is related to us. */
128 for (const Object *o : Object::Iterate()) {
129 assert(o->town != this);
130 }
131
132 /* Check no tile is related to us. */
133 for (const auto tile : Map::Iterate()) {
134 switch (GetTileType(tile)) {
135 case MP_HOUSE:
136 assert(GetTownIndex(tile) != this->index);
137 break;
138
139 case MP_ROAD:
140 assert(!HasTownOwnedRoad(tile) || GetTownIndex(tile) != this->index);
141 break;
142
143 case MP_TUNNELBRIDGE:
144 assert(!TestTownOwnsBridge(tile, this));
145 break;
146
147 default:
148 break;
149 }
150 }
151#endif /* WITH_ASSERT */
152
153 /* Clear the persistent storage list. */
154 for (auto &psa : this->psa_list) {
155 delete psa;
156 }
157 this->psa_list.clear();
158
159 Source src{this->index, SourceType::Town};
164}
165
166
172{
173 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_REBUILD);
175
176 /* Give objects a new home! */
177 for (Object *o : Object::Iterate()) {
178 if (o->town == nullptr) o->town = CalcClosestTownFromTile(o->location.tile, UINT_MAX);
179 }
180}
181
187{
188 if (layout != TL_RANDOM) {
189 this->layout = layout;
190 return;
191 }
192
193 this->layout = static_cast<TownLayout>(TileHash(TileX(this->xy), TileY(this->xy)) % (NUM_TLS - 1));
194}
195
200/* static */ Town *Town::GetRandom()
201{
202 if (Town::GetNumItems() == 0) return nullptr;
203 int num = RandomRange((uint16_t)Town::GetNumItems());
204 size_t index = std::numeric_limits<size_t>::max();
205
206 while (num >= 0) {
207 num--;
208 index++;
209
210 /* Make sure we have a valid town */
211 while (!Town::IsValidID(index)) {
212 index++;
213 assert(index < Town::GetPoolSize());
214 }
215 }
216
217 return Town::Get(index);
218}
219
220void Town::FillCachedName() const
221{
222 this->cached_name = GetTownName(this);
223}
224
230{
231 return (_price[PR_CLEAR_HOUSE] * this->removal_cost) >> 8;
232}
233
234static bool TryBuildTownHouse(Town *t, TileIndex tile, TownExpandModes modes);
235static Town *CreateRandomTown(uint attempts, uint32_t townnameparts, TownSize size, bool city, TownLayout layout);
236
237static void TownDrawHouseLift(const TileInfo *ti)
238{
239 AddChildSpriteScreen(SPR_LIFT, PAL_NONE, 14, 60 - GetLiftPosition(ti->tile));
240}
241
242typedef void TownDrawTileProc(const TileInfo *ti);
243static TownDrawTileProc * const _town_draw_tile_procs[1] = {
244 TownDrawHouseLift
245};
246
253{
255}
256
261static void DrawTile_Town(TileInfo *ti)
262{
263 HouseID house_id = GetHouseType(ti->tile);
264
265 if (house_id >= NEW_HOUSE_OFFSET) {
266 /* Houses don't necessarily need new graphics. If they don't have a
267 * spritegroup associated with them, then the sprite for the substitute
268 * house id is drawn instead. */
269 if (HouseSpec::Get(house_id)->grf_prop.HasSpriteGroups()) {
270 DrawNewHouseTile(ti, house_id);
271 return;
272 } else {
273 house_id = HouseSpec::Get(house_id)->grf_prop.subst_id;
274 }
275 }
276
277 /* Retrieve pointer to the draw town tile struct */
278 const DrawBuildingsTileStruct *dcts = &_town_draw_tile_data[house_id << 4 | TileHash2Bit(ti->x, ti->y) << 2 | GetHouseBuildingStage(ti->tile)];
279
281
282 DrawGroundSprite(dcts->ground.sprite, dcts->ground.pal);
283
284 /* If houses are invisible, do not draw the upper part */
285 if (IsInvisibilitySet(TO_HOUSES)) return;
286
287 /* Add a house on top of the ground? */
288 SpriteID image = dcts->building.sprite;
289 if (image != 0) {
290 AddSortableSpriteToDraw(image, dcts->building.pal, *ti, *dcts, IsTransparencySet(TO_HOUSES));
291
292 if (IsTransparencySet(TO_HOUSES)) return;
293 }
294
295 {
296 int proc = dcts->draw_proc - 1;
297
298 if (proc >= 0) _town_draw_tile_procs[proc](ti);
299 }
300}
301
302static int GetSlopePixelZ_Town(TileIndex tile, uint, uint, bool)
303{
304 return GetTileMaxPixelZ(tile);
305}
306
313{
314 HouseID hid = GetHouseType(tile);
315
316 /* For NewGRF house tiles we might not be drawing a foundation. We need to
317 * account for this, as other structures should
318 * draw the wall of the foundation in this case.
319 */
320 if (hid >= NEW_HOUSE_OFFSET) {
321 const HouseSpec *hs = HouseSpec::Get(hid);
323 uint32_t callback_res = GetHouseCallback(CBID_HOUSE_DRAW_FOUNDATIONS, 0, 0, hid, Town::GetByTile(tile), tile);
324 if (callback_res != CALLBACK_FAILED && !ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DRAW_FOUNDATIONS, callback_res)) return FOUNDATION_NONE;
325 }
326 }
327 return FlatteningFoundation(tileh);
328}
329
337{
338 if (GetHouseType(tile) >= NEW_HOUSE_OFFSET) {
339 AnimateNewHouseTile(tile);
340 return;
341 }
342
343 if (TimerGameTick::counter & 3) return;
344
345 /* If the house is not one with a lift anymore, then stop this animating.
346 * Not exactly sure when this happens, but probably when a house changes.
347 * Before this was just a return...so it'd leak animated tiles..
348 * That bug seems to have been here since day 1?? */
349 if (!HouseSpec::Get(GetHouseType(tile))->building_flags.Test(BuildingFlag::IsAnimated)) {
350 DeleteAnimatedTile(tile);
351 return;
352 }
353
354 if (!LiftHasDestination(tile)) {
355 uint i;
356
357 /* Building has 6 floors, number 0 .. 6, where 1 is illegal.
358 * This is due to the fact that the first floor is, in the graphics,
359 * the height of 2 'normal' floors.
360 * Furthermore, there are 6 lift positions from floor N (incl) to floor N + 1 (excl) */
361 do {
362 i = RandomRange(7);
363 } while (i == 1 || i * 6 == GetLiftPosition(tile));
364
365 SetLiftDestination(tile, i);
366 }
367
368 int pos = GetLiftPosition(tile);
369 int dest = GetLiftDestination(tile) * 6;
370 pos += (pos < dest) ? 1 : -1;
371 SetLiftPosition(tile, pos);
372
373 if (pos == dest) {
374 HaltLift(tile);
375 DeleteAnimatedTile(tile);
376 }
377
379}
380
387static bool IsCloseToTown(TileIndex tile, uint dist)
388{
389 if (_town_kdtree.Count() == 0) return false;
390 Town *t = Town::Get(_town_kdtree.FindNearest(TileX(tile), TileY(tile)));
391 return DistanceManhattan(tile, t->xy) < dist;
392}
393
396{
397 Point pt = RemapCoords2(TileX(this->xy) * TILE_SIZE, TileY(this->xy) * TILE_SIZE);
398
399 if (this->cache.sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeTown(this->index));
400
401 std::string town_string;
402 if (this->larger_town) {
403 town_string = GetString(_settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_CITY_POP : STR_VIEWPORT_TOWN_CITY, this->index, this->cache.population);
404 } else {
405 town_string = GetString(_settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_POP : STR_TOWN_NAME, this->index, this->cache.population);
406 }
407
408 this->cache.sign.UpdatePosition(pt.x, pt.y - 24 * ZOOM_BASE,
409 town_string,
410 GetString(STR_TOWN_NAME, this->index, this->cache.population)
411);
412
413 _viewport_sign_kdtree.Insert(ViewportSignKdtreeItem::MakeTown(this->index));
414
416}
417
420{
421 for (Town *t : Town::Iterate()) {
422 t->UpdateVirtCoord();
423 }
424}
425
428{
429 for (Town *t : Town::Iterate()) {
430 t->cached_name.clear();
431 }
432}
433
439static void ChangePopulation(Town *t, int mod)
440{
441 t->cache.population += mod;
442 if (_generating_town) [[unlikely]] return;
443
444 InvalidateWindowData(WC_TOWN_VIEW, t->index); // Cargo requirements may appear/vanish for small populations
446
447 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_POPULATION_CHANGE);
448}
449
455{
456 uint32_t pop = 0;
457 for (const Town *t : Town::Iterate()) pop += t->cache.population;
458 return pop;
459}
460
469{
470 for (StationList::iterator it = t->stations_near.begin(); it != t->stations_near.end(); /* incremented inside loop */) {
471 const Station *st = *it;
472
473 bool covers_area = st->TileIsInCatchment(tile);
474 if (flags.Any(BUILDING_2_TILES_Y)) covers_area |= st->TileIsInCatchment(tile + TileDiffXY(0, 1));
475 if (flags.Any(BUILDING_2_TILES_X)) covers_area |= st->TileIsInCatchment(tile + TileDiffXY(1, 0));
476 if (flags.Any(BUILDING_HAS_4_TILES)) covers_area |= st->TileIsInCatchment(tile + TileDiffXY(1, 1));
477
478 if (covers_area && !st->CatchmentCoversTown(t->index)) {
479 it = t->stations_near.erase(it);
480 } else {
481 ++it;
482 }
483 }
484}
485
491{
492 assert(IsTileType(tile, MP_HOUSE));
493
494 /* Progress in construction stages */
496 if (GetHouseConstructionTick(tile) != 0) return;
497
498 TriggerHouseAnimation_ConstructionStageChanged(tile, false);
499
500 if (IsHouseCompleted(tile)) {
501 /* Now that construction is complete, we can add the population of the
502 * building to the town. */
503 ChangePopulation(Town::GetByTile(tile), HouseSpec::Get(GetHouseType(tile))->population);
504 ResetHouseAge(tile);
505 }
507}
508
514{
516 if (flags.Any(BUILDING_HAS_1_TILE)) AdvanceSingleHouseConstruction(TileAddXY(tile, 0, 0));
517 if (flags.Any(BUILDING_2_TILES_Y)) AdvanceSingleHouseConstruction(TileAddXY(tile, 0, 1));
518 if (flags.Any(BUILDING_2_TILES_X)) AdvanceSingleHouseConstruction(TileAddXY(tile, 1, 0));
519 if (flags.Any(BUILDING_HAS_4_TILES)) AdvanceSingleHouseConstruction(TileAddXY(tile, 1, 1));
520}
521
530static void TownGenerateCargo(Town *t, CargoType cargo, uint amount, StationFinder &stations, bool affected_by_recession)
531{
532 if (amount == 0) return;
533
534 /* All production is halved during a recession (except for NewGRF-supplied town cargo). */
535 if (affected_by_recession && EconomyIsInRecession()) {
536 amount = (amount + 1) >> 1;
537 }
538
539 /* Scale by cargo scale setting. */
540 amount = ScaleByCargoScale(amount, true);
541 if (amount == 0) return;
542
543 /* Actually generate cargo and update town statistics. */
544 auto &supplied = t->GetOrCreateCargoSupplied(cargo);
545 supplied.history[THIS_MONTH].production += amount;
546 supplied.history[THIS_MONTH].transported += MoveGoodsToStation(cargo, amount, {t->index, SourceType::Town}, stations.GetStations());;
547}
548
556static void TownGenerateCargoOriginal(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
557{
558 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[tpe]) {
559 uint32_t r = Random();
560 if (GB(r, 0, 8) < rate) {
561 CargoType cargo_type = cs->Index();
562 uint amt = (GB(r, 0, 8) * cs->town_production_multiplier / TOWN_PRODUCTION_DIVISOR) / 8 + 1;
563
564 TownGenerateCargo(t, cargo_type, amt, stations, true);
565 }
566 }
567}
568
576static void TownGenerateCargoBinomial(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
577{
578 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[tpe]) {
579 CargoType cargo_type = cs->Index();
580 uint32_t r = Random();
581
582 /* Make a bitmask with up to 32 bits set, one for each potential pax. */
583 int genmax = (rate + 7) / 8;
584 uint32_t genmask = (genmax >= 32) ? 0xFFFFFFFF : ((1 << genmax) - 1);
585
586 /* Mask random value by potential pax and count number of actual pax. */
587 uint amt = CountBits(r & genmask) * cs->town_production_multiplier / TOWN_PRODUCTION_DIVISOR;
588
589 TownGenerateCargo(t, cargo_type, amt, stations, true);
590 }
591}
592
599static void TileLoop_Town(TileIndex tile)
600{
601 HouseID house_id = GetHouseType(tile);
602
603 /* NewHouseTileLoop returns false if Callback 21 succeeded, i.e. the house
604 * doesn't exist any more, so don't continue here. */
605 if (house_id >= NEW_HOUSE_OFFSET && !NewHouseTileLoop(tile)) return;
606
607 if (!IsHouseCompleted(tile)) {
608 /* Construction is not completed, so we advance a construction stage. */
610 return;
611 }
612
613 const HouseSpec *hs = HouseSpec::Get(house_id);
614
615 /* If the lift has a destination, it is already an animated tile. */
616 if (hs->building_flags.Test(BuildingFlag::IsAnimated) &&
617 house_id < NEW_HOUSE_OFFSET &&
618 !LiftHasDestination(tile) &&
619 Chance16(1, 2)) {
620 AddAnimatedTile(tile);
621 }
622
623 Town *t = Town::GetByTile(tile);
624 uint32_t r = Random();
625
626 StationFinder stations(TileArea(tile, 1, 1));
627
629 for (uint i = 0; i < 256; i++) {
630 uint16_t callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, r, house_id, t, tile);
631
632 if (callback == CALLBACK_FAILED || callback == CALLBACK_HOUSEPRODCARGO_END) break;
633
634 CargoType cargo = GetCargoTranslation(GB(callback, 8, 7), hs->grf_prop.grffile);
635 if (!IsValidCargoType(cargo)) continue;
636
637 uint amt = GB(callback, 0, 8);
638 if (amt == 0) continue;
639
640 /* NewGRF-supplied town cargos are not affected by recessions. */
641 TownGenerateCargo(t, cargo, amt, stations, false);
642 }
643 } else {
645 case TCGM_ORIGINAL:
646 /* Original (quadratic) cargo generation algorithm */
649 break;
650
651 case TCGM_BITCOUNT:
652 /* Binomial distribution per tick, by a series of coin flips */
653 /* Reduce generation rate to a 1/4, using tile bits to spread out distribution.
654 * As tick counter is incremented by 256 between each call, we ignore the lower 8 bits. */
655 if (GB(TimerGameTick::counter, 8, 2) == GB(tile.base(), 0, 2)) {
658 }
659 break;
660
661 default:
662 NOT_REACHED();
663 }
664 }
665
667
668 if (hs->building_flags.Any(BUILDING_HAS_1_TILE) &&
670 CanDeleteHouse(tile) &&
671 GetHouseAge(tile) >= hs->minimum_life &&
672 --t->time_until_rebuild == 0) {
673 t->time_until_rebuild = GB(r, 16, 8) + 192;
674
675 ClearTownHouse(t, tile);
676
677 /* Rebuild with another house? */
678 if (GB(r, 24, 8) >= 12) {
679 /* If we are multi-tile houses, make sure to replace the house
680 * closest to city center. If we do not do this, houses tend to
681 * wander away from roads and other houses. */
682 if (hs->building_flags.Any(BUILDING_HAS_2_TILES)) {
683 /* House tiles are always the most north tile. Move the new
684 * house to the south if we are north of the city center. */
685 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
686 int x = Clamp(grid_pos.x, 0, 1);
687 int y = Clamp(grid_pos.y, 0, 1);
688
689 if (hs->building_flags.Test(BuildingFlag::Size2x2)) {
690 tile = TileAddXY(tile, x, y);
691 } else if (hs->building_flags.Test(BuildingFlag::Size1x2)) {
692 tile = TileAddXY(tile, 0, y);
693 } else if (hs->building_flags.Test(BuildingFlag::Size2x1)) {
694 tile = TileAddXY(tile, x, 0);
695 }
696 }
697
700
701 TryBuildTownHouse(t, tile, modes);
702 }
703 }
704
705 cur_company.Restore();
706}
707
715{
716 if (flags.Test(DoCommandFlag::Auto)) return CommandCost(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
717 if (!CanDeleteHouse(tile)) return CommandCost(STR_ERROR_BUILDING_IS_PROTECTED);
718
719 const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
720
722 cost.AddCost(hs->GetRemovalCost());
723
724 int rating = hs->remove_rating_decrease;
725 Town *t = Town::GetByTile(tile);
726
729 /* NewGRFs can add indestructible houses. */
730 if (rating > RATING_MAXIMUM) {
731 return CommandCost(STR_ERROR_BUILDING_IS_PROTECTED);
732 }
733 /* If town authority controls removal, check the company's rating. */
734 if (rating > t->ratings[_current_company] && _settings_game.difficulty.town_council_tolerance != TOWN_COUNCIL_PERMISSIVE) {
735 return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index);
736 }
737 }
738 }
739
740 ChangeTownRating(t, -rating, RATING_HOUSE_MINIMUM, flags);
741 if (flags.Test(DoCommandFlag::Execute)) {
742 ClearTownHouse(t, tile);
743 }
744
745 return cost;
746}
747
748static void AddProducedCargo_Town(TileIndex tile, CargoArray &produced)
749{
750 HouseID house_id = GetHouseType(tile);
751 const HouseSpec *hs = HouseSpec::Get(house_id);
752 Town *t = Town::GetByTile(tile);
753
755 for (uint i = 0; i < 256; i++) {
756 uint16_t callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, 0, house_id, t, tile);
757
758 if (callback == CALLBACK_FAILED || callback == CALLBACK_HOUSEPRODCARGO_END) break;
759
760 CargoType cargo = GetCargoTranslation(GB(callback, 8, 7), hs->grf_prop.grffile);
761
762 if (!IsValidCargoType(cargo)) continue;
763 produced[cargo]++;
764 }
765 } else {
766 if (hs->population > 0) {
767 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_PASSENGERS]) {
768 produced[cs->Index()]++;
769 }
770 }
771 if (hs->mail_generation > 0) {
772 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_MAIL]) {
773 produced[cs->Index()]++;
774 }
775 }
776 }
777}
778
786static void AddAcceptedCargoSetMask(CargoType cargo, uint amount, CargoArray &acceptance, CargoTypes &always_accepted)
787{
788 if (!IsValidCargoType(cargo) || amount == 0) return;
789 acceptance[cargo] += amount;
790 SetBit(always_accepted, cargo);
791}
792
802void AddAcceptedCargoOfHouse(TileIndex tile, HouseID house, const HouseSpec *hs, Town *t, CargoArray &acceptance, CargoTypes &always_accepted)
803{
804 CargoType accepts[lengthof(hs->accepts_cargo)];
805
806 /* Set the initial accepted cargo types */
807 for (uint8_t i = 0; i < lengthof(accepts); i++) {
808 accepts[i] = hs->accepts_cargo[i];
809 }
810
811 /* Check for custom accepted cargo types */
813 uint16_t callback = GetHouseCallback(CBID_HOUSE_ACCEPT_CARGO, 0, 0, house, t, tile, {}, tile == INVALID_TILE);
814 if (callback != CALLBACK_FAILED) {
815 /* Replace accepted cargo types with translated values from callback */
816 accepts[0] = GetCargoTranslation(GB(callback, 0, 5), hs->grf_prop.grffile);
817 accepts[1] = GetCargoTranslation(GB(callback, 5, 5), hs->grf_prop.grffile);
818 accepts[2] = GetCargoTranslation(GB(callback, 10, 5), hs->grf_prop.grffile);
819 }
820 }
821
822 /* Check for custom cargo acceptance */
824 uint16_t callback = GetHouseCallback(CBID_HOUSE_CARGO_ACCEPTANCE, 0, 0, house, t, tile, {}, tile == INVALID_TILE);
825 if (callback != CALLBACK_FAILED) {
826 AddAcceptedCargoSetMask(accepts[0], GB(callback, 0, 4), acceptance, always_accepted);
827 AddAcceptedCargoSetMask(accepts[1], GB(callback, 4, 4), acceptance, always_accepted);
828 if (_settings_game.game_creation.landscape != LandscapeType::Temperate && HasBit(callback, 12)) {
829 /* The 'S' bit indicates food instead of goods */
830 AddAcceptedCargoSetMask(GetCargoTypeByLabel(CT_FOOD), GB(callback, 8, 4), acceptance, always_accepted);
831 } else {
832 AddAcceptedCargoSetMask(accepts[2], GB(callback, 8, 4), acceptance, always_accepted);
833 }
834 return;
835 }
836 }
837
838 /* No custom acceptance, so fill in with the default values */
839 for (uint8_t i = 0; i < lengthof(accepts); i++) {
840 AddAcceptedCargoSetMask(accepts[i], hs->cargo_acceptance[i], acceptance, always_accepted);
841 }
842}
843
844static void AddAcceptedCargo_Town(TileIndex tile, CargoArray &acceptance, CargoTypes &always_accepted)
845{
846 HouseID house = GetHouseType(tile);
847 AddAcceptedCargoOfHouse(tile, house, HouseSpec::Get(house), Town::GetByTile(tile), acceptance, always_accepted);
848}
849
856{
857 CargoTypes always_accepted{};
858 CargoArray acceptance{};
859 AddAcceptedCargoOfHouse(INVALID_TILE, hs->Index(), hs, nullptr, acceptance, always_accepted);
860 return acceptance;
861}
862
863static void GetTileDesc_Town(TileIndex tile, TileDesc &td)
864{
865 const HouseID house = GetHouseType(tile);
866 const HouseSpec *hs = HouseSpec::Get(house);
867 bool house_completed = IsHouseCompleted(tile);
868
869 td.str = hs->building_name;
871
872 std::array<int32_t, 1> regs100;
873 uint16_t callback_res = GetHouseCallback(CBID_HOUSE_CUSTOM_NAME, house_completed ? 1 : 0, 0, house, Town::GetByTile(tile), tile, regs100);
874 if (callback_res != CALLBACK_FAILED && callback_res != 0x400) {
875 StringID new_name = STR_NULL;
876 if (callback_res == 0x40F) {
877 new_name = GetGRFStringID(hs->grf_prop.grfid, static_cast<GRFStringID>(regs100[0]));
878 } else if (callback_res > 0x400) {
880 } else {
881 new_name = GetGRFStringID(hs->grf_prop.grfid, GRFSTR_MISC_GRF_TEXT + callback_res);
882 }
883 if (new_name != STR_NULL && new_name != STR_UNDEFINED) {
884 td.str = new_name;
885 }
886 }
887
888 if (!house_completed) {
889 td.dparam = td.str;
890 td.str = STR_LAI_TOWN_INDUSTRY_DESCRIPTION_UNDER_CONSTRUCTION;
891 }
892
893 if (hs->grf_prop.HasGrfFile()) {
894 const GRFConfig *gc = GetGRFConfig(hs->grf_prop.grfid);
895 td.grf = gc->GetName();
896 }
897
898 td.owner[0] = OWNER_TOWN;
899}
900
901static TrackStatus GetTileTrackStatus_Town(TileIndex, TransportType, uint, DiagDirection)
902{
903 /* not used */
904 return 0;
905}
906
907static void ChangeTileOwner_Town(TileIndex, Owner, Owner)
908{
909 /* not used */
910}
911
912static bool GrowTown(Town *t, TownExpandModes modes);
913
918static void TownTickHandler(Town *t)
919{
920 if (HasBit(t->flags, TOWN_IS_GROWING)) {
923 int i = (int)t->grow_counter - 1;
924 if (i < 0) {
925 if (GrowTown(t, modes)) {
926 i = t->growth_rate;
927 } else {
928 /* If growth failed wait a bit before retrying */
929 i = std::min<uint16_t>(t->growth_rate, Ticks::TOWN_GROWTH_TICKS - 1);
930 }
931 }
932 t->grow_counter = i;
933 }
934}
935
938{
939 if (_game_mode == GM_EDITOR) return;
940
941 for (Town *t : Town::Iterate()) {
943 }
944}
945
952{
953 if (IsRoadDepotTile(tile) || IsBayRoadStopTile(tile)) return ROAD_NONE;
954
955 return GetAnyRoadBits(tile, RTT_ROAD, true);
956}
957
963{
964 RoadType best_rt = ROADTYPE_ROAD;
965 const RoadTypeInfo *best = nullptr;
966 const uint16_t assume_max_speed = 50;
967
968 for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
969 if (RoadTypeIsTram(rt)) continue;
970
971 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
972
973 /* Unused road type. */
974 if (rti->label == 0) continue;
975
976 /* Can town build this road. */
977 if (!rti->flags.Test(RoadTypeFlag::TownBuild)) continue;
978
979 /* Not yet introduced at this date. */
981
982 if (best != nullptr) {
983 if ((rti->max_speed == 0 ? assume_max_speed : rti->max_speed) < (best->max_speed == 0 ? assume_max_speed : best->max_speed)) continue;
984 }
985
986 best_rt = rt;
987 best = rti;
988 }
989
990 return best_rt;
991}
992
998{
999 const RoadTypeInfo *best = nullptr;
1000 for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
1001 if (RoadTypeIsTram(rt)) continue;
1002 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
1003 if (rti->label == 0) continue; // Unused road type.
1004 if (!rti->flags.Test(RoadTypeFlag::TownBuild)) continue; // Town can't build this road type.
1005
1006 if (best != nullptr && rti->introduction_date >= best->introduction_date) continue;
1007 best = rti;
1008 }
1009
1010 if (best == nullptr) return TimerGameCalendar::Date(INT32_MAX);
1011 return best->introduction_date;
1012}
1013
1019{
1020 auto min_date = GetTownRoadTypeFirstIntroductionDate();
1021 if (min_date <= TimerGameCalendar::date) return true;
1022
1023 if (min_date < INT32_MAX) {
1025 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_YET),
1026 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_YET_EXPLANATION, min_date),
1027 WL_CRITICAL);
1028 } else {
1030 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_AT_ALL),
1031 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_AT_ALL_EXPLANATION), WL_CRITICAL);
1032 }
1033 return false;
1034}
1035
1046static bool IsNeighbourRoadTile(TileIndex tile, const DiagDirection dir, uint dist_multi)
1047{
1048 if (!IsValidTile(tile)) return false;
1049
1050 /* Lookup table for the used diff values */
1051 const TileIndexDiff tid_lt[3] = {
1055 };
1056
1057 dist_multi = (dist_multi + 1) * 4;
1058 for (uint pos = 4; pos < dist_multi; pos++) {
1059 /* Go (pos / 4) tiles to the left or the right */
1060 TileIndexDiff cur = tid_lt[(pos & 1) ? 0 : 1] * (pos / 4);
1061
1062 /* Use the current tile as origin, or go one tile backwards */
1063 if (pos & 2) cur += tid_lt[2];
1064
1065 /* Test for roadbit parallel to dir and facing towards the middle axis */
1066 if (IsValidTile(tile + cur) &&
1067 GetTownRoadBits(TileAdd(tile, cur)) & DiagDirToRoadBits((pos & 2) ? dir : ReverseDiagDir(dir))) return true;
1068 }
1069 return false;
1070}
1071
1081{
1082 if (DistanceFromEdge(tile) == 0) return false;
1083
1084 /* Prevent towns from building roads under bridges along the bridge. Looks silly. */
1085 if (IsBridgeAbove(tile) && GetBridgeAxis(tile) == DiagDirToAxis(dir)) return false;
1086
1087 /* Check if there already is a road at this point? */
1088 if (GetTownRoadBits(tile) == ROAD_NONE) {
1089 /* No, try if we are able to build a road piece there.
1090 * If that fails clear the land, and if that fails exit.
1091 * This is to make sure that we can build a road here later. */
1095 return false;
1096 }
1097 }
1098
1099 Slope cur_slope = _settings_game.construction.build_on_slopes ? std::get<0>(GetFoundationSlope(tile)) : GetTileSlope(tile);
1100 bool ret = !IsNeighbourRoadTile(tile, dir, t->layout == TL_ORIGINAL ? 1 : 2);
1101 if (cur_slope == SLOPE_FLAT) return ret;
1102
1103 /* If the tile is not a slope in the right direction, then
1104 * maybe terraform some. */
1105 Slope desired_slope = (dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? SLOPE_NW : SLOPE_NE;
1106 if (desired_slope != cur_slope && ComplementSlope(desired_slope) != cur_slope) {
1107 if (Chance16(1, 8)) {
1108 CommandCost res = CMD_ERROR;
1109 if (!_generating_world && Chance16(1, 10)) {
1110 /* Note: Do not replace "^ SLOPE_ELEVATED" with ComplementSlope(). The slope might be steep. */
1112 tile, Chance16(1, 16) ? cur_slope : cur_slope ^ SLOPE_ELEVATED, false));
1113 }
1114 if (res.Failed() && Chance16(1, 3)) {
1115 /* We can consider building on the slope, though. */
1116 return ret;
1117 }
1118 }
1119 return false;
1120 }
1121 return ret;
1122}
1123
1124static bool TerraformTownTile(TileIndex tile, Slope edges, bool dir)
1125{
1126 assert(tile < Map::Size());
1127
1129 if (r.Failed() || r.GetCost() >= (_price[PR_TERRAFORM] + 2) * 8) return false;
1131 return true;
1132}
1133
1134static void LevelTownLand(TileIndex tile)
1135{
1136 assert(tile < Map::Size());
1137
1138 /* Don't terraform if land is plain or if there's a house there. */
1139 if (IsTileType(tile, MP_HOUSE)) return;
1140 Slope tileh = GetTileSlope(tile);
1141 if (tileh == SLOPE_FLAT) return;
1142
1143 /* First try up, then down */
1144 if (!TerraformTownTile(tile, ~tileh & SLOPE_ELEVATED, true)) {
1145 TerraformTownTile(tile, tileh & SLOPE_ELEVATED, false);
1146 }
1147}
1148
1158{
1159 /* align the grid to the downtown */
1160 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile); // Vector from downtown to the tile
1161 RoadBits rcmd = ROAD_NONE;
1162
1163 switch (t->layout) {
1164 default: NOT_REACHED();
1165
1166 case TL_2X2_GRID:
1167 if ((grid_pos.x % 3) == 0) rcmd |= ROAD_Y;
1168 if ((grid_pos.y % 3) == 0) rcmd |= ROAD_X;
1169 break;
1170
1171 case TL_3X3_GRID:
1172 if ((grid_pos.x % 4) == 0) rcmd |= ROAD_Y;
1173 if ((grid_pos.y % 4) == 0) rcmd |= ROAD_X;
1174 break;
1175 }
1176
1177 /* Optimise only X-junctions */
1178 if (rcmd != ROAD_ALL) return rcmd;
1179
1180 RoadBits rb_template;
1181
1182 switch (GetTileSlope(tile)) {
1183 default: rb_template = ROAD_ALL; break;
1184 case SLOPE_W: rb_template = ROAD_NW | ROAD_SW; break;
1185 case SLOPE_SW: rb_template = ROAD_Y | ROAD_SW; break;
1186 case SLOPE_S: rb_template = ROAD_SW | ROAD_SE; break;
1187 case SLOPE_SE: rb_template = ROAD_X | ROAD_SE; break;
1188 case SLOPE_E: rb_template = ROAD_SE | ROAD_NE; break;
1189 case SLOPE_NE: rb_template = ROAD_Y | ROAD_NE; break;
1190 case SLOPE_N: rb_template = ROAD_NE | ROAD_NW; break;
1191 case SLOPE_NW: rb_template = ROAD_X | ROAD_NW; break;
1192 case SLOPE_STEEP_W:
1193 case SLOPE_STEEP_S:
1194 case SLOPE_STEEP_E:
1195 case SLOPE_STEEP_N:
1196 rb_template = ROAD_NONE;
1197 break;
1198 }
1199
1200 /* Stop if the template is compatible to the growth dir */
1201 if (DiagDirToRoadBits(ReverseDiagDir(dir)) & rb_template) return rb_template;
1202 /* If not generate a straight road in the direction of the growth */
1204}
1205
1217{
1218 /* We can't look further than that. */
1219 if (DistanceFromEdge(tile) == 0) return false;
1220
1221 uint counter = 0; // counts the house neighbour tiles
1222
1223 /* Check the tiles E,N,W and S of the current tile for houses */
1224 for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
1225 /* Count both void and house tiles for checking whether there
1226 * are enough houses in the area. This to make it likely that
1227 * houses get build up to the edge of the map. */
1228 switch (GetTileType(TileAddByDiagDir(tile, dir))) {
1229 case MP_HOUSE:
1230 case MP_VOID:
1231 counter++;
1232 break;
1233
1234 default:
1235 break;
1236 }
1237
1238 /* If there are enough neighbours stop here */
1239 if (counter >= 3) {
1240 return TryBuildTownHouse(t, tile, modes);
1241 }
1242 }
1243 return false;
1244}
1245
1254static bool GrowTownWithRoad(const Town *t, TileIndex tile, RoadBits rcmd)
1255{
1258}
1259
1269static bool CanRoadContinueIntoNextTile(const Town *t, const TileIndex tile, const DiagDirection road_dir)
1270{
1271 const TileIndexDiff delta = TileOffsByDiagDir(road_dir); // +1 tile in the direction of the road
1272 TileIndex next_tile = tile + delta; // The tile beyond which must be connectable to the target tile
1273 RoadBits rcmd = DiagDirToRoadBits(ReverseDiagDir(road_dir));
1275
1276 /* Before we try anything, make sure the tile is on the map and not the void. */
1277 if (!IsValidTile(next_tile)) return false;
1278
1279 /* If the next tile is a bridge or tunnel, allow if it's continuing in the same direction. */
1280 if (IsTileType(next_tile, MP_TUNNELBRIDGE)) {
1281 return GetTunnelBridgeTransportType(next_tile) == TRANSPORT_ROAD && GetTunnelBridgeDirection(next_tile) == road_dir;
1282 }
1283
1284 /* If the next tile is a station, allow if it's a road station facing the proper direction. Otherwise return false. */
1285 if (IsTileType(next_tile, MP_STATION)) {
1286 /* If the next tile is a road station, allow if it can be entered by the new tunnel/bridge, otherwise disallow. */
1287 if (IsDriveThroughStopTile(next_tile)) return GetDriveThroughStopAxis(next_tile) == DiagDirToAxis(road_dir);
1288 if (IsBayRoadStopTile(next_tile)) return GetBayRoadStopDir(next_tile) == ReverseDiagDir(road_dir);
1289 return false;
1290 }
1291
1292 /* If the next tile is a road depot, allow if it's facing the right way. */
1293 if (IsTileType(next_tile, MP_ROAD)) {
1294 return IsRoadDepot(next_tile) && GetRoadDepotDirection(next_tile) == ReverseDiagDir(road_dir);
1295 }
1296
1297 /* If the next tile is a railroad track, check if towns are allowed to build level crossings.
1298 * If level crossing are not allowed, reject the construction. Else allow DoCommand to determine if the rail track is buildable. */
1299 if (IsTileType(next_tile, MP_RAILWAY) && !_settings_game.economy.allow_town_level_crossings) return false;
1300
1301 /* If a road tile can be built, the construction is allowed. */
1302 return Command<CMD_BUILD_ROAD>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, next_tile, rcmd, rt, DRD_NONE, t->index).Succeeded();
1303}
1304
1315static bool GrowTownWithBridge(const Town *t, const TileIndex tile, const DiagDirection bridge_dir)
1316{
1317 assert(bridge_dir < DIAGDIR_END);
1318
1319 const Slope slope = GetTileSlope(tile);
1320
1321 /* Make sure the direction is compatible with the slope.
1322 * Well we check if the slope has an up bit set in the
1323 * reverse direction. */
1324 if (slope != SLOPE_FLAT && slope & InclinedSlope(bridge_dir)) return false;
1325
1326 /* Assure that the bridge is connectable to the start side */
1327 if (!(GetTownRoadBits(TileAddByDiagDir(tile, ReverseDiagDir(bridge_dir))) & DiagDirToRoadBits(bridge_dir))) return false;
1328
1329 /* We are in the right direction */
1330 uint bridge_length = 0; // This value stores the length of the possible bridge
1331 TileIndex bridge_tile = tile; // Used to store the other waterside
1332
1333 const TileIndexDiff delta = TileOffsByDiagDir(bridge_dir);
1334
1335 /* To prevent really small towns from building disproportionately
1336 * long bridges, make the max a function of its population. */
1337 const uint TOWN_BRIDGE_LENGTH_CAP = 11;
1338 uint base_bridge_length = 5;
1339 uint max_bridge_length = std::min(t->cache.population / 1000 + base_bridge_length, TOWN_BRIDGE_LENGTH_CAP);
1340
1341 if (slope == SLOPE_FLAT) {
1342 /* Bridges starting on flat tiles are only allowed when crossing rivers, rails or one-way roads. */
1343 do {
1344 if (bridge_length++ >= base_bridge_length) {
1345 /* Allow to cross rivers, not big lakes, nor large amounts of rails or one-way roads. */
1346 return false;
1347 }
1348 bridge_tile += delta;
1349 } while (IsValidTile(bridge_tile) && ((IsWaterTile(bridge_tile) && !IsSea(bridge_tile)) || IsPlainRailTile(bridge_tile) || (IsNormalRoadTile(bridge_tile) && GetDisallowedRoadDirections(bridge_tile) != DRD_NONE)));
1350 } else {
1351 do {
1352 if (bridge_length++ >= max_bridge_length) {
1353 /* Ensure the bridge is not longer than the max allowed length. */
1354 return false;
1355 }
1356 bridge_tile += delta;
1357 } while (IsValidTile(bridge_tile) && (IsWaterTile(bridge_tile) || IsPlainRailTile(bridge_tile) || (IsNormalRoadTile(bridge_tile) && GetDisallowedRoadDirections(bridge_tile) != DRD_NONE)));
1358 }
1359
1360 /* Don't allow a bridge where the start and end tiles are adjacent with no span between. */
1361 if (bridge_length == 1) return false;
1362
1363 /* Make sure the road can be continued past the bridge. At this point, bridge_tile holds the end tile of the bridge. */
1364 if (!CanRoadContinueIntoNextTile(t, bridge_tile, bridge_dir)) return false;
1365
1366 /* If another parallel bridge exists nearby, this one would be redundant and shouldn't be built. We don't care about flat bridges. */
1367 if (slope != SLOPE_FLAT) {
1368 for (auto search : SpiralTileSequence(tile, bridge_length, 0, 0)) {
1369 /* Only consider bridge head tiles. */
1370 if (!IsBridgeTile(search)) continue;
1371
1372 /* Only consider road bridges. */
1373 if (GetTunnelBridgeTransportType(search) != TRANSPORT_ROAD) continue;
1374
1375 /* If the bridge is facing the same direction as the proposed bridge, we've found a redundant bridge. */
1376 if (GetTileSlope(search) & InclinedSlope(ReverseDiagDir(bridge_dir))) return false;
1377 }
1378 }
1379
1380 for (uint8_t times = 0; times <= 22; times++) {
1381 uint8_t bridge_type = RandomRange(MAX_BRIDGES - 1);
1382
1383 /* Can we actually build the bridge? */
1385 if (Command<CMD_BUILD_BRIDGE>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_BRIDGE>()), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, rt).Succeeded()) {
1386 Command<CMD_BUILD_BRIDGE>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_BRIDGE>()).Set(DoCommandFlag::Execute), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, rt);
1387 return true;
1388 }
1389 }
1390 /* Quit if it selecting an appropriate bridge type fails a large number of times. */
1391 return false;
1392}
1393
1404static bool GrowTownWithTunnel(const Town *t, const TileIndex tile, const DiagDirection tunnel_dir)
1405{
1406 assert(tunnel_dir < DIAGDIR_END);
1407
1408 Slope slope = GetTileSlope(tile);
1409
1410 /* Only consider building a tunnel if the starting tile is sloped properly. */
1411 if (slope != InclinedSlope(tunnel_dir)) return false;
1412
1413 /* Assure that the tunnel is connectable to the start side */
1414 if (!(GetTownRoadBits(TileAddByDiagDir(tile, ReverseDiagDir(tunnel_dir))) & DiagDirToRoadBits(tunnel_dir))) return false;
1415
1416 const TileIndexDiff delta = TileOffsByDiagDir(tunnel_dir);
1417 int max_tunnel_length = 0;
1418
1419 /* There are two conditions for building tunnels: Under a mountain and under an obstruction. */
1420 if (CanRoadContinueIntoNextTile(t, tile, tunnel_dir)) {
1421 /* 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. */
1422 TileIndex slope_tile = tile;
1423 for (uint8_t tiles = 0; tiles < 4; tiles++) {
1424 if (!IsValidTile(slope_tile)) return false;
1425 slope = GetTileSlope(slope_tile);
1426 if (slope != InclinedSlope(tunnel_dir) && !IsSteepSlope(slope) && !IsSlopeWithOneCornerRaised(slope)) return false;
1427 slope_tile += delta;
1428 }
1429
1430 /* More population means longer tunnels, but make sure we can at least cover the smallest mountain which neccesitates tunneling. */
1431 max_tunnel_length = (t->cache.population / 1000) + 7;
1432 } else {
1433 /* When tunneling under an obstruction, the length limit is 5, enough to tunnel under a four-track railway. */
1434 max_tunnel_length = 5;
1435 }
1436
1437 uint8_t tunnel_length = 0;
1438 TileIndex tunnel_tile = tile; // Iteratator to store the other end tile of the tunnel.
1439
1440 /* Find the end tile of the tunnel for length and continuation checks. */
1441 do {
1442 if (tunnel_length++ >= max_tunnel_length) return false;
1443 tunnel_tile += delta;
1444 /* The tunnel ends when start and end tiles are the same height. */
1445 } while (IsValidTile(tunnel_tile) && GetTileZ(tile) != GetTileZ(tunnel_tile));
1446
1447 /* Don't allow a tunnel where the start and end tiles are adjacent. */
1448 if (tunnel_length == 1) return false;
1449
1450 /* Make sure the road can be continued past the tunnel. At this point, tunnel_tile holds the end tile of the tunnel. */
1451 if (!CanRoadContinueIntoNextTile(t, tunnel_tile, tunnel_dir)) return false;
1452
1453 /* Attempt to build the tunnel. Return false if it fails to let the town build a road instead. */
1455 if (Command<CMD_BUILD_TUNNEL>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_TUNNEL>()), tile, TRANSPORT_ROAD, rt).Succeeded()) {
1456 Command<CMD_BUILD_TUNNEL>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_TUNNEL>()).Set(DoCommandFlag::Execute), tile, TRANSPORT_ROAD, rt);
1457 return true;
1458 }
1459
1460 return false;
1461}
1462
1470{
1471 static const TileIndexDiffC tiles[] = { {-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1} };
1472 bool allow = false;
1473
1474 for (const auto &ptr : tiles) {
1475 TileIndex cur_tile = t + ToTileIndexDiff(ptr);
1476 if (!IsValidTile(cur_tile)) continue;
1477
1478 if (!(IsTileType(cur_tile, MP_ROAD) || IsAnyRoadStopTile(cur_tile))) continue;
1479 allow = true;
1480
1481 RoadType road_rt = GetRoadTypeRoad(cur_tile);
1482 RoadType tram_rt = GetRoadTypeTram(cur_tile);
1483 if (road_rt != INVALID_ROADTYPE && !GetRoadTypeInfo(road_rt)->flags.Test(RoadTypeFlag::NoHouses)) return true;
1484 if (tram_rt != INVALID_ROADTYPE && !GetRoadTypeInfo(tram_rt)->flags.Test(RoadTypeFlag::NoHouses)) return true;
1485 }
1486
1487 /* If no road was found surrounding the tile we can allow building the house since there is
1488 * nothing which forbids it, if a road was found but the execution reached this point, then
1489 * all the found roads don't allow houses to be built */
1490 return !allow;
1491}
1492
1498{
1499 if (!IsTileType(tile, MP_ROAD)) return true;
1500
1501 /* Allow extending on roadtypes which can be built by town, or if the road type matches the type the town will build. */
1502 RoadType rt = GetRoadTypeRoad(tile);
1504}
1505
1511{
1512 return modes.Test(TownExpandMode::Roads);
1513}
1514
1515/* The possible states of town growth. */
1516enum class TownGrowthResult {
1517 Succeed,
1518 SearchStopped,
1519 Continue,
1520};
1521
1540static TownGrowthResult GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection target_dir, Town *t1, TownExpandModes modes)
1541{
1542 RoadBits rcmd = ROAD_NONE; // RoadBits for the road construction command
1543 TileIndex tile = *tile_ptr; // The main tile on which we base our growth
1544
1545 assert(tile < Map::Size());
1546
1547 if (cur_rb == ROAD_NONE) {
1548 /* Tile has no road.
1549 * We will return TownGrowthResult::SearchStopped to say that this is the last iteration. */
1550
1551 if (!TownAllowedToBuildRoads(modes)) return TownGrowthResult::SearchStopped;
1552 if (!_settings_game.economy.allow_town_level_crossings && IsTileType(tile, MP_RAILWAY)) return TownGrowthResult::SearchStopped;
1553
1554 /* Remove hills etc */
1555 if (!_settings_game.construction.build_on_slopes || Chance16(1, 6)) LevelTownLand(tile);
1556
1557 /* Is a road allowed here? */
1558 switch (t1->layout) {
1559 default: NOT_REACHED();
1560
1561 case TL_3X3_GRID:
1562 case TL_2X2_GRID:
1563 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1564 if (rcmd == ROAD_NONE) return TownGrowthResult::SearchStopped;
1565 break;
1566
1567 case TL_BETTER_ROADS:
1568 case TL_ORIGINAL:
1569 if (!IsRoadAllowedHere(t1, tile, target_dir)) return TownGrowthResult::SearchStopped;
1570
1571 DiagDirection source_dir = ReverseDiagDir(target_dir);
1572
1573 if (Chance16(1, 4)) {
1574 /* Randomize a new target dir */
1575 do target_dir = RandomDiagDir(); while (target_dir == source_dir);
1576 }
1577
1578 if (!IsRoadAllowedHere(t1, TileAddByDiagDir(tile, target_dir), target_dir)) {
1579 /* A road is not allowed to continue the randomized road,
1580 * return if the road we're trying to build is curved. */
1581 if (target_dir != ReverseDiagDir(source_dir)) return TownGrowthResult::SearchStopped;
1582
1583 /* Return if neither side of the new road is a house */
1586 return TownGrowthResult::SearchStopped;
1587 }
1588
1589 /* That means that the road is only allowed if there is a house
1590 * at any side of the new road. */
1591 }
1592
1593 rcmd = DiagDirToRoadBits(target_dir) | DiagDirToRoadBits(source_dir);
1594 break;
1595 }
1596
1597 } else if (target_dir < DIAGDIR_END && !(cur_rb & DiagDirToRoadBits(ReverseDiagDir(target_dir)))) {
1598 if (!TownCanGrowRoad(tile)) return TownGrowthResult::Continue;
1599
1600 if (!TownAllowedToBuildRoads(modes)) return TownGrowthResult::SearchStopped;
1601
1602 /* Continue building on a partial road.
1603 * Should be always OK, so we only generate
1604 * the fitting RoadBits */
1605 switch (t1->layout) {
1606 default: NOT_REACHED();
1607
1608 case TL_3X3_GRID:
1609 case TL_2X2_GRID:
1610 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1611 break;
1612
1613 case TL_BETTER_ROADS:
1614 case TL_ORIGINAL:
1615 rcmd = DiagDirToRoadBits(ReverseDiagDir(target_dir));
1616 break;
1617 }
1618 } else {
1619 bool allow_house = true; // Value which decides if we want to construct a house
1620
1621 /* Reached a tunnel/bridge? Then continue at the other side of it, unless
1622 * it is the starting tile. Half the time, we stay on this side then.*/
1623 if (IsTileType(tile, MP_TUNNELBRIDGE)) {
1624 if (GetTunnelBridgeTransportType(tile) == TRANSPORT_ROAD && (target_dir != DIAGDIR_END || Chance16(1, 2))) {
1625 *tile_ptr = GetOtherTunnelBridgeEnd(tile);
1626 }
1627 return TownGrowthResult::Continue;
1628 }
1629
1630 /* Possibly extend the road in a direction.
1631 * Randomize a direction and if it has a road, bail out. */
1632 target_dir = RandomDiagDir();
1633 RoadBits target_rb = DiagDirToRoadBits(target_dir);
1634 TileIndex house_tile; // position of a possible house
1635
1636 if (cur_rb & target_rb) {
1637 /* If it's a road turn possibly build a house in a corner.
1638 * Use intersection with straight road as an indicator
1639 * that we randomed corner house position.
1640 * A turn (and we check for that later) always has only
1641 * one common bit with a straight road so it has the same
1642 * chance to be chosen as the house on the side of a road.
1643 */
1644 if ((cur_rb & ROAD_X) != target_rb) return TownGrowthResult::Continue;
1645
1646 /* Check whether it is a turn and if so determine
1647 * position of the corner tile */
1648 switch (cur_rb) {
1649 case ROAD_N:
1650 house_tile = TileAddByDir(tile, DIR_S);
1651 break;
1652 case ROAD_S:
1653 house_tile = TileAddByDir(tile, DIR_N);
1654 break;
1655 case ROAD_E:
1656 house_tile = TileAddByDir(tile, DIR_W);
1657 break;
1658 case ROAD_W:
1659 house_tile = TileAddByDir(tile, DIR_E);
1660 break;
1661 default:
1662 return TownGrowthResult::Continue; // not a turn
1663 }
1664 target_dir = DIAGDIR_END;
1665 } else {
1666 house_tile = TileAddByDiagDir(tile, target_dir);
1667 }
1668
1669 /* Don't walk into water. */
1670 if (HasTileWaterGround(house_tile)) return TownGrowthResult::Continue;
1671
1672 if (!IsValidTile(house_tile)) return TownGrowthResult::Continue;
1673
1674 TownGrowthResult result = TownGrowthResult::Continue;
1675
1676 if (target_dir != DIAGDIR_END && TownAllowedToBuildRoads(modes)) {
1677 switch (t1->layout) {
1678 default: NOT_REACHED();
1679
1680 case TL_3X3_GRID: // Use 2x2 grid afterwards!
1681 if (GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir), modes)) {
1682 result = TownGrowthResult::Succeed;
1683 }
1684 [[fallthrough]];
1685
1686 case TL_2X2_GRID:
1687 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1688 allow_house = (rcmd & target_rb) == ROAD_NONE;
1689 break;
1690
1691 case TL_BETTER_ROADS: // Use original afterwards!
1692 if (GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir), modes)) {
1693 result = TownGrowthResult::Succeed;
1694 }
1695 [[fallthrough]];
1696
1697 case TL_ORIGINAL:
1698 /* Allow a house at the edge. 60% chance or
1699 * always ok if no road allowed. */
1700 rcmd = target_rb;
1701 allow_house = (!IsRoadAllowedHere(t1, house_tile, target_dir) || Chance16(6, 10));
1702 break;
1703 }
1704 }
1705
1706 allow_house &= RoadTypesAllowHouseHere(house_tile);
1707
1708 if (allow_house) {
1709 /* Build a house, but not if there already is a house there. */
1710 if (!IsTileType(house_tile, MP_HOUSE)) {
1711 /* Level the land if possible */
1712 if (Chance16(1, 6)) LevelTownLand(house_tile);
1713
1714 /* And build a house.
1715 * Set result to -1 if we managed to build it. */
1716 if (TryBuildTownHouse(t1, house_tile, modes)) {
1717 result = TownGrowthResult::Succeed;
1718 }
1719 }
1720 return result;
1721 }
1722
1723 if (!TownCanGrowRoad(tile)) return result;
1724 }
1725
1726 /* Return if a water tile */
1727 if (HasTileWaterGround(tile)) return TownGrowthResult::SearchStopped;
1728
1729 /* Make the roads look nicer */
1730 rcmd = CleanUpRoadBits(tile, rcmd);
1731 if (rcmd == ROAD_NONE) return TownGrowthResult::SearchStopped;
1732
1733 /* Only use the target direction for bridges and tunnels to ensure they're connected.
1734 * The target_dir is as computed previously according to town layout, so
1735 * it will match it perfectly. */
1736 if (GrowTownWithBridge(t1, tile, target_dir)) {
1737 return TownGrowthResult::Succeed;
1738 }
1739 if (GrowTownWithTunnel(t1, tile, target_dir)) {
1740 return TownGrowthResult::Succeed;
1741 }
1742
1743 if (GrowTownWithRoad(t1, tile, rcmd)) {
1744 return TownGrowthResult::Succeed;
1745 }
1746 return TownGrowthResult::SearchStopped;
1747}
1748
1757{
1758 TileIndex target_tile = tile + TileOffsByDiagDir(dir);
1759 if (!IsValidTile(target_tile)) return false;
1760 if (HasTileWaterGround(target_tile)) return false;
1761
1762 RoadBits target_rb = GetTownRoadBits(target_tile);
1763 if (TownAllowedToBuildRoads(modes)) {
1764 /* Check whether a road connection exists or can be build. */
1765 switch (GetTileType(target_tile)) {
1766 case MP_ROAD:
1767 return target_rb != ROAD_NONE;
1768
1769 case MP_STATION:
1770 return IsDriveThroughStopTile(target_tile);
1771
1772 case MP_TUNNELBRIDGE:
1773 return GetTunnelBridgeTransportType(target_tile) == TRANSPORT_ROAD;
1774
1775 case MP_HOUSE:
1776 case MP_INDUSTRY:
1777 case MP_OBJECT:
1778 return false;
1779
1780 default:
1781 /* Checked for void and water earlier */
1782 return true;
1783 }
1784 } else {
1785 /* Check whether a road connection already exists,
1786 * and it leads somewhere else. */
1788 return (target_rb & back_rb) != 0 && (target_rb & ~back_rb) != 0;
1789 }
1790}
1791
1798static bool GrowTownAtRoad(Town *t, TileIndex tile, TownExpandModes modes)
1799{
1800 /* Special case.
1801 * @see GrowTownInTile Check the else if
1802 */
1803 DiagDirection target_dir = DIAGDIR_END; // The direction in which we want to extend the town
1804
1805 assert(tile < Map::Size());
1806
1807 /* Number of times to search.
1808 * Better roads, 2X2 and 3X3 grid grow quite fast so we give
1809 * them a little handicap. */
1810 int iterations;
1811 switch (t->layout) {
1812 case TL_BETTER_ROADS:
1813 iterations = 10 + t->cache.num_houses * 2 / 9;
1814 break;
1815
1816 case TL_3X3_GRID:
1817 case TL_2X2_GRID:
1818 iterations = 10 + t->cache.num_houses * 1 / 9;
1819 break;
1820
1821 default:
1822 iterations = 10 + t->cache.num_houses * 4 / 9;
1823 break;
1824 }
1825
1826 do {
1827 RoadBits cur_rb = GetTownRoadBits(tile); // The RoadBits of the current tile
1828
1829 /* Try to grow the town from this point */
1830 switch (GrowTownInTile(&tile, cur_rb, target_dir, t, modes)) {
1831 case TownGrowthResult::Succeed:
1832 return true;
1833 case TownGrowthResult::SearchStopped:
1834 iterations = 0;
1835 break;
1836 default:
1837 break;
1838 };
1839
1840 /* Exclude the source position from the bitmask
1841 * and return if no more road blocks available */
1842 if (IsValidDiagDirection(target_dir)) cur_rb &= ~DiagDirToRoadBits(ReverseDiagDir(target_dir));
1843 if (cur_rb == ROAD_NONE) return false;
1844
1845 if (IsTileType(tile, MP_TUNNELBRIDGE)) {
1846 /* Only build in the direction away from the tunnel or bridge. */
1847 target_dir = ReverseDiagDir(GetTunnelBridgeDirection(tile));
1848 } else {
1849 /* Select a random bit from the blockmask, walk a step
1850 * and continue the search from there. */
1851 do {
1852 if (cur_rb == ROAD_NONE) return false;
1853 RoadBits target_bits;
1854 do {
1855 target_dir = RandomDiagDir();
1856 target_bits = DiagDirToRoadBits(target_dir);
1857 } while (!(cur_rb & target_bits));
1858 cur_rb &= ~target_bits;
1859 } while (!CanFollowRoad(tile, target_dir, modes));
1860 }
1861 tile = TileAddByDiagDir(tile, target_dir);
1862
1863 if (IsTileType(tile, MP_ROAD) && !IsRoadDepot(tile) && HasTileRoadType(tile, RTT_ROAD)) {
1864 /* Don't allow building over roads of other cities */
1865 if (IsRoadOwner(tile, RTT_ROAD, OWNER_TOWN) && Town::GetByTile(tile) != t) {
1866 return false;
1867 } else if (IsRoadOwner(tile, RTT_ROAD, OWNER_NONE) && _game_mode == GM_EDITOR) {
1868 /* If we are in the SE, and this road-piece has no town owner yet, it just found an
1869 * owner :) (happy happy happy road now) */
1870 SetRoadOwner(tile, RTT_ROAD, OWNER_TOWN);
1871 SetTownIndex(tile, t->index);
1872 }
1873 }
1874
1875 /* Max number of times is checked. */
1876 } while (--iterations >= 0);
1877
1878 return false;
1879}
1880
1889{
1890 uint32_t r = Random();
1891 uint a = GB(r, 0, 2);
1892 uint b = GB(r, 8, 2);
1893 if (a == b) b ^= 2;
1894 return (RoadBits)((ROAD_NW << a) + (ROAD_NW << b));
1895}
1896
1902static bool GrowTown(Town *t, TownExpandModes modes)
1903{
1904 static const TileIndexDiffC _town_coord_mod[] = {
1905 {-1, 0},
1906 { 1, 1},
1907 { 1, -1},
1908 {-1, -1},
1909 {-1, 0},
1910 { 0, 2},
1911 { 2, 0},
1912 { 0, -2},
1913 {-1, -1},
1914 {-2, 2},
1915 { 2, 2},
1916 { 2, -2},
1917 { 0, 0}
1918 };
1919
1920 /* Current "company" is a town */
1922
1923 TileIndex tile = t->xy; // The tile we are working with ATM
1924
1925 /* Find a road that we can base the construction on. */
1926 for (const auto &ptr : _town_coord_mod) {
1927 if (GetTownRoadBits(tile) != ROAD_NONE) {
1928 bool success = GrowTownAtRoad(t, tile, modes);
1929 cur_company.Restore();
1930 return success;
1931 }
1932 tile = TileAdd(tile, ToTileIndexDiff(ptr));
1933 }
1934
1935 /* No road available, try to build a random road block by
1936 * clearing some land and then building a road there. */
1937 if (TownAllowedToBuildRoads(modes)) {
1938 tile = t->xy;
1939 for (const auto &ptr : _town_coord_mod) {
1940 /* Only work with plain land that not already has a house */
1941 if (!IsTileType(tile, MP_HOUSE) && IsTileFlat(tile)) {
1945 cur_company.Restore();
1946 return true;
1947 }
1948 }
1949 tile = TileAdd(tile, ToTileIndexDiff(ptr));
1950 }
1951 }
1952
1953 cur_company.Restore();
1954 return false;
1955}
1956
1962{
1963 static const std::array<std::array<uint32_t, NUM_HOUSE_ZONES>, 23> _town_squared_town_zone_radius_data = {{
1964 { 4, 0, 0, 0, 0}, // 0
1965 { 16, 0, 0, 0, 0},
1966 { 25, 0, 0, 0, 0},
1967 { 36, 0, 0, 0, 0},
1968 { 49, 0, 4, 0, 0},
1969 { 64, 0, 4, 0, 0}, // 20
1970 { 64, 0, 9, 0, 1},
1971 { 64, 0, 9, 0, 4},
1972 { 64, 0, 16, 0, 4},
1973 { 81, 0, 16, 0, 4},
1974 { 81, 0, 16, 0, 4}, // 40
1975 { 81, 0, 25, 0, 9},
1976 { 81, 36, 25, 0, 9},
1977 { 81, 36, 25, 16, 9},
1978 { 81, 49, 0, 25, 9},
1979 { 81, 64, 0, 25, 9}, // 60
1980 { 81, 64, 0, 36, 9},
1981 { 81, 64, 0, 36, 16},
1982 {100, 81, 0, 49, 16},
1983 {100, 81, 0, 49, 25},
1984 {121, 81, 0, 49, 25}, // 80
1985 {121, 81, 0, 49, 25},
1986 {121, 81, 0, 49, 36}, // 88
1987 }};
1988
1989 if (t->cache.num_houses < std::size(_town_squared_town_zone_radius_data) * 4) {
1990 t->cache.squared_town_zone_radius = _town_squared_town_zone_radius_data[t->cache.num_houses / 4];
1991 } else {
1992 int mass = t->cache.num_houses / 8;
1993 /* Actually we are proportional to sqrt() but that's right because we are covering an area.
1994 * The offsets are to make sure the radii do not decrease in size when going from the table
1995 * to the calculated value.*/
1996 t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownEdge)] = mass * 15 - 40;
1997 t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownOutskirt)] = mass * 9 - 15;
1998 t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownOuterSuburb)] = 0;
1999 t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownInnerSuburb)] = mass * 5 - 5;
2000 t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownCentre)] = mass * 3 + 5;
2001 }
2002}
2003
2009{
2011 uint32_t production = ScaleByCargoScale(t->cache.population >> 3, true);
2012 if (production == 0) continue;
2013
2014 auto &supplied = t->GetOrCreateCargoSupplied(cs->Index());
2015 supplied.history[LAST_MONTH].production = production;
2016 }
2017
2019 uint32_t production = ScaleByCargoScale(t->cache.population >> 4, true);
2020 if (production == 0) continue;
2021
2022 auto &supplied = t->GetOrCreateCargoSupplied(cs->Index());
2023 supplied.history[LAST_MONTH].production = production;
2024 }
2025}
2026
2027static void UpdateTownGrowthRate(Town *t);
2028static void UpdateTownGrowth(Town *t);
2029
2041static void DoCreateTown(Town *t, TileIndex tile, uint32_t townnameparts, TownSize size, bool city, TownLayout layout, bool manual)
2042{
2043 AutoRestoreBackup backup(_generating_town, true);
2044
2045 t->xy = tile;
2046 t->cache.num_houses = 0;
2047 t->time_until_rebuild = 10;
2049 t->flags = 0;
2050 t->cache.population = 0;
2052 /* Spread growth across ticks so even if there are many
2053 * similar towns they're unlikely to grow all in one tick */
2055 t->growth_rate = TownTicksToGameTicks(250);
2056 t->show_zone = false;
2057
2058 _town_kdtree.Insert(t->index);
2059
2060 /* Set the default cargo requirement for town growth */
2062 case LandscapeType::Arctic:
2064 break;
2065
2066 case LandscapeType::Tropic:
2069 break;
2070
2071 default:
2072 break;
2073 }
2074
2075 t->fund_buildings_months = 0;
2076
2077 for (uint i = 0; i != MAX_COMPANIES; i++) t->ratings[i] = RATING_INITIAL;
2078
2079 t->have_ratings = {};
2080 t->exclusivity = CompanyID::Invalid();
2081 t->exclusive_counter = 0;
2082 t->statues = {};
2083
2084 {
2086 t->townnamegrfid = tnp.grfid;
2087 t->townnametype = tnp.type;
2088 }
2089 t->townnameparts = townnameparts;
2090
2091 t->InitializeLayout(layout);
2092
2093 t->larger_town = city;
2094
2095 int x = (int)size * 16 + 3;
2096 if (size == TSZ_RANDOM) x = (Random() & 0xF) + 8;
2097 /* Don't create huge cities when founding town in-game */
2098 if (city && (!manual || _game_mode == GM_EDITOR)) x *= _settings_game.economy.initial_city_size;
2099
2100 t->cache.num_houses += x;
2102
2103 int i = x * 4;
2104 do {
2106 } while (--i);
2107
2108 t->UpdateVirtCoord();
2109 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_REBUILD);
2110
2111 t->cache.num_houses -= x;
2116}
2117
2124{
2125 /* Check if too close to the edge of map */
2126 if (DistanceFromEdge(tile) < 12) {
2127 return CommandCost(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB);
2128 }
2129
2130 /* Check distance to all other towns. */
2131 if (IsCloseToTown(tile, 20)) {
2132 return CommandCost(STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN);
2133 }
2134
2135 /* Can only build on clear flat areas, possibly with trees. */
2136 if ((!IsTileType(tile, MP_CLEAR) && !IsTileType(tile, MP_TREES)) || !IsTileFlat(tile)) {
2137 return CommandCost(STR_ERROR_SITE_UNSUITABLE);
2138 }
2139
2141}
2142
2148static bool IsUniqueTownName(const std::string &name)
2149{
2150 for (const Town *t : Town::Iterate()) {
2151 if (!t->name.empty() && t->name == name) return false;
2152 }
2153
2154 return true;
2155}
2156
2169std::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)
2170{
2172
2173 if (size >= TSZ_END) return { CMD_ERROR, 0, TownID::Invalid() };
2174 if (layout >= NUM_TLS) return { CMD_ERROR, 0, TownID::Invalid() };
2175
2176 /* Some things are allowed only in the scenario editor and for game scripts. */
2177 if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY) {
2178 if (_settings_game.economy.found_town == TF_FORBIDDEN) return { CMD_ERROR, 0, TownID::Invalid() };
2179 if (size == TSZ_LARGE) return { CMD_ERROR, 0, TownID::Invalid() };
2180 if (random_location) return { CMD_ERROR, 0, TownID::Invalid() };
2182 return { CMD_ERROR, 0, TownID::Invalid() };
2183 }
2184 } else if (_current_company == OWNER_DEITY && random_location) {
2185 /* Random parameter is not allowed for Game Scripts. */
2186 return { CMD_ERROR, 0, TownID::Invalid() };
2187 }
2188
2189 if (text.empty()) {
2190 /* If supplied name is empty, townnameparts has to generate unique automatic name */
2191 if (!VerifyTownName(townnameparts, &par)) return { CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE), 0, TownID::Invalid() };
2192 } else {
2193 /* If name is not empty, it has to be unique custom name */
2194 if (Utf8StringLength(text) >= MAX_LENGTH_TOWN_NAME_CHARS) return { CMD_ERROR, 0, TownID::Invalid() };
2195 if (!IsUniqueTownName(text)) return { CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE), 0, TownID::Invalid() };
2196 }
2197
2198 /* Allocate town struct */
2199 if (!Town::CanAllocateItem()) return { CommandCost(STR_ERROR_TOO_MANY_TOWNS), 0, TownID::Invalid() };
2200
2201 if (!random_location) {
2202 CommandCost ret = TownCanBePlacedHere(tile);
2203 if (ret.Failed()) return { ret, 0, TownID::Invalid() };
2204 }
2205
2206 static const uint8_t price_mult[][TSZ_RANDOM + 1] = {{ 15, 25, 40, 25 }, { 20, 35, 55, 35 }};
2207 /* multidimensional arrays have to have defined length of non-first dimension */
2208 static_assert(lengthof(price_mult[0]) == 4);
2209
2210 CommandCost cost(EXPENSES_OTHER, _price[PR_BUILD_TOWN]);
2211 uint8_t mult = price_mult[city][size];
2212
2213 cost.MultiplyCost(mult);
2214
2215 /* Create the town */
2216 TownID new_town = TownID::Invalid();
2217 if (flags.Test(DoCommandFlag::Execute)) {
2218 if (cost.GetCost() > GetAvailableMoneyForCommand()) {
2219 return { CommandCost(EXPENSES_OTHER), cost.GetCost(), TownID::Invalid() };
2220 }
2221
2222 Backup<bool> old_generating_world(_generating_world, true);
2224 Town *t;
2225 if (random_location) {
2226 t = CreateRandomTown(20, townnameparts, size, city, layout);
2227 } else {
2228 t = new Town(tile);
2229 DoCreateTown(t, tile, townnameparts, size, city, layout, true);
2230 }
2231
2233 old_generating_world.Restore();
2234
2235 if (t == nullptr) return { CommandCost(STR_ERROR_NO_SPACE_FOR_TOWN), 0, TownID::Invalid() };
2236
2237 new_town = t->index;
2238
2239 if (!text.empty()) {
2240 t->name = text;
2241 t->UpdateVirtCoord();
2242 }
2243
2244 if (_game_mode != GM_EDITOR) {
2245 /* 't' can't be nullptr since 'random' is false outside scenedit */
2246 assert(!random_location);
2247
2249 AddTileNewsItem(GetEncodedString(STR_NEWS_NEW_TOWN_UNSPONSORED, t->index), NewsType::IndustryOpen, tile);
2250 } else {
2251 std::string company_name = GetString(STR_COMPANY_NAME, _current_company);
2252 AddTileNewsItem(GetEncodedString(STR_NEWS_NEW_TOWN, company_name, t->index), NewsType::IndustryOpen, tile);
2253 }
2254 AI::BroadcastNewEvent(new ScriptEventTownFounded(t->index));
2255 Game::NewEvent(new ScriptEventTownFounded(t->index));
2256 }
2257 }
2258 return { cost, 0, new_town };
2259}
2260
2271{
2272 switch (layout) {
2273 case TL_2X2_GRID: return TileXY(TileX(tile) - TileX(tile) % 3, TileY(tile) - TileY(tile) % 3);
2274 case TL_3X3_GRID: return TileXY(TileX(tile) & ~3, TileY(tile) & ~3);
2275 default: return tile;
2276 }
2277}
2278
2289{
2290 switch (layout) {
2291 case TL_2X2_GRID: return TileX(tile) % 3 == 0 && TileY(tile) % 3 == 0;
2292 case TL_3X3_GRID: return TileX(tile) % 4 == 0 && TileY(tile) % 4 == 0;
2293 default: return true;
2294 }
2295}
2296
2310{
2311 for (auto coast : SpiralTileSequence(tile, 40)) {
2312 /* Find nearest land tile */
2313 if (!IsTileType(tile, MP_CLEAR)) continue;
2314
2315 TileIndex furthest = INVALID_TILE;
2316 uint max_dist = 0;
2317 for (auto test : SpiralTileSequence(coast, 10)) {
2318 if (!IsTileType(test, MP_CLEAR) || !IsTileFlat(test) || !IsTileAlignedToGrid(test, layout)) continue;
2319
2320 uint dist = GetClosestWaterDistance(test, true);
2321 if (dist > max_dist) {
2322 furthest = test;
2323 max_dist = dist;
2324 }
2325 }
2326 return furthest;
2327 }
2328
2329 /* if we get here just give up */
2330 return INVALID_TILE;
2331}
2332
2338{
2340 case LandscapeType::Temperate: return HouseZone::ClimateTemperate;
2342 case LandscapeType::Tropic: return HouseZone::ClimateSubtropic;
2343 case LandscapeType::Toyland: return HouseZone::ClimateToyland;
2344 default: NOT_REACHED();
2345 }
2346}
2347
2357static Town *CreateRandomTown(uint attempts, uint32_t townnameparts, TownSize size, bool city, TownLayout layout)
2358{
2359 assert(_game_mode == GM_EDITOR || _generating_world); // These are the preconditions for CMD_DELETE_TOWN
2360
2361 if (!Town::CanAllocateItem()) return nullptr;
2362
2363 do {
2364 /* Generate a tile index not too close from the edge */
2365 TileIndex tile = AlignTileToGrid(RandomTile(), layout);
2366
2367 /* if we tried to place the town on water, slide it over onto
2368 * the nearest likely-looking spot */
2369 if (IsTileType(tile, MP_WATER)) {
2370 tile = FindNearestGoodCoastalTownSpot(tile, layout);
2371 if (tile == INVALID_TILE) continue;
2372 }
2373
2374 /* Make sure town can be placed here */
2375 if (TownCanBePlacedHere(tile).Failed()) continue;
2376
2377 /* Allocate a town struct */
2378 Town *t = new Town(tile);
2379
2380 DoCreateTown(t, tile, townnameparts, size, city, layout, false);
2381
2382 /* if the population is still 0 at the point, then the
2383 * placement is so bad it couldn't grow at all */
2384 if (t->cache.population > 0) return t;
2385
2388 cur_company.Restore();
2389 assert(rc.Succeeded());
2390
2391 /* We already know that we can allocate a single town when
2392 * entering this function. However, we create and delete
2393 * a town which "resets" the allocation checks. As such we
2394 * need to check again when assertions are enabled. */
2395 assert(Town::CanAllocateItem());
2396 } while (--attempts != 0);
2397
2398 return nullptr;
2399}
2400
2407{
2408 static const uint8_t num_initial_towns[4] = {5, 11, 23, 46}; // very low, low, normal, high
2411 }
2412 return Map::ScaleBySize(num_initial_towns[_settings_game.difficulty.number_towns]);
2413}
2414
2422bool GenerateTowns(TownLayout layout, std::optional<uint> number)
2423{
2424 uint current_number = 0;
2425 uint total;
2426 if (number.has_value()) {
2427 total = number.value();
2428 } else if (_settings_game.difficulty.number_towns == static_cast<uint>(CUSTOM_TOWN_NUMBER_DIFFICULTY)) {
2429 total = GetDefaultTownsForMapSize();
2430 } else {
2431 total = GetDefaultTownsForMapSize() + (Random() & 7);
2432 }
2433
2434 total = std::min<uint>(TownPool::MAX_SIZE, total);
2435 uint32_t townnameparts;
2436 TownNames town_names;
2437
2439
2440 /* Pre-populate the town names list with the names of any towns already on the map */
2441 for (const Town *town : Town::Iterate()) {
2442 town_names.insert(town->GetCachedName());
2443 }
2444
2445 /* Randomised offset for city status. This means with e.g. 1-in-4 towns being cities, a map with 10 towns
2446 * may have 2 or 3 cities, instead of always 3. */
2447 uint city_random_offset = _settings_game.economy.larger_towns == 0 ? 0 : (Random() % _settings_game.economy.larger_towns);
2448
2449 /* First attempt will be made at creating the suggested number of towns.
2450 * Note that this is really a suggested value, not a required one.
2451 * We would not like the system to lock up just because the user wanted 100 cities on a 64*64 map, would we? */
2452 do {
2453 bool city = (_settings_game.economy.larger_towns != 0 && ((city_random_offset + current_number) % _settings_game.economy.larger_towns) == 0);
2455 /* Get a unique name for the town. */
2456 if (!GenerateTownName(_random, &townnameparts, &town_names)) continue;
2457 /* try 20 times to create a random-sized town for the first loop. */
2458 if (CreateRandomTown(20, townnameparts, TSZ_RANDOM, city, layout) != nullptr) current_number++; // If creation was successful, raise a flag.
2459 } while (--total);
2460
2461 town_names.clear();
2462
2463 /* Build the town k-d tree again to make sure it's well balanced */
2464 RebuildTownKdtree();
2465
2466 if (current_number != 0) return true;
2467
2468 /* If current_number is still zero at this point, it means that not a single town has been created.
2469 * So give it a last try, but now more aggressive */
2470 if (GenerateTownName(_random, &townnameparts) &&
2471 CreateRandomTown(10000, townnameparts, TSZ_RANDOM, _settings_game.economy.larger_towns != 0, layout) != nullptr) {
2472 return true;
2473 }
2474
2475 /* If there are no towns at all and we are generating new game, bail out */
2476 if (Town::GetNumItems() == 0 && _game_mode != GM_EDITOR) {
2477 ShowErrorMessage(GetEncodedString(STR_ERROR_COULD_NOT_CREATE_TOWN), {}, WL_CRITICAL);
2478 }
2479
2480 return false; // we are still without a town? we failed, simply
2481}
2482
2483
2491{
2492 uint dist = DistanceSquare(tile, t->xy);
2493
2494 if (t->fund_buildings_months != 0 && dist <= 25) return HouseZone::TownCentre;
2495
2496 HouseZone smallest = HouseZone::TownEdge;
2497 for (HouseZone i : HZ_ZONE_ALL) {
2498 if (dist < t->cache.squared_town_zone_radius[to_underlying(i)]) smallest = i;
2499 }
2500
2501 return smallest;
2502}
2503
2515static inline void ClearMakeHouseTile(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool is_protected)
2516{
2518 assert(cc.Succeeded());
2519
2520 IncreaseBuildingCount(t, type);
2521 MakeHouseTile(tile, t->index, counter, stage, type, random_bits, is_protected);
2522 if (HouseSpec::Get(type)->building_flags.Test(BuildingFlag::IsAnimated)) AddAnimatedTile(tile, false);
2523
2524 MarkTileDirtyByTile(tile);
2525}
2526
2527
2539static void MakeTownHouse(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool is_protected)
2540{
2542
2543 ClearMakeHouseTile(tile, t, counter, stage, type, random_bits, is_protected);
2544 if (size.Any(BUILDING_2_TILES_Y)) ClearMakeHouseTile(tile + TileDiffXY(0, 1), t, counter, stage, ++type, random_bits, is_protected);
2545 if (size.Any(BUILDING_2_TILES_X)) ClearMakeHouseTile(tile + TileDiffXY(1, 0), t, counter, stage, ++type, random_bits, is_protected);
2546 if (size.Any(BUILDING_HAS_4_TILES)) ClearMakeHouseTile(tile + TileDiffXY(1, 1), t, counter, stage, ++type, random_bits, is_protected);
2547
2548 ForAllStationsAroundTiles(TileArea(tile, size.Any(BUILDING_2_TILES_X) ? 2 : 1, size.Any(BUILDING_2_TILES_Y) ? 2 : 1), [t](Station *st, TileIndex) {
2549 t->stations_near.insert(st);
2550 return true;
2551 });
2552}
2553
2554
2561static inline bool CanBuildHouseHere(TileIndex tile, bool noslope)
2562{
2563 /* cannot build on these slopes... */
2564 Slope slope = GetTileSlope(tile);
2565 if ((noslope && slope != SLOPE_FLAT) || IsSteepSlope(slope)) return false;
2566
2567 /* at least one RoadTypes allow building the house here? */
2568 if (!RoadTypesAllowHouseHere(tile)) return false;
2569
2570 /* building under a bridge? */
2571 if (IsBridgeAbove(tile)) return false;
2572
2573 /* can we clear the land? */
2575}
2576
2577
2586static inline bool CheckBuildHouseSameZ(TileIndex tile, int z, bool noslope)
2587{
2588 if (!CanBuildHouseHere(tile, noslope)) return false;
2589
2590 /* if building on slopes is allowed, there will be flattening foundation (to tile max z) */
2591 if (GetTileMaxZ(tile) != z) return false;
2592
2593 return true;
2594}
2595
2596
2605static bool CheckFree2x2Area(TileIndex tile, int z, bool noslope)
2606{
2607 /* we need to check this tile too because we can be at different tile now */
2608 if (!CheckBuildHouseSameZ(tile, z, noslope)) return false;
2609
2610 for (DiagDirection d = DIAGDIR_SE; d < DIAGDIR_END; d++) {
2611 tile += TileOffsByDiagDir(d);
2612 if (!CheckBuildHouseSameZ(tile, z, noslope)) return false;
2613 }
2614
2615 return true;
2616}
2617
2618
2626static inline bool TownLayoutAllowsHouseHere(Town *t, TileIndex tile, TownExpandModes modes)
2627{
2628 if (!modes.Test(TownExpandMode::Buildings)) return false;
2629
2630 /* Allow towns everywhere when we don't build roads */
2631 if (!TownAllowedToBuildRoads(modes)) return true;
2632
2633 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
2634
2635 switch (t->layout) {
2636 case TL_2X2_GRID:
2637 if ((grid_pos.x % 3) == 0 || (grid_pos.y % 3) == 0) return false;
2638 break;
2639
2640 case TL_3X3_GRID:
2641 if ((grid_pos.x % 4) == 0 || (grid_pos.y % 4) == 0) return false;
2642 break;
2643
2644 default:
2645 break;
2646 }
2647
2648 return true;
2649}
2650
2651
2660{
2661 if (!modes.Test(TownExpandMode::Buildings)) return false;
2662
2663 /* Allow towns everywhere when we don't build roads */
2664 if (!TownAllowedToBuildRoads(modes)) return true;
2665
2666 /* Compute relative position of tile. (Positive offsets are towards north) */
2667 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
2668
2669 switch (t->layout) {
2670 case TL_2X2_GRID:
2671 grid_pos.x %= 3;
2672 grid_pos.y %= 3;
2673 if ((grid_pos.x != 2 && grid_pos.x != -1) ||
2674 (grid_pos.y != 2 && grid_pos.y != -1)) return false;
2675 break;
2676
2677 case TL_3X3_GRID:
2678 if ((grid_pos.x & 3) < 2 || (grid_pos.y & 3) < 2) return false;
2679 break;
2680
2681 default:
2682 break;
2683 }
2684
2685 return true;
2686}
2687
2688
2698static bool CheckTownBuild2House(TileIndex *tile, Town *t, int maxz, bool noslope, DiagDirection second, TownExpandModes modes)
2699{
2700 /* 'tile' is already checked in BuildTownHouse() - CanBuildHouseHere() and slope test */
2701
2702 TileIndex tile2 = *tile + TileOffsByDiagDir(second);
2703 if (TownLayoutAllowsHouseHere(t, tile2, modes) && CheckBuildHouseSameZ(tile2, maxz, noslope)) return true;
2704
2705 tile2 = *tile + TileOffsByDiagDir(ReverseDiagDir(second));
2706 if (TownLayoutAllowsHouseHere(t, tile2, modes) && CheckBuildHouseSameZ(tile2, maxz, noslope)) {
2707 *tile = tile2;
2708 return true;
2709 }
2710
2711 return false;
2712}
2713
2714
2723static bool CheckTownBuild2x2House(TileIndex *tile, Town *t, int maxz, bool noslope, TownExpandModes modes)
2724{
2725 TileIndex tile2 = *tile;
2726
2727 for (DiagDirection d = DIAGDIR_SE;; d++) { // 'd' goes through DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_END
2728 if (TownLayoutAllows2x2HouseHere(t, tile2, modes) && CheckFree2x2Area(tile2, maxz, noslope)) {
2729 *tile = tile2;
2730 return true;
2731 }
2732 if (d == DIAGDIR_END) break;
2733 tile2 += TileOffsByDiagDir(ReverseDiagDir(d)); // go clockwise
2734 }
2735
2736 return false;
2737}
2738
2749static void BuildTownHouse(Town *t, TileIndex tile, const HouseSpec *hs, HouseID house, uint8_t random_bits, bool house_completed, bool is_protected)
2750{
2751 /* build the house */
2752 t->cache.num_houses++;
2753
2754 uint8_t construction_counter = 0;
2755 uint8_t construction_stage = 0;
2756
2757 if (_generating_world || _game_mode == GM_EDITOR || house_completed) {
2758 uint32_t construction_random = Random();
2759
2760 construction_stage = TOWN_HOUSE_COMPLETED;
2761 if (_generating_world && !hs->extra_flags.Test(HouseExtraFlag::BuildingIsHistorical) && Chance16(1, 7)) construction_stage = GB(construction_random, 0, 2);
2762
2763 if (construction_stage == TOWN_HOUSE_COMPLETED) {
2765 } else {
2766 construction_counter = GB(construction_random, 2, 2);
2767 }
2768 }
2769
2770 MakeTownHouse(tile, t, construction_counter, construction_stage, house, random_bits, is_protected);
2773
2774 BuildingFlags size = hs->building_flags;
2775
2776 TriggerHouseAnimation_ConstructionStageChanged(tile, true);
2777 if (size.Any(BUILDING_2_TILES_Y)) TriggerHouseAnimation_ConstructionStageChanged(tile + TileDiffXY(0, 1), true);
2778 if (size.Any(BUILDING_2_TILES_X)) TriggerHouseAnimation_ConstructionStageChanged(tile + TileDiffXY(1, 0), true);
2779 if (size.Any(BUILDING_HAS_4_TILES)) TriggerHouseAnimation_ConstructionStageChanged(tile + TileDiffXY(1, 1), true);
2780}
2781
2789{
2790 /* forbidden building here by town layout */
2791 if (!TownLayoutAllowsHouseHere(t, tile, modes)) return false;
2792
2793 /* no house allowed at all, bail out */
2794 if (!CanBuildHouseHere(tile, false)) return false;
2795
2796 Slope slope = GetTileSlope(tile);
2797 int maxz = GetTileMaxZ(tile);
2798
2799 /* Get the town zone type of the current tile, as well as the climate.
2800 * This will allow to easily compare with the specs of the new house to build */
2801 HouseZones zones = GetTownRadiusGroup(t, tile);
2802
2804 case LandscapeType::Temperate: zones.Set(HouseZone::ClimateTemperate); break;
2805 case LandscapeType::Arctic: zones.Set(maxz > HighestSnowLine() ? HouseZone::ClimateSubarcticAboveSnow : HouseZone::ClimateSubarcticBelowSnow); break;
2806 case LandscapeType::Tropic: zones.Set(HouseZone::ClimateSubtropic); break;
2807 case LandscapeType::Toyland: zones.Set(HouseZone::ClimateToyland); break;
2808 }
2809
2810 /* bits 0-4 are used
2811 * bits 11-15 are used
2812 * bits 5-10 are not used. */
2813 static std::vector<std::pair<HouseID, uint>> probs;
2814 probs.clear();
2815
2816 uint probability_max = 0;
2817
2818 /* Generate a list of all possible houses that can be built. */
2819 for (const auto &hs : HouseSpec::Specs()) {
2820 /* Verify that the candidate house spec matches the current tile status */
2821 if (!hs.building_availability.All(zones) || !hs.enabled || hs.grf_prop.override_id != INVALID_HOUSE_ID) continue;
2822
2823 /* Don't let these counters overflow. Global counters are 32bit, there will never be that many houses. */
2824 if (hs.class_id != HOUSE_NO_CLASS) {
2825 /* id_count is always <= class_count, so it doesn't need to be checked */
2826 if (t->cache.building_counts.class_count[hs.class_id] == UINT16_MAX) continue;
2827 } else {
2828 /* If the house has no class, check id_count instead */
2829 if (t->cache.building_counts.id_count[hs.Index()] == UINT16_MAX) continue;
2830 }
2831
2832 uint cur_prob = hs.probability;
2833 probability_max += cur_prob;
2834 probs.emplace_back(hs.Index(), cur_prob);
2835 }
2836
2837 TileIndex base_tile = tile;
2838
2839 while (probability_max > 0) {
2840 /* Building a multitile building can change the location of tile.
2841 * The building would still be built partially on that tile, but
2842 * its northern tile would be elsewhere. However, if the callback
2843 * fails we would be basing further work from the changed tile.
2844 * So a next 1x1 tile building could be built on the wrong tile. */
2845 tile = base_tile;
2846
2847 uint r = RandomRange(probability_max);
2848 uint i;
2849 for (i = 0; i < probs.size(); i++) {
2850 if (probs[i].second > r) break;
2851 r -= probs[i].second;
2852 }
2853
2854 HouseID house = probs[i].first;
2855 probability_max -= probs[i].second;
2856
2857 /* remove tested house from the set */
2858 probs[i] = probs.back();
2859 probs.pop_back();
2860
2861 const HouseSpec *hs = HouseSpec::Get(house);
2862
2863 if (!_generating_world && _game_mode != GM_EDITOR && hs->extra_flags.Test(HouseExtraFlag::BuildingIsHistorical)) {
2864 continue;
2865 }
2866
2867 if (TimerGameCalendar::year < hs->min_year || TimerGameCalendar::year > hs->max_year) continue;
2868
2869 /* Special houses that there can be only one of. */
2870 uint oneof = 0;
2871
2872 if (hs->building_flags.Test(BuildingFlag::IsChurch)) {
2873 SetBit(oneof, TOWN_HAS_CHURCH);
2874 } else if (hs->building_flags.Test(BuildingFlag::IsStadium)) {
2875 SetBit(oneof, TOWN_HAS_STADIUM);
2876 }
2877
2878 if (t->flags & oneof) continue;
2879
2880 /* Make sure there is no slope? */
2881 bool noslope = hs->building_flags.Test(BuildingFlag::NotSloped);
2882 if (noslope && slope != SLOPE_FLAT) continue;
2883
2884 if (hs->building_flags.Test(BuildingFlag::Size2x2)) {
2885 if (!CheckTownBuild2x2House(&tile, t, maxz, noslope, modes)) continue;
2886 } else if (hs->building_flags.Test(BuildingFlag::Size2x1)) {
2887 if (!CheckTownBuild2House(&tile, t, maxz, noslope, DIAGDIR_SW, modes)) continue;
2888 } else if (hs->building_flags.Test(BuildingFlag::Size1x2)) {
2889 if (!CheckTownBuild2House(&tile, t, maxz, noslope, DIAGDIR_SE, modes)) continue;
2890 } else {
2891 /* 1x1 house checks are already done */
2892 }
2893
2894 uint8_t random_bits = Random();
2895
2897 uint16_t callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile, {}, true, random_bits);
2898 if (callback_res != CALLBACK_FAILED && !Convert8bitBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_ALLOW_CONSTRUCTION, callback_res)) continue;
2899 }
2900
2901 /* Special houses that there can be only one of. */
2902 t->flags |= oneof;
2903
2904 BuildTownHouse(t, tile, hs, house, random_bits, false, hs->extra_flags.Test(HouseExtraFlag::BuildingIsProtected));
2905
2906 return true;
2907 }
2908
2909 return false;
2910}
2911
2920CommandCost CmdPlaceHouse(DoCommandFlags flags, TileIndex tile, HouseID house, bool is_protected)
2921{
2922 if (_game_mode != GM_EDITOR && _settings_game.economy.place_houses == PH_FORBIDDEN) return CMD_ERROR;
2923
2924 if (Town::GetNumItems() == 0) return CommandCost(STR_ERROR_MUST_FOUND_TOWN_FIRST);
2925
2926 if (static_cast<size_t>(house) >= HouseSpec::Specs().size()) return CMD_ERROR;
2927 const HouseSpec *hs = HouseSpec::Get(house);
2928 if (!hs->enabled) return CMD_ERROR;
2929
2930 Town *t = ClosestTownFromTile(tile, UINT_MAX);
2931
2932 /* cannot build on these slopes... */
2933 Slope slope = GetTileSlope(tile);
2934 if (IsSteepSlope(slope)) return CommandCost(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
2935
2936 /* building under a bridge? */
2937 if (IsBridgeAbove(tile)) return CommandCost(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
2938
2939 /* can we clear the land? */
2941 if (!cost.Succeeded()) return cost;
2942
2943 int maxz = GetTileMaxZ(tile);
2944
2945 /* Make sure there is no slope? */
2946 bool noslope = hs->building_flags.Test(BuildingFlag::NotSloped);
2947 if (noslope && slope != SLOPE_FLAT) return CommandCost(STR_ERROR_FLAT_LAND_REQUIRED);
2948
2949 TileArea ta = tile;
2950 if (hs->building_flags.Test(BuildingFlag::Size2x2)) ta.Add(TileAddXY(tile, 1, 1));
2951 if (hs->building_flags.Test(BuildingFlag::Size2x1)) ta.Add(TileAddByDiagDir(tile, DIAGDIR_SW));
2952 if (hs->building_flags.Test(BuildingFlag::Size1x2)) ta.Add(TileAddByDiagDir(tile, DIAGDIR_SE));
2953
2954 /* Check additional tiles covered by this house. */
2955 for (const TileIndex &subtile : ta) {
2957 if (!cost.Succeeded()) return cost;
2958
2959 if (!CheckBuildHouseSameZ(subtile, maxz, noslope)) return CommandCost(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
2960 }
2961
2962 if (flags.Test(DoCommandFlag::Execute)) {
2963 bool house_completed = _settings_game.economy.place_houses == PH_ALLOWED_CONSTRUCTED;
2964 BuildTownHouse(t, tile, hs, house, Random(), house_completed, is_protected);
2965 }
2966
2967 return CommandCost();
2968}
2969
2976static void DoClearTownHouseHelper(TileIndex tile, Town *t, HouseID house)
2977{
2978 assert(IsTileType(tile, MP_HOUSE));
2979 DecreaseBuildingCount(t, house);
2980 DoClearSquare(tile);
2981
2982 DeleteNewGRFInspectWindow(GSF_HOUSES, tile.base());
2983}
2984
2993{
2994 if (house >= 3) { // house id 0,1,2 MUST be single tile houses, or this code breaks.
2995 if (HouseSpec::Get(house - 1)->building_flags.Test(BuildingFlag::Size2x1)) {
2996 house--;
2997 return TileDiffXY(-1, 0);
2998 } else if (HouseSpec::Get(house - 1)->building_flags.Any(BUILDING_2_TILES_Y)) {
2999 house--;
3000 return TileDiffXY(0, -1);
3001 } else if (HouseSpec::Get(house - 2)->building_flags.Any(BUILDING_HAS_4_TILES)) {
3002 house -= 2;
3003 return TileDiffXY(-1, 0);
3004 } else if (HouseSpec::Get(house - 3)->building_flags.Any(BUILDING_HAS_4_TILES)) {
3005 house -= 3;
3006 return TileDiffXY(-1, -1);
3007 }
3008 }
3009 return TileDiffXY(0, 0);
3010}
3011
3018{
3019 assert(IsTileType(tile, MP_HOUSE));
3020
3021 HouseID house = GetHouseType(tile);
3022
3023 /* The northernmost tile of the house is the main house. */
3024 tile += GetHouseNorthPart(house);
3025
3026 const HouseSpec *hs = HouseSpec::Get(house);
3027
3028 /* Remove population from the town if the house is finished. */
3029 if (IsHouseCompleted(tile)) {
3031 }
3032
3033 t->cache.num_houses--;
3034
3035 /* Clear flags for houses that only may exist once/town. */
3036 if (hs->building_flags.Test(BuildingFlag::IsChurch)) {
3038 } else if (hs->building_flags.Test(BuildingFlag::IsStadium)) {
3040 }
3041
3042 /* Do the actual clearing of tiles */
3043 DoClearTownHouseHelper(tile, t, house);
3044 if (hs->building_flags.Any(BUILDING_2_TILES_Y)) DoClearTownHouseHelper(tile + TileDiffXY(0, 1), t, ++house);
3045 if (hs->building_flags.Any(BUILDING_2_TILES_X)) DoClearTownHouseHelper(tile + TileDiffXY(1, 0), t, ++house);
3046 if (hs->building_flags.Any(BUILDING_HAS_4_TILES)) DoClearTownHouseHelper(tile + TileDiffXY(1, 1), t, ++house);
3047
3049
3051}
3052
3060CommandCost CmdRenameTown(DoCommandFlags flags, TownID town_id, const std::string &text)
3061{
3062 Town *t = Town::GetIfValid(town_id);
3063 if (t == nullptr) return CMD_ERROR;
3064
3065 bool reset = text.empty();
3066
3067 if (!reset) {
3069 if (!IsUniqueTownName(text)) return CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE);
3070 }
3071
3072 if (flags.Test(DoCommandFlag::Execute)) {
3073 t->cached_name.clear();
3074 if (reset) {
3075 t->name.clear();
3076 } else {
3077 t->name = text;
3078 }
3079
3080 t->UpdateVirtCoord();
3081 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_RESORT);
3082 ClearAllStationCachedNames();
3083 ClearAllIndustryCachedNames();
3085 }
3086 return CommandCost();
3087}
3088
3095{
3096 for (const CargoSpec *cs : CargoSpec::Iterate()) {
3097 if (cs->town_acceptance_effect == effect) return cs;
3098 }
3099 return nullptr;
3100}
3101
3111{
3112 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3113
3114 if (tae < TAE_BEGIN || tae >= TAE_END) return CMD_ERROR;
3115
3116 Town *t = Town::GetIfValid(town_id);
3117 if (t == nullptr) return CMD_ERROR;
3118
3119 /* Validate if there is a cargo which is the requested TownEffect */
3121 if (cargo == nullptr) return CMD_ERROR;
3122
3123 if (flags.Test(DoCommandFlag::Execute)) {
3124 t->goal[tae] = goal;
3127 }
3128
3129 return CommandCost();
3130}
3131
3140{
3141 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3142 Town *t = Town::GetIfValid(town_id);
3143 if (t == nullptr) return CMD_ERROR;
3144
3145 if (flags.Test(DoCommandFlag::Execute)) {
3146 t->text.clear();
3147 if (!text.empty()) t->text = text;
3149 }
3150
3151 return CommandCost();
3152}
3153
3161CommandCost CmdTownGrowthRate(DoCommandFlags flags, TownID town_id, uint16_t growth_rate)
3162{
3163 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3164
3165 Town *t = Town::GetIfValid(town_id);
3166 if (t == nullptr) return CMD_ERROR;
3167
3168 if (flags.Test(DoCommandFlag::Execute)) {
3169 if (growth_rate == 0) {
3170 /* Just clear the flag, UpdateTownGrowth will determine a proper growth rate */
3172 } else {
3173 uint old_rate = t->growth_rate;
3174 if (t->grow_counter >= old_rate) {
3175 /* This also catches old_rate == 0 */
3176 t->grow_counter = growth_rate;
3177 } else {
3178 /* Scale grow_counter, so half finished houses stay half finished */
3179 t->grow_counter = t->grow_counter * growth_rate / old_rate;
3180 }
3181 t->growth_rate = growth_rate;
3183 }
3186 }
3187
3188 return CommandCost();
3189}
3190
3199CommandCost CmdTownRating(DoCommandFlags flags, TownID town_id, CompanyID company_id, int16_t rating)
3200{
3201 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3202
3203 Town *t = Town::GetIfValid(town_id);
3204 if (t == nullptr) return CMD_ERROR;
3205
3206 if (!Company::IsValidID(company_id)) return CMD_ERROR;
3207
3208 int16_t new_rating = Clamp(rating, RATING_MINIMUM, RATING_MAXIMUM);
3209 if (flags.Test(DoCommandFlag::Execute)) {
3210 t->ratings[company_id] = new_rating;
3212 }
3213
3214 return CommandCost();
3215}
3216
3224CommandCost CmdExpandTown(DoCommandFlags flags, TownID town_id, uint32_t grow_amount, TownExpandModes modes)
3225{
3226 if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY) return CMD_ERROR;
3227 if (modes.None()) return CMD_ERROR;
3228 Town *t = Town::GetIfValid(town_id);
3229 if (t == nullptr) return CMD_ERROR;
3230
3231 if (flags.Test(DoCommandFlag::Execute)) {
3232 /* The more houses, the faster we grow */
3233 if (grow_amount == 0) {
3234 uint amount = RandomRange(ClampTo<uint16_t>(t->cache.num_houses / 10)) + 3;
3235 t->cache.num_houses += amount;
3237
3238 uint n = amount * 10;
3239 do GrowTown(t, modes); while (--n);
3240
3241 t->cache.num_houses -= amount;
3242 } else {
3243 for (; grow_amount > 0; grow_amount--) {
3244 /* Try several times to grow, as we are really suppose to grow */
3245 for (uint i = 0; i < 25; i++) if (GrowTown(t, modes)) break;
3246 }
3247 }
3249
3251 }
3252
3253 return CommandCost();
3254}
3255
3263{
3264 if (_game_mode != GM_EDITOR && !_generating_world) return CMD_ERROR;
3265 Town *t = Town::GetIfValid(town_id);
3266 if (t == nullptr) return CMD_ERROR;
3267
3268 /* Stations refer to towns. */
3269 for (const Station *st : Station::Iterate()) {
3270 if (st->town == t) {
3271 /* Non-oil rig stations are always a problem. */
3272 if (!st->facilities.Test(StationFacility::Airport) || st->airport.type != AT_OILRIG) return CMD_ERROR;
3273 /* We can only automatically delete oil rigs *if* there's no vehicle on them. */
3274 CommandCost ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, st->airport.tile);
3275 if (ret.Failed()) return ret;
3276 }
3277 }
3278
3279 /* Waypoints refer to towns. */
3280 for (const Waypoint *wp : Waypoint::Iterate()) {
3281 if (wp->town == t) return CMD_ERROR;
3282 }
3283
3284 /* Depots refer to towns. */
3285 for (const Depot *d : Depot::Iterate()) {
3286 if (d->town == t) return CMD_ERROR;
3287 }
3288
3289 /* Check all tiles for town ownership. First check for bridge tiles, as
3290 * these do not directly have an owner so we need to check adjacent
3291 * tiles. This won't work correctly in the same loop if the adjacent
3292 * tile was already deleted earlier in the loop. */
3293 for (const auto current_tile : Map::Iterate()) {
3294 if (IsTileType(current_tile, MP_TUNNELBRIDGE) && TestTownOwnsBridge(current_tile, t)) {
3295 CommandCost ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, current_tile);
3296 if (ret.Failed()) return ret;
3297 }
3298 }
3299
3300 /* Check all remaining tiles for town ownership. */
3301 for (const auto current_tile : Map::Iterate()) {
3302 bool try_clear = false;
3303 switch (GetTileType(current_tile)) {
3304 case MP_ROAD:
3305 try_clear = HasTownOwnedRoad(current_tile) && GetTownIndex(current_tile) == t->index;
3306 break;
3307
3308 case MP_HOUSE:
3309 try_clear = GetTownIndex(current_tile) == t->index;
3310 break;
3311
3312 case MP_INDUSTRY:
3313 try_clear = Industry::GetByTile(current_tile)->town == t;
3314 break;
3315
3316 case MP_OBJECT:
3317 if (Town::GetNumItems() == 1) {
3318 /* No towns will be left, remove it! */
3319 try_clear = true;
3320 } else {
3321 Object *o = Object::GetByTile(current_tile);
3322 if (o->town == t) {
3323 if (o->type == OBJECT_STATUE) {
3324 /* Statue... always remove. */
3325 try_clear = true;
3326 } else {
3327 /* Tell to find a new town. */
3328 if (flags.Test(DoCommandFlag::Execute)) o->town = nullptr;
3329 }
3330 }
3331 }
3332 break;
3333
3334 default:
3335 break;
3336 }
3337 if (try_clear) {
3338 CommandCost ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, current_tile);
3339 if (ret.Failed()) return ret;
3340 }
3341 }
3342
3343 /* The town destructor will delete the other things related to the town. */
3344 if (flags.Test(DoCommandFlag::Execute)) {
3345 _town_kdtree.Remove(t->index);
3346 if (t->cache.sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeTown(t->index));
3347 delete t;
3348 }
3349
3350 return CommandCost();
3351}
3352
3359{
3364 static const uint8_t town_action_costs[] = {
3365 2, 4, 9, 35, 48, 53, 117, 175
3366 };
3367 static_assert(std::size(town_action_costs) == to_underlying(TownAction::End));
3368
3369 assert(to_underlying(action) < std::size(town_action_costs));
3370 return town_action_costs[to_underlying(action)];
3371}
3372
3380{
3381 if (flags.Test(DoCommandFlag::Execute)) {
3382 ModifyStationRatingAround(t->xy, _current_company, 0x40, 10);
3383 }
3384 return CommandCost();
3385}
3386
3394{
3395 if (flags.Test(DoCommandFlag::Execute)) {
3396 ModifyStationRatingAround(t->xy, _current_company, 0x70, 15);
3397 }
3398 return CommandCost();
3399}
3400
3408{
3409 if (flags.Test(DoCommandFlag::Execute)) {
3410 ModifyStationRatingAround(t->xy, _current_company, 0xA0, 20);
3411 }
3412 return CommandCost();
3413}
3414
3422{
3423 /* Check if the company is allowed to fund new roads. */
3425
3426 if (flags.Test(DoCommandFlag::Execute)) {
3427 t->road_build_months = 6;
3428
3429 std::string company_name = GetString(STR_COMPANY_NAME, _current_company);
3430
3432 GetEncodedString(TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_ROAD_REBUILDING_MINUTES : STR_NEWS_ROAD_REBUILDING_MONTHS, t->index, company_name),
3434 AI::BroadcastNewEvent(new ScriptEventRoadReconstruction(_current_company, t->index));
3435 Game::NewEvent(new ScriptEventRoadReconstruction(_current_company, t->index));
3436 }
3437 return CommandCost();
3438}
3439
3445static bool CheckClearTile(TileIndex tile)
3446{
3449 cur_company.Restore();
3450 return r.Succeeded();
3451}
3452
3461{
3462 if (!Object::CanAllocateItem()) return CommandCost(STR_ERROR_TOO_MANY_OBJECTS);
3463
3464 static const int STATUE_NUMBER_INNER_TILES = 25; // Number of tiles int the center of the city, where we try to protect houses.
3465
3466 TileIndex best_position = INVALID_TILE;
3467 uint tile_count = 0;
3468 for (auto tile : SpiralTileSequence(t->xy, 9)) {
3469 tile_count++;
3470
3471 /* Statues can be build on slopes, just like houses. Only the steep slopes is a no go. */
3472 if (IsSteepSlope(GetTileSlope(tile))) continue;
3473 /* Don't build statues under bridges. */
3474 if (IsBridgeAbove(tile)) continue;
3475
3476 /* A clear-able open space is always preferred. */
3477 if ((IsTileType(tile, MP_CLEAR) || IsTileType(tile, MP_TREES)) && CheckClearTile(tile)) {
3478 best_position = tile;
3479 break;
3480 }
3481
3482 bool house = IsTileType(tile, MP_HOUSE);
3483
3484 /* Searching inside the inner circle. */
3485 if (tile_count <= STATUE_NUMBER_INNER_TILES) {
3486 /* Save first house in inner circle. */
3487 if (house && best_position == INVALID_TILE && CheckClearTile(tile)) {
3488 best_position = tile;
3489 }
3490
3491 /* If we have reached the end of the inner circle, and have a saved house, terminate the search. */
3492 if (tile_count == STATUE_NUMBER_INNER_TILES && best_position != INVALID_TILE) break;
3493 }
3494
3495 /* Searching outside the circle, just pick the first possible spot. */
3496 if (!house || !CheckClearTile(tile)) continue;
3497 best_position = tile;
3498 break;
3499 }
3500 if (best_position == INVALID_TILE) return CommandCost(STR_ERROR_STATUE_NO_SUITABLE_PLACE);
3501
3502 if (flags.Test(DoCommandFlag::Execute)) {
3505 cur_company.Restore();
3506 BuildObject(OBJECT_STATUE, best_position, _current_company, t);
3507 t->statues.Set(_current_company); // Once found and built, "inform" the Town.
3508 MarkTileDirtyByTile(best_position);
3509 }
3510 return CommandCost();
3511}
3512
3520{
3521 /* Check if it's allowed to buy the rights */
3523
3524 if (flags.Test(DoCommandFlag::Execute)) {
3525 /* And grow for 3 months */
3526 t->fund_buildings_months = 3;
3527
3528 /* Enable growth (also checking GameScript's opinion) */
3530
3531 /* Build a new house, but add a small delay to make sure
3532 * that spamming funding doesn't let town grow any faster
3533 * than 1 house per 2 * TOWN_GROWTH_TICKS ticks.
3534 * Also emulate original behaviour when town was only growing in
3535 * TOWN_GROWTH_TICKS intervals, to make sure that it's not too
3536 * tick-perfect and gives player some time window where they can
3537 * spam funding with the exact same efficiency.
3538 */
3540
3542 }
3543 return CommandCost();
3544}
3545
3553{
3554 /* Check if it's allowed to buy the rights */
3556 if (t->exclusivity != CompanyID::Invalid()) return CMD_ERROR;
3557
3558 if (flags.Test(DoCommandFlag::Execute)) {
3559 t->exclusive_counter = 12;
3561
3562 ModifyStationRatingAround(t->xy, _current_company, 130, 17);
3563
3565
3566 /* Spawn news message */
3567 auto cni = std::make_unique<CompanyNewsInformation>(STR_NEWS_EXCLUSIVE_RIGHTS_TITLE, Company::Get(_current_company));
3568 EncodedString message = GetEncodedString(TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MINUTES : STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MONTHS, t->index, cni->company_name);
3569 AddNewsItem(std::move(message),
3570 NewsType::General, NewsStyle::Company, {}, t->index, {}, std::move(cni));
3571 AI::BroadcastNewEvent(new ScriptEventExclusiveTransportRights(_current_company, t->index));
3572 Game::NewEvent(new ScriptEventExclusiveTransportRights(_current_company, t->index));
3573 }
3574 return CommandCost();
3575}
3576
3584{
3585 if (flags.Test(DoCommandFlag::Execute)) {
3586 if (Chance16(1, 14)) {
3587 /* set as unwanted for 6 months */
3588 t->unwanted[_current_company] = 6;
3589
3590 /* set all close by station ratings to 0 */
3591 for (Station *st : Station::Iterate()) {
3592 if (st->town == t && st->owner == _current_company) {
3593 for (GoodsEntry &ge : st->goods) ge.rating = 0;
3594 }
3595 }
3596
3597 /* only show error message to the executing player. All errors are handled command.c
3598 * but this is special, because it can only 'fail' on a DoCommandFlag::Execute */
3599 if (IsLocalCompany()) ShowErrorMessage(GetEncodedString(STR_ERROR_BRIBE_FAILED), {}, WL_INFO);
3600
3601 /* decrease by a lot!
3602 * ChangeTownRating is only for stuff in demolishing. Bribe failure should
3603 * be independent of any cheat settings
3604 */
3605 if (t->ratings[_current_company] > RATING_BRIBE_DOWN_TO) {
3606 t->ratings[_current_company] = RATING_BRIBE_DOWN_TO;
3608 }
3609 } else {
3610 ChangeTownRating(t, RATING_BRIBE_UP_STEP, RATING_BRIBE_MAXIMUM, DoCommandFlag::Execute);
3611 if (t->exclusivity != _current_company && t->exclusivity != CompanyID::Invalid()) {
3612 t->exclusivity = CompanyID::Invalid();
3613 t->exclusive_counter = 0;
3614 }
3615 }
3616 }
3617 return CommandCost();
3618}
3619
3620typedef CommandCost TownActionProc(Town *t, DoCommandFlags flags);
3621static TownActionProc * const _town_action_proc[] = {
3630};
3631static_assert(std::size(_town_action_proc) == to_underlying(TownAction::End));
3632
3640{
3641 TownActions buttons{};
3642
3643 /* Spectators and unwanted have no options */
3644 if (cid != COMPANY_SPECTATOR && !(_settings_game.economy.bribe && t->unwanted[cid])) {
3645
3646 /* Actions worth more than this are not able to be performed */
3647 Money avail = GetAvailableMoney(cid);
3648
3649 /* Check the action bits for validity and
3650 * if they are valid add them */
3651 for (TownAction cur = {}; cur != TownAction::End; ++cur) {
3652
3653 /* Is the company prohibited from bribing ? */
3654 if (cur == TownAction::Bribe) {
3655 /* Company can't bribe if setting is disabled */
3656 if (!_settings_game.economy.bribe) continue;
3657 /* Company can bribe if another company has exclusive transport rights,
3658 * or its standing with the town is less than outstanding. */
3659 if (t->ratings[cid] >= RATING_BRIBE_MAXIMUM) {
3660 if (t->exclusivity == _current_company) continue;
3661 if (t->exclusive_counter == 0) continue;
3662 }
3663 }
3664
3665 /* Is the company not able to buy exclusive rights ? */
3667
3668 /* Is the company not able to fund buildings ? */
3670
3671 /* Is the company not able to fund local road reconstruction? */
3673
3674 /* Is the company not able to build a statue ? */
3675 if (cur == TownAction::BuildStatue && t->statues.Test(cid)) continue;
3676
3677 if (avail >= GetTownActionCost(cur) * _price[PR_TOWN_ACTION] >> 8) {
3678 buttons.Set(cur);
3679 }
3680 }
3681 }
3682
3683 return buttons;
3684}
3685
3696{
3697 Town *t = Town::GetIfValid(town_id);
3698 if (t == nullptr || to_underlying(action) >= std::size(_town_action_proc)) return CMD_ERROR;
3699
3700 if (!GetMaskOfTownActions(_current_company, t).Test(action)) return CMD_ERROR;
3701
3702 CommandCost cost(EXPENSES_OTHER, _price[PR_TOWN_ACTION] * GetTownActionCost(action) >> 8);
3703
3704 CommandCost ret = _town_action_proc[to_underlying(action)](t, flags);
3705 if (ret.Failed()) return ret;
3706
3707 if (flags.Test(DoCommandFlag::Execute)) {
3709 }
3710
3711 return cost;
3712}
3713
3714template <typename Func>
3715static void ForAllStationsNearTown(Town *t, Func func)
3716{
3717 /* Ideally the search radius should be close to the actual town zone 0 radius.
3718 * The true radius is not stored or calculated anywhere, only the squared radius. */
3719 /* The efficiency of this search might be improved for large towns and many stations on the map,
3720 * by using an integer square root approximation giving a value not less than the true square root. */
3721 uint search_radius = t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownEdge)] / 2;
3722 ForAllStationsRadius(t->xy, search_radius, [&](const Station * st) {
3723 if (DistanceSquare(st->xy, t->xy) <= t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownEdge)]) {
3724 func(st);
3725 }
3726 });
3727}
3728
3733static void UpdateTownRating(Town *t)
3734{
3735 /* Increase company ratings if they're low */
3736 for (const Company *c : Company::Iterate()) {
3737 if (t->ratings[c->index] < RATING_GROWTH_MAXIMUM) {
3738 t->ratings[c->index] = std::min((int)RATING_GROWTH_MAXIMUM, t->ratings[c->index] + RATING_GROWTH_UP_STEP);
3739 }
3740 }
3741
3742 ForAllStationsNearTown(t, [&](const Station *st) {
3743 if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
3744 if (Company::IsValidID(st->owner)) {
3745 int new_rating = t->ratings[st->owner] + RATING_STATION_UP_STEP;
3746 t->ratings[st->owner] = std::min<int>(new_rating, INT16_MAX); // do not let it overflow
3747 }
3748 } else {
3749 if (Company::IsValidID(st->owner)) {
3750 int new_rating = t->ratings[st->owner] + RATING_STATION_DOWN_STEP;
3751 t->ratings[st->owner] = std::max(new_rating, INT16_MIN);
3752 }
3753 }
3754 });
3755
3756 /* clamp all ratings to valid values */
3757 for (uint i = 0; i < MAX_COMPANIES; i++) {
3758 t->ratings[i] = Clamp(t->ratings[i], RATING_MINIMUM, RATING_MAXIMUM);
3759 }
3760
3762}
3763
3764
3771static void UpdateTownGrowCounter(Town *t, uint16_t prev_growth_rate)
3772{
3773 if (t->growth_rate == TOWN_GROWTH_RATE_NONE) return;
3774 if (prev_growth_rate == TOWN_GROWTH_RATE_NONE) {
3775 t->grow_counter = std::min<uint16_t>(t->growth_rate, t->grow_counter);
3776 return;
3777 }
3778 t->grow_counter = RoundDivSU((uint32_t)t->grow_counter * (t->growth_rate + 1), prev_growth_rate + 1);
3779}
3780
3787{
3788 int n = 0;
3789 ForAllStationsNearTown(t, [&](const Station * st) {
3790 if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
3791 n++;
3792 }
3793 });
3794 return n;
3795}
3796
3804{
3810 static const uint16_t _grow_count_values[2][6] = {
3811 { 120, 120, 120, 100, 80, 60 }, // Fund new buildings has been activated
3812 { 320, 420, 300, 220, 160, 100 } // Normal values
3813 };
3814
3815 int n = CountActiveStations(t);
3816 uint16_t m = _grow_count_values[t->fund_buildings_months != 0 ? 0 : 1][std::min(n, 5)];
3817
3818 uint growth_multiplier = _settings_game.economy.town_growth_rate != 0 ? _settings_game.economy.town_growth_rate - 1 : 1;
3819
3820 m >>= growth_multiplier;
3821 if (t->larger_town) m /= 2;
3822
3823 return TownTicksToGameTicks(m / (t->cache.num_houses / 50 + 1));
3824}
3825
3831{
3832 if (HasBit(t->flags, TOWN_CUSTOM_GROWTH)) return;
3833 uint old_rate = t->growth_rate;
3835 UpdateTownGrowCounter(t, old_rate);
3837}
3838
3843static void UpdateTownGrowth(Town *t)
3844{
3846
3849
3851
3852 if (t->fund_buildings_months == 0) {
3853 /* Check if all goals are reached for this town to grow (given we are not funding it) */
3854 for (int i = TAE_BEGIN; i < TAE_END; i++) {
3855 switch (t->goal[i]) {
3856 case TOWN_GROWTH_WINTER:
3857 if (TileHeight(t->xy) >= GetSnowLine() && t->received[i].old_act == 0 && t->cache.population > 90) return;
3858 break;
3859 case TOWN_GROWTH_DESERT:
3860 if (GetTropicZone(t->xy) == TROPICZONE_DESERT && t->received[i].old_act == 0 && t->cache.population > 60) return;
3861 break;
3862 default:
3863 if (t->goal[i] > t->received[i].old_act) return;
3864 break;
3865 }
3866 }
3867 }
3868
3869 if (HasBit(t->flags, TOWN_CUSTOM_GROWTH)) {
3872 return;
3873 }
3874
3875 if (t->fund_buildings_months == 0 && CountActiveStations(t) == 0 && !Chance16(1, 12)) return;
3876
3879}
3880
3888{
3889 /* The required rating is hardcoded to RATING_VERYPOOR (see below), not the authority attitude setting, so we can bail out like this. */
3890 if (_settings_game.difficulty.town_council_tolerance == TOWN_COUNCIL_PERMISSIVE) return CommandCost();
3891
3893
3895 if (t == nullptr) return CommandCost();
3896
3897 if (t->ratings[_current_company] > RATING_VERYPOOR) return CommandCost();
3898
3899 return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index);
3900}
3901
3911{
3912 if (Town::GetNumItems() == 0) return nullptr;
3913
3914 TownID tid = _town_kdtree.FindNearest(TileX(tile), TileY(tile));
3915 Town *town = Town::Get(tid);
3916 if (DistanceManhattan(tile, town->xy) < threshold) return town;
3917 return nullptr;
3918}
3919
3928Town *ClosestTownFromTile(TileIndex tile, uint threshold)
3929{
3930 switch (GetTileType(tile)) {
3931 case MP_ROAD:
3932 if (IsRoadDepot(tile)) return CalcClosestTownFromTile(tile, threshold);
3933
3934 if (!HasTownOwnedRoad(tile)) {
3935 TownID tid = GetTownIndex(tile);
3936
3937 if (tid == TownID::Invalid()) {
3938 /* in the case we are generating "many random towns", this value may be TownID::Invalid() */
3939 if (_generating_world) return CalcClosestTownFromTile(tile, threshold);
3940 assert(Town::GetNumItems() == 0);
3941 return nullptr;
3942 }
3943
3944 assert(Town::IsValidID(tid));
3945 Town *town = Town::Get(tid);
3946
3947 if (DistanceManhattan(tile, town->xy) >= threshold) town = nullptr;
3948
3949 return town;
3950 }
3951 [[fallthrough]];
3952
3953 case MP_HOUSE:
3954 return Town::GetByTile(tile);
3955
3956 default:
3957 return CalcClosestTownFromTile(tile, threshold);
3958 }
3959}
3960
3961static bool _town_rating_test = false;
3962static std::map<const Town *, int> _town_test_ratings;
3963
3970{
3971 static int ref_count = 0; // Number of times test-mode is switched on.
3972 if (mode) {
3973 if (ref_count == 0) {
3974 _town_test_ratings.clear();
3975 }
3976 ref_count++;
3977 } else {
3978 assert(ref_count > 0);
3979 ref_count--;
3980 }
3981 _town_rating_test = !(ref_count == 0);
3982}
3983
3989static int GetRating(const Town *t)
3990{
3991 if (_town_rating_test) {
3992 auto it = _town_test_ratings.find(t);
3993 if (it != _town_test_ratings.end()) {
3994 return it->second;
3995 }
3996 }
3997 return t->ratings[_current_company];
3998}
3999
4007void ChangeTownRating(Town *t, int add, int max, DoCommandFlags flags)
4008{
4009 /* if magic_bulldozer cheat is active, town doesn't penalize for removing stuff */
4010 if (t == nullptr || flags.Test(DoCommandFlag::NoModifyTownRating) ||
4012 (_cheats.magic_bulldozer.value && add < 0)) {
4013 return;
4014 }
4015
4016 int rating = GetRating(t);
4017 if (add < 0) {
4018 if (rating > max) {
4019 rating += add;
4020 if (rating < max) rating = max;
4021 }
4022 } else {
4023 if (rating < max) {
4024 rating += add;
4025 if (rating > max) rating = max;
4026 }
4027 }
4028 if (_town_rating_test) {
4029 _town_test_ratings[t] = rating;
4030 } else {
4032 t->ratings[_current_company] = rating;
4034 }
4035}
4036
4045{
4046 /* if magic_bulldozer cheat is active, town doesn't restrict your destructive actions */
4047 if (t == nullptr || !Company::IsValidID(_current_company) ||
4049 return CommandCost();
4050 }
4051
4052 /* minimum rating needed to be allowed to remove stuff */
4053 static const int needed_rating[][TOWN_RATING_CHECK_TYPE_COUNT] = {
4054 /* ROAD_REMOVE, TUNNELBRIDGE_REMOVE */
4059 };
4060
4061 /* check if you're allowed to remove the road/bridge/tunnel
4062 * owned by a town no removal if rating is lower than ... depends now on
4063 * difficulty setting. Minimum town rating selected by difficulty level
4064 */
4065 int needed = needed_rating[_settings_game.difficulty.town_council_tolerance][type];
4066
4067 if (GetRating(t) < needed) {
4068 return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index);
4069 }
4070
4071 return CommandCost();
4072}
4073
4074template <>
4075Town::SuppliedHistory SumHistory(std::span<const Town::SuppliedHistory> history)
4076{
4077 uint32_t production = std::accumulate(std::begin(history), std::end(history), 0, [](uint32_t r, const auto &s) { return r + s.production; });
4078 uint32_t transported = std::accumulate(std::begin(history), std::end(history), 0, [](uint32_t r, const auto &s) { return r + s.transported; });
4079 auto count = std::size(history);
4080 return {.production = ClampTo<uint16_t>(production / count), .transported = ClampTo<uint16_t>(transported / count)};
4081}
4082
4083static const IntervalTimer<TimerGameEconomy> _economy_towns_monthly({TimerGameEconomy::MONTH, TimerGameEconomy::Priority::TOWN}, [](auto)
4084{
4085 for (Town *t : Town::Iterate()) {
4086 /* Check for active town actions and decrement their counters. */
4087 if (t->road_build_months != 0) t->road_build_months--;
4089
4090 if (t->exclusive_counter != 0) {
4091 if (--t->exclusive_counter == 0) t->exclusivity = CompanyID::Invalid();
4092 }
4093
4094 /* Check for active failed bribe cooloff periods and decrement them. */
4095 for (const Company *c : Company::Iterate()) {
4096 if (t->unwanted[c->index] > 0) t->unwanted[c->index]--;
4097 }
4098
4100
4101 /* Update cargo statistics. */
4102 for (auto &s : t->supplied) RotateHistory(s.history, t->valid_history, HISTORY_YEAR, TimerGameEconomy::month);
4103 for (auto &received : t->received) received.NewMonth();
4104
4107
4109 }
4110});
4111
4112static const IntervalTimer<TimerGameEconomy> _economy_towns_yearly({TimerGameEconomy::YEAR, TimerGameEconomy::Priority::TOWN}, [](auto)
4113{
4114 /* Increment house ages */
4115 for (const auto t : Map::Iterate()) {
4116 if (!IsTileType(t, MP_HOUSE)) continue;
4118 }
4119});
4120
4121static CommandCost TerraformTile_Town(TileIndex tile, DoCommandFlags flags, int z_new, Slope tileh_new)
4122{
4123 if (AutoslopeEnabled()) {
4124 HouseID house = GetHouseType(tile);
4125 GetHouseNorthPart(house); // modifies house to the ID of the north tile
4126 const HouseSpec *hs = HouseSpec::Get(house);
4127
4128 /* Here we differ from TTDP by checking BuildingFlag::NotSloped */
4129 if (!hs->building_flags.Test(BuildingFlag::NotSloped) && !IsSteepSlope(tileh_new) &&
4130 (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) {
4131 bool allow_terraform = true;
4132
4133 /* Call the autosloping callback per tile, not for the whole building at once. */
4134 house = GetHouseType(tile);
4135 hs = HouseSpec::Get(house);
4137 /* If the callback fails, allow autoslope. */
4138 uint16_t res = GetHouseCallback(CBID_HOUSE_AUTOSLOPE, 0, 0, house, Town::GetByTile(tile), tile);
4139 if (res != CALLBACK_FAILED && ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_AUTOSLOPE, res)) allow_terraform = false;
4140 }
4141
4142 if (allow_terraform) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
4143 }
4144 }
4145
4146 return Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
4147}
4148
4150extern const TileTypeProcs _tile_type_town_procs = {
4151 DrawTile_Town, // draw_tile_proc
4152 GetSlopePixelZ_Town, // get_slope_z_proc
4153 ClearTile_Town, // clear_tile_proc
4154 AddAcceptedCargo_Town, // add_accepted_cargo_proc
4155 GetTileDesc_Town, // get_tile_desc_proc
4156 GetTileTrackStatus_Town, // get_tile_track_status_proc
4157 nullptr, // click_tile_proc
4158 AnimateTile_Town, // animate_tile_proc
4159 TileLoop_Town, // tile_loop_proc
4160 ChangeTileOwner_Town, // change_tile_owner_proc
4161 AddProducedCargo_Town, // add_produced_cargo_proc
4162 nullptr, // vehicle_enter_tile_proc
4163 GetFoundation_Town, // get_foundation_proc
4164 TerraformTile_Town, // terraform_tile_proc
4165};
4166
4167std::span<const DrawBuildingsTileStruct> GetTownDrawTileData()
4168{
4169 return _town_draw_tile_data;
4170}
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.
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
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.
debug_inline 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 ClrBit(T &x, const uint8_t y)
Clears a bit in a variable.
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:23
bool IsValidCargoType(CargoType cargo)
Test whether cargo type is not INVALID_CARGO.
Definition cargo_type.h:106
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 All(const Timpl &other) const
Test if all of the values are set.
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 & 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.
Enum-as-bit-set wrapper.
static void NewEvent(class ScriptEvent *event)
Queue a new event for a Game Script.
An interval timer will fire every interval, and will continue to fire until it is deleted.
Definition timer.h:76
K-dimensional tree, specialised for 2-dimensional space.
Definition kdtree.hpp:33
void Build(It begin, It end)
Clear and rebuild the tree from a new sequence of elements,.
Definition kdtree.hpp:360
size_t Count() const
Get number of elements stored in tree.
Definition kdtree.hpp:428
void Insert(const T &element)
Insert a single element in the tree.
Definition kdtree.hpp:396
void Remove(const T &element)
Remove a single element from the tree, if it exists.
Definition kdtree.hpp:415
T FindNearest(CoordT x, CoordT y) const
Find the element closest to given coordinate, in Manhattan distance.
Definition kdtree.hpp:439
RoadTypeLabel label
Unique 32 bit road type identifier.
Definition road.h:138
TimerGameCalendar::Date introduction_date
Introduction date.
Definition road.h:157
RoadTypeFlags flags
Bit mask of road type flags.
Definition road.h:118
uint16_t max_speed
Maximum speed for vehicles travelling on this road type.
Definition road.h:133
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 Date date
Current date in days (day counter).
static Year year
Current year, starting at 0.
static constexpr TimerGame< struct Calendar >::Date MAX_DATE
The date of the last day of the max year.
Timer that is increased every 27ms, and counts towards economy time units, expressed in days / months...
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.
CommandCost CommandCostWithParam(StringID str, uint64_t value)
Return an error status, with string and parameter.
Definition command.cpp:417
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.
@ Execute
execute the given command
@ NoModifyTownRating
do not change town rating
@ NoTestTownRating
town rating does not disallow you from building
@ NoWater
don't allow building on water
@ Auto
don't allow building on structures
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.
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.
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23)
Definition enum_type.hpp:17
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:66
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:1543
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
@ BuildingIsProtected
towns and AI will not remove this house, while human players will be able to
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
Definition house.h:55
@ ClimateSubarcticAboveSnow
Building can appear in sub-arctic climate above the snow line.
@ ClimateSubarcticBelowSnow
Building can appear in sub-arctic climate below the snow line.
@ ClimateTemperate
Building can appear in temperate climate.
@ ClimateToyland
Building can appear in toyland climate.
@ ClimateSubtropic
Building can appear in subtropical climate.
uint16_t HouseID
OpenTTD ID of house types.
Definition house_type.h:13
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,...
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:95
Command definitions related to landscape (slopes etc.).
@ Random
Randomise borders.
uint DistanceSquare(TileIndex t0, TileIndex t1)
Gets the 'Square' distance between the two given tiles.
Definition map.cpp:159
uint DistanceFromEdge(TileIndex tile)
Param the minimum distance to an edge.
Definition map.cpp:202
uint DistanceManhattan(TileIndex t0, TileIndex t1)
Gets the Manhattan distance between the two given tiles.
Definition map.cpp:142
uint GetClosestWaterDistance(TileIndex tile, bool water)
Finds the distance for the closest tile with water/land given a tile.
Definition map.cpp:236
TileIndex TileAddXY(TileIndex tile, int x, int y)
Adds a given offset to a tile.
Definition map_func.h:469
TileIndex TileAddByDir(TileIndex tile, Direction dir)
Adds a Direction to a tile.
Definition map_func.h:598
static debug_inline TileIndex TileXY(uint x, uint y)
Returns the TileIndex of a coordinate.
Definition map_func.h:372
TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc)
Return the offset between two tiles from a TileIndexDiffC struct.
Definition map_func.h:439
TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir)
Adds a DiagDir to a tile.
Definition map_func.h:610
TileIndexDiff TileDiffXY(int x, int y)
Calculates an offset for the given coordinate(-offset).
Definition map_func.h:388
constexpr TileIndex TileAdd(TileIndex tile, TileIndexDiff offset)
Adds a given offset to a tile.
Definition map_func.h:456
#define RandomTile()
Get a valid random tile.
Definition map_func.h:651
static debug_inline uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition map_func.h:424
static debug_inline uint TileX(TileIndex tile)
Get the X component of a tile.
Definition map_func.h:414
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition map_func.h:569
TileIndexDiffC TileIndexToTileIndexDiffC(TileIndex tile_a, TileIndex tile_b)
Returns the diff between two tiles.
Definition map_func.h:530
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
@ GSF_FAKE_TOWNS
Fake town GrfSpecFeature for NewGRF debugging (parent scope)
Definition newgrf.h:95
@ 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.
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:902
@ General
General news (from towns)
@ IndustryOpen
Opening of industries.
@ Company
Company news item. (Newspaper with face)
@ Normal
Normal news item. (Newspaper with text only)
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 debug_inline 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:47
Road specific functions.
@ NoHouses
Bit number for setting this roadtype as not house friendly.
@ TownBuild
Bit number for allowing towns to build this roadtype.
const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
Definition road.h:230
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:235
bool HasTownOwnedRoad(Tile t)
Checks if given tile has town owned road.
Definition road_map.h:264
static debug_inline bool IsNormalRoadTile(Tile t)
Return whether a tile is a normal road tile.
Definition road_map.h:58
static debug_inline bool IsRoadDepot(Tile t)
Return whether a tile is a road depot.
Definition road_map.h:90
DisallowedRoadDirections GetDisallowedRoadDirections(Tile t)
Gets the disallowed directions.
Definition road_map.h:285
bool HasTileRoadType(Tile t, RoadTramType rtt)
Check if a tile has a road or a tram road type.
Definition road_map.h:195
DiagDirection GetRoadDepotDirection(Tile t)
Get the direction of the exit of a road depot.
Definition road_map.h:545
static debug_inline bool IsRoadDepotTile(Tile t)
Return whether a tile is a road depot tile.
Definition road_map.h:100
bool IsRoadOwner(Tile t, RoadTramType rtt, Owner o)
Check if a specific road type is owned by an owner.
Definition road_map.h:252
RoadBits
Enumeration for the road parts on a tile.
Definition road_type.h:40
@ ROAD_SW
South-west part.
Definition road_type.h:43
@ ROAD_ALL
Full 4-way crossing.
Definition road_type.h:54
@ ROAD_NONE
No road-part is build.
Definition road_type.h:41
@ ROAD_E
Road at the two eastern edges.
Definition road_type.h:50
@ ROAD_NE
North-east part.
Definition road_type.h:45
@ ROAD_N
Road at the two northern edges.
Definition road_type.h:49
@ ROAD_SE
South-east part.
Definition road_type.h:44
@ ROAD_Y
Full road along the y-axis (north-west + south-east)
Definition road_type.h:47
@ ROAD_S
Road at the two southern edges.
Definition road_type.h:51
@ ROAD_W
Road at the two western edges.
Definition road_type.h:52
@ ROAD_NW
North-west part.
Definition road_type.h:42
@ ROAD_X
Full road along the x-axis (south-west + north-east)
Definition road_type.h:46
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
@ ROADTYPE_END
Used for iterations.
Definition road_type.h:27
@ ROADTYPE_BEGIN
Used for iterations.
Definition road_type.h:24
@ DRD_NONE
None of the directions are disallowed.
Definition road_type.h:62
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:48
@ SLOPE_W
the west corner of the tile is raised
Definition slope_type.h:50
@ SLOPE_ELEVATED
bit mask containing all 'simple' slopes
Definition slope_type.h:61
@ SLOPE_E
the east corner of the tile is raised
Definition slope_type.h:52
@ SLOPE_S
the south corner of the tile is raised
Definition slope_type.h:51
@ SLOPE_N
the north corner of the tile is raised
Definition slope_type.h:53
@ SLOPE_SW
south and west corner are raised
Definition slope_type.h:56
@ SLOPE_FLAT
a flat tile
Definition slope_type.h:49
@ SLOPE_STEEP_W
a steep slope falling to east (from west)
Definition slope_type.h:66
@ SLOPE_NE
north and east corner are raised
Definition slope_type.h:58
@ SLOPE_STEEP_E
a steep slope falling to west (from east)
Definition slope_type.h:68
@ SLOPE_SE
south and east corner are raised
Definition slope_type.h:57
@ SLOPE_NW
north and west corner are raised
Definition slope_type.h:55
@ SLOPE_STEEP_N
a steep slope falling to south (from north)
Definition slope_type.h:69
@ SLOPE_STEEP_S
a steep slope falling to north (from south)
Definition slope_type.h:67
Foundation
Enumeration for Foundations.
Definition slope_type.h:93
@ FOUNDATION_LEVELED
The tile is leveled up to a flat slope.
Definition slope_type.h:95
@ FOUNDATION_NONE
The tile has no foundation, the slope remains unchanged.
Definition slope_type.h:94
@ Town
Source/destination is a town.
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.
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:347
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:113
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:192
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
bool value
tells if the bool cheat is active or not
Definition cheat_type.h:18
Cheat magic_bulldozer
dynamite industries, objects
Definition cheat_type.h:27
GUISettings gui
settings related to the GUI
bool build_on_slopes
allow building on slopes
T y
Y coordinate.
T x
X coordinate.
T x
X coordinate.
T y
Y coordinate.
uint8_t number_towns
the amount of towns
uint8_t town_council_tolerance
minimum required town ratings to be allowed to demolish stuff
This structure is the same for both Industries and Houses.
Definition sprite.h:81
bool bribe
enable bribing the local authority
TownFounding found_town
town founding.
PlaceHouses place_houses
players are allowed to place town houses.
bool exclusive_rights
allow buying exclusive rights
uint8_t initial_city_size
multiplier for the initial size of the cities compared to towns
TownLayout town_layout
select town layout,
bool allow_town_level_crossings
towns are allowed to build level crossings
uint8_t town_growth_rate
town growth rate
bool allow_town_roads
towns are allowed to build roads (always allowed when generating world / in SE)
bool fund_buildings
allow funding new buildings
bool fund_roads
allow funding local road reconstruction
TownCargoGenMode town_cargogen_mode
algorithm for generating cargo from houses,
uint8_t dist_local_authority
distance for town local authority, default 20
uint8_t larger_towns
the number of cities to build. These start off larger and grow twice as fast
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.
bool population_in_label
show the population of a town in its label?
uint16_t custom_town_number
manually entered number of towns
LandscapeType landscape
the landscape we're currently in
uint8_t town_name
the town name generator used for town names
EconomySettings economy
settings to change the economy
ConstructionSettings construction
construction of things in-game
DifficultySettings difficulty
settings related to the difficulty
GameCreationSettings game_creation
settings used during the creation of a game (map)
Stores station stats for a single cargo.
CargoType accepts_cargo[HOUSE_NUM_ACCEPTS]
input cargo slots
Definition house.h:108
SubstituteGRFFileProps grf_prop
Properties related the the grf file.
Definition house.h:114
uint8_t probability
Relative probability of appearing (16 is the standard value)
Definition house.h:117
uint8_t removal_cost
cost multiplier for removing it
Definition house.h:103
uint8_t mail_generation
mail generation multiplier (tile based, as the acceptances below)
Definition house.h:106
bool enabled
the house is available to build (true by default, but can be disabled by newgrf)
Definition house.h:111
Money GetRemovalCost() const
Get the cost for removing this house.
Definition town_cmd.cpp:229
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:109
TimerGameCalendar::Year max_year
last year it can be built
Definition house.h:101
HouseCallbackMasks callback_mask
Bitmask of house callbacks that have to be called.
Definition house.h:115
uint16_t remove_rating_decrease
rating decrease if removed
Definition house.h:105
uint8_t population
population (Zero on other tiles in multi tile house.)
Definition house.h:102
HouseExtraFlags extra_flags
some more flags
Definition house.h:118
uint8_t cargo_acceptance[HOUSE_NUM_ACCEPTS]
acceptance level for the cargo slots
Definition house.h:107
HouseID Index() const
Gets the index of this spec.
HouseClassID class_id
defines the class this house has (not grf file based)
Definition house.h:119
StringID building_name
building name
Definition house.h:104
uint8_t minimum_life
The minimum number of years this house will survive before the town rebuilds it.
Definition house.h:122
HouseZones building_availability
where can it be built (climates, zones)
Definition house.h:110
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
Size related data of the map.
Definition map_func.h:206
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:327
static IterateWrapper Iterate()
Returns an iterable ensemble of all Tiles.
Definition map_func.h:362
static debug_inline uint Size()
Get the size of the map.
Definition map_func.h:287
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.
Represents the covered area of e.g.
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< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
static size_t GetPoolSize()
Returns first unused index.
static Titem * Get(auto index)
Returns Titem with given index.
static size_t GetNumItems()
Returns number of valid items in the pool.
Tindex index
Index of this pool item.
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
static bool IsValidID(auto index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
static bool CleaningPool()
Returns current state of pool cleaning - yes or no.
static Titem * GetIfValid(auto index)
Returns Titem with given index.
Base class for all pools.
static constexpr size_t MAX_SIZE
Make template parameter accessible from outside.
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)
Returns an iterable ensemble of all valid stations of type T.
Station data structure.
bool CatchmentCoversTown(TownID t) const
Test if the given town ID is covered by our catchment area.
Definition station.cpp:452
uint16_t override_id
id of the entity been replaced by
Tile description for the 'land area information' tool.
Definition tile_cmd.h:36
std::optional< std::string > grf
newGRF used for the tile contents
Definition tile_cmd.h:47
StringID str
Description of the tile.
Definition tile_cmd.h:37
std::array< Owner, 4 > owner
Name of the owner(s)
Definition tile_cmd.h:39
uint64_t dparam
Parameter of the str string.
Definition tile_cmd.h:38
std::optional< bool > town_can_upgrade
Whether the town can upgrade this house during town growth.
Definition tile_cmd.h:54
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:30
Slope tileh
Slope of the tile.
Definition tile_cmd.h:31
TileIndex tile
Tile index.
Definition tile_cmd.h:32
Set of callback functions for performing tile operations of a given tile type.
Definition tile_cmd.h:142
uint32_t population
Current population of people.
Definition town.h:43
uint32_t num_houses
Amount of houses.
Definition town.h:42
TrackedViewportSign sign
Location of name sign, UpdateVirtCoord updates this.
Definition town.h:44
BuildingCounts< uint16_t > building_counts
The number of each type of building in the town.
Definition town.h:47
std::array< uint32_t, NUM_HOUSE_ZONES > squared_town_zone_radius
UpdateTownRadius updates this given the house count.
Definition town.h:46
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:53
EncodedString text
General text with additional information.
Definition town.h:104
bool larger_town
if this is a larger town and should grow more quickly
Definition town.h:140
CompanyMask statues
which companies have a statue?
Definition town.h:69
uint16_t time_until_rebuild
time until we rebuild a house
Definition town.h:132
std::string cached_name
NOSAVE: Cache of the resolved name of the town, if not using a custom town name.
Definition town.h:63
TileIndex xy
town center tile
Definition town.h:54
uint8_t fund_buildings_months
fund buildings program in action?
Definition town.h:137
TownLayout layout
town specific road layout
Definition town.h:141
static Town * GetRandom()
Return a random valid town.
Definition town_cmd.cpp:200
std::string name
Custom town name. If empty, the town was not renamed and uses the generated name.
Definition town.h:62
uint16_t grow_counter
counter to count when to grow, value is smaller than or equal to growth_rate
Definition town.h:134
uint8_t flags
See TownFlags.
Definition town.h:65
TownCache cache
Container for all cacheable data.
Definition town.h:56
TypedIndexContainer< std::array< uint8_t, MAX_COMPANIES >, CompanyID > unwanted
how many months companies aren't wanted by towns (bribe)
Definition town.h:73
CompanyID exclusivity
which company has exclusivity
Definition town.h:74
ValidHistoryMask valid_history
Mask of valid history records.
Definition town.h:102
void InitializeLayout(TownLayout layout)
Assign the town layout.
Definition town_cmd.cpp:186
bool show_zone
NOSAVE: mark town to show the local authority zone in the viewports.
Definition town.h:143
uint8_t exclusive_counter
months till the exclusivity expires
Definition town.h:75
void UpdateVirtCoord()
Resize the sign (label) of the town after it changes population.
Definition town_cmd.cpp:395
CompanyMask have_ratings
which companies have a rating
Definition town.h:72
~Town()
Destroy the town.
Definition town_cmd.cpp:112
TypedIndexContainer< std::array< int16_t, MAX_COMPANIES >, CompanyID > ratings
ratings of each company for this town
Definition town.h:76
uint16_t growth_rate
town growth rate
Definition town.h:135
StationList stations_near
NOSAVE: List of nearby stations.
Definition town.h:130
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:171
uint8_t road_build_months
fund road reconstruction in action?
Definition town.h:138
std::array< TransportedCargoStat< uint16_t >, NUM_TAE > received
Cargo statistics about received cargotypes.
Definition town.h:100
std::array< uint32_t, NUM_TAE > goal
Amount of cargo required for the town to grow.
Definition town.h:101
void UpdatePosition(int center, int top, std::string_view str, std::string_view str_small={})
Update the position of the viewport sign.
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:95
int GetTileMaxZ(TileIndex t)
Get top height of the tile inside the map.
Definition tile_map.cpp:136
int GetTileZ(TileIndex tile)
Get bottom height of the tile.
Definition tile_map.cpp:116
uint TileHash(uint x, uint y)
Calculate a hash value from a tile position.
Definition tile_map.h:324
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
static debug_inline TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
Definition tile_map.h:96
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
static debug_inline bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition tile_map.h:150
Slope GetTileSlope(TileIndex tile)
Return the slope of a given tile inside the map.
Definition tile_map.h:279
static debug_inline uint TileHeight(Tile tile)
Returns the height of a tile.
Definition tile_map.h:29
@ TROPICZONE_DESERT
Tile is desert.
Definition tile_type.h:78
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:95
static constexpr uint TILE_SIZE
Tile size in world coordinates.
Definition tile_type.h:15
@ MP_TREES
Tile got trees.
Definition tile_type.h:52
@ MP_ROAD
A tile with road (or tram tracks)
Definition tile_type.h:50
@ MP_STATION
A tile of a station.
Definition tile_type.h:53
@ MP_TUNNELBRIDGE
Tunnel entry/exit and bridge heads.
Definition tile_type.h:57
@ MP_CLEAR
A tile without any structures, i.e. grass, rocks, farm fields etc.
Definition tile_type.h:48
@ MP_HOUSE
A house by a town.
Definition tile_type.h:51
@ MP_WATER
Water tile.
Definition tile_type.h:54
@ MP_RAILWAY
A railway.
Definition tile_type.h:49
@ MP_INDUSTRY
Part of an industry.
Definition tile_type.h:56
@ MP_VOID
Invisible tiles at the SW and SE border.
Definition tile_type.h:55
@ MP_OBJECT
Contains objects such as transmitters and owned land.
Definition tile_type.h:58
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
static const uint TOWN_GROWTH_DESERT
The town needs the cargo for growth when on desert (any amount)
Definition town.h:33
@ TOWN_HAS_CHURCH
There can be only one church by town.
Definition town.h:236
@ TOWN_HAS_STADIUM
There can be only one stadium by town.
Definition town.h:237
@ TOWN_IS_GROWING
Conditions for town growth are met. Grow according to Town::growth_rate.
Definition town.h:235
@ TOWN_CUSTOM_GROWTH
Growth rate is controlled by GS.
Definition town.h:238
TownRatingCheckType
Action types that a company must ask permission for to a town authority.
Definition town.h:214
@ TOWN_RATING_CHECK_TYPE_COUNT
Number of town checking action types.
Definition town.h:217
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:251
@ RoadRebuild
Rebuild the roads.
@ Bribe
Try to bribe the council.
@ BuildStatue
Build a statue.
@ BuyRights
Buy exclusive transport rights.
@ FundBuildings
Fund new buildings.
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 CommandCost TownActionAdvertiseSmall(Town *t, DoCommandFlags flags)
Perform the "small advertising campaign" town action.
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.
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 CommandCost TownCanBePlacedHere(TileIndex tile)
Check if it's possible to place a town on a given tile.
static bool IsNeighbourRoadTile(TileIndex tile, const DiagDirection dir, uint dist_multi)
Check for parallel road inside a given distance.
CommandCost CmdPlaceHouse(DoCommandFlags flags, TileIndex tile, HouseID house, bool is_protected)
Place an individual house.
static bool _generating_town
Set if a town is being generated.
Definition town_cmd.cpp:85
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.
Definition town_cmd.cpp:599
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 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:576
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:513
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:454
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)
Callback function to clear a house tile.
Definition town_cmd.cpp:714
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:556
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:439
CargoArray GetAcceptedCargoOfHouse(const HouseSpec *hs)
Get accepted cargo of a house prototype.
Definition town_cmd.cpp:855
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:786
static DiagDirection RandomDiagDir()
Return a random direction.
Definition town_cmd.cpp:252
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:468
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:427
CommandCost CmdDeleteTown(DoCommandFlags flags, TownID town_id)
Delete a town (scenario editor or worldgen only).
static Foundation GetFoundation_Town(TileIndex tile, Slope tileh)
Get the foundation for a house.
Definition town_cmd.cpp:312
static TimerGameCalendar::Date GetTownRoadTypeFirstIntroductionDate()
Get the calendar date of the earliest town-buildable road type.
Definition town_cmd.cpp:997
static void AnimateTile_Town(TileIndex tile)
Animate a tile for a town.
Definition town_cmd.cpp:336
const TileTypeProcs _tile_type_town_procs
Tile callback functions for a town.
Definition landscape.cpp:52
RoadType GetTownRoadType()
Get the road type that towns should build at this current moment.
Definition town_cmd.cpp:962
static RoadBits GetTownRoadBits(TileIndex tile)
Return the RoadBits of a tile, ignoring depot and bay road stops.
Definition town_cmd.cpp:951
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 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 bool TestTownOwnsBridge(TileIndex tile, const Town *t)
Check if a town 'owns' a bridge.
Definition town_cmd.cpp:96
void OnTick_Town()
Iterate through all towns and call their tick handler.
Definition town_cmd.cpp:937
static CommandCost TownActionAdvertiseLarge(Town *t, DoCommandFlags flags)
Perform the "large advertising campaign" town action.
bool CheckTownRoadTypes()
Check if towns are able to build road.
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:490
static void TownTickHandler(Town *t)
Handle the town tick for a single town, by growing the town if desired.
Definition town_cmd.cpp:918
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:802
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:387
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:530
static bool IsUniqueTownName(const std::string &name)
Verifies this custom name is unique.
static void DrawTile_Town(TileInfo *ti)
Draw a house and its tile.
Definition town_cmd.cpp:261
void UpdateAllTownVirtCoords()
Update the virtual coords needed to draw the town sign for all towns.
Definition town_cmd.cpp:419
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:115
@ TCGM_ORIGINAL
Original algorithm (quadratic cargo by population)
Definition town_type.h:114
static constexpr int RATING_ROAD_NEEDED_NEUTRAL
"Neutral"
Definition town_type.h:70
TownLayout
Town Layouts.
Definition town_type.h:81
@ TL_3X3_GRID
Geometric 3x3 grid algorithm.
Definition town_type.h:86
@ TL_ORIGINAL
Original algorithm (min. 1 distance between roads)
Definition town_type.h:83
@ TL_2X2_GRID
Geometric 2x2 grid algorithm.
Definition town_type.h:85
@ TL_RANDOM
Random town layout.
Definition town_type.h:88
@ TL_BETTER_ROADS
Extended original algorithm (min. 2 distance between roads)
Definition town_type.h:84
@ NUM_TLS
Number of town layouts.
Definition town_type.h:90
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:107
@ TF_FORBIDDEN
Forbidden.
Definition town_type.h:105
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_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
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:119
@ Roads
Allow town to place roads.
@ Buildings
Allow town to place buildings.
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
TransportType
Available types of transport.
@ TRANSPORT_ROAD
Transport by road vehicle.
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:663
void AddChildSpriteScreen(SpriteID image, PaletteID pal, int x, int y, bool transparent, const SubSprite *sub, bool scale, bool relative)
Add a child sprite to a parent sprite.
Definition viewport.cpp:824
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.
bool HasTileWaterGround(Tile t)
Checks whether the tile has water at the ground.
Definition water_map.h:350
bool IsWaterTile(Tile t)
Is it a water tile with plain water?
Definition water_map.h:190
bool IsSea(Tile t)
Is it a sea water tile?
Definition water_map.h:158
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:1184
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition window.cpp:3175
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:3267
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition window.cpp:3149
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: