浏览代码

Merged changes from trunk (since r452)

Michał W. Urbańczyk 17 年之前
父节点
当前提交
dd9b506293
共有 9 个文件被更改,包括 329 次插入128 次删除
  1. 282 113
      CBattleInterface.cpp
  2. 17 3
      CBattleInterface.h
  3. 12 1
      CCallback.cpp
  4. 2 0
      CCallback.h
  5. 4 4
      CGameInterface.h
  6. 6 1
      CGameState.cpp
  7. 4 4
      CPlayerInterface.cpp
  8. 2 2
      CPlayerInterface.h
  9. 二进制
      CPreGame.cpp

+ 282 - 113
CBattleInterface.cpp

@@ -19,7 +19,7 @@ extern SDL_Color zwykly;
 SDL_Surface * CBattleInterface::cellBorder, * CBattleInterface::cellShade;
 
 CBattleInterface::CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2) 
-: printCellBorders(true), attackingHeroInstance(hero1), defendingHeroInstance(hero2), animCount(0), activeStack(-1), givenCommand(NULL)
+: printCellBorders(true), attackingHeroInstance(hero1), defendingHeroInstance(hero2), animCount(0), activeStack(-1), givenCommand(NULL), attackingInfo(NULL)
 {
 	//initializing armies
 	this->army1 = army1;
@@ -213,7 +213,10 @@ void CBattleInterface::show(SDL_Surface * to)
 		}
 	}
 	//showing selected unit's range
-	showRange(to, activeStack);
+	if(creAnims[activeStack]->getType() != 0) //don't show if unit is moving
+	{
+		showRange(to, activeStack);
+	}
 
 	//showing menu background and console
 	blitAt(menu, 0, 556, to);
@@ -244,25 +247,31 @@ void CBattleInterface::show(SDL_Surface * to)
 	{
 		stackByHex[j->second.position] = j->second.ID;
 	}
+
+	attackingShowHelper(); // handle attack animation
+
 	for(int b=0; b<187; ++b)
 	{
 		if(stackByHex[b]!=-1)
 		{
-			creAnims[stackByHex[b]]->nextFrame(to, creAnims[stackByHex[b]]->pos.x, creAnims[stackByHex[b]]->pos.y, creDir[stackByHex[b]], animCount%2==0 || creAnims[stackByHex[b]]->getType()==0, stackByHex[b]==activeStack); //increment always when moving
+			creAnims[stackByHex[b]]->nextFrame(to, creAnims[stackByHex[b]]->pos.x, creAnims[stackByHex[b]]->pos.y, creDir[stackByHex[b]], (animCount%2==0 || creAnims[stackByHex[b]]->getType()!=2) && stacks[stackByHex[b]].alive, stackByHex[b]==activeStack); //increment always when moving, never if stack died
 			//printing amount
-			if(stacks[stackByHex[b]].attackerOwned)
+			if(stacks[stackByHex[b]].amount > 0) //don't print if stack is not alive
 			{
-				CSDL_Ext::blit8bppAlphaTo24bpp(amountNormal, NULL, to, &genRect(amountNormal->h, amountNormal->w, creAnims[stackByHex[b]]->pos.x + 220, creAnims[stackByHex[b]]->pos.y + 260));
-				std::stringstream ss;
-				ss<<stacks[stackByHex[b]].amount;
-				CSDL_Ext::printAtMiddleWB(ss.str(), creAnims[stackByHex[b]]->pos.x + 220 + 14, creAnims[stackByHex[b]]->pos.y + 260 + 4, GEOR13, 20, zwykly, to);
-			}
-			else
-			{
-				CSDL_Ext::blit8bppAlphaTo24bpp(amountNormal, NULL, to, &genRect(amountNormal->h, amountNormal->w, creAnims[stackByHex[b]]->pos.x + 202, creAnims[stackByHex[b]]->pos.y + 260));
-				std::stringstream ss;
-				ss<<stacks[stackByHex[b]].amount;
-				CSDL_Ext::printAtMiddleWB(ss.str(), creAnims[stackByHex[b]]->pos.x + 202 + 14, creAnims[stackByHex[b]]->pos.y + 260 + 4, GEOR13, 20, zwykly, to);
+				if(stacks[stackByHex[b]].attackerOwned)
+				{
+					CSDL_Ext::blit8bppAlphaTo24bpp(amountNormal, NULL, to, &genRect(amountNormal->h, amountNormal->w, creAnims[stackByHex[b]]->pos.x + 220, creAnims[stackByHex[b]]->pos.y + 260));
+					std::stringstream ss;
+					ss<<stacks[stackByHex[b]].amount;
+					CSDL_Ext::printAtMiddleWB(ss.str(), creAnims[stackByHex[b]]->pos.x + 220 + 14, creAnims[stackByHex[b]]->pos.y + 260 + 4, GEOR13, 20, zwykly, to);
+				}
+				else
+				{
+					CSDL_Ext::blit8bppAlphaTo24bpp(amountNormal, NULL, to, &genRect(amountNormal->h, amountNormal->w, creAnims[stackByHex[b]]->pos.x + 202, creAnims[stackByHex[b]]->pos.y + 260));
+					std::stringstream ss;
+					ss<<stacks[stackByHex[b]].amount;
+					CSDL_Ext::printAtMiddleWB(ss.str(), creAnims[stackByHex[b]]->pos.x + 202 + 14, creAnims[stackByHex[b]]->pos.y + 260 + 4, GEOR13, 20, zwykly, to);
+				}
 			}
 		}
 	}
