NewGRF: Allow using Action 2/3 for custom signal sprites
This is mostly the same format as the railtype custom signal mechanism
This commit is contained in:
@@ -278,11 +278,42 @@
|
||||
</table>
|
||||
</p>
|
||||
<p>This is indicated by the feature name: <font face="monospace">action0_global_extra_station_names</font>, version 1</p>
|
||||
<h3 id="a0signals"><a href="https://newgrf-specs.tt-wiki.net/wiki/Action0">Action 0 - Signals (Feature 0E)</a></h3>
|
||||
<p>Note that Action 0 feature 0E is not supported (does nothing) in standard OpenTTD.</p>
|
||||
<p>This implementation of feature 0E is not the same as that in TTDPatch.</p>
|
||||
<h4 id="signals_enable_programmable_signals">Enable custom signal sprites for programmable pre-signals (mappable property: signals_enable_programmable_signals)</h4>
|
||||
<p>This enables <a href="#a3signals_custom_signal_sprites">Action 2/3 Signals (Feature 0E) custom signal sprites</a> for programmable pre-signals for this GRF.<br />
|
||||
Programmable pre-signals have the signal type value: 06.<br />
|
||||
The property length is 1 byte. 0 is disabled (default). 1 is enabled.<br />
|
||||
The Action 0 Id field is not used, the value is ignored.
|
||||
</p>
|
||||
<p>This is indicated by the feature name: <font face="monospace">action0_signals_programmable_signals</font>, version 1</p>
|
||||
<h4 id="signals_enable_restricted_signals">Enable restricted signal flag for custom signal sprites (mappable property: signals_enable_restricted_signals)</h4>
|
||||
<p>This applies to <a href="#a3signals_custom_signal_sprites">Action 2/3 Signals (Feature 0E) custom signal sprites</a> for this GRF.<br />
|
||||
When enabled, bit 24 of variable 18 (extra callback info) is set if the signal is restricted (has a routing restriction program attached).<br />
|
||||
When enabled, the "Show restricted electric signals using default graphics" client setting and signal post recolouring is not applied.<br />
|
||||
This flag should only be set if the Action 2/3 actually returns a different sprite when bit 24 of variable 18 is set.<br />
|
||||
The property length is 1 byte. 0 is disabled (default). 1 is enabled.<br />
|
||||
The Action 0 Id field is not used, the value is ignored.
|
||||
</p>
|
||||
<p>This is indicated by the feature name: <font face="monospace">action0_signals_restricted_signals</font>, version 1</p>
|
||||
<br />
|
||||
<br />
|
||||
<h3 id="varaction2_station"><a href="https://newgrf-specs.tt-wiki.net/wiki/VariationalAction2/Stations">Variational Action 2 - Stations</a></h3>
|
||||
<h4 id="varaction2_station_var42">Track type in purchase list (42)</h4>
|
||||
<p>This is indicated by the feature name: <font face="monospace">varaction2_station_var42</font>, version 1</p>
|
||||
<br />
|
||||
<h3 id="a3signals"><a href="https://newgrf-specs.tt-wiki.net/wiki/Action3">Action 3 - Signals (Feature 0E)</a></h3>
|
||||
<p>Note that Action 3 feature 0E is not supported (does nothing) in standard OpenTTD.</p>
|
||||
<p>This implementation of feature 0E is not the same as that in TTDPatch.</p>
|
||||
<h4 id="a3signals_custom_signal_sprites">Custom signal sprites using Action 2/3 (action 3 ID: 0)</h4>
|
||||
<p>This feature allows using Action 3 to assign an Action 2 chain which dynamically resolves signal sprites, in a very similar way to that of <a href="https://newgrf-specs.tt-wiki.net/wiki/Action3/Railtypes#Signal_sprites_.280B.29">Action 2/3 - Railtype custom signal sprites</a>,<br />
|
||||
however, this applies to all signals, not only those of a particular rail type.</p>
|
||||
<p>Variational Action 2 variables 10, 18 and 40 are available and have the same format as in <a href="https://newgrf-specs.tt-wiki.net/wiki/VariationalAction2/Railtypes">VariationalAction2/Railtypes</a>.</p>
|
||||
<p>Rail type custom signal sprites have a higher priority than custom signal sprites for all signals as set here.</p>
|
||||
<p>Note that this is not a generic callback, the sprite group must be assigned to ID 0 (further IDs may be allocated for other purposes in future).</p>
|
||||
<p>This is indicated by the feature name: <font face="monospace">action3_signals_custom_signal_sprites</font>, version 1</p>
|
||||
<br />
|
||||
<h3 id="action5">Action 14 - Type ID Mapping for Action 5</h3>
|
||||
<p>See <a href="https://newgrf-specs.tt-wiki.net/wiki/Action14">Action 14 Specification</a> and <a href="https://newgrf-specs.tt-wiki.net/wiki/Action5">Action 5 Specification</a> for background information.</p>
|
||||
<p>The action 5 type ID mapping mechanism has the feature name: <font face="monospace">action5_type_id_mapping</font>, this document describes version 1.</p>
|
||||
|
@@ -266,6 +266,8 @@ add_files(
|
||||
newgrf_industries.h
|
||||
newgrf_industrytiles.cpp
|
||||
newgrf_industrytiles.h
|
||||
newgrf_newsignals.cpp
|
||||
newgrf_newsignals.h
|
||||
newgrf_object.cpp
|
||||
newgrf_object.h
|
||||
newgrf_profiling.cpp
|
||||
|
@@ -33,6 +33,7 @@
|
||||
#include "newgrf_airporttiles.h"
|
||||
#include "newgrf_airport.h"
|
||||
#include "newgrf_object.h"
|
||||
#include "newgrf_newsignals.h"
|
||||
#include "rev.h"
|
||||
#include "fios.h"
|
||||
#include "strings_func.h"
|
||||
@@ -4058,6 +4059,39 @@ static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, c
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define properties for signals
|
||||
* @param id Local ID (unused).
|
||||
* @param numinfo Number of subsequent IDs to change the property for.
|
||||
* @param prop The property to change.
|
||||
* @param buf The property value.
|
||||
* @return ChangeInfoResult.
|
||||
*/
|
||||
static ChangeInfoResult SignalsChangeInfo(uint id, int numinfo, int prop, const GRFFilePropertyRemapEntry *mapping_entry, ByteReader *buf)
|
||||
{
|
||||
/* Properties which are handled per item */
|
||||
ChangeInfoResult ret = CIR_SUCCESS;
|
||||
for (int i = 0; i < numinfo; i++) {
|
||||
switch (prop) {
|
||||
case A0RPI_SIGNALS_ENABLE_PROGRAMMABLE_SIGNALS:
|
||||
if (MappedPropertyLengthMismatch(buf, 1, mapping_entry)) break;
|
||||
SB(_cur.grffile->new_signal_ctrl_flags, NSCF_PROGSIG, 1, (buf->ReadByte() != 0 ? 1 : 0));
|
||||
break;
|
||||
|
||||
case A0RPI_SIGNALS_ENABLE_RESTRICTED_SIGNALS:
|
||||
if (MappedPropertyLengthMismatch(buf, 1, mapping_entry)) break;
|
||||
SB(_cur.grffile->new_signal_ctrl_flags, NSCF_RESTRICTEDSIG, 1, (buf->ReadByte() != 0 ? 1 : 0));
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = HandleAction0PropertyDefault(buf, prop);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ignore properties for objects
|
||||
* @param prop The property to ignore.
|
||||
@@ -4886,7 +4920,7 @@ static void FeatureChangeInfo(ByteReader *buf)
|
||||
/* GSF_CARGOES */ nullptr, // Cargo is handled during reservation
|
||||
/* GSF_SOUNDFX */ SoundEffectChangeInfo,
|
||||
/* GSF_AIRPORTS */ AirportChangeInfo,
|
||||
/* GSF_SIGNALS */ nullptr,
|
||||
/* GSF_SIGNALS */ SignalsChangeInfo,
|
||||
/* GSF_OBJECTS */ ObjectChangeInfo,
|
||||
/* GSF_RAILTYPES */ RailTypeChangeInfo,
|
||||
/* GSF_AIRPORTTILES */ AirportTilesChangeInfo,
|
||||
@@ -5301,6 +5335,7 @@ static void NewSpriteGroup(ByteReader *buf)
|
||||
case GSF_RAILTYPES:
|
||||
case GSF_ROADTYPES:
|
||||
case GSF_TRAMTYPES:
|
||||
case GSF_SIGNALS:
|
||||
{
|
||||
byte num_loaded = type;
|
||||
byte num_loading = buf->ReadByte();
|
||||
@@ -5789,6 +5824,39 @@ static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount)
|
||||
}
|
||||
}
|
||||
|
||||
static void SignalsMapSpriteGroup(ByteReader *buf, uint8 idcount)
|
||||
{
|
||||
uint8 *ids = AllocaM(uint8, idcount);
|
||||
for (uint i = 0; i < idcount; i++) {
|
||||
ids[i] = buf->ReadByte();
|
||||
}
|
||||
|
||||
/* Skip the cargo type section, we only care about the default group */
|
||||
uint8 cidcount = buf->ReadByte();
|
||||
buf->Skip(cidcount * 3);
|
||||
|
||||
uint16 groupid = buf->ReadWord();
|
||||
if (!IsValidGroupID(groupid, "SignalsMapSpriteGroup")) return;
|
||||
|
||||
for (uint i = 0; i < idcount; i++) {
|
||||
uint8 id = ids[i];
|
||||
|
||||
switch (id) {
|
||||
case NSA3ID_CUSTOM_SIGNALS:
|
||||
_cur.grffile->new_signals_group = _cur.spritegroups[groupid];
|
||||
if (!HasBit(_cur.grffile->new_signal_ctrl_flags, NSCF_GROUPSET)) {
|
||||
SetBit(_cur.grffile->new_signal_ctrl_flags, NSCF_GROUPSET);
|
||||
_new_signals_grfs.push_back(_cur.grffile);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
grfmsg(1, "SignalsMapSpriteGroup: ID not implemented: %d", id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount)
|
||||
{
|
||||
if (_cur.grffile->objectspec == nullptr) {
|
||||
@@ -6050,6 +6118,10 @@ static void FeatureMapSpriteGroup(ByteReader *buf)
|
||||
AirportMapSpriteGroup(buf, idcount);
|
||||
return;
|
||||
|
||||
case GSF_SIGNALS:
|
||||
SignalsMapSpriteGroup(buf, idcount);
|
||||
break;
|
||||
|
||||
case GSF_OBJECTS:
|
||||
ObjectMapSpriteGroup(buf, idcount);
|
||||
break;
|
||||
@@ -8398,6 +8470,9 @@ static const GRFFeatureInfo _grf_feature_list[] = {
|
||||
GRFFeatureInfo("action0_railtype_disable_realistic_braking", 1),
|
||||
GRFFeatureInfo("action0_roadtype_extra_flags", 1),
|
||||
GRFFeatureInfo("action0_global_extra_station_names", 1),
|
||||
GRFFeatureInfo("action0_signals_programmable_signals", 1),
|
||||
GRFFeatureInfo("action0_signals_restricted_signals", 1),
|
||||
GRFFeatureInfo("action3_signals_custom_signal_sprites", 1),
|
||||
GRFFeatureInfo(),
|
||||
};
|
||||
|
||||
@@ -8520,6 +8595,8 @@ static const GRFPropertyMapDefinition _grf_action0_remappable_properties[] = {
|
||||
GRFPropertyMapDefinition(GSF_ROADTYPES, A0RPI_ROADTYPE_EXTRA_FLAGS, "roadtype_extra_flags"),
|
||||
GRFPropertyMapDefinition(GSF_TRAMTYPES, A0RPI_ROADTYPE_EXTRA_FLAGS, "roadtype_extra_flags"),
|
||||
GRFPropertyMapDefinition(GSF_GLOBALVAR, A0RPI_GLOBALVAR_EXTRA_STATION_NAMES, "global_extra_station_names"),
|
||||
GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_ENABLE_PROGRAMMABLE_SIGNALS, "signals_enable_programmable_signals"),
|
||||
GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_ENABLE_RESTRICTED_SIGNALS, "signals_enable_restricted_signals"),
|
||||
GRFPropertyMapDefinition(),
|
||||
};
|
||||
|
||||
@@ -9140,6 +9217,7 @@ static void ResetNewGRF()
|
||||
|
||||
_grf_files.clear();
|
||||
_cur.grffile = nullptr;
|
||||
_new_signals_grfs.clear();
|
||||
}
|
||||
|
||||
/** Clear all NewGRF errors */
|
||||
@@ -9314,6 +9392,9 @@ GRFFile::GRFFile(const GRFConfig *config)
|
||||
this->traininfo_vehicle_pitch = 0;
|
||||
this->traininfo_vehicle_width = TRAININFO_DEFAULT_VEHICLE_WIDTH;
|
||||
|
||||
this->new_signals_group = nullptr;
|
||||
this->new_signal_ctrl_flags = 0;
|
||||
|
||||
/* Mark price_base_multipliers as 'not set' */
|
||||
for (Price i = PR_BEGIN; i < PR_END; i++) {
|
||||
this->price_base_multipliers[i] = INVALID_PRICE_MODIFIER;
|
||||
|
17
src/newgrf.h
17
src/newgrf.h
@@ -120,6 +120,8 @@ enum Action0RemapPropertyIds {
|
||||
A0RPI_RAILTYPE_DISABLE_REALISTIC_BRAKING,
|
||||
A0RPI_ROADTYPE_EXTRA_FLAGS,
|
||||
A0RPI_GLOBALVAR_EXTRA_STATION_NAMES,
|
||||
A0RPI_SIGNALS_ENABLE_PROGRAMMABLE_SIGNALS,
|
||||
A0RPI_SIGNALS_ENABLE_RESTRICTED_SIGNALS,
|
||||
};
|
||||
|
||||
enum GRFPropertyMapFallbackMode {
|
||||
@@ -215,6 +217,18 @@ struct Action5TypeRemapSet {
|
||||
}
|
||||
};
|
||||
|
||||
/** New signal control flags. */
|
||||
enum NewSignalCtrlFlags {
|
||||
NSCF_GROUPSET = 0, ///< Custom signal sprites group set.
|
||||
NSCF_PROGSIG = 1, ///< Custom signal sprites enabled for programmable pre-signals.
|
||||
NSCF_RESTRICTEDSIG = 2, ///< Custom signal sprite flag enabled for restricted signals.
|
||||
};
|
||||
|
||||
/** New signal control flags. */
|
||||
enum NewSignalAction3ID {
|
||||
NSA3ID_CUSTOM_SIGNALS = 0, ///< Action 3 ID for custom signal sprites
|
||||
};
|
||||
|
||||
/** Dynamic data of a loaded NewGRF */
|
||||
struct GRFFile : ZeroedMemoryAllocator {
|
||||
char *filename;
|
||||
@@ -266,6 +280,9 @@ struct GRFFile : ZeroedMemoryAllocator {
|
||||
uint32 var8D_overlay; ///< Overlay for global variable 8D (action 0x14)
|
||||
uint32 var9D_overlay; ///< Overlay for global variable 9D (action 0x14)
|
||||
|
||||
const SpriteGroup *new_signals_group; ///< New signals sprite group
|
||||
byte new_signal_ctrl_flags; ///< Ctrl flags for new signals
|
||||
|
||||
GRFFile(const struct GRFConfig *config);
|
||||
~GRFFile();
|
||||
|
||||
|
67
src/newgrf_newsignals.cpp
Normal file
67
src/newgrf_newsignals.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file newgrf_newsignals.cpp NewGRF handling of new signals. */
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "debug.h"
|
||||
#include "newgrf_newsignals.h"
|
||||
#include "map_func.h"
|
||||
|
||||
#include "safeguards.h"
|
||||
|
||||
std::vector<const GRFFile *> _new_signals_grfs;
|
||||
|
||||
/* virtual */ uint32 NewSignalsScopeResolver::GetRandomBits() const
|
||||
{
|
||||
uint tmp = CountBits(this->tile + (TileX(this->tile) + TileY(this->tile)) * TILE_SIZE);
|
||||
return GB(tmp, 0, 2);
|
||||
}
|
||||
|
||||
/* virtual */ uint32 NewSignalsScopeResolver::GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const
|
||||
{
|
||||
if (this->tile == INVALID_TILE) {
|
||||
switch (variable) {
|
||||
case 0x40: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch (variable) {
|
||||
case 0x40: return GetTerrainType(this->tile, this->context);
|
||||
}
|
||||
|
||||
DEBUG(grf, 1, "Unhandled new signals tile variable 0x%X", variable);
|
||||
|
||||
extra->available = false;
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
/* virtual */ const SpriteGroup *NewSignalsResolverObject::ResolveReal(const RealSpriteGroup *group) const
|
||||
{
|
||||
if (!group->loading.empty()) return group->loading[0];
|
||||
if (!group->loaded.empty()) return group->loaded[0];
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GrfSpecFeature NewSignalsResolverObject::GetFeature() const
|
||||
{
|
||||
return GSF_SIGNALS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolver object for rail types.
|
||||
* @param grffile GRF file.
|
||||
* @param tile %Tile containing the track. For track on a bridge this is the southern bridgehead.
|
||||
* @param context Are we resolving sprites for the upper halftile, or on a bridge?
|
||||
* @param param1 Extra parameter (first parameter of the callback, except railtypes do not have callbacks).
|
||||
* @param param2 Extra parameter (second parameter of the callback, except railtypes do not have callbacks).
|
||||
*/
|
||||
NewSignalsResolverObject::NewSignalsResolverObject(const GRFFile *grffile, TileIndex tile, TileContext context, uint32 param1, uint32 param2)
|
||||
: ResolverObject(grffile, CBID_NO_CALLBACK, param1, param2), newsignals_scope(*this, tile, context)
|
||||
{
|
||||
this->root_spritegroup = grffile != nullptr ? grffile->new_signals_group : nullptr;
|
||||
}
|
57
src/newgrf_newsignals.h
Normal file
57
src/newgrf_newsignals.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file newgrf_newsignals.h NewGRF handling of new signals. */
|
||||
|
||||
#ifndef NEWGRF_NEWSIGNALS_H
|
||||
#define NEWGRF_NEWSIGNALS_H
|
||||
|
||||
#include "newgrf_commons.h"
|
||||
#include "newgrf_spritegroup.h"
|
||||
|
||||
extern std::vector<const GRFFile *> _new_signals_grfs;
|
||||
|
||||
/** Resolver for the new signals scope. */
|
||||
struct NewSignalsScopeResolver : public ScopeResolver {
|
||||
TileIndex tile; ///< Tracktile. For track on a bridge this is the southern bridgehead.
|
||||
TileContext context; ///< Are we resolving sprites for the upper halftile, or on a bridge?
|
||||
|
||||
/**
|
||||
* Constructor of the railtype scope resolvers.
|
||||
* @param ro Surrounding resolver.
|
||||
* @param tile %Tile containing the track. For track on a bridge this is the southern bridgehead.
|
||||
* @param context Are we resolving sprites for the upper halftile, or on a bridge?
|
||||
*/
|
||||
NewSignalsScopeResolver(ResolverObject &ro, TileIndex tile, TileContext context)
|
||||
: ScopeResolver(ro), tile(tile), context(context)
|
||||
{
|
||||
}
|
||||
|
||||
uint32 GetRandomBits() const override;
|
||||
uint32 GetVariable(byte variable, uint32 parameter, GetVariableExtra *extra) const override;
|
||||
};
|
||||
|
||||
/** Resolver object for rail types. */
|
||||
struct NewSignalsResolverObject : public ResolverObject {
|
||||
NewSignalsScopeResolver newsignals_scope; ///< Resolver for the new signals scope.
|
||||
|
||||
NewSignalsResolverObject(const GRFFile *grffile, TileIndex tile, TileContext context, uint32 param1 = 0, uint32 param2 = 0);
|
||||
|
||||
ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) override
|
||||
{
|
||||
switch (scope) {
|
||||
case VSG_SCOPE_SELF: return &this->newsignals_scope;
|
||||
default: return ResolverObject::GetScope(scope, relative);
|
||||
}
|
||||
}
|
||||
|
||||
const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const override;
|
||||
|
||||
GrfSpecFeature GetFeature() const override;
|
||||
};
|
||||
|
||||
#endif /* NEWGRF_RAILTYPE_H */
|
@@ -10,6 +10,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "debug.h"
|
||||
#include "newgrf_railtype.h"
|
||||
#include "newgrf_newsignals.h"
|
||||
#include "date_func.h"
|
||||
#include "depot_base.h"
|
||||
#include "town.h"
|
||||
@@ -114,17 +115,7 @@ SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSp
|
||||
return group->GetResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the sprite to draw for a given signal.
|
||||
* @param rti The rail type data (spec).
|
||||
* @param tile The tile to get the sprite for.
|
||||
* @param type Signal type.
|
||||
* @param var Signal variant.
|
||||
* @param state Signal state.
|
||||
* @param gui Is the sprite being used on the map or in the GUI?
|
||||
* @return The sprite to draw.
|
||||
*/
|
||||
SpriteID GetCustomSignalSprite(const RailtypeInfo *rti, TileIndex tile, SignalType type, SignalVariant var, SignalState state, bool gui, bool restricted)
|
||||
static SpriteID GetRailTypeCustomSignalSprite(const RailtypeInfo *rti, TileIndex tile, SignalType type, SignalVariant var, SignalState state, bool gui, bool restricted)
|
||||
{
|
||||
if (rti->group[RTSG_SIGNALS] == nullptr) return 0;
|
||||
if (type == SIGTYPE_PROG && !HasBit(rti->ctrl_flags, RTCF_PROGSIG)) return 0;
|
||||
@@ -140,6 +131,36 @@ SpriteID GetCustomSignalSprite(const RailtypeInfo *rti, TileIndex tile, SignalTy
|
||||
return group->GetResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the sprite to draw for a given signal.
|
||||
* @param rti The rail type data (spec).
|
||||
* @param tile The tile to get the sprite for.
|
||||
* @param type Signal type.
|
||||
* @param var Signal variant.
|
||||
* @param state Signal state.
|
||||
* @param gui Is the sprite being used on the map or in the GUI?
|
||||
* @return The sprite to draw.
|
||||
*/
|
||||
CustomSignalSpriteResult GetCustomSignalSprite(const RailtypeInfo *rti, TileIndex tile, SignalType type, SignalVariant var, SignalState state, bool gui, bool restricted)
|
||||
{
|
||||
SpriteID spr = GetRailTypeCustomSignalSprite(rti, tile, type, var, state, gui, restricted);
|
||||
if (spr != 0) return { spr, HasBit(rti->ctrl_flags, RTCF_PROGSIG) };
|
||||
|
||||
for (const GRFFile *grf : _new_signals_grfs) {
|
||||
if (type == SIGTYPE_PROG && !HasBit(grf->new_signal_ctrl_flags, NSCF_PROGSIG)) continue;
|
||||
|
||||
uint32 param1 = gui ? 0x10 : 0x00;
|
||||
uint32 param2 = (type << 16) | (var << 8) | state;
|
||||
if (restricted && HasBit(grf->new_signal_ctrl_flags, NSCF_RESTRICTEDSIG)) SetBit(param2, 24);
|
||||
NewSignalsResolverObject object(grf, tile, TCX_NORMAL, param1, param2);
|
||||
|
||||
const SpriteGroup *group = object.Resolve();
|
||||
if (group != nullptr && group->GetNumResults() != 0) return { group->GetResult(), HasBit(grf->new_signal_ctrl_flags, NSCF_RESTRICTEDSIG) };
|
||||
}
|
||||
|
||||
return { 0, false };
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate an index to the GRF-local railtype-translation table into a RailType.
|
||||
* @param railtype Index into GRF-local translation table.
|
||||
|
@@ -55,8 +55,13 @@ struct RailTypeResolverObject : public ResolverObject {
|
||||
uint32 GetDebugID() const override;
|
||||
};
|
||||
|
||||
struct CustomSignalSpriteResult {
|
||||
SpriteID sprite_id;
|
||||
bool restricted_valid;
|
||||
};
|
||||
|
||||
SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg, TileContext context = TCX_NORMAL, uint *num_results = nullptr);
|
||||
SpriteID GetCustomSignalSprite(const RailtypeInfo *rti, TileIndex tile, SignalType type, SignalVariant var, SignalState state, bool gui = false, bool restricted = false);
|
||||
CustomSignalSpriteResult GetCustomSignalSprite(const RailtypeInfo *rti, TileIndex tile, SignalType type, SignalVariant var, SignalState state, bool gui = false, bool restricted = false);
|
||||
|
||||
RailType GetRailTypeTranslation(uint8 railtype, const GRFFile *grffile);
|
||||
uint8 GetReverseRailTypeTranslation(RailType railtype, const GRFFile *grffile);
|
||||
|
@@ -113,8 +113,8 @@ void ResolveRailTypeGUISprites(RailtypeInfo *rti)
|
||||
|
||||
for (SignalType type = SIGTYPE_NORMAL; type < SIGTYPE_END; type = (SignalType)(type + 1)) {
|
||||
for (SignalVariant var = SIG_ELECTRIC; var <= SIG_SEMAPHORE; var = (SignalVariant)(var + 1)) {
|
||||
SpriteID red = GetCustomSignalSprite(rti, INVALID_TILE, type, var, SIGNAL_STATE_RED, true);
|
||||
SpriteID green = GetCustomSignalSprite(rti, INVALID_TILE, type, var, SIGNAL_STATE_GREEN, true);
|
||||
SpriteID red = GetCustomSignalSprite(rti, INVALID_TILE, type, var, SIGNAL_STATE_RED, true).sprite_id;
|
||||
SpriteID green = GetCustomSignalSprite(rti, INVALID_TILE, type, var, SIGNAL_STATE_GREEN, true).sprite_id;
|
||||
rti->gui_sprites.signals[type][var][0] = (red != 0) ? red + SIGNAL_TO_SOUTH : _signal_lookup[var][type];
|
||||
rti->gui_sprites.signals[type][var][1] = (green != 0) ? green + SIGNAL_TO_SOUTH : _signal_lookup[var][type] + 1;
|
||||
}
|
||||
@@ -2670,7 +2670,8 @@ void DrawSingleSignal(TileIndex tile, const RailtypeInfo *rti, Track track, Sign
|
||||
uint x, y;
|
||||
GetSignalXY(tile, pos, x, y);
|
||||
|
||||
SpriteID sprite = GetCustomSignalSprite(rti, tile, type, variant, condition, false, show_restricted);
|
||||
const CustomSignalSpriteResult result = GetCustomSignalSprite(rti, tile, type, variant, condition, false, show_restricted);
|
||||
SpriteID sprite = result.sprite_id;
|
||||
bool is_custom_sprite = (sprite != 0);
|
||||
if (sprite != 0) {
|
||||
sprite += image;
|
||||
@@ -2692,7 +2693,7 @@ void DrawSingleSignal(TileIndex tile, const RailtypeInfo *rti, Track track, Sign
|
||||
is_custom_sprite = file != nullptr && (file->flags & SFF_USERGRF) && !(file->flags & SFF_OGFX);
|
||||
}
|
||||
|
||||
if (is_custom_sprite && show_restricted && _settings_client.gui.show_restricted_signal_default && !HasBit(rti->ctrl_flags, RTCF_RESTRICTEDSIG)) {
|
||||
if (is_custom_sprite && show_restricted && _settings_client.gui.show_restricted_signal_default && !result.restricted_valid) {
|
||||
/* Use duplicate sprite block, instead of GRF-specified signals */
|
||||
if (type == SIGTYPE_PROG) {
|
||||
if (variant == SIG_SEMAPHORE) {
|
||||
|
@@ -1719,7 +1719,7 @@ static void DrawTunnelBridgeRampSingleSignal(const TileInfo *ti, bool is_green,
|
||||
SignalVariant variant = IsTunnelBridgeSemaphore(ti->tile) ? SIG_SEMAPHORE : SIG_ELECTRIC;
|
||||
const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
|
||||
|
||||
SpriteID sprite = GetCustomSignalSprite(rti, ti->tile, type, variant, is_green ? SIGNAL_STATE_GREEN : SIGNAL_STATE_RED);
|
||||
SpriteID sprite = GetCustomSignalSprite(rti, ti->tile, type, variant, is_green ? SIGNAL_STATE_GREEN : SIGNAL_STATE_RED).sprite_id;
|
||||
bool is_custom_sprite = (sprite != 0);
|
||||
|
||||
if (is_custom_sprite) {
|
||||
|
Reference in New Issue
Block a user