1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-12-24 00:36:29 +02:00

Implemented translations for H3M maps

This commit is contained in:
Ivan Savenko
2023-02-25 17:44:15 +02:00
parent 5b767d8b0d
commit 260f6d626c
10 changed files with 110 additions and 69 deletions

View File

@@ -35,11 +35,12 @@ VCMI_LIB_NAMESPACE_BEGIN
const bool CMapLoaderH3M::IS_PROFILING_ENABLED = false;
CMapLoaderH3M::CMapLoaderH3M(const std::string & mapName, const std::string & encodingName, CInputStream * stream)
CMapLoaderH3M::CMapLoaderH3M(const std::string & mapName, const std::string & modName, const std::string & encodingName, CInputStream * stream)
: map(nullptr)
, reader(new CBinaryReader(stream))
, inputStream(stream)
, mapName(mapName)
, mapName(boost::algorithm::to_lower_copy(mapName))
, modName(modName)
, fileEncoding(encodingName)
{
}
@@ -161,8 +162,8 @@ void CMapLoaderH3M::readHeader()
mapHeader->areAnyPlayers = reader->readBool();
mapHeader->height = mapHeader->width = reader->readUInt32();
mapHeader->twoLevel = reader->readBool();
mapHeader->name = readLocalizedString();
mapHeader->description = readLocalizedString();
mapHeader->name = readLocalizedString("header.name");
mapHeader->description = readLocalizedString("header.description");
mapHeader->difficulty = reader->readInt8();
if(mapHeader->version != EMapFormat::ROE)
{
@@ -270,7 +271,7 @@ void CMapLoaderH3M::readPlayerInfo()
if (mapHeader->players[i].mainCustomHeroPortrait == 0xff)
mapHeader->players[i].mainCustomHeroPortrait = -1; //correct 1-byte -1 (0xff) into 4-byte -1
mapHeader->players[i].mainCustomHeroName = readLocalizedString();
mapHeader->players[i].mainCustomHeroName = readLocalizedString(TextIdentifier("header", "player", i, "mainHeroName"));
}
else
mapHeader->players[i].mainCustomHeroId = -1; //correct 1-byte -1 (0xff) into 4-byte -1
@@ -284,7 +285,7 @@ void CMapLoaderH3M::readPlayerInfo()
{
SHeroName vv;
vv.heroId = reader->readUInt8();
vv.heroName = readLocalizedString();
vv.heroName = readLocalizedString( TextIdentifier("header", "heroNames", vv.heroId));
mapHeader->players[i].heroesNames.push_back(vv);
}
@@ -650,7 +651,7 @@ void CMapLoaderH3M::readDisposedHeroes()
{
map->disposedHeroes[g].heroId = reader->readUInt8();
map->disposedHeroes[g].portrait = reader->readUInt8();
map->disposedHeroes[g].name = readLocalizedString();
map->disposedHeroes[g].name = readLocalizedString(TextIdentifier("header", "heroes", map->disposedHeroes[g].heroId));
map->disposedHeroes[g].players = reader->readUInt8();
}
}
@@ -738,8 +739,8 @@ void CMapLoaderH3M::readRumors()
for(int it = 0; it < rumNr; it++)
{
Rumor ourRumor;
ourRumor.name = readLocalizedString();
ourRumor.text = readLocalizedString();
ourRumor.name = readLocalizedString(TextIdentifier("header", "rumor", it, "name"));
ourRumor.text = readLocalizedString(TextIdentifier("header", "rumor", it, "text"));
map->rumors.push_back(ourRumor);
}
}
@@ -788,7 +789,7 @@ void CMapLoaderH3M::readPredefinedHeroes()
bool hasCustomBio = reader->readBool();
if(hasCustomBio)
{
hero->biographyCustom = readLocalizedString();
hero->biographyCustom = readLocalizedString(TextIdentifier("heroes", z, "biography"));
}
// 0xFF is default, 00 male, 01 female
@@ -994,7 +995,7 @@ void CMapLoaderH3M::readObjects()
auto * evnt = new CGEvent();
nobj = evnt;
readMessageAndGuards(evnt->message, evnt);
readMessageAndGuards(evnt->message, evnt, objPos);
evnt->gainedExp = reader->readUInt32();
evnt->manaDiff = reader->readUInt32();
@@ -1084,7 +1085,7 @@ void CMapLoaderH3M::readObjects()
bool hasMessage = reader->readBool();
if(hasMessage)
{
cre->message = readLocalizedString();
cre->message = readLocalizedString(TextIdentifier("monster", objPos.x, objPos.y, objPos.z, "message"));
readResourses(cre->resources);
int artID = 0;
@@ -1130,13 +1131,13 @@ void CMapLoaderH3M::readObjects()
{
auto * sb = new CGSignBottle();
nobj = sb;
sb->message = readLocalizedString();
sb->message = readLocalizedString(TextIdentifier("sign", objPos.x, objPos.y, objPos.z, "message"));
reader->skip(4);
break;
}
case Obj::SEER_HUT:
{
nobj = readSeerHut();
nobj = readSeerHut(objPos);
break;
}
case Obj::WITCH_HUT:
@@ -1217,7 +1218,7 @@ void CMapLoaderH3M::readObjects()
auto * art = new CGArtifact();
nobj = art;
readMessageAndGuards(art->message, art);
readMessageAndGuards(art->message, art, objPos);
if(objTempl->id == Obj::SPELL_SCROLL)
{
@@ -1239,7 +1240,7 @@ void CMapLoaderH3M::readObjects()
auto * res = new CGResource();
nobj = res;
readMessageAndGuards(res->message, res);
readMessageAndGuards(res->message, res, objPos);
res->amount = reader->readUInt32();
if(objTempl->subid == Res::GOLD)
@@ -1253,7 +1254,7 @@ void CMapLoaderH3M::readObjects()
case Obj::RANDOM_TOWN:
case Obj::TOWN:
{
nobj = readTown(objTempl->subid);
nobj = readTown(objTempl->subid, objPos);
break;
}
case Obj::MINE:
@@ -1298,7 +1299,7 @@ void CMapLoaderH3M::readObjects()
{
auto * box = new CGPandoraBox();
nobj = box;
readMessageAndGuards(box->message, box);
readMessageAndGuards(box->message, box, objPos);
box->gainedExp = reader->readUInt32();
box->manaDiff = reader->readUInt32();
@@ -1412,7 +1413,7 @@ void CMapLoaderH3M::readObjects()
case Obj::QUEST_GUARD:
{
auto * guard = new CGQuestGuard();
readQuest(guard);
readQuest(guard, objPos);
nobj = guard;
break;
}
@@ -1604,7 +1605,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(const ObjectInstanceID & idToBeGiven,
bool hasName = reader->readBool();
if(hasName)
{
nhi->nameCustom = readLocalizedString();
nhi->nameCustom = readLocalizedString(TextIdentifier("heroes", nhi->subID, "name"));
}
if(map->version > EMapFormat::AB)
{
@@ -1669,7 +1670,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(const ObjectInstanceID & idToBeGiven,
bool hasCustomBiography = reader->readBool();
if(hasCustomBiography)
{
nhi->biographyCustom = readLocalizedString();
nhi->biographyCustom = readLocalizedString(TextIdentifier("heroes", nhi->subID, "biography"));
}
nhi->sex = reader->readUInt8();
@@ -1740,13 +1741,13 @@ CGObjectInstance * CMapLoaderH3M::readHero(const ObjectInstanceID & idToBeGiven,
return nhi;
}
CGSeerHut * CMapLoaderH3M::readSeerHut()
CGSeerHut * CMapLoaderH3M::readSeerHut(const int3 & position)
{
auto * hut = new CGSeerHut();
if(map->version > EMapFormat::ROE)
{
readQuest(hut);
readQuest(hut, position);
}
else
{
@@ -1854,7 +1855,7 @@ CGSeerHut * CMapLoaderH3M::readSeerHut()
return hut;
}
void CMapLoaderH3M::readQuest(IQuestObject * guard)
void CMapLoaderH3M::readQuest(IQuestObject * guard, const int3 & position)
{
guard->quest->missionType = static_cast<CQuest::Emission>(reader->readUInt8());
@@ -1926,15 +1927,15 @@ void CMapLoaderH3M::readQuest(IQuestObject * guard)
{
guard->quest->lastDay = limit;
}
guard->quest->firstVisitText = readLocalizedString();
guard->quest->nextVisitText = readLocalizedString();
guard->quest->completedText = readLocalizedString();
guard->quest->firstVisitText = readLocalizedString(TextIdentifier("quest", position.x, position.y, position.z, "firstVisit"));
guard->quest->nextVisitText = readLocalizedString(TextIdentifier("quest", position.x, position.y, position.z, "nextVisit"));
guard->quest->completedText = readLocalizedString(TextIdentifier("quest", position.x, position.y, position.z, "completed"));
guard->quest->isCustomFirst = !guard->quest->firstVisitText.empty();
guard->quest->isCustomNext = !guard->quest->nextVisitText.empty();
guard->quest->isCustomComplete = !guard->quest->completedText.empty();
}
CGTownInstance * CMapLoaderH3M::readTown(int castleID)
CGTownInstance * CMapLoaderH3M::readTown(int castleID, const int3 & position)
{
auto * nt = new CGTownInstance();
if(map->version > EMapFormat::ROE)
@@ -1945,7 +1946,7 @@ CGTownInstance * CMapLoaderH3M::readTown(int castleID)
bool hasName = reader->readBool();
if(hasName)
{
nt->setNameTranslated( readLocalizedString());
nt->setNameTranslated(readLocalizedString(TextIdentifier("town", position.x, position.y, position.z, "name")));
}
bool hasGarrison = reader->readBool();
@@ -2025,8 +2026,8 @@ CGTownInstance * CMapLoaderH3M::readTown(int castleID)
{
CCastleEvent nce;
nce.town = nt;
nce.name = readLocalizedString();
nce.message = readLocalizedString();
nce.name = readBasicString();
nce.message = readLocalizedString(TextIdentifier("town", position.x, position.y, position.z, "event", gh, "description"));
readResourses(nce.resources);
@@ -2136,8 +2137,8 @@ void CMapLoaderH3M::readEvents()
for(int yyoo = 0; yyoo < numberOfEvents; ++yyoo)
{
CMapEvent ne;
ne.name = readLocalizedString();
ne.message = readLocalizedString();
ne.name = readBasicString();
ne.message = readLocalizedString(TextIdentifier("event", yyoo, "description"));
readResourses(ne.resources);
ne.players = reader->readUInt8();
@@ -2159,12 +2160,12 @@ void CMapLoaderH3M::readEvents()
}
}
void CMapLoaderH3M::readMessageAndGuards(std::string& message, CCreatureSet* guards)
void CMapLoaderH3M::readMessageAndGuards(std::string& message, CCreatureSet* guards, const int3 & position)
{
bool hasMessage = reader->readBool();
if(hasMessage)
{
message = readLocalizedString();
message = readLocalizedString(TextIdentifier("guards", position.x, position.y, position.z, "message"));
bool hasGuards = reader->readBool();
if(hasGuards)
{
@@ -2243,11 +2244,23 @@ int3 CMapLoaderH3M::readInt3()
return p;
}
std::string CMapLoaderH3M::readLocalizedString()
std::string CMapLoaderH3M::readBasicString()
{
return TextOperations::toUnicode(reader->readBaseString(), fileEncoding);
}
std::string CMapLoaderH3M::readLocalizedString(const TextIdentifier & stringIdentifier)
{
std::string mapString = TextOperations::toUnicode(reader->readBaseString(), fileEncoding);
TextIdentifier fullIdentifier(mapName, stringIdentifier.get());
if (mapString.empty())
return "";
VLC->generaltexth->registerString(modName, fullIdentifier, mapString);
return VLC->generaltexth->translate(fullIdentifier.get());
}
void CMapLoaderH3M::afterRead()
{
//convert main town positions for all players to actual object position, in H3M it is position of active tile