OpenTTD Source: src/station.cpp Source File

OpenTTD Source 15.3

station.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
10#include "stdafx.h"
11#include "core/flatset_type.hpp"
12#include "company_func.h"
13#include "company_base.h"
14#include "roadveh.h"
15#include "viewport_func.h"
16#include "viewport_kdtree.h"
17#include "command_func.h"
18#include "news_func.h"
19#include "aircraft.h"
20#include "vehiclelist.h"
21#include "core/pool_func.hpp"
22#include "station_base.h"
23#include "station_kdtree.h"
24#include "roadstop_base.h"
25#include "industry.h"
26#include "town.h"
27#include "core/random_func.hpp"
28#include "linkgraph/linkgraph.h"
29#include "linkgraph/linkgraphschedule.h"
30
31#include "table/strings.h"
32
33#include "safeguards.h"
34
36 StationPool _station_pool("Station");
37 INSTANTIATE_POOL_METHODS(Station)
38
39
40 StationKdtree _station_kdtree{};
41
42void RebuildStationKdtree()
43{
44 std::vector<StationID> stids;
45 for (const Station *st : Station::Iterate()) {
46 stids.push_back(st->index);
47 }
48 _station_kdtree.Build(stids.begin(), stids.end());
49}
50
51
52BaseStation::~BaseStation()
53{
54 if (CleaningPool()) return;
55
56 CloseWindowById(WC_TRAINS_LIST, VehicleListIdentifier(VL_STATION_LIST, VEH_TRAIN, this->owner, this->index).ToWindowNumber());
57 CloseWindowById(WC_ROADVEH_LIST, VehicleListIdentifier(VL_STATION_LIST, VEH_ROAD, this->owner, this->index).ToWindowNumber());
58 CloseWindowById(WC_SHIPS_LIST, VehicleListIdentifier(VL_STATION_LIST, VEH_SHIP, this->owner, this->index).ToWindowNumber());
59 CloseWindowById(WC_AIRCRAFT_LIST, VehicleListIdentifier(VL_STATION_LIST, VEH_AIRCRAFT, this->owner, this->index).ToWindowNumber());
60
61 this->sign.MarkDirty();
62}
63
64Station::Station(TileIndex tile) :
65 SpecializedStation<Station, false>(tile),
66 bus_station(INVALID_TILE, 0, 0),
67 truck_station(INVALID_TILE, 0, 0),
68 ship_station(INVALID_TILE, 0, 0),
69 indtype(IT_INVALID),
70 time_since_load(255),
71 time_since_unload(255),
72 last_vehicle_type(VEH_INVALID)
73{
74 /* this->random_bits is set in Station::AddFacility() */
75}
76
84Station::~Station()
85{
86 if (CleaningPool()) {
87 for (GoodsEntry &ge : this->goods) {
88 if (!ge.HasData()) continue;
89 ge.GetData().cargo.OnCleanPool();
90 }
91 return;
92 }
93
94 while (!this->loading_vehicles.empty()) {
95 this->loading_vehicles.front()->LeaveStation();
96 }
97
98 for (Aircraft *a : Aircraft::Iterate()) {
99 if (!a->IsNormalAircraft()) continue;
100 if (a->targetairport == this->index) a->targetairport = StationID::Invalid();
101 }
102
103 for (CargoType cargo = 0; cargo < NUM_CARGO; ++cargo) {
104 LinkGraph *lg = LinkGraph::GetIfValid(this->goods[cargo].link_graph);
105 if (lg == nullptr) continue;
106
107 for (NodeID node = 0; node < lg->Size(); ++node) {
108 Station *st = Station::Get((*lg)[node].station);
109 if (!st->goods[cargo].HasData()) continue;
110 st->goods[cargo].GetData().flows.erase(this->index);
111 if ((*lg)[node].HasEdgeTo(this->goods[cargo].node) && (*lg)[node][this->goods[cargo].node].LastUpdate() != EconomyTime::INVALID_DATE) {
112 st->goods[cargo].GetData().flows.DeleteFlows(this->index);
113 RerouteCargo(st, cargo, this->index, st->index);
114 }
115 }
116 lg->RemoveNode(this->goods[cargo].node);
117 if (lg->Size() == 0) {
118 LinkGraphSchedule::instance.Dequeue(lg);
119 delete lg;
120 }
121 }
122
123 for (Vehicle *v : Vehicle::Iterate()) {
124 /* Forget about this station if this station is removed */
125 if (v->last_station_visited == this->index) {
126 v->last_station_visited = StationID::Invalid();
127 }
128 if (v->last_loading_station == this->index) {
129 v->last_loading_station = StationID::Invalid();
130 }
131 }
132
133 /* Remove station from industries and towns that reference it. */
134 this->RemoveFromAllNearbyLists();
135
136 /* Clear the persistent storage. */
137 delete this->airport.psa;
138
139 if (this->owner == OWNER_NONE) {
140 /* Invalidate all in case of oil rigs. */
141 InvalidateWindowClassesData(WC_STATION_LIST, 0);
142 } else {
143 InvalidateWindowData(WC_STATION_LIST, this->owner, 0);
144 }
145
146 CloseWindowById(WC_STATION_VIEW, index);
147
148 /* Now delete all orders that go to the station */
149 RemoveOrderFromAllVehicles(OT_GOTO_STATION, this->index);
150
151 /* Remove all news items */
152 DeleteStationNews(this->index);
153
154 for (GoodsEntry &ge : this->goods) {
155 if (!ge.HasData()) continue;
156 ge.GetData().cargo.Truncate();
157 }
158
159 CargoPacket::InvalidateAllFrom(this->index);
160
161 _station_kdtree.Remove(this->index);
162 if (this->sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeStation(this->index));
163}
164
165
170 void BaseStation::PostDestructor(size_t)
171{
172 InvalidateWindowData(WC_SELECT_STATION, 0, 0);
173}
174
175bool BaseStation::SetRoadStopTileData(TileIndex tile, uint8_t data, bool animation)
176{
177 for (RoadStopTileData &tile_data : this->custom_roadstop_tile_data) {
178 if (tile_data.tile == tile) {
179 uint8_t &v = animation ? tile_data.animation_frame : tile_data.random_bits;
180 if (v == data) return false;
181 v = data;
182 return true;
183 }
184 }
185 RoadStopTileData tile_data;
186 tile_data.tile = tile;
187 tile_data.animation_frame = animation ? data : 0;
188 tile_data.random_bits = animation ? 0 : data;
189 this->custom_roadstop_tile_data.push_back(tile_data);
190 return data != 0;
191}
192
193void BaseStation::RemoveRoadStopTileData(TileIndex tile)
194{
195 for (RoadStopTileData &tile_data : this->custom_roadstop_tile_data) {
196 if (tile_data.tile == tile) {
197 tile_data = this->custom_roadstop_tile_data.back();
198 this->custom_roadstop_tile_data.pop_back();
199 return;
200 }
201 }
202}
203
209 RoadStop *Station::GetPrimaryRoadStop(const RoadVehicle *v) const
210{
211 RoadStop *rs = this->GetPrimaryRoadStop(v->IsBus() ? RoadStopType::Bus : RoadStopType::Truck);
212
213 for (; rs != nullptr; rs = rs->next) {
214 /* The vehicle cannot go to this roadstop (different roadtype) */
215 if (!HasTileAnyRoadType(rs->xy, v->compatible_roadtypes)) continue;
216 /* The vehicle is articulated and can therefore not go to a standard road stop. */
217 if (IsBayRoadStopTile(rs->xy) && v->HasArticulatedPart()) continue;
218
219 /* The vehicle can actually go to this road stop. So, return it! */
220 break;
221 }
222
223 return rs;
224}
225
230 void Station::AddFacility(StationFacility new_facility_bit, TileIndex facil_xy)
231{
232 if (this->facilities.None()) {
233 this->MoveSign(facil_xy);
234 this->random_bits = Random();
235 }
236 this->facilities.Set(new_facility_bit);
237 this->owner = _current_company;
238 this->build_date = TimerGameCalendar::date;
239 SetWindowClassesDirty(WC_VEHICLE_ORDERS);
240}
241
247 void Station::MarkTilesDirty(bool cargo_change) const
248{
249 if (this->train_station.tile == INVALID_TILE) return;
250
251 /* cargo_change is set if we're refreshing the tiles due to cargo moving
252 * around. */
253 if (cargo_change) {
254 /* Don't waste time updating if there are no custom station graphics
255 * that might change. Even if there are custom graphics, they might
256 * not change. Unfortunately we have no way of telling. */
257 if (this->speclist.empty()) return;
258 }
259
260 for (TileIndex tile : this->train_station) {
261 if (this->TileBelongsToRailStation(tile)) {
262 MarkTileDirtyByTile(tile);
263 }
264 }
265}
266
267/* virtual */ uint Station::GetPlatformLength(TileIndex tile) const
268{
269 assert(this->TileBelongsToRailStation(tile));
270
271 TileIndexDiff delta = TileOffsByAxis(GetRailStationAxis(tile));
272
273 TileIndex t = tile;
274 uint len = 0;
275 do {
276 t -= delta;
277 len++;
278 } while (IsCompatibleTrainStationTile(t, tile));
279
280 t = tile;
281 do {
282 t += delta;
283 len++;
284 } while (IsCompatibleTrainStationTile(t, tile));
285
286 return len - 1;
287}
288
289/* virtual */ uint Station::GetPlatformLength(TileIndex tile, DiagDirection dir) const
290{
291 TileIndex start_tile = tile;
292 uint length = 0;
293 assert(IsRailStationTile(tile));
294 assert(dir < DIAGDIR_END);
295
296 do {
297 length++;
298 tile += TileOffsByDiagDir(dir);
299 } while (IsCompatibleTrainStationTile(tile, start_tile));
300
301 return length;
302}
303
311 static uint GetTileCatchmentRadius(TileIndex tile, const Station *st)
312{
313 assert(IsTileType(tile, MP_STATION));
314
315 if (_settings_game.station.modified_catchment) {
316 switch (GetStationType(tile)) {
317 case StationType::Rail: return CA_TRAIN;
318 case StationType::Oilrig: return CA_UNMODIFIED;
319 case StationType::Airport: return st->airport.GetSpec()->catchment;
320 case StationType::Truck: return CA_TRUCK;
321 case StationType::Bus: return CA_BUS;
322 case StationType::Dock: return CA_DOCK;
323
324 default: NOT_REACHED();
325 case StationType::Buoy:
326 case StationType::RailWaypoint:
327 case StationType::RoadWaypoint: return CA_NONE;
328 }
329 } else {
330 switch (GetStationType(tile)) {
331 default: return CA_UNMODIFIED;
332 case StationType::Buoy:
333 case StationType::RailWaypoint:
334 case StationType::RoadWaypoint: return CA_NONE;
335 }
336 }
337}
338
343uint Station::GetCatchmentRadius() const
344{
345 uint ret = CA_NONE;
346
347 if (_settings_game.station.modified_catchment) {
348 if (this->bus_stops != nullptr) ret = std::max<uint>(ret, CA_BUS);
349 if (this->truck_stops != nullptr) ret = std::max<uint>(ret, CA_TRUCK);
350 if (this->train_station.tile != INVALID_TILE) ret = std::max<uint>(ret, CA_TRAIN);
351 if (this->ship_station.tile != INVALID_TILE) ret = std::max<uint>(ret, CA_DOCK);
352 if (this->airport.tile != INVALID_TILE) ret = std::max<uint>(ret, this->airport.GetSpec()->catchment);
353 } else {
354 if (this->bus_stops != nullptr || this->truck_stops != nullptr || this->train_station.tile != INVALID_TILE || this->ship_station.tile != INVALID_TILE || this->airport.tile != INVALID_TILE) {
355 ret = CA_UNMODIFIED;
356 }
357 }
358
359 return ret;
360}
361
366 Rect Station::GetCatchmentRect() const
367{
368 assert(!this->rect.IsEmpty());
369
370 /* Compute acceptance rectangle */
371 int catchment_radius = this->GetCatchmentRadius();
372
373 Rect ret = {
374 std::max<int>(this->rect.left - catchment_radius, 0),
375 std::max<int>(this->rect.top - catchment_radius, 0),
376 std::min<int>(this->rect.right + catchment_radius, Map::MaxX()),
377 std::min<int>(this->rect.bottom + catchment_radius, Map::MaxY())
378 };
379
380 return ret;
381}
382
389 void Station::AddIndustryToDeliver(Industry *ind, TileIndex tile)
390{
391 /* Using DistanceMax to get about the same order as with previously used SpiralTileSequence. */
392 uint distance = DistanceMax(this->xy, tile);
393
394 /* Don't check further if this industry is already in the list but update the distance if it's closer */
395 auto pos = std::ranges::find(this->industries_near, ind, &IndustryListEntry::industry);
396 if (pos != this->industries_near.end()) {
397 if (pos->distance > distance) {
398 auto node = this->industries_near.extract(pos);
399 node.value().distance = distance;
400 this->industries_near.insert(std::move(node));
401 }
402 return;
403 }
404
405 /* Include only industries that can accept cargo */
406 if (!ind->IsCargoAccepted()) return;
407
408 this->industries_near.insert(IndustryListEntry{distance, ind});
409}
410
415 void Station::RemoveIndustryToDeliver(Industry *ind)
416{
417 auto pos = std::ranges::find(this->industries_near, ind, &IndustryListEntry::industry);
418 if (pos != this->industries_near.end()) {
419 this->industries_near.erase(pos);
420 }
421}
422
423
427 void Station::RemoveFromAllNearbyLists()
428{
429 FlatSet<TownID> towns;
430 FlatSet<IndustryID> industries;
431
432 for (const auto &tile : this->catchment_tiles) {
433 TileType type = GetTileType(tile);
434 if (type == MP_HOUSE) {
435 towns.insert(GetTownIndex(tile));
436 } else if (type == MP_INDUSTRY) {
437 industries.insert(GetIndustryIndex(tile));
438 }
439 }
440
441 for (const TownID &townid : towns) { Town::Get(townid)->stations_near.erase(this); }
442 for (const IndustryID &industryid : industries) { Industry::Get(industryid)->stations_near.erase(this); }
443}
444
452 bool Station::CatchmentCoversTown(TownID t) const
453{
454 BitmapTileIterator it(this->catchment_tiles);
455 for (TileIndex tile = it; tile != INVALID_TILE; tile = ++it) {
456 if (IsTileType(tile, MP_HOUSE) && GetTownIndex(tile) == t) return true;
457 }
458 return false;
459}
460
466 void Station::RecomputeCatchment(bool no_clear_nearby_lists)
467{
468 this->industries_near.clear();
469 if (!no_clear_nearby_lists) this->RemoveFromAllNearbyLists();
470
471 if (this->rect.IsEmpty()) {
472 this->catchment_tiles.Reset();
473 return;
474 }
475
476 if (!_settings_game.station.serve_neutral_industries && this->industry != nullptr) {
477 /* Station is associated with an industry, so we only need to deliver to that industry. */
478 this->catchment_tiles.Initialize(this->industry->location);
479 for (TileIndex tile : this->industry->location) {
480 if (IsTileType(tile, MP_INDUSTRY) && GetIndustryIndex(tile) == this->industry->index) {
481 this->catchment_tiles.SetTile(tile);
482 }
483 }
484 /* The industry's stations_near may have been computed before its neutral station was built so clear and re-add here. */
485 for (Station *st : this->industry->stations_near) {
486 st->RemoveIndustryToDeliver(this->industry);
487 }
488 this->industry->stations_near.clear();
489 this->industry->stations_near.insert(this);
490 this->industries_near.insert(IndustryListEntry{0, this->industry});
491 return;
492 }
493
494 this->catchment_tiles.Initialize(GetCatchmentRect());
495
496 /* Loop finding all station tiles */
497 TileArea ta(TileXY(this->rect.left, this->rect.top), TileXY(this->rect.right, this->rect.bottom));
498 for (TileIndex tile : ta) {
499 if (!IsTileType(tile, MP_STATION) || GetStationIndex(tile) != this->index) continue;
500
501 uint r = GetTileCatchmentRadius(tile, this);
502 if (r == CA_NONE) continue;
503
504 /* This tile sub-loop doesn't need to test any tiles, they are simply added to the catchment set. */
505 TileArea ta2 = TileArea(tile, 1, 1).Expand(r);
506 for (TileIndex tile2 : ta2) this->catchment_tiles.SetTile(tile2);
507 }
508
509 /* Search catchment tiles for towns and industries */
510 BitmapTileIterator it(this->catchment_tiles);
511 for (TileIndex tile = it; tile != INVALID_TILE; tile = ++it) {
512 if (IsTileType(tile, MP_HOUSE)) {
513 Town *t = Town::GetByTile(tile);
514 t->stations_near.insert(this);
515 }
516 if (IsTileType(tile, MP_INDUSTRY)) {
517 Industry *i = Industry::GetByTile(tile);
518
519 /* Ignore industry if it has a neutral station. It already can't be this station. */
520 if (!_settings_game.station.serve_neutral_industries && i->neutral_station != nullptr) continue;
521
522 i->stations_near.insert(this);
523
524 /* Add if we can deliver to this industry as well */
525 this->AddIndustryToDeliver(i, tile);
526 }
527 }
528}
529
534/* static */ void Station::RecomputeCatchmentForAll()
535{
536 for (Town *t : Town::Iterate()) { t->stations_near.clear(); }
537 for (Industry *i : Industry::Iterate()) { i->stations_near.clear(); }
538 for (Station *st : Station::Iterate()) { st->RecomputeCatchment(true); }
539}
540
541/************************************************************************/
542/* StationRect implementation */
543/************************************************************************/
544
545StationRect::StationRect()
546{
547 this->MakeEmpty();
548}
549
550void StationRect::MakeEmpty()
551{
552 this->left = this->top = this->right = this->bottom = 0;
553}
554
564 bool StationRect::PtInExtendedRect(int x, int y, int distance) const
565{
566 return this->left - distance <= x && x <= this->right + distance &&
567 this->top - distance <= y && y <= this->bottom + distance;
568}
569
570bool StationRect::IsEmpty() const
571{
572 return this->left == 0 || this->left > this->right || this->top > this->bottom;
573}
574
575 CommandCost StationRect::BeforeAddTile(TileIndex tile, StationRectMode mode)
576{
577 int x = TileX(tile);
578 int y = TileY(tile);
579 if (this->IsEmpty()) {
580 /* we are adding the first station tile */
581 if (mode != ADD_TEST) {
582 this->left = this->right = x;
583 this->top = this->bottom = y;
584 }
585 } else if (!this->PtInExtendedRect(x, y)) {
586 /* current rect is not empty and new point is outside this rect
587 * make new spread-out rectangle */
588 Rect new_rect = {std::min(x, this->left), std::min(y, this->top), std::max(x, this->right), std::max(y, this->bottom)};
589
590 /* check new rect dimensions against preset max */
591 int w = new_rect.Width();
592 int h = new_rect.Height();
593 if (mode != ADD_FORCE && (w > _settings_game.station.station_spread || h > _settings_game.station.station_spread)) {
594 assert(mode != ADD_TRY);
595 return CommandCost(STR_ERROR_STATION_TOO_SPREAD_OUT);
596 }
597
598 /* spread-out ok, return true */
599 if (mode != ADD_TEST) {
600 /* we should update the station rect */
601 *this = new_rect;
602 }
603 } else {
604 ; // new point is inside the rect, we don't need to do anything
605 }
606 return CommandCost();
607}
608
609 CommandCost StationRect::BeforeAddRect(TileIndex tile, int w, int h, StationRectMode mode)
610{
611 if (mode == ADD_FORCE || (w <= _settings_game.station.station_spread && h <= _settings_game.station.station_spread)) {
612 /* Important when the old rect is completely inside the new rect, resp. the old one was empty. */
613 CommandCost ret = this->BeforeAddTile(tile, mode);
614 if (ret.Succeeded()) ret = this->BeforeAddTile(TileAddXY(tile, w - 1, h - 1), mode);
615 return ret;
616 }
617 return CommandCost();
618}
619
629/* static */ bool StationRect::ScanForStationTiles(StationID st_id, int left_a, int top_a, int right_a, int bottom_a)
630{
631 TileArea ta(TileXY(left_a, top_a), TileXY(right_a, bottom_a));
632 for (TileIndex tile : ta) {
633 if (IsTileType(tile, MP_STATION) && GetStationIndex(tile) == st_id) return true;
634 }
635
636 return false;
637}
638
639bool StationRect::AfterRemoveTile(BaseStation *st, TileIndex tile)
640{
641 int x = TileX(tile);
642 int y = TileY(tile);
643
644 /* look if removed tile was on the bounding rect edge
645 * and try to reduce the rect by this edge
646 * do it until we have empty rect or nothing to do */
647 for (;;) {
648 /* check if removed tile is on rect edge */
649 bool left_edge = (x == this->left);
650 bool right_edge = (x == this->right);
651 bool top_edge = (y == this->top);
652 bool bottom_edge = (y == this->bottom);
653
654 /* can we reduce the rect in either direction? */
655 bool reduce_x = ((left_edge || right_edge) && !ScanForStationTiles(st->index, x, this->top, x, this->bottom));
656 bool reduce_y = ((top_edge || bottom_edge) && !ScanForStationTiles(st->index, this->left, y, this->right, y));
657 if (!(reduce_x || reduce_y)) break; // nothing to do (can't reduce)
658
659 if (reduce_x) {
660 /* reduce horizontally */
661 if (left_edge) {
662 /* move left edge right */
663 this->left = x = x + 1;
664 } else {
665 /* move right edge left */
666 this->right = x = x - 1;
667 }
668 }
669 if (reduce_y) {
670 /* reduce vertically */
671 if (top_edge) {
672 /* move top edge down */
673 this->top = y = y + 1;
674 } else {
675 /* move bottom edge up */
676 this->bottom = y = y - 1;
677 }
678 }
679
680 if (left > right || top > bottom) {
681 /* can't continue, if the remaining rectangle is empty */
682 this->MakeEmpty();
683 return true; // empty remaining rect
684 }
685 }
686 return false; // non-empty remaining rect
687}
688
689bool StationRect::AfterRemoveRect(BaseStation *st, TileArea ta)
690{
691 assert(this->PtInExtendedRect(TileX(ta.tile), TileY(ta.tile)));
692 assert(this->PtInExtendedRect(TileX(ta.tile) + ta.w - 1, TileY(ta.tile) + ta.h - 1));
693
694 bool empty = this->AfterRemoveTile(st, ta.tile);
695 if (ta.w != 1 || ta.h != 1) empty = empty || this->AfterRemoveTile(st, TileAddXY(ta.tile, ta.w - 1, ta.h - 1));
696 return empty;
697}
698
699 StationRect& StationRect::operator = (const Rect &src)
700{
701 this->left = src.left;
702 this->top = src.top;
703 this->right = src.right;
704 this->bottom = src.bottom;
705 return *this;
706}
707
713 Money AirportMaintenanceCost(Owner owner)
714{
715 Money total_cost = 0;
716
717 for (const Station *st : Station::Iterate()) {
718 if (st->owner == owner && st->facilities.Test(StationFacility::Airport)) {
719 total_cost += _price[PR_INFRASTRUCTURE_AIRPORT] * st->airport.GetSpec()->maintenance_cost;
720 }
721 }
722 /* 3 bits fraction for the maintenance cost factor. */
723 return total_cost >> 3;
724}
725
726bool StationCompare::operator() (const Station *lhs, const Station *rhs) const
727{
728 return lhs->index < rhs->index;
729}
aircraft.h
Base for aircraft.
CargoType
uint8_t CargoType
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:21
NUM_CARGO
static const CargoType NUM_CARGO
Maximum number of cargo types in a game.
Definition cargo_type.h:73
BaseBitSet::Test
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
Definition base_bitset_type.hpp:141
BaseBitSet::None
constexpr bool None() const
Test if none of the values are set.
Definition base_bitset_type.hpp:188
BaseBitSet::Set
constexpr Timpl & Set()
Set all bits.
Definition base_bitset_type.hpp:40
BitmapTileArea::SetTile
void SetTile(TileIndex tile)
Add a tile as part of the tile area.
Definition bitmap_type.h:79
BitmapTileArea::Initialize
void Initialize(const Rect &r)
Initialize the BitmapTileArea with the specified Rect.
Definition bitmap_type.h:57
BitmapTileArea::Reset
void Reset()
Reset and clear the BitmapTileArea.
Definition bitmap_type.h:45
BitmapTileIterator
Iterator to iterate over all tiles belonging to a bitmaptilearea.
Definition bitmap_type.h:106
CommandCost
Common return value for all commands.
Definition command_type.h:24
CommandCost::Succeeded
bool Succeeded() const
Did this command succeed?
Definition command_type.h:168
FlatSet
Flat set implementation that uses a sorted vector for storage.
Definition flatset_type.hpp:20
FlatSet::insert
std::pair< const_iterator, bool > insert(const Tkey &key)
Insert a key into the set, if it does not already exist.
Definition flatset_type.hpp:31
Kdtree
K-dimensional tree, specialised for 2-dimensional space.
Definition kdtree.hpp:33
Kdtree::Build
void Build(It begin, It end)
Clear and rebuild the tree from a new sequence of elements,.
Definition kdtree.hpp:360
Kdtree::Remove
void Remove(const T &element)
Remove a single element from the tree, if it exists.
Definition kdtree.hpp:415
LinkGraphSchedule::instance
static LinkGraphSchedule instance
Static instance of LinkGraphSchedule.
Definition linkgraphschedule.h:52
LinkGraphSchedule::Dequeue
void Dequeue(LinkGraph *lg)
Remove a link graph from the execution queue.
Definition linkgraphschedule.h:77
LinkGraph
A connected component of a link graph.
Definition linkgraph.h:37
LinkGraph::Size
NodeID Size() const
Get the current size of the component.
Definition linkgraph.h:230
LinkGraph::RemoveNode
void RemoveNode(NodeID id)
Remove a node from the link graph by overwriting it with the last node.
Definition linkgraph.cpp:116
OverflowSafeInt< int64_t >
TimerGameCalendar::date
static Date date
Current date in days (day counter).
Definition timer_game_calendar.h:33
TimerGameConst< struct Economy >::INVALID_DATE
static constexpr TimerGame< struct Economy >::Date INVALID_DATE
Representation of an invalid date.
Definition timer_game_common.h:193
command_func.h
Functions related to commands.
company_base.h
Definition of stuff that is very close to a company, like the company struct itself.
_current_company
CompanyID _current_company
Company currently doing an action.
Definition company_cmd.cpp:56
company_func.h
Functions related to companies.
OWNER_NONE
static constexpr Owner OWNER_NONE
The tile has no ownership.
Definition company_type.h:26
DiagDirection
DiagDirection
Enumeration for diagonal directions.
Definition direction_type.h:78
DIAGDIR_END
@ DIAGDIR_END
Used for iterations.
Definition direction_type.h:84
flatset_type.hpp
Flat set container implementation.
Station::MarkTilesDirty
void MarkTilesDirty(bool cargo_change) const
Marks the tiles of the station as dirty.
Definition station.cpp:247
ViewportSign::MarkDirty
void MarkDirty(ZoomLevel maxzoom=ZoomLevel::Max) const
Mark the sign dirty in all viewports.
Definition viewport.cpp:1555
MarkTileDirtyByTile
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_height_override)
Mark a tile given by its index dirty for repaint.
Definition viewport.cpp:2128
industry.h
Base of all industries.
GetIndustryIndex
IndustryID GetIndustryIndex(Tile t)
Get the industry ID of the given tile.
Definition industry_map.h:63
BorderFlag::Random
@ Random
Randomise borders.
linkgraph.h
Declaration of link graph classes used for cargo distribution.
linkgraphschedule.h
Declaration of link graph schedule used for cargo distribution.
DistanceMax
uint DistanceMax(TileIndex t0, TileIndex t1)
Gets the biggest distance component (x or y) between the two given tiles.
Definition map.cpp:201
TileAddXY
TileIndex TileAddXY(TileIndex tile, int x, int y)
Adds a given offset to a tile.
Definition map_func.h:483
TileOffsByAxis
TileIndexDiff TileOffsByAxis(Axis axis)
Convert an Axis to a TileIndexDiff.
Definition map_func.h:568
TileXY
static TileIndex TileXY(uint x, uint y)
Returns the TileIndex of a coordinate.
Definition map_func.h:385
TileY
static uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition map_func.h:438
TileX
static uint TileX(TileIndex tile)
Get the X component of a tile.
Definition map_func.h:428
TileOffsByDiagDir
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition map_func.h:583
TileIndexDiff
int32_t TileIndexDiff
An offset value between two tiles.
Definition map_type.h:23
news_func.h
Functions related to news.
DeleteStationNews
void DeleteStationNews(StationID sid)
Remove news regarding given station so there are no 'unknown station now accepts Mail' or 'First trai...
Definition news_gui.cpp:1027
RemoveOrderFromAllVehicles
void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination, bool hangar)
Removes an order from all vehicles.
Definition order_cmd.cpp:1756
pool_func.hpp
Some methods of Pool are placed here in order to reduce compilation time and binary size.
INSTANTIATE_POOL_METHODS
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don't get linker errors.
Definition pool_func.hpp:210
random_func.hpp
Pseudo random number generator.
HasTileAnyRoadType
bool HasTileAnyRoadType(Tile t, RoadTypes rts)
Check if a tile has one of the specified road types.
Definition road_map.h:206
roadstop_base.h
Base class for roadstops.
roadveh.h
Road vehicle states.
safeguards.h
A number of safeguards to prevent using unsafe methods.
_settings_game
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
_station_pool
StationPool _station_pool("Station")
The pool of stations.
AirportMaintenanceCost
Money AirportMaintenanceCost(Owner owner)
Calculates the maintenance cost of all airports of a company.
Definition station.cpp:713
GetTileCatchmentRadius
static uint GetTileCatchmentRadius(TileIndex tile, const Station *st)
Get the catchment size of an individual station tile.
Definition station.cpp:311
station_base.h
Base classes/functions for stations.
RerouteCargo
void RerouteCargo(Station *st, CargoType cargo, StationID avoid, StationID avoid2)
Reroute cargo of type c at station st or in any vehicles unloading there.
Definition station_cmd.cpp:4144
station_kdtree.h
Declarations for accessing the k-d tree of stations.
GetStationType
StationType GetStationType(Tile t)
Get the station type of this tile.
Definition station_map.h:44
IsBayRoadStopTile
bool IsBayRoadStopTile(Tile t)
Is tile t a bay (non-drive through) road stop station?
Definition station_map.h:266
IsCompatibleTrainStationTile
bool IsCompatibleTrainStationTile(Tile test_tile, Tile station_tile)
Check if a tile is a valid continuation to a railstation tile.
Definition station_map.h:544
IsRailStationTile
bool IsRailStationTile(Tile t)
Is this tile a station tile and a rail station?
Definition station_map.h:102
GetStationIndex
StationID GetStationIndex(Tile t)
Get StationID from a tile.
Definition station_map.h:28
GetRailStationAxis
Axis GetRailStationAxis(Tile t)
Get the rail direction of a rail station.
Definition station_map.h:503
CA_TRAIN
static constexpr uint CA_TRAIN
Catchment for train stations with "modified catchment" enabled.
Definition station_type.h:117
RoadStopType
RoadStopType
Types of RoadStops.
Definition station_type.h:43
RoadStopType::Bus
@ Bus
A standard stop for buses.
StationFacility
StationFacility
The facilities a station might be having.
Definition station_type.h:50
StationFacility::Airport
@ Airport
Station with an airport.
CA_NONE
static constexpr uint CA_NONE
Catchment when the station has no facilities.
Definition station_type.h:114
CA_DOCK
static constexpr uint CA_DOCK
Catchment for docks with "modified catchment" enabled.
Definition station_type.h:118
CA_BUS
static constexpr uint CA_BUS
Catchment for bus stops with "modified catchment" enabled.
Definition station_type.h:115
CA_UNMODIFIED
static constexpr uint CA_UNMODIFIED
Catchment for all stations with "modified catchment" disabled.
Definition station_type.h:120
CA_TRUCK
static constexpr uint CA_TRUCK
Catchment for truck stops with "modified catchment" enabled.
Definition station_type.h:116
stdafx.h
Definition of base types and functions in a cross-platform compatible way.
Aircraft
Aircraft, helicopters, rotors and their shadows belong to this class.
Definition aircraft.h:72
AirportSpec::catchment
uint8_t catchment
catchment area of this airport
Definition newgrf_airport.h:116
Airport::psa
PersistentStorage * psa
Persistent storage for NewGRF airports.
Definition station_base.h:379
Airport::GetSpec
const AirportSpec * GetSpec() const
Get the AirportSpec that from the airport type of this airport.
Definition station_base.h:386
BaseStation
Base class for all station-ish types.
Definition base_station_base.h:58
BaseStation::xy
TileIndex xy
Base tile of the station.
Definition base_station_base.h:59
BaseStation::speclist
std::vector< SpecMapping< StationSpec > > speclist
List of rail station specs of this station.
Definition base_station_base.h:71
BaseStation::facilities
StationFacilities facilities
The facilities that this station has.
Definition base_station_base.h:69
BaseStation::train_station
TileArea train_station
Tile area the train 'station' part covers.
Definition base_station_base.h:83
BaseStation::owner
Owner owner
The owner of this station.
Definition base_station_base.h:68
BaseStation::rect
StationRect rect
NOSAVE: Station spread out rectangle maintained by StationRect::xxx() functions.
Definition base_station_base.h:84
BaseStation::PostDestructor
static void PostDestructor(size_t index)
Invalidating of the JoinStation window has to be done after removing item from the pool.
Definition station.cpp:170
BaseStation::random_bits
uint16_t random_bits
Random bits assigned to this station.
Definition base_station_base.h:76
BaseStation::sign
TrackedViewportSign sign
NOSAVE: Dimensions of sign.
Definition base_station_base.h:60
BaseStation::custom_roadstop_tile_data
std::vector< RoadStopTileData > custom_roadstop_tile_data
List of custom road stop tile data.
Definition base_station_base.h:86
BaseStation::build_date
TimerGameCalendar::Date build_date
Date of construction.
Definition base_station_base.h:74
CargoPacket::InvalidateAllFrom
static void InvalidateAllFrom(Source src)
Invalidates (sets source_id to INVALID_SOURCE) all cargo packets from given source.
Definition cargopacket.cpp:132
GameSettings::station
StationSettings station
settings related to station management
Definition settings_type.h:644
GoodsEntry
Stores station stats for a single cargo.
Definition station_base.h:167
IndustryListEntry
Definition station_base.h:506
Industry
Defines the internal data of a functional industry.
Definition industry.h:62
Industry::IsCargoAccepted
bool IsCargoAccepted() const
Test if this industry accepts any cargo.
Definition industry.h:223
Industry::GetByTile
static Industry * GetByTile(TileIndex tile)
Get the industry of the given tile.
Definition industry.h:251
Industry::location
TileArea location
Location of the industry.
Definition industry.h:106
Industry::neutral_station
Station * neutral_station
Associated neutral station.
Definition industry.h:108
Industry::stations_near
StationList stations_near
NOSAVE: List of nearby stations.
Definition industry.h:123
Map::MaxY
static uint MaxY()
Gets the maximum Y coordinate within the map, including MP_VOID.
Definition map_func.h:308
Map::MaxX
static uint MaxX()
Gets the maximum X coordinate within the map, including MP_VOID.
Definition map_func.h:299
OrthogonalTileArea
Represents the covered area of e.g.
Definition tilearea_type.h:18
OrthogonalTileArea::w
uint16_t w
The width of the area.
Definition tilearea_type.h:20
OrthogonalTileArea::tile
TileIndex tile
The base tile of the area.
Definition tilearea_type.h:19
OrthogonalTileArea::h
uint16_t h
The height of the area.
Definition tilearea_type.h:21
OrthogonalTileArea::Expand
OrthogonalTileArea & Expand(int rad)
Expand a tile area by rad tiles in each direction, keeping within map bounds.
Definition tilearea.cpp:123
PoolID< uint16_t, struct TownIDTag, 64000, 0xFFFF >
Pool::PoolItem<&_vehicle_pool >::Iterate
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Definition pool_type.hpp:436
Pool::PoolItem<&_town_pool >::Get
static Titem * Get(auto index)
Returns Titem with given index.
Definition pool_type.hpp:387
Pool::PoolItem<&_station_pool >::index
Tindex index
Index of this pool item.
Definition pool_type.hpp:286
Pool::PoolItem<&_station_pool >::CleaningPool
static bool CleaningPool()
Returns current state of pool cleaning - yes or no.
Definition pool_type.hpp:366
Pool::PoolItem<&_link_graph_pool >::GetIfValid
static Titem * GetIfValid(auto index)
Returns Titem with given index.
Definition pool_type.hpp:398
Pool
Base class for all pools.
Definition pool_type.hpp:133
Rect
Specification of a rectangle with absolute coordinates of all edges.
Definition geometry_type.hpp:101
Rect::Width
int Width() const
Get width of Rect.
Definition geometry_type.hpp:111
Rect::Height
int Height() const
Get height of Rect.
Definition geometry_type.hpp:117
RoadStopTileData
Definition base_station_base.h:29
RoadStop
A Stop for a Road Vehicle.
Definition roadstop_base.h:21
RoadStop::next
RoadStop * next
Next stop of the given type at this station.
Definition roadstop_base.h:71
RoadStop::xy
TileIndex xy
Position on the map.
Definition roadstop_base.h:70
RoadVehicle
Buses, trucks and trams belong to this class.
Definition roadveh.h:98
RoadVehicle::compatible_roadtypes
RoadTypes compatible_roadtypes
NOSAVE: Roadtypes this consist is powered on.
Definition roadveh.h:110
RoadVehicle::IsBus
bool IsBus() const
Check whether a roadvehicle is a bus.
Definition roadveh_cmd.cpp:82
SpecializedStation
Class defining several overloaded accessors so we don't have to cast base stations that often.
Definition base_station_base.h:211
SpecializedStation< Station, false >::Iterate
static Pool::IterateWrapper< Station > Iterate(size_t from=0)
Returns an iterable ensemble of all valid stations of type T.
Definition base_station_base.h:299
SpecializedStation< Station, false >::Get
static Station * Get(auto index)
Gets station with given index.
Definition base_station_base.h:248
StationRect
StationRect - used to track station spread out rectangle - cheaper than scanning whole map.
Definition base_station_base.h:36
StationRect::ScanForStationTiles
static bool ScanForStationTiles(StationID st_id, int left_a, int top_a, int right_a, int bottom_a)
Check whether station tiles of the given station id exist in the given rectangle.
Definition station.cpp:629
StationRect::PtInExtendedRect
bool PtInExtendedRect(int x, int y, int distance=0) const
Determines whether a given point (x, y) is within a certain distance of the station rectangle.
Definition station.cpp:564
StationSettings::station_spread
uint8_t station_spread
amount a station may spread
Definition settings_type.h:597
StationSettings::modified_catchment
bool modified_catchment
different-size catchment areas
Definition settings_type.h:593
StationSettings::serve_neutral_industries
bool serve_neutral_industries
company stations can serve industries with attached neutral stations
Definition settings_type.h:594
Station
Station data structure.
Definition station_base.h:520
Station::~Station
~Station()
Clean up a station by clearing vehicle orders, invalidating windows and removing link stats.
Definition station.cpp:84
Station::GetPlatformLength
uint GetPlatformLength(TileIndex tile, DiagDirection dir) const override
Determines the REMAINING length of a platform, starting at (and including) the given tile.
Definition station.cpp:289
Station::bus_stops
RoadStop * bus_stops
All the road stops.
Definition station_base.h:529
Station::CatchmentCoversTown
bool CatchmentCoversTown(TownID t) const
Test if the given town ID is covered by our catchment area.
Definition station.cpp:452
Station::ship_station
TileArea ship_station
Tile area the ship 'station' part covers.
Definition station_base.h:535
Station::industries_near
IndustryList industries_near
Cached list of industries near the station that can accept cargo,.
Definition station_base.h:552
Station::GetCatchmentRect
Rect GetCatchmentRect() const
Determines catchment rectangle of this station.
Definition station.cpp:366
Station::industry
Industry * industry
NOSAVE: Associated industry for neutral stations. (Rebuilt on load from Industry->st)
Definition station_base.h:553
Station::MoveSign
void MoveSign(TileIndex new_xy) override
Move the station main coordinate somewhere else.
Definition station_cmd.cpp:452
Station::RecomputeCatchmentForAll
static void RecomputeCatchmentForAll()
Recomputes catchment of all stations.
Definition station.cpp:534
Station::goods
std::array< GoodsEntry, NUM_CARGO > goods
Goods at this station.
Definition station_base.h:549
Station::RemoveFromAllNearbyLists
void RemoveFromAllNearbyLists()
Remove this station from the nearby stations lists of nearby towns and industries.
Definition station.cpp:427
Station::TileBelongsToRailStation
bool TileBelongsToRailStation(TileIndex tile) const override
Check whether a specific tile belongs to this station.
Definition station_base.h:585
Station::catchment_tiles
BitmapTileArea catchment_tiles
NOSAVE: Set of individual tiles covered by catchment area.
Definition station_base.h:540
Station::RecomputeCatchment
void RecomputeCatchment(bool no_clear_nearby_lists=false)
Recompute tiles covered in our catchment area.
Definition station.cpp:466
Station::GetCatchmentRadius
uint GetCatchmentRadius() const
Determines the catchment radius of the station.
Definition station.cpp:343
Station::airport
Airport airport
Tile area the airport covers.
Definition station_base.h:534
Station::AddIndustryToDeliver
void AddIndustryToDeliver(Industry *ind, TileIndex tile)
Add nearby industry to station's industries_near list if it accepts cargo.
Definition station.cpp:389
Station::RemoveIndustryToDeliver
void RemoveIndustryToDeliver(Industry *ind)
Remove nearby industry from station's industries_near list.
Definition station.cpp:415
Station::truck_stops
RoadStop * truck_stops
All the truck stops.
Definition station_base.h:531
Station::AddFacility
void AddFacility(StationFacility new_facility_bit, TileIndex facil_xy)
Called when new facility is built on the station.
Definition station.cpp:230
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > >
Town
Town data structure.
Definition town.h:63
Town::stations_near
StationList stations_near
NOSAVE: List of nearby stations.
Definition town.h:140
TrackedViewportSign::kdtree_valid
bool kdtree_valid
Are the sign data valid for use with the _viewport_sign_kdtree?
Definition viewport_type.h:61
VehicleListIdentifier
The information about a vehicle list.
Definition vehiclelist.h:32
Vehicle
Vehicle data structure.
Definition vehicle_base.h:205
Vehicle::HasArticulatedPart
bool HasArticulatedPart() const
Check if an engine has an articulated part.
Definition vehicle_base.h:931
IsTileType
static bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition tile_map.h:150
GetTileType
static TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
Definition tile_map.h:96
INVALID_TILE
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:95
TileType
TileType
The different types of tiles.
Definition tile_type.h:47
MP_STATION
@ MP_STATION
A tile of a station.
Definition tile_type.h:53
MP_HOUSE
@ MP_HOUSE
A house by a town.
Definition tile_type.h:51
MP_INDUSTRY
@ MP_INDUSTRY
Part of an industry.
Definition tile_type.h:56
TileArea
OrthogonalTileArea TileArea
Shorthand for the much more common orthogonal tile area.
Definition tilearea_type.h:102
town.h
Base of the town class.
GetTownIndex
TownID GetTownIndex(Tile t)
Get the index of which town this house/street is attached to.
Definition town_map.h:23
VEH_INVALID
@ VEH_INVALID
Non-existing type of vehicle.
Definition vehicle_type.h:36
VEH_ROAD
@ VEH_ROAD
Road vehicle type.
Definition vehicle_type.h:26
VEH_AIRCRAFT
@ VEH_AIRCRAFT
Aircraft vehicle type.
Definition vehicle_type.h:28
VEH_SHIP
@ VEH_SHIP
Ship vehicle type.
Definition vehicle_type.h:27
VEH_TRAIN
@ VEH_TRAIN
Train vehicle type.
Definition vehicle_type.h:25
vehiclelist.h
Functions and type for generating vehicle lists.
VL_STATION_LIST
@ VL_STATION_LIST
Index is the station.
Definition vehiclelist.h:25
viewport_func.h
Functions related to (drawing on) viewports.
CloseWindowById
void CloseWindowById(WindowClass cls, WindowNumber number, bool force, int data)
Close a window by its class and window number (if it is open).
Definition window.cpp:1195
SetWindowClassesDirty
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition window.cpp:3205
InvalidateWindowData
void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool gui_scope)
Mark window data of the window of a given class and specific window number as invalid (in need of re-...
Definition window.cpp:3297
InvalidateWindowClassesData
void InvalidateWindowClassesData(WindowClass cls, int data, bool gui_scope)
Mark window data of all windows of a given class as invalid (in need of re-computing) Note that by de...
Definition window.cpp:3314
WC_STATION_LIST
@ WC_STATION_LIST
Station list; Window numbers:
Definition window_type.h:307
WC_ROADVEH_LIST
@ WC_ROADVEH_LIST
Road vehicle list; Window numbers:
Definition window_type.h:319
WC_VEHICLE_ORDERS
@ WC_VEHICLE_ORDERS
Vehicle orders; Window numbers:
Definition window_type.h:217
WC_SELECT_STATION
@ WC_SELECT_STATION
Select station (when joining stations); Window numbers:
Definition window_type.h:247
WC_SHIPS_LIST
@ WC_SHIPS_LIST
Ships list; Window numbers:
Definition window_type.h:325
WC_STATION_VIEW
@ WC_STATION_VIEW
Station view; Window numbers:
Definition window_type.h:350
WC_TRAINS_LIST
@ WC_TRAINS_LIST
Trains list; Window numbers:
Definition window_type.h:313
WC_AIRCRAFT_LIST
@ WC_AIRCRAFT_LIST
Aircraft list; Window numbers:
Definition window_type.h:331