ソースを参照

remove base json from specialty bonuses

Henning Koehler 8 年 前
コミット
038cb4bf19
4 ファイル変更40 行追加1 行削除
  1. 2 1
      lib/CHeroHandler.cpp
  2. 2 0
      lib/HeroBonus.cpp
  3. 30 0
      lib/JsonNode.cpp
  4. 6 0
      lib/JsonNode.h

+ 2 - 1
lib/CHeroHandler.cpp

@@ -766,7 +766,8 @@ void CHeroHandler::afterLoadFinalization()
 				if(!base.isEmpty())
 				{
 					specNode["base"] = base;
-					//TODO: subtract base from bonuses
+					for(JsonNode & node : specVec)
+						node = JsonUtils::difference(node, base);
 				}
 			}
 			// add json for bonuses

+ 2 - 0
lib/HeroBonus.cpp

@@ -1736,6 +1736,8 @@ std::string nameForBonus(const Bonus & bonus)
 		return CreatureID::encode(bonus.subtype) + "2" + CreatureID::encode(bonus.additionalInfo);
 	case Bonus::GENERATE_RESOURCE:
 		return GameConstants::RESOURCE_NAMES[bonus.subtype];
+	case Bonus::STACKS_SPEED:
+		return "speed";
 	default:
 		return vstd::findKey(bonusNameMap, bonus.type);
 	}

+ 30 - 0
lib/JsonNode.cpp

@@ -899,6 +899,36 @@ JsonNode JsonUtils::intersect(const JsonNode & a, const JsonNode & b, bool prune
 	return nullNode;
 }
 
+JsonNode JsonUtils::difference(const JsonNode & node, const JsonNode & base)
+{
+	if(node.getType() == JsonNode::DATA_STRUCT && base.getType() == JsonNode::DATA_STRUCT)
+	{
+		// subtract individual properties
+		JsonNode result(JsonNode::DATA_STRUCT);
+		for(auto property : node.Struct())
+		{
+			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;
+			}
+			else
+			{
+				result[property.first] = property.second;
+			}
+		}
+		return result;
+	}
+	else
+	{
+		if(node == base)
+			return nullNode;
+	}
+	return node;
+}
+
 JsonNode JsonUtils::assembleFromFiles(std::vector<std::string> files)
 {
 	bool isValid;

+ 6 - 0
lib/JsonNode.h

@@ -199,6 +199,12 @@ namespace JsonUtils
 	DLL_LINKAGE JsonNode intersect(const JsonNode & a, const JsonNode & b, bool pruneEmpty = true);
 	DLL_LINKAGE JsonNode intersect(const std::vector<JsonNode> & nodes, bool pruneEmpty = true);
 
+	/**
+	 * @brief construct node representing the difference "node - base"
+	 * merging difference with base gives node
+	 */
+	DLL_LINKAGE JsonNode difference(const JsonNode & node, const JsonNode & base);
+
 	/**
 	 * @brief generate one Json structure from multiple files
 	 * @param files - list of filenames with parts of json structure