44 #include "table/strings.h"
67 for (
TileIndex t = begin; t != end; t += delta) {
87 if (_bridge[i].sprite_table != NULL) {
88 for (
BridgePieces j = BRIDGE_PIECE_NORTH; j < BRIDGE_PIECE_INVALID; j++)
free(_bridge[i].sprite_table[j]);
89 free(_bridge[i].sprite_table);
94 memset(&_bridge, 0,
sizeof(_bridge));
96 memcpy(&_bridge, &_orig_bridge,
sizeof(_orig_bridge));
107 if (length < 2)
return length;
111 for (
int delta = 1;; delta++) {
112 for (
int count = 0; count < delta; count++) {
113 if (length == 0)
return sum;
152 assert(table < BRIDGE_PIECE_INVALID);
154 return _bridge_sprite_table[index][table];
252 TransportType transport_type = Extract<TransportType, 15, 2>(p2);
255 switch (transport_type) {
257 roadtypes = Extract<RoadTypes, 8, 2>(p2);
262 railtype = Extract<RailType, 8, 4>(p2);
288 if (tile_start == tile_end) {
295 }
else if (
TileY(tile_start) ==
TileY(tile_end)) {
301 if (tile_end < tile_start)
Swap(tile_start, tile_end);
307 if (ret.
Failed())
return ret;
316 bool pbs_reservation =
false;
323 if (z_start != z_end)
return_cmd_error(STR_ERROR_BRIDGEHEADS_NOT_SAME_HEIGHT);
341 _game_mode != GM_EDITOR) {
362 cost.
AddCost((bridge_len + 1) * _price[PR_CLEAR_BRIDGE]);
367 if (is_new_owner) owner = company;
369 switch (transport_type) {
389 if (ret.
Failed())
return ret;
392 if (terraform_cost_north.
Failed() || (terraform_cost_north.
GetCost() != 0 && !allow_on_slopes))
return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
393 cost.
AddCost(terraform_cost_north);
397 if (ret.
Failed())
return ret;
401 if (terraform_cost_south.
Failed() || (terraform_cost_south.
GetCost() != 0 && !allow_on_slopes))
return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
402 cost.
AddCost(terraform_cost_south);
404 const TileIndex heads[] = {tile_start, tile_end};
405 for (
int i = 0; i < 2; i++) {
418 for (
TileIndex tile = tile_start + delta; tile != tile_end; tile += delta) {
469 if (ret.
Failed())
return ret;
491 switch (transport_type) {
516 Owner owner_road = owner;
517 Owner owner_tram = owner;
520 MakeRoadBridgeRamp(tile_start, owner, owner_road, owner_tram, bridge_type, dir, roadtypes);
554 switch (transport_type) {
563 cost.
AddCost((int64)bridge_len * _price[PR_BUILD_BRIDGE] *
GetBridgeSpec(bridge_type)->price >> 8);
566 cost.
AddCost((int64)bridge_len * _price[PR_BUILD_AQUEDUCT]);
589 TransportType transport_type = Extract<TransportType, 8, 2>(p1);
594 switch (transport_type) {
596 railtype = Extract<RailType, 0, 4>(p1);
601 rts = Extract<RoadTypes, 0, 2>(p1);
629 if (ret.
Failed())
return ret;
660 if (start_z == end_z)
break;
667 if (tiles == tiles_bump) {
672 cost.
AddCost(_price[PR_BUILD_TUNNEL]);
677 cost.
AddCost(_price[PR_BUILD_TUNNEL]);
698 coa = _cleared_object_areas.Append();
711 cost.
AddCost(_price[PR_BUILD_TUNNEL]);
714 switch (transport_type) {
717 default: NOT_REACHED();
788 default: NOT_REACHED();
801 if (ret.
Failed())
return ret;
806 if (ret.
Failed())
return ret;
817 if (ret.
Failed())
return ret;
847 DoClearSquare(endtile);
869 DoClearSquare(endtile);
885 if (ret.
Failed())
return ret;
890 if (ret.
Failed())
return ret;
902 if (ret.
Failed())
return ret;
945 DoClearSquare(endtile);
946 for (
TileIndex c = tile + delta; c != endtile; c += delta) {
1002 AddSortableSpriteToDraw(psid->
sprite, psid->
pal, x, y, w, h,
BB_HEIGHT_UNDER_BRIDGE - PILLAR_Z_OFFSET, z,
IsTransparencySet(
TO_BRIDGES), 0, 0, -PILLAR_Z_OFFSET, subsprite);
1019 for (cur_z = z_top; cur_z >= z_bottom; cur_z -=
TILE_HEIGHT) {
1038 static const int bounding_box_size[2] = {16, 2};
1039 static const int back_pillar_offset[2] = { 0, 9};
1041 static const int INF = 1000;
1042 static const SubSprite half_pillar_sub_sprite[2][2] = {
1043 { { -14, -INF, INF, INF }, { -INF, -INF, -15, INF } },
1044 { { -INF, -INF, 15, INF }, { 16, -INF, INF, INF } },
1047 if (psid->
sprite == 0)
return;
1051 int z_front_north = ti->
z;
1052 int z_back_north = ti->
z;
1053 int z_front_south = ti->
z;
1054 int z_back_south = ti->
z;
1059 int z_front =
max(z_front_north, z_front_south);
1060 int z_back =
max(z_back_north, z_back_south);
1063 int w = bounding_box_size[axis];
1064 int h = bounding_box_size[
OtherAxis(axis)];
1066 int x_back = x - back_pillar_offset[axis];
1067 int y_back = y - back_pillar_offset[
OtherAxis(axis)];
1071 if (z_front_north < z_front)
DrawPillar(psid, x, y, bottom_z, w, h, &half_pillar_sub_sprite[axis][0]);
1072 if (z_front_south < z_front)
DrawPillar(psid, x, y, bottom_z, w, h, &half_pillar_sub_sprite[axis][1]);
1075 int z_bridge_back = z_bridge - 2 * (int)
TILE_HEIGHT;
1076 if (drawfarpillar && (z_back_north <= z_bridge_back || z_back_south <= z_bridge_back)) {
1077 bottom_z =
DrawPillarColumn(z_back, z_bridge_back, psid, x_back, y_back, w, h);
1078 if (z_back_north < z_back)
DrawPillar(psid, x_back, y_back, bottom_z, w, h, &half_pillar_sub_sprite[axis][0]);
1079 if (z_back_south < z_back)
DrawPillar(psid, x_back, y_back, bottom_z, w, h, &half_pillar_sub_sprite[axis][1]);
1094 static const SpriteID tram_offsets[2][6] = { { 107, 108, 109, 110, 111, 112 }, { 4, 5, 15, 16, 17, 18 } };
1095 static const SpriteID back_offsets[6] = { 95, 96, 99, 102, 100, 101 };
1096 static const SpriteID front_offsets[6] = { 97, 98, 103, 106, 104, 105 };
1098 static const uint size_x[6] = { 1, 16, 16, 1, 16, 1 };
1099 static const uint size_y[6] = { 16, 1, 1, 16, 1, 16 };
1100 static const uint front_bb_offset_x[6] = { 15, 0, 0, 15, 0, 15 };
1101 static const uint front_bb_offset_y[6] = { 0, 15, 15, 0, 15, 0 };
1107 x, y, size_x[offset], size_y[offset], 0x28, z,
1114 x, y, size_x[offset], size_y[offset], 0x28, z,
1125 x, y, size_x[offset] + front_bb_offset_x[offset], size_y[offset] + front_bb_offset_y[offset], 0x28, z,
1158 static const int _tunnel_BB[4][12] = {
1161 { 1, 0, -15, -14, 0, 15, 16, 1, 0, 1, 16, 15 },
1162 { 0, 1, -14, -15, 15, 0, 1, 16, 1, 0, 15, 16 },
1163 { 1, 0, -15, -14, 0, 15, 16, 1, 0, 1, 16, 15 },
1164 { 0, 1, -14, -15, 15, 0, 1, 16, 1, 0, 15, 16 },
1166 const int *BB_data = _tunnel_BB[tunnelbridge_direction];
1168 bool catenary =
false;
1175 if (rti->UsesOverlay()) {
1181 image = SPR_TUNNEL_ENTRY_REAR_ROAD;
1186 image += tunnelbridge_direction * 2;
1193 static const SpriteID tunnel_sprites[2][4] = { { 28, 78, 79, 27 }, { 5, 76, 77, 4 } };
1201 AddSortableSpriteToDraw(SPR_TRAMWAY_TUNNEL_WIRES + tunnelbridge_direction, PAL_NONE, ti->
x, ti->
y, BB_data[10], BB_data[11],
TILE_HEIGHT, ti->
z,
IsTransparencySet(
TO_CATENARY), BB_data[8], BB_data[9],
BB_Z_SEPARATOR);
1206 if (rti->UsesOverlay()) {
1208 if (surface != 0)
DrawGroundSprite(surface + tunnelbridge_direction, PAL_NONE);
1229 AddSortableSpriteToDraw(image + 1, PAL_NONE, ti->
x +
TILE_SIZE - 1, ti->
y +
TILE_SIZE - 1, BB_data[0], BB_data[1],
TILE_HEIGHT, ti->
z,
false, BB_data[2], BB_data[3],
BB_Z_SEPARATOR);
1231 if (railtype_overlay != 0)
AddSortableSpriteToDraw(railtype_overlay + tunnelbridge_direction, PAL_NONE, ti->
x +
TILE_SIZE - 1, ti->
y +
TILE_SIZE - 1, BB_data[0], BB_data[1],
TILE_HEIGHT, ti->
z,
false, BB_data[2], BB_data[3],
BB_Z_SEPARATOR);
1247 assert(base_offset != 8);
1253 assert( (base_offset & 0x07) == 0x00);
1258 base_offset += (6 - tunnelbridge_direction) % 4;
1263 psid = &GetBridgeSpriteTable(
GetBridgeType(ti->
tile), BRIDGE_PIECE_HEAD)[base_offset];
1265 psid = _aqueduct_sprites + base_offset;
1271 DrawShoreTile(ti->
tileh);
1273 DrawClearLandTile(ti, 3);
1294 uint offset = tunnelbridge_direction;
1297 offset = (offset + 1) & 1;
1308 if (rti->UsesOverlay()) {
1363 return BRIDGE_PIECE_NORTH;
1364 }
else if (south == 1) {
1365 return BRIDGE_PIECE_SOUTH;
1366 }
else if (north < south) {
1367 return north & 1 ? BRIDGE_PIECE_INNER_SOUTH : BRIDGE_PIECE_INNER_NORTH;
1368 }
else if (north > south) {
1369 return south & 1 ? BRIDGE_PIECE_INNER_NORTH : BRIDGE_PIECE_INNER_SOUTH;
1371 return north & 1 ? BRIDGE_PIECE_MIDDLE_EVEN : BRIDGE_PIECE_MIDDLE_ODD;
1422 psid = base_offset + GetBridgeSpriteTable(type, piece);
1424 drawfarpillar =
true;
1425 psid = _aqueduct_sprites;
1428 if (axis !=
AXIS_X) psid += 4;
1444 AddSortableSpriteToDraw(psid->
sprite, psid->
pal, x, y, 16, 1, 0x28, z,
IsTransparencySet(
TO_BRIDGES), 0, 0, BRIDGE_Z_START);
1446 AddSortableSpriteToDraw(psid->
sprite, psid->
pal, x, y, 1, 16, 0x28, z,
IsTransparencySet(
TO_BRIDGES), 0, 0, BRIDGE_Z_START);
1481 if (psid->
sprite &
SPRITE_MASK)
AddSortableSpriteToDraw(psid->
sprite, psid->
pal, x, y, 16, 4, 0x28, z,
IsTransparencySet(
TO_BRIDGES), 0, 3, BRIDGE_Z_START);
1484 if (psid->
sprite &
SPRITE_MASK)
AddSortableSpriteToDraw(psid->
sprite, psid->
pal, x, y, 4, 16, 0x28, z,
IsTransparencySet(
TO_BRIDGES), 3, 0, BRIDGE_Z_START);
1495 if (ti->
z + 5 == z) {
1514 static int GetSlopePixelZ_TunnelBridge(
TileIndex tile, uint x, uint y)
1526 if (5 <= pos && pos <= 10)
return z;
1534 if (5 <= pos && pos <= 10) {
1540 default: NOT_REACHED();
1546 return z + 1 + delta;
1563 td->
str = (tt ==
TRANSPORT_RAIL) ? STR_LAI_TUNNEL_DESCRIPTION_RAILROAD : STR_LAI_TUNNEL_DESCRIPTION_ROAD;
1580 td->
owner_type[i] = STR_LAND_AREA_INFORMATION_ROAD_OWNER;
1581 td->
owner[i] = road_owner;
1585 td->
owner_type[i] = STR_LAND_AREA_INFORMATION_TRAM_OWNER;
1586 td->
owner[i] = tram_owner;
1596 if (td->
rail_speed == 0 || spd < td->rail_speed) {
1606 static void TileLoop_TunnelBridge(
TileIndex tile)
1644 static void ChangeTileOwner_TunnelBridge(
TileIndex tile,
Owner old_owner,
Owner new_owner)
1657 Company::Get(old_owner)->infrastructure.road[rt] -= num_pieces * 2;
1713 int z = GetSlopePixelZ(x, y) - v->
z_pos;
1732 SndPlayVehicleFx(SND_05_TRAIN_THROUGH_TUNNEL, v);
1736 if (frame == _tunnel_visibility_frame[dir]) {
1757 if (frame == _tunnel_visibility_frame[dir]) {
1759 assert(frame == rv->frame + 1);
1813 default: NOT_REACHED();
1847 default: NOT_REACHED();
1879 extern const TileTypeProcs _tile_type_tunnelbridge_procs = {
1881 GetSlopePixelZ_TunnelBridge,
1884 GetTileDesc_TunnelBridge,
1885 GetTileTrackStatus_TunnelBridge,
1888 TileLoop_TunnelBridge,
1889 ChangeTileOwner_TunnelBridge,
1891 VehicleEnter_TunnelBridge,
1892 GetFoundation_TunnelBridge,
1893 TerraformTile_TunnelBridge,