--- a/src/rail_cmd.cpp Sun Feb 03 20:34:26 2008 +0000
+++ b/src/rail_cmd.cpp Mon Mar 10 15:26:39 2008 +0000
@@ -45,6 +45,7 @@
#include "table/sprites.h"
#include "table/strings.h"
#include "table/railtypes.h"
+#include "table/track_land.h"
const byte _track_sloped_sprites[14] = {
14, 15, 22, 13,
@@ -356,9 +357,11 @@
if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
- if (GetRoadTileType(tile) == ROAD_TILE_NORMAL) {
+ if (IsNormalRoad(tile)) {
if (HasRoadWorks(tile)) return_cmd_error(STR_ROAD_WORKS_IN_PROGRESS);
+ if (GetDisallowedRoadDirections(tile) != DRD_NONE) return_cmd_error(STR_ERR_CROSSING_ON_ONEWAY_ROAD);
+
RoadTypes roadtypes = GetRoadTypes(tile);
RoadBits road = GetRoadBits(tile, ROADTYPE_ROAD);
RoadBits tram = GetRoadBits(tile, ROADTYPE_TRAM);
@@ -366,7 +369,7 @@
default: break;
case ROADTYPES_TRAM:
/* Tram crossings must always have road. */
- SetRoadOwner(tile, ROADTYPE_ROAD, _current_player);
+ if (flags & DC_EXEC) SetRoadOwner(tile, ROADTYPE_ROAD, _current_player);
roadtypes |= ROADTYPES_ROAD;
break;
@@ -455,7 +458,7 @@
if (!IsLevelCrossing(tile) ||
GetCrossingRailBits(tile) != trackbit ||
(_current_player != OWNER_WATER && !CheckTileOwnership(tile)) ||
- !EnsureNoVehicleOnGround(tile)) {
+ (!(flags & DC_BANKRUPT) && !EnsureNoVehicleOnGround(tile))) {
return CMD_ERROR;
}
@@ -910,8 +913,7 @@
if (tile == INVALID_TILE) return false;
/* Check for track bits on the new tile */
- uint32 ts = GetTileTrackStatus(tile, TRANSPORT_RAIL, 0);
- TrackdirBits trackdirbits = (TrackdirBits)(ts & TRACKDIR_BIT_MASK);
+ TrackdirBits trackdirbits = TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_RAIL, 0));
if (TracksOverlap(TrackdirBitsToTrackBits(trackdirbits))) return false;
trackdirbits &= TrackdirReachesTrackdirs(trackdir);
@@ -1312,7 +1314,7 @@
default: // MP_STATION, MP_ROAD
if (flags & DC_EXEC) {
- Track track = (tt == MP_STATION) ? GetRailStationTrack(tile) : AxisToTrack(OtherAxis(GetCrossingRoadAxis(tile)));
+ Track track = ((tt == MP_STATION) ? GetRailStationTrack(tile) : GetCrossingRailTrack(tile));
YapfNotifyTrackLayoutChange(tile, track);
}
@@ -1398,8 +1400,6 @@
}
}
-#include "table/track_land.h"
-
/**
* Get surface height in point (x,y)
* On tiles with halftile foundations move (x,y) to a save point wrt. track
@@ -1433,27 +1433,20 @@
}
};
- static const SpriteID SignalBase[2][2][4] = {
- { /* Signals on left side */
- { 0x4FB, 0x1323, 0x1333, 0x1343}, /* light signals */
- { 0x1353, 0x1363, 0x1373, 0x1383} /* semaphores */
- }, { /* Signals on right side */
- { 0x4FB, 0x1323, 0x1333, 0x1343}, /* light signals */
- { 0x1446, 0x1456, 0x1466, 0x1476} /* semaphores */
- /* | | | | */
- /* normal, entry, exit, combo */
- }
- };
-
uint x = TileX(tile) * TILE_SIZE + SignalPositions[side][pos].x;
uint y = TileY(tile) * TILE_SIZE + SignalPositions[side][pos].y;
SpriteID sprite;
- if (GetSignalType(tile, track) == SIGTYPE_NORMAL && GetSignalVariant(tile, track) == SIG_ELECTRIC) {
- sprite = SignalBase[side][GetSignalVariant(tile, track)][GetSignalType(tile, track)] + image + condition;
+ SignalType type = GetSignalType(tile, track);
+ SignalVariant variant = GetSignalVariant(tile, track);
+
+ if (type == SIGTYPE_NORMAL && variant == SIG_ELECTRIC) {
+ /* Normal electric signals are picked from original sprites. */
+ sprite = SPR_ORIGINAL_SIGNALS_BASE + image + condition;
} else {
- sprite = SPR_SIGNALS_BASE + (GetSignalType(tile, track) - 1) * 16 + GetSignalVariant(tile, track) * 64 + image + condition;
+ /* All other signals are picked from add on sprites. */
+ sprite = SPR_SIGNALS_BASE + (type - 1) * 16 + variant * 64 + image + condition;
}
AddSortableSpriteToDraw(sprite, PAL_NONE, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, GetSaveSlopeZ(x, y, track));
@@ -1698,42 +1691,59 @@
pal = PAL_NONE;
switch (rgt) {
case RAIL_GROUND_BARREN: pal = PALETTE_TO_BARE_LAND; break;
- case RAIL_GROUND_ICE_DESERT: image += rti->snow_offset; break;
+ case RAIL_GROUND_ICE_DESERT:
+ case RAIL_GROUND_HALF_SNOW: image += rti->snow_offset; break; // higher part has snow in this case too
default: break;
}
DrawGroundSprite(image, pal, &(_halftile_sub_sprite[halftile_corner]));
}
}
+/** Enums holding the offsets from base signal sprite,
+ * according to the side it is representing.
+ * The addtion of 2 per enum is necessary in order to "jump" over the
+ * green state sprite, all signal sprites being in pair,
+ * starting with the off-red state */
+enum {
+ SIGNAL_TO_SOUTHWEST = 0,
+ SIGNAL_TO_NORTHEAST = 2,
+ SIGNAL_TO_SOUTHEAST = 4,
+ SIGNAL_TO_NORTHWEST = 6,
+ SIGNAL_TO_EAST = 8,
+ SIGNAL_TO_WEST = 10,
+ SIGNAL_TO_SOUTH = 12,
+ SIGNAL_TO_NORTH = 14,
+};
+
static void DrawSignals(TileIndex tile, TrackBits rails)
{
-#define MAYBE_DRAW_SIGNAL(x,y,z,t) if (IsSignalPresent(tile, x)) DrawSingleSignal(tile, t, GetSingleSignalState(tile, x), y - 0x4FB, z)
+#define MAYBE_DRAW_SIGNAL(x,y,z,t) if (IsSignalPresent(tile, x)) DrawSingleSignal(tile, t, GetSingleSignalState(tile, x), y, z)
if (!(rails & TRACK_BIT_Y)) {
if (!(rails & TRACK_BIT_X)) {
if (rails & TRACK_BIT_LEFT) {
- MAYBE_DRAW_SIGNAL(2, 0x509, 0, TRACK_LEFT);
- MAYBE_DRAW_SIGNAL(3, 0x507, 1, TRACK_LEFT);
+ MAYBE_DRAW_SIGNAL(2, SIGNAL_TO_NORTH, 0, TRACK_LEFT);
+ MAYBE_DRAW_SIGNAL(3, SIGNAL_TO_SOUTH, 1, TRACK_LEFT);
}
if (rails & TRACK_BIT_RIGHT) {
- MAYBE_DRAW_SIGNAL(0, 0x509, 2, TRACK_RIGHT);
- MAYBE_DRAW_SIGNAL(1, 0x507, 3, TRACK_RIGHT);
+ MAYBE_DRAW_SIGNAL(0, SIGNAL_TO_NORTH, 2, TRACK_RIGHT);
+ MAYBE_DRAW_SIGNAL(1, SIGNAL_TO_SOUTH, 3, TRACK_RIGHT);
}
if (rails & TRACK_BIT_UPPER) {
- MAYBE_DRAW_SIGNAL(3, 0x505, 4, TRACK_UPPER);
- MAYBE_DRAW_SIGNAL(2, 0x503, 5, TRACK_UPPER);
+ MAYBE_DRAW_SIGNAL(3, SIGNAL_TO_WEST, 4, TRACK_UPPER);
+ MAYBE_DRAW_SIGNAL(2, SIGNAL_TO_EAST, 5, TRACK_UPPER);
}
if (rails & TRACK_BIT_LOWER) {
- MAYBE_DRAW_SIGNAL(1, 0x505, 6, TRACK_LOWER);
- MAYBE_DRAW_SIGNAL(0, 0x503, 7, TRACK_LOWER);
+ MAYBE_DRAW_SIGNAL(1, SIGNAL_TO_WEST, 6, TRACK_LOWER);
+ MAYBE_DRAW_SIGNAL(0, SIGNAL_TO_EAST, 7, TRACK_LOWER);
}
} else {
- MAYBE_DRAW_SIGNAL(3, 0x4FB, 8, TRACK_X);
- MAYBE_DRAW_SIGNAL(2, 0x4FD, 9, TRACK_X);
+ MAYBE_DRAW_SIGNAL(3, SIGNAL_TO_SOUTHWEST, 8, TRACK_X);
+ MAYBE_DRAW_SIGNAL(2, SIGNAL_TO_NORTHEAST, 9, TRACK_X);
}
} else {
- MAYBE_DRAW_SIGNAL(3, 0x4FF, 10, TRACK_Y);
- MAYBE_DRAW_SIGNAL(2, 0x501, 11, TRACK_Y);
+ MAYBE_DRAW_SIGNAL(3, SIGNAL_TO_SOUTHEAST, 10, TRACK_Y);
+ MAYBE_DRAW_SIGNAL(2, SIGNAL_TO_NORTHWEST, 11, TRACK_Y);
}
}
@@ -1767,7 +1777,7 @@
relocation = rti->total_offset;
- image = dts->ground_sprite;
+ image = dts->ground.sprite;
if (image != SPR_FLAT_GRASS_TILE) image += rti->total_offset;
/* adjust ground tile for desert
@@ -1803,7 +1813,7 @@
if (dts != NULL && dts->seq != NULL) {
relocation = GetCustomStationRelocation(statspec, st, ti->tile);
- image = dts->ground_sprite;
+ image = dts->ground.sprite;
if (HasBit(image, SPRITE_MODIFIER_USE_OFFSET)) {
image += GetCustomStationGroundRelocation(statspec, st, ti->tile);
image += rti->custom_ground_offset;
@@ -1818,7 +1828,7 @@
/* There is no custom layout, fall back to the default graphics */
dts = &_waypoint_gfx_table[GetWaypointAxis(ti->tile)];
relocation = 0;
- image = dts->ground_sprite + rti->total_offset;
+ image = dts->ground.sprite + rti->total_offset;
if (IsSnowRailGround(ti->tile)) image += rti->snow_offset;
}
}
@@ -1828,7 +1838,7 @@
if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
foreach_draw_tile_seq(dtss, dts->seq) {
- SpriteID image = dtss->image;
+ SpriteID image = dtss->image.sprite;
SpriteID pal;
/* Unlike stations, our default waypoint has no variation for
@@ -1843,7 +1853,7 @@
if (!(!HasBit(image, SPRITE_MODIFIER_OPAQUE) && IsTransparencySet(TO_BUILDINGS)) && HasBit(image, PALETTE_MODIFIER_COLOR)) {
pal = _drawtile_track_palette;
} else {
- pal = dtss->pal;
+ pal = dtss->image.pal;
}
if ((byte)dtss->delta_z != 0x80) {
@@ -1868,9 +1878,9 @@
SpriteID palette = PLAYER_SPRITE_COLOR(_local_player);
DrawSprite(ground, PAL_NONE, x, y);
- for (; dtss->image != 0; dtss++) {
+ for (; dtss->image.sprite != 0; dtss++) {
Point pt = RemapCoords(dtss->delta_x, dtss->delta_y, dtss->delta_z);
- SpriteID image = dtss->image + offset;
+ SpriteID image = dtss->image.sprite + offset;
DrawSprite(image, HasBit(image, PALETTE_MODIFIER_COLOR) ? palette : PAL_NONE, x + pt.x, y + pt.y);
}
@@ -1879,7 +1889,7 @@
void DrawTrainDepotSprite(int x, int y, int dir, RailType railtype)
{
const DrawTileSprites* dts = &_depot_gfx_table[dir];
- SpriteID image = dts->ground_sprite;
+ SpriteID image = dts->ground.sprite;
uint32 offset = GetRailTypeInfo(railtype)->total_offset;
if (image != SPR_FLAT_GRASS_TILE) image += offset;
@@ -1891,7 +1901,7 @@
uint32 offset = GetRailTypeInfo(railtype)->total_offset;
const DrawTileSprites* dts = &_waypoint_gfx_table[AXIS_X];
- DrawTileSequence(x, y, dts->ground_sprite + offset, dts->seq, 0);
+ DrawTileSequence(x, y, dts->ground.sprite + offset, dts->seq, 0);
}
static uint GetSlopeZ_Track(TileIndex tile, uint x, uint y)
@@ -1934,12 +1944,62 @@
}
switch (_opt.landscape) {
- case LT_ARCTIC:
- if (GetTileZ(tile) > GetSnowLine()) {
- new_ground = RAIL_GROUND_ICE_DESERT;
+ case LT_ARCTIC: {
+ uint z;
+ Slope slope = GetTileSlope(tile, &z);
+ bool half = false;
+
+ /* for non-flat track, use lower part of track
+ * in other cases, use the highest part with track */
+ if (IsPlainRailTile(tile)) {
+ TrackBits track = GetTrackBits(tile);
+ Foundation f = GetRailFoundation(slope, track);
+
+ switch (f) {
+ case FOUNDATION_NONE:
+ /* no foundation - is the track on the upper side of three corners raised tile? */
+ if (IsSlopeWithThreeCornersRaised(slope)) z += TILE_HEIGHT;
+ break;
+
+ case FOUNDATION_INCLINED_X:
+ case FOUNDATION_INCLINED_Y:
+ /* sloped track - is it on a steep slope? */
+ if (IsSteepSlope(slope)) z += TILE_HEIGHT;
+ break;
+
+ case FOUNDATION_STEEP_LOWER:
+ /* only lower part of steep slope */
+ z += TILE_HEIGHT;
+ break;
+
+ default:
+ /* if it is a steep slope, then there is a track on higher part */
+ if (IsSteepSlope(slope)) z += TILE_HEIGHT;
+ z += TILE_HEIGHT;
+ break;
+ }
+
+ half = IsInsideMM(f, FOUNDATION_STEEP_BOTH, FOUNDATION_HALFTILE_N + 1);
+ } else {
+ /* is the depot on a non-flat tile? */
+ if (slope != SLOPE_FLAT) z += TILE_HEIGHT;
+ }
+
+ /* 'z' is now the lowest part of the highest track bit -
+ * for sloped track, it is 'z' of lower part
+ * for two track bits, it is 'z' of higher track bit
+ * For non-continuous foundations (and STEEP_BOTH), 'half' is set */
+ if (z > GetSnowLine()) {
+ if (half && z - GetSnowLine() == TILE_HEIGHT) {
+ /* track on non-continuous foundation, lower part is not under snow */
+ new_ground = RAIL_GROUND_HALF_SNOW;
+ } else {
+ new_ground = RAIL_GROUND_ICE_DESERT;
+ }
goto set_ground;
}
break;
+ }
case LT_TROPIC:
if (GetTropicZone(tile) == TROPICZONE_DESERT) {
@@ -2040,20 +2100,21 @@
}
-static uint32 GetTileTrackStatus_Track(TileIndex tile, TransportType mode, uint sub_mode)
+static TrackStatus GetTileTrackStatus_Track(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
{
if (mode != TRANSPORT_RAIL) return 0;
+ TrackBits trackbits = TRACK_BIT_NONE;
+ TrackdirBits red_signals = TRACKDIR_BIT_NONE;
+
switch (GetRailTileType(tile)) {
default: NOT_REACHED();
- case RAIL_TILE_NORMAL: {
- TrackBits rails = GetTrackBits(tile);
- uint32 ret = rails * 0x101;
- return (rails == TRACK_BIT_CROSS) ? ret | 0x40 : ret;
- }
+ case RAIL_TILE_NORMAL:
+ trackbits = GetTrackBits(tile);
+ break;
case RAIL_TILE_SIGNALS: {
- uint32 ret = GetTrackBits(tile) * 0x101;
+ trackbits = GetTrackBits(tile);
byte a = GetPresentSignals(tile);
uint b = GetSignalStates(tile);
@@ -2066,17 +2127,29 @@
if ((a & 0xC) == 0) b |= 0xC;
if ((a & 0x3) == 0) b |= 0x3;
- if ((b & 0x8) == 0) ret |= 0x10070000;
- if ((b & 0x4) == 0) ret |= 0x07100000;
- if ((b & 0x2) == 0) ret |= 0x20080000;
- if ((b & 0x1) == 0) ret |= 0x08200000;
+ if ((b & 0x8) == 0) red_signals |= (TRACKDIR_BIT_LEFT_N | TRACKDIR_BIT_X_NE | TRACKDIR_BIT_Y_SE | TRACKDIR_BIT_UPPER_E);
+ if ((b & 0x4) == 0) red_signals |= (TRACKDIR_BIT_LEFT_S | TRACKDIR_BIT_X_SW | TRACKDIR_BIT_Y_NW | TRACKDIR_BIT_UPPER_W);
+ if ((b & 0x2) == 0) red_signals |= (TRACKDIR_BIT_RIGHT_N | TRACKDIR_BIT_LOWER_E);
+ if ((b & 0x1) == 0) red_signals |= (TRACKDIR_BIT_RIGHT_S | TRACKDIR_BIT_LOWER_W);
- return ret;
+ break;
}
- case RAIL_TILE_DEPOT: return AxisToTrackBits(DiagDirToAxis(GetRailDepotDirection(tile))) * 0x101;
- case RAIL_TILE_WAYPOINT: return GetRailWaypointBits(tile) * 0x101;
+ case RAIL_TILE_DEPOT: {
+ DiagDirection dir = GetRailDepotDirection(tile);
+
+ if (side != INVALID_DIAGDIR && side != dir) break;
+
+ trackbits = AxisToTrackBits(DiagDirToAxis(dir));
+ break;
+ }
+
+ case RAIL_TILE_WAYPOINT:
+ trackbits = GetRailWaypointBits(tile);
+ break;
}
+
+ return CombineTrackStatus(TrackBitsToTrackdirBits(trackbits), red_signals);
}
static void ClickTile_Track(TileIndex tile)
@@ -2146,7 +2219,7 @@
if (new_player != PLAYER_SPECTATOR) {
SetTileOwner(tile, new_player);
} else {
- DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
+ DoCommand(tile, 0, 0, DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR);
}
}