diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp
index 014884c..6437f23 100644
--- a/src/airport_gui.cpp
+++ b/src/airport_gui.cpp
@@ -91,7 +91,7 @@ struct BuildAirToolbarWindow : Window {
{
if (!gui_scope) return;
- if (!CanBuildVehicleInfrastructure(VEH_AIRCRAFT, 0)) delete this;
+ if (!CanBuildVehicleInfrastructure(VEH_AIRCRAFT)) delete this;
}
virtual void OnClick(Point pt, int widget, int click_count)
@@ -159,7 +159,7 @@ struct BuildAirToolbarWindow : Window {
*/
static EventState AirportToolbarGlobalHotkeys(int hotkey)
{
- if (_game_mode != GM_NORMAL || !CanBuildVehicleInfrastructure(VEH_AIRCRAFT, 0)) return ES_NOT_HANDLED;
+ if (_game_mode != GM_NORMAL || !CanBuildVehicleInfrastructure(VEH_AIRCRAFT)) return ES_NOT_HANDLED;
Window *w = ShowBuildAirToolbar();
if (w == NULL) return ES_NOT_HANDLED;
return w->OnHotkey(hotkey);
diff --git a/src/dock_gui.cpp b/src/dock_gui.cpp
index 531fb4b..79eaa89 100644
--- a/src/dock_gui.cpp
+++ b/src/dock_gui.cpp
@@ -117,7 +117,7 @@ struct BuildDocksToolbarWindow : Window {
{
if (!gui_scope) return;
- bool can_build = CanBuildVehicleInfrastructure(VEH_SHIP, 0);
+ bool can_build = CanBuildVehicleInfrastructure(VEH_SHIP);
this->SetWidgetsDisabledState(!can_build,
WID_DT_DEPOT,
WID_DT_STATION,
@@ -145,17 +145,17 @@ struct BuildDocksToolbarWindow : Window {
break;
case WID_DT_DEPOT: // Build depot button
- if (!CanBuildVehicleInfrastructure(VEH_SHIP, 0)) return;
+ if (!CanBuildVehicleInfrastructure(VEH_SHIP)) return;
if (HandlePlacePushButton(this, WID_DT_DEPOT, SPR_CURSOR_SHIP_DEPOT, HT_RECT)) ShowBuildDocksDepotPicker(this);
break;
case WID_DT_STATION: // Build station button
- if (!CanBuildVehicleInfrastructure(VEH_SHIP, 0)) return;
+ if (!CanBuildVehicleInfrastructure(VEH_SHIP)) return;
if (HandlePlacePushButton(this, WID_DT_STATION, SPR_CURSOR_DOCK, HT_SPECIAL)) ShowBuildDockStationPicker(this);
break;
case WID_DT_BUOY: // Build buoy button
- if (!CanBuildVehicleInfrastructure(VEH_SHIP, 0)) return;
+ if (!CanBuildVehicleInfrastructure(VEH_SHIP)) return;
HandlePlacePushButton(this, WID_DT_BUOY, SPR_CURSOR_BUOY, HT_RECT);
break;
diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp
index 2c407b6..56e663c 100644
--- a/src/rail_gui.cpp
+++ b/src/rail_gui.cpp
@@ -444,7 +444,7 @@ struct BuildRailToolbarWindow : Window {
{
if (!gui_scope) return;
- if (!CanBuildVehicleInfrastructure(VEH_TRAIN, 0)) delete this;
+ if (!CanBuildVehicleInfrastructure(VEH_TRAIN)) delete this;
}
/**
@@ -778,7 +778,7 @@ struct BuildRailToolbarWindow : Window {
*/
static EventState RailToolbarGlobalHotkeys(int hotkey)
{
- if (_game_mode != GM_NORMAL || !CanBuildVehicleInfrastructure(VEH_TRAIN, 0)) return ES_NOT_HANDLED;
+ if (_game_mode != GM_NORMAL || !CanBuildVehicleInfrastructure(VEH_TRAIN)) return ES_NOT_HANDLED;
extern RailType _last_built_railtype;
Window *w = ShowBuildRailToolbar(_last_built_railtype);
if (w == NULL) return ES_NOT_HANDLED;
diff --git a/src/road.cpp b/src/road.cpp
index b891bb5..8cb4859 100644
--- a/src/road.cpp
+++ b/src/road.cpp
@@ -257,10 +257,11 @@ bool RoadTypeIdentifier::UnpackIfValid(uint32 data)
*/
RoadSubTypes ExistingRoadSubTypesForRoadType(RoadType rt, CompanyID c, bool any_date)
{
- if (c != INVALID_COMPANY) {
+ /* Check only players which can actually own vehicles, editor and gamescripts are considered deities */
+ if (c < OWNER_END) {
const Company *company = Company::GetIfValid(c);
- return company->avail_roadtypes[rt];
+ if (company != NULL) return company->avail_roadtypes[rt];
}
RoadSubTypes known_roadsubtypes = ROADSUBTYPES_NONE;
diff --git a/src/road_gui.cpp b/src/road_gui.cpp
index 1b9a32f..12c4f73 100644
--- a/src/road_gui.cpp
+++ b/src/road_gui.cpp
@@ -300,7 +300,7 @@ struct BuildRoadToolbarWindow : Window {
{
if (!gui_scope) return;
- bool can_build = CanBuildVehicleInfrastructure(VEH_ROAD, this->roadtype_identifier.basetype);
+ bool can_build = CanBuildVehicleInfrastructure(this->roadtype_identifier, _local_company, false);
this->SetWidgetsDisabledState(!can_build,
WID_ROT_DEPOT,
@@ -440,7 +440,7 @@ struct BuildRoadToolbarWindow : Window {
break;
case WID_ROT_DEPOT:
- if (_game_mode == GM_EDITOR || !CanBuildVehicleInfrastructure(VEH_ROAD, this->roadtype_identifier.basetype)) return;
+ if (_game_mode == GM_EDITOR || !CanBuildVehicleInfrastructure(this->roadtype_identifier, _local_company, false)) return;
if (HandlePlacePushButton(this, WID_ROT_DEPOT, GetRoadTypeInfo(roadtype_identifier)->cursor.depot, HT_RECT)) {
ShowRoadDepotPicker(this);
this->last_started_action = widget;
@@ -448,7 +448,7 @@ struct BuildRoadToolbarWindow : Window {
break;
case WID_ROT_BUS_STATION:
- if (_game_mode == GM_EDITOR || !CanBuildVehicleInfrastructure(VEH_ROAD, this->roadtype_identifier.basetype)) return;
+ if (_game_mode == GM_EDITOR || !CanBuildVehicleInfrastructure(this->roadtype_identifier, _local_company, false)) return;
if (HandlePlacePushButton(this, WID_ROT_BUS_STATION, SPR_CURSOR_BUS_STATION, HT_RECT)) {
ShowRVStationPicker(this, ROADSTOP_BUS);
this->last_started_action = widget;
@@ -456,7 +456,7 @@ struct BuildRoadToolbarWindow : Window {
break;
case WID_ROT_TRUCK_STATION:
- if (_game_mode == GM_EDITOR || !CanBuildVehicleInfrastructure(VEH_ROAD, this->roadtype_identifier.basetype)) return;
+ if (_game_mode == GM_EDITOR || !CanBuildVehicleInfrastructure(this->roadtype_identifier, _local_company, false)) return;
if (HandlePlacePushButton(this, WID_ROT_TRUCK_STATION, SPR_CURSOR_TRUCK_STATION, HT_RECT)) {
ShowRVStationPicker(this, ROADSTOP_TRUCK);
this->last_started_action = widget;
@@ -707,7 +707,7 @@ struct BuildRoadToolbarWindow : Window {
*/
static EventState RoadTramToolbarGlobalHotkeys(int hotkey, RoadTypeIdentifier last_build)
{
- if (last_build.basetype == ROADTYPE_TRAM && (_game_mode != GM_NORMAL || !CanBuildVehicleInfrastructure(VEH_ROAD, last_build.basetype))) return ES_NOT_HANDLED;
+ if (last_build.basetype == ROADTYPE_TRAM && (_game_mode != GM_NORMAL || !CanBuildVehicleInfrastructure(last_build, _local_company, false))) return ES_NOT_HANDLED;
Window *w = NULL;
switch (_game_mode) {
@@ -1316,7 +1316,7 @@ DropDownList *GetScenRoadTypeDropDownList(RoadTypes roadtypes)
for (RoadType rt = ROADTYPE_BEGIN; rt < ROADTYPE_END; rt++) {
if (!HasBit(roadtypes, rt)) continue;
- used_roadtypes = ExistingRoadSubTypesForRoadType(rt, INVALID_COMPANY, true);
+ used_roadtypes = ExistingRoadSubTypesForRoadType(rt, OWNER_DEITY, true);
/* If it's not used ever, don't show it to the user. */
RoadTypeIdentifier rtid;
diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp
index 4fe7d03..4180218 100644
--- a/src/toolbar_gui.cpp
+++ b/src/toolbar_gui.cpp
@@ -2054,9 +2054,9 @@ struct MainToolbarWindow : Window {
this->SetWidgetDisabledState(WID_TN_GOAL, Goal::GetNumItems() == 0);
this->SetWidgetDisabledState(WID_TN_STORY, StoryPage::GetNumItems() == 0);
- this->SetWidgetDisabledState(WID_TN_RAILS, !CanBuildVehicleInfrastructure(VEH_TRAIN, 0));
- this->SetWidgetDisabledState(WID_TN_TRAMS, !CanBuildVehicleInfrastructure(VEH_ROAD, ROADTYPE_TRAM));
- this->SetWidgetDisabledState(WID_TN_AIR, !CanBuildVehicleInfrastructure(VEH_AIRCRAFT, 0));
+ this->SetWidgetDisabledState(WID_TN_RAILS, !CanBuildVehicleInfrastructure(VEH_TRAIN));
+ this->SetWidgetDisabledState(WID_TN_TRAMS, !CanBuildVehicleInfrastructure(RoadTypeIdentifier(ROADTYPE_TRAM, ROADSUBTYPE_NORMAL), _local_company, false)); //TODO: should loop through all tramtypes
+ this->SetWidgetDisabledState(WID_TN_AIR, !CanBuildVehicleInfrastructure(VEH_AIRCRAFT));
this->DrawWidgets();
}
@@ -2097,11 +2097,11 @@ struct MainToolbarWindow : Window {
case MTHK_AIRCRAFT_LIST: ShowVehicleListWindow(_local_company, VEH_AIRCRAFT); break;
case MTHK_ZOOM_IN: ToolbarZoomInClick(this); break;
case MTHK_ZOOM_OUT: ToolbarZoomOutClick(this); break;
- case MTHK_BUILD_RAIL: if (CanBuildVehicleInfrastructure(VEH_TRAIN, 0)) ShowBuildRailToolbar(_last_built_railtype); break;
+ case MTHK_BUILD_RAIL: if (CanBuildVehicleInfrastructure(VEH_TRAIN)) ShowBuildRailToolbar(_last_built_railtype); break;
case MTHK_BUILD_ROAD: ShowBuildRoadToolbar(_last_built_roadtype_identifier); break;
- case MTHK_BUILD_TRAM: if (CanBuildVehicleInfrastructure(VEH_ROAD, ROADTYPE_TRAM)) ShowBuildRoadToolbar(_last_built_tramtype_identifier); break;
+ case MTHK_BUILD_TRAM: if (CanBuildVehicleInfrastructure(_last_built_tramtype_identifier, _local_company , false)) ShowBuildRoadToolbar(_last_built_tramtype_identifier); break;
case MTHK_BUILD_DOCKS: ShowBuildDocksToolbar(); break;
- case MTHK_BUILD_AIRPORT: if (CanBuildVehicleInfrastructure(VEH_AIRCRAFT, 0)) ShowBuildAirToolbar(); break;
+ case MTHK_BUILD_AIRPORT: if (CanBuildVehicleInfrastructure(VEH_AIRCRAFT)) ShowBuildAirToolbar(); break;
case MTHK_BUILD_TREES: ShowBuildTreesToolbar(); break;
case MTHK_MUSIC: ShowMusicWindow(); break;
case MTHK_AI_DEBUG: ShowAIDebugWindow(); break;
diff --git a/src/vehicle.cpp b/src/vehicle.cpp
index 86e3dbc..9fc2711 100644
--- a/src/vehicle.cpp
+++ b/src/vehicle.cpp
@@ -1714,12 +1714,12 @@ UnitID GetFreeUnitNumber(VehicleType type)
* vehicle type. This to disable building stations etc. when
* you are not allowed/able to have the vehicle type yet.
* @param type the vehicle type to check this for
- * @param subtype for road vehicles, either ROADTYPE_ROAD, ROADTYPE_TRAM or INVALID_ROADTYPE
* @return true if there is any reason why you may build
* the infrastructure for the given vehicle type
*/
-bool CanBuildVehicleInfrastructure(VehicleType type, uint subtype)
+bool CanBuildVehicleInfrastructure(VehicleType type)
{
+ assert(type != VEH_ROAD);
assert(IsCompanyBuildableVehicleType(type));
if (!Company::IsValidID(_local_company)) return false;
@@ -1728,7 +1728,6 @@ bool CanBuildVehicleInfrastructure(VehicleType type, uint subtype)
UnitID max;
switch (type) {
case VEH_TRAIN: max = _settings_game.vehicle.max_trains; break;
- case VEH_ROAD: max = _settings_game.vehicle.max_roadveh; break;
case VEH_SHIP: max = _settings_game.vehicle.max_ships; break;
case VEH_AIRCRAFT: max = _settings_game.vehicle.max_aircraft; break;
default: NOT_REACHED();
@@ -1739,8 +1738,7 @@ bool CanBuildVehicleInfrastructure(VehicleType type, uint subtype)
/* Can we actually build the vehicle type? */
const Engine *e;
FOR_ALL_ENGINES_OF_TYPE(e, type) {
- if ((type != VEH_ROAD || subtype == INVALID_ROADTYPE || subtype == e->GetRoadType().basetype) &&
- HasBit(e->company_avail, _local_company)) return true;
+ if (HasBit(e->company_avail, _local_company)) return true;
}
return false;
}
@@ -1748,14 +1746,45 @@ bool CanBuildVehicleInfrastructure(VehicleType type, uint subtype)
/* We should be able to build infrastructure when we have the actual vehicle type */
const Vehicle *v;
FOR_ALL_VEHICLES(v) {
- if (v->type == type &&
- (type != VEH_ROAD || subtype == INVALID_ROADTYPE || subtype == RoadVehicle::From(v)->rtid.basetype) &&
- v->owner == _local_company) return true;
+ if (v->type == type && v->owner == _local_company) return true;
}
return false;
}
+/**
+ * Check whether we can build infrastructure for the given RoadType. This to disable building stations etc. when
+ * you are not allowed/able to have the RoadType yet.
+ * @param rtid the roadtype to check this for
+ * @param company the company id to check this for
+ * @param any_date to check only existing vehicles or if it is possible to build them in the future
+ * @return true if there is any reason why you may build the infrastructure for the given roadtype
+ */
+bool CanBuildVehicleInfrastructure(RoadTypeIdentifier rtid, CompanyID company, bool any_date)
+{
+ if (_game_mode != GM_EDITOR && !Company::IsValidID(company)) return false;
+ if (!_settings_client.gui.disable_unsuitable_building) return true;
+
+ RoadSubTypes roadsubtypes = ExistingRoadSubTypesForRoadType(rtid.basetype, company, any_date);
+
+ if (_settings_game.vehicle.max_roadveh > 0) {
+ /* Can we actually build the vehicle type? */
+ const Engine *e;
+ FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) {
+ if (e->GetRoadType() == rtid && HasBit(roadsubtypes, e->GetRoadType().subtype)) return true;
+ }
+ return false;
+ }
+
+ /* We should be able to build infrastructure when we have the actual vehicle type */
+ const Vehicle *v;
+ FOR_ALL_VEHICLES(v) {
+ if (v->type == VEH_ROAD && (company == OWNER_NONE || v->owner == company) &&
+ HasBit(roadsubtypes, RoadVehicle::From(v)->rtid.subtype) && RoadVehicle::From(v)->rtid == rtid) return true;
+ }
+
+ return false;
+}
/**
* Determines the #LiveryScheme for a vehicle.
diff --git a/src/vehicle_func.h b/src/vehicle_func.h
index 9d08529..430d793 100644
--- a/src/vehicle_func.h
+++ b/src/vehicle_func.h
@@ -71,7 +71,8 @@ UnitID GetFreeUnitNumber(VehicleType type);
void VehicleEnterDepot(Vehicle *v);
-bool CanBuildVehicleInfrastructure(VehicleType type, uint subtype);
+bool CanBuildVehicleInfrastructure(VehicleType type);
+bool CanBuildVehicleInfrastructure(RoadTypeIdentifier rtid, CompanyID company, bool any_date);
/** Position information of a vehicle after it moved */
struct GetNewVehiclePosResult {