@@ -149,18 +149,18 @@ RoadTypeIdentifier AllocateRoadType(RoadTypeLabel label, RoadType basetype)
rti->alternate_labels.Clear();

/* Make us compatible with ourself. */
rti->powered_roadtypes = (RoadSubTypes)(1 << rt);
rti->powered_roadtypes = (RoadSubTypes)(1LL << rt);

/* We also introduce ourself. */
rti->introduces_roadtypes = (RoadSubTypes)(1 << rt);
rti->introduces_roadtypes = (RoadSubTypes)(1LL << rt);

/* Default sort order; order of allocation, but with some
* offsets so it's easier for NewGRF to pick a spot without
* changing the order of other (original) road types.
* The << is so you can place other roadtypes in between the
* other roadtypes, the 7 is to be able to place something
* before the first (default) road type. */
rti->sorting_order = rt << 4 | 7;
rti->sorting_order = rt << 2 | 7;

rtid.basetype = basetype;
rtid.subtype = rt;
@@ -610,8 +610,8 @@ static CommandCost CheckRoadSlope(Slope tileh, RoadBits *pieces, RoadBits existi
* @param tile tile where to build road
* @param flags operation to perform
* @param p1 bit 0..3 road pieces to build (RoadBits)
* bit 4..8 road type
* bit 9..10 disallowed directions to toggle
* bit 4..10 road type
* bit 11..12 disallowed directions to toggle
* @param p2 the town that is building the road (0 if not applicable)
* @param text unused
* @return the cost of this operation or an error
@@ -647,10 +647,10 @@ CommandCost CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
if (pieces == ROAD_NONE) return CMD_ERROR;

RoadTypeIdentifier rtid;
if (!rtid.UnpackIfValid(GB(p1, 4, 5))) return CMD_ERROR;
if (!rtid.UnpackIfValid(GB(p1, 4, 7))) return CMD_ERROR;
if (!ValParamRoadType(rtid)) return CMD_ERROR;

DisallowedRoadDirections toggle_drd = Extract<DisallowedRoadDirections, 9, 2>(p1);
DisallowedRoadDirections toggle_drd = Extract<DisallowedRoadDirections, 11, 2>(p1);

Slope tileh = GetTileSlope(tile);

@@ -990,9 +990,9 @@ static bool CanConnectToRoad(TileIndex tile, RoadType rt, DiagDirection dir)
* - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1). Only used if bit 6 is set or if we are building a single tile
* - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2). Only used if bit 6 is set or if we are building a single tile
* - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4)
* - p2 = (bit 3..7) - road type identifier
* - p2 = (bit 8) - set road direction
* - p2 = (bit 9) - defines two different behaviors for this command:
* - p2 = (bit 3..9) - road type identifier
* - p2 = (bit 10) - set road direction
* - p2 = (bit 11) - defines two different behaviors for this command:
* - 0 = Build up to an obstacle. Do not build the first and last roadbits unless they can be connected to something, or if we are building a single tile
* - 1 = Fail if an obstacle is found. Always take into account bit 0 and 1. This behavior is used for scripts
* @param text unused
@@ -1006,7 +1006,7 @@ CommandCost CmdBuildLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32 p

TileIndex end_tile = p1;
RoadTypeIdentifier rtid;
if (!rtid.UnpackIfValid(GB(p2, 3, 5))) return CMD_ERROR;
if (!rtid.UnpackIfValid(GB(p2, 3, 7))) return CMD_ERROR;
if (!ValParamRoadType(rtid)) return CMD_ERROR;

Axis axis = Extract<Axis, 2, 1>(p2);
@@ -1028,15 +1028,15 @@ CommandCost CmdBuildLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32 p
* when you just 'click' on one tile to build them. */
if ((axis == AXIS_Y) == (start_tile == end_tile && HasBit(p2, 0) == HasBit(p2, 1))) drd ^= DRD_BOTH;
/* No disallowed direction bits have to be toggled */
if (!HasBit(p2, 8)) drd = DRD_NONE;
if (!HasBit(p2, 10)) drd = DRD_NONE;

CommandCost cost(EXPENSES_CONSTRUCTION);
CommandCost last_error = CMD_ERROR;
TileIndex tile = start_tile;
bool had_bridge = false;
bool had_tunnel = false;
bool had_success = false;
bool is_ai = HasBit(p2, 9);
bool is_ai = HasBit(p2, 11);

/* Start tile is the first tile clicked by the user. */
for (;;) {
@@ -1056,7 +1056,7 @@ CommandCost CmdBuildLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32 p
if (tile == start_tile && HasBit(p2, 0)) bits &= DiagDirToRoadBits(dir);
}

