소스 검색

* fixed defending creature in battle end window (slot id was used instead of creature id)
* redone casualties calculacion
* redone battle-end checking (now it works always)
* further fixes/checkings around netcode

Michał W. Urbańczyk 17 년 전
부모
커밋
5e0986f9d8
6개의 변경된 파일89개의 추가작업 그리고 63개의 파일을 삭제
  1. 3 3
      CBattleInterface.cpp
  2. 37 23
      CGameState.cpp
  3. 7 7
      CGameState.h
  4. 14 4
      lib/Connection.cpp
  5. 26 26
      server/CGameHandler.cpp
  6. 2 0
      server/CGameHandler.h

+ 3 - 3
CBattleInterface.cpp

@@ -1449,10 +1449,10 @@ CBattleReslutWindow::CBattleReslutWindow(const BattleResult &br, SDL_Rect & pos,
 		int bestPower = 0;
 		int bestPower = 0;
 		for(std::map<si32,std::pair<ui32,si32> >::const_iterator it = owner->army2->slots.begin(); it!=owner->army2->slots.end(); ++it)
 		for(std::map<si32,std::pair<ui32,si32> >::const_iterator it = owner->army2->slots.begin(); it!=owner->army2->slots.end(); ++it)
 		{
 		{
-			if( CGI->creh->creatures[it->first].AIValue > bestPower)
+			if( CGI->creh->creatures[it->second.first].AIValue > bestPower)
 			{
 			{
-				bestPower = CGI->creh->creatures[it->first].AIValue;
-				bestMonsterID = it->first;
+				bestPower = CGI->creh->creatures[it->second.first].AIValue;
+				bestMonsterID = it->second.first;
 			}
 			}
 		}
 		}
 		SDL_BlitSurface(graphics->bigImgs[bestMonsterID], NULL, background, &genRect(64, 58, 391, 38));
 		SDL_BlitSurface(graphics->bigImgs[bestMonsterID], NULL, background, &genRect(64, 58, 391, 38));

+ 37 - 23
CGameState.cpp

@@ -253,8 +253,8 @@ std::vector<int> BattleInfo::getPath(int start, int dest, bool*accessibility)
 	return path;
 	return path;
 }
 }
 
 
-CStack::CStack(CCreature * C, int A, int O, int I, bool AO)
-	:creature(C),amount(A),owner(O), alive(true), position(-1), ID(I), attackerOwned(AO), firstHPleft(C->hitPoints)
+CStack::CStack(CCreature * C, int A, int O, int I, bool AO, int S)
+	:creature(C),amount(A), baseAmount(A), owner(O), alive(true), position(-1), ID(I), attackerOwned(AO), firstHPleft(C->hitPoints), slot(S)
 {
 {
 }
 }
 void CGameState::applyNL(IPack * pack)
 void CGameState::applyNL(IPack * pack)
@@ -552,27 +552,6 @@ void CGameState::applyNL(IPack * pack)
 			at->amount = br->newAmount;
 			at->amount = br->newAmount;
 			at->firstHPleft = br->newHP;
 			at->firstHPleft = br->newHP;
 			at->alive = !br->killed();
 			at->alive = !br->killed();
-			
-			if(br->killedAmount>0) //setting casualities
-			{
-				bool found = false;
-				for(std::set<std::pair<ui32,si32> >::iterator it = curB->cas[1 - at->attackerOwned].begin(); it!=curB->cas[1 - at->attackerOwned].end(); ++it)
-				{
-					if(it->first == at->creature->idNumber)
-					{
-						found = true;
-						std::pair<ui32,si32>  mod = *it;
-						mod.second += br->killedAmount;
-
-						curB->cas[1 - at->attackerOwned].insert(it, mod);
-						curB->cas[1 - at->attackerOwned].erase(it);
-					}
-				}
-				if(!found)
-				{
-					curB->cas[1 - at->attackerOwned].insert(std::make_pair(at->creature->idNumber, br->killedAmount));
-				}
-			}
 			break;
 			break;
 		}
 		}
 	case 3006:
 	case 3006:
@@ -1341,3 +1320,38 @@ int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender)
 
 
 	return (float)damageBase * (float)attacker->amount * dmgBonusMultiplier;
 	return (float)damageBase * (float)attacker->amount * dmgBonusMultiplier;
 }
 }