@@ -362,8 +371,17 @@ void CBattleInterface::stackRemoved(CStack stack)
 	creAnims.erase(stack.ID);
 }
 
-void CBattleInterface::stackKilled(int ID)
+void CBattleInterface::stackKilled(int ID, int dmg, int killed, int IDby)
 {
+	creAnims[ID]->setType(5); //death
+	for(int i=0; i<creAnims[ID]->framesInGroup(5)-1; ++i)
+	{
+		show();
+		CSDL_Ext::update();
+		SDL_framerateDelay(LOCPLINT->mainFPSmng);
+	}
+	
+	printConsoleAttacked(ID, dmg, killed, IDby);
 }
 
 void CBattleInterface::stackActivated(int number)
@@ -548,8 +566,18 @@ void CBattleInterface::stackMoved(int number, int destHex, bool startMoving, boo
 	creAnims[number]->pos.y = coords.second;
 }
 
-void CBattleInterface::stackIsAttacked(int ID)
+void CBattleInterface::stackIsAttacked(int ID, int dmg, int killed, int IDby)
 {
+	creAnims[ID]->setType(3); //getting hit
+	for(int i=0; i<creAnims[ID]->framesInGroup(3); ++i)
+	{
+		show();
+		CSDL_Ext::update();
+		SDL_framerateDelay(LOCPLINT->mainFPSmng);
+	}
+	creAnims[ID]->setType(2);
+
+	printConsoleAttacked(ID, dmg, killed, IDby);
 }
 
 void CBattleInterface::stackAttacking(int ID, int dest)
