diff --git a/docs/newgrf-roadstops-nml.html b/docs/newgrf-roadstops-nml.html
index c8284cbb67..a111739eee 100644
--- a/docs/newgrf-roadstops-nml.html
+++ b/docs/newgrf-roadstops-nml.html
@@ -84,6 +84,10 @@
Only allow drive-through stops (not bay stops). (This only takes effect from road_stops version 2).
RST_GENERAL_FLAG_NO_AUTO_ROAD_CONNECTION
Do not automatically build connecting road pieces. (This only takes effect from road_stops version 3).
+ RST_GENERAL_FLAG_BUILD_MENU_ROAD_ONLY
+ Only show in the road build menu (not tram). (This only takes effect from road_stops version 4).
+ RST_GENERAL_FLAG_BUILD_MENU_TRAM_ONLY
+ Only show in the tram build menu (not road). (This only takes effect from road_stops version 4).
| minimum_bridge_height | Array of 6 items [0..255, ...] | Minimum clearances required for a bridge for each of the 6 views/rotations (or 0 to not allow any bridge). Values are given in height level units (1 level == 8px). |
| disallowed_bridge_pillars | Array of 6 items [bitmask(RST_BRIDGE_PILLAR_FLAG_, ...), ...] |
diff --git a/docs/newgrf-roadstops.html b/docs/newgrf-roadstops.html
index 7e0b31b090..6e75d16772 100644
--- a/docs/newgrf-roadstops.html
+++ b/docs/newgrf-roadstops.html
@@ -153,6 +153,8 @@
|
| 2 | 4 | Do not show catenary graphics.This requires road_stops, version 2. |
| 3 | 8 | Only allow drive-through stops (not bay stops).This requires road_stops, version 2. |
| 4 | 10 | Do not automatically build connecting road pieces.This requires road_stops, version 3. |
+ | 5 | 20 | Only show in the road build menu (not tram).This requires road_stops, version 4. |
+ | 6 | 40 | Only show in the tram build menu (not road).This requires road_stops, version 4. |
The default value is 0 (no flags enabled).
diff --git a/src/newgrf_extension.cpp b/src/newgrf_extension.cpp
index 52af6db64d..65eceebc6f 100644
--- a/src/newgrf_extension.cpp
+++ b/src/newgrf_extension.cpp
@@ -54,7 +54,7 @@ extern const GRFFeatureInfo _grf_feature_list[] = {
GRFFeatureInfo("action0_object_edge_foundation_mode", 2),
GRFFeatureInfo("action0_object_flood_resistant", 1),
GRFFeatureInfo("action0_object_viewport_map_tile_type", 1),
- GRFFeatureInfo("road_stops", 3),
+ GRFFeatureInfo("road_stops", 4),
GRFFeatureInfo("new_landscape", 1),
GRFFeatureInfo(),
};
diff --git a/src/newgrf_roadstop.cpp b/src/newgrf_roadstop.cpp
index 696179d5ec..b07832f12d 100644
--- a/src/newgrf_roadstop.cpp
+++ b/src/newgrf_roadstop.cpp
@@ -477,17 +477,18 @@ void TriggerRoadStopRandomisation(Station *st, TileIndex tile, RoadStopRandomTri
/**
* Checks if there's any new stations by a specific RoadStopType
- * @param rs the RoadStopType to check for.
- * @return true if there was any new RoadStopSpec's found for the given RoadStopType, else false.
+ * @param rs the RoadStopType to check.
+ * @param roadtype the RoadType to check.
+ * @return true if there was any new RoadStopSpec's found for the given RoadStopType and RoadType, else false.
*/
-bool GetIfNewStopsByType(RoadStopType rs)
+bool GetIfNewStopsByType(RoadStopType rs, RoadType roadtype)
{
if (!(RoadStopClass::GetClassCount() > 1 || RoadStopClass::Get(ROADSTOP_CLASS_DFLT)->GetSpecCount() > 1)) return false;
for (uint i = 0; i < RoadStopClass::GetClassCount(); i++) {
// We don't want to check the default or waypoint classes. These classes are always available.
if (i == ROADSTOP_CLASS_DFLT || i == ROADSTOP_CLASS_WAYP) continue;
RoadStopClass *roadstopclass = RoadStopClass::Get((RoadStopClassID)i);
- if (GetIfClassHasNewStopsByType(roadstopclass, rs)) return true;
+ if (GetIfClassHasNewStopsByType(roadstopclass, rs, roadtype)) return true;
}
return false;
}
@@ -495,13 +496,14 @@ bool GetIfNewStopsByType(RoadStopType rs)
/**
* Checks if the given RoadStopClass has any specs assigned to it, compatible with the given RoadStopType.
* @param roadstopclass the RoadStopClass to check.
- * @param rs the RoadStopType to check by.
- * @return true if the roadstopclass has any specs compatible with the given RoadStopType.
+ * @param rs the RoadStopType to check.
+ * @param roadtype the RoadType to check.
+ * @return true if the RoadStopSpec has any specs compatible with the given RoadStopType and RoadType.
*/
-bool GetIfClassHasNewStopsByType(RoadStopClass *roadstopclass, RoadStopType rs)
+bool GetIfClassHasNewStopsByType(RoadStopClass *roadstopclass, RoadStopType rs, RoadType roadtype)
{
for (uint j = 0; j < roadstopclass->GetSpecCount(); j++) {
- if (GetIfStopIsForType(roadstopclass->GetSpec(j), rs)) return true;
+ if (GetIfStopIsForType(roadstopclass->GetSpec(j), rs, roadtype)) return true;
}
return false;
}
@@ -509,13 +511,18 @@ bool GetIfClassHasNewStopsByType(RoadStopClass *roadstopclass, RoadStopType rs)
/**
* Checks if the given RoadStopSpec is compatible with the given RoadStopType.
* @param roadstopspec the RoadStopSpec to check.
- * @param rs the RoadStopType to check by.
- * @return true if the roadstopspec is compatible with the given RoadStopType.
+ * @param rs the RoadStopType to check.
+ * @param roadtype the RoadType to check.
+ * @return true if the RoadStopSpec is compatible with the given RoadStopType and RoadType.
*/
-bool GetIfStopIsForType(const RoadStopSpec *roadstopspec, RoadStopType rs)
+bool GetIfStopIsForType(const RoadStopSpec *roadstopspec, RoadStopType rs, RoadType roadtype)
{
// The roadstopspec is nullptr, must be the default station, always return true.
if (roadstopspec == nullptr) return true;
+
+ if (HasBit(roadstopspec->flags, RSF_BUILD_MENU_ROAD_ONLY) && !RoadTypeIsRoad(roadtype)) return false;
+ if (HasBit(roadstopspec->flags, RSF_BUILD_MENU_TRAM_ONLY) && !RoadTypeIsTram(roadtype)) return false;
+
if (roadstopspec->stop_type == ROADSTOPTYPE_ALL) return true;
switch (rs) {
diff --git a/src/newgrf_roadstop.h b/src/newgrf_roadstop.h
index f5c126f2a5..f5b05b0de4 100644
--- a/src/newgrf_roadstop.h
+++ b/src/newgrf_roadstop.h
@@ -69,6 +69,8 @@ enum RoadStopSpecFlags {
RSF_NO_CATENARY, ///< Do not show catenary.
RSF_DRIVE_THROUGH_ONLY, ///< Stop is drive-through only.
RSF_NO_AUTO_ROAD_CONNECTION, ///< No auto road connection.
+ RSF_BUILD_MENU_ROAD_ONLY, ///< Only show in the road build menu (not tram).
+ RSF_BUILD_MENU_TRAM_ONLY, ///< Only show in the tram build menu (not road).
};
enum RoadStopSpecIntlFlags {
@@ -181,9 +183,9 @@ uint8 GetRoadStopTileAnimationSpeed(TileIndex tile);
void TriggerRoadStopAnimation(BaseStation *st, TileIndex tile, StationAnimationTrigger trigger, CargoID cargo_type = CT_INVALID);
void TriggerRoadStopRandomisation(Station *st, TileIndex tile, RoadStopRandomTrigger trigger, CargoID cargo_type = CT_INVALID);
-bool GetIfNewStopsByType(RoadStopType rs);
-bool GetIfClassHasNewStopsByType(RoadStopClass *roadstopclass, RoadStopType rs);
-bool GetIfStopIsForType(const RoadStopSpec *roadstopspec, RoadStopType rs);
+bool GetIfNewStopsByType(RoadStopType rs, RoadType roadtype);
+bool GetIfClassHasNewStopsByType(RoadStopClass *roadstopclass, RoadStopType rs, RoadType roadtype);
+bool GetIfStopIsForType(const RoadStopSpec *roadstopspec, RoadStopType rs, RoadType roadtype);
uint GetCountOfCompatibleStopsByType(RoadStopClass *roadstopclass, RoadStopType rs);
diff --git a/src/road_gui.cpp b/src/road_gui.cpp
index 2b40630563..46b1af7262 100644
--- a/src/road_gui.cpp
+++ b/src/road_gui.cpp
@@ -95,7 +95,12 @@ static RoadType _cur_roadtype;
*/
static bool IsRoadStopAvailable(const RoadStopSpec *roadstopspec, StationType type)
{
- if (roadstopspec == nullptr || !HasBit(roadstopspec->callback_mask, CBM_ROAD_STOP_AVAIL)) return true;
+ if (roadstopspec == nullptr) return true;
+
+ if (HasBit(roadstopspec->flags, RSF_BUILD_MENU_ROAD_ONLY) && !RoadTypeIsRoad(_cur_roadtype)) return false;
+ if (HasBit(roadstopspec->flags, RSF_BUILD_MENU_TRAM_ONLY) && !RoadTypeIsTram(_cur_roadtype)) return false;
+
+ if (!HasBit(roadstopspec->callback_mask, CBM_ROAD_STOP_AVAIL)) return true;
uint16 cb_res = GetRoadStopCallback(CBID_STATION_AVAILABILITY, 0, 0, roadstopspec, nullptr, INVALID_TILE, _cur_roadtype, type, 0);
if (cb_res == CALLBACK_FAILED) return true;
@@ -788,7 +793,7 @@ struct BuildRoadToolbarWindow : Window {
case DDSP_BUILD_BUSSTOP:
case DDSP_REMOVE_BUSSTOP:
- if (this->IsWidgetLowered(WID_ROT_BUS_STATION) && GetIfClassHasNewStopsByType(RoadStopClass::Get(_roadstop_gui_settings.roadstop_class), ROADSTOP_BUS)) {
+ if (this->IsWidgetLowered(WID_ROT_BUS_STATION) && GetIfClassHasNewStopsByType(RoadStopClass::Get(_roadstop_gui_settings.roadstop_class), ROADSTOP_BUS, _cur_roadtype)) {
if (_remove_button_clicked) {
TileArea ta(start_tile, end_tile);
DoCommandP(ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_BUS, CMD_REMOVE_ROAD_STOP | CMD_MSG(this->rti->strings.err_remove_station[ROADSTOP_BUS]), CcPlaySound_CONSTRUCTION_OTHER);
@@ -800,7 +805,7 @@ struct BuildRoadToolbarWindow : Window {
case DDSP_BUILD_TRUCKSTOP:
case DDSP_REMOVE_TRUCKSTOP:
- if (this->IsWidgetLowered(WID_ROT_TRUCK_STATION) && GetIfClassHasNewStopsByType(RoadStopClass::Get(_roadstop_gui_settings.roadstop_class), ROADSTOP_TRUCK)) {
+ if (this->IsWidgetLowered(WID_ROT_TRUCK_STATION) && GetIfClassHasNewStopsByType(RoadStopClass::Get(_roadstop_gui_settings.roadstop_class), ROADSTOP_TRUCK, _cur_roadtype)) {
if (_remove_button_clicked) {
TileArea ta(start_tile, end_tile);
DoCommandP(ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_TRUCK, CMD_REMOVE_ROAD_STOP | CMD_MSG(this->rti->strings.err_remove_station[ROADSTOP_TRUCK]), CcPlaySound_CONSTRUCTION_OTHER);
@@ -1245,7 +1250,7 @@ public:
this->vscrollList = nullptr;
this->vscrollMatrix = nullptr;
this->roadStopType = rs;
- bool newstops = GetIfNewStopsByType(rs);
+ bool newstops = GetIfNewStopsByType(rs, _cur_roadtype);
this->CreateNestedTree();
@@ -1302,7 +1307,7 @@ public:
}
if (newstops) {
/* The currently selected class doesn't have any stops for this RoadStopType, reset the selection. */
- if (!GetIfClassHasNewStopsByType(RoadStopClass::Get(_roadstop_gui_settings.roadstop_class), rs)) {
+ if (!GetIfClassHasNewStopsByType(RoadStopClass::Get(_roadstop_gui_settings.roadstop_class), rs, _cur_roadtype)) {
_roadstop_gui_settings.roadstop_class = ROADSTOP_CLASS_DFLT;
_roadstop_gui_settings.roadstop_type = 0;
}
@@ -1310,7 +1315,7 @@ public:
_roadstop_gui_settings.roadstop_type = std::min((int)_roadstop_gui_settings.roadstop_type, _roadstop_gui_settings.roadstop_count - 1);
/* Reset back to default class if the previously selected class is not available for this road stop type. */
- if (!GetIfClassHasNewStopsByType(RoadStopClass::Get(_roadstop_gui_settings.roadstop_class), roadStopType)) {
+ if (!GetIfClassHasNewStopsByType(RoadStopClass::Get(_roadstop_gui_settings.roadstop_class), roadStopType, _cur_roadtype)) {
_roadstop_gui_settings.roadstop_class = ROADSTOP_CLASS_DFLT;
}
@@ -1364,7 +1369,7 @@ public:
continue;
}
RoadStopClass *rs_class = RoadStopClass::Get(rs_id);
- if (GetIfClassHasNewStopsByType(rs_class, this->roadStopType)) this->roadstop_classes.push_back(rs_id);
+ if (GetIfClassHasNewStopsByType(rs_class, this->roadStopType, _cur_roadtype)) this->roadstop_classes.push_back(rs_id);
}
if (this->ShowNewStops()) {
@@ -1614,7 +1619,7 @@ public:
int y = this->vscrollList->GetScrolledRowFromWidget(pt.y, this, WID_BROS_NEWST_LIST);
if (y >= (int)this->roadstop_classes.size()) return;
RoadStopClassID class_id = this->roadstop_classes[y];
- if (_roadstop_gui_settings.roadstop_class != class_id && GetIfClassHasNewStopsByType(RoadStopClass::Get(class_id), roadStopType)) {
+ if (_roadstop_gui_settings.roadstop_class != class_id && GetIfClassHasNewStopsByType(RoadStopClass::Get(class_id), roadStopType, _cur_roadtype)) {
_roadstop_gui_settings.roadstop_class = class_id;
RoadStopClass *rsclass = RoadStopClass::Get(_roadstop_gui_settings.roadstop_class);
_roadstop_gui_settings.roadstop_count = rsclass->GetSpecCount();