瀏覽代碼

Per-instance bonuses for artifacts

It is now possible to give artifacts per-instance bonuses, if needed.

Unlike shared bonuses, per-instance bonuses stack if multiple instances
of same artifacts are equipped on hero.

This to implement resource-producing artifacts in line with H3 -
equipping multiple such artifacts on a single hero will give bonus from
each instance of such artifact.

Also, both existing bonuses and new instanceBonuses fields now use json
object instead of json lists. This allows easier modification of
individual bonuses of artifacts and potentially - custom icons /
descriptions for artifact bonuses.
Ivan Savenko 5 月之前
父節點
當前提交
62316a6420

文件差異過大導致無法顯示
+ 193 - 193
config/artifacts.json


+ 11 - 2
config/schemas/artifact.json

@@ -66,9 +66,18 @@
 			"description" : "Used together with components fild. Marks the artifact as fused. Cannot be disassembled."
 		},
 		"bonuses" : {
-			"type" : "array",
 			"description" : "Bonuses provided by this artifact using bonus system",
-			"items" : { "$ref" : "bonusInstance.json" }
+			"type" : "object",
+			"additionalProperties" : {
+				"$ref" : "bonusInstance.json"
+			}
+		},
+		"instanceBonuses" : {
+			"description" : "Bonuses provided by every instance of this artifact using bonus system",
+			"type" : "object",
+			"additionalProperties" : {
+				"$ref" : "bonusInstance.json"
+			}
 		},
 		"growing" : {
 			"type" : "object",

+ 9 - 0
docs/modders/Entities_Format/Artifact_Format.md

@@ -54,11 +54,20 @@ In order to make functional artifact you also need:
 	},
 
 	// Bonuses provided by this artifact using bonus system
+	// If hero equips multiple instances of the same artifact, their effect will not stack
 	"bonuses":
 	{
 		Bonus_1,
 		Bonus_2
 	},
+	
+	// Bonuses provided by every instance of this artifact using bonus system
+	// These bonuses will stack if hero equips multiple instances of this artifact
+	"instanceBonuses":
+	{
+		Bonus_1,
+		Bonus_2
+	},
 
 	// Optional, list of components for combinational artifacts
 	"components": 

+ 28 - 3
lib/entities/artifact/CArtHandler.cpp

@@ -181,10 +181,35 @@ std::shared_ptr<CArtifact> CArtHandler::loadFromJson(const std::string & scope,
 	loadType(art.get(), node);
 	loadComponents(art.get(), node);
 
-	for(const auto & b : node["bonuses"].Vector())
+	if (node["bonuses"].isVector())
 	{
-		auto bonus = JsonUtils::parseBonus(b);
-		art->addNewBonus(bonus);
+		for(const auto & b : node["bonuses"].Vector())
+		{
+			auto bonus = JsonUtils::parseBonus(b);
+			art->addNewBonus(bonus);
+		}
+	}
+	else
+	{
+		for(const auto & b : node["bonuses"].Struct())
+		{
+			if (b.second.isNull())
+				continue;
+			auto bonus = JsonUtils::parseBonus(b.second);
+			art->addNewBonus(bonus);
+		}
+	}
+
+	for(const auto & b : node["instanceBonuses"].Struct())
+	{
+		if (b.second.isNull())
+			continue;
+		auto bonus = JsonUtils::parseBonus(b.second);
+		bonus->source = BonusSource::ARTIFACT;
+		bonus->duration = BonusDuration::PERMANENT;
+		bonus->description.appendTextID(art->getNameTextID());
+		bonus->description.appendRawString(" %+d");
+		art->instanceBonuses.push_back(bonus);
 	}
 
 	const JsonNode & warMachine = node["warMachine"];

+ 3 - 0
lib/entities/artifact/CArtifact.h

@@ -102,6 +102,9 @@ class DLL_LINKAGE CArtifact final : public Artifact, public CBonusSystemNode,
 	std::map<ArtBearer, std::vector<ArtifactPosition>> possibleSlots;
 
 public:
+	/// Bonuses that are created for each instance of artifact
+	std::vector<std::shared_ptr<Bonus>> instanceBonuses;
+
 	EArtifactClass aClass = EArtifactClass::ART_SPECIAL;
 	bool onlyOnWaterMap;
 

+ 4 - 0
lib/mapping/CMap.cpp

@@ -855,6 +855,10 @@ CArtifactInstance * CMap::createArtifact(const ArtifactID & artID, const SpellID
 		artInst->addNewBonus(bonus);
 		artInst->addCharges(art->getDefaultStartCharges());
 	}
+
+	for (const auto & bonus : art->instanceBonuses)
+		artInst->addNewBonus(std::make_shared<Bonus>(*bonus));
+
 	return artInst;
 }
 

部分文件因文件數量過多而無法顯示