@@ -560,134 +588,97 @@ void CBattleInterface::stackAttacking(int ID, int dest)
 		switch(CBattleHex::mutualPosition(aStack.position, dest)) //attack direction
 		{
 			case 0:
-				//reverseCreature(ID, aStack.position, true);
-				creAnims[ID]->setType(10);
-				for(int i=0; i<creAnims[ID]->framesInGroup(10); ++i)
-				{
-					show();
-					CSDL_Ext::update();
-					SDL_framerateDelay(LOCPLINT->mainFPSmng);
-				}
 				//reverseCreature(ID, aStack.position, true);
 				break;
 			case 1:
-				creAnims[ID]->setType(10);
-				for(int i=0; i<creAnims[ID]->framesInGroup(10); ++i)
-				{
-					show();
-					CSDL_Ext::update();
-					SDL_framerateDelay(LOCPLINT->mainFPSmng);
-				}
 				break;
 			case 2:
-				creAnims[ID]->setType(11);
-				for(int i=0; i<creAnims[ID]->framesInGroup(11); ++i)
-				{
-					show();
-					CSDL_Ext::update();
-					SDL_framerateDelay(LOCPLINT->mainFPSmng);
-				}
 				break;
 			case 3:
-				creAnims[ID]->setType(12);
-				for(int i=0; i<creAnims[ID]->framesInGroup(12); ++i)
-				{
-					show();
-					CSDL_Ext::update();
-					SDL_framerateDelay(LOCPLINT->mainFPSmng);
-				}
 				break;
 			case 4:
-				//reverseCreature(ID, aStack.position, true);
-				creAnims[ID]->setType(12);
-				for(int i=0; i<creAnims[ID]->framesInGroup(12); ++i)
-				{
-					show();
-					CSDL_Ext::update();
-					SDL_framerateDelay(LOCPLINT->mainFPSmng);
-				}
 				//reverseCreature(ID, aStack.position, true);
 				break;
 			case 5:
-				reverseCreature(ID, aStack.position, true);
-				creAnims[ID]->setType(11);
-				for(int i=0; i<creAnims[ID]->framesInGroup(11); ++i)
-				{
-					show();
-					CSDL_Ext::update();
-					SDL_framerateDelay(LOCPLINT->mainFPSmng);
-				}
 				reverseCreature(ID, aStack.position, true);
 				break;
 		}
-		creAnims[ID]->setType(2);
 	}
 	else //else for if(aStack.creature->isDoubleWide())
 	{
 		switch(CBattleHex::mutualPosition(aStack.position, dest)) //attack direction
 		{
 			case 0:
-				reverseCreature(ID, aStack.position, true);
-				creAnims[ID]->setType(10);
-				for(int i=0; i<creAnims[ID]->framesInGroup(10); ++i)
-				{
-					show();
-					CSDL_Ext::update();
-					SDL_framerateDelay(LOCPLINT->mainFPSmng);
-				}
 				reverseCreature(ID, aStack.position, true);
 				break;
 			case 1:
-				creAnims[ID]->setType(10);
-				for(int i=0; i<creAnims[ID]->framesInGroup(10); ++i)
-				{
-					show();
-					CSDL_Ext::update();
-					SDL_framerateDelay(LOCPLINT->mainFPSmng);
-				}
 				break;
 			case 2:
-				creAnims[ID]->setType(11);
-				for(int i=0; i<creAnims[ID]->framesInGroup(11); ++i)
-				{
-					show();
-					CSDL_Ext::update();
-					SDL_framerateDelay(LOCPLINT->mainFPSmng);
-				}
 				break;
 			case 3:
-				creAnims[ID]->setType(12);
-				for(int i=0; i<creAnims[ID]->framesInGroup(12); ++i)
-				{
-					show();
-					CSDL_Ext::update();
-					SDL_framerateDelay(LOCPLINT->mainFPSmng);
-				}
 				break;
 			case 4:
-				reverseCreature(ID, aStack.position, true);
-				creAnims[ID]->setType(12);
-				for(int i=0; i<creAnims[ID]->framesInGroup(12); ++i)
-				{
-					show();
-					CSDL_Ext::update();
-					SDL_framerateDelay(LOCPLINT->mainFPSmng);
-				}
 				reverseCreature(ID, aStack.position, true);
 				break;
 			case 5:
 				reverseCreature(ID, aStack.position, true);
-				creAnims[ID]->setType(11);
-				for(int i=0; i<creAnims[ID]->framesInGroup(11); ++i)
-				{
-					show();
-					CSDL_Ext::update();
-					SDL_framerateDelay(LOCPLINT->mainFPSmng);
-				}
-				reverseCreature(ID, aStack.position, true);
 				break;
 		}
-		creAnims[ID]->setType(2);
+	}
+
+	attackingInfo = new CAttHelper;
+	attackingInfo->dest = dest;
+	attackingInfo->frame = 0;
+	attackingInfo->ID = ID;
+	attackingInfo->reversing = false;
+
+	if(aStack.creature->isDoubleWide())
+	{
+		switch(CBattleHex::mutualPosition(aStack.position, dest)) //attack direction
+		{
+			case 0:
+				attackingInfo->maxframe = creAnims[ID]->framesInGroup(10);
+				break;
+			case 1:
+				attackingInfo->maxframe = creAnims[ID]->framesInGroup(10);
+				break;
+			case 2:
+				attackingInfo->maxframe = creAnims[ID]->framesInGroup(11);
+				break;
+			case 3:
+				attackingInfo->maxframe = creAnims[ID]->framesInGroup(12);
+				break;
+			case 4:
+				attackingInfo->maxframe = creAnims[ID]->framesInGroup(12);
+				break;
+			case 5:
+				attackingInfo->maxframe = creAnims[ID]->framesInGroup(11);
+				break;
+		}
+	}
+	else //else for if(aStack.creature->isDoubleWide())
+	{
+		switch(CBattleHex::mutualPosition(aStack.position, dest)) //attack direction
+		{
+			case 0:
+				attackingInfo->maxframe = creAnims[ID]->framesInGroup(10);
+				break;
+			case 1:
+				attackingInfo->maxframe = creAnims[ID]->framesInGroup(10);
+				break;
+			case 2:
+				attackingInfo->maxframe = creAnims[ID]->framesInGroup(11);
+				break;
+			case 3:
+				attackingInfo->maxframe = creAnims[ID]->framesInGroup(12);
+				break;
+			case 4:
+				attackingInfo->maxframe = creAnims[ID]->framesInGroup(12);
+				break;
+			case 5:
+				attackingInfo->maxframe = creAnims[ID]->framesInGroup(11);
+				break;
+		}
 	}
 }
 