+
+void BattleInfo::calculateCasualties( std::set<std::pair<ui32,si32> > *casualties )
+{
+	for(int i=0; i<stacks.size();i++)//setting casualties
+	{
+		if(!stacks[i]->alive)
+		{
+			casualties[!stacks[i]->attackerOwned].insert(std::pair<ui32,si32>(stacks[i]->creature->idNumber,stacks[i]->baseAmount));
+		}
+		else if(stacks[i]->amount != stacks[i]->baseAmount)
+		{
+			casualties[!stacks[i]->attackerOwned].insert(std::pair<ui32,si32>(stacks[i]->creature->idNumber,stacks[i]->baseAmount - stacks[i]->amount));
+		}
+	}
+	//if(br->killedAmount>0) 
+	//{
+	//	bool found = false;
+	//	for(std::set<std::pair<ui32,si32> >::iterator it = curB->cas[1 - at->attackerOwned].begin(); it!=curB->cas[1 - at->attackerOwned].end(); ++it)
+	//	{
+	//		if(it->first == at->creature->idNumber)
+	//		{
+	//			found = true;
+	//			std::pair<ui32,si32>  mod = *it;
+	//			mod.second += br->killedAmount;
+
+	//			curB->cas[1 - at->attackerOwned].insert(it, mod);
+	//			curB->cas[1 - at->attackerOwned].erase(it);
+	//		}
+	//	}
+	//	if(!found)
+	//	{
+	//		curB->cas[1 - at->attackerOwned].insert(std::make_pair(at->creature->idNumber, br->killedAmount));
+	//	}
+	//}
+}

+ 7 - 7
CGameState.h

@@ -58,11 +58,10 @@ struct DLL_EXPORT BattleInfo
 	si32 hero1, hero2;
 	si32 hero1, hero2;
 	CCreatureSet army1, army2;
 	CCreatureSet army1, army2;
 	std::vector<CStack*> stacks;
 	std::vector<CStack*> stacks;
-	std::set<std::pair<ui32,si32> > cas[2]; //first => casualties of attackers - set of pairs crid<>number
 
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 	{
-		h & side1 & side2 & round & activeStack & siege & tile & stacks & army1 & army2 & hero1 & hero2 & cas[0] & cas[1];
+		h & side1 & side2 & round & activeStack & siege & tile & stacks & army1 & army2 & hero1 & hero2;
 	}
 	}
 	CStack * getStack(int stackID);
 	CStack * getStack(int stackID);
 	CStack * getStackT(int tileID);
 	CStack * getStackT(int tileID);
@@ -75,6 +74,7 @@ struct DLL_EXPORT BattleInfo
 	static signed char mutualPosition(int hex1, int hex2); //returns info about mutual position of given hexes (-1 - they're distant, 0 - left top, 1 - right top, 2 - right, 3 - right bottom, 4 - left bottom, 5 - left)
 	static signed char mutualPosition(int hex1, int hex2); //returns info about mutual position of given hexes (-1 - they're distant, 0 - left top, 1 - right top, 2 - right, 3 - right bottom, 4 - left bottom, 5 - left)
 	static std::vector<int> neighbouringTiles(int hex);
 	static std::vector<int> neighbouringTiles(int hex);
 	static int calculateDmg(const CStack* attacker, const CStack* defender); //TODO: add additional conditions and require necessary data
 	static int calculateDmg(const CStack* attacker, const CStack* defender); //TODO: add additional conditions and require necessary data
+	void calculateCasualties(std::set<std::pair<ui32,si32> > *casualties);
 };
 };
 
 
 class DLL_EXPORT CStack
 class DLL_EXPORT CStack
@@ -82,15 +82,15 @@ class DLL_EXPORT CStack
 public:
 public:
 	ui32 ID; //unique ID of stack
 	ui32 ID; //unique ID of stack
 	CCreature * creature;
 	CCreature * creature;
-	ui32 amount;
+	ui32 amount, baseAmount;
 	ui32 firstHPleft; //HP of first creature in stack
 	ui32 firstHPleft; //HP of first creature in stack
-	ui8 owner;
+	ui8 owner, slot;  //owner - player colour (255 for neutrals), slot - position in garrison (255 for neutrals/called creatures)
 	ui8 attackerOwned; //if true, this stack is owned by attakcer (this one from left hand side of battle)
 	ui8 attackerOwned; //if true, this stack is owned by attakcer (this one from left hand side of battle)
 	ui16 position; //position on battlefield
 	ui16 position; //position on battlefield
 	ui8 alive; //true if it is alive
 	ui8 alive; //true if it is alive
 
 
