OpenTTD Source 20260911-master-gee2b2ac12a
object_cmd.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
9
10#include "stdafx.h"
11#include "clear_map.h"
12#include "landscape.h"
13#include "command_func.h"
14#include "company_func.h"
15#include "viewport_func.h"
16#include "company_base.h"
17#include "town.h"
18#include "bridge_map.h"
19#include "genworld.h"
20#include "autoslope.h"
21#include "clear_func.h"
22#include "water.h"
23#include "window_func.h"
24#include "company_gui.h"
25#include "cheat_type.h"
26#include "object.h"
27#include "cargopacket.h"
28#include "core/random_func.hpp"
29#include "core/pool_func.hpp"
30#include "object_map.h"
31#include "object_base.h"
32#include "newgrf_config.h"
33#include "newgrf_object.h"
35#include "newgrf_debug.h"
36#include "vehicle_func.h"
37#include "station_func.h"
38#include "object_cmd.h"
39#include "landscape_cmd.h"
41
42#include "table/strings.h"
43#include "table/object_land.h"
44
45#include "safeguards.h"
46
47ObjectPool _object_pool("Object");
49/* static */ std::array<uint16_t, NUM_OBJECTS> Object::counts;
50
56/* static */ Object *Object::GetByTile(TileIndex tile)
57{
58 return Object::Get(GetObjectIndex(tile));
59}
60
72
78
89void BuildObject(ObjectType type, TileIndex tile, CompanyID owner, Town *town, uint8_t view)
90{
91 const ObjectSpec *spec = ObjectSpec::Get(type);
92
93 TileArea ta(tile, GB(spec->size, HasBit(view, 0) ? 4 : 0, 4), GB(spec->size, HasBit(view, 0) ? 0 : 4, 4));
94 Object *o = Object::Create(type, town == nullptr ? CalcClosestTownFromTile(tile) : town, ta, TimerGameCalendar::date, view);
95
96 /* If nothing owns the object, the colour will be random. Otherwise
97 * get the colour from the company's livery settings. */
98 if (owner == OWNER_NONE) {
99 o->recolour_offset = Random();
100 } else {
101 o->recolour_offset = Company::Get(owner)->GetCompanyRecolourOffset(LiveryScheme::Default);
102 }
103
104 /* If the object wants only one colour, then give it that colour. */
105 if (!spec->flags.Test(ObjectFlag::Uses2CC)) o->recolour_offset &= 0xF;
106
108 uint16_t res = GetObjectCallback(CBID_OBJECT_COLOUR, o->recolour_offset, 0, spec, o, tile);
109 if (res != CALLBACK_FAILED) {
110 if (res >= 0x100) ErrorUnknownCallbackResult(spec->grf_prop.grfid, CBID_OBJECT_COLOUR, res);
111 o->recolour_offset = GB(res, 0, 8);
112 }
113 }
114
115 assert(o->town != nullptr);
116
117 for (TileIndex t : ta) {
121 /* Update company infrastructure counts for objects build on canals owned by nobody. */
122 if (wc == WaterClass::Canal && owner != OWNER_NONE && (IsTileOwner(t, OWNER_NONE) || IsTileOwner(t, OWNER_WATER))) {
123 Company::Get(owner)->infrastructure.water++;
125 }
126 bool remove = IsDockingTile(t);
127 MakeObject(t, owner, o->index, wc, Random());
128 if (remove) RemoveDockingTile(t);
130 }
131
134}
135
141{
143 for (TileIndex t : ta) {
144 /* We encode the company HQ size in the animation state. */
147 }
148}
149
155static uint8_t GetCompanyHQSize(TileIndex tile)
156{
157 /* We encode the company HQ size in the animation state. */
158 return GetAnimationFrame(tile);
159}
160
166void UpdateCompanyHQ(TileIndex tile, uint score)
167{
168 if (tile == INVALID_TILE) return;
169
170 uint8_t val = 0;
171 if (score >= 170) val++;
172 if (score >= 350) val++;
173 if (score >= 520) val++;
174 if (score >= 720) val++;
175
176 while (GetCompanyHQSize(tile) < val) {
178 }
179}
180
186{
187 for (Object *obj : Object::Iterate()) {
188 Owner owner = GetTileOwner(obj->location.tile);
189 /* Not the current owner, so colour doesn't change. */
190 if (owner != c->index) continue;
191
192 const ObjectSpec *spec = ObjectSpec::GetByTile(obj->location.tile);
193 /* Using the object colour callback, so not using company colour. */
194 if (spec->callback_mask.Test(ObjectCallbackMask::Colour)) continue;
195
197 }
198}
199
200extern CommandCost CheckBuildableTile(TileIndex tile, DiagDirections invalid_dirs, int &allowed_z, bool allow_steep, bool check_bridge);
202
212{
214
215 if (type >= ObjectSpec::Count()) return CMD_ERROR;
216 const ObjectSpec *spec = ObjectSpec::Get(type);
217 if (_game_mode == GameMode::Normal && !spec->IsAvailable() && !_generating_world) return CMD_ERROR;
218 if ((_game_mode == GameMode::Editor || _generating_world) && !spec->WasEverAvailable()) return CMD_ERROR;
219
221 if (spec->flags.Test(ObjectFlag::OnlyInGame) && (_generating_world || _game_mode != GameMode::Normal || _current_company > MAX_COMPANIES)) return CMD_ERROR;
222 if (view >= spec->views) return CMD_ERROR;
223
224 if (!Object::CanAllocateItem()) return CommandCost(STR_ERROR_TOO_MANY_OBJECTS);
225 if (Town::GetNumItems() == 0) return CommandCost(STR_ERROR_MUST_FOUND_TOWN_FIRST);
226
227 int size_x = GB(spec->size, HasBit(view, 0) ? 4 : 0, 4);
228 int size_y = GB(spec->size, HasBit(view, 0) ? 0 : 4, 4);
229 TileArea ta(tile, size_x, size_y);
230 for (TileIndex t : ta) {
231 if (!IsValidTile(t)) return CommandCost(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP); // Might be off the map
232 }
233
234 if (type == OBJECT_OWNED_LAND) {
235 /* Owned land is special as it can be placed on any slope. */
236 cost.AddCost(Command<Commands::LandscapeClear>::Do(flags, tile));
237 } else {
238 /* Check the surface to build on. At this time we can't actually execute the
239 * the CLEAR_TILE commands since the newgrf callback later on can check
240 * some information about the tiles. */
241 bool allow_water = spec->flags.Any({ObjectFlag::BuiltOnWater, ObjectFlag::NotOnLand});
242 bool allow_ground = !spec->flags.Test(ObjectFlag::NotOnLand);
243 for (TileIndex t : ta) {
244 if (HasTileWaterGround(t)) {
245 if (!allow_water) return CommandCost(STR_ERROR_CAN_T_BUILD_ON_WATER);
246 if (!IsWaterTile(t)) {
247 /* Normal water tiles don't have to be cleared. For all other tile types clear
248 * the tile but leave the water. */
249 cost.AddCost(Command<Commands::LandscapeClear>::Do(DoCommandFlags{flags}.Reset({DoCommandFlag::NoWater, DoCommandFlag::Execute}), t));
250 } else {
251 /* Can't build on water owned by another company. */
252 Owner o = GetTileOwner(t);
253 if (o != OWNER_NONE && o != OWNER_WATER) cost.AddCost(CheckOwnership(o, t));
254
255 /* If freeform edges are disabled, don't allow building on edge tiles. */
256 if (!_settings_game.construction.freeform_edges && (!IsInsideMM(TileX(t), 1, Map::MaxX() - 1) || !IsInsideMM(TileY(t), 1, Map::MaxY() - 1))) {
257 return CommandCost(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP);
258 }
259
260 /* However, the tile has to be clear of vehicles. */
262 }
263 } else {
264 if (!allow_ground) return CommandCost(STR_ERROR_MUST_BE_BUILT_ON_WATER);
265 /* For non-water tiles, we'll have to clear it before building. */
266
267 /* When relocating HQ, allow it to be relocated (partial) on itself. */
268 if (!(type == OBJECT_HQ &&
271 IsObjectType(t, OBJECT_HQ))) {
272 cost.AddCost(Command<Commands::LandscapeClear>::Do(DoCommandFlags{flags}.Reset(DoCommandFlag::Execute), t));
273 }
274 }
275 }
276
277 /* So, now the surface is checked... check the slope of said surface. */
278 auto [slope, allowed_z] = GetTileSlopeZ(tile);
279 if (slope != SLOPE_FLAT) allowed_z++;
280
281 for (TileIndex t : ta) {
282 uint16_t callback = CALLBACK_FAILED;
283 std::array<int32_t, 16> regs100;
285 TileIndex diff = t - tile;
286 callback = GetObjectCallback(CBID_OBJECT_LAND_SLOPE_CHECK, GetTileSlope(t), TileY(diff) << 4 | TileX(diff), spec, nullptr, t, regs100, view);
287 }
288
289 if (callback == CALLBACK_FAILED) {
290 cost.AddCost(CheckBuildableTile(t, {}, allowed_z, false, false));
291 } else {
292 /* The meaning of bit 10 is inverted for a grf version < 8. */
293 if (spec->grf_prop.grffile->grf_version < 8) ToggleBit(callback, 10);
294 CommandCost ret = GetErrorMessageFromLocationCallbackResult(callback, regs100, spec->grf_prop.grffile, STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
295 if (ret.Failed()) return ret;
296 }
297 }
298
299 if (flags.Test(DoCommandFlag::Execute)) {
300 /* This is basically a copy of the loop above with the exception that we now
301 * execute the commands and don't check for errors, since that's already done. */
302 for (TileIndex t : ta) {
303 if (HasTileWaterGround(t)) {
304 if (!IsWaterTile(t)) {
305 Command<Commands::LandscapeClear>::Do(DoCommandFlags{flags}.Reset(DoCommandFlag::NoWater), t);
306 }
307 } else {
308 Command<Commands::LandscapeClear>::Do(flags, t);
309 }
310 }
311 }
312 }
313 if (cost.Failed()) return cost;
314
315 /* Finally do a check for bridges. */
316 for (TileIndex t : ta) {
317 if (IsBridgeAbove(t)) {
318 if (!spec->flags.Test(ObjectFlag::AllowUnderBridge)) return CommandCost(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
319
320 int height_diff = GetTileMaxZ(t) + spec->height - GetBridgeHeight(GetSouthernBridgeEnd(t));
321 if (height_diff > 0) return CommandCostWithParam(STR_ERROR_BRIDGE_TOO_LOW_FOR_OBJECT, height_diff * TILE_HEIGHT_STEP);
322 }
323 }
324
325 int hq_score = 0;
326 uint build_object_size = 1;
327 switch (type) {
330 if (!IsTileFlat(tile)) return CommandCost(STR_ERROR_FLAT_LAND_REQUIRED);
331 break;
332
334 if (IsTileType(tile, TileType::Object) &&
337 return CommandCost(STR_ERROR_YOU_ALREADY_OWN_IT);
338 }
339 break;
340
341 case OBJECT_HQ: {
343 if (c->location_of_HQ != INVALID_TILE) {
344 /* Don't relocate HQ on the same location. */
345 if (c->location_of_HQ == tile) return CommandCost(STR_ERROR_ALREADY_BUILT);
346 /* We need to persuade a bit harder to remove the old HQ. */
348 cost.AddCost(ClearTile_Object(c->location_of_HQ, flags));
349 _current_company = c->index;
350 }
351
352 if (flags.Test(DoCommandFlag::Execute)) {
353 hq_score = UpdateCompanyRatingAndValue(c, false);
354 c->location_of_HQ = tile;
355 SetWindowDirty(WindowClass::Company, c->index);
356 }
357 break;
358 }
359
360 case OBJECT_STATUE:
361 /* This may never be constructed using this method. */
362 return CMD_ERROR;
363
364 default: // i.e. NewGRF provided.
365 build_object_size = size_x * size_y;
366 break;
367 }
368
369 /* Don't allow building more objects if the company has reached its limit. */
371 if (c != nullptr && GB(c->build_object_limit, 16, 16) < build_object_size) {
372 return CommandCost(STR_ERROR_BUILD_OBJECT_LIMIT_REACHED);
373 }
374
375 if (flags.Test(DoCommandFlag::Execute)) {
376 BuildObject(type, tile, _current_company == OWNER_DEITY ? OWNER_NONE : _current_company, nullptr, view);
377
378 /* Make sure the HQ starts at the right size. */
379 if (type == OBJECT_HQ) UpdateCompanyHQ(tile, hq_score);
380
381 /* Subtract the tile from the build limit. */
382 if (c != nullptr) c->build_object_limit -= build_object_size << 16;
383 }
384
385 cost.AddCost(spec->GetBuildCost() * build_object_size);
386 return cost;
387}
388
399CommandCost CmdBuildObjectArea(DoCommandFlags flags, TileIndex tile, TileIndex start_tile, ObjectType type, uint8_t view, bool diagonal)
400{
401 if (start_tile >= Map::Size()) return CMD_ERROR;
402
403 if (type >= ObjectSpec::Count()) return CMD_ERROR;
404 const ObjectSpec *spec = ObjectSpec::Get(type);
405 if (view >= spec->views) return CMD_ERROR;
406
407 if (spec->size != OBJECT_SIZE_1X1) return CMD_ERROR;
408
409 Money money = GetAvailableMoneyForCommand();
411 CommandCost last_error = CMD_ERROR;
412 bool had_success = false;
413
415 int limit = (c == nullptr ? INT32_MAX : GB(c->build_object_limit, 16, 16));
416
417 std::unique_ptr<TileIterator> iter = TileIterator::Create(tile, start_tile, diagonal);
418 for (; *iter != INVALID_TILE; ++(*iter)) {
419 TileIndex t = *iter;
420 CommandCost ret = Command<Commands::BuildObject>::Do(DoCommandFlags{flags}.Reset(DoCommandFlag::Execute), t, type, view);
421
422 /* If we've reached the limit, stop building (or testing). */
423 if (c != nullptr && limit-- <= 0) break;
424
425 if (ret.Failed()) {
426 last_error = std::move(ret);
427 continue;
428 }
429
430 had_success = true;
431 if (flags.Test(DoCommandFlag::Execute)) {
432 money -= ret.GetCost();
433
434 /* If we run out of money, stop building. */
435 if (ret.GetCost() > 0 && money < 0) break;
436 Command<Commands::BuildObject>::Do(flags, t, type, view);
437 }
438 cost.AddCost(ret.GetCost());
439 }
440
441 return had_success ? cost : last_error;
442}
443
450
452static void DrawTile_Object(TileInfo *ti)
453{
454 ObjectType type = GetObjectType(ti->tile);
455 const ObjectSpec *spec = ObjectSpec::Get(type);
456
457 /* Fall back for when the object doesn't exist anymore. */
458 if (!spec->IsEnabled()) type = OBJECT_TRANSMITTER;
459
461
462 if (type < NEW_OBJECT_OFFSET) {
463 const DrawTileSprites *dts = nullptr;
464 Owner to = GetTileOwner(ti->tile);
465 PaletteID palette = to == OWNER_NONE ? PAL_NONE : GetCompanyPalette(to);
466
467 if (type == OBJECT_HQ) {
469 dts = &_object_hq[GetCompanyHQSize(ti->tile) << 2 | TileY(diff) << 1 | TileX(diff)];
470 } else {
471 dts = &_objects[type];
472 }
473
475 /* If an object has no foundation, but tries to draw a (flat) ground
476 * type... we have to be nice and convert that for them. */
477 switch (dts->ground.sprite) {
478 case SPR_FLAT_BARE_LAND: DrawClearLandTile(ti, 0); break;
481 case SPR_FLAT_GRASS_TILE: DrawClearLandTile(ti, 3); break;
482 default: DrawGroundSprite(dts->ground.sprite, palette); break;
483 }
484 } else {
485 DrawGroundSprite(dts->ground.sprite, palette);
486 }
487
489 for (const DrawTileSeqStruct &dtss : dts->GetSequence()) {
490 AddSortableSpriteToDraw(dtss.image.sprite, palette, *ti, dtss, IsTransparencySet(TransparencyOption::Structures));
491 }
492 }
493 } else {
494 DrawNewObjectTile(ti, spec);
495 }
496
497 DrawBridgeMiddle(ti, {});
498}
499
501static int GetSlopePixelZ_Object(TileIndex tile, uint x, uint y, [[maybe_unused]] bool ground_vehicle)
502{
503 if (IsObjectType(tile, OBJECT_OWNED_LAND)) {
504 auto [tileh, z] = GetTilePixelSlope(tile);
505
506 return z + GetPartialPixelZ(x & 0xF, y & 0xF, tileh);
507 } else {
508 return GetTileMaxPixelZ(tile);
509 }
510}
511
517{
519 for (TileIndex tile_cur : o->location) {
521
522 MakeWaterKeepingClass(tile_cur, GetTileOwner(tile_cur));
523 }
524 delete o;
525}
526
527std::vector<ClearedObjectArea> _cleared_object_areas;
528
535{
536 TileArea ta = TileArea(tile, 1, 1);
537
538 for (ClearedObjectArea &coa : _cleared_object_areas) {
539 if (coa.area.Intersects(ta)) return &coa;
540 }
541
542 return nullptr;
543}
544
547{
548 /* Get to the northern most tile. */
549 Object *o = Object::GetByTile(tile);
550 TileArea ta = o->location;
551
552 ObjectType type = o->type;
553 const ObjectSpec *spec = ObjectSpec::Get(type);
554
555 CommandCost cost(ExpensesType::Construction, spec->GetClearCost() * ta.w * ta.h / 5);
556 if (spec->flags.Test(ObjectFlag::ClearIncome)) cost.MultiplyCost(-1); // They get an income!
557
558 /* Towns can't remove any objects. */
560
561 /* Water can remove everything! */
563 if (flags.Test(DoCommandFlag::NoWater) && IsTileOnWater(tile)) {
564 /* There is water under the object, treat it as water tile. */
565 return CommandCost(STR_ERROR_CAN_T_BUILD_ON_WATER);
566 } else if (!spec->flags.Test(ObjectFlag::Autoremove) && flags.Test(DoCommandFlag::Auto)) {
567 /* No automatic removal by overbuilding stuff. */
568 return CommandCost(type == OBJECT_HQ ? STR_ERROR_COMPANY_HEADQUARTERS_IN : STR_ERROR_OBJECT_IN_THE_WAY);
569 } else if (_game_mode == GameMode::Editor) {
570 /* No further limitations for the editor. */
571 } else if (GetTileOwner(tile) == OWNER_NONE) {
572 /* Owned by nobody and unremovable, so we can only remove it with brute force! */
573 if (!_cheats.magic_bulldozer.value && spec->flags.Test(ObjectFlag::CannotRemove)) return CMD_ERROR;
574 } else if (CommandCost ret = CheckTileOwnership(tile); ret.Failed()) {
575 /* We don't own it!. */
576 return ret;
578 /* In the game editor or with cheats we can remove, otherwise we can't. */
579 if (!_cheats.magic_bulldozer.value) {
580 if (type == OBJECT_HQ) return CommandCost(STR_ERROR_COMPANY_HEADQUARTERS_IN);
581 return CMD_ERROR;
582 }
583
584 /* Removing with the cheat costs more in TTDPatch / the specs. */
585 cost.MultiplyCost(25);
586 }
587 } else if (spec->flags.Any({ObjectFlag::BuiltOnWater, ObjectFlag::NotOnLand})) {
588 /* Water can't remove objects that are buildable on water. */
589 return CMD_ERROR;
590 }
591
592 switch (type) {
593 case OBJECT_HQ: {
595 if (flags.Test(DoCommandFlag::Execute)) {
596 c->location_of_HQ = INVALID_TILE; // reset HQ position
597 SetWindowDirty(WindowClass::Company, c->index);
599 }
600
601 /* cost of relocating company is 1% of company value */
603 break;
604 }
605
606 case OBJECT_STATUE:
607 if (flags.Test(DoCommandFlag::Execute)) {
608 Town *town = o->town;
609 town->statues.Reset(GetTileOwner(tile));
610 SetWindowDirty(WindowClass::TownAuthority, town->index);
611 }
612 break;
613
614 default:
615 break;
616 }
617
618 _cleared_object_areas.emplace_back(tile, ta);
619
621
622 return cost;
623}
624
626static void AddAcceptedCargo_Object(TileIndex tile, CargoArray &acceptance, CargoTypes &always_accepted)
627{
628 if (!IsObjectType(tile, OBJECT_HQ)) return;
629
630 /* HQ accepts passenger and mail; but we have to divide the values
631 * between 4 tiles it occupies! */
632
633 /* HQ level (depends on company performance) in the range 1..5. */
634 uint level = GetCompanyHQSize(tile) + 1;
635
636 /* Top town building generates 10, so to make HQ interesting, the top
637 * type makes 20. */
638 CargoType pass = GetCargoTypeByLabel(CT_PASSENGERS);
639 if (IsValidCargoType(pass)) {
640 acceptance[pass] += std::max(1U, level);
641 always_accepted.Set(pass);
642 }
643
644 /* Top town building generates 4, HQ can make up to 8. The
645 * proportion passengers:mail is different because such a huge
646 * commercial building generates unusually high amount of mail
647 * correspondence per physical visitor. */
648 CargoType mail = GetCargoTypeByLabel(CT_MAIL);
649 if (IsValidCargoType(mail)) {
650 acceptance[mail] += std::max(1U, level / 2);
651 always_accepted.Set(mail);
652 }
653}
654
656static void AddProducedCargo_Object(TileIndex tile, CargoArray &produced)
657{
658 if (!IsObjectType(tile, OBJECT_HQ)) return;
659
660 CargoType pass = GetCargoTypeByLabel(CT_PASSENGERS);
661 if (IsValidCargoType(pass)) produced[pass]++;
662 CargoType mail = GetCargoTypeByLabel(CT_MAIL);
663 if (IsValidCargoType(mail)) produced[mail]++;
664}
665
666
669{
670 const ObjectSpec *spec = ObjectSpec::GetByTile(tile);
671 td.str = spec->name;
672 td.owner[0] = GetTileOwner(tile);
674
675 if (spec->grf_prop.HasGrfFile()) {
676 td.grf = GetGRFConfig(spec->grf_prop.grfid)->GetName();
677 }
678}
679
681static void TileLoop_Object(TileIndex tile)
682{
683 const ObjectSpec *spec = ObjectSpec::GetByTile(tile);
684 if (spec->flags.Test(ObjectFlag::Animation)) {
685 Object *o = Object::GetByTile(tile);
688 }
689
690 if (IsTileOnWater(tile)) TileLoop_Water(tile);
691
692 if (!IsObjectType(tile, OBJECT_HQ)) return;
693
694 /* HQ accepts passenger and mail; but we have to divide the values
695 * between 4 tiles it occupies! */
696
697 /* HQ level (depends on company performance) in the range 1..5. */
698 uint level = GetCompanyHQSize(tile) + 1;
699 assert(level < 6);
700
701 StationFinder stations(TileArea(tile, 2, 2));
702
703 uint r = Random();
704 /* Top town buildings generate 250, so the top HQ type makes 256. */
705 CargoType pass = GetCargoTypeByLabel(CT_PASSENGERS);
706 if (IsValidCargoType(pass) && GB(r, 0, 8) < (256 / 4 / (6 - level))) {
707 uint amt = GB(r, 0, 8) / 8 / 4 + 1;
708
709 /* Production is halved during recessions. */
710 if (EconomyIsInRecession()) amt = (amt + 1) >> 1;
711
712 /* Scale by cargo scale setting. */
713 amt = ScaleByCargoScale(amt, true);
714
715 MoveGoodsToStation(pass, amt, {GetTileOwner(tile), SourceType::Headquarters}, stations.GetStations());
716 }
717
718 /* Top town building generates 90, HQ can make up to 196. The
719 * proportion passengers:mail is about the same as in the acceptance
720 * equations. */
721 CargoType mail = GetCargoTypeByLabel(CT_MAIL);
722 if (IsValidCargoType(mail) && GB(r, 8, 8) < (196 / 4 / (6 - level))) {
723 uint amt = GB(r, 8, 8) / 8 / 4 + 1;
724
725 /* Production is halved during recessions. */
726 if (EconomyIsInRecession()) amt = (amt + 1) >> 1;
727
728 /* Scale by cargo scale setting. */
729 amt = ScaleByCargoScale(amt, true);
730
731 MoveGoodsToStation(mail, amt, {GetTileOwner(tile), SourceType::Headquarters}, stations.GetStations());
732 }
733}
734
735
738{
739 if (!IsObjectType(tile, OBJECT_HQ)) return false;
740
742 return true;
743}
744
751{
752 if (!Object::CanAllocateItem()) return false;
753 if (!IsValidTile(coast_tile)) return false;
754
755 /* We always start on a coast tile. */
756 if (!IsTileType(coast_tile, TileType::Water) || GetWaterTileType(coast_tile) != WaterTileType::Coast) return false;
757
758 /* Don't build near another lighthouse. */
759 constexpr uint LIGHTHOUSE_MIN_DISTANCE_DIAMETER = 16 * 2 + 1; // 16 tile radius, plus middle tile.
760 for (auto t : SpiralTileSequence(coast_tile, LIGHTHOUSE_MIN_DISTANCE_DIAMETER)) {
761 if (IsObjectTypeTile(t, OBJECT_LIGHTHOUSE)) return false;
762 }
763
764 /* Find a suitable tile nearby to build. */
765 for (TileIndex build_tile : SpiralTileSequence(coast_tile, 3)) {
766 if (!IsTileType(build_tile, TileType::Clear) || !IsTileFlat(build_tile) || IsBridgeAbove(build_tile)) continue;
767 BuildObject(OBJECT_LIGHTHOUSE, build_tile);
768
769 /* Generate rocks from each coast tile surrounding the chosen coast tile. This is done because we don't have
770 * control of the direction of GenerateRocks, so this gives more chance for rocks to be generated in water. */
771 uint32_t r = Random();
772 for (TileIndex rock_tile : SpiralTileSequence(coast_tile, 3)) {
773 if (!IsCoastTile(rock_tile)) continue;
774 GenerateRocks(rock_tile, GB(r, 0, 4) + 5);
775 r >>= 4;
776 }
777
778 return true;
779 }
780
781 return false;
782}
783
788static void TryBuildTownLighthouse(Town *town)
789{
790 TileIndex start_tile = town->xy;
791
792 /* As a sanity check to speed up generation, a town in the mountains is unlikely to have a lighthouse. */
793 if (GetTileZ(start_tile) > 4) return;
794
795 /* Create a perimeter a random distance around the town to search. */
797 radius = std::sqrt(radius);
798 radius += RandomRange(radius);
799
800 /* Find the northern tile of the perimeter for the SpiralTileSequence. */
801 start_tile = TileAddWrap(town->xy, -radius, -radius);
802 if (!IsValidTile(start_tile)) return;
803
804 /* Search the perimeter for a suitable tile. */
805 for (TileIndex coast_tile : SpiralTileSequence(start_tile, 1, radius * 2, radius * 2)) {
806 if (TryBuildLighthouseNearTile(coast_tile)) return;
807 }
808}
809
814{
815 for (Town *town : Town::Iterate()) {
817 }
818}
819
825{
826 uint maxx = Map::MaxX();
827 uint maxy = Map::MaxY();
828 uint r = Random();
829
830 /* Pick a random perimeter tile to start from. */
831 int perimeter = (GB(r, 16, 16) % (2 * (maxx + maxy))) - maxy;
832 DiagDirection dir;
833 for (dir = DiagDirection::NE; perimeter > 0; dir++) {
834 perimeter -= (DiagDirToAxis(dir) == Axis::X) ? maxx : maxy;
835 }
836
837 TileIndex tile;
838 switch (dir) {
839 default:
840 case DiagDirection::NE: tile = TileXY(maxx - 1, r % maxy); break;
841 case DiagDirection::SE: tile = TileXY(r % maxx, 1); break;
842 case DiagDirection::SW: tile = TileXY(1, r % maxy); break;
843 case DiagDirection::NW: tile = TileXY(r % maxx, maxy - 1); break;
844 }
845
846 /* Now walk inwards until we find a valid tile, or hit the other edge of the map. */
847 while (IsValidTile(tile)) {
848 if (TryBuildLighthouseNearTile(tile)) return true;
849 tile += TileOffsByDiagDir(dir);
850 }
851
852 return false;
853}
854
859static void BuildCoastLighthouses(uint16_t amount)
860{
861 for (uint j = amount; j != 0; j--) {
863 }
864}
865
871{
872 TileIndex tile = RandomTile();
873 int h;
874 if (IsTileType(tile, TileType::Clear) && IsTileFlat(tile, &h) && h >= 4 && !IsBridgeAbove(tile)) {
875 for (auto t : SpiralTileSequence(tile, 9)) {
876 if (IsObjectTypeTile(t, OBJECT_TRANSMITTER)) return false;
877 }
879 return true;
880 }
881 return false;
882}
883
888{
889 /* Set a guestimate on how much we progress */
890 SetGeneratingWorldProgress(GenWorldProgress::Objects, static_cast<uint>(ObjectSpec::Count()));
891
892 /* Determine number of water tiles at map border needed for freeform_edges */
893 uint num_water_tiles = 0;
894 if (_settings_game.construction.freeform_edges) {
895 for (uint x = 0; x < Map::MaxX(); x++) {
896 if (IsTileType(TileXY(x, 1), TileType::Water)) num_water_tiles++;
897 if (IsTileType(TileXY(x, Map::MaxY() - 1), TileType::Water)) num_water_tiles++;
898 }
899 for (uint y = 1; y < Map::MaxY() - 1; y++) {
900 if (IsTileType(TileXY(1, y), TileType::Water)) num_water_tiles++;
901 if (IsTileType(TileXY(Map::MaxX() - 1, y), TileType::Water)) num_water_tiles++;
902 }
903 }
904
905 /* Iterate over all possible object types */
906 for (const auto &spec : ObjectSpec::Specs()) {
907
908 /* Continue, if the object was never available till now or shall not be placed */
909 if (!spec.WasEverAvailable() || spec.generate_amount == 0) continue;
910
911 uint16_t amount = spec.generate_amount;
912
913 /* Scale by map size */
914 if (spec.flags.Test(ObjectFlag::ScaleByWater) && _settings_game.construction.freeform_edges) {
915 /* Maybe scale the object count by the amount of land at the borders.
916 * The -6 is because the top borders are TileType::Void (-2) and all corners
917 * are counted twice (-4). */
918 amount = Map::ScaleBySize1D(amount * num_water_tiles) / (2 * Map::MaxY() + 2 * Map::MaxX() - 6);
919 } else if (spec.flags.Test(ObjectFlag::ScaleByWater)) {
920 amount = Map::ScaleBySize1D(amount);
921 } else {
922 amount = Map::ScaleBySize(amount);
923 }
924
925 /* Ready to place objects. */
926 switch (spec.Index()) {
928 for (uint j = Map::ScaleBySize(1000); j != 0 && amount != 0 && Object::CanAllocateItem(); j--) {
929 if (TryBuildTransmitter()) amount--;
930 }
931 break;
932
935 BuildCoastLighthouses(amount);
936 break;
937
938 default:
939 for (uint j = Map::ScaleBySize(1000); j != 0 && amount != 0 && Object::CanAllocateItem(); j--) {
940 uint8_t view = RandomRange(spec.views);
942 }
943 break;
944 }
946 }
947}
948
950static void ChangeTileOwner_Object(TileIndex tile, Owner old_owner, Owner new_owner)
951{
952 if (!IsTileOwner(tile, old_owner)) return;
953
954 bool do_clear = false;
955
956 ObjectType type = GetObjectType(tile);
957 if ((type == OBJECT_OWNED_LAND || type >= NEW_OBJECT_OFFSET) && new_owner != INVALID_OWNER) {
958 SetTileOwner(tile, new_owner);
959 if (GetWaterClass(tile) == WaterClass::Canal) {
960 Company::Get(old_owner)->infrastructure.water--;
961 Company::Get(new_owner)->infrastructure.water++;
962 }
963 } else if (type == OBJECT_STATUE) {
964 Town *t = Object::GetByTile(tile)->town;
965 t->statues.Reset(old_owner);
966 if (new_owner != INVALID_OWNER && !t->statues.Test(new_owner)) {
967 /* Transfer ownership to the new company */
968 t->statues.Set(new_owner);
969 SetTileOwner(tile, new_owner);
970 } else {
971 do_clear = true;
972 }
973
974 SetWindowDirty(WindowClass::TownAuthority, t->index);
975 } else {
976 do_clear = true;
977 }
978
979 if (do_clear) {
981 /* When clearing objects, they may turn into canal, which may require transferring ownership. */
982 ChangeTileOwner(tile, old_owner, new_owner);
983 }
984}
985
987static CommandCost TerraformTile_Object(TileIndex tile, DoCommandFlags flags, int z_new, Slope tileh_new)
988{
989 ObjectType type = GetObjectType(tile);
990
991 if (type == OBJECT_OWNED_LAND) {
992 /* Owned land remains unsold */
994 if (ret.Succeeded()) return CommandCost();
995 } else if (AutoslopeEnabled() && type != OBJECT_TRANSMITTER && type != OBJECT_LIGHTHOUSE) {
996 /* Behaviour:
997 * - Both new and old slope must not be steep.
998 * - TileMaxZ must not be changed.
999 * - Allow autoslope by default.
1000 * - Disallow autoslope if callback succeeds and returns non-zero.
1001 */
1002 Slope tileh_old = GetTileSlope(tile);
1003 /* TileMaxZ must not be changed. Slopes must not be steep. */
1004 if (!IsSteepSlope(tileh_old) && !IsSteepSlope(tileh_new) && (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) {
1005 const ObjectSpec *spec = ObjectSpec::Get(type);
1006
1007 /* Call callback 'disable autosloping for objects'. */
1009 /* If the callback fails, allow autoslope. */
1010 uint16_t res = GetObjectCallback(CBID_OBJECT_AUTOSLOPE, 0, 0, spec, Object::GetByTile(tile), tile);
1012 } else if (spec->IsEnabled()) {
1013 /* allow autoslope */
1015 }
1016 }
1017 }
1018
1019 return Command<Commands::LandscapeClear>::Do(flags, tile);
1020}
1021
1023static CommandCost CheckBuildAbove_Object(TileIndex tile, DoCommandFlags flags, [[maybe_unused]] Axis axis, int height)
1024{
1025 const ObjectSpec *spec = ObjectSpec::GetByTile(tile);
1026 if (!spec->flags.Test(ObjectFlag::AllowUnderBridge)) return Command<Commands::LandscapeClear>::Do(flags, tile);
1027
1028 int height_diff = GetTileMaxZ(tile) + spec->height - height;
1029 if (height_diff > 0) return CommandCostWithParam(STR_ERROR_BRIDGE_TOO_LOW_FOR_OBJECT, height_diff * TILE_HEIGHT_STEP);
1030 return CommandCost();
1031}
1032
1035 .draw_tile_proc = DrawTile_Object,
1036 .get_slope_pixel_z_proc = GetSlopePixelZ_Object,
1037 .clear_tile_proc = ClearTile_Object,
1038 .add_accepted_cargo_proc = AddAcceptedCargo_Object,
1039 .get_tile_desc_proc = GetTileDesc_Object,
1040 .click_tile_proc = ClickTile_Object,
1041 .animate_tile_proc = [](TileIndex tile) { AnimateNewObjectTile(tile); },
1042 .tile_loop_proc = TileLoop_Object,
1043 .change_tile_owner_proc = ChangeTileOwner_Object,
1044 .add_produced_cargo_proc = AddProducedCargo_Object,
1045 .get_foundation_proc = GetFoundation_Object,
1046 .terraform_tile_proc = TerraformTile_Object,
1047 .check_build_above_proc = CheckBuildAbove_Object,
1048};
Functions related to autoslope.
bool AutoslopeEnabled()
Tests if autoslope is enabled for _current_company.
Definition autoslope.h:65
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 bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
constexpr T ToggleBit(T &x, const uint8_t y)
Toggles a bit in a variable.
void DrawBridgeMiddle(const TileInfo *ti, BridgePillarFlags blocked_pillars)
Draw the middle bits of a bridge.
TileIndex GetSouthernBridgeEnd(TileIndex t)
Finds the southern end of a bridge starting at a middle tile.
int GetBridgeHeight(TileIndex t)
Get the height ('z') of a bridge.
Map accessor functions for bridges.
bool IsBridgeAbove(Tile t)
checks if a bridge is set above the ground of this tile
Definition bridge_map.h:45
bool IsValidCargoType(CargoType cargo)
Test whether cargo type is not INVALID_CARGO.
Definition cargo_type.h:110
EnumBitSet< CargoType, uint64_t > CargoTypes
Bitset of CargoType elements.
Definition cargo_type.h:113
static constexpr CargoLabel CT_PASSENGERS
Available types of cargo Labels may be re-used between different climates.
Definition cargo_type.h:31
CargoType
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:22
Base class for cargo packets.
Cheats _cheats
All the cheats.
Definition cheat.cpp:16
Types related to cheating.
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
constexpr Timpl & Reset()
Reset all bits.
constexpr Timpl & Set()
Set all bits.
constexpr bool Any(const Timpl &other) const
Test if any of the given values are set.
Common return value for all commands.
bool Succeeded() const
Did this command succeed?
void AddCost(const Money &cost)
Adds the given cost to the cost of the command.
Money GetCost() const
The costs as made up to this moment.
bool Failed() const
Did this command fail?
void MultiplyCost(int factor)
Multiplies the cost of the command by the given factor.
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 std::unique_ptr< TileIterator > Create(TileIndex corner1, TileIndex corner2, bool diagonal)
Create either an OrthogonalTileIterator or DiagonalTileIterator given the diagonal parameter.
Definition tilearea.cpp:292
Wrapper class to abstract away the way the tiles are stored.
Definition map_func.h:25
static Date date
Current date in days (day counter).
void DrawClearLandTile(const TileInfo *ti, uint8_t density)
Draw a ClearGround::Grass tile.
Definition clear_cmd.cpp:61
void GenerateRocks(TileIndex tile, uint32_t count)
Generate a cluster of rocks.
Functions related to clear (TileType::Clear) land.
Map accessors for 'clear' tiles.
CommandCost CommandCostWithParam(StringID str, uint64_t value)
Return an error status, with string and parameter.
Definition command.cpp:416
Functions related to commands.
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
@ Auto
don't allow building on structures
@ NoModifyTownRating
do not change town rating
@ NoWater
don't allow building on water
@ Execute
execute the given command
@ NoTestTownRating
town rating does not disallow you from building
EnumBitSet< DoCommandFlag, uint16_t > DoCommandFlags
Bitset of DoCommandFlag elements.
Definition of stuff that is very close to a company, like the company struct itself.
Money CalculateCompanyValue(const Company *c, bool including_loan=true)
Calculate the value of the company.
Definition economy.cpp:151
CommandCost CheckTileOwnership(TileIndex tile)
Check whether the current owner owns the stuff on the given tile.
PaletteID GetCompanyPalette(CompanyID company)
Get the palette for recolouring with a company colour.
Money GetAvailableMoneyForCommand()
This functions returns the money which can be used to execute a command.
CommandCost CheckOwnership(Owner owner, TileIndex tile)
Check whether the current owner owns something.
CompanyID _current_company
Company currently doing an action.
Functions related to companies.
void ShowCompany(CompanyID company)
Show the window with the overview of the company.
void DirtyCompanyInfrastructureWindows(CompanyID company)
Redraw all windows with company infrastructure counts.
GUI Functions related to companies.
static constexpr Owner OWNER_DEITY
The object is owned by a superuser / goal script.
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.
static constexpr Owner INVALID_OWNER
An invalid owner.
static constexpr Owner OWNER_WATER
The tile/execution is done by "water".
Axis DiagDirToAxis(DiagDirection d)
Convert a DiagDirection to the axis.
Axis
Enumeration for the two axis X and Y.
@ X
The X axis.
DiagDirection
Enumeration for diagonal directions.
@ SW
Southwest.
@ NW
Northwest.
@ NE
Northeast, upper right on your monitor.
@ SE
Southeast.
EnumBitSet< DiagDirection, uint8_t > DiagDirections
Bitset of DiagDirection elements.
int UpdateCompanyRatingAndValue(Company *c, bool update)
if update is set to true, the economy is updated with this score (also the house is updated,...
Definition economy.cpp:203
Prices _price
Prices and also the fractional part.
Definition economy.cpp:107
bool EconomyIsInRecession()
Is the economy in recession?
uint ScaleByCargoScale(uint num, bool town)
Scale a number by the cargo scale setting.
@ Construction
Construction costs.
@ BuildFoundation
Price for building foundation under other constructions e.g. roads, rails, depots,...
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23).
Definition enum_type.hpp:21
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.
@ Objects
Generate objects (radio tower, light houses).
Definition genworld.h:67
void SetGeneratingWorldProgress(GenWorldProgress cls, uint total)
Set the total of a stage of the world generation.
uint32_t PaletteID
The number of the palette.
Definition gfx_type.h:18
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_height_override)
Mark a tile given by its index dirty for repaint.
@ TownEdge
Edge of the town; roads without pavement.
Definition house.h:60
uint GetPartialPixelZ(int x, int y, Slope corners)
Determines height at given coordinate of a slope.
void ChangeTileOwner(TileIndex tile, Owner old_owner, Owner new_owner)
Change the owner of a tile.
void DrawFoundation(TileInfo *ti, Foundation f)
Draw foundation f at tile ti.
const TileTypeProcs _tile_type_object_procs
TileTypeProcs definitions for TileType::Object tiles.
Definition landscape.cpp:62
Functions related to OTTD's landscape.
Command definitions related to landscape (slopes etc.).
@ Default
Default scheme.
Definition livery.h:24
TileIndex TileAddWrap(TileIndex tile, int addx, int addy)
This function checks if we add addx/addy to tile, if we do wrap around the edges.
Definition map.cpp:120
static TileIndex TileXY(uint x, uint y)
Returns the TileIndex of a coordinate.
Definition map_func.h:376
static uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition map_func.h:429
static uint TileX(TileIndex tile)
Get the X component of a tile.
Definition map_func.h:419
#define RandomTile()
Get a valid random tile.
Definition map_func.h:656
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition map_func.h:574
constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
@ Objects
Objects feature.
Definition newgrf.h:95
@ CBID_OBJECT_LAND_SLOPE_CHECK
Callback done for each tile of an object to check the slope.
@ CBID_OBJECT_AUTOSLOPE
Called to determine if one can alter the ground below an object tile.
@ CBID_OBJECT_COLOUR
Called to determine the colour of a town building.
@ Autoslope
decides allowance of autosloping
@ Colour
decide the colour of the building
@ SlopeCheck
decides slope suitability
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
CommandCost GetErrorMessageFromLocationCallbackResult(uint16_t cb_res, std::span< const int32_t > textstack, const GRFFile *grffile, StringID default_error)
Get the error message from a shape/location/slope check callback result.
bool ConvertBooleanCallback(const GRFFile *grffile, uint16_t cbid, uint16_t cb_res)
Converts a callback result into a boolean.
void ErrorUnknownCallbackResult(GrfID grfid, uint16_t cbid, uint16_t cb_res)
Record that a NewGRF returned an unknown/invalid callback result.
GRFConfig * GetGRFConfig(GrfID grfid, uint32_t mask)
Retrieve a NewGRF from the current config by its grfid.
Functions to find and configure NewGRFs.
Functions/types related to NewGRF debugging.
void DeleteNewGRFInspectWindow(GrfSpecFeature feature, uint index)
Delete inspect window for a given feature and index.
void DrawNewObjectTile(TileInfo *ti, const ObjectSpec *spec)
Draw an object on the map.
bool TriggerObjectAnimation(Object *o, ObjectAnimationTrigger trigger, const ObjectSpec *spec)
Trigger the update of animation on a whole object.
bool TriggerObjectTileAnimation(Object *o, TileIndex tile, ObjectAnimationTrigger trigger, const ObjectSpec *spec)
Trigger the update of animation on a single tile.
void AnimateNewObjectTile(TileIndex tile)
Handle the animation of the object tile.
uint16_t GetObjectCallback(CallbackID callback, uint32_t param1, uint32_t param2, const ObjectSpec *spec, Object *o, TileIndex tile, std::span< int32_t > regs100, uint8_t view)
Perform a callback for an object.
Functions related to NewGRF objects.
static const uint8_t OBJECT_SIZE_1X1
The value of a NewGRF's size property when the object is 1x1 tiles: low nibble for X,...
@ Autoremove
Object get automatically removed (like "owned land").
@ CannotRemove
Object can not be removed.
@ AllowUnderBridge
Object can built under a bridge.
@ OnlyInScenedit
Object can only be constructed in the scenario editor.
@ BuiltOnWater
Object can be built on water (not required).
@ OnlyInGame
Object can only be built in game.
@ HasNoFoundation
Do not display foundations when on a slope.
@ Uses2CC
Object wants 2CC colour mapping.
@ NotOnLand
Object can not be on land, implicitly sets ObjectFlag::BuiltOnWater.
@ ScaleByWater
Object count is roughly scaled by water amount at edges.
@ Animation
Object has animated tiles.
@ ClearIncome
When object is cleared a positive income is generated instead of a cost.
Functions related to objects.
Base for all objects.
static void DrawTile_Object(TileInfo *ti)
Tile callback function signature for drawing a tile and its contents to the screen.
void UpdateObjectColours(const Company *c)
Updates the colour of the object whenever a company changes.
static int GetSlopePixelZ_Object(TileIndex tile, uint x, uint y, bool ground_vehicle)
Tile callback function signature for obtaining the world Z coordinate of a given point of a tile.
static bool ClickTile_Object(TileIndex tile)
Tile callback function signature for clicking a tile.
static bool TryBuildLighthouseNearTile(TileIndex coast_tile)
Try to build a lighthouse near a coast tile.
void BuildObject(ObjectType type, TileIndex tile, CompanyID owner, Town *town, uint8_t view)
Actually build the object.
static void ReallyClearObjectTile(Object *o)
Perform the actual removal of the object from the map.
static void AddProducedCargo_Object(TileIndex tile, CargoArray &produced)
Tile callback function signature for obtaining the produced cargo of a tile.
static CommandCost CheckBuildAbove_Object(TileIndex tile, DoCommandFlags flags, Axis axis, int height)
Tile callback function signature to test if a bridge can be built above a tile.
void GenerateObjects()
Generate objects, including lighthouses, transmitters, and any NewGRF objects.
CommandCost CheckBuildableTile(TileIndex tile, DiagDirections invalid_dirs, int &allowed_z, bool allow_steep, bool check_bridge)
Checks if the given tile is buildable, flat and has a certain height.
void InitializeObjects()
Initialize/reset the objects.
static void TryBuildTownLighthouse(Town *town)
Try to build a lighthouse near a town.
static uint8_t GetCompanyHQSize(TileIndex tile)
Get the size of the HQ.
static void ChangeTileOwner_Object(TileIndex tile, Owner old_owner, Owner new_owner)
Tile callback function signature for changing the owner of a tile.
static CommandCost ClearTile_Object(TileIndex tile, DoCommandFlags flags)
Tile callback function signature for clearing a tile.
static bool TryBuildTransmitter()
Try to build a transmitter.
CommandCost CmdBuildObjectArea(DoCommandFlags flags, TileIndex tile, TileIndex start_tile, ObjectType type, uint8_t view, bool diagonal)
Construct multiple objects in an area.
static void GetTileDesc_Object(TileIndex tile, TileDesc &td)
Tile callback function signature for obtaining a tile description.
static CommandCost TerraformTile_Object(TileIndex tile, DoCommandFlags flags, int z_new, Slope tileh_new)
Tile callback function signature of the terraforming callback.
ObjectType GetObjectType(Tile t)
Gets the ObjectType of the given object tile.
static void BuildCoastLighthouses(uint16_t amount)
Try to build lighthouses along coasts.
static bool TryBuildCoastLighthouse()
Try to build a lighthouse along the coast.
void UpdateCompanyHQ(TileIndex tile, uint score)
Update the CompanyHQ to the state associated with the given score.
ClearedObjectArea * FindClearedObject(TileIndex tile)
Find the entry in _cleared_object_areas which occupies a certain tile.
static Foundation GetFoundation_Object(TileIndex tile, Slope tileh)
Tile callback function signature for getting the foundation of a tile.
static void IncreaseCompanyHQSize(TileIndex tile)
Increase the HQ size.
CommandCost CmdBuildObject(DoCommandFlags flags, TileIndex tile, ObjectType type, uint8_t view)
Build an object object.
static void BuildTownLighthouses()
Try to build lighthouses near every town.
static void AddAcceptedCargo_Object(TileIndex tile, CargoArray &acceptance, CargoTypes &always_accepted)
Tile callback function signature for obtaining cargo acceptance of a tile.
static void TileLoop_Object(TileIndex tile)
Tile callback function signature for running periodic tile updates.
Command definitions related to objects.
Sprites to use and how to display them for object tiles.
Map accessors for object tiles.
void MakeObject(Tile t, Owner o, ObjectID index, WaterClass wc, uint8_t random)
Make an Object tile.
Definition object_map.h:74
bool IsObjectTypeTile(Tile t, ObjectType type)
Check whether a tile is a object tile of a specific type.
Definition object_map.h:36
bool IsObjectType(Tile t, ObjectType type)
Check whether the object on a tile is of a specific type.
Definition object_map.h:25
ObjectID GetObjectIndex(Tile t)
Get the index of which object this tile is attached to.
Definition object_map.h:47
static const ObjectType OBJECT_LIGHTHOUSE
The nice lighthouse.
Definition object_type.h:19
uint16_t ObjectType
Types of objects.
Definition object_type.h:16
static const ObjectType OBJECT_STATUE
Statue in towns.
Definition object_type.h:20
static const ObjectType OBJECT_HQ
HeadQuarter of a player.
Definition object_type.h:22
static const ObjectType OBJECT_TRANSMITTER
The large antenna.
Definition object_type.h:18
@ Built
Triggered when the object is built (for all tiles at the same time).
Definition object_type.h:37
@ TileLoop
Triggered in the periodic tile loop.
Definition object_type.h:38
@ TileLoopNorth
Triggered every 256 ticks (for all tiles at the same time).
Definition object_type.h:39
static const ObjectType NEW_OBJECT_OFFSET
Offset for new objects.
Definition object_type.h:24
static const ObjectType OBJECT_OWNED_LAND
Owned land 'flag'.
Definition object_type.h:21
@ Editor
In the scenario editor.
Definition openttd.h:21
@ Normal
Playing a game.
Definition openttd.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.
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.
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
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:170
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:377
Slope
Enumeration for the slope-type.
Definition slope_type.h:53
@ SLOPE_FLAT
a flat tile
Definition slope_type.h:54
Foundation
Enumeration for Foundations.
Definition slope_type.h:119
@ None
The tile has no foundation, the slope remains unchanged.
Definition slope_type.h:120
@ Headquarters
Source/destination are company headquarters.
Definition source_type.h:23
static const SpriteID SPR_FLAT_2_THIRD_GRASS_TILE
Definition sprites.h:676
static const SpriteID SPR_FLAT_BARE_LAND
Definition sprites.h:674
static const SpriteID SPR_FLAT_1_THIRD_GRASS_TILE
Definition sprites.h:675
static const SpriteID SPR_FLAT_GRASS_TILE
Definition sprites.h:677
Functions related to stations.
Definition of base types and functions in a cross-platform compatible way.
Class for storing amounts of cargo.
Definition cargo_type.h:118
static void InvalidateAllFrom(Source src)
Invalidates (sets source_id to INVALID_SOURCE) all cargo packets from given source.
Keeps track of removed objects during execution/testruns of commands.
Definition object_base.h:87
TileIndex location_of_HQ
Northern tile of HQ; INVALID_TILE when there is none.
uint32_t build_object_limit
Amount of tiles we can (still) build objects on (times 65536). Also applies to buying land and placin...
uint8_t GetCompanyRecolourOffset(LiveryScheme livery_scheme, bool use_secondary=true) const
Get offset for recolour palette of specific company.
A tile child sprite and palette to draw for stations etc, with 3D bounding box.
Definition sprite.h:33
Ground palette sprite of a tile, together with its sprite layout.
Definition sprite.h:55
PalSpriteID ground
Palette and sprite for the ground.
Definition sprite.h:56
virtual std::span< const DrawTileSeqStruct > GetSequence() const =0
The child sprites to draw.
std::string GetName() const
Get the name of this grf.
GrfID grfid
grfid that introduced this entity.
const struct GRFFile * grffile
grf file that introduced this entity
bool HasGrfFile() const
Test if this entity was introduced by NewGRF.
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:331
static uint ScaleBySize1D(uint n)
Scales the given value by the maps circumference, where the given value is for a 256 by 256 map.
Definition map_func.h:344
static uint MaxY()
Gets the maximum Y coordinate within the map, including TileType::Void.
Definition map_func.h:298
static uint MaxX()
Gets the maximum X coordinate within the map, including TileType::Void.
Definition map_func.h:289
static uint Size()
Get the size of the map.
Definition map_func.h:280
An object that isn't use for transport, industries or houses.
bool IsEnabled() const
Test if this object is enabled.
StandardGRFFileProps grf_prop
Properties related the the grf file.
StringID name
The name for this object.
static const ObjectSpec * GetByTile(TileIndex tile)
Get the specification associated with a tile.
static const ObjectSpec * Get(ObjectType index)
Get the specification associated with a specific ObjectType.
bool IsAvailable() const
Check whether the object is available at this time.
Money GetClearCost() const
Get the cost for clearing a structure of this type.
uint8_t size
The size of this objects; low nibble for X, high nibble for Y.
ObjectCallbackMasks callback_mask
Bitmask of requested/allowed callbacks.
ObjectFlags flags
Flags/settings related to the object.
uint8_t height
The height of this structure, in heightlevels; max MAX_TILE_HEIGHT.
bool WasEverAvailable() const
Check whether the object was available at some point in the past or present in this game with the cur...
Money GetBuildCost() const
Get the cost for building a structure of this type.
uint8_t views
The number of views.
An object, such as transmitter, on the map.
Definition object_base.h:24
ObjectType type
Type of the object.
Definition object_base.h:25
Town * town
Town the object is built in.
Definition object_base.h:26
static std::array< uint16_t, NUM_OBJECTS > counts
Number of objects per type ingame.
Definition object_base.h:81
uint8_t recolour_offset
Recolour offset of the object (basically the 2CC colour offset), for display purpose.
Definition object_base.h:29
static Object * GetByTile(TileIndex tile)
Get the object associated with a tile.
static void IncTypeCount(ObjectType type)
Increment the count of objects for this type.
Definition object_base.h:45
TimerGameCalendar::Date build_date
Date of construction.
Definition object_base.h:28
TileArea location
Location of the object.
Definition object_base.h:27
static void DecTypeCount(ObjectType type)
Decrement the count of objects for this type.
Definition object_base.h:56
static void ResetTypeCounts()
Resets object counts.
Definition object_base.h:75
uint16_t w
The width of the area.
TileIndex tile
The base tile of the area.
uint16_t h
The height of the area.
SpriteID sprite
The 'real' sprite.
Definition gfx_type.h:23
static Pool::IterateWrapper< Object > Iterate(size_t from=0)
static T * Create(Targs &&... args)
static Object * Get(auto index)
static bool CanAllocateItem(size_t n=1)
static Company * GetIfValid(auto index)
Tile description for the 'land area information' tool.
Definition tile_cmd.h:40
std::optional< std::string > grf
newGRF used for the tile contents
Definition tile_cmd.h:51
StringID str
Description of the tile.
Definition tile_cmd.h:41
TimerGameCalendar::Date build_date
Date of construction of tile contents.
Definition tile_cmd.h:45
std::array< Owner, 4 > owner
Name of the owner(s).
Definition tile_cmd.h:43
Tile information, used while rendering the tile.
Definition tile_cmd.h:34
Slope tileh
Slope of the tile.
Definition tile_cmd.h:35
TileIndex tile
Tile index.
Definition tile_cmd.h:36
Set of callback functions for performing tile operations of a given tile type.
Definition tile_cmd.h:214
std::array< uint32_t, NUM_HOUSE_ZONES > squared_town_zone_radius
UpdateTownRadius updates this given the house count.
Definition town.h:57
Town data structure.
Definition town.h:64
CompanyMask statues
which companies have a statue?
Definition town.h:82
TileIndex xy
town center tile
Definition town.h:65
TownCache cache
Container for all cacheable data.
Definition town.h:67
bool IsTileFlat(TileIndex tile, int *h)
Check if a given tile is flat.
Definition tile_map.cpp:94
std::tuple< Slope, int > GetTileSlopeZ(TileIndex tile)
Return the slope of a given tile inside the map.
Definition tile_map.cpp:55
int GetTileMaxZ(TileIndex t)
Get top height of the tile inside the map.
Definition tile_map.cpp:135
int GetTileZ(TileIndex tile)
Get bottom height of the tile.
Definition tile_map.cpp:115
static bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition tile_map.h:150
bool IsTileOwner(Tile tile, Owner owner)
Checks if a tile belongs to the given owner.
Definition tile_map.h:214
Owner GetTileOwner(Tile tile)
Returns the owner of a tile.
Definition tile_map.h:178
void SetTileOwner(Tile tile, Owner owner)
Sets the owner of a tile.
Definition tile_map.h:198
int GetTileMaxPixelZ(TileIndex tile)
Get top height of the tile.
Definition tile_map.h:312
uint8_t GetAnimationFrame(Tile t)
Get the current animation frame.
Definition tile_map.h:250
std::tuple< Slope, int > GetTilePixelSlope(TileIndex tile)
Return the slope of a given tile.
Definition tile_map.h:289
bool IsValidTile(Tile tile)
Checks if a tile is valid.
Definition tile_map.h:161
void SetAnimationFrame(Tile t, uint8_t frame)
Set a new animation frame.
Definition tile_map.h:262
Slope GetTileSlope(TileIndex tile)
Return the slope of a given tile inside the map.
Definition tile_map.h:279
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > > TileIndex
The index/ID of a Tile.
Definition tile_type.h:92
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:100
@ Water
Water tile.
Definition tile_type.h:55
@ Object
Contains objects such as transmitters and owned land.
Definition tile_type.h:59
@ Clear
A tile without any structures, i.e. grass, rocks, farm fields etc.
Definition tile_type.h:49
OrthogonalTileArea TileArea
Shorthand for the much more common orthogonal tile area.
Definition of the game-calendar-timer.
Base of the town class.
Town * CalcClosestTownFromTile(TileIndex tile, uint threshold=UINT_MAX)
Return the town closest to the given tile within threshold.
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...
@ Structures
other objects such as transmitters and lighthouses
CommandCost EnsureNoVehicleOnGround(TileIndex tile)
Ensure there is no vehicle at the ground at the given position.
Definition vehicle.cpp:558
Functions related to vehicles.
void AddSortableSpriteToDraw(SpriteID image, PaletteID pal, int x, int y, int z, const SpriteBounds &bounds, bool transparent, const SubSprite *sub)
Draw a (transparent) sprite at given coordinates with a given bounding box.
Definition viewport.cpp:664
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.
static const int TILE_HEIGHT_STEP
One Z unit tile height difference is displayed as 50m.
Functions related to water management.
void TileLoop_Water(TileIndex tile)
Tile callback function signature for running periodic tile updates.
void ClearNeighbourNonFloodingStates(TileIndex tile)
Clear non-flooding state of the tiles around a tile.
Definition water_cmd.cpp:99
bool HasTileWaterGround(Tile t)
Checks whether the tile has water at the ground.
Definition water_map.h:356
bool IsTileOnWater(Tile t)
Tests if the tile was built on water.
Definition water_map.h:140
WaterClass
classes of water (for WaterTileType::Clear water tile type).
Definition water_map.h:41
@ Invalid
Used for industry tiles on land (also for oilrig if newgrf says so).
Definition water_map.h:45
@ Canal
Canal.
Definition water_map.h:43
WaterTileType GetWaterTileType(Tile t)
Get the water tile type of a tile.
Definition water_map.h:82
WaterClass GetWaterClass(Tile t)
Get the water class at a tile.
Definition water_map.h:116
bool IsCoastTile(Tile t)
Is it a coast tile.
Definition water_map.h:216
bool IsDockingTile(Tile t)
Checks whether the tile is marked as a dockling tile.
Definition water_map.h:378
@ Coast
Coast.
Definition water_map.h:33
bool IsWaterTile(Tile t)
Is it a water tile with plain water?
Definition water_map.h:194
void InvalidateWaterRegion(TileIndex tile)
Marks the water region that tile is part of as invalid.
Handles dividing the water in the map into regions to assist pathfinding.
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting).
Definition window.cpp:3212
Window functions not directly related to making/drawing windows.