/* $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; /** * 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); } /** * 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; } /** * 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) + _price[PR_CLEAR_RAIL]; } void DrawTrainDepotSprite(int x, int y, int image, RailType railtype); Vehicle *EnsureNoTrainOnTrackProc(Vehicle *v, void *data); int TicksToLeaveDepot(const Train *v); Foundation GetRailFoundation(Slope tileh, TrackBits bits); /** * Finds out if a company has a certain 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); /** * Validate functions for rail building. * @param rail the railtype to check. * @return true if the current company may build the rail. */ bool ValParamRailtype(const RailType rail); /** * Returns the "best" railtype a company can build. * As the AI doesn't know what the BEST one is, we have our own priority list * here. When adding new railtypes, modify this function * @param company the company "in action" * @return The "best" railtype a company has available */ RailType GetBestRailtype(const CompanyID company); /** * Get the rail types the given company can build. * @param c the company to get the rail types for. * @return the rail types. */ RailTypes GetCompanyRailtypes(const CompanyID c); /** * Get the rail type for a given label. * @param label the railtype label. * @return the railtype. */ RailType GetRailTypeByLabel(RailTypeLabel label); /** * Reset all rail type information to its default values. */ void ResetRailTypes(); /** * Resolve sprites of custom rail types */ void InitRailTypes(); /** * Allocate a new rail type label */ RailType AllocateRailType(RailTypeLabel label); #endif /* RAIL_H */