OpenTTD Source 20251104-master-g3befbdd52f
town_cmd.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10#include "stdafx.h"
11#include "misc/history_type.hpp"
12#include "misc/history_func.hpp"
13#include "road.h"
14#include "road_internal.h" /* Cleaning up road bits */
15#include "road_cmd.h"
16#include "landscape.h"
17#include "viewport_func.h"
18#include "viewport_kdtree.h"
19#include "command_func.h"
20#include "company_func.h"
21#include "industry.h"
22#include "station_base.h"
23#include "waypoint_base.h"
24#include "station_kdtree.h"
25#include "company_base.h"
26#include "news_func.h"
27#include "error.h"
28#include "object.h"
29#include "genworld.h"
30#include "newgrf_debug.h"
31#include "newgrf_house.h"
32#include "newgrf_text.h"
33#include "autoslope.h"
34#include "tunnelbridge_map.h"
35#include "strings_func.h"
36#include "window_func.h"
37#include "string_func.h"
38#include "newgrf_cargo.h"
39#include "cheat_type.h"
40#include "animated_tile_func.h"
41#include "subsidy_func.h"
42#include "core/pool_func.hpp"
43#include "town.h"
44#include "town_kdtree.h"
45#include "townname_func.h"
46#include "core/random_func.hpp"
47#include "core/backup_type.hpp"
48#include "depot_base.h"
49#include "object_map.h"
50#include "object_base.h"
51#include "ai/ai.hpp"
52#include "game/game.hpp"
53#include "town_cmd.h"
54#include "landscape_cmd.h"
55#include "road_cmd.h"
56#include "terraform_cmd.h"
57#include "tunnelbridge_cmd.h"
58#include "map_func.h"
59#include "timer/timer.h"
63
64#include "table/strings.h"
65#include "table/town_land.h"
66
67#include "safeguards.h"
68
69/* Initialize the town-pool */
70TownPool _town_pool("Town");
72
73
74TownKdtree _town_kdtree{};
75
76void RebuildTownKdtree()
77{
78 std::vector<TownID> townids;
79 for (const Town *town : Town::Iterate()) {
80 townids.push_back(town->index);
81 }
82 _town_kdtree.Build(townids.begin(), townids.end());
83}
84
86static bool _generating_town = false;
87
97static bool TestTownOwnsBridge(TileIndex tile, const Town *t)
98{
99 if (!IsTileOwner(tile, OWNER_TOWN)) return false;
100
102 bool town_owned = IsTileType(adjacent, MP_ROAD) && IsTileOwner(adjacent, OWNER_TOWN) && GetTownIndex(adjacent) == t->index;
103
104 if (!town_owned) {
105 /* Or other adjacent road */
107 town_owned = IsTileType(adjacent, MP_ROAD) && IsTileOwner(adjacent, OWNER_TOWN) && GetTownIndex(adjacent) == t->index;
108 }
109
110 return town_owned;
111}
112
114{
115 if (CleaningPool()) return;
116
117 /* Delete town authority window
118 * and remove from list of sorted towns */
121
122#ifdef WITH_ASSERT
123 /* Check no industry is related to us. */
124 for (const Industry *i : Industry::Iterate()) {
125 assert(i->town != this);
126 }
127
128 /* ... and no object is related to us. */
129 for (const Object *o : Object::Iterate()) {
130 assert(o->town != this);
131 }
132
133 /* Check no tile is related to us. */
134 for (const auto tile : Map::Iterate()) {
135 switch (GetTileType(tile)) {
136 case MP_HOUSE:
137 assert(GetTownIndex(tile) != this->index);
138 break;
139
140 case MP_ROAD:
141 assert(!HasTownOwnedRoad(tile) || GetTownIndex(tile) != this->index);
142 break;
143
144 case MP_TUNNELBRIDGE:
145 assert(!TestTownOwnsBridge(tile, this));
146 break;
147
148 default:
149 break;
150 }
151 }
152#endif /* WITH_ASSERT */
153
154 /* Clear the persistent storage list. */
155 for (auto &psa : this->psa_list) {
156 delete psa;
157 }
158 this->psa_list.clear();
159
160 Source src{this->index, SourceType::Town};
165}
166
167
173{
174 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_REBUILD);
176
177 /* Give objects a new home! */
178 for (Object *o : Object::Iterate()) {
179 if (o->town == nullptr) o->town = CalcClosestTownFromTile(o->location.tile, UINT_MAX);
180 }
181}
182
188{
189 if (layout != TL_RANDOM) {
190 this->layout = layout;
191 return;
192 }
193
194 this->layout = static_cast<TownLayout>(TileHash(TileX(this->xy), TileY(this->xy)) % (NUM_TLS - 1));
195}
196
201/* static */ Town *Town::GetRandom()
202{
203 if (Town::GetNumItems() == 0) return nullptr;
204 int num = RandomRange((uint16_t)Town::GetNumItems());
205 size_t index = std::numeric_limits<size_t>::max();
206
207 while (num >= 0) {
208 num--;
209 index++;
210
211 /* Make sure we have a valid town */
212 while (!Town::IsValidID(index)) {
213 index++;
214 assert(index < Town::GetPoolSize());
215 }
216 }
217
218 return Town::Get(index);
219}
220
221void Town::FillCachedName() const
222{
223 this->cached_name = GetTownName(this);
224}
225
231{
232 return (_price[PR_CLEAR_HOUSE] * this->removal_cost) >> 8;
233}
234
235static bool TryBuildTownHouse(Town *t, TileIndex tile, TownExpandModes modes);
236static Town *CreateRandomTown(uint attempts, uint32_t townnameparts, TownSize size, bool city, TownLayout layout);
237
238static void TownDrawHouseLift(const TileInfo *ti)
239{
240 AddChildSpriteScreen(SPR_LIFT, PAL_NONE, 14, 60 - GetLiftPosition(ti->tile));
241}
242
243typedef void TownDrawTileProc(const TileInfo *ti);
244static TownDrawTileProc * const _town_draw_tile_procs[1] = {
245 TownDrawHouseLift
246};
247
254{
256}
257
262static void DrawTile_Town(TileInfo *ti)
263{
264 HouseID house_id = GetHouseType(ti->tile);
265
266 if (house_id >= NEW_HOUSE_OFFSET) {
267 /* Houses don't necessarily need new graphics. If they don't have a
268 * spritegroup associated with them, then the sprite for the substitute
269 * house id is drawn instead. */
270 if (HouseSpec::Get(house_id)->grf_prop.HasSpriteGroups()) {
271 DrawNewHouseTile(ti, house_id);
272 return;
273 } else {
274 house_id = HouseSpec::Get(house_id)->grf_prop.subst_id;
275 }
276 }
277
278 /* Retrieve pointer to the draw town tile struct */
279 const DrawBuildingsTileStruct *dcts = &_town_draw_tile_data[house_id << 4 | TileHash2Bit(ti->x, ti->y) << 2 | GetHouseBuildingStage(ti->tile)];
280
282
283 DrawGroundSprite(dcts->ground.sprite, dcts->ground.pal);
284
285 /* If houses are invisible, do not draw the upper part */
286 if (IsInvisibilitySet(TO_HOUSES)) return;
287
288 /* Add a house on top of the ground? */
289 SpriteID image = dcts->building.sprite;
290 if (image != 0) {
291 AddSortableSpriteToDraw(image, dcts->building.pal, *ti, *dcts, IsTransparencySet(TO_HOUSES));
292
293 if (IsTransparencySet(TO_HOUSES)) return;
294 }
295
296 {
297 int proc = dcts->draw_proc - 1;
298
299 if (proc >= 0) _town_draw_tile_procs[proc](ti);
300 }
301}
302
303static int GetSlopePixelZ_Town(TileIndex tile, uint, uint, bool)
304{
305 return GetTileMaxPixelZ(tile);
306}
307
314{
315 HouseID hid = GetHouseType(tile);
316
317 /* For NewGRF house tiles we might not be drawing a foundation. We need to
318 * account for this, as other structures should
319 * draw the wall of the foundation in this case.
320 */
321 if (hid >= NEW_HOUSE_OFFSET) {
322 const HouseSpec *hs = HouseSpec::Get(hid);
324 uint32_t callback_res = GetHouseCallback(CBID_HOUSE_DRAW_FOUNDATIONS, 0, 0, hid, Town::GetByTile(tile), tile);
325 if (callback_res != CALLBACK_FAILED && !ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DRAW_FOUNDATIONS, callback_res)) return FOUNDATION_NONE;
326 }
327 }
328 return FlatteningFoundation(tileh);
329}
330
338{
339 if (GetHouseType(tile) >= NEW_HOUSE_OFFSET) {
340 AnimateNewHouseTile(tile);
341 return;
342 }
343
344 if (TimerGameTick::counter & 3) return;
345
346 /* If the house is not one with a lift anymore, then stop this animating.
347 * Not exactly sure when this happens, but probably when a house changes.
348 * Before this was just a return...so it'd leak animated tiles..
349 * That bug seems to have been here since day 1?? */
350 if (!HouseSpec::Get(GetHouseType(tile))->building_flags.Test(BuildingFlag::IsAnimated)) {
351 DeleteAnimatedTile(tile);
352 return;
353 }
354
355 if (!LiftHasDestination(tile)) {
356 uint i;
357
358 /* Building has 6 floors, number 0 .. 6, where 1 is illegal.
359 * This is due to the fact that the first floor is, in the graphics,
360 * the height of 2 'normal' floors.
361 * Furthermore, there are 6 lift positions from floor N (incl) to floor N + 1 (excl) */
362 do {
363 i = RandomRange(7);
364 } while (i == 1 || i * 6 == GetLiftPosition(tile));
365
366 SetLiftDestination(tile, i);
367 }
368
369 int pos = GetLiftPosition(tile);
370 int dest = GetLiftDestination(tile) * 6;
371 pos += (pos < dest) ? 1 : -1;
372 SetLiftPosition(tile, pos);
373
374 if (pos == dest) {
375 HaltLift(tile);
376 DeleteAnimatedTile(tile);
377 }
378
380}
381
388static bool IsCloseToTown(TileIndex tile, uint dist)
389{
390 if (_town_kdtree.Count() == 0) return false;
391 Town *t = Town::Get(_town_kdtree.FindNearest(TileX(tile), TileY(tile)));
392 return DistanceManhattan(tile, t->xy) < dist;
393}
394
397{
398 Point pt = RemapCoords2(TileX(this->xy) * TILE_SIZE, TileY(this->xy) * TILE_SIZE);
399
400 if (this->cache.sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeTown(this->index));
401
402 std::string town_string;
403 if (this->larger_town) {
404 town_string = GetString(_settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_CITY_POP : STR_VIEWPORT_TOWN_CITY, this->index, this->cache.population);
405 } else {
406 town_string = GetString(_settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_POP : STR_TOWN_NAME, this->index, this->cache.population);
407 }
408
409 this->cache.sign.UpdatePosition(pt.x, pt.y - 24 * ZOOM_BASE,
410 town_string,
411 GetString(STR_TOWN_NAME, this->index, this->cache.population)
412);
413
414 _viewport_sign_kdtree.Insert(ViewportSignKdtreeItem::MakeTown(this->index));
415
417}
418
421{
422 for (Town *t : Town::Iterate()) {
423 t->UpdateVirtCoord();
424 }
425}
426
429{
430 for (Town *t : Town::Iterate()) {
431 t->cached_name.clear();
432 }
433}
434
440static void ChangePopulation(Town *t, int mod)
441{
442 t->cache.population += mod;
443 if (_generating_town) [[unlikely]] return;
444
445 InvalidateWindowData(WC_TOWN_VIEW, t->index); // Cargo requirements may appear/vanish for small populations
447
448 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_POPULATION_CHANGE);
449}
450
456{
457 uint32_t pop = 0;
458 for (const Town *t : Town::Iterate()) pop += t->cache.population;
459 return pop;
460}
461
470{
471 for (StationList::iterator it = t->stations_near.begin(); it != t->stations_near.end(); /* incremented inside loop */) {
472 const Station *st = *it;
473
474 bool covers_area = st->TileIsInCatchment(tile);
475 if (flags.Any(BUILDING_2_TILES_Y)) covers_area |= st->TileIsInCatchment(tile + TileDiffXY(0, 1));
476 if (flags.Any(BUILDING_2_TILES_X)) covers_area |= st->TileIsInCatchment(tile + TileDiffXY(1, 0));
477 if (flags.Any(BUILDING_HAS_4_TILES)) covers_area |= st->TileIsInCatchment(tile + TileDiffXY(1, 1));
478
479 if (covers_area && !st->CatchmentCoversTown(t->index)) {
480 it = t->stations_near.erase(it);
481 } else {
482 ++it;
483 }
484 }
485}
486
492{
493 assert(IsTileType(tile, MP_HOUSE));
494
495 /* Progress in construction stages */
497 if (GetHouseConstructionTick(tile) != 0) return;
498
499 TriggerHouseAnimation_ConstructionStageChanged(tile, false);
500
501 if (IsHouseCompleted(tile)) {
502 /* Now that construction is complete, we can add the population of the
503 * building to the town. */
504 ChangePopulation(Town::GetByTile(tile), HouseSpec::Get(GetHouseType(tile))->population);
505 ResetHouseAge(tile);
506 }
508}
509
515{
517 if (flags.Any(BUILDING_HAS_1_TILE)) AdvanceSingleHouseConstruction(TileAddXY(tile, 0, 0));
518 if (flags.Any(BUILDING_2_TILES_Y)) AdvanceSingleHouseConstruction(TileAddXY(tile, 0, 1));
519 if (flags.Any(BUILDING_2_TILES_X)) AdvanceSingleHouseConstruction(TileAddXY(tile, 1, 0));
520 if (flags.Any(BUILDING_HAS_4_TILES)) AdvanceSingleHouseConstruction(TileAddXY(tile, 1, 1));
521}
522
531static void TownGenerateCargo(Town *t, CargoType cargo, uint amount, StationFinder &stations, bool affected_by_recession)
532{
533 if (amount == 0) return;
534
535 /* All production is halved during a recession (except for NewGRF-supplied town cargo). */
536 if (affected_by_recession && EconomyIsInRecession()) {
537 amount = (amount + 1) >> 1;
538 }
539
540 /* Scale by cargo scale setting. */
541 amount = ScaleByCargoScale(amount, true);
542 if (amount == 0) return;
543
544 /* Actually generate cargo and update town statistics. */
545 auto &supplied = t->GetOrCreateCargoSupplied(cargo);
546 supplied.history[THIS_MONTH].production += amount;
547 supplied.history[THIS_MONTH].transported += MoveGoodsToStation(cargo, amount, {t->index, SourceType::Town}, stations.GetStations());;
548}
549
557static void TownGenerateCargoOriginal(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
558{
559 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[tpe]) {
560 uint32_t r = Random();
561 if (GB(r, 0, 8) < rate) {
562 CargoType cargo_type = cs->Index();
563 uint amt = (GB(r, 0, 8) * cs->town_production_multiplier / TOWN_PRODUCTION_DIVISOR) / 8 + 1;
564
565 TownGenerateCargo(t, cargo_type, amt, stations, true);
566 }
567 }
568}
569
577static void TownGenerateCargoBinomial(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
578{
579 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[tpe]) {
580 CargoType cargo_type = cs->Index();
581 uint32_t r = Random();
582
583 /* Make a bitmask with up to 32 bits set, one for each potential pax. */
584 int genmax = (rate + 7) / 8;
585 uint32_t genmask = (genmax >= 32) ? 0xFFFFFFFF : ((1 << genmax) - 1);
586
587 /* Mask random value by potential pax and count number of actual pax. */
588 uint amt = CountBits(r & genmask) * cs->town_production_multiplier / TOWN_PRODUCTION_DIVISOR;
589
590 TownGenerateCargo(t, cargo_type, amt, stations, true);
591 }
592}
593
600static void TileLoop_Town(TileIndex tile)
601{
602 HouseID house_id = GetHouseType(tile);
603
604 /* NewHouseTileLoop returns false if Callback 21 succeeded, i.e. the house
605 * doesn't exist any more, so don't continue here. */
606 if (house_id >= NEW_HOUSE_OFFSET && !NewHouseTileLoop(tile)) return;
607
608 if (!IsHouseCompleted(tile)) {
609 /* Construction is not completed, so we advance a construction stage. */
611 return;
612 }
613
614 const HouseSpec *hs = HouseSpec::Get(house_id);
615
616 /* If the lift has a destination, it is already an animated tile. */
617 if (hs->building_flags.Test(BuildingFlag::IsAnimated) &&
618 house_id < NEW_HOUSE_OFFSET &&
619 !LiftHasDestination(tile) &&
620 Chance16(1, 2)) {
621 AddAnimatedTile(tile);
622 }
623
624 Town *t = Town::GetByTile(tile);
625 uint32_t r = Random();
626
627 StationFinder stations(TileArea(tile, 1, 1));
628
630 for (uint i = 0; i < 256; i++) {
631 uint16_t callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, r, house_id, t, tile);
632
633 if (callback == CALLBACK_FAILED || callback == CALLBACK_HOUSEPRODCARGO_END) break;
634
635 CargoType cargo = GetCargoTranslation(GB(callback, 8, 7), hs->grf_prop.grffile);
636 if (!IsValidCargoType(cargo)) continue;
637
638 uint amt = GB(callback, 0, 8);
639 if (amt == 0) continue;
640
641 /* NewGRF-supplied town cargos are not affected by recessions. */
642 TownGenerateCargo(t, cargo, amt, stations, false);
643 }
644 } else {
646 case TCGM_ORIGINAL:
647 /* Original (quadratic) cargo generation algorithm */
650 break;
651
652 case TCGM_BITCOUNT:
653 /* Binomial distribution per tick, by a series of coin flips */
654 /* Reduce generation rate to a 1/4, using tile bits to spread out distribution.
655 * As tick counter is incremented by 256 between each call, we ignore the lower 8 bits. */
656 if (GB(TimerGameTick::counter, 8, 2) == GB(tile.base(), 0, 2)) {
659 }
660 break;
661
662 default:
663 NOT_REACHED();
664 }
665 }
666
668
669 if (hs->building_flags.Any(BUILDING_HAS_1_TILE) &&
671 CanDeleteHouse(tile) &&
672 GetHouseAge(tile) >= hs->minimum_life &&
673 --t->time_until_rebuild == 0) {
674 t->time_until_rebuild = GB(r, 16, 8) + 192;
675
676 ClearTownHouse(t, tile);
677
678 /* Rebuild with another house? */
679 if (GB(r, 24, 8) >= 12) {
680 /* If we are multi-tile houses, make sure to replace the house
681 * closest to city center. If we do not do this, houses tend to
682 * wander away from roads and other houses. */
683 if (hs->building_flags.Any(BUILDING_HAS_2_TILES)) {
684 /* House tiles are always the most north tile. Move the new
685 * house to the south if we are north of the city center. */
686 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
687 int x = Clamp(grid_pos.x, 0, 1);
688 int y = Clamp(grid_pos.y, 0, 1);
689
690 if (hs->building_flags.Test(BuildingFlag::Size2x2)) {
691 tile = TileAddXY(tile, x, y);
692 } else if (hs->building_flags.Test(BuildingFlag::Size1x2)) {
693 tile = TileAddXY(tile, 0, y);
694 } else if (hs->building_flags.Test(BuildingFlag::Size2x1)) {
695 tile = TileAddXY(tile, x, 0);
696 }
697 }
698
701
702 TryBuildTownHouse(t, tile, modes);
703 }
704 }
705
706 cur_company.Restore();
707}
708
716{
717 if (flags.Test(DoCommandFlag::Auto)) return CommandCost(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
718 if (!CanDeleteHouse(tile)) return CommandCost(STR_ERROR_BUILDING_IS_PROTECTED);
719
720 const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
721
723 cost.AddCost(hs->GetRemovalCost());
724
725 int rating = hs->remove_rating_decrease;
726 Town *t = Town::GetByTile(tile);
727
730 /* NewGRFs can add indestructible houses. */
731 if (rating > RATING_MAXIMUM) {
732 return CommandCost(STR_ERROR_BUILDING_IS_PROTECTED);
733 }
734 /* If town authority controls removal, check the company's rating. */
735 if (rating > t->ratings[_current_company] && _settings_game.difficulty.town_council_tolerance != TOWN_COUNCIL_PERMISSIVE) {
736 return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index);
737 }
738 }
739 }
740
741 ChangeTownRating(t, -rating, RATING_HOUSE_MINIMUM, flags);
742 if (flags.Test(DoCommandFlag::Execute)) {
743 ClearTownHouse(t, tile);
744 }
745
746 return cost;
747}
748
749static void AddProducedCargo_Town(TileIndex tile, CargoArray &produced)
750{
751 HouseID house_id = GetHouseType(tile);
752 const HouseSpec *hs = HouseSpec::Get(house_id);
753 Town *t = Town::GetByTile(tile);
754
756 for (uint i = 0; i < 256; i++) {
757 uint16_t callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, 0, house_id, t, tile);
758
759 if (callback == CALLBACK_FAILED || callback == CALLBACK_HOUSEPRODCARGO_END) break;
760
761 CargoType cargo = GetCargoTranslation(GB(callback, 8, 7), hs->grf_prop.grffile);
762
763 if (!IsValidCargoType(cargo)) continue;
764 produced[cargo]++;
765 }
766 } else {
767 if (hs->population > 0) {
768 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_PASSENGERS]) {
769 produced[cs->Index()]++;
770 }
771 }
772 if (hs->mail_generation > 0) {
773 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_MAIL]) {
774 produced[cs->Index()]++;
775 }
776 }
777 }
778}
779
787static void AddAcceptedCargoSetMask(CargoType cargo, uint amount, CargoArray &acceptance, CargoTypes &always_accepted)
788{
789 if (!IsValidCargoType(cargo) || amount == 0) return;
790 acceptance[cargo] += amount;
791 SetBit(always_accepted, cargo);
792}
793
803void AddAcceptedCargoOfHouse(TileIndex tile, HouseID house, const HouseSpec *hs, Town *t, CargoArray &acceptance, CargoTypes &always_accepted)
804{
805 CargoType accepts[lengthof(hs->accepts_cargo)];
806
807 /* Set the initial accepted cargo types */
808 for (uint8_t i = 0; i < lengthof(accepts); i++) {
809 accepts[i] = hs->accepts_cargo[i];
810 }
811
812 /* Check for custom accepted cargo types */
814 uint16_t callback = GetHouseCallback(CBID_HOUSE_ACCEPT_CARGO, 0, 0, house, t, tile, {}, tile == INVALID_TILE);
815 if (callback != CALLBACK_FAILED) {
816 /* Replace accepted cargo types with translated values from callback */
817 accepts[0] = GetCargoTranslation(GB(callback, 0, 5), hs->grf_prop.grffile);
818 accepts[1] = GetCargoTranslation(GB(callback, 5, 5), hs->grf_prop.grffile);
819 accepts[2] = GetCargoTranslation(GB(callback, 10, 5), hs->grf_prop.grffile);
820 }
821 }
822
823 /* Check for custom cargo acceptance */
825 uint16_t callback = GetHouseCallback(CBID_HOUSE_CARGO_ACCEPTANCE, 0, 0, house, t, tile, {}, tile == INVALID_TILE);
826 if (callback != CALLBACK_FAILED) {
827 AddAcceptedCargoSetMask(accepts[0], GB(callback, 0, 4), acceptance, always_accepted);
828 AddAcceptedCargoSetMask(accepts[1], GB(callback, 4, 4), acceptance, always_accepted);
829 if (_settings_game.game_creation.landscape != LandscapeType::Temperate && HasBit(callback, 12)) {
830 /* The 'S' bit indicates food instead of goods */
831 AddAcceptedCargoSetMask(GetCargoTypeByLabel(CT_FOOD), GB(callback, 8, 4), acceptance, always_accepted);
832 } else {
833 AddAcceptedCargoSetMask(accepts[2], GB(callback, 8, 4), acceptance, always_accepted);
834 }
835 return;
836 }
837 }
838
839 /* No custom acceptance, so fill in with the default values */
840 for (uint8_t i = 0; i < lengthof(accepts); i++) {
841 AddAcceptedCargoSetMask(accepts[i], hs->cargo_acceptance[i], acceptance, always_accepted);
842 }
843}
844
845static void AddAcceptedCargo_Town(TileIndex tile, CargoArray &acceptance, CargoTypes &always_accepted)
846{
847 HouseID house = GetHouseType(tile);
848 AddAcceptedCargoOfHouse(tile, house, HouseSpec::Get(house), Town::GetByTile(tile), acceptance, always_accepted);
849}
850
857{
858 CargoTypes always_accepted{};
859 CargoArray acceptance{};
860 AddAcceptedCargoOfHouse(INVALID_TILE, hs->Index(), hs, nullptr, acceptance, always_accepted);
861 return acceptance;
862}
863
864static void GetTileDesc_Town(TileIndex tile, TileDesc &td)
865{
866 const HouseID house = GetHouseType(tile);
867 const HouseSpec *hs = HouseSpec::Get(house);
868 bool house_completed = IsHouseCompleted(tile);
869
870 td.str = hs->building_name;
872
873 std::array<int32_t, 1> regs100;
874 uint16_t callback_res = GetHouseCallback(CBID_HOUSE_CUSTOM_NAME, house_completed ? 1 : 0, 0, house, Town::GetByTile(tile), tile, regs100);
875 if (callback_res != CALLBACK_FAILED && callback_res != 0x400) {
876 StringID new_name = STR_NULL;
877 if (callback_res == 0x40F) {
878 new_name = GetGRFStringID(hs->grf_prop.grfid, static_cast<GRFStringID>(regs100[0]));
879 } else if (callback_res > 0x400) {
881 } else {
882 new_name = GetGRFStringID(hs->grf_prop.grfid, GRFSTR_MISC_GRF_TEXT + callback_res);
883 }
884 if (new_name != STR_NULL && new_name != STR_UNDEFINED) {
885 td.str = new_name;
886 }
887 }
888
889 if (!house_completed) {
890 td.dparam = td.str;
891 td.str = STR_LAI_TOWN_INDUSTRY_DESCRIPTION_UNDER_CONSTRUCTION;
892 }
893
894 if (hs->grf_prop.HasGrfFile()) {
895 const GRFConfig *gc = GetGRFConfig(hs->grf_prop.grfid);
896 td.grf = gc->GetName();
897 }
898
899 td.owner[0] = OWNER_TOWN;
900}
901
902static TrackStatus GetTileTrackStatus_Town(TileIndex, TransportType, uint, DiagDirection)
903{
904 /* not used */
905 return 0;
906}
907
908static void ChangeTileOwner_Town(TileIndex, Owner, Owner)
909{
910 /* not used */
911}
912
913static bool GrowTown(Town *t, TownExpandModes modes);
914
919static void TownTickHandler(Town *t)
920{
924 int i = (int)t->grow_counter - 1;
925 if (i < 0) {
926 if (GrowTown(t, modes)) {
927 i = t->growth_rate;
928 } else {
929 /* If growth failed wait a bit before retrying */
930 i = std::min<uint16_t>(t->growth_rate, Ticks::TOWN_GROWTH_TICKS - 1);
931 }
932 }
933 t->grow_counter = i;
934 }
935}
936
939{
940 if (_game_mode == GM_EDITOR) return;
941
942 for (Town *t : Town::Iterate()) {
944 }
945}
946
953{
954 if (IsRoadDepotTile(tile) || IsBayRoadStopTile(tile)) return ROAD_NONE;
955
956 return GetAnyRoadBits(tile, RTT_ROAD, true);
957}
958
964{
965 RoadType best_rt = ROADTYPE_ROAD;
966 const RoadTypeInfo *best = nullptr;
967 const uint16_t assume_max_speed = 50;
968
970 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
971
972 /* Can town build this road. */
973 if (!rti->flags.Test(RoadTypeFlag::TownBuild)) continue;
974
975 /* Not yet introduced at this date. */
977
978 if (best != nullptr) {
979 if ((rti->max_speed == 0 ? assume_max_speed : rti->max_speed) < (best->max_speed == 0 ? assume_max_speed : best->max_speed)) continue;
980 }
981
982 best_rt = rt;
983 best = rti;
984 }
985
986 return best_rt;
987}
988
994{
995 const RoadTypeInfo *best = nullptr;
997 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
998
999 if (!rti->flags.Test(RoadTypeFlag::TownBuild)) continue; // Town can't build this road type.
1000
1001 if (best != nullptr && rti->introduction_date >= best->introduction_date) continue;
1002 best = rti;
1003 }
1004
1005 if (best == nullptr) return TimerGameCalendar::Date(INT32_MAX);
1006 return best->introduction_date;
1007}
1008
1014{
1015 auto min_date = GetTownRoadTypeFirstIntroductionDate();
1016 if (min_date <= TimerGameCalendar::date) return true;
1017
1018 if (min_date < INT32_MAX) {
1020 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_YET),
1021 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_YET_EXPLANATION, min_date),
1022 WL_CRITICAL);
1023 } else {
1025 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_AT_ALL),
1026 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_AT_ALL_EXPLANATION), WL_CRITICAL);
1027 }
1028 return false;
1029}
1030
1041static bool IsNeighbourRoadTile(TileIndex tile, const DiagDirection dir, uint dist_multi)
1042{
1043 if (!IsValidTile(tile)) return false;
1044
1045 /* Lookup table for the used diff values */
1046 const TileIndexDiff tid_lt[3] = {
1050 };
1051
1052 dist_multi = (dist_multi + 1) * 4;
1053 for (uint pos = 4; pos < dist_multi; pos++) {
1054 /* Go (pos / 4) tiles to the left or the right */
1055 TileIndexDiff cur = tid_lt[(pos & 1) ? 0 : 1] * (pos / 4);
1056
1057 /* Use the current tile as origin, or go one tile backwards */
1058 if (pos & 2) cur += tid_lt[2];
1059
1060 /* Test for roadbit parallel to dir and facing towards the middle axis */
1061 if (IsValidTile(tile + cur) &&
1062 GetTownRoadBits(TileAdd(tile, cur)) & DiagDirToRoadBits((pos & 2) ? dir : ReverseDiagDir(dir))) return true;
1063 }
1064 return false;
1065}
1066
1076{
1077 if (DistanceFromEdge(tile) == 0) return false;
1078
1079 /* Prevent towns from building roads under bridges along the bridge. Looks silly. */
1080 if (IsBridgeAbove(tile) && GetBridgeAxis(tile) == DiagDirToAxis(dir)) return false;
1081
1082 /* Check if there already is a road at this point? */
1083 if (GetTownRoadBits(tile) == ROAD_NONE) {
1084 /* No, try if we are able to build a road piece there.
1085 * If that fails clear the land, and if that fails exit.
1086 * This is to make sure that we can build a road here later. */
1090 return false;
1091 }
1092 }
1093
1094 Slope cur_slope = _settings_game.construction.build_on_slopes ? std::get<0>(GetFoundationSlope(tile)) : GetTileSlope(tile);
1095 bool ret = !IsNeighbourRoadTile(tile, dir, t->layout == TL_ORIGINAL ? 1 : 2);
1096 if (cur_slope == SLOPE_FLAT) return ret;
1097
1098 /* If the tile is not a slope in the right direction, then
1099 * maybe terraform some. */
1100 Slope desired_slope = (dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? SLOPE_NW : SLOPE_NE;
1101 if (desired_slope != cur_slope && ComplementSlope(desired_slope) != cur_slope) {
1102 if (Chance16(1, 8)) {
1103 CommandCost res = CMD_ERROR;
1104 if (!_generating_world && Chance16(1, 10)) {
1105 /* Note: Do not replace "^ SLOPE_ELEVATED" with ComplementSlope(). The slope might be steep. */
1107 tile, Chance16(1, 16) ? cur_slope : cur_slope ^ SLOPE_ELEVATED, false));
1108 }
1109 if (res.Failed() && Chance16(1, 3)) {
1110 /* We can consider building on the slope, though. */
1111 return ret;
1112 }
1113 }
1114 return false;
1115 }
1116 return ret;
1117}
1118
1119static bool TerraformTownTile(TileIndex tile, Slope edges, bool dir)
1120{
1121 assert(tile < Map::Size());
1122
1124 if (r.Failed() || r.GetCost() >= (_price[PR_TERRAFORM] + 2) * 8) return false;
1126 return true;
1127}
1128
1129static void LevelTownLand(TileIndex tile)
1130{
1131 assert(tile < Map::Size());
1132
1133 /* Don't terraform if land is plain or if there's a house there. */
1134 if (IsTileType(tile, MP_HOUSE)) return;
1135 Slope tileh = GetTileSlope(tile);
1136 if (tileh == SLOPE_FLAT) return;
1137
1138 /* First try up, then down */
1139 if (!TerraformTownTile(tile, ~tileh & SLOPE_ELEVATED, true)) {
1140 TerraformTownTile(tile, tileh & SLOPE_ELEVATED, false);
1141 }
1142}
1143
1153{
1154 /* align the grid to the downtown */
1155 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile); // Vector from downtown to the tile
1156 RoadBits rcmd = ROAD_NONE;
1157
1158 switch (t->layout) {
1159 default: NOT_REACHED();
1160
1161 case TL_2X2_GRID:
1162 if ((grid_pos.x % 3) == 0) rcmd |= ROAD_Y;
1163 if ((grid_pos.y % 3) == 0) rcmd |= ROAD_X;
1164 break;
1165
1166 case TL_3X3_GRID:
1167 if ((grid_pos.x % 4) == 0) rcmd |= ROAD_Y;
1168 if ((grid_pos.y % 4) == 0) rcmd |= ROAD_X;
1169 break;
1170 }
1171
1172 /* Optimise only X-junctions */
1173 if (rcmd != ROAD_ALL) return rcmd;
1174
1175 RoadBits rb_template;
1176
1177 switch (GetTileSlope(tile)) {
1178 default: rb_template = ROAD_ALL; break;
1179 case SLOPE_W: rb_template = ROAD_NW | ROAD_SW; break;
1180 case SLOPE_SW: rb_template = ROAD_Y | ROAD_SW; break;
1181 case SLOPE_S: rb_template = ROAD_SW | ROAD_SE; break;
1182 case SLOPE_SE: rb_template = ROAD_X | ROAD_SE; break;
1183 case SLOPE_E: rb_template = ROAD_SE | ROAD_NE; break;
1184 case SLOPE_NE: rb_template = ROAD_Y | ROAD_NE; break;
1185 case SLOPE_N: rb_template = ROAD_NE | ROAD_NW; break;
1186 case SLOPE_NW: rb_template = ROAD_X | ROAD_NW; break;
1187 case SLOPE_STEEP_W:
1188 case SLOPE_STEEP_S:
1189 case SLOPE_STEEP_E:
1190 case SLOPE_STEEP_N:
1191 rb_template = ROAD_NONE;
1192 break;
1193 }
1194
1195 /* Stop if the template is compatible to the growth dir */
1196 if (DiagDirToRoadBits(ReverseDiagDir(dir)) & rb_template) return rb_template;
1197 /* If not generate a straight road in the direction of the growth */
1199}
1200
1212{
1213 /* We can't look further than that. */
1214 if (DistanceFromEdge(tile) == 0) return false;
1215
1216 uint counter = 0; // counts the house neighbour tiles
1217
1218 /* Check the tiles E,N,W and S of the current tile for houses */
1219 for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
1220 /* Count both void and house tiles for checking whether there
1221 * are enough houses in the area. This to make it likely that
1222 * houses get build up to the edge of the map. */
1223 switch (GetTileType(TileAddByDiagDir(tile, dir))) {
1224 case MP_HOUSE:
1225 case MP_VOID:
1226 counter++;
1227 break;
1228
1229 default:
1230 break;
1231 }
1232
1233 /* If there are enough neighbours stop here */
1234 if (counter >= 3) {
1235 return TryBuildTownHouse(t, tile, modes);
1236 }
1237 }
1238 return false;
1239}
1240
1249static bool GrowTownWithRoad(const Town *t, TileIndex tile, RoadBits rcmd)
1250{
1253}
1254
1264static bool CanRoadContinueIntoNextTile(const Town *t, const TileIndex tile, const DiagDirection road_dir)
1265{
1266 const TileIndexDiff delta = TileOffsByDiagDir(road_dir); // +1 tile in the direction of the road
1267 TileIndex next_tile = tile + delta; // The tile beyond which must be connectable to the target tile
1268 RoadBits rcmd = DiagDirToRoadBits(ReverseDiagDir(road_dir));
1270
1271 /* Before we try anything, make sure the tile is on the map and not the void. */
1272 if (!IsValidTile(next_tile)) return false;
1273
1274 /* If the next tile is a bridge or tunnel, allow if it's continuing in the same direction. */
1275 if (IsTileType(next_tile, MP_TUNNELBRIDGE)) {
1276 return GetTunnelBridgeTransportType(next_tile) == TRANSPORT_ROAD && GetTunnelBridgeDirection(next_tile) == road_dir;
1277 }
1278
1279 /* If the next tile is a station, allow if it's a road station facing the proper direction. Otherwise return false. */
1280 if (IsTileType(next_tile, MP_STATION)) {
1281 /* If the next tile is a road station, allow if it can be entered by the new tunnel/bridge, otherwise disallow. */
1282 if (IsDriveThroughStopTile(next_tile)) return GetDriveThroughStopAxis(next_tile) == DiagDirToAxis(road_dir);
1283 if (IsBayRoadStopTile(next_tile)) return GetBayRoadStopDir(next_tile) == ReverseDiagDir(road_dir);
1284 return false;
1285 }
1286
1287 /* If the next tile is a road depot, allow if it's facing the right way. */
1288 if (IsTileType(next_tile, MP_ROAD)) {
1289 return IsRoadDepot(next_tile) && GetRoadDepotDirection(next_tile) == ReverseDiagDir(road_dir);
1290 }
1291
1292 /* If the next tile is a railroad track, check if towns are allowed to build level crossings.
1293 * If level crossing are not allowed, reject the construction. Else allow DoCommand to determine if the rail track is buildable. */
1294 if (IsTileType(next_tile, MP_RAILWAY) && !_settings_game.economy.allow_town_level_crossings) return false;
1295
1296 /* If a road tile can be built, the construction is allowed. */
1297 return Command<CMD_BUILD_ROAD>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, next_tile, rcmd, rt, DRD_NONE, t->index).Succeeded();
1298}
1299
1310static bool GrowTownWithBridge(const Town *t, const TileIndex tile, const DiagDirection bridge_dir)
1311{
1312 assert(bridge_dir < DIAGDIR_END);
1313
1314 const Slope slope = GetTileSlope(tile);
1315
1316 /* Make sure the direction is compatible with the slope.
1317 * Well we check if the slope has an up bit set in the
1318 * reverse direction. */
1319 if (slope != SLOPE_FLAT && slope & InclinedSlope(bridge_dir)) return false;
1320
1321 /* Assure that the bridge is connectable to the start side */
1322 if (!(GetTownRoadBits(TileAddByDiagDir(tile, ReverseDiagDir(bridge_dir))) & DiagDirToRoadBits(bridge_dir))) return false;
1323
1324 /* We are in the right direction */
1325 uint bridge_length = 0; // This value stores the length of the possible bridge
1326 TileIndex bridge_tile = tile; // Used to store the other waterside
1327
1328 const TileIndexDiff delta = TileOffsByDiagDir(bridge_dir);
1329
1330 /* To prevent really small towns from building disproportionately
1331 * long bridges, make the max a function of its population. */
1332 const uint TOWN_BRIDGE_LENGTH_CAP = 11;
1333 uint base_bridge_length = 5;
1334 uint max_bridge_length = std::min(t->cache.population / 1000 + base_bridge_length, TOWN_BRIDGE_LENGTH_CAP);
1335
1336 if (slope == SLOPE_FLAT) {
1337 /* Bridges starting on flat tiles are only allowed when crossing rivers, rails or one-way roads. */
1338 do {
1339 if (bridge_length++ >= base_bridge_length) {
1340 /* Allow to cross rivers, not big lakes, nor large amounts of rails or one-way roads. */
1341 return false;
1342 }
1343 bridge_tile += delta;
1344 } while (IsValidTile(bridge_tile) && ((IsWaterTile(bridge_tile) && !IsSea(bridge_tile)) || IsPlainRailTile(bridge_tile) || (IsNormalRoadTile(bridge_tile) && GetDisallowedRoadDirections(bridge_tile) != DRD_NONE)));
1345 } else {
1346 do {
1347 if (bridge_length++ >= max_bridge_length) {
1348 /* Ensure the bridge is not longer than the max allowed length. */
1349 return false;
1350 }
1351 bridge_tile += delta;
1352 } while (IsValidTile(bridge_tile) && (IsWaterTile(bridge_tile) || IsPlainRailTile(bridge_tile) || (IsNormalRoadTile(bridge_tile) && GetDisallowedRoadDirections(bridge_tile) != DRD_NONE)));
1353 }
1354
1355 /* Don't allow a bridge where the start and end tiles are adjacent with no span between. */
1356 if (bridge_length == 1) return false;
1357
1358 /* Make sure the road can be continued past the bridge. At this point, bridge_tile holds the end tile of the bridge. */
1359 if (!CanRoadContinueIntoNextTile(t, bridge_tile, bridge_dir)) return false;
1360
1361 /* If another parallel bridge exists nearby, this one would be redundant and shouldn't be built. We don't care about flat bridges. */
1362 if (slope != SLOPE_FLAT) {
1363 for (auto search : SpiralTileSequence(tile, bridge_length, 0, 0)) {
1364 /* Only consider bridge head tiles. */
1365 if (!IsBridgeTile(search)) continue;
1366
1367 /* Only consider road bridges. */
1368 if (GetTunnelBridgeTransportType(search) != TRANSPORT_ROAD) continue;
1369
1370 /* If the bridge is facing the same direction as the proposed bridge, we've found a redundant bridge. */
1371 if (GetTileSlope(search) & InclinedSlope(ReverseDiagDir(bridge_dir))) return false;
1372 }
1373 }
1374
1375 for (uint8_t times = 0; times <= 22; times++) {
1376 uint8_t bridge_type = RandomRange(MAX_BRIDGES - 1);
1377
1378 /* Can we actually build the bridge? */
1380 if (Command<CMD_BUILD_BRIDGE>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_BRIDGE>()), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, rt).Succeeded()) {
1381 Command<CMD_BUILD_BRIDGE>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_BRIDGE>()).Set(DoCommandFlag::Execute), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, rt);
1382 return true;
1383 }
1384 }
1385 /* Quit if it selecting an appropriate bridge type fails a large number of times. */
1386 return false;
1387}
1388
1399static bool GrowTownWithTunnel(const Town *t, const TileIndex tile, const DiagDirection tunnel_dir)
1400{
1401 assert(tunnel_dir < DIAGDIR_END);
1402
1403 Slope slope = GetTileSlope(tile);
1404
1405 /* Only consider building a tunnel if the starting tile is sloped properly. */
1406 if (slope != InclinedSlope(tunnel_dir)) return false;
1407
1408 /* Assure that the tunnel is connectable to the start side */
1409 if (!(GetTownRoadBits(TileAddByDiagDir(tile, ReverseDiagDir(tunnel_dir))) & DiagDirToRoadBits(tunnel_dir))) return false;
1410
1411 const TileIndexDiff delta = TileOffsByDiagDir(tunnel_dir);
1412 int max_tunnel_length = 0;
1413
1414 /* There are two conditions for building tunnels: Under a mountain and under an obstruction. */
1415 if (CanRoadContinueIntoNextTile(t, tile, tunnel_dir)) {
1416 /* 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. */
1417 TileIndex slope_tile = tile;
1418 for (uint8_t tiles = 0; tiles < 4; tiles++) {
1419 if (!IsValidTile(slope_tile)) return false;
1420 slope = GetTileSlope(slope_tile);
1421 if (slope != InclinedSlope(tunnel_dir) && !IsSteepSlope(slope) && !IsSlopeWithOneCornerRaised(slope)) return false;
1422 slope_tile += delta;
1423 }
1424
1425 /* More population means longer tunnels, but make sure we can at least cover the smallest mountain which necessitates tunneling. */
1426 max_tunnel_length = (t->cache.population / 1000) + 7;
1427 } else {
1428 /* When tunneling under an obstruction, the length limit is 5, enough to tunnel under a four-track railway. */
1429 max_tunnel_length = 5;
1430 }
1431
1432 uint8_t tunnel_length = 0;
1433 TileIndex tunnel_tile = tile; // Iterator to store the other end tile of the tunnel.
1434
1435 /* Find the end tile of the tunnel for length and continuation checks. */
1436 do {
1437 if (tunnel_length++ >= max_tunnel_length) return false;
1438 tunnel_tile += delta;
1439 /* The tunnel ends when start and end tiles are the same height. */
1440 } while (IsValidTile(tunnel_tile) && GetTileZ(tile) != GetTileZ(tunnel_tile));
1441
1442 /* Don't allow a tunnel where the start and end tiles are adjacent. */
1443 if (tunnel_length == 1) return false;
1444
1445 /* Make sure the road can be continued past the tunnel. At this point, tunnel_tile holds the end tile of the tunnel. */
1446 if (!CanRoadContinueIntoNextTile(t, tunnel_tile, tunnel_dir)) return false;
1447
1448 /* Attempt to build the tunnel. Return false if it fails to let the town build a road instead. */
1450 if (Command<CMD_BUILD_TUNNEL>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_TUNNEL>()), tile, TRANSPORT_ROAD, rt).Succeeded()) {
1451 Command<CMD_BUILD_TUNNEL>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_TUNNEL>()).Set(DoCommandFlag::Execute), tile, TRANSPORT_ROAD, rt);
1452 return true;
1453 }
1454
1455 return false;
1456}
1457
1465{
1466 static const TileIndexDiffC tiles[] = { {-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1} };
1467 bool allow = false;
1468
1469 for (const auto &ptr : tiles) {
1470 TileIndex cur_tile = t + ToTileIndexDiff(ptr);
1471 if (!IsValidTile(cur_tile)) continue;
1472
1473 if (!(IsTileType(cur_tile, MP_ROAD) || IsAnyRoadStopTile(cur_tile))) continue;
1474 allow = true;
1475
1476 RoadType road_rt = GetRoadTypeRoad(cur_tile);
1477 RoadType tram_rt = GetRoadTypeTram(cur_tile);
1478 if (road_rt != INVALID_ROADTYPE && !GetRoadTypeInfo(road_rt)->flags.Test(RoadTypeFlag::NoHouses)) return true;
1479 if (tram_rt != INVALID_ROADTYPE && !GetRoadTypeInfo(tram_rt)->flags.Test(RoadTypeFlag::NoHouses)) return true;
1480 }
1481
1482 /* If no road was found surrounding the tile we can allow building the house since there is
1483 * nothing which forbids it, if a road was found but the execution reached this point, then
1484 * all the found roads don't allow houses to be built */
1485 return !allow;
1486}
1487
1493{
1494 if (!IsTileType(tile, MP_ROAD)) return true;
1495
1496 /* Allow extending on roadtypes which can be built by town, or if the road type matches the type the town will build. */
1497 RoadType rt = GetRoadTypeRoad(tile);
1499}
1500
1506{
1507 return modes.Test(TownExpandMode::Roads);
1508}
1509
1510/* The possible states of town growth. */
1511enum class TownGrowthResult {
1512 Succeed,
1513 SearchStopped,
1514 Continue,
1515};
1516
1535static TownGrowthResult GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection target_dir, Town *t1, TownExpandModes modes)
1536{
1537 RoadBits rcmd = ROAD_NONE; // RoadBits for the road construction command
1538 TileIndex tile = *tile_ptr; // The main tile on which we base our growth
1539
1540 assert(tile < Map::Size());
1541
1542 if (cur_rb == ROAD_NONE) {
1543 /* Tile has no road.
1544 * We will return TownGrowthResult::SearchStopped to say that this is the last iteration. */
1545
1546 if (!TownAllowedToBuildRoads(modes)) return TownGrowthResult::SearchStopped;
1547 if (!_settings_game.economy.allow_town_level_crossings && IsTileType(tile, MP_RAILWAY)) return TownGrowthResult::SearchStopped;
1548
1549 /* Remove hills etc */
1550 if (!_settings_game.construction.build_on_slopes || Chance16(1, 6)) LevelTownLand(tile);
1551
1552 /* Is a road allowed here? */
1553 switch (t1->layout) {
1554 default: NOT_REACHED();
1555
1556 case TL_3X3_GRID:
1557 case TL_2X2_GRID:
1558 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1559 if (rcmd == ROAD_NONE) return TownGrowthResult::SearchStopped;
1560 break;
1561
1562 case TL_BETTER_ROADS:
1563 case TL_ORIGINAL:
1564 if (!IsRoadAllowedHere(t1, tile, target_dir)) return TownGrowthResult::SearchStopped;
1565
1566 DiagDirection source_dir = ReverseDiagDir(target_dir);
1567
1568 if (Chance16(1, 4)) {
1569 /* Randomize a new target dir */
1570 do target_dir = RandomDiagDir(); while (target_dir == source_dir);
1571 }
1572
1573 if (!IsRoadAllowedHere(t1, TileAddByDiagDir(tile, target_dir), target_dir)) {
1574 /* A road is not allowed to continue the randomized road,
1575 * return if the road we're trying to build is curved. */
1576 if (target_dir != ReverseDiagDir(source_dir)) return TownGrowthResult::SearchStopped;
1577
1578 /* Return if neither side of the new road is a house */
1581 return TownGrowthResult::SearchStopped;
1582 }
1583
1584 /* That means that the road is only allowed if there is a house
1585 * at any side of the new road. */
1586 }
1587
1588 rcmd = DiagDirToRoadBits(target_dir) | DiagDirToRoadBits(source_dir);
1589 break;
1590 }
1591
1592 } else if (target_dir < DIAGDIR_END && !(cur_rb & DiagDirToRoadBits(ReverseDiagDir(target_dir)))) {
1593 if (!TownCanGrowRoad(tile)) return TownGrowthResult::Continue;
1594
1595 if (!TownAllowedToBuildRoads(modes)) return TownGrowthResult::SearchStopped;
1596
1597 /* Continue building on a partial road.
1598 * Should be always OK, so we only generate
1599 * the fitting RoadBits */
1600 switch (t1->layout) {
1601 default: NOT_REACHED();
1602
1603 case TL_3X3_GRID:
1604 case TL_2X2_GRID:
1605 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1606 break;
1607
1608 case TL_BETTER_ROADS:
1609 case TL_ORIGINAL:
1610 rcmd = DiagDirToRoadBits(ReverseDiagDir(target_dir));
1611 break;
1612 }
1613 } else {
1614 bool allow_house = true; // Value which decides if we want to construct a house
1615
1616 /* Reached a tunnel/bridge? Then continue at the other side of it, unless
1617 * it is the starting tile. Half the time, we stay on this side then.*/
1618 if (IsTileType(tile, MP_TUNNELBRIDGE)) {
1619 if (GetTunnelBridgeTransportType(tile) == TRANSPORT_ROAD && (target_dir != DIAGDIR_END || Chance16(1, 2))) {
1620 *tile_ptr = GetOtherTunnelBridgeEnd(tile);
1621 }
1622 return TownGrowthResult::Continue;
1623 }
1624
1625 /* Possibly extend the road in a direction.
1626 * Randomize a direction and if it has a road, bail out. */
1627 target_dir = RandomDiagDir();
1628 RoadBits target_rb = DiagDirToRoadBits(target_dir);
1629 TileIndex house_tile; // position of a possible house
1630
1631 if (cur_rb & target_rb) {
1632 /* If it's a road turn possibly build a house in a corner.
1633 * Use intersection with straight road as an indicator
1634 * that we randomised corner house position.
1635 * A turn (and we check for that later) always has only
1636 * one common bit with a straight road so it has the same
1637 * chance to be chosen as the house on the side of a road.
1638 */
1639 if ((cur_rb & ROAD_X) != target_rb) return TownGrowthResult::Continue;
1640
1641 /* Check whether it is a turn and if so determine
1642 * position of the corner tile */
1643 switch (cur_rb) {
1644 case ROAD_N:
1645 house_tile = TileAddByDir(tile, DIR_S);
1646 break;
1647 case ROAD_S:
1648 house_tile = TileAddByDir(tile, DIR_N);
1649 break;
1650 case ROAD_E:
1651 house_tile = TileAddByDir(tile, DIR_W);
1652 break;
1653 case ROAD_W:
1654 house_tile = TileAddByDir(tile, DIR_E);
1655 break;
1656 default:
1657 return TownGrowthResult::Continue; // not a turn
1658 }
1659 target_dir = DIAGDIR_END;
1660 } else {
1661 house_tile = TileAddByDiagDir(tile, target_dir);
1662 }
1663
1664 /* Don't walk into water. */
1665 if (HasTileWaterGround(house_tile)) return TownGrowthResult::Continue;
1666
1667 if (!IsValidTile(house_tile)) return TownGrowthResult::Continue;
1668
1669 TownGrowthResult result = TownGrowthResult::Continue;
1670
1671 if (target_dir != DIAGDIR_END && TownAllowedToBuildRoads(modes)) {
1672 switch (t1->layout) {
1673 default: NOT_REACHED();
1674
1675 case TL_3X3_GRID: // Use 2x2 grid afterwards!
1676 if (GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir), modes)) {
1677 result = TownGrowthResult::Succeed;
1678 }
1679 [[fallthrough]];
1680
1681 case TL_2X2_GRID:
1682 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1683 allow_house = (rcmd & target_rb) == ROAD_NONE;
1684 break;
1685
1686 case TL_BETTER_ROADS: // Use original afterwards!
1687 if (GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir), modes)) {
1688 result = TownGrowthResult::Succeed;
1689 }
1690 [[fallthrough]];
1691
1692 case TL_ORIGINAL:
1693 /* Allow a house at the edge. 60% chance or
1694 * always ok if no road allowed. */
1695 rcmd = target_rb;
1696 allow_house = (!IsRoadAllowedHere(t1, house_tile, target_dir) || Chance16(6, 10));
1697 break;
1698 }
1699 }
1700
1701 allow_house &= RoadTypesAllowHouseHere(house_tile);
1702
1703 if (allow_house) {
1704 /* Build a house, but not if there already is a house there. */
1705 if (!IsTileType(house_tile, MP_HOUSE)) {
1706 /* Level the land if possible */
1707 if (Chance16(1, 6)) LevelTownLand(house_tile);
1708
1709 /* And build a house.
1710 * Set result to -1 if we managed to build it. */
1711 if (TryBuildTownHouse(t1, house_tile, modes)) {
1712 result = TownGrowthResult::Succeed;
1713 }
1714 }
1715 return result;
1716 }
1717
1718 if (!TownCanGrowRoad(tile)) return result;
1719 }
1720
1721 /* Return if a water tile */
1722 if (HasTileWaterGround(tile)) return TownGrowthResult::SearchStopped;
1723
1724 /* Make the roads look nicer */
1725 rcmd = CleanUpRoadBits(tile, rcmd);
1726 if (rcmd == ROAD_NONE) return TownGrowthResult::SearchStopped;
1727
1728 /* Only use the target direction for bridges and tunnels to ensure they're connected.
1729 * The target_dir is as computed previously according to town layout, so
1730 * it will match it perfectly. */
1731 if (GrowTownWithBridge(t1, tile, target_dir)) {
1732 return TownGrowthResult::Succeed;
1733 }
1734 if (GrowTownWithTunnel(t1, tile, target_dir)) {
1735 return TownGrowthResult::Succeed;
1736 }
1737
1738 if (GrowTownWithRoad(t1, tile, rcmd)) {
1739 return TownGrowthResult::Succeed;
1740 }
1741 return TownGrowthResult::SearchStopped;
1742}
1743
1752{
1753 TileIndex target_tile = tile + TileOffsByDiagDir(dir);
1754 if (!IsValidTile(target_tile)) return false;
1755 if (HasTileWaterGround(target_tile)) return false;
1756
1757 RoadBits target_rb = GetTownRoadBits(target_tile);
1758 if (TownAllowedToBuildRoads(modes)) {
1759 /* Check whether a road connection exists or can be build. */
1760 switch (GetTileType(target_tile)) {
1761 case MP_ROAD:
1762 return target_rb != ROAD_NONE;
1763
1764 case MP_STATION:
1765 return IsDriveThroughStopTile(target_tile);
1766
1767 case MP_TUNNELBRIDGE:
1768 return GetTunnelBridgeTransportType(target_tile) == TRANSPORT_ROAD;
1769
1770 case MP_HOUSE:
1771 case MP_INDUSTRY:
1772 case MP_OBJECT:
1773 return false;
1774
1775 default:
1776 /* Checked for void and water earlier */
1777 return true;
1778 }
1779 } else {
1780 /* Check whether a road connection already exists,
1781 * and it leads somewhere else. */
1783 return (target_rb & back_rb) != 0 && (target_rb & ~back_rb) != 0;
1784 }
1785}
1786
1793static bool GrowTownAtRoad(Town *t, TileIndex tile, TownExpandModes modes)
1794{
1795 /* Special case.
1796 * @see GrowTownInTile Check the else if
1797 */
1798 DiagDirection target_dir = DIAGDIR_END; // The direction in which we want to extend the town
1799
1800 assert(tile < Map::Size());
1801
1802 /* Number of times to search.
1803 * Better roads, 2X2 and 3X3 grid grow quite fast so we give
1804 * them a little handicap. */
1805 int iterations;
1806 switch (t->layout) {
1807 case TL_BETTER_ROADS:
1808 iterations = 10 + t->cache.num_houses * 2 / 9;
1809 break;
1810
1811 case TL_3X3_GRID:
1812 case TL_2X2_GRID:
1813 iterations = 10 + t->cache.num_houses * 1 / 9;
1814 break;
1815
1816 default:
1817 iterations = 10 + t->cache.num_houses * 4 / 9;
1818 break;
1819 }
1820
1821 do {
1822 RoadBits cur_rb = GetTownRoadBits(tile); // The RoadBits of the current tile
1823
1824 /* Try to grow the town from this point */
1825 switch (GrowTownInTile(&tile, cur_rb, target_dir, t, modes)) {
1826 case TownGrowthResult::Succeed:
1827 return true;
1828 case TownGrowthResult::SearchStopped:
1829 iterations = 0;
1830 break;
1831 default:
1832 break;
1833 };
1834
1835 /* Exclude the source position from the bitmask
1836 * and return if no more road blocks available */
1837 if (IsValidDiagDirection(target_dir)) cur_rb &= ~DiagDirToRoadBits(ReverseDiagDir(target_dir));
1838 if (cur_rb == ROAD_NONE) return false;
1839
1840 if (IsTileType(tile, MP_TUNNELBRIDGE)) {
1841 /* Only build in the direction away from the tunnel or bridge. */
1842 target_dir = ReverseDiagDir(GetTunnelBridgeDirection(tile));
1843 } else {
1844 /* Select a random bit from the blockmask, walk a step
1845 * and continue the search from there. */
1846 do {
1847 if (cur_rb == ROAD_NONE) return false;
1848 RoadBits target_bits;
1849 do {
1850 target_dir = RandomDiagDir();
1851 target_bits = DiagDirToRoadBits(target_dir);
1852 } while (!(cur_rb & target_bits));
1853 cur_rb &= ~target_bits;
1854 } while (!CanFollowRoad(tile, target_dir, modes));
1855 }
1856 tile = TileAddByDiagDir(tile, target_dir);
1857
1858 if (IsTileType(tile, MP_ROAD) && !IsRoadDepot(tile) && HasTileRoadType(tile, RTT_ROAD)) {
1859 /* Don't allow building over roads of other cities */
1860 if (IsRoadOwner(tile, RTT_ROAD, OWNER_TOWN) && Town::GetByTile(tile) != t) {
1861 return false;
1862 } else if (IsRoadOwner(tile, RTT_ROAD, OWNER_NONE) && _game_mode == GM_EDITOR) {
1863 /* If we are in the SE, and this road-piece has no town owner yet, it just found an
1864 * owner :) (happy happy happy road now) */
1866 SetTownIndex(tile, t->index);
1867 }
1868 }
1869
1870 /* Max number of times is checked. */
1871 } while (--iterations >= 0);
1872
1873 return false;
1874}
1875
1884{
1885 uint32_t r = Random();
1886 uint a = GB(r, 0, 2);
1887 uint b = GB(r, 8, 2);
1888 if (a == b) b ^= 2;
1889 return (RoadBits)((ROAD_NW << a) + (ROAD_NW << b));
1890}
1891
1897static bool GrowTown(Town *t, TownExpandModes modes)
1898{
1899 static const TileIndexDiffC _town_coord_mod[] = {
1900 {-1, 0},
1901 { 1, 1},
1902 { 1, -1},
1903 {-1, -1},
1904 {-1, 0},
1905 { 0, 2},
1906 { 2, 0},
1907 { 0, -2},
1908 {-1, -1},
1909 {-2, 2},
1910 { 2, 2},
1911 { 2, -2},
1912 { 0, 0}
1913 };
1914
1915 /* Current "company" is a town */
1917
1918 TileIndex tile = t->xy; // The tile we are working with ATM
1919
1920 /* Find a road that we can base the construction on. */
1921 for (const auto &ptr : _town_coord_mod) {
1922 if (GetTownRoadBits(tile) != ROAD_NONE) {
1923 bool success = GrowTownAtRoad(t, tile, modes);
1924 cur_company.Restore();
1925 return success;
1926 }
1927 tile = TileAdd(tile, ToTileIndexDiff(ptr));
1928 }
1929
1930 /* No road available, try to build a random road block by
1931 * clearing some land and then building a road there. */
1932 if (TownAllowedToBuildRoads(modes)) {
1933 tile = t->xy;
1934 for (const auto &ptr : _town_coord_mod) {
1935 /* Only work with plain land that not already has a house */
1936 if (!IsTileType(tile, MP_HOUSE) && IsTileFlat(tile)) {
1940 cur_company.Restore();
1941 return true;
1942 }
1943 }
1944 tile = TileAdd(tile, ToTileIndexDiff(ptr));
1945 }
1946 }
1947
1948 cur_company.Restore();
1949 return false;
1950}
1951
1957{
1958 static const std::array<std::array<uint32_t, NUM_HOUSE_ZONES>, 23> _town_squared_town_zone_radius_data = {{
1959 { 4, 0, 0, 0, 0}, // 0
1960 { 16, 0, 0, 0, 0},
1961 { 25, 0, 0, 0, 0},
1962 { 36, 0, 0, 0, 0},
1963 { 49, 0, 4, 0, 0},
1964 { 64, 0, 4, 0, 0}, // 20
1965 { 64, 0, 9, 0, 1},
1966 { 64, 0, 9, 0, 4},
1967 { 64, 0, 16, 0, 4},
1968 { 81, 0, 16, 0, 4},
1969 { 81, 0, 16, 0, 4}, // 40
1970 { 81, 0, 25, 0, 9},
1971 { 81, 36, 25, 0, 9},
1972 { 81, 36, 25, 16, 9},
1973 { 81, 49, 0, 25, 9},
1974 { 81, 64, 0, 25, 9}, // 60
1975 { 81, 64, 0, 36, 9},
1976 { 81, 64, 0, 36, 16},
1977 {100, 81, 0, 49, 16},
1978 {100, 81, 0, 49, 25},
1979 {121, 81, 0, 49, 25}, // 80
1980 {121, 81, 0, 49, 25},
1981 {121, 81, 0, 49, 36}, // 88
1982 }};
1983
1984 if (t->cache.num_houses < std::size(_town_squared_town_zone_radius_data) * 4) {
1985 t->cache.squared_town_zone_radius = _town_squared_town_zone_radius_data[t->cache.num_houses / 4];
1986 } else {
1987 int mass = t->cache.num_houses / 8;
1988 /* Actually we are proportional to sqrt() but that's right because we are covering an area.
1989 * The offsets are to make sure the radii do not decrease in size when going from the table
1990 * to the calculated value.*/
1991 t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownEdge)] = mass * 15 - 40;
1992 t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownOutskirt)] = mass * 9 - 15;
1993 t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownOuterSuburb)] = 0;
1994 t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownInnerSuburb)] = mass * 5 - 5;
1995 t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownCentre)] = mass * 3 + 5;
1996 }
1997}
1998
2004{
2006 uint32_t production = ScaleByCargoScale(t->cache.population >> 3, true);
2007 if (production == 0) continue;
2008
2009 auto &supplied = t->GetOrCreateCargoSupplied(cs->Index());
2010 supplied.history[LAST_MONTH].production = production;
2011 }
2012
2014 uint32_t production = ScaleByCargoScale(t->cache.population >> 4, true);
2015 if (production == 0) continue;
2016
2017 auto &supplied = t->GetOrCreateCargoSupplied(cs->Index());
2018 supplied.history[LAST_MONTH].production = production;
2019 }
2020}
2021
2022static void UpdateTownGrowthRate(Town *t);
2023static void UpdateTownGrowth(Town *t);
2024
2036static void DoCreateTown(Town *t, TileIndex tile, uint32_t townnameparts, TownSize size, bool city, TownLayout layout, bool manual)
2037{
2038 AutoRestoreBackup backup(_generating_town, true);
2039
2040 t->xy = tile;
2041 t->cache.num_houses = 0;
2042 t->time_until_rebuild = 10;
2044 t->flags.Reset();
2045 t->cache.population = 0;
2047 /* Spread growth across ticks so even if there are many
2048 * similar towns they're unlikely to grow all in one tick */
2050 t->growth_rate = TownTicksToGameTicks(250);
2051 t->show_zone = false;
2052
2053 _town_kdtree.Insert(t->index);
2054
2055 /* Set the default cargo requirement for town growth */
2057 case LandscapeType::Arctic:
2059 break;
2060
2061 case LandscapeType::Tropic:
2064 break;
2065
2066 default:
2067 break;
2068 }
2069
2070 t->fund_buildings_months = 0;
2071
2072 for (uint i = 0; i != MAX_COMPANIES; i++) t->ratings[i] = RATING_INITIAL;
2073
2074 t->have_ratings = {};
2075 t->exclusivity = CompanyID::Invalid();
2076 t->exclusive_counter = 0;
2077 t->statues = {};
2078
2079 {
2081 t->townnamegrfid = tnp.grfid;
2082 t->townnametype = tnp.type;
2083 }
2084 t->townnameparts = townnameparts;
2085
2086 t->InitializeLayout(layout);
2087
2088 t->larger_town = city;
2089
2090 int x = (int)size * 16 + 3;
2091 if (size == TSZ_RANDOM) x = (Random() & 0xF) + 8;
2092 /* Don't create huge cities when founding town in-game */
2093 if (city && (!manual || _game_mode == GM_EDITOR)) x *= _settings_game.economy.initial_city_size;
2094
2095 t->cache.num_houses += x;
2097
2098 int i = x * 4;
2099 do {
2101 } while (--i);
2102
2103 t->UpdateVirtCoord();
2104 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_REBUILD);
2105
2106 t->cache.num_houses -= x;
2111}
2112
2119{
2120 /* Check if too close to the edge of map */
2121 if (DistanceFromEdge(tile) < 12) {
2122 return CommandCost(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB);
2123 }
2124
2125 /* Check distance to all other towns. */
2126 if (IsCloseToTown(tile, 20)) {
2127 return CommandCost(STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN);
2128 }
2129
2130 /* Can only build on clear flat areas, possibly with trees. */
2131 if ((!IsTileType(tile, MP_CLEAR) && !IsTileType(tile, MP_TREES)) || !IsTileFlat(tile)) {
2132 return CommandCost(STR_ERROR_SITE_UNSUITABLE);
2133 }
2134
2136}
2137
2143static bool IsUniqueTownName(const std::string &name)
2144{
2145 for (const Town *t : Town::Iterate()) {
2146 if (!t->name.empty() && t->name == name) return false;
2147 }
2148
2149 return true;
2150}
2151
2164std::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)
2165{
2167
2168 if (size >= TSZ_END) return { CMD_ERROR, 0, TownID::Invalid() };
2169 if (layout >= NUM_TLS) return { CMD_ERROR, 0, TownID::Invalid() };
2170
2171 /* Some things are allowed only in the scenario editor and for game scripts. */
2172 if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY) {
2173 if (_settings_game.economy.found_town == TF_FORBIDDEN) return { CMD_ERROR, 0, TownID::Invalid() };
2174 if (size == TSZ_LARGE) return { CMD_ERROR, 0, TownID::Invalid() };
2175 if (random_location) return { CMD_ERROR, 0, TownID::Invalid() };
2177 return { CMD_ERROR, 0, TownID::Invalid() };
2178 }
2179 } else if (_current_company == OWNER_DEITY && random_location) {
2180 /* Random parameter is not allowed for Game Scripts. */
2181 return { CMD_ERROR, 0, TownID::Invalid() };
2182 }
2183
2184 if (text.empty()) {
2185 /* If supplied name is empty, townnameparts has to generate unique automatic name */
2186 if (!VerifyTownName(townnameparts, &par)) return { CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE), 0, TownID::Invalid() };
2187 } else {
2188 /* If name is not empty, it has to be unique custom name */
2189 if (Utf8StringLength(text) >= MAX_LENGTH_TOWN_NAME_CHARS) return { CMD_ERROR, 0, TownID::Invalid() };
2190 if (!IsUniqueTownName(text)) return { CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE), 0, TownID::Invalid() };
2191 }
2192
2193 /* Allocate town struct */
2194 if (!Town::CanAllocateItem()) return { CommandCost(STR_ERROR_TOO_MANY_TOWNS), 0, TownID::Invalid() };
2195
2196 if (!random_location) {
2197 CommandCost ret = TownCanBePlacedHere(tile);
2198 if (ret.Failed()) return { ret, 0, TownID::Invalid() };
2199 }
2200
2201 static const uint8_t price_mult[][TSZ_RANDOM + 1] = {{ 15, 25, 40, 25 }, { 20, 35, 55, 35 }};
2202 /* multidimensional arrays have to have defined length of non-first dimension */
2203 static_assert(lengthof(price_mult[0]) == 4);
2204
2205 CommandCost cost(EXPENSES_OTHER, _price[PR_BUILD_TOWN]);
2206 uint8_t mult = price_mult[city][size];
2207
2208 cost.MultiplyCost(mult);
2209
2210 /* Create the town */
2211 TownID new_town = TownID::Invalid();
2212 if (flags.Test(DoCommandFlag::Execute)) {
2213 if (cost.GetCost() > GetAvailableMoneyForCommand()) {
2214 return { CommandCost(EXPENSES_OTHER), cost.GetCost(), TownID::Invalid() };
2215 }
2216
2217 Backup<bool> old_generating_world(_generating_world, true);
2219 Town *t;
2220 if (random_location) {
2221 t = CreateRandomTown(20, townnameparts, size, city, layout);
2222 } else {
2223 t = new Town(tile);
2224 DoCreateTown(t, tile, townnameparts, size, city, layout, true);
2225 }
2226
2228 old_generating_world.Restore();
2229
2230 if (t == nullptr) return { CommandCost(STR_ERROR_NO_SPACE_FOR_TOWN), 0, TownID::Invalid() };
2231
2232 new_town = t->index;
2233
2234 if (!text.empty()) {
2235 t->name = text;
2236 t->UpdateVirtCoord();
2237 }
2238
2239 if (_game_mode != GM_EDITOR) {
2240 /* 't' can't be nullptr since 'random' is false outside scenedit */
2241 assert(!random_location);
2242
2244 AddTileNewsItem(GetEncodedString(STR_NEWS_NEW_TOWN_UNSPONSORED, t->index), NewsType::IndustryOpen, tile);
2245 } else {
2246 std::string company_name = GetString(STR_COMPANY_NAME, _current_company);
2247 AddTileNewsItem(GetEncodedString(STR_NEWS_NEW_TOWN, company_name, t->index), NewsType::IndustryOpen, tile);
2248 }
2249 AI::BroadcastNewEvent(new ScriptEventTownFounded(t->index));
2250 Game::NewEvent(new ScriptEventTownFounded(t->index));
2251 }
2252 }
2253 return { cost, 0, new_town };
2254}
2255
2266{
2267 switch (layout) {
2268 case TL_2X2_GRID: return TileXY(TileX(tile) - TileX(tile) % 3, TileY(tile) - TileY(tile) % 3);
2269 case TL_3X3_GRID: return TileXY(TileX(tile) & ~3, TileY(tile) & ~3);
2270 default: return tile;
2271 }
2272}
2273
2284{
2285 switch (layout) {
2286 case TL_2X2_GRID: return TileX(tile) % 3 == 0 && TileY(tile) % 3 == 0;
2287 case TL_3X3_GRID: return TileX(tile) % 4 == 0 && TileY(tile) % 4 == 0;
2288 default: return true;
2289 }
2290}
2291
2305{
2306 for (auto coast : SpiralTileSequence(tile, 40)) {
2307 /* Find nearest land tile */
2308 if (!IsTileType(tile, MP_CLEAR)) continue;
2309
2310 TileIndex furthest = INVALID_TILE;
2311 uint max_dist = 0;
2312 for (auto test : SpiralTileSequence(coast, 10)) {
2313 if (!IsTileType(test, MP_CLEAR) || !IsTileFlat(test) || !IsTileAlignedToGrid(test, layout)) continue;
2314
2315 uint dist = GetClosestWaterDistance(test, true);
2316 if (dist > max_dist) {
2317 furthest = test;
2318 max_dist = dist;
2319 }
2320 }
2321 return furthest;
2322 }
2323
2324 /* if we get here just give up */
2325 return INVALID_TILE;
2326}
2327
2333{
2335 case LandscapeType::Temperate: return HouseZone::ClimateTemperate;
2337 case LandscapeType::Tropic: return HouseZone::ClimateSubtropic;
2338 case LandscapeType::Toyland: return HouseZone::ClimateToyland;
2339 default: NOT_REACHED();
2340 }
2341}
2342
2352static Town *CreateRandomTown(uint attempts, uint32_t townnameparts, TownSize size, bool city, TownLayout layout)
2353{
2354 assert(_game_mode == GM_EDITOR || _generating_world); // These are the preconditions for CMD_DELETE_TOWN
2355
2356 if (!Town::CanAllocateItem()) return nullptr;
2357
2358 do {
2359 /* Generate a tile index not too close from the edge */
2360 TileIndex tile = AlignTileToGrid(RandomTile(), layout);
2361
2362 /* if we tried to place the town on water, slide it over onto
2363 * the nearest likely-looking spot */
2364 if (IsTileType(tile, MP_WATER)) {
2365 tile = FindNearestGoodCoastalTownSpot(tile, layout);
2366 if (tile == INVALID_TILE) continue;
2367 }
2368
2369 /* Make sure town can be placed here */
2370 if (TownCanBePlacedHere(tile).Failed()) continue;
2371
2372 /* Allocate a town struct */
2373 Town *t = new Town(tile);
2374
2375 DoCreateTown(t, tile, townnameparts, size, city, layout, false);
2376
2377 /* if the population is still 0 at the point, then the
2378 * placement is so bad it couldn't grow at all */
2379 if (t->cache.population > 0) return t;
2380
2383 cur_company.Restore();
2384 assert(rc.Succeeded());
2385
2386 /* We already know that we can allocate a single town when
2387 * entering this function. However, we create and delete
2388 * a town which "resets" the allocation checks. As such we
2389 * need to check again when assertions are enabled. */
2390 assert(Town::CanAllocateItem());
2391 } while (--attempts != 0);
2392
2393 return nullptr;
2394}
2395
2402{
2403 static const uint8_t num_initial_towns[4] = {5, 11, 23, 46}; // very low, low, normal, high
2406 }
2407 return Map::ScaleBySize(num_initial_towns[_settings_game.difficulty.number_towns]);
2408}
2409
2417bool GenerateTowns(TownLayout layout, std::optional<uint> number)
2418{
2419 uint current_number = 0;
2420 uint total;
2421 if (number.has_value()) {
2422 total = number.value();
2423 } else if (_settings_game.difficulty.number_towns == static_cast<uint>(CUSTOM_TOWN_NUMBER_DIFFICULTY)) {
2424 total = GetDefaultTownsForMapSize();
2425 } else {
2427 }
2428
2429 total = std::min<uint>(TownPool::MAX_SIZE, total);
2430 uint32_t townnameparts;
2431 TownNames town_names;
2432
2434
2435 /* Pre-populate the town names list with the names of any towns already on the map */
2436 for (const Town *town : Town::Iterate()) {
2437 town_names.insert(town->GetCachedName());
2438 }
2439
2440 /* Randomised offset for city status. This means with e.g. 1-in-4 towns being cities, a map with 10 towns
2441 * may have 2 or 3 cities, instead of always 3. */
2442 uint city_random_offset = _settings_game.economy.larger_towns == 0 ? 0 : (Random() % _settings_game.economy.larger_towns);
2443
2444 /* First attempt will be made at creating the suggested number of towns.
2445 * Note that this is really a suggested value, not a required one.
2446 * We would not like the system to lock up just because the user wanted 100 cities on a 64*64 map, would we? */
2447 do {
2448 bool city = (_settings_game.economy.larger_towns != 0 && ((city_random_offset + current_number) % _settings_game.economy.larger_towns) == 0);
2450 /* Get a unique name for the town. */
2451 if (!GenerateTownName(_random, &townnameparts, &town_names)) continue;
2452 /* try 20 times to create a random-sized town for the first loop. */
2453 if (CreateRandomTown(20, townnameparts, TSZ_RANDOM, city, layout) != nullptr) current_number++; // If creation was successful, raise a flag.
2454 } while (--total);
2455
2456 town_names.clear();
2457
2458 /* Build the town k-d tree again to make sure it's well balanced */
2459 RebuildTownKdtree();
2460
2461 if (current_number != 0) return true;
2462
2463 /* If current_number is still zero at this point, it means that not a single town has been created.
2464 * So give it a last try, but now more aggressive */
2465 if (GenerateTownName(_random, &townnameparts) &&
2466 CreateRandomTown(10000, townnameparts, TSZ_RANDOM, _settings_game.economy.larger_towns != 0, layout) != nullptr) {
2467 return true;
2468 }
2469
2470 /* If there are no towns at all and we are generating new game, bail out */
2471 if (Town::GetNumItems() == 0 && _game_mode != GM_EDITOR) {
2472 ShowErrorMessage(GetEncodedString(STR_ERROR_COULD_NOT_CREATE_TOWN), {}, WL_CRITICAL);
2473 }
2474
2475 return false; // we are still without a town? we failed, simply
2476}
2477
2478
2486{
2487 uint dist = DistanceSquare(tile, t->xy);
2488
2489 if (t->fund_buildings_months != 0 && dist <= 25) return HouseZone::TownCentre;
2490
2491 HouseZone smallest = HouseZone::TownEdge;
2492 for (HouseZone i : HZ_ZONE_ALL) {
2493 if (dist < t->cache.squared_town_zone_radius[to_underlying(i)]) smallest = i;
2494 }
2495
2496 return smallest;
2497}
2498
2510static inline void ClearMakeHouseTile(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool is_protected)
2511{
2513 assert(cc.Succeeded());
2514
2515 IncreaseBuildingCount(t, type);
2516 MakeHouseTile(tile, t->index, counter, stage, type, random_bits, is_protected);
2517 if (HouseSpec::Get(type)->building_flags.Test(BuildingFlag::IsAnimated)) AddAnimatedTile(tile, false);
2518
2519 MarkTileDirtyByTile(tile);
2520}
2521
2522
2534static void MakeTownHouse(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool is_protected)
2535{
2537
2538 ClearMakeHouseTile(tile, t, counter, stage, type, random_bits, is_protected);
2539 if (size.Any(BUILDING_2_TILES_Y)) ClearMakeHouseTile(tile + TileDiffXY(0, 1), t, counter, stage, ++type, random_bits, is_protected);
2540 if (size.Any(BUILDING_2_TILES_X)) ClearMakeHouseTile(tile + TileDiffXY(1, 0), t, counter, stage, ++type, random_bits, is_protected);
2541 if (size.Any(BUILDING_HAS_4_TILES)) ClearMakeHouseTile(tile + TileDiffXY(1, 1), t, counter, stage, ++type, random_bits, is_protected);
2542
2543 ForAllStationsAroundTiles(TileArea(tile, size.Any(BUILDING_2_TILES_X) ? 2 : 1, size.Any(BUILDING_2_TILES_Y) ? 2 : 1), [t](Station *st, TileIndex) {
2544 t->stations_near.insert(st);
2545 return true;
2546 });
2547}
2548
2549
2556static inline bool CanBuildHouseHere(TileIndex tile, bool noslope)
2557{
2558 /* cannot build on these slopes... */
2559 Slope slope = GetTileSlope(tile);
2560 if ((noslope && slope != SLOPE_FLAT) || IsSteepSlope(slope)) return false;
2561
2562 /* at least one RoadTypes allow building the house here? */
2563 if (!RoadTypesAllowHouseHere(tile)) return false;
2564
2565 /* building under a bridge? */
2566 if (IsBridgeAbove(tile)) return false;
2567
2568 /* can we clear the land? */
2570}
2571
2572
2581static inline bool CheckBuildHouseSameZ(TileIndex tile, int z, bool noslope)
2582{
2583 if (!CanBuildHouseHere(tile, noslope)) return false;
2584
2585 /* if building on slopes is allowed, there will be flattening foundation (to tile max z) */
2586 if (GetTileMaxZ(tile) != z) return false;
2587
2588 return true;
2589}
2590
2591
2600static bool CheckFree2x2Area(TileIndex tile, int z, bool noslope)
2601{
2602 /* we need to check this tile too because we can be at different tile now */
2603 if (!CheckBuildHouseSameZ(tile, z, noslope)) return false;
2604
2605 for (DiagDirection d = DIAGDIR_SE; d < DIAGDIR_END; d++) {
2606 tile += TileOffsByDiagDir(d);
2607 if (!CheckBuildHouseSameZ(tile, z, noslope)) return false;
2608 }
2609
2610 return true;
2611}
2612
2613
2621static inline bool TownLayoutAllowsHouseHere(Town *t, TileIndex tile, TownExpandModes modes)
2622{
2623 if (!modes.Test(TownExpandMode::Buildings)) return false;
2624
2625 /* Allow towns everywhere when we don't build roads */
2626 if (!TownAllowedToBuildRoads(modes)) return true;
2627
2628 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
2629
2630 switch (t->layout) {
2631 case TL_2X2_GRID:
2632 if ((grid_pos.x % 3) == 0 || (grid_pos.y % 3) == 0) return false;
2633 break;
2634
2635 case TL_3X3_GRID:
2636 if ((grid_pos.x % 4) == 0 || (grid_pos.y % 4) == 0) return false;
2637 break;
2638
2639 default:
2640 break;
2641 }
2642
2643 return true;
2644}
2645
2646
2655{
2656 if (!modes.Test(TownExpandMode::Buildings)) return false;
2657
2658 /* Allow towns everywhere when we don't build roads */
2659 if (!TownAllowedToBuildRoads(modes)) return true;
2660
2661 /* Compute relative position of tile. (Positive offsets are towards north) */
2662 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
2663
2664 switch (t->layout) {
2665 case TL_2X2_GRID:
2666 grid_pos.x %= 3;
2667 grid_pos.y %= 3;
2668 if ((grid_pos.x != 2 && grid_pos.x != -1) ||
2669 (grid_pos.y != 2 && grid_pos.y != -1)) return false;
2670 break;
2671
2672 case TL_3X3_GRID:
2673 if ((grid_pos.x & 3) < 2 || (grid_pos.y & 3) < 2) return false;
2674 break;
2675
2676 default:
2677 break;
2678 }
2679
2680 return true;
2681}
2682
2683
2693static bool CheckTownBuild2House(TileIndex *tile, Town *t, int maxz, bool noslope, DiagDirection second, TownExpandModes modes)
2694{
2695 /* 'tile' is already checked in BuildTownHouse() - CanBuildHouseHere() and slope test */
2696
2697 TileIndex tile2 = *tile + TileOffsByDiagDir(second);
2698 if (TownLayoutAllowsHouseHere(t, tile2, modes) && CheckBuildHouseSameZ(tile2, maxz, noslope)) return true;
2699
2700 tile2 = *tile + TileOffsByDiagDir(ReverseDiagDir(second));
2701 if (TownLayoutAllowsHouseHere(t, tile2, modes) && CheckBuildHouseSameZ(tile2, maxz, noslope)) {
2702 *tile = tile2;
2703 return true;
2704 }
2705
2706 return false;
2707}
2708
2709
2718static bool CheckTownBuild2x2House(TileIndex *tile, Town *t, int maxz, bool noslope, TownExpandModes modes)
2719{
2720 TileIndex tile2 = *tile;
2721
2722 for (DiagDirection d = DIAGDIR_SE;; d++) { // 'd' goes through DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_END
2723 if (TownLayoutAllows2x2HouseHere(t, tile2, modes) && CheckFree2x2Area(tile2, maxz, noslope)) {
2724 *tile = tile2;
2725 return true;
2726 }
2727 if (d == DIAGDIR_END) break;
2728 tile2 += TileOffsByDiagDir(ReverseDiagDir(d)); // go clockwise
2729 }
2730
2731 return false;
2732}
2733
2744static void BuildTownHouse(Town *t, TileIndex tile, const HouseSpec *hs, HouseID house, uint8_t random_bits, bool house_completed, bool is_protected)
2745{
2746 /* build the house */
2747 t->cache.num_houses++;
2748
2749 uint8_t construction_counter = 0;
2750 uint8_t construction_stage = 0;
2751
2752 if (_generating_world || _game_mode == GM_EDITOR || house_completed) {
2753 uint32_t construction_random = Random();
2754
2755 construction_stage = TOWN_HOUSE_COMPLETED;
2756 if (_generating_world && !hs->extra_flags.Test(HouseExtraFlag::BuildingIsHistorical) && Chance16(1, 7)) construction_stage = GB(construction_random, 0, 2);
2757
2758 if (construction_stage == TOWN_HOUSE_COMPLETED) {
2760 } else {
2761 construction_counter = GB(construction_random, 2, 2);
2762 }
2763 }
2764
2765 MakeTownHouse(tile, t, construction_counter, construction_stage, house, random_bits, is_protected);
2768
2769 BuildingFlags size = hs->building_flags;
2770
2771 TriggerHouseAnimation_ConstructionStageChanged(tile, true);
2772 if (size.Any(BUILDING_2_TILES_Y)) TriggerHouseAnimation_ConstructionStageChanged(tile + TileDiffXY(0, 1), true);
2773 if (size.Any(BUILDING_2_TILES_X)) TriggerHouseAnimation_ConstructionStageChanged(tile + TileDiffXY(1, 0), true);
2774 if (size.Any(BUILDING_HAS_4_TILES)) TriggerHouseAnimation_ConstructionStageChanged(tile + TileDiffXY(1, 1), true);
2775}
2776
2784{
2785 /* forbidden building here by town layout */
2786 if (!TownLayoutAllowsHouseHere(t, tile, modes)) return false;
2787
2788 /* no house allowed at all, bail out */
2789 if (!CanBuildHouseHere(tile, false)) return false;
2790
2791 Slope slope = GetTileSlope(tile);
2792 int maxz = GetTileMaxZ(tile);
2793
2794 /* Get the town zone type of the current tile, as well as the climate.
2795 * This will allow to easily compare with the specs of the new house to build */
2796 HouseZones zones = GetTownRadiusGroup(t, tile);
2797
2799 case LandscapeType::Temperate: zones.Set(HouseZone::ClimateTemperate); break;
2800 case LandscapeType::Arctic: zones.Set(maxz > HighestSnowLine() ? HouseZone::ClimateSubarcticAboveSnow : HouseZone::ClimateSubarcticBelowSnow); break;
2801 case LandscapeType::Tropic: zones.Set(HouseZone::ClimateSubtropic); break;
2802 case LandscapeType::Toyland: zones.Set(HouseZone::ClimateToyland); break;
2803 }
2804
2805 /* bits 0-4 are used
2806 * bits 11-15 are used
2807 * bits 5-10 are not used. */
2808 static std::vector<std::pair<HouseID, uint>> probs;
2809 probs.clear();
2810
2811 uint probability_max = 0;
2812
2813 /* Generate a list of all possible houses that can be built. */
2814 for (const auto &hs : HouseSpec::Specs()) {
2815 /* Verify that the candidate house spec matches the current tile status */
2816 if (!hs.building_availability.All(zones) || !hs.enabled || hs.grf_prop.override_id != INVALID_HOUSE_ID) continue;
2817
2818 /* Don't let these counters overflow. Global counters are 32bit, there will never be that many houses. */
2819 if (hs.class_id != HOUSE_NO_CLASS) {
2820 /* id_count is always <= class_count, so it doesn't need to be checked */
2821 if (t->cache.building_counts.class_count[hs.class_id] == UINT16_MAX) continue;
2822 } else {
2823 /* If the house has no class, check id_count instead */
2824 if (t->cache.building_counts.id_count[hs.Index()] == UINT16_MAX) continue;
2825 }
2826
2827 uint cur_prob = hs.probability;
2828 probability_max += cur_prob;
2829 probs.emplace_back(hs.Index(), cur_prob);
2830 }
2831
2832 TileIndex base_tile = tile;
2833
2834 while (probability_max > 0) {
2835 /* Building a multitile building can change the location of tile.
2836 * The building would still be built partially on that tile, but
2837 * its northern tile would be elsewhere. However, if the callback
2838 * fails we would be basing further work from the changed tile.
2839 * So a next 1x1 tile building could be built on the wrong tile. */
2840 tile = base_tile;
2841
2842 uint r = RandomRange(probability_max);
2843 uint i;
2844 for (i = 0; i < probs.size(); i++) {
2845 if (probs[i].second > r) break;
2846 r -= probs[i].second;
2847 }
2848
2849 HouseID house = probs[i].first;
2850 probability_max -= probs[i].second;
2851
2852 /* remove tested house from the set */
2853 probs[i] = probs.back();
2854 probs.pop_back();
2855
2856 const HouseSpec *hs = HouseSpec::Get(house);
2857
2858 if (!_generating_world && _game_mode != GM_EDITOR && hs->extra_flags.Test(HouseExtraFlag::BuildingIsHistorical)) {
2859 continue;
2860 }
2861
2862 if (TimerGameCalendar::year < hs->min_year || TimerGameCalendar::year > hs->max_year) continue;
2863
2864 /* Special houses that there can be only one of. */
2865 TownFlags oneof{};
2866
2867 if (hs->building_flags.Test(BuildingFlag::IsChurch)) {
2868 oneof.Set(TownFlag::HasChurch);
2869 } else if (hs->building_flags.Test(BuildingFlag::IsStadium)) {
2870 oneof.Set(TownFlag::HasStadium);
2871 }
2872
2873 if (t->flags.Any(oneof)) continue;
2874
2875 /* Make sure there is no slope? */
2876 bool noslope = hs->building_flags.Test(BuildingFlag::NotSloped);
2877 if (noslope && slope != SLOPE_FLAT) continue;
2878
2879 if (hs->building_flags.Test(BuildingFlag::Size2x2)) {
2880 if (!CheckTownBuild2x2House(&tile, t, maxz, noslope, modes)) continue;
2881 } else if (hs->building_flags.Test(BuildingFlag::Size2x1)) {
2882 if (!CheckTownBuild2House(&tile, t, maxz, noslope, DIAGDIR_SW, modes)) continue;
2883 } else if (hs->building_flags.Test(BuildingFlag::Size1x2)) {
2884 if (!CheckTownBuild2House(&tile, t, maxz, noslope, DIAGDIR_SE, modes)) continue;
2885 } else {
2886 /* 1x1 house checks are already done */
2887 }
2888
2889 uint8_t random_bits = Random();
2890
2892 uint16_t callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile, {}, true, random_bits);
2893 if (callback_res != CALLBACK_FAILED && !Convert8bitBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_ALLOW_CONSTRUCTION, callback_res)) continue;
2894 }
2895
2896 /* Special houses that there can be only one of. */
2897 t->flags.Set(oneof);
2898
2899 BuildTownHouse(t, tile, hs, house, random_bits, false, hs->extra_flags.Test(HouseExtraFlag::BuildingIsProtected));
2900
2901 return true;
2902 }
2903
2904 return false;
2905}
2906
2915CommandCost CmdPlaceHouse(DoCommandFlags flags, TileIndex tile, HouseID house, bool is_protected)
2916{
2917 if (_game_mode != GM_EDITOR && _settings_game.economy.place_houses == PH_FORBIDDEN) return CMD_ERROR;
2918
2919 if (Town::GetNumItems() == 0) return CommandCost(STR_ERROR_MUST_FOUND_TOWN_FIRST);
2920
2921 if (static_cast<size_t>(house) >= HouseSpec::Specs().size()) return CMD_ERROR;
2922 const HouseSpec *hs = HouseSpec::Get(house);
2923 if (!hs->enabled) return CMD_ERROR;
2924
2925 Town *t = ClosestTownFromTile(tile, UINT_MAX);
2926
2927 /* cannot build on these slopes... */
2928 Slope slope = GetTileSlope(tile);
2929 if (IsSteepSlope(slope)) return CommandCost(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
2930
2931 /* building under a bridge? */
2932 if (IsBridgeAbove(tile)) return CommandCost(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
2933
2934 /* can we clear the land? */
2936 if (!cost.Succeeded()) return cost;
2937
2938 int maxz = GetTileMaxZ(tile);
2939
2940 /* Make sure there is no slope? */
2941 bool noslope = hs->building_flags.Test(BuildingFlag::NotSloped);
2942 if (noslope && slope != SLOPE_FLAT) return CommandCost(STR_ERROR_FLAT_LAND_REQUIRED);
2943
2944 TileArea ta = tile;
2945 if (hs->building_flags.Test(BuildingFlag::Size2x2)) ta.Add(TileAddXY(tile, 1, 1));
2946 if (hs->building_flags.Test(BuildingFlag::Size2x1)) ta.Add(TileAddByDiagDir(tile, DIAGDIR_SW));
2947 if (hs->building_flags.Test(BuildingFlag::Size1x2)) ta.Add(TileAddByDiagDir(tile, DIAGDIR_SE));
2948
2949 /* Check additional tiles covered by this house. */
2950 for (const TileIndex &subtile : ta) {
2952 if (!cost.Succeeded()) return cost;
2953
2954 if (!CheckBuildHouseSameZ(subtile, maxz, noslope)) return CommandCost(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
2955 }
2956
2957 if (flags.Test(DoCommandFlag::Execute)) {
2958 bool house_completed = _settings_game.economy.place_houses == PH_ALLOWED_CONSTRUCTED;
2959 BuildTownHouse(t, tile, hs, house, Random(), house_completed, is_protected);
2960 }
2961
2962 return CommandCost();
2963}
2964
2971static void DoClearTownHouseHelper(TileIndex tile, Town *t, HouseID house)
2972{
2973 assert(IsTileType(tile, MP_HOUSE));
2974 DecreaseBuildingCount(t, house);
2975 DoClearSquare(tile);
2976
2977 DeleteNewGRFInspectWindow(GSF_HOUSES, tile.base());
2978}
2979
2988{
2989 if (house >= 3) { // house id 0,1,2 MUST be single tile houses, or this code breaks.
2990 if (HouseSpec::Get(house - 1)->building_flags.Test(BuildingFlag::Size2x1)) {
2991 house--;
2992 return TileDiffXY(-1, 0);
2993 } else if (HouseSpec::Get(house - 1)->building_flags.Any(BUILDING_2_TILES_Y)) {
2994 house--;
2995 return TileDiffXY(0, -1);
2996 } else if (HouseSpec::Get(house - 2)->building_flags.Any(BUILDING_HAS_4_TILES)) {
2997 house -= 2;
2998 return TileDiffXY(-1, 0);
2999 } else if (HouseSpec::Get(house - 3)->building_flags.Any(BUILDING_HAS_4_TILES)) {
3000 house -= 3;
3001 return TileDiffXY(-1, -1);
3002 }
3003 }
3004 return TileDiffXY(0, 0);
3005}
3006
3013{
3014 assert(IsTileType(tile, MP_HOUSE));
3015
3016 HouseID house = GetHouseType(tile);
3017
3018 /* The northernmost tile of the house is the main house. */
3019 tile += GetHouseNorthPart(house);
3020
3021 const HouseSpec *hs = HouseSpec::Get(house);
3022
3023 /* Remove population from the town if the house is finished. */
3024 if (IsHouseCompleted(tile)) {
3026 }
3027
3028 t->cache.num_houses--;
3029
3030 /* Clear flags for houses that only may exist once/town. */
3031 if (hs->building_flags.Test(BuildingFlag::IsChurch)) {
3033 } else if (hs->building_flags.Test(BuildingFlag::IsStadium)) {
3035 }
3036
3037 /* Do the actual clearing of tiles */
3038 DoClearTownHouseHelper(tile, t, house);
3039 if (hs->building_flags.Any(BUILDING_2_TILES_Y)) DoClearTownHouseHelper(tile + TileDiffXY(0, 1), t, ++house);
3040 if (hs->building_flags.Any(BUILDING_2_TILES_X)) DoClearTownHouseHelper(tile + TileDiffXY(1, 0), t, ++house);
3041 if (hs->building_flags.Any(BUILDING_HAS_4_TILES)) DoClearTownHouseHelper(tile + TileDiffXY(1, 1), t, ++house);
3042
3044
3046}
3047
3055CommandCost CmdRenameTown(DoCommandFlags flags, TownID town_id, const std::string &text)
3056{
3057 Town *t = Town::GetIfValid(town_id);
3058 if (t == nullptr) return CMD_ERROR;
3059
3060 bool reset = text.empty();
3061
3062 if (!reset) {
3064 if (!IsUniqueTownName(text)) return CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE);
3065 }
3066
3067 if (flags.Test(DoCommandFlag::Execute)) {
3068 t->cached_name.clear();
3069 if (reset) {
3070 t->name.clear();
3071 } else {
3072 t->name = text;
3073 }
3074
3075 t->UpdateVirtCoord();
3076 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_RESORT);
3077 ClearAllStationCachedNames();
3078 ClearAllIndustryCachedNames();
3080 }
3081 return CommandCost();
3082}
3083
3090{
3091 for (const CargoSpec *cs : CargoSpec::Iterate()) {
3092 if (cs->town_acceptance_effect == effect) return cs;
3093 }
3094 return nullptr;
3095}
3096
3106{
3107 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3108
3109 if (tae < TAE_BEGIN || tae >= TAE_END) return CMD_ERROR;
3110
3111 Town *t = Town::GetIfValid(town_id);
3112 if (t == nullptr) return CMD_ERROR;
3113
3114 /* Validate if there is a cargo which is the requested TownEffect */
3116 if (cargo == nullptr) return CMD_ERROR;
3117
3118 if (flags.Test(DoCommandFlag::Execute)) {
3119 t->goal[tae] = goal;
3122 }
3123
3124 return CommandCost();
3125}
3126
3135{
3136 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3137 Town *t = Town::GetIfValid(town_id);
3138 if (t == nullptr) return CMD_ERROR;
3139
3140 if (flags.Test(DoCommandFlag::Execute)) {
3141 t->text.clear();
3142 if (!text.empty()) t->text = text;
3144 }
3145
3146 return CommandCost();
3147}
3148
3156CommandCost CmdTownGrowthRate(DoCommandFlags flags, TownID town_id, uint16_t growth_rate)
3157{
3158 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3159
3160 Town *t = Town::GetIfValid(town_id);
3161 if (t == nullptr) return CMD_ERROR;
3162
3163 if (flags.Test(DoCommandFlag::Execute)) {
3164 if (growth_rate == 0) {
3165 /* Just clear the flag, UpdateTownGrowth will determine a proper growth rate */
3167 } else {
3168 uint old_rate = t->growth_rate;
3169 if (t->grow_counter >= old_rate) {
3170 /* This also catches old_rate == 0 */
3171 t->grow_counter = growth_rate;
3172 } else {
3173 /* Scale grow_counter, so half finished houses stay half finished */
3174 t->grow_counter = t->grow_counter * growth_rate / old_rate;
3175 }
3176 t->growth_rate = growth_rate;
3178 }
3181 }
3182
3183 return CommandCost();
3184}
3185
3194CommandCost CmdTownRating(DoCommandFlags flags, TownID town_id, CompanyID company_id, int16_t rating)
3195{
3196 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3197
3198 Town *t = Town::GetIfValid(town_id);
3199 if (t == nullptr) return CMD_ERROR;
3200
3201 if (!Company::IsValidID(company_id)) return CMD_ERROR;
3202
3203 int16_t new_rating = Clamp(rating, RATING_MINIMUM, RATING_MAXIMUM);
3204 if (flags.Test(DoCommandFlag::Execute)) {
3205 t->ratings[company_id] = new_rating;
3207 }
3208
3209 return CommandCost();
3210}
3211
3219CommandCost CmdExpandTown(DoCommandFlags flags, TownID town_id, uint32_t grow_amount, TownExpandModes modes)
3220{
3221 if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY) return CMD_ERROR;
3222 if (modes.None()) return CMD_ERROR;
3223 Town *t = Town::GetIfValid(town_id);
3224 if (t == nullptr) return CMD_ERROR;
3225
3226 if (flags.Test(DoCommandFlag::Execute)) {
3227 /* The more houses, the faster we grow */
3228 if (grow_amount == 0) {
3229 uint amount = RandomRange(ClampTo<uint16_t>(t->cache.num_houses / 10)) + 3;
3230 t->cache.num_houses += amount;
3232
3233 uint n = amount * 10;
3234 do GrowTown(t, modes); while (--n);
3235
3236 t->cache.num_houses -= amount;
3237 } else {
3238 for (; grow_amount > 0; grow_amount--) {
3239 /* Try several times to grow, as we are really suppose to grow */
3240 for (uint i = 0; i < 25; i++) if (GrowTown(t, modes)) break;
3241 }
3242 }
3244
3246 }
3247
3248 return CommandCost();
3249}
3250
3258{
3259 if (_game_mode != GM_EDITOR && !_generating_world) return CMD_ERROR;
3260 Town *t = Town::GetIfValid(town_id);
3261 if (t == nullptr) return CMD_ERROR;
3262
3263 /* Stations refer to towns. */
3264 for (const Station *st : Station::Iterate()) {
3265 if (st->town == t) {
3266 /* Non-oil rig stations are always a problem. */
3267 if (!st->facilities.Test(StationFacility::Airport) || st->airport.type != AT_OILRIG) return CMD_ERROR;
3268 /* We can only automatically delete oil rigs *if* there's no vehicle on them. */
3269 CommandCost ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, st->airport.tile);
3270 if (ret.Failed()) return ret;
3271 }
3272 }
3273
3274 /* Waypoints refer to towns. */
3275 for (const Waypoint *wp : Waypoint::Iterate()) {
3276 if (wp->town == t) return CMD_ERROR;
3277 }
3278
3279 /* Depots refer to towns. */
3280 for (const Depot *d : Depot::Iterate()) {
3281 if (d->town == t) return CMD_ERROR;
3282 }
3283
3284 /* Check all tiles for town ownership. First check for bridge tiles, as
3285 * these do not directly have an owner so we need to check adjacent
3286 * tiles. This won't work correctly in the same loop if the adjacent
3287 * tile was already deleted earlier in the loop. */
3288 for (const auto current_tile : Map::Iterate()) {
3289 if (IsTileType(current_tile, MP_TUNNELBRIDGE) && TestTownOwnsBridge(current_tile, t)) {
3290 CommandCost ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, current_tile);
3291 if (ret.Failed()) return ret;
3292 }
3293 }
3294
3295 /* Check all remaining tiles for town ownership. */
3296 for (const auto current_tile : Map::Iterate()) {
3297 bool try_clear = false;
3298 switch (GetTileType(current_tile)) {
3299 case MP_ROAD:
3300 try_clear = HasTownOwnedRoad(current_tile) && GetTownIndex(current_tile) == t->index;
3301 break;
3302
3303 case MP_HOUSE:
3304 try_clear = GetTownIndex(current_tile) == t->index;
3305 break;
3306
3307 case MP_INDUSTRY:
3308 try_clear = Industry::GetByTile(current_tile)->town == t;
3309 break;
3310
3311 case MP_OBJECT:
3312 if (Town::GetNumItems() == 1) {
3313 /* No towns will be left, remove it! */
3314 try_clear = true;
3315 } else {
3316 Object *o = Object::GetByTile(current_tile);
3317 if (o->town == t) {
3318 if (o->type == OBJECT_STATUE) {
3319 /* Statue... always remove. */
3320 try_clear = true;
3321 } else {
3322 /* Tell to find a new town. */
3323 if (flags.Test(DoCommandFlag::Execute)) o->town = nullptr;
3324 }
3325 }
3326 }
3327 break;
3328
3329 default:
3330 break;
3331 }
3332 if (try_clear) {
3333 CommandCost ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, current_tile);
3334 if (ret.Failed()) return ret;
3335 }
3336 }
3337
3338 /* The town destructor will delete the other things related to the town. */
3339 if (flags.Test(DoCommandFlag::Execute)) {
3340 _town_kdtree.Remove(t->index);
3341 if (t->cache.sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeTown(t->index));
3342 delete t;
3343 }
3344
3345 return CommandCost();
3346}
3347
3354{
3359 static const uint8_t town_action_costs[] = {
3360 2, 4, 9, 35, 48, 53, 117, 175
3361 };
3362 static_assert(std::size(town_action_costs) == to_underlying(TownAction::End));
3363
3364 assert(to_underlying(action) < std::size(town_action_costs));
3365 return town_action_costs[to_underlying(action)];
3366}
3367
3375{
3376 if (flags.Test(DoCommandFlag::Execute)) {
3378 }
3379 return CommandCost();
3380}
3381
3389{
3390 if (flags.Test(DoCommandFlag::Execute)) {
3392 }
3393 return CommandCost();
3394}
3395
3403{
3404 if (flags.Test(DoCommandFlag::Execute)) {
3406 }
3407 return CommandCost();
3408}
3409
3417{
3418 /* Check if the company is allowed to fund new roads. */
3420
3421 if (flags.Test(DoCommandFlag::Execute)) {
3422 t->road_build_months = 6;
3423
3424 std::string company_name = GetString(STR_COMPANY_NAME, _current_company);
3425
3427 GetEncodedString(TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_ROAD_REBUILDING_MINUTES : STR_NEWS_ROAD_REBUILDING_MONTHS, t->index, company_name),
3429 AI::BroadcastNewEvent(new ScriptEventRoadReconstruction(_current_company, t->index));
3430 Game::NewEvent(new ScriptEventRoadReconstruction(_current_company, t->index));
3431 }
3432 return CommandCost();
3433}
3434
3440static bool CheckClearTile(TileIndex tile)
3441{
3444 cur_company.Restore();
3445 return r.Succeeded();
3446}
3447
3456{
3457 if (!Object::CanAllocateItem()) return CommandCost(STR_ERROR_TOO_MANY_OBJECTS);
3458
3459 static const int STATUE_NUMBER_INNER_TILES = 25; // Number of tiles int the center of the city, where we try to protect houses.
3460
3461 TileIndex best_position = INVALID_TILE;
3462 uint tile_count = 0;
3463 for (auto tile : SpiralTileSequence(t->xy, 9)) {
3464 tile_count++;
3465
3466 /* Statues can be build on slopes, just like houses. Only the steep slopes is a no go. */
3467 if (IsSteepSlope(GetTileSlope(tile))) continue;
3468 /* Don't build statues under bridges. */
3469 if (IsBridgeAbove(tile)) continue;
3470
3471 /* A clear-able open space is always preferred. */
3472 if ((IsTileType(tile, MP_CLEAR) || IsTileType(tile, MP_TREES)) && CheckClearTile(tile)) {
3473 best_position = tile;
3474 break;
3475 }
3476
3477 bool house = IsTileType(tile, MP_HOUSE);
3478
3479 /* Searching inside the inner circle. */
3480 if (tile_count <= STATUE_NUMBER_INNER_TILES) {
3481 /* Save first house in inner circle. */
3482 if (house && best_position == INVALID_TILE && CheckClearTile(tile)) {
3483 best_position = tile;
3484 }
3485
3486 /* If we have reached the end of the inner circle, and have a saved house, terminate the search. */
3487 if (tile_count == STATUE_NUMBER_INNER_TILES && best_position != INVALID_TILE) break;
3488 }
3489
3490 /* Searching outside the circle, just pick the first possible spot. */
3491 if (!house || !CheckClearTile(tile)) continue;
3492 best_position = tile;
3493 break;
3494 }
3495 if (best_position == INVALID_TILE) return CommandCost(STR_ERROR_STATUE_NO_SUITABLE_PLACE);
3496
3497 if (flags.Test(DoCommandFlag::Execute)) {
3500 cur_company.Restore();
3501 BuildObject(OBJECT_STATUE, best_position, _current_company, t);
3502 t->statues.Set(_current_company); // Once found and built, "inform" the Town.
3503 MarkTileDirtyByTile(best_position);
3504 }
3505 return CommandCost();
3506}
3507
3515{
3516 /* Check if it's allowed to buy the rights */
3518
3519 if (flags.Test(DoCommandFlag::Execute)) {
3520 /* And grow for 3 months */
3521 t->fund_buildings_months = 3;
3522
3523 /* Enable growth (also checking GameScript's opinion) */
3525
3526 /* Build a new house, but add a small delay to make sure
3527 * that spamming funding doesn't let town grow any faster
3528 * than 1 house per 2 * TOWN_GROWTH_TICKS ticks.
3529 * Also emulate original behaviour when town was only growing in
3530 * TOWN_GROWTH_TICKS intervals, to make sure that it's not too
3531 * tick-perfect and gives player some time window where they can
3532 * spam funding with the exact same efficiency.
3533 */
3535
3537 }
3538 return CommandCost();
3539}
3540
3548{
3549 /* Check if it's allowed to buy the rights */
3551 if (t->exclusivity != CompanyID::Invalid()) return CMD_ERROR;
3552
3553 if (flags.Test(DoCommandFlag::Execute)) {
3554 t->exclusive_counter = 12;
3556
3558
3560
3561 /* Spawn news message */
3562 auto cni = std::make_unique<CompanyNewsInformation>(STR_NEWS_EXCLUSIVE_RIGHTS_TITLE, Company::Get(_current_company));
3563 EncodedString message = GetEncodedString(TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MINUTES : STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MONTHS, t->index, cni->company_name);
3564 AddNewsItem(std::move(message),
3565 NewsType::General, NewsStyle::Company, {}, t->index, {}, std::move(cni));
3566 AI::BroadcastNewEvent(new ScriptEventExclusiveTransportRights(_current_company, t->index));
3567 Game::NewEvent(new ScriptEventExclusiveTransportRights(_current_company, t->index));
3568 }
3569 return CommandCost();
3570}
3571
3579{
3580 if (flags.Test(DoCommandFlag::Execute)) {
3581 if (Chance16(1, 14)) {
3582 /* set as unwanted for 6 months */
3583 t->unwanted[_current_company] = 6;
3584
3585 /* set all close by station ratings to 0 */
3586 for (Station *st : Station::Iterate()) {
3587 if (st->town == t && st->owner == _current_company) {
3588 for (GoodsEntry &ge : st->goods) ge.rating = 0;
3589 }
3590 }
3591
3592 /* only show error message to the executing player. All errors are handled command.c
3593 * but this is special, because it can only 'fail' on a DoCommandFlag::Execute */
3594 if (IsLocalCompany()) ShowErrorMessage(GetEncodedString(STR_ERROR_BRIBE_FAILED), {}, WL_INFO);
3595
3596 /* decrease by a lot!
3597 * ChangeTownRating is only for stuff in demolishing. Bribe failure should
3598 * be independent of any cheat settings
3599 */
3600 if (t->ratings[_current_company] > RATING_BRIBE_DOWN_TO) {
3601 t->ratings[_current_company] = RATING_BRIBE_DOWN_TO;
3603 }
3604 } else {
3605 ChangeTownRating(t, RATING_BRIBE_UP_STEP, RATING_BRIBE_MAXIMUM, DoCommandFlag::Execute);
3606 if (t->exclusivity != _current_company && t->exclusivity != CompanyID::Invalid()) {
3607 t->exclusivity = CompanyID::Invalid();
3608 t->exclusive_counter = 0;
3609 }
3610 }
3611 }
3612 return CommandCost();
3613}
3614
3615typedef CommandCost TownActionProc(Town *t, DoCommandFlags flags);
3616static TownActionProc * const _town_action_proc[] = {
3625};
3626static_assert(std::size(_town_action_proc) == to_underlying(TownAction::End));
3627
3635{
3636 TownActions buttons{};
3637
3638 /* Spectators and unwanted have no options */
3639 if (cid != COMPANY_SPECTATOR && !(_settings_game.economy.bribe && t->unwanted[cid])) {
3640
3641 /* Actions worth more than this are not able to be performed */
3642 Money avail = GetAvailableMoney(cid);
3643
3644 /* Check the action bits for validity and
3645 * if they are valid add them */
3646 for (TownAction cur = {}; cur != TownAction::End; ++cur) {
3647
3648 /* Is the company prohibited from bribing ? */
3649 if (cur == TownAction::Bribe) {
3650 /* Company can't bribe if setting is disabled */
3651 if (!_settings_game.economy.bribe) continue;
3652 /* Company can bribe if another company has exclusive transport rights,
3653 * or its standing with the town is less than outstanding. */
3654 if (t->ratings[cid] >= RATING_BRIBE_MAXIMUM) {
3655 if (t->exclusivity == _current_company) continue;
3656 if (t->exclusive_counter == 0) continue;
3657 }
3658 }
3659
3660 /* Is the company not able to buy exclusive rights ? */
3662
3663 /* Is the company not able to fund buildings ? */
3665
3666 /* Is the company not able to fund local road reconstruction? */
3668
3669 /* Is the company not able to build a statue ? */
3670 if (cur == TownAction::BuildStatue && t->statues.Test(cid)) continue;
3671
3672 if (avail >= GetTownActionCost(cur) * _price[PR_TOWN_ACTION] >> 8) {
3673 buttons.Set(cur);
3674 }
3675 }
3676 }
3677
3678 return buttons;
3679}
3680
3691{
3692 Town *t = Town::GetIfValid(town_id);
3693 if (t == nullptr || to_underlying(action) >= std::size(_town_action_proc)) return CMD_ERROR;
3694
3695 if (!GetMaskOfTownActions(_current_company, t).Test(action)) return CMD_ERROR;
3696
3697 CommandCost cost(EXPENSES_OTHER, _price[PR_TOWN_ACTION] * GetTownActionCost(action) >> 8);
3698
3699 CommandCost ret = _town_action_proc[to_underlying(action)](t, flags);
3700 if (ret.Failed()) return ret;
3701
3702 if (flags.Test(DoCommandFlag::Execute)) {
3704 }
3705
3706 return cost;
3707}
3708
3709template <typename Func>
3710static void ForAllStationsNearTown(Town *t, Func func)
3711{
3712 /* Ideally the search radius should be close to the actual town zone 0 radius.
3713 * The true radius is not stored or calculated anywhere, only the squared radius. */
3714 /* The efficiency of this search might be improved for large towns and many stations on the map,
3715 * by using an integer square root approximation giving a value not less than the true square root. */
3716 uint search_radius = t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownEdge)] / 2;
3717 ForAllStationsRadius(t->xy, search_radius, [&](const Station * st) {
3718 if (DistanceSquare(st->xy, t->xy) <= t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownEdge)]) {
3719 func(st);
3720 }
3721 });
3722}
3723
3728static void UpdateTownRating(Town *t)
3729{
3730 /* Increase company ratings if they're low */
3731 for (const Company *c : Company::Iterate()) {
3732 if (t->ratings[c->index] < RATING_GROWTH_MAXIMUM) {
3733 t->ratings[c->index] = std::min((int)RATING_GROWTH_MAXIMUM, t->ratings[c->index] + RATING_GROWTH_UP_STEP);
3734 }
3735 }
3736
3737 ForAllStationsNearTown(t, [&](const Station *st) {
3738 if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
3739 if (Company::IsValidID(st->owner)) {
3740 int new_rating = t->ratings[st->owner] + RATING_STATION_UP_STEP;
3741 t->ratings[st->owner] = std::min<int>(new_rating, INT16_MAX); // do not let it overflow
3742 }
3743 } else {
3744 if (Company::IsValidID(st->owner)) {
3745 int new_rating = t->ratings[st->owner] + RATING_STATION_DOWN_STEP;
3746 t->ratings[st->owner] = std::max(new_rating, INT16_MIN);
3747 }
3748 }
3749 });
3750
3751 /* clamp all ratings to valid values */
3752 for (uint i = 0; i < MAX_COMPANIES; i++) {
3753 t->ratings[i] = Clamp(t->ratings[i], RATING_MINIMUM, RATING_MAXIMUM);
3754 }
3755
3757}
3758
3759
3766static void UpdateTownGrowCounter(Town *t, uint16_t prev_growth_rate)
3767{
3768 if (t->growth_rate == TOWN_GROWTH_RATE_NONE) return;
3769 if (prev_growth_rate == TOWN_GROWTH_RATE_NONE) {
3770 t->grow_counter = std::min<uint16_t>(t->growth_rate, t->grow_counter);
3771 return;
3772 }
3773 t->grow_counter = RoundDivSU((uint32_t)t->grow_counter * (t->growth_rate + 1), prev_growth_rate + 1);
3774}
3775
3782{
3783 int n = 0;
3784 ForAllStationsNearTown(t, [&](const Station * st) {
3785 if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
3786 n++;
3787 }
3788 });
3789 return n;
3790}
3791
3799{
3805 static const uint16_t _grow_count_values[2][6] = {
3806 { 120, 120, 120, 100, 80, 60 }, // Fund new buildings has been activated
3807 { 320, 420, 300, 220, 160, 100 } // Normal values
3808 };
3809
3810 int n = CountActiveStations(t);
3811 uint16_t m = _grow_count_values[t->fund_buildings_months != 0 ? 0 : 1][std::min(n, 5)];
3812
3813 uint growth_multiplier = _settings_game.economy.town_growth_rate != 0 ? _settings_game.economy.town_growth_rate - 1 : 1;
3814
3815 m >>= growth_multiplier;
3816 if (t->larger_town) m /= 2;
3817
3818 return TownTicksToGameTicks(m / (t->cache.num_houses / 50 + 1));
3819}
3820
3826{
3827 if (t->flags.Test(TownFlag::CustomGrowth)) return;
3828 uint old_rate = t->growth_rate;
3830 UpdateTownGrowCounter(t, old_rate);
3832}
3833
3838static void UpdateTownGrowth(Town *t)
3839{
3841
3844
3846
3847 if (t->fund_buildings_months == 0) {
3848 /* Check if all goals are reached for this town to grow (given we are not funding it) */
3849 for (int i = TAE_BEGIN; i < TAE_END; i++) {
3850 switch (t->goal[i]) {
3851 case TOWN_GROWTH_WINTER:
3852 if (TileHeight(t->xy) >= GetSnowLine() && t->received[i].old_act == 0 && t->cache.population > 90) return;
3853 break;
3854 case TOWN_GROWTH_DESERT:
3855 if (GetTropicZone(t->xy) == TROPICZONE_DESERT && t->received[i].old_act == 0 && t->cache.population > 60) return;
3856 break;
3857 default:
3858 if (t->goal[i] > t->received[i].old_act) return;
3859 break;
3860 }
3861 }
3862 }
3863
3867 return;
3868 }
3869
3870 if (t->fund_buildings_months == 0 && CountActiveStations(t) == 0 && !Chance16(1, 12)) return;
3871
3874}
3875
3883{
3884 /* The required rating is hardcoded to RATING_VERYPOOR (see below), not the authority attitude setting, so we can bail out like this. */
3885 if (_settings_game.difficulty.town_council_tolerance == TOWN_COUNCIL_PERMISSIVE) return CommandCost();
3886
3888
3890 if (t == nullptr) return CommandCost();
3891
3892 if (t->ratings[_current_company] > RATING_VERYPOOR) return CommandCost();
3893
3894 return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index);
3895}
3896
3906{
3907 if (Town::GetNumItems() == 0) return nullptr;
3908
3909 TownID tid = _town_kdtree.FindNearest(TileX(tile), TileY(tile));
3910 Town *town = Town::Get(tid);
3911 if (DistanceManhattan(tile, town->xy) < threshold) return town;
3912 return nullptr;
3913}
3914
3923Town *ClosestTownFromTile(TileIndex tile, uint threshold)
3924{
3925 switch (GetTileType(tile)) {
3926 case MP_ROAD:
3927 if (IsRoadDepot(tile)) return CalcClosestTownFromTile(tile, threshold);
3928
3929 if (!HasTownOwnedRoad(tile)) {
3930 TownID tid = GetTownIndex(tile);
3931
3932 if (tid == TownID::Invalid()) {
3933 /* in the case we are generating "many random towns", this value may be TownID::Invalid() */
3934 if (_generating_world) return CalcClosestTownFromTile(tile, threshold);
3935 assert(Town::GetNumItems() == 0);
3936 return nullptr;
3937 }
3938
3939 assert(Town::IsValidID(tid));
3940 Town *town = Town::Get(tid);
3941
3942 if (DistanceManhattan(tile, town->xy) >= threshold) town = nullptr;
3943
3944 return town;
3945 }
3946 [[fallthrough]];
3947
3948 case MP_HOUSE:
3949 return Town::GetByTile(tile);
3950
3951 default:
3952 return CalcClosestTownFromTile(tile, threshold);
3953 }
3954}
3955
3956static bool _town_rating_test = false;
3957static std::map<const Town *, int> _town_test_ratings;
3958
3965{
3966 static int ref_count = 0; // Number of times test-mode is switched on.
3967 if (mode) {
3968 if (ref_count == 0) {
3969 _town_test_ratings.clear();
3970 }
3971 ref_count++;
3972 } else {
3973 assert(ref_count > 0);
3974 ref_count--;
3975 }
3976 _town_rating_test = !(ref_count == 0);
3977}
3978
3984static int GetRating(const Town *t)
3985{
3986 if (_town_rating_test) {
3987 auto it = _town_test_ratings.find(t);
3988 if (it != _town_test_ratings.end()) {
3989 return it->second;
3990 }
3991 }
3992 return t->ratings[_current_company];
3993}
3994
4002void ChangeTownRating(Town *t, int add, int max, DoCommandFlags flags)
4003{
4004 /* if magic_bulldozer cheat is active, town doesn't penalize for removing stuff */
4005 if (t == nullptr || flags.Test(DoCommandFlag::NoModifyTownRating) ||
4007 (_cheats.magic_bulldozer.value && add < 0)) {
4008 return;
4009 }
4010
4011 int rating = GetRating(t);
4012 if (add < 0) {
4013 if (rating > max) {
4014 rating += add;
4015 if (rating < max) rating = max;
4016 }
4017 } else {
4018 if (rating < max) {
4019 rating += add;
4020 if (rating > max) rating = max;
4021 }
4022 }
4023 if (_town_rating_test) {
4024 _town_test_ratings[t] = rating;
4025 } else {
4027 t->ratings[_current_company] = rating;
4029 }
4030}
4031
4040{
4041 /* if magic_bulldozer cheat is active, town doesn't restrict your destructive actions */
4042 if (t == nullptr || !Company::IsValidID(_current_company) ||
4044 return CommandCost();
4045 }
4046
4047 /* minimum rating needed to be allowed to remove stuff */
4048 static const int needed_rating[][to_underlying(TownRatingCheckType::End)] = {
4049 /* RoadRemove, TunnelBridgeRemove */
4054 };
4055
4056 /* check if you're allowed to remove the road/bridge/tunnel
4057 * owned by a town no removal if rating is lower than ... depends now on
4058 * difficulty setting. Minimum town rating selected by difficulty level
4059 */
4060 int needed = needed_rating[_settings_game.difficulty.town_council_tolerance][to_underlying(type)];
4061
4062 if (GetRating(t) < needed) {
4063 return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index);
4064 }
4065
4066 return CommandCost();
4067}
4068
4069template <>
4070Town::SuppliedHistory SumHistory(std::span<const Town::SuppliedHistory> history)
4071{
4072 uint32_t production = std::accumulate(std::begin(history), std::end(history), 0, [](uint32_t r, const auto &s) { return r + s.production; });
4073 uint32_t transported = std::accumulate(std::begin(history), std::end(history), 0, [](uint32_t r, const auto &s) { return r + s.transported; });
4074 auto count = std::size(history);
4075 return {.production = ClampTo<uint16_t>(production / count), .transported = ClampTo<uint16_t>(transported / count)};
4076}
4077
4078static const IntervalTimer<TimerGameEconomy> _economy_towns_monthly({TimerGameEconomy::MONTH, TimerGameEconomy::Priority::TOWN}, [](auto)
4079{
4080 for (Town *t : Town::Iterate()) {
4081 /* Check for active town actions and decrement their counters. */
4082 if (t->road_build_months != 0) t->road_build_months--;
4084
4085 if (t->exclusive_counter != 0) {
4086 if (--t->exclusive_counter == 0) t->exclusivity = CompanyID::Invalid();
4087 }
4088
4089 /* Check for active failed bribe cooloff periods and decrement them. */
4090 for (const Company *c : Company::Iterate()) {
4091 if (t->unwanted[c->index] > 0) t->unwanted[c->index]--;
4092 }
4093
4095
4096 /* Update cargo statistics. */
4097 for (auto &s : t->supplied) RotateHistory(s.history, t->valid_history, HISTORY_YEAR, TimerGameEconomy::month);
4098 for (auto &received : t->received) received.NewMonth();
4099
4102
4104 }
4105});
4106
4107static const IntervalTimer<TimerGameEconomy> _economy_towns_yearly({TimerGameEconomy::YEAR, TimerGameEconomy::Priority::TOWN}, [](auto)
4108{
4109 /* Increment house ages */
4110 for (const auto t : Map::Iterate()) {
4111 if (!IsTileType(t, MP_HOUSE)) continue;
4113 }
4114});
4115
4116static CommandCost TerraformTile_Town(TileIndex tile, DoCommandFlags flags, int z_new, Slope tileh_new)
4117{
4118 if (AutoslopeEnabled()) {
4119 HouseID house = GetHouseType(tile);
4120 GetHouseNorthPart(house); // modifies house to the ID of the north tile
4121 const HouseSpec *hs = HouseSpec::Get(house);
4122
4123 /* Here we differ from TTDP by checking BuildingFlag::NotSloped */
4124 if (!hs->building_flags.Test(BuildingFlag::NotSloped) && !IsSteepSlope(tileh_new) &&
4125 (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) {
4126 bool allow_terraform = true;
4127
4128 /* Call the autosloping callback per tile, not for the whole building at once. */
4129 house = GetHouseType(tile);
4130 hs = HouseSpec::Get(house);
4132 /* If the callback fails, allow autoslope. */
4133 uint16_t res = GetHouseCallback(CBID_HOUSE_AUTOSLOPE, 0, 0, house, Town::GetByTile(tile), tile);
4134 if (res != CALLBACK_FAILED && ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_AUTOSLOPE, res)) allow_terraform = false;
4135 }
4136
4137 if (allow_terraform) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
4138 }
4139 }
4140
4141 return Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
4142}
4143
4145extern const TileTypeProcs _tile_type_town_procs = {
4146 DrawTile_Town, // draw_tile_proc
4147 GetSlopePixelZ_Town, // get_slope_z_proc
4148 ClearTile_Town, // clear_tile_proc
4149 AddAcceptedCargo_Town, // add_accepted_cargo_proc
4150 GetTileDesc_Town, // get_tile_desc_proc
4151 GetTileTrackStatus_Town, // get_tile_track_status_proc
4152 nullptr, // click_tile_proc
4153 AnimateTile_Town, // animate_tile_proc
4154 TileLoop_Town, // tile_loop_proc
4155 ChangeTileOwner_Town, // change_tile_owner_proc
4156 AddProducedCargo_Town, // add_produced_cargo_proc
4157 nullptr, // vehicle_enter_tile_proc
4158 GetFoundation_Town, // get_foundation_proc
4159 TerraformTile_Town, // terraform_tile_proc
4160 nullptr, // check_build_above_proc
4161};
4162
4163std::span<const DrawBuildingsTileStruct> GetTownDrawTileData()
4164{
4165 return _town_draw_tile_data;
4166}
Base functions for all AIs.
@ AT_OILRIG
Oilrig airport.
Definition airport.h:38
void AddAnimatedTile(TileIndex tile, bool mark_dirty)
Add the given tile to the animated tile table (if it does not exist yet).
void DeleteAnimatedTile(TileIndex tile, bool immediate)
Stops animation on the given tile.
Tile animation!
Functions related to autoslope.
bool AutoslopeEnabled()
Tests if autoslope is enabled for _current_company.
Definition autoslope.h:65
Class for backupping variables and making sure they are restored later.
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
constexpr uint CountBits(T value)
Counts the number of set bits in a variable.
debug_inline static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
static const uint MAX_BRIDGES
Maximal number of available bridge specs.
Definition bridge.h:18
bool IsBridgeTile(Tile t)
checks if there is a bridge on this tile
Definition bridge_map.h:35
bool IsBridgeAbove(Tile t)
checks if a bridge is set above the ground of this tile
Definition bridge_map.h:45
Axis GetBridgeAxis(Tile t)
Get the axis of the bridge that goes over the tile.
Definition bridge_map.h:68
uint8_t CargoType
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:23
bool IsValidCargoType(CargoType cargo)
Test whether cargo type is not INVALID_CARGO.
Definition cargo_type.h:106
TownProductionEffect
Town effect when producing cargo.
Definition cargotype.h:35
@ TPE_PASSENGERS
Cargo behaves passenger-like for production.
Definition cargotype.h:37
@ TPE_MAIL
Cargo behaves mail-like for production.
Definition cargotype.h:38
TownAcceptanceEffect
Town growth effect when delivering cargo.
Definition cargotype.h:22
@ TAE_END
End of town effects.
Definition cargotype.h:30
@ TAE_FOOD
Cargo behaves food/fizzy-drinks-like.
Definition cargotype.h:29
@ TAE_WATER
Cargo behaves water-like.
Definition cargotype.h:28
Cheats _cheats
All the cheats.
Definition cheat.cpp:16
Types related to cheating.
static void BroadcastNewEvent(ScriptEvent *event, CompanyID skip_company=CompanyID::Invalid())
Broadcast a new event to all active AIs.
Definition ai_core.cpp:255
constexpr bool All(const Timpl &other) const
Test if all of the values are set.
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
constexpr bool None() const
Test if none of the values are set.
constexpr Timpl & 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.
Enum-as-bit-set wrapper.
static void NewEvent(class ScriptEvent *event)
Queue a new event for a Game Script.
An interval timer will fire every interval, and will continue to fire until it is deleted.
Definition timer.h:76
K-dimensional tree, specialised for 2-dimensional space.
Definition kdtree.hpp:33
void Build(It begin, It end)
Clear and rebuild the tree from a new sequence of elements,.
Definition kdtree.hpp:360
size_t Count() const
Get number of elements stored in tree.
Definition kdtree.hpp:428
void Insert(const T &element)
Insert a single element in the tree.
Definition kdtree.hpp:396
void Remove(const T &element)
Remove a single element from the tree, if it exists.
Definition kdtree.hpp:415
T FindNearest(CoordT x, CoordT y) const
Find the element closest to given coordinate, in Manhattan distance.
Definition kdtree.hpp:439
TimerGameCalendar::Date introduction_date
Introduction date.
Definition road.h:141
RoadTypeFlags flags
Bit mask of road type flags.
Definition road.h:102
uint16_t max_speed
Maximum speed for vehicles travelling on this road type.
Definition road.h:117
Generate TileIndices around a center tile or tile area, with increasing distance.
Structure contains cached list of stations nearby.
const StationList & GetStations()
Run a tile loop to find stations around a tile, on demand.
static constexpr TimerGameTick::Ticks TOWN_GROWTH_TICKS
Cycle duration for towns trying to grow (this originates from the size of the town array in TTD).
static Date date
Current date in days (day counter).
static Year year
Current year, starting at 0.
static constexpr TimerGame< struct Calendar >::Date MAX_DATE
The date of the last day of the max year.
Timer that is increased every 27ms, and counts towards economy time units, expressed in days / months...
static Month month
Current month (0..11).
static bool UsingWallclockUnits(bool newgame=false)
Check if we are using wallclock units.
static TickCounter counter
Monotonic counter, in ticks, since start of game.
CommandCost CommandCostWithParam(StringID str, uint64_t value)
Return an error status, with string and parameter.
Definition command.cpp:417
Functions related to commands.
static constexpr DoCommandFlags CommandFlagsToDCFlags(CommandFlags cmd_flags)
Extracts the DC flags needed for DoCommand from the flags returned by GetCommandFlags.
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
@ Execute
execute the given command
@ NoModifyTownRating
do not change town rating
@ NoTestTownRating
town rating does not disallow you from building
@ NoWater
don't allow building on water
@ Auto
don't allow building on structures
Definition of stuff that is very close to a company, like the company struct itself.
Money GetAvailableMoneyForCommand()
This functions returns the money which can be used to execute a command.
Money GetAvailableMoney(CompanyID company)
Get the amount of money that a company has available, or INT64_MAX if there is no such valid company.
CompanyID _current_company
Company currently doing an action.
Functions related to companies.
bool IsLocalCompany()
Is the current company the local company?
static constexpr Owner OWNER_DEITY
The object is owned by a superuser / goal script.
static constexpr CompanyID COMPANY_SPECTATOR
The client is spectating.
static constexpr Owner OWNER_TOWN
A town owns the tile, or a town is expanding.
static constexpr Owner OWNER_NONE
The tile has no ownership.
Base for all depots (except hangars)
DiagDirection ReverseDiagDir(DiagDirection d)
Returns the reverse direction of the given DiagDirection.
bool IsValidDiagDirection(DiagDirection d)
Checks if an integer value is a valid DiagDirection.
DiagDirection ChangeDiagDir(DiagDirection d, DiagDirDiff delta)
Applies a difference on a DiagDirection.
Axis DiagDirToAxis(DiagDirection d)
Convert a DiagDirection to the axis.
@ DIR_N
North.
@ DIR_S
South.
@ DIR_W
West.
@ DIR_E
East.
@ DIAGDIRDIFF_90RIGHT
90 degrees right
@ DIAGDIRDIFF_90LEFT
90 degrees left
DiagDirection
Enumeration for diagonal directions.
@ DIAGDIR_NW
Northwest.
@ DIAGDIR_SE
Southeast.
@ DIAGDIR_END
Used for iterations.
@ DIAGDIR_BEGIN
Used for iterations.
@ DIAGDIR_SW
Southwest.
bool EconomyIsInRecession()
Is the economy in recession?
uint ScaleByCargoScale(uint num, bool town)
Scale a number by the cargo scale setting.
@ EXPENSES_CONSTRUCTION
Construction costs.
@ EXPENSES_OTHER
Other expenses.
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23)
Definition enum_type.hpp:17
Functions related to errors.
@ WL_CRITICAL
Critical errors, the MessageBox is shown in all cases.
Definition error.h:27
@ WL_INFO
Used for DoCommand-like (and some non-fatal AI GUI) errors/information.
Definition error.h:24
void ShowErrorMessage(EncodedString &&summary_msg, int x, int y, CommandCost &cc)
Display an error message in a window.
Base functions for all Games.
bool _generating_world
Whether we are generating the map or not.
Definition genworld.cpp:74
Functions related to world/map generation.
void IncreaseGeneratingWorldProgress(GenWorldProgress cls)
Increases the current stage of the world generation with one.
@ GWP_TOWN
Generate towns.
Definition genworld.h:66
void SetGeneratingWorldProgress(GenWorldProgress cls, uint total)
Set the total of a stage of the world generation.
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition gfx_type.h:17
uint8_t GetSnowLine()
Get the current snow line, either variable or static.
uint8_t HighestSnowLine()
Get the highest possible snow line height, either variable or static.
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
Definition gfx.cpp:1547
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_height_override)
Mark a tile given by its index dirty for repaint.
void UpdateValidHistory(ValidHistoryMask &valid_history, const HistoryRange &hr, uint cur_month)
Update mask of valid records for a historical data.
Definition history.cpp:25
Functions for storing historical data.
void RotateHistory(HistoryData< T > &history, ValidHistoryMask valid_history, const HistoryRange &hr, uint cur_month)
Rotate historical data.
Types for storing historical data.
@ BuildingIsHistorical
this house will only appear during town generation in random games, thus the historical
@ BuildingIsProtected
towns and AI will not remove this house, while human players will be able to
static const HouseID NEW_HOUSE_OFFSET
Offset for new houses.
Definition house.h:28
static const uint8_t TOWN_HOUSE_COMPLETED
Simple value that indicates the house has reached the final stage of construction.
Definition house.h:25
HouseZone
Definition house.h:55
@ ClimateSubarcticAboveSnow
Building can appear in sub-arctic climate above the snow line.
@ ClimateSubarcticBelowSnow
Building can appear in sub-arctic climate below the snow line.
@ ClimateTemperate
Building can appear in temperate climate.
@ ClimateToyland
Building can appear in toyland climate.
@ ClimateSubtropic
Building can appear in subtropical climate.
uint16_t HouseID
OpenTTD ID of house types.
Definition house_type.h:13
Base of all industries.
void DrawFoundation(TileInfo *ti, Foundation f)
Draw foundation f at tile ti.
std::tuple< Slope, int > GetFoundationSlope(TileIndex tile)
Get slope of a tile on top of a (possible) foundation If a tile does not have a foundation,...
Functions related to OTTD's landscape.
Point RemapCoords2(int x, int y)
Map 3D world or tile coordinate to equivalent 2D coordinate as used in the viewports and smallmap.
Definition landscape.h:97
Command definitions related to landscape (slopes etc.).
@ Random
Randomise borders.
uint DistanceSquare(TileIndex t0, TileIndex t1)
Gets the 'Square' distance between the two given tiles.
Definition map.cpp: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:482
TileIndex TileAddByDir(TileIndex tile, Direction dir)
Adds a Direction to a tile.
Definition map_func.h:611
static debug_inline TileIndex TileXY(uint x, uint y)
Returns the TileIndex of a coordinate.
Definition map_func.h:385
TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc)
Return the offset between two tiles from a TileIndexDiffC struct.
Definition map_func.h:452
TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir)
Adds a DiagDir to a tile.
Definition map_func.h:623
TileIndexDiff TileDiffXY(int x, int y)
Calculates an offset for the given coordinate(-offset).
Definition map_func.h:401
constexpr TileIndex TileAdd(TileIndex tile, TileIndexDiff offset)
Adds a given offset to a tile.
Definition map_func.h:469
#define RandomTile()
Get a valid random tile.
Definition map_func.h:664
static debug_inline uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition map_func.h:437
static debug_inline uint TileX(TileIndex tile)
Get the X component of a tile.
Definition map_func.h:427
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition map_func.h:582
TileIndexDiffC TileIndexToTileIndexDiffC(TileIndex tile_a, TileIndex tile_b)
Returns the diff between two tiles.
Definition map_func.h:543
int32_t TileIndexDiff
An offset value between two tiles.
Definition map_type.h:23
constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
constexpr int RoundDivSU(int a, uint b)
Computes round(a / b) for signed a and unsigned b.
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition math_func.hpp:79
@ GSF_FAKE_TOWNS
Fake town GrfSpecFeature for NewGRF debugging (parent scope)
Definition newgrf.h:95
@ CBID_HOUSE_DRAW_FOUNDATIONS
Called to determine the type (if any) of foundation to draw for house tile.
@ CBID_HOUSE_CARGO_ACCEPTANCE
Called to decide how much cargo a town building can accept.
@ CBID_HOUSE_AUTOSLOPE
Called to determine if one can alter the ground below a house tile.
@ CBID_HOUSE_CUSTOM_NAME
Called on the Get Tile Description for an house tile.
@ CBID_HOUSE_ALLOW_CONSTRUCTION
Determine whether the house can be built on the specified tile.
@ CBID_HOUSE_ACCEPT_CARGO
Called to determine which cargoes a town building should accept.
@ CBID_HOUSE_PRODUCE_CARGO
Called to determine how much cargo a town building produces.
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
@ AllowConstruction
decide whether the house can be built on a given tile
@ AcceptCargo
decides accepted types
@ CargoAcceptance
decides amount of cargo acceptance
@ DrawFoundations
decides if default foundations need to be drawn
@ ProduceCargo
custom cargo production
@ Autoslope
decides allowance of autosloping
static const uint CALLBACK_HOUSEPRODCARGO_END
Sentinel indicating that the loop for CBID_HOUSE_PRODUCE_CARGO has ended.
CargoType GetCargoTranslation(uint8_t cargo, const GRFFile *grffile, bool usebit)
Translate a GRF-local cargo slot/bitnum into a CargoType.
Cargo support for NewGRFs.
void ErrorUnknownCallbackResult(uint32_t grfid, uint16_t cbid, uint16_t cb_res)
Record that a NewGRF returned an unknown/invalid callback result.
bool Convert8bitBooleanCallback(const GRFFile *grffile, uint16_t cbid, uint16_t cb_res)
Converts a callback result into a boolean.
bool ConvertBooleanCallback(const GRFFile *grffile, uint16_t cbid, uint16_t cb_res)
Converts a callback result into a boolean.
GRFConfig * GetGRFConfig(uint32_t grfid, uint32_t mask)
Retrieve a NewGRF from the current config by its grfid.
Functions/types related to NewGRF debugging.
void DeleteNewGRFInspectWindow(GrfSpecFeature feature, uint index)
Delete inspect window for a given feature and index.
void DecreaseBuildingCount(Town *t, HouseID house_id)
DecreaseBuildingCount() Decrease the number of a building when it is deleted.
void IncreaseBuildingCount(Town *t, HouseID house_id)
IncreaseBuildingCount() Increase the count of a building when it has been added by a town.
void InitializeBuildingCounts()
Initialise global building counts and all town building counts.
Functions related to NewGRF houses.
StringID GetGRFStringID(uint32_t grfid, GRFStringID stringid)
Returns the index for this stringid associated with its grfID.
Header of Action 04 "universal holder" structure and functions.
static constexpr GRFStringID GRFSTR_MISC_GRF_TEXT
Miscellaneous GRF text range.
Functions related to news.
void AddNewsItem(EncodedString &&headline, NewsType type, NewsStyle style, NewsFlags flags, NewsReference ref1={}, NewsReference ref2={}, std::unique_ptr< NewsAllocatedData > &&data=nullptr, AdviceType advice_type=AdviceType::Invalid)
Add a new newsitem to be shown.
Definition news_gui.cpp:902
@ General
General news (from towns)
@ IndustryOpen
Opening of industries.
@ Company
Company news item. (Newspaper with face)
@ Normal
Normal news item. (Newspaper with text only)
Functions related to objects.
void BuildObject(ObjectType type, TileIndex tile, CompanyID owner=OWNER_NONE, struct Town *town=nullptr, uint8_t view=0)
Actually build the object.
Base for all objects.
Map accessors for object tiles.
static const ObjectType OBJECT_STATUE
Statue in towns.
Definition object_type.h:20
Some methods of Pool are placed here in order to reduce compilation time and binary size.
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don't get linker errors.
static debug_inline bool IsPlainRailTile(Tile t)
Checks whether the tile is a rail tile or rail tile with signals.
Definition rail_map.h:60
Randomizer _random
Random used in the game state calculations.
Pseudo random number generator.
uint32_t RandomRange(uint32_t limit, const std::source_location location=std::source_location::current())
Pick a random number between 0 and limit - 1, inclusive.
bool Chance16(const uint32_t a, const uint32_t b, const std::source_location location=std::source_location::current())
Flips a coin with given probability.
RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb)
Clean up unnecessary RoadBits of a planned tile.
Definition road.cpp:59
Road specific functions.
@ NoHouses
Bit number for setting this roadtype as not house friendly.
@ TownBuild
Bit number for allowing towns to build this roadtype.
RoadTypes GetMaskForRoadTramType(RoadTramType rtt)
Get the mask for road types of the given RoadTramType.
Definition road.h:184
const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
Definition road.h:216
void UpdateNearestTownForRoadTiles(bool invalidate)
Updates cached nearest town for all road tiles.
Road related functions.
RoadBits DiagDirToRoadBits(DiagDirection d)
Create the road-part which belongs to the given DiagDirection.
Definition road_func.h:96
Functions used internally by the roads.
RoadBits GetAnyRoadBits(Tile tile, RoadTramType rtt, bool straight_tunnel_bridge_entrance)
Returns the RoadBits on an arbitrary tile Special behaviour:
Definition road_map.cpp:54
void SetRoadOwner(Tile t, RoadTramType rtt, Owner o)
Set the owner of a specific road type.
Definition road_map.h:235
bool HasTownOwnedRoad(Tile t)
Checks if given tile has town owned road.
Definition road_map.h:264
static debug_inline bool IsNormalRoadTile(Tile t)
Return whether a tile is a normal road tile.
Definition road_map.h:58
static debug_inline bool IsRoadDepot(Tile t)
Return whether a tile is a road depot.
Definition road_map.h:90
DisallowedRoadDirections GetDisallowedRoadDirections(Tile t)
Gets the disallowed directions.
Definition road_map.h:285
bool HasTileRoadType(Tile t, RoadTramType rtt)
Check if a tile has a road or a tram road type.
Definition road_map.h:195
DiagDirection GetRoadDepotDirection(Tile t)
Get the direction of the exit of a road depot.
Definition road_map.h:545
static debug_inline bool IsRoadDepotTile(Tile t)
Return whether a tile is a road depot tile.
Definition road_map.h:100
bool IsRoadOwner(Tile t, RoadTramType rtt, Owner o)
Check if a specific road type is owned by an owner.
Definition road_map.h:252
RoadBits
Enumeration for the road parts on a tile.
Definition road_type.h: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:48
@ SLOPE_W
the west corner of the tile is raised
Definition slope_type.h:50
@ SLOPE_ELEVATED
bit mask containing all 'simple' slopes
Definition slope_type.h:61
@ SLOPE_E
the east corner of the tile is raised
Definition slope_type.h:52
@ SLOPE_S
the south corner of the tile is raised
Definition slope_type.h:51
@ SLOPE_N
the north corner of the tile is raised
Definition slope_type.h:53
@ SLOPE_SW
south and west corner are raised
Definition slope_type.h:56
@ SLOPE_FLAT
a flat tile
Definition slope_type.h:49
@ SLOPE_STEEP_W
a steep slope falling to east (from west)
Definition slope_type.h:66
@ SLOPE_NE
north and east corner are raised
Definition slope_type.h:58
@ SLOPE_STEEP_E
a steep slope falling to west (from east)
Definition slope_type.h:68
@ SLOPE_SE
south and east corner are raised
Definition slope_type.h:57
@ SLOPE_NW
north and west corner are raised
Definition slope_type.h:55
@ SLOPE_STEEP_N
a steep slope falling to south (from north)
Definition slope_type.h:69
@ SLOPE_STEEP_S
a steep slope falling to north (from south)
Definition slope_type.h:67
Foundation
Enumeration for Foundations.
Definition slope_type.h:93
@ FOUNDATION_LEVELED
The tile is leveled up to a flat slope.
Definition slope_type.h:95
@ FOUNDATION_NONE
The tile has no foundation, the slope remains unchanged.
Definition slope_type.h:94
@ Town
Source/destination is a town.
Base classes/functions for stations.
void ForAllStationsAroundTiles(const TileArea &ta, Func func)
Call a function on all stations that have any part of the requested area within their catchment.
void UpdateAllStationVirtCoords()
Update the virtual coords needed to draw the station sign for all stations.
void UpdateAirportsNoise()
Recalculate the noise generated by the airports of each town.
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:350
Functions related to low-level strings.
EncodedString GetEncodedString(StringID str)
Encode a string with no parameters into an encoded string.
Definition strings.cpp:90
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
Definition strings.cpp:424
Functions related to OTTD's strings.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
Class to backup a specific variable and restore it upon destruction of this object to prevent stack v...
Class to backup a specific variable and restore it later.
void Restore()
Restore the variable.
Owner owner
The owner of this station.
Class for storing amounts of cargo.
Definition cargo_type.h:113
static void InvalidateAllFrom(Source src)
Invalidates (sets source_id to INVALID_SOURCE) all cargo packets from given source.
Specification of a cargo type.
Definition cargotype.h:74
static IterateWrapper Iterate(size_t from=0)
Returns an iterable ensemble of all valid CargoSpec.
Definition cargotype.h:192
static std::array< std::vector< const CargoSpec * >, NUM_TPE > town_production_cargoes
List of cargo specs for each Town Product Effect.
Definition cargotype.h:25
bool value
tells if the bool cheat is active or not
Definition cheat_type.h:18
Cheat magic_bulldozer
dynamite industries, objects
Definition cheat_type.h:27
GUISettings gui
settings related to the GUI
bool build_on_slopes
allow building on slopes
T y
Y coordinate.
T x
X coordinate.
T x
X coordinate.
T y
Y coordinate.
uint8_t number_towns
the amount of towns
uint8_t town_council_tolerance
minimum required town ratings to be allowed to demolish stuff
This structure is the same for both Industries and Houses.
Definition sprite.h:81
bool bribe
enable bribing the local authority
TownFounding found_town
town founding.
PlaceHouses place_houses
players are allowed to place town houses.
bool exclusive_rights
allow buying exclusive rights
uint8_t initial_city_size
multiplier for the initial size of the cities compared to towns
TownLayout town_layout
select town layout,
bool allow_town_level_crossings
towns are allowed to build level crossings
uint8_t town_growth_rate
town growth rate
bool allow_town_roads
towns are allowed to build roads (always allowed when generating world / in SE)
bool fund_buildings
allow funding new buildings
bool fund_roads
allow funding local road reconstruction
TownCargoGenMode town_cargogen_mode
algorithm for generating cargo from houses,
uint8_t dist_local_authority
distance for town local authority, default 20
uint8_t larger_towns
the number of cities to build. These start off larger and grow twice as fast
Information about GRF, used in the game and (part of it) in savegames.
std::string GetName() const
Get the name of this grf.
const struct GRFFile * grffile
grf file that introduced this entity
uint32_t grfid
grfid that introduced this entity.
bool HasGrfFile() const
Test if this entity was introduced by NewGRF.
bool population_in_label
show the population of a town in its label?
uint16_t custom_town_number
manually entered number of towns
LandscapeType landscape
the landscape we're currently in
uint8_t town_name
the town name generator used for town names
EconomySettings economy
settings to change the economy
ConstructionSettings construction
construction of things in-game
DifficultySettings difficulty
settings related to the difficulty
GameCreationSettings game_creation
settings used during the creation of a game (map)
Stores station stats for a single cargo.
CargoType accepts_cargo[HOUSE_NUM_ACCEPTS]
input cargo slots
Definition house.h:108
SubstituteGRFFileProps grf_prop
Properties related the the grf file.
Definition house.h:114
uint8_t probability
Relative probability of appearing (16 is the standard value)
Definition house.h:117
uint8_t removal_cost
cost multiplier for removing it
Definition house.h:103
uint8_t mail_generation
mail generation multiplier (tile based, as the acceptances below)
Definition house.h:106
bool enabled
the house is available to build (true by default, but can be disabled by newgrf)
Definition house.h:111
Money GetRemovalCost() const
Get the cost for removing this house.
Definition town_cmd.cpp:230
static HouseSpec * Get(size_t house_id)
Get the spec for a house ID.
BuildingFlags building_flags
some flags that describe the house (size, stadium etc...)
Definition house.h:109
TimerGameCalendar::Year max_year
last year it can be built
Definition house.h:101
HouseCallbackMasks callback_mask
Bitmask of house callbacks that have to be called.
Definition house.h:115
uint16_t remove_rating_decrease
rating decrease if removed
Definition house.h:105
uint8_t population
population (Zero on other tiles in multi tile house.)
Definition house.h:102
HouseExtraFlags extra_flags
some more flags
Definition house.h:118
uint8_t cargo_acceptance[HOUSE_NUM_ACCEPTS]
acceptance level for the cargo slots
Definition house.h:107
HouseID Index() const
Gets the index of this spec.
HouseClassID class_id
defines the class this house has (not grf file based)
Definition house.h:119
StringID building_name
building name
Definition house.h:104
uint8_t minimum_life
The minimum number of years this house will survive before the town rebuilds it.
Definition house.h:122
HouseZones building_availability
where can it be built (climates, zones)
Definition house.h:110
static std::vector< HouseSpec > & Specs()
Get a reference to all HouseSpecs.
Defines the internal data of a functional industry.
Definition industry.h:62
Town * town
Nearest town.
Definition industry.h:107
static Industry * GetByTile(TileIndex tile)
Get the industry of the given tile.
Definition industry.h:251
Size related data of the map.
Definition map_func.h:206
static uint ScaleBySize(uint n)
Scales the given value by the map size, where the given value is for a 256 by 256 map.
Definition map_func.h:340
static IterateWrapper Iterate()
Returns an iterable ensemble of all Tiles.
Definition map_func.h:375
static uint ScaleByLandProportion(uint n)
Scales the given value by the number of water tiles.
Definition map_func.h:318
static debug_inline uint Size()
Get the size of the map.
Definition map_func.h:290
An object, such as transmitter, on the map.
Definition object_base.h:23
ObjectType type
Type of the object.
Definition object_base.h:24
Town * town
Town the object is built in.
Definition object_base.h:25
static Object * GetByTile(TileIndex tile)
Get the object associated with a tile.
Represents the covered area of e.g.
void Add(TileIndex to_add)
Add a single tile to a tile area; enlarge if needed.
Definition tilearea.cpp:43
SpriteID sprite
The 'real' sprite.
Definition gfx_type.h:23
PaletteID pal
The palette (use PAL_NONE) if not needed)
Definition gfx_type.h:24
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
static size_t GetPoolSize()
Returns first unused index.
static Titem * Get(auto index)
Returns Titem with given index.
static size_t GetNumItems()
Returns number of valid items in the pool.
Tindex index
Index of this pool item.
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
static bool IsValidID(auto index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
static bool CleaningPool()
Returns current state of pool cleaning - yes or no.
static Titem * GetIfValid(auto index)
Returns Titem with given index.
Base class for all pools.
static constexpr size_t MAX_SIZE
Make template parameter accessible from outside.
A location from where cargo can come from (or go to).
Definition source_type.h:32
static Pool::IterateWrapper< Station > Iterate(size_t from=0)
Returns an iterable ensemble of all valid stations of type T.
Station data structure.
bool CatchmentCoversTown(TownID t) const
Test if the given town ID is covered by our catchment area.
Definition station.cpp:452
uint16_t override_id
id of the entity been replaced by
Tile description for the 'land area information' tool.
Definition tile_cmd.h:36
std::optional< std::string > grf
newGRF used for the tile contents
Definition tile_cmd.h:47
StringID str
Description of the tile.
Definition tile_cmd.h:37
std::array< Owner, 4 > owner
Name of the owner(s)
Definition tile_cmd.h:39
uint64_t dparam
Parameter of the str string.
Definition tile_cmd.h:38
std::optional< bool > town_can_upgrade
Whether the town can upgrade this house during town growth.
Definition tile_cmd.h:54
A pair-construct of a TileIndexDiff.
Definition map_type.h:31
int16_t x
The x value of the coordinate.
Definition map_type.h:32
int16_t y
The y value of the coordinate.
Definition map_type.h:33
Tile information, used while rendering the tile.
Definition tile_cmd.h:30
Slope tileh
Slope of the tile.
Definition tile_cmd.h:31
TileIndex tile
Tile index.
Definition tile_cmd.h:32
Set of callback functions for performing tile operations of a given tile type.
Definition tile_cmd.h:152
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
TownLayout layout
town specific road layout
Definition town.h:151
static Town * GetRandom()
Return a random valid town.
Definition town_cmd.cpp:201
std::string name
Custom town name. If empty, the town was not renamed and uses the generated name.
Definition town.h:72
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:187
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:396
CompanyMask have_ratings
which companies have a rating
Definition town.h:82
~Town()
Destroy the town.
Definition town_cmd.cpp:113
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:172
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
void UpdatePosition(int center, int top, std::string_view str, std::string_view str_small={})
Update the position of the viewport sign.
bool kdtree_valid
Are the sign data valid for use with the _viewport_sign_kdtree?
Representation of a waypoint.
void DeleteSubsidyWith(Source source)
Delete the subsidies associated with a given cargo source type and id.
Definition subsidy.cpp:119
Functions related to subsidies.
Command definitions related to terraforming.
bool IsTileFlat(TileIndex tile, int *h)
Check if a given tile is flat.
Definition tile_map.cpp:95
int GetTileMaxZ(TileIndex t)
Get top height of the tile inside the map.
Definition tile_map.cpp:136
int GetTileZ(TileIndex tile)
Get bottom height of the tile.
Definition tile_map.cpp:116
uint TileHash(uint x, uint y)
Calculate a hash value from a tile position.
Definition tile_map.h:324
bool IsTileOwner(Tile tile, Owner owner)
Checks if a tile belongs to the given owner.
Definition tile_map.h:214
int GetTileMaxPixelZ(TileIndex tile)
Get top height of the tile.
Definition tile_map.h:312
static debug_inline TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
Definition tile_map.h:96
bool IsValidTile(Tile tile)
Checks if a tile is valid.
Definition tile_map.h:161
uint TileHash2Bit(uint x, uint y)
Get the last two bits of the TileHash from a tile position.
Definition tile_map.h:342
TropicZone GetTropicZone(Tile tile)
Get the tropic zone.
Definition tile_map.h:238
static debug_inline bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition tile_map.h:150
Slope GetTileSlope(TileIndex tile)
Return the slope of a given tile inside the map.
Definition tile_map.h:279
static debug_inline uint TileHeight(Tile tile)
Returns the height of a tile.
Definition tile_map.h:29
@ TROPICZONE_DESERT
Tile is desert.
Definition tile_type.h:78
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:95
static constexpr uint TILE_SIZE
Tile size in world coordinates.
Definition tile_type.h:15
@ MP_TREES
Tile got trees.
Definition tile_type.h:52
@ MP_ROAD
A tile with road (or tram tracks)
Definition tile_type.h:50
@ MP_STATION
A tile of a station.
Definition tile_type.h:53
@ MP_TUNNELBRIDGE
Tunnel entry/exit and bridge heads.
Definition tile_type.h:57
@ MP_CLEAR
A tile without any structures, i.e. grass, rocks, farm fields etc.
Definition tile_type.h:48
@ MP_HOUSE
A house by a town.
Definition tile_type.h:51
@ MP_WATER
Water tile.
Definition tile_type.h:54
@ MP_RAILWAY
A railway.
Definition tile_type.h:49
@ MP_INDUSTRY
Part of an industry.
Definition tile_type.h:56
@ MP_VOID
Invisible tiles at the SW and SE border.
Definition tile_type.h:55
@ MP_OBJECT
Contains objects such as transmitters and owned land.
Definition tile_type.h:58
OrthogonalTileArea TileArea
Shorthand for the much more common orthogonal tile area.
Definition of Interval and OneShot timers.
Definition of the game-calendar-timer.
Definition of the game-economy-timer.
Definition of the tick-based game-timer.
Base of the town class.
static const uint TOWN_GROWTH_WINTER
The town only needs this cargo in the winter (any amount)
Definition town.h:32
TownRatingCheckType
Action types that a company must ask permission for to a town authority.
Definition town.h:224
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:247
@ RoadRebuild
Rebuild the roads.
@ Bribe
Try to bribe the council.
@ BuildStatue
Build a statue.
@ BuyRights
Buy exclusive transport rights.
@ FundBuildings
Fund new buildings.
@ HasChurch
There can be only one church by town.
@ CustomGrowth
Growth rate is controlled by GS.
@ HasStadium
There can be only one stadium by town.
@ IsGrowing
Conditions for town growth are met. Grow according to Town::growth_rate.
static const uint16_t TOWN_GROWTH_RATE_NONE
Special value for Town::growth_rate to disable town growth.
Definition town.h:34
static bool RoadTypesAllowHouseHere(TileIndex t)
Checks whether at least one surrounding road allows to build a house here.
static bool CheckFree2x2Area(TileIndex tile, int z, bool noslope)
Checks if a house of size 2x2 can be built at this tile.
std::tuple< CommandCost, Money, TownID > CmdFoundTown(DoCommandFlags flags, TileIndex tile, TownSize size, bool city, TownLayout layout, bool random_location, uint32_t townnameparts, const std::string &text)
Create a new town.
void ChangeTownRating(Town *t, int add, int max, DoCommandFlags flags)
Changes town rating of the current company.
HouseZones GetClimateMaskForLandscape()
Get the HouseZones climate mask for the current landscape type.
static bool GrowTownAtRoad(Town *t, TileIndex tile, TownExpandModes modes)
Try to grow a town at a given road tile.
static CommandCost TownActionAdvertiseSmall(Town *t, DoCommandFlags flags)
Perform the "small advertising campaign" town action.
static CommandCost TownActionFundBuildings(Town *t, DoCommandFlags flags)
Perform the "fund new buildings" town action.
static bool IsTileAlignedToGrid(TileIndex tile, TownLayout layout)
Towns must all be placed on the same grid or when they eventually interpenetrate their road networks ...
static CommandCost TownActionBuildStatue(Town *t, DoCommandFlags flags)
Perform a 9x9 tiles circular search from the center of the town in order to find a free tile to place...
static CommandCost TownActionBribe(Town *t, DoCommandFlags flags)
Perform the "bribe" town action.
TileIndexDiff GetHouseNorthPart(HouseID &house)
Determines if a given HouseID is part of a multitile house.
static int GetRating(const Town *t)
Get the rating of a town for the _current_company.
uint GetDefaultTownsForMapSize()
Calculate the number of towns which should be on the map according to the current "town density" newg...
void ClearTownHouse(Town *t, TileIndex tile)
Clear a town house.
static uint GetNormalGrowthRate(Town *t)
Calculates town growth rate in normal conditions (custom growth rate not set).
TownActions GetMaskOfTownActions(CompanyID cid, const Town *t)
Get a list of available town authority actions.
static CommandCost TownActionBuyRights(Town *t, DoCommandFlags flags)
Perform the "buy exclusive transport rights" town action.
static bool GrowTownWithBridge(const Town *t, const TileIndex tile, const DiagDirection bridge_dir)
Grows the town with a bridge.
const CargoSpec * FindFirstCargoWithTownAcceptanceEffect(TownAcceptanceEffect effect)
Determines the first cargo with a certain town effect.
static TileIndex FindNearestGoodCoastalTownSpot(TileIndex tile, TownLayout layout)
Given a spot on the map (presumed to be a water tile), find a good coastal spot to build a city.
Town * ClosestTownFromTile(TileIndex tile, uint threshold)
Return the town closest (in distance or ownership) to a given tile, within a given threshold.
static bool IsRoadAllowedHere(Town *t, TileIndex tile, DiagDirection dir)
Check if a Road is allowed on a given tile.
static bool CanRoadContinueIntoNextTile(const Town *t, const TileIndex tile, const DiagDirection road_dir)
Checks if a town road can be continued into the next tile.
static bool TryBuildTownHouse(Town *t, TileIndex tile, TownExpandModes modes)
Tries to build a house at this tile.
static void UpdateTownGrowCounter(Town *t, uint16_t prev_growth_rate)
Updates town grow counter after growth rate change.
static int CountActiveStations(Town *t)
Calculates amount of active stations in the range of town (HZB_TOWN_EDGE).
static CommandCost TownCanBePlacedHere(TileIndex tile)
Check if it's possible to place a town on a given tile.
static bool IsNeighbourRoadTile(TileIndex tile, const DiagDirection dir, uint dist_multi)
Check for parallel road inside a given distance.
CommandCost CmdPlaceHouse(DoCommandFlags flags, TileIndex tile, HouseID house, bool is_protected)
Place an individual house.
static bool _generating_town
Set if a town is being generated.
Definition town_cmd.cpp:86
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:600
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:577
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:514
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:455
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:715
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:557
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:440
CargoArray GetAcceptedCargoOfHouse(const HouseSpec *hs)
Get accepted cargo of a house prototype.
Definition town_cmd.cpp:856
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:787
static DiagDirection RandomDiagDir()
Return a random direction.
Definition town_cmd.cpp:253
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:469
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:428
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:313
static TimerGameCalendar::Date GetTownRoadTypeFirstIntroductionDate()
Get the calendar date of the earliest town-buildable road type.
Definition town_cmd.cpp:993
static void AnimateTile_Town(TileIndex tile)
Animate a tile for a town.
Definition town_cmd.cpp:337
const TileTypeProcs _tile_type_town_procs
Tile callback functions for a town.
Definition landscape.cpp:53
RoadType GetTownRoadType()
Get the road type that towns should build at this current moment.
Definition town_cmd.cpp:963
static RoadBits GetTownRoadBits(TileIndex tile)
Return the RoadBits of a tile, ignoring depot and bay road stops.
Definition town_cmd.cpp:952
CommandCost CmdRenameTown(DoCommandFlags flags, TownID town_id, const std::string &text)
Rename a town (server-only).
CommandCost CmdTownCargoGoal(DoCommandFlags flags, TownID town_id, TownAcceptanceEffect tae, uint32_t goal)
Change the cargo goal of a town.
static void DoCreateTown(Town *t, TileIndex tile, uint32_t townnameparts, TownSize size, bool city, TownLayout layout, bool manual)
Actually create a town.
CommandCost CheckforTownRating(DoCommandFlags flags, Town *t, TownRatingCheckType type)
Does the town authority allow the (destructive) action of the current company?
HouseZone GetTownRadiusGroup(const Town *t, TileIndex tile)
Returns the bit corresponding to the town zone of the specified tile.
static bool CheckTownBuild2House(TileIndex *tile, Town *t, int maxz, bool noslope, DiagDirection second, TownExpandModes modes)
Checks if a 1x2 or 2x1 building is allowed here, accounting for road layout and tile heights.
static bool TestTownOwnsBridge(TileIndex tile, const Town *t)
Check if a town 'owns' a bridge.
Definition town_cmd.cpp:97
void OnTick_Town()
Iterate through all towns and call their tick handler.
Definition town_cmd.cpp:938
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:491
static void TownTickHandler(Town *t)
Handle the town tick for a single town, by growing the town if desired.
Definition town_cmd.cpp:919
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:803
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:388
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:531
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:262
void UpdateAllTownVirtCoords()
Update the virtual coords needed to draw the town sign for all towns.
Definition town_cmd.cpp:420
Command definitions related to towns.
Declarations for accessing the k-d tree of towns.
Sprites to use and how to display them for town tiles.
static const DrawBuildingsTileStruct _town_draw_tile_data[]
structure of houses graphics
Definition town_land.h:27
void IncrementHouseAge(Tile t)
Increments the age of the house.
Definition town_map.h:259
void HaltLift(Tile t)
Stop the lift of this animated house from moving.
Definition town_map.h:137
HouseID GetHouseType(Tile t)
Get the type of this house, which is an index into the house spec array.
Definition town_map.h:60
void ResetHouseAge(Tile t)
Sets the age of the house to zero.
Definition town_map.h:248
void MakeHouseTile(Tile t, TownID tid, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool house_protected)
Make the tile a house.
Definition town_map.h:375
void IncHouseConstructionTick(Tile t)
Sets the increment stage of a house It is working with the whole counter + stage 5 bits,...
Definition town_map.h:230
uint8_t GetLiftPosition(Tile t)
Get the position of the lift on this animated house.
Definition town_map.h:147
void SetLiftDestination(Tile t, uint8_t dest)
Set the new destination of the lift for this animated house, and activate the LiftHasDestination bit.
Definition town_map.h:115
TimerGameCalendar::Year GetHouseAge(Tile t)
Get the age of the house.
Definition town_map.h:271
void SetLiftPosition(Tile t, uint8_t pos)
Set the position of the lift on this animated house.
Definition town_map.h:157
uint8_t GetLiftDestination(Tile t)
Get the current destination for this lift.
Definition town_map.h:126
uint8_t GetHouseBuildingStage(Tile t)
House Construction Scheme.
Definition town_map.h:205
TownID GetTownIndex(Tile t)
Get the index of which town this house/street is attached to.
Definition town_map.h:23
void SetTownIndex(Tile t, TownID index)
Set the town index for a road or house tile.
Definition town_map.h:35
bool LiftHasDestination(Tile t)
Check if the lift of this animated house has a destination.
Definition town_map.h:104
bool IsHouseCompleted(Tile t)
Get the completion of this house.
Definition town_map.h:167
bool IsHouseProtected(Tile t)
Check if the house is protected from removal by towns.
Definition town_map.h:82
uint8_t GetHouseConstructionTick(Tile t)
Gets the construction stage of a house.
Definition town_map.h:217
static constexpr int RATING_GROWTH_UP_STEP
when a town grows, all companies have rating increased a bit ...
Definition town_type.h:53
static constexpr int RATING_INITIAL
initial rating
Definition town_type.h:45
static constexpr int RATING_ROAD_NEEDED_HOSTILE
"Hostile"
Definition town_type.h:71
@ TCGM_BITCOUNT
Bit-counted algorithm (normal distribution from individual house population)
Definition town_type.h:115
@ TCGM_ORIGINAL
Original algorithm (quadratic cargo by population)
Definition town_type.h:114
static constexpr int RATING_ROAD_NEEDED_NEUTRAL
"Neutral"
Definition town_type.h:70
TownLayout
Town Layouts.
Definition town_type.h:81
@ TL_3X3_GRID
Geometric 3x3 grid algorithm.
Definition town_type.h:86
@ TL_ORIGINAL
Original algorithm (min. 1 distance between roads)
Definition town_type.h:83
@ TL_2X2_GRID
Geometric 2x2 grid algorithm.
Definition town_type.h:85
@ TL_RANDOM
Random town layout.
Definition town_type.h:88
@ TL_BETTER_ROADS
Extended original algorithm (min. 2 distance between roads)
Definition town_type.h:84
@ NUM_TLS
Number of town layouts.
Definition town_type.h:90
static constexpr int RATING_TUNNEL_BRIDGE_NEEDED_LENIENT
rating needed, "Lenient" difficulty settings
Definition town_type.h:61
@ TF_CUSTOM_LAYOUT
Allowed, with custom town layout.
Definition town_type.h:107
@ TF_FORBIDDEN
Forbidden.
Definition town_type.h:105
static constexpr int RATING_TUNNEL_BRIDGE_NEEDED_HOSTILE
"Hostile"
Definition town_type.h:63
static constexpr int RATING_TUNNEL_BRIDGE_NEEDED_PERMISSIVE
"Permissive" (local authority disabled)
Definition town_type.h:64
static constexpr int RATING_TUNNEL_BRIDGE_NEEDED_NEUTRAL
"Neutral"
Definition town_type.h:62
static constexpr int RATING_ROAD_NEEDED_LENIENT
rating needed, "Lenient" difficulty settings
Definition town_type.h:69
TownSize
Supported initial town sizes.
Definition town_type.h:21
@ TSZ_RANDOM
Random size, bigger than small, smaller than large.
Definition town_type.h:25
@ TSZ_END
Number of available town sizes.
Definition town_type.h:27
@ TSZ_LARGE
Large town.
Definition town_type.h:24
static const uint MAX_LENGTH_TOWN_NAME_CHARS
The maximum length of a town name in characters including '\0'.
Definition town_type.h:119
@ Roads
Allow town to place roads.
@ Buildings
Allow town to place buildings.
static constexpr int RATING_ROAD_NEEDED_PERMISSIVE
"Permissive" (local authority disabled)
Definition town_type.h:72
static constexpr int RATING_GROWTH_MAXIMUM
... up to RATING_MEDIOCRE
Definition town_type.h:54
bool VerifyTownName(uint32_t r, const TownNameParams *par, TownNames *town_names)
Verifies the town name is valid and unique.
Definition townname.cpp:103
bool GenerateTownName(Randomizer &randomizer, uint32_t *townnameparts, TownNames *town_names)
Generates valid town name.
Definition townname.cpp:136
Town name generator stuff.
bool IsTransparencySet(TransparencyOption to)
Check if the transparency option bit is set and if we aren't in the game menu (there's never transpar...
bool IsInvisibilitySet(TransparencyOption to)
Check if the invisibility option bit is set and if we aren't in the game menu (there's never transpar...
@ TO_HOUSES
town buildings
TransportType
Available types of transport.
@ TRANSPORT_ROAD
Transport by road vehicle.
Command definitions related to tunnels and bridges.
Functions that have tunnels and bridges in common.
DiagDirection GetTunnelBridgeDirection(Tile t)
Get the direction pointing to the other end.
TransportType GetTunnelBridgeTransportType(Tile t)
Tunnel: Get the transport type of the tunnel (road or rail) Bridge: Get the transport type of the bri...
TileIndex GetOtherTunnelBridgeEnd(Tile t)
Determines type of the wormhole and returns its other end.
void AddSortableSpriteToDraw(SpriteID image, PaletteID pal, int x, int y, int z, const SpriteBounds &bounds, bool transparent, const SubSprite *sub)
Draw a (transparent) sprite at given coordinates with a given bounding box.
Definition viewport.cpp:663
void AddChildSpriteScreen(SpriteID image, PaletteID pal, int x, int y, bool transparent, const SubSprite *sub, bool scale, bool relative)
Add a child sprite to a parent sprite.
Definition viewport.cpp:824
void DrawGroundSprite(SpriteID image, PaletteID pal, const SubSprite *sub, int extra_offs_x, int extra_offs_y)
Draws a ground sprite for the current tile.
Definition viewport.cpp:579
Functions related to (drawing on) viewports.
bool HasTileWaterGround(Tile t)
Checks whether the tile has water at the ground.
Definition water_map.h: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:1193
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition window.cpp:3184
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:3276
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition window.cpp:3158
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: