213 /* Get higher track */ |
213 /* Get higher track */ |
214 Corner highest_corner = GetHighestSlopeCorner(tileh); |
214 Corner highest_corner = GetHighestSlopeCorner(tileh); |
215 TrackBits higher_track = CornerToTrackBits(highest_corner); |
215 TrackBits higher_track = CornerToTrackBits(highest_corner); |
216 |
216 |
217 /* Only higher track? */ |
217 /* Only higher track? */ |
218 if (bits == higher_track) return FOUNDATION_STEEP_HIGHER; |
218 if (bits == higher_track) return HalftileFoundation(highest_corner); |
219 |
219 |
220 /* Overlap with higher track? */ |
220 /* Overlap with higher track? */ |
221 if (TracksOverlap(bits | higher_track)) return FOUNDATION_INVALID; |
221 if (TracksOverlap(bits | higher_track)) return FOUNDATION_INVALID; |
222 |
222 |
223 /* either lower track or both higher and lower track */ |
223 /* either lower track or both higher and lower track */ |
224 return ((bits & higher_track) != 0 ? FOUNDATION_INVALID : FOUNDATION_STEEP_LOWER); |
224 return ((bits & higher_track) != 0 ? FOUNDATION_STEEP_BOTH : FOUNDATION_STEEP_LOWER); |
225 } else { |
225 } else { |
226 if ((~_valid_tracks_without_foundation[tileh] & bits) == 0) return FOUNDATION_NONE; |
226 if ((~_valid_tracks_without_foundation[tileh] & bits) == 0) return FOUNDATION_NONE; |
227 |
227 |
228 bool valid_on_leveled = ((~_valid_tracks_on_leveled_foundation[tileh] & bits) == 0); |
228 bool valid_on_leveled = ((~_valid_tracks_on_leveled_foundation[tileh] & bits) == 0); |
229 |
229 |
|
230 Corner track_corner; |
230 switch (bits) { |
231 switch (bits) { |
|
232 case TRACK_BIT_LEFT: track_corner = CORNER_W; break; |
|
233 case TRACK_BIT_LOWER: track_corner = CORNER_S; break; |
|
234 case TRACK_BIT_RIGHT: track_corner = CORNER_E; break; |
|
235 case TRACK_BIT_UPPER: track_corner = CORNER_N; break; |
|
236 |
|
237 case TRACK_BIT_HORZ: |
|
238 if (tileh == SLOPE_N) return HalftileFoundation(CORNER_N); |
|
239 if (tileh == SLOPE_S) return HalftileFoundation(CORNER_S); |
|
240 return (valid_on_leveled ? FOUNDATION_LEVELED : FOUNDATION_INVALID); |
|
241 |
|
242 case TRACK_BIT_VERT: |
|
243 if (tileh == SLOPE_W) return HalftileFoundation(CORNER_W); |
|
244 if (tileh == SLOPE_E) return HalftileFoundation(CORNER_E); |
|
245 return (valid_on_leveled ? FOUNDATION_LEVELED : FOUNDATION_INVALID); |
|
246 |
231 case TRACK_BIT_X: |
247 case TRACK_BIT_X: |
232 if (HasSlopeHighestCorner(tileh)) return FOUNDATION_INCLINED_X; |
248 if (HasSlopeHighestCorner(tileh)) return FOUNDATION_INCLINED_X; |
233 return (valid_on_leveled ? FOUNDATION_LEVELED : FOUNDATION_INVALID); |
249 return (valid_on_leveled ? FOUNDATION_LEVELED : FOUNDATION_INVALID); |
234 |
250 |
235 case TRACK_BIT_Y: |
251 case TRACK_BIT_Y: |
1420 * @param track TrackBits to draw |
1449 * @param track TrackBits to draw |
1421 */ |
1450 */ |
1422 static void DrawTrackBits(TileInfo* ti, TrackBits track) |
1451 static void DrawTrackBits(TileInfo* ti, TrackBits track) |
1423 { |
1452 { |
1424 const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile)); |
1453 const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile)); |
|
1454 RailGroundType rgt = GetRailGroundType(ti->tile); |
|
1455 Foundation f = GetRailFoundation(ti->tileh, track); |
|
1456 Corner halftile_corner = CORNER_INVALID; |
|
1457 |
|
1458 if (IsNonContinuousFoundation(f)) { |
|
1459 /* Save halftile corner */ |
|
1460 halftile_corner = (f == FOUNDATION_STEEP_BOTH ? GetHighestSlopeCorner(ti->tileh) : GetHalftileFoundationCorner(f)); |
|
1461 /* Draw lower part first */ |
|
1462 track &= ~CornerToTrackBits(halftile_corner); |
|
1463 f = (f == FOUNDATION_STEEP_BOTH ? FOUNDATION_STEEP_LOWER : FOUNDATION_NONE); |
|
1464 } |
|
1465 |
|
1466 DrawFoundation(ti, f); |
|
1467 /* DrawFoundation modifies ti */ |
|
1468 |
1425 SpriteID image; |
1469 SpriteID image; |
1426 SpriteID pal = PAL_NONE; |
1470 SpriteID pal = PAL_NONE; |
1427 bool junction = false; |
1471 bool junction = false; |
1428 |
1472 |
1429 /* Select the sprite to use. */ |
1473 /* Select the sprite to use. */ |
1430 (image = rti->base_sprites.track_y, track == TRACK_BIT_Y) || |
1474 if (track == 0) { |
1431 (image++, track == TRACK_BIT_X) || |
1475 /* Clear ground (only track on halftile foundation) */ |
1432 (image++, track == TRACK_BIT_UPPER) || |
1476 switch (rgt) { |
1433 (image++, track == TRACK_BIT_LOWER) || |
1477 case RAIL_GROUND_BARREN: image = SPR_FLAT_BARE_LAND; break; |
1434 (image++, track == TRACK_BIT_RIGHT) || |
1478 case RAIL_GROUND_ICE_DESERT: image = SPR_FLAT_SNOWY_TILE; break; |
1435 (image++, track == TRACK_BIT_LEFT) || |
1479 default: image = SPR_FLAT_GRASS_TILE; break; |
1436 (image++, track == TRACK_BIT_CROSS) || |
1480 } |
1437 |
1481 image += _tileh_to_sprite[ti->tileh]; |
1438 (image = rti->base_sprites.track_ns, track == TRACK_BIT_HORZ) || |
1482 } else { |
1439 (image++, track == TRACK_BIT_VERT) || |
1483 if (ti->tileh != SLOPE_FLAT) { |
1440 |
1484 /* track on non-flat ground */ |
1441 (junction = true, false) || |
1485 image = _track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.track_y; |
1442 (image = rti->base_sprites.ground, (track & TRACK_BIT_3WAY_NE) == 0) || |
1486 } else { |
1443 (image++, (track & TRACK_BIT_3WAY_SW) == 0) || |
1487 /* track on flat ground */ |
1444 (image++, (track & TRACK_BIT_3WAY_NW) == 0) || |
1488 (image = rti->base_sprites.track_y, track == TRACK_BIT_Y) || |
1445 (image++, (track & TRACK_BIT_3WAY_SE) == 0) || |
1489 (image++, track == TRACK_BIT_X) || |
1446 (image++, true); |
1490 (image++, track == TRACK_BIT_UPPER) || |
1447 |
1491 (image++, track == TRACK_BIT_LOWER) || |
1448 if (ti->tileh != SLOPE_FLAT) { |
1492 (image++, track == TRACK_BIT_RIGHT) || |
1449 DrawFoundation(ti, GetRailFoundation(ti->tileh, track)); |
1493 (image++, track == TRACK_BIT_LEFT) || |
1450 |
1494 (image++, track == TRACK_BIT_CROSS) || |
1451 /* DrawFoundation() modifies it. |
1495 |
1452 * Default sloped sprites.. */ |
1496 (image = rti->base_sprites.track_ns, track == TRACK_BIT_HORZ) || |
1453 if (ti->tileh != SLOPE_FLAT) image = _track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.track_y; |
1497 (image++, track == TRACK_BIT_VERT) || |
1454 } |
1498 |
1455 |
1499 (junction = true, false) || |
1456 switch (GetRailGroundType(ti->tile)) { |
1500 (image = rti->base_sprites.ground, (track & TRACK_BIT_3WAY_NE) == 0) || |
1457 case RAIL_GROUND_BARREN: pal = PALETTE_TO_BARE_LAND; break; |
1501 (image++, (track & TRACK_BIT_3WAY_SW) == 0) || |
1458 case RAIL_GROUND_ICE_DESERT: image += rti->snow_offset; break; |
1502 (image++, (track & TRACK_BIT_3WAY_NW) == 0) || |
1459 default: break; |
1503 (image++, (track & TRACK_BIT_3WAY_SE) == 0) || |
|
1504 (image++, true); |
|
1505 } |
|
1506 |
|
1507 switch (rgt) { |
|
1508 case RAIL_GROUND_BARREN: pal = PALETTE_TO_BARE_LAND; break; |
|
1509 case RAIL_GROUND_ICE_DESERT: image += rti->snow_offset; break; |
|
1510 default: break; |
|
1511 } |
1460 } |
1512 } |
1461 |
1513 |
1462 DrawGroundSprite(image, pal); |
1514 DrawGroundSprite(image, pal); |
1463 |
1515 |
1464 /* Draw track pieces individually for junction tiles */ |
1516 /* Draw track pieces individually for junction tiles */ |
1467 if (track & TRACK_BIT_Y) DrawGroundSprite(rti->base_sprites.single_x, PAL_NONE); |
1519 if (track & TRACK_BIT_Y) DrawGroundSprite(rti->base_sprites.single_x, PAL_NONE); |
1468 if (track & TRACK_BIT_UPPER) DrawGroundSprite(rti->base_sprites.single_n, PAL_NONE); |
1520 if (track & TRACK_BIT_UPPER) DrawGroundSprite(rti->base_sprites.single_n, PAL_NONE); |
1469 if (track & TRACK_BIT_LOWER) DrawGroundSprite(rti->base_sprites.single_s, PAL_NONE); |
1521 if (track & TRACK_BIT_LOWER) DrawGroundSprite(rti->base_sprites.single_s, PAL_NONE); |
1470 if (track & TRACK_BIT_LEFT) DrawGroundSprite(rti->base_sprites.single_w, PAL_NONE); |
1522 if (track & TRACK_BIT_LEFT) DrawGroundSprite(rti->base_sprites.single_w, PAL_NONE); |
1471 if (track & TRACK_BIT_RIGHT) DrawGroundSprite(rti->base_sprites.single_e, PAL_NONE); |
1523 if (track & TRACK_BIT_RIGHT) DrawGroundSprite(rti->base_sprites.single_e, PAL_NONE); |
|
1524 } |
|
1525 |
|
1526 if (IsValidCorner(halftile_corner)) { |
|
1527 DrawFoundation(ti, HalftileFoundation(halftile_corner)); |
|
1528 |
|
1529 /* Draw higher halftile-overlay: Use the sloped sprites with three corners raised. They probably best fit the lightning. */ |
|
1530 Slope fake_slope = SlopeWithThreeCornersRaised(OppositeCorner(halftile_corner)); |
|
1531 image = _track_sloped_sprites[fake_slope - 1] + rti->base_sprites.track_y; |
|
1532 pal = PAL_NONE; |
|
1533 switch (rgt) { |
|
1534 case RAIL_GROUND_BARREN: pal = PALETTE_TO_BARE_LAND; break; |
|
1535 case RAIL_GROUND_ICE_DESERT: image += rti->snow_offset; break; |
|
1536 default: break; |
|
1537 } |
|
1538 |
|
1539 static const int INF = 1000; // big number compared to tilesprite size |
|
1540 static const SubSprite _halftile_sub_sprite[4] = { |
|
1541 { -INF , -INF , 32 - 33, INF }, // CORNER_W, clip 33 pixels from right |
|
1542 { -INF , 0 + 7, INF , INF }, // CORNER_S, clip 7 pixels from top |
|
1543 { -31 + 33, -INF , INF , INF }, // CORNER_E, clip 33 pixels from left |
|
1544 { -INF , -INF , INF , 30 - 23 } // CORNER_N, clip 23 pixels from bottom |
|
1545 }; |
|
1546 |
|
1547 DrawGroundSprite(image, pal, &(_halftile_sub_sprite[halftile_corner])); |
1472 } |
1548 } |
1473 } |
1549 } |
1474 |
1550 |
1475 static void DrawSignals(TileIndex tile, TrackBits rails) |
1551 static void DrawSignals(TileIndex tile, TrackBits rails) |
1476 { |
1552 { |
2287 |
2363 |
2288 /* First test autoslope. However if it succeeds we still have to test the rest, because non-autoslope terraforming is cheaper. */ |
2364 /* First test autoslope. However if it succeeds we still have to test the rest, because non-autoslope terraforming is cheaper. */ |
2289 CommandCost autoslope_result = TestAutoslopeOnRailTile(tile, flags, z_old, tileh_old, z_new, tileh_new, rail_bits); |
2365 CommandCost autoslope_result = TestAutoslopeOnRailTile(tile, flags, z_old, tileh_old, z_new, tileh_new, rail_bits); |
2290 |
2366 |
2291 /* When there is only a single horizontal/vertical track, one corner can be terraformed. */ |
2367 /* When there is only a single horizontal/vertical track, one corner can be terraformed. */ |
2292 Slope allowed_corner; |
2368 Corner allowed_corner; |
2293 switch (rail_bits) { |
2369 switch (rail_bits) { |
2294 case TRACK_BIT_RIGHT: allowed_corner = SLOPE_W; break; |
2370 case TRACK_BIT_RIGHT: allowed_corner = CORNER_W; break; |
2295 case TRACK_BIT_UPPER: allowed_corner = SLOPE_S; break; |
2371 case TRACK_BIT_UPPER: allowed_corner = CORNER_S; break; |
2296 case TRACK_BIT_LEFT: allowed_corner = SLOPE_E; break; |
2372 case TRACK_BIT_LEFT: allowed_corner = CORNER_E; break; |
2297 case TRACK_BIT_LOWER: allowed_corner = SLOPE_N; break; |
2373 case TRACK_BIT_LOWER: allowed_corner = CORNER_N; break; |
2298 default: return autoslope_result; |
2374 default: return autoslope_result; |
2299 } |
2375 } |
2300 |
2376 |
2301 Slope track_corners = ComplementSlope(allowed_corner); |
|
2302 |
|
2303 Foundation f_old = GetRailFoundation(tileh_old, rail_bits); |
2377 Foundation f_old = GetRailFoundation(tileh_old, rail_bits); |
2304 switch (f_old) { |
2378 |
2305 case FOUNDATION_NONE: |
2379 /* Do not allow terraforming if allowed_corner is part of anti-zig-zag foundations */ |
2306 /* Everything is valid, which only changes allowed_corner */ |
2380 if (tileh_old != SLOPE_NS && tileh_old != SLOPE_EW && IsSpecialRailFoundation(f_old)) return autoslope_result; |
2307 |
2381 |
2308 /* Compute height of track */ |
2382 /* Everything is valid, which only changes allowed_corner */ |
2309 if (tileh_old == track_corners) z_old += TILE_HEIGHT; |
2383 for (Corner corner = (Corner)0; corner < CORNER_END; corner = (Corner)(corner + 1)) { |
2310 if (tileh_new == track_corners) { |
2384 if (allowed_corner == corner) continue; |
2311 z_new += TILE_HEIGHT; |
2385 if (z_old + GetSlopeZInCorner(tileh_old, corner) != z_new + GetSlopeZInCorner(tileh_new, corner)) return autoslope_result; |
2312 } else { |
|
2313 /* do not build a foundation */ |
|
2314 if ((tileh_new != SLOPE_FLAT) && (tileh_new != allowed_corner)) return autoslope_result; |
|
2315 } |
|
2316 |
|
2317 /* Track height must remain unchanged */ |
|
2318 if (z_old != z_new) return autoslope_result; |
|
2319 break; |
|
2320 |
|
2321 case FOUNDATION_LEVELED: |
|
2322 /* Is allowed_corner covered by the foundation? */ |
|
2323 if ((tileh_old & allowed_corner) == 0) return autoslope_result; |
|
2324 |
|
2325 /* allowed_corner may only be raised -> steep slope */ |
|
2326 if ((z_old != z_new) || (tileh_new != (tileh_old | SLOPE_STEEP))) return autoslope_result; |
|
2327 break; |
|
2328 |
|
2329 case FOUNDATION_STEEP_LOWER: |
|
2330 /* Only allow to lower highest corner */ |
|
2331 if ((z_old != z_new) || (tileh_new != (tileh_old & ~SLOPE_STEEP))) return autoslope_result; |
|
2332 break; |
|
2333 |
|
2334 case FOUNDATION_STEEP_HIGHER: |
|
2335 return autoslope_result; |
|
2336 |
|
2337 default: NOT_REACHED(); |
|
2338 } |
2386 } |
2339 |
2387 |
2340 /* Make the ground dirty */ |
2388 /* Make the ground dirty */ |
2341 if ((flags & DC_EXEC) != 0) SetRailGroundType(tile, RAIL_GROUND_BARREN); |
2389 if ((flags & DC_EXEC) != 0) SetRailGroundType(tile, RAIL_GROUND_BARREN); |
2342 |
2390 |