Browse Source

converted special.json; fixed bugs in specialty json construction

Henning Koehler 8 năm trước cách đây
mục cha
commit
2b8f111a81
4 tập tin đã thay đổi với 282 bổ sung92 xóa
  1. 240 89
      config/heroes/special.json
  2. 26 0
      lib/HeroBonus.cpp
  3. 2 0
      lib/HeroBonus.h
  4. 14 3
      lib/JsonNode.cpp

+ 240 - 89
config/heroes/special.json

@@ -10,10 +10,14 @@
 		[
 		[
 			{ "skill" : "leadership", "level": "advanced" }
 			{ "skill" : "leadership", "level": "advanced" }
 		],
 		],
-		"specialties":
-		[
-			{ "type":12, "val": 2, "subtype": 0, "info": 0 }
-		]
+		"specialty" : {
+			"bonuses" : {
+				"speed" : {
+					"type" : "STACKS_SPEED",
+					"val" : 2
+				}
+			}
+		}
 	},
 	},
 	"adrienne":
 	"adrienne":
 	{
 	{
@@ -25,11 +29,9 @@
 		"skills":
 		"skills":
 		[
 		[
 			{ "skill" : "wisdom", "level": "basic" },
 			{ "skill" : "wisdom", "level": "basic" },
-			{ "skill" : "fireMagic", "level": "expert" } ],
-		"specialties":
-		[
-			{ "type":11, "val": 14, "subtype": 0, "info": 3 }
-		]
+			{ "skill" : "fireMagic", "level": "expert" }
+		],
+		"specialty" : { "bonuses" : {  } }
 	},
 	},
 	"catherine":
 	"catherine":
 	{
 	{
@@ -42,10 +44,38 @@
 			{ "skill" : "leadership", "level": "basic" },
 			{ "skill" : "leadership", "level": "basic" },
 			{ "skill" : "offence", "level": "basic" }
 			{ "skill" : "offence", "level": "basic" }
 		],
 		],
-		"specialties":
-		[
-			{ "type":1, "val": 0, "subtype": 0, "info": 4 }
-		]
+		"specialty" : {
+			"base" : {
+				"limiters" : [
+					{
+						"parameters" : [ "griffin", true ],
+						"type" : "CREATURE_TYPE_LIMITER"
+					}
+				]
+			},
+			"bonuses" : {
+				"attack" : {
+					"subtype" : "primSkill.attack",
+					"type" : "PRIMARY_SKILL",
+					"updater" : {
+						"parameters" : [ 8, 3 ],
+						"type" : "GROWS_WITH_LEVEL"
+					}
+				},
+				"defence" : {
+					"subtype" : "primSkill.defence",
+					"type" : "PRIMARY_SKILL",
+					"updater" : {
+						"parameters" : [ 8, 3 ],
+						"type" : "GROWS_WITH_LEVEL"
+					}
+				},
+				"speed" : {
+					"type" : "STACKS_SPEED",
+					"val" : 1
+				}
+			}
+		}
 	},
 	},
 	"dracon":
 	"dracon":
 	{
 	{
@@ -58,11 +88,18 @@
 		[
 		[
 			{ "skill" : "wisdom", "level": "advanced" }
 			{ "skill" : "wisdom", "level": "advanced" }
 		],
 		],
-		"specialties":
-		[
-			{ "type":9, "val": 0, "subtype": 8, "info": 136 },
-			{ "type":9, "val": 0, "subtype": 34, "info": 136 }
-		]
+		"specialty" : {
+			"base" : {
+				"addInfo" : "creature.enchanter",
+				"type" : "SPECIAL_UPGRADE"
+			},
+			"bonuses" : {
+				"archMage2enchanter" : { "subtype" : "creature.archMage" },
+				"mage2enchanter" : { "subtype" : "creature.mage" },
+				"monk2enchanter" : { "subtype" : "creature.monk" },
+				"zealot2enchanter" : { "subtype" : "creature.zealot" }
+			}
+		}
 	},
 	},
 	"gelu":
 	"gelu":
 	{
 	{
@@ -75,11 +112,18 @@
 			{ "skill" : "archery", "level": "basic" },
 			{ "skill" : "archery", "level": "basic" },
 			{ "skill" : "leadership", "level": "basic" }
 			{ "skill" : "leadership", "level": "basic" }
 		],
 		],
