Attached Files | kb-projected-attack-result-256.bmp [^] (239,158 bytes) 2012-05-07 17:06
show-kills-on-hover-over-enemy-stack.patch [^] (44,710 bytes) 2012-06-15 14:33 [Show Content] [Hide Content]Index: lib/IGameCallback.cpp
===================================================================
--- lib/IGameCallback.cpp (revision 2753)
+++ lib/IGameCallback.cpp (working copy)
@@ -199,7 +199,7 @@
return gs->curB->battlefieldType;
}
-// int CBattleInfoCallback::battleGetObstaclesAtTile(BattleHex tile) //returns bitfield
+// int CBattleInfoCallback::battleGetObstaclesAtTile(BattleHex tile) //returns bitfield
// {
// //TODO - write
// return -1;
@@ -294,7 +294,7 @@
}
}
-std::vector<BattleHex> CBattleInfoCallback::battleGetAvailableHexes(const CStack * stack, bool addOccupiable, std::vector<BattleHex> * attackable)
+std::vector<BattleHex> CBattleInfoCallback::battleGetAvailableHexes(const CStack * stack, bool addOccupiable, std::vector<BattleHex> * attackable, bool ignoreTactics)
{
//boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
if(!gs->curB)
@@ -302,7 +302,7 @@
tlog2<<"battleGetAvailableHexes called when there is no battle!"<<std::endl;
return std::vector<BattleHex>();
}
- return gs->curB->getAccessibility(stack, addOccupiable, attackable);
+ return gs->curB->getAccessibility(stack, addOccupiable, attackable, false, ignoreTactics);
//return gs->battleGetRange(ID);
}
@@ -435,7 +435,7 @@
return 0;
//TODO move to config file
- static const int dmgs[] = {70, 70, -1,
+ static const int dmgs[] = {70, 70, -1,
90, 70, 90,
70, 90, 70};
if(gs->curB->town->subID < ARRAY_COUNT(dmgs))
@@ -444,7 +444,7 @@
}
CGameState * CPrivilagedInfoCallback::gameState ()
-{
+{
return gs;
}
@@ -499,7 +499,7 @@
double distance = pos.dist2d(int3(xd,yd,pos.z)) - 0.5;
if(distance <= radious)
{
- if(player < 0
+ if(player < 0
|| (mode == 1 && team->fogOfWarMap[xd][yd][pos.z]==0)
|| (mode == -1 && team->fogOfWarMap[xd][yd][pos.z]==1)
)
@@ -523,7 +523,7 @@
std::vector<int> floors;
if(level == -1)
{
-
+
for (int xd = 0; xd <= gs->map->width - 1; xd++)
for(int b=0; b<gs->map->twoLevel + 1; ++b) //if gs->map->twoLevel is false then false (0) + 1 is 1, if it's true (1) then we have 2
{
@@ -798,7 +798,7 @@
bool CGameInfoCallback::getHeroInfo( const CGObjectInstance *hero, InfoAboutHero &dest ) const
{
const CGHeroInstance *h = dynamic_cast<const CGHeroInstance *>(hero);
-
+
ERROR_RET_VAL_IF(!h, "That's not a hero!", false);
ERROR_RET_VAL_IF(!isVisible(h->getPosition(false)), "That hero is not visible!", false);
@@ -878,7 +878,7 @@
// const CArmedInstance *armi = dynamic_cast<const CArmedInstance*>(obj);
// if(!armi)
// return NULL;
-// else
+// else
// return armi;
// }
@@ -938,7 +938,7 @@
ret.resize(gs->players[player].availableHeroes.size());
std::copy(gs->players[player].availableHeroes.begin(),gs->players[player].availableHeroes.end(),ret.begin());
return ret;
-}
+}
const TerrainTile * CGameInfoCallback::getTile( int3 tile, bool verbose) const
{
@@ -996,7 +996,7 @@
else if(ID == 6) //shipyard
{
const TerrainTile *tile = getTile(t->bestLocation());
-
+
if(!tile || tile->tertype != TerrainTile::water )
ret = EBuildingState::NO_WATER; //lack of water
}
@@ -1079,7 +1079,7 @@
int ret = 0;
const PlayerState *p = gs->getPlayer(player);
ERROR_RET_VAL_IF(!p, "No such player!", -1);
-
+
if(includeGarrisoned)
return p->heroes.size();
else
@@ -1135,7 +1135,7 @@
{
for (size_t j = 0; j < (*i).second.towns.size(); ++j)
{
- if ((*i).first==player
+ if ((*i).first==player
|| (isVisible((*i).second.towns[j],player) && !onlyOur))
{
ret.push_back((*i).second.towns[j]);
Index: lib/BattleState.cpp
===================================================================
--- lib/BattleState.cpp (revision 2753)
+++ lib/BattleState.cpp (working copy)
@@ -107,7 +107,7 @@
{
for(ui32 g=0; g<stacks.size(); ++g)
{
- if(stacks[g]->position == tileID
+ if(stacks[g]->position == tileID
|| (stacks[g]->doubleWide() && stacks[g]->attackerOwned && stacks[g]->position-1 == tileID)
|| (stacks[g]->doubleWide() && !stacks[g]->attackerOwned && stacks[g]->position+1 == tileID))
{
@@ -234,8 +234,8 @@
for(int b=0; b<GameConstants::BFIELD_SIZE; ++b)
predecessor[b] = -1;
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)
hexq.push(std::make_pair(start, true));
dists[hexq.front().first] = 0;
@@ -269,7 +269,7 @@
}
};
-std::vector<BattleHex> BattleInfo::getAccessibility( const CStack * stack, bool addOccupiable, std::vector<BattleHex> * attackable /*= NULL*/, bool forPassingBy /*= false*/ ) const
+std::vector<BattleHex> BattleInfo::getAccessibility( const CStack * stack, bool addOccupiable, std::vector<BattleHex> * attackable /*= NULL*/, bool forPassingBy /*= false*/, bool ignoreTactics ) const
{
std::vector<BattleHex> ret;
bool ac[GameConstants::BFIELD_SIZE];
@@ -313,11 +313,11 @@
ac[v] = false;
}
}
-
+
for (int i = 0; i < GameConstants::BFIELD_SIZE; ++i)
{
bool rangeFits;
- if (tacticDistance)
+ if (tacticDistance && !ignoreTactics)
{
rangeFits = pr[i] >= 0; //reachable in terms of obstacles
if(!forPassingBy) //only if we're passing through, we may step out of the tactic range -> otherwise check range
@@ -326,7 +326,7 @@
else
rangeFits = dist[i] <= stack->Speed(0, true); //we can reach the stack
- if( ( !addOccupiable && rangeFits && ac[i] )
+ if( ( !addOccupiable && rangeFits && ac[i] )
|| ( addOccupiable && rangeFits && isAccessible(i, ac, stack->doubleWide(), stack->attackerOwned, stack->hasBonusOfType(Bonus::FLYING), true) )//we can reach it
|| (vstd::contains(occupyable, i) && (!tacticDistance && dist[ i + (stack->attackerOwned ? 1 : -1 ) ] <= stack->Speed(0, true) ) && ac[i + (stack->attackerOwned ? 1 : -1 )] ) //it's occupyable and we can reach adjacent hex
)
@@ -366,14 +366,14 @@
continue;
}
-
+
BOOST_FOREACH(BattleHex he, occupiedBySecond)
{
if(HLP::meleeAttackable(he, ret))
attackable->push_back(he);
}
-
+
}
}
@@ -454,7 +454,7 @@
int dist[GameConstants::BFIELD_SIZE]; //calculated distances
makeBFS(start, accessibility, predecessor, dist, twoHex, attackerOwned, flyingCreature, false);
-
+
if(predecessor[dest] == -1) //cannot reach destination
{
return std::make_pair(std::vector<BattleHex>(), 0);
@@ -476,7 +476,7 @@
bool shooting, ui8 charge, bool lucky, bool deathBlow, bool ballistaDoubleDmg ) const
{
double additiveBonus = 1.0, multBonus = 1.0,
- minDmg = attacker->getMinDamage() * attackerCount,
+ minDmg = attacker->getMinDamage() * attackerCount,
maxDmg = attacker->getMaxDamage() * attackerCount;
if(attacker->getCreature()->idNumber == 149) //arrow turret
@@ -496,8 +496,8 @@
if(attacker->hasBonusOfType(Bonus::SIEGE_WEAPON) && attacker->getCreature()->idNumber != 149) //any siege weapon, but only ballista can attack (second condition - not arrow turret)
{ //minDmg and maxDmg are multiplied by hero attack + 1
- minDmg *= attackerHero->getPrimSkillLevel(0) + 1;
- maxDmg *= attackerHero->getPrimSkillLevel(0) + 1;
+ minDmg *= attackerHero->getPrimSkillLevel(0) + 1;
+ maxDmg *= attackerHero->getPrimSkillLevel(0) + 1;
}
int attackDefenceDifference = 0;
@@ -1067,7 +1067,7 @@
}
std::pair<const CStack *, BattleHex> BattleInfo::getNearestStack(const CStack * closest, boost::logic::tribool attackerOwned) const
-{
+{
bool ac[GameConstants::BFIELD_SIZE];
std::set<BattleHex> occupyable;
@@ -1201,7 +1201,7 @@
int healedHealth;
if (spell->id == Spells::SACRIFICE && sacrificedStack)
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 = calculateSpellBonus(healedHealth, spell, caster, stack);
return std::min<ui32>(healedHealth, stack->MaxHealth() - stack->firstHPleft + (resurrect ? stack->baseAmount * stack->MaxHealth() : 0));
@@ -1393,7 +1393,7 @@
bool BattleInfo::battleCanShoot(const CStack * stack, BattleHex dest) const
{
if(tacticDistance) //no shooting during tactics
- return false;
+ return false;
const CStack *dst = getStackT(dest);
@@ -1446,9 +1446,9 @@
CStack * stack = NULL;
for(ui32 g=0; g<stacks.size(); ++g)
{
- if(stacks[g]->position == pos
- || (stacks[g]->doubleWide()
- &&( (stacks[g]->attackerOwned && stacks[g]->position-1 == pos)
+ if(stacks[g]->position == pos
+ || (stacks[g]->doubleWide()
+ &&( (stacks[g]->attackerOwned && stacks[g]->position-1 == pos)
|| (!stacks[g]->attackerOwned && stacks[g]->position+1 == pos) )
) )
{
@@ -1486,7 +1486,7 @@
void BattleInfo::localInit()
{
belligerents[0]->battle = belligerents[1]->battle = this;
-
+
BOOST_FOREACH(CArmedInstance *b, belligerents)
b->attachTo(this);
@@ -1620,7 +1620,7 @@
curB->castSpells[0] = curB->castSpells[1] = 0;
curB->sides[0] = armies[0]->tempOwner;
curB->sides[1] = armies[1]->tempOwner;
- if(curB->sides[1] == 254)
+ if(curB->sides[1] == 254)
curB->sides[1] = 255;
std::vector<CStack*> & stacks = (curB->stacks);
@@ -1661,7 +1661,7 @@
CGH::readBattlePositions(positions[3]["levels"], defenderTight);
CGH::readBattlePositions(positions[4]["levels"], attackerCreBank);
CGH::readBattlePositions(positions[5]["levels"], defenderCreBank);
-
+
BOOST_FOREACH (auto position, config["commanderPositions"]["field"].Vector())
{
commanderField.push_back (position.Float());
@@ -1672,7 +1672,7 @@
}
//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++)
{
int pos;
@@ -1703,7 +1703,7 @@
}
//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
if(stacks[g]->doubleWide() && stacks[g]->attackerOwned)
@@ -1837,7 +1837,7 @@
if(r.rand(1,100) <= 40) //put cliff-like obstacle
{
RangeGenerator obidgen(0, ABSOLUTE_OBSTACLES_COUNT-1, ourRand);
-
+
try
{
auto obstPtr = make_shared<CObstacleInstance>();
@@ -2069,17 +2069,17 @@
}
break;
}
-
+
if(spell->id < 10) //it's adventure spell (not combat))
return ESpellCastProblem::ADVMAP_SPELL_INSTEAD_OF_BATTLE_SPELL;
- 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;
if(battleMinSpellLevel() > spell->level) //non - casting hero stops caster from casting this spell
return ESpellCastProblem::SPELL_LEVEL_LIMIT_EXCEEDED;
-
+
int spellIDs[] = {66, 67, 68, 69}; //IDs of summon elemental spells (fire, earth, water, air)
int creIDs[] = {114, 113, 115, 112}; //(fire, earth, water, air)
@@ -2161,8 +2161,8 @@
if(spell->getTargetType() == CSpell::OBSTACLE)
{
//isObstacleOnTile(dest)
- //
- //
+ //
+ //
//TODO
//assert that it's remove obstacle
//rules whether we can remove spell-created obstacle
@@ -2179,7 +2179,7 @@
{
if(!deadStack && !aliveStack)
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;
if(deadStack && deadStack->owner != player) //you can resurrect only your own stacks //FIXME: it includes alive stacks as well
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
@@ -2377,7 +2377,7 @@
case Spells::BLESS:
case Spells::CURSE: //undeads are immune to bless & curse
if (subject->hasBonusOfType(Bonus::UNDEAD))
- return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
+ return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
break;
case Spells::HASTE:
case Spells::SLOW:
@@ -2418,7 +2418,7 @@
}
break;
}
-
+
bool damageSpell = (vstd::contains(VLC->spellh->damageSpells, spell->id));
if (damageSpell && subject->hasBonusOfType(Bonus::DIRECT_DAMAGE_IMMUNITY))
@@ -2465,7 +2465,7 @@
if(subject->hasBonusOfType(Bonus::SPELL_IMMUNITY, spell->id) ||
( immunities->size() > 0 && immunities->totalValue() >= spell->level && spell->level))
- {
+ {
return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
}
}
@@ -2517,8 +2517,8 @@
for(std::set<CStack*>::const_iterator it = affectedCreatures.begin(); it != affectedCreatures.end(); ++it)
{
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]
)
{
@@ -2571,7 +2571,7 @@
if(stacks.size())
{
//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; });
return highestIDStack->ID + 1;
@@ -2592,7 +2592,7 @@
const CStack * BattleInfo::getStackIf(boost::function<bool(const CStack*)> pred) const
{
auto stackItr = range::find_if(stacks, pred);
- return stackItr == stacks.end()
+ return stackItr == stacks.end()
? NULL
: *stackItr;
}
@@ -2642,7 +2642,7 @@
}
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)
{
assert(base);
@@ -2708,7 +2708,7 @@
speed = ((100 + percentBonus) * speed)/100;
//bind effect check - doesn't influence stack initiative
- if (useBind && getEffect(72))
+ if (useBind && getEffect(72))
{
return 0;
}
@@ -2752,11 +2752,11 @@
}
void CStack::stackEffectToFeature(std::vector<Bonus> & sf, const Bonus & sse)
-{
+{
si32 power = VLC->spellh->spells[sse.sid]->powers[sse.val];
switch(sse.sid)
{
- case 27: //shield
+ case 27: //shield
sf.push_back(featureGenerator(Bonus::GENERAL_DAMAGE_REDUCTION, 0, power, sse.turnsRemain));
sf.back().sid = sse.sid;
break;
@@ -2970,7 +2970,7 @@
return position - 1;
else
return position + 1;
- }
+ }
else
{
return BattleHex::INVALID;
@@ -3147,12 +3147,12 @@
&& BattleHex::mutualPosition(attackerPos, defenderPos + (defender->attackerOwned ? -1 : 1)) >= 0)
|| (defender->doubleWide() && attacker->doubleWide()//back <=> back
&& BattleHex::mutualPosition(attackerPos + (attacker->attackerOwned ? -1 : 1), defenderPos + (defender->attackerOwned ? -1 : 1)) >= 0);
-
+
}
bool CStack::ableToRetaliate() const
{
- return alive()
+ return alive()
&& (counterAttacks > 0 || hasBonusOfType(Bonus::UNLIMITED_RETALIATIONS))
&& !hasBonusOfType(Bonus::SIEGE_WEAPON)
&& !hasBonusOfType(Bonus::HYPNOTIZED)
Index: lib/IGameCallback.h
===================================================================
--- lib/IGameCallback.h (revision 2753)
+++ lib/IGameCallback.h (working copy)
@@ -104,7 +104,7 @@
TStacks battleGetStacks(EStackOwnership whose = MINE_AND_ENEMY, bool onlyAlive = true); //returns stacks on battlefield
void getStackQueue( std::vector<const CStack *> &out, int howMany ); //returns vector of stack in order of their move sequence
void battleGetStackCountOutsideHexes(bool *ac); // returns hexes which when in front of a stack cause us to move the amount box back
- std::vector<BattleHex> battleGetAvailableHexes(const CStack * stack, bool addOccupiable, std::vector<BattleHex> * attackable = NULL); //returns numbers of hexes reachable by creature with id ID
+ std::vector<BattleHex> battleGetAvailableHexes(const CStack * stack, bool addOccupiable, std::vector<BattleHex> * attackable = NULL, bool ignoreTactics = false); //returns numbers of hexes reachable by creature with id ID
std::vector<int> battleGetDistances(const CStack * stack, BattleHex hex = BattleHex::INVALID, BattleHex * predecessors = NULL); //returns vector of distances to [dest hex number]
std::set<BattleHex> battleGetAttackedHexes(const CStack* attacker, BattleHex destinationTile, BattleHex attackerPos = BattleHex::INVALID);
bool battleCanShoot(const CStack * stack, BattleHex dest); //returns true if unit with id ID can shoot to dest
@@ -162,7 +162,7 @@
const PlayerState * getPlayer(int color, bool verbose = true) const;
int getResource(int Player, int which) const;
bool isVisible(int3 pos) const;
- int getPlayerRelations(ui8 color1, ui8 color2) const;// 0 = enemy, 1 = ally, 2 = same player
+ int getPlayerRelations(ui8 color1, ui8 color2) const;// 0 = enemy, 1 = ally, 2 = same player
void getThievesGuildInfo(SThievesGuildInfo & thi, const CGObjectInstance * obj); //get thieves' guild info obtainable while visiting given object
int getPlayerStatus(int player) const; //-1 if no such player
int getCurrentPlayer() const; //player that currently makes move // TODO synchronous turns
@@ -205,7 +205,7 @@
int howManyTowns(int Player) const;
const CGTownInstance * getTownInfo(int val, bool mode)const; //mode = 0 -> val = player town serial; mode = 1 -> val = object id (serial)
std::vector<const CGHeroInstance *> getAvailableHeroes(const CGObjectInstance * townOrTavern) const; //heroes that can be recruited
- std::string getTavernGossip(const CGObjectInstance * townOrTavern) const;
+ std::string getTavernGossip(const CGObjectInstance * townOrTavern) const;
int canBuildStructure(const CGTownInstance *t, int ID);//// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
std::set<int> getBuildingRequiments(const CGTownInstance *t, int ID);
virtual bool getTownInfo(const CGObjectInstance *town, InfoAboutTown &dest) const;
@@ -238,7 +238,7 @@
int getResourceAmount(int type)const;
TResources getResourceAmount() const;
- const std::vector< std::vector< std::vector<ui8> > > & getVisibilityMap()const; //returns visibility map
+ const std::vector< std::vector< std::vector<ui8> > > & getVisibilityMap()const; //returns visibility map
const PlayerSettings * getPlayerSettings(int color) const;
};
@@ -288,7 +288,7 @@
virtual void setOwner(int objid, ui8 owner)=0;
virtual void setHoverName(int objid, MetaString * name)=0;
virtual void changePrimSkill(int ID, int which, si64 val, bool abs=false)=0;
- virtual void changeSecSkill(int ID, int which, int val, bool abs=false)=0;
+ virtual void changeSecSkill(int ID, int which, int val, bool abs=false)=0;
virtual void showBlockingDialog(BlockingDialog *iw, const CFunctionList<void(ui32)> &callback)=0;
virtual ui32 showBlockingDialog(BlockingDialog *iw) =0; //synchronous version of above //TODO:
virtual void showGarrisonDialog(int upobj, int hid, bool removableUnits, const boost::function<void()> &cb) =0; //cb will be called when player closes garrison window
Index: lib/BattleState.h
===================================================================
--- lib/BattleState.h (revision 2753)
+++ lib/BattleState.h (working copy)
@@ -32,7 +32,7 @@
struct DLL_LINKAGE SiegeInfo
{
ui8 wallState[8]; //[0] - keep, [1] - bottom tower, [2] - bottom wall, [3] - below gate, [4] - over gate, [5] - upper wall, [6] - uppert tower, [7] - gate; 1 - intact, 2 - damaged, 3 - destroyed
-
+
template <typename Handler> void serialize(Handler &h, const int version)
{
h & wallState;
@@ -98,7 +98,7 @@
int getAvaliableHex(TCreature creID, bool attackerOwned, int initialPos = -1) const; //find place for summon / clone effects
void makeBFS(BattleHex start, bool*accessibility, BattleHex *predecessor, int *dists, bool twoHex, bool attackerOwned, bool flying, bool fillPredecessors) const; //*accessibility must be prepared bool[187] array; last two pointers must point to the at least 187-elements int arrays - there is written result
std::pair< std::vector<BattleHex>, int > getPath(BattleHex start, BattleHex dest, bool*accessibility, bool flyingCreature, bool twoHex, bool attackerOwned); //returned value: pair<path, length>; length may be different than number of elements in path since flying vreatures jump between distant hexes
- std::vector<BattleHex> getAccessibility(const CStack * stack, bool addOccupiable, std::vector<BattleHex> * attackable = NULL, bool forPassingBy = false) const; //returns vector of accessible tiles (taking into account the creature range)
+ std::vector<BattleHex> getAccessibility(const CStack * stack, bool addOccupiable, std::vector<BattleHex> * attackable = NULL, bool forPassingBy = false, bool ignoreTactics = false) const; //returns vector of accessible tiles (taking into account the creature range)
bool isObstacleVisibleForSide(const CObstacleInstance &obstacle, ui8 side) const;
shared_ptr<CObstacleInstance> getObstacleOnTile(BattleHex tile) const;
@@ -166,7 +166,7 @@
};
class DLL_LINKAGE CStack : public CBonusSystemNode, public CStackBasicDescriptor
-{
+{
public:
const CStackInstance *base;
Index: client/BattleInterface/CBattleInterface.cpp
===================================================================
--- client/BattleInterface/CBattleInterface.cpp (revision 2753)
+++ client/BattleInterface/CBattleInterface.cpp (working copy)
@@ -67,6 +67,14 @@
}
} cmpst2 ;
+std::string formatDmgRange(std::pair<ui32, ui32> dmgRange)
+{
+ if(dmgRange.first != dmgRange.second)
+ return (boost::format("%d - %d") % dmgRange.first % dmgRange.second).str();
+ else
+ return (boost::format("%d") % dmgRange.first).str();
+}
+
static void transformPalette(SDL_Surface * surf, double rCor, double gCor, double bCor)
{
SDL_Color * colorsToChange = surf->format->palette->colors;
@@ -92,8 +100,8 @@
CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2, const SDL_Rect & myRect, CPlayerInterface * att, CPlayerInterface * defen)
: queue(NULL), attackingHeroInstance(hero1), defendingHeroInstance(hero2), animCount(0),
- activeStack(NULL), stackToActivate(NULL), selectedStack(NULL), mouseHoveredStack(-1), lastMouseHoveredStackAnimationTime(-1), previouslyHoveredHex(-1),
- currentlyHoveredHex(-1), attackingHex(-1), tacticianInterface(NULL), stackCanCastSpell(false), creatureCasting(false), spellDestSelectMode(false), spellSelMode(NO_LOCATION), spellToCast(NULL), sp(NULL),
+ activeStack(NULL), stackToActivate(NULL), selectedStack(NULL), mouseHoveredStack(-1), lastMouseHoveredStackAnimationTime(-1),
+ currentlyHoveredHex(-1), attackingHex(-1), tacticianInterface(NULL), stackCanCastSpell(false), creatureCasting(false), spellDestSelectMode(false), spellSelMode(NO_LOCATION), spellToCast(NULL), sp(NULL),
siegeH(NULL), attackerInt(att), defenderInt(defen), curInt(att), animIDhelper(0),
givenCommand(NULL), myTurn(false), resWindow(NULL), moveStarted(false), moveSh(-1), bresult(NULL)
@@ -123,10 +131,10 @@
pos.y += queue->pos.h / 2; //center whole window
queue->moveTo(Point(pos.x, pos.y - queue->pos.h));
-// queue->pos.x = pos.x;
-// queue->pos.y = pos.y - queue->pos.h;
-// pos.h += queue->pos.h;
-// center();
+// queue->pos.x = pos.x;
+// queue->pos.y = pos.y - queue->pos.h;
+// pos.h += queue->pos.h;
+// center();
}
queue->update();
@@ -198,16 +206,20 @@
transformPalette(amountEffNeutral, 1.00, 1.00, 0.18);
////blitting menu background and terrain
-// blitAt(background, pos.x, pos.y);
-// blitAt(menu, pos.x, 556 + pos.y);
+// blitAt(background, pos.x, pos.y);
+// blitAt(menu, pos.x, 556 + pos.y);
+ labelAtkEstimate = new CLabel(400 + pos.x, 200 + pos.y, FONT_MEDIUM, TOPLEFT, Colors::Cornsilk, "");
+ labelAtkEstimate->disable();
+ labelAtkEstimate->autoRedraw = false;
+
//preparing buttons and console
bOptions = new CAdventureMapButton (CGI->generaltexth->zelp[381].first, CGI->generaltexth->zelp[381].second, boost::bind(&CBattleInterface::bOptionsf,this), 3, 561, "icm003.def", SDLK_o);
bSurrender = new CAdventureMapButton (CGI->generaltexth->zelp[379].first, CGI->generaltexth->zelp[379].second, boost::bind(&CBattleInterface::bSurrenderf,this), 54, 561, "icm001.def", SDLK_s);
bFlee = new CAdventureMapButton (CGI->generaltexth->zelp[380].first, CGI->generaltexth->zelp[380].second, boost::bind(&CBattleInterface::bFleef,this), 105, 561, "icm002.def", SDLK_r);
bFlee->block(!curInt->cb->battleCanFlee());
bSurrender->block(curInt->cb->battleGetSurrenderCost() < 0);
- bAutofight = new CAdventureMapButton (CGI->generaltexth->zelp[382].first, CGI->generaltexth->zelp[382].second, boost::bind(&CBattleInterface::bAutofightf,this), 157, 561, "icm004.def", SDLK_a);
+ bAutofight = new CAdventureMapButton (CGI->generaltexth->zelp[382].first, CGI->generaltexth->zelp[382].second, boost::bind(&CBattleInterface::bAutofightf,this), 157, 561, "icm004.def", SDLK_a);
bSpell = new CAdventureMapButton (CGI->generaltexth->zelp[385].first, CGI->generaltexth->zelp[385].second, boost::bind(&CBattleInterface::bSpellf,this), 645, 561, "icm005.def", SDLK_c);
bSpell->block(true);
bWait = new CAdventureMapButton (CGI->generaltexth->zelp[386].first, CGI->generaltexth->zelp[386].second, boost::bind(&CBattleInterface::bWaitf,this), 696, 561, "icm006.def", SDLK_w);
@@ -373,7 +385,7 @@
int channel = CCS->soundh->playSoundFromSet(CCS->soundh->battleIntroSounds);
CCS->soundh->setCallback(channel, boost::bind(&CMusicHandler::playMusicFromSet, CCS->musich, CCS->musich->battleMusics, -1));
- memset(stackCountOutsideHexes, 1, GameConstants::BFIELD_SIZE * sizeof(bool)); //initialize array with trues
+ memset(stackCountOutsideHexes, 1, GameConstants::BFIELD_SIZE * sizeof(bool)); //initialize array with trues
currentAction = INVALID;
selectedAction = INVALID;
@@ -398,6 +410,7 @@
SDL_FreeSurface(amountEffNeutral);
SDL_FreeSurface(cellBorders);
SDL_FreeSurface(backgroundWithHexes);
+ delete labelAtkEstimate;
delete bOptions;
delete bSurrender;
delete bFlee;
@@ -585,13 +598,12 @@
{
if(bfield[b]->strictHovered && bfield[b]->hovered)
{
- if(previouslyHoveredHex == -1) previouslyHoveredHex = b; //something to start with
- if(currentlyHoveredHex == -1) currentlyHoveredHex = b; //something to start with
- if(currentlyHoveredHex != b) //repair hover info
+ // clear death toll estimate of previously hovered enemy stack
+ if(currentlyHoveredHex >= 0 && currentlyHoveredHex != b)
{
- previouslyHoveredHex = currentlyHoveredHex;
- currentlyHoveredHex = b;
+ labelAtkEstimate->setTxt( "" );
}
+
//print shade
if(spellToCast) //when casting spell
{
@@ -626,7 +638,7 @@
{//TODO: do not check it every frame
if (activeStack) //highlight all attackable hexes
{
- std::set<BattleHex> set = curInt->cb->battleGetAttackedHexes(activeStack, currentlyHoveredHex, attackingHex);
+ std::set<BattleHex> set = curInt->cb->battleGetAttackedHexes(activeStack, b, attackingHex);
BOOST_FOREACH(BattleHex hex, set)
{
int x = 14 + ((hex/GameConstants::BFIELD_WIDTH)%2==0 ? 22 : 0) + 44*(hex%GameConstants::BFIELD_WIDTH) + pos.x;
@@ -636,15 +648,25 @@
}
}
- //patch by ench0: show enemy stack movement shadow
- // activeStack == NULL means it is opponent's turn...
+ //patch by ench0
+ // on hover over enemy stack:
+ // - show movement shadow of this enemy stack; and
+ // - show estimated dmg to this enemy stack by our active stack
+ // Note: activeStack == NULL means it is opponent's turn
if(activeStack && settings["battle"]["stackRange"].Bool())
{
- // display the movement shadow of the stack at b (i.e. stack under mouse)
+ // Do we have a stack at hex under mouse pointer and is it alive?
const CStack * const shere = curInt->cb->battleGetStackByPos(b, false);
if (shere && shere != activeStack && shere->alive())
{
- std::vector<BattleHex> v = curInt->cb->battleGetAvailableHexes(shere, true );
+ // display the movement shadow of the stack at b.
+ //
+ // Note by ench0: Last bool=true indicates that we want want to display the real range
+ // of the creature even during tactics mode. Default behaviour is 'false' and that
+ // results in weird behaviour during tactics (shadow of the enemy being displayed on the
+ // attackers part of the battlefield) , which IMHO is an indication of some logic
+ // problem with the BattleInfo::getAccessibility method...
+ std::vector<BattleHex> v = curInt->cb->battleGetAvailableHexes(shere, true, NULL, true);
BOOST_FOREACH (BattleHex hex, v)
{
int x = 14 + ((hex / GameConstants::BFIELD_WIDTH ) % 2 == 0 ? 22 : 0) + 44 * (hex % GameConstants::BFIELD_WIDTH) + pos.x;
@@ -652,6 +674,53 @@
SDL_Rect temp_rect = genRect (cellShade->h, cellShade->w, x, y);
CSDL_Ext::blit8bppAlphaTo24bpp (cellShade, NULL, to, &temp_rect);
}
+
+ // if it is an enemy stack then calculate estimated damage
+ if( activeStack->owner != shere->owner )
+ {
+ // Calculate damage only once, when mouse moves over the
+ // stack for the first time (not every frame)
+ if(currentlyHoveredHex != b)
+ {
+ assert(activeStack);
+ assert(shere);
+ assert(curInt);
+ assert(curInt->cb);
+
+ TDmgRange rngEstDamage = curInt->cb->battleEstimateDamage(activeStack, shere); //calculating estimated dmg
+ ui32 iTotalStackHealth = shere->getCreature()->MaxHealth() * ( shere->count - 1 ) + shere->firstHPleft;
+ ui32 iEstDmgMin = rngEstDamage.first;
+ ui32 iEstDmgMax = rngEstDamage.second;
+ ui32 iNumCreaturesWillDieMin = 0;
+ ui32 iNumCreaturesWillDieMax = 0;
+
+ // if we can't kill even the first (possibly wounded) creature with
+ // max possible damage then we're not killing anything here
+ if( shere->firstHPleft <= iEstDmgMax )
+ {
+ iEstDmgMax -= shere->firstHPleft;
+ iNumCreaturesWillDieMax = iEstDmgMax / shere->getCreature()->MaxHealth() + 1;
+ if( iNumCreaturesWillDieMax > shere->count ) iNumCreaturesWillDieMax = shere->count;
+
+ if( shere->firstHPleft <= iEstDmgMin )
+ {
+ iEstDmgMin -= shere->firstHPleft;
+ iNumCreaturesWillDieMin = iEstDmgMin / shere->getCreature()->MaxHealth() + 1;
+ if( iNumCreaturesWillDieMin > shere->count ) iNumCreaturesWillDieMin = shere->count;
+ }
+ }
+
+ // display a label with the estimated damage to this enemy stack. The label
+ // will appear to the right of the creature.
+ {
+ std::string estDeadText = (boost::format("Kills %d to %d") % iNumCreaturesWillDieMin % iNumCreaturesWillDieMax).str();
+
+ labelAtkEstimate->setTxt( estDeadText );
+ labelAtkEstimate->pos.x = bfield[b]->pos.x + bfield[b]->pos.w;
+ labelAtkEstimate->pos.y = bfield[b]->pos.y;
+ }
+ }
+ }
}
}
@@ -661,6 +730,9 @@
SDL_Rect temp_rect = genRect(cellShade->h, cellShade->w, x, y);
CSDL_Ext::blit8bppAlphaTo24bpp(cellShade, NULL, to, &temp_rect);
}
+
+ currentlyHoveredHex = b;
+ break;
}
}
@@ -678,7 +750,7 @@
for(size_t b = 0; b < obstacles.size(); ++b)
{
const auto &oi = obstacles[b];
- if(oi->obstacleType != CObstacleInstance::ABSOLUTE_OBSTACLE && oi->obstacleType != CObstacleInstance::MOAT)
+ if(oi->obstacleType != CObstacleInstance::ABSOLUTE_OBSTACLE && oi->obstacleType != CObstacleInstance::MOAT)
{
//BattleHex position = CGI->heroh->obstacles.find(obstacles[b].ID)->second.getMaxBlocked(obstacles[b].pos);
hexToObstacle.insert(std::make_pair(oi->pos, b));
@@ -752,7 +824,7 @@
if(changedStack)
{
- //we may have changed active interface (another side in hot-seat),
+ //we may have changed active interface (another side in hot-seat),
// so we can't continue drawing with old setting. So we call ourselves again and end.
SDL_SetClipRect(to, &buf); //restoring previous clip_rect
show(to);
@@ -882,6 +954,7 @@
}
else
{
+ labelAtkEstimate->showAll(to);
console->showAll(to);
bConsoleUp->showAll(to);
bConsoleDown->showAll(to);
@@ -1330,7 +1403,7 @@
creAnims[stack->ID]->setType(CCreatureAnim::HOLDING);
creAnims[stack->ID]->pos = Rect(coords.x, coords.y, creAnims[stack->ID]->fullWidth, creAnims[stack->ID]->fullHeight);
creDir[stack->ID] = stack->attackerOwned;
-
+
}
void CBattleInterface::stackRemoved(int stackID)
@@ -1989,7 +2062,7 @@
//set casting flag to true if creature can use it to not check it every time
const Bonus *spellcaster = s->getBonus(Selector::type(Bonus::SPELLCASTER)),
*randomSpellcaster = s->getBonus(Selector::type(Bonus::RANDOM_SPELLCASTER));
- if (s->casts && (spellcaster || randomSpellcaster))
+ if (s->casts && (spellcaster || randomSpellcaster))
{
stackCanCastSpell = true;
if(randomSpellcaster)
@@ -2185,13 +2258,13 @@
&& !stack->hasBonusOfType(Bonus::SIEGE_WEAPON) //and not a war machine...
)
{
- const BattleHex nextPos = stack->position + (stack->attackerOwned ? 1 : -1);
- const bool edge = stack->position % GameConstants::BFIELD_WIDTH == (stack->attackerOwned ? GameConstants::BFIELD_WIDTH - 2 : 1);
- const bool moveInside = !edge && !stackCountOutsideHexes[nextPos];
+ const BattleHex nextPos = stack->position + (stack->attackerOwned ? 1 : -1);
+ const bool edge = stack->position % GameConstants::BFIELD_WIDTH == (stack->attackerOwned ? GameConstants::BFIELD_WIDTH - 2 : 1);
+ const bool moveInside = !edge && !stackCountOutsideHexes[nextPos];
int xAdd = (stack->attackerOwned ? 220 : 202) +
- (stack->doubleWide() ? 44 : 0) * (stack->attackerOwned ? +1 : -1) +
- (moveInside ? amountNormal->w + 10 : 0) * (stack->attackerOwned ? -1 : +1);
- int yAdd = 260 + ((stack->attackerOwned || moveInside) ? 0 : -15);
+ (stack->doubleWide() ? 44 : 0) * (stack->attackerOwned ? +1 : -1) +
+ (moveInside ? amountNormal->w + 10 : 0) * (stack->attackerOwned ? -1 : +1);
+ int yAdd = 260 + ((stack->attackerOwned || moveInside) ? 0 : -15);
//blitting amount background box
SDL_Surface *amountBG = NULL;
TBonusListPtr spellEffects = stack->getSpellBonuses();
@@ -2457,10 +2530,10 @@
void CBattleInterface::endAction(const BattleAction* action)
{
const CStack * stack = curInt->cb->battleGetStackByID(action->stackNumber);
- //if((action->actionType==2 || (action->actionType==6 && action->destinationTile!=cb->battleGetPos(action->stackNumber)))) //activating interface when move is finished
-// {
-// activate();
-// }
+// if((action->actionType==2 || (action->actionType==6 && action->destinationTile!=cb->battleGetPos(action->stackNumber)))) //activating interface when move is finished
+// {
+// activate();
+// }
if(action->actionType == BattleAction::HERO_SPELL)
{
if(action->side)
@@ -2479,9 +2552,9 @@
//check if we should reverse stacks
//for some strange reason, it's not enough
-// std::set<const CStack *> stacks;
-// stacks.insert(LOCPLINT->cb->battleGetStackByID(action->stackNumber));
-// stacks.insert(LOCPLINT->cb->battleGetStackByPos(action->destinationTile));
+// std::set<const CStack *> stacks;
+// stacks.insert(LOCPLINT->cb->battleGetStackByID(action->stackNumber));
+// stacks.insert(LOCPLINT->cb->battleGetStackByPos(action->destinationTile));
TStacks stacks = curInt->cb->battleGetStacks(CBattleCallback::MINE_AND_ENEMY);
BOOST_FOREACH(const CStack *s, stacks)
@@ -2495,7 +2568,7 @@
queue->update();
if(tacticsMode) //stack ended movement in tactics phase -> select the next one
- bTacticNextStack(stack);
+ bTacticNextStack(stack);
if( action->actionType == BattleAction::HERO_SPELL) //we have activated next stack after sending request that has been just realized -> blockmap due to movement has changed
redrawBackgroundWithHexes(activeStack);
@@ -2679,14 +2752,6 @@
return NO_LOCATION; //should never happen
}
-std::string formatDmgRange(std::pair<ui32, ui32> dmgRange)
-{
- if(dmgRange.first != dmgRange.second)
- return (boost::format("%d - %d") % dmgRange.first % dmgRange.second).str();
- else
- return (boost::format("%d") % dmgRange.first).str();
-}
-
bool CBattleInterface::canStackMoveHere (const CStack * activeStack, BattleHex myNumber)
{
std::vector<BattleHex> acc = curInt->cb->battleGetAvailableHexes (activeStack, false);
@@ -2705,17 +2770,17 @@
if(!myTurn) //we are not permit to do anything
return;
- // This function handles mouse move over hexes and l-clicking on them.
+ // This function handles mouse move over hexes and l-clicking on them.
// First we decide what happens if player clicks on this hex and set appropriately
// consoleMsg, cursorFrame/Type and prepare lambda realizeAction.
- //
+ //
// Then, depending whether it was hover/click we either call the action or set tooltip/cursor.
//used when hovering -> tooltip message and cursor to be set
std::string consoleMsg;
bool setCursor = true; //if we want to suppress setting cursor
int cursorType = ECursor::COMBAT, cursorFrame = ECursor::COMBAT_POINTER;
-
+
//used when l-clicking -> action to be called upon the click
std::function<void()> realizeAction;
@@ -2731,7 +2796,7 @@
}
if(eventType == LCLICK && realizeAction)
{
- //opening creature window shouldn't affect myTurn...
+ //opening creature window shouldn't affect myTurn...
if(currentAction != CREATURE_INFO)
{
myTurn = false; //tends to crash with empty calls
@@ -2751,10 +2816,10 @@
bool ourStack = false;
if (shere)
ourStack = shere->owner == curInt->playerID;
-
+
//TODO: handle
bool noStackIsHovered = true; //will cause removing a blue glow
-
+
localActions.clear();
illegalActions.clear();
@@ -2762,9 +2827,9 @@
{
bool legalAction = false; //this action is legal and can't be performed
bool notLegal = false; //this action is not legal and should display message
-
+
switch (action)
- {
+ {
case CHOOSE_TACTICS_STACK:
if (shere && ourStack)
legalAction = true;
@@ -2836,7 +2901,7 @@
if (creatureCasting)
skill = sactive->valOfBonuses(Selector::typeSubtype(Bonus::SPELLCASTER, Spells::TELEPORT));
else
- skill = getActiveHero()->getSpellSchoolLevel (CGI->spellh->spells[spellToCast->additionalInfo]);
+ skill = getActiveHero()->getSpellSchoolLevel (CGI->spellh->spells[spellToCast->additionalInfo]);
//TODO: explicitely save power, skill
if (curInt->cb->battleCanTeleportTo(selectedStack, myNumber, skill))
legalAction = true;
@@ -2862,7 +2927,7 @@
auto tilesThatMustBeClear = sp->rangeInHexes(myNumber, hero->getSpellSchoolLevel(sp), side, &hexesOutsideBattlefield);
BOOST_FOREACH(BattleHex hex, tilesThatMustBeClear)
{
- if(curInt->cb->battleGetStackByPos(hex) || !!curInt->cb->battleGetObstacleOnPos(hex, false)
+ if(curInt->cb->battleGetStackByPos(hex) || !!curInt->cb->battleGetObstacleOnPos(hex, false)
|| !hex.isAvailable())
{
legalAction = false;
@@ -3052,14 +3117,14 @@
cursorFrame = ECursor::COMBAT_QUERY;
consoleMsg = (boost::format(CGI->generaltexth->allTexts[297]) % shere->getName()).str();
realizeAction = [=]{ GH.pushInt(createCreWindow(shere, true)); };
-
+
//setting console text
const time_t curTime = time(NULL);
CCreatureAnimation *hoveredStackAnim = creAnims[shere->ID];
if (shere->ID != mouseHoveredStack
&& curTime > lastMouseHoveredStackAnimationTime + HOVER_ANIM_DELTA
- && hoveredStackAnim->getType() == CCreatureAnim::HOLDING
+ && hoveredStackAnim->getType() == CCreatureAnim::HOLDING
&& hoveredStackAnim->framesInGroup(CCreatureAnim::MOUSEON) > 0)
{
hoveredStackAnim->playOnce(CCreatureAnim::MOUSEON);
@@ -3104,7 +3169,7 @@
cursorFrame = 0;
if(consoleMsg.empty() && sp)
consoleMsg = boost::str(boost::format(CGI->generaltexth->allTexts[26]) % sp->name); //Cast %s
-
+
realizeAction = [=]
{
if (secondaryTarget) //select that target now
@@ -3112,7 +3177,7 @@
possibleActions.clear();
switch (sp->id)
{
- case Spells::TELEPORT: //don't cast spell yet, only select target
+ case Spells::TELEPORT: //don't cast spell yet, only select target
possibleActions.push_back (TELEPORT);
spellToCast->selectedStack = selectedStack->ID;
break;
@@ -3162,7 +3227,7 @@
bool CBattleInterface::isCastingPossibleHere (const CStack * sactive, const CStack * shere, BattleHex myNumber)
{
creatureCasting = stackCanCastSpell && !spellDestSelectMode; //TODO: allow creatures to cast aimed spells
-
+
bool isCastingPossible = true;
int spellID = -1;
@@ -3175,7 +3240,7 @@
spellID = spellToCast->additionalInfo;
sp = NULL;
- if (spellID >= 0)
+ if (spellID >= 0)
sp = CGI->spellh->spells[spellID];
if (sp)
@@ -3444,7 +3509,7 @@
assert(!defname.empty());
//we assume here that effect graphics have the same size as the usual obstacle image
// -> if we know how to blit obstacle, let's blit the effect in the same place
- Point whereTo = whereToBlitObstacleImage(imageOfObstacle(oi), oi);
+ Point whereTo = whereToBlitObstacleImage(imageOfObstacle(oi), oi);
addNewAnim(new CSpellEffectAnimation(this, defname, whereTo.x, whereTo.y));
//TODO we need to wait after playing sound till it's finished, otherwise it overlaps and sounds really bad
Index: client/BattleInterface/CBattleInterface.h
===================================================================
--- client/BattleInterface/CBattleInterface.h (revision 2753)
+++ client/BattleInterface/CBattleInterface.h (working copy)
@@ -100,10 +100,12 @@
FREE_LOCATION, //used with Force Field and Fire Wall - all tiles affected by spell must be free
CATAPULT, HEAL, RISE_DEMONS
};
+
private:
SDL_Surface * background, * menu, * amountNormal, * amountNegative, * amountPositive, * amountEffNeutral, * cellBorders, * backgroundWithHexes;
CAdventureMapButton * bOptions, * bSurrender, * bFlee, * bAutofight, * bSpell,
* bWait, * bDefence, * bConsoleUp, * bConsoleDown, *btactNext, *btactEnd;
+ CLabel * labelAtkEstimate; // a GUI element to display projected attack results when hovering mouse over enemy stack. TODO: Using CLabel is really a hack, some better-looking GUI element should be used...
CBattleConsole * console;
CBattleHero * attackingHero, * defendingHero; //fighting heroes
CStackQueue *queue;
@@ -184,7 +186,7 @@
const CBattleInterface * owner;
public:
const CGTownInstance * town; //besieged town
-
+
SiegeHelper(const CGTownInstance * siegeTown, const CBattleInterface * _owner); //c-tor
~SiegeHelper(); //d-tor
@@ -287,7 +289,7 @@
friend class CPlayerInterface;
friend class CAdventureMapButton;
friend class CInGameConsole;
-
+
friend class CBattleResultWindow;
friend class CBattleHero;
friend class CSpellEffectAnimation;
BatEstBG.bmp [^] (15,182 bytes) 2012-06-19 15:22
|