summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/newgrf.cpp43
-rw-r--r--src/newgrf.h4
-rw-r--r--src/rail.cpp12
-rw-r--r--src/rail.h12
-rw-r--r--src/rail_type.h2
-rw-r--r--src/table/railtypes.h12
6 files changed, 83 insertions, 2 deletions
diff --git a/src/newgrf.cpp b/src/newgrf.cpp
index dae87a922..baed23f6f 100644
--- a/src/newgrf.cpp
+++ b/src/newgrf.cpp
@@ -479,6 +479,17 @@ static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop
case 0x05: { // Track type
uint8 tracktype = grf_load_byte(&buf);
+ if (tracktype < _cur_grffile->railtype_max) {
+ RailType railtype = GetRailTypeByLabel(_cur_grffile->railtype_list[tracktype]);
+ if (railtype == INVALID_RAILTYPE) {
+ /* Rail type is not available, so disable this engine */
+ ei[i].climates = 0x80;
+ } else {
+ rvi[i].railtype = railtype;
+ }
+ break;
+ }
+
switch (tracktype) {
case 0: rvi->railtype = rvi->engclass >= 2 ? RAILTYPE_ELECTRIC : RAILTYPE_RAIL; break;
case 1: rvi->railtype = RAILTYPE_MONO; break;
@@ -610,8 +621,13 @@ static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop
} else {
break;
}
- if (rvi->railtype == RAILTYPE_RAIL && engclass >= EC_ELECTRIC) rvi->railtype = RAILTYPE_ELECTRIC;
- if (rvi->railtype == RAILTYPE_ELECTRIC && engclass < EC_ELECTRIC) rvi->railtype = RAILTYPE_RAIL;
+
+ if (_cur_grffile->railtype_max == 0) {
+ /* Use traction type to select between normal and electrified
+ * rail only when no translation list is in place. */
+ if (rvi->railtype == RAILTYPE_RAIL && engclass >= EC_ELECTRIC) rvi->railtype = RAILTYPE_ELECTRIC;
+ if (rvi->railtype == RAILTYPE_ELECTRIC && engclass < EC_ELECTRIC) rvi->railtype = RAILTYPE_RAIL;
+ }
rvi->engclass = engclass;
} break;
@@ -1749,6 +1765,12 @@ static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, by
buf += 8;
break;
+ case 0x12: // Rail type translation table
+ /* This is loaded during the reservation stage, so just skip it here. */
+ /* Each entry is 4 bytes. */
+ buf += 4;
+ break;
+
default:
ret = CIR_UNKNOWN;
break;
@@ -1810,6 +1832,23 @@ static ChangeInfoResult GlobalVarReserveInfo(uint gvid, int numinfo, int prop, b
break;
}
+ case 0x12: { // Rail type translation table
+ if (i == 0) {
+ if (gvid != 0) {
+ grfmsg(1, "ReserveChangeInfo: Rail type translation table must start at zero");
+ return CIR_INVALID_ID;
+ }
+
+ free(_cur_grffile->railtype_list);
+ _cur_grffile->railtype_max = numinfo;
+ _cur_grffile->railtype_list = MallocT<RailTypeLabel>(numinfo);
+ }
+
+ RailTypeLabel rtl = grf_load_dword(&buf);
+ _cur_grffile->railtype_list[i] = BSWAP32(rtl);
+ break;
+ }
+
default:
ret = CIR_UNKNOWN;
break;
diff --git a/src/newgrf.h b/src/newgrf.h
index 83690e003..172de0d5f 100644
--- a/src/newgrf.h
+++ b/src/newgrf.h
@@ -10,6 +10,7 @@
#include "cargotype.h"
#include "industry_type.h"
#include "station_type.h"
+#include "rail_type.h"
enum GrfLoadingStage {
GLS_FILESCAN,
@@ -98,6 +99,9 @@ struct GRFFile {
uint8 cargo_max;
CargoLabel *cargo_list;
uint8 cargo_map[NUM_CARGO];
+
+ uint8 railtype_max;
+ RailTypeLabel *railtype_list;
};
extern GRFFile *_first_grffile;
diff --git a/src/rail.cpp b/src/rail.cpp
index ddc716206..aa5ade657 100644
--- a/src/rail.cpp
+++ b/src/rail.cpp
@@ -207,3 +207,15 @@ RailTypes GetCompanyRailtypes(CompanyID company)
return rt;
}
+
+RailType GetRailTypeByLabel(RailTypeLabel label)
+{
+ /* Loop through each rail type until the label is found */
+ for (RailType r = RAILTYPE_BEGIN; r != RAILTYPE_END; r++) {
+ const RailtypeInfo *rti = GetRailTypeInfo(r);
+ if (rti->label == 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 a787165ad..5a9236597 100644
--- a/src/rail.h
+++ b/src/rail.h
@@ -132,6 +132,11 @@ struct RailtypeInfo {
* Cost multiplier for building this rail type
*/
uint8 cost_multiplier;
+
+ /**
+ * Unique 32 bit rail type identifier
+ */
+ RailTypeLabel label;
};
@@ -255,6 +260,13 @@ RailType GetBestRailtype(const CompanyID company);
RailTypes GetCompanyRailtypes(const CompanyID c);
/**
+ * Get the rail type for a given label.
+ * @param label the railtype label.
+ * @return the railtype.
+ */
+RailType GetRailTypeByLabel(RailTypeLabel label);
+
+/**
* Reset all rail type information to its default values.
*/
void ResetRailTypes();
diff --git a/src/rail_type.h b/src/rail_type.h
index 73876bd4a..e4cf3905d 100644
--- a/src/rail_type.h
+++ b/src/rail_type.h
@@ -7,6 +7,8 @@
#include "core/enum_type.hpp"
+typedef uint32 RailTypeLabel;
+
/**
* Enumeration for all possible railtypes.
*
diff --git a/src/table/railtypes.h b/src/table/railtypes.h
index 037014541..b1082689c 100644
--- a/src/table/railtypes.h
+++ b/src/table/railtypes.h
@@ -73,6 +73,9 @@ static const RailtypeInfo _original_railtypes[] = {
/* cost multiplier */
8,
+
+ /* rail type label */
+ 'RAIL',
},
/** Electrified railway */
@@ -142,6 +145,9 @@ static const RailtypeInfo _original_railtypes[] = {
/* cost multiplier */
12,
+
+ /* rail type label */
+ 'ELRL',
},
/** Monorail */
@@ -207,6 +213,9 @@ static const RailtypeInfo _original_railtypes[] = {
/* cost multiplier */
16,
+
+ /* rail type label */
+ 'MONO',
},
/** Maglev */
@@ -272,6 +281,9 @@ static const RailtypeInfo _original_railtypes[] = {
/* cost multiplier */
24,
+
+ /* rail type label */
+ 'MGLV',
},
};