* 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);
RailTypes GetCompanyRailtypes(CompanyID company, bool introduces = true);
RailTypes GetRailTypes(bool introduces);
RailType GetRailTypeByLabel(RailTypeLabel label, bool allow_alternate_labels = true);
void ResetRailTypes();
void InitRailTypes();
RailType AllocateRailType(RailTypeLabel label);
extern std::vector