mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
Further work on bonus system.
This commit is contained in:
parent
b2a4d857b5
commit
27f83ea8c3
@ -484,11 +484,11 @@ void CArtHandler::getAllowedArts(std::vector<CArtifact*> &out, std::vector<CArti
|
||||
}
|
||||
void CArtHandler::giveArtBonus( int aid, Bonus::BonusType type, int val, int subtype, int valType, ILimiter * limiter )
|
||||
{
|
||||
Bonus added(Bonus::PERMANENT,type,Bonus::ARTIFACT,val,aid,subtype);
|
||||
added.valType = valType;
|
||||
added.limiter = limiter;
|
||||
Bonus *added = new Bonus(Bonus::PERMANENT,type,Bonus::ARTIFACT,val,aid,subtype);
|
||||
added->valType = valType;
|
||||
added->limiter.reset(limiter);
|
||||
if(type == Bonus::MORALE || Bonus::LUCK)
|
||||
added.description = "\n" + artifacts[aid]->Name() + (val > 0 ? " +" : " ") + boost::lexical_cast<std::string>(val);
|
||||
added->description = "\n" + artifacts[aid]->Name() + (val > 0 ? " +" : " ") + boost::lexical_cast<std::string>(val);
|
||||
artifacts[aid]->addNewBonus(added);
|
||||
}
|
||||
|
||||
|
@ -126,7 +126,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);
|
||||
Bonus *added = new Bonus(Bonus::PERMANENT, type, Bonus::CREATURE_ABILITY, val, idNumber, subtype, Bonus::BASE_NUMBER);
|
||||
addNewBonus(added);
|
||||
}
|
||||
// void CCreature::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const
|
||||
@ -364,7 +364,7 @@ void CCreatureHandler::loadCreatures()
|
||||
case '+': //add new ability
|
||||
{
|
||||
int creatureID;
|
||||
Bonus nsf;
|
||||
Bonus *nsf = new Bonus();
|
||||
si32 buf;
|
||||
std::string type;
|
||||
|
||||
@ -392,15 +392,15 @@ void CCreatureHandler::loadCreatures()
|
||||
tlog1 << "Error: invalid type " << type << " in cr_abils.txt" << std::endl;
|
||||
break;
|
||||
}
|
||||
nsf.type = it->second;
|
||||
nsf->type = it->second;
|
||||
|
||||
reader >> buf; nsf.val = buf;
|
||||
reader >> buf; nsf.subtype = buf;
|
||||
reader >> buf; nsf.additionalInfo = buf;
|
||||
nsf.source = Bonus::CREATURE_ABILITY;
|
||||
nsf.id = cre->idNumber;
|
||||
nsf.duration = Bonus::ONE_BATTLE;
|
||||
nsf.turnsRemain = 0;
|
||||
reader >> buf; nsf->val = buf;
|
||||
reader >> buf; nsf->subtype = buf;
|
||||
reader >> buf; nsf->additionalInfo = buf;
|
||||
nsf->source = Bonus::CREATURE_ABILITY;
|
||||
nsf->id = cre->idNumber;
|
||||
nsf->duration = Bonus::ONE_BATTLE;
|
||||
nsf->turnsRemain = 0;
|
||||
|
||||
cre->addNewBonus(nsf);
|
||||
break;
|
||||
|
@ -979,17 +979,17 @@ void CGHeroInstance::initObj()
|
||||
{
|
||||
blockVisit = true;
|
||||
speciality.growthsWithLevel = false;
|
||||
Bonus bonus;
|
||||
|
||||
if(!type)
|
||||
return; //TODO support prison
|
||||
|
||||
for (std::vector<SSpecialtyInfo>::const_iterator it = type->spec.begin(); it != type->spec.end(); it++)
|
||||
{
|
||||
bonus.val = it->val;
|
||||
bonus.id = id; //from the hero, speciality has no unique id
|
||||
bonus.duration = Bonus::PERMANENT;
|
||||
bonus.source = Bonus::HERO_SPECIAL;
|
||||
Bonus *bonus = new Bonus();
|
||||
bonus->val = it->val;
|
||||
bonus->id = id; //from the hero, speciality has no unique id
|
||||
bonus->duration = Bonus::PERMANENT;
|
||||
bonus->source = Bonus::HERO_SPECIAL;
|
||||
switch (it->type)
|
||||
{
|
||||
case 1:// creature speciality
|
||||
@ -1010,139 +1010,139 @@ void CGHeroInstance::initObj()
|
||||
}
|
||||
}
|
||||
|
||||
bonus.limiter = new CCreatureTypeLimiter (specCreature, true); //with upgrades
|
||||
bonus.type = Bonus::PRIMARY_SKILL;
|
||||
bonus.additionalInfo = it->additionalinfo;
|
||||
bonus.valType = Bonus::ADDITIVE_VALUE;
|
||||
bonus->limiter.reset(new CCreatureTypeLimiter (specCreature, true)); //with upgrades
|
||||
bonus->type = Bonus::PRIMARY_SKILL;
|
||||
bonus->additionalInfo = it->additionalinfo;
|
||||
bonus->valType = Bonus::ADDITIVE_VALUE;
|
||||
|
||||
bonus.subtype = PrimarySkill::ATTACK;
|
||||
bonus->subtype = PrimarySkill::ATTACK;
|
||||
speciality.addNewBonus(bonus);
|
||||
|
||||
bonus.subtype = PrimarySkill::DEFENSE;
|
||||
bonus->subtype = PrimarySkill::DEFENSE;
|
||||
speciality.addNewBonus(bonus);
|
||||
//values will be calculated later
|
||||
|
||||
bonus.type = Bonus::STACKS_SPEED;
|
||||
bonus.val = 1; //+1 speed
|
||||
bonus->type = Bonus::STACKS_SPEED;
|
||||
bonus->val = 1; //+1 speed
|
||||
speciality.addNewBonus(bonus);
|
||||
}
|
||||
break;
|
||||
case 2://secondary skill
|
||||
speciality.growthsWithLevel = true;
|
||||
bonus.type = Bonus::SPECIAL_SECONDARY_SKILL; //needs to be recalculated with level, based on this value
|
||||
bonus.valType = Bonus::BASE_NUMBER; // to receive nonzero value
|
||||
bonus.subtype = it->subtype; //skill id
|
||||
bonus.val = it->val; //value per level, in percent
|
||||
bonus->type = Bonus::SPECIAL_SECONDARY_SKILL; //needs to be recalculated with level, based on this value
|
||||
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.addNewBonus(bonus);
|
||||
switch (it->additionalinfo)
|
||||
{
|
||||
case 0: //normal
|
||||
bonus.valType = Bonus::PERCENT_TO_BASE;
|
||||
bonus->valType = Bonus::PERCENT_TO_BASE;
|
||||
break;
|
||||
case 1: //when it's navigation or there's no 'base' at all
|
||||
bonus.valType = Bonus::PERCENT_TO_ALL;
|
||||
bonus->valType = Bonus::PERCENT_TO_ALL;
|
||||
break;
|
||||
}
|
||||
bonus.type = Bonus::SECONDARY_SKILL_PREMY; //value will be calculated later
|
||||
bonus->type = Bonus::SECONDARY_SKILL_PREMY; //value will be calculated later
|
||||
speciality.addNewBonus(bonus);
|
||||
break;
|
||||
case 3://spell damage bonus, level dependant but calculated elsehwere
|
||||
bonus.type = Bonus::SPECIAL_SPELL_LEV;
|
||||
bonus.subtype = it->subtype;
|
||||
bonus->type = Bonus::SPECIAL_SPELL_LEV;
|
||||
bonus->subtype = it->subtype;
|
||||
speciality.addNewBonus(bonus);
|
||||
break;
|
||||
case 4://creature stat boost
|
||||
switch (it->subtype)
|
||||
{
|
||||
case 1://attack
|
||||
bonus.type = Bonus::PRIMARY_SKILL;
|
||||
bonus.subtype = PrimarySkill::ATTACK;
|
||||
bonus->type = Bonus::PRIMARY_SKILL;
|
||||
bonus->subtype = PrimarySkill::ATTACK;
|
||||
break;
|
||||
case 2://defense
|
||||
bonus.type = Bonus::PRIMARY_SKILL;
|
||||
bonus.subtype = PrimarySkill::DEFENSE;
|
||||
bonus->type = Bonus::PRIMARY_SKILL;
|
||||
bonus->subtype = PrimarySkill::DEFENSE;
|
||||
break;
|
||||
case 3:
|
||||
bonus.type = Bonus::CREATURE_DAMAGE;
|
||||
bonus.subtype = 0; //both min and max
|
||||
bonus->type = Bonus::CREATURE_DAMAGE;
|
||||
bonus->subtype = 0; //both min and max
|
||||
break;
|
||||
case 4://hp
|
||||
bonus.type = Bonus::STACK_HEALTH;
|
||||
bonus->type = Bonus::STACK_HEALTH;
|
||||
break;
|
||||
case 5:
|
||||
bonus.type = Bonus::STACKS_SPEED;
|
||||
bonus->type = Bonus::STACKS_SPEED;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
bonus.valType = Bonus::ADDITIVE_VALUE;
|
||||
bonus.limiter = new CCreatureTypeLimiter (*VLC->creh->creatures[it->additionalinfo], true);
|
||||
bonus->valType = Bonus::ADDITIVE_VALUE;
|
||||
bonus->limiter.reset(new CCreatureTypeLimiter (*VLC->creh->creatures[it->additionalinfo], true));
|
||||
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
|
||||
bonus->type = Bonus::SPECIFIC_SPELL_DAMAGE;
|
||||
bonus->valType = Bonus::BASE_NUMBER; // current spell system is screwed
|
||||
bonus->subtype = it->subtype; //spell id
|
||||
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
|
||||
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.addNewBonus(bonus);
|
||||
break;
|
||||
case 7://maxed mastery for spell
|
||||
bonus.type = Bonus::MAXED_SPELL;
|
||||
bonus.subtype = it->subtype; //spell i
|
||||
bonus->type = Bonus::MAXED_SPELL;
|
||||
bonus->subtype = it->subtype; //spell i
|
||||
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
|
||||
bonus->type = Bonus::SPECIAL_PECULIAR_ENCHANT;
|
||||
bonus->subtype = it->subtype; //spell id
|
||||
bonus->additionalInfo = it->additionalinfo;//0, 1 for Coronius
|
||||
speciality.addNewBonus(bonus);
|
||||
break;
|
||||
case 9://upgrade creatures
|
||||
{
|
||||
std::vector<CCreature*>* creatures = &VLC->creh->creatures;
|
||||
bonus.type = Bonus::SPECIAL_UPGRADE;
|
||||
bonus.subtype = it->subtype; //base id
|
||||
bonus.additionalInfo = it->additionalinfo; //target id
|
||||
bonus->type = Bonus::SPECIAL_UPGRADE;
|
||||
bonus->subtype = it->subtype; //base id
|
||||
bonus->additionalInfo = it->additionalinfo; //target id
|
||||
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
|
||||
bonus->subtype = *i; //propagate for regular upgrades of base creature
|
||||
speciality.addNewBonus(bonus);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 10://resource generation
|
||||
bonus.type = Bonus::GENERATE_RESOURCE;
|
||||
bonus.subtype = it->subtype;
|
||||
bonus->type = Bonus::GENERATE_RESOURCE;
|
||||
bonus->subtype = it->subtype;
|
||||
speciality.addNewBonus(bonus);
|
||||
break;
|
||||
case 11://starting skill with mastery (Adrienne)
|
||||
cb->changeSecSkill(id, it->val, it->additionalinfo); //simply give it and forget
|
||||
break;
|
||||
case 12://army speed
|
||||
bonus.type = Bonus::STACKS_SPEED;
|
||||
bonus->type = Bonus::STACKS_SPEED;
|
||||
speciality.addNewBonus(bonus);
|
||||
break;
|
||||
case 13://Dragon bonuses (Mutare)
|
||||
bonus.type = Bonus::PRIMARY_SKILL;
|
||||
bonus.valType = Bonus::ADDITIVE_VALUE;
|
||||
bonus->type = Bonus::PRIMARY_SKILL;
|
||||
bonus->valType = Bonus::ADDITIVE_VALUE;
|
||||
switch (it->subtype)
|
||||
{
|
||||
case 1:
|
||||
bonus.subtype = PrimarySkill::ATTACK;
|
||||
bonus->subtype = PrimarySkill::ATTACK;
|
||||
break;
|
||||
case 2:
|
||||
bonus.subtype = PrimarySkill::DEFENSE;
|
||||
bonus->subtype = PrimarySkill::DEFENSE;
|
||||
break;
|
||||
}
|
||||
bonus.limiter = new HasAnotherBonusLimiter(Bonus::DRAGON_NATURE);
|
||||
bonus->limiter.reset(new HasAnotherBonusLimiter(Bonus::DRAGON_NATURE));
|
||||
speciality.addNewBonus(bonus);
|
||||
break;
|
||||
default:
|
||||
@ -1247,9 +1247,9 @@ void CGHeroInstance::updateSkill(int which, int val)
|
||||
}
|
||||
else
|
||||
{
|
||||
Bonus bonus(Bonus::PERMANENT, Bonus::SECONDARY_SKILL_PREMY, id, skillVal, ID, which, Bonus::BASE_NUMBER);
|
||||
bonus.source = Bonus::SECONDARY_SKILL;
|
||||
addNewBonus (bonus);
|
||||
Bonus *bonus = new Bonus(Bonus::PERMANENT, Bonus::SECONDARY_SKILL_PREMY, id, skillVal, ID, which, Bonus::BASE_NUMBER);
|
||||
bonus->source = Bonus::SECONDARY_SKILL;
|
||||
addNewBonus(bonus);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1506,7 +1506,7 @@ int CGHeroInstance::getSpellCost(const CSpell *sp) const
|
||||
|
||||
void CGHeroInstance::pushPrimSkill(int which, int val)
|
||||
{
|
||||
addNewBonus(Bonus(Bonus::PERMANENT, Bonus::PRIMARY_SKILL, Bonus::HERO_BASE_SKILL, val, id, which));
|
||||
addNewBonus(new 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
|
||||
@ -2132,7 +2132,7 @@ void CGTownInstance::initObj()
|
||||
//add special bonuses from buildings
|
||||
if(subID == 4 && vstd::contains(builtBuildings, 17))
|
||||
{
|
||||
addNewBonus( Bonus(Bonus::PERMANENT, Bonus::DARKNESS, Bonus::TOWN_STRUCTURE, 20, 17) );
|
||||
addNewBonus(new Bonus(Bonus::PERMANENT, Bonus::DARKNESS, Bonus::TOWN_STRUCTURE, 20, 17) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3435,25 +3435,10 @@ int BattleInfo::calculateSpellDuration( const CSpell * spell, const CGHeroInstan
|
||||
}
|
||||
}
|
||||
|
||||
CStack * BattleInfo::generateNewStack(const CStackInstance &base, int stackID, bool attackerOwned, int slot, int /*TerrainTile::EterrainType*/ terrain, int position) const
|
||||
CStack * BattleInfo::generateNewStack(const CStackInstance &base, int stackID, bool attackerOwned, int slot, int position) const
|
||||
{
|
||||
CStack * ret = new CStack(&base, attackerOwned ? side1 : side2, stackID, attackerOwned, slot);
|
||||
|
||||
//TODO: bonus na bitwê z limiterem
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//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;
|
||||
|
||||
ret->position = position;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -236,7 +236,7 @@ struct DLL_EXPORT BattleInfo : public CBonusSystemNode
|
||||
void calculateCasualties(std::map<ui32,si32> *casualties) const; //casualties are array of maps size 2 (attacker, defeneder), maps are (crid => amount)
|
||||
std::set<CStack*> getAttackedCreatures(const CSpell * s, int skillLevel, ui8 attackerOwner, int destinationTile); //calculates stack affected by given spell
|
||||
static int calculateSpellDuration(const CSpell * spell, const CGHeroInstance * caster, int usedSpellPower);
|
||||
CStack * generateNewStack(const CStackInstance &base, int stackID, bool attackerOwned, int slot, int /*TerrainTile::EterrainType*/ terrain, int position) const; //helper for CGameHandler::setupBattle and spells addign new stacks to the battlefield
|
||||
CStack * generateNewStack(const CStackInstance &base, int stackID, bool attackerOwned, int slot, int position) const; //helper for CGameHandler::setupBattle and spells addign new stacks to the battlefield
|
||||
ui32 getSpellCost(const CSpell * sp, const CGHeroInstance * caster) const; //returns cost of given spell
|
||||
int hexToWallPart(int hex) const; //returns part of destructible wall / gate / keep under given hex or -1 if not found
|
||||
int lineToWallHex(int line) const; //returns hex with wall in given line
|
||||
@ -278,19 +278,19 @@ public:
|
||||
void stackEffectToFeature(BonusList & sf, const Bonus & sse);
|
||||
std::vector<si32> activeSpells() const; //returns vector of active spell IDs sorted by time of cast
|
||||
|
||||
static inline Bonus featureGenerator(Bonus::BonusType type, si16 subtype, si32 value, ui16 turnsRemain, si32 additionalInfo = 0, si32 limit = Bonus::NO_LIMIT)
|
||||
static inline Bonus *featureGenerator(Bonus::BonusType type, si16 subtype, si32 value, ui16 turnsRemain, si32 additionalInfo = 0, si32 limit = Bonus::NO_LIMIT)
|
||||
{
|
||||
Bonus hb(makeFeature(type, Bonus::N_TURNS, subtype, value, Bonus::SPELL_EFFECT, turnsRemain, additionalInfo));
|
||||
hb.effectRange = limit;
|
||||
hb.source = Bonus::CASTED_SPELL; //right?
|
||||
Bonus *hb = makeFeature(type, Bonus::N_TURNS, subtype, value, Bonus::SPELL_EFFECT, turnsRemain, additionalInfo);
|
||||
hb->effectRange = limit;
|
||||
hb->source = Bonus::CASTED_SPELL; //right?
|
||||
return hb;
|
||||
}
|
||||
|
||||
static inline Bonus featureGeneratorVT(Bonus::BonusType type, si16 subtype, si32 value, ui16 turnsRemain, ui8 valType)
|
||||
static inline Bonus *featureGeneratorVT(Bonus::BonusType type, si16 subtype, si32 value, ui16 turnsRemain, ui8 valType)
|
||||
{
|
||||
Bonus ret(makeFeature(type, Bonus::N_TURNS, subtype, value, Bonus::SPELL_EFFECT, turnsRemain));
|
||||
ret.valType = valType;
|
||||
ret.source = Bonus::CASTED_SPELL; //right?
|
||||
Bonus *ret(makeFeature(type, Bonus::N_TURNS, subtype, value, Bonus::SPELL_EFFECT, turnsRemain));
|
||||
ret->valType = valType;
|
||||
ret->source = Bonus::CASTED_SPELL; //right?
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -488,6 +488,12 @@ public:
|
||||
const_cast<T&>(data).serialize(*this,version);
|
||||
}
|
||||
template <typename T>
|
||||
void saveSerializable(const boost::shared_ptr<T> &data)
|
||||
{
|
||||
T *internalPtr = data.get();
|
||||
*this << internalPtr;
|
||||
}
|
||||
template <typename T>
|
||||
void saveSerializable(const std::vector<T> &data)
|
||||
{
|
||||
boost::uint32_t length = data.size();
|
||||
@ -735,6 +741,13 @@ public:
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
void loadSerializable(boost::shared_ptr<T> &data)
|
||||
{
|
||||
T *internalPtr;
|
||||
*this >> internalPtr;
|
||||
data.reset(internalPtr);
|
||||
}
|
||||
template <typename T>
|
||||
void loadSerializable(std::vector<T> &data)
|
||||
{
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include <boost/assign/list_of.hpp>
|
||||
#include "CCreatureSet.h"
|
||||
#include <boost/algorithm/string/trim.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include "../hch/CHeroHandler.h"
|
||||
|
||||
#define FOREACH_CONST_PARENT(pname) TCNodes parents; getParents(parents); BOOST_FOREACH(const CBonusSystemNode *pname, parents)
|
||||
#define FOREACH_PARENT(pname) TNodes parents; getParents(parents); BOOST_FOREACH(CBonusSystemNode *pname, parents)
|
||||
@ -99,49 +101,15 @@ void DLL_EXPORT BonusList::getBonuses(BonusList &out, const CSelector &selector,
|
||||
out.push_back(i);
|
||||
}
|
||||
|
||||
namespace HHLP
|
||||
{
|
||||
class SourceComp
|
||||
{
|
||||
public:
|
||||
Bonus::BonusSource src;
|
||||
SourceComp(Bonus::BonusSource _src) : src(_src)
|
||||
{
|
||||
}
|
||||
bool operator()(const Bonus * bon)
|
||||
{
|
||||
return bon->source == src;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void DLL_EXPORT BonusList::removeSpells(Bonus::BonusSource sourceType)
|
||||
{
|
||||
std::remove_if(begin(), end(), HHLP::SourceComp(sourceType));
|
||||
remove_if(Selector::sourceType(sourceType));
|
||||
}
|
||||
|
||||
void BonusList::limit(const CBonusSystemNode &node)
|
||||
{
|
||||
limit_start:
|
||||
for(iterator i = begin(); i != end(); i++)
|
||||
{
|
||||
Bonus *b = *i;
|
||||
if(b->limiter && b->limiter->limit(b, node))
|
||||
{
|
||||
iterator toErase = i;
|
||||
if(i != begin())
|
||||
{
|
||||
i--;
|
||||
erase(toErase);
|
||||
}
|
||||
else
|
||||
{
|
||||
erase(toErase);
|
||||
goto limit_start;
|
||||
}
|
||||
}
|
||||
}
|
||||
remove_if(boost::bind(&CBonusSystemNode::isLimitedOnUs, node, _1));
|
||||
}
|
||||
|
||||
int CBonusSystemNode::valOfBonuses(Bonus::BonusType type, const CSelector &selector) const
|
||||
@ -358,27 +326,36 @@ void CBonusSystemNode::popBonuses(const CSelector &s)
|
||||
child->popBonuses(s);
|
||||
}
|
||||
|
||||
void CBonusSystemNode::addNewBonus(const Bonus &b)
|
||||
{
|
||||
addNewBonus(new Bonus(b));
|
||||
}
|
||||
// void CBonusSystemNode::addNewBonus(const Bonus &b)
|
||||
// {
|
||||
// addNewBonus(new Bonus(b));
|
||||
// }
|
||||
|
||||
void CBonusSystemNode::addNewBonus(Bonus *b)
|
||||
{
|
||||
exportedBonuses.push_back(b);
|
||||
|
||||
if(!b->propagator)
|
||||
bonuses.push_back(b);
|
||||
else
|
||||
{
|
||||
//prop
|
||||
}
|
||||
whereToPropagate(b)->bonuses.push_back(b);
|
||||
}
|
||||
|
||||
void CBonusSystemNode::removeBonus(Bonus *b)
|
||||
{
|
||||
exportedBonuses -= b;
|
||||
//TODO: prop
|
||||
CBonusSystemNode *whereIsOurBonus = whereToPropagate(b);
|
||||
whereIsOurBonus->bonuses -= b;
|
||||
delNull(b);
|
||||
}
|
||||
|
||||
CBonusSystemNode * CBonusSystemNode::whereToPropagate(Bonus *b)
|
||||
{
|
||||
if(b->propagator)
|
||||
return b->propagator->getDestNode(this);
|
||||
else
|
||||
return this;
|
||||
}
|
||||
|
||||
bool CBonusSystemNode::isLimitedOnUs(Bonus *b) const
|
||||
{
|
||||
return b->limiter && b->limiter->limit(b, *this);
|
||||
}
|
||||
|
||||
int NBonus::valOf(const CBonusSystemNode *obj, Bonus::BonusType type, int subtype /*= -1*/)
|
||||
@ -445,8 +422,6 @@ Bonus::Bonus(ui8 Dur, ui8 Type, ui8 Src, si32 Val, ui32 ID, std::string Desc, si
|
||||
turnsRemain = 0;
|
||||
valType = ADDITIVE_VALUE;
|
||||
effectRange = NO_LIMIT;
|
||||
limiter = NULL;
|
||||
propagator = NULL;
|
||||
boost::algorithm::trim(description);
|
||||
}
|
||||
|
||||
@ -456,8 +431,6 @@ Bonus::Bonus(ui8 Dur, ui8 Type, ui8 Src, si32 Val, ui32 ID, si32 Subtype/*=-1*/,
|
||||
additionalInfo = -1;
|
||||
turnsRemain = 0;
|
||||
effectRange = NO_LIMIT;
|
||||
limiter = NULL;
|
||||
propagator = NULL;
|
||||
}
|
||||
|
||||
Bonus::Bonus()
|
||||
@ -467,8 +440,16 @@ Bonus::Bonus()
|
||||
turnsRemain = 0;
|
||||
valType = ADDITIVE_VALUE;
|
||||
effectRange = NO_LIMIT;
|
||||
limiter = NULL;
|
||||
propagator = NULL;
|
||||
}
|
||||
|
||||
Bonus::~Bonus()
|
||||
{
|
||||
}
|
||||
|
||||
Bonus * Bonus::addLimiter(ILimiter *Limiter)
|
||||
{
|
||||
limiter.reset(Limiter);
|
||||
return this;
|
||||
}
|
||||
|
||||
CSelector DLL_EXPORT operator&&(const CSelector &first, const CSelector &second)
|
||||
@ -525,6 +506,19 @@ namespace Selector
|
||||
}
|
||||
}
|
||||
|
||||
const CCreature * retrieveCreature(const CBonusSystemNode *node)
|
||||
{
|
||||
switch(node->nodeType)
|
||||
{
|
||||
case CBonusSystemNode::CREATURE:
|
||||
return (static_cast<const CCreature *>(node));
|
||||
case CBonusSystemNode::STACK:
|
||||
return (static_cast<const CStackInstance *>(node))->type;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
DLL_EXPORT std::ostream & operator<<(std::ostream &out, const BonusList &bonusList)
|
||||
{
|
||||
int i = 0;
|
||||
@ -621,4 +615,66 @@ bool HasAnotherBonusLimiter::limit( const Bonus *b, const CBonusSystemNode &node
|
||||
IPropagator::~IPropagator()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CBonusSystemNode * IPropagator::getDestNode(CBonusSystemNode *source)
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
CreatureNativeTerrainLimiter::CreatureNativeTerrainLimiter(int TerrainType)
|
||||
: terrainType(TerrainType)
|
||||
{
|
||||
}
|
||||
|
||||
CreatureNativeTerrainLimiter::CreatureNativeTerrainLimiter()
|
||||
{
|
||||
|
||||
}
|
||||
bool CreatureNativeTerrainLimiter::limit(const Bonus *b, const CBonusSystemNode &node) const
|
||||
{
|
||||
const CCreature *c = retrieveCreature(&node);
|
||||
return !c || VLC->heroh->nativeTerrains[c->faction] != terrainType; //drop bonus for non-creatures or non-native residents
|
||||
}
|
||||
|
||||
CreatureFactionLimiter::CreatureFactionLimiter(int Faction)
|
||||
: faction(Faction)
|
||||
{
|
||||
}
|
||||
|
||||
CreatureFactionLimiter::CreatureFactionLimiter()
|
||||
{
|
||||
}
|
||||
bool CreatureFactionLimiter::limit(const Bonus *b, const CBonusSystemNode &node) const
|
||||
{
|
||||
const CCreature *c = retrieveCreature(&node);
|
||||
return !c || c->faction != faction; //drop bonus for non-creatures or non-native residents
|
||||
}
|
||||
|
||||
CreatureAlignmentLimiter::CreatureAlignmentLimiter()
|
||||
{
|
||||
}
|
||||
|
||||
CreatureAlignmentLimiter::CreatureAlignmentLimiter(si8 Alignment)
|
||||
: alignment(Alignment)
|
||||
{
|
||||
}
|
||||
|
||||
bool CreatureAlignmentLimiter::limit(const Bonus *b, const CBonusSystemNode &node) const
|
||||
{
|
||||
const CCreature *c = retrieveCreature(&node);
|
||||
if(!c)
|
||||
return true;
|
||||
switch(alignment)
|
||||
{
|
||||
case GOOD:
|
||||
return !c->isGood(); //if not good -> return true (drop bonus)
|
||||
case NEUTRAL:
|
||||
return c->isEvil() || c->isGood();
|
||||
case EVIL:
|
||||
return !c->isEvil();
|
||||
default:
|
||||
tlog1 << "Warning: illegal alignment in limiter!\n";
|
||||
return true;
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
#include <list>
|
||||
#include <set>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/smart_ptr/shared_ptr.hpp>
|
||||
|
||||
/*
|
||||
* HeroBonus.h, part of VCMI engine
|
||||
@ -229,14 +230,15 @@ struct DLL_EXPORT Bonus
|
||||
si32 additionalInfo;
|
||||
ui8 effectRange; //if not NO_LIMIT, bonus will be ommitted by default
|
||||
|
||||
ILimiter *limiter;
|
||||
IPropagator *propagator;
|
||||
boost::shared_ptr<ILimiter> limiter;
|
||||
boost::shared_ptr<IPropagator> propagator;
|
||||
|
||||
std::string description;
|
||||
|
||||
Bonus(ui8 Dur, ui8 Type, ui8 Src, si32 Val, ui32 ID, std::string Desc, si32 Subtype=-1);
|
||||
Bonus(ui8 Dur, ui8 Type, ui8 Src, si32 Val, ui32 ID, si32 Subtype=-1, ui8 ValType = ADDITIVE_VALUE);
|
||||
Bonus();
|
||||
~Bonus();
|
||||
|
||||
// //comparison
|
||||
// bool operator==(const HeroBonus &other)
|
||||
@ -294,6 +296,8 @@ struct DLL_EXPORT Bonus
|
||||
const CSpell * sourceSpell() const;
|
||||
|
||||
std::string Description() const;
|
||||
|
||||
Bonus *addLimiter(ILimiter *Limiter); //returns this for convenient chain-calls
|
||||
};
|
||||
|
||||
struct DLL_EXPORT stackExperience : public Bonus
|
||||
@ -337,6 +341,7 @@ class DLL_EXPORT IPropagator
|
||||
{
|
||||
public:
|
||||
virtual ~IPropagator();
|
||||
virtual CBonusSystemNode *getDestNode(CBonusSystemNode *source);
|
||||
};
|
||||
|
||||
class DLL_EXPORT ILimiter
|
||||
@ -405,9 +410,12 @@ 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 addNewBonus(const Bonus &b); //b will copied
|
||||
void removeBonus(Bonus *b);
|
||||
|
||||
bool isLimitedOnUs(Bonus *b) const; //if bonus should be removed from list acquired from this node
|
||||
CBonusSystemNode *whereToPropagate(Bonus *b);
|
||||
|
||||
void popBonuses(const CSelector &s);
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
@ -432,16 +440,16 @@ namespace NBonus
|
||||
};
|
||||
|
||||
//generates HeroBonus from given data
|
||||
inline Bonus makeFeature(Bonus::BonusType type, ui8 duration, si16 subtype, si32 value, Bonus::BonusSource source, ui16 turnsRemain = 0, si32 additionalInfo = 0)
|
||||
inline Bonus* makeFeature(Bonus::BonusType type, ui8 duration, si16 subtype, si32 value, Bonus::BonusSource source, ui16 turnsRemain = 0, si32 additionalInfo = 0)
|
||||
{
|
||||
Bonus sf;
|
||||
sf.type = type;
|
||||
sf.duration = duration;
|
||||
sf.source = source;
|
||||
sf.turnsRemain = turnsRemain;
|
||||
sf.subtype = subtype;
|
||||
sf.val = value;
|
||||
sf.additionalInfo = additionalInfo;
|
||||
Bonus* sf = new Bonus();
|
||||
sf->type = type;
|
||||
sf->duration = duration;
|
||||
sf->source = source;
|
||||
sf->turnsRemain = turnsRemain;
|
||||
sf->subtype = subtype;
|
||||
sf->val = value;
|
||||
sf->additionalInfo = additionalInfo;
|
||||
|
||||
return sf;
|
||||
}
|
||||
@ -497,7 +505,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class CWillLastTurns
|
||||
class DLL_EXPORT CWillLastTurns
|
||||
{
|
||||
public:
|
||||
int turnsRequested;
|
||||
@ -515,7 +523,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class CCreatureTypeLimiter : public ILimiter //affect only stacks of given creature (and optionally it's upgrades)
|
||||
class DLL_EXPORT CCreatureTypeLimiter : public ILimiter //affect only stacks of given creature (and optionally it's upgrades)
|
||||
{
|
||||
public:
|
||||
const CCreature *creature;
|
||||
@ -532,14 +540,14 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class HasAnotherBonusLimiter : public ILimiter //applies only to nodes that have another bonus working
|
||||
class DLL_EXPORT HasAnotherBonusLimiter : public ILimiter //applies only to nodes that have another bonus working
|
||||
{
|
||||
public:
|
||||
TBonusType type;
|
||||
TBonusSubtype subtype;
|
||||
ui8 isSubtypeRelevant; //check for subtype only if this is true
|
||||
|
||||
HasAnotherBonusLimiter(TBonusType bonus);
|
||||
HasAnotherBonusLimiter(TBonusType bonus = Bonus::NONE);
|
||||
HasAnotherBonusLimiter(TBonusType bonus, TBonusSubtype _subtype);
|
||||
|
||||
bool limit(const Bonus *b, const CBonusSystemNode &node) const OVERRIDE;
|
||||
@ -550,6 +558,53 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_EXPORT CreatureNativeTerrainLimiter : public ILimiter //applies only to creatures that are on their native terrain
|
||||
{
|
||||
public:
|
||||
si8 terrainType;
|
||||
CreatureNativeTerrainLimiter();
|
||||
CreatureNativeTerrainLimiter(int TerrainType);
|
||||
|
||||
bool limit(const Bonus *b, const CBonusSystemNode &node) const OVERRIDE;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & terrainType;
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_EXPORT CreatureFactionLimiter : public ILimiter //applies only to creatures of given faction
|
||||
{
|
||||
public:
|
||||
si8 faction;
|
||||
CreatureFactionLimiter();
|
||||
CreatureFactionLimiter(int TerrainType);
|
||||
|
||||
bool limit(const Bonus *b, const CBonusSystemNode &node) const OVERRIDE;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & faction;
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_EXPORT CreatureAlignmentLimiter : public ILimiter //applies only to creatures of given alignment
|
||||
{
|
||||
public:
|
||||
si8 alignment;
|
||||
CreatureAlignmentLimiter();
|
||||
CreatureAlignmentLimiter(si8 Alignment);
|
||||
|
||||
bool limit(const Bonus *b, const CBonusSystemNode &node) const OVERRIDE;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & alignment;
|
||||
}
|
||||
};
|
||||
|
||||
const CCreature *retrieveCreature(const CBonusSystemNode *node);
|
||||
|
||||
namespace Selector
|
||||
{
|
||||
extern DLL_EXPORT CSelectFieldEqual<TBonusType> type;
|
||||
|
@ -664,17 +664,17 @@ DLL_EXPORT void NewTurn::applyGs( CGameState *gs )
|
||||
case DOUBLE_GROWTH:
|
||||
b->val = 100;
|
||||
b->type = Bonus::CREATURE_GROWTH_PERCENT;
|
||||
b->limiter = new CCreatureTypeLimiter(*VLC->creh->creatures[creatureid], false);
|
||||
b->limiter.reset(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->limiter.reset(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->limiter.reset(new CCreatureTypeLimiter(*VLC->creh->creatures[42], true));
|
||||
break;
|
||||
case PLAGUE:
|
||||
b->val = -100; //no basic creatures
|
||||
@ -985,8 +985,8 @@ DLL_EXPORT void BattleSpellCast::applyGs( CGameState *gs )
|
||||
creID = 112; //air elemental
|
||||
break;
|
||||
}
|
||||
const int3 & tile = gs->curB->tile;
|
||||
TerrainTile::EterrainType ter = gs->map->terrain[tile.x][tile.y][tile.z].tertype;
|
||||
// const int3 & tile = gs->curB->tile;
|
||||
// TerrainTile::EterrainType ter = gs->map->terrain[tile.x][tile.y][tile.z].tertype;
|
||||
|
||||
int pos; //position of stack on the battlefield - to be calculated
|
||||
|
||||
@ -1004,7 +1004,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);
|
||||
CStack * summonedStack = gs->curB->generateNewStack(CStackInstance(creID, h->getPrimSkillLevel(2) * VLC->spellh->spells[id].powers[skill], h), gs->curB->stacks.size(), !side, 255, pos);
|
||||
summonedStack->state.insert(SUMMONED);
|
||||
//summonedStack->addNewBonus( makeFeature(HeroBonus::SUMMONED, HeroBonus::ONE_BATTLE, 0, 0, HeroBonus::BONUS_FROM_HERO) );
|
||||
|
||||
|
@ -75,6 +75,10 @@ void registerTypes1(Serializer &s)
|
||||
//end of objects
|
||||
s.template registerType<ILimiter>();
|
||||
s.template registerType<CCreatureTypeLimiter>();
|
||||
s.template registerType<HasAnotherBonusLimiter>();
|
||||
s.template registerType<CreatureNativeTerrainLimiter>();
|
||||
s.template registerType<CreatureFactionLimiter>();
|
||||
s.template registerType<CreatureAlignmentLimiter>();
|
||||
}
|
||||
|
||||
template<typename Serializer> DLL_EXPORT
|
||||
|
@ -314,7 +314,9 @@ struct DLL_EXPORT Mapa : public CMapHeader
|
||||
{
|
||||
h & static_cast<CMapHeader&>(*this);
|
||||
h & rumors & allowedSpell & allowedAbilities & allowedArtifact & allowedHeroes & events & grailPos;
|
||||
h & monsters & heroesToBeat & artInstances; //hopefully serialization is now automagical?
|
||||
h & monsters;
|
||||
h & heroesToBeat;
|
||||
h & artInstances; //hopefully serialization is now automagical?
|
||||
|
||||
//TODO: viccondetails
|
||||
if(h.saving)
|
||||
|
@ -1478,7 +1478,7 @@ void CGameHandler::setupBattle(BattleInfo * curB, int3 tile, const CArmedInstanc
|
||||
else
|
||||
pos = attackerLoose[army1->stacksCount()-1][k];
|
||||
|
||||
CStack * stack = curB->generateNewStack(i->second, stacks.size(), true, i->first, gs->map->terrain[tile.x][tile.y][tile.z].tertype, pos);
|
||||
CStack * stack = curB->generateNewStack(i->second, stacks.size(), true, i->first, pos);
|
||||
stacks.push_back(stack);
|
||||
}
|
||||
|
||||
@ -1493,7 +1493,7 @@ void CGameHandler::setupBattle(BattleInfo * curB, int3 tile, const CArmedInstanc
|
||||
else
|
||||
pos = defenderLoose[army2->stacksCount()-1][k];
|
||||
|
||||
CStack * stack = curB->generateNewStack(i->second, stacks.size(), false, i->first, gs->map->terrain[tile.x][tile.y][tile.z].tertype, pos);
|
||||
CStack * stack = curB->generateNewStack(i->second, stacks.size(), false, i->first, pos);
|
||||
stacks.push_back(stack);
|
||||
}
|
||||
|
||||
@ -1514,17 +1514,17 @@ void CGameHandler::setupBattle(BattleInfo * curB, int3 tile, const CArmedInstanc
|
||||
{
|
||||
if(hero1->getArt(13)) //ballista
|
||||
{
|
||||
CStack * stack = curB->generateNewStack(CStackInstance(146, 1, hero1), stacks.size(), true, 255, gs->map->terrain[tile.x][tile.y][tile.z].tertype, 52);
|
||||
CStack * stack = curB->generateNewStack(CStackInstance(146, 1, hero1), stacks.size(), true, 255, 52);
|
||||
stacks.push_back(stack);
|
||||
}
|
||||
if(hero1->getArt(14)) //ammo cart
|
||||
{
|
||||
CStack * stack = curB->generateNewStack(CStackInstance(148, 1, hero1), stacks.size(), true, 255, gs->map->terrain[tile.x][tile.y][tile.z].tertype, 18);
|
||||
CStack * stack = curB->generateNewStack(CStackInstance(148, 1, hero1), stacks.size(), true, 255, 18);
|
||||
stacks.push_back(stack);
|
||||
}
|
||||
if(hero1->getArt(15)) //first aid tent
|
||||
{
|
||||
CStack * stack = curB->generateNewStack(CStackInstance(147, 1, hero1), stacks.size(), true, 255, gs->map->terrain[tile.x][tile.y][tile.z].tertype, 154);
|
||||
CStack * stack = curB->generateNewStack(CStackInstance(147, 1, hero1), stacks.size(), true, 255, 154);
|
||||
stacks.push_back(stack);
|
||||
}
|
||||
}
|
||||
@ -1533,23 +1533,23 @@ void CGameHandler::setupBattle(BattleInfo * curB, int3 tile, const CArmedInstanc
|
||||
//defending hero shouldn't receive ballista (bug #551)
|
||||
if(hero2->getArt(13) && !town) //ballista
|
||||
{
|
||||
CStack * stack = curB->generateNewStack(CStackInstance(146, 1, hero2), stacks.size(), false, 255, gs->map->terrain[tile.x][tile.y][tile.z].tertype, 66);
|
||||
CStack * stack = curB->generateNewStack(CStackInstance(146, 1, hero2), stacks.size(), false, 255, 66);
|
||||
stacks.push_back(stack);
|
||||
}
|
||||
if(hero2->getArt(14)) //ammo cart
|
||||
{
|
||||
CStack * stack = curB->generateNewStack(CStackInstance(148, 1, hero1), stacks.size(), false, 255, gs->map->terrain[tile.x][tile.y][tile.z].tertype, 32);
|
||||
CStack * stack = curB->generateNewStack(CStackInstance(148, 1, hero1), stacks.size(), false, 255, 32);
|
||||
stacks.push_back(stack);
|
||||
}
|
||||
if(hero2->getArt(15)) //first aid tent
|
||||
{
|
||||
CStack * stack = curB->generateNewStack(CStackInstance(147, 1, hero2), stacks.size(), false, 255, gs->map->terrain[tile.x][tile.y][tile.z].tertype, 168);
|
||||
CStack * stack = curB->generateNewStack(CStackInstance(147, 1, hero2), stacks.size(), false, 255, 168);
|
||||
stacks.push_back(stack);
|
||||
}
|
||||
}
|
||||
if(town && hero1 && town->hasFort()) //catapult
|
||||
{
|
||||
CStack * stack = curB->generateNewStack(CStackInstance(145, 1, hero1), stacks.size(), true, 255, gs->map->terrain[tile.x][tile.y][tile.z].tertype, 120);
|
||||
CStack * stack = curB->generateNewStack(CStackInstance(145, 1, hero1), stacks.size(), true, 255, 120);
|
||||
stacks.push_back(stack);
|
||||
}
|
||||
//war machines added
|
||||
@ -1559,14 +1559,14 @@ void CGameHandler::setupBattle(BattleInfo * curB, int3 tile, const CArmedInstanc
|
||||
|
||||
case 3: //castle
|
||||
{//lower tower / upper tower
|
||||
CStack * stack = curB->generateNewStack(CStackInstance(149, 1, hero2), stacks.size(), false, 255, gs->map->terrain[tile.x][tile.y][tile.z].tertype, -4);
|
||||
CStack * stack = curB->generateNewStack(CStackInstance(149, 1, hero2), stacks.size(), false, 255, -4);
|
||||
stacks.push_back(stack);
|
||||
stack = curB->generateNewStack(CStackInstance(149, 1, hero2), stacks.size(), false, 255, gs->map->terrain[tile.x][tile.y][tile.z].tertype, -3);
|
||||
stack = curB->generateNewStack(CStackInstance(149, 1, hero2), stacks.size(), false, 255, -3);
|
||||
stacks.push_back(stack);
|
||||
}
|
||||
case 2: //citadel
|
||||
{//main tower
|
||||
CStack * stack = curB->generateNewStack(CStackInstance(149, 1, hero2), stacks.size(), false, 255, gs->map->terrain[tile.x][tile.y][tile.z].tertype, -2);
|
||||
CStack * stack = curB->generateNewStack(CStackInstance(149, 1, hero2), stacks.size(), false, 255, -2);
|
||||
stacks.push_back(stack);
|
||||
}
|
||||
}
|
||||
@ -1676,8 +1676,7 @@ void CGameHandler::setupBattle(BattleInfo * curB, int3 tile, const CArmedInstanc
|
||||
}
|
||||
}
|
||||
|
||||
//giving terrain premies for heroes & stacks
|
||||
|
||||
//giving terrain overalay premies
|
||||
int bonusSubtype = -1;
|
||||
switch(terType)
|
||||
{
|
||||
@ -1703,86 +1702,47 @@ void CGameHandler::setupBattle(BattleInfo * curB, int3 tile, const CArmedInstanc
|
||||
}
|
||||
|
||||
{ //common part for cases 9, 14, 15, 16, 17
|
||||
const CGHeroInstance * cHero = NULL;
|
||||
for(int i=0; i<2; ++i)
|
||||
{
|
||||
if(i == 0) cHero = hero1;
|
||||
else cHero = hero2;
|
||||
|
||||
if(cHero == NULL) continue;
|
||||
|
||||
GiveBonus gs;
|
||||
gs.bonus = Bonus(Bonus::ONE_BATTLE, Bonus::MAGIC_SCHOOL_SKILL, Bonus::OBJECT, 3, -1, "", bonusSubtype);
|
||||
gs.id = cHero->id;
|
||||
|
||||
sendAndApply(&gs);
|
||||
}
|
||||
|
||||
curB->addNewBonus(new Bonus(Bonus::ONE_BATTLE, Bonus::MAGIC_SCHOOL_SKILL, Bonus::TERRAIN_OVERLAY, 3, -1, "", bonusSubtype));
|
||||
break;
|
||||
}
|
||||
|
||||
case 18: //holy ground
|
||||
{
|
||||
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]->addNewBonus(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, 1, Bonus::TERRAIN_OVERLAY));
|
||||
else if (stacks[g]->type->isEvil())
|
||||
stacks[g]->addNewBonus(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, -1, Bonus::TERRAIN_OVERLAY));
|
||||
}
|
||||
curB->addNewBonus(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, +1, Bonus::TERRAIN_OVERLAY)->addLimiter(new CreatureAlignmentLimiter(GOOD)));
|
||||
curB->addNewBonus(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, -1, Bonus::TERRAIN_OVERLAY)->addLimiter(new CreatureAlignmentLimiter(EVIL)));
|
||||
break;
|
||||
}
|
||||
case 19: //clover field
|
||||
{
|
||||
for(int g=0; g<stacks.size(); ++g)
|
||||
{
|
||||
if(stacks[g]->type->faction == -1) //+2 luck bonus for neutral creatures
|
||||
{
|
||||
stacks[g]->addNewBonus(makeFeature(Bonus::LUCK, Bonus::ONE_BATTLE, 0, 2, Bonus::TERRAIN_OVERLAY));
|
||||
}
|
||||
}
|
||||
{ //+2 luck bonus for neutral creatures
|
||||
curB->addNewBonus(makeFeature(Bonus::LUCK, Bonus::ONE_BATTLE, 0, +2, Bonus::TERRAIN_OVERLAY)->addLimiter(new CreatureFactionLimiter(-1)));
|
||||
break;
|
||||
}
|
||||
case 20: //evil fog
|
||||
{
|
||||
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]->addNewBonus(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, -1, Bonus::TERRAIN_OVERLAY));
|
||||
else if (stacks[g]->type->isEvil())
|
||||
stacks[g]->addNewBonus(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, 1, Bonus::TERRAIN_OVERLAY));
|
||||
}
|
||||
curB->addNewBonus(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, -1, Bonus::TERRAIN_OVERLAY)->addLimiter(new CreatureAlignmentLimiter(GOOD)));
|
||||
curB->addNewBonus(makeFeature(Bonus::MORALE, Bonus::ONE_BATTLE, 0, +1, Bonus::TERRAIN_OVERLAY)->addLimiter(new CreatureAlignmentLimiter(EVIL)));
|
||||
break;
|
||||
}
|
||||
case 22: //cursed ground
|
||||
{
|
||||
for(int g=0; g<stacks.size(); ++g) //no luck nor morale
|
||||
{
|
||||
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;
|
||||
for(int i=0; i<2; ++i) //blocking spells above level 1
|
||||
{
|
||||
if(i == 0) cHero = hero1;
|
||||
else cHero = hero2;
|
||||
|
||||
if(cHero == NULL) continue;
|
||||
|
||||
GiveBonus gs;
|
||||
gs.bonus = Bonus(Bonus::ONE_BATTLE, Bonus::BLOCK_SPELLS_ABOVE_LEVEL, Bonus::OBJECT, 1, -1, "", bonusSubtype);
|
||||
gs.id = cHero->id;
|
||||
|
||||
sendAndApply(&gs);
|
||||
}
|
||||
|
||||
curB->addNewBonus(makeFeature(Bonus::NO_MORALE, Bonus::ONE_BATTLE, 0, 0, Bonus::TERRAIN_OVERLAY));
|
||||
curB->addNewBonus(makeFeature(Bonus::NO_LUCK, Bonus::ONE_BATTLE, 0, 0, Bonus::TERRAIN_OVERLAY));
|
||||
curB->addNewBonus(makeFeature(Bonus::BLOCK_SPELLS_ABOVE_LEVEL, Bonus::ONE_BATTLE, 0, 1, Bonus::TERRAIN_OVERLAY));
|
||||
break;
|
||||
}
|
||||
}
|
||||
//overlay premies given
|
||||
|
||||
//premies given
|
||||
//native terrain bonuses
|
||||
int terrain = this->getTile(tile)->tertype;
|
||||
if(town) //during siege always take premies for native terrain of faction
|
||||
terrain = VLC->heroh->nativeTerrains[town->town->typeID];
|
||||
|
||||
ILimiter *nativeTerrain = new CreatureNativeTerrainLimiter(terrain);
|
||||
curB->addNewBonus(makeFeature(Bonus::STACKS_SPEED, Bonus::ONE_BATTLE, 0, 1, Bonus::TERRAIN_NATIVE)->addLimiter(nativeTerrain));
|
||||
curB->addNewBonus(makeFeature(Bonus::PRIMARY_SKILL, Bonus::ONE_BATTLE, PrimarySkill::ATTACK, 1, Bonus::TERRAIN_NATIVE)->addLimiter(nativeTerrain));
|
||||
curB->addNewBonus(makeFeature(Bonus::PRIMARY_SKILL, Bonus::ONE_BATTLE, PrimarySkill::DEFENSE, 1, Bonus::TERRAIN_NATIVE)->addLimiter(nativeTerrain));
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//send info about battles
|
||||
BattleStart bs;
|
||||
|
Loading…
Reference in New Issue
Block a user