/* $Id$ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see
* 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. * @note: Something more flexible might be desirable in the future. */ SpriteID total_offset; /** * Bridge offset */ SpriteID bridge_offset; /** * Offset to add to ground sprite when drawing custom waypoints / stations */ byte custom_ground_offset; /** * Multiplier for curve maximum speed advantage */ byte curve_speed; /** * Bit mask of rail type flags */ RailTypeFlags flags; /** * Cost multiplier for building this rail type */ uint16 cost_multiplier; /** * Acceleration type of this rail type */ uint8 acceleration_type; /** * Maximum speed for vehicles travelling on this rail type */ uint16 max_speed; /** * Unique 32 bit rail type identifier */ RailTypeLabel label; /** * Colour on mini-map */ byte map_colour; /** * Introduction date. * When #INVALID_DATE or a vehicle using this railtype gets introduced earlier, * the vehicle's introduction date will be used instead for this railtype. * The introduction at this date is furthermore limited by the * #introduction_required_types. */ Date introduction_date; /** * Bitmask of railtypes that are required for this railtype to be introduced * at a given #introduction_date. */ RailTypes introduction_required_railtypes; /** * Bitmask of which other railtypes are introduced when this railtype is introduced. */ RailTypes introduces_railtypes; /** * The sorting order of this railtype for the toolbar dropdown. */ byte sorting_order; /** * Sprite groups for resolving sprites */ const SpriteGroup *group[RTSG_END]; inline bool UsesOverlay() const { return this->group[RTSG_GROUND] != NULL; } }; /** * 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) { /* rail -> el. rail * calculate the price as 5 / 4 of (cost build el. rail) - (cost build rail) * (the price of workers to get to place is that 1/4) */ if (HasPowerOnRail(from, to)) { Money cost = ((RailBuildCost(to) - RailBuildCost(from)) * 5) >> 2; if (cost != 0) return cost; } /* el. rail -> rail * calculate the price as 1 / 4 of (cost build el. rail) - (cost build rail) * (the price of workers is 1 / 4 + price of copper sold to a recycle center) */ if (HasPowerOnRail(to, from)) { Money cost = (RailBuildCost(from) - RailBuildCost(to)) >> 2; if (cost != 0) return cost; } /* make the price the same as remove + build new type */ return RailBuildCost(to) + RailClearCost(from); } 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); void ResetRailTypes(); void InitRailTypes(); RailType AllocateRailType(RailTypeLabel label); #endif /* RAIL_H */