* 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); } /** * 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. * @return Total cost. */ static inline Money RailMaintenanceCost(RailType railtype, uint32 num) { assert(railtype < RAILTYPE_END); return (_price[PR_INFRASTRUCTURE_RAIL] * GetRailTypeInfo(railtype)->maintenance_multiplier * num * (1 + IntSqrt(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 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); #endif /* RAIL_H */