Переглянути джерело

* window of result of battle is shown when one of players has no live stacks
* confirm window is shown before retreat
* minor improvements

mateuszb 17 роки тому
батько
коміт
781340f339
4 змінених файлів з 80 додано та 31 видалено
  1. 55 27
      CBattleInterface.cpp
  2. 1 0
      CBattleInterface.h
  3. 2 2
      lib/NetPacks.h
  4. 22 2
      server/CGameHandler.cpp

+ 55 - 27
CBattleInterface.cpp

@@ -414,6 +414,14 @@ void CBattleInterface::bSurrenderf()
 }
 
 void CBattleInterface::bFleef()
+{
+	
+	CFunctionList<void()> ony = boost::bind(&CBattleInterface::activate,this);
+	ony += boost::bind(&CBattleInterface::reallyFlee,this);
+	LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[28],std::vector<SComponent*>(), ony, boost::bind(&CBattleInterface::activate,this), true, false);
+}
+
+void CBattleInterface::reallyFlee()
 {
 	giveCommand(4,0,0);
 	CGI->curh->changeGraphic(0, 0);
@@ -1456,41 +1464,61 @@ CBattleReslutWindow::CBattleReslutWindow(const BattleResult &br, SDL_Rect & pos,
 	CSDL_Ext::printAtMiddle(attackerName, 156, 44, GEOR16, zwykly, background);
 	CSDL_Ext::printAtMiddle(defenderName, 314, 44, GEOR16, zwykly, background);
 	//printing casualities
-	if(br.s1.size()==0)
+	for(int step = 0; step < 2; ++step)
 	{
-		CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[523], 235, 360, GEOR16, zwykly, background);
-	}
-	else
-	{
-		int xPos = 235 - (br.s1.size()*32 + (br.s1.size() - 1)*10)/2; //increment by 42 with each picture
-		int yPos = 344;
-		for(std::set<std::pair<ui32,si32> >::const_iterator it=br.s1.begin(); it!=br.s1.end(); ++it)
+		if(br.casualties[step].size()==0)
 		{
-			blitAt(graphics->smallImgs[it->first], xPos, yPos, background);
-			std::stringstream amount;
-			amount<<it->second;
-			CSDL_Ext::printAtMiddle(amount.str(), xPos+16, yPos + 42, GEOR13, zwykly, background);
-			xPos += 42;
+			CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[523], 235, 360 + 97*step, GEOR16, zwykly, background);
+		}
+		else
+		{
+			int xPos = 235 - (br.casualties[step].size()*32 + (br.casualties[step].size() - 1)*10)/2; //increment by 42 with each picture
+			int yPos = 344 + step*97;
+			for(std::set<std::pair<ui32,si32> >::const_iterator it=br.casualties[step].begin(); it!=br.casualties[step].end(); ++it)
+			{
+				blitAt(graphics->smallImgs[it->first], xPos, yPos, background);
+				std::stringstream amount;
+				amount<<it->second;
+				CSDL_Ext::printAtMiddle(amount.str(), xPos+16, yPos + 42, GEOR13, zwykly, background);
+				xPos += 42;
+			}
 		}
 	}
-	if(br.s2.size()==0)
-	{
-		CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[523], 235, 457, GEOR16, zwykly, background);
-	}
-	else
+	//printing result description
+	bool weAreAttacker = (LOCPLINT->playerID == owner->attackingHeroInstance->tempOwner);
+	switch(br.result)
 	{
-		int xPos = 235 - (br.s2.size()*32 + (br.s2.size() - 1)*10)/2; //increment by 42 with each picture
-		int yPos = 441;
-		for(std::set<std::pair<ui32,si32> >::const_iterator it=br.s2.begin(); it!=br.s2.end(); ++it)
+	case 0: //normal victory
+		if((br.winner == 0 && weAreAttacker) || (br.winner == 1 && !weAreAttacker)) //we've won
 		{
-			blitAt(graphics->smallImgs[it->first], xPos, yPos, background);
-			std::stringstream amount;
-			amount<<it->second;
-			CSDL_Ext::printAtMiddle(amount.str(), xPos+16, yPos + 42, GEOR13, zwykly, background);
-			xPos += 42;
+			CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[304], 235, 235, GEOR13, zwykly, background);
 		}
