OpenTTD Source 20260206-master-g4d4e37dbf1
town_cmd.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
9
10#include "stdafx.h"
11#include "misc/history_type.hpp"
12#include "misc/history_func.hpp"
13#include "road.h"
14#include "road_internal.h" /* Cleaning up road bits */
15#include "road_cmd.h"
16#include "landscape.h"
17#include "viewport_func.h"
18#include "viewport_kdtree.h"
19#include "command_func.h"
20#include "company_func.h"
21#include "industry.h"
22#include "station_base.h"
23#include "waypoint_base.h"
24#include "station_kdtree.h"
25#include "company_base.h"
26#include "news_func.h"
27#include "error.h"
28#include "object.h"
29#include "genworld.h"
30#include "newgrf_debug.h"
31#include "newgrf_house.h"
32#include "newgrf_text.h"
33#include "autoslope.h"
34#include "tunnelbridge_map.h"
35#include "strings_func.h"
36#include "window_func.h"
37#include "string_func.h"
38#include "newgrf_cargo.h"
39#include "cheat_type.h"
40#include "animated_tile_func.h"
41#include "subsidy_func.h"
42#include "core/pool_func.hpp"
43#include "town.h"
44#include "town_kdtree.h"
45#include "townname_func.h"
46#include "core/random_func.hpp"
47#include "core/backup_type.hpp"
48#include "depot_base.h"
49#include "object_map.h"
50#include "object_base.h"
51#include "ai/ai.hpp"
52#include "game/game.hpp"
53#include "town_cmd.h"
54#include "landscape_cmd.h"
55#include "road_cmd.h"
56#include "terraform_cmd.h"
57#include "tunnelbridge_cmd.h"
58#include "clear_map.h"
59#include "tree_map.h"
60#include "map_func.h"
61#include "timer/timer.h"
65
66#include "table/strings.h"
67#include "table/town_land.h"
68
69#include "safeguards.h"
70
71/* Initialize the town-pool */
72TownPool _town_pool("Town");
74
75
76TownKdtree _town_kdtree{};
77
78void RebuildTownKdtree()
79{
80 std::vector<TownID> townids;
81 for (const Town *town : Town::Iterate()) {
82 townids.push_back(town->index);
83 }
84 _town_kdtree.Build(townids.begin(), townids.end());
85}
86
88static bool _generating_town = false;
89
99static bool TestTownOwnsBridge(TileIndex tile, const Town *t)
100{
101 if (!IsTileOwner(tile, OWNER_TOWN)) return false;
102
104 bool town_owned = IsTileType(adjacent, TileType::Road) && IsTileOwner(adjacent, OWNER_TOWN) && GetTownIndex(adjacent) == t->index;
105
106 if (!town_owned) {
107 /* Or other adjacent road */
109 town_owned = IsTileType(adjacent, TileType::Road) && IsTileOwner(adjacent, OWNER_TOWN) && GetTownIndex(adjacent) == t->index;
110 }
111
112 return town_owned;
113}
114
116{
117 if (CleaningPool()) return;
118
119 /* Delete town authority window
120 * and remove from list of sorted towns */
123
124#ifdef WITH_ASSERT
125 /* Check no industry is related to us. */
126 for (const Industry *i : Industry::Iterate()) {
127 assert(i->town != this);
128 }
129
130 /* ... and no object is related to us. */
131 for (const Object *o : Object::Iterate()) {
132 assert(o->town != this);
133 }
134
135 /* Check no tile is related to us. */
136 for (const auto tile : Map::Iterate()) {
137 switch (GetTileType(tile)) {
138 case TileType::House:
139 assert(GetTownIndex(tile) != this->index);
140 break;
141
142 case TileType::Road:
143 assert(!HasTownOwnedRoad(tile) || GetTownIndex(tile) != this->index);
144 break;
145
147 assert(!TestTownOwnsBridge(tile, this));
148 break;
149
150 default:
151 break;
152 }
153 }
154#endif /* WITH_ASSERT */
155
156 /* Clear the persistent storage list. */
157 for (auto &psa : this->psa_list) {
158 delete psa;
159 }
160 this->psa_list.clear();
161
162 Source src{this->index, SourceType::Town};
167}
168
169
175{
176 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_REBUILD);
178
179 /* Give objects a new home! */
180 for (Object *o : Object::Iterate()) {
181 if (o->town == nullptr) o->town = CalcClosestTownFromTile(o->location.tile, UINT_MAX);
182 }
183}
184
190{
191 if (layout != TL_RANDOM) {
192 this->layout = layout;
193 return;
194 }
195
196 this->layout = static_cast<TownLayout>(TileHash(TileX(this->xy), TileY(this->xy)) % (NUM_TLS - 1));
197}
198
203/* static */ Town *Town::GetRandom()
204{
205 if (Town::GetNumItems() == 0) return nullptr;
206 int num = RandomRange((uint16_t)Town::GetNumItems());
207 size_t index = std::numeric_limits<size_t>::max();
208
209 while (num >= 0) {
210 num--;
211 index++;
212
213 /* Make sure we have a valid town */
214 while (!Town::IsValidID(index)) {
215 index++;
216 assert(index < Town::GetPoolSize());
217 }
218 }
219
220 return Town::Get(index);
221}
222
223void Town::FillCachedName() const
224{
225 this->cached_name = GetTownName(this);
226}
227
233{
234 return (_price[Price::ClearHouse] * this->removal_cost) >> 8;
235}
236
237static bool TryBuildTownHouse(Town *t, TileIndex tile, TownExpandModes modes);
238static Town *CreateRandomTown(uint attempts, uint32_t townnameparts, TownSize size, bool city, TownLayout layout);
239
240static void TownDrawHouseLift(const TileInfo *ti)
241{
242 AddChildSpriteScreen(SPR_LIFT, PAL_NONE, 14, 60 - GetLiftPosition(ti->tile));
243}
244
245typedef void TownDrawTileProc(const TileInfo *ti);
246static TownDrawTileProc * const _town_draw_tile_procs[1] = {
247 TownDrawHouseLift
248};
249
256{
258}
259
264static void DrawTile_Town(TileInfo *ti)
265{
266 HouseID house_id = GetHouseType(ti->tile);
267
268 if (house_id >= NEW_HOUSE_OFFSET) {
269 /* Houses don't necessarily need new graphics. If they don't have a
270 * spritegroup associated with them, then the sprite for the substitute
271 * house id is drawn instead. */
272 if (HouseSpec::Get(house_id)->grf_prop.HasSpriteGroups()) {
273 DrawNewHouseTile(ti, house_id);
274 return;
275 } else {
276 house_id = HouseSpec::Get(house_id)->grf_prop.subst_id;
277 }
278 }
279
280 /* Retrieve pointer to the draw town tile struct */
281 const DrawBuildingsTileStruct *dcts = &_town_draw_tile_data[house_id << 4 | TileHash2Bit(ti->x, ti->y) << 2 | GetHouseBuildingStage(ti->tile)];
282
284
285 DrawGroundSprite(dcts->ground.sprite, dcts->ground.pal);
286
287 /* If houses are invisible, do not draw the upper part */
288 if (IsInvisibilitySet(TO_HOUSES)) return;
289
290 /* Add a house on top of the ground? */
291 SpriteID image = dcts->building.sprite;
292 if (image != 0) {
293 AddSortableSpriteToDraw(image, dcts->building.pal, *ti, *dcts, IsTransparencySet(TO_HOUSES));
294
295 if (IsTransparencySet(TO_HOUSES)) return;
296 }
297
298 {
299 int proc = dcts->draw_proc - 1;
300
301 if (proc >= 0) _town_draw_tile_procs[proc](ti);
302 }
303}
304
305static int GetSlopePixelZ_Town(TileIndex tile, uint, uint, bool)
306{
307 return GetTileMaxPixelZ(tile);
308}
309
316{
317 HouseID hid = GetHouseType(tile);
318
319 /* For NewGRF house tiles we might not be drawing a foundation. We need to
320 * account for this, as other structures should
321 * draw the wall of the foundation in this case.
322 */
323 if (hid >= NEW_HOUSE_OFFSET) {
324 const HouseSpec *hs = HouseSpec::Get(hid);
326 uint32_t callback_res = GetHouseCallback(CBID_HOUSE_DRAW_FOUNDATIONS, 0, 0, hid, Town::GetByTile(tile), tile);
327 if (callback_res != CALLBACK_FAILED && !ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DRAW_FOUNDATIONS, callback_res)) return FOUNDATION_NONE;
328 }
329 }
330 return FlatteningFoundation(tileh);
331}
332
340{
341 if (GetHouseType(tile) >= NEW_HOUSE_OFFSET) {
342 AnimateNewHouseTile(tile);
343 return;
344 }
345
346 if (TimerGameTick::counter & 3) return;
347
348 /* If the house is not one with a lift anymore, then stop this animating.
349 * Not exactly sure when this happens, but probably when a house changes.
350 * Before this was just a return...so it'd leak animated tiles..
351 * That bug seems to have been here since day 1?? */
352 if (!HouseSpec::Get(GetHouseType(tile))->building_flags.Test(BuildingFlag::IsAnimated)) {
353 DeleteAnimatedTile(tile);
354 return;
355 }
356
357 if (!LiftHasDestination(tile)) {
358 uint i;
359
360 /* Building has 6 floors, number 0 .. 6, where 1 is illegal.
361 * This is due to the fact that the first floor is, in the graphics,
362 * the height of 2 'normal' floors.
363 * Furthermore, there are 6 lift positions from floor N (incl) to floor N + 1 (excl) */
364 do {
365 i = RandomRange(7);
366 } while (i == 1 || i * 6 == GetLiftPosition(tile));
367
368 SetLiftDestination(tile, i);
369 }
370
371 int pos = GetLiftPosition(tile);
372 int dest = GetLiftDestination(tile) * 6;
373 pos += (pos < dest) ? 1 : -1;
374 SetLiftPosition(tile, pos);
375
376 if (pos == dest) {
377 HaltLift(tile);
378 DeleteAnimatedTile(tile);
379 }
380
382}
383
390static bool IsCloseToTown(TileIndex tile, uint dist)
391{
392 if (_town_kdtree.Count() == 0) return false;
393 Town *t = Town::Get(_town_kdtree.FindNearest(TileX(tile), TileY(tile)));
394 return DistanceManhattan(tile, t->xy) < dist;
395}
396
399{
400 Point pt = RemapCoords2(TileX(this->xy) * TILE_SIZE, TileY(this->xy) * TILE_SIZE);
401
402 if (this->cache.sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeTown(this->index));
403
404 std::string town_string;
405 if (this->larger_town) {
406 town_string = GetString(_settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_CITY_POP : STR_VIEWPORT_TOWN_CITY, this->index, this->cache.population);
407 } else {
408 town_string = GetString(_settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_POP : STR_TOWN_NAME, this->index, this->cache.population);
409 }
410
411 this->cache.sign.UpdatePosition(pt.x, pt.y - 24 * ZOOM_BASE,
412 town_string,
413 GetString(STR_TOWN_NAME, this->index, this->cache.population)
414);
415
416 _viewport_sign_kdtree.Insert(ViewportSignKdtreeItem::MakeTown(this->index));
417
419}
420
423{
424 for (Town *t : Town::Iterate()) {
425 t->UpdateVirtCoord();
426 }
427}
428
431{
432 for (Town *t : Town::Iterate()) {
433 t->cached_name.clear();
434 }
435}
436
442static void ChangePopulation(Town *t, int mod)
443{
444 t->cache.population += mod;
445 if (_generating_town) [[unlikely]] return;
446
447 InvalidateWindowData(WC_TOWN_VIEW, t->index); // Cargo requirements may appear/vanish for small populations
448 if (_settings_client.gui.population_in_label) t->UpdateVirtCoord();
449
450 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_POPULATION_CHANGE);
451}
452
458{
459 uint32_t pop = 0;
460 for (const Town *t : Town::Iterate()) pop += t->cache.population;
461 return pop;
462}
463
471static void RemoveNearbyStations(Town *t, TileIndex tile, BuildingFlags flags)
472{
473 for (StationList::iterator it = t->stations_near.begin(); it != t->stations_near.end(); /* incremented inside loop */) {
474 const Station *st = *it;
475
476 bool covers_area = st->TileIsInCatchment(tile);
477 if (flags.Any(BUILDING_2_TILES_Y)) covers_area |= st->TileIsInCatchment(tile + TileDiffXY(0, 1));
478 if (flags.Any(BUILDING_2_TILES_X)) covers_area |= st->TileIsInCatchment(tile + TileDiffXY(1, 0));
479 if (flags.Any(BUILDING_HAS_4_TILES)) covers_area |= st->TileIsInCatchment(tile + TileDiffXY(1, 1));
480
481 if (covers_area && !st->CatchmentCoversTown(t->index)) {
482 it = t->stations_near.erase(it);
483 } else {
484 ++it;
485 }
486 }
487}
488
494{
495 assert(IsTileType(tile, TileType::House));
496
497 /* Progress in construction stages */
499 if (GetHouseConstructionTick(tile) != 0) return;
500
501 TriggerHouseAnimation_ConstructionStageChanged(tile, false);
502
503 if (IsHouseCompleted(tile)) {
504 /* Now that construction is complete, we can add the population of the
505 * building to the town. */
506 ChangePopulation(Town::GetByTile(tile), HouseSpec::Get(GetHouseType(tile))->population);
507 ResetHouseAge(tile);
508 }
510}
511
517{
518 BuildingFlags flags = HouseSpec::Get(GetHouseType(tile))->building_flags;
519 if (flags.Any(BUILDING_HAS_1_TILE)) AdvanceSingleHouseConstruction(TileAddXY(tile, 0, 0));
520 if (flags.Any(BUILDING_2_TILES_Y)) AdvanceSingleHouseConstruction(TileAddXY(tile, 0, 1));
521 if (flags.Any(BUILDING_2_TILES_X)) AdvanceSingleHouseConstruction(TileAddXY(tile, 1, 0));
522 if (flags.Any(BUILDING_HAS_4_TILES)) AdvanceSingleHouseConstruction(TileAddXY(tile, 1, 1));
523}
524
533static void TownGenerateCargo(Town *t, CargoType cargo, uint amount, StationFinder &stations, bool affected_by_recession)
534{
535 if (amount == 0) return;
536
537 /* All production is halved during a recession (except for NewGRF-supplied town cargo). */
538 if (affected_by_recession && EconomyIsInRecession()) {
539 amount = (amount + 1) >> 1;
540 }
541
542 /* Scale by cargo scale setting. */
543 amount = ScaleByCargoScale(amount, true);
544 if (amount == 0) return;
545
546 /* Actually generate cargo and update town statistics. */
547 auto &supplied = t->GetOrCreateCargoSupplied(cargo);
548 supplied.history[THIS_MONTH].production += amount;
549 supplied.history[THIS_MONTH].transported += MoveGoodsToStation(cargo, amount, {t->index, SourceType::Town}, stations.GetStations());;
550}
551
559static void TownGenerateCargoOriginal(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
560{
561 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[tpe]) {
562 uint32_t r = Random();
563 if (GB(r, 0, 8) < rate) {
564 CargoType cargo_type = cs->Index();
565 uint amt = (GB(r, 0, 8) * cs->town_production_multiplier / TOWN_PRODUCTION_DIVISOR) / 8 + 1;
566
567 TownGenerateCargo(t, cargo_type, amt, stations, true);
568 }
569 }
570}
571
579static void TownGenerateCargoBinomial(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
580{
581 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[tpe]) {
582 CargoType cargo_type = cs->Index();
583 uint32_t r = Random();
584
585 /* Make a bitmask with up to 32 bits set, one for each potential pax. */
586 int genmax = (rate + 7) / 8;
587 uint32_t genmask = (genmax >= 32) ? 0xFFFFFFFF : ((1 << genmax) - 1);
588
589 /* Mask random value by potential pax and count number of actual pax. */
590 uint amt = CountBits(r & genmask) * cs->town_production_multiplier / TOWN_PRODUCTION_DIVISOR;
591
592 TownGenerateCargo(t, cargo_type, amt, stations, true);
593 }
594}
595
602static void TileLoop_Town(TileIndex tile)
603{
604 HouseID house_id = GetHouseType(tile);
605
606 /* NewHouseTileLoop returns false if Callback 21 succeeded, i.e. the house
607 * doesn't exist any more, so don't continue here. */
608 if (house_id >= NEW_HOUSE_OFFSET && !NewHouseTileLoop(tile)) return;
609
610 if (!IsHouseCompleted(tile)) {
611 /* Construction is not completed, so we advance a construction stage. */
613 return;
614 }
615
616 const HouseSpec *hs = HouseSpec::Get(house_id);
617
618 /* If the lift has a destination, it is already an animated tile. */
620 house_id < NEW_HOUSE_OFFSET &&
621 !LiftHasDestination(tile) &&
622 Chance16(1, 2)) {
623 AddAnimatedTile(tile);
624 }
625
626 Town *t = Town::GetByTile(tile);
627 uint32_t r = Random();
628
629 StationFinder stations(TileArea(tile, 1, 1));
630
632 for (uint i = 0; i < 256; i++) {
633 uint16_t callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, r, house_id, t, tile);
634
635 if (callback == CALLBACK_FAILED || callback == CALLBACK_HOUSEPRODCARGO_END) break;
636
637 CargoType cargo = GetCargoTranslation(GB(callback, 8, 7), hs->grf_prop.grffile);
638 if (!IsValidCargoType(cargo)) continue;
639
640 uint amt = GB(callback, 0, 8);
641 if (amt == 0) continue;
642
643 /* NewGRF-supplied town cargos are not affected by recessions. */
644 TownGenerateCargo(t, cargo, amt, stations, false);
645 }
646 } else {
647 switch (_settings_game.economy.town_cargogen_mode) {
648 case TCGM_ORIGINAL:
649 /* Original (quadratic) cargo generation algorithm */
652 break;
653
654 case TCGM_BITCOUNT:
655 /* Binomial distribution per tick, by a series of coin flips */
656 /* Reduce generation rate to a 1/4, using tile bits to spread out distribution.
657 * As tick counter is incremented by 256 between each call, we ignore the lower 8 bits. */
658 if (GB(TimerGameTick::counter, 8, 2) == GB(tile.base(), 0, 2)) {
661 }
662 break;
663
664 default:
665 NOT_REACHED();
666 }
667 }
668
670
671 if (hs->building_flags.Any(BUILDING_HAS_1_TILE) &&
673 CanDeleteHouse(tile) &&
674 GetHouseAge(tile) >= hs->minimum_life &&
675 --t->time_until_rebuild == 0) {
676 t->time_until_rebuild = GB(r, 16, 8) + 192;
677
678 ClearTownHouse(t, tile);
679
680 /* Rebuild with another house? */
681 if (GB(r, 24, 8) >= 12) {
682 /* If we are multi-tile houses, make sure to replace the house
683 * closest to city center. If we do not do this, houses tend to
684 * wander away from roads and other houses. */
685 if (hs->building_flags.Any(BUILDING_HAS_2_TILES)) {
686 /* House tiles are always the most north tile. Move the new
687 * house to the south if we are north of the city center. */
688 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
689 int x = Clamp(grid_pos.x, 0, 1);
690 int y = Clamp(grid_pos.y, 0, 1);
691
693 tile = TileAddXY(tile, x, y);
694 } else if (hs->building_flags.Test(BuildingFlag::Size1x2)) {
695 tile = TileAddXY(tile, 0, y);
696 } else if (hs->building_flags.Test(BuildingFlag::Size2x1)) {
697 tile = TileAddXY(tile, x, 0);
698 }
699 }
700
701 TownExpandModes modes{TownExpandMode::Buildings};
702 if (_settings_game.economy.allow_town_roads) modes.Set(TownExpandMode::Roads);
703
704 TryBuildTownHouse(t, tile, modes);
705 }
706 }
707
708 cur_company.Restore();
709}
710
717static CommandCost ClearTile_Town(TileIndex tile, DoCommandFlags flags)
718{
719 if (flags.Test(DoCommandFlag::Auto)) return CommandCost(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
720 if (!CanDeleteHouse(tile)) return CommandCost(STR_ERROR_BUILDING_IS_PROTECTED);
721
722 const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
723
725 cost.AddCost(hs->GetRemovalCost());
726
727 int rating = hs->remove_rating_decrease;
728 Town *t = Town::GetByTile(tile);
729
731 if (!_cheats.magic_bulldozer.value && !flags.Test(DoCommandFlag::NoTestTownRating)) {
732 /* NewGRFs can add indestructible houses. */
733 if (rating > RATING_MAXIMUM) {
734 return CommandCost(STR_ERROR_BUILDING_IS_PROTECTED);
735 }
736 /* If town authority controls removal, check the company's rating. */
737 if (rating > t->ratings[_current_company] && _settings_game.difficulty.town_council_tolerance != TOWN_COUNCIL_PERMISSIVE) {
738 return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index);
739 }
740 }
741 }
742
743 ChangeTownRating(t, -rating, RATING_HOUSE_MINIMUM, flags);
744 if (flags.Test(DoCommandFlag::Execute)) {
745 ClearTownHouse(t, tile);
746 }
747
748 return cost;
749}
750
751static void AddProducedCargo_Town(TileIndex tile, CargoArray &produced)
752{
753 HouseID house_id = GetHouseType(tile);
754 const HouseSpec *hs = HouseSpec::Get(house_id);
755 Town *t = Town::GetByTile(tile);
756
758 for (uint i = 0; i < 256; i++) {
759 uint16_t callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, 0, house_id, t, tile);
760
761 if (callback == CALLBACK_FAILED || callback == CALLBACK_HOUSEPRODCARGO_END) break;
762
763 CargoType cargo = GetCargoTranslation(GB(callback, 8, 7), hs->grf_prop.grffile);
764
765 if (!IsValidCargoType(cargo)) continue;
766 produced[cargo]++;
767 }
768 } else {
769 if (hs->population > 0) {
771 produced[cs->Index()]++;
772 }
773 }
774 if (hs->mail_generation > 0) {
776 produced[cs->Index()]++;
777 }
778 }
779 }
780}
781
789static void AddAcceptedCargoSetMask(CargoType cargo, uint amount, CargoArray &acceptance, CargoTypes &always_accepted)
790{
791 if (!IsValidCargoType(cargo) || amount == 0) return;
792 acceptance[cargo] += amount;
793 SetBit(always_accepted, cargo);
794}
795
805void AddAcceptedCargoOfHouse(TileIndex tile, HouseID house, const HouseSpec *hs, Town *t, CargoArray &acceptance, CargoTypes &always_accepted)
806{
807 CargoType accepts[lengthof(hs->accepts_cargo)];
808
809 /* Set the initial accepted cargo types */
810 for (uint8_t i = 0; i < lengthof(accepts); i++) {
811 accepts[i] = hs->accepts_cargo[i];
812 }
813
814 /* Check for custom accepted cargo types */
816 uint16_t callback = GetHouseCallback(CBID_HOUSE_ACCEPT_CARGO, 0, 0, house, t, tile, {}, tile == INVALID_TILE);
817 if (callback != CALLBACK_FAILED) {
818 /* Replace accepted cargo types with translated values from callback */
819 accepts[0] = GetCargoTranslation(GB(callback, 0, 5), hs->grf_prop.grffile);
820 accepts[1] = GetCargoTranslation(GB(callback, 5, 5), hs->grf_prop.grffile);
821 accepts[2] = GetCargoTranslation(GB(callback, 10, 5), hs->grf_prop.grffile);
822 }
823 }
824
825 /* Check for custom cargo acceptance */
827 uint16_t callback = GetHouseCallback(CBID_HOUSE_CARGO_ACCEPTANCE, 0, 0, house, t, tile, {}, tile == INVALID_TILE);
828 if (callback != CALLBACK_FAILED) {
829 AddAcceptedCargoSetMask(accepts[0], GB(callback, 0, 4), acceptance, always_accepted);
830 AddAcceptedCargoSetMask(accepts[1], GB(callback, 4, 4), acceptance, always_accepted);
831 if (_settings_game.game_creation.landscape != LandscapeType::Temperate && HasBit(callback, 12)) {
832 /* The 'S' bit indicates food instead of goods */
833 AddAcceptedCargoSetMask(GetCargoTypeByLabel(CT_FOOD), GB(callback, 8, 4), acceptance, always_accepted);
834 } else {
835 AddAcceptedCargoSetMask(accepts[2], GB(callback, 8, 4), acceptance, always_accepted);
836 }
837 return;
838 }
839 }
840
841 /* No custom acceptance, so fill in with the default values */
842 for (uint8_t i = 0; i < lengthof(accepts); i++) {
843 AddAcceptedCargoSetMask(accepts[i], hs->cargo_acceptance[i], acceptance, always_accepted);
844 }
845}
846
847static void AddAcceptedCargo_Town(TileIndex tile, CargoArray &acceptance, CargoTypes &always_accepted)
848{
849 HouseID house = GetHouseType(tile);
850 AddAcceptedCargoOfHouse(tile, house, HouseSpec::Get(house), Town::GetByTile(tile), acceptance, always_accepted);
851}
852
859{
860 CargoTypes always_accepted{};
861 CargoArray acceptance{};
862 AddAcceptedCargoOfHouse(INVALID_TILE, hs->Index(), hs, nullptr, acceptance, always_accepted);
863 return acceptance;
864}
865
866static void GetTileDesc_Town(TileIndex tile, TileDesc &td)
867{
868 const HouseID house = GetHouseType(tile);
869 const HouseSpec *hs = HouseSpec::Get(house);
870 bool house_completed = IsHouseCompleted(tile);
871
872 td.str = hs->building_name;
874
875 std::array<int32_t, 1> regs100;
876 uint16_t callback_res = GetHouseCallback(CBID_HOUSE_CUSTOM_NAME, house_completed ? 1 : 0, 0, house, Town::GetByTile(tile), tile, regs100);
877 if (callback_res != CALLBACK_FAILED && callback_res != 0x400) {
878 StringID new_name = STR_NULL;
879 if (callback_res == 0x40F) {
880 new_name = GetGRFStringID(hs->grf_prop.grfid, static_cast<GRFStringID>(regs100[0]));
881 } else if (callback_res > 0x400) {
883 } else {
884 new_name = GetGRFStringID(hs->grf_prop.grfid, GRFSTR_MISC_GRF_TEXT + callback_res);
885 }
886 if (new_name != STR_NULL && new_name != STR_UNDEFINED) {
887 td.str = new_name;
888 }
889 }
890
891 if (!house_completed) {
892 td.dparam = td.str;
893 td.str = STR_LAI_TOWN_INDUSTRY_DESCRIPTION_UNDER_CONSTRUCTION;
894 }
895
896 if (hs->grf_prop.HasGrfFile()) {
897 const GRFConfig *gc = GetGRFConfig(hs->grf_prop.grfid);
898 td.grf = gc->GetName();
899 }
900
901 td.owner[0] = OWNER_TOWN;
902}
903
904static TrackStatus GetTileTrackStatus_Town(TileIndex, TransportType, uint, DiagDirection)
905{
906 /* not used */
907 return 0;
908}
909
910static void ChangeTileOwner_Town(TileIndex, Owner, Owner)
911{
912 /* not used */
913}
914
915static bool GrowTown(Town *t, TownExpandModes modes);
916
921static void TownTickHandler(Town *t)
922{
924 TownExpandModes modes{TownExpandMode::Buildings};
925 if (_settings_game.economy.allow_town_roads) modes.Set(TownExpandMode::Roads);
926 int i = (int)t->grow_counter - 1;
927 if (i < 0) {
928 if (GrowTown(t, modes)) {
929 i = t->growth_rate;
930 } else {
931 /* If growth failed wait a bit before retrying */
932 i = std::min<uint16_t>(t->growth_rate, Ticks::TOWN_GROWTH_TICKS - 1);
933 }
934 }
935 t->grow_counter = i;
936 }
937}
938
941{
942 if (_game_mode == GM_EDITOR) return;
943
944 for (Town *t : Town::Iterate()) {
946 }
947}
948
955{
956 if (IsRoadDepotTile(tile) || IsBayRoadStopTile(tile)) return ROAD_NONE;
957
958 return GetAnyRoadBits(tile, RTT_ROAD, true);
959}
960
966{
967 RoadType best_rt = ROADTYPE_ROAD;
968 const RoadTypeInfo *best = nullptr;
969 const uint16_t assume_max_speed = 50;
970
972 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
973
974 /* Can town build this road. */
975 if (!rti->flags.Test(RoadTypeFlag::TownBuild)) continue;
976
977 /* Not yet introduced at this date. */
979
980 if (best != nullptr) {
981 if ((rti->max_speed == 0 ? assume_max_speed : rti->max_speed) < (best->max_speed == 0 ? assume_max_speed : best->max_speed)) continue;
982 }
983
984 best_rt = rt;
985 best = rti;
986 }
987
988 return best_rt;
989}
990
995static TimerGameCalendar::Date GetTownRoadTypeFirstIntroductionDate()
996{
997 const RoadTypeInfo *best = nullptr;
999 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
1000
1001 if (!rti->flags.Test(RoadTypeFlag::TownBuild)) continue; // Town can't build this road type.
1002
1003 if (best != nullptr && rti->introduction_date >= best->introduction_date) continue;
1004 best = rti;
1005 }
1006
1007 if (best == nullptr) return TimerGameCalendar::Date(INT32_MAX);
1008 return best->introduction_date;
1009}
1010
1016{
1017 auto min_date = GetTownRoadTypeFirstIntroductionDate();
1018 if (min_date <= TimerGameCalendar::date) return true;
1019
1020 if (min_date < INT32_MAX) {
1022 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_YET),
1023 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_YET_EXPLANATION, min_date),
1024 WL_CRITICAL);
1025 } else {
1027 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_AT_ALL),
1028 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_AT_ALL_EXPLANATION), WL_CRITICAL);
1029 }
1030 return false;
1031}
1032
1043static bool IsNeighbourRoadTile(TileIndex tile, const DiagDirection dir, uint dist_multi)
1044{
1045 if (!IsValidTile(tile)) return false;
1046
1047 /* Lookup table for the used diff values */
1048 const TileIndexDiff tid_lt[3] = {
1052 };
1053
1054 dist_multi = (dist_multi + 1) * 4;
1055 for (uint pos = 4; pos < dist_multi; pos++) {
1056 /* Go (pos / 4) tiles to the left or the right */
1057 TileIndexDiff cur = tid_lt[(pos & 1) ? 0 : 1] * (pos / 4);
1058
1059 /* Use the current tile as origin, or go one tile backwards */
1060 if (pos & 2) cur += tid_lt[2];
1061
1062 /* Test for roadbit parallel to dir and facing towards the middle axis */
1063 if (IsValidTile(tile + cur) &&
1064 GetTownRoadBits(TileAdd(tile, cur)) & DiagDirToRoadBits((pos & 2) ? dir : ReverseDiagDir(dir))) return true;
1065 }
1066 return false;
1067}
1068
1078{
1079 if (DistanceFromEdge(tile) == 0) return false;
1080
1081 /* Prevent towns from building roads under bridges along the bridge. Looks silly. */
1082 if (IsBridgeAbove(tile) && GetBridgeAxis(tile) == DiagDirToAxis(dir)) return false;
1083
1084 /* Check if there already is a road at this point? */
1085 if (GetTownRoadBits(tile) == ROAD_NONE) {
1086 /* No, try if we are able to build a road piece there.
1087 * If that fails clear the land, and if that fails exit.
1088 * This is to make sure that we can build a road here later. */
1090 if (Command<Commands::BuildRoad>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile, (dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? ROAD_Y : ROAD_X, rt, DRD_NONE, t->index).Failed() &&
1091 Command<Commands::LandscapeClear>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile).Failed()) {
1092 return false;
1093 }
1094 }
1095
1096 Slope cur_slope = _settings_game.construction.build_on_slopes ? std::get<0>(GetFoundationSlope(tile)) : GetTileSlope(tile);
1097 bool ret = !IsNeighbourRoadTile(tile, dir, t->layout == TL_ORIGINAL ? 1 : 2);
1098 if (cur_slope == SLOPE_FLAT) return ret;
1099
1100 /* If the tile is not a slope in the right direction, then
1101 * maybe terraform some. */
1102 Slope desired_slope = (dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? SLOPE_NW : SLOPE_NE;
1103 if (desired_slope != cur_slope && ComplementSlope(desired_slope) != cur_slope) {
1104 if (Chance16(1, 8)) {
1105 CommandCost res = CMD_ERROR;
1106 if (!_generating_world && Chance16(1, 10)) {
1107 /* Note: Do not replace "^ SLOPE_ELEVATED" with ComplementSlope(). The slope might be steep. */
1108 res = std::get<0>(Command<Commands::TerraformLand>::Do({DoCommandFlag::Execute, DoCommandFlag::Auto, DoCommandFlag::NoWater},
1109 tile, Chance16(1, 16) ? cur_slope : cur_slope ^ SLOPE_ELEVATED, false));
1110 }
1111 if (res.Failed() && Chance16(1, 3)) {
1112 /* We can consider building on the slope, though. */
1113 return ret;
1114 }
1115 }
1116 return false;
1117 }
1118 return ret;
1119}
1120
1121static bool TerraformTownTile(TileIndex tile, Slope edges, bool dir)
1122{
1123 assert(tile < Map::Size());
1124
1125 CommandCost r = std::get<0>(Command<Commands::TerraformLand>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile, edges, dir));
1126 if (r.Failed() || r.GetCost() >= (_price[Price::Terraform] + 2) * 8) return false;
1127 Command<Commands::TerraformLand>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater, DoCommandFlag::Execute}, tile, edges, dir);
1128 return true;
1129}
1130
1131static void LevelTownLand(TileIndex tile)
1132{
1133 assert(tile < Map::Size());
1134
1135 /* Don't terraform if land is plain or if there's a house there. */
1136 if (IsTileType(tile, TileType::House)) return;
1137 Slope tileh = GetTileSlope(tile);
1138 if (tileh == SLOPE_FLAT) return;
1139
1140 /* First try up, then down */
1141 if (!TerraformTownTile(tile, ~tileh & SLOPE_ELEVATED, true)) {
1142 TerraformTownTile(tile, tileh & SLOPE_ELEVATED, false);
1143 }
1144}
1145
1155{
1156 /* align the grid to the downtown */
1157 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile); // Vector from downtown to the tile
1158 RoadBits rcmd = ROAD_NONE;
1159
1160 switch (t->layout) {
1161 default: NOT_REACHED();
1162
1163 case TL_2X2_GRID:
1164 if ((grid_pos.x % 3) == 0) rcmd |= ROAD_Y;
1165 if ((grid_pos.y % 3) == 0) rcmd |= ROAD_X;
1166 break;
1167
1168 case TL_3X3_GRID:
1169 if ((grid_pos.x % 4) == 0) rcmd |= ROAD_Y;
1170 if ((grid_pos.y % 4) == 0) rcmd |= ROAD_X;
1171 break;
1172 }
1173
1174 /* Optimise only X-junctions */
1175 if (rcmd != ROAD_ALL) return rcmd;
1176
1177 RoadBits rb_template;
1178
1179 switch (GetTileSlope(tile)) {
1180 default: rb_template = ROAD_ALL; break;
1181 case SLOPE_W: rb_template = ROAD_NW | ROAD_SW; break;
1182 case SLOPE_SW: rb_template = ROAD_Y | ROAD_SW; break;
1183 case SLOPE_S: rb_template = ROAD_SW | ROAD_SE; break;
1184 case SLOPE_SE: rb_template = ROAD_X | ROAD_SE; break;
1185 case SLOPE_E: rb_template = ROAD_SE | ROAD_NE; break;
1186 case SLOPE_NE: rb_template = ROAD_Y | ROAD_NE; break;
1187 case SLOPE_N: rb_template = ROAD_NE | ROAD_NW; break;
1188 case SLOPE_NW: rb_template = ROAD_X | ROAD_NW; break;
1189 case SLOPE_STEEP_W:
1190 case SLOPE_STEEP_S:
1191 case SLOPE_STEEP_E:
1192 case SLOPE_STEEP_N:
1193 rb_template = ROAD_NONE;
1194 break;
1195 }
1196
1197 /* Stop if the template is compatible to the growth dir */
1198 if (DiagDirToRoadBits(ReverseDiagDir(dir)) & rb_template) return rb_template;
1199 /* If not generate a straight road in the direction of the growth */
1201}
1202
1214static bool GrowTownWithExtraHouse(Town *t, TileIndex tile, TownExpandModes modes)
1215{
1216 /* We can't look further than that. */
1217 if (DistanceFromEdge(tile) == 0) return false;
1218
1219 uint counter = 0; // counts the house neighbour tiles
1220
1221 /* Check the tiles E,N,W and S of the current tile for houses */
1222 for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
1223 /* Count both void and house tiles for checking whether there
1224 * are enough houses in the area. This to make it likely that
1225 * houses get build up to the edge of the map. */
1226 switch (GetTileType(TileAddByDiagDir(tile, dir))) {
1227 case TileType::House:
1228 case TileType::Void:
1229 counter++;
1230 break;
1231
1232 default:
1233 break;
1234 }
1235
1236 /* If there are enough neighbours stop here */
1237 if (counter >= 3) {
1238 return TryBuildTownHouse(t, tile, modes);
1239 }
1240 }
1241 return false;
1242}
1243
1252static bool GrowTownWithRoad(const Town *t, TileIndex tile, RoadBits rcmd)
1253{
1255 return Command<Commands::BuildRoad>::Do({DoCommandFlag::Execute, DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile, rcmd, rt, DRD_NONE, t->index).Succeeded();
1256}
1257
1267static bool CanRoadContinueIntoNextTile(const Town *t, const TileIndex tile, const DiagDirection road_dir)
1268{
1269 const TileIndexDiff delta = TileOffsByDiagDir(road_dir); // +1 tile in the direction of the road
1270 TileIndex next_tile = tile + delta; // The tile beyond which must be connectable to the target tile
1271 RoadBits rcmd = DiagDirToRoadBits(ReverseDiagDir(road_dir));
1273
1274 /* Before we try anything, make sure the tile is on the map and not the void. */
1275 if (!IsValidTile(next_tile)) return false;
1276
1277 /* If the next tile is a bridge or tunnel, allow if it's continuing in the same direction. */
1278 if (IsTileType(next_tile, TileType::TunnelBridge)) {
1279 return GetTunnelBridgeTransportType(next_tile) == TRANSPORT_ROAD && GetTunnelBridgeDirection(next_tile) == road_dir;
1280 }
1281
1282 /* If the next tile is a station, allow if it's a road station facing the proper direction. Otherwise return false. */
1283 if (IsTileType(next_tile, TileType::Station)) {
1284 /* If the next tile is a road station, allow if it can be entered by the new tunnel/bridge, otherwise disallow. */
1285 if (IsDriveThroughStopTile(next_tile)) return GetDriveThroughStopAxis(next_tile) == DiagDirToAxis(road_dir);
1286 if (IsBayRoadStopTile(next_tile)) return GetBayRoadStopDir(next_tile) == ReverseDiagDir(road_dir);
1287 return false;
1288 }
1289
1290 /* If the next tile is a road depot, allow if it's facing the right way. */
1291 if (IsTileType(next_tile, TileType::Road)) {
1292 return IsRoadDepot(next_tile) && GetRoadDepotDirection(next_tile) == ReverseDiagDir(road_dir);
1293 }
1294
1295 /* If the next tile is a railroad track, check if towns are allowed to build level crossings.
1296 * If level crossing are not allowed, reject the construction. Else allow DoCommand to determine if the rail track is buildable. */
1297 if (IsTileType(next_tile, TileType::Railway) && !_settings_game.economy.allow_town_level_crossings) return false;
1298
1299 /* If a road tile can be built, the construction is allowed. */
1300 return Command<Commands::BuildRoad>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, next_tile, rcmd, rt, DRD_NONE, t->index).Succeeded();
1301}
1302
1313static bool GrowTownWithBridge(const Town *t, const TileIndex tile, const DiagDirection bridge_dir)
1314{
1315 assert(bridge_dir < DIAGDIR_END);
1316
1317 const Slope slope = GetTileSlope(tile);
1318
1319 /* Make sure the direction is compatible with the slope.
1320 * Well we check if the slope has an up bit set in the
1321 * reverse direction. */
1322 if (slope != SLOPE_FLAT && slope & InclinedSlope(bridge_dir)) return false;
1323
1324 /* Assure that the bridge is connectable to the start side */
1325 if (!(GetTownRoadBits(TileAddByDiagDir(tile, ReverseDiagDir(bridge_dir))) & DiagDirToRoadBits(bridge_dir))) return false;
1326
1327 /* We are in the right direction */
1328 uint bridge_length = 0; // This value stores the length of the possible bridge
1329 TileIndex bridge_tile = tile; // Used to store the other waterside
1330
1331 const TileIndexDiff delta = TileOffsByDiagDir(bridge_dir);
1332
1333 /* To prevent really small towns from building disproportionately
1334 * long bridges, make the max a function of its population. */
1335 const uint TOWN_BRIDGE_LENGTH_CAP = 11;
1336 uint base_bridge_length = 5;
1337 uint max_bridge_length = std::min(t->cache.population / 1000 + base_bridge_length, TOWN_BRIDGE_LENGTH_CAP);
1338
1339 if (slope == SLOPE_FLAT) {
1340 /* Bridges starting on flat tiles are only allowed when crossing rivers, rails or one-way roads. */
1341 do {
1342 if (bridge_length++ >= base_bridge_length) {
1343 /* Allow to cross rivers, not big lakes, nor large amounts of rails or one-way roads. */
1344 return false;
1345 }
1346 bridge_tile += delta;
1347 } while (IsValidTile(bridge_tile) && ((IsWaterTile(bridge_tile) && !IsSea(bridge_tile)) || IsPlainRailTile(bridge_tile) || (IsNormalRoadTile(bridge_tile) && GetDisallowedRoadDirections(bridge_tile) != DRD_NONE)));
1348 } else {
1349 do {
1350 if (bridge_length++ >= max_bridge_length) {
1351 /* Ensure the bridge is not longer than the max allowed length. */
1352 return false;
1353 }
1354 bridge_tile += delta;
1355 } while (IsValidTile(bridge_tile) && (IsWaterTile(bridge_tile) || IsPlainRailTile(bridge_tile) || (IsNormalRoadTile(bridge_tile) && GetDisallowedRoadDirections(bridge_tile) != DRD_NONE)));
1356 }
1357
1358 /* Don't allow a bridge where the start and end tiles are adjacent with no span between. */
1359 if (bridge_length == 1) return false;
1360
1361 /* Make sure the road can be continued past the bridge. At this point, bridge_tile holds the end tile of the bridge. */
1362 if (!CanRoadContinueIntoNextTile(t, bridge_tile, bridge_dir)) return false;
1363
1364 /* If another parallel bridge exists nearby, this one would be redundant and shouldn't be built. We don't care about flat bridges. */
1365 if (slope != SLOPE_FLAT) {
1366 for (auto search : SpiralTileSequence(tile, bridge_length, 0, 0)) {
1367 /* Only consider bridge head tiles. */
1368 if (!IsBridgeTile(search)) continue;
1369
1370 /* Only consider road bridges. */
1371 if (GetTunnelBridgeTransportType(search) != TRANSPORT_ROAD) continue;
1372
1373 /* If the bridge is facing the same direction as the proposed bridge, we've found a redundant bridge. */
1374 if (GetTileSlope(search) & InclinedSlope(ReverseDiagDir(bridge_dir))) return false;
1375 }
1376 }
1377
1378 for (uint8_t times = 0; times <= 22; times++) {
1379 uint8_t bridge_type = RandomRange(MAX_BRIDGES - 1);
1380
1381 /* Can we actually build the bridge? */
1383 if (Command<Commands::BuildBridge>::Do(CommandFlagsToDCFlags(GetCommandFlags<Commands::BuildBridge>()), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, rt).Succeeded()) {
1384 Command<Commands::BuildBridge>::Do(CommandFlagsToDCFlags(GetCommandFlags<Commands::BuildBridge>()).Set(DoCommandFlag::Execute), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, rt);
1385 return true;
1386 }
1387 }
1388 /* Quit if it selecting an appropriate bridge type fails a large number of times. */
1389 return false;
1390}
1391
1402static bool GrowTownWithTunnel(const Town *t, const TileIndex tile, const DiagDirection tunnel_dir)
1403{
1404 assert(tunnel_dir < DIAGDIR_END);
1405
1406 Slope slope = GetTileSlope(tile);
1407
1408 /* Only consider building a tunnel if the starting tile is sloped properly. */
1409 if (slope != InclinedSlope(tunnel_dir)) return false;
1410
1411 /* Assure that the tunnel is connectable to the start side */
1412 if (!(GetTownRoadBits(TileAddByDiagDir(tile, ReverseDiagDir(tunnel_dir))) & DiagDirToRoadBits(tunnel_dir))) return false;
1413
1414 const TileIndexDiff delta = TileOffsByDiagDir(tunnel_dir);
1415 int max_tunnel_length = 0;
1416
1417 /* There are two conditions for building tunnels: Under a mountain and under an obstruction. */
1418 if (CanRoadContinueIntoNextTile(t, tile, tunnel_dir)) {
1419 /* 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. */
1420 TileIndex slope_tile = tile;
1421 for (uint8_t tiles = 0; tiles < 4; tiles++) {
1422 if (!IsValidTile(slope_tile)) return false;
1423 slope = GetTileSlope(slope_tile);
1424 if (slope != InclinedSlope(tunnel_dir) && !IsSteepSlope(slope) && !IsSlopeWithOneCornerRaised(slope)) return false;
1425 slope_tile += delta;
1426 }
1427
1428 /* More population means longer tunnels, but make sure we can at least cover the smallest mountain which necessitates tunneling. */
1429 max_tunnel_length = (t->cache.population / 1000) + 7;
1430 } else {
1431 /* When tunneling under an obstruction, the length limit is 5, enough to tunnel under a four-track railway. */
1432 max_tunnel_length = 5;
1433 }
1434
1435 uint8_t tunnel_length = 0;
1436 TileIndex tunnel_tile = tile; // Iterator to store the other end tile of the tunnel.
1437
1438 /* Find the end tile of the tunnel for length and continuation checks. */
1439 do {
1440 if (tunnel_length++ >= max_tunnel_length) return false;
1441 tunnel_tile += delta;
1442 /* The tunnel ends when start and end tiles are the same height. */
1443 } while (IsValidTile(tunnel_tile) && GetTileZ(tile) != GetTileZ(tunnel_tile));
1444
1445 /* Don't allow a tunnel where the start and end tiles are adjacent. */
1446 if (tunnel_length == 1) return false;
1447
1448 /* Make sure the road can be continued past the tunnel. At this point, tunnel_tile holds the end tile of the tunnel. */
1449 if (!CanRoadContinueIntoNextTile(t, tunnel_tile, tunnel_dir)) return false;
1450
1451 /* Attempt to build the tunnel. Return false if it fails to let the town build a road instead. */
1453 if (Command<Commands::BuildTunnel>::Do(CommandFlagsToDCFlags(GetCommandFlags<Commands::BuildTunnel>()), tile, TRANSPORT_ROAD, rt).Succeeded()) {
1454 Command<Commands::BuildTunnel>::Do(CommandFlagsToDCFlags(GetCommandFlags<Commands::BuildTunnel>()).Set(DoCommandFlag::Execute), tile, TRANSPORT_ROAD, rt);
1455 return true;
1456 }
1457
1458 return false;
1459}
1460
1468{
1469 static const TileIndexDiffC tiles[] = { {-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1} };
1470 bool allow = false;
1471
1472 for (const auto &ptr : tiles) {
1473 TileIndex cur_tile = t + ToTileIndexDiff(ptr);
1474 if (!IsValidTile(cur_tile)) continue;
1475
1476 if (!(IsTileType(cur_tile, TileType::Road) || IsAnyRoadStopTile(cur_tile))) continue;
1477 allow = true;
1478
1479 RoadType road_rt = GetRoadTypeRoad(cur_tile);
1480 if (road_rt != INVALID_ROADTYPE && !GetRoadTypeInfo(road_rt)->flags.Test(RoadTypeFlag::NoHouses)) return true;
1481 }
1482
1483 /* If no road was found surrounding the tile we can allow building the house since there is
1484 * nothing which forbids it, if a road was found but the execution reached this point, then
1485 * all the found roads don't allow houses to be built */
1486 return !allow;
1487}
1488
1494{
1495 if (!IsTileType(tile, TileType::Road)) return true;
1496
1497 /* Allow extending on roadtypes which can be built by town, or if the road type matches the type the town will build. */
1498 RoadType rt = GetRoadTypeRoad(tile);
1500}
1501
1506static inline bool TownAllowedToBuildRoads(TownExpandModes modes)
1507{
1508 return modes.Test(TownExpandMode::Roads);
1509}
1510
1511/* The possible states of town growth. */
1517
1537static TownGrowthResult GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection target_dir, Town *t1, TownExpandModes modes)
1538{
1539 RoadBits rcmd = ROAD_NONE; // RoadBits for the road construction command
1540 TileIndex tile = *tile_ptr; // The main tile on which we base our growth
1541
1542 assert(tile < Map::Size());
1543
1544 if (cur_rb == ROAD_NONE) {
1545 /* Tile has no road.
1546 * We will return TownGrowthResult::SearchStopped to say that this is the last iteration. */
1547
1549 if (!_settings_game.economy.allow_town_level_crossings && IsTileType(tile, TileType::Railway)) return TownGrowthResult::SearchStopped;
1550
1551 /* Remove hills etc */
1552 if (!_settings_game.construction.build_on_slopes || Chance16(1, 6)) LevelTownLand(tile);
1553
1554 /* Is a road allowed here? */
1555 switch (t1->layout) {
1556 default: NOT_REACHED();
1557
1558 case TL_3X3_GRID:
1559 case TL_2X2_GRID:
1560 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1561 if (rcmd == ROAD_NONE) return TownGrowthResult::SearchStopped;
1562 break;
1563
1564 case TL_BETTER_ROADS:
1565 case TL_ORIGINAL:
1566 if (!IsRoadAllowedHere(t1, tile, target_dir)) return TownGrowthResult::SearchStopped;
1567
1568 DiagDirection source_dir = ReverseDiagDir(target_dir);
1569
1570 if (Chance16(1, 4)) {
1571 /* Randomize a new target dir */
1572 do target_dir = RandomDiagDir(); while (target_dir == source_dir);
1573 }
1574
1575 if (!IsRoadAllowedHere(t1, TileAddByDiagDir(tile, target_dir), target_dir)) {
1576 /* A road is not allowed to continue the randomized road,
1577 * return if the road we're trying to build is curved. */
1578 if (target_dir != ReverseDiagDir(source_dir)) return TownGrowthResult::SearchStopped;
1579
1580 /* Return if neither side of the new road is a house */
1584 }
1585
1586 /* That means that the road is only allowed if there is a house
1587 * at any side of the new road. */
1588 }
1589
1590 rcmd = DiagDirToRoadBits(target_dir) | DiagDirToRoadBits(source_dir);
1591 break;
1592 }
1593
1594 } else if (target_dir < DIAGDIR_END && !(cur_rb & DiagDirToRoadBits(ReverseDiagDir(target_dir)))) {
1596
1598
1599 /* Continue building on a partial road.
1600 * Should be always OK, so we only generate
1601 * the fitting RoadBits */
1602 switch (t1->layout) {
1603 default: NOT_REACHED();
1604
1605 case TL_3X3_GRID:
1606 case TL_2X2_GRID:
1607 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1608 break;
1609
1610 case TL_BETTER_ROADS:
1611 case TL_ORIGINAL:
1612 rcmd = DiagDirToRoadBits(ReverseDiagDir(target_dir));
1613 break;
1614 }
1615 } else {
1616 bool allow_house = true; // Value which decides if we want to construct a house
1617
1618 /* Reached a tunnel/bridge? Then continue at the other side of it, unless
1619 * it is the starting tile. Half the time, we stay on this side then.*/
1621 if (GetTunnelBridgeTransportType(tile) == TRANSPORT_ROAD && (target_dir != DIAGDIR_END || Chance16(1, 2))) {
1622 *tile_ptr = GetOtherTunnelBridgeEnd(tile);
1623 }
1625 }
1626
1627 /* Possibly extend the road in a direction.
1628 * Randomize a direction and if it has a road, bail out. */
1629 target_dir = RandomDiagDir();
1630 RoadBits target_rb = DiagDirToRoadBits(target_dir);
1631 TileIndex house_tile; // position of a possible house
1632
1633 if (cur_rb & target_rb) {
1634 /* If it's a road turn possibly build a house in a corner.
1635 * Use intersection with straight road as an indicator
1636 * that we randomised corner house position.
1637 * A turn (and we check for that later) always has only
1638 * one common bit with a straight road so it has the same
1639 * chance to be chosen as the house on the side of a road.
1640 */
1641 if ((cur_rb & ROAD_X) != target_rb) return TownGrowthResult::Continue;
1642
1643 /* Check whether it is a turn and if so determine
1644 * position of the corner tile */
1645 switch (cur_rb) {
1646 case ROAD_N:
1647 house_tile = TileAddByDir(tile, DIR_S);
1648 break;
1649 case ROAD_S:
1650 house_tile = TileAddByDir(tile, DIR_N);
1651 break;
1652 case ROAD_E:
1653 house_tile = TileAddByDir(tile, DIR_W);
1654 break;
1655 case ROAD_W:
1656 house_tile = TileAddByDir(tile, DIR_E);
1657 break;
1658 default:
1659 return TownGrowthResult::Continue; // not a turn
1660 }
1661 target_dir = DIAGDIR_END;
1662 } else {
1663 house_tile = TileAddByDiagDir(tile, target_dir);
1664 }
1665
1666 /* Don't walk into water. */
1667 if (HasTileWaterGround(house_tile)) return TownGrowthResult::Continue;
1668
1669 if (!IsValidTile(house_tile)) return TownGrowthResult::Continue;
1670
1672
1673 if (target_dir != DIAGDIR_END && TownAllowedToBuildRoads(modes)) {
1674 switch (t1->layout) {
1675 default: NOT_REACHED();
1676
1677 case TL_3X3_GRID: // Use 2x2 grid afterwards!
1678 if (GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir), modes)) {
1680 }
1681 [[fallthrough]];
1682
1683 case TL_2X2_GRID:
1684 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1685 allow_house = (rcmd & target_rb) == ROAD_NONE;
1686 break;
1687
1688 case TL_BETTER_ROADS: // Use original afterwards!
1689 if (GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir), modes)) {
1691 }
1692 [[fallthrough]];
1693
1694 case TL_ORIGINAL:
1695 /* Allow a house at the edge. 60% chance or
1696 * always ok if no road allowed. */
1697 rcmd = target_rb;
1698 allow_house = (!IsRoadAllowedHere(t1, house_tile, target_dir) || Chance16(6, 10));
1699 break;
1700 }
1701 }
1702
1703 allow_house &= RoadTypesAllowHouseHere(house_tile);
1704
1705 if (allow_house) {
1706 /* Build a house, but not if there already is a house there. */
1707 if (!IsTileType(house_tile, TileType::House)) {
1708 /* Level the land if possible */
1709 if (Chance16(1, 6)) LevelTownLand(house_tile);
1710
1711 /* And build a house.
1712 * Set result to -1 if we managed to build it. */
1713 if (TryBuildTownHouse(t1, house_tile, modes)) {
1715 }
1716 }
1717 return result;
1718 }
1719
1720 if (!TownCanGrowRoad(tile)) return result;
1721 }
1722
1723 /* Return if a water tile */
1725
1726 /* Make the roads look nicer */
1727 rcmd = CleanUpRoadBits(tile, rcmd);
1728 if (rcmd == ROAD_NONE) return TownGrowthResult::SearchStopped;
1729
1730 /* Only use the target direction for bridges and tunnels to ensure they're connected.
1731 * The target_dir is as computed previously according to town layout, so
1732 * it will match it perfectly. */
1733 if (GrowTownWithBridge(t1, tile, target_dir)) {
1735 }
1736 if (GrowTownWithTunnel(t1, tile, target_dir)) {
1738 }
1739
1740 if (GrowTownWithRoad(t1, tile, rcmd)) {
1742 }
1744}
1745
1754static bool CanFollowRoad(TileIndex tile, DiagDirection dir, TownExpandModes modes)
1755{
1756 TileIndex target_tile = tile + TileOffsByDiagDir(dir);
1757 if (!IsValidTile(target_tile)) return false;
1758 if (HasTileWaterGround(target_tile)) return false;
1759
1760 RoadBits target_rb = GetTownRoadBits(target_tile);
1761 if (TownAllowedToBuildRoads(modes)) {
1762 /* Check whether a road connection exists or can be build. */
1763 switch (GetTileType(target_tile)) {
1764 case TileType::Road:
1765 return target_rb != ROAD_NONE;
1766
1767 case TileType::Station:
1768 return IsDriveThroughStopTile(target_tile);
1769
1771 return GetTunnelBridgeTransportType(target_tile) == TRANSPORT_ROAD;
1772
1773 case TileType::House:
1774 case TileType::Industry:
1775 case TileType::Object:
1776 return false;
1777
1778 default:
1779 /* Checked for void and water earlier */
1780 return true;
1781 }
1782 } else {
1783 /* Check whether a road connection already exists,
1784 * and it leads somewhere else. */
1786 return (target_rb & back_rb) != 0 && (target_rb & ~back_rb) != 0;
1787 }
1788}
1789
1797static bool GrowTownAtRoad(Town *t, TileIndex tile, TownExpandModes modes)
1798{
1799 /* Special case.
1800 * @see GrowTownInTile Check the else if
1801 */
1802 DiagDirection target_dir = DIAGDIR_END; // The direction in which we want to extend the town
1803
1804 assert(tile < Map::Size());
1805
1806 /* Number of times to search.
1807 * Better roads, 2X2 and 3X3 grid grow quite fast so we give
1808 * them a little handicap. */
1809 int iterations;
1810 switch (t->layout) {
1811 case TL_BETTER_ROADS:
1812 iterations = 10 + t->cache.num_houses * 2 / 9;
1813 break;
1814
1815 case TL_3X3_GRID:
1816 case TL_2X2_GRID:
1817 iterations = 10 + t->cache.num_houses * 1 / 9;
1818 break;
1819
1820 default:
1821 iterations = 10 + t->cache.num_houses * 4 / 9;
1822 break;
1823 }
1824
1825 do {
1826 RoadBits cur_rb = GetTownRoadBits(tile); // The RoadBits of the current tile
1827
1828 /* Try to grow the town from this point */
1829 switch (GrowTownInTile(&tile, cur_rb, target_dir, t, modes)) {
1831 return true;
1833 iterations = 0;
1834 break;
1835 default:
1836 break;
1837 };
1838
1839 /* Exclude the source position from the bitmask
1840 * and return if no more road blocks available */
1841 if (IsValidDiagDirection(target_dir)) cur_rb &= ~DiagDirToRoadBits(ReverseDiagDir(target_dir));
1842 if (cur_rb == ROAD_NONE) return false;
1843
1845 /* Only build in the direction away from the tunnel or bridge. */
1846 target_dir = ReverseDiagDir(GetTunnelBridgeDirection(tile));
1847 } else {
1848 /* Select a random bit from the blockmask, walk a step
1849 * and continue the search from there. */
1850 do {
1851 if (cur_rb == ROAD_NONE) return false;
1852 RoadBits target_bits;
1853 do {
1854 target_dir = RandomDiagDir();
1855 target_bits = DiagDirToRoadBits(target_dir);
1856 } while (!(cur_rb & target_bits));
1857 cur_rb &= ~target_bits;
1858 } while (!CanFollowRoad(tile, target_dir, modes));
1859 }
1860 tile = TileAddByDiagDir(tile, target_dir);
1861
1862 if (IsTileType(tile, TileType::Road) && !IsRoadDepot(tile) && HasTileRoadType(tile, RTT_ROAD)) {
1863 /* Don't allow building over roads of other cities */
1864 if (IsRoadOwner(tile, RTT_ROAD, OWNER_TOWN) && Town::GetByTile(tile) != t) {
1865 return false;
1866 } else if (IsRoadOwner(tile, RTT_ROAD, OWNER_NONE) && _game_mode == GM_EDITOR) {
1867 /* If we are in the SE, and this road-piece has no town owner yet, it just found an
1868 * owner :) (happy happy happy road now) */
1870 SetTownIndex(tile, t->index);
1871 }
1872 }
1873
1874 /* Max number of times is checked. */
1875 } while (--iterations >= 0);
1876
1877 return false;
1878}
1879
1888{
1889 uint32_t r = Random();
1890 uint a = GB(r, 0, 2);
1891 uint b = GB(r, 8, 2);
1892 if (a == b) b ^= 2;
1893 return (RoadBits)((ROAD_NW << a) + (ROAD_NW << b));
1894}
1895
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, TileType::House) && IsTileFlat(tile)) {
1942 if (Command<Commands::LandscapeClear>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile).Succeeded()) {
1944 Command<Commands::BuildRoad>::Do({DoCommandFlag::Execute, DoCommandFlag::Auto}, tile, GenRandomRoadBits(), rt, DRD_NONE, t->index);
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.*/
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.Reset();
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 */
2054 t->grow_counter = t->index % Ticks::TOWN_GROWTH_TICKS;
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 */
2061 switch (_settings_game.game_creation.landscape) {
2064 break;
2065
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 {
2085 TownNameParams tnp(_settings_game.game_creation.town_name);
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
2124static CommandCost TownCanBePlacedHere(TileIndex tile, bool check_surrounding)
2125{
2126 /* Check if too close to the edge of map */
2127 if (DistanceFromEdge(tile) < 12) {
2128 return CommandCost(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB);
2129 }
2130
2131 /* Check distance to all other towns. */
2132 if (IsCloseToTown(tile, _settings_game.economy.town_min_distance)) {
2133 return CommandCost(STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN);
2134 }
2135
2136 /* Can only build on clear flat areas, possibly with trees. */
2137 if ((!IsTileType(tile, TileType::Clear) && !IsTileType(tile, TileType::Trees)) || !IsTileFlat(tile)) {
2138 return CommandCost(STR_ERROR_SITE_UNSUITABLE);
2139 }
2140
2141 /* We might want to make sure the town has enough room. */
2142 if (check_surrounding) {
2143 constexpr uint SEARCH_DIAMETER = 5; // Center tile of town + 2 tile radius.
2144 /* Half of the tiles in the search must be valid for the town to build upon. */
2145 constexpr uint VALID_TILE_GOAL = (SEARCH_DIAMETER * SEARCH_DIAMETER) / 2;
2146 uint counter = 0;
2147 int town_height = GetTileZ(tile);
2148 for (TileIndex t : SpiralTileSequence(tile, SEARCH_DIAMETER)) {
2149 if (counter == VALID_TILE_GOAL) break;
2150
2151 switch (GetTileType(t)) {
2152 case TileType::Clear:
2153 /* Don't allow rough tiles, as they are likely wetlands. */
2154 if (GetClearGround(t) == ClearGround::Rough) continue;
2155 break;
2156
2157 case TileType::Trees:
2158 /* Don't allow rough trees, as they are likely wetlands. */
2159 if (GetTreeGround(t) == TreeGround::Rough) continue;
2160 break;
2161
2162 default:
2163 continue;
2164 }
2165
2166 bool elevation_similar = (GetTileMaxZ(t) <= town_height + 1) && (GetTileZ(t) >= town_height - 1);
2167 if (elevation_similar) counter++;
2168 }
2169
2170 if (counter < VALID_TILE_GOAL) return CommandCost(STR_ERROR_SITE_UNSUITABLE);
2171 }
2172
2174}
2175
2181static bool IsUniqueTownName(const std::string &name)
2182{
2183 for (const Town *t : Town::Iterate()) {
2184 if (!t->name.empty() && t->name == name) return false;
2185 }
2186
2187 return true;
2188}
2189
2202std::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)
2203{
2204 TownNameParams par(_settings_game.game_creation.town_name);
2205
2206 if (size >= TSZ_END) return { CMD_ERROR, 0, TownID::Invalid() };
2207 if (layout >= NUM_TLS) return { CMD_ERROR, 0, TownID::Invalid() };
2208
2209 /* Some things are allowed only in the scenario editor and for game scripts. */
2210 if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY) {
2211 if (_settings_game.economy.found_town == TF_FORBIDDEN) return { CMD_ERROR, 0, TownID::Invalid() };
2212 if (size == TSZ_LARGE) return { CMD_ERROR, 0, TownID::Invalid() };
2213 if (random_location) return { CMD_ERROR, 0, TownID::Invalid() };
2214 if (_settings_game.economy.found_town != TF_CUSTOM_LAYOUT && layout != _settings_game.economy.town_layout) {
2215 return { CMD_ERROR, 0, TownID::Invalid() };
2216 }
2217 } else if (_current_company == OWNER_DEITY && random_location) {
2218 /* Random parameter is not allowed for Game Scripts. */
2219 return { CMD_ERROR, 0, TownID::Invalid() };
2220 }
2221
2222 if (text.empty()) {
2223 /* If supplied name is empty, townnameparts has to generate unique automatic name */
2224 if (!VerifyTownName(townnameparts, &par)) return { CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE), 0, TownID::Invalid() };
2225 } else {
2226 /* If name is not empty, it has to be unique custom name */
2227 if (Utf8StringLength(text) >= MAX_LENGTH_TOWN_NAME_CHARS) return { CMD_ERROR, 0, TownID::Invalid() };
2228 if (!IsUniqueTownName(text)) return { CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE), 0, TownID::Invalid() };
2229 }
2230
2231 /* Allocate town struct */
2232 if (!Town::CanAllocateItem()) return { CommandCost(STR_ERROR_TOO_MANY_TOWNS), 0, TownID::Invalid() };
2233
2234 if (!random_location) {
2235 CommandCost ret = TownCanBePlacedHere(tile, false);
2236 if (ret.Failed()) return { ret, 0, TownID::Invalid() };
2237 }
2238
2239 static const uint8_t price_mult[][TSZ_RANDOM + 1] = {{ 15, 25, 40, 25 }, { 20, 35, 55, 35 }};
2240 /* multidimensional arrays have to have defined length of non-first dimension */
2241 static_assert(lengthof(price_mult[0]) == 4);
2242
2244 uint8_t mult = price_mult[city][size];
2245
2246 cost.MultiplyCost(mult);
2247
2248 /* Create the town */
2249 TownID new_town = TownID::Invalid();
2250 if (flags.Test(DoCommandFlag::Execute)) {
2251 if (cost.GetCost() > GetAvailableMoneyForCommand()) {
2252 return { CommandCost(EXPENSES_OTHER), cost.GetCost(), TownID::Invalid() };
2253 }
2254
2255 Backup<bool> old_generating_world(_generating_world, true);
2257 Town *t;
2258 if (random_location) {
2259 t = CreateRandomTown(20, townnameparts, size, city, layout);
2260 } else {
2261 t = Town::Create(tile);
2262 DoCreateTown(t, tile, townnameparts, size, city, layout, true);
2263 }
2264
2266 old_generating_world.Restore();
2267
2268 if (t == nullptr) return { CommandCost(STR_ERROR_NO_SPACE_FOR_TOWN), 0, TownID::Invalid() };
2269
2270 new_town = t->index;
2271
2272 if (!text.empty()) {
2273 t->name = text;
2274 t->UpdateVirtCoord();
2275 }
2276
2277 if (_game_mode != GM_EDITOR) {
2278 /* 't' can't be nullptr since 'random' is false outside scenedit */
2279 assert(!random_location);
2280
2282 AddTileNewsItem(GetEncodedString(STR_NEWS_NEW_TOWN_UNSPONSORED, t->index), NewsType::IndustryOpen, tile);
2283 } else {
2284 std::string company_name = GetString(STR_COMPANY_NAME, _current_company);
2285 AddTileNewsItem(GetEncodedString(STR_NEWS_NEW_TOWN, company_name, t->index), NewsType::IndustryOpen, tile);
2286 }
2287 AI::BroadcastNewEvent(new ScriptEventTownFounded(t->index));
2288 Game::NewEvent(new ScriptEventTownFounded(t->index));
2289 }
2290 }
2291 return { cost, 0, new_town };
2292}
2293
2304{
2305 switch (layout) {
2306 case TL_2X2_GRID: return TileXY(TileX(tile) - TileX(tile) % 3, TileY(tile) - TileY(tile) % 3);
2307 case TL_3X3_GRID: return TileXY(TileX(tile) & ~3, TileY(tile) & ~3);
2308 default: return tile;
2309 }
2310}
2311
2322{
2323 switch (layout) {
2324 case TL_2X2_GRID: return TileX(tile) % 3 == 0 && TileY(tile) % 3 == 0;
2325 case TL_3X3_GRID: return TileX(tile) % 4 == 0 && TileY(tile) % 4 == 0;
2326 default: return true;
2327 }
2328}
2329
2343{
2344 for (auto coast : SpiralTileSequence(tile, 40)) {
2345 /* Find nearest land tile */
2346 if (!IsTileType(coast, TileType::Clear)) continue;
2347
2348 TileIndex furthest = INVALID_TILE;
2349 uint max_dist = 0;
2350 for (auto test : SpiralTileSequence(coast, 10)) {
2351 if (!IsTileType(test, TileType::Clear) || !IsTileFlat(test) || !IsTileAlignedToGrid(test, layout)) continue;
2352 if (TownCanBePlacedHere(test, true).Failed()) continue;
2353
2354 uint dist = GetClosestWaterDistance(test, true);
2355 if (dist > max_dist) {
2356 furthest = test;
2357 max_dist = dist;
2358 }
2359 }
2360 return furthest;
2361 }
2362
2363 /* if we get here just give up */
2364 return INVALID_TILE;
2365}
2366
2372{
2373 switch (_settings_game.game_creation.landscape) {
2378 default: NOT_REACHED();
2379 }
2380}
2381
2391static Town *CreateRandomTown(uint attempts, uint32_t townnameparts, TownSize size, bool city, TownLayout layout)
2392{
2393 assert(_game_mode == GM_EDITOR || _generating_world); // These are the preconditions for Commands::DeleteTown
2394
2395 if (!Town::CanAllocateItem()) return nullptr;
2396
2397 do {
2398 /* Generate a tile index not too close from the edge */
2399 TileIndex tile = AlignTileToGrid(RandomTile(), layout);
2400
2401 /* If we tried to place the town on water, find a suitable land tile nearby.
2402 * Otherwise, evaluate the land tile. */
2403 if (IsTileType(tile, TileType::Water)) {
2404 tile = FindNearestGoodCoastalTownSpot(tile, layout);
2405 if (tile == INVALID_TILE) continue;
2406 } else if (TownCanBePlacedHere(tile, true).Failed()) continue;
2407
2408 /* Allocate a town struct */
2409 Town *t = Town::Create(tile);
2410
2411 DoCreateTown(t, tile, townnameparts, size, city, layout, false);
2412
2413 /* if the population is still 0 at the point, then the
2414 * placement is so bad it couldn't grow at all */
2415 if (t->cache.population > 0) return t;
2416
2418 [[maybe_unused]] CommandCost rc = Command<Commands::DeleteTown>::Do(DoCommandFlag::Execute, t->index);
2419 cur_company.Restore();
2420 assert(rc.Succeeded());
2421
2422 /* We already know that we can allocate a single town when
2423 * entering this function. However, we create and delete
2424 * a town which "resets" the allocation checks. As such we
2425 * need to check again when assertions are enabled. */
2426 assert(Town::CanAllocateItem());
2427 } while (--attempts != 0);
2428
2429 return nullptr;
2430}
2431
2438{
2439 static const uint8_t num_initial_towns[4] = {5, 11, 23, 46}; // very low, low, normal, high
2440 if (_settings_game.difficulty.number_towns == static_cast<uint>(CUSTOM_TOWN_NUMBER_DIFFICULTY)) {
2441 return _settings_newgame.game_creation.custom_town_number;
2442 }
2443 return Map::ScaleBySize(num_initial_towns[_settings_game.difficulty.number_towns]);
2444}
2445
2453bool GenerateTowns(TownLayout layout, std::optional<uint> number)
2454{
2455 uint current_number = 0;
2456 uint total;
2457 if (number.has_value()) {
2458 total = number.value();
2459 } else if (_settings_game.difficulty.number_towns == static_cast<uint>(CUSTOM_TOWN_NUMBER_DIFFICULTY)) {
2460 total = GetDefaultTownsForMapSize();
2461 } else {
2462 total = Map::ScaleByLandProportion(GetDefaultTownsForMapSize() + (Random() & 7));
2463 }
2464
2465 total = Clamp<uint>(total, 1, TownPool::MAX_SIZE);
2466 uint32_t townnameparts;
2467 TownNames town_names;
2468
2470
2471 /* Pre-populate the town names list with the names of any towns already on the map */
2472 for (const Town *town : Town::Iterate()) {
2473 town_names.insert(town->GetCachedName());
2474 }
2475
2476 /* Randomised offset for city status. This means with e.g. 1-in-4 towns being cities, a map with 10 towns
2477 * may have 2 or 3 cities, instead of always 3. */
2478 uint city_random_offset = _settings_game.economy.larger_towns == 0 ? 0 : (Random() % _settings_game.economy.larger_towns);
2479
2480 /* First attempt will be made at creating the suggested number of towns.
2481 * Note that this is really a suggested value, not a required one.
2482 * We would not like the system to lock up just because the user wanted 100 cities on a 64*64 map, would we? */
2483 do {
2484 bool city = (_settings_game.economy.larger_towns != 0 && ((city_random_offset + current_number) % _settings_game.economy.larger_towns) == 0);
2486 /* Get a unique name for the town. */
2487 if (!GenerateTownName(_random, &townnameparts, &town_names)) continue;
2488 /* try 20 times to create a random-sized town for the first loop. */
2489 if (CreateRandomTown(20, townnameparts, TSZ_RANDOM, city, layout) != nullptr) current_number++; // If creation was successful, raise a flag.
2490 } while (--total);
2491
2492 town_names.clear();
2493
2494 /* Build the town k-d tree again to make sure it's well balanced */
2495 RebuildTownKdtree();
2496
2497 if (current_number != 0) return true;
2498
2499 /* If current_number is still zero at this point, it means that not a single town has been created.
2500 * So give it a last try, but now more aggressive */
2501 if (GenerateTownName(_random, &townnameparts) &&
2502 CreateRandomTown(10000, townnameparts, TSZ_RANDOM, _settings_game.economy.larger_towns != 0, layout) != nullptr) {
2503 return true;
2504 }
2505
2506 /* If there are no towns at all and we are generating new game, bail out */
2507 if (Town::GetNumItems() == 0 && _game_mode != GM_EDITOR) {
2508 ShowErrorMessage(GetEncodedString(STR_ERROR_COULD_NOT_CREATE_TOWN), {}, WL_CRITICAL);
2509 }
2510
2511 return false; // we are still without a town? we failed, simply
2512}
2513
2514
2522{
2523 uint dist = DistanceSquare(tile, t->xy);
2524
2525 if (t->fund_buildings_months != 0 && dist <= 25) return HouseZone::TownCentre;
2526
2527 HouseZone smallest = HouseZone::TownEdge;
2528 for (HouseZone i : HZ_ZONE_ALL) {
2529 if (dist < t->cache.squared_town_zone_radius[to_underlying(i)]) smallest = i;
2530 }
2531
2532 return smallest;
2533}
2534
2546static inline void ClearMakeHouseTile(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool is_protected)
2547{
2548 [[maybe_unused]] CommandCost cc = Command<Commands::LandscapeClear>::Do({DoCommandFlag::Execute, DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile);
2549 assert(cc.Succeeded());
2550
2551 IncreaseBuildingCount(t, type);
2552 MakeHouseTile(tile, t->index, counter, stage, type, random_bits, is_protected);
2553 if (HouseSpec::Get(type)->building_flags.Test(BuildingFlag::IsAnimated)) AddAnimatedTile(tile, false);
2554
2555 MarkTileDirtyByTile(tile);
2556}
2557
2558
2570static void MakeTownHouse(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool is_protected)
2571{
2572 BuildingFlags size = HouseSpec::Get(type)->building_flags;
2573
2574 ClearMakeHouseTile(tile, t, counter, stage, type, random_bits, is_protected);
2575 if (size.Any(BUILDING_2_TILES_Y)) ClearMakeHouseTile(tile + TileDiffXY(0, 1), t, counter, stage, ++type, random_bits, is_protected);
2576 if (size.Any(BUILDING_2_TILES_X)) ClearMakeHouseTile(tile + TileDiffXY(1, 0), t, counter, stage, ++type, random_bits, is_protected);
2577 if (size.Any(BUILDING_HAS_4_TILES)) ClearMakeHouseTile(tile + TileDiffXY(1, 1), t, counter, stage, ++type, random_bits, is_protected);
2578
2579 ForAllStationsAroundTiles(TileArea(tile, size.Any(BUILDING_2_TILES_X) ? 2 : 1, size.Any(BUILDING_2_TILES_Y) ? 2 : 1), [t](Station *st, TileIndex) {
2580 t->stations_near.insert(st);
2581 return true;
2582 });
2583}
2584
2585
2592static inline bool CanBuildHouseHere(TileIndex tile, bool noslope)
2593{
2594 /* cannot build on these slopes... */
2595 Slope slope = GetTileSlope(tile);
2596 if ((noslope && slope != SLOPE_FLAT) || IsSteepSlope(slope)) return false;
2597
2598 /* at least one RoadTypes allow building the house here? */
2599 if (!RoadTypesAllowHouseHere(tile)) return false;
2600
2601 /* building under a bridge? */
2602 if (IsBridgeAbove(tile)) return false;
2603
2604 /* can we clear the land? */
2605 return Command<Commands::LandscapeClear>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, tile).Succeeded();
2606}
2607
2608
2617static inline bool CheckBuildHouseSameZ(TileIndex tile, int z, bool noslope)
2618{
2619 if (!CanBuildHouseHere(tile, noslope)) return false;
2620
2621 /* if building on slopes is allowed, there will be flattening foundation (to tile max z) */
2622 if (GetTileMaxZ(tile) != z) return false;
2623
2624 return true;
2625}
2626
2627
2636static bool CheckFree2x2Area(TileIndex tile, int z, bool noslope)
2637{
2638 /* we need to check this tile too because we can be at different tile now */
2639 if (!CheckBuildHouseSameZ(tile, z, noslope)) return false;
2640
2641 for (DiagDirection d = DIAGDIR_SE; d < DIAGDIR_END; d++) {
2642 tile += TileOffsByDiagDir(d);
2643 if (!CheckBuildHouseSameZ(tile, z, noslope)) return false;
2644 }
2645
2646 return true;
2647}
2648
2649
2658static inline bool TownLayoutAllowsHouseHere(Town *t, TileIndex tile, TownExpandModes modes)
2659{
2660 if (!modes.Test(TownExpandMode::Buildings)) return false;
2661
2662 /* Allow towns everywhere when we don't build roads */
2663 if (!TownAllowedToBuildRoads(modes)) return true;
2664
2665 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
2666
2667 switch (t->layout) {
2668 case TL_2X2_GRID:
2669 if ((grid_pos.x % 3) == 0 || (grid_pos.y % 3) == 0) return false;
2670 break;
2671
2672 case TL_3X3_GRID:
2673 if ((grid_pos.x % 4) == 0 || (grid_pos.y % 4) == 0) return false;
2674 break;
2675
2676 default:
2677 break;
2678 }
2679
2680 return true;
2681}
2682
2683
2692static inline bool TownLayoutAllows2x2HouseHere(Town *t, TileIndex tile, TownExpandModes modes)
2693{
2694 if (!modes.Test(TownExpandMode::Buildings)) return false;
2695
2696 /* Allow towns everywhere when we don't build roads */
2697 if (!TownAllowedToBuildRoads(modes)) return true;
2698
2699 /* Compute relative position of tile. (Positive offsets are towards north) */
2700 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
2701
2702 switch (t->layout) {
2703 case TL_2X2_GRID:
2704 grid_pos.x %= 3;
2705 grid_pos.y %= 3;
2706 if ((grid_pos.x != 2 && grid_pos.x != -1) ||
2707 (grid_pos.y != 2 && grid_pos.y != -1)) return false;
2708 break;
2709
2710 case TL_3X3_GRID:
2711 if ((grid_pos.x & 3) < 2 || (grid_pos.y & 3) < 2) return false;
2712 break;
2713
2714 default:
2715 break;
2716 }
2717
2718 return true;
2719}
2720
2721
2732static bool CheckTownBuild2House(TileIndex *tile, Town *t, int maxz, bool noslope, DiagDirection second, TownExpandModes modes)
2733{
2734 /* 'tile' is already checked in BuildTownHouse() - CanBuildHouseHere() and slope test */
2735
2736 TileIndex tile2 = *tile + TileOffsByDiagDir(second);
2737 if (TownLayoutAllowsHouseHere(t, tile2, modes) && CheckBuildHouseSameZ(tile2, maxz, noslope)) return true;
2738
2739 tile2 = *tile + TileOffsByDiagDir(ReverseDiagDir(second));
2740 if (TownLayoutAllowsHouseHere(t, tile2, modes) && CheckBuildHouseSameZ(tile2, maxz, noslope)) {
2741 *tile = tile2;
2742 return true;
2743 }
2744
2745 return false;
2746}
2747
2748
2758static bool CheckTownBuild2x2House(TileIndex *tile, Town *t, int maxz, bool noslope, TownExpandModes modes)
2759{
2760 TileIndex tile2 = *tile;
2761
2762 for (DiagDirection d = DIAGDIR_SE;; d++) { // 'd' goes through DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_END
2763 if (TownLayoutAllows2x2HouseHere(t, tile2, modes) && CheckFree2x2Area(tile2, maxz, noslope)) {
2764 *tile = tile2;
2765 return true;
2766 }
2767 if (d == DIAGDIR_END) break;
2768 tile2 += TileOffsByDiagDir(ReverseDiagDir(d)); // go clockwise
2769 }
2770
2771 return false;
2772}
2773
2784static void BuildTownHouse(Town *t, TileIndex tile, const HouseSpec *hs, HouseID house, uint8_t random_bits, bool house_completed, bool is_protected)
2785{
2786 /* build the house */
2787 t->cache.num_houses++;
2788
2789 uint8_t construction_counter = 0;
2790 uint8_t construction_stage = 0;
2791
2792 if (_generating_world || _game_mode == GM_EDITOR || house_completed) {
2793 uint32_t construction_random = Random();
2794
2795 construction_stage = TOWN_HOUSE_COMPLETED;
2796 if (_generating_world && !hs->extra_flags.Test(HouseExtraFlag::BuildingIsHistorical) && Chance16(1, 7)) construction_stage = GB(construction_random, 0, 2);
2797
2798 if (construction_stage == TOWN_HOUSE_COMPLETED) {
2800 } else {
2801 construction_counter = GB(construction_random, 2, 2);
2802 }
2803 }
2804
2805 MakeTownHouse(tile, t, construction_counter, construction_stage, house, random_bits, is_protected);
2808
2809 BuildingFlags size = hs->building_flags;
2810
2811 TriggerHouseAnimation_ConstructionStageChanged(tile, true);
2812 if (size.Any(BUILDING_2_TILES_Y)) TriggerHouseAnimation_ConstructionStageChanged(tile + TileDiffXY(0, 1), true);
2813 if (size.Any(BUILDING_2_TILES_X)) TriggerHouseAnimation_ConstructionStageChanged(tile + TileDiffXY(1, 0), true);
2814 if (size.Any(BUILDING_HAS_4_TILES)) TriggerHouseAnimation_ConstructionStageChanged(tile + TileDiffXY(1, 1), true);
2815}
2816
2824static bool TryBuildTownHouse(Town *t, TileIndex tile, TownExpandModes modes)
2825{
2826 /* forbidden building here by town layout */
2827 if (!TownLayoutAllowsHouseHere(t, tile, modes)) return false;
2828
2829 /* no house allowed at all, bail out */
2830 if (!CanBuildHouseHere(tile, false)) return false;
2831
2832 Slope slope = GetTileSlope(tile);
2833 int maxz = GetTileMaxZ(tile);
2834
2835 /* Get the town zone type of the current tile, as well as the climate.
2836 * This will allow to easily compare with the specs of the new house to build */
2837 HouseZones zones = GetTownRadiusGroup(t, tile);
2838
2839 switch (_settings_game.game_creation.landscape) {
2844 }
2845
2846 /* bits 0-4 are used
2847 * bits 11-15 are used
2848 * bits 5-10 are not used. */
2849 static std::vector<std::pair<HouseID, uint>> probs;
2850 probs.clear();
2851
2852 uint probability_max = 0;
2853
2854 /* Generate a list of all possible houses that can be built. */
2855 for (const auto &hs : HouseSpec::Specs()) {
2856 /* Verify that the candidate house spec matches the current tile status */
2857 if (!hs.building_availability.All(zones) || !hs.enabled || hs.grf_prop.override_id != INVALID_HOUSE_ID) continue;
2858
2859 /* Don't let these counters overflow. Global counters are 32bit, there will never be that many houses. */
2860 if (hs.class_id != HOUSE_NO_CLASS) {
2861 /* id_count is always <= class_count, so it doesn't need to be checked */
2862 if (t->cache.building_counts.class_count[hs.class_id] == UINT16_MAX) continue;
2863 } else {
2864 /* If the house has no class, check id_count instead */
2865 if (t->cache.building_counts.id_count[hs.Index()] == UINT16_MAX) continue;
2866 }
2867
2868 uint cur_prob = hs.probability;
2869 probability_max += cur_prob;
2870 probs.emplace_back(hs.Index(), cur_prob);
2871 }
2872
2873 TileIndex base_tile = tile;
2874
2875 while (probability_max > 0) {
2876 /* Building a multitile building can change the location of tile.
2877 * The building would still be built partially on that tile, but
2878 * its northern tile would be elsewhere. However, if the callback
2879 * fails we would be basing further work from the changed tile.
2880 * So a next 1x1 tile building could be built on the wrong tile. */
2881 tile = base_tile;
2882
2883 uint r = RandomRange(probability_max);
2884 uint i;
2885 for (i = 0; i < probs.size(); i++) {
2886 if (probs[i].second > r) break;
2887 r -= probs[i].second;
2888 }
2889
2890 HouseID house = probs[i].first;
2891 probability_max -= probs[i].second;
2892
2893 /* remove tested house from the set */
2894 probs[i] = probs.back();
2895 probs.pop_back();
2896
2897 const HouseSpec *hs = HouseSpec::Get(house);
2898
2899 if (!_generating_world && _game_mode != GM_EDITOR && hs->extra_flags.Test(HouseExtraFlag::BuildingIsHistorical)) {
2900 continue;
2901 }
2902
2904
2905 /* Special houses that there can be only one of. */
2906 TownFlags oneof{};
2907
2909 oneof.Set(TownFlag::HasChurch);
2912 }
2913
2914 if (t->flags.Any(oneof)) continue;
2915
2916 /* Make sure there is no slope? */
2917 bool noslope = hs->building_flags.Test(BuildingFlag::NotSloped);
2918 if (noslope && slope != SLOPE_FLAT) continue;
2919
2921 if (!CheckTownBuild2x2House(&tile, t, maxz, noslope, modes)) continue;
2922 } else if (hs->building_flags.Test(BuildingFlag::Size2x1)) {
2923 if (!CheckTownBuild2House(&tile, t, maxz, noslope, DIAGDIR_SW, modes)) continue;
2924 } else if (hs->building_flags.Test(BuildingFlag::Size1x2)) {
2925 if (!CheckTownBuild2House(&tile, t, maxz, noslope, DIAGDIR_SE, modes)) continue;
2926 } else {
2927 /* 1x1 house checks are already done */
2928 }
2929
2930 uint8_t random_bits = Random();
2931
2933 uint16_t callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile, {}, true, random_bits);
2934 if (callback_res != CALLBACK_FAILED && !Convert8bitBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_ALLOW_CONSTRUCTION, callback_res)) continue;
2935 }
2936
2937 /* Special houses that there can be only one of. */
2938 t->flags.Set(oneof);
2939
2940 BuildTownHouse(t, tile, hs, house, random_bits, false, hs->extra_flags.Test(HouseExtraFlag::BuildingIsProtected));
2941
2942 return true;
2943 }
2944
2945 return false;
2946}
2947
2957CommandCost CmdPlaceHouse(DoCommandFlags flags, TileIndex tile, HouseID house, bool is_protected, bool replace)
2958{
2959 if (_game_mode != GM_EDITOR && _settings_game.economy.place_houses == PlaceHouses::Forbidden) return CMD_ERROR;
2960
2961 if (Town::GetNumItems() == 0) return CommandCost(STR_ERROR_MUST_FOUND_TOWN_FIRST);
2962
2963 if (static_cast<size_t>(house) >= HouseSpec::Specs().size()) return CMD_ERROR;
2964 const HouseSpec *hs = HouseSpec::Get(house);
2965 if (!hs->enabled) return CMD_ERROR;
2966
2967 int maxz = GetTileMaxZ(tile);
2968
2969 /* Check each tile of a multi-tile house. */
2970 TileArea ta(tile, 1, 1);
2971 if (hs->building_flags.Test(BuildingFlag::Size2x2)) ta.Add(TileAddXY(tile, 1, 1));
2974
2975 for (const TileIndex subtile : ta) {
2976 /* Houses cannot be built on steep slopes. */
2977 Slope slope = GetTileSlope(subtile);
2978 if (IsSteepSlope(slope)) return CommandCost(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
2979
2980 /* Houses cannot be built under bridges. */
2981 if (IsBridgeAbove(subtile)) return CommandCost(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
2982
2983 /* Make sure there is no slope? */
2984 bool noslope = hs->building_flags.Test(BuildingFlag::NotSloped);
2985 if (noslope && slope != SLOPE_FLAT) return CommandCost(STR_ERROR_FLAT_LAND_REQUIRED);
2986
2987 /* All tiles of a multi-tile house must have the same z-level. */
2988 if (GetTileMaxZ(subtile) != maxz) return CommandCost(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
2989
2990 /* We might be replacing an existing house, otherwise check if we can clear land. */
2991 if (!(replace && GetTileType(subtile) == TileType::House)) {
2992 CommandCost cost = Command<Commands::LandscapeClear>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, subtile);
2993 if (!cost.Succeeded()) return cost;
2994 }
2995 }
2996
2997 if (flags.Test(DoCommandFlag::Execute)) {
2998 /* If replacing, clear any existing houses first. */
2999 if (replace) {
3000 for (const TileIndex &subtile : ta) {
3001 if (GetTileType(subtile) == TileType::House) ClearTownHouse(Town::GetByTile(subtile), subtile);
3002 }
3003 }
3004
3005 Town *t = ClosestTownFromTile(tile, UINT_MAX);
3006 bool house_completed = _settings_game.economy.place_houses == PlaceHouses::AllowedConstructed;
3007 BuildTownHouse(t, tile, hs, house, Random(), house_completed, is_protected);
3008 }
3009
3010 return CommandCost();
3011}
3012
3024CommandCost CmdPlaceHouseArea(DoCommandFlags flags, TileIndex tile, TileIndex start_tile, HouseID house, bool is_protected, bool replace, bool diagonal)
3025{
3026 if (start_tile >= Map::Size()) return CMD_ERROR;
3027
3028 if (_game_mode != GM_EDITOR && _settings_game.economy.place_houses == PlaceHouses::Forbidden) return CMD_ERROR;
3029
3030 if (Town::GetNumItems() == 0) return CommandCost(STR_ERROR_MUST_FOUND_TOWN_FIRST);
3031
3032 if (static_cast<size_t>(house) >= HouseSpec::Specs().size()) return CMD_ERROR;
3033 const HouseSpec *hs = HouseSpec::Get(house);
3034 if (!hs->enabled) return CMD_ERROR;
3035
3036 /* Only allow placing an area of 1x1 houses. */
3038
3039 /* Use the built object limit to rate limit house placement. */
3041 int limit = (c == nullptr ? INT32_MAX : GB(c->build_object_limit, 16, 16));
3042
3043 CommandCost last_error = CMD_ERROR;
3044 bool had_success = false;
3045
3046 std::unique_ptr<TileIterator> iter = TileIterator::Create(tile, start_tile, diagonal);
3047 for (; *iter != INVALID_TILE; ++(*iter)) {
3048 TileIndex t = *iter;
3049 CommandCost ret = Command<Commands::PlaceHouse>::Do(DoCommandFlags{flags}.Reset(DoCommandFlag::Execute), t, house, is_protected, replace);
3050
3051 /* If we've reached the limit, stop building (or testing). */
3052 if (c != nullptr && limit-- <= 0) break;
3053
3054 if (ret.Failed()) {
3055 last_error = std::move(ret);
3056 continue;
3057 }
3058
3059 if (flags.Test(DoCommandFlag::Execute)) Command<Commands::PlaceHouse>::Do(flags, t, house, is_protected, replace);
3060 had_success = true;
3061 }
3062
3063 return had_success ? CommandCost{} : last_error;
3064}
3065
3072static void DoClearTownHouseHelper(TileIndex tile, Town *t, HouseID house)
3073{
3074 assert(IsTileType(tile, TileType::House));
3075 DecreaseBuildingCount(t, house);
3076 DoClearSquare(tile);
3077
3078 DeleteNewGRFInspectWindow(GSF_HOUSES, tile.base());
3079}
3080
3089{
3090 if (house >= 3) { // house id 0,1,2 MUST be single tile houses, or this code breaks.
3091 if (HouseSpec::Get(house - 1)->building_flags.Test(BuildingFlag::Size2x1)) {
3092 house--;
3093 return TileDiffXY(-1, 0);
3094 } else if (HouseSpec::Get(house - 1)->building_flags.Any(BUILDING_2_TILES_Y)) {
3095 house--;
3096 return TileDiffXY(0, -1);
3097 } else if (HouseSpec::Get(house - 2)->building_flags.Any(BUILDING_HAS_4_TILES)) {
3098 house -= 2;
3099 return TileDiffXY(-1, 0);
3100 } else if (HouseSpec::Get(house - 3)->building_flags.Any(BUILDING_HAS_4_TILES)) {
3101 house -= 3;
3102 return TileDiffXY(-1, -1);
3103 }
3104 }
3105 return TileDiffXY(0, 0);
3106}
3107
3114{
3115 assert(IsTileType(tile, TileType::House));
3116
3117 HouseID house = GetHouseType(tile);
3118
3119 /* The northernmost tile of the house is the main house. */
3120 tile += GetHouseNorthPart(house);
3121
3122 const HouseSpec *hs = HouseSpec::Get(house);
3123
3124 /* Remove population from the town if the house is finished. */
3125 if (IsHouseCompleted(tile)) {
3127 }
3128
3129 t->cache.num_houses--;
3130
3131 /* Clear flags for houses that only may exist once/town. */
3136 }
3137
3138 /* Do the actual clearing of tiles */
3139 DoClearTownHouseHelper(tile, t, house);
3140 if (hs->building_flags.Any(BUILDING_2_TILES_Y)) DoClearTownHouseHelper(tile + TileDiffXY(0, 1), t, ++house);
3141 if (hs->building_flags.Any(BUILDING_2_TILES_X)) DoClearTownHouseHelper(tile + TileDiffXY(1, 0), t, ++house);
3142 if (hs->building_flags.Any(BUILDING_HAS_4_TILES)) DoClearTownHouseHelper(tile + TileDiffXY(1, 1), t, ++house);
3143
3145
3147}
3148
3156CommandCost CmdRenameTown(DoCommandFlags flags, TownID town_id, const std::string &text)
3157{
3158 Town *t = Town::GetIfValid(town_id);
3159 if (t == nullptr) return CMD_ERROR;
3160
3161 bool reset = text.empty();
3162
3163 if (!reset) {
3165 if (!IsUniqueTownName(text)) return CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE);
3166 }
3167
3168 if (flags.Test(DoCommandFlag::Execute)) {
3169 t->cached_name.clear();
3170 if (reset) {
3171 t->name.clear();
3172 } else {
3173 t->name = text;
3174 }
3175
3176 t->UpdateVirtCoord();
3177 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_RESORT);
3178 ClearAllStationCachedNames();
3179 ClearAllIndustryCachedNames();
3181 }
3182 return CommandCost();
3183}
3184
3191{
3192 for (const CargoSpec *cs : CargoSpec::Iterate()) {
3193 if (cs->town_acceptance_effect == effect) return cs;
3194 }
3195 return nullptr;
3196}
3197
3206CommandCost CmdTownCargoGoal(DoCommandFlags flags, TownID town_id, TownAcceptanceEffect tae, uint32_t goal)
3207{
3208 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3209
3210 if (tae < TAE_BEGIN || tae >= TAE_END) return CMD_ERROR;
3211
3212 Town *t = Town::GetIfValid(town_id);
3213 if (t == nullptr) return CMD_ERROR;
3214
3215 /* Validate if there is a cargo which is the requested TownEffect */
3217 if (cargo == nullptr) return CMD_ERROR;
3218
3219 if (flags.Test(DoCommandFlag::Execute)) {
3220 t->goal[tae] = goal;
3223 }
3224
3225 return CommandCost();
3226}
3227
3235CommandCost CmdTownSetText(DoCommandFlags flags, TownID town_id, const EncodedString &text)
3236{
3237 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3238 Town *t = Town::GetIfValid(town_id);
3239 if (t == nullptr) return CMD_ERROR;
3240
3241 if (flags.Test(DoCommandFlag::Execute)) {
3242 t->text.clear();
3243 if (!text.empty()) t->text = text;
3245 }
3246
3247 return CommandCost();
3248}
3249
3257CommandCost CmdTownGrowthRate(DoCommandFlags flags, TownID town_id, uint16_t growth_rate)
3258{
3259 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3260
3261 Town *t = Town::GetIfValid(town_id);
3262 if (t == nullptr) return CMD_ERROR;
3263
3264 if (flags.Test(DoCommandFlag::Execute)) {
3265 if (growth_rate == 0) {
3266 /* Just clear the flag, UpdateTownGrowth will determine a proper growth rate */
3268 } else {
3269 uint old_rate = t->growth_rate;
3270 if (t->grow_counter >= old_rate) {
3271 /* This also catches old_rate == 0 */
3272 t->grow_counter = growth_rate;
3273 } else {
3274 /* Scale grow_counter, so half finished houses stay half finished */
3275 t->grow_counter = t->grow_counter * growth_rate / old_rate;
3276 }
3277 t->growth_rate = growth_rate;
3279 }
3282 }
3283
3284 return CommandCost();
3285}
3286
3295CommandCost CmdTownRating(DoCommandFlags flags, TownID town_id, CompanyID company_id, int16_t rating)
3296{
3297 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3298
3299 Town *t = Town::GetIfValid(town_id);
3300 if (t == nullptr) return CMD_ERROR;
3301
3302 if (!Company::IsValidID(company_id)) return CMD_ERROR;
3303
3304 int16_t new_rating = Clamp(rating, RATING_MINIMUM, RATING_MAXIMUM);
3305 if (flags.Test(DoCommandFlag::Execute)) {
3306 t->ratings[company_id] = new_rating;
3308 }
3309
3310 return CommandCost();
3311}
3312
3321CommandCost CmdExpandTown(DoCommandFlags flags, TownID town_id, uint32_t grow_amount, TownExpandModes modes)
3322{
3323 if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY) return CMD_ERROR;
3324 if (modes.None()) return CMD_ERROR;
3325 Town *t = Town::GetIfValid(town_id);
3326 if (t == nullptr) return CMD_ERROR;
3327
3328 if (flags.Test(DoCommandFlag::Execute)) {
3329 /* The more houses, the faster we grow */
3330 if (grow_amount == 0) {
3331 uint amount = RandomRange(ClampTo<uint16_t>(t->cache.num_houses / 10)) + 3;
3332 t->cache.num_houses += amount;
3334
3335 uint n = amount * 10;
3336 do GrowTown(t, modes); while (--n);
3337
3338 t->cache.num_houses -= amount;
3339 } else {
3340 for (; grow_amount > 0; grow_amount--) {
3341 /* Try several times to grow, as we are really suppose to grow */
3342 for (uint i = 0; i < 25; i++) if (GrowTown(t, modes)) break;
3343 }
3344 }
3346
3348 }
3349
3350 return CommandCost();
3351}
3352
3359CommandCost CmdDeleteTown(DoCommandFlags flags, TownID town_id)
3360{
3361 if (_game_mode != GM_EDITOR && !_generating_world) return CMD_ERROR;
3362 Town *t = Town::GetIfValid(town_id);
3363 if (t == nullptr) return CMD_ERROR;
3364
3365 /* Stations refer to towns. */
3366 for (const Station *st : Station::Iterate()) {
3367 if (st->town == t) {
3368 /* Non-oil rig stations are always a problem. */
3369 if (!st->facilities.Test(StationFacility::Airport) || st->airport.type != AT_OILRIG) return CMD_ERROR;
3370 /* We can only automatically delete oil rigs *if* there's no vehicle on them. */
3371 CommandCost ret = Command<Commands::LandscapeClear>::Do(flags, st->airport.tile);
3372 if (ret.Failed()) return ret;
3373 }
3374 }
3375
3376 /* Waypoints refer to towns. */
3377 for (const Waypoint *wp : Waypoint::Iterate()) {
3378 if (wp->town == t) return CMD_ERROR;
3379 }
3380
3381 /* Depots refer to towns. */
3382 for (const Depot *d : Depot::Iterate()) {
3383 if (d->town == t) return CMD_ERROR;
3384 }
3385
3386 /* Check all tiles for town ownership. First check for bridge tiles, as
3387 * these do not directly have an owner so we need to check adjacent
3388 * tiles. This won't work correctly in the same loop if the adjacent
3389 * tile was already deleted earlier in the loop. */
3390 for (const auto current_tile : Map::Iterate()) {
3391 if (IsTileType(current_tile, TileType::TunnelBridge) && TestTownOwnsBridge(current_tile, t)) {
3392 CommandCost ret = Command<Commands::LandscapeClear>::Do(flags, current_tile);
3393 if (ret.Failed()) return ret;
3394 }
3395 }
3396
3397 /* Check all remaining tiles for town ownership. */
3398 for (const auto current_tile : Map::Iterate()) {
3399 bool try_clear = false;
3400 switch (GetTileType(current_tile)) {
3401 case TileType::Road:
3402 try_clear = HasTownOwnedRoad(current_tile) && GetTownIndex(current_tile) == t->index;
3403 break;
3404
3405 case TileType::House:
3406 try_clear = GetTownIndex(current_tile) == t->index;
3407 break;
3408
3409 case TileType::Industry:
3410 try_clear = Industry::GetByTile(current_tile)->town == t;
3411 break;
3412
3413 case TileType::Object:
3414 if (Town::GetNumItems() == 1) {
3415 /* No towns will be left, remove it! */
3416 try_clear = true;
3417 } else {
3418 Object *o = Object::GetByTile(current_tile);
3419 if (o->town == t) {
3420 if (o->type == OBJECT_STATUE) {
3421 /* Statue... always remove. */
3422 try_clear = true;
3423 } else {
3424 /* Tell to find a new town. */
3425 if (flags.Test(DoCommandFlag::Execute)) o->town = nullptr;
3426 }
3427 }
3428 }
3429 break;
3430
3431 default:
3432 break;
3433 }
3434 if (try_clear) {
3435 CommandCost ret = Command<Commands::LandscapeClear>::Do(flags, current_tile);
3436 if (ret.Failed()) return ret;
3437 }
3438 }
3439
3440 /* The town destructor will delete the other things related to the town. */
3441 if (flags.Test(DoCommandFlag::Execute)) {
3442 _town_kdtree.Remove(t->index);
3443 if (t->cache.sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeTown(t->index));
3444 delete t;
3445 }
3446
3447 return CommandCost();
3448}
3449
3456{
3461 static const uint8_t town_action_costs[] = {
3462 2, 4, 9, 35, 48, 53, 117, 175
3463 };
3464 static_assert(std::size(town_action_costs) == to_underlying(TownAction::End));
3465
3466 assert(to_underlying(action) < std::size(town_action_costs));
3467 return town_action_costs[to_underlying(action)];
3468}
3469
3476static CommandCost TownActionAdvertiseSmall(Town *t, DoCommandFlags flags)
3477{
3478 if (flags.Test(DoCommandFlag::Execute)) {
3480 }
3481 return CommandCost();
3482}
3483
3490static CommandCost TownActionAdvertiseMedium(Town *t, DoCommandFlags flags)
3491{
3492 if (flags.Test(DoCommandFlag::Execute)) {
3494 }
3495 return CommandCost();
3496}
3497
3504static CommandCost TownActionAdvertiseLarge(Town *t, DoCommandFlags flags)
3505{
3506 if (flags.Test(DoCommandFlag::Execute)) {
3508 }
3509 return CommandCost();
3510}
3511
3518static CommandCost TownActionRoadRebuild(Town *t, DoCommandFlags flags)
3519{
3520 /* Check if the company is allowed to fund new roads. */
3521 if (!_settings_game.economy.fund_roads) return CMD_ERROR;
3522
3523 if (flags.Test(DoCommandFlag::Execute)) {
3524 t->road_build_months = 6;
3525
3526 std::string company_name = GetString(STR_COMPANY_NAME, _current_company);
3527
3529 GetEncodedString(TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_ROAD_REBUILDING_MINUTES : STR_NEWS_ROAD_REBUILDING_MONTHS, t->index, company_name),
3530 NewsType::General, NewsStyle::Normal, {}, t->index);
3531 AI::BroadcastNewEvent(new ScriptEventRoadReconstruction(_current_company, t->index));
3532 Game::NewEvent(new ScriptEventRoadReconstruction(_current_company, t->index));
3533 }
3534 return CommandCost();
3535}
3536
3542static bool CheckClearTile(TileIndex tile)
3543{
3545 CommandCost r = Command<Commands::LandscapeClear>::Do({}, tile);
3546 cur_company.Restore();
3547 return r.Succeeded();
3548}
3549
3557static CommandCost TownActionBuildStatue(Town *t, DoCommandFlags flags)
3558{
3559 if (!Object::CanAllocateItem()) return CommandCost(STR_ERROR_TOO_MANY_OBJECTS);
3560
3561 static const int STATUE_NUMBER_INNER_TILES = 25; // Number of tiles int the center of the city, where we try to protect houses.
3562
3563 TileIndex best_position = INVALID_TILE;
3564 uint tile_count = 0;
3565 for (auto tile : SpiralTileSequence(t->xy, 9)) {
3566 tile_count++;
3567
3568 /* Statues can be build on slopes, just like houses. Only the steep slopes is a no go. */
3569 if (IsSteepSlope(GetTileSlope(tile))) continue;
3570 /* Don't build statues under bridges. */
3571 if (IsBridgeAbove(tile)) continue;
3572
3573 /* A clear-able open space is always preferred. */
3574 if ((IsTileType(tile, TileType::Clear) || IsTileType(tile, TileType::Trees)) && CheckClearTile(tile)) {
3575 best_position = tile;
3576 break;
3577 }
3578
3579 bool house = IsTileType(tile, TileType::House);
3580
3581 /* Searching inside the inner circle. */
3582 if (tile_count <= STATUE_NUMBER_INNER_TILES) {
3583 /* Save first house in inner circle. */
3584 if (house && best_position == INVALID_TILE && CheckClearTile(tile)) {
3585 best_position = tile;
3586 }
3587
3588 /* If we have reached the end of the inner circle, and have a saved house, terminate the search. */
3589 if (tile_count == STATUE_NUMBER_INNER_TILES && best_position != INVALID_TILE) break;
3590 }
3591
3592 /* Searching outside the circle, just pick the first possible spot. */
3593 if (!house || !CheckClearTile(tile)) continue;
3594 best_position = tile;
3595 break;
3596 }
3597 if (best_position == INVALID_TILE) return CommandCost(STR_ERROR_STATUE_NO_SUITABLE_PLACE);
3598
3599 if (flags.Test(DoCommandFlag::Execute)) {
3601 Command<Commands::LandscapeClear>::Do(DoCommandFlag::Execute, best_position);
3602 cur_company.Restore();
3603 BuildObject(OBJECT_STATUE, best_position, _current_company, t);
3604 t->statues.Set(_current_company); // Once found and built, "inform" the Town.
3605 MarkTileDirtyByTile(best_position);
3606 }
3607 return CommandCost();
3608}
3609
3616static CommandCost TownActionFundBuildings(Town *t, DoCommandFlags flags)
3617{
3618 /* Check if it's allowed to buy the rights */
3619 if (!_settings_game.economy.fund_buildings) return CMD_ERROR;
3620
3621 if (flags.Test(DoCommandFlag::Execute)) {
3622 /* And grow for 3 months */
3623 t->fund_buildings_months = 3;
3624
3625 /* Enable growth (also checking GameScript's opinion) */
3627
3628 /* Build a new house, but add a small delay to make sure
3629 * that spamming funding doesn't let town grow any faster
3630 * than 1 house per 2 * TOWN_GROWTH_TICKS ticks.
3631 * Also emulate original behaviour when town was only growing in
3632 * TOWN_GROWTH_TICKS intervals, to make sure that it's not too
3633 * tick-perfect and gives player some time window where they can
3634 * spam funding with the exact same efficiency.
3635 */
3637
3638 SetWindowDirty(WC_TOWN_VIEW, t->index);
3639 }
3640 return CommandCost();
3641}
3642
3649static CommandCost TownActionBuyRights(Town *t, DoCommandFlags flags)
3650{
3651 /* Check if it's allowed to buy the rights */
3652 if (!_settings_game.economy.exclusive_rights) return CMD_ERROR;
3653 if (t->exclusivity != CompanyID::Invalid()) return CMD_ERROR;
3654
3655 if (flags.Test(DoCommandFlag::Execute)) {
3656 t->exclusive_counter = 12;
3658
3660
3662
3663 /* Spawn news message */
3664 auto cni = std::make_unique<CompanyNewsInformation>(STR_NEWS_EXCLUSIVE_RIGHTS_TITLE, Company::Get(_current_company));
3665 EncodedString message = GetEncodedString(TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MINUTES : STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MONTHS, t->index, cni->company_name);
3666 AddNewsItem(std::move(message),
3667 NewsType::General, NewsStyle::Company, {}, t->index, {}, std::move(cni));
3668 AI::BroadcastNewEvent(new ScriptEventExclusiveTransportRights(_current_company, t->index));
3669 Game::NewEvent(new ScriptEventExclusiveTransportRights(_current_company, t->index));
3670 }
3671 return CommandCost();
3672}
3673
3680static CommandCost TownActionBribe(Town *t, DoCommandFlags flags)
3681{
3682 if (flags.Test(DoCommandFlag::Execute)) {
3683 if (Chance16(1, 14)) {
3684 /* set as unwanted for 6 months */
3685 t->unwanted[_current_company] = 6;
3686
3687 /* set all close by station ratings to 0 */
3688 for (Station *st : Station::Iterate()) {
3689 if (st->town == t && st->owner == _current_company) {
3690 for (GoodsEntry &ge : st->goods) ge.rating = 0;
3691 }
3692 }
3693
3694 /* only show error message to the executing player. All errors are handled command.c
3695 * but this is special, because it can only 'fail' on a DoCommandFlag::Execute */
3696 if (IsLocalCompany()) ShowErrorMessage(GetEncodedString(STR_ERROR_BRIBE_FAILED), {}, WL_INFO);
3697
3698 /* decrease by a lot!
3699 * ChangeTownRating is only for stuff in demolishing. Bribe failure should
3700 * be independent of any cheat settings
3701 */
3702 if (t->ratings[_current_company] > RATING_BRIBE_DOWN_TO) {
3703 t->ratings[_current_company] = RATING_BRIBE_DOWN_TO;
3705 }
3706 } else {
3707 ChangeTownRating(t, RATING_BRIBE_UP_STEP, RATING_BRIBE_MAXIMUM, DoCommandFlag::Execute);
3708 if (t->exclusivity != _current_company && t->exclusivity != CompanyID::Invalid()) {
3709 t->exclusivity = CompanyID::Invalid();
3710 t->exclusive_counter = 0;
3711 }
3712 }
3713 }
3714 return CommandCost();
3715}
3716
3717typedef CommandCost TownActionProc(Town *t, DoCommandFlags flags);
3718static TownActionProc * const _town_action_proc[] = {
3727};
3728static_assert(std::size(_town_action_proc) == to_underlying(TownAction::End));
3729
3736TownActions GetMaskOfTownActions(CompanyID cid, const Town *t)
3737{
3738 TownActions buttons{};
3739
3740 /* Spectators and unwanted have no options */
3741 if (cid != COMPANY_SPECTATOR && !(_settings_game.economy.bribe && t->unwanted[cid])) {
3742
3743 /* Actions worth more than this are not able to be performed */
3744 Money avail = GetAvailableMoney(cid);
3745
3746 /* Check the action bits for validity and
3747 * if they are valid add them */
3748 for (TownAction cur = {}; cur != TownAction::End; ++cur) {
3749
3750 /* Is the company prohibited from bribing ? */
3751 if (cur == TownAction::Bribe) {
3752 /* Company can't bribe if setting is disabled */
3753 if (!_settings_game.economy.bribe) continue;
3754 /* Company can bribe if another company has exclusive transport rights,
3755 * or its standing with the town is less than outstanding. */
3756 if (t->ratings[cid] >= RATING_BRIBE_MAXIMUM) {
3757 if (t->exclusivity == _current_company) continue;
3758 if (t->exclusive_counter == 0) continue;
3759 }
3760 }
3761
3762 /* Is the company not able to buy exclusive rights ? */
3763 if (cur == TownAction::BuyRights && (!_settings_game.economy.exclusive_rights || t->exclusive_counter != 0)) continue;
3764
3765 /* Is the company not able to fund buildings ? */
3766 if (cur == TownAction::FundBuildings && !_settings_game.economy.fund_buildings) continue;
3767
3768 /* Is the company not able to fund local road reconstruction? */
3769 if (cur == TownAction::RoadRebuild && !_settings_game.economy.fund_roads) continue;
3770
3771 /* Is the company not able to build a statue ? */
3772 if (cur == TownAction::BuildStatue && t->statues.Test(cid)) continue;
3773
3774 if (avail >= GetTownActionCost(cur) * _price[Price::TownAction] >> 8) {
3775 buttons.Set(cur);
3776 }
3777 }
3778 }
3779
3780 return buttons;
3781}
3782
3792CommandCost CmdDoTownAction(DoCommandFlags flags, TownID town_id, TownAction action)
3793{
3794 Town *t = Town::GetIfValid(town_id);
3795 if (t == nullptr || to_underlying(action) >= std::size(_town_action_proc)) return CMD_ERROR;
3796
3797 if (!GetMaskOfTownActions(_current_company, t).Test(action)) return CMD_ERROR;
3798
3799 CommandCost cost(EXPENSES_OTHER, _price[Price::TownAction] * GetTownActionCost(action) >> 8);
3800
3801 CommandCost ret = _town_action_proc[to_underlying(action)](t, flags);
3802 if (ret.Failed()) return ret;
3803
3804 if (flags.Test(DoCommandFlag::Execute)) {
3806 }
3807
3808 return cost;
3809}
3810
3811template <typename Func>
3812static void ForAllStationsNearTown(Town *t, Func func)
3813{
3814 /* Ideally the search radius should be close to the actual town zone 0 radius.
3815 * The true radius is not stored or calculated anywhere, only the squared radius. */
3816 /* The efficiency of this search might be improved for large towns and many stations on the map,
3817 * by using an integer square root approximation giving a value not less than the true square root. */
3819 ForAllStationsRadius(t->xy, search_radius, [&](const Station * st) {
3820 if (DistanceSquare(st->xy, t->xy) <= t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownEdge)]) {
3821 func(st);
3822 }
3823 });
3824}
3825
3830static void UpdateTownRating(Town *t)
3831{
3832 /* Increase company ratings if they're low */
3833 for (const Company *c : Company::Iterate()) {
3834 if (t->ratings[c->index] < RATING_GROWTH_MAXIMUM) {
3835 t->ratings[c->index] = std::min((int)RATING_GROWTH_MAXIMUM, t->ratings[c->index] + RATING_GROWTH_UP_STEP);
3836 }
3837 }
3838
3839 ForAllStationsNearTown(t, [&](const Station *st) {
3840 if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
3841 if (Company::IsValidID(st->owner)) {
3842 int new_rating = t->ratings[st->owner] + RATING_STATION_UP_STEP;
3843 t->ratings[st->owner] = std::min<int>(new_rating, INT16_MAX); // do not let it overflow
3844 }
3845 } else {
3846 if (Company::IsValidID(st->owner)) {
3847 int new_rating = t->ratings[st->owner] + RATING_STATION_DOWN_STEP;
3848 t->ratings[st->owner] = std::max(new_rating, INT16_MIN);
3849 }
3850 }
3851 });
3852
3853 /* clamp all ratings to valid values */
3854 for (uint i = 0; i < MAX_COMPANIES; i++) {
3855 t->ratings[i] = Clamp(t->ratings[i], RATING_MINIMUM, RATING_MAXIMUM);
3856 }
3857
3859}
3860
3861
3868static void UpdateTownGrowCounter(Town *t, uint16_t prev_growth_rate)
3869{
3870 if (t->growth_rate == TOWN_GROWTH_RATE_NONE) return;
3871 if (prev_growth_rate == TOWN_GROWTH_RATE_NONE) {
3872 t->grow_counter = std::min<uint16_t>(t->growth_rate, t->grow_counter);
3873 return;
3874 }
3875 t->grow_counter = RoundDivSU((uint32_t)t->grow_counter * (t->growth_rate + 1), prev_growth_rate + 1);
3876}
3877
3884{
3885 int n = 0;
3886 ForAllStationsNearTown(t, [&](const Station * st) {
3887 if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
3888 n++;
3889 }
3890 });
3891 return n;
3892}
3893
3901{
3907 static const uint16_t _grow_count_values[2][6] = {
3908 { 120, 120, 120, 100, 80, 60 }, // Fund new buildings has been activated
3909 { 320, 420, 300, 220, 160, 100 } // Normal values
3910 };
3911
3912 int n = CountActiveStations(t);
3913 uint16_t m = _grow_count_values[t->fund_buildings_months != 0 ? 0 : 1][std::min(n, 5)];
3914
3915 uint growth_multiplier = _settings_game.economy.town_growth_rate != 0 ? _settings_game.economy.town_growth_rate - 1 : 1;
3916
3917 m >>= growth_multiplier;
3918 if (t->larger_town) m /= 2;
3919
3920 return TownTicksToGameTicks(m / (t->cache.num_houses / 50 + 1));
3921}
3922
3928{
3929 if (t->flags.Test(TownFlag::CustomGrowth)) return;
3930 uint old_rate = t->growth_rate;
3932 UpdateTownGrowCounter(t, old_rate);
3933 SetWindowDirty(WC_TOWN_VIEW, t->index);
3934}
3935
3940static void UpdateTownGrowth(Town *t)
3941{
3943
3945 SetWindowDirty(WC_TOWN_VIEW, t->index);
3946
3947 if (_settings_game.economy.town_growth_rate == 0 && t->fund_buildings_months == 0) return;
3948
3949 if (t->fund_buildings_months == 0) {
3950 /* Check if all goals are reached for this town to grow (given we are not funding it) */
3951 for (int i = TAE_BEGIN; i < TAE_END; i++) {
3952 switch (t->goal[i]) {
3953 case TOWN_GROWTH_WINTER:
3954 if (TileHeight(t->xy) >= GetSnowLine() && t->received[i].old_act == 0 && t->cache.population > 90) return;
3955 break;
3956 case TOWN_GROWTH_DESERT:
3957 if (GetTropicZone(t->xy) == TROPICZONE_DESERT && t->received[i].old_act == 0 && t->cache.population > 60) return;
3958 break;
3959 default:
3960 if (t->goal[i] > t->received[i].old_act) return;
3961 break;
3962 }
3963 }
3964 }
3965
3968 SetWindowDirty(WC_TOWN_VIEW, t->index);
3969 return;
3970 }
3971
3972 if (t->fund_buildings_months == 0 && CountActiveStations(t) == 0 && !Chance16(1, 12)) return;
3973
3975 SetWindowDirty(WC_TOWN_VIEW, t->index);
3976}
3977
3985{
3986 /* The required rating is hardcoded to RATING_VERYPOOR (see below), not the authority attitude setting, so we can bail out like this. */
3987 if (_settings_game.difficulty.town_council_tolerance == TOWN_COUNCIL_PERMISSIVE) return CommandCost();
3988
3990
3991 Town *t = ClosestTownFromTile(tile, _settings_game.economy.dist_local_authority);
3992 if (t == nullptr) return CommandCost();
3993
3994 if (t->ratings[_current_company] > RATING_VERYPOOR) return CommandCost();
3995
3996 return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index);
3997}
3998
4008{
4009 if (Town::GetNumItems() == 0) return nullptr;
4010
4011 TownID tid = _town_kdtree.FindNearest(TileX(tile), TileY(tile));
4012 Town *town = Town::Get(tid);
4013 if (DistanceManhattan(tile, town->xy) < threshold) return town;
4014 return nullptr;
4015}
4016
4025Town *ClosestTownFromTile(TileIndex tile, uint threshold)
4026{
4027 switch (GetTileType(tile)) {
4028 case TileType::Road:
4029 if (IsRoadDepot(tile)) return CalcClosestTownFromTile(tile, threshold);
4030
4031 if (!HasTownOwnedRoad(tile)) {
4032 TownID tid = GetTownIndex(tile);
4033
4034 if (tid == TownID::Invalid()) {
4035 /* in the case we are generating "many random towns", this value may be TownID::Invalid() */
4036 if (_generating_world) return CalcClosestTownFromTile(tile, threshold);
4037 assert(Town::GetNumItems() == 0);
4038 return nullptr;
4039 }
4040
4041 assert(Town::IsValidID(tid));
4042 Town *town = Town::Get(tid);
4043
4044 if (DistanceManhattan(tile, town->xy) >= threshold) town = nullptr;
4045
4046 return town;
4047 }
4048 [[fallthrough]];
4049
4050 case TileType::House:
4051 return Town::GetByTile(tile);
4052
4053 default:
4054 return CalcClosestTownFromTile(tile, threshold);
4055 }
4056}
4057
4058static bool _town_rating_test = false;
4059static std::map<const Town *, int> _town_test_ratings;
4060
4067{
4068 static int ref_count = 0; // Number of times test-mode is switched on.
4069 if (mode) {
4070 if (ref_count == 0) {
4071 _town_test_ratings.clear();
4072 }
4073 ref_count++;
4074 } else {
4075 assert(ref_count > 0);
4076 ref_count--;
4077 }
4078 _town_rating_test = !(ref_count == 0);
4079}
4080
4086static int GetRating(const Town *t)
4087{
4088 if (_town_rating_test) {
4089 auto it = _town_test_ratings.find(t);
4090 if (it != _town_test_ratings.end()) {
4091 return it->second;
4092 }
4093 }
4094 return t->ratings[_current_company];
4095}
4096
4104void ChangeTownRating(Town *t, int add, int max, DoCommandFlags flags)
4105{
4106 /* if magic_bulldozer cheat is active, town doesn't penalize for removing stuff */
4107 if (t == nullptr || flags.Test(DoCommandFlag::NoModifyTownRating) ||
4109 (_cheats.magic_bulldozer.value && add < 0)) {
4110 return;
4111 }
4112
4113 int rating = GetRating(t);
4114 if (add < 0) {
4115 if (rating > max) {
4116 rating += add;
4117 if (rating < max) rating = max;
4118 }
4119 } else {
4120 if (rating < max) {
4121 rating += add;
4122 if (rating > max) rating = max;
4123 }
4124 }
4125 if (_town_rating_test) {
4126 _town_test_ratings[t] = rating;
4127 } else {
4129 t->ratings[_current_company] = rating;
4131 }
4132}
4133
4142{
4143 /* if magic_bulldozer cheat is active, town doesn't restrict your destructive actions */
4144 if (t == nullptr || !Company::IsValidID(_current_company) ||
4145 _cheats.magic_bulldozer.value || flags.Test(DoCommandFlag::NoTestTownRating)) {
4146 return CommandCost();
4147 }
4148
4149 /* minimum rating needed to be allowed to remove stuff */
4150 static const int needed_rating[][to_underlying(TownRatingCheckType::End)] = {
4151 /* RoadRemove, TunnelBridgeRemove */
4156 };
4157
4158 /* check if you're allowed to remove the road/bridge/tunnel
4159 * owned by a town no removal if rating is lower than ... depends now on
4160 * difficulty setting. Minimum town rating selected by difficulty level
4161 */
4162 int needed = needed_rating[_settings_game.difficulty.town_council_tolerance][to_underlying(type)];
4163
4164 if (GetRating(t) < needed) {
4165 return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index);
4166 }
4167
4168 return CommandCost();
4169}
4170
4171template <>
4172Town::SuppliedHistory SumHistory(std::span<const Town::SuppliedHistory> history)
4173{
4174 uint64_t production = std::accumulate(std::begin(history), std::end(history), 0, [](uint64_t r, const auto &s) { return r + s.production; });
4175 uint64_t transported = std::accumulate(std::begin(history), std::end(history), 0, [](uint64_t r, const auto &s) { return r + s.transported; });
4176 auto count = std::size(history);
4177 return {.production = ClampTo<uint32_t>(production / count), .transported = ClampTo<uint32_t>(transported / count)};
4178}
4179
4180static const IntervalTimer<TimerGameEconomy> _economy_towns_monthly({TimerGameEconomy::Trigger::Month, TimerGameEconomy::Priority::Town}, [](auto)
4181{
4182 for (Town *t : Town::Iterate()) {
4183 /* Check for active town actions and decrement their counters. */
4184 if (t->road_build_months != 0) t->road_build_months--;
4186
4187 if (t->exclusive_counter != 0) {
4188 if (--t->exclusive_counter == 0) t->exclusivity = CompanyID::Invalid();
4189 }
4190
4191 /* Check for active failed bribe cooloff periods and decrement them. */
4192 for (const Company *c : Company::Iterate()) {
4193 if (t->unwanted[c->index] > 0) t->unwanted[c->index]--;
4194 }
4195
4197
4198 /* Update cargo statistics. */
4199 for (auto &s : t->supplied) RotateHistory(s.history, t->valid_history, HISTORY_YEAR, TimerGameEconomy::month);
4200 for (auto &received : t->received) received.NewMonth();
4201
4204
4205 SetWindowDirty(WC_TOWN_VIEW, t->index);
4206 }
4207});
4208
4209static const IntervalTimer<TimerGameEconomy> _economy_towns_yearly({TimerGameEconomy::Trigger::Year, TimerGameEconomy::Priority::Town}, [](auto)
4210{
4211 /* Increment house ages */
4212 for (const auto t : Map::Iterate()) {
4213 if (!IsTileType(t, TileType::House)) continue;
4215 }
4216});
4217
4218static CommandCost TerraformTile_Town(TileIndex tile, DoCommandFlags flags, int z_new, Slope tileh_new)
4219{
4220 if (AutoslopeEnabled()) {
4221 HouseID house = GetHouseType(tile);
4222 GetHouseNorthPart(house); // modifies house to the ID of the north tile
4223 const HouseSpec *hs = HouseSpec::Get(house);
4224
4225 /* Here we differ from TTDP by checking BuildingFlag::NotSloped */
4226 if (!hs->building_flags.Test(BuildingFlag::NotSloped) && !IsSteepSlope(tileh_new) &&
4227 (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) {
4228 bool allow_terraform = true;
4229
4230 /* Call the autosloping callback per tile, not for the whole building at once. */
4231 house = GetHouseType(tile);
4232 hs = HouseSpec::Get(house);
4234 /* If the callback fails, allow autoslope. */
4235 uint16_t res = GetHouseCallback(CBID_HOUSE_AUTOSLOPE, 0, 0, house, Town::GetByTile(tile), tile);
4236 if (res != CALLBACK_FAILED && ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_AUTOSLOPE, res)) allow_terraform = false;
4237 }
4238
4239 if (allow_terraform) return CommandCost(EXPENSES_CONSTRUCTION, _price[Price::BuildFoundation]);
4240 }
4241 }
4242
4243 return Command<Commands::LandscapeClear>::Do(flags, tile);
4244}
4245
4247extern const TileTypeProcs _tile_type_town_procs = {
4248 DrawTile_Town, // draw_tile_proc
4249 GetSlopePixelZ_Town, // get_slope_z_proc
4250 ClearTile_Town, // clear_tile_proc
4251 AddAcceptedCargo_Town, // add_accepted_cargo_proc
4252 GetTileDesc_Town, // get_tile_desc_proc
4253 GetTileTrackStatus_Town, // get_tile_track_status_proc
4254 nullptr, // click_tile_proc
4255 AnimateTile_Town, // animate_tile_proc
4256 TileLoop_Town, // tile_loop_proc
4257 ChangeTileOwner_Town, // change_tile_owner_proc
4258 AddProducedCargo_Town, // add_produced_cargo_proc
4259 nullptr, // vehicle_enter_tile_proc
4260 GetFoundation_Town, // get_foundation_proc
4261 TerraformTile_Town, // terraform_tile_proc
4262 nullptr, // check_build_above_proc
4263};
4264
4265std::span<const DrawBuildingsTileStruct> GetTownDrawTileData()
4266{
4267 return _town_draw_tile_data;
4268}
Base functions for all AIs.
@ AT_OILRIG
Oilrig airport.
Definition airport.h:38
void AddAnimatedTile(TileIndex tile, bool mark_dirty)
Add the given tile to the animated tile table (if it does not exist yet).
void DeleteAnimatedTile(TileIndex tile, bool immediate)
Stops animation on the given tile.
Tile animation!
Functions related to autoslope.
bool AutoslopeEnabled()
Tests if autoslope is enabled for _current_company.
Definition autoslope.h:65
Class for backupping variables and making sure they are restored later.
static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
constexpr uint CountBits(T value)
Counts the number of set bits in a variable.
constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
static const uint MAX_BRIDGES
Maximal number of available bridge specs.
Definition bridge.h:18
bool IsBridgeTile(Tile t)
checks if there is a bridge on this tile
Definition bridge_map.h:35
bool IsBridgeAbove(Tile t)
checks if a bridge is set above the ground of this tile
Definition bridge_map.h:45
Axis GetBridgeAxis(Tile t)
Get the axis of the bridge that goes over the tile.
Definition bridge_map.h:68
uint8_t CargoType
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:21
bool IsValidCargoType(CargoType cargo)
Test whether cargo type is not INVALID_CARGO.
Definition cargo_type.h:104
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 & Reset()
Reset all bits.
constexpr Timpl & Set()
Set all bits.
constexpr bool Any(const Timpl &other) const
Test if any of the given values are set.
Common return value for all commands.
bool Succeeded() const
Did this command succeed?
void AddCost(const Money &cost)
Adds the given cost to the cost of the command.
Money GetCost() const
The costs as made up to this moment.
bool Failed() const
Did this command fail?
void MultiplyCost(int factor)
Multiplies the cost of the command by the given factor.
Container for an encoded string, created by GetEncodedString.
static void NewEvent(class ScriptEvent *event)
Queue a new event for a Game Script.
An interval timer will fire every interval, and will continue to fire until it is deleted.
Definition timer.h:76
TimerGameCalendar::Date introduction_date
Introduction date.
Definition road.h:140
RoadTypeFlags flags
Bit mask of road type flags.
Definition road.h:101
uint16_t max_speed
Maximum speed for vehicles travelling on this road type.
Definition road.h:116
Generate TileIndices around a center tile or tile area, with increasing distance.
Structure contains cached list of stations nearby.
const StationList & GetStations()
Run a tile loop to find stations around a tile, on demand.
static constexpr TimerGameTick::Ticks TOWN_GROWTH_TICKS
Cycle duration for towns trying to grow (this originates from the size of the town array in TTD).
static std::unique_ptr< TileIterator > Create(TileIndex corner1, TileIndex corner2, bool diagonal)
Create either an OrthogonalTileIterator or DiagonalTileIterator given the diagonal parameter.
Definition tilearea.cpp:291
static Date date
Current date in days (day counter).
static Year year
Current year, starting at 0.
static constexpr TimerGame< struct Calendar >::Date MAX_DATE
static Month month
Current month (0..11).
static bool UsingWallclockUnits(bool newgame=false)
Check if we are using wallclock units.
static TickCounter counter
Monotonic counter, in ticks, since start of game.
Map accessors for 'clear' tiles.
@ Rough
Rough mounds (3).
Definition clear_map.h:23
ClearGround GetClearGround(Tile t)
Get the type of clear tile.
Definition clear_map.h:52
CommandFlags GetCommandFlags(Commands cmd)
Get the command flags associated with the given command.
Definition command.cpp:113
CommandCost CommandCostWithParam(StringID str, uint64_t value)
Return an error status, with string and parameter.
Definition command.cpp:416
Functions related to commands.
static constexpr DoCommandFlags CommandFlagsToDCFlags(CommandFlags cmd_flags)
Extracts the DC flags needed for DoCommand from the flags returned by GetCommandFlags.
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
@ Auto
don't allow building on structures
@ NoModifyTownRating
do not change town rating
@ NoWater
don't allow building on water
@ Execute
execute the given command
@ NoTestTownRating
town rating does not disallow you from building
Definition of stuff that is very close to a company, like the company struct itself.
Money GetAvailableMoneyForCommand()
This functions returns the money which can be used to execute a command.
Money GetAvailableMoney(CompanyID company)
Get the amount of money that a company has available, or INT64_MAX if there is no such valid company.
CompanyID _current_company
Company currently doing an action.
Functions related to companies.
bool IsLocalCompany()
Is the current company the local company?
static constexpr Owner OWNER_DEITY
The object is owned by a superuser / goal script.
static constexpr CompanyID COMPANY_SPECTATOR
The client is spectating.
static constexpr Owner OWNER_TOWN
A town owns the tile, or a town is expanding.
static constexpr Owner OWNER_NONE
The tile has no ownership.
Base for all depots (except hangars).
DiagDirection ReverseDiagDir(DiagDirection d)
Returns the reverse direction of the given DiagDirection.
bool IsValidDiagDirection(DiagDirection d)
Checks if an integer value is a valid DiagDirection.
DiagDirection ChangeDiagDir(DiagDirection d, DiagDirDiff delta)
Applies a difference on a DiagDirection.
Axis DiagDirToAxis(DiagDirection d)
Convert a DiagDirection to the axis.
@ DIR_N
North.
@ DIR_S
South.
@ DIR_W
West.
@ DIR_E
East.
@ DIAGDIRDIFF_90RIGHT
90 degrees right
@ DIAGDIRDIFF_90LEFT
90 degrees left
DiagDirection
Enumeration for diagonal directions.
@ DIAGDIR_NW
Northwest.
@ DIAGDIR_SE
Southeast.
@ DIAGDIR_END
Used for iterations.
@ DIAGDIR_BEGIN
Used for iterations.
@ DIAGDIR_SW
Southwest.
bool EconomyIsInRecession()
Is the economy in recession?
uint ScaleByCargoScale(uint num, bool town)
Scale a number by the cargo scale setting.
@ EXPENSES_CONSTRUCTION
Construction costs.
@ EXPENSES_OTHER
Other expenses.
@ Terraform
Price for terraforming land, e.g. rising, lowering and flattening.
@ BuildFoundation
Price for building foundation under other constructions e.g. roads, rails, depots,...
@ TownAction
Price for interaction with local authorities.
@ ClearHouse
Price for destroying houses and other town buildings.
@ BuildTown
Price for funding new towns and cities.
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23).
Definition enum_type.hpp: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:64
void SetGeneratingWorldProgress(GenWorldProgress cls, uint total)
Set the total of a stage of the world generation.
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition gfx_type.h:17
uint8_t GetSnowLine()
Get the current snow line, either variable or static.
uint8_t HighestSnowLine()
Get the highest possible snow line height, either variable or static.
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
Definition gfx.cpp:1554
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_height_override)
Mark a tile given by its index dirty for repaint.
void UpdateValidHistory(ValidHistoryMask &valid_history, const HistoryRange &hr, uint cur_month)
Update mask of valid records for a historical data.
Definition history.cpp:25
Functions for storing historical data.
void RotateHistory(HistoryData< T > &history, ValidHistoryMask valid_history, const HistoryRange &hr, uint cur_month)
Rotate historical data.
Types for storing historical data.
@ BuildingIsHistorical
this house will only appear during town generation in random games, thus the historical
Definition house.h:93
@ BuildingIsProtected
towns and AI will not remove this house, while human players will be able to
Definition house.h:94
@ Size1x1
The building is a single tile.
Definition house.h:39
@ Size2x2
The building is 2x2 tiles.
Definition house.h:43
@ IsAnimated
The building uses animation.
Definition house.h:44
@ NotSloped
The building can only be built on flat land; when not set foundations are placed.
Definition house.h:40
@ Size2x1
The building is 2x1 tiles, i.e. wider on the X-axis.
Definition house.h:41
@ IsChurch
The building functions as a church, i.e. only one can be built in a town.
Definition house.h:45
@ IsStadium
The building functions as a stadium, i.e. only one can be built in a town.
Definition house.h:46
@ Size1x2
The building is 1x2 tiles, i.e. wider on the Y-axis.
Definition house.h:42
static const HouseID NEW_HOUSE_OFFSET
Offset for new houses.
Definition house.h:28
static const uint8_t TOWN_HOUSE_COMPLETED
Simple value that indicates the house has reached the final stage of construction.
Definition house.h:25
HouseZone
Concentric rings of zoning around the centre of a town.
Definition house.h:57
@ TownOuterSuburb
Outer suburbs; roads with pavement.
Definition house.h:60
@ ClimateSubarcticAboveSnow
Building can appear in sub-arctic climate above the snow line.
Definition house.h:65
@ ClimateSubarcticBelowSnow
Building can appear in sub-arctic climate below the snow line.
Definition house.h:67
@ TownInnerSuburb
Inner suburbs; roads with pavement and trees.
Definition house.h:61
@ TownOutskirt
Outskirts of a town; roads without pavement.
Definition house.h:59
@ TownEdge
Edge of the town; roads without pavement.
Definition house.h:58
@ TownCentre
Centre of town; roads with pavement and streetlights.
Definition house.h:62
@ ClimateTemperate
Building can appear in temperate climate.
Definition house.h:66
@ ClimateToyland
Building can appear in toyland climate.
Definition house.h:69
@ ClimateSubtropic
Building can appear in subtropical climate.
Definition house.h:68
uint16_t HouseID
OpenTTD ID of house types.
Definition house_type.h:15
Base of all industries.
void DrawFoundation(TileInfo *ti, Foundation f)
Draw foundation f at tile ti.
std::tuple< Slope, int > GetFoundationSlope(TileIndex tile)
Get slope of a tile on top of a (possible) foundation If a tile does not have a foundation,...
const TileTypeProcs _tile_type_town_procs
Tile callback functions for a town.
Definition landscape.cpp:55
Functions related to OTTD's landscape.
Point RemapCoords2(int x, int y)
Map 3D world or tile coordinate to equivalent 2D coordinate as used in the viewports and smallmap.
Definition landscape.h:97
Command definitions related to landscape (slopes etc.).
@ Arctic
Landscape with snow levels.
@ Toyland
Landscape with funky industries and vehicles.
@ Tropic
Landscape with distinct rainforests and deserts,.
@ Temperate
Base landscape.
#define Point
Macro that prevents name conflicts between included headers.
uint DistanceSquare(TileIndex t0, TileIndex t1)
Gets the 'Square' distance between the two given tiles.
Definition map.cpp:175
uint DistanceFromEdge(TileIndex tile)
Param the minimum distance to an edge.
Definition map.cpp:218
uint DistanceManhattan(TileIndex t0, TileIndex t1)
Gets the Manhattan distance between the two given tiles.
Definition map.cpp:158
uint GetClosestWaterDistance(TileIndex tile, bool water)
Finds the distance for the closest tile with water/land given a tile.
Definition map.cpp:252
Functions related to maps.
TileIndex TileAddXY(TileIndex tile, int x, int y)
Adds a given offset to a tile.
Definition map_func.h:472
TileIndex TileAddByDir(TileIndex tile, Direction dir)
Adds a Direction to a tile.
Definition map_func.h:601
TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc)
Return the offset between two tiles from a TileIndexDiffC struct.
Definition map_func.h:442
TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir)
Adds a DiagDir to a tile.
Definition map_func.h:613
TileIndexDiff TileDiffXY(int x, int y)
Calculates an offset for the given coordinate(-offset).
Definition map_func.h:391
static TileIndex TileXY(uint x, uint y)
Returns the TileIndex of a coordinate.
Definition map_func.h:375
static uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition map_func.h:427
static uint TileX(TileIndex tile)
Get the X component of a tile.
Definition map_func.h:417
constexpr TileIndex TileAdd(TileIndex tile, TileIndexDiff offset)
Adds a given offset to a tile.
Definition map_func.h:459
#define RandomTile()
Get a valid random tile.
Definition map_func.h:654
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition map_func.h:572
TileIndexDiffC TileIndexToTileIndexDiffC(TileIndex tile_a, TileIndex tile_b)
Returns the diff between two tiles.
Definition map_func.h:533
int32_t TileIndexDiff
An offset value between two tiles.
Definition map_type.h:23
constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
constexpr int RoundDivSU(int a, uint b)
Computes round(a / b) for signed a and unsigned b.
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition math_func.hpp:79
constexpr To ClampTo(From value)
Clamp the given value down to lie within the requested type.
@ GSF_FAKE_TOWNS
Fake town GrfSpecFeature for NewGRF debugging (parent scope).
Definition newgrf.h:97
@ CBID_HOUSE_DRAW_FOUNDATIONS
Called to determine the type (if any) of foundation to draw for house tile.
@ CBID_HOUSE_CARGO_ACCEPTANCE
Called to decide how much cargo a town building can accept.
@ CBID_HOUSE_AUTOSLOPE
Called to determine if one can alter the ground below a house tile.
@ CBID_HOUSE_CUSTOM_NAME
Called on the Get Tile Description for an house tile.
@ CBID_HOUSE_ALLOW_CONSTRUCTION
Determine whether the house can be built on the specified tile.
@ CBID_HOUSE_ACCEPT_CARGO
Called to determine which cargoes a town building should accept.
@ CBID_HOUSE_PRODUCE_CARGO
Called to determine how much cargo a town building produces.
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
@ AllowConstruction
decide whether the house can be built on a given tile
@ AcceptCargo
decides accepted types
@ CargoAcceptance
decides amount of cargo acceptance
@ DrawFoundations
decides if default foundations need to be drawn
@ ProduceCargo
custom cargo production
@ Autoslope
decides allowance of autosloping
static const uint CALLBACK_HOUSEPRODCARGO_END
Sentinel indicating that the loop for CBID_HOUSE_PRODUCE_CARGO has ended.
CargoType GetCargoTranslation(uint8_t cargo, const GRFFile *grffile, bool usebit)
Translate a GRF-local cargo slot/bitnum into a CargoType.
Cargo support for NewGRFs.
void ErrorUnknownCallbackResult(uint32_t grfid, uint16_t cbid, uint16_t cb_res)
Record that a NewGRF returned an unknown/invalid callback result.
bool Convert8bitBooleanCallback(const GRFFile *grffile, uint16_t cbid, uint16_t cb_res)
Converts a callback result into a boolean.
bool ConvertBooleanCallback(const GRFFile *grffile, uint16_t cbid, uint16_t cb_res)
Converts a callback result into a boolean.
GRFConfig * GetGRFConfig(uint32_t grfid, uint32_t mask)
Retrieve a NewGRF from the current config by its grfid.
Functions/types related to NewGRF debugging.
void DeleteNewGRFInspectWindow(GrfSpecFeature feature, uint index)
Delete inspect window for a given feature and index.
void DecreaseBuildingCount(Town *t, HouseID house_id)
DecreaseBuildingCount() Decrease the number of a building when it is deleted.
void IncreaseBuildingCount(Town *t, HouseID house_id)
IncreaseBuildingCount() Increase the count of a building when it has been added by a town.
void InitializeBuildingCounts()
Initialise global building counts and all town building counts.
Functions related to NewGRF houses.
StringID GetGRFStringID(uint32_t grfid, GRFStringID stringid)
Returns the index for this stringid associated with its grfID.
Header of Action 04 "universal holder" structure and functions.
StrongType::Typedef< uint32_t, struct GRFStringIDTag, StrongType::Compare, StrongType::Integer > GRFStringID
Type for GRF-internal string IDs.
static constexpr GRFStringID GRFSTR_MISC_GRF_TEXT
Miscellaneous GRF text range.
Functions related to news.
void AddNewsItem(EncodedString &&headline, NewsType type, NewsStyle style, NewsFlags flags, NewsReference ref1={}, NewsReference ref2={}, std::unique_ptr< NewsAllocatedData > &&data=nullptr, AdviceType advice_type=AdviceType::Invalid)
Add a new newsitem to be shown.
Definition news_gui.cpp:902
@ General
General news (from towns).
Definition news_type.h:45
@ IndustryOpen
Opening of industries.
Definition news_type.h:35
@ Company
Company news item. (Newspaper with face).
Definition news_type.h:82
@ Normal
Normal news item. (Newspaper with text only).
Definition news_type.h:80
Functions related to objects.
void BuildObject(ObjectType type, TileIndex tile, CompanyID owner=OWNER_NONE, struct Town *town=nullptr, uint8_t view=0)
Actually build the object.
Base for all objects.
Map accessors for object tiles.
static const ObjectType OBJECT_STATUE
Statue in towns.
Definition object_type.h:20
Some methods of Pool are placed here in order to reduce compilation time and binary size.
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don't get linker errors.
static bool IsPlainRailTile(Tile t)
Checks whether the tile is a rail tile or rail tile with signals.
Definition rail_map.h:60
Randomizer _random
Random used in the game state calculations.
Pseudo random number generator.
uint32_t RandomRange(uint32_t limit, const std::source_location location=std::source_location::current())
Pick a random number between 0 and limit - 1, inclusive.
bool Chance16(const uint32_t a, const uint32_t b, const std::source_location location=std::source_location::current())
Flips a coin with given probability.
RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb)
Clean up unnecessary RoadBits of a planned tile.
Definition road.cpp:59
Road specific functions.
@ NoHouses
Bit number for setting this roadtype as not house friendly.
Definition road.h:27
@ TownBuild
Bit number for allowing towns to build this roadtype.
Definition road.h:29
RoadTypes GetMaskForRoadTramType(RoadTramType rtt)
Get the mask for road types of the given RoadTramType.
Definition road.h:183
const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
Definition road.h:215
void UpdateNearestTownForRoadTiles(bool invalidate)
Updates cached nearest town for all road tiles.
Road related functions.
RoadBits DiagDirToRoadBits(DiagDirection d)
Create the road-part which belongs to the given DiagDirection.
Definition road_func.h:96
Functions used internally by the roads.
RoadBits GetAnyRoadBits(Tile tile, RoadTramType rtt, bool straight_tunnel_bridge_entrance)
Returns the RoadBits on an arbitrary tile Special behaviour:
Definition road_map.cpp:54
void SetRoadOwner(Tile t, RoadTramType rtt, Owner o)
Set the owner of a specific road type.
Definition road_map.h:235
bool HasTownOwnedRoad(Tile t)
Checks if given tile has town owned road.
Definition road_map.h:264
static bool IsRoadDepotTile(Tile t)
Return whether a tile is a road depot tile.
Definition road_map.h:100
DisallowedRoadDirections GetDisallowedRoadDirections(Tile t)
Gets the disallowed directions.
Definition road_map.h: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:550
static bool IsRoadDepot(Tile t)
Return whether a tile is a road depot.
Definition road_map.h:90
static bool IsNormalRoadTile(Tile t)
Return whether a tile is a normal road tile.
Definition road_map.h:58
bool IsRoadOwner(Tile t, RoadTramType rtt, Owner o)
Check if a specific road type is owned by an owner.
Definition road_map.h:252
RoadBits
Enumeration for the road parts on a tile.
Definition road_type.h:56
@ ROAD_SW
South-west part.
Definition road_type.h:59
@ ROAD_ALL
Full 4-way crossing.
Definition road_type.h:70
@ ROAD_NONE
No road-part is build.
Definition road_type.h:57
@ ROAD_E
Road at the two eastern edges.
Definition road_type.h:66
@ ROAD_NE
North-east part.
Definition road_type.h:61
@ ROAD_N
Road at the two northern edges.
Definition road_type.h:65
@ ROAD_SE
South-east part.
Definition road_type.h:60
@ ROAD_Y
Full road along the y-axis (north-west + south-east).
Definition road_type.h:63
@ ROAD_S
Road at the two southern edges.
Definition road_type.h:67
@ ROAD_W
Road at the two western edges.
Definition road_type.h:68
@ ROAD_NW
North-west part.
Definition road_type.h:58
@ ROAD_X
Full road along the x-axis (south-west + north-east).
Definition road_type.h:62
@ RTT_ROAD
Road road type.
Definition road_type.h:38
RoadType
The different roadtypes we support.
Definition road_type.h:23
@ INVALID_ROADTYPE
flag for invalid roadtype
Definition road_type.h:28
@ ROADTYPE_ROAD
Basic road type.
Definition road_type.h:25
@ DRD_NONE
None of the directions are disallowed.
Definition road_type.h:78
A number of safeguards to prevent using unsafe methods.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
GameSettings _settings_newgame
Game settings for new games (updated from the intro screen).
Definition settings.cpp:62
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:60
static constexpr int GetSlopeMaxZ(Slope s)
Returns the height of the highest corner of a slope relative to TileZ (= minimal height).
Definition slope_func.h:160
bool IsSlopeWithOneCornerRaised(Slope s)
Tests if a specific slope has exactly one corner raised.
Definition slope_func.h:88
static constexpr bool IsSteepSlope(Slope s)
Checks if a slope is steep.
Definition slope_func.h:36
Foundation FlatteningFoundation(Slope s)
Returns the foundation needed to flatten a slope.
Definition slope_func.h:369
Slope InclinedSlope(DiagDirection dir)
Returns the slope that is inclined in a specific direction.
Definition slope_func.h:256
Slope ComplementSlope(Slope s)
Return the complement of a slope.
Definition slope_func.h:76
Slope
Enumeration for the slope-type.
Definition slope_type.h:47
@ SLOPE_W
the west corner of the tile is raised
Definition slope_type.h:49
@ SLOPE_ELEVATED
bit mask containing all 'simple' slopes
Definition slope_type.h:60
@ SLOPE_E
the east corner of the tile is raised
Definition slope_type.h:51
@ SLOPE_S
the south corner of the tile is raised
Definition slope_type.h:50
@ SLOPE_N
the north corner of the tile is raised
Definition slope_type.h:52
@ SLOPE_SW
south and west corner are raised
Definition slope_type.h:55
@ SLOPE_FLAT
a flat tile
Definition slope_type.h:48
@ SLOPE_STEEP_W
a steep slope falling to east (from west)
Definition slope_type.h:65
@ SLOPE_NE
north and east corner are raised
Definition slope_type.h:57
@ SLOPE_STEEP_E
a steep slope falling to west (from east)
Definition slope_type.h:67
@ SLOPE_SE
south and east corner are raised
Definition slope_type.h:56
@ SLOPE_NW
north and west corner are raised
Definition slope_type.h:54
@ SLOPE_STEEP_N
a steep slope falling to south (from north)
Definition slope_type.h:68
@ SLOPE_STEEP_S
a steep slope falling to north (from south)
Definition slope_type.h:66
Foundation
Enumeration for Foundations.
Definition slope_type.h:92
@ FOUNDATION_LEVELED
The tile is leveled up to a flat slope.
Definition slope_type.h:94
@ FOUNDATION_NONE
The tile has no foundation, the slope remains unchanged.
Definition slope_type.h:93
@ Town
Source/destination is a town.
Definition source_type.h:22
Base classes/functions for stations.
void ForAllStationsAroundTiles(const TileArea &ta, Func func)
Call a function on all stations that have any part of the requested area within their catchment.
void UpdateAllStationVirtCoords()
Update the virtual coords needed to draw the station sign for all stations.
void UpdateAirportsNoise()
Recalculate the noise generated by the airports of each town.
void ModifyStationRatingAround(TileIndex tile, Owner owner, int amount, uint radius)
Forcibly modify station ratings near a given tile.
Declarations for accessing the k-d tree of stations.
void ForAllStationsRadius(TileIndex center, uint radius, Func func)
Call a function on all stations whose sign is within a radius of a center tile.
bool IsBayRoadStopTile(Tile t)
Is tile t a bay (non-drive through) road stop station?
bool IsDriveThroughStopTile(Tile t)
Is tile t a drive through road stop station or waypoint?
Axis GetDriveThroughStopAxis(Tile t)
Gets the axis of the drive through stop.
DiagDirection GetBayRoadStopDir(Tile t)
Gets the direction the bay road stop entrance points towards.
bool IsAnyRoadStopTile(Tile t)
Is tile t a road stop station?
@ Airport
Station with an airport.
Definition of base types and functions in a cross-platform compatible way.
#define lengthof(array)
Return the length of an fixed size array.
Definition stdafx.h:271
size_t Utf8StringLength(std::string_view str)
Get the length of an UTF-8 encoded string in number of characters and thus not the number of bytes th...
Definition string.cpp:349
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:111
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
uint32_t build_object_limit
Amount of tiles we can (still) build objects on (times 65536). Also applies to buying land and placin...
T y
Y coordinate.
T x
X coordinate.
T x
X coordinate.
T y
Y coordinate.
This structure is the same for both Industries and Houses.
Definition sprite.h:81
Information about GRF, used in the game and (part of it) in savegames.
std::string GetName() const
Get the name of this grf.
const struct GRFFile * grffile
grf file that introduced this entity
uint32_t grfid
grfid that introduced this entity.
bool HasGrfFile() const
Test if this entity was introduced by NewGRF.
Stores station stats for a single cargo.
uint8_t rating
Station rating for this cargo.
CargoType accepts_cargo[HOUSE_NUM_ACCEPTS]
input cargo slots
Definition house.h:110
SubstituteGRFFileProps grf_prop
Properties related the the grf file.
Definition house.h:116
uint8_t probability
Relative probability of appearing (16 is the standard value).
Definition house.h:119
uint8_t removal_cost
cost multiplier for removing it
Definition house.h:105
uint8_t mail_generation
mail generation multiplier (tile based, as the acceptances below)
Definition house.h:108
bool enabled
the house is available to build (true by default, but can be disabled by newgrf)
Definition house.h:113
Money GetRemovalCost() const
Get the cost for removing this house.
Definition town_cmd.cpp:232
static HouseSpec * Get(size_t house_id)
Get the spec for a house ID.
BuildingFlags building_flags
some flags that describe the house (size, stadium etc...)
Definition house.h:111
TimerGameCalendar::Year max_year
last year it can be built
Definition house.h:103
HouseCallbackMasks callback_mask
Bitmask of house callbacks that have to be called.
Definition house.h:117
uint16_t remove_rating_decrease
rating decrease if removed
Definition house.h:107
uint8_t population
population (Zero on other tiles in multi tile house.)
Definition house.h:104
HouseExtraFlags extra_flags
some more flags
Definition house.h:120
uint8_t cargo_acceptance[HOUSE_NUM_ACCEPTS]
acceptance level for the cargo slots
Definition house.h:109
HouseID Index() const
Gets the index of this spec.
HouseClassID class_id
defines the class this house has (not grf file based)
Definition house.h:121
StringID building_name
building name
Definition house.h:106
uint8_t minimum_life
The minimum number of years this house will survive before the town rebuilds it.
Definition house.h:124
HouseZones building_availability
where can it be built (climates, zones)
Definition house.h:112
static std::vector< HouseSpec > & Specs()
Get a reference to all HouseSpecs.
Defines the internal data of a functional industry.
Definition industry.h:62
Town * town
Nearest town.
Definition industry.h:107
static Industry * GetByTile(TileIndex tile)
Get the industry of the given tile.
Definition industry.h:251
static uint ScaleBySize(uint n)
Scales the given value by the map size, where the given value is for a 256 by 256 map.
Definition map_func.h:330
static IterateWrapper Iterate()
Returns an iterable ensemble of all Tiles.
Definition map_func.h:365
static uint ScaleByLandProportion(uint n)
Scales the given value by the number of water tiles.
Definition map_func.h:308
static uint Size()
Get the size of the map.
Definition map_func.h:280
An object, such as transmitter, on the map.
Definition object_base.h:23
ObjectType type
Type of the object.
Definition object_base.h:24
Town * town
Town the object is built in.
Definition object_base.h:25
static Object * GetByTile(TileIndex tile)
Get the object associated with a tile.
void Add(TileIndex to_add)
Add a single tile to a tile area; enlarge if needed.
Definition tilearea.cpp:43
SpriteID sprite
The 'real' sprite.
Definition gfx_type.h:23
PaletteID pal
The palette (use PAL_NONE) if not needed).
Definition gfx_type.h:24
static Pool::IterateWrapper< Town > Iterate(size_t from=0)
static Town * Get(auto index)
static bool CanAllocateItem(size_t n=1)
static bool IsValidID(auto index)
static T * Create(Targs &&... args)
static Company * GetIfValid(auto index)
static constexpr size_t MAX_SIZE
A location from where cargo can come from (or go to).
Definition source_type.h:32
static Pool::IterateWrapper< Station > Iterate(size_t from=0)
Station data structure.
bool CatchmentCoversTown(TownID t) const
Test if the given town ID is covered by our catchment area.
Definition station.cpp:452
uint16_t override_id
id of the entity been replaced by
Tile description for the 'land area information' tool.
Definition tile_cmd.h:38
std::optional< std::string > grf
newGRF used for the tile contents
Definition tile_cmd.h:49
StringID str
Description of the tile.
Definition tile_cmd.h:39
std::array< Owner, 4 > owner
Name of the owner(s).
Definition tile_cmd.h:41
uint64_t dparam
Parameter of the str string.
Definition tile_cmd.h:40
std::optional< bool > town_can_upgrade
Whether the town can upgrade this house during town growth.
Definition tile_cmd.h:56
A pair-construct of a TileIndexDiff.
Definition map_type.h:31
int16_t x
The x value of the coordinate.
Definition map_type.h:32
int16_t y
The y value of the coordinate.
Definition map_type.h:33
Tile information, used while rendering the tile.
Definition tile_cmd.h:32
Slope tileh
Slope of the tile.
Definition tile_cmd.h:33
TileIndex tile
Tile index.
Definition tile_cmd.h:34
Set of callback functions for performing tile operations of a given tile type.
Definition tile_cmd.h:154
uint32_t population
Current population of people.
Definition town.h:53
uint32_t num_houses
Amount of houses.
Definition town.h:52
TrackedViewportSign sign
Location of name sign, UpdateVirtCoord updates this.
Definition town.h:54
BuildingCounts< uint16_t > building_counts
The number of each type of building in the town.
Definition town.h:57
std::array< uint32_t, NUM_HOUSE_ZONES > squared_town_zone_radius
UpdateTownRadius updates this given the house count.
Definition town.h:56
Struct holding parameters used to generate town name.
uint16_t type
town name style
uint32_t grfid
newgrf ID (0 if not used)
Town data structure.
Definition town.h:63
EncodedString text
General text with additional information.
Definition town.h:114
bool larger_town
if this is a larger town and should grow more quickly
Definition town.h:150
CompanyMask statues
which companies have a statue?
Definition town.h:79
uint16_t time_until_rebuild
time until we rebuild a house
Definition town.h:142
std::string cached_name
NOSAVE: Cache of the resolved name of the town, if not using a custom town name.
Definition town.h:73
TileIndex xy
town center tile
Definition town.h:64
uint8_t fund_buildings_months
fund buildings program in action?
Definition town.h:147
SuppliedCargoes supplied
Cargo statistics about supplied cargo.
Definition town.h:109
TownLayout layout
town specific road layout
Definition town.h:151
static Town * GetRandom()
Return a random valid town.
Definition town_cmd.cpp:203
std::string name
Custom town name. If empty, the town was not renamed and uses the generated name.
Definition town.h:72
Town(TownID index, TileIndex tile=INVALID_TILE)
Creates a new town.
Definition town.h:162
uint16_t grow_counter
counter to count when to grow, value is smaller than or equal to growth_rate
Definition town.h:144
TownFlags flags
See TownFlags.
Definition town.h:75
TownCache cache
Container for all cacheable data.
Definition town.h:66
TypedIndexContainer< std::array< uint8_t, MAX_COMPANIES >, CompanyID > unwanted
how many months companies aren't wanted by towns (bribe)
Definition town.h:83
CompanyID exclusivity
which company has exclusivity
Definition town.h:84
ValidHistoryMask valid_history
Mask of valid history records.
Definition town.h:112
void InitializeLayout(TownLayout layout)
Assign the town layout.
Definition town_cmd.cpp:189
bool show_zone
NOSAVE: mark town to show the local authority zone in the viewports.
Definition town.h:153
uint8_t exclusive_counter
months till the exclusivity expires
Definition town.h:85
void UpdateVirtCoord()
Resize the sign (label) of the town after it changes population.
Definition town_cmd.cpp:398
CompanyMask have_ratings
which companies have a rating
Definition town.h:82
~Town()
Destroy the town.
Definition town_cmd.cpp:115
TypedIndexContainer< std::array< int16_t, MAX_COMPANIES >, CompanyID > ratings
ratings of each company for this town
Definition town.h:86
uint16_t growth_rate
town growth rate
Definition town.h:145
StationList stations_near
NOSAVE: List of nearby stations.
Definition town.h:140
static void PostDestructor(size_t index)
Invalidating of the "nearest town cache" has to be done after removing item from the pool.
Definition town_cmd.cpp:174
uint8_t road_build_months
fund road reconstruction in action?
Definition town.h:148
std::array< TransportedCargoStat< uint16_t >, NUM_TAE > received
Cargo statistics about received cargotypes.
Definition town.h:110
std::array< uint32_t, NUM_TAE > goal
Amount of cargo required for the town to grow.
Definition town.h:111
bool kdtree_valid
Are the sign data valid for use with the _viewport_sign_kdtree?
Representation of a waypoint.
void DeleteSubsidyWith(Source source)
Delete the subsidies associated with a given cargo source type and id.
Definition subsidy.cpp:119
Functions related to subsidies.
Command definitions related to terraforming.
bool IsTileFlat(TileIndex tile, int *h)
Check if a given tile is flat.
Definition tile_map.cpp:94
int GetTileMaxZ(TileIndex t)
Get top height of the tile inside the map.
Definition tile_map.cpp:135
int GetTileZ(TileIndex tile)
Get bottom height of the tile.
Definition tile_map.cpp:115
static bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition tile_map.h:150
uint TileHash(uint x, uint y)
Calculate a hash value from a tile position.
Definition tile_map.h:324
static uint TileHeight(Tile tile)
Returns the height of a tile.
Definition tile_map.h:29
bool IsTileOwner(Tile tile, Owner owner)
Checks if a tile belongs to the given owner.
Definition tile_map.h:214
int GetTileMaxPixelZ(TileIndex tile)
Get top height of the tile.
Definition tile_map.h:312
bool IsValidTile(Tile tile)
Checks if a tile is valid.
Definition tile_map.h:161
uint TileHash2Bit(uint x, uint y)
Get the last two bits of the TileHash from a tile position.
Definition tile_map.h:342
TropicZone GetTropicZone(Tile tile)
Get the tropic zone.
Definition tile_map.h:238
Slope GetTileSlope(TileIndex tile)
Return the slope of a given tile inside the map.
Definition tile_map.h:279
static TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
Definition tile_map.h:96
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > > TileIndex
The index/ID of a Tile.
Definition tile_type.h:92
@ TROPICZONE_DESERT
Tile is desert.
Definition tile_type.h:83
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:100
static constexpr uint TILE_SIZE
Tile size in world coordinates.
Definition tile_type.h:15
@ TunnelBridge
Tunnel entry/exit and bridge heads.
Definition tile_type.h:58
@ Water
Water tile.
Definition tile_type.h:55
@ Station
A tile of a station or airport.
Definition tile_type.h:54
@ Object
Contains objects such as transmitters and owned land.
Definition tile_type.h:59
@ Industry
Part of an industry.
Definition tile_type.h:57
@ Railway
A tile with railway.
Definition tile_type.h:50
@ Void
Invisible tiles at the SW and SE border.
Definition tile_type.h:56
@ Trees
Tile with one or more trees.
Definition tile_type.h:53
@ House
A house by a town.
Definition tile_type.h:52
@ Road
A tile with road and/or tram tracks.
Definition tile_type.h:51
@ Clear
A tile without any structures, i.e. grass, rocks, farm fields etc.
Definition tile_type.h:49
OrthogonalTileArea TileArea
Shorthand for the much more common orthogonal tile area.
Definition of Interval and OneShot timers.
Definition of the game-calendar-timer.
Definition of the game-economy-timer.
Definition of the tick-based game-timer.
Base of the town class.
static const uint TOWN_GROWTH_WINTER
The town only needs this cargo in the winter (any amount).
Definition town.h:32
TownRatingCheckType
Action types that a company must ask permission for to a town authority.
Definition town.h:225
@ End
End marker.
Definition town.h:228
static const uint TOWN_GROWTH_DESERT
The town needs the cargo for growth when on desert (any amount).
Definition town.h:33
static const uint CUSTOM_TOWN_NUMBER_DIFFICULTY
value for custom town number in difficulty settings
Definition town.h:29
Town * CalcClosestTownFromTile(TileIndex tile, uint threshold=UINT_MAX)
Return the town closest to the given tile within threshold.
TownAction
Town actions of a company.
Definition town.h:248
@ RoadRebuild
Rebuild the roads.
Definition town.h:252
@ Bribe
Try to bribe the council.
Definition town.h:256
@ End
End marker.
Definition town.h:257
@ BuildStatue
Build a statue.
Definition town.h:253
@ BuyRights
Buy exclusive transport rights.
Definition town.h:255
@ FundBuildings
Fund new buildings.
Definition town.h:254
@ HasChurch
There can be only one church by town.
Definition town.h:43
@ CustomGrowth
Growth rate is controlled by GS.
Definition town.h:45
@ HasStadium
There can be only one stadium by town.
Definition town.h:44
@ IsGrowing
Conditions for town growth are met. Grow according to Town::growth_rate.
Definition town.h:42
static const uint16_t TOWN_GROWTH_RATE_NONE
Special value for Town::growth_rate to disable town growth.
Definition town.h:34
static bool RoadTypesAllowHouseHere(TileIndex t)
Checks whether at least one surrounding road allows to build a house here.
static bool CheckFree2x2Area(TileIndex tile, int z, bool noslope)
Checks if a house of size 2x2 can be built at this tile.
std::tuple< CommandCost, Money, TownID > CmdFoundTown(DoCommandFlags flags, TileIndex tile, TownSize size, bool city, TownLayout layout, bool random_location, uint32_t townnameparts, const std::string &text)
Create a new town.
void ChangeTownRating(Town *t, int add, int max, DoCommandFlags flags)
Changes town rating of the current company.
HouseZones GetClimateMaskForLandscape()
Get the HouseZones climate mask for the current landscape type.
static bool GrowTownAtRoad(Town *t, TileIndex tile, TownExpandModes modes)
Try to grow a town at a given road tile.
static 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.
TownGrowthResult
@ Continue
The town hasn't grown yet, but try again.
@ Succeed
The town has grown.
@ SearchStopped
There is a reason not to try growing the town now.
static bool CanRoadContinueIntoNextTile(const Town *t, const TileIndex tile, const DiagDirection road_dir)
Checks if a town road can be continued into the next tile.
static bool TryBuildTownHouse(Town *t, TileIndex tile, TownExpandModes modes)
Tries to build a house at this tile.
static void UpdateTownGrowCounter(Town *t, uint16_t prev_growth_rate)
Updates town grow counter after growth rate change.
static int CountActiveStations(Town *t)
Calculates amount of active stations in the range of town (HZB_TOWN_EDGE).
static bool IsNeighbourRoadTile(TileIndex tile, const DiagDirection dir, uint dist_multi)
Check for parallel road inside a given distance.
static bool _generating_town
Set if a town is being generated.
Definition town_cmd.cpp:88
static void MakeTownHouse(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool is_protected)
Write house information into the map.
static bool CheckTownBuild2x2House(TileIndex *tile, Town *t, int maxz, bool noslope, TownExpandModes modes)
Checks if a 1x2 or 2x1 building is allowed here, accounting for road layout and tile heights.
static void TileLoop_Town(TileIndex tile)
Tile callback function.
Definition town_cmd.cpp:602
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:579
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:516
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:457
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:717
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:559
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:442
CargoArray GetAcceptedCargoOfHouse(const HouseSpec *hs)
Get accepted cargo of a house prototype.
Definition town_cmd.cpp:858
static void AddAcceptedCargoSetMask(CargoType cargo, uint amount, CargoArray &acceptance, CargoTypes &always_accepted)
Fill cargo acceptance array and always_accepted mask, if cargo type is valid.
Definition town_cmd.cpp:789
static DiagDirection RandomDiagDir()
Return a random direction.
Definition town_cmd.cpp:255
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:471
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:430
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:315
static TimerGameCalendar::Date GetTownRoadTypeFirstIntroductionDate()
Get the calendar date of the earliest town-buildable road type.
Definition town_cmd.cpp:995
static void AnimateTile_Town(TileIndex tile)
Animate a tile for a town.
Definition town_cmd.cpp:339
CommandCost CmdPlaceHouse(DoCommandFlags flags, TileIndex tile, HouseID house, bool is_protected, bool replace)
Place an individual house.
RoadType GetTownRoadType()
Get the road type that towns should build at this current moment.
Definition town_cmd.cpp:965
static RoadBits GetTownRoadBits(TileIndex tile)
Return the RoadBits of a tile, ignoring depot and bay road stops.
Definition town_cmd.cpp:954
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 CommandCost TownCanBePlacedHere(TileIndex tile, bool check_surrounding)
Check if it's possible to place a town on a given tile.
static bool TestTownOwnsBridge(TileIndex tile, const Town *t)
Check if a town 'owns' a bridge.
Definition town_cmd.cpp:99
void OnTick_Town()
Iterate through all towns and call their tick handler.
Definition town_cmd.cpp:940
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:493
static void TownTickHandler(Town *t)
Handle the town tick for a single town, by growing the town if desired.
Definition town_cmd.cpp:921
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:805
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:390
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:533
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:264
void UpdateAllTownVirtCoords()
Update the virtual coords needed to draw the town sign for all towns.
Definition town_cmd.cpp:422
CommandCost CmdPlaceHouseArea(DoCommandFlags flags, TileIndex tile, TileIndex start_tile, HouseID house, bool is_protected, bool replace, bool diagonal)
Construct multiple houses in an area.
Command definitions related to towns.
Declarations for accessing the k-d tree of towns.
Sprites to use and how to display them for town tiles.
static const DrawBuildingsTileStruct _town_draw_tile_data[]
structure of houses graphics
Definition town_land.h:27
void IncrementHouseAge(Tile t)
Increments the age of the house.
Definition town_map.h:259
void HaltLift(Tile t)
Stop the lift of this animated house from moving.
Definition town_map.h:137
HouseID GetHouseType(Tile t)
Get the type of this house, which is an index into the house spec array.
Definition town_map.h:60
void ResetHouseAge(Tile t)
Sets the age of the house to zero.
Definition town_map.h:248
void MakeHouseTile(Tile t, TownID tid, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool house_protected)
Make the tile a house.
Definition town_map.h:375
void IncHouseConstructionTick(Tile t)
Sets the increment stage of a house It is working with the whole counter + stage 5 bits,...
Definition town_map.h:230
uint8_t GetLiftPosition(Tile t)
Get the position of the lift on this animated house.
Definition town_map.h:147
void SetLiftDestination(Tile t, uint8_t dest)
Set the new destination of the lift for this animated house, and activate the LiftHasDestination bit.
Definition town_map.h:115
TimerGameCalendar::Year GetHouseAge(Tile t)
Get the age of the house.
Definition town_map.h:271
void SetLiftPosition(Tile t, uint8_t pos)
Set the position of the lift on this animated house.
Definition town_map.h:157
uint8_t GetLiftDestination(Tile t)
Get the current destination for this lift.
Definition town_map.h:126
uint8_t GetHouseBuildingStage(Tile t)
House Construction Scheme.
Definition town_map.h:205
TownID GetTownIndex(Tile t)
Get the index of which town this house/street is attached to.
Definition town_map.h:23
void SetTownIndex(Tile t, TownID index)
Set the town index for a road or house tile.
Definition town_map.h:35
bool LiftHasDestination(Tile t)
Check if the lift of this animated house has a destination.
Definition town_map.h:104
bool IsHouseCompleted(Tile t)
Get the completion of this house.
Definition town_map.h:167
bool IsHouseProtected(Tile t)
Check if the house is protected from removal by towns.
Definition town_map.h:82
uint8_t GetHouseConstructionTick(Tile t)
Gets the construction stage of a house.
Definition town_map.h:217
static constexpr int RATING_GROWTH_UP_STEP
when a town grows, all companies have rating increased a bit ...
Definition town_type.h:53
static constexpr int RATING_INITIAL
initial rating
Definition town_type.h:45
static constexpr int RATING_ROAD_NEEDED_HOSTILE
"Hostile"
Definition town_type.h:71
@ TCGM_BITCOUNT
Bit-counted algorithm (normal distribution from individual house population).
Definition town_type.h:118
@ TCGM_ORIGINAL
Original algorithm (quadratic cargo by population).
Definition town_type.h:117
static constexpr int RATING_ROAD_NEEDED_NEUTRAL
"Neutral"
Definition town_type.h:70
TownLayout
Town Layouts.
Definition town_type.h:84
@ TL_3X3_GRID
Geometric 3x3 grid algorithm.
Definition town_type.h:89
@ TL_ORIGINAL
Original algorithm (min. 1 distance between roads).
Definition town_type.h:86
@ TL_2X2_GRID
Geometric 2x2 grid algorithm.
Definition town_type.h:88
@ TL_RANDOM
Random town layout.
Definition town_type.h:91
@ TL_BETTER_ROADS
Extended original algorithm (min. 2 distance between roads).
Definition town_type.h:87
@ NUM_TLS
Number of town layouts.
Definition town_type.h:93
static constexpr int RATING_TUNNEL_BRIDGE_NEEDED_LENIENT
rating needed, "Lenient" difficulty settings
Definition town_type.h:61
@ TF_CUSTOM_LAYOUT
Allowed, with custom town layout.
Definition town_type.h:110
@ TF_FORBIDDEN
Forbidden.
Definition town_type.h:108
static constexpr int RATING_TUNNEL_BRIDGE_NEEDED_HOSTILE
"Hostile"
Definition town_type.h:63
static constexpr int RATING_TUNNEL_BRIDGE_NEEDED_PERMISSIVE
"Permissive" (local authority disabled)
Definition town_type.h:64
static constexpr int RATING_STATION_DOWN_STEP
... but loses for badly serviced stations
Definition town_type.h:56
static constexpr int RATING_TUNNEL_BRIDGE_NEEDED_NEUTRAL
"Neutral"
Definition town_type.h:62
static constexpr int RATING_ROAD_NEEDED_LENIENT
rating needed, "Lenient" difficulty settings
Definition town_type.h:69
static constexpr int RATING_STATION_UP_STEP
when a town grows, company gains reputation for all well serviced stations ...
Definition town_type.h:55
TownSize
Supported initial town sizes.
Definition town_type.h:21
@ TSZ_RANDOM
Random size, bigger than small, smaller than large.
Definition town_type.h:25
@ TSZ_END
Number of available town sizes.
Definition town_type.h:27
@ TSZ_LARGE
Large town.
Definition town_type.h:24
static const uint MAX_LENGTH_TOWN_NAME_CHARS
The maximum length of a town name in characters including '\0'.
Definition town_type.h:122
@ Roads
Allow town to place roads.
Definition town_type.h:100
@ Buildings
Allow town to place buildings.
Definition town_type.h:99
static constexpr int RATING_ROAD_NEEDED_PERMISSIVE
"Permissive" (local authority disabled)
Definition town_type.h:72
static constexpr int RATING_GROWTH_MAXIMUM
... up to RATING_MEDIOCRE
Definition town_type.h:54
bool VerifyTownName(uint32_t r, const TownNameParams *par, TownNames *town_names)
Verifies the town name is valid and unique.
Definition townname.cpp:103
bool GenerateTownName(Randomizer &randomizer, uint32_t *townnameparts, TownNames *town_names)
Generates valid town name.
Definition townname.cpp:136
Town name generator stuff.
bool IsTransparencySet(TransparencyOption to)
Check if the transparency option bit is set and if we aren't in the game menu (there's never transpar...
bool IsInvisibilitySet(TransparencyOption to)
Check if the invisibility option bit is set and if we aren't in the game menu (there's never transpar...
@ TO_HOUSES
town buildings
TransportType
Available types of transport.
@ TRANSPORT_ROAD
Transport by road vehicle.
Map accessors for tree tiles.
TreeGround GetTreeGround(Tile t)
Returns the groundtype for tree tiles.
Definition tree_map.h:102
@ Rough
Rough land.
Definition tree_map.h:54
Command definitions related to tunnels and bridges.
Functions that have tunnels and bridges in common.
DiagDirection GetTunnelBridgeDirection(Tile t)
Get the direction pointing to the other end.
TransportType GetTunnelBridgeTransportType(Tile t)
Tunnel: Get the transport type of the tunnel (road or rail) Bridge: Get the transport type of the bri...
TileIndex GetOtherTunnelBridgeEnd(Tile t)
Determines type of the wormhole and returns its other end.
void AddSortableSpriteToDraw(SpriteID image, PaletteID pal, int x, int y, int z, const SpriteBounds &bounds, bool transparent, const SubSprite *sub)
Draw a (transparent) sprite at given coordinates with a given bounding box.
Definition viewport.cpp:658
void AddChildSpriteScreen(SpriteID image, PaletteID pal, int x, int y, bool transparent, const SubSprite *sub, bool scale, bool relative)
Add a child sprite to a parent sprite.
Definition viewport.cpp:819
void DrawGroundSprite(SpriteID image, PaletteID pal, const SubSprite *sub, int extra_offs_x, int extra_offs_y)
Draws a ground sprite for the current tile.
Definition viewport.cpp:579
Functions related to (drawing on) viewports.
Declarations for accessing the k-d tree of viewports.
bool HasTileWaterGround(Tile t)
Checks whether the tile has water at the ground.
Definition water_map.h:352
bool IsWaterTile(Tile t)
Is it a water tile with plain water?
Definition water_map.h:192
bool IsSea(Tile t)
Is it a sea water tile?
Definition water_map.h:160
Base of waypoints.
void CloseWindowById(WindowClass cls, WindowNumber number, bool force, int data)
Close a window by its class and window number (if it is open).
Definition window.cpp:1198
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting).
Definition window.cpp:3218
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:3310
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting).
Definition window.cpp:3188
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: