1
0
Fork 0

Compare commits

...

11 Commits

Author SHA1 Message Date
Su 318126e067
Merge 5e984eec1a into 614a01907a 2025-07-27 20:56:42 +00:00
Peter Nelson 614a01907a
Codechange: Make functions for click and confirm beeps. (#14484)
Avoids repetition.
2025-07-27 21:54:32 +01:00
Peter Nelson f51067f9f5
Codechange: Give all bridge sprite tables descriptive names. (#14483)
Finish off the work started 17 years ago...
2025-07-27 20:14:37 +01:00
Susan 5e984eec1a Cleanup: Deduplicate rewritten code 2025-07-17 08:59:37 +01:00
Susan a48f491f09 Cleanup: CodeQL fixes 2025-07-11 07:54:29 +01:00
Susan 3ef5783bf9 Codechange: Reorder returns 2025-07-11 07:03:03 +01:00
Susan 7f6b5d3103 Codechange: use BridgePiecePillarFlags in more places 2025-07-11 05:31:49 +01:00
Susan 5a1a8adb3f Codechange: Less indentation 2025-07-11 02:29:58 +01:00
Susan 1000875f88 Codechange: use BridgePiecePillarFlags instead of uint8_t 2025-07-10 03:06:34 +01:00
Susan 1f5ae37e2c Codechange: use BridgeSpecCtrlFlags instead of uint8_t 2025-07-09 23:48:28 +01:00
Susan 3be979cc05 Feature: Stations under bridges 2025-07-09 06:14:43 +01:00
26 changed files with 733 additions and 332 deletions

View File

@ -509,7 +509,7 @@ public:
this->SetWidgetLoweredState(WID_AP_BTN_DONTHILIGHT, !_settings_client.gui.station_show_coverage); this->SetWidgetLoweredState(WID_AP_BTN_DONTHILIGHT, !_settings_client.gui.station_show_coverage);
this->SetWidgetLoweredState(WID_AP_BTN_DOHILIGHT, _settings_client.gui.station_show_coverage); this->SetWidgetLoweredState(WID_AP_BTN_DOHILIGHT, _settings_client.gui.station_show_coverage);
this->SetDirty(); this->SetDirty();
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
this->UpdateSelectSize(); this->UpdateSelectSize();
SetViewportCatchmentStation(nullptr, true); SetViewportCatchmentStation(nullptr, true);
break; break;

View File

@ -37,6 +37,30 @@ constexpr uint SPRITES_PER_BRIDGE_PIECE = 32; ///< Number of sprites there are p
typedef uint BridgeType; ///< Bridge spec number. 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 * 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 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 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. 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]; extern BridgeSpec _bridge[MAX_BRIDGES];
@ -75,6 +101,15 @@ void DrawBridgeMiddle(const TileInfo *ti);
CommandCost CheckBridgeAvailability(BridgeType bridge_type, uint bridge_len, DoCommandFlags flags = {}); CommandCost CheckBridgeAvailability(BridgeType bridge_type, uint bridge_len, DoCommandFlags flags = {});
int CalcBridgeLenCostFactor(int x); 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(); void ResetBridges();
#endif /* BRIDGE_H */ #endif /* BRIDGE_H */

View File

@ -382,6 +382,8 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo
StringID errmsg = INVALID_STRING_ID; 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); 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; GUIBridgeList bl;
if (ret.Failed()) { if (ret.Failed()) {
errmsg = ret.GetErrorMessage(); errmsg = ret.GetErrorMessage();
@ -415,11 +417,13 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo
} }
bool any_available = false; bool any_available = false;
StringID type_errmsg = INVALID_STRING_ID;
CommandCost type_check; CommandCost type_check;
/* loop for all bridgetypes */ /* loop for all bridgetypes */
for (BridgeType brd_type = 0; brd_type != MAX_BRIDGES; brd_type++) { for (BridgeType brd_type = 0; brd_type != MAX_BRIDGES; brd_type++) {
type_check = CheckBridgeAvailability(brd_type, bridge_len); type_check = CheckBridgeAvailability(brd_type, bridge_len);
if (type_check.Succeeded()) { 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 */ /* bridge is accepted, add to list */
BuildBridgeData &item = bl.emplace_back(); BuildBridgeData &item = bl.emplace_back();
item.index = brd_type; item.index = brd_type;
@ -428,10 +432,12 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo
* bridge itself (not computed with DoCommandFlag::QueryCost) */ * 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; item.cost = ret.GetCost() + (((int64_t)tot_bridgedata_len * _price[PR_BUILD_BRIDGE] * item.spec->price) >> 8) + infra_cost;
any_available = true; 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*/ /* 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(); errmsg = type_check.GetErrorMessage();
} }

View File

@ -469,7 +469,7 @@ public:
this->RaiseWidget(_settings_client.gui.station_show_coverage + BDSW_LT_OFF); this->RaiseWidget(_settings_client.gui.station_show_coverage + BDSW_LT_OFF);
_settings_client.gui.station_show_coverage = (widget != BDSW_LT_OFF); _settings_client.gui.station_show_coverage = (widget != BDSW_LT_OFF);
this->LowerWidget(_settings_client.gui.station_show_coverage + BDSW_LT_OFF); this->LowerWidget(_settings_client.gui.station_show_coverage + BDSW_LT_OFF);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
this->SetDirty(); this->SetDirty();
SetViewportCatchmentStation(nullptr, true); SetViewportCatchmentStation(nullptr, true);
break; break;
@ -580,7 +580,7 @@ public:
this->RaiseWidget(WID_BDD_X + _ship_depot_direction); this->RaiseWidget(WID_BDD_X + _ship_depot_direction);
_ship_depot_direction = (widget == WID_BDD_X ? AXIS_X : AXIS_Y); _ship_depot_direction = (widget == WID_BDD_X ? AXIS_X : AXIS_Y);
this->LowerWidget(WID_BDD_X + _ship_depot_direction); this->LowerWidget(WID_BDD_X + _ship_depot_direction);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
UpdateDocksDirection(); UpdateDocksDirection();
this->SetDirty(); this->SetDirty();
break; break;

View File

@ -323,7 +323,7 @@ static void StartGeneratingLandscape(GenerateLandscapeWindowMode mode)
MakeNewgameSettingsLive(); MakeNewgameSettingsLive();
ResetGRFConfig(true); ResetGRFConfig(true);
if (_settings_client.sound.confirm) SndPlayFx(SND_15_BEEP); SndConfirmBeep();
switch (mode) { switch (mode) {
case GLWM_GENERATE: _switch_mode = (_game_mode == GM_EDITOR) ? SM_GENRANDLAND : SM_NEWGAME; break; case GLWM_GENERATE: _switch_mode = (_game_mode == GM_EDITOR) ? SM_GENRANDLAND : SM_NEWGAME; break;
case GLWM_HEIGHTMAP: _switch_mode = (_game_mode == GM_EDITOR) ? SM_LOAD_HEIGHTMAP : SM_START_HEIGHTMAP; break; case GLWM_HEIGHTMAP: _switch_mode = (_game_mode == GM_EDITOR) ? SM_LOAD_HEIGHTMAP : SM_START_HEIGHTMAP; break;

View File

@ -3076,7 +3076,7 @@ struct IndustryCargoesWindow : public Window {
case WID_IC_NOTIFY: case WID_IC_NOTIFY:
this->ToggleWidgetLoweredState(WID_IC_NOTIFY); this->ToggleWidgetLoweredState(WID_IC_NOTIFY);
this->SetWidgetDirty(WID_IC_NOTIFY); this->SetWidgetDirty(WID_IC_NOTIFY);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
if (this->IsWidgetLowered(WID_IC_NOTIFY)) { if (this->IsWidgetLowered(WID_IC_NOTIFY)) {
if (FindWindowByClass(WC_SMALLMAP) == nullptr) ShowSmallMap(); if (FindWindowByClass(WC_SMALLMAP) == nullptr) ShowSmallMap();

View File

@ -5244,6 +5244,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_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_TOO_LONG :{WHITE}... bridge too long
STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}Bridge would end out of the map 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 # Tunnel related errors
STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Can't build tunnel here... STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}Can't build tunnel here...

View File

@ -64,7 +64,7 @@ bool HandlePlacePushButton(Window *w, WidgetID widget, CursorID cursor, HighLigh
{ {
if (w->IsWidgetDisabled(widget)) return false; if (w->IsWidgetDisabled(widget)) return false;
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
w->SetDirty(); w->SetDirty();
if (w->IsWidgetLowered(widget)) { if (w->IsWidgetLowered(widget)) {

View File

@ -12,6 +12,7 @@
#ifndef NEWGRF_ROADSTATION_H #ifndef NEWGRF_ROADSTATION_H
#define NEWGRF_ROADSTATION_H #define NEWGRF_ROADSTATION_H
#include "bridge.h"
#include "newgrf_animation_type.h" #include "newgrf_animation_type.h"
#include "newgrf_spritegroup.h" #include "newgrf_spritegroup.h"
#include "newgrf_badge_type.h" #include "newgrf_badge_type.h"
@ -71,6 +72,12 @@ enum class RoadStopSpecFlag : uint8_t {
}; };
using RoadStopSpecFlags = EnumBitSet<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 { enum RoadStopView : uint8_t {
RSV_BAY_NE = 0, ///< Bay road stop, facing Northeast RSV_BAY_NE = 0, ///< Bay road stop, facing Northeast
RSV_BAY_SE = 1, ///< Bay road stop, facing Southeast RSV_BAY_SE = 1, ///< Bay road stop, facing Southeast
@ -133,17 +140,20 @@ struct RoadStopSpec : NewGRFSpecBase<RoadStopClassID> {
RoadStopDrawModes draw_mode = {RoadStopDrawMode::Road, RoadStopDrawMode::Overlay}; RoadStopDrawModes draw_mode = {RoadStopDrawMode::Road, RoadStopDrawMode::Overlay};
RoadStopCallbackMasks callback_mask{}; RoadStopCallbackMasks callback_mask{};
RoadStopSpecFlags flags{}; RoadStopSpecFlags flags{};
RoadStopSpecIntlFlags internal_flags{};
CargoTypes cargo_triggers = 0; ///< Bitmask of cargo types which cause trigger re-randomizing CargoTypes cargo_triggers = 0; ///< Bitmask of cargo types which cause trigger re-randomizing
AnimationInfo<StationAnimationTriggers> animation; AnimationInfo<StationAnimationTriggers> animation;
uint8_t bridge_height[6]; ///< Minimum height for a bridge above, 0 for none 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 build_cost_multiplier = 16; ///< Build cost multiplier per tile.
uint8_t clear_cost_multiplier = 16; ///< Clear 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; std::vector<BadgeID> badges;
/** /**

View File

@ -10,6 +10,7 @@
#ifndef NEWGRF_STATION_H #ifndef NEWGRF_STATION_H
#define NEWGRF_STATION_H #define NEWGRF_STATION_H
#include "bridge.h"
#include "core/enum_type.hpp" #include "core/enum_type.hpp"
#include "newgrf_animation_type.h" #include "newgrf_animation_type.h"
#include "newgrf_badge_type.h" #include "newgrf_badge_type.h"
@ -118,6 +119,12 @@ enum class StationSpecFlag : uint8_t {
}; };
using StationSpecFlags = EnumBitSet<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. */ /** Station specification. */
struct StationSpec : NewGRFSpecBase<StationClassID> { struct StationSpec : NewGRFSpecBase<StationClassID> {
StationSpec() : name(0), 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 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 { enum class TileFlag : uint8_t {
Pylons = 0, ///< Tile should contain catenary pylons. Pylons = 0, ///< Tile should contain catenary pylons.
NoWires = 1, ///< Tile should NOT contain catenary wires. NoWires = 1, ///< Tile should NOT contain catenary wires.
@ -172,10 +185,18 @@ struct StationSpec : NewGRFSpecBase<StationClassID> {
AnimationInfo<StationAnimationTriggers> animation; AnimationInfo<StationAnimationTriggers> animation;
StationSpecIntlFlags internal_flags{}; ///< Bitmask of internal spec flags
/** Custom platform layouts, keyed by platform and length combined. */ /** Custom platform layouts, keyed by platform and length combined. */
std::unordered_map<uint16_t, std::vector<uint8_t>> layouts; std::unordered_map<uint16_t, std::vector<uint8_t>> layouts;
std::vector<BadgeID> badges; 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. */ /** Class containing information relating to station classes. */

View File

@ -319,7 +319,7 @@ public:
if (_object_gui.sel_type != std::numeric_limits<uint16_t>::max()) { if (_object_gui.sel_type != std::numeric_limits<uint16_t>::max()) {
_object_gui.sel_view = this->GetWidget<NWidgetBase>(widget)->GetParentWidget<NWidgetMatrix>()->GetCurrentElement(); _object_gui.sel_view = this->GetWidget<NWidgetBase>(widget)->GetParentWidget<NWidgetMatrix>()->GetCurrentElement();
this->InvalidateData(PickerInvalidation::Position); this->InvalidateData(PickerInvalidation::Position);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
} }
break; break;

View File

@ -384,7 +384,7 @@ void PickerWindow::OnClick(Point pt, WidgetID widget, int)
this->callbacks.SetSelectedClass(*it); this->callbacks.SetSelectedClass(*it);
this->InvalidateData({PickerInvalidation::Type, PickerInvalidation::Position, PickerInvalidation::Validate}); this->InvalidateData({PickerInvalidation::Type, PickerInvalidation::Position, PickerInvalidation::Validate});
} }
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
CloseWindowById(WC_SELECT_STATION, 0); CloseWindowById(WC_SELECT_STATION, 0);
break; break;
} }
@ -434,7 +434,7 @@ void PickerWindow::OnClick(Point pt, WidgetID widget, int)
this->callbacks.SetSelectedType(item.index); this->callbacks.SetSelectedType(item.index);
this->InvalidateData(PickerInvalidation::Position); this->InvalidateData(PickerInvalidation::Position);
} }
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
CloseWindowById(WC_SELECT_STATION, 0); CloseWindowById(WC_SELECT_STATION, 0);
break; break;
} }

View File

@ -357,7 +357,7 @@ static void BuildRailClick_Remove(Window *w)
{ {
if (w->IsWidgetDisabled(WID_RAT_REMOVE)) return; if (w->IsWidgetDisabled(WID_RAT_REMOVE)) return;
ToggleRailButton_Remove(w); ToggleRailButton_Remove(w);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
/* handle station builder */ /* handle station builder */
if (w->IsWidgetLowered(WID_RAT_BUILD_STATION)) { if (w->IsWidgetLowered(WID_RAT_BUILD_STATION)) {
@ -1239,7 +1239,7 @@ public:
this->RaiseWidget(WID_BRAS_PLATFORM_DIR_X + _station_gui.axis); this->RaiseWidget(WID_BRAS_PLATFORM_DIR_X + _station_gui.axis);
_station_gui.axis = (Axis)(widget - WID_BRAS_PLATFORM_DIR_X); _station_gui.axis = (Axis)(widget - WID_BRAS_PLATFORM_DIR_X);
this->LowerWidget(WID_BRAS_PLATFORM_DIR_X + _station_gui.axis); this->LowerWidget(WID_BRAS_PLATFORM_DIR_X + _station_gui.axis);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
this->SetDirty(); this->SetDirty();
CloseWindowById(WC_SELECT_STATION, 0); CloseWindowById(WC_SELECT_STATION, 0);
break; break;
@ -1271,7 +1271,7 @@ public:
this->LowerWidget(_settings_client.gui.station_numtracks + WID_BRAS_PLATFORM_NUM_BEGIN); this->LowerWidget(_settings_client.gui.station_numtracks + WID_BRAS_PLATFORM_NUM_BEGIN);
this->LowerWidget(_settings_client.gui.station_platlength + WID_BRAS_PLATFORM_LEN_BEGIN); this->LowerWidget(_settings_client.gui.station_platlength + WID_BRAS_PLATFORM_LEN_BEGIN);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
this->SetDirty(); this->SetDirty();
CloseWindowById(WC_SELECT_STATION, 0); CloseWindowById(WC_SELECT_STATION, 0);
break; break;
@ -1304,7 +1304,7 @@ public:
this->LowerWidget(_settings_client.gui.station_numtracks + WID_BRAS_PLATFORM_NUM_BEGIN); this->LowerWidget(_settings_client.gui.station_numtracks + WID_BRAS_PLATFORM_NUM_BEGIN);
this->LowerWidget(_settings_client.gui.station_platlength + WID_BRAS_PLATFORM_LEN_BEGIN); this->LowerWidget(_settings_client.gui.station_platlength + WID_BRAS_PLATFORM_LEN_BEGIN);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
this->SetDirty(); this->SetDirty();
CloseWindowById(WC_SELECT_STATION, 0); CloseWindowById(WC_SELECT_STATION, 0);
break; break;
@ -1338,7 +1338,7 @@ public:
this->SetWidgetLoweredState(_settings_client.gui.station_numtracks + WID_BRAS_PLATFORM_NUM_BEGIN, !_settings_client.gui.station_dragdrop); this->SetWidgetLoweredState(_settings_client.gui.station_numtracks + WID_BRAS_PLATFORM_NUM_BEGIN, !_settings_client.gui.station_dragdrop);
this->SetWidgetLoweredState(_settings_client.gui.station_platlength + WID_BRAS_PLATFORM_LEN_BEGIN, !_settings_client.gui.station_dragdrop); this->SetWidgetLoweredState(_settings_client.gui.station_platlength + WID_BRAS_PLATFORM_LEN_BEGIN, !_settings_client.gui.station_dragdrop);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
this->SetDirty(); this->SetDirty();
CloseWindowById(WC_SELECT_STATION, 0); CloseWindowById(WC_SELECT_STATION, 0);
break; break;
@ -1350,7 +1350,7 @@ public:
this->SetWidgetLoweredState(WID_BRAS_HIGHLIGHT_OFF, !_settings_client.gui.station_show_coverage); this->SetWidgetLoweredState(WID_BRAS_HIGHLIGHT_OFF, !_settings_client.gui.station_show_coverage);
this->SetWidgetLoweredState(WID_BRAS_HIGHLIGHT_ON, _settings_client.gui.station_show_coverage); this->SetWidgetLoweredState(WID_BRAS_HIGHLIGHT_ON, _settings_client.gui.station_show_coverage);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
this->SetDirty(); this->SetDirty();
SetViewportCatchmentStation(nullptr, true); SetViewportCatchmentStation(nullptr, true);
break; break;
@ -1743,7 +1743,7 @@ struct BuildRailDepotWindow : public PickerWindowBase {
this->RaiseWidget(WID_BRAD_DEPOT_NE + _build_depot_direction); this->RaiseWidget(WID_BRAD_DEPOT_NE + _build_depot_direction);
_build_depot_direction = (DiagDirection)(widget - WID_BRAD_DEPOT_NE); _build_depot_direction = (DiagDirection)(widget - WID_BRAD_DEPOT_NE);
this->LowerWidget(WID_BRAD_DEPOT_NE + _build_depot_direction); this->LowerWidget(WID_BRAD_DEPOT_NE + _build_depot_direction);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
this->SetDirty(); this->SetDirty();
break; break;
} }

View File

@ -582,7 +582,7 @@ struct BuildRoadToolbarWindow : Window {
CloseWindowById(WC_SELECT_STATION, 0); CloseWindowById(WC_SELECT_STATION, 0);
ToggleRoadButton_Remove(this); ToggleRoadButton_Remove(this);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
break; break;
case WID_ROT_CONVERT_ROAD: case WID_ROT_CONVERT_ROAD:
@ -1145,7 +1145,7 @@ struct BuildRoadDepotWindow : public PickerWindowBase {
this->RaiseWidget(WID_BROD_DEPOT_NE + _road_depot_orientation); this->RaiseWidget(WID_BROD_DEPOT_NE + _road_depot_orientation);
_road_depot_orientation = (DiagDirection)(widget - WID_BROD_DEPOT_NE); _road_depot_orientation = (DiagDirection)(widget - WID_BROD_DEPOT_NE);
this->LowerWidget(WID_BROD_DEPOT_NE + _road_depot_orientation); this->LowerWidget(WID_BROD_DEPOT_NE + _road_depot_orientation);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
this->SetDirty(); this->SetDirty();
break; break;
@ -1477,7 +1477,7 @@ public:
this->RaiseWidget(WID_BROS_STATION_NE + _roadstop_gui.orientation); this->RaiseWidget(WID_BROS_STATION_NE + _roadstop_gui.orientation);
_roadstop_gui.orientation = (DiagDirection)(widget - WID_BROS_STATION_NE); _roadstop_gui.orientation = (DiagDirection)(widget - WID_BROS_STATION_NE);
this->LowerWidget(WID_BROS_STATION_NE + _roadstop_gui.orientation); this->LowerWidget(WID_BROS_STATION_NE + _roadstop_gui.orientation);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
this->SetDirty(); this->SetDirty();
CloseWindowById(WC_SELECT_STATION, 0); CloseWindowById(WC_SELECT_STATION, 0);
break; break;
@ -1487,7 +1487,7 @@ public:
this->RaiseWidget(_settings_client.gui.station_show_coverage + WID_BROS_LT_OFF); this->RaiseWidget(_settings_client.gui.station_show_coverage + WID_BROS_LT_OFF);
_settings_client.gui.station_show_coverage = (widget != WID_BROS_LT_OFF); _settings_client.gui.station_show_coverage = (widget != WID_BROS_LT_OFF);
this->LowerWidget(_settings_client.gui.station_show_coverage + WID_BROS_LT_OFF); this->LowerWidget(_settings_client.gui.station_show_coverage + WID_BROS_LT_OFF);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
this->SetDirty(); this->SetDirty();
SetViewportCatchmentStation(nullptr, true); SetViewportCatchmentStation(nullptr, true);
break; break;

View File

@ -1717,7 +1717,7 @@ public:
const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_SM_MAP); const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_SM_MAP);
Point zoom_pt = { (int)wid->current_x / 2, (int)wid->current_y / 2}; Point zoom_pt = { (int)wid->current_x / 2, (int)wid->current_y / 2};
this->SetZoomLevel((widget == WID_SM_ZOOM_IN) ? ZLC_ZOOM_IN : ZLC_ZOOM_OUT, &zoom_pt); this->SetZoomLevel((widget == WID_SM_ZOOM_IN) ? ZLC_ZOOM_IN : ZLC_ZOOM_OUT, &zoom_pt);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
break; break;
} }
@ -1729,13 +1729,13 @@ public:
case WID_SM_VEGETATION: // Show vegetation case WID_SM_VEGETATION: // Show vegetation
case WID_SM_OWNERS: // Show land owners case WID_SM_OWNERS: // Show land owners
this->SwitchMapType((SmallMapType)(widget - WID_SM_CONTOUR)); this->SwitchMapType((SmallMapType)(widget - WID_SM_CONTOUR));
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
break; break;
case WID_SM_CENTERMAP: // Center the smallmap again case WID_SM_CENTERMAP: // Center the smallmap again
this->SmallMapCenterOnCurrentPos(); this->SmallMapCenterOnCurrentPos();
this->HandleButtonClick(WID_SM_CENTERMAP); this->HandleButtonClick(WID_SM_CENTERMAP);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
break; break;
case WID_SM_TOGGLETOWNNAME: // Toggle town names case WID_SM_TOGGLETOWNNAME: // Toggle town names
@ -1743,7 +1743,7 @@ public:
this->SetWidgetLoweredState(WID_SM_TOGGLETOWNNAME, this->show_towns); this->SetWidgetLoweredState(WID_SM_TOGGLETOWNNAME, this->show_towns);
this->SetDirty(); this->SetDirty();
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
break; break;
case WID_SM_SHOW_IND_NAMES: // Toggle industry names case WID_SM_SHOW_IND_NAMES: // Toggle industry names
@ -1751,7 +1751,7 @@ public:
this->SetWidgetLoweredState(WID_SM_SHOW_IND_NAMES, this->show_ind_names); this->SetWidgetLoweredState(WID_SM_SHOW_IND_NAMES, this->show_ind_names);
this->SetDirty(); this->SetDirty();
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
break; break;
case WID_SM_LEGEND: // Legend case WID_SM_LEGEND: // Legend

View File

@ -247,6 +247,22 @@ void SndPlayFx(SoundID sound)
StartSound(sound, 0.5, UINT8_MAX); StartSound(sound, 0.5, UINT8_MAX);
} }
/**
* Play a beep sound for a click event if enabled in settings.
*/
void SndClickBeep()
{
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP);
}
/**
* Play a beep sound for a confirm event if enabled in settings.
*/
void SndConfirmBeep()
{
if (_settings_client.sound.confirm) SndPlayFx(SND_15_BEEP);
}
/** Names corresponding to the sound set's files */ /** Names corresponding to the sound set's files */
static const std::string_view _sound_file_names[] = { "samples" }; static const std::string_view _sound_file_names[] = { "samples" };