@@ -730,6 +721,144 @@ void CBattleInterface::showRange(SDL_Surface * to, int ID)
 	}
 }
 
+
+void CBattleInterface::attackingShowHelper()
+{
+	if(attackingInfo && !attackingInfo->reversing)
+	{
+		if(attackingInfo->frame == 0)
+		{
+			CStack aStack = LOCPLINT->cb->battleGetStackByID(attackingInfo->ID); //attacking stack
+			if(aStack.creature->isDoubleWide())
+			{
+				switch(CBattleHex::mutualPosition(aStack.position, attackingInfo->dest)) //attack direction
+				{
+					case 0:
+						creAnims[attackingInfo->ID]->setType(10);
+						break;
+					case 1:
+						creAnims[attackingInfo->ID]->setType(10);
+						break;
+					case 2:
+						creAnims[attackingInfo->ID]->setType(11);
+						break;
+					case 3:
+						creAnims[attackingInfo->ID]->setType(12);
+						break;
+					case 4:
+						creAnims[attackingInfo->ID]->setType(12);
+						break;
+					case 5:
+						creAnims[attackingInfo->ID]->setType(11);
+						break;
+				}
+			}
+			else //else for if(aStack.creature->isDoubleWide())
+			{
+				switch(CBattleHex::mutualPosition(aStack.position, attackingInfo->dest)) //attack direction
+				{
+					case 0:
+						creAnims[attackingInfo->ID]->setType(10);
+						break;
+					case 1:
+						creAnims[attackingInfo->ID]->setType(10);
+						break;
+					case 2:
+						creAnims[attackingInfo->ID]->setType(11);
+						break;
+					case 3:
+						creAnims[attackingInfo->ID]->setType(12);
+						break;
+					case 4:
+						creAnims[attackingInfo->ID]->setType(12);
+						break;
+					case 5:
+						creAnims[attackingInfo->ID]->setType(11);
+						break;
+				}
+			}
+		}
+		else if(attackingInfo->frame == (attackingInfo->maxframe - 1))
+		{
+			attackingInfo->reversing = true;
+			CStack aStack = LOCPLINT->cb->battleGetStackByID(attackingInfo->ID); //attacking stack
+			if(aStack.creature->isDoubleWide())
+			{
+				switch(CBattleHex::mutualPosition(aStack.position, attackingInfo->dest)) //attack direction
+				{
+					case 0:
+						//reverseCreature(ID, aStack.position, true);
+						break;
+					case 1:
+						break;
+					case 2:
+						break;
+					case 3:
+						break;
+					case 4:
+						//reverseCreature(ID, aStack.position, true);
+						break;
+					case 5:
+						reverseCreature(attackingInfo->ID, aStack.position, true);
+						break;
+				}
+			}
+			else //else for if(aStack.creature->isDoubleWide())
+			{
+				switch(CBattleHex::mutualPosition(aStack.position, attackingInfo->dest)) //attack direction
+				{
+					case 0:
+						reverseCreature(attackingInfo->ID, aStack.position, true);
+						break;
+					case 1:
+						break;
+					case 2:
+						break;
+					case 3:
+						break;
+					case 4:
+						reverseCreature(attackingInfo->ID, aStack.position, true);
+						break;
+					case 5:
+						reverseCreature(attackingInfo->ID, aStack.position, true);
+						break;
+				}
+			}
+			attackingInfo->reversing = false;
+			creAnims[attackingInfo->ID]->setType(2);
+			delete attackingInfo;
+			attackingInfo = NULL;
+		}
+		if(attackingInfo)
+		{
+			attackingInfo->frame++;
+		}
+	}
+}
+
+void CBattleInterface::printConsoleAttacked(int ID, int dmg, int killed, int IDby)
+{
+	char tabh[200];
+	CStack attacker = LOCPLINT->cb->battleGetStackByID(IDby);
+	CStack defender = LOCPLINT->cb->battleGetStackByID(ID);
+	int end = sprintf(tabh, CGI->generaltexth->allTexts[attacker.amount > 1 ? 377 : 376].c_str(),
+		(attacker.amount > 1 ? attacker.creature->namePl.c_str() : attacker.creature->nameSing.c_str()),
+		dmg);
+	if(killed > 0)
+	{
+		if(killed > 1)
+		{
+			sprintf(tabh + end, CGI->generaltexth->allTexts[379].c_str(), killed, defender.creature->namePl.c_str());
+		}
+		else //killed == 1
+		{
+			sprintf(tabh + end, CGI->generaltexth->allTexts[378].c_str(), defender.creature->nameSing.c_str());
+		}
+	}
+
+	console->addText(std::string(tabh));
+}
+
 void CBattleHero::show(SDL_Surface *to)
 {
 	//animation of flag
@@ -865,9 +994,14 @@ void CBattleHex::hover(bool on)
 {
 	hovered = on;
 	Hoverable::hover(on);
+	if(!on && setAlterText)
+	{
+		myInterface->console->alterTxt = std::string();
+		setAlterText = false;
+	}
 }
 
-CBattleHex::CBattleHex() : myNumber(-1), accesible(true), hovered(false), strictHovered(false), myInterface(NULL)
+CBattleHex::CBattleHex() : myNumber(-1), accesible(true), hovered(false), strictHovered(false), myInterface(NULL), setAlterText(false)
 {
 }
 
@@ -884,6 +1018,26 @@ void CBattleHex::mouseMoved(SDL_MouseMotionEvent &sEvent)
 			strictHovered = true;
 		}
 	}
