Browse Source

Text of configurable/rewardable objects now uses translator

Ivan Savenko 2 years ago
parent
commit
3a348abf4f

+ 8 - 3
lib/CTownHandler.cpp

@@ -63,14 +63,19 @@ std::string CBuilding::getDescriptionTranslated() const
 	return VLC->generaltexth->translate(getDescriptionTextID());
 }
 
+std::string CBuilding::getBaseTextID() const
+{
+	return TextIdentifier("building", modScope, town->faction->identifier, identifier).get();
+}
+
 std::string CBuilding::getNameTextID() const
 {
-	return TextIdentifier("building", modScope, town->faction->identifier, identifier, "name").get();
+	return TextIdentifier(getBaseTextID(), "name").get();
 }
 
 std::string CBuilding::getDescriptionTextID() const
 {
-	return TextIdentifier("building", modScope, town->faction->identifier, identifier, "description").get();
+	return TextIdentifier(getBaseTextID(), "description").get();
 }
 
 BuildingID CBuilding::getBase() const
@@ -639,7 +644,7 @@ void CTownHandler::loadBuilding(CTown * town, const std::string & stringID, cons
 		if(source["type"].String() == "configurable" && ret->subId == BuildingSubID::NONE)
 		{
 			ret->subId = BuildingSubID::CUSTOM_VISITING_REWARD;
-			ret->rewardableObjectInfo.init(source);
+			ret->rewardableObjectInfo.init(source, ret->getBaseTextID());
 		}
 	}
 	//MODS COMPATIBILITY FOR 0.96

+ 1 - 0
lib/CTownHandler.h

@@ -88,6 +88,7 @@ public:
 	std::string getNameTranslated() const;
 	std::string getDescriptionTranslated() const;
 
+	std::string getBaseTextID() const;
 	std::string getNameTextID() const;
 	std::string getDescriptionTextID() const;
 

+ 15 - 0
lib/JsonNode.cpp

@@ -460,6 +460,21 @@ const JsonNode & JsonNode::operator[](const std::string & child) const
 	return nullNode;
 }
 
+JsonNode & JsonNode::operator[](size_t child)
+{
+	if (child >= Vector().size() )
+		Vector().resize(child + 1);
+	return Vector()[child];
+}
+
+const JsonNode & JsonNode::operator[](size_t child) const
+{
+	if (child < Vector().size() )
+		return Vector()[child];
+
+	return nullNode;
+}
+
 const JsonNode & JsonNode::resolvePointer(const std::string &jsonPointer) const
 {
 	return ::resolvePointer(*this, jsonPointer);

+ 3 - 0
lib/JsonNode.h

@@ -129,6 +129,9 @@ public:
 	JsonNode & operator[](const std::string & child);
 	const JsonNode & operator[](const std::string & child) const;
 
+	JsonNode & operator[](size_t child);
+	const JsonNode & operator[](size_t  child) const;
+
 	std::string toJson(bool compact = false) const;
 
 	template <typename Handler> void serialize(Handler &h, const int version)

+ 6 - 1
lib/mapObjectConstructors/AObjectTypeHandler.cpp

@@ -133,9 +133,14 @@ bool AObjectTypeHandler::hasNameTextID() const
 	return false;
 }
 
+std::string AObjectTypeHandler::getBaseTextID() const
+{
+	return TextIdentifier("mapObject", modScope, typeName, subTypeName).get();
+}
+
 std::string AObjectTypeHandler::getNameTextID() const
 {
-	return TextIdentifier("mapObject", modScope, typeName, subTypeName, "name").get();
+	return TextIdentifier(getBaseTextID(), "name").get();
 }
 
 std::string AObjectTypeHandler::getNameTranslated() const

+ 3 - 0
lib/mapObjectConstructors/AObjectTypeHandler.h

@@ -89,6 +89,9 @@ public:
 	/// returns true if this class provides custom text ID's instead of generic per-object name
 	virtual bool hasNameTextID() const;
 
+	/// returns base prefix for all translatable strings of this object
+	std::string getBaseTextID() const;
+
 	/// returns object's name in form of translatable text ID
 	virtual std::string getNameTextID() const;
 

+ 1 - 1
lib/mapObjectConstructors/CRewardableConstructor.cpp

