tron@2186: /* $Id$ */ tron@2186: rubidium@9111: /** @file rail.h Rail specific functions. */ celestar@2232: matthijs@1942: #ifndef RAIL_H matthijs@1942: #define RAIL_H matthijs@1942: rubidium@8101: #include "rail_type.h" rubidium@8101: #include "track_type.h" rubidium@8119: #include "vehicle_type.h" rubidium@8123: #include "gfx_type.h" rubidium@8113: #include "core/bitmath_func.hpp" rubidium@8123: #include "economy_func.h" smatz@9154: #include "slope_type.h" matthijs@1942: peter1138@8860: enum RailTypeFlag { peter1138@8860: RTF_CATENARY = 0, ///< Set if the rail type should have catenary drawn peter1138@8860: }; peter1138@8860: peter1138@8860: enum RailTypeFlags { peter1138@8860: RTFB_NONE = 0, peter1138@8860: RTFB_CATENARY = 1 << RTF_CATENARY, peter1138@8860: }; peter1138@8860: DECLARE_ENUM_AS_BIT_SET(RailTypeFlags); peter1138@8860: celestar@2233: /** This struct contains all the info that is needed to draw and construct tracks. celestar@2233: */ rubidium@6248: struct RailtypeInfo { celestar@2274: /** Struct containing the main sprites. @note not all sprites are listed, but only celestar@2274: * the ones used directly in the code */ celestar@2233: struct { celestar@2233: SpriteID track_y; ///< single piece of rail in Y direction, with ground celestar@2233: SpriteID track_ns; ///< two pieces of rail in North and South corner (East-West direction) celestar@2233: SpriteID ground; ///< ground sprite for a 3-way switch celestar@2233: SpriteID single_y; ///< single piece of rail in Y direction, without ground celestar@2233: SpriteID single_x; ///< single piece of rail in X direction celestar@2233: SpriteID single_n; ///< single piece of rail in the northern corner celestar@2233: SpriteID single_s; ///< single piece of rail in the southern corner celestar@2233: SpriteID single_e; ///< single piece of rail in the eastern corner celestar@2233: SpriteID single_w; ///< single piece of rail in the western corner rubidium@9493: SpriteID single_sloped;///< single piecs of rail for slopes tron@2511: SpriteID crossing; ///< level crossing, rail in X direction tron@2511: SpriteID tunnel; ///< tunnel sprites base celestar@2233: } base_sprites; celestar@2233: celestar@2274: /** struct containing the sprites for the rail GUI. @note only sprites referred to celestar@2274: * directly in the code are listed */ celestar@2274: struct { celestar@2274: SpriteID build_ns_rail; ///< button for building single rail in N-S direction celestar@2274: SpriteID build_x_rail; ///< button for building single rail in X direction celestar@2274: SpriteID build_ew_rail; ///< button for building single rail in E-W direction celestar@2274: SpriteID build_y_rail; ///< button for building single rail in Y direction celestar@2274: SpriteID auto_rail; ///< button for the autorail construction celestar@2274: SpriteID build_depot; ///< button for building depots celestar@2274: SpriteID build_tunnel; ///< button for building a tunnel celestar@2274: SpriteID convert_rail; ///< button for converting rail celestar@2274: } gui_sprites; celestar@2274: celestar@2274: struct { rubidium@7396: CursorID rail_ns; ///< Cursor for building rail in N-S direction rubidium@7396: CursorID rail_swne; ///< Cursor for building rail in X direction rubidium@7396: CursorID rail_ew; ///< Cursor for building rail in E-W direction rubidium@7396: CursorID rail_nwse; ///< Cursor for building rail in Y direction rubidium@7396: CursorID autorail; ///< Cursor for autorail tool rubidium@7396: CursorID depot; ///< Cursor for building a depot rubidium@7396: CursorID tunnel; ///< Cursor for building a tunnel rubidium@7396: CursorID convert; ///< Cursor for converting track tron@2514: } cursor; tron@2514: tron@2514: struct { celestar@2274: StringID toolbar_caption; celestar@2274: } strings; celestar@2274: celestar@2233: /** sprite number difference between a piece of track on a snowy ground and the corresponding one on normal ground */ celestar@2233: SpriteID snow_offset; celestar@2233: celestar@3355: /** bitmask to the OTHER railtypes on which an engine of THIS railtype generates power */ rubidium@8236: RailTypes powered_railtypes; celestar@3355: celestar@3355: /** bitmask to the OTHER railtypes on which an engine of THIS railtype can physically travel */ rubidium@8236: RailTypes compatible_railtypes; celestar@2254: celestar@2254: /** celestar@2254: * Offset between the current railtype and normal rail. This means that:
celestar@2254: * 1) All the sprites in a railset MUST be in the same order. This order celestar@2254: * is determined by normal rail. Check sprites 1005 and following for this order
celestar@2254: * 2) The position where the railtype is loaded must always be the same, otherwise belugas@6420: * the offset will fail. celestar@2254: * @note: Something more flexible might be desirable in the future. celestar@2254: */ celestar@2254: SpriteID total_offset; celestar@2536: celestar@2536: /** tron@4077: * Bridge offset tron@4077: */ celestar@2536: SpriteID bridge_offset; peter1138@3503: peter1138@3503: /** peter1138@3503: * Offset to add to ground sprite when drawing custom waypoints / stations peter1138@3503: */ peter1138@3503: byte custom_ground_offset; peter1138@8169: peter1138@8169: /** peter1138@8169: * Multiplier for curve maximum speed advantage peter1138@8169: */ peter1138@8169: byte curve_speed; peter1138@8860: peter1138@8860: /** peter1138@8860: * Bit mask of rail type flags peter1138@8860: */ peter1138@8860: RailTypeFlags flags; rubidium@6248: }; celestar@2233: celestar@2233: matthijs@1967: /** celestar@2233: * Returns a pointer to the Railtype information for a given railtype celestar@2233: * @param railtype the rail type which the information is requested for celestar@2233: * @return The pointer to the RailtypeInfo celestar@2233: */ ludde@2236: static inline const RailtypeInfo *GetRailTypeInfo(RailType railtype) celestar@2233: { rubidium@6162: extern RailtypeInfo _railtypes[RAILTYPE_END]; celestar@2233: assert(railtype < RAILTYPE_END); ludde@2236: return &_railtypes[railtype]; celestar@2233: } celestar@2233: celestar@2233: /** matthijs@2006: * Checks if an engine of the given RailType can drive on a tile with a given matthijs@2006: * RailType. This would normally just be an equality check, but for electric matthijs@2006: * rails (which also support non-electric engines). matthijs@2006: * @return Whether the engine can drive on this tile. matthijs@2006: * @param enginetype The RailType of the engine we are considering. matthijs@2006: * @param tiletype The RailType of the tile we are considering. matthijs@2006: */ matthijs@2006: static inline bool IsCompatibleRail(RailType enginetype, RailType tiletype) matthijs@2006: { skidd13@7928: return HasBit(GetRailTypeInfo(enginetype)->compatible_railtypes, tiletype); matthijs@2006: } matthijs@2006: rubidium@7396: /** rubidium@7396: * Checks if an engine of the given RailType got power on a tile with a given rubidium@7396: * RailType. This would normally just be an equality check, but for electric rubidium@7396: * rails (which also support non-electric engines). rubidium@7396: * @return Whether the engine got power on this tile. rubidium@7396: * @param enginetype The RailType of the engine we are considering. rubidium@7396: * @param tiletype The RailType of the tile we are considering. rubidium@7396: */ celestar@3355: static inline bool HasPowerOnRail(RailType enginetype, RailType tiletype) celestar@3355: { skidd13@7928: return HasBit(GetRailTypeInfo(enginetype)->powered_railtypes, tiletype); celestar@3355: } celestar@3355: maedhros@7730: maedhros@7730: extern int _railtype_cost_multiplier[RAILTYPE_END]; maedhros@7730: extern const int _default_railtype_cost_multiplier[RAILTYPE_END]; maedhros@7730: maedhros@7730: /** maedhros@7730: * Returns the cost of building the specified railtype. maedhros@7730: * @param railtype The railtype being built. maedhros@7730: * @return The cost multiplier. maedhros@7730: */ maedhros@7730: static inline Money RailBuildCost(RailType railtype) maedhros@7730: { maedhros@7730: assert(railtype < RAILTYPE_END); maedhros@7730: return (_price.build_rail * _railtype_cost_multiplier[railtype]) >> 3; maedhros@7730: } maedhros@7730: smatz@8043: /** smatz@8043: * Calculates the cost of rail conversion smatz@8043: * @param from The railtype we are converting from smatz@8043: * @param to The railtype we are converting to smatz@8043: * @return Cost per TrackBit smatz@8043: */ smatz@8043: static inline Money RailConvertCost(RailType from, RailType to) smatz@8043: { smatz@8043: /* rail -> el. rail smatz@8043: * calculate the price as 5 / 4 of (cost build el. rail) - (cost build rail) smatz@8043: * (the price of workers to get to place is that 1/4) smatz@8043: */ smatz@8043: if (HasPowerOnRail(from, to)) { smatz@8043: return ((RailBuildCost(to) - RailBuildCost(from)) * 5) >> 2; smatz@8043: } smatz@8043: smatz@8043: /* el. rail -> rail smatz@8043: * calculate the price as 1 / 4 of (cost build el. rail) - (cost build rail) smatz@8043: * (the price of workers is 1 / 4 + price of copper sold to a recycle center) smatz@8043: */ smatz@8043: if (HasPowerOnRail(to, from)) { smatz@8043: return (RailBuildCost(from) - RailBuildCost(to)) >> 2; smatz@8043: } smatz@8043: smatz@8043: /* make the price the same as remove + build new type */ smatz@8043: return RailBuildCost(to) + _price.remove_rail; smatz@8043: } smatz@8043: rubidium@9775: Vehicle *UpdateTrainPowerProc(Vehicle *v, void *data); tron@2520: void DrawTrainDepotSprite(int x, int y, int image, RailType railtype); tron@2520: void DrawDefaultWaypointSprite(int x, int y, RailType railtype); rubidium@9775: Vehicle *EnsureNoTrainOnTrackProc(Vehicle *v, void *data); smatz@8712: int TicksToLeaveDepot(const Vehicle *v); celestar@3355: rubidium@7335: Foundation GetRailFoundation(Slope tileh, TrackBits bits); KUDr@5116: KUDr@5116: rubidium@8236: /** rubidium@8236: * Finds out if a Player has a certain railtype available rubidium@8236: * @param p Player in question rubidium@8236: * @param railtype requested RailType rubidium@8236: * @return true if player has requested RailType available rubidium@8236: */ rubidium@8236: bool HasRailtypeAvail(const PlayerID p, const RailType railtype); rubidium@8236: rubidium@8236: /** rubidium@8236: * Validate functions for rail building. rubidium@8236: * @param rail the railtype to check. rubidium@8236: * @return true if the current player may build the rail. rubidium@8236: */ rubidium@8236: bool ValParamRailtype(const RailType rail); rubidium@8236: rubidium@8236: /** rubidium@8236: * Returns the "best" railtype a player can build. rubidium@8236: * As the AI doesn't know what the BEST one is, we have our own priority list rubidium@8236: * here. When adding new railtypes, modify this function rubidium@8236: * @param p the player "in action" rubidium@8236: * @return The "best" railtype a player has available rubidium@8236: */ rubidium@8236: RailType GetBestRailtype(const PlayerID p); rubidium@8236: rubidium@8236: /** rubidium@8236: * Get the rail types the given player can build. rubidium@8236: * @param p the player to get the rail types for. rubidium@8236: * @return the rail types. rubidium@8236: */ rubidium@8236: RailTypes GetPlayerRailtypes(const PlayerID p); rubidium@8236: celestar@2536: #endif /* RAIL_H */