+
+	if(hovered && strictHovered) //print attacked creature to console
+	{
+		if(myInterface->console->alterTxt.size() == 0 && LOCPLINT->cb->battleGetStack(myNumber) != -1 &&
+			LOCPLINT->cb->battleGetStackByPos(myNumber).owner != LOCPLINT->playerID &&
+			LOCPLINT->cb->battleGetStackByPos(myNumber).alive)
+		{
+			char tabh[160];
+			CStack attackedStack = LOCPLINT->cb->battleGetStackByPos(myNumber);
+			std::string attackedName = attackedStack.amount == 1 ? attackedStack.creature->nameSing : attackedStack.creature->namePl;
+			sprintf(tabh, CGI->generaltexth->allTexts[220].c_str(), attackedName.c_str());
+			myInterface->console->alterTxt = std::string(tabh);
+			setAlterText = true;
+		}
+	}
+	else if(setAlterText)
+	{
+		myInterface->console->alterTxt = std::string();
+		setAlterText = false;
+	}
 }
 
 void CBattleHex::clickLeft(boost::logic::tribool down)
@@ -919,7 +1073,7 @@ void CBattleHex::clickRight(boost::logic::tribool down)
 	}
 }
 
-CBattleConsole::CBattleConsole() : lastShown(-1)
+CBattleConsole::CBattleConsole() : lastShown(-1), alterTxt("")
 {
 }
 