-		"specialties":
-		[
-			{ "type":9, "val": 0, "subtype": 2, "info": 137 },
-			{ "type":9, "val": 0, "subtype": 18, "info": 137 }
-		]
+		"specialty" : {
+			"base" : {
+				"addInfo" : "creature.sharpshooter",
+				"type" : "SPECIAL_UPGRADE"
+			},
+			"bonuses" : {
+				"archer2sharpshooter" : { "subtype" : "creature.archer" },
+				"grandElf2sharpshooter" : { "subtype" : "creature.grandElf" },
+				"marksman2sharpshooter" : { "subtype" : "creature.marksman" },
+				"woodElf2sharpshooter" : { "subtype" : "creature.woodElf" }
+			}
+		}
 	},
 	},
 	"kilgor":
 	"kilgor":
 	{
 	{
@@ -91,12 +135,33 @@
 		[
 		[
 			{ "skill" : "offence", "level": "advanced" }
 			{ "skill" : "offence", "level": "advanced" }
 		],
 		],
-		"specialties":
-		[
-			{ "type":4, "val": 5,  "subtype": 1, "info": 96 },
-			{ "type":4, "val": 5,  "subtype": 2, "info": 96 },
-			{ "type":4, "val": 10, "subtype": 3, "info": 96 }
-		]
+		"specialty" : {
+			"base" : {
+				"limiters" : [
+					{
+						"parameters" : [ "behemoth", true ],
+						"type" : "CREATURE_TYPE_LIMITER"
+					}
+				]
+			},
+			"bonuses" : {
+				"damage" : {
+					"subtype" : 0,
+					"type" : "CREATURE_DAMAGE",
+					"val" : 10
+				},
+				"attack" : {
+					"subtype" : "primSkill.attack",
+					"type" : "PRIMARY_SKILL",
+					"val" : 5
+				},
+				"defence" : {
+					"subtype" : "primSkill.defence",
+					"type" : "PRIMARY_SKILL",
+					"val" : 5
+				}
+			}
+		}
 	},
 	},
 	"undeadHaart": // undead version of Lord Haart
 	"undeadHaart": // undead version of Lord Haart
 	{
 	{
@@ -109,12 +174,33 @@
 		[
 		[
 			{ "skill" : "necromancy", "level": "advanced" }
 			{ "skill" : "necromancy", "level": "advanced" }
 		],
 		],
-		"specialties":
-		[
-			{ "type":4, "val": 5,  "subtype": 1, "info": 66 },
-			{ "type":4, "val": 5,  "subtype": 2, "info": 66 },
-			{ "type":4, "val": 10, "subtype": 3, "info": 66 }
-		]
+		"specialty" : {
+			"base" : {
+				"limiters" : [
+					{
+						"parameters" : [ "blackKnight", true ],
+						"type" : "CREATURE_TYPE_LIMITER"
+					}
+				]
+			},
+			"bonuses" : {
+				"damage" : {
+					"subtype" : 0,
+					"type" : "CREATURE_DAMAGE",
+					"val" : 10
+				},
+				"attack" : {
+					"subtype" : "primSkill.attack",
+					"type" : "PRIMARY_SKILL",
+					"val" : 5
+				},
+				"defence" : {
+					"subtype" : "primSkill.defence",
+					"type" : "PRIMARY_SKILL",
+					"val" : 5
+				}
+			}
+		}
 	},
 	},
 	"mutare":
 	"mutare":
 	{
 	{
@@ -128,11 +214,22 @@
 			{ "skill" : "estates", "level": "basic" },
 			{ "skill" : "estates", "level": "basic" },
 			{ "skill" : "tactics", "level": "basic" }
 			{ "skill" : "tactics", "level": "basic" }
 		],
 		],
-		"specialties":
-		[
-			{ "type":13, "val": 5, "subtype": 1, "info": 0 },
-			{ "type":13, "val": 5, "subtype": 2, "info": 0 }
-		]
+		"specialty" : {
+			"base" : {
+				"limiters" : [
+					{
+						"parameters" : [ "DRAGON_NATURE" ],
+						"type" : "HAS_ANOTHER_BONUS_LIMITER"
+					}
+				],
+				"type" : "PRIMARY_SKILL",
+				"val" : 5
+			},
+			"bonuses" : {
+				"attack" : { "subtype" : "primSkill.attack" },
+				"defence" : { "subtype" : "primSkill.defence" }
+			}
+		}
 	},
 	},
 	"roland":
 	"roland":
 	{
 	{
@@ -145,10 +242,38 @@
 			{ "skill" : "leadership", "level": "basic" },
 			{ "skill" : "leadership", "level": "basic" },
 			{ "skill" : "armorer", "level": "basic" }
 			{ "skill" : "armorer", "level": "basic" }
 		],
 		],
