mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r9892) -Codechange: lots of ground work for allowing multiple types of "road" with multiple owners on a single tile.
This commit is contained in:
parent
c685a7179f
commit
d86b5e5e93
|
@ -2579,11 +2579,11 @@ static int32 AiDoBuildDefaultRoadBlock(TileIndex tile, const AiDefaultBlockData
|
|||
if (p->mode == 2) {
|
||||
if (IsTileType(c, MP_STREET) &&
|
||||
GetRoadTileType(c) == ROAD_TILE_NORMAL &&
|
||||
(GetRoadBits(c) & p->attr) != 0) {
|
||||
(GetRoadBits(c, ROADTYPE_ROAD) & p->attr) != 0) {
|
||||
roadflag |= 2;
|
||||
|
||||
// all bits are already built?
|
||||
if ((GetRoadBits(c) & p->attr) == p->attr) continue;
|
||||
if ((GetRoadBits(c, ROADTYPE_ROAD) & p->attr) == p->attr) continue;
|
||||
}
|
||||
|
||||
ret = DoCommand(c, p->attr, 0, flag | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD);
|
||||
|
|
|
@ -211,7 +211,6 @@ static inline void SetBridgeMiddle(TileIndex t, Axis a)
|
|||
SETBIT(_m[t].m6, 6 + a);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generic part to make a bridge ramp for both roads and rails.
|
||||
* @param t the tile to make a bridge ramp
|
||||
|
@ -219,13 +218,15 @@ static inline void SetBridgeMiddle(TileIndex t, Axis a)
|
|||
* @param bridgetype the type of bridge this bridge ramp belongs to
|
||||
* @param d the direction this ramp must be facing
|
||||
* @param tt the transport type of the bridge
|
||||
* @param rt the road or rail type
|
||||
* @note this function should not be called directly.
|
||||
*/
|
||||
static inline void MakeBridgeRamp(TileIndex t, Owner o, uint bridgetype, DiagDirection d, TransportType tt)
|
||||
static inline void MakeBridgeRamp(TileIndex t, Owner o, uint bridgetype, DiagDirection d, TransportType tt, uint rt)
|
||||
{
|
||||
SetTileType(t, MP_TUNNELBRIDGE);
|
||||
SetTileOwner(t, o);
|
||||
_m[t].m2 = bridgetype << 4;
|
||||
_m[t].m3 = rt;
|
||||
_m[t].m4 = 0;
|
||||
_m[t].m5 = 1 << 7 | tt << 2 | d;
|
||||
}
|
||||
|
@ -236,11 +237,11 @@ static inline void MakeBridgeRamp(TileIndex t, Owner o, uint bridgetype, DiagDir
|
|||
* @param o the new owner of the bridge ramp
|
||||
* @param bridgetype the type of bridge this bridge ramp belongs to
|
||||
* @param d the direction this ramp must be facing
|
||||
* @param r the road type of the bridge
|
||||
*/
|
||||
static inline void MakeRoadBridgeRamp(TileIndex t, Owner o, uint bridgetype, DiagDirection d)
|
||||
static inline void MakeRoadBridgeRamp(TileIndex t, Owner o, uint bridgetype, DiagDirection d, RoadTypes r)
|
||||
{
|
||||
MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_ROAD);
|
||||
_m[t].m3 = 0;
|
||||
MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_ROAD, r);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -253,8 +254,7 @@ static inline void MakeRoadBridgeRamp(TileIndex t, Owner o, uint bridgetype, Dia
|
|||
*/
|
||||
static inline void MakeRailBridgeRamp(TileIndex t, Owner o, uint bridgetype, DiagDirection d, RailType r)
|
||||
{
|
||||
MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_RAIL);
|
||||
_m[t].m3 = r;
|
||||
MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_RAIL, r);
|
||||
}
|
||||
|
||||
|
||||
|
|
103
src/openttd.cpp
103
src/openttd.cpp
|
@ -1108,8 +1108,8 @@ static void ConvertTownOwner()
|
|||
for (tile = 0; tile != MapSize(); tile++) {
|
||||
switch (GetTileType(tile)) {
|
||||
case MP_STREET:
|
||||
if (IsLevelCrossing(tile) && GetCrossingRoadOwner(tile) & 0x80) {
|
||||
SetCrossingRoadOwner(tile, OWNER_TOWN);
|
||||
if (GB(_m[tile].m5, 4, 2) == ROAD_TILE_CROSSING && HASBIT(_m[tile].m4, 7)) {
|
||||
_m[tile].m4 = OWNER_TOWN;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
|
||||
|
@ -1414,6 +1414,70 @@ bool AfterLoadGame()
|
|||
}
|
||||
}
|
||||
|
||||
if (CheckSavegameVersion(48)) {
|
||||
for (TileIndex t = 0; t < map_size; t++) {
|
||||
switch (GetTileType(t)) {
|
||||
case MP_RAILWAY:
|
||||
if (IsPlainRailTile(t)) {
|
||||
/* Swap ground type and signal type for plain rail tiles, so the
|
||||
* ground type uses the same bits as for depots and waypoints. */
|
||||
uint tmp = GB(_m[t].m4, 0, 4);
|
||||
SB(_m[t].m4, 0, 4, GB(_m[t].m2, 0, 4));
|
||||
SB(_m[t].m2, 0, 4, tmp);
|
||||
} else if (HASBIT(_m[t].m5, 2)) {
|
||||
/* Split waypoint and depot rail type and remove the subtype. */
|
||||
CLRBIT(_m[t].m5, 2);
|
||||
CLRBIT(_m[t].m5, 6);
|
||||
}
|
||||
break;
|
||||
|
||||
case MP_STREET:
|
||||
/* Swap m3 and m4, so the track type for rail crossings is the
|
||||
* same as for normal rail. */
|
||||
Swap(_m[t].m3, _m[t].m4);
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (CheckSavegameVersion(61)) {
|
||||
/* Added the RoadType */
|
||||
for (TileIndex t = 0; t < map_size; t++) {
|
||||
switch(GetTileType(t)) {
|
||||
case MP_STREET:
|
||||
SB(_m[t].m5, 6, 2, GB(_m[t].m5, 4, 2));
|
||||
switch (GetRoadTileType(t)) {
|
||||
default: NOT_REACHED();
|
||||
case ROAD_TILE_NORMAL:
|
||||
SB(_m[t].m4, 0, 4, GB(_m[t].m5, 0, 4));
|
||||
SB(_m[t].m4, 4, 4, 0);
|
||||
SB(_m[t].m6, 2, 4, 0);
|
||||
break;
|
||||
case ROAD_TILE_CROSSING:
|
||||
SB(_m[t].m4, 5, 2, GB(_m[t].m5, 2, 2));
|
||||
break;
|
||||
case ROAD_TILE_DEPOT: break;
|
||||
}
|
||||
SetRoadTypes(t, ROADTYPES_ROAD);
|
||||
break;
|
||||
|
||||
case MP_STATION:
|
||||
if (IsRoadStop(t)) SetRoadTypes(t, ROADTYPES_ROAD);
|
||||
break;
|
||||
|
||||
case MP_TUNNELBRIDGE:
|
||||
if ((IsTunnel(t) ? GetTunnelTransportType(t) : GetBridgeTransportType(t)) == TRANSPORT_ROAD) {
|
||||
SetRoadTypes(t, ROADTYPES_ROAD);
|
||||
}
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (CheckSavegameVersion(42)) {
|
||||
Vehicle* v;
|
||||
|
||||
|
@ -1436,9 +1500,10 @@ bool AfterLoadGame()
|
|||
|
||||
MakeRoadNormal(
|
||||
t,
|
||||
GetTileOwner(t),
|
||||
axis == AXIS_X ? ROAD_Y : ROAD_X,
|
||||
town
|
||||
ROADTYPES_ROAD,
|
||||
town,
|
||||
GetTileOwner(t), OWNER_NONE, OWNER_NONE
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
@ -1486,34 +1551,6 @@ bool AfterLoadGame()
|
|||
}
|
||||
}
|
||||
|
||||
if (CheckSavegameVersion(48)) {
|
||||
for (TileIndex t = 0; t < map_size; t++) {
|
||||
switch (GetTileType(t)) {
|
||||
case MP_RAILWAY:
|
||||
if (IsPlainRailTile(t)) {
|
||||
/* Swap ground type and signal type for plain rail tiles, so the
|
||||
* ground type uses the same bits as for depots and waypoints. */
|
||||
uint tmp = GB(_m[t].m4, 0, 4);
|
||||
SB(_m[t].m4, 0, 4, GB(_m[t].m2, 0, 4));
|
||||
SB(_m[t].m2, 0, 4, tmp);
|
||||
} else if (HASBIT(_m[t].m5, 2)) {
|
||||
/* Split waypoint and depot rail type and remove the subtype. */
|
||||
CLRBIT(_m[t].m5, 2);
|
||||
CLRBIT(_m[t].m5, 6);
|
||||
}
|
||||
break;
|
||||
|
||||
case MP_STREET:
|
||||
/* Swap m3 and m4, so the track type for rail crossings is the
|
||||
* same as for normal rail. */
|
||||
Swap(_m[t].m3, _m[t].m4);
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Elrails got added in rev 24 */
|
||||
if (CheckSavegameVersion(24)) {
|
||||
Vehicle *v;
|
||||
|
@ -1772,8 +1809,6 @@ bool AfterLoadGame()
|
|||
* space for newhouses grf features. A new byte, m7, was also added. */
|
||||
if (CheckSavegameVersion(53)) {
|
||||
for (TileIndex t = 0; t < map_size; t++) {
|
||||
_me[t].m7 = 0;
|
||||
|
||||
if (IsTileType(t, MP_HOUSE)) {
|
||||
if (GB(_m[t].m3, 6, 2) != TOWN_HOUSE_COMPLETED) {
|
||||
/* Move the construction stage from m3[7..6] to m5[5..4].
|
||||
|
|
|
@ -295,10 +295,25 @@ int32 CmdBuildSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
if (GetRoadTileType(tile) == ROAD_TILE_NORMAL) {
|
||||
if (HasRoadWorks(tile)) return_cmd_error(STR_ROAD_WORKS_IN_PROGRESS);
|
||||
|
||||
if ((track == TRACK_X && GetRoadBits(tile) == ROAD_Y) ||
|
||||
(track == TRACK_Y && GetRoadBits(tile) == ROAD_X)) {
|
||||
RoadTypes roadtypes = GetRoadTypes(tile);
|
||||
RoadBits road = GetRoadBits(tile, ROADTYPE_ROAD);
|
||||
RoadBits tram = GetRoadBits(tile, ROADTYPE_TRAM);
|
||||
switch (roadtypes) {
|
||||
default: break;
|
||||
case ROADTYPES_ROADTRAM: if (road == tram) break;
|
||||
/* FALL THROUGH */
|
||||
case ROADTYPES_ROADHWAY: // Road and highway are incompatible in this case
|
||||
case ROADTYPES_TRAMHWAY: // Tram and highway are incompatible in this case
|
||||
case ROADTYPES_ALL: // Also incompatible
|
||||
return CMD_ERROR;
|
||||
}
|
||||
|
||||
road |= tram | GetRoadBits(tile, ROADTYPE_HWAY);
|
||||
|
||||
if ((track == TRACK_X && road == ROAD_Y) ||
|
||||
(track == TRACK_Y && road == ROAD_X)) {
|
||||
if (flags & DC_EXEC) {
|
||||
MakeRoadCrossing(tile, GetTileOwner(tile), _current_player, (track == TRACK_X ? AXIS_Y : AXIS_X), railtype, GetTownIndex(tile));
|
||||
MakeRoadCrossing(tile, GetRoadOwner(tile, ROADTYPE_ROAD), GetRoadOwner(tile, ROADTYPE_TRAM), GetRoadOwner(tile, ROADTYPE_HWAY), _current_player, (track == TRACK_X ? AXIS_Y : AXIS_X), railtype, roadtypes, GetTownIndex(tile));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -359,7 +374,7 @@ int32 CmdRemoveSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
}
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
MakeRoadNormal(tile, GetCrossingRoadOwner(tile), GetCrossingRoadBits(tile), GetTownIndex(tile));
|
||||
MakeRoadNormal(tile, GetCrossingRoadBits(tile), GetRoadTypes(tile), GetTownIndex(tile), GetRoadOwner(tile, ROADTYPE_ROAD), GetRoadOwner(tile, ROADTYPE_TRAM), GetRoadOwner(tile, ROADTYPE_HWAY));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
65
src/road.h
65
src/road.h
|
@ -7,6 +7,68 @@
|
|||
|
||||
#include "helpers.hpp"
|
||||
|
||||
/**
|
||||
* The different roadtypes we support
|
||||
* @note currently only ROADTYPE_ROAD is supported.
|
||||
*/
|
||||
enum RoadType {
|
||||
ROADTYPE_ROAD = 0,
|
||||
ROADTYPE_TRAM = 1,
|
||||
ROADTYPE_HWAY = 2, ///< Only a placeholder. Not sure what we are going to do with this road type.
|
||||
ROADTYPE_END,
|
||||
INVALID_ROADTYPE = 0xFF
|
||||
};
|
||||
DECLARE_POSTFIX_INCREMENT(RoadType);
|
||||
|
||||
/**
|
||||
* The different roadtypes we support, but then a bitmask of them
|
||||
* @note currently only ROADTYPES_ROAD is supported.
|
||||
*/
|
||||
enum RoadTypes {
|
||||
ROADTYPES_NONE = 0,
|
||||
ROADTYPES_ROAD = 1 << ROADTYPE_ROAD,
|
||||
ROADTYPES_TRAM = 1 << ROADTYPE_TRAM,
|
||||
ROADTYPES_HWAY = 1 << ROADTYPE_HWAY,
|
||||
ROADTYPES_ROADTRAM = ROADTYPES_ROAD | ROADTYPES_TRAM,
|
||||
ROADTYPES_ROADHWAY = ROADTYPES_ROAD | ROADTYPES_HWAY,
|
||||
ROADTYPES_TRAMHWAY = ROADTYPES_TRAM | ROADTYPES_HWAY,
|
||||
ROADTYPES_ALL = ROADTYPES_ROAD | ROADTYPES_TRAM | ROADTYPES_HWAY,
|
||||
};
|
||||
DECLARE_ENUM_AS_BIT_SET(RoadTypes);
|
||||
|
||||
/**
|
||||
* Whether the given roadtype is valid.
|
||||
* @param rt the roadtype to check for validness
|
||||
* @return true if and only if valid
|
||||
*/
|
||||
static inline bool IsValidRoadType(RoadType rt)
|
||||
{
|
||||
return rt == ROADTYPE_ROAD;
|
||||
}
|
||||
|
||||
/**
|
||||
* Are the given bits pointing to valid roadtypes?
|
||||
* @param rts the roadtypes to check for validness
|
||||
* @return true if and only if valid
|
||||
*/
|
||||
static inline bool AreValidRoadTypes(RoadTypes rts)
|
||||
{
|
||||
return rts == ROADTYPES_ROAD;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps a RoadType to the corresponding RoadTypes value
|
||||
*/
|
||||
static inline RoadTypes RoadTypeToRoadTypes(RoadType rt)
|
||||
{
|
||||
return (RoadTypes)(1 << rt);
|
||||
}
|
||||
|
||||
static inline RoadTypes ComplementRoadTypes(RoadTypes r)
|
||||
{
|
||||
return (RoadTypes)(ROADTYPES_ALL ^ r);
|
||||
}
|
||||
|
||||
enum RoadBits {
|
||||
ROAD_NONE = 0U,
|
||||
ROAD_NW = 1U,
|
||||
|
@ -48,8 +110,9 @@ static inline bool IsStraightRoadTrackdir(Trackdir dir)
|
|||
* @param remove the roadbits that are going to be removed
|
||||
* @param owner the actual owner of the roadbits of the tile
|
||||
* @param edge_road are the removed bits from a town?
|
||||
* @param rt the road type to remove the bits from
|
||||
* @return true when it is allowed to remove the road bits
|
||||
*/
|
||||
bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, bool *edge_road);
|
||||
bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, bool *edge_road, RoadType rt);
|
||||
|
||||
#endif /* ROAD_H */
|
||||
|
|
134
src/road_cmd.cpp
134
src/road_cmd.cpp
|
@ -41,13 +41,13 @@ static uint CountRoadBits(RoadBits r)
|
|||
}
|
||||
|
||||
|
||||
bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, bool *edge_road)
|
||||
bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, bool *edge_road, RoadType rt)
|
||||
{
|
||||
RoadBits present;
|
||||
RoadBits n;
|
||||
*edge_road = true;
|
||||
|
||||
if (_game_mode == GM_EDITOR) return true;
|
||||
if (_game_mode == GM_EDITOR || remove == ROAD_NONE) return true;
|
||||
|
||||
/* Only do the special processing for actual players. */
|
||||
if (!IsValidPlayer(_current_player)) return true;
|
||||
|
@ -60,11 +60,11 @@ bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, bool *ed
|
|||
|
||||
/* Get a bitmask of which neighbouring roads has a tile */
|
||||
n = ROAD_NONE;
|
||||
present = GetAnyRoadBits(tile);
|
||||
if (present & ROAD_NE && GetAnyRoadBits(TILE_ADDXY(tile, -1, 0)) & ROAD_SW) n |= ROAD_NE;
|
||||
if (present & ROAD_SE && GetAnyRoadBits(TILE_ADDXY(tile, 0, 1)) & ROAD_NW) n |= ROAD_SE;
|
||||
if (present & ROAD_SW && GetAnyRoadBits(TILE_ADDXY(tile, 1, 0)) & ROAD_NE) n |= ROAD_SW;
|
||||
if (present & ROAD_NW && GetAnyRoadBits(TILE_ADDXY(tile, 0, -1)) & ROAD_SE) n |= ROAD_NW;
|
||||
present = GetAnyRoadBits(tile, rt);
|
||||
if (present & ROAD_NE && GetAnyRoadBits(TILE_ADDXY(tile, -1, 0), rt) & ROAD_SW) n |= ROAD_NE;
|
||||
if (present & ROAD_SE && GetAnyRoadBits(TILE_ADDXY(tile, 0, 1), rt) & ROAD_NW) n |= ROAD_SE;
|
||||
if (present & ROAD_SW && GetAnyRoadBits(TILE_ADDXY(tile, 1, 0), rt) & ROAD_NE) n |= ROAD_SW;
|
||||
if (present & ROAD_NW && GetAnyRoadBits(TILE_ADDXY(tile, 0, -1), rt) & ROAD_SE) n |= ROAD_NW;
|
||||
|
||||
/* If 0 or 1 bits are set in n, or if no bits that match the bits to remove,
|
||||
* then allow it */
|
||||
|
@ -84,15 +84,16 @@ bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, bool *ed
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, bool *edge_road)
|
||||
static bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, bool *edge_road, RoadType rt)
|
||||
{
|
||||
return CheckAllowRemoveRoad(tile, remove, IsLevelCrossingTile(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile), edge_road);
|
||||
return CheckAllowRemoveRoad(tile, remove, GetRoadOwner(tile, rt), edge_road, rt);
|
||||
}
|
||||
|
||||
/** Delete a piece of road.
|
||||
* @param tile tile where to remove road from
|
||||
* @param flags operation to perform
|
||||
* @param p1 bit 0..3 road pieces to remove (RoadBits)
|
||||
* bit 4..5 road type
|
||||
* @param p2 unused
|
||||
*/
|
||||
int32 CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
||||
|
@ -100,7 +101,6 @@ int32 CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
/* cost for removing inner/edge -roads */
|
||||
static const uint16 road_remove_cost[2] = {50, 18};
|
||||
|
||||
Owner owner;
|
||||
Town *t;
|
||||
/* true if the roadpiece was always removeable,
|
||||
* false if it was a center piece. Affects town ratings drop */
|
||||
|
@ -108,9 +108,10 @@ int32 CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
|
||||
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
|
||||
|
||||
if (!IsTileType(tile, MP_STREET)) return CMD_ERROR;
|
||||
RoadType rt = (RoadType)GB(p1, 4, 2);
|
||||
if (!IsTileType(tile, MP_STREET) || !IsValidRoadType(rt)) return CMD_ERROR;
|
||||
|
||||
owner = IsLevelCrossingTile(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile);
|
||||
Owner owner = GetRoadOwner(tile, rt);
|
||||
|
||||
if (owner == OWNER_TOWN && _game_mode != GM_EDITOR) {
|
||||
t = GetTownByTile(tile);
|
||||
|
@ -119,8 +120,11 @@ int32 CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
}
|
||||
|
||||
RoadBits pieces = Extract<RoadBits, 0>(p1);
|
||||
RoadTypes rts = GetRoadTypes(tile);
|
||||
/* The tile doesn't have the given road type */
|
||||
if (!HASBIT(rts, rt)) return CMD_ERROR;
|
||||
|
||||
if (!CheckAllowRemoveRoad(tile, pieces, &edge_road)) return CMD_ERROR;
|
||||
if (!CheckAllowRemoveRoad(tile, pieces, &edge_road, rt)) return CMD_ERROR;
|
||||
|
||||
if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
|
||||
|
||||
|
@ -130,7 +134,7 @@ int32 CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
|
||||
switch (GetRoadTileType(tile)) {
|
||||
case ROAD_TILE_NORMAL: {
|
||||
RoadBits present = GetRoadBits(tile);
|
||||
RoadBits present = GetRoadBits(tile, rt);
|
||||
RoadBits c = pieces;
|
||||
|
||||
if (HasRoadWorks(tile)) return_cmd_error(STR_ROAD_WORKS_IN_PROGRESS);
|
||||
|
@ -150,9 +154,14 @@ int32 CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
|
||||
present ^= c;
|
||||
if (present == 0) {
|
||||
DoClearSquare(tile);
|
||||
RoadTypes rts = GetRoadTypes(tile) & ComplementRoadTypes(RoadTypeToRoadTypes(rt));
|
||||
if (rts == ROADTYPES_NONE) {
|
||||
DoClearSquare(tile);
|
||||
} else {
|
||||
SetRoadTypes(tile, rts);
|
||||
}
|
||||
} else {
|
||||
SetRoadBits(tile, present);
|
||||
SetRoadBits(tile, present, rt);
|
||||
MarkTileDirtyByTile(tile);
|
||||
}
|
||||
}
|
||||
|
@ -165,9 +174,16 @@ int32 CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
}
|
||||
|
||||
if (flags & DC_EXEC) {
|
||||
ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
|
||||
if (rt == ROADTYPE_ROAD) {
|
||||
ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
|
||||
}
|
||||
|
||||
MakeRailNormal(tile, GetTileOwner(tile), GetCrossingRailBits(tile), GetRailType(tile));
|
||||
RoadTypes rts = GetRoadTypes(tile) & ComplementRoadTypes(RoadTypeToRoadTypes(rt));
|
||||
if (rts == ROADTYPES_NONE) {
|
||||
MakeRailNormal(tile, GetTileOwner(tile), GetCrossingRailBits(tile), GetRailType(tile));
|
||||
} else {
|
||||
SetRoadTypes(tile, rts);
|
||||
}
|
||||
MarkTileDirtyByTile(tile);
|
||||
YapfNotifyTrackLayoutChange(tile, FindFirstTrack(GetTrackBits(tile)));
|
||||
}
|
||||
|
@ -255,6 +271,7 @@ static uint32 CheckRoadSlope(Slope tileh, RoadBits* pieces, RoadBits existing)
|
|||
* @param tile tile where to build road
|
||||
* @param flags operation to perform
|
||||
* @param p1 bit 0..3 road pieces to build (RoadBits)
|
||||
* bit 4..5 road type
|
||||
* @param p2 the town that is building the road (0 if not applicable)
|
||||
*/
|
||||
int32 CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
||||
|
@ -272,6 +289,9 @@ int32 CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
|
||||
RoadBits pieces = Extract<RoadBits, 0>(p1);
|
||||
|
||||
RoadType rt = (RoadType)GB(p1, 4, 2);
|
||||
if (!IsValidRoadType(rt)) return CMD_ERROR;
|
||||
|
||||
tileh = GetTileSlope(tile, NULL);
|
||||
|
||||
switch (GetTileType(tile)) {
|
||||
|
@ -280,7 +300,7 @@ int32 CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
case ROAD_TILE_NORMAL:
|
||||
if (HasRoadWorks(tile)) return_cmd_error(STR_ROAD_WORKS_IN_PROGRESS);
|
||||
|
||||
existing = GetRoadBits(tile);
|
||||
existing = GetRoadBits(tile, rt);
|
||||
if ((existing & pieces) == pieces) {
|
||||
return_cmd_error(STR_1007_ALREADY_BUILT);
|
||||
}
|
||||
|
@ -288,10 +308,9 @@ int32 CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
break;
|
||||
|
||||
case ROAD_TILE_CROSSING:
|
||||
if (pieces != GetCrossingRoadBits(tile)) { // XXX is this correct?
|
||||
return_cmd_error(STR_1007_ALREADY_BUILT);
|
||||
}
|
||||
goto do_clear;
|
||||
if (HASBIT(GetRoadTypes(tile), rt)) return_cmd_error(STR_1007_ALREADY_BUILT);
|
||||
if (pieces & ComplementRoadBits(GetCrossingRoadBits(tile))) goto do_clear;
|
||||
break;
|
||||
|
||||
default:
|
||||
case ROAD_TILE_DEPOT:
|
||||
|
@ -332,7 +351,7 @@ int32 CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
|
||||
if (flags & DC_EXEC) {
|
||||
YapfNotifyTrackLayoutChange(tile, FindFirstTrack(GetTrackBits(tile)));
|
||||
MakeRoadCrossing(tile, _current_player, GetTileOwner(tile), roaddir, GetRailType(tile), p2);
|
||||
MakeRoadCrossing(tile, _current_player, _current_player, _current_player, GetTileOwner(tile), roaddir, GetRailType(tile), RoadTypeToRoadTypes(rt), p2);
|
||||
MarkTileDirtyByTile(tile);
|
||||
}
|
||||
return _price.build_road * 2;
|
||||
|
@ -362,9 +381,13 @@ do_clear:;
|
|||
|
||||
if (flags & DC_EXEC) {
|
||||
if (IsTileType(tile, MP_STREET)) {
|
||||
SetRoadBits(tile, existing | pieces);
|
||||
if (existing == 0) {
|
||||
SetRoadTypes(tile, GetRoadTypes(tile) | RoadTypeToRoadTypes(rt));
|
||||
SetRoadOwner(tile, rt, _current_player);
|
||||
}
|
||||
SetRoadBits(tile, existing | pieces, rt);
|
||||
} else {
|
||||
MakeRoadNormal(tile, _current_player, pieces, p2);
|
||||
MakeRoadNormal(tile, pieces, RoadTypeToRoadTypes(rt), p2, _current_player, _current_player, _current_player);
|
||||
}
|
||||
|
||||
MarkTileDirtyByTile(tile);
|
||||
|
@ -411,6 +434,7 @@ int32 DoConvertStreetRail(TileIndex tile, RailType totype, bool exec)
|
|||
* - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1)
|
||||
* - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2)
|
||||
* - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4)
|
||||
* - p2 = (bit 3) - road type
|
||||
*/
|
||||
int32 CmdBuildLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
|
||||
{
|
||||
|
@ -422,6 +446,7 @@ int32 CmdBuildLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
if (p1 >= MapSize()) return CMD_ERROR;
|
||||
|
||||
start_tile = p1;
|
||||
RoadType rt = (RoadType)HASBIT(p2, 3);
|
||||
|
||||
/* Only drag in X or Y direction dictated by the direction variable */
|
||||
if (!HASBIT(p2, 2) && TileY(start_tile) != TileY(end_tile)) return CMD_ERROR; // x-axis
|
||||
|
@ -444,7 +469,7 @@ int32 CmdBuildLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
if (tile == end_tile && !HASBIT(p2, 1)) bits &= ROAD_NW | ROAD_NE;
|
||||
if (tile == start_tile && HASBIT(p2, 0)) bits &= ROAD_SE | ROAD_SW;
|
||||
|
||||
ret = DoCommand(tile, bits, 0, flags, CMD_BUILD_ROAD);
|
||||
ret = DoCommand(tile, rt << 4 | bits, 0, flags, CMD_BUILD_ROAD);
|
||||
if (CmdFailed(ret)) {
|
||||
if (_error_message != STR_1007_ALREADY_BUILT) return CMD_ERROR;
|
||||
_error_message = INVALID_STRING_ID;
|
||||
|
@ -468,6 +493,7 @@ int32 CmdBuildLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
* - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1)
|
||||
* - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2)
|
||||
* - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4)
|
||||
* - p2 = (bit 3) - road type
|
||||
*/
|
||||
int32 CmdRemoveLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
|
||||
{
|
||||
|
@ -479,6 +505,7 @@ int32 CmdRemoveLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
if (p1 >= MapSize()) return CMD_ERROR;
|
||||
|
||||
start_tile = p1;
|
||||
RoadType rt = (RoadType)HASBIT(p2, 3);
|
||||
|
||||
/* Only drag in X or Y direction dictated by the direction variable */
|
||||
if (!HASBIT(p2, 2) && TileY(start_tile) != TileY(end_tile)) return CMD_ERROR; // x-axis
|
||||
|
@ -503,7 +530,7 @@ int32 CmdRemoveLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
|
||||
/* try to remove the halves. */
|
||||
if (bits != 0) {
|
||||
ret = DoCommand(tile, bits, 0, flags, CMD_REMOVE_ROAD);
|
||||
ret = DoCommand(tile, rt << 4 | bits, 0, flags, CMD_REMOVE_ROAD);
|
||||
if (!CmdFailed(ret)) cost += ret;
|
||||
}
|
||||
|
||||
|
@ -519,6 +546,7 @@ int32 CmdRemoveLongRoad(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
* @param tile tile where to build the depot
|
||||
* @param flags operation to perform
|
||||
* @param p1 bit 0..1 entrance direction (DiagDirection)
|
||||
* bit 2 road type
|
||||
* @param p2 unused
|
||||
*
|
||||
* @todo When checking for the tile slope,
|
||||
|
@ -533,6 +561,7 @@ int32 CmdBuildRoadDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
|
||||
|
||||
DiagDirection dir = Extract<DiagDirection, 0>(p1);
|
||||
RoadType rt = (RoadType)HASBIT(p1, 2);
|
||||
|
||||
tileh = GetTileSlope(tile, NULL);
|
||||
if (tileh != SLOPE_FLAT && (
|
||||
|
@ -555,7 +584,7 @@ int32 CmdBuildRoadDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
dep->xy = tile;
|
||||
dep->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
|
||||
|
||||
MakeRoadDepot(tile, _current_player, dir);
|
||||
MakeRoadDepot(tile, _current_player, dir, rt);
|
||||
MarkTileDirtyByTile(tile);
|
||||
}
|
||||
return cost + _price.build_road_depot;
|
||||
|
@ -577,7 +606,7 @@ static int32 ClearTile_Road(TileIndex tile, byte flags)
|
|||
{
|
||||
switch (GetRoadTileType(tile)) {
|
||||
case ROAD_TILE_NORMAL: {
|
||||
RoadBits b = GetRoadBits(tile);
|
||||
RoadBits b = GetAllRoadBits(tile);
|
||||
|
||||
#define M(x) (1 << (x))
|
||||
/* Clear the road if only one piece is on the tile OR the AI tries
|
||||
|
@ -685,7 +714,7 @@ static bool AlwaysDrawUnpavedRoads(TileIndex tile, Roadside roadside)
|
|||
*/
|
||||
static void DrawRoadBits(TileInfo* ti)
|
||||
{
|
||||
RoadBits road = GetRoadBits(ti->tile);
|
||||
RoadBits road = GetRoadBits(ti->tile, ROADTYPE_ROAD);
|
||||
const DrawRoadTileStruct *drts;
|
||||
SpriteID image = 0;
|
||||
SpriteID pal = PAL_NONE;
|
||||
|
@ -836,7 +865,7 @@ static uint GetSlopeZ_Road(TileIndex tile, uint x, uint y)
|
|||
|
||||
if (tileh == SLOPE_FLAT) return z;
|
||||
if (GetRoadTileType(tile) == ROAD_TILE_NORMAL) {
|
||||
uint f = GetRoadFoundation(tileh, GetRoadBits(tile));
|
||||
uint f = GetRoadFoundation(tileh, GetAllRoadBits(tile));
|
||||
|
||||
if (f != 0) {
|
||||
if (IsSteepSlope(tileh)) {
|
||||
|
@ -856,7 +885,7 @@ static Slope GetSlopeTileh_Road(TileIndex tile, Slope tileh)
|
|||
{
|
||||
if (tileh == SLOPE_FLAT) return SLOPE_FLAT;
|
||||
if (GetRoadTileType(tile) == ROAD_TILE_NORMAL) {
|
||||
uint f = GetRoadFoundation(tileh, GetRoadBits(tile));
|
||||
uint f = GetRoadFoundation(tileh, GetAllRoadBits(tile));
|
||||
|
||||
if (f == 0) return tileh;
|
||||
if (f < 15) return SLOPE_FLAT; // leveled foundation
|
||||
|
@ -924,7 +953,7 @@ static void TileLoop_Road(TileIndex tile)
|
|||
/* Show an animation to indicate road work */
|
||||
if (t->road_build_months != 0 &&
|
||||
(DistanceManhattan(t->xy, tile) < 8 || grp != 0) &&
|
||||
GetRoadTileType(tile) == ROAD_TILE_NORMAL && (GetRoadBits(tile) == ROAD_X || GetRoadBits(tile) == ROAD_Y)) {
|
||||
GetRoadTileType(tile) == ROAD_TILE_NORMAL && (GetAllRoadBits(tile) == ROAD_X || GetAllRoadBits(tile) == ROAD_Y)) {
|
||||
if (GetTileSlope(tile, NULL) == SLOPE_FLAT && EnsureNoVehicleOnGround(tile) && CHANCE16(1, 20)) {
|
||||
StartRoadWorks(tile);
|
||||
|
||||
|
@ -978,15 +1007,18 @@ static const byte _road_trackbits[16] = {
|
|||
|
||||
static uint32 GetTileTrackStatus_Road(TileIndex tile, TransportType mode)
|
||||
{
|
||||
RoadType rt = ROADTYPE_ROAD;
|
||||
|
||||
switch (mode) {
|
||||
case TRANSPORT_RAIL:
|
||||
if (!IsLevelCrossing(tile)) return 0;
|
||||
return GetCrossingRailBits(tile) * 0x101;
|
||||
|
||||
case TRANSPORT_ROAD:
|
||||
if (!HASBIT(GetRoadTypes(tile), rt)) return 0;
|
||||
switch (GetRoadTileType(tile)) {
|
||||
case ROAD_TILE_NORMAL:
|
||||
return HasRoadWorks(tile) ? 0 : _road_trackbits[GetRoadBits(tile)] * 0x101;
|
||||
return HasRoadWorks(tile) ? 0 : _road_trackbits[GetRoadBits(tile, rt)] * 0x101;
|
||||
|
||||
case ROAD_TILE_CROSSING: {
|
||||
uint32 r = AxisToTrackBits(GetCrossingRoadAxis(tile)) * 0x101;
|
||||
|
@ -1060,30 +1092,26 @@ static uint32 VehicleEnter_Road(Vehicle *v, TileIndex tile, int x, int y)
|
|||
|
||||
static void ChangeTileOwner_Road(TileIndex tile, PlayerID old_player, PlayerID new_player)
|
||||
{
|
||||
if (IsLevelCrossing(tile) && GetCrossingRoadOwner(tile) == old_player) {
|
||||
SetCrossingRoadOwner(tile, new_player == PLAYER_SPECTATOR ? OWNER_NONE : new_player);
|
||||
if (GetRoadTileType(tile) == ROAD_TILE_DEPOT) {
|
||||
DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsTileOwner(tile, old_player)) return;
|
||||
for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) {
|
||||
if (!HASBIT(GetRoadTypes(tile), rt)) continue;
|
||||
|
||||
if (new_player != PLAYER_SPECTATOR) {
|
||||
SetTileOwner(tile, new_player);
|
||||
} else {
|
||||
switch (GetRoadTileType(tile)) {
|
||||
case ROAD_TILE_NORMAL:
|
||||
SetTileOwner(tile, OWNER_NONE);
|
||||
break;
|
||||
if (GetRoadOwner(tile, rt) == old_player) {
|
||||
SetRoadOwner(tile, rt, new_player == PLAYER_SPECTATOR ? OWNER_NONE : new_player);
|
||||
|
||||
case ROAD_TILE_CROSSING:
|
||||
MakeRoadNormal(tile, GetCrossingRoadOwner(tile), GetCrossingRoadBits(tile), GetTownIndex(tile));
|
||||
break;
|
||||
|
||||
default:
|
||||
case ROAD_TILE_DEPOT:
|
||||
DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
|
||||
break;
|
||||
if (rt == ROADTYPE_TRAM) {
|
||||
DoCommand(tile, ROADTYPE_TRAM << 4 | GetRoadBits(tile, ROADTYPE_ROAD), 0, DC_EXEC, CMD_REMOVE_ROAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IsLevelCrossing(tile)) {
|
||||
MakeRoadNormal(tile, GetCrossingRoadBits(tile), GetRoadTypes(tile), GetTownIndex(tile), GetRoadOwner(tile, ROADTYPE_ROAD), GetRoadOwner(tile, ROADTYPE_TRAM), GetRoadOwner(tile, ROADTYPE_HWAY));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ void CcBuildRoadTunnel(bool success, TileIndex tile, uint32 p1, uint32 p2)
|
|||
|
||||
static void PlaceRoad_Tunnel(TileIndex tile)
|
||||
{
|
||||
DoCommandP(tile, 0x200, 0, CcBuildRoadTunnel, CMD_BUILD_TUNNEL | CMD_AUTO | CMD_MSG(STR_5016_CAN_T_BUILD_TUNNEL_HERE));
|
||||
DoCommandP(tile, 0x200 | ROADTYPES_ROAD, 0, CcBuildRoadTunnel, CMD_BUILD_TUNNEL | CMD_AUTO | CMD_MSG(STR_5016_CAN_T_BUILD_TUNNEL_HERE));
|
||||
}
|
||||
|
||||
static void BuildRoadOutsideStation(TileIndex tile, DiagDirection direction)
|
||||
|
@ -113,7 +113,7 @@ static void PlaceRoad_BusStation(TileIndex tile)
|
|||
if (_remove_button_clicked) {
|
||||
DoCommandP(tile, 0, RoadStop::BUS, CcPlaySound1D, CMD_REMOVE_ROAD_STOP | CMD_MSG(STR_CAN_T_REMOVE_BUS_STATION));
|
||||
} else {
|
||||
PlaceRoadStop(tile, RoadStop::BUS, CMD_BUILD_ROAD_STOP | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1808_CAN_T_BUILD_BUS_STATION));
|
||||
PlaceRoadStop(tile, ROADTYPES_ROAD << 2 | RoadStop::BUS, CMD_BUILD_ROAD_STOP | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1808_CAN_T_BUILD_BUS_STATION));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,7 +122,7 @@ static void PlaceRoad_TruckStation(TileIndex tile)
|
|||
if (_remove_button_clicked) {
|
||||
DoCommandP(tile, 0, RoadStop::TRUCK, CcPlaySound1D, CMD_REMOVE_ROAD_STOP | CMD_MSG(STR_CAN_T_REMOVE_TRUCK_STATION));
|
||||
} else {
|
||||
PlaceRoadStop(tile, RoadStop::TRUCK, CMD_BUILD_ROAD_STOP | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1809_CAN_T_BUILD_TRUCK_STATION));
|
||||
PlaceRoadStop(tile, ROADTYPES_ROAD << 2 | RoadStop::TRUCK, CMD_BUILD_ROAD_STOP | CMD_AUTO | CMD_NO_WATER | CMD_MSG(STR_1809_CAN_T_BUILD_TRUCK_STATION));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -297,7 +297,7 @@ static void BuildRoadToolbWndProc(Window *w, WindowEvent *e)
|
|||
|
||||
if (e->we.place.userdata == 0) {
|
||||
ResetObjectToPlace();
|
||||
ShowBuildBridgeWindow(start_tile, end_tile, 0x80);
|
||||
ShowBuildBridgeWindow(start_tile, end_tile, 0x80 | ROADTYPES_ROAD);
|
||||
} else if (e->we.place.userdata != 4) {
|
||||
DoCommandP(end_tile, start_tile, _place_road_flag, CcPlaySound1D,
|
||||
_remove_button_clicked ?
|
||||
|
@ -312,7 +312,7 @@ static void BuildRoadToolbWndProc(Window *w, WindowEvent *e)
|
|||
case WE_PLACE_PRESIZE: {
|
||||
TileIndex tile = e->we.place.tile;
|
||||
|
||||
DoCommand(tile, 0x200, 0, DC_AUTO, CMD_BUILD_TUNNEL);
|
||||
DoCommand(tile, 0x200 | ROADTYPES_ROAD, 0, DC_AUTO, CMD_BUILD_TUNNEL);
|
||||
VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -14,13 +14,15 @@
|
|||
#include "depot.h"
|
||||
|
||||
|
||||
RoadBits GetAnyRoadBits(TileIndex tile)
|
||||
RoadBits GetAnyRoadBits(TileIndex tile, RoadType rt)
|
||||
{
|
||||
if (!HASBIT(GetRoadTypes(tile), rt)) return ROAD_NONE;
|
||||
|
||||
switch (GetTileType(tile)) {
|
||||
case MP_STREET:
|
||||
switch (GetRoadTileType(tile)) {
|
||||
default:
|
||||
case ROAD_TILE_NORMAL: return GetRoadBits(tile);
|
||||
case ROAD_TILE_NORMAL: return GetRoadBits(tile, rt);
|
||||
case ROAD_TILE_CROSSING: return GetCrossingRoadBits(tile);
|
||||
case ROAD_TILE_DEPOT: return DiagDirToRoadBits(GetRoadDepotDirection(tile));
|
||||
}
|
||||
|
@ -44,15 +46,16 @@ RoadBits GetAnyRoadBits(TileIndex tile)
|
|||
}
|
||||
|
||||
|
||||
TrackBits GetAnyRoadTrackBits(TileIndex tile)
|
||||
TrackBits GetAnyRoadTrackBits(TileIndex tile, RoadType rt)
|
||||
{
|
||||
uint32 r;
|
||||
|
||||
/* Don't allow local authorities to build roads through road depots or road stops. */
|
||||
if ((IsTileType(tile, MP_STREET) && IsTileDepotType(tile, TRANSPORT_ROAD)) || (IsTileType(tile, MP_STATION) && !IsDriveThroughStopTile(tile))) {
|
||||
if ((IsTileType(tile, MP_STREET) && IsTileDepotType(tile, TRANSPORT_ROAD)) || (IsTileType(tile, MP_STATION) && !IsDriveThroughStopTile(tile)) || !HASBIT(GetRoadTypes(tile), rt)) {
|
||||
return TRACK_BIT_NONE;
|
||||
}
|
||||
|
||||
r = GetTileTrackStatus(tile, TRANSPORT_ROAD);
|
||||
|
||||
return (TrackBits)(byte)(r | (r >> 8));
|
||||
}
|
||||
|
|
147
src/road_map.h
147
src/road_map.h
|
@ -18,9 +18,9 @@ enum RoadTileType {
|
|||
};
|
||||
|
||||
static inline RoadTileType GetRoadTileType(TileIndex t)
|
||||
{
|
||||
{
|
||||
assert(IsTileType(t, MP_STREET));
|
||||
return (RoadTileType)GB(_m[t].m5, 4, 4);
|
||||
return (RoadTileType)GB(_m[t].m5, 6, 2);
|
||||
}
|
||||
|
||||
static inline bool IsLevelCrossing(TileIndex t)
|
||||
|
@ -33,23 +33,104 @@ static inline bool IsLevelCrossingTile(TileIndex t)
|
|||
return IsTileType(t, MP_STREET) && IsLevelCrossing(t);
|
||||
}
|
||||
|
||||
static inline RoadBits GetRoadBits(TileIndex t)
|
||||
static inline RoadBits GetRoadBits(TileIndex t, RoadType rt)
|
||||
{
|
||||
assert(GetRoadTileType(t) == ROAD_TILE_NORMAL);
|
||||
return (RoadBits)GB(_m[t].m5, 0, 4);
|
||||
switch (rt) {
|
||||
default: NOT_REACHED();
|
||||
case ROADTYPE_ROAD: return (RoadBits)GB(_m[t].m4, 0, 4);
|
||||
case ROADTYPE_TRAM: return (RoadBits)GB(_m[t].m4, 4, 4);
|
||||
case ROADTYPE_HWAY: return (RoadBits)GB(_m[t].m6, 2, 4);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SetRoadBits(TileIndex t, RoadBits r)
|
||||
static inline RoadBits GetAllRoadBits(TileIndex tile)
|
||||
{
|
||||
return GetRoadBits(tile, ROADTYPE_ROAD) | GetRoadBits(tile, ROADTYPE_TRAM) | GetRoadBits(tile, ROADTYPE_HWAY);
|
||||
}
|
||||
|
||||
static inline void SetRoadBits(TileIndex t, RoadBits r, RoadType rt)
|
||||
{
|
||||
assert(GetRoadTileType(t) == ROAD_TILE_NORMAL); // XXX incomplete
|
||||
SB(_m[t].m5, 0, 4, r);
|
||||
switch (rt) {
|
||||
default: NOT_REACHED();
|
||||
case ROADTYPE_ROAD: SB(_m[t].m4, 0, 4, r); break;
|
||||
case ROADTYPE_TRAM: SB(_m[t].m4, 4, 4, r); break;
|
||||
case ROADTYPE_HWAY: SB(_m[t].m6, 2, 4, r); break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline RoadTypes GetRoadTypes(TileIndex t)
|
||||
{
|
||||
if (IsTileType(t, MP_STREET)) {
|
||||
return (RoadTypes)GB(_me[t].m7, 5, 3);
|
||||
} else {
|
||||
return (RoadTypes)GB(_m[t].m3, 0, 3);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SetRoadTypes(TileIndex t, RoadTypes rt)
|
||||
{
|
||||
if (IsTileType(t, MP_STREET)) {
|
||||
SB(_me[t].m7, 5, 3, rt);
|
||||
} else {
|
||||
assert(IsTileType(t, MP_STATION) || IsTileType(t, MP_TUNNELBRIDGE));
|
||||
SB(_m[t].m3, 0, 2, rt);
|
||||
}
|
||||
}
|
||||
|
||||
static inline Owner GetRoadOwner(TileIndex t, RoadType rt)
|
||||
{
|
||||
if (!IsTileType(t, MP_STREET)) return GetTileOwner(t);
|
||||
|
||||
switch (GetRoadTileType(t)) {
|
||||
default: NOT_REACHED();
|
||||
case ROAD_TILE_NORMAL:
|
||||
switch (rt) {
|
||||
default: NOT_REACHED();
|
||||
case ROADTYPE_ROAD: return (Owner)GB( _m[t].m1, 0, 5);
|
||||
case ROADTYPE_TRAM: return (Owner)GB( _m[t].m5, 0, 5);
|
||||
case ROADTYPE_HWAY: return (Owner)GB(_me[t].m7, 0, 5);
|
||||
}
|
||||
case ROAD_TILE_CROSSING:
|
||||
switch (rt) {
|
||||
default: NOT_REACHED();
|
||||
case ROADTYPE_ROAD: return (Owner)GB( _m[t].m4, 0, 5);
|
||||
case ROADTYPE_TRAM: return (Owner)GB( _m[t].m5, 0, 5);
|
||||
case ROADTYPE_HWAY: return (Owner)GB(_me[t].m7, 0, 5);
|
||||
}
|
||||
case ROAD_TILE_DEPOT: return GetTileOwner(t);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void SetRoadOwner(TileIndex t, RoadType rt, Owner o)
|
||||
{
|
||||
if (!IsTileType(t, MP_STREET)) return SetTileOwner(t, o);
|
||||
|
||||
switch (GetRoadTileType(t)) {
|
||||
default: NOT_REACHED();
|
||||
case ROAD_TILE_NORMAL:
|
||||
switch (rt) {
|
||||
default: NOT_REACHED();
|
||||
case ROADTYPE_ROAD: SB( _m[t].m1, 0, 5, o); break;
|
||||
case ROADTYPE_TRAM: SB( _m[t].m5, 0, 5, o); break;
|
||||
case ROADTYPE_HWAY: SB(_me[t].m7, 0, 5, o); break;
|
||||
}
|
||||
case ROAD_TILE_CROSSING:
|
||||
switch (rt) {
|
||||
default: NOT_REACHED();
|
||||
case ROADTYPE_ROAD: SB( _m[t].m4, 0, 5, o); break;
|
||||
case ROADTYPE_TRAM: SB( _m[t].m5, 0, 5, o); break;
|
||||
case ROADTYPE_HWAY: SB(_me[t].m7, 0, 5, o); break;
|
||||
}
|
||||
case ROAD_TILE_DEPOT: return SetTileOwner(t, o);
|
||||
}
|
||||
}
|
||||
|
||||
static inline Axis GetCrossingRoadAxis(TileIndex t)
|
||||
{
|
||||
assert(GetRoadTileType(t) == ROAD_TILE_CROSSING);
|
||||
return (Axis)GB(_m[t].m5, 3, 1);
|
||||
return (Axis)GB(_m[t].m4, 6, 1);
|
||||
}
|
||||
|
||||
static inline RoadBits GetCrossingRoadBits(TileIndex tile)
|
||||
|
@ -63,35 +144,22 @@ static inline TrackBits GetCrossingRailBits(TileIndex tile)
|
|||
}
|
||||
|
||||
|
||||
// TODO swap owner of road and rail
|
||||
static inline Owner GetCrossingRoadOwner(TileIndex t)
|
||||
{
|
||||
assert(GetRoadTileType(t) == ROAD_TILE_CROSSING);
|
||||
return (Owner)_m[t].m4;
|
||||
}
|
||||
|
||||
static inline void SetCrossingRoadOwner(TileIndex t, Owner o)
|
||||
{
|
||||
assert(GetRoadTileType(t) == ROAD_TILE_CROSSING);
|
||||
_m[t].m4 = o;
|
||||
}
|
||||
|
||||
static inline void UnbarCrossing(TileIndex t)
|
||||
{
|
||||
assert(GetRoadTileType(t) == ROAD_TILE_CROSSING);
|
||||
CLRBIT(_m[t].m5, 2);
|
||||
CLRBIT(_m[t].m4, 5);
|
||||
}
|
||||
|
||||
static inline void BarCrossing(TileIndex t)
|
||||
{
|
||||
assert(GetRoadTileType(t) == ROAD_TILE_CROSSING);
|
||||
SETBIT(_m[t].m5, 2);
|
||||
SETBIT(_m[t].m4, 5);
|
||||
}
|
||||
|
||||
static inline bool IsCrossingBarred(TileIndex t)
|
||||
{
|
||||
assert(GetRoadTileType(t) == ROAD_TILE_CROSSING);
|
||||
return HASBIT(_m[t].m5, 2);
|
||||
return HASBIT(_m[t].m4, 5);
|
||||
}
|
||||
|
||||
#define IsOnDesert IsOnSnow
|
||||
|
@ -174,9 +242,10 @@ static inline DiagDirection GetRoadDepotDirection(TileIndex t)
|
|||
* - bridge ramps: start of the ramp is treated as road piece
|
||||
* - bridge middle parts: bridge itself is ignored
|
||||
* @param tile the tile to get the road bits for
|
||||
* @param rt the road type to get the road bits form
|
||||
* @return the road bits of the given tile
|
||||
*/
|
||||
RoadBits GetAnyRoadBits(TileIndex tile);
|
||||
RoadBits GetAnyRoadBits(TileIndex tile, RoadType rt);
|
||||
|
||||
/**
|
||||
* Get the accessible track bits for the given tile.
|
||||
|
@ -186,39 +255,45 @@ RoadBits GetAnyRoadBits(TileIndex tile);
|
|||
* @param tile the tile to get the track bits for
|
||||
* @return the track bits for the given tile
|
||||
*/
|
||||
TrackBits GetAnyRoadTrackBits(TileIndex tile);
|
||||
TrackBits GetAnyRoadTrackBits(TileIndex tile, RoadType rt);
|
||||
|
||||
|
||||
static inline void MakeRoadNormal(TileIndex t, Owner owner, RoadBits bits, TownID town)
|
||||
static inline void MakeRoadNormal(TileIndex t, RoadBits bits, RoadTypes rot, TownID town, Owner road, Owner tram, Owner hway)
|
||||
{
|
||||
SetTileType(t, MP_STREET);
|
||||
SetTileOwner(t, owner);
|
||||
SetTileOwner(t, road);
|
||||
_m[t].m2 = town;
|
||||
_m[t].m3 = 0 << 7 | 0 << 4 | 0;
|
||||
_m[t].m4 = 0;
|
||||
_m[t].m5 = ROAD_TILE_NORMAL << 4 | bits;
|
||||
_m[t].m3 = 0;
|
||||
_m[t].m4 = (HASBIT(rot, ROADTYPE_ROAD) ? bits : 0) << 4 | HASBIT(rot, ROADTYPE_TRAM) ? bits : 0;
|
||||
_m[t].m5 = ROAD_TILE_NORMAL << 6 | tram;
|
||||
SB(_m[t].m6, 2, 4, HASBIT(rot, ROADTYPE_HWAY) ? bits : 0);
|
||||
_me[t].m7 = rot << 5 | hway;
|
||||
}
|
||||
|
||||
|
||||
static inline void MakeRoadCrossing(TileIndex t, Owner road, Owner rail, Axis roaddir, RailType rt, uint town)
|
||||
static inline void MakeRoadCrossing(TileIndex t, Owner road, Owner tram, Owner hway, Owner rail, Axis roaddir, RailType rat, RoadTypes rot, uint town)
|
||||
{
|
||||
SetTileType(t, MP_STREET);
|
||||
SetTileOwner(t, rail);
|
||||
_m[t].m2 = town;
|
||||
_m[t].m3 = 0 << 7 | 0 << 4 | rt;
|
||||
_m[t].m4 = road;
|
||||
_m[t].m5 = ROAD_TILE_CROSSING << 4 | roaddir << 3 | 0 << 2;
|
||||
_m[t].m3 = rat;
|
||||
_m[t].m4 = roaddir << 6 | road;
|
||||
_m[t].m5 = ROAD_TILE_CROSSING << 6 | tram;
|
||||
SB(_m[t].m6, 2, 4, 0);
|
||||
_me[t].m7 = rot << 5 | hway;
|
||||
}
|
||||
|
||||
|
||||
static inline void MakeRoadDepot(TileIndex t, Owner owner, DiagDirection dir)
|
||||
static inline void MakeRoadDepot(TileIndex t, Owner owner, DiagDirection dir, RoadType rt)
|
||||
{
|
||||
SetTileType(t, MP_STREET);
|
||||
SetTileOwner(t, owner);
|
||||
_m[t].m2 = 0;
|
||||
_m[t].m3 = 0;
|
||||
_m[t].m4 = 0;
|
||||
_m[t].m5 = ROAD_TILE_DEPOT << 4 | dir;
|
||||
_m[t].m5 = ROAD_TILE_DEPOT << 6 | dir;
|
||||
SB(_m[t].m6, 2, 4, 0);
|
||||
_me[t].m7 = RoadTypeToRoadTypes(rt) << 5;
|
||||
}
|
||||
|
||||
#endif /* ROAD_MAP_H */
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include <setjmp.h>
|
||||
#include <list>
|
||||
|
||||
extern const uint16 SAVEGAME_VERSION = 60;
|
||||
extern const uint16 SAVEGAME_VERSION = 61;
|
||||
uint16 _sl_version; ///< the major savegame version identifier
|
||||
byte _sl_minor_version; ///< the minor savegame version, DO NOT USE!
|
||||
|
||||
|
|
|
@ -1214,6 +1214,7 @@ static RoadStop **FindRoadStopSpot(bool truck_station, Station* st)
|
|||
* @param p1 entrance direction (DiagDirection)
|
||||
* @param p2 bit 0: 0 for Bus stops, 1 for truck stops
|
||||
* bit 1: 0 for normal, 1 for drive-through
|
||||
* bit 2..4: the roadtypes
|
||||
*/
|
||||
int32 CmdBuildRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
||||
{
|
||||
|
@ -1222,17 +1223,23 @@ int32 CmdBuildRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
bool build_over_road = is_drive_through && IsTileType(tile, MP_STREET) && GetRoadTileType(tile) == ROAD_TILE_NORMAL;
|
||||
bool town_owned_road = build_over_road && IsTileOwner(tile, OWNER_TOWN);
|
||||
Owner cur_owner = _current_player;
|
||||
RoadTypes rts = (RoadTypes)GB(p2, 2, 3);
|
||||
|
||||
if (rts == ROADTYPES_NONE || HASBIT(rts, ROADTYPE_HWAY)) return CMD_ERROR;
|
||||
|
||||
/* Saveguard the parameters */
|
||||
if (!IsValidDiagDirection((DiagDirection)p1)) return CMD_ERROR;
|
||||
/* If it is a drive-through stop check for valid axis */
|
||||
if (is_drive_through && !IsValidAxis((Axis)p1)) return CMD_ERROR;
|
||||
/* Road bits in the wrong direction */
|
||||
if (build_over_road && (GetRoadBits(tile) & ((Axis)p1 == AXIS_X ? ROAD_Y : ROAD_X)) != 0) return_cmd_error(STR_DRIVE_THROUGH_ERROR_DIRECTION);
|
||||
if (build_over_road && (GetAllRoadBits(tile) & ((Axis)p1 == AXIS_X ? ROAD_Y : ROAD_X)) != 0) return_cmd_error(STR_DRIVE_THROUGH_ERROR_DIRECTION);
|
||||
/* Not allowed to build over this road */
|
||||
if (build_over_road) {
|
||||
if (IsTileOwner(tile, OWNER_TOWN) && !_patches.road_stop_on_town_road) return_cmd_error(STR_DRIVE_THROUGH_ERROR_ON_TOWN_ROAD);
|
||||
if (!IsTileOwner(tile, OWNER_TOWN) && !CheckOwnership(GetTileOwner(tile))) return CMD_ERROR;
|
||||
if (GetRoadTileType(tile) != ROAD_TILE_NORMAL) return CMD_ERROR;
|
||||
if (!IsTileOwner(tile, OWNER_TOWN) && !CheckOwnership(GetRoadOwner(tile, ROADTYPE_ROAD)) && !CheckOwnership(GetRoadOwner(tile, ROADTYPE_TRAM))) return CMD_ERROR;
|
||||
/* Do not remove roadtypes! */
|
||||
if (rts != GetRoadTypes(tile) && rts != ROADTYPES_ROADTRAM) return CMD_ERROR;
|
||||
}
|
||||
|
||||
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
|
||||
|
@ -1311,9 +1318,9 @@ int32 CmdBuildRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
|
||||
RoadStop::Type rs_type = type ? RoadStop::TRUCK : RoadStop::BUS;
|
||||
if (is_drive_through) {
|
||||
MakeDriveThroughRoadStop(tile, st->owner, st->index, rs_type, (Axis)p1, town_owned_road);
|
||||
MakeDriveThroughRoadStop(tile, st->owner, st->index, rs_type, rts, (Axis)p1, town_owned_road);
|
||||
} else {
|
||||
MakeRoadStop(tile, st->owner, st->index, rs_type, (DiagDirection)p1);
|
||||
MakeRoadStop(tile, st->owner, st->index, rs_type, rts, (DiagDirection)p1);
|
||||
}
|
||||
|
||||
UpdateStationVirtCoordDirty(st);
|
||||
|
@ -1389,7 +1396,8 @@ int32 CmdRemoveRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
Station *st = GetStationByTile(tile);
|
||||
/* Save the stop info before it is removed */
|
||||
bool is_drive_through = IsDriveThroughStopTile(tile);
|
||||
RoadBits road_bits = GetAnyRoadBits(tile);
|
||||
RoadTypes rts = GetRoadTypes(tile);
|
||||
RoadBits road_bits = GetAnyRoadBits(tile, HASBIT(rts, ROADTYPE_ROAD) ? ROADTYPE_ROAD : ROADTYPE_TRAM);
|
||||
bool is_towns_road = is_drive_through && GetStopBuiltOnTownRoad(tile);
|
||||
|
||||
int32 ret = RemoveRoadStop(st, flags, tile);
|
||||
|
@ -1403,7 +1411,12 @@ int32 CmdRemoveRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
index = ClosestTownFromTile(tile, (uint)-1)->index;
|
||||
_current_player = OWNER_TOWN;
|
||||
}
|
||||
DoCommand(tile, road_bits, index, DC_EXEC, CMD_BUILD_ROAD);
|
||||
if (HASBIT(rts, ROADTYPE_ROAD)) {
|
||||
DoCommand(tile, ROADTYPE_ROAD << 4 | road_bits, index, DC_EXEC, CMD_BUILD_ROAD);
|
||||
}
|
||||
if (HASBIT(rts, ROADTYPE_TRAM)) {
|
||||
DoCommand(tile, ROADTYPE_TRAM << 4 | road_bits, index, DC_EXEC, CMD_BUILD_ROAD);
|
||||
}
|
||||
_current_player = cur_owner;
|
||||
}
|
||||
|
||||
|
@ -2676,7 +2689,8 @@ static bool CanRemoveRoadWithStop(TileIndex tile)
|
|||
if (!GetStopBuiltOnTownRoad(tile)) return true;
|
||||
|
||||
bool edge_road;
|
||||
return CheckAllowRemoveRoad(tile, GetAnyRoadBits(tile), OWNER_TOWN, &edge_road);
|
||||
return CheckAllowRemoveRoad(tile, GetAnyRoadBits(tile, ROADTYPE_ROAD), OWNER_TOWN, &edge_road, ROADTYPE_ROAD) &&
|
||||
CheckAllowRemoveRoad(tile, GetAnyRoadBits(tile, ROADTYPE_TRAM), OWNER_TOWN, &edge_road, ROADTYPE_TRAM);
|
||||
}
|
||||
|
||||
static int32 ClearTile_Station(TileIndex tile, byte flags)
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#define STATION_MAP_H
|
||||
|
||||
#include "rail_map.h"
|
||||
#include "road_map.h"
|
||||
#include "station.h"
|
||||
|
||||
typedef byte StationGfx;
|
||||
|
@ -309,15 +310,17 @@ static inline void MakeRailStation(TileIndex t, Owner o, StationID sid, Axis a,
|
|||
SetRailType(t, rt);
|
||||
}
|
||||
|
||||
static inline void MakeRoadStop(TileIndex t, Owner o, StationID sid, RoadStop::Type rst, DiagDirection d)
|
||||
static inline void MakeRoadStop(TileIndex t, Owner o, StationID sid, RoadStop::Type rst, RoadTypes rt, DiagDirection d)
|
||||
{
|
||||
MakeStation(t, o, sid, (rst == RoadStop::BUS ? GFX_BUS_BASE : GFX_TRUCK_BASE) + d);
|
||||
SetRoadTypes(t, rt);
|
||||
}
|
||||
|
||||
static inline void MakeDriveThroughRoadStop(TileIndex t, Owner o, StationID sid, RoadStop::Type rst, Axis a, bool on_town_road)
|
||||
static inline void MakeDriveThroughRoadStop(TileIndex t, Owner o, StationID sid, RoadStop::Type rst, RoadTypes rt, Axis a, bool on_town_road)
|
||||
{
|
||||
MakeStation(t, o, sid, (rst == RoadStop::BUS ? GFX_BUS_BASE_EXT : GFX_TRUCK_BASE_EXT) + a);
|
||||
SB(_m[t].m6, 3, 1, on_town_road);
|
||||
SetRoadTypes(t, rt);
|
||||
}
|
||||
|
||||
static inline void MakeAirport(TileIndex t, Owner o, StationID sid, byte section)
|
||||
|
|
|
@ -636,7 +636,7 @@ void OnTick_Town()
|
|||
|
||||
static RoadBits GetTownRoadMask(TileIndex tile)
|
||||
{
|
||||
TrackBits b = GetAnyRoadTrackBits(tile);
|
||||
TrackBits b = GetAnyRoadTrackBits(tile, ROADTYPE_ROAD);
|
||||
RoadBits r = ROAD_NONE;
|
||||
|
||||
if (b & TRACK_BIT_X) r |= ROAD_X;
|
||||
|
@ -676,7 +676,7 @@ static bool IsRoadAllowedHere(TileIndex tile, int dir)
|
|||
|
||||
for (;;) {
|
||||
/* Check if there already is a road at this point? */
|
||||
if (GetAnyRoadTrackBits(tile) == 0) {
|
||||
if (GetAnyRoadTrackBits(tile, ROADTYPE_ROAD) == 0) {
|
||||
/* No, try to build one in the direction.
|
||||
* if that fails clear the land, and if that fails exit.
|
||||
* This is to make sure that we can build a road here later. */
|
||||
|
@ -1221,7 +1221,7 @@ static bool GrowTown(Town *t)
|
|||
/* Find a road that we can base the construction on. */
|
||||
tile = t->xy;
|
||||
for (ptr = _town_coord_mod; ptr != endof(_town_coord_mod); ++ptr) {
|
||||
if (GetAnyRoadTrackBits(tile) != 0) {
|
||||
if (GetAnyRoadTrackBits(tile, ROADTYPE_ROAD) != 0) {
|
||||
int r = GrowTownAtRoad(t, tile);
|
||||
_current_player = old_player;
|
||||
return r != 0;
|
||||
|
@ -2208,7 +2208,7 @@ Town *ClosestTownFromTile(TileIndex tile, uint threshold)
|
|||
{
|
||||
if (IsTileType(tile, MP_HOUSE) || (
|
||||
IsTileType(tile, MP_STREET) &&
|
||||
(IsLevelCrossing(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile)) == OWNER_TOWN
|
||||
GetRoadOwner(tile, ROADTYPE_ROAD) == OWNER_TOWN
|
||||
)) {
|
||||
return GetTownByTile(tile);
|
||||
} else {
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "macros.h"
|
||||
#include "map.h"
|
||||
#include "rail.h"
|
||||
#include "road.h"
|
||||
|
||||
/**
|
||||
* Is this a tunnel (entrance)?
|
||||
|
@ -93,13 +94,14 @@ bool IsTunnelInWay(TileIndex, uint z);
|
|||
* @param t the entrance of the tunnel
|
||||
* @param o the owner of the entrance
|
||||
* @param d the direction facing out of the tunnel
|
||||
* @param r the road type used in the tunnel
|
||||
*/
|
||||
static inline void MakeRoadTunnel(TileIndex t, Owner o, DiagDirection d)
|
||||
static inline void MakeRoadTunnel(TileIndex t, Owner o, DiagDirection d, RoadTypes r)
|
||||
{
|
||||
SetTileType(t, MP_TUNNELBRIDGE);
|
||||
SetTileOwner(t, o);
|
||||
_m[t].m2 = 0;
|
||||
_m[t].m3 = 0;
|
||||
_m[t].m3 = r;
|
||||
_m[t].m4 = 0;
|
||||
_m[t].m5 = TRANSPORT_ROAD << 2 | d;
|
||||
}
|
||||
|
|
|
@ -172,12 +172,14 @@ bool CheckBridge_Stuff(byte bridge_type, uint bridge_len)
|
|||
* @param p1 packed start tile coords (~ dx)
|
||||
* @param p2 various bitstuffed elements
|
||||
* - p2 = (bit 0- 7) - bridge type (hi bh)
|
||||
* - p2 = (bit 8-..) - rail type. bit15 ((x>>8)&0x80) means road bridge.
|
||||
* - p2 = (bit 8-..) - rail type or road types.
|
||||
* - p2 = (bit 15 ) - set means road bridge.
|
||||
*/
|
||||
int32 CmdBuildBridge(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
|
||||
{
|
||||
uint bridge_type;
|
||||
RailType railtype;
|
||||
RoadTypes roadtypes;
|
||||
uint x;
|
||||
uint y;
|
||||
uint sx;
|
||||
|
@ -207,6 +209,8 @@ int32 CmdBuildBridge(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
/* type of bridge */
|
||||
if (HASBIT(p2, 15)) {
|
||||
railtype = INVALID_RAILTYPE; // road bridge
|
||||
roadtypes = (RoadTypes)GB(p2, 8, 2);
|
||||
if (roadtypes > ROADTYPES_ALL || roadtypes == ROADTYPES_NONE) return CMD_ERROR;
|
||||
} else {
|
||||
if (!ValParamRailtype(GB(p2, 8, 8))) return CMD_ERROR;
|
||||
railtype = (RailType)GB(p2, 8, 8);
|
||||
|
@ -352,8 +356,8 @@ int32 CmdBuildBridge(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
MakeRailBridgeRamp(tile_start, owner, bridge_type, dir, railtype);
|
||||
MakeRailBridgeRamp(tile_end, owner, bridge_type, ReverseDiagDir(dir), railtype);
|
||||
} else {
|
||||
MakeRoadBridgeRamp(tile_start, owner, bridge_type, dir);
|
||||
MakeRoadBridgeRamp(tile_end, owner, bridge_type, ReverseDiagDir(dir));
|
||||
MakeRoadBridgeRamp(tile_start, owner, bridge_type, dir, roadtypes);
|
||||
MakeRoadBridgeRamp(tile_end, owner, bridge_type, ReverseDiagDir(dir), roadtypes);
|
||||
}
|
||||
MarkTileDirtyByTile(tile_start);
|
||||
MarkTileDirtyByTile(tile_end);
|
||||
|
@ -442,7 +446,7 @@ not_valid_below:;
|
|||
/** Build Tunnel.
|
||||
* @param start_tile start tile of tunnel
|
||||
* @param flags type of operation
|
||||
* @param p1 railtype, 0x200 for road tunnel
|
||||
* @param p1 railtype or roadtypes. bit 9 set means road tunnel
|
||||
* @param p2 unused
|
||||
*/
|
||||
int32 CmdBuildTunnel(TileIndex start_tile, uint32 flags, uint32 p1, uint32 p2)
|
||||
|
@ -459,7 +463,11 @@ int32 CmdBuildTunnel(TileIndex start_tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
|
||||
_build_tunnel_endtile = 0;
|
||||
|
||||
if (p1 != 0x200 && !ValParamRailtype(p1)) return CMD_ERROR;
|
||||
if (HASBIT(p1, 9)) {
|
||||
if (!ValParamRailtype(p1)) return CMD_ERROR;
|
||||
} else if (GB(p1, 0, 4) > ROADTYPES_ALL || GB(p1, 0, 4) == ROADTYPES_NONE) {
|
||||
return CMD_ERROR;
|
||||
}
|
||||
|
||||
start_tileh = GetTileSlope(start_tile, &start_z);
|
||||
|
||||
|
@ -519,8 +527,8 @@ int32 CmdBuildTunnel(TileIndex start_tile, uint32 flags, uint32 p1, uint32 p2)
|
|||
UpdateSignalsOnSegment(start_tile, direction);
|
||||
YapfNotifyTrackLayoutChange(start_tile, AxisToTrack(DiagDirToAxis(direction)));
|
||||
} else {
|
||||
MakeRoadTunnel(start_tile, _current_player, direction);
|
||||
MakeRoadTunnel(end_tile, _current_player, ReverseDiagDir(direction));
|
||||
MakeRoadTunnel(start_tile, _current_player, direction, (RoadTypes)GB(p1, 0, 4));
|
||||
MakeRoadTunnel(end_tile, _current_player, ReverseDiagDir(direction), (RoadTypes)GB(p1, 0, 4));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue