1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

* minor refactoring

* minor improvements in battle interface
This commit is contained in:
mateuszb 2011-01-09 17:41:46 +00:00
parent c1bd81abdd
commit 56ec829049
12 changed files with 93 additions and 99 deletions

View File

@ -242,7 +242,7 @@ void CStupidAI::print(const std::string &text) const
BattleAction CStupidAI::goTowards(const CStack * stack, THex hex) BattleAction CStupidAI::goTowards(const CStack * stack, THex hex)
{ {
THex realDest = hex; THex realDest = hex;
int predecessors[BFIELD_SIZE]; THex predecessors[BFIELD_SIZE];
std::vector<int> dists = cb->battleGetDistances(stack, hex); std::vector<int> dists = cb->battleGetDistances(stack, hex);
if(distToNearestNeighbour(hex, dists, &realDest) > BFIELD_SIZE) if(distToNearestNeighbour(hex, dists, &realDest) > BFIELD_SIZE)
{ {

View File

@ -523,20 +523,20 @@ const CStack* CBattleCallback::battleGetStackByPos(THex pos, bool onlyAlive)
return gs->curB->battleGetStack(pos, onlyAlive); return gs->curB->battleGetStack(pos, onlyAlive);
} }
int CBattleCallback::battleGetPos(int stack) THex CBattleCallback::battleGetPos(int stack)
{ {
boost::shared_lock<boost::shared_mutex> lock(*gs->mx); boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
if(!gs->curB) if(!gs->curB)
{ {
tlog2<<"battleGetPos called when there is no battle!"<<std::endl; tlog2<<"battleGetPos called when there is no battle!"<<std::endl;
return -1; return THex::INVALID;
} }
for(size_t g=0; g<gs->curB->stacks.size(); ++g) for(size_t g=0; g<gs->curB->stacks.size(); ++g)
{ {
if(gs->curB->stacks[g]->ID == stack) if(gs->curB->stacks[g]->ID == stack)
return gs->curB->stacks[g]->position; return gs->curB->stacks[g]->position;
} }
return -1; return THex::INVALID;
} }
std::vector<const CStack*> CBattleCallback::battleGetStacks(bool onlyAlive /*= true*/) std::vector<const CStack*> CBattleCallback::battleGetStacks(bool onlyAlive /*= true*/)
@ -592,7 +592,7 @@ bool CBattleCallback::battleCanCastSpell()
if(!gs->curB) //there is no battle if(!gs->curB) //there is no battle
return false; return false;
if(gs->curB->side1 == player) if(gs->curB->sides[0] == player)
return gs->curB->castSpells[0] == 0 && gs->curB->heroes[0] && gs->curB->heroes[0]->getArt(17); return gs->curB->castSpells[0] == 0 && gs->curB->heroes[0] && gs->curB->heroes[0]->getArt(17);
else else
return gs->curB->castSpells[1] == 0 && gs->curB->heroes[1] && gs->curB->heroes[1]->getArt(17); return gs->curB->castSpells[1] == 0 && gs->curB->heroes[1] && gs->curB->heroes[1]->getArt(17);
@ -620,7 +620,7 @@ ui8 CBattleCallback::battleGetWallState(int partOfWall)
return gs->curB->si.wallState[partOfWall]; return gs->curB->si.wallState[partOfWall];
} }
int CBattleCallback::battleGetWallUnderHex(int hex) int CBattleCallback::battleGetWallUnderHex(THex hex)
{ {
if(!gs->curB || gs->curB->siege == 0) if(!gs->curB || gs->curB->siege == 0)
{ {
@ -637,7 +637,7 @@ TDmgRange CBattleCallback::battleEstimateDamage(const CStack * attacker, const C
const CGHeroInstance * attackerHero, * defenderHero; const CGHeroInstance * attackerHero, * defenderHero;
bool shooting = battleCanShoot(attacker, defender->position); bool shooting = battleCanShoot(attacker, defender->position);
if(gs->curB->side1 == player) if(gs->curB->sides[0] == player)
{ {
attackerHero = gs->curB->heroes[0]; attackerHero = gs->curB->heroes[0];
defenderHero = gs->curB->heroes[1]; defenderHero = gs->curB->heroes[1];
@ -1060,14 +1060,15 @@ CBattleCallback::CBattleCallback(CGameState *GS, int Player, CClient *C )
cl = C; cl = C;
} }
std::vector<int> CBattleCallback::battleGetDistances(const CStack * stack, THex hex /*= THex::INVALID*/, int * predecessors /*= NULL*/) std::vector<int> CBattleCallback::battleGetDistances(const CStack * stack, THex hex /*= THex::INVALID*/, THex * predecessors /*= NULL*/)
{ {
if(!hex.isValid()) if(!hex.isValid())
hex = stack->position; hex = stack->position;
std::vector<int> ret; std::vector<int> ret;
bool ac[BFIELD_SIZE]; bool ac[BFIELD_SIZE];
int pr[BFIELD_SIZE], dist[BFIELD_SIZE]; THex pr[BFIELD_SIZE];
int dist[BFIELD_SIZE];
gs->curB->makeBFS(stack->position, ac, pr, dist, stack->doubleWide(), stack->attackerOwned, stack->hasBonusOfType(Bonus::FLYING), false); gs->curB->makeBFS(stack->position, ac, pr, dist, stack->doubleWide(), stack->attackerOwned, stack->hasBonusOfType(Bonus::FLYING), false);
for(int i=0; i<BFIELD_SIZE; ++i) for(int i=0; i<BFIELD_SIZE; ++i)
@ -1080,7 +1081,7 @@ std::vector<int> CBattleCallback::battleGetDistances(const CStack * stack, THex
if(predecessors) if(predecessors)
{ {
memcpy(predecessors, pr, BFIELD_SIZE * sizeof(int)); memcpy(predecessors, pr, BFIELD_SIZE * sizeof(THex));
} }
return ret; return ret;

View File

@ -80,18 +80,18 @@ public:
virtual std::vector<CObstacleInstance> battleGetAllObstacles()=0; //returns all obstacles on the battlefield virtual std::vector<CObstacleInstance> battleGetAllObstacles()=0; //returns all obstacles on the battlefield
virtual const CStack * battleGetStackByID(int ID, bool onlyAlive = true)=0; //returns stack info by given ID virtual const CStack * battleGetStackByID(int ID, bool onlyAlive = true)=0; //returns stack info by given ID
virtual const CStack * battleGetStackByPos(THex pos, bool onlyAlive = true)=0; //returns stack info by given pos virtual const CStack * battleGetStackByPos(THex pos, bool onlyAlive = true)=0; //returns stack info by given pos
virtual int battleGetPos(int stack)=0; //returns position (tile ID) of stack virtual THex battleGetPos(int stack)=0; //returns position (tile ID) of stack
virtual int battleMakeAction(BattleAction* action)=0;//for casting spells by hero - DO NOT use it for moving active stack virtual int battleMakeAction(BattleAction* action)=0;//for casting spells by hero - DO NOT use it for moving active stack
virtual std::vector<const CStack*> battleGetStacks(bool onlyAlive = true)=0; //returns stacks on battlefield virtual std::vector<const CStack*> battleGetStacks(bool onlyAlive = true)=0; //returns stacks on battlefield
virtual void getStackQueue( std::vector<const CStack *> &out, int howMany )=0; //returns vector of stack in order of their move sequence virtual void getStackQueue( std::vector<const CStack *> &out, int howMany )=0; //returns vector of stack in order of their move sequence
virtual std::vector<THex> battleGetAvailableHexes(const CStack * stack, bool addOccupiable)=0; //returns numbers of hexes reachable by creature with id ID virtual std::vector<THex> battleGetAvailableHexes(const CStack * stack, bool addOccupiable)=0; //returns numbers of hexes reachable by creature with id ID
virtual std::vector<int> battleGetDistances(const CStack * stack, THex hex = THex::INVALID, int * predecessors = NULL)=0; //returns vector of distances to [dest hex number] virtual std::vector<int> battleGetDistances(const CStack * stack, THex hex = THex::INVALID, THex * predecessors = NULL)=0; //returns vector of distances to [dest hex number]
virtual bool battleCanShoot(const CStack * stack, THex dest)=0; //returns true if unit with id ID can shoot to dest virtual bool battleCanShoot(const CStack * stack, THex dest)=0; //returns true if unit with id ID can shoot to dest
virtual bool battleCanCastSpell()=0; //returns true, if caller can cast a spell virtual bool battleCanCastSpell()=0; //returns true, if caller can cast a spell
virtual bool battleCanFlee()=0; //returns true if caller can flee from the battle virtual bool battleCanFlee()=0; //returns true if caller can flee from the battle
virtual const CGTownInstance * battleGetDefendedTown()=0; //returns defended town if current battle is a siege, NULL instead virtual const CGTownInstance * battleGetDefendedTown()=0; //returns defended town if current battle is a siege, NULL instead
virtual ui8 battleGetWallState(int partOfWall)=0; //for determining state of a part of the wall; format: parameter [0] - keep, [1] - bottom tower, [2] - bottom wall, [3] - below gate, [4] - over gate, [5] - upper wall, [6] - uppert tower, [7] - gate; returned value: 1 - intact, 2 - damaged, 3 - destroyed; 0 - no battle virtual ui8 battleGetWallState(int partOfWall)=0; //for determining state of a part of the wall; format: parameter [0] - keep, [1] - bottom tower, [2] - bottom wall, [3] - below gate, [4] - over gate, [5] - upper wall, [6] - uppert tower, [7] - gate; returned value: 1 - intact, 2 - damaged, 3 - destroyed; 0 - no battle
virtual int battleGetWallUnderHex(int hex)=0; //returns part of destructible wall / gate / keep under given hex or -1 if not found virtual int battleGetWallUnderHex(THex hex)=0; //returns part of destructible wall / gate / keep under given hex or -1 if not found
virtual TDmgRange battleEstimateDamage(const CStack * attacker, const CStack * defender, TDmgRange * retaliationDmg = NULL)=0; //estimates damage dealt by attacker to defender; it may be not precise especially when stack has randomly working bonuses; returns pair <min dmg, max dmg> virtual TDmgRange battleEstimateDamage(const CStack * attacker, const CStack * defender, TDmgRange * retaliationDmg = NULL)=0; //estimates damage dealt by attacker to defender; it may be not precise especially when stack has randomly working bonuses; returns pair <min dmg, max dmg>
virtual ui8 battleGetSiegeLevel()=0; //returns 0 when there is no siege, 1 if fort, 2 is citadel, 3 is castle virtual ui8 battleGetSiegeLevel()=0; //returns 0 when there is no siege, 1 if fort, 2 is citadel, 3 is castle
virtual const CGHeroInstance * battleGetFightingHero(ui8 side) const =0; //returns hero corresponding to given side (0 - attacker, 1 - defender) virtual const CGHeroInstance * battleGetFightingHero(ui8 side) const =0; //returns hero corresponding to given side (0 - attacker, 1 - defender)
@ -208,18 +208,18 @@ public:
std::vector<CObstacleInstance> battleGetAllObstacles() OVERRIDE; //returns all obstacles on the battlefield std::vector<CObstacleInstance> battleGetAllObstacles() OVERRIDE; //returns all obstacles on the battlefield
const CStack * battleGetStackByID(int ID, bool onlyAlive = true) OVERRIDE; //returns stack info by given ID const CStack * battleGetStackByID(int ID, bool onlyAlive = true) OVERRIDE; //returns stack info by given ID
const CStack * battleGetStackByPos(THex pos, bool onlyAlive = true) OVERRIDE; //returns stack info by given pos const CStack * battleGetStackByPos(THex pos, bool onlyAlive = true) OVERRIDE; //returns stack info by given pos
int battleGetPos(int stack) OVERRIDE; //returns position (tile ID) of stack THex battleGetPos(int stack) OVERRIDE; //returns position (tile ID) of stack
int battleMakeAction(BattleAction* action) OVERRIDE;//for casting spells by hero - DO NOT use it for moving active stack int battleMakeAction(BattleAction* action) OVERRIDE;//for casting spells by hero - DO NOT use it for moving active stack
std::vector<const CStack*> battleGetStacks(bool onlyAlive = true) OVERRIDE; //returns stacks on battlefield std::vector<const CStack*> battleGetStacks(bool onlyAlive = true) OVERRIDE; //returns stacks on battlefield
void getStackQueue( std::vector<const CStack *> &out, int howMany ) OVERRIDE; //returns vector of stack in order of their move sequence void getStackQueue( std::vector<const CStack *> &out, int howMany ) OVERRIDE; //returns vector of stack in order of their move sequence
std::vector<THex> battleGetAvailableHexes(const CStack * stack, bool addOccupiable) OVERRIDE; //reutrns numbers of hexes reachable by creature with id ID std::vector<THex> battleGetAvailableHexes(const CStack * stack, bool addOccupiable) OVERRIDE; //reutrns numbers of hexes reachable by creature with id ID
std::vector<int> battleGetDistances(const CStack * stack, THex hex = THex::INVALID, int * predecessors = NULL) OVERRIDE; //returns vector of distances to [dest hex number]; if predecessors is not null, it must point to BFIELD_SIZE * sizeof(int) of allocated memory std::vector<int> battleGetDistances(const CStack * stack, THex hex = THex::INVALID, THex * predecessors = NULL) OVERRIDE; //returns vector of distances to [dest hex number]; if predecessors is not null, it must point to BFIELD_SIZE * sizeof(int) of allocated memory
bool battleCanShoot(const CStack * stack, THex dest) OVERRIDE; //returns true if unit with id ID can shoot to dest bool battleCanShoot(const CStack * stack, THex dest) OVERRIDE; //returns true if unit with id ID can shoot to dest
bool battleCanCastSpell() OVERRIDE; //returns true, if caller can cast a spell bool battleCanCastSpell() OVERRIDE; //returns true, if caller can cast a spell
bool battleCanFlee() OVERRIDE; //returns true if caller can flee from the battle bool battleCanFlee() OVERRIDE; //returns true if caller can flee from the battle
const CGTownInstance * battleGetDefendedTown() OVERRIDE; //returns defended town if current battle is a siege, NULL instead const CGTownInstance * battleGetDefendedTown() OVERRIDE; //returns defended town if current battle is a siege, NULL instead
ui8 battleGetWallState(int partOfWall) OVERRIDE; //for determining state of a part of the wall; format: parameter [0] - keep, [1] - bottom tower, [2] - bottom wall, [3] - below gate, [4] - over gate, [5] - upper wall, [6] - uppert tower, [7] - gate; returned value: 1 - intact, 2 - damaged, 3 - destroyed; 0 - no battle ui8 battleGetWallState(int partOfWall) OVERRIDE; //for determining state of a part of the wall; format: parameter [0] - keep, [1] - bottom tower, [2] - bottom wall, [3] - below gate, [4] - over gate, [5] - upper wall, [6] - uppert tower, [7] - gate; returned value: 1 - intact, 2 - damaged, 3 - destroyed; 0 - no battle
int battleGetWallUnderHex(int hex) OVERRIDE; //returns part of destructible wall / gate / keep under given hex or -1 if not found int battleGetWallUnderHex(THex hex) OVERRIDE; //returns part of destructible wall / gate / keep under given hex or -1 if not found
TDmgRange battleEstimateDamage(const CStack * attacker, const CStack * defender, TDmgRange * retaliationDmg = NULL) OVERRIDE; //estimates damage dealt by attacker to defender; it may be not precise especially when stack has randomly working bonuses; returns pair <min dmg, max dmg> TDmgRange battleEstimateDamage(const CStack * attacker, const CStack * defender, TDmgRange * retaliationDmg = NULL) OVERRIDE; //estimates damage dealt by attacker to defender; it may be not precise especially when stack has randomly working bonuses; returns pair <min dmg, max dmg>
ui8 battleGetSiegeLevel() OVERRIDE; //returns 0 when there is no siege, 1 if fort, 2 is citadel, 3 is castle ui8 battleGetSiegeLevel() OVERRIDE; //returns 0 when there is no siege, 1 if fort, 2 is citadel, 3 is castle
const CGHeroInstance * battleGetFightingHero(ui8 side) const OVERRIDE; //returns hero corresponding ot given side (0 - attacker, 1 - defender) const CGHeroInstance * battleGetFightingHero(ui8 side) const OVERRIDE; //returns hero corresponding ot given side (0 - attacker, 1 - defender)

View File

@ -876,54 +876,44 @@ bool CMeleeAttack::init()
return false; return false;
} }
int reversedShift = 0; //shift of attacking stack's position due to reversing bool toReverse = isToReverse(attackingStackPosBeforeReturn, dest, owner->creDir[stack->ID], attackedStack->doubleWide(), owner->creDir[attackedStack->ID]);
if(attackingStack->attackerOwned)
{
if(attackingStack->doubleWide() && THex::mutualPosition(attackingStackPosBeforeReturn, dest) == -1)
{
if(THex::mutualPosition(attackingStackPosBeforeReturn + (attackingStack->attackerOwned ? -1 : 1), dest) >= 0) //if reversing stack will make its position adjacent to dest
{
reversedShift = (attackingStack->attackerOwned ? -1 : 1);
}
}
}
else //if(astack->attackerOwned)
{
if(attackingStack->doubleWide() && THex::mutualPosition(attackingStackPosBeforeReturn, dest) == -1)
{
if(THex::mutualPosition(attackingStackPosBeforeReturn + (attackingStack->attackerOwned ? -1 : 1), dest) >= 0) //if reversing stack will make its position adjacent to dest
{
reversedShift = (attackingStack->attackerOwned ? -1 : 1);
}
}
} if(toReverse)
//reversing stack if necessary
if(isToReverse(attackingStackPosBeforeReturn, dest, owner->creDir[stack->ID], attackedStack->doubleWide(), owner->creDir[attackedStack->ID]))
{ {
owner->addNewAnim(new CReverseAnim(owner, stack, attackingStackPosBeforeReturn, true)); owner->addNewAnim(new CReverseAnim(owner, stack, attackingStackPosBeforeReturn, true));
return false; return false;
} }
//reversed //reversed
shooting = false; shooting = false;
posShiftDueToDist = reversedShift;
static const int mutPosToGroup[] = {11, 11, 12, 13, 13, 12}; static const int mutPosToGroup[] = {11, 11, 12, 13, 13, 12};
int mutPos = THex::mutualPosition(attackingStackPosBeforeReturn + reversedShift, dest); int revShiftattacker = (attackingStack->attackerOwned ? -1 : 1);
int mutPos = THex::mutualPosition(attackingStackPosBeforeReturn, dest);
if(mutPos == -1 && attackedStack->doubleWide()) if(mutPos == -1 && attackedStack->doubleWide())
{ {
mutPos = THex::mutualPosition(attackingStackPosBeforeReturn + reversedShift, attackedStack->occupiedHex()); mutPos = THex::mutualPosition(attackingStackPosBeforeReturn + revShiftattacker, attackedStack->position);
} }
if (mutPos == -1 && attackedStack->doubleWide())
{
mutPos = THex::mutualPosition(attackingStackPosBeforeReturn, attackedStack->occupiedHex());
}
if (mutPos == -1 && attackedStack->doubleWide() && attackingStack->doubleWide())
{
mutPos = THex::mutualPosition(attackingStackPosBeforeReturn + revShiftattacker, attackedStack->occupiedHex());
}
switch(mutPos) //attack direction switch(mutPos) //attack direction
{ {
case 0: case 1: case 2: case 3: case 4: case 5: case 0: case 1: case 2: case 3: case 4: case 5:
group = mutPosToGroup[mutPos]; group = mutPosToGroup[mutPos];
break; break;
default: default:
tlog1<<"Critical Error! Wrong dest in stackAttacking! dest: "<<dest<<" attacking stack pos: "<<attackingStackPosBeforeReturn<<" reversed shift: "<<reversedShift<<std::endl; tlog1<<"Critical Error! Wrong dest in stackAttacking! dest: "<<dest<<" attacking stack pos: "<<attackingStackPosBeforeReturn<<" mutual pos: "<<mutPos<<std::endl;
group = 11; group = 11;
break; break;
} }
@ -1041,7 +1031,6 @@ bool CShootingAnim::init()
//attack aniamtion //attack aniamtion
posShiftDueToDist = 0;
shooting = true; shooting = true;
if(projectileAngle > straightAngle) //upper shot if(projectileAngle > straightAngle) //upper shot

View File

@ -190,7 +190,6 @@ class CBattleAttack : public CBattleStackAnimation
{ {
protected: protected:
THex dest; //atacked hex THex dest; //atacked hex
int posShiftDueToDist;
bool shooting; bool shooting;
int group; //if shooting is true, print this animation group int group; //if shooting is true, print this animation group
const CStack * attackedStack; const CStack * attackedStack;

View File

@ -547,23 +547,23 @@ void CClient::stopConnection()
void CClient::battleStarted(const BattleInfo * info) void CClient::battleStarted(const BattleInfo * info)
{ {
CPlayerInterface * att, * def; CPlayerInterface * att, * def;
if(vstd::contains(playerint, info->side1) && playerint[info->side1]->human) if(vstd::contains(playerint, info->sides[0]) && playerint[info->sides[0]]->human)
att = static_cast<CPlayerInterface*>( playerint[info->side1] ); att = static_cast<CPlayerInterface*>( playerint[info->sides[0]] );
else else
att = NULL; att = NULL;
if(vstd::contains(playerint, info->side2) && playerint[info->side2]->human) if(vstd::contains(playerint, info->sides[1]) && playerint[info->sides[1]]->human)
def = static_cast<CPlayerInterface*>( playerint[info->side2] ); def = static_cast<CPlayerInterface*>( playerint[info->sides[1]] );
else else
def = NULL; def = NULL;
new CBattleInterface(info->belligerents[0], info->belligerents[1], info->heroes[0], info->heroes[1], Rect((conf.cc.resx - 800)/2, (conf.cc.resy - 600)/2, 800, 600), att, def); new CBattleInterface(info->belligerents[0], info->belligerents[1], info->heroes[0], info->heroes[1], Rect((conf.cc.resx - 800)/2, (conf.cc.resy - 600)/2, 800, 600), att, def);
if(vstd::contains(battleints,info->side1)) if(vstd::contains(battleints,info->sides[0]))
battleints[info->side1]->battleStart(info->belligerents[0], info->belligerents[1], info->tile, info->heroes[0], info->heroes[1], 0); battleints[info->sides[0]]->battleStart(info->belligerents[0], info->belligerents[1], info->tile, info->heroes[0], info->heroes[1], 0);
if(vstd::contains(battleints,info->side2)) if(vstd::contains(battleints,info->sides[1]))
battleints[info->side2]->battleStart(info->belligerents[0], info->belligerents[1], info->tile, info->heroes[0], info->heroes[1], 1); battleints[info->sides[1]]->battleStart(info->belligerents[0], info->belligerents[1], info->tile, info->heroes[0], info->heroes[1], 1);
if(vstd::contains(battleints,254)) if(vstd::contains(battleints,254))
battleints[254]->battleStart(info->belligerents[0], info->belligerents[1], info->tile, info->heroes[0], info->heroes[1], 1); battleints[254]->battleStart(info->belligerents[0], info->belligerents[1], info->tile, info->heroes[0], info->heroes[1], 1);
} }

View File

@ -37,8 +37,8 @@
cl->battleints[player]->function(__VA_ARGS__); cl->battleints[player]->function(__VA_ARGS__);
#define BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(function,...) \ #define BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(function,...) \
BATTLE_INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side1, function, __VA_ARGS__) \ BATTLE_INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->sides[0], function, __VA_ARGS__) \
BATTLE_INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->side2, function, __VA_ARGS__) \ BATTLE_INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->sides[1], function, __VA_ARGS__) \
BATTLE_INTERFACE_CALL_IF_PRESENT(254, function, __VA_ARGS__) BATTLE_INTERFACE_CALL_IF_PRESENT(254, function, __VA_ARGS__)
/* /*
* NetPacksClient.cpp, part of VCMI engine * NetPacksClient.cpp, part of VCMI engine
@ -530,7 +530,7 @@ void BattleSetActiveStack::applyCl( CClient *cl )
int playerToCall = -1; //player that will move activated stack int playerToCall = -1; //player that will move activated stack
if( activated->hasBonusOfType(Bonus::HYPNOTIZED) ) if( activated->hasBonusOfType(Bonus::HYPNOTIZED) )
{ {
playerToCall = ( GS(cl)->curB->side1 == activated->owner ? GS(cl)->curB->side2 : GS(cl)->curB->side1 ); playerToCall = ( GS(cl)->curB->sides[0] == activated->owner ? GS(cl)->curB->sides[1] : GS(cl)->curB->sides[0] );
} }
else else
{ {

View File

@ -216,7 +216,7 @@ void BattleInfo::getAccessibilityMap(bool *accessibility, bool twoHex, bool atta
} }
} }
bool BattleInfo::isAccessible(int hex, bool * accessibility, bool twoHex, bool attackerOwned, bool flying, bool lastPos) bool BattleInfo::isAccessible(THex hex, bool * accessibility, bool twoHex, bool attackerOwned, bool flying, bool lastPos)
{ {
if(flying && !lastPos) if(flying && !lastPos)
return true; return true;
@ -232,7 +232,7 @@ bool BattleInfo::isAccessible(int hex, bool * accessibility, bool twoHex, bool a
} }
} }
void BattleInfo::makeBFS(THex start, bool *accessibility, int *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(THex start, bool *accessibility, THex *predecessor, int *dists, bool twoHex, bool attackerOwned, bool flying, bool fillPredecessors) const //both pointers must point to the at least 187-elements int arrays
{ {
//inits //inits
for(int b=0; b<BFIELD_SIZE; ++b) for(int b=0; b<BFIELD_SIZE; ++b)
@ -282,7 +282,8 @@ std::vector<THex> BattleInfo::getAccessibility(const CStack * stack, bool addOcc
getAccessibilityMap(ac, stack->doubleWide(), stack->attackerOwned, addOccupiable, occupyable, stack->hasBonusOfType(Bonus::FLYING), stack); getAccessibilityMap(ac, stack->doubleWide(), stack->attackerOwned, addOccupiable, occupyable, stack->hasBonusOfType(Bonus::FLYING), stack);
int pr[BFIELD_SIZE], dist[BFIELD_SIZE]; THex pr[BFIELD_SIZE];
int dist[BFIELD_SIZE];
makeBFS(stack->position, ac, pr, dist, stack->doubleWide(), stack->attackerOwned, stack->hasBonusOfType(Bonus::FLYING), false); makeBFS(stack->position, ac, pr, dist, stack->doubleWide(), stack->attackerOwned, stack->hasBonusOfType(Bonus::FLYING), false);
if(stack->doubleWide()) if(stack->doubleWide())
@ -354,21 +355,21 @@ bool BattleInfo::isStackBlocked(const CStack * stack) const
} }
std::pair< std::vector<int>, int > BattleInfo::getPath(int start, int dest, bool*accessibility, bool flyingCreature, bool twoHex, bool attackerOwned) std::pair< std::vector<THex>, int > BattleInfo::getPath(THex start, THex dest, bool*accessibility, bool flyingCreature, bool twoHex, bool attackerOwned)
{ {
int predecessor[BFIELD_SIZE]; //for getting the Path THex predecessor[BFIELD_SIZE]; //for getting the Path
int dist[BFIELD_SIZE]; //calculated distances int dist[BFIELD_SIZE]; //calculated distances
makeBFS(start, accessibility, predecessor, dist, twoHex, attackerOwned, flyingCreature, false); makeBFS(start, accessibility, predecessor, dist, twoHex, attackerOwned, flyingCreature, false);
if(predecessor[dest] == -1) //cannot reach destination if(predecessor[dest] == -1) //cannot reach destination
{ {
return std::make_pair(std::vector<int>(), 0); return std::make_pair(std::vector<THex>(), 0);
} }
//making the Path //making the Path
std::vector<int> path; std::vector<THex> path;
int curElem = dest; THex curElem = dest;
while(curElem != start) while(curElem != start)
{ {
path.push_back(curElem); path.push_back(curElem);
@ -630,7 +631,7 @@ void BattleInfo::calculateCasualties( std::map<ui32,si32> *casualties ) const
} }
} }
std::set<CStack*> BattleInfo::getAttackedCreatures( const CSpell * s, int skillLevel, ui8 attackerOwner, int destinationTile ) std::set<CStack*> BattleInfo::getAttackedCreatures( const CSpell * s, int skillLevel, ui8 attackerOwner, THex destinationTile )
{ {
std::set<ui16> attackedHexes = s->rangeInHexes(destinationTile, skillLevel); std::set<ui16> attackedHexes = s->rangeInHexes(destinationTile, skillLevel);
std::set<CStack*> attackedCres; /*std::set to exclude multiple occurrences of two hex creatures*/ std::set<CStack*> attackedCres; /*std::set to exclude multiple occurrences of two hex creatures*/
@ -715,9 +716,9 @@ int BattleInfo::calculateSpellDuration( const CSpell * spell, const CGHeroInstan
} }
} }
CStack * BattleInfo::generateNewStack(const CStackInstance &base, int stackID, bool attackerOwned, int slot, int position) const CStack * BattleInfo::generateNewStack(const CStackInstance &base, int stackID, bool attackerOwned, int slot, THex position) const
{ {
int owner = attackerOwned ? side1 : side2; int owner = attackerOwned ? sides[0] : sides[1];
assert(owner >= PLAYER_LIMIT || base.armyObj && base.armyObj->tempOwner == owner); assert(owner >= PLAYER_LIMIT || base.armyObj && base.armyObj->tempOwner == owner);
CStack * ret = new CStack(&base, owner, stackID, attackerOwned, slot); CStack * ret = new CStack(&base, owner, stackID, attackerOwned, slot);
@ -725,9 +726,9 @@ CStack * BattleInfo::generateNewStack(const CStackInstance &base, int stackID, b
return ret; return ret;
} }
CStack * BattleInfo::generateNewStack(const CStackBasicDescriptor &base, int stackID, bool attackerOwned, int slot, int position) const CStack * BattleInfo::generateNewStack(const CStackBasicDescriptor &base, int stackID, bool attackerOwned, int slot, THex position) const
{ {
int owner = attackerOwned ? side1 : side2; int owner = attackerOwned ? sides[0] : sides[1];
CStack * ret = new CStack(&base, owner, stackID, attackerOwned, slot); CStack * ret = new CStack(&base, owner, stackID, attackerOwned, slot);
ret->position = position; ret->position = position;
return ret; return ret;
@ -781,14 +782,15 @@ int BattleInfo::lineToWallHex( int line ) const
return lineToHex[line]; return lineToHex[line];
} }
std::pair<const CStack *, int> BattleInfo::getNearestStack(const CStack * closest, boost::logic::tribool attackerOwned) const std::pair<const CStack *, THex> BattleInfo::getNearestStack(const CStack * closest, boost::logic::tribool attackerOwned) const
{ {
bool ac[BFIELD_SIZE]; bool ac[BFIELD_SIZE];
std::set<THex> occupyable; std::set<THex> 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);
int predecessor[BFIELD_SIZE], dist[BFIELD_SIZE]; THex predecessor[BFIELD_SIZE];
int dist[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>
@ -828,7 +830,7 @@ std::pair<const CStack *, int> BattleInfo::getNearestStack(const CStack * closes
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 * , int>(NULL, -1); return std::make_pair<const CStack * , THex>(NULL, THex::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
{ {
@ -1139,7 +1141,7 @@ bool BattleInfo::battleCanShoot(const CStack * stack, THex dest) const
bool BattleInfo::battleCanFlee(int player) const bool BattleInfo::battleCanFlee(int player) const
{ {
if (player == side1) if (player == sides[0])
{ {
if (!heroes[0]) if (!heroes[0])
return false;//current player have no hero return false;//current player have no hero
@ -1154,7 +1156,7 @@ bool BattleInfo::battleCanFlee(int player) const
|| ( heroes[1] && heroes[1]->hasBonusOfType(Bonus::ENEMY_CANT_ESCAPE))) || ( heroes[1] && heroes[1]->hasBonusOfType(Bonus::ENEMY_CANT_ESCAPE)))
return false; return false;
if (player == side2 && siege //defender in siege if (player == sides[1] && siege //defender in siege
&& !(town->subID == 6 && vstd::contains(town->builtBuildings, 17)))//without escape tunnel && !(town->subID == 6 && vstd::contains(town->builtBuildings, 17)))//without escape tunnel
return false; return false;
@ -1256,10 +1258,10 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, int terrain, int terType, const
{ {
CMP_stack cmpst; CMP_stack cmpst;
BattleInfo *curB = new BattleInfo; BattleInfo *curB = new BattleInfo;
curB->side1 = armies[0]->tempOwner; curB->sides[0] = armies[0]->tempOwner;
curB->side2 = armies[1]->tempOwner; curB->sides[1] = armies[1]->tempOwner;
if(curB->side2 == 254) if(curB->sides[1] == 254)
curB->side2 = 255; curB->sides[1] = 255;
std::vector<CStack*> & stacks = (curB->stacks); std::vector<CStack*> & stacks = (curB->stacks);
@ -1883,7 +1885,7 @@ bool CStack::doubleWide() const
return getCreature()->doubleWide; return getCreature()->doubleWide;
} }
int CStack::occupiedHex() const THex CStack::occupiedHex() const
{ {
if (doubleWide()) if (doubleWide())
{ {
@ -1894,7 +1896,7 @@ int CStack::occupiedHex() const
} }
else else
{ {
return -1; return THex::INVALID;
} }
} }
BonusList CStack::getSpellBonuses() const BonusList CStack::getSpellBonuses() const

View File

@ -47,7 +47,7 @@ struct DLL_EXPORT SiegeInfo
struct DLL_EXPORT BattleInfo : public CBonusSystemNode struct DLL_EXPORT BattleInfo : public CBonusSystemNode
{ {
ui8 side1, side2; //side1 - attacker, side2 - defender ui8 sides[2]; //sides[0] - attacker, sides[1] - defender
si32 round, activeStack; si32 round, activeStack;
ui8 siege; // = 0 ordinary battle = 1 a siege with a Fort = 2 a siege with a Citadel = 3 a siege with a Castle ui8 siege; // = 0 ordinary battle = 1 a siege with a Fort = 2 a siege with a Citadel = 3 a siege with a Castle
const CGTownInstance * town; //used during town siege - id of attacked town; -1 if not town defence const CGTownInstance * town; //used during town siege - id of attacked town; -1 if not town defence
@ -62,7 +62,7 @@ struct DLL_EXPORT BattleInfo : public CBonusSystemNode
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & side1 & side2 & round & activeStack & siege & town & tile & stacks & belligerents & obstacles h & sides & round & activeStack & siege & town & tile & stacks & belligerents & obstacles
& castSpells & si & battlefieldType; & castSpells & si & battlefieldType;
h & heroes; h & heroes;
h & static_cast<CBonusSystemNode&>(*this); h & static_cast<CBonusSystemNode&>(*this);
@ -79,9 +79,9 @@ struct DLL_EXPORT BattleInfo : public CBonusSystemNode
CStack * getStackT(THex tileID, bool onlyAlive = true); CStack * getStackT(THex tileID, bool onlyAlive = true);
const CStack * getStackT(THex tileID, bool onlyAlive = true) const; const CStack * getStackT(THex tileID, bool onlyAlive = true) const;
void getAccessibilityMap(bool *accessibility, bool twoHex, bool attackerOwned, bool addOccupiable, std::set<THex> & occupyable, bool flying, const CStack* stackToOmmit = NULL) const; //send pointer to at least 187 allocated bytes void getAccessibilityMap(bool *accessibility, bool twoHex, bool attackerOwned, bool addOccupiable, std::set<THex> & occupyable, bool flying, const CStack* stackToOmmit = NULL) const; //send pointer to at least 187 allocated bytes
static bool isAccessible(int hex, bool * accessibility, bool twoHex, bool attackerOwned, bool flying, bool lastPos); //helper for makeBFS static bool isAccessible(THex hex, bool * accessibility, bool twoHex, bool attackerOwned, bool flying, bool lastPos); //helper for makeBFS
void makeBFS(THex start, bool*accessibility, int *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 void makeBFS(THex start, bool*accessibility, THex *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<int>, int > getPath(int start, int 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::pair< std::vector<THex>, int > getPath(THex start, THex 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<THex> getAccessibility(const CStack * stack, bool addOccupiable) const; //returns vector of accessible tiles (taking into account the creature range) std::vector<THex> getAccessibility(const CStack * stack, bool addOccupiable) const; //returns vector of accessible tiles (taking into account the creature range)
bool isStackBlocked(const CStack * stack) const; //returns true if there is neighboring enemy stack bool isStackBlocked(const CStack * stack) const; //returns true if there is neighboring enemy stack
@ -90,14 +90,14 @@ struct DLL_EXPORT BattleInfo : public CBonusSystemNode
TDmgRange calculateDmgRange( const CStack* attacker, const CStack* defender, TQuantity attackerCount, TQuantity defenderCount, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky) const; //charge - number of hexes travelled before attack (for champion's jousting); returns pair <min dmg, max dmg> TDmgRange calculateDmgRange( const CStack* attacker, const CStack* defender, TQuantity attackerCount, TQuantity defenderCount, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky) const; //charge - number of hexes travelled before attack (for champion's jousting); returns pair <min dmg, max dmg>
TDmgRange calculateDmgRange(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky) const; //charge - number of hexes travelled before attack (for champion's jousting); returns pair <min dmg, max dmg> TDmgRange calculateDmgRange(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky) const; //charge - number of hexes travelled before attack (for champion's jousting); returns pair <min dmg, max dmg>
void calculateCasualties(std::map<ui32,si32> *casualties) const; //casualties are array of maps size 2 (attacker, defeneder), maps are (crid => amount) void calculateCasualties(std::map<ui32,si32> *casualties) const; //casualties are array of maps size 2 (attacker, defeneder), maps are (crid => amount)
std::set<CStack*> getAttackedCreatures(const CSpell * s, int skillLevel, ui8 attackerOwner, int destinationTile); //calculates stack affected by given spell std::set<CStack*> getAttackedCreatures(const CSpell * s, int skillLevel, ui8 attackerOwner, THex destinationTile); //calculates stack affected by given spell
static int calculateSpellDuration(const CSpell * spell, const CGHeroInstance * caster, int usedSpellPower); static int calculateSpellDuration(const CSpell * spell, const CGHeroInstance * caster, int usedSpellPower);
CStack * generateNewStack(const CStackInstance &base, int stackID, bool attackerOwned, int slot, int position) const; //helper for CGameHandler::setupBattle and spells addign new stacks to the battlefield CStack * generateNewStack(const CStackInstance &base, int stackID, bool attackerOwned, int slot, THex position) const; //helper for CGameHandler::setupBattle and spells addign new stacks to the battlefield
CStack * generateNewStack(const CStackBasicDescriptor &base, int stackID, bool attackerOwned, int slot, int position) const; //helper for CGameHandler::setupBattle and spells addign new stacks to the battlefield CStack * generateNewStack(const CStackBasicDescriptor &base, int stackID, bool attackerOwned, int slot, THex position) const; //helper for CGameHandler::setupBattle and spells addign new stacks to the battlefield
ui32 getSpellCost(const CSpell * sp, const CGHeroInstance * caster) const; //returns cost of given spell ui32 getSpellCost(const CSpell * sp, const CGHeroInstance * caster) const; //returns cost of given spell
int hexToWallPart(THex hex) const; //returns part of destructible wall / gate / keep under given hex or -1 if not found int hexToWallPart(THex hex) const; //returns part of destructible wall / gate / keep under given hex or -1 if not found
int lineToWallHex(int line) const; //returns hex with wall in given line int lineToWallHex(int line) const; //returns hex with wall in given line
std::pair<const CStack *, int> getNearestStack(const CStack * closest, boost::logic::tribool attackerOwned) const; //if attackerOwned is indetermnate, returened stack is of any owner; hex is the number of hex we should be looking from; returns (nerarest creature, predecessorHex) std::pair<const CStack *, THex> getNearestStack(const CStack * closest, boost::logic::tribool attackerOwned) const; //if attackerOwned is indetermnate, returened stack is of any owner; hex is the number of hex we should be looking from; returns (nerarest creature, predecessorHex)
ui32 calculateSpellBonus(ui32 baseDamage, const CSpell * sp, const CGHeroInstance * caster, const CStack * affectedCreature) const; ui32 calculateSpellBonus(ui32 baseDamage, const CSpell * sp, const CGHeroInstance * caster, const CStack * affectedCreature) const;
ui32 calculateSpellDmg(const CSpell * sp, const CGHeroInstance * caster, const CStack * affectedCreature, int spellSchoolLevel, int usedSpellPower) const; //calculates damage inflicted by spell ui32 calculateSpellDmg(const CSpell * sp, const CGHeroInstance * caster, const CStack * affectedCreature, int spellSchoolLevel, int usedSpellPower) const; //calculates damage inflicted by spell
ui32 calculateHealedHP(const CGHeroInstance * caster, const CSpell * spell, const CStack * stack) const; ui32 calculateHealedHP(const CGHeroInstance * caster, const CSpell * spell, const CStack * stack) const;
@ -171,7 +171,7 @@ public:
static bool isMeleeAttackPossible(const CStack * attacker, const CStack * defender, THex attackerPos = THex::INVALID, THex defenderPos = THex::INVALID); static bool isMeleeAttackPossible(const CStack * attacker, const CStack * defender, THex attackerPos = THex::INVALID, THex defenderPos = THex::INVALID);
bool doubleWide() const; bool doubleWide() const;
int occupiedHex() const; //returns number of occupied hex (not the position) if stack is double wide; otherwise -1 THex occupiedHex() const; //returns number of occupied hex (not the position) if stack is double wide; otherwise -1
void prepareAttacked(BattleStackAttacked &bsa) const; //requires bsa.damageAmout filled void prepareAttacked(BattleStackAttacked &bsa) const; //requires bsa.damageAmout filled

View File

@ -906,12 +906,12 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
h->initHero(1); h->initHero(1);
h->initObj(); h->initObj();
h->setCreature(0, 110, 1); h->setCreature(0, 110, 1);
h->setCreature(1, 69, 61); h->setCreature(1, 69, 1);
CGCreature *c = new CGCreature(); CGCreature *c = new CGCreature();
c->setOwner(1); c->setOwner(1);
c->putStack(0, new CStackInstance(69, 6)); c->putStack(0, new CStackInstance(69, 6));
//c->putStack(1, new CStackInstance(11, 3)); c->putStack(1, new CStackInstance(11, 3));
c->subID = 34; c->subID = 34;
c->initObj(); c->initObj();

View File

@ -1159,7 +1159,8 @@ struct BattleResult : public CPackForClient//3003
struct BattleStackMoved : public CPackForClient//3004 struct BattleStackMoved : public CPackForClient//3004
{ {
ui32 stack, tile; ui32 stack;
THex tile;
ui8 ending, distance, teleporting; ui8 ending, distance, teleporting;
BattleStackMoved(){type = 3004;}; BattleStackMoved(){type = 3004;};
void applyFirstCl(CClient *cl); void applyFirstCl(CClient *cl);

View File

@ -322,7 +322,7 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
BattleResultsApplied resultsApplied; BattleResultsApplied resultsApplied;
const CArmedInstance *bEndArmy1 = gs->curB->belligerents[0]; const CArmedInstance *bEndArmy1 = gs->curB->belligerents[0];
const CArmedInstance *bEndArmy2 = gs->curB->belligerents[0]; const CArmedInstance *bEndArmy2 = gs->curB->belligerents[1];
resultsApplied.player1 = bEndArmy1->tempOwner; resultsApplied.player1 = bEndArmy1->tempOwner;
resultsApplied.player2 = bEndArmy2->tempOwner; resultsApplied.player2 = bEndArmy2->tempOwner;
@ -343,8 +343,10 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
battleResult.data->exp[1] *= (100+hero2->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0f; battleResult.data->exp[1] *= (100+hero2->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0f;
ui8 sides[2]; ui8 sides[2];
sides[0] = gs->curB->side1; for(int i=0; i<2; ++i)
sides[1] = gs->curB->side2; {
sides[i] = gs->curB->sides[i];
}
ui8 loser = sides[!battleResult.data->winner]; ui8 loser = sides[!battleResult.data->winner];
CasualtiesAfterBattle cab1(bEndArmy1, gs->curB), cab2(bEndArmy2, gs->curB); //calculate casualties before deleting battle CasualtiesAfterBattle cab1(bEndArmy1, gs->curB), cab2(bEndArmy2, gs->curB); //calculate casualties before deleting battle
@ -616,7 +618,7 @@ int CGameHandler::moveStack(int stack, int dest)
//if(dists[dest] > curStack->creature->speed && !(stackAtEnd && dists[dest] == curStack->creature->speed+1)) //we can attack a stack if we can go to adjacent hex //if(dists[dest] > curStack->creature->speed && !(stackAtEnd && dists[dest] == curStack->creature->speed+1)) //we can attack a stack if we can go to adjacent hex
// return false; // return false;
std::pair< std::vector<int>, int > path = gs->curB->getPath(curStack->position, dest, accessibilityWithOccupyable, curStack->hasBonusOfType(Bonus::FLYING), curStack->doubleWide(), curStack->attackerOwned); std::pair< std::vector<THex>, int > path = gs->curB->getPath(curStack->position, dest, accessibilityWithOccupyable, curStack->hasBonusOfType(Bonus::FLYING), curStack->doubleWide(), curStack->attackerOwned);
ret = path.second; ret = path.second;
@ -3039,7 +3041,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
} }
case BattleAction::RETREAT: //retreat/flee case BattleAction::RETREAT: //retreat/flee
{ {
if( !gs->curB->battleCanFlee(ba.side ? gs->curB->side2 : gs->curB->side1) ) if( !gs->curB->battleCanFlee(ba.side ? gs->curB->sides[1] : gs->curB->sides[0]) )
break; break;
//TODO: remove retreating hero from map and place it in recruitment list //TODO: remove retreating hero from map and place it in recruitment list
BattleResult *br = new BattleResult; BattleResult *br = new BattleResult;