CommandCost ret = DoCommand(tile, drd << 9 | rtid.Pack() << 4 | bits, 0, flags, CMD_BUILD_ROAD);
CommandCost ret = DoCommand(tile, drd << 11 | rtid.Pack() << 4 | bits, 0, flags, CMD_BUILD_ROAD);
if (ret.Failed()) {
last_error = ret;
if (last_error.GetErrorMessage() != STR_ERROR_ALREADY_BUILT) {
@@ -1101,7 +1101,7 @@ CommandCost CmdBuildLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32 p
* - 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 - 7) - road type
* - p2 = (bit 3 - 9) - road type
* @param text unused
* @return the cost of this operation or an error
*/
@@ -1113,7 +1113,7 @@ CommandCost CmdRemoveLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32

TileIndex end_tile = p1;
RoadTypeIdentifier rtid;
if (!rtid.UnpackIfValid(GB(p2, 3, 5))) return CMD_ERROR;
if (!rtid.UnpackIfValid(GB(p2, 3, 7))) return CMD_ERROR;

Axis axis = Extract<Axis, 2, 1>(p2);
/* Only drag in X or Y direction dictated by the direction variable */
@@ -1172,7 +1172,7 @@ CommandCost CmdRemoveLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32
* @param tile tile where to build the depot
* @param flags operation to perform
* @param p1 bit 0..1 entrance direction (DiagDirection)
* bit 2..7 road type identifier
* bit 2..8 road type identifier
* @param p2 unused
* @param text unused
* @return the cost of this operation or an error
@@ -1185,7 +1185,7 @@ CommandCost CmdBuildRoadDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, ui
DiagDirection dir = Extract<DiagDirection, 0, 2>(p1);

RoadTypeIdentifier rtid;
if (!rtid.UnpackIfValid(GB(p1, 2, 5))) return CMD_ERROR;
if (!rtid.UnpackIfValid(GB(p1, 2, 7))) return CMD_ERROR;
if (!ValParamRoadType(rtid)) return CMD_ERROR;

Slope tileh = GetTileSlope(tile);
@@ -2318,14 +2318,14 @@ static void ConvertRoadTypeOwner(TileIndex tile, uint num_pieces, Owner owner, R
* @param flags operation to perform
* @param p1 start tile of drag
* @param p2 various bitstuffed elements:
* - p2 = (bit 0..4) new roadtype to convert to.
* - p2 = (bit 0..6) new roadtype to convert to.
* @param text unused
* @return the cost of this operation or an error
*/
CommandCost CmdConvertRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
RoadTypeIdentifier to_type;
if (!to_type.UnpackIfValid(GB(p2, 0, 5))) return CMD_ERROR;
if (!to_type.UnpackIfValid(GB(p2, 0, 7))) return CMD_ERROR;

TileIndex area_start = p1;
TileIndex area_end = tile;
@@ -179,13 +179,13 @@ static inline void SetRoadBits(TileIndex t, RoadBits r, RoadType rt)
static inline RoadSubType GetRoadSubTypeRoad(TileIndex t)
{
assert(MayHaveRoad(t));
return (RoadSubType)GB(_m[t].m4, 0, 4);
return (RoadSubType)_m[t].m4;
}

static inline RoadSubType GetRoadSubTypeTram(TileIndex t)
{
assert(MayHaveRoad(t));
return (RoadSubType)GB(_m[t].m4, 4, 4);
return (RoadSubType)_me[t].m9;
}

static inline RoadSubType GetRoadSubType(TileIndex t, RoadType rt)
@@ -770,8 +770,8 @@ struct RoadTypeIdentifiers {
static inline void SetRoadTypes(TileIndex t, RoadTypeIdentifiers rtids)
{
assert(MayHaveRoad(t));
SB(_m[t].m4, 0, 4, rtids.road_identifier.subtype);
SB(_m[t].m4, 4, 4, rtids.tram_identifier.subtype);
_m[t].m4 = rtids.road_identifier.subtype;
_me[t].m9 = rtids.tram_identifier.subtype;
}

/**
@@ -817,6 +817,7 @@ static inline void MakeRoadCrossing(TileIndex t, Owner road, Owner tram, Owner r
_m[t].m5 = ROAD_TILE_CROSSING << 6 | roaddir;
SB(_me[t].m6, 2, 4, 0);
_me[t].m7 = road;
_me[t].m9 = INVALID_ROADTYPES;
SetRoadTypes(t, rtids);
SetRoadOwner(t, ROADTYPE_TRAM, tram);
}
@@ -839,6 +840,7 @@ static inline void MakeRoadDepot(TileIndex t, Owner owner, DepotID did, DiagDire
_m[t].m5 = ROAD_TILE_DEPOT << 6 | dir;
SB(_me[t].m6, 2, 4, 0);
_me[t].m7 = owner;
_me[t].m9 = INVALID_ROADTYPES;
SetRoadTypes(t, RoadTypeIdentifiers::FromRoadTypeIdentifier(rtid));
SetRoadOwner(t, ROADTYPE_TRAM, owner);
}
@@ -37,8 +37,8 @@ enum RoadSubType {
ROADSUBTYPE_BEGIN = 0, ///< Used for iterations
ROADSUBTYPE_NORMAL = 0, ///< Plain road/tram
ROADSUBTYPE_ELECTRIC = 1, ///< Electrified road/tram
ROADSUBTYPE_END = 15, ///< Used for iterations
INVALID_ROADSUBTYPE = 0xF, ///< flag for invalid roadsubtype
ROADSUBTYPE_END = 63, ///< Used for iterations
INVALID_ROADSUBTYPE = 63, ///< flag for invalid roadsubtype
};
DECLARE_POSTFIX_INCREMENT(RoadSubType);

@@ -62,8 +62,8 @@ typedef SimpleTinyEnumT<RoadTypes, byte> RoadTypesByte;
*/
enum RoadSubTypes {
ROADSUBTYPES_NONE = 0, ///< No roadsubtypes
ROADSUBTYPES_NORMAL = 1 << ROADSUBTYPE_NORMAL, ///< Plain road/tram
ROADSUBTYPES_ELECTRIC = 1 << ROADSUBTYPE_ELECTRIC, ///< Electrified road/tram
ROADSUBTYPES_NORMAL = 1LL << ROADSUBTYPE_NORMAL, ///< Plain road/tram
ROADSUBTYPES_ELECTRIC = 1LL << ROADSUBTYPE_ELECTRIC, ///< Electrified road/tram
};
DECLARE_ENUM_AS_BIT_SET(RoadSubTypes)

@@ -1258,6 +1258,36 @@ bool AfterLoadGame()
SB(_me[t].m7, 6, 2, 0);
}
}

/* Railtype moved from m3 to m8 in version 199. */
for (TileIndex t = 0; t < map_size; t++) {
switch (GetTileType(t)) {
case MP_RAILWAY:
SetRailType(t, (RailType)GB(_m[t].m3, 0, 4));
break;

case MP_ROAD:
if (IsLevelCrossing(t)) {
SetRailType(t, (RailType)GB(_m[t].m3, 0, 4));
}
break;

case MP_STATION:
if (HasStationRail(t)) {
SetRailType(t, (RailType)GB(_m[t].m3, 0, 4));
}
break;

case MP_TUNNELBRIDGE:
if (GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL) {
SetRailType(t, (RailType)GB(_m[t].m3, 0, 4));
}
break;

default:
break;
}
}
}

