mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-26 03:52:01 +02:00
refactoring: TDmgRange pair -> DamageRange struct
This commit is contained in:
parent
6382e0a3a0
commit
31147ac83b
@ -13,9 +13,9 @@
|
|||||||
// Eventually only IBattleInfoCallback and battle::Unit should be used,
|
// Eventually only IBattleInfoCallback and battle::Unit should be used,
|
||||||
// CUnitState should be private and CStack should be removed completely
|
// CUnitState should be private and CStack should be removed completely
|
||||||
|
|
||||||
uint64_t averageDmg(const TDmgRange & range)
|
uint64_t averageDmg(const DamageRange & range)
|
||||||
{
|
{
|
||||||
return (range.first + range.second) / 2;
|
return (range.min + range.max) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
AttackPossibility::AttackPossibility(BattleHex from, BattleHex dest, const BattleAttackInfo & attack)
|
AttackPossibility::AttackPossibility(BattleHex from, BattleHex dest, const BattleAttackInfo & attack)
|
||||||
@ -156,14 +156,14 @@ AttackPossibility AttackPossibility::evaluate(const BattleAttackInfo & attackInf
|
|||||||
{
|
{
|
||||||
int64_t damageDealt, damageReceived, defenderDamageReduce, attackerDamageReduce;
|
int64_t damageDealt, damageReceived, defenderDamageReduce, attackerDamageReduce;
|
||||||
|
|
||||||
TDmgRange retaliation(0, 0);
|
DamageRange retaliation;
|
||||||
auto attackDmg = state.battleEstimateDamage(ap.attack, &retaliation);
|
auto attackDmg = state.battleEstimateDamage(ap.attack, &retaliation);
|
||||||
|
|
||||||
vstd::amin(attackDmg.first, defenderState->getAvailableHealth());
|
vstd::amin(attackDmg.min, defenderState->getAvailableHealth());
|
||||||
vstd::amin(attackDmg.second, defenderState->getAvailableHealth());
|
vstd::amin(attackDmg.max, defenderState->getAvailableHealth());
|
||||||
|
|
||||||
vstd::amin(retaliation.first, ap.attackerState->getAvailableHealth());
|
vstd::amin(retaliation.min, ap.attackerState->getAvailableHealth());
|
||||||
vstd::amin(retaliation.second, ap.attackerState->getAvailableHealth());
|
vstd::amin(retaliation.max, ap.attackerState->getAvailableHealth());
|
||||||
|
|
||||||
damageDealt = averageDmg(attackDmg);
|
damageDealt = averageDmg(attackDmg);
|
||||||
defenderDamageReduce = calculateDamageReduce(attacker, defender, damageDealt, state);
|
defenderDamageReduce = calculateDamageReduce(attacker, defender, damageDealt, state);
|
||||||
|
@ -68,7 +68,7 @@ int64_t BattleExchangeVariant::trackAttack(
|
|||||||
static const auto selectorBlocksRetaliation = Selector::type()(Bonus::BLOCKS_RETALIATION);
|
static const auto selectorBlocksRetaliation = Selector::type()(Bonus::BLOCKS_RETALIATION);
|
||||||
const bool counterAttacksBlocked = attacker->hasBonus(selectorBlocksRetaliation, cachingStringBlocksRetaliation);
|
const bool counterAttacksBlocked = attacker->hasBonus(selectorBlocksRetaliation, cachingStringBlocksRetaliation);
|
||||||
|
|
||||||
TDmgRange retaliation;
|
DamageRange retaliation;
|
||||||
// FIXME: provide distance info for Jousting bonus
|
// FIXME: provide distance info for Jousting bonus
|
||||||
BattleAttackInfo bai(attacker.get(), defender.get(), 0, shooting);
|
BattleAttackInfo bai(attacker.get(), defender.get(), 0, shooting);
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ int64_t BattleExchangeVariant::trackAttack(
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto attack = cb.battleEstimateDamage(bai, &retaliation);
|
auto attack = cb.battleEstimateDamage(bai, &retaliation);
|
||||||
int64_t attackDamage = (attack.first + attack.second) / 2;
|
int64_t attackDamage = (attack.min + attack.max) / 2;
|
||||||
int64_t defenderDamageReduce = AttackPossibility::calculateDamageReduce(attacker.get(), defender.get(), attackDamage, cb);
|
int64_t defenderDamageReduce = AttackPossibility::calculateDamageReduce(attacker.get(), defender.get(), attackDamage, cb);
|
||||||
int64_t attackerDamageReduce = 0;
|
int64_t attackerDamageReduce = 0;
|
||||||
|
|
||||||
@ -108,9 +108,9 @@ int64_t BattleExchangeVariant::trackAttack(
|
|||||||
|
|
||||||
if(defender->alive() && defender->ableToRetaliate() && !counterAttacksBlocked && !shooting)
|
if(defender->alive() && defender->ableToRetaliate() && !counterAttacksBlocked && !shooting)
|
||||||
{
|
{
|
||||||
if(retaliation.second != 0)
|
if(retaliation.max != 0)
|
||||||
{
|
{
|
||||||
auto retaliationDamage = (retaliation.first + retaliation.second) / 2;
|
auto retaliationDamage = (retaliation.min + retaliation.max) / 2;
|
||||||
attackerDamageReduce = AttackPossibility::calculateDamageReduce(defender.get(), attacker.get(), retaliationDamage, cb);
|
attackerDamageReduce = AttackPossibility::calculateDamageReduce(defender.get(), attacker.get(), retaliationDamage, cb);
|
||||||
|
|
||||||
if(!evaluateOnly)
|
if(!evaluateOnly)
|
||||||
|
@ -428,9 +428,9 @@ uint32_t HypotheticBattle::nextUnitId() const
|
|||||||
return nextId++;
|
return nextId++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t HypotheticBattle::getActualDamage(const TDmgRange & damage, int32_t attackerCount, vstd::RNG & rng) const
|
int64_t HypotheticBattle::getActualDamage(const DamageRange & damage, int32_t attackerCount, vstd::RNG & rng) const
|
||||||
{
|
{
|
||||||
return (damage.first + damage.second) / 2;
|
return (damage.min + damage.max) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t HypotheticBattle::getTreeVersion() const
|
int64_t HypotheticBattle::getTreeVersion() const
|
||||||
|
@ -138,7 +138,7 @@ public:
|
|||||||
|
|
||||||
uint32_t nextUnitId() const override;
|
uint32_t nextUnitId() const override;
|
||||||
|
|
||||||
int64_t getActualDamage(const TDmgRange & damage, int32_t attackerCount, vstd::RNG & rng) const override;
|
int64_t getActualDamage(const DamageRange & damage, int32_t attackerCount, vstd::RNG & rng) const override;
|
||||||
|
|
||||||
int64_t getTreeVersion() const;
|
int64_t getTreeVersion() const;
|
||||||
|
|
||||||
|
@ -56,9 +56,9 @@ public:
|
|||||||
void calcDmg(const CStack * ourStack)
|
void calcDmg(const CStack * ourStack)
|
||||||
{
|
{
|
||||||
// FIXME: provide distance info for Jousting bonus
|
// FIXME: provide distance info for Jousting bonus
|
||||||
TDmgRange retal, dmg = cbc->battleEstimateDamage(ourStack, s, 0, &retal);
|
DamageRange retal, dmg = cbc->battleEstimateDamage(ourStack, s, 0, &retal);
|
||||||
adi = static_cast<int>((dmg.first + dmg.second) / 2);
|
adi = static_cast<int>((dmg.min + dmg.max) / 2);
|
||||||
adr = static_cast<int>((retal.first + retal.second) / 2);
|
adr = static_cast<int>((retal.min + retal.max) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const EnemyInfo& ei) const
|
bool operator==(const EnemyInfo& ei) const
|
||||||
|
@ -32,12 +32,12 @@
|
|||||||
#include "../../lib/spells/Problem.h"
|
#include "../../lib/spells/Problem.h"
|
||||||
#include "../../lib/CGeneralTextHandler.h"
|
#include "../../lib/CGeneralTextHandler.h"
|
||||||
|
|
||||||
static std::string formatDmgRange(std::pair<ui32, ui32> dmgRange)
|
static std::string formatDmgRange(DamageRange dmgRange)
|
||||||
{
|
{
|
||||||
if (dmgRange.first != dmgRange.second)
|
if (dmgRange.min != dmgRange.max)
|
||||||
return (boost::format("%d - %d") % dmgRange.first % dmgRange.second).str();
|
return (boost::format("%d - %d") % dmgRange.min % dmgRange.max).str();
|
||||||
else
|
else
|
||||||
return (boost::format("%d") % dmgRange.first).str();
|
return (boost::format("%d") % dmgRange.min).str();
|
||||||
}
|
}
|
||||||
|
|
||||||
BattleActionsController::BattleActionsController(BattleInterface & owner):
|
BattleActionsController::BattleActionsController(BattleInterface & owner):
|
||||||
@ -356,8 +356,8 @@ std::string BattleActionsController::actionGetStatusMessage(PossiblePlayerBattle
|
|||||||
case PossiblePlayerBattleAction::ATTACK_AND_RETURN: //TODO: allow to disable return
|
case PossiblePlayerBattleAction::ATTACK_AND_RETURN: //TODO: allow to disable return
|
||||||
{
|
{
|
||||||
BattleHex attackFromHex = owner.fieldController->fromWhichHexAttack(targetHex);
|
BattleHex attackFromHex = owner.fieldController->fromWhichHexAttack(targetHex);
|
||||||
TDmgRange damage = owner.curInt->cb->battleEstimateDamage(owner.stacksController->getActiveStack(), targetStack, attackFromHex);
|
DamageRange damage = owner.curInt->cb->battleEstimateDamage(owner.stacksController->getActiveStack(), targetStack, attackFromHex);
|
||||||
std::string estDmgText = formatDmgRange(std::make_pair((ui32)damage.first, (ui32)damage.second)); //calculating estimated dmg
|
std::string estDmgText = formatDmgRange(damage); //calculating estimated dmg
|
||||||
return (boost::format(CGI->generaltexth->allTexts[36]) % targetStack->getName() % estDmgText).str(); //Attack %s (%s damage)
|
return (boost::format(CGI->generaltexth->allTexts[36]) % targetStack->getName() % estDmgText).str(); //Attack %s (%s damage)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,8 +365,8 @@ std::string BattleActionsController::actionGetStatusMessage(PossiblePlayerBattle
|
|||||||
{
|
{
|
||||||
auto const * shooter = owner.stacksController->getActiveStack();
|
auto const * shooter = owner.stacksController->getActiveStack();
|
||||||
|
|
||||||
TDmgRange damage = owner.curInt->cb->battleEstimateDamage(shooter, targetStack, shooter->getPosition());
|
DamageRange damage = owner.curInt->cb->battleEstimateDamage(shooter, targetStack, shooter->getPosition());
|
||||||
std::string estDmgText = formatDmgRange(std::make_pair((ui32)damage.first, (ui32)damage.second)); //calculating estimated dmg
|
std::string estDmgText = formatDmgRange(damage); //calculating estimated dmg
|
||||||
//printing - Shoot %s (%d shots left, %s damage)
|
//printing - Shoot %s (%d shots left, %s damage)
|
||||||
return (boost::format(CGI->generaltexth->allTexts[296]) % targetStack->getName() % shooter->shots.available() % estDmgText).str();
|
return (boost::format(CGI->generaltexth->allTexts[296]) % targetStack->getName() % shooter->shots.available() % estDmgText).str();
|
||||||
}
|
}
|
||||||
|
@ -1295,7 +1295,6 @@ enum class EHealPower : ui8
|
|||||||
// Typedef declarations
|
// Typedef declarations
|
||||||
typedef ui8 TFaction;
|
typedef ui8 TFaction;
|
||||||
typedef si64 TExpType;
|
typedef si64 TExpType;
|
||||||
typedef std::pair<si64, si64> TDmgRange;
|
|
||||||
typedef si32 TBonusSubtype;
|
typedef si32 TBonusSubtype;
|
||||||
typedef si32 TQuantity;
|
typedef si32 TQuantity;
|
||||||
|
|
||||||
|
@ -663,14 +663,14 @@ const IBonusBearer * BattleInfo::asBearer() const
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t BattleInfo::getActualDamage(const TDmgRange & damage, int32_t attackerCount, vstd::RNG & rng) const
|
int64_t BattleInfo::getActualDamage(const DamageRange & damage, int32_t attackerCount, vstd::RNG & rng) const
|
||||||
{
|
{
|
||||||
if(damage.first != damage.second)
|
if(damage.min != damage.max)
|
||||||
{
|
{
|
||||||
int64_t sum = 0;
|
int64_t sum = 0;
|
||||||
|
|
||||||
auto howManyToAv = std::min<int32_t>(10, attackerCount);
|
auto howManyToAv = std::min<int32_t>(10, attackerCount);
|
||||||
auto rangeGen = rng.getInt64Range(damage.first, damage.second);
|
auto rangeGen = rng.getInt64Range(damage.min, damage.max);
|
||||||
|
|
||||||
for(int32_t g = 0; g < howManyToAv; ++g)
|
for(int32_t g = 0; g < howManyToAv; ++g)
|
||||||
sum += rangeGen();
|
sum += rangeGen();
|
||||||
@ -679,7 +679,7 @@ int64_t BattleInfo::getActualDamage(const TDmgRange & damage, int32_t attackerCo
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return damage.first;
|
return damage.min;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ public:
|
|||||||
|
|
||||||
uint32_t nextUnitId() const override;
|
uint32_t nextUnitId() const override;
|
||||||
|
|
||||||
int64_t getActualDamage(const TDmgRange & damage, int32_t attackerCount, vstd::RNG & rng) const override;
|
int64_t getActualDamage(const DamageRange & damage, int32_t attackerCount, vstd::RNG & rng) const override;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// IBattleState
|
// IBattleState
|
||||||
|
@ -715,48 +715,49 @@ bool CBattleInfoCallback::battleCanShoot(const battle::Unit * attacker, BattleHe
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TDmgRange CBattleInfoCallback::calculateDmgRange(const BattleAttackInfo & info) const
|
DamageRange CBattleInfoCallback::calculateDmgRange(const BattleAttackInfo & info) const
|
||||||
{
|
{
|
||||||
DamageCalculator calculator(*this, info);
|
DamageCalculator calculator(*this, info);
|
||||||
|
|
||||||
return calculator.calculateDmgRange();
|
return calculator.calculateDmgRange();
|
||||||
}
|
}
|
||||||
|
|
||||||
TDmgRange CBattleInfoCallback::battleEstimateDamage(const battle::Unit * attacker, const battle::Unit * defender, BattleHex attackerPosition, TDmgRange * retaliationDmg) const
|
DamageRange CBattleInfoCallback::battleEstimateDamage(const battle::Unit * attacker, const battle::Unit * defender, BattleHex attackerPosition, DamageRange * retaliationDmg) const
|
||||||
{
|
{
|
||||||
RETURN_IF_NOT_BATTLE(std::make_pair(0, 0));
|
RETURN_IF_NOT_BATTLE({0, 0});
|
||||||
auto reachability = battleGetDistances(attacker, attacker->getPosition());
|
auto reachability = battleGetDistances(attacker, attacker->getPosition());
|
||||||
int movementDistance = reachability[attackerPosition];
|
int movementDistance = reachability[attackerPosition];
|
||||||
return battleEstimateDamage(attacker, defender, movementDistance, retaliationDmg);
|
return battleEstimateDamage(attacker, defender, movementDistance, retaliationDmg);
|
||||||
}
|
}
|
||||||
|
|
||||||
TDmgRange CBattleInfoCallback::battleEstimateDamage(const battle::Unit * attacker, const battle::Unit * defender, int movementDistance, TDmgRange * retaliationDmg) const
|
DamageRange CBattleInfoCallback::battleEstimateDamage(const battle::Unit * attacker, const battle::Unit * defender, int movementDistance, DamageRange * retaliationDmg) const
|
||||||
{
|
{
|
||||||
RETURN_IF_NOT_BATTLE(std::make_pair(0, 0));
|
RETURN_IF_NOT_BATTLE({0, 0});
|
||||||
const bool shooting = battleCanShoot(attacker, defender->getPosition());
|
const bool shooting = battleCanShoot(attacker, defender->getPosition());
|
||||||
const BattleAttackInfo bai(attacker, defender, movementDistance, shooting);
|
const BattleAttackInfo bai(attacker, defender, movementDistance, shooting);
|
||||||
return battleEstimateDamage(bai, retaliationDmg);
|
return battleEstimateDamage(bai, retaliationDmg);
|
||||||
}
|
}
|
||||||
|
|
||||||
TDmgRange CBattleInfoCallback::battleEstimateDamage(const BattleAttackInfo & bai, TDmgRange * retaliationDmg) const
|
DamageRange CBattleInfoCallback::battleEstimateDamage(const BattleAttackInfo & bai, DamageRange * retaliationDmg) const
|
||||||
{
|
{
|
||||||
RETURN_IF_NOT_BATTLE(std::make_pair(0, 0));
|
RETURN_IF_NOT_BATTLE({0, 0});
|
||||||
|
|
||||||
TDmgRange ret = calculateDmgRange(bai);
|
DamageRange ret = calculateDmgRange(bai);
|
||||||
|
|
||||||
if(retaliationDmg)
|
if(retaliationDmg)
|
||||||
{
|
{
|
||||||
if(bai.shooting)
|
if(bai.shooting)
|
||||||
{
|
{
|
||||||
//FIXME: handle RANGED_RETALIATION
|
//FIXME: handle RANGED_RETALIATION
|
||||||
retaliationDmg->first = retaliationDmg->second = 0;
|
retaliationDmg->min = 0;
|
||||||
|
retaliationDmg->max = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//TODO: rewrite using boost::numeric::interval
|
//TODO: rewrite using boost::numeric::interval
|
||||||
//TODO: rewire once more using interval-based fuzzy arithmetic
|
//TODO: rewire once more using interval-based fuzzy arithmetic
|
||||||
|
|
||||||
int64_t TDmgRange::* pairElems[] = {&TDmgRange::first, &TDmgRange::second};
|
int64_t DamageRange::* pairElems[] = {&DamageRange::min, &DamageRange::max};
|
||||||
for (int i=0; i<2; ++i)
|
for (int i=0; i<2; ++i)
|
||||||
{
|
{
|
||||||
auto retaliationAttack = bai.reverse();
|
auto retaliationAttack = bai.reverse();
|
||||||
|
@ -117,14 +117,14 @@ public:
|
|||||||
bool battleIsUnitBlocked(const battle::Unit * unit) const; //returns true if there is neighboring enemy stack
|
bool battleIsUnitBlocked(const battle::Unit * unit) const; //returns true if there is neighboring enemy stack
|
||||||
std::set<const battle::Unit *> battleAdjacentUnits(const battle::Unit * unit) const;
|
std::set<const battle::Unit *> battleAdjacentUnits(const battle::Unit * unit) const;
|
||||||
|
|
||||||
TDmgRange calculateDmgRange(const BattleAttackInfo & info) const; //charge - number of hexes travelled before attack (for champion's jousting); returns pair <min dmg, max dmg>
|
DamageRange calculateDmgRange(const BattleAttackInfo & info) const;
|
||||||
|
|
||||||
/// estimates damage dealt by attacker to defender;
|
/// estimates damage dealt by attacker to defender;
|
||||||
/// only non-random bonuses are considered in estimation
|
/// only non-random bonuses are considered in estimation
|
||||||
/// returns pair <min dmg, max dmg>
|
/// returns pair <min dmg, max dmg>
|
||||||
TDmgRange battleEstimateDamage(const BattleAttackInfo & bai, TDmgRange * retaliationDmg = nullptr) const;
|
DamageRange battleEstimateDamage(const BattleAttackInfo & bai, DamageRange * retaliationDmg = nullptr) const;
|
||||||
TDmgRange battleEstimateDamage(const battle::Unit * attacker, const battle::Unit * defender, BattleHex attackerPosition, TDmgRange * retaliationDmg = nullptr) const;
|
DamageRange battleEstimateDamage(const battle::Unit * attacker, const battle::Unit * defender, BattleHex attackerPosition, DamageRange * retaliationDmg = nullptr) const;
|
||||||
TDmgRange battleEstimateDamage(const battle::Unit * attacker, const battle::Unit * defender, int movementDistance, TDmgRange * retaliationDmg = nullptr) const;
|
DamageRange battleEstimateDamage(const battle::Unit * attacker, const battle::Unit * defender, int movementDistance, DamageRange * retaliationDmg = nullptr) const;
|
||||||
|
|
||||||
bool battleHasDistancePenalty(const IBonusBearer * shooter, BattleHex shooterPosition, BattleHex destHex) const;
|
bool battleHasDistancePenalty(const IBonusBearer * shooter, BattleHex shooterPosition, BattleHex destHex) const;
|
||||||
bool battleHasWallPenalty(const IBonusBearer * shooter, BattleHex shooterPosition, BattleHex destHex) const;
|
bool battleHasWallPenalty(const IBonusBearer * shooter, BattleHex shooterPosition, BattleHex destHex) const;
|
||||||
|
@ -20,10 +20,10 @@
|
|||||||
|
|
||||||
VCMI_LIB_NAMESPACE_BEGIN
|
VCMI_LIB_NAMESPACE_BEGIN
|
||||||
|
|
||||||
TDmgRange DamageCalculator::getBaseDamageSingle() const
|
DamageRange DamageCalculator::getBaseDamageSingle() const
|
||||||
{
|
{
|
||||||
double minDmg = 0.0;
|
int64_t minDmg = 0.0;
|
||||||
double maxDmg = 0.0;
|
int64_t maxDmg = 0.0;
|
||||||
|
|
||||||
minDmg = info.attacker->getMinDamage(info.shooting);
|
minDmg = info.attacker->getMinDamage(info.shooting);
|
||||||
maxDmg = info.attacker->getMaxDamage(info.shooting);
|
maxDmg = info.attacker->getMaxDamage(info.shooting);
|
||||||
@ -63,7 +63,7 @@ TDmgRange DamageCalculator::getBaseDamageSingle() const
|
|||||||
return { minDmg, maxDmg };
|
return { minDmg, maxDmg };
|
||||||
}
|
}
|
||||||
|
|
||||||
TDmgRange DamageCalculator::getBaseDamageBlessCurse() const
|
DamageRange DamageCalculator::getBaseDamageBlessCurse() const
|
||||||
{
|
{
|
||||||
const std::string cachingStrForcedMinDamage = "type_ALWAYS_MINIMUM_DAMAGE";
|
const std::string cachingStrForcedMinDamage = "type_ALWAYS_MINIMUM_DAMAGE";
|
||||||
static const auto selectorForcedMinDamage = Selector::type()(Bonus::ALWAYS_MINIMUM_DAMAGE);
|
static const auto selectorForcedMinDamage = Selector::type()(Bonus::ALWAYS_MINIMUM_DAMAGE);
|
||||||
@ -76,10 +76,10 @@ TDmgRange DamageCalculator::getBaseDamageBlessCurse() const
|
|||||||
|
|
||||||
int curseBlessAdditiveModifier = blessEffects->totalValue() - curseEffects->totalValue();
|
int curseBlessAdditiveModifier = blessEffects->totalValue() - curseEffects->totalValue();
|
||||||
|
|
||||||
TDmgRange baseDamage = getBaseDamageSingle();
|
DamageRange baseDamage = getBaseDamageSingle();
|
||||||
TDmgRange modifiedDamage = {
|
DamageRange modifiedDamage = {
|
||||||
std::max(static_cast<int64_t>(1), baseDamage.first + curseBlessAdditiveModifier),
|
std::max(static_cast<int64_t>(1), baseDamage.min + curseBlessAdditiveModifier),
|
||||||
std::max(static_cast<int64_t>(1), baseDamage.second + curseBlessAdditiveModifier)
|
std::max(static_cast<int64_t>(1), baseDamage.max + curseBlessAdditiveModifier)
|
||||||
};
|
};
|
||||||
|
|
||||||
if(curseEffects->size() && blessEffects->size() )
|
if(curseEffects->size() && blessEffects->size() )
|
||||||
@ -91,29 +91,29 @@ TDmgRange DamageCalculator::getBaseDamageBlessCurse() const
|
|||||||
if(curseEffects->size())
|
if(curseEffects->size())
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
modifiedDamage.first,
|
modifiedDamage.min,
|
||||||
modifiedDamage.first
|
modifiedDamage.min
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if(blessEffects->size())
|
if(blessEffects->size())
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
modifiedDamage.second,
|
modifiedDamage.max,
|
||||||
modifiedDamage.second
|
modifiedDamage.max
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return modifiedDamage;
|
return modifiedDamage;
|
||||||
}
|
}
|
||||||
|
|
||||||
TDmgRange DamageCalculator::getBaseDamageStack() const
|
DamageRange DamageCalculator::getBaseDamageStack() const
|
||||||
{
|
{
|
||||||
auto stackSize = info.attacker->getCount();
|
auto stackSize = info.attacker->getCount();
|
||||||
auto baseDamage = getBaseDamageBlessCurse();
|
auto baseDamage = getBaseDamageBlessCurse();
|
||||||
return {
|
return {
|
||||||
baseDamage.first * stackSize,
|
baseDamage.min * stackSize,
|
||||||
baseDamage.second * stackSize
|
baseDamage.max * stackSize
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,9 +461,9 @@ int DamageCalculator::battleBonusValue(const IBonusBearer * bearer, const CSelec
|
|||||||
return bearer->getBonuses(selector, noLimit.Or(limitMatches))->totalValue();
|
return bearer->getBonuses(selector, noLimit.Or(limitMatches))->totalValue();
|
||||||
};
|
};
|
||||||
|
|
||||||
TDmgRange DamageCalculator::calculateDmgRange() const
|
DamageRange DamageCalculator::calculateDmgRange() const
|
||||||
{
|
{
|
||||||
TDmgRange result = getBaseDamageStack();
|
DamageRange result = getBaseDamageStack();
|
||||||
|
|
||||||
auto attackFactors = getAttackFactors();
|
auto attackFactors = getAttackFactors();
|
||||||
auto defenseFactors = getDefenseFactors();
|
auto defenseFactors = getDefenseFactors();
|
||||||
@ -486,8 +486,8 @@ TDmgRange DamageCalculator::calculateDmgRange() const
|
|||||||
double resultingFactor = std::min(8.0, attackFactorTotal) * std::max( 0.01, defenseFactorTotal);
|
double resultingFactor = std::min(8.0, attackFactorTotal) * std::max( 0.01, defenseFactorTotal);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
std::max( 1.0, std::floor(result.first * resultingFactor)),
|
std::max<int64_t>( 1.0, std::floor(result.min * resultingFactor)),
|
||||||
std::max( 1.0, std::floor(result.second * resultingFactor))
|
std::max<int64_t>( 1.0, std::floor(result.max * resultingFactor))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ class CBattleInfoCallback;
|
|||||||
class IBonusBearer;
|
class IBonusBearer;
|
||||||
class CSelector;
|
class CSelector;
|
||||||
struct BattleAttackInfo;
|
struct BattleAttackInfo;
|
||||||
|
struct DamageRange;
|
||||||
|
|
||||||
class DLL_LINKAGE DamageCalculator
|
class DLL_LINKAGE DamageCalculator
|
||||||
{
|
{
|
||||||
@ -26,9 +27,9 @@ class DLL_LINKAGE DamageCalculator
|
|||||||
|
|
||||||
int battleBonusValue(const IBonusBearer * bearer, const CSelector & selector) const;
|
int battleBonusValue(const IBonusBearer * bearer, const CSelector & selector) const;
|
||||||
|
|
||||||
TDmgRange getBaseDamageSingle() const;
|
DamageRange getBaseDamageSingle() const;
|
||||||
TDmgRange getBaseDamageBlessCurse() const;
|
DamageRange getBaseDamageBlessCurse() const;
|
||||||
TDmgRange getBaseDamageStack() const;
|
DamageRange getBaseDamageStack() const;
|
||||||
|
|
||||||
int getActorAttackBase() const;
|
int getActorAttackBase() const;
|
||||||
int getActorAttackEffective() const;
|
int getActorAttackEffective() const;
|
||||||
@ -66,7 +67,7 @@ public:
|
|||||||
info(info)
|
info(info)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
TDmgRange calculateDmgRange() const;
|
DamageRange calculateDmgRange() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_END
|
VCMI_LIB_NAMESPACE_END
|
||||||
|
@ -26,6 +26,12 @@ namespace battle
|
|||||||
using UnitFilter = std::function<bool(const Unit *)>;
|
using UnitFilter = std::function<bool(const Unit *)>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct DamageRange
|
||||||
|
{
|
||||||
|
int64_t min = 0;
|
||||||
|
int64_t max = 0;
|
||||||
|
};
|
||||||
|
|
||||||
#if SCRIPTING_ENABLED
|
#if SCRIPTING_ENABLED
|
||||||
namespace scripting
|
namespace scripting
|
||||||
{
|
{
|
||||||
|
@ -66,7 +66,7 @@ public:
|
|||||||
|
|
||||||
virtual uint32_t nextUnitId() const = 0;
|
virtual uint32_t nextUnitId() const = 0;
|
||||||
|
|
||||||
virtual int64_t getActualDamage(const TDmgRange & damage, int32_t attackerCount, vstd::RNG & rng) const = 0;
|
virtual int64_t getActualDamage(const DamageRange & damage, int32_t attackerCount, vstd::RNG & rng) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE IBattleState : public IBattleInfo
|
class DLL_LINKAGE IBattleState : public IBattleInfo
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#include "CGTownInstance.h"
|
#include "CGTownInstance.h"
|
||||||
#include "CObjectClassesHandler.h"
|
#include "CObjectClassesHandler.h"
|
||||||
#include "../spells/CSpellHandler.h"
|
#include "../spells/CSpellHandler.h"
|
||||||
|
#include "../battle/IBattleInfoCallback.h"
|
||||||
#include "../NetPacks.h"
|
#include "../NetPacks.h"
|
||||||
#include "../CConfigHandler.h"
|
#include "../CConfigHandler.h"
|
||||||
#include "../CGeneralTextHandler.h"
|
#include "../CGeneralTextHandler.h"
|
||||||
@ -807,7 +807,7 @@ void CGTownInstance::addTownBonuses()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TDmgRange CGTownInstance::getTowerDamageRange() const
|
DamageRange CGTownInstance::getTowerDamageRange() const
|
||||||
{
|
{
|
||||||
assert(hasBuilt(BuildingID::CASTLE));
|
assert(hasBuilt(BuildingID::CASTLE));
|
||||||
|
|
||||||
@ -825,7 +825,7 @@ TDmgRange CGTownInstance::getTowerDamageRange() const
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
TDmgRange CGTownInstance::getKeepDamageRange() const
|
DamageRange CGTownInstance::getKeepDamageRange() const
|
||||||
{
|
{
|
||||||
assert(hasBuilt(BuildingID::CITADEL));
|
assert(hasBuilt(BuildingID::CITADEL));
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ VCMI_LIB_NAMESPACE_BEGIN
|
|||||||
class CCastleEvent;
|
class CCastleEvent;
|
||||||
class CGTownInstance;
|
class CGTownInstance;
|
||||||
class CGDwelling;
|
class CGDwelling;
|
||||||
|
struct DamageRange;
|
||||||
|
|
||||||
class DLL_LINKAGE CSpecObjInfo
|
class DLL_LINKAGE CSpecObjInfo
|
||||||
{
|
{
|
||||||
@ -332,10 +333,10 @@ public:
|
|||||||
void deleteTownBonus(BuildingID::EBuildingID bid);
|
void deleteTownBonus(BuildingID::EBuildingID bid);
|
||||||
|
|
||||||
/// Returns damage range for secondary towers of this town
|
/// Returns damage range for secondary towers of this town
|
||||||
TDmgRange getTowerDamageRange() const;
|
DamageRange getTowerDamageRange() const;
|
||||||
|
|
||||||
/// Returns damage range for central tower(keep) of this town
|
/// Returns damage range for central tower(keep) of this town
|
||||||
TDmgRange getKeepDamageRange() const;
|
DamageRange getKeepDamageRange() const;
|
||||||
|
|
||||||
const CTown * getTown() const ;
|
const CTown * getTown() const ;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user