diff --git a/CBattleInterface.cpp b/CBattleInterface.cpp index 5d6829f9b..d7c80b278 100644 --- a/CBattleInterface.cpp +++ b/CBattleInterface.cpp @@ -922,7 +922,8 @@ void CBattleInterface::hexLclicked(int whichOne) giveCommand(2,whichOne,activeStack); } else if(dest->owner != attackingHeroInstance->tempOwner - && LOCPLINT->cb->battleCanShoot(activeStack, whichOne)) //shooting + && LOCPLINT->cb->battleCanShoot(activeStack, whichOne) + && BattleInfo::mutualPosition(LOCPLINT->cb->battleGetPos(activeStack),whichOne) < 0 ) //shooting { giveCommand(7,whichOne,activeStack); } diff --git a/CGameState.cpp b/CGameState.cpp index bba06529d..0e49e4371 100644 --- a/CGameState.cpp +++ b/CGameState.cpp @@ -256,6 +256,7 @@ std::vector BattleInfo::getPath(int start, int dest, bool*accessibility) CStack::CStack(CCreature * C, int A, int O, int I, bool AO, int S) :creature(C),amount(A), baseAmount(A), owner(O), position(-1), ID(I), attackerOwned(AO), firstHPleft(C->hitPoints), slot(S), counterAttacks(0) { + abilities = C->abilities; state.insert(ALIVE); } void CGameState::applyNL(IPack * pack) diff --git a/CPlayerInterface.cpp b/CPlayerInterface.cpp index 7558a395d..3a85a0a7f 100644 --- a/CPlayerInterface.cpp +++ b/CPlayerInterface.cpp @@ -2946,6 +2946,11 @@ CRecrutationWindow::CRecrutationWindow(const std::vector > &C max = new AdventureMapButton("","",boost::bind(&CRecrutationWindow::Max,this),pos.x+134,pos.y+313,"IRCBTNS.DEF"); buy = new AdventureMapButton("","",boost::bind(&CRecrutationWindow::Buy,this),pos.x+212,pos.y+313,"IBY6432.DEF"); cancel = new AdventureMapButton("","",boost::bind(&CRecrutationWindow::Cancel,this),pos.x+290,pos.y+313,"ICN6432.DEF"); + if(!creatures[0].amount) + { + max->block(true); + buy->block(true); + } } CRecrutationWindow::~CRecrutationWindow() { diff --git a/config/battleBack.txt b/config/battleBack.txt index a2deb4963..a787ec3ce 100644 --- a/config/battleBack.txt +++ b/config/battleBack.txt @@ -3,7 +3,7 @@ 2 CMBKGRMT.BMP CMBKGRTR.BMP 2 CMBKSNMT.BMP CMBKSNTR.BMP 1 CMBKSWMP.BMP -2 CMBKPGH.BMP CMBKRK.BMP +2 CMBKRGH.BMP CMBKRK.BMP 1 CMBKSUB.BMP 1 CMBKLAVA.BMP 1 CMBKDECK.BMP \ No newline at end of file diff --git a/hch/CCreatureHandler.cpp b/hch/CCreatureHandler.cpp index 083fa6fe1..2fa975455 100644 --- a/hch/CCreatureHandler.cpp +++ b/hch/CCreatureHandler.cpp @@ -312,6 +312,10 @@ void CCreatureHandler::loadCreatures() ncre.abilities.insert(FLYING); if(boost::algorithm::find_first(ncre.abilityRefs, "SHOOTING_ARMY")) ncre.abilities.insert(SHOOTER); + if(boost::algorithm::find_first(ncre.abilityRefs, "const_two_attacks")) + ncre.abilities.insert(TWICE_ATTACK); + if(boost::algorithm::find_first(ncre.abilityRefs, "const_free_attack")) + ncre.abilities.insert(NO_ENEMY_RETALIATION); if(ncre.nameSing!=std::string("") && ncre.namePl!=std::string("")) { ncre.idNumber = creatures.size(); @@ -453,6 +457,7 @@ void CCreatureHandler::loadCreatures() creatures[122].abilities.insert(DOUBLE_WIDE);//water elemental should be treated as double-wide creatures[123].abilities.insert(DOUBLE_WIDE);//ice elemental should be treated as double-wide + creatures[140].abilities.insert(DOUBLE_WIDE);//boar should be treated as double-wide } void CCreatureHandler::loadAnimationInfo() diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index a6ce53611..3198b0dd3 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -898,16 +898,27 @@ upgend: sendAndApply(&bat); //counterattack if(!vstd::contains(curStack->abilities,NO_ENEMY_RETALIATION) + && stackAtEnd->alive() && !stackAtEnd->counterAttacks ) //TODO: support for multiple retaliatons per turn { prepareAttack(bat,stackAtEnd,curStack); bat.flags |= 2; sendAndApply(&bat); } + + if(vstd::contains(curStack->abilities,TWICE_ATTACK) + && curStack->alive()) + { + bat.flags = 0; + prepareAttack(bat,curStack,stackAtEnd); + sendAndApply(&bat); + } break; } case 7: //shoot { + //TODO: check arrows count + //TODO: check if stack isn't blocked by enemy CStack *curStack = gs->curB->getStack(ba.stackNumber), *destStack= gs->curB->getStackT(ba.destinationTile); @@ -915,6 +926,13 @@ upgend: prepareAttack(bat,curStack,destStack); bat.flags |= 1; + if(vstd::contains(curStack->abilities,TWICE_ATTACK) + && curStack->alive()) + { + prepareAttack(bat,curStack,destStack); + sendAndApply(&bat); + } + sendAndApply(&bat); break; }