* 1) All the sprites in a railset MUST be in the same order. This order * is determined by normal rail. Check sprites 1005 and following for this order
* 2) The position where the railtype is loaded must always be the same, otherwise * the offset will fail. */ inline uint GetRailtypeSpriteOffset() const { return 82 * this->fallback_railtype; } }; /** * Returns a pointer to the Railtype information for a given railtype * @param railtype the rail type which the information is requested for * @return The pointer to the RailtypeInfo */ static inline const RailtypeInfo *GetRailTypeInfo(RailType railtype) { extern RailtypeInfo _railtypes[RAILTYPE_END]; assert(railtype < RAILTYPE_END); return &_railtypes[railtype]; } /** * Checks if an engine of the given RailType can drive on a tile with a given * RailType. This would normally just be an equality check, but for electric * rails (which also support non-electric engines). * @return Whether the engine can drive on this tile. * @param enginetype The RailType of the engine we are considering. * @param tiletype The RailType of the tile we are considering. */ static inline bool IsCompatibleRail(RailType enginetype, RailType tiletype) { return HasBit(GetRailTypeInfo(enginetype)->compatible_railtypes, tiletype); } /** * Checks if an engine of the given RailType got power on a tile with a given * RailType. This would normally just be an equality check, but for electric * rails (which also support non-electric engines). * @return Whether the engine got power on this tile. * @param enginetype The RailType of the engine we are considering. * @param tiletype The RailType of the tile we are considering. */ static inline bool HasPowerOnRail(RailType enginetype, RailType tiletype) { return HasBit(GetRailTypeInfo(enginetype)->powered_railtypes, tiletype); } /** * Test if a RailType disallows build of level crossings. * @param rt The RailType to check. * @return Whether level crossings are not allowed. */ static inline bool RailNoLevelCrossings(RailType rt) { return HasBit(GetRailTypeInfo(rt)->flags, RTF_NO_LEVEL_CROSSING); } /** * Test if 90 degree turns are disallowed between two railtypes. * @param rt1 First railtype to test for. * @param rt2 Second railtype to test for. * @param def Default value to use if the rail type doesn't specify anything. * @return True if 90 degree turns are disallowed between the two rail types. */ static inline bool Rail90DegTurnDisallowed(RailType rt1, RailType rt2, bool def = _settings_game.pf.forbid_90_deg) { if (rt1 == INVALID_RAILTYPE || rt2 == INVALID_RAILTYPE) return def; const RailtypeInfo *rti1 = GetRailTypeInfo(rt1); const RailtypeInfo *rti2 = GetRailTypeInfo(rt2); bool rt1_90deg = HasBit(rti1->flags, RTF_DISALLOW_90DEG) || (!HasBit(rti1->flags, RTF_ALLOW_90DEG) && def); bool rt2_90deg = HasBit(rti2->flags, RTF_DISALLOW_90DEG) || (!HasBit(rti2->flags, RTF_ALLOW_90DEG) && def); return rt1_90deg || rt2_90deg; } /** * Returns the cost of building the specified railtype. * @param railtype The railtype being built. * @return The cost multiplier. */ static inline Money RailBuildCost(RailType railtype) { assert(railtype < RAILTYPE_END); return (_price[PR_BUILD_RAIL] * GetRailTypeInfo(railtype)->cost_multiplier) >> 3; } /** * Returns the 'cost' of clearing the specified railtype. * @param railtype The railtype being removed. * @return The cost. */ static inline Money RailClearCost(RailType railtype) { /* Clearing rail in fact earns money, but if the build cost is set * very low then a loophole exists where money can be made. * In this case we limit the removal earnings to 3/4s of the build * cost. */ assert(railtype < RAILTYPE_END); return max(_price[PR_CLEAR_RAIL], -RailBuildCost(railtype) * 3 / 4); } /** * Calculates the cost of rail conversion * @param from The railtype we are converting from * @param to The railtype we are converting to * @return Cost per TrackBit */ static inline Money RailConvertCost(RailType from, RailType to) { /* Get the costs for removing and building anew * A conversion can never be more costly */ Money rebuildcost = RailBuildCost(to) + RailClearCost(from); /* Conversion between somewhat compatible railtypes: * Pay 1/8 of the target rail cost (labour costs) and additionally any difference in the * build costs, if the target type is more expensive (material upgrade costs). * Upgrade can never be more expensive than re-building. */ if (HasPowerOnRail(from, to) || HasPowerOnRail(to, from)) { Money upgradecost = RailBuildCost(to) / 8 + max((Money)0, RailBuildCost(to) - RailBuildCost(from)); return min(upgradecost, rebuildcost); } /* make the price the same as remove + build new type for rail types * which are not compatible in any way */ return rebuildcost; } /** * Calculates the maintenance cost of a number of track bits. * @param railtype The railtype to get the cost of. * @param num Number of track bits of this railtype. * @param total_num Total number of track bits of all railtypes. * @return Total cost. */ static inline Money RailMaintenanceCost(RailType railtype, uint32 num, uint32 total_num) { assert(railtype < RAILTYPE_END); return (_price[PR_INFRASTRUCTURE_RAIL] * GetRailTypeInfo(railtype)->maintenance_multiplier * num * (1 + IntSqrt(total_num))) >> 11; // 4 bits fraction for the multiplier and 7 bits scaling. } /** * Calculates the maintenance cost of a number of signals. * @param num Number of signals. * @return Total cost. */ static inline Money SignalMaintenanceCost(uint32 num) { return (_price[PR_INFRASTRUCTURE_RAIL] * 15 * num * (1 + IntSqrt(num))) >> 8; // 1 bit fraction for the multiplier and 7 bits scaling. } void DrawTrainDepotSprite(int x, int y, int image, RailType railtype); int TicksToLeaveDepot(const Train *v); Foundation GetRailFoundation(Slope tileh, TrackBits bits); bool HasRailtypeAvail(const CompanyID company, const RailType railtype); bool HasAnyRailtypesAvail(const CompanyID company); bool ValParamRailtype(const RailType rail); RailTypes AddDateIntroducedRailTypes(RailTypes current, Date date); RailType GetBestRailtype(const CompanyID company); RailTypes GetCompanyRailtypes(const CompanyID c); RailType GetRailTypeByLabel(RailTypeLabel label, bool allow_alternate_labels = true); void ResetRailTypes(); void InitRailTypes(); RailType AllocateRailType(RailTypeLabel label); 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. * @param var Railtype. */ #define FOR_ALL_SORTED_RAILTYPES(var) for (uint8 index = 0; index < _sorted_railtypes_size && (var = _sorted_railtypes[index], true) ; index++) #endif /* RAIL_H */