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

vcmi: move obligatory marker to CSkillHandler

It is working, now it is possible to
define other obligatory skills than wisdom or magic schools,
but only 2 types of obligatory skills exists - like wisdom and
like magic school
This commit is contained in:
Konstantin 2023-02-27 12:42:57 +03:00
parent 4acf3778ef
commit f26fac5562
5 changed files with 61 additions and 28 deletions

View File

@ -60,6 +60,14 @@
"type": "string",
"description": "localizable skill name"
},
"obligatoryMajor":{
"type": "boolean",
"description": "This skill is major obligatory (like H3 Wisdom)"
},
"obligatoryMinor":{
"type": "boolean",
"description": "This skill is minor obligatory (like H3 Magic school)"
},
"gainChance" : {
"description" : "Chance for the skill to be offered on level-up (heroClass may override)",
"anyOf" : [

View File

@ -196,6 +196,7 @@
},
"wisdom" : {
"index" : 7,
"obligatoryMajor" : true,
"base" : {
"effects" : {
"main" : {
@ -401,6 +402,7 @@
},
"fireMagic" : {
"index" : 14,
"obligatoryMinor" : true,
"base" : {
"effects" : {
"main" : {
@ -428,6 +430,7 @@
},
"airMagic" : {
"index" : 15,
"obligatoryMinor" : true,
"base" : {
"effects" : {
"main" : {
@ -455,6 +458,7 @@
},
"waterMagic" : {
"index" : 16,
"obligatoryMinor" : true,
"base" : {
"effects" : {
"main" : {
@ -482,6 +486,7 @@
},
"earthMagic" : {
"index" : 17,
"obligatoryMinor" : true,
"base" : {
"effects" : {
"main" : {

View File

@ -33,8 +33,8 @@ CSkill::LevelInfo::~LevelInfo()
{
}
CSkill::CSkill(SecondarySkill id, std::string identifier)
: id(id), identifier(identifier)
CSkill::CSkill(SecondarySkill id, std::string identifier, bool obligatoryMajor, bool obligatoryMinor)
: id(id), identifier(identifier), obligatoryMajor(obligatoryMajor), obligatoryMinor(obligatoryMinor)
{
gainChance[0] = gainChance[1] = 0; //affects CHeroClassHandler::afterLoadFinalization()
levels.resize(NSecondarySkill::levels.size() - 1);
@ -207,8 +207,11 @@ CSkill * CSkillHandler::loadFromJson(const std::string & scope, const JsonNode &
{
assert(identifier.find(':') == std::string::npos);
assert(!scope.empty());
bool major, minor;
CSkill * skill = new CSkill(SecondarySkill((si32)index), identifier);
major = json["obligatoryMajor"].Bool();
minor = json["obligatoryMinor"].Bool();
CSkill * skill = new CSkill(SecondarySkill((si32)index), identifier, major, minor);
skill->modScope = scope;
VLC->generaltexth->registerString(scope, skill->getNameTextID(), json["name"].String());

View File

@ -51,9 +51,15 @@ private:
std::string identifier;
public:
CSkill(SecondarySkill id = SecondarySkill::DEFAULT, std::string identifier = "default");
CSkill(SecondarySkill id = SecondarySkill::DEFAULT, std::string identifier = "default", bool obligatoryMajor = false, bool obligatoryMinor = false);
~CSkill();
enum class Obligatory : ui8
{
MAJOR = 0,
MINOR = 1,
};
int32_t getIndex() const override;
int32_t getIconIndex() const override;
std::string getJsonKey() const override;
@ -70,6 +76,7 @@ public:
LevelInfo & at(int level);
std::string toString() const;
bool obligatory(Obligatory val) const { return val == Obligatory::MAJOR ? obligatoryMajor : obligatoryMinor; };
std::array<si32, 2> gainChance; // gainChance[0/1] = default gain chance on level-up for might/magic heroes
@ -82,11 +89,16 @@ public:
h & identifier;
h & gainChance;
h & levels;
h & obligatoryMajor;
h & obligatoryMinor;
}
friend class CSkillHandler;
friend DLL_LINKAGE std::ostream & operator<<(std::ostream & out, const CSkill & skill);
friend DLL_LINKAGE std::ostream & operator<<(std::ostream & out, const CSkill::LevelInfo & info);
private:
bool obligatoryMajor;
bool obligatoryMinor;
};
class DLL_LINKAGE CSkillHandler: public CHandlerBase<SecondarySkill, Skill, CSkill, SkillService>

View File

@ -1145,28 +1145,41 @@ ArtBearer::ArtBearer CGHeroInstance::bearerType() const
std::vector<SecondarySkill> CGHeroInstance::getLevelUpProposedSecondarySkills() const
{
std::vector<SecondarySkill> obligatorySkills; //hero is offered magic school or wisdom if possible
if (!skillsInfo.wisdomCounter)
{
if (canLearnSkill(SecondarySkill::WISDOM))
obligatorySkills.emplace_back(SecondarySkill::WISDOM);
}
if (!skillsInfo.magicSchoolCounter)
{
std::vector<SecondarySkill> ss =
{
SecondarySkill::FIRE_MAGIC, SecondarySkill::AIR_MAGIC, SecondarySkill::WATER_MAGIC, SecondarySkill::EARTH_MAGIC
};
auto getObligatorySkills = [](CSkill::Obligatory obl){
std::vector<SecondarySkill> obligatory = {};
for(int i = 0; i < VLC->skillh->size(); i++)
if((*VLC->skillh)[SecondarySkill(i)]->obligatory(obl))
{
obligatory.emplace_back(i);
break;
}
return obligatory;
};
auto selectObligatorySkill = [&](std::vector<SecondarySkill>& ss) -> void
{
std::shuffle(ss.begin(), ss.end(), skillsInfo.rand.getStdGenerator());
for(const auto & skill : ss)
{
if (canLearnSkill(skill)) //only schools hero doesn't know yet
if (canLearnSkill(skill)) //only skills hero doesn't know yet
{
obligatorySkills.push_back(skill);
break; //only one
}
}
};
if (!skillsInfo.wisdomCounter)
{
auto obligatory = getObligatorySkills(CSkill::Obligatory::MAJOR);
selectObligatorySkill(obligatory);
}
if (!skillsInfo.magicSchoolCounter)
{
auto obligatory = getObligatorySkills(CSkill::Obligatory::MINOR);
selectObligatorySkill(obligatory);
}
std::vector<SecondarySkill> skills;
@ -1339,20 +1352,12 @@ void CGHeroInstance::levelUp(const std::vector<SecondarySkill> & skills)
//deterministic secondary skills
skillsInfo.magicSchoolCounter = (skillsInfo.magicSchoolCounter + 1) % maxlevelsToMagicSchool();
skillsInfo.wisdomCounter = (skillsInfo.wisdomCounter + 1) % maxlevelsToWisdom();
if(vstd::contains(skills, SecondarySkill::WISDOM))
for(const auto & skill : skills)
{
skillsInfo.resetWisdomCounter();
}
SecondarySkill spellSchools[] = {
SecondarySkill::FIRE_MAGIC, SecondarySkill::AIR_MAGIC, SecondarySkill::WATER_MAGIC, SecondarySkill::EARTH_MAGIC};
for(const auto & skill : spellSchools)
{
if(vstd::contains(skills, skill))
{
if((*VLC->skillh)[skill]->obligatory(CSkill::Obligatory::MAJOR))
skillsInfo.resetWisdomCounter();
if((*VLC->skillh)[skill]->obligatory(CSkill::Obligatory::MINOR))
skillsInfo.resetMagicSchoolCounter();
break;
}
}
//update specialty and other bonuses that scale with level