mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-24 03:47:18 +02:00
Bonuses now use pointers.
Things are very broken.
This commit is contained in:
parent
4d657eaf47
commit
cdf7b2b4d9
@ -1155,7 +1155,7 @@ void CCastleInterface::CCreaInfo::clickRight(tribool down, bool previousState)
|
||||
ch = ci->town->visitingHero;
|
||||
};
|
||||
if (bl.size())
|
||||
summ+=AddToString (CGI->arth->artifacts[bl.front().id]->Name()+" %+d", descr, bl.totalValue());
|
||||
summ+=AddToString (CGI->arth->artifacts[bl.front()->id]->Name()+" %+d", descr, bl.totalValue());
|
||||
|
||||
//TODO: player bonuses
|
||||
|
||||
|
@ -129,13 +129,13 @@ void GiveBonus::applyCl( CClient *cl )
|
||||
case HERO:
|
||||
{
|
||||
const CGHeroInstance *h = GS(cl)->getHero(id);
|
||||
INTERFACE_CALL_IF_PRESENT(h->tempOwner, heroBonusChanged, h, h->bonuses.back(),true);
|
||||
INTERFACE_CALL_IF_PRESENT(h->tempOwner, heroBonusChanged, h, *h->bonuses.back(),true);
|
||||
}
|
||||
break;
|
||||
case PLAYER:
|
||||
{
|
||||
const PlayerState *p = GS(cl)->getPlayer(id);
|
||||
INTERFACE_CALL_IF_PRESENT(id, playerBonusChanged, p->bonuses.back(), true);
|
||||
INTERFACE_CALL_IF_PRESENT(id, playerBonusChanged, *p->bonuses.back(), true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -183,8 +183,8 @@ int CArtifact::getArtClassSerial() const
|
||||
|
||||
void CScroll::Init()
|
||||
{
|
||||
bonuses.push_back (Bonus (Bonus::PERMANENT, Bonus::SPELL, Bonus::ARTIFACT, 1, id, spellid, Bonus::INDEPENDENT_MAX));
|
||||
//boost::algorithm::replace_first(description, "[spell name]", VLC->spellh->spells[spellid].name);
|
||||
// addNewBonus (Bonus (Bonus::PERMANENT, Bonus::SPELL, Bonus::ARTIFACT, 1, id, spellid, Bonus::INDEPENDENT_MAX));
|
||||
// //boost::algorithm::replace_first(description, "[spell name]", VLC->spellh->spells[spellid].name);
|
||||
}
|
||||
|
||||
CArtHandler::CArtHandler()
|
||||
@ -489,7 +489,7 @@ void CArtHandler::giveArtBonus( int aid, Bonus::BonusType type, int val, int sub
|
||||
added.limiter = limiter;
|
||||
if(type == Bonus::MORALE || Bonus::LUCK)
|
||||
added.description = "\n" + artifacts[aid]->Name() + (val > 0 ? " +" : " ") + boost::lexical_cast<std::string>(val);
|
||||
artifacts[aid]->bonuses.push_back(added);
|
||||
artifacts[aid]->addNewBonus(added);
|
||||
}
|
||||
|
||||
void CArtHandler::addBonuses()
|
||||
|
@ -78,17 +78,17 @@ bool CCreature::isDoubleWide() const
|
||||
|
||||
bool CCreature::isFlying() const
|
||||
{
|
||||
return vstd::contains(bonuses, Bonus::FLYING);
|
||||
return hasBonusOfType(Bonus::FLYING);
|
||||
}
|
||||
|
||||
bool CCreature::isShooting() const
|
||||
{
|
||||
return vstd::contains(bonuses, Bonus::SHOOTER);
|
||||
return hasBonusOfType(Bonus::SHOOTER);
|
||||
}
|
||||
|
||||
bool CCreature::isUndead() const
|
||||
{
|
||||
return vstd::contains(bonuses, Bonus::UNDEAD);
|
||||
return hasBonusOfType(Bonus::UNDEAD);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -127,7 +127,7 @@ CCreature::CCreature()
|
||||
void CCreature::addBonus(int val, int type, int subtype /*= -1*/)
|
||||
{
|
||||
Bonus added(Bonus::PERMANENT, type, Bonus::CREATURE_ABILITY, val, idNumber, subtype, Bonus::BASE_NUMBER);
|
||||
bonuses.push_back(added);
|
||||
addNewBonus(added);
|
||||
}
|
||||
// void CCreature::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const
|
||||
// {
|
||||
@ -312,12 +312,12 @@ void CCreatureHandler::loadCreatures()
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "const_raises_morale"))
|
||||
{
|
||||
ncre.addBonus(+1, Bonus::MORALE);;
|
||||
ncre.bonuses.back().effectRange = Bonus::ONLY_ALLIED_ARMY;
|
||||
ncre.bonuses.back()->effectRange = Bonus::ONLY_ALLIED_ARMY;
|
||||
}
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "const_lowers_morale"))
|
||||
{
|
||||
ncre.addBonus(-1, Bonus::MORALE);;
|
||||
ncre.bonuses.back().effectRange = Bonus::ONLY_ENEMY_ARMY;
|
||||
ncre.bonuses.back()->effectRange = Bonus::ONLY_ENEMY_ARMY;
|
||||
}
|
||||
if(boost::algorithm::find_first(ncre.abilityRefs, "KING_1"))
|
||||
ncre.addBonus(0, Bonus::KING1);
|
||||
@ -380,13 +380,13 @@ void CCreatureHandler::loadCreatures()
|
||||
cre->doubleWide = true;
|
||||
else if(type == "ENEMY_MORALE_DECREASING")
|
||||
{
|
||||
cre->addBonus(-1, Bonus::MORALE);;
|
||||
cre->bonuses.back().effectRange = Bonus::ONLY_ENEMY_ARMY;
|
||||
cre->addBonus(-1, Bonus::MORALE);
|
||||
cre->bonuses.back()->effectRange = Bonus::ONLY_ENEMY_ARMY;
|
||||
}
|
||||
else if(type == "ENEMY_LUCK_DECREASING")
|
||||
{
|
||||
cre->addBonus(-1, Bonus::LUCK);;
|
||||
cre->bonuses.back().effectRange = Bonus::ONLY_ENEMY_ARMY;
|
||||
cre->addBonus(-1, Bonus::LUCK);
|
||||
cre->bonuses.back()->effectRange = Bonus::ONLY_ENEMY_ARMY;
|
||||
}
|
||||
else
|
||||
tlog1 << "Error: invalid type " << type << " in cr_abils.txt" << std::endl;
|
||||
@ -402,7 +402,7 @@ void CCreatureHandler::loadCreatures()
|
||||
nsf.duration = Bonus::ONE_BATTLE;
|
||||
nsf.turnsRemain = 0;
|
||||
|
||||
cre->bonuses += nsf;
|
||||
cre->addNewBonus(nsf);
|
||||
break;
|
||||
}
|
||||
case '-': //remove ability
|
||||
@ -424,7 +424,8 @@ void CCreatureHandler::loadCreatures()
|
||||
|
||||
Bonus::BonusType ecf = static_cast<Bonus::BonusType>(typeNo);
|
||||
|
||||
creatures[creatureID]->bonuses -= ecf;
|
||||
Bonus *b = creatures[creatureID]->getBonus(Selector::type(ecf));
|
||||
creatures[creatureID]->removeBonus(b);
|
||||
break;
|
||||
}
|
||||
case '0': //end reading
|
||||
|
@ -1016,15 +1016,15 @@ void CGHeroInstance::initObj()
|
||||
bonus.valType = Bonus::ADDITIVE_VALUE;
|
||||
|
||||
bonus.subtype = PrimarySkill::ATTACK;
|
||||
speciality.bonuses.push_back (bonus);
|
||||
speciality.addNewBonus(bonus);
|
||||
|
||||
bonus.subtype = PrimarySkill::DEFENSE;
|
||||
speciality.bonuses.push_back (bonus);
|
||||
speciality.addNewBonus(bonus);
|
||||
//values will be calculated later
|
||||
|
||||
bonus.type = Bonus::STACKS_SPEED;
|
||||
bonus.val = 1; //+1 speed
|
||||
speciality.bonuses.push_back (bonus);
|
||||
speciality.addNewBonus(bonus);
|
||||
}
|
||||
break;
|
||||
case 2://secondary skill
|
||||
@ -1033,7 +1033,7 @@ void CGHeroInstance::initObj()
|
||||
bonus.valType = Bonus::BASE_NUMBER; // to receive nonzero value
|
||||
bonus.subtype = it->subtype; //skill id
|
||||
bonus.val = it->val; //value per level, in percent
|
||||
speciality.bonuses.push_back (bonus);
|
||||
speciality.addNewBonus(bonus);
|
||||
switch (it->additionalinfo)
|
||||
{
|
||||
case 0: //normal
|
||||
@ -1044,12 +1044,12 @@ void CGHeroInstance::initObj()
|
||||
break;
|
||||
}
|
||||
bonus.type = Bonus::SECONDARY_SKILL_PREMY; //value will be calculated later
|
||||
speciality.bonuses.push_back(bonus);
|
||||
speciality.addNewBonus(bonus);
|
||||
break;
|
||||
case 3://spell damage bonus, level dependant but calculated elsehwere
|
||||
bonus.type = Bonus::SPECIAL_SPELL_LEV;
|
||||
bonus.subtype = it->subtype;
|
||||
speciality.bonuses.push_back (bonus);
|
||||
speciality.addNewBonus(bonus);
|
||||
break;
|
||||
case 4://creature stat boost
|
||||
switch (it->subtype)
|
||||
@ -1077,30 +1077,30 @@ void CGHeroInstance::initObj()
|
||||
}
|
||||
bonus.valType = Bonus::ADDITIVE_VALUE;
|
||||
bonus.limiter = new CCreatureTypeLimiter (*VLC->creh->creatures[it->additionalinfo], true);
|
||||
speciality.bonuses.push_back (bonus);
|
||||
speciality.addNewBonus(bonus);
|
||||
break;
|
||||
case 5://spell damage bonus in percent
|
||||
bonus.type = Bonus::SPECIFIC_SPELL_DAMAGE;
|
||||
bonus.valType = Bonus::BASE_NUMBER; // current spell system is screwed
|
||||
bonus.subtype = it->subtype; //spell id
|
||||
speciality.bonuses.push_back (bonus);
|
||||
speciality.addNewBonus(bonus);
|
||||
break;
|
||||
case 6://damage bonus for bless (Adela)
|
||||
bonus.type = Bonus::SPECIAL_BLESS_DAMAGE;
|
||||
bonus.subtype = it->subtype; //spell id if you ever wanted to use it otherwise
|
||||
bonus.additionalInfo = it->additionalinfo; //damage factor
|
||||
speciality.bonuses.push_back (bonus);
|
||||
speciality.addNewBonus(bonus);
|
||||
break;
|
||||
case 7://maxed mastery for spell
|
||||
bonus.type = Bonus::MAXED_SPELL;
|
||||
bonus.subtype = it->subtype; //spell i
|
||||
speciality.bonuses.push_back (bonus);
|
||||
speciality.addNewBonus(bonus);
|
||||
break;
|
||||
case 8://peculiar spells - enchantments
|
||||
bonus.type = Bonus::SPECIAL_PECULIAR_ENCHANT;
|
||||
bonus.subtype = it->subtype; //spell id
|
||||
bonus.additionalInfo = it->additionalinfo;//0, 1 for Coronius
|
||||
speciality.bonuses.push_back (bonus);
|
||||
speciality.addNewBonus(bonus);
|
||||
break;
|
||||
case 9://upgrade creatures
|
||||
{
|
||||
@ -1108,27 +1108,27 @@ void CGHeroInstance::initObj()
|
||||
bonus.type = Bonus::SPECIAL_UPGRADE;
|
||||
bonus.subtype = it->subtype; //base id
|
||||
bonus.additionalInfo = it->additionalinfo; //target id
|
||||
speciality.bonuses.push_back (bonus);
|
||||
speciality.addNewBonus(bonus);
|
||||
|
||||
for (std::set<ui32>::iterator i = (*creatures)[it->subtype]->upgrades.begin();
|
||||
i != (*creatures)[it->subtype]->upgrades.end(); i++)
|
||||
{
|
||||
bonus.subtype = *i; //propagate for regular upgrades of base creature
|
||||
speciality.bonuses.push_back (bonus);
|
||||
speciality.addNewBonus(bonus);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 10://resource generation
|
||||
bonus.type = Bonus::GENERATE_RESOURCE;
|
||||
bonus.subtype = it->subtype;
|
||||
speciality.bonuses.push_back (bonus);
|
||||
speciality.addNewBonus(bonus);
|
||||
break;
|
||||
case 11://starting skill with mastery (Adrienne)
|
||||
cb->changeSecSkill (id, it->val, it->additionalinfo); //simply give it and forget
|
||||
cb->changeSecSkill(id, it->val, it->additionalinfo); //simply give it and forget
|
||||
break;
|
||||
case 12://army speed
|
||||
bonus.type = Bonus::STACKS_SPEED;
|
||||
speciality.bonuses.push_back (bonus);
|
||||
speciality.addNewBonus(bonus);
|
||||
break;
|
||||
case 13://Dragon bonuses (Mutare)
|
||||
bonus.type = Bonus::PRIMARY_SKILL;
|
||||
@ -1143,7 +1143,7 @@ void CGHeroInstance::initObj()
|
||||
break;
|
||||
}
|
||||
bonus.limiter = new HasAnotherBonusLimiter(Bonus::DRAGON_NATURE);
|
||||
speciality.bonuses.push_back (bonus);
|
||||
speciality.addNewBonus(bonus);
|
||||
break;
|
||||
default:
|
||||
tlog2 << "Unexpected hero speciality " << type <<'\n';
|
||||
@ -1161,7 +1161,8 @@ void CGHeroInstance::UpdateSpeciality()
|
||||
if (speciality.growthsWithLevel)
|
||||
{
|
||||
std::vector<CCreature*>* creatures = &VLC->creh->creatures;
|
||||
for (std::list<Bonus>::iterator it = speciality.bonuses.begin(); it != speciality.bonuses.end(); it++)
|
||||
|
||||
BOOST_FOREACH(Bonus *it, speciality.bonuses)
|
||||
{
|
||||
switch (it->type)
|
||||
{
|
||||
@ -1248,7 +1249,7 @@ void CGHeroInstance::updateSkill(int which, int val)
|
||||
{
|
||||
Bonus bonus(Bonus::PERMANENT, Bonus::SECONDARY_SKILL_PREMY, id, skillVal, ID, which, Bonus::BASE_NUMBER);
|
||||
bonus.source = Bonus::SECONDARY_SKILL;
|
||||
bonuses.push_back (bonus);
|
||||
addNewBonus (bonus);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1505,7 +1506,7 @@ int CGHeroInstance::getSpellCost(const CSpell *sp) const
|
||||
|
||||
void CGHeroInstance::pushPrimSkill(int which, int val)
|
||||
{
|
||||
bonuses.push_back(Bonus(Bonus::PERMANENT, Bonus::PRIMARY_SKILL, Bonus::HERO_BASE_SKILL, val, id, which));
|
||||
addNewBonus(Bonus(Bonus::PERMANENT, Bonus::PRIMARY_SKILL, Bonus::HERO_BASE_SKILL, val, id, which));
|
||||
}
|
||||
|
||||
// void CGHeroInstance::getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root /*= NULL*/) const
|
||||
@ -2131,7 +2132,7 @@ void CGTownInstance::initObj()
|
||||
//add special bonuses from buildings
|
||||
if(subID == 4 && vstd::contains(builtBuildings, 17))
|
||||
{
|
||||
bonuses.push_back( Bonus(Bonus::PERMANENT, Bonus::DARKNESS, Bonus::TOWN_STRUCTURE, 20, 17) );
|
||||
addNewBonus( Bonus(Bonus::PERMANENT, Bonus::DARKNESS, Bonus::TOWN_STRUCTURE, 20, 17) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -708,11 +708,11 @@ ui32 CStack::Speed( int turn /*= 0*/ ) const
|
||||
int speed = valOfBonuses(Selector::type(Bonus::STACKS_SPEED) && Selector::turns(turn));
|
||||
|
||||
int percentBonus = 0;
|
||||
BOOST_FOREACH(const Bonus &b, bonuses)
|
||||
BOOST_FOREACH(const Bonus *b, bonuses)
|
||||
{
|
||||
if(b.type == Bonus::STACKS_SPEED)
|
||||
if(b->type == Bonus::STACKS_SPEED)
|
||||
{
|
||||
percentBonus += b.additionalInfo;
|
||||
percentBonus += b->additionalInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@ -729,7 +729,7 @@ ui32 CStack::Speed( int turn /*= 0*/ ) const
|
||||
|
||||
const Bonus * CStack::getEffect( ui16 id, int turn /*= 0*/ ) const
|
||||
{
|
||||
for (BonusList::const_iterator it = bonuses.begin(); it != bonuses.end(); it++)
|
||||
BOOST_FOREACH(Bonus *it, bonuses)
|
||||
{
|
||||
if(it->source == Bonus::SPELL_EFFECT && it->id == id)
|
||||
{
|
||||
@ -742,179 +742,179 @@ const Bonus * CStack::getEffect( ui16 id, int turn /*= 0*/ ) const
|
||||
|
||||
void CStack::stackEffectToFeature(BonusList & sf, const Bonus & sse)
|
||||
{
|
||||
si32 power = VLC->spellh->spells[sse.id].powers[sse.val];
|
||||
Bonus * bonus = getBonus(Selector::typeSybtype(Bonus::SPECIAL_PECULIAR_ENCHANT, sse.id));
|
||||
if (bonus)
|
||||
{
|
||||
switch(bonus->additionalInfo)
|
||||
{
|
||||
case 0: //normal
|
||||
switch(type->level)
|
||||
{
|
||||
case 1: case 2:
|
||||
power += 3; //it doesn't necessarily make sense for some spells, use it wisely
|
||||
break;
|
||||
case 3: case 4:
|
||||
power += 2;
|
||||
break;
|
||||
case 5: case 6:
|
||||
power += 1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 1: //only Coronius as yet
|
||||
power = std::max(5 - type->level, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch(sse.id)
|
||||
{
|
||||
case 27: //shield
|
||||
sf.push_back(featureGenerator(Bonus::GENERAL_DAMAGE_REDUCTION, 0, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 28: //air shield
|
||||
sf.push_back(featureGenerator(Bonus::GENERAL_DAMAGE_REDUCTION, 1, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 29: //fire shield
|
||||
sf.push_back(featureGenerator(Bonus::FIRE_SHIELD, 0, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 30: //protection from air
|
||||
sf.push_back(featureGenerator(Bonus::SPELL_DAMAGE_REDUCTION, 0, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 31: //protection from fire
|
||||
sf.push_back(featureGenerator(Bonus::SPELL_DAMAGE_REDUCTION, 1, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 32: //protection from water
|
||||
sf.push_back(featureGenerator(Bonus::SPELL_DAMAGE_REDUCTION, 2, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 33: //protection from earth
|
||||
sf.push_back(featureGenerator(Bonus::SPELL_DAMAGE_REDUCTION, 3, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 34: //anti-magic
|
||||
sf.push_back(featureGenerator(Bonus::LEVEL_SPELL_IMMUNITY, 0, power - 1, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 41: //bless
|
||||
if (hasBonusOfType(Bonus::SPECIAL_BLESS_DAMAGE, 41)) //TODO: better handling of bonus percentages
|
||||
{
|
||||
int damagePercent = dynamic_cast<const CGHeroInstance*>(armyObj)->level * valOfBonuses(Bonus::SPECIAL_BLESS_DAMAGE, 41) / type->level;
|
||||
sf.push_back(featureGenerator(Bonus::CREATURE_DAMAGE, 0, damagePercent, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.back().valType = Bonus::PERCENT_TO_ALL;
|
||||
}
|
||||
sf.push_back(featureGenerator(Bonus::ALWAYS_MAXIMUM_DAMAGE, -1, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 42: //curse
|
||||
sf.push_back(featureGenerator(Bonus::ALWAYS_MINIMUM_DAMAGE, -1, -1 * power, sse.turnsRemain, sse.val >= 2 ? 20 : 0));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 43: //bloodlust
|
||||
sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK, power, sse.turnsRemain, 0, Bonus::ONLY_MELEE_FIGHT));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 44: //precision
|
||||
sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK, power, sse.turnsRemain, 0, Bonus::ONLY_DISTANCE_FIGHT));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 45: //weakness
|
||||
sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK, -1 * power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 46: //stone skin
|
||||
sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 47: //disrupting ray
|
||||
sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE, -1 * power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 48: //prayer
|
||||
sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.push_back(featureGenerator(Bonus::STACKS_SPEED, 0, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 49: //mirth
|
||||
sf.push_back(featureGenerator(Bonus::MORALE, 0, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 50: //sorrow
|
||||
sf.push_back(featureGenerator(Bonus::MORALE, 0, -1 * power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 51: //fortune
|
||||
sf.push_back(featureGenerator(Bonus::LUCK, 0, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 52: //misfortune
|
||||
sf.push_back(featureGenerator(Bonus::LUCK, 0, -1 * power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 53: //haste
|
||||
sf.push_back(featureGenerator(Bonus::STACKS_SPEED, 0, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 54: //slow
|
||||
sf.push_back(featureGeneratorVT(Bonus::STACKS_SPEED, 0, -1 * ( 100 - power ), sse.turnsRemain, Bonus::PERCENT_TO_ALL));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 55: //slayer
|
||||
if (bonus) //Coronius
|
||||
{
|
||||
sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
}
|
||||
sf.push_back(featureGenerator(Bonus::SLAYER, 0, sse.val, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 56: //frenzy
|
||||
sf.push_back(featureGenerator(Bonus::IN_FRENZY, 0, VLC->spellh->spells[56].powers[sse.val]/100.0, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 58: //counterstrike
|
||||
sf.push_back(featureGenerator(Bonus::ADDITIONAL_RETALIATION, 0, power, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 59: //bersek
|
||||
sf.push_back(featureGenerator(Bonus::ATTACKS_NEAREST_CREATURE, 0, sse.val, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 60: //hypnotize
|
||||
sf.push_back(featureGenerator(Bonus::HYPNOTIZED, 0, sse.val, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 61: //forgetfulness
|
||||
sf.push_back(featureGenerator(Bonus::FORGETFULL, 0, sse.val, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
case 62: //blind
|
||||
sf.push_back(makeFeature(Bonus::NOT_ACTIVE, Bonus::UNITL_BEING_ATTACKED | Bonus::N_TURNS, 0, 0, Bonus::SPELL_EFFECT, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
sf.push_back(makeFeature(Bonus::GENERAL_ATTACK_REDUCTION, Bonus::UNTIL_ATTACK | Bonus::N_TURNS, 0, power, Bonus::SPELL_EFFECT, sse.turnsRemain));
|
||||
sf.back().id = sse.id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// si32 power = VLC->spellh->spells[sse.id].powers[sse.val];
|
||||
// Bonus * bonus = getBonus(Selector::typeSybtype(Bonus::SPECIAL_PECULIAR_ENCHANT, sse.id));
|
||||
// if (bonus)
|
||||
// {
|
||||
// switch(bonus->additionalInfo)
|
||||
// {
|
||||
// case 0: //normal
|
||||
// switch(type->level)
|
||||
// {
|
||||
// case 1: case 2:
|
||||
// power += 3; //it doesn't necessarily make sense for some spells, use it wisely
|
||||
// break;
|
||||
// case 3: case 4:
|
||||
// power += 2;
|
||||
// break;
|
||||
// case 5: case 6:
|
||||
// power += 1;
|
||||
// break;
|
||||
// }
|
||||
// break;
|
||||
// case 1: //only Coronius as yet
|
||||
// power = std::max(5 - type->level, 0);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// switch(sse.id)
|
||||
// {
|
||||
// case 27: //shield
|
||||
// sf.push_back(featureGenerator(Bonus::GENERAL_DAMAGE_REDUCTION, 0, power, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 28: //air shield
|
||||
// sf.push_back(featureGenerator(Bonus::GENERAL_DAMAGE_REDUCTION, 1, power, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 29: //fire shield
|
||||
// sf.push_back(featureGenerator(Bonus::FIRE_SHIELD, 0, power, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 30: //protection from air
|
||||
// sf.push_back(featureGenerator(Bonus::SPELL_DAMAGE_REDUCTION, 0, power, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 31: //protection from fire
|
||||
// sf.push_back(featureGenerator(Bonus::SPELL_DAMAGE_REDUCTION, 1, power, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 32: //protection from water
|
||||
// sf.push_back(featureGenerator(Bonus::SPELL_DAMAGE_REDUCTION, 2, power, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 33: //protection from earth
|
||||
// sf.push_back(featureGenerator(Bonus::SPELL_DAMAGE_REDUCTION, 3, power, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 34: //anti-magic
|
||||
// sf.push_back(featureGenerator(Bonus::LEVEL_SPELL_IMMUNITY, 0, power - 1, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 41: //bless
|
||||
// if (hasBonusOfType(Bonus::SPECIAL_BLESS_DAMAGE, 41)) //TODO: better handling of bonus percentages
|
||||
// {
|
||||
// int damagePercent = dynamic_cast<const CGHeroInstance*>(armyObj)->level * valOfBonuses(Bonus::SPECIAL_BLESS_DAMAGE, 41) / type->level;
|
||||
// sf.push_back(featureGenerator(Bonus::CREATURE_DAMAGE, 0, damagePercent, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// sf.back().valType = Bonus::PERCENT_TO_ALL;
|
||||
// }
|
||||
// sf.push_back(featureGenerator(Bonus::ALWAYS_MAXIMUM_DAMAGE, -1, power, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 42: //curse
|
||||
// sf.push_back(featureGenerator(Bonus::ALWAYS_MINIMUM_DAMAGE, -1, -1 * power, sse.turnsRemain, sse.val >= 2 ? 20 : 0));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 43: //bloodlust
|
||||
// sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK, power, sse.turnsRemain, 0, Bonus::ONLY_MELEE_FIGHT));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 44: //precision
|
||||
// sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK, power, sse.turnsRemain, 0, Bonus::ONLY_DISTANCE_FIGHT));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 45: //weakness
|
||||
// sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK, -1 * power, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 46: //stone skin
|
||||
// sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE, power, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 47: //disrupting ray
|
||||
// sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE, -1 * power, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 48: //prayer
|
||||
// sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK, power, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE, power, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// sf.push_back(featureGenerator(Bonus::STACKS_SPEED, 0, power, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 49: //mirth
|
||||
// sf.push_back(featureGenerator(Bonus::MORALE, 0, power, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 50: //sorrow
|
||||
// sf.push_back(featureGenerator(Bonus::MORALE, 0, -1 * power, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 51: //fortune
|
||||
// sf.push_back(featureGenerator(Bonus::LUCK, 0, power, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 52: //misfortune
|
||||
// sf.push_back(featureGenerator(Bonus::LUCK, 0, -1 * power, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 53: //haste
|
||||
// sf.push_back(featureGenerator(Bonus::STACKS_SPEED, 0, power, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 54: //slow
|
||||
// sf.push_back(featureGeneratorVT(Bonus::STACKS_SPEED, 0, -1 * ( 100 - power ), sse.turnsRemain, Bonus::PERCENT_TO_ALL));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 55: //slayer
|
||||
// if (bonus) //Coronius
|
||||
// {
|
||||
// sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK, power, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// }
|
||||
// sf.push_back(featureGenerator(Bonus::SLAYER, 0, sse.val, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 56: //frenzy
|
||||
// sf.push_back(featureGenerator(Bonus::IN_FRENZY, 0, VLC->spellh->spells[56].powers[sse.val]/100.0, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 58: //counterstrike
|
||||
// sf.push_back(featureGenerator(Bonus::ADDITIONAL_RETALIATION, 0, power, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 59: //bersek
|
||||
// sf.push_back(featureGenerator(Bonus::ATTACKS_NEAREST_CREATURE, 0, sse.val, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 60: //hypnotize
|
||||
// sf.push_back(featureGenerator(Bonus::HYPNOTIZED, 0, sse.val, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 61: //forgetfulness
|
||||
// sf.push_back(featureGenerator(Bonus::FORGETFULL, 0, sse.val, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// case 62: //blind
|
||||
// sf.push_back(makeFeature(Bonus::NOT_ACTIVE, Bonus::UNITL_BEING_ATTACKED | Bonus::N_TURNS, 0, 0, Bonus::SPELL_EFFECT, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// sf.push_back(makeFeature(Bonus::GENERAL_ATTACK_REDUCTION, Bonus::UNTIL_ATTACK | Bonus::N_TURNS, 0, power, Bonus::SPELL_EFFECT, sse.turnsRemain));
|
||||
// sf.back().id = sse.id;
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
|
||||
ui8 CStack::howManyEffectsSet(ui16 id) const
|
||||
{
|
||||
ui8 ret = 0;
|
||||
for (BonusList::const_iterator it = bonuses.begin(); it != bonuses.end(); it++)
|
||||
if(it->source == Bonus::SPELL_EFFECT && it->id == id) //effect found
|
||||
{
|
||||
++ret;
|
||||
}
|
||||
BOOST_FOREACH(const Bonus *it, bonuses)
|
||||
if(it->source == Bonus::SPELL_EFFECT && it->id == id) //effect found
|
||||
{
|
||||
++ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -968,7 +968,7 @@ std::vector<si32> CStack::activeSpells() const
|
||||
std::vector<si32> ret;
|
||||
|
||||
BonusList spellEffects = getSpellBonuses();
|
||||
for(BonusList::const_iterator it = spellEffects.begin(); it != spellEffects.end(); it++)
|
||||
BOOST_FOREACH(const Bonus *it, spellEffects)
|
||||
{
|
||||
if (!vstd::contains(ret, it->id)) //do not duplicate spells with multiple effects
|
||||
ret.push_back(it->id);
|
||||
@ -1427,8 +1427,8 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Bonus bb(Bonus::PERMANENT, Bonus::PRIMARY_SKILL, Bonus::CAMPAIGN_BONUS, val, si->whichMapInCampaign, g);
|
||||
hero->bonuses.push_back(bb);
|
||||
Bonus *bb = new Bonus(Bonus::PERMANENT, Bonus::PRIMARY_SKILL, Bonus::CAMPAIGN_BONUS, val, si->whichMapInCampaign, g);
|
||||
hero->addNewBonus(bb);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -2262,7 +2262,7 @@ UpgradeInfo CGameState::getUpgradeInfo(const CStackInstance &stack)
|
||||
else if(h)
|
||||
{ //hero speciality
|
||||
BonusList lista = h->speciality.getBonuses(Selector::typeSybtype(Bonus::SPECIAL_UPGRADE, base->idNumber));
|
||||
for (BonusList::iterator it = lista.begin(); it != lista.end(); it++)
|
||||
BOOST_FOREACH(const Bonus *it, lista)
|
||||
{
|
||||
ui16 nid = it->additionalInfo;
|
||||
if (nid != base->idNumber) //in very specific case the upgrade is avaliable by default (?)
|
||||
@ -3136,11 +3136,11 @@ std::pair<ui32, ui32> BattleInfo::calculateDmgRange( const CStack* attacker, con
|
||||
|
||||
for(int g = 0; g < VLC->creh->creatures.size(); ++g)
|
||||
{
|
||||
BOOST_FOREACH(const Bonus &b, VLC->creh->creatures[g]->bonuses)
|
||||
BOOST_FOREACH(const Bonus *b, VLC->creh->creatures[g]->bonuses)
|
||||
{
|
||||
if ( (b.type == Bonus::KING3 && spLevel >= 3) || //expert
|
||||
(b.type == Bonus::KING2 && spLevel >= 2) || //adv +
|
||||
(b.type == Bonus::KING1 && spLevel >= 0) ) //none or basic +
|
||||
if ( (b->type == Bonus::KING3 && spLevel >= 3) || //expert
|
||||
(b->type == Bonus::KING2 && spLevel >= 2) || //adv +
|
||||
(b->type == Bonus::KING1 && spLevel >= 0) ) //none or basic +
|
||||
{
|
||||
affectedIds.push_back(g);
|
||||
break;
|
||||
@ -3237,7 +3237,8 @@ std::pair<ui32, ui32> BattleInfo::calculateDmgRange( const CStack* attacker, con
|
||||
public:
|
||||
static bool hasAdvancedAirShield(const CStack * stack)
|
||||
{
|
||||
for (BonusList::const_iterator it = stack->bonuses.begin(); it != stack->bonuses.end(); it++)
|
||||
|
||||
BOOST_FOREACH(const Bonus *it, stack->bonuses)
|
||||
{
|
||||
if (it->source == Bonus::SPELL_EFFECT && it->id == 28 && it->val >= 2)
|
||||
{
|
||||
@ -3332,7 +3333,7 @@ si8 CGameState::battleMaxSpellLevel()
|
||||
const CGHeroInstance *h1 = curB->heroes[0];
|
||||
if(h1)
|
||||
{
|
||||
for(std::list<Bonus>::const_iterator i = h1->bonuses.begin(); i != h1->bonuses.end(); i++)
|
||||
BOOST_FOREACH(const Bonus *i, h1->bonuses)
|
||||
if(i->type == Bonus::BLOCK_SPELLS_ABOVE_LEVEL)
|
||||
amin(levelLimit, i->val);
|
||||
}
|
||||
@ -3340,7 +3341,8 @@ si8 CGameState::battleMaxSpellLevel()
|
||||
const CGHeroInstance *h2 = curB->heroes[1];
|
||||
if(h2)
|
||||
{
|
||||
for(std::list<Bonus>::const_iterator i = h2->bonuses.begin(); i != h2->bonuses.end(); i++)
|
||||
|
||||
BOOST_FOREACH(const Bonus *i, h2->bonuses)
|
||||
if(i->type == Bonus::BLOCK_SPELLS_ABOVE_LEVEL)
|
||||
amin(levelLimit, i->val);
|
||||
}
|
||||
@ -3437,16 +3439,20 @@ CStack * BattleInfo::generateNewStack(const CStackInstance &base, int stackID, b
|
||||
{
|
||||
CStack * ret = new CStack(&base, attackerOwned ? side1 : side2, stackID, attackerOwned, slot);
|
||||
|
||||
//native terrain bonuses
|
||||
int faction = ret->type->faction;
|
||||
if(faction >= 0 && VLC->heroh->nativeTerrains[faction] == terrain)
|
||||
{
|
||||
ret->bonuses.push_back(makeFeature(Bonus::STACKS_SPEED, Bonus::ONE_BATTLE, 0, 1, Bonus::TERRAIN_NATIVE));
|
||||
ret->bonuses.push_back(makeFeature(Bonus::PRIMARY_SKILL, Bonus::ONE_BATTLE, PrimarySkill::ATTACK, 1, Bonus::TERRAIN_NATIVE));
|
||||
ret->bonuses.push_back(makeFeature(Bonus::PRIMARY_SKILL, Bonus::ONE_BATTLE, PrimarySkill::DEFENSE, 1, Bonus::TERRAIN_NATIVE));
|
||||
}
|
||||
//TODO: bonus na bitwê z limiterem
|
||||
|
||||
ret->position = position;
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//native terrain bonuses
|
||||
// int faction = ret->type->faction;
|
||||
// if(faction >= 0 && VLC->heroh->nativeTerrains[faction] == terrain)
|
||||
// {
|
||||
// ret->addNewBonus(makeFeature(Bonus::STACKS_SPEED, Bonus::ONE_BATTLE, 0, 1, Bonus::TERRAIN_NATIVE));
|
||||
// ret->addNewBonus(makeFeature(Bonus::PRIMARY_SKILL, Bonus::ONE_BATTLE, PrimarySkill::ATTACK, 1, Bonus::TERRAIN_NATIVE));
|
||||
// ret->addNewBonus(makeFeature(Bonus::PRIMARY_SKILL, Bonus::ONE_BATTLE, PrimarySkill::DEFENSE, 1, Bonus::TERRAIN_NATIVE));
|
||||
// }
|
||||
//
|
||||
// ret->position = position;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ int DLL_EXPORT BonusList::totalValue() const
|
||||
int indepMax = 0;
|
||||
bool hasIndepMax = false;
|
||||
|
||||
for(const_iterator i = begin(); i != end(); i++)
|
||||
BOOST_FOREACH(Bonus *i, *this)
|
||||
{
|
||||
switch(i->valType)
|
||||
{
|
||||
@ -65,38 +65,38 @@ int DLL_EXPORT BonusList::totalValue() const
|
||||
}
|
||||
const DLL_EXPORT Bonus * BonusList::getFirst(const CSelector &selector) const
|
||||
{
|
||||
for (const_iterator i = begin(); i != end(); i++)
|
||||
if(selector(*i))
|
||||
BOOST_FOREACH(Bonus *i, *this)
|
||||
if(selector(i))
|
||||
return &*i;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DLL_EXPORT Bonus * BonusList::getFirst(const CSelector &select)
|
||||
{
|
||||
for (iterator i = begin(); i != end(); i++)
|
||||
if(select(*i))
|
||||
BOOST_FOREACH(Bonus *i, *this)
|
||||
if(select(i))
|
||||
return &*i;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void DLL_EXPORT BonusList::getModifiersWDescr(TModDescr &out) const
|
||||
{
|
||||
for(const_iterator i = begin(); i != end(); i++)
|
||||
BOOST_FOREACH(Bonus *i, *this)
|
||||
out.push_back(std::make_pair(i->val, i->Description()));
|
||||
}
|
||||
|
||||
void DLL_EXPORT BonusList::getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *source /*= NULL*/) const
|
||||
{
|
||||
for(const_iterator i = begin(); i != end(); i++)
|
||||
if(selector(*i) && i->effectRange == Bonus::NO_LIMIT)
|
||||
out.push_back(*i);
|
||||
BOOST_FOREACH(Bonus *i, *this)
|
||||
if(selector(i) && i->effectRange == Bonus::NO_LIMIT)
|
||||
out.push_back(i);
|
||||
}
|
||||
|
||||
void DLL_EXPORT BonusList::getBonuses(BonusList &out, const CSelector &selector, const CSelector &limit, const CBonusSystemNode *source /*= NULL*/) const
|
||||
{
|
||||
for(const_iterator i = begin(); i != end(); i++)
|
||||
if(selector(*i) && (!limit || limit(*i)))
|
||||
out.push_back(*i);
|
||||
BOOST_FOREACH(Bonus *i, *this)
|
||||
if(selector(i) && (!limit || limit(i)))
|
||||
out.push_back(i);
|
||||
}
|
||||
|
||||
namespace HHLP
|
||||
@ -108,9 +108,9 @@ namespace HHLP
|
||||
SourceComp(Bonus::BonusSource _src) : src(_src)
|
||||
{
|
||||
}
|
||||
bool operator()(const Bonus & bon)
|
||||
bool operator()(const Bonus * bon)
|
||||
{
|
||||
return bon.source == src;
|
||||
return bon->source == src;
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -126,7 +126,8 @@ void BonusList::limit(const CBonusSystemNode &node)
|
||||
limit_start:
|
||||
for(iterator i = begin(); i != end(); i++)
|
||||
{
|
||||
if(i->limiter && i->limiter->limit(*i, node))
|
||||
Bonus *b = *i;
|
||||
if(b->limiter && b->limiter->limit(b, node))
|
||||
{
|
||||
iterator toErase = i;
|
||||
if(i != begin())
|
||||
@ -344,6 +345,31 @@ void CBonusSystemNode::detachFrom(const CBonusSystemNode *parent)
|
||||
|
||||
}
|
||||
|
||||
void CBonusSystemNode::popBonuses(const CSelector &s)
|
||||
{
|
||||
//TODO
|
||||
//prop
|
||||
|
||||
bonuses.remove_if(s);
|
||||
BOOST_FOREACH(CBonusSystemNode *child, children)
|
||||
child->popBonuses(s);
|
||||
}
|
||||
|
||||
void CBonusSystemNode::addNewBonus(const Bonus &b)
|
||||
{
|
||||
addNewBonus(new Bonus(b));
|
||||
}
|
||||
|
||||
void CBonusSystemNode::addNewBonus(Bonus *b)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CBonusSystemNode::removeBonus(Bonus *b)
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
|
||||
int NBonus::valOf(const CBonusSystemNode *obj, Bonus::BonusType type, int subtype /*= -1*/)
|
||||
{
|
||||
if(obj)
|
||||
@ -473,7 +499,7 @@ namespace Selector
|
||||
{
|
||||
Bonus dummy;
|
||||
dummy.type = type;
|
||||
return sel(dummy);
|
||||
return sel(&dummy);
|
||||
}
|
||||
|
||||
bool DLL_EXPORT matchesTypeSubtype(const CSelector &sel, TBonusType type, TBonusSubtype subtype)
|
||||
@ -481,16 +507,16 @@ namespace Selector
|
||||
Bonus dummy;
|
||||
dummy.type = type;
|
||||
dummy.subtype = subtype;
|
||||
return sel(dummy);
|
||||
return sel(&dummy);
|
||||
}
|
||||
}
|
||||
|
||||
DLL_EXPORT std::ostream & operator<<(std::ostream &out, const BonusList &bonusList)
|
||||
{
|
||||
int i = 0;
|
||||
BOOST_FOREACH(const Bonus &b, bonusList)
|
||||
BOOST_FOREACH(const Bonus *b, bonusList)
|
||||
{
|
||||
out << "Bonus " << i++ << "\n" << b << std::endl;
|
||||
out << "Bonus " << i++ << "\n" << *b << std::endl;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@ -520,12 +546,12 @@ ILimiter::~ILimiter()
|
||||
{
|
||||
}
|
||||
|
||||
bool ILimiter::limit(const Bonus &b, const CBonusSystemNode &node) const /*return true to drop the bonus */
|
||||
bool ILimiter::limit(const Bonus *b, const CBonusSystemNode &node) const /*return true to drop the bonus */
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CCreatureTypeLimiter::limit(const Bonus &b, const CBonusSystemNode &node) const
|
||||
bool CCreatureTypeLimiter::limit(const Bonus *b, const CBonusSystemNode &node) const
|
||||
{
|
||||
switch (node.nodeType)
|
||||
{
|
||||
@ -566,7 +592,7 @@ HasAnotherBonusLimiter::HasAnotherBonusLimiter( TBonusType bonus, TBonusSubtype
|
||||
{
|
||||
}
|
||||
|
||||
bool HasAnotherBonusLimiter::limit( const Bonus &b, const CBonusSystemNode &node ) const
|
||||
bool HasAnotherBonusLimiter::limit( const Bonus *b, const CBonusSystemNode &node ) const
|
||||
{
|
||||
if(isSubtypeRelevant)
|
||||
{
|
||||
|
@ -28,7 +28,7 @@ class ILimiter;
|
||||
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;
|
||||
typedef boost::function<bool(const Bonus&)> CSelector;
|
||||
typedef boost::function<bool(const Bonus*)> CSelector;
|
||||
|
||||
namespace PrimarySkill
|
||||
{
|
||||
@ -253,25 +253,25 @@ struct DLL_EXPORT Bonus
|
||||
h & duration & type & subtype & source & val & id & description & additionalInfo & turnsRemain & valType & effectRange & limiter;
|
||||
}
|
||||
|
||||
static bool OneDay(const Bonus &hb)
|
||||
static bool OneDay(const Bonus *hb)
|
||||
{
|
||||
return hb.duration & Bonus::ONE_DAY;
|
||||
return hb->duration & Bonus::ONE_DAY;
|
||||
}
|
||||
static bool OneWeek(const Bonus &hb)
|
||||
static bool OneWeek(const Bonus *hb)
|
||||
{
|
||||
return hb.duration & Bonus::ONE_WEEK;
|
||||
return hb->duration & Bonus::ONE_WEEK;
|
||||
}
|
||||
static bool OneBattle(const Bonus &hb)
|
||||
static bool OneBattle(const Bonus *hb)
|
||||
{
|
||||
return hb.duration & Bonus::ONE_BATTLE;
|
||||
return hb->duration & Bonus::ONE_BATTLE;
|
||||
}
|
||||
static bool UntilAttack(const Bonus &hb)
|
||||
static bool UntilAttack(const Bonus *hb)
|
||||
{
|
||||
return hb.duration & Bonus::UNTIL_ATTACK;
|
||||
return hb->duration & Bonus::UNTIL_ATTACK;
|
||||
}
|
||||
static bool UntilBeingAttacked(const Bonus &hb)
|
||||
static bool UntilBeingAttacked(const Bonus *hb)
|
||||
{
|
||||
return hb.duration & Bonus::UNITL_BEING_ATTACKED;
|
||||
return hb->duration & Bonus::UNITL_BEING_ATTACKED;
|
||||
}
|
||||
static bool IsFrom(const Bonus &hb, ui8 source, ui32 id) //if id==0xffffff then id doesn't matter
|
||||
{
|
||||
@ -308,7 +308,7 @@ struct DLL_EXPORT stackExperience : public Bonus
|
||||
|
||||
DLL_EXPORT std::ostream & operator<<(std::ostream &out, const Bonus &bonus);
|
||||
|
||||
class BonusList : public std::list<Bonus>
|
||||
class BonusList : public std::list<Bonus*>
|
||||
{
|
||||
public:
|
||||
int DLL_EXPORT totalValue() const; //subtype -> subtype of bonus, if -1 then any
|
||||
@ -325,7 +325,7 @@ public:
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<std::list<Bonus>&>(*this);
|
||||
h & static_cast<std::list<Bonus*>&>(*this);
|
||||
}
|
||||
};
|
||||
|
||||
@ -336,7 +336,7 @@ class DLL_EXPORT ILimiter
|
||||
public:
|
||||
virtual ~ILimiter();
|
||||
|
||||
virtual bool limit(const Bonus &b, const CBonusSystemNode &node) const; //return true to drop the bonus
|
||||
virtual bool limit(const Bonus *b, const CBonusSystemNode &node) const; //return true to drop the bonus
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{}
|
||||
@ -348,7 +348,7 @@ public:
|
||||
BonusList bonuses; //wielded bonuses (local and up-propagated here)
|
||||
std::vector<Bonus*> exportedBonuses;
|
||||
|
||||
std::vector<const CBonusSystemNode *> parents, //parents -> we inherit bonuses from them, we may attach our bonuses to them
|
||||
std::vector<CBonusSystemNode *> parents, //parents -> we inherit bonuses from them, we may attach our bonuses to them
|
||||
children;
|
||||
|
||||
ui8 nodeType;
|
||||
@ -396,6 +396,11 @@ public:
|
||||
|
||||
void attachTo(const CBonusSystemNode *parent);
|
||||
void detachFrom(const CBonusSystemNode *parent);
|
||||
void addNewBonus(Bonus *b); //b will be deleted with destruction of node
|
||||
void addNewBonus(const Bonus &b); //b will copied
|
||||
void removeBonus(Bonus *b);
|
||||
|
||||
void popBonuses(const CSelector &s);
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
@ -441,7 +446,7 @@ public:
|
||||
:first(First), second(Second)
|
||||
{
|
||||
}
|
||||
bool operator()(const Bonus &bonus) const
|
||||
bool operator()(const Bonus *bonus) const
|
||||
{
|
||||
return first(bonus) && second(bonus);
|
||||
}
|
||||
@ -456,7 +461,7 @@ public:
|
||||
:first(First), second(Second)
|
||||
{
|
||||
}
|
||||
bool operator()(const Bonus &bonus) const
|
||||
bool operator()(const Bonus *bonus) const
|
||||
{
|
||||
return first(bonus) || second(bonus);
|
||||
}
|
||||
@ -473,9 +478,9 @@ public:
|
||||
: ptr(Ptr), val(Val)
|
||||
{
|
||||
}
|
||||
bool operator()(const Bonus &bonus) const
|
||||
bool operator()(const Bonus *bonus) const
|
||||
{
|
||||
return bonus.*ptr == val;
|
||||
return bonus->*ptr == val;
|
||||
}
|
||||
CSelectFieldEqual& operator()(const T &setVal)
|
||||
{
|
||||
@ -489,11 +494,11 @@ class CWillLastTurns
|
||||
public:
|
||||
int turnsRequested;
|
||||
|
||||
bool operator()(const Bonus &bonus) const
|
||||
bool operator()(const Bonus *bonus) const
|
||||
{
|
||||
return turnsRequested <= 0 //every present effect will last zero (or "less") turns
|
||||
|| !(bonus.duration & Bonus::N_TURNS) //so do every not expriing after N-turns effect
|
||||
|| bonus.turnsRemain > turnsRequested;
|
||||
|| !(bonus->duration & Bonus::N_TURNS) //so do every not expriing after N-turns effect
|
||||
|| bonus->turnsRemain > turnsRequested;
|
||||
}
|
||||
CWillLastTurns& operator()(const int &setVal)
|
||||
{
|
||||
@ -511,7 +516,7 @@ public:
|
||||
CCreatureTypeLimiter();
|
||||
CCreatureTypeLimiter(const CCreature &Creature, ui8 IncludeUpgrades = true);
|
||||
|
||||
bool limit(const Bonus &b, const CBonusSystemNode &node) const;
|
||||
bool limit(const Bonus *b, const CBonusSystemNode &node) const OVERRIDE;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
@ -529,7 +534,7 @@ public:
|
||||
HasAnotherBonusLimiter(TBonusType bonus);
|
||||
HasAnotherBonusLimiter(TBonusType bonus, TBonusSubtype _subtype);
|
||||
|
||||
bool limit(const Bonus &b, const CBonusSystemNode &node) const;
|
||||
bool limit(const Bonus *b, const CBonusSystemNode &node) const OVERRIDE;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
|
@ -185,33 +185,26 @@ DLL_EXPORT void SetAvailableHeroes::applyGs( CGameState *gs )
|
||||
|
||||
DLL_EXPORT void GiveBonus::applyGs( CGameState *gs )
|
||||
{
|
||||
BonusList *bonuses = NULL;
|
||||
CBonusSystemNode *cbsn = NULL;
|
||||
switch(who)
|
||||
{
|
||||
case HERO:
|
||||
{
|
||||
CGHeroInstance *h = gs->getHero(id);
|
||||
assert(h);
|
||||
bonuses = &h->bonuses;
|
||||
}
|
||||
cbsn = gs->getHero(id);
|
||||
break;
|
||||
case PLAYER:
|
||||
{
|
||||
PlayerState *p = gs->getPlayer(id);
|
||||
assert(p);
|
||||
bonuses = &p->bonuses;
|
||||
}
|
||||
cbsn = gs->getPlayer(id);
|
||||
break;
|
||||
case TOWN:
|
||||
{
|
||||
CGTownInstance *t = gs->getTown(id);
|
||||
assert(t);
|
||||
bonuses = &t->bonuses;
|
||||
}
|
||||
cbsn = gs->getTown(id);
|
||||
break;
|
||||
}
|
||||
|
||||
bonuses->push_back(bonus);
|
||||
std::string &descr = bonuses->back().description;
|
||||
assert(cbsn);
|
||||
|
||||
Bonus *b = new Bonus(bonus);
|
||||
cbsn->addNewBonus(b);
|
||||
|
||||
std::string &descr = b->description;
|
||||
|
||||
if(!bdescr.message.size()
|
||||
&& bonus.source == Bonus::OBJECT
|
||||
@ -248,13 +241,13 @@ DLL_EXPORT void PlayerEndsGame::applyGs( CGameState *gs )
|
||||
|
||||
DLL_EXPORT void RemoveBonus::applyGs( CGameState *gs )
|
||||
{
|
||||
std::list<Bonus> &bonuses = (who == HERO ? gs->getHero(whoID)->bonuses : gs->getPlayer(whoID)->bonuses);
|
||||
BonusList &bonuses = (who == HERO ? gs->getHero(whoID)->bonuses : gs->getPlayer(whoID)->bonuses);
|
||||
|
||||
for(std::list<Bonus>::iterator i = bonuses.begin(); i != bonuses.end(); i++)
|
||||
for(BonusList::iterator i = bonuses.begin(); i != bonuses.end(); i++)
|
||||
{
|
||||
if(i->source == source && i->id == id)
|
||||
if((*i)->source == source && (*i)->id == id)
|
||||
{
|
||||
bonus = *i; //backup bonus (to show to interfaces later)
|
||||
bonus = **i; //backup bonus (to show to interfaces later)
|
||||
bonuses.erase(i);
|
||||
break;
|
||||
}
|
||||
@ -654,50 +647,45 @@ DLL_EXPORT void NewTurn::applyGs( CGameState *gs )
|
||||
|
||||
if (specialWeek != NO_ACTION) //first pack applied, reset all effects and aplly new
|
||||
{
|
||||
BOOST_FOREACH(CGHeroInstance *h, gs->map->heroes)
|
||||
h->bonuses.remove_if(Bonus::OneDay);
|
||||
//TODO? won't work for battles lasting several turns (not an issue now but...)
|
||||
gs->globalEffects.popBonuses(Bonus::OneDay); //works for children -> all game objs
|
||||
|
||||
if(gs->getDate(1)) //new week, Monday that is
|
||||
{
|
||||
for( std::map<ui8, PlayerState>::iterator i=gs->players.begin() ; i!=gs->players.end();i++)
|
||||
i->second.bonuses.remove_if(Bonus::OneWeek);
|
||||
BOOST_FOREACH(CGHeroInstance *h, gs->map->heroes)
|
||||
h->bonuses.remove_if(Bonus::OneWeek);
|
||||
gs->globalEffects.popBonuses(Bonus::OneWeek); //works for children -> all game objs
|
||||
|
||||
gs->globalEffects.bonuses.remove_if(Bonus::OneWeek);
|
||||
|
||||
Bonus b;
|
||||
b.duration = Bonus::ONE_WEEK;
|
||||
b.source = Bonus::SPECIAL_WEEK;
|
||||
b.effectRange = Bonus::NO_LIMIT;
|
||||
b.valType = Bonus::BASE_NUMBER; //certainly not intuitive
|
||||
Bonus *b = new Bonus();
|
||||
b->duration = Bonus::ONE_WEEK;
|
||||
b->source = Bonus::SPECIAL_WEEK;
|
||||
b->effectRange = Bonus::NO_LIMIT;
|
||||
b->valType = Bonus::BASE_NUMBER; //certainly not intuitive
|
||||
switch (specialWeek)
|
||||
{
|
||||
case DOUBLE_GROWTH:
|
||||
b.val = 100;
|
||||
b.type = Bonus::CREATURE_GROWTH_PERCENT;
|
||||
b.limiter = new CCreatureTypeLimiter(*VLC->creh->creatures[creatureid], false);
|
||||
b->val = 100;
|
||||
b->type = Bonus::CREATURE_GROWTH_PERCENT;
|
||||
b->limiter = new CCreatureTypeLimiter(*VLC->creh->creatures[creatureid], false);
|
||||
break;
|
||||
case BONUS_GROWTH:
|
||||
b.val = 5;
|
||||
b.type = Bonus::CREATURE_GROWTH;
|
||||
b.limiter = new CCreatureTypeLimiter(*VLC->creh->creatures[creatureid], false);
|
||||
b->val = 5;
|
||||
b->type = Bonus::CREATURE_GROWTH;
|
||||
b->limiter = new CCreatureTypeLimiter(*VLC->creh->creatures[creatureid], false);
|
||||
break;
|
||||
case DEITYOFFIRE:
|
||||
b.val = 15;
|
||||
b.type = Bonus::CREATURE_GROWTH;
|
||||
b.limiter = new CCreatureTypeLimiter(*VLC->creh->creatures[42], true);
|
||||
b->val = 15;
|
||||
b->type = Bonus::CREATURE_GROWTH;
|
||||
b->limiter = new CCreatureTypeLimiter(*VLC->creh->creatures[42], true);
|
||||
break;
|
||||
case PLAGUE:
|
||||
b.val = -100; //no basic creatures
|
||||
b.type = Bonus::CREATURE_GROWTH_PERCENT;
|
||||
b->val = -100; //no basic creatures
|
||||
b->type = Bonus::CREATURE_GROWTH_PERCENT;
|
||||
break;
|
||||
default:
|
||||
b.val = 0;
|
||||
b->val = 0;
|
||||
|
||||
}
|
||||
if (b.val)
|
||||
gs->globalEffects.bonuses.push_back(b);
|
||||
if (b->val)
|
||||
gs->globalEffects.addNewBonus(b);
|
||||
}
|
||||
}
|
||||
else //second pack is applied
|
||||
@ -709,8 +697,6 @@ DLL_EXPORT void NewTurn::applyGs( CGameState *gs )
|
||||
i->second.daysWithoutCastle = 0;
|
||||
else
|
||||
i->second.daysWithoutCastle++;
|
||||
|
||||
i->second.bonuses.remove_if(Bonus::OneDay);
|
||||
}
|
||||
if(resetBuilded) //reset amount of structures set in this turn in towns
|
||||
{
|
||||
@ -786,28 +772,29 @@ DLL_EXPORT void BattleNextRound::applyGs( CGameState *gs )
|
||||
//remove effects and restore only those with remaining turns in duration
|
||||
BonusList tmpEffects = s->bonuses;
|
||||
s->bonuses.removeSpells(Bonus::CASTED_SPELL);
|
||||
for (BonusList::iterator it = tmpEffects.begin(); it != tmpEffects.end(); it++)
|
||||
|
||||
BOOST_FOREACH(Bonus *it, tmpEffects)
|
||||
{
|
||||
it->turnsRemain--;
|
||||
if(it->turnsRemain > 0)
|
||||
s->bonuses.push_back(*it);
|
||||
s->addNewBonus(it);
|
||||
}
|
||||
|
||||
//the same as above for features
|
||||
BonusList tmpFeatures = s->bonuses;
|
||||
s->bonuses.clear();
|
||||
|
||||
BOOST_FOREACH(Bonus &b, tmpFeatures)
|
||||
BOOST_FOREACH(Bonus *b, tmpFeatures)
|
||||
{
|
||||
if((b.duration & Bonus::N_TURNS) != 0)
|
||||
if((b->duration & Bonus::N_TURNS) != 0)
|
||||
{
|
||||
b.turnsRemain--;
|
||||
if(b.turnsRemain > 0)
|
||||
s->bonuses.push_back(b);
|
||||
b->turnsRemain--;
|
||||
if(b->turnsRemain > 0)
|
||||
s->addNewBonus(b);
|
||||
}
|
||||
else
|
||||
{
|
||||
s->bonuses.push_back(b);
|
||||
s->addNewBonus(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -954,9 +941,10 @@ DLL_EXPORT void BattleSpellCast::applyGs( CGameState *gs )
|
||||
if(s && !vstd::contains(resisted, s->ID)) //if stack exists and it didn't resist
|
||||
{
|
||||
BonusList remainingEff;
|
||||
//WTF?
|
||||
for (BonusList::iterator it = remainingEff.begin(); it != remainingEff.end(); it++)
|
||||
{
|
||||
if (onlyHelpful && VLC->spellh->spells[ it->id ].positiveness != 1)
|
||||
if (onlyHelpful && VLC->spellh->spells[ (*it)->id ].positiveness != 1)
|
||||
{
|
||||
remainingEff.push_back(*it);
|
||||
}
|
||||
@ -968,11 +956,11 @@ DLL_EXPORT void BattleSpellCast::applyGs( CGameState *gs )
|
||||
//removing all features from spells
|
||||
BonusList tmpFeatures = s->bonuses;
|
||||
s->bonuses.clear();
|
||||
BOOST_FOREACH(Bonus &b, tmpFeatures)
|
||||
BOOST_FOREACH(Bonus *b, tmpFeatures)
|
||||
{
|
||||
const CSpell *sp = b.sourceSpell();
|
||||
if(sp && sp->positiveness != 1) //if(b.source != HeroBonus::SPELL_EFFECT || b.positiveness != 1)
|
||||
s->bonuses.push_back(b);
|
||||
const CSpell *sp = b->sourceSpell();
|
||||
if(sp && sp->positiveness != 1) //if(b->source != HeroBonus::SPELL_EFFECT || b.positiveness != 1)
|
||||
s->addNewBonus(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1005,7 +993,7 @@ DLL_EXPORT void BattleSpellCast::applyGs( CGameState *gs )
|
||||
bool ac[BFIELD_SIZE];
|
||||
std::set<int> occupyable;
|
||||
bool twoHex = VLC->creh->creatures[creID]->isDoubleWide();
|
||||
bool flying = vstd::contains(VLC->creh->creatures[creID]->bonuses, Bonus::FLYING);
|
||||
bool flying = VLC->creh->creatures[creID]->isFlying();// vstd::contains(VLC->creh->creatures[creID]->bonuses, Bonus::FLYING);
|
||||
gs->curB->getAccessibilityMap(ac, twoHex, !side, true, occupyable, flying);
|
||||
for(int g=0; g<BFIELD_SIZE; ++g)
|
||||
{
|
||||
@ -1018,7 +1006,7 @@ DLL_EXPORT void BattleSpellCast::applyGs( CGameState *gs )
|
||||
|
||||
CStack * summonedStack = gs->curB->generateNewStack(CStackInstance(creID, h->getPrimSkillLevel(2) * VLC->spellh->spells[id].powers[skill], h), gs->curB->stacks.size(), !side, 255, ter, pos);
|
||||
summonedStack->state.insert(SUMMONED);
|
||||
//summonedStack->bonuses.push_back( makeFeature(HeroBonus::SUMMONED, HeroBonus::ONE_BATTLE, 0, 0, HeroBonus::BONUS_FROM_HERO) );
|
||||
//summonedStack->addNewBonus( makeFeature(HeroBonus::SUMMONED, HeroBonus::ONE_BATTLE, 0, 0, HeroBonus::BONUS_FROM_HERO) );
|
||||
|
||||
gs->curB->stacks.push_back(summonedStack);
|
||||
}
|
||||
@ -1027,7 +1015,7 @@ DLL_EXPORT void BattleSpellCast::applyGs( CGameState *gs )
|
||||
void actualizeEffect(CStack * s, Bonus & ef)
|
||||
{
|
||||
//actualizing effects vector
|
||||
for (BonusList::iterator it = s->bonuses.begin(); it != s->bonuses.end(); it++)
|
||||
BOOST_FOREACH(Bonus *it, s->bonuses)
|
||||
{
|
||||
if(it->id == ef.id)
|
||||
{
|
||||
@ -1038,13 +1026,13 @@ void actualizeEffect(CStack * s, Bonus & ef)
|
||||
BonusList sf;
|
||||
s->stackEffectToFeature(sf, ef);
|
||||
|
||||
BOOST_FOREACH(const Bonus &fromEffect, sf)
|
||||
BOOST_FOREACH(const Bonus *fromEffect, sf)
|
||||
{
|
||||
BOOST_FOREACH(Bonus &stackBonus, s->bonuses) //TODO: optimize
|
||||
BOOST_FOREACH(Bonus *stackBonus, s->bonuses) //TODO: optimize
|
||||
{
|
||||
if(stackBonus.source == Bonus::SPELL_EFFECT && stackBonus.type == fromEffect.type && stackBonus.subtype == fromEffect.subtype)
|
||||
if(stackBonus->source == Bonus::SPELL_EFFECT && stackBonus->type == fromEffect->type && stackBonus->subtype == fromEffect->subtype)
|
||||
{
|
||||
stackBonus.turnsRemain = std::max(stackBonus.turnsRemain, ef.turnsRemain);
|
||||
stackBonus->turnsRemain = std::max(stackBonus->turnsRemain, ef.turnsRemain);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1060,12 +1048,12 @@ DLL_EXPORT void SetStackEffect::applyGs( CGameState *gs )
|
||||
{
|
||||
if(effect.id == 42 || !s->hasBonus(Selector::source(Bonus::CASTED_SPELL, effect.id)))//disrupting ray or not on the list - just add
|
||||
{
|
||||
s->bonuses.push_back(effect);
|
||||
s->addNewBonus(new Bonus(effect));
|
||||
BonusList sf;
|
||||
s->stackEffectToFeature(sf, effect);
|
||||
BOOST_FOREACH(const Bonus &fromEffect, sf)
|
||||
BOOST_FOREACH(Bonus *fromEffect, sf)
|
||||
{
|
||||
s->bonuses.push_back(fromEffect);
|
||||
s->addNewBonus(fromEffect);
|
||||
}
|
||||
}
|
||||
else //just actualize
|
||||
@ -1109,7 +1097,7 @@ DLL_EXPORT void StacksHealedOrResurrected::applyGs( CGameState *gs )
|
||||
changedStack->state.insert(ALIVE);
|
||||
if(healedStacks[g].lowLevelResurrection)
|
||||
changedStack->state.insert(SUMMONED);
|
||||
//changedStack->bonuses.push_back( makeFeature(HeroBonus::SUMMONED, HeroBonus::ONE_BATTLE, 0, 0, HeroBonus::BONUS_FROM_HERO) );
|
||||
//changedStack->addNewBonus( makeFeature(HeroBonus::SUMMONED, HeroBonus::ONE_BATTLE, 0, 0, HeroBonus::BONUS_FROM_HERO) );
|
||||
}
|
||||
//int missingHPfirst = changedStack->MaxHealth() - changedStack->firstHPleft;
|
||||
int res = std::min( healedStacks[g].healedHP / changedStack->MaxHealth() , changedStack->baseAmount - changedStack->count );
|
||||
@ -1127,9 +1115,10 @@ DLL_EXPORT void StacksHealedOrResurrected::applyGs( CGameState *gs )
|
||||
//removal of negative effects
|
||||
if(resurrected)
|
||||
{
|
||||
|
||||
for (BonusList::iterator it = changedStack->bonuses.begin(); it != changedStack->bonuses.end(); it++)
|
||||
{
|
||||
if(VLC->spellh->spells[it->id].positiveness < 0)
|
||||
if(VLC->spellh->spells[(*it)->id].positiveness < 0)
|
||||
{
|
||||
changedStack->bonuses.erase(it);
|
||||
}
|
||||
@ -1139,12 +1128,12 @@ DLL_EXPORT void StacksHealedOrResurrected::applyGs( CGameState *gs )
|
||||
BonusList tmpFeatures = changedStack->bonuses;
|
||||
changedStack->bonuses.clear();
|
||||
|
||||
BOOST_FOREACH(Bonus &b, tmpFeatures)
|
||||
BOOST_FOREACH(Bonus *b, tmpFeatures)
|
||||
{
|
||||
const CSpell *s = b.sourceSpell();
|
||||
const CSpell *s = b->sourceSpell();
|
||||
if(s && s->positiveness >= 0)
|
||||
{
|
||||
changedStack->bonuses.push_back(b);
|
||||
changedStack->addNewBonus(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -365,18 +365,18 @@ void CGameHandler::startBattle(const CArmedInstance *army1, const CArmedInstance
|
||||
{
|
||||
BonusList bl;
|
||||
hero1->getBonuses(bl, Selector::type(Bonus::OPENING_BATTLE_SPELL));
|
||||
BOOST_FOREACH (Bonus b, bl)
|
||||
BOOST_FOREACH (Bonus *b, bl)
|
||||
{
|
||||
handleSpellCasting(b.subtype, 3, -1, 0, hero1->tempOwner, NULL, hero2, b.val);
|
||||
handleSpellCasting(b->subtype, 3, -1, 0, hero1->tempOwner, NULL, hero2, b->val);
|
||||
}
|
||||
}
|
||||
if (hero2 && hero2->hasBonusOfType(Bonus::OPENING_BATTLE_SPELL))
|
||||
{
|
||||
BonusList bl;
|
||||
hero2->getBonuses(bl, Selector::type(Bonus::OPENING_BATTLE_SPELL));
|
||||
BOOST_FOREACH (Bonus b, bl)
|
||||
BOOST_FOREACH (Bonus *b, bl)
|
||||
{
|
||||
handleSpellCasting(b.subtype, 3, -1, 1, hero2->tempOwner, NULL, hero1, b.val);
|
||||
handleSpellCasting(b->subtype, 3, -1, 1, hero2->tempOwner, NULL, hero1, b->val);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1664,15 +1664,15 @@ void CGameHandler::setupBattle(BattleInfo * curB, int3 tile, const CArmedInstanc
|
||||
{
|
||||
if(town->subID == 0 && vstd::contains(town->builtBuildings,22)) //castle, brotherhood of sword built
|
||||
for(int g=0; g<stacks.size(); ++g)
|
||||
stacks[g]->bonuses.push_back(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, 2, Bonus::TOWN_STRUCTURE));
|
||||
stacks[g]->addNewBonus(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, 2, Bonus::TOWN_STRUCTURE));
|
||||
|
||||
else if(vstd::contains(town->builtBuildings,5)) //tavern is built
|
||||
for(int g=0; g<stacks.size(); ++g)
|
||||
stacks[g]->bonuses.push_back(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, 1, Bonus::TOWN_STRUCTURE));
|
||||
stacks[g]->addNewBonus(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, 1, Bonus::TOWN_STRUCTURE));
|
||||
|
||||
if(town->subID == 1 && vstd::contains(town->builtBuildings,21)) //rampart, fountain of fortune is present
|
||||
for(int g=0; g<stacks.size(); ++g)
|
||||
stacks[g]->bonuses.push_back(makeFeature(Bonus::LUCK, Bonus::ONE_BATTLE, 0, 2, Bonus::TOWN_STRUCTURE));
|
||||
stacks[g]->addNewBonus(makeFeature(Bonus::LUCK, Bonus::ONE_BATTLE, 0, 2, Bonus::TOWN_STRUCTURE));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1726,9 +1726,9 @@ void CGameHandler::setupBattle(BattleInfo * curB, int3 tile, const CArmedInstanc
|
||||
for(int g=0; g<stacks.size(); ++g) //+1 morale bonus for good creatures, -1 morale bonus for evil creatures
|
||||
{
|
||||
if (stacks[g]->type->isGood())
|
||||
stacks[g]->bonuses.push_back(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, 1, Bonus::TERRAIN_OVERLAY));
|
||||
stacks[g]->addNewBonus(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, 1, Bonus::TERRAIN_OVERLAY));
|
||||
else if (stacks[g]->type->isEvil())
|
||||
stacks[g]->bonuses.push_back(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, -1, Bonus::TERRAIN_OVERLAY));
|
||||
stacks[g]->addNewBonus(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, -1, Bonus::TERRAIN_OVERLAY));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1738,7 +1738,7 @@ void CGameHandler::setupBattle(BattleInfo * curB, int3 tile, const CArmedInstanc
|
||||
{
|
||||
if(stacks[g]->type->faction == -1) //+2 luck bonus for neutral creatures
|
||||
{
|
||||
stacks[g]->bonuses.push_back(makeFeature(Bonus::LUCK, Bonus::ONE_BATTLE, 0, 2, Bonus::TERRAIN_OVERLAY));
|
||||
stacks[g]->addNewBonus(makeFeature(Bonus::LUCK, Bonus::ONE_BATTLE, 0, 2, Bonus::TERRAIN_OVERLAY));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1748,9 +1748,9 @@ void CGameHandler::setupBattle(BattleInfo * curB, int3 tile, const CArmedInstanc
|
||||
for(int g=0; g<stacks.size(); ++g) //-1 morale bonus for good creatures, +1 morale bonus for evil creatures
|
||||
{
|
||||
if (stacks[g]->type->isGood())
|
||||
stacks[g]->bonuses.push_back(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, -1, Bonus::TERRAIN_OVERLAY));
|
||||
stacks[g]->addNewBonus(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, -1, Bonus::TERRAIN_OVERLAY));
|
||||
else if (stacks[g]->type->isEvil())
|
||||
stacks[g]->bonuses.push_back(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, 1, Bonus::TERRAIN_OVERLAY));
|
||||
stacks[g]->addNewBonus(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, 1, Bonus::TERRAIN_OVERLAY));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1758,8 +1758,8 @@ void CGameHandler::setupBattle(BattleInfo * curB, int3 tile, const CArmedInstanc
|
||||
{
|
||||
for(int g=0; g<stacks.size(); ++g) //no luck nor morale
|
||||
{
|
||||
stacks[g]->bonuses.push_back(makeFeature(Bonus::NO_MORALE, Bonus::ONE_BATTLE, 0, 0, Bonus::TERRAIN_OVERLAY));
|
||||
stacks[g]->bonuses.push_back(makeFeature(Bonus::NO_LUCK, Bonus::ONE_BATTLE, 0, 0, Bonus::TERRAIN_OVERLAY));
|
||||
stacks[g]->addNewBonus(makeFeature(Bonus::NO_MORALE, Bonus::ONE_BATTLE, 0, 0, Bonus::TERRAIN_OVERLAY));
|
||||
stacks[g]->addNewBonus(makeFeature(Bonus::NO_LUCK, Bonus::ONE_BATTLE, 0, 0, Bonus::TERRAIN_OVERLAY));
|
||||
}
|
||||
|
||||
const CGHeroInstance * cHero = NULL;
|
||||
@ -4213,11 +4213,11 @@ static std::vector<ui32> calculateResistedStacks(const CSpell * sp, const CGHero
|
||||
|
||||
bl.insert(bl.end(), b2.begin(), b2.end());
|
||||
|
||||
BOOST_FOREACH(Bonus bb, bl)
|
||||
BOOST_FOREACH(Bonus *bb, bl)
|
||||
{
|
||||
if( (bb.type == Bonus::SPELL_IMMUNITY && bb.subtype == sp->id || //100% sure spell immunity
|
||||
bb.type == Bonus::LEVEL_SPELL_IMMUNITY && bb.val >= sp->level) //some creature abilities have level 0
|
||||
&& bb.source != Bonus::CREATURE_ABILITY)
|
||||
if( (bb->type == Bonus::SPELL_IMMUNITY && bb->subtype == sp->id || //100% sure spell immunity
|
||||
bb->type == Bonus::LEVEL_SPELL_IMMUNITY && bb->val >= sp->level) //some creature abilities have level 0
|
||||
&& bb->source != Bonus::CREATURE_ABILITY)
|
||||
{
|
||||
ret.push_back((*it)->ID);
|
||||
continue;
|
||||
@ -5026,9 +5026,9 @@ void CGameHandler::handleAfterAttackCasting( const BattleAttack & bat )
|
||||
const CStack * attacker = gs->curB->getStack(bat.stackAttacking);
|
||||
if( attacker->hasBonusOfType(Bonus::SPELL_AFTER_ATTACK) )
|
||||
{
|
||||
BOOST_FOREACH(const Bonus & sf, attacker->getBonuses(Selector::type(Bonus::SPELL_AFTER_ATTACK)))
|
||||
BOOST_FOREACH(const Bonus *sf, attacker->getBonuses(Selector::type(Bonus::SPELL_AFTER_ATTACK)))
|
||||
{
|
||||
if (sf.type == Bonus::SPELL_AFTER_ATTACK)
|
||||
if (sf->type == Bonus::SPELL_AFTER_ATTACK)
|
||||
{
|
||||
const CStack * oneOfAttacked = NULL;
|
||||
for(int g=0; g<bat.bsa.size(); ++g)
|
||||
@ -5042,10 +5042,10 @@ void CGameHandler::handleAfterAttackCasting( const BattleAttack & bat )
|
||||
if(oneOfAttacked == NULL) //all attacked creatures have been killed
|
||||
return;
|
||||
|
||||
int spellID = sf.subtype;
|
||||
int spellLevel = sf.val;
|
||||
int chance = sf.additionalInfo % 1000;
|
||||
//int meleeRanged = sf.additionalInfo / 1000;
|
||||
int spellID = sf->subtype;
|
||||
int spellLevel = sf->val;
|
||||
int chance = sf->additionalInfo % 1000;
|
||||
//int meleeRanged = sf->additionalInfo / 1000;
|
||||
int destination = oneOfAttacked->position;
|
||||
//check if spell should be casted (probability handling)
|
||||
if( rand()%100 >= chance )
|
||||
|
Loading…
x
Reference in New Issue
Block a user