OpenTTD Source 20250205-master-gfd85ab1e2c
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 "road.h"
12#include "road_internal.h" /* Cleaning up road bits */
13#include "road_cmd.h"
14#include "landscape.h"
15#include "viewport_func.h"
16#include "viewport_kdtree.h"
17#include "command_func.h"
18#include "company_func.h"
19#include "industry.h"
20#include "station_base.h"
21#include "waypoint_base.h"
22#include "station_kdtree.h"
23#include "company_base.h"
24#include "news_func.h"
25#include "error.h"
26#include "object.h"
27#include "genworld.h"
28#include "newgrf_debug.h"
29#include "newgrf_house.h"
30#include "newgrf_text.h"
31#include "autoslope.h"
32#include "tunnelbridge_map.h"
33#include "strings_func.h"
34#include "window_func.h"
35#include "string_func.h"
36#include "newgrf_cargo.h"
37#include "cheat_type.h"
38#include "animated_tile_func.h"
39#include "subsidy_func.h"
40#include "core/pool_func.hpp"
41#include "town.h"
42#include "town_kdtree.h"
43#include "townname_func.h"
44#include "core/random_func.hpp"
45#include "core/backup_type.hpp"
46#include "depot_base.h"
47#include "object_map.h"
48#include "object_base.h"
49#include "ai/ai.hpp"
50#include "game/game.hpp"
51#include "town_cmd.h"
52#include "landscape_cmd.h"
53#include "road_cmd.h"
54#include "terraform_cmd.h"
55#include "tunnelbridge_cmd.h"
56#include "timer/timer.h"
60
61#include "table/strings.h"
62#include "table/town_land.h"
63
64#include "safeguards.h"
65
66/* Initialize the town-pool */
67TownPool _town_pool("Town");
69
70
71TownKdtree _town_kdtree{};
72
73void RebuildTownKdtree()
74{
75 std::vector<TownID> townids;
76 for (const Town *town : Town::Iterate()) {
77 townids.push_back(town->index);
78 }
79 _town_kdtree.Build(townids.begin(), townids.end());
80}
81
83static bool _generating_town = false;
84
94static bool TestTownOwnsBridge(TileIndex tile, const Town *t)
95{
96 if (!IsTileOwner(tile, OWNER_TOWN)) return false;
97
99 bool town_owned = IsTileType(adjacent, MP_ROAD) && IsTileOwner(adjacent, OWNER_TOWN) && GetTownIndex(adjacent) == t->index;
100
101 if (!town_owned) {
102 /* Or other adjacent road */
104 town_owned = IsTileType(adjacent, MP_ROAD) && IsTileOwner(adjacent, OWNER_TOWN) && GetTownIndex(adjacent) == t->index;
105 }
106
107 return town_owned;
108}
109
111{
112 if (CleaningPool()) return;
113
114 /* Delete town authority window
115 * and remove from list of sorted towns */
117
118#ifdef WITH_ASSERT
119 /* Check no industry is related to us. */
120 for (const Industry *i : Industry::Iterate()) {
121 assert(i->town != this);
122 }
123
124 /* ... and no object is related to us. */
125 for (const Object *o : Object::Iterate()) {
126 assert(o->town != this);
127 }
128
129 /* Check no tile is related to us. */
130 for (const auto tile : Map::Iterate()) {
131 switch (GetTileType(tile)) {
132 case MP_HOUSE:
133 assert(GetTownIndex(tile) != this->index);
134 break;
135
136 case MP_ROAD:
137 assert(!HasTownOwnedRoad(tile) || GetTownIndex(tile) != this->index);
138 break;
139
140 case MP_TUNNELBRIDGE:
141 assert(!TestTownOwnsBridge(tile, this));
142 break;
143
144 default:
145 break;
146 }
147 }
148#endif /* WITH_ASSERT */
149
150 /* Clear the persistent storage list. */
151 for (auto &psa : this->psa_list) {
152 delete psa;
153 }
154 this->psa_list.clear();
155
160}
161
162
168{
169 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_REBUILD);
171
172 /* Give objects a new home! */
173 for (Object *o : Object::Iterate()) {
174 if (o->town == nullptr) o->town = CalcClosestTownFromTile(o->location.tile, UINT_MAX);
175 }
176}
177
183{
184 if (layout != TL_RANDOM) {
185 this->layout = layout;
186 return;
187 }
188
189 this->layout = static_cast<TownLayout>(TileHash(TileX(this->xy), TileY(this->xy)) % (NUM_TLS - 1));
190}
191
196/* static */ Town *Town::GetRandom()
197{
198 if (Town::GetNumItems() == 0) return nullptr;
199 int num = RandomRange((uint16_t)Town::GetNumItems());
200 size_t index = std::numeric_limits<size_t>::max();
201
202 while (num >= 0) {
203 num--;
204 index++;
205
206 /* Make sure we have a valid town */
207 while (!Town::IsValidID(index)) {
208 index++;
209 assert(index < Town::GetPoolSize());
210 }
211 }
212
213 return Town::Get(index);
214}
215
216void Town::FillCachedName() const
217{
218 this->cached_name = GetTownName(this);
219}
220
226{
227 return (_price[PR_CLEAR_HOUSE] * this->removal_cost) >> 8;
228}
229
230/* Local */
231static int _grow_town_result;
232
233/* The possible states of town growth. */
234enum TownGrowthResult {
235 GROWTH_SUCCEED = -1,
236 GROWTH_SEARCH_STOPPED = 0
237// GROWTH_SEARCH_RUNNING >= 1
238};
239
240static bool TryBuildTownHouse(Town *t, TileIndex tile);
241static Town *CreateRandomTown(uint attempts, uint32_t townnameparts, TownSize size, bool city, TownLayout layout);
242
243static void TownDrawHouseLift(const TileInfo *ti)
244{
245 AddChildSpriteScreen(SPR_LIFT, PAL_NONE, 14, 60 - GetLiftPosition(ti->tile));
246}
247
248typedef void TownDrawTileProc(const TileInfo *ti);
249static TownDrawTileProc * const _town_draw_tile_procs[1] = {
250 TownDrawHouseLift
251};
252
259{
261}
262
267static void DrawTile_Town(TileInfo *ti)
268{
269 HouseID house_id = GetHouseType(ti->tile);
270
271 if (house_id >= NEW_HOUSE_OFFSET) {
272 /* Houses don't necessarily need new graphics. If they don't have a
273 * spritegroup associated with them, then the sprite for the substitute
274 * house id is drawn instead. */
275 if (HouseSpec::Get(house_id)->grf_prop.spritegroup[0] != nullptr) {
276 DrawNewHouseTile(ti, house_id);
277 return;
278 } else {
279 house_id = HouseSpec::Get(house_id)->grf_prop.subst_id;
280 }
281 }
282
283 /* Retrieve pointer to the draw town tile struct */
284 const DrawBuildingsTileStruct *dcts = &_town_draw_tile_data[house_id << 4 | TileHash2Bit(ti->x, ti->y) << 2 | GetHouseBuildingStage(ti->tile)];
285
287
288 DrawGroundSprite(dcts->ground.sprite, dcts->ground.pal);
289
290 /* If houses are invisible, do not draw the upper part */
291 if (IsInvisibilitySet(TO_HOUSES)) return;
292
293 /* Add a house on top of the ground? */
294 SpriteID image = dcts->building.sprite;
295 if (image != 0) {
296 AddSortableSpriteToDraw(image, dcts->building.pal,
297 ti->x + dcts->subtile_x,
298 ti->y + dcts->subtile_y,
299 dcts->width,
300 dcts->height,
301 dcts->dz,
302 ti->z,
304 );
305
306 if (IsTransparencySet(TO_HOUSES)) return;
307 }
308
309 {
310 int proc = dcts->draw_proc - 1;
311
312 if (proc >= 0) _town_draw_tile_procs[proc](ti);
313 }
314}
315
316static int GetSlopePixelZ_Town(TileIndex tile, uint, uint, bool)
317{
318 return GetTileMaxPixelZ(tile);
319}
320
327{
328 HouseID hid = GetHouseType(tile);
329
330 /* For NewGRF house tiles we might not be drawing a foundation. We need to
331 * account for this, as other structures should
332 * draw the wall of the foundation in this case.
333 */
334 if (hid >= NEW_HOUSE_OFFSET) {
335 const HouseSpec *hs = HouseSpec::Get(hid);
337 uint32_t callback_res = GetHouseCallback(CBID_HOUSE_DRAW_FOUNDATIONS, 0, 0, hid, Town::GetByTile(tile), tile);
338 if (callback_res != CALLBACK_FAILED && !ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DRAW_FOUNDATIONS, callback_res)) return FOUNDATION_NONE;
339 }
340 }
341 return FlatteningFoundation(tileh);
342}
343
351{
352 if (GetHouseType(tile) >= NEW_HOUSE_OFFSET) {
353 AnimateNewHouseTile(tile);
354 return;
355 }
356
357 if (TimerGameTick::counter & 3) return;
358
359 /* If the house is not one with a lift anymore, then stop this animating.
360 * Not exactly sure when this happens, but probably when a house changes.
361 * Before this was just a return...so it'd leak animated tiles..
362 * That bug seems to have been here since day 1?? */
363 if (!HouseSpec::Get(GetHouseType(tile))->building_flags.Test(BuildingFlag::IsAnimated)) {
364 DeleteAnimatedTile(tile);
365 return;
366 }
367
368 if (!LiftHasDestination(tile)) {
369 uint i;
370
371 /* Building has 6 floors, number 0 .. 6, where 1 is illegal.
372 * This is due to the fact that the first floor is, in the graphics,
373 * the height of 2 'normal' floors.
374 * Furthermore, there are 6 lift positions from floor N (incl) to floor N + 1 (excl) */
375 do {
376 i = RandomRange(7);
377 } while (i == 1 || i * 6 == GetLiftPosition(tile));
378
379 SetLiftDestination(tile, i);
380 }
381
382 int pos = GetLiftPosition(tile);
383 int dest = GetLiftDestination(tile) * 6;
384 pos += (pos < dest) ? 1 : -1;
385 SetLiftPosition(tile, pos);
386
387 if (pos == dest) {
388 HaltLift(tile);
389 DeleteAnimatedTile(tile);
390 }
391
393}
394
401static bool IsCloseToTown(TileIndex tile, uint dist)
402{
403 if (_town_kdtree.Count() == 0) return false;
404 Town *t = Town::Get(_town_kdtree.FindNearest(TileX(tile), TileY(tile)));
405 return DistanceManhattan(tile, t->xy) < dist;
406}
407
410{
411 Point pt = RemapCoords2(TileX(this->xy) * TILE_SIZE, TileY(this->xy) * TILE_SIZE);
412
413 if (this->cache.sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeTown(this->index));
414
415 SetDParam(0, this->index);
416 SetDParam(1, this->cache.population);
417 this->cache.sign.UpdatePosition(pt.x, pt.y - 24 * ZOOM_BASE,
418 _settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_POP : STR_TOWN_NAME,
419 STR_TOWN_NAME);
420
421 _viewport_sign_kdtree.Insert(ViewportSignKdtreeItem::MakeTown(this->index));
422
424}
425
428{
429 for (Town *t : Town::Iterate()) {
430 t->UpdateVirtCoord();
431 }
432}
433
436{
437 for (Town *t : Town::Iterate()) {
438 t->cached_name.clear();
439 }
440}
441
447static void ChangePopulation(Town *t, int mod)
448{
449 t->cache.population += mod;
450 if (_generating_town) [[unlikely]] return;
451
452 InvalidateWindowData(WC_TOWN_VIEW, t->index); // Cargo requirements may appear/vanish for small populations
454
455 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_POPULATION_CHANGE);
456}
457
463{
464 uint32_t pop = 0;
465 for (const Town *t : Town::Iterate()) pop += t->cache.population;
466 return pop;
467}
468
477{
478 for (StationList::iterator it = t->stations_near.begin(); it != t->stations_near.end(); /* incremented inside loop */) {
479 const Station *st = *it;
480
481 bool covers_area = st->TileIsInCatchment(tile);
482 if (flags.Any(BUILDING_2_TILES_Y)) covers_area |= st->TileIsInCatchment(tile + TileDiffXY(0, 1));
483 if (flags.Any(BUILDING_2_TILES_X)) covers_area |= st->TileIsInCatchment(tile + TileDiffXY(1, 0));
484 if (flags.Any(BUILDING_HAS_4_TILES)) covers_area |= st->TileIsInCatchment(tile + TileDiffXY(1, 1));
485
486 if (covers_area && !st->CatchmentCoversTown(t->index)) {
487 it = t->stations_near.erase(it);
488 } else {
489 ++it;
490 }
491 }
492}
493
499{
500 assert(IsTileType(tile, MP_HOUSE));
501
502 /* Progress in construction stages */
504 if (GetHouseConstructionTick(tile) != 0) return;
505
506 AnimateNewHouseConstruction(tile);
507
508 if (IsHouseCompleted(tile)) {
509 /* Now that construction is complete, we can add the population of the
510 * building to the town. */
511 ChangePopulation(Town::GetByTile(tile), HouseSpec::Get(GetHouseType(tile))->population);
512 ResetHouseAge(tile);
513 }
515}
516
522{
524 if (flags.Any(BUILDING_HAS_1_TILE)) AdvanceSingleHouseConstruction(TileAddXY(tile, 0, 0));
525 if (flags.Any(BUILDING_2_TILES_Y)) AdvanceSingleHouseConstruction(TileAddXY(tile, 0, 1));
526 if (flags.Any(BUILDING_2_TILES_X)) AdvanceSingleHouseConstruction(TileAddXY(tile, 1, 0));
527 if (flags.Any(BUILDING_HAS_4_TILES)) AdvanceSingleHouseConstruction(TileAddXY(tile, 1, 1));
528}
529
538static void TownGenerateCargo(Town *t, CargoType ct, uint amount, StationFinder &stations, bool affected_by_recession)
539{
540 if (amount == 0) return;
541
542 /* All production is halved during a recession (except for NewGRF-supplied town cargo). */
543 if (affected_by_recession && EconomyIsInRecession()) {
544 amount = (amount + 1) >> 1;
545 }
546
547 /* Scale by cargo scale setting. */
548 amount = ScaleByCargoScale(amount, true);
549
550 /* Actually generate cargo and update town statistics. */
551 t->supplied[ct].new_max += amount;
552 t->supplied[ct].new_act += MoveGoodsToStation(ct, amount, SourceType::Town, t->index, stations.GetStations());;
553}
554
562static void TownGenerateCargoOriginal(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
563{
564 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[tpe]) {
565 uint32_t r = Random();
566 if (GB(r, 0, 8) < rate) {
567 CargoType cargo_type = cs->Index();
568 uint amt = (GB(r, 0, 8) * cs->town_production_multiplier / TOWN_PRODUCTION_DIVISOR) / 8 + 1;
569
570 TownGenerateCargo(t, cargo_type, amt, stations, true);
571 }
572 }
573}
574
582static void TownGenerateCargoBinominal(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
583{
584 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[tpe]) {
585 CargoType cargo_type = cs->Index();
586 uint32_t r = Random();
587
588 /* Make a bitmask with up to 32 bits set, one for each potential pax. */
589 int genmax = (rate + 7) / 8;
590 uint32_t genmask = (genmax >= 32) ? 0xFFFFFFFF : ((1 << genmax) - 1);
591
592 /* Mask random value by potential pax and count number of actual pax. */
593 uint amt = CountBits(r & genmask) * cs->town_production_multiplier / TOWN_PRODUCTION_DIVISOR;
594
595 TownGenerateCargo(t, cargo_type, amt, stations, true);
596 }
597}
598
605static void TileLoop_Town(TileIndex tile)
606{
607 HouseID house_id = GetHouseType(tile);
608
609 /* NewHouseTileLoop returns false if Callback 21 succeeded, i.e. the house
610 * doesn't exist any more, so don't continue here. */
611 if (house_id >= NEW_HOUSE_OFFSET && !NewHouseTileLoop(tile)) return;
612
613 if (!IsHouseCompleted(tile)) {
614 /* Construction is not completed, so we advance a construction stage. */
616 return;
617 }
618
619 const HouseSpec *hs = HouseSpec::Get(house_id);
620
621 /* If the lift has a destination, it is already an animated tile. */
622 if (hs->building_flags.Test(BuildingFlag::IsAnimated) &&
623 house_id < NEW_HOUSE_OFFSET &&
624 !LiftHasDestination(tile) &&
625 Chance16(1, 2)) {
626 AddAnimatedTile(tile);
627 }
628
629 Town *t = Town::GetByTile(tile);
630 uint32_t r = Random();
631
632 StationFinder stations(TileArea(tile, 1, 1));
633
635 for (uint i = 0; i < 256; i++) {
636 uint16_t callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, r, house_id, t, tile);
637
638 if (callback == CALLBACK_FAILED || callback == CALLBACK_HOUSEPRODCARGO_END) break;
639
640 CargoType cargo = GetCargoTranslation(GB(callback, 8, 7), hs->grf_prop.grffile);
641 if (!IsValidCargoType(cargo)) continue;
642
643 uint amt = GB(callback, 0, 8);
644 if (amt == 0) continue;
645
646 /* NewGRF-supplied town cargos are not affected by recessions. */
647 TownGenerateCargo(t, cargo, amt, stations, false);
648 }
649 } else {
651 case TCGM_ORIGINAL:
652 /* Original (quadratic) cargo generation algorithm */
655 break;
656
657 case TCGM_BITCOUNT:
658 /* Binomial distribution per tick, by a series of coin flips */
659 /* Reduce generation rate to a 1/4, using tile bits to spread out distribution.
660 * As tick counter is incremented by 256 between each call, we ignore the lower 8 bits. */
661 if (GB(TimerGameTick::counter, 8, 2) == GB(tile.base(), 0, 2)) {
664 }
665 break;
666
667 default:
668 NOT_REACHED();
669 }
670 }
671
673
674 if (hs->building_flags.Any(BUILDING_HAS_1_TILE) &&
676 CanDeleteHouse(tile) &&
677 GetHouseAge(tile) >= hs->minimum_life &&
678 --t->time_until_rebuild == 0) {
679 t->time_until_rebuild = GB(r, 16, 8) + 192;
680
681 ClearTownHouse(t, tile);
682
683 /* Rebuild with another house? */
684 if (GB(r, 24, 8) >= 12) {
685 /* If we are multi-tile houses, make sure to replace the house
686 * closest to city center. If we do not do this, houses tend to
687 * wander away from roads and other houses. */
688 if (hs->building_flags.Any(BUILDING_HAS_2_TILES)) {
689 /* House tiles are always the most north tile. Move the new
690 * house to the south if we are north of the city center. */
691 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
692 int x = Clamp(grid_pos.x, 0, 1);
693 int y = Clamp(grid_pos.y, 0, 1);
694
695 if (hs->building_flags.Test(BuildingFlag::Size2x2)) {
696 tile = TileAddXY(tile, x, y);
697 } else if (hs->building_flags.Test(BuildingFlag::Size1x2)) {
698 tile = TileAddXY(tile, 0, y);
699 } else if (hs->building_flags.Test(BuildingFlag::Size2x1)) {
700 tile = TileAddXY(tile, x, 0);
701 }
702 }
703
704 TryBuildTownHouse(t, tile);
705 }
706 }
707
708 cur_company.Restore();
709}
710
718{
719 if (flags & DC_AUTO) return CommandCost(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
720 if (!CanDeleteHouse(tile)) return CMD_ERROR;
721
722 const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
723
725 cost.AddCost(hs->GetRemovalCost());
726
727 int rating = hs->remove_rating_decrease;
728 Town *t = Town::GetByTile(tile);
729
732 /* NewGRFs can add indestructible houses. */
733 if (rating > RATING_MAXIMUM) {
734 SetDParam(0, t->index);
735 return CommandCost(CMD_ERROR);
736 }
737 /* If town authority controls removal, check the company's rating. */
738 if (rating > t->ratings[_current_company] && _settings_game.difficulty.town_council_tolerance != TOWN_COUNCIL_PERMISSIVE) {
739 SetDParam(0, t->index);
740 return CommandCost(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS);
741 }
742 }
743 }
744
745 ChangeTownRating(t, -rating, RATING_HOUSE_MINIMUM, flags);
746 if (flags & DC_EXEC) {
747 ClearTownHouse(t, tile);
748 }
749
750 return cost;
751}
752
753static void AddProducedCargo_Town(TileIndex tile, CargoArray &produced)
754{
755 HouseID house_id = GetHouseType(tile);
756 const HouseSpec *hs = HouseSpec::Get(house_id);
757 Town *t = Town::GetByTile(tile);
758
760 for (uint i = 0; i < 256; i++) {
761 uint16_t callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, 0, house_id, t, tile);
762
763 if (callback == CALLBACK_FAILED || callback == CALLBACK_HOUSEPRODCARGO_END) break;
764
765 CargoType cargo = GetCargoTranslation(GB(callback, 8, 7), hs->grf_prop.grffile);
766
767 if (!IsValidCargoType(cargo)) continue;
768 produced[cargo]++;
769 }
770 } else {
771 if (hs->population > 0) {
772 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_PASSENGERS]) {
773 produced[cs->Index()]++;
774 }
775 }
776 if (hs->mail_generation > 0) {
777 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_MAIL]) {
778 produced[cs->Index()]++;
779 }
780 }
781 }
782}
783
791static void AddAcceptedCargoSetMask(CargoType cargo, uint amount, CargoArray &acceptance, CargoTypes &always_accepted)
792{
793 if (!IsValidCargoType(cargo) || amount == 0) return;
794 acceptance[cargo] += amount;
795 SetBit(always_accepted, cargo);
796}
797
807void AddAcceptedCargoOfHouse(TileIndex tile, HouseID house, const HouseSpec *hs, Town *t, CargoArray &acceptance, CargoTypes &always_accepted)
808{
809 CargoType accepts[lengthof(hs->accepts_cargo)];
810
811 /* Set the initial accepted cargo types */
812 for (uint8_t i = 0; i < lengthof(accepts); i++) {
813 accepts[i] = hs->accepts_cargo[i];
814 }
815
816 /* Check for custom accepted cargo types */
818 uint16_t callback = GetHouseCallback(CBID_HOUSE_ACCEPT_CARGO, 0, 0, house, t, tile, tile == INVALID_TILE);
819 if (callback != CALLBACK_FAILED) {
820 /* Replace accepted cargo types with translated values from callback */
821 accepts[0] = GetCargoTranslation(GB(callback, 0, 5), hs->grf_prop.grffile);
822 accepts[1] = GetCargoTranslation(GB(callback, 5, 5), hs->grf_prop.grffile);
823 accepts[2] = GetCargoTranslation(GB(callback, 10, 5), hs->grf_prop.grffile);
824 }
825 }
826
827 /* Check for custom cargo acceptance */
829 uint16_t callback = GetHouseCallback(CBID_HOUSE_CARGO_ACCEPTANCE, 0, 0, house, t, tile, tile == INVALID_TILE);
830 if (callback != CALLBACK_FAILED) {
831 AddAcceptedCargoSetMask(accepts[0], GB(callback, 0, 4), acceptance, always_accepted);
832 AddAcceptedCargoSetMask(accepts[1], GB(callback, 4, 4), acceptance, always_accepted);
833 if (_settings_game.game_creation.landscape != LandscapeType::Temperate && HasBit(callback, 12)) {
834 /* The 'S' bit indicates food instead of goods */
835 AddAcceptedCargoSetMask(GetCargoTypeByLabel(CT_FOOD), GB(callback, 8, 4), acceptance, always_accepted);
836 } else {
837 AddAcceptedCargoSetMask(accepts[2], GB(callback, 8, 4), acceptance, always_accepted);
838 }
839 return;
840 }
841 }
842
843 /* No custom acceptance, so fill in with the default values */
844 for (uint8_t i = 0; i < lengthof(accepts); i++) {
845 AddAcceptedCargoSetMask(accepts[i], hs->cargo_acceptance[i], acceptance, always_accepted);
846 }
847}
848
849static void AddAcceptedCargo_Town(TileIndex tile, CargoArray &acceptance, CargoTypes &always_accepted)
850{
851 HouseID house = GetHouseType(tile);
852 AddAcceptedCargoOfHouse(tile, house, HouseSpec::Get(house), Town::GetByTile(tile), acceptance, always_accepted);
853}
854
861{
862 CargoTypes always_accepted;
863 CargoArray acceptance{};
864 AddAcceptedCargoOfHouse(INVALID_TILE, hs->Index(), hs, nullptr, acceptance, always_accepted);
865 return acceptance;
866}
867
868static void GetTileDesc_Town(TileIndex tile, TileDesc *td)
869{
870 const HouseID house = GetHouseType(tile);
871 const HouseSpec *hs = HouseSpec::Get(house);
872 bool house_completed = IsHouseCompleted(tile);
873
874 td->str = hs->building_name;
875
876 uint16_t callback_res = GetHouseCallback(CBID_HOUSE_CUSTOM_NAME, house_completed ? 1 : 0, 0, house, Town::GetByTile(tile), tile);
877 if (callback_res != CALLBACK_FAILED && callback_res != 0x400) {
878 if (callback_res > 0x400) {
880 } else {
881 StringID new_name = GetGRFStringID(hs->grf_prop.grfid, GRFSTR_MISC_GRF_TEXT + callback_res);
882 if (new_name != STR_NULL && new_name != STR_UNDEFINED) {
883 td->str = new_name;
884 }
885 }
886 }
887
888 if (!house_completed) {
889 td->dparam = td->str;
890 td->str = STR_LAI_TOWN_INDUSTRY_DESCRIPTION_UNDER_CONSTRUCTION;
891 }
892
893 if (hs->grf_prop.HasGrfFile()) {
894 const GRFConfig *gc = GetGRFConfig(hs->grf_prop.grfid);
895 td->grf = gc->GetName();
896 }
897
898 td->owner[0] = OWNER_TOWN;
899}
900
901static TrackStatus GetTileTrackStatus_Town(TileIndex, TransportType, uint, DiagDirection)
902{
903 /* not used */
904 return 0;
905}
906
907static void ChangeTileOwner_Town(TileIndex, Owner, Owner)
908{
909 /* not used */
910}
911
912static bool GrowTown(Town *t);
913
918static void TownTickHandler(Town *t)
919{
920 if (HasBit(t->flags, TOWN_IS_GROWING)) {
921 int i = (int)t->grow_counter - 1;
922 if (i < 0) {
923 if (GrowTown(t)) {
924 i = t->growth_rate;
925 } else {
926 /* If growth failed wait a bit before retrying */
927 i = std::min<uint16_t>(t->growth_rate, Ticks::TOWN_GROWTH_TICKS - 1);
928 }
929 }
930 t->grow_counter = i;
931 }
932}
933
936{
937 if (_game_mode == GM_EDITOR) return;
938
939 for (Town *t : Town::Iterate()) {
941 }
942}
943
950{
951 if (IsRoadDepotTile(tile) || IsBayRoadStopTile(tile)) return ROAD_NONE;
952
953 return GetAnyRoadBits(tile, RTT_ROAD, true);
954}
955
961{
962 RoadType best_rt = ROADTYPE_ROAD;
963 const RoadTypeInfo *best = nullptr;
964 const uint16_t assume_max_speed = 50;
965
966 for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
967 if (RoadTypeIsTram(rt)) continue;
968
969 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
970
971 /* Unused road type. */
972 if (rti->label == 0) continue;
973
974 /* Can town build this road. */
975 if (!rti->flags.Test(RoadTypeFlag::TownBuild)) continue;
976
977 /* Not yet introduced at this date. */
979
980 if (best != nullptr) {
981 if ((rti->max_speed == 0 ? assume_max_speed : rti->max_speed) < (best->max_speed == 0 ? assume_max_speed : best->max_speed)) continue;
982 }
983
984 best_rt = rt;
985 best = rti;
986 }
987
988 return best_rt;
989}
990
995static TimerGameCalendar::Date GetTownRoadTypeFirstIntroductionDate()
996{
997 const RoadTypeInfo *best = nullptr;
998 for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
999 if (RoadTypeIsTram(rt)) continue;
1000 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
1001 if (rti->label == 0) continue; // Unused road type.
1002 if (!rti->flags.Test(RoadTypeFlag::TownBuild)) continue; // Town can't build this road type.
1003
1004 if (best != nullptr && rti->introduction_date >= best->introduction_date) continue;
1005 best = rti;
1006 }
1007
1008 if (best == nullptr) return TimerGameCalendar::Date(INT32_MAX);
1009 return best->introduction_date;
1010}
1011
1017{
1018 auto min_date = GetTownRoadTypeFirstIntroductionDate();
1019 if (min_date <= TimerGameCalendar::date) return true;
1020
1021 if (min_date < INT32_MAX) {
1022 SetDParam(0, min_date);
1023 ShowErrorMessage(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_YET, STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_YET_EXPLANATION, WL_CRITICAL);
1024 } else {
1025 ShowErrorMessage(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_AT_ALL, STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_AT_ALL_EXPLANATION, WL_CRITICAL);
1026 }
1027 return false;
1028}
1029
1040static bool IsNeighborRoadTile(TileIndex tile, const DiagDirection dir, uint dist_multi)
1041{
1042 if (!IsValidTile(tile)) return false;
1043
1044 /* Lookup table for the used diff values */
1045 const TileIndexDiff tid_lt[3] = {
1049 };
1050
1051 dist_multi = (dist_multi + 1) * 4;
1052 for (uint pos = 4; pos < dist_multi; pos++) {
1053 /* Go (pos / 4) tiles to the left or the right */
1054 TileIndexDiff cur = tid_lt[(pos & 1) ? 0 : 1] * (pos / 4);
1055
1056 /* Use the current tile as origin, or go one tile backwards */
1057 if (pos & 2) cur += tid_lt[2];
1058
1059 /* Test for roadbit parallel to dir and facing towards the middle axis */
1060 if (IsValidTile(tile + cur) &&
1061 GetTownRoadBits(TileAdd(tile, cur)) & DiagDirToRoadBits((pos & 2) ? dir : ReverseDiagDir(dir))) return true;
1062 }
1063 return false;
1064}
1065
1075{
1076 if (DistanceFromEdge(tile) == 0) return false;
1077
1078 /* Prevent towns from building roads under bridges along the bridge. Looks silly. */
1079 if (IsBridgeAbove(tile) && GetBridgeAxis(tile) == DiagDirToAxis(dir)) return false;
1080
1081 /* Check if there already is a road at this point? */
1082 if (GetTownRoadBits(tile) == ROAD_NONE) {
1083 /* No, try if we are able to build a road piece there.
1084 * If that fails clear the land, and if that fails exit.
1085 * This is to make sure that we can build a road here later. */
1087 if (Command<CMD_BUILD_ROAD>::Do(DC_AUTO | DC_NO_WATER, tile, (dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? ROAD_Y : ROAD_X, rt, DRD_NONE, t->index).Failed() &&
1089 return false;
1090 }
1091 }
1092
1093 Slope cur_slope = _settings_game.construction.build_on_slopes ? std::get<0>(GetFoundationSlope(tile)) : GetTileSlope(tile);
1094 bool ret = !IsNeighborRoadTile(tile, dir, t->layout == TL_ORIGINAL ? 1 : 2);
1095 if (cur_slope == SLOPE_FLAT) return ret;
1096
1097 /* If the tile is not a slope in the right direction, then
1098 * maybe terraform some. */
1099 Slope desired_slope = (dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? SLOPE_NW : SLOPE_NE;
1100 if (desired_slope != cur_slope && ComplementSlope(desired_slope) != cur_slope) {
1101 if (Chance16(1, 8)) {
1102 CommandCost res = CMD_ERROR;
1103 if (!_generating_world && Chance16(1, 10)) {
1104 /* Note: Do not replace "^ SLOPE_ELEVATED" with ComplementSlope(). The slope might be steep. */
1106 tile, Chance16(1, 16) ? cur_slope : cur_slope ^ SLOPE_ELEVATED, false));
1107 }
1108 if (res.Failed() && Chance16(1, 3)) {
1109 /* We can consider building on the slope, though. */
1110 return ret;
1111 }
1112 }
1113 return false;
1114 }
1115 return ret;
1116}
1117
1118static bool TerraformTownTile(TileIndex tile, Slope edges, bool dir)
1119{
1120 assert(tile < Map::Size());
1121
1122 CommandCost r = std::get<0>(Command<CMD_TERRAFORM_LAND>::Do(DC_AUTO | DC_NO_WATER, tile, edges, dir));
1123 if (r.Failed() || r.GetCost() >= (_price[PR_TERRAFORM] + 2) * 8) return false;
1125 return true;
1126}
1127
1128static void LevelTownLand(TileIndex tile)
1129{
1130 assert(tile < Map::Size());
1131
1132 /* Don't terraform if land is plain or if there's a house there. */
1133 if (IsTileType(tile, MP_HOUSE)) return;
1134 Slope tileh = GetTileSlope(tile);
1135 if (tileh == SLOPE_FLAT) return;
1136
1137 /* First try up, then down */
1138 if (!TerraformTownTile(tile, ~tileh & SLOPE_ELEVATED, true)) {
1139 TerraformTownTile(tile, tileh & SLOPE_ELEVATED, false);
1140 }
1141}
1142
1152{
1153 /* align the grid to the downtown */
1154 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile); // Vector from downtown to the tile
1155 RoadBits rcmd = ROAD_NONE;
1156
1157 switch (t->layout) {
1158 default: NOT_REACHED();
1159
1160 case TL_2X2_GRID:
1161 if ((grid_pos.x % 3) == 0) rcmd |= ROAD_Y;
1162 if ((grid_pos.y % 3) == 0) rcmd |= ROAD_X;
1163 break;
1164
1165 case TL_3X3_GRID:
1166 if ((grid_pos.x % 4) == 0) rcmd |= ROAD_Y;
1167 if ((grid_pos.y % 4) == 0) rcmd |= ROAD_X;
1168 break;
1169 }
1170
1171 /* Optimise only X-junctions */
1172 if (rcmd != ROAD_ALL) return rcmd;
1173
1174 RoadBits rb_template;
1175
1176 switch (GetTileSlope(tile)) {
1177 default: rb_template = ROAD_ALL; break;
1178 case SLOPE_W: rb_template = ROAD_NW | ROAD_SW; break;
1179 case SLOPE_SW: rb_template = ROAD_Y | ROAD_SW; break;
1180 case SLOPE_S: rb_template = ROAD_SW | ROAD_SE; break;
1181 case SLOPE_SE: rb_template = ROAD_X | ROAD_SE; break;
1182 case SLOPE_E: rb_template = ROAD_SE | ROAD_NE; break;
1183 case SLOPE_NE: rb_template = ROAD_Y | ROAD_NE; break;
1184 case SLOPE_N: rb_template = ROAD_NE | ROAD_NW; break;
1185 case SLOPE_NW: rb_template = ROAD_X | ROAD_NW; break;
1186 case SLOPE_STEEP_W:
1187 case SLOPE_STEEP_S:
1188 case SLOPE_STEEP_E:
1189 case SLOPE_STEEP_N:
1190 rb_template = ROAD_NONE;
1191 break;
1192 }
1193
1194 /* Stop if the template is compatible to the growth dir */
1195 if (DiagDirToRoadBits(ReverseDiagDir(dir)) & rb_template) return rb_template;
1196 /* If not generate a straight road in the direction of the growth */
1198}
1199
1211{
1212 /* We can't look further than that. */
1213 if (DistanceFromEdge(tile) == 0) return false;
1214
1215 uint counter = 0; // counts the house neighbor tiles
1216
1217 /* Check the tiles E,N,W and S of the current tile for houses */
1218 for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
1219 /* Count both void and house tiles for checking whether there
1220 * are enough houses in the area. This to make it likely that
1221 * houses get build up to the edge of the map. */
1222 switch (GetTileType(TileAddByDiagDir(tile, dir))) {
1223 case MP_HOUSE:
1224 case MP_VOID:
1225 counter++;
1226 break;
1227
1228 default:
1229 break;
1230 }
1231
1232 /* If there are enough neighbors stop here */
1233 if (counter >= 3) {
1234 if (TryBuildTownHouse(t, tile)) {
1235 _grow_town_result = GROWTH_SUCCEED;
1236 return true;
1237 }
1238 return false;
1239 }
1240 }
1241 return false;
1242}
1243
1252static bool GrowTownWithRoad(const Town *t, TileIndex tile, RoadBits rcmd)
1253{
1255 if (Command<CMD_BUILD_ROAD>::Do(DC_EXEC | DC_AUTO | DC_NO_WATER, tile, rcmd, rt, DRD_NONE, t->index).Succeeded()) {
1256 _grow_town_result = GROWTH_SUCCEED;
1257 return true;
1258 }
1259 return false;
1260}
1261
1271static bool CanRoadContinueIntoNextTile(const Town *t, const TileIndex tile, const DiagDirection road_dir)
1272{
1273 const TileIndexDiff delta = TileOffsByDiagDir(road_dir); // +1 tile in the direction of the road
1274 TileIndex next_tile = tile + delta; // The tile beyond which must be connectable to the target tile
1275 RoadBits rcmd = DiagDirToRoadBits(ReverseDiagDir(road_dir));
1277
1278 /* Before we try anything, make sure the tile is on the map and not the void. */
1279 if (!IsValidTile(next_tile)) return false;
1280
1281 /* If the next tile is a bridge or tunnel, allow if it's continuing in the same direction. */
1282 if (IsTileType(next_tile, MP_TUNNELBRIDGE)) {
1283 return GetTunnelBridgeTransportType(next_tile) == TRANSPORT_ROAD && GetTunnelBridgeDirection(next_tile) == road_dir;
1284 }
1285
1286 /* If the next tile is a station, allow if it's a road station facing the proper direction. Otherwise return false. */
1287 if (IsTileType(next_tile, MP_STATION)) {
1288 /* If the next tile is a road station, allow if it can be entered by the new tunnel/bridge, otherwise disallow. */
1289 if (IsDriveThroughStopTile(next_tile)) return GetDriveThroughStopAxis(next_tile) == DiagDirToAxis(road_dir);
1290 if (IsBayRoadStopTile(next_tile)) return GetBayRoadStopDir(next_tile) == ReverseDiagDir(road_dir);
1291 return false;
1292 }
1293
1294 /* If the next tile is a road depot, allow if it's facing the right way. */
1295 if (IsTileType(next_tile, MP_ROAD)) {
1296 return IsRoadDepot(next_tile) && GetRoadDepotDirection(next_tile) == ReverseDiagDir(road_dir);
1297 }
1298
1299 /* If the next tile is a railroad track, check if towns are allowed to build level crossings.
1300 * If level crossing are not allowed, reject the construction. Else allow DoCommand to determine if the rail track is buildable. */
1301 if (IsTileType(next_tile, MP_RAILWAY) && !_settings_game.economy.allow_town_level_crossings) return false;
1302
1303 /* If a road tile can be built, the construction is allowed. */
1304 return Command<CMD_BUILD_ROAD>::Do(DC_AUTO | DC_NO_WATER, next_tile, rcmd, rt, DRD_NONE, t->index).Succeeded();
1305}
1306
1313static bool RedundantBridgeExistsNearby(TileIndex tile, void *user_data)
1314{
1315 /* Don't look into the void. */
1316 if (!IsValidTile(tile)) return false;
1317
1318 /* Only consider bridge head tiles. */
1319 if (!IsBridgeTile(tile)) return false;
1320
1321 /* Only consider road bridges. */
1322 if (GetTunnelBridgeTransportType(tile) != TRANSPORT_ROAD) return false;
1323
1324 /* If the bridge is facing the same direction as the proposed bridge, we've found a redundant bridge. */
1325 return (GetTileSlope(tile) & InclinedSlope(ReverseDiagDir(*(DiagDirection *)user_data)));
1326}
1327
1338static bool GrowTownWithBridge(const Town *t, const TileIndex tile, const DiagDirection bridge_dir)
1339{
1340 assert(bridge_dir < DIAGDIR_END);
1341
1342 const Slope slope = GetTileSlope(tile);
1343
1344 /* Make sure the direction is compatible with the slope.
1345 * Well we check if the slope has an up bit set in the
1346 * reverse direction. */
1347 if (slope != SLOPE_FLAT && slope & InclinedSlope(bridge_dir)) return false;
1348
1349 /* Assure that the bridge is connectable to the start side */
1350 if (!(GetTownRoadBits(TileAddByDiagDir(tile, ReverseDiagDir(bridge_dir))) & DiagDirToRoadBits(bridge_dir))) return false;
1351
1352 /* We are in the right direction */
1353 uint bridge_length = 0; // This value stores the length of the possible bridge
1354 TileIndex bridge_tile = tile; // Used to store the other waterside
1355
1356 const TileIndexDiff delta = TileOffsByDiagDir(bridge_dir);
1357
1358 /* To prevent really small towns from building disproportionately
1359 * long bridges, make the max a function of its population. */
1360 const uint TOWN_BRIDGE_LENGTH_CAP = 11;
1361 uint base_bridge_length = 5;
1362 uint max_bridge_length = std::min(t->cache.population / 1000 + base_bridge_length, TOWN_BRIDGE_LENGTH_CAP);
1363
1364 if (slope == SLOPE_FLAT) {
1365 /* Bridges starting on flat tiles are only allowed when crossing rivers, rails or one-way roads. */
1366 do {
1367 if (bridge_length++ >= base_bridge_length) {
1368 /* Allow to cross rivers, not big lakes, nor large amounts of rails or one-way roads. */
1369 return false;
1370 }
1371 bridge_tile += delta;
1372 } while (IsValidTile(bridge_tile) && ((IsWaterTile(bridge_tile) && !IsSea(bridge_tile)) || IsPlainRailTile(bridge_tile) || (IsNormalRoadTile(bridge_tile) && GetDisallowedRoadDirections(bridge_tile) != DRD_NONE)));
1373 } else {
1374 do {
1375 if (bridge_length++ >= max_bridge_length) {
1376 /* Ensure the bridge is not longer than the max allowed length. */
1377 return false;
1378 }
1379 bridge_tile += delta;
1380 } while (IsValidTile(bridge_tile) && (IsWaterTile(bridge_tile) || IsPlainRailTile(bridge_tile) || (IsNormalRoadTile(bridge_tile) && GetDisallowedRoadDirections(bridge_tile) != DRD_NONE)));
1381 }
1382
1383 /* Don't allow a bridge where the start and end tiles are adjacent with no span between. */
1384 if (bridge_length == 1) return false;
1385
1386 /* Make sure the road can be continued past the bridge. At this point, bridge_tile holds the end tile of the bridge. */
1387 if (!CanRoadContinueIntoNextTile(t, bridge_tile, bridge_dir)) return false;
1388
1389 /* If another parallel bridge exists nearby, this one would be redundant and shouldn't be built. We don't care about flat bridges. */
1390 TileIndex search = tile;
1391 DiagDirection direction_to_match = bridge_dir;
1392 if (slope != SLOPE_FLAT && CircularTileSearch(&search, bridge_length, 0, 0, RedundantBridgeExistsNearby, &direction_to_match)) return false;
1393
1394 for (uint8_t times = 0; times <= 22; times++) {
1395 uint8_t bridge_type = RandomRange(MAX_BRIDGES - 1);
1396
1397 /* Can we actually build the bridge? */
1399 if (Command<CMD_BUILD_BRIDGE>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_BRIDGE>()), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, rt).Succeeded()) {
1400 Command<CMD_BUILD_BRIDGE>::Do(DC_EXEC | CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_BRIDGE>()), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, rt);
1401 _grow_town_result = GROWTH_SUCCEED;
1402 return true;
1403 }
1404 }
1405 /* Quit if it selecting an appropriate bridge type fails a large number of times. */
1406 return false;
1407}
1408
1419static bool GrowTownWithTunnel(const Town *t, const TileIndex tile, const DiagDirection tunnel_dir)
1420{
1421 assert(tunnel_dir < DIAGDIR_END);
1422
1423 Slope slope = GetTileSlope(tile);
1424
1425 /* Only consider building a tunnel if the starting tile is sloped properly. */
1426 if (slope != InclinedSlope(tunnel_dir)) return false;
1427
1428 /* Assure that the tunnel is connectable to the start side */
1429 if (!(GetTownRoadBits(TileAddByDiagDir(tile, ReverseDiagDir(tunnel_dir))) & DiagDirToRoadBits(tunnel_dir))) return false;
1430
1431 const TileIndexDiff delta = TileOffsByDiagDir(tunnel_dir);
1432 int max_tunnel_length = 0;
1433
1434 /* There are two conditions for building tunnels: Under a mountain and under an obstruction. */
1435 if (CanRoadContinueIntoNextTile(t, tile, tunnel_dir)) {
1436 /* 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. */
1437 TileIndex slope_tile = tile;
1438 for (uint8_t tiles = 0; tiles < 4; tiles++) {
1439 if (!IsValidTile(slope_tile)) return false;
1440 slope = GetTileSlope(slope_tile);
1441 if (slope != InclinedSlope(tunnel_dir) && !IsSteepSlope(slope) && !IsSlopeWithOneCornerRaised(slope)) return false;
1442 slope_tile += delta;
1443 }
1444
1445 /* More population means longer tunnels, but make sure we can at least cover the smallest mountain which neccesitates tunneling. */
1446 max_tunnel_length = (t->cache.population / 1000) + 7;
1447 } else {
1448 /* When tunneling under an obstruction, the length limit is 5, enough to tunnel under a four-track railway. */
1449 max_tunnel_length = 5;
1450 }
1451
1452 uint8_t tunnel_length = 0;
1453 TileIndex tunnel_tile = tile; // Iteratator to store the other end tile of the tunnel.
1454
1455 /* Find the end tile of the tunnel for length and continuation checks. */
1456 do {
1457 if (tunnel_length++ >= max_tunnel_length) return false;
1458 tunnel_tile += delta;
1459 /* The tunnel ends when start and end tiles are the same height. */
1460 } while (IsValidTile(tunnel_tile) && GetTileZ(tile) != GetTileZ(tunnel_tile));
1461
1462 /* Don't allow a tunnel where the start and end tiles are adjacent. */
1463 if (tunnel_length == 1) return false;
1464
1465 /* Make sure the road can be continued past the tunnel. At this point, tunnel_tile holds the end tile of the tunnel. */
1466 if (!CanRoadContinueIntoNextTile(t, tunnel_tile, tunnel_dir)) return false;
1467
1468 /* Attempt to build the tunnel. Return false if it fails to let the town build a road instead. */
1470 if (Command<CMD_BUILD_TUNNEL>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_TUNNEL>()), tile, TRANSPORT_ROAD, rt).Succeeded()) {
1471 Command<CMD_BUILD_TUNNEL>::Do(DC_EXEC | CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_TUNNEL>()), tile, TRANSPORT_ROAD, rt);
1472 _grow_town_result = GROWTH_SUCCEED;
1473 return true;
1474 }
1475
1476 return false;
1477}
1478
1486{
1487 static const TileIndexDiffC tiles[] = { {-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1} };
1488 bool allow = false;
1489
1490 for (const auto &ptr : tiles) {
1491 TileIndex cur_tile = t + ToTileIndexDiff(ptr);
1492 if (!IsValidTile(cur_tile)) continue;
1493
1494 if (!(IsTileType(cur_tile, MP_ROAD) || IsAnyRoadStopTile(cur_tile))) continue;
1495 allow = true;
1496
1497 RoadType road_rt = GetRoadTypeRoad(cur_tile);
1498 RoadType tram_rt = GetRoadTypeTram(cur_tile);
1499 if (road_rt != INVALID_ROADTYPE && !GetRoadTypeInfo(road_rt)->flags.Test(RoadTypeFlag::NoHouses)) return true;
1500 if (tram_rt != INVALID_ROADTYPE && !GetRoadTypeInfo(tram_rt)->flags.Test(RoadTypeFlag::NoHouses)) return true;
1501 }
1502
1503 /* If no road was found surrounding the tile we can allow building the house since there is
1504 * nothing which forbids it, if a road was found but the execution reached this point, then
1505 * all the found roads don't allow houses to be built */
1506 return !allow;
1507}
1508
1514{
1515 if (!IsTileType(tile, MP_ROAD)) return true;
1516
1517 /* Allow extending on roadtypes which can be built by town, or if the road type matches the type the town will build. */
1518 RoadType rt = GetRoadTypeRoad(tile);
1520}
1521
1526static inline bool TownAllowedToBuildRoads()
1527{
1528 return _settings_game.economy.allow_town_roads || _generating_world || _game_mode == GM_EDITOR;
1529}
1530
1548static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection target_dir, Town *t1)
1549{
1550 RoadBits rcmd = ROAD_NONE; // RoadBits for the road construction command
1551 TileIndex tile = *tile_ptr; // The main tile on which we base our growth
1552
1553 assert(tile < Map::Size());
1554
1555 if (cur_rb == ROAD_NONE) {
1556 /* Tile has no road. First reset the status counter
1557 * to say that this is the last iteration. */
1558 _grow_town_result = GROWTH_SEARCH_STOPPED;
1559
1560 if (!TownAllowedToBuildRoads()) return;
1562
1563 /* Remove hills etc */
1564 if (!_settings_game.construction.build_on_slopes || Chance16(1, 6)) LevelTownLand(tile);
1565
1566 /* Is a road allowed here? */
1567 switch (t1->layout) {
1568 default: NOT_REACHED();
1569
1570 case TL_3X3_GRID:
1571 case TL_2X2_GRID:
1572 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1573 if (rcmd == ROAD_NONE) return;
1574 break;
1575
1576 case TL_BETTER_ROADS:
1577 case TL_ORIGINAL:
1578 if (!IsRoadAllowedHere(t1, tile, target_dir)) return;
1579
1580 DiagDirection source_dir = ReverseDiagDir(target_dir);
1581
1582 if (Chance16(1, 4)) {
1583 /* Randomize a new target dir */
1584 do target_dir = RandomDiagDir(); while (target_dir == source_dir);
1585 }
1586
1587 if (!IsRoadAllowedHere(t1, TileAddByDiagDir(tile, target_dir), target_dir)) {
1588 /* A road is not allowed to continue the randomized road,
1589 * return if the road we're trying to build is curved. */
1590 if (target_dir != ReverseDiagDir(source_dir)) return;
1591
1592 /* Return if neither side of the new road is a house */
1595 return;
1596 }
1597
1598 /* That means that the road is only allowed if there is a house
1599 * at any side of the new road. */
1600 }
1601
1602 rcmd = DiagDirToRoadBits(target_dir) | DiagDirToRoadBits(source_dir);
1603 break;
1604 }
1605
1606 } else if (target_dir < DIAGDIR_END && !(cur_rb & DiagDirToRoadBits(ReverseDiagDir(target_dir)))) {
1607 if (!TownCanGrowRoad(tile)) return;
1608
1609 /* Continue building on a partial road.
1610 * Should be always OK, so we only generate
1611 * the fitting RoadBits */
1612 _grow_town_result = GROWTH_SEARCH_STOPPED;
1613
1614 if (!TownAllowedToBuildRoads()) return;
1615
1616 switch (t1->layout) {
1617 default: NOT_REACHED();
1618
1619 case TL_3X3_GRID:
1620 case TL_2X2_GRID:
1621 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1622 break;
1623
1624 case TL_BETTER_ROADS:
1625 case TL_ORIGINAL:
1626 rcmd = DiagDirToRoadBits(ReverseDiagDir(target_dir));
1627 break;
1628 }
1629 } else {
1630 bool allow_house = true; // Value which decides if we want to construct a house
1631
1632 /* Reached a tunnel/bridge? Then continue at the other side of it, unless
1633 * it is the starting tile. Half the time, we stay on this side then.*/
1634 if (IsTileType(tile, MP_TUNNELBRIDGE)) {
1635 if (GetTunnelBridgeTransportType(tile) == TRANSPORT_ROAD && (target_dir != DIAGDIR_END || Chance16(1, 2))) {
1636 *tile_ptr = GetOtherTunnelBridgeEnd(tile);
1637 }
1638 return;
1639 }
1640
1641 /* Possibly extend the road in a direction.
1642 * Randomize a direction and if it has a road, bail out. */
1643 target_dir = RandomDiagDir();
1644 RoadBits target_rb = DiagDirToRoadBits(target_dir);
1645 TileIndex house_tile; // position of a possible house
1646
1647 if (cur_rb & target_rb) {
1648 /* If it's a road turn possibly build a house in a corner.
1649 * Use intersection with straight road as an indicator
1650 * that we randomed corner house position.
1651 * A turn (and we check for that later) always has only
1652 * one common bit with a straight road so it has the same
1653 * chance to be chosen as the house on the side of a road.
1654 */
1655 if ((cur_rb & ROAD_X) != target_rb) return;
1656
1657 /* Check whether it is a turn and if so determine
1658 * position of the corner tile */
1659 switch (cur_rb) {
1660 case ROAD_N:
1661 house_tile = TileAddByDir(tile, DIR_S);
1662 break;
1663 case ROAD_S:
1664 house_tile = TileAddByDir(tile, DIR_N);
1665 break;
1666 case ROAD_E:
1667 house_tile = TileAddByDir(tile, DIR_W);
1668 break;
1669 case ROAD_W:
1670 house_tile = TileAddByDir(tile, DIR_E);
1671 break;
1672 default:
1673 return; // not a turn
1674 }
1675 target_dir = DIAGDIR_END;
1676 } else {
1677 house_tile = TileAddByDiagDir(tile, target_dir);
1678 }
1679
1680 /* Don't walk into water. */
1681 if (HasTileWaterGround(house_tile)) return;
1682
1683 if (!IsValidTile(house_tile)) return;
1684
1685 if (target_dir != DIAGDIR_END && TownAllowedToBuildRoads()) {
1686 switch (t1->layout) {
1687 default: NOT_REACHED();
1688
1689 case TL_3X3_GRID: // Use 2x2 grid afterwards!
1690 GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir));
1691 [[fallthrough]];
1692
1693 case TL_2X2_GRID:
1694 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1695 allow_house = (rcmd & target_rb) == ROAD_NONE;
1696 break;
1697
1698 case TL_BETTER_ROADS: // Use original afterwards!
1699 GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir));
1700 [[fallthrough]];
1701
1702 case TL_ORIGINAL:
1703 /* Allow a house at the edge. 60% chance or
1704 * always ok if no road allowed. */
1705 rcmd = target_rb;
1706 allow_house = (!IsRoadAllowedHere(t1, house_tile, target_dir) || Chance16(6, 10));
1707 break;
1708 }
1709 }
1710
1711 allow_house &= RoadTypesAllowHouseHere(house_tile);
1712
1713 if (allow_house) {
1714 /* Build a house, but not if there already is a house there. */
1715 if (!IsTileType(house_tile, MP_HOUSE)) {
1716 /* Level the land if possible */
1717 if (Chance16(1, 6)) LevelTownLand(house_tile);
1718
1719 /* And build a house.
1720 * Set result to -1 if we managed to build it. */
1721 if (TryBuildTownHouse(t1, house_tile)) {
1722 _grow_town_result = GROWTH_SUCCEED;
1723 }
1724 }
1725 return;
1726 }
1727
1728 if (!TownCanGrowRoad(tile)) return;
1729
1730 _grow_town_result = GROWTH_SEARCH_STOPPED;
1731 }
1732
1733 /* Return if a water tile */
1734 if (HasTileWaterGround(tile)) return;
1735
1736 /* Make the roads look nicer */
1737 rcmd = CleanUpRoadBits(tile, rcmd);
1738 if (rcmd == ROAD_NONE) return;
1739
1740 /* Only use the target direction for bridges and tunnels to ensure they're connected.
1741 * The target_dir is as computed previously according to town layout, so
1742 * it will match it perfectly. */
1743 if (GrowTownWithBridge(t1, tile, target_dir)) return;
1744 if (GrowTownWithTunnel(t1, tile, target_dir)) return;
1745
1746 GrowTownWithRoad(t1, tile, rcmd);
1747}
1748
1757{
1758 TileIndex target_tile = tile + TileOffsByDiagDir(dir);
1759 if (!IsValidTile(target_tile)) return false;
1760 if (HasTileWaterGround(target_tile)) return false;
1761
1762 RoadBits target_rb = GetTownRoadBits(target_tile);
1764 /* Check whether a road connection exists or can be build. */
1765 switch (GetTileType(target_tile)) {
1766 case MP_ROAD:
1767 return target_rb != ROAD_NONE;
1768
1769 case MP_STATION:
1770 return IsDriveThroughStopTile(target_tile);
1771
1772 case MP_TUNNELBRIDGE:
1773 return GetTunnelBridgeTransportType(target_tile) == TRANSPORT_ROAD;
1774
1775 case MP_HOUSE:
1776 case MP_INDUSTRY:
1777 case MP_OBJECT:
1778 return false;
1779
1780 default:
1781 /* Checked for void and water earlier */
1782 return true;
1783 }
1784 } else {
1785 /* Check whether a road connection already exists,
1786 * and it leads somewhere else. */
1788 return (target_rb & back_rb) != 0 && (target_rb & ~back_rb) != 0;
1789 }
1790}
1791
1798static bool GrowTownAtRoad(Town *t, TileIndex tile)
1799{
1800 /* Special case.
1801 * @see GrowTownInTile Check the else if
1802 */
1803 DiagDirection target_dir = DIAGDIR_END; // The direction in which we want to extend the town
1804
1805 assert(tile < Map::Size());
1806
1807 /* Number of times to search.
1808 * Better roads, 2X2 and 3X3 grid grow quite fast so we give
1809 * them a little handicap. */
1810 switch (t->layout) {
1811 case TL_BETTER_ROADS:
1812 _grow_town_result = 10 + t->cache.num_houses * 2 / 9;
1813 break;
1814
1815 case TL_3X3_GRID:
1816 case TL_2X2_GRID:
1817 _grow_town_result = 10 + t->cache.num_houses * 1 / 9;
1818 break;
1819
1820 default:
1821 _grow_town_result = 10 + t->cache.num_houses * 4 / 9;
1822 break;
1823 }
1824
1825 do {
1826 RoadBits cur_rb = GetTownRoadBits(tile); // The RoadBits of the current tile
1827
1828 /* Try to grow the town from this point */
1829 GrowTownInTile(&tile, cur_rb, target_dir, t);
1830 if (_grow_town_result == GROWTH_SUCCEED) return true;
1831
1832 /* Exclude the source position from the bitmask
1833 * and return if no more road blocks available */
1834 if (IsValidDiagDirection(target_dir)) cur_rb &= ~DiagDirToRoadBits(ReverseDiagDir(target_dir));
1835 if (cur_rb == ROAD_NONE) return false;
1836
1837 if (IsTileType(tile, MP_TUNNELBRIDGE)) {
1838 /* Only build in the direction away from the tunnel or bridge. */
1839 target_dir = ReverseDiagDir(GetTunnelBridgeDirection(tile));
1840 } else {
1841 /* Select a random bit from the blockmask, walk a step
1842 * and continue the search from there. */
1843 do {
1844 if (cur_rb == ROAD_NONE) return false;
1845 RoadBits target_bits;
1846 do {
1847 target_dir = RandomDiagDir();
1848 target_bits = DiagDirToRoadBits(target_dir);
1849 } while (!(cur_rb & target_bits));
1850 cur_rb &= ~target_bits;
1851 } while (!CanFollowRoad(tile, target_dir));
1852 }
1853 tile = TileAddByDiagDir(tile, target_dir);
1854
1855 if (IsTileType(tile, MP_ROAD) && !IsRoadDepot(tile) && HasTileRoadType(tile, RTT_ROAD)) {
1856 /* Don't allow building over roads of other cities */
1857 if (IsRoadOwner(tile, RTT_ROAD, OWNER_TOWN) && Town::GetByTile(tile) != t) {
1858 return false;
1859 } else if (IsRoadOwner(tile, RTT_ROAD, OWNER_NONE) && _game_mode == GM_EDITOR) {
1860 /* If we are in the SE, and this road-piece has no town owner yet, it just found an
1861 * owner :) (happy happy happy road now) */
1862 SetRoadOwner(tile, RTT_ROAD, OWNER_TOWN);
1863 SetTownIndex(tile, t->index);
1864 }
1865 }
1866
1867 /* Max number of times is checked. */
1868 } while (--_grow_town_result >= 0);
1869
1870 return false;
1871}
1872
1881{
1882 uint32_t r = Random();
1883 uint a = GB(r, 0, 2);
1884 uint b = GB(r, 8, 2);
1885 if (a == b) b ^= 2;
1886 return (RoadBits)((ROAD_NW << a) + (ROAD_NW << b));
1887}
1888
1894static bool GrowTown(Town *t)
1895{
1896 static const TileIndexDiffC _town_coord_mod[] = {
1897 {-1, 0},
1898 { 1, 1},
1899 { 1, -1},
1900 {-1, -1},
1901 {-1, 0},
1902 { 0, 2},
1903 { 2, 0},
1904 { 0, -2},
1905 {-1, -1},
1906 {-2, 2},
1907 { 2, 2},
1908 { 2, -2},
1909 { 0, 0}
1910 };
1911
1912 /* Current "company" is a town */
1914
1915 TileIndex tile = t->xy; // The tile we are working with ATM
1916
1917 /* Find a road that we can base the construction on. */
1918 for (const auto &ptr : _town_coord_mod) {
1919 if (GetTownRoadBits(tile) != ROAD_NONE) {
1920 bool success = GrowTownAtRoad(t, tile);
1921 cur_company.Restore();
1922 return success;
1923 }
1924 tile = TileAdd(tile, ToTileIndexDiff(ptr));
1925 }
1926
1927 /* No road available, try to build a random road block by
1928 * clearing some land and then building a road there. */
1930 tile = t->xy;
1931 for (const auto &ptr : _town_coord_mod) {
1932 /* Only work with plain land that not already has a house */
1933 if (!IsTileType(tile, MP_HOUSE) && IsTileFlat(tile)) {
1934 if (Command<CMD_LANDSCAPE_CLEAR>::Do(DC_AUTO | DC_NO_WATER, tile).Succeeded()) {
1937 cur_company.Restore();
1938 return true;
1939 }
1940 }
1941 tile = TileAdd(tile, ToTileIndexDiff(ptr));
1942 }
1943 }
1944
1945 cur_company.Restore();
1946 return false;
1947}
1948
1954{
1955 static const std::array<std::array<uint32_t, HZB_END>, 23> _town_squared_town_zone_radius_data = {{
1956 { 4, 0, 0, 0, 0}, // 0
1957 { 16, 0, 0, 0, 0},
1958 { 25, 0, 0, 0, 0},
1959 { 36, 0, 0, 0, 0},
1960 { 49, 0, 4, 0, 0},
1961 { 64, 0, 4, 0, 0}, // 20
1962 { 64, 0, 9, 0, 1},
1963 { 64, 0, 9, 0, 4},
1964 { 64, 0, 16, 0, 4},
1965 { 81, 0, 16, 0, 4},
1966 { 81, 0, 16, 0, 4}, // 40
1967 { 81, 0, 25, 0, 9},
1968 { 81, 36, 25, 0, 9},
1969 { 81, 36, 25, 16, 9},
1970 { 81, 49, 0, 25, 9},
1971 { 81, 64, 0, 25, 9}, // 60
1972 { 81, 64, 0, 36, 9},
1973 { 81, 64, 0, 36, 16},
1974 {100, 81, 0, 49, 16},
1975 {100, 81, 0, 49, 25},
1976 {121, 81, 0, 49, 25}, // 80
1977 {121, 81, 0, 49, 25},
1978 {121, 81, 0, 49, 36}, // 88
1979 }};
1980
1981 if (t->cache.num_houses < std::size(_town_squared_town_zone_radius_data) * 4) {
1982 t->cache.squared_town_zone_radius = _town_squared_town_zone_radius_data[t->cache.num_houses / 4];
1983 } else {
1984 int mass = t->cache.num_houses / 8;
1985 /* Actually we are proportional to sqrt() but that's right because we are covering an area.
1986 * The offsets are to make sure the radii do not decrease in size when going from the table
1987 * to the calculated value.*/
1988 t->cache.squared_town_zone_radius[HZB_TOWN_EDGE] = mass * 15 - 40;
1989 t->cache.squared_town_zone_radius[HZB_TOWN_OUTSKIRT] = mass * 9 - 15;
1990 t->cache.squared_town_zone_radius[HZB_TOWN_OUTER_SUBURB] = 0;
1991 t->cache.squared_town_zone_radius[HZB_TOWN_INNER_SUBURB] = mass * 5 - 5;
1992 t->cache.squared_town_zone_radius[HZB_TOWN_CENTRE] = mass * 3 + 5;
1993 }
1994}
1995
2001{
2003 t->supplied[cs->Index()].old_max = ScaleByCargoScale(t->cache.population >> 3, true);
2004 }
2006 t->supplied[cs->Index()].old_max = ScaleByCargoScale(t->cache.population >> 4, true);
2007 }
2008}
2009
2010static void UpdateTownGrowthRate(Town *t);
2011static void UpdateTownGrowth(Town *t);
2012
2024static void DoCreateTown(Town *t, TileIndex tile, uint32_t townnameparts, TownSize size, bool city, TownLayout layout, bool manual)
2025{
2026 AutoRestoreBackup backup(_generating_town, true);
2027
2028 t->xy = tile;
2029 t->cache.num_houses = 0;
2030 t->time_until_rebuild = 10;
2032 t->flags = 0;
2033 t->cache.population = 0;
2035 /* Spread growth across ticks so even if there are many
2036 * similar towns they're unlikely to grow all in one tick */
2038 t->growth_rate = TownTicksToGameTicks(250);
2039 t->show_zone = false;
2040
2041 _town_kdtree.Insert(t->index);
2042
2043 /* Set the default cargo requirement for town growth */
2045 case LandscapeType::Arctic:
2047 break;
2048
2049 case LandscapeType::Tropic:
2052 break;
2053
2054 default:
2055 break;
2056 }
2057
2058 t->fund_buildings_months = 0;
2059
2060 for (uint i = 0; i != MAX_COMPANIES; i++) t->ratings[i] = RATING_INITIAL;
2061
2062 t->have_ratings = 0;
2064 t->exclusive_counter = 0;
2065 t->statues = 0;
2066
2067 {
2069 t->townnamegrfid = tnp.grfid;
2070 t->townnametype = tnp.type;
2071 }
2072 t->townnameparts = townnameparts;
2073
2074 t->InitializeLayout(layout);
2075
2076 t->larger_town = city;
2077
2078 int x = (int)size * 16 + 3;
2079 if (size == TSZ_RANDOM) x = (Random() & 0xF) + 8;
2080 /* Don't create huge cities when founding town in-game */
2081 if (city && (!manual || _game_mode == GM_EDITOR)) x *= _settings_game.economy.initial_city_size;
2082
2083 t->cache.num_houses += x;
2085
2086 int i = x * 4;
2087 do {
2088 GrowTown(t);
2089 } while (--i);
2090
2091 t->UpdateVirtCoord();
2092 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_REBUILD);
2093
2094 t->cache.num_houses -= x;
2099}
2100
2107{
2108 /* Check if too close to the edge of map */
2109 if (DistanceFromEdge(tile) < 12) {
2110 return CommandCost(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB);
2111 }
2112
2113 /* Check distance to all other towns. */
2114 if (IsCloseToTown(tile, 20)) {
2115 return CommandCost(STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN);
2116 }
2117
2118 /* Can only build on clear flat areas, possibly with trees. */
2119 if ((!IsTileType(tile, MP_CLEAR) && !IsTileType(tile, MP_TREES)) || !IsTileFlat(tile)) {
2120 return CommandCost(STR_ERROR_SITE_UNSUITABLE);
2121 }
2122
2124}
2125
2131static bool IsUniqueTownName(const std::string &name)
2132{
2133 for (const Town *t : Town::Iterate()) {
2134 if (!t->name.empty() && t->name == name) return false;
2135 }
2136
2137 return true;
2138}
2139
2152std::tuple<CommandCost, Money, TownID> CmdFoundTown(DoCommandFlag flags, TileIndex tile, TownSize size, bool city, TownLayout layout, bool random_location, uint32_t townnameparts, const std::string &text)
2153{
2155
2156 if (size >= TSZ_END) return { CMD_ERROR, 0, INVALID_TOWN };
2157 if (layout >= NUM_TLS) return { CMD_ERROR, 0, INVALID_TOWN };
2158
2159 /* Some things are allowed only in the scenario editor and for game scripts. */
2160 if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY) {
2161 if (_settings_game.economy.found_town == TF_FORBIDDEN) return { CMD_ERROR, 0, INVALID_TOWN };
2162 if (size == TSZ_LARGE) return { CMD_ERROR, 0, INVALID_TOWN };
2163 if (random_location) return { CMD_ERROR, 0, INVALID_TOWN };
2165 return { CMD_ERROR, 0, INVALID_TOWN };
2166 }
2167 } else if (_current_company == OWNER_DEITY && random_location) {
2168 /* Random parameter is not allowed for Game Scripts. */
2169 return { CMD_ERROR, 0, INVALID_TOWN };
2170 }
2171
2172 if (text.empty()) {
2173 /* If supplied name is empty, townnameparts has to generate unique automatic name */
2174 if (!VerifyTownName(townnameparts, &par)) return { CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE), 0, INVALID_TOWN };
2175 } else {
2176 /* If name is not empty, it has to be unique custom name */
2177 if (Utf8StringLength(text) >= MAX_LENGTH_TOWN_NAME_CHARS) return { CMD_ERROR, 0, INVALID_TOWN };
2178 if (!IsUniqueTownName(text)) return { CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE), 0, INVALID_TOWN };
2179 }
2180
2181 /* Allocate town struct */
2182 if (!Town::CanAllocateItem()) return { CommandCost(STR_ERROR_TOO_MANY_TOWNS), 0, INVALID_TOWN };
2183
2184 if (!random_location) {
2185 CommandCost ret = TownCanBePlacedHere(tile);
2186 if (ret.Failed()) return { ret, 0, INVALID_TOWN };
2187 }
2188
2189 static const uint8_t price_mult[][TSZ_RANDOM + 1] = {{ 15, 25, 40, 25 }, { 20, 35, 55, 35 }};
2190 /* multidimensional arrays have to have defined length of non-first dimension */
2191 static_assert(lengthof(price_mult[0]) == 4);
2192
2193 CommandCost cost(EXPENSES_OTHER, _price[PR_BUILD_TOWN]);
2194 uint8_t mult = price_mult[city][size];
2195
2196 cost.MultiplyCost(mult);
2197
2198 /* Create the town */
2199 TownID new_town = INVALID_TOWN;
2200 if (flags & DC_EXEC) {
2201 if (cost.GetCost() > GetAvailableMoneyForCommand()) {
2202 return { CommandCost(EXPENSES_OTHER), cost.GetCost(), INVALID_TOWN };
2203 }
2204
2205 Backup<bool> old_generating_world(_generating_world, true);
2207 Town *t;
2208 if (random_location) {
2209 t = CreateRandomTown(20, townnameparts, size, city, layout);
2210 } else {
2211 t = new Town(tile);
2212 DoCreateTown(t, tile, townnameparts, size, city, layout, true);
2213 }
2214
2216 old_generating_world.Restore();
2217
2218 if (t == nullptr) return { CommandCost(STR_ERROR_NO_SPACE_FOR_TOWN), 0, INVALID_TOWN };
2219
2220 new_town = t->index;
2221
2222 if (!text.empty()) {
2223 t->name = text;
2224 t->UpdateVirtCoord();
2225 }
2226
2227 if (_game_mode != GM_EDITOR) {
2228 /* 't' can't be nullptr since 'random' is false outside scenedit */
2229 assert(!random_location);
2230
2232 SetDParam(0, t->index);
2233 AddTileNewsItem(STR_NEWS_NEW_TOWN_UNSPONSORED, NT_INDUSTRY_OPEN, tile);
2234 } else {
2236 std::string company_name = GetString(STR_COMPANY_NAME);
2237
2238 SetDParamStr(0, company_name);
2239 SetDParam(1, t->index);
2240
2241 AddTileNewsItem(STR_NEWS_NEW_TOWN, NT_INDUSTRY_OPEN, tile);
2242 }
2243 AI::BroadcastNewEvent(new ScriptEventTownFounded(t->index));
2244 Game::NewEvent(new ScriptEventTownFounded(t->index));
2245 }
2246 }
2247 return { cost, 0, new_town };
2248}
2249
2260{
2261 switch (layout) {
2262 case TL_2X2_GRID: return TileXY(TileX(tile) - TileX(tile) % 3, TileY(tile) - TileY(tile) % 3);
2263 case TL_3X3_GRID: return TileXY(TileX(tile) & ~3, TileY(tile) & ~3);
2264 default: return tile;
2265 }
2266}
2267
2278{
2279 switch (layout) {
2280 case TL_2X2_GRID: return TileX(tile) % 3 == 0 && TileY(tile) % 3 == 0;
2281 case TL_3X3_GRID: return TileX(tile) % 4 == 0 && TileY(tile) % 4 == 0;
2282 default: return true;
2283 }
2284}
2285
2294
2311static bool FindFurthestFromWater(TileIndex tile, void *user_data)
2312{
2313 SpotData *sp = (SpotData*)user_data;
2314 uint dist = GetClosestWaterDistance(tile, true);
2315
2316 if (IsTileType(tile, MP_CLEAR) &&
2317 IsTileFlat(tile) &&
2318 IsTileAlignedToGrid(tile, sp->layout) &&
2319 dist > sp->max_dist) {
2320 sp->tile = tile;
2321 sp->max_dist = dist;
2322 }
2323
2324 return false;
2325}
2326
2331static bool FindNearestEmptyLand(TileIndex tile, void *)
2332{
2333 return IsTileType(tile, MP_CLEAR);
2334}
2335
2349{
2350 SpotData sp = { INVALID_TILE, 0, layout };
2351
2352 TileIndex coast = tile;
2353 if (CircularTileSearch(&coast, 40, FindNearestEmptyLand, nullptr)) {
2354 CircularTileSearch(&coast, 10, FindFurthestFromWater, &sp);
2355 return sp.tile;
2356 }
2357
2358 /* if we get here just give up */
2359 return INVALID_TILE;
2360}
2361
2371static Town *CreateRandomTown(uint attempts, uint32_t townnameparts, TownSize size, bool city, TownLayout layout)
2372{
2373 assert(_game_mode == GM_EDITOR || _generating_world); // These are the preconditions for CMD_DELETE_TOWN
2374
2375 if (!Town::CanAllocateItem()) return nullptr;
2376
2377 do {
2378 /* Generate a tile index not too close from the edge */
2379 TileIndex tile = AlignTileToGrid(RandomTile(), layout);
2380
2381 /* if we tried to place the town on water, slide it over onto
2382 * the nearest likely-looking spot */
2383 if (IsTileType(tile, MP_WATER)) {
2384 tile = FindNearestGoodCoastalTownSpot(tile, layout);
2385 if (tile == INVALID_TILE) continue;
2386 }
2387
2388 /* Make sure town can be placed here */
2389 if (TownCanBePlacedHere(tile).Failed()) continue;
2390
2391 /* Allocate a town struct */
2392 Town *t = new Town(tile);
2393
2394 DoCreateTown(t, tile, townnameparts, size, city, layout, false);
2395
2396 /* if the population is still 0 at the point, then the
2397 * placement is so bad it couldn't grow at all */
2398 if (t->cache.population > 0) return t;
2399
2401 [[maybe_unused]] CommandCost rc = Command<CMD_DELETE_TOWN>::Do(DC_EXEC, t->index);
2402 cur_company.Restore();
2403 assert(rc.Succeeded());
2404
2405 /* We already know that we can allocate a single town when
2406 * entering this function. However, we create and delete
2407 * a town which "resets" the allocation checks. As such we
2408 * need to check again when assertions are enabled. */
2409 assert(Town::CanAllocateItem());
2410 } while (--attempts != 0);
2411
2412 return nullptr;
2413}
2414
2415static const uint8_t _num_initial_towns[4] = {5, 11, 23, 46}; // very low, low, normal, high
2416
2424{
2425 uint current_number = 0;
2426 uint difficulty = (_game_mode != GM_EDITOR) ? _settings_game.difficulty.number_towns : 0;
2427 uint total = (difficulty == (uint)CUSTOM_TOWN_NUMBER_DIFFICULTY) ? _settings_game.game_creation.custom_town_number : Map::ScaleBySize(_num_initial_towns[difficulty] + (Random() & 7));
2428 total = std::min<uint>(TownPool::MAX_SIZE, total);
2429 uint32_t townnameparts;
2430 TownNames town_names;
2431
2433
2434 /* Pre-populate the town names list with the names of any towns already on the map */
2435 for (const Town *town : Town::Iterate()) {
2436 town_names.insert(town->GetCachedName());
2437 }
2438
2439 /* Randomised offset for city status. This means with e.g. 1-in-4 towns being cities, a map with 10 towns
2440 * may have 2 or 3 cities, instead of always 3. */
2441 uint city_random_offset = _settings_game.economy.larger_towns == 0 ? 0 : (Random() % _settings_game.economy.larger_towns);
2442
2443 /* First attempt will be made at creating the suggested number of towns.
2444 * Note that this is really a suggested value, not a required one.
2445 * We would not like the system to lock up just because the user wanted 100 cities on a 64*64 map, would we? */
2446 do {
2447 bool city = (_settings_game.economy.larger_towns != 0 && ((city_random_offset + current_number) % _settings_game.economy.larger_towns) == 0);
2449 /* Get a unique name for the town. */
2450 if (!GenerateTownName(_random, &townnameparts, &town_names)) continue;
2451 /* try 20 times to create a random-sized town for the first loop. */
2452 if (CreateRandomTown(20, townnameparts, TSZ_RANDOM, city, layout) != nullptr) current_number++; // If creation was successful, raise a flag.
2453 } while (--total);
2454
2455 town_names.clear();
2456
2457 /* Build the town k-d tree again to make sure it's well balanced */
2458 RebuildTownKdtree();
2459
2460 if (current_number != 0) return true;
2461
2462 /* If current_number is still zero at this point, it means that not a single town has been created.
2463 * So give it a last try, but now more aggressive */
2464 if (GenerateTownName(_random, &townnameparts) &&
2465 CreateRandomTown(10000, townnameparts, TSZ_RANDOM, _settings_game.economy.larger_towns != 0, layout) != nullptr) {
2466 return true;
2467 }
2468
2469 /* If there are no towns at all and we are generating new game, bail out */
2470 if (Town::GetNumItems() == 0 && _game_mode != GM_EDITOR) {
2471 ShowErrorMessage(STR_ERROR_COULD_NOT_CREATE_TOWN, INVALID_STRING_ID, WL_CRITICAL);
2472 }
2473
2474 return false; // we are still without a town? we failed, simply
2475}
2476
2477
2484HouseZonesBits GetTownRadiusGroup(const Town *t, TileIndex tile)
2485{
2486 uint dist = DistanceSquare(tile, t->xy);
2487
2488 if (t->fund_buildings_months && dist <= 25) return HZB_TOWN_CENTRE;
2489
2490 HouseZonesBits smallest = HZB_TOWN_EDGE;
2491 for (HouseZonesBits i = HZB_BEGIN; i < HZB_END; i++) {
2492 if (dist < t->cache.squared_town_zone_radius[i]) smallest = i;
2493 }
2494
2495 return smallest;
2496}
2497
2508static inline void ClearMakeHouseTile(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits)
2509{
2511 assert(cc.Succeeded());
2512
2513 IncreaseBuildingCount(t, type);
2514 MakeHouseTile(tile, t->index, counter, stage, type, random_bits);
2515 if (HouseSpec::Get(type)->building_flags.Test(BuildingFlag::IsAnimated)) AddAnimatedTile(tile, false);
2516
2517 MarkTileDirtyByTile(tile);
2518}
2519
2520
2531static void MakeTownHouse(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits)
2532{
2534
2535 ClearMakeHouseTile(tile, t, counter, stage, type, random_bits);
2536 if (size.Any(BUILDING_2_TILES_Y)) ClearMakeHouseTile(tile + TileDiffXY(0, 1), t, counter, stage, ++type, random_bits);
2537 if (size.Any(BUILDING_2_TILES_X)) ClearMakeHouseTile(tile + TileDiffXY(1, 0), t, counter, stage, ++type, random_bits);
2538 if (size.Any(BUILDING_HAS_4_TILES)) ClearMakeHouseTile(tile + TileDiffXY(1, 1), t, counter, stage, ++type, random_bits);
2539
2540 ForAllStationsAroundTiles(TileArea(tile, size.Any(BUILDING_2_TILES_X) ? 2 : 1, size.Any(BUILDING_2_TILES_Y) ? 2 : 1), [t](Station *st, TileIndex) {
2541 t->stations_near.insert(st);
2542 return true;
2543 });
2544}
2545
2546
2553static inline bool CanBuildHouseHere(TileIndex tile, bool noslope)
2554{
2555 /* cannot build on these slopes... */
2556 Slope slope = GetTileSlope(tile);
2557 if ((noslope && slope != SLOPE_FLAT) || IsSteepSlope(slope)) return false;
2558
2559 /* at least one RoadTypes allow building the house here? */
2560 if (!RoadTypesAllowHouseHere(tile)) return false;
2561
2562 /* building under a bridge? */
2563 if (IsBridgeAbove(tile)) return false;
2564
2565 /* can we clear the land? */
2566 return Command<CMD_LANDSCAPE_CLEAR>::Do(DC_AUTO | DC_NO_WATER, tile).Succeeded();
2567}
2568
2569
2578static inline bool CheckBuildHouseSameZ(TileIndex tile, int z, bool noslope)
2579{
2580 if (!CanBuildHouseHere(tile, noslope)) return false;
2581
2582 /* if building on slopes is allowed, there will be flattening foundation (to tile max z) */
2583 if (GetTileMaxZ(tile) != z) return false;
2584
2585 return true;
2586}
2587
2588
2597static bool CheckFree2x2Area(TileIndex tile, int z, bool noslope)
2598{
2599 /* we need to check this tile too because we can be at different tile now */
2600 if (!CheckBuildHouseSameZ(tile, z, noslope)) return false;
2601
2602 for (DiagDirection d = DIAGDIR_SE; d < DIAGDIR_END; d++) {
2603 tile += TileOffsByDiagDir(d);
2604 if (!CheckBuildHouseSameZ(tile, z, noslope)) return false;
2605 }
2606
2607 return true;
2608}
2609
2610
2618static inline bool TownLayoutAllowsHouseHere(Town *t, TileIndex tile)
2619{
2620 /* Allow towns everywhere when we don't build roads */
2621 if (!TownAllowedToBuildRoads()) return true;
2622
2623 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
2624
2625 switch (t->layout) {
2626 case TL_2X2_GRID:
2627 if ((grid_pos.x % 3) == 0 || (grid_pos.y % 3) == 0) return false;
2628 break;
2629
2630 case TL_3X3_GRID:
2631 if ((grid_pos.x % 4) == 0 || (grid_pos.y % 4) == 0) return false;
2632 break;
2633
2634 default:
2635 break;
2636 }
2637
2638 return true;
2639}
2640
2641
2649static inline bool TownLayoutAllows2x2HouseHere(Town *t, TileIndex tile)
2650{
2651 /* Allow towns everywhere when we don't build roads */
2652 if (!TownAllowedToBuildRoads()) return true;
2653
2654 /* Compute relative position of tile. (Positive offsets are towards north) */
2655 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
2656
2657 switch (t->layout) {
2658 case TL_2X2_GRID:
2659 grid_pos.x %= 3;
2660 grid_pos.y %= 3;
2661 if ((grid_pos.x != 2 && grid_pos.x != -1) ||
2662 (grid_pos.y != 2 && grid_pos.y != -1)) return false;
2663 break;
2664
2665 case TL_3X3_GRID:
2666 if ((grid_pos.x & 3) < 2 || (grid_pos.y & 3) < 2) return false;
2667 break;
2668
2669 default:
2670 break;
2671 }
2672
2673 return true;
2674}
2675
2676
2686static bool CheckTownBuild2House(TileIndex *tile, Town *t, int maxz, bool noslope, DiagDirection second)
2687{
2688 /* 'tile' is already checked in BuildTownHouse() - CanBuildHouseHere() and slope test */
2689
2690 TileIndex tile2 = *tile + TileOffsByDiagDir(second);
2691 if (TownLayoutAllowsHouseHere(t, tile2) && CheckBuildHouseSameZ(tile2, maxz, noslope)) return true;
2692
2693 tile2 = *tile + TileOffsByDiagDir(ReverseDiagDir(second));
2694 if (TownLayoutAllowsHouseHere(t, tile2) && CheckBuildHouseSameZ(tile2, maxz, noslope)) {
2695 *tile = tile2;
2696 return true;
2697 }
2698
2699 return false;
2700}
2701
2702
2711static bool CheckTownBuild2x2House(TileIndex *tile, Town *t, int maxz, bool noslope)
2712{
2713 TileIndex tile2 = *tile;
2714
2715 for (DiagDirection d = DIAGDIR_SE;; d++) { // 'd' goes through DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_END
2716 if (TownLayoutAllows2x2HouseHere(t, tile2) && CheckFree2x2Area(tile2, maxz, noslope)) {
2717 *tile = tile2;
2718 return true;
2719 }
2720 if (d == DIAGDIR_END) break;
2721 tile2 += TileOffsByDiagDir(ReverseDiagDir(d)); // go clockwise
2722 }
2723
2724 return false;
2725}
2726
2735static void BuildTownHouse(Town *t, TileIndex tile, const HouseSpec *hs, HouseID house, uint8_t random_bits)
2736{
2737 /* build the house */
2738 t->cache.num_houses++;
2739
2740 uint8_t construction_counter = 0;
2741 uint8_t construction_stage = 0;
2742
2743 if (_generating_world || _game_mode == GM_EDITOR) {
2744 uint32_t construction_random = Random();
2745
2746 construction_stage = TOWN_HOUSE_COMPLETED;
2747 if (_generating_world && !hs->extra_flags.Test(HouseExtraFlag::BuildingIsHistorical) && Chance16(1, 7)) construction_stage = GB(construction_random, 0, 2);
2748
2749 if (construction_stage == TOWN_HOUSE_COMPLETED) {
2751 } else {
2752 construction_counter = GB(construction_random, 2, 2);
2753 }
2754 }
2755
2756 MakeTownHouse(tile, t, construction_counter, construction_stage, house, random_bits);
2759}
2760
2767static bool TryBuildTownHouse(Town *t, TileIndex tile)
2768{
2769 /* forbidden building here by town layout */
2770 if (!TownLayoutAllowsHouseHere(t, tile)) return false;
2771
2772 /* no house allowed at all, bail out */
2773 if (!CanBuildHouseHere(tile, false)) return false;
2774
2775 Slope slope = GetTileSlope(tile);
2776 int maxz = GetTileMaxZ(tile);
2777
2778 /* Get the town zone type of the current tile, as well as the climate.
2779 * This will allow to easily compare with the specs of the new house to build */
2780 HouseZonesBits rad = GetTownRadiusGroup(t, tile);
2781
2782 /* Above snow? */
2784 if (_settings_game.game_creation.landscape == LandscapeType::Arctic && maxz > HighestSnowLine()) land = -1;
2785
2786 uint bitmask = (1 << rad) + (1 << (land + 12));
2787
2788 /* bits 0-4 are used
2789 * bits 11-15 are used
2790 * bits 5-10 are not used. */
2791 static std::vector<std::pair<HouseID, uint>> probs;
2792 probs.clear();
2793
2794 uint probability_max = 0;
2795
2796 /* Generate a list of all possible houses that can be built. */
2797 for (const auto &hs : HouseSpec::Specs()) {
2798 /* Verify that the candidate house spec matches the current tile status */
2799 if ((~hs.building_availability & bitmask) != 0 || !hs.enabled || hs.grf_prop.override != INVALID_HOUSE_ID) continue;
2800
2801 /* Don't let these counters overflow. Global counters are 32bit, there will never be that many houses. */
2802 if (hs.class_id != HOUSE_NO_CLASS) {
2803 /* id_count is always <= class_count, so it doesn't need to be checked */
2804 if (t->cache.building_counts.class_count[hs.class_id] == UINT16_MAX) continue;
2805 } else {
2806 /* If the house has no class, check id_count instead */
2807 if (t->cache.building_counts.id_count[hs.Index()] == UINT16_MAX) continue;
2808 }
2809
2810 uint cur_prob = hs.probability;
2811 probability_max += cur_prob;
2812 probs.emplace_back(hs.Index(), cur_prob);
2813 }
2814
2815 TileIndex baseTile = tile;
2816
2817 while (probability_max > 0) {
2818 /* Building a multitile building can change the location of tile.
2819 * The building would still be built partially on that tile, but
2820 * its northern tile would be elsewhere. However, if the callback
2821 * fails we would be basing further work from the changed tile.
2822 * So a next 1x1 tile building could be built on the wrong tile. */
2823 tile = baseTile;
2824
2825 uint r = RandomRange(probability_max);
2826 uint i;
2827 for (i = 0; i < probs.size(); i++) {
2828 if (probs[i].second > r) break;
2829 r -= probs[i].second;
2830 }
2831
2832 HouseID house = probs[i].first;
2833 probability_max -= probs[i].second;
2834
2835 /* remove tested house from the set */
2836 probs[i] = probs.back();
2837 probs.pop_back();
2838
2839 const HouseSpec *hs = HouseSpec::Get(house);
2840
2841 if (!_generating_world && _game_mode != GM_EDITOR && hs->extra_flags.Test(HouseExtraFlag::BuildingIsHistorical)) {
2842 continue;
2843 }
2844
2845 if (TimerGameCalendar::year < hs->min_year || TimerGameCalendar::year > hs->max_year) continue;
2846
2847 /* Special houses that there can be only one of. */
2848 uint oneof = 0;
2849
2850 if (hs->building_flags.Test(BuildingFlag::IsChurch)) {
2851 SetBit(oneof, TOWN_HAS_CHURCH);
2852 } else if (hs->building_flags.Test(BuildingFlag::IsStadium)) {
2853 SetBit(oneof, TOWN_HAS_STADIUM);
2854 }
2855
2856 if (t->flags & oneof) continue;
2857
2858 /* Make sure there is no slope? */
2859 bool noslope = hs->building_flags.Test(BuildingFlag::NotSloped);
2860 if (noslope && slope != SLOPE_FLAT) continue;
2861
2862 if (hs->building_flags.Test(BuildingFlag::Size2x2)) {
2863 if (!CheckTownBuild2x2House(&tile, t, maxz, noslope)) continue;
2864 } else if (hs->building_flags.Test(BuildingFlag::Size2x1)) {
2865 if (!CheckTownBuild2House(&tile, t, maxz, noslope, DIAGDIR_SW)) continue;
2866 } else if (hs->building_flags.Test(BuildingFlag::Size1x2)) {
2867 if (!CheckTownBuild2House(&tile, t, maxz, noslope, DIAGDIR_SE)) continue;
2868 } else {
2869 /* 1x1 house checks are already done */
2870 }
2871
2872 uint8_t random_bits = Random();
2873
2875 uint16_t callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile, true, random_bits);
2876 if (callback_res != CALLBACK_FAILED && !Convert8bitBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_ALLOW_CONSTRUCTION, callback_res)) continue;
2877 }
2878
2879 /* Special houses that there can be only one of. */
2880 t->flags |= oneof;
2881
2882 BuildTownHouse(t, tile, hs, house, random_bits);
2883
2884 return true;
2885 }
2886
2887 return false;
2888}
2889
2890CommandCost CmdPlaceHouse(DoCommandFlag flags, TileIndex tile, HouseID house)
2891{
2892 if (_game_mode != GM_EDITOR) return CMD_ERROR;
2893 if (Town::GetNumItems() == 0) return CommandCost(STR_ERROR_MUST_FOUND_TOWN_FIRST);
2894
2895 if (static_cast<size_t>(house) >= HouseSpec::Specs().size()) return CMD_ERROR;
2896 const HouseSpec *hs = HouseSpec::Get(house);
2897 if (!hs->enabled) return CMD_ERROR;
2898
2899 Town *t = ClosestTownFromTile(tile, UINT_MAX);
2900
2901 /* cannot build on these slopes... */
2902 Slope slope = GetTileSlope(tile);
2903 if (IsSteepSlope(slope)) return CommandCost(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
2904
2905 /* building under a bridge? */
2906 if (IsBridgeAbove(tile)) return CommandCost(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
2907
2908 /* can we clear the land? */
2910 if (!cost.Succeeded()) return cost;
2911
2912 int maxz = GetTileMaxZ(tile);
2913
2914 /* Make sure there is no slope? */
2915 bool noslope = hs->building_flags.Test(BuildingFlag::NotSloped);
2916 if (noslope && slope != SLOPE_FLAT) return CommandCost(STR_ERROR_FLAT_LAND_REQUIRED);
2917
2918 TileArea ta = tile;
2919 if (hs->building_flags.Test(BuildingFlag::Size2x2)) ta.Add(TileAddXY(tile, 1, 1));
2920 if (hs->building_flags.Test(BuildingFlag::Size2x1)) ta.Add(TileAddByDiagDir(tile, DIAGDIR_SW));
2921 if (hs->building_flags.Test(BuildingFlag::Size1x2)) ta.Add(TileAddByDiagDir(tile, DIAGDIR_SE));
2922
2923 /* Check additonal tiles covered by this house. */
2924 for (const TileIndex &subtile : ta) {
2926 if (!cost.Succeeded()) return cost;
2927
2928 if (!CheckBuildHouseSameZ(subtile, maxz, noslope)) return CommandCost(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
2929 }
2930
2931 if (flags & DC_EXEC) {
2932 BuildTownHouse(t, tile, hs, house, Random());
2933 }
2934
2935 return CommandCost();
2936}
2937
2944static void DoClearTownHouseHelper(TileIndex tile, Town *t, HouseID house)
2945{
2946 assert(IsTileType(tile, MP_HOUSE));
2947 DecreaseBuildingCount(t, house);
2948 DoClearSquare(tile);
2949
2950 DeleteNewGRFInspectWindow(GSF_HOUSES, tile.base());
2951}
2952
2961{
2962 if (house >= 3) { // house id 0,1,2 MUST be single tile houses, or this code breaks.
2963 if (HouseSpec::Get(house - 1)->building_flags.Test(BuildingFlag::Size2x1)) {
2964 house--;
2965 return TileDiffXY(-1, 0);
2966 } else if (HouseSpec::Get(house - 1)->building_flags.Any(BUILDING_2_TILES_Y)) {
2967 house--;
2968 return TileDiffXY(0, -1);
2969 } else if (HouseSpec::Get(house - 2)->building_flags.Any(BUILDING_HAS_4_TILES)) {
2970 house -= 2;
2971 return TileDiffXY(-1, 0);
2972 } else if (HouseSpec::Get(house - 3)->building_flags.Any(BUILDING_HAS_4_TILES)) {
2973 house -= 3;
2974 return TileDiffXY(-1, -1);
2975 }
2976 }
2977 return TileDiffXY(0, 0);
2978}
2979
2986{
2987 assert(IsTileType(tile, MP_HOUSE));
2988
2989 HouseID house = GetHouseType(tile);
2990
2991 /* The northernmost tile of the house is the main house. */
2992 tile += GetHouseNorthPart(house);
2993
2994 const HouseSpec *hs = HouseSpec::Get(house);
2995
2996 /* Remove population from the town if the house is finished. */
2997 if (IsHouseCompleted(tile)) {
2999 }
3000
3001 t->cache.num_houses--;
3002
3003 /* Clear flags for houses that only may exist once/town. */
3004 if (hs->building_flags.Test(BuildingFlag::IsChurch)) {
3006 } else if (hs->building_flags.Test(BuildingFlag::IsStadium)) {
3008 }
3009
3010 /* Do the actual clearing of tiles */
3011 DoClearTownHouseHelper(tile, t, house);
3012 if (hs->building_flags.Any(BUILDING_2_TILES_Y)) DoClearTownHouseHelper(tile + TileDiffXY(0, 1), t, ++house);
3013 if (hs->building_flags.Any(BUILDING_2_TILES_X)) DoClearTownHouseHelper(tile + TileDiffXY(1, 0), t, ++house);
3014 if (hs->building_flags.Any(BUILDING_HAS_4_TILES)) DoClearTownHouseHelper(tile + TileDiffXY(1, 1), t, ++house);
3015
3017
3019}
3020
3028CommandCost CmdRenameTown(DoCommandFlag flags, TownID town_id, const std::string &text)
3029{
3030 Town *t = Town::GetIfValid(town_id);
3031 if (t == nullptr) return CMD_ERROR;
3032
3033 bool reset = text.empty();
3034
3035 if (!reset) {
3037 if (!IsUniqueTownName(text)) return CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE);
3038 }
3039
3040 if (flags & DC_EXEC) {
3041 t->cached_name.clear();
3042 if (reset) {
3043 t->name.clear();
3044 } else {
3045 t->name = text;
3046 }
3047
3048 t->UpdateVirtCoord();
3049 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_RESORT);
3050 ClearAllStationCachedNames();
3051 ClearAllIndustryCachedNames();
3053 }
3054 return CommandCost();
3055}
3056
3063{
3064 for (const CargoSpec *cs : CargoSpec::Iterate()) {
3065 if (cs->town_acceptance_effect == effect) return cs;
3066 }
3067 return nullptr;
3068}
3069
3078CommandCost CmdTownCargoGoal(DoCommandFlag flags, TownID town_id, TownAcceptanceEffect tae, uint32_t goal)
3079{
3080 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3081
3082 if (tae < TAE_BEGIN || tae >= TAE_END) return CMD_ERROR;
3083
3084 Town *t = Town::GetIfValid(town_id);
3085 if (t == nullptr) return CMD_ERROR;
3086
3087 /* Validate if there is a cargo which is the requested TownEffect */
3089 if (cargo == nullptr) return CMD_ERROR;
3090
3091 if (flags & DC_EXEC) {
3092 t->goal[tae] = goal;
3095 }
3096
3097 return CommandCost();
3098}
3099
3107CommandCost CmdTownSetText(DoCommandFlag flags, TownID town_id, const std::string &text)
3108{
3109 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3110 Town *t = Town::GetIfValid(town_id);
3111 if (t == nullptr) return CMD_ERROR;
3112
3113 if (flags & DC_EXEC) {
3114 t->text.clear();
3115 if (!text.empty()) t->text = text;
3117 }
3118
3119 return CommandCost();
3120}
3121
3129CommandCost CmdTownGrowthRate(DoCommandFlag flags, TownID town_id, uint16_t growth_rate)
3130{
3131 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3132
3133 Town *t = Town::GetIfValid(town_id);
3134 if (t == nullptr) return CMD_ERROR;
3135
3136 if (flags & DC_EXEC) {
3137 if (growth_rate == 0) {
3138 /* Just clear the flag, UpdateTownGrowth will determine a proper growth rate */
3140 } else {
3141 uint old_rate = t->growth_rate;
3142 if (t->grow_counter >= old_rate) {
3143 /* This also catches old_rate == 0 */
3144 t->grow_counter = growth_rate;
3145 } else {
3146 /* Scale grow_counter, so half finished houses stay half finished */
3147 t->grow_counter = t->grow_counter * growth_rate / old_rate;
3148 }
3149 t->growth_rate = growth_rate;
3151 }
3154 }
3155
3156 return CommandCost();
3157}
3158
3167CommandCost CmdTownRating(DoCommandFlag flags, TownID town_id, CompanyID company_id, int16_t rating)
3168{
3169 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3170
3171 Town *t = Town::GetIfValid(town_id);
3172 if (t == nullptr) return CMD_ERROR;
3173
3174 if (!Company::IsValidID(company_id)) return CMD_ERROR;
3175
3176 int16_t new_rating = Clamp(rating, RATING_MINIMUM, RATING_MAXIMUM);
3177 if (flags & DC_EXEC) {
3178 t->ratings[company_id] = new_rating;
3180 }
3181
3182 return CommandCost();
3183}
3184
3192CommandCost CmdExpandTown(DoCommandFlag flags, TownID town_id, uint32_t grow_amount)
3193{
3194 if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY) return CMD_ERROR;
3195 Town *t = Town::GetIfValid(town_id);
3196 if (t == nullptr) return CMD_ERROR;
3197
3198 if (flags & DC_EXEC) {
3199 /* The more houses, the faster we grow */
3200 if (grow_amount == 0) {
3201 uint amount = RandomRange(ClampTo<uint16_t>(t->cache.num_houses / 10)) + 3;
3202 t->cache.num_houses += amount;
3204
3205 uint n = amount * 10;
3206 do GrowTown(t); while (--n);
3207
3208 t->cache.num_houses -= amount;
3209 } else {
3210 for (; grow_amount > 0; grow_amount--) {
3211 /* Try several times to grow, as we are really suppose to grow */
3212 for (uint i = 0; i < 25; i++) if (GrowTown(t)) break;
3213 }
3214 }
3216
3218 }
3219
3220 return CommandCost();
3221}
3222
3230{
3231 if (_game_mode != GM_EDITOR && !_generating_world) return CMD_ERROR;
3232 Town *t = Town::GetIfValid(town_id);
3233 if (t == nullptr) return CMD_ERROR;
3234
3235 /* Stations refer to towns. */
3236 for (const Station *st : Station::Iterate()) {
3237 if (st->town == t) {
3238 /* Non-oil rig stations are always a problem. */
3239 if (!(st->facilities & FACIL_AIRPORT) || st->airport.type != AT_OILRIG) return CMD_ERROR;
3240 /* We can only automatically delete oil rigs *if* there's no vehicle on them. */
3241 CommandCost ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, st->airport.tile);
3242 if (ret.Failed()) return ret;
3243 }
3244 }
3245
3246 /* Waypoints refer to towns. */
3247 for (const Waypoint *wp : Waypoint::Iterate()) {
3248 if (wp->town == t) return CMD_ERROR;
3249 }
3250
3251 /* Depots refer to towns. */
3252 for (const Depot *d : Depot::Iterate()) {
3253 if (d->town == t) return CMD_ERROR;
3254 }
3255
3256 /* Check all tiles for town ownership. First check for bridge tiles, as
3257 * these do not directly have an owner so we need to check adjacent
3258 * tiles. This won't work correctly in the same loop if the adjacent
3259 * tile was already deleted earlier in the loop. */
3260 for (const auto current_tile : Map::Iterate()) {
3261 if (IsTileType(current_tile, MP_TUNNELBRIDGE) && TestTownOwnsBridge(current_tile, t)) {
3262 CommandCost ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, current_tile);
3263 if (ret.Failed()) return ret;
3264 }
3265 }
3266
3267 /* Check all remaining tiles for town ownership. */
3268 for (const auto current_tile : Map::Iterate()) {
3269 bool try_clear = false;
3270 switch (GetTileType(current_tile)) {
3271 case MP_ROAD:
3272 try_clear = HasTownOwnedRoad(current_tile) && GetTownIndex(current_tile) == t->index;
3273 break;
3274
3275 case MP_HOUSE:
3276 try_clear = GetTownIndex(current_tile) == t->index;
3277 break;
3278
3279 case MP_INDUSTRY:
3280 try_clear = Industry::GetByTile(current_tile)->town == t;
3281 break;
3282
3283 case MP_OBJECT:
3284 if (Town::GetNumItems() == 1) {
3285 /* No towns will be left, remove it! */
3286 try_clear = true;
3287 } else {
3288 Object *o = Object::GetByTile(current_tile);
3289 if (o->town == t) {
3290 if (o->type == OBJECT_STATUE) {
3291 /* Statue... always remove. */
3292 try_clear = true;
3293 } else {
3294 /* Tell to find a new town. */
3295 if (flags & DC_EXEC) o->town = nullptr;
3296 }
3297 }
3298 }
3299 break;
3300
3301 default:
3302 break;
3303 }
3304 if (try_clear) {
3305 CommandCost ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, current_tile);
3306 if (ret.Failed()) return ret;
3307 }
3308 }
3309
3310 /* The town destructor will delete the other things related to the town. */
3311 if (flags & DC_EXEC) {
3312 _town_kdtree.Remove(t->index);
3313 if (t->cache.sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeTown(t->index));
3314 delete t;
3315 }
3316
3317 return CommandCost();
3318}
3319
3325 2, 4, 9, 35, 48, 53, 117, 175
3326};
3327
3335{
3336 if (flags & DC_EXEC) {
3337 ModifyStationRatingAround(t->xy, _current_company, 0x40, 10);
3338 }
3339 return CommandCost();
3340}
3341
3349{
3350 if (flags & DC_EXEC) {
3351 ModifyStationRatingAround(t->xy, _current_company, 0x70, 15);
3352 }
3353 return CommandCost();
3354}
3355
3363{
3364 if (flags & DC_EXEC) {
3365 ModifyStationRatingAround(t->xy, _current_company, 0xA0, 20);
3366 }
3367 return CommandCost();
3368}
3369
3377{
3378 /* Check if the company is allowed to fund new roads. */
3380
3381 if (flags & DC_EXEC) {
3382 t->road_build_months = 6;
3383
3385 std::string company_name = GetString(STR_COMPANY_NAME);
3386
3387 SetDParam(0, t->index);
3388 SetDParamStr(1, company_name);
3389
3391 TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_ROAD_REBUILDING_MINUTES : STR_NEWS_ROAD_REBUILDING_MONTHS,
3392 NT_GENERAL, NF_NORMAL, NR_TOWN, t->index, NR_NONE, UINT32_MAX);
3393 AI::BroadcastNewEvent(new ScriptEventRoadReconstruction((ScriptCompany::CompanyID)(Owner)_current_company, t->index));
3394 Game::NewEvent(new ScriptEventRoadReconstruction((ScriptCompany::CompanyID)(Owner)_current_company, t->index));
3395 }
3396 return CommandCost();
3397}
3398
3404static bool CheckClearTile(TileIndex tile)
3405{
3408 cur_company.Restore();
3409 return r.Succeeded();
3410}
3411
3416
3417 StatueBuildSearchData(TileIndex best_pos, int count) : best_position(best_pos), tile_count(count) { }
3418};
3419
3426static bool SearchTileForStatue(TileIndex tile, void *user_data)
3427{
3428 static const int STATUE_NUMBER_INNER_TILES = 25; // Number of tiles int the center of the city, where we try to protect houses.
3429
3430 StatueBuildSearchData *statue_data = (StatueBuildSearchData *)user_data;
3431 statue_data->tile_count++;
3432
3433 /* Statues can be build on slopes, just like houses. Only the steep slopes is a no go. */
3434 if (IsSteepSlope(GetTileSlope(tile))) return false;
3435 /* Don't build statues under bridges. */
3436 if (IsBridgeAbove(tile)) return false;
3437
3438 /* A clear-able open space is always preferred. */
3439 if ((IsTileType(tile, MP_CLEAR) || IsTileType(tile, MP_TREES)) && CheckClearTile(tile)) {
3440 statue_data->best_position = tile;
3441 return true;
3442 }
3443
3444 bool house = IsTileType(tile, MP_HOUSE);
3445
3446 /* Searching inside the inner circle. */
3447 if (statue_data->tile_count <= STATUE_NUMBER_INNER_TILES) {
3448 /* Save first house in inner circle. */
3449 if (house && statue_data->best_position == INVALID_TILE && CheckClearTile(tile)) {
3450 statue_data->best_position = tile;
3451 }
3452
3453 /* If we have reached the end of the inner circle, and have a saved house, terminate the search. */
3454 return statue_data->tile_count == STATUE_NUMBER_INNER_TILES && statue_data->best_position != INVALID_TILE;
3455 }
3456
3457 /* Searching outside the circle, just pick the first possible spot. */
3458 statue_data->best_position = tile; // Is optimistic, the condition below must also hold.
3459 return house && CheckClearTile(tile);
3460}
3461
3470{
3471 if (!Object::CanAllocateItem()) return CommandCost(STR_ERROR_TOO_MANY_OBJECTS);
3472
3473 TileIndex tile = t->xy;
3474 StatueBuildSearchData statue_data(INVALID_TILE, 0);
3475 if (!CircularTileSearch(&tile, 9, SearchTileForStatue, &statue_data)) return CommandCost(STR_ERROR_STATUE_NO_SUITABLE_PLACE);
3476
3477 if (flags & DC_EXEC) {
3480 cur_company.Restore();
3482 SetBit(t->statues, _current_company); // Once found and built, "inform" the Town.
3484 }
3485 return CommandCost();
3486}
3487
3495{
3496 /* Check if it's allowed to buy the rights */
3498
3499 if (flags & DC_EXEC) {
3500 /* And grow for 3 months */
3501 t->fund_buildings_months = 3;
3502
3503 /* Enable growth (also checking GameScript's opinion) */
3505
3506 /* Build a new house, but add a small delay to make sure
3507 * that spamming funding doesn't let town grow any faster
3508 * than 1 house per 2 * TOWN_GROWTH_TICKS ticks.
3509 * Also emulate original behaviour when town was only growing in
3510 * TOWN_GROWTH_TICKS intervals, to make sure that it's not too
3511 * tick-perfect and gives player some time window where they can
3512 * spam funding with the exact same efficiency.
3513 */
3515
3517 }
3518 return CommandCost();
3519}
3520
3528{
3529 /* Check if it's allowed to buy the rights */
3531 if (t->exclusivity != INVALID_COMPANY) return CMD_ERROR;
3532
3533 if (flags & DC_EXEC) {
3534 t->exclusive_counter = 12;
3536
3537 ModifyStationRatingAround(t->xy, _current_company, 130, 17);
3538
3540
3541 /* Spawn news message */
3542 auto cni = std::make_unique<CompanyNewsInformation>(Company::Get(_current_company));
3543 SetDParam(0, STR_NEWS_EXCLUSIVE_RIGHTS_TITLE);
3544 SetDParam(1, TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MINUTES : STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MONTHS);
3545 SetDParam(2, t->index);
3546 SetDParamStr(3, cni->company_name);
3547 AddNewsItem(STR_MESSAGE_NEWS_FORMAT, NT_GENERAL, NF_COMPANY, NR_TOWN, t->index, NR_NONE, UINT32_MAX, std::move(cni));
3548 AI::BroadcastNewEvent(new ScriptEventExclusiveTransportRights((ScriptCompany::CompanyID)(Owner)_current_company, t->index));
3549 Game::NewEvent(new ScriptEventExclusiveTransportRights((ScriptCompany::CompanyID)(Owner)_current_company, t->index));
3550 }
3551 return CommandCost();
3552}
3553
3561{
3562 if (flags & DC_EXEC) {
3563 if (Chance16(1, 14)) {
3564 /* set as unwanted for 6 months */
3565 t->unwanted[_current_company] = 6;
3566
3567 /* set all close by station ratings to 0 */
3568 for (Station *st : Station::Iterate()) {
3569 if (st->town == t && st->owner == _current_company) {
3570 for (GoodsEntry &ge : st->goods) ge.rating = 0;
3571 }
3572 }
3573
3574 /* only show error message to the executing player. All errors are handled command.c
3575 * but this is special, because it can only 'fail' on a DC_EXEC */
3576 if (IsLocalCompany()) ShowErrorMessage(STR_ERROR_BRIBE_FAILED, INVALID_STRING_ID, WL_INFO);
3577
3578 /* decrease by a lot!
3579 * ChangeTownRating is only for stuff in demolishing. Bribe failure should
3580 * be independent of any cheat settings
3581 */
3582 if (t->ratings[_current_company] > RATING_BRIBE_DOWN_TO) {
3583 t->ratings[_current_company] = RATING_BRIBE_DOWN_TO;
3585 }
3586 } else {
3587 ChangeTownRating(t, RATING_BRIBE_UP_STEP, RATING_BRIBE_MAXIMUM, DC_EXEC);
3590 t->exclusive_counter = 0;
3591 }
3592 }
3593 }
3594 return CommandCost();
3595}
3596
3597typedef CommandCost TownActionProc(Town *t, DoCommandFlag flags);
3598static TownActionProc * const _town_action_proc[] = {
3607};
3608
3616{
3617 TownActions buttons = TACT_NONE;
3618
3619 /* Spectators and unwanted have no options */
3620 if (cid != COMPANY_SPECTATOR && !(_settings_game.economy.bribe && t->unwanted[cid])) {
3621
3622 /* Actions worth more than this are not able to be performed */
3623 Money avail = GetAvailableMoney(cid);
3624
3625 /* Check the action bits for validity and
3626 * if they are valid add them */
3627 for (uint i = 0; i != lengthof(_town_action_costs); i++) {
3628 const TownActions cur = (TownActions)(1 << i);
3629
3630 /* Is the company prohibited from bribing ? */
3631 if (cur == TACT_BRIBE) {
3632 /* Company can't bribe if setting is disabled */
3633 if (!_settings_game.economy.bribe) continue;
3634 /* Company can bribe if another company has exclusive transport rights,
3635 * or its standing with the town is less than outstanding. */
3636 if (t->ratings[cid] >= RATING_BRIBE_MAXIMUM) {
3637 if (t->exclusivity == _current_company) continue;
3638 if (t->exclusive_counter == 0) continue;
3639 }
3640 }
3641
3642 /* Is the company not able to buy exclusive rights ? */
3643 if (cur == TACT_BUY_RIGHTS && (!_settings_game.economy.exclusive_rights || t->exclusive_counter != 0)) continue;
3644
3645 /* Is the company not able to fund buildings ? */
3647
3648 /* Is the company not able to fund local road reconstruction? */
3649 if (cur == TACT_ROAD_REBUILD && !_settings_game.economy.fund_roads) continue;
3650
3651 /* Is the company not able to build a statue ? */
3652 if (cur == TACT_BUILD_STATUE && HasBit(t->statues, cid)) continue;
3653
3654 if (avail >= _town_action_costs[i] * _price[PR_TOWN_ACTION] >> 8) {
3655 buttons |= cur;
3656 }
3657 }
3658 }
3659
3660 return buttons;
3661}
3662
3672CommandCost CmdDoTownAction(DoCommandFlag flags, TownID town_id, uint8_t action)
3673{
3674 Town *t = Town::GetIfValid(town_id);
3675 if (t == nullptr || action >= lengthof(_town_action_proc)) return CMD_ERROR;
3676
3677 if (!HasBit(GetMaskOfTownActions(_current_company, t), action)) return CMD_ERROR;
3678
3679 CommandCost cost(EXPENSES_OTHER, _price[PR_TOWN_ACTION] * _town_action_costs[action] >> 8);
3680
3681 CommandCost ret = _town_action_proc[action](t, flags);
3682 if (ret.Failed()) return ret;
3683
3684 if (flags & DC_EXEC) {
3686 }
3687
3688 return cost;
3689}
3690
3691template <typename Func>
3692static void ForAllStationsNearTown(Town *t, Func func)
3693{
3694 /* Ideally the search radius should be close to the actual town zone 0 radius.
3695 * The true radius is not stored or calculated anywhere, only the squared radius. */
3696 /* The efficiency of this search might be improved for large towns and many stations on the map,
3697 * by using an integer square root approximation giving a value not less than the true square root. */
3698 uint search_radius = t->cache.squared_town_zone_radius[HZB_TOWN_EDGE] / 2;
3699 ForAllStationsRadius(t->xy, search_radius, [&](const Station * st) {
3700 if (DistanceSquare(st->xy, t->xy) <= t->cache.squared_town_zone_radius[HZB_TOWN_EDGE]) {
3701 func(st);
3702 }
3703 });
3704}
3705
3710static void UpdateTownRating(Town *t)
3711{
3712 /* Increase company ratings if they're low */
3713 for (const Company *c : Company::Iterate()) {
3714 if (t->ratings[c->index] < RATING_GROWTH_MAXIMUM) {
3715 t->ratings[c->index] = std::min((int)RATING_GROWTH_MAXIMUM, t->ratings[c->index] + RATING_GROWTH_UP_STEP);
3716 }
3717 }
3718
3719 ForAllStationsNearTown(t, [&](const Station *st) {
3720 if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
3721 if (Company::IsValidID(st->owner)) {
3722 int new_rating = t->ratings[st->owner] + RATING_STATION_UP_STEP;
3723 t->ratings[st->owner] = std::min<int>(new_rating, INT16_MAX); // do not let it overflow
3724 }
3725 } else {
3726 if (Company::IsValidID(st->owner)) {
3727 int new_rating = t->ratings[st->owner] + RATING_STATION_DOWN_STEP;
3728 t->ratings[st->owner] = std::max(new_rating, INT16_MIN);
3729 }
3730 }
3731 });
3732
3733 /* clamp all ratings to valid values */
3734 for (uint i = 0; i < MAX_COMPANIES; i++) {
3735 t->ratings[i] = Clamp(t->ratings[i], RATING_MINIMUM, RATING_MAXIMUM);
3736 }
3737
3739}
3740
3741
3748static void UpdateTownGrowCounter(Town *t, uint16_t prev_growth_rate)
3749{
3750 if (t->growth_rate == TOWN_GROWTH_RATE_NONE) return;
3751 if (prev_growth_rate == TOWN_GROWTH_RATE_NONE) {
3752 t->grow_counter = std::min<uint16_t>(t->growth_rate, t->grow_counter);
3753 return;
3754 }
3755 t->grow_counter = RoundDivSU((uint32_t)t->grow_counter * (t->growth_rate + 1), prev_growth_rate + 1);
3756}
3757
3764{
3765 int n = 0;
3766 ForAllStationsNearTown(t, [&](const Station * st) {
3767 if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
3768 n++;
3769 }
3770 });
3771 return n;
3772}
3773
3781{
3787 static const uint16_t _grow_count_values[2][6] = {
3788 { 120, 120, 120, 100, 80, 60 }, // Fund new buildings has been activated
3789 { 320, 420, 300, 220, 160, 100 } // Normal values
3790 };
3791
3792 int n = CountActiveStations(t);
3793 uint16_t m = _grow_count_values[t->fund_buildings_months != 0 ? 0 : 1][std::min(n, 5)];
3794
3795 uint growth_multiplier = _settings_game.economy.town_growth_rate != 0 ? _settings_game.economy.town_growth_rate - 1 : 1;
3796
3797 m >>= growth_multiplier;
3798 if (t->larger_town) m /= 2;
3799
3800 return TownTicksToGameTicks(m / (t->cache.num_houses / 50 + 1));
3801}
3802
3808{
3809 if (HasBit(t->flags, TOWN_CUSTOM_GROWTH)) return;
3810 uint old_rate = t->growth_rate;
3812 UpdateTownGrowCounter(t, old_rate);
3814}
3815
3820static void UpdateTownGrowth(Town *t)
3821{
3823
3826
3828
3829 if (t->fund_buildings_months == 0) {
3830 /* Check if all goals are reached for this town to grow (given we are not funding it) */
3831 for (int i = TAE_BEGIN; i < TAE_END; i++) {
3832 switch (t->goal[i]) {
3833 case TOWN_GROWTH_WINTER:
3834 if (TileHeight(t->xy) >= GetSnowLine() && t->received[i].old_act == 0 && t->cache.population > 90) return;
3835 break;
3836 case TOWN_GROWTH_DESERT:
3837 if (GetTropicZone(t->xy) == TROPICZONE_DESERT && t->received[i].old_act == 0 && t->cache.population > 60) return;
3838 break;
3839 default:
3840 if (t->goal[i] > t->received[i].old_act) return;
3841 break;
3842 }
3843 }
3844 }
3845
3846 if (HasBit(t->flags, TOWN_CUSTOM_GROWTH)) {
3849 return;
3850 }
3851
3852 if (t->fund_buildings_months == 0 && CountActiveStations(t) == 0 && !Chance16(1, 12)) return;
3853
3856}
3857
3865{
3866 /* The required rating is hardcoded to RATING_VERYPOOR (see below), not the authority attitude setting, so we can bail out like this. */
3867 if (_settings_game.difficulty.town_council_tolerance == TOWN_COUNCIL_PERMISSIVE) return CommandCost();
3868
3870
3872 if (t == nullptr) return CommandCost();
3873
3874 if (t->ratings[_current_company] > RATING_VERYPOOR) return CommandCost();
3875
3876 SetDParam(0, t->index);
3877 return CommandCost(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS);
3878}
3879
3889{
3890 if (Town::GetNumItems() == 0) return nullptr;
3891
3892 TownID tid = _town_kdtree.FindNearest(TileX(tile), TileY(tile));
3893 Town *town = Town::Get(tid);
3894 if (DistanceManhattan(tile, town->xy) < threshold) return town;
3895 return nullptr;
3896}
3897
3906Town *ClosestTownFromTile(TileIndex tile, uint threshold)
3907{
3908 switch (GetTileType(tile)) {
3909 case MP_ROAD:
3910 if (IsRoadDepot(tile)) return CalcClosestTownFromTile(tile, threshold);
3911
3912 if (!HasTownOwnedRoad(tile)) {
3913 TownID tid = GetTownIndex(tile);
3914
3915 if (tid == INVALID_TOWN) {
3916 /* in the case we are generating "many random towns", this value may be INVALID_TOWN */
3917 if (_generating_world) return CalcClosestTownFromTile(tile, threshold);
3918 assert(Town::GetNumItems() == 0);
3919 return nullptr;
3920 }
3921
3922 assert(Town::IsValidID(tid));
3923 Town *town = Town::Get(tid);
3924
3925 if (DistanceManhattan(tile, town->xy) >= threshold) town = nullptr;
3926
3927 return town;
3928 }
3929 [[fallthrough]];
3930
3931 case MP_HOUSE:
3932 return Town::GetByTile(tile);
3933
3934 default:
3935 return CalcClosestTownFromTile(tile, threshold);
3936 }
3937}
3938
3939static bool _town_rating_test = false;
3940static std::map<const Town *, int> _town_test_ratings;
3941
3948{
3949 static int ref_count = 0; // Number of times test-mode is switched on.
3950 if (mode) {
3951 if (ref_count == 0) {
3952 _town_test_ratings.clear();
3953 }
3954 ref_count++;
3955 } else {
3956 assert(ref_count > 0);
3957 ref_count--;
3958 }
3959 _town_rating_test = !(ref_count == 0);
3960}
3961
3967static int GetRating(const Town *t)
3968{
3969 if (_town_rating_test) {
3970 auto it = _town_test_ratings.find(t);
3971 if (it != _town_test_ratings.end()) {
3972 return it->second;
3973 }
3974 }
3975 return t->ratings[_current_company];
3976}
3977
3985void ChangeTownRating(Town *t, int add, int max, DoCommandFlag flags)
3986{
3987 /* if magic_bulldozer cheat is active, town doesn't penalize for removing stuff */
3988 if (t == nullptr || (flags & DC_NO_MODIFY_TOWN_RATING) ||
3990 (_cheats.magic_bulldozer.value && add < 0)) {
3991 return;
3992 }
3993
3994 int rating = GetRating(t);
3995 if (add < 0) {
3996 if (rating > max) {
3997 rating += add;
3998 if (rating < max) rating = max;
3999 }
4000 } else {
4001 if (rating < max) {
4002 rating += add;
4003 if (rating > max) rating = max;
4004 }
4005 }
4006 if (_town_rating_test) {
4007 _town_test_ratings[t] = rating;
4008 } else {
4010 t->ratings[_current_company] = rating;
4012 }
4013}
4014
4023{
4024 /* if magic_bulldozer cheat is active, town doesn't restrict your destructive actions */
4025 if (t == nullptr || !Company::IsValidID(_current_company) ||
4027 return CommandCost();
4028 }
4029
4030 /* minimum rating needed to be allowed to remove stuff */
4031 static const int needed_rating[][TOWN_RATING_CHECK_TYPE_COUNT] = {
4032 /* ROAD_REMOVE, TUNNELBRIDGE_REMOVE */
4037 };
4038
4039 /* check if you're allowed to remove the road/bridge/tunnel
4040 * owned by a town no removal if rating is lower than ... depends now on
4041 * difficulty setting. Minimum town rating selected by difficulty level
4042 */
4043 int needed = needed_rating[_settings_game.difficulty.town_council_tolerance][type];
4044
4045 if (GetRating(t) < needed) {
4046 SetDParam(0, t->index);
4047 return CommandCost(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS);
4048 }
4049
4050 return CommandCost();
4051}
4052
4053static IntervalTimer<TimerGameEconomy> _economy_towns_monthly({TimerGameEconomy::MONTH, TimerGameEconomy::Priority::TOWN}, [](auto)
4054{
4055 for (Town *t : Town::Iterate()) {
4056 /* Check for active town actions and decrement their counters. */
4057 if (t->road_build_months != 0) t->road_build_months--;
4059
4060 if (t->exclusive_counter != 0) {
4061 if (--t->exclusive_counter == 0) t->exclusivity = INVALID_COMPANY;
4062 }
4063
4064 /* Check for active failed bribe cooloff periods and decrement them. */
4065 for (const Company *c : Company::Iterate()) {
4066 if (t->unwanted[c->index] > 0) t->unwanted[c->index]--;
4067 }
4068
4069 /* Update cargo statistics. */
4070 for (auto &supplied : t->supplied) supplied.NewMonth();
4071 for (auto &received : t->received) received.NewMonth();
4072
4075
4077 }
4078});
4079
4080static IntervalTimer<TimerGameEconomy> _economy_towns_yearly({TimerGameEconomy::YEAR, TimerGameEconomy::Priority::TOWN}, [](auto)
4081{
4082 /* Increment house ages */
4083 for (const auto t : Map::Iterate()) {
4084 if (!IsTileType(t, MP_HOUSE)) continue;
4086 }
4087});
4088
4089static CommandCost TerraformTile_Town(TileIndex tile, DoCommandFlag flags, int z_new, Slope tileh_new)
4090{
4091 if (AutoslopeEnabled()) {
4092 HouseID house = GetHouseType(tile);
4093 GetHouseNorthPart(house); // modifies house to the ID of the north tile
4094 const HouseSpec *hs = HouseSpec::Get(house);
4095
4096 /* Here we differ from TTDP by checking BuildingFlag::NotSloped */
4097 if (!hs->building_flags.Test(BuildingFlag::NotSloped) && !IsSteepSlope(tileh_new) &&
4098 (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) {
4099 bool allow_terraform = true;
4100
4101 /* Call the autosloping callback per tile, not for the whole building at once. */
4102 house = GetHouseType(tile);
4103 hs = HouseSpec::Get(house);
4105 /* If the callback fails, allow autoslope. */
4106 uint16_t res = GetHouseCallback(CBID_HOUSE_AUTOSLOPE, 0, 0, house, Town::GetByTile(tile), tile);
4107 if (res != CALLBACK_FAILED && ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_AUTOSLOPE, res)) allow_terraform = false;
4108 }
4109
4110 if (allow_terraform) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
4111 }
4112 }
4113
4114 return Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
4115}
4116
4118extern const TileTypeProcs _tile_type_town_procs = {
4119 DrawTile_Town, // draw_tile_proc
4120 GetSlopePixelZ_Town, // get_slope_z_proc
4121 ClearTile_Town, // clear_tile_proc
4122 AddAcceptedCargo_Town, // add_accepted_cargo_proc
4123 GetTileDesc_Town, // get_tile_desc_proc
4124 GetTileTrackStatus_Town, // get_tile_track_status_proc
4125 nullptr, // click_tile_proc
4126 AnimateTile_Town, // animate_tile_proc
4127 TileLoop_Town, // tile_loop_proc
4128 ChangeTileOwner_Town, // change_tile_owner_proc
4129 AddProducedCargo_Town, // add_produced_cargo_proc
4130 nullptr, // vehicle_enter_tile_proc
4131 GetFoundation_Town, // get_foundation_proc
4132 TerraformTile_Town, // terraform_tile_proc
4133};
4134
4135std::span<const DrawBuildingsTileStruct> GetTownDrawTileData()
4136{
4137 return _town_draw_tile_data;
4138}
Base functions for all AIs.
@ AT_OILRIG
Oilrig airport.
Definition airport.h:38
void AddAnimatedTile(TileIndex tile, bool mark_dirty)
Add the given tile to the animated tile table (if it does not exist yet).
void DeleteAnimatedTile(TileIndex tile, bool immediate)
Stops animation on the given tile.
Tile animation!
Functions related to autoslope.
bool AutoslopeEnabled()
Tests if autoslope is enabled for _current_company.
Definition autoslope.h:65
Class for backupping variables and making sure they are restored later.
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
constexpr uint CountBits(T value)
Counts the number of set bits in a variable.
debug_inline static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
constexpr T ClrBit(T &x, const uint8_t y)
Clears a bit in a variable.
static const uint MAX_BRIDGES
Maximal number of available bridge specs.
Definition bridge.h:35
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:22
bool IsValidCargoType(CargoType t)
Test whether cargo type is not INVALID_CARGO.
Definition cargo_type.h:105
@ Town
Source/destination is a town.
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=MAX_COMPANIES)
Broadcast a new event to all active AIs.
Definition ai_core.cpp:263
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.
constexpr bool Any(const EnumBitSet &other) const
Test if any of the enum values are set.
constexpr bool Test(Tenum value) const
Test if the enum value is set.
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:35
void Build(It begin, It end)
Clear and rebuild the tree from a new sequence of elements,.
Definition kdtree.hpp:362
size_t Count() const
Get number of elements stored in tree.
Definition kdtree.hpp:430
void Insert(const T &element)
Insert a single element in the tree.
Definition kdtree.hpp:398
void Remove(const T &element)
Remove a single element from the tree, if it exists.
Definition kdtree.hpp:417
T FindNearest(CoordT x, CoordT y) const
Find the element closest to given coordinate, in Manhattan distance.
Definition kdtree.hpp:441
RoadTypeLabel label
Unique 32 bit road type identifier.
Definition road.h:137
TimerGameCalendar::Date introduction_date
Introduction date.
Definition road.h:156
RoadTypeFlags flags
Bit mask of road type flags.
Definition road.h:117
uint16_t max_speed
Maximum speed for vehicles travelling on this road type.
Definition road.h:132
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.
static bool UsingWallclockUnits(bool newgame=false)
Check if we are using wallclock units.
static TickCounter counter
Monotonic counter, in ticks, since start of game.
Functions related to commands.
static constexpr DoCommandFlag 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.
DoCommandFlag
List of flags for a command.
@ DC_NONE
no flag is set
@ DC_NO_TEST_TOWN_RATING
town rating does not disallow you from building
@ DC_AUTO
don't allow building on structures
@ DC_NO_WATER
don't allow building on water
@ DC_NO_MODIFY_TOWN_RATING
do not change town rating
@ DC_EXEC
execute the given command
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?
Owner
Enum for all companies/owners.
@ INVALID_COMPANY
An invalid company.
@ COMPANY_SPECTATOR
The client is spectating.
@ OWNER_DEITY
The object is owned by a superuser / goal script.
@ OWNER_NONE
The tile has no ownership.
@ OWNER_TOWN
A town owns the tile, or a town is expanding.
@ MAX_COMPANIES
Maximum number of companies.
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:15
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(StringID 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:69
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:77
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:1529
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_height_override)
Mark a tile given by its index dirty for repaint.
@ BuildingIsHistorical
this house will only appear during town generation in random games, thus the historical
static const HouseID NEW_HOUSE_OFFSET
Offset for new houses.
Definition house.h:27
static const uint8_t TOWN_HOUSE_COMPLETED
Simple value that indicates the house has reached the final stage of construction.
Definition house.h:24
uint16_t HouseID
OpenTTD ID of house types.
Definition house_type.h:13
Base of all industries.
void DrawFoundation(TileInfo *ti, Foundation f)
Draw foundation f at tile ti.
std::tuple< Slope, int > GetFoundationSlope(TileIndex tile)
Get slope of a tile on top of a (possible) foundation If a tile does not have a foundation,...
Functions related to OTTD's landscape.
Point RemapCoords2(int x, int y)
Map 3D world or tile coordinate to equivalent 2D coordinate as used in the viewports and smallmap.
Definition landscape.h:95
Command definitions related to landscape (slopes etc.).
@ Random
Randomise borders.
bool CircularTileSearch(TileIndex *tile, uint size, TestTileOnSearchProc proc, void *user_data)
Function performing a search around a center tile and going outward, thus in circle.
Definition map.cpp:244
uint DistanceSquare(TileIndex t0, TileIndex t1)
Gets the 'Square' distance between the two given tiles.
Definition map.cpp:160
uint DistanceFromEdge(TileIndex tile)
Param the minimum distance to an edge.
Definition map.cpp:203
uint DistanceManhattan(TileIndex t0, TileIndex t1)
Gets the Manhattan distance between the two given tiles.
Definition map.cpp:143
uint GetClosestWaterDistance(TileIndex tile, bool water)
Finds the distance for the closest tile with water/land given a tile.
Definition map.cpp:326
TileIndex TileAddXY(TileIndex tile, int x, int y)
Adds a given offset to a tile.
Definition map_func.h:470
TileIndex TileAddByDir(TileIndex tile, Direction dir)
Adds a Direction to a tile.
Definition map_func.h:599
static debug_inline TileIndex TileXY(uint x, uint y)
Returns the TileIndex of a coordinate.
Definition map_func.h:373
TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc)
Return the offset between two tiles from a TileIndexDiffC struct.
Definition map_func.h:440
TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir)
Adds a DiagDir to a tile.
Definition map_func.h:611
TileIndexDiff TileDiffXY(int x, int y)
Calculates an offset for the given coordinate(-offset).
Definition map_func.h:389
constexpr TileIndex TileAdd(TileIndex tile, TileIndexDiff offset)
Adds a given offset to a tile.
Definition map_func.h:457
#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:425
static debug_inline uint TileX(TileIndex tile)
Get the X component of a tile.
Definition map_func.h:415
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition map_func.h:570
TileIndexDiffC TileIndexToTileIndexDiffC(TileIndex tile_a, TileIndex tile_b)
Returns the diff between two tiles.
Definition map_func.h:531
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:92
@ 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(StringID string, NewsType type, NewsFlag flags, NewsReferenceType reftype1=NR_NONE, uint32_t ref1=UINT32_MAX, NewsReferenceType reftype2=NR_NONE, uint32_t ref2=UINT32_MAX, std::unique_ptr< NewsAllocatedData > &&data=nullptr, AdviceType advice_type=AdviceType::Invalid)
Add a new newsitem to be shown.
Definition news_gui.cpp:899
@ NT_INDUSTRY_OPEN
Opening of industries.
Definition news_type.h:29
@ NT_GENERAL
General news (from towns)
Definition news_type.h:39
@ NR_TOWN
Reference town. Scroll to town when clicking on the news.
Definition news_type.h:73
@ NR_NONE
Empty reference.
Definition news_type.h:68
@ NF_COMPANY
Company news item. (Newspaper with face)
Definition news_type.h:98
@ NF_NORMAL
Normal news item. (Newspaper with text only)
Definition news_type.h:96
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:18
Some methods of Pool are placed here in order to reduce compilation time and binary size.
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don't get linker errors.
static debug_inline bool IsPlainRailTile(Tile t)
Checks whether the tile is a rail tile or rail tile with signals.
Definition rail_map.h:60
Randomizer _random
Random used in the game state calculations.
Pseudo random number generator.
uint32_t RandomRange(uint32_t limit, const std::source_location location=std::source_location::current())
Pick a random number between 0 and limit - 1, inclusive.
bool Chance16(const uint32_t a, const uint32_t b, const std::source_location location=std::source_location::current())
Flips a coin with given probability.
RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb)
Clean up unnecessary RoadBits of a planned tile.
Definition road.cpp:47
Road specific functions.
@ NoHouses
Bit number for setting this roadtype as not house friendly.
@ TownBuild
Bit number for allowing towns to build this roadtype.
const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
Definition road.h:217
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:33
void SetRoadOwner(Tile t, RoadTramType rtt, Owner o)
Set the owner of a specific road type.
Definition road_map.h:251
bool HasTownOwnedRoad(Tile t)
Checks if given tile has town owned road.
Definition road_map.h:280
static debug_inline bool IsNormalRoadTile(Tile t)
Return whether a tile is a normal road tile.
Definition road_map.h:74
static debug_inline bool IsRoadDepot(Tile t)
Return whether a tile is a road depot.
Definition road_map.h:106
DisallowedRoadDirections GetDisallowedRoadDirections(Tile t)
Gets the disallowed directions.
Definition road_map.h:301
bool HasTileRoadType(Tile t, RoadTramType rtt)
Check if a tile has a road or a tram road type.
Definition road_map.h:211
DiagDirection GetRoadDepotDirection(Tile t)
Get the direction of the exit of a road depot.
Definition road_map.h:565
static debug_inline bool IsRoadDepotTile(Tile t)
Return whether a tile is a road depot tile.
Definition road_map.h:116
bool IsRoadOwner(Tile t, RoadTramType rtt, Owner o)
Check if a specific road type is owned by an owner.
Definition road_map.h:268
RoadBits
Enumeration for the road parts on a tile.
Definition road_type.h:52
@ ROAD_SW
South-west part.
Definition road_type.h:55
@ ROAD_ALL
Full 4-way crossing.
Definition road_type.h:66
@ ROAD_NONE
No road-part is build.
Definition road_type.h:53
@ ROAD_E
Road at the two eastern edges.
Definition road_type.h:62
@ ROAD_NE
North-east part.
Definition road_type.h:57
@ ROAD_N
Road at the two northern edges.
Definition road_type.h:61
@ ROAD_SE
South-east part.
Definition road_type.h:56
@ ROAD_Y
Full road along the y-axis (north-west + south-east)
Definition road_type.h:59
@ ROAD_S
Road at the two southern edges.
Definition road_type.h:63
@ ROAD_W
Road at the two western edges.
Definition road_type.h:64
@ ROAD_NW
North-west part.
Definition road_type.h:54
@ ROAD_X
Full road along the x-axis (south-west + north-east)
Definition road_type.h:58
RoadType
The different roadtypes we support.
Definition road_type.h:25
@ INVALID_ROADTYPE
flag for invalid roadtype
Definition road_type.h:30
@ ROADTYPE_ROAD
Basic road type.
Definition road_type.h:27
@ ROADTYPE_END
Used for iterations.
Definition road_type.h:29
@ ROADTYPE_BEGIN
Used for iterations.
Definition road_type.h:26
@ DRD_NONE
None of the directions are disallowed.
Definition road_type.h:74
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:57
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:56
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
Base classes/functions for stations.
void ForAllStationsAroundTiles(const TileArea &ta, Func func)
Call a function on all stations that have any part of the requested area within their catchment.
void UpdateAllStationVirtCoords()
Update the virtual coords needed to draw the station sign for all stations.
void UpdateAirportsNoise()
Recalculate the noise generated by the airports of each town.
Declarations for accessing the k-d tree of stations.
void ForAllStationsRadius(TileIndex center, uint radius, Func func)
Call a function on all stations whose sign is within a radius of a center tile.
bool IsBayRoadStopTile(Tile t)
Is tile t a bay (non-drive through) road stop station?
bool IsDriveThroughStopTile(Tile t)
Is tile t a drive through road stop station or waypoint?
Axis GetDriveThroughStopAxis(Tile t)
Gets the axis of the drive through stop.
DiagDirection GetBayRoadStopDir(Tile t)
Gets the direction the bay road stop entrance points towards.
bool IsAnyRoadStopTile(Tile t)
Is tile t a road stop station?
@ FACIL_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:277
size_t Utf8StringLength(const char *s)
Get the length of an UTF-8 encoded string in number of characters and thus not the number of bytes th...
Definition string.cpp:359
Functions related to low-level strings.
void SetDParam(size_t n, uint64_t v)
Set a string parameter v at index n in the global string parameter array.
Definition strings.cpp:104
std::string GetString(StringID string)
Resolve the given StringID into a std::string with all the associated DParam lookups and formatting.
Definition strings.cpp:332
void SetDParamStr(size_t n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
Definition strings.cpp:370
Functions related to OTTD's strings.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
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:112
static void InvalidateAllFrom(SourceType src_type, SourceID src)
Invalidates (sets source_id to INVALID_SOURCE) all cargo packets from given source.
Specification of a cargo type.
Definition cargotype.h:77
static IterateWrapper Iterate(size_t from=0)
Returns an iterable ensemble of all valid CargoSpec.
Definition cargotype.h:196
static std::array< std::vector< const CargoSpec * >, NUM_TPE > town_production_cargoes
List of cargo specs for each Town Product Effect.
Definition cargotype.h:27
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
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:67
bool bribe
enable bribing the local authority
TownFounding found_town
town founding.
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.
const char * GetName() const
Get the name of this grf.
bool HasGrfFile() const
Test if this entity was introduced by NewGRF.
uint32_t grfid
grfid that introduced this entity.
const struct GRFFile * grffile
grf file that introduced this entity
std::array< const struct SpriteGroup *, Tcnt > spritegroup
pointers to the different sprites of the entity
uint16_t override
id of the entity been replaced by
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:102
uint8_t probability
Relative probability of appearing (16 is the standard value)
Definition house.h:111
uint8_t removal_cost
cost multiplier for removing it
Definition house.h:97
uint8_t mail_generation
mail generation multiplier (tile based, as the acceptances below)
Definition house.h:100
bool enabled
the house is available to build (true by default, but can be disabled by newgrf)
Definition house.h:105
Money GetRemovalCost() const
Get the cost for removing this house.
Definition town_cmd.cpp:225
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:103
TimerGameCalendar::Year max_year
last year it can be built
Definition house.h:95
HouseCallbackMasks callback_mask
Bitmask of house callbacks that have to be called.
Definition house.h:109
uint16_t remove_rating_decrease
rating decrease if removed
Definition house.h:99
uint8_t population
population (Zero on other tiles in multi tile house.)
Definition house.h:96
HouseExtraFlags extra_flags
some more flags
Definition house.h:112
uint8_t cargo_acceptance[HOUSE_NUM_ACCEPTS]
acceptance level for the cargo slots
Definition house.h:101
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:113
StringID building_name
building name
Definition house.h:98
uint8_t minimum_life
The minimum number of years this house will survive before the town rebuilds it.
Definition house.h:116
GRFFileProps grf_prop
Properties related the the grf file.
Definition house.h:108
HouseZones building_availability
where can it be built (climates, zones)
Definition house.h:104
static std::vector< HouseSpec > & Specs()
Get a reference to all HouseSpecs.
Defines the internal data of a functional industry.
Definition industry.h:66
Town * town
Nearest town.
Definition industry.h:95
static Industry * GetByTile(TileIndex tile)
Get the industry of the given tile.
Definition industry.h:238
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:328
static IterateWrapper Iterate()
Returns an iterable ensemble of all Tiles.
Definition map_func.h:363
static debug_inline uint Size()
Get the size of the map.
Definition map_func.h:288
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
Coordinates of a point in 2D.
static size_t GetPoolSize()
Returns first unused index.
Tindex index
Index of this pool item.
static size_t GetNumItems()
Returns number of valid items in the pool.
static bool CleaningPool()
Returns current state of pool cleaning - yes or no.
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
static Titem * GetIfValid(size_t index)
Returns Titem with given index.
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
static Titem * Get(size_t index)
Returns Titem with given index.
Base class for all pools.
Definition pool_type.hpp:79
static constexpr size_t MAX_SIZE
Make template parameter accessible from outside.
Definition pool_type.hpp:90
static Pool::IterateWrapper< Station > Iterate(size_t from=0)
Returns an iterable ensemble of all valid stations of type T.
Used as the user_data for FindFurthestFromWater.
uint max_dist
holds the distance that tile is from the water
TownLayout layout
tells us what kind of town we're building
TileIndex tile
holds the tile that was found
Station data structure.
bool CatchmentCoversTown(TownID t) const
Test if the given town ID is covered by our catchment area.
Definition station.cpp:451
Structure for storing data while searching the best place to build a statue.
int tile_count
Number of tiles tried.
TileIndex best_position
Best position found so far.
Tile description for the 'land area information' tool.
Definition tile_cmd.h:52
StringID str
Description of the tile.
Definition tile_cmd.h:53
uint64_t dparam
Parameter of the str string.
Definition tile_cmd.h:54
const char * grf
newGRF used for the tile contents
Definition tile_cmd.h:63
Owner owner[4]
Name of the owner(s)
Definition tile_cmd.h:55
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:43
int z
Height.
Definition tile_cmd.h:48
int x
X position of the tile in unit coordinates.
Definition tile_cmd.h:44
Slope tileh
Slope of the tile.
Definition tile_cmd.h:46
TileIndex tile
Tile index.
Definition tile_cmd.h:47
int y
Y position of the tile in unit coordinates.
Definition tile_cmd.h:45
Set of callback functions for performing tile operations of a given tile type.
Definition tile_cmd.h:158
uint32_t population
Current population of people.
Definition town.h:42
uint32_t num_houses
Amount of houses.
Definition town.h:41
std::array< uint32_t, HZB_END > squared_town_zone_radius
UpdateTownRadius updates this given the house count.
Definition town.h:45
TrackedViewportSign sign
Location of name sign, UpdateVirtCoord updates this.
Definition town.h:43
BuildingCounts< uint16_t > building_counts
The number of each type of building in the town.
Definition town.h:46
Struct holding parameters used to generate town name.
uint16_t type
town name style
uint32_t grfid
newgrf ID (0 if not used)
Town data structure.
Definition town.h:52
bool larger_town
if this is a larger town and should grow more quickly
Definition town.h:99
TransportedCargoStat< uint32_t > supplied[NUM_CARGO]
Cargo statistics about supplied cargo.
Definition town.h:77
CompanyMask statues
which companies have a statue?
Definition town.h:68
uint16_t time_until_rebuild
time until we rebuild a house
Definition town.h:91
std::string cached_name
NOSAVE: Cache of the resolved name of the town, if not using a custom town name.
Definition town.h:62
TileIndex xy
town center tile
Definition town.h:53
uint8_t fund_buildings_months
fund buildings program in action?
Definition town.h:96
int16_t ratings[MAX_COMPANIES]
ratings of each company for this town
Definition town.h:75
TownLayout layout
town specific road layout
Definition town.h:100
TransportedCargoStat< uint16_t > received[NUM_TAE]
Cargo statistics about received cargotypes.
Definition town.h:78
static Town * GetRandom()
Return a random valid town.
Definition town_cmd.cpp:196
std::string name
Custom town name. If empty, the town was not renamed and uses the generated name.
Definition town.h:61
uint16_t grow_counter
counter to count when to grow, value is smaller than or equal to growth_rate
Definition town.h:93
uint8_t flags
See TownFlags.
Definition town.h:64
TownCache cache
Container for all cacheable data.
Definition town.h:55
CompanyID exclusivity
which company has exclusivity
Definition town.h:73
void InitializeLayout(TownLayout layout)
Assign the town layout.
Definition town_cmd.cpp:182
bool show_zone
NOSAVE: mark town to show the local authority zone in the viewports.
Definition town.h:102
uint32_t goal[NUM_TAE]
Amount of cargo required for the town to grow.
Definition town.h:79
uint8_t exclusive_counter
months till the exclusivity expires
Definition town.h:74
void UpdateVirtCoord()
Resize the sign (label) of the town after it changes population.
Definition town_cmd.cpp:409
std::string text
General text with additional information.
Definition town.h:81
CompanyMask have_ratings
which companies have a rating
Definition town.h:71
~Town()
Destroy the town.
Definition town_cmd.cpp:110
uint8_t unwanted[MAX_COMPANIES]
how many months companies aren't wanted by towns (bribe)
Definition town.h:72
uint16_t growth_rate
town growth rate
Definition town.h:94
StationList stations_near
NOSAVE: List of nearby stations.
Definition town.h:89
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:167
uint8_t road_build_months
fund road reconstruction in action?
Definition town.h:97
void UpdatePosition(int center, int top, StringID str, StringID str_small=STR_NULL)
Update the position of the viewport sign.
bool kdtree_valid
Are the sign data valid for use with the _viewport_sign_kdtree?
Tstorage new_max
Maximum amount this month.
Definition town_type.h:117
Tstorage old_max
Maximum amount last month.
Definition town_type.h:116
Tstorage old_act
Actually transported last month.
Definition town_type.h:118
Tstorage new_act
Actually transported this month.
Definition town_type.h:119
Representation of a waypoint.
void DeleteSubsidyWith(SourceType type, SourceID index)
Delete the subsidies associated with a given cargo source type and id.
Definition subsidy.cpp:151
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
static const uint TILE_SIZE
Tile size in world coordinates.
Definition tile_type.h:15
@ 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
@ 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:31
static const uint TOWN_GROWTH_DESERT
The town needs the cargo for growth when on desert (any amount)
Definition town.h:32
@ TOWN_HAS_CHURCH
There can be only one church by town.
Definition town.h:195
@ TOWN_HAS_STADIUM
There can be only one stadium by town.
Definition town.h:196
@ TOWN_IS_GROWING
Conditions for town growth are met. Grow according to Town::growth_rate.
Definition town.h:194
@ TOWN_CUSTOM_GROWTH
Growth rate is controlled by GS.
Definition town.h:197
TownRatingCheckType
Action types that a company must ask permission for to a town authority.
Definition town.h:173
@ TOWN_RATING_CHECK_TYPE_COUNT
Number of town checking action types.
Definition town.h:176
TownActions
Town actions of a company.
Definition town.h:210
@ TACT_BUILD_STATUE
Build a statue.
Definition town.h:217
@ TACT_ROAD_REBUILD
Rebuild the roads.
Definition town.h:216
@ TACT_BUY_RIGHTS
Buy exclusive transport rights.
Definition town.h:219
@ TACT_BRIBE
Try to bribe the council.
Definition town.h:220
@ TACT_COUNT
Number of available town actions.
Definition town.h:222
@ TACT_FUND_BUILDINGS
Fund new buildings.
Definition town.h:218
@ TACT_NONE
Empty action set.
Definition town.h:211
static const uint CUSTOM_TOWN_NUMBER_DIFFICULTY
value for custom town number in difficulty settings
Definition town.h:28
Town * CalcClosestTownFromTile(TileIndex tile, uint threshold=UINT_MAX)
Return the town closest to the given tile within threshold.
static const uint16_t TOWN_GROWTH_RATE_NONE
Special value for Town::growth_rate to disable town growth.
Definition town.h:33
static bool RoadTypesAllowHouseHere(TileIndex t)
Checks whether at least one surrounding road allows to build a house here.
std::tuple< CommandCost, Money, TownID > CmdFoundTown(DoCommandFlag flags, TileIndex tile, TownSize size, bool city, TownLayout layout, bool random_location, uint32_t townnameparts, const std::string &text)
Create a new town.
static bool CheckFree2x2Area(TileIndex tile, int z, bool noslope)
Checks if a house of size 2x2 can be built at this tile.
static bool TownLayoutAllows2x2HouseHere(Town *t, TileIndex tile)
Checks if the current town layout allows a 2x2 building here.
static void ClearMakeHouseTile(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits)
Clears tile and builds a house or house part.
HouseZonesBits GetTownRadiusGroup(const Town *t, TileIndex tile)
Returns the bit corresponding to the town zone of the specified tile.
static bool GrowTownWithExtraHouse(Town *t, TileIndex tile)
Grows the town with an extra house.
static bool SearchTileForStatue(TileIndex tile, void *user_data)
Search callback function for TownActionBuildStatue.
static bool FindNearestEmptyLand(TileIndex tile, void *)
CircularTileSearch callback to find the nearest land tile.
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 TownActionBribe(Town *t, DoCommandFlag flags)
Perform the "bribe" town action.
CommandCost CmdRenameTown(DoCommandFlag flags, TownID town_id, const std::string &text)
Rename a town (server-only).
TileIndexDiff GetHouseNorthPart(HouseID &house)
Determines if a given HouseID is part of a multitile house.
static CommandCost TownActionAdvertiseLarge(Town *t, DoCommandFlag flags)
Perform the "large advertising campaign" town action.
static CommandCost TownActionAdvertiseSmall(Town *t, DoCommandFlag flags)
Perform the "small advertising campaign" town action.
static int GetRating(const Town *t)
Get the rating of a town for the _current_company.
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 ClearTile_Town(TileIndex tile, DoCommandFlag flags)
Callback function to clear a house tile.
Definition town_cmd.cpp:717
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.
CommandCost CmdTownGrowthRate(DoCommandFlag flags, TownID town_id, uint16_t growth_rate)
Change the growth rate of the town.
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.
CommandCost CmdTownRating(DoCommandFlag flags, TownID town_id, CompanyID company_id, int16_t rating)
Change the rating of a company in a town.
static void UpdateTownGrowCounter(Town *t, uint16_t prev_growth_rate)
Updates town grow counter after growth rate change.
CommandCost CmdTownCargoGoal(DoCommandFlag flags, TownID town_id, TownAcceptanceEffect tae, uint32_t goal)
Change the cargo goal of a town.
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 _generating_town
Set if a town is being generated.
Definition town_cmd.cpp:83
static bool CanFollowRoad(TileIndex tile, DiagDirection dir)
Checks whether a road can be followed or is a dead end, that can not be extended to the next tile.
static bool RedundantBridgeExistsNearby(TileIndex tile, void *user_data)
CircularTileSearch proc which checks for a nearby parallel bridge to avoid building redundant bridges...
static bool TownLayoutAllowsHouseHere(Town *t, TileIndex tile)
Checks if the current town layout allows building here.
static void TileLoop_Town(TileIndex tile)
Tile callback function.
Definition town_cmd.cpp:605
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 CommandCost TownActionAdvertiseMedium(Town *t, DoCommandFlag flags)
Perform the "medium advertising campaign" town action.
static bool GrowTownWithRoad(const Town *t, TileIndex tile, RoadBits rcmd)
Grows the town with a road piece.
CommandCost CmdDeleteTown(DoCommandFlag flags, TownID town_id)
Delete a town (scenario editor or worldgen only).
static void UpdateTownRating(Town *t)
Monthly callback to update town and station ratings.
static void AdvanceHouseConstruction(TileIndex tile)
Increase the construction stage of a house.
Definition town_cmd.cpp:521
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:462
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 bool CheckClearTile(TileIndex tile)
Check whether the land can be cleared.
const uint8_t _town_action_costs[TACT_COUNT]
Factor in the cost of each town action.
static CommandCost TownActionRoadRebuild(Town *t, DoCommandFlag flags)
Perform the "local road reconstruction" town action.
static CommandCost TownActionFundBuildings(Town *t, DoCommandFlag flags)
Perform the "fund new buildings" 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:562
void UpdateTownMaxPass(Town *t)
Update the maximum amount of montly 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:447
static bool CheckTownBuild2x2House(TileIndex *tile, Town *t, int maxz, bool noslope)
Checks if a 1x2 or 2x1 building is allowed here, accounting for road layout and tile heights.
CargoArray GetAcceptedCargoOfHouse(const HouseSpec *hs)
Get accepted cargo of a house prototype.
Definition town_cmd.cpp:860
static bool TownAllowedToBuildRoads()
Check if the town is allowed to build roads.
static bool IsNeighborRoadTile(TileIndex tile, const DiagDirection dir, uint dist_multi)
Check for parallel road inside a given distance.
static bool GrowTown(Town *t)
Grow the town.
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:791
static DiagDirection RandomDiagDir()
Return a random direction.
Definition town_cmd.cpp:258
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:476
static bool GrowTownAtRoad(Town *t, TileIndex tile)
Try to grow a town at a given road tile.
Town * CalcClosestTownFromTile(TileIndex tile, uint threshold)
Return the town closest to the given tile within threshold.
void ClearAllTownCachedNames()
Clear the cached_name of all towns.
Definition town_cmd.cpp:435
void ChangeTownRating(Town *t, int add, int max, DoCommandFlag flags)
Changes town rating of the current company.
static bool FindFurthestFromWater(TileIndex tile, void *user_data)
CircularTileSearch callback; finds the tile furthest from any water.
static Foundation GetFoundation_Town(TileIndex tile, Slope tileh)
Get the foundation for a house.
Definition town_cmd.cpp:326
static TimerGameCalendar::Date GetTownRoadTypeFirstIntroductionDate()
Get the calendar date of the earliest town-buildable road type.
Definition town_cmd.cpp:995
static void AnimateTile_Town(TileIndex tile)
Animate a tile for a town.
Definition town_cmd.cpp:350
CommandCost CmdDoTownAction(DoCommandFlag flags, TownID town_id, uint8_t action)
Do a town action.
const TileTypeProcs _tile_type_town_procs
Tile callback functions for a town.
Definition landscape.cpp:51
RoadType GetTownRoadType()
Get the road type that towns should build at this current moment.
Definition town_cmd.cpp:960
static RoadBits GetTownRoadBits(TileIndex tile)
Return the RoadBits of a tile, ignoring depot and bay road stops.
Definition town_cmd.cpp:949
CommandCost CmdExpandTown(DoCommandFlag flags, TownID town_id, uint32_t grow_amount)
Expand a town (scenario editor only).
static CommandCost TownActionBuyRights(Town *t, DoCommandFlag flags)
Perform the "buy exclusive transport rights" town action.
static void DoCreateTown(Town *t, TileIndex tile, uint32_t townnameparts, TownSize size, bool city, TownLayout layout, bool manual)
Actually create a town.
static bool TryBuildTownHouse(Town *t, TileIndex tile)
Tries to build a house at this tile.
static bool TestTownOwnsBridge(TileIndex tile, const Town *t)
Check if a town 'owns' a bridge.
Definition town_cmd.cpp:94
void OnTick_Town()
Iterate through all towns and call their tick handler.
Definition town_cmd.cpp:935
bool CheckTownRoadTypes()
Check if towns are able to build road.
bool GenerateTowns(TownLayout layout)
Generate a number of towns with a given layout.
CommandCost CheckIfAuthorityAllowsNewStation(TileIndex tile, DoCommandFlag flags)
Checks whether the local authority allows construction of a new station (rail, road,...
CommandCost CheckforTownRating(DoCommandFlag flags, Town *t, TownRatingCheckType type)
Does the town authority allow the (destructive) action of the current company?
static bool CheckTownBuild2House(TileIndex *tile, Town *t, int maxz, bool noslope, DiagDirection second)
Checks if a 1x2 or 2x1 building is allowed here, accounting for road layout and tile heights.
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:498
static void TownTickHandler(Town *t)
Handle the town tick for a single town, by growing the town if desired.
Definition town_cmd.cpp:918
static void MakeTownHouse(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits)
Write house information into the map.
void SetTownRatingTestMode(bool mode)
Switch the town rating to test-mode, to allow commands to be tested without affecting current ratings...
static CommandCost TownActionBuildStatue(Town *t, DoCommandFlag flags)
Perform a 9x9 tiles circular search from the center of the town in order to find a free tile to place...
static bool _town_rating_test
If true, town rating is in test-mode.
void UpdateTownRadius(Town *t)
Update the cached town zone radii of a town, based on the number of houses.
static void BuildTownHouse(Town *t, TileIndex tile, const HouseSpec *hs, HouseID house, uint8_t random_bits)
Build a house at this tile.
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:807
CommandCost CmdTownSetText(DoCommandFlag flags, TownID town_id, const std::string &text)
Set a custom text in the Town window.
static void TownGenerateCargo(Town *t, CargoType ct, uint amount, StationFinder &stations, bool affected_by_recession)
Generate cargo for a house, scaled by the current economy scale.
Definition town_cmd.cpp:538
static bool IsCloseToTown(TileIndex tile, uint dist)
Determines if a town is close to a tile.
Definition town_cmd.cpp:401
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.
static void TownGenerateCargoBinominal(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
Generate cargo for a house using the binominal algorithm.
Definition town_cmd.cpp:582
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:267
void UpdateAllTownVirtCoords()
Update the virtual coords needed to draw the town sign for all towns.
Definition town_cmd.cpp:427
static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection target_dir, Town *t1)
Grows the given town.
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:237
void HaltLift(Tile t)
Stop the lift of this animated house from moving.
Definition town_map.h:115
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:226
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:208
uint8_t GetLiftPosition(Tile t)
Get the position of the lift on this animated house.
Definition town_map.h:125
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:93
TimerGameCalendar::Year GetHouseAge(Tile t)
Get the age of the house.
Definition town_map.h:249
void SetLiftPosition(Tile t, uint8_t pos)
Set the position of the lift on this animated house.
Definition town_map.h:135
uint8_t GetLiftDestination(Tile t)
Get the current destination for this lift.
Definition town_map.h:104
uint8_t GetHouseBuildingStage(Tile t)
House Construction Scheme.
Definition town_map.h:183
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:82
bool IsHouseCompleted(Tile t)
Get the completion of this house.
Definition town_map.h:145
void MakeHouseTile(Tile t, TownID tid, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits)
Make the tile a house.
Definition town_map.h:352
uint8_t GetHouseConstructionTick(Tile t)
Gets the construction stage of a house.
Definition town_map.h:195
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:107
@ TCGM_ORIGINAL
Original algorithm (quadratic cargo by population)
Definition town_type.h:106
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:99
@ TF_FORBIDDEN
Forbidden.
Definition town_type.h:97
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:111
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 w, int h, int dz, int z, bool transparent, int bb_offset_x, int bb_offset_y, int bb_offset_z, const SubSprite *sub)
Draw a (transparent) sprite at given coordinates with a given bounding box.
Definition viewport.cpp:671
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:827
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:587
Functions related to (drawing on) viewports.
bool HasTileWaterGround(Tile t)
Checks whether the tile has water at the ground.
Definition water_map.h:350
bool IsWaterTile(Tile t)
Is it a water tile with plain water?
Definition water_map.h:190
bool IsSea(Tile t)
Is it a sea water tile?
Definition water_map.h:158
Base of waypoints.
void CloseWindowById(WindowClass cls, WindowNumber number, bool force, int data)
Close a window by its class and window number (if it is open).
Definition window.cpp:1137
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition window.cpp:3125
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:3217
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition window.cpp:3099
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: