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

vcmi: split creatures and faction members

This commit is contained in:
Konstantin 2023-04-27 00:11:04 +03:00
parent f4f0fd5945
commit af25ad0866
10 changed files with 90 additions and 74 deletions

View File

@ -213,8 +213,8 @@ uint64_t evaluateArtifactArmyValue(CArtifactInstance * art)
10 * art->valOfBonuses(Bonus::MOVEMENT, 1)
+ 1200 * art->valOfBonuses(Bonus::STACKS_SPEED)
+ 700 * art->valOfBonuses(Bonus::MORALE)
+ 700 * art->getAttack(false)
+ 700 * art->getDefense(false)
+ 700 * art->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK)
+ 700 * art->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE)
+ 700 * art->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::KNOWLEDGE)
+ 700 * art->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::SPELL_POWER)
+ 500 * art->valOfBonuses(Bonus::LUCK);

View File

@ -18,7 +18,7 @@ class CreatureID;
class ResourceSet;
enum class EGameResID : int8_t;
class DLL_LINKAGE Creature : public EntityWithNativeTerrain<CreatureID>
class DLL_LINKAGE Creature : public CreatureEntity<CreatureID>
{
protected:
// use getNamePlural/Singular instead

View File

@ -42,6 +42,30 @@ public:
Returns magic resistance considering some bonuses.
*/
virtual int32_t magicResistance() const;
/**
Returns minimal damage of creature or (when implemented) hero.
*/
virtual int getMinDamage(bool ranged) const;
/**
Returns maximal damage of creature or (when implemented) hero.
*/
virtual int getMaxDamage(bool ranged) const;
/**
Returns attack of creature or hero.
*/
virtual int getAttack(bool ranged) const;
/**
Returns defence of creature or hero.
*/
virtual int getDefense(bool ranged) const;
};
/// Base class for creatures and battle stacks
class DLL_LINKAGE ICreature: public IFactionMember
{
public:
ui32 Speed(int turn = 0, bool useBind = false) const; //get speed (in moving tiles) of creature with all modificators
ui32 MaxHealth() const; //get max HP of stack with all modifiers
};
class DLL_LINKAGE Entity
@ -73,7 +97,7 @@ class DLL_LINKAGE EntityWithBonuses : public EntityT<IdType>, public IConstBonus
};
template <typename IdType>
class DLL_LINKAGE EntityWithNativeTerrain : public EntityT<IdType>, public IFactionMember
class DLL_LINKAGE CreatureEntity : public EntityT<IdType>, public ICreature
{
};

View File

@ -45,4 +45,59 @@ int32_t IFactionMember::magicResistance() const
return val;
}
int IFactionMember::getAttack(bool ranged) const
{
const std::string cachingStr = "type_PRIMARY_SKILLs_ATTACK";
static const auto selector = Selector::typeSubtype(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK);
return getBonusBearer()->valOfBonuses(selector, cachingStr);
}
int IFactionMember::getDefense(bool ranged) const
{
const std::string cachingStr = "type_PRIMARY_SKILLs_DEFENSE";
static const auto selector = Selector::typeSubtype(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE);
return getBonusBearer()->valOfBonuses(selector, cachingStr);
}
int IFactionMember::getMinDamage(bool ranged) const
{
const std::string cachingStr = "type_CREATURE_DAMAGEs_0Otype_CREATURE_DAMAGEs_1";
static const auto selector = Selector::typeSubtype(Bonus::CREATURE_DAMAGE, 0).Or(Selector::typeSubtype(Bonus::CREATURE_DAMAGE, 1));
return getBonusBearer()->valOfBonuses(selector, cachingStr);
}
int IFactionMember::getMaxDamage(bool ranged) const
{
const std::string cachingStr = "type_CREATURE_DAMAGEs_0Otype_CREATURE_DAMAGEs_2";
static const auto selector = Selector::typeSubtype(Bonus::CREATURE_DAMAGE, 0).Or(Selector::typeSubtype(Bonus::CREATURE_DAMAGE, 2));
return getBonusBearer()->valOfBonuses(selector, cachingStr);
}
ui32 ICreature::MaxHealth() const
{
const std::string cachingStr = "type_STACK_HEALTH";
static const auto selector = Selector::type()(Bonus::STACK_HEALTH);
auto value = getBonusBearer()->valOfBonuses(selector, cachingStr);
return std::max(1, value); //never 0
}
ui32 ICreature::Speed(int turn, bool useBind) const
{
//war machines cannot move
if(getBonusBearer()->hasBonus(Selector::type()(Bonus::SIEGE_WEAPON).And(Selector::turns(turn))))
{
return 0;
}
//bind effect check - doesn't influence stack initiative
if(useBind && getBonusBearer()->hasBonus(Selector::type()(Bonus::BIND_EFFECT).And(Selector::turns(turn))))
{
return 0;
}
return getBonusBearer()->valOfBonuses(Selector::type()(Bonus::STACKS_SPEED).And(Selector::turns(turn)));
}
VCMI_LIB_NAMESPACE_END

View File

@ -71,7 +71,7 @@ const IBonusBearer * CCreature::getBonusBearer() const
uint32_t CCreature::getMaxHealth() const
{
return CBonusSystemNode::MaxHealth();
return MaxHealth();
}
int32_t CCreature::getAdvMapAmountMin() const

View File

@ -63,7 +63,7 @@ public:
void serializeJson(JsonSerializeFormat & handler);
};
class DLL_LINKAGE CStackInstance : public CBonusSystemNode, public CStackBasicDescriptor, public CArtifactSet, public IFactionMember
class DLL_LINKAGE CStackInstance : public CBonusSystemNode, public CStackBasicDescriptor, public CArtifactSet, public ICreature
{
protected:
const CArmedInstance *_armyObj; //stack must be part of some army, army must be part of some object

View File

@ -744,46 +744,6 @@ int IBonusBearer::LuckValAndBonusList(TConstBonusListPtr & bonusList) const
return std::clamp(luckValue.getValueAndList(bonusList), -3, +3);
}
ui32 IBonusBearer::MaxHealth() const
{
const std::string cachingStr = "type_STACK_HEALTH";
static const auto selector = Selector::type()(Bonus::STACK_HEALTH);
auto value = valOfBonuses(selector, cachingStr);
return std::max(1, value); //never 0
}
int IBonusBearer::getAttack(bool ranged) const
{
const std::string cachingStr = "type_PRIMARY_SKILLs_ATTACK";
static const auto selector = Selector::typeSubtype(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK);
return getBonuses(selector, nullptr, cachingStr)->totalValue();
}
int IBonusBearer::getDefense(bool ranged) const
{
const std::string cachingStr = "type_PRIMARY_SKILLs_DEFENSE";
static const auto selector = Selector::typeSubtype(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE);
return getBonuses(selector, nullptr, cachingStr)->totalValue();
}
int IBonusBearer::getMinDamage(bool ranged) const
{
const std::string cachingStr = "type_CREATURE_DAMAGEs_0Otype_CREATURE_DAMAGEs_1";
static const auto selector = Selector::typeSubtype(Bonus::CREATURE_DAMAGE, 0).Or(Selector::typeSubtype(Bonus::CREATURE_DAMAGE, 1));
return valOfBonuses(selector, cachingStr);
}
int IBonusBearer::getMaxDamage(bool ranged) const
{
const std::string cachingStr = "type_CREATURE_DAMAGEs_0Otype_CREATURE_DAMAGEs_2";
static const auto selector = Selector::typeSubtype(Bonus::CREATURE_DAMAGE, 0).Or(Selector::typeSubtype(Bonus::CREATURE_DAMAGE, 2));
return valOfBonuses(selector, cachingStr);
}
int IBonusBearer::getPrimSkillLevel(PrimarySkill::PrimarySkill id) const
{
static const CSelector selectorAllSkills = Selector::type()(Bonus::PRIMARY_SKILL);
@ -795,22 +755,6 @@ int IBonusBearer::getPrimSkillLevel(PrimarySkill::PrimarySkill id) const
return ret; //sp=0 works in old saves
}
ui32 IBonusBearer::Speed(int turn, bool useBind) const
{
//war machines cannot move
if(hasBonus(Selector::type()(Bonus::SIEGE_WEAPON).And(Selector::turns(turn))))
{
return 0;
}
//bind effect check - doesn't influence stack initiative
if(useBind && hasBonus(Selector::type()(Bonus::BIND_EFFECT).And(Selector::turns(turn))))
{
return 0;
}
return valOfBonuses(Selector::type()(Bonus::STACKS_SPEED).And(Selector::turns(turn)));
}
bool IBonusBearer::isLiving() const //TODO: theoreticaly there exists "LIVING" bonus in stack experience documentation
{
static const std::string cachingStr = "IBonusBearer::isLiving";

View File

@ -743,11 +743,6 @@ public:
//various hlp functions for non-trivial values
//used for stacks and creatures only
virtual int getMinDamage(bool ranged) const;
virtual int getMaxDamage(bool ranged) const;
virtual int getAttack(bool ranged) const;
virtual int getDefense(bool ranged) const;
int MoraleVal() const; //range [-3, +3]
int LuckVal() const; //range [-3, +3]
/**
@ -758,9 +753,7 @@ public:
int MoraleValAndBonusList(TConstBonusListPtr & bonusList) const;
int LuckValAndBonusList(TConstBonusListPtr & bonusList) const;
ui32 MaxHealth() const; //get max HP of stack with all modifiers
bool isLiving() const; //non-undead, non-non living or alive
ui32 Speed(int turn = 0, bool useBind = false) const; //get speed of creature with all modificators
int getPrimSkillLevel(PrimarySkill::PrimarySkill id) const;

View File

@ -41,7 +41,7 @@ namespace BattlePhases
class CUnitState;
class DLL_LINKAGE Unit : public IUnitInfo, public spells::Caster, public virtual IBonusBearer, public IFactionMember
class DLL_LINKAGE Unit : public IUnitInfo, public spells::Caster, public virtual IBonusBearer, public ICreature
{
public:
virtual ~Unit();

View File

@ -29,10 +29,10 @@ VCMI_REGISTER_SCRIPT_API(UnitProxy, "battle.Unit")
const std::vector<UnitProxy::CustomRegType> UnitProxy::REGISTER_CUSTOM =
{
{"getMinDamage", LuaMethodWrapper<Unit, decltype(&IBonusBearer::getMinDamage), &IBonusBearer::getMinDamage>::invoke, false},
{"getMaxDamage", LuaMethodWrapper<Unit, decltype(&IBonusBearer::getMaxDamage), &IBonusBearer::getMaxDamage>::invoke, false},
{"getAttack", LuaMethodWrapper<Unit, decltype(&IBonusBearer::getAttack), &IBonusBearer::getAttack>::invoke, false},
{"getDefense", LuaMethodWrapper<Unit, decltype(&IBonusBearer::getDefense), &IBonusBearer::getDefense>::invoke, false},
{"getMinDamage", LuaMethodWrapper<Unit, decltype(&ICreature::getMinDamage), &ICreature::getMinDamage>::invoke, false},
{"getMaxDamage", LuaMethodWrapper<Unit, decltype(&ICreature::getMaxDamage), &ICreature::getMaxDamage>::invoke, false},
{"getAttack", LuaMethodWrapper<Unit, decltype(&ICreature::getAttack), &ICreature::getAttack>::invoke, false},
{"getDefense", LuaMethodWrapper<Unit, decltype(&ICreature::getDefense), &ICreature::getDefense>::invoke, false},
{"isAlive", LuaMethodWrapper<Unit, decltype(&Unit::alive), &Unit::alive>::invoke, false},
{"unitId", LuaMethodWrapper<Unit, decltype(&IUnitInfo::unitId), &IUnitInfo::unitId>::invoke, false},
};