@@ -930,7 +1084,11 @@ CBattleConsole::~CBattleConsole()
 
 void CBattleConsole::show(SDL_Surface * to)
 {
-	if(texts.size())
+	if(alterTxt.size())
+	{
+		CSDL_Ext::printAtMiddleWB(alterTxt, pos.x + pos.w/2, pos.y + 10, GEOR13, 80, zwykly, to);
+	}
+	else if(texts.size())
 	{
 		if(texts.size()==1)
 		{
@@ -948,7 +1106,18 @@ bool CBattleConsole::addText(std::string text)
 {
 	if(text.size()>70)
 		return false; //text too long!
-	texts.push_back(text);
+	int firstInToken = 0;
+	for(int i=0; i<text.size(); ++i) //tokenize
+	{
+		if(text[i] == 10)
+		{
+			texts.push_back( text.substr(firstInToken, i-firstInToken) );
+			firstInToken = i+1;
+			lastShown++;
+		}
+	}
+
+	texts.push_back( text.substr(firstInToken, text.size()) );
 	lastShown++;
 	return true;
 }

+ 17 - 3
CBattleInterface.h

@@ -26,6 +26,8 @@ class CBattleInterface;
 
 class CBattleHex : public Hoverable, public MotionInterested, public ClickableL, public ClickableR
 {
+private:
+	bool setAlterText; //if true, this hex has set alternative text in console and will clean it
 public:
 	unsigned int myNumber;
 	bool accesible;
@@ -53,8 +55,9 @@ class CBattleConsole : public IShowable, public CIntObject
 {
 private:
 	std::vector< std::string > texts; //a place where texts are stored
-	int lastShown; //las shown line of text
+	int lastShown; //last shown line of text
 public:
+	std::string alterTxt; //if it's not empty, this text is displayed
 	CBattleConsole(); //c-tor
 	~CBattleConsole(); //d-tor
 	void show(SDL_Surface * to = 0);
@@ -81,6 +84,17 @@ private:
 	int activeStack; //number of active stack; -1 - no one
 	void showRange(SDL_Surface * to, int ID); //show helper funtion ot mark range of a unit
 
+	class CAttHelper
+	{
+	public:
+		int ID; //attacking stack
+		int dest; //atacked hex
+		int frame, maxframe; //frame of animation, number of frames of animation
+		bool reversing;
+	} * attackingInfo;
+	void attackingShowHelper();
+	void printConsoleAttacked(int ID, int dmg, int killed, int IDby);
+
 public:
 	CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2); //c-tor
 	~CBattleInterface(); //d-tor
@@ -112,10 +126,10 @@ public:
 	//call-ins
 	void newStack(CStack stack); //new stack appeared on battlefield
 	void stackRemoved(CStack stack); //stack disappeared from batlefiled
-	void stackKilled(int ID); //stack has been killed (but corpses remain)
+	void stackKilled(int ID, int dmg, int killed, int IDby); //stack has been killed (but corpses remain)
 	void stackActivated(int number); //active stack has been changed
 	void stackMoved(int number, int destHex, bool startMoving, bool endMoving); //stack with id number moved to destHex
-	void stackIsAttacked(int ID); //called when stack id attacked
+	void stackIsAttacked(int ID, int dmg, int killed, int IDby); //called when stack id attacked by stack with id IDby
 	void stackAttacking(int ID, int dest); //called when stack with id ID is attacking something on hex dest
 	void newRound(int number); //caled when round is ended; number is the number of round
 	void hexLclicked(int whichOne); //hex only call-in

+ 12 - 1
CCallback.cpp

@@ -765,7 +765,13 @@ int CCallback::battleGetStack(int pos)
 {
 	for(int g=0; g<CGI->state->curB->stacks.size(); ++g)
 	{
-		if(CGI->state->curB->stacks[g]->position == pos)
+		if(CGI->state->curB->stacks[g]->position == pos ||
+				( CGI->state->curB->stacks[g]->creature->isDoubleWide() && 
+					( (CGI->state->curB->stacks[g]->attackerOwned && CGI->state->curB->stacks[g]->position-1 == pos) || 
+						(!CGI->state->curB->stacks[g]->attackerOwned && CGI->state->curB->stacks[g]->position+1 == pos)
+					) 
+				)
+			)
 			return CGI->state->curB->stacks[g]->ID;
 	}
 	return -1;
@@ -781,6 +787,11 @@ CStack CCallback::battleGetStackByID(int ID)
 	return CStack();
 }
 
+CStack CCallback::battleGetStackByPos(int pos)
+{
+	return battleGetStackByID(battleGetStack(pos));
+}
+
 int CCallback::battleGetPos(int stack)
 {
 	for(int g=0; g<CGI->state->curB->stacks.size(); ++g)

+ 2 - 0
CCallback.h

@@ -60,6 +60,7 @@ public:
 	virtual int battleGetObstaclesAtTile(int tile)=0; //returns bitfield 
 	virtual int battleGetStack(int pos)=0; //returns ID of stack on the tile
 	virtual CStack battleGetStackByID(int ID)=0; //returns stack info by given ID
+	virtual CStack battleGetStackByPos(int pos)=0; //returns stack info by given pos
 	virtual int battleGetPos(int stack)=0; //returns position (tile ID) of stack
 	//virtual int battleMakeAction(BattleAction* action)=0;//perform action with an active stack (or custom action)
 	virtual std::map<int, CStack> battleGetStacks()=0; //returns stacks on battlefield
@@ -131,6 +132,7 @@ public:
 	int battleGetObstaclesAtTile(int tile); //returns bitfield 
 	int battleGetStack(int pos); //returns ID of stack on the tile
 	CStack battleGetStackByID(int ID); //returns stack info by given ID
+	CStack battleGetStackByPos(int pos); //returns stack info by given pos
 	int battleGetPos(int stack); //returns position (tile ID) of stack
 	//int battleMakeAction(BattleAction* action);//perform action with an active stack (or custom action)
 	std::map<int, CStack> battleGetStacks(); //returns stacks on battlefield

+ 4 - 4
CGameInterface.h

@@ -72,8 +72,8 @@ public:
 	virtual void battleEnd(CCreatureSet * army1, CCreatureSet * army2, CArmedInstance *hero1, CArmedInstance *hero2, std::vector<int> capturedArtifacts, int expForWinner, bool winner){};
 	virtual void battleStackMoved(int ID, int dest, bool startMoving, bool endMoving)=0;
 	virtual void battleStackAttacking(int ID, int dest)=0;
-	virtual void battleStackIsAttacked(int ID)=0;
-	virtual void battleStackKilled(int ID)=0;
+	virtual void battleStackIsAttacked(int ID, int dmg, int killed, int IDby)=0;
+	virtual void battleStackKilled(int ID, int dmg, int killed, int IDby)=0;
 	//
 
 };
@@ -91,8 +91,8 @@ public:
 	virtual void heroCreated(const CGHeroInstance*){};
 	virtual void battleStackMoved(int ID, int dest, bool startMoving, bool endMoving){};
 	virtual void battleStackAttacking(int ID, int dest){};
-	virtual void battleStackIsAttacked(int ID){};
-	virtual void battleStackKilled(int ID){};
+	virtual void battleStackIsAttacked(int ID, int dmg, int killed, int IDby){};
+	virtual void battleStackKilled(int ID, int dmg, int killed, int IDby){};
 	virtual BattleAction activeStack(int stackID) {BattleAction ba; ba.actionType = 3; ba.stackNumber = stackID; return ba;};
 };
 #endif //CGAMEINTERFACE_H

+ 6 - 1
CGameState.cpp

@@ -474,12 +474,17 @@ bool CGameState::battleMoveCreatureStack(int ID, int dest)
 				curB->stacks[numberOfStackAtEnd]->firstHPleft -= damageFirst;
 			}
 
+			int cresInstackBefore = curB->stacks[numberOfStackAtEnd]->amount; 
 			curB->stacks[numberOfStackAtEnd]->amount -= cresKilled;
 			if(curB->stacks[numberOfStackAtEnd]->amount<=0) //stack killed
 			{
 				curB->stacks[numberOfStackAtEnd]->amount = 0;
+				LOCPLINT->battleStackKilled(curB->stacks[numberOfStackAtEnd]->ID, finalDmg, std::min(cresKilled, cresInstackBefore) , ID);
 				curB->stacks[numberOfStackAtEnd]->alive = false;
-				LOCPLINT->battleStackKilled(curB->stacks[numberOfStackAtEnd]->ID);
+			}
+			else
+			{
+				LOCPLINT->battleStackIsAttacked(curB->stacks[numberOfStackAtEnd]->ID, finalDmg, std::min(cresKilled, cresInstackBefore), ID);
 			}
 
 			//damage applied

+ 4 - 4
CPlayerInterface.cpp

@@ -2080,14 +2080,14 @@ void CPlayerInterface::battleStackAttacking(int ID, int dest)
 	dynamic_cast<CBattleInterface*>(curint)->stackAttacking(ID, dest);
 }
 
-void CPlayerInterface::battleStackIsAttacked(int ID)
+void CPlayerInterface::battleStackIsAttacked(int ID, int dmg, int killed, int IDby)
 {
-	dynamic_cast<CBattleInterface*>(curint)->stackIsAttacked(ID);
+	dynamic_cast<CBattleInterface*>(curint)->stackIsAttacked(ID, dmg, killed, IDby);
 }
 
-void CPlayerInterface::battleStackKilled(int ID)
+void CPlayerInterface::battleStackKilled(int ID, int dmg, int killed, int IDby)
 {
-	dynamic_cast<CBattleInterface*>(curint)->stackKilled(ID);
+	dynamic_cast<CBattleInterface*>(curint)->stackKilled(ID, dmg, killed, IDby);
 }
 
 void CPlayerInterface::showComp(SComponent comp)

+ 2 - 2
CPlayerInterface.h

@@ -341,8 +341,8 @@ public:
 	void battleEnd(CCreatureSet * army1, CCreatureSet * army2, CArmedInstance *hero1, CArmedInstance *hero2, std::vector<int> capturedArtifacts, int expForWinner, bool winner);
 	void battleStackMoved(int ID, int dest, bool startMoving, bool endMoving);
 	void battleStackAttacking(int ID, int dest);
-	void battleStackIsAttacked(int ID);
-	void battleStackKilled(int ID);
+	void battleStackIsAttacked(int ID, int dmg, int killed, int IDby);
+	void battleStackKilled(int ID, int dmg, int killed, int IDby);
 
 
 	//-------------//

二进制
CPreGame.cpp