summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfrosch <frosch@openttd.org>2021-01-10 14:37:40 +0100
committerfrosch <github@elsenhans.name>2021-01-10 21:24:38 +0100
commit868d84bbfc8d2c1471ef713854dd05ebc872615a (patch)
treeeaad084698335fd20cd31e01729fa6e0eec9fa47
parent5b089605606ecbf6d7e9996b49f6cb0605deaa68 (diff)
downloadopenttd-868d84bbfc8d2c1471ef713854dd05ebc872615a.tar.xz
Add: [NewGRF] vehicle variable 63 to test the tracktype of the current tile against a given tracktype.
-rw-r--r--src/newgrf_engine.cpp30
-rw-r--r--src/newgrf_railtype.cpp22
-rw-r--r--src/newgrf_railtype.h1
-rw-r--r--src/newgrf_roadtype.cpp31
-rw-r--r--src/newgrf_roadtype.h1
-rw-r--r--src/table/newgrf_debug_data.h3
6 files changed, 87 insertions, 1 deletions
diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp
index 8066ea432..e3dc059ff 100644
--- a/src/newgrf_engine.cpp
+++ b/src/newgrf_engine.cpp
@@ -702,6 +702,36 @@ static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object,
return ret;
}
+ case 0x63:
+ /* Tile compatibility wrt. arbitrary track-type
+ * Format:
+ * bit 0: Type 'parameter' is known.
+ * bit 1: Engines with type 'parameter' are compatible with this tile.
+ * bit 2: Engines with type 'parameter' are powered on this tile.
+ * bit 3: This tile has type 'parameter' or it is considered equivalent (alternate labels).
+ */
+ switch (v->type) {
+ case VEH_TRAIN: {
+ RailType param_type = GetRailTypeTranslation(parameter, object->ro.grffile);
+ if (param_type == INVALID_RAILTYPE) return 0x00;
+ RailType tile_type = GetTileRailType(v->tile);
+ if (tile_type == param_type) return 0x0F;
+ return (HasPowerOnRail(param_type, tile_type) ? 0x04 : 0x00) |
+ (IsCompatibleRail(param_type, tile_type) ? 0x02 : 0x00) |
+ 0x01;
+ }
+ case VEH_ROAD: {
+ RoadTramType rtt = GetRoadTramType(RoadVehicle::From(v)->roadtype);
+ RoadType param_type = GetRoadTypeTranslation(rtt, parameter, object->ro.grffile);
+ if (param_type == INVALID_ROADTYPE) return 0x00;
+ RoadType tile_type = GetRoadType(v->tile, rtt);
+ if (tile_type == param_type) return 0x0F;
+ return (HasPowerOnRoad(param_type, tile_type) ? 0x06 : 0x00) |
+ 0x01;
+ }
+ default: return 0x00;
+ }
+
case 0xFE:
case 0xFF: {
uint16 modflags = 0;
diff --git a/src/newgrf_railtype.cpp b/src/newgrf_railtype.cpp
index 2a98948e7..326ee80ba 100644
--- a/src/newgrf_railtype.cpp
+++ b/src/newgrf_railtype.cpp
@@ -139,6 +139,28 @@ SpriteID GetCustomSignalSprite(const RailtypeInfo *rti, TileIndex tile, SignalTy
}
/**
+ * Translate an index to the GRF-local railtype-translation table into a RailType.
+ * @param railtype Index into GRF-local translation table.
+ * @param grffile Originating GRF file.
+ * @return RailType or INVALID_RAILTYPE if the railtype is unknown.
+ */
+RailType GetRailTypeTranslation(uint8 railtype, const GRFFile *grffile)
+{
+ if (grffile == nullptr || grffile->railtype_list.size() == 0) {
+ /* No railtype table present. Return railtype as-is (if valid), so it works for original railtypes. */
+ if (railtype >= RAILTYPE_END || GetRailTypeInfo(static_cast<RailType>(railtype))->label == 0) return INVALID_RAILTYPE;
+
+ return static_cast<RailType>(railtype);
+ } else {
+ /* Railtype table present, but invalid index, return invalid type. */
+ if (railtype >= grffile->railtype_list.size()) return INVALID_RAILTYPE;
+
+ /* Look up railtype including alternate labels. */
+ return GetRailTypeByLabel(grffile->railtype_list[railtype]);
+ }
+}
+
+/**
* Perform a reverse railtype lookup to get the GRF internal ID.
* @param railtype The global (OpenTTD) railtype.
* @param grffile The GRF to do the lookup for.
diff --git a/src/newgrf_railtype.h b/src/newgrf_railtype.h
index 1e0ff01d8..c38211738 100644
--- a/src/newgrf_railtype.h
+++ b/src/newgrf_railtype.h
@@ -58,6 +58,7 @@ struct RailTypeResolverObject : public ResolverObject {
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);
+RailType GetRailTypeTranslation(uint8 railtype, const GRFFile *grffile);
uint8 GetReverseRailTypeTranslation(RailType railtype, const GRFFile *grffile);
#endif /* NEWGRF_RAILTYPE_H */
diff --git a/src/newgrf_roadtype.cpp b/src/newgrf_roadtype.cpp
index 3f6150cd3..025d03bb6 100644
--- a/src/newgrf_roadtype.cpp
+++ b/src/newgrf_roadtype.cpp
@@ -133,6 +133,37 @@ SpriteID GetCustomRoadSprite(const RoadTypeInfo *rti, TileIndex tile, RoadTypeSp
}
/**
+ * Translate an index to the GRF-local road/tramtype-translation table into a RoadType.
+ * @param rtt Whether to index the road- or tramtype-table.
+ * @param tracktype Index into GRF-local translation table.
+ * @param grffile Originating GRF file.
+ * @return RoadType or INVALID_ROADTYPE if the roadtype is unknown.
+ */
+RoadType GetRoadTypeTranslation(RoadTramType rtt, uint8 tracktype, const GRFFile *grffile)
+{
+ /* Because OpenTTD mixes RoadTypes and TramTypes into the same type,
+ * the mapping of the original road- and tramtypes does not match the default GRF-local mapping.
+ * So, this function cannot provide any similar behavior to GetCargoTranslation() and GetRailTypeTranslation()
+ * when the GRF defines no translation table.
+ * But since there is only one default road/tram-type, this makes little sense anyway.
+ * So for GRF without translation table, we always return INVALID_ROADTYPE.
+ */
+
+ if (grffile == nullptr) return INVALID_ROADTYPE;
+
+ const auto &list = rtt == RTT_TRAM ? grffile->tramtype_list : grffile->roadtype_list;
+ if (tracktype >= list.size()) return INVALID_ROADTYPE;
+
+ /* Look up roadtype including alternate labels. */
+ RoadType result = GetRoadTypeByLabel(list[tracktype]);
+
+ /* Check whether the result is actually the wanted road/tram-type */
+ if (result != INVALID_ROADTYPE && GetRoadTramType(result) != rtt) return INVALID_ROADTYPE;
+
+ return result;
+}
+
+/**
* Perform a reverse roadtype lookup to get the GRF internal ID.
* @param roadtype The global (OpenTTD) roadtype.
* @param grffile The GRF to do the lookup for.
diff --git a/src/newgrf_roadtype.h b/src/newgrf_roadtype.h
index 07451f656..0e0869793 100644
--- a/src/newgrf_roadtype.h
+++ b/src/newgrf_roadtype.h
@@ -48,6 +48,7 @@ struct RoadTypeResolverObject : public ResolverObject {
SpriteID GetCustomRoadSprite(const RoadTypeInfo *rti, TileIndex tile, RoadTypeSpriteGroup rtsg, TileContext context = TCX_NORMAL, uint *num_results = nullptr);
+RoadType GetRoadTypeTranslation(RoadTramType rtt, uint8 tracktype, const GRFFile *grffile);
uint8 GetReverseRoadTypeTranslation(RoadType roadtype, const GRFFile *grffile);
#endif /* NEWGRF_ROADTYPE_H */
diff --git a/src/table/newgrf_debug_data.h b/src/table/newgrf_debug_data.h
index 4e5abaff5..d69c2d5cc 100644
--- a/src/table/newgrf_debug_data.h
+++ b/src/table/newgrf_debug_data.h
@@ -63,7 +63,8 @@ static const NIVariable _niv_vehicles[] = {
NIV(0x4D, "position in articulated vehicle"),
NIV(0x60, "count vehicle id occurrences"),
// 0x61 not useful, since it requires register 0x10F
- NIV(0x62, "Curvature/position difference to other vehicle"),
+ NIV(0x62, "curvature/position difference to other vehicle"),
+ NIV(0x63, "tile compatibility wrt. track-type"),
NIV_END()
};