浏览代码

use resolveidentifier

Laserlicht 3 周之前
父节点
当前提交
5da8a7a4dc

+ 2 - 1
client/windows/CCastleInterface.cpp

@@ -2212,7 +2212,8 @@ void CMageGuildScreen::Scroll::clickPressed(const Point & cursorPosition)
 			return;
 			return;
 		}
 		}
 
 
-		auto costBase = TResources(GAME->interface()->cb->getSettings().getValue(EGameSettings::TOWNS_SPELL_RESEARCH_COST).Vector()[level]);
+		ResourceSet costBase;
+		costBase.resolveFromJson(GAME->interface()->cb->getSettings().getValue(EGameSettings::TOWNS_SPELL_RESEARCH_COST).Vector()[level]);
 		auto costExponent = GAME->interface()->cb->getSettings().getValue(EGameSettings::TOWNS_SPELL_RESEARCH_COST_EXPONENT_PER_RESEARCH).Vector()[level].Float();
 		auto costExponent = GAME->interface()->cb->getSettings().getValue(EGameSettings::TOWNS_SPELL_RESEARCH_COST_EXPONENT_PER_RESEARCH).Vector()[level].Float();
 		auto cost = costBase * std::pow(town->spellResearchAcceptedCounter + 1, costExponent);
 		auto cost = costBase * std::pow(town->spellResearchAcceptedCounter + 1, costExponent);
 
 

+ 1 - 1
lib/CCreatureHandler.cpp

