From f5d78f9eba44eb687193b5734134ca838ad961c1 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sat, 7 Dec 2024 11:26:53 +0000 Subject: [PATCH] Change: [NewGRF] Install translation tables into overridden NewGRF. (#12879) When a NewGRF overrides another, any translation table that the overriding NewGRF installs will also be installed in the target file. This allows the overridden NewGRF to make use of a cargo or rail/road type translation table without directly modifying the original file. --- src/newgrf.cpp | 49 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 0021a989bb..0c1b8b1e03 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -602,6 +602,20 @@ static void SetNewGRFOverride(uint32_t source_grfid, uint32_t target_grfid) } } +/** + * Get overridden GRF for current GRF if present. + * @return Overridden GRFFile if present, or nullptr. + */ +static GRFFile *GetCurrentGRFOverride() +{ + auto found = _grf_id_overrides.find(_cur.grffile->grfid); + if (found != std::end(_grf_id_overrides)) { + GRFFile *grffile = GetFileByGRFID(found->second); + if (grffile != nullptr) return grffile; + } + return nullptr; +} + /** * Returns the engine associated to a certain internal_id, resp. allocates it. * @param file NewGRF that wants to change the engine. @@ -2687,24 +2701,33 @@ static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, Byt * @param gvid ID of the global variable. This is basically only checked for zerones. * @param numinfo Number of subsequent IDs to change the property for. * @param buf The property value. - * @param[in,out] translation_table Storage location for the translation table. + * @param gettable Function to get storage for the translation table. * @param name Name of the table for debug output. * @return ChangeInfoResult. */ -template -static ChangeInfoResult LoadTranslationTable(uint gvid, int numinfo, ByteReader &buf, std::vector &translation_table, const char *name) +template +static ChangeInfoResult LoadTranslationTable(uint gvid, int numinfo, ByteReader &buf, TGetTableFunc gettable, std::string_view name) { if (gvid != 0) { GrfMsg(1, "LoadTranslationTable: {} translation table must start at zero", name); return CIR_INVALID_ID; } + std::vector &translation_table = gettable(*_cur.grffile); translation_table.clear(); translation_table.reserve(numinfo); for (int i = 0; i < numinfo; i++) { translation_table.push_back(T(BSWAP32(buf.ReadDWord()))); } + GRFFile *grf_override = GetCurrentGRFOverride(); + if (grf_override != nullptr) { + /* GRF override is present, copy the translation table to the overridden GRF as well. */ + GrfMsg(1, "LoadTranslationTable: Copying {} translation table to override GRFID '{}'", name, BSWAP32(grf_override->grfid)); + std::vector &override_table = gettable(*grf_override); + override_table = translation_table; + } + return CIR_SUCCESS; } @@ -2734,16 +2757,16 @@ static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, By /* Properties which are handled as a whole */ switch (prop) { case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos) - return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo"); + return LoadTranslationTable(gvid, numinfo, buf, [](GRFFile &grf) -> std::vector & { return grf.cargo_list; }, "Cargo"); case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes) - return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type"); + return LoadTranslationTable(gvid, numinfo, buf, [](GRFFile &grf) -> std::vector & { return grf.railtype_list; }, "Rail type"); - case 0x16: // Road type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes) - return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->roadtype_list, "Road type"); + case 0x16: // Road type translation table; loading during both reservation and activation stage (in case it is selected depending on defined roadtypes) + return LoadTranslationTable(gvid, numinfo, buf, [](GRFFile &grf) -> std::vector & { return grf.roadtype_list; }, "Road type"); - case 0x17: // Tram type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes) - return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->tramtype_list, "Tram type"); + case 0x17: // Tram type translation table; loading during both reservation and activation stage (in case it is selected depending on defined tramtypes) + return LoadTranslationTable(gvid, numinfo, buf, [](GRFFile &grf) -> std::vector & { return grf.tramtype_list; }, "Tram type"); default: break; @@ -2952,16 +2975,16 @@ static ChangeInfoResult GlobalVarReserveInfo(uint gvid, int numinfo, int prop, B /* Properties which are handled as a whole */ switch (prop) { case 0x09: // Cargo Translation Table; loading during both reservation and activation stage (in case it is selected depending on defined cargos) - return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->cargo_list, "Cargo"); + return LoadTranslationTable(gvid, numinfo, buf, [](GRFFile &grf) -> std::vector & { return grf.cargo_list; }, "Cargo"); case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes) - return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type"); + return LoadTranslationTable(gvid, numinfo, buf, [](GRFFile &grf) -> std::vector & { return grf.railtype_list; }, "Rail type"); case 0x16: // Road type translation table; loading during both reservation and activation stage (in case it is selected depending on defined roadtypes) - return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->roadtype_list, "Road type"); + return LoadTranslationTable(gvid, numinfo, buf, [](GRFFile &grf) -> std::vector & { return grf.roadtype_list; }, "Road type"); case 0x17: // Tram type translation table; loading during both reservation and activation stage (in case it is selected depending on defined tramtypes) - return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->tramtype_list, "Tram type"); + return LoadTranslationTable(gvid, numinfo, buf, [](GRFFile &grf) -> std::vector & { return grf.tramtype_list; }, "Tram type"); default: break;