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) {
518 MakeRoadBridgeRamp(tile_start, owner, owner_road, owner_tram, bridge_type, dir, roadtypes);
552 switch (transport_type) {
561 cost.
AddCost((int64)bridge_len * _price[PR_BUILD_BRIDGE] *
GetBridgeSpec(bridge_type)->price >> 8);
564 cost.
AddCost((int64)bridge_len * _price[PR_BUILD_AQUEDUCT]);
587 TransportType transport_type = Extract<TransportType, 8, 2>(p1);
592 switch (transport_type) {
594 railtype = Extract<RailType, 0, 4>(p1);
599 rts = Extract<RoadTypes, 0, 2>(p1);
627 if (ret.
Failed())
return ret;
658 if (start_z == end_z)
break;
665 if (tiles == tiles_bump) {
670 cost.
AddCost(_price[PR_BUILD_TUNNEL]);
675 cost.
AddCost(_price[PR_BUILD_TUNNEL]);
696 coa = _cleared_object_areas.Append();
709 cost.
AddCost(_price[PR_BUILD_TUNNEL]);
712 switch (transport_type) {
715 default: NOT_REACHED();
786 default: NOT_REACHED();
799 if (ret.
Failed())
return ret;
804 if (ret.
Failed())
return ret;
815 if (ret.
Failed())
return ret;
845 DoClearSquare(endtile);
867 DoClearSquare(endtile);
883 if (ret.
Failed())
return ret;
888 if (ret.
Failed())
return ret;
900 if (ret.
Failed())
return ret;
943 DoClearSquare(endtile);
944 for (
TileIndex c = tile + delta; c != endtile; c += delta) {
1000 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);
1017 for (cur_z = z_top; cur_z >= z_bottom; cur_z -=
TILE_HEIGHT) {
1036 static const int bounding_box_size[2] = {16, 2};
1037 static const int back_pillar_offset[2] = { 0, 9};
1039 static const int INF = 1000;
1040 static const SubSprite half_pillar_sub_sprite[2][2] = {
1041 { { -14, -INF, INF, INF }, { -INF, -INF, -15, INF } },
1042 { { -INF, -INF, 15, INF }, { 16, -INF, INF, INF } },
1045 if (psid->
sprite == 0)
return;
1049 int z_front_north = ti->
z;
1050 int z_back_north = ti->
z;
1051 int z_front_south = ti->
z;
1052 int z_back_south = ti->
z;
1057 int z_front =
max(z_front_north, z_front_south);
1058 int z_back =
max(z_back_north, z_back_south);
1061 int w = bounding_box_size[axis];
1062 int h = bounding_box_size[
OtherAxis(axis)];
1064 int x_back = x - back_pillar_offset[axis];
1065 int y_back = y - back_pillar_offset[
OtherAxis(axis)];
1069 if (z_front_north < z_front)
DrawPillar(psid, x, y, bottom_z, w, h, &half_pillar_sub_sprite[axis][0]);
1070 if (z_front_south < z_front)
DrawPillar(psid, x, y, bottom_z, w, h, &half_pillar_sub_sprite[axis][1]);
1073 int z_bridge_back = z_bridge - 2 * (int)
TILE_HEIGHT;
1074 if (drawfarpillar && (z_back_north <= z_bridge_back || z_back_south <= z_bridge_back)) {
1075 bottom_z =
DrawPillarColumn(z_back, z_bridge_back, psid, x_back, y_back, w, h);
1076 if (z_back_north < z_back)
DrawPillar(psid, x_back, y_back, bottom_z, w, h, &half_pillar_sub_sprite[axis][0]);
1077 if (z_back_south < z_back)
DrawPillar(psid, x_back, y_back, bottom_z, w, h, &half_pillar_sub_sprite[axis][1]);
1092 static const SpriteID tram_offsets[2][6] = { { 107, 108, 109, 110, 111, 112 }, { 4, 5, 15, 16, 17, 18 } };
1093 static const SpriteID back_offsets[6] = { 95, 96, 99, 102, 100, 101 };
1094 static const SpriteID front_offsets[6] = { 97, 98, 103, 106, 104, 105 };
1096 static const uint size_x[6] = { 1, 16, 16, 1, 16, 1 };
1097 static const uint size_y[6] = { 16, 1, 1, 16, 1, 16 };
1098 static const uint front_bb_offset_x[6] = { 15, 0, 0, 15, 0, 15 };
1099 static const uint front_bb_offset_y[6] = { 0, 15, 15, 0, 15, 0 };
1105 x, y, size_x[offset], size_y[offset], 0x28, z,
1112 x, y, size_x[offset], size_y[offset], 0x28, z,
1123 x, y, size_x[offset] + front_bb_offset_x[offset], size_y[offset] + front_bb_offset_y[offset], 0x28, z,
1156 static const int _tunnel_BB[4][12] = {
1159 { 1, 0, -15, -14, 0, 15, 16, 1, 0, 1, 16, 15 },
1160 { 0, 1, -14, -15, 15, 0, 1, 16, 1, 0, 15, 16 },
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 },
1164 const int *BB_data = _tunnel_BB[tunnelbridge_direction];
1166 bool catenary =
false;
1173 if (rti->UsesOverlay()) {
1179 image = SPR_TUNNEL_ENTRY_REAR_ROAD;
1184 image += tunnelbridge_direction * 2;
1191 static const SpriteID tunnel_sprites[2][4] = { { 28, 78, 79, 27 }, { 5, 76, 77, 4 } };
1199 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);
1204 if (rti->UsesOverlay()) {
1206 if (surface != 0)
DrawGroundSprite(surface + tunnelbridge_direction, PAL_NONE);
1211 if (rti->UsesOverlay()) {
1232 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);
1234 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);
1250 assert(base_offset != 8);
1256 assert( (base_offset & 0x07) == 0x00);
1261 base_offset += (6 - tunnelbridge_direction) % 4;
1266 psid = &GetBridgeSpriteTable(
GetBridgeType(ti->
tile), BRIDGE_PIECE_HEAD)[base_offset];
1268 psid = _aqueduct_sprites + base_offset;
1274 DrawShoreTile(ti->
tileh);
1276 DrawClearLandTile(ti, 3);
1297 uint offset = tunnelbridge_direction;
1300 offset = (offset + 1) & 1;
1311 if (rti->UsesOverlay()) {
1327 if (rti->UsesOverlay()) {
1375 return BRIDGE_PIECE_NORTH;
1376 }
else if (south == 1) {
1377 return BRIDGE_PIECE_SOUTH;
1378 }
else if (north < south) {
1379 return north & 1 ? BRIDGE_PIECE_INNER_SOUTH : BRIDGE_PIECE_INNER_NORTH;
1380 }
else if (north > south) {
1381 return south & 1 ? BRIDGE_PIECE_INNER_NORTH : BRIDGE_PIECE_INNER_SOUTH;
1383 return north & 1 ? BRIDGE_PIECE_MIDDLE_EVEN : BRIDGE_PIECE_MIDDLE_ODD;
1434 psid = base_offset + GetBridgeSpriteTable(type, piece);
1436 drawfarpillar =
true;
1437 psid = _aqueduct_sprites;
1440 if (axis !=
AXIS_X) psid += 4;
1456 AddSortableSpriteToDraw(psid->
sprite, psid->
pal, x, y, 16, 1, 0x28, z,
IsTransparencySet(
TO_BRIDGES), 0, 0, BRIDGE_Z_START);
1458 AddSortableSpriteToDraw(psid->
sprite, psid->
pal, x, y, 1, 16, 0x28, z,
IsTransparencySet(
TO_BRIDGES), 0, 0, BRIDGE_Z_START);
1484 if (rti->UsesOverlay()) {
1503 if (psid->
sprite &
SPRITE_MASK)
AddSortableSpriteToDraw(psid->
sprite, psid->
pal, x, y, 16, 4, 0x28, z,
IsTransparencySet(
TO_BRIDGES), 0, 3, BRIDGE_Z_START);
1506 if (psid->
sprite &
SPRITE_MASK)
AddSortableSpriteToDraw(psid->
sprite, psid->
pal, x, y, 4, 16, 0x28, z,
IsTransparencySet(
TO_BRIDGES), 3, 0, BRIDGE_Z_START);
1517 if (ti->
z + 5 == z) {
1536 static int GetSlopePixelZ_TunnelBridge(
TileIndex tile, uint x, uint y)
1548 if (5 <= pos && pos <= 10)
return z;
1556 if (5 <= pos && pos <= 10) {
1562 default: NOT_REACHED();
1568 return z + 1 + delta;
1585 td->
str = (tt ==
TRANSPORT_RAIL) ? STR_LAI_TUNNEL_DESCRIPTION_RAILROAD : STR_LAI_TUNNEL_DESCRIPTION_ROAD;
1602 td->
owner_type[i] = STR_LAND_AREA_INFORMATION_ROAD_OWNER;
1603 td->
owner[i] = road_owner;
1607 td->
owner_type[i] = STR_LAND_AREA_INFORMATION_TRAM_OWNER;
1608 td->
owner[i] = tram_owner;
1618 if (td->
rail_speed == 0 || spd < td->rail_speed) {
1628 static void TileLoop_TunnelBridge(
TileIndex tile)
1666 static void ChangeTileOwner_TunnelBridge(
TileIndex tile,
Owner old_owner,
Owner new_owner)
1679 Company::Get(old_owner)->infrastructure.road[rt] -= num_pieces * 2;
1735 int z = GetSlopePixelZ(x, y) - v->
z_pos;
1754 SndPlayVehicleFx(SND_05_TRAIN_THROUGH_TUNNEL, v);
1758 if (frame == _tunnel_visibility_frame[dir]) {
1779 if (frame == _tunnel_visibility_frame[dir]) {
1781 assert(frame == rv->frame + 1);
1835 default: NOT_REACHED();
1869 default: NOT_REACHED();
1901 extern const TileTypeProcs _tile_type_tunnelbridge_procs = {
1903 GetSlopePixelZ_TunnelBridge,
1906 GetTileDesc_TunnelBridge,
1907 GetTileTrackStatus_TunnelBridge,
1910 TileLoop_TunnelBridge,
1911 ChangeTileOwner_TunnelBridge,
1913 VehicleEnter_TunnelBridge,
1914 GetFoundation_TunnelBridge,
1915 TerraformTile_TunnelBridge,