-		"specialties":
-		[
-			{ "type":1, "val": 0, "subtype": 0, "info": 4 }
-		]
+		"specialty" : {
+			"base" : {
+				"limiters" : [
+					{
+						"parameters" : [ "griffin", true ],
+						"type" : "CREATURE_TYPE_LIMITER"
+					}
+				]
+			},
+			"bonuses" : {
+				"attack" : {
+					"subtype" : "primSkill.attack",
+					"type" : "PRIMARY_SKILL",
+					"updater" : {
+						"parameters" : [ 8, 3 ],
+						"type" : "GROWS_WITH_LEVEL"
+					}
+				},
+				"defence" : {
+					"subtype" : "primSkill.defence",
+					"type" : "PRIMARY_SKILL",
+					"updater" : {
+						"parameters" : [ 8, 3 ],
+						"type" : "GROWS_WITH_LEVEL"
+					}
+				},
+				"speed" : {
+					"type" : "STACKS_SPEED",
+					"val" : 1
+				}
+			}
+		}
 	},
 	},
 	"mutareDrake":
 	"mutareDrake":
 	{
 	{
@@ -162,11 +287,23 @@
 			{ "skill" : "estates", "level": "basic" },
 			{ "skill" : "estates", "level": "basic" },
 			{ "skill" : "tactics", "level": "basic" }
 			{ "skill" : "tactics", "level": "basic" }
 		],
 		],
