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)
{
THex realDest = hex;
int predecessors[BFIELD_SIZE];
THex predecessors[BFIELD_SIZE];
std::vector<int> dists = cb->battleGetDistances(stack, hex);
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);
}
int CBattleCallback::battleGetPos(int stack)
THex CBattleCallback::battleGetPos(int stack)
{
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
if(!gs->curB)
{
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)
{
if(gs->curB->stacks[g]->ID == stack)
return gs->curB->stacks[g]->position;
}
return -1;
return THex::INVALID;
}
std::vector<const CStack*> CBattleCallback::battleGetStacks(bool onlyAlive /*= true*/)
@ -592,7 +592,7 @@ bool CBattleCallback::battleCanCastSpell()
if(!gs->curB) //there is no battle
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);
else
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];
}
int CBattleCallback::battleGetWallUnderHex(int hex)
int CBattleCallback::battleGetWallUnderHex(THex hex)
{
if(!gs->curB || gs->curB->siege == 0)
{
@ -637,7 +637,7 @@ TDmgRange CBattleCallback::battleEstimateDamage(const CStack * attacker, const C
const CGHeroInstance * attackerHero, * defenderHero;
bool shooting = battleCanShoot(attacker, defender->position);
if(gs->curB->side1 == player)
if(gs->curB->sides[0] == player)
{
attackerHero = gs->curB->heroes[0];
defenderHero = gs->curB->heroes[1];
@ -1060,14 +1060,15 @@ CBattleCallback::CBattleCallback(CGameState *GS, int Player, CClient *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())
hex = stack->position;
std::vector<int> ret;
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);
for(int i=0; i<BFIELD_SIZE; ++i)
@ -1080,7 +1081,7 @@ std::vector<int> CBattleCallback::battleGetDistances(const CStack * stack, THex
if(predecessors)
{
memcpy(predecessors, pr, BFIELD_SIZE * sizeof(int));
memcpy(predecessors, pr, BFIELD_SIZE * sizeof(THex));
}
return ret;

View File

@ -80,18 +80,18 @@ public:
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 * 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 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 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 battleCanCastSpell()=0; //returns true, if caller can cast a spell
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 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 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)
@ -208,18 +208,18 @@ public:
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 * 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
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
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 battleCanCastSpell() OVERRIDE; //returns true, if caller can cast a spell
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
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>
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)

View File

@ -876,54 +876,44 @@ bool CMeleeAttack::init()
return false;
}
int reversedShift = 0; //shift of attacking stack's position due to reversing
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);
}
}
bool toReverse = isToReverse(attackingStackPosBeforeReturn, dest, owner->creDir[stack->ID], attackedStack->doubleWide(), owner->creDir[attackedStack->ID]);
}
//reversing stack if necessary
if(isToReverse(attackingStackPosBeforeReturn, dest, owner->creDir[stack->ID], attackedStack->doubleWide(), owner->creDir[attackedStack->ID]))
if(toReverse)
{
owner->addNewAnim(new CReverseAnim(owner, stack, attackingStackPosBeforeReturn, true));
return false;
}
//reversed
shooting = false;
posShiftDueToDist = reversedShift;
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())
{
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
{
case 0: case 1: case 2: case 3: case 4: case 5:
group = mutPosToGroup[mutPos];
break;
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;
break;
}
@ -1041,7 +1031,6 @@ bool CShootingAnim::init()
//attack aniamtion
posShiftDueToDist = 0;
shooting = true;
if(projectileAngle > straightAngle) //upper shot

View File

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

View File

@ -547,23 +547,23 @@ void CClient::stopConnection()
void CClient::battleStarted(const BattleInfo * info)
{
CPlayerInterface * att, * def;
if(vstd::contains(playerint, info->side1) && playerint[info->side1]->human)
att = static_cast<CPlayerInterface*>( playerint[info->side1] );
if(vstd::contains(playerint, info->sides[0]) && playerint[info->sides[0]]->human)
att = static_cast<CPlayerInterface*>( playerint[info->sides[0]] );
else
att = NULL;
if(vstd::contains(playerint, info->side2) && playerint[info->side2]->human)
def = static_cast<CPlayerInterface*>( playerint[info->side2] );
if(vstd::contains(playerint, info->sides[1]) && playerint[info->sides[1]]->human)
def = static_cast<CPlayerInterface*>( playerint[info->sides[1]] );
else
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);
if(vstd::contains(battleints,info->side1))
battleints[info->side1]->battleStart(info->belligerents[0], info->belligerents[1], info->tile, info->heroes[0], info->heroes[1], 0);
if(vstd::contains(battleints,info->side2))
battleints[info->side2]->battleStart(info->belligerents[0], info->belligerents[1], info->tile, info->heroes[0], info->heroes[1], 1);
if(vstd::contains(battleints,info->sides[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->sides[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))
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__);
#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->side2, function, __VA_ARGS__) \
BATTLE_INTERFACE_CALL_IF_PRESENT(GS(cl)->curB->sides[0], 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__)
/*
* NetPacksClient.cpp, part of VCMI engine
@ -530,7 +530,7 @@ void BattleSetActiveStack::applyCl( CClient *cl )
int playerToCall = -1; //player that will move activated stack
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
{

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)
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
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);
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);
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
makeBFS(start, accessibility, predecessor, dist, twoHex, attackerOwned, flyingCreature, false);
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
std::vector<int> path;
int curElem = dest;
std::vector<THex> path;
THex curElem = dest;
while(curElem != start)
{
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<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);
CStack * ret = new CStack(&base, owner, stackID, attackerOwned, slot);
@ -725,9 +726,9 @@ CStack * BattleInfo::generateNewStack(const CStackInstance &base, int stackID, b
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);
ret->position = position;
return ret;
@ -781,14 +782,15 @@ int BattleInfo::lineToWallHex( int line ) const
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];
std::set<THex> occupyable;
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);
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<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
{
@ -1139,7 +1141,7 @@ bool BattleInfo::battleCanShoot(const CStack * stack, THex dest) const
bool BattleInfo::battleCanFlee(int player) const
{
if (player == side1)
if (player == sides[0])
{
if (!heroes[0])
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)))
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
return false;
@ -1256,10 +1258,10 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, int terrain, int terType, const
{
CMP_stack cmpst;
BattleInfo *curB = new BattleInfo;
curB->side1 = armies[0]->tempOwner;
curB->side2 = armies[1]->tempOwner;
if(curB->side2 == 254)
curB->side2 = 255;
curB->sides[0] = armies[0]->tempOwner;
curB->sides[1] = armies[1]->tempOwner;
if(curB->sides[1] == 254)
curB->sides[1] = 255;
std::vector<CStack*> & stacks = (curB->stacks);
@ -1883,7 +1885,7 @@ bool CStack::doubleWide() const
return getCreature()->doubleWide;
}
int CStack::occupiedHex() const
THex CStack::occupiedHex() const
{
if (doubleWide())
{
@ -1894,7 +1896,7 @@ int CStack::occupiedHex() const
}
else
{
return -1;
return THex::INVALID;
}
}
BonusList CStack::getSpellBonuses() const

View File

@ -47,7 +47,7 @@ struct DLL_EXPORT SiegeInfo
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;
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
@ -62,7 +62,7 @@ struct DLL_EXPORT BattleInfo : public CBonusSystemNode
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;
h & heroes;
h & static_cast<CBonusSystemNode&>(*this);
@ -79,9 +79,9 @@ struct DLL_EXPORT BattleInfo : public CBonusSystemNode
CStack * getStackT(THex tileID, bool onlyAlive = true);
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
static bool isAccessible(int 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
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
static bool isAccessible(THex hex, bool * accessibility, bool twoHex, bool attackerOwned, bool flying, bool lastPos); //helper for makeBFS
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<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)
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, 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)
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);
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 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 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, 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
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
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 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;
@ -171,7 +171,7 @@ public:
static bool isMeleeAttackPossible(const CStack * attacker, const CStack * defender, THex attackerPos = THex::INVALID, THex defenderPos = THex::INVALID);
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

View File

@ -906,12 +906,12 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
h->initHero(1);
h->initObj();
h->setCreature(0, 110, 1);
h->setCreature(1, 69, 61);
h->setCreature(1, 69, 1);
CGCreature *c = new CGCreature();
c->setOwner(1);
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->initObj();

View File

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

View File

@ -322,7 +322,7 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
BattleResultsApplied resultsApplied;
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.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;
ui8 sides[2];
sides[0] = gs->curB->side1;
sides[1] = gs->curB->side2;
for(int i=0; i<2; ++i)
{
sides[i] = gs->curB->sides[i];
}
ui8 loser = sides[!battleResult.data->winner];
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
// 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;
@ -3039,7 +3041,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
}
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;
//TODO: remove retreating hero from map and place it in recruitment list
BattleResult *br = new BattleResult;