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