mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-24 08:32:34 +02:00
vcmi: morale and luck now also IFactionMember
Not all bonus bearers have morale and luck, only faction members
This commit is contained in:
parent
e37f798a68
commit
a2d4c72016
@ -372,7 +372,7 @@ CTownTooltip::CTownTooltip(Point pos, const CGTownInstance * town)
|
|||||||
init(InfoAboutTown(town, true));
|
init(InfoAboutTown(town, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MoraleLuckBox::set(const IBonusBearer * node)
|
void MoraleLuckBox::set(const IFactionMember * node)
|
||||||
{
|
{
|
||||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
|
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
|
||||||
|
|
||||||
@ -393,21 +393,21 @@ void MoraleLuckBox::set(const IBonusBearer * node)
|
|||||||
text = CGI->generaltexth->arraytxt[textId[morale]];
|
text = CGI->generaltexth->arraytxt[textId[morale]];
|
||||||
boost::algorithm::replace_first(text,"%s",CGI->generaltexth->arraytxt[neutralDescr[morale]-mrlt]);
|
boost::algorithm::replace_first(text,"%s",CGI->generaltexth->arraytxt[neutralDescr[morale]-mrlt]);
|
||||||
|
|
||||||
if (morale && node && (node->hasBonusOfType(Bonus::UNDEAD)
|
if (morale && node && (node->getBonusBearer()->hasBonusOfType(Bonus::UNDEAD)
|
||||||
|| node->hasBonusOfType(Bonus::NON_LIVING)))
|
|| node->getBonusBearer()->hasBonusOfType(Bonus::NON_LIVING)))
|
||||||
{
|
{
|
||||||
text += CGI->generaltexth->arraytxt[113]; //unaffected by morale
|
text += CGI->generaltexth->arraytxt[113]; //unaffected by morale
|
||||||
bonusValue = 0;
|
bonusValue = 0;
|
||||||
}
|
}
|
||||||
else if(morale && node && node->hasBonusOfType(Bonus::NO_MORALE))
|
else if(morale && node && node->getBonusBearer()->hasBonusOfType(Bonus::NO_MORALE))
|
||||||
{
|
{
|
||||||
auto noMorale = node->getBonus(Selector::type()(Bonus::NO_MORALE));
|
auto noMorale = node->getBonusBearer()->getBonus(Selector::type()(Bonus::NO_MORALE));
|
||||||
text += "\n" + noMorale->Description();
|
text += "\n" + noMorale->Description();
|
||||||
bonusValue = 0;
|
bonusValue = 0;
|
||||||
}
|
}
|
||||||
else if (!morale && node && node->hasBonusOfType(Bonus::NO_LUCK))
|
else if (!morale && node && node->getBonusBearer()->hasBonusOfType(Bonus::NO_LUCK))
|
||||||
{
|
{
|
||||||
auto noLuck = node->getBonus(Selector::type()(Bonus::NO_LUCK));
|
auto noLuck = node->getBonusBearer()->getBonus(Selector::type()(Bonus::NO_LUCK));
|
||||||
text += "\n" + noLuck->Description();
|
text += "\n" + noLuck->Description();
|
||||||
bonusValue = 0;
|
bonusValue = 0;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ VCMI_LIB_NAMESPACE_BEGIN
|
|||||||
class CGGarrison;
|
class CGGarrison;
|
||||||
struct InfoAboutArmy;
|
struct InfoAboutArmy;
|
||||||
class CArmedInstance;
|
class CArmedInstance;
|
||||||
class IBonusBearer;
|
class IFactionMember;
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_END
|
VCMI_LIB_NAMESPACE_END
|
||||||
|
|
||||||
@ -170,7 +170,7 @@ public:
|
|||||||
bool morale; //true if morale, false if luck
|
bool morale; //true if morale, false if luck
|
||||||
bool small;
|
bool small;
|
||||||
|
|
||||||
void set(const IBonusBearer *node);
|
void set(const IFactionMember *node);
|
||||||
|
|
||||||
MoraleLuckBox(bool Morale, const Rect &r, bool Small=false);
|
MoraleLuckBox(bool Morale, const Rect &r, bool Small=false);
|
||||||
};
|
};
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
VCMI_LIB_NAMESPACE_BEGIN
|
VCMI_LIB_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
class BonusList;
|
||||||
|
|
||||||
namespace PrimarySkill
|
namespace PrimarySkill
|
||||||
{
|
{
|
||||||
enum PrimarySkill : int8_t;
|
enum PrimarySkill : int8_t;
|
||||||
@ -50,6 +52,18 @@ public:
|
|||||||
Returns primskill of creature or hero.
|
Returns primskill of creature or hero.
|
||||||
*/
|
*/
|
||||||
int getPrimSkillLevel(PrimarySkill::PrimarySkill id) const;
|
int getPrimSkillLevel(PrimarySkill::PrimarySkill id) const;
|
||||||
|
/**
|
||||||
|
Returns morale or luck of creature or hero.
|
||||||
|
*/
|
||||||
|
int MoraleVal() const; //range [-3, +3]
|
||||||
|
int LuckVal() const; //range [-3, +3]
|
||||||
|
/**
|
||||||
|
Returns total value of all morale bonuses and sets bonusList as a pointer to the list of selected bonuses.
|
||||||
|
@param bonusList is the out param it's list of all selected bonuses
|
||||||
|
@return total value of all morale in the range [-3, +3] and 0 otherwise
|
||||||
|
*/
|
||||||
|
int MoraleValAndBonusList(std::shared_ptr<const BonusList> & bonusList) const;
|
||||||
|
int LuckValAndBonusList(std::shared_ptr<const BonusList> & bonusList) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_END
|
VCMI_LIB_NAMESPACE_END
|
@ -88,6 +88,55 @@ int IFactionMember::getPrimSkillLevel(PrimarySkill::PrimarySkill id) const
|
|||||||
return std::max(ret, minSkillValue); //otherwise, some artifacts may cause negative skill value effect, sp=0 works in old saves
|
return std::max(ret, minSkillValue); //otherwise, some artifacts may cause negative skill value effect, sp=0 works in old saves
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int IFactionMember::MoraleValAndBonusList(TConstBonusListPtr & bonusList) const
|
||||||
|
{
|
||||||
|
static const auto unaffectedByMoraleSelector = Selector::type()(Bonus::NON_LIVING).Or(Selector::type()(Bonus::UNDEAD))
|
||||||
|
.Or(Selector::type()(Bonus::SIEGE_WEAPON)).Or(Selector::type()(Bonus::NO_MORALE));
|
||||||
|
|
||||||
|
static const std::string cachingStrUn = "IFactionMember::unaffectedByMoraleSelector";
|
||||||
|
auto unaffected = getBonusBearer()->hasBonus(unaffectedByMoraleSelector, cachingStrUn);
|
||||||
|
if(unaffected)
|
||||||
|
{
|
||||||
|
if(bonusList && !bonusList->empty())
|
||||||
|
bonusList = std::make_shared<const BonusList>();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const auto moraleSelector = Selector::type()(Bonus::MORALE);
|
||||||
|
static const std::string cachingStrMor = "type_MORALE";
|
||||||
|
bonusList = getBonusBearer()->getBonuses(moraleSelector, cachingStrMor);
|
||||||
|
|
||||||
|
return std::clamp(bonusList->totalValue(), -3, +3);
|
||||||
|
}
|
||||||
|
|
||||||
|
int IFactionMember::LuckValAndBonusList(TConstBonusListPtr & bonusList) const
|
||||||
|
{
|
||||||
|
if(getBonusBearer()->hasBonusOfType(Bonus::NO_LUCK))
|
||||||
|
{
|
||||||
|
if(bonusList && !bonusList->empty())
|
||||||
|
bonusList = std::make_shared<const BonusList>();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const auto luckSelector = Selector::type()(Bonus::LUCK);
|
||||||
|
static const std::string cachingStrLuck = "type_LUCK";
|
||||||
|
bonusList = getBonusBearer()->getBonuses(luckSelector, cachingStrLuck);
|
||||||
|
|
||||||
|
return std::clamp(bonusList->totalValue(), -3, +3);
|
||||||
|
}
|
||||||
|
|
||||||
|
int IFactionMember::MoraleVal() const
|
||||||
|
{
|
||||||
|
TConstBonusListPtr tmp = nullptr;
|
||||||
|
return MoraleValAndBonusList(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
int IFactionMember::LuckVal() const
|
||||||
|
{
|
||||||
|
TConstBonusListPtr tmp = nullptr;
|
||||||
|
return LuckValAndBonusList(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
ui32 ICreature::MaxHealth() const
|
ui32 ICreature::MaxHealth() const
|
||||||
{
|
{
|
||||||
const std::string cachingStr = "type_STACK_HEALTH";
|
const std::string cachingStr = "type_STACK_HEALTH";
|
||||||
@ -114,7 +163,7 @@ ui32 ICreature::Speed(int turn, bool useBind) const
|
|||||||
|
|
||||||
bool ICreature::isLiving() const //TODO: theoreticaly there exists "LIVING" bonus in stack experience documentation
|
bool ICreature::isLiving() const //TODO: theoreticaly there exists "LIVING" bonus in stack experience documentation
|
||||||
{
|
{
|
||||||
static const std::string cachingStr = "IBonusBearer::isLiving";
|
static const std::string cachingStr = "ICreature::isLiving";
|
||||||
static const CSelector selector = Selector::type()(Bonus::UNDEAD)
|
static const CSelector selector = Selector::type()(Bonus::UNDEAD)
|
||||||
.Or(Selector::type()(Bonus::NON_LIVING))
|
.Or(Selector::type()(Bonus::NON_LIVING))
|
||||||
.Or(Selector::type()(Bonus::GARGOYLE))
|
.Or(Selector::type()(Bonus::GARGOYLE))
|
||||||
|
@ -606,22 +606,6 @@ void BonusList::insert(BonusList::TInternalContainer::iterator position, BonusLi
|
|||||||
changed();
|
changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
CSelector IBonusBearer::anaffectedByMoraleSelector =
|
|
||||||
Selector::type()(Bonus::NON_LIVING)
|
|
||||||
.Or(Selector::type()(Bonus::UNDEAD))
|
|
||||||
.Or(Selector::type()(Bonus::SIEGE_WEAPON))
|
|
||||||
.Or(Selector::type()(Bonus::NO_MORALE));
|
|
||||||
|
|
||||||
CSelector IBonusBearer::moraleSelector = Selector::type()(Bonus::MORALE);
|
|
||||||
CSelector IBonusBearer::luckSelector = Selector::type()(Bonus::LUCK);
|
|
||||||
|
|
||||||
IBonusBearer::IBonusBearer()
|
|
||||||
:anaffectedByMorale(this, anaffectedByMoraleSelector),
|
|
||||||
moraleValue(this, moraleSelector, 0),
|
|
||||||
luckValue(this, luckSelector, 0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int IBonusBearer::valOfBonuses(Bonus::BonusType type, const CSelector &selector) const
|
int IBonusBearer::valOfBonuses(Bonus::BonusType type, const CSelector &selector) const
|
||||||
{
|
{
|
||||||
return valOfBonuses(Selector::type()(type).And(selector));
|
return valOfBonuses(Selector::type()(type).And(selector));
|
||||||
@ -685,47 +669,6 @@ bool IBonusBearer::hasBonusFrom(Bonus::BonusSource source, ui32 sourceID) const
|
|||||||
|
|
||||||
return hasBonus(Selector::source(source,sourceID), fmt.str());
|
return hasBonus(Selector::source(source,sourceID), fmt.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
int IBonusBearer::MoraleVal() const
|
|
||||||
{
|
|
||||||
if(anaffectedByMorale.getHasBonus())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return std::clamp(moraleValue.getValue(), -3, +3);
|
|
||||||
}
|
|
||||||
|
|
||||||
int IBonusBearer::LuckVal() const
|
|
||||||
{
|
|
||||||
if(hasBonusOfType(Bonus::NO_LUCK))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return std::clamp(luckValue.getValue(), -3, +3);
|
|
||||||
}
|
|
||||||
|
|
||||||
int IBonusBearer::MoraleValAndBonusList(TConstBonusListPtr & bonusList) const
|
|
||||||
{
|
|
||||||
if(anaffectedByMorale.getHasBonus())
|
|
||||||
{
|
|
||||||
if(!bonusList->empty())
|
|
||||||
bonusList = std::make_shared<const BonusList>();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::clamp(moraleValue.getValueAndList(bonusList), -3, +3);
|
|
||||||
}
|
|
||||||
|
|
||||||
int IBonusBearer::LuckValAndBonusList(TConstBonusListPtr & bonusList) const
|
|
||||||
{
|
|
||||||
if(hasBonusOfType(Bonus::NO_LUCK))
|
|
||||||
{
|
|
||||||
if(!bonusList->empty())
|
|
||||||
bonusList = std::make_shared<const BonusList>();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::clamp(luckValue.getValueAndList(bonusList), -3, +3);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<const Bonus> IBonusBearer::getBonus(const CSelector &selector) const
|
std::shared_ptr<const Bonus> IBonusBearer::getBonus(const CSelector &selector) const
|
||||||
{
|
{
|
||||||
auto bonuses = getAllBonuses(selector, Selector::all);
|
auto bonuses = getAllBonuses(selector, Selector::all);
|
||||||
|
@ -663,20 +663,12 @@ DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const BonusList &bonusL
|
|||||||
|
|
||||||
class DLL_LINKAGE IBonusBearer
|
class DLL_LINKAGE IBonusBearer
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
static CSelector anaffectedByMoraleSelector;
|
|
||||||
CCheckProxy anaffectedByMorale;
|
|
||||||
static CSelector moraleSelector;
|
|
||||||
CTotalsProxy moraleValue;
|
|
||||||
static CSelector luckSelector;
|
|
||||||
CTotalsProxy luckValue;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//new bonusing node interface
|
//new bonusing node interface
|
||||||
// * selector is predicate that tests if HeroBonus matches our criteria
|
// * selector is predicate that tests if HeroBonus matches our criteria
|
||||||
// * root is node on which call was made (nullptr will be replaced with this)
|
// * root is node on which call was made (nullptr will be replaced with this)
|
||||||
//interface
|
//interface
|
||||||
IBonusBearer();
|
IBonusBearer() = default;
|
||||||
virtual ~IBonusBearer() = default;
|
virtual ~IBonusBearer() = default;
|
||||||
virtual TConstBonusListPtr getAllBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = nullptr, const std::string &cachingStr = "") const = 0;
|
virtual TConstBonusListPtr getAllBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = nullptr, const std::string &cachingStr = "") const = 0;
|
||||||
int valOfBonuses(const CSelector &selector, const std::string &cachingStr = "") const;
|
int valOfBonuses(const CSelector &selector, const std::string &cachingStr = "") const;
|
||||||
@ -693,19 +685,6 @@ public:
|
|||||||
bool hasBonusOfType(Bonus::BonusType type, int subtype = -1) const;//determines if hero has a bonus of given type (and optionally subtype)
|
bool hasBonusOfType(Bonus::BonusType type, int subtype = -1) const;//determines if hero has a bonus of given type (and optionally subtype)
|
||||||
bool hasBonusFrom(Bonus::BonusSource source, ui32 sourceID) const;
|
bool hasBonusFrom(Bonus::BonusSource source, ui32 sourceID) const;
|
||||||
|
|
||||||
//various hlp functions for non-trivial values
|
|
||||||
//used for stacks and creatures only
|
|
||||||
|
|
||||||
int MoraleVal() const; //range [-3, +3]
|
|
||||||
int LuckVal() const; //range [-3, +3]
|
|
||||||
/**
|
|
||||||
Returns total value of all morale bonuses and sets bonusList as a pointer to the list of selected bonuses.
|
|
||||||
@param bonusList is the out param it's list of all selected bonuses
|
|
||||||
@return total value of all morale in the range [-3, +3] and 0 otherwise
|
|
||||||
*/
|
|
||||||
int MoraleValAndBonusList(TConstBonusListPtr & bonusList) const;
|
|
||||||
int LuckValAndBonusList(TConstBonusListPtr & bonusList) const;
|
|
||||||
|
|
||||||
virtual int64_t getTreeVersion() const = 0;
|
virtual int64_t getTreeVersion() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user