OpenTTD

rail_cmd.cpp
Go to the documentation of this file.
1 /* $Id: rail_cmd.cpp 27893 2017-08-13 18:38:42Z frosch $ */
2
3 /*
4 * This file is part of OpenTTD.
5 * 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.
6 * 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.
7 * 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/>.
8 */
9
12 #include "stdafx.h"
13 #include "cmd_helper.h"
14 #include "viewport_func.h"
15 #include "command_func.h"
16 #include "depot_base.h"
17 #include "pathfinder/yapf/yapf_cache.h"
18 #include "newgrf_debug.h"
19 #include "newgrf_railtype.h"
20 #include "train.h"
21 #include "autoslope.h"
22 #include "water.h"
23 #include "tunnelbridge_map.h"
24 #include "vehicle_func.h"
25 #include "sound_func.h"
26 #include "tunnelbridge.h"
27 #include "elrail_func.h"
28 #include "town.h"
29 #include "pbs.h"
30 #include "company_base.h"
31 #include "core/backup_type.hpp"
32 #include "date_func.h"
33 #include "strings_func.h"
34 #include "company_gui.h"
35 #include "object_map.h"
36
37 #include "table/strings.h"
38 #include "table/railtypes.h"
39 #include "table/track_land.h"
40
41 #include "safeguards.h"
42
44 typedef SmallVector<Train *, 16> TrainList;
45
46 RailtypeInfo _railtypes[RAILTYPE_END];
47 RailType _sorted_railtypes[RAILTYPE_END];
48 uint8 _sorted_railtypes_size;
49
51 enum SignalOffsets {
52 SIGNAL_TO_SOUTHWEST,
53 SIGNAL_TO_NORTHEAST,
54 SIGNAL_TO_SOUTHEAST,
55 SIGNAL_TO_NORTHWEST,
56 SIGNAL_TO_EAST,
57 SIGNAL_TO_WEST,
58 SIGNAL_TO_SOUTH,
59 SIGNAL_TO_NORTH,
60 };
61
65 void ResetRailTypes()
66 {
67 assert_compile(lengthof(_original_railtypes) <= lengthof(_railtypes));
68
69 uint i = 0;
70 for (; i < lengthof(_original_railtypes); i++) _railtypes[i] = _original_railtypes[i];
71
72 static const RailtypeInfo empty_railtype = {
73 {0,0,0,0,0,0,0,0,0,0,0,0},
74 {0,0,0,0,0,0,0,0,{}},
75 {0,0,0,0,0,0,0,0},
76 {0,0,0,0,0,0},
77 0, RAILTYPES_NONE, RAILTYPES_NONE, 0, 0, 0, RTFB_NONE, 0, 0, 0, 0, 0,
78 RailTypeLabelList(), 0, 0, RAILTYPES_NONE, RAILTYPES_NONE, 0,
79 {}, {} };
80 for (; i < lengthof(_railtypes); i++) _railtypes[i] = empty_railtype;
81 }
82
83 void ResolveRailTypeGUISprites(RailtypeInfo *rti)
84 {
85 SpriteID cursors_base = GetCustomRailSprite(rti, INVALID_TILE, RTSG_CURSORS);
86 if (cursors_base != 0) {
87 rti->gui_sprites.build_ns_rail = cursors_base + 0;
88 rti->gui_sprites.build_x_rail = cursors_base + 1;
89 rti->gui_sprites.build_ew_rail = cursors_base + 2;
90 rti->gui_sprites.build_y_rail = cursors_base + 3;
91 rti->gui_sprites.auto_rail = cursors_base + 4;
92 rti->gui_sprites.build_depot = cursors_base + 5;
93 rti->gui_sprites.build_tunnel = cursors_base + 6;
94 rti->gui_sprites.convert_rail = cursors_base + 7;
95 rti->cursor.rail_ns = cursors_base + 8;
96 rti->cursor.rail_swne = cursors_base + 9;
97 rti->cursor.rail_ew = cursors_base + 10;
98 rti->cursor.rail_nwse = cursors_base + 11;
99 rti->cursor.autorail = cursors_base + 12;
100 rti->cursor.depot = cursors_base + 13;
101 rti->cursor.tunnel = cursors_base + 14;
102 rti->cursor.convert = cursors_base + 15;
103 }
104
105 /* Array of default GUI signal sprite numbers. */
106 const SpriteID _signal_lookup[2][SIGTYPE_END] = {
107 {SPR_IMG_SIGNAL_ELECTRIC_NORM, SPR_IMG_SIGNAL_ELECTRIC_ENTRY, SPR_IMG_SIGNAL_ELECTRIC_EXIT,
108 SPR_IMG_SIGNAL_ELECTRIC_COMBO, SPR_IMG_SIGNAL_ELECTRIC_PBS, SPR_IMG_SIGNAL_ELECTRIC_PBS_OWAY},
109
110 {SPR_IMG_SIGNAL_SEMAPHORE_NORM, SPR_IMG_SIGNAL_SEMAPHORE_ENTRY, SPR_IMG_SIGNAL_SEMAPHORE_EXIT,
111 SPR_IMG_SIGNAL_SEMAPHORE_COMBO, SPR_IMG_SIGNAL_SEMAPHORE_PBS, SPR_IMG_SIGNAL_SEMAPHORE_PBS_OWAY},
112 };
113
114 for (SignalType type = SIGTYPE_NORMAL; type < SIGTYPE_END; type = (SignalType)(type + 1)) {
115 for (SignalVariant var = SIG_ELECTRIC; var <= SIG_SEMAPHORE; var = (SignalVariant)(var + 1)) {
116 SpriteID red = GetCustomSignalSprite(rti, INVALID_TILE, type, var, SIGNAL_STATE_RED, true);
117 SpriteID green = GetCustomSignalSprite(rti, INVALID_TILE, type, var, SIGNAL_STATE_GREEN, true);
118 rti->gui_sprites.signals[type][var][0] = (red != 0) ? red + SIGNAL_TO_SOUTH : _signal_lookup[var][type];
119 rti->gui_sprites.signals[type][var][1] = (green != 0) ? green + SIGNAL_TO_SOUTH : _signal_lookup[var][type] + 1;
120 }
121 }
122 }
123
130 static int CDECL CompareRailTypes(const RailType *first, const RailType *second)
131 {
132 return GetRailTypeInfo(*first)->sorting_order - GetRailTypeInfo(*second)->sorting_order;
133 }
134
138 void InitRailTypes()
139 {
140 for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
141 RailtypeInfo *rti = &_railtypes[rt];
142 ResolveRailTypeGUISprites(rti);
143 }
144
145 _sorted_railtypes_size = 0;
146 for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
147 if (_railtypes[rt].label != 0) {
148 _sorted_railtypes[_sorted_railtypes_size++] = rt;
149 }
150 }
151 QSortT(_sorted_railtypes, _sorted_railtypes_size, CompareRailTypes);
152 }
153
157 RailType AllocateRailType(RailTypeLabel label)
158 {
159 for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) {
160 RailtypeInfo *rti = &_railtypes[rt];
161
162 if (rti->label == 0) {
163 /* Set up new rail type */
164 *rti = _original_railtypes[RAILTYPE_RAIL];
165 rti->label = label;
166 rti->alternate_labels.Clear();
167
168 /* Make us compatible with ourself. */
169 rti->powered_railtypes = (RailTypes)(1 << rt);
170 rti->compatible_railtypes = (RailTypes)(1 << rt);
171
172 /* We also introduce ourself. */
173 rti->introduces_railtypes = (RailTypes)(1 << rt);
174
175 /* Default sort order; order of allocation, but with some
176 * offsets so it's easier for NewGRF to pick a spot without
177 * changing the order of other (original) rail types.
178 * The << is so you can place other railtypes in between the
179 * other railtypes, the 7 is to be able to place something
180 * before the first (default) rail type. */
181 rti->sorting_order = rt << 4 | 7;
182 return rt;
183 }
184 }
185
186 return INVALID_RAILTYPE;
187 }
188
189 static const byte _track_sloped_sprites[14] = {
190 14, 15, 22, 13,
191 0, 21, 17, 12,
192 23, 0, 18, 20,
193 19, 16
194 };
195
196
197 /* 4
198 * ---------
199 * |\ /|
200 * | \ 1/ |
201 * | \ / |
202 * | \ / |
203 * 16| \ |32
204 * | / \2 |
205 * | / \ |
206 * | / \ |
207 * |/ \|
208 * ---------
209 * 8
210 */
211
212
213
214 /* MAP2 byte: abcd???? => Signal On? Same coding as map3lo
215 * MAP3LO byte: abcd???? => Signal Exists?
216 * a and b are for diagonals, upper and left,
217 * one for each direction. (ie a == NE->SW, b ==
218 * SW->NE, or v.v., I don't know. b and c are
219 * similar for lower and right.
220 * MAP2 byte: ????abcd => Type of ground.
221 * MAP3LO byte: ????abcd => Type of rail.
222 * MAP5: 00abcdef => rail
223 * 01abcdef => rail w/ signals
224 * 10uuuuuu => unused
225 * 11uuuudd => rail depot
226 */
227
236 static CommandCost EnsureNoTrainOnTrack(TileIndex tile, Track track)
237 {
238 TrackBits rail_bits = TrackToTrackBits(track);
239 return EnsureNoTrainOnTrackBits(tile, rail_bits);
240 }
241
249 static CommandCost CheckTrackCombination(TileIndex tile, TrackBits to_build, uint flags)
250 {
251 if (!IsPlainRail(tile)) return_cmd_error(STR_ERROR_IMPOSSIBLE_TRACK_COMBINATION);
252
253 /* So, we have a tile with tracks on it (and possibly signals). Let's see
254 * what tracks first */
255 TrackBits current = GetTrackBits(tile); // The current track layout.
256 TrackBits future = current | to_build; // The track layout we want to build.
257
258 /* Are we really building something new? */
259 if (current == future) {
260 /* Nothing new is being built */
261 return_cmd_error(STR_ERROR_ALREADY_BUILT);
262 }
263
264 /* Let's see if we may build this */
265 if ((flags & DC_NO_RAIL_OVERLAP) || HasSignals(tile)) {
266 /* If we are not allowed to overlap (flag is on for ai companies or we have
267 * signals on the tile), check that */
268 if (future != TRACK_BIT_HORZ && future != TRACK_BIT_VERT) {
269 return_cmd_error((flags & DC_NO_RAIL_OVERLAP) ? STR_ERROR_IMPOSSIBLE_TRACK_COMBINATION : STR_ERROR_MUST_REMOVE_SIGNALS_FIRST);
270 }
271 }
272 /* Normally, we may overlap and any combination is valid */
273 return CommandCost();
274 }
275
276
278 static const TrackBits _valid_tracks_without_foundation[15] = {
279 TRACK_BIT_ALL,
280 TRACK_BIT_RIGHT,
281 TRACK_BIT_UPPER,
282 TRACK_BIT_X,
283
284 TRACK_BIT_LEFT,
285 TRACK_BIT_NONE,
286 TRACK_BIT_Y,
287 TRACK_BIT_LOWER,
288
289 TRACK_BIT_LOWER,
290 TRACK_BIT_Y,
291 TRACK_BIT_NONE,
292 TRACK_BIT_LEFT,
293
294 TRACK_BIT_X,
295 TRACK_BIT_UPPER,
296 TRACK_BIT_RIGHT,
297 };
298
300 static const TrackBits _valid_tracks_on_leveled_foundation[15] = {
301 TRACK_BIT_NONE,
302 TRACK_BIT_LEFT,
303 TRACK_BIT_LOWER,
304 TRACK_BIT_Y | TRACK_BIT_LOWER | TRACK_BIT_LEFT,
305
306 TRACK_BIT_RIGHT,
307 TRACK_BIT_ALL,
308 TRACK_BIT_X | TRACK_BIT_LOWER | TRACK_BIT_RIGHT,
309 TRACK_BIT_ALL,
310
311 TRACK_BIT_UPPER,
312 TRACK_BIT_X | TRACK_BIT_UPPER | TRACK_BIT_LEFT,
313 TRACK_BIT_ALL,
314 TRACK_BIT_ALL,
315
316 TRACK_BIT_Y | TRACK_BIT_UPPER | TRACK_BIT_RIGHT,
317 TRACK_BIT_ALL,
318 TRACK_BIT_ALL
319 };
320
328 Foundation GetRailFoundation(Slope tileh, TrackBits bits)
329 {
330 if (bits == TRACK_BIT_NONE) return FOUNDATION_NONE;
331
332 if (IsSteepSlope(tileh)) {
333 /* Test for inclined foundations */
334 if (bits == TRACK_BIT_X) return FOUNDATION_INCLINED_X;
335 if (bits == TRACK_BIT_Y) return FOUNDATION_INCLINED_Y;
336
337 /* Get higher track */
338 Corner highest_corner = GetHighestSlopeCorner(tileh);
339 TrackBits higher_track = CornerToTrackBits(highest_corner);
340
341 /* Only higher track? */
342 if (bits == higher_track) return HalftileFoundation(highest_corner);
343
344 /* Overlap with higher track? */
345 if (TracksOverlap(bits | higher_track)) return FOUNDATION_INVALID;
346
347 /* either lower track or both higher and lower track */
348 return ((bits & higher_track) != 0 ? FOUNDATION_STEEP_BOTH : FOUNDATION_STEEP_LOWER);
349 } else {
350 if ((~_valid_tracks_without_foundation[tileh] & bits) == 0) return FOUNDATION_NONE;
351
352 bool valid_on_leveled = ((~_valid_tracks_on_leveled_foundation[tileh] & bits) == 0);
353
354 Corner track_corner;
355 switch (bits) {
356 case TRACK_BIT_LEFT: track_corner = CORNER_W; break;
357 case TRACK_BIT_LOWER: track_corner = CORNER_S; break;
358 case TRACK_BIT_RIGHT: track_corner = CORNER_E; break;
359 case TRACK_BIT_UPPER: track_corner = CORNER_N; break;
360
361 case TRACK_BIT_HORZ:
362 if (tileh == SLOPE_N) return HalftileFoundation(CORNER_N);
363 if (tileh == SLOPE_S) return HalftileFoundation(CORNER_S);
364 return (valid_on_leveled ? FOUNDATION_LEVELED : FOUNDATION_INVALID);
365
366 case TRACK_BIT_VERT:
367 if (tileh == SLOPE_W) return HalftileFoundation(CORNER_W);
368 if (tileh == SLOPE_E) return HalftileFoundation(CORNER_E);
369 return (valid_on_leveled ? FOUNDATION_LEVELED : FOUNDATION_INVALID);
370
371 case TRACK_BIT_X:
372 if (IsSlopeWithOneCornerRaised(tileh)) return FOUNDATION_INCLINED_X;
373 return (valid_on_leveled ? FOUNDATION_LEVELED : FOUNDATION_INVALID);
374
375 case TRACK_BIT_Y:
376 if (IsSlopeWithOneCornerRaised(tileh)) return FOUNDATION_INCLINED_Y;
377 return (valid_on_leveled ? FOUNDATION_LEVELED : FOUNDATION_INVALID);
378
379 default:
380 return (valid_on_leveled ? FOUNDATION_LEVELED : FOUNDATION_INVALID);
381 }
382 /* Single diagonal track */
383
384 /* Track must be at least valid on leveled foundation */
385 if (!valid_on_leveled) return FOUNDATION_INVALID;
386
387 /* If slope has three raised corners, build leveled foundation */
388 if (IsSlopeWithThreeCornersRaised(tileh)) return FOUNDATION_LEVELED;
389
390 /* If neighboured corners of track_corner are lowered, build halftile foundation */
391 if ((tileh & SlopeWithThreeCornersRaised(OppositeCorner(track_corner))) == SlopeWithOneCornerRaised(track_corner)) return HalftileFoundation(track_corner);
392
393 /* else special anti-zig-zag foundation */
394 return SpecialRailFoundation(track_corner);
395 }
396 }
397
398
408 static CommandCost CheckRailSlope(Slope tileh, TrackBits rail_bits, TrackBits existing, TileIndex tile)
409 {
410 /* don't allow building on the lower side of a coast */
411 if (GetFloodingBehaviour(tile) != FLOOD_NONE) {
412 if (!IsSteepSlope(tileh) && ((~_valid_tracks_on_leveled_foundation[tileh] & (rail_bits | existing)) != 0)) return_cmd_error(STR_ERROR_CAN_T_BUILD_ON_WATER);
413 }
414
415 Foundation f_new = GetRailFoundation(tileh, rail_bits | existing);
416
417 /* check track/slope combination */
418 if ((f_new == FOUNDATION_INVALID) ||
419 ((f_new != FOUNDATION_NONE) && (!_settings_game.construction.build_on_slopes))) {
420 return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
421 }
422
423 Foundation f_old = GetRailFoundation(tileh, existing);
424 return CommandCost(EXPENSES_CONSTRUCTION, f_new != f_old ? _price[PR_BUILD_FOUNDATION] : (Money)0);
425 }
426
427 /* Validate functions for rail building */
428 static inline bool ValParamTrackOrientation(Track track)
429 {
430 return IsValidTrack(track);
431 }
432
442 CommandCost CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
443 {
444 RailType railtype = Extract<RailType, 0, 4>(p1);
445 Track track = Extract<Track, 0, 3>(p2);
446 CommandCost cost(EXPENSES_CONSTRUCTION);
447
448 if (!ValParamRailtype(railtype) || !ValParamTrackOrientation(track)) return CMD_ERROR;
449
450 Slope tileh = GetTileSlope(tile);
451 TrackBits trackbit = TrackToTrackBits(track);
452
453 switch (GetTileType(tile)) {
454 case MP_RAILWAY: {
455 CommandCost ret = CheckTileOwnership(tile);
456 if (ret.Failed()) return ret;
457
458 if (!IsPlainRail(tile)) return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); // just get appropriate error message
459
460 if (!IsCompatibleRail(GetRailType(tile), railtype)) return_cmd_error(STR_ERROR_IMPOSSIBLE_TRACK_COMBINATION);
461
462 ret = CheckTrackCombination(tile, trackbit, flags);
463 if (ret.Succeeded()) ret = EnsureNoTrainOnTrack(tile, track);
464 if (ret.Failed()) return ret;
465
466 ret = CheckRailSlope(tileh, trackbit, GetTrackBits(tile), tile);
467 if (ret.Failed()) return ret;
468 cost.AddCost(ret);
469
470 /* If the rail types don't match, try to convert only if engines of
471 * the new rail type are not powered on the present rail type and engines of
472 * the present rail type are powered on the new rail type. */
473 if (GetRailType(tile) != railtype && !HasPowerOnRail(railtype, GetRailType(tile))) {
474 if (HasPowerOnRail(GetRailType(tile), railtype)) {
475 ret = DoCommand(tile, tile, railtype, flags, CMD_CONVERT_RAIL);
476 if (ret.Failed()) return ret;
477 cost.AddCost(ret);
478 } else {
479 return CMD_ERROR;
480 }
481 }
482
483 if (flags & DC_EXEC) {
484 SetRailGroundType(tile, RAIL_GROUND_BARREN);
485 TrackBits bits = GetTrackBits(tile);
486 SetTrackBits(tile, bits | trackbit);
487 /* Subtract old infrastructure count. */
488 uint pieces = CountBits(bits);
489 if (TracksOverlap(bits)) pieces *= pieces;
490 Company::Get(GetTileOwner(tile))->infrastructure.rail[GetRailType(tile)] -= pieces;
491 /* Add new infrastructure count. */
492 pieces = CountBits(bits | trackbit);
493 if (TracksOverlap(bits | trackbit)) pieces *= pieces;
494 Company::Get(GetTileOwner(tile))->infrastructure.rail[GetRailType(tile)] += pieces;
495 DirtyCompanyInfrastructureWindows(GetTileOwner(tile));
496 }
497 break;
498 }
499
500 case MP_ROAD: {
501 /* Level crossings may only be built on these slopes */
502 if (!HasBit(VALID_LEVEL_CROSSING_SLOPES, tileh)) return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
503
504 CommandCost ret = EnsureNoVehicleOnGround(tile);
505 if (ret.Failed()) return ret;
506
507 if (IsNormalRoad(tile)) {
508 if (HasRoadWorks(tile)) return_cmd_error(STR_ERROR_ROAD_WORKS_IN_PROGRESS);
509
510 if (GetDisallowedRoadDirections(tile) != DRD_NONE) return_cmd_error(STR_ERROR_CROSSING_ON_ONEWAY_ROAD);
511
512 if (RailNoLevelCrossings(railtype)) return_cmd_error(STR_ERROR_CROSSING_DISALLOWED);
513
514 RoadTypes roadtypes = GetRoadTypes(tile);
515 RoadBits road = GetRoadBits(tile, ROADTYPE_ROAD);
516 RoadBits tram = GetRoadBits(tile, ROADTYPE_TRAM);
517 if ((track == TRACK_X && ((road | tram) & ROAD_X) == 0) ||
518 (track == TRACK_Y && ((road | tram) & ROAD_Y) == 0)) {
519 Owner road_owner = GetRoadOwner(tile, ROADTYPE_ROAD);
520 Owner tram_owner = GetRoadOwner(tile, ROADTYPE_TRAM);
521 /* Disallow breaking end-of-line of someone else
522 * so trams can still reverse on this tile. */
523 if (Company::IsValidID(tram_owner) && HasExactlyOneBit(tram)) {
524 CommandCost ret = CheckOwnership(tram_owner);
525 if (ret.Failed()) return ret;
526 }
527 /* Crossings must always have a road... */
528 uint num_new_road_pieces = 2 - CountBits(road);
529 if (road == ROAD_NONE) road_owner = _current_company;
530 roadtypes |= ROADTYPES_ROAD;
531 /* ...but tram is not required. */
532 uint num_new_tram_pieces = (tram != ROAD_NONE) ? 2 - CountBits(tram) : 0;
533
534 cost.AddCost((num_new_road_pieces + num_new_tram_pieces) * _price[PR_BUILD_ROAD]);
535
536 if (flags & DC_EXEC) {
537 MakeRoadCrossing(tile, road_owner, tram_owner, _current_company, (track == TRACK_X ? AXIS_Y : AXIS_X), railtype, roadtypes, GetTownIndex(tile));
538 UpdateLevelCrossing(tile, false);
539 Company::Get(_current_company)->infrastructure.rail[railtype] += LEVELCROSSING_TRACKBIT_FACTOR;
540 DirtyCompanyInfrastructureWindows(_current_company);
541 if (num_new_road_pieces > 0 && Company::IsValidID(road_owner)) {
542 Company::Get(road_owner)->infrastructure.road[ROADTYPE_ROAD] += num_new_road_pieces;
543 DirtyCompanyInfrastructureWindows(road_owner);
544 }
545 if (num_new_tram_pieces > 0 && Company::IsValidID(tram_owner)) {
546 Company::Get(tram_owner)->infrastructure.road[ROADTYPE_TRAM] += num_new_tram_pieces;
547 DirtyCompanyInfrastructureWindows(tram_owner);
548 }
549 }
550 break;
551 }
552 }
553
554 if (IsLevelCrossing(tile) && GetCrossingRailBits(tile) == trackbit) {
555 return_cmd_error(STR_ERROR_ALREADY_BUILT);
556 }
557 }
558 FALLTHROUGH;
559
560 default: {
561 /* Will there be flat water on the lower halftile? */
562 bool water_ground = IsTileType(tile, MP_WATER) && IsSlopeWithOneCornerRaised(tileh);
563
564 CommandCost ret = CheckRailSlope(tileh, trackbit, TRACK_BIT_NONE, tile);
565 if (ret.Failed()) return ret;
566 cost.AddCost(ret);
567
568 ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
569 if (ret.Failed()) return ret;
570 cost.AddCost(ret);
571
572 if (water_ground) {
573 cost.AddCost(-_price[PR_CLEAR_WATER]);
574 cost.AddCost(_price[PR_CLEAR_ROUGH]);
575 }
576
577 if (flags & DC_EXEC) {
578 MakeRailNormal(tile, _current_company, trackbit, railtype);
579 if (water_ground) SetRailGroundType(tile, RAIL_GROUND_WATER);
580 Company::Get(_current_company)->infrastructure.rail[railtype]++;
581 DirtyCompanyInfrastructureWindows(_current_company);
582 }
583 break;
584 }
585 }
586
587 if (flags & DC_EXEC) {
588 MarkTileDirtyByTile(tile);
589 AddTrackToSignalBuffer(tile, track, _current_company);
590 YapfNotifyTrackLayoutChange(tile, track);
591 }
592
593 cost.AddCost(RailBuildCost(railtype));
594 return cost;
595 }
596
606 CommandCost CmdRemoveSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
607 {
608 Track track = Extract<Track, 0, 3>(p2);
609 CommandCost cost(EXPENSES_CONSTRUCTION);
610 bool crossing = false;
611
612 if (!ValParamTrackOrientation(track)) return CMD_ERROR;
613 TrackBits trackbit = TrackToTrackBits(track);
614
615 /* Need to read tile owner now because it may change when the rail is removed
616 * Also, in case of floods, _current_company != owner
617 * There may be invalid tiletype even in exec run (when removing long track),
618 * so do not call GetTileOwner(tile) in any case here */
619 Owner owner = INVALID_OWNER;
620
621 Train *v = NULL;
622
623 switch (GetTileType(tile)) {
624 case MP_ROAD: {
625 if (!IsLevelCrossing(tile) || GetCrossingRailBits(tile) != trackbit) return_cmd_error(STR_ERROR_THERE_IS_NO_RAILROAD_TRACK);
626
627 if (_current_company != OWNER_WATER) {
628 CommandCost ret = CheckTileOwnership(tile);
629 if (ret.Failed()) return ret;
630 }
631
632 if (!(flags & DC_BANKRUPT)) {
633 CommandCost ret = EnsureNoVehicleOnGround(tile);
634 if (ret.Failed()) return ret;
635 }
636
637 cost.AddCost(RailClearCost(GetRailType(tile)));
638
639 if (flags & DC_EXEC) {
640 if (HasReservedTracks(tile, trackbit)) {
641 v = GetTrainForReservation(tile, track);
642 if (v != NULL) FreeTrainTrackReservation(v);
643 }
644 owner = GetTileOwner(tile);
645 Company::Get(owner)->infrastructure.rail[GetRailType(tile)] -= LEVELCROSSING_TRACKBIT_FACTOR;
646 DirtyCompanyInfrastructureWindows(owner);
647 MakeRoadNormal(tile, GetCrossingRoadBits(tile), GetRoadTypes(tile), GetTownIndex(tile), GetRoadOwner(tile, ROADTYPE_ROAD), GetRoadOwner(tile, ROADTYPE_TRAM));
648 DeleteNewGRFInspectWindow(GSF_RAILTYPES, tile);
649 }
650 break;
651 }
652
653 case MP_RAILWAY: {
654 TrackBits present;
655 /* There are no rails present at depots. */
656 if (!IsPlainRail(tile)) return_cmd_error(STR_ERROR_THERE_IS_NO_RAILROAD_TRACK);
657
658 if (_current_company != OWNER_WATER) {
659 CommandCost ret = CheckTileOwnership(tile);
660 if (ret.Failed()) return ret;
661 }
662
663 CommandCost ret = EnsureNoTrainOnTrack(tile, track);
664 if (ret.Failed()) return ret;
665
666 present = GetTrackBits(tile);
667 if ((present & trackbit) == 0) return_cmd_error(STR_ERROR_THERE_IS_NO_RAILROAD_TRACK);
668 if (present == (TRACK_BIT_X | TRACK_BIT_Y)) crossing = true;
669
670 cost.AddCost(RailClearCost(GetRailType(tile)));
671
672 /* Charge extra to remove signals on the track, if they are there */
673 if (HasSignalOnTrack(tile, track)) {
674 cost.AddCost(DoCommand(tile, track, 0, flags, CMD_REMOVE_SIGNALS));
675 }
676
677 if (flags & DC_EXEC) {
678 if (HasReservedTracks(tile, trackbit)) {
679 v = GetTrainForReservation(tile, track);
680 if (v != NULL) FreeTrainTrackReservation(v);
681 }
682
683 owner = GetTileOwner(tile);
684
685 /* Subtract old infrastructure count. */
686 uint pieces = CountBits(present);
687 if (TracksOverlap(present)) pieces *= pieces;
688 Company::Get(owner)->infrastructure.rail[GetRailType(tile)] -= pieces;
689 /* Add new infrastructure count. */
690 present ^= trackbit;
691 pieces = CountBits(present);
692 if (TracksOverlap(present)) pieces *= pieces;
693 Company::Get(owner)->infrastructure.rail[GetRailType(tile)] += pieces;
694 DirtyCompanyInfrastructureWindows(owner);
695
696 if (present == 0) {
697 Slope tileh = GetTileSlope(tile);
698 /* If there is flat water on the lower halftile, convert the tile to shore so the water remains */
699 if (GetRailGroundType(tile) == RAIL_GROUND_WATER && IsSlopeWithOneCornerRaised(tileh)) {
700 MakeShore(tile);
701 } else {
702 DoClearSquare(tile);
703 }
704 DeleteNewGRFInspectWindow(GSF_RAILTYPES, tile);
705 } else {
706 SetTrackBits(tile, present);
707 SetTrackReservation(tile, GetRailReservationTrackBits(tile) & present);
708 }
709 }
710 break;
711 }
712
713 default: return_cmd_error(STR_ERROR_THERE_IS_NO_RAILROAD_TRACK);
714 }
715
716 if (flags & DC_EXEC) {
717 /* if we got that far, 'owner' variable is set correctly */
718 assert(Company::IsValidID(owner));
719
720 MarkTileDirtyByTile(tile);
721 if (crossing) {
722 /* crossing is set when only TRACK_BIT_X and TRACK_BIT_Y are set. As we
723 * are removing one of these pieces, we'll need to update signals for
724 * both directions explicitly, as after the track is removed it won't
725 * 'connect' with the other piece. */
726 AddTrackToSignalBuffer(tile, TRACK_X, owner);
727 AddTrackToSignalBuffer(tile, TRACK_Y, owner);
728 YapfNotifyTrackLayoutChange(tile, TRACK_X);
729 YapfNotifyTrackLayoutChange(tile, TRACK_Y);
730 } else {
731 AddTrackToSignalBuffer(tile, track, owner);
732 YapfNotifyTrackLayoutChange(tile, track);
733 }
734
735 if (v != NULL) TryPathReserve(v, true);
736 }
737
738 return cost;
739 }
740
741
749 bool FloodHalftile(TileIndex t)
750 {
751 assert(IsPlainRailTile(t));
752
753 bool flooded = false;
754 if (GetRailGroundType(t) == RAIL_GROUND_WATER) return flooded;
755
756 Slope tileh = GetTileSlope(t);
757 TrackBits rail_bits = GetTrackBits(t);
758
759 if (IsSlopeWithOneCornerRaised(tileh)) {
760 TrackBits lower_track = CornerToTrackBits(OppositeCorner(GetHighestSlopeCorner(tileh)));
761
762 TrackBits to_remove = lower_track & rail_bits;
763 if (to_remove != 0) {
764 Backup<CompanyByte> cur_company(_current_company, OWNER_WATER, FILE_LINE);
765 flooded = DoCommand(t, 0, FIND_FIRST_BIT(to_remove), DC_EXEC, CMD_REMOVE_SINGLE_RAIL).Succeeded();
766 cur_company.Restore();
767 if (!flooded) return flooded; // not yet floodable
768 rail_bits = rail_bits & ~to_remove;
769 if (rail_bits == 0) {
770 MakeShore(t);
771 MarkTileDirtyByTile(t);
772 return flooded;
773 }
774 }
775
776 if (IsNonContinuousFoundation(GetRailFoundation(tileh, rail_bits))) {
777 flooded = true;
778 SetRailGroundType(t, RAIL_GROUND_WATER);
779 MarkTileDirtyByTile(t);
780 }
781 } else {
782 /* Make shore on steep slopes and 'three-corners-raised'-slopes. */
783 if (ApplyFoundationToSlope(GetRailFoundation(tileh, rail_bits), &tileh) == 0) {
784 if (IsSteepSlope(tileh) || IsSlopeWithThreeCornersRaised(tileh)) {
785 flooded = true;
786 SetRailGroundType(t, RAIL_GROUND_WATER);
787 MarkTileDirtyByTile(t);
788 }
789 }
790 }
791 return flooded;
792 }
793
794 static const TileIndexDiffC _trackdelta[] = {
795 { -1, 0 }, { 0, 1 }, { -1, 0 }, { 0, 1 }, { 1, 0 }, { 0, 1 },
796 { 0, 0 },
797 { 0, 0 },
798 { 1, 0 }, { 0, -1 }, { 0, -1 }, { 1, 0 }, { 0, -1 }, { -1, 0 },
799 { 0, 0 },
800 { 0, 0 }
801 };
802
803
804 static CommandCost ValidateAutoDrag(Trackdir *trackdir, TileIndex start, TileIndex end)
805 {
806 int x = TileX(start);
807 int y = TileY(start);
808 int ex = TileX(end);
809 int ey = TileY(end);
810
811 if (!ValParamTrackOrientation(TrackdirToTrack(*trackdir))) return CMD_ERROR;
812
813 /* calculate delta x,y from start to end tile */
814 int dx = ex - x;
815 int dy = ey - y;
816
817 /* calculate delta x,y for the first direction */
818 int trdx = _trackdelta[*trackdir].x;
819 int trdy = _trackdelta[*trackdir].y;
820
821 if (!IsDiagonalTrackdir(*trackdir)) {
822 trdx += _trackdelta[*trackdir ^ 1].x;
823 trdy += _trackdelta[*trackdir ^ 1].y;
824 }
825
826 /* validate the direction */
827 while ((trdx <= 0 && dx > 0) ||
828 (trdx >= 0 && dx < 0) ||
829 (trdy <= 0 && dy > 0) ||
830 (trdy >= 0 && dy < 0)) {
831 if (!HasBit(*trackdir, 3)) { // first direction is invalid, try the other
832 SetBit(*trackdir, 3); // reverse the direction
833 trdx = -trdx;
834 trdy = -trdy;
835 } else { // other direction is invalid too, invalid drag
836 return CMD_ERROR;
837 }
838 }
839
840 /* (for diagonal tracks, this is already made sure of by above test), but:
841 * for non-diagonal tracks, check if the start and end tile are on 1 line */
842 if (!IsDiagonalTrackdir(*trackdir)) {
843 trdx = _trackdelta[*trackdir].x;
844 trdy = _trackdelta[*trackdir].y;
845 if (abs(dx) != abs(dy) && abs(dx) + abs(trdy) != abs(dy) + abs(trdx)) return CMD_ERROR;
846 }
847
848 return CommandCost();
849 }
850
864 static CommandCost CmdRailTrackHelper(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
865 {
866 CommandCost total_cost(EXPENSES_CONSTRUCTION);
867 Track track = Extract<Track, 4, 3>(p2);
868 bool remove = HasBit(p2, 7);
869 RailType railtype = Extract<RailType, 0, 4>(p2);
870
871 if ((!remove && !ValParamRailtype(railtype)) || !ValParamTrackOrientation(track)) return CMD_ERROR;
872 if (p1 >= MapSize()) return CMD_ERROR;
873 TileIndex end_tile = p1;
874 Trackdir trackdir = TrackToTrackdir(track);
875
876 CommandCost ret = ValidateAutoDrag(&trackdir, tile, end_tile);
877 if (ret.Failed()) return ret;
878
879 bool had_success = false;
880 CommandCost last_error = CMD_ERROR;
881 for (;;) {
882 CommandCost ret = DoCommand(tile, remove ? 0 : railtype, TrackdirToTrack(trackdir), flags, remove ? CMD_REMOVE_SINGLE_RAIL : CMD_BUILD_SINGLE_RAIL);
883
884 if (ret.Failed()) {
885 last_error = ret;
886 if (last_error.GetErrorMessage() != STR_ERROR_ALREADY_BUILT && !remove) {
887 if (HasBit(p2, 8)) return last_error;
888 break;
889 }
890
891 /* Ownership errors are more important. */
892 if (last_error.GetErrorMessage() == STR_ERROR_OWNED_BY && remove) break;
893 } else {
894 had_success = true;
895 total_cost.AddCost(ret);
896 }
897
898 if (tile == end_tile) break;
899
900 tile += ToTileIndexDiff(_trackdelta[trackdir]);
901
902 /* toggle railbit for the non-diagonal tracks */
903 if (!IsDiagonalTrackdir(trackdir)) ToggleBit(trackdir, 0);
904 }
905
906 if (had_success) return total_cost;
907 return last_error;
908 }
909
924 CommandCost CmdBuildRailroadTrack(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
925 {
926 return CmdRailTrackHelper(tile, flags, p1, ClrBit(p2, 7), text);
927 }
928
943 CommandCost CmdRemoveRailroadTrack(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
944 {
945 return CmdRailTrackHelper(tile, flags, p1, SetBit(p2, 7), text);
946 }
947
960 CommandCost CmdBuildTrainDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
961 {
962 /* check railtype and valid direction for depot (0 through 3), 4 in total */
963 RailType railtype = Extract<RailType, 0, 4>(p1);
964 if (!ValParamRailtype(railtype)) return CMD_ERROR;
965
966 Slope tileh = GetTileSlope(tile);
967
968 DiagDirection dir = Extract<DiagDirection, 0, 2>(p2);
969
970 /* Prohibit construction if
971 * The tile is non-flat AND
972 * 1) build-on-slopes is disabled
973 * 2) the tile is steep i.e. spans two height levels
974 * 3) the exit points in the wrong direction
975 */
976
977 if (tileh != SLOPE_FLAT && (
978 !_settings_game.construction.build_on_slopes ||
979 !CanBuildDepotByTileh(dir, tileh)
980 )) {
981 return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED);
982 }
983
984 CommandCost cost = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
985 if (cost.Failed()) return cost;
986
987 if (IsBridgeAbove(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
988
989 if (!Depot::CanAllocateItem()) return CMD_ERROR;
990
991 if (flags & DC_EXEC) {
992 Depot *d = new Depot(tile);
993 d->build_date = _date;
994
995 MakeRailDepot(tile, _current_company, d->index, dir, railtype);
996 MarkTileDirtyByTile(tile);
997 MakeDefaultName(d);
998
999 Company::Get(_current_company)->infrastructure.rail[railtype]++;
1000 DirtyCompanyInfrastructureWindows(_current_company);
1001
1002 AddSideToSignalBuffer(tile, INVALID_DIAGDIR, _current_company);
1003 YapfNotifyTrackLayoutChange(tile, DiagDirToDiagTrack(dir));
1004 }
1005
1006 cost.AddCost(_price[PR_BUILD_DEPOT_TRAIN]);
1007 cost.AddCost(RailBuildCost(railtype));
1008 return cost;
1009 }
1010
1032 CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
1033 {
1034 Track track = Extract<Track, 0, 3>(p1);
1035 bool ctrl_pressed = HasBit(p1, 3); // was the CTRL button pressed
1036 SignalVariant sigvar = (ctrl_pressed ^ HasBit(p1, 4)) ? SIG_SEMAPHORE : SIG_ELECTRIC; // the signal variant of the new signal
1037 SignalType sigtype = Extract<SignalType, 5, 3>(p1); // the signal type of the new signal
1038 bool convert_signal = HasBit(p1, 8); // convert button pressed
1039 SignalType cycle_start = Extract<SignalType, 9, 3>(p1);
1040 SignalType cycle_stop = Extract<SignalType, 12, 3>(p1);
1041 uint num_dir_cycle = GB(p1, 15, 2);
1042
1043 if (sigtype > SIGTYPE_LAST) return CMD_ERROR;
1044 if (cycle_start > cycle_stop || cycle_stop > SIGTYPE_LAST) return CMD_ERROR;
1045
1046 /* You can only build signals on plain rail tiles, and the selected track must exist */
1047 if (!ValParamTrackOrientation(track) || !IsPlainRailTile(tile) ||
1048 !HasTrack(tile, track)) {
1049 return_cmd_error(STR_ERROR_THERE_IS_NO_RAILROAD_TRACK);
1050 }
1051 /* Protect against invalid signal copying */
1052 if (p2 != 0 && (p2 & SignalOnTrack(track)) == 0) return CMD_ERROR;
1053
1054 CommandCost ret = CheckTileOwnership(tile);
1055 if (ret.Failed()) return ret;
1056
1057 /* See if this is a valid track combination for signals (no overlap) */
1058 if (TracksOverlap(GetTrackBits(tile))) return_cmd_error(STR_ERROR_NO_SUITABLE_RAILROAD_TRACK);
1059
1060 /* In case we don't want to change an existing signal, return without error. */
1061 if (HasBit(p1, 17) && HasSignalOnTrack(tile, track)) return CommandCost();
1062
1063 /* you can not convert a signal if no signal is on track */
1064 if (convert_signal && !HasSignalOnTrack(tile, track)) return_cmd_error(STR_ERROR_THERE_ARE_NO_SIGNALS);
1065
1066 CommandCost cost;
1067 if (!HasSignalOnTrack(tile, track)) {
1068 /* build new signals */
1069 cost = CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_SIGNALS]);
1070 } else {
1071 if (p2 != 0 && sigvar != GetSignalVariant(tile, track)) {
1072 /* convert signals <-> semaphores */
1073 cost = CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_SIGNALS] + _price[PR_CLEAR_SIGNALS]);
1074
1075 } else if (convert_signal) {
1076 /* convert button pressed */
1077 if (ctrl_pressed || GetSignalVariant(tile, track) != sigvar) {
1078 /* convert electric <-> semaphore */
1079 cost = CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_SIGNALS] + _price[PR_CLEAR_SIGNALS]);
1080 } else {
1081 /* it is free to change signal type: normal-pre-exit-combo */
1082 cost = CommandCost();
1083 }
1084
1085 } else {
1086 /* it is free to change orientation/pre-exit-combo signals */
1087 cost = CommandCost();
1088 }
1089 }
1090
1091 if (flags & DC_EXEC) {
1092 Train *v = NULL;
1093 /* The new/changed signal could block our path. As this can lead to
1094 * stale reservations, we clear the path reservation here and try
1095 * to redo it later on. */
1096 if (HasReservedTracks(tile, TrackToTrackBits(track))) {
1097 v = GetTrainForReservation(tile, track);
1098 if (v != NULL) FreeTrainTrackReservation(v);
1099 }
1100
1101 if (!HasSignals(tile)) {
1102 /* there are no signals at all on this tile yet */
1103 SetHasSignals(tile, true);
1104 SetSignalStates(tile, 0xF); // all signals are on
1105 SetPresentSignals(tile, 0); // no signals built by default
1106 SetSignalType(tile, track, sigtype);
1107 SetSignalVariant(tile, track, sigvar);
1108 }
1109
1110 /* Subtract old signal infrastructure count. */
1111 Company::Get(GetTileOwner(tile))->infrastructure.signal -= CountBits(GetPresentSignals(tile));
1112
1113 if (p2 == 0) {
1114 if (!HasSignalOnTrack(tile, track)) {
1115 /* build new signals */
1116 SetPresentSignals(tile, GetPresentSignals(tile) | (IsPbsSignal(sigtype) ? KillFirstBit(SignalOnTrack(track)) : SignalOnTrack(track)));
1117 SetSignalType(tile, track, sigtype);
1118 SetSignalVariant(tile, track, sigvar);
1119 while (num_dir_cycle-- > 0) CycleSignalSide(tile, track);
1120 } else {
1121 if (convert_signal) {
1122 /* convert signal button pressed */
1123 if (ctrl_pressed) {
1124 /* toggle the present signal variant: SIG_ELECTRIC <-> SIG_SEMAPHORE */
1125 SetSignalVariant(tile, track, (GetSignalVariant(tile, track) == SIG_ELECTRIC) ? SIG_SEMAPHORE : SIG_ELECTRIC);
1126 /* Query current signal type so the check for PBS signals below works. */
1127 sigtype = GetSignalType(tile, track);
1128 } else {
1129 /* convert the present signal to the chosen type and variant */
1130 SetSignalType(tile, track, sigtype);
1131 SetSignalVariant(tile, track, sigvar);
1132 if (IsPbsSignal(sigtype) && (GetPresentSignals(tile) & SignalOnTrack(track)) == SignalOnTrack(track)) {
1133 SetPresentSignals(tile, (GetPresentSignals(tile) & ~SignalOnTrack(track)) | KillFirstBit(SignalOnTrack(track)));
1134 }
1135 }
1136
1137 } else if (ctrl_pressed) {
1138 /* cycle between cycle_start and cycle_end */
1139 sigtype = (SignalType)(GetSignalType(tile, track) + 1);
1140
1141 if (sigtype < cycle_start || sigtype > cycle_stop) sigtype = cycle_start;
1142
1143 SetSignalType(tile, track, sigtype);
1144 if (IsPbsSignal(sigtype) && (GetPresentSignals(tile) & SignalOnTrack(track)) == SignalOnTrack(track)) {
1145 SetPresentSignals(tile, (GetPresentSignals(tile) & ~SignalOnTrack(track)) | KillFirstBit(SignalOnTrack(track)));
1146 }
1147 } else {
1148 /* cycle the signal side: both -> left -> right -> both -> ... */
1149 CycleSignalSide(tile, track);
1150 /* Query current signal type so the check for PBS signals below works. */
1151 sigtype = GetSignalType(tile, track);
1152 }
1153 }
1154 } else {
1155 /* If CmdBuildManySignals is called with copying signals, just copy the
1156 * direction of the first signal given as parameter by CmdBuildManySignals */
1157 SetPresentSignals(tile, (GetPresentSignals(tile) & ~SignalOnTrack(track)) | (p2 & SignalOnTrack(track)));
1158 SetSignalVariant(tile, track, sigvar);
1159 SetSignalType(tile, track, sigtype);
1160 }
1161
1162 /* Add new signal infrastructure count. */
1163 Company::Get(GetTileOwner(tile))->infrastructure.signal += CountBits(GetPresentSignals(tile));
1164 DirtyCompanyInfrastructureWindows(GetTileOwner(tile));
1165
1166 if (IsPbsSignal(sigtype)) {
1167 /* PBS signals should show red unless they are on reserved tiles without a train. */
1168 uint mask = GetPresentSignals(tile) & SignalOnTrack(track);
1169 SetSignalStates(tile, (GetSignalStates(tile) & ~mask) | ((HasBit(GetRailReservationTrackBits(tile), track) && EnsureNoVehicleOnGround(tile).Succeeded() ? UINT_MAX : 0) & mask));
1170 }
1171 MarkTileDirtyByTile(tile);
1172 AddTrackToSignalBuffer(tile, track, _current_company);
1173 YapfNotifyTrackLayoutChange(tile, track);
1174 if (v != NULL) {
1175 /* Extend the train's path if it's not stopped or loading, or not at a safe position. */
1176 if (!(((v->vehstatus & VS_STOPPED) && v->cur_speed == 0) || v->current_order.IsType(OT_LOADING)) ||
1177 !IsSafeWaitingPosition(v, v->tile, v->GetVehicleTrackdir(), true, _settings_game.pf.forbid_90_deg)) {
1178 TryPathReserve(v, true);
1179 }
1180 }
1181 }
1182
1183 return cost;
1184 }
1185
1186 static bool CheckSignalAutoFill(TileIndex &tile, Trackdir &trackdir, int &signal_ctr, bool remove)
1187 {
1188 tile = AddTileIndexDiffCWrap(tile, _trackdelta[trackdir]);
1189 if (tile == INVALID_TILE) return false;
1190
1191 /* Check for track bits on the new tile */
1192 TrackdirBits trackdirbits = TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_RAIL, 0));
1193
1194 if (TracksOverlap(TrackdirBitsToTrackBits(trackdirbits))) return false;
1195 trackdirbits &= TrackdirReachesTrackdirs(trackdir);
1196
1197 /* No track bits, must stop */
1198 if (trackdirbits == TRACKDIR_BIT_NONE) return false;
1199
1200 /* Get the first track dir */
1201 trackdir = RemoveFirstTrackdir(&trackdirbits);
1202
1203 /* Any left? It's a junction so we stop */
1204 if (trackdirbits != TRACKDIR_BIT_NONE) return false;
1205
1206 switch (GetTileType(tile)) {
1207 case MP_RAILWAY:
1208 if (IsRailDepot(tile)) return false;
1209 if (!remove && HasSignalOnTrack(tile, TrackdirToTrack(trackdir))) return false;
1210 signal_ctr++;
1211 if (IsDiagonalTrackdir(trackdir)) {
1212 signal_ctr++;
1213 /* Ensure signal_ctr even so X and Y pieces get signals */
1214 ClrBit(signal_ctr, 0);
1215 }
1216 return true;
1217
1218 case MP_ROAD:
1219 if (!IsLevelCrossing(tile)) return false;
1220 signal_ctr += 2;
1221 return true;
1222
1223 case MP_TUNNELBRIDGE: {
1224 TileIndex orig_tile = tile; // backup old value
1225
1226 if (GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL) return false;
1227 if (GetTunnelBridgeDirection(tile) != TrackdirToExitdir(trackdir)) return false;
1228
1229 /* Skip to end of tunnel or bridge
1230 * note that tile is a parameter by reference, so it must be updated */
1231 tile = GetOtherTunnelBridgeEnd(tile);
1232
1233 signal_ctr += (GetTunnelBridgeLength(orig_tile, tile) + 2) * 2;
1234 return true;
1235 }
1236
1237 default: return false;
1238 }
1239 }
1240
1258 static CommandCost CmdSignalTrackHelper(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
1259 {
1260 CommandCost total_cost(EXPENSES_CONSTRUCTION);
1261 TileIndex start_tile = tile;
1262
1263 Track track = Extract<Track, 0, 3>(p2);
1264 bool mode = HasBit(p2, 3);
1265 bool semaphores = HasBit(p2, 4);
1266 bool remove = HasBit(p2, 5);
1267 bool autofill = HasBit(p2, 6);
1268 bool minimise_gaps = HasBit(p2, 10);
1269 byte signal_density = GB(p2, 24, 8);
1270
1271 if (p1 >= MapSize() || !ValParamTrackOrientation(track)) return CMD_ERROR;
1272 TileIndex end_tile = p1;
1273 if (signal_density == 0 || signal_density > 20) return CMD_ERROR;
1274
1275 if (!IsPlainRailTile(tile)) return_cmd_error(STR_ERROR_THERE_IS_NO_RAILROAD_TRACK);
1276
1277 /* for vertical/horizontal tracks, double the given signals density
1278 * since the original amount will be too dense (shorter tracks) */
1279 signal_density *= 2;
1280
1281 Trackdir trackdir = TrackToTrackdir(track);
1282 CommandCost ret = ValidateAutoDrag(&trackdir, tile, end_tile);
1283 if (ret.Failed()) return ret;
1284
1285 track = TrackdirToTrack(trackdir); // trackdir might have changed, keep track in sync
1286 Trackdir start_trackdir = trackdir;
1287
1288 /* Must start on a valid track to be able to avoid loops */
1289 if (!HasTrack(tile, track)) return CMD_ERROR;
1290
1291 SignalType sigtype = (SignalType)GB(p2, 7, 3);
1292 if (sigtype > SIGTYPE_LAST) return CMD_ERROR;
1293
1294 byte signals;
1295 /* copy the signal-style of the first rail-piece if existing */
1296 if (HasSignalOnTrack(tile, track)) {
1297 signals = GetPresentSignals(tile) & SignalOnTrack(track);
1298 assert(signals != 0);
1299
1300 /* copy signal/semaphores style (independent of CTRL) */
1301 semaphores = GetSignalVariant(tile, track) != SIG_ELECTRIC;
1302
1303 sigtype = GetSignalType(tile, track);
1304 /* Don't but copy entry or exit-signal type */
1305 if (sigtype == SIGTYPE_ENTRY || sigtype == SIGTYPE_EXIT) sigtype = SIGTYPE_NORMAL;
1306 } else { // no signals exist, drag a two-way signal stretch
1307 signals = IsPbsSignal(sigtype) ? SignalAlongTrackdir(trackdir) : SignalOnTrack(track);
1308 }
1309
1310 byte signal_dir = 0;
1311 if (signals & SignalAlongTrackdir(trackdir)) SetBit(signal_dir, 0);
1312 if (signals & SignalAgainstTrackdir(trackdir)) SetBit(signal_dir, 1);
1313
1314 /* signal_ctr - amount of tiles already processed
1315 * last_used_ctr - amount of tiles before previously placed signal
1316 * signals_density - setting to put signal on every Nth tile (double space on |, -- tracks)
1317 * last_suitable_ctr - amount of tiles before last possible signal place
1318 * last_suitable_tile - last tile where it is possible to place a signal
1319 * last_suitable_trackdir - trackdir of the last tile
1320 **********
1321 * trackdir - trackdir to build with autorail
1322 * semaphores - semaphores or signals
1323 * signals - is there a signal/semaphore on the first tile, copy its style (two-way/single-way)
1324 * and convert all others to semaphore/signal
1325 * remove - 1 remove signals, 0 build signals */
1326 int signal_ctr = 0;
1327 int last_used_ctr = INT_MIN; // initially INT_MIN to force building/removing at the first tile
1328 int last_suitable_ctr = 0;
1329 TileIndex last_suitable_tile = INVALID_TILE;
1330 Trackdir last_suitable_trackdir = INVALID_TRACKDIR;
1331 CommandCost last_error = CMD_ERROR;
1332 bool had_success = false;
1333 for (;;) {
1334 /* only build/remove signals with the specified density */
1335 if (remove || minimise_gaps || signal_ctr % signal_density == 0) {
1336 uint32 p1 = GB(TrackdirToTrack(trackdir), 0, 3);
1337 SB(p1, 3, 1, mode);
1338 SB(p1, 4, 1, semaphores);
1339 SB(p1, 5, 3, sigtype);
1340 if (!remove && signal_ctr == 0) SetBit(p1, 17);
1341
1342 /* Pick the correct orientation for the track direction */
1343 signals = 0;
1344 if (HasBit(signal_dir, 0)) signals |= SignalAlongTrackdir(trackdir);
1345 if (HasBit(signal_dir, 1)) signals |= SignalAgainstTrackdir(trackdir);
1346
1347 /* Test tiles in between for suitability as well if minimising gaps. */
1348 bool test_only = !remove && minimise_gaps && signal_ctr < (last_used_ctr + signal_density);
1349 CommandCost ret = DoCommand(tile, p1, signals, test_only ? flags & ~DC_EXEC : flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS);
1350
1351 if (ret.Succeeded()) {
1352 /* Remember last track piece where we can place a signal. */
1353 last_suitable_ctr = signal_ctr;
1354 last_suitable_tile = tile;
1355 last_suitable_trackdir = trackdir;
1356 } else if (!test_only && last_suitable_tile != INVALID_TILE) {
1357 /* If a signal can't be placed, place it at the last possible position. */
1358 SB(p1, 0, 3, TrackdirToTrack(last_suitable_trackdir));
1359 ClrBit(p1, 17);
1360
1361 /* Pick the correct orientation for the track direction. */
1362 signals = 0;
1363 if (HasBit(signal_dir, 0)) signals |= SignalAlongTrackdir(last_suitable_trackdir);
1364 if (HasBit(signal_dir, 1)) signals |= SignalAgainstTrackdir(last_suitable_trackdir);
1365
1366 ret = DoCommand(last_suitable_tile, p1, signals, flags, remove ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS);
1367 }
1368
1369 /* Collect cost. */
1370 if (!test_only) {
1371 /* Be user-friendly and try placing signals as much as possible */
1372 if (ret.Succeeded()) {
1373 had_success = true;
1374 total_cost.AddCost(ret);
1375 last_used_ctr = last_suitable_ctr;
1376 last_suitable_tile = INVALID_TILE;
1377 } else {
1378 /* The "No railway" error is the least important one. */
1379 if (ret.GetErrorMessage() != STR_ERROR_THERE_IS_NO_RAILROAD_TRACK ||
1380 last_error.GetErrorMessage() == INVALID_STRING_ID) {
1381 last_error = ret;
1382 }
1383 }
1384 }
1385 }
1386
1387 if (autofill) {
1388 if (!CheckSignalAutoFill(tile, trackdir, signal_ctr, remove)) break;
1389
1390 /* Prevent possible loops */
1391 if (tile == start_tile && trackdir == start_trackdir) break;
1392 } else {
1393 if (tile == end_tile) break;
1394
1395 tile += ToTileIndexDiff(_trackdelta[trackdir]);
1396 signal_ctr++;
1397
1398 /* toggle railbit for the non-diagonal tracks (|, -- tracks) */
1399 if (IsDiagonalTrackdir(trackdir)) {
1400 signal_ctr++;
1401 } else {
1402 ToggleBit(trackdir, 0);
1403 }
1404 }
1405 }
1406
1407 return had_success ? total_cost : last_error;
1408 }
1409
1428 CommandCost CmdBuildSignalTrack(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
1429 {
1430 return CmdSignalTrackHelper(tile, flags, p1, p2, text);
1431 }
1432
1445 CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
1446 {
1447 Track track = Extract<Track, 0, 3>(p1);
1448
1449 if (!ValParamTrackOrientation(track) || !IsPlainRailTile(tile) || !HasTrack(tile, track)) {
1450 return_cmd_error(STR_ERROR_THERE_IS_NO_RAILROAD_TRACK);
1451 }
1452 if (!HasSignalOnTrack(tile, track)) {
1453 return_cmd_error(STR_ERROR_THERE_ARE_NO_SIGNALS);
1454 }
1455
1456 /* Only water can remove signals from anyone */
1457 if (_current_company != OWNER_WATER) {
1458 CommandCost ret = CheckTileOwnership(tile);
1459 if (ret.Failed()) return ret;
1460 }
1461
1462 /* Do it? */
1463 if (flags & DC_EXEC) {
1464 Train *v = NULL;
1465 if (HasReservedTracks(tile, TrackToTrackBits(track))) {
1466 v = GetTrainForReservation(tile, track);
1467 } else if (IsPbsSignal(GetSignalType(tile, track))) {
1468 /* PBS signal, might be the end of a path reservation. */
1469 Trackdir td = TrackToTrackdir(track);
1470 for (int i = 0; v == NULL && i < 2; i++, td = ReverseTrackdir(td)) {
1471 /* Only test the active signal side. */
1472 if (!HasSignalOnTrackdir(tile, ReverseTrackdir(td))) continue;
1473 TileIndex next = TileAddByDiagDir(tile, TrackdirToExitdir(td));
1474 TrackBits tracks = TrackdirBitsToTrackBits(TrackdirReachesTrackdirs(td));
1475 if (HasReservedTracks(next, tracks)) {
1476 v = GetTrainForReservation(next, TrackBitsToTrack(GetReservedTrackbits(next) & tracks));
1477 }
1478 }
1479 }
1480 Company::Get(GetTileOwner(tile))->infrastructure.signal -= CountBits(GetPresentSignals(tile));
1481 SetPresentSignals(tile, GetPresentSignals(tile) & ~SignalOnTrack(track));
1482 Company::Get(GetTileOwner(tile))->infrastructure.signal += CountBits(GetPresentSignals(tile));
1483 DirtyCompanyInfrastructureWindows(GetTileOwner(tile));
1484
1485 /* removed last signal from tile? */
1486 if (GetPresentSignals(tile) == 0) {
1487 SetSignalStates(tile, 0);
1488 SetHasSignals(tile, false);
1489 SetSignalVariant(tile, INVALID_TRACK, SIG_ELECTRIC); // remove any possible semaphores
1490 }
1491
1492 AddTrackToSignalBuffer(tile, track, GetTileOwner(tile));
1493 YapfNotifyTrackLayoutChange(tile, track);
1494 if (v != NULL) TryPathReserve(v, false);
1495
1496 MarkTileDirtyByTile(tile);
1497 }
1498
1499 return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_SIGNALS]);
1500 }
1501
1520 CommandCost CmdRemoveSignalTrack(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
1521 {
1522 return CmdSignalTrackHelper(tile, flags, p1, SetBit(p2, 5), text); // bit 5 is remove bit
1523 }
1524
1526 static Vehicle *UpdateTrainPowerProc(Vehicle *v, void *data)
1527 {
1528 if (v->type != VEH_TRAIN) return NULL;
1529
1530 TrainList *affected_trains = static_cast<TrainList*>(data);
1531 affected_trains->Include(Train::From(v)->First());
1532
1533 return NULL;
1534 }
1535
1548 CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
1549 {
1550 RailType totype = Extract<RailType, 0, 4>(p2);
1551 TileIndex area_start = p1;
1552 TileIndex area_end = tile;
1553 bool diagonal = HasBit(p2, 4);
1554
1555 if (!ValParamRailtype(totype)) return CMD_ERROR;
1556 if (area_start >= MapSize()) return CMD_ERROR;
1557
1558 TrainList affected_trains;
1559
1560 CommandCost cost(EXPENSES_CONSTRUCTION);
1561 CommandCost error = CommandCost(STR_ERROR_NO_SUITABLE_RAILROAD_TRACK); // by default, there is no track to convert.
1562
1563 TileIterator *iter = diagonal ? (TileIterator *)new DiagonalTileIterator(area_start, area_end) : new OrthogonalTileIterator(area_start, area_end);
1564 for (; (tile = *iter) != INVALID_TILE; ++(*iter)) {
1565 TileType tt = GetTileType(tile);
1566
1567 /* Check if there is any track on tile */
1568 switch (tt) {
1569 case MP_RAILWAY:
1570 break;
1571 case MP_STATION:
1572 if (!HasStationRail(tile)) continue;
1573 break;
1574 case MP_ROAD:
1575 if (!IsLevelCrossing(tile)) continue;
1576 if (RailNoLevelCrossings(totype)) {
1577 error.MakeError(STR_ERROR_CROSSING_DISALLOWED);
1578 continue;
1579 }
1580 break;
1581 case MP_TUNNELBRIDGE:
1582 if (GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL) continue;
1583 break;
1584 default: continue;
1585 }
1586
1587 /* Original railtype we are converting from */
1588 RailType type = GetRailType(tile);
1589
1590 /* Converting to the same type or converting 'hidden' elrail -> rail */
1591 if (type == totype || (_settings_game.vehicle.disable_elrails && totype == RAILTYPE_RAIL && type == RAILTYPE_ELECTRIC)) continue;
1592
1593 /* Trying to convert other's rail */
1594 CommandCost ret = CheckTileOwnership(tile);
1595 if (ret.Failed()) {
1596 error = ret;
1597 continue;
1598 }
1599
1600 SmallVector<Train *, 2> vehicles_affected;
1601
1602 /* Vehicle on the tile when not converting Rail <-> ElRail
1603 * Tunnels and bridges have special check later */
1604 if (tt != MP_TUNNELBRIDGE) {
1605 if (!IsCompatibleRail(type, totype)) {
1606 CommandCost ret = IsPlainRailTile(tile) ? EnsureNoTrainOnTrackBits(tile, GetTrackBits(tile)) : EnsureNoVehicleOnGround(tile);
1607 if (ret.Failed()) {
1608 error = ret;
1609 continue;
1610 }
1611 }
1612 if (flags & DC_EXEC) { // we can safely convert, too
1613 TrackBits reserved = GetReservedTrackbits(tile);
1614 Track track;
1615 while ((track = RemoveFirstTrack(&reserved)) != INVALID_TRACK) {
1616 Train *v = GetTrainForReservation(tile, track);
1617 if (v != NULL && !HasPowerOnRail(v->railtype, totype)) {
1618 /* No power on new rail type, reroute. */
1619 FreeTrainTrackReservation(v);
1620 *vehicles_affected.Append() = v;
1621 }
1622 }
1623
1624 /* Update the company infrastructure counters. */
1625 if (!IsRailStationTile(tile) || !IsStationTileBlocked(tile)) {
1626 Company *c = Company::Get(GetTileOwner(tile));
1627 uint num_pieces = IsLevelCrossingTile(tile) ? LEVELCROSSING_TRACKBIT_FACTOR : 1;
1628 if (IsPlainRailTile(tile)) {
1629 TrackBits bits = GetTrackBits(tile);
1630 num_pieces = CountBits(bits);
1631 if (TracksOverlap(bits)) num_pieces *= num_pieces;
1632 }
1633 c->infrastructure.rail[type] -= num_pieces;
1634 c->infrastructure.rail[totype] += num_pieces;
1635 DirtyCompanyInfrastructureWindows(c->index);
1636 }
1637
1638 SetRailType(tile, totype);
1639 MarkTileDirtyByTile(tile);
1640 /* update power of train on this tile */
1641 FindVehicleOnPos(tile, &affected_trains, &UpdateTrainPowerProc);
1642 }
1643 }
1644
1645 switch (tt) {
1646 case MP_RAILWAY:
1647 switch (GetRailTileType(tile)) {
1648 case RAIL_TILE_DEPOT:
1649 if (flags & DC_EXEC) {
1650 /* notify YAPF about the track layout change */
1651 YapfNotifyTrackLayoutChange(tile, GetRailDepotTrack(tile));
1652
1653 /* Update build vehicle window related to this depot */
1654 InvalidateWindowData(WC_VEHICLE_DEPOT, tile);
1655 InvalidateWindowData(WC_BUILD_VEHICLE, tile);
1656 }
1657 cost.AddCost(RailConvertCost(type, totype));
1658 break;
1659
1660 default: // RAIL_TILE_NORMAL, RAIL_TILE_SIGNALS
1661 if (flags & DC_EXEC) {
1662 /* notify YAPF about the track layout change */
1663 TrackBits tracks = GetTrackBits(tile);
1664 while (tracks != TRACK_BIT_NONE) {
1665 YapfNotifyTrackLayoutChange(tile, RemoveFirstTrack(&tracks));
1666 }
1667 }
1668 cost.AddCost(RailConvertCost(type, totype) * CountBits(GetTrackBits(tile)));
1669 break;
1670 }
1671 break;
1672
1673 case MP_TUNNELBRIDGE: {
1674 TileIndex endtile = GetOtherTunnelBridgeEnd(tile);
1675
1676 /* If both ends of tunnel/bridge are in the range, do not try to convert twice -
1677 * it would cause assert because of different test and exec runs */
1678 if (endtile < tile) {
1679 if (diagonal) {
1680 if (DiagonalTileArea(area_start, area_end).Contains(endtile)) continue;
1681 } else {
1682 if (OrthogonalTileArea(area_start, area_end).Contains(endtile)) continue;
1683 }
1684 }
1685
1686 /* When not converting rail <-> el. rail, any vehicle cannot be in tunnel/bridge */
1687 if (!IsCompatibleRail(GetRailType(tile), totype)) {
1688 CommandCost ret = TunnelBridgeIsFree(tile, endtile);
1689 if (ret.Failed()) {
1690 error = ret;
1691 continue;
1692 }
1693 }
1694
1695 if (flags & DC_EXEC) {
1696 Track track = DiagDirToDiagTrack(GetTunnelBridgeDirection(tile));
1697 if (HasTunnelBridgeReservation(tile)) {
1698 Train *v = GetTrainForReservation(tile, track);
1699 if (v != NULL && !HasPowerOnRail(v->railtype, totype)) {
1700 /* No power on new rail type, reroute. */
1701 FreeTrainTrackReservation(v);
1702 *vehicles_affected.Append() = v;
1703 }
1704 }
1705
1706 /* Update the company infrastructure counters. */
1707 uint num_pieces = (GetTunnelBridgeLength(tile, endtile) + 2) * TUNNELBRIDGE_TRACKBIT_FACTOR;
1708 Company *c = Company::Get(GetTileOwner(tile));
1709 c->infrastructure.rail[GetRailType(tile)] -= num_pieces;
1710 c->infrastructure.rail[totype] += num_pieces;
1711 DirtyCompanyInfrastructureWindows(c->index);
1712
1713 SetRailType(tile, totype);
1714 SetRailType(endtile, totype);
1715
1716 FindVehicleOnPos(tile, &affected_trains, &UpdateTrainPowerProc);
1717 FindVehicleOnPos(endtile, &affected_trains, &UpdateTrainPowerProc);
1718
1719 YapfNotifyTrackLayoutChange(tile, track);
1720 YapfNotifyTrackLayoutChange(endtile, track);
1721
1722 if (IsBridge(tile)) {
1723 MarkBridgeDirty(tile);
1724 } else {
1725 MarkTileDirtyByTile(tile);
1726 MarkTileDirtyByTile(endtile);
1727 }
1728 }
1729
1730 cost.AddCost((GetTunnelBridgeLength(tile, endtile) + 2) * RailConvertCost(type, totype));
1731 break;
1732 }
1733
1734 default: // MP_STATION, MP_ROAD
1735 if (flags & DC_EXEC) {
1736 Track track = ((tt == MP_STATION) ? GetRailStationTrack(tile) : GetCrossingRailTrack(tile));
1737 YapfNotifyTrackLayoutChange(tile, track);
1738 }
1739
1740 cost.AddCost(RailConvertCost(type, totype));
1741 break;
1742 }
1743
1744 for (uint i = 0; i < vehicles_affected.Length(); ++i) {
1745 TryPathReserve(vehicles_affected[i], true);
1746 }
1747 }
1748
1749 if (flags & DC_EXEC) {
1750 /* Railtype changed, update trains as when entering different track */
1751 for (Train **v = affected_trains.Begin(); v != affected_trains.End(); v++) {
1752 (*v)->ConsistChanged(CCF_TRACK);
1753 }
1754 }
1755
1756 delete iter;
1757 return (cost.GetCost() == 0) ? error : cost;
1758 }
1759
1760 static CommandCost RemoveTrainDepot(TileIndex tile, DoCommandFlag flags)
1761 {
1762 if (_current_company != OWNER_WATER) {
1763 CommandCost ret = CheckTileOwnership(tile);
1764 if (ret.Failed()) return ret;
1765 }
1766
1767 CommandCost ret = EnsureNoVehicleOnGround(tile);
1768 if (ret.Failed()) return ret;
1769
1770 if (flags & DC_EXEC) {
1771 /* read variables before the depot is removed */
1772 DiagDirection dir = GetRailDepotDirection(tile);
1773 Owner owner = GetTileOwner(tile);
1774 Train *v = NULL;
1775
1776 if (HasDepotReservation(tile)) {
1777 v = GetTrainForReservation(tile, DiagDirToDiagTrack(dir));
1778 if (v != NULL) FreeTrainTrackReservation(v);
1779 }
1780
1781 Company::Get(owner)->infrastructure.rail[GetRailType(tile)]--;
1782 DirtyCompanyInfrastructureWindows(owner);
1783
1784 delete Depot::GetByTile(tile);
1785 DoClearSquare(tile);
1786 AddSideToSignalBuffer(tile, dir, owner);
1787 YapfNotifyTrackLayoutChange(tile, DiagDirToDiagTrack(dir));
1788 if (v != NULL) TryPathReserve(v, true);
1789 }
1790
1791 return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_DEPOT_TRAIN]);
1792 }
1793
1794 static CommandCost ClearTile_Track(TileIndex tile, DoCommandFlag flags)
1795 {
1796 CommandCost cost(EXPENSES_CONSTRUCTION);
1797
1798 if (flags & DC_AUTO) {
1799 if (!IsTileOwner(tile, _current_company)) {
1800 return_cmd_error(STR_ERROR_AREA_IS_OWNED_BY_ANOTHER);
1801 }
1802
1803 if (IsPlainRail(tile)) {
1804 return_cmd_error(STR_ERROR_MUST_REMOVE_RAILROAD_TRACK);
1805 } else {
1806 return_cmd_error(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
1807 }
1808 }
1809
1810 switch (GetRailTileType(tile)) {
1811 case RAIL_TILE_SIGNALS:
1812 case RAIL_TILE_NORMAL: {
1813 Slope tileh = GetTileSlope(tile);
1814 /* Is there flat water on the lower halftile that gets cleared expensively? */
1815 bool water_ground = (GetRailGroundType(tile) == RAIL_GROUND_WATER && IsSlopeWithOneCornerRaised(tileh));
1816
1817 TrackBits tracks = GetTrackBits(tile);
1818 while (tracks != TRACK_BIT_NONE) {
1819 Track track = RemoveFirstTrack(&tracks);
1820 CommandCost ret = DoCommand(tile, 0, track, flags, CMD_REMOVE_SINGLE_RAIL);
1821 if (ret.Failed()) return ret;
1822 cost.AddCost(ret);
1823 }
1824
1825 /* When bankrupting, don't make water dirty, there could be a ship on lower halftile.
1826 * Same holds for non-companies clearing the tile, e.g. disasters. */
1827 if (water_ground && !(flags & DC_BANKRUPT) && Company::IsValidID(_current_company)) {
1828 CommandCost ret = EnsureNoVehicleOnGround(tile);
1829 if (ret.Failed()) return ret;
1830
1831 /* The track was removed, and left a coast tile. Now also clear the water. */
1832 if (flags & DC_EXEC) DoClearSquare(tile);
1833 cost.AddCost(_price[PR_CLEAR_WATER]);
1834 }
1835
1836 return cost;
1837 }
1838
1839 case RAIL_TILE_DEPOT:
1840 return RemoveTrainDepot(tile, flags);
1841
1842 default:
1843 return CMD_ERROR;
1844 }
1845 }
1846
1851 static uint GetSaveSlopeZ(uint x, uint y, Track track)
1852 {
1853 switch (track) {
1854 case TRACK_UPPER: x &= ~0xF; y &= ~0xF; break;
1855 case TRACK_LOWER: x |= 0xF; y |= 0xF; break;
1856 case TRACK_LEFT: x |= 0xF; y &= ~0xF; break;
1857 case TRACK_RIGHT: x &= ~0xF; y |= 0xF; break;
1858 default: break;
1859 }
1860 return GetSlopePixelZ(x, y);
1861 }
1862
1863 static void DrawSingleSignal(TileIndex tile, const RailtypeInfo *rti, Track track, SignalState condition, SignalOffsets image, uint pos)
1864 {
1865 bool side;
1866 switch (_settings_game.construction.train_signal_side) {
1867 case 0: side = false; break; // left
1868 case 2: side = true; break; // right
1869 default: side = _settings_game.vehicle.road_side != 0; break; // driving side
1870 }
1871 static const Point SignalPositions[2][12] = {
1872 { // Signals on the left side
1873 /* LEFT LEFT RIGHT RIGHT UPPER UPPER */
1874 { 8, 5}, {14, 1}, { 1, 14}, { 9, 11}, { 1, 0}, { 3, 10},
1875 /* LOWER LOWER X X Y Y */
1876 {11, 4}, {14, 14}, {11, 3}, { 4, 13}, { 3, 4}, {11, 13}
1877 }, { // Signals on the right side
1878 /* LEFT LEFT RIGHT RIGHT UPPER UPPER */
1879 {14, 1}, {12, 10}, { 4, 6}, { 1, 14}, {10, 4}, { 0, 1},
1880 /* LOWER LOWER X X Y Y */
1881 {14, 14}, { 5, 12}, {11, 13}, { 4, 3}, {13, 4}, { 3, 11}
1882 }
1883 };
1884
1885 uint x = TileX(tile) * TILE_SIZE + SignalPositions[side][pos].x;
1886 uint y = TileY(tile) * TILE_SIZE + SignalPositions[side][pos].y;
1887
1888 SignalType type = GetSignalType(tile, track);
1889 SignalVariant variant = GetSignalVariant(tile, track);
1890
1891 SpriteID sprite = GetCustomSignalSprite(rti, tile, type, variant, condition);
1892 if (sprite != 0) {
1893 sprite += image;
1894 } else {
1895 /* Normal electric signals are stored in a different sprite block than all other signals. */
1896 sprite = (type == SIGTYPE_NORMAL && variant == SIG_ELECTRIC) ? SPR_ORIGINAL_SIGNALS_BASE : SPR_SIGNALS_BASE - 16;
1897 sprite += type * 16 + variant * 64 + image * 2 + condition + (type > SIGTYPE_LAST_NOPBS ? 64 : 0);
1898 }
1899
1900 AddSortableSpriteToDraw(sprite, PAL_NONE, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, GetSaveSlopeZ(x, y, track));
1901 }
1902
1903 static uint32 _drawtile_track_palette;
1904
1905
1906
1908 struct FenceOffset {
1909 Corner height_ref;
1910 int x_offs;
1911 int y_offs;
1912 int x_size;
1913 int y_size;
1914 };
1915
1917 static FenceOffset _fence_offsets[] = {
1918 { CORNER_INVALID, 0, 1, 16, 1 }, // RFO_FLAT_X_NW
1919 { CORNER_INVALID, 1, 0, 1, 16 }, // RFO_FLAT_Y_NE
1920 { CORNER_W, 8, 8, 1, 1 }, // RFO_FLAT_LEFT
1921 { CORNER_N, 8, 8, 1, 1 }, // RFO_FLAT_UPPER
1922 { CORNER_INVALID, 0, 1, 16, 1 }, // RFO_SLOPE_SW_NW
1923 { CORNER_INVALID, 1, 0, 1, 16 }, // RFO_SLOPE_SE_NE
1924 { CORNER_INVALID, 0, 1, 16, 1 }, // RFO_SLOPE_NE_NW
1925 { CORNER_INVALID, 1, 0, 1, 16 }, // RFO_SLOPE_NW_NE
1926 { CORNER_INVALID, 0, 15, 16, 1 }, // RFO_FLAT_X_SE
1927 { CORNER_INVALID, 15, 0, 1, 16 }, // RFO_FLAT_Y_SW
1928 { CORNER_E, 8, 8, 1, 1 }, // RFO_FLAT_RIGHT
1929 { CORNER_S, 8, 8, 1, 1 }, // RFO_FLAT_LOWER
1930 { CORNER_INVALID, 0, 15, 16, 1 }, // RFO_SLOPE_SW_SE
1931 { CORNER_INVALID, 15, 0, 1, 16 }, // RFO_SLOPE_SE_SW
1932 { CORNER_INVALID, 0, 15, 16, 1 }, // RFO_SLOPE_NE_SE
1933 { CORNER_INVALID, 15, 0, 1, 16 }, // RFO_SLOPE_NW_SW
1934 };
1935
1943 static void DrawTrackFence(const TileInfo *ti, SpriteID base_image, uint num_sprites, RailFenceOffset rfo)
1944 {
1945 int z = ti->z;
1946 if (_fence_offsets[rfo].height_ref != CORNER_INVALID) {
1947 z += GetSlopePixelZInCorner(RemoveHalftileSlope(ti->tileh), _fence_offsets[rfo].height_ref);
1948 }
1949 AddSortableSpriteToDraw(base_image + (rfo % num_sprites), _drawtile_track_palette,
1950 ti->x + _fence_offsets[rfo].x_offs,
1951 ti->y + _fence_offsets[rfo].y_offs,
1952 _fence_offsets[rfo].x_size,
1953 _fence_offsets[rfo].y_size,
1954 4, z);
1955 }
1956
1960 static void DrawTrackFence_NW(const TileInfo *ti, SpriteID base_image, uint num_sprites)
1961 {
1962 RailFenceOffset rfo = RFO_FLAT_X_NW;
1963 if (ti->tileh & SLOPE_NW) rfo = (ti->tileh & SLOPE_W) ? RFO_SLOPE_SW_NW : RFO_SLOPE_NE_NW;
1964 DrawTrackFence(ti, base_image, num_sprites, rfo);
1965 }
1966
1970 static void DrawTrackFence_SE(const TileInfo *ti, SpriteID base_image, uint num_sprites)
1971 {
1972 RailFenceOffset rfo = RFO_FLAT_X_SE;
1973 if (ti->tileh & SLOPE_SE) rfo = (ti->tileh & SLOPE_S) ? RFO_SLOPE_SW_SE : RFO_SLOPE_NE_SE;
1974 DrawTrackFence(ti, base_image, num_sprites, rfo);
1975 }
1976
1980 static void DrawTrackFence_NE(const TileInfo *ti, SpriteID base_image, uint num_sprites)
1981 {
1982 RailFenceOffset rfo = RFO_FLAT_Y_NE;
1983 if (ti->tileh & SLOPE_NE) rfo = (ti->tileh & SLOPE_E) ? RFO_SLOPE_SE_NE : RFO_SLOPE_NW_NE;
1984 DrawTrackFence(ti, base_image, num_sprites, rfo);
1985 }
1986
1990 static void DrawTrackFence_SW(const TileInfo *ti, SpriteID base_image, uint num_sprites)
1991 {
1992 RailFenceOffset rfo = RFO_FLAT_Y_SW;
1993 if (ti->tileh & SLOPE_SW) rfo = (ti->tileh & SLOPE_S) ? RFO_SLOPE_SE_SW : RFO_SLOPE_NW_SW;
1994 DrawTrackFence(ti, base_image, num_sprites, rfo);
1995 }
1996
2002 static void DrawTrackDetails(const TileInfo *ti, const RailtypeInfo *rti)
2003 {
2004 /* Base sprite for track fences.
2005 * Note: Halftile slopes only have fences on the upper part. */
2006 uint num_sprites = 0;
2007 SpriteID base_image = GetCustomRailSprite(rti, ti->tile, RTSG_FENCES, IsHalftileSlope(ti->tileh) ? TCX_UPPER_HALFTILE : TCX_NORMAL, &num_sprites);
2008 if (base_image == 0) {
2009 base_image = SPR_TRACK_FENCE_FLAT_X;
2010 num_sprites = 8;
2011 }
2012
2013 assert(num_sprites > 0);
2014
2015 switch (GetRailGroundType(ti->tile)) {
2016 case RAIL_GROUND_FENCE_NW: DrawTrackFence_NW(ti, base_image, num_sprites); break;
2017 case RAIL_GROUND_FENCE_SE: DrawTrackFence_SE(ti, base_image, num_sprites); break;
2018 case RAIL_GROUND_FENCE_SENW: DrawTrackFence_NW(ti, base_image, num_sprites);
2019 DrawTrackFence_SE(ti, base_image, num_sprites); break;
2020 case RAIL_GROUND_FENCE_NE: DrawTrackFence_NE(ti, base_image, num_sprites); break;
2021 case RAIL_GROUND_FENCE_SW: DrawTrackFence_SW(ti, base_image, num_sprites); break;
2022 case RAIL_GROUND_FENCE_NESW: DrawTrackFence_NE(ti, base_image, num_sprites);
2023 DrawTrackFence_SW(ti, base_image, num_sprites); break;
2024 case RAIL_GROUND_FENCE_VERT1: DrawTrackFence(ti, base_image, num_sprites, RFO_FLAT_LEFT); break;
2025 case RAIL_GROUND_FENCE_VERT2: DrawTrackFence(ti, base_image, num_sprites, RFO_FLAT_RIGHT); break;
2026 case RAIL_GROUND_FENCE_HORIZ1: DrawTrackFence(ti, base_image, num_sprites, RFO_FLAT_UPPER); break;
2027 case RAIL_GROUND_FENCE_HORIZ2: DrawTrackFence(ti, base_image, num_sprites, RFO_FLAT_LOWER); break;
2028 case RAIL_GROUND_WATER: {
2029 Corner track_corner;
2030 if (IsHalftileSlope(ti->tileh)) {
2031 /* Steep slope or one-corner-raised slope with halftile foundation */
2032 track_corner = GetHalftileSlopeCorner(ti->tileh);
2033 } else {
2034 /* Three-corner-raised slope */
2035 track_corner = OppositeCorner(GetHighestSlopeCorner(ComplementSlope(ti->tileh)));
2036 }
2037 switch (track_corner) {
2038 case CORNER_W: DrawTrackFence(ti, base_image, num_sprites, RFO_FLAT_LEFT); break;
2039 case CORNER_S: DrawTrackFence(ti, base_image, num_sprites, RFO_FLAT_LOWER); break;
2040 case CORNER_E: DrawTrackFence(ti, base_image, num_sprites, RFO_FLAT_RIGHT); break;
2041 case CORNER_N: DrawTrackFence(ti, base_image, num_sprites, RFO_FLAT_UPPER); break;
2042 default: NOT_REACHED();
2043 }
2044 break;
2045 }
2046 default: break;
2047 }
2048 }
2049
2050 /* SubSprite for drawing the track halftile of 'three-corners-raised'-sloped rail sprites. */
2051 static const int INF = 1000; // big number compared to tilesprite size
2052 static const SubSprite _halftile_sub_sprite[4] = {
2053 { -INF , -INF , 32 - 33, INF }, // CORNER_W, clip 33 pixels from right
2054 { -INF , 0 + 7, INF , INF }, // CORNER_S, clip 7 pixels from top
2055 { -31 + 33, -INF , INF , INF }, // CORNER_E, clip 33 pixels from left
2056 { -INF , -INF , INF , 30 - 23 } // CORNER_N, clip 23 pixels from bottom
2057 };
2058
2059 static inline void DrawTrackSprite(SpriteID sprite, PaletteID pal, const TileInfo *ti, Slope s)
2060 {
2061 DrawGroundSprite(sprite, pal, NULL, 0, (ti->tileh & s) ? -8 : 0);
2062 }
2063
2064 static void DrawTrackBitsOverlay(TileInfo *ti, TrackBits track, const RailtypeInfo *rti)
2065 {
2066 RailGroundType rgt = GetRailGroundType(ti->tile);
2067 Foundation f = GetRailFoundation(ti->tileh, track);
2068 Corner halftile_corner = CORNER_INVALID;
2069
2070 if (IsNonContinuousFoundation(f)) {
2071 /* Save halftile corner */
2072 halftile_corner = (f == FOUNDATION_STEEP_BOTH ? GetHighestSlopeCorner(ti->tileh) : GetHalftileFoundationCorner(f));
2073 /* Draw lower part first */
2074 track &= ~CornerToTrackBits(halftile_corner);
2075 f = (f == FOUNDATION_STEEP_BOTH ? FOUNDATION_STEEP_LOWER : FOUNDATION_NONE);
2076 }
2077
2078 DrawFoundation(ti, f);
2079 /* DrawFoundation modifies ti */
2080
2081 /* Draw ground */
2082 if (rgt == RAIL_GROUND_WATER) {
2083 if (track != TRACK_BIT_NONE || IsSteepSlope(ti->tileh)) {
2084 /* three-corner-raised slope or steep slope with track on upper part */
2085 DrawShoreTile(ti->tileh);
2086 } else {
2087 /* single-corner-raised slope with track on upper part */
2088 DrawGroundSprite(SPR_FLAT_WATER_TILE, PAL_NONE);
2089 }
2090 } else {
2091 SpriteID image;
2092
2093 switch (rgt) {
2094 case RAIL_GROUND_BARREN: image = SPR_FLAT_BARE_LAND; break;
2095 case RAIL_GROUND_ICE_DESERT: image = SPR_FLAT_SNOW_DESERT_TILE; break;
2096 default: image = SPR_FLAT_GRASS_TILE; break;
2097 }
2098
2099 image += SlopeToSpriteOffset(ti->tileh);
2100
2101 DrawGroundSprite(image, PAL_NONE);
2102 }
2103
2104 SpriteID overlay = GetCustomRailSprite(rti, ti->tile, RTSG_OVERLAY);
2105 SpriteID ground = GetCustomRailSprite(rti, ti->tile, RTSG_GROUND);
2106 TrackBits pbs = _settings_client.gui.show_track_reservation ? GetRailReservationTrackBits(ti->tile) : TRACK_BIT_NONE;
2107
2108 if (track == TRACK_BIT_NONE) {
2109 /* Half-tile foundation, no track here? */
2110 } else if (ti->tileh == SLOPE_NW && track == TRACK_BIT_Y) {
2111 DrawGroundSprite(ground + RTO_SLOPE_NW, PAL_NONE);
2112 if (pbs != TRACK_BIT_NONE) DrawGroundSprite(overlay + RTO_SLOPE_NW, PALETTE_CRASH);
2113 } else if (ti->tileh == SLOPE_NE && track == TRACK_BIT_X) {
2114 DrawGroundSprite(ground + RTO_SLOPE_NE, PAL_NONE);
2115 if (pbs != TRACK_BIT_NONE) DrawGroundSprite(overlay + RTO_SLOPE_NE, PALETTE_CRASH);
2116 } else if (ti->tileh == SLOPE_SE && track == TRACK_BIT_Y) {
2117 DrawGroundSprite(ground + RTO_SLOPE_SE, PAL_NONE);
2118 if (pbs != TRACK_BIT_NONE) DrawGroundSprite(overlay + RTO_SLOPE_SE, PALETTE_CRASH);
2119 } else if (ti->tileh == SLOPE_SW && track == TRACK_BIT_X) {
2120 DrawGroundSprite(ground + RTO_SLOPE_SW, PAL_NONE);
2121 if (pbs != TRACK_BIT_NONE) DrawGroundSprite(overlay + RTO_SLOPE_SW, PALETTE_CRASH);
2122 } else {
2123 switch (track) {
2124 /* Draw single ground sprite when not overlapping. No track overlay
2125 * is necessary for these sprites. */
2126 case TRACK_BIT_X: DrawGroundSprite(ground + RTO_X, PAL_NONE); break;
2127 case TRACK_BIT_Y: DrawGroundSprite(ground + RTO_Y, PAL_NONE); break;
2128 case TRACK_BIT_UPPER: DrawTrackSprite(ground + RTO_N, PAL_NONE, ti, SLOPE_N); break;
2129 case TRACK_BIT_LOWER: DrawTrackSprite(ground + RTO_S, PAL_NONE, ti, SLOPE_S); break;
2130 case TRACK_BIT_RIGHT: DrawTrackSprite(ground + RTO_E, PAL_NONE, ti, SLOPE_E); break;
2131 case TRACK_BIT_LEFT: DrawTrackSprite(ground + RTO_W, PAL_NONE, ti, SLOPE_W); break;
2132 case TRACK_BIT_CROSS: DrawGroundSprite(ground + RTO_CROSSING_XY, PAL_NONE); break;
2133 case TRACK_BIT_HORZ: DrawTrackSprite(ground + RTO_N, PAL_NONE, ti, SLOPE_N);
2134 DrawTrackSprite(ground + RTO_S, PAL_NONE, ti, SLOPE_S); break;
2135 case TRACK_BIT_VERT: DrawTrackSprite(ground + RTO_E, PAL_NONE, ti, SLOPE_E);
2136 DrawTrackSprite(ground + RTO_W, PAL_NONE, ti, SLOPE_W); break;
2137
2138 default:
2139 /* We're drawing a junction tile */
2140 if ((track & TRACK_BIT_3WAY_NE) == 0) {
2141 DrawGroundSprite(ground + RTO_JUNCTION_SW, PAL_NONE);
2142 } else if ((track & TRACK_BIT_3WAY_SW) == 0) {
2143 DrawGroundSprite(ground + RTO_JUNCTION_NE, PAL_NONE);
2144 } else if ((track & TRACK_BIT_3WAY_NW) == 0) {
2145 DrawGroundSprite(ground + RTO_JUNCTION_SE, PAL_NONE);
2146 } else if ((track & TRACK_BIT_3WAY_SE) == 0) {
2147 DrawGroundSprite(ground + RTO_JUNCTION_NW, PAL_NONE);
2148 } else {
2149 DrawGroundSprite(ground + RTO_JUNCTION_NSEW, PAL_NONE);
2150 }
2151
2152 /* Mask out PBS bits as we shall draw them afterwards anyway. */
2153 track &= ~pbs;
2154
2155 /* Draw regular track bits */
2156 if (track & TRACK_BIT_X) DrawGroundSprite(overlay + RTO_X, PAL_NONE);
2157 if (track & TRACK_BIT_Y) DrawGroundSprite(overlay + RTO_Y, PAL_NONE);
2158 if (track & TRACK_BIT_UPPER) DrawGroundSprite(overlay + RTO_N, PAL_NONE);
2159 if (track & TRACK_BIT_LOWER) DrawGroundSprite(overlay + RTO_S, PAL_NONE);
2160 if (track & TRACK_BIT_RIGHT) DrawGroundSprite(overlay + RTO_E, PAL_NONE);
2161 if (track & TRACK_BIT_LEFT) DrawGroundSprite(overlay + RTO_W, PAL_NONE);
2162 }
2163
2164 /* Draw reserved track bits */
2165 if (pbs & TRACK_BIT_X) DrawGroundSprite(overlay + RTO_X, PALETTE_CRASH);
2166 if (pbs & TRACK_BIT_Y) DrawGroundSprite(overlay + RTO_Y, PALETTE_CRASH);
2167 if (pbs & TRACK_BIT_UPPER) DrawTrackSprite(overlay + RTO_N, PALETTE_CRASH, ti, SLOPE_N);
2168 if (pbs & TRACK_BIT_LOWER) DrawTrackSprite(overlay + RTO_S, PALETTE_CRASH, ti, SLOPE_S);
2169 if (pbs & TRACK_BIT_RIGHT) DrawTrackSprite(overlay + RTO_E, PALETTE_CRASH, ti, SLOPE_E);
2170 if (pbs & TRACK_BIT_LEFT) DrawTrackSprite(overlay + RTO_W, PALETTE_CRASH, ti, SLOPE_W);
2171 }
2172
2173 if (IsValidCorner(halftile_corner)) {
2174 DrawFoundation(ti, HalftileFoundation(halftile_corner));
2175 overlay = GetCustomRailSprite(rti, ti->tile, RTSG_OVERLAY, TCX_UPPER_HALFTILE);
2176 ground = GetCustomRailSprite(rti, ti->tile, RTSG_GROUND, TCX_UPPER_HALFTILE);
2177
2178 /* Draw higher halftile-overlay: Use the sloped sprites with three corners raised. They probably best fit the lightning. */
2179 Slope fake_slope = SlopeWithThreeCornersRaised(OppositeCorner(halftile_corner));
2180
2181 SpriteID image;
2182 switch (rgt) {
2183 case RAIL_GROUND_BARREN: image = SPR_FLAT_BARE_LAND; break;
2184 case RAIL_GROUND_ICE_DESERT:
2185 case RAIL_GROUND_HALF_SNOW: image = SPR_FLAT_SNOW_DESERT_TILE; break;
2186 default: image = SPR_FLAT_GRASS_TILE; break;
2187 }
2188
2189 image += SlopeToSpriteOffset(fake_slope);
2190
2191 DrawGroundSprite(image, PAL_NONE, &(_halftile_sub_sprite[halftile_corner]));
2192
2193 track = CornerToTrackBits(halftile_corner);
2194
2195 int offset;
2196 switch (track) {
2197 default: NOT_REACHED();
2198 case TRACK_BIT_UPPER: offset = RTO_N; break;
2199 case TRACK_BIT_LOWER: offset = RTO_S; break;
2200 case TRACK_BIT_RIGHT: offset = RTO_E; break;
2201 case TRACK_BIT_LEFT: offset = RTO_W; break;
2202 }
2203
2204 DrawTrackSprite(ground + offset, PAL_NONE, ti, fake_slope);
2205 if (_settings_client.gui.show_track_reservation && HasReservedTracks(ti->tile, track)) {
2206 DrawTrackSprite(overlay + offset, PALETTE_CRASH, ti, fake_slope);
2207 }
2208 }
2209 }
2210
2216 static void DrawTrackBits(TileInfo *ti, TrackBits track)
2217 {
2218 const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
2219
2220 if (rti->UsesOverlay()) {
2221 DrawTrackBitsOverlay(ti, track, rti);
2222 return;
2223 }
2224
2225 RailGroundType rgt = GetRailGroundType(ti->tile);
2226 Foundation f = GetRailFoundation(ti->tileh, track);
2227 Corner halftile_corner = CORNER_INVALID;
2228
2229 if (IsNonContinuousFoundation(f)) {
2230 /* Save halftile corner */
2231 halftile_corner = (f == FOUNDATION_STEEP_BOTH ? GetHighestSlopeCorner(ti->tileh) : GetHalftileFoundationCorner(f));
2232 /* Draw lower part first */
2233 track &= ~CornerToTrackBits(halftile_corner);
2234 f = (f == FOUNDATION_STEEP_BOTH ? FOUNDATION_STEEP_LOWER : FOUNDATION_NONE);
2235 }
2236
2237 DrawFoundation(ti, f);
2238 /* DrawFoundation modifies ti */
2239
2240 SpriteID image;
2241 PaletteID pal = PAL_NONE;
2242 const SubSprite *sub = NULL;
2243 bool junction = false;
2244
2245 /* Select the sprite to use. */
2246 if (track == 0) {
2247 /* Clear ground (only track on halftile foundation) */
2248 if (rgt == RAIL_GROUND_WATER) {
2249 if (IsSteepSlope(ti->tileh)) {
2250 DrawShoreTile(ti->tileh);
2251 image = 0;
2252 } else {
2253 image = SPR_FLAT_WATER_TILE;
2254 }
2255 } else {
2256 switch (rgt) {
2257 case RAIL_GROUND_BARREN: image = SPR_FLAT_BARE_LAND; break;
2258 case RAIL_GROUND_ICE_DESERT: image = SPR_FLAT_SNOW_DESERT_TILE; break;
2259 default: image = SPR_FLAT_GRASS_TILE; break;
2260 }
2261 image += SlopeToSpriteOffset(ti->tileh);
2262 }
2263 } else {
2264 if (ti->tileh != SLOPE_FLAT) {
2265 /* track on non-flat ground */
2266 image = _track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.track_y;
2267 } else {
2268 /* track on flat ground */
2269 (image = rti->base_sprites.track_y, track == TRACK_BIT_Y) ||
2270 (image++, track == TRACK_BIT_X) ||
2271 (image++, track == TRACK_BIT_UPPER) ||
2272 (image++, track == TRACK_BIT_LOWER) ||
2273 (image++, track == TRACK_BIT_RIGHT) ||
2274 (image++, track == TRACK_BIT_LEFT) ||
2275 (image++, track == TRACK_BIT_CROSS) ||
2276
2277 (image = rti->base_sprites.track_ns, track == TRACK_BIT_HORZ) ||
2278 (image++, track == TRACK_BIT_VERT) ||
2279
2280 (junction = true, false) ||
2281 (image = rti->base_sprites.ground, (track & TRACK_BIT_3WAY_NE) == 0) ||
2282 (image++, (track & TRACK_BIT_3WAY_SW) == 0) ||
2283 (image++, (track & TRACK_BIT_3WAY_NW) == 0) ||
2284 (image++, (track & TRACK_BIT_3WAY_SE) == 0) ||
2285 (image++, true);
2286 }
2287
2288 switch (rgt) {
2289 case RAIL_GROUND_BARREN: pal = PALETTE_TO_BARE_LAND; break;
2290 case RAIL_GROUND_ICE_DESERT: image += rti->snow_offset; break;
2291 case RAIL_GROUND_WATER: {
2292 /* three-corner-raised slope */
2293 DrawShoreTile(ti->tileh);
2294 Corner track_corner = OppositeCorner(GetHighestSlopeCorner(ComplementSlope(ti->tileh)));
2295 sub = &(_halftile_sub_sprite[track_corner]);
2296 break;
2297 }
2298 default: break;
2299 }
2300 }
2301
2302 if (image != 0) DrawGroundSprite(image, pal, sub);
2303
2304 /* Draw track pieces individually for junction tiles */
2305 if (junction) {
2306 if (track & TRACK_BIT_X) DrawGroundSprite(rti->base_sprites.single_x, PAL_NONE);
2307 if (track & TRACK_BIT_Y) DrawGroundSprite(rti->base_sprites.single_y, PAL_NONE);
2308 if (track & TRACK_BIT_UPPER) DrawGroundSprite(rti->base_sprites.single_n, PAL_NONE);
2309 if (track & TRACK_BIT_LOWER) DrawGroundSprite(rti->base_sprites.single_s, PAL_NONE);
2310 if (track & TRACK_BIT_LEFT) DrawGroundSprite(rti->base_sprites.single_w, PAL_NONE);
2311 if (track & TRACK_BIT_RIGHT) DrawGroundSprite(rti->base_sprites.single_e, PAL_NONE);
2312 }
2313
2314 /* PBS debugging, draw reserved tracks darker */
2315 if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation) {
2316 /* Get reservation, but mask track on halftile slope */
2317 TrackBits pbs = GetRailReservationTrackBits(ti->tile) & track;
2318 if (pbs & TRACK_BIT_X) {
2319 if (ti->tileh == SLOPE_FLAT || ti->tileh == SLOPE_ELEVATED) {
2320 DrawGroundSprite(rti->base_sprites.single_x, PALETTE_CRASH);
2321 } else {
2322 DrawGroundSprite(_track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.single_sloped - 20, PALETTE_CRASH);
2323 }
2324 }
2325 if (pbs & TRACK_BIT_Y) {
2326 if (ti->tileh == SLOPE_FLAT || ti->tileh == SLOPE_ELEVATED) {
2327 DrawGroundSprite(rti->base_sprites.single_y, PALETTE_CRASH);
2328 } else {
2329 DrawGroundSprite(_track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.single_sloped - 20, PALETTE_CRASH);
2330 }
2331 }
2332 if (pbs & TRACK_BIT_UPPER) DrawGroundSprite(rti->base_sprites.single_n, PALETTE_CRASH, NULL, 0, ti->tileh & SLOPE_N ? -(int)TILE_HEIGHT : 0);
2333 if (pbs & TRACK_BIT_LOWER) DrawGroundSprite(rti->base_sprites.single_s, PALETTE_CRASH, NULL, 0, ti->tileh & SLOPE_S ? -(int)TILE_HEIGHT : 0);
2334 if (pbs & TRACK_BIT_LEFT) DrawGroundSprite(rti->base_sprites.single_w, PALETTE_CRASH, NULL, 0, ti->tileh & SLOPE_W ? -(int)TILE_HEIGHT : 0);
2335 if (pbs & TRACK_BIT_RIGHT) DrawGroundSprite(rti->base_sprites.single_e, PALETTE_CRASH, NULL, 0, ti->tileh & SLOPE_E ? -(int)TILE_HEIGHT : 0);
2336 }
2337
2338 if (IsValidCorner(halftile_corner)) {
2339 DrawFoundation(ti, HalftileFoundation(halftile_corner));
2340
2341 /* Draw higher halftile-overlay: Use the sloped sprites with three corners raised. They probably best fit the lightning. */
2342 Slope fake_slope = SlopeWithThreeCornersRaised(OppositeCorner(halftile_corner));
2343 image = _track_sloped_sprites[fake_slope - 1] + rti->base_sprites.track_y;
2344 pal = PAL_NONE;
2345 switch (rgt) {
2346 case RAIL_GROUND_BARREN: pal = PALETTE_TO_BARE_LAND; break;
2347 case RAIL_GROUND_ICE_DESERT:
2348 case RAIL_GROUND_HALF_SNOW: image += rti->snow_offset; break; // higher part has snow in this case too
2349 default: break;
2350 }
2351 DrawGroundSprite(image, pal, &(_halftile_sub_sprite[halftile_corner]));
2352
2353 if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && HasReservedTracks(ti->tile, CornerToTrackBits(halftile_corner))) {
2354 static const byte _corner_to_track_sprite[] = {3, 1, 2, 0};
2355 DrawGroundSprite(_corner_to_track_sprite[halftile_corner] + rti->base_sprites.single_n, PALETTE_CRASH, NULL, 0, -(int)TILE_HEIGHT);
2356 }
2357 }
2358 }
2359
2360 static void DrawSignals(TileIndex tile, TrackBits rails, const RailtypeInfo *rti)
2361 {
2362 #define MAYBE_DRAW_SIGNAL(x, y, z, t) if (IsSignalPresent(tile, x)) DrawSingleSignal(tile, rti, t, GetSingleSignalState(tile, x), y, z)
2363
2364 if (!(rails & TRACK_BIT_Y)) {
2365 if (!(rails & TRACK_BIT_X)) {
2366 if (rails & TRACK_BIT_LEFT) {
2367 MAYBE_DRAW_SIGNAL(2, SIGNAL_TO_NORTH, 0, TRACK_LEFT);
2368 MAYBE_DRAW_SIGNAL(3, SIGNAL_TO_SOUTH, 1, TRACK_LEFT);
2369 }
2370 if (rails & TRACK_BIT_RIGHT) {
2371 MAYBE_DRAW_SIGNAL(0, SIGNAL_TO_NORTH, 2, TRACK_RIGHT);
2372 MAYBE_DRAW_SIGNAL(1, SIGNAL_TO_SOUTH, 3, TRACK_RIGHT);
2373 }
2374 if (rails & TRACK_BIT_UPPER) {
2375 MAYBE_DRAW_SIGNAL(3, SIGNAL_TO_WEST, 4, TRACK_UPPER);
2376 MAYBE_DRAW_SIGNAL(2, SIGNAL_TO_EAST, 5, TRACK_UPPER);
2377 }
2378 if (rails & TRACK_BIT_LOWER) {
2379 MAYBE_DRAW_SIGNAL(1, SIGNAL_TO_WEST, 6, TRACK_LOWER);
2380 MAYBE_DRAW_SIGNAL(0, SIGNAL_TO_EAST, 7, TRACK_LOWER);
2381 }
2382 } else {
2383 MAYBE_DRAW_SIGNAL(3, SIGNAL_TO_SOUTHWEST, 8, TRACK_X);
2384 MAYBE_DRAW_SIGNAL(2, SIGNAL_TO_NORTHEAST, 9, TRACK_X);
2385 }
2386 } else {
2387 MAYBE_DRAW_SIGNAL(3, SIGNAL_TO_SOUTHEAST, 10, TRACK_Y);
2388 MAYBE_DRAW_SIGNAL(2, SIGNAL_TO_NORTHWEST, 11, TRACK_Y);
2389 }
2390 }
2391
2392 static void DrawTile_Track(TileInfo *ti)
2393 {
2394 const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
2395
2396 _drawtile_track_palette = COMPANY_SPRITE_COLOUR(GetTileOwner(ti->tile));
2397
2398 if (IsPlainRail(ti->tile)) {
2399 TrackBits rails = GetTrackBits(ti->tile);
2400
2401 DrawTrackBits(ti, rails);
2402
2403 if (HasBit(_display_opt, DO_FULL_DETAIL)) DrawTrackDetails(ti, rti);
2404
2405 if (HasRailCatenaryDrawn(GetRailType(ti->tile))) DrawRailCatenary(ti);
2406
2407 if (HasSignals(ti->tile)) DrawSignals(ti->tile, rails, rti);
2408 } else {
2409 /* draw depot */
2410 const DrawTileSprites *dts;
2411 PaletteID pal = PAL_NONE;
2412 SpriteID relocation;
2413
2414 if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
2415
2416 if (IsInvisibilitySet(TO_BUILDINGS)) {
2417 /* Draw rail instead of depot */
2418 dts = &_depot_invisible_gfx_table[GetRailDepotDirection(ti->tile)];
2419 } else {
2420 dts = &_depot_gfx_table[GetRailDepotDirection(ti->tile)];
2421 }
2422
2423 SpriteID image;
2424 if (rti->UsesOverlay()) {
2425 image = SPR_FLAT_GRASS_TILE;
2426 } else {
2427 image = dts->ground.sprite;
2428 if (image != SPR_FLAT_GRASS_TILE) image += rti->GetRailtypeSpriteOffset();
2429 }
2430
2431 /* adjust ground tile for desert
2432 * don't adjust for snow, because snow in depots looks weird */
2433 if (IsSnowRailGround(ti->tile) && _settings_game.game_creation.landscape == LT_TROPIC) {
2434 if (image != SPR_FLAT_GRASS_TILE) {
2435 image += rti->snow_offset; // tile with tracks
2436 } else {
2437 image = SPR_FLAT_SNOW_DESERT_TILE; // flat ground
2438 }
2439 }
2440
2441 DrawGroundSprite(image, GroundSpritePaletteTransform(image, pal, _drawtile_track_palette));
2442
2443 if (rti->UsesOverlay()) {
2444 SpriteID ground = GetCustomRailSprite(rti, ti->tile, RTSG_GROUND);
2445
2446 switch (GetRailDepotDirection(ti->tile)) {
2447 case DIAGDIR_NE:
2448 if (!IsInvisibilitySet(TO_BUILDINGS)) break;
2449 FALLTHROUGH;
2450 case DIAGDIR_SW:
2451 DrawGroundSprite(ground + RTO_X, PAL_NONE);
2452 break;
2453 case DIAGDIR_NW:
2454 if (!IsInvisibilitySet(TO_BUILDINGS)) break;
2455 FALLTHROUGH;
2456 case DIAGDIR_SE:
2457 DrawGroundSprite(ground + RTO_Y, PAL_NONE);
2458 break;
2459 default:
2460 break;
2461 }
2462
2463 if (_settings_client.gui.show_track_reservation && HasDepotReservation(ti->tile)) {
2464 SpriteID overlay = GetCustomRailSprite(rti, ti->tile, RTSG_OVERLAY);
2465
2466 switch (GetRailDepotDirection(ti->tile)) {
2467 case DIAGDIR_NE:
2468 if (!IsInvisibilitySet(TO_BUILDINGS)) break;
2469 FALLTHROUGH;
2470 case DIAGDIR_SW:
2471 DrawGroundSprite(overlay + RTO_X, PALETTE_CRASH);
2472 break;
2473 case DIAGDIR_NW:
2474 if (!IsInvisibilitySet(TO_BUILDINGS)) break;
2475 FALLTHROUGH;
2476 case DIAGDIR_SE:
2477 DrawGroundSprite(overlay + RTO_Y, PALETTE_CRASH);
2478 break;
2479 default:
2480 break;
2481 }
2482 }
2483 } else {
2484 /* PBS debugging, draw reserved tracks darker */
2485 if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && HasDepotReservation(ti->tile)) {
2486 switch (GetRailDepotDirection(ti->tile)) {
2487 case DIAGDIR_NE:
2488 if (!IsInvisibilitySet(TO_BUILDINGS)) break;
2489 FALLTHROUGH;
2490 case DIAGDIR_SW:
2491 DrawGroundSprite(rti->base_sprites.single_x, PALETTE_CRASH);
2492 break;
2493 case DIAGDIR_NW:
2494 if (!IsInvisibilitySet(TO_BUILDINGS)) break;
2495 FALLTHROUGH;
2496 case DIAGDIR_SE:
2497 DrawGroundSprite(rti->base_sprites.single_y, PALETTE_CRASH);
2498 break;
2499 default:
2500 break;
2501 }
2502 }
2503 }
2504 int depot_sprite = GetCustomRailSprite(rti, ti->tile, RTSG_DEPOT);
2505 relocation = depot_sprite != 0 ? depot_sprite - SPR_RAIL_DEPOT_SE_1 : rti->GetRailtypeSpriteOffset();
2506
2507 if (HasRailCatenaryDrawn(GetRailType(ti->tile))) DrawRailCatenary(ti);
2508
2509 DrawRailTileSeq(ti, dts, TO_BUILDINGS, relocation, 0, _drawtile_track_palette);
2510 }
2511 DrawBridgeMiddle(ti);
2512 }
2513
2514 void DrawTrainDepotSprite(int x, int y, int dir, RailType railtype)
2515 {
2516 const DrawTileSprites *dts = &_depot_gfx_table[dir];
2517 const RailtypeInfo *rti = GetRailTypeInfo(railtype);
2518 SpriteID image = rti->UsesOverlay() ? SPR_FLAT_GRASS_TILE : dts->ground.sprite;
2519 uint32 offset = rti->GetRailtypeSpriteOffset();
2520
2521 if (image != SPR_FLAT_GRASS_TILE) image += offset;
2522 PaletteID palette = COMPANY_SPRITE_COLOUR(_local_company);
2523
2524 DrawSprite(image, PAL_NONE, x, y);
2525
2526 if (rti->UsesOverlay()) {
2527 SpriteID ground = GetCustomRailSprite(rti, INVALID_TILE, RTSG_GROUND);
2528
2529 switch (dir) {
2530 case DIAGDIR_SW: DrawSprite(ground + RTO_X, PAL_NONE, x, y); break;
2531 case DIAGDIR_SE: DrawSprite(ground + RTO_Y, PAL_NONE, x, y); break;
2532 default: break;
2533 }
2534 }
2535 int depot_sprite = GetCustomRailSprite(rti, INVALID_TILE, RTSG_DEPOT);
2536 if (depot_sprite != 0) offset = depot_sprite - SPR_RAIL_DEPOT_SE_1;
2537
2538 DrawRailTileSeqInGUI(x, y, dts, offset, 0, palette);
2539 }
2540
2541 static int GetSlopePixelZ_Track(TileIndex tile, uint x, uint y)
2542 {
2543 if (IsPlainRail(tile)) {
2544 int z;
2545 Slope tileh = GetTilePixelSlope(tile, &z);
2546 if (tileh == SLOPE_FLAT) return z;
2547
2548 z += ApplyPixelFoundationToSlope(GetRailFoundation(tileh, GetTrackBits(tile)), &tileh);
2549 return z + GetPartialPixelZ(x & 0xF, y & 0xF, tileh);
2550 } else {
2551 return GetTileMaxPixelZ(tile);
2552 }
2553 }
2554
2555 static Foundation GetFoundation_Track(TileIndex tile, Slope tileh)
2556 {
2557 return IsPlainRail(tile) ? GetRailFoundation(tileh, GetTrackBits(tile)) : FlatteningFoundation(tileh);
2558 }
2559
2560 static void TileLoop_Track(TileIndex tile)
2561 {
2562 RailGroundType old_ground = GetRailGroundType(tile);
2563 RailGroundType new_ground;
2564
2565 if (old_ground == RAIL_GROUND_WATER) {
2566 TileLoop_Water(tile);
2567 return;
2568 }
2569
2570 switch (_settings_game.game_creation.landscape) {
2571 case LT_ARCTIC: {
2572 int z;
2573 Slope slope = GetTileSlope(tile, &z);
2574 bool half = false;
2575
2576 /* for non-flat track, use lower part of track
2577 * in other cases, use the highest part with track */
2578 if (IsPlainRail(tile)) {
2579 TrackBits track = GetTrackBits(tile);
2580 Foundation f = GetRailFoundation(slope, track);
2581
2582 switch (f) {
2583 case FOUNDATION_NONE:
2584 /* no foundation - is the track on the upper side of three corners raised tile? */
2585 if (IsSlopeWithThreeCornersRaised(slope)) z++;
2586 break;
2587
2588 case FOUNDATION_INCLINED_X:
2589 case FOUNDATION_INCLINED_Y:
2590 /* sloped track - is it on a steep slope? */
2591 if (IsSteepSlope(slope)) z++;
2592 break;
2593
2594 case FOUNDATION_STEEP_LOWER:
2595 /* only lower part of steep slope */
2596 z++;
2597 break;
2598
2599 default:
2600 /* if it is a steep slope, then there is a track on higher part */
2601 if (IsSteepSlope(slope)) z++;
2602 z++;
2603 break;
2604 }
2605
2606 half = IsInsideMM(f, FOUNDATION_STEEP_BOTH, FOUNDATION_HALFTILE_N + 1);
2607 } else {
2608 /* is the depot on a non-flat tile? */
2609 if (slope != SLOPE_FLAT) z++;
2610 }
2611
2612 /* 'z' is now the lowest part of the highest track bit -
2613 * for sloped track, it is 'z' of lower part
2614 * for two track bits, it is 'z' of higher track bit
2615 * For non-continuous foundations (and STEEP_BOTH), 'half' is set */
2616 if (z > GetSnowLine()) {
2617 if (half && z - GetSnowLine() == 1) {
2618 /* track on non-continuous foundation, lower part is not under snow */
2619 new_ground = RAIL_GROUND_HALF_SNOW;
2620 } else {
2621 new_ground = RAIL_GROUND_ICE_DESERT;
2622 }
2623 goto set_ground;
2624 }
2625 break;
2626 }
2627
2628 case LT_TROPIC:
2629 if (GetTropicZone(tile) == TROPICZONE_DESERT) {
2630 new_ground = RAIL_GROUND_ICE_DESERT;
2631 goto set_ground;
2632 }
2633 break;
2634 }
2635
2636 new_ground = RAIL_GROUND_GRASS;
2637
2638 if (IsPlainRail(tile) && old_ground != RAIL_GROUND_BARREN) { // wait until bottom is green
2639 /* determine direction of fence */
2640 TrackBits rail = GetTrackBits(tile);
2641
2642 Owner owner = GetTileOwner(tile);
2643 byte fences = 0;
2644
2645 for (DiagDirection d = DIAGDIR_BEGIN; d < DIAGDIR_END; d++) {
2646 static const TrackBits dir_to_trackbits[DIAGDIR_END] = {TRACK_BIT_3WAY_NE, TRACK_BIT_3WAY_SE, TRACK_BIT_3WAY_SW, TRACK_BIT_3WAY_NW};
2647
2648 /* Track bit on this edge => no fence. */
2649 if ((rail & dir_to_trackbits[d]) != TRACK_BIT_NONE) continue;
2650
2651 TileIndex tile2 = tile + TileOffsByDiagDir(d);
2652
2653 /* Show fences if it's a house, industry, object, road, tunnelbridge or not owned by us. */
2654 if (!IsValidTile(tile2) || IsTileType(tile2, MP_HOUSE) || IsTileType(tile2, MP_INDUSTRY) ||
2655 IsTileType(tile2, MP_ROAD) || (IsTileType(tile2, MP_OBJECT) && !IsObjectType(tile2, OBJECT_OWNED_LAND)) || IsTileType(tile2, MP_TUNNELBRIDGE) || !IsTileOwner(tile2, owner)) {
2656 fences |= 1 << d;
2657 }
2658 }
2659
2660 switch (fences) {
2661 case 0: break;
2662 case (1 << DIAGDIR_NE): new_ground = RAIL_GROUND_FENCE_NE; break;
2663 case (1 << DIAGDIR_SE): new_ground = RAIL_GROUND_FENCE_SE; break;
2664 case (1 << DIAGDIR_SW): new_ground = RAIL_GROUND_FENCE_SW; break;
2665 case (1 << DIAGDIR_NW): new_ground = RAIL_GROUND_FENCE_NW; break;
2666 case (1 << DIAGDIR_NE) | (1 << DIAGDIR_SW): new_ground = RAIL_GROUND_FENCE_NESW; break;
2667 case (1 << DIAGDIR_SE) | (1 << DIAGDIR_NW): new_ground = RAIL_GROUND_FENCE_SENW; break;
2668 case (1 << DIAGDIR_NE) | (1 << DIAGDIR_SE): new_ground = RAIL_GROUND_FENCE_VERT1; break;
2669 case (1 << DIAGDIR_NE) | (1 << DIAGDIR_NW): new_ground = RAIL_GROUND_FENCE_HORIZ2; break;
2670 case (1 << DIAGDIR_SE) | (1 << DIAGDIR_SW): new_ground = RAIL_GROUND_FENCE_HORIZ1; break;
2671 case (1 << DIAGDIR_SW) | (1 << DIAGDIR_NW): new_ground = RAIL_GROUND_FENCE_VERT2; break;
2672 default: NOT_REACHED();
2673 }
2674 }
2675
2676 set_ground:
2677 if (old_ground != new_ground) {
2678 SetRailGroundType(tile, new_ground);
2679 MarkTileDirtyByTile(tile);
2680 }
2681 }
2682
2683
2684 static TrackStatus GetTileTrackStatus_Track(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
2685 {
2686 /* Case of half tile slope with water. */
2687 if (mode == TRANSPORT_WATER && IsPlainRail(tile) && GetRailGroundType(tile) == RAIL_GROUND_WATER && IsSlopeWithOneCornerRaised(GetTileSlope(tile))) {
2688 TrackBits tb = GetTrackBits(tile);
2689 switch (tb) {
2690 default: NOT_REACHED();
2691 case TRACK_BIT_UPPER: tb = TRACK_BIT_LOWER; break;
2692 case TRACK_BIT_LOWER: tb = TRACK_BIT_UPPER; break;
2693 case TRACK_BIT_LEFT: tb = TRACK_BIT_RIGHT; break;
2694 case TRACK_BIT_RIGHT: tb = TRACK_BIT_LEFT; break;
2695 }
2696 return CombineTrackStatus(TrackBitsToTrackdirBits(tb), TRACKDIR_BIT_NONE);
2697 }
2698
2699 if (mode != TRANSPORT_RAIL) return 0;
2700
2701 TrackBits trackbits = TRACK_BIT_NONE;
2702 TrackdirBits red_signals = TRACKDIR_BIT_NONE;
2703
2704 switch (GetRailTileType(tile)) {
2705 default: NOT_REACHED();
2706 case RAIL_TILE_NORMAL:
2707 trackbits = GetTrackBits(tile);
2708 break;
2709
2710 case RAIL_TILE_SIGNALS: {
2711 trackbits = GetTrackBits(tile);
2712 byte a = GetPresentSignals(tile);
2713 uint b = GetSignalStates(tile);
2714
2715 b &= a;
2716
2717 /* When signals are not present (in neither direction),
2718 * we pretend them to be green. Otherwise, it depends on
2719 * the signal type. For signals that are only active from
2720 * one side, we set the missing signals explicitly to
2721 * `green'. Otherwise, they implicitly become `red'. */
2722 if (!IsOnewaySignal(tile, TRACK_UPPER) || (a & SignalOnTrack(TRACK_UPPER)) == 0) b |= ~a & SignalOnTrack(TRACK_UPPER);
2723 if (!IsOnewaySignal(tile, TRACK_LOWER) || (a & SignalOnTrack(TRACK_LOWER)) == 0) b |= ~a & SignalOnTrack(TRACK_LOWER);
2724
2725 if ((b & 0x8) == 0) red_signals |= (TRACKDIR_BIT_LEFT_N | TRACKDIR_BIT_X_NE | TRACKDIR_BIT_Y_SE | TRACKDIR_BIT_UPPER_E);
2726 if ((b & 0x4) == 0) red_signals |= (TRACKDIR_BIT_LEFT_S | TRACKDIR_BIT_X_SW | TRACKDIR_BIT_Y_NW | TRACKDIR_BIT_UPPER_W);
2727 if ((b & 0x2) == 0) red_signals |= (TRACKDIR_BIT_RIGHT_N | TRACKDIR_BIT_LOWER_E);
2728 if ((b & 0x1) == 0) red_signals |= (TRACKDIR_BIT_RIGHT_S | TRACKDIR_BIT_LOWER_W);
2729
2730 break;
2731 }
2732
2733 case RAIL_TILE_DEPOT: {
2734 DiagDirection dir = GetRailDepotDirection(tile);
2735
2736 if (side != INVALID_DIAGDIR && side != dir) break;
2737
2738 trackbits = DiagDirToDiagTrackBits(dir);
2739 break;
2740 }
2741 }
2742
2743 return CombineTrackStatus(TrackBitsToTrackdirBits(trackbits), red_signals);
2744 }
2745
2746 static bool ClickTile_Track(TileIndex tile)
2747 {
2748 if (!IsRailDepot(tile)) return false;
2749
2750 ShowDepotWindow(tile, VEH_TRAIN);
2751 return true;
2752 }
2753
2754 static void GetTileDesc_Track(TileIndex tile, TileDesc *td)
2755 {
2756 const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(tile));
2757 td->rail_speed = rti->max_speed;
2758 td->railtype = rti->strings.name;
2759 td->owner[0] = GetTileOwner(tile);
2760 switch (GetRailTileType(tile)) {
2761 case RAIL_TILE_NORMAL:
2762 td->str = STR_LAI_RAIL_DESCRIPTION_TRACK;
2763 break;
2764
2765 case RAIL_TILE_SIGNALS: {
2766 static const StringID signal_type[6][6] = {
2767 {
2768 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_SIGNALS,
2769 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PRESIGNALS,
2770 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_EXITSIGNALS,
2771 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_COMBOSIGNALS,
2772 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PBSSIGNALS,
2773 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_NOENTRYSIGNALS
2774 },
2775 {
2776 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PRESIGNALS,
2777 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRESIGNALS,
2778 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_EXITSIGNALS,
2779 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_COMBOSIGNALS,
2780 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_PBSSIGNALS,
2781 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_NOENTRYSIGNALS
2782 },
2783 {
2784 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_EXITSIGNALS,
2785 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_EXITSIGNALS,
2786 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXITSIGNALS,
2787 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_COMBOSIGNALS,
2788 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_PBSSIGNALS,
2789 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_NOENTRYSIGNALS
2790 },
2791 {
2792 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_COMBOSIGNALS,
2793 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_COMBOSIGNALS,
2794 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_COMBOSIGNALS,
2795 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBOSIGNALS,
2796 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_PBSSIGNALS,
2797 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_NOENTRYSIGNALS
2798 },
2799 {
2800 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PBSSIGNALS,
2801 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_PBSSIGNALS,
2802 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_PBSSIGNALS,
2803 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_PBSSIGNALS,
2804 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBSSIGNALS,
2805 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBS_NOENTRYSIGNALS
2806 },
2807 {
2808 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_NOENTRYSIGNALS,
2809 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_NOENTRYSIGNALS,
2810 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_NOENTRYSIGNALS,
2811 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_NOENTRYSIGNALS,
2812 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBS_NOENTRYSIGNALS,
2813 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NOENTRYSIGNALS
2814 }
2815 };
2816
2817 SignalType primary_signal;
2818 SignalType secondary_signal;
2819 if (HasSignalOnTrack(tile, TRACK_UPPER)) {
2820 primary_signal = GetSignalType(tile, TRACK_UPPER);
2821 secondary_signal = HasSignalOnTrack(tile, TRACK_LOWER) ? GetSignalType(tile, TRACK_LOWER) : primary_signal;
2822 } else {
2823 secondary_signal = primary_signal = GetSignalType(tile, TRACK_LOWER);
2824 }
2825
2826 td->str = signal_type[secondary_signal][primary_signal];
2827 break;
2828 }
2829
2830 case RAIL_TILE_DEPOT:
2831 td->str = STR_LAI_RAIL_DESCRIPTION_TRAIN_DEPOT;
2832 if (_settings_game.vehicle.train_acceleration_model != AM_ORIGINAL) {
2833 if (td->rail_speed > 0) {
2834 td->rail_speed = min(td->rail_speed, 61);
2835 } else {
2836 td->rail_speed = 61;
2837 }
2838 }
2839 td->build_date = Depot::GetByTile(tile)->build_date;
2840 break;
2841
2842 default:
2843 NOT_REACHED();
2844 }
2845 }
2846
2847 static void ChangeTileOwner_Track(TileIndex tile, Owner old_owner, Owner new_owner)
2848 {
2849 if (!IsTileOwner(tile, old_owner)) return;
2850
2851 if (new_owner != INVALID_OWNER) {
2852 /* Update company infrastructure counts. No need to dirty windows here, we'll redraw the whole screen anyway. */
2853 uint num_pieces = 1;
2854 if (IsPlainRail(tile)) {
2855 TrackBits bits = GetTrackBits(tile);
2856 num_pieces = CountBits(bits);
2857 if (TracksOverlap(bits)) num_pieces *= num_pieces;
2858 }
2859 RailType rt = GetRailType(tile);
2860 Company::Get(old_owner)->infrastructure.rail[rt] -= num_pieces;
2861 Company::Get(new_owner)->infrastructure.rail[rt] += num_pieces;
2862
2863 if (HasSignals(tile)) {
2864 uint num_sigs = CountBits(GetPresentSignals(tile));
2865 Company::Get(old_owner)->infrastructure.signal -= num_sigs;
2866 Company::Get(new_owner)->infrastructure.signal += num_sigs;
2867 }
2868
2869 SetTileOwner(tile, new_owner);
2870 } else {
2871 DoCommand(tile, 0, 0, DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR);
2872 }
2873 }
2874
2875 static const byte _fractcoords_behind[4] = { 0x8F, 0x8, 0x80, 0xF8 };
2876 static const byte _fractcoords_enter[4] = { 0x8A, 0x48, 0x84, 0xA8 };
2877 static const int8 _deltacoord_leaveoffset[8] = {
2878 -1, 0, 1, 0, /* x */
2879 0, 1, 0, -1 /* y */
2880 };
2881
2882
2889 int TicksToLeaveDepot(const Train *v)
2890 {
2891 DiagDirection dir = GetRailDepotDirection(v->tile);
2892 int length = v->CalcNextVehicleOffset();
2893
2894 switch (dir) {
2895 case DIAGDIR_NE: return ((int)(v->x_pos & 0x0F) - ((_fractcoords_enter[dir] & 0x0F) - (length + 1)));
2896 case DIAGDIR_SE: return -((int)(v->y_pos & 0x0F) - ((_fractcoords_enter[dir] >> 4) + (length + 1)));
2897 case DIAGDIR_SW: return -((int)(v->x_pos & 0x0F) - ((_fractcoords_enter[dir] & 0x0F) + (length + 1)));
2898 default:
2899 case DIAGDIR_NW: return ((int)(v->y_pos & 0x0F) - ((_fractcoords_enter[dir] >> 4) - (length + 1)));
2900 }
2901
2902 return 0; // make compilers happy
2903 }
2904
2909 static VehicleEnterTileStatus VehicleEnter_Track(Vehicle *u, TileIndex tile, int x, int y)
2910 {
2911 /* this routine applies only to trains in depot tiles */
2912 if (u->type != VEH_TRAIN || !IsRailDepotTile(tile)) return VETSB_CONTINUE;
2913
2914 Train *v = Train::From(u);
2915
2916 /* depot direction */
2917 DiagDirection dir = GetRailDepotDirection(tile);
2918
2919 /* Calculate the point where the following wagon should be activated. */
2920 int length = v->CalcNextVehicleOffset();
2921
2922 byte fract_coord_leave =
2923 ((_fractcoords_enter[dir] & 0x0F) + // x
2924 (length + 1) * _deltacoord_leaveoffset[dir]) +
2925 (((_fractcoords_enter[dir] >> 4) + // y
2926 ((length + 1) * _deltacoord_leaveoffset[dir + 4])) << 4);
2927
2928 byte fract_coord = (x & 0xF) + ((y & 0xF) << 4);
2929
2930 if (_fractcoords_behind[dir] == fract_coord) {
2931 /* make sure a train is not entering the tile from behind */
2932 return VETSB_CANNOT_ENTER;
2933 } else if (_fractcoords_enter[dir] == fract_coord) {
2934 if (DiagDirToDir(ReverseDiagDir(dir)) == v->direction) {
2935 /* enter the depot */
2936 v->track = TRACK_BIT_DEPOT,
2937 v->vehstatus |= VS_HIDDEN; // hide it
2938 v->direction = ReverseDir(v->direction);
2939 if (v->Next() == NULL) VehicleEnterDepot(v->First());
2940 v->tile = tile;
2941
2942 InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
2943 return VETSB_ENTERED_WORMHOLE;
2944 }
2945 } else if (fract_coord_leave == fract_coord) {
2946 if (DiagDirToDir(dir) == v->direction) {
2947 /* leave the depot? */
2948 if ((v = v->Next()) != NULL) {
2949 v->vehstatus &= ~VS_HIDDEN;
2950 v->track = (DiagDirToAxis(dir) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y);
2951 }
2952 }
2953 }
2954
2955 return VETSB_CONTINUE;
2956 }
2957
2969 static CommandCost TestAutoslopeOnRailTile(TileIndex tile, uint flags, int z_old, Slope tileh_old, int z_new, Slope tileh_new, TrackBits rail_bits)
2970 {
2971 if (!_settings_game.construction.build_on_slopes || !AutoslopeEnabled()) return_cmd_error(STR_ERROR_MUST_REMOVE_RAILROAD_TRACK);
2972
2973 /* Is the slope-rail_bits combination valid in general? I.e. is it safe to call GetRailFoundation() ? */
2974 if (CheckRailSlope(tileh_new, rail_bits, TRACK_BIT_NONE, tile).Failed()) return_cmd_error(STR_ERROR_MUST_REMOVE_RAILROAD_TRACK);
2975
2976 /* Get the slopes on top of the foundations */
2977 z_old += ApplyFoundationToSlope(GetRailFoundation(tileh_old, rail_bits), &tileh_old);
2978 z_new += ApplyFoundationToSlope(GetRailFoundation(tileh_new, rail_bits), &tileh_new);
2979
2980 Corner track_corner;
2981 switch (rail_bits) {
2982 case TRACK_BIT_LEFT: track_corner = CORNER_W; break;
2983 case TRACK_BIT_LOWER: track_corner = CORNER_S; break;
2984 case TRACK_BIT_RIGHT: track_corner = CORNER_E; break;
2985 case TRACK_BIT_UPPER: track_corner = CORNER_N; break;
2986
2987 /* Surface slope must not be changed */
2988 default:
2989 if (z_old != z_new || tileh_old != tileh_new) return_cmd_error(STR_ERROR_MUST_REMOVE_RAILROAD_TRACK);
2990 return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
2991 }
2992
2993 /* The height of the track_corner must not be changed. The rest ensures GetRailFoundation() already. */
2994 z_old += GetSlopeZInCorner(RemoveHalftileSlope(tileh_old), track_corner);
2995 z_new += GetSlopeZInCorner(RemoveHalftileSlope(tileh_new), track_corner);
2996 if (z_old != z_new) return_cmd_error(STR_ERROR_MUST_REMOVE_RAILROAD_TRACK);
2997
2998 CommandCost cost = CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
2999 /* Make the ground dirty, if surface slope has changed */
3000 if (tileh_old != tileh_new) {
3001 /* If there is flat water on the lower halftile add the cost for clearing it */
3002 if (GetRailGroundType(tile) == RAIL_GROUND_WATER && IsSlopeWithOneCornerRaised(tileh_old)) cost.AddCost(_price[PR_CLEAR_WATER]);
3003 if ((flags & DC_EXEC) != 0) SetRailGroundType(tile, RAIL_GROUND_BARREN);
3004 }
3005 return cost;
3006 }
3007
3011 static Vehicle *EnsureNoShipProc(Vehicle *v, void *data)
3012 {
3013 return v->type == VEH_SHIP ? v : NULL;
3014 }
3015
3016 static CommandCost TerraformTile_Track(TileIndex tile, DoCommandFlag flags, int z_new, Slope tileh_new)
3017 {
3018 int z_old;
3019 Slope tileh_old = GetTileSlope(tile, &z_old);
3020 if (IsPlainRail(tile)) {
3021 TrackBits rail_bits = GetTrackBits(tile);
3022 /* Is there flat water on the lower halftile that must be cleared expensively? */
3023 bool was_water = (GetRailGroundType(tile) == RAIL_GROUND_WATER && IsSlopeWithOneCornerRaised(tileh_old));
3024
3025 /* Allow clearing the water only if there is no ship */
3026 if (was_water && HasVehicleOnPos(tile, NULL, &EnsureNoShipProc)) return_cmd_error(STR_ERROR_SHIP_IN_THE_WAY);
3027
3028 /* First test autoslope. However if it succeeds we still have to test the rest, because non-autoslope terraforming is cheaper. */
3029 CommandCost autoslope_result = TestAutoslopeOnRailTile(tile, flags, z_old, tileh_old, z_new, tileh_new, rail_bits);
3030
3031 /* When there is only a single horizontal/vertical track, one corner can be terraformed. */
3032 Corner allowed_corner;
3033 switch (rail_bits) {
3034 case TRACK_BIT_RIGHT: allowed_corner = CORNER_W; break;
3035 case TRACK_BIT_UPPER: allowed_corner = CORNER_S; break;
3036 case TRACK_BIT_LEFT: allowed_corner = CORNER_E; break;
3037 case TRACK_BIT_LOWER: allowed_corner = CORNER_N; break;
3038 default: return autoslope_result;
3039 }
3040
3041 Foundation f_old = GetRailFoundation(tileh_old, rail_bits);
3042
3043 /* Do not allow terraforming if allowed_corner is part of anti-zig-zag foundations */
3044 if (tileh_old != SLOPE_NS && tileh_old != SLOPE_EW && IsSpecialRailFoundation(f_old)) return autoslope_result;
3045
3046 /* Everything is valid, which only changes allowed_corner */
3047 for (Corner corner = (Corner)0; corner < CORNER_END; corner = (Corner)(corner + 1)) {
3048 if (allowed_corner == corner) continue;
3049 if (z_old + GetSlopeZInCorner(tileh_old, corner) != z_new + GetSlopeZInCorner(tileh_new, corner)) return autoslope_result;
3050 }
3051
3052 /* Make the ground dirty */
3053 if ((flags & DC_EXEC) != 0) SetRailGroundType(tile, RAIL_GROUND_BARREN);
3054
3055 /* allow terraforming */
3056 return CommandCost(EXPENSES_CONSTRUCTION, was_water ? _price[PR_CLEAR_WATER] : (Money)0);
3057 } else if (_settings_game.construction.build_on_slopes && AutoslopeEnabled() &&
3058 AutoslopeCheckForEntranceEdge(tile, z_new, tileh_new, GetRailDepotDirection(tile))) {
3059 return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
3060 }
3061 return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
3062 }
3063
3064
3065 extern const TileTypeProcs _tile_type_rail_procs = {
3066 DrawTile_Track, // draw_tile_proc
3067 GetSlopePixelZ_Track, // get_slope_z_proc
3068 ClearTile_Track, // clear_tile_proc
3069 NULL, // add_accepted_cargo_proc
3070 GetTileDesc_Track, // get_tile_desc_proc
3071 GetTileTrackStatus_Track, // get_tile_track_status_proc
3072 ClickTile_Track, // click_tile_proc
3073 NULL, // animate_tile_proc
3074 TileLoop_Track, // tile_loop_proc
3075 ChangeTileOwner_Track, // change_tile_owner_proc
3076 NULL, // add_produced_cargo_proc
3077 VehicleEnter_Track, // vehicle_enter_tile_proc
3078 GetFoundation_Track, // get_foundation_proc
3079 TerraformTile_Track, // terraform_tile_proc
3080 };
VehicleSettings::disable_elrails
bool disable_elrails
when true, the elrails are disabled
Definition: settings_type.h:454
RAILTYPE_END
Used for iterations.
Definition: rail_type.h:35
strings_func.h
Functions related to OTTD&#39;s strings.
GetTileType
static TileType GetTileType(TileIndex tile)
Get the tiletype of a given tile.
Definition: tile_map.h:89
RTO_SLOPE_NW
Piece of rail on slope with north-west raised.
Definition: rail.h:69
DC_AUTO
don&#39;t allow building on structures
Definition: command_type.h:343
IsHalftileSlope
static bool IsHalftileSlope(Slope s)
Checks for non-continuous slope on halftile foundations.
Definition: slope_func.h:49
HasVehicleOnPos
bool HasVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
Checks whether a vehicle is on a specific location.
Definition: vehicle.cpp:512
ApplyFoundationToSlope
uint ApplyFoundationToSlope(Foundation f, Slope *s)
Applies a foundation to a slope.
Definition: landscape.cpp:99
GameSettings::vehicle
VehicleSettings vehicle
options for vehicles
Definition: settings_type.h:552
HasPowerOnRail
static bool HasPowerOnRail(RailType enginetype, RailType tiletype)
Checks if an engine of the given RailType got power on a tile with a given RailType.
Definition: rail.h:324
newgrf_debug.h
Functions/types related to NewGRF debugging.
InitRailTypes
void InitRailTypes()
Resolve sprites of custom rail types.
Definition: rail_cmd.cpp:138
RAIL_GROUND_FENCE_HORIZ2
Grass with a fence at the northern side.
Definition: rail_map.h:498
EnsureNoTrainOnTrackBits
CommandCost EnsureNoTrainOnTrackBits(TileIndex tile, TrackBits track_bits)
Tests if a vehicle interacts with the specified track bits.
Definition: vehicle.cpp:600
SLOPE_N
the north corner of the tile is raised
Definition: slope_type.h:55
PaletteID
uint32 PaletteID
The number of the palette.
Definition: gfx_type.h:20
Corner
Corner
Enumeration of tile corners.
Definition: slope_type.h:24
CmdRemoveSignalTrack
CommandCost CmdRemoveSignalTrack(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Remove signals on a stretch of track.
Definition: rail_cmd.cpp:1520
HasSignalOnTrackdir
static bool HasSignalOnTrackdir(TileIndex tile, Trackdir trackdir)
Checks for the presence of signals along the given trackdir on the given rail tile.
Definition: rail_map.h:427
VS_STOPPED
Vehicle is stopped by the player.
Definition: vehicle_base.h:33
AddTrackToSignalBuffer
void AddTrackToSignalBuffer(TileIndex tile, Track track, Owner owner)
Add track to signal update buffer.
Definition: signal.cpp:582
RailtypeInfo::base_sprites
struct RailtypeInfo::@36 base_sprites
Struct containing the main sprites.
_settings_game
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition: settings.cpp:77
company_base.h
Definition of stuff that is very close to a company, like the company struct itself.
Train::CalcNextVehicleOffset
int CalcNextVehicleOffset() const
Calculate the offset from this vehicle&#39;s center to the following center taking the vehicle lengths in...
Definition: train.h:170
DrawTrackFence
static void DrawTrackFence(const TileInfo *ti, SpriteID base_image, uint num_sprites, RailFenceOffset rfo)
Draw a track fence.
Definition: rail_cmd.cpp:1943
newgrf_railtype.h
NewGRF handling of rail types.
GetRailTypeInfo
static const RailtypeInfo * GetRailTypeInfo(RailType railtype)
Returns a pointer to the Railtype information for a given railtype.
Definition: rail.h:296
GetTropicZone
static TropicZone GetTropicZone(TileIndex tile)
Get the tropic zone.
Definition: tile_map.h:231
GetTunnelBridgeTransportType
static TransportType GetTunnelBridgeTransportType(TileIndex t)
Tunnel: Get the transport type of the tunnel (road or rail) Bridge: Get the transport type of the bri...
Definition: tunnelbridge_map.h:41
RailTypes
RailTypes
The different roadtypes we support, but then a bitmask of them.
Definition: rail_type.h:52
RAIL_TILE_DEPOT
Depot (one entrance)
Definition: rail_map.h:27
GetSaveSlopeZ
static uint GetSaveSlopeZ(uint x, uint y, Track track)
Get surface height in point (x,y) On tiles with halftile foundations move (x,y) to a safe point wrt...
Definition: rail_cmd.cpp:1851
SetTileOwner
static void SetTileOwner(TileIndex tile, Owner owner)
Sets the owner of a tile.
Definition: tile_map.h:191
TileInfo
Tile information, used while rendering the tile.
Definition: tile_cmd.h:44
SLOPE_SE
south and east corner are raised
Definition: slope_type.h:59
RFO_SLOPE_NW_NE
Slope NW, Track Y, Fence NE.
Definition: rail.h:99
RailConvertCost
static Money RailConvertCost(RailType from, RailType to)
Calculates the cost of rail conversion.
Definition: rail.h:372
RailtypeInfo::single_sloped
SpriteID single_sloped
single piece of rail for slopes
Definition: rail.h:132
RAIL_GROUND_FENCE_NESW
Grass with a fence at the NE and SW edges.
Definition: rail_map.h:494
_valid_tracks_without_foundation
static const TrackBits _valid_tracks_without_foundation[15]
Valid TrackBits on a specific (non-steep)-slope without foundation.
Definition: rail_cmd.cpp:278
SLOPE_W
the west corner of the tile is raised
Definition: slope_type.h:52
SIGTYPE_EXIT
presignal block exit
Definition: signal_type.h:28
TileLoop_Water
void TileLoop_Water(TileIndex tile)
Let a water tile floods its diagonal adjoining tiles called from tunnelbridge_cmd, and by TileLoop_Industry() and TileLoop_Track()
Definition: water_cmd.cpp:1153
GameCreationSettings::landscape
byte landscape
the landscape we&#39;re currently in
Definition: settings_type.h:288
SignalType
SignalType
Type of signal, i.e.
Definition: signal_type.h:25
RailtypeInfo::auto_rail
SpriteID auto_rail
button for the autorail construction
Definition: rail.h:146
Vehicle::direction
DirectionByte direction
facing
Definition: vehicle_base.h:271
TO_BUILDINGS
company buildings - depots, stations, HQ, ...
Definition: transparency.h:29
RailType
RailType
Enumeration for all possible railtypes.
Definition: rail_type.h:29
TRACK_BIT_3WAY_SW
"Arrow" to the south-west
Definition: track_type.h:54
TROPICZONE_DESERT
Tile is desert.
Definition: tile_type.h:73
LEVELCROSSING_TRACKBIT_FACTOR
static const uint LEVELCROSSING_TRACKBIT_FACTOR
Multiplier for how many regular track bits a level crossing counts.
Definition: economy_type.h:216
RFO_FLAT_Y_NE
Slope FLAT, Track Y, Fence NE.
Definition: rail.h:93
_original_railtypes
static const RailtypeInfo _original_railtypes[]
Global Railtype definition.
Definition: railtypes.h:21
SIGTYPE_ENTRY
presignal block entry
Definition: signal_type.h:27
MarkBridgeDirty
void MarkBridgeDirty(TileIndex begin, TileIndex end, DiagDirection direction, uint bridge_height)
Mark bridge tiles dirty.
Definition: tunnelbridge_cmd.cpp:64
MP_INDUSTRY
Part of an industry.
Definition: tile_type.h:51
_display_opt
byte _display_opt
What do we want to draw/do?
Definition: transparency_gui.cpp:28
_fence_offsets
static FenceOffset _fence_offsets[]
Offsets for drawing fences.
Definition: rail_cmd.cpp:1917
GetPartialPixelZ
uint GetPartialPixelZ(int x, int y, Slope corners)
Determines height at given coordinate of a slope.
Definition: landscape.cpp:152
EnsureNoVehicleOnGround
CommandCost EnsureNoVehicleOnGround(TileIndex tile)
Ensure there is no vehicle at the ground at the given position.
Definition: vehicle.cpp:538
INVALID_DIAGDIR
Flag for an invalid DiagDirection.
Definition: direction_type.h:87
CmdBuildSignalTrack
CommandCost CmdBuildSignalTrack(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Build signals on a stretch of track.
Definition: rail_cmd.cpp:1428
Pool::PoolItem<&_company_pool >::Get
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:246
GetHalftileFoundationCorner
static Corner GetHalftileFoundationCorner(Foundation f)
Returns the halftile corner of a halftile-foundation.
Definition: slope_func.h:335
date_func.h
Functions related to dates.
IsInsideMM
static bool IsInsideMM(const T x, const uint min, const uint max)
Checks if a value is in an interval.
Definition: math_func.hpp:266
RailtypeInfo::build_y_rail
SpriteID build_y_rail
button for building single rail in Y direction
Definition: rail.h:145
VehicleEnter_Track
static VehicleEnterTileStatus VehicleEnter_Track(Vehicle *u, TileIndex tile, int x, int y)
Tile callback routine when vehicle enters tile.
Definition: rail_cmd.cpp:2909
ToggleBit
static T ToggleBit(T &x, const uint8 y)
Toggles a bit in a variable.
Definition: bitmath_func.hpp:183
TrackdirToTrack
static Track TrackdirToTrack(Trackdir trackdir)
Returns the Track that a given Trackdir represents.
Definition: track_func.h:272
CmdBuildSingleSignal
CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Build signals, alternate between double/single, signal/semaphore, pre/exit/combo-signals, and what-else not.
Definition: rail_cmd.cpp:1032
ROADTYPE_ROAD
Basic road type.
Definition: road_type.h:24
RTO_S
Piece of rail in southern corner.
Definition: rail.h:63
TileType
TileType
The different types of tiles.
Definition: tile_type.h:42
DrawTrackFence_SE
static void DrawTrackFence_SE(const TileInfo *ti, SpriteID base_image, uint num_sprites)
Draw fence at SE border matching the tile slope.
Definition: rail_cmd.cpp:1970
train.h
Base for the train class.
HasSignalOnTrack
static bool HasSignalOnTrack(TileIndex tile, Track track)
Checks for the presence of signals (either way) on the given track on the given rail tile...
Definition: rail_map.h:414
SetBit
static T SetBit(T &x, const uint8 y)
Set a bit in a variable.
Definition: bitmath_func.hpp:123
FenceOffset
Offsets for drawing fences.
Definition: rail_cmd.cpp:1908
MakeShore
static void MakeShore(TileIndex t)
Helper function to make a coast tile.
Definition: water_map.h:354
SLOPE_NS
north and south corner are raised
Definition: slope_type.h:62
Track
Track
These are used to specify a single track.
Definition: track_type.h:21
GetCrossingRailBits
static TrackBits GetCrossingRailBits(TileIndex tile)
Get the rail track bits of a level crossing.
Definition: road_map.h:338
Vehicle::cur_speed
uint16 cur_speed
current speed
Definition: vehicle_base.h:293
MP_ROAD
A tile with road (or tram tracks)
Definition: tile_type.h:45
CMD_ERROR
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
Definition: command_func.h:25
RTO_JUNCTION_NE
Ballast for junction &#39;pointing&#39; NE.
Definition: rail.h:72
FenceOffset::y_offs
int y_offs
Bounding box Y offset.
Definition: rail_cmd.cpp:1911
WC_VEHICLE_DEPOT
Depot view; Window numbers:
Definition: window_type.h:346
TileInfo::tileh
Slope tileh
Slope of the tile.
Definition: tile_cmd.h:47
FloodHalftile
bool FloodHalftile(TileIndex t)
Called from water_cmd if a non-flat rail-tile gets flooded and should be converted to shore...
Definition: rail_cmd.cpp:749
ROAD_X
Full road along the x-axis (south-west + north-east)
Definition: road_type.h:61
_valid_tracks_on_leveled_foundation
static const TrackBits _valid_tracks_on_leveled_foundation[15]
Valid TrackBits on a specific (non-steep)-slope with leveled foundation.
Definition: rail_cmd.cpp:300
TRACKDIR_BIT_RIGHT_S
Track right, direction south.
Definition: track_type.h:113
RTO_JUNCTION_NW
Ballast for junction &#39;pointing&#39; NW.
Definition: rail.h:74
SignalState
SignalState
These are states in which a signal can be.
Definition: signal_type.h:46
CmdBuildSingleRail
CommandCost CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Build a single piece of rail.
Definition: rail_cmd.cpp:442
ValParamRailtype
bool ValParamRailtype(const RailType rail)
Validate functions for rail building.
Definition: rail.cpp:198
RAIL_GROUND_FENCE_VERT1
Grass with a fence at the eastern side.
Definition: rail_map.h:495
RTO_SLOPE_NE
Piece of rail on slope with north-east raised.
Definition: rail.h:66
IsOnewaySignal
static bool IsOnewaySignal(TileIndex t, Track track)
One-way signals can&#39;t be passed the &#39;wrong&#39; way.
Definition: rail_map.h:320
TRANSPORT_WATER
Transport over water.
Definition: transport_type.h:31
TrainList
SmallVector< Train *, 16 > TrainList
Helper type for lists/vectors of trains.
Definition: rail_cmd.cpp:44
HalftileFoundation
static Foundation HalftileFoundation(Corner corner)
Returns the halftile foundation for single horizontal/vertical track.
Definition: slope_func.h:393
IsValidCorner
static bool IsValidCorner(Corner corner)
Rangecheck for Corner enumeration.
Definition: slope_func.h:26
vehicle_func.h
Functions related to vehicles.
DiagDirToDiagTrackBits
static TrackBits DiagDirToDiagTrackBits(DiagDirection diagdir)
Maps a (4-way) direction to the diagonal track bits incidating with that diagdir. ...
Definition: track_func.h:512
AddSideToSignalBuffer
void AddSideToSignalBuffer(TileIndex tile, DiagDirection side, Owner owner)
Add side of tile to signal update buffer.
Definition: signal.cpp:614
RTO_W
Piece of rail in western corner.
Definition: rail.h:65
RailtypeInfo::single_e
SpriteID single_e
single piece of rail in the eastern corner
Definition: rail.h:130
TileX
static uint TileX(TileIndex tile)
Get the X component of a tile.
Definition: map_func.h:207
VehicleEnterDepot
void VehicleEnterDepot(Vehicle *v)
Vehicle entirely entered the depot, update its status, orders, vehicle windows, service it...
Definition: vehicle.cpp:1426
RTSG_FENCES
Fence images.
Definition: rail.h:49
GameSettings::pf
PathfinderSettings pf
settings for all pathfinders
Definition: settings_type.h:550
WC_BUILD_VEHICLE
Build vehicle; Window numbers:
Definition: window_type.h:378
CmdRemoveRailroadTrack
CommandCost CmdRemoveRailroadTrack(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Build rail on a stretch of track.
Definition: rail_cmd.cpp:943
TileAddByDiagDir
static TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir)
Adds a DiagDir to a tile.
Definition: map_func.h:372
Vehicle
Vehicle data structure.
Definition: vehicle_base.h:212
depot_base.h
Base for all depots (except hangars)
SmallVector::Clear
void Clear()
Remove all items from the list.
Definition: smallvec_type.hpp:98
SmallVector::Begin
const T * Begin() const
Get the pointer to the first item (const)
Definition: smallvec_type.hpp:272
TileDesc
Tile description for the &#39;land area information&#39; tool.
Definition: tile_cmd.h:53
CMD_LANDSCAPE_CLEAR
demolish a tile
Definition: command_type.h:182
CheckTileOwnership
CommandCost CheckTileOwnership(TileIndex tile)
Check whether the current owner owns the stuff on the given tile.
Definition: company_cmd.cpp:328
RailtypeInfo::alternate_labels
RailTypeLabelList alternate_labels
Rail type labels this type provides in addition to the main label.
Definition: rail.h:230
Pool::PoolItem::index
Tindex index
Index of this pool item.
Definition: pool_type.hpp:147
SLOPE_E
the east corner of the tile is raised
Definition: slope_type.h:54
GetRoadBits
static RoadBits GetRoadBits(TileIndex t, RoadType rt)
Get the present road bits for a specific road type.
Definition: road_map.h:111
CompareRailTypes
static int CDECL CompareRailTypes(const RailType *first, const RailType *second)
Compare railtypes based on their sorting order.
Definition: rail_cmd.cpp:130
RAIL_GROUND_ICE_DESERT
Icy or sandy.
Definition: rail_map.h:499
DIAGDIR_NE
Northeast, upper right on your monitor.
Definition: direction_type.h:82
IsSteepSlope
static bool IsSteepSlope(Slope s)
Checks if a slope is steep.
Definition: slope_func.h:38
SpecializedVehicle::First
T * First() const
Get the first vehicle in the chain.
Definition: vehicle_base.h:1010
DO_FULL_DETAIL
Also draw details of track and roads.
Definition: openttd.h:47
TRACK_LEFT
Track in the left corner of the tile (west)
Definition: track_type.h:27
RFO_FLAT_LOWER
Slope FLAT, Track LOWER, Fence N.
Definition: rail.h:103
cmd_helper.h
Helper functions to extract data from command parameters.
ResetRailTypes
void ResetRailTypes()
Reset all rail type information to its default values.
Definition: rail_cmd.cpp:65
RailtypeInfo::cursor
struct RailtypeInfo::@38 cursor
Cursors associated with the rail type.
PathfinderSettings::forbid_90_deg
bool forbid_90_deg
forbid trains to make 90 deg turns
Definition: settings_type.h:421
RAIL_GROUND_FENCE_SW
Grass with a fence at the SW edge.
Definition: rail_map.h:493
DiagDirToDiagTrack
static Track DiagDirToDiagTrack(DiagDirection diagdir)
Maps a (4-way) direction to the diagonal track incidating with that diagdir.
Definition: track_func.h:500
RAIL_GROUND_BARREN
Nothing (dirt)
Definition: rail_map.h:487
SmallVector
Simple vector template class.
Definition: smallvec_type.hpp:29
GetHalftileSlopeCorner
static Corner GetHalftileSlopeCorner(Slope s)
Returns the leveled halftile of a halftile slope.
Definition: slope_func.h:150
MP_RAILWAY
A railway.
Definition: tile_type.h:44
GetRailStationTrack
static Track GetRailStationTrack(TileIndex t)
Get the rail track of a rail station tile.
Definition: station_map.h:350
CommandCost::GetCost
Money GetCost() const
The costs as made up to this moment.
Definition: command_type.h:84
RailtypeInfo::compatible_railtypes
RailTypes compatible_railtypes
bitmask to the OTHER railtypes on which an engine of THIS railtype can physically travel ...
Definition: rail.h:180
MP_OBJECT
Contains objects such as transmitters and owned land.
Definition: tile_type.h:53
DrawTrackFence_NW
static void DrawTrackFence_NW(const TileInfo *ti, SpriteID base_image, uint num_sprites)
Draw fence at NW border matching the tile slope.
Definition: rail_cmd.cpp:1960
RAILTYPE_RAIL
Standard non-electric rails.
Definition: rail_type.h:31
TCX_NORMAL
Nothing special.
Definition: newgrf_commons.h:27
SetHasSignals
static void SetHasSignals(TileIndex tile, bool signals)
Add/remove the &#39;has signal&#39; bit from the RailTileType.
Definition: rail_map.h:84
SLOPE_SW
south and west corner are raised
Definition: slope_type.h:58
SetTrackBits
static void SetTrackBits(TileIndex t, TrackBits b)
Sets the track bits of the given tile.
Definition: rail_map.h:148
RFO_FLAT_LEFT
Slope FLAT, Track LEFT, Fence E.
Definition: rail.h:94
DrawTrackDetails
static void DrawTrackDetails(const TileInfo *ti, const RailtypeInfo *rti)
Draw track fences.
Definition: rail_cmd.cpp:2002
CommandCost
Common return value for all commands.
Definition: command_type.h:25
DIAGDIR_BEGIN
Used for iterations.
Definition: direction_type.h:81
HasExactlyOneBit
static bool HasExactlyOneBit(T value)
Test whether value has exactly 1 bit set.
Definition: bitmath_func.hpp:276
RailtypeInfo::autorail
CursorID autorail
Cursor for autorail tool.
Definition: rail.h:158
SlopeWithOneCornerRaised
static Slope SlopeWithOneCornerRaised(Corner corner)
Returns the slope with a specific corner raised.
Definition: slope_func.h:101
AllocateRailType
RailType AllocateRailType(RailTypeLabel label)
Allocate a new rail type label.
Definition: rail_cmd.cpp:157
IsLevelCrossing
static bool IsLevelCrossing(TileIndex t)
Return whether a tile is a level crossing.
Definition: road_map.h:68
RailNoLevelCrossings
static bool RailNoLevelCrossings(RailType rt)
Test if a RailType disallows build of level crossings.
Definition: rail.h:334
GetSignalStates
static uint GetSignalStates(TileIndex tile)
Set the states of the signals (Along/AgainstTrackDir)
Definition: rail_map.h:363
Vehicle::vehstatus
byte vehstatus
Status.
Definition: vehicle_base.h:317
TrackdirToExitdir
static DiagDirection TrackdirToExitdir(Trackdir trackdir)
Maps a trackdir to the (4-way) direction the tile is exited when following that trackdir.
Definition: track_func.h:427
RailtypeInfo::strings
struct RailtypeInfo::@39 strings
Strings associated with the rail type.
SpecializedVehicle< Train, Type >::From
static Train * From(Vehicle *v)
Converts a Vehicle to SpecializedVehicle with type checking.
Definition: vehicle_base.h:1113
RailtypeInfo::track_y
SpriteID track_y
single piece of rail in Y direction, with ground
Definition: rail.h:123
TestAutoslopeOnRailTile
static CommandCost TestAutoslopeOnRailTile(TileIndex tile, uint flags, int z_old, Slope tileh_old, int z_new, Slope tileh_new, TrackBits rail_bits)
Tests if autoslope is allowed.
Definition: rail_cmd.cpp:2969
SmallVector::End
const T * End() const
Get the pointer behind the last valid item (const)
Definition: smallvec_type.hpp:292
SLOPE_FLAT
a flat tile
Definition: slope_type.h:51
TileDesc::rail_speed
uint16 rail_speed
Speed limit of rail (bridges and track)
Definition: tile_cmd.h:66
TileInfo::z
int z
Height.
Definition: tile_cmd.h:49
TILE_SIZE
static const uint TILE_SIZE
Tile size in world coordinates.
Definition: tile_type.h:15
DrawFoundation
void DrawFoundation(TileInfo *ti, Foundation f)
Draw foundation f at tile ti.
Definition: landscape.cpp:390
CommandCost::AddCost
void AddCost(const Money &cost)
Adds the given cost to the cost of the command.
Definition: command_type.h:64
TileDesc::owner
Owner owner[4]
Name of the owner(s)
Definition: tile_cmd.h:55
GetHighestSlopeCorner
static Corner GetHighestSlopeCorner(Slope s)
Returns the highest corner of a slope (one corner raised or a steep slope).
Definition: slope_func.h:128
SB
static T SB(T &x, const uint8 s, const uint8 n, const U d)
Set n bits in x starting at bit s to d.
Definition: bitmath_func.hpp:60
RailtypeInfo::rail_ew
CursorID rail_ew
Cursor for building rail in E-W direction.
Definition: rail.h:156
RAIL_GROUND_FENCE_SENW
Grass with a fence at the NW and SE edges.
Definition: rail_map.h:491
CornerToTrackBits
static TrackBits CornerToTrackBits(Corner corner)
Returns a single horizontal/vertical trackbit that is in a specific tile corner.
Definition: track_func.h:109
CommandCost::MakeError
void MakeError(StringID message)
Makes this CommandCost behave like an error command.
Definition: command_type.h:102
TRACK_BIT_3WAY_NW
"Arrow" to the north-west
Definition: track_type.h:55
IsObjectType
static bool IsObjectType(TileIndex t, ObjectType type)
Check whether the object on a tile is of a specific type.
Definition: object_map.h:27
YapfNotifyTrackLayoutChange
void YapfNotifyTrackLayoutChange(TileIndex tile, Track track)
Use this function to notify YAPF that track layout (or signal configuration) has change.
Definition: yapf_rail.cpp:642
SLOPE_NE
north and east corner are raised
Definition: slope_type.h:60
RailtypeInfo
This struct contains all the info that is needed to draw and construct tracks.
Definition: rail.h:116
HasRoadWorks
static bool HasRoadWorks(TileIndex t)
Check if a tile has road works.
Definition: road_map.h:482
SmallVector::Append
T * Append(uint to_add=1)
Append an item and return it.
Definition: smallvec_type.hpp:134
Depot::build_date
Date build_date
Date of construction.
Definition: depot_base.h:27
Backup
Class to backup a specific variable and restore it later.
Definition: backup_type.hpp:23
SignalOnTrack
static byte SignalOnTrack(Track track)
Maps a Track to the bits that store the status of the two signals that can be present on the given tr...
Definition: signal_func.h:44
TRACKDIR_BIT_UPPER_E
Track upper, direction east.
Definition: track_type.h:110
_local_company
CompanyByte _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition: company_cmd.cpp:46
DC_BANKRUPT
company bankrupts, skip money check, skip vehicle on tile check in some cases
Definition: command_type.h:348
viewport_func.h
Functions related to (drawing on) viewports.
RAIL_TILE_SIGNALS
Normal rail tile with signals.
Definition: rail_map.h:26
RailtypeInfo::signals
SpriteID signals[SIGTYPE_END][2][2]
signal GUI sprites (type, variant, state)
Definition: rail.h:150
HasStationRail
static bool HasStationRail(TileIndex t)
Has this station tile a rail? In other words, is this station tile a rail station or rail waypoint...
Definition: station_map.h:136
TRACK_BIT_RIGHT
Right track.
Definition: track_type.h:48
SpecialRailFoundation
static Foundation SpecialRailFoundation(Corner corner)
Returns the special rail foundation for single horizontal/vertical track.
Definition: slope_func.h:405
TileIndexDiffC::y
int16 y
The y value of the coordinate.
Definition: map_type.h:60
RailFenceOffset
RailFenceOffset
Offsets from base sprite for fence sprites.
Definition: rail.h:91
GetTileSlope
Slope GetTileSlope(TileIndex tile, int *h)
Return the slope of a given tile inside the map.
Definition: tile_map.cpp:115
TrackBitsToTrack
static Track TrackBitsToTrack(TrackBits tracks)
Converts TrackBits to Track.
Definition: track_func.h:203
GetPresentSignals
static uint GetPresentSignals(TileIndex tile)
Get whether the given signals are present (Along/AgainstTrackDir)
Definition: rail_map.h:394
IsValidTile
static bool IsValidTile(TileIndex tile)
Checks if a tile is valid.
Definition: tile_map.h:154
TRACKDIR_BIT_RIGHT_N
Track right, direction north.
Definition: track_type.h:120
RailtypeInfo::single_y
SpriteID single_y
single piece of rail in Y direction, without ground
Definition: rail.h:127
CMD_BUILD_SINGLE_RAIL
build a single rail track
Definition: command_type.h:180
IsBridgeAbove
static bool IsBridgeAbove(TileIndex t)
checks if a bridge is set above the ground of this tile
Definition: bridge_map.h:45
RAIL_GROUND_HALF_SNOW
Snow only on higher part of slope (steep or one corner raised)
Definition: rail_map.h:501
TrackBits
TrackBits
Bitfield corresponding to Track.
Definition: track_type.h:41
TRACKDIR_BIT_X_NE
Track x-axis, direction north-east.
Definition: track_type.h:108
IsTileOwner
static bool IsTileOwner(TileIndex tile, Owner owner)
Checks if a tile belongs to the given owner.
Definition: tile_map.h:207
TRACK_BIT_VERT
Left and right track.
Definition: track_type.h:51
DrawRailTileSeqInGUI
static void DrawRailTileSeqInGUI(int x, int y, const DrawTileSprites *dts, int32 total_offset, uint32 newgrf_offset, PaletteID default_palette)
Draw tile sprite sequence in GUI with railroad specifics.
Definition: sprite.h:101
FLOOD_NONE
The tile does not flood neighboured tiles.
Definition: water.h:22
ComplementSlope
static Slope ComplementSlope(Slope s)
Return the complement of a slope.
Definition: slope_func.h:78
GetCustomRailSprite
SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg, TileContext context, uint *num_results)
Get the sprite to draw for the given tile.
Definition: newgrf_railtype.cpp:94
TileInfo::x
uint x
X position of the tile in unit coordinates.
Definition: tile_cmd.h:45
CmdSignalTrackHelper
static CommandCost CmdSignalTrackHelper(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Build many signals by dragging; AutoSignals.
Definition: rail_cmd.cpp:1258
DRD_NONE
None of the directions are disallowed.
Definition: road_map.h:256
TileOffsByDiagDir
static TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition: map_func.h:343
TCX_UPPER_HALFTILE
Querying information about the upper part of a tile with halftile foundation.
Definition: newgrf_commons.h:28
Foundation
Foundation
Enumeration for Foundations.
Definition: slope_type.h:95
RailtypeInfo::ground
SpriteID ground
ground sprite for a 3-way switch
Definition: rail.h:125
IsTileType
static bool IsTileType(TileIndex tile, TileType type)
Checks if a tile is a give tiletype.
Definition: tile_map.h:143
railtypes.h
All the railtype-specific information is stored here.
TRACK_BIT_ALL
All possible tracks.
Definition: track_type.h:56
MakeDefaultName
void MakeDefaultName(T *obj)
Set the default name for a depot/waypoint.
Definition: town.h:229
DiagonalTileIterator
Iterator to iterate over a diagonal area of the map.
Definition: tilearea_type.h:188
TileInfo::tile
TileIndex tile
Tile index.
Definition: tile_cmd.h:48
ApplyPixelFoundationToSlope
static uint ApplyPixelFoundationToSlope(Foundation f, Slope *s)
Applies a foundation to a slope.
Definition: landscape.h:127
TRACK_Y
Track along the y-axis (north-west to south-east)
Definition: track_type.h:24
DoCommand
CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags)
Shorthand for calling the long DoCommand with a container.
Definition: command.cpp:436
AXIS_Y
The y axis.
Definition: direction_type.h:129
SmallVector::Length
uint Length() const
Get the number of items in the list.
Definition: smallvec_type.hpp:262
GetRoadOwner
static Owner GetRoadOwner(TileIndex t, RoadType rt)
Get the owner of a specific road type.
Definition: road_map.h:199
FOUNDATION_LEVELED
The tile is leveled up to a flat slope.
Definition: slope_type.h:97
ConstructionSettings::train_signal_side
byte train_signal_side
show signals on left / driving / right side
Definition: settings_type.h:306
TRACKDIR_BIT_UPPER_W
Track upper, direction west.
Definition: track_type.h:117
FOUNDATION_HALFTILE_N
Level north halftile non-continuously.
Definition: slope_type.h:107
TRACKDIR_BIT_LOWER_W
Track lower, direction west.
Definition: track_type.h:118
IsValidTrack
static bool IsValidTrack(Track track)
Checks if a Track is valid.
Definition: track_func.h:38
IsRailStationTile
static bool IsRailStationTile(TileIndex t)
Is this tile a station tile and a rail station?
Definition: station_map.h:103
tunnelbridge.h
Header file for things common for tunnels and bridges.
TRACK_BIT_X
X-axis track.
Definition: track_type.h:43
DrawTileSprites
Ground palette sprite of a tile, together with its sprite layout.
Definition: sprite.h:60
FIND_FIRST_BIT
#define FIND_FIRST_BIT(x)
Returns the first non-zero bit in a 6-bit value (from right).
Definition: bitmath_func.hpp:202
FenceOffset::height_ref
Corner height_ref
Corner to use height offset from.
Definition: rail_cmd.cpp:1909
DirtyCompanyInfrastructureWindows
void DirtyCompanyInfrastructureWindows(CompanyID company)
Redraw all windows with company infrastructure counts.
Definition: company_gui.cpp:2473
GetFloodingBehaviour
FloodingBehaviour GetFloodingBehaviour(TileIndex tile)
Returns the behaviour of a tile during flooding.
Definition: water_cmd.cpp:1005
VehicleSettings::road_side
byte road_side
the side of the road vehicles drive on
Definition: settings_type.h:464
RTSG_OVERLAY
Images for overlaying track.
Definition: rail.h:41
GetTownIndex
static TownID GetTownIndex(TileIndex t)
Get the index of which town this house/street is attached to.
Definition: town_map.h:24
RFO_SLOPE_SE_SW
Slope SE, Track Y, Fence SW.
Definition: rail.h:105
yapf_cache.h
Entry point for OpenTTD to YAPF&#39;s cache.
CmdConvertRail
CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Convert one rail type to the other.
Definition: rail_cmd.cpp:1548
CommandCost::GetErrorMessage
StringID GetErrorMessage() const
Returns the error message of a command.
Definition: command_type.h:142
Order::IsType
bool IsType(OrderType type) const
Check whether this order is of the given type.
Definition: order_base.h:63
RAIL_GROUND_FENCE_NW
Grass with a fence at the NW edge.
Definition: rail_map.h:489
TunnelBridgeIsFree
CommandCost TunnelBridgeIsFree(TileIndex tile, TileIndex endtile, const Vehicle *ignore)
Finds vehicle in tunnel / bridge.
Definition: vehicle.cpp:567
GetTileOwner
static Owner GetTileOwner(TileIndex tile)
Returns the owner of a tile.
Definition: tile_map.h:171
RFO_FLAT_UPPER
Slope FLAT, Track UPPER, Fence S.
Definition: rail.h:95
GetRailDepotDirection
static DiagDirection GetRailDepotDirection(TileIndex t)
Returns the direction the depot is facing to.
Definition: rail_map.h:172
ReverseDiagDir
static DiagDirection ReverseDiagDir(DiagDirection d)
Returns the reverse direction of the given DiagDirection.
Definition: direction_func.h:120
TRACK_RIGHT
Track in the right corner of the tile (east)
Definition: track_type.h:28
DoCommandFlag
DoCommandFlag
List of flags for a command.
Definition: command_type.h:340
GetTunnelBridgeLength
static uint GetTunnelBridgeLength(TileIndex begin, TileIndex end)
Calculates the length of a tunnel or a bridge (without end tiles)
Definition: tunnelbridge.h:26
DIAGDIR_SE
Southeast.
Definition: direction_type.h:83
DIAGDIR_SW
Southwest.
Definition: direction_type.h:84
SpecializedVehicle::Next
T * Next() const
Get next vehicle in the chain.
Definition: vehicle_base.h:1028
RTO_SLOPE_SW
Piece of rail on slope with south-west raised.
Definition: rail.h:68
VETSB_ENTERED_WORMHOLE
The vehicle either entered a bridge, tunnel or depot tile (this includes the last tile of the bridge/...
Definition: tile_cmd.h:38
_settings_client
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:76
RTO_X
Piece of rail in X direction.
Definition: rail.h:60
IsSafeWaitingPosition
bool IsSafeWaitingPosition(const Train *v, TileIndex tile, Trackdir trackdir, bool include_line_end, bool forbid_90deg)
Determine whether a certain track on a tile is a safe position to end a path.
Definition: pbs.cpp:383
VALID_LEVEL_CROSSING_SLOPES
static const uint32 VALID_LEVEL_CROSSING_SLOPES
Constant bitset with safe slopes for building a level crossing.
Definition: slope_type.h:88
CommandCost::Succeeded
bool Succeeded() const
Did this command succeed?
Definition: command_type.h:152
TRACK_BIT_3WAY_NE
"Arrow" to the north-east
Definition: track_type.h:52
stdafx.h
Definition of base types and functions in a cross-platform compatible way.
CmdRemoveSingleSignal
CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Remove signals.
Definition: rail_cmd.cpp:1445
DiagonalTileArea
Represents a diagonal tile area.
Definition: tilearea_type.h:64
GetRailReservationTrackBits
static TrackBits GetRailReservationTrackBits(TileIndex t)
Returns the reserved track bits of the tile.
Definition: rail_map.h:195
CmdRailTrackHelper
static CommandCost CmdRailTrackHelper(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Build or remove a stretch of railroad tracks.
Definition: rail_cmd.cpp:864
object_map.h
Map accessors for object tiles.
BB_HEIGHT_UNDER_BRIDGE
static const uint BB_HEIGHT_UNDER_BRIDGE
Some values for constructing bounding boxes (BB).
Definition: viewport_type.h:74
safeguards.h
A number of safeguards to prevent using unsafe methods.
RailtypeInfo::build_ns_rail
SpriteID build_ns_rail
button for building single rail in N-S direction
Definition: rail.h:142
ROADTYPE_TRAM
Trams.
Definition: road_type.h:25
TileIndexDiffC::x
int16 x
The x value of the coordinate.
Definition: map_type.h:59
TRACK_LOWER
Track in the lower corner of the tile (south)
Definition: track_type.h:26
GroundSpritePaletteTransform
static PaletteID GroundSpritePaletteTransform(SpriteID image, PaletteID pal, PaletteID default_pal)
Applies PALETTE_MODIFIER_COLOUR to a palette entry of a ground sprite.
Definition: sprite.h:170
RailtypeInfo::introduces_railtypes
RailTypes introduces_railtypes
Bitmask of which other railtypes are introduced when this railtype is introduced. ...
Definition: rail.h:255
VETSB_CANNOT_ENTER
The vehicle cannot enter the tile.
Definition: tile_cmd.h:39
MP_WATER
Water tile.
Definition: tile_type.h:49
RemoveFirstTrackdir
static Trackdir RemoveFirstTrackdir(TrackdirBits *trackdirs)
Removes first Trackdir from TrackdirBits and returns it.
Definition: track_func.h:166
TileInfo::y
uint y
Y position of the tile in unit coordinates.
Definition: tile_cmd.h:46
GetRailFoundation
Foundation GetRailFoundation(Slope tileh, TrackBits bits)
Checks if a track combination is valid on a specific slope and returns the needed foundation...
Definition: rail_cmd.cpp:328
RoadBits
RoadBits
Enumeration for the road parts on a tile.
Definition: road_type.h:55
Trackdir
Trackdir
Enumeration for tracks and directions.
Definition: track_type.h:74
RailtypeInfo::sorting_order
byte sorting_order
The sorting order of this railtype for the toolbar dropdown.
Definition: rail.h:260
ShowDepotWindow
void ShowDepotWindow(TileIndex tile, VehicleType type)
Opens a depot window.
Definition: depot_gui.cpp:1092
DIAGDIR_END
Used for iterations.
Definition: direction_type.h:86
RFO_SLOPE_SW_NW
Slope SW, Track X, Fence NW.
Definition: rail.h:96
FOUNDATION_INCLINED_Y
The tile has an along Y-axis inclined foundation.
Definition: slope_type.h:99
GetTilePixelSlope
static Slope GetTilePixelSlope(TileIndex tile, int *h)
Return the slope of a given tile.
Definition: tile_map.h:273
RAIL_GROUND_FENCE_NE
Grass with a fence at the NE edge.
Definition: rail_map.h:492
TILE_HEIGHT
static const uint TILE_HEIGHT
Height of a height level in world coordinate AND in pixels in #ZOOM_LVL_BASE.
Definition: tile_type.h:18
GetTrainForReservation
Train * GetTrainForReservation(TileIndex tile, Track track)
Find the train which has reserved a specific path.
Definition: pbs.cpp:333
ROAD_NONE
No road-part is build.
Definition: road_type.h:56
IsSlopeWithOneCornerRaised
static bool IsSlopeWithOneCornerRaised(Slope s)
Tests if a specific slope has exactly one corner raised.
Definition: slope_func.h:90
OrthogonalTileArea
Represents the covered area of e.g.
Definition: tilearea_type.h:18
company_gui.h
GUI Functions related to companies.
TUNNELBRIDGE_TRACKBIT_FACTOR
static const uint TUNNELBRIDGE_TRACKBIT_FACTOR
Multiplier for how many regular track bits a tunnel/bridge counts.
Definition: economy_type.h:214
pbs.h
PBS support routines.
RAIL_GROUND_GRASS
Grassy.
Definition: rail_map.h:488
SetSignalStates
static void SetSignalStates(TileIndex tile, uint state)
Set the states of the signals (Along/AgainstTrackDir)
Definition: rail_map.h:353
RailtypeInfo::max_speed
uint16 max_speed
Maximum speed for vehicles travelling on this rail type.
Definition: rail.h:220
FindVehicleOnPos
void FindVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
Find a vehicle from a specific location.
Definition: vehicle.cpp:497
RailtypeInfo::single_w
SpriteID single_w
single piece of rail in the western corner
Definition: rail.h:131
Vehicle::tile
TileIndex tile
Current tile index.
Definition: vehicle_base.h:230
GetCustomSignalSprite
SpriteID GetCustomSignalSprite(const RailtypeInfo *rti, TileIndex tile, SignalType type, SignalVariant var, SignalState state, bool gui)
Get the sprite to draw for a given signal.
Definition: newgrf_railtype.cpp:119
CheckOwnership
CommandCost CheckOwnership(Owner owner, TileIndex tile)
Check whether the current owner owns something.
Definition: company_cmd.cpp:310
OBJECT_OWNED_LAND
static const ObjectType OBJECT_OWNED_LAND
Owned land &#39;flag&#39;.
Definition: object_type.h:21
RailtypeInfo::rail_nwse
CursorID rail_nwse
Cursor for building rail in Y direction.
Definition: rail.h:157
SetPresentSignals
static void SetPresentSignals(TileIndex tile, uint signals)
Set whether the given signals are present (Along/AgainstTrackDir)
Definition: rail_map.h:384
RAIL_GROUND_WATER
Grass with a fence and shore or water on the free halftile.
Definition: rail_map.h:500
TileIterator
Base class for tile iterators.
Definition: tilearea_type.h:99
SlopeWithThreeCornersRaised
static Slope SlopeWithThreeCornersRaised(Corner corner)
Returns the slope with all except one corner raised.
Definition: slope_func.h:208
DIAGDIR_NW
Northwest.
Definition: direction_type.h:85
track_land.h
Sprites to use and how to display them for train depot tiles.
RTO_CROSSING_XY
Crossing of X and Y rail, with ballast.
Definition: rail.h:70
RailtypeInfo::single_x
SpriteID single_x
single piece of rail in X direction, without ground
Definition: rail.h:126
RailtypeInfo::convert_rail
SpriteID convert_rail
button for converting rail
Definition: rail.h:149
GetRailDepotTrack
static Track GetRailDepotTrack(TileIndex t)
Returns the track of a depot, ignoring direction.
Definition: rail_map.h:183
DiagDirection
DiagDirection
Enumeration for diagonal directions.
Definition: direction_type.h:80
RailClearCost
static Money RailClearCost(RailType railtype)
Returns the &#39;cost&#39; of clearing the specified railtype.
Definition: rail.h:355
lengthof
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:42
SLOPE_ELEVATED
bit mask containing all &#39;simple&#39; slopes
Definition: slope_type.h:63
DrawTrackFence_NE
static void DrawTrackFence_NE(const TileInfo *ti, SpriteID base_image, uint num_sprites)
Draw fence at NE border matching the tile slope.
Definition: rail_cmd.cpp:1980
RTSG_DEPOT
Depot images.
Definition: rail.h:48
TrackdirReachesTrackdirs
static TrackdirBits TrackdirReachesTrackdirs(Trackdir trackdir)
Maps a trackdir to the trackdirs that can be reached from it (ie, when entering the next tile...
Definition: track_func.h:572
min
static T min(const T a, const T b)
Returns the minimum of two values.
Definition: math_func.hpp:42
FlatteningFoundation
static Foundation FlatteningFoundation(Slope s)
Returns the foundation needed to flatten a slope.
Definition: slope_func.h:371
DrawRailTileSeq
static void DrawRailTileSeq(const struct TileInfo *ti, const DrawTileSprites *dts, TransparencyOption to, int32 total_offset, uint32 newgrf_offset, PaletteID default_palette)
Draw tile sprite sequence on tile with railroad specifics.
Definition: sprite.h:91
TileDesc::railtype
StringID railtype
Type of rail on the tile.
Definition: tile_cmd.h:65
RailtypeInfo::label
RailTypeLabel label
Unique 32 bit rail type identifier.
Definition: rail.h:225
FOUNDATION_STEEP_BOTH
The tile has a steep slope. The lowest corner is raised by a foundation and the upper halftile is lev...
Definition: slope_type.h:103
CmdBuildTrainDepot
CommandCost CmdBuildTrainDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Build a train depot.
Definition: rail_cmd.cpp:960
RTFB_NONE
All flags cleared.
Definition: rail.h:30
RTO_Y
Piece of rail in Y direction.
Definition: rail.h:61
CheckRailSlope
static CommandCost CheckRailSlope(Slope tileh, TrackBits rail_bits, TrackBits existing, TileIndex tile)
Tests if a track can be build on a tile.
Definition: rail_cmd.cpp:408
autoslope.h
Functions related to autoslope.
sound_func.h
Functions related to sound.
GetTunnelBridgeDirection
static DiagDirection GetTunnelBridgeDirection(TileIndex t)
Get the direction pointing to the other end.
Definition: tunnelbridge_map.h:28
IsPlainRailTile
static bool IsPlainRailTile(TileIndex t)
Checks whether the tile is a rail tile or rail tile with signals.
Definition: rail_map.h:61
StringID
uint32 StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:18
AutoslopeEnabled
static bool AutoslopeEnabled()
Tests if autoslope is enabled for _current_company.
Definition: autoslope.h:46
CombineTrackStatus
static TrackStatus CombineTrackStatus(TrackdirBits trackdirbits, TrackdirBits red_signals)
Builds a TrackStatus.
Definition: track_func.h:376
ConstructionSettings::build_on_slopes
bool build_on_slopes
allow building on slopes
Definition: settings_type.h:301
CommandCost::Failed
bool Failed() const
Did this command fail?
Definition: command_type.h:161
RTO_SLOPE_SE
Piece of rail on slope with south-east raised.
Definition: rail.h:67
RFO_FLAT_X_SE
Slope FLAT, Track X, Fence SE.
Definition: rail.h:100
RailtypeInfo::single_n
SpriteID single_n
single piece of rail in the northern corner
Definition: rail.h:128
UpdateLevelCrossing
void UpdateLevelCrossing(TileIndex tile, bool sound=true)
Sets correct crossing state.
Definition: train_cmd.cpp:1699
RTO_E
Piece of rail in eastern corner.
Definition: rail.h:64
RoadTypes
RoadTypes
The different roadtypes we support, but then a bitmask of them.
Definition: road_type.h:36
SLOPE_EW
east and west corner are raised
Definition: slope_type.h:61
AddSortableSpriteToDraw
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:688
ReverseTrackdir
static Trackdir ReverseTrackdir(Trackdir trackdir)
Maps a trackdir to the reverse trackdir.
Definition: track_func.h:257
CMD_BUILD_SIGNALS
build a signal
Definition: command_type.h:186
RemoveHalftileSlope
static Slope RemoveHalftileSlope(Slope s)
Removes a halftile slope from a slope.
Definition: slope_func.h:62
return_cmd_error
#define return_cmd_error(errcode)
Returns from a function with a specific StringID as error.
Definition: command_func.h:35
GetTileTrackStatus
TrackStatus GetTileTrackStatus(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
Returns information about trackdirs and signal states.
Definition: landscape.cpp:509
RailtypeInfo::single_s
SpriteID single_s
single piece of rail in the southern corner
Definition: rail.h:129
RTO_N
Piece of rail in northern corner.
Definition: rail.h:62
VEH_SHIP
Ship vehicle type.
Definition: vehicle_type.h:26
HasSignals
static bool HasSignals(TileIndex t)
Checks if a rail tile has signals.
Definition: rail_map.h:73
RFO_SLOPE_NE_NW
Slope NE, Track X, Fence NW.
Definition: rail.h:98
RailtypeInfo::build_depot
SpriteID build_depot
button for building depots
Definition: rail.h:147
Train
&#39;Train&#39; is either a loco or a wagon.
Definition: train.h:88
RailtypeInfo::depot
CursorID depot
Cursor for building a depot.
Definition: rail.h:159
EnsureNoShipProc
static Vehicle * EnsureNoShipProc(Vehicle *v, void *data)
Test-procedure for HasVehicleOnPos to check for a ship.
Definition: rail_cmd.cpp:3011
CmdRemoveSingleRail
CommandCost CmdRemoveSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Remove a single piece of track.
Definition: rail_cmd.cpp:606
GetRailTileType
static RailTileType GetRailTileType(TileIndex t)
Returns the RailTileType (normal with or without signals, waypoint or depot).
Definition: rail_map.h:37
GetCrossingRoadBits
static RoadBits GetCrossingRoadBits(TileIndex tile)
Get the road bits of a level crossing.
Definition: road_map.h:318
MarkTileDirtyByTile
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset)
Mark a tile given by its index dirty for repaint.
Definition: viewport.cpp:1904
CMD_CONVERT_RAIL
convert a rail type
Definition: command_type.h:193
Company
Definition: company_base.h:110
TileIndexDiffC
A pair-construct of a TileIndexDiff.
Definition: map_type.h:58
GetTrackBits
static TrackBits GetTrackBits(TileIndex tile)
Gets the track bits of the given tile.
Definition: rail_map.h:137
Company::infrastructure
CompanyInfrastructure infrastructure
NOSAVE: Counts of company owned infrastructure.
Definition: company_base.h:125
AXIS_X
The X axis.
Definition: direction_type.h:128
CompanyInfrastructure::rail
uint32 rail[RAILTYPE_END]
Count of company owned track bits for each rail type.
Definition: company_base.h:34
EXPENSES_CONSTRUCTION
Construction costs.
Definition: economy_type.h:151
RailtypeInfo::convert
CursorID convert
Cursor for converting track.
Definition: rail.h:161
DiagDirToAxis
static Axis DiagDirToAxis(DiagDirection d)
Convert a DiagDirection to the axis.
Definition: direction_func.h:216
TRACK_BIT_CROSS
X-Y-axis cross.
Definition: track_type.h:49
ToTileIndexDiff
static TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc)
Return the offset between to tiles from a TileIndexDiffC struct.
Definition: map_func.h:232
GetOtherTunnelBridgeEnd
static TileIndex GetOtherTunnelBridgeEnd(TileIndex t)
Determines type of the wormhole and returns its other end.
Definition: tunnelbridge_map.h:80
TRANSPORT_RAIL
Transport by train.
Definition: transport_type.h:29
DC_EXEC
execute the given command
Definition: command_type.h:342
TrackToTrackBits
static TrackBits TrackToTrackBits(Track track)
Maps a Track to the corresponding TrackBits value.
Definition: track_func.h:87
EnsureNoTrainOnTrack
static CommandCost EnsureNoTrainOnTrack(TileIndex tile, Track track)
Tests if a vehicle interacts with the specified track.
Definition: rail_cmd.cpp:236
GetSlopePixelZInCorner
static int GetSlopePixelZInCorner(Slope tileh, Corner corner)
Determine the Z height of a corner relative to TileZ.
Definition: landscape.h:54
SignalAgainstTrackdir
static byte SignalAgainstTrackdir(Trackdir trackdir)
Maps a trackdir to the bit that stores its status in the map arrays, in the direction against the tra...
Definition: signal_func.h:34
DrawTileSprites::ground
PalSpriteID ground
Palette and sprite for the ground.
Definition: sprite.h:61
KillFirstBit
static T KillFirstBit(T value)
Clear the first bit in an integer.
Definition: bitmath_func.hpp:241
MapSize
static uint MapSize()
Get the size of the map.
Definition: map_func.h:94
CanBuildDepotByTileh
static bool CanBuildDepotByTileh(DiagDirection direction, Slope tileh)
Find out if the slope of the tile is suitable to build a depot of given direction.
Definition: depot_func.h:28
INVALID_TRACK
Flag for an invalid track.
Definition: track_type.h:30
ClrBit
static T ClrBit(T &x, const uint8 y)
Clears a bit in a variable.
Definition: bitmath_func.hpp:153
IsSlopeWithThreeCornersRaised
static bool IsSlopeWithThreeCornersRaised(Slope s)
Tests if a specific slope has exactly three corners raised.
Definition: slope_func.h:197
Train::GetVehicleTrackdir
Trackdir GetVehicleTrackdir() const
Get the tracks of the train vehicle.
Definition: train_cmd.cpp:4032
IsRailDepot
static bool IsRailDepot(TileIndex t)
Is this rail tile a rail depot?
Definition: rail_map.h:96
IsStationTileBlocked
bool IsStationTileBlocked(TileIndex tile)
Check whether a rail station tile is NOT traversable.
Definition: newgrf_station.cpp:851
ClientSettings::gui
GUISettings gui
settings related to the GUI
Definition: settings_type.h:561
MP_TUNNELBRIDGE
Tunnel entry/exit and bridge heads.
Definition: tile_type.h:52
RemoveFirstTrack
static Track RemoveFirstTrack(TrackBits *tracks)
Removes first Track from TrackBits and returns it.
Definition: track_func.h:141
TRACK_BIT_LOWER
Lower track.
Definition: track_type.h:46
IsRailDepotTile
static bool IsRailDepotTile(TileIndex t)
Is this tile rail tile and a rail depot?
Definition: rail_map.h:106
RAILTYPE_ELECTRIC
Electric rails.
Definition: rail_type.h:32
UpdateTrainPowerProc
static Vehicle * UpdateTrainPowerProc(Vehicle *v, void *data)
Update power of train under which is the railtype being converted.
Definition: rail_cmd.cpp:1526
TRACK_BIT_UPPER
Upper track.
Definition: track_type.h:45
HasTunnelBridgeReservation
static bool HasTunnelBridgeReservation(TileIndex t)
Get the reservation state of the rail tunnel/bridge.
Definition: tunnelbridge_map.h:93
SpriteID
uint32 SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition: gfx_type.h:19
RailtypeInfo::rail_swne
CursorID rail_swne
Cursor for building rail in X direction.
Definition: rail.h:155
TRACKDIR_BIT_X_SW
Track x-axis, direction south-west.
Definition: track_type.h:115
RFO_FLAT_RIGHT
Slope FLAT, Track RIGHT, Fence W.
Definition: rail.h:102
_current_company
CompanyByte _current_company
Company currently doing an action.
Definition: company_cmd.cpp:47
TRACK_BIT_HORZ
Upper and lower track.
Definition: track_type.h:50
TileTypeProcs
Set of callback functions for performing tile operations of a given tile type.
Definition: tile_cmd.h:144
TileIndex
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:80
PALETTE_CRASH
static const PaletteID PALETTE_CRASH
Recolour sprite greying of crashed vehicles.
Definition: sprites.h:1569
TRACK_BIT_DEPOT
Bitflag for a depot.
Definition: track_type.h:59
SignalAlongTrackdir
static byte SignalAlongTrackdir(Trackdir trackdir)
Maps a trackdir to the bit that stores its status in the map arrays, in the direction along with the ...
Definition: signal_func.h:24
PALETTE_TO_BARE_LAND
static const PaletteID PALETTE_TO_BARE_LAND
sets colour to bare land stuff for rail, road and crossings
Definition: sprites.h:1557
FenceOffset::x_offs
int x_offs
Bounding box X offset.
Definition: rail_cmd.cpp:1910
TRACKDIR_BIT_Y_NW
Track y-axis, direction north-west.
Definition: track_type.h:116
IsLevelCrossingTile
static bool IsLevelCrossingTile(TileIndex t)
Return whether a tile is a level crossing tile.
Definition: road_map.h:78
SLOPE_NW
north and west corner are raised
Definition: slope_type.h:57
RailBuildCost
static Money RailBuildCost(RailType railtype)
Returns the cost of building the specified railtype.
Definition: rail.h:344
MakeRoadCrossing
static void MakeRoadCrossing(TileIndex t, Owner road, Owner tram, Owner rail, Axis roaddir, RailType rat, RoadTypes rot, uint town)
Make a level crossing.
Definition: road_map.h:577
RTSG_CURSORS
Cursor and toolbar icon images.
Definition: rail.h:40
DrawTrackFence_SW
static void DrawTrackFence_SW(const TileInfo *ti, SpriteID base_image, uint num_sprites)
Draw fence at SW border matching the tile slope.
Definition: rail_cmd.cpp:1990
TileY
static uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition: map_func.h:217
VETSB_CONTINUE
Bit sets of the above specified bits.
Definition: tile_cmd.h:36
TrackToTrackdir
static Trackdir TrackToTrackdir(Track track)
Returns a Trackdir for the given Track.
Definition: track_func.h:289
error
void CDECL error(const char *s,...)
Error handling for fatal non-user errors.
Definition: openttd.cpp:110
TicksToLeaveDepot
int TicksToLeaveDepot(const Train *v)
Compute number of ticks when next wagon will leave a depot.
Definition: rail_cmd.cpp:2889
SIG_SEMAPHORE
Old-fashioned semaphore signal.
Definition: signal_type.h:20
abs
static T abs(const T a)
Returns the absolute value of (scalar) variable.
Definition: math_func.hpp:83
FOUNDATION_NONE
The tile has no foundation, the slope remains unchanged.
Definition: slope_type.h:96
GetReservedTrackbits
TrackBits GetReservedTrackbits(TileIndex t)
Get the reserved trackbits for any tile, regardless of type.
Definition: pbs.cpp:26
FreeTrainTrackReservation
void FreeTrainTrackReservation(const Train *v)
Free the reserved path in front of a vehicle.
Definition: train_cmd.cpp:2258
FOUNDATION_INCLINED_X
The tile has an along X-axis inclined foundation.
Definition: slope_type.h:98
TransportType
TransportType
Available types of transport.
Definition: transport_type.h:21
GB
static uint GB(const T x, const uint8 s, const uint8 n)
Fetch n bits from x, started at bit s.
Definition: bitmath_func.hpp:34
FOUNDATION_INVALID
Used inside "rail_cmd.cpp" to indicate invalid slope/track combination.
Definition: slope_type.h:115
FenceOffset::x_size
int x_size
Bounding box X size.
Definition: rail_cmd.cpp:1912
IsDiagonalTrackdir
static bool IsDiagonalTrackdir(Trackdir trackdir)
Checks if a given Trackdir is diagonal.
Definition: track_func.h:619
Slope
Slope
Enumeration for the slope-type.
Definition: slope_type.h:50
FenceOffset::y_size
int y_size
Bounding box Y size.
Definition: rail_cmd.cpp:1913
MP_STATION
A tile of a station.
Definition: tile_type.h:48
RailtypeInfo::build_tunnel
SpriteID build_tunnel
button for building a tunnel
Definition: rail.h:148
DrawRailCatenary
void DrawRailCatenary(const TileInfo *ti)
Draws overhead wires and pylons for electric railways.
Definition: elrail.cpp:564
RTO_JUNCTION_SE
Ballast for junction &#39;pointing&#39; SE.
Definition: rail.h:73
HasTrack
static bool HasTrack(TileIndex tile, Track track)
Returns whether the given track is present on the given tile.
Definition: rail_map.h:161
SmallVector::Include
bool Include(const T &item)
Tests whether a item is present in the vector, and appends it to the end if not.
Definition: smallvec_type.hpp:250
RAIL_TILE_NORMAL
Normal rail tile without signals.
Definition: rail_map.h:25
RTO_JUNCTION_SW
Ballast for junction &#39;pointing&#39; SW.
Definition: rail.h:71
RAILTYPES_NONE
No rail types.
Definition: rail_type.h:53
GUISettings::show_track_reservation
bool show_track_reservation
highlight reserved tracks.
Definition: settings_type.h:127
SubSprite
Used to only draw a part of the sprite.
Definition: gfx_type.h:219
RTSG_GROUND
Main group of ground images.
Definition: rail.h:42
RFO_SLOPE_SE_NE
Slope SE, Track Y, Fence NE.
Definition: rail.h:97
Pool::PoolItem<&_depot_pool >::CanAllocateItem
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function() ...
Definition: pool_type.hpp:216
SignalOffsets
SignalOffsets
Enum holding the signal offset in the sprite sheet according to the side it is representing.
Definition: rail_cmd.cpp:51
IsCompatibleRail
static bool IsCompatibleRail(RailType enginetype, RailType tiletype)
Checks if an engine of the given RailType can drive on a tile with a given RailType.
Definition: rail.h:311
RailtypeInfo::powered_railtypes
RailTypes powered_railtypes
bitmask to the OTHER railtypes on which an engine of THIS railtype generates power ...
Definition: rail.h:177
RailtypeInfo::GetRailtypeSpriteOffset
uint GetRailtypeSpriteOffset() const
Offset between the current railtype and normal rail.
Definition: rail.h:284
VS_HIDDEN
Vehicle is not visible.
Definition: vehicle_base.h:32
CountBits
static uint CountBits(T value)
Counts the number of set bits in a variable.
Definition: bitmath_func.hpp:253
TrackdirBits
TrackdirBits
Enumeration of bitmasks for the TrackDirs.
Definition: track_type.h:106
SIGNAL_STATE_RED
The signal is red.
Definition: signal_type.h:47
command_func.h
Functions related to commands.
Point
Coordinates of a point in 2D.
Definition: geometry_type.hpp:28
CMD_REMOVE_SINGLE_RAIL
remove a single rail track
Definition: command_type.h:181
RailtypeInfo::gui_sprites
struct RailtypeInfo::@37 gui_sprites
struct containing the sprites for the rail GUI.
OrthogonalTileIterator
Iterator to iterate over a tile area (rectangle) of the map.
Definition: tilearea_type.h:138
DrawGroundSprite
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:604
GetSnowLine
byte GetSnowLine()
Get the current snow line, either variable or static.
Definition: landscape.cpp:564
Pool::PoolItem<&_company_pool >::IsValidID
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-NULL) Titem.
Definition: pool_type.hpp:235
HasRailCatenaryDrawn
static bool HasRailCatenaryDrawn(RailType rt)
Test if we should draw rail catenary.
Definition: elrail_func.h:32
TileDesc::build_date
Date build_date
Date of construction of tile contents.
Definition: tile_cmd.h:57
RailTypeLabelList
SmallVector< RailTypeLabel, 4 > RailTypeLabelList
List of rail type labels.
Definition: rail.h:111
TRACK_BIT_3WAY_SE
"Arrow" to the south-east
Definition: track_type.h:53
VehicleSettings::train_acceleration_model
uint8 train_acceleration_model
realistic acceleration for trains
Definition: settings_type.h:449
elrail_func.h
header file for electrified rail specific functions
RFO_SLOPE_SW_SE
Slope SW, Track X, Fence SE.
Definition: rail.h:104
FOUNDATION_STEEP_LOWER
The tile has a steep slope. The lowest corner is raised by a foundation to allow building railroad on...
Definition: slope_type.h:100
RailGroundType
RailGroundType
The ground &#39;under&#39; the rail.
Definition: rail_map.h:486
MakeRoadNormal
static void MakeRoadNormal(TileIndex t, RoadBits bits, RoadTypes rot, TownID town, Owner road, Owner tram)
Make a normal road tile.
Definition: road_map.h:553
SlopeToSpriteOffset
static uint SlopeToSpriteOffset(Slope s)
Returns the Sprite offset for a given Slope.
Definition: slope_func.h:417
GameSettings::construction
ConstructionSettings construction
construction of things in-game
Definition: settings_type.h:545
INVALID_STRING_ID
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
Definition: strings_type.h:19
tunnelbridge_map.h
Functions that have tunnels and bridges in common.
GetDisallowedRoadDirections
static DisallowedRoadDirections GetDisallowedRoadDirections(TileIndex t)
Gets the disallowed directions.
Definition: road_map.h:271
GetRoadTypes
static RoadTypes GetRoadTypes(TileIndex t)
Get the present road types of a tile.
Definition: road_map.h:166
IsNormalRoad
static bool IsNormalRoad(TileIndex t)
Return whether a tile is a normal road.
Definition: road_map.h:47
GetSlopeZInCorner
int GetSlopeZInCorner(Slope tileh, Corner corner)
Determine the Z height of a corner relative to TileZ.
Definition: landscape.cpp:295
AutoslopeCheckForEntranceEdge
static bool AutoslopeCheckForEntranceEdge(TileIndex tile, int z_new, Slope tileh_new, DiagDirection entrance)
Autoslope check for tiles with an entrance on an edge.
Definition: autoslope.h:33
RailtypeInfo::name
StringID name
Name of this rail type.
Definition: rail.h:165
RAIL_GROUND_FENCE_SE
Grass with a fence at the SE edge.
Definition: rail_map.h:490
CMD_REMOVE_SIGNALS
remove a signal
Definition: command_type.h:187
DC_NO_RAIL_OVERLAP
don&#39;t allow overlap of rails (used in buildrail)
Definition: command_type.h:346
TileDesc::str
StringID str
Description of the tile.
Definition: tile_cmd.h:54
RailtypeInfo::tunnel
SpriteID tunnel
tunnel sprites base
Definition: rail.h:134
RailtypeInfo::rail_ns
CursorID rail_ns
Cursor for building rail in N-S direction.
Definition: rail.h:154
RFO_SLOPE_NE_SE
Slope NE, Track X, Fence SE.
Definition: rail.h:106
Vehicle::x_pos
int32 x_pos
x coordinate.
Definition: vehicle_base.h:268
TRACKDIR_BIT_Y_SE
Track y-axis, direction south-east.
Definition: track_type.h:109
HasReservedTracks
static bool HasReservedTracks(TileIndex tile, TrackBits tracks)
Check whether some of tracks is reserved on a tile.
Definition: pbs.h:60
HasBit
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
Definition: bitmath_func.hpp:105
DrawTrackBits
static void DrawTrackBits(TileInfo *ti, TrackBits track)
Draw ground sprite and track bits.
Definition: rail_cmd.cpp:2216
Backup::Restore
void Restore()
Restore the variable.
Definition: backup_type.hpp:114
TrackBitsToTrackdirBits
static TrackdirBits TrackBitsToTrackdirBits(TrackBits bits)
Converts TrackBits to TrackdirBits while allowing both directions.
Definition: track_func.h:329
SIG_ELECTRIC
Light signal.
Definition: signal_type.h:19
TRACKDIR_BIT_LEFT_S
Track left, direction south.
Definition: track_type.h:112
INVALID_TILE
static const TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition: tile_type.h:85
town.h
Base of the town class.
RAILTYPE_BEGIN
Used for iterations.
Definition: rail_type.h:30
RailtypeInfo::track_ns
SpriteID track_ns
two pieces of rail in North and South corner (East-West direction)
Definition: rail.h:124
GameSettings::game_creation
GameCreationSettings game_creation
settings used during the creation of a game (map)
Definition: settings_type.h:544
TRACKDIR_BIT_NONE
No track build.
Definition: track_type.h:107
IsPlainRail
static bool IsPlainRail(TileIndex t)
Returns whether this is plain rails, with or without signals.
Definition: rail_map.h:50
TRACKDIR_BIT_LEFT_N
Track left, direction north.
Definition: track_type.h:119
MP_HOUSE
A house by a town.
Definition: tile_type.h:46
ROAD_Y
Full road along the y-axis (north-west + south-east)
Definition: road_type.h:62
GetCrossingRailTrack
static Track GetCrossingRailTrack(TileIndex tile)
Get the rail track of a level crossing.
Definition: road_map.h:328
Vehicle::y_pos
int32 y_pos
y coordinate.
Definition: vehicle_base.h:269
RTO_JUNCTION_NSEW
Ballast for full junction.
Definition: rail.h:75
TRACK_BIT_LEFT
Left track.
Definition: track_type.h:47
RFO_FLAT_X_NW
Slope FLAT, Track X, Fence NW.
Definition: rail.h:92
INVALID_RAILTYPE
Flag for invalid railtype.
Definition: rail_type.h:36
IsInvisibilitySet
static bool IsInvisibilitySet(TransparencyOption to)
Check if the invisibility option bit is set and if we aren&#39;t in the game menu (there&#39;s never transpar...
Definition: transparency.h:61
TrackdirBitsToTrackBits
static TrackBits TrackdirBitsToTrackBits(TrackdirBits bits)
Discards all directional information from a TrackdirBits value.
Definition: track_func.h:318
HasDepotReservation
static bool HasDepotReservation(TileIndex t)
Get the reservation state of the depot.
Definition: rail_map.h:259
Owner
Owner
Enum for all companies/owners.
Definition: company_type.h:20
INVALID_TRACKDIR
Flag for an invalid trackdir.
Definition: track_type.h:93
CheckTrackCombination
static CommandCost CheckTrackCombination(TileIndex tile, TrackBits to_build, uint flags)
Check that the new track bits may be built.
Definition: rail_cmd.cpp:249
TRACK_X
Track along the x-axis (north-east to south-west)
Definition: track_type.h:23
water.h
Functions related to water (management)
IsNonContinuousFoundation
static bool IsNonContinuousFoundation(Foundation f)
Tests if a foundation is a non-continuous foundation, i.e.
Definition: slope_func.h:322
RailtypeInfo::build_x_rail
SpriteID build_x_rail
button for building single rail in X direction
Definition: rail.h:143
VehicleEnterTileStatus
VehicleEnterTileStatus
The returned bits of VehicleEnterTile.
Definition: tile_cmd.h:22
RAIL_GROUND_FENCE_HORIZ1
Grass with a fence at the southern side.
Definition: rail_map.h:497
AddTileIndexDiffCWrap
static TileIndex AddTileIndexDiffCWrap(TileIndex tile, TileIndexDiffC diff)
Add a TileIndexDiffC to a TileIndex and returns the new one.
Definition: map_func.h:302
SetTrackReservation
static void SetTrackReservation(TileIndex t, TrackBits b)
Sets the reserved track bits of the tile.
Definition: rail_map.h:210
PalSpriteID::sprite
SpriteID sprite
The &#39;real&#39; sprite.
Definition: gfx_type.h:25
RFO_SLOPE_NW_SW
Slope NW, Track Y, Fence SW.
Definition: rail.h:107
TRACKDIR_BIT_LOWER_E
Track lower, direction east.
Definition: track_type.h:111
SignalVariant
SignalVariant
Variant of the signal, i.e.
Definition: signal_type.h:18
CmdBuildRailroadTrack
CommandCost CmdBuildRailroadTrack(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Build rail on a stretch of track.
Definition: rail_cmd.cpp:924
_date
Date _date
Current date in days (day counter)
Definition: date.cpp:28
TryPathReserve
bool TryPathReserve(Train *v, bool mark_as_stuck=false, bool first_tile_okay=false)
Try to reserve a path to a safe position.
Definition: train_cmd.cpp:2696
QSortT
static void QSortT(T *base, uint num, int(CDECL *comparator)(const T *, const T *), bool desc=false)
Type safe qsort()
Definition: sort_func.hpp:28
ReverseDir
static Direction ReverseDir(Direction d)
Return the reverse of a direction.
Definition: direction_func.h:56
SIGTYPE_NORMAL
normal signal
Definition: signal_type.h:26
RailtypeInfo::build_ew_rail
SpriteID build_ew_rail
button for building single rail in E-W direction
Definition: rail.h:144
TRACK_UPPER
Track in the upper corner of the tile (north)
Definition: track_type.h:25
SLOPE_S
the south corner of the tile is raised
Definition: slope_type.h:53
OWNER_WATER
The tile/execution is done by "water".
Definition: company_type.h:28
DeleteNewGRFInspectWindow
void DeleteNewGRFInspectWindow(GrfSpecFeature feature, uint index)
Delete inspect window for a given feature and index.
Definition: newgrf_debug_gui.cpp:734
BaseVehicle::type
VehicleTypeByte type
Type of vehicle.
Definition: vehicle_type.h:54
IsSpecialRailFoundation
static bool IsSpecialRailFoundation(Foundation f)
Tests if a foundation is a special rail foundation for single horizontal/vertical track...
Definition: slope_func.h:347
CCF_TRACK
Valid changes while vehicle is driving, and possibly changing tracks.
Definition: train.h:51
TrackStatusToTrackdirBits
static TrackdirBits TrackStatusToTrackdirBits(TrackStatus ts)
Returns the present-trackdir-information of a TrackStatus.
Definition: track_func.h:340
DrawBridgeMiddle
void DrawBridgeMiddle(const TileInfo *ti)
Draw the middle bits of a bridge.
Definition: tunnelbridge_cmd.cpp:1391
backup_type.hpp
Class for backupping variables and making sure they are restored later.
ROADTYPES_ROAD
Road.
Definition: road_type.h:38
TRACK_BIT_NONE
No track.
Definition: track_type.h:42
OverflowSafeInt< int64, INT64_MAX, INT64_MIN >
DrawSprite
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
Draw a sprite, not in a viewport.
Definition: gfx.cpp:833
GetRailType
static RailType GetRailType(TileIndex t)
Gets the rail type of the given tile.
Definition: rail_map.h:116
OppositeCorner
static Corner OppositeCorner(Corner corner)
Returns the opposite corner.
Definition: slope_func.h:186
TracksOverlap
static bool TracksOverlap(TrackBits bits)
Checks if the given tracks overlap, ie form a crossing.
Definition: track_func.h:633
Vehicle::current_order
Order current_order
The current order (+ status, like: loading)
Definition: vehicle_base.h:318
IsBridge
static bool IsBridge(TileIndex t)
Checks if this is a bridge, instead of a tunnel.
Definition: bridge_map.h:24
DiagDirToDir
static Direction DiagDirToDir(DiagDirection dir)
Convert a DiagDirection to a Direction.
Definition: direction_func.h:184
TRACK_BIT_Y
Y-axis track.
Definition: track_type.h:44
Depot
Definition: depot_base.h:21
RAIL_GROUND_FENCE_VERT2
Grass with a fence at the western side.
Definition: rail_map.h:496
INVALID_OWNER
An invalid owner.
Definition: company_type.h:31
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:3220
SIGNAL_STATE_GREEN
The signal is green.
Definition: signal_type.h:48
RFO_FLAT_Y_SW
Slope FLAT, Track Y, Fence SW.
Definition: rail.h:101
RailtypeInfo::snow_offset
SpriteID snow_offset
sprite number difference between a piece of track on a snowy ground and the corresponding one on norm...
Definition: rail.h:174
SetRailType
static void SetRailType(TileIndex t, RailType r)
Sets the rail type of the given tile.
Definition: rail_map.h:126
GetTileMaxPixelZ
static int GetTileMaxPixelZ(TileIndex tile)
Get top height of the tile.
Definition: tile_map.h:299
VEH_TRAIN
Train vehicle type.
Definition: vehicle_type.h:24