-	CStack(CCreature * C, int A, int O, int I, bool AO);
-	CStack() : creature(NULL),amount(-1),owner(255), alive(true), position(-1), ID(-1), attackerOwned(true), firstHPleft(-1){};
+	CStack(CCreature * C, int A, int O, int I, bool AO, int S);
+	CStack() : creature(NULL),amount(-1),owner(255), alive(true), position(-1), ID(-1), attackerOwned(true), firstHPleft(-1), slot(255), baseAmount(-1){};
 
 
 	template <typename Handler> void save(Handler &h, const int version)
 	template <typename Handler> void save(Handler &h, const int version)
 	{
 	{
@@ -104,7 +104,7 @@ public:
 	}
 	}
 	template <typename Handler> void serialize(Handler &h, const int version)
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 	{
-		h & ID & amount & firstHPleft & owner & attackerOwned & position & alive;
+		h & ID & amount & baseAmount & firstHPleft & owner & attackerOwned & position & alive;
 		if(h.saving)
 		if(h.saving)
 			save(h,version);
 			save(h,version);
 		else
 		else

+ 14 - 4
lib/Connection.cpp

@@ -56,13 +56,16 @@ CConnection::CConnection(std::string host, std::string port, std::string Name, s
 		std::cout<< "Critical problem: No endpoints found!" << std::endl;
 		std::cout<< "Critical problem: No endpoints found!" << std::endl;
 		goto connerror1;
 		goto connerror1;
 	}
 	}
+	int i=0;
 	while(pom != end)
 	while(pom != end)
 	{
 	{
-		std::cout << (boost::asio::ip::tcp::endpoint&)*pom << std::endl;
+		std::cout << "\t" << i << ": " << (boost::asio::ip::tcp::endpoint&)*pom << std::endl;
 		pom++;
 		pom++;
 	}
 	}
+	i=0;
 	while(endpoint_iterator != end)
 	while(endpoint_iterator != end)
 	{
 	{
+		std::cout << "Trying connection to " << (boost::asio::ip::tcp::endpoint&)*endpoint_iterator << "  (" << i++ << ")" << std::endl;
 		socket->connect(*endpoint_iterator, error);
 		socket->connect(*endpoint_iterator, error);
 		if(!error)
 		if(!error)
 		{
 		{
@@ -71,18 +74,20 @@ CConnection::CConnection(std::string host, std::string port, std::string Name, s
 		}
 		}
 		else
 		else
 		{
 		{
-			std::cout << "Problem with connecting. " << std::endl;
+			std::cout << "Problem with connecting: " << std::endl <<  error << std::endl;
 		}
 		}
+		endpoint_iterator++;
 	}
 	}
 
 
 	//we shouldn't be here - error handling
 	//we shouldn't be here - error handling
 connerror1:
 connerror1:
+	std::cout << "Something went wrong... checking for error info" << std::endl;
 	if(error)
 	if(error)
 		std::cout << error <<std::endl;
 		std::cout << error <<std::endl;
 	else
 	else
 		std::cout << "No error info. " << std::endl;
 		std::cout << "No error info. " << std::endl;
 	delete io_service;
 	delete io_service;
-	delete socket;	
+	//delete socket;	
 	throw std::string("Can't establish connection :(");
 	throw std::string("Can't establish connection :(");
 }
 }
 CConnection::CConnection(
 CConnection::CConnection(
@@ -99,7 +104,12 @@ CConnection::CConnection(boost::asio::basic_socket_acceptor<boost::asio::ip::tcp
 	boost::system::error_code error = asio::error::host_not_found;
 	boost::system::error_code error = asio::error::host_not_found;
 	socket = new tcp::socket(*io_service);
 	socket = new tcp::socket(*io_service);
 	acceptor->accept(*socket,error);
 	acceptor->accept(*socket,error);
-	if (error){ delete socket;	throw "Can't establish connection :("; }
+	if (error)
+	{ 
+		std::cout << "Error on accepting: " << std::endl << error << std::endl;
+		delete socket;	
+		throw "Can't establish connection :("; 
+	}
 	init();
 	init();
 }
 }
 int CConnection::write(const void * data, unsigned size)
 int CConnection::write(const void * data, unsigned size)

+ 26 - 26
server/CGameHandler.cpp

@@ -271,32 +271,11 @@ void CGameHandler::startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile
 			BattleSetActiveStack sas;
 			BattleSetActiveStack sas;
 			sas.stack = stacks[i]->ID;
 			sas.stack = stacks[i]->ID;
 			sendAndApply(&sas);
 			sendAndApply(&sas);
-
-			//wait for response about battle action
-
 			boost::unique_lock<boost::mutex> lock(battleMadeAction.mx);
 			boost::unique_lock<boost::mutex> lock(battleMadeAction.mx);
 			while(!battleMadeAction.data)
 			while(!battleMadeAction.data)
 				battleMadeAction.cond.wait(lock);
 				battleMadeAction.cond.wait(lock);
 			battleMadeAction.data = false;
 			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);
