diff --git a/src/gamedata/d_dehacked.cpp b/src/gamedata/d_dehacked.cpp index c7105117d..7156796db 100644 --- a/src/gamedata/d_dehacked.cpp +++ b/src/gamedata/d_dehacked.cpp @@ -282,6 +282,7 @@ static int PatchSize; static char *Line1, *Line2; static int dversion, pversion; static bool including, includenotext; +static int LumpFileNum; static const char *unknown_str = "Unknown key %s encountered in %s %d.\n"; @@ -2169,7 +2170,7 @@ static int PatchMusic (int dummy) keystring << "MUSIC_" << Line1; - TableElement te = { newname, newname, newname, newname }; + TableElement te = { LumpFileNum, { newname, newname, newname, newname } }; DehStrings.Insert(keystring, te); DPrintf (DMSG_SPAMMY, "Music %s set to:\n%s\n", keystring.GetChars(), newname.GetChars()); } @@ -2285,7 +2286,7 @@ static int PatchText (int oldSize) if (str != NULL) { FString newname = newStr; - TableElement te = { newname, newname, newname, newname }; + TableElement te = { LumpFileNum, { newname, newname, newname, newname } }; DehStrings.Insert(str, te); EnglishStrings.Remove(str); // remove entry so that it won't get found again by the next iteration or by another replacement later good = true; @@ -2340,7 +2341,7 @@ static int PatchStrings (int dummy) // Account for a discrepancy between Boom's and ZDoom's name for the red skull key pickup message const char *ll = Line1; if (!stricmp(ll, "GOTREDSKULL")) ll = "GOTREDSKUL"; - TableElement te = { holdstring, holdstring, holdstring, holdstring }; + TableElement te = { LumpFileNum, { holdstring, holdstring, holdstring, holdstring } }; DehStrings.Insert(ll, te); DPrintf (DMSG_SPAMMY, "%s set to:\n%s\n", Line1, holdstring.GetChars()); } @@ -2496,13 +2497,19 @@ int D_LoadDehLumps(DehLumpSource source) bool D_LoadDehLump(int lumpnum) { + auto ls = LumpFileNum; + LumpFileNum = Wads.GetLumpFile(lumpnum); + PatchSize = Wads.LumpLength(lumpnum); PatchName = copystring(Wads.GetLumpFullPath(lumpnum)); PatchFile = new char[PatchSize + 1]; Wads.ReadLump(lumpnum, PatchFile); PatchFile[PatchSize] = '\0'; // terminate with a '\0' character - return DoDehPatch(); + auto res = DoDehPatch(); + LumpFileNum = ls; + + return res; } bool D_LoadDehFile(const char *patchfile) diff --git a/src/gamedata/stringtable.cpp b/src/gamedata/stringtable.cpp index ea8fa074b..724951c22 100644 --- a/src/gamedata/stringtable.cpp +++ b/src/gamedata/stringtable.cpp @@ -67,8 +67,8 @@ void FStringTable::LoadStrings () { auto lumpdata = Wads.ReadLumpIntoArray(lump); - if (!ParseLanguageCSV(lumpdata)) - LoadLanguage (lumpdata); + if (!ParseLanguageCSV(lump, lumpdata)) + LoadLanguage (lump, lumpdata); } UpdateLanguage(); allMacros.Clear(); @@ -191,7 +191,7 @@ bool FStringTable::readMacros(int lumpnum) // //========================================================================== -bool FStringTable::ParseLanguageCSV(const TArray &buffer) +bool FStringTable::ParseLanguageCSV(int lumpnum, const TArray &buffer) { if (memcmp(buffer.Data(), "default,", 8)) return false; auto data = parseCSV(buffer); @@ -199,6 +199,7 @@ bool FStringTable::ParseLanguageCSV(const TArray &buffer) int labelcol = -1; int filtercol = -1; TArray> langrows; + bool hasDefaultEntry = false; if (data.Size() > 0) { @@ -221,6 +222,7 @@ bool FStringTable::ParseLanguageCSV(const TArray &buffer) if (lang.CompareNoCase("default") == 0) { langrows.Push(std::make_pair(column, default_table)); + hasDefaultEntry = true; } else if (lang.Len() < 4) { @@ -243,12 +245,16 @@ bool FStringTable::ParseLanguageCSV(const TArray &buffer) } FName strName = row[labelcol]; + if (hasDefaultEntry) + { + DeleteForLabel(lumpnum, strName); + } for (auto &langentry : langrows) { auto str = row[langentry.first]; if (str.Len() > 0) { - InsertString(langentry.second, strName, str); + InsertString(lumpnum, langentry.second, strName, str); } else { @@ -266,7 +272,7 @@ bool FStringTable::ParseLanguageCSV(const TArray &buffer) // //========================================================================== -void FStringTable::LoadLanguage (const TArray &buffer) +void FStringTable::LoadLanguage (int lumpnum, const TArray &buffer) { bool errordone = false; TArray activeMaps; @@ -363,10 +369,14 @@ void FStringTable::LoadLanguage (const TArray &buffer) } if (!skip) { + if (activeMaps[0] == default_table) + { + DeleteForLabel(lumpnum, strName); + } // Insert the string into all relevant tables. for (auto map : activeMaps) { - InsertString(map, strName, strText); + InsertString(lumpnum, map, strName, strText); } } } @@ -384,16 +394,40 @@ void FStringTable::DeleteString(int langid, FName label) allStrings[langid].Remove(label); } +//========================================================================== +// +// This deletes all older entries for a given label. This gets called +// when a string in the default table gets updated. +// +//========================================================================== + +void FStringTable::DeleteForLabel(int lumpnum, FName label) +{ + decltype(allStrings)::Iterator it(allStrings); + decltype(allStrings)::Pair *pair; + auto filenum = Wads.GetLumpFile(lumpnum); + + while (it.NextPair(pair)) + { + auto entry = pair->Value.CheckKey(label); + if (entry && entry->filenum < filenum) + { + pair->Value.Remove(label); + } + } + +} + //========================================================================== // // // //========================================================================== -void FStringTable::InsertString(int langid, FName label, const FString &string) +void FStringTable::InsertString(int lumpnum, int langid, FName label, const FString &string) { const char *strlangid = (const char *)&langid; - TableElement te = { string, string, string, string }; + TableElement te = { lumpnum, { string, string, string, string } }; long index; while ((index = te.strings[0].IndexOf("@[")) >= 0) { diff --git a/src/gamedata/stringtable.h b/src/gamedata/stringtable.h index e96d29c58..37dac5553 100644 --- a/src/gamedata/stringtable.h +++ b/src/gamedata/stringtable.h @@ -49,6 +49,7 @@ struct TableElement { + int filenum; FString strings[4]; }; @@ -104,14 +105,15 @@ private: LangMap allStrings; TArray> currentLanguageSet; - void LoadLanguage (const TArray &buffer); + void LoadLanguage (int lumpnum, const TArray &buffer); TArray> parseCSV(const TArray &buffer); - bool ParseLanguageCSV(const TArray &buffer); + bool ParseLanguageCSV(int lumpnum, const TArray &buffer); bool LoadLanguageFromSpreadsheet(int lumpnum, const TArray &buffer); bool readMacros(int lumpnum); - void InsertString(int langid, FName label, const FString &string); + void InsertString(int lumpnum, int langid, FName label, const FString &string); void DeleteString(int langid, FName label); + void DeleteForLabel(int lumpnum, FName label); static size_t ProcessEscapes (char *str); };