浏览代码

Tactics more or less working (some improvements still needed, as proper updating battle GUI).

Michał W. Urbańczyk 14 年之前
父节点
当前提交
2f9ed138f6
共有 6 个文件被更改,包括 120 次插入60 次删除
  1. 1 1
      AI/GeniusAI/BattleLogic.cpp
  2. 17 20
      AI/StupidAI/StupidAI.cpp
  3. 7 3
      CCallback.cpp
  4. 14 2
      CCallback.h
  5. 80 33
      client/CBattleInterface.cpp
  6. 1 1
      lib/BattleAction.h

+ 1 - 1
AI/GeniusAI/BattleLogic.cpp

@@ -75,7 +75,7 @@ void CBattleLogic::SetCurrentTurn(int turn)
 void CBattleLogic::MakeStatistics(int currentCreatureId)
 void CBattleLogic::MakeStatistics(int currentCreatureId)
 {
 {
 	typedef std::vector<const CStack*> vector_stacks;
 	typedef std::vector<const CStack*> vector_stacks;
-	vector_stacks allStacks = m_cb->battleGetStacks(false);
+	vector_stacks allStacks = m_cb->battleGetStacks();
 	const CStack *currentStack = m_cb->battleGetStackByID(currentCreatureId);
 	const CStack *currentStack = m_cb->battleGetStackByID(currentCreatureId);
 	if(currentStack->position < 0) //turret
 	if(currentStack->position < 0) //turret
 	{
 	{

+ 17 - 20
AI/StupidAI/StupidAI.cpp

@@ -105,34 +105,31 @@ BattleAction CStupidAI::activeStack( const CStack * stack )
 	std::vector<int> dists = cb->battleGetDistances(stack);
 	std::vector<int> dists = cb->battleGetDistances(stack);
 	std::vector<EnemyInfo> enemiesShootable, enemiesReachable, enemiesUnreachable;
 	std::vector<EnemyInfo> enemiesShootable, enemiesReachable, enemiesUnreachable;
 
 
-	BOOST_FOREACH(const CStack *s, cb->battleGetStacks())
+	BOOST_FOREACH(const CStack *s, cb->battleGetStacks(IBattleCallback::ONLY_ENEMY))
 	{
 	{
-		if(s->owner != stack->owner)
+		if(cb->battleCanShoot(stack, s->position))
 		{
 		{
-			if(cb->battleCanShoot(stack, s->position))
-			{
-				enemiesShootable.push_back(s);
-			}
-			else
+			enemiesShootable.push_back(s);
+		}
+		else
+		{
+			BOOST_FOREACH(THex hex, avHexes)
 			{
 			{
-				BOOST_FOREACH(THex hex, avHexes)
+				if(CStack::isMeleeAttackPossible(stack, s, hex))
 				{
 				{
-					if(CStack::isMeleeAttackPossible(stack, s, hex))
+					std::vector<EnemyInfo>::iterator i = std::find(enemiesReachable.begin(), enemiesReachable.end(), s);
+					if(i == enemiesReachable.end())
 					{
 					{
-						std::vector<EnemyInfo>::iterator i = std::find(enemiesReachable.begin(), enemiesReachable.end(), s);
-						if(i == enemiesReachable.end())
-						{
-							enemiesReachable.push_back(s);
-							i = enemiesReachable.begin() + (enemiesReachable.size() - 1);
-						}
-
-						i->attackFrom.push_back(hex);
+						enemiesReachable.push_back(s);
+						i = enemiesReachable.begin() + (enemiesReachable.size() - 1);
 					}
 					}
-				}
 
 
-				if(!vstd::contains(enemiesReachable, s))
-					enemiesUnreachable.push_back(s);
+					i->attackFrom.push_back(hex);
+				}
 			}
 			}
+
+			if(!vstd::contains(enemiesReachable, s))
+				enemiesUnreachable.push_back(s);
 		}
 		}
 	}
 	}
 
 

+ 7 - 3
CCallback.cpp

@@ -539,10 +539,10 @@ THex CBattleCallback::battleGetPos(int stack)
 	return THex::INVALID;
 	return THex::INVALID;
 }
 }
 
 
-std::vector<const CStack*> CBattleCallback::battleGetStacks(bool onlyAlive /*= true*/)
+TStacks CBattleCallback::battleGetStacks(EStackOwnership whose /*= MINE_AND_ENEMY*/, bool onlyAlive /*= true*/)
 {
 {
 	boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
 	boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
-	std::vector<const CStack*> ret;
+	TStacks ret;
 	if(!gs->curB) //there is no battle
 	if(!gs->curB) //there is no battle
 	{
 	{
 		tlog2<<"battleGetStacks called when there is no battle!"<<std::endl;
 		tlog2<<"battleGetStacks called when there is no battle!"<<std::endl;
@@ -550,8 +550,12 @@ std::vector<const CStack*> CBattleCallback::battleGetStacks(bool onlyAlive /*= t
 	}
 	}
 
 
 	BOOST_FOREACH(const CStack *s, gs->curB->stacks)
 	BOOST_FOREACH(const CStack *s, gs->curB->stacks)
-		if(s->alive()  ||  !onlyAlive)
+	{
+		bool ownerMatches = whose == MINE_AND_ENEMY || whose == ONLY_MINE && s->owner == player;
+		bool alivenessMatches = s->alive()  ||  !onlyAlive;
+		if(ownerMatches && alivenessMatches)
 			ret.push_back(s);
 			ret.push_back(s);
+	}
 
 
 	return ret;
 	return ret;
 }
 }

+ 14 - 2
CCallback.h

@@ -44,6 +44,7 @@ struct CGPathNode;
 struct CGPath;
 struct CGPath;
 class CGGarrison;
 class CGGarrison;
 class CObstacleInstance;
 class CObstacleInstance;
+typedef std::vector<const CStack*> TStacks;
 
 
 struct InfoAboutTown
 struct InfoAboutTown
 {
 {
@@ -79,6 +80,11 @@ public:
 		OK, GENERAL_CASTING_PROBLEM, ANOTHER_ELEMENTAL_SUMMONED
 		OK, GENERAL_CASTING_PROBLEM, ANOTHER_ELEMENTAL_SUMMONED
 	};
 	};
 
 
+	enum EStackOwnership
+	{
+		ONLY_MINE, ONLY_ENEMY, MINE_AND_ENEMY
+	};
+
 	bool waitTillRealize; //if true, request functions will return after they are realized by server
 	bool waitTillRealize; //if true, request functions will return after they are realized by server
 	//battle
 	//battle
 	virtual int battleGetBattlefieldType()=0; //   1. sand/shore   2. sand/mesas   3. dirt/birches   4. dirt/hills   5. dirt/pines   6. grass/hills   7. grass/pines   8. lava   9. magic plains   10. snow/mountains   11. snow/trees   12. subterranean   13. swamp/trees   14. fiery fields   15. rock lands   16. magic clouds   17. lucid pools   18. holy ground   19. clover field   20. evil fog   21. "favourable winds" text on magic plains background   22. cursed ground   23. rough   24. ship to ship   25. ship
 	virtual int battleGetBattlefieldType()=0; //   1. sand/shore   2. sand/mesas   3. dirt/birches   4. dirt/hills   5. dirt/pines   6. grass/hills   7. grass/pines   8. lava   9. magic plains   10. snow/mountains   11. snow/trees   12. subterranean   13. swamp/trees   14. fiery fields   15. rock lands   16. magic clouds   17. lucid pools   18. holy ground   19. clover field   20. evil fog   21. "favourable winds" text on magic plains background   22. cursed ground   23. rough   24. ship to ship   25. ship
@@ -88,7 +94,7 @@ public:
 	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 THex 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 TStacks battleGetStacks(EStackOwnership whose = MINE_AND_ENEMY, 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, THex * 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]
@@ -108,6 +114,12 @@ public:
 	virtual si8 battleGetTacticDist() =0; //returns tactic distance for calling player or 0 if player is not in tactic phase
 	virtual si8 battleGetTacticDist() =0; //returns tactic distance for calling player or 0 if player is not in tactic phase
 	virtual ui8 battleGetMySide() =0; //return side of player in battle (attacker/defender)
 	virtual ui8 battleGetMySide() =0; //return side of player in battle (attacker/defender)
 	virtual bool battleMakeTacticAction(BattleAction * action) =0; // performs tactic phase actions
 	virtual bool battleMakeTacticAction(BattleAction * action) =0; // performs tactic phase actions
+
+	//convienience methods using the ones above
+	TStacks battleGetAllStacks() //returns all stacks, alive or dead or undead or mechanical :)
+	{
+		return battleGetStacks(MINE_AND_ENEMY, false);
+	}
 };
 };
 
 
 class ICallback : public virtual IBattleCallback
 class ICallback : public virtual IBattleCallback
@@ -220,7 +232,7 @@ public:
 	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
 	THex 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
+	TStacks battleGetStacks(EStackOwnership whose = MINE_AND_ENEMY, 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, 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
 	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

+ 80 - 33
client/CBattleInterface.cpp

@@ -1134,7 +1134,7 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe
 	//initializing armies
 	//initializing armies
 	this->army1 = army1;
 	this->army1 = army1;
 	this->army2 = army2;
 	this->army2 = army2;
-	std::vector<const CStack*> stacks = curInt->cb->battleGetStacks(false);
+	std::vector<const CStack*> stacks = curInt->cb->battleGetAllStacks();
 	BOOST_FOREACH(const CStack *s, stacks)
 	BOOST_FOREACH(const CStack *s, stacks)
 	{
 	{
 		newStack(s);
 		newStack(s);
@@ -1170,8 +1170,7 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe
 	}
 	}
 	
 	
 	//preparing menu background
 	//preparing menu background
-	menu = BitmapHandler::loadBitmap("CBAR.BMP");
-	graphics->blueToPlayersAdv(menu, hero1->tempOwner);
+	//graphics->blueToPlayersAdv(menu, hero1->tempOwner);
 
 
 	//preparing graphics for displaying amounts of creatures
 	//preparing graphics for displaying amounts of creatures
 	amountNormal = BitmapHandler::loadBitmap("CMNUMWIN.BMP");
 	amountNormal = BitmapHandler::loadBitmap("CMNUMWIN.BMP");
@@ -1191,9 +1190,9 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe
 	transformPalette(amountEffNeutral, 1.00f, 1.00f, 0.18f);
 	transformPalette(amountEffNeutral, 1.00f, 1.00f, 0.18f);
 
 
 	////blitting menu background and terrain
 	////blitting menu background and terrain
-	blitAt(background, pos.x, pos.y);
-	blitAt(menu, pos.x, 556 + pos.y);
-	CSDL_Ext::update();
+// 	blitAt(background, pos.x, pos.y);
+// 	blitAt(menu, pos.x, 556 + pos.y);
+// 	CSDL_Ext::update();
 
 
 	//preparing buttons and console
 	//preparing buttons and console
 	bOptions = new AdventureMapButton (CGI->generaltexth->zelp[381].first, CGI->generaltexth->zelp[381].second, boost::bind(&CBattleInterface::bOptionsf,this), 3 + pos.x, 561 + pos.y, "icm003.def", SDLK_o);
 	bOptions = new AdventureMapButton (CGI->generaltexth->zelp[381].first, CGI->generaltexth->zelp[381].second, boost::bind(&CBattleInterface::bOptionsf,this), 3 + pos.x, 561 + pos.y, "icm003.def", SDLK_o);
@@ -1221,7 +1220,14 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe
 		btactEnd = new AdventureMapButton(std::string(), std::string(), boost::bind(&CBattleInterface::bEndTacticPhase,this), 419 + pos.x, 560 + pos.y, "icm012.def", SDLK_RETURN);
 		btactEnd = new AdventureMapButton(std::string(), std::string(), boost::bind(&CBattleInterface::bEndTacticPhase,this), 419 + pos.x, 560 + pos.y, "icm012.def", SDLK_RETURN);
 		bDefence->block(true);
 		bDefence->block(true);
 		bWait->block(true);
 		bWait->block(true);
+		menu = BitmapHandler::loadBitmap("COPLACBR.BMP");
 	}
 	}
+	else
+	{
+		menu = BitmapHandler::loadBitmap("CBAR.BMP");
+		btactEnd = btactNext = NULL;
+	}
+	graphics->blueToPlayersAdv(menu, curInt->playerID);
 
 
 	//loading hero animations
 	//loading hero animations
 	if(hero1) // attacking hero
 	if(hero1) // attacking hero
@@ -1340,18 +1346,11 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe
 		children.push_back(&bfield[i]);
 		children.push_back(&bfield[i]);
 	}
 	}
 
 
-	if(curInt->cb->battleGetTacticDist())
+	if(tacticsMode)
 	{
 	{
-		BOOST_FOREACH(const CStack *s, curInt->cb->battleGetStacks())
-		{
-			if(s->owner == curInt->playerID)
-			{
-				active = 1;
-				stackActivated(s);
-				active = 0;
-				break;
-			}
-		}
+		active = 1;
+		bTacticNextStack();
+		active = 0;
 	}
 	}
 }
 }
 
 
@@ -1435,8 +1434,6 @@ void CBattleInterface::activate()
 	bSpell->activate();
 	bSpell->activate();
 	bWait->activate();
 	bWait->activate();
 	bDefence->activate();
 	bDefence->activate();
-	bConsoleUp->activate();
-	bConsoleDown->activate();
 	for(int b=0; b<BFIELD_SIZE; ++b)
 	for(int b=0; b<BFIELD_SIZE; ++b)
 	{
 	{
 		bfield[b].activate();
 		bfield[b].activate();
@@ -1448,6 +1445,17 @@ void CBattleInterface::activate()
 	if(curInt->sysOpts.showQueue)
 	if(curInt->sysOpts.showQueue)
 		queue->activate();
 		queue->activate();
 
 
+	if(tacticsMode)
+	{
+		btactNext->activate();
+		btactEnd->activate();
+	}
+	else
+	{
+		bConsoleUp->activate();
+		bConsoleDown->activate();
+	}
+
 	LOCPLINT->cingconsole->activate();
 	LOCPLINT->cingconsole->activate();
 }
 }
 
 
@@ -1463,8 +1471,6 @@ void CBattleInterface::deactivate()
 	bSpell->deactivate();
 	bSpell->deactivate();
 	bWait->deactivate();
 	bWait->deactivate();
 	bDefence->deactivate();
 	bDefence->deactivate();
-	bConsoleUp->deactivate();
-	bConsoleDown->deactivate();
 	for(int b=0; b<BFIELD_SIZE; ++b)
 	for(int b=0; b<BFIELD_SIZE; ++b)
 	{
 	{
 		bfield[b].deactivate();
 		bfield[b].deactivate();
@@ -1476,12 +1482,23 @@ void CBattleInterface::deactivate()
 	if(curInt->sysOpts.showQueue)
 	if(curInt->sysOpts.showQueue)
 		queue->deactivate();
 		queue->deactivate();
 
 
+	if(tacticsMode)
+	{
+		btactNext->deactivate();
+		btactEnd->deactivate();
+	}
+	else
+	{
+		bConsoleUp->deactivate();
+		bConsoleDown->deactivate();
+	}
+
 	LOCPLINT->cingconsole->deactivate();
 	LOCPLINT->cingconsole->deactivate();
 }
 }
 
 
 void CBattleInterface::show(SDL_Surface * to)
 void CBattleInterface::show(SDL_Surface * to)
 {
 {
-	std::vector<const CStack*> stacks = curInt->cb->battleGetStacks(false); //used in a few places
+	std::vector<const CStack*> stacks = curInt->cb->battleGetAllStacks(); //used in a few places
 	++animCount;
 	++animCount;
 	if(!to) //"evaluating" to
 	if(!to) //"evaluating" to
 		to = screen;
 		to = screen;
@@ -1694,7 +1711,18 @@ void CBattleInterface::show(SDL_Surface * to)
 
 
 	//showing menu background and console
 	//showing menu background and console
 	blitAt(menu, pos.x, 556 + pos.y, to);
 	blitAt(menu, pos.x, 556 + pos.y, to);
-	console->show(to);
+	
+	if(tacticsMode)
+	{
+		btactNext->show(to);
+		btactEnd->show(to);
+	}
+	else
+	{
+		console->show(to);
+		bConsoleUp->show(to);
+		bConsoleDown->show(to);
+	}
 
 
 	//showing buttons
 	//showing buttons
 	bOptions->show(to);
 	bOptions->show(to);
@@ -1704,8 +1732,6 @@ void CBattleInterface::show(SDL_Surface * to)
 	bSpell->show(to);
 	bSpell->show(to);
 	bWait->show(to);
 	bWait->show(to);
 	bDefence->show(to);
 	bDefence->show(to);
-	bConsoleUp->show(to);
-	bConsoleDown->show(to);
 
 
 	//showing window with result of battle
 	//showing window with result of battle
 	if(resWindow)
 	if(resWindow)
@@ -2293,7 +2319,7 @@ void CBattleInterface::stackAttacking( const CStack * attacker, THex dest, const
 void CBattleInterface::newRoundFirst( int round )
 void CBattleInterface::newRoundFirst( int round )
 {
 {
 	//handle regeneration
 	//handle regeneration
-	std::vector<const CStack*> stacks = curInt->cb->battleGetStacks(false);
+	std::vector<const CStack*> stacks = curInt->cb->battleGetStacks(); //gets only alive stacks
 	BOOST_FOREACH(const CStack *s, stacks)
 	BOOST_FOREACH(const CStack *s, stacks)
 	{
 	{
 		//don't show animation when no HP is regenerated
 		//don't show animation when no HP is regenerated
@@ -2302,13 +2328,13 @@ void CBattleInterface::newRoundFirst( int round )
 			continue;
 			continue;
 		}
 		}
 
 
-		if( s->hasBonusOfType(Bonus::HP_REGENERATION) && s->alive() )
+		if( s->hasBonusOfType(Bonus::HP_REGENERATION))
 			displayEffect(74, s->position);
 			displayEffect(74, s->position);
 
 
-		if( s->hasBonusOfType(Bonus::FULL_HP_REGENERATION, 0) && s->alive() )
+		if( s->hasBonusOfType(Bonus::FULL_HP_REGENERATION, 0))
 			displayEffect(4, s->position);
 			displayEffect(4, s->position);
 
 
-		if( s->hasBonusOfType(Bonus::FULL_HP_REGENERATION, 1) && s->alive() )
+		if( s->hasBonusOfType(Bonus::FULL_HP_REGENERATION, 1))
 			displayEffect(74, s->position);
 			displayEffect(74, s->position);
 	}
 	}
 	waitForAnims();
 	waitForAnims();
@@ -2358,8 +2384,7 @@ void CBattleInterface::giveCommand(ui8 action, THex tile, ui32 stack, si32 addit
 	{
 	{
 		curInt->cb->battleMakeTacticAction(ba);
 		curInt->cb->battleMakeTacticAction(ba);
 		delNull(ba);
 		delNull(ba);
-		// TODO:
-		// activate next stack
+		bTacticNextStack();
 	}
 	}
 }
 }
 
 
@@ -3341,6 +3366,23 @@ void CBattleInterface::showQueue()
 
 
 void CBattleInterface::startAction(const BattleAction* action)
 void CBattleInterface::startAction(const BattleAction* action)
 {
 {
+	if(action->actionType == BattleAction::END_TACTIC_PHASE)
+	{
+		menu = BitmapHandler::loadBitmap("CBAR.bmp");
+		graphics->blueToPlayersAdv(menu, curInt->playerID);
+		if(active)
+		{
+			tacticsMode = false;
+			btactEnd->deactivate();
+			btactNext->deactivate();
+			bConsoleDown->activate();
+			bConsoleUp->activate();
+		}
+		redraw();
+
+		return;
+	}
+
 	const CStack *stack = curInt->cb->battleGetStackByID(action->stackNumber);
 	const CStack *stack = curInt->cb->battleGetStackByID(action->stackNumber);
 
 
 	if(stack)
 	if(stack)
@@ -3423,12 +3465,17 @@ void CBattleInterface::bEndTacticPhase()
 {
 {
 	BattleAction endt = BattleAction::makeEndOFTacticPhase(curInt->cb->battleGetMySide());
 	BattleAction endt = BattleAction::makeEndOFTacticPhase(curInt->cb->battleGetMySide());
 	curInt->cb->battleMakeTacticAction(&endt);
 	curInt->cb->battleMakeTacticAction(&endt);
-
+	btactEnd->block(true);
 }
 }
 
 
 void CBattleInterface::bTacticNextStack()
 void CBattleInterface::bTacticNextStack()
 {
 {
-
+	TStacks stacksOfMine = curInt->cb->battleGetStacks(IBattleCallback::ONLY_MINE);
+	TStacks::iterator it = vstd::find(stacksOfMine, activeStack);
+	if(it != stacksOfMine.end() && ++it != stacksOfMine.end())
+		stackActivated(*it);
+	else
+		stackActivated(stacksOfMine.front());
 }
 }
 
 
 void CBattleHero::show(SDL_Surface *to)
 void CBattleHero::show(SDL_Surface *to)

+ 1 - 1
lib/BattleAction.h

@@ -23,7 +23,7 @@ struct DLL_EXPORT BattleAction
 	{
 	{
 		END_TACTIC_PHASE = -2, INVALID = -1, NO_ACTION = 0, HERO_SPELL, WALK, DEFEND, RETREAT, SURRENDER, WALK_AND_ATTACK, SHOOT, WAIT, CATAPULT, MONSTER_SPELL, BAD_MORALE, STACK_HEAL
 		END_TACTIC_PHASE = -2, INVALID = -1, NO_ACTION = 0, HERO_SPELL, WALK, DEFEND, RETREAT, SURRENDER, WALK_AND_ATTACK, SHOOT, WAIT, CATAPULT, MONSTER_SPELL, BAD_MORALE, STACK_HEAL
 	};
 	};
-	ui8 actionType; //use ActionType enum for values
+	si8 actionType; //use ActionType enum for values
 		//10 = Monster casts a spell (i.e. Faerie Dragons)	11 - Bad morale freeze	12 - stacks heals another stack
 		//10 = Monster casts a spell (i.e. Faerie Dragons)	11 - Bad morale freeze	12 - stacks heals another stack
 	THex destinationTile;
 	THex destinationTile;
 	si32 additionalInfo; // e.g. spell number if type is 1 || 10; tile to attack if type is 6
 	si32 additionalInfo; // e.g. spell number if type is 1 || 10; tile to attack if type is 6