OpenTTD Source 20241222-master-gc72542431a
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 <http://www.gnu.org/licenses/>.
6 */
7
10#include "stdafx.h"
11#include "landscape.h"
12#include "command_func.h"
13#include "company_func.h"
14#include "viewport_func.h"
15#include "company_base.h"
16#include "town.h"
17#include "bridge_map.h"
18#include "genworld.h"
19#include "autoslope.h"
20#include "clear_func.h"
21#include "water.h"
22#include "window_func.h"
23#include "company_gui.h"
24#include "cheat_type.h"
25#include "object.h"
26#include "cargopacket.h"
27#include "core/random_func.hpp"
28#include "core/pool_func.hpp"
29#include "object_map.h"
30#include "object_base.h"
31#include "newgrf_config.h"
32#include "newgrf_object.h"
34#include "newgrf_debug.h"
35#include "vehicle_func.h"
36#include "station_func.h"
37#include "object_cmd.h"
38#include "landscape_cmd.h"
40
41#include "table/strings.h"
42#include "table/object_land.h"
43
44#include "safeguards.h"
45
46ObjectPool _object_pool("Object");
49
56{
57 return Object::Get(GetObjectIndex(tile));
58}
59
67{
68 assert(IsTileType(t, MP_OBJECT));
69 return Object::GetByTile(t)->type;
70}
71
77
88void BuildObject(ObjectType type, TileIndex tile, CompanyID owner, Town *town, uint8_t view)
89{
90 const ObjectSpec *spec = ObjectSpec::Get(type);
91
92 TileArea ta(tile, GB(spec->size, HasBit(view, 0) ? 4 : 0, 4), GB(spec->size, HasBit(view, 0) ? 0 : 4, 4));
93 Object *o = new Object();
94 o->type = type;
95 o->location = ta;
96 o->town = town == nullptr ? CalcClosestTownFromTile(tile) : town;
98 o->view = view;
99
100 /* If nothing owns the object, the colour will be random. Otherwise
101 * get the colour from the company's livery settings. */
102 if (owner == OWNER_NONE) {
103 o->colour = Random();
104 } else {
105 const Livery *l = Company::Get(owner)->livery;
106 o->colour = l->colour1 + l->colour2 * 16;
107 }
108
109 /* If the object wants only one colour, then give it that colour. */
110 if ((spec->flags & OBJECT_FLAG_2CC_COLOUR) == 0) o->colour &= 0xF;
111
112 if (HasBit(spec->callback_mask, CBM_OBJ_COLOUR)) {
113 uint16_t res = GetObjectCallback(CBID_OBJECT_COLOUR, o->colour, 0, spec, o, tile);
114 if (res != CALLBACK_FAILED) {
115 if (res >= 0x100) ErrorUnknownCallbackResult(spec->grf_prop.grfid, CBID_OBJECT_COLOUR, res);
116 o->colour = GB(res, 0, 8);
117 }
118 }
119
120 assert(o->town != nullptr);
121
122 for (TileIndex t : ta) {
126 /* Update company infrastructure counts for objects build on canals owned by nobody. */
127 if (wc == WATER_CLASS_CANAL && owner != OWNER_NONE && (IsTileOwner(t, OWNER_NONE) || IsTileOwner(t, OWNER_WATER))) {
128 Company::Get(owner)->infrastructure.water++;
130 }
131 bool remove = IsDockingTile(t);
132 MakeObject(t, owner, o->index, wc, Random());
133 if (remove) RemoveDockingTile(t);
135 }
136
139}
140
146{
148 for (TileIndex t : ta) {
151 }
152}
153
155#define GetCompanyHQSize GetAnimationFrame
157#define IncreaseCompanyHQSize IncreaseAnimationStage
158
164void UpdateCompanyHQ(TileIndex tile, uint score)
165{
166 if (tile == INVALID_TILE) return;
167
168 uint8_t val = 0;
169 if (score >= 170) val++;
170 if (score >= 350) val++;
171 if (score >= 520) val++;
172 if (score >= 720) val++;
173
174 while (GetCompanyHQSize(tile) < val) {
176 }
177}
178
184{
185 for (Object *obj : Object::Iterate()) {
186 Owner owner = GetTileOwner(obj->location.tile);
187 /* Not the current owner, so colour doesn't change. */
188 if (owner != c->index) continue;
189
190 const ObjectSpec *spec = ObjectSpec::GetByTile(obj->location.tile);
191 /* Using the object colour callback, so not using company colour. */
192 if (HasBit(spec->callback_mask, CBM_OBJ_COLOUR)) continue;
193
194 const Livery *l = c->livery;
195 obj->colour = ((spec->flags & OBJECT_FLAG_2CC_COLOUR) ? (l->colour2 * 16) : 0) + l->colour1;
196 }
197}
198
199extern CommandCost CheckBuildableTile(TileIndex tile, uint invalid_dirs, int &allowed_z, bool allow_steep, bool check_bridge);
200static CommandCost ClearTile_Object(TileIndex tile, DoCommandFlag flags);
201
211{
213
214 if (type >= ObjectSpec::Count()) return CMD_ERROR;
215 const ObjectSpec *spec = ObjectSpec::Get(type);
216 if (_game_mode == GM_NORMAL && !spec->IsAvailable() && !_generating_world) return CMD_ERROR;
217 if ((_game_mode == GM_EDITOR || _generating_world) && !spec->WasEverAvailable()) return CMD_ERROR;
218
219 if ((spec->flags & OBJECT_FLAG_ONLY_IN_SCENEDIT) != 0 && ((!_generating_world && _game_mode != GM_EDITOR) || _current_company != OWNER_NONE)) return CMD_ERROR;
220 if ((spec->flags & OBJECT_FLAG_ONLY_IN_GAME) != 0 && (_generating_world || _game_mode != GM_NORMAL || _current_company > MAX_COMPANIES)) return CMD_ERROR;
221 if (view >= spec->views) return CMD_ERROR;
222
223 if (!Object::CanAllocateItem()) return CommandCost(STR_ERROR_TOO_MANY_OBJECTS);
224 if (Town::GetNumItems() == 0) return CommandCost(STR_ERROR_MUST_FOUND_TOWN_FIRST);
225
226 int size_x = GB(spec->size, HasBit(view, 0) ? 4 : 0, 4);
227 int size_y = GB(spec->size, HasBit(view, 0) ? 0 : 4, 4);
228 TileArea ta(tile, size_x, size_y);
229 for (TileIndex t : ta) {
230 if (!IsValidTile(t)) return CommandCost(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB); // Might be off the map
231 }
232
233 if (type == OBJECT_OWNED_LAND) {
234 /* Owned land is special as it can be placed on any slope. */
235 cost.AddCost(Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile));
236 } else {
237 /* Check the surface to build on. At this time we can't actually execute the
238 * the CLEAR_TILE commands since the newgrf callback later on can check
239 * some information about the tiles. */
240 bool allow_water = (spec->flags & (OBJECT_FLAG_BUILT_ON_WATER | OBJECT_FLAG_NOT_ON_LAND)) != 0;
241 bool allow_ground = (spec->flags & OBJECT_FLAG_NOT_ON_LAND) == 0;
242 for (TileIndex t : ta) {
243 if (HasTileWaterGround(t)) {
244 if (!allow_water) return CommandCost(STR_ERROR_CAN_T_BUILD_ON_WATER);
245 if (!IsWaterTile(t)) {
246 /* Normal water tiles don't have to be cleared. For all other tile types clear
247 * the tile but leave the water. */
249 } else {
250 /* Can't build on water owned by another company. */
251 Owner o = GetTileOwner(t);
252 if (o != OWNER_NONE && o != OWNER_WATER) cost.AddCost(CheckOwnership(o, t));
253
254 /* However, the tile has to be clear of vehicles. */
256 }
257 } else {
258 if (!allow_ground) return CommandCost(STR_ERROR_MUST_BE_BUILT_ON_WATER);
259 /* For non-water tiles, we'll have to clear it before building. */
260
261 /* When relocating HQ, allow it to be relocated (partial) on itself. */
262 if (!(type == OBJECT_HQ &&
263 IsTileType(t, MP_OBJECT) &&
265 IsObjectType(t, OBJECT_HQ))) {
267 }
268 }
269 }
270
271 /* So, now the surface is checked... check the slope of said surface. */
272 auto [slope, allowed_z] = GetTileSlopeZ(tile);
273 if (slope != SLOPE_FLAT) allowed_z++;
274
275 for (TileIndex t : ta) {
276 uint16_t callback = CALLBACK_FAILED;
278 TileIndex diff = t - tile;
279 callback = GetObjectCallback(CBID_OBJECT_LAND_SLOPE_CHECK, GetTileSlope(t), TileY(diff) << 4 | TileX(diff), spec, nullptr, t, view);
280 }
281
282 if (callback == CALLBACK_FAILED) {
283 cost.AddCost(CheckBuildableTile(t, 0, allowed_z, false, false));
284 } else {
285 /* The meaning of bit 10 is inverted for a grf version < 8. */
286 if (spec->grf_prop.grffile->grf_version < 8) ToggleBit(callback, 10);
287 CommandCost ret = GetErrorMessageFromLocationCallbackResult(callback, spec->grf_prop.grffile, STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
288 if (ret.Failed()) return ret;
289 }
290 }
291
292 if (flags & DC_EXEC) {
293 /* This is basically a copy of the loop above with the exception that we now
294 * execute the commands and don't check for errors, since that's already done. */
295 for (TileIndex t : ta) {
296 if (HasTileWaterGround(t)) {
297 if (!IsWaterTile(t)) {
299 }
300 } else {
302 }
303 }
304 }
305 }
306 if (cost.Failed()) return cost;
307
308 /* Finally do a check for bridges. */
309 for (TileIndex t : ta) {
310 if (IsBridgeAbove(t) && (
313 return CommandCost(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
314 }
315 }
316
317 int hq_score = 0;
318 uint build_object_size = 1;
319 switch (type) {
322 if (!IsTileFlat(tile)) return CommandCost(STR_ERROR_FLAT_LAND_REQUIRED);
323 break;
324
326 if (IsTileType(tile, MP_OBJECT) &&
329 return CommandCost(STR_ERROR_YOU_ALREADY_OWN_IT);
330 }
331 break;
332
333 case OBJECT_HQ: {
335 if (c->location_of_HQ != INVALID_TILE) {
336 /* Don't relocate HQ on the same location. */
337 if (c->location_of_HQ == tile) return CommandCost(STR_ERROR_ALREADY_BUILT);
338 /* We need to persuade a bit harder to remove the old HQ. */
340 cost.AddCost(ClearTile_Object(c->location_of_HQ, flags));
342 }
343
344 if (flags & DC_EXEC) {
345 hq_score = UpdateCompanyRatingAndValue(c, false);
346 c->location_of_HQ = tile;
348 }
349 break;
350 }
351
352 case OBJECT_STATUE:
353 /* This may never be constructed using this method. */
354 return CMD_ERROR;
355
356 default: // i.e. NewGRF provided.
357 build_object_size = size_x * size_y;
358 break;
359 }
360
361 /* Don't allow building more objects if the company has reached its limit. */
363 if (c != nullptr && GB(c->build_object_limit, 16, 16) < build_object_size) {
364 return CommandCost(STR_ERROR_BUILD_OBJECT_LIMIT_REACHED);
365 }
366
367 if (flags & DC_EXEC) {
368 BuildObject(type, tile, _current_company == OWNER_DEITY ? OWNER_NONE : _current_company, nullptr, view);
369
370 /* Make sure the HQ starts at the right size. */
371 if (type == OBJECT_HQ) UpdateCompanyHQ(tile, hq_score);
372
373 /* Subtract the tile from the build limit. */
374 if (c != nullptr) c->build_object_limit -= build_object_size << 16;
375 }
376
377 cost.AddCost(spec->GetBuildCost() * build_object_size);
378 return cost;
379}
380
391CommandCost CmdBuildObjectArea(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, ObjectType type, uint8_t view, bool diagonal)
392{
393 if (start_tile >= Map::Size()) return CMD_ERROR;
394
395 if (type >= ObjectSpec::Count()) return CMD_ERROR;
396 const ObjectSpec *spec = ObjectSpec::Get(type);
397 if (view >= spec->views) return CMD_ERROR;
398
399 if (spec->size != OBJECT_SIZE_1X1) return CMD_ERROR;
400
403 CommandCost last_error = CMD_ERROR;
404 bool had_success = false;
405
407 int limit = (c == nullptr ? INT32_MAX : GB(c->build_object_limit, 16, 16));
408
409 std::unique_ptr<TileIterator> iter = TileIterator::Create(tile, start_tile, diagonal);
410 for (; *iter != INVALID_TILE; ++(*iter)) {
411 TileIndex t = *iter;
412 CommandCost ret = Command<CMD_BUILD_OBJECT>::Do(flags & ~DC_EXEC, t, type, view);
413
414 /* If we've reached the limit, stop building (or testing). */
415 if (c != nullptr && limit-- <= 0) break;
416
417 if (ret.Failed()) {
418 last_error = ret;
419 continue;
420 }
421
422 had_success = true;
423 if (flags & DC_EXEC) {
424 money -= ret.GetCost();
425
426 /* If we run out of money, stop building. */
427 if (ret.GetCost() > 0 && money < 0) break;
428 Command<CMD_BUILD_OBJECT>::Do(flags, t, type, view);
429 }
430 cost.AddCost(ret);
431 }
432
433 return had_success ? cost : last_error;
434}
435
436static Foundation GetFoundation_Object(TileIndex tile, Slope tileh);
437
438static void DrawTile_Object(TileInfo *ti)
439{
440 ObjectType type = GetObjectType(ti->tile);
441 const ObjectSpec *spec = ObjectSpec::Get(type);
442
443 /* Fall back for when the object doesn't exist anymore. */
444 if (!spec->IsEnabled()) type = OBJECT_TRANSMITTER;
445
446 if ((spec->flags & OBJECT_FLAG_HAS_NO_FOUNDATION) == 0) DrawFoundation(ti, GetFoundation_Object(ti->tile, ti->tileh));
447
448 if (type < NEW_OBJECT_OFFSET) {
449 const DrawTileSprites *dts = nullptr;
450 Owner to = GetTileOwner(ti->tile);
451 PaletteID palette = to == OWNER_NONE ? PAL_NONE : COMPANY_SPRITE_COLOUR(to);
452
453 if (type == OBJECT_HQ) {
455 dts = &_object_hq[GetCompanyHQSize(ti->tile) << 2 | TileY(diff) << 1 | TileX(diff)];
456 } else {
457 dts = &_objects[type];
458 }
459
461 /* If an object has no foundation, but tries to draw a (flat) ground
462 * type... we have to be nice and convert that for them. */
463 switch (dts->ground.sprite) {
464 case SPR_FLAT_BARE_LAND: DrawClearLandTile(ti, 0); break;
465 case SPR_FLAT_1_THIRD_GRASS_TILE: DrawClearLandTile(ti, 1); break;
466 case SPR_FLAT_2_THIRD_GRASS_TILE: DrawClearLandTile(ti, 2); break;
467 case SPR_FLAT_GRASS_TILE: DrawClearLandTile(ti, 3); break;
468 default: DrawGroundSprite(dts->ground.sprite, palette); break;
469 }
470 } else {
471 DrawGroundSprite(dts->ground.sprite, palette);
472 }
473
475 const DrawTileSeqStruct *dtss;
476 foreach_draw_tile_seq(dtss, dts->seq) {
478 dtss->image.sprite, palette,
479 ti->x + dtss->delta_x, ti->y + dtss->delta_y,
480 dtss->size_x, dtss->size_y,
481 dtss->size_z, ti->z + dtss->delta_z,
483 );
484 }
485 }
486 } else {
487 DrawNewObjectTile(ti, spec);
488 }
489
491}
492
493static int GetSlopePixelZ_Object(TileIndex tile, uint x, uint y, bool)
494{
495 if (IsObjectType(tile, OBJECT_OWNED_LAND)) {
496 auto [tileh, z] = GetTilePixelSlope(tile);
497
498 return z + GetPartialPixelZ(x & 0xF, y & 0xF, tileh);
499 } else {
500 return GetTileMaxPixelZ(tile);
501 }
502}
503
504static Foundation GetFoundation_Object(TileIndex tile, Slope tileh)
505{
507}
508
514{
516 for (TileIndex tile_cur : o->location) {
517 DeleteNewGRFInspectWindow(GSF_OBJECTS, tile_cur.base());
518
519 MakeWaterKeepingClass(tile_cur, GetTileOwner(tile_cur));
520 }
521 delete o;
522}
523
524std::vector<ClearedObjectArea> _cleared_object_areas;
525
532{
533 TileArea ta = TileArea(tile, 1, 1);
534
535 for (ClearedObjectArea &coa : _cleared_object_areas) {
536 if (coa.area.Intersects(ta)) return &coa;
537 }
538
539 return nullptr;
540}
541
542static CommandCost ClearTile_Object(TileIndex tile, DoCommandFlag flags)
543{
544 /* Get to the northern most tile. */
545 Object *o = Object::GetByTile(tile);
546 TileArea ta = o->location;
547
548 ObjectType type = o->type;
549 const ObjectSpec *spec = ObjectSpec::Get(type);
550
551 CommandCost cost(EXPENSES_CONSTRUCTION, spec->GetClearCost() * ta.w * ta.h / 5);
552 if (spec->flags & OBJECT_FLAG_CLEAR_INCOME) cost.MultiplyCost(-1); // They get an income!
553
554 /* Towns can't remove any objects. */
556
557 /* Water can remove everything! */
559 if ((flags & DC_NO_WATER) && IsTileOnWater(tile)) {
560 /* There is water under the object, treat it as water tile. */
561 return CommandCost(STR_ERROR_CAN_T_BUILD_ON_WATER);
562 } else if (!(spec->flags & OBJECT_FLAG_AUTOREMOVE) && (flags & DC_AUTO)) {
563 /* No automatic removal by overbuilding stuff. */
564 return CommandCost(type == OBJECT_HQ ? STR_ERROR_COMPANY_HEADQUARTERS_IN : STR_ERROR_OBJECT_IN_THE_WAY);
565 } else if (_game_mode == GM_EDITOR) {
566 /* No further limitations for the editor. */
567 } else if (GetTileOwner(tile) == OWNER_NONE) {
568 /* Owned by nobody and unremovable, so we can only remove it with brute force! */
570 } else if (CheckTileOwnership(tile).Failed()) {
571 /* We don't own it!. */
572 return CommandCost(STR_ERROR_OWNED_BY);
573 } else if ((spec->flags & OBJECT_FLAG_CANNOT_REMOVE) != 0 && (spec->flags & OBJECT_FLAG_AUTOREMOVE) == 0) {
574 /* In the game editor or with cheats we can remove, otherwise we can't. */
576 if (type == OBJECT_HQ) return CommandCost(STR_ERROR_COMPANY_HEADQUARTERS_IN);
577 return CMD_ERROR;
578 }
579
580 /* Removing with the cheat costs more in TTDPatch / the specs. */
581 cost.MultiplyCost(25);
582 }
583 } else if ((spec->flags & (OBJECT_FLAG_BUILT_ON_WATER | OBJECT_FLAG_NOT_ON_LAND)) != 0) {
584 /* Water can't remove objects that are buildable on water. */
585 return CMD_ERROR;
586 }
587
588 switch (type) {
589 case OBJECT_HQ: {
591 if (flags & DC_EXEC) {
592 c->location_of_HQ = INVALID_TILE; // reset HQ position
595 }
596
597 /* cost of relocating company is 1% of company value */
599 break;
600 }
601
602 case OBJECT_STATUE:
603 if (flags & DC_EXEC) {
604 Town *town = o->town;
605 ClrBit(town->statues, GetTileOwner(tile));
607 }
608 break;
609
610 default:
611 break;
612 }
613
614 _cleared_object_areas.push_back({tile, ta});
615
616 if (flags & DC_EXEC) ReallyClearObjectTile(o);
617
618 return cost;
619}
620
621static void AddAcceptedCargo_Object(TileIndex tile, CargoArray &acceptance, CargoTypes &always_accepted)
622{
623 if (!IsObjectType(tile, OBJECT_HQ)) return;
624
625 /* HQ accepts passenger and mail; but we have to divide the values
626 * between 4 tiles it occupies! */
627
628 /* HQ level (depends on company performance) in the range 1..5. */
629 uint level = GetCompanyHQSize(tile) + 1;
630
631 /* Top town building generates 10, so to make HQ interesting, the top
632 * type makes 20. */
633 CargoID pass = GetCargoIDByLabel(CT_PASSENGERS);
634 if (IsValidCargoID(pass)) {
635 acceptance[pass] += std::max(1U, level);
636 SetBit(always_accepted, pass);
637 }
638
639 /* Top town building generates 4, HQ can make up to 8. The
640 * proportion passengers:mail is different because such a huge
641 * commercial building generates unusually high amount of mail
642 * correspondence per physical visitor. */
643 CargoID mail = GetCargoIDByLabel(CT_MAIL);
644 if (IsValidCargoID(mail)) {
645 acceptance[mail] += std::max(1U, level / 2);
646 SetBit(always_accepted, mail);
647 }
648}
649
650static void AddProducedCargo_Object(TileIndex tile, CargoArray &produced)
651{
652 if (!IsObjectType(tile, OBJECT_HQ)) return;
653
654 CargoID pass = GetCargoIDByLabel(CT_PASSENGERS);
655 if (IsValidCargoID(pass)) produced[pass]++;
656 CargoID mail = GetCargoIDByLabel(CT_MAIL);
657 if (IsValidCargoID(mail)) produced[mail]++;
658}
659
660
661static void GetTileDesc_Object(TileIndex tile, TileDesc *td)
662{
663 const ObjectSpec *spec = ObjectSpec::GetByTile(tile);
664 td->str = spec->name;
665 td->owner[0] = GetTileOwner(tile);
667
668 if (spec->grf_prop.HasGrfFile()) {
669 td->grf = GetGRFConfig(spec->grf_prop.grfid)->GetName();
670 }
671}
672
673static void TileLoop_Object(TileIndex tile)
674{
675 const ObjectSpec *spec = ObjectSpec::GetByTile(tile);
676 if (spec->flags & OBJECT_FLAG_ANIMATION) {
677 Object *o = Object::GetByTile(tile);
679 if (o->location.tile == tile) TriggerObjectAnimation(o, OAT_256_TICKS, spec);
680 }
681
682 if (IsTileOnWater(tile)) TileLoop_Water(tile);
683
684 if (!IsObjectType(tile, OBJECT_HQ)) return;
685
686 /* HQ accepts passenger and mail; but we have to divide the values
687 * between 4 tiles it occupies! */
688
689 /* HQ level (depends on company performance) in the range 1..5. */
690 uint level = GetCompanyHQSize(tile) + 1;
691 assert(level < 6);
692
693 StationFinder stations(TileArea(tile, 2, 2));
694
695 uint r = Random();
696 /* Top town buildings generate 250, so the top HQ type makes 256. */
697 CargoID pass = GetCargoIDByLabel(CT_PASSENGERS);
698 if (IsValidCargoID(pass) && GB(r, 0, 8) < (256 / 4 / (6 - level))) {
699 uint amt = GB(r, 0, 8) / 8 / 4 + 1;
700
701 /* Production is halved during recessions. */
702 if (EconomyIsInRecession()) amt = (amt + 1) >> 1;
703
704 /* Scale by cargo scale setting. */
705 amt = ScaleByCargoScale(amt, true);
706
707 MoveGoodsToStation(pass, amt, SourceType::Headquarters, GetTileOwner(tile), stations.GetStations());
708 }
709
710 /* Top town building generates 90, HQ can make up to 196. The
711 * proportion passengers:mail is about the same as in the acceptance
712 * equations. */
713 CargoID mail = GetCargoIDByLabel(CT_MAIL);
714 if (IsValidCargoID(mail) && GB(r, 8, 8) < (196 / 4 / (6 - level))) {
715 uint amt = GB(r, 8, 8) / 8 / 4 + 1;
716
717 /* Production is halved during recessions. */
718 if (EconomyIsInRecession()) amt = (amt + 1) >> 1;
719
720 /* Scale by cargo scale setting. */
721 amt = ScaleByCargoScale(amt, true);
722
723 MoveGoodsToStation(mail, amt, SourceType::Headquarters, GetTileOwner(tile), stations.GetStations());
724 }
725}
726
727
728static TrackStatus GetTileTrackStatus_Object(TileIndex, TransportType, uint, DiagDirection)
729{
730 return 0;
731}
732
733static bool ClickTile_Object(TileIndex tile)
734{
735 if (!IsObjectType(tile, OBJECT_HQ)) return false;
736
738 return true;
739}
740
741static void AnimateTile_Object(TileIndex tile)
742{
744}
745
751static bool HasTransmitter(TileIndex tile, void *)
752{
754}
755
761{
762 uint maxx = Map::MaxX();
763 uint maxy = Map::MaxY();
764 uint r = Random();
765
766 /* Scatter the lighthouses more evenly around the perimeter */
767 int perimeter = (GB(r, 16, 16) % (2 * (maxx + maxy))) - maxy;
768 DiagDirection dir;
769 for (dir = DIAGDIR_NE; perimeter > 0; dir++) {
770 perimeter -= (DiagDirToAxis(dir) == AXIS_X) ? maxx : maxy;
771 }
772
773 TileIndex tile;
774 switch (dir) {
775 default:
776 case DIAGDIR_NE: tile = TileXY(maxx - 1, r % maxy); break;
777 case DIAGDIR_SE: tile = TileXY(r % maxx, 1); break;
778 case DIAGDIR_SW: tile = TileXY(1, r % maxy); break;
779 case DIAGDIR_NW: tile = TileXY(r % maxx, maxy - 1); break;
780 }
781
782 /* Only build lighthouses at tiles where the border is sea. */
783 if (!IsTileType(tile, MP_WATER)) return false;
784
785 for (int j = 0; j < 19; j++) {
786 int h;
787 if (IsTileType(tile, MP_CLEAR) && IsTileFlat(tile, &h) && h <= 2 && !IsBridgeAbove(tile)) {
789 assert(tile < Map::Size());
790 return true;
791 }
792 tile += TileOffsByDiagDir(dir);
793 if (!IsValidTile(tile)) return false;
794 }
795 return false;
796}
797
803{
804 TileIndex tile = RandomTile();
805 int h;
806 if (IsTileType(tile, MP_CLEAR) && IsTileFlat(tile, &h) && h >= 4 && !IsBridgeAbove(tile)) {
807 TileIndex t = tile;
808 if (CircularTileSearch(&t, 9, HasTransmitter, nullptr)) return false;
809
811 return true;
812 }
813 return false;
814}
815
816void GenerateObjects()
817{
818 /* Set a guestimate on how much we progress */
819 SetGeneratingWorldProgress(GWP_OBJECT, (uint)ObjectSpec::Count());
820
821 /* Determine number of water tiles at map border needed for freeform_edges */
822 uint num_water_tiles = 0;
824 for (uint x = 0; x < Map::MaxX(); x++) {
825 if (IsTileType(TileXY(x, 1), MP_WATER)) num_water_tiles++;
826 if (IsTileType(TileXY(x, Map::MaxY() - 1), MP_WATER)) num_water_tiles++;
827 }
828 for (uint y = 1; y < Map::MaxY() - 1; y++) {
829 if (IsTileType(TileXY(1, y), MP_WATER)) num_water_tiles++;
830 if (IsTileType(TileXY(Map::MaxX() - 1, y), MP_WATER)) num_water_tiles++;
831 }
832 }
833
834 /* Iterate over all possible object types */
835 for (const auto &spec : ObjectSpec::Specs()) {
836
837 /* Continue, if the object was never available till now or shall not be placed */
838 if (!spec.WasEverAvailable() || spec.generate_amount == 0) continue;
839
840 uint16_t amount = spec.generate_amount;
841
842 /* Scale by map size */
844 /* Scale the amount of lighthouses with the amount of land at the borders.
845 * The -6 is because the top borders are MP_VOID (-2) and all corners
846 * are counted twice (-4). */
847 amount = Map::ScaleBySize1D(amount * num_water_tiles) / (2 * Map::MaxY() + 2 * Map::MaxX() - 6);
848 } else if (spec.flags & OBJECT_FLAG_SCALE_BY_WATER) {
849 amount = Map::ScaleBySize1D(amount);
850 } else {
851 amount = Map::ScaleBySize(amount);
852 }
853
854 /* Now try to place the requested amount of this object */
855 for (uint j = Map::ScaleBySize(1000); j != 0 && amount != 0 && Object::CanAllocateItem(); j--) {
856 switch (spec.Index()) {
858 if (TryBuildTransmitter()) amount--;
859 break;
860
862 if (TryBuildLightHouse()) amount--;
863 break;
864
865 default:
866 uint8_t view = RandomRange(spec.views);
868 break;
869 }
870 }
872 }
873}
874
875static void ChangeTileOwner_Object(TileIndex tile, Owner old_owner, Owner new_owner)
876{
877 if (!IsTileOwner(tile, old_owner)) return;
878
879 bool do_clear = false;
880
881 ObjectType type = GetObjectType(tile);
882 if ((type == OBJECT_OWNED_LAND || type >= NEW_OBJECT_OFFSET) && new_owner != INVALID_OWNER) {
883 SetTileOwner(tile, new_owner);
884 if (GetWaterClass(tile) == WATER_CLASS_CANAL) {
885 Company::Get(old_owner)->infrastructure.water--;
886 Company::Get(new_owner)->infrastructure.water++;
887 }
888 } else if (type == OBJECT_STATUE) {
889 Town *t = Object::GetByTile(tile)->town;
890 ClrBit(t->statues, old_owner);
891 if (new_owner != INVALID_OWNER && !HasBit(t->statues, new_owner)) {
892 /* Transfer ownership to the new company */
893 SetBit(t->statues, new_owner);
894 SetTileOwner(tile, new_owner);
895 } else {
896 do_clear = true;
897 }
898
900 } else {
901 do_clear = true;
902 }
903
904 if (do_clear) {
906 /* When clearing objects, they may turn into canal, which may require transferring ownership. */
907 ChangeTileOwner(tile, old_owner, new_owner);
908 }
909}
910
911static CommandCost TerraformTile_Object(TileIndex tile, DoCommandFlag flags, int z_new, Slope tileh_new)
912{
913 ObjectType type = GetObjectType(tile);
914
915 if (type == OBJECT_OWNED_LAND) {
916 /* Owned land remains unsold */
918 if (ret.Succeeded()) return CommandCost();
919 } else if (AutoslopeEnabled() && type != OBJECT_TRANSMITTER && type != OBJECT_LIGHTHOUSE) {
920 /* Behaviour:
921 * - Both new and old slope must not be steep.
922 * - TileMaxZ must not be changed.
923 * - Allow autoslope by default.
924 * - Disallow autoslope if callback succeeds and returns non-zero.
925 */
926 Slope tileh_old = GetTileSlope(tile);
927 /* TileMaxZ must not be changed. Slopes must not be steep. */
928 if (!IsSteepSlope(tileh_old) && !IsSteepSlope(tileh_new) && (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) {
929 const ObjectSpec *spec = ObjectSpec::Get(type);
930
931 /* Call callback 'disable autosloping for objects'. */
933 /* If the callback fails, allow autoslope. */
934 uint16_t res = GetObjectCallback(CBID_OBJECT_AUTOSLOPE, 0, 0, spec, Object::GetByTile(tile), tile);
935 if (res == CALLBACK_FAILED || !ConvertBooleanCallback(spec->grf_prop.grffile, CBID_OBJECT_AUTOSLOPE, res)) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
936 } else if (spec->IsEnabled()) {
937 /* allow autoslope */
938 return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
939 }
940 }
941 }
942
943 return Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
944}
945
946extern const TileTypeProcs _tile_type_object_procs = {
947 DrawTile_Object, // draw_tile_proc
948 GetSlopePixelZ_Object, // get_slope_z_proc
949 ClearTile_Object, // clear_tile_proc
950 AddAcceptedCargo_Object, // add_accepted_cargo_proc
951 GetTileDesc_Object, // get_tile_desc_proc
952 GetTileTrackStatus_Object, // get_tile_track_status_proc
953 ClickTile_Object, // click_tile_proc
954 AnimateTile_Object, // animate_tile_proc
955 TileLoop_Object, // tile_loop_proc
956 ChangeTileOwner_Object, // change_tile_owner_proc
957 AddProducedCargo_Object, // add_produced_cargo_proc
958 nullptr, // vehicle_enter_tile_proc
959 GetFoundation_Object, // get_foundation_proc
960 TerraformTile_Object, // terraform_tile_proc
961};
Functions related to autoslope.
bool AutoslopeEnabled()
Tests if autoslope is enabled for _current_company.
Definition autoslope.h:65
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.
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 ToggleBit(T &x, const uint8_t y)
Toggles a bit in a variable.
constexpr T ClrBit(T &x, const uint8_t y)
Clears a bit in a variable.
void DrawBridgeMiddle(const TileInfo *ti)
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
uint8_t CargoID
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:22
bool IsValidCargoID(CargoID t)
Test whether cargo type is not INVALID_CARGO.
Definition cargo_type.h:107
static constexpr CargoLabel CT_PASSENGERS
Available types of cargo Labels may be re-used between different climates.
Definition cargo_type.h:30
@ Headquarters
Source/destination are company headquarters.
Base class for cargo packets.
Cheats _cheats
All the cheats.
Definition cheat.cpp:16
Types related to cheating.
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.
Structure contains cached list of stations nearby.
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:291
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).
Functions related to clear (MP_CLEAR) land.
Functions related to commands.
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
DoCommandFlag
List of flags for a command.
@ DC_NO_TEST_TOWN_RATING
town rating does not disallow you from building
@ DC_AUTO
don't allow building on structures
@ DC_NO_WATER
don't allow building on water
@ DC_NO_MODIFY_TOWN_RATING
do not change town rating
@ DC_EXEC
execute the given command
Definition of stuff that is very close to a company, like the company struct itself.
Money CalculateCompanyValue(const Company *c, bool including_loan=true)
Calculate the value of the company.
Definition economy.cpp:149
CommandCost CheckTileOwnership(TileIndex tile)
Check whether the current owner owns the stuff on the given tile.
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.
Owner
Enum for all companies/owners.
@ INVALID_OWNER
An invalid owner.
@ OWNER_DEITY
The object is owned by a superuser / goal script.
@ OWNER_NONE
The tile has no ownership.
@ OWNER_WATER
The tile/execution is done by "water".
@ OWNER_TOWN
A town owns the tile, or a town is expanding.
@ MAX_COMPANIES
Maximum number of companies.
Axis DiagDirToAxis(DiagDirection d)
Convert a DiagDirection to the axis.
@ AXIS_X
The X axis.
DiagDirection
Enumeration for diagonal directions.
@ DIAGDIR_NE
Northeast, upper right on your monitor.
@ DIAGDIR_NW
Northwest.
@ DIAGDIR_SE
Southeast.
@ DIAGDIR_SW
Southwest.
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:201
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.
bool _generating_world
Whether we are generating the map or not.
Definition genworld.cpp:67
Functions related to world/map generation.
void IncreaseGeneratingWorldProgress(GenWorldProgress cls)
Increases the current stage of the world generation with one.
@ GWP_OBJECT
Generate objects (radio tower, light houses)
Definition genworld.h:76
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:19
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_height_override)
Mark a tile given by its index dirty for repaint.
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.
Functions related to OTTD's landscape.
Command definitions related to landscape (slopes etc.).
bool CircularTileSearch(TileIndex *tile, uint size, TestTileOnSearchProc proc, void *user_data)
Function performing a search around a center tile and going outward, thus in circle.
Definition map.cpp:247
static debug_inline TileIndex TileXY(uint x, uint y)
Returns the TileIndex of a coordinate.
Definition map_func.h:373
#define RandomTile()
Get a valid random tile.
Definition map_func.h:661
static debug_inline uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition map_func.h:425
static debug_inline uint TileX(TileIndex tile)
Get the X component of a tile.
Definition map_func.h:415
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition map_func.h:567
@ OAT_BUILT
Triggered when the object is built (for all tiles at the same time).
@ OAT_TILELOOP
Triggered in the periodic tile loop.
@ OAT_256_TICKS
Triggered every 256 ticks (for all tiles at the same time).
@ 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.
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
@ CBM_OBJ_COLOUR
decide the colour of the building
@ CBM_OBJ_SLOPE_CHECK
decides slope suitability
@ CBM_OBJ_AUTOSLOPE
decides allowance of autosloping
CommandCost GetErrorMessageFromLocationCallbackResult(uint16_t cb_res, const GRFFile *grffile, StringID default_error)
Get the error message from a shape/location/slope check callback result.
void ErrorUnknownCallbackResult(uint32_t grfid, uint16_t cbid, uint16_t cb_res)
Record that a NewGRF returned an unknown/invalid callback result.
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 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 TriggerObjectAnimation(Object *o, ObjectAnimationTrigger trigger, const ObjectSpec *spec)
Trigger the update of animation on a whole object.
void DrawNewObjectTile(TileInfo *ti, const ObjectSpec *spec)
Draw an object on the map.
uint16_t GetObjectCallback(CallbackID callback, uint32_t param1, uint32_t param2, const ObjectSpec *spec, Object *o, TileIndex tile, uint8_t view)
Perform a callback for an object.
void 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.
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,...
@ OBJECT_FLAG_CLEAR_INCOME
When object is cleared a positive income is generated instead of a cost.
@ OBJECT_FLAG_ALLOW_UNDER_BRIDGE
Object can built under a bridge.
@ OBJECT_FLAG_HAS_NO_FOUNDATION
Do not display foundations when on a slope.
@ OBJECT_FLAG_AUTOREMOVE
Object get automatically removed (like "owned land").
@ OBJECT_FLAG_SCALE_BY_WATER
Object count is roughly scaled by water amount at edges.
@ OBJECT_FLAG_2CC_COLOUR
Object wants 2CC colour mapping.
@ OBJECT_FLAG_ANIMATION
Object has animated tiles.
@ OBJECT_FLAG_BUILT_ON_WATER
Object can be built on water (not required).
@ OBJECT_FLAG_CANNOT_REMOVE
Object can not be removed.
@ OBJECT_FLAG_NOT_ON_LAND
Object can not be on land, implicitly sets OBJECT_FLAG_BUILT_ON_WATER.
@ OBJECT_FLAG_ONLY_IN_GAME
Object can only be built in game.
@ OBJECT_FLAG_ONLY_IN_SCENEDIT
Object can only be constructed in the scenario editor.
Functions related to objects.
Base for all objects.
CommandCost CheckBuildableTile(TileIndex tile, uint 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 UpdateObjectColours(const Company *c)
Updates the colour of the object whenever a company changes.
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.
void InitializeObjects()
Initialize/reset the objects.
#define IncreaseCompanyHQSize
We encode the company HQ size in the animation stage.
CommandCost CmdBuildObjectArea(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, ObjectType type, uint8_t view, bool diagonal)
Construct multiple objects in an area.
static bool TryBuildTransmitter()
Try to build a transmitter.
static bool TryBuildLightHouse()
Try to build a lighthouse.
#define GetCompanyHQSize
We encode the company HQ size in the animation stage.
static void IncreaseAnimationStage(TileIndex tile)
Increase the animation stage of a whole structure.
ObjectType GetObjectType(Tile t)
Gets the ObjectType of the given object tile.
CommandCost CmdBuildObject(DoCommandFlag flags, TileIndex tile, ObjectType type, uint8_t view)
Build an object object.
static bool HasTransmitter(TileIndex tile, void *)
Helper function for CircularTileSearch.
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.
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:17
uint16_t ObjectType
Types of objects.
Definition object_type.h:14
static const ObjectType OBJECT_STATUE
Statue in towns.
Definition object_type.h:18
static const ObjectType OBJECT_HQ
HeadQuarter of a player.
Definition object_type.h:20
static const ObjectType NUM_OBJECTS
Number of supported objects overall.
Definition object_type.h:23
static const ObjectType OBJECT_TRANSMITTER
The large antenna.
Definition object_type.h:16
static const ObjectType NEW_OBJECT_OFFSET
Offset for new objects.
Definition object_type.h:22
static const ObjectType OBJECT_OWNED_LAND
Owned land 'flag'.
Definition object_type.h:19
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:57
static constexpr int GetSlopeMaxZ(Slope s)
Returns the height of the highest corner of a slope relative to TileZ (= minimal height)
Definition slope_func.h:160
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
Enumeration for the slope-type.
Definition slope_type.h:48
@ SLOPE_FLAT
a flat tile
Definition slope_type.h:49
Foundation
Enumeration for Foundations.
Definition slope_type.h:93
@ FOUNDATION_NONE
The tile has no foundation, the slope remains unchanged.
Definition slope_type.h:94
#define foreach_draw_tile_seq(idx, list)
Iterate through all DrawTileSeqStructs in DrawTileSprites.
Definition sprite.h:79
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:114
static void InvalidateAllFrom(SourceType src_type, SourceID src)
Invalidates (sets source_id to INVALID_SOURCE) all cargo packets from given source.
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
Keeps track of removed objects during execution/testruns of commands.
Definition object_base.h:84
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.
bool freeform_edges
allow terraforming the tiles at the map edges
A tile child sprite and palette to draw for stations etc, with 3D bounding box.
Definition sprite.h:25
int8_t delta_z
0x80 identifies child sprites
Definition sprite.h:28
int8_t delta_x
0x80 is sequence terminator
Definition sprite.h:26
Ground palette sprite of a tile, together with its sprite layout.
Definition sprite.h:58
const DrawTileSeqStruct * seq
Array of child sprites. Terminated with a terminator entry.
Definition sprite.h:60
PalSpriteID ground
Palette and sprite for the ground.
Definition sprite.h:59
const char * GetName() const
Get the name of this grf.
bool HasGrfFile() const
Test if this entity was introduced by NewGRF.
uint32_t grfid
grfid that introduced this entity.
const struct GRFFile * grffile
grf file that introduced this entity
ConstructionSettings construction
construction of things in-game
Information about a particular livery.
Definition livery.h:78
Colours colour2
Second colour, for vehicles with 2CC support.
Definition livery.h:81
Colours colour1
First colour, for all vehicles.
Definition livery.h:80
static uint ScaleBySize(uint n)
Scales the given value by the map size, where the given value is for a 256 by 256 map.
Definition map_func.h:328
static 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:341
static uint MaxY()
Gets the maximum Y coordinate within the map, including MP_VOID.
Definition map_func.h:306
static debug_inline uint Size()
Get the size of the map.
Definition map_func.h:288
static debug_inline uint MaxX()
Gets the maximum X coordinate within the map, including MP_VOID.
Definition map_func.h:297
Allow incrementing of ObjectClassID variables.
bool IsEnabled() const
Test if this object is enabled.
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.
GRFFilePropsBase< 2 > grf_prop
Properties related the the grf file.
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.
uint8_t generate_amount
Number of objects which are attempted to be generated per 256^2 map during world generation.
uint Index() const
Gets the index of this spec.
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.
uint16_t callback_mask
Bitmask of requested/allowed callbacks.
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.
static void IncTypeCount(ObjectType type)
Increment the count of objects for this type.
Definition object_base.h:43
TimerGameCalendar::Date build_date
Date of construction.
Definition object_base.h:27
static uint16_t counts[NUM_OBJECTS]
Number of objects per type ingame.
Definition object_base.h:78
uint8_t view
The view setting for this object.
Definition object_base.h:29
TileArea location
Location of the object.
Definition object_base.h:26
uint8_t colour
Colour of the object, for display purpose.
Definition object_base.h:28
static void DecTypeCount(ObjectType type)
Decrement the count of objects for this type.
Definition object_base.h:54
static void ResetTypeCounts()
Resets object counts.
Definition object_base.h:72
Represents the covered area of e.g.
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:24
Tindex index
Index of this pool item.
static size_t GetNumItems()
Returns number of valid items in the pool.
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
static Titem * GetIfValid(size_t index)
Returns Titem with given index.
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
static Titem * Get(size_t index)
Returns Titem with given index.
Base class for all pools.
Definition pool_type.hpp:80
Tile description for the 'land area information' tool.
Definition tile_cmd.h:52
StringID str
Description of the tile.
Definition tile_cmd.h:53
TimerGameCalendar::Date build_date
Date of construction of tile contents.
Definition tile_cmd.h:57
const char * grf
newGRF used for the tile contents
Definition tile_cmd.h:63
Owner owner[4]
Name of the owner(s)
Definition tile_cmd.h:55
Tile information, used while rendering the tile.
Definition tile_cmd.h:43
int z
Height.
Definition tile_cmd.h:48
int x
X position of the tile in unit coordinates.
Definition tile_cmd.h:44
Slope tileh
Slope of the tile.
Definition tile_cmd.h:46
TileIndex tile
Tile index.
Definition tile_cmd.h:47
int y
Y position of the tile in unit coordinates.
Definition tile_cmd.h:45
Set of callback functions for performing tile operations of a given tile type.
Definition tile_cmd.h:158
Town data structure.
Definition town.h:54
CompanyMask statues
which companies have a statue?
Definition town.h:70
bool IsTileFlat(TileIndex tile, int *h)
Check if a given tile is flat.
Definition tile_map.cpp:95
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:136
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
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
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:95
@ MP_CLEAR
A tile without any structures, i.e. grass, rocks, farm fields etc.
Definition tile_type.h:48
@ MP_WATER
Water tile.
Definition tile_type.h:54
@ 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 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.
@ TO_STRUCTURES
other objects such as transmitters and lighthouses
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...
TransportType
Available types of transport.
CommandCost EnsureNoVehicleOnGround(TileIndex tile)
Ensure there is no vehicle at the ground at the given position.
Definition vehicle.cpp:546
Functions related to vehicles.
void AddSortableSpriteToDraw(SpriteID image, PaletteID pal, int x, int y, int w, int h, int dz, int z, bool transparent, int bb_offset_x, int bb_offset_y, int bb_offset_z, const SubSprite *sub)
Draw a (transparent) sprite at given coordinates with a given bounding box.
Definition viewport.cpp:671
void DrawGroundSprite(SpriteID image, PaletteID pal, const SubSprite *sub, int extra_offs_x, int extra_offs_y)
Draws a ground sprite for the current tile.
Definition viewport.cpp:587
Functions related to (drawing on) viewports.
Functions related to water (management)
void TileLoop_Water(TileIndex tile)
Let a water tile floods its diagonal adjoining tiles called from tunnelbridge_cmd,...
void ClearNeighbourNonFloodingStates(TileIndex tile)
Clear non-flooding state of the tiles around a tile.
Definition water_cmd.cpp:97
bool HasTileWaterGround(Tile t)
Checks whether the tile has water at the ground.
Definition water_map.h:350
bool IsTileOnWater(Tile t)
Tests if the tile was built on water.
Definition water_map.h:136
WaterClass
classes of water (for WATER_TILE_CLEAR water tile type).
Definition water_map.h:39
@ WATER_CLASS_CANAL
Canal.
Definition water_map.h:41
@ WATER_CLASS_INVALID
Used for industry tiles on land (also for oilrig if newgrf says so).
Definition water_map.h:43
WaterClass GetWaterClass(Tile t)
Get the water class at a tile.
Definition water_map.h:112
bool IsDockingTile(Tile t)
Checks whether the tile is marked as a dockling tile.
Definition water_map.h:371
bool IsWaterTile(Tile t)
Is it a water tile with plain water?
Definition water_map.h:190
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:3101
Window functions not directly related to making/drawing windows.
@ WC_TOWN_AUTHORITY
Town authority; Window numbers:
@ WC_COMPANY
Company view; Window numbers: