diff options
author | rubidium <rubidium@openttd.org> | 2009-03-02 22:57:47 +0000 |
---|---|---|
committer | rubidium <rubidium@openttd.org> | 2009-03-02 22:57:47 +0000 |
commit | 7831346ef8924c757fbd763c225c7b29b665604f (patch) | |
tree | 7514d56ab72b15863906486d7256f8e5dd2cef01 /src | |
parent | 6dd3703a4caafff9a56d878ffac6ce322739067d (diff) | |
download | openttd-7831346ef8924c757fbd763c225c7b29b665604f.tar.xz |
(svn r15601) -Fix [FS#2615]: bridges/tunnels don't store tram owner making it possible to remove someone's tram tracks.
-Feature: allow building road stops on road/tram tracks of competitors.
Diffstat (limited to 'src')
-rw-r--r-- | src/bridge_map.h | 10 | ||||
-rw-r--r-- | src/lang/english.txt | 1 | ||||
-rw-r--r-- | src/rail_cmd.cpp | 15 | ||||
-rw-r--r-- | src/road_cmd.cpp | 24 | ||||
-rw-r--r-- | src/road_map.h | 138 | ||||
-rw-r--r-- | src/road_type.h | 17 | ||||
-rw-r--r-- | src/saveload/afterload.cpp | 77 | ||||
-rw-r--r-- | src/saveload/saveload.cpp | 2 | ||||
-rw-r--r-- | src/settings.cpp | 1 | ||||
-rw-r--r-- | src/settings_gui.cpp | 1 | ||||
-rw-r--r-- | src/settings_type.h | 1 | ||||
-rw-r--r-- | src/station_cmd.cpp | 71 | ||||
-rw-r--r-- | src/station_map.h | 22 | ||||
-rw-r--r-- | src/toolbar_gui.cpp | 3 | ||||
-rw-r--r-- | src/tunnel_map.h | 7 | ||||
-rw-r--r-- | src/tunnelbridge_cmd.cpp | 56 | ||||
-rw-r--r-- | src/tunnelbridge_map.h | 4 |
17 files changed, 265 insertions, 185 deletions
diff --git a/src/bridge_map.h b/src/bridge_map.h index 309fc0dd4..7a6035ca6 100644 --- a/src/bridge_map.h +++ b/src/bridge_map.h @@ -71,7 +71,7 @@ static inline bool IsBridgeAbove(TileIndex t) static inline BridgeType GetBridgeType(TileIndex t) { assert(IsBridgeTile(t)); - return GB(_m[t].m2, 4, 4); + return GB(_m[t].m6, 2, 4); } /** @@ -168,10 +168,11 @@ static inline void MakeBridgeRamp(TileIndex t, Owner o, BridgeType bridgetype, D { SetTileType(t, MP_TUNNELBRIDGE); SetTileOwner(t, o); - _m[t].m2 = bridgetype << 4; + _m[t].m2 = 0; _m[t].m3 = rt; _m[t].m4 = 0; _m[t].m5 = 1 << 7 | tt << 2 | d; + SB(_m[t].m6, 2, 4, bridgetype); } /** @@ -184,7 +185,10 @@ static inline void MakeBridgeRamp(TileIndex t, Owner o, BridgeType bridgetype, D */ static inline void MakeRoadBridgeRamp(TileIndex t, Owner o, BridgeType bridgetype, DiagDirection d, RoadTypes r) { - MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_ROAD, r); + MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_ROAD, 0); + SetRoadOwner(t, ROADTYPE_ROAD, o); + if (o != OWNER_TOWN) SetRoadOwner(t, ROADTYPE_TRAM, o); + SetRoadTypes(t, r); } /** diff --git a/src/lang/english.txt b/src/lang/english.txt index 810aa6d99..fb7384c02 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -945,6 +945,7 @@ STR_CONFIG_SETTING_NONUNIFORM_STATIONS :{LTBLUE}Nonunif STR_CONFIG_SETTING_FREIGHT_TRAINS :{LTBLUE}Weight multiplier for freight to simulate heavy trains: {ORANGE}{STRING} STR_CONFIG_SETTING_PLANE_SPEED :{LTBLUE}Plane speed factor: {ORANGE}1 / {STRING1} STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :{LTBLUE}Allow drive-through road stops on town owned roads: {ORANGE}{STRING} +STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD :{LTBLUE}Allow drive-through road stops on roads owned by competitors: {ORANGE}{STRING} STR_CONFIG_SETTING_ADJACENT_STATIONS :{LTBLUE}Allow building adjacent stations: {ORANGE}{STRING} STR_CONFIG_SETTING_DYNAMIC_ENGINES :{LTBLUE}Enable multiple NewGRF engine sets: {ORANGE}{STRING} STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}Changing this setting is not possible when there are vehicles. diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 13955b8b6..1e5573881 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -378,20 +378,17 @@ CommandCost CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, u roadtypes |= ROADTYPES_ROAD; 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; + case ROADTYPES_ALL: + if (road != tram) return CMD_ERROR; + break; } - road |= tram | GetRoadBits(tile, ROADTYPE_HWAY); + road |= tram; if ((track == TRACK_X && road == ROAD_Y) || (track == TRACK_Y && road == ROAD_X)) { if (flags & DC_EXEC) { - MakeRoadCrossing(tile, GetRoadOwner(tile, ROADTYPE_ROAD), GetRoadOwner(tile, ROADTYPE_TRAM), GetRoadOwner(tile, ROADTYPE_HWAY), _current_company, (track == TRACK_X ? AXIS_Y : AXIS_X), railtype, roadtypes, GetTownIndex(tile)); + MakeRoadCrossing(tile, GetRoadOwner(tile, ROADTYPE_ROAD), GetRoadOwner(tile, ROADTYPE_TRAM), _current_company, (track == TRACK_X ? AXIS_Y : AXIS_X), railtype, roadtypes, GetTownIndex(tile)); UpdateLevelCrossing(tile, false); } break; @@ -475,7 +472,7 @@ CommandCost CmdRemoveSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, if (v != NULL) FreeTrainTrackReservation(v); } owner = GetTileOwner(tile); - MakeRoadNormal(tile, GetCrossingRoadBits(tile), GetRoadTypes(tile), GetTownIndex(tile), GetRoadOwner(tile, ROADTYPE_ROAD), GetRoadOwner(tile, ROADTYPE_TRAM), GetRoadOwner(tile, ROADTYPE_HWAY)); + MakeRoadNormal(tile, GetCrossingRoadBits(tile), GetRoadTypes(tile), GetTownIndex(tile), GetRoadOwner(tile, ROADTYPE_ROAD), GetRoadOwner(tile, ROADTYPE_TRAM)); } break; } diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 1935c460a..511ca8169 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -176,8 +176,6 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec /* The tile doesn't have the given road type */ if (!HasBit(rts, rt)) return CMD_ERROR; - bool town_road_under_stop = false; - switch (GetTileType(tile)) { case MP_ROAD: if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR; @@ -185,7 +183,6 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec case MP_STATION: if (!IsDriveThroughStopTile(tile)) return CMD_ERROR; - if (rt == ROADTYPE_ROAD) town_road_under_stop = GetStopBuiltOnTownRoad(tile); if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR; break; @@ -198,7 +195,7 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec return CMD_ERROR; } - if (!CheckAllowRemoveRoad(tile, pieces, town_road_under_stop ? OWNER_TOWN : GetRoadOwner(tile, rt), rt, flags, town_check)) return CMD_ERROR; + if (!CheckAllowRemoveRoad(tile, pieces, GetRoadOwner(tile, rt), rt, flags, town_check)) return CMD_ERROR; if (!IsTileType(tile, MP_ROAD)) { /* If it's the last roadtype, just clear the whole tile */ @@ -213,6 +210,15 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec SetRoadTypes(other_end, GetRoadTypes(other_end) & ~RoadTypeToRoadTypes(rt)); SetRoadTypes(tile, GetRoadTypes(tile) & ~RoadTypeToRoadTypes(rt)); + /* If the owner of the bridge sells all it's road, also move the ownership + * to the owner of the other roadtype. */ + RoadType other_rt = (rt == ROADTYPE_ROAD) ? ROADTYPE_TRAM : ROADTYPE_ROAD; + Owner other_owner = GetRoadOwner(tile, other_rt); + if (other_owner != GetTileOwner(tile)) { + SetTileOwner(tile, other_owner); + SetTileOwner(other_end, other_owner); + } + /* Mark tiles diry that have been repaved */ MarkTileDirtyByTile(tile); MarkTileDirtyByTile(other_end); @@ -547,7 +553,7 @@ CommandCost CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 YapfNotifyTrackLayoutChange(tile, FindFirstTrack(GetTrackBits(tile))); /* Always add road to the roadtypes (can't draw without it) */ bool reserved = HasBit(GetTrackReservation(tile), AxisToTrack(OtherAxis(roaddir))); - MakeRoadCrossing(tile, _current_company, _current_company, _current_company, GetTileOwner(tile), roaddir, GetRailType(tile), RoadTypeToRoadTypes(rt) | ROADTYPES_ROAD, p2); + MakeRoadCrossing(tile, _current_company, _current_company, GetTileOwner(tile), roaddir, GetRailType(tile), RoadTypeToRoadTypes(rt) | ROADTYPES_ROAD, p2); SetCrossingReservation(tile, reserved); UpdateLevelCrossing(tile, false); MarkTileDirtyByTile(tile); @@ -639,6 +645,8 @@ do_clear:; SetRoadTypes(other_end, GetRoadTypes(other_end) | RoadTypeToRoadTypes(rt)); SetRoadTypes(tile, GetRoadTypes(tile) | RoadTypeToRoadTypes(rt)); + SetRoadOwner(other_end, rt, _current_company); + SetRoadOwner(tile, rt, _current_company); /* Mark tiles diry that have been repaved */ MarkTileDirtyByTile(other_end); @@ -653,11 +661,11 @@ do_clear:; case MP_STATION: assert(IsDriveThroughStopTile(tile)); SetRoadTypes(tile, GetRoadTypes(tile) | RoadTypeToRoadTypes(rt)); - if (rt == ROADTYPE_ROAD) SetStopBuiltOnTownRoad(tile, false); + SetRoadOwner(tile, rt, _current_company); break; default: - MakeRoadNormal(tile, pieces, RoadTypeToRoadTypes(rt), p2, _current_company, _current_company, _current_company); + MakeRoadNormal(tile, pieces, RoadTypeToRoadTypes(rt), p2, _current_company, _current_company); break; } @@ -911,7 +919,7 @@ static CommandCost ClearTile_Road(TileIndex tile, DoCommandFlag flags) /* Must iterate over the roadtypes in a reverse manner because * tram tracks must be removed before the road bits. */ - RoadType rt = ROADTYPE_HWAY; + RoadType rt = ROADTYPE_TRAM; do { if (HasBit(rts, rt)) { CommandCost tmp_ret = RemoveRoad(tile, flags, GetCrossingRoadBits(tile), rt, false); diff --git a/src/road_map.h b/src/road_map.h index 0131f2f05..2b87216f9 100644 --- a/src/road_map.h +++ b/src/road_map.h @@ -59,9 +59,8 @@ static inline RoadBits GetRoadBits(TileIndex t, RoadType rt) assert(IsNormalRoad(t)); 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); + case ROADTYPE_ROAD: return (RoadBits)GB(_m[t].m5, 0, 4); + case ROADTYPE_TRAM: return (RoadBits)GB(_m[t].m3, 0, 4); } } @@ -74,9 +73,7 @@ static inline RoadBits GetRoadBits(TileIndex t, RoadType rt) */ static inline RoadBits GetOtherRoadBits(TileIndex t, RoadType rt) { - return ((rt == ROADTYPE_ROAD) ? ROAD_NONE : GetRoadBits(t, ROADTYPE_ROAD)) | - ((rt == ROADTYPE_TRAM) ? ROAD_NONE : GetRoadBits(t, ROADTYPE_TRAM)) | - ((rt == ROADTYPE_HWAY) ? ROAD_NONE : GetRoadBits(t, ROADTYPE_HWAY)); + return GetRoadBits(t, rt == ROADTYPE_ROAD ? ROADTYPE_TRAM : ROADTYPE_ROAD); } /** @@ -87,7 +84,7 @@ static inline RoadBits GetOtherRoadBits(TileIndex t, RoadType rt) */ static inline RoadBits GetAllRoadBits(TileIndex tile) { - return GetRoadBits(tile, ROADTYPE_ROAD) | GetRoadBits(tile, ROADTYPE_TRAM) | GetRoadBits(tile, ROADTYPE_HWAY); + return GetRoadBits(tile, ROADTYPE_ROAD) | GetRoadBits(tile, ROADTYPE_TRAM); } static inline void SetRoadBits(TileIndex t, RoadBits r, RoadType rt) @@ -95,29 +92,20 @@ static inline void SetRoadBits(TileIndex t, RoadBits r, RoadType rt) assert(IsNormalRoad(t)); // XXX incomplete 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; + case ROADTYPE_ROAD: SB(_m[t].m5, 0, 4, r); break; + case ROADTYPE_TRAM: SB(_m[t].m3, 0, 4, r); break; } } static inline RoadTypes GetRoadTypes(TileIndex t) { - if (IsTileType(t, MP_ROAD)) { - return (RoadTypes)GB(_me[t].m7, 5, 3); - } else { - return (RoadTypes)GB(_m[t].m3, 0, 3); - } + return (RoadTypes)GB(_me[t].m7, 6, 2); } static inline void SetRoadTypes(TileIndex t, RoadTypes rt) { - if (IsTileType(t, MP_ROAD)) { - SB(_me[t].m7, 5, 3, rt); - } else { - assert(IsTileType(t, MP_STATION) || IsTileType(t, MP_TUNNELBRIDGE)); - SB(_m[t].m3, 0, 2, rt); - } + assert(IsTileType(t, MP_ROAD) || IsTileType(t, MP_STATION) || IsTileType(t, MP_TUNNELBRIDGE)); + SB(_me[t].m7, 6, 2, rt); } static inline bool HasTileRoadType(TileIndex t, RoadType rt) @@ -127,63 +115,24 @@ static inline bool HasTileRoadType(TileIndex t, RoadType rt) static inline Owner GetRoadOwner(TileIndex t, RoadType rt) { - if (!IsTileType(t, MP_ROAD)) return GetTileOwner(t); - - switch (GetRoadTileType(t)) { + switch (rt) { 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: { - /* Trams don't need OWNER_TOWN, and remapping OWNER_NONE - * to OWNER_TOWN makes it use one bit less */ - Owner o = (Owner)GB( _m[t].m5, 0, 4); - return o == OWNER_TOWN ? OWNER_NONE : o; - } - 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: { - /* Trams don't need OWNER_TOWN, and remapping OWNER_NONE - * to OWNER_TOWN makes it use one bit less */ - Owner o = (Owner)GB( _m[t].m5, 0, 4); - return o == OWNER_TOWN ? OWNER_NONE : o; - } - case ROADTYPE_HWAY: return (Owner)GB(_me[t].m7, 0, 5); - } - case ROAD_TILE_DEPOT: return GetTileOwner(t); + case ROADTYPE_ROAD: return (Owner)GB(IsNormalRoadTile(t) ? _m[t].m1 : _me[t].m7, 0, 5); + case ROADTYPE_TRAM: { + /* Trams don't need OWNER_TOWN, and remapping OWNER_NONE + * to OWNER_TOWN makes it use one bit less */ + Owner o = (Owner)GB(_m[t].m3, 4, 4); + return o == OWNER_TOWN ? OWNER_NONE : o; + } } } static inline void SetRoadOwner(TileIndex t, RoadType rt, Owner o) { - if (!IsTileType(t, MP_ROAD)) return SetTileOwner(t, o); - - switch (GetRoadTileType(t)) { + switch (rt) { 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, 4, o == OWNER_NONE ? OWNER_TOWN : o); break; - case ROADTYPE_HWAY: SB(_me[t].m7, 0, 5, o); break; - } - break; - case ROAD_TILE_CROSSING: - switch (rt) { - default: NOT_REACHED(); - case ROADTYPE_ROAD: SB( _m[t].m4, 0, 5, o); break; - /* Trams don't need OWNER_TOWN, and remapping OWNER_NONE - * to OWNER_TOWN makes it use one bit less */ - case ROADTYPE_TRAM: SB( _m[t].m5, 0, 4, o == OWNER_NONE ? OWNER_TOWN : o); break; - case ROADTYPE_HWAY: SB(_me[t].m7, 0, 5, o); break; - } - break; - case ROAD_TILE_DEPOT: return SetTileOwner(t, o); + case ROADTYPE_ROAD: SB(IsNormalRoadTile(t) ? _m[t].m1 : _me[t].m7, 0, 5, o); break; + case ROADTYPE_TRAM: SB(_m[t].m3, 4, 4, o == OWNER_NONE ? OWNER_TOWN : o); break; } } @@ -200,7 +149,6 @@ static inline bool IsRoadOwner(TileIndex t, RoadType rt, Owner o) */ static inline bool HasTownOwnedRoad(TileIndex t) { - assert(IsTileType(t, MP_ROAD)); return HasTileRoadType(t, ROADTYPE_ROAD) && IsRoadOwner(t, ROADTYPE_ROAD, OWNER_TOWN); } @@ -240,7 +188,7 @@ static inline void SetDisallowedRoadDirections(TileIndex t, DisallowedRoadDirect static inline Axis GetCrossingRoadAxis(TileIndex t) { assert(IsLevelCrossing(t)); - return (Axis)GB(_m[t].m4, 6, 1); + return (Axis)GB(_m[t].m5, 0, 1); } static inline Axis GetCrossingRailAxis(TileIndex t) @@ -304,13 +252,13 @@ static inline TrackBits GetRailCrossingReservation(TileIndex t) static inline bool IsCrossingBarred(TileIndex t) { assert(IsLevelCrossing(t)); - return HasBit(_m[t].m4, 5); + return HasBit(_m[t].m5, 5); } static inline void SetCrossingBarred(TileIndex t, bool barred) { assert(IsLevelCrossing(t)); - SB(_m[t].m4, 5, 1, barred); + SB(_m[t].m5, 5, 1, barred ? 1 : 0); } static inline void UnbarCrossing(TileIndex t) @@ -326,13 +274,13 @@ static inline void BarCrossing(TileIndex t) #define IsOnDesert IsOnSnow static inline bool IsOnSnow(TileIndex t) { - return HasBit(_m[t].m3, 7); + return HasBit(_me[t].m7, 5); } #define ToggleDesert ToggleSnow static inline void ToggleSnow(TileIndex t) { - ToggleBit(_m[t].m3, 7); + ToggleBit(_me[t].m7, 5); } @@ -348,12 +296,12 @@ enum Roadside { static inline Roadside GetRoadside(TileIndex tile) { - return (Roadside)GB(_m[tile].m3, 4, 3); + return (Roadside)GB(_m[tile].m6, 3, 3); } static inline void SetRoadside(TileIndex tile, Roadside s) { - SB(_m[tile].m3, 4, 3, s); + SB(_m[tile].m6, 3, 3, s); } static inline bool HasRoadWorks(TileIndex t) @@ -363,9 +311,9 @@ static inline bool HasRoadWorks(TileIndex t) static inline bool IncreaseRoadWorksCounter(TileIndex t) { - AB(_m[t].m3, 0, 4, 1); + AB(_me[t].m7, 0, 4, 1); - return GB(_m[t].m3, 0, 4) == 15; + return GB(_me[t].m7, 0, 4) == 15; } static inline void StartRoadWorks(TileIndex t) @@ -384,7 +332,7 @@ static inline void TerminateRoadWorks(TileIndex t) assert(HasRoadWorks(t)); SetRoadside(t, (Roadside)(GetRoadside(t) - ROADSIDE_GRASS_ROAD_WORKS + ROADSIDE_GRASS)); /* Stop the counter */ - SB(_m[t].m3, 0, 4, 0); + SB(_me[t].m7, 0, 4, 0); } @@ -434,31 +382,32 @@ TrackBits GetAnyRoadTrackBits(TileIndex tile, RoadType rt); bool IsPossibleCrossing(const TileIndex tile, Axis ax); -static inline void MakeRoadNormal(TileIndex t, RoadBits bits, RoadTypes rot, TownID town, Owner road, Owner tram, Owner hway) +static inline void MakeRoadNormal(TileIndex t, RoadBits bits, RoadTypes rot, TownID town, Owner road, Owner tram) { SetTileType(t, MP_ROAD); SetTileOwner(t, road); _m[t].m2 = town; - _m[t].m3 = 0; - _m[t].m4 = (HasBit(rot, ROADTYPE_TRAM) ? bits : 0) << 4 | (HasBit(rot, ROADTYPE_ROAD) ? bits : 0); - _m[t].m5 = ROAD_TILE_NORMAL << 6; + _m[t].m3 = (HasBit(rot, ROADTYPE_TRAM) ? bits : 0); + _m[t].m4 = 0; + _m[t].m5 = (HasBit(rot, ROADTYPE_ROAD) ? bits : 0) | ROAD_TILE_NORMAL << 6; + SetRoadOwner(t, ROADTYPE_TRAM, tram); + SB(_m[t].m6, 2, 4, 0); + _me[t].m7 = rot << 6; SetRoadOwner(t, ROADTYPE_TRAM, 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 tram, Owner hway, Owner rail, Axis roaddir, RailType rat, RoadTypes rot, uint town) +static inline void MakeRoadCrossing(TileIndex t, Owner road, Owner tram, Owner rail, Axis roaddir, RailType rat, RoadTypes rot, uint town) { SetTileType(t, MP_ROAD); SetTileOwner(t, rail); _m[t].m2 = town; _m[t].m3 = rat; - _m[t].m4 = roaddir << 6 | road; - _m[t].m5 = ROAD_TILE_CROSSING << 6; - SetRoadOwner(t, ROADTYPE_TRAM, tram); + _m[t].m4 = 0; + _m[t].m5 = ROAD_TILE_CROSSING << 6 | roaddir; SB(_m[t].m6, 2, 4, 0); - _me[t].m7 = rot << 5 | hway; + _me[t].m7 = rot << 6 | road; + SetRoadOwner(t, ROADTYPE_TRAM, tram); } @@ -471,7 +420,8 @@ static inline void MakeRoadDepot(TileIndex t, Owner owner, DiagDirection dir, Ro _m[t].m4 = 0; _m[t].m5 = ROAD_TILE_DEPOT << 6 | dir; SB(_m[t].m6, 2, 4, 0); - _me[t].m7 = RoadTypeToRoadTypes(rt) << 5; + _me[t].m7 = RoadTypeToRoadTypes(rt) << 6 | owner; + SetRoadOwner(t, ROADTYPE_TRAM, owner); } #endif /* ROAD_MAP_H */ diff --git a/src/road_type.h b/src/road_type.h index 8cdf64df0..4554de2d3 100644 --- a/src/road_type.h +++ b/src/road_type.h @@ -16,7 +16,6 @@ enum RoadType { ROADTYPE_BEGIN = 0, ///< Used for iterations ROADTYPE_ROAD = 0, ///< Basic road type ROADTYPE_TRAM = 1, ///< Trams - ROADTYPE_HWAY = 2, ///< Only a placeholder. Not sure what we are going to do with this road type. ROADTYPE_END, ///< Used for iterations INVALID_ROADTYPE = 0xFF ///< flag for invalid roadtype }; @@ -27,16 +26,12 @@ DECLARE_POSTFIX_INCREMENT(RoadType); * @note currently only roadtypes with ROADTYPE_ROAD and ROADTYPE_TRAM are supported. */ enum RoadTypes { - ROADTYPES_NONE = 0, ///< No roadtypes - ROADTYPES_ROAD = 1 << ROADTYPE_ROAD, ///< Road - ROADTYPES_TRAM = 1 << ROADTYPE_TRAM, ///< Trams - ROADTYPES_HWAY = 1 << ROADTYPE_HWAY, ///< Highway (or whatever substitute) - ROADTYPES_ROADTRAM = ROADTYPES_ROAD | ROADTYPES_TRAM, ///< Road + trams - ROADTYPES_ROADHWAY = ROADTYPES_ROAD | ROADTYPES_HWAY, ///< Road + highway (or whatever substitute) - ROADTYPES_TRAMHWAY = ROADTYPES_TRAM | ROADTYPES_HWAY, ///< Trams + highway (or whatever substitute) - ROADTYPES_ALL = ROADTYPES_ROAD | ROADTYPES_TRAM | ROADTYPES_HWAY, ///< Road + trams + highway (or whatever substitute) - ROADTYPES_END, ///< Used for iterations? - INVALID_ROADTYPES = 0xFF ///< Invalid roadtypes + ROADTYPES_NONE = 0, ///< No roadtypes + ROADTYPES_ROAD = 1 << ROADTYPE_ROAD, ///< Road + ROADTYPES_TRAM = 1 << ROADTYPE_TRAM, ///< Trams + ROADTYPES_ALL = ROADTYPES_ROAD | ROADTYPES_TRAM, ///< Road + trams + ROADTYPES_END, ///< Used for iterations? + INVALID_ROADTYPES = 0xFF ///< Invalid roadtypes }; DECLARE_ENUM_AS_BIT_SET(RoadTypes); template <> struct EnumPropsT<RoadTypes> : MakeEnumPropsT<RoadTypes, byte, ROADTYPES_NONE, ROADTYPES_END, INVALID_ROADTYPES> {}; diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 2f2362a81..de48d461a 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -312,7 +312,7 @@ static void FixOwnerOfRailTrack(TileIndex t) if (IsLevelCrossingTile(t)) { /* else change the crossing to normal road (road vehicles won't care) */ MakeRoadNormal(t, GetCrossingRoadBits(t), GetRoadTypes(t), GetTownIndex(t), - GetRoadOwner(t, ROADTYPE_ROAD), GetRoadOwner(t, ROADTYPE_TRAM), GetRoadOwner(t, ROADTYPE_HWAY)); + GetRoadOwner(t, ROADTYPE_ROAD), GetRoadOwner(t, ROADTYPE_TRAM)); return; } @@ -709,7 +709,7 @@ bool AfterLoadGame() /* Added the RoadType */ bool old_bridge = CheckSavegameVersion(42); for (TileIndex t = 0; t < map_size; t++) { - switch(GetTileType(t)) { + switch (GetTileType(t)) { case MP_ROAD: SB(_m[t].m5, 6, 2, GB(_m[t].m5, 4, 2)); switch (GetRoadTileType(t)) { @@ -744,6 +744,73 @@ bool AfterLoadGame() } } + if (CheckSavegameVersion(114)) { + bool fix_roadtypes = !CheckSavegameVersion(61); + bool old_bridge = CheckSavegameVersion(42); + + for (TileIndex t = 0; t < map_size; t++) { + switch (GetTileType(t)) { + case MP_ROAD: + if (fix_roadtypes) SetRoadTypes(t, (RoadTypes)GB(_me[t].m7, 5, 3)); + SB(_me[t].m7, 5, 1, GB(_m[t].m3, 7, 1)); //snow/desert + switch (GetRoadTileType(t)) { + default: NOT_REACHED(); + case ROAD_TILE_NORMAL: + SB(_me[t].m7, 0, 4, GB(_m[t].m3, 0, 4)); // road works + SB(_m[t].m6, 3, 3, GB(_m[t].m3, 4, 3)); // ground + SB(_m[t].m3, 0, 4, GB(_m[t].m4, 4, 4)); // tram bits + SB(_m[t].m3, 4, 4, GB(_m[t].m5, 0, 4)); // tram owner + SB(_m[t].m5, 0, 4, GB(_m[t].m4, 0, 4)); // road bits + break; + + case ROAD_TILE_CROSSING: + SB(_me[t].m7, 0, 5, GB(_m[t].m4, 0, 5)); // road owner + SB(_m[t].m6, 3, 3, GB(_m[t].m3, 4, 3)); // ground + SB(_m[t].m3, 4, 4, GB(_m[t].m5, 0, 4)); // tram owner + SB(_m[t].m5, 0, 1, GB(_m[t].m4, 6, 1)); // road axis + SB(_m[t].m5, 5, 1, GB(_m[t].m4, 5, 1)); // crossing state + break; + + case ROAD_TILE_DEPOT: + break; + } + if (!HasTownOwnedRoad(t)) { + const Town *town = CalcClosestTownFromTile(t, (uint)-1); + if (town != NULL) SetTownIndex(t, town->index); + } + _m[t].m4 = 0; + break; + + case MP_STATION: + if (!IsRoadStop(t)) break; + + if (fix_roadtypes) SetRoadTypes(t, (RoadTypes)GB(_m[t].m3, 0, 3)); + SB(_me[t].m7, 0, 5, HasBit(_m[t].m6, 2) ? OWNER_TOWN : GetTileOwner(t)); + SB(_m[t].m3, 4, 4, _m[t].m1); + _m[t].m4 = 0; + break; + + case MP_TUNNELBRIDGE: + if (old_bridge && IsBridge(t) && HasBit(_m[t].m5, 6)) break; + if (((old_bridge && IsBridge(t)) ? (TransportType)GB(_m[t].m5, 1, 2) : GetTunnelBridgeTransportType(t)) == TRANSPORT_ROAD) { + if (fix_roadtypes) SetRoadTypes(t, (RoadTypes)GB(_m[t].m3, 0, 3)); + + Owner o = GetTileOwner(t); + SB(_me[t].m7, 0, 5, o); // road owner + SB(_m[t].m3, 4, 4, o == OWNER_NONE ? OWNER_TOWN : o); // tram owner + } + SB(_m[t].m6, 2, 4, GB(_m[t].m2, 4, 4)); // bridge type + SB(_me[t].m7, 5, 1, GB(_m[t].m4, 7, 1)); // snow/desert + + _m[t].m2 = 0; + _m[t].m4 = 0; + break; + + default: break; + } + } + } + if (CheckSavegameVersion(42)) { Vehicle *v; @@ -769,7 +836,7 @@ bool AfterLoadGame() axis == AXIS_X ? ROAD_Y : ROAD_X, ROADTYPES_ROAD, town, - GetTileOwner(t), OWNER_NONE, OWNER_NONE + GetTileOwner(t), OWNER_NONE ); } } else { @@ -942,10 +1009,6 @@ bool AfterLoadGame() } break; - case MP_ROAD: /* Clear PBS reservation on crossing */ - if (IsLevelCrossing(t)) ClrBit(_m[t].m5, 0); - break; - case MP_STATION: /* Clear PBS reservation on station */ ClrBit(_m[t].m3, 6); break; diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index d93f7fe1f..8b6b8e198 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -38,7 +38,7 @@ #include "saveload_internal.h" -extern const uint16 SAVEGAME_VERSION = 113; +extern const uint16 SAVEGAME_VERSION = 114; SavegameType _savegame_type; ///< type of savegame we are loading diff --git a/src/settings.cpp b/src/settings.cpp index 506ba8abf..f0731aa9a 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1379,6 +1379,7 @@ const SettingDesc _settings[] = { SDT_BOOL(GameSettings, station.modified_catchment, 0, 0, true, STR_CONFIG_SETTING_CATCHMENT, NULL), SDT_CONDBOOL(GameSettings, order.gradual_loading, 40, SL_MAX_VERSION, 0, 0, true, STR_CONFIG_SETTING_GRADUAL_LOADING, NULL), SDT_CONDBOOL(GameSettings, construction.road_stop_on_town_road, 47, SL_MAX_VERSION, 0, 0, true, STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD, NULL), + SDT_CONDBOOL(GameSettings, construction.road_stop_on_competitor_road, 114, SL_MAX_VERSION, 0, 0, true, STR_CONFIG_SETTING_STOP_ON_COMPETITOR_ROAD,NULL), SDT_CONDBOOL(GameSettings, station.adjacent_stations, 62, SL_MAX_VERSION, 0, 0, true, STR_CONFIG_SETTING_ADJACENT_STATIONS, NULL), SDT_CONDBOOL(GameSettings, economy.station_noise_level, 96, SL_MAX_VERSION, 0, 0, false, STR_CONFIG_SETTING_NOISE_LEVEL, InvalidateTownViewWindow), SDT_CONDBOOL(GameSettings, station.distant_join_stations, 106, SL_MAX_VERSION, 0, 0, true, STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS, DeleteSelectStationWindow), diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 2175139ab..e4ada3f92 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -1096,6 +1096,7 @@ static SettingEntry _settings_stations[] = { SettingEntry("economy.station_noise_level"), SettingEntry("station.modified_catchment"), SettingEntry("construction.road_stop_on_town_road"), + SettingEntry("construction.road_stop_on_competitor_road"), }; /** Stations sub-page */ static SettingsPage _settings_stations_page = {_settings_stations, lengthof(_settings_stations)}; diff --git a/src/settings_type.h b/src/settings_type.h index e385fa2a5..6185aae72 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -166,6 +166,7 @@ struct ConstructionSettings { bool signal_side; ///< show signals on right side bool extra_dynamite; ///< extra dynamite bool road_stop_on_town_road; ///< allow building of drive-through road stops on town owned roads + bool road_stop_on_competitor_road; ///< allow building of drive-through road stops on roads owned by competitors uint8 raw_industry_construction; ///< type of (raw) industry construction (none, "normal", prospecting) bool freeform_edges; ///< allow terraforming the tiles at the map edges }; diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 1e19cc55d..6748cdf2d 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -1392,7 +1392,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 + * bit 2..3: the roadtypes * bit 5: allow stations directly adjacent to other stations. * bit 16..31: station ID to join (INVALID_STATION if build new one) */ @@ -1401,10 +1401,11 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin bool type = HasBit(p2, 0); bool is_drive_through = HasBit(p2, 1); bool build_over_road = is_drive_through && IsNormalRoadTile(tile); - bool town_owned_road = false; - RoadTypes rts = (RoadTypes)GB(p2, 2, 3); + RoadTypes rts = (RoadTypes)GB(p2, 2, 2); StationID station_to_join = GB(p2, 16, 16); bool distant_join = (station_to_join != INVALID_STATION); + Owner tram_owner = _current_company; + Owner road_owner = _current_company; if (distant_join && (!_settings_game.station.distant_join_stations || !IsValidStationID(station_to_join))) return CMD_ERROR; @@ -1428,20 +1429,21 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin if (build_over_road) { /* there is a road, check if we can build road+tram stop over it */ if (HasBit(cur_rts, ROADTYPE_ROAD)) { - Owner road_owner = GetRoadOwner(tile, ROADTYPE_ROAD); + road_owner = GetRoadOwner(tile, ROADTYPE_ROAD); if (road_owner == OWNER_TOWN) { - town_owned_road = true; if (!_settings_game.construction.road_stop_on_town_road) return_cmd_error(STR_DRIVE_THROUGH_ERROR_ON_TOWN_ROAD); - } else { - if (road_owner != OWNER_NONE && !CheckOwnership(road_owner)) return CMD_ERROR; + } else if (!_settings_game.construction.road_stop_on_competitor_road && road_owner != OWNER_NONE && !CheckOwnership(road_owner)) { + return CMD_ERROR; } num_roadbits += CountBits(GetRoadBits(tile, ROADTYPE_ROAD)); } /* there is a tram, check if we can build road+tram stop over it */ if (HasBit(cur_rts, ROADTYPE_TRAM)) { - Owner tram_owner = GetRoadOwner(tile, ROADTYPE_TRAM); - if (tram_owner != OWNER_NONE && !CheckOwnership(tram_owner)) return CMD_ERROR; + tram_owner = GetRoadOwner(tile, ROADTYPE_TRAM); + if (!_settings_game.construction.road_stop_on_competitor_road && tram_owner != OWNER_NONE && !CheckOwnership(tram_owner)) { + return CMD_ERROR; + } num_roadbits += CountBits(GetRoadBits(tile, ROADTYPE_TRAM)); } @@ -1516,7 +1518,7 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin RoadStopType rs_type = type ? ROADSTOP_TRUCK : ROADSTOP_BUS; if (is_drive_through) { - MakeDriveThroughRoadStop(tile, st->owner, st->index, rs_type, rts, (Axis)p1, town_owned_road); + MakeDriveThroughRoadStop(tile, st->owner, road_owner, tram_owner, st->index, rs_type, rts, (Axis)p1); } else { MakeRoadStop(tile, st->owner, st->index, rs_type, rts, (DiagDirection)p1); } @@ -1629,7 +1631,6 @@ CommandCost CmdRemoveRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, ui RoadBits road_bits = IsDriveThroughStopTile(tile) ? ((GetRoadStopDir(tile) == DIAGDIR_NE) ? ROAD_X : ROAD_Y) : DiagDirToRoadBits(GetRoadStopDir(tile)); - bool is_towns_road = is_drive_through && GetStopBuiltOnTownRoad(tile); CommandCost ret = RemoveRoadStop(st, flags, tile); @@ -1639,7 +1640,7 @@ CommandCost CmdRemoveRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, ui * removed by the owner of the roadstop, _current_company is the * owner of the road stop. */ MakeRoadNormal(tile, road_bits, rts, ClosestTownFromTile(tile, UINT_MAX)->index, - is_towns_road ? OWNER_TOWN : _current_company, _current_company, _current_company); + GetRoadOwner(tile, ROADTYPE_ROAD), GetRoadOwner(tile, ROADTYPE_TRAM)); } return ret; @@ -2478,10 +2479,27 @@ static void GetAcceptedCargo_Station(TileIndex tile, AcceptedCargo ac) static void GetTileDesc_Station(TileIndex tile, TileDesc *td) { td->owner[0] = GetTileOwner(tile); - if (IsDriveThroughStopTile(tile) && HasTileRoadType(tile, ROADTYPE_ROAD) && GetStopBuiltOnTownRoad(tile)) { - /* Display a second owner */ - td->owner_type[1] = STR_ROAD_OWNER; - td->owner[1] = OWNER_TOWN; + if (IsDriveThroughStopTile(tile)) { + Owner road_owner = INVALID_OWNER; + Owner tram_owner = INVALID_OWNER; + RoadTypes rts = GetRoadTypes(tile); + if (HasBit(rts, ROADTYPE_ROAD)) road_owner = GetRoadOwner(tile, ROADTYPE_ROAD); + if (HasBit(rts, ROADTYPE_TRAM)) tram_owner = GetRoadOwner(tile, ROADTYPE_TRAM); + + /* Is there a mix of owners? */ + if ((tram_owner != INVALID_OWNER && tram_owner != td->owner[0]) || + (road_owner != INVALID_OWNER && road_owner != td->owner[0])) { + uint i = 1; + if (road_owner != INVALID_OWNER) { + td->owner_type[i] = STR_ROAD_OWNER; + td->owner[i] = road_owner; + i++; + } + if (tram_owner != INVALID_OWNER) { + td->owner_type[i] = STR_TRAM_OWNER; + td->owner[i] = tram_owner; + } + } } td->build_date = GetStationByTile(tile)->build_date; @@ -3117,6 +3135,15 @@ void DeleteOilRig(TileIndex tile) static void ChangeTileOwner_Station(TileIndex tile, Owner old_owner, Owner new_owner) { + if (IsDriveThroughStopTile(tile)) { + for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) { + /* Update all roadtypes, no matter if they are present */ + if (GetRoadOwner(tile, rt) == old_owner) { + SetRoadOwner(tile, rt, new_owner == INVALID_OWNER ? OWNER_NONE : new_owner); + } + } + } + if (!IsTileOwner(tile, old_owner)) return; if (new_owner != INVALID_OWNER) { @@ -3150,10 +3177,16 @@ static void ChangeTileOwner_Station(TileIndex tile, Owner old_owner, Owner new_o */ static bool CanRemoveRoadWithStop(TileIndex tile, DoCommandFlag flags) { - /* The road can always be cleared if it was not a town-owned road */ - if (!GetStopBuiltOnTownRoad(tile)) return true; + Owner road_owner = _current_company; + Owner tram_owner = _current_company; + + RoadTypes rts = GetRoadTypes(tile); + if (HasBit(rts, ROADTYPE_ROAD)) road_owner = GetRoadOwner(tile, ROADTYPE_ROAD); + if (HasBit(rts, ROADTYPE_TRAM)) tram_owner = GetRoadOwner(tile, ROADTYPE_TRAM); + + if ((road_owner != OWNER_TOWN && !CheckOwnership(road_owner)) || !CheckOwnership(tram_owner)) return false; - return CheckAllowRemoveRoad(tile, GetAnyRoadBits(tile, ROADTYPE_ROAD), OWNER_TOWN, ROADTYPE_ROAD, flags); + return road_owner != OWNER_TOWN || CheckAllowRemoveRoad(tile, GetAnyRoadBits(tile, ROADTYPE_ROAD), OWNER_TOWN, ROADTYPE_ROAD, flags); } static CommandCost ClearTile_Station(TileIndex tile, DoCommandFlag flags) diff --git a/src/station_map.h b/src/station_map.h index c7d938f3d..d9b0499e4 100644 --- a/src/station_map.h +++ b/src/station_map.h @@ -145,19 +145,6 @@ static inline bool IsDriveThroughStopTile(TileIndex t) return IsRoadStopTile(t) && GetStationGfx(t) >= GFX_TRUCK_BUS_DRIVETHROUGH_OFFSET; } -static inline bool GetStopBuiltOnTownRoad(TileIndex t) -{ - assert(IsDriveThroughStopTile(t)); - return HasBit(_m[t].m6, 2); -} - -static inline void SetStopBuiltOnTownRoad(TileIndex t, bool on_town_road) -{ - assert(IsDriveThroughStopTile(t)); - SB(_m[t].m6, 2, 1, on_town_road); -} - - /** * Gets the direction the road stop entrance points towards. */ @@ -341,13 +328,16 @@ static inline void MakeRoadStop(TileIndex t, Owner o, StationID sid, RoadStopTyp { MakeStation(t, o, sid, (rst == ROADSTOP_BUS ? STATION_BUS : STATION_TRUCK), d); SetRoadTypes(t, rt); + SetRoadOwner(t, ROADTYPE_ROAD, o); + SetRoadOwner(t, ROADTYPE_TRAM, o); } -static inline void MakeDriveThroughRoadStop(TileIndex t, Owner o, StationID sid, RoadStopType rst, RoadTypes rt, Axis a, bool on_town_road) +static inline void MakeDriveThroughRoadStop(TileIndex t, Owner station, Owner road, Owner tram, StationID sid, RoadStopType rst, RoadTypes rt, Axis a) { - MakeStation(t, o, sid, (rst == ROADSTOP_BUS ? STATION_BUS : STATION_TRUCK), GFX_TRUCK_BUS_DRIVETHROUGH_OFFSET + a); - SB(_m[t].m6, 2, 1, on_town_road); + MakeStation(t, station, sid, (rst == ROADSTOP_BUS ? STATION_BUS : STATION_TRUCK), GFX_TRUCK_BUS_DRIVETHROUGH_OFFSET + a); SetRoadTypes(t, rt); + SetRoadOwner(t, ROADTYPE_ROAD, road); + SetRoadOwner(t, ROADTYPE_TRAM, tram); } static inline void MakeAirport(TileIndex t, Owner o, StationID sid, byte section) diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index 5b6793208..3b195f596 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -649,9 +649,6 @@ static void ToolbarBuildRoadClick(Window *w) const Company *c = GetCompany(_local_company); DropDownList *list = new DropDownList(); for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) { - /* Highways don't exist */ - if (rt == ROADTYPE_HWAY) continue; - /* The standard road button is *always* available */ list->push_back(new DropDownListStringItem(STR_180A_ROAD_CONSTRUCTION + rt, rt, !(HasBit(c->avail_roadtypes, rt) || rt == ROADTYPE_ROAD))); } diff --git a/src/tunnel_map.h b/src/tunnel_map.h index 87abbea3c..b5e2e8a5d 100644 --- a/src/tunnel_map.h +++ b/src/tunnel_map.h @@ -9,7 +9,7 @@ #include "rail_type.h" #include "road_type.h" #include "transport_type.h" -#include "tile_map.h" +#include "road_map.h" /** @@ -50,9 +50,12 @@ static inline void MakeRoadTunnel(TileIndex t, Owner o, DiagDirection d, RoadTyp 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_ROAD << 2 | d; + SetRoadOwner(t, ROADTYPE_ROAD, o); + if (o != OWNER_TOWN) SetRoadOwner(t, ROADTYPE_TRAM, o); + SetRoadTypes(t, r); } /** diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 585be6ed5..ddd38adf4 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -211,7 +211,7 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u /* type of bridge */ switch (transport_type) { case TRANSPORT_ROAD: - roadtypes = (RoadTypes)GB(p2, 8, 3); + roadtypes = (RoadTypes)GB(p2, 8, 2); if (!AreValidRoadTypes(roadtypes) || !HasRoadTypesAvail(_current_company, roadtypes)) return CMD_ERROR; break; @@ -354,7 +354,7 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u /* do the drill? */ if (flags & DC_EXEC) { DiagDirection dir = AxisToDiagDir(direction); - Owner owner = (replace_bridge && IsTileOwner(tile_start, OWNER_TOWN)) ? OWNER_TOWN : _current_company; + Owner owner = replace_bridge ? GetTileOwner(tile_start) : _current_company; switch (transport_type) { case TRANSPORT_RAIL: @@ -480,7 +480,7 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1, if (transport_type == TRANSPORT_RAIL) { if (!ValParamRailtype((RailType)p1)) return CMD_ERROR; } else { - const RoadTypes rts = (RoadTypes)GB(p1, 0, 3); + const RoadTypes rts = (RoadTypes)GB(p1, 0, 2); if (!AreValidRoadTypes(rts) || !HasRoadTypesAvail(_current_company, rts)) return CMD_ERROR; } @@ -570,8 +570,8 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1, AddSideToSignalBuffer(start_tile, INVALID_DIAGDIR, _current_company); YapfNotifyTrackLayoutChange(start_tile, DiagDirToDiagTrack(direction)); } else { - MakeRoadTunnel(start_tile, _current_company, direction, (RoadTypes)GB(p1, 0, 3)); - MakeRoadTunnel(end_tile, _current_company, ReverseDiagDir(direction), (RoadTypes)GB(p1, 0, 3)); + MakeRoadTunnel(start_tile, _current_company, direction, (RoadTypes)GB(p1, 0, 2)); + MakeRoadTunnel(end_tile, _current_company, ReverseDiagDir(direction), (RoadTypes)GB(p1, 0, 2)); } } @@ -583,11 +583,19 @@ static inline bool CheckAllowRemoveTunnelBridge(TileIndex tile) { /* Floods can remove anything as well as the scenario editor */ if (_current_company == OWNER_WATER || _game_mode == GM_EDITOR) return true; - /* Obviously if the bridge/tunnel belongs to us, or no-one, we can remove it */ - if (CheckTileOwnership(tile) || IsTileOwner(tile, OWNER_NONE)) return true; - /* Otherwise we can only remove town-owned stuff with extra settings, or cheat */ - if (IsTileOwner(tile, OWNER_TOWN) && (_settings_game.construction.extra_dynamite || _cheats.magic_bulldozer.value)) return true; - return false; + + RoadTypes rts = GetRoadTypes(tile); + Owner road_owner = _current_company; + Owner tram_owner = _current_company; + + if (HasBit(rts, ROADTYPE_ROAD)) road_owner = GetRoadOwner(tile, ROADTYPE_ROAD); + if (HasBit(rts, ROADTYPE_TRAM)) tram_owner = GetRoadOwner(tile, ROADTYPE_TRAM); + + /* We can remove unowned road and if the town allows it */ + if (road_owner == OWNER_NONE || (road_owner == OWNER_TOWN && (_settings_game.construction.extra_dynamite || _cheats.magic_bulldozer.value))) road_owner = _current_company; + if (tram_owner == OWNER_NONE) tram_owner = _current_company; + + return CheckOwnership(road_owner) && CheckOwnership(tram_owner); } static CommandCost DoClearTunnel(TileIndex tile, DoCommandFlag flags) @@ -1242,6 +1250,27 @@ static void GetTileDesc_TunnelBridge(TileIndex tile, TileDesc *td) td->str = (tt == TRANSPORT_WATER) ? STR_AQUEDUCT : GetBridgeSpec(GetBridgeType(tile))->transport_name[tt]; } td->owner[0] = GetTileOwner(tile); + + Owner road_owner = INVALID_OWNER; + Owner tram_owner = INVALID_OWNER; + RoadTypes rts = GetRoadTypes(tile); + if (HasBit(rts, ROADTYPE_ROAD)) road_owner = GetRoadOwner(tile, ROADTYPE_ROAD); + if (HasBit(rts, ROADTYPE_TRAM)) tram_owner = GetRoadOwner(tile, ROADTYPE_TRAM); + + /* Is there a mix of owners? */ + if ((tram_owner != INVALID_OWNER && tram_owner != td->owner[0]) || + (road_owner != INVALID_OWNER && road_owner != td->owner[0])) { + uint i = 1; + if (road_owner != INVALID_OWNER) { + td->owner_type[i] = STR_ROAD_OWNER; + td->owner[i] = road_owner; + i++; + } + if (tram_owner != INVALID_OWNER) { + td->owner_type[i] = STR_TRAM_OWNER; + td->owner[i] = tram_owner; + } + } } @@ -1292,6 +1321,13 @@ static TrackStatus GetTileTrackStatus_TunnelBridge(TileIndex tile, TransportType static void ChangeTileOwner_TunnelBridge(TileIndex tile, Owner old_owner, Owner new_owner) { + for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) { + /* Update all roadtypes, no matter if they are present */ + if (GetRoadOwner(tile, rt) == old_owner) { + SetRoadOwner(tile, rt, new_owner == INVALID_OWNER ? OWNER_NONE : new_owner); + } + } + if (!IsTileOwner(tile, old_owner)) return; if (new_owner != INVALID_OWNER) { diff --git a/src/tunnelbridge_map.h b/src/tunnelbridge_map.h index 5b5c6e447..5bb2a7465 100644 --- a/src/tunnelbridge_map.h +++ b/src/tunnelbridge_map.h @@ -52,7 +52,7 @@ static inline TransportType GetTunnelBridgeTransportType(TileIndex t) static inline bool HasTunnelBridgeSnowOrDesert(TileIndex t) { assert(IsTileType(t, MP_TUNNELBRIDGE)); - return HasBit(_m[t].m4, 7); + return HasBit(_me[t].m7, 5); } /** @@ -66,7 +66,7 @@ static inline bool HasTunnelBridgeSnowOrDesert(TileIndex t) static inline void SetTunnelBridgeSnowOrDesert(TileIndex t, bool snow_or_desert) { assert(IsTileType(t, MP_TUNNELBRIDGE)); - SB(_m[t].m4, 7, 1, snow_or_desert); + SB(_me[t].m7, 5, 1, snow_or_desert); } /** |