changeset 18909:403293ec3333 draft

(svn r23758) -Feature: [NewGRF] Alternate rail type label list.
author michi_cc <michi_cc@openttd.org>
date Thu, 05 Jan 2012 19:40:34 +0000
parents b7744a321dc6
children b8b329975ee3
files src/newgrf.cpp src/rail.cpp src/rail.h src/rail_cmd.cpp src/table/railtypes.h
diffstat 5 files changed, 54 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/newgrf.cpp
+++ b/src/newgrf.cpp
@@ -3894,7 +3894,7 @@
 				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 @@
 				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 @@
 {
 	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 @@
 				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 @@
 				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
--- a/src/rail.cpp
+++ b/src/rail.cpp
@@ -277,9 +277,10 @@
 /**
  * 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 @@
 		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;
 }
--- a/src/rail.h
+++ b/src/rail.h
@@ -96,6 +96,9 @@
 	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 @@
 	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 @@
 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();
--- a/src/rail_cmd.cpp
+++ b/src/rail_cmd.cpp
@@ -99,6 +99,9 @@
 			/* 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);
--- a/src/table/railtypes.h
+++ b/src/table/railtypes.h
@@ -93,6 +93,9 @@
 		/* rail type label */
 		'RAIL',
 
+		/* alternate labels */
+		RailTypeLabelList(),
+
 		/* map colour */
 		0x0A,
 
@@ -190,6 +193,9 @@
 		/* rail type label */
 		'ELRL',
 
+		/* alternate labels */
+		RailTypeLabelList(),
+
 		/* map colour */
 		0x0A,
 
@@ -283,6 +289,9 @@
 		/* rail type label */
 		'MONO',
 
+		/* alternate labels */
+		RailTypeLabelList(),
+
 		/* map colour */
 		0x0A,
 
@@ -376,6 +385,9 @@
 		/* rail type label */
 		'MGLV',
 
+		/* alternate labels */
+		RailTypeLabelList(),
+
 		/* map colour */
 		0x0A,