1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-06 09:09:40 +02:00

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.
This commit is contained in:
Ivan Savenko
2025-05-21 19:23:35 +03:00
parent b806775f3a
commit 62316a6420
6 changed files with 521 additions and 471 deletions

File diff suppressed because it is too large Load Diff

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",

View File

@@ -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":

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"];

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;

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;
}