154 TRACK_BIT_ALL, |
155 TRACK_BIT_ALL, |
155 TRACK_BIT_ALL |
156 TRACK_BIT_ALL |
156 } |
157 } |
157 }; |
158 }; |
158 |
159 |
159 uint GetRailFoundation(Slope tileh, TrackBits bits) |
160 Foundation GetRailFoundation(Slope tileh, TrackBits bits) |
160 { |
161 { |
161 uint i; |
|
162 |
|
163 if (!IsSteepSlope(tileh)) { |
162 if (!IsSteepSlope(tileh)) { |
164 if ((~_valid_tileh_slopes[0][tileh] & bits) == 0) return 0; |
163 if ((~_valid_tileh_slopes[0][tileh] & bits) == 0) return FOUNDATION_NONE; |
165 if ((~_valid_tileh_slopes[1][tileh] & bits) == 0) return tileh; |
164 if ((~_valid_tileh_slopes[1][tileh] & bits) == 0) return FOUNDATION_LEVELED; |
166 } |
165 } |
167 |
166 |
168 switch (bits) { |
167 switch (bits) { |
169 default: NOT_REACHED(); |
168 default: NOT_REACHED(); |
170 case TRACK_BIT_X: i = 0; break; |
169 case TRACK_BIT_X: return FOUNDATION_INCLINED_X; |
171 case TRACK_BIT_Y: i = 1; break; |
170 case TRACK_BIT_Y: return FOUNDATION_INCLINED_Y; |
172 case TRACK_BIT_LEFT: return 15 + 8 + (tileh == SLOPE_STEEP_W ? 4 : 0); |
171 case TRACK_BIT_LEFT: return (tileh == SLOPE_STEEP_W ? FOUNDATION_STEEP_HIGHER : FOUNDATION_STEEP_LOWER); |
173 case TRACK_BIT_LOWER: return 15 + 8 + (tileh == SLOPE_STEEP_S ? 5 : 1); |
172 case TRACK_BIT_LOWER: return (tileh == SLOPE_STEEP_S ? FOUNDATION_STEEP_HIGHER : FOUNDATION_STEEP_LOWER); |
174 case TRACK_BIT_RIGHT: return 15 + 8 + (tileh == SLOPE_STEEP_E ? 6 : 2); |
173 case TRACK_BIT_RIGHT: return (tileh == SLOPE_STEEP_E ? FOUNDATION_STEEP_HIGHER : FOUNDATION_STEEP_LOWER); |
175 case TRACK_BIT_UPPER: return 15 + 8 + (tileh == SLOPE_STEEP_N ? 7 : 3); |
174 case TRACK_BIT_UPPER: return (tileh == SLOPE_STEEP_N ? FOUNDATION_STEEP_HIGHER : FOUNDATION_STEEP_LOWER); |
176 } |
175 } |
177 switch (tileh) { |
|
178 case SLOPE_W: |
|
179 case SLOPE_STEEP_W: i += 0; break; |
|
180 case SLOPE_S: |
|
181 case SLOPE_STEEP_S: i += 2; break; |
|
182 case SLOPE_E: |
|
183 case SLOPE_STEEP_E: i += 4; break; |
|
184 case SLOPE_N: |
|
185 case SLOPE_STEEP_N: i += 6; break; |
|
186 default: return 0; |
|
187 } |
|
188 return i + 15; |
|
189 } |
176 } |
190 |
177 |
191 |
178 |
192 static CommandCost CheckRailSlope(Slope tileh, TrackBits rail_bits, TrackBits existing, TileIndex tile) |
179 static CommandCost CheckRailSlope(Slope tileh, TrackBits rail_bits, TrackBits existing, TileIndex tile) |
193 { |
180 { |
621 cost = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); |
607 cost = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); |
622 if (CmdFailed(cost)) return CMD_ERROR; |
608 if (CmdFailed(cost)) return CMD_ERROR; |
623 |
609 |
624 if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST); |
610 if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST); |
625 |
611 |
626 d = AllocateDepot(); |
612 Depot *d = new Depot(tile); |
|
613 |
627 if (d == NULL) return CMD_ERROR; |
614 if (d == NULL) return CMD_ERROR; |
|
615 AutoPtrT<Depot> d_auto_delete = d; |
628 |
616 |
629 if (flags & DC_EXEC) { |
617 if (flags & DC_EXEC) { |
630 MakeRailDepot(tile, _current_player, dir, (RailType)p1); |
618 MakeRailDepot(tile, _current_player, dir, (RailType)p1); |
631 MarkTileDirtyByTile(tile); |
619 MarkTileDirtyByTile(tile); |
632 |
620 |
633 d->xy = tile; |
|
634 d->town_index = ClosestTownFromTile(tile, (uint)-1)->index; |
621 d->town_index = ClosestTownFromTile(tile, (uint)-1)->index; |
635 |
622 |
636 UpdateSignalsOnSegment(tile, dir); |
623 UpdateSignalsOnSegment(tile, dir); |
637 YapfNotifyTrackLayoutChange(tile, TrackdirToTrack(DiagdirToDiagTrackdir(dir))); |
624 YapfNotifyTrackLayoutChange(tile, TrackdirToTrack(DiagdirToDiagTrackdir(dir))); |
|
625 d_auto_delete.Detach(); |
638 } |
626 } |
639 |
627 |
640 return cost.AddCost(_price.build_train_depot); |
628 return cost.AddCost(_price.build_train_depot); |
641 } |
629 } |
642 |
630 |
1223 static uint32 _drawtile_track_palette; |
1212 static uint32 _drawtile_track_palette; |
1224 |
1213 |
1225 |
1214 |
1226 static void DrawTrackFence_NW(const TileInfo *ti) |
1215 static void DrawTrackFence_NW(const TileInfo *ti) |
1227 { |
1216 { |
1228 SpriteID image = 0x515; |
1217 SpriteID image = SPR_TRACK_FENCE_FLAT_X; |
1229 if (ti->tileh != SLOPE_FLAT) image = (ti->tileh & SLOPE_S) ? 0x519 : 0x51B; |
1218 if (ti->tileh != SLOPE_FLAT) image = (ti->tileh & SLOPE_S) ? SPR_TRACK_FENCE_SLOPE_SW : SPR_TRACK_FENCE_SLOPE_NE; |
1230 AddSortableSpriteToDraw(image, _drawtile_track_palette, |
1219 AddSortableSpriteToDraw(image, _drawtile_track_palette, |
1231 ti->x, ti->y + 1, 16, 1, 4, ti->z); |
1220 ti->x, ti->y + 1, 16, 1, 4, ti->z); |
1232 } |
1221 } |
1233 |
1222 |
1234 static void DrawTrackFence_SE(const TileInfo *ti) |
1223 static void DrawTrackFence_SE(const TileInfo *ti) |
1235 { |
1224 { |
1236 SpriteID image = 0x515; |
1225 SpriteID image = SPR_TRACK_FENCE_FLAT_X; |
1237 if (ti->tileh != SLOPE_FLAT) image = (ti->tileh & SLOPE_S) ? 0x519 : 0x51B; |
1226 if (ti->tileh != SLOPE_FLAT) image = (ti->tileh & SLOPE_S) ? SPR_TRACK_FENCE_SLOPE_SW : SPR_TRACK_FENCE_SLOPE_NE; |
1238 AddSortableSpriteToDraw(image, _drawtile_track_palette, |
1227 AddSortableSpriteToDraw(image, _drawtile_track_palette, |
1239 ti->x, ti->y + TILE_SIZE - 1, 16, 1, 4, ti->z); |
1228 ti->x, ti->y + TILE_SIZE - 1, 16, 1, 4, ti->z); |
1240 } |
1229 } |
1241 |
1230 |
1242 static void DrawTrackFence_NW_SE(const TileInfo *ti) |
1231 static void DrawTrackFence_NW_SE(const TileInfo *ti) |
1245 DrawTrackFence_SE(ti); |
1234 DrawTrackFence_SE(ti); |
1246 } |
1235 } |
1247 |
1236 |
1248 static void DrawTrackFence_NE(const TileInfo *ti) |
1237 static void DrawTrackFence_NE(const TileInfo *ti) |
1249 { |
1238 { |
1250 SpriteID image = 0x516; |
1239 SpriteID image = SPR_TRACK_FENCE_FLAT_Y; |
1251 if (ti->tileh != SLOPE_FLAT) image = (ti->tileh & SLOPE_S) ? 0x51A : 0x51C; |
1240 if (ti->tileh != SLOPE_FLAT) image = (ti->tileh & SLOPE_S) ? SPR_TRACK_FENCE_SLOPE_SE : SPR_TRACK_FENCE_SLOPE_NW; |
1252 AddSortableSpriteToDraw(image, _drawtile_track_palette, |
1241 AddSortableSpriteToDraw(image, _drawtile_track_palette, |
1253 ti->x + 1, ti->y, 1, 16, 4, ti->z); |
1242 ti->x + 1, ti->y, 1, 16, 4, ti->z); |
1254 } |
1243 } |
1255 |
1244 |
1256 static void DrawTrackFence_SW(const TileInfo *ti) |
1245 static void DrawTrackFence_SW(const TileInfo *ti) |
1257 { |
1246 { |
1258 SpriteID image = 0x516; |
1247 SpriteID image = SPR_TRACK_FENCE_FLAT_Y; |
1259 if (ti->tileh != SLOPE_FLAT) image = (ti->tileh & SLOPE_S) ? 0x51A : 0x51C; |
1248 if (ti->tileh != SLOPE_FLAT) image = (ti->tileh & SLOPE_S) ? SPR_TRACK_FENCE_SLOPE_SE : SPR_TRACK_FENCE_SLOPE_NW; |
1260 AddSortableSpriteToDraw(image, _drawtile_track_palette, |
1249 AddSortableSpriteToDraw(image, _drawtile_track_palette, |
1261 ti->x + TILE_SIZE - 1, ti->y, 1, 16, 4, ti->z); |
1250 ti->x + TILE_SIZE - 1, ti->y, 1, 16, 4, ti->z); |
1262 } |
1251 } |
1263 |
1252 |
1264 static void DrawTrackFence_NE_SW(const TileInfo *ti) |
1253 static void DrawTrackFence_NE_SW(const TileInfo *ti) |
1265 { |
1254 { |
1266 DrawTrackFence_NE(ti); |
1255 DrawTrackFence_NE(ti); |
1267 DrawTrackFence_SW(ti); |
1256 DrawTrackFence_SW(ti); |
1268 } |
1257 } |
1269 |
1258 |
|
1259 /** |
|
1260 * Draw fence at eastern side of track. |
|
1261 */ |
1270 static void DrawTrackFence_NS_1(const TileInfo *ti) |
1262 static void DrawTrackFence_NS_1(const TileInfo *ti) |
1271 { |
1263 { |
1272 int z = ti->z; |
1264 int z = ti->z; |
1273 if (ti->tileh & SLOPE_W) z += TILE_HEIGHT; |
1265 if (ti->tileh & SLOPE_W) z += TILE_HEIGHT; |
1274 AddSortableSpriteToDraw(0x517, _drawtile_track_palette, |
1266 AddSortableSpriteToDraw(SPR_TRACK_FENCE_FLAT_VERT, _drawtile_track_palette, |
1275 ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z); |
1267 ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z); |
1276 } |
1268 } |
1277 |
1269 |
|
1270 /** |
|
1271 * Draw fence at western side of track. |
|
1272 */ |
1278 static void DrawTrackFence_NS_2(const TileInfo *ti) |
1273 static void DrawTrackFence_NS_2(const TileInfo *ti) |
1279 { |
1274 { |
1280 int z = ti->z; |
1275 int z = ti->z; |
1281 if (ti->tileh & SLOPE_E) z += TILE_HEIGHT; |
1276 if (ti->tileh & SLOPE_E) z += TILE_HEIGHT; |
1282 AddSortableSpriteToDraw(0x517, _drawtile_track_palette, |
1277 AddSortableSpriteToDraw(SPR_TRACK_FENCE_FLAT_VERT, _drawtile_track_palette, |
1283 ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z); |
1278 ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z); |
1284 } |
1279 } |
1285 |
1280 |
|
1281 /** |
|
1282 * Draw fence at southern side of track. |
|
1283 */ |
1286 static void DrawTrackFence_WE_1(const TileInfo *ti) |
1284 static void DrawTrackFence_WE_1(const TileInfo *ti) |
1287 { |
1285 { |
1288 int z = ti->z; |
1286 int z = ti->z; |
1289 if (ti->tileh & SLOPE_N) z += TILE_HEIGHT; |
1287 if (ti->tileh & SLOPE_N) z += TILE_HEIGHT; |
1290 AddSortableSpriteToDraw(0x518, _drawtile_track_palette, |
1288 AddSortableSpriteToDraw(SPR_TRACK_FENCE_FLAT_HORZ, _drawtile_track_palette, |
1291 ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z); |
1289 ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z); |
1292 } |
1290 } |
1293 |
1291 |
|
1292 /** |
|
1293 * Draw fence at northern side of track. |
|
1294 */ |
1294 static void DrawTrackFence_WE_2(const TileInfo *ti) |
1295 static void DrawTrackFence_WE_2(const TileInfo *ti) |
1295 { |
1296 { |
1296 int z = ti->z; |
1297 int z = ti->z; |
1297 if (ti->tileh & SLOPE_S) z += TILE_HEIGHT; |
1298 if (ti->tileh & SLOPE_S) z += TILE_HEIGHT; |
1298 AddSortableSpriteToDraw(0x518, _drawtile_track_palette, |
1299 AddSortableSpriteToDraw(SPR_TRACK_FENCE_FLAT_HORZ, _drawtile_track_palette, |
1299 ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z); |
1300 ti->x + TILE_SIZE / 2, ti->y + TILE_SIZE / 2, 1, 1, 4, z); |
1300 } |
1301 } |
1301 |
1302 |
1302 |
1303 |
1303 static void DrawTrackDetails(const TileInfo* ti) |
1304 static void DrawTrackDetails(const TileInfo* ti) |
1348 (image++, (track & TRACK_BIT_3WAY_NW) == 0) || |
1349 (image++, (track & TRACK_BIT_3WAY_NW) == 0) || |
1349 (image++, (track & TRACK_BIT_3WAY_SE) == 0) || |
1350 (image++, (track & TRACK_BIT_3WAY_SE) == 0) || |
1350 (image++, true); |
1351 (image++, true); |
1351 |
1352 |
1352 if (ti->tileh != SLOPE_FLAT) { |
1353 if (ti->tileh != SLOPE_FLAT) { |
1353 uint foundation = GetRailFoundation(ti->tileh, track); |
1354 DrawFoundation(ti, GetRailFoundation(ti->tileh, track)); |
1354 |
|
1355 if (foundation != 0) DrawFoundation(ti, foundation); |
|
1356 |
1355 |
1357 /* DrawFoundation() modifies it. |
1356 /* DrawFoundation() modifies it. |
1358 * Default sloped sprites.. */ |
1357 * Default sloped sprites.. */ |
1359 if (ti->tileh != SLOPE_FLAT) |
1358 if (ti->tileh != SLOPE_FLAT) image = _track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.track_y; |
1360 image = _track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.track_y; |
|
1361 } |
1359 } |
1362 |
1360 |
1363 switch (GetRailGroundType(ti->tile)) { |
1361 switch (GetRailGroundType(ti->tile)) { |
1364 case RAIL_GROUND_BARREN: pal = PALETTE_TO_BARE_LAND; break; |
1362 case RAIL_GROUND_BARREN: pal = PALETTE_TO_BARE_LAND; break; |
1365 case RAIL_GROUND_ICE_DESERT: image += rti->snow_offset; break; |
1363 case RAIL_GROUND_ICE_DESERT: image += rti->snow_offset; break; |
1512 image += rti->total_offset; |
1510 image += rti->total_offset; |
1513 } else { |
1511 } else { |
1514 image += relocation; |
1512 image += relocation; |
1515 } |
1513 } |
1516 |
1514 |
1517 if (HASBIT(_transparent_opt, TO_BUILDINGS)) { |
1515 if (!HASBIT(_transparent_opt, TO_BUILDINGS) && HASBIT(image, PALETTE_MODIFIER_COLOR)) { |
1518 SETBIT(image, PALETTE_MODIFIER_TRANSPARENT); |
|
1519 pal = PALETTE_TO_TRANSPARENT; |
|
1520 } else if (HASBIT(image, PALETTE_MODIFIER_COLOR)) { |
|
1521 pal = _drawtile_track_palette; |
1516 pal = _drawtile_track_palette; |
1522 } else { |
1517 } else { |
1523 pal = dtss->pal; |
1518 pal = dtss->pal; |
1524 } |
1519 } |
1525 |
1520 |
1526 if ((byte)dtss->delta_z != 0x80) { |
1521 if ((byte)dtss->delta_z != 0x80) { |
1527 AddSortableSpriteToDraw( |
1522 AddSortableSpriteToDraw( |
1528 image, pal, |
1523 image, pal, |
1529 ti->x + dtss->delta_x, ti->y + dtss->delta_y, |
1524 ti->x + dtss->delta_x, ti->y + dtss->delta_y, |
1530 dtss->size_x, dtss->size_y, |
1525 dtss->size_x, dtss->size_y, |
1531 dtss->size_z, ti->z + dtss->delta_z |
1526 dtss->size_z, ti->z + dtss->delta_z, |
|
1527 HASBIT(_transparent_opt, TO_BUILDINGS) |
1532 ); |
1528 ); |
1533 } else { |
1529 } else { |
1534 AddChildSpriteScreen(image, pal, dtss->delta_x, dtss->delta_y); |
1530 AddChildSpriteScreen(image, pal, dtss->delta_x, dtss->delta_y); |
1535 } |
1531 } |
1536 } |
1532 } |
1674 if (VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL) return true; |
1670 if (VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL) return true; |
1675 |
1671 |
1676 /* check for a vehicle with that trackdir on the end tile of the tunnel */ |
1672 /* check for a vehicle with that trackdir on the end tile of the tunnel */ |
1677 if (VehicleFromPos(end, &dest, SignalVehicleCheckProc) != NULL) return true; |
1673 if (VehicleFromPos(end, &dest, SignalVehicleCheckProc) != NULL) return true; |
1678 |
1674 |
1679 /* now check all tiles from start to end for a warping vehicle |
1675 /* now check all tiles from start to end for a warping vehicle */ |
1680 * NOTE: the hashes for tiles may overlap, so this could maybe be optimised a bit by not checking every tile? */ |
|
1681 dest.track = 0x40; //Vehicle inside a tunnel or on a bridge |
1676 dest.track = 0x40; //Vehicle inside a tunnel or on a bridge |
1682 for (; tile != end; tile += TileOffsByDiagDir(direction)) { |
1677 if (VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL) return true; |
1683 if (VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL) |
1678 if (VehicleFromPos(end, &dest, SignalVehicleCheckProc) != NULL) return true; |
1684 return true; |
|
1685 } |
|
1686 |
1679 |
1687 /* no vehicle found */ |
1680 /* no vehicle found */ |
1688 return false; |
1681 return false; |
1689 } |
1682 } |
1690 |
1683 |
1838 uint z; |
1831 uint z; |
1839 Slope tileh = GetTileSlope(tile, &z); |
1832 Slope tileh = GetTileSlope(tile, &z); |
1840 |
1833 |
1841 if (tileh == SLOPE_FLAT) return z; |
1834 if (tileh == SLOPE_FLAT) return z; |
1842 if (IsPlainRailTile(tile)) { |
1835 if (IsPlainRailTile(tile)) { |
1843 uint f = GetRailFoundation(tileh, GetTrackBits(tile)); |
1836 z += ApplyFoundationToSlope(GetRailFoundation(tileh, GetTrackBits(tile)), &tileh); |
1844 |
|
1845 if (f != 0) { |
|
1846 if (IsSteepSlope(tileh)) { |
|
1847 z += TILE_HEIGHT; |
|
1848 } else if (f < 15) { |
|
1849 return z + TILE_HEIGHT; // leveled foundation |
|
1850 } |
|
1851 tileh = _inclined_tileh[f - 15]; // inclined foundation |
|
1852 } |
|
1853 return z + GetPartialZ(x & 0xF, y & 0xF, tileh); |
1837 return z + GetPartialZ(x & 0xF, y & 0xF, tileh); |
1854 } else { |
1838 } else { |
1855 return z + TILE_HEIGHT; |
1839 return z + TILE_HEIGHT; |
1856 } |
1840 } |
1857 } |
1841 } |
1858 |
1842 |
1859 static Slope GetSlopeTileh_Track(TileIndex tile, Slope tileh) |
1843 static Foundation GetFoundation_Track(TileIndex tile, Slope tileh) |
1860 { |
1844 { |
1861 if (tileh == SLOPE_FLAT) return SLOPE_FLAT; |
1845 return IsPlainRailTile(tile) ? GetRailFoundation(tileh, GetTrackBits(tile)) : FlatteningFoundation(tileh); |
1862 if (IsPlainRailTile(tile)) { |
|
1863 uint f = GetRailFoundation(tileh, GetTrackBits(tile)); |
|
1864 |
|
1865 if (f == 0) return tileh; |
|
1866 if (f < 15) return SLOPE_FLAT; // leveled foundation |
|
1867 return _inclined_tileh[f - 15]; // inclined foundation |
|
1868 } else { |
|
1869 return SLOPE_FLAT; |
|
1870 } |
|
1871 } |
1846 } |
1872 |
1847 |
1873 static void GetAcceptedCargo_Track(TileIndex tile, AcceptedCargo ac) |
1848 static void GetAcceptedCargo_Track(TileIndex tile, AcceptedCargo ac) |
1874 { |
1849 { |
1875 /* not used */ |
1850 /* not used */ |