+		else
+		{
+			CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[311], 235, 235, GEOR13, zwykly, background);
+		}
+		break;
+	case 1: //flee
+		if((br.winner == 0 && weAreAttacker) || (br.winner == 1 && !weAreAttacker)) //we've won
+		{
+			CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[303], 235, 235, GEOR13, zwykly, background);
+		}
+		else
+		{
+			CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[310], 235, 235, GEOR13, zwykly, background);
+		}
+		break;
+	case 2: //surrender
+		if((br.winner == 0 && weAreAttacker) || (br.winner == 1 && !weAreAttacker)) //we've won
+		{
+			CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[302], 235, 235, GEOR13, zwykly, background);
+		}
+		else
+		{
+			CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[309], 235, 235, GEOR13, zwykly, background);
+		}
+		break;
 	}
-
 }
 
 CBattleReslutWindow::~CBattleReslutWindow()

+ 1 - 0
CBattleInterface.h

@@ -147,6 +147,7 @@ public:
 	void bOptionsf();
 	void bSurrenderf();
 	void bFleef();
+	void reallyFlee(); //performs fleeing without asking player
 	void bAutofightf();
 	void bSpellf();
 	void bWaitf();

+ 2 - 2
lib/NetPacks.h

@@ -376,7 +376,7 @@ struct BattleResult : public CPack<BattleResult>//3003
 {
 	ui8 result; //0 - normal victory; 1 - escape; 2 - surrender
 	ui8 winner; //0 - attacker, 1 - defender, [2 - draw (should be possible?)]
-	std::set<std::pair<ui32,si32> > s1, s2; //first => casualties of attackers - set of pairs crid<>number
+	std::set<std::pair<ui32,si32> > casualties[2]; //first => casualties of attackers - set of pairs crid<>number
 	ui32 exp[2]; //exp for attacker and defender
 	std::set<ui32> artifacts; //artifacts taken from loser to winner
 
@@ -385,7 +385,7 @@ struct BattleResult : public CPack<BattleResult>//3003
 	BattleResult(){type = 3003;};
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
-		h & result & winner & s1 & s2 & exp & artifacts;
+		h & result & winner & casualties[0] & casualties[1] & exp & artifacts;
 	}
 };
 

+ 22 - 2
server/CGameHandler.cpp

@@ -279,6 +279,25 @@ void CGameHandler::startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile
 				battleMadeAction.cond.wait(lock);
 			battleMadeAction.data = false;
 		}
+		//checking winning condition
+		bool hasStack[2]; //hasStack[0] - true if attacker has a living stack; defender similarily
+		hasStack[0] = hasStack[1] = false;
+		for(int b = 0; b<stacks.size(); ++b)
+		{
+			if(stacks[b]->alive)
+			{
+				hasStack[1-stacks[b]->attackerOwned] = true;
+			}
+		}
+		if(!hasStack[0] || !hasStack[1]) //somebody has won
+		{
+			BattleResult *br = new BattleResult;
+			br->result = 0;
+			br->winner = hasStack[1]; //fleeing side loses
+			br->casualties[0] = gs->curB->cas[0]; //setting casualities
+			br->casualties[1] = gs->curB->cas[1]; //as above - second side ;]
+			battleResult.set(br);
+		}
 	}
 
 	//unblock engaged players
@@ -319,6 +338,7 @@ void prepareAttack(BattleAttack &bat, CStack *att, CStack *def)
 	{
 		bat.bsa.newAmount = 0;
 		bat.bsa.flags |= 1;
+		bat.bsa.killedAmount = def->amount; //we cannot kill more creatures than we have
 	}
 	else
 	{
@@ -867,8 +887,8 @@ upgend:
 							BattleResult *br = new BattleResult;
 							br->result = 1;
 							br->winner = !ba.side; //fleeing side loses
-							br->s1 = gs->curB->cas[0]; //setting casualities
-							br->s2 = gs->curB->cas[1]; //as above - second side ;]
+							br->casualties[0] = gs->curB->cas[0]; //setting casualities
+							br->casualties[1] = gs->curB->cas[1]; //as above - second side ;]
 							battleResult.set(br);
 							break;
 						}