OpenTTD Source 20250613-master-ga1786fa1f4
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
231static bool TryBuildTownHouse(Town *t, TileIndex tile, TownExpandModes modes);
232static Town *CreateRandomTown(uint attempts, uint32_t townnameparts, TownSize size, bool city, TownLayout layout);
233
234static void TownDrawHouseLift(const TileInfo *ti)
235{
236 AddChildSpriteScreen(SPR_LIFT, PAL_NONE, 14, 60 - GetLiftPosition(ti->tile));
237}
238
239typedef void TownDrawTileProc(const TileInfo *ti);
240static TownDrawTileProc * const _town_draw_tile_procs[1] = {
241 TownDrawHouseLift
242};
243
250{
252}
253
258static void DrawTile_Town(TileInfo *ti)
259{
260 HouseID house_id = GetHouseType(ti->tile);
261
262 if (house_id >= NEW_HOUSE_OFFSET) {
263 /* Houses don't necessarily need new graphics. If they don't have a
264 * spritegroup associated with them, then the sprite for the substitute
265 * house id is drawn instead. */
266 if (HouseSpec::Get(house_id)->grf_prop.HasSpriteGroups()) {
267 DrawNewHouseTile(ti, house_id);
268 return;
269 } else {
270 house_id = HouseSpec::Get(house_id)->grf_prop.subst_id;
271 }
272 }
273
274 /* Retrieve pointer to the draw town tile struct */
275 const DrawBuildingsTileStruct *dcts = &_town_draw_tile_data[house_id << 4 | TileHash2Bit(ti->x, ti->y) << 2 | GetHouseBuildingStage(ti->tile)];
276
278
279 DrawGroundSprite(dcts->ground.sprite, dcts->ground.pal);
280
281 /* If houses are invisible, do not draw the upper part */
282 if (IsInvisibilitySet(TO_HOUSES)) return;
283
284 /* Add a house on top of the ground? */
285 SpriteID image = dcts->building.sprite;
286 if (image != 0) {
287 AddSortableSpriteToDraw(image, dcts->building.pal,
288 ti->x + dcts->subtile_x,
289 ti->y + dcts->subtile_y,
290 dcts->width,
291 dcts->height,
292 dcts->dz,
293 ti->z,
295 );
296
297 if (IsTransparencySet(TO_HOUSES)) return;
298 }
299
300 {
301 int proc = dcts->draw_proc - 1;
302
303 if (proc >= 0) _town_draw_tile_procs[proc](ti);
304 }
305}
306
307static int GetSlopePixelZ_Town(TileIndex tile, uint, uint, bool)
308{
309 return GetTileMaxPixelZ(tile);
310}
311
318{
319 HouseID hid = GetHouseType(tile);
320
321 /* For NewGRF house tiles we might not be drawing a foundation. We need to
322 * account for this, as other structures should
323 * draw the wall of the foundation in this case.
324 */
325 if (hid >= NEW_HOUSE_OFFSET) {
326 const HouseSpec *hs = HouseSpec::Get(hid);
328 uint32_t callback_res = GetHouseCallback(CBID_HOUSE_DRAW_FOUNDATIONS, 0, 0, hid, Town::GetByTile(tile), tile);
329 if (callback_res != CALLBACK_FAILED && !ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DRAW_FOUNDATIONS, callback_res)) return FOUNDATION_NONE;
330 }
331 }
332 return FlatteningFoundation(tileh);
333}
334
342{
343 if (GetHouseType(tile) >= NEW_HOUSE_OFFSET) {
344 AnimateNewHouseTile(tile);
345 return;
346 }
347
348 if (TimerGameTick::counter & 3) return;
349
350 /* If the house is not one with a lift anymore, then stop this animating.
351 * Not exactly sure when this happens, but probably when a house changes.
352 * Before this was just a return...so it'd leak animated tiles..
353 * That bug seems to have been here since day 1?? */
354 if (!HouseSpec::Get(GetHouseType(tile))->building_flags.Test(BuildingFlag::IsAnimated)) {
355 DeleteAnimatedTile(tile);
356 return;
357 }
358
359 if (!LiftHasDestination(tile)) {
360 uint i;
361
362 /* Building has 6 floors, number 0 .. 6, where 1 is illegal.
363 * This is due to the fact that the first floor is, in the graphics,
364 * the height of 2 'normal' floors.
365 * Furthermore, there are 6 lift positions from floor N (incl) to floor N + 1 (excl) */
366 do {
367 i = RandomRange(7);
368 } while (i == 1 || i * 6 == GetLiftPosition(tile));
369
370 SetLiftDestination(tile, i);
371 }
372
373 int pos = GetLiftPosition(tile);
374 int dest = GetLiftDestination(tile) * 6;
375 pos += (pos < dest) ? 1 : -1;
376 SetLiftPosition(tile, pos);
377
378 if (pos == dest) {
379 HaltLift(tile);
380 DeleteAnimatedTile(tile);
381 }
382
384}
385
392static bool IsCloseToTown(TileIndex tile, uint dist)
393{
394 if (_town_kdtree.Count() == 0) return false;
395 Town *t = Town::Get(_town_kdtree.FindNearest(TileX(tile), TileY(tile)));
396 return DistanceManhattan(tile, t->xy) < dist;
397}
398
401{
402 Point pt = RemapCoords2(TileX(this->xy) * TILE_SIZE, TileY(this->xy) * TILE_SIZE);
403
404 if (this->cache.sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeTown(this->index));
405
406 std::string town_string = GetString(STR_TOWN_NAME, this->index);
407 this->cache.sign.UpdatePosition(pt.x, pt.y - 24 * ZOOM_BASE,
408 _settings_client.gui.population_in_label ? GetString(STR_VIEWPORT_TOWN_POP, this->index, this->cache.population) : town_string,
409 town_string);
410
411 _viewport_sign_kdtree.Insert(ViewportSignKdtreeItem::MakeTown(this->index));
412
414}
415
418{
419 for (Town *t : Town::Iterate()) {
420 t->UpdateVirtCoord();
421 }
422}
423
426{
427 for (Town *t : Town::Iterate()) {
428 t->cached_name.clear();
429 }
430}
431
437static void ChangePopulation(Town *t, int mod)
438{
439 t->cache.population += mod;
440 if (_generating_town) [[unlikely]] return;
441
442 InvalidateWindowData(WC_TOWN_VIEW, t->index); // Cargo requirements may appear/vanish for small populations
444
445 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_POPULATION_CHANGE);
446}
447
453{
454 uint32_t pop = 0;
455 for (const Town *t : Town::Iterate()) pop += t->cache.population;
456 return pop;
457}
458
467{
468 for (StationList::iterator it = t->stations_near.begin(); it != t->stations_near.end(); /* incremented inside loop */) {
469 const Station *st = *it;
470
471 bool covers_area = st->TileIsInCatchment(tile);
472 if (flags.Any(BUILDING_2_TILES_Y)) covers_area |= st->TileIsInCatchment(tile + TileDiffXY(0, 1));
473 if (flags.Any(BUILDING_2_TILES_X)) covers_area |= st->TileIsInCatchment(tile + TileDiffXY(1, 0));
474 if (flags.Any(BUILDING_HAS_4_TILES)) covers_area |= st->TileIsInCatchment(tile + TileDiffXY(1, 1));
475
476 if (covers_area && !st->CatchmentCoversTown(t->index)) {
477 it = t->stations_near.erase(it);
478 } else {
479 ++it;
480 }
481 }
482}
483
489{
490 assert(IsTileType(tile, MP_HOUSE));
491
492 /* Progress in construction stages */
494 if (GetHouseConstructionTick(tile) != 0) return;
495
496 TriggerHouseAnimation_ConstructionStageChanged(tile, false);
497
498 if (IsHouseCompleted(tile)) {
499 /* Now that construction is complete, we can add the population of the
500 * building to the town. */
501 ChangePopulation(Town::GetByTile(tile), HouseSpec::Get(GetHouseType(tile))->population);
502 ResetHouseAge(tile);
503 }
505}
506
512{
514 if (flags.Any(BUILDING_HAS_1_TILE)) AdvanceSingleHouseConstruction(TileAddXY(tile, 0, 0));
515 if (flags.Any(BUILDING_2_TILES_Y)) AdvanceSingleHouseConstruction(TileAddXY(tile, 0, 1));
516 if (flags.Any(BUILDING_2_TILES_X)) AdvanceSingleHouseConstruction(TileAddXY(tile, 1, 0));
517 if (flags.Any(BUILDING_HAS_4_TILES)) AdvanceSingleHouseConstruction(TileAddXY(tile, 1, 1));
518}
519
528static void TownGenerateCargo(Town *t, CargoType cargo, uint amount, StationFinder &stations, bool affected_by_recession)
529{
530 if (amount == 0) return;
531
532 /* All production is halved during a recession (except for NewGRF-supplied town cargo). */
533 if (affected_by_recession && EconomyIsInRecession()) {
534 amount = (amount + 1) >> 1;
535 }
536
537 /* Scale by cargo scale setting. */
538 amount = ScaleByCargoScale(amount, true);
539
540 /* Actually generate cargo and update town statistics. */
541 t->supplied[cargo].new_max += amount;
542 t->supplied[cargo].new_act += MoveGoodsToStation(cargo, amount, {t->index, SourceType::Town}, stations.GetStations());;
543}
544
552static void TownGenerateCargoOriginal(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
553{
554 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[tpe]) {
555 uint32_t r = Random();
556 if (GB(r, 0, 8) < rate) {
557 CargoType cargo_type = cs->Index();
558 uint amt = (GB(r, 0, 8) * cs->town_production_multiplier / TOWN_PRODUCTION_DIVISOR) / 8 + 1;
559
560 TownGenerateCargo(t, cargo_type, amt, stations, true);
561 }
562 }
563}
564
572static void TownGenerateCargoBinomial(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
573{
574 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[tpe]) {
575 CargoType cargo_type = cs->Index();
576 uint32_t r = Random();
577
578 /* Make a bitmask with up to 32 bits set, one for each potential pax. */
579 int genmax = (rate + 7) / 8;
580 uint32_t genmask = (genmax >= 32) ? 0xFFFFFFFF : ((1 << genmax) - 1);
581
582 /* Mask random value by potential pax and count number of actual pax. */
583 uint amt = CountBits(r & genmask) * cs->town_production_multiplier / TOWN_PRODUCTION_DIVISOR;
584
585 TownGenerateCargo(t, cargo_type, amt, stations, true);
586 }
587}
588
595static void TileLoop_Town(TileIndex tile)
596{
597 HouseID house_id = GetHouseType(tile);
598
599 /* NewHouseTileLoop returns false if Callback 21 succeeded, i.e. the house
600 * doesn't exist any more, so don't continue here. */
601 if (house_id >= NEW_HOUSE_OFFSET && !NewHouseTileLoop(tile)) return;
602
603 if (!IsHouseCompleted(tile)) {
604 /* Construction is not completed, so we advance a construction stage. */
606 return;
607 }
608
609 const HouseSpec *hs = HouseSpec::Get(house_id);
610
611 /* If the lift has a destination, it is already an animated tile. */
612 if (hs->building_flags.Test(BuildingFlag::IsAnimated) &&
613 house_id < NEW_HOUSE_OFFSET &&
614 !LiftHasDestination(tile) &&
615 Chance16(1, 2)) {
616 AddAnimatedTile(tile);
617 }
618
619 Town *t = Town::GetByTile(tile);
620 uint32_t r = Random();
621
622 StationFinder stations(TileArea(tile, 1, 1));
623
625 for (uint i = 0; i < 256; i++) {
626 uint16_t callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, r, house_id, t, tile);
627
628 if (callback == CALLBACK_FAILED || callback == CALLBACK_HOUSEPRODCARGO_END) break;
629
630 CargoType cargo = GetCargoTranslation(GB(callback, 8, 7), hs->grf_prop.grffile);
631 if (!IsValidCargoType(cargo)) continue;
632
633 uint amt = GB(callback, 0, 8);
634 if (amt == 0) continue;
635
636 /* NewGRF-supplied town cargos are not affected by recessions. */
637 TownGenerateCargo(t, cargo, amt, stations, false);
638 }
639 } else {
641 case TCGM_ORIGINAL:
642 /* Original (quadratic) cargo generation algorithm */
645 break;
646
647 case TCGM_BITCOUNT:
648 /* Binomial distribution per tick, by a series of coin flips */
649 /* Reduce generation rate to a 1/4, using tile bits to spread out distribution.
650 * As tick counter is incremented by 256 between each call, we ignore the lower 8 bits. */
651 if (GB(TimerGameTick::counter, 8, 2) == GB(tile.base(), 0, 2)) {
654 }
655 break;
656
657 default:
658 NOT_REACHED();
659 }
660 }
661
663
664 if (hs->building_flags.Any(BUILDING_HAS_1_TILE) &&
666 CanDeleteHouse(tile) &&
667 GetHouseAge(tile) >= hs->minimum_life &&
668 --t->time_until_rebuild == 0) {
669 t->time_until_rebuild = GB(r, 16, 8) + 192;
670
671 ClearTownHouse(t, tile);
672
673 /* Rebuild with another house? */
674 if (GB(r, 24, 8) >= 12) {
675 /* If we are multi-tile houses, make sure to replace the house
676 * closest to city center. If we do not do this, houses tend to
677 * wander away from roads and other houses. */
678 if (hs->building_flags.Any(BUILDING_HAS_2_TILES)) {
679 /* House tiles are always the most north tile. Move the new
680 * house to the south if we are north of the city center. */
681 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
682 int x = Clamp(grid_pos.x, 0, 1);
683 int y = Clamp(grid_pos.y, 0, 1);
684
685 if (hs->building_flags.Test(BuildingFlag::Size2x2)) {
686 tile = TileAddXY(tile, x, y);
687 } else if (hs->building_flags.Test(BuildingFlag::Size1x2)) {
688 tile = TileAddXY(tile, 0, y);
689 } else if (hs->building_flags.Test(BuildingFlag::Size2x1)) {
690 tile = TileAddXY(tile, x, 0);
691 }
692 }
693
696
697 TryBuildTownHouse(t, tile, modes);
698 }
699 }
700
701 cur_company.Restore();
702}
703
711{
712 if (flags.Test(DoCommandFlag::Auto)) return CommandCost(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
713 if (!CanDeleteHouse(tile)) return CMD_ERROR;
714
715 const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
716
718 cost.AddCost(hs->GetRemovalCost());
719
720 int rating = hs->remove_rating_decrease;
721 Town *t = Town::GetByTile(tile);
722
725 /* NewGRFs can add indestructible houses. */
726 if (rating > RATING_MAXIMUM) {
727 return CommandCost(CMD_ERROR);
728 }
729 /* If town authority controls removal, check the company's rating. */
730 if (rating > t->ratings[_current_company] && _settings_game.difficulty.town_council_tolerance != TOWN_COUNCIL_PERMISSIVE) {
731 return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index);
732 }
733 }
734 }
735
736 ChangeTownRating(t, -rating, RATING_HOUSE_MINIMUM, flags);
737 if (flags.Test(DoCommandFlag::Execute)) {
738 ClearTownHouse(t, tile);
739 }
740
741 return cost;
742}
743
744static void AddProducedCargo_Town(TileIndex tile, CargoArray &produced)
745{
746 HouseID house_id = GetHouseType(tile);
747 const HouseSpec *hs = HouseSpec::Get(house_id);
748 Town *t = Town::GetByTile(tile);
749
751 for (uint i = 0; i < 256; i++) {
752 uint16_t callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, 0, house_id, t, tile);
753
754 if (callback == CALLBACK_FAILED || callback == CALLBACK_HOUSEPRODCARGO_END) break;
755
756 CargoType cargo = GetCargoTranslation(GB(callback, 8, 7), hs->grf_prop.grffile);
757
758 if (!IsValidCargoType(cargo)) continue;
759 produced[cargo]++;
760 }
761 } else {
762 if (hs->population > 0) {
763 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_PASSENGERS]) {
764 produced[cs->Index()]++;
765 }
766 }
767 if (hs->mail_generation > 0) {
768 for (const CargoSpec *cs : CargoSpec::town_production_cargoes[TPE_MAIL]) {
769 produced[cs->Index()]++;
770 }
771 }
772 }
773}
774
782static void AddAcceptedCargoSetMask(CargoType cargo, uint amount, CargoArray &acceptance, CargoTypes &always_accepted)
783{
784 if (!IsValidCargoType(cargo) || amount == 0) return;
785 acceptance[cargo] += amount;
786 SetBit(always_accepted, cargo);
787}
788
798void AddAcceptedCargoOfHouse(TileIndex tile, HouseID house, const HouseSpec *hs, Town *t, CargoArray &acceptance, CargoTypes &always_accepted)
799{
800 CargoType accepts[lengthof(hs->accepts_cargo)];
801
802 /* Set the initial accepted cargo types */
803 for (uint8_t i = 0; i < lengthof(accepts); i++) {
804 accepts[i] = hs->accepts_cargo[i];
805 }
806
807 /* Check for custom accepted cargo types */
809 uint16_t callback = GetHouseCallback(CBID_HOUSE_ACCEPT_CARGO, 0, 0, house, t, tile, {}, tile == INVALID_TILE);
810 if (callback != CALLBACK_FAILED) {
811 /* Replace accepted cargo types with translated values from callback */
812 accepts[0] = GetCargoTranslation(GB(callback, 0, 5), hs->grf_prop.grffile);
813 accepts[1] = GetCargoTranslation(GB(callback, 5, 5), hs->grf_prop.grffile);
814 accepts[2] = GetCargoTranslation(GB(callback, 10, 5), hs->grf_prop.grffile);
815 }
816 }
817
818 /* Check for custom cargo acceptance */
820 uint16_t callback = GetHouseCallback(CBID_HOUSE_CARGO_ACCEPTANCE, 0, 0, house, t, tile, {}, tile == INVALID_TILE);
821 if (callback != CALLBACK_FAILED) {
822 AddAcceptedCargoSetMask(accepts[0], GB(callback, 0, 4), acceptance, always_accepted);
823 AddAcceptedCargoSetMask(accepts[1], GB(callback, 4, 4), acceptance, always_accepted);
824 if (_settings_game.game_creation.landscape != LandscapeType::Temperate && HasBit(callback, 12)) {
825 /* The 'S' bit indicates food instead of goods */
826 AddAcceptedCargoSetMask(GetCargoTypeByLabel(CT_FOOD), GB(callback, 8, 4), acceptance, always_accepted);
827 } else {
828 AddAcceptedCargoSetMask(accepts[2], GB(callback, 8, 4), acceptance, always_accepted);
829 }
830 return;
831 }
832 }
833
834 /* No custom acceptance, so fill in with the default values */
835 for (uint8_t i = 0; i < lengthof(accepts); i++) {
836 AddAcceptedCargoSetMask(accepts[i], hs->cargo_acceptance[i], acceptance, always_accepted);
837 }
838}
839
840static void AddAcceptedCargo_Town(TileIndex tile, CargoArray &acceptance, CargoTypes &always_accepted)
841{
842 HouseID house = GetHouseType(tile);
843 AddAcceptedCargoOfHouse(tile, house, HouseSpec::Get(house), Town::GetByTile(tile), acceptance, always_accepted);
844}
845
852{
853 CargoTypes always_accepted{};
854 CargoArray acceptance{};
855 AddAcceptedCargoOfHouse(INVALID_TILE, hs->Index(), hs, nullptr, acceptance, always_accepted);
856 return acceptance;
857}
858
859static void GetTileDesc_Town(TileIndex tile, TileDesc &td)
860{
861 const HouseID house = GetHouseType(tile);
862 const HouseSpec *hs = HouseSpec::Get(house);
863 bool house_completed = IsHouseCompleted(tile);
864
865 td.str = hs->building_name;
867
868 std::array<int32_t, 1> regs100;
869 uint16_t callback_res = GetHouseCallback(CBID_HOUSE_CUSTOM_NAME, house_completed ? 1 : 0, 0, house, Town::GetByTile(tile), tile, regs100);
870 if (callback_res != CALLBACK_FAILED && callback_res != 0x400) {
871 StringID new_name = STR_NULL;
872 if (callback_res == 0x40F) {
873 new_name = GetGRFStringID(hs->grf_prop.grfid, static_cast<GRFStringID>(regs100[0]));
874 } else if (callback_res > 0x400) {
876 } else {
877 new_name = GetGRFStringID(hs->grf_prop.grfid, GRFSTR_MISC_GRF_TEXT + callback_res);
878 }
879 if (new_name != STR_NULL && new_name != STR_UNDEFINED) {
880 td.str = new_name;
881 }
882 }
883
884 if (!house_completed) {
885 td.dparam = td.str;
886 td.str = STR_LAI_TOWN_INDUSTRY_DESCRIPTION_UNDER_CONSTRUCTION;
887 }
888
889 if (hs->grf_prop.HasGrfFile()) {
890 const GRFConfig *gc = GetGRFConfig(hs->grf_prop.grfid);
891 td.grf = gc->GetName();
892 }
893
894 td.owner[0] = OWNER_TOWN;
895}
896
897static TrackStatus GetTileTrackStatus_Town(TileIndex, TransportType, uint, DiagDirection)
898{
899 /* not used */
900 return 0;
901}
902
903static void ChangeTileOwner_Town(TileIndex, Owner, Owner)
904{
905 /* not used */
906}
907
908static bool GrowTown(Town *t, TownExpandModes modes);
909
914static void TownTickHandler(Town *t)
915{
916 if (HasBit(t->flags, TOWN_IS_GROWING)) {
919 int i = (int)t->grow_counter - 1;
920 if (i < 0) {
921 if (GrowTown(t, modes)) {
922 i = t->growth_rate;
923 } else {
924 /* If growth failed wait a bit before retrying */
925 i = std::min<uint16_t>(t->growth_rate, Ticks::TOWN_GROWTH_TICKS - 1);
926 }
927 }
928 t->grow_counter = i;
929 }
930}
931
934{
935 if (_game_mode == GM_EDITOR) return;
936
937 for (Town *t : Town::Iterate()) {
939 }
940}
941
948{
949 if (IsRoadDepotTile(tile) || IsBayRoadStopTile(tile)) return ROAD_NONE;
950
951 return GetAnyRoadBits(tile, RTT_ROAD, true);
952}
953
959{
960 RoadType best_rt = ROADTYPE_ROAD;
961 const RoadTypeInfo *best = nullptr;
962 const uint16_t assume_max_speed = 50;
963
964 for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
965 if (RoadTypeIsTram(rt)) continue;
966
967 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
968
969 /* Unused road type. */
970 if (rti->label == 0) continue;
971
972 /* Can town build this road. */
973 if (!rti->flags.Test(RoadTypeFlag::TownBuild)) continue;
974
975 /* Not yet introduced at this date. */
977
978 if (best != nullptr) {
979 if ((rti->max_speed == 0 ? assume_max_speed : rti->max_speed) < (best->max_speed == 0 ? assume_max_speed : best->max_speed)) continue;
980 }
981
982 best_rt = rt;
983 best = rti;
984 }
985
986 return best_rt;
987}
988
994{
995 const RoadTypeInfo *best = nullptr;
996 for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) {
997 if (RoadTypeIsTram(rt)) continue;
998 const RoadTypeInfo *rti = GetRoadTypeInfo(rt);
999 if (rti->label == 0) continue; // Unused road type.
1000 if (!rti->flags.Test(RoadTypeFlag::TownBuild)) continue; // Town can't build this road type.
1001
1002 if (best != nullptr && rti->introduction_date >= best->introduction_date) continue;
1003 best = rti;
1004 }
1005
1006 if (best == nullptr) return TimerGameCalendar::Date(INT32_MAX);
1007 return best->introduction_date;
1008}
1009
1015{
1016 auto min_date = GetTownRoadTypeFirstIntroductionDate();
1017 if (min_date <= TimerGameCalendar::date) return true;
1018
1019 if (min_date < INT32_MAX) {
1021 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_YET),
1022 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_YET_EXPLANATION, min_date),
1023 WL_CRITICAL);
1024 } else {
1026 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_AT_ALL),
1027 GetEncodedString(STR_ERROR_NO_TOWN_ROADTYPES_AVAILABLE_AT_ALL_EXPLANATION), WL_CRITICAL);
1028 }
1029 return false;
1030}
1031
1042static bool IsNeighbourRoadTile(TileIndex tile, const DiagDirection dir, uint dist_multi)
1043{
1044 if (!IsValidTile(tile)) return false;
1045
1046 /* Lookup table for the used diff values */
1047 const TileIndexDiff tid_lt[3] = {
1051 };
1052
1053 dist_multi = (dist_multi + 1) * 4;
1054 for (uint pos = 4; pos < dist_multi; pos++) {
1055 /* Go (pos / 4) tiles to the left or the right */
1056 TileIndexDiff cur = tid_lt[(pos & 1) ? 0 : 1] * (pos / 4);
1057
1058 /* Use the current tile as origin, or go one tile backwards */
1059 if (pos & 2) cur += tid_lt[2];
1060
1061 /* Test for roadbit parallel to dir and facing towards the middle axis */
1062 if (IsValidTile(tile + cur) &&
1063 GetTownRoadBits(TileAdd(tile, cur)) & DiagDirToRoadBits((pos & 2) ? dir : ReverseDiagDir(dir))) return true;
1064 }
1065 return false;
1066}
1067
1077{
1078 if (DistanceFromEdge(tile) == 0) return false;
1079
1080 /* Prevent towns from building roads under bridges along the bridge. Looks silly. */
1081 if (IsBridgeAbove(tile) && GetBridgeAxis(tile) == DiagDirToAxis(dir)) return false;
1082
1083 /* Check if there already is a road at this point? */
1084 if (GetTownRoadBits(tile) == ROAD_NONE) {
1085 /* No, try if we are able to build a road piece there.
1086 * If that fails clear the land, and if that fails exit.
1087 * This is to make sure that we can build a road here later. */
1091 return false;
1092 }
1093 }
1094
1095 Slope cur_slope = _settings_game.construction.build_on_slopes ? std::get<0>(GetFoundationSlope(tile)) : GetTileSlope(tile);
1096 bool ret = !IsNeighbourRoadTile(tile, dir, t->layout == TL_ORIGINAL ? 1 : 2);
1097 if (cur_slope == SLOPE_FLAT) return ret;
1098
1099 /* If the tile is not a slope in the right direction, then
1100 * maybe terraform some. */
1101 Slope desired_slope = (dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? SLOPE_NW : SLOPE_NE;
1102 if (desired_slope != cur_slope && ComplementSlope(desired_slope) != cur_slope) {
1103 if (Chance16(1, 8)) {
1104 CommandCost res = CMD_ERROR;
1105 if (!_generating_world && Chance16(1, 10)) {
1106 /* Note: Do not replace "^ SLOPE_ELEVATED" with ComplementSlope(). The slope might be steep. */
1108 tile, Chance16(1, 16) ? cur_slope : cur_slope ^ SLOPE_ELEVATED, false));
1109 }
1110 if (res.Failed() && Chance16(1, 3)) {
1111 /* We can consider building on the slope, though. */
1112 return ret;
1113 }
1114 }
1115 return false;
1116 }
1117 return ret;
1118}
1119
1120static bool TerraformTownTile(TileIndex tile, Slope edges, bool dir)
1121{
1122 assert(tile < Map::Size());
1123
1125 if (r.Failed() || r.GetCost() >= (_price[PR_TERRAFORM] + 2) * 8) return false;
1127 return true;
1128}
1129
1130static void LevelTownLand(TileIndex tile)
1131{
1132 assert(tile < Map::Size());
1133
1134 /* Don't terraform if land is plain or if there's a house there. */
1135 if (IsTileType(tile, MP_HOUSE)) return;
1136 Slope tileh = GetTileSlope(tile);
1137 if (tileh == SLOPE_FLAT) return;
1138
1139 /* First try up, then down */
1140 if (!TerraformTownTile(tile, ~tileh & SLOPE_ELEVATED, true)) {
1141 TerraformTownTile(tile, tileh & SLOPE_ELEVATED, false);
1142 }
1143}
1144
1154{
1155 /* align the grid to the downtown */
1156 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile); // Vector from downtown to the tile
1157 RoadBits rcmd = ROAD_NONE;
1158
1159 switch (t->layout) {
1160 default: NOT_REACHED();
1161
1162 case TL_2X2_GRID:
1163 if ((grid_pos.x % 3) == 0) rcmd |= ROAD_Y;
1164 if ((grid_pos.y % 3) == 0) rcmd |= ROAD_X;
1165 break;
1166
1167 case TL_3X3_GRID:
1168 if ((grid_pos.x % 4) == 0) rcmd |= ROAD_Y;
1169 if ((grid_pos.y % 4) == 0) rcmd |= ROAD_X;
1170 break;
1171 }
1172
1173 /* Optimise only X-junctions */
1174 if (rcmd != ROAD_ALL) return rcmd;
1175
1176 RoadBits rb_template;
1177
1178 switch (GetTileSlope(tile)) {
1179 default: rb_template = ROAD_ALL; break;
1180 case SLOPE_W: rb_template = ROAD_NW | ROAD_SW; break;
1181 case SLOPE_SW: rb_template = ROAD_Y | ROAD_SW; break;
1182 case SLOPE_S: rb_template = ROAD_SW | ROAD_SE; break;
1183 case SLOPE_SE: rb_template = ROAD_X | ROAD_SE; break;
1184 case SLOPE_E: rb_template = ROAD_SE | ROAD_NE; break;
1185 case SLOPE_NE: rb_template = ROAD_Y | ROAD_NE; break;
1186 case SLOPE_N: rb_template = ROAD_NE | ROAD_NW; break;
1187 case SLOPE_NW: rb_template = ROAD_X | ROAD_NW; break;
1188 case SLOPE_STEEP_W:
1189 case SLOPE_STEEP_S:
1190 case SLOPE_STEEP_E:
1191 case SLOPE_STEEP_N:
1192 rb_template = ROAD_NONE;
1193 break;
1194 }
1195
1196 /* Stop if the template is compatible to the growth dir */
1197 if (DiagDirToRoadBits(ReverseDiagDir(dir)) & rb_template) return rb_template;
1198 /* If not generate a straight road in the direction of the growth */
1200}
1201
1213{
1214 /* We can't look further than that. */
1215 if (DistanceFromEdge(tile) == 0) return false;
1216
1217 uint counter = 0; // counts the house neighbour tiles
1218
1219 /* Check the tiles E,N,W and S of the current tile for houses */
1220 for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
1221 /* Count both void and house tiles for checking whether there
1222 * are enough houses in the area. This to make it likely that
1223 * houses get build up to the edge of the map. */
1224 switch (GetTileType(TileAddByDiagDir(tile, dir))) {
1225 case MP_HOUSE:
1226 case MP_VOID:
1227 counter++;
1228 break;
1229
1230 default:
1231 break;
1232 }
1233
1234 /* If there are enough neighbours stop here */
1235 if (counter >= 3) {
1236 return TryBuildTownHouse(t, tile, modes);
1237 }
1238 }
1239 return false;
1240}
1241
1250static bool GrowTownWithRoad(const Town *t, TileIndex tile, RoadBits rcmd)
1251{
1254}
1255
1265static bool CanRoadContinueIntoNextTile(const Town *t, const TileIndex tile, const DiagDirection road_dir)
1266{
1267 const TileIndexDiff delta = TileOffsByDiagDir(road_dir); // +1 tile in the direction of the road
1268 TileIndex next_tile = tile + delta; // The tile beyond which must be connectable to the target tile
1269 RoadBits rcmd = DiagDirToRoadBits(ReverseDiagDir(road_dir));
1271
1272 /* Before we try anything, make sure the tile is on the map and not the void. */
1273 if (!IsValidTile(next_tile)) return false;
1274
1275 /* If the next tile is a bridge or tunnel, allow if it's continuing in the same direction. */
1276 if (IsTileType(next_tile, MP_TUNNELBRIDGE)) {
1277 return GetTunnelBridgeTransportType(next_tile) == TRANSPORT_ROAD && GetTunnelBridgeDirection(next_tile) == road_dir;
1278 }
1279
1280 /* If the next tile is a station, allow if it's a road station facing the proper direction. Otherwise return false. */
1281 if (IsTileType(next_tile, MP_STATION)) {
1282 /* If the next tile is a road station, allow if it can be entered by the new tunnel/bridge, otherwise disallow. */
1283 if (IsDriveThroughStopTile(next_tile)) return GetDriveThroughStopAxis(next_tile) == DiagDirToAxis(road_dir);
1284 if (IsBayRoadStopTile(next_tile)) return GetBayRoadStopDir(next_tile) == ReverseDiagDir(road_dir);
1285 return false;
1286 }
1287
1288 /* If the next tile is a road depot, allow if it's facing the right way. */
1289 if (IsTileType(next_tile, MP_ROAD)) {
1290 return IsRoadDepot(next_tile) && GetRoadDepotDirection(next_tile) == ReverseDiagDir(road_dir);
1291 }
1292
1293 /* If the next tile is a railroad track, check if towns are allowed to build level crossings.
1294 * If level crossing are not allowed, reject the construction. Else allow DoCommand to determine if the rail track is buildable. */
1295 if (IsTileType(next_tile, MP_RAILWAY) && !_settings_game.economy.allow_town_level_crossings) return false;
1296
1297 /* If a road tile can be built, the construction is allowed. */
1298 return Command<CMD_BUILD_ROAD>::Do({DoCommandFlag::Auto, DoCommandFlag::NoWater}, next_tile, rcmd, rt, DRD_NONE, t->index).Succeeded();
1299}
1300
1311static bool GrowTownWithBridge(const Town *t, const TileIndex tile, const DiagDirection bridge_dir)
1312{
1313 assert(bridge_dir < DIAGDIR_END);
1314
1315 const Slope slope = GetTileSlope(tile);
1316
1317 /* Make sure the direction is compatible with the slope.
1318 * Well we check if the slope has an up bit set in the
1319 * reverse direction. */
1320 if (slope != SLOPE_FLAT && slope & InclinedSlope(bridge_dir)) return false;
1321
1322 /* Assure that the bridge is connectable to the start side */
1323 if (!(GetTownRoadBits(TileAddByDiagDir(tile, ReverseDiagDir(bridge_dir))) & DiagDirToRoadBits(bridge_dir))) return false;
1324
1325 /* We are in the right direction */
1326 uint bridge_length = 0; // This value stores the length of the possible bridge
1327 TileIndex bridge_tile = tile; // Used to store the other waterside
1328
1329 const TileIndexDiff delta = TileOffsByDiagDir(bridge_dir);
1330
1331 /* To prevent really small towns from building disproportionately
1332 * long bridges, make the max a function of its population. */
1333 const uint TOWN_BRIDGE_LENGTH_CAP = 11;
1334 uint base_bridge_length = 5;
1335 uint max_bridge_length = std::min(t->cache.population / 1000 + base_bridge_length, TOWN_BRIDGE_LENGTH_CAP);
1336
1337 if (slope == SLOPE_FLAT) {
1338 /* Bridges starting on flat tiles are only allowed when crossing rivers, rails or one-way roads. */
1339 do {
1340 if (bridge_length++ >= base_bridge_length) {
1341 /* Allow to cross rivers, not big lakes, nor large amounts of rails or one-way roads. */
1342 return false;
1343 }
1344 bridge_tile += delta;
1345 } while (IsValidTile(bridge_tile) && ((IsWaterTile(bridge_tile) && !IsSea(bridge_tile)) || IsPlainRailTile(bridge_tile) || (IsNormalRoadTile(bridge_tile) && GetDisallowedRoadDirections(bridge_tile) != DRD_NONE)));
1346 } else {
1347 do {
1348 if (bridge_length++ >= max_bridge_length) {
1349 /* Ensure the bridge is not longer than the max allowed length. */
1350 return false;
1351 }
1352 bridge_tile += delta;
1353 } while (IsValidTile(bridge_tile) && (IsWaterTile(bridge_tile) || IsPlainRailTile(bridge_tile) || (IsNormalRoadTile(bridge_tile) && GetDisallowedRoadDirections(bridge_tile) != DRD_NONE)));
1354 }
1355
1356 /* Don't allow a bridge where the start and end tiles are adjacent with no span between. */
1357 if (bridge_length == 1) return false;
1358
1359 /* Make sure the road can be continued past the bridge. At this point, bridge_tile holds the end tile of the bridge. */
1360 if (!CanRoadContinueIntoNextTile(t, bridge_tile, bridge_dir)) return false;
1361
1362 /* If another parallel bridge exists nearby, this one would be redundant and shouldn't be built. We don't care about flat bridges. */
1363 if (slope != SLOPE_FLAT) {
1364 for (auto search : SpiralTileSequence(tile, bridge_length, 0, 0)) {
1365 /* Only consider bridge head tiles. */
1366 if (!IsBridgeTile(search)) continue;
1367
1368 /* Only consider road bridges. */
1369 if (GetTunnelBridgeTransportType(search) != TRANSPORT_ROAD) continue;
1370
1371 /* If the bridge is facing the same direction as the proposed bridge, we've found a redundant bridge. */
1372 if (GetTileSlope(search) & InclinedSlope(ReverseDiagDir(bridge_dir))) return false;
1373 }
1374 }
1375
1376 for (uint8_t times = 0; times <= 22; times++) {
1377 uint8_t bridge_type = RandomRange(MAX_BRIDGES - 1);
1378
1379 /* Can we actually build the bridge? */
1381 if (Command<CMD_BUILD_BRIDGE>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_BRIDGE>()), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, rt).Succeeded()) {
1382 Command<CMD_BUILD_BRIDGE>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_BRIDGE>()).Set(DoCommandFlag::Execute), tile, bridge_tile, TRANSPORT_ROAD, bridge_type, rt);
1383 return true;
1384 }
1385 }
1386 /* Quit if it selecting an appropriate bridge type fails a large number of times. */
1387 return false;
1388}
1389
1400static bool GrowTownWithTunnel(const Town *t, const TileIndex tile, const DiagDirection tunnel_dir)
1401{
1402 assert(tunnel_dir < DIAGDIR_END);
1403
1404 Slope slope = GetTileSlope(tile);
1405
1406 /* Only consider building a tunnel if the starting tile is sloped properly. */
1407 if (slope != InclinedSlope(tunnel_dir)) return false;
1408
1409 /* Assure that the tunnel is connectable to the start side */
1410 if (!(GetTownRoadBits(TileAddByDiagDir(tile, ReverseDiagDir(tunnel_dir))) & DiagDirToRoadBits(tunnel_dir))) return false;
1411
1412 const TileIndexDiff delta = TileOffsByDiagDir(tunnel_dir);
1413 int max_tunnel_length = 0;
1414
1415 /* There are two conditions for building tunnels: Under a mountain and under an obstruction. */
1416 if (CanRoadContinueIntoNextTile(t, tile, tunnel_dir)) {
1417 /* 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. */
1418 TileIndex slope_tile = tile;
1419 for (uint8_t tiles = 0; tiles < 4; tiles++) {
1420 if (!IsValidTile(slope_tile)) return false;
1421 slope = GetTileSlope(slope_tile);
1422 if (slope != InclinedSlope(tunnel_dir) && !IsSteepSlope(slope) && !IsSlopeWithOneCornerRaised(slope)) return false;
1423 slope_tile += delta;
1424 }
1425
1426 /* More population means longer tunnels, but make sure we can at least cover the smallest mountain which neccesitates tunneling. */
1427 max_tunnel_length = (t->cache.population / 1000) + 7;
1428 } else {
1429 /* When tunneling under an obstruction, the length limit is 5, enough to tunnel under a four-track railway. */
1430 max_tunnel_length = 5;
1431 }
1432
1433 uint8_t tunnel_length = 0;
1434 TileIndex tunnel_tile = tile; // Iteratator to store the other end tile of the tunnel.
1435
1436 /* Find the end tile of the tunnel for length and continuation checks. */
1437 do {
1438 if (tunnel_length++ >= max_tunnel_length) return false;
1439 tunnel_tile += delta;
1440 /* The tunnel ends when start and end tiles are the same height. */
1441 } while (IsValidTile(tunnel_tile) && GetTileZ(tile) != GetTileZ(tunnel_tile));
1442
1443 /* Don't allow a tunnel where the start and end tiles are adjacent. */
1444 if (tunnel_length == 1) return false;
1445
1446 /* Make sure the road can be continued past the tunnel. At this point, tunnel_tile holds the end tile of the tunnel. */
1447 if (!CanRoadContinueIntoNextTile(t, tunnel_tile, tunnel_dir)) return false;
1448
1449 /* Attempt to build the tunnel. Return false if it fails to let the town build a road instead. */
1451 if (Command<CMD_BUILD_TUNNEL>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_TUNNEL>()), tile, TRANSPORT_ROAD, rt).Succeeded()) {
1452 Command<CMD_BUILD_TUNNEL>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_TUNNEL>()).Set(DoCommandFlag::Execute), tile, TRANSPORT_ROAD, rt);
1453 return true;
1454 }
1455
1456 return false;
1457}
1458
1466{
1467 static const TileIndexDiffC tiles[] = { {-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1} };
1468 bool allow = false;
1469
1470 for (const auto &ptr : tiles) {
1471 TileIndex cur_tile = t + ToTileIndexDiff(ptr);
1472 if (!IsValidTile(cur_tile)) continue;
1473
1474 if (!(IsTileType(cur_tile, MP_ROAD) || IsAnyRoadStopTile(cur_tile))) continue;
1475 allow = true;
1476
1477 RoadType road_rt = GetRoadTypeRoad(cur_tile);
1478 RoadType tram_rt = GetRoadTypeTram(cur_tile);
1479 if (road_rt != INVALID_ROADTYPE && !GetRoadTypeInfo(road_rt)->flags.Test(RoadTypeFlag::NoHouses)) return true;
1480 if (tram_rt != INVALID_ROADTYPE && !GetRoadTypeInfo(tram_rt)->flags.Test(RoadTypeFlag::NoHouses)) return true;
1481 }
1482
1483 /* If no road was found surrounding the tile we can allow building the house since there is
1484 * nothing which forbids it, if a road was found but the execution reached this point, then
1485 * all the found roads don't allow houses to be built */
1486 return !allow;
1487}
1488
1494{
1495 if (!IsTileType(tile, MP_ROAD)) return true;
1496
1497 /* Allow extending on roadtypes which can be built by town, or if the road type matches the type the town will build. */
1498 RoadType rt = GetRoadTypeRoad(tile);
1500}
1501
1507{
1508 return modes.Test(TownExpandMode::Roads);
1509}
1510
1511/* The possible states of town growth. */
1512enum class TownGrowthResult {
1513 Succeed,
1514 SearchStopped,
1515 Continue,
1516};
1517
1536static TownGrowthResult GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection target_dir, Town *t1, TownExpandModes modes)
1537{
1538 RoadBits rcmd = ROAD_NONE; // RoadBits for the road construction command
1539 TileIndex tile = *tile_ptr; // The main tile on which we base our growth
1540
1541 assert(tile < Map::Size());
1542
1543 if (cur_rb == ROAD_NONE) {
1544 /* Tile has no road.
1545 * We will return TownGrowthResult::SearchStopped to say that this is the last iteration. */
1546
1547 if (!TownAllowedToBuildRoads(modes)) return TownGrowthResult::SearchStopped;
1548 if (!_settings_game.economy.allow_town_level_crossings && IsTileType(tile, MP_RAILWAY)) return TownGrowthResult::SearchStopped;
1549
1550 /* Remove hills etc */
1551 if (!_settings_game.construction.build_on_slopes || Chance16(1, 6)) LevelTownLand(tile);
1552
1553 /* Is a road allowed here? */
1554 switch (t1->layout) {
1555 default: NOT_REACHED();
1556
1557 case TL_3X3_GRID:
1558 case TL_2X2_GRID:
1559 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1560 if (rcmd == ROAD_NONE) return TownGrowthResult::SearchStopped;
1561 break;
1562
1563 case TL_BETTER_ROADS:
1564 case TL_ORIGINAL:
1565 if (!IsRoadAllowedHere(t1, tile, target_dir)) return TownGrowthResult::SearchStopped;
1566
1567 DiagDirection source_dir = ReverseDiagDir(target_dir);
1568
1569 if (Chance16(1, 4)) {
1570 /* Randomize a new target dir */
1571 do target_dir = RandomDiagDir(); while (target_dir == source_dir);
1572 }
1573
1574 if (!IsRoadAllowedHere(t1, TileAddByDiagDir(tile, target_dir), target_dir)) {
1575 /* A road is not allowed to continue the randomized road,
1576 * return if the road we're trying to build is curved. */
1577 if (target_dir != ReverseDiagDir(source_dir)) return TownGrowthResult::SearchStopped;
1578
1579 /* Return if neither side of the new road is a house */
1582 return TownGrowthResult::SearchStopped;
1583 }
1584
1585 /* That means that the road is only allowed if there is a house
1586 * at any side of the new road. */
1587 }
1588
1589 rcmd = DiagDirToRoadBits(target_dir) | DiagDirToRoadBits(source_dir);
1590 break;
1591 }
1592
1593 } else if (target_dir < DIAGDIR_END && !(cur_rb & DiagDirToRoadBits(ReverseDiagDir(target_dir)))) {
1594 if (!TownCanGrowRoad(tile)) return TownGrowthResult::Continue;
1595
1596 if (!TownAllowedToBuildRoads(modes)) return TownGrowthResult::SearchStopped;
1597
1598 /* Continue building on a partial road.
1599 * Should be always OK, so we only generate
1600 * the fitting RoadBits */
1601 switch (t1->layout) {
1602 default: NOT_REACHED();
1603
1604 case TL_3X3_GRID:
1605 case TL_2X2_GRID:
1606 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1607 break;
1608
1609 case TL_BETTER_ROADS:
1610 case TL_ORIGINAL:
1611 rcmd = DiagDirToRoadBits(ReverseDiagDir(target_dir));
1612 break;
1613 }
1614 } else {
1615 bool allow_house = true; // Value which decides if we want to construct a house
1616
1617 /* Reached a tunnel/bridge? Then continue at the other side of it, unless
1618 * it is the starting tile. Half the time, we stay on this side then.*/
1619 if (IsTileType(tile, MP_TUNNELBRIDGE)) {
1620 if (GetTunnelBridgeTransportType(tile) == TRANSPORT_ROAD && (target_dir != DIAGDIR_END || Chance16(1, 2))) {
1621 *tile_ptr = GetOtherTunnelBridgeEnd(tile);
1622 }
1623 return TownGrowthResult::Continue;
1624 }
1625
1626 /* Possibly extend the road in a direction.
1627 * Randomize a direction and if it has a road, bail out. */
1628 target_dir = RandomDiagDir();
1629 RoadBits target_rb = DiagDirToRoadBits(target_dir);
1630 TileIndex house_tile; // position of a possible house
1631
1632 if (cur_rb & target_rb) {
1633 /* If it's a road turn possibly build a house in a corner.
1634 * Use intersection with straight road as an indicator
1635 * that we randomed corner house position.
1636 * A turn (and we check for that later) always has only
1637 * one common bit with a straight road so it has the same
1638 * chance to be chosen as the house on the side of a road.
1639 */
1640 if ((cur_rb & ROAD_X) != target_rb) return TownGrowthResult::Continue;
1641
1642 /* Check whether it is a turn and if so determine
1643 * position of the corner tile */
1644 switch (cur_rb) {
1645 case ROAD_N:
1646 house_tile = TileAddByDir(tile, DIR_S);
1647 break;
1648 case ROAD_S:
1649 house_tile = TileAddByDir(tile, DIR_N);
1650 break;
1651 case ROAD_E:
1652 house_tile = TileAddByDir(tile, DIR_W);
1653 break;
1654 case ROAD_W:
1655 house_tile = TileAddByDir(tile, DIR_E);
1656 break;
1657 default:
1658 return TownGrowthResult::Continue; // not a turn
1659 }
1660 target_dir = DIAGDIR_END;
1661 } else {
1662 house_tile = TileAddByDiagDir(tile, target_dir);
1663 }
1664
1665 /* Don't walk into water. */
1666 if (HasTileWaterGround(house_tile)) return TownGrowthResult::Continue;
1667
1668 if (!IsValidTile(house_tile)) return TownGrowthResult::Continue;
1669
1670 TownGrowthResult result = TownGrowthResult::Continue;
1671
1672 if (target_dir != DIAGDIR_END && TownAllowedToBuildRoads(modes)) {
1673 switch (t1->layout) {
1674 default: NOT_REACHED();
1675
1676 case TL_3X3_GRID: // Use 2x2 grid afterwards!
1677 if (GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir), modes)) {
1678 result = TownGrowthResult::Succeed;
1679 }
1680 [[fallthrough]];
1681
1682 case TL_2X2_GRID:
1683 rcmd = GetTownRoadGridElement(t1, tile, target_dir);
1684 allow_house = (rcmd & target_rb) == ROAD_NONE;
1685 break;
1686
1687 case TL_BETTER_ROADS: // Use original afterwards!
1688 if (GrowTownWithExtraHouse(t1, TileAddByDiagDir(house_tile, target_dir), modes)) {
1689 result = TownGrowthResult::Succeed;
1690 }
1691 [[fallthrough]];
1692
1693 case TL_ORIGINAL:
1694 /* Allow a house at the edge. 60% chance or
1695 * always ok if no road allowed. */
1696 rcmd = target_rb;
1697 allow_house = (!IsRoadAllowedHere(t1, house_tile, target_dir) || Chance16(6, 10));
1698 break;
1699 }
1700 }
1701
1702 allow_house &= RoadTypesAllowHouseHere(house_tile);
1703
1704 if (allow_house) {
1705 /* Build a house, but not if there already is a house there. */
1706 if (!IsTileType(house_tile, MP_HOUSE)) {
1707 /* Level the land if possible */
1708 if (Chance16(1, 6)) LevelTownLand(house_tile);
1709
1710 /* And build a house.
1711 * Set result to -1 if we managed to build it. */
1712 if (TryBuildTownHouse(t1, house_tile, modes)) {
1713 result = TownGrowthResult::Succeed;
1714 }
1715 }
1716 return result;
1717 }
1718
1719 if (!TownCanGrowRoad(tile)) return result;
1720 }
1721
1722 /* Return if a water tile */
1723 if (HasTileWaterGround(tile)) return TownGrowthResult::SearchStopped;
1724
1725 /* Make the roads look nicer */
1726 rcmd = CleanUpRoadBits(tile, rcmd);
1727 if (rcmd == ROAD_NONE) return TownGrowthResult::SearchStopped;
1728
1729 /* Only use the target direction for bridges and tunnels to ensure they're connected.
1730 * The target_dir is as computed previously according to town layout, so
1731 * it will match it perfectly. */
1732 if (GrowTownWithBridge(t1, tile, target_dir)) {
1733 return TownGrowthResult::Succeed;
1734 }
1735 if (GrowTownWithTunnel(t1, tile, target_dir)) {
1736 return TownGrowthResult::Succeed;
1737 }
1738
1739 if (GrowTownWithRoad(t1, tile, rcmd)) {
1740 return TownGrowthResult::Succeed;
1741 }
1742 return TownGrowthResult::SearchStopped;
1743}
1744
1753{
1754 TileIndex target_tile = tile + TileOffsByDiagDir(dir);
1755 if (!IsValidTile(target_tile)) return false;
1756 if (HasTileWaterGround(target_tile)) return false;
1757
1758 RoadBits target_rb = GetTownRoadBits(target_tile);
1759 if (TownAllowedToBuildRoads(modes)) {
1760 /* Check whether a road connection exists or can be build. */
1761 switch (GetTileType(target_tile)) {
1762 case MP_ROAD:
1763 return target_rb != ROAD_NONE;
1764
1765 case MP_STATION:
1766 return IsDriveThroughStopTile(target_tile);
1767
1768 case MP_TUNNELBRIDGE:
1769 return GetTunnelBridgeTransportType(target_tile) == TRANSPORT_ROAD;
1770
1771 case MP_HOUSE:
1772 case MP_INDUSTRY:
1773 case MP_OBJECT:
1774 return false;
1775
1776 default:
1777 /* Checked for void and water earlier */
1778 return true;
1779 }
1780 } else {
1781 /* Check whether a road connection already exists,
1782 * and it leads somewhere else. */
1784 return (target_rb & back_rb) != 0 && (target_rb & ~back_rb) != 0;
1785 }
1786}
1787
1794static bool GrowTownAtRoad(Town *t, TileIndex tile, TownExpandModes modes)
1795{
1796 /* Special case.
1797 * @see GrowTownInTile Check the else if
1798 */
1799 DiagDirection target_dir = DIAGDIR_END; // The direction in which we want to extend the town
1800
1801 assert(tile < Map::Size());
1802
1803 /* Number of times to search.
1804 * Better roads, 2X2 and 3X3 grid grow quite fast so we give
1805 * them a little handicap. */
1806 int iterations;
1807 switch (t->layout) {
1808 case TL_BETTER_ROADS:
1809 iterations = 10 + t->cache.num_houses * 2 / 9;
1810 break;
1811
1812 case TL_3X3_GRID:
1813 case TL_2X2_GRID:
1814 iterations = 10 + t->cache.num_houses * 1 / 9;
1815 break;
1816
1817 default:
1818 iterations = 10 + t->cache.num_houses * 4 / 9;
1819 break;
1820 }
1821
1822 do {
1823 RoadBits cur_rb = GetTownRoadBits(tile); // The RoadBits of the current tile
1824
1825 /* Try to grow the town from this point */
1826 switch (GrowTownInTile(&tile, cur_rb, target_dir, t, modes)) {
1827 case TownGrowthResult::Succeed:
1828 return true;
1829 case TownGrowthResult::SearchStopped:
1830 iterations = 0;
1831 break;
1832 default:
1833 break;
1834 };
1835
1836 /* Exclude the source position from the bitmask
1837 * and return if no more road blocks available */
1838 if (IsValidDiagDirection(target_dir)) cur_rb &= ~DiagDirToRoadBits(ReverseDiagDir(target_dir));
1839 if (cur_rb == ROAD_NONE) return false;
1840
1841 if (IsTileType(tile, MP_TUNNELBRIDGE)) {
1842 /* Only build in the direction away from the tunnel or bridge. */
1843 target_dir = ReverseDiagDir(GetTunnelBridgeDirection(tile));
1844 } else {
1845 /* Select a random bit from the blockmask, walk a step
1846 * and continue the search from there. */
1847 do {
1848 if (cur_rb == ROAD_NONE) return false;
1849 RoadBits target_bits;
1850 do {
1851 target_dir = RandomDiagDir();
1852 target_bits = DiagDirToRoadBits(target_dir);
1853 } while (!(cur_rb & target_bits));
1854 cur_rb &= ~target_bits;
1855 } while (!CanFollowRoad(tile, target_dir, modes));
1856 }
1857 tile = TileAddByDiagDir(tile, target_dir);
1858
1859 if (IsTileType(tile, MP_ROAD) && !IsRoadDepot(tile) && HasTileRoadType(tile, RTT_ROAD)) {
1860 /* Don't allow building over roads of other cities */
1861 if (IsRoadOwner(tile, RTT_ROAD, OWNER_TOWN) && Town::GetByTile(tile) != t) {
1862 return false;
1863 } else if (IsRoadOwner(tile, RTT_ROAD, OWNER_NONE) && _game_mode == GM_EDITOR) {
1864 /* If we are in the SE, and this road-piece has no town owner yet, it just found an
1865 * owner :) (happy happy happy road now) */
1866 SetRoadOwner(tile, RTT_ROAD, OWNER_TOWN);
1867 SetTownIndex(tile, t->index);
1868 }
1869 }
1870
1871 /* Max number of times is checked. */
1872 } while (--iterations >= 0);
1873
1874 return false;
1875}
1876
1885{
1886 uint32_t r = Random();
1887 uint a = GB(r, 0, 2);
1888 uint b = GB(r, 8, 2);
1889 if (a == b) b ^= 2;
1890 return (RoadBits)((ROAD_NW << a) + (ROAD_NW << b));
1891}
1892
1898static bool GrowTown(Town *t, TownExpandModes modes)
1899{
1900 static const TileIndexDiffC _town_coord_mod[] = {
1901 {-1, 0},
1902 { 1, 1},
1903 { 1, -1},
1904 {-1, -1},
1905 {-1, 0},
1906 { 0, 2},
1907 { 2, 0},
1908 { 0, -2},
1909 {-1, -1},
1910 {-2, 2},
1911 { 2, 2},
1912 { 2, -2},
1913 { 0, 0}
1914 };
1915
1916 /* Current "company" is a town */
1918
1919 TileIndex tile = t->xy; // The tile we are working with ATM
1920
1921 /* Find a road that we can base the construction on. */
1922 for (const auto &ptr : _town_coord_mod) {
1923 if (GetTownRoadBits(tile) != ROAD_NONE) {
1924 bool success = GrowTownAtRoad(t, tile, modes);
1925 cur_company.Restore();
1926 return success;
1927 }
1928 tile = TileAdd(tile, ToTileIndexDiff(ptr));
1929 }
1930
1931 /* No road available, try to build a random road block by
1932 * clearing some land and then building a road there. */
1933 if (TownAllowedToBuildRoads(modes)) {
1934 tile = t->xy;
1935 for (const auto &ptr : _town_coord_mod) {
1936 /* Only work with plain land that not already has a house */
1937 if (!IsTileType(tile, MP_HOUSE) && IsTileFlat(tile)) {
1941 cur_company.Restore();
1942 return true;
1943 }
1944 }
1945 tile = TileAdd(tile, ToTileIndexDiff(ptr));
1946 }
1947 }
1948
1949 cur_company.Restore();
1950 return false;
1951}
1952
1958{
1959 static const std::array<std::array<uint32_t, NUM_HOUSE_ZONES>, 23> _town_squared_town_zone_radius_data = {{
1960 { 4, 0, 0, 0, 0}, // 0
1961 { 16, 0, 0, 0, 0},
1962 { 25, 0, 0, 0, 0},
1963 { 36, 0, 0, 0, 0},
1964 { 49, 0, 4, 0, 0},
1965 { 64, 0, 4, 0, 0}, // 20
1966 { 64, 0, 9, 0, 1},
1967 { 64, 0, 9, 0, 4},
1968 { 64, 0, 16, 0, 4},
1969 { 81, 0, 16, 0, 4},
1970 { 81, 0, 16, 0, 4}, // 40
1971 { 81, 0, 25, 0, 9},
1972 { 81, 36, 25, 0, 9},
1973 { 81, 36, 25, 16, 9},
1974 { 81, 49, 0, 25, 9},
1975 { 81, 64, 0, 25, 9}, // 60
1976 { 81, 64, 0, 36, 9},
1977 { 81, 64, 0, 36, 16},
1978 {100, 81, 0, 49, 16},
1979 {100, 81, 0, 49, 25},
1980 {121, 81, 0, 49, 25}, // 80
1981 {121, 81, 0, 49, 25},
1982 {121, 81, 0, 49, 36}, // 88
1983 }};
1984
1985 if (t->cache.num_houses < std::size(_town_squared_town_zone_radius_data) * 4) {
1986 t->cache.squared_town_zone_radius = _town_squared_town_zone_radius_data[t->cache.num_houses / 4];
1987 } else {
1988 int mass = t->cache.num_houses / 8;
1989 /* Actually we are proportional to sqrt() but that's right because we are covering an area.
1990 * The offsets are to make sure the radii do not decrease in size when going from the table
1991 * to the calculated value.*/
1992 t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownEdge)] = mass * 15 - 40;
1993 t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownOutskirt)] = mass * 9 - 15;
1994 t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownOuterSuburb)] = 0;
1995 t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownInnerSuburb)] = mass * 5 - 5;
1996 t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownCentre)] = mass * 3 + 5;
1997 }
1998}
1999
2005{
2007 t->supplied[cs->Index()].old_max = ScaleByCargoScale(t->cache.population >> 3, true);
2008 }
2010 t->supplied[cs->Index()].old_max = ScaleByCargoScale(t->cache.population >> 4, true);
2011 }
2012}
2013
2014static void UpdateTownGrowthRate(Town *t);
2015static void UpdateTownGrowth(Town *t);
2016
2028static void DoCreateTown(Town *t, TileIndex tile, uint32_t townnameparts, TownSize size, bool city, TownLayout layout, bool manual)
2029{
2030 AutoRestoreBackup backup(_generating_town, true);
2031
2032 t->xy = tile;
2033 t->cache.num_houses = 0;
2034 t->time_until_rebuild = 10;
2036 t->flags = 0;
2037 t->cache.population = 0;
2039 /* Spread growth across ticks so even if there are many
2040 * similar towns they're unlikely to grow all in one tick */
2042 t->growth_rate = TownTicksToGameTicks(250);
2043 t->show_zone = false;
2044
2045 _town_kdtree.Insert(t->index);
2046
2047 /* Set the default cargo requirement for town growth */
2049 case LandscapeType::Arctic:
2051 break;
2052
2053 case LandscapeType::Tropic:
2056 break;
2057
2058 default:
2059 break;
2060 }
2061
2062 t->fund_buildings_months = 0;
2063
2064 for (uint i = 0; i != MAX_COMPANIES; i++) t->ratings[i] = RATING_INITIAL;
2065
2066 t->have_ratings = {};
2067 t->exclusivity = CompanyID::Invalid();
2068 t->exclusive_counter = 0;
2069 t->statues = {};
2070
2071 {
2073 t->townnamegrfid = tnp.grfid;
2074 t->townnametype = tnp.type;
2075 }
2076 t->townnameparts = townnameparts;
2077
2078 t->InitializeLayout(layout);
2079
2080 t->larger_town = city;
2081
2082 int x = (int)size * 16 + 3;
2083 if (size == TSZ_RANDOM) x = (Random() & 0xF) + 8;
2084 /* Don't create huge cities when founding town in-game */
2085 if (city && (!manual || _game_mode == GM_EDITOR)) x *= _settings_game.economy.initial_city_size;
2086
2087 t->cache.num_houses += x;
2089
2090 int i = x * 4;
2091 do {
2093 } while (--i);
2094
2095 t->UpdateVirtCoord();
2096 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_REBUILD);
2097
2098 t->cache.num_houses -= x;
2103}
2104
2111{
2112 /* Check if too close to the edge of map */
2113 if (DistanceFromEdge(tile) < 12) {
2114 return CommandCost(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB);
2115 }
2116
2117 /* Check distance to all other towns. */
2118 if (IsCloseToTown(tile, 20)) {
2119 return CommandCost(STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN);
2120 }
2121
2122 /* Can only build on clear flat areas, possibly with trees. */
2123 if ((!IsTileType(tile, MP_CLEAR) && !IsTileType(tile, MP_TREES)) || !IsTileFlat(tile)) {
2124 return CommandCost(STR_ERROR_SITE_UNSUITABLE);
2125 }
2126
2128}
2129
2135static bool IsUniqueTownName(const std::string &name)
2136{
2137 for (const Town *t : Town::Iterate()) {
2138 if (!t->name.empty() && t->name == name) return false;
2139 }
2140
2141 return true;
2142}
2143
2156std::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)
2157{
2159
2160 if (size >= TSZ_END) return { CMD_ERROR, 0, TownID::Invalid() };
2161 if (layout >= NUM_TLS) return { CMD_ERROR, 0, TownID::Invalid() };
2162
2163 /* Some things are allowed only in the scenario editor and for game scripts. */
2164 if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY) {
2165 if (_settings_game.economy.found_town == TF_FORBIDDEN) return { CMD_ERROR, 0, TownID::Invalid() };
2166 if (size == TSZ_LARGE) return { CMD_ERROR, 0, TownID::Invalid() };
2167 if (random_location) return { CMD_ERROR, 0, TownID::Invalid() };
2169 return { CMD_ERROR, 0, TownID::Invalid() };
2170 }
2171 } else if (_current_company == OWNER_DEITY && random_location) {
2172 /* Random parameter is not allowed for Game Scripts. */
2173 return { CMD_ERROR, 0, TownID::Invalid() };
2174 }
2175
2176 if (text.empty()) {
2177 /* If supplied name is empty, townnameparts has to generate unique automatic name */
2178 if (!VerifyTownName(townnameparts, &par)) return { CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE), 0, TownID::Invalid() };
2179 } else {
2180 /* If name is not empty, it has to be unique custom name */
2181 if (Utf8StringLength(text) >= MAX_LENGTH_TOWN_NAME_CHARS) return { CMD_ERROR, 0, TownID::Invalid() };
2182 if (!IsUniqueTownName(text)) return { CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE), 0, TownID::Invalid() };
2183 }
2184
2185 /* Allocate town struct */
2186 if (!Town::CanAllocateItem()) return { CommandCost(STR_ERROR_TOO_MANY_TOWNS), 0, TownID::Invalid() };
2187
2188 if (!random_location) {
2189 CommandCost ret = TownCanBePlacedHere(tile);
2190 if (ret.Failed()) return { ret, 0, TownID::Invalid() };
2191 }
2192
2193 static const uint8_t price_mult[][TSZ_RANDOM + 1] = {{ 15, 25, 40, 25 }, { 20, 35, 55, 35 }};
2194 /* multidimensional arrays have to have defined length of non-first dimension */
2195 static_assert(lengthof(price_mult[0]) == 4);
2196
2197 CommandCost cost(EXPENSES_OTHER, _price[PR_BUILD_TOWN]);
2198 uint8_t mult = price_mult[city][size];
2199
2200 cost.MultiplyCost(mult);
2201
2202 /* Create the town */
2203 TownID new_town = TownID::Invalid();
2204 if (flags.Test(DoCommandFlag::Execute)) {
2205 if (cost.GetCost() > GetAvailableMoneyForCommand()) {
2206 return { CommandCost(EXPENSES_OTHER), cost.GetCost(), TownID::Invalid() };
2207 }
2208
2209 Backup<bool> old_generating_world(_generating_world, true);
2211 Town *t;
2212 if (random_location) {
2213 t = CreateRandomTown(20, townnameparts, size, city, layout);
2214 } else {
2215 t = new Town(tile);
2216 DoCreateTown(t, tile, townnameparts, size, city, layout, true);
2217 }
2218
2220 old_generating_world.Restore();
2221
2222 if (t == nullptr) return { CommandCost(STR_ERROR_NO_SPACE_FOR_TOWN), 0, TownID::Invalid() };
2223
2224 new_town = t->index;
2225
2226 if (!text.empty()) {
2227 t->name = text;
2228 t->UpdateVirtCoord();
2229 }
2230
2231 if (_game_mode != GM_EDITOR) {
2232 /* 't' can't be nullptr since 'random' is false outside scenedit */
2233 assert(!random_location);
2234
2236 AddTileNewsItem(GetEncodedString(STR_NEWS_NEW_TOWN_UNSPONSORED, t->index), NewsType::IndustryOpen, tile);
2237 } else {
2238 std::string company_name = GetString(STR_COMPANY_NAME, _current_company);
2239 AddTileNewsItem(GetEncodedString(STR_NEWS_NEW_TOWN, company_name, t->index), NewsType::IndustryOpen, tile);
2240 }
2241 AI::BroadcastNewEvent(new ScriptEventTownFounded(t->index));
2242 Game::NewEvent(new ScriptEventTownFounded(t->index));
2243 }
2244 }
2245 return { cost, 0, new_town };
2246}
2247
2258{
2259 switch (layout) {
2260 case TL_2X2_GRID: return TileXY(TileX(tile) - TileX(tile) % 3, TileY(tile) - TileY(tile) % 3);
2261 case TL_3X3_GRID: return TileXY(TileX(tile) & ~3, TileY(tile) & ~3);
2262 default: return tile;
2263 }
2264}
2265
2276{
2277 switch (layout) {
2278 case TL_2X2_GRID: return TileX(tile) % 3 == 0 && TileY(tile) % 3 == 0;
2279 case TL_3X3_GRID: return TileX(tile) % 4 == 0 && TileY(tile) % 4 == 0;
2280 default: return true;
2281 }
2282}
2283
2297{
2298 for (auto coast : SpiralTileSequence(tile, 40)) {
2299 /* Find nearest land tile */
2300 if (!IsTileType(tile, MP_CLEAR)) continue;
2301
2302 TileIndex furthest = INVALID_TILE;
2303 uint max_dist = 0;
2304 for (auto test : SpiralTileSequence(coast, 10)) {
2305 if (!IsTileType(test, MP_CLEAR) || !IsTileFlat(test) || !IsTileAlignedToGrid(test, layout)) continue;
2306
2307 uint dist = GetClosestWaterDistance(test, true);
2308 if (dist > max_dist) {
2309 furthest = test;
2310 max_dist = dist;
2311 }
2312 }
2313 return furthest;
2314 }
2315
2316 /* if we get here just give up */
2317 return INVALID_TILE;
2318}
2319
2325{
2327 case LandscapeType::Temperate: return HouseZone::ClimateTemperate;
2329 case LandscapeType::Tropic: return HouseZone::ClimateSubtropic;
2330 case LandscapeType::Toyland: return HouseZone::ClimateToyland;
2331 default: NOT_REACHED();
2332 }
2333}
2334
2344static Town *CreateRandomTown(uint attempts, uint32_t townnameparts, TownSize size, bool city, TownLayout layout)
2345{
2346 assert(_game_mode == GM_EDITOR || _generating_world); // These are the preconditions for CMD_DELETE_TOWN
2347
2348 if (!Town::CanAllocateItem()) return nullptr;
2349
2350 do {
2351 /* Generate a tile index not too close from the edge */
2352 TileIndex tile = AlignTileToGrid(RandomTile(), layout);
2353
2354 /* if we tried to place the town on water, slide it over onto
2355 * the nearest likely-looking spot */
2356 if (IsTileType(tile, MP_WATER)) {
2357 tile = FindNearestGoodCoastalTownSpot(tile, layout);
2358 if (tile == INVALID_TILE) continue;
2359 }
2360
2361 /* Make sure town can be placed here */
2362 if (TownCanBePlacedHere(tile).Failed()) continue;
2363
2364 /* Allocate a town struct */
2365 Town *t = new Town(tile);
2366
2367 DoCreateTown(t, tile, townnameparts, size, city, layout, false);
2368
2369 /* if the population is still 0 at the point, then the
2370 * placement is so bad it couldn't grow at all */
2371 if (t->cache.population > 0) return t;
2372
2375 cur_company.Restore();
2376 assert(rc.Succeeded());
2377
2378 /* We already know that we can allocate a single town when
2379 * entering this function. However, we create and delete
2380 * a town which "resets" the allocation checks. As such we
2381 * need to check again when assertions are enabled. */
2382 assert(Town::CanAllocateItem());
2383 } while (--attempts != 0);
2384
2385 return nullptr;
2386}
2387
2394{
2395 static const uint8_t num_initial_towns[4] = {5, 11, 23, 46}; // very low, low, normal, high
2398 }
2399 return Map::ScaleBySize(num_initial_towns[_settings_game.difficulty.number_towns]);
2400}
2401
2409bool GenerateTowns(TownLayout layout, std::optional<uint> number)
2410{
2411 uint current_number = 0;
2412 uint total;
2413 if (number.has_value()) {
2414 total = number.value();
2415 } else if (_settings_game.difficulty.number_towns == static_cast<uint>(CUSTOM_TOWN_NUMBER_DIFFICULTY)) {
2416 total = GetDefaultTownsForMapSize();
2417 } else {
2418 total = GetDefaultTownsForMapSize() + (Random() & 7);
2419 }
2420
2421 total = std::min<uint>(TownPool::MAX_SIZE, total);
2422 uint32_t townnameparts;
2423 TownNames town_names;
2424
2426
2427 /* Pre-populate the town names list with the names of any towns already on the map */
2428 for (const Town *town : Town::Iterate()) {
2429 town_names.insert(town->GetCachedName());
2430 }
2431
2432 /* Randomised offset for city status. This means with e.g. 1-in-4 towns being cities, a map with 10 towns
2433 * may have 2 or 3 cities, instead of always 3. */
2434 uint city_random_offset = _settings_game.economy.larger_towns == 0 ? 0 : (Random() % _settings_game.economy.larger_towns);
2435
2436 /* First attempt will be made at creating the suggested number of towns.
2437 * Note that this is really a suggested value, not a required one.
2438 * We would not like the system to lock up just because the user wanted 100 cities on a 64*64 map, would we? */
2439 do {
2440 bool city = (_settings_game.economy.larger_towns != 0 && ((city_random_offset + current_number) % _settings_game.economy.larger_towns) == 0);
2442 /* Get a unique name for the town. */
2443 if (!GenerateTownName(_random, &townnameparts, &town_names)) continue;
2444 /* try 20 times to create a random-sized town for the first loop. */
2445 if (CreateRandomTown(20, townnameparts, TSZ_RANDOM, city, layout) != nullptr) current_number++; // If creation was successful, raise a flag.
2446 } while (--total);
2447
2448 town_names.clear();
2449
2450 /* Build the town k-d tree again to make sure it's well balanced */
2451 RebuildTownKdtree();
2452
2453 if (current_number != 0) return true;
2454
2455 /* If current_number is still zero at this point, it means that not a single town has been created.
2456 * So give it a last try, but now more aggressive */
2457 if (GenerateTownName(_random, &townnameparts) &&
2458 CreateRandomTown(10000, townnameparts, TSZ_RANDOM, _settings_game.economy.larger_towns != 0, layout) != nullptr) {
2459 return true;
2460 }
2461
2462 /* If there are no towns at all and we are generating new game, bail out */
2463 if (Town::GetNumItems() == 0 && _game_mode != GM_EDITOR) {
2464 ShowErrorMessage(GetEncodedString(STR_ERROR_COULD_NOT_CREATE_TOWN), {}, WL_CRITICAL);
2465 }
2466
2467 return false; // we are still without a town? we failed, simply
2468}
2469
2470
2478{
2479 uint dist = DistanceSquare(tile, t->xy);
2480
2481 if (t->fund_buildings_months != 0 && dist <= 25) return HouseZone::TownCentre;
2482
2483 HouseZone smallest = HouseZone::TownEdge;
2484 for (HouseZone i : HZ_ZONE_ALL) {
2485 if (dist < t->cache.squared_town_zone_radius[to_underlying(i)]) smallest = i;
2486 }
2487
2488 return smallest;
2489}
2490
2502static inline void ClearMakeHouseTile(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool is_protected)
2503{
2505 assert(cc.Succeeded());
2506
2507 IncreaseBuildingCount(t, type);
2508 MakeHouseTile(tile, t->index, counter, stage, type, random_bits, is_protected);
2509 if (HouseSpec::Get(type)->building_flags.Test(BuildingFlag::IsAnimated)) AddAnimatedTile(tile, false);
2510
2511 MarkTileDirtyByTile(tile);
2512}
2513
2514
2526static void MakeTownHouse(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool is_protected)
2527{
2529
2530 ClearMakeHouseTile(tile, t, counter, stage, type, random_bits, is_protected);
2531 if (size.Any(BUILDING_2_TILES_Y)) ClearMakeHouseTile(tile + TileDiffXY(0, 1), t, counter, stage, ++type, random_bits, is_protected);
2532 if (size.Any(BUILDING_2_TILES_X)) ClearMakeHouseTile(tile + TileDiffXY(1, 0), t, counter, stage, ++type, random_bits, is_protected);
2533 if (size.Any(BUILDING_HAS_4_TILES)) ClearMakeHouseTile(tile + TileDiffXY(1, 1), t, counter, stage, ++type, random_bits, is_protected);
2534
2535 ForAllStationsAroundTiles(TileArea(tile, size.Any(BUILDING_2_TILES_X) ? 2 : 1, size.Any(BUILDING_2_TILES_Y) ? 2 : 1), [t](Station *st, TileIndex) {
2536 t->stations_near.insert(st);
2537 return true;
2538 });
2539}
2540
2541
2548static inline bool CanBuildHouseHere(TileIndex tile, bool noslope)
2549{
2550 /* cannot build on these slopes... */
2551 Slope slope = GetTileSlope(tile);
2552 if ((noslope && slope != SLOPE_FLAT) || IsSteepSlope(slope)) return false;
2553
2554 /* at least one RoadTypes allow building the house here? */
2555 if (!RoadTypesAllowHouseHere(tile)) return false;
2556
2557 /* building under a bridge? */
2558 if (IsBridgeAbove(tile)) return false;
2559
2560 /* can we clear the land? */
2562}
2563
2564
2573static inline bool CheckBuildHouseSameZ(TileIndex tile, int z, bool noslope)
2574{
2575 if (!CanBuildHouseHere(tile, noslope)) return false;
2576
2577 /* if building on slopes is allowed, there will be flattening foundation (to tile max z) */
2578 if (GetTileMaxZ(tile) != z) return false;
2579
2580 return true;
2581}
2582
2583
2592static bool CheckFree2x2Area(TileIndex tile, int z, bool noslope)
2593{
2594 /* we need to check this tile too because we can be at different tile now */
2595 if (!CheckBuildHouseSameZ(tile, z, noslope)) return false;
2596
2597 for (DiagDirection d = DIAGDIR_SE; d < DIAGDIR_END; d++) {
2598 tile += TileOffsByDiagDir(d);
2599 if (!CheckBuildHouseSameZ(tile, z, noslope)) return false;
2600 }
2601
2602 return true;
2603}
2604
2605
2613static inline bool TownLayoutAllowsHouseHere(Town *t, TileIndex tile, TownExpandModes modes)
2614{
2615 if (!modes.Test(TownExpandMode::Buildings)) return false;
2616
2617 /* Allow towns everywhere when we don't build roads */
2618 if (!TownAllowedToBuildRoads(modes)) return true;
2619
2620 TileIndexDiffC grid_pos = TileIndexToTileIndexDiffC(t->xy, tile);
2621
2622 switch (t->layout) {
2623 case TL_2X2_GRID:
2624 if ((grid_pos.x % 3) == 0 || (grid_pos.y % 3) == 0) return false;
2625 break;
2626
2627 case TL_3X3_GRID:
2628 if ((grid_pos.x % 4) == 0 || (grid_pos.y % 4) == 0) return false;
2629 break;
2630
2631 default:
2632 break;
2633 }
2634
2635 return true;
2636}
2637
2638
2647{
2648 if (!modes.Test(TownExpandMode::Buildings)) return false;
2649
2650 /* Allow towns everywhere when we don't build roads */
2651 if (!TownAllowedToBuildRoads(modes)) 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, TownExpandModes modes)
2686{
2687 /* 'tile' is already checked in BuildTownHouse() - CanBuildHouseHere() and slope test */
2688
2689 TileIndex tile2 = *tile + TileOffsByDiagDir(second);
2690 if (TownLayoutAllowsHouseHere(t, tile2, modes) && CheckBuildHouseSameZ(tile2, maxz, noslope)) return true;
2691
2692 tile2 = *tile + TileOffsByDiagDir(ReverseDiagDir(second));
2693 if (TownLayoutAllowsHouseHere(t, tile2, modes) && 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, TownExpandModes modes)
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, modes) && 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 BuildingFlags size = hs->building_flags;
2762
2763 TriggerHouseAnimation_ConstructionStageChanged(tile, true);
2764 if (size.Any(BUILDING_2_TILES_Y)) TriggerHouseAnimation_ConstructionStageChanged(tile + TileDiffXY(0, 1), true);
2765 if (size.Any(BUILDING_2_TILES_X)) TriggerHouseAnimation_ConstructionStageChanged(tile + TileDiffXY(1, 0), true);
2766 if (size.Any(BUILDING_HAS_4_TILES)) TriggerHouseAnimation_ConstructionStageChanged(tile + TileDiffXY(1, 1), true);
2767}
2768
2776{
2777 /* forbidden building here by town layout */
2778 if (!TownLayoutAllowsHouseHere(t, tile, modes)) return false;
2779
2780 /* no house allowed at all, bail out */
2781 if (!CanBuildHouseHere(tile, false)) return false;
2782
2783 Slope slope = GetTileSlope(tile);
2784 int maxz = GetTileMaxZ(tile);
2785
2786 /* Get the town zone type of the current tile, as well as the climate.
2787 * This will allow to easily compare with the specs of the new house to build */
2788 HouseZones zones = GetTownRadiusGroup(t, tile);
2789
2791 case LandscapeType::Temperate: zones.Set(HouseZone::ClimateTemperate); break;
2792 case LandscapeType::Arctic: zones.Set(maxz > HighestSnowLine() ? HouseZone::ClimateSubarcticAboveSnow : HouseZone::ClimateSubarcticBelowSnow); break;
2793 case LandscapeType::Tropic: zones.Set(HouseZone::ClimateSubtropic); break;
2794 case LandscapeType::Toyland: zones.Set(HouseZone::ClimateToyland); break;
2795 }
2796
2797 /* bits 0-4 are used
2798 * bits 11-15 are used
2799 * bits 5-10 are not used. */
2800 static std::vector<std::pair<HouseID, uint>> probs;
2801 probs.clear();
2802
2803 uint probability_max = 0;
2804
2805 /* Generate a list of all possible houses that can be built. */
2806 for (const auto &hs : HouseSpec::Specs()) {
2807 /* Verify that the candidate house spec matches the current tile status */
2808 if (!hs.building_availability.All(zones) || !hs.enabled || hs.grf_prop.override_id != INVALID_HOUSE_ID) continue;
2809
2810 /* Don't let these counters overflow. Global counters are 32bit, there will never be that many houses. */
2811 if (hs.class_id != HOUSE_NO_CLASS) {
2812 /* id_count is always <= class_count, so it doesn't need to be checked */
2813 if (t->cache.building_counts.class_count[hs.class_id] == UINT16_MAX) continue;
2814 } else {
2815 /* If the house has no class, check id_count instead */
2816 if (t->cache.building_counts.id_count[hs.Index()] == UINT16_MAX) continue;
2817 }
2818
2819 uint cur_prob = hs.probability;
2820 probability_max += cur_prob;
2821 probs.emplace_back(hs.Index(), cur_prob);
2822 }
2823
2824 TileIndex base_tile = tile;
2825
2826 while (probability_max > 0) {
2827 /* Building a multitile building can change the location of tile.
2828 * The building would still be built partially on that tile, but
2829 * its northern tile would be elsewhere. However, if the callback
2830 * fails we would be basing further work from the changed tile.
2831 * So a next 1x1 tile building could be built on the wrong tile. */
2832 tile = base_tile;
2833
2834 uint r = RandomRange(probability_max);
2835 uint i;
2836 for (i = 0; i < probs.size(); i++) {
2837 if (probs[i].second > r) break;
2838 r -= probs[i].second;
2839 }
2840
2841 HouseID house = probs[i].first;
2842 probability_max -= probs[i].second;
2843
2844 /* remove tested house from the set */
2845 probs[i] = probs.back();
2846 probs.pop_back();
2847
2848 const HouseSpec *hs = HouseSpec::Get(house);
2849
2850 if (!_generating_world && _game_mode != GM_EDITOR && hs->extra_flags.Test(HouseExtraFlag::BuildingIsHistorical)) {
2851 continue;
2852 }
2853
2854 if (TimerGameCalendar::year < hs->min_year || TimerGameCalendar::year > hs->max_year) continue;
2855
2856 /* Special houses that there can be only one of. */
2857 uint oneof = 0;
2858
2859 if (hs->building_flags.Test(BuildingFlag::IsChurch)) {
2860 SetBit(oneof, TOWN_HAS_CHURCH);
2861 } else if (hs->building_flags.Test(BuildingFlag::IsStadium)) {
2862 SetBit(oneof, TOWN_HAS_STADIUM);
2863 }
2864
2865 if (t->flags & oneof) continue;
2866
2867 /* Make sure there is no slope? */
2868 bool noslope = hs->building_flags.Test(BuildingFlag::NotSloped);
2869 if (noslope && slope != SLOPE_FLAT) continue;
2870
2871 if (hs->building_flags.Test(BuildingFlag::Size2x2)) {
2872 if (!CheckTownBuild2x2House(&tile, t, maxz, noslope, modes)) continue;
2873 } else if (hs->building_flags.Test(BuildingFlag::Size2x1)) {
2874 if (!CheckTownBuild2House(&tile, t, maxz, noslope, DIAGDIR_SW, modes)) continue;
2875 } else if (hs->building_flags.Test(BuildingFlag::Size1x2)) {
2876 if (!CheckTownBuild2House(&tile, t, maxz, noslope, DIAGDIR_SE, modes)) continue;
2877 } else {
2878 /* 1x1 house checks are already done */
2879 }
2880
2881 uint8_t random_bits = Random();
2882
2884 uint16_t callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile, {}, true, random_bits);
2885 if (callback_res != CALLBACK_FAILED && !Convert8bitBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_ALLOW_CONSTRUCTION, callback_res)) continue;
2886 }
2887
2888 /* Special houses that there can be only one of. */
2889 t->flags |= oneof;
2890
2891 BuildTownHouse(t, tile, hs, house, random_bits, false, hs->extra_flags.Test(HouseExtraFlag::BuildingIsProtected));
2892
2893 return true;
2894 }
2895
2896 return false;
2897}
2898
2907CommandCost CmdPlaceHouse(DoCommandFlags flags, TileIndex tile, HouseID house, bool is_protected)
2908{
2909 if (_game_mode != GM_EDITOR && _settings_game.economy.place_houses == PH_FORBIDDEN) return CMD_ERROR;
2910
2911 if (Town::GetNumItems() == 0) return CommandCost(STR_ERROR_MUST_FOUND_TOWN_FIRST);
2912
2913 if (static_cast<size_t>(house) >= HouseSpec::Specs().size()) return CMD_ERROR;
2914 const HouseSpec *hs = HouseSpec::Get(house);
2915 if (!hs->enabled) return CMD_ERROR;
2916
2917 Town *t = ClosestTownFromTile(tile, UINT_MAX);
2918
2919 /* cannot build on these slopes... */
2920 Slope slope = GetTileSlope(tile);
2921 if (IsSteepSlope(slope)) return CommandCost(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
2922
2923 /* building under a bridge? */
2924 if (IsBridgeAbove(tile)) return CommandCost(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
2925
2926 /* can we clear the land? */
2928 if (!cost.Succeeded()) return cost;
2929
2930 int maxz = GetTileMaxZ(tile);
2931
2932 /* Make sure there is no slope? */
2933 bool noslope = hs->building_flags.Test(BuildingFlag::NotSloped);
2934 if (noslope && slope != SLOPE_FLAT) return CommandCost(STR_ERROR_FLAT_LAND_REQUIRED);
2935
2936 TileArea ta = tile;
2937 if (hs->building_flags.Test(BuildingFlag::Size2x2)) ta.Add(TileAddXY(tile, 1, 1));
2938 if (hs->building_flags.Test(BuildingFlag::Size2x1)) ta.Add(TileAddByDiagDir(tile, DIAGDIR_SW));
2939 if (hs->building_flags.Test(BuildingFlag::Size1x2)) ta.Add(TileAddByDiagDir(tile, DIAGDIR_SE));
2940
2941 /* Check additional tiles covered by this house. */
2942 for (const TileIndex &subtile : ta) {
2944 if (!cost.Succeeded()) return cost;
2945
2946 if (!CheckBuildHouseSameZ(subtile, maxz, noslope)) return CommandCost(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
2947 }
2948
2949 if (flags.Test(DoCommandFlag::Execute)) {
2950 bool house_completed = _settings_game.economy.place_houses == PH_ALLOWED_CONSTRUCTED;
2951 BuildTownHouse(t, tile, hs, house, Random(), house_completed, is_protected);
2952 }
2953
2954 return CommandCost();
2955}
2956
2963static void DoClearTownHouseHelper(TileIndex tile, Town *t, HouseID house)
2964{
2965 assert(IsTileType(tile, MP_HOUSE));
2966 DecreaseBuildingCount(t, house);
2967 DoClearSquare(tile);
2968
2969 DeleteNewGRFInspectWindow(GSF_HOUSES, tile.base());
2970}
2971
2980{
2981 if (house >= 3) { // house id 0,1,2 MUST be single tile houses, or this code breaks.
2982 if (HouseSpec::Get(house - 1)->building_flags.Test(BuildingFlag::Size2x1)) {
2983 house--;
2984 return TileDiffXY(-1, 0);
2985 } else if (HouseSpec::Get(house - 1)->building_flags.Any(BUILDING_2_TILES_Y)) {
2986 house--;
2987 return TileDiffXY(0, -1);
2988 } else if (HouseSpec::Get(house - 2)->building_flags.Any(BUILDING_HAS_4_TILES)) {
2989 house -= 2;
2990 return TileDiffXY(-1, 0);
2991 } else if (HouseSpec::Get(house - 3)->building_flags.Any(BUILDING_HAS_4_TILES)) {
2992 house -= 3;
2993 return TileDiffXY(-1, -1);
2994 }
2995 }
2996 return TileDiffXY(0, 0);
2997}
2998
3005{
3006 assert(IsTileType(tile, MP_HOUSE));
3007
3008 HouseID house = GetHouseType(tile);
3009
3010 /* The northernmost tile of the house is the main house. */
3011 tile += GetHouseNorthPart(house);
3012
3013 const HouseSpec *hs = HouseSpec::Get(house);
3014
3015 /* Remove population from the town if the house is finished. */
3016 if (IsHouseCompleted(tile)) {
3018 }
3019
3020 t->cache.num_houses--;
3021
3022 /* Clear flags for houses that only may exist once/town. */
3023 if (hs->building_flags.Test(BuildingFlag::IsChurch)) {
3025 } else if (hs->building_flags.Test(BuildingFlag::IsStadium)) {
3027 }
3028
3029 /* Do the actual clearing of tiles */
3030 DoClearTownHouseHelper(tile, t, house);
3031 if (hs->building_flags.Any(BUILDING_2_TILES_Y)) DoClearTownHouseHelper(tile + TileDiffXY(0, 1), t, ++house);
3032 if (hs->building_flags.Any(BUILDING_2_TILES_X)) DoClearTownHouseHelper(tile + TileDiffXY(1, 0), t, ++house);
3033 if (hs->building_flags.Any(BUILDING_HAS_4_TILES)) DoClearTownHouseHelper(tile + TileDiffXY(1, 1), t, ++house);
3034
3036
3038}
3039
3047CommandCost CmdRenameTown(DoCommandFlags flags, TownID town_id, const std::string &text)
3048{
3049 Town *t = Town::GetIfValid(town_id);
3050 if (t == nullptr) return CMD_ERROR;
3051
3052 bool reset = text.empty();
3053
3054 if (!reset) {
3056 if (!IsUniqueTownName(text)) return CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE);
3057 }
3058
3059 if (flags.Test(DoCommandFlag::Execute)) {
3060 t->cached_name.clear();
3061 if (reset) {
3062 t->name.clear();
3063 } else {
3064 t->name = text;
3065 }
3066
3067 t->UpdateVirtCoord();
3068 InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_RESORT);
3069 ClearAllStationCachedNames();
3070 ClearAllIndustryCachedNames();
3072 }
3073 return CommandCost();
3074}
3075
3082{
3083 for (const CargoSpec *cs : CargoSpec::Iterate()) {
3084 if (cs->town_acceptance_effect == effect) return cs;
3085 }
3086 return nullptr;
3087}
3088
3098{
3099 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3100
3101 if (tae < TAE_BEGIN || tae >= TAE_END) return CMD_ERROR;
3102
3103 Town *t = Town::GetIfValid(town_id);
3104 if (t == nullptr) return CMD_ERROR;
3105
3106 /* Validate if there is a cargo which is the requested TownEffect */
3108 if (cargo == nullptr) return CMD_ERROR;
3109
3110 if (flags.Test(DoCommandFlag::Execute)) {
3111 t->goal[tae] = goal;
3114 }
3115
3116 return CommandCost();
3117}
3118
3127{
3128 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3129 Town *t = Town::GetIfValid(town_id);
3130 if (t == nullptr) return CMD_ERROR;
3131
3132 if (flags.Test(DoCommandFlag::Execute)) {
3133 t->text.clear();
3134 if (!text.empty()) t->text = text;
3136 }
3137
3138 return CommandCost();
3139}
3140
3148CommandCost CmdTownGrowthRate(DoCommandFlags flags, TownID town_id, uint16_t growth_rate)
3149{
3150 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3151
3152 Town *t = Town::GetIfValid(town_id);
3153 if (t == nullptr) return CMD_ERROR;
3154
3155 if (flags.Test(DoCommandFlag::Execute)) {
3156 if (growth_rate == 0) {
3157 /* Just clear the flag, UpdateTownGrowth will determine a proper growth rate */
3159 } else {
3160 uint old_rate = t->growth_rate;
3161 if (t->grow_counter >= old_rate) {
3162 /* This also catches old_rate == 0 */
3163 t->grow_counter = growth_rate;
3164 } else {
3165 /* Scale grow_counter, so half finished houses stay half finished */
3166 t->grow_counter = t->grow_counter * growth_rate / old_rate;
3167 }
3168 t->growth_rate = growth_rate;
3170 }
3173 }
3174
3175 return CommandCost();
3176}
3177
3186CommandCost CmdTownRating(DoCommandFlags flags, TownID town_id, CompanyID company_id, int16_t rating)
3187{
3188 if (_current_company != OWNER_DEITY) return CMD_ERROR;
3189
3190 Town *t = Town::GetIfValid(town_id);
3191 if (t == nullptr) return CMD_ERROR;
3192
3193 if (!Company::IsValidID(company_id)) return CMD_ERROR;
3194
3195 int16_t new_rating = Clamp(rating, RATING_MINIMUM, RATING_MAXIMUM);
3196 if (flags.Test(DoCommandFlag::Execute)) {
3197 t->ratings[company_id] = new_rating;
3199 }
3200
3201 return CommandCost();
3202}
3203
3211CommandCost CmdExpandTown(DoCommandFlags flags, TownID town_id, uint32_t grow_amount, TownExpandModes modes)
3212{
3213 if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY) return CMD_ERROR;
3214 if (modes.None()) return CMD_ERROR;
3215 Town *t = Town::GetIfValid(town_id);
3216 if (t == nullptr) return CMD_ERROR;
3217
3218 if (flags.Test(DoCommandFlag::Execute)) {
3219 /* The more houses, the faster we grow */
3220 if (grow_amount == 0) {
3221 uint amount = RandomRange(ClampTo<uint16_t>(t->cache.num_houses / 10)) + 3;
3222 t->cache.num_houses += amount;
3224
3225 uint n = amount * 10;
3226 do GrowTown(t, modes); while (--n);
3227
3228 t->cache.num_houses -= amount;
3229 } else {
3230 for (; grow_amount > 0; grow_amount--) {
3231 /* Try several times to grow, as we are really suppose to grow */
3232 for (uint i = 0; i < 25; i++) if (GrowTown(t, modes)) break;
3233 }
3234 }
3236
3238 }
3239
3240 return CommandCost();
3241}
3242
3250{
3251 if (_game_mode != GM_EDITOR && !_generating_world) return CMD_ERROR;
3252 Town *t = Town::GetIfValid(town_id);
3253 if (t == nullptr) return CMD_ERROR;
3254
3255 /* Stations refer to towns. */
3256 for (const Station *st : Station::Iterate()) {
3257 if (st->town == t) {
3258 /* Non-oil rig stations are always a problem. */
3259 if (!st->facilities.Test(StationFacility::Airport) || st->airport.type != AT_OILRIG) return CMD_ERROR;
3260 /* We can only automatically delete oil rigs *if* there's no vehicle on them. */
3261 CommandCost ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, st->airport.tile);
3262 if (ret.Failed()) return ret;
3263 }
3264 }
3265
3266 /* Waypoints refer to towns. */
3267 for (const Waypoint *wp : Waypoint::Iterate()) {
3268 if (wp->town == t) return CMD_ERROR;
3269 }
3270
3271 /* Depots refer to towns. */
3272 for (const Depot *d : Depot::Iterate()) {
3273 if (d->town == t) return CMD_ERROR;
3274 }
3275
3276 /* Check all tiles for town ownership. First check for bridge tiles, as
3277 * these do not directly have an owner so we need to check adjacent
3278 * tiles. This won't work correctly in the same loop if the adjacent
3279 * tile was already deleted earlier in the loop. */
3280 for (const auto current_tile : Map::Iterate()) {
3281 if (IsTileType(current_tile, MP_TUNNELBRIDGE) && TestTownOwnsBridge(current_tile, t)) {
3282 CommandCost ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, current_tile);
3283 if (ret.Failed()) return ret;
3284 }
3285 }
3286
3287 /* Check all remaining tiles for town ownership. */
3288 for (const auto current_tile : Map::Iterate()) {
3289 bool try_clear = false;
3290 switch (GetTileType(current_tile)) {
3291 case MP_ROAD:
3292 try_clear = HasTownOwnedRoad(current_tile) && GetTownIndex(current_tile) == t->index;
3293 break;
3294
3295 case MP_HOUSE:
3296 try_clear = GetTownIndex(current_tile) == t->index;
3297 break;
3298
3299 case MP_INDUSTRY:
3300 try_clear = Industry::GetByTile(current_tile)->town == t;
3301 break;
3302
3303 case MP_OBJECT:
3304 if (Town::GetNumItems() == 1) {
3305 /* No towns will be left, remove it! */
3306 try_clear = true;
3307 } else {
3308 Object *o = Object::GetByTile(current_tile);
3309 if (o->town == t) {
3310 if (o->type == OBJECT_STATUE) {
3311 /* Statue... always remove. */
3312 try_clear = true;
3313 } else {
3314 /* Tell to find a new town. */
3315 if (flags.Test(DoCommandFlag::Execute)) o->town = nullptr;
3316 }
3317 }
3318 }
3319 break;
3320
3321 default:
3322 break;
3323 }
3324 if (try_clear) {
3325 CommandCost ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, current_tile);
3326 if (ret.Failed()) return ret;
3327 }
3328 }
3329
3330 /* The town destructor will delete the other things related to the town. */
3331 if (flags.Test(DoCommandFlag::Execute)) {
3332 _town_kdtree.Remove(t->index);
3333 if (t->cache.sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeTown(t->index));
3334 delete t;
3335 }
3336
3337 return CommandCost();
3338}
3339
3346{
3351 static const uint8_t town_action_costs[] = {
3352 2, 4, 9, 35, 48, 53, 117, 175
3353 };
3354 static_assert(std::size(town_action_costs) == to_underlying(TownAction::End));
3355
3356 assert(to_underlying(action) < std::size(town_action_costs));
3357 return town_action_costs[to_underlying(action)];
3358}
3359
3367{
3368 if (flags.Test(DoCommandFlag::Execute)) {
3369 ModifyStationRatingAround(t->xy, _current_company, 0x40, 10);
3370 }
3371 return CommandCost();
3372}
3373
3381{
3382 if (flags.Test(DoCommandFlag::Execute)) {
3383 ModifyStationRatingAround(t->xy, _current_company, 0x70, 15);
3384 }
3385 return CommandCost();
3386}
3387
3395{
3396 if (flags.Test(DoCommandFlag::Execute)) {
3397 ModifyStationRatingAround(t->xy, _current_company, 0xA0, 20);
3398 }
3399 return CommandCost();
3400}
3401
3409{
3410 /* Check if the company is allowed to fund new roads. */
3412
3413 if (flags.Test(DoCommandFlag::Execute)) {
3414 t->road_build_months = 6;
3415
3416 std::string company_name = GetString(STR_COMPANY_NAME, _current_company);
3417
3419 GetEncodedString(TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_ROAD_REBUILDING_MINUTES : STR_NEWS_ROAD_REBUILDING_MONTHS, t->index, company_name),
3421 AI::BroadcastNewEvent(new ScriptEventRoadReconstruction(_current_company, t->index));
3422 Game::NewEvent(new ScriptEventRoadReconstruction(_current_company, t->index));
3423 }
3424 return CommandCost();
3425}
3426
3432static bool CheckClearTile(TileIndex tile)
3433{
3436 cur_company.Restore();
3437 return r.Succeeded();
3438}
3439
3448{
3449 if (!Object::CanAllocateItem()) return CommandCost(STR_ERROR_TOO_MANY_OBJECTS);
3450
3451 static const int STATUE_NUMBER_INNER_TILES = 25; // Number of tiles int the center of the city, where we try to protect houses.
3452
3453 TileIndex best_position = INVALID_TILE;
3454 uint tile_count = 0;
3455 for (auto tile : SpiralTileSequence(t->xy, 9)) {
3456 tile_count++;
3457
3458 /* Statues can be build on slopes, just like houses. Only the steep slopes is a no go. */
3459 if (IsSteepSlope(GetTileSlope(tile))) continue;
3460 /* Don't build statues under bridges. */
3461 if (IsBridgeAbove(tile)) continue;
3462
3463 /* A clear-able open space is always preferred. */
3464 if ((IsTileType(tile, MP_CLEAR) || IsTileType(tile, MP_TREES)) && CheckClearTile(tile)) {
3465 best_position = tile;
3466 break;
3467 }
3468
3469 bool house = IsTileType(tile, MP_HOUSE);
3470
3471 /* Searching inside the inner circle. */
3472 if (tile_count <= STATUE_NUMBER_INNER_TILES) {
3473 /* Save first house in inner circle. */
3474 if (house && best_position == INVALID_TILE && CheckClearTile(tile)) {
3475 best_position = tile;
3476 }
3477
3478 /* If we have reached the end of the inner circle, and have a saved house, terminate the search. */
3479 if (tile_count == STATUE_NUMBER_INNER_TILES && best_position != INVALID_TILE) break;
3480 }
3481
3482 /* Searching outside the circle, just pick the first possible spot. */
3483 if (!house || !CheckClearTile(tile)) continue;
3484 best_position = tile;
3485 break;
3486 }
3487 if (best_position == INVALID_TILE) return CommandCost(STR_ERROR_STATUE_NO_SUITABLE_PLACE);
3488
3489 if (flags.Test(DoCommandFlag::Execute)) {
3492 cur_company.Restore();
3493 BuildObject(OBJECT_STATUE, best_position, _current_company, t);
3494 t->statues.Set(_current_company); // Once found and built, "inform" the Town.
3495 MarkTileDirtyByTile(best_position);
3496 }
3497 return CommandCost();
3498}
3499
3507{
3508 /* Check if it's allowed to buy the rights */
3510
3511 if (flags.Test(DoCommandFlag::Execute)) {
3512 /* And grow for 3 months */
3513 t->fund_buildings_months = 3;
3514
3515 /* Enable growth (also checking GameScript's opinion) */
3517
3518 /* Build a new house, but add a small delay to make sure
3519 * that spamming funding doesn't let town grow any faster
3520 * than 1 house per 2 * TOWN_GROWTH_TICKS ticks.
3521 * Also emulate original behaviour when town was only growing in
3522 * TOWN_GROWTH_TICKS intervals, to make sure that it's not too
3523 * tick-perfect and gives player some time window where they can
3524 * spam funding with the exact same efficiency.
3525 */
3527
3529 }
3530 return CommandCost();
3531}
3532
3540{
3541 /* Check if it's allowed to buy the rights */
3543 if (t->exclusivity != CompanyID::Invalid()) return CMD_ERROR;
3544
3545 if (flags.Test(DoCommandFlag::Execute)) {
3546 t->exclusive_counter = 12;
3548
3549 ModifyStationRatingAround(t->xy, _current_company, 130, 17);
3550
3552
3553 /* Spawn news message */
3554 auto cni = std::make_unique<CompanyNewsInformation>(STR_NEWS_EXCLUSIVE_RIGHTS_TITLE, Company::Get(_current_company));
3555 EncodedString message = GetEncodedString(TimerGameEconomy::UsingWallclockUnits() ? STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MINUTES : STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION_MONTHS, t->index, cni->company_name);
3556 AddNewsItem(std::move(message),
3557 NewsType::General, NewsStyle::Company, {}, t->index, {}, std::move(cni));
3558 AI::BroadcastNewEvent(new ScriptEventExclusiveTransportRights(_current_company, t->index));
3559 Game::NewEvent(new ScriptEventExclusiveTransportRights(_current_company, t->index));
3560 }
3561 return CommandCost();
3562}
3563
3571{
3572 if (flags.Test(DoCommandFlag::Execute)) {
3573 if (Chance16(1, 14)) {
3574 /* set as unwanted for 6 months */
3575 t->unwanted[_current_company] = 6;
3576
3577 /* set all close by station ratings to 0 */
3578 for (Station *st : Station::Iterate()) {
3579 if (st->town == t && st->owner == _current_company) {
3580 for (GoodsEntry &ge : st->goods) ge.rating = 0;
3581 }
3582 }
3583
3584 /* only show error message to the executing player. All errors are handled command.c
3585 * but this is special, because it can only 'fail' on a DoCommandFlag::Execute */
3586 if (IsLocalCompany()) ShowErrorMessage(GetEncodedString(STR_ERROR_BRIBE_FAILED), {}, WL_INFO);
3587
3588 /* decrease by a lot!
3589 * ChangeTownRating is only for stuff in demolishing. Bribe failure should
3590 * be independent of any cheat settings
3591 */
3592 if (t->ratings[_current_company] > RATING_BRIBE_DOWN_TO) {
3593 t->ratings[_current_company] = RATING_BRIBE_DOWN_TO;
3595 }
3596 } else {
3597 ChangeTownRating(t, RATING_BRIBE_UP_STEP, RATING_BRIBE_MAXIMUM, DoCommandFlag::Execute);
3598 if (t->exclusivity != _current_company && t->exclusivity != CompanyID::Invalid()) {
3599 t->exclusivity = CompanyID::Invalid();
3600 t->exclusive_counter = 0;
3601 }
3602 }
3603 }
3604 return CommandCost();
3605}
3606
3607typedef CommandCost TownActionProc(Town *t, DoCommandFlags flags);
3608static TownActionProc * const _town_action_proc[] = {
3617};
3618static_assert(std::size(_town_action_proc) == to_underlying(TownAction::End));
3619
3627{
3628 TownActions buttons{};
3629
3630 /* Spectators and unwanted have no options */
3631 if (cid != COMPANY_SPECTATOR && !(_settings_game.economy.bribe && t->unwanted[cid])) {
3632
3633 /* Actions worth more than this are not able to be performed */
3634 Money avail = GetAvailableMoney(cid);
3635
3636 /* Check the action bits for validity and
3637 * if they are valid add them */
3638 for (TownAction cur = {}; cur != TownAction::End; ++cur) {
3639
3640 /* Is the company prohibited from bribing ? */
3641 if (cur == TownAction::Bribe) {
3642 /* Company can't bribe if setting is disabled */
3643 if (!_settings_game.economy.bribe) continue;
3644 /* Company can bribe if another company has exclusive transport rights,
3645 * or its standing with the town is less than outstanding. */
3646 if (t->ratings[cid] >= RATING_BRIBE_MAXIMUM) {
3647 if (t->exclusivity == _current_company) continue;
3648 if (t->exclusive_counter == 0) continue;
3649 }
3650 }
3651
3652 /* Is the company not able to buy exclusive rights ? */
3654
3655 /* Is the company not able to fund buildings ? */
3657
3658 /* Is the company not able to fund local road reconstruction? */
3660
3661 /* Is the company not able to build a statue ? */
3662 if (cur == TownAction::BuildStatue && t->statues.Test(cid)) continue;
3663
3664 if (avail >= GetTownActionCost(cur) * _price[PR_TOWN_ACTION] >> 8) {
3665 buttons.Set(cur);
3666 }
3667 }
3668 }
3669
3670 return buttons;
3671}
3672
3683{
3684 Town *t = Town::GetIfValid(town_id);
3685 if (t == nullptr || to_underlying(action) >= std::size(_town_action_proc)) return CMD_ERROR;
3686
3687 if (!GetMaskOfTownActions(_current_company, t).Test(action)) return CMD_ERROR;
3688
3689 CommandCost cost(EXPENSES_OTHER, _price[PR_TOWN_ACTION] * GetTownActionCost(action) >> 8);
3690
3691 CommandCost ret = _town_action_proc[to_underlying(action)](t, flags);
3692 if (ret.Failed()) return ret;
3693
3694 if (flags.Test(DoCommandFlag::Execute)) {
3696 }
3697
3698 return cost;
3699}
3700
3701template <typename Func>
3702static void ForAllStationsNearTown(Town *t, Func func)
3703{
3704 /* Ideally the search radius should be close to the actual town zone 0 radius.
3705 * The true radius is not stored or calculated anywhere, only the squared radius. */
3706 /* The efficiency of this search might be improved for large towns and many stations on the map,
3707 * by using an integer square root approximation giving a value not less than the true square root. */
3708 uint search_radius = t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownEdge)] / 2;
3709 ForAllStationsRadius(t->xy, search_radius, [&](const Station * st) {
3710 if (DistanceSquare(st->xy, t->xy) <= t->cache.squared_town_zone_radius[to_underlying(HouseZone::TownEdge)]) {
3711 func(st);
3712 }
3713 });
3714}
3715
3720static void UpdateTownRating(Town *t)
3721{
3722 /* Increase company ratings if they're low */
3723 for (const Company *c : Company::Iterate()) {
3724 if (t->ratings[c->index] < RATING_GROWTH_MAXIMUM) {
3725 t->ratings[c->index] = std::min((int)RATING_GROWTH_MAXIMUM, t->ratings[c->index] + RATING_GROWTH_UP_STEP);
3726 }
3727 }
3728
3729 ForAllStationsNearTown(t, [&](const Station *st) {
3730 if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
3731 if (Company::IsValidID(st->owner)) {
3732 int new_rating = t->ratings[st->owner] + RATING_STATION_UP_STEP;
3733 t->ratings[st->owner] = std::min<int>(new_rating, INT16_MAX); // do not let it overflow
3734 }
3735 } else {
3736 if (Company::IsValidID(st->owner)) {
3737 int new_rating = t->ratings[st->owner] + RATING_STATION_DOWN_STEP;
3738 t->ratings[st->owner] = std::max(new_rating, INT16_MIN);
3739 }
3740 }
3741 });
3742
3743 /* clamp all ratings to valid values */
3744 for (uint i = 0; i < MAX_COMPANIES; i++) {
3745 t->ratings[i] = Clamp(t->ratings[i], RATING_MINIMUM, RATING_MAXIMUM);
3746 }
3747
3749}
3750
3751
3758static void UpdateTownGrowCounter(Town *t, uint16_t prev_growth_rate)
3759{
3760 if (t->growth_rate == TOWN_GROWTH_RATE_NONE) return;
3761 if (prev_growth_rate == TOWN_GROWTH_RATE_NONE) {
3762 t->grow_counter = std::min<uint16_t>(t->growth_rate, t->grow_counter);
3763 return;
3764 }
3765 t->grow_counter = RoundDivSU((uint32_t)t->grow_counter * (t->growth_rate + 1), prev_growth_rate + 1);
3766}
3767
3774{
3775 int n = 0;
3776 ForAllStationsNearTown(t, [&](const Station * st) {
3777 if (st->time_since_load <= 20 || st->time_since_unload <= 20) {
3778 n++;
3779 }
3780 });
3781 return n;
3782}
3783
3791{
3797 static const uint16_t _grow_count_values[2][6] = {
3798 { 120, 120, 120, 100, 80, 60 }, // Fund new buildings has been activated
3799 { 320, 420, 300, 220, 160, 100 } // Normal values
3800 };
3801
3802 int n = CountActiveStations(t);
3803 uint16_t m = _grow_count_values[t->fund_buildings_months != 0 ? 0 : 1][std::min(n, 5)];
3804
3805 uint growth_multiplier = _settings_game.economy.town_growth_rate != 0 ? _settings_game.economy.town_growth_rate - 1 : 1;
3806
3807 m >>= growth_multiplier;
3808 if (t->larger_town) m /= 2;
3809
3810 return TownTicksToGameTicks(m / (t->cache.num_houses / 50 + 1));
3811}
3812
3818{
3819 if (HasBit(t->flags, TOWN_CUSTOM_GROWTH)) return;
3820 uint old_rate = t->growth_rate;
3822 UpdateTownGrowCounter(t, old_rate);
3824}
3825
3830static void UpdateTownGrowth(Town *t)
3831{
3833
3836
3838
3839 if (t->fund_buildings_months == 0) {
3840 /* Check if all goals are reached for this town to grow (given we are not funding it) */
3841 for (int i = TAE_BEGIN; i < TAE_END; i++) {
3842 switch (t->goal[i]) {
3843 case TOWN_GROWTH_WINTER:
3844 if (TileHeight(t->xy) >= GetSnowLine() && t->received[i].old_act == 0 && t->cache.population > 90) return;
3845 break;
3846 case TOWN_GROWTH_DESERT:
3847 if (GetTropicZone(t->xy) == TROPICZONE_DESERT && t->received[i].old_act == 0 && t->cache.population > 60) return;
3848 break;
3849 default:
3850 if (t->goal[i] > t->received[i].old_act) return;
3851 break;
3852 }
3853 }
3854 }
3855
3856 if (HasBit(t->flags, TOWN_CUSTOM_GROWTH)) {
3859 return;
3860 }
3861
3862 if (t->fund_buildings_months == 0 && CountActiveStations(t) == 0 && !Chance16(1, 12)) return;
3863
3866}
3867
3875{
3876 /* The required rating is hardcoded to RATING_VERYPOOR (see below), not the authority attitude setting, so we can bail out like this. */
3877 if (_settings_game.difficulty.town_council_tolerance == TOWN_COUNCIL_PERMISSIVE) return CommandCost();
3878
3880
3882 if (t == nullptr) return CommandCost();
3883
3884 if (t->ratings[_current_company] > RATING_VERYPOOR) return CommandCost();
3885
3886 return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index);
3887}
3888
3898{
3899 if (Town::GetNumItems() == 0) return nullptr;
3900
3901 TownID tid = _town_kdtree.FindNearest(TileX(tile), TileY(tile));
3902 Town *town = Town::Get(tid);
3903 if (DistanceManhattan(tile, town->xy) < threshold) return town;
3904 return nullptr;
3905}
3906
3915Town *ClosestTownFromTile(TileIndex tile, uint threshold)
3916{
3917 switch (GetTileType(tile)) {
3918 case MP_ROAD:
3919 if (IsRoadDepot(tile)) return CalcClosestTownFromTile(tile, threshold);
3920
3921 if (!HasTownOwnedRoad(tile)) {
3922 TownID tid = GetTownIndex(tile);
3923
3924 if (tid == TownID::Invalid()) {
3925 /* in the case we are generating "many random towns", this value may be TownID::Invalid() */
3926 if (_generating_world) return CalcClosestTownFromTile(tile, threshold);
3927 assert(Town::GetNumItems() == 0);
3928 return nullptr;
3929 }
3930
3931 assert(Town::IsValidID(tid));
3932 Town *town = Town::Get(tid);
3933
3934 if (DistanceManhattan(tile, town->xy) >= threshold) town = nullptr;
3935
3936 return town;
3937 }
3938 [[fallthrough]];
3939
3940 case MP_HOUSE:
3941 return Town::GetByTile(tile);
3942
3943 default:
3944 return CalcClosestTownFromTile(tile, threshold);
3945 }
3946}
3947
3948static bool _town_rating_test = false;
3949static std::map<const Town *, int> _town_test_ratings;
3950
3957{
3958 static int ref_count = 0; // Number of times test-mode is switched on.
3959 if (mode) {
3960 if (ref_count == 0) {
3961 _town_test_ratings.clear();
3962 }
3963 ref_count++;
3964 } else {
3965 assert(ref_count > 0);
3966 ref_count--;
3967 }
3968 _town_rating_test = !(ref_count == 0);
3969}
3970
3976static int GetRating(const Town *t)
3977{
3978 if (_town_rating_test) {
3979 auto it = _town_test_ratings.find(t);
3980 if (it != _town_test_ratings.end()) {
3981 return it->second;
3982 }
3983 }
3984 return t->ratings[_current_company];
3985}
3986
3994void ChangeTownRating(Town *t, int add, int max, DoCommandFlags flags)
3995{
3996 /* if magic_bulldozer cheat is active, town doesn't penalize for removing stuff */
3997 if (t == nullptr || flags.Test(DoCommandFlag::NoModifyTownRating) ||
3999 (_cheats.magic_bulldozer.value && add < 0)) {
4000 return;
4001 }
4002
4003 int rating = GetRating(t);
4004 if (add < 0) {
4005 if (rating > max) {
4006 rating += add;
4007 if (rating < max) rating = max;
4008 }
4009 } else {
4010 if (rating < max) {
4011 rating += add;
4012 if (rating > max) rating = max;
4013 }
4014 }
4015 if (_town_rating_test) {
4016 _town_test_ratings[t] = rating;
4017 } else {
4019 t->ratings[_current_company] = rating;
4021 }
4022}
4023
4032{
4033 /* if magic_bulldozer cheat is active, town doesn't restrict your destructive actions */
4034 if (t == nullptr || !Company::IsValidID(_current_company) ||
4036 return CommandCost();
4037 }
4038
4039 /* minimum rating needed to be allowed to remove stuff */
4040 static const int needed_rating[][TOWN_RATING_CHECK_TYPE_COUNT] = {
4041 /* ROAD_REMOVE, TUNNELBRIDGE_REMOVE */
4046 };
4047
4048 /* check if you're allowed to remove the road/bridge/tunnel
4049 * owned by a town no removal if rating is lower than ... depends now on
4050 * difficulty setting. Minimum town rating selected by difficulty level
4051 */
4052 int needed = needed_rating[_settings_game.difficulty.town_council_tolerance][type];
4053
4054 if (GetRating(t) < needed) {
4055 return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index);
4056 }
4057
4058 return CommandCost();
4059}
4060
4061static const IntervalTimer<TimerGameEconomy> _economy_towns_monthly({TimerGameEconomy::MONTH, TimerGameEconomy::Priority::TOWN}, [](auto)
4062{
4063 for (Town *t : Town::Iterate()) {
4064 /* Check for active town actions and decrement their counters. */
4065 if (t->road_build_months != 0) t->road_build_months--;
4067
4068 if (t->exclusive_counter != 0) {
4069 if (--t->exclusive_counter == 0) t->exclusivity = CompanyID::Invalid();
4070 }
4071
4072 /* Check for active failed bribe cooloff periods and decrement them. */
4073 for (const Company *c : Company::Iterate()) {
4074 if (t->unwanted[c->index] > 0) t->unwanted[c->index]--;
4075 }
4076
4077 /* Update cargo statistics. */
4078 for (auto &supplied : t->supplied) supplied.NewMonth();
4079 for (auto &received : t->received) received.NewMonth();
4080
4083
4085 }
4086});
4087
4088static const IntervalTimer<TimerGameEconomy> _economy_towns_yearly({TimerGameEconomy::YEAR, TimerGameEconomy::Priority::TOWN}, [](auto)
4089{
4090 /* Increment house ages */
4091 for (const auto t : Map::Iterate()) {
4092 if (!IsTileType(t, MP_HOUSE)) continue;
4094 }
4095});
4096
4097static CommandCost TerraformTile_Town(TileIndex tile, DoCommandFlags flags, int z_new, Slope tileh_new)
4098{
4099 if (AutoslopeEnabled()) {
4100 HouseID house = GetHouseType(tile);
4101 GetHouseNorthPart(house); // modifies house to the ID of the north tile
4102 const HouseSpec *hs = HouseSpec::Get(house);
4103
4104 /* Here we differ from TTDP by checking BuildingFlag::NotSloped */
4105 if (!hs->building_flags.Test(BuildingFlag::NotSloped) && !IsSteepSlope(tileh_new) &&
4106 (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) {
4107 bool allow_terraform = true;
4108
4109 /* Call the autosloping callback per tile, not for the whole building at once. */
4110 house = GetHouseType(tile);
4111 hs = HouseSpec::Get(house);
4113 /* If the callback fails, allow autoslope. */
4114 uint16_t res = GetHouseCallback(CBID_HOUSE_AUTOSLOPE, 0, 0, house, Town::GetByTile(tile), tile);
4115 if (res != CALLBACK_FAILED && ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_AUTOSLOPE, res)) allow_terraform = false;
4116 }
4117
4118 if (allow_terraform) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
4119 }
4120 }
4121
4122 return Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
4123}
4124
4126extern const TileTypeProcs _tile_type_town_procs = {
4127 DrawTile_Town, // draw_tile_proc
4128 GetSlopePixelZ_Town, // get_slope_z_proc
4129 ClearTile_Town, // clear_tile_proc
4130 AddAcceptedCargo_Town, // add_accepted_cargo_proc
4131 GetTileDesc_Town, // get_tile_desc_proc
4132 GetTileTrackStatus_Town, // get_tile_track_status_proc
4133 nullptr, // click_tile_proc
4134 AnimateTile_Town, // animate_tile_proc
4135 TileLoop_Town, // tile_loop_proc
4136 ChangeTileOwner_Town, // change_tile_owner_proc
4137 AddProducedCargo_Town, // add_produced_cargo_proc
4138 nullptr, // vehicle_enter_tile_proc
4139 GetFoundation_Town, // get_foundation_proc
4140 TerraformTile_Town, // terraform_tile_proc
4141};
4142
4143std::span<const DrawBuildingsTileStruct> GetTownDrawTileData()
4144{
4145 return _town_draw_tile_data;
4146}
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 cargo)
Test whether cargo type is not INVALID_CARGO.
Definition cargo_type.h:106
TownProductionEffect
Town effect when producing cargo.
Definition cargotype.h:35
@ TPE_PASSENGERS
Cargo behaves passenger-like for production.
Definition cargotype.h:37
@ TPE_MAIL
Cargo behaves mail-like for production.
Definition cargotype.h:38
TownAcceptanceEffect
Town growth effect when delivering cargo.
Definition cargotype.h:22
@ TAE_END
End of town effects.
Definition cargotype.h:30
@ TAE_FOOD
Cargo behaves food/fizzy-drinks-like.
Definition cargotype.h:29
@ TAE_WATER
Cargo behaves water-like.
Definition cargotype.h:28
Cheats _cheats
All the cheats.
Definition cheat.cpp:16
Types related to cheating.
static void BroadcastNewEvent(ScriptEvent *event, CompanyID skip_company=CompanyID::Invalid())
Broadcast a new event to all active AIs.
Definition ai_core.cpp:255
constexpr bool All(const Timpl &other) const
Test if all of the values are set.
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
constexpr bool None() const
Test if none of the values are set.
constexpr Timpl & Set()
Set all bits.
constexpr bool Any(const Timpl &other) const
Test if any of the given values are set.
Common return value for all commands.
bool Succeeded() const
Did this command succeed?
void AddCost(const Money &cost)
Adds the given cost to the cost of the command.
Money GetCost() const
The costs as made up to this moment.
bool Failed() const
Did this command fail?
void MultiplyCost(int factor)
Multiplies the cost of the command by the given factor.
Container for an encoded string, created by GetEncodedString.
Enum-as-bit-set wrapper.
static void NewEvent(class ScriptEvent *event)
Queue a new event for a Game Script.
An interval timer will fire every interval, and will continue to fire until it is deleted.
Definition timer.h:76
K-dimensional tree, specialised for 2-dimensional space.
Definition kdtree.hpp:33
void Build(It begin, It end)
Clear and rebuild the tree from a new sequence of elements,.
Definition kdtree.hpp:360
size_t Count() const
Get number of elements stored in tree.
Definition kdtree.hpp:428
void Insert(const T &element)
Insert a single element in the tree.
Definition kdtree.hpp:396
void Remove(const T &element)
Remove a single element from the tree, if it exists.
Definition kdtree.hpp:415
T FindNearest(CoordT x, CoordT y) const
Find the element closest to given coordinate, in Manhattan distance.
Definition kdtree.hpp:439
RoadTypeLabel label
Unique 32 bit road type identifier.
Definition road.h:138
TimerGameCalendar::Date introduction_date
Introduction date.
Definition road.h:157
RoadTypeFlags flags
Bit mask of road type flags.
Definition road.h:118
uint16_t max_speed
Maximum speed for vehicles travelling on this road type.
Definition road.h:133
Generate TileIndices around a center tile or tile area, with increasing distance.
Structure contains cached list of stations nearby.
const StationList & GetStations()
Run a tile loop to find stations around a tile, on demand.
static constexpr TimerGameTick::Ticks TOWN_GROWTH_TICKS
Cycle duration for towns trying to grow (this originates from the size of the town array in TTD).
static Date date
Current date in days (day counter).
static Year year
Current year, starting at 0.
static constexpr TimerGame< struct Calendar >::Date MAX_DATE
The date of the last day of the max year.
static bool UsingWallclockUnits(bool newgame=false)
Check if we are using wallclock units.
static TickCounter counter
Monotonic counter, in ticks, since start of game.
CommandCost CommandCostWithParam(StringID str, uint64_t value)
Return an error status, with string and parameter.
Definition command.cpp:417
Functions related to commands.
static constexpr DoCommandFlags CommandFlagsToDCFlags(CommandFlags cmd_flags)
Extracts the DC flags needed for DoCommand from the flags returned by GetCommandFlags.
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
@ Execute
execute the given command
@ NoModifyTownRating
do not change town rating
@ NoTestTownRating
town rating does not disallow you from building
@ NoWater
don't allow building on water
@ Auto
don't allow building on structures
Definition of stuff that is very close to a company, like the company struct itself.
Money GetAvailableMoneyForCommand()
This functions returns the money which can be used to execute a command.
Money GetAvailableMoney(CompanyID company)
Get the amount of money that a company has available, or INT64_MAX if there is no such valid company.
CompanyID _current_company
Company currently doing an action.
Functions related to companies.
bool IsLocalCompany()
Is the current company the local company?
static constexpr Owner OWNER_DEITY
The object is owned by a superuser / goal script.
static constexpr CompanyID COMPANY_SPECTATOR
The client is spectating.
static constexpr Owner OWNER_TOWN
A town owns the tile, or a town is expanding.
static constexpr Owner OWNER_NONE
The tile has no ownership.
Base for all depots (except hangars)
DiagDirection ReverseDiagDir(DiagDirection d)
Returns the reverse direction of the given DiagDirection.
bool IsValidDiagDirection(DiagDirection d)
Checks if an integer value is a valid DiagDirection.
DiagDirection ChangeDiagDir(DiagDirection d, DiagDirDiff delta)
Applies a difference on a DiagDirection.
Axis DiagDirToAxis(DiagDirection d)
Convert a DiagDirection to the axis.
@ DIR_N
North.
@ DIR_S
South.
@ DIR_W
West.
@ DIR_E
East.
@ DIAGDIRDIFF_90RIGHT
90 degrees right
@ DIAGDIRDIFF_90LEFT
90 degrees left
DiagDirection
Enumeration for diagonal directions.
@ DIAGDIR_NW
Northwest.
@ DIAGDIR_SE
Southeast.
@ DIAGDIR_END
Used for iterations.
@ DIAGDIR_BEGIN
Used for iterations.
@ DIAGDIR_SW
Southwest.
bool EconomyIsInRecession()
Is the economy in recession?
uint ScaleByCargoScale(uint num, bool town)
Scale a number by the cargo scale setting.
@ EXPENSES_CONSTRUCTION
Construction costs.
@ EXPENSES_OTHER
Other expenses.
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23)
Definition enum_type.hpp:17
Functions related to errors.
@ WL_CRITICAL
Critical errors, the MessageBox is shown in all cases.
Definition error.h:27
@ WL_INFO
Used for DoCommand-like (and some non-fatal AI GUI) errors/information.
Definition error.h:24
void ShowErrorMessage(EncodedString &&summary_msg, int x, int y, CommandCost &cc)
Display an error message in a window.
Base functions for all Games.
bool _generating_world
Whether we are generating the map or not.
Definition genworld.cpp:74
Functions related to world/map generation.
void IncreaseGeneratingWorldProgress(GenWorldProgress cls)
Increases the current stage of the world generation with one.
@ GWP_TOWN
Generate towns.
Definition genworld.h:66
void SetGeneratingWorldProgress(GenWorldProgress cls, uint total)
Set the total of a stage of the world generation.
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition gfx_type.h:17
uint8_t GetSnowLine()
Get the current snow line, either variable or static.
uint8_t HighestSnowLine()
Get the highest possible snow line height, either variable or static.
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
Definition gfx.cpp:1535
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
HouseZone
Definition house.h:55
@ ClimateSubarcticAboveSnow
Building can appear in sub-arctic climate above the snow line.
@ ClimateSubarcticBelowSnow
Building can appear in sub-arctic climate below the snow line.
@ ClimateTemperate
Building can appear in temperate climate.
@ ClimateToyland
Building can appear in toyland climate.
@ ClimateSubtropic
Building can appear in subtropical climate.
uint16_t HouseID
OpenTTD ID of house types.
Definition house_type.h:13
Base of all industries.
void DrawFoundation(TileInfo *ti, Foundation f)
Draw foundation f at tile ti.
std::tuple< Slope, int > GetFoundationSlope(TileIndex tile)
Get slope of a tile on top of a (possible) foundation If a tile does not have a foundation,...
Functions related to OTTD's landscape.
Point RemapCoords2(int x, int y)
Map 3D world or tile coordinate to equivalent 2D coordinate as used in the viewports and smallmap.
Definition landscape.h:95
Command definitions related to landscape (slopes etc.).
@ Random
Randomise borders.
uint DistanceSquare(TileIndex t0, TileIndex t1)
Gets the 'Square' distance between the two given tiles.
Definition map.cpp:159
uint DistanceFromEdge(TileIndex tile)
Param the minimum distance to an edge.
Definition map.cpp:202
uint DistanceManhattan(TileIndex t0, TileIndex t1)
Gets the Manhattan distance between the two given tiles.
Definition map.cpp:142
uint GetClosestWaterDistance(TileIndex tile, bool water)
Finds the distance for the closest tile with water/land given a tile.
Definition map.cpp:236
TileIndex TileAddXY(TileIndex tile, int x, int y)
Adds a given offset to a tile.
Definition map_func.h:469
TileIndex TileAddByDir(TileIndex tile, Direction dir)
Adds a Direction to a tile.
Definition map_func.h:598
static debug_inline TileIndex TileXY(uint x, uint y)
Returns the TileIndex of a coordinate.
Definition map_func.h:372
TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc)
Return the offset between two tiles from a TileIndexDiffC struct.
Definition map_func.h:439
TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir)
Adds a DiagDir to a tile.
Definition map_func.h:610
TileIndexDiff TileDiffXY(int x, int y)
Calculates an offset for the given coordinate(-offset).
Definition map_func.h:388
constexpr TileIndex TileAdd(TileIndex tile, TileIndexDiff offset)
Adds a given offset to a tile.
Definition map_func.h:456
#define RandomTile()
Get a valid random tile.
Definition map_func.h:651
static debug_inline uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition map_func.h:424
static debug_inline uint TileX(TileIndex tile)
Get the X component of a tile.
Definition map_func.h:414
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition map_func.h:569
TileIndexDiffC TileIndexToTileIndexDiffC(TileIndex tile_a, TileIndex tile_b)
Returns the diff between two tiles.
Definition map_func.h:530
int32_t TileIndexDiff
An offset value between two tiles.
Definition map_type.h:23
constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
constexpr int RoundDivSU(int a, uint b)
Computes round(a / b) for signed a and unsigned b.
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition math_func.hpp:79
@ GSF_FAKE_TOWNS
Fake town GrfSpecFeature for NewGRF debugging (parent scope)
Definition newgrf.h:95
@ CBID_HOUSE_DRAW_FOUNDATIONS
Called to determine the type (if any) of foundation to draw for house tile.
@ CBID_HOUSE_CARGO_ACCEPTANCE
Called to decide how much cargo a town building can accept.
@ CBID_HOUSE_AUTOSLOPE
Called to determine if one can alter the ground below a house tile.
@ CBID_HOUSE_CUSTOM_NAME
Called on the Get Tile Description for an house tile.
@ CBID_HOUSE_ALLOW_CONSTRUCTION
Determine whether the house can be built on the specified tile.
@ CBID_HOUSE_ACCEPT_CARGO
Called to determine which cargoes a town building should accept.
@ CBID_HOUSE_PRODUCE_CARGO
Called to determine how much cargo a town building produces.
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
@ AllowConstruction
decide whether the house can be built on a given tile
@ AcceptCargo
decides accepted types
@ CargoAcceptance
decides amount of cargo acceptance
@ DrawFoundations
decides if default foundations need to be drawn
@ ProduceCargo
custom cargo production
@ Autoslope
decides allowance of autosloping
static const uint CALLBACK_HOUSEPRODCARGO_END
Sentinel indicating that the loop for CBID_HOUSE_PRODUCE_CARGO has ended.
CargoType GetCargoTranslation(uint8_t cargo, const GRFFile *grffile, bool usebit)
Translate a GRF-local cargo slot/bitnum into a CargoType.
Cargo support for NewGRFs.
void ErrorUnknownCallbackResult(uint32_t grfid, uint16_t cbid, uint16_t cb_res)
Record that a NewGRF returned an unknown/invalid callback result.
bool Convert8bitBooleanCallback(const GRFFile *grffile, uint16_t cbid, uint16_t cb_res)
Converts a callback result into a boolean.
bool ConvertBooleanCallback(const GRFFile *grffile, uint16_t cbid, uint16_t cb_res)
Converts a callback result into a boolean.
GRFConfig * GetGRFConfig(uint32_t grfid, uint32_t mask)
Retrieve a NewGRF from the current config by its grfid.
Functions/types related to NewGRF debugging.
void DeleteNewGRFInspectWindow(GrfSpecFeature feature, uint index)
Delete inspect window for a given feature and index.
void DecreaseBuildingCount(Town *t, HouseID house_id)
DecreaseBuildingCount() Decrease the number of a building when it is deleted.
void IncreaseBuildingCount(Town *t, HouseID house_id)
IncreaseBuildingCount() Increase the count of a building when it has been added by a town.
void InitializeBuildingCounts()
Initialise global building counts and all town building counts.
Functions related to NewGRF houses.
StringID GetGRFStringID(uint32_t grfid, GRFStringID stringid)
Returns the index for this stringid associated with its grfID.
Header of Action 04 "universal holder" structure and functions.
static constexpr GRFStringID GRFSTR_MISC_GRF_TEXT
Miscellaneous GRF text range.
Functions related to news.
void AddNewsItem(EncodedString &&headline, NewsType type, NewsStyle style, NewsFlags flags, NewsReference ref1={}, NewsReference ref2={}, std::unique_ptr< NewsAllocatedData > &&data=nullptr, AdviceType advice_type=AdviceType::Invalid)
Add a new newsitem to be shown.
Definition news_gui.cpp:902
@ General
General news (from towns)
@ IndustryOpen
Opening of industries.
@ Company
Company news item. (Newspaper with face)
@ Normal
Normal news item. (Newspaper with text only)
Functions related to objects.
void BuildObject(ObjectType type, TileIndex tile, CompanyID owner=OWNER_NONE, struct Town *town=nullptr, uint8_t view=0)
Actually build the object.
Base for all objects.
Map accessors for object tiles.
static const ObjectType OBJECT_STATUE
Statue in towns.
Definition object_type.h:20
Some methods of Pool are placed here in order to reduce compilation time and binary size.
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don't get linker errors.
static debug_inline bool IsPlainRailTile(Tile t)
Checks whether the tile is a rail tile or rail tile with signals.
Definition rail_map.h:60
Randomizer _random
Random used in the game state calculations.
Pseudo random number generator.
uint32_t RandomRange(uint32_t limit, const std::source_location location=std::source_location::current())
Pick a random number between 0 and limit - 1, inclusive.
bool Chance16(const uint32_t a, const uint32_t b, const std::source_location location=std::source_location::current())
Flips a coin with given probability.
RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb)
Clean up unnecessary RoadBits of a planned tile.
Definition road.cpp:47
Road specific functions.
@ NoHouses
Bit number for setting this roadtype as not house friendly.
@ TownBuild
Bit number for allowing towns to build this roadtype.
const RoadTypeInfo * GetRoadTypeInfo(RoadType roadtype)
Returns a pointer to the Roadtype information for a given roadtype.
Definition road.h:230
void UpdateNearestTownForRoadTiles(bool invalidate)
Updates cached nearest town for all road tiles.
Road related functions.
RoadBits DiagDirToRoadBits(DiagDirection d)
Create the road-part which belongs to the given DiagDirection.
Definition road_func.h:96
Functions used internally by the roads.
RoadBits GetAnyRoadBits(Tile tile, RoadTramType rtt, bool straight_tunnel_bridge_entrance)
Returns the RoadBits on an arbitrary tile Special behaviour:
Definition road_map.cpp:54
void SetRoadOwner(Tile t, RoadTramType rtt, Owner o)
Set the owner of a specific road type.
Definition road_map.h:235
bool HasTownOwnedRoad(Tile t)
Checks if given tile has town owned road.
Definition road_map.h:264
static debug_inline bool IsNormalRoadTile(Tile t)
Return whether a tile is a normal road tile.
Definition road_map.h:58
static debug_inline bool IsRoadDepot(Tile t)
Return whether a tile is a road depot.
Definition road_map.h:90
DisallowedRoadDirections GetDisallowedRoadDirections(Tile t)
Gets the disallowed directions.
Definition road_map.h:285
bool HasTileRoadType(Tile t, RoadTramType rtt)
Check if a tile has a road or a tram road type.
Definition road_map.h:195
DiagDirection GetRoadDepotDirection(Tile t)
Get the direction of the exit of a road depot.
Definition road_map.h:545
static debug_inline bool IsRoadDepotTile(Tile t)
Return whether a tile is a road depot tile.
Definition road_map.h:100
bool IsRoadOwner(Tile t, RoadTramType rtt, Owner o)
Check if a specific road type is owned by an owner.
Definition road_map.h:252
RoadBits
Enumeration for the road parts on a tile.
Definition road_type.h:40
@ ROAD_SW
South-west part.
Definition road_type.h:43
@ ROAD_ALL
Full 4-way crossing.
Definition road_type.h:54
@ ROAD_NONE
No road-part is build.
Definition road_type.h:41
@ ROAD_E
Road at the two eastern edges.
Definition road_type.h:50
@ ROAD_NE
North-east part.
Definition road_type.h:45
@ ROAD_N
Road at the two northern edges.
Definition road_type.h:49
@ ROAD_SE
South-east part.
Definition road_type.h:44
@ ROAD_Y
Full road along the y-axis (north-west + south-east)
Definition road_type.h:47
@ ROAD_S
Road at the two southern edges.
Definition road_type.h:51
@ ROAD_W
Road at the two western edges.
Definition road_type.h:52
@ ROAD_NW
North-west part.
Definition road_type.h:42
@ ROAD_X
Full road along the x-axis (south-west + north-east)
Definition road_type.h:46
RoadType
The different roadtypes we support.
Definition road_type.h:23
@ INVALID_ROADTYPE
flag for invalid roadtype
Definition road_type.h:28
@ ROADTYPE_ROAD
Basic road type.
Definition road_type.h:25
@ ROADTYPE_END
Used for iterations.
Definition road_type.h:27
@ ROADTYPE_BEGIN
Used for iterations.
Definition road_type.h:24
@ DRD_NONE
None of the directions are disallowed.
Definition road_type.h:62
A number of safeguards to prevent using unsafe methods.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
GameSettings _settings_newgame
Game settings for new games (updated from the intro screen).
Definition settings.cpp:62
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:60
static constexpr int GetSlopeMaxZ(Slope s)
Returns the height of the highest corner of a slope relative to TileZ (= minimal height)
Definition slope_func.h:160
bool IsSlopeWithOneCornerRaised(Slope s)
Tests if a specific slope has exactly one corner raised.
Definition slope_func.h:88
static constexpr bool IsSteepSlope(Slope s)
Checks if a slope is steep.
Definition slope_func.h:36
Foundation FlatteningFoundation(Slope s)
Returns the foundation needed to flatten a slope.
Definition slope_func.h:369
Slope InclinedSlope(DiagDirection dir)
Returns the slope that is inclined in a specific direction.
Definition slope_func.h:256
Slope ComplementSlope(Slope s)
Return the complement of a slope.
Definition slope_func.h:76
Slope
Enumeration for the slope-type.
Definition slope_type.h:48
@ SLOPE_W
the west corner of the tile is raised
Definition slope_type.h:50
@ SLOPE_ELEVATED
bit mask containing all 'simple' slopes
Definition slope_type.h:61
@ SLOPE_E
the east corner of the tile is raised
Definition slope_type.h:52
@ SLOPE_S
the south corner of the tile is raised
Definition slope_type.h:51
@ SLOPE_N
the north corner of the tile is raised
Definition slope_type.h:53
@ SLOPE_SW
south and west corner are raised
Definition slope_type.h:56
@ SLOPE_FLAT
a flat tile
Definition slope_type.h:49
@ SLOPE_STEEP_W
a steep slope falling to east (from west)
Definition slope_type.h:66
@ SLOPE_NE
north and east corner are raised
Definition slope_type.h:58
@ SLOPE_STEEP_E
a steep slope falling to west (from east)
Definition slope_type.h:68
@ SLOPE_SE
south and east corner are raised
Definition slope_type.h:57
@ SLOPE_NW
north and west corner are raised
Definition slope_type.h:55
@ SLOPE_STEEP_N
a steep slope falling to south (from north)
Definition slope_type.h:69
@ SLOPE_STEEP_S
a steep slope falling to north (from south)
Definition slope_type.h:67
Foundation
Enumeration for Foundations.
Definition slope_type.h:93
@ FOUNDATION_LEVELED
The tile is leveled up to a flat slope.
Definition slope_type.h:95
@ FOUNDATION_NONE
The tile has no foundation, the slope remains unchanged.
Definition slope_type.h:94
@ Town
Source/destination is a town.
Base classes/functions for stations.
void ForAllStationsAroundTiles(const TileArea &ta, Func func)
Call a function on all stations that have any part of the requested area within their catchment.
void UpdateAllStationVirtCoords()
Update the virtual coords needed to draw the station sign for all stations.
void UpdateAirportsNoise()
Recalculate the noise generated by the airports of each town.
Declarations for accessing the k-d tree of stations.
void ForAllStationsRadius(TileIndex center, uint radius, Func func)
Call a function on all stations whose sign is within a radius of a center tile.
bool IsBayRoadStopTile(Tile t)
Is tile t a bay (non-drive through) road stop station?
bool IsDriveThroughStopTile(Tile t)
Is tile t a drive through road stop station or waypoint?
Axis GetDriveThroughStopAxis(Tile t)
Gets the axis of the drive through stop.
DiagDirection GetBayRoadStopDir(Tile t)
Gets the direction the bay road stop entrance points towards.
bool IsAnyRoadStopTile(Tile t)
Is tile t a road stop station?
@ Airport
Station with an airport.
Definition of base types and functions in a cross-platform compatible way.
#define lengthof(array)
Return the length of an fixed size array.
Definition stdafx.h:271
size_t Utf8StringLength(std::string_view str)
Get the length of an UTF-8 encoded string in number of characters and thus not the number of bytes th...
Definition string.cpp:347
Functions related to low-level strings.
EncodedString GetEncodedString(StringID str)
Encode a string with no parameters into an encoded string.
Definition strings.cpp:91
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
Definition strings.cpp:415
Functions related to OTTD's strings.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
Class to backup a specific variable and restore it upon destruction of this object to prevent stack v...
Class to backup a specific variable and restore it later.
void Restore()
Restore the variable.
Owner owner
The owner of this station.
Class for storing amounts of cargo.
Definition cargo_type.h:113
static void InvalidateAllFrom(Source src)
Invalidates (sets source_id to INVALID_SOURCE) all cargo packets from given source.
Specification of a cargo type.
Definition cargotype.h:74
static IterateWrapper Iterate(size_t from=0)
Returns an iterable ensemble of all valid CargoSpec.
Definition cargotype.h:192
static std::array< std::vector< const CargoSpec * >, NUM_TPE > town_production_cargoes
List of cargo specs for each Town Product Effect.
Definition cargotype.h:25
bool value
tells if the bool cheat is active or not
Definition cheat_type.h:18
Cheat magic_bulldozer
dynamite industries, objects
Definition cheat_type.h:27
GUISettings gui
settings related to the GUI
bool build_on_slopes
allow building on slopes
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:72
bool bribe
enable bribing the local authority
TownFounding found_town
town founding.
PlaceHouses place_houses
players are allowed to place town houses.
bool exclusive_rights
allow buying exclusive rights
uint8_t initial_city_size
multiplier for the initial size of the cities compared to towns
TownLayout town_layout
select town layout,
bool allow_town_level_crossings
towns are allowed to build level crossings
uint8_t town_growth_rate
town growth rate
bool allow_town_roads
towns are allowed to build roads (always allowed when generating world / in SE)
bool fund_buildings
allow funding new buildings
bool fund_roads
allow funding local road reconstruction
TownCargoGenMode town_cargogen_mode
algorithm for generating cargo from houses,
uint8_t dist_local_authority
distance for town local authority, default 20
uint8_t larger_towns
the number of cities to build. These start off larger and grow twice as fast
Information about GRF, used in the game and (part of it) in savegames.
std::string GetName() const
Get the name of this grf.
const struct GRFFile * grffile
grf file that introduced this entity
uint32_t grfid
grfid that introduced this entity.
bool HasGrfFile() const
Test if this entity was introduced by NewGRF.
bool population_in_label
show the population of a town in its label?
uint16_t custom_town_number
manually entered number of towns
LandscapeType landscape
the landscape we're currently in
uint8_t town_name
the town name generator used for town names
EconomySettings economy
settings to change the economy
ConstructionSettings construction
construction of things in-game
DifficultySettings difficulty
settings related to the difficulty
GameCreationSettings game_creation
settings used during the creation of a game (map)
Stores station stats for a single cargo.
CargoType accepts_cargo[HOUSE_NUM_ACCEPTS]
input cargo slots
Definition house.h:108
SubstituteGRFFileProps grf_prop
Properties related the the grf file.
Definition house.h:114
uint8_t probability
Relative probability of appearing (16 is the standard value)
Definition house.h:117
uint8_t removal_cost
cost multiplier for removing it
Definition house.h:103
uint8_t mail_generation
mail generation multiplier (tile based, as the acceptances below)
Definition house.h:106
bool enabled
the house is available to build (true by default, but can be disabled by newgrf)
Definition house.h:111
Money GetRemovalCost() const
Get the cost for removing this house.
Definition town_cmd.cpp: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:109
TimerGameCalendar::Year max_year
last year it can be built
Definition house.h:101
HouseCallbackMasks callback_mask
Bitmask of house callbacks that have to be called.
Definition house.h:115
uint16_t remove_rating_decrease
rating decrease if removed
Definition house.h:105
uint8_t population
population (Zero on other tiles in multi tile house.)
Definition house.h:102
HouseExtraFlags extra_flags
some more flags
Definition house.h:118
uint8_t cargo_acceptance[HOUSE_NUM_ACCEPTS]
acceptance level for the cargo slots
Definition house.h:107
HouseID Index() const
Gets the index of this spec.
HouseClassID class_id
defines the class this house has (not grf file based)
Definition house.h:119
StringID building_name
building name
Definition house.h:104
uint8_t minimum_life
The minimum number of years this house will survive before the town rebuilds it.
Definition house.h:122
HouseZones building_availability
where can it be built (climates, zones)
Definition house.h:110
static std::vector< HouseSpec > & Specs()
Get a reference to all HouseSpecs.
Defines the internal data of a functional industry.
Definition industry.h:64
Town * town
Nearest town.
Definition industry.h:93
static Industry * GetByTile(TileIndex tile)
Get the industry of the given tile.
Definition industry.h:236
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.
Station data structure.
bool CatchmentCoversTown(TownID t) const
Test if the given town ID is covered by our catchment area.
Definition station.cpp:452
uint16_t override_id
id of the entity been replaced by
Tile description for the 'land area information' tool.
Definition tile_cmd.h:38
std::optional< std::string > grf
newGRF used for the tile contents
Definition tile_cmd.h:49
StringID str
Description of the tile.
Definition tile_cmd.h:39
std::array< Owner, 4 > owner
Name of the owner(s)
Definition tile_cmd.h:41
uint64_t dparam
Parameter of the str string.
Definition tile_cmd.h:40
std::optional< bool > town_can_upgrade
Whether the town can upgrade this house during town growth.
Definition tile_cmd.h:56
A pair-construct of a TileIndexDiff.
Definition map_type.h:31
int16_t x
The x value of the coordinate.
Definition map_type.h:32
int16_t y
The y value of the coordinate.
Definition map_type.h:33
Tile information, used while rendering the tile.
Definition tile_cmd.h:29
int z
Height.
Definition tile_cmd.h:34
int x
X position of the tile in unit coordinates.
Definition tile_cmd.h:30
Slope tileh
Slope of the tile.
Definition tile_cmd.h:32
TileIndex tile
Tile index.
Definition tile_cmd.h:33
int y
Y position of the tile in unit coordinates.
Definition tile_cmd.h:31
Set of callback functions for performing tile operations of a given tile type.
Definition tile_cmd.h:144
uint32_t population
Current population of people.
Definition town.h:42
uint32_t num_houses
Amount of houses.
Definition town.h:41
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
std::array< uint32_t, NUM_HOUSE_ZONES > squared_town_zone_radius
UpdateTownRadius updates this given the house count.
Definition town.h:45
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
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
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
TypedIndexContainer< std::array< uint8_t, MAX_COMPANIES >, CompanyID > unwanted
how many months companies aren't wanted by towns (bribe)
Definition town.h:72
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:400
CompanyMask have_ratings
which companies have a rating
Definition town.h:71
~Town()
Destroy the town.
Definition town_cmd.cpp:110
TypedIndexContainer< std::array< int16_t, MAX_COMPANIES >, CompanyID > ratings
ratings of each company for this town
Definition town.h:75
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.
std::tuple< CommandCost, Money, TownID > CmdFoundTown(DoCommandFlags flags, TileIndex tile, TownSize size, bool city, TownLayout layout, bool random_location, uint32_t townnameparts, const std::string &text)
Create a new town.
void ChangeTownRating(Town *t, int add, int max, DoCommandFlags flags)
Changes town rating of the current company.
HouseZones GetClimateMaskForLandscape()
Get the HouseZones climate mask for the current landscape type.
static bool GrowTownAtRoad(Town *t, TileIndex tile, TownExpandModes modes)
Try to grow a town at a given road tile.
static CommandCost TownActionAdvertiseSmall(Town *t, DoCommandFlags flags)
Perform the "small advertising campaign" town action.
static CommandCost TownActionFundBuildings(Town *t, DoCommandFlags flags)
Perform the "fund new buildings" town action.
static bool IsTileAlignedToGrid(TileIndex tile, TownLayout layout)
Towns must all be placed on the same grid or when they eventually interpenetrate their road networks ...
static CommandCost TownActionBuildStatue(Town *t, DoCommandFlags flags)
Perform a 9x9 tiles circular search from the center of the town in order to find a free tile to place...
static CommandCost TownActionBribe(Town *t, DoCommandFlags flags)
Perform the "bribe" town action.
TileIndexDiff GetHouseNorthPart(HouseID &house)
Determines if a given HouseID is part of a multitile house.
static int GetRating(const Town *t)
Get the rating of a town for the _current_company.
uint GetDefaultTownsForMapSize()
Calculate the number of towns which should be on the map according to the current "town density" newg...
void ClearTownHouse(Town *t, TileIndex tile)
Clear a town house.
static uint GetNormalGrowthRate(Town *t)
Calculates town growth rate in normal conditions (custom growth rate not set).
TownActions GetMaskOfTownActions(CompanyID cid, const Town *t)
Get a list of available town authority actions.
static CommandCost TownActionBuyRights(Town *t, DoCommandFlags flags)
Perform the "buy exclusive transport rights" town action.
static bool GrowTownWithBridge(const Town *t, const TileIndex tile, const DiagDirection bridge_dir)
Grows the town with a bridge.
const CargoSpec * FindFirstCargoWithTownAcceptanceEffect(TownAcceptanceEffect effect)
Determines the first cargo with a certain town effect.
static TileIndex FindNearestGoodCoastalTownSpot(TileIndex tile, TownLayout layout)
Given a spot on the map (presumed to be a water tile), find a good coastal spot to build a city.
Town * ClosestTownFromTile(TileIndex tile, uint threshold)
Return the town closest (in distance or ownership) to a given tile, within a given threshold.
static bool IsRoadAllowedHere(Town *t, TileIndex tile, DiagDirection dir)
Check if a Road is allowed on a given tile.
static bool CanRoadContinueIntoNextTile(const Town *t, const TileIndex tile, const DiagDirection road_dir)
Checks if a town road can be continued into the next tile.
static bool TryBuildTownHouse(Town *t, TileIndex tile, TownExpandModes modes)
Tries to build a house at this tile.
static void UpdateTownGrowCounter(Town *t, uint16_t prev_growth_rate)
Updates town grow counter after growth rate change.
static int CountActiveStations(Town *t)
Calculates amount of active stations in the range of town (HZB_TOWN_EDGE).
static CommandCost TownCanBePlacedHere(TileIndex tile)
Check if it's possible to place a town on a given tile.
static bool IsNeighbourRoadTile(TileIndex tile, const DiagDirection dir, uint dist_multi)
Check for parallel road inside a given distance.
CommandCost CmdPlaceHouse(DoCommandFlags flags, TileIndex tile, HouseID house, bool is_protected)
Place an individual house.
static bool _generating_town
Set if a town is being generated.
Definition town_cmd.cpp:83
static void MakeTownHouse(TileIndex tile, Town *t, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool is_protected)
Write house information into the map.
static bool CheckTownBuild2x2House(TileIndex *tile, Town *t, int maxz, bool noslope, TownExpandModes modes)
Checks if a 1x2 or 2x1 building is allowed here, accounting for road layout and tile heights.
static void TileLoop_Town(TileIndex tile)
Tile callback function.
Definition town_cmd.cpp:595
static bool CanBuildHouseHere(TileIndex tile, bool noslope)
Check if a house can be built here, based on slope, whether there's a bridge above,...
static bool TownLayoutAllowsHouseHere(Town *t, TileIndex tile, TownExpandModes modes)
Checks if the current town layout allows building here.
bool GenerateTowns(TownLayout layout, std::optional< uint > number)
Generate a number of towns with a given layout.
static bool GrowTownWithRoad(const Town *t, TileIndex tile, RoadBits rcmd)
Grows the town with a road piece.
CommandCost CmdDoTownAction(DoCommandFlags flags, TownID town_id, TownAction action)
Do a town action.
static void TownGenerateCargoBinomial(Town *t, TownProductionEffect tpe, uint8_t rate, StationFinder &stations)
Generate cargo for a house using the binomial algorithm.
Definition town_cmd.cpp:572
static void UpdateTownRating(Town *t)
Monthly callback to update town and station ratings.
static bool TownLayoutAllows2x2HouseHere(Town *t, TileIndex tile, TownExpandModes modes)
Checks if the current town layout allows a 2x2 building here.
static void AdvanceHouseConstruction(TileIndex tile)
Increase the construction stage of a house.
Definition town_cmd.cpp:511
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:452
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:710
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:552
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:437
CargoArray GetAcceptedCargoOfHouse(const HouseSpec *hs)
Get accepted cargo of a house prototype.
Definition town_cmd.cpp:851
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:782
static DiagDirection RandomDiagDir()
Return a random direction.
Definition town_cmd.cpp:249
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:466
uint8_t GetTownActionCost(TownAction action)
Get cost factors for a TownAction.
CommandCost CmdTownSetText(DoCommandFlags flags, TownID town_id, const EncodedString &text)
Set a custom text in the Town window.
Town * CalcClosestTownFromTile(TileIndex tile, uint threshold)
Return the town closest to the given tile within threshold.
CommandCost CmdTownGrowthRate(DoCommandFlags flags, TownID town_id, uint16_t growth_rate)
Change the growth rate of the town.
static TownGrowthResult GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection target_dir, Town *t1, TownExpandModes modes)
Grows the given town.
static CommandCost TownActionRoadRebuild(Town *t, DoCommandFlags flags)
Perform the "local road reconstruction" town action.
void ClearAllTownCachedNames()
Clear the cached_name of all towns.
Definition town_cmd.cpp:425
CommandCost CmdDeleteTown(DoCommandFlags flags, TownID town_id)
Delete a town (scenario editor or worldgen only).
static Foundation GetFoundation_Town(TileIndex tile, Slope tileh)
Get the foundation for a house.
Definition town_cmd.cpp:317
static TimerGameCalendar::Date GetTownRoadTypeFirstIntroductionDate()
Get the calendar date of the earliest town-buildable road type.
Definition town_cmd.cpp:993
static void AnimateTile_Town(TileIndex tile)
Animate a tile for a town.
Definition town_cmd.cpp:341
const TileTypeProcs _tile_type_town_procs
Tile callback functions for a town.
Definition landscape.cpp:52
RoadType GetTownRoadType()
Get the road type that towns should build at this current moment.
Definition town_cmd.cpp:958
static RoadBits GetTownRoadBits(TileIndex tile)
Return the RoadBits of a tile, ignoring depot and bay road stops.
Definition town_cmd.cpp:947
CommandCost CmdRenameTown(DoCommandFlags flags, TownID town_id, const std::string &text)
Rename a town (server-only).
CommandCost CmdTownCargoGoal(DoCommandFlags flags, TownID town_id, TownAcceptanceEffect tae, uint32_t goal)
Change the cargo goal of a town.
static void DoCreateTown(Town *t, TileIndex tile, uint32_t townnameparts, TownSize size, bool city, TownLayout layout, bool manual)
Actually create a town.
CommandCost CheckforTownRating(DoCommandFlags flags, Town *t, TownRatingCheckType type)
Does the town authority allow the (destructive) action of the current company?
HouseZone GetTownRadiusGroup(const Town *t, TileIndex tile)
Returns the bit corresponding to the town zone of the specified tile.
static bool CheckTownBuild2House(TileIndex *tile, Town *t, int maxz, bool noslope, DiagDirection second, TownExpandModes modes)
Checks if a 1x2 or 2x1 building is allowed here, accounting for road layout and tile heights.
static bool TestTownOwnsBridge(TileIndex tile, const Town *t)
Check if a town 'owns' a bridge.
Definition town_cmd.cpp:94
void OnTick_Town()
Iterate through all towns and call their tick handler.
Definition town_cmd.cpp:933
static CommandCost TownActionAdvertiseLarge(Town *t, DoCommandFlags flags)
Perform the "large advertising campaign" town action.
bool CheckTownRoadTypes()
Check if towns are able to build road.
static bool GrowTown(Town *t, TownExpandModes modes)
Grow the town.
static void UpdateTownGrowthRate(Town *t)
Updates town growth rate.
static RoadBits GetTownRoadGridElement(Town *t, TileIndex tile, DiagDirection dir)
Generate the RoadBits of a grid tile.
static void AdvanceSingleHouseConstruction(TileIndex tile)
Helper function for house construction stage progression.
Definition town_cmd.cpp:488
static void TownTickHandler(Town *t)
Handle the town tick for a single town, by growing the town if desired.
Definition town_cmd.cpp:914
void SetTownRatingTestMode(bool mode)
Switch the town rating to test-mode, to allow commands to be tested without affecting current ratings...
static bool _town_rating_test
If true, town rating is in test-mode.
CommandCost CmdTownRating(DoCommandFlags flags, TownID town_id, CompanyID company_id, int16_t rating)
Change the rating of a company in a town.
void UpdateTownRadius(Town *t)
Update the cached town zone radii of a town, based on the number of houses.
static bool GrowTownWithExtraHouse(Town *t, TileIndex tile, TownExpandModes modes)
Grows the town with an extra house.
void AddAcceptedCargoOfHouse(TileIndex tile, HouseID house, const HouseSpec *hs, Town *t, CargoArray &acceptance, CargoTypes &always_accepted)
Determine accepted cargo for a house.
Definition town_cmd.cpp:798
static bool TownAllowedToBuildRoads(TownExpandModes modes)
Check if the town is allowed to build roads.
CommandCost CmdExpandTown(DoCommandFlags flags, TownID town_id, uint32_t grow_amount, TownExpandModes modes)
Expand a town (scenario editor only).
static bool IsCloseToTown(TileIndex tile, uint dist)
Determines if a town is close to a tile.
Definition town_cmd.cpp:392
static void UpdateTownGrowth(Town *t)
Updates town growth state (whether it is growing or not).
static void DoClearTownHouseHelper(TileIndex tile, Town *t, HouseID house)
Update data structures when a house is removed.
static RoadBits GenRandomRoadBits()
Generate a random road block.
static bool CheckBuildHouseSameZ(TileIndex tile, int z, bool noslope)
Check if a tile where we want to build a multi-tile house has an appropriate max Z.
CommandCost CheckIfAuthorityAllowsNewStation(TileIndex tile, DoCommandFlags flags)
Checks whether the local authority allows construction of a new station (rail, road,...
static bool CanFollowRoad(TileIndex tile, DiagDirection dir, TownExpandModes modes)
Checks whether a road can be followed or is a dead end, that can not be extended to the next tile.
static void BuildTownHouse(Town *t, TileIndex tile, const HouseSpec *hs, HouseID house, uint8_t random_bits, bool house_completed, bool is_protected)
Build a house at this tile.
static void TownGenerateCargo(Town *t, CargoType cargo, uint amount, StationFinder &stations, bool affected_by_recession)
Generate cargo for a house, scaled by the current economy scale.
Definition town_cmd.cpp:528
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:258
void UpdateAllTownVirtCoords()
Update the virtual coords needed to draw the town sign for all towns.
Definition town_cmd.cpp:417
Command definitions related to towns.
Declarations for accessing the k-d tree of towns.
Sprites to use and how to display them for town tiles.
static const DrawBuildingsTileStruct _town_draw_tile_data[]
structure of houses graphics
Definition town_land.h:27
void IncrementHouseAge(Tile t)
Increments the age of the house.
Definition town_map.h:259
void HaltLift(Tile t)
Stop the lift of this animated house from moving.
Definition town_map.h:137
HouseID GetHouseType(Tile t)
Get the type of this house, which is an index into the house spec array.
Definition town_map.h:60
void ResetHouseAge(Tile t)
Sets the age of the house to zero.
Definition town_map.h:248
void MakeHouseTile(Tile t, TownID tid, uint8_t counter, uint8_t stage, HouseID type, uint8_t random_bits, bool house_protected)
Make the tile a house.
Definition town_map.h:375
void IncHouseConstructionTick(Tile t)
Sets the increment stage of a house It is working with the whole counter + stage 5 bits,...
Definition town_map.h:230
uint8_t GetLiftPosition(Tile t)
Get the position of the lift on this animated house.
Definition town_map.h:147
void SetLiftDestination(Tile t, uint8_t dest)
Set the new destination of the lift for this animated house, and activate the LiftHasDestination bit.
Definition town_map.h:115
TimerGameCalendar::Year GetHouseAge(Tile t)
Get the age of the house.
Definition town_map.h:271
void SetLiftPosition(Tile t, uint8_t pos)
Set the position of the lift on this animated house.
Definition town_map.h:157
uint8_t GetLiftDestination(Tile t)
Get the current destination for this lift.
Definition town_map.h:126
uint8_t GetHouseBuildingStage(Tile t)
House Construction Scheme.
Definition town_map.h:205
TownID GetTownIndex(Tile t)
Get the index of which town this house/street is attached to.
Definition town_map.h:23
void SetTownIndex(Tile t, TownID index)
Set the town index for a road or house tile.
Definition town_map.h:35
bool LiftHasDestination(Tile t)
Check if the lift of this animated house has a destination.
Definition town_map.h:104
bool IsHouseCompleted(Tile t)
Get the completion of this house.
Definition town_map.h:167
bool IsHouseProtected(Tile t)
Check if the house is protected from removal by towns.
Definition town_map.h:82
uint8_t GetHouseConstructionTick(Tile t)
Gets the construction stage of a house.
Definition town_map.h:217
static constexpr int RATING_GROWTH_UP_STEP
when a town grows, all companies have rating increased a bit ...
Definition town_type.h:53
static constexpr int RATING_INITIAL
initial rating
Definition town_type.h:45
static constexpr int RATING_ROAD_NEEDED_HOSTILE
"Hostile"
Definition town_type.h:71
@ TCGM_BITCOUNT
Bit-counted algorithm (normal distribution from individual house population)
Definition town_type.h:115
@ TCGM_ORIGINAL
Original algorithm (quadratic cargo by population)
Definition town_type.h:114
static constexpr int RATING_ROAD_NEEDED_NEUTRAL
"Neutral"
Definition town_type.h:70
TownLayout
Town Layouts.
Definition town_type.h:81
@ TL_3X3_GRID
Geometric 3x3 grid algorithm.
Definition town_type.h:86
@ TL_ORIGINAL
Original algorithm (min. 1 distance between roads)
Definition town_type.h:83
@ TL_2X2_GRID
Geometric 2x2 grid algorithm.
Definition town_type.h:85
@ TL_RANDOM
Random town layout.
Definition town_type.h:88
@ TL_BETTER_ROADS
Extended original algorithm (min. 2 distance between roads)
Definition town_type.h:84
@ NUM_TLS
Number of town layouts.
Definition town_type.h:90
static constexpr int RATING_TUNNEL_BRIDGE_NEEDED_LENIENT
rating needed, "Lenient" difficulty settings
Definition town_type.h:61
@ TF_CUSTOM_LAYOUT
Allowed, with custom town layout.
Definition town_type.h:107
@ TF_FORBIDDEN
Forbidden.
Definition town_type.h:105
static constexpr int RATING_TUNNEL_BRIDGE_NEEDED_HOSTILE
"Hostile"
Definition town_type.h:63
static constexpr int RATING_TUNNEL_BRIDGE_NEEDED_PERMISSIVE
"Permissive" (local authority disabled)
Definition town_type.h:64
static constexpr int RATING_TUNNEL_BRIDGE_NEEDED_NEUTRAL
"Neutral"
Definition town_type.h:62
static constexpr int RATING_ROAD_NEEDED_LENIENT
rating needed, "Lenient" difficulty settings
Definition town_type.h:69
TownSize
Supported initial town sizes.
Definition town_type.h:21
@ TSZ_RANDOM
Random size, bigger than small, smaller than large.
Definition town_type.h:25
@ TSZ_END
Number of available town sizes.
Definition town_type.h:27
@ TSZ_LARGE
Large town.
Definition town_type.h:24
static const uint MAX_LENGTH_TOWN_NAME_CHARS
The maximum length of a town name in characters including '\0'.
Definition town_type.h:119
@ Roads
Allow town to place roads.
@ Buildings
Allow town to place buildings.
static constexpr int RATING_ROAD_NEEDED_PERMISSIVE
"Permissive" (local authority disabled)
Definition town_type.h:72
static constexpr int RATING_GROWTH_MAXIMUM
... up to RATING_MEDIOCRE
Definition town_type.h:54
bool VerifyTownName(uint32_t r, const TownNameParams *par, TownNames *town_names)
Verifies the town name is valid and unique.
Definition townname.cpp:103
bool GenerateTownName(Randomizer &randomizer, uint32_t *townnameparts, TownNames *town_names)
Generates valid town name.
Definition townname.cpp:136
Town name generator stuff.
bool IsTransparencySet(TransparencyOption to)
Check if the transparency option bit is set and if we aren't in the game menu (there's never transpar...
bool IsInvisibilitySet(TransparencyOption to)
Check if the invisibility option bit is set and if we aren't in the game menu (there's never transpar...
@ TO_HOUSES
town buildings
TransportType
Available types of transport.
@ TRANSPORT_ROAD
Transport by road vehicle.
Command definitions related to tunnels and bridges.
Functions that have tunnels and bridges in common.
DiagDirection GetTunnelBridgeDirection(Tile t)
Get the direction pointing to the other end.
TransportType GetTunnelBridgeTransportType(Tile t)
Tunnel: Get the transport type of the tunnel (road or rail) Bridge: Get the transport type of the bri...
TileIndex GetOtherTunnelBridgeEnd(Tile t)
Determines type of the wormhole and returns its other end.
void AddSortableSpriteToDraw(SpriteID image, PaletteID pal, int x, int y, int 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:663
void AddChildSpriteScreen(SpriteID image, PaletteID pal, int x, int y, bool transparent, const SubSprite *sub, bool scale, bool relative)
Add a child sprite to a parent sprite.
Definition viewport.cpp:819
void DrawGroundSprite(SpriteID image, PaletteID pal, const SubSprite *sub, int extra_offs_x, int extra_offs_y)
Draws a ground sprite for the current tile.
Definition viewport.cpp:579
Functions related to (drawing on) viewports.
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:1182
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition window.cpp:3173
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:3265
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition window.cpp:3147
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: