OpenTTD Source 20250924-master-gbec4e71d53
waypoint_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
12#include "command_func.h"
13#include "landscape.h"
14#include "bridge_map.h"
15#include "town.h"
16#include "waypoint_base.h"
19#include "strings_func.h"
20#include "viewport_func.h"
21#include "viewport_kdtree.h"
22#include "window_func.h"
24#include "vehicle_func.h"
25#include "string_func.h"
26#include "company_func.h"
27#include "newgrf_station.h"
28#include "newgrf_roadstop.h"
29#include "company_base.h"
30#include "water.h"
31#include "company_gui.h"
32#include "waypoint_cmd.h"
33#include "landscape_cmd.h"
34#include "station_layout_type.h"
35
36#include "table/strings.h"
37
38#include "safeguards.h"
39
44{
45 Point pt = RemapCoords2(TileX(this->xy) * TILE_SIZE, TileY(this->xy) * TILE_SIZE);
46 if (this->sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeWaypoint(this->index));
47
48 this->sign.UpdatePosition(pt.x, pt.y - 32 * ZOOM_BASE, GetString(STR_WAYPOINT_NAME, this->index));
49
50 _viewport_sign_kdtree.Insert(ViewportSignKdtreeItem::MakeWaypoint(this->index));
51
52 /* Recenter viewport */
54}
55
61{
62 if (this->xy == new_xy) return;
63
64 this->BaseStation::MoveSign(new_xy);
65}
66
75static Waypoint *FindDeletedWaypointCloseTo(TileIndex tile, StringID str, CompanyID cid, bool is_road)
76{
77 Waypoint *best = nullptr;
78 uint thres = 8;
79
80 for (Waypoint *wp : Waypoint::Iterate()) {
81 if (!wp->IsInUse() && wp->string_id == str && wp->owner == cid && HasBit(wp->waypoint_flags, WPF_ROAD) == is_road) {
82 uint cur_dist = DistanceManhattan(tile, wp->xy);
83
84 if (cur_dist < thres) {
85 thres = cur_dist;
86 best = wp;
87 }
88 }
89 }
90
91 return best;
92}
93
102{
103 /* The axis for rail waypoints is easy. */
104 if (IsRailWaypointTile(tile)) return GetRailStationAxis(tile);
105
106 /* Non-plain rail type, no valid axis for waypoints. */
107 if (!IsTileType(tile, MP_RAILWAY) || GetRailTileType(tile) != RAIL_TILE_NORMAL) return INVALID_AXIS;
108
109 switch (GetTrackBits(tile)) {
110 case TRACK_BIT_X: return AXIS_X;
111 case TRACK_BIT_Y: return AXIS_Y;
112 default: return INVALID_AXIS;
113 }
114}
115
124{
125 /* The axis for existing road waypoints is easy. */
126 if (IsRoadWaypointTile(tile)) return GetDriveThroughStopAxis(tile);
127
128 /* Non-plain road type, no valid axis for waypoints. */
129 if (!IsNormalRoadTile(tile)) return INVALID_AXIS;
130
131 RoadBits bits = GetAllRoadBits(tile);
132
133 if ((bits & ROAD_Y) == 0) return AXIS_X;
134 if ((bits & ROAD_X) == 0) return AXIS_Y;
135
136 return INVALID_AXIS;
137}
138
140
148{
149 /* if waypoint is set, then we have special handling to allow building on top of already existing waypoints.
150 * so waypoint points to StationID::Invalid() if we can build on any waypoint.
151 * Or it points to a waypoint if we're only allowed to build on exactly that waypoint. */
152 if (waypoint != nullptr && IsTileType(tile, MP_STATION)) {
153 if (!IsRailWaypoint(tile)) {
154 return ClearTile_Station(tile, DoCommandFlag::Auto); // get error message
155 } else {
156 StationID wp = GetStationIndex(tile);
157 if (*waypoint == StationID::Invalid()) {
158 *waypoint = wp;
159 } else if (*waypoint != wp) {
160 return CommandCost(STR_ERROR_WAYPOINT_ADJOINS_MORE_THAN_ONE_EXISTING);
161 }
162 }
163 }
164
165 if (GetAxisForNewRailWaypoint(tile) != axis) return CommandCost(STR_ERROR_NO_SUITABLE_RAILROAD_TRACK);
166
167 Owner owner = GetTileOwner(tile);
168 CommandCost ret = CheckOwnership(owner);
169 if (ret.Succeeded()) ret = EnsureNoVehicleOnGround(tile);
170 if (ret.Failed()) return ret;
171
172 Slope tileh = GetTileSlope(tile);
173 if (tileh != SLOPE_FLAT &&
174 (!_settings_game.construction.build_on_slopes || IsSteepSlope(tileh) || !(tileh & (0x3 << axis)) || !(tileh & ~(0x3 << axis)))) {
175 return CommandCost(STR_ERROR_FLAT_LAND_REQUIRED);
176 }
177
178 return CommandCost();
179}
180
181extern CommandCost FindJoiningWaypoint(StationID existing_station, StationID station_to_join, bool adjacent, TileArea ta, Waypoint **wp, bool is_road);
182extern CommandCost CanExpandRailStation(const BaseStation *st, TileArea &new_ta);
183extern CommandCost CalculateRoadStopCost(TileArea tile_area, DoCommandFlags flags, bool is_drive_through, StationType station_type, const RoadStopSpec *roadstopspec, Axis axis, DiagDirection ddir, StationID *est, RoadType rt, Money unit_cost);
185
186extern CommandCost RemoveRoadWaypointStop(TileIndex tile, DoCommandFlags flags, int replacement_spec_index);
187
202CommandCost CmdBuildRailWaypoint(DoCommandFlags flags, TileIndex start_tile, Axis axis, uint8_t width, uint8_t height, StationClassID spec_class, uint16_t spec_index, StationID station_to_join, bool adjacent)
203{
204 if (!IsValidAxis(axis)) return CMD_ERROR;
205 /* Check if the given station class is valid */
206 if (static_cast<uint>(spec_class) >= StationClass::GetClassCount()) return CMD_ERROR;
207 const StationClass *cls = StationClass::Get(spec_class);
208 if (!IsWaypointClass(*cls)) return CMD_ERROR;
209 if (spec_index >= cls->GetSpecCount()) return CMD_ERROR;
210
211 /* The number of parts to build */
212 uint8_t count = axis == AXIS_X ? height : width;
213
214 if ((axis == AXIS_X ? width : height) != 1) return CMD_ERROR;
215 if (count == 0 || count > _settings_game.station.station_spread) return CMD_ERROR;
216
217 bool reuse = (station_to_join != NEW_STATION);
218 if (!reuse) station_to_join = StationID::Invalid();
219 bool distant_join = (station_to_join != StationID::Invalid());
220
221 if (distant_join && (!_settings_game.station.distant_join_stations || !Waypoint::IsValidID(station_to_join))) return CMD_ERROR;
222
223 TileArea new_location(start_tile, width, height);
224
225 /* only AddCost for non-existing waypoints */
227 for (TileIndex cur_tile : new_location) {
228 if (!IsRailWaypointTile(cur_tile)) cost.AddCost(_price[PR_BUILD_WAYPOINT_RAIL]);
229 }
230
231 /* Make sure the area below consists of clear tiles. (OR tiles belonging to a certain rail station) */
232 StationID est = StationID::Invalid();
233
234 const StationSpec *spec = StationClass::Get(spec_class)->GetSpec(spec_index);
235 RailStationTileLayout stl{spec, count, 1};
236 auto it = stl.begin();
237
238 /* Check whether the tiles we're building on are valid rail or not. */
239 TileIndexDiff offset = TileOffsByAxis(OtherAxis(axis));
240 for (int i = 0; i < count; i++) {
241 TileIndex tile = start_tile + i * offset;
242 CommandCost ret = IsValidTileForWaypoint(tile, axis, &est);
243 if (ret.Failed()) return ret;
244
245 ret = IsRailStationBridgeAboveOk(tile, spec, StationType::RailWaypoint, *it++ + axis);
246 if (ret.Failed()) return ret;
247 }
248
249 Waypoint *wp = nullptr;
250 CommandCost ret = FindJoiningWaypoint(est, station_to_join, adjacent, new_location, &wp, false);
251 if (ret.Failed()) return ret;
252
253 /* Check if there is an already existing, deleted, waypoint close to us that we can reuse. */
254 TileIndex center_tile = start_tile + (count / 2) * offset;
255 if (wp == nullptr && reuse) wp = FindDeletedWaypointCloseTo(center_tile, STR_SV_STNAME_WAYPOINT, _current_company, false);
256
257 if (wp != nullptr) {
258 /* Reuse an existing waypoint. */
259 if (wp->owner != _current_company) return CommandCost(STR_ERROR_TOO_CLOSE_TO_ANOTHER_WAYPOINT);
260
261 /* Check if we want to expand an already existing waypoint. */
262 if (wp->train_station.tile != INVALID_TILE) {
263 ret = CanExpandRailStation(wp, new_location);
264 if (ret.Failed()) return ret;
265 }
266
267 ret = wp->rect.BeforeAddRect(start_tile, width, height, StationRect::ADD_TEST);
268 if (ret.Failed()) return ret;
269 } else {
270 /* Check if we can create a new waypoint. */
271 if (!Waypoint::CanAllocateItem()) return CommandCost(STR_ERROR_TOO_MANY_STATIONS_LOADING);
272 }
273
274 /* Check if we can allocate a custom spec to this waypoint. */
275 auto specindex = AllocateSpecToStation(spec, wp);
276 if (!specindex.has_value()) return CommandCost(STR_ERROR_TOO_MANY_STATION_SPECS);
277
278 if (flags.Test(DoCommandFlag::Execute)) {
279 if (wp == nullptr) {
280 wp = new Waypoint(start_tile);
281 } else if (!wp->IsInUse()) {
282 /* Move existing (recently deleted) waypoint to the new location */
283 wp->xy = start_tile;
284 }
285 wp->owner = GetTileOwner(start_tile);
286
287 wp->rect.BeforeAddRect(start_tile, width, height, StationRect::ADD_TRY);
288 if (specindex.has_value()) AssignSpecToStation(spec, wp, *specindex);
289
290 wp->delete_ctr = 0;
293 wp->string_id = STR_SV_STNAME_WAYPOINT;
294 wp->train_station = new_location;
295
296 if (wp->town == nullptr) MakeDefaultName(wp);
297
298 wp->UpdateVirtCoord();
299
300 auto it = stl.begin();
301
302 Company *c = Company::Get(wp->owner);
303 for (int i = 0; i < count; i++) {
304 TileIndex tile = start_tile + i * offset;
305 uint8_t old_specindex = HasStationTileRail(tile) ? GetCustomStationSpecIndex(tile) : 0;
307 bool reserved = IsTileType(tile, MP_RAILWAY) ?
310 MakeRailWaypoint(tile, wp->owner, wp->index, axis, *it++, GetRailType(tile));
311 SetCustomStationSpecIndex(tile, *specindex);
312
313 SetRailStationTileFlags(tile, spec);
314
315 SetRailStationReservation(tile, reserved);
317
318 DeallocateSpecFromStation(wp, old_specindex);
320 }
322 }
323
324 return cost;
325}
326
340CommandCost CmdBuildRoadWaypoint(DoCommandFlags flags, TileIndex start_tile, Axis axis, uint8_t width, uint8_t height, RoadStopClassID spec_class, uint16_t spec_index, StationID station_to_join, bool adjacent)
341{
342 if (!IsValidAxis(axis)) return CMD_ERROR;
343 /* Check if the given station class is valid */
344 if (static_cast<uint>(spec_class) >= RoadStopClass::GetClassCount()) return CMD_ERROR;
345 const RoadStopClass *cls = RoadStopClass::Get(spec_class);
346 if (!IsWaypointClass(*cls)) return CMD_ERROR;
347 if (spec_index >= cls->GetSpecCount()) return CMD_ERROR;
348
349 const RoadStopSpec *roadstopspec = RoadStopClass::Get(spec_class)->GetSpec(spec_index);
350
351 /* The number of parts to build */
352 uint8_t count = axis == AXIS_X ? height : width;
353
354 if ((axis == AXIS_X ? width : height) != 1) return CMD_ERROR;
355 if (count == 0 || count > _settings_game.station.station_spread) return CMD_ERROR;
356
357 bool reuse = (station_to_join != NEW_STATION);
358 if (!reuse) station_to_join = StationID::Invalid();
359 bool distant_join = (station_to_join != StationID::Invalid());
360
361 if (distant_join && (!_settings_game.station.distant_join_stations || !Waypoint::IsValidID(station_to_join))) return CMD_ERROR;
362
363 TileArea roadstop_area(start_tile, width, height);
364
365 /* Total road stop cost. */
366 Money unit_cost;
367 if (roadstopspec != nullptr) {
368 unit_cost = roadstopspec->GetBuildCost(PR_BUILD_STATION_TRUCK);
369 } else {
370 unit_cost = _price[PR_BUILD_STATION_TRUCK];
371 }
372 StationID est = StationID::Invalid();
373 CommandCost cost = CalculateRoadStopCost(roadstop_area, flags, true, StationType::RoadWaypoint, roadstopspec, axis, AxisToDiagDir(axis), &est, INVALID_ROADTYPE, unit_cost);
374 if (cost.Failed()) return cost;
375
376 Waypoint *wp = nullptr;
377 CommandCost ret = FindJoiningWaypoint(est, station_to_join, adjacent, roadstop_area, &wp, true);
378 if (ret.Failed()) return ret;
379
380 /* Check if there is an already existing, deleted, waypoint close to us that we can reuse. */
381 TileIndex center_tile = start_tile + (count / 2) * TileOffsByAxis(OtherAxis(axis));
382 if (wp == nullptr && reuse) wp = FindDeletedWaypointCloseTo(center_tile, STR_SV_STNAME_WAYPOINT, _current_company, true);
383
384 if (wp != nullptr) {
385 /* Reuse an existing waypoint. */
386 if (!HasBit(wp->waypoint_flags, WPF_ROAD)) return CMD_ERROR;
387 if (wp->owner != _current_company) return CommandCost(STR_ERROR_TOO_CLOSE_TO_ANOTHER_WAYPOINT);
388
389 ret = wp->rect.BeforeAddRect(start_tile, width, height, StationRect::ADD_TEST);
390 if (ret.Failed()) return ret;
391 } else {
392 /* Check if we can create a new waypoint. */
393 if (!Waypoint::CanAllocateItem()) return CommandCost(STR_ERROR_TOO_MANY_STATIONS_LOADING);
394 }
395
396 /* Check if we can allocate a custom spec to this waypoint. */
397 auto specindex = AllocateSpecToRoadStop(roadstopspec, wp);
398 if (!specindex.has_value()) return CommandCost(STR_ERROR_TOO_MANY_STATION_SPECS);
399
400 if (flags.Test(DoCommandFlag::Execute)) {
401 if (wp == nullptr) {
402 wp = new Waypoint(start_tile);
404 } else if (!wp->IsInUse()) {
405 /* Move existing (recently deleted) waypoint to the new location */
406 wp->xy = start_tile;
407 }
409
410 wp->rect.BeforeAddRect(start_tile, width, height, StationRect::ADD_TRY);
411 if (specindex.has_value()) AssignSpecToRoadStop(roadstopspec, wp, *specindex);
412
413 if (roadstopspec != nullptr) {
414 /* Include this road stop spec's animation trigger bitmask
415 * in the station's cached copy. */
416 wp->cached_roadstop_anim_triggers.Set(roadstopspec->animation.triggers);
417 }
418
419 wp->delete_ctr = 0;
422 wp->string_id = STR_SV_STNAME_WAYPOINT;
423
424 if (wp->town == nullptr) MakeDefaultName(wp);
425
426 wp->UpdateVirtCoord();
427
428 /* Check every tile in the area. */
429 for (TileIndex cur_tile : roadstop_area) {
430 /* Get existing road types and owners before any tile clearing */
431 RoadType road_rt = MayHaveRoad(cur_tile) ? GetRoadType(cur_tile, RTT_ROAD) : INVALID_ROADTYPE;
432 RoadType tram_rt = MayHaveRoad(cur_tile) ? GetRoadType(cur_tile, RTT_TRAM) : INVALID_ROADTYPE;
433 Owner road_owner = road_rt != INVALID_ROADTYPE ? GetRoadOwner(cur_tile, RTT_ROAD) : _current_company;
434 Owner tram_owner = tram_rt != INVALID_ROADTYPE ? GetRoadOwner(cur_tile, RTT_TRAM) : _current_company;
435
436 if (IsRoadWaypointTile(cur_tile)) {
437 RemoveRoadWaypointStop(cur_tile, flags, *specindex);
438 }
439
440 wp->road_waypoint_area.Add(cur_tile);
441
442 wp->rect.BeforeAddTile(cur_tile, StationRect::ADD_TRY);
443
444 /* Update company infrastructure counts. If the current tile is a normal road tile, remove the old
445 * bits first. */
446 if (IsNormalRoadTile(cur_tile)) {
447 UpdateCompanyRoadInfrastructure(road_rt, road_owner, -(int)CountBits(GetRoadBits(cur_tile, RTT_ROAD)));
448 UpdateCompanyRoadInfrastructure(tram_rt, tram_owner, -(int)CountBits(GetRoadBits(cur_tile, RTT_TRAM)));
449 }
450
453
454 MakeDriveThroughRoadStop(cur_tile, wp->owner, road_owner, tram_owner, wp->index, StationType::RoadWaypoint, road_rt, tram_rt, axis);
455 SetCustomRoadStopSpecIndex(cur_tile, *specindex);
456 if (roadstopspec != nullptr) wp->SetRoadStopRandomBits(cur_tile, 0);
457
458 Company::Get(wp->owner)->infrastructure.station++;
459
460 MarkTileDirtyByTile(cur_tile);
461 }
463 }
464 return cost;
465}
466
474{
475 if (tile == 0 || !HasTileWaterGround(tile)) return CommandCost(STR_ERROR_SITE_UNSUITABLE);
476 if (IsBridgeAbove(tile)) return CommandCost(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
477
478 if (!IsTileFlat(tile)) return CommandCost(STR_ERROR_SITE_UNSUITABLE);
479
480 /* Check if there is an already existing, deleted, waypoint close to us that we can reuse. */
481 Waypoint *wp = FindDeletedWaypointCloseTo(tile, STR_SV_STNAME_BUOY, OWNER_NONE, false);
482 if (wp == nullptr && !Waypoint::CanAllocateItem()) return CommandCost(STR_ERROR_TOO_MANY_STATIONS_LOADING);
483
484 CommandCost cost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_WAYPOINT_BUOY]);
485 if (!IsWaterTile(tile)) {
487 if (ret.Failed()) return ret;
488 cost.AddCost(ret.GetCost());
489 }
490
491 if (flags.Test(DoCommandFlag::Execute)) {
492 if (wp == nullptr) {
493 wp = new Waypoint(tile);
494 } else {
495 /* Move existing (recently deleted) buoy to the new location */
496 wp->xy = tile;
498 }
499 wp->rect.BeforeAddTile(tile, StationRect::ADD_TRY);
500
501 wp->string_id = STR_SV_STNAME_BUOY;
502
504 wp->owner = OWNER_NONE;
505
507
508 if (wp->town == nullptr) MakeDefaultName(wp);
509
510 MakeBuoy(tile, wp->index, GetWaterClass(tile));
514
515 wp->UpdateVirtCoord();
517 }
518
519 return cost;
520}
521
530{
531 /* XXX: strange stuff, allow clearing as invalid company when clearing landscape */
533
534 Waypoint *wp = Waypoint::GetByTile(tile);
535
536 if (HasStationInUse(wp->index, false, _current_company)) return CommandCost(STR_ERROR_BUOY_IS_IN_USE);
537 /* remove the buoy if there is a ship on tile when company goes bankrupt... */
538 if (!flags.Test(DoCommandFlag::Bankrupt)) {
540 if (ret.Failed()) return ret;
541 }
542
543 if (flags.Test(DoCommandFlag::Execute)) {
545
547
548 /* We have to set the water tile's state to the same state as before the
549 * buoy was placed. Otherwise one could plant a buoy on a canal edge,
550 * remove it and flood the land (if the canal edge is at level 0) */
551 MakeWaterKeepingClass(tile, GetTileOwner(tile));
552
553 wp->rect.AfterRemoveTile(wp, tile);
554
555 wp->UpdateVirtCoord();
556 wp->delete_ctr = 0;
557 }
558
559 return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_WAYPOINT_BUOY]);
560}
561
567static bool IsUniqueWaypointName(const std::string &name)
568{
569 for (const Waypoint *wp : Waypoint::Iterate()) {
570 if (!wp->name.empty() && wp->name == name) return false;
571 }
572
573 return true;
574}
575
583CommandCost CmdRenameWaypoint(DoCommandFlags flags, StationID waypoint_id, const std::string &text)
584{
585 Waypoint *wp = Waypoint::GetIfValid(waypoint_id);
586 if (wp == nullptr) return CMD_ERROR;
587
588 if (wp->owner != OWNER_NONE) {
590 if (ret.Failed()) return ret;
591 }
592
593 bool reset = text.empty();
594
595 if (!reset) {
597 if (!IsUniqueWaypointName(text)) return CommandCost(STR_ERROR_NAME_MUST_BE_UNIQUE);
598 }
599
600 if (flags.Test(DoCommandFlag::Execute)) {
601 if (reset) {
602 wp->name.clear();
603 } else {
604 wp->name = text;
605 }
606
607 wp->UpdateVirtCoord();
608 }
609 return CommandCost();
610}
debug_inline constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
constexpr uint CountBits(T value)
Counts the number of set bits in a variable.
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
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
constexpr Timpl & Reset()
Reset all bits.
constexpr Timpl & Set()
Set all bits.
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?
Enum-as-bit-set wrapper.
void Insert(const T &element)
Insert a single element in the tree.
Definition kdtree.hpp:396
void Remove(const T &element)
Remove a single element from the tree, if it exists.
Definition kdtree.hpp:415
Struct containing information relating to NewGRF classes for stations and airports.
static NewGRFClass * Get(Tindex class_index)
Get a particular class.
uint GetSpecCount() const
Get the number of allocated specs within the class.
static uint GetClassCount()
Get the number of allocated classes.
const Tspec * GetSpec(uint index) const
Get a spec from the class at a given index.
static Date date
Current date in days (day counter).
Functions related to commands.
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
@ Execute
execute the given command
@ Bankrupt
company bankrupts, skip money check, skip vehicle on tile check in some cases
@ Auto
don't allow building on structures
Definition of stuff that is very close to a company, like the company struct itself.
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 DirtyCompanyInfrastructureWindows(CompanyID company)
Redraw all windows with company infrastructure counts.
GUI Functions related to companies.
static constexpr Owner OWNER_NONE
The tile has no ownership.
bool IsValidAxis(Axis d)
Checks if an integer value is a valid Axis.
DiagDirection AxisToDiagDir(Axis a)
Converts an Axis to a DiagDirection.
Axis OtherAxis(Axis a)
Select the other axis as provided.
Axis
Allow incrementing of DiagDirDiff variables.
@ INVALID_AXIS
Flag for an invalid Axis.
@ AXIS_X
The X axis.
@ AXIS_Y
The y axis.
DiagDirection
Enumeration for diagonal directions.
static const uint ROAD_STOP_TRACKBIT_FACTOR
Multiplier for how many regular track bits a bay stop counts.
@ EXPENSES_CONSTRUCTION
Construction costs.
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_height_override)
Mark a tile given by its index dirty for repaint.
Functions related to OTTD's landscape.
Point RemapCoords2(int x, int y)
Map 3D world or tile coordinate to equivalent 2D coordinate as used in the viewports and smallmap.
Definition landscape.h:95
Command definitions related to landscape (slopes etc.).
uint DistanceManhattan(TileIndex t0, TileIndex t1)
Gets the Manhattan distance between the two given tiles.
Definition map.cpp:142
TileIndexDiff TileOffsByAxis(Axis axis)
Convert an Axis to a TileIndexDiff.
Definition map_func.h:554
static debug_inline uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition map_func.h:424
static debug_inline uint TileX(TileIndex tile)
Get the X component of a tile.
Definition map_func.h:414
int32_t TileIndexDiff
An offset value between two tiles.
Definition map_type.h:23
uint8_t StationGfx
Copy from station_map.h.
NewGRF definitions and structures for road stops.
bool IsWaypointClass(const RoadStopClass &cls)
Test if a RoadStopClass is the waypoint class.
RoadStopClassID
void AssignSpecToStation(const StationSpec *spec, BaseStation *st, uint8_t specindex)
Assign a previously allocated StationSpec specindex to a Station.
void DeallocateSpecFromStation(BaseStation *st, uint8_t specindex)
Deallocate a StationSpec from a Station.
std::optional< uint8_t > AllocateSpecToStation(const StationSpec *spec, BaseStation *st)
Allocate a StationSpec to a Station.
Header file for NewGRF stations.
StationClassID
RailType GetRailType(Tile t)
Gets the rail type of the given tile.
Definition rail_map.h:115
static debug_inline RailTileType GetRailTileType(Tile t)
Returns the RailTileType (normal with or without signals, waypoint or depot).
Definition rail_map.h:36
TrackBits GetTrackBits(Tile tile)
Gets the track bits of the given tile.
Definition rail_map.h:136
@ RAIL_TILE_NORMAL
Normal rail tile without signals.
Definition rail_map.h:24
TrackBits GetRailReservationTrackBits(Tile t)
Returns the reserved track bits of the tile.
Definition rail_map.h:194
void UpdateCompanyRoadInfrastructure(RoadType rt, Owner o, int count)
Update road infrastructure counts for a company.
Definition road_cmd.cpp:186
bool MayHaveRoad(Tile t)
Test whether a tile can have road/tram types.
Definition road_map.cpp:21
static debug_inline bool IsNormalRoadTile(Tile t)
Return whether a tile is a normal road tile.
Definition road_map.h:58
RoadBits GetRoadBits(Tile t, RoadTramType rtt)
Get the present road bits for a specific road type.
Definition road_map.h:112
RoadBits GetAllRoadBits(Tile tile)
Get all set RoadBits on the given tile.
Definition road_map.h:125
Owner GetRoadOwner(Tile t, RoadTramType rtt)
Get the owner of a specific road type.
Definition road_map.h:218
RoadBits
Enumeration for the road parts on a tile.
Definition road_type.h:40
@ ROAD_Y
Full road along the y-axis (north-west + south-east)
Definition road_type.h:47
@ ROAD_X
Full road along the x-axis (south-west + north-east)
Definition road_type.h:46
RoadType
The different roadtypes we support.
Definition road_type.h:23
@ INVALID_ROADTYPE
flag for invalid roadtype
Definition road_type.h:28
A number of safeguards to prevent using unsafe methods.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
static constexpr bool IsSteepSlope(Slope s)
Checks if a slope is steep.
Definition slope_func.h:36
Slope
Enumeration for the slope-type.
Definition slope_type.h:48
@ SLOPE_FLAT
a flat tile
Definition slope_type.h:49
bool HasStationInUse(StationID station, bool include_company, CompanyID company)
Tests whether the company's vehicles have this station in orders.
void SetRailStationTileFlags(TileIndex tile, const StationSpec *statspec)
Set rail station tile flags for the given tile.
Functions related to station layouts.
void SetCustomStationSpecIndex(Tile t, uint8_t specindex)
Set the custom station spec for this tile.
bool IsRailWaypointTile(Tile t)
Is this tile a station tile and a rail waypoint?
void MakeDriveThroughRoadStop(Tile t, Owner station, Owner road, Owner tram, StationID sid, StationType rst, RoadType road_rt, RoadType tram_rt, Axis a)
Make the given tile a drivethrough roadstop tile.
StationID GetStationIndex(Tile t)
Get StationID from a tile.
Definition station_map.h:28
bool HasStationTileRail(Tile t)
Has this station tile a rail? In other words, is this station tile a rail station or rail waypoint?
uint GetCustomStationSpecIndex(Tile t)
Get the custom station spec for this tile.
bool IsRailWaypoint(Tile t)
Is this station tile a rail waypoint?
void SetRailStationReservation(Tile t, bool b)
Set the reservation state of the rail station.
Axis GetRailStationAxis(Tile t)
Get the rail direction of a rail station.
void MakeRailWaypoint(Tile t, Owner o, StationID sid, Axis a, uint8_t section, RailType rt)
Make the given tile a rail waypoint tile.
bool IsRoadWaypointTile(Tile t)
Is this tile a station tile and a road waypoint?
Axis GetDriveThroughStopAxis(Tile t)
Gets the axis of the drive through stop.
void MakeBuoy(Tile t, StationID sid, WaterClass wc)
Make the given tile a buoy tile.
bool HasStationReservation(Tile t)
Get the reservation state of the rail station.
void SetCustomRoadStopSpecIndex(Tile t, uint8_t specindex)
Set the custom road stop spec for this tile.
@ Dock
Station with a dock.
@ TruckStop
Station with truck stops.
@ Train
Station with train station.
@ BusStop
Station with bus stops.
StationType
Station types.
static const uint MAX_LENGTH_STATION_NAME_CHARS
The maximum length of a station name in characters including '\0'.
Definition of base types and functions in a cross-platform compatible way.
size_t Utf8StringLength(std::string_view str)
Get the length of an UTF-8 encoded string in number of characters and thus not the number of bytes th...
Definition string.cpp:347
Functions related to low-level strings.
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
Definition strings.cpp:424
Functions related to OTTD's strings.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
Base class for all station-ish types.
StringID string_id
Default name (town area) of station.
TileIndex xy
Base tile of the station.
StationFacilities facilities
The facilities that this station has.
TileArea train_station
Tile area the train 'station' part covers.
Owner owner
The owner of this station.
uint8_t delete_ctr
Delete counter. If greater than 0 then it is decremented until it reaches 0; the waypoint is then is ...
StationAnimationTriggers cached_roadstop_anim_triggers
NOSAVE: Combined animation trigger bitmask for road stops, used to determine if trigger processing sh...
StationRect rect
NOSAVE: Station spread out rectangle maintained by StationRect::xxx() functions.
bool IsInUse() const
Check whether the base station currently is in use; in use means that it is not scheduled for deletio...
Town * town
The town this station is associated with.
static BaseStation * GetByTile(TileIndex tile)
Get the base station belonging to a specific tile.
TrackedViewportSign sign
NOSAVE: Dimensions of sign.
TimerGameCalendar::Date build_date
Date of construction.
std::string name
Custom name.
uint32_t station
Count of company owned station tiles.
CompanyInfrastructure infrastructure
NOSAVE: Counts of company owned infrastructure.
bool build_on_slopes
allow building on slopes
T y
Y coordinate.
T x
X coordinate.
ConstructionSettings construction
construction of things in-game
StationSettings station
settings related to station management
Represents the covered area of e.g.
void Add(TileIndex to_add)
Add a single tile to a tile area; enlarge if needed.
Definition tilearea.cpp:43
TileIndex tile
The base tile of the area.
static Titem * Get(auto index)
Returns Titem with given index.
Tindex index
Index of this pool item.
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
static bool IsValidID(auto index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
Road stop specification.
Money GetBuildCost(Price category) const
Get the cost for building a road stop of this type.
static bool IsValidID(auto index)
Tests whether given index is a valid index for station of this type.
static Pool::IterateWrapper< Waypoint > Iterate(size_t from=0)
Returns an iterable ensemble of all valid stations of type T.
static Waypoint * GetIfValid(auto index)
Returns station if the index is a valid index for this station type.
uint8_t station_spread
amount a station may spread
bool distant_join_stations
allow to join non-adjacent stations
Station specification.
void UpdatePosition(int center, int top, std::string_view str, std::string_view str_small={})
Update the position of the viewport sign.
bool kdtree_valid
Are the sign data valid for use with the _viewport_sign_kdtree?
Representation of a waypoint.
TileArea road_waypoint_area
Tile area the road waypoint part covers.
uint16_t waypoint_flags
Waypoint flags, see WaypointFlags.
void MoveSign(TileIndex new_xy) override
Move the waypoint main coordinate somewhere else.
void UpdateVirtCoord() override
Update the virtual coords needed to draw the waypoint sign.
bool IsTileFlat(TileIndex tile, int *h)
Check if a given tile is flat.
Definition tile_map.cpp:95
Owner GetTileOwner(Tile tile)
Returns the owner of a tile.
Definition tile_map.h:178
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
static constexpr uint TILE_SIZE
Tile size in world coordinates.
Definition tile_type.h:15
@ MP_STATION
A tile of a station.
Definition tile_type.h:53
@ MP_RAILWAY
A railway.
Definition tile_type.h:49
Definition of the game-calendar-timer.
Base of the town class.
void MakeDefaultName(T *obj)
Set the default name for a depot/waypoint.
Definition town.h:284
Track AxisToTrack(Axis a)
Convert an Axis to the corresponding Track AXIS_X -> TRACK_X AXIS_Y -> TRACK_Y Uses the fact that the...
Definition track_func.h:66
@ TRACK_BIT_Y
Y-axis track.
Definition track_type.h:38
@ TRACK_BIT_X
X-axis track.
Definition track_type.h:37
CommandCost EnsureNoVehicleOnGround(TileIndex tile)
Ensure there is no vehicle at the ground at the given position.
Definition vehicle.cpp:527
Functions related to vehicles.
Functions related to (drawing on) viewports.
Functions related to water (management)
void ClearNeighbourNonFloodingStates(TileIndex tile)
Clear non-flooding state of the tiles around a tile.
Definition water_cmd.cpp:97
void CheckForDockingTile(TileIndex t)
Mark the supplied tile as a docking tile if it is suitable for docking.
bool HasTileWaterGround(Tile t)
Checks whether the tile has water at the ground.
Definition water_map.h:352
WaterClass GetWaterClass(Tile t)
Get the water class at a tile.
Definition water_map.h:114
bool IsWaterTile(Tile t)
Is it a water tile with plain water?
Definition water_map.h:192
Handles dividing the water in the map into regions to assist pathfinding.
Base of waypoints.
@ WPF_ROAD
This is a road waypoint.
static CommandCost IsValidTileForWaypoint(TileIndex tile, Axis axis, StationID *waypoint)
Check whether the given tile is suitable for a waypoint.
CommandCost CmdBuildRoadWaypoint(DoCommandFlags flags, TileIndex start_tile, Axis axis, uint8_t width, uint8_t height, RoadStopClassID spec_class, uint16_t spec_index, StationID station_to_join, bool adjacent)
Build a road waypoint on an existing road.
CommandCost CmdBuildRailWaypoint(DoCommandFlags flags, TileIndex start_tile, Axis axis, uint8_t width, uint8_t height, StationClassID spec_class, uint16_t spec_index, StationID station_to_join, bool adjacent)
Convert existing rail to waypoint.
CommandCost IsRailStationBridgeAboveOk(TileIndex tile, const StationSpec *spec, StationType type, StationGfx layout)
Test if a rail station can be built below a bridge.
CommandCost CanExpandRailStation(const BaseStation *st, TileArea &new_ta)
Check whether we can expand the rail part of the given station.
Axis GetAxisForNewRailWaypoint(TileIndex tile)
Get the axis for a new rail waypoint.
Axis GetAxisForNewRoadWaypoint(TileIndex tile)
Get the axis for a new road waypoint.
CommandCost FindJoiningWaypoint(StationID existing_station, StationID station_to_join, bool adjacent, TileArea ta, Waypoint **wp, bool is_road)
Find a nearby waypoint that joins this waypoint.
CommandCost RemoveRoadWaypointStop(TileIndex tile, DoCommandFlags flags, int replacement_spec_index)
Remove a road waypoint.
CommandCost RemoveBuoy(TileIndex tile, DoCommandFlags flags)
Remove a buoy.
CommandCost ClearTile_Station(TileIndex tile, DoCommandFlags flags)
Clear a single tile of a station.
CommandCost CmdRenameWaypoint(DoCommandFlags flags, StationID waypoint_id, const std::string &text)
Rename a waypoint.
CommandCost CmdBuildBuoy(DoCommandFlags flags, TileIndex tile)
Build a buoy.
static bool IsUniqueWaypointName(const std::string &name)
Check whether the name is unique amongst the waypoints.
static Waypoint * FindDeletedWaypointCloseTo(TileIndex tile, StringID str, CompanyID cid, bool is_road)
Find a deleted waypoint close to a tile.
CommandCost CalculateRoadStopCost(TileArea tile_area, DoCommandFlags flags, bool is_drive_through, StationType station_type, const RoadStopSpec *roadstopspec, Axis axis, DiagDirection ddir, StationID *est, RoadType rt, Money unit_cost)
Calculates cost of new road stops within the area.
Command definitions related to waypoints.
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:3276
Window functions not directly related to making/drawing windows.
@ WC_WAYPOINT_VIEW
Waypoint view; Window numbers:
Entry point for OpenTTD to YAPF's cache.
void YapfNotifyTrackLayoutChange(TileIndex tile, Track track)
Use this function to notify YAPF that track layout (or signal configuration) has change.