mirror of https://github.com/OpenTTD/OpenTTD
(svn r3907) Replace many bridge related direct map accesses with calls to shiny new functions and mark some strange constructs with XXX
parent
d6134455a5
commit
b8da06ddb1
|
@ -2157,8 +2157,7 @@ static bool AiRemoveTileAndGoForward(Player *p)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(_m[tile].m5 & 0x40)) {
|
if (IsBridgeRamp(tile)) {
|
||||||
|
|
||||||
// Check if the bridge points in the right direction.
|
// Check if the bridge points in the right direction.
|
||||||
// This is not really needed the first place AiRemoveTileAndGoForward is called.
|
// This is not really needed the first place AiRemoveTileAndGoForward is called.
|
||||||
if (DiagDirToAxis(GetBridgeRampDirection(tile)) != (p->ai.cur_dir_a & 1U)) return false;
|
if (DiagDirToAxis(GetBridgeRampDirection(tile)) != (p->ai.cur_dir_a & 1U)) return false;
|
||||||
|
@ -3669,8 +3668,12 @@ pos_3:
|
||||||
CMD_REMOVE_ROAD);
|
CMD_REMOVE_ROAD);
|
||||||
}
|
}
|
||||||
} else if (IsTileType(tile, MP_TUNNELBRIDGE)) {
|
} else if (IsTileType(tile, MP_TUNNELBRIDGE)) {
|
||||||
if (!IsTileOwner(tile, _current_player) || (_m[tile].m5 & 0xC6) != 0x80)
|
if (!IsTileOwner(tile, _current_player) ||
|
||||||
|
!IsBridge(tile) ||
|
||||||
|
!IsBridgeRamp(tile) ||
|
||||||
|
GetBridgeTransportType(tile) != TRANSPORT_RAIL) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m5 = 0;
|
m5 = 0;
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "../../stdafx.h"
|
#include "../../stdafx.h"
|
||||||
#include "../../openttd.h"
|
#include "../../openttd.h"
|
||||||
|
#include "../../bridge_map.h"
|
||||||
#include "../../debug.h"
|
#include "../../debug.h"
|
||||||
#include "../../functions.h"
|
#include "../../functions.h"
|
||||||
#include "../../map.h"
|
#include "../../map.h"
|
||||||
|
@ -44,8 +45,7 @@ static bool IsRoad(TileIndex tile)
|
||||||
(IsTileType(tile, MP_STREET) && !IsTileDepotType(tile, TRANSPORT_ROAD)) ||
|
(IsTileType(tile, MP_STREET) && !IsTileDepotType(tile, TRANSPORT_ROAD)) ||
|
||||||
(IsTileType(tile, MP_TUNNELBRIDGE) && (
|
(IsTileType(tile, MP_TUNNELBRIDGE) && (
|
||||||
(IsTunnel(tile) && GetTunnelTransportType(tile) == TRANSPORT_ROAD) ||
|
(IsTunnel(tile) && GetTunnelTransportType(tile) == TRANSPORT_ROAD) ||
|
||||||
// road bridge?
|
(IsBridge(tile) && GetBridgeTransportType(tile) == TRANSPORT_ROAD)
|
||||||
((_m[tile].m5 & 0x80) != 0 && (_m[tile].m5 & 0x2) == 0x2)
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,7 +234,7 @@ static void AyStar_AiPathFinder_GetNeighbours(AyStar *aystar, OpenListNode *curr
|
||||||
if (IsTunnel(atile)) {
|
if (IsTunnel(atile)) {
|
||||||
if (GetTunnelDirection(atile) != i) continue;
|
if (GetTunnelDirection(atile) != i) continue;
|
||||||
} else {
|
} else {
|
||||||
if ((_m[atile].m5 & 1U) != DiagDirToAxis(i)) continue;
|
if (GetBridgeRampDirection(atile) != i) continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
28
bridge_map.h
28
bridge_map.h
|
@ -7,9 +7,21 @@
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "rail.h"
|
#include "rail.h"
|
||||||
|
#include "road_map.h"
|
||||||
#include "tile.h"
|
#include "tile.h"
|
||||||
|
|
||||||
|
|
||||||
|
static inline bool IsBridge(TileIndex t)
|
||||||
|
{
|
||||||
|
return HASBIT(_m[t].m5, 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool IsBridgeTile(TileIndex t)
|
||||||
|
{
|
||||||
|
return IsTileType(t, MP_TUNNELBRIDGE) && IsBridge(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline bool IsBridgeRamp(TileIndex t)
|
static inline bool IsBridgeRamp(TileIndex t)
|
||||||
{
|
{
|
||||||
return !HASBIT(_m[t].m5, 6);
|
return !HASBIT(_m[t].m5, 6);
|
||||||
|
@ -61,6 +73,12 @@ static inline Axis GetBridgeAxis(TileIndex t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline TransportType GetBridgeTransportType(TileIndex t)
|
||||||
|
{
|
||||||
|
return (TransportType)GB(_m[t].m5, 1, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline bool IsClearUnderBridge(TileIndex t)
|
static inline bool IsClearUnderBridge(TileIndex t)
|
||||||
{
|
{
|
||||||
return GB(_m[t].m5, 3, 3) == 0;
|
return GB(_m[t].m5, 3, 3) == 0;
|
||||||
|
@ -82,6 +100,16 @@ static inline TransportType GetTransportTypeUnderBridge(TileIndex t)
|
||||||
return (TransportType)GB(_m[t].m5, 3, 2);
|
return (TransportType)GB(_m[t].m5, 3, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline RoadBits GetRoadBitsUnderBridge(TileIndex t)
|
||||||
|
{
|
||||||
|
return GetBridgeAxis(t) == AXIS_X ? ROAD_Y : ROAD_X;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline TrackBits GetRailBitsUnderBridge(TileIndex t)
|
||||||
|
{
|
||||||
|
return GetBridgeAxis(t) == AXIS_X ? TRACK_BIT_Y : TRACK_BIT_X;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds the end of a bridge in the specified direction starting at a middle tile
|
* Finds the end of a bridge in the specified direction starting at a middle tile
|
||||||
|
|
7
npf.c
7
npf.c
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "openttd.h"
|
#include "openttd.h"
|
||||||
|
#include "bridge_map.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "functions.h"
|
#include "functions.h"
|
||||||
#include "npf.h"
|
#include "npf.h"
|
||||||
|
@ -484,8 +485,10 @@ static bool VehicleMayEnterTile(Owner owner, TileIndex tile, DiagDirection enter
|
||||||
/* if we were on a railway middle part, we are now at a railway bridge ending */
|
/* if we were on a railway middle part, we are now at a railway bridge ending */
|
||||||
#endif
|
#endif
|
||||||
if ((IsTunnel(tile) && GetTunnelTransportType(tile) == TRANSPORT_RAIL) ||
|
if ((IsTunnel(tile) && GetTunnelTransportType(tile) == TRANSPORT_RAIL) ||
|
||||||
(_m[tile].m5 & 0xC6) == 0x80 || /* railway bridge ending */
|
(IsBridge(tile) && (
|
||||||
((_m[tile].m5 & 0xF8) == 0xE0 && GB(_m[tile].m5, 0, 1) != (enterdir & 0x1))) { /* railway under bridge */
|
(IsBridgeRamp(tile) && GetBridgeTransportType(tile) == TRANSPORT_RAIL) ||
|
||||||
|
(IsBridgeMiddle(tile) && IsTransportUnderBridge(tile) && GetTransportTypeUnderBridge(tile) == TRANSPORT_RAIL)
|
||||||
|
))) {
|
||||||
return IsTileOwner(tile, owner);
|
return IsTileOwner(tile, owner);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
38
pathfind.c
38
pathfind.c
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "openttd.h"
|
#include "openttd.h"
|
||||||
|
#include "bridge_map.h"
|
||||||
#include "functions.h"
|
#include "functions.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "tile.h"
|
#include "tile.h"
|
||||||
|
@ -137,11 +138,18 @@ static void TPFMode2(TrackPathFinder* tpf, TileIndex tile, DiagDirection directi
|
||||||
|
|
||||||
/* XXX: Mode 2 is currently only used for ships, why is this code here? */
|
/* XXX: Mode 2 is currently only used for ships, why is this code here? */
|
||||||
if (tpf->tracktype == TRANSPORT_RAIL) {
|
if (tpf->tracktype == TRANSPORT_RAIL) {
|
||||||
if (IsTileType(tile, MP_RAILWAY) || IsTileType(tile, MP_STATION) || IsTileType(tile, MP_TUNNELBRIDGE)) {
|
switch (GetTileType(tile)) {
|
||||||
|
case MP_TUNNELBRIDGE:
|
||||||
|
// bridge middle has no owner
|
||||||
|
if (IsBridge(tile) && IsBridgeMiddle(tile)) break;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
|
case MP_RAILWAY:
|
||||||
|
case MP_STATION:
|
||||||
owner = GetTileOwner(tile);
|
owner = GetTileOwner(tile);
|
||||||
/* Check if we are on the middle of a bridge (has no owner) */
|
break;
|
||||||
if (IsTileType(tile, MP_TUNNELBRIDGE) && (_m[tile].m5 & 0xC0) == 0xC0)
|
|
||||||
owner = -1;
|
default: break; // XXX can this occur?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,11 +160,19 @@ static void TPFMode2(TrackPathFinder* tpf, TileIndex tile, DiagDirection directi
|
||||||
|
|
||||||
/* Check in case of rail if the owner is the same */
|
/* Check in case of rail if the owner is the same */
|
||||||
if (tpf->tracktype == TRANSPORT_RAIL) {
|
if (tpf->tracktype == TRANSPORT_RAIL) {
|
||||||
if (IsTileType(tile, MP_RAILWAY) || IsTileType(tile, MP_STATION) || IsTileType(tile, MP_TUNNELBRIDGE))
|
switch (GetTileType(tile)) {
|
||||||
/* Check if we are on the middle of a bridge (has no owner) */
|
case MP_TUNNELBRIDGE:
|
||||||
if (!IsTileType(tile, MP_TUNNELBRIDGE) || (_m[tile].m5 & 0xC0) != 0xC0)
|
// bridge middle has no owner
|
||||||
if (owner != -1 && !IsTileOwner(tile, owner))
|
if (IsBridge(tile) && IsBridgeMiddle(tile)) break;
|
||||||
return;
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
|
case MP_RAILWAY:
|
||||||
|
case MP_STATION:
|
||||||
|
if (owner != -1 && !IsTileOwner(tile, owner)) return;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: break; // XXX can this occur?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (++tpf->rd.cur_length > 50)
|
if (++tpf->rd.cur_length > 50)
|
||||||
|
@ -296,8 +312,8 @@ static void TPFMode1(TrackPathFinder* tpf, TileIndex tile, DiagDirection directi
|
||||||
if (IsTileType(tile_org, MP_RAILWAY) || IsTileType(tile_org, MP_STATION) || IsTileType(tile_org, MP_TUNNELBRIDGE))
|
if (IsTileType(tile_org, MP_RAILWAY) || IsTileType(tile_org, MP_STATION) || IsTileType(tile_org, MP_TUNNELBRIDGE))
|
||||||
if (IsTileType(tile, MP_RAILWAY) || IsTileType(tile, MP_STATION) || IsTileType(tile, MP_TUNNELBRIDGE))
|
if (IsTileType(tile, MP_RAILWAY) || IsTileType(tile, MP_STATION) || IsTileType(tile, MP_TUNNELBRIDGE))
|
||||||
/* Check if we are on a bridge (middle parts don't have an owner */
|
/* Check if we are on a bridge (middle parts don't have an owner */
|
||||||
if (!IsTileType(tile, MP_TUNNELBRIDGE) || (_m[tile].m5 & 0xC0) != 0xC0)
|
if (!IsBridgeTile(tile) || !IsBridgeMiddle(tile))
|
||||||
if (!IsTileType(tile_org, MP_TUNNELBRIDGE) || (_m[tile_org].m5 & 0xC0) != 0xC0)
|
if (!IsBridgeTile(tile_org) || !IsBridgeMiddle(tile_org))
|
||||||
if (GetTileOwner(tile_org) != GetTileOwner(tile))
|
if (GetTileOwner(tile_org) != GetTileOwner(tile))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
33
rail.c
33
rail.c
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "openttd.h"
|
#include "openttd.h"
|
||||||
|
#include "bridge_map.h"
|
||||||
#include "rail.h"
|
#include "rail.h"
|
||||||
#include "station.h"
|
#include "station.h"
|
||||||
#include "tunnel_map.h"
|
#include "tunnel_map.h"
|
||||||
|
@ -124,18 +125,32 @@ RailType GetTileRailType(TileIndex tile, Trackdir trackdir)
|
||||||
type = _m[tile].m3 & RAILTYPE_MASK;
|
type = _m[tile].m3 & RAILTYPE_MASK;
|
||||||
break;
|
break;
|
||||||
case MP_TUNNELBRIDGE:
|
case MP_TUNNELBRIDGE:
|
||||||
if (IsTunnel(tile) && GetTunnelTransportType(tile) == TRANSPORT_RAIL) {
|
if (IsTunnel(tile)) {
|
||||||
|
if (GetTunnelTransportType(tile) == TRANSPORT_RAIL) {
|
||||||
return _m[tile].m3 & RAILTYPE_MASK;
|
return _m[tile].m3 & RAILTYPE_MASK;
|
||||||
}
|
}
|
||||||
/* railway bridge ending */
|
} else {
|
||||||
if ((_m[tile].m5 & 0xC6) == 0x80) type = _m[tile].m3 & RAILTYPE_MASK;
|
if (IsBridgeRamp(tile)) {
|
||||||
/* on railway bridge */
|
if (GetBridgeTransportType(tile) == TRANSPORT_RAIL) {
|
||||||
if ((_m[tile].m5 & 0xC6) == 0xC0 && ((DiagDirection)(_m[tile].m5 & 0x1)) == (exitdir & 0x1))
|
return _m[tile].m3 & RAILTYPE_MASK;
|
||||||
type = (_m[tile].m3 >> 4) & RAILTYPE_MASK;
|
}
|
||||||
/* under bridge (any type) */
|
} else {
|
||||||
if ((_m[tile].m5 & 0xF8) == 0xE0 && (_m[tile].m5 & 0x1U) != (exitdir & 0x1))
|
if (GetBridgeAxis(tile) == DiagDirToAxis(exitdir)) {
|
||||||
type = _m[tile].m3 & RAILTYPE_MASK;
|
if (GetBridgeTransportType(tile) == TRANSPORT_RAIL) {
|
||||||
|
/* on the bridge */
|
||||||
|
return (_m[tile].m3 >> 4) & RAILTYPE_MASK;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (IsTransportUnderBridge(tile) &&
|
||||||
|
GetTransportTypeUnderBridge(tile) == TRANSPORT_RAIL) {
|
||||||
|
/* under the bridge */
|
||||||
|
return _m[tile].m3 & RAILTYPE_MASK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
30
rail_cmd.c
30
rail_cmd.c
|
@ -288,25 +288,23 @@ int32 CmdBuildSingleRail(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
|
|
||||||
switch (GetTileType(tile)) {
|
switch (GetTileType(tile)) {
|
||||||
case MP_TUNNELBRIDGE:
|
case MP_TUNNELBRIDGE:
|
||||||
if ((m5 & 0xC0) != 0xC0 || // not bridge middle part?
|
if (!IsBridge(tile) ||
|
||||||
(m5 & 0x01 ? TRACK_BIT_X : TRACK_BIT_Y) != trackbit) { // wrong direction?
|
!IsBridgeMiddle(tile) ||
|
||||||
|
(GetBridgeAxis(tile) == AXIS_X ? TRACK_BIT_Y : TRACK_BIT_X) != trackbit) {
|
||||||
// Get detailed error message
|
// Get detailed error message
|
||||||
return DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
return DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (m5 & 0x38) { // what's under the bridge?
|
if (IsClearUnderBridge(tile)) {
|
||||||
case 0x00: // clear land
|
|
||||||
ret = CheckRailSlope(tileh, trackbit, 0, tile);
|
ret = CheckRailSlope(tileh, trackbit, 0, tile);
|
||||||
if (CmdFailed(ret)) return ret;
|
if (CmdFailed(ret)) return ret;
|
||||||
cost += ret;
|
cost += ret;
|
||||||
|
|
||||||
if (flags & DC_EXEC) SetRailUnderBridge(tile, _current_player, p1);
|
if (flags & DC_EXEC) SetRailUnderBridge(tile, _current_player, p1);
|
||||||
break;
|
} else if (IsTransportUnderBridge(tile) &&
|
||||||
|
GetTransportTypeUnderBridge(tile) == TRANSPORT_RAIL) {
|
||||||
case 0x20: // rail already there
|
|
||||||
return_cmd_error(STR_1007_ALREADY_BUILT);
|
return_cmd_error(STR_1007_ALREADY_BUILT);
|
||||||
|
} else {
|
||||||
default:
|
|
||||||
// Get detailed error message
|
// Get detailed error message
|
||||||
return DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
return DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
||||||
}
|
}
|
||||||
|
@ -411,14 +409,14 @@ int32 CmdRemoveSingleRail(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
switch (GetTileType(tile))
|
switch (GetTileType(tile))
|
||||||
{
|
{
|
||||||
case MP_TUNNELBRIDGE:
|
case MP_TUNNELBRIDGE:
|
||||||
if (!EnsureNoVehicleZ(tile, TilePixelHeight(tile)))
|
if (!IsBridge(tile) ||
|
||||||
return CMD_ERROR;
|
!IsBridgeMiddle(tile) ||
|
||||||
|
!IsTransportUnderBridge(tile) ||
|
||||||
if ((_m[tile].m5 & 0xF8) != 0xE0)
|
GetTransportTypeUnderBridge(tile) != TRANSPORT_RAIL ||
|
||||||
return CMD_ERROR;
|
GetRailBitsUnderBridge(tile) != trackbit ||
|
||||||
|
!EnsureNoVehicleZ(tile, TilePixelHeight(tile))) {
|
||||||
if ((_m[tile].m5 & 1 ? TRACK_BIT_X : TRACK_BIT_Y) != trackbit)
|
|
||||||
return CMD_ERROR;
|
return CMD_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(flags & DC_EXEC))
|
if (!(flags & DC_EXEC))
|
||||||
return _price.remove_rail;
|
return _price.remove_rail;
|
||||||
|
|
30
road_cmd.c
30
road_cmd.c
|
@ -129,11 +129,11 @@ int32 CmdRemoveRoad(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
case MP_TUNNELBRIDGE:
|
case MP_TUNNELBRIDGE:
|
||||||
if (!EnsureNoVehicleZ(tile, TilePixelHeight(tile))) return CMD_ERROR;
|
if (!EnsureNoVehicleZ(tile, TilePixelHeight(tile))) return CMD_ERROR;
|
||||||
|
|
||||||
if ((ti.map5 & 0xE9) == 0xE8) {
|
if (!IsBridge(tile) ||
|
||||||
if (pieces & ROAD_X) return CMD_ERROR;
|
!IsBridgeMiddle(tile) ||
|
||||||
} else if ((ti.map5 & 0xE9) == 0xE9) {
|
!IsTransportUnderBridge(tile) ||
|
||||||
if (pieces & ROAD_Y) return CMD_ERROR;
|
GetTransportTypeUnderBridge(tile) != TRANSPORT_ROAD ||
|
||||||
} else {
|
(pieces & ComplementRoadBits(GetRoadBitsUnderBridge(tile))) != 0) {
|
||||||
return CMD_ERROR;
|
return CMD_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,20 +357,24 @@ int32 CmdBuildRoad(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
|
return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* is this middle part of a bridge? */
|
if (!IsBridge(tile) || !IsBridgeMiddle(tile)) goto do_clear;
|
||||||
if ((ti.map5 & 0xC0) != 0xC0) goto do_clear;
|
|
||||||
|
|
||||||
/* only allow roads pertendicular to bridge */
|
/* only allow roads pertendicular to bridge */
|
||||||
if (((pieces & ROAD_Y) != 0) == ((ti.map5 & 0x01U) != 0)) goto do_clear;
|
if ((pieces & (GetBridgeAxis(tile) == AXIS_X ? ROAD_X : ROAD_Y)) != 0) {
|
||||||
|
goto do_clear;
|
||||||
|
}
|
||||||
|
|
||||||
/* check if clear land under bridge */
|
/* check if clear land under bridge */
|
||||||
if ((ti.map5 & 0xF8) == 0xE8) { /* road under bridge */
|
if (IsTransportUnderBridge(tile)) {
|
||||||
return_cmd_error(STR_1007_ALREADY_BUILT);
|
switch (GetTransportTypeUnderBridge(tile)) {
|
||||||
} else if ((ti.map5 & 0xE0) == 0xE0) { /* other transport route under bridge */
|
case TRANSPORT_ROAD: return_cmd_error(STR_1007_ALREADY_BUILT);
|
||||||
return_cmd_error(STR_1008_MUST_REMOVE_RAILROAD_TRACK);
|
default: return_cmd_error(STR_1008_MUST_REMOVE_RAILROAD_TRACK);
|
||||||
} else if ((ti.map5 & 0xF8) == 0xC8) { /* water under bridge */
|
}
|
||||||
|
} else {
|
||||||
|
if (IsWaterUnderBridge(tile)) {
|
||||||
return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER);
|
return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* all checked, can build road now! */
|
/* all checked, can build road now! */
|
||||||
cost = _price.build_road * 2;
|
cost = _price.build_road * 2;
|
||||||
|
|
15
road_map.c
15
road_map.c
|
@ -25,15 +25,16 @@ RoadBits GetAnyRoadBits(TileIndex tile)
|
||||||
return DiagDirToRoadBits(GetRoadStationDir(tile));
|
return DiagDirToRoadBits(GetRoadStationDir(tile));
|
||||||
|
|
||||||
case MP_TUNNELBRIDGE:
|
case MP_TUNNELBRIDGE:
|
||||||
if (_m[tile].m5 & 0x80) {
|
if (IsBridge(tile)) {
|
||||||
// bridge
|
if (IsBridgeMiddle(tile)) {
|
||||||
if (_m[tile].m5 & 0x40) {
|
if (!IsTransportUnderBridge(tile) ||
|
||||||
// middle part
|
GetBridgeTransportType(tile) != TRANSPORT_ROAD) {
|
||||||
if ((_m[tile].m5 & 0x38) != 0x28) return 0; // no road under bridge
|
return 0;
|
||||||
return _m[tile].m5 & 1 ? ROAD_X : ROAD_Y;
|
}
|
||||||
|
return GetRoadBitsUnderBridge(tile);
|
||||||
} else {
|
} else {
|
||||||
// ending
|
// ending
|
||||||
if (GB(_m[tile].m5, 1, 2) != TRANSPORT_ROAD) return 0; // not a road bridge
|
if (GetBridgeTransportType(tile) != TRANSPORT_ROAD) return 0;
|
||||||
return DiagDirToRoadBits(ReverseDiagDir(GetBridgeRampDirection(tile)));
|
return DiagDirToRoadBits(ReverseDiagDir(GetBridgeRampDirection(tile)));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "openttd.h"
|
#include "openttd.h"
|
||||||
|
#include "bridge_map.h"
|
||||||
#include "clear_map.h"
|
#include "clear_map.h"
|
||||||
#include "functions.h"
|
#include "functions.h"
|
||||||
#include "spritecache.h"
|
#include "spritecache.h"
|
||||||
|
@ -351,7 +352,7 @@ static inline TileType GetEffectiveTileType(TileIndex tile)
|
||||||
if (IsTunnel(tile)) {
|
if (IsTunnel(tile)) {
|
||||||
tt = GetTunnelTransportType(tile);
|
tt = GetTunnelTransportType(tile);
|
||||||
} else {
|
} else {
|
||||||
tt = GB(_m[tile].m5, 1, 2);
|
tt = GetBridgeTransportType(tile);
|
||||||
}
|
}
|
||||||
switch (tt) {
|
switch (tt) {
|
||||||
case TRANSPORT_RAIL: t = MP_RAILWAY; break;
|
case TRANSPORT_RAIL: t = MP_RAILWAY; break;
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "openttd.h"
|
#include "openttd.h"
|
||||||
|
#include "bridge_map.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "functions.h"
|
#include "functions.h"
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
|
@ -2545,7 +2546,7 @@ static bool CheckCompatibleRail(const Vehicle *v, TileIndex tile)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MP_TUNNELBRIDGE:
|
case MP_TUNNELBRIDGE:
|
||||||
if ((_m[tile].m5 & 0xC0) == 0xC0) { // is bridge middle part?
|
if (IsBridge(tile) && IsBridgeMiddle(tile)) {
|
||||||
uint height;
|
uint height;
|
||||||
uint tileh = GetTileSlope(tile, &height);
|
uint tileh = GetTileSlope(tile, &height);
|
||||||
|
|
||||||
|
|
|
@ -670,22 +670,18 @@ static int32 DoClearBridge(TileIndex tile, uint32 flags)
|
||||||
DoClearSquare(tile);
|
DoClearSquare(tile);
|
||||||
DoClearSquare(endtile);
|
DoClearSquare(endtile);
|
||||||
for (c = tile + delta; c != endtile; c += delta) {
|
for (c = tile + delta; c != endtile; c += delta) {
|
||||||
if (_m[c].m5 & 0x20) {
|
if (IsTransportUnderBridge(c)) {
|
||||||
// transport under bridge
|
if (GetTransportTypeUnderBridge(c) == TRANSPORT_RAIL) {
|
||||||
if (GB(_m[c].m5, 3, 2) == TRANSPORT_RAIL) {
|
MakeRailNormal(c, GetTileOwner(c), GetRailBitsUnderBridge(c), GB(_m[c].m3, 0, 3));
|
||||||
MakeRailNormal(c, GetTileOwner(c), _m[c].m5 & 1 ? TRACK_BIT_X : TRACK_BIT_Y, GB(_m[c].m3, 0, 3));
|
|
||||||
} else {
|
} else {
|
||||||
uint town = IsTileOwner(c, OWNER_TOWN) ? ClosestTownFromTile(c, (uint)-1)->index : 0;
|
uint town = IsTileOwner(c, OWNER_TOWN) ? ClosestTownFromTile(c, (uint)-1)->index : 0;
|
||||||
MakeRoadNormal(c, GetTileOwner(c), _m[c].m5 & 1 ? ROAD_X : ROAD_Y, town);
|
MakeRoadNormal(c, GetTileOwner(c), GetRoadBitsUnderBridge(c), town);
|
||||||
}
|
}
|
||||||
MarkTileDirtyByTile(c);
|
MarkTileDirtyByTile(c);
|
||||||
} else {
|
} else {
|
||||||
// clear under bridge
|
if (IsClearUnderBridge(c)) {
|
||||||
if (GB(_m[c].m5, 3, 2) == 0) {
|
|
||||||
// grass under bridge
|
|
||||||
DoClearSquare(c);
|
DoClearSquare(c);
|
||||||
} else {
|
} else {
|
||||||
// water under bridge
|
|
||||||
if (GetTileSlope(c, NULL) == 0) {
|
if (GetTileSlope(c, NULL) == 0) {
|
||||||
MakeWater(c);
|
MakeWater(c);
|
||||||
} else {
|
} else {
|
||||||
|
@ -705,12 +701,10 @@ static int32 DoClearBridge(TileIndex tile, uint32 flags)
|
||||||
|
|
||||||
static int32 ClearTile_TunnelBridge(TileIndex tile, byte flags)
|
static int32 ClearTile_TunnelBridge(TileIndex tile, byte flags)
|
||||||
{
|
{
|
||||||
byte m5 = _m[tile].m5;
|
|
||||||
|
|
||||||
if (IsTunnel(tile)) {
|
if (IsTunnel(tile)) {
|
||||||
if (flags & DC_AUTO) return_cmd_error(STR_5006_MUST_DEMOLISH_TUNNEL_FIRST);
|
if (flags & DC_AUTO) return_cmd_error(STR_5006_MUST_DEMOLISH_TUNNEL_FIRST);
|
||||||
return DoClearTunnel(tile, flags);
|
return DoClearTunnel(tile, flags);
|
||||||
} else if (m5 & 0x80) {
|
} else if (IsBridge(tile)) { // XXX Is this necessary?
|
||||||
if (flags & DC_AUTO) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
|
if (flags & DC_AUTO) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
|
||||||
return DoClearBridge(tile, flags);
|
return DoClearBridge(tile, flags);
|
||||||
}
|
}
|
||||||
|
@ -739,8 +733,10 @@ int32 DoConvertTunnelBridgeRail(TileIndex tile, uint totype, bool exec)
|
||||||
MarkTileDirtyByTile(endtile);
|
MarkTileDirtyByTile(endtile);
|
||||||
}
|
}
|
||||||
return (length + 1) * (_price.build_rail >> 1);
|
return (length + 1) * (_price.build_rail >> 1);
|
||||||
} else if ((_m[tile].m5 & 0xF8) == 0xE0) {
|
} else if (IsBridge(tile) &&
|
||||||
// bridge middle part with rail below
|
IsBridgeMiddle(tile) &&
|
||||||
|
IsTransportUnderBridge(tile) &&
|
||||||
|
GetTransportTypeUnderBridge(tile) == TRANSPORT_RAIL) {
|
||||||
// only check for train under bridge
|
// only check for train under bridge
|
||||||
if (!CheckTileOwnership(tile) || !EnsureNoVehicleZ(tile, TilePixelHeight(tile)))
|
if (!CheckTileOwnership(tile) || !EnsureNoVehicleZ(tile, TilePixelHeight(tile)))
|
||||||
return CMD_ERROR;
|
return CMD_ERROR;
|
||||||
|
@ -753,7 +749,7 @@ int32 DoConvertTunnelBridgeRail(TileIndex tile, uint totype, bool exec)
|
||||||
MarkTileDirtyByTile(tile);
|
MarkTileDirtyByTile(tile);
|
||||||
}
|
}
|
||||||
return _price.build_rail >> 1;
|
return _price.build_rail >> 1;
|
||||||
} else if ((_m[tile].m5 & 0xC6) == 0x80) {
|
} else if (IsBridge(tile) && IsBridgeRamp(tile) && GetBridgeTransportType(tile) == TRANSPORT_RAIL) {
|
||||||
TileIndexDiff delta;
|
TileIndexDiff delta;
|
||||||
int32 cost;
|
int32 cost;
|
||||||
uint z = TilePixelHeight(tile);
|
uint z = TilePixelHeight(tile);
|
||||||
|
@ -762,7 +758,6 @@ int32 DoConvertTunnelBridgeRail(TileIndex tile, uint totype, bool exec)
|
||||||
|
|
||||||
if (!CheckTileOwnership(tile)) return CMD_ERROR;
|
if (!CheckTileOwnership(tile)) return CMD_ERROR;
|
||||||
|
|
||||||
// railway bridge
|
|
||||||
endtile = GetOtherBridgeEnd(tile);
|
endtile = GetOtherBridgeEnd(tile);
|
||||||
// Make sure there's no vehicle on the bridge
|
// Make sure there's no vehicle on the bridge
|
||||||
v = FindVehicleBetween(tile, endtile, z);
|
v = FindVehicleBetween(tile, endtile, z);
|
||||||
|
@ -821,6 +816,7 @@ extern const byte _road_sloped_sprites[14];
|
||||||
|
|
||||||
static void DrawBridgePillars(const TileInfo *ti, int x, int y, int z)
|
static void DrawBridgePillars(const TileInfo *ti, int x, int y, int z)
|
||||||
{
|
{
|
||||||
|
Axis axis = GetBridgeAxis(ti->tile);
|
||||||
const PalSpriteID *b;
|
const PalSpriteID *b;
|
||||||
PalSpriteID image;
|
PalSpriteID image;
|
||||||
int piece;
|
int piece;
|
||||||
|
@ -830,7 +826,7 @@ static void DrawBridgePillars(const TileInfo *ti, int x, int y, int z)
|
||||||
// Draw first piece
|
// Draw first piece
|
||||||
// (necessary for cantilever bridges)
|
// (necessary for cantilever bridges)
|
||||||
|
|
||||||
image = b[12 + GB(ti->map5, 0, 1)];
|
image = b[axis == AXIS_X ? 12 : 13];
|
||||||
piece = GetBridgePiece(ti->tile);
|
piece = GetBridgePiece(ti->tile);
|
||||||
|
|
||||||
if (image != 0 && piece != 0) {
|
if (image != 0 && piece != 0) {
|
||||||
|
@ -838,7 +834,7 @@ static void DrawBridgePillars(const TileInfo *ti, int x, int y, int z)
|
||||||
DrawGroundSpriteAt(image, x, y, z);
|
DrawGroundSpriteAt(image, x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
image = b[GB(ti->map5, 0, 1) * 6 + piece];
|
image = b[piece + (axis == AXIS_X ? 0 : 6)];
|
||||||
|
|
||||||
if (image != 0) {
|
if (image != 0) {
|
||||||
int back_height, front_height, i=z;
|
int back_height, front_height, i=z;
|
||||||
|
@ -853,7 +849,7 @@ static void DrawBridgePillars(const TileInfo *ti, int x, int y, int z)
|
||||||
|
|
||||||
if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
|
if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
|
||||||
|
|
||||||
p = _tileh_bits[(image & 1) * 2 + (ti->map5&0x01)];
|
p = _tileh_bits[(image & 1) * 2 + (axis == AXIS_X ? 0 : 1)];
|
||||||
front_height = ti->z + ((ti->tileh & p[0])?8:0);
|
front_height = ti->z + ((ti->tileh & p[0])?8:0);
|
||||||
back_height = ti->z + ((ti->tileh & p[1])?8:0);
|
back_height = ti->z + ((ti->tileh & p[1])?8:0);
|
||||||
|
|
||||||
|
@ -920,7 +916,6 @@ static void DrawTile_TunnelBridge(TileInfo *ti)
|
||||||
const PalSpriteID *b;
|
const PalSpriteID *b;
|
||||||
bool ice = _m[ti->tile].m4 & 0x80;
|
bool ice = _m[ti->tile].m4 & 0x80;
|
||||||
|
|
||||||
// draw tunnel?
|
|
||||||
if (IsTunnel(ti->tile)) {
|
if (IsTunnel(ti->tile)) {
|
||||||
if (GetTunnelTransportType(ti->tile) == TRANSPORT_RAIL) {
|
if (GetTunnelTransportType(ti->tile) == TRANSPORT_RAIL) {
|
||||||
image = GetRailTypeInfo(GB(_m[ti->tile].m3, 0, 4))->base_sprites.tunnel;
|
image = GetRailTypeInfo(GB(_m[ti->tile].m3, 0, 4))->base_sprites.tunnel;
|
||||||
|
@ -934,30 +929,30 @@ static void DrawTile_TunnelBridge(TileInfo *ti)
|
||||||
DrawGroundSprite(image);
|
DrawGroundSprite(image);
|
||||||
|
|
||||||
AddSortableSpriteToDraw(image+1, ti->x + 15, ti->y + 15, 1, 1, 8, (byte)ti->z);
|
AddSortableSpriteToDraw(image+1, ti->x + 15, ti->y + 15, 1, 1, 8, (byte)ti->z);
|
||||||
// draw bridge?
|
} else if (IsBridge(ti->tile)) { // XXX is this necessary?
|
||||||
} else if (ti->map5 & 0x80) {
|
|
||||||
RailType rt;
|
|
||||||
int base_offset;
|
int base_offset;
|
||||||
|
|
||||||
if (HASBIT(ti->map5, 1)) { /* This is a road bridge */
|
if (GetBridgeTransportType(ti->tile) == TRANSPORT_RAIL) {
|
||||||
base_offset = 8;
|
RailType rt;
|
||||||
} else { /* Rail bridge */
|
|
||||||
if (HASBIT(ti->map5, 6)) { /* The bits we need depend on the fact whether it is a bridge head or not */
|
if (IsBridgeRamp(ti->tile)) {
|
||||||
rt = GB(_m[ti->tile].m3, 4, 3);
|
|
||||||
} else {
|
|
||||||
rt = GB(_m[ti->tile].m3, 0, 3);
|
rt = GB(_m[ti->tile].m3, 0, 3);
|
||||||
|
} else {
|
||||||
|
rt = GB(_m[ti->tile].m3, 4, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
base_offset = GetRailTypeInfo(rt)->bridge_offset;
|
base_offset = GetRailTypeInfo(rt)->bridge_offset;
|
||||||
assert(base_offset != 8); /* This one is used for roads */
|
assert(base_offset != 8); /* This one is used for roads */
|
||||||
|
} else {
|
||||||
|
base_offset = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* as the lower 3 bits are used for other stuff, make sure they are clear */
|
/* as the lower 3 bits are used for other stuff, make sure they are clear */
|
||||||
assert( (base_offset & 0x07) == 0x00);
|
assert( (base_offset & 0x07) == 0x00);
|
||||||
|
|
||||||
if (!(ti->map5 & 0x40)) { // bridge ramps
|
if (IsBridgeRamp(ti->tile)) {
|
||||||
if (!(BRIDGE_NO_FOUNDATION & (1 << ti->tileh))) { // no foundations for 0, 3, 6, 9, 12
|
if (!(BRIDGE_NO_FOUNDATION & (1 << ti->tileh))) { // no foundations for 0, 3, 6, 9, 12
|
||||||
int f = GetBridgeFoundation(ti->tileh, ti->map5 & 0x1); // pass direction
|
int f = GetBridgeFoundation(ti->tileh, DiagDirToAxis(GetBridgeRampDirection(ti->tile)));
|
||||||
if (f) DrawFoundation(ti, f);
|
if (f) DrawFoundation(ti, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1002,7 +997,6 @@ static void DrawTile_TunnelBridge(TileInfo *ti)
|
||||||
image += rti->total_offset;
|
image += rti->total_offset;
|
||||||
if (ice) image += rti->snow_offset;
|
if (ice) image += rti->snow_offset;
|
||||||
} else {
|
} else {
|
||||||
// road
|
|
||||||
if (ti->tileh == 0) {
|
if (ti->tileh == 0) {
|
||||||
image = (axis == AXIS_X ? SPR_ROAD_Y : SPR_ROAD_X);
|
image = (axis == AXIS_X ? SPR_ROAD_Y : SPR_ROAD_X);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1037,12 +1031,11 @@ static void DrawTile_TunnelBridge(TileInfo *ti)
|
||||||
// draw rail or road component
|
// draw rail or road component
|
||||||
image = b[0];
|
image = b[0];
|
||||||
if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
|
if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
|
||||||
AddSortableSpriteToDraw(
|
if (axis == AXIS_X) {
|
||||||
image, ti->x, ti->y,
|
AddSortableSpriteToDraw(image, ti->x, ti->y, 16, 11, 1, z);
|
||||||
axis == AXIS_X ? 16 : 11,
|
} else {
|
||||||
axis == AXIS_X ? 11 : 16,
|
AddSortableSpriteToDraw(image, ti->x, ti->y, 11, 16, 1, z);
|
||||||
1, z
|
}
|
||||||
);
|
|
||||||
|
|
||||||
x = ti->x;
|
x = ti->x;
|
||||||
y = ti->y;
|
y = ti->y;
|
||||||
|
@ -1081,17 +1074,15 @@ static uint GetSlopeZ_TunnelBridge(const TileInfo* ti)
|
||||||
uint tileh = ti->tileh;
|
uint tileh = ti->tileh;
|
||||||
|
|
||||||
// swap directions if Y tunnel/bridge to let the code handle the X case only.
|
// swap directions if Y tunnel/bridge to let the code handle the X case only.
|
||||||
if (ti->map5 & 1) uintswap(x,y);
|
if (ti->map5 & 1) uintswap(x,y); // XXX bogus: it could be a tunnel, bridge ramp or bridge middle tile
|
||||||
|
|
||||||
// to the side of the tunnel/bridge?
|
// to the side of the tunnel/bridge?
|
||||||
if (IS_INT_INSIDE(y, 5, 10+1)) {
|
if (IS_INT_INSIDE(y, 5, 10+1)) {
|
||||||
// tunnel?
|
if (IsTunnel(ti->tile)) return z;
|
||||||
if ((ti->map5 & 0xF0) == 0) return z;
|
|
||||||
|
|
||||||
// bridge?
|
// bridge?
|
||||||
if (ti->map5 & 0x80) {
|
if (IsBridge(ti->tile)) {
|
||||||
// bridge ending?
|
if (IsBridgeRamp(ti->tile)) {
|
||||||
if (!(ti->map5 & 0x40)) {
|
|
||||||
if (BRIDGE_FULL_LEVELED_FOUNDATION & (1 << tileh)) // 7, 11, 13, 14
|
if (BRIDGE_FULL_LEVELED_FOUNDATION & (1 << tileh)) // 7, 11, 13, 14
|
||||||
z += 8;
|
z += 8;
|
||||||
|
|
||||||
|
@ -1105,8 +1096,6 @@ static uint GetSlopeZ_TunnelBridge(const TileInfo* ti)
|
||||||
// ramp in opposite dir
|
// ramp in opposite dir
|
||||||
return z + ((x ^ 0xF) >> 1);
|
return z + ((x ^ 0xF) >> 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// bridge middle part
|
|
||||||
} else {
|
} else {
|
||||||
// build on slopes?
|
// build on slopes?
|
||||||
if (tileh != 0) z += 8;
|
if (tileh != 0) z += 8;
|
||||||
|
@ -1119,8 +1108,9 @@ static uint GetSlopeZ_TunnelBridge(const TileInfo* ti)
|
||||||
|
|
||||||
// in the shared area, assume that we're below the bridge, cause otherwise the hint would've caught it.
|
// in the shared area, assume that we're below the bridge, cause otherwise the hint would've caught it.
|
||||||
// if rail or road below then it means it's possibly build on slope below the bridge.
|
// if rail or road below then it means it's possibly build on slope below the bridge.
|
||||||
if (ti->map5 & 0x20) {
|
if (IsTransportUnderBridge(ti->tile)) {
|
||||||
uint f = _bridge_foundations[ti->map5 & 1][tileh];
|
uint f = _bridge_foundations[GetBridgeAxis(ti->tile)][tileh];
|
||||||
|
|
||||||
// make sure that the slope is not inclined foundation
|
// make sure that the slope is not inclined foundation
|
||||||
if (IS_BYTE_INSIDE(f, 1, 15)) return z;
|
if (IS_BYTE_INSIDE(f, 1, 15)) return z;
|
||||||
|
|
||||||
|
@ -1132,11 +1122,10 @@ static uint GetSlopeZ_TunnelBridge(const TileInfo* ti)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// if it's a bridge middle with transport route below, then we need to compensate for build on slopes
|
if (IsBridge(ti->tile) && IsBridgeMiddle(ti->tile) && IsTransportUnderBridge(ti->tile)) {
|
||||||
if ((ti->map5 & (0x80 | 0x40 | 0x20)) == (0x80 | 0x40 | 0x20)) {
|
|
||||||
uint f;
|
uint f;
|
||||||
if (tileh != 0) z += 8;
|
if (tileh != 0) z += 8;
|
||||||
f = _bridge_foundations[ti->map5 & 1][tileh];
|
f = _bridge_foundations[GetBridgeAxis(ti->tile)][tileh];
|
||||||
if (IS_BYTE_INSIDE(f, 1, 15)) return z;
|
if (IS_BYTE_INSIDE(f, 1, 15)) return z;
|
||||||
if (f != 0) tileh = _inclined_tileh[f - 15];
|
if (f != 0) tileh = _inclined_tileh[f - 15];
|
||||||
}
|
}
|
||||||
|
@ -1196,7 +1185,7 @@ static void GetTileDesc_TunnelBridge(TileIndex tile, TileDesc *td)
|
||||||
td->str = (GetTunnelTransportType(tile) == TRANSPORT_RAIL) ?
|
td->str = (GetTunnelTransportType(tile) == TRANSPORT_RAIL) ?
|
||||||
STR_5017_RAILROAD_TUNNEL : STR_5018_ROAD_TUNNEL;
|
STR_5017_RAILROAD_TUNNEL : STR_5018_ROAD_TUNNEL;
|
||||||
} else {
|
} else {
|
||||||
td->str = _bridge_tile_str[GB(_m[tile].m5, 1, 2) << 4 | GetBridgeType(tile)];
|
td->str = _bridge_tile_str[GetBridgeTransportType(tile) << 4 | GetBridgeType(tile)];
|
||||||
|
|
||||||
// the owner is stored at the end of the bridge
|
// the owner is stored at the end of the bridge
|
||||||
if (IsBridgeMiddle(tile)) tile = GetSouthernBridgeEnd(tile);
|
if (IsBridgeMiddle(tile)) tile = GetSouthernBridgeEnd(tile);
|
||||||
|
@ -1235,8 +1224,9 @@ static void TileLoop_TunnelBridge(TileIndex tile)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if it's a bridge with water below, call tileloop_water on it.
|
if (IsBridge(tile) && IsBridgeMiddle(tile) && IsWaterUnderBridge(tile)) {
|
||||||
if ((_m[tile].m5 & 0xF8) == 0xC8) TileLoop_Water(tile);
|
TileLoop_Water(tile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ClickTile_TunnelBridge(TileIndex tile)
|
static void ClickTile_TunnelBridge(TileIndex tile)
|
||||||
|
@ -1248,41 +1238,34 @@ static void ClickTile_TunnelBridge(TileIndex tile)
|
||||||
static uint32 GetTileTrackStatus_TunnelBridge(TileIndex tile, TransportType mode)
|
static uint32 GetTileTrackStatus_TunnelBridge(TileIndex tile, TransportType mode)
|
||||||
{
|
{
|
||||||
uint32 result;
|
uint32 result;
|
||||||
byte m5 = _m[tile].m5;
|
|
||||||
|
|
||||||
if (IsTunnel(tile)) {
|
if (IsTunnel(tile)) {
|
||||||
if (GetTunnelTransportType(tile) == mode) {
|
if (GetTunnelTransportType(tile) == mode) {
|
||||||
return DiagDirToAxis(GetTunnelDirection(tile)) == AXIS_X ? 0x101 : 0x202;
|
return DiagDirToAxis(GetTunnelDirection(tile)) == AXIS_X ? 0x101 : 0x202;
|
||||||
}
|
}
|
||||||
} else if (m5 & 0x80) {
|
} else if (IsBridge(tile)) { // XXX is this necessary?
|
||||||
/* This is a bridge */
|
/* This is a bridge */
|
||||||
result = 0;
|
result = 0;
|
||||||
if (GB(m5, 1, 2) == mode) {
|
if (GetBridgeTransportType(tile) == mode) {
|
||||||
/* Transport over the bridge is compatible */
|
/* Transport over the bridge is compatible */
|
||||||
result = m5 & 1 ? 0x202 : 0x101;
|
result = (GetBridgeAxis(tile) == AXIS_X ? 0x101 : 0x202);
|
||||||
}
|
}
|
||||||
if (m5 & 0x40) {
|
if (IsBridgeMiddle(tile)) {
|
||||||
/* Bridge middle part */
|
/* Bridge middle part */
|
||||||
if (!(m5 & 0x20)) {
|
if (IsTransportUnderBridge(tile)) {
|
||||||
/* Clear ground or water underneath */
|
if (GetTransportTypeUnderBridge(tile) != mode) return result;
|
||||||
if ((m5 & 0x18) != 8) {
|
} else {
|
||||||
/* Clear ground */
|
if (IsClearUnderBridge(tile)) {
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
if (mode != TRANSPORT_WATER) return result;
|
if (mode != TRANSPORT_WATER) return result;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
/* Transport underneath */
|
|
||||||
if (GB(m5, 3, 2) != mode) {
|
|
||||||
/* Incompatible transport underneath */
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* If we've not returned yet, there is a compatible
|
/* If we've not returned yet, there is a compatible
|
||||||
* transport or water beneath, so we can add it to
|
* transport or water beneath, so we can add it to
|
||||||
* result */
|
* result */
|
||||||
/* Why is this xor'd ? Can't it just be or'd? */
|
/* Why is this xor'd ? Can't it just be or'd? */
|
||||||
result ^= m5 & 1 ? 0x101 : 0x202;
|
result ^= (GetBridgeAxis(tile) == AXIS_X ? 0x202 : 0x101);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1298,13 +1281,11 @@ static void ChangeTileOwner_TunnelBridge(TileIndex tile, PlayerID old_player, Pl
|
||||||
if (new_player != OWNER_SPECTATOR) {
|
if (new_player != OWNER_SPECTATOR) {
|
||||||
SetTileOwner(tile, new_player);
|
SetTileOwner(tile, new_player);
|
||||||
} else {
|
} else {
|
||||||
if ((_m[tile].m5 & 0xE0) == 0xE0) {
|
if (IsBridge(tile) && IsBridgeMiddle(tile) && IsTransportUnderBridge(tile)) {
|
||||||
// the stuff BELOW the middle part is owned by the deleted player.
|
// the stuff BELOW the middle part is owned by the deleted player.
|
||||||
if (!(_m[tile].m5 & (1 << 4 | 1 << 3))) {
|
if (GetTransportTypeUnderBridge(tile) == TRANSPORT_RAIL) {
|
||||||
// convert railway into grass.
|
|
||||||
SetClearUnderBridge(tile);
|
SetClearUnderBridge(tile);
|
||||||
} else {
|
} else {
|
||||||
// for road, change the owner of the road to local authority
|
|
||||||
SetTileOwner(tile, OWNER_NONE);
|
SetTileOwner(tile, OWNER_NONE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1396,13 +1377,13 @@ static uint32 VehicleEnter_TunnelBridge(Vehicle *v, TileIndex tile, int x, int y
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (_m[tile].m5 & 0x80) {
|
} else if (IsBridge(tile)) { // XXX is this necessary?
|
||||||
if (v->type == VEH_Road || (v->type == VEH_Train && IsFrontEngine(v))) {
|
if (v->type == VEH_Road || (v->type == VEH_Train && IsFrontEngine(v))) {
|
||||||
uint h;
|
uint h;
|
||||||
|
|
||||||
// Compensate for possible foundation
|
// Compensate for possible foundation
|
||||||
if (GetTileSlope(tile, &h) != 0) h += 8;
|
if (GetTileSlope(tile, &h) != 0) h += 8;
|
||||||
if (!(_m[tile].m5 & 0x40) || // start/end tile of bridge
|
if (IsBridgeRamp(tile) ||
|
||||||
myabs(h - v->z_pos) > 2) { // high above the ground -> on the bridge
|
myabs(h - v->z_pos) > 2) { // high above the ground -> on the bridge
|
||||||
/* modify speed of vehicle */
|
/* modify speed of vehicle */
|
||||||
uint16 spd = _bridge[GetBridgeType(tile)].speed;
|
uint16 spd = _bridge[GetBridgeType(tile)].speed;
|
||||||
|
|
26
water_cmd.c
26
water_cmd.c
|
@ -241,14 +241,13 @@ int32 CmdBuildCanal(int x, int y, uint32 flags, uint32 p1, uint32 p2)
|
||||||
if (IsTileType(tile, MP_WATER)) continue;
|
if (IsTileType(tile, MP_WATER)) continue;
|
||||||
|
|
||||||
/* is middle piece of a bridge? */
|
/* is middle piece of a bridge? */
|
||||||
if (IsTileType(tile, MP_TUNNELBRIDGE) && _m[tile].m5 & 0x40) { /* build under bridge */
|
if (IsBridgeTile(tile) && IsBridgeMiddle(tile)) {
|
||||||
if (_m[tile].m5 & 0x20) // transport route under bridge
|
if (IsTransportUnderBridge(tile)) {
|
||||||
return_cmd_error(STR_5800_OBJECT_IN_THE_WAY);
|
return_cmd_error(STR_5800_OBJECT_IN_THE_WAY);
|
||||||
|
|
||||||
if (_m[tile].m5 & 0x18) { // already water under bridge
|
|
||||||
return_cmd_error(STR_1007_ALREADY_BUILT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsWaterUnderBridge(tile)) return_cmd_error(STR_1007_ALREADY_BUILT);
|
||||||
|
|
||||||
if (flags & DC_EXEC) SetWaterUnderBridge(tile);
|
if (flags & DC_EXEC) SetWaterUnderBridge(tile);
|
||||||
} else {
|
} else {
|
||||||
/* no bridge, try to clear it. */
|
/* no bridge, try to clear it. */
|
||||||
|
@ -354,8 +353,7 @@ static bool IsWateredTile(TileIndex tile)
|
||||||
return !(m5 < 75 || (m5 >= 83 && m5 <= 114));
|
return !(m5 < 75 || (m5 >= 83 && m5 <= 114));
|
||||||
|
|
||||||
case MP_TUNNELBRIDGE:
|
case MP_TUNNELBRIDGE:
|
||||||
// true, if tile is middle part of bridge with water underneath
|
return IsBridge(tile) && IsBridgeMiddle(tile) && IsWaterUnderBridge(tile);
|
||||||
return (m5 & 0xF8) == 0xC8;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
@ -542,8 +540,7 @@ static void TileLoopWaterHelper(TileIndex tile, const TileIndexDiffC *offs)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MP_TUNNELBRIDGE:
|
case MP_TUNNELBRIDGE:
|
||||||
// Middle part of bridge with clear land below?
|
if (IsBridge(target) && IsBridgeMiddle(target) && IsClearUnderBridge(target)) {
|
||||||
if ((_m[target].m5 & 0xF8) == 0xC0) {
|
|
||||||
SetWaterUnderBridge(target);
|
SetWaterUnderBridge(target);
|
||||||
MarkTileDirtyByTile(target);
|
MarkTileDirtyByTile(target);
|
||||||
}
|
}
|
||||||
|
@ -553,16 +550,15 @@ static void TileLoopWaterHelper(TileIndex tile, const TileIndexDiffC *offs)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (IsTileType(target, MP_TUNNELBRIDGE)) {
|
if (IsBridgeTile(target) && IsBridgeMiddle(target)) {
|
||||||
byte m5 = _m[target].m5;
|
if (IsWaterUnderBridge(target) ||
|
||||||
if ((m5 & 0xF8) == 0xC8 || (m5 & 0xF8) == 0xF0) return;
|
(IsTransportUnderBridge(target) && GetTransportTypeUnderBridge(target) == TRANSPORT_WATER)) { // XXX does this happen at all?
|
||||||
|
return;
|
||||||
if ((m5 & 0xC0) == 0xC0) {
|
}
|
||||||
SetWaterUnderBridge(target);
|
SetWaterUnderBridge(target);
|
||||||
MarkTileDirtyByTile(target);
|
MarkTileDirtyByTile(target);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
_current_player = OWNER_WATER;
|
_current_player = OWNER_WATER;
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue