Browse Source

* fixed attacking with shooting stack in a close-combat
* max/buy buttons in recruitment window are not active when there are no available creatures to buy
* reading no-retalation and twice-attack abilities
* boars are treated as two-hex
* dead stack won't retaliate
* support for double attack (not tested)
* one more typo fixed in battle backgrounds list

Michał W. Urbańczyk 17 năm trước cách đây
mục cha
commit
dc7d324045

+ 2 - 1
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);
 		}

+ 1 - 0
CGameState.cpp

@@ -256,6 +256,7 @@ std::vector<int> 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)

+ 5 - 0
CPlayerInterface.cpp

@@ -2946,6 +2946,11 @@ CRecrutationWindow::CRecrutationWindow(const std::vector<std::pair<int,int> > &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()
 {

+ 1 - 1
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

+ 5 - 0
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()

+ 18 - 0
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;
 						}