Merge pull request #5735 from IvanSavenko/artifact_bonuses

Per-instance bonuses for artifacts
This commit is contained in:
Ivan Savenko
2025-05-23 16:03:59 +03:00
committed by GitHub
6 changed files with 521 additions and 471 deletions
+466 -466
View File
File diff suppressed because it is too large Load Diff
+11 -2
View File
@@ -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",
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}