diff --git a/docs/newgrf-additions-nml.html b/docs/newgrf-additions-nml.html index 4a5fe65638..37c7873428 100644 --- a/docs/newgrf-additions-nml.html +++ b/docs/newgrf-additions-nml.html @@ -535,6 +535,11 @@ item (FEAT_GLOBALVARS) { Set whether signals should be drawn on the opposite side of the track for the most recently defined style (defined using the define_style property). + style_realistic_braking_only0 or 1 + + Set whether signals using this style may only be built when realistic braking is enabled, for the most recently defined style (defined using the define_style property). + + no_default_style0 or 1 When enabled, custom signal graphics from this GRF are only used for custom signal styles, not the default style diff --git a/docs/newgrf-additions.html b/docs/newgrf-additions.html index fc36f3b8e2..702a52838e 100644 --- a/docs/newgrf-additions.html +++ b/docs/newgrf-additions.html @@ -507,6 +507,13 @@ The Action 0 Id field is not used, the value is ignored.

This is indicated by the feature name: action0_signals_style, version 1

+

Set custom signal style signal requires realistic braking (mappable property: signals_style_realistic_braking_only)

+

This applies to the most recent custom signal style defined using the signals_define_style property.
+ When enabled, signals using this style may only be built when realistic braking is enabled.

+

The property length is 1 byte. 0 is disabled (default). 1 is enabled.
+ The Action 0 Id field is not used, the value is ignored. +

+

This is indicated by the feature name: action0_signals_style, version 1

Set whether custom signal sprites should not be used for the default signal style (mappable property: signals_no_default_style)

This applies to Action 2/3 Signals (Feature 0E) custom signal sprites for this GRF.
When enabled, this GRF is not used for the default signal style, it is only used for custom signal styles defined with signals_define_style.

diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 4ecec5daed..a279d03dbe 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -4298,6 +4298,15 @@ static ChangeInfoResult SignalsChangeInfo(uint id, int numinfo, int prop, const break; } + case A0RPI_SIGNALS_STYLE_REALISTIC_BRAKING_ONLY: { + if (MappedPropertyLengthMismatch(buf, 1, mapping_entry)) break; + uint8 value = buf->ReadByte(); + if (_cur.grffile->current_new_signal_style != nullptr) { + SB(_cur.grffile->current_new_signal_style->style_flags, NSSF_REALISTIC_BRAKING_ONLY, 1, (value != 0 ? 1 : 0)); + } + break; + } + default: ret = HandleAction0PropertyDefault(buf, prop); break; diff --git a/src/newgrf_extension.cpp b/src/newgrf_extension.cpp index 98fe2efda0..e3674a41e2 100644 --- a/src/newgrf_extension.cpp +++ b/src/newgrf_extension.cpp @@ -102,6 +102,7 @@ extern const GRFPropertyMapDefinition _grf_action0_remappable_properties[] = { GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_ELECTRIC_ENABLED, "signals_style_electric_enabled"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_OPPOSITE_SIDE, "signals_style_opposite_side"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_COMBINED_NORMAL_SHUNT, "signals_style_combined_normal_shunt"), + GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_REALISTIC_BRAKING_ONLY, "signals_style_realistic_braking_only"), GRFPropertyMapDefinition(GSF_OBJECTS, A0RPI_OBJECT_USE_LAND_GROUND, "object_use_land_ground"), GRFPropertyMapDefinition(GSF_OBJECTS, A0RPI_OBJECT_EDGE_FOUNDATION_MODE, "object_edge_foundation_mode"), GRFPropertyMapDefinition(GSF_OBJECTS, A0RPI_OBJECT_FLOOD_RESISTANT, "object_flood_resistant"), diff --git a/src/newgrf_extension.h b/src/newgrf_extension.h index 2531201494..705555d061 100644 --- a/src/newgrf_extension.h +++ b/src/newgrf_extension.h @@ -46,6 +46,7 @@ enum Action0RemapPropertyIds { A0RPI_SIGNALS_STYLE_ELECTRIC_ENABLED, A0RPI_SIGNALS_STYLE_OPPOSITE_SIDE, A0RPI_SIGNALS_STYLE_COMBINED_NORMAL_SHUNT, + A0RPI_SIGNALS_STYLE_REALISTIC_BRAKING_ONLY, A0RPI_OBJECT_USE_LAND_GROUND, A0RPI_OBJECT_EDGE_FOUNDATION_MODE, A0RPI_OBJECT_FLOOD_RESISTANT, diff --git a/src/newgrf_newsignals.cpp b/src/newgrf_newsignals.cpp index 9445747267..c120702d2f 100644 --- a/src/newgrf_newsignals.cpp +++ b/src/newgrf_newsignals.cpp @@ -21,6 +21,7 @@ std::vector _new_signals_grfs; std::array _new_signal_styles; std::array _new_signal_style_mapping; uint _num_new_signal_styles = 0; +uint16 _enabled_new_signal_styles_mask = 0; /* virtual */ uint32 NewSignalsScopeResolver::GetRandomBits() const { diff --git a/src/newgrf_newsignals.h b/src/newgrf_newsignals.h index 25dca6e416..50e3d2d59e 100644 --- a/src/newgrf_newsignals.h +++ b/src/newgrf_newsignals.h @@ -34,6 +34,7 @@ enum NewSignalStyleFlags { NSSF_OPPOSITE_SIDE = 3, NSSF_LOOKAHEAD_SINGLE_SIGNAL = 4, NSSF_COMBINED_NORMAL_SHUNT = 5, + NSSF_REALISTIC_BRAKING_ONLY = 6, }; struct NewSignalStyle { @@ -56,6 +57,7 @@ struct NewSignalStyleMapping { }; extern std::array _new_signal_style_mapping; extern uint _num_new_signal_styles; +extern uint16 _enabled_new_signal_styles_mask; /** Resolver for the new signals scope. */ struct NewSignalsScopeResolver : public ScopeResolver { diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 8336b2c853..0a163eabd0 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -1481,7 +1481,8 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint which_signals = GB(p1, 9, 6); - uint signal_style = std::min(GB(p1, 19, 4), _num_new_signal_styles); + uint signal_style = GB(p1, 19, 4); + if (signal_style > _num_new_signal_styles || !HasBit(_enabled_new_signal_styles_mask, signal_style)) return CMD_ERROR; if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC && IsSignalTypeUnsuitableForRealisticBraking(sigtype)) return CMD_ERROR; diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index 8a25bd3ffd..f718ef8ffb 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -1876,7 +1876,7 @@ private: this->realistic_braking_mode = (_settings_game.vehicle.train_braking_model == TBM_REALISTIC); this->progsig_ui_shown = _settings_client.gui.show_progsig_ui; this->noentry_ui_shown = _settings_client.gui.show_noentrysig_ui; - this->style_selector_shown = _num_new_signal_styles > 0; + this->style_selector_shown = _enabled_new_signal_styles_mask > 1; bool show_norm = this->realistic_braking_mode || this->all_signal_mode; bool show_presig = !this->realistic_braking_mode && this->all_signal_mode; @@ -2106,7 +2106,9 @@ public: DropDownList list; list.emplace_back(new DropDownListStringItem(STR_BUILD_SIGNAL_DEFAULT_STYLE, 0, false)); for (uint i = 0; i < _num_new_signal_styles; i++) { - list.emplace_back(new DropDownListStringItem(_new_signal_styles[i].name, i + 1, false)); + if (HasBit(_enabled_new_signal_styles_mask, i + 1)) { + list.emplace_back(new DropDownListStringItem(_new_signal_styles[i].name, i + 1, false)); + } } ShowDropDownList(this, std::move(list), _cur_signal_style, widget); break; @@ -2148,12 +2150,12 @@ public: this->SetWidgetDisabledState(WID_BS_DRAG_SIGNALS_DENSITY_DECREASE, _settings_client.gui.drag_signals_density == 1); this->SetWidgetDisabledState(WID_BS_DRAG_SIGNALS_DENSITY_INCREASE, _settings_client.gui.drag_signals_density == 20); - if (_cur_signal_style > _num_new_signal_styles) _cur_signal_style = 0; + if (_cur_signal_style > _num_new_signal_styles || !HasBit(_enabled_new_signal_styles_mask, _cur_signal_style)) _cur_signal_style = 0; if (this->all_signal_mode != (_settings_client.gui.signal_gui_mode == SIGNAL_GUI_ALL) || this->progsig_ui_shown != _settings_client.gui.show_progsig_ui || this->realistic_braking_mode != (_settings_game.vehicle.train_braking_model == TBM_REALISTIC) || this->noentry_ui_shown != _settings_client.gui.show_noentrysig_ui || - this->style_selector_shown != (_num_new_signal_styles > 0)) { + this->style_selector_shown != (_enabled_new_signal_styles_mask > 1)) { this->SetSignalUIMode(); this->ReInit(); } diff --git a/src/signal.cpp b/src/signal.cpp index 588d2ba68f..e1ee1b7b40 100644 --- a/src/signal.cpp +++ b/src/signal.cpp @@ -1707,6 +1707,8 @@ static bool DetermineExtraAspectsVariable() _signal_style_masks = {}; + _enabled_new_signal_styles_mask = 1; + if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC) { for (RailType r = RAILTYPE_BEGIN; r != RAILTYPE_END; r++) { const RailtypeInfo *rti = GetRailTypeInfo(r); @@ -1743,6 +1745,13 @@ static bool DetermineExtraAspectsVariable() _new_signal_styles[i].electric_mask &= (1 << SIGTYPE_PBS) | (1 << SIGTYPE_PBS_ONEWAY) | (1 << SIGTYPE_NO_ENTRY); _new_signal_styles[i].semaphore_mask &= (1 << SIGTYPE_PBS) | (1 << SIGTYPE_PBS_ONEWAY) | (1 << SIGTYPE_NO_ENTRY); } + uint8 mask = 0xFF; + if (HasBit(_new_signal_styles[i].style_flags, NSSF_REALISTIC_BRAKING_ONLY) && _settings_game.vehicle.train_braking_model != TBM_REALISTIC) { + mask = 0; + } else if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC) { + mask &= (1 << SIGTYPE_NORMAL) | (1 << SIGTYPE_PBS) | (1 << SIGTYPE_PBS_ONEWAY) | (1 << SIGTYPE_NO_ENTRY); + } + if ((_new_signal_styles[i].electric_mask | _new_signal_styles[i].semaphore_mask) & mask) SetBit(_enabled_new_signal_styles_mask, i + 1); } for (uint i = _num_new_signal_styles; i < MAX_NEW_SIGNAL_STYLES; i++) { _new_signal_styles[i].lookahead_extra_aspects = new_extra_aspects;