mirror of https://github.com/OpenTTD/OpenTTD
Compare commits
9 Commits
ab7b01026e
...
0cf5ebc4ae
Author | SHA1 | Date |
---|---|---|
|
0cf5ebc4ae | |
|
6b6caa6fa8 | |
|
a48f491f09 | |
|
3ef5783bf9 | |
|
7f6b5d3103 | |
|
5a1a8adb3f | |
|
1000875f88 | |
|
1f5ae37e2c | |
|
3be979cc05 |
35
src/bridge.h
35
src/bridge.h
|
@ -37,6 +37,30 @@ constexpr uint SPRITES_PER_BRIDGE_PIECE = 32; ///< Number of sprites there are p
|
|||
|
||||
typedef uint BridgeType; ///< Bridge spec number.
|
||||
|
||||
/**
|
||||
* Actions that can be performed when the vehicle enters the depot.
|
||||
*/
|
||||
enum class BridgePiecePillarFlag : uint8_t {
|
||||
BPPF_CORNER_W = 1 << 0,
|
||||
BPPF_CORNER_S = 1 << 1,
|
||||
BPPF_CORNER_E = 1 << 2,
|
||||
BPPF_CORNER_N = 1 << 3,
|
||||
BPPF_ALL_CORNERS = 0xF,
|
||||
BPPF_EDGE_NE = 1 << 4,
|
||||
BPPF_EDGE_SE = 1 << 5,
|
||||
BPPF_EDGE_SW = 1 << 6,
|
||||
BPPF_EDGE_NW = 1 << 7,
|
||||
};
|
||||
using BridgePiecePillarFlags = EnumBitSet<BridgePiecePillarFlag, uint8_t>;
|
||||
|
||||
enum class BridgeSpecCtrlFlag : uint8_t{
|
||||
BSCF_CUSTOM_PILLAR_FLAGS,
|
||||
BSCF_INVALID_PILLAR_FLAGS,
|
||||
BSCF_NOT_AVAILABLE_TOWN,
|
||||
BSCF_NOT_AVAILABLE_AI_GS,
|
||||
};
|
||||
using BridgeSpecCtrlFlags = EnumBitSet<BridgeSpecCtrlFlag, uint8_t>;
|
||||
|
||||
/**
|
||||
* Struct containing information about a single bridge type
|
||||
*/
|
||||
|
@ -52,6 +76,8 @@ struct BridgeSpec {
|
|||
StringID transport_name[2]; ///< description of the bridge, when built for road or rail
|
||||
std::vector<std::vector<PalSpriteID>> sprite_table; ///< table of sprites for drawing the bridge
|
||||
uint8_t flags; ///< bit 0 set: disable drawing of far pillars.
|
||||
BridgeSpecCtrlFlags ctrl_flags; ///< control flags
|
||||
std::array<BridgePiecePillarFlags, 12> pillar_flags; ///< bridge pillar flags: 6 x pairs of x and y flags
|
||||
};
|
||||
|
||||
extern BridgeSpec _bridge[MAX_BRIDGES];
|
||||
|
@ -75,6 +101,15 @@ void DrawBridgeMiddle(const TileInfo *ti);
|
|||
CommandCost CheckBridgeAvailability(BridgeType bridge_type, uint bridge_len, DoCommandFlags flags = {});
|
||||
int CalcBridgeLenCostFactor(int x);
|
||||
|
||||
BridgePiecePillarFlags GetBridgeTilePillarFlags(TileIndex tile, TileIndex northern_bridge_end, TileIndex southern_bridge_end, BridgeType bridge_type, TransportType bridge_transport_type);
|
||||
|
||||
struct BridgePieceDebugInfo {
|
||||
BridgePieces piece;
|
||||
BridgePiecePillarFlags pillar_flags;
|
||||
uint pillar_index;
|
||||
};
|
||||
BridgePieceDebugInfo GetBridgePieceDebugInfo(TileIndex tile);
|
||||
|
||||
void ResetBridges();
|
||||
|
||||
#endif /* BRIDGE_H */
|
||||
|
|
|
@ -382,6 +382,8 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo
|
|||
StringID errmsg = INVALID_STRING_ID;
|
||||
CommandCost ret = Command<CMD_BUILD_BRIDGE>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_BRIDGE>()) | DoCommandFlag::QueryCost, end, start, transport_type, 0, road_rail_type);
|
||||
|
||||
const bool query_per_bridge_type = ret.Failed() && (ret.GetErrorMessage() == STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION || ret.GetErrorMessage() == STR_ERROR_BRIDGE_PILLARS_OBSTRUCT_STATION);
|
||||
|
||||
GUIBridgeList bl;
|
||||
if (ret.Failed()) {
|
||||
errmsg = ret.GetErrorMessage();
|
||||
|
@ -415,11 +417,13 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo
|
|||
}
|
||||
|
||||
bool any_available = false;
|
||||
StringID type_errmsg = INVALID_STRING_ID;
|
||||
CommandCost type_check;
|
||||
/* loop for all bridgetypes */
|
||||
for (BridgeType brd_type = 0; brd_type != MAX_BRIDGES; brd_type++) {
|
||||
type_check = CheckBridgeAvailability(brd_type, bridge_len);
|
||||
if (type_check.Succeeded()) {
|
||||
if (query_per_bridge_type && Command<CMD_BUILD_BRIDGE>::Do(CommandFlagsToDCFlags(GetCommandFlags<CMD_BUILD_BRIDGE>()) | DoCommandFlag::QueryCost, end, start, transport_type, brd_type, road_rail_type).Failed()) continue;
|
||||
/* bridge is accepted, add to list */
|
||||
BuildBridgeData &item = bl.emplace_back();
|
||||
item.index = brd_type;
|
||||
|
@ -428,10 +432,12 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo
|
|||
* bridge itself (not computed with DoCommandFlag::QueryCost) */
|
||||
item.cost = ret.GetCost() + (((int64_t)tot_bridgedata_len * _price[PR_BUILD_BRIDGE] * item.spec->price) >> 8) + infra_cost;
|
||||
any_available = true;
|
||||
} else if (type_check.GetErrorMessage() != INVALID_STRING_ID && !query_per_bridge_type) {
|
||||
type_errmsg = type_check.GetErrorMessage();
|
||||
}
|
||||
}
|
||||
/* give error cause if no bridges available here*/
|
||||
if (!any_available)
|
||||
if (!any_available && type_errmsg != INVALID_STRING_ID) errmsg = type_errmsg;
|
||||
{
|
||||
errmsg = type_check.GetErrorMessage();
|
||||
}
|
||||
|
|
|
@ -5002,6 +5002,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}O terren
|
|||
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Terreno inclinado na direção errada
|
||||
STR_ERROR_CAN_T_DO_THIS :{WHITE}Não é possível fazer isto...
|
||||
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}A construção precisa ser demolida primeiro
|
||||
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}... construção é protegida
|
||||
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Não é possível limpar esta área...
|
||||
STR_ERROR_SITE_UNSUITABLE :{WHITE}... local não adequado
|
||||
STR_ERROR_ALREADY_BUILT :{WHITE}... já construído
|
||||
|
|
|
@ -268,6 +268,7 @@ STR_UNITS_YEARS :{NUM}{NBSP}any{
|
|||
STR_UNITS_PERIODS :{NUM}{NBSP}període{P "" s}
|
||||
|
||||
STR_LIST_SEPARATOR :,{SPACE}
|
||||
STR_TRUNCATION_ELLIPSIS :...
|
||||
|
||||
# Common window strings
|
||||
STR_LIST_FILTER_TITLE :{BLACK}Filtre:
|
||||
|
@ -286,7 +287,7 @@ STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Tanca la
|
|||
STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Títol de la finestra: arrossegueu el títol per desplaçar la finestra.
|
||||
STR_TOOLTIP_SHADE :{BLACK}Ombra de la finestra: mostra només la barra de títol.
|
||||
STR_TOOLTIP_DEBUG :{BLACK}Mostra la informació de depuració NewGRF
|
||||
STR_TOOLTIP_DEFSIZE :{BLACK}Redimensiona la finestra a la mida predeterminada. Ctrl+Clic desa la mida actual com a predeterminada.
|
||||
STR_TOOLTIP_DEFSIZE :{BLACK}Redimensiona la finestra a la mida predeterminada. Amb Ctrl+Clic, es desa la mida actual com a predeterminada. Amb Ctrl+doble clic, es restableix als valors per defecte.
|
||||
STR_TOOLTIP_STICKY :{BLACK}Marca aquesta finestra com a no eliminable per la tecla «Tanca totes les finestres». Ctrl+Clic per desar també l'estat predeterminat.
|
||||
STR_TOOLTIP_RESIZE :{BLACK}Clica i arrossega per redimensionar aquesta finestra
|
||||
STR_TOOLTIP_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Commuta entre la mida gran i petita de la finestra
|
||||
|
@ -1108,7 +1109,7 @@ STR_GAME_OPTIONS_BASE_MUSIC_DESCRIPTION_TOOLTIP :Informació add
|
|||
STR_GAME_OPTIONS_ONLINE_CONTENT :Descarrega contingut
|
||||
STR_GAME_OPTIONS_ONLINE_CONTENT_TOOLTIP :Comprova si hi ha continguts nous o actualitzats per a descarregar.
|
||||
|
||||
STR_GAME_OPTIONS_SOCIAL_PLUGINS_NONE :{LTBLUE}(no s'han instal·lat complements per a interactuar amb plataformes socials)
|
||||
STR_GAME_OPTIONS_SOCIAL_PLUGINS_NONE :(no s'han instal·lat complements per a interactuar amb plataformes socials)
|
||||
|
||||
STR_GAME_OPTIONS_SOCIAL_PLUGIN_TITLE :{STRING} ({STRING})
|
||||
STR_GAME_OPTIONS_SOCIAL_PLUGIN_PLATFORM :Plataforma:
|
||||
|
@ -1226,7 +1227,7 @@ STR_CITY_APPROVAL_PERMISSIVE :Permissiva (les
|
|||
STR_WARNING_NO_SUITABLE_AI :{WHITE}No hi ha cap IA disponible...{}Podeu descarregar-ne a través del «Contingut en línia».
|
||||
|
||||
# Settings tree in the Game Options window
|
||||
STR_CONFIG_SETTING_FILTER_TITLE :{G=Masculin}{BLACK}Filtre:
|
||||
STR_CONFIG_SETTING_FILTER_TITLE :{G=Masculin}Filtre:
|
||||
STR_CONFIG_SETTING_EXPAND_ALL :Desplega-ho tot
|
||||
STR_CONFIG_SETTING_COLLAPSE_ALL :Plega-ho tot
|
||||
STR_CONFIG_SETTING_RESET_ALL :Restableix tots els valors
|
||||
|
@ -1302,6 +1303,9 @@ STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Tipus d'interè
|
|||
STR_CONFIG_SETTING_RUNNING_COSTS :Costos d'utilització: {STRING}
|
||||
STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :Fixa el nivell de manteniment i els costos d'utilització dels vehicles i infraestructures
|
||||
###length 3
|
||||
STR_CONFIG_SETTING_RUNNING_COSTS_LOW :Baix
|
||||
STR_CONFIG_SETTING_RUNNING_COSTS_MEDIUM :Mitjà
|
||||
STR_CONFIG_SETTING_RUNNING_COSTS_HIGH :Alt
|
||||
|
||||
STR_CONFIG_SETTING_CONSTRUCTION_SPEED :Ritme de construcció: {STRING}
|
||||
STR_CONFIG_SETTING_CONSTRUCTION_SPEED_HELPTEXT :Limita la quantitat d'accions de construcció per part de les IA
|
||||
|
@ -1324,6 +1328,9 @@ STR_CONFIG_SETTING_SUBSIDY_DURATION_DISABLED :Sense subsidis
|
|||
STR_CONFIG_SETTING_CONSTRUCTION_COSTS :Costos de construcció: {STRING}
|
||||
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HELPTEXT :Fixa el nivell de construcció i els preus de compra
|
||||
###length 3
|
||||
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_LOW :Baix
|
||||
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_MEDIUM :Mitjà
|
||||
STR_CONFIG_SETTING_CONSTRUCTION_COSTS_HIGH :Alt
|
||||
|
||||
STR_CONFIG_SETTING_RECESSIONS :Recessions: {STRING}
|
||||
STR_CONFIG_SETTING_RECESSIONS_HELPTEXT :Si està activat, poden haver recessions periòdicament. Durant una recessió, tota la producció és significativament més baixa, tornant al nivell previ quan s'acabi el període de recessió.
|
||||
|
@ -2079,9 +2086,9 @@ STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :La classe de c
|
|||
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Mode de distribució per altres classes de càrrega: {STRING}
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"Asimètric" vol dir que quantitats arbitràries de càrrega poden ser enviades en qualsevol sentit. "Manual" significa que no s'aplicarà cap distribució automàtica a aquestes càrregues.
|
||||
###length 3
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manual
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :asimètric
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_SYMMETRIC :simètric
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :Manual
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :Asimètric
|
||||
STR_CONFIG_SETTING_DISTRIBUTION_SYMMETRIC :Simètric
|
||||
|
||||
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :Precisió de la distribució: {STRING}
|
||||
STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :Com més alt el valor indicat, més temps de processador requerirà el càlcul del graf de distribució. Si requereix massa temps podeu notar ralentització. Si indiqueu un valor baix, però, la distribució serà poc acurada, i us podeu trobar que la càrrega no és enviada als llocs que espereu.
|
||||
|
@ -2331,16 +2338,19 @@ STR_FACE_SIMPLE_TOOLTIP :{BLACK}Selecci
|
|||
STR_FACE_LOAD :{BLACK}Carrega
|
||||
STR_FACE_LOAD_TOOLTIP :{BLACK}Carrega la cara preferida
|
||||
STR_FACE_LOAD_DONE :{WHITE}S'ha carregat la cara personalitzada des de l'arxiu de configuració de l'OpenTTD.
|
||||
STR_FACE_FACECODE :{BLACK}Número de la cara
|
||||
STR_FACE_FACECODE_TOOLTIP :{BLACK}Veure i/o assigna el número de la cara del president
|
||||
STR_FACE_FACECODE_CAPTION :{WHITE}Veure i/o assigna el número de la cara del president
|
||||
STR_FACE_FACECODE_SET :{WHITE}El número de la nova cara ha estat assignat
|
||||
STR_FACE_FACECODE_ERR :{WHITE}No s'ha pogut assignar el número de cara del president - ha de ser un nombre entre 0 i 4,294,967,295!
|
||||
STR_FACE_FACECODE :{BLACK}Codi de la cara
|
||||
STR_FACE_FACECODE_TOOLTIP :{BLACK}Veure i/o assigna el codi de la cara del president
|
||||
STR_FACE_FACECODE_CAPTION :{WHITE}Veure i/o assigna el codi de la cara del president
|
||||
STR_FACE_FACECODE_SET :{WHITE}S'ha assignat el codi de la nova cara del president.
|
||||
STR_FACE_FACECODE_ERR :{WHITE}No s'ha pogut assignar el codi de cara del president - ha de ser una etiqueta i nombre vàlids.
|
||||
STR_FACE_SAVE :{BLACK}Desa
|
||||
STR_FACE_SAVE_TOOLTIP :{BLACK}Desa la cara preferida
|
||||
STR_FACE_SAVE_DONE :{WHITE}Es desarà aquesta cara personalitzada a l'arxiu de configuració de l'OpenTTD.
|
||||
STR_FACE_SETTING_TOGGLE :{STRING} {ORANGE}{STRING}
|
||||
STR_FACE_SETTING_NUMERIC :{STRING} {ORANGE}{NUM} / {NUM}
|
||||
STR_FACE_YES :Sí
|
||||
STR_FACE_NO :No
|
||||
STR_FACE_STYLE :Estil:
|
||||
STR_FACE_HAIR :Cabell:
|
||||
STR_FACE_EYEBROWS :Celles:
|
||||
STR_FACE_EYECOLOUR :Color dels ulls:
|
||||
|
@ -2813,6 +2823,10 @@ STR_PICKER_MODE_USED_TOOLTIP :Commuta entre m
|
|||
STR_PICKER_MODE_SAVED :Desats
|
||||
STR_PICKER_MODE_SAVED_TOOLTIP :Commuta entre mostrar tots o bé només els elements desats.
|
||||
|
||||
STR_PICKER_PREVIEW_SHRINK :‒
|
||||
STR_PICKER_PREVIEW_SHRINK_TOOLTIP :Redueix l'alçària de les vistes prèvies. Amb Ctrl+clic, es redueix fins al mínim.
|
||||
STR_PICKER_PREVIEW_EXPAND :+
|
||||
STR_PICKER_PREVIEW_EXPAND_TOOLTIP :Augmenta l'alçària de les vistes prèvies. Amb Ctrl+clic, s'augmenta fins al màxim.
|
||||
|
||||
STR_PICKER_STATION_CLASS_TOOLTIP :Trieu quina classe d'estació voleu veure.
|
||||
STR_PICKER_STATION_TYPE_TOOLTIP :Trieu quin tipus d'estació voleu construir. Amb Ctrl+clic, s'afegeix o es trau l'element de la llista de desats.
|
||||
|
@ -3053,6 +3067,11 @@ STR_FOUND_TOWN_INITIAL_SIZE_TOOLTIP :{BLACK}Seleccio
|
|||
STR_FOUND_TOWN_CITY :{BLACK}Ciutat
|
||||
STR_FOUND_TOWN_CITY_TOOLTIP :{BLACK}Les ciutats creixen més ràpid que els pobles{}Depenent de la configuració, són més grans quan es funden
|
||||
|
||||
STR_FOUND_TOWN_EXPAND_MODE :{YELLOW}Expansió de la població:
|
||||
STR_FOUND_TOWN_EXPAND_BUILDINGS :Edificis
|
||||
STR_FOUND_TOWN_EXPAND_BUILDINGS_TOOLTIP :Augmenta el nombre d'edificis de les poblacions.
|
||||
STR_FOUND_TOWN_EXPAND_ROADS :Carreteres
|
||||
STR_FOUND_TOWN_EXPAND_ROADS_TOOLTIP :Augmenta el nombre de carreteres de la població.
|
||||
|
||||
STR_FOUND_TOWN_ROAD_LAYOUT :{YELLOW}Disposició de les carreteres de la població:
|
||||
STR_FOUND_TOWN_SELECT_LAYOUT_TOOLTIP :{BLACK}Selecciona la disposició de les carreteres utilitzades per a aquesta població
|
||||
|
@ -3677,6 +3696,10 @@ STR_TOWN_VIEW_RENAME_TOOLTIP :{BLACK}Canvia e
|
|||
|
||||
STR_TOWN_VIEW_EXPAND_BUTTON :{BLACK}Eixampla
|
||||
STR_TOWN_VIEW_EXPAND_TOOLTIP :{BLACK}Incrementa la mida de la població
|
||||
STR_TOWN_VIEW_EXPAND_BUILDINGS_BUTTON :{BLACK}Expandeix els edificis
|
||||
STR_TOWN_VIEW_EXPAND_BUILDINGS_TOOLTIP :{BLACK}Augmenta el nombre d'edificis de la població.
|
||||
STR_TOWN_VIEW_EXPAND_ROADS_BUTTON :{BLACK}Expandeix les carreteres
|
||||
STR_TOWN_VIEW_EXPAND_ROADS_TOOLTIP :{BLACK}Augmenta el nombre de carreteres de la població.
|
||||
STR_TOWN_VIEW_DELETE_BUTTON :{BLACK}Esborra
|
||||
STR_TOWN_VIEW_DELETE_TOOLTIP :{BLACK}Esborra totalment aquesta població
|
||||
|
||||
|
@ -4415,10 +4438,10 @@ STR_VEHICLE_VIEW_SHIP_ORDERS_TOOLTIP :{BLACK}Mostra l
|
|||
STR_VEHICLE_VIEW_AIRCRAFT_ORDERS_TOOLTIP :{BLACK}Mostra les ordres de l'avió. Ctrl+Clic per mostrar l'horari de l'avió
|
||||
|
||||
###length VEHICLE_TYPES
|
||||
STR_VEHICLE_VIEW_TRAIN_SHOW_DETAILS_TOOLTIP :{BLACK}Mostra els detalls del tren
|
||||
STR_VEHICLE_VIEW_ROAD_VEHICLE_SHOW_DETAILS_TOOLTIP :{BLACK}Mostra els detalls del vehicle
|
||||
STR_VEHICLE_VIEW_SHIP_SHOW_DETAILS_TOOLTIP :{BLACK}Mostra els detalls del vaixell
|
||||
STR_VEHICLE_VIEW_AIRCRAFT_SHOW_DETAILS_TOOLTIP :{BLACK}Mostra els detalls de l'avió
|
||||
STR_VEHICLE_VIEW_TRAIN_SHOW_DETAILS_TOOLTIP :{BLACK}Mostra els detalls del tren. Amb Ctrl+clic, es mostra el grup del tren.
|
||||
STR_VEHICLE_VIEW_ROAD_VEHICLE_SHOW_DETAILS_TOOLTIP :{BLACK}Mostra els detalls del vehicle. Amb Ctrl+clic, es mostra el grup del vehicle.
|
||||
STR_VEHICLE_VIEW_SHIP_SHOW_DETAILS_TOOLTIP :{BLACK}Mostra els detalls del vaixell. Amb Ctrl+clic, es mostra el grup del vaixell.
|
||||
STR_VEHICLE_VIEW_AIRCRAFT_SHOW_DETAILS_TOOLTIP :{BLACK}Mostra els detalls de l'aeronau. Amb Ctrl+clic, es mostra el grup de l'aeronau.
|
||||
|
||||
###length VEHICLE_TYPES
|
||||
STR_VEHICLE_VIEW_TRAIN_STATUS_START_STOP_TOOLTIP :{BLACK}Acció actual del tren - Feu clic per parar-lo o engegar-lo.
|
||||
|
@ -4742,14 +4765,15 @@ STR_TIMETABLE_TOOLTIP :{BLACK}Horari -
|
|||
STR_TIMETABLE_NO_TRAVEL :Sense viatge
|
||||
STR_TIMETABLE_NOT_TIMETABLEABLE :Viatge (automàtic; programat per la següent ordre manual)
|
||||
STR_TIMETABLE_TRAVEL_NOT_TIMETABLED :Viatge (fora d'horari)
|
||||
STR_TIMETABLE_TRAVEL_NOT_TIMETABLED_SPEED :Viatja (sense horari) com a molt a {VELOCITY}
|
||||
STR_TIMETABLE_TRAVEL_FOR :Viatge a {STRING}
|
||||
STR_TIMETABLE_TRAVEL_FOR_SPEED :Viatja durant {STRING} com a molt a {VELOCITY}
|
||||
STR_TIMETABLE_TRAVEL_FOR_ESTIMATED :Viatja (durant {STRING}, sense horari)
|
||||
STR_TIMETABLE_TRAVEL_FOR_SPEED_ESTIMATED :Viatja (durant {STRING}, sense horari) com a molt a {VELOCITY}
|
||||
STR_TIMETABLE_STAY_FOR_ESTIMATED :{SPACE}(quedar-s'hi durant {STRING}, sense horari)
|
||||
STR_TIMETABLE_AND_TRAVEL_FOR_ESTIMATED :{SPACE}(viatja durant {STRING}, sense horari)
|
||||
STR_TIMETABLE_STAY_FOR :i estigues {STRING}
|
||||
STR_TIMETABLE_AND_TRAVEL_FOR :i viatge per {STRING}
|
||||
STR_TIMETABLE_STAY_FOR :{SPACE}i estigues {STRING}
|
||||
STR_TIMETABLE_AND_TRAVEL_FOR :{SPACE}i viatja durant {STRING}
|
||||
|
||||
STR_TIMETABLE_APPROX_TIME :{BLACK}L'horari trigara aproximadament {STRING} a completar-se.
|
||||
STR_TIMETABLE_TOTAL_TIME :{BLACK}L'horari tardarà {STRING} a complir-se
|
||||
|
@ -5897,3 +5921,11 @@ STR_SHIP :{BLACK}{SHIP}
|
|||
STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY})
|
||||
|
||||
STR_BADGE_NAME_LIST :{STRING}: {GOLD}{STRING}
|
||||
STR_BADGE_CONFIG_MENU_TOOLTIP :Obre la configuració d'insígnies
|
||||
STR_BADGE_CONFIG_RESET :Restableix
|
||||
STR_BADGE_CONFIG_ICONS :{WHITE}Icones d'insígnies
|
||||
STR_BADGE_CONFIG_FILTERS :{WHITE}Filtres d'insígnies
|
||||
STR_BADGE_CONFIG_PREVIEW :Imatge de previsualització
|
||||
STR_BADGE_CONFIG_NAME :Nom
|
||||
STR_BADGE_FILTER_ANY_LABEL :Qualsevol {STRING}
|
||||
STR_BADGE_FILTER_IS_LABEL :{STRING} és {STRING}
|
||||
|
|
|
@ -5242,6 +5242,8 @@ STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Start an
|
|||
STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... ends of bridge must both be on land
|
||||
STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... bridge too long
|
||||
STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Bridge would end out of the map
|
||||
STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION :{WHITE}Bridge is too low for station
|
||||
STR_ERROR_BRIDGE_PILLARS_OBSTRUCT_STATION :{WHITE}Bridge pillars obstruct station
|
||||
|
||||
# Tunnel related errors
|
||||
STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Can't build tunnel here...
|
||||
|
|
|
@ -5001,6 +5001,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}Tarvitaa
|
|||
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Maa viettää väärään suuntaan.
|
||||
STR_ERROR_CAN_T_DO_THIS :{WHITE}Ei onnistu...
|
||||
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Rakennus täytyy purkaa ensin.
|
||||
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}… rakennus on suojattu
|
||||
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Aluetta ei voi tyhjentää...
|
||||
STR_ERROR_SITE_UNSUITABLE :{WHITE}... maasto on sopimaton
|
||||
STR_ERROR_ALREADY_BUILT :{WHITE}... se on jo rakennettu
|
||||
|
|
|
@ -5102,6 +5102,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}Απαι
|
|||
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Το έδαφος έχει λάθος κλίση
|
||||
STR_ERROR_CAN_T_DO_THIS :{WHITE}Αυτό δεν γίνεται...
|
||||
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Το κτίριο πρέπει πρώτα να κατεδαφιστεί
|
||||
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}... το κτίριο προστατεύεται
|
||||
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Είναι αδύνατο να καθαριστεί αυτή η περιοχή...
|
||||
STR_ERROR_SITE_UNSUITABLE :{WHITE}... ακατάλληλη περιοχή
|
||||
STR_ERROR_ALREADY_BUILT :{WHITE}... ήδη κατασκευασμένο
|
||||
|
|
|
@ -330,6 +330,7 @@ STR_UNITS_YEARS :{NUM}{NBSP}év
|
|||
STR_UNITS_PERIODS :{NUM}{NBSP}időszak
|
||||
|
||||
STR_LIST_SEPARATOR :,{SPACE}
|
||||
STR_TRUNCATION_ELLIPSIS :...
|
||||
|
||||
# Common window strings
|
||||
STR_LIST_FILTER_TITLE :{BLACK}Szűrő kifejezés:
|
||||
|
|
|
@ -5387,6 +5387,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}Wymagany
|
|||
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Teren pochylony w złym kierunku
|
||||
STR_ERROR_CAN_T_DO_THIS :{WHITE}Nie można tego zrobić...
|
||||
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Należy najpierw zburzyć budynek
|
||||
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}... budynek jest chroniony
|
||||
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Nie można wyczyścić terenu...
|
||||
STR_ERROR_SITE_UNSUITABLE :{WHITE}... nieodpowiednie miejsce
|
||||
STR_ERROR_ALREADY_BUILT :{WHITE}... już zbudowano
|
||||
|
|
|
@ -647,7 +647,7 @@ STR_GRAPH_KEY_COMPANY_SELECTION_TOOLTIP :{BLACK}Alternar
|
|||
|
||||
# Company league window
|
||||
STR_COMPANY_LEAGUE_TABLE_CAPTION :{WHITE}Classificação de Empresas
|
||||
STR_COMPANY_LEAGUE_COMPANY_NAME :{ORANGE}{COMPANY} {BLACK}{COMPANY_NUM} '{STRING}'
|
||||
STR_COMPANY_LEAGUE_COMPANY_NAME :{ORANGE}{COMPANY} {BLACK}{COMPANY_NUM} "{STRING}"
|
||||
STR_COMPANY_LEAGUE_COMPANY_RANK :{YELLOW}#{NUM}
|
||||
STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_ENGINEER :Engenheiro
|
||||
STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_TRAFFIC_MANAGER :Gestor de Tráfego
|
||||
|
@ -5002,6 +5002,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}É neces
|
|||
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Terreno inclinado na direcção incorrecta
|
||||
STR_ERROR_CAN_T_DO_THIS :{WHITE}Não é possível fazer isto...
|
||||
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}O edifício deve ser demolido primeiro
|
||||
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}... o edifício está protegido
|
||||
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Não é possível limpar esta área...
|
||||
STR_ERROR_SITE_UNSUITABLE :{WHITE}... sítio inadequado
|
||||
STR_ERROR_ALREADY_BUILT :{WHITE}... já está construído
|
||||
|
|
|
@ -5188,6 +5188,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}Необ
|
|||
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Неверный уклон земли
|
||||
STR_ERROR_CAN_T_DO_THIS :{WHITE}Это невозможно...
|
||||
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}Сначала снесите здания
|
||||
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}... это здание защищено от изменений
|
||||
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}Невозможно расчистить данный участок...
|
||||
STR_ERROR_SITE_UNSUITABLE :{WHITE}... неподходящее место
|
||||
STR_ERROR_ALREADY_BUILT :{WHITE}... уже построено
|
||||
|
|
|
@ -5001,6 +5001,7 @@ STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}需要
|
|||
STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}地面斜坡方向不對
|
||||
STR_ERROR_CAN_T_DO_THIS :{WHITE}不能執行以下動作...
|
||||
STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}必須先摧毀建築物
|
||||
STR_ERROR_BUILDING_IS_PROTECTED :{WHITE}……建築物受到保護
|
||||
STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}不能清除這個地段...
|
||||
STR_ERROR_SITE_UNSUITABLE :{WHITE}... 地點不適合
|
||||
STR_ERROR_ALREADY_BUILT :{WHITE}……經已建成
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#ifndef NEWGRF_ROADSTATION_H
|
||||
#define NEWGRF_ROADSTATION_H
|
||||
|
||||
#include "bridge.h"
|
||||
#include "newgrf_animation_type.h"
|
||||
#include "newgrf_spritegroup.h"
|
||||
#include "newgrf_badge_type.h"
|
||||
|
@ -71,6 +72,12 @@ enum class RoadStopSpecFlag : uint8_t {
|
|||
};
|
||||
using RoadStopSpecFlags = EnumBitSet<RoadStopSpecFlag, uint8_t>;
|
||||
|
||||
enum class RoadStopSpecIntlFlag : uint8_t {
|
||||
BridgeHeightsSet, ///< bridge_height[6] is set.
|
||||
BridgeDisallowedPillarsSet, ///< bridge_disallowed_pillars[6] is set.
|
||||
};
|
||||
using RoadStopSpecIntlFlags = EnumBitSet<RoadStopSpecIntlFlag, uint8_t>;
|
||||
|
||||
enum RoadStopView : uint8_t {
|
||||
RSV_BAY_NE = 0, ///< Bay road stop, facing Northeast
|
||||
RSV_BAY_SE = 1, ///< Bay road stop, facing Southeast
|
||||
|
@ -133,17 +140,20 @@ struct RoadStopSpec : NewGRFSpecBase<RoadStopClassID> {
|
|||
RoadStopDrawModes draw_mode = {RoadStopDrawMode::Road, RoadStopDrawMode::Overlay};
|
||||
RoadStopCallbackMasks callback_mask{};
|
||||
RoadStopSpecFlags flags{};
|
||||
RoadStopSpecIntlFlags internal_flags{};
|
||||
|
||||
CargoTypes cargo_triggers = 0; ///< Bitmask of cargo types which cause trigger re-randomizing
|
||||
|
||||
AnimationInfo<StationAnimationTriggers> animation;
|
||||
|
||||
uint8_t bridge_height[6]; ///< Minimum height for a bridge above, 0 for none
|
||||
uint8_t bridge_disallowed_pillars[6]; ///< Disallowed pillar flags for a bridge above
|
||||
BridgePiecePillarFlags bridge_disallowed_pillars[6]; ///< Disallowed pillar flags for a bridge above
|
||||
|
||||
uint8_t build_cost_multiplier = 16; ///< Build cost multiplier per tile.
|
||||
uint8_t clear_cost_multiplier = 16; ///< Clear cost multiplier per tile.
|
||||
|
||||
uint8_t height; ///< The height of this structure, in heightlevels; max MAX_TILE_HEIGHT.
|
||||
|
||||
std::vector<BadgeID> badges;
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#ifndef NEWGRF_STATION_H
|
||||
#define NEWGRF_STATION_H
|
||||
|
||||
#include "bridge.h"
|
||||
#include "core/enum_type.hpp"
|
||||
#include "newgrf_animation_type.h"
|
||||
#include "newgrf_badge_type.h"
|
||||
|
@ -118,6 +119,12 @@ enum class StationSpecFlag : uint8_t {
|
|||
};
|
||||
using StationSpecFlags = EnumBitSet<StationSpecFlag, uint8_t>;
|
||||
|
||||
enum class StationSpecIntlFlag : uint8_t {
|
||||
BridgeHeightsSet, ///< bridge_height[8] is set.
|
||||
BridgeDisallowedPillarsSet, ///< bridge_disallowed_pillars[8] is set.
|
||||
};
|
||||
using StationSpecIntlFlags = EnumBitSet<StationSpecIntlFlag, uint8_t>;
|
||||
|
||||
/** Station specification. */
|
||||
struct StationSpec : NewGRFSpecBase<StationClassID> {
|
||||
StationSpec() : name(0),
|
||||
|
@ -162,6 +169,12 @@ struct StationSpec : NewGRFSpecBase<StationClassID> {
|
|||
|
||||
StationSpecFlags flags; ///< Bitmask of flags, bit 0: use different sprite set; bit 1: divide cargo about by station size
|
||||
|
||||
struct BridgeAboveFlags {
|
||||
uint8_t height = UINT8_MAX; ///< Minimum height for a bridge above, 0 for none
|
||||
BridgePiecePillarFlags disallowed_pillars = {}; ///< Disallowed pillar flags for a bridge above
|
||||
};
|
||||
std::vector<BridgeAboveFlags> bridge_above_flags; ///< List of bridge above flags.
|
||||
|
||||
enum class TileFlag : uint8_t {
|
||||
Pylons = 0, ///< Tile should contain catenary pylons.
|
||||
NoWires = 1, ///< Tile should NOT contain catenary wires.
|
||||
|
@ -172,10 +185,18 @@ struct StationSpec : NewGRFSpecBase<StationClassID> {
|
|||
|
||||
AnimationInfo<StationAnimationTriggers> animation;
|
||||
|
||||
StationSpecIntlFlags internal_flags{}; ///< Bitmask of internal spec flags
|
||||
|
||||
/** Custom platform layouts, keyed by platform and length combined. */
|
||||
std::unordered_map<uint16_t, std::vector<uint8_t>> layouts;
|
||||
|
||||
std::vector<BadgeID> badges;
|
||||
|
||||
BridgeAboveFlags GetBridgeAboveFlags(uint gfx) const
|
||||
{
|
||||
if (gfx < this->bridge_above_flags.size()) return this->bridge_above_flags[gfx];
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
/** Class containing information relating to station classes. */
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
/** @file station_cmd.cpp Handling of station tiles. */
|
||||
|
||||
#include "core/enum_type.hpp"
|
||||
#include "stdafx.h"
|
||||
#include "core/flatset_type.hpp"
|
||||
#include "aircraft.h"
|
||||
|
@ -949,125 +950,6 @@ static CommandCost CheckFlatLandRailStation(TileIndex tile_cur, TileIndex north_
|
|||
return cost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a road stop can be built at the given tile.
|
||||
* @param cur_tile Tile to check.
|
||||
* @param allowed_z Height allowed for the tile. If allowed_z is negative, it will be set to the height of this tile.
|
||||
* @param flags Operation to perform.
|
||||
* @param invalid_dirs Prohibited directions (set of DiagDirections).
|
||||
* @param is_drive_through True if trying to build a drive-through station.
|
||||
* @param station_type Station type (bus, truck or road waypoint).
|
||||
* @param axis Axis of a drive-through road stop.
|
||||
* @param station StationID to be queried and returned if available.
|
||||
* @param rt Road type to build, may be INVALID_ROADTYPE if an existing road is required.
|
||||
* @return The cost in case of success, or an error code if it failed.
|
||||
*/
|
||||
static CommandCost CheckFlatLandRoadStop(TileIndex cur_tile, int &allowed_z, DoCommandFlags flags, DiagDirections invalid_dirs, bool is_drive_through, StationType station_type, Axis axis, StationID *station, RoadType rt)
|
||||
{
|
||||
CommandCost cost(EXPENSES_CONSTRUCTION);
|
||||
|
||||
CommandCost ret = CheckBuildableTile(cur_tile, invalid_dirs, allowed_z, !is_drive_through);
|
||||
if (ret.Failed()) return ret;
|
||||
cost.AddCost(ret.GetCost());
|
||||
|
||||
/* If station is set, then we have special handling to allow building on top of already existing stations.
|
||||
* Station points to StationID::Invalid() if we can build on any station.
|
||||
* Or it points to a station if we're only allowed to build on exactly that station. */
|
||||
if (station != nullptr && IsTileType(cur_tile, MP_STATION)) {
|
||||
if (!IsAnyRoadStop(cur_tile)) {
|
||||
return ClearTile_Station(cur_tile, DoCommandFlag::Auto); // Get error message.
|
||||
} else {
|
||||
if (station_type != GetStationType(cur_tile) ||
|
||||
is_drive_through != IsDriveThroughStopTile(cur_tile)) {
|
||||
return ClearTile_Station(cur_tile, DoCommandFlag::Auto); // Get error message.
|
||||
}
|
||||
/* Drive-through station in the wrong direction. */
|
||||
if (is_drive_through && IsDriveThroughStopTile(cur_tile) && GetDriveThroughStopAxis(cur_tile) != axis) {
|
||||
return CommandCost(STR_ERROR_DRIVE_THROUGH_DIRECTION);
|
||||
}
|
||||
StationID st = GetStationIndex(cur_tile);
|
||||
if (*station == StationID::Invalid()) {
|
||||
*station = st;
|
||||
} else if (*station != st) {
|
||||
return CommandCost(STR_ERROR_ADJOINS_MORE_THAN_ONE_EXISTING);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bool build_over_road = is_drive_through && IsNormalRoadTile(cur_tile);
|
||||
/* Road bits in the wrong direction. */
|
||||
RoadBits rb = IsNormalRoadTile(cur_tile) ? GetAllRoadBits(cur_tile) : ROAD_NONE;
|
||||
if (build_over_road && (rb & (axis == AXIS_X ? ROAD_Y : ROAD_X)) != 0) {
|
||||
/* Someone was pedantic and *NEEDED* three fracking different error messages. */
|
||||
switch (CountBits(rb)) {
|
||||
case 1:
|
||||
return CommandCost(STR_ERROR_DRIVE_THROUGH_DIRECTION);
|
||||
|
||||
case 2:
|
||||
if (rb == ROAD_X || rb == ROAD_Y) return CommandCost(STR_ERROR_DRIVE_THROUGH_DIRECTION);
|
||||
return CommandCost(STR_ERROR_DRIVE_THROUGH_CORNER);
|
||||
|
||||
default: // 3 or 4
|
||||
return CommandCost(STR_ERROR_DRIVE_THROUGH_JUNCTION);
|
||||
}
|
||||
}
|
||||
|
||||
if (build_over_road) {
|
||||
/* There is a road, check if we can build road+tram stop over it. */
|
||||
RoadType road_rt = GetRoadType(cur_tile, RTT_ROAD);
|
||||
if (road_rt != INVALID_ROADTYPE) {
|
||||
Owner road_owner = GetRoadOwner(cur_tile, RTT_ROAD);
|
||||
if (road_owner == OWNER_TOWN) {
|
||||
if (!_settings_game.construction.road_stop_on_town_road) return CommandCost(STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD);
|
||||
} else if (!_settings_game.construction.road_stop_on_competitor_road && road_owner != OWNER_NONE) {
|
||||
ret = CheckOwnership(road_owner);
|
||||
if (ret.Failed()) return ret;
|
||||
}
|
||||
uint num_pieces = CountBits(GetRoadBits(cur_tile, RTT_ROAD));
|
||||
|
||||
if (rt != INVALID_ROADTYPE && RoadTypeIsRoad(rt) && !HasPowerOnRoad(rt, road_rt)) return CommandCost(STR_ERROR_NO_SUITABLE_ROAD);
|
||||
|
||||
if (GetDisallowedRoadDirections(cur_tile) != DRD_NONE && road_owner != OWNER_TOWN) {
|
||||
ret = CheckOwnership(road_owner);
|
||||
if (ret.Failed()) return ret;
|
||||
}
|
||||
|
||||
cost.AddCost(RoadBuildCost(road_rt) * (2 - num_pieces));
|
||||
} else if (rt != INVALID_ROADTYPE && RoadTypeIsRoad(rt)) {
|
||||
cost.AddCost(RoadBuildCost(rt) * 2);
|
||||
}
|
||||
|
||||
/* There is a tram, check if we can build road+tram stop over it. */
|
||||
RoadType tram_rt = GetRoadType(cur_tile, RTT_TRAM);
|
||||
if (tram_rt != INVALID_ROADTYPE) {
|
||||
Owner tram_owner = GetRoadOwner(cur_tile, RTT_TRAM);
|
||||
if (Company::IsValidID(tram_owner) &&
|
||||
(!_settings_game.construction.road_stop_on_competitor_road ||
|
||||
/* Disallow breaking end-of-line of someone else
|
||||
* so trams can still reverse on this tile. */
|
||||
HasExactlyOneBit(GetRoadBits(cur_tile, RTT_TRAM)))) {
|
||||
ret = CheckOwnership(tram_owner);
|
||||
if (ret.Failed()) return ret;
|
||||
}
|
||||
uint num_pieces = CountBits(GetRoadBits(cur_tile, RTT_TRAM));
|
||||
|
||||
if (rt != INVALID_ROADTYPE && RoadTypeIsTram(rt) && !HasPowerOnRoad(rt, tram_rt)) return CommandCost(STR_ERROR_NO_SUITABLE_ROAD);
|
||||
|
||||
cost.AddCost(RoadBuildCost(tram_rt) * (2 - num_pieces));
|
||||
} else if (rt != INVALID_ROADTYPE && RoadTypeIsTram(rt)) {
|
||||
cost.AddCost(RoadBuildCost(rt) * 2);
|
||||
}
|
||||
} else if (rt == INVALID_ROADTYPE) {
|
||||
return CommandCost(STR_ERROR_THERE_IS_NO_ROAD);
|
||||
} else {
|
||||
ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, cur_tile);
|
||||
if (ret.Failed()) return ret;
|
||||
cost.AddCost(ret.GetCost());
|
||||
cost.AddCost(RoadBuildCost(rt) * 2);
|
||||
}
|
||||
}
|
||||
|
||||
return cost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether we can expand the rail part of the given station.
|
||||
|
@ -1324,6 +1206,230 @@ void SetRailStationTileFlags(TileIndex tile, const StationSpec *statspec)
|
|||
SetStationTileHaveWires(tile, !flags.Test(StationSpec::TileFlag::NoWires));
|
||||
}
|
||||
|
||||
CommandCost IsRailStationBridgeAboveOk(TileIndex tile, const StationSpec *statspec, uint8_t layout, TileIndex northern_bridge_end, TileIndex southern_bridge_end, int bridge_height,
|
||||
BridgeType bridge_type, TransportType bridge_transport_type)
|
||||
{
|
||||
if (statspec != nullptr && statspec->internal_flags.Test(StationSpecIntlFlag::BridgeHeightsSet)) {
|
||||
int height_above = statspec->GetBridgeAboveFlags(layout).height;
|
||||
if (height_above == 0) return CommandCost(INVALID_STRING_ID);
|
||||
if (GetTileMaxZ(tile) + height_above > bridge_height) {
|
||||
return CommandCost(STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION);
|
||||
}
|
||||
} else if (!statspec) {
|
||||
/* Default stations/waypoints */
|
||||
const int height = layout < 4 ? 2 : 5;
|
||||
if (GetTileMaxZ(tile) + height > bridge_height) return CommandCost(STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION);
|
||||
} else {
|
||||
return CommandCost(INVALID_STRING_ID);
|
||||
}
|
||||
|
||||
BridgePiecePillarFlags disallowed_pillar_flags;
|
||||
if (statspec != nullptr && statspec->internal_flags.Test(StationSpecIntlFlag::BridgeDisallowedPillarsSet)) {
|
||||
/* Pillar flags set by NewGRF */
|
||||
disallowed_pillar_flags = statspec->GetBridgeAboveFlags(layout).disallowed_pillars;
|
||||
} else if (!statspec) {
|
||||
/* Default stations/waypoints */
|
||||
if (layout < 8) {
|
||||
static const BridgePiecePillarFlags st_flags[8] = {
|
||||
{BridgePiecePillarFlag::BPPF_EDGE_SW, BridgePiecePillarFlag::BPPF_EDGE_NE}, //0x50,
|
||||
{BridgePiecePillarFlag::BPPF_EDGE_NW, BridgePiecePillarFlag::BPPF_EDGE_SE}, //0xA0,
|
||||
{BridgePiecePillarFlag::BPPF_EDGE_SW, BridgePiecePillarFlag::BPPF_EDGE_NE}, //0x50,
|
||||
{BridgePiecePillarFlag::BPPF_EDGE_NW, BridgePiecePillarFlag::BPPF_EDGE_SE}, //0xA0,
|
||||
{BridgePiecePillarFlag::BPPF_EDGE_SW, BridgePiecePillarFlag::BPPF_EDGE_NE, BridgePiecePillarFlag::BPPF_EDGE_SE, BridgePiecePillarFlag::BPPF_CORNER_E, BridgePiecePillarFlag::BPPF_CORNER_S}, //0x50 | 0x26,
|
||||
{BridgePiecePillarFlag::BPPF_EDGE_NW, BridgePiecePillarFlag::BPPF_EDGE_SE, BridgePiecePillarFlag::BPPF_EDGE_NE, BridgePiecePillarFlag::BPPF_CORNER_N, BridgePiecePillarFlag::BPPF_CORNER_E}, //0xA0 | 0x1C,
|
||||
{BridgePiecePillarFlag::BPPF_EDGE_NW, BridgePiecePillarFlag::BPPF_EDGE_SE, BridgePiecePillarFlag::BPPF_EDGE_NW, BridgePiecePillarFlag::BPPF_CORNER_N, BridgePiecePillarFlag::BPPF_CORNER_W}, //0x50 | 0x89,
|
||||
{BridgePiecePillarFlag::BPPF_EDGE_NW, BridgePiecePillarFlag::BPPF_EDGE_SE, BridgePiecePillarFlag::BPPF_EDGE_SW, BridgePiecePillarFlag::BPPF_CORNER_S, BridgePiecePillarFlag::BPPF_CORNER_W} //0xA0 | 0x43
|
||||
};
|
||||
|
||||
disallowed_pillar_flags = st_flags[layout];
|
||||
} else {
|
||||
disallowed_pillar_flags = {};
|
||||
}
|
||||
} else if (GetStationTileFlags(layout, statspec).Test(StationSpec::TileFlag::Blocked)) {
|
||||
/* Non-track station tiles */
|
||||
disallowed_pillar_flags = {};
|
||||
} else {
|
||||
/* Tracked station tiles */
|
||||
const Axis axis = HasBit(layout, 0) ? AXIS_Y : AXIS_X;
|
||||
disallowed_pillar_flags = axis == AXIS_X ? BridgePiecePillarFlags({BridgePiecePillarFlag::BPPF_EDGE_SW, BridgePiecePillarFlag::BPPF_EDGE_NE}) : BridgePiecePillarFlags({BridgePiecePillarFlag::BPPF_EDGE_NW, BridgePiecePillarFlag::BPPF_EDGE_SE}); //0x50, 0xA0
|
||||
}
|
||||
|
||||
if (!(GetBridgeTilePillarFlags(tile, northern_bridge_end, southern_bridge_end, bridge_type, bridge_transport_type) & disallowed_pillar_flags).Any()) return CommandCost(STR_ERROR_BRIDGE_PILLARS_OBSTRUCT_STATION);
|
||||
|
||||
return CommandCost();
|
||||
}
|
||||
|
||||
CommandCost IsRailStationBridgeAboveOk(TileIndex tile, const StationSpec *statspec, uint8_t layout)
|
||||
{
|
||||
if (!IsBridgeAbove(tile)) return CommandCost();
|
||||
|
||||
TileIndex southern_bridge_end = GetSouthernBridgeEnd(tile);
|
||||
TileIndex northern_bridge_end = GetNorthernBridgeEnd(tile);
|
||||
return IsRailStationBridgeAboveOk(tile, statspec, layout, northern_bridge_end, southern_bridge_end, GetBridgeHeight(southern_bridge_end),
|
||||
GetBridgeType(southern_bridge_end), GetTunnelBridgeTransportType(southern_bridge_end));
|
||||
}
|
||||
|
||||
CommandCost IsRoadStopBridgeAboveOK(TileIndex tile, const RoadStopSpec *spec, bool drive_through, DiagDirection entrance,
|
||||
TileIndex northern_bridge_end, TileIndex southern_bridge_end, int bridge_height,
|
||||
BridgeType bridge_type, TransportType bridge_transport_type)
|
||||
{
|
||||
if (spec != nullptr && spec->internal_flags.Test(RoadStopSpecIntlFlag::BridgeHeightsSet)) {
|
||||
int height = spec->bridge_height[drive_through ? (GFX_TRUCK_BUS_DRIVETHROUGH_OFFSET + DiagDirToAxis(entrance)) : entrance];
|
||||
if (height == 0) return CommandCost(INVALID_STRING_ID);
|
||||
if (GetTileMaxZ(tile) + height > bridge_height) {
|
||||
return CommandCost(STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION);
|
||||
}
|
||||
} else {
|
||||
return CommandCost(INVALID_STRING_ID);
|
||||
|
||||
if (GetTileMaxZ(tile) + (drive_through ? 1 : 2) > bridge_height) {
|
||||
return CommandCost(STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION);
|
||||
}
|
||||
}
|
||||
|
||||
BridgePiecePillarFlags disallowed_pillar_flags = {};
|
||||
if (spec != nullptr && spec->internal_flags.Test(RoadStopSpecIntlFlag::BridgeDisallowedPillarsSet)) {
|
||||
disallowed_pillar_flags = spec->bridge_disallowed_pillars[drive_through ? (GFX_TRUCK_BUS_DRIVETHROUGH_OFFSET + DiagDirToAxis(entrance)) : entrance];
|
||||
} else if (drive_through) {
|
||||
disallowed_pillar_flags = DiagDirToAxis(entrance) == AXIS_X ? BridgePiecePillarFlags({BridgePiecePillarFlag::BPPF_EDGE_SW, BridgePiecePillarFlag::BPPF_EDGE_NE}) : BridgePiecePillarFlags({BridgePiecePillarFlag::BPPF_EDGE_NW, BridgePiecePillarFlag::BPPF_EDGE_SE}); //0x50, 0xA0
|
||||
} else {
|
||||
disallowed_pillar_flags.Set((BridgePiecePillarFlags) (4 + entrance));
|
||||
}
|
||||
if (!(GetBridgeTilePillarFlags(tile, northern_bridge_end, southern_bridge_end, bridge_type, bridge_transport_type) & disallowed_pillar_flags).Any()) return CommandCost(STR_ERROR_BRIDGE_PILLARS_OBSTRUCT_STATION);
|
||||
|
||||
return CommandCost();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a road stop can be built at the given tile.
|
||||
* @param cur_tile Tile to check.
|
||||
* @param allowed_z Height allowed for the tile. If allowed_z is negative, it will be set to the height of this tile.
|
||||
* @param flags Operation to perform.
|
||||
* @param invalid_dirs Prohibited directions (set of DiagDirections).
|
||||
* @param is_drive_through True if trying to build a drive-through station.
|
||||
* @param station_type Station type (bus, truck or road waypoint).
|
||||
* @param axis Axis of a drive-through road stop.
|
||||
* @param station StationID to be queried and returned if available.
|
||||
* @param rt Road type to build, may be INVALID_ROADTYPE if an existing road is required.
|
||||
* @return The cost in case of success, or an error code if it failed.
|
||||
*/
|
||||
static CommandCost CheckFlatLandRoadStop(TileIndex cur_tile, int &allowed_z, const RoadStopSpec *spec, DoCommandFlags flags, DiagDirections invalid_dirs, bool is_drive_through, StationType station_type, Axis axis, StationID *station, RoadType rt)
|
||||
{
|
||||
CommandCost cost(EXPENSES_CONSTRUCTION);
|
||||
|
||||
bool allow_under_bridge = spec != nullptr && spec->internal_flags.Test(RoadStopSpecIntlFlag::BridgeHeightsSet);
|
||||
CommandCost ret = CheckBuildableTile(cur_tile, invalid_dirs, allowed_z, !is_drive_through, true);
|
||||
if (ret.Failed()) return ret;
|
||||
cost.AddCost(ret.GetCost());
|
||||
|
||||
if (allow_under_bridge && IsBridgeAbove(cur_tile)) {
|
||||
TileIndex southern_bridge_end = GetSouthernBridgeEnd(cur_tile);
|
||||
TileIndex northern_bridge_end = GetNorthernBridgeEnd(cur_tile);
|
||||
CommandCost bridge_ret = IsRoadStopBridgeAboveOK(cur_tile, spec, is_drive_through, DiagDirection::DIAGDIR_NE /*obviously wrong, but how do you get the "first bit" from invalid_dirs? and how would that be correct?? */,
|
||||
northern_bridge_end, southern_bridge_end, GetBridgeHeight(southern_bridge_end),
|
||||
GetBridgeType(southern_bridge_end), GetTunnelBridgeTransportType(southern_bridge_end));
|
||||
if (bridge_ret.Failed()) return bridge_ret;
|
||||
}
|
||||
|
||||
/* If station is set, then we have special handling to allow building on top of already existing stations.
|
||||
* Station points to StationID::Invalid() if we can build on any station.
|
||||
* Or it points to a station if we're only allowed to build on exactly that station. */
|
||||
if (station != nullptr && IsTileType(cur_tile, MP_STATION)) {
|
||||
if (!IsAnyRoadStop(cur_tile)) {
|
||||
return ClearTile_Station(cur_tile, DoCommandFlag::Auto); // Get error message.
|
||||
} else {
|
||||
if (station_type != GetStationType(cur_tile) ||
|
||||
is_drive_through != IsDriveThroughStopTile(cur_tile)) {
|
||||
return ClearTile_Station(cur_tile, DoCommandFlag::Auto); // Get error message.
|
||||
}
|
||||
/* Drive-through station in the wrong direction. */
|
||||
if (is_drive_through && IsDriveThroughStopTile(cur_tile) && GetDriveThroughStopAxis(cur_tile) != axis) {
|
||||
return CommandCost(STR_ERROR_DRIVE_THROUGH_DIRECTION);
|
||||
}
|
||||
StationID st = GetStationIndex(cur_tile);
|
||||
if (*station == StationID::Invalid()) {
|
||||
*station = st;
|
||||
} else if (*station != st) {
|
||||
return CommandCost(STR_ERROR_ADJOINS_MORE_THAN_ONE_EXISTING);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bool build_over_road = is_drive_through && IsNormalRoadTile(cur_tile);
|
||||
/* Road bits in the wrong direction. */
|
||||
RoadBits rb = IsNormalRoadTile(cur_tile) ? GetAllRoadBits(cur_tile) : ROAD_NONE;
|
||||
if (build_over_road && (rb & (axis == AXIS_X ? ROAD_Y : ROAD_X)) != 0) {
|
||||
/* Someone was pedantic and *NEEDED* three fracking different error messages. */
|
||||
switch (CountBits(rb)) {
|
||||
case 1:
|
||||
return CommandCost(STR_ERROR_DRIVE_THROUGH_DIRECTION);
|
||||
|
||||
case 2:
|
||||
if (rb == ROAD_X || rb == ROAD_Y) return CommandCost(STR_ERROR_DRIVE_THROUGH_DIRECTION);
|
||||
return CommandCost(STR_ERROR_DRIVE_THROUGH_CORNER);
|
||||
|
||||
default: // 3 or 4
|
||||
return CommandCost(STR_ERROR_DRIVE_THROUGH_JUNCTION);
|
||||
}
|
||||
}
|
||||
|
||||
if (build_over_road) {
|
||||
/* There is a road, check if we can build road+tram stop over it. */
|
||||
RoadType road_rt = GetRoadType(cur_tile, RTT_ROAD);
|
||||
if (road_rt != INVALID_ROADTYPE) {
|
||||
Owner road_owner = GetRoadOwner(cur_tile, RTT_ROAD);
|
||||
if (road_owner == OWNER_TOWN) {
|
||||
if (!_settings_game.construction.road_stop_on_town_road) return CommandCost(STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD);
|
||||
} else if (!_settings_game.construction.road_stop_on_competitor_road && road_owner != OWNER_NONE) {
|
||||
ret = CheckOwnership(road_owner);
|
||||
if (ret.Failed()) return ret;
|
||||
}
|
||||
uint num_pieces = CountBits(GetRoadBits(cur_tile, RTT_ROAD));
|
||||
|
||||
if (rt != INVALID_ROADTYPE && RoadTypeIsRoad(rt) && !HasPowerOnRoad(rt, road_rt)) return CommandCost(STR_ERROR_NO_SUITABLE_ROAD);
|
||||
|
||||
if (GetDisallowedRoadDirections(cur_tile) != DRD_NONE && road_owner != OWNER_TOWN) {
|
||||
ret = CheckOwnership(road_owner);
|
||||
if (ret.Failed()) return ret;
|
||||
}
|
||||
|
||||
cost.AddCost(RoadBuildCost(road_rt) * (2 - num_pieces));
|
||||
} else if (rt != INVALID_ROADTYPE && RoadTypeIsRoad(rt)) {
|
||||
cost.AddCost(RoadBuildCost(rt) * 2);
|
||||
}
|
||||
|
||||
/* There is a tram, check if we can build road+tram stop over it. */
|
||||
RoadType tram_rt = GetRoadType(cur_tile, RTT_TRAM);
|
||||
if (tram_rt != INVALID_ROADTYPE) {
|
||||
Owner tram_owner = GetRoadOwner(cur_tile, RTT_TRAM);
|
||||
if (Company::IsValidID(tram_owner) &&
|
||||
(!_settings_game.construction.road_stop_on_competitor_road ||
|
||||
/* Disallow breaking end-of-line of someone else
|
||||
* so trams can still reverse on this tile. */
|
||||
HasExactlyOneBit(GetRoadBits(cur_tile, RTT_TRAM)))) {
|
||||
ret = CheckOwnership(tram_owner);
|
||||
if (ret.Failed()) return ret;
|
||||
}
|
||||
uint num_pieces = CountBits(GetRoadBits(cur_tile, RTT_TRAM));
|
||||
|
||||
if (rt != INVALID_ROADTYPE && RoadTypeIsTram(rt) && !HasPowerOnRoad(rt, tram_rt)) return CommandCost(STR_ERROR_NO_SUITABLE_ROAD);
|
||||
|
||||
cost.AddCost(RoadBuildCost(tram_rt) * (2 - num_pieces));
|
||||
} else if (rt != INVALID_ROADTYPE && RoadTypeIsTram(rt)) {
|
||||
cost.AddCost(RoadBuildCost(rt) * 2);
|
||||
}
|
||||
} else if (rt == INVALID_ROADTYPE) {
|
||||
return CommandCost(STR_ERROR_THERE_IS_NO_ROAD);
|
||||
} else {
|
||||
ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, cur_tile);
|
||||
if (ret.Failed()) return ret;
|
||||
cost.AddCost(ret.GetCost());
|
||||
cost.AddCost(RoadBuildCost(rt) * 2);
|
||||
}
|
||||
}
|
||||
|
||||
return cost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build rail station
|
||||
* @param flags operation to perform
|
||||
|
@ -1362,6 +1468,9 @@ CommandCost CmdBuildRailStation(DoCommandFlags flags, TileIndex tile_org, RailTy
|
|||
w_org = numtracks;
|
||||
}
|
||||
|
||||
/* Check if the first tile and the last tile are valid */
|
||||
if (!IsValidTile(tile_org) || TileAddWrap(tile_org, w_org - 1, h_org - 1) == INVALID_TILE) return CMD_ERROR;
|
||||
|
||||
bool reuse = (station_to_join != NEW_STATION);
|
||||
if (!reuse) station_to_join = StationID::Invalid();
|
||||
bool distant_join = (station_to_join != StationID::Invalid());
|
||||
|
@ -1376,6 +1485,32 @@ CommandCost CmdBuildRailStation(DoCommandFlags flags, TileIndex tile_org, RailTy
|
|||
/* Make sure the area below consists of clear tiles. (OR tiles belonging to a certain rail station) */
|
||||
StationID est = StationID::Invalid();
|
||||
std::vector<Train *> affected_vehicles;
|
||||
|
||||
const StationSpec *statspec = StationClass::Get(spec_class)->GetSpec(spec_index);
|
||||
|
||||
TileIndexDiff tile_delta = TileOffsByAxis(axis); // offset to go to the next platform tile
|
||||
TileIndexDiff track_delta = TileOffsByAxis(OtherAxis(axis)); // offset to go to the next track
|
||||
std::vector<uint8_t> layout_buffer;
|
||||
layout_buffer.resize(numtracks * plat_len);
|
||||
GetStationLayout(&layout_buffer[0], numtracks, plat_len, statspec);
|
||||
|
||||
{
|
||||
TileIndex tile_track = tile_org;
|
||||
uint8_t *check_layout_ptr = &layout_buffer[0];
|
||||
for (uint i = 0; i < numtracks; i++) {
|
||||
TileIndex tile = tile_track;
|
||||
for (uint j = 0; j < plat_len; j++) {
|
||||
ret = IsRailStationBridgeAboveOk(tile, statspec, *check_layout_ptr++);
|
||||
if (ret.Failed()) {
|
||||
//return CommandCost::DualErrorMessage(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST, ret.GetErrorMessage()); //FIXME
|
||||
return ret;
|
||||
}
|
||||
tile += tile_delta;
|
||||
}
|
||||
tile_track += track_delta;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add construction and clearing expenses. */
|
||||
CommandCost cost = CalculateRailStationCost(new_location, flags, axis, &est, rt, affected_vehicles, spec_class, spec_index, plat_len, numtracks);
|
||||
if (cost.Failed()) return cost;
|
||||
|
@ -1393,7 +1528,6 @@ CommandCost CmdBuildRailStation(DoCommandFlags flags, TileIndex tile_org, RailTy
|
|||
}
|
||||
|
||||
/* Check if we can allocate a custom stationspec to this station */
|
||||
const StationSpec *statspec = StationClass::Get(spec_class)->GetSpec(spec_index);
|
||||
int specindex = AllocateSpecToStation(statspec, st, flags.Test(DoCommandFlag::Execute));
|
||||
if (specindex == -1) return CommandCost(STR_ERROR_TOO_MANY_STATION_SPECS);
|
||||
|
||||
|
@ -1423,8 +1557,6 @@ CommandCost CmdBuildRailStation(DoCommandFlags flags, TileIndex tile_org, RailTy
|
|||
st->cached_anim_triggers.Set(statspec->animation.triggers);
|
||||
}
|
||||
|
||||
TileIndexDiff tile_delta = TileOffsByAxis(axis); // offset to go to the next platform tile
|
||||
TileIndexDiff track_delta = TileOffsByAxis(OtherAxis(axis)); // offset to go to the next track
|
||||
Track track = AxisToTrack(axis);
|
||||
|
||||
std::vector<uint8_t> layouts(numtracks * plat_len);
|
||||
|
@ -1913,7 +2045,7 @@ static CommandCost FindJoiningRoadStop(StationID existing_stop, StationID statio
|
|||
* @param unit_cost The cost to build one road stop of the current type.
|
||||
* @return The cost in case of success, or an error code if it failed.
|
||||
*/
|
||||
CommandCost CalculateRoadStopCost(TileArea tile_area, DoCommandFlags flags, bool is_drive_through, StationType station_type, Axis axis, DiagDirection ddir, StationID *est, RoadType rt, Money unit_cost)
|
||||
CommandCost CalculateRoadStopCost(TileArea tile_area, DoCommandFlags flags, bool is_drive_through, StationType station_type, const RoadStopSpec *roadstopspec, Axis axis, DiagDirection ddir, StationID *est, RoadType rt, Money unit_cost)
|
||||
{
|
||||
DiagDirections invalid_dirs{};
|
||||
if (is_drive_through) {
|
||||
|
@ -1927,7 +2059,7 @@ CommandCost CalculateRoadStopCost(TileArea tile_area, DoCommandFlags flags, bool
|
|||
int allowed_z = -1;
|
||||
CommandCost cost(EXPENSES_CONSTRUCTION);
|
||||
for (TileIndex cur_tile : tile_area) {
|
||||
CommandCost ret = CheckFlatLandRoadStop(cur_tile, allowed_z, flags, invalid_dirs, is_drive_through, station_type, axis, est, rt);
|
||||
CommandCost ret = CheckFlatLandRoadStop(cur_tile, allowed_z, roadstopspec, flags, invalid_dirs, is_drive_through, station_type, axis, est, rt);
|
||||
if (ret.Failed()) return ret;
|
||||
|
||||
bool is_preexisting_roadstop = IsTileType(cur_tile, MP_STATION) && IsAnyRoadStop(cur_tile);
|
||||
|
@ -2008,7 +2140,7 @@ CommandCost CmdBuildRoadStop(DoCommandFlags flags, TileIndex tile, uint8_t width
|
|||
unit_cost = _price[is_truck_stop ? PR_BUILD_STATION_TRUCK : PR_BUILD_STATION_BUS];
|
||||
}
|
||||
StationID est = StationID::Invalid();
|
||||
CommandCost cost = CalculateRoadStopCost(roadstop_area, flags, is_drive_through, is_truck_stop ? StationType::Truck : StationType::Bus, axis, ddir, &est, rt, unit_cost);
|
||||
CommandCost cost = CalculateRoadStopCost(roadstop_area, flags, is_drive_through, is_truck_stop ? StationType::Truck : StationType::Bus, roadstopspec, axis, ddir, &est, rt, unit_cost);
|
||||
if (cost.Failed()) return cost;
|
||||
|
||||
Station *st = nullptr;
|
||||
|
@ -3380,6 +3512,7 @@ draw_default_foundation:
|
|||
}
|
||||
|
||||
DrawRailTileSeq(ti, t, TO_BUILDINGS, total_offset, relocation, palette);
|
||||
DrawBridgeMiddle(ti);
|
||||
}
|
||||
|
||||
void StationPickerDrawSprite(int x, int y, StationType st, RailType railtype, RoadType roadtype, int image)
|
||||
|
|
|
@ -740,8 +740,53 @@ static const std::span<const std::span<const PalSpriteID>> _bridge_sprite_table[
|
|||
* @param nrl description of the rail bridge in query tool
|
||||
* @param nrd description of the road bridge in query tool
|
||||
*/
|
||||
#define MBR(y, mnl, mxl, p, mxs, spr, plt, dsc, nrl, nrd) \
|
||||
{TimerGameCalendar::Year{y}, mnl, mxl, p, mxs, spr, plt, dsc, { nrl, nrd }, {}, 0}
|
||||
#define MBR(y, mnl, mxl, p, mxs, spr, plt, dsc, nrl, nrd, pillars) \
|
||||
{TimerGameCalendar::Year{y}, mnl, mxl, p, mxs, spr, plt, dsc, { nrl, nrd }, {}, 0, BridgeSpecCtrlFlags(), pillars}
|
||||
|
||||
static constexpr std::array<BridgePiecePillarFlags, 12> all_pillars = {
|
||||
BridgePiecePillarFlag::BPPF_ALL_CORNERS, //0x0F,
|
||||
BridgePiecePillarFlag::BPPF_ALL_CORNERS, //0x0F,
|
||||
BridgePiecePillarFlag::BPPF_ALL_CORNERS, //0x0F,
|
||||
BridgePiecePillarFlag::BPPF_ALL_CORNERS, //0x0F,
|
||||
BridgePiecePillarFlag::BPPF_ALL_CORNERS, //0x0F,
|
||||
BridgePiecePillarFlag::BPPF_ALL_CORNERS, //0x0F,
|
||||
BridgePiecePillarFlag::BPPF_ALL_CORNERS, //0x0F,
|
||||
BridgePiecePillarFlag::BPPF_ALL_CORNERS, //0x0F,
|
||||
BridgePiecePillarFlag::BPPF_ALL_CORNERS, //0x0F,
|
||||
BridgePiecePillarFlag::BPPF_ALL_CORNERS, //0x0F,
|
||||
BridgePiecePillarFlag::BPPF_ALL_CORNERS, //0x0F,
|
||||
BridgePiecePillarFlag::BPPF_ALL_CORNERS, //0x0F
|
||||
};
|
||||
|
||||
static constexpr std::array<BridgePiecePillarFlags, 12> susp_pillars = {
|
||||
BridgePiecePillarFlags({BridgePiecePillarFlag::BPPF_CORNER_W, BridgePiecePillarFlag::BPPF_CORNER_S}), //0x03,
|
||||
BridgePiecePillarFlags({BridgePiecePillarFlag::BPPF_CORNER_S, BridgePiecePillarFlag::BPPF_CORNER_E}), //0x06,
|
||||
BridgePiecePillarFlags({BridgePiecePillarFlag::BPPF_CORNER_E, BridgePiecePillarFlag::BPPF_CORNER_N}), //0x0C,
|
||||
BridgePiecePillarFlags({BridgePiecePillarFlag::BPPF_CORNER_W, BridgePiecePillarFlag::BPPF_CORNER_N}), //0x09,
|
||||
BridgePiecePillarFlags({BridgePiecePillarFlag::BPPF_CORNER_E, BridgePiecePillarFlag::BPPF_CORNER_N}), //0x0C,
|
||||
BridgePiecePillarFlags({BridgePiecePillarFlag::BPPF_CORNER_W, BridgePiecePillarFlag::BPPF_CORNER_N}), //0x09,
|
||||
BridgePiecePillarFlags({BridgePiecePillarFlag::BPPF_CORNER_W, BridgePiecePillarFlag::BPPF_CORNER_S}), //0x03,
|
||||
BridgePiecePillarFlags({BridgePiecePillarFlag::BPPF_CORNER_S, BridgePiecePillarFlag::BPPF_CORNER_E}), //0x06,
|
||||
BridgePiecePillarFlags({BridgePiecePillarFlag::BPPF_ALL_CORNERS}), //0x0F,
|
||||
BridgePiecePillarFlags({BridgePiecePillarFlag::BPPF_ALL_CORNERS}), //0x0F,
|
||||
BridgePiecePillarFlags({BridgePiecePillarFlag()}), //0x00,
|
||||
BridgePiecePillarFlags({BridgePiecePillarFlag()}), //0x00
|
||||
};
|
||||
|
||||
static constexpr std::array<BridgePiecePillarFlags, 12> cant_pillars = {
|
||||
BridgePiecePillarFlags({BridgePiecePillarFlag()}), //0x00,
|
||||
BridgePiecePillarFlags({BridgePiecePillarFlag()}), //0x00,
|
||||
BridgePiecePillarFlags({BridgePiecePillarFlag::BPPF_CORNER_E, BridgePiecePillarFlag::BPPF_CORNER_N}), //0x0C,
|
||||
BridgePiecePillarFlags({BridgePiecePillarFlag::BPPF_CORNER_W, BridgePiecePillarFlag::BPPF_CORNER_N}), //0x09,
|
||||
BridgePiecePillarFlags({BridgePiecePillarFlag::BPPF_CORNER_E, BridgePiecePillarFlag::BPPF_CORNER_N}), //0x0C,
|
||||
BridgePiecePillarFlags({BridgePiecePillarFlag::BPPF_CORNER_W, BridgePiecePillarFlag::BPPF_CORNER_N}), //0x09,
|
||||
BridgePiecePillarFlags({BridgePiecePillarFlag::BPPF_CORNER_E, BridgePiecePillarFlag::BPPF_CORNER_N}), //0x0C,
|
||||
BridgePiecePillarFlags({BridgePiecePillarFlag::BPPF_CORNER_W, BridgePiecePillarFlag::BPPF_CORNER_N}), //0x09,
|
||||
BridgePiecePillarFlags({BridgePiecePillarFlag::BPPF_CORNER_E, BridgePiecePillarFlag::BPPF_CORNER_N}), //0x0C,
|
||||
BridgePiecePillarFlags({BridgePiecePillarFlag::BPPF_CORNER_W, BridgePiecePillarFlag::BPPF_CORNER_N}), //0x09,
|
||||
BridgePiecePillarFlags({BridgePiecePillarFlag::BPPF_CORNER_E, BridgePiecePillarFlag::BPPF_CORNER_N}), //0x0C,
|
||||
BridgePiecePillarFlags({BridgePiecePillarFlag::BPPF_CORNER_W, BridgePiecePillarFlag::BPPF_CORNER_N}), //0x09
|
||||
};
|
||||
|
||||
const BridgeSpec _orig_bridge[] = {
|
||||
/*
|
||||
|
@ -755,43 +800,43 @@ const BridgeSpec _orig_bridge[] = {
|
|||
string with description name on rail name on road
|
||||
| | | | */
|
||||
MBR( 0, 0, 0xFFFF, 80, 32, 0xA24, PAL_NONE,
|
||||
STR_BRIDGE_NAME_WOODEN, STR_LAI_BRIDGE_DESCRIPTION_RAIL_WOODEN, STR_LAI_BRIDGE_DESCRIPTION_ROAD_WOODEN),
|
||||
STR_BRIDGE_NAME_WOODEN, STR_LAI_BRIDGE_DESCRIPTION_RAIL_WOODEN, STR_LAI_BRIDGE_DESCRIPTION_ROAD_WOODEN, all_pillars),
|
||||
|
||||
MBR( 0, 0, 2, 112, 48, 0xA26, PALETTE_TO_STRUCT_RED,
|
||||
STR_BRIDGE_NAME_CONCRETE, STR_LAI_BRIDGE_DESCRIPTION_RAIL_CONCRETE, STR_LAI_BRIDGE_DESCRIPTION_ROAD_CONCRETE),
|
||||
STR_BRIDGE_NAME_CONCRETE, STR_LAI_BRIDGE_DESCRIPTION_RAIL_CONCRETE, STR_LAI_BRIDGE_DESCRIPTION_ROAD_CONCRETE, all_pillars),
|
||||
|
||||
MBR(1930, 0, 5, 144, 64, 0xA25, PAL_NONE,
|
||||
STR_BRIDGE_NAME_GIRDER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_GIRDER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_GIRDER_STEEL),
|
||||
STR_BRIDGE_NAME_GIRDER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_GIRDER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_GIRDER_STEEL, all_pillars),
|
||||
|
||||
MBR( 0, 2, 10, 168, 80, 0xA22, PALETTE_TO_STRUCT_CONCRETE,
|
||||
STR_BRIDGE_NAME_SUSPENSION_CONCRETE, STR_LAI_BRIDGE_DESCRIPTION_RAIL_SUSPENSION_CONCRETE, STR_LAI_BRIDGE_DESCRIPTION_ROAD_SUSPENSION_CONCRETE),
|
||||
STR_BRIDGE_NAME_SUSPENSION_CONCRETE, STR_LAI_BRIDGE_DESCRIPTION_RAIL_SUSPENSION_CONCRETE, STR_LAI_BRIDGE_DESCRIPTION_ROAD_SUSPENSION_CONCRETE, susp_pillars),
|
||||
|
||||
MBR(1930, 3, 0xFFFF, 185, 96, 0xA22, PAL_NONE,
|
||||
STR_BRIDGE_NAME_SUSPENSION_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_SUSPENSION_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_SUSPENSION_STEEL),
|
||||
STR_BRIDGE_NAME_SUSPENSION_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_SUSPENSION_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_SUSPENSION_STEEL, susp_pillars),
|
||||
|
||||
MBR(1930, 3, 0xFFFF, 192, 112, 0xA22, PALETTE_TO_STRUCT_YELLOW,
|
||||
STR_BRIDGE_NAME_SUSPENSION_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_SUSPENSION_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_SUSPENSION_STEEL),
|
||||
STR_BRIDGE_NAME_SUSPENSION_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_SUSPENSION_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_SUSPENSION_STEEL, susp_pillars),
|
||||
|
||||
MBR(1930, 3, 7, 224, 160, 0xA23, PAL_NONE,
|
||||
STR_BRIDGE_NAME_CANTILEVER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_CANTILEVER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_CANTILEVER_STEEL),
|
||||
STR_BRIDGE_NAME_CANTILEVER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_CANTILEVER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_CANTILEVER_STEEL, cant_pillars),
|
||||
|
||||
MBR(1930, 3, 8, 232, 208, 0xA23, PALETTE_TO_STRUCT_BROWN,
|
||||
STR_BRIDGE_NAME_CANTILEVER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_CANTILEVER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_CANTILEVER_STEEL),
|
||||
STR_BRIDGE_NAME_CANTILEVER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_CANTILEVER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_CANTILEVER_STEEL, cant_pillars),
|
||||
|
||||
MBR(1930, 3, 9, 248, 240, 0xA23, PALETTE_TO_STRUCT_RED,
|
||||
STR_BRIDGE_NAME_CANTILEVER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_CANTILEVER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_CANTILEVER_STEEL),
|
||||
STR_BRIDGE_NAME_CANTILEVER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_CANTILEVER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_CANTILEVER_STEEL, cant_pillars),
|
||||
|
||||
MBR(1930, 0, 2, 240, 256, 0xA27, PAL_NONE,
|
||||
STR_BRIDGE_NAME_GIRDER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_GIRDER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_GIRDER_STEEL),
|
||||
STR_BRIDGE_NAME_GIRDER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_GIRDER_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_GIRDER_STEEL, all_pillars),
|
||||
|
||||
MBR(1995, 2, 0xFFFF, 255, 320, 0xA28, PAL_NONE,
|
||||
STR_BRIDGE_NAME_TUBULAR_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_TUBULAR_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_TUBULAR_STEEL),
|
||||
STR_BRIDGE_NAME_TUBULAR_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_TUBULAR_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_TUBULAR_STEEL, cant_pillars),
|
||||
|
||||
MBR(2005, 2, 0xFFFF, 380, 512, 0xA28, PALETTE_TO_STRUCT_YELLOW,
|
||||
STR_BRIDGE_NAME_TUBULAR_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_TUBULAR_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_TUBULAR_STEEL),
|
||||
STR_BRIDGE_NAME_TUBULAR_STEEL, STR_LAI_BRIDGE_DESCRIPTION_RAIL_TUBULAR_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_TUBULAR_STEEL, cant_pillars),
|
||||
|
||||
MBR(2010, 2, 0xFFFF, 510, 608, 0xA28, PALETTE_TO_STRUCT_CONCRETE,
|
||||
STR_BRIDGE_TUBULAR_SILICON, STR_LAI_BRIDGE_DESCRIPTION_RAIL_TUBULAR_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_TUBULAR_STEEL)
|
||||
STR_BRIDGE_TUBULAR_SILICON, STR_LAI_BRIDGE_DESCRIPTION_RAIL_TUBULAR_STEEL, STR_LAI_BRIDGE_DESCRIPTION_ROAD_TUBULAR_STEEL, cant_pillars)
|
||||
};
|
||||
|
||||
#undef MBR
|
||||
|
|
|
@ -39,10 +39,13 @@
|
|||
#include "object_base.h"
|
||||
#include "water.h"
|
||||
#include "company_gui.h"
|
||||
#include "newgrf_roadstop.h"
|
||||
#include "station_func.h"
|
||||
#include "station_map.h"
|
||||
#include "tunnelbridge_cmd.h"
|
||||
#include "landscape_cmd.h"
|
||||
#include "terraform_cmd.h"
|
||||
#include "newgrf_station.h"
|
||||
|
||||
#include "table/strings.h"
|
||||
#include "table/bridge_land.h"
|
||||
|
@ -55,6 +58,12 @@ TileIndex _build_tunnel_endtile; ///< The end of a tunnel; as hidden return from
|
|||
/** Z position of the bridge sprites relative to bridge height (downwards) */
|
||||
static const int BRIDGE_Z_START = 3;
|
||||
|
||||
extern CommandCost IsRailStationBridgeAboveOk(TileIndex tile, const StationSpec *statspec, uint8_t layout, TileIndex northern_bridge_end, TileIndex southern_bridge_end, int bridge_height,
|
||||
BridgeType bridge_type, TransportType bridge_transport_type);
|
||||
|
||||
extern CommandCost IsRoadStopBridgeAboveOK(TileIndex tile, const RoadStopSpec *spec, bool drive_through, DiagDirection entrance,
|
||||
TileIndex northern_bridge_end, TileIndex southern_bridge_end, int bridge_height,
|
||||
BridgeType bridge_type, TransportType bridge_transport_type);
|
||||
|
||||
/**
|
||||
* Mark bridge tiles dirty.
|
||||
|
@ -391,6 +400,43 @@ CommandCost CmdBuildBridge(DoCommandFlags flags, TileIndex tile_end, TileIndex t
|
|||
/* If bridge belonged to bankrupt company, it has a new owner now */
|
||||
is_new_owner = (owner == OWNER_NONE);
|
||||
if (is_new_owner) owner = company;
|
||||
|
||||
TileIndexDiff delta = (direction == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
|
||||
for (TileIndex tile = tile_start + delta; tile != tile_end; tile += delta) {
|
||||
if (!IsTileType(tile, MP_STATION)) continue;
|
||||
switch (GetStationType(tile)) {
|
||||
case StationType::Rail:
|
||||
case StationType::RailWaypoint: {
|
||||
CommandCost ret = IsRailStationBridgeAboveOk(tile, GetStationSpec(tile), GetStationGfx(tile), tile_start, tile_end, z_start + 1, bridge_type, transport_type);
|
||||
if (ret.Failed()) {
|
||||
if (ret.GetErrorMessage() != INVALID_STRING_ID) return ret;
|
||||
ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
|
||||
if (ret.Failed()) return ret;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case StationType::Bus:
|
||||
case StationType::Truck:
|
||||
case StationType::RoadWaypoint: {
|
||||
CommandCost ret = IsRoadStopBridgeAboveOK(tile, GetRoadStopSpec(tile), IsDriveThroughStopTile(tile), IsDriveThroughStopTile(tile) ? AxisToDiagDir(GetDriveThroughStopAxis(tile)) : GetBayRoadStopDir(tile),
|
||||
tile_start, tile_end, z_start + 1, bridge_type, transport_type);
|
||||
if (ret.Failed()) {
|
||||
if (ret.GetErrorMessage() != INVALID_STRING_ID) return ret;
|
||||
ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
|
||||
if (ret.Failed()) return ret;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case StationType::Buoy:
|
||||
/* Buoys are always allowed */
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Build a new bridge. */
|
||||
|
||||
|
@ -467,6 +513,45 @@ CommandCost CmdBuildBridge(DoCommandFlags flags, TileIndex tile_end, TileIndex t
|
|||
break;
|
||||
}
|
||||
|
||||
case MP_STATION: {
|
||||
switch (GetStationType(tile)) {
|
||||
case StationType::Airport:
|
||||
goto not_valid_below;
|
||||
|
||||
case StationType::Rail:
|
||||
case StationType::RailWaypoint: {
|
||||
CommandCost ret = IsRailStationBridgeAboveOk(tile, GetStationSpec(tile), GetStationGfx(tile), tile_start, tile_end, z_start + 1, bridge_type, transport_type);
|
||||
if (ret.Failed()) {
|
||||
if (ret.GetErrorMessage() != INVALID_STRING_ID) return ret;
|
||||
goto not_valid_below;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case StationType::Bus:
|
||||
case StationType::Truck:
|
||||
case StationType::RoadWaypoint: {
|
||||
CommandCost ret = IsRoadStopBridgeAboveOK(tile, GetRoadStopSpec(tile), IsDriveThroughStopTile(tile), IsDriveThroughStopTile(tile) ? AxisToDiagDir(GetDriveThroughStopAxis(tile)) : GetBayRoadStopDir(tile),
|
||||
tile_start, tile_end, z_start + 1, bridge_type, transport_type);
|
||||
if (ret.Failed()) {
|
||||
if (ret.GetErrorMessage() != INVALID_STRING_ID) return ret;
|
||||
goto not_valid_below;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case StationType::Buoy:
|
||||
/* Buoys are always allowed */
|
||||
break;
|
||||
|
||||
default:
|
||||
//if (!(GetStationType(tile) == StationType::Dock && _settings_game.construction.allow_docks_under_bridges)) goto not_valid_below;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case MP_CLEAR:
|
||||
break;
|
||||
|
||||
|
@ -1517,6 +1602,49 @@ static BridgePieces CalcBridgePiece(uint north, uint south)
|
|||
}
|
||||
}
|
||||
|
||||
BridgePiecePillarFlags GetBridgeTilePillarFlags(TileIndex tile, TileIndex northern_bridge_end, TileIndex southern_bridge_end, BridgeType bridge_type, TransportType bridge_transport_type)
|
||||
{
|
||||
if (bridge_transport_type == TRANSPORT_WATER) return BridgePiecePillarFlag::BPPF_ALL_CORNERS;
|
||||
|
||||
BridgePieces piece = CalcBridgePiece(
|
||||
GetTunnelBridgeLength(tile, northern_bridge_end) + 1,
|
||||
GetTunnelBridgeLength(tile, southern_bridge_end) + 1
|
||||
);
|
||||
assert(piece < BRIDGE_PIECE_HEAD);
|
||||
|
||||
const BridgeSpec *spec = GetBridgeSpec(bridge_type);
|
||||
const Axis axis = TileX(northern_bridge_end) == TileX(southern_bridge_end) ? AXIS_Y : AXIS_X;
|
||||
if (!spec->ctrl_flags.Test(BridgeSpecCtrlFlag::BSCF_INVALID_PILLAR_FLAGS)) {
|
||||
return spec->pillar_flags[piece * 2 + (axis == AXIS_Y ? 1 : 0)];
|
||||
} else {
|
||||
uint base_offset;
|
||||
if (bridge_transport_type == TRANSPORT_RAIL) {
|
||||
base_offset = GetRailTypeInfo(GetRailType(southern_bridge_end))->bridge_offset;
|
||||
} else {
|
||||
base_offset = 8;
|
||||
}
|
||||
|
||||
const PalSpriteID *psid = &GetBridgeSpriteTable(bridge_type, piece)[base_offset];
|
||||
if (axis == AXIS_Y) psid += 4;
|
||||
return psid[2].sprite != 0 ? BridgePiecePillarFlag::BPPF_ALL_CORNERS : BridgePiecePillarFlags();
|
||||
}
|
||||
}
|
||||
|
||||
BridgePieceDebugInfo GetBridgePieceDebugInfo(TileIndex tile)
|
||||
{
|
||||
TileIndex rampnorth = GetNorthernBridgeEnd(tile);
|
||||
TileIndex rampsouth = GetSouthernBridgeEnd(tile);
|
||||
|
||||
BridgePieces piece = CalcBridgePiece(
|
||||
GetTunnelBridgeLength(tile, rampnorth) + 1,
|
||||
GetTunnelBridgeLength(tile, rampsouth) + 1
|
||||
);
|
||||
BridgePiecePillarFlags pillar_flags = GetBridgeTilePillarFlags(tile, rampnorth, rampsouth, GetBridgeType(rampnorth), GetTunnelBridgeTransportType(rampnorth));
|
||||
const Axis axis = TileX(rampnorth) == TileX(rampsouth) ? AXIS_Y : AXIS_X;
|
||||
uint pillar_index = piece * 2 + (axis == AXIS_Y ? 1 : 0);
|
||||
return { piece, pillar_flags, pillar_index };
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw the middle bits of a bridge.
|
||||
* @param ti Tile information of the tile to draw it on.
|
||||
|
|
|
@ -182,7 +182,9 @@ static CommandCost IsValidTileForWaypoint(TileIndex tile, Axis axis, StationID *
|
|||
extern void GetStationLayout(uint8_t *layout, uint numtracks, uint plat_len, const StationSpec *statspec);
|
||||
extern CommandCost FindJoiningWaypoint(StationID existing_station, StationID station_to_join, bool adjacent, TileArea ta, Waypoint **wp, bool is_road);
|
||||
extern CommandCost CanExpandRailStation(const BaseStation *st, TileArea &new_ta);
|
||||
extern CommandCost CalculateRoadStopCost(TileArea tile_area, DoCommandFlags flags, bool is_drive_through, StationType station_type, Axis axis, DiagDirection ddir, StationID *est, RoadType rt, Money unit_cost);
|
||||
extern CommandCost CalculateRoadStopCost(TileArea tile_area, DoCommandFlags flags, bool is_drive_through, StationType station_type, const RoadStopSpec *roadstopspec, Axis axis, DiagDirection ddir, StationID *est, RoadType rt, Money unit_cost);
|
||||
extern CommandCost IsRailStationBridgeAboveOk(TileIndex tile, const StationSpec *statspec, uint8_t layout);
|
||||
|
||||
extern CommandCost RemoveRoadWaypointStop(TileIndex tile, DoCommandFlags flags, int replacement_spec_index);
|
||||
|
||||
/**
|
||||
|
@ -220,6 +222,17 @@ CommandCost CmdBuildRailWaypoint(DoCommandFlags flags, TileIndex start_tile, Axi
|
|||
|
||||
if (distant_join && (!_settings_game.station.distant_join_stations || !Waypoint::IsValidID(station_to_join))) return CMD_ERROR;
|
||||
|
||||
const StationSpec *spec = StationClass::Get(spec_class)->GetSpec(spec_index);
|
||||
std::vector<uint8_t> layout_ptr;
|
||||
layout_ptr.resize(count);
|
||||
if (spec == nullptr) {
|
||||
/* The layout must be 0 for the 'normal' waypoints by design. */
|
||||
//memset(layout_ptr, 0, count); //FIXME
|
||||
} else {
|
||||
/* But for NewGRF waypoints we like to have their style. */
|
||||
GetStationLayout(&layout_ptr[0], count, 1, spec);
|
||||
}
|
||||
|
||||
TileArea new_location(start_tile, width, height);
|
||||
|
||||
/* only AddCost for non-existing waypoints */
|
||||
|
@ -237,6 +250,10 @@ CommandCost CmdBuildRailWaypoint(DoCommandFlags flags, TileIndex start_tile, Axi
|
|||
TileIndex tile = start_tile + i * offset;
|
||||
CommandCost ret = IsValidTileForWaypoint(tile, axis, &est);
|
||||
if (ret.Failed()) return ret;
|
||||
ret = IsRailStationBridgeAboveOk(tile, spec, layout_ptr[i]);
|
||||
if (ret.Failed()) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
Waypoint *wp = nullptr;
|
||||
|
@ -364,7 +381,7 @@ CommandCost CmdBuildRoadWaypoint(DoCommandFlags flags, TileIndex start_tile, Axi
|
|||
unit_cost = _price[PR_BUILD_STATION_TRUCK];
|
||||
}
|
||||
StationID est = StationID::Invalid();
|
||||
CommandCost cost = CalculateRoadStopCost(roadstop_area, flags, true, StationType::RoadWaypoint, axis, AxisToDiagDir(axis), &est, INVALID_ROADTYPE, unit_cost);
|
||||
CommandCost cost = CalculateRoadStopCost(roadstop_area, flags, true, StationType::RoadWaypoint, roadstopspec, axis, AxisToDiagDir(axis), &est, INVALID_ROADTYPE, unit_cost);
|
||||
if (cost.Failed()) return cost;
|
||||
|
||||
Waypoint *wp = nullptr;
|
||||
|
|
Loading…
Reference in New Issue