/* Elrails got added in rev 24 */
@@ -272,6 +272,53 @@ static void Save_MAP7()
}
}

static void Load_MAP8()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();

for (TileIndex i = 0; i != size;) {
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m8 = buf[j];
}
}

static void Save_MAP8()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();

SlSetLength(size);
for (TileIndex i = 0; i != size;) {
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m8;
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
}
}

static void Load_MAP9()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();

for (TileIndex i = 0; i != size;) {
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m9 = buf[j];
}
}

static void Save_MAP9()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();

SlSetLength(size);
for (TileIndex i = 0; i != size;) {
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m9;
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
}
}


extern const ChunkHandler _map_chunk_handlers[] = {
{ 'MAPS', Save_MAPS, Load_MAPS, NULL, Check_MAPS, CH_RIFF },
{ 'MAPT', Save_MAPT, Load_MAPT, NULL, NULL, CH_RIFF },
@@ -282,5 +329,7 @@ extern const ChunkHandler _map_chunk_handlers[] = {
{ 'M3HI', Save_MAP4, Load_MAP4, NULL, NULL, CH_RIFF },
{ 'MAP5', Save_MAP5, Load_MAP5, NULL, NULL, CH_RIFF },
{ 'MAPE', Save_MAP6, Load_MAP6, NULL, NULL, CH_RIFF },
{ 'MAP7', Save_MAP7, Load_MAP7, NULL, NULL, CH_RIFF | CH_LAST },
{ 'MAP7', Save_MAP7, Load_MAP7, NULL, NULL, CH_RIFF },
{ 'MAP8', Save_MAP8, Load_MAP8, NULL, NULL, CH_RIFF },
{ 'MAP9', Save_MAP9, Load_MAP9, NULL, NULL, CH_RIFF | CH_LAST },
};
@@ -1196,11 +1196,11 @@ static void RestoreTrainReservation(Train *v)
* @param tile_org northern most position of station dragging/placement
* @param flags operation to perform
* @param p1 various bitstuffed elements
* - p1 = (bit 0- 3) - railtype
* - p1 = (bit 4) - orientation (Axis)
* - p1 = (bit 0- 5) - railtype
* - p1 = (bit 8-15) - number of tracks
* - p1 = (bit 16-23) - platform length
* - p1 = (bit 24) - allow stations directly adjacent to other stations.
* - p1 = (bit 25) - orientation (Axis)
* @param p2 various bitstuffed elements
* - p2 = (bit 0- 7) - custom station class
* - p2 = (bit 8-15) - custom station id
@@ -1211,8 +1211,8 @@ static void RestoreTrainReservation(Train *v)
CommandCost CmdBuildRailStation(TileIndex tile_org, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
/* Unpack parameters */
RailType rt = Extract<RailType, 0, 4>(p1);
Axis axis = Extract<Axis, 4, 1>(p1);
RailType rt = Extract<RailType, 0, 6>(p1);
Axis axis = Extract<Axis, 25, 1>(p1);
byte numtracks = GB(p1, 8, 8);
byte plat_len = GB(p1, 16, 8);
bool adjacent = HasBit(p1, 24);
@@ -58,6 +58,7 @@ static inline void MakeRoadTunnel(TileIndex t, Owner o, DiagDirection d, RoadTyp
_m[t].m5 = TRANSPORT_ROAD << 2 | d;
SB(_me[t].m6, 2, 4, 0);
_me[t].m7 = 0;
_me[t].m8 = 0;
SetRoadOwner(t, ROADTYPE_ROAD, o);
if (o != OWNER_TOWN) SetRoadOwner(t, ROADTYPE_TRAM, o);
SetRoadTypes(t, r);
@@ -75,11 +76,12 @@ static inline void MakeRailTunnel(TileIndex t, Owner o, DiagDirection d, RailTyp
SetTileType(t, MP_TUNNELBRIDGE);
SetTileOwner(t, o);
_m[t].m2 = 0;
_m[t].m3 = r;
_m[t].m3 = 0;
_m[t].m4 = 0;
_m[t].m5 = TRANSPORT_RAIL << 2 | d;
SB(_me[t].m6, 2, 4, 0);
_me[t].m7 = 0;
_me[t].m8 = r;
}

#endif /* TUNNEL_MAP_H */
@@ -233,7 +233,7 @@ CommandCost CheckBridgeAvailability(BridgeType bridge_type, uint bridge_len, DoC
* @param p1 packed start tile coords (~ dx)
* @param p2 various bitstuffed elements
* - p2 = (bit 0- 7) - bridge type (hi bh)
* - p2 = (bit 8-12) - rail type or road types.
* - p2 = (bit 8-14) - rail type or road types.
* - p2 = (bit 15-16) - transport type.
* @param text unused
* @return the cost of this operation or an error
@@ -255,12 +255,12 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u
/* type of bridge */
switch (transport_type) {
case TRANSPORT_ROAD:
if (!rtid.UnpackIfValid(GB(p2, 8, 5))) return CMD_ERROR;
if (!rtid.UnpackIfValid(GB(p2, 8, 7))) return CMD_ERROR;
if (!ValParamRoadType(rtid)) return CMD_ERROR;
break;

case TRANSPORT_RAIL:
railtype = Extract<RailType, 8, 4>(p2);
railtype = Extract<RailType, 8, 6>(p2);
if (!ValParamRailtype(railtype)) return CMD_ERROR;
break;

@@ -591,7 +591,7 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u
* Build Tunnel.
* @param start_tile start tile of tunnel
* @param flags type of operation
* @param p1 bit 0-4 railtype or roadtypes
* @param p1 bit 0-6 railtype or roadtypes
* bit 8-9 transport type
* @param p2 unused
* @param text unused
@@ -607,12 +607,12 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1,
_build_tunnel_endtile = 0;
switch (transport_type) {
case TRANSPORT_RAIL:
railtype = Extract<RailType, 0, 4>(p1);
railtype = Extract<RailType, 0, 6>(p1);
if (!ValParamRailtype(railtype)) return CMD_ERROR;
break;

case TRANSPORT_ROAD:
if (!rtid.UnpackIfValid(GB(p1, 0, 5))) return CMD_ERROR;
if (!rtid.UnpackIfValid(GB(p1, 0, 7))) return CMD_ERROR;
if (!ValParamRoadType(rtid)) return CMD_ERROR;
break;