Przeglądaj źródła

All Heroes 3 texts are now passed through translator

Ivan Savenko 2 lat temu
rodzic
commit
cb4f5edae9

+ 0 - 2
client/lobby/CBonusSelection.cpp

@@ -141,8 +141,6 @@ void CBonusSelection::loadPositionsOfGraphics()
 
 		idx++;
 	}
-
-	assert(idx == CGI->generaltexth->campaignMapNames.size());
 }
 
 void CBonusSelection::createBonusesIcons()

+ 3 - 3
client/lobby/SelectionTab.cpp

@@ -99,8 +99,8 @@ bool mapSorter::operator()(const std::shared_ptr<CMapInfo> aaa, const std::share
 		switch(sortBy)
 		{
 		case _numOfMaps: //by number of maps in campaign
-			return CGI->generaltexth->campaignRegionNames[aaa->campaignHeader->mapVersion].size() <
-				   CGI->generaltexth->campaignRegionNames[bbb->campaignHeader->mapVersion].size();
+			return CGI->generaltexth->getCampaignLength(aaa->campaignHeader->mapVersion) <
+				   CGI->generaltexth->getCampaignLength(bbb->campaignHeader->mapVersion);
 			break;
 		case _name: //by name
 			return boost::ilexicographical_compare(aaa->campaignHeader->name, bbb->campaignHeader->name);
@@ -660,7 +660,7 @@ void SelectionTab::ListItem::updateItem(std::shared_ptr<CMapInfo> info, bool sel
 		iconLossCondition->disable();
 		labelNumberOfCampaignMaps->enable();
 		std::ostringstream ostr(std::ostringstream::out);
-		ostr << CGI->generaltexth->campaignRegionNames[info->campaignHeader->mapVersion].size();
+		ostr << CGI->generaltexth->getCampaignLength(info->campaignHeader->mapVersion);
 		labelNumberOfCampaignMaps->setText(ostr.str());
 		labelNumberOfCampaignMaps->setColor(color);
 	}

+ 5 - 11
client/windows/CCreatureWindow.cpp

@@ -377,10 +377,7 @@ CStackWindow::CommanderMainSection::CommanderMainSection(CStackWindow * owner, i
 
 	auto getSkillDescription = [this](int skillIndex) -> std::string
 	{
-		if(CGI->generaltexth->znpc00.size() == 0)
-			return "";
-
-		return CGI->generaltexth->znpc00[151 + (12 * skillIndex) + (parent->info->commander->secondarySkills[skillIndex] * 2)];
+		return CGI->generaltexth->znpc00[152 + (12 * skillIndex) + (parent->info->commander->secondarySkills[skillIndex] * 2)];
 	};
 
 	for(int index = ECommander::ATTACK; index <= ECommander::SPELL_POWER; ++index)
@@ -868,9 +865,9 @@ std::string CStackWindow::generateStackExpDescription()
 	if (!vstd::iswithin(tier, 1, 7))
 		tier = 0;
 	int number;
-	std::string expText = CGI->generaltexth->zcrexp[325];
+	std::string expText = CGI->generaltexth->translate("vcmi.stackExperience.description");
 	boost::replace_first(expText, "%s", creature->namePl);
-	boost::replace_first(expText, "%s", CGI->generaltexth->zcrexp[rank]);
+	boost::replace_first(expText, "%s", CGI->generaltexth->translate("vcmi.stackExperience.rank", rank));
 	boost::replace_first(expText, "%i", boost::lexical_cast<std::string>(rank));
 	boost::replace_first(expText, "%i", boost::lexical_cast<std::string>(stack->experience));
 	number = static_cast<int>(CGI->creh->expRanks[tier][rank] - stack->experience);
@@ -905,13 +902,10 @@ void CStackWindow::setSelection(si32 newSkill, std::shared_ptr<CCommanderSkillIc
 {
 	auto getSkillDescription = [this](int skillIndex, bool selected) -> std::string
 	{
-		if(CGI->generaltexth->znpc00.size() == 0)
-			return "";
-
 		if(selected)
-			return CGI->generaltexth->znpc00[151 + (12 * skillIndex) + ((info->commander->secondarySkills[skillIndex] + 1) * 2)]; //upgrade description
+			return CGI->generaltexth->znpc00[152 + (12 * skillIndex) + ((info->commander->secondarySkills[skillIndex] + 1) * 2)]; //upgrade description
 		else
-			return CGI->generaltexth->znpc00[151 + (12 * skillIndex) + (info->commander->secondarySkills[skillIndex] * 2)];
+			return CGI->generaltexth->znpc00[152 + (12 * skillIndex) + (info->commander->secondarySkills[skillIndex] * 2)];
 	};
 
 	auto getSkillImage = [this](int skillIndex) -> std::string

+ 15 - 1
config/translate.json

@@ -66,5 +66,19 @@
 	"vcmi.randomMapTab.widgets.defaultTemplate"      : "default",
 	"vcmi.randomMapTab.widgets.templateLabel"        : "Template",
 	"vcmi.randomMapTab.widgets.teamAlignmentsButton" : "Setup...",
-	"vcmi.randomMapTab.widgets.teamAlignmentsLabel"  : "Team alignments"
+	"vcmi.randomMapTab.widgets.teamAlignmentsLabel"  : "Team alignments",
+	
+	// few strings from WoG used by vcmi
+	"vcmi.stackExperience.description" : "» S t a c k   E x p e r i e n c e   D e t a i l s «\n\nCreature Type ................... : %s\nExperience Rank ................. : %s (%i)\nExperience Points ............... : %i\nExperience Points to Next Rank .. : %i\nMaximum Experience per Battle ... : %i%% (%i)\nNumber of Creatures in stack .... : %i\nMaximum New Recruits\n without losing current Rank .... : %i\nExperience Multiplier ........... : %.2f\nUpgrade Multiplier .............. : %.2f\nExperience after Rank 10 ........ : %i\nMaximum New Recruits to remain at\n Rank 10 if at Maximum Experience : %i",
+	"vcmi.stackExperience.rank.1" : "Basic",
+	"vcmi.stackExperience.rank.2" : "Novice",
+	"vcmi.stackExperience.rank.3" : "Trained",
+	"vcmi.stackExperience.rank.4" : "Skilled",
+	"vcmi.stackExperience.rank.5" : "Proven",
+	"vcmi.stackExperience.rank.6" : "Veteran",
+	"vcmi.stackExperience.rank.7" : "Adept",
+	"vcmi.stackExperience.rank.8" : "Expert",
+	"vcmi.stackExperience.rank.9" : "Elite",
+	"vcmi.stackExperience.rank.10" : "Master",
+	"vcmi.stackExperience.rank.11" : "Ace"
 }

+ 26 - 39
lib/CGeneralTextHandler.cpp

@@ -380,6 +380,7 @@ CGeneralTextHandler::CGeneralTextHandler():
 	seerEmpty        (*this, "core.seerhut.empty"  ),
 	seerNames        (*this, "core.seerhut.names"  ),
 	capColors        (*this, "vcmi.capitalColors"  ),
+	znpc00           (*this, "vcmi.znpc00"  ), // technically - wog
 	qeModCommands    (*this, "vcmi.quickExchange" )
 {
 	readToVector("core.vcdesc",   "DATA/VCDESC.TXT"   );
@@ -506,70 +507,46 @@ CGeneralTextHandler::CGeneralTextHandler():
 		parser.endLine();
 
 		std::string text;
+		size_t campaignsCount = 0;
 		do
 		{
 			text = parser.readString();
 			if (!text.empty())
-				campaignMapNames.push_back(text);
+			{
+				registerH3String("core.camptext.names", campaignsCount, text);
+				campaignsCount += 1;
+			}
 		}
 		while (parser.endLine() && !text.empty());
 
-		for (size_t i=0; i<campaignMapNames.size(); i++)
+		for (size_t i=0; i<campaignsCount; i++)
 		{
+			size_t region = 0;
+
 			do // skip empty space and header
 			{
 				text = parser.readString();
 			}
 			while (parser.endLine() && text.empty());
 
-			campaignRegionNames.push_back(std::vector<std::string>());
 			do
 			{
 				text = parser.readString();
 				if (!text.empty())
-					campaignRegionNames.back().push_back(text);
+				{
+					registerH3String("core.camptext.regions." + std::to_string(campaignsCount), region, text);
+					region += 1;
+				}
 			}
 			while (parser.endLine() && !text.empty());
-		}
-	}
-	if (VLC->modh->modules.STACK_EXP)
-	{
-		CLegacyConfigParser parser("DATA/ZCREXP.TXT");
-		parser.endLine();//header
-		for (size_t iter=0; iter<325; iter++)
-		{
-			parser.readString(); //ignore 1st column with description
-			zcrexp.push_back(parser.readString());
-			parser.endLine();
-		}
-		// line 325 - some weird formatting here
-		zcrexp.push_back(parser.readString());
-		parser.readString();
-		parser.endLine();
 
-		do // rest of file can be read normally
-		{
-			parser.readString(); //ignore 1st column with description
-			zcrexp.push_back(parser.readString());
+			scenariosCountPerCampaign.push_back(region);
 		}
-		while (parser.endLine());
 	}
 	if (VLC->modh->modules.COMMANDERS)
 	{
-		try
-		{
-			CLegacyConfigParser parser("DATA/ZNPC00.TXT");
-			parser.endLine();//header
-
-			do
-			{
-				znpc00.push_back(parser.readString());
-			} while (parser.endLine());
-		}
-		catch (const std::runtime_error &)
-		{
-			logGlobal->warn("WoG file ZNPC00.TXT containing commander texts was not found");
-		}
+		if (CResourceHandler::get()->existsResource(ResourceID("DATA/ZNPC00.TXT", EResType::TEXT)))
+			readToVector("vcmi.znpc00", "DATA/ZNPC00.TXT" );
 	}
 
 	dumpAllTexts();
@@ -597,12 +574,22 @@ void CGeneralTextHandler::dumpAllTexts()
 		boost::replace_all(cleanString, "\n", "\\n");
 		boost::replace_all(cleanString, "\r", "\\r");
 		boost::replace_all(cleanString, "\t", "\\t");
+		boost::replace_all(cleanString, "\"", "\\\"");
 
 		logGlobal->info("\"%s\" : \"%s\",", entry.first, cleanString);
 	}
 	logGlobal->info("END TEXT EXPORT");
 }
 
+size_t CGeneralTextHandler::getCampaignLength(size_t campaignID) const
+{
+	assert(campaignID < scenariosCountPerCampaign.size());
+
+	if ( campaignID < scenariosCountPerCampaign.size())
+		return scenariosCountPerCampaign[campaignID];
+	return 0;
+}
+
 std::vector<std::string> CGeneralTextHandler::findStringsWithPrefix(std::string const & prefix)
 {
 	std::vector<std::string> result;

+ 10 - 7
lib/CGeneralTextHandler.h

@@ -130,7 +130,13 @@ class DLL_LINKAGE CGeneralTextHandler
 
 	void readToVector(std::string sourceID, std::string sourceName);
 
+	/// number of scenarios in specific campaign. TODO: move to a better location
+	std::vector<size_t> scenariosCountPerCampaign;
 public:
+	// returns true if identifier with such name was registered, even if not translated to current language
+	// not required right now, can be added if necessary
+	// bool identifierExists( const std::string identifier) const;
+
 	/// returns translated version of a string that can be displayed to user
 	const std::string & translate(const std::string & identifier) const;
 
@@ -143,7 +149,7 @@ public:
 	/// converts identifier into user-readable string, may be identical to 'translate' but reserved for serialization calls
 	const std::string & deserialize(const std::string & identifier) const;
 
-	/// Debug methods, dumps all currently known texts into console using Json-like format
+	/// Debug method, dumps all currently known texts into console using Json-like format
 	void dumpAllTexts();
 
 	LegacyTextContainer allTexts;
@@ -182,18 +188,15 @@ public:
 
 	//sec skills
 	LegacyTextContainer levels;
-	std::vector<std::string> zcrexp; //more or less useful content of that file
 	//commanders
-	std::vector<std::string> znpc00; //more or less useful content of that file
-
-	//campaigns
-	std::vector<std::string> campaignMapNames;
-	std::vector<std::vector<std::string>> campaignRegionNames;
+	LegacyTextContainer znpc00; //more or less useful content of that file
 
 	std::vector<std::string> findStringsWithPrefix(std::string const & prefix);
 
 	int32_t pluralText(const int32_t textIndex, const int32_t count) const;
 
+	size_t getCampaignLength(size_t campaignID) const;
+
 	CGeneralTextHandler();
 	CGeneralTextHandler(const CGeneralTextHandler&) = delete;
 	CGeneralTextHandler operator=(const CGeneralTextHandler&) = delete;

+ 1 - 1
lib/mapping/CCampaignHandler.cpp

@@ -79,7 +79,7 @@ std::unique_ptr<CCampaign> CCampaignHandler::getCampaign( const std::string & na
 	ret->header = readHeaderFromMemory(reader);
 	ret->header.filename = name;
 
-	int howManyScenarios = static_cast<int>(VLC->generaltexth->campaignRegionNames[ret->header.mapVersion].size());
+	int howManyScenarios = static_cast<int>(VLC->generaltexth->getCampaignLength(ret->header.mapVersion));
 	for(int g=0; g<howManyScenarios; ++g)
 	{
 		CCampaignScenario sc = readScenarioFromMemory(reader, ret->header.version, ret->header.mapVersion);

+ 2 - 0
lib/mapping/CCampaignHandler.h

@@ -229,6 +229,8 @@ public:
 
 class DLL_LINKAGE CCampaignHandler
 {
+	std::vector<size_t> scenariosCountPerCampaign;
+
 	static CCampaignHeader readHeaderFromMemory(CBinaryReader & reader);
 	static CCampaignScenario readScenarioFromMemory(CBinaryReader & reader, int version, int mapVersion );
 	static CScenarioTravel readScenarioTravelFromMemory(CBinaryReader & reader, int version);