1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-26 22:57:00 +02:00

Merge pull request #3502 from IvanSavenko/campaign_localization_fix

Fixed missing translation strings on loading campaign save
This commit is contained in:
Ivan Savenko 2024-01-16 11:49:25 +02:00 committed by GitHub
commit bdd649a3be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 66 additions and 24 deletions

View File

@ -264,11 +264,14 @@ void TextLocalizationContainer::registerStringOverride(const std::string & modCo
void TextLocalizationContainer::addSubContainer(const TextLocalizationContainer & container)
{
assert(!vstd::contains(subContainers, &container));
subContainers.push_back(&container);
}
void TextLocalizationContainer::removeSubContainer(const TextLocalizationContainer & container)
{
assert(vstd::contains(subContainers, &container));
subContainers.erase(std::remove(subContainers.begin(), subContainers.end(), &container), subContainers.end());
}
@ -414,6 +417,28 @@ void TextLocalizationContainer::jsonSerialize(JsonNode & dest) const
}
}
TextContainerRegistrable::TextContainerRegistrable()
{
VLC->generaltexth->addSubContainer(*this);
}
TextContainerRegistrable::~TextContainerRegistrable()
{
VLC->generaltexth->removeSubContainer(*this);
}
TextContainerRegistrable::TextContainerRegistrable(const TextContainerRegistrable & other)
: TextLocalizationContainer(other)
{
VLC->generaltexth->addSubContainer(*this);
}
TextContainerRegistrable::TextContainerRegistrable(TextContainerRegistrable && other) noexcept
:TextLocalizationContainer(other)
{
VLC->generaltexth->addSubContainer(*this);
}
void CGeneralTextHandler::readToVector(const std::string & sourceID, const std::string & sourceName)
{
CLegacyConfigParser parser(TextPath::builtin(sourceName));

View File

@ -218,6 +218,18 @@ public:
}
};
class DLL_LINKAGE TextContainerRegistrable : public TextLocalizationContainer
{
public:
TextContainerRegistrable();
~TextContainerRegistrable();
TextContainerRegistrable(const TextContainerRegistrable & other);
TextContainerRegistrable(TextContainerRegistrable && other) noexcept;
TextContainerRegistrable& operator=(TextContainerRegistrable b) = delete;
};
/// Handles all text-related data in game
class DLL_LINKAGE CGeneralTextHandler: public TextLocalizationContainer
{

View File

@ -124,7 +124,7 @@ static std::string convertMapName(std::string input)
return input;
}
std::string CampaignHandler::readLocalizedString(CBinaryReader & reader, std::string filename, std::string modName, std::string encoding, std::string identifier)
std::string CampaignHandler::readLocalizedString(CampaignHeader & target, CBinaryReader & reader, std::string filename, std::string modName, std::string encoding, std::string identifier)
{
TextIdentifier stringID( "campaign", convertMapName(filename), identifier);
@ -133,7 +133,7 @@ std::string CampaignHandler::readLocalizedString(CBinaryReader & reader, std::st
if (input.empty())
return "";
VLC->generaltexth->registerString(modName, stringID, input);
target.getTexts().registerString(modName, stringID, input);
return stringID.get();
}
@ -383,8 +383,8 @@ void CampaignHandler::readHeaderFromMemory( CampaignHeader & ret, CBinaryReader
ret.version = static_cast<CampaignVersion>(reader.readUInt32());
ui8 campId = reader.readUInt8() - 1;//change range of it from [1, 20] to [0, 19]
ret.loadLegacyData(campId);
ret.name.appendTextID(readLocalizedString(reader, filename, modName, encoding, "name"));
ret.description.appendTextID(readLocalizedString(reader, filename, modName, encoding, "description"));
ret.name.appendTextID(readLocalizedString(ret, reader, filename, modName, encoding, "name"));
ret.description.appendTextID(readLocalizedString(ret, reader, filename, modName, encoding, "description"));
if (ret.version > CampaignVersion::RoE)
ret.difficultyChoosenByPlayer = reader.readInt8();
else
@ -396,7 +396,7 @@ void CampaignHandler::readHeaderFromMemory( CampaignHeader & ret, CBinaryReader
ret.encoding = encoding;
}
CampaignScenario CampaignHandler::readScenarioFromMemory( CBinaryReader & reader, const CampaignHeader & header)
CampaignScenario CampaignHandler::readScenarioFromMemory( CBinaryReader & reader, CampaignHeader & header)
{
auto prologEpilogReader = [&](const std::string & identifier) -> CampaignScenarioPrologEpilog
{
@ -410,7 +410,7 @@ CampaignScenario CampaignHandler::readScenarioFromMemory( CBinaryReader & reader
ret.prologVideo = CampaignHandler::prologVideoName(index);
ret.prologMusic = CampaignHandler::prologMusicName(reader.readUInt8());
ret.prologVoice = isOriginalCampaign ? CampaignHandler::prologVoiceName(index) : AudioPath();
ret.prologText.appendTextID(readLocalizedString(reader, header.filename, header.modName, header.encoding, identifier));
ret.prologText.appendTextID(readLocalizedString(header, reader, header.filename, header.modName, header.encoding, identifier));
}
return ret;
};
@ -428,7 +428,7 @@ CampaignScenario CampaignHandler::readScenarioFromMemory( CBinaryReader & reader
}
ret.regionColor = reader.readUInt8();
ret.difficulty = reader.readUInt8();
ret.regionText.appendTextID(readLocalizedString(reader, header.filename, header.modName, header.encoding, ret.mapName + ".region"));
ret.regionText.appendTextID(readLocalizedString(header, reader, header.filename, header.modName, header.encoding, ret.mapName + ".region"));
ret.prolog = prologEpilogReader(ret.mapName + ".prolog");
ret.epilog = prologEpilogReader(ret.mapName + ".epilog");

View File

@ -16,7 +16,7 @@ VCMI_LIB_NAMESPACE_BEGIN
class DLL_LINKAGE CampaignHandler
{
static std::string readLocalizedString(CBinaryReader & reader, std::string filename, std::string modName, std::string encoding, std::string identifier);
static std::string readLocalizedString(CampaignHeader & target, CBinaryReader & reader, std::string filename, std::string modName, std::string encoding, std::string identifier);
static void readCampaign(Campaign * target, const std::vector<ui8> & stream, std::string filename, std::string modName, std::string encoding);
@ -27,7 +27,7 @@ class DLL_LINKAGE CampaignHandler
//parsers for original H3C campaigns
static void readHeaderFromMemory(CampaignHeader & target, CBinaryReader & reader, std::string filename, std::string modName, std::string encoding);
static CampaignScenario readScenarioFromMemory(CBinaryReader & reader, const CampaignHeader & header);
static CampaignScenario readScenarioFromMemory(CBinaryReader & reader, CampaignHeader & header);
static CampaignTravel readScenarioTravelFromMemory(CBinaryReader & reader, CampaignVersion version);
/// returns h3c split in parts. 0 = h3c header, 1-end - maps (binary h3m)
/// headerOnly - only header will be decompressed, returned vector wont have any maps

View File

@ -169,6 +169,11 @@ const CampaignRegions & CampaignHeader::getRegions() const
return campaignRegions;
}
TextContainerRegistrable & CampaignHeader::getTexts()
{
return textContainer;
}
bool CampaignState::isConquered(CampaignScenarioID whichScenario) const
{
return vstd::contains(mapsConquered, whichScenario);

View File

@ -9,9 +9,10 @@
*/
#pragma once
#include "../lib/GameConstants.h"
#include "../lib/MetaString.h"
#include "../lib/filesystem/ResourcePath.h"
#include "../GameConstants.h"
#include "../MetaString.h"
#include "../filesystem/ResourcePath.h"
#include "../CGeneralTextHandler.h"
#include "CampaignConstants.h"
#include "CampaignScenarioPrologEpilog.h"
@ -87,6 +88,8 @@ class DLL_LINKAGE CampaignHeader : public boost::noncopyable
void loadLegacyData(ui8 campId);
TextContainerRegistrable textContainer;
public:
bool playerSelectedDifficulty() const;
bool formatVCMI() const;
@ -99,6 +102,7 @@ public:
AudioPath getMusic() const;
const CampaignRegions & getRegions() const;
TextContainerRegistrable & getTexts();
template <typename Handler> void serialize(Handler &h, const int formatVersion)
{
@ -112,6 +116,8 @@ public:
h & modName;
h & music;
h & encoding;
if (formatVersion >= 832)
h & textContainer;
}
};

View File

@ -122,13 +122,9 @@ CMapHeader::CMapHeader() : version(EMapFormat::VCMI), height(72), width(72),
setupEvents();
allowedHeroes = VLC->heroh->getDefaultAllowed();
players.resize(PlayerColor::PLAYER_LIMIT_I);
VLC->generaltexth->addSubContainer(*this);
}
CMapHeader::~CMapHeader()
{
VLC->generaltexth->removeSubContainer(*this);
}
CMapHeader::~CMapHeader() = default;
ui8 CMapHeader::levels() const
{
@ -137,9 +133,6 @@ ui8 CMapHeader::levels() const
void CMapHeader::registerMapStrings()
{
VLC->generaltexth->removeSubContainer(*this);
VLC->generaltexth->addSubContainer(*this);
//get supported languages. Assuming that translation containing most strings is the base language
std::set<std::string> mapLanguages, mapBaseLanguages;
int maxStrings = 0;
@ -193,7 +186,7 @@ void CMapHeader::registerMapStrings()
JsonUtils::mergeCopy(data, translations[language]);
for(auto & s : data.Struct())
registerString("map", TextIdentifier(s.first), s.second.String(), language);
texts.registerString("map", TextIdentifier(s.first), s.second.String(), language);
}
std::string mapRegisterLocalizedString(const std::string & modContext, CMapHeader & mapHeader, const TextIdentifier & UID, const std::string & localized)
@ -203,7 +196,7 @@ std::string mapRegisterLocalizedString(const std::string & modContext, CMapHeade
std::string mapRegisterLocalizedString(const std::string & modContext, CMapHeader & mapHeader, const TextIdentifier & UID, const std::string & localized, const std::string & language)
{
mapHeader.registerString(modContext, UID, localized, language);
mapHeader.texts.registerString(modContext, UID, localized, language);
mapHeader.translations.Struct()[language].Struct()[UID.get()].String() = localized;
return UID.get();
}

View File

@ -192,7 +192,7 @@ struct DLL_LINKAGE TriggeredEvent
};
/// The map header holds information about loss/victory condition,map format, version, players, height, width,...
class DLL_LINKAGE CMapHeader: public TextLocalizationContainer
class DLL_LINKAGE CMapHeader
{
void setupEvents();
public:
@ -240,13 +240,14 @@ public:
/// translations for map to be transferred over network
JsonNode translations;
TextContainerRegistrable texts;
void registerMapStrings();
template <typename Handler>
void serialize(Handler & h, const int Version)
{
h & static_cast<TextLocalizationContainer&>(*this);
h & texts;
h & version;
h & mods;
h & name;