@@ -18,7 +18,7 @@ VCMI_LIB_NAMESPACE_BEGIN
 
 void CRewardableConstructor::initTypeData(const JsonNode & config)
 {
-	objectInfo.init(config);
+	objectInfo.init(config, getBaseTextID());
 	blockVisit = config["blockedVisitable"].Bool();
 
 	if (!config["name"].isNull())

+ 4 - 1
lib/mapObjects/CGTownBuilding.cpp

@@ -297,7 +297,10 @@ CTownRewardableBuilding::CTownRewardableBuilding(const BuildingID & index, Build
 void CTownRewardableBuilding::initObj(CRandomGenerator & rand)
 {
 	assert(town && town->town);
-	town->town->buildings.at(bID)->rewardableObjectInfo.configureObject(configuration, rand);
+
+	auto building = town->town->buildings.at(bID);
+
+	building->rewardableObjectInfo.configureObject(configuration, rand);
 	for(auto & rewardInfo : configuration.info)
 	{
 		for (auto & bonus : rewardInfo.reward.bonuses)

+ 55 - 23
lib/rewardable/Info.cpp

@@ -10,33 +10,33 @@
 
 #include "StdInc.h"
 #include "Info.h"
+
+#include "Configuration.h"
 #include "Limiter.h"
 #include "Reward.h"
-#include "Configuration.h"
 
-#include "../CCreatureSet.h"
-#include "../CRandomGenerator.h"
-#include "../StringConstants.h"
-#include "../CCreatureHandler.h"
-#include "../CModHandler.h"
-#include "../NetPacksBase.h"
-#include "../JsonRandom.h"
-#include "../IGameCallback.h"
 #include "../CGeneralTextHandler.h"
-#include "../JsonNode.h"
+#include "../CModHandler.h"
 #include "../IGameCallback.h"
+#include "../JsonRandom.h"
 #include "../mapObjects/IObjectInterface.h"
 
 VCMI_LIB_NAMESPACE_BEGIN
 
 namespace {
-	MetaString loadMessage(const JsonNode & value)
+	MetaString loadMessage(const JsonNode & value, const TextIdentifier & textIdentifier )
 	{
 		MetaString ret;
 		if (value.isNumber())
+		{
 			ret.appendLocalString(EMetaText::ADVOB_TXT, static_cast<ui32>(value.Float()));
-		else
-			ret.appendRawString(value.String());
+			return ret;
+		}
+
+		if (value.String().empty())
+			return ret;
+
+		ret.appendTextID(textIdentifier.get());
 		return ret;
 	}
 
@@ -51,9 +51,38 @@ namespace {
 	}
 }
 
-void Rewardable::Info::init(const JsonNode & objectConfig)
+void Rewardable::Info::init(const JsonNode & objectConfig, const std::string & objectName)
 {
+	objectTextID = objectName;
+
+	auto loadString = [&](const JsonNode & entry, const TextIdentifier & textID){
+		if (entry.isString() && !entry.String().empty())
+			VLC->generaltexth->registerString(entry.meta, textID, entry.String());
+	};
+
 	parameters = objectConfig;
+
+	for(size_t i = 0; i < parameters["rewards"].Vector().size(); ++i)
+	{
+		const JsonNode message = parameters["rewards"][i]["message"];
+		loadString(message, TextIdentifier(objectName, "rewards", i));
+	}
+
+	for(size_t i = 0; i < parameters["onVisited"].Vector().size(); ++i)
+	{
+		const JsonNode message = parameters["onVisited"][i]["message"];
+		loadString(message, TextIdentifier(objectName, "onVisited", i));
+	}
+
+	for(size_t i = 0; i < parameters["onEmpty"].Vector().size(); ++i)
+	{
+		const JsonNode message = parameters["onEmpty"][i]["message"];
+		loadString(message, TextIdentifier(objectName, "onEmpty", i));
+	}
+
+	loadString(parameters["onSelectMessage"], TextIdentifier(objectName, "onSelect"));
+	loadString(parameters["onVisitedMessage"], TextIdentifier(objectName, "onVisited"));
+	loadString(parameters["onEmptyMessage"], TextIdentifier(objectName, "onEmpty"));
 }
 
 Rewardable::LimitersList Rewardable::Info::configureSublimiters(Rewardable::Configuration & object, CRandomGenerator & rng, const JsonNode & source) const
@@ -157,10 +186,13 @@ void Rewardable::Info::configureRewards(
 		CRandomGenerator & rng, const
 		JsonNode & source,
 		std::map<si32, si32> & thrownDice,
-		Rewardable::EEventType event ) const
+		Rewardable::EEventType event,
+		const std::string & modeName) const
 {
-	for (const JsonNode & reward : source.Vector())
+	for(size_t i = 0; i < source.Vector().size(); ++i)
 	{
+		const JsonNode reward = source.Vector()[i];
+
 		if (!reward["appearChance"].isNull())
 		{
 			JsonNode chance = reward["appearChance"];
@@ -188,7 +220,7 @@ void Rewardable::Info::configureRewards(
 		configureReward(object, rng, info.reward, reward);
 
 		info.visitType = event;
-		info.message = loadMessage(reward["message"]);
+		info.message = loadMessage(reward["message"], TextIdentifier(objectTextID, modeName, i));
 
 		for (const auto & artifact : info.reward.artifacts )
 			info.message.replaceLocalString(EMetaText::ART_NAMES, artifact.getNum());
@@ -206,17 +238,17 @@ void Rewardable::Info::configureObject(Rewardable::Configuration & object, CRand
 
 	std::map<si32, si32> thrownDice;
 
-	configureRewards(object, rng, parameters["rewards"], thrownDice, Rewardable::EEventType::EVENT_FIRST_VISIT);
-	configureRewards(object, rng, parameters["onVisited"], thrownDice, Rewardable::EEventType::EVENT_ALREADY_VISITED);
-	configureRewards(object, rng, parameters["onEmpty"], thrownDice, Rewardable::EEventType::EVENT_NOT_AVAILABLE);
+	configureRewards(object, rng, parameters["rewards"], thrownDice, Rewardable::EEventType::EVENT_FIRST_VISIT, "rewards");
+	configureRewards(object, rng, parameters["onVisited"], thrownDice, Rewardable::EEventType::EVENT_ALREADY_VISITED, "onVisited");
+	configureRewards(object, rng, parameters["onEmpty"], thrownDice, Rewardable::EEventType::EVENT_NOT_AVAILABLE, "onEmpty");
 
-	object.onSelect   = loadMessage(parameters["onSelectMessage"]);
+	object.onSelect   = loadMessage(parameters["onSelectMessage"], TextIdentifier(objectTextID, "onSelect"));
 
 	if (!parameters["onVisitedMessage"].isNull())
 	{
 		Rewardable::VisitInfo onVisited;
 		onVisited.visitType = Rewardable::EEventType::EVENT_ALREADY_VISITED;
-		onVisited.message = loadMessage(parameters["onVisitedMessage"]);
+		onVisited.message = loadMessage(parameters["onVisitedMessage"], TextIdentifier(objectTextID, "onVisited"));
 		object.info.push_back(onVisited);
 	}
 
@@ -224,7 +256,7 @@ void Rewardable::Info::configureObject(Rewardable::Configuration & object, CRand
 	{
 		Rewardable::VisitInfo onEmpty;
 		onEmpty.visitType = Rewardable::EEventType::EVENT_NOT_AVAILABLE;
-		onEmpty.message = loadMessage(parameters["onEmptyMessage"]);
+		onEmpty.message = loadMessage(parameters["onEmptyMessage"], TextIdentifier(objectTextID, "onEmpty"));
 		object.info.push_back(onEmpty);
 	}
 

+ 3 - 2
lib/rewardable/Info.h

@@ -30,8 +30,9 @@ enum class EEventType;
 class DLL_LINKAGE Info : public IObjectInfo
 {
 	JsonNode parameters;
+	std::string objectTextID;
 
-	void configureRewards(Rewardable::Configuration & object, CRandomGenerator & rng, const JsonNode & source, std::map<si32, si32> & thrownDice, Rewardable::EEventType mode) const;
+	void configureRewards(Rewardable::Configuration & object, CRandomGenerator & rng, const JsonNode & source, std::map<si32, si32> & thrownDice, Rewardable::EEventType mode, const std::string & textPrefix) const;
 
 	void configureLimiter(Rewardable::Configuration & object, CRandomGenerator & rng, Rewardable::Limiter & limiter, const JsonNode & source) const;
 	Rewardable::LimitersList configureSublimiters(Rewardable::Configuration & object, CRandomGenerator & rng, const JsonNode & source) const;
@@ -58,7 +59,7 @@ public:
 
 	void configureObject(Rewardable::Configuration & object, CRandomGenerator & rng) const;
 
-	void init(const JsonNode & objectConfig);
+	void init(const JsonNode & objectConfig, const std::string & objectTextID);
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{