View File

@ -21,4 +21,7 @@ void SndPlayVehicleFx(SoundID sound, const Vehicle *v);
void SndPlayFx(SoundID sound); void SndPlayFx(SoundID sound);
void SndCopyToPool(); void SndCopyToPool();
void SndClickBeep();
void SndConfirmBeep();
#endif /* SOUND_FUNC_H */ #endif /* SOUND_FUNC_H */

View File

@ -7,6 +7,7 @@
/** @file station_cmd.cpp Handling of station tiles. */ /** @file station_cmd.cpp Handling of station tiles. */
#include "core/enum_type.hpp"
#include "stdafx.h" #include "stdafx.h"
#include "core/flatset_type.hpp" #include "core/flatset_type.hpp"
#include "aircraft.h" #include "aircraft.h"
@ -949,125 +950,6 @@ static CommandCost CheckFlatLandRailStation(TileIndex tile_cur, TileIndex north_
return cost; 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. * 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)); 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 * Build rail station
* @param flags operation to perform * @param flags operation to perform
@ -1362,6 +1468,9 @@ CommandCost CmdBuildRailStation(DoCommandFlags flags, TileIndex tile_org, RailTy
w_org = numtracks; 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); bool reuse = (station_to_join != NEW_STATION);
if (!reuse) station_to_join = StationID::Invalid(); if (!reuse) station_to_join = StationID::Invalid();
bool distant_join = (station_to_join != StationID::Invalid()); bool distant_join = (station_to_join != StationID::Invalid());
@ -1376,6 +1485,7 @@ 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) */ /* Make sure the area below consists of clear tiles. (OR tiles belonging to a certain rail station) */
StationID est = StationID::Invalid(); StationID est = StationID::Invalid();
std::vector<Train *> affected_vehicles; std::vector<Train *> affected_vehicles;
/* Add construction and clearing expenses. */ /* Add construction and clearing expenses. */
CommandCost cost = CalculateRailStationCost(new_location, flags, axis, &est, rt, affected_vehicles, spec_class, spec_index, plat_len, numtracks); CommandCost cost = CalculateRailStationCost(new_location, flags, axis, &est, rt, affected_vehicles, spec_class, spec_index, plat_len, numtracks);
if (cost.Failed()) return cost; if (cost.Failed()) return cost;
@ -1423,23 +1533,30 @@ CommandCost CmdBuildRailStation(DoCommandFlags flags, TileIndex tile_org, RailTy
st->cached_anim_triggers.Set(statspec->animation.triggers); 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); std::vector<uint8_t> layouts(numtracks * plat_len);
GetStationLayout(layouts.data(), numtracks, plat_len, statspec); GetStationLayout(layouts.data(), numtracks, plat_len, statspec);
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);
uint8_t numtracks_orig = numtracks; uint8_t numtracks_orig = numtracks;
Company *c = Company::Get(st->owner); Company *c = Company::Get(st->owner);
size_t layout_idx = 0; size_t layout_idx = 0;
TileIndex tile_track = tile_org; TileIndex tile_track = tile_org;
do { do {
TileIndex tile = tile_track; TileIndex tile = tile_track;
int w = plat_len; int w = plat_len;
do { do {
uint8_t layout = layouts[layout_idx++]; uint8_t layout = layouts[layout_idx++];
ret = IsRailStationBridgeAboveOk(tile, statspec, layout);
if (ret.Failed()) {
//return CommandCost::DualErrorMessage(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST, ret.GetErrorMessage()); //FIXME
return ret;
}
if (IsRailStationTile(tile) && HasStationReservation(tile)) { if (IsRailStationTile(tile) && HasStationReservation(tile)) {
/* Check for trains having a reservation for this tile. */ /* Check for trains having a reservation for this tile. */
Train *v = GetTrainForReservation(tile, AxisToTrack(GetRailStationAxis(tile))); Train *v = GetTrainForReservation(tile, AxisToTrack(GetRailStationAxis(tile)));
@ -1913,7 +2030,7 @@ static CommandCost FindJoiningRoadStop(StationID existing_stop, StationID statio
* @param unit_cost The cost to build one road stop of the current type. * @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. * @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{}; DiagDirections invalid_dirs{};
if (is_drive_through) { if (is_drive_through) {
@ -1927,7 +2044,7 @@ CommandCost CalculateRoadStopCost(TileArea tile_area, DoCommandFlags flags, bool
int allowed_z = -1; int allowed_z = -1;
CommandCost cost(EXPENSES_CONSTRUCTION); CommandCost cost(EXPENSES_CONSTRUCTION);
for (TileIndex cur_tile : tile_area) { 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; if (ret.Failed()) return ret;
bool is_preexisting_roadstop = IsTileType(cur_tile, MP_STATION) && IsAnyRoadStop(cur_tile); bool is_preexisting_roadstop = IsTileType(cur_tile, MP_STATION) && IsAnyRoadStop(cur_tile);
@ -2008,7 +2125,7 @@ CommandCost CmdBuildRoadStop(DoCommandFlags flags, TileIndex tile, uint8_t width
unit_cost = _price[is_truck_stop ? PR_BUILD_STATION_TRUCK : PR_BUILD_STATION_BUS]; unit_cost = _price[is_truck_stop ? PR_BUILD_STATION_TRUCK : PR_BUILD_STATION_BUS];
} }
StationID est = StationID::Invalid(); 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; if (cost.Failed()) return cost;
Station *st = nullptr; Station *st = nullptr;
@ -3380,6 +3497,7 @@ draw_default_foundation:
} }
DrawRailTileSeq(ti, t, TO_BUILDINGS, total_offset, relocation, palette); 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) void StationPickerDrawSprite(int x, int y, StationType st, RailType railtype, RoadType roadtype, int image)

View File

@ -47,7 +47,7 @@ static const PalSpriteID _aqueduct_sprite_table_heads[] = {
{SPR_AQUEDUCT_RAMP_SW, PAL_NONE}, {SPR_AQUEDUCT_RAMP_SE, PAL_NONE}, {SPR_AQUEDUCT_RAMP_NE, PAL_NONE}, {SPR_AQUEDUCT_RAMP_NW, PAL_NONE}, {SPR_AQUEDUCT_RAMP_SW, PAL_NONE}, {SPR_AQUEDUCT_RAMP_SE, PAL_NONE}, {SPR_AQUEDUCT_RAMP_NE, PAL_NONE}, {SPR_AQUEDUCT_RAMP_NW, PAL_NONE},
}; };
static const PalSpriteID _bridge_sprite_table_4_0[] = { static const PalSpriteID _bridge_sprite_table_suspension_oxide_north[] = {
{ 0x9A9, PAL_NONE }, { 0x99F, PAL_NONE }, { 0x9B1, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9A9, PAL_NONE }, { 0x99F, PAL_NONE }, { 0x9B1, PAL_NONE }, { 0x0, PAL_NONE },
{ 0x9A5, PAL_NONE }, { 0x997, PAL_NONE }, { 0x9AD, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9A5, PAL_NONE }, { 0x997, PAL_NONE }, { 0x9AD, PAL_NONE }, { 0x0, PAL_NONE },
{ 0x99D, PAL_NONE }, { 0x99F, PAL_NONE }, { 0x9B1, PAL_NONE }, { 0x0, PAL_NONE }, { 0x99D, PAL_NONE }, { 0x99F, PAL_NONE }, { 0x9B1, PAL_NONE }, { 0x0, PAL_NONE },
@ -58,7 +58,7 @@ static const PalSpriteID _bridge_sprite_table_4_0[] = {
{ 0x1116, PAL_NONE }, { 0x997, PAL_NONE }, { 0x9AD, PAL_NONE }, { 0x0, PAL_NONE }, { 0x1116, PAL_NONE }, { 0x997, PAL_NONE }, { 0x9AD, PAL_NONE }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_4_1[] = { static const PalSpriteID _bridge_sprite_table_suspension_oxide_south[] = {
{ 0x9AA, PAL_NONE }, { 0x9A0, PAL_NONE }, { 0x9B2, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9AA, PAL_NONE }, { 0x9A0, PAL_NONE }, { 0x9B2, PAL_NONE }, { 0x0, PAL_NONE },
{ 0x9A6, PAL_NONE }, { 0x998, PAL_NONE }, { 0x9AE, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9A6, PAL_NONE }, { 0x998, PAL_NONE }, { 0x9AE, PAL_NONE }, { 0x0, PAL_NONE },
{ 0x99E, PAL_NONE }, { 0x9A0, PAL_NONE }, { 0x9B2, PAL_NONE }, { 0x0, PAL_NONE }, { 0x99E, PAL_NONE }, { 0x9A0, PAL_NONE }, { 0x9B2, PAL_NONE }, { 0x0, PAL_NONE },
@ -69,7 +69,7 @@ static const PalSpriteID _bridge_sprite_table_4_1[] = {
{ 0x1117, PAL_NONE }, { 0x998, PAL_NONE }, { 0x9AE, PAL_NONE }, { 0x0, PAL_NONE }, { 0x1117, PAL_NONE }, { 0x998, PAL_NONE }, { 0x9AE, PAL_NONE }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_4_2[] = { static const PalSpriteID _bridge_sprite_table_suspension_oxide_inner_north[] = {
{ 0x9AC, PAL_NONE }, { 0x9A4, PAL_NONE }, { 0x9B4, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9AC, PAL_NONE }, { 0x9A4, PAL_NONE }, { 0x9B4, PAL_NONE }, { 0x0, PAL_NONE },
{ 0x9A8, PAL_NONE }, { 0x99C, PAL_NONE }, { 0x9B0, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9A8, PAL_NONE }, { 0x99C, PAL_NONE }, { 0x9B0, PAL_NONE }, { 0x0, PAL_NONE },
{ 0x9A2, PAL_NONE }, { 0x9A4, PAL_NONE }, { 0x9B4, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9A2, PAL_NONE }, { 0x9A4, PAL_NONE }, { 0x9B4, PAL_NONE }, { 0x0, PAL_NONE },
@ -80,7 +80,7 @@ static const PalSpriteID _bridge_sprite_table_4_2[] = {
{ 0x1119, PAL_NONE }, { 0x99C, PAL_NONE }, { 0x9B0, PAL_NONE }, { 0x0, PAL_NONE }, { 0x1119, PAL_NONE }, { 0x99C, PAL_NONE }, { 0x9B0, PAL_NONE }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_4_3[] = { static const PalSpriteID _bridge_sprite_table_suspension_oxide_inner_south[] = {
{ 0x9AB, PAL_NONE }, { 0x9A3, PAL_NONE }, { 0x9B3, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9AB, PAL_NONE }, { 0x9A3, PAL_NONE }, { 0x9B3, PAL_NONE }, { 0x0, PAL_NONE },
{ 0x9A7, PAL_NONE }, { 0x99B, PAL_NONE }, { 0x9AF, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9A7, PAL_NONE }, { 0x99B, PAL_NONE }, { 0x9AF, PAL_NONE }, { 0x0, PAL_NONE },
{ 0x9A1, PAL_NONE }, { 0x9A3, PAL_NONE }, { 0x9B3, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9A1, PAL_NONE }, { 0x9A3, PAL_NONE }, { 0x9B3, PAL_NONE }, { 0x0, PAL_NONE },
@ -91,7 +91,7 @@ static const PalSpriteID _bridge_sprite_table_4_3[] = {
{ 0x1118, PAL_NONE }, { 0x99B, PAL_NONE }, { 0x9AF, PAL_NONE }, { 0x0, PAL_NONE }, { 0x1118, PAL_NONE }, { 0x99B, PAL_NONE }, { 0x9AF, PAL_NONE }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_4_4[] = { static const PalSpriteID _bridge_sprite_table_suspension_oxide_middle_odd[] = {
{ 0x9B6, PAL_NONE }, { 0x9BA, PAL_NONE }, { 0x9BC, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9B6, PAL_NONE }, { 0x9BA, PAL_NONE }, { 0x9BC, PAL_NONE }, { 0x0, PAL_NONE },
{ 0x9B5, PAL_NONE }, { 0x9B9, PAL_NONE }, { 0x9BB, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9B5, PAL_NONE }, { 0x9B9, PAL_NONE }, { 0x9BB, PAL_NONE }, { 0x0, PAL_NONE },
{ 0x9B8, PAL_NONE }, { 0x9BA, PAL_NONE }, { 0x9BC, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9B8, PAL_NONE }, { 0x9BA, PAL_NONE }, { 0x9BC, PAL_NONE }, { 0x0, PAL_NONE },
@ -102,7 +102,7 @@ static const PalSpriteID _bridge_sprite_table_4_4[] = {
{ 0x111E, PAL_NONE }, { 0x9B9, PAL_NONE }, { 0x9BB, PAL_NONE }, { 0x0, PAL_NONE }, { 0x111E, PAL_NONE }, { 0x9B9, PAL_NONE }, { 0x9BB, PAL_NONE }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_4_5[] = { static const PalSpriteID _bridge_sprite_table_suspension_middle_even[] = {
{ 0x9BD, PAL_NONE }, { 0x9C1, PAL_NONE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9BD, PAL_NONE }, { 0x9C1, PAL_NONE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
{ 0x9BE, PAL_NONE }, { 0x9C2, PAL_NONE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9BE, PAL_NONE }, { 0x9C2, PAL_NONE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
{ 0x9BF, PAL_NONE }, { 0x9C1, PAL_NONE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9BF, PAL_NONE }, { 0x9C1, PAL_NONE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
@ -113,7 +113,7 @@ static const PalSpriteID _bridge_sprite_table_4_5[] = {
{ 0x1121, PAL_NONE }, { 0x9C2, PAL_NONE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0x1121, PAL_NONE }, { 0x9C2, PAL_NONE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_4_6[] = { static const PalSpriteID _bridge_sprite_table_generic_oxide_heads[] = {
{ 0x986, PAL_NONE }, { 0x988, PAL_NONE }, { 0x985, PAL_NONE }, { 0x987, PAL_NONE }, { 0x986, PAL_NONE }, { 0x988, PAL_NONE }, { 0x985, PAL_NONE }, { 0x987, PAL_NONE },
{ 0x98A, PAL_NONE }, { 0x98C, PAL_NONE }, { 0x989, PAL_NONE }, { 0x98B, PAL_NONE }, { 0x98A, PAL_NONE }, { 0x98C, PAL_NONE }, { 0x989, PAL_NONE }, { 0x98B, PAL_NONE },
{ 0x98E, PAL_NONE }, { 0x990, PAL_NONE }, { 0x98D, PAL_NONE }, { 0x98F, PAL_NONE }, { 0x98E, PAL_NONE }, { 0x990, PAL_NONE }, { 0x98D, PAL_NONE }, { 0x98F, PAL_NONE },
@ -124,7 +124,7 @@ static const PalSpriteID _bridge_sprite_table_4_6[] = {
{ 0x1113, PAL_NONE }, { 0x1115, PAL_NONE }, { 0x1112, PAL_NONE }, { 0x1114, PAL_NONE }, { 0x1113, PAL_NONE }, { 0x1115, PAL_NONE }, { 0x1112, PAL_NONE }, { 0x1114, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_5_0[] = { static const PalSpriteID _bridge_sprite_table_suspension_yellow_north[] = {
{ 0x9A9, PALETTE_TO_STRUCT_YELLOW }, { 0x99F, PALETTE_TO_STRUCT_YELLOW }, { 0x9B1, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x9A9, PALETTE_TO_STRUCT_YELLOW }, { 0x99F, PALETTE_TO_STRUCT_YELLOW }, { 0x9B1, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
{ 0x9A5, PALETTE_TO_STRUCT_YELLOW }, { 0x997, PALETTE_TO_STRUCT_YELLOW }, { 0x9AD, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x9A5, PALETTE_TO_STRUCT_YELLOW }, { 0x997, PALETTE_TO_STRUCT_YELLOW }, { 0x9AD, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
{ 0x99D, PALETTE_TO_STRUCT_YELLOW }, { 0x99F, PALETTE_TO_STRUCT_YELLOW }, { 0x9B1, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x99D, PALETTE_TO_STRUCT_YELLOW }, { 0x99F, PALETTE_TO_STRUCT_YELLOW }, { 0x9B1, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
@ -135,7 +135,7 @@ static const PalSpriteID _bridge_sprite_table_5_0[] = {
{ 0x1116, PALETTE_TO_STRUCT_YELLOW }, { 0x997, PALETTE_TO_STRUCT_YELLOW }, { 0x9AD, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x1116, PALETTE_TO_STRUCT_YELLOW }, { 0x997, PALETTE_TO_STRUCT_YELLOW }, { 0x9AD, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_5_1[] = { static const PalSpriteID _bridge_sprite_table_suspension_yellow_south[] = {
{ 0x9AA, PALETTE_TO_STRUCT_YELLOW }, { 0x9A0, PALETTE_TO_STRUCT_YELLOW }, { 0x9B2, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x9AA, PALETTE_TO_STRUCT_YELLOW }, { 0x9A0, PALETTE_TO_STRUCT_YELLOW }, { 0x9B2, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
{ 0x9A6, PALETTE_TO_STRUCT_YELLOW }, { 0x998, PALETTE_TO_STRUCT_YELLOW }, { 0x9AE, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x9A6, PALETTE_TO_STRUCT_YELLOW }, { 0x998, PALETTE_TO_STRUCT_YELLOW }, { 0x9AE, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
{ 0x99E, PALETTE_TO_STRUCT_YELLOW }, { 0x9A0, PALETTE_TO_STRUCT_YELLOW }, { 0x9B2, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x99E, PALETTE_TO_STRUCT_YELLOW }, { 0x9A0, PALETTE_TO_STRUCT_YELLOW }, { 0x9B2, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
@ -146,7 +146,7 @@ static const PalSpriteID _bridge_sprite_table_5_1[] = {
{ 0x1117, PALETTE_TO_STRUCT_YELLOW }, { 0x998, PALETTE_TO_STRUCT_YELLOW }, { 0x9AE, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x1117, PALETTE_TO_STRUCT_YELLOW }, { 0x998, PALETTE_TO_STRUCT_YELLOW }, { 0x9AE, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_5_2[] = { static const PalSpriteID _bridge_sprite_table_suspension_yellow_inner_north[] = {
{ 0x9AC, PALETTE_TO_STRUCT_YELLOW }, { 0x9A4, PALETTE_TO_STRUCT_YELLOW }, { 0x9B4, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x9AC, PALETTE_TO_STRUCT_YELLOW }, { 0x9A4, PALETTE_TO_STRUCT_YELLOW }, { 0x9B4, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
{ 0x9A8, PALETTE_TO_STRUCT_YELLOW }, { 0x99C, PALETTE_TO_STRUCT_YELLOW }, { 0x9B0, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x9A8, PALETTE_TO_STRUCT_YELLOW }, { 0x99C, PALETTE_TO_STRUCT_YELLOW }, { 0x9B0, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
{ 0x9A2, PALETTE_TO_STRUCT_YELLOW }, { 0x9A4, PALETTE_TO_STRUCT_YELLOW }, { 0x9B4, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x9A2, PALETTE_TO_STRUCT_YELLOW }, { 0x9A4, PALETTE_TO_STRUCT_YELLOW }, { 0x9B4, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
@ -157,7 +157,7 @@ static const PalSpriteID _bridge_sprite_table_5_2[] = {
{ 0x1119, PALETTE_TO_STRUCT_YELLOW }, { 0x99C, PALETTE_TO_STRUCT_YELLOW }, { 0x9B0, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x1119, PALETTE_TO_STRUCT_YELLOW }, { 0x99C, PALETTE_TO_STRUCT_YELLOW }, { 0x9B0, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_5_3[] = { static const PalSpriteID _bridge_sprite_table_suspension_yellow_inner_south[] = {
{ 0x9AB, PALETTE_TO_STRUCT_YELLOW }, { 0x9A3, PALETTE_TO_STRUCT_YELLOW }, { 0x9B3, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x9AB, PALETTE_TO_STRUCT_YELLOW }, { 0x9A3, PALETTE_TO_STRUCT_YELLOW }, { 0x9B3, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
{ 0x9A7, PALETTE_TO_STRUCT_YELLOW }, { 0x99B, PALETTE_TO_STRUCT_YELLOW }, { 0x9AF, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x9A7, PALETTE_TO_STRUCT_YELLOW }, { 0x99B, PALETTE_TO_STRUCT_YELLOW }, { 0x9AF, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
{ 0x9A1, PALETTE_TO_STRUCT_YELLOW }, { 0x9A3, PALETTE_TO_STRUCT_YELLOW }, { 0x9B3, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x9A1, PALETTE_TO_STRUCT_YELLOW }, { 0x9A3, PALETTE_TO_STRUCT_YELLOW }, { 0x9B3, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
@ -168,7 +168,7 @@ static const PalSpriteID _bridge_sprite_table_5_3[] = {
{ 0x1118, PALETTE_TO_STRUCT_YELLOW }, { 0x99B, PALETTE_TO_STRUCT_YELLOW }, { 0x9AF, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x1118, PALETTE_TO_STRUCT_YELLOW }, { 0x99B, PALETTE_TO_STRUCT_YELLOW }, { 0x9AF, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_5_4[] = { static const PalSpriteID _bridge_sprite_table_suspension_yellow_middle_odd[] = {
{ 0x9B6, PALETTE_TO_STRUCT_YELLOW }, { 0x9BA, PALETTE_TO_STRUCT_YELLOW }, { 0x9BC, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x9B6, PALETTE_TO_STRUCT_YELLOW }, { 0x9BA, PALETTE_TO_STRUCT_YELLOW }, { 0x9BC, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
{ 0x9B5, PALETTE_TO_STRUCT_YELLOW }, { 0x9B9, PALETTE_TO_STRUCT_YELLOW }, { 0x9BB, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x9B5, PALETTE_TO_STRUCT_YELLOW }, { 0x9B9, PALETTE_TO_STRUCT_YELLOW }, { 0x9BB, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
{ 0x9B8, PALETTE_TO_STRUCT_YELLOW }, { 0x9BA, PALETTE_TO_STRUCT_YELLOW }, { 0x9BC, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x9B8, PALETTE_TO_STRUCT_YELLOW }, { 0x9BA, PALETTE_TO_STRUCT_YELLOW }, { 0x9BC, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
@ -179,7 +179,7 @@ static const PalSpriteID _bridge_sprite_table_5_4[] = {
{ 0x111E, PALETTE_TO_STRUCT_YELLOW }, { 0x9B9, PALETTE_TO_STRUCT_YELLOW }, { 0x9BB, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x111E, PALETTE_TO_STRUCT_YELLOW }, { 0x9B9, PALETTE_TO_STRUCT_YELLOW }, { 0x9BB, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_5_5[] = { static const PalSpriteID _bridge_sprite_table_suspension_yellow_middle_even[] = {
{ 0x9BD, PALETTE_TO_STRUCT_YELLOW }, { 0x9C1, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9BD, PALETTE_TO_STRUCT_YELLOW }, { 0x9C1, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
{ 0x9BE, PALETTE_TO_STRUCT_YELLOW }, { 0x9C2, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9BE, PALETTE_TO_STRUCT_YELLOW }, { 0x9C2, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
{ 0x9BF, PALETTE_TO_STRUCT_YELLOW }, { 0x9C1, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9BF, PALETTE_TO_STRUCT_YELLOW }, { 0x9C1, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
@ -190,7 +190,7 @@ static const PalSpriteID _bridge_sprite_table_5_5[] = {
{ 0x1121, PALETTE_TO_STRUCT_YELLOW }, { 0x9C2, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0x1121, PALETTE_TO_STRUCT_YELLOW }, { 0x9C2, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_5_6[] = { static const PalSpriteID _bridge_sprite_table_generic_yellow_heads[] = {
{ 0x986, PAL_NONE }, { 0x988, PAL_NONE }, { 0x985, PAL_NONE }, { 0x987, PAL_NONE }, { 0x986, PAL_NONE }, { 0x988, PAL_NONE }, { 0x985, PAL_NONE }, { 0x987, PAL_NONE },
{ 0x98A, PAL_NONE }, { 0x98C, PAL_NONE }, { 0x989, PAL_NONE }, { 0x98B, PAL_NONE }, { 0x98A, PAL_NONE }, { 0x98C, PAL_NONE }, { 0x989, PAL_NONE }, { 0x98B, PAL_NONE },
{ 0x98E, PALETTE_TO_STRUCT_YELLOW }, { 0x990, PALETTE_TO_STRUCT_YELLOW }, { 0x98D, PALETTE_TO_STRUCT_YELLOW }, { 0x98F, PALETTE_TO_STRUCT_YELLOW }, { 0x98E, PALETTE_TO_STRUCT_YELLOW }, { 0x990, PALETTE_TO_STRUCT_YELLOW }, { 0x98D, PALETTE_TO_STRUCT_YELLOW }, { 0x98F, PALETTE_TO_STRUCT_YELLOW },
@ -201,7 +201,7 @@ static const PalSpriteID _bridge_sprite_table_5_6[] = {
{ 0x1113, PALETTE_TO_STRUCT_YELLOW }, { 0x1115, PALETTE_TO_STRUCT_YELLOW }, { 0x1112, PALETTE_TO_STRUCT_YELLOW }, { 0x1114, PALETTE_TO_STRUCT_YELLOW }, { 0x1113, PALETTE_TO_STRUCT_YELLOW }, { 0x1115, PALETTE_TO_STRUCT_YELLOW }, { 0x1112, PALETTE_TO_STRUCT_YELLOW }, { 0x1114, PALETTE_TO_STRUCT_YELLOW },
}; };
static const PalSpriteID _bridge_sprite_table_6_0[] = { static const PalSpriteID _bridge_sprite_table_cantilever_oxide_north[] = {
{ 0x9CD, PAL_NONE }, { 0x9D9, PAL_NONE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9CD, PAL_NONE }, { 0x9D9, PAL_NONE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
{ 0x9CE, PAL_NONE }, { 0x9DA, PAL_NONE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9CE, PAL_NONE }, { 0x9DA, PAL_NONE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
{ 0x9D3, PAL_NONE }, { 0x9D9, PAL_NONE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9D3, PAL_NONE }, { 0x9D9, PAL_NONE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
@ -212,7 +212,7 @@ static const PalSpriteID _bridge_sprite_table_6_0[] = {
{ 0x1125, PAL_NONE }, { 0x9DA, PAL_NONE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0x1125, PAL_NONE }, { 0x9DA, PAL_NONE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_6_1[] = { static const PalSpriteID _bridge_sprite_table_cantilever_oxide_south[] = {
{ 0x9CB, PAL_NONE }, { 0x9D7, PAL_NONE }, { 0x9DD, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9CB, PAL_NONE }, { 0x9D7, PAL_NONE }, { 0x9DD, PAL_NONE }, { 0x0, PAL_NONE },
{ 0x9D0, PAL_NONE }, { 0x9DC, PAL_NONE }, { 0x9E0, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9D0, PAL_NONE }, { 0x9DC, PAL_NONE }, { 0x9E0, PAL_NONE }, { 0x0, PAL_NONE },
{ 0x9D1, PAL_NONE }, { 0x9D7, PAL_NONE }, { 0x9DD, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9D1, PAL_NONE }, { 0x9D7, PAL_NONE }, { 0x9DD, PAL_NONE }, { 0x0, PAL_NONE },
@ -223,7 +223,7 @@ static const PalSpriteID _bridge_sprite_table_6_1[] = {
{ 0x1127, PAL_NONE }, { 0x9DC, PAL_NONE }, { 0x9E0, PAL_NONE }, { 0x0, PAL_NONE }, { 0x1127, PAL_NONE }, { 0x9DC, PAL_NONE }, { 0x9E0, PAL_NONE }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_6_2[] = { static const PalSpriteID _bridge_sprite_table_cantilever_oxide_middle[] = {
{ 0x9CC, PAL_NONE }, { 0x9D8, PAL_NONE }, { 0x9DE, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9CC, PAL_NONE }, { 0x9D8, PAL_NONE }, { 0x9DE, PAL_NONE }, { 0x0, PAL_NONE },
{ 0x9CF, PAL_NONE }, { 0x9DB, PAL_NONE }, { 0x9DF, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9CF, PAL_NONE }, { 0x9DB, PAL_NONE }, { 0x9DF, PAL_NONE }, { 0x0, PAL_NONE },
{ 0x9D2, PAL_NONE }, { 0x9D8, PAL_NONE }, { 0x9DE, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9D2, PAL_NONE }, { 0x9D8, PAL_NONE }, { 0x9DE, PAL_NONE }, { 0x0, PAL_NONE },
@ -234,7 +234,7 @@ static const PalSpriteID _bridge_sprite_table_6_2[] = {
{ 0x1126, PAL_NONE }, { 0x9DB, PAL_NONE }, { 0x9DF, PAL_NONE }, { 0x0, PAL_NONE }, { 0x1126, PAL_NONE }, { 0x9DB, PAL_NONE }, { 0x9DF, PAL_NONE }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_6_3[] = { static const PalSpriteID _bridge_sprite_table_cantilever_oxide_heads[] = {
{ 0x986, PAL_NONE }, { 0x988, PAL_NONE }, { 0x985, PAL_NONE }, { 0x987, PAL_NONE }, { 0x986, PAL_NONE }, { 0x988, PAL_NONE }, { 0x985, PAL_NONE }, { 0x987, PAL_NONE },
{ 0x98A, PAL_NONE }, { 0x98C, PAL_NONE }, { 0x989, PAL_NONE }, { 0x98B, PAL_NONE }, { 0x98A, PAL_NONE }, { 0x98C, PAL_NONE }, { 0x989, PAL_NONE }, { 0x98B, PAL_NONE },
{ 0x98E, PAL_NONE }, { 0x990, PAL_NONE }, { 0x98D, PAL_NONE }, { 0x98F, PAL_NONE }, { 0x98E, PAL_NONE }, { 0x990, PAL_NONE }, { 0x98D, PAL_NONE }, { 0x98F, PAL_NONE },
@ -245,7 +245,7 @@ static const PalSpriteID _bridge_sprite_table_6_3[] = {
{ 0x1113, PAL_NONE }, { 0x1115, PAL_NONE }, { 0x1112, PAL_NONE }, { 0x1114, PAL_NONE }, { 0x1113, PAL_NONE }, { 0x1115, PAL_NONE }, { 0x1112, PAL_NONE }, { 0x1114, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_7_0[] = { static const PalSpriteID _bridge_sprite_table_cantilever_brown_north[] = {
{ 0x9CD, PALETTE_TO_STRUCT_BROWN }, { 0x9D9, PALETTE_TO_STRUCT_BROWN }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9CD, PALETTE_TO_STRUCT_BROWN }, { 0x9D9, PALETTE_TO_STRUCT_BROWN }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
{ 0x9CE, PALETTE_TO_STRUCT_BROWN }, { 0x9DA, PALETTE_TO_STRUCT_BROWN }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9CE, PALETTE_TO_STRUCT_BROWN }, { 0x9DA, PALETTE_TO_STRUCT_BROWN }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
{ 0x9D3, PALETTE_TO_STRUCT_BROWN }, { 0x9D9, PALETTE_TO_STRUCT_BROWN }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9D3, PALETTE_TO_STRUCT_BROWN }, { 0x9D9, PALETTE_TO_STRUCT_BROWN }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
@ -256,7 +256,7 @@ static const PalSpriteID _bridge_sprite_table_7_0[] = {
{ 0x1125, PALETTE_TO_STRUCT_BROWN }, { 0x9DA, PALETTE_TO_STRUCT_BROWN }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0x1125, PALETTE_TO_STRUCT_BROWN }, { 0x9DA, PALETTE_TO_STRUCT_BROWN }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_7_1[] = { static const PalSpriteID _bridge_sprite_table_cantilever_brown_south[] = {
{ 0x9CB, PALETTE_TO_STRUCT_BROWN }, { 0x9D7, PALETTE_TO_STRUCT_BROWN }, { 0x9DD, PALETTE_TO_STRUCT_BROWN }, { 0x0, PAL_NONE }, { 0x9CB, PALETTE_TO_STRUCT_BROWN }, { 0x9D7, PALETTE_TO_STRUCT_BROWN }, { 0x9DD, PALETTE_TO_STRUCT_BROWN }, { 0x0, PAL_NONE },
{ 0x9D0, PALETTE_TO_STRUCT_BROWN }, { 0x9DC, PALETTE_TO_STRUCT_BROWN }, { 0x9E0, PALETTE_TO_STRUCT_BROWN }, { 0x0, PAL_NONE }, { 0x9D0, PALETTE_TO_STRUCT_BROWN }, { 0x9DC, PALETTE_TO_STRUCT_BROWN }, { 0x9E0, PALETTE_TO_STRUCT_BROWN }, { 0x0, PAL_NONE },
{ 0x9D1, PALETTE_TO_STRUCT_BROWN }, { 0x9D7, PALETTE_TO_STRUCT_BROWN }, { 0x9DD, PALETTE_TO_STRUCT_BROWN }, { 0x0, PAL_NONE }, { 0x9D1, PALETTE_TO_STRUCT_BROWN }, { 0x9D7, PALETTE_TO_STRUCT_BROWN }, { 0x9DD, PALETTE_TO_STRUCT_BROWN }, { 0x0, PAL_NONE },
@ -267,7 +267,7 @@ static const PalSpriteID _bridge_sprite_table_7_1[] = {
{ 0x1127, PALETTE_TO_STRUCT_BROWN }, { 0x9DC, PALETTE_TO_STRUCT_BROWN }, { 0x9E0, PALETTE_TO_STRUCT_BROWN }, { 0x0, PAL_NONE }, { 0x1127, PALETTE_TO_STRUCT_BROWN }, { 0x9DC, PALETTE_TO_STRUCT_BROWN }, { 0x9E0, PALETTE_TO_STRUCT_BROWN }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_7_2[] = { static const PalSpriteID _bridge_sprite_table_cantilever_brown_middle[] = {
{ 0x9CC, PALETTE_TO_STRUCT_BROWN }, { 0x9D8, PALETTE_TO_STRUCT_BROWN }, { 0x9DE, PALETTE_TO_STRUCT_BROWN }, { 0x0, PAL_NONE }, { 0x9CC, PALETTE_TO_STRUCT_BROWN }, { 0x9D8, PALETTE_TO_STRUCT_BROWN }, { 0x9DE, PALETTE_TO_STRUCT_BROWN }, { 0x0, PAL_NONE },
{ 0x9CF, PALETTE_TO_STRUCT_BROWN }, { 0x9DB, PALETTE_TO_STRUCT_BROWN }, { 0x9DF, PALETTE_TO_STRUCT_BROWN }, { 0x0, PAL_NONE }, { 0x9CF, PALETTE_TO_STRUCT_BROWN }, { 0x9DB, PALETTE_TO_STRUCT_BROWN }, { 0x9DF, PALETTE_TO_STRUCT_BROWN }, { 0x0, PAL_NONE },
{ 0x9D2, PALETTE_TO_STRUCT_BROWN }, { 0x9D8, PALETTE_TO_STRUCT_BROWN }, { 0x9DE, PALETTE_TO_STRUCT_BROWN }, { 0x0, PAL_NONE }, { 0x9D2, PALETTE_TO_STRUCT_BROWN }, { 0x9D8, PALETTE_TO_STRUCT_BROWN }, { 0x9DE, PALETTE_TO_STRUCT_BROWN }, { 0x0, PAL_NONE },
@ -278,7 +278,7 @@ static const PalSpriteID _bridge_sprite_table_7_2[] = {
{ 0x1126, PALETTE_TO_STRUCT_BROWN }, { 0x9DB, PALETTE_TO_STRUCT_BROWN }, { 0x9DF, PALETTE_TO_STRUCT_BROWN }, { 0x0, PAL_NONE }, { 0x1126, PALETTE_TO_STRUCT_BROWN }, { 0x9DB, PALETTE_TO_STRUCT_BROWN }, { 0x9DF, PALETTE_TO_STRUCT_BROWN }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_7_3[] = { static const PalSpriteID _bridge_sprite_table_cantilever_brown_heads[] = {
{ 0x986, PAL_NONE }, { 0x988, PAL_NONE }, { 0x985, PAL_NONE }, { 0x987, PAL_NONE }, { 0x986, PAL_NONE }, { 0x988, PAL_NONE }, { 0x985, PAL_NONE }, { 0x987, PAL_NONE },
{ 0x98A, PAL_NONE }, { 0x98C, PAL_NONE }, { 0x989, PAL_NONE }, { 0x98B, PAL_NONE }, { 0x98A, PAL_NONE }, { 0x98C, PAL_NONE }, { 0x989, PAL_NONE }, { 0x98B, PAL_NONE },
{ 0x98E, PALETTE_TO_STRUCT_BROWN }, { 0x990, PALETTE_TO_STRUCT_BROWN }, { 0x98D, PALETTE_TO_STRUCT_BROWN }, { 0x98F, PALETTE_TO_STRUCT_BROWN }, { 0x98E, PALETTE_TO_STRUCT_BROWN }, { 0x990, PALETTE_TO_STRUCT_BROWN }, { 0x98D, PALETTE_TO_STRUCT_BROWN }, { 0x98F, PALETTE_TO_STRUCT_BROWN },
@ -289,7 +289,7 @@ static const PalSpriteID _bridge_sprite_table_7_3[] = {
{ 0x1113, PALETTE_TO_STRUCT_BROWN }, { 0x1115, PALETTE_TO_STRUCT_BROWN }, { 0x1112, PALETTE_TO_STRUCT_BROWN }, { 0x1114, PALETTE_TO_STRUCT_BROWN }, { 0x1113, PALETTE_TO_STRUCT_BROWN }, { 0x1115, PALETTE_TO_STRUCT_BROWN }, { 0x1112, PALETTE_TO_STRUCT_BROWN }, { 0x1114, PALETTE_TO_STRUCT_BROWN },
}; };
static const PalSpriteID _bridge_sprite_table_8_0[] = { static const PalSpriteID _bridge_sprite_table_cantilever_red_north[] = {
{ 0x9CD, PALETTE_TO_STRUCT_RED }, { 0x9D9, PALETTE_TO_STRUCT_RED }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9CD, PALETTE_TO_STRUCT_RED }, { 0x9D9, PALETTE_TO_STRUCT_RED }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
{ 0x9CE, PALETTE_TO_STRUCT_RED }, { 0x9DA, PALETTE_TO_STRUCT_RED }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9CE, PALETTE_TO_STRUCT_RED }, { 0x9DA, PALETTE_TO_STRUCT_RED }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
{ 0x9D3, PALETTE_TO_STRUCT_RED }, { 0x9D9, PALETTE_TO_STRUCT_RED }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9D3, PALETTE_TO_STRUCT_RED }, { 0x9D9, PALETTE_TO_STRUCT_RED }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
@ -300,7 +300,7 @@ static const PalSpriteID _bridge_sprite_table_8_0[] = {
{ 0x1125, PALETTE_TO_STRUCT_RED }, { 0x9DA, PALETTE_TO_STRUCT_RED }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0x1125, PALETTE_TO_STRUCT_RED }, { 0x9DA, PALETTE_TO_STRUCT_RED }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_8_1[] = { static const PalSpriteID _bridge_sprite_table_cantilever_red_south[] = {
{ 0x9CB, PALETTE_TO_STRUCT_RED }, { 0x9D7, PALETTE_TO_STRUCT_RED }, { 0x9DD, PALETTE_TO_STRUCT_RED }, { 0x0, PAL_NONE }, { 0x9CB, PALETTE_TO_STRUCT_RED }, { 0x9D7, PALETTE_TO_STRUCT_RED }, { 0x9DD, PALETTE_TO_STRUCT_RED }, { 0x0, PAL_NONE },
{ 0x9D0, PALETTE_TO_STRUCT_RED }, { 0x9DC, PALETTE_TO_STRUCT_RED }, { 0x9E0, PALETTE_TO_STRUCT_RED }, { 0x0, PAL_NONE }, { 0x9D0, PALETTE_TO_STRUCT_RED }, { 0x9DC, PALETTE_TO_STRUCT_RED }, { 0x9E0, PALETTE_TO_STRUCT_RED }, { 0x0, PAL_NONE },
{ 0x9D1, PALETTE_TO_STRUCT_RED }, { 0x9D7, PALETTE_TO_STRUCT_RED }, { 0x9DD, PALETTE_TO_STRUCT_RED }, { 0x0, PAL_NONE }, { 0x9D1, PALETTE_TO_STRUCT_RED }, { 0x9D7, PALETTE_TO_STRUCT_RED }, { 0x9DD, PALETTE_TO_STRUCT_RED }, { 0x0, PAL_NONE },
@ -311,7 +311,7 @@ static const PalSpriteID _bridge_sprite_table_8_1[] = {
{ 0x1127, PALETTE_TO_STRUCT_RED }, { 0x9DC, PALETTE_TO_STRUCT_RED }, { 0x9E0, PALETTE_TO_STRUCT_RED }, { 0x0, PAL_NONE }, { 0x1127, PALETTE_TO_STRUCT_RED }, { 0x9DC, PALETTE_TO_STRUCT_RED }, { 0x9E0, PALETTE_TO_STRUCT_RED }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_8_2[] = { static const PalSpriteID _bridge_sprite_table_cantilever_red_middle[] = {
{ 0x9CC, PALETTE_TO_STRUCT_RED }, { 0x9D8, PALETTE_TO_STRUCT_RED }, { 0x9DE, PALETTE_TO_STRUCT_RED }, { 0x0, PAL_NONE }, { 0x9CC, PALETTE_TO_STRUCT_RED }, { 0x9D8, PALETTE_TO_STRUCT_RED }, { 0x9DE, PALETTE_TO_STRUCT_RED }, { 0x0, PAL_NONE },
{ 0x9CF, PALETTE_TO_STRUCT_RED }, { 0x9DB, PALETTE_TO_STRUCT_RED }, { 0x9DF, PALETTE_TO_STRUCT_RED }, { 0x0, PAL_NONE }, { 0x9CF, PALETTE_TO_STRUCT_RED }, { 0x9DB, PALETTE_TO_STRUCT_RED }, { 0x9DF, PALETTE_TO_STRUCT_RED }, { 0x0, PAL_NONE },
{ 0x9D2, PALETTE_TO_STRUCT_RED }, { 0x9D8, PALETTE_TO_STRUCT_RED }, { 0x9DE, PALETTE_TO_STRUCT_RED }, { 0x0, PAL_NONE }, { 0x9D2, PALETTE_TO_STRUCT_RED }, { 0x9D8, PALETTE_TO_STRUCT_RED }, { 0x9DE, PALETTE_TO_STRUCT_RED }, { 0x0, PAL_NONE },
@ -322,7 +322,7 @@ static const PalSpriteID _bridge_sprite_table_8_2[] = {
{ 0x1126, PALETTE_TO_STRUCT_RED }, { 0x9DB, PALETTE_TO_STRUCT_RED }, { 0x9DF, PALETTE_TO_STRUCT_RED }, { 0x0, PAL_NONE }, { 0x1126, PALETTE_TO_STRUCT_RED }, { 0x9DB, PALETTE_TO_STRUCT_RED }, { 0x9DF, PALETTE_TO_STRUCT_RED }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_8_3[] = { static const PalSpriteID _bridge_sprite_table_cantilever_red_heads[] = {
{ 0x986, PAL_NONE }, { 0x988, PAL_NONE }, { 0x985, PAL_NONE }, { 0x987, PAL_NONE }, { 0x986, PAL_NONE }, { 0x988, PAL_NONE }, { 0x985, PAL_NONE }, { 0x987, PAL_NONE },
{ 0x98A, PAL_NONE }, { 0x98C, PAL_NONE }, { 0x989, PAL_NONE }, { 0x98B, PAL_NONE }, { 0x98A, PAL_NONE }, { 0x98C, PAL_NONE }, { 0x989, PAL_NONE }, { 0x98B, PAL_NONE },
{ 0x98E, PALETTE_TO_STRUCT_RED }, { 0x990, PALETTE_TO_STRUCT_RED }, { 0x98D, PALETTE_TO_STRUCT_RED }, { 0x98F, PALETTE_TO_STRUCT_RED }, { 0x98E, PALETTE_TO_STRUCT_RED }, { 0x990, PALETTE_TO_STRUCT_RED }, { 0x98D, PALETTE_TO_STRUCT_RED }, { 0x98F, PALETTE_TO_STRUCT_RED },
@ -399,7 +399,7 @@ static const PalSpriteID _bridge_sprite_table_archgirder_heads[] = {
MW( SPR_BTGEN_MGLV_RAMP_X_DOWN ), MW( SPR_BTGEN_MGLV_RAMP_Y_DOWN ), MW( SPR_BTGEN_MGLV_RAMP_X_UP ), MW( SPR_BTGEN_MGLV_RAMP_Y_UP ), MW( SPR_BTGEN_MGLV_RAMP_X_DOWN ), MW( SPR_BTGEN_MGLV_RAMP_Y_DOWN ), MW( SPR_BTGEN_MGLV_RAMP_X_UP ), MW( SPR_BTGEN_MGLV_RAMP_Y_UP ),
}; };
static const PalSpriteID _bridge_sprite_table_concrete_suspended_A[] = { static const PalSpriteID _bridge_sprite_table_suspension_concrete_north[] = {
MC( SPR_BTSUS_RAIL_X_REAR_TILE_A ), MC( SPR_BTSUS_X_FRONT_TILE_A ), MC( SPR_BTSUS_X_PILLAR_TILE_A ), MN( 0x0 ), MC( SPR_BTSUS_RAIL_X_REAR_TILE_A ), MC( SPR_BTSUS_X_FRONT_TILE_A ), MC( SPR_BTSUS_X_PILLAR_TILE_A ), MN( 0x0 ),
MC( SPR_BTSUS_RAIL_Y_REAR_TILE_A ), MC( SPR_BTSUS_Y_FRONT_TILE_A ), MC( SPR_BTSUS_Y_PILLAR_TILE_A ), MN( 0x0 ), MC( SPR_BTSUS_RAIL_Y_REAR_TILE_A ), MC( SPR_BTSUS_Y_FRONT_TILE_A ), MC( SPR_BTSUS_Y_PILLAR_TILE_A ), MN( 0x0 ),
MC( SPR_BTSUS_ROAD_X_REAR_TILE_A ), MC( SPR_BTSUS_X_FRONT_TILE_A ), MC( SPR_BTSUS_X_PILLAR_TILE_A ), MN( 0x0 ), MC( SPR_BTSUS_ROAD_X_REAR_TILE_A ), MC( SPR_BTSUS_X_FRONT_TILE_A ), MC( SPR_BTSUS_X_PILLAR_TILE_A ), MN( 0x0 ),
@ -410,7 +410,7 @@ static const PalSpriteID _bridge_sprite_table_concrete_suspended_A[] = {
MC( SPR_BTSUS_MGLV_Y_REAR_TILE_A ), MC( SPR_BTSUS_Y_FRONT_TILE_A ), MC( SPR_BTSUS_Y_PILLAR_TILE_A ), MN( 0x0 ), MC( SPR_BTSUS_MGLV_Y_REAR_TILE_A ), MC( SPR_BTSUS_Y_FRONT_TILE_A ), MC( SPR_BTSUS_Y_PILLAR_TILE_A ), MN( 0x0 ),
}; };
static const PalSpriteID _bridge_sprite_table_concrete_suspended_B[] = { static const PalSpriteID _bridge_sprite_table_suspension_concrete_south[] = {
MC( SPR_BTSUS_RAIL_X_REAR_TILE_B ), MC( SPR_BTSUS_X_FRONT_TILE_B ), MC( SPR_BTSUS_X_PILLAR_TILE_B ), MN( 0x0 ), MC( SPR_BTSUS_RAIL_X_REAR_TILE_B ), MC( SPR_BTSUS_X_FRONT_TILE_B ), MC( SPR_BTSUS_X_PILLAR_TILE_B ), MN( 0x0 ),
MC( SPR_BTSUS_RAIL_Y_REAR_TILE_B ), MC( SPR_BTSUS_Y_FRONT_TILE_B ), MC( SPR_BTSUS_Y_PILLAR_TILE_B ), MN( 0x0 ), MC( SPR_BTSUS_RAIL_Y_REAR_TILE_B ), MC( SPR_BTSUS_Y_FRONT_TILE_B ), MC( SPR_BTSUS_Y_PILLAR_TILE_B ), MN( 0x0 ),
MC( SPR_BTSUS_ROAD_X_REAR_TILE_B ), MC( SPR_BTSUS_X_FRONT_TILE_B ), MC( SPR_BTSUS_X_PILLAR_TILE_B ), MN( 0x0 ), MC( SPR_BTSUS_ROAD_X_REAR_TILE_B ), MC( SPR_BTSUS_X_FRONT_TILE_B ), MC( SPR_BTSUS_X_PILLAR_TILE_B ), MN( 0x0 ),
@ -421,7 +421,7 @@ static const PalSpriteID _bridge_sprite_table_concrete_suspended_B[] = {
MC( SPR_BTSUS_MGLV_Y_REAR_TILE_B ), MC( SPR_BTSUS_Y_FRONT_TILE_B ), MC( SPR_BTSUS_Y_PILLAR_TILE_B ), MN( 0x0 ), MC( SPR_BTSUS_MGLV_Y_REAR_TILE_B ), MC( SPR_BTSUS_Y_FRONT_TILE_B ), MC( SPR_BTSUS_Y_PILLAR_TILE_B ), MN( 0x0 ),
}; };
static const PalSpriteID _bridge_sprite_table_concrete_suspended_C[] = { static const PalSpriteID _bridge_sprite_table_suspension_concrete_inner_north[] = {
MC( SPR_BTSUS_RAIL_X_REAR_TILE_C ), MC( SPR_BTSUS_X_FRONT_TILE_C ), MC( SPR_BTSUS_X_PILLAR_TILE_C ), MN( 0x0 ), MC( SPR_BTSUS_RAIL_X_REAR_TILE_C ), MC( SPR_BTSUS_X_FRONT_TILE_C ), MC( SPR_BTSUS_X_PILLAR_TILE_C ), MN( 0x0 ),
MC( SPR_BTSUS_RAIL_Y_REAR_TILE_C ), MC( SPR_BTSUS_Y_FRONT_TILE_C ), MC( SPR_BTSUS_Y_PILLAR_TILE_C ), MN( 0x0 ), MC( SPR_BTSUS_RAIL_Y_REAR_TILE_C ), MC( SPR_BTSUS_Y_FRONT_TILE_C ), MC( SPR_BTSUS_Y_PILLAR_TILE_C ), MN( 0x0 ),
MC( SPR_BTSUS_ROAD_X_REAR_TILE_C ), MC( SPR_BTSUS_X_FRONT_TILE_C ), MC( SPR_BTSUS_X_PILLAR_TILE_C ), MN( 0x0 ), MC( SPR_BTSUS_ROAD_X_REAR_TILE_C ), MC( SPR_BTSUS_X_FRONT_TILE_C ), MC( SPR_BTSUS_X_PILLAR_TILE_C ), MN( 0x0 ),
@ -432,7 +432,7 @@ static const PalSpriteID _bridge_sprite_table_concrete_suspended_C[] = {
MC( SPR_BTSUS_MGLV_Y_REAR_TILE_C ), MC( SPR_BTSUS_Y_FRONT_TILE_C ), MC( SPR_BTSUS_Y_PILLAR_TILE_C ), MN( 0x0 ), MC( SPR_BTSUS_MGLV_Y_REAR_TILE_C ), MC( SPR_BTSUS_Y_FRONT_TILE_C ), MC( SPR_BTSUS_Y_PILLAR_TILE_C ), MN( 0x0 ),
}; };
static const PalSpriteID _bridge_sprite_table_concrete_suspended_D[] = { static const PalSpriteID _bridge_sprite_table_suspension_concrete_inner_south[] = {
MC( SPR_BTSUS_RAIL_X_REAR_TILE_D ), MC( SPR_BTSUS_X_FRONT_TILE_D ), MC( SPR_BTSUS_X_PILLAR_TILE_D ), MN( 0x0 ), MC( SPR_BTSUS_RAIL_X_REAR_TILE_D ), MC( SPR_BTSUS_X_FRONT_TILE_D ), MC( SPR_BTSUS_X_PILLAR_TILE_D ), MN( 0x0 ),
MC( SPR_BTSUS_RAIL_Y_REAR_TILE_D ), MC( SPR_BTSUS_Y_FRONT_TILE_D ), MC( SPR_BTSUS_Y_PILLAR_TILE_D ), MN( 0x0 ), MC( SPR_BTSUS_RAIL_Y_REAR_TILE_D ), MC( SPR_BTSUS_Y_FRONT_TILE_D ), MC( SPR_BTSUS_Y_PILLAR_TILE_D ), MN( 0x0 ),
MC( SPR_BTSUS_ROAD_X_REAR_TILE_D ), MC( SPR_BTSUS_X_FRONT_TILE_D ), MC( SPR_BTSUS_X_PILLAR_TILE_D ), MN( 0x0 ), MC( SPR_BTSUS_ROAD_X_REAR_TILE_D ), MC( SPR_BTSUS_X_FRONT_TILE_D ), MC( SPR_BTSUS_X_PILLAR_TILE_D ), MN( 0x0 ),
@ -443,7 +443,7 @@ static const PalSpriteID _bridge_sprite_table_concrete_suspended_D[] = {
MC( SPR_BTSUS_MGLV_Y_REAR_TILE_D ), MC( SPR_BTSUS_Y_FRONT_TILE_D ), MC( SPR_BTSUS_Y_PILLAR_TILE_D ), MN( 0x0 ), MC( SPR_BTSUS_MGLV_Y_REAR_TILE_D ), MC( SPR_BTSUS_Y_FRONT_TILE_D ), MC( SPR_BTSUS_Y_PILLAR_TILE_D ), MN( 0x0 ),
}; };
static const PalSpriteID _bridge_sprite_table_concrete_suspended_E[] = { static const PalSpriteID _bridge_sprite_table_suspension_concrete_middle_odd[] = {
MC( SPR_BTSUS_RAIL_X_REAR_TILE_E ), MC( SPR_BTSUS_X_FRONT_TILE_E ), MC( SPR_BTSUS_X_PILLAR_TILE_E ), MN( 0x0 ), MC( SPR_BTSUS_RAIL_X_REAR_TILE_E ), MC( SPR_BTSUS_X_FRONT_TILE_E ), MC( SPR_BTSUS_X_PILLAR_TILE_E ), MN( 0x0 ),
MC( SPR_BTSUS_RAIL_Y_REAR_TILE_E ), MC( SPR_BTSUS_Y_FRONT_TILE_E ), MC( SPR_BTSUS_Y_PILLAR_TILE_E ), MN( 0x0 ), MC( SPR_BTSUS_RAIL_Y_REAR_TILE_E ), MC( SPR_BTSUS_Y_FRONT_TILE_E ), MC( SPR_BTSUS_Y_PILLAR_TILE_E ), MN( 0x0 ),
MC( SPR_BTSUS_ROAD_X_REAR_TILE_E ), MC( SPR_BTSUS_X_FRONT_TILE_E ), MC( SPR_BTSUS_X_PILLAR_TILE_E ), MN( 0x0 ), MC( SPR_BTSUS_ROAD_X_REAR_TILE_E ), MC( SPR_BTSUS_X_FRONT_TILE_E ), MC( SPR_BTSUS_X_PILLAR_TILE_E ), MN( 0x0 ),
@ -454,7 +454,7 @@ static const PalSpriteID _bridge_sprite_table_concrete_suspended_E[] = {
MC( SPR_BTSUS_MGLV_Y_REAR_TILE_E ), MC( SPR_BTSUS_Y_FRONT_TILE_E ), MC( SPR_BTSUS_Y_PILLAR_TILE_E ), MN( 0x0 ), MC( SPR_BTSUS_MGLV_Y_REAR_TILE_E ), MC( SPR_BTSUS_Y_FRONT_TILE_E ), MC( SPR_BTSUS_Y_PILLAR_TILE_E ), MN( 0x0 ),
}; };
static const PalSpriteID _bridge_sprite_table_concrete_suspended_F[] = { static const PalSpriteID _bridge_sprite_table_suspension_concrete_middle_even[] = {
MC( SPR_BTSUS_RAIL_X_REAR_TILE_F ), MC( SPR_BTSUS_X_FRONT ), MN( 0x0 ), MN( 0x0 ), MC( SPR_BTSUS_RAIL_X_REAR_TILE_F ), MC( SPR_BTSUS_X_FRONT ), MN( 0x0 ), MN( 0x0 ),
MC( SPR_BTSUS_RAIL_Y_REAR_TILE_F ), MC( SPR_BTSUS_Y_FRONT ), MN( 0x0 ), MN( 0x0 ), MC( SPR_BTSUS_RAIL_Y_REAR_TILE_F ), MC( SPR_BTSUS_Y_FRONT ), MN( 0x0 ), MN( 0x0 ),
MC( SPR_BTSUS_ROAD_X_REAR_TILE_F ), MC( SPR_BTSUS_X_FRONT ), MN( 0x0 ), MN( 0x0 ), MC( SPR_BTSUS_ROAD_X_REAR_TILE_F ), MC( SPR_BTSUS_X_FRONT ), MN( 0x0 ), MN( 0x0 ),
@ -465,7 +465,7 @@ static const PalSpriteID _bridge_sprite_table_concrete_suspended_F[] = {
MC( SPR_BTSUS_MGLV_Y_REAR_TILE_F ), MC( SPR_BTSUS_Y_FRONT ), MN( 0x0 ), MN( 0x0 ), MC( SPR_BTSUS_MGLV_Y_REAR_TILE_F ), MC( SPR_BTSUS_Y_FRONT ), MN( 0x0 ), MN( 0x0 ),
}; };
static const PalSpriteID _bridge_sprite_table_concrete_suspended_heads[] = { static const PalSpriteID _bridge_sprite_table_generic_concrete_heads[] = {
MN( SPR_BTGEN_RAIL_X_SLOPE_UP ), MN( SPR_BTGEN_RAIL_Y_SLOPE_UP ), MN( SPR_BTGEN_RAIL_X_SLOPE_DOWN ), MN( SPR_BTGEN_RAIL_Y_SLOPE_DOWN ), MN( SPR_BTGEN_RAIL_X_SLOPE_UP ), MN( SPR_BTGEN_RAIL_Y_SLOPE_UP ), MN( SPR_BTGEN_RAIL_X_SLOPE_DOWN ), MN( SPR_BTGEN_RAIL_Y_SLOPE_DOWN ),
MN( SPR_BTGEN_RAIL_RAMP_X_DOWN ), MN( SPR_BTGEN_RAIL_RAMP_Y_DOWN ), MN( SPR_BTGEN_RAIL_RAMP_X_UP ), MN( SPR_BTGEN_RAIL_RAMP_Y_UP ), MN( SPR_BTGEN_RAIL_RAMP_X_DOWN ), MN( SPR_BTGEN_RAIL_RAMP_Y_DOWN ), MN( SPR_BTGEN_RAIL_RAMP_X_UP ), MN( SPR_BTGEN_RAIL_RAMP_Y_UP ),
MC( SPR_BTGEN_ROAD_X_SLOPE_UP ), MC( SPR_BTGEN_ROAD_Y_SLOPE_UP ), MC( SPR_BTGEN_ROAD_X_SLOPE_DOWN ), MC( SPR_BTGEN_ROAD_Y_SLOPE_DOWN ), MC( SPR_BTGEN_ROAD_X_SLOPE_UP ), MC( SPR_BTGEN_ROAD_Y_SLOPE_UP ), MC( SPR_BTGEN_ROAD_X_SLOPE_DOWN ), MC( SPR_BTGEN_ROAD_Y_SLOPE_DOWN ),
@ -476,7 +476,7 @@ static const PalSpriteID _bridge_sprite_table_concrete_suspended_heads[] = {
MC( SPR_BTGEN_MGLV_RAMP_X_DOWN ), MC( SPR_BTGEN_MGLV_RAMP_Y_DOWN ), MC( SPR_BTGEN_MGLV_RAMP_X_UP ), MC( SPR_BTGEN_MGLV_RAMP_Y_UP ), MC( SPR_BTGEN_MGLV_RAMP_X_DOWN ), MC( SPR_BTGEN_MGLV_RAMP_Y_DOWN ), MC( SPR_BTGEN_MGLV_RAMP_X_UP ), MC( SPR_BTGEN_MGLV_RAMP_Y_UP ),
}; };
static const PalSpriteID _bridge_sprite_table_9_0[] = { static const PalSpriteID _bridge_sprite_table_girder_middle[] = {
{ 0x9F9, PAL_NONE }, { 0x9FD, PAL_NONE }, { 0x9C9, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9F9, PAL_NONE }, { 0x9FD, PAL_NONE }, { 0x9C9, PAL_NONE }, { 0x0, PAL_NONE },
{ 0x9FA, PAL_NONE }, { 0x9FE, PAL_NONE }, { 0x9CA, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9FA, PAL_NONE }, { 0x9FE, PAL_NONE }, { 0x9CA, PAL_NONE }, { 0x0, PAL_NONE },
{ 0x9FB, PAL_NONE }, { 0x9FD, PAL_NONE }, { 0x9C9, PAL_NONE }, { 0x0, PAL_NONE }, { 0x9FB, PAL_NONE }, { 0x9FD, PAL_NONE }, { 0x9C9, PAL_NONE }, { 0x0, PAL_NONE },
@ -487,7 +487,7 @@ static const PalSpriteID _bridge_sprite_table_9_0[] = {
{ 0x1133, PAL_NONE }, { 0x9FE, PAL_NONE }, { 0x9CA, PAL_NONE }, { 0x0, PAL_NONE }, { 0x1133, PAL_NONE }, { 0x9FE, PAL_NONE }, { 0x9CA, PAL_NONE }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_10_0[] = { static const PalSpriteID _bridge_sprite_table_tubular_oxide_north[] = {
{ 0xA0B, PAL_NONE }, { 0xA01, PAL_NONE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0xA0B, PAL_NONE }, { 0xA01, PAL_NONE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
{ 0xA0C, PAL_NONE }, { 0xA02, PAL_NONE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0xA0C, PAL_NONE }, { 0xA02, PAL_NONE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
{ 0xA11, PAL_NONE }, { 0xA01, PAL_NONE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0xA11, PAL_NONE }, { 0xA01, PAL_NONE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
@ -498,7 +498,7 @@ static const PalSpriteID _bridge_sprite_table_10_0[] = {
{ 0xA1E, PAL_NONE }, { 0xA02, PAL_NONE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0xA1E, PAL_NONE }, { 0xA02, PAL_NONE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_10_1[] = { static const PalSpriteID _bridge_sprite_table_tubular_oxide_south[] = {
{ 0xA09, PAL_NONE }, { 0x9FF, PAL_NONE }, { 0xA05, PAL_NONE }, { 0x0, PAL_NONE }, { 0xA09, PAL_NONE }, { 0x9FF, PAL_NONE }, { 0xA05, PAL_NONE }, { 0x0, PAL_NONE },
{ 0xA0E, PAL_NONE }, { 0xA04, PAL_NONE }, { 0xA08, PAL_NONE }, { 0x0, PAL_NONE }, { 0xA0E, PAL_NONE }, { 0xA04, PAL_NONE }, { 0xA08, PAL_NONE }, { 0x0, PAL_NONE },
{ 0xA0F, PAL_NONE }, { 0x9FF, PAL_NONE }, { 0xA05, PAL_NONE }, { 0x0, PAL_NONE }, { 0xA0F, PAL_NONE }, { 0x9FF, PAL_NONE }, { 0xA05, PAL_NONE }, { 0x0, PAL_NONE },
@ -509,7 +509,7 @@ static const PalSpriteID _bridge_sprite_table_10_1[] = {
{ 0xA20, PAL_NONE }, { 0xA04, PAL_NONE }, { 0xA08, PAL_NONE }, { 0x0, PAL_NONE }, { 0xA20, PAL_NONE }, { 0xA04, PAL_NONE }, { 0xA08, PAL_NONE }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_10_2[] = { static const PalSpriteID _bridge_sprite_table_tubular_oxide_middle[] = {
{ 0xA0A, PAL_NONE }, { 0xA00, PAL_NONE }, { 0xA06, PAL_NONE }, { 0x0, PAL_NONE }, { 0xA0A, PAL_NONE }, { 0xA00, PAL_NONE }, { 0xA06, PAL_NONE }, { 0x0, PAL_NONE },
{ 0xA0D, PAL_NONE }, { 0xA03, PAL_NONE }, { 0xA07, PAL_NONE }, { 0x0, PAL_NONE }, { 0xA0D, PAL_NONE }, { 0xA03, PAL_NONE }, { 0xA07, PAL_NONE }, { 0x0, PAL_NONE },
{ 0xA10, PAL_NONE }, { 0xA00, PAL_NONE }, { 0xA06, PAL_NONE }, { 0x0, PAL_NONE }, { 0xA10, PAL_NONE }, { 0xA00, PAL_NONE }, { 0xA06, PAL_NONE }, { 0x0, PAL_NONE },
@ -520,7 +520,7 @@ static const PalSpriteID _bridge_sprite_table_10_2[] = {
{ 0xA1F, PAL_NONE }, { 0xA03, PAL_NONE }, { 0xA07, PAL_NONE }, { 0x0, PAL_NONE }, { 0xA1F, PAL_NONE }, { 0xA03, PAL_NONE }, { 0xA07, PAL_NONE }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_11_0[] = { static const PalSpriteID _bridge_sprite_table_tubular_yellow_north[] = {
{ 0xA0B, PALETTE_TO_STRUCT_YELLOW }, { 0xA01, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0xA0B, PALETTE_TO_STRUCT_YELLOW }, { 0xA01, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
{ 0xA0C, PALETTE_TO_STRUCT_YELLOW }, { 0xA02, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0xA0C, PALETTE_TO_STRUCT_YELLOW }, { 0xA02, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
{ 0xA11, PALETTE_TO_STRUCT_YELLOW }, { 0xA01, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0xA11, PALETTE_TO_STRUCT_YELLOW }, { 0xA01, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
@ -531,7 +531,7 @@ static const PalSpriteID _bridge_sprite_table_11_0[] = {
{ 0xA1E, PALETTE_TO_STRUCT_YELLOW }, { 0xA02, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0xA1E, PALETTE_TO_STRUCT_YELLOW }, { 0xA02, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_11_1[] = { static const PalSpriteID _bridge_sprite_table_tubular_yellow_south[] = {
{ 0xA09, PALETTE_TO_STRUCT_YELLOW }, { 0x9FF, PALETTE_TO_STRUCT_YELLOW }, { 0xA05, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0xA09, PALETTE_TO_STRUCT_YELLOW }, { 0x9FF, PALETTE_TO_STRUCT_YELLOW }, { 0xA05, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
{ 0xA0E, PALETTE_TO_STRUCT_YELLOW }, { 0xA04, PALETTE_TO_STRUCT_YELLOW }, { 0xA08, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0xA0E, PALETTE_TO_STRUCT_YELLOW }, { 0xA04, PALETTE_TO_STRUCT_YELLOW }, { 0xA08, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
{ 0xA0F, PALETTE_TO_STRUCT_YELLOW }, { 0x9FF, PALETTE_TO_STRUCT_YELLOW }, { 0xA05, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0xA0F, PALETTE_TO_STRUCT_YELLOW }, { 0x9FF, PALETTE_TO_STRUCT_YELLOW }, { 0xA05, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
@ -542,7 +542,7 @@ static const PalSpriteID _bridge_sprite_table_11_1[] = {
{ 0xA20, PALETTE_TO_STRUCT_YELLOW }, { 0xA04, PALETTE_TO_STRUCT_YELLOW }, { 0xA08, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0xA20, PALETTE_TO_STRUCT_YELLOW }, { 0xA04, PALETTE_TO_STRUCT_YELLOW }, { 0xA08, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_11_2[] = { static const PalSpriteID _bridge_sprite_table_tubular_yellow_middle[] = {
{ 0xA0A, PALETTE_TO_STRUCT_YELLOW }, { 0xA00, PALETTE_TO_STRUCT_YELLOW }, { 0xA06, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0xA0A, PALETTE_TO_STRUCT_YELLOW }, { 0xA00, PALETTE_TO_STRUCT_YELLOW }, { 0xA06, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
{ 0xA0D, PALETTE_TO_STRUCT_YELLOW }, { 0xA03, PALETTE_TO_STRUCT_YELLOW }, { 0xA07, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0xA0D, PALETTE_TO_STRUCT_YELLOW }, { 0xA03, PALETTE_TO_STRUCT_YELLOW }, { 0xA07, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
{ 0xA10, PALETTE_TO_STRUCT_YELLOW }, { 0xA00, PALETTE_TO_STRUCT_YELLOW }, { 0xA06, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0xA10, PALETTE_TO_STRUCT_YELLOW }, { 0xA00, PALETTE_TO_STRUCT_YELLOW }, { 0xA06, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
@ -553,7 +553,7 @@ static const PalSpriteID _bridge_sprite_table_11_2[] = {
{ 0xA1F, PALETTE_TO_STRUCT_YELLOW }, { 0xA03, PALETTE_TO_STRUCT_YELLOW }, { 0xA07, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE }, { 0xA1F, PALETTE_TO_STRUCT_YELLOW }, { 0xA03, PALETTE_TO_STRUCT_YELLOW }, { 0xA07, PALETTE_TO_STRUCT_YELLOW }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_12_0[] = { static const PalSpriteID _bridge_sprite_table_tubular_silicon_north[] = {
{ 0xA0B, PALETTE_TO_STRUCT_CONCRETE }, { 0xA01, PALETTE_TO_STRUCT_CONCRETE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0xA0B, PALETTE_TO_STRUCT_CONCRETE }, { 0xA01, PALETTE_TO_STRUCT_CONCRETE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
{ 0xA0C, PALETTE_TO_STRUCT_CONCRETE }, { 0xA02, PALETTE_TO_STRUCT_CONCRETE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0xA0C, PALETTE_TO_STRUCT_CONCRETE }, { 0xA02, PALETTE_TO_STRUCT_CONCRETE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
{ 0xA11, PALETTE_TO_STRUCT_CONCRETE }, { 0xA01, PALETTE_TO_STRUCT_CONCRETE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0xA11, PALETTE_TO_STRUCT_CONCRETE }, { 0xA01, PALETTE_TO_STRUCT_CONCRETE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
@ -564,7 +564,7 @@ static const PalSpriteID _bridge_sprite_table_12_0[] = {
{ 0xA1E, PALETTE_TO_STRUCT_CONCRETE }, { 0xA02, PALETTE_TO_STRUCT_CONCRETE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE }, { 0xA1E, PALETTE_TO_STRUCT_CONCRETE }, { 0xA02, PALETTE_TO_STRUCT_CONCRETE }, { 0x0, PAL_NONE }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_12_1[] = { static const PalSpriteID _bridge_sprite_table_tubular_silicon_south[] = {
{ 0xA09, PALETTE_TO_STRUCT_CONCRETE }, { 0x9FF, PALETTE_TO_STRUCT_CONCRETE }, { 0xA05, PALETTE_TO_STRUCT_CONCRETE }, { 0x0, PAL_NONE }, { 0xA09, PALETTE_TO_STRUCT_CONCRETE }, { 0x9FF, PALETTE_TO_STRUCT_CONCRETE }, { 0xA05, PALETTE_TO_STRUCT_CONCRETE }, { 0x0, PAL_NONE },
{ 0xA0E, PALETTE_TO_STRUCT_CONCRETE }, { 0xA04, PALETTE_TO_STRUCT_CONCRETE }, { 0xA08, PALETTE_TO_STRUCT_CONCRETE }, { 0x0, PAL_NONE }, { 0xA0E, PALETTE_TO_STRUCT_CONCRETE }, { 0xA04, PALETTE_TO_STRUCT_CONCRETE }, { 0xA08, PALETTE_TO_STRUCT_CONCRETE }, { 0x0, PAL_NONE },
{ 0xA0F, PALETTE_TO_STRUCT_CONCRETE }, { 0x9FF, PALETTE_TO_STRUCT_CONCRETE }, { 0xA05, PALETTE_TO_STRUCT_CONCRETE }, { 0x0, PAL_NONE }, { 0xA0F, PALETTE_TO_STRUCT_CONCRETE }, { 0x9FF, PALETTE_TO_STRUCT_CONCRETE }, { 0xA05, PALETTE_TO_STRUCT_CONCRETE }, { 0x0, PAL_NONE },
@ -575,7 +575,7 @@ static const PalSpriteID _bridge_sprite_table_12_1[] = {
{ 0xA20, PALETTE_TO_STRUCT_CONCRETE }, { 0xA04, PALETTE_TO_STRUCT_CONCRETE }, { 0xA08, PALETTE_TO_STRUCT_CONCRETE }, { 0x0, PAL_NONE }, { 0xA20, PALETTE_TO_STRUCT_CONCRETE }, { 0xA04, PALETTE_TO_STRUCT_CONCRETE }, { 0xA08, PALETTE_TO_STRUCT_CONCRETE }, { 0x0, PAL_NONE },
}; };
static const PalSpriteID _bridge_sprite_table_12_2[] = { static const PalSpriteID _bridge_sprite_table_tubular_silicon_middle[] = {
{ 0xA0A, PALETTE_TO_STRUCT_CONCRETE }, { 0xA00, PALETTE_TO_STRUCT_CONCRETE }, { 0xA06, PALETTE_TO_STRUCT_CONCRETE }, { 0x0, PAL_NONE }, { 0xA0A, PALETTE_TO_STRUCT_CONCRETE }, { 0xA00, PALETTE_TO_STRUCT_CONCRETE }, { 0xA06, PALETTE_TO_STRUCT_CONCRETE }, { 0x0, PAL_NONE },
{ 0xA0D, PALETTE_TO_STRUCT_CONCRETE }, { 0xA03, PALETTE_TO_STRUCT_CONCRETE }, { 0xA07, PALETTE_TO_STRUCT_CONCRETE }, { 0x0, PAL_NONE }, { 0xA0D, PALETTE_TO_STRUCT_CONCRETE }, { 0xA03, PALETTE_TO_STRUCT_CONCRETE }, { 0xA07, PALETTE_TO_STRUCT_CONCRETE }, { 0x0, PAL_NONE },
{ 0xA10, PALETTE_TO_STRUCT_CONCRETE }, { 0xA00, PALETTE_TO_STRUCT_CONCRETE }, { 0xA06, PALETTE_TO_STRUCT_CONCRETE }, { 0x0, PAL_NONE }, { 0xA10, PALETTE_TO_STRUCT_CONCRETE }, { 0xA00, PALETTE_TO_STRUCT_CONCRETE }, { 0xA06, PALETTE_TO_STRUCT_CONCRETE }, { 0x0, PAL_NONE },
@ -596,64 +596,64 @@ static const std::span<const PalSpriteID> _bridge_sprite_table_archgirder[] = {
_bridge_sprite_table_archgirder_heads, _bridge_sprite_table_archgirder_heads,
}; };
static const std::span<const PalSpriteID> _bridge_sprite_table_4[] = { static const std::span<const PalSpriteID> _bridge_sprite_table_suspension_oxide[] = {
_bridge_sprite_table_4_0, _bridge_sprite_table_suspension_oxide_north,
_bridge_sprite_table_4_1, _bridge_sprite_table_suspension_oxide_south,
_bridge_sprite_table_4_2, _bridge_sprite_table_suspension_oxide_inner_north,
_bridge_sprite_table_4_3, _bridge_sprite_table_suspension_oxide_inner_south,
_bridge_sprite_table_4_4, _bridge_sprite_table_suspension_oxide_middle_odd,
_bridge_sprite_table_4_5, _bridge_sprite_table_suspension_middle_even,
_bridge_sprite_table_4_6, _bridge_sprite_table_generic_oxide_heads,
}; };
static const std::span<const PalSpriteID> _bridge_sprite_table_5[] = { static const std::span<const PalSpriteID> _bridge_sprite_table_suspension_yellow[] = {
_bridge_sprite_table_5_0, _bridge_sprite_table_suspension_yellow_north,
_bridge_sprite_table_5_1, _bridge_sprite_table_suspension_yellow_south,
_bridge_sprite_table_5_2, _bridge_sprite_table_suspension_yellow_inner_north,
_bridge_sprite_table_5_3, _bridge_sprite_table_suspension_yellow_inner_south,
_bridge_sprite_table_5_4, _bridge_sprite_table_suspension_yellow_middle_odd,
_bridge_sprite_table_5_5, _bridge_sprite_table_suspension_yellow_middle_even,
_bridge_sprite_table_5_6, _bridge_sprite_table_generic_yellow_heads,
}; };
static const std::span<const PalSpriteID> _bridge_sprite_table_concrete_suspended[] = { static const std::span<const PalSpriteID> _bridge_sprite_table_suspension_concrete[] = {
_bridge_sprite_table_concrete_suspended_A, _bridge_sprite_table_suspension_concrete_north,
_bridge_sprite_table_concrete_suspended_B, _bridge_sprite_table_suspension_concrete_south,
_bridge_sprite_table_concrete_suspended_C, _bridge_sprite_table_suspension_concrete_inner_north,
_bridge_sprite_table_concrete_suspended_D, _bridge_sprite_table_suspension_concrete_inner_south,
_bridge_sprite_table_concrete_suspended_E, _bridge_sprite_table_suspension_concrete_middle_odd,
_bridge_sprite_table_concrete_suspended_F, _bridge_sprite_table_suspension_concrete_middle_even,
_bridge_sprite_table_concrete_suspended_heads, _bridge_sprite_table_generic_concrete_heads,
}; };
static const std::span<const PalSpriteID> _bridge_sprite_table_6[] = { static const std::span<const PalSpriteID> _bridge_sprite_table_cantilever_oxide[] = {
_bridge_sprite_table_6_0, _bridge_sprite_table_cantilever_oxide_north,
_bridge_sprite_table_6_1, _bridge_sprite_table_cantilever_oxide_south,
_bridge_sprite_table_6_2, _bridge_sprite_table_cantilever_oxide_middle,
_bridge_sprite_table_6_2, _bridge_sprite_table_cantilever_oxide_middle,
_bridge_sprite_table_6_2, _bridge_sprite_table_cantilever_oxide_middle,
_bridge_sprite_table_6_2, _bridge_sprite_table_cantilever_oxide_middle,
_bridge_sprite_table_6_3, _bridge_sprite_table_cantilever_oxide_heads,
}; };
static const std::span<const PalSpriteID> _bridge_sprite_table_7[] = { static const std::span<const PalSpriteID> _bridge_sprite_table_cantilever_brown[] = {
_bridge_sprite_table_7_0, _bridge_sprite_table_cantilever_brown_north,
_bridge_sprite_table_7_1, _bridge_sprite_table_cantilever_brown_south,
_bridge_sprite_table_7_2, _bridge_sprite_table_cantilever_brown_middle,
_bridge_sprite_table_7_2, _bridge_sprite_table_cantilever_brown_middle,
_bridge_sprite_table_7_2, _bridge_sprite_table_cantilever_brown_middle,
_bridge_sprite_table_7_2, _bridge_sprite_table_cantilever_brown_middle,
_bridge_sprite_table_7_3, _bridge_sprite_table_cantilever_brown_heads,
}; };
static const std::span<const PalSpriteID> _bridge_sprite_table_8[] = { static const std::span<const PalSpriteID> _bridge_sprite_table_cantilever_red[] = {
_bridge_sprite_table_8_0, _bridge_sprite_table_cantilever_red_north,
_bridge_sprite_table_8_1, _bridge_sprite_table_cantilever_red_south,
_bridge_sprite_table_8_2, _bridge_sprite_table_cantilever_red_middle,
_bridge_sprite_table_8_2, _bridge_sprite_table_cantilever_red_middle,
_bridge_sprite_table_8_2, _bridge_sprite_table_cantilever_red_middle,
_bridge_sprite_table_8_2, _bridge_sprite_table_cantilever_red_middle,
_bridge_sprite_table_8_3, _bridge_sprite_table_cantilever_red_heads,
}; };
static const std::span<const PalSpriteID> _bridge_sprite_table_wood[] = { static const std::span<const PalSpriteID> _bridge_sprite_table_wood[] = {
@ -676,60 +676,60 @@ static const std::span<const PalSpriteID> _bridge_sprite_table_concrete[] = {
_bridge_sprite_table_concrete_heads, _bridge_sprite_table_concrete_heads,
}; };
static const std::span<const PalSpriteID> _bridge_sprite_table_9[] = { static const std::span<const PalSpriteID> _bridge_sprite_table_girder[] = {
_bridge_sprite_table_9_0, _bridge_sprite_table_girder_middle,
_bridge_sprite_table_9_0, _bridge_sprite_table_girder_middle,
_bridge_sprite_table_9_0, _bridge_sprite_table_girder_middle,
_bridge_sprite_table_9_0, _bridge_sprite_table_girder_middle,
_bridge_sprite_table_9_0, _bridge_sprite_table_girder_middle,
_bridge_sprite_table_9_0, _bridge_sprite_table_girder_middle,
_bridge_sprite_table_4_6, _bridge_sprite_table_generic_oxide_heads,
}; };
static const std::span<const PalSpriteID> _bridge_sprite_table_10[] = { static const std::span<const PalSpriteID> _bridge_sprite_table_tubular_oxide[] = {
_bridge_sprite_table_10_0, _bridge_sprite_table_tubular_oxide_north,
_bridge_sprite_table_10_1, _bridge_sprite_table_tubular_oxide_south,
_bridge_sprite_table_10_2, _bridge_sprite_table_tubular_oxide_middle,
_bridge_sprite_table_10_2, _bridge_sprite_table_tubular_oxide_middle,
_bridge_sprite_table_10_2, _bridge_sprite_table_tubular_oxide_middle,
_bridge_sprite_table_10_2, _bridge_sprite_table_tubular_oxide_middle,
_bridge_sprite_table_4_6, _bridge_sprite_table_generic_oxide_heads,
}; };
static const std::span<const PalSpriteID> _bridge_sprite_table_11[] = { static const std::span<const PalSpriteID> _bridge_sprite_table_tubular_yellow[] = {
_bridge_sprite_table_11_0, _bridge_sprite_table_tubular_yellow_north,
_bridge_sprite_table_11_1, _bridge_sprite_table_tubular_yellow_south,
_bridge_sprite_table_11_2, _bridge_sprite_table_tubular_yellow_middle,
_bridge_sprite_table_11_2, _bridge_sprite_table_tubular_yellow_middle,
_bridge_sprite_table_11_2, _bridge_sprite_table_tubular_yellow_middle,
_bridge_sprite_table_11_2, _bridge_sprite_table_tubular_yellow_middle,
_bridge_sprite_table_5_6, _bridge_sprite_table_generic_yellow_heads,
}; };
static const std::span<const PalSpriteID> _bridge_sprite_table_12[] = { static const std::span<const PalSpriteID> _bridge_sprite_table_tubular_silicon[] = {
_bridge_sprite_table_12_0, _bridge_sprite_table_tubular_silicon_north,
_bridge_sprite_table_12_1, _bridge_sprite_table_tubular_silicon_south,
_bridge_sprite_table_12_2, _bridge_sprite_table_tubular_silicon_middle,
_bridge_sprite_table_12_2, _bridge_sprite_table_tubular_silicon_middle,
_bridge_sprite_table_12_2, _bridge_sprite_table_tubular_silicon_middle,
_bridge_sprite_table_12_2, _bridge_sprite_table_tubular_silicon_middle,
_bridge_sprite_table_concrete_suspended_heads, _bridge_sprite_table_generic_concrete_heads,
}; };
static const std::span<const std::span<const PalSpriteID>> _bridge_sprite_table[MAX_BRIDGES] = { static const std::span<const std::span<const PalSpriteID>> _bridge_sprite_table[MAX_BRIDGES] = {
_bridge_sprite_table_wood, _bridge_sprite_table_wood,
_bridge_sprite_table_concrete, _bridge_sprite_table_concrete,
_bridge_sprite_table_archgirder, _bridge_sprite_table_archgirder,
_bridge_sprite_table_concrete_suspended, _bridge_sprite_table_suspension_concrete,
_bridge_sprite_table_4, _bridge_sprite_table_suspension_oxide,
_bridge_sprite_table_5, _bridge_sprite_table_suspension_yellow,
_bridge_sprite_table_6, _bridge_sprite_table_cantilever_oxide,
_bridge_sprite_table_7, _bridge_sprite_table_cantilever_brown,
_bridge_sprite_table_8, _bridge_sprite_table_cantilever_red,
_bridge_sprite_table_9, _bridge_sprite_table_girder,
_bridge_sprite_table_10, _bridge_sprite_table_tubular_oxide,
_bridge_sprite_table_11, _bridge_sprite_table_tubular_yellow,
_bridge_sprite_table_12 _bridge_sprite_table_tubular_silicon,
}; };
/** /**
@ -745,8 +745,53 @@ static const std::span<const std::span<const PalSpriteID>> _bridge_sprite_table[
* @param nrl description of the rail bridge in query tool * @param nrl description of the rail bridge in query tool
* @param nrd description of the road 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) \ #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} {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[] = { const BridgeSpec _orig_bridge[] = {
/* /*
@ -760,43 +805,43 @@ const BridgeSpec _orig_bridge[] = {
string with description name on rail name on road string with description name on rail name on road
| | | | */ | | | | */
MBR( 0, 0, 0xFFFF, 80, 32, 0xA24, PAL_NONE, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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 #undef MBR

View File

@ -621,7 +621,7 @@ struct ScenarioEditorLandscapeGenerationWindow : Window {
if (!IsInsideMM(size, 1, 8 + 1)) return; if (!IsInsideMM(size, 1, 8 + 1)) return;
_terraform_size = size; _terraform_size = size;
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
this->SetDirty(); this->SetDirty();
break; break;
} }

View File

@ -117,7 +117,7 @@ public:
static void PopupMainToolbarMenu(Window *w, WidgetID widget, DropDownList &&list, int def) static void PopupMainToolbarMenu(Window *w, WidgetID widget, DropDownList &&list, int def)
{ {
ShowDropDownList(w, std::move(list), def, widget, 0, true); ShowDropDownList(w, std::move(list), def, widget, 0, true);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
} }
/** /**
@ -204,7 +204,7 @@ static CallBackFunction ToolbarPauseClick(Window *)
if (_networking && !_network_server) return CBF_NONE; // only server can pause the game if (_networking && !_network_server) return CBF_NONE; // only server can pause the game
if (Command<CMD_PAUSE>::Post(PauseMode::Normal, _pause_mode.None())) { if (Command<CMD_PAUSE>::Post(PauseMode::Normal, _pause_mode.None())) {
if (_settings_client.sound.confirm) SndPlayFx(SND_15_BEEP); SndConfirmBeep();
} }
return CBF_NONE; return CBF_NONE;
} }
@ -220,7 +220,7 @@ static CallBackFunction ToolbarFastForwardClick(Window *)
ChangeGameSpeed(_game_speed == 100); ChangeGameSpeed(_game_speed == 100);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
return CBF_NONE; return CBF_NONE;
} }
@ -291,7 +291,7 @@ static CallBackFunction ToolbarOptionsClick(Window *w)
list.push_back(MakeDropDownListCheckedItem(IsTransparencySet(TO_SIGNS), STR_SETTINGS_MENU_TRANSPARENT_SIGNS, OME_SHOW_STATIONSIGNS)); list.push_back(MakeDropDownListCheckedItem(IsTransparencySet(TO_SIGNS), STR_SETTINGS_MENU_TRANSPARENT_SIGNS, OME_SHOW_STATIONSIGNS));
ShowDropDownList(w, std::move(list), 0, WID_TN_SETTINGS, 140, true); ShowDropDownList(w, std::move(list), 0, WID_TN_SETTINGS, 140, true);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
return CBF_NONE; return CBF_NONE;
} }
@ -684,7 +684,7 @@ static CallBackFunction ToolbarGraphsClick(Window *w)
if (_toolbar_mode != TB_NORMAL) AddDropDownLeagueTableOptions(list); if (_toolbar_mode != TB_NORMAL) AddDropDownLeagueTableOptions(list);
ShowDropDownList(w, std::move(list), GRMN_OPERATING_PROFIT_GRAPH, WID_TN_GRAPHS, 140, true); ShowDropDownList(w, std::move(list), GRMN_OPERATING_PROFIT_GRAPH, WID_TN_GRAPHS, 140, true);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
return CBF_NONE; return CBF_NONE;
} }
@ -697,7 +697,7 @@ static CallBackFunction ToolbarLeagueClick(Window *w)
int selected = list[0]->result; int selected = list[0]->result;
ShowDropDownList(w, std::move(list), selected, WID_TN_LEAGUE, 140, true); ShowDropDownList(w, std::move(list), selected, WID_TN_LEAGUE, 140, true);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
return CBF_NONE; return CBF_NONE;
} }
@ -857,7 +857,7 @@ static CallBackFunction ToolbarZoomInClick(Window *w)
{ {
if (DoZoomInOutWindow(ZOOM_IN, GetMainWindow())) { if (DoZoomInOutWindow(ZOOM_IN, GetMainWindow())) {
w->HandleButtonClick((_game_mode == GM_EDITOR) ? (WidgetID)WID_TE_ZOOM_IN : (WidgetID)WID_TN_ZOOM_IN); w->HandleButtonClick((_game_mode == GM_EDITOR) ? (WidgetID)WID_TE_ZOOM_IN : (WidgetID)WID_TN_ZOOM_IN);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
} }
return CBF_NONE; return CBF_NONE;
} }
@ -868,7 +868,7 @@ static CallBackFunction ToolbarZoomOutClick(Window *w)
{ {
if (DoZoomInOutWindow(ZOOM_OUT, GetMainWindow())) { if (DoZoomInOutWindow(ZOOM_OUT, GetMainWindow())) {
w->HandleButtonClick((_game_mode == GM_EDITOR) ? (WidgetID)WID_TE_ZOOM_OUT : (WidgetID)WID_TN_ZOOM_OUT); w->HandleButtonClick((_game_mode == GM_EDITOR) ? (WidgetID)WID_TE_ZOOM_OUT : (WidgetID)WID_TN_ZOOM_OUT);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
} }
return CBF_NONE; return CBF_NONE;
} }
@ -878,7 +878,7 @@ static CallBackFunction ToolbarZoomOutClick(Window *w)
static CallBackFunction ToolbarBuildRailClick(Window *w) static CallBackFunction ToolbarBuildRailClick(Window *w)
{ {
ShowDropDownList(w, GetRailTypeDropDownList(), _last_built_railtype, WID_TN_RAILS, 140, true); ShowDropDownList(w, GetRailTypeDropDownList(), _last_built_railtype, WID_TN_RAILS, 140, true);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
return CBF_NONE; return CBF_NONE;
} }
@ -900,7 +900,7 @@ static CallBackFunction MenuClickBuildRail(int index)
static CallBackFunction ToolbarBuildRoadClick(Window *w) static CallBackFunction ToolbarBuildRoadClick(Window *w)
{ {
ShowDropDownList(w, GetRoadTypeDropDownList(RTTB_ROAD), _last_built_roadtype, WID_TN_ROADS, 140, true); ShowDropDownList(w, GetRoadTypeDropDownList(RTTB_ROAD), _last_built_roadtype, WID_TN_ROADS, 140, true);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
return CBF_NONE; return CBF_NONE;
} }
@ -922,7 +922,7 @@ static CallBackFunction MenuClickBuildRoad(int index)
static CallBackFunction ToolbarBuildTramClick(Window *w) static CallBackFunction ToolbarBuildTramClick(Window *w)
{ {
ShowDropDownList(w, GetRoadTypeDropDownList(RTTB_TRAM), _last_built_tramtype, WID_TN_TRAMS, 140, true); ShowDropDownList(w, GetRoadTypeDropDownList(RTTB_TRAM), _last_built_tramtype, WID_TN_TRAMS, 140, true);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
return CBF_NONE; return CBF_NONE;
} }
@ -946,7 +946,7 @@ static CallBackFunction ToolbarBuildWaterClick(Window *w)
DropDownList list; DropDownList list;
list.push_back(MakeDropDownListIconItem(SPR_IMG_BUILD_CANAL, PAL_NONE, STR_WATERWAYS_MENU_WATERWAYS_CONSTRUCTION, 0)); list.push_back(MakeDropDownListIconItem(SPR_IMG_BUILD_CANAL, PAL_NONE, STR_WATERWAYS_MENU_WATERWAYS_CONSTRUCTION, 0));
ShowDropDownList(w, std::move(list), 0, WID_TN_WATER, 140, true); ShowDropDownList(w, std::move(list), 0, WID_TN_WATER, 140, true);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
return CBF_NONE; return CBF_NONE;
} }
@ -968,7 +968,7 @@ static CallBackFunction ToolbarBuildAirClick(Window *w)
DropDownList list; DropDownList list;
list.push_back(MakeDropDownListIconItem(SPR_IMG_AIRPORT, PAL_NONE, STR_AIRCRAFT_MENU_AIRPORT_CONSTRUCTION, 0)); list.push_back(MakeDropDownListIconItem(SPR_IMG_AIRPORT, PAL_NONE, STR_AIRCRAFT_MENU_AIRPORT_CONSTRUCTION, 0));
ShowDropDownList(w, std::move(list), 0, WID_TN_AIR, 140, true); ShowDropDownList(w, std::move(list), 0, WID_TN_AIR, 140, true);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
return CBF_NONE; return CBF_NONE;
} }
@ -992,7 +992,7 @@ static CallBackFunction ToolbarForestClick(Window *w)
list.push_back(MakeDropDownListIconItem(SPR_IMG_PLANTTREES, PAL_NONE, STR_LANDSCAPING_MENU_PLANT_TREES, 1)); list.push_back(MakeDropDownListIconItem(SPR_IMG_PLANTTREES, PAL_NONE, STR_LANDSCAPING_MENU_PLANT_TREES, 1));
list.push_back(MakeDropDownListIconItem(SPR_IMG_SIGN, PAL_NONE, STR_LANDSCAPING_MENU_PLACE_SIGN, 2)); list.push_back(MakeDropDownListIconItem(SPR_IMG_SIGN, PAL_NONE, STR_LANDSCAPING_MENU_PLACE_SIGN, 2));
ShowDropDownList(w, std::move(list), 0, WID_TN_LANDSCAPE, 100, true); ShowDropDownList(w, std::move(list), 0, WID_TN_LANDSCAPE, 100, true);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
return CBF_NONE; return CBF_NONE;
} }
@ -1188,7 +1188,7 @@ static CallBackFunction ToolbarSwitchClick(Window *w)
w->ReInit(); w->ReInit();
w->SetWidgetLoweredState(_game_mode == GM_EDITOR ? (WidgetID)WID_TE_SWITCH_BAR : (WidgetID)WID_TN_SWITCH_BAR, _toolbar_mode == TB_LOWER); w->SetWidgetLoweredState(_game_mode == GM_EDITOR ? (WidgetID)WID_TE_SWITCH_BAR : (WidgetID)WID_TN_SWITCH_BAR, _toolbar_mode == TB_LOWER);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
return CBF_NONE; return CBF_NONE;
} }
@ -1232,7 +1232,7 @@ static CallBackFunction ToolbarScenDateForward(Window *w)
static CallBackFunction ToolbarScenGenLand(Window *w) static CallBackFunction ToolbarScenGenLand(Window *w)
{ {
w->HandleButtonClick(WID_TE_LAND_GENERATE); w->HandleButtonClick(WID_TE_LAND_GENERATE);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
ShowEditorTerraformToolbar(); ShowEditorTerraformToolbar();
return CBF_NONE; return CBF_NONE;
@ -1256,7 +1256,7 @@ static CallBackFunction ToolbarScenGenTown(int index)
static CallBackFunction ToolbarScenGenIndustry(Window *w) static CallBackFunction ToolbarScenGenIndustry(Window *w)
{ {
w->HandleButtonClick(WID_TE_INDUSTRY); w->HandleButtonClick(WID_TE_INDUSTRY);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
ShowBuildIndustryWindow(); ShowBuildIndustryWindow();
return CBF_NONE; return CBF_NONE;
} }
@ -1264,7 +1264,7 @@ static CallBackFunction ToolbarScenGenIndustry(Window *w)
static CallBackFunction ToolbarScenBuildRoadClick(Window *w) static CallBackFunction ToolbarScenBuildRoadClick(Window *w)
{ {
ShowDropDownList(w, GetScenRoadTypeDropDownList(RTTB_ROAD), _last_built_roadtype, WID_TE_ROADS, 140, true); ShowDropDownList(w, GetScenRoadTypeDropDownList(RTTB_ROAD), _last_built_roadtype, WID_TE_ROADS, 140, true);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
return CBF_NONE; return CBF_NONE;
} }
@ -1284,7 +1284,7 @@ static CallBackFunction ToolbarScenBuildRoad(int index)
static CallBackFunction ToolbarScenBuildTramClick(Window *w) static CallBackFunction ToolbarScenBuildTramClick(Window *w)
{ {
ShowDropDownList(w, GetScenRoadTypeDropDownList(RTTB_TRAM), _last_built_tramtype, WID_TE_TRAMS, 140, true); ShowDropDownList(w, GetScenRoadTypeDropDownList(RTTB_TRAM), _last_built_tramtype, WID_TE_TRAMS, 140, true);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
return CBF_NONE; return CBF_NONE;
} }
@ -1304,7 +1304,7 @@ static CallBackFunction ToolbarScenBuildTram(int index)
static CallBackFunction ToolbarScenBuildDocks(Window *w) static CallBackFunction ToolbarScenBuildDocks(Window *w)
{ {
w->HandleButtonClick(WID_TE_WATER); w->HandleButtonClick(WID_TE_WATER);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
ShowBuildDocksScenToolbar(); ShowBuildDocksScenToolbar();
return CBF_NONE; return CBF_NONE;
} }
@ -1312,7 +1312,7 @@ static CallBackFunction ToolbarScenBuildDocks(Window *w)
static CallBackFunction ToolbarScenPlantTrees(Window *w) static CallBackFunction ToolbarScenPlantTrees(Window *w)
{ {
w->HandleButtonClick(WID_TE_TREES); w->HandleButtonClick(WID_TE_TREES);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
ShowBuildTreesToolbar(); ShowBuildTreesToolbar();
return CBF_NONE; return CBF_NONE;
} }
@ -1320,7 +1320,7 @@ static CallBackFunction ToolbarScenPlantTrees(Window *w)
static CallBackFunction ToolbarScenPlaceSign(Window *w) static CallBackFunction ToolbarScenPlaceSign(Window *w)
{ {
w->HandleButtonClick(WID_TE_SIGNS); w->HandleButtonClick(WID_TE_SIGNS);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
return SelectSignTool(); return SelectSignTool();
} }
@ -2407,7 +2407,7 @@ struct ScenarioEditorToolbarWindow : Window {
{ {
CallBackFunction cbf = _scen_toolbar_dropdown_procs[widget](index); CallBackFunction cbf = _scen_toolbar_dropdown_procs[widget](index);
if (cbf != CBF_NONE) _last_started_action = cbf; if (cbf != CBF_NONE) _last_started_action = cbf;
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
} }
EventState OnHotkey(int hotkey) override EventState OnHotkey(int hotkey) override

View File

@ -1739,7 +1739,7 @@ struct BuildHouseWindow : public PickerWindow {
this->SetWidgetLoweredState(WID_BH_PROTECT_OFF, !BuildHouseWindow::house_protected); this->SetWidgetLoweredState(WID_BH_PROTECT_OFF, !BuildHouseWindow::house_protected);
this->SetWidgetLoweredState(WID_BH_PROTECT_ON, BuildHouseWindow::house_protected); this->SetWidgetLoweredState(WID_BH_PROTECT_ON, BuildHouseWindow::house_protected);
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
this->SetDirty(); this->SetDirty();
break; break;

View File

@ -80,7 +80,7 @@ public:
} else { } else {
/* toggle the bit of the transparencies variable and play a sound */ /* toggle the bit of the transparencies variable and play a sound */
ToggleTransparency((TransparencyOption)(widget - WID_TT_BEGIN)); ToggleTransparency((TransparencyOption)(widget - WID_TT_BEGIN));
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
MarkWholeScreenDirty(); MarkWholeScreenDirty();
} }
} else if (widget == WID_TT_BUTTONS) { } else if (widget == WID_TT_BUTTONS) {
@ -94,7 +94,7 @@ public:
if (i == WID_TT_TEXT|| i == WID_TT_END) return; if (i == WID_TT_TEXT|| i == WID_TT_END) return;
ToggleInvisibility((TransparencyOption)(i - WID_TT_BEGIN)); ToggleInvisibility((TransparencyOption)(i - WID_TT_BEGIN));
if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); SndClickBeep();
/* Redraw whole screen only if transparency is set */ /* Redraw whole screen only if transparency is set */
if (IsTransparencySet((TransparencyOption)(i - WID_TT_BEGIN))) { if (IsTransparencySet((TransparencyOption)(i - WID_TT_BEGIN))) {

View File

@ -102,7 +102,7 @@ class BuildTreesWindow : public Window
if (this->tree_to_plant >= 0) { if (this->tree_to_plant >= 0) {
/* Activate placement */ /* Activate placement */
if (_settings_client.sound.confirm) SndPlayFx(SND_15_BEEP); SndConfirmBeep();
SetObjectToPlace(SPR_CURSOR_TREE, PAL_NONE, HT_RECT | HT_DIAGONAL, this->window_class, this->window_number); SetObjectToPlace(SPR_CURSOR_TREE, PAL_NONE, HT_RECT | HT_DIAGONAL, this->window_class, this->window_number);
this->tree_to_plant = current_tree; // SetObjectToPlace may call ResetObjectToPlace which may reset tree_to_plant to -1 this->tree_to_plant = current_tree; // SetObjectToPlace may call ResetObjectToPlace which may reset tree_to_plant to -1
} else { } else {
@ -180,7 +180,7 @@ public:
break; break;
case WID_BT_MANY_RANDOM: // place trees randomly over the landscape case WID_BT_MANY_RANDOM: // place trees randomly over the landscape
if (_settings_client.sound.confirm) SndPlayFx(SND_15_BEEP); SndConfirmBeep();
PlaceTreesRandomly(); PlaceTreesRandomly();
MarkWholeScreenDirty(); MarkWholeScreenDirty();
break; break;

View File

@ -39,10 +39,13 @@
#include "object_base.h" #include "object_base.h"
#include "water.h" #include "water.h"
#include "company_gui.h" #include "company_gui.h"
#include "newgrf_roadstop.h"
#include "station_func.h" #include "station_func.h"
#include "station_map.h"
#include "tunnelbridge_cmd.h" #include "tunnelbridge_cmd.h"
#include "landscape_cmd.h" #include "landscape_cmd.h"
#include "terraform_cmd.h" #include "terraform_cmd.h"
#include "newgrf_station.h"
#include "table/strings.h" #include "table/strings.h"
#include "table/bridge_land.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) */ /** Z position of the bridge sprites relative to bridge height (downwards) */
static const int BRIDGE_Z_START = 3; 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. * Mark bridge tiles dirty.
@ -434,6 +443,43 @@ CommandCost CmdBuildBridge(DoCommandFlags flags, TileIndex tile_end, TileIndex t
/* If bridge belonged to bankrupt company, it has a new owner now */ /* If bridge belonged to bankrupt company, it has a new owner now */
is_new_owner = (owner == OWNER_NONE); is_new_owner = (owner == OWNER_NONE);
if (is_new_owner) owner = company; 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 { } else {
/* Build a new bridge. */ /* Build a new bridge. */
@ -510,6 +556,45 @@ CommandCost CmdBuildBridge(DoCommandFlags flags, TileIndex tile_end, TileIndex t
break; 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: case MP_CLEAR:
break; break;
@ -1574,6 +1659,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. * Draw the middle bits of a bridge.
* @param ti Tile information of the tile to draw it on. * @param ti Tile information of the tile to draw it on.

View File

@ -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 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 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 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); 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; 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); TileArea new_location(start_tile, width, height);
/* only AddCost for non-existing waypoints */ /* only AddCost for non-existing waypoints */
@ -237,6 +250,10 @@ CommandCost CmdBuildRailWaypoint(DoCommandFlags flags, TileIndex start_tile, Axi
TileIndex tile = start_tile + i * offset; TileIndex tile = start_tile + i * offset;
CommandCost ret = IsValidTileForWaypoint(tile, axis, &est); CommandCost ret = IsValidTileForWaypoint(tile, axis, &est);
if (ret.Failed()) return ret; if (ret.Failed()) return ret;
ret = IsRailStationBridgeAboveOk(tile, spec, layout_ptr[i]);
if (ret.Failed()) {
return ret;
}
} }
Waypoint *wp = nullptr; Waypoint *wp = nullptr;
@ -364,7 +381,7 @@ CommandCost CmdBuildRoadWaypoint(DoCommandFlags flags, TileIndex start_tile, Axi
unit_cost = _price[PR_BUILD_STATION_TRUCK]; unit_cost = _price[PR_BUILD_STATION_TRUCK];
} }
StationID est = StationID::Invalid(); 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; if (cost.Failed()) return cost;
Waypoint *wp = nullptr; Waypoint *wp = nullptr;