diff --git a/lib/CHeroHandler.cpp b/lib/CHeroHandler.cpp index 7003ea582..24d1b1a7c 100644 --- a/lib/CHeroHandler.cpp +++ b/lib/CHeroHandler.cpp @@ -840,7 +840,7 @@ void CHeroHandler::afterLoadFinalization() if(specVec.size() > 1) { JsonNode base = JsonUtils::intersect(specVec); - if(!base.isEmpty()) + if(base.containsBaseData()) { specNode["base"] = base; for(JsonNode & node : specVec) diff --git a/lib/JsonNode.cpp b/lib/JsonNode.cpp index 503e052bc..246ed7332 100644 --- a/lib/JsonNode.cpp +++ b/lib/JsonNode.cpp @@ -214,21 +214,22 @@ bool JsonNode::isNumber() const return type == JsonType::DATA_INTEGER || type == JsonType::DATA_FLOAT; } -bool JsonNode::isEmpty() const +bool JsonNode::containsBaseData() const { switch(type) { case JsonType::DATA_NULL: - return true; + return false; case JsonType::DATA_STRUCT: for(auto elem : *data.Struct) { - if(!elem.second.isEmpty()) - return false; + if(elem.second.containsBaseData()) + return true; } - return true; - default: return false; + default: + //other types (including vector) cannot be extended via merge + return true; } } @@ -908,7 +909,7 @@ JsonNode JsonUtils::intersect(const JsonNode & a, const JsonNode & b, bool prune if(vstd::contains(b.Struct(), property.first)) { JsonNode propertyIntersect = JsonUtils::intersect(property.second, b.Struct().find(property.first)->second); - if(pruneEmpty && propertyIntersect.isEmpty()) + if(pruneEmpty && !propertyIntersect.containsBaseData()) continue; result[property.first] = propertyIntersect; } @@ -934,16 +935,17 @@ JsonNode JsonUtils::difference(const JsonNode & node, const JsonNode & base) { if(vstd::contains(base.Struct(), property.first)) { - JsonNode propertyDifference = JsonUtils::difference(property.second, base.Struct().find(property.first)->second); - if(propertyDifference.isEmpty()) - continue; - result[property.first] = propertyDifference; + const JsonNode propertyDifference = JsonUtils::difference(property.second, base.Struct().find(property.first)->second); + if(!propertyDifference.isNull()) + result[property.first] = propertyDifference; } else { result[property.first] = property.second; } } + if(result.Struct().empty()) + return nullNode; return result; } else diff --git a/lib/JsonNode.h b/lib/JsonNode.h index 1d7e1c76e..e53e78fdd 100644 --- a/lib/JsonNode.h +++ b/lib/JsonNode.h @@ -75,7 +75,9 @@ public: bool isNull() const; bool isNumber() const; - bool isEmpty() const; + /// true if node contains not-null data that cannot be extended via merging + /// used for generating common base node from multiple nodes (e.g. bonuses) + bool containsBaseData() const; bool isCompact() const; /// removes all data from node and sets type to null void clear();