OpenTTD Source 20250312-master-gcdcc6b491d
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
156 Source src{this->index, SourceType::Town};
161}
162
163
169{
170 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_REBUILD);
172
173 /* Give objects a new home! */
174 for (Object *o : Object::Iterate()) {
175 if (o->town == nullptr) o->town = CalcClosestTownFromTile(o->location.tile, UINT_MAX);
176 }
177}
178
184{
185 if (layout != TL_RANDOM) {
186 this->layout = layout;
187 return;
188 }
189
190 this->layout = static_cast<TownLayout>(TileHash(TileX(this->xy), TileY(this->xy)) % (NUM_TLS - 1));
191}
192
197/* static */ Town *Town::GetRandom()
198{
199 if (Town::GetNumItems() == 0) return nullptr;
200 int num = RandomRange((uint16_t)Town::GetNumItems());
201 size_t index = std::numeric_limits<size_t>::max();
202
203 while (num >= 0) {
204 num--;
205 index++;
206
207 /* Make sure we have a valid town */
208 while (!Town::IsValidID(index)) {
209 index++;
210 assert(index < Town::GetPoolSize());
211 }
212 }
213
214 return Town::Get(index);
215}
216
217void Town::FillCachedName() const
218{
219 this->cached_name = GetTownName(this);
220}
221
227{
228 return (_price[PR_CLEAR_HOUSE] * this->removal_cost) >> 8;
229}
230
231/* Local */
232static int _grow_town_result;
233
234/* The possible states of town growth. */
235enum TownGrowthResult {
236 GROWTH_SUCCEED = -1,
237 GROWTH_SEARCH_STOPPED = 0
238// GROWTH_SEARCH_RUNNING >= 1
239};
240
241static bool TryBuildTownHouse(Town *t, TileIndex tile);
242static Town *CreateRandomTown(uint attempts, uint32_t townnameparts, TownSize size, bool city, TownLayout layout);
243
244static void TownDrawHouseLift(const TileInfo *ti)
245{
246 AddChildSpriteScreen(SPR_LIFT, PAL_NONE, 14, 60 - GetLiftPosition(ti->tile));
247}
248
249typedef void TownDrawTileProc(const TileInfo *ti);
250static TownDrawTileProc * const _town_draw_tile_procs[1] = {
251 TownDrawHouseLift
252};
253
260{
262}
263
268static void DrawTile_Town(TileInfo *ti)
269{
270 HouseID house_id = GetHouseType(ti->tile);
271
272 if (house_id >= NEW_HOUSE_OFFSET) {
273 /* Houses don't necessarily need new graphics. If they don't have a
274 * spritegroup associated with them, then the sprite for the substitute
275 * house id is drawn instead. */
276 if (HouseSpec::Get(house_id)->grf_prop.GetSpriteGroup() != nullptr) {
277 DrawNewHouseTile(ti, house_id);
278 return;
279 } else {
280 house_id = HouseSpec::Get(house_id)->grf_prop.subst_id;
281 }
282 }
283
284 /* Retrieve pointer to the draw town tile struct */
285 const DrawBuildingsTileStruct *dcts = &_town_draw_tile_data[house_id << 4 | TileHash2Bit(ti->x, ti->y) << 2 | GetHouseBuildingStage(ti->tile)];
286
288
289 DrawGroundSprite(dcts->ground.sprite, dcts->ground.pal);
290
291 /* If houses are invisible, do not draw the upper part */
292 if (IsInvisibilitySet(TO_HOUSES)) return;
293
294 /* Add a house on top of the ground? */
295 SpriteID image = dcts->building.sprite;
296 if (image != 0) {
297 AddSortableSpriteToDraw(image, dcts->building.pal,
298 ti->x + dcts->subtile_x,
299 ti->y + dcts->subtile_y,
300 dcts->width,
301 dcts->height,
302 dcts->dz,
303 ti->z,
305 );
306
307 if (IsTransparencySet(TO_HOUSES)) return;
308 }
309
310 {
311 int proc = dcts->draw_proc - 1;
312
313 if (proc >= 0) _town_draw_tile_procs[proc](ti);
314 }
315}
316
317static int GetSlopePixelZ_Town(TileIndex tile, uint, uint, bool)
318{
319 return GetTileMaxPixelZ(tile);
320}
321
328{
329 HouseID hid = GetHouseType(tile);
330
331 /* For NewGRF house tiles we might not be drawing a foundation. We need to
332 * account for this, as other structures should
333 * draw the wall of the foundation in this case.
334 */
335 if (hid >= NEW_HOUSE_OFFSET) {
336 const HouseSpec *hs = HouseSpec::Get(hid);
338 uint32_t callback_res = GetHouseCallback(CBID_HOUSE_DRAW_FOUNDATIONS, 0, 0, hid, Town::GetByTile(tile), tile);
339 if (callback_res != CALLBACK_FAILED && !ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DRAW_FOUNDATIONS, callback_res)) return FOUNDATION_NONE;
340 }
341 }
342 return FlatteningFoundation(tileh);
343}
344
352{
353 if (GetHouseType(tile) >= NEW_HOUSE_OFFSET) {
354 AnimateNewHouseTile(tile);
355 return;
356 }
357
358 if (TimerGameTick::counter & 3) return;
359
360 /* If the house is not one with a lift anymore, then stop this animating.
361 * Not exactly sure when this happens, but probably when a house changes.
362 * Before this was just a return...so it'd leak animated tiles..
363 * That bug seems to have been here since day 1?? */
364 if (!HouseSpec::Get(GetHouseType(tile))->building_flags.Test(BuildingFlag::IsAnimated)) {
365 DeleteAnimatedTile(tile);
366 return;
367 }
368
369 if (!LiftHasDestination(tile)) {
370 uint i;
371
372 /* Building has 6 floors, number 0 .. 6, where 1 is illegal.
373 * This is due to the fact that the first floor is, in the graphics,
374 * the height of 2 'normal' floors.
375 * Furthermore, there are 6 lift positions from floor N (incl) to floor N + 1 (excl) */
376 do {
377 i = RandomRange(7);
378 } while (i == 1 || i * 6 == GetLiftPosition(tile));
379
380 SetLiftDestination(tile, i);
381 }
382
383 int pos = GetLiftPosition(tile);
384 int dest = GetLiftDestination(tile) * 6;
385 pos += (pos < dest) ? 1 : -1;
386 SetLiftPosition(tile, pos);
387
388 if (pos == dest) {
389 HaltLift(tile);
390 DeleteAnimatedTile(tile);
391 }
392
394}
395
402static bool IsCloseToTown(TileIndex tile, uint dist)
403{
404 if (_town_kdtree.Count() == 0) return false;
405 Town *t = Town::Get(_town_kdtree.FindNearest(TileX(tile), TileY(tile)));
406 return DistanceManhattan(tile, t->xy) < dist;
407}
408
411{
412 Point pt = RemapCoords2(TileX(this->xy) * TILE_SIZE, TileY(this->xy) * TILE_SIZE);
413
414 if (this->cache.sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeTown(this->index));
415
416 std::string town_string = GetString(STR_TOWN_NAME, this->index);
417 this->cache.sign.UpdatePosition(pt.x, pt.y - 24 * ZOOM_BASE,
418 _settings_client.gui.population_in_label ? GetString(STR_VIEWPORT_TOWN_POP, this->index, this->cache.population) : town_string,
419 town_string);
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, {t->index, SourceType::Town}, 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 TownGenerateCargoBinomial(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.Test(DoCommandFlag::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 return CommandCost(CMD_ERROR);
735 }
736 /* If town authority controls removal, check the company's rating. */
737 if (rating > t->ratings[_current_company] && _settings_game.difficulty.town_council_tolerance != TOWN_COUNCIL_PERMISSIVE) {
738 return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index);
739 }
740 }
741 }
742
743 ChangeTownRating(t, -rating, RATING_HOUSE_MINIMUM, flags);
744 if (flags.Test(DoCommandFlag::Execute)) {
745 ClearTownHouse(t, tile);
746 }
747
748 return cost;
749}
750
751static void AddProducedCargo_Town(TileIndex tile, CargoArray &produced)
752{
753 HouseID house_id = GetHouseType(tile);
754 const HouseSpec *hs = HouseSpec::Get(house_id);
755 Town *t = Town::GetByTile(tile);
756
758 for (uint i = 0; i < 256; i++) {
759 uint16_t callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, 0, house_id, t, tile);
760
761 if (callback == CALLBACK_FAILED || callback == CALLBACK_HOUSEPRODCARGO_END) break;
762
763 CargoType cargo = GetCargoTranslation(GB(callback, 8, 7), hs->grf_prop.grffile);
764
765 if (!IsValidCargoType(cargo)) continue;
766 produced[cargo]++;
767 }
768 } else {
769 if (hs->population > 0) {
770 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_PASSENGERS]) {
771 produced[cs->Index()]++;
772 }
773 }
774 if (hs->mail_generation > 0) {
775 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_MAIL]) {
776 produced[cs->Index()]++;
777 }
778 }
779 }
780}
781
789static void AddAcceptedCargoSetMask(CargoType cargo, uint amount, CargoArray &acceptance, CargoTypes &always_accepted)
790{
791 if (!IsValidCargoType(cargo) || amount == 0) return;
792 acceptance[cargo] += amount;
793 SetBit(always_accepted, cargo);
794}
795
805void AddAcceptedCargoOfHouse(TileIndex tile, HouseID house, const HouseSpec *hs, Town *t, CargoArray &acceptance, CargoTypes &always_accepted)
806{
807 CargoType accepts[lengthof(hs->accepts_cargo)];
808
809 /* Set the initial accepted cargo types */
810 for (uint8_t i = 0; i < lengthof(accepts); i++) {
811 accepts[i] = hs->accepts_cargo[i];
812 }
813
814 /* Check for custom accepted cargo types */
816 uint16_t callback = GetHouseCallback(CBID_HOUSE_ACCEPT_CARGO, 0, 0, house, t, tile, tile == INVALID_TILE);
817 if (callback != CALLBACK_FAILED) {
818 /* Replace accepted cargo types with translated values from callback */
819 accepts[0] = GetCargoTranslation(GB(callback, 0, 5), hs->grf_prop.grffile);
820 accepts[1] = GetCargoTranslation(GB(callback, 5, 5), hs->grf_prop.grffile);
821 accepts[2] = GetCargoTranslation(GB(callback, 10, 5), hs->grf_prop.grffile);
822 }
823 }
824
825 /* Check for custom cargo acceptance */
827 uint16_t callback = GetHouseCallback(CBID_HOUSE_CARGO_ACCEPTANCE, 0, 0, house, t, tile, tile == INVALID_TILE);
828 if (callback != CALLBACK_FAILED) {
829 AddAcceptedCargoSetMask(accepts[0], GB(callback, 0, 4), acceptance, always_accepted);
830 AddAcceptedCargoSetMask(accepts[1], GB(callback, 4, 4), acceptance, always_accepted);
831 if (_settings_game.game_creation.landscape != LandscapeType::Temperate && HasBit(callback, 12)) {
832 /* The 'S' bit indicates food instead of goods */
833 AddAcceptedCargoSetMask(GetCargoTypeByLabel(CT_FOOD), GB(callback, 8, 4), acceptance, always_accepted);
834 } else {
835 AddAcceptedCargoSetMask(accepts[2], GB(callback, 8, 4), acceptance, always_accepted);
836 }
837 return;
838 }
839 }
840
841 /* No custom acceptance, so fill in with the default values */
842 for (uint8_t i = 0; i < lengthof(accepts); i++) {
843 AddAcceptedCargoSetMask(accepts[i], hs->cargo_acceptance[i], acceptance, always_accepted);
844 }
845}
846
847static void AddAcceptedCargo_Town(TileIndex tile, CargoArray &acceptance, CargoTypes &always_accepted)
848{
849 HouseID house = GetHouseType(tile);
850 AddAcceptedCargoOfHouse(tile, house, HouseSpec::Get(house), Town::GetByTile(tile), acceptance, always_accepted);
851}
852
859{
860 CargoTypes always_accepted{};
861 CargoArray acceptance{};
862 AddAcceptedCargoOfHouse(INVALID_TILE, hs->Index(), hs, nullptr, acceptance, always_accepted);
863 return acceptance;
864}
865
866static void GetTileDesc_Town(TileIndex tile, TileDesc &td)
867{
868 const HouseID house = GetHouseType(tile);
869 const HouseSpec *hs = HouseSpec::Get(house);
870 bool house_completed = IsHouseCompleted(tile);
871
872 td.str = hs->building_name;
874
875 uint16_t callback_res = GetHouseCallback(CBID_HOUSE_CUSTOM_NAME, house_completed ? 1 : 0, 0, house, Town::GetByTile(tile), tile);
876 if (callback_res != CALLBACK_FAILED && callback_res != 0x400) {
877 if (callback_res > 0x400) {
879 } else {
880 StringID new_name = GetGRFStringID(hs->grf_prop.grfid, GRFSTR_MISC_GRF_TEXT + callback_res);
881 if (new_name != STR_NULL && new_name != STR_UNDEFINED) {
882 td.str = new_name;
883 }
884 }
885 }
886
887 if (!house_completed) {
888 td.dparam = td.str;
889 td.str = STR_LAI_TOWN_INDUSTRY_DESCRIPTION_UNDER_CONSTRUCTION;
890 }
891
892 if (hs->grf_prop.HasGrfFile()) {
893 const GRFConfig *gc = GetGRFConfig(hs->grf_prop.grfid);
894 td.grf = gc->GetName();
895 }
896
897 td.owner[0] = OWNER_TOWN;
898}
899
900static TrackStatus GetTileTrackStatus_Town(TileIndex, TransportType, uint, DiagDirection)
901{
902 /* not used */
903 return 0;
904}
905
906static void ChangeTileOwner_Town(TileIndex, Owner, Owner)
907{
908 /* not used */
909}
910
911static bool GrowTown(Town *t);
912
917static void TownTickHandler(Town *t)
918{
919 if (HasBit(t->flags, TOWN_IS_GROWING)) {
920 int i = (int)t->grow_counter - 1;
921 if (i < 0) {
922 if (GrowTown(t)) {
923 i = t->growth_rate;
924 } else {
925 /* If growth failed wait a bit before retrying */
926 i = std::min<uint16_t>(t->growth_rate, Ticks::TOWN_GROWTH_TICKS - 1);
927 }
928 }
929 t->grow_counter = i;
930 }
931}
932
935{
936 if (_game_mode == GM_EDITOR) return;
937
938 for (Town *t : Town::Iterate()) {
940 }
941}
942
949{
950 if (IsRoadDepotTile(tile) || IsBayRoadStopTile(tile)) return ROAD_NONE;
951
952 return GetAnyRoadBits(tile, RTT_ROAD, true);
953}
954
960{
961 RoadType best_rt = ROADTYPE_ROAD;
962 const RoadTypeInfo *best = nullptr;
963 const uint16_t assume_max_speed = 50;
964
965 for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
966 if (RoadTypeIsTram(rt)) continue;
967
968 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
969
970 /* Unused road type. */
971 if (rti->label == 0) continue;
972
973 /* Can town build this road. */
974 if (!rti->flags.Test(RoadTypeFlag::TownBuild)) continue;
975
976 /* Not yet introduced at this date. */
978
979 if (best != nullptr) {
980 if ((rti->max_speed == 0 ? assume_max_speed : rti->max_speed) < (best->max_speed == 0 ? assume_max_speed : best->max_speed)) continue;
981 }
982
983 best_rt = rt;
984 best = rti;
985 }
986
987 return best_rt;
988}
989
994static TimerGameCalendar::Date GetTownRoadTypeFirstIntroductionDate()
995{
996 const RoadTypeInfo *best = nullptr;
997 for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
998 if (RoadTypeIsTram(rt)) continue;
999 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
1000 if (rti->label == 0) continue; // Unused road type.
1001 if (!rti->flags.Test(RoadTypeFlag::TownBuild)) continue; // Town can't build this road type.
1002
1003 if (best != nullptr && rti->introduction_date >= best->introduction_date) continue;
1004 best = rti;
1005 }
1006
1007 if (best == nullptr) return TimerGameCalendar::Date(INT32_MAX);
1008 return best->introduction_date;
1009}
1010
1016{
1017 auto min_date = GetTownRoadTypeFirstIntroductionDate();
1018 if (min_date <= TimerGameCalendar::date) return true;
1019
1020 if (min_date < INT32_MAX) {
1022 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_YET),
1023 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_YET_EXPLANATION, min_date),
1024 WL_CRITICAL);
1025 } else {
1027 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_AT_ALL),
1028 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_AT_ALL_EXPLANATION), WL_CRITICAL);
1029 }
1030 return false;
1031}
1032
1043static bool IsNeighbourRoadTile(TileIndex tile, const DiagDirection dir, uint dist_multi)
1044{
1045 if (!IsValidTile(tile)) return false;
1046
1047 /* Lookup table for the used diff values */
1048 const TileIndexDiff tid_lt[3] = {
1052 };
1053
1054 dist_multi = (dist_multi + 1) * 4;
1055 for (uint pos = 4; pos < dist_multi; pos++) {
1056 /* Go (pos / 4) tiles to the left or the right */
1057 TileIndexDiff cur = tid_lt[(pos & 1) ? 0 : 1] * (pos / 4);
1058
1059 /* Use the current tile as origin, or go one tile backwards */
1060 if (pos & 2) cur += tid_lt[2];
1061
1062 /* Test for roadbit parallel to dir and facing towards the middle axis */
1063 if (IsValidTile(tile + cur) &&
1064 GetTownRoadBits(TileAdd(tile, cur)) & DiagDirToRoadBits((pos & 2) ? dir : ReverseDiagDir(dir))) return true;
1065 }
1066 return false;
1067}
1068
1078{
1079 if (DistanceFromEdge(tile) == 0) return false;
1080
1081 /* Prevent towns from building roads under bridges along the bridge. Looks silly. */
1082 if (IsBridgeAbove(tile) && GetBridgeAxis(tile) == DiagDirToAxis(dir)) return false;
1083
1084 /* Check if there already is a road at this point? */
1085 if (GetTownRoadBits(tile) == ROAD_NONE) {
1086 /* No, try if we are able to build a road piece there.
1087 * If that fails clear the land, and if that fails exit.
1088 * This is to make sure that we can build a road here later. */
1092 return false;
1093 }
1094 }
1095
1096 Slope cur_slope = _settings_game.construction.build_on_slopes ? std::get<0>(GetFoundationSlope(tile)) : GetTileSlope(tile);
1097 bool ret = !IsNeighbourRoadTile(tile, dir, t->layout == TL_ORIGINAL ? 1 : 2);
1098 if (cur_slope == SLOPE_FLAT) return ret;
1099
1100 /* If the tile is not a slope in the right direction, then
1101 * maybe terraform some. */
1102 Slope desired_slope = (dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? SLOPE_NW : SLOPE_NE;
1103 if (desired_slope != cur_slope && ComplementSlope(desired_slope) != cur_slope) {
1104 if (Chance16(1, 8)) {
1105 CommandCost res = CMD_ERROR;
1106 if (!_generating_world && Chance16(1, 10)) {
1107 /* Note: Do not replace "^ SLOPE_ELEVATED" with ComplementSlope(). The slope might be steep. */
1109 tile, Chance16(1, 16) ? cur_slope : cur_slope ^ SLOPE_ELEVATED, false));
1110 }
1111 if (res.Failed() && Chance16(1, 3)) {
1112 /* We can consider building on the slope, though. */
1113 return ret;
1114 }
1115 }
1116 return false;
1117 }
1118 return ret;
1119}
1120
1121static bool TerraformTownTile(TileIndex tile, Slope edges, bool dir)
1122{
1123 assert(tile < Map::Size());
1124
1126 if (r.Failed() || r.GetCost() >= (_price[PR_TERRAFORM] + 2) * 8) return false;
1128 return true;
1129}
1130
1131static void LevelTownLand(TileIndex tile)
1132{
1133 assert(tile < Map::Size());
1134
1135 /* Don't terraform if land is plain or if there's a house there. */
1136 if (IsTileType(tile, MP_HOUSE)) return;
1137 Slope tileh = GetTileSlope(tile);
1138 if (tileh == SLOPE_FLAT) return;
1139
1140 /* First try up, then down */
1141 if (!TerraformTownTile(tile, ~tileh & SLOPE_ELEVATED, true)) {
1142 TerraformTownTile(tile, tileh & SLOPE_ELEVATED, false);
1143 }
1144}
1145
1155{
1156 /* align the grid to the downtown */
1157 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile); // Vector from downtown to the tile
1158 RoadBits rcmd = ROAD_NONE;
1159
1160 switch (t->layout) {
1161 default: NOT_REACHED();
1162
1163 case TL_2X2_GRID:
1164 if ((grid_pos.x % 3) == 0) rcmd |= ROAD_Y;
1165 if ((grid_pos.y % 3) == 0) rcmd |= ROAD_X;
1166 break;
1167
1168 case TL_3X3_GRID:
1169 if ((grid_pos.x % 4) == 0) rcmd |= ROAD_Y;
1170 if ((grid_pos.y % 4) == 0) rcmd |= ROAD_X;
1171 break;
1172 }
1173
1174 /* Optimise only X-junctions */
1175 if (rcmd != ROAD_ALL) return rcmd;
1176
1177 RoadBits rb_template;
1178
1179 switch (GetTileSlope(tile)) {
1180 default: rb_template = ROAD_ALL; break;
1181 case SLOPE_W: rb_template = ROAD_NW | ROAD_SW; break;
1182 case SLOPE_SW: rb_template = ROAD_Y | ROAD_SW; break;
1183 case SLOPE_S: rb_template = ROAD_SW | ROAD_SE; break;
1184 case SLOPE_SE: rb_template = ROAD_X | ROAD_SE; break;
1185 case SLOPE_E: rb_template = ROAD_SE | ROAD_NE; break;
1186 case SLOPE_NE: rb_template = ROAD_Y | ROAD_NE; break;
1187 case SLOPE_N: rb_template = ROAD_NE | ROAD_NW; break;
1188 case SLOPE_NW: rb_template = ROAD_X | ROAD_NW; break;
1189 case SLOPE_STEEP_W:
1190 case SLOPE_STEEP_S:
1191 case SLOPE_STEEP_E:
1192 case SLOPE_STEEP_N:
1193 rb_template = ROAD_NONE;
1194 break;
1195 }
1196
1197 /* Stop if the template is compatible to the growth dir */
1198 if (DiagDirToRoadBits(ReverseDiagDir(dir)) & rb_template) return rb_template;
1199 /* If not generate a straight road in the direction of the growth */
1201}
1202
1214{
1215 /* We can't look further than that. */
1216 if (DistanceFromEdge(tile) == 0) return false;
1217
1218 uint counter = 0; // counts the house neighbour tiles
1219
1220 /* Check the tiles E,N,W and S of the current tile for houses */
1221 for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
1222 /* Count both void and house tiles for checking whether there
1223 * are enough houses in the area. This to make it likely that
1224 * houses get build up to the edge of the map. */
1225 switch (GetTileType(TileAddByDiagDir(tile, dir))) {
1226 case MP_HOUSE:
1227 case MP_VOID:
1228 counter++;
1229 break;
1230
1231 default:
1232 break;
1233 }
1234
1235 /* If there are enough neighbours stop here */
1236 if (counter >= 3) {
1237 if (TryBuildTownHouse(t, tile)) {
1238 _grow_town_result = GROWTH_SUCCEED;
1239 return true;
1240 }
1241 return false;
1242 }
1243 }
1244 return false;
1245}
1246
1255static bool GrowTownWithRoad(const Town *t, TileIndex tile, RoadBits rcmd)
1256{
1259 _grow_town_result = GROWTH_SUCCEED;
1260 return true;
1261 }
1262 return false;
1263}
1264
1274static bool CanRoadContinueIntoNextTile(const Town *t, const TileIndex tile, const DiagDirection road_dir)
1275{
1276 const TileIndexDiff delta = TileOffsByDiagDir(road_dir); // +1 tile in the direction of the road
1277 TileIndex next_tile = tile + delta; // The tile beyond which must be connectable to the target tile
1278 RoadBits rcmd = DiagDirToRoadBits(ReverseDiagDir(road_dir));
1280
1281 /* Before we try anything, make sure the tile is on the map and not the void. */
1282 if (!IsValidTile(next_tile)) return false;
1283
1284 /* If the next tile is a bridge or tunnel, allow if it's continuing in the same direction. */
1285 if (IsTileType(next_tile, MP_TUNNELBRIDGE)) {
1286 return GetTunnelBridgeTransportType(next_tile) == TRANSPORT_ROAD && GetTunnelBridgeDirection(next_tile) == road_dir;
1287 }
1288
1289 /* If the next tile is a station, allow if it's a road station facing the proper direction. Otherwise return false. */
1290 if (IsTileType(next_tile, MP_STATION)) {
1291 /* If the next tile is a road station, allow if it can be entered by the new tunnel/bridge, otherwise disallow. */
1292 if (IsDriveThroughStopTile(next_tile)) return GetDriveThroughStopAxis(next_tile) == DiagDirToAxis(road_dir);
1293 if (IsBayRoadStopTile(next_tile)) return GetBayRoadStopDir(next_tile) == ReverseDiagDir(road_dir);
1294 return false;
1295 }
1296
1297 /* If the next tile is a road depot, allow if it's facing the right way. */
1298 if (IsTileType(next_tile, MP_ROAD)) {
1299 return IsRoadDepot(next_tile) && GetRoadDepotDirection(next_tile) == ReverseDiagDir(road_dir);
1300 }
1301
1302 /* If the next tile is a railroad track, check if towns are allowed to build level crossings.
1303 * If level crossing are not allowed, reject the construction. Else allow DoCommand to determine if the rail track is buildable. */
1304 if (IsTileType(next_tile, MP_RAILWAY) && !_settings_game.economy.allow_town_level_crossings) return false;
1305
1306 /* If a road tile can be built, the construction is allowed. */
1307 return Command<CMD_BUILD_ROAD>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, next_tile, rcmd, rt, DRD_NONE, t->index).Succeeded();
1308}
1309
1316static bool RedundantBridgeExistsNearby(TileIndex tile, void *user_data)
1317{
1318 /* Don't look into the void. */
1319 if (!IsValidTile(tile)) return false;
1320
1321 /* Only consider bridge head tiles. */
1322 if (!IsBridgeTile(tile)) return false;
1323
1324 /* Only consider road bridges. */
1325 if (GetTunnelBridgeTransportType(tile) != TRANSPORT_ROAD) return false;
1326
1327 /* If the bridge is facing the same direction as the proposed bridge, we've found a redundant bridge. */
1328 return (GetTileSlope(tile) & InclinedSlope(ReverseDiagDir(*(DiagDirection *)user_data)));
1329}
1330
1341static bool GrowTownWithBridge(const Town *t, const TileIndex tile, const DiagDirection bridge_dir)
1342{
1343 assert(bridge_dir < DIAGDIR_END);
1344
1345 const Slope slope = GetTileSlope(tile);
1346
1347 /* Make sure the direction is compatible with the slope.
1348 * Well we check if the slope has an up bit set in the
1349 * reverse direction. */
1350 if (slope != SLOPE_FLAT && slope & InclinedSlope(bridge_dir)) return false;
1351
1352 /* Assure that the bridge is connectable to the start side */
1353 if (!(GetTownRoadBits(TileAddByDiagDir(tile, ReverseDiagDir(bridge_dir))) & DiagDirToRoadBits(bridge_dir))) return false;
1354
1355 /* We are in the right direction */
1356 uint bridge_length = 0; // This value stores the length of the possible bridge
1357 TileIndex bridge_tile = tile; // Used to store the other waterside
1358
1359 const TileIndexDiff delta = TileOffsByDiagDir(bridge_dir);
1360
1361 /* To prevent really small towns from building disproportionately
1362 * long bridges, make the max a function of its population. */
1363 const uint TOWN_BRIDGE_LENGTH_CAP = 11;
1364 uint base_bridge_length = 5;
1365 uint max_bridge_length = std::min(t->cache.population / 1000 + base_bridge_length, TOWN_BRIDGE_LENGTH_CAP);
1366
1367 if (slope == SLOPE_FLAT) {
1368 /* Bridges starting on flat tiles are only allowed when crossing rivers, rails or one-way roads. */
1369 do {
1370 if (bridge_length++ >= base_bridge_length) {
1371 /* Allow to cross rivers, not big lakes, nor large amounts of rails or one-way roads. */
1372 return false;
1373 }
1374 bridge_tile += delta;
1375 } while (IsValidTile(bridge_tile) && ((IsWaterTile(bridge_tile) && !IsSea(bridge_tile)) || IsPlainRailTile(bridge_tile) || (IsNormalRoadTile(bridge_tile) && GetDisallowedRoadDirections(bridge_tile) != DRD_NONE)));
1376 } else {
1377 do {
1378 if (bridge_length++ >= max_bridge_length) {
1379 /* Ensure the bridge is not longer than the max allowed length. */
1380 return false;
1381 }
1382 bridge_tile += delta;
1383 } while (IsValidTile(bridge_tile) && (IsWaterTile(bridge_tile) || IsPlainRailTile(bridge_tile) || (IsNormalRoadTile(bridge_tile) && GetDisallowedRoadDirections(bridge_tile) != DRD_NONE)));
1384 }
1385
1386 /* Don't allow a bridge where the start and end tiles are adjacent with no span between. */
1387 if (bridge_length == 1) return false;
1388
1389 /* Make sure the road can be continued past the bridge. At this point, bridge_tile holds the end tile of the bridge. */
1390 if (!CanRoadContinueIntoNextTile(t, bridge_tile, bridge_dir)) return false;
1391
1392 /* If another parallel bridge exists nearby, this one would be redundant and shouldn't be built. We don't care about flat bridges. */
1393 TileIndex search = tile;
1394 DiagDirection direction_to_match = bridge_dir;
1395 if (slope != SLOPE_FLAT && CircularTileSearch(&search, bridge_length, 0, 0, RedundantBridgeExistsNearby, &direction_to_match)) return false;
1396
1397 for (uint8_t times = 0; times <= 22; times++) {
1398 uint8_t bridge_type = RandomRange(MAX_BRIDGES - 1);
1399
1400 /* Can we actually build the bridge? */
1402 if (Command<CMD_BUILD_BRIDGE>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_BRIDGE>()), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, rt).Succeeded()) {
1403 Command<CMD_BUILD_BRIDGE>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_BRIDGE>()).Set(DoCommandFlag::Execute), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, rt);
1404 _grow_town_result = GROWTH_SUCCEED;
1405 return true;
1406 }
1407 }
1408 /* Quit if it selecting an appropriate bridge type fails a large number of times. */
1409 return false;
1410}
1411
1422static bool GrowTownWithTunnel(const Town *t, const TileIndex tile, const DiagDirection tunnel_dir)
1423{
1424 assert(tunnel_dir < DIAGDIR_END);
1425
1426 Slope slope = GetTileSlope(tile);
1427
1428 /* Only consider building a tunnel if the starting tile is sloped properly. */
1429 if (slope != InclinedSlope(tunnel_dir)) return false;
1430
1431 /* Assure that the tunnel is connectable to the start side */
1432 if (!(GetTownRoadBits(TileAddByDiagDir(tile, ReverseDiagDir(tunnel_dir))) & DiagDirToRoadBits(tunnel_dir))) return false;
1433
1434 const TileIndexDiff delta = TileOffsByDiagDir(tunnel_dir);
1435 int max_tunnel_length = 0;
1436
1437 /* There are two conditions for building tunnels: Under a mountain and under an obstruction. */
1438 if (CanRoadContinueIntoNextTile(t, tile, tunnel_dir)) {
1439 /* 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. */
1440 TileIndex slope_tile = tile;
1441 for (uint8_t tiles = 0; tiles < 4; tiles++) {
1442 if (!IsValidTile(slope_tile)) return false;
1443 slope = GetTileSlope(slope_tile);
1444 if (slope != InclinedSlope(tunnel_dir) && !IsSteepSlope(slope) && !IsSlopeWithOneCornerRaised(slope)) return false;
1445 slope_tile += delta;
1446 }
1447
1448 /* More population means longer tunnels, but make sure we can at least cover the smallest mountain which neccesitates tunneling. */
1449 max_tunnel_length = (t->cache.population / 1000) + 7;
1450 } else {
1451 /* When tunneling under an obstruction, the length limit is 5, enough to tunnel under a four-track railway. */
1452 max_tunnel_length = 5;
1453 }
1454
1455 uint8_t tunnel_length = 0;
1456 TileIndex tunnel_tile = tile; // Iteratator to store the other end tile of the tunnel.
1457
1458 /* Find the end tile of the tunnel for length and continuation checks. */
1459 do {
1460 if (tunnel_length++ >= max_tunnel_length) return false;
1461 tunnel_tile += delta;
1462 /* The tunnel ends when start and end tiles are the same height. */
1463 } while (IsValidTile(tunnel_tile) && GetTileZ(tile) != GetTileZ(tunnel_tile));
1464
1465 /* Don't allow a tunnel where the start and end tiles are adjacent. */
1466 if (tunnel_length == 1) return false;
1467
1468 /* Make sure the road can be continued past the tunnel. At this point, tunnel_tile holds the end tile of the tunnel. */
1469 if (!CanRoadContinueIntoNextTile(t, tunnel_tile, tunnel_dir)) return false;
1470
1471 /* Attempt to build the tunnel. Return false if it fails to let the town build a road instead. */
1473 if (Command<CMD_BUILD_TUNNEL>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_TUNNEL>()), tile, TRANSPORT_ROAD, rt).Succeeded()) {
1474 Command<CMD_BUILD_TUNNEL>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_TUNNEL>()).Set(DoCommandFlag::Execute), tile, TRANSPORT_ROAD, rt);
1475 _grow_town_result = GROWTH_SUCCEED;
1476 return true;
1477 }
1478
1479 return false;
1480}
1481
1489{
1490 static const TileIndexDiffC tiles[] = { {-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1} };
1491 bool allow = false;
1492
1493 for (const auto &ptr : tiles) {
1494 TileIndex cur_tile = t + ToTileIndexDiff(ptr);
1495 if (!IsValidTile(cur_tile)) continue;
1496
1497 if (!(IsTileType(cur_tile, MP_ROAD) || IsAnyRoadStopTile(cur_tile))) continue;
1498 allow = true;
1499
1500 RoadType road_rt = GetRoadTypeRoad(cur_tile);
1501 RoadType tram_rt = GetRoadTypeTram(cur_tile);
1502 if (road_rt != INVALID_ROADTYPE && !GetRoadTypeInfo(road_rt)->flags.Test(RoadTypeFlag::NoHouses)) return true;
1503 if (tram_rt != INVALID_ROADTYPE && !GetRoadTypeInfo(tram_rt)->flags.Test(RoadTypeFlag::NoHouses)) return true;
1504 }
1505
1506 /* If no road was found surrounding the tile we can allow building the house since there is
1507 * nothing which forbids it, if a road was found but the execution reached this point, then
1508 * all the found roads don't allow houses to be built */
1509 return !allow;
1510}
1511
1517{
1518 if (!IsTileType(tile, MP_ROAD)) return true;
1519
1520 /* Allow extending on roadtypes which can be built by town, or if the road type matches the type the town will build. */
1521 RoadType rt = GetRoadTypeRoad(tile);
1523}
1524
1529static inline bool TownAllowedToBuildRoads()
1530{
1531 return _settings_game.economy.allow_town_roads || _generating_world || _game_mode == GM_EDITOR;
1532}
1533
1551static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection target_dir, Town *t1)
1552{
1553 RoadBits rcmd = ROAD_NONE; // RoadBits for the road construction command
1554 TileIndex tile = *tile_ptr; // The main tile on which we base our growth
1555
1556 assert(tile < Map::Size());
1557
1558 if (cur_rb == ROAD_NONE) {
1559 /* Tile has no road. First reset the status counter
1560 * to say that this is the last iteration. */
1561 _grow_town_result = GROWTH_SEARCH_STOPPED;
1562
1563 if (!TownAllowedToBuildRoads()) return;
1565
1566 /* Remove hills etc */
1567 if (!_settings_game.construction.build_on_slopes || Chance16(1, 6)) LevelTownLand(tile);
1568
1569 /* Is a road allowed here? */
1570 switch (t1->layout) {
1571 default: NOT_REACHED();
1572
1573 case TL_3X3_GRID:
1574 case TL_2X2_GRID:
1575 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1576 if (rcmd == ROAD_NONE) return;
1577 break;
1578
1579 case TL_BETTER_ROADS:
1580 case TL_ORIGINAL:
1581 if (!IsRoadAllowedHere(t1, tile, target_dir)) return;
1582
1583 DiagDirection source_dir = ReverseDiagDir(target_dir);
1584
1585 if (Chance16(1, 4)) {
1586 /* Randomize a new target dir */
1587 do target_dir = RandomDiagDir(); while (target_dir == source_dir);
1588 }
1589
1590 if (!IsRoadAllowedHere(t1, TileAddByDiagDir(tile, target_dir), target_dir)) {
1591 /* A road is not allowed to continue the randomized road,
1592 * return if the road we're trying to build is curved. */
1593 if (target_dir != ReverseDiagDir(source_dir)) return;
1594
1595 /* Return if neither side of the new road is a house */
1598 return;
1599 }
1600
1601 /* That means that the road is only allowed if there is a house
1602 * at any side of the new road. */
1603 }
1604
1605 rcmd = DiagDirToRoadBits(target_dir) | DiagDirToRoadBits(source_dir);
1606 break;
1607 }
1608
1609 } else if (target_dir < DIAGDIR_END && !(cur_rb & DiagDirToRoadBits(ReverseDiagDir(target_dir)))) {
1610 if (!TownCanGrowRoad(tile)) return;
1611
1612 /* Continue building on a partial road.
1613 * Should be always OK, so we only generate
1614 * the fitting RoadBits */
1615 _grow_town_result = GROWTH_SEARCH_STOPPED;
1616
1617 if (!TownAllowedToBuildRoads()) return;
1618
1619 switch (t1->layout) {
1620 default: NOT_REACHED();
1621
1622 case TL_3X3_GRID:
1623 case TL_2X2_GRID:
1624 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1625 break;
1626
1627 case TL_BETTER_ROADS:
1628 case TL_ORIGINAL:
1629 rcmd = DiagDirToRoadBits(ReverseDiagDir(target_dir));
1630 break;
1631 }
1632 } else {
1633 bool allow_house = true; // Value which decides if we want to construct a house
1634
1635 /* Reached a tunnel/bridge? Then continue at the other side of it, unless
1636 * it is the starting tile. Half the time, we stay on this side then.*/
1637 if (IsTileType(tile, MP_TUNNELBRIDGE)) {
1638 if (GetTunnelBridgeTransportType(tile) == TRANSPORT_ROAD && (target_dir != DIAGDIR_END || Chance16(1, 2))) {
1639 *tile_ptr = GetOtherTunnelBridgeEnd(tile);
1640 }
1641 return;
1642 }
1643
1644 /* Possibly extend the road in a direction.
1645 * Randomize a direction and if it has a road, bail out. */
1646 target_dir = RandomDiagDir();
1647 RoadBits target_rb = DiagDirToRoadBits(target_dir);
1648 TileIndex house_tile; // position of a possible house
1649
1650 if (cur_rb & target_rb) {
1651 /* If it's a road turn possibly build a house in a corner.
1652 * Use intersection with straight road as an indicator
1653 * that we randomed corner house position.
1654 * A turn (and we check for that later) always has only
1655 * one common bit with a straight road so it has the same
1656 * chance to be chosen as the house on the side of a road.
1657 */
1658 if ((cur_rb & ROAD_X) != target_rb) return;
1659
1660 /* Check whether it is a turn and if so determine
1661 * position of the corner tile */
1662 switch (cur_rb) {
1663 case ROAD_N:
1664 house_tile = TileAddByDir(tile, DIR_S);
1665 break;
1666 case ROAD_S:
1667 house_tile = TileAddByDir(tile, DIR_N);
1668 break;
1669 case ROAD_E:
1670 house_tile = TileAddByDir(tile, DIR_W);
1671 break;
1672 case ROAD_W:
1673 house_tile = TileAddByDir(tile, DIR_E);
1674 break;
1675 default:
1676 return; // not a turn
1677 }
1678 target_dir = DIAGDIR_END;
1679 } else {
1680 house_tile = TileAddByDiagDir(tile, target_dir);
1681 }
1682
1683 /* Don't walk into water. */
1684 if (HasTileWaterGround(house_tile)) return;
1685
1686 if (!IsValidTile(house_tile)) return;
1687
1688 if (target_dir != DIAGDIR_END && TownAllowedToBuildRoads()) {
1689 switch (t1->layout) {
1690 default: NOT_REACHED();
1691
1692 case TL_3X3_GRID: // Use 2x2 grid afterwards!
1693 GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir));
1694 [[fallthrough]];
1695
1696 case TL_2X2_GRID:
1697 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1698 allow_house = (rcmd & target_rb) == ROAD_NONE;
1699 break;
1700
1701 case TL_BETTER_ROADS: // Use original afterwards!
1702 GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir));
1703 [[fallthrough]];
1704
1705 case TL_ORIGINAL:
1706 /* Allow a house at the edge. 60% chance or
1707 * always ok if no road allowed. */
1708 rcmd = target_rb;
1709 allow_house = (!IsRoadAllowedHere(t1, house_tile, target_dir) || Chance16(6, 10));
1710 break;
1711 }
1712 }
1713
1714 allow_house &= RoadTypesAllowHouseHere(house_tile);
1715
1716 if (allow_house) {
1717 /* Build a house, but not if there already is a house there. */
1718 if (!IsTileType(house_tile, MP_HOUSE)) {
1719 /* Level the land if possible */
1720 if (Chance16(1, 6)) LevelTownLand(house_tile);
1721
1722 /* And build a house.
1723 * Set result to -1 if we managed to build it. */
1724 if (TryBuildTownHouse(t1, house_tile)) {
1725 _grow_town_result = GROWTH_SUCCEED;
1726 }
1727 }
1728 return;
1729 }
1730
1731 if (!TownCanGrowRoad(tile)) return;
1732
1733 _grow_town_result = GROWTH_SEARCH_STOPPED;
1734 }
1735
1736 /* Return if a water tile */
1737 if (HasTileWaterGround(tile)) return;
1738
1739 /* Make the roads look nicer */
1740 rcmd = CleanUpRoadBits(tile, rcmd);
1741 if (rcmd == ROAD_NONE) return;
1742
1743 /* Only use the target direction for bridges and tunnels to ensure they're connected.
1744 * The target_dir is as computed previously according to town layout, so
1745 * it will match it perfectly. */
1746 if (GrowTownWithBridge(t1, tile, target_dir)) return;
1747 if (GrowTownWithTunnel(t1, tile, target_dir)) return;
1748
1749 GrowTownWithRoad(t1, tile, rcmd);
1750}
1751
1760{
1761 TileIndex target_tile = tile + TileOffsByDiagDir(dir);
1762 if (!IsValidTile(target_tile)) return false;
1763 if (HasTileWaterGround(target_tile)) return false;
1764
1765 RoadBits target_rb = GetTownRoadBits(target_tile);
1767 /* Check whether a road connection exists or can be build. */
1768 switch (GetTileType(target_tile)) {
1769 case MP_ROAD:
1770 return target_rb != ROAD_NONE;
1771
1772 case MP_STATION:
1773 return IsDriveThroughStopTile(target_tile);
1774
1775 case MP_TUNNELBRIDGE:
1776 return GetTunnelBridgeTransportType(target_tile) == TRANSPORT_ROAD;
1777
1778 case MP_HOUSE:
1779 case MP_INDUSTRY:
1780 case MP_OBJECT:
1781 return false;
1782
1783 default:
1784 /* Checked for void and water earlier */
1785 return true;
1786 }
1787 } else {
1788 /* Check whether a road connection already exists,
1789 * and it leads somewhere else. */
1791 return (target_rb & back_rb) != 0 && (target_rb & ~back_rb) != 0;
1792 }
1793}
1794
1801static bool GrowTownAtRoad(Town *t, TileIndex tile)
1802{
1803 /* Special case.
1804 * @see GrowTownInTile Check the else if
1805 */
1806 DiagDirection target_dir = DIAGDIR_END; // The direction in which we want to extend the town
1807
1808 assert(tile < Map::Size());
1809
1810 /* Number of times to search.
1811 * Better roads, 2X2 and 3X3 grid grow quite fast so we give
1812 * them a little handicap. */
1813 switch (t->layout) {
1814 case TL_BETTER_ROADS:
1815 _grow_town_result = 10 + t->cache.num_houses * 2 / 9;
1816 break;
1817
1818 case TL_3X3_GRID:
1819 case TL_2X2_GRID:
1820 _grow_town_result = 10 + t->cache.num_houses * 1 / 9;
1821 break;
1822
1823 default:
1824 _grow_town_result = 10 + t->cache.num_houses * 4 / 9;
1825 break;
1826 }
1827
1828 do {
1829 RoadBits cur_rb = GetTownRoadBits(tile); // The RoadBits of the current tile
1830
1831 /* Try to grow the town from this point */
1832 GrowTownInTile(&tile, cur_rb, target_dir, t);
1833 if (_grow_town_result == GROWTH_SUCCEED) return true;
1834
1835 /* Exclude the source position from the bitmask
1836 * and return if no more road blocks available */
1837 if (IsValidDiagDirection(target_dir)) cur_rb &= ~DiagDirToRoadBits(ReverseDiagDir(target_dir));
1838 if (cur_rb == ROAD_NONE) return false;
1839
1840 if (IsTileType(tile, MP_TUNNELBRIDGE)) {
1841 /* Only build in the direction away from the tunnel or bridge. */
1842 target_dir = ReverseDiagDir(GetTunnelBridgeDirection(tile));
1843 } else {
1844 /* Select a random bit from the blockmask, walk a step
1845 * and continue the search from there. */
1846 do {
1847 if (cur_rb == ROAD_NONE) return false;
1848 RoadBits target_bits;
1849 do {
1850 target_dir = RandomDiagDir();
1851 target_bits = DiagDirToRoadBits(target_dir);
1852 } while (!(cur_rb & target_bits));
1853 cur_rb &= ~target_bits;
1854 } while (!CanFollowRoad(tile, target_dir));
1855 }
1856 tile = TileAddByDiagDir(tile, target_dir);
1857
1858 if (IsTileType(tile, MP_ROAD) && !IsRoadDepot(tile) && HasTileRoadType(tile, RTT_ROAD)) {
1859 /* Don't allow building over roads of other cities */
1860 if (IsRoadOwner(tile, RTT_ROAD, OWNER_TOWN) && Town::GetByTile(tile) != t) {
1861 return false;
1862 } else if (IsRoadOwner(tile, RTT_ROAD, OWNER_NONE) && _game_mode == GM_EDITOR) {
1863 /* If we are in the SE, and this road-piece has no town owner yet, it just found an
1864 * owner :) (happy happy happy road now) */
1865 SetRoadOwner(tile, RTT_ROAD, OWNER_TOWN);
1866 SetTownIndex(tile, t->index);
1867 }
1868 }
1869
1870 /* Max number of times is checked. */
1871 } while (--_grow_town_result >= 0);
1872
1873 return false;
1874}
1875
1884{
1885 uint32_t r = Random();
1886 uint a = GB(r, 0, 2);
1887 uint b = GB(r, 8, 2);
1888 if (a == b) b ^= 2;
1889 return (RoadBits)((ROAD_NW << a) + (ROAD_NW << b));
1890}
1891
1897static bool GrowTown(Town *t)
1898{
1899 static const TileIndexDiffC _town_coord_mod[] = {
1900 {-1, 0},
1901 { 1, 1},
1902 { 1, -1},
1903 {-1, -1},
1904 {-1, 0},
1905 { 0, 2},
1906 { 2, 0},
1907 { 0, -2},
1908 {-1, -1},
1909 {-2, 2},
1910 { 2, 2},
1911 { 2, -2},
1912 { 0, 0}
1913 };
1914
1915 /* Current "company" is a town */
1917
1918 TileIndex tile = t->xy; // The tile we are working with ATM
1919
1920 /* Find a road that we can base the construction on. */
1921 for (const auto &ptr : _town_coord_mod) {
1922 if (GetTownRoadBits(tile) != ROAD_NONE) {
1923 bool success = GrowTownAtRoad(t, tile);
1924 cur_company.Restore();
1925 return success;
1926 }
1927 tile = TileAdd(tile, ToTileIndexDiff(ptr));
1928 }
1929
1930 /* No road available, try to build a random road block by
1931 * clearing some land and then building a road there. */
1933 tile = t->xy;
1934 for (const auto &ptr : _town_coord_mod) {
1935 /* Only work with plain land that not already has a house */
1936 if (!IsTileType(tile, MP_HOUSE) && IsTileFlat(tile)) {
1940 cur_company.Restore();
1941 return true;
1942 }
1943 }
1944 tile = TileAdd(tile, ToTileIndexDiff(ptr));
1945 }
1946 }
1947
1948 cur_company.Restore();
1949 return false;
1950}
1951
1957{
1958 static const std::array<std::array<uint32_t, HZB_END>, 23> _town_squared_town_zone_radius_data = {{
1959 { 4, 0, 0, 0, 0}, // 0
1960 { 16, 0, 0, 0, 0},
1961 { 25, 0, 0, 0, 0},
1962 { 36, 0, 0, 0, 0},
1963 { 49, 0, 4, 0, 0},
1964 { 64, 0, 4, 0, 0}, // 20
1965 { 64, 0, 9, 0, 1},
1966 { 64, 0, 9, 0, 4},
1967 { 64, 0, 16, 0, 4},
1968 { 81, 0, 16, 0, 4},
1969 { 81, 0, 16, 0, 4}, // 40
1970 { 81, 0, 25, 0, 9},
1971 { 81, 36, 25, 0, 9},
1972 { 81, 36, 25, 16, 9},
1973 { 81, 49, 0, 25, 9},
1974 { 81, 64, 0, 25, 9}, // 60
1975 { 81, 64, 0, 36, 9},
1976 { 81, 64, 0, 36, 16},
1977 {100, 81, 0, 49, 16},
1978 {100, 81, 0, 49, 25},
1979 {121, 81, 0, 49, 25}, // 80
1980 {121, 81, 0, 49, 25},
1981 {121, 81, 0, 49, 36}, // 88
1982 }};
1983
1984 if (t->cache.num_houses < std::size(_town_squared_town_zone_radius_data) * 4) {
1985 t->cache.squared_town_zone_radius = _town_squared_town_zone_radius_data[t->cache.num_houses / 4];
1986 } else {
1987 int mass = t->cache.num_houses / 8;
1988 /* Actually we are proportional to sqrt() but that's right because we are covering an area.
1989 * The offsets are to make sure the radii do not decrease in size when going from the table
1990 * to the calculated value.*/
1991 t->cache.squared_town_zone_radius[HZB_TOWN_EDGE] = mass * 15 - 40;
1992 t->cache.squared_town_zone_radius[HZB_TOWN_OUTSKIRT] = mass * 9 - 15;
1993 t->cache.squared_town_zone_radius[HZB_TOWN_OUTER_SUBURB] = 0;
1994 t->cache.squared_town_zone_radius[HZB_TOWN_INNER_SUBURB] = mass * 5 - 5;
1995 t->cache.squared_town_zone_radius[HZB_TOWN_CENTRE] = mass * 3 + 5;
1996 }
1997}
1998
2004{
2006 t->supplied[cs->Index()].old_max = ScaleByCargoScale(t->cache.population >> 3, true);
2007 }
2009 t->supplied[cs->Index()].old_max = ScaleByCargoScale(t->cache.population >> 4, true);
2010 }
2011}
2012
2013static void UpdateTownGrowthRate(Town *t);
2014static void UpdateTownGrowth(Town *t);
2015
2027static void DoCreateTown(Town *t, TileIndex tile, uint32_t townnameparts, TownSize size, bool city, TownLayout layout, bool manual)
2028{
2029 AutoRestoreBackup backup(_generating_town, true);
2030
2031 t->xy = tile;
2032 t->cache.num_houses = 0;
2033 t->time_until_rebuild = 10;
2035 t->flags = 0;
2036 t->cache.population = 0;
2038 /* Spread growth across ticks so even if there are many
2039 * similar towns they're unlikely to grow all in one tick */
2041 t->growth_rate = TownTicksToGameTicks(250);
2042 t->show_zone = false;
2043
2044 _town_kdtree.Insert(t->index);
2045
2046 /* Set the default cargo requirement for town growth */
2048 case LandscapeType::Arctic:
2050 break;
2051
2052 case LandscapeType::Tropic:
2055 break;
2056
2057 default:
2058 break;
2059 }
2060
2061 t->fund_buildings_months = 0;
2062
2063 for (uint i = 0; i != MAX_COMPANIES; i++) t->ratings[i] = RATING_INITIAL;
2064
2065 t->have_ratings = {};
2066 t->exclusivity = CompanyID::Invalid();
2067 t->exclusive_counter = 0;
2068 t->statues = {};
2069
2070 {
2072 t->townnamegrfid = tnp.grfid;
2073 t->townnametype = tnp.type;
2074 }
2075 t->townnameparts = townnameparts;
2076
2077 t->InitializeLayout(layout);
2078
2079 t->larger_town = city;
2080
2081 int x = (int)size * 16 + 3;
2082 if (size == TSZ_RANDOM) x = (Random() & 0xF) + 8;
2083 /* Don't create huge cities when founding town in-game */
2084 if (city && (!manual || _game_mode == GM_EDITOR)) x *= _settings_game.economy.initial_city_size;
2085
2086 t->cache.num_houses += x;
2088
2089 int i = x * 4;
2090 do {
2091 GrowTown(t);
2092 } while (--i);
2093
2094 t->UpdateVirtCoord();
2095 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_REBUILD);
2096
2097 t->cache.num_houses -= x;
2102}
2103
2110{
2111 /* Check if too close to the edge of map */
2112 if (DistanceFromEdge(tile) < 12) {
2113 return CommandCost(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB);
2114 }
2115
2116 /* Check distance to all other towns. */
2117 if (IsCloseToTown(tile, 20)) {
2118 return CommandCost(STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN);
2119 }
2120
2121 /* Can only build on clear flat areas, possibly with trees. */
2122 if ((!IsTileType(tile, MP_CLEAR) && !IsTileType(tile, MP_TREES)) || !IsTileFlat(tile)) {
2123 return CommandCost(STR_ERROR_SITE_UNSUITABLE);
2124 }
2125
2127}
2128
2134static bool IsUniqueTownName(const std::string &name)
2135{
2136 for (const Town *t : Town::Iterate()) {
2137 if (!t->name.empty() && t->name == name) return false;
2138 }
2139
2140 return true;
2141}
2142
2155std::tuple<CommandCost, Money, TownID> CmdFoundTown(DoCommandFlags flags, TileIndex tile, TownSize size, bool city, TownLayout layout, bool random_location, uint32_t townnameparts, const std::string &text)
2156{
2158
2159 if (size >= TSZ_END) return { CMD_ERROR, 0, TownID::Invalid() };
2160 if (layout >= NUM_TLS) return { CMD_ERROR, 0, TownID::Invalid() };
2161
2162 /* Some things are allowed only in the scenario editor and for game scripts. */
2163 if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY) {
2164 if (_settings_game.economy.found_town == TF_FORBIDDEN) return { CMD_ERROR, 0, TownID::Invalid() };
2165 if (size == TSZ_LARGE) return { CMD_ERROR, 0, TownID::Invalid() };
2166 if (random_location) return { CMD_ERROR, 0, TownID::Invalid() };
2168 return { CMD_ERROR, 0, TownID::Invalid() };
2169 }
2170 } else if (_current_company == OWNER_DEITY && random_location) {
2171 /* Random parameter is not allowed for Game Scripts. */
2172 return { CMD_ERROR, 0, TownID::Invalid() };
2173 }
2174
2175 if (text.empty()) {
2176 /* If supplied name is empty, townnameparts has to generate unique automatic name */
2177 if (!VerifyTownName(townnameparts, &par)) return { CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE), 0, TownID::Invalid() };
2178 } else {
2179 /* If name is not empty, it has to be unique custom name */
2180 if (Utf8StringLength(text) >= MAX_LENGTH_TOWN_NAME_CHARS) return { CMD_ERROR, 0, TownID::Invalid() };
2181 if (!IsUniqueTownName(text)) return { CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE), 0, TownID::Invalid() };
2182 }
2183
2184 /* Allocate town struct */
2185 if (!Town::CanAllocateItem()) return { CommandCost(STR_ERROR_TOO_MANY_TOWNS), 0, TownID::Invalid() };
2186
2187 if (!random_location) {
2188 CommandCost ret = TownCanBePlacedHere(tile);
2189 if (ret.Failed()) return { ret, 0, TownID::Invalid() };
2190 }
2191
2192 static const uint8_t price_mult[][TSZ_RANDOM + 1] = {{ 15, 25, 40, 25 }, { 20, 35, 55, 35 }};
2193 /* multidimensional arrays have to have defined length of non-first dimension */
2194 static_assert(lengthof(price_mult[0]) == 4);
2195
2196 CommandCost cost(EXPENSES_OTHER, _price[PR_BUILD_TOWN]);
2197 uint8_t mult = price_mult[city][size];
2198
2199 cost.MultiplyCost(mult);
2200
2201 /* Create the town */
2202 TownID new_town = TownID::Invalid();
2203 if (flags.Test(DoCommandFlag::Execute)) {
2204 if (cost.GetCost() > GetAvailableMoneyForCommand()) {
2205 return { CommandCost(EXPENSES_OTHER), cost.GetCost(), TownID::Invalid() };
2206 }
2207
2208 Backup<bool> old_generating_world(_generating_world, true);
2210 Town *t;
2211 if (random_location) {
2212 t = CreateRandomTown(20, townnameparts, size, city, layout);
2213 } else {
2214 t = new Town(tile);
2215 DoCreateTown(t, tile, townnameparts, size, city, layout, true);
2216 }
2217
2219 old_generating_world.Restore();
2220
2221 if (t == nullptr) return { CommandCost(STR_ERROR_NO_SPACE_FOR_TOWN), 0, TownID::Invalid() };
2222
2223 new_town = t->index;
2224
2225 if (!text.empty()) {
2226 t->name = text;
2227 t->UpdateVirtCoord();
2228 }
2229
2230 if (_game_mode != GM_EDITOR) {
2231 /* 't' can't be nullptr since 'random' is false outside scenedit */
2232 assert(!random_location);
2233
2235 AddTileNewsItem(GetEncodedString(STR_NEWS_NEW_TOWN_UNSPONSORED, t->index), NewsType::IndustryOpen, tile);
2236 } else {
2237 std::string company_name = GetString(STR_COMPANY_NAME, _current_company);
2238 AddTileNewsItem(GetEncodedString(STR_NEWS_NEW_TOWN, company_name, t->index), NewsType::IndustryOpen, tile);
2239 }
2240 AI::BroadcastNewEvent(new ScriptEventTownFounded(t->index));
2241 Game::NewEvent(new ScriptEventTownFounded(t->index));
2242 }
2243 }
2244 return { cost, 0, new_town };
2245}
2246
2257{
2258 switch (layout) {
2259 case TL_2X2_GRID: return TileXY(TileX(tile) - TileX(tile) % 3, TileY(tile) - TileY(tile) % 3);
2260 case TL_3X3_GRID: return TileXY(TileX(tile) & ~3, TileY(tile) & ~3);
2261 default: return tile;
2262 }
2263}
2264
2275{
2276 switch (layout) {
2277 case TL_2X2_GRID: return TileX(tile) % 3 == 0 && TileY(tile) % 3 == 0;
2278 case TL_3X3_GRID: return TileX(tile) % 4 == 0 && TileY(tile) % 4 == 0;
2279 default: return true;
2280 }
2281}
2282
2291
2308static bool FindFurthestFromWater(TileIndex tile, void *user_data)
2309{
2310 SpotData *sp = (SpotData*)user_data;
2311 uint dist = GetClosestWaterDistance(tile, true);
2312
2313 if (IsTileType(tile, MP_CLEAR) &&
2314 IsTileFlat(tile) &&
2315 IsTileAlignedToGrid(tile, sp->layout) &&
2316 dist > sp->max_dist) {
2317 sp->tile = tile;
2318 sp->max_dist = dist;
2319 }
2320
2321 return false;
2322}
2323
2328static bool FindNearestEmptyLand(TileIndex tile, void *)
2329{
2330 return IsTileType(tile, MP_CLEAR);
2331}
2332
2346{
2347 SpotData sp = { INVALID_TILE, 0, layout };
2348
2349 TileIndex coast = tile;
2350 if (CircularTileSearch(&coast, 40, FindNearestEmptyLand, nullptr)) {
2351 CircularTileSearch(&coast, 10, FindFurthestFromWater, &sp);
2352 return sp.tile;
2353 }
2354
2355 /* if we get here just give up */
2356 return INVALID_TILE;
2357}
2358
2368static Town *CreateRandomTown(uint attempts, uint32_t townnameparts, TownSize size, bool city, TownLayout layout)
2369{
2370 assert(_game_mode == GM_EDITOR || _generating_world); // These are the preconditions for CMD_DELETE_TOWN
2371
2372 if (!Town::CanAllocateItem()) return nullptr;
2373
2374 do {
2375 /* Generate a tile index not too close from the edge */
2376 TileIndex tile = AlignTileToGrid(RandomTile(), layout);
2377
2378 /* if we tried to place the town on water, slide it over onto
2379 * the nearest likely-looking spot */
2380 if (IsTileType(tile, MP_WATER)) {
2381 tile = FindNearestGoodCoastalTownSpot(tile, layout);
2382 if (tile == INVALID_TILE) continue;
2383 }
2384
2385 /* Make sure town can be placed here */
2386 if (TownCanBePlacedHere(tile).Failed()) continue;
2387
2388 /* Allocate a town struct */
2389 Town *t = new Town(tile);
2390
2391 DoCreateTown(t, tile, townnameparts, size, city, layout, false);
2392
2393 /* if the population is still 0 at the point, then the
2394 * placement is so bad it couldn't grow at all */
2395 if (t->cache.population > 0) return t;
2396
2399 cur_company.Restore();
2400 assert(rc.Succeeded());
2401
2402 /* We already know that we can allocate a single town when
2403 * entering this function. However, we create and delete
2404 * a town which "resets" the allocation checks. As such we
2405 * need to check again when assertions are enabled. */
2406 assert(Town::CanAllocateItem());
2407 } while (--attempts != 0);
2408
2409 return nullptr;
2410}
2411
2412static const uint8_t _num_initial_towns[4] = {5, 11, 23, 46}; // very low, low, normal, high
2413
2421{
2422 uint current_number = 0;
2423 uint difficulty = (_game_mode != GM_EDITOR) ? _settings_game.difficulty.number_towns : 0;
2424 uint total = (difficulty == (uint)CUSTOM_TOWN_NUMBER_DIFFICULTY) ? _settings_game.game_creation.custom_town_number : Map::ScaleBySize(_num_initial_towns[difficulty] + (Random() & 7));
2425 total = std::min<uint>(TownPool::MAX_SIZE, total);
2426 uint32_t townnameparts;
2427 TownNames town_names;
2428
2430
2431 /* Pre-populate the town names list with the names of any towns already on the map */
2432 for (const Town *town : Town::Iterate()) {
2433 town_names.insert(town->GetCachedName());
2434 }
2435
2436 /* Randomised offset for city status. This means with e.g. 1-in-4 towns being cities, a map with 10 towns
2437 * may have 2 or 3 cities, instead of always 3. */
2438 uint city_random_offset = _settings_game.economy.larger_towns == 0 ? 0 : (Random() % _settings_game.economy.larger_towns);
2439
2440 /* First attempt will be made at creating the suggested number of towns.
2441 * Note that this is really a suggested value, not a required one.
2442 * We would not like the system to lock up just because the user wanted 100 cities on a 64*64 map, would we? */
2443 do {
2444 bool city = (_settings_game.economy.larger_towns != 0 && ((city_random_offset + current_number) % _settings_game.economy.larger_towns) == 0);
2446 /* Get a unique name for the town. */
2447 if (!GenerateTownName(_random, &townnameparts, &town_names)) continue;
2448 /* try 20 times to create a random-sized town for the first loop. */
2449 if (CreateRandomTown(20, townnameparts, TSZ_RANDOM, city, layout) != nullptr) current_number++; // If creation was successful, raise a flag.
2450 } while (--total);
2451
2452 town_names.clear();
2453
2454 /* Build the town k-d tree again to make sure it's well balanced */
2455 RebuildTownKdtree();
2456
2457 if (current_number != 0) return true;
2458
2459 /* If current_number is still zero at this point, it means that not a single town has been created.
2460 * So give it a last try, but now more aggressive */
2461 if (GenerateTownName(_random, &townnameparts) &&
2462 CreateRandomTown(10000, townnameparts, TSZ_RANDOM, _settings_game.economy.larger_towns != 0, layout) != nullptr) {
2463 return true;
2464 }
2465
2466 /* If there are no towns at all and we are generating new game, bail out */
2467 if (Town::GetNumItems() == 0 && _game_mode != GM_EDITOR) {
2468 ShowErrorMessage(GetEncodedString(STR_ERROR_COULD_NOT_CREATE_TOWN), {}, WL_CRITICAL);
2469 }
2470
2471 return false; // we are still without a town? we failed, simply
2472}
2473
2474
2481HouseZonesBits GetTownRadiusGroup(const Town *t, TileIndex tile)
2482{
2483 uint dist = DistanceSquare(tile, t->xy);
2484
2485 if (t->fund_buildings_months && dist <= 25) return HZB_TOWN_CENTRE;
2486
2487 HouseZonesBits smallest = HZB_TOWN_EDGE;
2488 for (HouseZonesBits i = HZB_BEGIN; i < HZB_END; i++) {
2489 if (dist < t->cache.squared_town_zone_radius[i]) smallest = i;
2490 }
2491
2492 return smallest;
2493}
2494
2506static inline void ClearMakeHouseTile(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool is_protected)
2507{
2509 assert(cc.Succeeded());
2510
2511 IncreaseBuildingCount(t, type);
2512 MakeHouseTile(tile, t->index, counter, stage, type, random_bits, is_protected);
2513 if (HouseSpec::Get(type)->building_flags.Test(BuildingFlag::IsAnimated)) AddAnimatedTile(tile, false);
2514
2515 MarkTileDirtyByTile(tile);
2516}
2517
2518
2530static void MakeTownHouse(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool is_protected)
2531{
2533
2534 ClearMakeHouseTile(tile, t, counter, stage, type, random_bits, is_protected);
2535 if (size.Any(BUILDING_2_TILES_Y)) ClearMakeHouseTile(tile + TileDiffXY(0, 1), t, counter, stage, ++type, random_bits, is_protected);
2536 if (size.Any(BUILDING_2_TILES_X)) ClearMakeHouseTile(tile + TileDiffXY(1, 0), t, counter, stage, ++type, random_bits, is_protected);
2537 if (size.Any(BUILDING_HAS_4_TILES)) ClearMakeHouseTile(tile + TileDiffXY(1, 1), t, counter, stage, ++type, random_bits, is_protected);
2538
2539 ForAllStationsAroundTiles(TileArea(tile, size.Any(BUILDING_2_TILES_X) ? 2 : 1, size.Any(BUILDING_2_TILES_Y) ? 2 : 1), [t](Station *st, TileIndex) {
2540 t->stations_near.insert(st);
2541 return true;
2542 });
2543}
2544
2545
2552static inline bool CanBuildHouseHere(TileIndex tile, bool noslope)
2553{
2554 /* cannot build on these slopes... */
2555 Slope slope = GetTileSlope(tile);
2556 if ((noslope && slope != SLOPE_FLAT) || IsSteepSlope(slope)) return false;
2557
2558 /* at least one RoadTypes allow building the house here? */
2559 if (!RoadTypesAllowHouseHere(tile)) return false;
2560
2561 /* building under a bridge? */
2562 if (IsBridgeAbove(tile)) return false;
2563
2564 /* can we clear the land? */
2566}
2567
2568
2577static inline bool CheckBuildHouseSameZ(TileIndex tile, int z, bool noslope)
2578{
2579 if (!CanBuildHouseHere(tile, noslope)) return false;
2580
2581 /* if building on slopes is allowed, there will be flattening foundation (to tile max z) */
2582 if (GetTileMaxZ(tile) != z) return false;
2583
2584 return true;
2585}
2586
2587
2596static bool CheckFree2x2Area(TileIndex tile, int z, bool noslope)
2597{
2598 /* we need to check this tile too because we can be at different tile now */
2599 if (!CheckBuildHouseSameZ(tile, z, noslope)) return false;
2600
2601 for (DiagDirection d = DIAGDIR_SE; d < DIAGDIR_END; d++) {
2602 tile += TileOffsByDiagDir(d);
2603 if (!CheckBuildHouseSameZ(tile, z, noslope)) return false;
2604 }
2605
2606 return true;
2607}
2608
2609
2617static inline bool TownLayoutAllowsHouseHere(Town *t, TileIndex tile)
2618{
2619 /* Allow towns everywhere when we don't build roads */
2620 if (!TownAllowedToBuildRoads()) return true;
2621
2622 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
2623
2624 switch (t->layout) {
2625 case TL_2X2_GRID:
2626 if ((grid_pos.x % 3) == 0 || (grid_pos.y % 3) == 0) return false;
2627 break;
2628
2629 case TL_3X3_GRID:
2630 if ((grid_pos.x % 4) == 0 || (grid_pos.y % 4) == 0) return false;
2631 break;
2632
2633 default:
2634 break;
2635 }
2636
2637 return true;
2638}
2639
2640
2648static inline bool TownLayoutAllows2x2HouseHere(Town *t, TileIndex tile)
2649{
2650 /* Allow towns everywhere when we don't build roads */
2651 if (!TownAllowedToBuildRoads()) return true;
2652
2653 /* Compute relative position of tile. (Positive offsets are towards north) */
2654 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
2655
2656 switch (t->layout) {
2657 case TL_2X2_GRID:
2658 grid_pos.x %= 3;
2659 grid_pos.y %= 3;
2660 if ((grid_pos.x != 2 && grid_pos.x != -1) ||
2661 (grid_pos.y != 2 && grid_pos.y != -1)) return false;
2662 break;
2663
2664 case TL_3X3_GRID:
2665 if ((grid_pos.x & 3) < 2 || (grid_pos.y & 3) < 2) return false;
2666 break;
2667
2668 default:
2669 break;
2670 }
2671
2672 return true;
2673}
2674
2675
2685static bool CheckTownBuild2House(TileIndex *tile, Town *t, int maxz, bool noslope, DiagDirection second)
2686{
2687 /* 'tile' is already checked in BuildTownHouse() - CanBuildHouseHere() and slope test */
2688
2689 TileIndex tile2 = *tile + TileOffsByDiagDir(second);
2690 if (TownLayoutAllowsHouseHere(t, tile2) && CheckBuildHouseSameZ(tile2, maxz, noslope)) return true;
2691
2692 tile2 = *tile + TileOffsByDiagDir(ReverseDiagDir(second));
2693 if (TownLayoutAllowsHouseHere(t, tile2) && CheckBuildHouseSameZ(tile2, maxz, noslope)) {
2694 *tile = tile2;
2695 return true;
2696 }
2697
2698 return false;
2699}
2700
2701
2710static bool CheckTownBuild2x2House(TileIndex *tile, Town *t, int maxz, bool noslope)
2711{
2712 TileIndex tile2 = *tile;
2713
2714 for (DiagDirection d = DIAGDIR_SE;; d++) { // 'd' goes through DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_END
2715 if (TownLayoutAllows2x2HouseHere(t, tile2) && CheckFree2x2Area(tile2, maxz, noslope)) {
2716 *tile = tile2;
2717 return true;
2718 }
2719 if (d == DIAGDIR_END) break;
2720 tile2 += TileOffsByDiagDir(ReverseDiagDir(d)); // go clockwise
2721 }
2722
2723 return false;
2724}
2725
2736static void BuildTownHouse(Town *t, TileIndex tile, const HouseSpec *hs, HouseID house, uint8_t random_bits, bool house_completed, bool is_protected)
2737{
2738 /* build the house */
2739 t->cache.num_houses++;
2740
2741 uint8_t construction_counter = 0;
2742 uint8_t construction_stage = 0;
2743
2744 if (_generating_world || _game_mode == GM_EDITOR || house_completed) {
2745 uint32_t construction_random = Random();
2746
2747 construction_stage = TOWN_HOUSE_COMPLETED;
2748 if (_generating_world && !hs->extra_flags.Test(HouseExtraFlag::BuildingIsHistorical) && Chance16(1, 7)) construction_stage = GB(construction_random, 0, 2);
2749
2750 if (construction_stage == TOWN_HOUSE_COMPLETED) {
2752 } else {
2753 construction_counter = GB(construction_random, 2, 2);
2754 }
2755 }
2756
2757 MakeTownHouse(tile, t, construction_counter, construction_stage, house, random_bits, is_protected);
2760}
2761
2768static bool TryBuildTownHouse(Town *t, TileIndex tile)
2769{
2770 /* forbidden building here by town layout */
2771 if (!TownLayoutAllowsHouseHere(t, tile)) return false;
2772
2773 /* no house allowed at all, bail out */
2774 if (!CanBuildHouseHere(tile, false)) return false;
2775
2776 Slope slope = GetTileSlope(tile);
2777 int maxz = GetTileMaxZ(tile);
2778
2779 /* Get the town zone type of the current tile, as well as the climate.
2780 * This will allow to easily compare with the specs of the new house to build */
2781 HouseZonesBits rad = GetTownRadiusGroup(t, tile);
2782
2783 /* Above snow? */
2785 if (_settings_game.game_creation.landscape == LandscapeType::Arctic && maxz > HighestSnowLine()) land = -1;
2786
2787 uint bitmask = (1 << rad) + (1 << (land + 12));
2788
2789 /* bits 0-4 are used
2790 * bits 11-15 are used
2791 * bits 5-10 are not used. */
2792 static std::vector<std::pair<HouseID, uint>> probs;
2793 probs.clear();
2794
2795 uint probability_max = 0;
2796
2797 /* Generate a list of all possible houses that can be built. */
2798 for (const auto &hs : HouseSpec::Specs()) {
2799 /* Verify that the candidate house spec matches the current tile status */
2800 if ((~hs.building_availability & bitmask) != 0 || !hs.enabled || hs.grf_prop.override != INVALID_HOUSE_ID) continue;
2801
2802 /* Don't let these counters overflow. Global counters are 32bit, there will never be that many houses. */
2803 if (hs.class_id != HOUSE_NO_CLASS) {
2804 /* id_count is always <= class_count, so it doesn't need to be checked */
2805 if (t->cache.building_counts.class_count[hs.class_id] == UINT16_MAX) continue;
2806 } else {
2807 /* If the house has no class, check id_count instead */
2808 if (t->cache.building_counts.id_count[hs.Index()] == UINT16_MAX) continue;
2809 }
2810
2811 uint cur_prob = hs.probability;
2812 probability_max += cur_prob;
2813 probs.emplace_back(hs.Index(), cur_prob);
2814 }
2815
2816 TileIndex baseTile = tile;
2817
2818 while (probability_max > 0) {
2819 /* Building a multitile building can change the location of tile.
2820 * The building would still be built partially on that tile, but
2821 * its northern tile would be elsewhere. However, if the callback
2822 * fails we would be basing further work from the changed tile.
2823 * So a next 1x1 tile building could be built on the wrong tile. */
2824 tile = baseTile;
2825
2826 uint r = RandomRange(probability_max);
2827 uint i;
2828 for (i = 0; i < probs.size(); i++) {
2829 if (probs[i].second > r) break;
2830 r -= probs[i].second;
2831 }
2832
2833 HouseID house = probs[i].first;
2834 probability_max -= probs[i].second;
2835
2836 /* remove tested house from the set */
2837 probs[i] = probs.back();
2838 probs.pop_back();
2839
2840 const HouseSpec *hs = HouseSpec::Get(house);
2841
2842 if (!_generating_world && _game_mode != GM_EDITOR && hs->extra_flags.Test(HouseExtraFlag::BuildingIsHistorical)) {
2843 continue;
2844 }
2845
2846 if (TimerGameCalendar::year < hs->min_year || TimerGameCalendar::year > hs->max_year) continue;
2847
2848 /* Special houses that there can be only one of. */
2849 uint oneof = 0;
2850
2851 if (hs->building_flags.Test(BuildingFlag::IsChurch)) {
2852 SetBit(oneof, TOWN_HAS_CHURCH);
2853 } else if (hs->building_flags.Test(BuildingFlag::IsStadium)) {
2854 SetBit(oneof, TOWN_HAS_STADIUM);
2855 }
2856
2857 if (t->flags & oneof) continue;
2858
2859 /* Make sure there is no slope? */
2860 bool noslope = hs->building_flags.Test(BuildingFlag::NotSloped);
2861 if (noslope && slope != SLOPE_FLAT) continue;
2862
2863 if (hs->building_flags.Test(BuildingFlag::Size2x2)) {
2864 if (!CheckTownBuild2x2House(&tile, t, maxz, noslope)) continue;
2865 } else if (hs->building_flags.Test(BuildingFlag::Size2x1)) {
2866 if (!CheckTownBuild2House(&tile, t, maxz, noslope, DIAGDIR_SW)) continue;
2867 } else if (hs->building_flags.Test(BuildingFlag::Size1x2)) {
2868 if (!CheckTownBuild2House(&tile, t, maxz, noslope, DIAGDIR_SE)) continue;
2869 } else {
2870 /* 1x1 house checks are already done */
2871 }
2872
2873 uint8_t random_bits = Random();
2874
2876 uint16_t callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile, true, random_bits);
2877 if (callback_res != CALLBACK_FAILED && !Convert8bitBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_ALLOW_CONSTRUCTION, callback_res)) continue;
2878 }
2879
2880 /* Special houses that there can be only one of. */
2881 t->flags |= oneof;
2882
2883 BuildTownHouse(t, tile, hs, house, random_bits, false, hs->extra_flags.Test(HouseExtraFlag::BuildingIsProtected));
2884
2885 return true;
2886 }
2887
2888 return false;
2889}
2890
2899CommandCost CmdPlaceHouse(DoCommandFlags flags, TileIndex tile, HouseID house, bool is_protected)
2900{
2901 if (_game_mode != GM_EDITOR && _settings_game.economy.place_houses == PH_FORBIDDEN) return CMD_ERROR;
2902
2903 if (Town::GetNumItems() == 0) return CommandCost(STR_ERROR_MUST_FOUND_TOWN_FIRST);
2904
2905 if (static_cast<size_t>(house) >= HouseSpec::Specs().size()) return CMD_ERROR;
2906 const HouseSpec *hs = HouseSpec::Get(house);
2907 if (!hs->enabled) return CMD_ERROR;
2908
2909 Town *t = ClosestTownFromTile(tile, UINT_MAX);
2910
2911 /* cannot build on these slopes... */
2912 Slope slope = GetTileSlope(tile);
2913 if (IsSteepSlope(slope)) return CommandCost(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
2914
2915 /* building under a bridge? */
2916 if (IsBridgeAbove(tile)) return CommandCost(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
2917
2918 /* can we clear the land? */
2920 if (!cost.Succeeded()) return cost;
2921
2922 int maxz = GetTileMaxZ(tile);
2923
2924 /* Make sure there is no slope? */
2925 bool noslope = hs->building_flags.Test(BuildingFlag::NotSloped);
2926 if (noslope && slope != SLOPE_FLAT) return CommandCost(STR_ERROR_FLAT_LAND_REQUIRED);
2927
2928 TileArea ta = tile;
2929 if (hs->building_flags.Test(BuildingFlag::Size2x2)) ta.Add(TileAddXY(tile, 1, 1));
2930 if (hs->building_flags.Test(BuildingFlag::Size2x1)) ta.Add(TileAddByDiagDir(tile, DIAGDIR_SW));
2931 if (hs->building_flags.Test(BuildingFlag::Size1x2)) ta.Add(TileAddByDiagDir(tile, DIAGDIR_SE));
2932
2933 /* Check additional tiles covered by this house. */
2934 for (const TileIndex &subtile : ta) {
2936 if (!cost.Succeeded()) return cost;
2937
2938 if (!CheckBuildHouseSameZ(subtile, maxz, noslope)) return CommandCost(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
2939 }
2940
2941 if (flags.Test(DoCommandFlag::Execute)) {
2942 bool house_completed = _settings_game.economy.place_houses == PH_ALLOWED_CONSTRUCTED;
2943 BuildTownHouse(t, tile, hs, house, Random(), house_completed, is_protected);
2944 }
2945
2946 return CommandCost();
2947}
2948
2955static void DoClearTownHouseHelper(TileIndex tile, Town *t, HouseID house)
2956{
2957 assert(IsTileType(tile, MP_HOUSE));
2958 DecreaseBuildingCount(t, house);
2959 DoClearSquare(tile);
2960
2961 DeleteNewGRFInspectWindow(GSF_HOUSES, tile.base());
2962}
2963
2972{
2973 if (house >= 3) { // house id 0,1,2 MUST be single tile houses, or this code breaks.
2974 if (HouseSpec::Get(house - 1)->building_flags.Test(BuildingFlag::Size2x1)) {
2975 house--;
2976 return TileDiffXY(-1, 0);
2977 } else if (HouseSpec::Get(house - 1)->building_flags.Any(BUILDING_2_TILES_Y)) {
2978 house--;
2979 return TileDiffXY(0, -1);
2980 } else if (HouseSpec::Get(house - 2)->building_flags.Any(BUILDING_HAS_4_TILES)) {
2981 house -= 2;
2982 return TileDiffXY(-1, 0);
2983 } else if (HouseSpec::Get(house - 3)->building_flags.Any(BUILDING_HAS_4_TILES)) {
2984 house -= 3;
2985 return TileDiffXY(-1, -1);
2986 }
2987 }
2988 return TileDiffXY(0, 0);
2989}
2990
2997{
2998 assert(IsTileType(tile, MP_HOUSE));
2999
3000 HouseID house = GetHouseType(tile);
3001
3002 /* The northernmost tile of the house is the main house. */
3003 tile += GetHouseNorthPart(house);
3004
3005 const HouseSpec *hs = HouseSpec::Get(house);
3006
3007 /* Remove population from the town if the house is finished. */
3008 if (IsHouseCompleted(tile)) {
3010 }
3011
3012 t->cache.num_houses--;
3013
3014 /* Clear flags for houses that only may exist once/town. */
3015 if (hs->building_flags.Test(BuildingFlag::IsChurch)) {
3017 } else if (hs->building_flags.Test(BuildingFlag::IsStadium)) {
3019 }
3020
3021 /* Do the actual clearing of tiles */
3022 DoClearTownHouseHelper(tile, t, house);
3023 if (hs->building_flags.Any(BUILDING_2_TILES_Y)) DoClearTownHouseHelper(tile + TileDiffXY(0, 1), t, ++house);
3024 if (hs->building_flags.Any(BUILDING_2_TILES_X)) DoClearTownHouseHelper(tile + TileDiffXY(1, 0), t, ++house);
3025 if (hs->building_flags.Any(BUILDING_HAS_4_TILES)) DoClearTownHouseHelper(tile + TileDiffXY(1, 1), t, ++house);
3026
3028
3030}
3031
3039CommandCost CmdRenameTown(DoCommandFlags flags, TownID town_id, const std::string &text)
3040{
3041 Town *t = Town::GetIfValid(town_id);
3042 if (t == nullptr) return CMD_ERROR;
3043
3044 bool reset = text.empty();
3045
3046 if (!reset) {
3048 if (!IsUniqueTownName(text)) return CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE);
3049 }
3050
3051 if (flags.Test(DoCommandFlag::Execute)) {
3052 t->cached_name.clear();
3053 if (reset) {
3054 t->name.clear();
3055 } else {
3056 t->name = text;
3057 }
3058
3059 t->UpdateVirtCoord();
3060 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_RESORT);
3061 ClearAllStationCachedNames();
3062 ClearAllIndustryCachedNames();
3064 }
3065 return CommandCost();
3066}
3067
3074{
3075 for (const CargoSpec *cs : CargoSpec::Iterate()) {
3076 if (cs->town_acceptance_effect == effect) return cs;
3077 }
3078 return nullptr;
3079}
3080
3090{
3091 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3092
3093 if (tae < TAE_BEGIN || tae >= TAE_END) return CMD_ERROR;
3094
3095 Town *t = Town::GetIfValid(town_id);
3096 if (t == nullptr) return CMD_ERROR;
3097
3098 /* Validate if there is a cargo which is the requested TownEffect */
3100 if (cargo == nullptr) return CMD_ERROR;
3101
3102 if (flags.Test(DoCommandFlag::Execute)) {
3103 t->goal[tae] = goal;
3106 }
3107
3108 return CommandCost();
3109}
3110
3119{
3120 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3121 Town *t = Town::GetIfValid(town_id);
3122 if (t == nullptr) return CMD_ERROR;
3123
3124 if (flags.Test(DoCommandFlag::Execute)) {
3125 t->text.clear();
3126 if (!text.empty()) t->text = text;
3128 }
3129
3130 return CommandCost();
3131}
3132
3140CommandCost CmdTownGrowthRate(DoCommandFlags flags, TownID town_id, uint16_t growth_rate)
3141{
3142 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3143
3144 Town *t = Town::GetIfValid(town_id);
3145 if (t == nullptr) return CMD_ERROR;
3146
3147 if (flags.Test(DoCommandFlag::Execute)) {
3148 if (growth_rate == 0) {
3149 /* Just clear the flag, UpdateTownGrowth will determine a proper growth rate */
3151 } else {
3152 uint old_rate = t->growth_rate;
3153 if (t->grow_counter >= old_rate) {
3154 /* This also catches old_rate == 0 */
3155 t->grow_counter = growth_rate;
3156 } else {
3157 /* Scale grow_counter, so half finished houses stay half finished */
3158 t->grow_counter = t->grow_counter * growth_rate / old_rate;
3159 }
3160 t->growth_rate = growth_rate;
3162 }
3165 }
3166
3167 return CommandCost();
3168}
3169
3178CommandCost CmdTownRating(DoCommandFlags flags, TownID town_id, CompanyID company_id, int16_t rating)
3179{
3180 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3181
3182 Town *t = Town::GetIfValid(town_id);
3183 if (t == nullptr) return CMD_ERROR;
3184
3185 if (!Company::IsValidID(company_id)) return CMD_ERROR;
3186
3187 int16_t new_rating = Clamp(rating, RATING_MINIMUM, RATING_MAXIMUM);
3188 if (flags.Test(DoCommandFlag::Execute)) {
3189 t->ratings[company_id] = new_rating;
3191 }
3192
3193 return CommandCost();
3194}
3195
3203CommandCost CmdExpandTown(DoCommandFlags flags, TownID town_id, uint32_t grow_amount)
3204{
3205 if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY) return CMD_ERROR;
3206 Town *t = Town::GetIfValid(town_id);
3207 if (t == nullptr) return CMD_ERROR;
3208
3209 if (flags.Test(DoCommandFlag::Execute)) {
3210 /* The more houses, the faster we grow */
3211 if (grow_amount == 0) {
3212 uint amount = RandomRange(ClampTo<uint16_t>(t->cache.num_houses / 10)) + 3;
3213 t->cache.num_houses += amount;
3215
3216 uint n = amount * 10;
3217 do GrowTown(t); while (--n);
3218
3219 t->cache.num_houses -= amount;
3220 } else {
3221 for (; grow_amount > 0; grow_amount--) {
3222 /* Try several times to grow, as we are really suppose to grow */
3223 for (uint i = 0; i < 25; i++) if (GrowTown(t)) break;
3224 }
3225 }
3227
3229 }
3230
3231 return CommandCost();
3232}
3233
3241{
3242 if (_game_mode != GM_EDITOR && !_generating_world) return CMD_ERROR;
3243 Town *t = Town::GetIfValid(town_id);
3244 if (t == nullptr) return CMD_ERROR;
3245
3246 /* Stations refer to towns. */
3247 for (const Station *st : Station::Iterate()) {
3248 if (st->town == t) {
3249 /* Non-oil rig stations are always a problem. */
3250 if (!st->facilities.Test(StationFacility::Airport) || st->airport.type != AT_OILRIG) return CMD_ERROR;
3251 /* We can only automatically delete oil rigs *if* there's no vehicle on them. */
3252 CommandCost ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, st->airport.tile);
3253 if (ret.Failed()) return ret;
3254 }
3255 }
3256
3257 /* Waypoints refer to towns. */
3258 for (const Waypoint *wp : Waypoint::Iterate()) {
3259 if (wp->town == t) return CMD_ERROR;
3260 }
3261
3262 /* Depots refer to towns. */
3263 for (const Depot *d : Depot::Iterate()) {
3264 if (d->town == t) return CMD_ERROR;
3265 }
3266
3267 /* Check all tiles for town ownership. First check for bridge tiles, as
3268 * these do not directly have an owner so we need to check adjacent
3269 * tiles. This won't work correctly in the same loop if the adjacent
3270 * tile was already deleted earlier in the loop. */
3271 for (const auto current_tile : Map::Iterate()) {
3272 if (IsTileType(current_tile, MP_TUNNELBRIDGE) && TestTownOwnsBridge(current_tile, t)) {
3273 CommandCost ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, current_tile);
3274 if (ret.Failed()) return ret;
3275 }
3276 }
3277
3278 /* Check all remaining tiles for town ownership. */
3279 for (const auto current_tile : Map::Iterate()) {
3280 bool try_clear = false;
3281 switch (GetTileType(current_tile)) {
3282 case MP_ROAD:
3283 try_clear = HasTownOwnedRoad(current_tile) && GetTownIndex(current_tile) == t->index;
3284 break;
3285
3286 case MP_HOUSE:
3287 try_clear = GetTownIndex(current_tile) == t->index;
3288 break;
3289
3290 case MP_INDUSTRY:
3291 try_clear = Industry::GetByTile(current_tile)->town == t;
3292 break;
3293
3294 case MP_OBJECT:
3295 if (Town::GetNumItems() == 1) {
3296 /* No towns will be left, remove it! */
3297 try_clear = true;
3298 } else {
3299 Object *o = Object::GetByTile(current_tile);
3300 if (o->town == t) {
3301 if (o->type == OBJECT_STATUE) {
3302 /* Statue... always remove. */
3303 try_clear = true;
3304 } else {
3305 /* Tell to find a new town. */
3306 if (flags.Test(DoCommandFlag::Execute)) o->town = nullptr;
3307 }
3308 }
3309 }
3310 break;
3311
3312 default:
3313 break;
3314 }
3315 if (try_clear) {
3316 CommandCost ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, current_tile);
3317 if (ret.Failed()) return ret;
3318 }
3319 }
3320
3321 /* The town destructor will delete the other things related to the town. */
3322 if (flags.Test(DoCommandFlag::Execute)) {
3323 _town_kdtree.Remove(t->index);
3324 if (t->cache.sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeTown(t->index));
3325 delete t;
3326 }
3327
3328 return CommandCost();
3329}
3330
3337{
3342 static const uint8_t town_action_costs[] = {
3343 2, 4, 9, 35, 48, 53, 117, 175
3344 };
3345 static_assert(std::size(town_action_costs) == to_underlying(TownAction::End));
3346
3347 assert(to_underlying(action) < std::size(town_action_costs));
3348 return town_action_costs[to_underlying(action)];
3349}
3350
3358{
3359 if (flags.Test(DoCommandFlag::Execute)) {
3360 ModifyStationRatingAround(t->xy, _current_company, 0x40, 10);
3361 }
3362 return CommandCost();
3363}
3364
3372{
3373 if (flags.Test(DoCommandFlag::Execute)) {
3374 ModifyStationRatingAround(t->xy, _current_company, 0x70, 15);
3375 }
3376 return CommandCost();
3377}
3378
3386{
3387 if (flags.Test(DoCommandFlag::Execute)) {
3388 ModifyStationRatingAround(t->xy, _current_company, 0xA0, 20);
3389 }
3390 return CommandCost();
3391}
3392
3400{
3401 /* Check if the company is allowed to fund new roads. */
3403
3404 if (flags.Test(DoCommandFlag::Execute)) {
3405 t->road_build_months = 6;
3406
3407 std::string company_name = GetString(STR_COMPANY_NAME, _current_company);
3408
3410 GetEncodedString(TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_ROAD_REBUILDING_MINUTES : STR_NEWS_ROAD_REBUILDING_MONTHS, t->index, company_name),
3412 AI::BroadcastNewEvent(new ScriptEventRoadReconstruction(_current_company, t->index));
3413 Game::NewEvent(new ScriptEventRoadReconstruction(_current_company, t->index));
3414 }
3415 return CommandCost();
3416}
3417
3423static bool CheckClearTile(TileIndex tile)
3424{
3427 cur_company.Restore();
3428 return r.Succeeded();
3429}
3430
3435
3436 StatueBuildSearchData(TileIndex best_pos, int count) : best_position(best_pos), tile_count(count) { }
3437};
3438
3445static bool SearchTileForStatue(TileIndex tile, void *user_data)
3446{
3447 static const int STATUE_NUMBER_INNER_TILES = 25; // Number of tiles int the center of the city, where we try to protect houses.
3448
3449 StatueBuildSearchData *statue_data = (StatueBuildSearchData *)user_data;
3450 statue_data->tile_count++;
3451
3452 /* Statues can be build on slopes, just like houses. Only the steep slopes is a no go. */
3453 if (IsSteepSlope(GetTileSlope(tile))) return false;
3454 /* Don't build statues under bridges. */
3455 if (IsBridgeAbove(tile)) return false;
3456
3457 /* A clear-able open space is always preferred. */
3458 if ((IsTileType(tile, MP_CLEAR) || IsTileType(tile, MP_TREES)) && CheckClearTile(tile)) {
3459 statue_data->best_position = tile;
3460 return true;
3461 }
3462
3463 bool house = IsTileType(tile, MP_HOUSE);
3464
3465 /* Searching inside the inner circle. */
3466 if (statue_data->tile_count <= STATUE_NUMBER_INNER_TILES) {
3467 /* Save first house in inner circle. */
3468 if (house && statue_data->best_position == INVALID_TILE && CheckClearTile(tile)) {
3469 statue_data->best_position = tile;
3470 }
3471
3472 /* If we have reached the end of the inner circle, and have a saved house, terminate the search. */
3473 return statue_data->tile_count == STATUE_NUMBER_INNER_TILES && statue_data->best_position != INVALID_TILE;
3474 }
3475
3476 /* Searching outside the circle, just pick the first possible spot. */
3477 statue_data->best_position = tile; // Is optimistic, the condition below must also hold.
3478 return house && CheckClearTile(tile);
3479}
3480
3489{
3490 if (!Object::CanAllocateItem()) return CommandCost(STR_ERROR_TOO_MANY_OBJECTS);
3491
3492 TileIndex tile = t->xy;
3493 StatueBuildSearchData statue_data(INVALID_TILE, 0);
3494 if (!CircularTileSearch(&tile, 9, SearchTileForStatue, &statue_data)) return CommandCost(STR_ERROR_STATUE_NO_SUITABLE_PLACE);
3495
3496 if (flags.Test(DoCommandFlag::Execute)) {
3499 cur_company.Restore();
3501 t->statues.Set(_current_company); // Once found and built, "inform" the Town.
3503 }
3504 return CommandCost();
3505}
3506
3514{
3515 /* Check if it's allowed to buy the rights */
3517
3518 if (flags.Test(DoCommandFlag::Execute)) {
3519 /* And grow for 3 months */
3520 t->fund_buildings_months = 3;
3521
3522 /* Enable growth (also checking GameScript's opinion) */
3524
3525 /* Build a new house, but add a small delay to make sure
3526 * that spamming funding doesn't let town grow any faster
3527 * than 1 house per 2 * TOWN_GROWTH_TICKS ticks.
3528 * Also emulate original behaviour when town was only growing in
3529 * TOWN_GROWTH_TICKS intervals, to make sure that it's not too
3530 * tick-perfect and gives player some time window where they can
3531 * spam funding with the exact same efficiency.
3532 */
3534
3536 }
3537 return CommandCost();
3538}
3539
3547{
3548 /* Check if it's allowed to buy the rights */
3550 if (t->exclusivity != CompanyID::Invalid()) return CMD_ERROR;
3551
3552 if (flags.Test(DoCommandFlag::Execute)) {
3553 t->exclusive_counter = 12;
3555
3556 ModifyStationRatingAround(t->xy, _current_company, 130, 17);
3557
3559
3560 /* Spawn news message */
3561 auto cni = std::make_unique<CompanyNewsInformation>(STR_NEWS_EXCLUSIVE_RIGHTS_TITLE, Company::Get(_current_company));
3562 EncodedString message = GetEncodedString(TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MINUTES : STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MONTHS, t->index, cni->company_name);
3563 AddNewsItem(std::move(message),
3564 NewsType::General, NewsStyle::Company, {}, t->index, {}, std::move(cni));
3565 AI::BroadcastNewEvent(new ScriptEventExclusiveTransportRights(_current_company, t->index));
3566 Game::NewEvent(new ScriptEventExclusiveTransportRights(_current_company, t->index));
3567 }
3568 return CommandCost();
3569}
3570
3578{
3579 if (flags.Test(DoCommandFlag::Execute)) {
3580 if (Chance16(1, 14)) {
3581 /* set as unwanted for 6 months */
3582 t->unwanted[_current_company] = 6;
3583
3584 /* set all close by station ratings to 0 */
3585 for (Station *st : Station::Iterate()) {
3586 if (st->town == t && st->owner == _current_company) {
3587 for (GoodsEntry &ge : st->goods) ge.rating = 0;
3588 }
3589 }
3590
3591 /* only show error message to the executing player. All errors are handled command.c
3592 * but this is special, because it can only 'fail' on a DoCommandFlag::Execute */
3593 if (IsLocalCompany()) ShowErrorMessage(GetEncodedString(STR_ERROR_BRIBE_FAILED), {}, WL_INFO);
3594
3595 /* decrease by a lot!
3596 * ChangeTownRating is only for stuff in demolishing. Bribe failure should
3597 * be independent of any cheat settings
3598 */
3599 if (t->ratings[_current_company] > RATING_BRIBE_DOWN_TO) {
3600 t->ratings[_current_company] = RATING_BRIBE_DOWN_TO;
3602 }
3603 } else {
3604 ChangeTownRating(t, RATING_BRIBE_UP_STEP, RATING_BRIBE_MAXIMUM, DoCommandFlag::Execute);
3605 if (t->exclusivity != _current_company && t->exclusivity != CompanyID::Invalid()) {
3606 t->exclusivity = CompanyID::Invalid();
3607 t->exclusive_counter = 0;
3608 }
3609 }
3610 }
3611 return CommandCost();
3612}
3613
3614typedef CommandCost TownActionProc(Town *t, DoCommandFlags flags);
3615static TownActionProc * const _town_action_proc[] = {
3624};
3625static_assert(std::size(_town_action_proc) == to_underlying(TownAction::End));
3626
3634{
3635 TownActions buttons{};
3636
3637 /* Spectators and unwanted have no options */
3638 if (cid != COMPANY_SPECTATOR && !(_settings_game.economy.bribe && t->unwanted[cid])) {
3639
3640 /* Actions worth more than this are not able to be performed */
3641 Money avail = GetAvailableMoney(cid);
3642
3643 /* Check the action bits for validity and
3644 * if they are valid add them */
3645 for (TownAction cur = {}; cur != TownAction::End; ++cur) {
3646
3647 /* Is the company prohibited from bribing ? */
3648 if (cur == TownAction::Bribe) {
3649 /* Company can't bribe if setting is disabled */
3650 if (!_settings_game.economy.bribe) continue;
3651 /* Company can bribe if another company has exclusive transport rights,
3652 * or its standing with the town is less than outstanding. */
3653 if (t->ratings[cid] >= RATING_BRIBE_MAXIMUM) {
3654 if (t->exclusivity == _current_company) continue;
3655 if (t->exclusive_counter == 0) continue;
3656 }
3657 }
3658
3659 /* Is the company not able to buy exclusive rights ? */
3661
3662 /* Is the company not able to fund buildings ? */
3664
3665 /* Is the company not able to fund local road reconstruction? */
3667
3668 /* Is the company not able to build a statue ? */
3669 if (cur == TownAction::BuildStatue && t->statues.Test(cid)) continue;
3670
3671 if (avail >= GetTownActionCost(cur) * _price[PR_TOWN_ACTION] >> 8) {
3672 buttons.Set(cur);
3673 }
3674 }
3675 }
3676
3677 return buttons;
3678}
3679
3690{
3691 Town *t = Town::GetIfValid(town_id);
3692 if (t == nullptr || to_underlying(action) >= std::size(_town_action_proc)) return CMD_ERROR;
3693
3694 if (!GetMaskOfTownActions(_current_company, t).Test(action)) return CMD_ERROR;
3695
3696 CommandCost cost(EXPENSES_OTHER, _price[PR_TOWN_ACTION] * GetTownActionCost(action) >> 8);
3697
3698 CommandCost ret = _town_action_proc[to_underlying(action)](t, flags);
3699 if (ret.Failed()) return ret;
3700
3701 if (flags.Test(DoCommandFlag::Execute)) {
3703 }
3704
3705 return cost;
3706}
3707
3708template <typename Func>
3709static void ForAllStationsNearTown(Town *t, Func func)
3710{
3711 /* Ideally the search radius should be close to the actual town zone 0 radius.
3712 * The true radius is not stored or calculated anywhere, only the squared radius. */
3713 /* The efficiency of this search might be improved for large towns and many stations on the map,
3714 * by using an integer square root approximation giving a value not less than the true square root. */
3715 uint search_radius = t->cache.squared_town_zone_radius[HZB_TOWN_EDGE] / 2;
3716 ForAllStationsRadius(t->xy, search_radius, [&](const Station * st) {
3717 if (DistanceSquare(st->xy, t->xy) <= t->cache.squared_town_zone_radius[HZB_TOWN_EDGE]) {
3718 func(st);
3719 }
3720 });
3721}
3722
3727static void UpdateTownRating(Town *t)
3728{
3729 /* Increase company ratings if they're low */
3730 for (const Company *c : Company::Iterate()) {
3731 if (t->ratings[c->index] < RATING_GROWTH_MAXIMUM) {
3732 t->ratings[c->index] = std::min((int)RATING_GROWTH_MAXIMUM, t->ratings[c->index] + RATING_GROWTH_UP_STEP);
3733 }
3734 }
3735
3736 ForAllStationsNearTown(t, [&](const Station *st) {
3737 if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
3738 if (Company::IsValidID(st->owner)) {
3739 int new_rating = t->ratings[st->owner] + RATING_STATION_UP_STEP;
3740 t->ratings[st->owner] = std::min<int>(new_rating, INT16_MAX); // do not let it overflow
3741 }
3742 } else {
3743 if (Company::IsValidID(st->owner)) {
3744 int new_rating = t->ratings[st->owner] + RATING_STATION_DOWN_STEP;
3745 t->ratings[st->owner] = std::max(new_rating, INT16_MIN);
3746 }
3747 }
3748 });
3749
3750 /* clamp all ratings to valid values */
3751 for (uint i = 0; i < MAX_COMPANIES; i++) {
3752 t->ratings[i] = Clamp(t->ratings[i], RATING_MINIMUM, RATING_MAXIMUM);
3753 }
3754
3756}
3757
3758
3765static void UpdateTownGrowCounter(Town *t, uint16_t prev_growth_rate)
3766{
3767 if (t->growth_rate == TOWN_GROWTH_RATE_NONE) return;
3768 if (prev_growth_rate == TOWN_GROWTH_RATE_NONE) {
3769 t->grow_counter = std::min<uint16_t>(t->growth_rate, t->grow_counter);
3770 return;
3771 }
3772 t->grow_counter = RoundDivSU((uint32_t)t->grow_counter * (t->growth_rate + 1), prev_growth_rate + 1);
3773}
3774
3781{
3782 int n = 0;
3783 ForAllStationsNearTown(t, [&](const Station * st) {
3784 if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
3785 n++;
3786 }
3787 });
3788 return n;
3789}
3790
3798{
3804 static const uint16_t _grow_count_values[2][6] = {
3805 { 120, 120, 120, 100, 80, 60 }, // Fund new buildings has been activated
3806 { 320, 420, 300, 220, 160, 100 } // Normal values
3807 };
3808
3809 int n = CountActiveStations(t);
3810 uint16_t m = _grow_count_values[t->fund_buildings_months != 0 ? 0 : 1][std::min(n, 5)];
3811
3812 uint growth_multiplier = _settings_game.economy.town_growth_rate != 0 ? _settings_game.economy.town_growth_rate - 1 : 1;
3813
3814 m >>= growth_multiplier;
3815 if (t->larger_town) m /= 2;
3816
3817 return TownTicksToGameTicks(m / (t->cache.num_houses / 50 + 1));
3818}
3819
3825{
3826 if (HasBit(t->flags, TOWN_CUSTOM_GROWTH)) return;
3827 uint old_rate = t->growth_rate;
3829 UpdateTownGrowCounter(t, old_rate);
3831}
3832
3837static void UpdateTownGrowth(Town *t)
3838{
3840
3843
3845
3846 if (t->fund_buildings_months == 0) {
3847 /* Check if all goals are reached for this town to grow (given we are not funding it) */
3848 for (int i = TAE_BEGIN; i < TAE_END; i++) {
3849 switch (t->goal[i]) {
3850 case TOWN_GROWTH_WINTER:
3851 if (TileHeight(t->xy) >= GetSnowLine() && t->received[i].old_act == 0 && t->cache.population > 90) return;
3852 break;
3853 case TOWN_GROWTH_DESERT:
3854 if (GetTropicZone(t->xy) == TROPICZONE_DESERT && t->received[i].old_act == 0 && t->cache.population > 60) return;
3855 break;
3856 default:
3857 if (t->goal[i] > t->received[i].old_act) return;
3858 break;
3859 }
3860 }
3861 }
3862
3863 if (HasBit(t->flags, TOWN_CUSTOM_GROWTH)) {
3866 return;
3867 }
3868
3869 if (t->fund_buildings_months == 0 && CountActiveStations(t) == 0 && !Chance16(1, 12)) return;
3870
3873}
3874
3882{
3883 /* The required rating is hardcoded to RATING_VERYPOOR (see below), not the authority attitude setting, so we can bail out like this. */
3884 if (_settings_game.difficulty.town_council_tolerance == TOWN_COUNCIL_PERMISSIVE) return CommandCost();
3885
3887
3889 if (t == nullptr) return CommandCost();
3890
3891 if (t->ratings[_current_company] > RATING_VERYPOOR) return CommandCost();
3892
3893 return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index);
3894}
3895
3905{
3906 if (Town::GetNumItems() == 0) return nullptr;
3907
3908 TownID tid = _town_kdtree.FindNearest(TileX(tile), TileY(tile));
3909 Town *town = Town::Get(tid);
3910 if (DistanceManhattan(tile, town->xy) < threshold) return town;
3911 return nullptr;
3912}
3913
3922Town *ClosestTownFromTile(TileIndex tile, uint threshold)
3923{
3924 switch (GetTileType(tile)) {
3925 case MP_ROAD:
3926 if (IsRoadDepot(tile)) return CalcClosestTownFromTile(tile, threshold);
3927
3928 if (!HasTownOwnedRoad(tile)) {
3929 TownID tid = GetTownIndex(tile);
3930
3931 if (tid == TownID::Invalid()) {
3932 /* in the case we are generating "many random towns", this value may be TownID::Invalid() */
3933 if (_generating_world) return CalcClosestTownFromTile(tile, threshold);
3934 assert(Town::GetNumItems() == 0);
3935 return nullptr;
3936 }
3937
3938 assert(Town::IsValidID(tid));
3939 Town *town = Town::Get(tid);
3940
3941 if (DistanceManhattan(tile, town->xy) >= threshold) town = nullptr;
3942
3943 return town;
3944 }
3945 [[fallthrough]];
3946
3947 case MP_HOUSE:
3948 return Town::GetByTile(tile);
3949
3950 default:
3951 return CalcClosestTownFromTile(tile, threshold);
3952 }
3953}
3954
3955static bool _town_rating_test = false;
3956static std::map<const Town *, int> _town_test_ratings;
3957
3964{
3965 static int ref_count = 0; // Number of times test-mode is switched on.
3966 if (mode) {
3967 if (ref_count == 0) {
3968 _town_test_ratings.clear();
3969 }
3970 ref_count++;
3971 } else {
3972 assert(ref_count > 0);
3973 ref_count--;
3974 }
3975 _town_rating_test = !(ref_count == 0);
3976}
3977
3983static int GetRating(const Town *t)
3984{
3985 if (_town_rating_test) {
3986 auto it = _town_test_ratings.find(t);
3987 if (it != _town_test_ratings.end()) {
3988 return it->second;
3989 }
3990 }
3991 return t->ratings[_current_company];
3992}
3993
4001void ChangeTownRating(Town *t, int add, int max, DoCommandFlags flags)
4002{
4003 /* if magic_bulldozer cheat is active, town doesn't penalize for removing stuff */
4004 if (t == nullptr || flags.Test(DoCommandFlag::NoModifyTownRating) ||
4006 (_cheats.magic_bulldozer.value && add < 0)) {
4007 return;
4008 }
4009
4010 int rating = GetRating(t);
4011 if (add < 0) {
4012 if (rating > max) {
4013 rating += add;
4014 if (rating < max) rating = max;
4015 }
4016 } else {
4017 if (rating < max) {
4018 rating += add;
4019 if (rating > max) rating = max;
4020 }
4021 }
4022 if (_town_rating_test) {
4023 _town_test_ratings[t] = rating;
4024 } else {
4026 t->ratings[_current_company] = rating;
4028 }
4029}
4030
4039{
4040 /* if magic_bulldozer cheat is active, town doesn't restrict your destructive actions */
4041 if (t == nullptr || !Company::IsValidID(_current_company) ||
4043 return CommandCost();
4044 }
4045
4046 /* minimum rating needed to be allowed to remove stuff */
4047 static const int needed_rating[][TOWN_RATING_CHECK_TYPE_COUNT] = {
4048 /* ROAD_REMOVE, TUNNELBRIDGE_REMOVE */
4053 };
4054
4055 /* check if you're allowed to remove the road/bridge/tunnel
4056 * owned by a town no removal if rating is lower than ... depends now on
4057 * difficulty setting. Minimum town rating selected by difficulty level
4058 */
4059 int needed = needed_rating[_settings_game.difficulty.town_council_tolerance][type];
4060
4061 if (GetRating(t) < needed) {
4062 return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index);
4063 }
4064
4065 return CommandCost();
4066}
4067
4068static IntervalTimer<TimerGameEconomy> _economy_towns_monthly({TimerGameEconomy::MONTH, TimerGameEconomy::Priority::TOWN}, [](auto)
4069{
4070 for (Town *t : Town::Iterate()) {
4071 /* Check for active town actions and decrement their counters. */
4072 if (t->road_build_months != 0) t->road_build_months--;
4074
4075 if (t->exclusive_counter != 0) {
4076 if (--t->exclusive_counter == 0) t->exclusivity = CompanyID::Invalid();
4077 }
4078
4079 /* Check for active failed bribe cooloff periods and decrement them. */
4080 for (const Company *c : Company::Iterate()) {
4081 if (t->unwanted[c->index] > 0) t->unwanted[c->index]--;
4082 }
4083
4084 /* Update cargo statistics. */
4085 for (auto &supplied : t->supplied) supplied.NewMonth();
4086 for (auto &received : t->received) received.NewMonth();
4087
4090
4092 }
4093});
4094
4095static IntervalTimer<TimerGameEconomy> _economy_towns_yearly({TimerGameEconomy::YEAR, TimerGameEconomy::Priority::TOWN}, [](auto)
4096{
4097 /* Increment house ages */
4098 for (const auto t : Map::Iterate()) {
4099 if (!IsTileType(t, MP_HOUSE)) continue;
4101 }
4102});
4103
4104static CommandCost TerraformTile_Town(TileIndex tile, DoCommandFlags flags, int z_new, Slope tileh_new)
4105{
4106 if (AutoslopeEnabled()) {
4107 HouseID house = GetHouseType(tile);
4108 GetHouseNorthPart(house); // modifies house to the ID of the north tile
4109 const HouseSpec *hs = HouseSpec::Get(house);
4110
4111 /* Here we differ from TTDP by checking BuildingFlag::NotSloped */
4112 if (!hs->building_flags.Test(BuildingFlag::NotSloped) && !IsSteepSlope(tileh_new) &&
4113 (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) {
4114 bool allow_terraform = true;
4115
4116 /* Call the autosloping callback per tile, not for the whole building at once. */
4117 house = GetHouseType(tile);
4118 hs = HouseSpec::Get(house);
4120 /* If the callback fails, allow autoslope. */
4121 uint16_t res = GetHouseCallback(CBID_HOUSE_AUTOSLOPE, 0, 0, house, Town::GetByTile(tile), tile);
4122 if (res != CALLBACK_FAILED && ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_AUTOSLOPE, res)) allow_terraform = false;
4123 }
4124
4125 if (allow_terraform) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
4126 }
4127 }
4128
4129 return Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
4130}
4131
4133extern const TileTypeProcs _tile_type_town_procs = {
4134 DrawTile_Town, // draw_tile_proc
4135 GetSlopePixelZ_Town, // get_slope_z_proc
4136 ClearTile_Town, // clear_tile_proc
4137 AddAcceptedCargo_Town, // add_accepted_cargo_proc
4138 GetTileDesc_Town, // get_tile_desc_proc
4139 GetTileTrackStatus_Town, // get_tile_track_status_proc
4140 nullptr, // click_tile_proc
4141 AnimateTile_Town, // animate_tile_proc
4142 TileLoop_Town, // tile_loop_proc
4143 ChangeTileOwner_Town, // change_tile_owner_proc
4144 AddProducedCargo_Town, // add_produced_cargo_proc
4145 nullptr, // vehicle_enter_tile_proc
4146 GetFoundation_Town, // get_foundation_proc
4147 TerraformTile_Town, // terraform_tile_proc
4148};
4149
4150std::span<const DrawBuildingsTileStruct> GetTownDrawTileData()
4151{
4152 return _town_draw_tile_data;
4153}
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:23
bool IsValidCargoType(CargoType t)
Test whether cargo type is not INVALID_CARGO.
Definition cargo_type.h:106
TownProductionEffect
Town effect when producing cargo.
Definition cargotype.h:35
@ TPE_PASSENGERS
Cargo behaves passenger-like for production.
Definition cargotype.h:37
@ TPE_MAIL
Cargo behaves mail-like for production.
Definition cargotype.h:38
TownAcceptanceEffect
Town growth effect when delivering cargo.
Definition cargotype.h:22
@ TAE_END
End of town effects.
Definition cargotype.h:30
@ TAE_FOOD
Cargo behaves food/fizzy-drinks-like.
Definition cargotype.h:29
@ TAE_WATER
Cargo behaves water-like.
Definition cargotype.h:28
Cheats _cheats
All the cheats.
Definition cheat.cpp:16
Types related to cheating.
static void BroadcastNewEvent(ScriptEvent *event, CompanyID skip_company=CompanyID::Invalid())
Broadcast a new event to all active AIs.
Definition ai_core.cpp:263
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
constexpr Timpl & Set()
Set all bits.
constexpr bool Any(const Timpl &other) const
Test if any of the given values are set.
Common return value for all commands.
bool Succeeded() const
Did this command succeed?
void AddCost(const Money &cost)
Adds the given cost to the cost of the command.
Money GetCost() const
The costs as made up to this moment.
bool Failed() const
Did this command fail?
void MultiplyCost(int factor)
Multiplies the cost of the command by the given factor.
Container for an encoded string, created by GetEncodedString.
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:138
TimerGameCalendar::Date introduction_date
Introduction date.
Definition road.h:157
RoadTypeFlags flags
Bit mask of road type flags.
Definition road.h:118
uint16_t max_speed
Maximum speed for vehicles travelling on this road type.
Definition road.h:133
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.
CommandCost CommandCostWithParam(StringID str, uint64_t value)
Return an error status, with string and parameter.
Definition command.cpp:418
Functions related to commands.
static constexpr DoCommandFlags CommandFlagsToDCFlags(CommandFlags cmd_flags)
Extracts the DC flags needed for DoCommand from the flags returned by GetCommandFlags.
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
@ Execute
execute the given command
@ NoModifyTownRating
do not change town rating
@ NoTestTownRating
town rating does not disallow you from building
@ NoWater
don't allow building on water
@ Auto
don't allow building on structures
Definition of stuff that is very close to a company, like the company struct itself.
Money GetAvailableMoneyForCommand()
This functions returns the money which can be used to execute a command.
Money GetAvailableMoney(CompanyID company)
Get the amount of money that a company has available, or INT64_MAX if there is no such valid company.
CompanyID _current_company
Company currently doing an action.
Functions related to companies.
bool IsLocalCompany()
Is the current company the local company?
static constexpr Owner OWNER_DEITY
The object is owned by a superuser / goal script.
static constexpr CompanyID COMPANY_SPECTATOR
The client is spectating.
static constexpr Owner OWNER_TOWN
A town owns the tile, or a town is expanding.
static constexpr Owner OWNER_NONE
The tile has no ownership.
Base for all depots (except hangars)
DiagDirection ReverseDiagDir(DiagDirection d)
Returns the reverse direction of the given DiagDirection.
bool IsValidDiagDirection(DiagDirection d)
Checks if an integer value is a valid DiagDirection.
DiagDirection ChangeDiagDir(DiagDirection d, DiagDirDiff delta)
Applies a difference on a DiagDirection.
Axis DiagDirToAxis(DiagDirection d)
Convert a DiagDirection to the axis.
@ DIR_N
North.
@ DIR_S
South.
@ DIR_W
West.
@ DIR_E
East.
@ DIAGDIRDIFF_90RIGHT
90 degrees right
@ DIAGDIRDIFF_90LEFT
90 degrees left
DiagDirection
Enumeration for diagonal directions.
@ DIAGDIR_NW
Northwest.
@ DIAGDIR_SE
Southeast.
@ DIAGDIR_END
Used for iterations.
@ DIAGDIR_BEGIN
Used for iterations.
@ DIAGDIR_SW
Southwest.
bool EconomyIsInRecession()
Is the economy in recession?
uint ScaleByCargoScale(uint num, bool town)
Scale a number by the cargo scale setting.
@ EXPENSES_CONSTRUCTION
Construction costs.
@ EXPENSES_OTHER
Other expenses.
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23)
Definition enum_type.hpp:17
Functions related to errors.
@ WL_CRITICAL
Critical errors, the MessageBox is shown in all cases.
Definition error.h:27
@ WL_INFO
Used for DoCommand-like (and some non-fatal AI GUI) errors/information.
Definition error.h:24
void ShowErrorMessage(EncodedString &&summary_msg, int x, int y, const 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:72
Functions related to world/map generation.
void IncreaseGeneratingWorldProgress(GenWorldProgress cls)
Increases the current stage of the world generation with one.
@ GWP_TOWN
Generate towns.
Definition genworld.h:66
void SetGeneratingWorldProgress(GenWorldProgress cls, uint total)
Set the total of a stage of the world generation.
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition gfx_type.h:17
uint8_t GetSnowLine()
Get the current snow line, either variable or static.
uint8_t HighestSnowLine()
Get the highest possible snow line height, either variable or static.
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
Definition gfx.cpp:1500
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
@ BuildingIsProtected
towns and AI will not remove this house, while human players will be able to
static const HouseID NEW_HOUSE_OFFSET
Offset for new houses.
Definition house.h:28
static const uint8_t TOWN_HOUSE_COMPLETED
Simple value that indicates the house has reached the final stage of construction.
Definition house.h:25
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:243
uint DistanceSquare(TileIndex t0, TileIndex t1)
Gets the 'Square' distance between the two given tiles.
Definition map.cpp:159
uint DistanceFromEdge(TileIndex tile)
Param the minimum distance to an edge.
Definition map.cpp:202
uint DistanceManhattan(TileIndex t0, TileIndex t1)
Gets the Manhattan distance between the two given tiles.
Definition map.cpp:142
uint GetClosestWaterDistance(TileIndex tile, bool water)
Finds the distance for the closest tile with water/land given a tile.
Definition map.cpp:325
TileIndex TileAddXY(TileIndex tile, int x, int y)
Adds a given offset to a tile.
Definition map_func.h:469
TileIndex TileAddByDir(TileIndex tile, Direction dir)
Adds a Direction to a tile.
Definition map_func.h:598
static debug_inline TileIndex TileXY(uint x, uint y)
Returns the TileIndex of a coordinate.
Definition map_func.h:372
TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc)
Return the offset between two tiles from a TileIndexDiffC struct.
Definition map_func.h:439
TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir)
Adds a DiagDir to a tile.
Definition map_func.h:610
TileIndexDiff TileDiffXY(int x, int y)
Calculates an offset for the given coordinate(-offset).
Definition map_func.h:388
constexpr TileIndex TileAdd(TileIndex tile, TileIndexDiff offset)
Adds a given offset to a tile.
Definition map_func.h:456
#define RandomTile()
Get a valid random tile.
Definition map_func.h:663
static debug_inline uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition map_func.h:424
static debug_inline uint TileX(TileIndex tile)
Get the X component of a tile.
Definition map_func.h:414
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition map_func.h:569
TileIndexDiffC TileIndexToTileIndexDiffC(TileIndex tile_a, TileIndex tile_b)
Returns the diff between two tiles.
Definition map_func.h:530
int32_t TileIndexDiff
An offset value between two tiles.
Definition map_type.h:23
constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
constexpr int RoundDivSU(int a, uint b)
Computes round(a / b) for signed a and unsigned b.
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition math_func.hpp:79
@ GSF_FAKE_TOWNS
Fake town GrfSpecFeature for NewGRF debugging (parent scope)
Definition newgrf.h:93
@ CBID_HOUSE_DRAW_FOUNDATIONS
Called to determine the type (if any) of foundation to draw for house tile.
@ CBID_HOUSE_CARGO_ACCEPTANCE
Called to decide how much cargo a town building can accept.
@ CBID_HOUSE_AUTOSLOPE
Called to determine if one can alter the ground below a house tile.
@ CBID_HOUSE_CUSTOM_NAME
Called on the Get Tile Description for an house tile.
@ CBID_HOUSE_ALLOW_CONSTRUCTION
Determine whether the house can be built on the specified tile.
@ CBID_HOUSE_ACCEPT_CARGO
Called to determine which cargoes a town building should accept.
@ CBID_HOUSE_PRODUCE_CARGO
Called to determine how much cargo a town building produces.
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
@ AllowConstruction
decide whether the house can be built on a given tile
@ AcceptCargo
decides accepted types
@ CargoAcceptance
decides amount of cargo acceptance
@ DrawFoundations
decides if default foundations need to be drawn
@ ProduceCargo
custom cargo production
@ Autoslope
decides allowance of autosloping
static const uint CALLBACK_HOUSEPRODCARGO_END
Sentinel indicating that the loop for CBID_HOUSE_PRODUCE_CARGO has ended.
CargoType GetCargoTranslation(uint8_t cargo, const GRFFile *grffile, bool usebit)
Translate a GRF-local cargo slot/bitnum into a CargoType.
Cargo support for NewGRFs.
void ErrorUnknownCallbackResult(uint32_t grfid, uint16_t cbid, uint16_t cb_res)
Record that a NewGRF returned an unknown/invalid callback result.
bool Convert8bitBooleanCallback(const GRFFile *grffile, uint16_t cbid, uint16_t cb_res)
Converts a callback result into a boolean.
bool ConvertBooleanCallback(const GRFFile *grffile, uint16_t cbid, uint16_t cb_res)
Converts a callback result into a boolean.
GRFConfig * GetGRFConfig(uint32_t grfid, uint32_t mask)
Retrieve a NewGRF from the current config by its grfid.
Functions/types related to NewGRF debugging.
void DeleteNewGRFInspectWindow(GrfSpecFeature feature, uint index)
Delete inspect window for a given feature and index.
void DecreaseBuildingCount(Town *t, HouseID house_id)
DecreaseBuildingCount() Decrease the number of a building when it is deleted.
void IncreaseBuildingCount(Town *t, HouseID house_id)
IncreaseBuildingCount() Increase the count of a building when it has been added by a town.
void InitializeBuildingCounts()
Initialise global building counts and all town building counts.
Functions related to NewGRF houses.
StringID GetGRFStringID(uint32_t grfid, GRFStringID stringid)
Returns the index for this stringid associated with its grfID.
Header of Action 04 "universal holder" structure and functions.
static constexpr GRFStringID GRFSTR_MISC_GRF_TEXT
Miscellaneous GRF text range.
Functions related to news.
void AddNewsItem(EncodedString &&headline, NewsType type, NewsStyle style, NewsFlags flags, NewsReference ref1={}, NewsReference ref2={}, std::unique_ptr< NewsAllocatedData > &&data=nullptr, AdviceType advice_type=AdviceType::Invalid)
Add a new newsitem to be shown.
Definition news_gui.cpp:902
@ General
General news (from towns)
@ IndustryOpen
Opening of industries.
@ Company
Company news item. (Newspaper with face)
@ Normal
Normal news item. (Newspaper with text only)
Functions related to objects.
void BuildObject(ObjectType type, TileIndex tile, CompanyID owner=OWNER_NONE, struct Town *town=nullptr, uint8_t view=0)
Actually build the object.
Base for all objects.
Map accessors for object tiles.
static const ObjectType OBJECT_STATUE
Statue in towns.
Definition object_type.h:20
Some methods of Pool are placed here in order to reduce compilation time and binary size.
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don't get linker errors.
static debug_inline bool IsPlainRailTile(Tile t)
Checks whether the tile is a rail tile or rail tile with signals.
Definition rail_map.h:60
Randomizer _random
Random used in the game state calculations.
Pseudo random number generator.
uint32_t RandomRange(uint32_t limit, const std::source_location location=std::source_location::current())
Pick a random number between 0 and limit - 1, inclusive.
bool Chance16(const uint32_t a, const uint32_t b, const std::source_location location=std::source_location::current())
Flips a coin with given probability.
RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb)
Clean up unnecessary RoadBits of a planned tile.
Definition road.cpp:47
Road specific functions.
@ NoHouses
Bit number for setting this roadtype as not house friendly.
@ TownBuild
Bit number for allowing towns to build this roadtype.
const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
Definition road.h:220
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:58
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:57
static constexpr int GetSlopeMaxZ(Slope s)
Returns the height of the highest corner of a slope relative to TileZ (= minimal height)
Definition slope_func.h:160
bool IsSlopeWithOneCornerRaised(Slope s)
Tests if a specific slope has exactly one corner raised.
Definition slope_func.h:88
static constexpr bool IsSteepSlope(Slope s)
Checks if a slope is steep.
Definition slope_func.h:36
Foundation FlatteningFoundation(Slope s)
Returns the foundation needed to flatten a slope.
Definition slope_func.h:369
Slope InclinedSlope(DiagDirection dir)
Returns the slope that is inclined in a specific direction.
Definition slope_func.h:256
Slope ComplementSlope(Slope s)
Return the complement of a slope.
Definition slope_func.h:76
Slope
Enumeration for the slope-type.
Definition slope_type.h:48
@ SLOPE_W
the west corner of the tile is raised
Definition slope_type.h:50
@ SLOPE_ELEVATED
bit mask containing all 'simple' slopes
Definition slope_type.h:61
@ SLOPE_E
the east corner of the tile is raised
Definition slope_type.h:52
@ SLOPE_S
the south corner of the tile is raised
Definition slope_type.h:51
@ SLOPE_N
the north corner of the tile is raised
Definition slope_type.h:53
@ SLOPE_SW
south and west corner are raised
Definition slope_type.h:56
@ SLOPE_FLAT
a flat tile
Definition slope_type.h:49
@ SLOPE_STEEP_W
a steep slope falling to east (from west)
Definition slope_type.h:66
@ SLOPE_NE
north and east corner are raised
Definition slope_type.h:58
@ SLOPE_STEEP_E
a steep slope falling to west (from east)
Definition slope_type.h:68
@ SLOPE_SE
south and east corner are raised
Definition slope_type.h:57
@ SLOPE_NW
north and west corner are raised
Definition slope_type.h:55
@ SLOPE_STEEP_N
a steep slope falling to south (from north)
Definition slope_type.h:69
@ SLOPE_STEEP_S
a steep slope falling to north (from south)
Definition slope_type.h:67
Foundation
Enumeration for Foundations.
Definition slope_type.h:93
@ FOUNDATION_LEVELED
The tile is leveled up to a flat slope.
Definition slope_type.h:95
@ FOUNDATION_NONE
The tile has no foundation, the slope remains unchanged.
Definition slope_type.h:94
@ Town
Source/destination is a town.
Base classes/functions for stations.
void ForAllStationsAroundTiles(const TileArea &ta, Func func)
Call a function on all stations that have any part of the requested area within their catchment.
void UpdateAllStationVirtCoords()
Update the virtual coords needed to draw the station sign for all stations.
void UpdateAirportsNoise()
Recalculate the noise generated by the airports of each town.
Declarations for accessing the k-d tree of stations.
void ForAllStationsRadius(TileIndex center, uint radius, Func func)
Call a function on all stations whose sign is within a radius of a center tile.
bool IsBayRoadStopTile(Tile t)
Is tile t a bay (non-drive through) road stop station?
bool IsDriveThroughStopTile(Tile t)
Is tile t a drive through road stop station or waypoint?
Axis GetDriveThroughStopAxis(Tile t)
Gets the axis of the drive through stop.
DiagDirection GetBayRoadStopDir(Tile t)
Gets the direction the bay road stop entrance points towards.
bool IsAnyRoadStopTile(Tile t)
Is tile t a road stop station?
@ Airport
Station with an airport.
Definition of base types and functions in a cross-platform compatible way.
#define lengthof(array)
Return the length of an fixed size array.
Definition stdafx.h: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:377
Functions related to low-level strings.
EncodedString GetEncodedString(StringID str)
Encode a string with no parameters into an encoded string.
Definition strings.cpp:90
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
Definition strings.cpp:426
Functions related to OTTD's strings.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
Class to backup a specific variable and restore it upon destruction of this object to prevent stack v...
Class to backup a specific variable and restore it later.
void Restore()
Restore the variable.
Owner owner
The owner of this station.
Class for storing amounts of cargo.
Definition cargo_type.h:113
static void InvalidateAllFrom(Source src)
Invalidates (sets source_id to INVALID_SOURCE) all cargo packets from given source.
Specification of a cargo type.
Definition cargotype.h:74
static IterateWrapper Iterate(size_t from=0)
Returns an iterable ensemble of all valid CargoSpec.
Definition cargotype.h:192
static std::array< std::vector< const CargoSpec * >, NUM_TPE > town_production_cargoes
List of cargo specs for each Town Product Effect.
Definition cargotype.h: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:76
bool bribe
enable bribing the local authority
TownFounding found_town
town founding.
PlaceHouses place_houses
players are allowed to place town houses.
bool exclusive_rights
allow buying exclusive rights
uint8_t initial_city_size
multiplier for the initial size of the cities compared to towns
TownLayout town_layout
select town layout,
bool allow_town_level_crossings
towns are allowed to build level crossings
uint8_t town_growth_rate
town growth rate
bool allow_town_roads
towns are allowed to build roads (always allowed when generating world / in SE)
bool fund_buildings
allow funding new buildings
bool fund_roads
allow funding local road reconstruction
TownCargoGenMode town_cargogen_mode
algorithm for generating cargo from houses,
uint8_t dist_local_authority
distance for town local authority, default 20
uint8_t larger_towns
the number of cities to build. These start off larger and grow twice as fast
const struct SpriteGroup * GetSpriteGroup(size_t index=0) const
Get the SpriteGroup at the specified index.
Information about GRF, used in the game and (part of it) in savegames.
const char * GetName() const
Get the name of this grf.
const struct GRFFile * grffile
grf file that introduced this entity
uint32_t grfid
grfid that introduced this entity.
bool HasGrfFile() const
Test if this entity was introduced by NewGRF.
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:103
uint8_t probability
Relative probability of appearing (16 is the standard value)
Definition house.h:112
uint8_t removal_cost
cost multiplier for removing it
Definition house.h:98
uint8_t mail_generation
mail generation multiplier (tile based, as the acceptances below)
Definition house.h:101
bool enabled
the house is available to build (true by default, but can be disabled by newgrf)
Definition house.h:106
Money GetRemovalCost() const
Get the cost for removing this house.
Definition town_cmd.cpp:226
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:104
TimerGameCalendar::Year max_year
last year it can be built
Definition house.h:96
HouseCallbackMasks callback_mask
Bitmask of house callbacks that have to be called.
Definition house.h:110
uint16_t remove_rating_decrease
rating decrease if removed
Definition house.h:100
uint8_t population
population (Zero on other tiles in multi tile house.)
Definition house.h:97
HouseExtraFlags extra_flags
some more flags
Definition house.h:113
uint8_t cargo_acceptance[HOUSE_NUM_ACCEPTS]
acceptance level for the cargo slots
Definition house.h:102
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:114
StringID building_name
building name
Definition house.h:99
uint8_t minimum_life
The minimum number of years this house will survive before the town rebuilds it.
Definition house.h:117
GRFFileProps grf_prop
Properties related the the grf file.
Definition house.h:109
HouseZones building_availability
where can it be built (climates, zones)
Definition house.h:105
static std::vector< HouseSpec > & Specs()
Get a reference to all HouseSpecs.
Defines the internal data of a functional industry.
Definition industry.h:63
Town * town
Nearest town.
Definition industry.h:92
static Industry * GetByTile(TileIndex tile)
Get the industry of the given tile.
Definition industry.h:235
Size related data of the map.
Definition map_func.h:206
static uint ScaleBySize(uint n)
Scales the given value by the map size, where the given value is for a 256 by 256 map.
Definition map_func.h:327
static IterateWrapper Iterate()
Returns an iterable ensemble of all Tiles.
Definition map_func.h:362
static debug_inline uint Size()
Get the size of the map.
Definition map_func.h:287
An object, such as transmitter, on the map.
Definition object_base.h:23
ObjectType type
Type of the object.
Definition object_base.h:24
Town * town
Town the object is built in.
Definition object_base.h:25
static Object * GetByTile(TileIndex tile)
Get the object associated with a tile.
Represents the covered area of e.g.
void Add(TileIndex to_add)
Add a single tile to a tile area; enlarge if needed.
Definition tilearea.cpp:43
SpriteID sprite
The 'real' sprite.
Definition gfx_type.h:23
PaletteID pal
The palette (use PAL_NONE) if not needed)
Definition gfx_type.h:24
Coordinates of a point in 2D.
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
static size_t GetPoolSize()
Returns first unused index.
static Titem * Get(auto index)
Returns Titem with given index.
static size_t GetNumItems()
Returns number of valid items in the pool.
Tindex index
Index of this pool item.
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
static bool IsValidID(auto index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
static bool CleaningPool()
Returns current state of pool cleaning - yes or no.
static Titem * GetIfValid(auto index)
Returns Titem with given index.
Base class for all pools.
static constexpr size_t MAX_SIZE
Make template parameter accessible from outside.
A location from where cargo can come from (or go to).
Definition source_type.h:32
static Pool::IterateWrapper< Station > Iterate(size_t from=0)
Returns an iterable ensemble of all valid stations of type T.
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
std::array< Owner, 4 > owner
Name of the owner(s)
Definition tile_cmd.h:55
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
std::optional< bool > town_can_upgrade
Whether the town can upgrade this house during town growth.
Definition tile_cmd.h:70
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:159
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
EncodedString text
General text with additional information.
Definition town.h:81
bool larger_town
if this is a larger town and should grow more quickly
Definition town.h:99
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
ReferenceThroughBaseContainer< std::array< int16_t, MAX_COMPANIES > > ratings
ratings of each company for this town
Definition town.h:75
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
TownLayout layout
town specific road layout
Definition town.h:100
static Town * GetRandom()
Return a random valid town.
Definition town_cmd.cpp:197
ReferenceThroughBaseContainer< std::array< uint8_t, MAX_COMPANIES > > unwanted
how many months companies aren't wanted by towns (bribe)
Definition town.h:72
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
std::array< TransportedCargoStat< uint32_t >, NUM_CARGO > supplied
Cargo statistics about supplied cargo.
Definition town.h:77
void InitializeLayout(TownLayout layout)
Assign the town layout.
Definition town_cmd.cpp:183
bool show_zone
NOSAVE: mark town to show the local authority zone in the viewports.
Definition town.h:102
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:410
CompanyMask have_ratings
which companies have a rating
Definition town.h:71
~Town()
Destroy the town.
Definition town_cmd.cpp:110
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:168
uint8_t road_build_months
fund road reconstruction in action?
Definition town.h:97
std::array< TransportedCargoStat< uint16_t >, NUM_TAE > received
Cargo statistics about received cargotypes.
Definition town.h:78
std::array< uint32_t, NUM_TAE > goal
Amount of cargo required for the town to grow.
Definition town.h:79
void UpdatePosition(int center, int top, std::string_view str, std::string_view str_small={})
Update the position of the viewport sign.
bool kdtree_valid
Are the sign data valid for use with the _viewport_sign_kdtree?
Representation of a waypoint.
void DeleteSubsidyWith(Source source)
Delete the subsidies associated with a given cargo source type and id.
Definition subsidy.cpp:119
Functions related to subsidies.
Command definitions related to terraforming.
bool IsTileFlat(TileIndex tile, int *h)
Check if a given tile is flat.
Definition tile_map.cpp:95
int GetTileMaxZ(TileIndex t)
Get top height of the tile inside the map.
Definition tile_map.cpp:136
int GetTileZ(TileIndex tile)
Get bottom height of the tile.
Definition tile_map.cpp:116
uint TileHash(uint x, uint y)
Calculate a hash value from a tile position.
Definition tile_map.h:324
bool IsTileOwner(Tile tile, Owner owner)
Checks if a tile belongs to the given owner.
Definition tile_map.h:214
int GetTileMaxPixelZ(TileIndex tile)
Get top height of the tile.
Definition tile_map.h:312
static debug_inline TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
Definition tile_map.h:96
bool IsValidTile(Tile tile)
Checks if a tile is valid.
Definition tile_map.h:161
uint TileHash2Bit(uint x, uint y)
Get the last two bits of the TileHash from a tile position.
Definition tile_map.h:342
TropicZone GetTropicZone(Tile tile)
Get the tropic zone.
Definition tile_map.h:238
static debug_inline bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition tile_map.h:150
Slope GetTileSlope(TileIndex tile)
Return the slope of a given tile inside the map.
Definition tile_map.h:279
static debug_inline uint TileHeight(Tile tile)
Returns the height of a tile.
Definition tile_map.h:29
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
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.
TownAction
Town actions of a company.
Definition town.h:210
@ RoadRebuild
Rebuild the roads.
@ Bribe
Try to bribe the council.
@ BuildStatue
Build a statue.
@ BuyRights
Buy exclusive transport rights.
@ FundBuildings
Fund new buildings.
static const uint16_t TOWN_GROWTH_RATE_NONE
Special value for Town::growth_rate to disable town growth.
Definition town.h:33
static bool RoadTypesAllowHouseHere(TileIndex t)
Checks whether at least one surrounding road allows to build a house here.
static bool CheckFree2x2Area(TileIndex tile, int z, bool noslope)
Checks if a house of size 2x2 can be built at this tile.
static bool TownLayoutAllows2x2HouseHere(Town *t, TileIndex tile)
Checks if the current town layout allows a 2x2 building here.
std::tuple< CommandCost, Money, TownID > CmdFoundTown(DoCommandFlags flags, TileIndex tile, TownSize size, bool city, TownLayout layout, bool random_location, uint32_t townnameparts, const std::string &text)
Create a new town.
void ChangeTownRating(Town *t, int add, int max, DoCommandFlags flags)
Changes town rating of the current company.
static CommandCost TownActionAdvertiseSmall(Town *t, DoCommandFlags flags)
Perform the "small advertising campaign" town action.
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 CommandCost TownActionFundBuildings(Town *t, DoCommandFlags flags)
Perform the "fund new buildings" town action.
static bool IsTileAlignedToGrid(TileIndex tile, TownLayout layout)
Towns must all be placed on the same grid or when they eventually interpenetrate their road networks ...
static CommandCost TownActionBuildStatue(Town *t, DoCommandFlags flags)
Perform a 9x9 tiles circular search from the center of the town in order to find a free tile to place...
static CommandCost TownActionBribe(Town *t, DoCommandFlags flags)
Perform the "bribe" town action.
TileIndexDiff GetHouseNorthPart(HouseID &house)
Determines if a given HouseID is part of a multitile house.
static int GetRating(const Town *t)
Get the rating of a town for the _current_company.
void ClearTownHouse(Town *t, TileIndex tile)
Clear a town house.
static uint GetNormalGrowthRate(Town *t)
Calculates town growth rate in normal conditions (custom growth rate not set).
TownActions GetMaskOfTownActions(CompanyID cid, const Town *t)
Get a list of available town authority actions.
static CommandCost TownActionBuyRights(Town *t, DoCommandFlags flags)
Perform the "buy exclusive transport rights" town action.
static bool GrowTownWithBridge(const Town *t, const TileIndex tile, const DiagDirection bridge_dir)
Grows the town with a bridge.
const CargoSpec * FindFirstCargoWithTownAcceptanceEffect(TownAcceptanceEffect effect)
Determines the first cargo with a certain town effect.
static TileIndex FindNearestGoodCoastalTownSpot(TileIndex tile, TownLayout layout)
Given a spot on the map (presumed to be a water tile), find a good coastal spot to build a city.
Town * ClosestTownFromTile(TileIndex tile, uint threshold)
Return the town closest (in distance or ownership) to a given tile, within a given threshold.
static bool IsRoadAllowedHere(Town *t, TileIndex tile, DiagDirection dir)
Check if a Road is allowed on a given tile.
static bool CanRoadContinueIntoNextTile(const Town *t, const TileIndex tile, const DiagDirection road_dir)
Checks if a town road can be continued into the next tile.
static void UpdateTownGrowCounter(Town *t, uint16_t prev_growth_rate)
Updates town grow counter after growth rate change.
static int CountActiveStations(Town *t)
Calculates amount of active stations in the range of town (HZB_TOWN_EDGE).
static CommandCost TownCanBePlacedHere(TileIndex tile)
Check if it's possible to place a town on a given tile.
static bool IsNeighbourRoadTile(TileIndex tile, const DiagDirection dir, uint dist_multi)
Check for parallel road inside a given distance.
CommandCost CmdPlaceHouse(DoCommandFlags flags, TileIndex tile, HouseID house, bool is_protected)
Place an individual house.
static bool _generating_town
Set if a town is being generated.
Definition town_cmd.cpp: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 void MakeTownHouse(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool is_protected)
Write house information into the map.
static bool 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 bool GrowTownWithRoad(const Town *t, TileIndex tile, RoadBits rcmd)
Grows the town with a road piece.
CommandCost CmdDoTownAction(DoCommandFlags flags, TownID town_id, TownAction action)
Do a town action.
static void TownGenerateCargoBinomial(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
Generate cargo for a house using the binomial algorithm.
Definition town_cmd.cpp:582
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 CommandCost ClearTile_Town(TileIndex tile, DoCommandFlags flags)
Callback function to clear a house tile.
Definition town_cmd.cpp:717
static bool CheckClearTile(TileIndex tile)
Check whether the land can be cleared.
static CommandCost TownActionAdvertiseMedium(Town *t, DoCommandFlags flags)
Perform the "medium advertising campaign" town action.
static void TownGenerateCargoOriginal(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
Generate cargo for a house using the original algorithm.
Definition town_cmd.cpp:562
static void ClearMakeHouseTile(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool is_protected)
Clears tile and builds a house or house part.
void UpdateTownMaxPass(Town *t)
Update the maximum amount of monthly passengers and mail for a town, based on its population.
static void ChangePopulation(Town *t, int mod)
Change the town's population as recorded in the town cache, town label, and town directory.
Definition town_cmd.cpp: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:858
static bool TownAllowedToBuildRoads()
Check if the town is allowed to build roads.
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:789
static DiagDirection RandomDiagDir()
Return a random direction.
Definition town_cmd.cpp:259
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
CommandCost CmdExpandTown(DoCommandFlags flags, TownID town_id, uint32_t grow_amount)
Expand a town (scenario editor only).
static bool GrowTownAtRoad(Town *t, TileIndex tile)
Try to grow a town at a given road tile.
uint8_t GetTownActionCost(TownAction action)
Get cost factors for a TownAction.
CommandCost CmdTownSetText(DoCommandFlags flags, TownID town_id, const EncodedString &text)
Set a custom text in the Town window.
Town * CalcClosestTownFromTile(TileIndex tile, uint threshold)
Return the town closest to the given tile within threshold.
CommandCost CmdTownGrowthRate(DoCommandFlags flags, TownID town_id, uint16_t growth_rate)
Change the growth rate of the town.
static CommandCost TownActionRoadRebuild(Town *t, DoCommandFlags flags)
Perform the "local road reconstruction" town action.
void ClearAllTownCachedNames()
Clear the cached_name of all towns.
Definition town_cmd.cpp:435
CommandCost CmdDeleteTown(DoCommandFlags flags, TownID town_id)
Delete a town (scenario editor or worldgen only).
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:327
static TimerGameCalendar::Date GetTownRoadTypeFirstIntroductionDate()
Get the calendar date of the earliest town-buildable road type.
Definition town_cmd.cpp:994
static void AnimateTile_Town(TileIndex tile)
Animate a tile for a town.
Definition town_cmd.cpp:351
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:959
static RoadBits GetTownRoadBits(TileIndex tile)
Return the RoadBits of a tile, ignoring depot and bay road stops.
Definition town_cmd.cpp:948
CommandCost CmdRenameTown(DoCommandFlags flags, TownID town_id, const std::string &text)
Rename a town (server-only).
CommandCost CmdTownCargoGoal(DoCommandFlags flags, TownID town_id, TownAcceptanceEffect tae, uint32_t goal)
Change the cargo goal of a town.
static void DoCreateTown(Town *t, TileIndex tile, uint32_t townnameparts, TownSize size, bool city, TownLayout layout, bool manual)
Actually create a town.
CommandCost CheckforTownRating(DoCommandFlags flags, Town *t, TownRatingCheckType type)
Does the town authority allow the (destructive) action of the current company?
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:934
static CommandCost TownActionAdvertiseLarge(Town *t, DoCommandFlags flags)
Perform the "large advertising campaign" town action.
bool CheckTownRoadTypes()
Check if towns are able to build road.
bool GenerateTowns(TownLayout layout)
Generate a number of towns with a given layout.
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:917
void SetTownRatingTestMode(bool mode)
Switch the town rating to test-mode, to allow commands to be tested without affecting current ratings...
static bool _town_rating_test
If true, town rating is in test-mode.
CommandCost CmdTownRating(DoCommandFlags flags, TownID town_id, CompanyID company_id, int16_t rating)
Change the rating of a company in a town.
void UpdateTownRadius(Town *t)
Update the cached town zone radii of a town, based on the number of houses.
void AddAcceptedCargoOfHouse(TileIndex tile, HouseID house, const HouseSpec *hs, Town *t, CargoArray &acceptance, CargoTypes &always_accepted)
Determine accepted cargo for a house.
Definition town_cmd.cpp:805
static 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:402
static void UpdateTownGrowth(Town *t)
Updates town growth state (whether it is growing or not).
static void DoClearTownHouseHelper(TileIndex tile, Town *t, HouseID house)
Update data structures when a house is removed.
static RoadBits GenRandomRoadBits()
Generate a random road block.
static bool CheckBuildHouseSameZ(TileIndex tile, int z, bool noslope)
Check if a tile where we want to build a multi-tile house has an appropriate max Z.
CommandCost CheckIfAuthorityAllowsNewStation(TileIndex tile, DoCommandFlags flags)
Checks whether the local authority allows construction of a new station (rail, road,...
static void BuildTownHouse(Town *t, TileIndex tile, const HouseSpec *hs, HouseID house, uint8_t random_bits, bool house_completed, bool is_protected)
Build a house at this tile.
static 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:268
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:259
void HaltLift(Tile t)
Stop the lift of this animated house from moving.
Definition town_map.h:137
HouseID GetHouseType(Tile t)
Get the type of this house, which is an index into the house spec array.
Definition town_map.h:60
void ResetHouseAge(Tile t)
Sets the age of the house to zero.
Definition town_map.h:248
void MakeHouseTile(Tile t, TownID tid, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool house_protected)
Make the tile a house.
Definition town_map.h:375
void IncHouseConstructionTick(Tile t)
Sets the increment stage of a house It is working with the whole counter + stage 5 bits,...
Definition town_map.h:230
uint8_t GetLiftPosition(Tile t)
Get the position of the lift on this animated house.
Definition town_map.h:147
void SetLiftDestination(Tile t, uint8_t dest)
Set the new destination of the lift for this animated house, and activate the LiftHasDestination bit.
Definition town_map.h:115
TimerGameCalendar::Year GetHouseAge(Tile t)
Get the age of the house.
Definition town_map.h:271
void SetLiftPosition(Tile t, uint8_t pos)
Set the position of the lift on this animated house.
Definition town_map.h:157
uint8_t GetLiftDestination(Tile t)
Get the current destination for this lift.
Definition town_map.h:126
uint8_t GetHouseBuildingStage(Tile t)
House Construction Scheme.
Definition town_map.h:205
TownID GetTownIndex(Tile t)
Get the index of which town this house/street is attached to.
Definition town_map.h:23
void SetTownIndex(Tile t, TownID index)
Set the town index for a road or house tile.
Definition town_map.h:35
bool LiftHasDestination(Tile t)
Check if the lift of this animated house has a destination.
Definition town_map.h:104
bool IsHouseCompleted(Tile t)
Get the completion of this house.
Definition town_map.h:167
bool IsHouseProtected(Tile t)
Check if the house is protected from removal by towns.
Definition town_map.h:82
uint8_t GetHouseConstructionTick(Tile t)
Gets the construction stage of a house.
Definition town_map.h:217
static constexpr int RATING_GROWTH_UP_STEP
when a town grows, all companies have rating increased a bit ...
Definition town_type.h:53
static constexpr int RATING_INITIAL
initial rating
Definition town_type.h:45
static constexpr int RATING_ROAD_NEEDED_HOSTILE
"Hostile"
Definition town_type.h:71
@ TCGM_BITCOUNT
Bit-counted algorithm (normal distribution from individual house population)
Definition town_type.h: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:673
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:829
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:589
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:1143
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition window.cpp:3132
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:3224
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition window.cpp:3106
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: