mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-24 08:32:34 +02:00
* fixed crash on calculating dmg dealt by stack under Curse
* fixed crash on sea battles (obstacles data got corrupted during conversion) * fixed crash when StupidAI had a catapult * minor fixes and refactorings (typename for bonus list under shared ptr)
This commit is contained in:
parent
bb1bdcb0a7
commit
9621cbcaa7
@ -250,6 +250,12 @@ BattleAction CStupidAI::goTowards(const CStack * stack, THex hex)
|
||||
dists = cb->battleGetDistances(stack, realDest, predecessors);
|
||||
std::vector<THex> avHexes = cb->battleGetAvailableHexes(stack, false);
|
||||
|
||||
if(!avHexes.size())
|
||||
{
|
||||
print("goTowards: Stack cannot move! That's " + stack->nodeName());
|
||||
return BattleAction::makeDefend(stack);
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
assert(realDest.isValid());
|
||||
|
@ -3179,7 +3179,7 @@ void CBattleInterface::spellCast( const BattleSpellCast * sc )
|
||||
boost::algorithm::replace_first(text, "%s", curInt->cb->battleGetStackByID(*sc->affectedCres.begin())->type->nameSing);
|
||||
}
|
||||
//The %s shrivel with age, and lose %d hit points."
|
||||
boost::shared_ptr<BonusList> bl = curInt->cb->battleGetStackByID(*sc->affectedCres.begin(), false)->getBonuses(Selector::type(Bonus::STACK_HEALTH));
|
||||
TBonusListPtr bl = curInt->cb->battleGetStackByID(*sc->affectedCres.begin(), false)->getBonuses(Selector::type(Bonus::STACK_HEALTH));
|
||||
bl->remove_if(Selector::source(Bonus::SPELL_EFFECT, 75));
|
||||
boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>(bl->totalValue()/2));
|
||||
}
|
||||
@ -3542,7 +3542,7 @@ void CBattleInterface::showAliveStack(const CStack *stack, SDL_Surface * to)
|
||||
int yAdd = 260 + ((stack->attackerOwned || moveInside) ? 0 : -15);
|
||||
//blitting amount background box
|
||||
SDL_Surface *amountBG = NULL;
|
||||
boost::shared_ptr<BonusList> spellEffects = stack->getSpellBonuses();
|
||||
TBonusListPtr spellEffects = stack->getSpellBonuses();
|
||||
if(!spellEffects->size())
|
||||
{
|
||||
amountBG = amountNormal;
|
||||
|
@ -44,11 +44,11 @@
|
||||
extern SDL_Surface * screen;
|
||||
using namespace boost::assign;
|
||||
|
||||
const boost::shared_ptr<BonusList> CHeroWithMaybePickedArtifact::getAllBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root /*= NULL*/, const std::string &cachingStr /*= ""*/) const
|
||||
const TBonusListPtr CHeroWithMaybePickedArtifact::getAllBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root /*= NULL*/, const std::string &cachingStr /*= ""*/) const
|
||||
{
|
||||
boost::shared_ptr<BonusList> out(new BonusList);
|
||||
boost::shared_ptr<BonusList> heroBonuses = hero->getAllBonuses(selector, limit, hero);
|
||||
boost::shared_ptr<BonusList> bonusesFromPickedUpArtifact;
|
||||
TBonusListPtr out(new BonusList);
|
||||
TBonusListPtr heroBonuses = hero->getAllBonuses(selector, limit, hero);
|
||||
TBonusListPtr bonusesFromPickedUpArtifact;
|
||||
|
||||
CArtifactsOfHero::SCommonPart *cp = cww->artSets.size() ? cww->artSets.front()->commonInfo : NULL;
|
||||
if(cp && cp->src.art && cp->src.valid() && cp->src.AOH && cp->src.AOH->getHero() == hero)
|
||||
@ -56,7 +56,7 @@ const boost::shared_ptr<BonusList> CHeroWithMaybePickedArtifact::getAllBonuses(c
|
||||
bonusesFromPickedUpArtifact = cp->src.art->getAllBonuses(selector, limit, hero);
|
||||
}
|
||||
else
|
||||
bonusesFromPickedUpArtifact = boost::shared_ptr<BonusList>(new BonusList);
|
||||
bonusesFromPickedUpArtifact = TBonusListPtr(new BonusList);
|
||||
|
||||
BOOST_FOREACH(Bonus *b, *bonusesFromPickedUpArtifact)
|
||||
*heroBonuses -= b;
|
||||
|
@ -46,7 +46,7 @@ public:
|
||||
CWindowWithArtifacts *cww;
|
||||
|
||||
CHeroWithMaybePickedArtifact(CWindowWithArtifacts *Cww, const CGHeroInstance *Hero);
|
||||
const boost::shared_ptr<BonusList> getAllBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = NULL, const std::string &cachingStr = "") const OVERRIDE;
|
||||
const TBonusListPtr getAllBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = NULL, const std::string &cachingStr = "") const OVERRIDE;
|
||||
};
|
||||
|
||||
class CHeroWindow: public CWindowWithGarrison, public CWindowWithArtifacts
|
||||
|
@ -17,7 +17,7 @@
|
||||
{ "id": 56, "defname": "OBBHS02.DEF", "blockmap": "XXLNX", "terrains": "1100000000000000000000100", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 57, "defname": "OBBHS03.DEF", "blockmap": "LXXX", "terrains": "1111100000000000000000100", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 91, "defname": "OBBHS04.DEF", "blockmap": "XXLNXX", "terrains": "1100000000000000000000000", "shift_x": -40, "shift_y": -20 },
|
||||
{ "id": 58, "defname": "OBBHS11A.DEF", "blockmap": "XXXLNXXX", "terrains": "100000000000000000000000", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 58, "defname": "OBBHS11A.DEF", "blockmap": "XXXLNXXX", "terrains": "1100000000000000000000000", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 59, "defname": "OBBHS12B.DEF", "blockmap": "NXXLNXX", "terrains": "1100000000000000000000000", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 60, "defname": "OBBHS14B.DEF", "blockmap": "NXLNXX", "terrains": "1111100000000000000000100", "shift_x": 36, "shift_y": 0 },
|
||||
{ "id": 92, "defname": "OBBHS16A.DEF", "blockmap": "XLNXX", "terrains": "1100000000000000000000000", "shift_x": -8, "shift_y": -28 },
|
||||
@ -34,7 +34,7 @@
|
||||
{ "id": 8, "defname": "OBDRK03.DEF", "blockmap": "X", "terrains": "1111110000000000000000100", "shift_x": -8, "shift_y": -8 },
|
||||
{ "id": 9, "defname": "OBDRK04.DEF", "blockmap": "LXX", "terrains": "1111110000000000000000100", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 10, "defname": "OBDSH01.DEF", "blockmap": "LXX", "terrains": "1111110000000000000000100", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 93, "defname": "OBDSM01.DEF", "blockmap": "NNXXXLNNXXXLNNXX", "terrains": "00000000000000000000000", "shift_x": 36, "shift_y": 0 },
|
||||
{ "id": 93, "defname": "OBDSM01.DEF", "blockmap": "NNXXXLNNXXXLNNXX", "terrains": "1100000000000000000000000", "shift_x": 36, "shift_y": 0 },
|
||||
{ "id": 17, "defname": "OBDSM02.DEF", "blockmap": "XXLNX", "terrains": "1111100000000000000000100", "shift_x": -9, "shift_y": -2 },
|
||||
{ "id": 18, "defname": "OBDSS17.DEF", "blockmap": "XXLNXXX", "terrains": "1111100000000000000000100", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 11, "defname": "OBDTF03.DEF", "blockmap": "XX", "terrains": "1111100000000000000001100", "shift_x": 14, "shift_y": 0 },
|
||||
@ -46,17 +46,17 @@
|
||||
{ "id": 67, "defname": "OBEFS01.DEF", "blockmap": "XX", "terrains": "0000000000000000000100000", "shift_x": 14, "shift_y": 0 },
|
||||
{ "id": 68, "defname": "OBEFS02.DEF", "blockmap": "NXLXXX", "terrains": "0000000000000000000100000", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 69, "defname": "OBEFS03.DEF", "blockmap": "LNXX", "terrains": "0000000000000000000100000", "shift_x": 0, "shift_y": 0 },
|
||||
{ "id": 70, "defname": "OBEFS04.DEF", "blockmap": "NNXXXLNXXX", "terrains": "000000000000000000100000", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 70, "defname": "OBEFS04.DEF", "blockmap": "NNXXXLNXXX", "terrains": "0000000000000000000100000", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 79, "defname": "OBFFS00.DEF", "blockmap": "X", "terrains": "0000000000000100000000000", "shift_x": 14, "shift_y": 0 },
|
||||
{ "id": 80, "defname": "OBFFS01.DEF", "blockmap": "XX", "terrains": "0000000000000100000000000", "shift_x": 14, "shift_y": 0 },
|
||||
{ "id": 81, "defname": "OBFFS02.DEF", "blockmap": "NXLXXX", "terrains": "0000000000000100000000000", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 82, "defname": "OBFFS03.DEF", "blockmap": "XXLNXXX", "terrains": "0000000000000100000000000", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 83, "defname": "OBFFS04.DEF", "blockmap": "XXXLXXXX", "terrains": "000000000000100000000000", "shift_x": -8, "shift_y": -42 },
|
||||
{ "id": 83, "defname": "OBFFS04.DEF", "blockmap": "XXXLXXXX", "terrains": "0000000000000100000000000", "shift_x": -8, "shift_y": -42 },
|
||||
{ "id": 19, "defname": "OBGLG01.DEF", "blockmap": "XX", "terrains": "0000000000001000000000000", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 94, "defname": "OBGRK01.DEF", "blockmap": "XX", "terrains": "0000000000001000000000000", "shift_x": 14, "shift_y": -42 },
|
||||
{ "id": 23, "defname": "OBGRK02.DEF", "blockmap": "XX", "terrains": "0000000000001000000000000", "shift_x": 14, "shift_y": 0 },
|
||||
{ "id": 20, "defname": "OBGRS02.DEF", "blockmap": "NXX", "terrains": "0000000000001000000000000", "shift_x": 14, "shift_y": 0 },
|
||||
{ "id": 22, "defname": "OBGRS01.DEF", "blockmap": "XXXXLNXXXX", "terrains": "000011010001000000000000", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 22, "defname": "OBGRS01.DEF", "blockmap": "XXXXLNXXXX", "terrains": "0000011010001000000000000", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 35, "defname": "OBGRS03.DEF", "blockmap": "XXXXXXX", "terrains": "1111111010000000000000100", "shift_x": 0, "shift_y": 0 },
|
||||
{ "id": 21, "defname": "OBGST01.DEF", "blockmap": "X", "terrains": "1111111010000000000000100", "shift_x": 14, "shift_y": 0 },
|
||||
{ "id": 61, "defname": "OBHGS00.DEF", "blockmap": "X", "terrains": "0000000000000000010000000", "shift_x": 14, "shift_y": 0 },
|
||||
@ -67,23 +67,23 @@
|
||||
{ "id": 75, "defname": "OBLPS00.DEF", "blockmap": "X", "terrains": "0000000000000000100000000", "shift_x": 14, "shift_y": 0 },
|
||||
{ "id": 76, "defname": "OBLPS01.DEF", "blockmap": "XX", "terrains": "0000000000000000100000000", "shift_x": 14, "shift_y": 0 },
|
||||
{ "id": 77, "defname": "OBLPS02.DEF", "blockmap": "NXXLNX", "terrains": "0000000000000000100000000", "shift_x": 36, "shift_y": 0 },
|
||||
{ "id": 78, "defname": "OBLPS03.DEF", "blockmap": "XXXXLNXXXX", "terrains": "000000000000000100000000", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 78, "defname": "OBLPS03.DEF", "blockmap": "XXXXLNXXXX", "terrains": "0000000000000000100000000", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 48, "defname": "OBLVS01.DEF", "blockmap": "XXLNNX", "terrains": "0000000100000000000000000", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 49, "defname": "OBLVS02.DEF", "blockmap": "XXXLXXX", "terrains": "0000000100000000000000000", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 50, "defname": "OBLVS03.DEF", "blockmap": "XXXXLNXXX", "terrains": "000000100000000000000000", "shift_x": -30, "shift_y": 0 },
|
||||
{ "id": 50, "defname": "OBLVS03.DEF", "blockmap": "XXXXLNXXX", "terrains": "0000000100000000000000000", "shift_x": -30, "shift_y": 0 },
|
||||
{ "id": 51, "defname": "OBLVS04.DEF", "blockmap": "XXX", "terrains": "0000000100000000000000000", "shift_x": 14, "shift_y": -42 },
|
||||
{ "id": 52, "defname": "OBLVS09.DEF", "blockmap": "XXLNXXLNNXX", "terrains": "000000100000000000000000", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 53, "defname": "OBLVS17.DEF", "blockmap": "NNXLXXXX", "terrains": "000000100000000000000000", "shift_x": -30, "shift_y": 0 },
|
||||
{ "id": 54, "defname": "OBLVS22.DEF", "blockmap": "XXXLXXXX", "terrains": "000000100000000000000000", "shift_x": -30, "shift_y": 0 },
|
||||
{ "id": 52, "defname": "OBLVS09.DEF", "blockmap": "XXLNXXLNNXX", "terrains": "0000000100000000000000000", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 53, "defname": "OBLVS17.DEF", "blockmap": "NNXLXXXX", "terrains": "0000000100000000000000000", "shift_x": -30, "shift_y": 0 },
|
||||
{ "id": 54, "defname": "OBLVS22.DEF", "blockmap": "XXXLXXXX", "terrains": "0000000100000000000000000", "shift_x": -30, "shift_y": 0 },
|
||||
{ "id": 88, "defname": "OBMCS00.DEF", "blockmap": "X", "terrains": "0000000000000001000000000", "shift_x": 14, "shift_y": 0 },
|
||||
{ "id": 89, "defname": "OBMCS01.DEF", "blockmap": "XLNX", "terrains": "0000000000000001000000000", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 90, "defname": "OBMCS02.DEF", "blockmap": "NXXLXX", "terrains": "0000000000000001000000000", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 41, "defname": "OBRGS01.DEF", "blockmap": "XLXX", "terrains": "1111100000000000000001100", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 40, "defname": "OBRGS02.DEF", "blockmap": "NXXLNXXX", "terrains": "111100000000000000001100", "shift_x": 14, "shift_y": 0 },
|
||||
{ "id": 40, "defname": "OBRGS02.DEF", "blockmap": "NXXLNXXX", "terrains": "1111100000000000000001100", "shift_x": 14, "shift_y": 0 },
|
||||
{ "id": 42, "defname": "OBRGS03.DEF", "blockmap": "XXLNX", "terrains": "1111100000000000000001100", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 43, "defname": "OBRGS04.DEF", "blockmap": "XXLX", "terrains": "1111100000000000000001100", "shift_x": -30, "shift_y": 0 },
|
||||
{ "id": 44, "defname": "OBRGS05.DEF", "blockmap": "NXLXX", "terrains": "1111100000000000000001100", "shift_x": -30, "shift_y": 0 },
|
||||
{ "id": 16, "defname": "OBRGS06.DEF", "blockmap": "NXXXXXXLNNNNNNNXLNNNNNNNNX", "terrains": "11100000000000000001100", "shift_x": -30, "shift_y": -30 },
|
||||
{ "id": 16, "defname": "OBRGS06.DEF", "blockmap": "NXXXXXXLNNNNNNNXLNNNNNNNNX", "terrains": "1111100000000000000001100", "shift_x": -30, "shift_y": -30 },
|
||||
{ "id": 84, "defname": "OBRLS00.DEF", "blockmap": "X", "terrains": "0000000000000010000000000", "shift_x": 14, "shift_y": 0 },
|
||||
{ "id": 85, "defname": "OBRLS01.DEF", "blockmap": "XX", "terrains": "0000000000000010000000000", "shift_x": 14, "shift_y": 0 },
|
||||
{ "id": 86, "defname": "OBRLS02.DEF", "blockmap": "XXX", "terrains": "0000000000000010000000000", "shift_x": 14, "shift_y": 0 },
|
||||
@ -98,16 +98,16 @@
|
||||
{ "id": 29, "defname": "OBSNS06.DEF", "blockmap": "LNXX", "terrains": "0000000001100000000000000", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 30, "defname": "OBSNS07.DEF", "blockmap": "XX", "terrains": "0000000001100000000000000", "shift_x": 14, "shift_y": 0 },
|
||||
{ "id": 31, "defname": "OBSNS08.DEF", "blockmap": "LNXXX", "terrains": "0000000001100000000000000", "shift_x": 36, "shift_y": 0 },
|
||||
{ "id": 32, "defname": "OBSNS09.DEF", "blockmap": "XXXXLNNXXXX", "terrains": "000000001100000000000000", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 33, "defname": "OBSNS10.DEF", "blockmap": "XXLNXLNXXLNNXXX", "terrains": "000000001100000000000000", "shift_x": -30, "shift_y": -30 },
|
||||
{ "id": 32, "defname": "OBSNS09.DEF", "blockmap": "XXXXLNNXXXX", "terrains": "0000000001100000000000000", "shift_x": -8, "shift_y": 0 },
|
||||
{ "id": 33, "defname": "OBSNS10.DEF", "blockmap": "XXLNXLNXXLNNXXX", "terrains": "0000000001100000000000000", "shift_x": -30, "shift_y": -30 },
|
||||
{ "id": 45, "defname": "OBSUS01.DEF", "blockmap": "XXLXXX", "terrains": "0000000000010000000000000", "shift_x": -8, "shift_y": -42 },
|
||||
{ "id": 46, "defname": "OBSUS02.DEF", "blockmap": "XXX", "terrains": "0000000000010000000000000", "shift_x": 14, "shift_y": -42 },
|
||||
{ "id": 47, "defname": "OBSUS11B.DEF", "blockmap": "XXXLXXXX", "terrains": "000000000010000000000000", "shift_x": -9, "shift_y": -43 },
|
||||
{ "id": 47, "defname": "OBSUS11B.DEF", "blockmap": "XXXLXXXX", "terrains": "0000000000010000000000000", "shift_x": -9, "shift_y": -43 },
|
||||
{ "id": 34, "defname": "OBSWS01.DEF", "blockmap": "LNX", "terrains": "0000000000001000000000000", "shift_x": 36, "shift_y": 0 },
|
||||
{ "id": 95, "defname": "OBSWS02.DEF", "blockmap": "XXXXXXX", "terrains": "0000000000001000000000000", "shift_x": -8, "shift_y": -42 },
|
||||
{ "id": 36, "defname": "OBSWS03.DEF", "blockmap": "XX", "terrains": "0000000000001000000000000", "shift_x": 14, "shift_y": 0 },
|
||||
{ "id": 37, "defname": "OBSWS04.DEF", "blockmap": "XXX", "terrains": "0000000000001000000000000", "shift_x": 14, "shift_y": 0 },
|
||||
{ "id": 38, "defname": "OBSWS11B.DEF", "blockmap": "XXXXLXXXX", "terrains": "000000000001000000000000", "shift_x": -30, "shift_y": -40 },
|
||||
{ "id": 38, "defname": "OBSWS11B.DEF", "blockmap": "XXXXLXXXX", "terrains": "0000000000001000000000000", "shift_x": -30, "shift_y": -40 },
|
||||
{ "id": 39, "defname": "OBSWS13A.DEF", "blockmap": "XXXXLXX", "terrains": "0000000000001000000000000", "shift_x": 14, "shift_y": 0 }
|
||||
]
|
||||
}
|
||||
|
@ -592,9 +592,15 @@ TDmgRange BattleInfo::calculateDmgRange( const CStack* attacker, const CStack* d
|
||||
{
|
||||
multBonus *= float(defender->valOfBonuses(Bonus::GENERAL_DAMAGE_REDUCTION, 1)) / 100.0f;
|
||||
}
|
||||
if(attacker->getEffect(42)) //curse handling (partial, the rest is below)
|
||||
|
||||
TBonusListPtr curseEffects = attacker->getBonuses(Selector::type(Bonus::ALWAYS_MINIMUM_DAMAGE)); //attacker->getEffect(42);
|
||||
TBonusListPtr blessEffects = attacker->getBonuses(Selector::type(Bonus::ALWAYS_MAXIMUM_DAMAGE)); //attacker->getEffect(43);
|
||||
int curseBlessAdditiveModifier = blessEffects->totalValue() - curseEffects->totalValue();
|
||||
double curseMultiplicativePenalty = curseEffects->size() ? (*std::max_element(curseEffects->begin(), curseEffects->end(), &Bonus::compareByAdditionalInfo))->additionalInfo : 0;
|
||||
|
||||
if(curseMultiplicativePenalty) //curse handling (partial, the rest is below)
|
||||
{
|
||||
multBonus *= 0.8f * float(VLC->spellh->spells[42]->powers[attacker->getEffect(42)->val]); //the second factor is 1 or 0
|
||||
multBonus *= 1.0 - curseMultiplicativePenalty/100;
|
||||
}
|
||||
|
||||
class HLP
|
||||
@ -633,14 +639,14 @@ TDmgRange BattleInfo::calculateDmgRange( const CStack* attacker, const CStack* d
|
||||
|
||||
TDmgRange returnedVal;
|
||||
|
||||
if(attacker->getEffect(42)) //curse handling (rest)
|
||||
if(curseEffects->size()) //curse handling (rest)
|
||||
{
|
||||
minDmg -= VLC->spellh->spells[42]->powers[attacker->getEffect(42)->val];
|
||||
minDmg += curseBlessAdditiveModifier;
|
||||
returnedVal = std::make_pair(int(minDmg), int(minDmg));
|
||||
}
|
||||
else if(attacker->getEffect(41)) //bless handling
|
||||
else if(blessEffects->size()) //bless handling
|
||||
{
|
||||
maxDmg += VLC->spellh->spells[41]->powers[attacker->getEffect(41)->val];
|
||||
maxDmg += curseBlessAdditiveModifier;
|
||||
returnedVal = std::make_pair(int(maxDmg), int(maxDmg));
|
||||
}
|
||||
else
|
||||
@ -1911,7 +1917,7 @@ SpellCasting::ESpellCastProblem BattleInfo::battleIsImmune(const CGHeroInstance
|
||||
break;
|
||||
case 78: //dispel helpful spells
|
||||
{
|
||||
boost::shared_ptr<BonusList> spellBon = subject->getSpellBonuses();
|
||||
TBonusListPtr spellBon = subject->getSpellBonuses();
|
||||
bool hasPositiveSpell = false;
|
||||
BOOST_FOREACH(const Bonus * b, *spellBon)
|
||||
{
|
||||
@ -1955,7 +1961,7 @@ SpellCasting::ESpellCastProblem BattleInfo::battleIsImmune(const CGHeroInstance
|
||||
return SpellCasting::STACK_IMMUNE_TO_SPELL;
|
||||
}
|
||||
|
||||
boost::shared_ptr<BonusList> immunities = subject->getBonuses(Selector::type(Bonus::LEVEL_SPELL_IMMUNITY));
|
||||
TBonusListPtr immunities = subject->getBonuses(Selector::type(Bonus::LEVEL_SPELL_IMMUNITY));
|
||||
if(subject->hasBonusOfType(Bonus::NEGATE_ALL_NATURAL_IMMUNITIES))
|
||||
{
|
||||
//std::remove_if(immunities->begin(), immunities->end(), NegateRemover);
|
||||
@ -2199,11 +2205,13 @@ void CStack::stackEffectToFeature(std::vector<Bonus> & sf, const Bonus & sse)
|
||||
sf.back().valType = Bonus::INDEPENDENT_MAX;
|
||||
sf.back().sid = sse.sid;
|
||||
case 41: //bless
|
||||
sf.push_back(featureGenerator(Bonus::ALWAYS_MAXIMUM_DAMAGE, -1, power, sse.turnsRemain));
|
||||
sf.push_back(featureGenerator(Bonus::ALWAYS_MAXIMUM_DAMAGE, -1, power, sse.turnsRemain));
|
||||
sf.back().valType = Bonus::INDEPENDENT_MAX;
|
||||
sf.back().sid = sse.sid;
|
||||
break;
|
||||
case 42: //curse
|
||||
sf.push_back(featureGenerator(Bonus::ALWAYS_MINIMUM_DAMAGE, -1, -1 * power, sse.turnsRemain, sse.val >= 2 ? 20 : 0));
|
||||
sf.push_back(featureGenerator(Bonus::ALWAYS_MINIMUM_DAMAGE, -1, power, sse.turnsRemain, sse.val >= 2 ? 20 : 0));
|
||||
sf.back().valType = Bonus::INDEPENDENT_MAX;
|
||||
sf.back().sid = sse.sid;
|
||||
break;
|
||||
case 43: //bloodlust
|
||||
@ -2434,7 +2442,7 @@ std::vector<si32> CStack::activeSpells() const
|
||||
{
|
||||
std::vector<si32> ret;
|
||||
|
||||
boost::shared_ptr<BonusList> spellEffects = getSpellBonuses();
|
||||
TBonusListPtr spellEffects = getSpellBonuses();
|
||||
BOOST_FOREACH(const Bonus *it, *spellEffects)
|
||||
{
|
||||
if (!vstd::contains(ret, it->sid)) //do not duplicate spells with multiple effects
|
||||
|
@ -1678,7 +1678,7 @@ UpgradeInfo CGameState::getUpgradeInfo(const CStackInstance &stack)
|
||||
t = static_cast<const CGTownInstance *>(stack.armyObj);
|
||||
else if(h)
|
||||
{ //hero speciality
|
||||
boost::shared_ptr<BonusList> lista = h->speciality.getBonuses(Selector::typeSubtype(Bonus::SPECIAL_UPGRADE, base->idNumber));
|
||||
TBonusListPtr lista = h->speciality.getBonuses(Selector::typeSubtype(Bonus::SPECIAL_UPGRADE, base->idNumber));
|
||||
BOOST_FOREACH(const Bonus *it, *lista)
|
||||
{
|
||||
ui16 nid = it->additionalInfo;
|
||||
|
@ -153,6 +153,7 @@ void CHeroHandler::loadObstacles()
|
||||
obi.defName = obs["defname"].String();
|
||||
obi.blockmap = obs["blockmap"].String();
|
||||
obi.allowedTerrains = obs["terrains"].String();
|
||||
assert(obi.allowedTerrains.size() >= 25);
|
||||
obi.posShift.first = obs["shift_x"].Float();
|
||||
obi.posShift.second = obs["shift_y"].Float();
|
||||
|
||||
|
@ -1877,12 +1877,12 @@ GrowthInfo CGTownInstance::getGrowthInfo(int level) const
|
||||
ret.entries.push_back(GrowthInfo::Entry(VLC->generaltexth->allTexts[591], dwellingBonus));// \nExternal dwellings %+d
|
||||
|
||||
//other *-of-legion-like bonuses (%d to growth cumulative with grail)
|
||||
boost::shared_ptr<BonusList> bonuses = getBonuses(Selector::type(Bonus::CREATURE_GROWTH) && Selector::subtype(level));
|
||||
TBonusListPtr bonuses = getBonuses(Selector::type(Bonus::CREATURE_GROWTH) && Selector::subtype(level));
|
||||
BOOST_FOREACH(const Bonus *b, *bonuses)
|
||||
ret.entries.push_back(GrowthInfo::Entry(b->Description() + " %+d", b->val));
|
||||
|
||||
//statue-of-legion-like bonus: % to base+castle
|
||||
boost::shared_ptr<BonusList> bonuses2 = getBonuses(Selector::type(Bonus::CREATURE_GROWTH_PERCENT));
|
||||
TBonusListPtr bonuses2 = getBonuses(Selector::type(Bonus::CREATURE_GROWTH_PERCENT));
|
||||
BOOST_FOREACH(const Bonus *b, *bonuses2)
|
||||
ret.entries.push_back(GrowthInfo::Entry(b->Description() + " %+d", b->val * (base + castleBonus) / 100));
|
||||
|
||||
@ -2239,7 +2239,7 @@ void CGTownInstance::deserializationFix()
|
||||
|
||||
void CGTownInstance::recreateBuildingsBonuses()
|
||||
{
|
||||
boost::shared_ptr<BonusList> bl(new BonusList);
|
||||
TBonusListPtr bl(new BonusList);
|
||||
getExportedBonusList().getBonuses(bl, Selector::sourceType(Bonus::TOWN_STRUCTURE));
|
||||
BOOST_FOREACH(Bonus *b, *bl)
|
||||
removeBonus(b);
|
||||
|
@ -147,7 +147,7 @@ void BonusList::getModifiersWDescr(TModDescr &out) const
|
||||
}
|
||||
}
|
||||
|
||||
void BonusList::getBonuses(boost::shared_ptr<BonusList> out, const CSelector &selector) const
|
||||
void BonusList::getBonuses(TBonusListPtr out, const CSelector &selector) const
|
||||
{
|
||||
// BOOST_FOREACH(Bonus *i, *this)
|
||||
// if(selector(i) && i->effectRange == Bonus::NO_LIMIT)
|
||||
@ -156,7 +156,7 @@ void BonusList::getBonuses(boost::shared_ptr<BonusList> out, const CSelector &se
|
||||
getBonuses(out, selector, 0);
|
||||
}
|
||||
|
||||
void BonusList::getBonuses(boost::shared_ptr<BonusList> out, const CSelector &selector, const CSelector &limit, const bool caching /*= false*/) const
|
||||
void BonusList::getBonuses(TBonusListPtr out, const CSelector &selector, const CSelector &limit, const bool caching /*= false*/) const
|
||||
{
|
||||
for (unsigned int i = 0; i < bonuses.size(); i++)
|
||||
{
|
||||
@ -170,7 +170,7 @@ void BonusList::getBonuses(boost::shared_ptr<BonusList> out, const CSelector &se
|
||||
|
||||
int BonusList::valOfBonuses(const CSelector &select) const
|
||||
{
|
||||
boost::shared_ptr<BonusList> ret(new BonusList());
|
||||
TBonusListPtr ret(new BonusList());
|
||||
CSelector limit = 0;
|
||||
getBonuses(ret, select, limit, false);
|
||||
ret->eliminateDuplicates();
|
||||
@ -260,7 +260,7 @@ int IBonusBearer::valOfBonuses(Bonus::BonusType type, int subtype /*= -1*/) cons
|
||||
int IBonusBearer::valOfBonuses(const CSelector &selector, const std::string &cachingStr) const
|
||||
{
|
||||
CSelector limit = 0;
|
||||
boost::shared_ptr<BonusList> hlp = getAllBonuses(selector, limit, NULL, cachingStr);
|
||||
TBonusListPtr hlp = getAllBonuses(selector, limit, NULL, cachingStr);
|
||||
return hlp->totalValue();
|
||||
}
|
||||
bool IBonusBearer::hasBonus(const CSelector &selector, const std::string &cachingStr /*= ""*/) const
|
||||
@ -303,12 +303,12 @@ int IBonusBearer::getBonusesCount(const CSelector &selector, const std::string &
|
||||
return getBonuses(selector, cachingStr)->size();
|
||||
}
|
||||
|
||||
const boost::shared_ptr<BonusList> IBonusBearer::getBonuses(const CSelector &selector, const std::string &cachingStr /*= ""*/) const
|
||||
const TBonusListPtr IBonusBearer::getBonuses(const CSelector &selector, const std::string &cachingStr /*= ""*/) const
|
||||
{
|
||||
return getAllBonuses(selector, 0, NULL, cachingStr);
|
||||
}
|
||||
|
||||
const boost::shared_ptr<BonusList> IBonusBearer::getBonuses(const CSelector &selector, const CSelector &limit, const std::string &cachingStr /*= ""*/) const
|
||||
const TBonusListPtr IBonusBearer::getBonuses(const CSelector &selector, const CSelector &limit, const std::string &cachingStr /*= ""*/) const
|
||||
{
|
||||
return getAllBonuses(selector, limit, NULL, cachingStr);
|
||||
}
|
||||
@ -422,7 +422,7 @@ bool IBonusBearer::isLiving() const //TODO: theoreticaly there exists "LIVING" b
|
||||
return(!hasBonus(Selector::type(Bonus::UNDEAD) || Selector::type(Bonus::NON_LIVING), cachingStr.str()));
|
||||
}
|
||||
|
||||
const boost::shared_ptr<BonusList> IBonusBearer::getSpellBonuses() const
|
||||
const TBonusListPtr IBonusBearer::getSpellBonuses() const
|
||||
{
|
||||
std::stringstream cachingStr;
|
||||
cachingStr << "source_" << Bonus::SPELL_EFFECT;
|
||||
@ -468,7 +468,7 @@ void CBonusSystemNode::getParents(TNodes &out)
|
||||
}
|
||||
}
|
||||
|
||||
void CBonusSystemNode::getAllBonusesRec(boost::shared_ptr<BonusList> out, const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root /*= NULL*/, const bool caching /*= false*/) const
|
||||
void CBonusSystemNode::getAllBonusesRec(TBonusListPtr out, const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root /*= NULL*/, const bool caching /*= false*/) const
|
||||
{
|
||||
TCNodes lparents;
|
||||
getParents(lparents);
|
||||
@ -478,9 +478,9 @@ void CBonusSystemNode::getAllBonusesRec(boost::shared_ptr<BonusList> out, const
|
||||
bonuses.getBonuses(out, selector, limit, caching);
|
||||
}
|
||||
|
||||
const boost::shared_ptr<BonusList> CBonusSystemNode::getAllBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root /*= NULL*/, const std::string &cachingStr /*= ""*/) const
|
||||
const TBonusListPtr CBonusSystemNode::getAllBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root /*= NULL*/, const std::string &cachingStr /*= ""*/) const
|
||||
{
|
||||
boost::shared_ptr<BonusList> ret(new BonusList());
|
||||
TBonusListPtr ret(new BonusList());
|
||||
if (CBonusSystemNode::cachingEnabled)
|
||||
{
|
||||
// Exclusive access for one thread
|
||||
@ -503,7 +503,7 @@ const boost::shared_ptr<BonusList> CBonusSystemNode::getAllBonuses(const CSelect
|
||||
// pre-calculated bonus results. Limiters can't be cached so they have to be calculated.
|
||||
if (cachingStr != "")
|
||||
{
|
||||
std::map<std::string, boost::shared_ptr<BonusList> >::iterator it(cachedRequests.find(cachingStr));
|
||||
std::map<std::string, TBonusListPtr >::iterator it(cachedRequests.find(cachingStr));
|
||||
if (cachedRequests.size() > 0 && it != cachedRequests.end())
|
||||
{
|
||||
ret = it->second;
|
||||
@ -589,7 +589,7 @@ void CBonusSystemNode::detachFrom(CBonusSystemNode *parent)
|
||||
|
||||
void CBonusSystemNode::popBonuses(const CSelector &s)
|
||||
{
|
||||
boost::shared_ptr<BonusList> bl(new BonusList);
|
||||
TBonusListPtr bl(new BonusList);
|
||||
exportedBonuses.getBonuses(bl, s);
|
||||
BOOST_FOREACH(Bonus *b, *bl)
|
||||
removeBonus(b);
|
||||
|
@ -23,7 +23,9 @@ struct Bonus;
|
||||
class CBonusSystemNode;
|
||||
class ILimiter;
|
||||
class IPropagator;
|
||||
class BonusList;
|
||||
|
||||
typedef boost::shared_ptr<BonusList> TBonusListPtr;
|
||||
typedef std::vector<std::pair<int,std::string> > TModDescr; //modifiers values and their descriptions
|
||||
typedef std::set<CBonusSystemNode*> TNodes;
|
||||
typedef std::set<const CBonusSystemNode*> TCNodes;
|
||||
@ -139,7 +141,7 @@ namespace PrimarySkill
|
||||
BONUS_NAME(HYPNOTIZED) \
|
||||
BONUS_NAME(ADDITIONAL_RETALIATION) /*value - number of additional retaliations*/ \
|
||||
BONUS_NAME(MAGIC_MIRROR) /* value - chance of redirecting in %*/ \
|
||||
BONUS_NAME(ALWAYS_MINIMUM_DAMAGE) /*unit does its minimum damage from range; subtype: -1 - any attack, 0 - melee, 1 - ranged, value: additional damage, additional info - multiplicative anti-bonus for dmg in % [eg 20 means that creature will inflict 80% of normal dmg]*/ \
|
||||
BONUS_NAME(ALWAYS_MINIMUM_DAMAGE) /*unit does its minimum damage from range; subtype: -1 - any attack, 0 - melee, 1 - ranged, value: additional damage penalty (it'll subtracted from dmg), additional info - multiplicative anti-bonus for dmg in % [eg 20 means that creature will inflict 80% of normal minimal dmg]*/ \
|
||||
BONUS_NAME(ALWAYS_MAXIMUM_DAMAGE) /*eg. bless effect, subtype: -1 - any attack, 0 - melee, 1 - ranged, value: additional damage, additional info - multiplicative bonus for dmg in %*/ \
|
||||
BONUS_NAME(ATTACKS_NEAREST_CREATURE) /*while in berserk*/ \
|
||||
BONUS_NAME(IN_FRENZY) /*value - level*/ \
|
||||
@ -272,6 +274,10 @@ struct DLL_EXPORT Bonus
|
||||
h & duration & type & subtype & source & val & sid & description & additionalInfo & turnsRemain & valType & effectRange & limiter & propagator;
|
||||
}
|
||||
|
||||
static bool compareByAdditionalInfo(const Bonus *a, const Bonus *b)
|
||||
{
|
||||
return a->additionalInfo < b->additionalInfo;
|
||||
}
|
||||
static bool OneDay(const Bonus *hb)
|
||||
{
|
||||
return hb->duration & Bonus::ONE_DAY;
|
||||
@ -357,10 +363,10 @@ public:
|
||||
|
||||
// BonusList functions
|
||||
int totalValue() const; //subtype -> subtype of bonus, if -1 then any
|
||||
void getBonuses(boost::shared_ptr<BonusList> out, const CSelector &selector, const CSelector &limit, const bool caching = false) const;
|
||||
void getBonuses(TBonusListPtr out, const CSelector &selector, const CSelector &limit, const bool caching = false) const;
|
||||
void getModifiersWDescr(TModDescr &out) const;
|
||||
|
||||
void getBonuses(boost::shared_ptr<BonusList> out, const CSelector &selector) const;
|
||||
void getBonuses(TBonusListPtr out, const CSelector &selector) const;
|
||||
|
||||
//special find functions
|
||||
Bonus *getFirst(const CSelector &select);
|
||||
@ -398,6 +404,7 @@ public:
|
||||
friend inline std::vector<Bonus*>::iterator range_end(BonusList & x);
|
||||
};
|
||||
|
||||
|
||||
// Extensions for BOOST_FOREACH to enable iterating of BonusList objects
|
||||
// Don't touch/call this functions
|
||||
inline std::vector<Bonus*>::iterator range_begin(BonusList & x)
|
||||
@ -466,13 +473,13 @@ public:
|
||||
// * selector is predicate that tests if HeroBonus matches our criteria
|
||||
// * root is node on which call was made (NULL will be replaced with this)
|
||||
//interface
|
||||
virtual const boost::shared_ptr<BonusList> getAllBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = NULL, const std::string &cachingStr = "") const = 0;
|
||||
virtual const TBonusListPtr getAllBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = NULL, const std::string &cachingStr = "") const = 0;
|
||||
void getModifiersWDescr(TModDescr &out, const CSelector &selector, const std::string &cachingStr = "") const; //out: pairs<modifier value, modifier description>
|
||||
int getBonusesCount(const CSelector &selector, const std::string &cachingStr = "") const;
|
||||
int valOfBonuses(const CSelector &selector, const std::string &cachingStr = "") const;
|
||||
bool hasBonus(const CSelector &selector, const std::string &cachingStr = "") const;
|
||||
const boost::shared_ptr<BonusList> getBonuses(const CSelector &selector, const CSelector &limit, const std::string &cachingStr = "") const;
|
||||
const boost::shared_ptr<BonusList> getBonuses(const CSelector &selector, const std::string &cachingStr = "") const;
|
||||
const TBonusListPtr getBonuses(const CSelector &selector, const CSelector &limit, const std::string &cachingStr = "") const;
|
||||
const TBonusListPtr getBonuses(const CSelector &selector, const std::string &cachingStr = "") const;
|
||||
|
||||
//legacy interface
|
||||
int valOfBonuses(Bonus::BonusType type, const CSelector &selector) const;
|
||||
@ -495,7 +502,7 @@ public:
|
||||
|
||||
si32 manaLimit() const; //maximum mana value for this hero (basically 10*knowledge)
|
||||
int getPrimSkillLevel(int id) const; //0-attack, 1-defence, 2-spell power, 3-knowledge
|
||||
const boost::shared_ptr<BonusList> getSpellBonuses() const;
|
||||
const TBonusListPtr getSpellBonuses() const;
|
||||
};
|
||||
|
||||
class DLL_EXPORT CBonusSystemNode : public IBonusBearer
|
||||
@ -518,16 +525,16 @@ private:
|
||||
// Setting a value to cachingStr before getting any bonuses caches the result for later requests.
|
||||
// This string needs to be unique, that's why it has to be setted in the following manner:
|
||||
// [property key]_[value] => only for selector
|
||||
mutable std::map<std::string, boost::shared_ptr<BonusList> > cachedRequests;
|
||||
mutable std::map<std::string, TBonusListPtr > cachedRequests;
|
||||
|
||||
void getAllBonusesRec(boost::shared_ptr<BonusList> out, const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = NULL, const bool caching = false) const;
|
||||
void getAllBonusesRec(TBonusListPtr out, const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = NULL, const bool caching = false) const;
|
||||
|
||||
public:
|
||||
|
||||
explicit CBonusSystemNode();
|
||||
virtual ~CBonusSystemNode();
|
||||
|
||||
const boost::shared_ptr<BonusList> getAllBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = NULL, const std::string &cachingStr = "") const;
|
||||
const TBonusListPtr getAllBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = NULL, const std::string &cachingStr = "") const;
|
||||
void getParents(TCNodes &out) const; //retrieves list of parent nodes (nodes to inherit bonuses from),
|
||||
const Bonus *getBonus(const CSelector &selector) const;
|
||||
|
||||
|
@ -4370,7 +4370,7 @@ void CGameHandler::attackCasting(const BattleAttack & bat, Bonus::BonusType atta
|
||||
if(attacker->hasBonusOfType(attackMode))
|
||||
{
|
||||
std::set<ui32> spellsToCast;
|
||||
boost::shared_ptr<BonusList> spells = attacker->getBonuses(Selector::type(attackMode));
|
||||
TBonusListPtr spells = attacker->getBonuses(Selector::type(attackMode));
|
||||
BOOST_FOREACH(const Bonus *sf, *spells)
|
||||
{
|
||||
spellsToCast.insert (sf->subtype);
|
||||
@ -4391,7 +4391,7 @@ void CGameHandler::attackCasting(const BattleAttack & bat, Bonus::BonusType atta
|
||||
if(oneOfAttacked == NULL) //all attacked creatures have been killed
|
||||
return;
|
||||
int spellLevel = 0;
|
||||
boost::shared_ptr<BonusList> spellsByType = attacker->getBonuses(Selector::typeSubtype(attackMode, spellID));
|
||||
TBonusListPtr spellsByType = attacker->getBonuses(Selector::typeSubtype(attackMode, spellID));
|
||||
BOOST_FOREACH(const Bonus *sf, *spellsByType)
|
||||
{
|
||||
amax(spellLevel, sf->additionalInfo % 1000); //pick highest level
|
||||
@ -4452,7 +4452,7 @@ void CGameHandler::handleAfterAttackCasting( const BattleAttack & bat )
|
||||
}
|
||||
}
|
||||
int acidDamage = 0;
|
||||
boost::shared_ptr<BonusList> acidBreath = attacker->getBonuses(Selector::type(Bonus::ACID_BREATH));
|
||||
TBonusListPtr acidBreath = attacker->getBonuses(Selector::type(Bonus::ACID_BREATH));
|
||||
BOOST_FOREACH(const Bonus *b, *acidBreath)
|
||||
{
|
||||
if (b->additionalInfo > rand()%100)
|
||||
@ -4935,7 +4935,7 @@ void CGameHandler::runBattle()
|
||||
{
|
||||
if(gs->curB->heroes[i] && gs->curB->heroes[i]->hasBonusOfType(Bonus::OPENING_BATTLE_SPELL))
|
||||
{
|
||||
boost::shared_ptr<BonusList> bl = gs->curB->heroes[i]->getBonuses(Selector::type(Bonus::OPENING_BATTLE_SPELL));
|
||||
TBonusListPtr bl = gs->curB->heroes[i]->getBonuses(Selector::type(Bonus::OPENING_BATTLE_SPELL));
|
||||
BOOST_FOREACH (Bonus *b, *bl)
|
||||
{
|
||||
handleSpellCasting(b->subtype, 3, -1, 0, gs->curB->heroes[i]->tempOwner, NULL, gs->curB->heroes[1-i], b->val, SpellCasting::HERO_CASTING, NULL);
|
||||
|
Loading…
Reference in New Issue
Block a user