37 #include "table/strings.h"
48 uint8 _sorted_railtypes_size;
73 {0,0,0,0,0,0,0,0,0,0,0,0},
77 0,
RAILTYPES_NONE,
RAILTYPES_NONE, 0, 0, 0,
RTFB_NONE, 0, 0, 0, 0, 0,
80 for (; i <
lengthof(_railtypes); i++) _railtypes[i] = empty_railtype;
86 if (cursors_base != 0) {
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},
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},
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;
142 ResolveRailTypeGUISprites(rti);
145 _sorted_railtypes_size = 0;
147 if (_railtypes[rt].label != 0) {
148 _sorted_railtypes[_sorted_railtypes_size++] = rt;
162 if (rti->
label == 0) {
189 static const byte _track_sloped_sprites[14] = {
259 if (current == future) {
269 return_cmd_error((flags & DC_NO_RAIL_OVERLAP) ? STR_ERROR_IMPOSSIBLE_TRACK_COMBINATION : STR_ERROR_MUST_REMOVE_SIGNALS_FIRST);
350 if ((~_valid_tracks_without_foundation[tileh] & bits) == 0)
return FOUNDATION_NONE;
352 bool valid_on_leveled = ((~_valid_tracks_on_leveled_foundation[tileh] & bits) == 0);
412 if (!
IsSteepSlope(tileh) && ((~_valid_tracks_on_leveled_foundation[tileh] & (rail_bits | existing)) != 0))
return_cmd_error(STR_ERROR_CAN_T_BUILD_ON_WATER);
428 static inline bool ValParamTrackOrientation(
Track track)
444 RailType railtype = Extract<RailType, 0, 4>(p1);
445 Track track = Extract<Track, 0, 3>(p2);
456 if (ret.
Failed())
return ret;
464 if (ret.
Failed())
return ret;
467 if (ret.
Failed())
return ret;
476 if (ret.
Failed())
return ret;
505 if (ret.
Failed())
return ret;
525 if (ret.
Failed())
return ret;
528 uint num_new_road_pieces = 2 -
CountBits(road);
534 cost.AddCost((num_new_road_pieces + num_new_tram_pieces) * _price[PR_BUILD_ROAD]);
565 if (ret.
Failed())
return ret;
569 if (ret.
Failed())
return ret;
573 cost.AddCost(-_price[PR_CLEAR_WATER]);
574 cost.AddCost(_price[PR_CLEAR_ROUGH]);
608 Track track = Extract<Track, 0, 3>(p2);
610 bool crossing =
false;
612 if (!ValParamTrackOrientation(track))
return CMD_ERROR;
629 if (ret.
Failed())
return ret;
634 if (ret.
Failed())
return ret;
660 if (ret.
Failed())
return ret;
664 if (ret.
Failed())
return ret;
667 if ((present & trackbit) == 0)
return_cmd_error(STR_ERROR_THERE_IS_NO_RAILROAD_TRACK);
753 bool flooded =
false;
762 TrackBits to_remove = lower_track & rail_bits;
763 if (to_remove != 0) {
767 if (!flooded)
return flooded;
768 rail_bits = rail_bits & ~to_remove;
769 if (rail_bits == 0) {
795 { -1, 0 }, { 0, 1 }, { -1, 0 }, { 0, 1 }, { 1, 0 }, { 0, 1 },
798 { 1, 0 }, { 0, -1 }, { 0, -1 }, { 1, 0 }, { 0, -1 }, { -1, 0 },
806 int x =
TileX(start);
807 int y =
TileY(start);
818 int trdx = _trackdelta[*trackdir].
x;
819 int trdy = _trackdelta[*trackdir].
y;
822 trdx += _trackdelta[*trackdir ^ 1].
x;
823 trdy += _trackdelta[*trackdir ^ 1].
y;
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)) {
843 trdx = _trackdelta[*trackdir].
x;
844 trdy = _trackdelta[*trackdir].
y;
867 Track track = Extract<Track, 4, 3>(p2);
868 bool remove =
HasBit(p2, 7);
869 RailType railtype = Extract<RailType, 0, 4>(p2);
876 CommandCost ret = ValidateAutoDrag(&trackdir, tile, end_tile);
877 if (ret.
Failed())
return ret;
879 bool had_success =
false;
886 if (last_error.
GetErrorMessage() != STR_ERROR_ALREADY_BUILT && !
remove) {
887 if (
HasBit(p2, 8))
return last_error;
892 if (last_error.
GetErrorMessage() == STR_ERROR_OWNED_BY &&
remove)
break;
898 if (tile == end_tile)
break;
906 if (had_success)
return total_cost;
963 RailType railtype = Extract<RailType, 0, 4>(p1);
985 if (cost.
Failed())
return cost;
1006 cost.
AddCost(_price[PR_BUILD_DEPOT_TRAIN]);
1034 Track track = Extract<Track, 0, 3>(p1);
1035 bool ctrl_pressed =
HasBit(p1, 3);
1037 SignalType sigtype = Extract<SignalType, 5, 3>(p1);
1038 bool convert_signal =
HasBit(p1, 8);
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);
1043 if (sigtype > SIGTYPE_LAST)
return CMD_ERROR;
1044 if (cycle_start > cycle_stop || cycle_stop > SIGTYPE_LAST)
return CMD_ERROR;
1055 if (ret.
Failed())
return ret;
1071 if (p2 != 0 && sigvar != GetSignalVariant(tile, track)) {
1075 }
else if (convert_signal) {
1077 if (ctrl_pressed || GetSignalVariant(tile, track) != sigvar) {
1106 SetSignalType(tile, track, sigtype);
1107 SetSignalVariant(tile, track, sigvar);
1117 SetSignalType(tile, track, sigtype);
1118 SetSignalVariant(tile, track, sigvar);
1119 while (num_dir_cycle-- > 0) CycleSignalSide(tile, track);
1121 if (convert_signal) {
1127 sigtype = GetSignalType(tile, track);
1130 SetSignalType(tile, track, sigtype);
1131 SetSignalVariant(tile, track, sigvar);
1137 }
else if (ctrl_pressed) {
1139 sigtype = (
SignalType)(GetSignalType(tile, track) + 1);
1141 if (sigtype < cycle_start || sigtype > cycle_stop) sigtype = cycle_start;
1143 SetSignalType(tile, track, sigtype);
1149 CycleSignalSide(tile, track);
1151 sigtype = GetSignalType(tile, track);
1158 SetSignalVariant(tile, track, sigvar);
1159 SetSignalType(tile, track, sigtype);
1166 if (IsPbsSignal(sigtype)) {
1186 static bool CheckSignalAutoFill(
TileIndex &tile,
Trackdir &trackdir,
int &signal_ctr,
bool remove)
1237 default:
return false;
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);
1273 if (signal_density == 0 || signal_density > 20)
return CMD_ERROR;
1279 signal_density *= 2;
1282 CommandCost ret = ValidateAutoDrag(&trackdir, tile, end_tile);
1283 if (ret.
Failed())
return ret;
1286 Trackdir start_trackdir = trackdir;
1292 if (sigtype > SIGTYPE_LAST)
return CMD_ERROR;
1298 assert(signals != 0);
1301 semaphores = GetSignalVariant(tile, track) !=
SIG_ELECTRIC;
1303 sigtype = GetSignalType(tile, track);
1310 byte signal_dir = 0;
1327 int last_used_ctr = INT_MIN;
1328 int last_suitable_ctr = 0;
1332 bool had_success =
false;
1335 if (
remove || minimise_gaps || signal_ctr % signal_density == 0) {
1338 SB(p1, 4, 1, semaphores);
1339 SB(p1, 5, 3, sigtype);
1340 if (!
remove && signal_ctr == 0)
SetBit(p1, 17);
1348 bool test_only = !
remove && minimise_gaps && signal_ctr < (last_used_ctr + signal_density);
1351 if (ret.Succeeded()) {
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) {
1372 if (ret.Succeeded()) {
1375 last_used_ctr = last_suitable_ctr;
1379 if (ret.GetErrorMessage() != STR_ERROR_THERE_IS_NO_RAILROAD_TRACK ||
1388 if (!CheckSignalAutoFill(tile, trackdir, signal_ctr,
remove))
break;
1391 if (tile == start_tile && trackdir == start_trackdir)
break;
1393 if (tile == end_tile)
break;
1407 return had_success ? total_cost : last_error;
1447 Track track = Extract<Track, 0, 3>(p1);
1459 if (ret.
Failed())
return ret;
1467 }
else if (IsPbsSignal(GetSignalType(tile, track))) {
1550 RailType totype = Extract<RailType, 0, 4>(p2);
1553 bool diagonal =
HasBit(p2, 4);
1577 error.
MakeError(STR_ERROR_CROSSING_DISALLOWED);
1620 *vehicles_affected.
Append() = v;
1661 if (flags & DC_EXEC) {
1678 if (endtile < tile) {
1702 *vehicles_affected.
Append() = v;
1744 for (uint i = 0; i < vehicles_affected.
Length(); ++i) {
1751 for (
Train **v = affected_trains.
Begin(); v != affected_trains.
End(); v++) {
1757 return (cost.
GetCost() == 0) ? error : cost;
1764 if (ret.
Failed())
return ret;
1768 if (ret.
Failed())
return ret;
1784 delete Depot::GetByTile(tile);
1785 DoClearSquare(tile);
1821 if (ret.
Failed())
return ret;
1829 if (ret.
Failed())
return ret;
1832 if (flags & DC_EXEC) DoClearSquare(tile);
1833 cost.AddCost(_price[PR_CLEAR_WATER]);
1840 return RemoveTrainDepot(tile, flags);
1860 return GetSlopePixelZ(x, y);
1867 case 0: side =
false;
break;
1868 case 2: side =
true;
break;
1871 static const Point SignalPositions[2][12] = {
1874 { 8, 5}, {14, 1}, { 1, 14}, { 9, 11}, { 1, 0}, { 3, 10},
1876 {11, 4}, {14, 14}, {11, 3}, { 4, 13}, { 3, 4}, {11, 13}
1879 {14, 1}, {12, 10}, { 4, 6}, { 1, 14}, {10, 4}, { 0, 1},
1881 {14, 14}, { 5, 12}, {11, 13}, { 4, 3}, {13, 4}, { 3, 11}
1888 SignalType type = GetSignalType(tile, track);
1897 sprite += type * 16 + variant * 64 + image * 2 + condition + (type > SIGTYPE_LAST_NOPBS ? 64 : 0);
1903 static uint32 _drawtile_track_palette;
1918 { CORNER_INVALID, 0, 1, 16, 1 },
1919 { CORNER_INVALID, 1, 0, 1, 16 },
1920 { CORNER_W, 8, 8, 1, 1 },
1921 { CORNER_N, 8, 8, 1, 1 },
1922 { CORNER_INVALID, 0, 1, 16, 1 },
1923 { CORNER_INVALID, 1, 0, 1, 16 },
1924 { CORNER_INVALID, 0, 1, 16, 1 },
1925 { CORNER_INVALID, 1, 0, 1, 16 },
1926 { CORNER_INVALID, 0, 15, 16, 1 },
1927 { CORNER_INVALID, 15, 0, 1, 16 },
1928 { CORNER_E, 8, 8, 1, 1 },
1929 { CORNER_S, 8, 8, 1, 1 },
1930 { CORNER_INVALID, 0, 15, 16, 1 },
1931 { CORNER_INVALID, 15, 0, 1, 16 },
1932 { CORNER_INVALID, 0, 15, 16, 1 },
1933 { CORNER_INVALID, 15, 0, 1, 16 },
1946 if (_fence_offsets[rfo].height_ref != CORNER_INVALID) {
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,
2006 uint num_sprites = 0;
2008 if (base_image == 0) {
2009 base_image = SPR_TRACK_FENCE_FLAT_X;
2013 assert(num_sprites > 0);
2015 switch (GetRailGroundType(ti->
tile)) {
2037 switch (track_corner) {
2042 default: NOT_REACHED();
2051 static const int INF = 1000;
2052 static const SubSprite _halftile_sub_sprite[4] = {
2053 { -INF , -INF , 32 - 33, INF },
2054 { -INF , 0 + 7, INF , INF },
2055 { -31 + 33, -INF , INF , INF },
2056 { -INF , -INF , INF , 30 - 23 }
2068 Corner halftile_corner = CORNER_INVALID;
2085 DrawShoreTile(ti->
tileh);
2096 default: image = SPR_FLAT_GRASS_TILE;
break;
2134 DrawTrackSprite(ground +
RTO_S, PAL_NONE, ti,
SLOPE_S);
break;
2136 DrawTrackSprite(ground +
RTO_W, PAL_NONE, ti,
SLOPE_W);
break;
2186 default: image = SPR_FLAT_GRASS_TILE;
break;
2191 DrawGroundSprite(image, PAL_NONE, &(_halftile_sub_sprite[halftile_corner]));
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;
2204 DrawTrackSprite(ground + offset, PAL_NONE, ti, fake_slope);
2206 DrawTrackSprite(overlay + offset,
PALETTE_CRASH, ti, fake_slope);
2220 if (rti->UsesOverlay()) {
2221 DrawTrackBitsOverlay(ti, track, rti);
2227 Corner halftile_corner = CORNER_INVALID;
2243 bool junction =
false;
2250 DrawShoreTile(ti->
tileh);
2253 image = SPR_FLAT_WATER_TILE;
2259 default: image = SPR_FLAT_GRASS_TILE;
break;
2270 (image++, track == TRACK_BIT_X) ||
2272 (image++, track == TRACK_BIT_LOWER) ||
2280 (junction =
true,
false) ||
2293 DrawShoreTile(ti->
tileh);
2295 sub = &(_halftile_sub_sprite[track_corner]);
2318 if (pbs & TRACK_BIT_X) {
2325 if (pbs & TRACK_BIT_Y) {
2354 static const byte _corner_to_track_sprite[] = {3, 1, 2, 0};
2362 #define MAYBE_DRAW_SIGNAL(x, y, z, t) if (IsSignalPresent(tile, x)) DrawSingleSignal(tile, rti, t, GetSingleSignalState(tile, x), y, z)
2364 if (!(rails & TRACK_BIT_Y)) {
2365 if (!(rails & TRACK_BIT_X)) {
2367 MAYBE_DRAW_SIGNAL(2, SIGNAL_TO_NORTH, 0,
TRACK_LEFT);
2368 MAYBE_DRAW_SIGNAL(3, SIGNAL_TO_SOUTH, 1,
TRACK_LEFT);
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);
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);
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);
2383 MAYBE_DRAW_SIGNAL(3, SIGNAL_TO_SOUTHWEST, 8,
TRACK_X);
2384 MAYBE_DRAW_SIGNAL(2, SIGNAL_TO_NORTHEAST, 9,
TRACK_X);
2387 MAYBE_DRAW_SIGNAL(3, SIGNAL_TO_SOUTHEAST, 10,
TRACK_Y);
2388 MAYBE_DRAW_SIGNAL(2, SIGNAL_TO_NORTHWEST, 11,
TRACK_Y);
2392 static void DrawTile_Track(
TileInfo *ti)
2424 if (rti->UsesOverlay()) {
2425 image = SPR_FLAT_GRASS_TILE;
2434 if (image != SPR_FLAT_GRASS_TILE) {
2437 image = SPR_FLAT_SNOW_DESERT_TILE;
2443 if (rti->UsesOverlay()) {
2487 void DrawTrainDepotSprite(
int x,
int y,
int dir,
RailType railtype)
2494 if (image != SPR_FLAT_GRASS_TILE) image += offset;
2499 if (rti->UsesOverlay()) {
2509 if (depot_sprite != 0) offset = depot_sprite - SPR_RAIL_DEPOT_SE_1;
2514 static int GetSlopePixelZ_Track(
TileIndex tile, uint x, uint y)
2533 static void TileLoop_Track(
TileIndex tile)
2645 default: NOT_REACHED();
2650 if (old_ground != new_ground) {
2651 SetRailGroundType(tile, new_ground);
2663 default: NOT_REACHED();
2678 default: NOT_REACHED();
2719 static bool ClickTile_Track(
TileIndex tile)
2735 td->
str = STR_LAI_RAIL_DESCRIPTION_TRACK;
2739 static const StringID signal_type[6][6] = {
2741 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_SIGNALS,
2742 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PRESIGNALS,
2743 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_EXITSIGNALS,
2744 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_COMBOSIGNALS,
2745 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PBSSIGNALS,
2746 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_NOENTRYSIGNALS
2749 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PRESIGNALS,
2750 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRESIGNALS,
2751 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_EXITSIGNALS,
2752 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_COMBOSIGNALS,
2753 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_PBSSIGNALS,
2754 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_NOENTRYSIGNALS
2757 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_EXITSIGNALS,
2758 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_EXITSIGNALS,
2759 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXITSIGNALS,
2760 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_COMBOSIGNALS,
2761 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_PBSSIGNALS,
2762 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_NOENTRYSIGNALS
2765 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_COMBOSIGNALS,
2766 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_COMBOSIGNALS,
2767 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_COMBOSIGNALS,
2768 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBOSIGNALS,
2769 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_PBSSIGNALS,
2770 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_NOENTRYSIGNALS
2773 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_PBSSIGNALS,
2774 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_PBSSIGNALS,
2775 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_PBSSIGNALS,
2776 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_PBSSIGNALS,
2777 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBSSIGNALS,
2778 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBS_NOENTRYSIGNALS
2781 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NORMAL_NOENTRYSIGNALS,
2782 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PRE_NOENTRYSIGNALS,
2783 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_NOENTRYSIGNALS,
2784 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_NOENTRYSIGNALS,
2785 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBS_NOENTRYSIGNALS,
2786 STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_NOENTRYSIGNALS
2793 primary_signal = GetSignalType(tile,
TRACK_UPPER);
2796 secondary_signal = primary_signal = GetSignalType(tile,
TRACK_LOWER);
2799 td->
str = signal_type[secondary_signal][primary_signal];
2804 td->
str = STR_LAI_RAIL_DESCRIPTION_TRAIN_DEPOT;
2826 uint num_pieces = 1;
2833 Company::Get(old_owner)->infrastructure.rail[rt] -= num_pieces;
2834 Company::Get(new_owner)->infrastructure.rail[rt] += num_pieces;
2838 Company::Get(old_owner)->infrastructure.signal -= num_sigs;
2839 Company::Get(new_owner)->infrastructure.signal += num_sigs;
2848 static const byte _fractcoords_behind[4] = { 0x8F, 0x8, 0x80, 0xF8 };
2849 static const byte _fractcoords_enter[4] = { 0x8A, 0x48, 0x84, 0xA8 };
2850 static const int8 _deltacoord_leaveoffset[8] = {
2868 case DIAGDIR_NE:
return ((
int)(v->
x_pos & 0x0F) - ((_fractcoords_enter[dir] & 0x0F) - (length + 1)));
2869 case DIAGDIR_SE:
return -((int)(v->
y_pos & 0x0F) - ((_fractcoords_enter[dir] >> 4) + (length + 1)));
2870 case DIAGDIR_SW:
return -((int)(v->
x_pos & 0x0F) - ((_fractcoords_enter[dir] & 0x0F) + (length + 1)));
2872 case DIAGDIR_NW:
return ((
int)(v->
y_pos & 0x0F) - ((_fractcoords_enter[dir] >> 4) - (length + 1)));
2895 byte fract_coord_leave =
2896 ((_fractcoords_enter[dir] & 0x0F) +
2897 (length + 1) * _deltacoord_leaveoffset[dir]) +
2898 (((_fractcoords_enter[dir] >> 4) +
2899 ((length + 1) * _deltacoord_leaveoffset[dir + 4])) << 4);
2901 byte fract_coord = (x & 0xF) + ((y & 0xF) << 4);
2903 if (_fractcoords_behind[dir] == fract_coord) {
2906 }
else if (_fractcoords_enter[dir] == fract_coord) {
2918 }
else if (fract_coord_leave == fract_coord) {
2921 if ((v = v->
Next()) != NULL) {
2954 switch (rail_bits) {
2955 case TRACK_BIT_LEFT: track_corner = CORNER_W;
break;
2956 case TRACK_BIT_LOWER: track_corner = CORNER_S;
break;
2957 case TRACK_BIT_RIGHT: track_corner = CORNER_E;
break;
2958 case TRACK_BIT_UPPER: track_corner = CORNER_N;
break;
2962 if (z_old != z_new || tileh_old != tileh_new)
return_cmd_error(STR_ERROR_MUST_REMOVE_RAILROAD_TRACK);
2969 if (z_old != z_new)
return_cmd_error(STR_ERROR_MUST_REMOVE_RAILROAD_TRACK);
2973 if (tileh_old != tileh_new) {
3006 switch (rail_bits) {
3007 case TRACK_BIT_RIGHT: allowed_corner = CORNER_W;
break;
3008 case TRACK_BIT_UPPER: allowed_corner = CORNER_S;
break;
3009 case TRACK_BIT_LEFT: allowed_corner = CORNER_E;
break;
3010 case TRACK_BIT_LOWER: allowed_corner = CORNER_N;
break;
3011 default:
return autoslope_result;
3020 for (
Corner corner = (
Corner)0; corner < CORNER_END; corner = (
Corner)(corner + 1)) {
3021 if (allowed_corner == corner)
continue;
3040 GetSlopePixelZ_Track,
3044 GetTileTrackStatus_Track,
3048 ChangeTileOwner_Track,
3051 GetFoundation_Track,
3052 TerraformTile_Track,