44 #include "table/strings.h"
60 if (_bridge[i].sprite_table != NULL) {
61 for (
BridgePieces j = BRIDGE_PIECE_NORTH; j < BRIDGE_PIECE_INVALID; j++)
free(_bridge[i].sprite_table[j]);
62 free(_bridge[i].sprite_table);
67 memset(&_bridge, 0,
sizeof(_bridge));
69 memcpy(&_bridge, &_orig_bridge,
sizeof(_orig_bridge));
80 if (length < 2)
return length;
84 for (
int delta = 1;; delta++) {
85 for (
int count = 0; count < delta; count++) {
86 if (length == 0)
return sum;
125 assert(table < BRIDGE_PIECE_INVALID);
127 return _bridge_sprite_table[index][table];
225 TransportType transport_type = Extract<TransportType, 15, 2>(p2);
228 switch (transport_type) {
230 roadtypes = Extract<RoadTypes, 8, 2>(p2);
235 railtype = Extract<RailType, 8, 4>(p2);
261 if (tile_start == tile_end) {
268 }
else if (
TileY(tile_start) ==
TileY(tile_end)) {
274 if (tile_end < tile_start)
Swap(tile_start, tile_end);
280 if (ret.
Failed())
return ret;
289 bool pbs_reservation =
false;
296 if (z_start != z_end)
return_cmd_error(STR_ERROR_BRIDGEHEADS_NOT_SAME_HEIGHT);
314 _game_mode != GM_EDITOR) {
335 cost.
AddCost((bridge_len + 1) * _price[PR_CLEAR_BRIDGE]);
340 if (is_new_owner) owner = company;
342 switch (transport_type) {
362 if (ret.
Failed())
return ret;
365 if (terraform_cost_north.
Failed() || (terraform_cost_north.
GetCost() != 0 && !allow_on_slopes))
return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
366 cost.
AddCost(terraform_cost_north);
370 if (ret.
Failed())
return ret;
374 if (terraform_cost_south.
Failed() || (terraform_cost_south.
GetCost() != 0 && !allow_on_slopes))
return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
375 cost.
AddCost(terraform_cost_south);
377 const TileIndex heads[] = {tile_start, tile_end};
378 for (
int i = 0; i < 2; i++) {
391 for (
TileIndex tile = tile_start + delta; tile != tile_end; tile += delta) {
442 if (ret.
Failed())
return ret;
464 switch (transport_type) {
489 Owner owner_road = owner;
490 Owner owner_tram = owner;
493 MakeRoadBridgeRamp(tile_start, owner, owner_road, owner_tram, bridge_type, dir, roadtypes);
510 for (
TileIndex tile = tile_start; tile <= tile_end; tile += delta) {
530 switch (transport_type) {
539 cost.
AddCost((int64)bridge_len * _price[PR_BUILD_BRIDGE] *
GetBridgeSpec(bridge_type)->price >> 8);
542 cost.
AddCost((int64)bridge_len * _price[PR_BUILD_AQUEDUCT]);
565 TransportType transport_type = Extract<TransportType, 8, 2>(p1);
570 switch (transport_type) {
572 railtype = Extract<RailType, 0, 4>(p1);
577 rts = Extract<RoadTypes, 0, 2>(p1);
605 if (ret.
Failed())
return ret;
636 if (start_z == end_z)
break;
643 if (tiles == tiles_bump) {
648 cost.
AddCost(_price[PR_BUILD_TUNNEL]);
653 cost.
AddCost(_price[PR_BUILD_TUNNEL]);
674 coa = _cleared_object_areas.Append();
687 cost.
AddCost(_price[PR_BUILD_TUNNEL]);
690 switch (transport_type) {
693 default: NOT_REACHED();
764 default: NOT_REACHED();
777 if (ret.
Failed())
return ret;
782 if (ret.
Failed())
return ret;
793 if (ret.
Failed())
return ret;
823 DoClearSquare(endtile);
845 DoClearSquare(endtile);
861 if (ret.
Failed())
return ret;
866 if (ret.
Failed())
return ret;
878 if (ret.
Failed())
return ret;
921 DoClearSquare(endtile);
922 for (
TileIndex c = tile + delta; c != endtile; c += delta) {
978 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);
995 for (cur_z = z_top; cur_z >= z_bottom; cur_z -=
TILE_HEIGHT) {
1014 static const int bounding_box_size[2] = {16, 2};
1015 static const int back_pillar_offset[2] = { 0, 9};
1017 static const int INF = 1000;
1018 static const SubSprite half_pillar_sub_sprite[2][2] = {
1019 { { -14, -INF, INF, INF }, { -INF, -INF, -15, INF } },
1020 { { -INF, -INF, 15, INF }, { 16, -INF, INF, INF } },
1023 if (psid->
sprite == 0)
return;
1027 int z_front_north = ti->
z;
1028 int z_back_north = ti->
z;
1029 int z_front_south = ti->
z;
1030 int z_back_south = ti->
z;
1035 int z_front =
max(z_front_north, z_front_south);
1036 int z_back =
max(z_back_north, z_back_south);
1039 int w = bounding_box_size[axis];
1040 int h = bounding_box_size[
OtherAxis(axis)];
1042 int x_back = x - back_pillar_offset[axis];
1043 int y_back = y - back_pillar_offset[
OtherAxis(axis)];
1047 if (z_front_north < z_front)
DrawPillar(psid, x, y, bottom_z, w, h, &half_pillar_sub_sprite[axis][0]);
1048 if (z_front_south < z_front)
DrawPillar(psid, x, y, bottom_z, w, h, &half_pillar_sub_sprite[axis][1]);
1051 int z_bridge_back = z_bridge - 2 * (int)
TILE_HEIGHT;
1052 if (drawfarpillar && (z_back_north <= z_bridge_back || z_back_south <= z_bridge_back)) {
1053 bottom_z =
DrawPillarColumn(z_back, z_bridge_back, psid, x_back, y_back, w, h);
1054 if (z_back_north < z_back)
DrawPillar(psid, x_back, y_back, bottom_z, w, h, &half_pillar_sub_sprite[axis][0]);
1055 if (z_back_south < z_back)
DrawPillar(psid, x_back, y_back, bottom_z, w, h, &half_pillar_sub_sprite[axis][1]);
1070 static const SpriteID tram_offsets[2][6] = { { 107, 108, 109, 110, 111, 112 }, { 4, 5, 15, 16, 17, 18 } };
1071 static const SpriteID back_offsets[6] = { 95, 96, 99, 102, 100, 101 };
1072 static const SpriteID front_offsets[6] = { 97, 98, 103, 106, 104, 105 };
1074 static const uint size_x[6] = { 1, 16, 16, 1, 16, 1 };
1075 static const uint size_y[6] = { 16, 1, 1, 16, 1, 16 };
1076 static const uint front_bb_offset_x[6] = { 15, 0, 0, 15, 0, 15 };
1077 static const uint front_bb_offset_y[6] = { 0, 15, 15, 0, 15, 0 };
1083 x, y, size_x[offset], size_y[offset], 0x28, z,
1090 x, y, size_x[offset], size_y[offset], 0x28, z,
1101 x, y, size_x[offset] + front_bb_offset_x[offset], size_y[offset] + front_bb_offset_y[offset], 0x28, z,
1134 static const int _tunnel_BB[4][12] = {
1137 { 1, 0, -15, -14, 0, 15, 16, 1, 0, 1, 16, 15 },
1138 { 0, 1, -14, -15, 15, 0, 1, 16, 1, 0, 15, 16 },
1139 { 1, 0, -15, -14, 0, 15, 16, 1, 0, 1, 16, 15 },
1140 { 0, 1, -14, -15, 15, 0, 1, 16, 1, 0, 15, 16 },
1142 const int *BB_data = _tunnel_BB[tunnelbridge_direction];
1144 bool catenary =
false;
1151 if (rti->UsesOverlay()) {
1157 image = SPR_TUNNEL_ENTRY_REAR_ROAD;
1162 image += tunnelbridge_direction * 2;
1169 static const SpriteID tunnel_sprites[2][4] = { { 28, 78, 79, 27 }, { 5, 76, 77, 4 } };
1177 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);
1182 if (rti->UsesOverlay()) {
1184 if (surface != 0)
DrawGroundSprite(surface + tunnelbridge_direction, PAL_NONE);
1205 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);
1207 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);
1223 assert(base_offset != 8);
1229 assert( (base_offset & 0x07) == 0x00);
1234 base_offset += (6 - tunnelbridge_direction) % 4;
1239 psid = &GetBridgeSpriteTable(
GetBridgeType(ti->
tile), BRIDGE_PIECE_HEAD)[base_offset];
1241 psid = _aqueduct_sprites + base_offset;
1247 DrawShoreTile(ti->
tileh);
1249 DrawClearLandTile(ti, 3);
1270 uint offset = tunnelbridge_direction;
1273 offset = (offset + 1) & 1;
1284 if (rti->UsesOverlay()) {
1339 return BRIDGE_PIECE_NORTH;
1340 }
else if (south == 1) {
1341 return BRIDGE_PIECE_SOUTH;
1342 }
else if (north < south) {
1343 return north & 1 ? BRIDGE_PIECE_INNER_SOUTH : BRIDGE_PIECE_INNER_NORTH;
1344 }
else if (north > south) {
1345 return south & 1 ? BRIDGE_PIECE_INNER_NORTH : BRIDGE_PIECE_INNER_SOUTH;
1347 return north & 1 ? BRIDGE_PIECE_MIDDLE_EVEN : BRIDGE_PIECE_MIDDLE_ODD;
1398 psid = base_offset + GetBridgeSpriteTable(type, piece);
1400 drawfarpillar =
true;
1401 psid = _aqueduct_sprites;
1404 if (axis !=
AXIS_X) psid += 4;
1420 AddSortableSpriteToDraw(psid->
sprite, psid->
pal, x, y, 16, 1, 0x28, z,
IsTransparencySet(
TO_BRIDGES), 0, 0, BRIDGE_Z_START);
1422 AddSortableSpriteToDraw(psid->
sprite, psid->
pal, x, y, 1, 16, 0x28, z,
IsTransparencySet(
TO_BRIDGES), 0, 0, BRIDGE_Z_START);
1457 if (psid->
sprite &
SPRITE_MASK)
AddSortableSpriteToDraw(psid->
sprite, psid->
pal, x, y, 16, 4, 0x28, z,
IsTransparencySet(
TO_BRIDGES), 0, 3, BRIDGE_Z_START);
1460 if (psid->
sprite &
SPRITE_MASK)
AddSortableSpriteToDraw(psid->
sprite, psid->
pal, x, y, 4, 16, 0x28, z,
IsTransparencySet(
TO_BRIDGES), 3, 0, BRIDGE_Z_START);
1471 if (ti->
z + 5 == z) {
1490 static int GetSlopePixelZ_TunnelBridge(
TileIndex tile, uint x, uint y)
1502 if (5 <= pos && pos <= 10)
return z;
1510 if (5 <= pos && pos <= 10) {
1516 default: NOT_REACHED();
1522 return z + 1 + delta;
1539 td->
str = (tt ==
TRANSPORT_RAIL) ? STR_LAI_TUNNEL_DESCRIPTION_RAILROAD : STR_LAI_TUNNEL_DESCRIPTION_ROAD;
1556 td->
owner_type[i] = STR_LAND_AREA_INFORMATION_ROAD_OWNER;
1557 td->
owner[i] = road_owner;
1561 td->
owner_type[i] = STR_LAND_AREA_INFORMATION_TRAM_OWNER;
1562 td->
owner[i] = tram_owner;
1572 if (td->
rail_speed == 0 || spd < td->rail_speed) {
1582 static void TileLoop_TunnelBridge(
TileIndex tile)
1620 static void ChangeTileOwner_TunnelBridge(
TileIndex tile,
Owner old_owner,
Owner new_owner)
1633 Company::Get(old_owner)->infrastructure.road[rt] -= num_pieces * 2;
1689 int z = GetSlopePixelZ(x, y) - v->
z_pos;
1708 SndPlayVehicleFx(SND_05_TRAIN_THROUGH_TUNNEL, v);
1712 if (frame == _tunnel_visibility_frame[dir]) {
1733 if (frame == _tunnel_visibility_frame[dir]) {
1735 assert(frame == rv->frame + 1);
1789 default: NOT_REACHED();
1823 default: NOT_REACHED();
1855 extern const TileTypeProcs _tile_type_tunnelbridge_procs = {
1857 GetSlopePixelZ_TunnelBridge,
1860 GetTileDesc_TunnelBridge,
1861 GetTileTrackStatus_TunnelBridge,
1864 TileLoop_TunnelBridge,
1865 ChangeTileOwner_TunnelBridge,
1867 VehicleEnter_TunnelBridge,
1868 GetFoundation_TunnelBridge,
1869 TerraformTile_TunnelBridge,