summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2009-03-02 22:57:47 +0000
committerrubidium <rubidium@openttd.org>2009-03-02 22:57:47 +0000
commit7831346ef8924c757fbd763c225c7b29b665604f (patch)
tree7514d56ab72b15863906486d7256f8e5dd2cef01
parent6dd3703a4caafff9a56d878ffac6ce322739067d (diff)
downloadopenttd-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.
-rw-r--r--docs/landscape.html46
-rw-r--r--docs/landscape_grid.html38
-rw-r--r--src/bridge_map.h10
-rw-r--r--src/lang/english.txt1
-rw-r--r--src/rail_cmd.cpp15
-rw-r--r--src/road_cmd.cpp24
-rw-r--r--src/road_map.h138
-rw-r--r--src/road_type.h17
-rw-r--r--src/saveload/afterload.cpp77
-rw-r--r--src/saveload/saveload.cpp2
-rw-r--r--src/settings.cpp1
-rw-r--r--src/settings_gui.cpp1
-rw-r--r--src/settings_type.h1
-rw-r--r--src/station_cmd.cpp71
-rw-r--r--src/station_map.h22
-rw-r--r--src/toolbar_gui.cpp3
-rw-r--r--src/tunnel_map.h7
-rw-r--r--src/tunnelbridge_cmd.cpp56
-rw-r--r--src/tunnelbridge_map.h4
19 files changed, 305 insertions, 229 deletions
diff --git a/docs/landscape.html b/docs/landscape.html
index c361f4f01..0f953f696 100644
--- a/docs/landscape.html
+++ b/docs/landscape.html
@@ -514,8 +514,8 @@
<td>
<ul>
<li>m2: Index into the array of towns (owning town for town roads; closest town otherwise, INVALID_TOWN if there is no town or we are creating a town)</li>
- <li>m3 bit 7 set = on snow or desert</li>
- <li>m7 bits 7..5: present road types
+ <li>m7 bit 5 set = on snow or desert</li>
+ <li>m7 bits 7..6: present road types
<table>
<tr>
<td>bit 0&nbsp; </td>
@@ -526,16 +526,11 @@
<td>bit 1&nbsp; </td>
<td>tram</td>
</tr>
-
- <tr>
- <td>bit 2&nbsp; </td>
- <td>reserved</td>
- </tr>
</table>
</li>
<li>m5 bits 7 clear: road or level-crossing
<ul>
- <li>m3 bits 6..4:
+ <li>m6 bits 5..3:
<table>
<tr>
<td><tt>0</tt>&nbsp; </td>
@@ -567,13 +562,12 @@
</tr>
</table>
</li>
- <li>m5 bits 3..0: <a href="#OwnershipInfo">owner</a> of road type 1 (tram); OWNER_NONE (<tt>10</tt>) is stored as OWNER_TOWN (<tt>0F</tt>)
- <li>m7 bits 4..0: <a href="#OwnershipInfo">owner</a> of road type 2 (reserved)
+ <li>m3 bits 7..4: <a href="#OwnershipInfo">owner</a> of road type 1 (tram); OWNER_NONE (<tt>10</tt>) is stored as OWNER_TOWN (<tt>0F</tt>)
<li>m5 bit 6 clear: road
<ul>
<li>m1: <a href="#OwnershipInfo">owner</a> of the road type 0 (normal road)</li>
- <li>m3 bits 3..0: counter for the roadworks</li>
- <li>m4 bits 3..0: road layout road type 0 (normal road): bit set = road piece present:
+ <li>m7 bits 3..0: counter for the roadworks</li>
+ <li>m5 bits 3..0: road layout road type 0 (normal road): bit set = road piece present:
<table>
<tr>
<td align=left>bit 0: </td>
@@ -593,8 +587,7 @@
</tr>
</table>
</li>
- <li>m4 bits 7..4: road layout road type 1 (tram)</li>
- <li>m6 bits 5..2: road layout road type 2 (reserved)</li>
+ <li>m3 bits 0..3: road layout road type 1 (tram)</li>
<li>m5 bits 5..4: bits to disallow vehicles to go a specific direction
<table>
<tr>
@@ -613,7 +606,7 @@
<ul>
<li>m1: <a href="#OwnershipInfo">owner</a> of the railway track</li>
<li>m3 bits 3..0: <a href="#TrackType">railway track type</a></li>
- <li>m4 bit 6: direction
+ <li>m5 bit 0: direction
<table>
<tr>
<td align=left><tt>0</tt>&nbsp; </td>
@@ -625,8 +618,8 @@
</tr>
</table>
</li>
- <li>m4 bit 5: set if crossing lights are on</li>
- <li>m4 bits 4..0: <a href="#OwnershipInfo">owner</a> of the road type 0 (normal road)</li>
+ <li>m5 bit 5: set if crossing lights are on</li>
+ <li>m6 bits 4..0: <a href="#OwnershipInfo">owner</a> of the road type 0 (normal road)</li>
<li>m5 bit 4: pbs reservation state</li>
</ul>
</li>
@@ -842,9 +835,9 @@
<ul>
<li>m1: <a href="#OwnershipInfo">owner</a> of the station</li>
<li>m2: index into the array of stations</li>
- <li>m3 bits 7..4: persistent random data for newstations</li>
+ <li>m3 bits 7..4: persistent random data for newstations (train station)</li>
+ <li>m3 bits 7..4: <a href="#OwnershipInfo">owner</a> of tram tracks (road stop)</li>
<li>m3 bits 3..0: <a href="#TrackType">track type</a> for railway stations</li>
- <li>m3 bits 2..0: present road types for road stops</li>
<li>m3 bits 1..0: water class for buoys and water part of docks</li>
<li>m4: custom station id; 0 means standard graphics</li>
<li>m5: graphics index (range from 0..255 for each station type):
@@ -943,10 +936,12 @@
</table>
</li>
<li>m6 bits 5..3: the station type (rail, airport, truck, bus, oilrig, dock, buoy)</li>
- <li>m6 bit 2: 1 when a drive through road stop is built over a town owned road, otherwise 0</li>
<li>m6 bit 2: pbs reservation state for railway stations</li>
+
<li>m6 bits 1..0 : <a href="#tropic_zone">Tropic zone definition</a></li>
- <li>m7: animation frame</li>
+ <li>m7 bits 4..0: <a href="#OwnershipInfo">owner</a> of road (road stops)</li>
+ <li>m7 bits 7..6: present road types (road stops)</li>
+ <li>m7: animation frame (train station)</li>
</ul>
</td>
</tr>
@@ -1413,15 +1408,13 @@
<td>
<ul>
<li>m1: <a href="#OwnershipInfo">owner</a></li>
- <li>m2 bits 7..4: see bridge ramp</li>
+ <li>m3 bits 7..4: <a href="#OwnershipInfo">owner</a> of tram</li>
<li>m3 bits 3..0: <a href="#TrackType">track type</a> for railway</li>
- <li>m3 bits 2..0: present road types for road</li>
- <li>m4 bit 7 set = on snow or desert</li>
<li>m5 bit 4: pbs reservation state for railway</li>
<li>m5 bits 7 clear: tunnel entrance/exit</li>
<li>m5 bit 7 set: bridge ramp
<ul>
- <li>m2 bits 7..4: <a name="BridgeType">bridge type</a>:
+ <li>m6 bits 5..2: <a name="BridgeType">bridge type</a>:
<table>
<tr>
<th align=left>Type&nbsp;</th>
@@ -1552,6 +1545,9 @@
</li>
<li>m6 bits 7..6 : Possibility of a bridge above, in the <a href="#bridge_direction">direction specified</a></li>
<li>m6 bits 1..0 : <a href="#tropic_zone">Tropic zone definition</a></li>
+ <li>m7 bits 4..0: <a href="#OwnershipInfo">owner</a> of road</li>
+ <li>m7 bit 5 set = on snow or desert</li>
+ <li>m7 bits 7..6: present road types for road</li>
</ul>
</td>
</tr>
diff --git a/docs/landscape_grid.html b/docs/landscape_grid.html
index 1b33f51a9..cc87cf2ad 100644
--- a/docs/landscape_grid.html
+++ b/docs/landscape_grid.html
@@ -137,10 +137,10 @@ the array so you can quickly see what is used and what is not.
<td class="bits"><span class="option">~~~</span>X XXXX</td>
<td class="bits">XXXX XXXX XXXX XXXX</td>
<td class="bits">XXXX XXXX</td>
+ <td class="bits"><span class="free">OOOO OOOO</span></td>
<td class="bits">XXXX XXXX</td>
- <td class="bits">XXXX XXXX</td>
- <td class="bits">XXXX XXXX</td>
- <td class="bits">XXXX XXXX</td>
+ <td class="bits">XXXX X<span class="free">O</span>XX</td>
+ <td class="bits">XXX<span class="free">O</span> XXXX</td>
</tr>
<tr>
<td class="caption">level crossing</td>
@@ -148,17 +148,17 @@ the array so you can quickly see what is used and what is not.
<td class="bits">-inherit-</td>
<td class="bits">-inherit-</td>
<td class="bits">XXXX <span class="option">~~</span>XX</td>
- <td class="bits"><span class="free">O</span>XXX XXXX</td>
- <td class="bits">XX<span class="free">O</span>X XXXX</td>
- <td class="bits">XX<span class="free">OO OO</span>XX</td>
<td class="bits">-inherit-</td>
+ <td class="bits">XXXX<span class="free"> OOO</span>X</td>
+ <td class="bits">XXXX X<span class="free">O</span>XX</td>
+ <td class="bits">XXXX XXXX</td>
</tr>
<tr>
<td class="caption">road depot</td>
<td class="bits">-inherit-</td>
<td class="bits">-inherit-</td>
<td class="bits">-inherit-</td>
- <td class="bits">X<span class="free">OOO OOOO</span></td>
+ <td class="bits"><span class="free">OOOO OOOO</span></td>
<td class="bits"><span class="free">OOOO OOOO</span></td>
<td class="bits">XX<span class="free">OO OO</span>XX</td>
<td class="bits">XX<span class="free">OO OO</span>XX</td>
@@ -205,11 +205,11 @@ the array so you can quickly see what is used and what is not.
<td class="bits">-inherit-</td>
<td class="bits">-inherit-</td>
<td class="bits">-inherit-</td>
- <td class="bits"><span class="free">OOOO O</span>XXX</td>
+ <td class="bits">XXXX XXXX</td>
<td class="bits"><span class="option">~~~~ ~~~~</span></td>
<td class="bits"><span class="option">~~~~ ~</span>XXX</td>
<td class="bits"><span class="free">OO</span>XX XXXX</td>
- <td class="bits"><span class="free">OOOO OOOO</span></td>
+ <td class="bits">XXXX X<span class="free">O</span>XX</td>
</tr>
<tr>
<td class="caption">dock</td>
@@ -308,22 +308,22 @@ the array so you can quickly see what is used and what is not.
<td class="bits">XXXX XXXX</td>
<td class="bits"><span class="option">~~~</span>X XXXX</td>
<td class="bits"><span class="free">OOOO OOOO OOOO OOOO</span></td>
- <td class="bits"><span class="free">OOOO</span> <span class="option">~</span><span class="abuse">XXX</span></td>
- <td class="bits">X<span class="free">OOO OOOO</span></td>
- <td class="bits">X<span class="free">OO</span>X <span class="option">~</span>XXX</td>
- <td class="bits">XX<span class="free">OO OO</span>XX</td>
+ <td class="bits">XXXX <span class="option">~~</span>XX</td>
<td class="bits"><span class="free">OOOO OOOO</span></td>
+ <td class="bits">X<span class="free">OO</span>X XXXX</td>
+ <td class="bits">XX<span class="free">OO OO</span>XX</td>
+ <td class="bits">XXXX X<span class="free">O</span>XX</td>
</tr>
<tr>
<td>bridge ramp</td>
<td class="bits">-inherit-</td>
<td class="bits">-inherit-</td>
- <td class="bits"><span class="free">OOOO OOOO</span> XXXX <span class="free">OOOO</span></td>
- <td class="bits"><span class="free">OOOO</span> <span class="option">~</span><span class="abuse">XXX</span></td>
- <td class="bits">X<span class="free">OOO OOOO</span></td>
- <td class="bits">X<span class="free">OO</span>X XXXX</td>
- <td class="bits">XX<span class="free">OO OO</span>XX</td>
- <td class="bits"><span class="free">OOOO OOOO</span></td>
+ <td class="bits">-inherit-</td>
+ <td class="bits">-inherit-</td>
+ <td class="bits">-inherit-</td>
+ <td class="bits">-inherit-</td>
+ <td class="bits">XXXX XXXX</td>
+ <td class="bits">-inherit-</td>
</tr>
<tr>
<td rowspan=2>A</td>
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);
}
/**