+			checkForBattleEnd(stacks);
 		}
 		}
 	}
 	}
 
 
@@ -887,8 +866,7 @@ upgend:
 							BattleResult *br = new BattleResult;
 							BattleResult *br = new BattleResult;
 							br->result = 1;
 							br->result = 1;
 							br->winner = !ba.side; //fleeing side loses
 							br->winner = !ba.side; //fleeing side loses
-							br->casualties[0] = gs->curB->cas[0]; //setting casualities
-							br->casualties[1] = gs->curB->cas[1]; //as above - second side ;]
+							gs->curB->calculateCasualties(br->casualties);
 							battleResult.set(br);
 							battleResult.set(br);
 							break;
 							break;
 						}
 						}
@@ -1204,7 +1182,7 @@ void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army
 	curB->activeStack = -1;
 	curB->activeStack = -1;
 	for(std::map<si32,std::pair<ui32,si32> >::iterator i = army1.slots.begin(); i!=army1.slots.end(); i++)
 	for(std::map<si32,std::pair<ui32,si32> >::iterator i = army1.slots.begin(); i!=army1.slots.end(); i++)
 	{
 	{
-		stacks.push_back(new CStack(&VLC->creh->creatures[i->second.first],i->second.second,hero1->tempOwner, stacks.size(), true));
+		stacks.push_back(new CStack(&VLC->creh->creatures[i->second.first],i->second.second,hero1->tempOwner, stacks.size(), true,i->first));
 		stacks[stacks.size()-1]->ID = stacks.size()-1;
 		stacks[stacks.size()-1]->ID = stacks.size()-1;
 	}
 	}
 	//initialization of positions
 	//initialization of positions
@@ -1258,7 +1236,7 @@ void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army
 		break;
 		break;
 	}
 	}
 	for(std::map<si32,std::pair<ui32,si32> >::iterator i = army2.slots.begin(); i!=army2.slots.end(); i++)
 	for(std::map<si32,std::pair<ui32,si32> >::iterator i = army2.slots.begin(); i!=army2.slots.end(); i++)
-		stacks.push_back(new CStack(&VLC->creh->creatures[i->second.first],i->second.second,hero2 ? hero2->tempOwner : 255, stacks.size(), false));
+		stacks.push_back(new CStack(&VLC->creh->creatures[i->second.first],i->second.second,hero2 ? hero2->tempOwner : 255, stacks.size(), false, i->first));
 	switch(army2.slots.size()) //for defender
 	switch(army2.slots.size()) //for defender
 	{
 	{
 	case 0:
 	case 0:
@@ -1332,3 +1310,25 @@ void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army
 	bs.info = curB;
 	bs.info = curB;
 	sendAndApply(&bs);
 	sendAndApply(&bs);
 }
 }
+
+void CGameHandler::checkForBattleEnd( std::vector<CStack*> &stacks )
+{
+	//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
+		gs->curB->calculateCasualties(br->casualties);
+		battleResult.set(br);
+	}
+}

+ 2 - 0
server/CGameHandler.h

@@ -54,6 +54,8 @@ class CGameHandler
 	void changeSecSkill(int ID, ui16 which, int val, bool abs=false);
 	void changeSecSkill(int ID, ui16 which, int val, bool abs=false);
 	void moveStack(int stack, int dest);
 	void moveStack(int stack, int dest);
 	void startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2); //use hero=NULL for no hero
 	void startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2); //use hero=NULL for no hero
+
+	void checkForBattleEnd( std::vector<CStack*> &stacks );
 	void setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army1, CCreatureSet &army2, CGHeroInstance * hero1, CGHeroInstance * hero2 );
 	void setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army1, CCreatureSet &army2, CGHeroInstance * hero1, CGHeroInstance * hero2 );
 
 
 public:
 public: