1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

reworked mod loading to follow standard approach

This commit is contained in:
Henning Koehler 2017-09-03 23:49:36 +12:00
parent cd35ece10c
commit 37df5c9d88
6 changed files with 51 additions and 154 deletions

View File

@ -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",

View File

@ -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",

View File

@ -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" : {

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
};