1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-12 02:28:11 +02:00

- build system update

- fixed gcc\clang warnings
This commit is contained in:
Ivan Savenko 2012-08-26 09:59:07 +00:00
parent d390113c23
commit d69f4b7632
7 changed files with 167 additions and 151 deletions

View File

@ -55,7 +55,7 @@ struct EnemyInfo
} }
}; };
bool isMoreProfitable(const EnemyInfo &ei1, const EnemyInfo& ei2) bool isMoreProfitable(const EnemyInfo &ei1, const EnemyInfo& ei2)
{ {
return (ei1.adi-ei1.adr) < (ei2.adi - ei2.adr); return (ei1.adi-ei1.adr) < (ei2.adi - ei2.adr);
} }
@ -175,68 +175,68 @@ void CStupidAI::battleStacksAttacked(const std::vector<BattleStackAttacked> & bs
print("battleStacksAttacked called"); print("battleStacksAttacked called");
} }
void CStupidAI::battleEnd(const BattleResult *br) void CStupidAI::battleEnd(const BattleResult *br)
{ {
print("battleEnd called"); print("battleEnd called");
} }
// void CStupidAI::battleResultsApplied() // void CStupidAI::battleResultsApplied()
// { // {
// print("battleResultsApplied called"); // print("battleResultsApplied called");
// } // }
void CStupidAI::battleNewRoundFirst(int round) void CStupidAI::battleNewRoundFirst(int round)
{ {
print("battleNewRoundFirst called"); print("battleNewRoundFirst called");
} }
void CStupidAI::battleNewRound(int round) void CStupidAI::battleNewRound(int round)
{ {
print("battleNewRound called"); print("battleNewRound called");
} }
void CStupidAI::battleStackMoved(const CStack * stack, std::vector<BattleHex> dest, int distance) void CStupidAI::battleStackMoved(const CStack * stack, std::vector<BattleHex> dest, int distance)
{ {
print("battleStackMoved called");; print("battleStackMoved called");;
} }
void CStupidAI::battleSpellCast(const BattleSpellCast *sc) void CStupidAI::battleSpellCast(const BattleSpellCast *sc)
{ {
print("battleSpellCast called"); print("battleSpellCast called");
} }
void CStupidAI::battleStacksEffectsSet(const SetStackEffect & sse) void CStupidAI::battleStacksEffectsSet(const SetStackEffect & sse)
{ {
print("battleStacksEffectsSet called"); print("battleStacksEffectsSet called");
} }
void CStupidAI::battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool Side) void CStupidAI::battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool Side)
{ {
print("battleStart called"); print("battleStart called");
side = Side; side = Side;
} }
void CStupidAI::battleStacksHealedRes(const std::vector<std::pair<ui32, ui32> > & healedStacks, bool lifeDrain, bool tentHeal, si32 lifeDrainFrom) void CStupidAI::battleStacksHealedRes(const std::vector<std::pair<ui32, ui32> > & healedStacks, bool lifeDrain, bool tentHeal, si32 lifeDrainFrom)
{ {
print("battleStacksHealedRes called"); print("battleStacksHealedRes called");
} }
void CStupidAI::battleNewStackAppeared(const CStack * stack) void CStupidAI::battleNewStackAppeared(const CStack * stack)
{ {
print("battleNewStackAppeared called"); print("battleNewStackAppeared called");
} }
void CStupidAI::battleObstaclesRemoved(const std::set<si32> & removedObstacles) void CStupidAI::battleObstaclesRemoved(const std::set<si32> & removedObstacles)
{ {
print("battleObstaclesRemoved called"); print("battleObstaclesRemoved called");
} }
void CStupidAI::battleCatapultAttacked(const CatapultAttack & ca) void CStupidAI::battleCatapultAttacked(const CatapultAttack & ca)
{ {
print("battleCatapultAttacked called"); print("battleCatapultAttacked called");
} }
void CStupidAI::battleStacksRemoved(const BattleStacksRemoved & bsr) void CStupidAI::battleStacksRemoved(const BattleStacksRemoved & bsr)
{ {
print("battleStacksRemoved called"); print("battleStacksRemoved called");
} }
@ -254,7 +254,7 @@ BattleAction CStupidAI::goTowards(const CStack * stack, BattleHex destination)
if(vstd::contains(avHexes, destination)) if(vstd::contains(avHexes, destination))
return BattleAction::makeMove(stack, destination); return BattleAction::makeMove(stack, destination);
auto destNeighbours = destination.neighbouringTiles(); auto destNeighbours = destination.neighbouringTiles();
if(vstd::contains_if(destNeighbours, [&](BattleHex n) { return stack->coversPos(destination); })) if(vstd::contains_if(destNeighbours, [&](BattleHex n) { return stack->coversPos(destination); }))
{ {
@ -278,8 +278,8 @@ BattleAction CStupidAI::goTowards(const CStack * stack, BattleHex destination)
auto distToDestNeighbour = [&](BattleHex hex) -> int auto distToDestNeighbour = [&](BattleHex hex) -> int
{ {
auto nearestNeighbourToHex = vstd::minElementByFun(destNeighbours, [&](BattleHex a) auto nearestNeighbourToHex = vstd::minElementByFun(destNeighbours, [&](BattleHex a)
{ {
return BattleHex::getDistance(a, hex); return BattleHex::getDistance(a, hex);
}); });
return BattleHex::getDistance(*nearestNeighbourToHex, hex); return BattleHex::getDistance(*nearestNeighbourToHex, hex);

View File

@ -349,7 +349,7 @@ namespace vstd
std::advance(itr, index); std::advance(itr, index);
return *itr; return *itr;
} }
template<typename Range, typename Predicate> template<typename Range, typename Predicate>
void erase_if(Range &vec, Predicate pred) void erase_if(Range &vec, Predicate pred)
{ {
@ -373,7 +373,7 @@ namespace vstd
auto minElementByFun(const ForwardRange& rng, ValueFunction vf) -> decltype(boost::begin(rng)) auto minElementByFun(const ForwardRange& rng, ValueFunction vf) -> decltype(boost::begin(rng))
{ {
typedef decltype(*boost::begin(rng)) ElemType; typedef decltype(*boost::begin(rng)) ElemType;
return boost::min_element(rng, [&] (const ElemType &lhs, const ElemType &rhs) -> bool return boost::min_element(rng, [&] (ElemType lhs, ElemType rhs) -> bool
{ {
return vf(lhs) < vf(rhs); return vf(lhs) < vf(rhs);
}); });

View File

@ -45,19 +45,19 @@ const CStack * BattleInfo::getNextStack() const
// void BattleInfo::getAccessibilityMap(bool *accessibility, bool twoHex, bool attackerOwned, bool addOccupiable, std::set<BattleHex> & occupyable, bool flying, const CStack * stackToOmmit) const // void BattleInfo::getAccessibilityMap(bool *accessibility, bool twoHex, bool attackerOwned, bool addOccupiable, std::set<BattleHex> & occupyable, bool flying, const CStack * stackToOmmit) const
// { // {
// memset(accessibility, 1, GameConstants::BFIELD_SIZE); //initialize array with trues // memset(accessibility, 1, GameConstants::BFIELD_SIZE); //initialize array with trues
// //
// //removing accessibility for side columns of hexes // //removing accessibility for side columns of hexes
// for(int v = 0; v < GameConstants::BFIELD_SIZE; ++v) // for(int v = 0; v < GameConstants::BFIELD_SIZE; ++v)
// { // {
// if( v % GameConstants::BFIELD_WIDTH == 0 || v % GameConstants::BFIELD_WIDTH == (GameConstants::BFIELD_WIDTH - 1) ) // if( v % GameConstants::BFIELD_WIDTH == 0 || v % GameConstants::BFIELD_WIDTH == (GameConstants::BFIELD_WIDTH - 1) )
// accessibility[v] = false; // accessibility[v] = false;
// } // }
// //
// for(ui32 g=0; g<stacks.size(); ++g) // for(ui32 g=0; g<stacks.size(); ++g)
// { // {
// if(!stacks[g]->alive() || (stackToOmmit && stacks[g]->ID==stackToOmmit->ID) || stacks[g]->position < 0) //we don't want to lock position of this stack (eg. if it's a turret) // if(!stacks[g]->alive() || (stackToOmmit && stacks[g]->ID==stackToOmmit->ID) || stacks[g]->position < 0) //we don't want to lock position of this stack (eg. if it's a turret)
// continue; // continue;
// //
// accessibility[stacks[g]->position] = false; // accessibility[stacks[g]->position] = false;
// if(stacks[g]->doubleWide()) //if it's a double hex creature // if(stacks[g]->doubleWide()) //if it's a double hex creature
// { // {
@ -76,7 +76,7 @@ const CStack * BattleInfo::getNextStack() const
// accessibility[hex] = false; // accessibility[hex] = false;
// } // }
// } // }
// //
// //walls // //walls
// if(siege > 0) // if(siege > 0)
// { // {
@ -85,7 +85,7 @@ const CStack * BattleInfo::getNextStack() const
// { // {
// accessibility[permanentlyLocked[b]] = false; // accessibility[permanentlyLocked[b]] = false;
// } // }
// //
// static const std::pair<int, BattleHex> lockedIfNotDestroyed[] = //(which part of wall, which hex is blocked if this part of wall is not destroyed // static const std::pair<int, BattleHex> lockedIfNotDestroyed[] = //(which part of wall, which hex is blocked if this part of wall is not destroyed
// {std::make_pair(2, BattleHex(182)), std::make_pair(3, BattleHex(130)), // {std::make_pair(2, BattleHex(182)), std::make_pair(3, BattleHex(130)),
// std::make_pair(4, BattleHex(62)), std::make_pair(5, BattleHex(29))}; // std::make_pair(4, BattleHex(62)), std::make_pair(5, BattleHex(29))};
@ -96,14 +96,14 @@ const CStack * BattleInfo::getNextStack() const
// accessibility[lockedIfNotDestroyed[b].second] = false; // accessibility[lockedIfNotDestroyed[b].second] = false;
// } // }
// } // }
// //
// //gate // //gate
// if(attackerOwned && si.wallState[7] < 3) //if it attacker's unit and gate is not destroyed // if(attackerOwned && si.wallState[7] < 3) //if it attacker's unit and gate is not destroyed
// { // {
// accessibility[95] = accessibility[96] = false; //block gate's hexes // accessibility[95] = accessibility[96] = false; //block gate's hexes
// } // }
// } // }
// //
// //occupyability // //occupyability
// if(addOccupiable && twoHex) // if(addOccupiable && twoHex)
// { // {
@ -131,7 +131,7 @@ const CStack * BattleInfo::getNextStack() const
// { // {
// if(flying && !lastPos) // if(flying && !lastPos)
// return true; // return true;
// //
// if(twoHex) // if(twoHex)
// { // {
// //if given hex is accessible and appropriate adjacent one is free too // //if given hex is accessible and appropriate adjacent one is free too
@ -146,13 +146,13 @@ const CStack * BattleInfo::getNextStack() const
// void BattleInfo::makeBFS(BattleHex start, bool *accessibility, BattleHex *predecessor, int *dists, bool twoHex, bool attackerOwned, bool flying, bool fillPredecessors) const //both pointers must point to the at least 187-elements int arrays // void BattleInfo::makeBFS(BattleHex start, bool *accessibility, BattleHex *predecessor, int *dists, bool twoHex, bool attackerOwned, bool flying, bool fillPredecessors) const //both pointers must point to the at least 187-elements int arrays
// { // {
// std::set<BattleHex> quicksands = getStoppers(!attackerOwned); // std::set<BattleHex> quicksands = getStoppers(!attackerOwned);
// //
// //inits // //inits
// for(int b=0; b<GameConstants::BFIELD_SIZE; ++b) // for(int b=0; b<GameConstants::BFIELD_SIZE; ++b)
// predecessor[b] = -1; // predecessor[b] = -1;
// for(int g=0; g<GameConstants::BFIELD_SIZE; ++g) // for(int g=0; g<GameConstants::BFIELD_SIZE; ++g)
// dists[g] = 100000000; // dists[g] = 100000000;
// //
// std::queue< std::pair<BattleHex, bool> > hexq; //bfs queue <hex, accessible> (second filed used only if fillPredecessors is true) // std::queue< std::pair<BattleHex, bool> > hexq; //bfs queue <hex, accessible> (second filed used only if fillPredecessors is true)
// hexq.push(std::make_pair(start, true)); // hexq.push(std::make_pair(start, true));
// dists[hexq.front().first] = 0; // dists[hexq.front().first] = 0;
@ -164,7 +164,7 @@ const CStack * BattleInfo::getNextStack() const
// hexq.pop(); // hexq.pop();
// if(curHex.first != start && !flying && vstd::contains(quicksands, curHex.first)) //walking stack can't step past the quicksands // if(curHex.first != start && !flying && vstd::contains(quicksands, curHex.first)) //walking stack can't step past the quicksands
// continue; // continue;
// //
// for(ui32 nr=0; nr<neighbours.size(); nr++) // for(ui32 nr=0; nr<neighbours.size(); nr++)
// { // {
// curNext = neighbours[nr]; //if(!accessibility[curNext] || (dists[curHex]+1)>=dists[curNext]) // curNext = neighbours[nr]; //if(!accessibility[curNext] || (dists[curHex]+1)>=dists[curNext])
@ -185,7 +185,7 @@ const CStack * BattleInfo::getNextStack() const
// } // }
// } // }
// }; // };
// //
BattleHex BattleInfo::getClosestTile (bool attackerOwned, int initialPos, std::set<BattleHex> & possibilities) const BattleHex BattleInfo::getClosestTile (bool attackerOwned, int initialPos, std::set<BattleHex> & possibilities) const
{ {
@ -224,18 +224,18 @@ BattleHex BattleInfo::getClosestTile (bool attackerOwned, int initialPos, std::s
int BattleInfo::getAvaliableHex(TCreature creID, bool attackerOwned, int initialPos) const int BattleInfo::getAvaliableHex(TCreature creID, bool attackerOwned, int initialPos) const
{ {
bool twoHex = VLC->creh->creatures[creID]->isDoubleWide(); bool twoHex = VLC->creh->creatures[creID]->isDoubleWide();
bool flying = VLC->creh->creatures[creID]->isFlying(); //bool flying = VLC->creh->creatures[creID]->isFlying();
int pos; int pos;
if (initialPos > -1) if (initialPos > -1)
pos = initialPos; pos = initialPos;
else //summon elementals depending on player side else //summon elementals depending on player side
{ {
if (attackerOwned) if (attackerOwned)
pos = 0; //top left pos = 0; //top left
else else
pos = GameConstants::BFIELD_WIDTH - 1; //top right pos = GameConstants::BFIELD_WIDTH - 1; //top right
} }
auto accessibility = getAccesibility(); auto accessibility = getAccesibility();
@ -255,7 +255,7 @@ int BattleInfo::getAvaliableHex(TCreature creID, bool attackerOwned, int initial
std::pair< std::vector<BattleHex>, int > BattleInfo::getPath(BattleHex start, BattleHex dest, const CStack *stack) std::pair< std::vector<BattleHex>, int > BattleInfo::getPath(BattleHex start, BattleHex dest, const CStack *stack)
{ {
auto reachability = getReachability(stack); auto reachability = getReachability(stack);
if(reachability.predecessors[dest] == -1) //cannot reach destination if(reachability.predecessors[dest] == -1) //cannot reach destination
{ {
return std::make_pair(std::vector<BattleHex>(), 0); return std::make_pair(std::vector<BattleHex>(), 0);
@ -450,16 +450,16 @@ CStack * BattleInfo::generateNewStack(const CStackBasicDescriptor &base, bool at
} }
// std::pair<const CStack *, BattleHex> BattleInfo::getNearestStack(const CStack * closest, boost::logic::tribool attackerOwned) const // std::pair<const CStack *, BattleHex> BattleInfo::getNearestStack(const CStack * closest, boost::logic::tribool attackerOwned) const
// { // {
// bool ac[GameConstants::BFIELD_SIZE]; // bool ac[GameConstants::BFIELD_SIZE];
// std::set<BattleHex> occupyable; // std::set<BattleHex> occupyable;
// //
// getAccessibilityMap(ac, closest->doubleWide(), closest->attackerOwned, false, occupyable, closest->hasBonusOfType(Bonus::FLYING), closest); // getAccessibilityMap(ac, closest->doubleWide(), closest->attackerOwned, false, occupyable, closest->hasBonusOfType(Bonus::FLYING), closest);
// //
// BattleHex predecessor[GameConstants::BFIELD_SIZE]; // BattleHex predecessor[GameConstants::BFIELD_SIZE];
// int dist[GameConstants::BFIELD_SIZE]; // int dist[GameConstants::BFIELD_SIZE];
// makeBFS(closest->position, ac, predecessor, dist, closest->doubleWide(), closest->attackerOwned, closest->hasBonusOfType(Bonus::FLYING), true); // makeBFS(closest->position, ac, predecessor, dist, closest->doubleWide(), closest->attackerOwned, closest->hasBonusOfType(Bonus::FLYING), true);
// //
// std::vector< std::pair< std::pair<int, int>, const CStack *> > stackPairs; //pairs <<distance, hex>, stack> // std::vector< std::pair< std::pair<int, int>, const CStack *> > stackPairs; //pairs <<distance, hex>, stack>
// for(int g=0; g<GameConstants::BFIELD_SIZE; ++g) // for(int g=0; g<GameConstants::BFIELD_SIZE; ++g)
// { // {
@ -473,12 +473,12 @@ CStack * BattleInfo::generateNewStack(const CStackBasicDescriptor &base, bool at
// stackPairs.push_back( std::make_pair( std::make_pair(dist[predecessor[g]], g), atG) ); // stackPairs.push_back( std::make_pair( std::make_pair(dist[predecessor[g]], g), atG) );
// } // }
// } // }
// //
// if(stackPairs.size() > 0) // if(stackPairs.size() > 0)
// { // {
// std::vector< std::pair< std::pair<int, int>, const CStack *> > minimalPairs; // std::vector< std::pair< std::pair<int, int>, const CStack *> > minimalPairs;
// minimalPairs.push_back(stackPairs[0]); // minimalPairs.push_back(stackPairs[0]);
// //
// for(int b=1; b<stackPairs.size(); ++b) // for(int b=1; b<stackPairs.size(); ++b)
// { // {
// if(stackPairs[b].first.first < minimalPairs[0].first.first) // if(stackPairs[b].first.first < minimalPairs[0].first.first)
@ -491,12 +491,12 @@ CStack * BattleInfo::generateNewStack(const CStackBasicDescriptor &base, bool at
// minimalPairs.push_back(stackPairs[b]); // minimalPairs.push_back(stackPairs[b]);
// } // }
// } // }
// //
// std::pair< std::pair<int, int>, const CStack *> minPair = minimalPairs[minimalPairs.size()/2]; // std::pair< std::pair<int, int>, const CStack *> minPair = minimalPairs[minimalPairs.size()/2];
// //
// return std::make_pair(minPair.second, predecessor[minPair.first.second]); // return std::make_pair(minPair.second, predecessor[minPair.first.second]);
// } // }
// //
// return std::make_pair<const CStack * , BattleHex>(NULL, BattleHex::INVALID); // return std::make_pair<const CStack * , BattleHex>(NULL, BattleHex::INVALID);
// } // }
ui32 BattleInfo::calculateSpellBonus(ui32 baseDamage, const CSpell * sp, const CGHeroInstance * caster, const CStack * affectedCreature) const ui32 BattleInfo::calculateSpellBonus(ui32 baseDamage, const CSpell * sp, const CGHeroInstance * caster, const CStack * affectedCreature) const
@ -584,7 +584,7 @@ ui32 BattleInfo::calculateHealedHP(const CGHeroInstance * caster, const CSpell *
int healedHealth; int healedHealth;
if (spell->id == Spells::SACRIFICE && sacrificedStack) if (spell->id == Spells::SACRIFICE && sacrificedStack)
healedHealth = (caster->getPrimSkillLevel(2) + sacrificedStack->MaxHealth() + spell->powers[caster->getSpellSchoolLevel(spell)]) * sacrificedStack->count; healedHealth = (caster->getPrimSkillLevel(2) + sacrificedStack->MaxHealth() + spell->powers[caster->getSpellSchoolLevel(spell)]) * sacrificedStack->count;
else else
healedHealth = caster->getPrimSkillLevel(2) * spell->power + spell->powers[caster->getSpellSchoolLevel(spell)]; healedHealth = caster->getPrimSkillLevel(2) * spell->power + spell->powers[caster->getSpellSchoolLevel(spell)];
healedHealth = calculateSpellBonus(healedHealth, spell, caster, stack); healedHealth = calculateSpellBonus(healedHealth, spell, caster, stack);
return std::min<ui32>(healedHealth, stack->MaxHealth() - stack->firstHPleft + (resurrect ? stack->baseAmount * stack->MaxHealth() : 0)); return std::min<ui32>(healedHealth, stack->MaxHealth() - stack->firstHPleft + (resurrect ? stack->baseAmount * stack->MaxHealth() : 0));
@ -610,9 +610,9 @@ const CStack * BattleInfo::battleGetStack(BattleHex pos, bool onlyAlive)
CStack * stack = NULL; CStack * stack = NULL;
for(ui32 g=0; g<stacks.size(); ++g) for(ui32 g=0; g<stacks.size(); ++g)
{ {
if(stacks[g]->position == pos if(stacks[g]->position == pos
|| (stacks[g]->doubleWide() || (stacks[g]->doubleWide()
&&( (stacks[g]->attackerOwned && stacks[g]->position-1 == pos) &&( (stacks[g]->attackerOwned && stacks[g]->position-1 == pos)
|| (!stacks[g]->attackerOwned && stacks[g]->position+1 == pos) ) || (!stacks[g]->attackerOwned && stacks[g]->position+1 == pos) )
) ) ) )
{ {
@ -633,7 +633,7 @@ const CGHeroInstance * BattleInfo::battleGetOwner(const CStack * stack) const
void BattleInfo::localInit() void BattleInfo::localInit()
{ {
belligerents[0]->battle = belligerents[1]->battle = this; belligerents[0]->battle = belligerents[1]->battle = this;
BOOST_FOREACH(CArmedInstance *b, belligerents) BOOST_FOREACH(CArmedInstance *b, belligerents)
b->attachTo(this); b->attachTo(this);
@ -767,7 +767,7 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, int terrain, int battlefieldTyp
curB->castSpells[0] = curB->castSpells[1] = 0; curB->castSpells[0] = curB->castSpells[1] = 0;
curB->sides[0] = armies[0]->tempOwner; curB->sides[0] = armies[0]->tempOwner;
curB->sides[1] = armies[1]->tempOwner; curB->sides[1] = armies[1]->tempOwner;
if(curB->sides[1] == 254) if(curB->sides[1] == 254)
curB->sides[1] = 255; curB->sides[1] = 255;
std::vector<CStack*> & stacks = (curB->stacks); std::vector<CStack*> & stacks = (curB->stacks);
@ -830,7 +830,7 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, int terrain, int battlefieldTyp
if(r.rand(1,100) <= 40) //put cliff-like obstacle if(r.rand(1,100) <= 40) //put cliff-like obstacle
{ {
RangeGenerator obidgen(0, ABSOLUTE_OBSTACLES_COUNT-1, ourRand); RangeGenerator obidgen(0, ABSOLUTE_OBSTACLES_COUNT-1, ourRand);
try try
{ {
auto obstPtr = make_shared<CObstacleInstance>(); auto obstPtr = make_shared<CObstacleInstance>();
@ -911,7 +911,7 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, int terrain, int battlefieldTyp
CGH::readBattlePositions(positions[3]["levels"], defenderTight); CGH::readBattlePositions(positions[3]["levels"], defenderTight);
CGH::readBattlePositions(positions[4]["levels"], attackerCreBank); CGH::readBattlePositions(positions[4]["levels"], attackerCreBank);
CGH::readBattlePositions(positions[5]["levels"], defenderCreBank); CGH::readBattlePositions(positions[5]["levels"], defenderCreBank);
BOOST_FOREACH (auto position, config["commanderPositions"]["field"].Vector()) BOOST_FOREACH (auto position, config["commanderPositions"]["field"].Vector())
{ {
commanderField.push_back (position.Float()); commanderField.push_back (position.Float());
@ -922,7 +922,7 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, int terrain, int battlefieldTyp
} }
//battleStartpos read //battleStartpos read
int k = 0; //stack serial int k = 0; //stack serial
for(TSlots::const_iterator i = armies[0]->Slots().begin(); i!=armies[0]->Slots().end(); i++, k++) for(TSlots::const_iterator i = armies[0]->Slots().begin(); i!=armies[0]->Slots().end(); i++, k++)
{ {
int pos; int pos;
@ -953,7 +953,7 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, int terrain, int battlefieldTyp
} }
//shifting positions of two-hex creatures //shifting positions of two-hex creatures
for(unsigned g=0; g<stacks.size(); ++g) for(unsigned g=0; g<stacks.size(); ++g)
{ {
//we should do that for creature bank too //we should do that for creature bank too
if(stacks[g]->doubleWide() && stacks[g]->attackerOwned) if(stacks[g]->doubleWide() && stacks[g]->attackerOwned)
@ -1211,8 +1211,8 @@ std::vector<ui32> BattleInfo::calculateResistedStacks(const CSpell * sp, const C
for(auto it = affectedCreatures.begin(); it != affectedCreatures.end(); ++it) for(auto it = affectedCreatures.begin(); it != affectedCreatures.end(); ++it)
{ {
if( (*it)->hasBonusOfType(Bonus::SPELL_IMMUNITY, sp->id) //100% sure spell immunity if( (*it)->hasBonusOfType(Bonus::SPELL_IMMUNITY, sp->id) //100% sure spell immunity
|| ( (*it)->count - 1 ) * (*it)->MaxHealth() + (*it)->firstHPleft || ( (*it)->count - 1 ) * (*it)->MaxHealth() + (*it)->firstHPleft
> >
usedSpellPower * 25 + sp->powers[spellLevel] usedSpellPower * 25 + sp->powers[spellLevel]
) )
{ {
@ -1244,7 +1244,7 @@ int BattleInfo::getIdForNewStack() const
if(stacks.size()) if(stacks.size())
{ {
//stacks vector may be sorted not by ID and they may be not contiguous -> find stack with max ID //stacks vector may be sorted not by ID and they may be not contiguous -> find stack with max ID
auto highestIDStack = *std::max_element(stacks.begin(), stacks.end(), auto highestIDStack = *std::max_element(stacks.begin(), stacks.end(),
[](const CStack *a, const CStack *b) { return a->ID < b->ID; }); [](const CStack *a, const CStack *b) { return a->ID < b->ID; });
return highestIDStack->ID + 1; return highestIDStack->ID + 1;
@ -1294,7 +1294,7 @@ BattleInfo::BattleInfo()
} }
CStack::CStack(const CStackInstance *Base, int O, int I, bool AO, int S) CStack::CStack(const CStackInstance *Base, int O, int I, bool AO, int S)
: base(Base), ID(I), owner(O), slot(S), attackerOwned(AO), : base(Base), ID(I), owner(O), slot(S), attackerOwned(AO),
counterAttacks(1) counterAttacks(1)
{ {
assert(base); assert(base);
@ -1360,7 +1360,7 @@ ui32 CStack::Speed( int turn /*= 0*/ , bool useBind /* = false*/) const
speed = ((100 + percentBonus) * speed)/100; speed = ((100 + percentBonus) * speed)/100;
//bind effect check - doesn't influence stack initiative //bind effect check - doesn't influence stack initiative
if (useBind && getEffect (Spells::BIND)) if (useBind && getEffect (Spells::BIND))
{ {
return 0; return 0;
} }
@ -1404,11 +1404,11 @@ const Bonus * CStack::getEffect( ui16 id, int turn /*= 0*/ ) const
} }
void CStack::stackEffectToFeature(std::vector<Bonus> & sf, const Bonus & sse) void CStack::stackEffectToFeature(std::vector<Bonus> & sf, const Bonus & sse)
{ {
si32 power = VLC->spellh->spells[sse.sid]->powers[sse.val]; si32 power = VLC->spellh->spells[sse.sid]->powers[sse.val];
switch(sse.sid) switch(sse.sid)
{ {
case 27: //shield case 27: //shield
sf.push_back(featureGenerator(Bonus::GENERAL_DAMAGE_REDUCTION, 0, power, sse.turnsRemain)); sf.push_back(featureGenerator(Bonus::GENERAL_DAMAGE_REDUCTION, 0, power, sse.turnsRemain));
sf.back().sid = sse.sid; sf.back().sid = sse.sid;
break; break;
@ -1627,7 +1627,7 @@ BattleHex CStack::occupiedHex(BattleHex assumedPos) const
return assumedPos - 1; return assumedPos - 1;
else else
return assumedPos + 1; return assumedPos + 1;
} }
else else
{ {
return BattleHex::INVALID; return BattleHex::INVALID;
@ -1819,12 +1819,12 @@ bool CStack::isMeleeAttackPossible(const CStack * attacker, const CStack * defen
&& BattleHex::mutualPosition(attackerPos, defenderPos + (defender->attackerOwned ? -1 : 1)) >= 0) && BattleHex::mutualPosition(attackerPos, defenderPos + (defender->attackerOwned ? -1 : 1)) >= 0)
|| (defender->doubleWide() && attacker->doubleWide()//back <=> back || (defender->doubleWide() && attacker->doubleWide()//back <=> back
&& BattleHex::mutualPosition(attackerPos + (attacker->attackerOwned ? -1 : 1), defenderPos + (defender->attackerOwned ? -1 : 1)) >= 0); && BattleHex::mutualPosition(attackerPos + (attacker->attackerOwned ? -1 : 1), defenderPos + (defender->attackerOwned ? -1 : 1)) >= 0);
} }
bool CStack::ableToRetaliate() const bool CStack::ableToRetaliate() const
{ {
return alive() return alive()
&& (counterAttacks > 0 || hasBonusOfType(Bonus::UNLIMITED_RETALIATIONS)) && (counterAttacks > 0 || hasBonusOfType(Bonus::UNLIMITED_RETALIATIONS))
&& !hasBonusOfType(Bonus::SIEGE_WEAPON) && !hasBonusOfType(Bonus::SIEGE_WEAPON)
&& !hasBonusOfType(Bonus::HYPNOTIZED) && !hasBonusOfType(Bonus::HYPNOTIZED)

View File

@ -8,6 +8,9 @@
#define RETURN_IF_NOT_BATTLE(X) if(!duringBattle()) {tlog1 << __FUNCTION__ << " called when no battle!\n"; return X; } #define RETURN_IF_NOT_BATTLE(X) if(!duringBattle()) {tlog1 << __FUNCTION__ << " called when no battle!\n"; return X; }
//allocate static member
const int ReachabilityInfo::INFINITE_DIST;
namespace SiegeStuffThatShouldBeMovedToHandlers // <=== TODO namespace SiegeStuffThatShouldBeMovedToHandlers // <=== TODO
{ {
static int lineToWallHex(int line) //returns hex with wall in given line (y coordinate) static int lineToWallHex(int line) //returns hex with wall in given line (y coordinate)
@ -31,7 +34,7 @@ namespace SiegeStuffThatShouldBeMovedToHandlers // <=== TODO
static int getMoatDamage(int townType) static int getMoatDamage(int townType)
{ {
//TODO move to config file //TODO move to config file
static const int dmgs[] = {70, 70, -1, static const int dmgs[] = {70, 70, -1,
90, 70, 90, 90, 70, 90,
70, 90, 70}; 70, 90, 70};
@ -41,26 +44,26 @@ namespace SiegeStuffThatShouldBeMovedToHandlers // <=== TODO
tlog1 << "No moat info for town " << townType << std::endl; tlog1 << "No moat info for town " << townType << std::endl;
return 0; return 0;
} }
static EWallParts::EWallParts hexToWallPart(BattleHex hex) static EWallParts::EWallParts hexToWallPart(BattleHex hex)
{ {
//potentially attackable parts of wall //potentially attackable parts of wall
// -2 - indestructible walls // -2 - indestructible walls
static const std::pair<int, EWallParts::EWallParts> attackable[] = static const std::pair<int, EWallParts::EWallParts> attackable[] =
{ {
std::make_pair(50, EWallParts::KEEP), std::make_pair(50, EWallParts::KEEP),
std::make_pair(183, EWallParts::BOTTOM_TOWER), std::make_pair(183, EWallParts::BOTTOM_TOWER),
std::make_pair(182, EWallParts::BOTTOM_WALL), std::make_pair(182, EWallParts::BOTTOM_WALL),
std::make_pair(130, EWallParts::BELOW_GATE), std::make_pair(130, EWallParts::BELOW_GATE),
std::make_pair(62, EWallParts::OVER_GATE), std::make_pair(62, EWallParts::OVER_GATE),
std::make_pair(29, EWallParts::UPPER_WAL), std::make_pair(29, EWallParts::UPPER_WAL),
std::make_pair(12, EWallParts::UPPER_TOWER), std::make_pair(12, EWallParts::UPPER_TOWER),
std::make_pair(95, EWallParts::GATE), std::make_pair(95, EWallParts::GATE),
std::make_pair(96, EWallParts::GATE), std::make_pair(96, EWallParts::GATE),
std::make_pair(45, EWallParts::INDESTRUCTIBLE_PART), std::make_pair(45, EWallParts::INDESTRUCTIBLE_PART),
std::make_pair(78, EWallParts::INDESTRUCTIBLE_PART), std::make_pair(78, EWallParts::INDESTRUCTIBLE_PART),
std::make_pair(112, EWallParts::INDESTRUCTIBLE_PART), std::make_pair(112, EWallParts::INDESTRUCTIBLE_PART),
std::make_pair(147, EWallParts::INDESTRUCTIBLE_PART) std::make_pair(147, EWallParts::INDESTRUCTIBLE_PART)
}; };
for(int g = 0; g < ARRAY_COUNT(attackable); ++g) for(int g = 0; g < ARRAY_COUNT(attackable); ++g)
{ {
@ -105,7 +108,7 @@ std::vector<shared_ptr<const CObstacleInstance> > CBattleInfoEssentials::battleG
{ {
std::vector<shared_ptr<const CObstacleInstance> > ret; std::vector<shared_ptr<const CObstacleInstance> > ret;
RETURN_IF_NOT_BATTLE(ret); RETURN_IF_NOT_BATTLE(ret);
if(!perspective) if(!perspective)
{ {
//if no particular perspective request, use default one //if no particular perspective request, use default one
@ -185,7 +188,7 @@ int CBattleInfoEssentials::battleGetMoatDmg() const
const CGTownInstance * CBattleInfoEssentials::battleGetDefendedTown() const const CGTownInstance * CBattleInfoEssentials::battleGetDefendedTown() const
{ {
RETURN_IF_NOT_BATTLE(nullptr); RETURN_IF_NOT_BATTLE(nullptr);
if(!getBattle() || getBattle()->town == NULL) if(!getBattle() || getBattle()->town == NULL)
return NULL; return NULL;
@ -307,14 +310,14 @@ bool CBattleInfoEssentials::battleCanFlee(int player) const
{ {
RETURN_IF_NOT_BATTLE(false); RETURN_IF_NOT_BATTLE(false);
ui8 mySide = playerToSide(player); ui8 mySide = playerToSide(player);
const CGHeroInstance *myHero = battleGetFightingHero(mySide), const CGHeroInstance *myHero = battleGetFightingHero(mySide),
*enemyHero = battleGetFightingHero(!mySide); *enemyHero = battleGetFightingHero(!mySide);
//current player have no hero //current player have no hero
if(!myHero) if(!myHero)
return false; return false;
//TODo use bonus system //TODo use bonus system
//ie. one of heroes is wearing shakles of war //ie. one of heroes is wearing shakles of war
if(NBonus::hasOfType(enemyHero, Bonus::ENEMY_CANT_ESCAPE) || NBonus::hasOfType(myHero, Bonus::ENEMY_CANT_ESCAPE)) if(NBonus::hasOfType(enemyHero, Bonus::ENEMY_CANT_ESCAPE) || NBonus::hasOfType(myHero, Bonus::ENEMY_CANT_ESCAPE))
return false; return false;
@ -326,7 +329,7 @@ bool CBattleInfoEssentials::battleCanFlee(int player) const
if(!(town->subID == 6 && town->hasBuilt(EBuilding::SPECIAL_1))) //not a stronghold with escape tunnel if(!(town->subID == 6 && town->hasBuilt(EBuilding::SPECIAL_1))) //not a stronghold with escape tunnel
return false; return false;
} }
return true; return true;
} }
@ -356,7 +359,7 @@ bool CBattleInfoEssentials::battleCanSurrender(int player) const
bool CBattleInfoEssentials::battleHasHero(ui8 side) const bool CBattleInfoEssentials::battleHasHero(ui8 side) const
{ {
RETURN_IF_NOT_BATTLE(false); RETURN_IF_NOT_BATTLE(false);
assert(side >= 0 && side < 2); assert(side < 2);
return getBattle()->heroes[side]; return getBattle()->heroes[side];
} }
@ -410,33 +413,33 @@ si8 CBattleInfoCallback::battleCanTeleportTo(const CStack * stack, BattleHex des
// std::vector<int> CBattleInfoCallback::battleGetDistances(const CStack * stack, BattleHex hex /*= BattleHex::INVALID*/, BattleHex * predecessors /*= NULL*/) // std::vector<int> CBattleInfoCallback::battleGetDistances(const CStack * stack, BattleHex hex /*= BattleHex::INVALID*/, BattleHex * predecessors /*= NULL*/)
// { // {
// // FIXME - This method is broken, hex argument is not used. However AI depends on that wrong behaviour. // // FIXME - This method is broken, hex argument is not used. However AI depends on that wrong behaviour.
// //
// if(!hex.isValid()) // if(!hex.isValid())
// hex = stack->position; // hex = stack->position;
// //
// std::vector<int> ret(GameConstants::BFIELD_SIZE, -1); //fill initial ret with -1's // std::vector<int> ret(GameConstants::BFIELD_SIZE, -1); //fill initial ret with -1's
// //
// if(!hex.isValid()) //stack has bad position? probably castle turret, return initial values (they can't move) // if(!hex.isValid()) //stack has bad position? probably castle turret, return initial values (they can't move)
// return ret; // return ret;
// //
// bool ac[GameConstants::BFIELD_SIZE] = {0}; // bool ac[GameConstants::BFIELD_SIZE] = {0};
// std::set<BattleHex> occupyable; // std::set<BattleHex> occupyable;
// getBattle()->getAccessibilityMap(ac, stack->doubleWide(), stack->attackerOwned, false, occupyable, stack->hasBonusOfType(Bonus::FLYING), stack); // getBattle()->getAccessibilityMap(ac, stack->doubleWide(), stack->attackerOwned, false, occupyable, stack->hasBonusOfType(Bonus::FLYING), stack);
// BattleHex pr[GameConstants::BFIELD_SIZE]; // BattleHex pr[GameConstants::BFIELD_SIZE];
// int dist[GameConstants::BFIELD_SIZE]; // int dist[GameConstants::BFIELD_SIZE];
// getBattle()->makeBFS(stack->position, ac, pr, dist, stack->doubleWide(), stack->attackerOwned, stack->hasBonusOfType(Bonus::FLYING), false); // getBattle()->makeBFS(stack->position, ac, pr, dist, stack->doubleWide(), stack->attackerOwned, stack->hasBonusOfType(Bonus::FLYING), false);
// //
// for(int i=0; i<GameConstants::BFIELD_SIZE; ++i) // for(int i=0; i<GameConstants::BFIELD_SIZE; ++i)
// { // {
// if(pr[i] != -1) // if(pr[i] != -1)
// ret[i] = dist[i]; // ret[i] = dist[i];
// } // }
// //
// if(predecessors) // if(predecessors)
// { // {
// memcpy(predecessors, pr, GameConstants::BFIELD_SIZE * sizeof(BattleHex)); // memcpy(predecessors, pr, GameConstants::BFIELD_SIZE * sizeof(BattleHex));
// } // }
// //
// return ret; // return ret;
// } // }
@ -457,7 +460,7 @@ std::set<BattleHex> CBattleInfoCallback::battleGetAttackedHexes(const CStack* at
} }
BOOST_FOREACH (BattleHex tile, at.friendlyCreaturePositions) BOOST_FOREACH (BattleHex tile, at.friendlyCreaturePositions)
{ {
if(const CStack * st = battleGetStackByPos(tile, true)) //friendly stacks can also be damaged by Dragon Breath if(battleGetStackByPos(tile, true)) //friendly stacks can also be damaged by Dragon Breath
{ {
attackedHexes.insert(tile); attackedHexes.insert(tile);
} }
@ -550,11 +553,11 @@ void CBattleInfoCallback::battleGetStackQueue(std::vector<const CStack *> &out,
}; };
//We'll split creatures with remaining movement to 4 buckets //We'll split creatures with remaining movement to 4 buckets
// [0] - turrets/catapult, // [0] - turrets/catapult,
// [1] - normal (unmoved) creatures, other war machines, // [1] - normal (unmoved) creatures, other war machines,
// [2] - waited cres that had morale, // [2] - waited cres that had morale,
// [3] - rest of waited cres // [3] - rest of waited cres
std::vector<const CStack *> phase[4]; std::vector<const CStack *> phase[4];
int toMove = 0; //how many stacks still has move int toMove = 0; //how many stacks still has move
const CStack *active = battleActiveStack(); const CStack *active = battleActiveStack();
@ -697,7 +700,7 @@ std::vector<BattleHex> CBattleInfoCallback::battleGetAvailableHexes(const CStack
// Available hexes are already present in ret vector. // Available hexes are already present in ret vector.
auto availableNeighbor = boost::find_if(ret, [=] (BattleHex availableHex) auto availableNeighbor = boost::find_if(ret, [=] (BattleHex availableHex)
{ return BattleHex::mutualPosition(hex, availableHex) >= 0; }); { return BattleHex::mutualPosition(hex, availableHex) >= 0; });
return availableNeighbor != ret.end(); return availableNeighbor != ret.end();
}; };
@ -733,7 +736,7 @@ bool CBattleInfoCallback::battleCanShoot(const CStack * stack, BattleHex dest) c
RETURN_IF_NOT_BATTLE(false); RETURN_IF_NOT_BATTLE(false);
if(battleTacticDist()) //no shooting during tactics if(battleTacticDist()) //no shooting during tactics
return false; return false;
const CStack *dst = battleGetStackByPos(dest); const CStack *dst = battleGetStackByPos(dest);
@ -757,17 +760,17 @@ bool CBattleInfoCallback::battleCanShoot(const CStack * stack, BattleHex dest) c
return false; return false;
} }
TDmgRange CBattleInfoCallback::calculateDmgRange(const CStack* attacker, const CStack* defender, bool shooting, TDmgRange CBattleInfoCallback::calculateDmgRange(const CStack* attacker, const CStack* defender, bool shooting,
ui8 charge, bool lucky, bool deathBlow, bool ballistaDoubleDmg) const ui8 charge, bool lucky, bool deathBlow, bool ballistaDoubleDmg) const
{ {
return calculateDmgRange(attacker, defender, attacker->count, shooting, charge, lucky, deathBlow, ballistaDoubleDmg); return calculateDmgRange(attacker, defender, attacker->count, shooting, charge, lucky, deathBlow, ballistaDoubleDmg);
} }
TDmgRange CBattleInfoCallback::calculateDmgRange( const CStack* attacker, const CStack* defender, TQuantity attackerCount, TDmgRange CBattleInfoCallback::calculateDmgRange( const CStack* attacker, const CStack* defender, TQuantity attackerCount,
bool shooting, ui8 charge, bool lucky, bool deathBlow, bool ballistaDoubleDmg ) const bool shooting, ui8 charge, bool lucky, bool deathBlow, bool ballistaDoubleDmg ) const
{ {
double additiveBonus = 1.0, multBonus = 1.0, double additiveBonus = 1.0, multBonus = 1.0,
minDmg = attacker->getMinDamage() * attackerCount, minDmg = attacker->getMinDamage() * attackerCount,
maxDmg = attacker->getMaxDamage() * attackerCount; maxDmg = attacker->getMaxDamage() * attackerCount;
if(attacker->getCreature()->idNumber == 149) //arrow turret if(attacker->getCreature()->idNumber == 149) //arrow turret
@ -794,8 +797,8 @@ TDmgRange CBattleInfoCallback::calculateDmgRange( const CStack* attacker, const
}; };
minDmg *= retreivePrimSkill(PrimarySkill::ATTACK) + 1; minDmg *= retreivePrimSkill(PrimarySkill::ATTACK) + 1;
maxDmg *= retreivePrimSkill(PrimarySkill::ATTACK) + 1; maxDmg *= retreivePrimSkill(PrimarySkill::ATTACK) + 1;
} }
int attackDefenceDifference = 0; int attackDefenceDifference = 0;
@ -925,8 +928,8 @@ TDmgRange CBattleInfoCallback::calculateDmgRange( const CStack* attacker, const
auto isAdvancedAirShield = [](const Bonus *bonus) auto isAdvancedAirShield = [](const Bonus *bonus)
{ {
return bonus->source == Bonus::SPELL_EFFECT return bonus->source == Bonus::SPELL_EFFECT
&& bonus->sid == Spells::AIR_SHIELD && bonus->sid == Spells::AIR_SHIELD
&& bonus->val >= SecSkillLevel::ADVANCED; && bonus->val >= SecSkillLevel::ADVANCED;
}; };
@ -982,8 +985,8 @@ TDmgRange CBattleInfoCallback::battleEstimateDamage(const CStack * attacker, con
RETURN_IF_NOT_BATTLE(std::make_pair(0, 0)); RETURN_IF_NOT_BATTLE(std::make_pair(0, 0));
const bool shooting = battleCanShoot(attacker, defender->position); const bool shooting = battleCanShoot(attacker, defender->position);
const ui8 mySide = !attacker->attackerOwned; //const ui8 mySide = !attacker->attackerOwned;
TDmgRange ret = calculateDmgRange(attacker, defender, shooting, 0, false, false, false); TDmgRange ret = calculateDmgRange(attacker, defender, shooting, 0, false, false, false);
if(retaliationDmg) if(retaliationDmg)
@ -1105,7 +1108,7 @@ ReachabilityInfo CBattleInfoCallback::makeBFS(const AccessibilityInfo &accessibi
//walking stack can't step past the quicksands //walking stack can't step past the quicksands
//TODO what if second hex of two-hex creature enters quicksand //TODO what if second hex of two-hex creature enters quicksand
if(curHex != params.startPosition && vstd::contains(quicksands, curHex)) if(curHex != params.startPosition && vstd::contains(quicksands, curHex))
continue; continue;
const int costToNeighbour = ret.distances[curHex] + 1; const int costToNeighbour = ret.distances[curHex] + 1;
@ -1298,7 +1301,7 @@ AttackableTiles CBattleInfoCallback::getPotentiallyAttackableHexes(const CStack*
BOOST_FOREACH (BattleHex tile, hexes) BOOST_FOREACH (BattleHex tile, hexes)
{ {
//friendly stacks can also be damaged by Dragon Breath //friendly stacks can also be damaged by Dragon Breath
if(const CStack * st = battleGetStackByPos(tile, true)) if(battleGetStackByPos(tile, true))
at.friendlyCreaturePositions.insert(tile); at.friendlyCreaturePositions.insert(tile);
} }
} }
@ -1402,7 +1405,7 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleIsImmune(const C
case Spells::BLESS: case Spells::BLESS:
case Spells::CURSE: //undeads are immune to bless & curse case Spells::CURSE: //undeads are immune to bless & curse
if (subject->hasBonusOfType(Bonus::UNDEAD)) if (subject->hasBonusOfType(Bonus::UNDEAD))
return ESpellCastProblem::STACK_IMMUNE_TO_SPELL; return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
break; break;
case Spells::HASTE: case Spells::HASTE:
case Spells::SLOW: case Spells::SLOW:
@ -1502,17 +1505,17 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleIsImmune(const C
immunities->remove_if([](const Bonus* b){ return b->source == Bonus::CREATURE_ABILITY; }); immunities->remove_if([](const Bonus* b){ return b->source == Bonus::CREATURE_ABILITY; });
} }
if(subject->hasBonusOfType(Bonus::SPELL_IMMUNITY, spell->id) if(subject->hasBonusOfType(Bonus::SPELL_IMMUNITY, spell->id)
|| ( immunities->size() > 0 && immunities->totalValue() >= spell->level && spell->level)) || ( immunities->size() > 0 && immunities->totalValue() >= spell->level && spell->level))
{ {
return ESpellCastProblem::STACK_IMMUNE_TO_SPELL; return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
} }
} }
else //no target stack on this tile else //no target stack on this tile
{ {
if(spell->getTargetType() == CSpell::CREATURE if(spell->getTargetType() == CSpell::CREATURE
|| (spell->getTargetType() == CSpell::CREATURE_EXPERT_MASSIVE || (spell->getTargetType() == CSpell::CREATURE_EXPERT_MASSIVE
&& mode == ECastingMode::HERO_CASTING && mode == ECastingMode::HERO_CASTING
&& caster && caster
&& caster->getSpellSchoolLevel(spell) < SecSkillLevel::EXPERT)) && caster->getSpellSchoolLevel(spell) < SecSkillLevel::EXPERT))
{ {
@ -1528,7 +1531,7 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastThisSpell
RETURN_IF_NOT_BATTLE(ESpellCastProblem::INVALID); RETURN_IF_NOT_BATTLE(ESpellCastProblem::INVALID);
const ui8 side = playerToSide(player); const ui8 side = playerToSide(player);
if(!battleDoWeKnowAbout(side)) if(!battleDoWeKnowAbout(side))
ESpellCastProblem::INVALID; return ESpellCastProblem::INVALID;
ESpellCastProblem::ESpellCastProblem genProblem = battleCanCastSpell(player, mode); ESpellCastProblem::ESpellCastProblem genProblem = battleCanCastSpell(player, mode);
if(genProblem != ESpellCastProblem::OK) if(genProblem != ESpellCastProblem::OK)
@ -1558,7 +1561,7 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastThisSpell
return ESpellCastProblem::ADVMAP_SPELL_INSTEAD_OF_BATTLE_SPELL; return ESpellCastProblem::ADVMAP_SPELL_INSTEAD_OF_BATTLE_SPELL;
//TODO? //TODO?
//if(NBonus::hasOfType(heroes[1-cside], Bonus::SPELL_IMMUNITY, spell->id)) //non - casting hero provides immunity for this spell //if(NBonus::hasOfType(heroes[1-cside], Bonus::SPELL_IMMUNITY, spell->id)) //non - casting hero provides immunity for this spell
// return ESpellCastProblem::SECOND_HEROS_SPELL_IMMUNITY; // return ESpellCastProblem::SECOND_HEROS_SPELL_IMMUNITY;
if(spell->isNegative()) if(spell->isNegative())
{ {
@ -1581,10 +1584,10 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastThisSpell
return ESpellCastProblem::SPELL_LEVEL_LIMIT_EXCEEDED; return ESpellCastProblem::SPELL_LEVEL_LIMIT_EXCEEDED;
//IDs of summon elemental spells (fire, earth, water, air) //IDs of summon elemental spells (fire, earth, water, air)
int spellIDs[] = { Spells::SUMMON_FIRE_ELEMENTAL, Spells::SUMMON_EARTH_ELEMENTAL, int spellIDs[] = { Spells::SUMMON_FIRE_ELEMENTAL, Spells::SUMMON_EARTH_ELEMENTAL,
Spells::SUMMON_WATER_ELEMENTAL, Spells::SUMMON_AIR_ELEMENTAL }; Spells::SUMMON_WATER_ELEMENTAL, Spells::SUMMON_AIR_ELEMENTAL };
//(fire, earth, water, air) elementals //(fire, earth, water, air) elementals
int creIDs[] = {114, 113, 115, 112}; int creIDs[] = {114, 113, 115, 112};
int arpos = vstd::find_pos(spellIDs, spell->id); int arpos = vstd::find_pos(spellIDs, spell->id);
if(arpos < ARRAY_COUNT(spellIDs)) if(arpos < ARRAY_COUNT(spellIDs))
@ -1688,8 +1691,8 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastThisSpell
if(spell->getTargetType() == CSpell::OBSTACLE) if(spell->getTargetType() == CSpell::OBSTACLE)
{ {
//isObstacleOnTile(dest) //isObstacleOnTile(dest)
// //
// //
//TODO //TODO
//assert that it's remove obstacle //assert that it's remove obstacle
//rules whether we can remove spell-created obstacle //rules whether we can remove spell-created obstacle
@ -1706,7 +1709,7 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastThisSpell
{ {
if(!deadStack && !aliveStack) if(!deadStack && !aliveStack)
return ESpellCastProblem::NO_APPROPRIATE_TARGET; return ESpellCastProblem::NO_APPROPRIATE_TARGET;
if(spell->id == Spells::ANIMATE_DEAD && deadStack && !deadStack->hasBonusOfType(Bonus::UNDEAD)) if(spell->id == Spells::ANIMATE_DEAD && deadStack && !deadStack->hasBonusOfType(Bonus::UNDEAD))
return ESpellCastProblem::NO_APPROPRIATE_TARGET; return ESpellCastProblem::NO_APPROPRIATE_TARGET;
if(deadStack && deadStack->owner != player) //you can resurrect only your own stacks //FIXME: it includes alive stacks as well if(deadStack && deadStack->owner != player) //you can resurrect only your own stacks //FIXME: it includes alive stacks as well
return ESpellCastProblem::NO_APPROPRIATE_TARGET; return ESpellCastProblem::NO_APPROPRIATE_TARGET;
@ -1733,7 +1736,7 @@ const CStack * CBattleInfoCallback::getStackIf(boost::function<bool(const CStack
RETURN_IF_NOT_BATTLE(nullptr); RETURN_IF_NOT_BATTLE(nullptr);
auto stacks = battleGetAllStacks(); auto stacks = battleGetAllStacks();
auto stackItr = range::find_if(stacks, pred); auto stackItr = range::find_if(stacks, pred);
return stackItr == stacks.end() return stackItr == stacks.end()
? NULL ? NULL
: *stackItr; : *stackItr;
} }
@ -1774,7 +1777,7 @@ TSpell CBattleInfoCallback::getRandomBeneficialSpell(const CStack * subject) con
{ {
if (spell->isPositive()) //only positive if (spell->isPositive()) //only positive
{ {
if (subject->hasBonusFrom(Bonus::SPELL_EFFECT, spell->id) if (subject->hasBonusFrom(Bonus::SPELL_EFFECT, spell->id)
|| battleCanCastThisSpellHere(subject->owner, spell, ECastingMode::CREATURE_ACTIVE_CASTING, subject->position) != ESpellCastProblem::OK) || battleCanCastThisSpellHere(subject->owner, spell, ECastingMode::CREATURE_ACTIVE_CASTING, subject->position) != ESpellCastProblem::OK)
continue; continue;
@ -1832,7 +1835,7 @@ TSpell CBattleInfoCallback::getRandomBeneficialSpell(const CStack * subject) con
{ {
auto kingMonster = getStackIf([&](const CStack *stack) //look for enemy, non-shooting stack auto kingMonster = getStackIf([&](const CStack *stack) //look for enemy, non-shooting stack
{ {
return stack->owner != subject->owner return stack->owner != subject->owner
&& (stack->hasBonus(Selector::type(Bonus::KING1) || Selector::type(Bonus::KING2) || Selector::type(Bonus::KING3))); && (stack->hasBonus(Selector::type(Bonus::KING1) || Selector::type(Bonus::KING2) || Selector::type(Bonus::KING3)));
}); });
@ -1906,7 +1909,7 @@ si8 CBattleInfoCallback::battleMaxSpellLevel() const
node = h; node = h;
//TODO else use battle node //TODO else use battle node
if(!node) if(!node)
return GameConstants::SPELL_LEVELS; return GameConstants::SPELL_LEVELS;
//We can't "just get value" - it'd be 0 if there are bonuses (and all would be blocked) //We can't "just get value" - it'd be 0 if there are bonuses (and all would be blocked)
auto b = node->getBonuses(Selector::type(Bonus::BLOCK_MAGIC_ABOVE)); auto b = node->getBonuses(Selector::type(Bonus::BLOCK_MAGIC_ABOVE));
@ -1994,8 +1997,8 @@ TStacks CPlayerBattleCallback::battleGetStacks(EStackOwnership whose /*= MINE_AN
RETURN_IF_NOT_BATTLE(ret); RETURN_IF_NOT_BATTLE(ret);
vstd::copy_if(battleGetAllStacks(), std::back_inserter(ret), [=](const CStack *s) -> bool vstd::copy_if(battleGetAllStacks(), std::back_inserter(ret), [=](const CStack *s) -> bool
{ {
const bool ownerMatches = (whose == MINE_AND_ENEMY) const bool ownerMatches = (whose == MINE_AND_ENEMY)
|| (whose == ONLY_MINE && s->owner == player) || (whose == ONLY_MINE && s->owner == player)
|| (whose == ONLY_ENEMY && s->owner != player); || (whose == ONLY_ENEMY && s->owner != player);
const bool alivenessMatches = s->alive() || !onlyAlive; const bool alivenessMatches = s->alive() || !onlyAlive;
return ownerMatches && alivenessMatches; return ownerMatches && alivenessMatches;

View File

@ -17,6 +17,7 @@ set(lib_SRCS
BattleHex.cpp BattleHex.cpp
BattleState.cpp BattleState.cpp
CArtHandler.cpp CArtHandler.cpp
CBattleCallback.cpp
CBuildingHandler.cpp CBuildingHandler.cpp
CCampaignHandler.cpp CCampaignHandler.cpp
CConsoleHandler.cpp CConsoleHandler.cpp
@ -29,7 +30,7 @@ set(lib_SRCS
CHeroHandler.cpp CHeroHandler.cpp
CLogger.cpp CLogger.cpp
CMapInfo.cpp CMapInfo.cpp
CModHandler.cpp CModHandler.cpp
CObjectHandler.cpp CObjectHandler.cpp
CObstacleInstance.cpp CObstacleInstance.cpp
Connection.cpp Connection.cpp

View File

@ -21,6 +21,8 @@ libvcmi_la_SOURCES = \
BattleState.h \ BattleState.h \
CArtHandler.cpp \ CArtHandler.cpp \
CArtHandler.h \ CArtHandler.h \
CBattleCallback.cpp \
CBattleCallback.h \
CBuildingHandler.cpp \ CBuildingHandler.cpp \
CBuildingHandler.h \ CBuildingHandler.h \
CCampaignHandler.cpp \ CCampaignHandler.cpp \

View File

@ -91,20 +91,20 @@ am_libvcmi_la_OBJECTS = libvcmi_la-CBinaryReader.lo \
libvcmi_la-CLodArchiveLoader.lo libvcmi_la-CMemoryStream.lo \ libvcmi_la-CLodArchiveLoader.lo libvcmi_la-CMemoryStream.lo \
libvcmi_la-CResourceLoader.lo libvcmi_la-BattleAction.lo \ libvcmi_la-CResourceLoader.lo libvcmi_la-BattleAction.lo \
libvcmi_la-BattleState.lo libvcmi_la-CArtHandler.lo \ libvcmi_la-BattleState.lo libvcmi_la-CArtHandler.lo \
libvcmi_la-CBuildingHandler.lo libvcmi_la-CCampaignHandler.lo \ libvcmi_la-CBattleCallback.lo libvcmi_la-CBuildingHandler.lo \
libvcmi_la-CConsoleHandler.lo libvcmi_la-CCreatureHandler.lo \ libvcmi_la-CCampaignHandler.lo libvcmi_la-CConsoleHandler.lo \
libvcmi_la-CCreatureSet.lo libvcmi_la-CDefObjInfoHandler.lo \ libvcmi_la-CCreatureHandler.lo libvcmi_la-CCreatureSet.lo \
libvcmi_la-CGameInterface.lo libvcmi_la-CGameState.lo \ libvcmi_la-CDefObjInfoHandler.lo libvcmi_la-CGameInterface.lo \
libvcmi_la-CGeneralTextHandler.lo libvcmi_la-CHeroHandler.lo \ libvcmi_la-CGameState.lo libvcmi_la-CGeneralTextHandler.lo \
libvcmi_la-CLogger.lo libvcmi_la-CMapInfo.lo \ libvcmi_la-CHeroHandler.lo libvcmi_la-CLogger.lo \
libvcmi_la-CModHandler.lo libvcmi_la-CObjectHandler.lo \ libvcmi_la-CMapInfo.lo libvcmi_la-CModHandler.lo \
libvcmi_la-CObstacleInstance.lo libvcmi_la-CSpellHandler.lo \ libvcmi_la-CObjectHandler.lo libvcmi_la-CObstacleInstance.lo \
libvcmi_la-CTownHandler.lo libvcmi_la-CThreadHelper.lo \ libvcmi_la-CSpellHandler.lo libvcmi_la-CTownHandler.lo \
libvcmi_la-Connection.lo libvcmi_la-HeroBonus.lo \ libvcmi_la-CThreadHelper.lo libvcmi_la-Connection.lo \
libvcmi_la-IGameCallback.lo libvcmi_la-JsonNode.lo \ libvcmi_la-HeroBonus.lo libvcmi_la-IGameCallback.lo \
libvcmi_la-NetPacksLib.lo libvcmi_la-ResourceSet.lo \ libvcmi_la-JsonNode.lo libvcmi_la-NetPacksLib.lo \
libvcmi_la-BattleHex.lo libvcmi_la-VCMI_Lib.lo \ libvcmi_la-ResourceSet.lo libvcmi_la-BattleHex.lo \
libvcmi_la-map.lo libvcmi_la-VCMI_Lib.lo libvcmi_la-map.lo
libvcmi_la_OBJECTS = $(am_libvcmi_la_OBJECTS) libvcmi_la_OBJECTS = $(am_libvcmi_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@) AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@ -313,6 +313,8 @@ libvcmi_la_SOURCES = \
BattleState.h \ BattleState.h \
CArtHandler.cpp \ CArtHandler.cpp \
CArtHandler.h \ CArtHandler.h \
CBattleCallback.cpp \
CBattleCallback.h \
CBuildingHandler.cpp \ CBuildingHandler.cpp \
CBuildingHandler.h \ CBuildingHandler.h \
CCampaignHandler.cpp \ CCampaignHandler.cpp \
@ -454,6 +456,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-BattleHex.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-BattleHex.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-BattleState.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-BattleState.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-CArtHandler.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-CArtHandler.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-CBattleCallback.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-CBinaryReader.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-CBinaryReader.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-CBuildingHandler.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-CBuildingHandler.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-CCampaignHandler.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvcmi_la-CCampaignHandler.Plo@am__quote@
@ -587,6 +590,13 @@ libvcmi_la-CArtHandler.lo: CArtHandler.cpp
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvcmi_la_CXXFLAGS) $(CXXFLAGS) -c -o libvcmi_la-CArtHandler.lo `test -f 'CArtHandler.cpp' || echo '$(srcdir)/'`CArtHandler.cpp @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvcmi_la_CXXFLAGS) $(CXXFLAGS) -c -o libvcmi_la-CArtHandler.lo `test -f 'CArtHandler.cpp' || echo '$(srcdir)/'`CArtHandler.cpp
libvcmi_la-CBattleCallback.lo: CBattleCallback.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvcmi_la_CXXFLAGS) $(CXXFLAGS) -MT libvcmi_la-CBattleCallback.lo -MD -MP -MF $(DEPDIR)/libvcmi_la-CBattleCallback.Tpo -c -o libvcmi_la-CBattleCallback.lo `test -f 'CBattleCallback.cpp' || echo '$(srcdir)/'`CBattleCallback.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libvcmi_la-CBattleCallback.Tpo $(DEPDIR)/libvcmi_la-CBattleCallback.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='CBattleCallback.cpp' object='libvcmi_la-CBattleCallback.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvcmi_la_CXXFLAGS) $(CXXFLAGS) -c -o libvcmi_la-CBattleCallback.lo `test -f 'CBattleCallback.cpp' || echo '$(srcdir)/'`CBattleCallback.cpp
libvcmi_la-CBuildingHandler.lo: CBuildingHandler.cpp libvcmi_la-CBuildingHandler.lo: CBuildingHandler.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvcmi_la_CXXFLAGS) $(CXXFLAGS) -MT libvcmi_la-CBuildingHandler.lo -MD -MP -MF $(DEPDIR)/libvcmi_la-CBuildingHandler.Tpo -c -o libvcmi_la-CBuildingHandler.lo `test -f 'CBuildingHandler.cpp' || echo '$(srcdir)/'`CBuildingHandler.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvcmi_la_CXXFLAGS) $(CXXFLAGS) -MT libvcmi_la-CBuildingHandler.lo -MD -MP -MF $(DEPDIR)/libvcmi_la-CBuildingHandler.Tpo -c -o libvcmi_la-CBuildingHandler.lo `test -f 'CBuildingHandler.cpp' || echo '$(srcdir)/'`CBuildingHandler.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libvcmi_la-CBuildingHandler.Tpo $(DEPDIR)/libvcmi_la-CBuildingHandler.Plo @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libvcmi_la-CBuildingHandler.Tpo $(DEPDIR)/libvcmi_la-CBuildingHandler.Plo