mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	reworked mod loading to follow standard approach
This commit is contained in:
		| @@ -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", | ||||
|   | ||||
| @@ -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", | ||||
|   | ||||
| @@ -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" : { | ||||
|   | ||||
| @@ -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); | ||||
| 	} | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|   | ||||
| @@ -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; | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user