Explorar o código

reworked mod loading to follow standard approach

Henning Koehler %!s(int64=8) %!d(string=hai) anos
pai
achega
37df5c9d88
Modificáronse 6 ficheiros con 51 adicións e 154 borrados
  1. 5 0
      config/schemas/mod.json
  2. 10 2
      config/schemas/skill.json
  3. 28 0
      config/skills.json
  4. 1 0
      lib/CModHandler.cpp
  5. 7 149
      lib/CSkillHandler.cpp
  6. 0 3
      lib/CSkillHandler.h

+ 5 - 0
config/schemas/mod.json

@@ -97,6 +97,11 @@
 			"description": "List of configuration files for spells",
 			"items": { "type":"string", "format" : "textFile" }
 		},
+		"skills": {
+			"type":"array",
+			"description": "List of configuration files for skills",
+			"items": { "type":"string", "format" : "textFile" }
+		},
 		"templates":{
 			"type":"array",
 			"description": "List of configuration files for RMG templates",

+ 10 - 2
config/schemas/skill.json

@@ -11,7 +11,7 @@
 		"skillBonus" : {
 			"type" : "object",
 			"description" : "Set of bonuses provided by skill at given level",
-			"required" : ["effects"],
+			"required" : ["description", "effects"],
 			"properties" : {
 				"description" : {
 					"type" : "string",
@@ -28,9 +28,17 @@
 		
 	},
 
-	"required" : ["basic", "advanced", "expert"],
+	"required" : ["name", "basic", "advanced", "expert"],
 
 	"properties" : {
+		"index" : {
+			"type": "number",
+			"description": "numeric id of skill, required for existing skills"
+		},
+		"name" : {
+			"type": "string",
+			"description": "localizable skill name"
+		},
 		"base" : {
 			"type" : "object",
 			"description" : "will be merged with all levels",

+ 28 - 0
config/skills.json

@@ -1,5 +1,6 @@
 {
 	"pathfinding" : {
+		"index" : 0,
 		"base" : {
 			"effects" : {
 				"main" : {
@@ -26,6 +27,7 @@
 		}
 	},
 	"archery" : {
+		"index" : 1,
 		"base" : {
 			"effects" : {
 				"main" : {
@@ -52,6 +54,7 @@
 		}
 	},
 	"logistics" : {
+		"index" : 2,
 		"base" : {
 			"effects" : {
 				"main" : {
@@ -78,6 +81,7 @@
 		}
 	},
 	"scouting" : {
+		"index" : 3,
 		"base" : {
 			"effects" : {
 				"main" : {
@@ -103,6 +107,7 @@
 		}
 	},
 	"diplomacy" : {
+		"index" : 4,
 		"base" : {
 			"effects" : {
 				"main" : {
@@ -137,6 +142,7 @@
 		}
 	},
 	"navigation" : {
+		"index" : 5,
 		"base" : {
 			"effects" : {
 				"main" : {
@@ -163,6 +169,7 @@
 		}
 	},
 	"leadership" : {
+		"index" : 6,
 		"base" : {
 			"effects" : {
 				"main" : {
@@ -188,6 +195,7 @@
 		}
 	},
 	"wisdom" : {
+		"index" : 7,
 		"base" : {
 			"effects" : {
 				"main" : {
@@ -214,6 +222,7 @@
 		}
 	},
 	"mysticism" : {
+		"index" : 8,
 		"base" : {
 			"effects" : {
 				"main" : {
@@ -239,6 +248,7 @@
 		}
 	},
 	"luck" : {
+		"index" : 9,
 		"base" : {
 			"effects" : {
 				"main" : {
@@ -264,6 +274,7 @@
 		}
 	},
 	"ballistics" : {
+		"index" : 10,
 		"base" : {
 			"effects" : {
 				"main" : {
@@ -296,6 +307,7 @@
 		}
 	},
 	"eagleEye" : {
+		"index" : 11,
 		"base" : {
 			"effects" : {
 				"main" : {
@@ -330,6 +342,7 @@
 		}
 	},
 	"necromancy" : {
+		"index" : 12,
 		"base" : {
 			"effects" : {
 				"main" : {
@@ -356,6 +369,7 @@
 		}
 	},
 	"estates" : {
+		"index" : 13,
 		"base" : {
 			"effects" : {
 				"main" : {
@@ -385,6 +399,7 @@
 		}
 	},
 	"fireMagic" : {
+		"index" : 14,
 		"base" : {
 			"effects" : {
 				"main" : {
@@ -411,6 +426,7 @@
 		}
 	},
 	"airMagic" : {
+		"index" : 15,
 		"base" : {
 			"effects" : {
 				"main" : {
@@ -437,6 +453,7 @@
 		}
 	},
 	"waterMagic" : {
+		"index" : 16,
 		"base" : {
 			"effects" : {
 				"main" : {
@@ -463,6 +480,7 @@
 		}
 	},
 	"earthMagic" : {
+		"index" : 17,
 		"base" : {
 			"effects" : {
 				"main" : {
@@ -489,6 +507,7 @@
 		}
 	},
 	"scholar" : {
+		"index" : 18,
 		"base" : {
 			"effects" : {
 				"main" : {
@@ -515,6 +534,7 @@
 		}
 	},
 	"tactics" : {
+		"index" : 19,
 		"base" : {
 			"effects" : {
 				"main" : {
@@ -541,6 +561,7 @@
 		}
 	},
 	"artillery" : {
+		"index" : 20,
 		"base" : {
 			"effects" : {
 				"main" : {
@@ -581,6 +602,7 @@
 		}
 	},
 	"learning" : {
+		"index" : 21,
 		"base" : {
 			"effects" : {
 				"main" : {
@@ -607,6 +629,7 @@
 		}
 	},
 	"offence" : {
+		"index" : 22,
 		"base" : {
 			"effects" : {
 				"main" : {
@@ -633,6 +656,7 @@
 		}
 	},
 	"armorer" : {
+		"index" : 23,
 		"base" : {
 			"effects" : {
 				"main" : {
@@ -659,6 +683,7 @@
 		}
 	},
 	"intelligence" : {
+		"index" : 24,
 		"base" : {
 			"effects" : {
 				"main" : {
@@ -685,6 +710,7 @@
 		}
 	},
 	"sorcery" : {
+		"index" : 25,
 		"base" : {
 			"effects" : {
 				"main" : {
@@ -711,6 +737,7 @@
 		}
 	},
 	"resistance" : {
+		"index" : 26,
 		"base" : {
 			"effects" : {
 				"main" : {
@@ -737,6 +764,7 @@
 		}
 	},
 	"firstAid" : {
+		"index" : 27,
 		"base" : {
 			"effects" : {
 				"main" : {

+ 1 - 0
lib/CModHandler.cpp

@@ -404,6 +404,7 @@ bool CContentHandler::ContentTypeHandler::loadMod(std::string modName, bool vali
 			continue;
 		}
 		// normal new object
+		logMod->trace("no index in loadMod(%s)", name);
 		performValidate(data,name);
 		handler->loadObject(modName, name, data);
 	}

+ 7 - 149
lib/CSkillHandler.cpp

@@ -27,7 +27,7 @@
 #include "battle/CBattleInfoCallback.h"
 
 ///CSkill
-CSkill::LevelInfo::LevelInfo() : description("")
+CSkill::LevelInfo::LevelInfo()
 {
 }
 
@@ -35,7 +35,7 @@ CSkill::LevelInfo::~LevelInfo()
 {
 }
 
-CSkill::CSkill(SecondarySkill id) : id(id), name("")
+CSkill::CSkill(SecondarySkill id) : id(id)
 {
 	if(id == SecondarySkill::DEFAULT)
 		identifier = "default";
@@ -101,14 +101,6 @@ std::string CSkill::toString() const
 ///CSkillHandler
 CSkillHandler::CSkillHandler()
 {
-	for(int id = 0; id < GameConstants::SKILL_QUANTITY; id++)
-	{
-		CSkill * skill = new CSkill(SecondarySkill(id));
-		for(int level = 1; level < NSecondarySkill::levels.size(); level++)
-			for (auto bonus : defaultBonus(SecondarySkill(id), level))
-				skill->addNewBonus(bonus, level);
-		objects.push_back(skill);
-	}
 }
 
 std::vector<JsonNode> CSkillHandler::loadLegacyData(size_t dataSize)
@@ -136,18 +128,18 @@ std::vector<JsonNode> CSkillHandler::loadLegacyData(size_t dataSize)
 	std::vector<JsonNode> legacyData;
 	for(int id = 0; id < GameConstants::SKILL_QUANTITY; id++)
 	{
-		CSkill & skill = *objects[id];
 		JsonNode skillNode(JsonNode::DATA_STRUCT);
+		skillNode["name"].String() = skillNames[id];
 		for(int level = 1; level < NSecondarySkill::levels.size(); level++)
 		{
-			skill.name = skillNames[id];
 			std::string & desc = skillInfoTexts[id][level-1];
-			skill.setDescription(desc, level);
 			auto & levelNode = skillNode[NSecondarySkill::levels[level]].Struct();
 			levelNode["description"].String() = desc;
+			levelNode["effects"].Struct(); // create empty effects objects
 		}
 		legacyData.push_back(skillNode);
 	}
+	objects.resize(legacyData.size());
 	return legacyData;
 }
 
@@ -175,8 +167,6 @@ CSkill * CSkillHandler::loadFromJson(const JsonNode & json, const std::string &
 		if(NSecondarySkill::names[id].compare(identifier) == 0)
 		{
 			skill = new CSkill(SecondarySkill(id));
-			//skill name isn't stored in JSON
-			skill->name = objects[id]->name;
 			break;
 		}
 	}
@@ -187,6 +177,7 @@ CSkill * CSkillHandler::loadFromJson(const JsonNode & json, const std::string &
 		throw std::runtime_error("invalid skill");
 	}
 
+	skill->name = json["name"].String();
 	for(int level = 1; level < NSecondarySkill::levels.size(); level++)
 	{
 		const std::string & levelName = NSecondarySkill::levels[level]; // basic, advanced, expert
@@ -198,11 +189,7 @@ CSkill * CSkillHandler::loadFromJson(const JsonNode & json, const std::string &
 			bonus->sid = skill->id;
 			skill->addNewBonus(bonus, level);
 		}
-		// parse skill description - tracked separately
-		if(vstd::contains(levelNode.Struct(), "description") && !levelNode["description"].isNull())
-			skill->setDescription(levelNode["description"].String(), level);
-		else
-			skill->setDescription(skillInfo(skill->id, level), level);
+		skill->setDescription(levelNode["description"].String(), level);
 	}
 	logMod->debug("loaded secondary skill %s(%d)", identifier, (int)skill->id);
 	logMod->trace("%s", skill->toString());
@@ -210,33 +197,6 @@ CSkill * CSkillHandler::loadFromJson(const JsonNode & json, const std::string &
 	return skill;
 }
 
-void CSkillHandler::loadObject(std::string scope, std::string name, const JsonNode & data)
-{
-	auto type_name = getTypeName();
-	auto object = loadFromJson(data, normalizeIdentifier(scope, "core", name));
-
-	if(object->id == SecondarySkill::DEFAULT) // new skill - no index identified
-	{
-		object->id = SecondarySkill(objects.size());
-		objects.push_back(object);
-	}
-	else
-		objects[object->id] = object;
-
-	registerObject(scope, type_name, name, object->id);
-}
-
-void CSkillHandler::loadObject(std::string scope, std::string name, const JsonNode & data, size_t index)
-{
-	auto type_name = getTypeName();
-	auto object = loadFromJson(data, normalizeIdentifier(scope, "core", name));
-
-	assert(object->id == index);
-	objects[index] = object;
-
-	registerObject(scope, type_name, name, object->id);
-}
-
 void CSkillHandler::afterLoadFinalization()
 {
 }
@@ -264,105 +224,3 @@ std::vector<bool> CSkillHandler::getDefaultAllowed() const
 	std::vector<bool> allowedSkills(objects.size(), true);
 	return allowedSkills;
 }
-
-// HMM3 default bonus provided by secondary skill
-std::vector<std::shared_ptr<Bonus>> CSkillHandler::defaultBonus(SecondarySkill skill, int level) const
-{
-	std::vector<std::shared_ptr<Bonus>> result;
-
-	// add bonus based on current values - useful for adding multiple bonuses easily
-	auto addBonus = [=, &result](int bonusVal, Bonus::BonusType bonusType = Bonus::SECONDARY_SKILL_PREMY, int subtype = 0)
-	{
-		if(bonusType == Bonus::SECONDARY_SKILL_PREMY || bonusType == Bonus::SECONDARY_SKILL_VAL2)
-			subtype = skill;
-		result.push_back(std::make_shared<Bonus>(Bonus::PERMANENT, bonusType, Bonus::SECONDARY_SKILL, bonusVal, skill, subtype, Bonus::BASE_NUMBER));
-	};
-
-	switch(skill)
-	{
-	case SecondarySkill::PATHFINDING:
-		addBonus(25 * level);
-		break;
-	case SecondarySkill::ARCHERY:
-		addBonus(5 + 5 * level * level);
-		break;
-	case SecondarySkill::LOGISTICS:
-		addBonus(10 * level);
-		break;
-	case SecondarySkill::SCOUTING:
-		addBonus(level, Bonus::SIGHT_RADIOUS);
-		break;
-	case SecondarySkill::DIPLOMACY:
-		addBonus(level);
-		addBonus(20 * level, Bonus::SURRENDER_DISCOUNT);
-		break;
-	case SecondarySkill::NAVIGATION:
-		addBonus(50 * level);
-		break;
-	case SecondarySkill::LEADERSHIP:
-		addBonus(level, Bonus::MORALE);
-		break;
-	case SecondarySkill::LUCK:
-		addBonus(level, Bonus::LUCK);
-		break;
-	case SecondarySkill::BALLISTICS:
-		addBonus(100, Bonus::MANUAL_CONTROL, CreatureID::CATAPULT);
-		addBonus(level);
-		break;
-	case SecondarySkill::EAGLE_EYE:
-		addBonus(30 + 10 * level);
-		addBonus(1 + level, Bonus::SECONDARY_SKILL_VAL2);
-		break;
-	case SecondarySkill::NECROMANCY:
-		addBonus(10 * level);
-		break;
-	case SecondarySkill::ESTATES:
-		addBonus(125 << (level-1));
-		break;
-	case SecondarySkill::FIRE_MAGIC:
-	case SecondarySkill::AIR_MAGIC:
-	case SecondarySkill::WATER_MAGIC:
-	case SecondarySkill::EARTH_MAGIC:
-		addBonus(level);
-		break;
-	case SecondarySkill::SCHOLAR:
-		addBonus(1 + level);
-		break;
-	case SecondarySkill::TACTICS:
-		addBonus(1 + 2 * level);
-		break;
-	case SecondarySkill::ARTILLERY:
-		addBonus(100, Bonus::MANUAL_CONTROL, CreatureID::BALLISTA);
-		addBonus(25 + 25 * level);
-		if(level > 1) // extra attack
-			addBonus(1, Bonus::SECONDARY_SKILL_VAL2);
-		 break;
-	case SecondarySkill::LEARNING:
-		addBonus(5 * level);
-		break;
-	case SecondarySkill::OFFENCE:
-		addBonus(10 * level);
-		break;
-	case SecondarySkill::ARMORER:
-		addBonus(5 * level);
-		break;
-	case SecondarySkill::INTELLIGENCE:
-		addBonus(25 << (level-1));
-		break;
-	case SecondarySkill::SORCERY:
-		addBonus(5 * level);
-		break;
-	case SecondarySkill::RESISTANCE:
-		addBonus(5 << (level-1));
-		break;
-	case SecondarySkill::FIRST_AID:
-		addBonus(100, Bonus::MANUAL_CONTROL, CreatureID::FIRST_AID_TENT);
-		addBonus(25 + 25 * level);
-		break;
-	default:
-		addBonus(level);
-		break;
-	}
-
-	return result;
-}

+ 0 - 3
lib/CSkillHandler.h

@@ -73,8 +73,6 @@ public:
 
 	std::vector<bool> getDefaultAllowed() const override;
 	const std::string getTypeName() const override;
-	void loadObject(std::string scope, std::string name, const JsonNode & data) override;
-	void loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) override;
 
 	const std::string & skillInfo(int skill, int level) const;
 	const std::string & skillName(int skill) const;
@@ -86,5 +84,4 @@ public:
 
 protected:
 	CSkill * loadFromJson(const JsonNode & json, const std::string & identifier) override;
-	std::vector<std::shared_ptr<Bonus>> defaultBonus(SecondarySkill skill, int level) const;
 };