summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/newgrf.cpp22
-rw-r--r--src/rail.cpp11
-rw-r--r--src/rail.h10
-rw-r--r--src/rail_cmd.cpp3
-rw-r--r--src/table/railtypes.h12
5 files changed, 54 insertions, 4 deletions
diff --git a/src/newgrf.cpp b/src/newgrf.cpp
index 970ccec25..b8c75107e 100644
--- a/src/newgrf.cpp
+++ b/src/newgrf.cpp
@@ -3894,7 +3894,7 @@ static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteR
int n = buf->ReadByte();
for (int j = 0; j != n; j++) {
RailTypeLabel label = buf->ReadDWord();
- RailType rt = GetRailTypeByLabel(BSWAP32(label));
+ RailType rt = GetRailTypeByLabel(BSWAP32(label), false);
if (rt != INVALID_RAILTYPE) {
switch (prop) {
case 0x0E: SetBit(rti->compatible_railtypes, rt); break;
@@ -3952,6 +3952,11 @@ static ChangeInfoResult RailTypeChangeInfo(uint id, int numinfo, int prop, ByteR
rti->maintenance_multiplier = buf->ReadWord();
break;
+ case 0x1D: // Alternate rail type label list
+ /* Skipped here as this is loaded during reservation stage. */
+ for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord();
+ break;
+
default:
ret = CIR_UNKNOWN;
break;
@@ -3965,6 +3970,8 @@ static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, Byte
{
ChangeInfoResult ret = CIR_SUCCESS;
+ extern RailtypeInfo _railtypes[RAILTYPE_END];
+
if (id + numinfo > RAILTYPE_END) {
grfmsg(1, "RailTypeReserveInfo: Rail type %u is invalid, max %u, ignoring", id + numinfo, RAILTYPE_END);
return CIR_INVALID_ID;
@@ -3977,7 +3984,7 @@ static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, Byte
RailTypeLabel rtl = buf->ReadDWord();
rtl = BSWAP32(rtl);
- RailType rt = GetRailTypeByLabel(rtl);
+ RailType rt = GetRailTypeByLabel(rtl, false);
if (rt == INVALID_RAILTYPE) {
/* Set up new rail type */
rt = AllocateRailType(rtl);
@@ -3999,6 +4006,17 @@ static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, Byte
buf->ReadWord();
break;
+ case 0x1D: // Alternate rail type label list
+ if (_cur.grffile->railtype_map[id + i] != INVALID_RAILTYPE) {
+ int n = buf->ReadByte();
+ for (int j = 0; j != n; j++) {
+ *_railtypes[_cur.grffile->railtype_map[id + i]].alternate_labels.Append() = BSWAP32(buf->ReadDWord());
+ }
+ break;
+ }
+ grfmsg(1, "RailTypeReserveInfo: Ignoring property 1D for rail type %u because no label was set", id + i);
+ /* FALL THROUGH */
+
case 0x0E: // Compatible railtype list
case 0x0F: // Powered railtype list
case 0x18: // Railtype list required for date introduction
diff --git a/src/rail.cpp b/src/rail.cpp
index 13346d607..fa0d86c88 100644
--- a/src/rail.cpp
+++ b/src/rail.cpp
@@ -277,9 +277,10 @@ RailTypes GetCompanyRailtypes(CompanyID company)
/**
* Get the rail type for a given label.
* @param label the railtype label.
+ * @param allow_alternate_labels Search in the alternate label lists as well.
* @return the railtype.
*/
-RailType GetRailTypeByLabel(RailTypeLabel label)
+RailType GetRailTypeByLabel(RailTypeLabel label, bool allow_alternate_labels)
{
/* Loop through each rail type until the label is found */
for (RailType r = RAILTYPE_BEGIN; r != RAILTYPE_END; r++) {
@@ -287,6 +288,14 @@ RailType GetRailTypeByLabel(RailTypeLabel label)
if (rti->label == label) return r;
}
+ if (allow_alternate_labels) {
+ /* Test if any rail type defines the label as an alternate. */
+ for (RailType r = RAILTYPE_BEGIN; r != RAILTYPE_END; r++) {
+ const RailtypeInfo *rti = GetRailTypeInfo(r);
+ if (rti->alternate_labels.Contains(label)) return r;
+ }
+ }
+
/* No matching label was found, so it is invalid */
return INVALID_RAILTYPE;
}
diff --git a/src/rail.h b/src/rail.h
index be7a030c5..b8ef0cb12 100644
--- a/src/rail.h
+++ b/src/rail.h
@@ -96,6 +96,9 @@ enum RailFenceOffset {
RFO_SLOPE_NW,
};
+/** List of rail type labels. */
+typedef SmallVector<RailTypeLabel, 4> RailTypeLabelList;
+
/**
* This struct contains all the info that is needed to draw and construct tracks.
*/
@@ -209,6 +212,11 @@ struct RailtypeInfo {
RailTypeLabel label;
/**
+ * Rail type labels this type provides in addition to the main label.
+ */
+ RailTypeLabelList alternate_labels;
+
+ /**
* Colour on mini-map
*/
byte map_colour;
@@ -404,7 +412,7 @@ RailTypes AddDateIntroducedRailTypes(RailTypes current, Date date);
RailType GetBestRailtype(const CompanyID company);
RailTypes GetCompanyRailtypes(const CompanyID c);
-RailType GetRailTypeByLabel(RailTypeLabel label);
+RailType GetRailTypeByLabel(RailTypeLabel label, bool allow_alternate_labels = true);
void ResetRailTypes();
void InitRailTypes();
diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp
index 8d3dec5e5..49a58fe6d 100644
--- a/src/rail_cmd.cpp
+++ b/src/rail_cmd.cpp
@@ -99,6 +99,9 @@ RailType AllocateRailType(RailTypeLabel label)
/* Set up new rail type */
memcpy(rti, &_railtypes[RAILTYPE_RAIL], sizeof(*rti));
rti->label = label;
+ /* Clear alternate label list. Can't use Reset() here as that would free
+ * the data pointer of RAILTYPE_RAIL and not our new rail type. */
+ new (&rti->alternate_labels) RailTypeLabelList;
/* Make us compatible with ourself. */
rti->powered_railtypes = (RailTypes)(1 << rt);
diff --git a/src/table/railtypes.h b/src/table/railtypes.h
index 065f78720..3ff6d9638 100644
--- a/src/table/railtypes.h
+++ b/src/table/railtypes.h
@@ -93,6 +93,9 @@ static const RailtypeInfo _original_railtypes[] = {
/* rail type label */
'RAIL',
+ /* alternate labels */
+ RailTypeLabelList(),
+
/* map colour */
0x0A,
@@ -190,6 +193,9 @@ static const RailtypeInfo _original_railtypes[] = {
/* rail type label */
'ELRL',
+ /* alternate labels */
+ RailTypeLabelList(),
+
/* map colour */
0x0A,
@@ -283,6 +289,9 @@ static const RailtypeInfo _original_railtypes[] = {
/* rail type label */
'MONO',
+ /* alternate labels */
+ RailTypeLabelList(),
+
/* map colour */
0x0A,
@@ -376,6 +385,9 @@ static const RailtypeInfo _original_railtypes[] = {
/* rail type label */
'MGLV',
+ /* alternate labels */
+ RailTypeLabelList(),
+
/* map colour */
0x0A,