302 return_cmd_error(STR_1007_ALREADY_BUILT); |
302 return_cmd_error(STR_1007_ALREADY_BUILT); |
303 } |
303 } |
304 /* FALLTHROUGH */ |
304 /* FALLTHROUGH */ |
305 |
305 |
306 default: |
306 default: |
307 ret = CheckRailSlope(tileh, trackbit, 0, tile); |
307 ret = CheckRailSlope(tileh, trackbit, TRACK_BIT_NONE, tile); |
308 if (CmdFailed(ret)) return ret; |
308 if (CmdFailed(ret)) return ret; |
309 cost += ret; |
309 cost += ret; |
310 |
310 |
311 ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); |
311 ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); |
312 if (CmdFailed(ret)) return ret; |
312 if (CmdFailed(ret)) return ret; |
335 Track track = (Track)p2; |
335 Track track = (Track)p2; |
336 TrackBits trackbit; |
336 TrackBits trackbit; |
337 int32 cost = _price.remove_rail; |
337 int32 cost = _price.remove_rail; |
338 bool crossing = false; |
338 bool crossing = false; |
339 |
339 |
340 if (!ValParamTrackOrientation(p2)) return CMD_ERROR; |
340 if (!ValParamTrackOrientation((Track)p2)) return CMD_ERROR; |
341 trackbit = TrackToTrackBits(track); |
341 trackbit = TrackToTrackBits(track); |
342 |
342 |
343 SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); |
343 SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION); |
344 |
344 |
345 switch (GetTileType(tile)) { |
345 switch (GetTileType(tile)) { |
448 (trdx >= 0 && dx < 0) || |
448 (trdx >= 0 && dx < 0) || |
449 (trdy <= 0 && dy > 0) || |
449 (trdy <= 0 && dy > 0) || |
450 (trdy >= 0 && dy < 0) |
450 (trdy >= 0 && dy < 0) |
451 ) { |
451 ) { |
452 if (!HASBIT(*trackdir, 3)) { // first direction is invalid, try the other |
452 if (!HASBIT(*trackdir, 3)) { // first direction is invalid, try the other |
453 SETBIT(*trackdir, 3); // reverse the direction |
453 *trackdir = SetBitT(*trackdir, 3); // reverse the direction |
454 trdx = -trdx; |
454 trdx = -trdx; |
455 trdy = -trdy; |
455 trdy = -trdy; |
456 } else { // other direction is invalid too, invalid drag |
456 } else { // other direction is invalid too, invalid drag |
457 return CMD_ERROR; |
457 return CMD_ERROR; |
458 } |
458 } |
584 |
584 |
585 d = AllocateDepot(); |
585 d = AllocateDepot(); |
586 if (d == NULL) return CMD_ERROR; |
586 if (d == NULL) return CMD_ERROR; |
587 |
587 |
588 if (flags & DC_EXEC) { |
588 if (flags & DC_EXEC) { |
589 MakeRailDepot(tile, _current_player, p2, p1); |
589 DiagDirection dir = (DiagDirection)p2; |
|
590 MakeRailDepot(tile, _current_player, dir, (RailType)p1); |
590 MarkTileDirtyByTile(tile); |
591 MarkTileDirtyByTile(tile); |
591 |
592 |
592 d->xy = tile; |
593 d->xy = tile; |
593 d->town_index = ClosestTownFromTile(tile, (uint)-1)->index; |
594 d->town_index = ClosestTownFromTile(tile, (uint)-1)->index; |
594 |
595 |
595 UpdateSignalsOnSegment(tile, p2); |
596 UpdateSignalsOnSegment(tile, dir); |
596 YapfNotifyTrackLayoutChange(tile, TrackdirToTrack(DiagdirToDiagTrackdir(p2))); |
597 YapfNotifyTrackLayoutChange(tile, TrackdirToTrack(DiagdirToDiagTrackdir(dir))); |
597 } |
598 } |
598 |
599 |
599 return cost + _price.build_train_depot; |
600 return cost + _price.build_train_depot; |
600 } |
601 } |
601 |
602 |
851 // 'hidden' elrails can't be downgraded to normal rail when elrails are disabled |
852 // 'hidden' elrails can't be downgraded to normal rail when elrails are disabled |
852 if (_patches.disable_elrails && totype == RAILTYPE_RAIL && GetRailType(tile) == RAILTYPE_ELECTRIC) return CMD_ERROR; |
853 if (_patches.disable_elrails && totype == RAILTYPE_RAIL && GetRailType(tile) == RAILTYPE_ELECTRIC) return CMD_ERROR; |
853 |
854 |
854 // change type. |
855 // change type. |
855 if (exec) { |
856 if (exec) { |
856 TrackBits tracks; |
|
857 SetRailType(tile, totype); |
857 SetRailType(tile, totype); |
858 MarkTileDirtyByTile(tile); |
858 MarkTileDirtyByTile(tile); |
859 |
859 |
860 // notify YAPF about the track layout change |
860 // notify YAPF about the track layout change |
861 for (tracks = GetTrackBits(tile); tracks != TRACK_BIT_NONE; tracks = KILL_FIRST_BIT(tracks)) |
861 TrackBits tracks = GetTrackBits(tile); |
862 YapfNotifyTrackLayoutChange(tile, FIND_FIRST_BIT(tracks)); |
862 while (tracks != TRACK_BIT_NONE) { |
|
863 YapfNotifyTrackLayoutChange(tile, RemoveFirstTrack(tracks)); |
|
864 } |
863 |
865 |
864 if (IsTileDepotType(tile, TRANSPORT_RAIL)) { |
866 if (IsTileDepotType(tile, TRANSPORT_RAIL)) { |
865 Vehicle *v; |
867 Vehicle *v; |
866 |
868 |
867 /* Update build vehicle window related to this depot */ |
869 /* Update build vehicle window related to this depot */ |
924 case MP_STREET: proc = DoConvertStreetRail; break; |
926 case MP_STREET: proc = DoConvertStreetRail; break; |
925 case MP_TUNNELBRIDGE: proc = DoConvertTunnelBridgeRail; break; |
927 case MP_TUNNELBRIDGE: proc = DoConvertTunnelBridgeRail; break; |
926 default: continue; |
928 default: continue; |
927 } |
929 } |
928 |
930 |
929 ret = proc(tile, p2, false); |
931 ret = proc(tile, (RailType)p2, false); |
930 if (CmdFailed(ret)) continue; |
932 if (CmdFailed(ret)) continue; |
931 cost += ret; |
933 cost += ret; |
932 |
934 |
933 if (flags & DC_EXEC) { |
935 if (flags & DC_EXEC) { |
934 money -= ret; |
936 money -= ret; |
935 if (money < 0) { |
937 if (money < 0) { |
936 _additional_cash_required = ret; |
938 _additional_cash_required = ret; |
937 return cost - ret; |
939 return cost - ret; |
938 } |
940 } |
939 proc(tile, p2, true); |
941 proc(tile, (RailType)p2, true); |
940 } |
942 } |
941 } |
943 } |
942 } |
944 } |
943 |
945 |
944 return (cost == 0) ? ret : cost; |
946 return (cost == 0) ? ret : cost; |
983 |
985 |
984 switch (GetRailTileType(tile)) { |
986 switch (GetRailTileType(tile)) { |
985 case RAIL_TILE_SIGNALS: |
987 case RAIL_TILE_SIGNALS: |
986 case RAIL_TILE_NORMAL: { |
988 case RAIL_TILE_NORMAL: { |
987 TrackBits tracks = GetTrackBits(tile); |
989 TrackBits tracks = GetTrackBits(tile); |
988 uint i; |
990 while (tracks != TRACK_BIT_NONE) { |
989 |
991 Track track = RemoveFirstTrack(tracks); |
990 for_each_bit (i, tracks) { |
992 ret = DoCommand(tile, 0, track, flags, CMD_REMOVE_SINGLE_RAIL); |
991 ret = DoCommand(tile, 0, i, flags, CMD_REMOVE_SINGLE_RAIL); |
|
992 if (CmdFailed(ret)) return CMD_ERROR; |
993 if (CmdFailed(ret)) return CMD_ERROR; |
993 cost += ret; |
994 cost += ret; |
994 } |
995 } |
995 return cost; |
996 return cost; |
996 } |
997 } |
1009 |
1010 |
1010 #include "table/track_land.h" |
1011 #include "table/track_land.h" |
1011 |
1012 |
1012 static void DrawSingleSignal(TileIndex tile, byte condition, uint image, uint pos) |
1013 static void DrawSingleSignal(TileIndex tile, byte condition, uint image, uint pos) |
1013 { |
1014 { |
1014 bool side = _opt.road_side & _patches.signal_side; |
1015 bool side = (_opt.road_side != 0) && _patches.signal_side; |
1015 static const Point SignalPositions[2][12] = { |
1016 static const Point SignalPositions[2][12] = { |
1016 { /* Signals on the left side */ |
1017 { /* Signals on the left side */ |
1017 /* LEFT LEFT RIGHT RIGHT UPPER UPPER */ |
1018 /* LEFT LEFT RIGHT RIGHT UPPER UPPER */ |
1018 { 8, 5}, {14, 1}, { 1, 14}, { 9, 11}, { 1, 0}, { 3, 10}, |
1019 { 8, 5}, {14, 1}, { 1, 14}, { 9, 11}, { 1, 0}, { 3, 10}, |
1019 /* LOWER LOWER X X Y Y */ |
1020 /* LOWER LOWER X X Y Y */ |
1401 // presignal info |
1402 // presignal info |
1402 int presignal_exits; |
1403 int presignal_exits; |
1403 int presignal_exits_free; |
1404 int presignal_exits_free; |
1404 |
1405 |
1405 // these are used to keep track of the signals that change. |
1406 // these are used to keep track of the signals that change. |
1406 byte bit[NUM_SSD_ENTRY]; |
1407 TrackdirByte bit[NUM_SSD_ENTRY]; |
1407 TileIndex tile[NUM_SSD_ENTRY]; |
1408 TileIndex tile[NUM_SSD_ENTRY]; |
1408 |
1409 |
1409 // these are used to keep track of the stack that modifies presignals recursively |
1410 // these are used to keep track of the stack that modifies presignals recursively |
1410 TileIndex next_tile[NUM_SSD_STACK]; |
1411 TileIndex next_tile[NUM_SSD_STACK]; |
1411 byte next_dir[NUM_SSD_STACK]; |
1412 DiagDirectionByte next_dir[NUM_SSD_STACK]; |
1412 |
1413 |
1413 } SetSignalsData; |
1414 } SetSignalsData; |
1414 |
1415 |
1415 static bool SetSignalsEnumProc(TileIndex tile, void* data, int track, uint length, byte* state) |
1416 static bool SetSignalsEnumProc(TileIndex tile, void* data, Trackdir trackdir, uint length, byte* state) |
1416 { |
1417 { |
1417 SetSignalsData* ssd = data; |
1418 SetSignalsData* ssd = (SetSignalsData*)data; |
1418 |
1419 |
1419 if (!IsTileType(tile, MP_RAILWAY)) return false; |
1420 if (!IsTileType(tile, MP_RAILWAY)) return false; |
1420 |
1421 |
1421 // the tile has signals? |
1422 // the tile has signals? |
1422 if (HasSignalOnTrack(tile, TrackdirToTrack(track))) { |
1423 if (HasSignalOnTrack(tile, TrackdirToTrack(trackdir))) { |
1423 if (HasSignalOnTrackdir(tile, ReverseTrackdir(track))) { |
1424 if (HasSignalOnTrackdir(tile, ReverseTrackdir(trackdir))) { |
1424 // yes, add the signal to the list of signals |
1425 // yes, add the signal to the list of signals |
1425 if (ssd->cur != NUM_SSD_ENTRY) { |
1426 if (ssd->cur != NUM_SSD_ENTRY) { |
1426 ssd->tile[ssd->cur] = tile; // remember the tile index |
1427 ssd->tile[ssd->cur] = tile; // remember the tile index |
1427 ssd->bit[ssd->cur] = track; // and the controlling bit number |
1428 ssd->bit[ssd->cur] = trackdir; // and the controlling bit number |
1428 ssd->cur++; |
1429 ssd->cur++; |
1429 } |
1430 } |
1430 |
1431 |
1431 // remember if this block has a presignal. |
1432 // remember if this block has a presignal. |
1432 ssd->has_presignal |= IsPresignalEntry(tile); |
1433 ssd->has_presignal |= IsPresignalEntry(tile); |
1433 } |
1434 } |
1434 |
1435 |
1435 if (HasSignalOnTrackdir(tile, track) && IsPresignalExit(tile)) { |
1436 if (HasSignalOnTrackdir(tile, trackdir) && IsPresignalExit(tile)) { |
1436 // this is an exit signal that points out from the segment |
1437 // this is an exit signal that points out from the segment |
1437 ssd->presignal_exits++; |
1438 ssd->presignal_exits++; |
1438 if (GetSignalStateByTrackdir(tile, track) != SIGNAL_STATE_RED) |
1439 if (GetSignalStateByTrackdir(tile, trackdir) != SIGNAL_STATE_RED) |
1439 ssd->presignal_exits_free++; |
1440 ssd->presignal_exits_free++; |
1440 } |
1441 } |
1441 |
1442 |
1442 return true; |
1443 return true; |
1443 } else if (IsTileDepotType(tile, TRANSPORT_RAIL)) { |
1444 } else if (IsTileDepotType(tile, TRANSPORT_RAIL)) { |
1453 uint track; |
1454 uint track; |
1454 } SignalVehicleCheckStruct; |
1455 } SignalVehicleCheckStruct; |
1455 |
1456 |
1456 static void *SignalVehicleCheckProc(Vehicle *v, void *data) |
1457 static void *SignalVehicleCheckProc(Vehicle *v, void *data) |
1457 { |
1458 { |
1458 const SignalVehicleCheckStruct* dest = data; |
1459 const SignalVehicleCheckStruct* dest = (SignalVehicleCheckStruct*)data; |
1459 |
1460 |
1460 if (v->type != VEH_Train) return NULL; |
1461 if (v->type != VEH_Train) return NULL; |
1461 |
1462 |
1462 /* Wrong tile, or no train? Not a match */ |
1463 /* Wrong tile, or no train? Not a match */ |
1463 if (v->tile != dest->tile) return NULL; |
1464 if (v->tile != dest->tile) return NULL; |
1548 } while ((offs = link->next) != 0xFFFF); |
1549 } while ((offs = link->next) != 0xFFFF); |
1549 } |
1550 } |
1550 } |
1551 } |
1551 } |
1552 } |
1552 |
1553 |
1553 static const byte _dir_from_track[14] = { |
1554 static const DiagDirection _dir_from_track[14] = { |
1554 0,1,0,1,2,1, 0,0, |
1555 DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_NE, |
1555 2,3,3,2,3,0, |
1556 DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE, |
1556 }; |
1557 }; |
1557 |
1558 |
1558 |
1559 |
1559 static void ChangeSignalStates(SetSignalsData *ssd) |
1560 static void ChangeSignalStates(SetSignalsData *ssd) |
1560 { |
1561 { |
1907 } |
1908 } |
1908 } |
1909 } |
1909 |
1910 |
1910 static const byte _fractcoords_behind[4] = { 0x8F, 0x8, 0x80, 0xF8 }; |
1911 static const byte _fractcoords_behind[4] = { 0x8F, 0x8, 0x80, 0xF8 }; |
1911 static const byte _fractcoords_enter[4] = { 0x8A, 0x48, 0x84, 0xA8 }; |
1912 static const byte _fractcoords_enter[4] = { 0x8A, 0x48, 0x84, 0xA8 }; |
1912 static const byte _deltacoord_leaveoffset[8] = { |
1913 static const signed char _deltacoord_leaveoffset[8] = { |
1913 -1, 0, 1, 0, /* x */ |
1914 -1, 0, 1, 0, /* x */ |
1914 0, 1, 0, -1 /* y */ |
1915 0, 1, 0, -1 /* y */ |
1915 }; |
1916 }; |
1916 |
1917 |
1917 static uint32 VehicleEnter_Track(Vehicle *v, TileIndex tile, int x, int y) |
1918 static uint32 VehicleEnter_Track(Vehicle *v, TileIndex tile, int x, int y) |
1943 /* make sure a train is not entering the tile from behind */ |
1944 /* make sure a train is not entering the tile from behind */ |
1944 return 8; |
1945 return 8; |
1945 } else if (_fractcoords_enter[dir] == fract_coord) { |
1946 } else if (_fractcoords_enter[dir] == fract_coord) { |
1946 if (DiagDirToDir(ReverseDiagDir(dir)) == v->direction) { |
1947 if (DiagDirToDir(ReverseDiagDir(dir)) == v->direction) { |
1947 /* enter the depot */ |
1948 /* enter the depot */ |
1948 v->u.rail.track = 0x80, |
1949 v->u.rail.track = TRACK_BIT_SPECIAL, |
1949 v->vehstatus |= VS_HIDDEN; /* hide it */ |
1950 v->vehstatus |= VS_HIDDEN; /* hide it */ |
1950 v->direction = ReverseDir(v->direction); |
1951 v->direction = ReverseDir(v->direction); |
1951 if (v->next == NULL) VehicleEnterDepot(v); |
1952 if (v->next == NULL) VehicleEnterDepot(v); |
1952 v->tile = tile; |
1953 v->tile = tile; |
1953 |
1954 |
1957 } else if (fract_coord_leave == fract_coord) { |
1958 } else if (fract_coord_leave == fract_coord) { |
1958 if (DiagDirToDir(dir) == v->direction) { |
1959 if (DiagDirToDir(dir) == v->direction) { |
1959 /* leave the depot? */ |
1960 /* leave the depot? */ |
1960 if ((v = v->next) != NULL) { |
1961 if ((v = v->next) != NULL) { |
1961 v->vehstatus &= ~VS_HIDDEN; |
1962 v->vehstatus &= ~VS_HIDDEN; |
1962 v->u.rail.track = (DiagDirToAxis(dir) == AXIS_X ? 1 : 2); |
1963 v->u.rail.track = (DiagDirToAxis(dir) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y); |
1963 } |
1964 } |
1964 } |
1965 } |
1965 } |
1966 } |
1966 |
1967 |
1967 return 0; |
1968 return 0; |
1968 } |
1969 } |
1969 |
1970 |
1970 |
1971 |
1971 const TileTypeProcs _tile_type_rail_procs = { |
1972 extern const TileTypeProcs _tile_type_rail_procs = { |
1972 DrawTile_Track, /* draw_tile_proc */ |
1973 DrawTile_Track, /* draw_tile_proc */ |
1973 GetSlopeZ_Track, /* get_slope_z_proc */ |
1974 GetSlopeZ_Track, /* get_slope_z_proc */ |
1974 ClearTile_Track, /* clear_tile_proc */ |
1975 ClearTile_Track, /* clear_tile_proc */ |
1975 GetAcceptedCargo_Track, /* get_accepted_cargo_proc */ |
1976 GetAcceptedCargo_Track, /* get_accepted_cargo_proc */ |
1976 GetTileDesc_Track, /* get_tile_desc_proc */ |
1977 GetTileDesc_Track, /* get_tile_desc_proc */ |