2019-04-06 06:46:15 +00:00
|
|
|
/*
|
|
|
|
* 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 <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/** @file road.h Road specific functions. */
|
|
|
|
|
|
|
|
#ifndef ROAD_H
|
|
|
|
#define ROAD_H
|
|
|
|
|
|
|
|
#include "road_type.h"
|
|
|
|
#include "gfx_type.h"
|
|
|
|
#include "core/bitmath_func.hpp"
|
|
|
|
#include "strings_type.h"
|
2023-04-24 18:33:18 +00:00
|
|
|
#include "timer/timer_game_calendar.h"
|
2019-04-06 06:46:15 +00:00
|
|
|
#include "core/enum_type.hpp"
|
|
|
|
#include "newgrf.h"
|
|
|
|
#include "economy_func.h"
|
|
|
|
|
|
|
|
|
|
|
|
enum RoadTramType : bool {
|
|
|
|
RTT_ROAD,
|
|
|
|
RTT_TRAM,
|
|
|
|
};
|
|
|
|
|
2023-05-08 17:01:06 +00:00
|
|
|
enum RoadTramTypes : uint8_t {
|
2019-04-06 06:46:15 +00:00
|
|
|
RTTB_ROAD = 1 << RTT_ROAD,
|
|
|
|
RTTB_TRAM = 1 << RTT_TRAM,
|
|
|
|
};
|
|
|
|
DECLARE_ENUM_AS_BIT_SET(RoadTramTypes)
|
|
|
|
|
2021-04-30 15:01:26 +00:00
|
|
|
static const RoadTramType _roadtramtypes[] = { RTT_ROAD, RTT_TRAM };
|
2019-04-06 06:46:15 +00:00
|
|
|
|
2024-01-24 21:24:34 +00:00
|
|
|
/** Roadtype flag bit numbers. Starts with RO instead of R because R is used for rails */
|
|
|
|
enum RoadTypeFlag {
|
2019-04-06 06:46:15 +00:00
|
|
|
ROTF_CATENARY = 0, ///< Bit number for adding catenary
|
|
|
|
ROTF_NO_LEVEL_CROSSING, ///< Bit number for disabling level crossing
|
|
|
|
ROTF_NO_HOUSES, ///< Bit number for setting this roadtype as not house friendly
|
|
|
|
ROTF_HIDDEN, ///< Bit number for hidden from construction.
|
2023-03-30 08:34:26 +00:00
|
|
|
ROTF_TOWN_BUILD, ///< Bit number for allowing towns to build this roadtype.
|
2024-01-24 21:24:34 +00:00
|
|
|
};
|
2019-04-06 06:46:15 +00:00
|
|
|
|
2024-01-24 21:24:34 +00:00
|
|
|
/** Roadtype flags. Starts with RO instead of R because R is used for rails */
|
|
|
|
enum RoadTypeFlags : uint8_t {
|
2019-04-06 06:46:15 +00:00
|
|
|
ROTFB_NONE = 0, ///< All flags cleared.
|
|
|
|
ROTFB_CATENARY = 1 << ROTF_CATENARY, ///< Value for drawing a catenary.
|
|
|
|
ROTFB_NO_LEVEL_CROSSING = 1 << ROTF_NO_LEVEL_CROSSING, ///< Value for disabling a level crossing.
|
|
|
|
ROTFB_NO_HOUSES = 1 << ROTF_NO_HOUSES, ///< Value for for setting this roadtype as not house friendly.
|
|
|
|
ROTFB_HIDDEN = 1 << ROTF_HIDDEN, ///< Value for hidden from construction.
|
2023-03-30 08:34:26 +00:00
|
|
|
ROTFB_TOWN_BUILD = 1 << ROTF_TOWN_BUILD, ///< Value for allowing towns to build this roadtype.
|
2019-04-06 06:46:15 +00:00
|
|
|
};
|
|
|
|
DECLARE_ENUM_AS_BIT_SET(RoadTypeFlags)
|
|
|
|
|
|
|
|
struct SpriteGroup;
|
|
|
|
|
|
|
|
/** Sprite groups for a roadtype. */
|
|
|
|
enum RoadTypeSpriteGroup {
|
|
|
|
ROTSG_CURSORS, ///< Optional: Cursor and toolbar icon images
|
|
|
|
ROTSG_OVERLAY, ///< Optional: Images for overlaying track
|
|
|
|
ROTSG_GROUND, ///< Required: Main group of ground images
|
2022-12-17 14:01:47 +00:00
|
|
|
ROTSG_TUNNEL, ///< Optional: Ground images for tunnels
|
2019-04-06 06:46:15 +00:00
|
|
|
ROTSG_CATENARY_FRONT, ///< Optional: Catenary front
|
|
|
|
ROTSG_CATENARY_BACK, ///< Optional: Catenary back
|
|
|
|
ROTSG_BRIDGE, ///< Required: Bridge surface images
|
|
|
|
ROTSG_reserved2, ///< Placeholder, if we need specific level crossing sprites.
|
|
|
|
ROTSG_DEPOT, ///< Optional: Depot images
|
|
|
|
ROTSG_reserved3, ///< Placeholder, if we add road fences (for highways).
|
2023-11-01 21:19:31 +00:00
|
|
|
ROTSG_ROADSTOP, ///< Required: Bay stop surface
|
2022-12-26 20:06:21 +00:00
|
|
|
ROTSG_ONEWAY, ///< Optional: One-way indicator images
|
2019-04-06 06:46:15 +00:00
|
|
|
ROTSG_END,
|
|
|
|
};
|
|
|
|
|
|
|
|
/** List of road type labels. */
|
|
|
|
typedef std::vector<RoadTypeLabel> RoadTypeLabelList;
|
|
|
|
|
|
|
|
class RoadTypeInfo {
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* struct containing the sprites for the road GUI. @note only sprites referred to
|
|
|
|
* directly in the code are listed
|
|
|
|
*/
|
|
|
|
struct {
|
|
|
|
SpriteID build_x_road; ///< button for building single rail in X direction
|
|
|
|
SpriteID build_y_road; ///< button for building single rail in Y direction
|
|
|
|
SpriteID auto_road; ///< button for the autoroad construction
|
|
|
|
SpriteID build_depot; ///< button for building depots
|
|
|
|
SpriteID build_tunnel; ///< button for building a tunnel
|
|
|
|
SpriteID convert_road; ///< button for converting road types
|
|
|
|
} gui_sprites;
|
|
|
|
|
|
|
|
struct {
|
|
|
|
CursorID road_swne; ///< Cursor for building rail in X direction
|
|
|
|
CursorID road_nwse; ///< Cursor for building rail in Y direction
|
|
|
|
CursorID autoroad; ///< Cursor for autorail tool
|
|
|
|
CursorID depot; ///< Cursor for building a depot
|
|
|
|
CursorID tunnel; ///< Cursor for building a tunnel
|
|
|
|
SpriteID convert_road; ///< Cursor for converting road types
|
|
|
|
} cursor; ///< Cursors associated with the road type.
|
|
|
|
|
|
|
|
struct {
|
|
|
|
StringID name; ///< Name of this rail type.
|
|
|
|
StringID toolbar_caption; ///< Caption in the construction toolbar GUI for this rail type.
|
|
|
|
StringID menu_text; ///< Name of this rail type in the main toolbar dropdown.
|
|
|
|
StringID build_caption; ///< Caption of the build vehicle GUI for this rail type.
|
|
|
|
StringID replace_text; ///< Text used in the autoreplace GUI.
|
|
|
|
StringID new_engine; ///< Name of an engine for this type of road in the engine preview GUI.
|
|
|
|
|
|
|
|
StringID err_build_road; ///< Building a normal piece of road
|
|
|
|
StringID err_remove_road; ///< Removing a normal piece of road
|
|
|
|
StringID err_depot; ///< Building a depot
|
|
|
|
StringID err_build_station[2]; ///< Building a bus or truck station
|
|
|
|
StringID err_remove_station[2]; ///< Removing of a bus or truck station
|
|
|
|
StringID err_convert_road; ///< Converting a road type
|
|
|
|
|
|
|
|
StringID picker_title[2]; ///< Title for the station picker for bus or truck stations
|
|
|
|
StringID picker_tooltip[2]; ///< Tooltip for the station picker for bus or truck stations
|
|
|
|
} strings; ///< Strings associated with the rail type.
|
|
|
|
|
|
|
|
/** bitmask to the OTHER roadtypes on which a vehicle of THIS roadtype generates power */
|
|
|
|
RoadTypes powered_roadtypes;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Bit mask of road type flags
|
|
|
|
*/
|
|
|
|
RoadTypeFlags flags;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Cost multiplier for building this road type
|
|
|
|
*/
|
2023-05-08 17:01:06 +00:00
|
|
|
uint16_t cost_multiplier;
|
2019-04-06 06:46:15 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Cost multiplier for maintenance of this road type
|
|
|
|
*/
|
2023-05-08 17:01:06 +00:00
|
|
|
uint16_t maintenance_multiplier;
|
2019-04-06 06:46:15 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Maximum speed for vehicles travelling on this road type
|
|
|
|
*/
|
2023-05-08 17:01:06 +00:00
|
|
|
uint16_t max_speed;
|
2019-04-06 06:46:15 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Unique 32 bit road type identifier
|
|
|
|
*/
|
|
|
|
RoadTypeLabel label;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Road type labels this type provides in addition to the main label.
|
|
|
|
*/
|
|
|
|
RoadTypeLabelList alternate_labels;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Colour on mini-map
|
|
|
|
*/
|
|
|
|
byte map_colour;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Introduction date.
|
|
|
|
* When #INVALID_DATE or a vehicle using this roadtype gets introduced earlier,
|
|
|
|
* the vehicle's introduction date will be used instead for this roadtype.
|
|
|
|
* The introduction at this date is furthermore limited by the
|
|
|
|
* #introduction_required_types.
|
|
|
|
*/
|
2023-04-24 18:33:18 +00:00
|
|
|
TimerGameCalendar::Date introduction_date;
|
2019-04-06 06:46:15 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Bitmask of roadtypes that are required for this roadtype to be introduced
|
|
|
|
* at a given #introduction_date.
|
|
|
|
*/
|
|
|
|
RoadTypes introduction_required_roadtypes;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Bitmask of which other roadtypes are introduced when this roadtype is introduced.
|
|
|
|
*/
|
|
|
|
RoadTypes introduces_roadtypes;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The sorting order of this roadtype for the toolbar dropdown.
|
|
|
|
*/
|
|
|
|
byte sorting_order;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* NewGRF providing the Action3 for the roadtype. nullptr if not available.
|
|
|
|
*/
|
|
|
|
const GRFFile *grffile[ROTSG_END];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sprite groups for resolving sprites
|
|
|
|
*/
|
|
|
|
const SpriteGroup *group[ROTSG_END];
|
|
|
|
|
|
|
|
inline bool UsesOverlay() const
|
|
|
|
{
|
|
|
|
return this->group[ROTSG_GROUND] != nullptr;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
extern RoadTypes _roadtypes_type;
|
|
|
|
|
2024-01-06 11:19:27 +00:00
|
|
|
inline bool RoadTypeIsRoad(RoadType roadtype)
|
2019-04-06 06:46:15 +00:00
|
|
|
{
|
|
|
|
return !HasBit(_roadtypes_type, roadtype);
|
|
|
|
}
|
|
|
|
|
2024-01-06 11:19:27 +00:00
|
|
|
inline bool RoadTypeIsTram(RoadType roadtype)
|
2019-04-06 06:46:15 +00:00
|
|
|
{
|
|
|
|
return HasBit(_roadtypes_type, roadtype);
|
|
|
|
}
|
|
|
|
|
2024-01-06 11:19:27 +00:00
|
|
|
inline RoadTramType GetRoadTramType(RoadType roadtype)
|
2019-04-06 06:46:15 +00:00
|
|
|
{
|
|
|
|
return RoadTypeIsTram(roadtype) ? RTT_TRAM : RTT_ROAD;
|
|
|
|
}
|
|
|
|
|
2024-01-06 11:19:27 +00:00
|
|
|
inline RoadTramType OtherRoadTramType(RoadTramType rtt)
|
2019-04-06 06:46:15 +00:00
|
|
|
{
|
|
|
|
return rtt == RTT_ROAD ? RTT_TRAM : RTT_ROAD;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a pointer to the Roadtype information for a given roadtype
|
|
|
|
* @param roadtype the road type which the information is requested for
|
|
|
|
* @return The pointer to the RoadTypeInfo
|
|
|
|
*/
|
2024-01-06 11:19:27 +00:00
|
|
|
inline const RoadTypeInfo *GetRoadTypeInfo(RoadType roadtype)
|
2019-04-06 06:46:15 +00:00
|
|
|
{
|
|
|
|
extern RoadTypeInfo _roadtypes[ROADTYPE_END];
|
|
|
|
assert(roadtype < ROADTYPE_END);
|
|
|
|
return &_roadtypes[roadtype];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if an engine of the given RoadType got power on a tile with a given
|
|
|
|
* RoadType. This would normally just be an equality check, but for electrified
|
|
|
|
* roads (which also support non-electric vehicles).
|
|
|
|
* @return Whether the engine got power on this tile.
|
|
|
|
* @param enginetype The RoadType of the engine we are considering.
|
|
|
|
* @param tiletype The RoadType of the tile we are considering.
|
|
|
|
*/
|
2024-01-06 11:19:27 +00:00
|
|
|
inline bool HasPowerOnRoad(RoadType enginetype, RoadType tiletype)
|
2019-04-06 06:46:15 +00:00
|
|
|
{
|
|
|
|
return HasBit(GetRoadTypeInfo(enginetype)->powered_roadtypes, tiletype);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the cost of building the specified roadtype.
|
|
|
|
* @param roadtype The roadtype being built.
|
|
|
|
* @return The cost multiplier.
|
|
|
|
*/
|
2024-01-06 11:19:27 +00:00
|
|
|
inline Money RoadBuildCost(RoadType roadtype)
|
2019-04-06 06:46:15 +00:00
|
|
|
{
|
|
|
|
assert(roadtype < ROADTYPE_END);
|
|
|
|
return (_price[PR_BUILD_ROAD] * GetRoadTypeInfo(roadtype)->cost_multiplier) >> 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the cost of clearing the specified roadtype.
|
|
|
|
* @param roadtype The roadtype being removed.
|
|
|
|
* @return The cost.
|
|
|
|
*/
|
2024-01-06 11:19:27 +00:00
|
|
|
inline Money RoadClearCost(RoadType roadtype)
|
2019-04-06 06:46:15 +00:00
|
|
|
{
|
|
|
|
assert(roadtype < ROADTYPE_END);
|
|
|
|
|
|
|
|
/* Flat fee for removing road. */
|
|
|
|
if (RoadTypeIsRoad(roadtype)) return _price[PR_CLEAR_ROAD];
|
|
|
|
|
|
|
|
/* Clearing tram earns a little money, but also incurs the standard clear road cost,
|
|
|
|
* so no profit can be made. */
|
|
|
|
return _price[PR_CLEAR_ROAD] - RoadBuildCost(roadtype) * 3 / 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Calculates the cost of road conversion
|
|
|
|
* @param from The roadtype we are converting from
|
|
|
|
* @param to The roadtype we are converting to
|
|
|
|
* @return Cost per RoadBit
|
|
|
|
*/
|
2024-01-06 11:19:27 +00:00
|
|
|
inline Money RoadConvertCost(RoadType from, RoadType to)
|
2019-04-06 06:46:15 +00:00
|
|
|
{
|
|
|
|
/* Don't apply convert costs when converting to the same roadtype (ex. building a roadstop over existing road) */
|
|
|
|
if (from == to) return (Money)0;
|
|
|
|
|
|
|
|
/* Same cost as removing and then building. */
|
|
|
|
return RoadBuildCost(to) + RoadClearCost(from);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Test if road disallows level crossings
|
|
|
|
* @param roadtype The roadtype we are testing
|
|
|
|
* @return True iff the roadtype disallows level crossings
|
|
|
|
*/
|
2024-01-06 11:19:27 +00:00
|
|
|
inline bool RoadNoLevelCrossing(RoadType roadtype)
|
2019-04-06 06:46:15 +00:00
|
|
|
{
|
|
|
|
assert(roadtype < ROADTYPE_END);
|
|
|
|
return HasBit(GetRoadTypeInfo(roadtype)->flags, ROTF_NO_LEVEL_CROSSING);
|
|
|
|
}
|
|
|
|
|
|
|
|
RoadType GetRoadTypeByLabel(RoadTypeLabel label, bool allow_alternate_labels = true);
|
|
|
|
|
|
|
|
void ResetRoadTypes();
|
|
|
|
void InitRoadTypes();
|
|
|
|
RoadType AllocateRoadType(RoadTypeLabel label, RoadTramType rtt);
|
|
|
|
bool HasAnyRoadTypesAvail(CompanyID company, RoadTramType rtt);
|
|
|
|
|
|
|
|
extern std::vector<RoadType> _sorted_roadtypes;
|
|
|
|
extern RoadTypes _roadtypes_hidden_mask;
|
|
|
|
|
|
|
|
#endif /* ROAD_H */
|