diff --git a/src/rail.cpp b/src/rail.cpp --- a/src/rail.cpp +++ b/src/rail.cpp @@ -180,14 +180,24 @@ RailType GetTileRailType(TileIndex tile) } /** - * Finds out if a company has a certain railtype available + * Finds out if a company has a certain buildable railtype available. * @param company the company in question * @param railtype requested RailType * @return true if company has requested RailType available */ bool HasRailtypeAvail(const CompanyID company, const RailType railtype) { - return HasBit(Company::Get(company)->avail_railtypes, railtype); + return !HasBit(_railtypes_hidden_mask, railtype) && HasBit(Company::Get(company)->avail_railtypes, railtype); +} + +/** + * Test if any buildable railtype is available for a company. + * @param company the company in question + * @return true if company has any RailTypes available + */ +bool HasAnyRailtypesAvail(const CompanyID company) +{ + return (Company::Get(company)->avail_railtypes & ~_railtypes_hidden_mask) != 0; } /** diff --git a/src/rail.h b/src/rail.h --- a/src/rail.h +++ b/src/rail.h @@ -26,10 +26,12 @@ enum RailTypeFlags { RTF_CATENARY = 0, ///< Bit number for drawing a catenary. RTF_NO_LEVEL_CROSSING = 1, ///< Bit number for disallowing level crossings. + RTF_HIDDEN = 2, ///< Bit number for hiding from selection. RTFB_NONE = 0, ///< All flags cleared. RTFB_CATENARY = 1 << RTF_CATENARY, ///< Value for drawing a catenary. RTFB_NO_LEVEL_CROSSING = 1 << RTF_NO_LEVEL_CROSSING, ///< Value for disallowing level crossings. + RTFB_HIDDEN = 1 << RTF_HIDDEN, ///< Value for hiding from selection. }; DECLARE_ENUM_AS_BIT_SET(RailTypeFlags) @@ -419,6 +421,7 @@ Foundation GetRailFoundation(Slope tileh bool HasRailtypeAvail(const CompanyID company, const RailType railtype); +bool HasAnyRailtypesAvail(const CompanyID company); bool ValParamRailtype(const RailType rail); RailTypes AddDateIntroducedRailTypes(RailTypes current, Date date); @@ -434,6 +437,7 @@ RailType AllocateRailType(RailTypeLabel extern RailType _sorted_railtypes[RAILTYPE_END]; extern uint8 _sorted_railtypes_size; +extern RailTypes _railtypes_hidden_mask; /** * Loop header for iterating over railtypes, sorted by sortorder. diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -46,6 +46,7 @@ typedef SmallVector TrainLi RailtypeInfo _railtypes[RAILTYPE_END]; RailType _sorted_railtypes[RAILTYPE_END]; uint8 _sorted_railtypes_size; +RailTypes _railtypes_hidden_mask; /** Enum holding the signal offset in the sprite sheet according to the side it is representing. */ enum SignalOffsets { @@ -78,6 +79,8 @@ void ResetRailTypes() RailTypeLabelList(), 0, 0, RAILTYPES_NONE, RAILTYPES_NONE, 0, {}, {} }; for (; i < lengthof(_railtypes); i++) _railtypes[i] = empty_railtype; + + _railtypes_hidden_mask = RAILTYPES_NONE; } void ResolveRailTypeGUISprites(RailtypeInfo *rti) @@ -140,11 +143,12 @@ void InitRailTypes() for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) { RailtypeInfo *rti = &_railtypes[rt]; ResolveRailTypeGUISprites(rti); + if (HasBit(rti->flags, RTF_HIDDEN)) SetBit(_railtypes_hidden_mask, rt); } _sorted_railtypes_size = 0; for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) { - if (_railtypes[rt].label != 0) { + if (_railtypes[rt].label != 0 && !HasBit(_railtypes_hidden_mask, rt)) { _sorted_railtypes[_sorted_railtypes_size++] = rt; } } diff --git a/src/vehicle.cpp b/src/vehicle.cpp --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -1757,7 +1757,10 @@ bool CanBuildVehicleInfrastructure(Vehic UnitID max; switch (type) { - case VEH_TRAIN: max = _settings_game.vehicle.max_trains; break; + case VEH_TRAIN: + if (!HasAnyRailtypesAvail(_local_company)) return false; + 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;