-		"specialties":
-		[
-			{ "type":13, "val": 1, "subtype": 1, "info": 5 },
-			{ "type":13, "val": 1, "subtype": 1, "info": 5 }
-		],
+		"specialty" : {
+			"base" : {
+				"limiters" : [
+					{
+						"parameters" : [ "DRAGON_NATURE" ],
+						"type" : "HAS_ANOTHER_BONUS_LIMITER"
+					}
+				],
+				"subtype" : "primSkill.attack",
+				"type" : "PRIMARY_SKILL",
+				"val" : 1
+			},
+			"bonuses" : {
+				"attack" : {  },
+				"attack2" : {  }
+			}
+		},
 		"army" :
 		"army" :
 		[
 		[
 			{
 			{
@@ -194,44 +331,38 @@
 			{ "skill" : "tactics", "level": "basic" },
 			{ "skill" : "tactics", "level": "basic" },
 			{ "skill" : "offence", "level": "basic" }
 			{ "skill" : "offence", "level": "basic" }
 		],
 		],
-		"specialty" :
-		[
-			{
-				"growsWithLevel" : true,
-				"bonuses" : [
+		"specialty" : {
+			"base" : {
+				"limiters" : [
 					{
 					{
-						"limiters" : [
-							{
-								"parameters" : [ "ogre", true ],
-								"type" : "CREATURE_TYPE_LIMITER"
-							}
-						],
-						"subtype" : "primSkill.attack",
-						"type" : "PRIMARY_SKILL",
-					},
-					{
-						"limiters" : [
-							{
-								"parameters" : [ "ogre", true ],
-								"type" : "CREATURE_TYPE_LIMITER"
-							}
-						],
-						"subtype" : "primSkill.defence",
-						"type" : "PRIMARY_SKILL",
-					},
-					{
-						"limiters" : [
-							{
-								"parameters" : [ "ogre", true ],
-								"type" : "CREATURE_TYPE_LIMITER"
-							}
-						],
-						"type" : "STACKS_SPEED",
-						"val" : 1
+						"parameters" : [ "ogre", true ],
+						"type" : "CREATURE_TYPE_LIMITER"
 					}
 					}
 				]
 				]
+			},
+			"bonuses" : {
+				"attack" : {
+					"subtype" : "primSkill.attack",
+					"type" : "PRIMARY_SKILL",
+					"updater" : {
+						"parameters" : [ 13, 4 ],
+						"type" : "GROWS_WITH_LEVEL"
+					}
+				},
+				"defence" : {
+					"subtype" : "primSkill.defence",
+					"type" : "PRIMARY_SKILL",
+					"updater" : {
+						"parameters" : [ 7, 4 ],
+						"type" : "GROWS_WITH_LEVEL"
+					}
+				},
+				"speed" : {
+					"type" : "STACKS_SPEED",
+					"val" : 1
+				}
 			}
 			}
-		],
+		},
 		"army" :
 		"army" :
 		[
 		[
 			{
 			{
@@ -259,12 +390,32 @@
 			{ "skill" : "leadership", "level": "basic" },
 			{ "skill" : "leadership", "level": "basic" },
 			{ "skill" : "tactics", "level": "basic" }
 			{ "skill" : "tactics", "level": "basic" }
 		],
 		],
-		"specialties":
-		[
-			{ "type":4, "val": 4, "subtype": 1, "info": 54 },
-			{ "type":4, "val": 2, "subtype": 2, "info": 54 },
-			{ "type":4, "val": 1, "subtype": 5, "info": 54 }
-		],
+		"specialty" : {
+			"base" : {
+				"limiters" : [
+					{
+						"parameters" : [ "devil", true ],
+						"type" : "CREATURE_TYPE_LIMITER"
+					}
+				]
+			},
+			"bonuses" : {
+				"attack" : {
+					"subtype" : "primSkill.attack",
+					"type" : "PRIMARY_SKILL",
+					"val" : 4
+				},
+				"defence" : {
+					"subtype" : "primSkill.defence",
+					"type" : "PRIMARY_SKILL",
+					"val" : 2
+				},
+				"speed" : {
+					"type" : "STACKS_SPEED",
+					"val" : 1
+				}
+			}
+		},
 		"army" :
 		"army" :
 		[
 		[
 			{
 			{

+ 26 - 0
lib/HeroBonus.cpp

@@ -1520,6 +1520,32 @@ int HasAnotherBonusLimiter::limit(const BonusLimitationContext &context) const
 	return NOT_SURE;
 	return NOT_SURE;
 }
 }
 
 
+std::string HasAnotherBonusLimiter::toString() const
+{
+	char buf[100];
+
+	std::string typeName = vstd::findKey(bonusNameMap, type);
+	if(isSubtypeRelevant)
+		sprintf(buf, "HasAnotherBonusLimiter(type=%s, subtype=%d)",	typeName.c_str(), subtype);
+	else
+		sprintf(buf, "HasAnotherBonusLimiter(type=%s)",	typeName.c_str());
+
+	return std::string(buf);
+}
+
+JsonNode HasAnotherBonusLimiter::toJsonNode() const
+{
+	JsonNode root(JsonNode::JsonType::DATA_STRUCT);
+	std::string typeName = vstd::findKey(bonusNameMap, type);
+
+	root["type"].String() = "HAS_ANOTHER_BONUS_LIMITER";
+	root["parameters"].Vector().push_back(JsonUtils::stringNode(typeName));
+	if(isSubtypeRelevant)
+		root["parameters"].Vector().push_back(JsonUtils::intNode(subtype));
+
+	return root;
+}
+
 IPropagator::~IPropagator()
 IPropagator::~IPropagator()
 {
 {
 
 

+ 2 - 0
lib/HeroBonus.h

@@ -881,6 +881,8 @@ public:
 	HasAnotherBonusLimiter(Bonus::BonusType bonus, TBonusSubtype _subtype);
 	HasAnotherBonusLimiter(Bonus::BonusType bonus, TBonusSubtype _subtype);
 
 
 	int limit(const BonusLimitationContext &context) const override;
 	int limit(const BonusLimitationContext &context) const override;
+	virtual std::string toString() const override;
+	virtual JsonNode toJsonNode() const override;
 
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 	{

+ 14 - 3
lib/JsonNode.cpp

@@ -927,6 +927,19 @@ JsonNode JsonUtils::intersect(const JsonNode & a, const JsonNode & b, bool prune
 
 
 JsonNode JsonUtils::difference(const JsonNode & node, const JsonNode & base)
 JsonNode JsonUtils::difference(const JsonNode & node, const JsonNode & base)
 {
 {
+	auto addsInfo = [](JsonNode diff) -> bool
+	{
+		switch(diff.getType())
+		{
+		case JsonNode::JsonType::DATA_NULL:
+			return false;
+		case JsonNode::JsonType::DATA_STRUCT:
+			return diff.Struct().size() > 0;
+		default:
+			return true;
+		}
+	};
+
 	if(node.getType() == JsonNode::JsonType::DATA_STRUCT && base.getType() == JsonNode::JsonType::DATA_STRUCT)
 	if(node.getType() == JsonNode::JsonType::DATA_STRUCT && base.getType() == JsonNode::JsonType::DATA_STRUCT)
 	{
 	{
 		// subtract individual properties
 		// subtract individual properties
@@ -936,7 +949,7 @@ JsonNode JsonUtils::difference(const JsonNode & node, const JsonNode & base)
 			if(vstd::contains(base.Struct(), property.first))
 			if(vstd::contains(base.Struct(), property.first))
 			{
 			{
 				const JsonNode propertyDifference = JsonUtils::difference(property.second, base.Struct().find(property.first)->second);
 				const JsonNode propertyDifference = JsonUtils::difference(property.second, base.Struct().find(property.first)->second);
-				if(!propertyDifference.isNull())
+				if(addsInfo(propertyDifference))
 					result[property.first] = propertyDifference;
 					result[property.first] = propertyDifference;
 			}
 			}
 			else
 			else
@@ -944,8 +957,6 @@ JsonNode JsonUtils::difference(const JsonNode & node, const JsonNode & base)
 				result[property.first] = property.second;
 				result[property.first] = property.second;
 			}
 			}
 		}
 		}
-		if(result.Struct().empty())
-			return nullNode;
 		return result;
 		return result;
 	}
 	}
 	else
 	else