@@ -623,7 +623,7 @@ std::shared_ptr<CCreature> CCreatureHandler::loadFromJson(const std::string & sc
 	JsonDeserializer handler(nullptr, node);
 	JsonDeserializer handler(nullptr, node);
 	cre->serializeJson(handler);
 	cre->serializeJson(handler);
 
 
-	cre->cost = ResourceSet(node["cost"]);
+	cre->cost.resolveFromJson(node["cost"]);
 
 
 	LIBRARY->generaltexth->registerString(scope, cre->getNameSingularTextID(), node["name"]["singular"]);
 	LIBRARY->generaltexth->registerString(scope, cre->getNameSingularTextID(), node["name"]["singular"]);
 	LIBRARY->generaltexth->registerString(scope, cre->getNamePluralTextID(), node["name"]["plural"]);
 	LIBRARY->generaltexth->registerString(scope, cre->getNamePluralTextID(), node["name"]["plural"]);

+ 14 - 6
lib/ResourceSet.cpp

@@ -20,19 +20,27 @@ VCMI_LIB_NAMESPACE_BEGIN
 
 
 ResourceSet::ResourceSet()
 ResourceSet::ResourceSet()
 {
 {
-	container.resize(LIBRARY->resourceTypeHandler->getAllObjects().size());
+	resizeContainer();
 };
 };
 
 
-ResourceSet::ResourceSet(const JsonNode & node)
+ResourceSet::ResourceSet(const ResourceSet& rhs)
+	: container(rhs.container) // vector copy constructor
+{
+	resizeContainer();
+}
+
+void ResourceSet::resizeContainer()
 {
 {
 	container.resize(LIBRARY->resourceTypeHandler->getAllObjects().size());
 	container.resize(LIBRARY->resourceTypeHandler->getAllObjects().size());
-	for(auto & i : LIBRARY->resourceTypeHandler->getAllObjects())
-		container[i] = static_cast<int>(node[i.toResource()->getJsonKey()].Float());
 }
 }
 
 
-ResourceSet::ResourceSet(const ResourceSet& rhs)
-	: container(rhs.container) // vector copy constructor
+void ResourceSet::resolveFromJson(const JsonNode & node)
 {
 {
+	for(auto & n : node.Struct())
+		LIBRARY->identifiers()->requestIdentifier(n.second.getModScope(), "resource", n.first, [n, this](int32_t identifier)
+		{
+			(*this)[identifier] = static_cast<int>(n.second.Float());
+		});
 }
 }
 
 
 void ResourceSet::serializeJson(JsonSerializeFormat & handler, const std::string & fieldName)
 void ResourceSet::serializeJson(JsonSerializeFormat & handler, const std::string & fieldName)

+ 15 - 5
lib/ResourceSet.h

@@ -27,16 +27,18 @@ class ResourceSet
 {
 {
 private:
 private:
 	std::vector<TResource> container = {};
 	std::vector<TResource> container = {};
+	DLL_LINKAGE void resizeContainer();
 public:
 public:
-	// read resources set from json. Format example: { "gold": 500, "wood":5 }
-	DLL_LINKAGE ResourceSet(const JsonNode & node);
 	DLL_LINKAGE ResourceSet();
 	DLL_LINKAGE ResourceSet();
 	DLL_LINKAGE ResourceSet(const ResourceSet& rhs);
 	DLL_LINKAGE ResourceSet(const ResourceSet& rhs);
 
 
+	DLL_LINKAGE void resolveFromJson(const JsonNode & node);
+
 
 
 #define scalarOperator(OPSIGN)									\
 #define scalarOperator(OPSIGN)									\
 	ResourceSet& operator OPSIGN ## =(const TResource &rhs) \
 	ResourceSet& operator OPSIGN ## =(const TResource &rhs) \
 	{														\
 	{														\
+		resizeContainer(); \
 		for(auto i = 0; i < container.size(); i++)						\
 		for(auto i = 0; i < container.size(); i++)						\
 			container.at(i) OPSIGN ## = rhs;						\
 			container.at(i) OPSIGN ## = rhs;						\
 															\
 															\
@@ -46,6 +48,7 @@ public:
 #define vectorOperator(OPSIGN)										\
 #define vectorOperator(OPSIGN)										\
 	ResourceSet& operator OPSIGN ## =(const ResourceSet &rhs)	\
 	ResourceSet& operator OPSIGN ## =(const ResourceSet &rhs)	\
 	{															\
 	{															\
+		resizeContainer(); \
 		for(auto i = 0; i < container.size(); i++)							\
 		for(auto i = 0; i < container.size(); i++)							\
 			container.at(i) OPSIGN ## = rhs[i];						\
 			container.at(i) OPSIGN ## = rhs[i];						\
 																\
 																\
@@ -85,24 +88,31 @@ public:
 	// Array-like interface
 	// Array-like interface
 	TResource & operator[](GameResID index)
 	TResource & operator[](GameResID index)
 	{
 	{
+		resizeContainer();
 		return operator[](index.getNum());
 		return operator[](index.getNum());
 	}
 	}
 
 
 	const TResource & operator[](GameResID index) const 
 	const TResource & operator[](GameResID index) const 
 	{
 	{
+		if (index.getNum() >= container.size()) {
+			static const TResource defaultValue{};
+			return defaultValue;
+		}
 		return operator[](index.getNum());
 		return operator[](index.getNum());
 	}
 	}
 
 
 	TResource & operator[](size_t index)
 	TResource & operator[](size_t index)
 	{
 	{
+		resizeContainer();
 		return container.at(index);
 		return container.at(index);
 	}
 	}
 
 
 	const TResource & operator[](size_t index) const 
 	const TResource & operator[](size_t index) const 
 	{
 	{
-		if(index >= container.size())
-			logGlobal->error("Try to access resource which is not existing! Maybe new resources in mod not marked as modType=Resources?");
-
+		if (index >= container.size()) {
+			static const TResource defaultValue{};
+			return defaultValue;
+		}
 		return container.at(index);
 		return container.at(index);
 	}
 	}
 
 

+ 2 - 2
lib/entities/faction/CTownHandler.cpp

@@ -281,8 +281,8 @@ void CTownHandler::loadBuilding(CTown * town, const std::string & stringID, cons
 	LIBRARY->generaltexth->registerString(source.getModScope(), ret->getDescriptionTextID(), source["description"]);
 	LIBRARY->generaltexth->registerString(source.getModScope(), ret->getDescriptionTextID(), source["description"]);
 
 
 	ret->subId = vstd::find_or(MappedKeys::SPECIAL_BUILDINGS, source["type"].String(), BuildingSubID::NONE);
 	ret->subId = vstd::find_or(MappedKeys::SPECIAL_BUILDINGS, source["type"].String(), BuildingSubID::NONE);
-	ret->resources = TResources(source["cost"]);
-	ret->produce =   TResources(source["produce"]);
+	ret->resources.resolveFromJson(source["cost"]);
+	ret->produce.resolveFromJson(source["produce"]);
 
 
 	ret->manualHeroVisit = source["manualHeroVisit"].Bool();
 	ret->manualHeroVisit = source["manualHeroVisit"].Bool();
 	ret->upgradeReplacesBonuses = source["upgradeReplacesBonuses"].Bool();
 	ret->upgradeReplacesBonuses = source["upgradeReplacesBonuses"].Bool();

+ 1 - 1
lib/gameState/CGameState.cpp

@@ -397,7 +397,7 @@ void CGameState::initDifficulty()
 	auto setDifficulty = [this](PlayerState & state, const JsonNode & json)
 	auto setDifficulty = [this](PlayerState & state, const JsonNode & json)
 	{
 	{
 		//set starting resources
 		//set starting resources
-		state.resources = TResources(json["resources"]);
+		state.resources.resolveFromJson(json["resources"]);
 
 
 		//handicap
 		//handicap
 		const PlayerSettings &ps = scenarioOps->getIthPlayersSettings(state.color);
 		const PlayerSettings &ps = scenarioOps->getIthPlayersSettings(state.color);

+ 1 - 1
lib/mapObjectConstructors/FlaggableInstanceConstructor.cpp

@@ -40,7 +40,7 @@ void FlaggableInstanceConstructor::initTypeData(const JsonNode & config)
 		}
 		}
 	}
 	}
 
 
-	dailyIncome = ResourceSet(config["dailyIncome"]);
+	dailyIncome.resolveFromJson(config["dailyIncome"]);
 }
 }
 
 
 void FlaggableInstanceConstructor::initializeObject(FlaggableMapObject * flaggable) const
 void FlaggableInstanceConstructor::initializeObject(FlaggableMapObject * flaggable) const

+ 1 - 4
lib/modding/ModManager.cpp

@@ -807,10 +807,7 @@ void ModDependenciesResolver::tryAddMods(TModList modsToResolve, const ModsStora
 			{
 			{
 				resolvedOnCurrentTreeLevel.insert(*it); // Not to the resolvedModIDs, so current node children will be resolved on the next iteration
 				resolvedOnCurrentTreeLevel.insert(*it); // Not to the resolvedModIDs, so current node children will be resolved on the next iteration
 				assert(!vstd::contains(sortedValidMods, *it));
 				assert(!vstd::contains(sortedValidMods, *it));
-				if(storage.getMod(*it).getValue("modType").String() == "Resources") // Resources needs to load before core to make it possible to override core elements with new resources and for correct init of ResourceSet
-					sortedValidMods.insert(sortedValidMods.begin(), *it);
-				else
-					sortedValidMods.push_back(*it);
+				sortedValidMods.push_back(*it);
 				it = modsToResolve.erase(it);
 				it = modsToResolve.erase(it);
 				continue;
 				continue;
 			}
 			}

+ 3 - 1
mapeditor/mapsettings/eventsettings.cpp

@@ -53,7 +53,9 @@ TResources resourcesFromVariant(const QVariant & v)
 	JsonNode vJson;
 	JsonNode vJson;
 	for(auto r : v.toMap().keys())
 	for(auto r : v.toMap().keys())
 		vJson[r.toStdString()].Integer() = v.toMap().value(r).toInt();
 		vJson[r.toStdString()].Integer() = v.toMap().value(r).toInt();
-	return TResources(vJson);
+	ResourceSet res;
+	res.resolveFromJson(vJson);
+	return res;
 }
 }
 
 
 QVariant toVariant(std::vector<ObjectInstanceID> objects)
 QVariant toVariant(std::vector<ObjectInstanceID> objects)

+ 2 - 1
server/CGameHandler.cpp

@@ -2293,7 +2293,8 @@ bool CGameHandler::spellResearch(ObjectInstanceID tid, SpellID spellAtSlot, bool
 		return true;
 		return true;
 	}
 	}
 
 
-	auto costBase = TResources(gameInfo().getSettings().getValue(EGameSettings::TOWNS_SPELL_RESEARCH_COST).Vector()[level]);
+	ResourceSet costBase;
+	costBase.resolveFromJson(gameInfo().getSettings().getValue(EGameSettings::TOWNS_SPELL_RESEARCH_COST).Vector()[level]);
 	auto costExponent = gameInfo().getSettings().getValue(EGameSettings::TOWNS_SPELL_RESEARCH_COST_EXPONENT_PER_RESEARCH).Vector()[level].Float();
 	auto costExponent = gameInfo().getSettings().getValue(EGameSettings::TOWNS_SPELL_RESEARCH_COST_EXPONENT_PER_RESEARCH).Vector()[level].Float();
 	auto cost = costBase * std::pow(t->spellResearchAcceptedCounter + 1, costExponent);
 	auto cost = costBase * std::pow(t->spellResearchAcceptedCounter + 1, costExponent);