Browse Source

Improved pathfinding in battles, removed problems with displaying movement, adventure map interface won't be called during battles.

Michał W. Urbańczyk 17 năm trước cách đây
mục cha
commit
4673a6d0e1
6 tập tin đã thay đổi với 70 bổ sung85 xóa
  1. 18 33
      CBattleInterface.cpp
  2. 0 1
      CBattleInterface.h
  3. 40 43
      CGameState.cpp
  4. 5 2
      CGameState.h
  5. 1 1
      CPlayerInterface.cpp
  6. 6 5
      server/CGameHandler.cpp

+ 18 - 33
CBattleInterface.cpp

@@ -7,6 +7,7 @@
 #include "hch/CObjectHandler.h"
 #include "hch/CHeroHandler.h"
 #include "hch/CDefHandler.h"
+#include "CCursorHandler.h"
 #include "CCallback.h"
 #include "CGameState.h"
 #include "hch/CGeneralTextHandler.h"
@@ -502,12 +503,12 @@ void CBattleInterface::stackMoved(int number, int destHex, bool startMoving, boo
 		}
 	}
 
-	int mutPos = CBattleHex::mutualPosition(curStackPos, destHex);
+	int mutPos = BattleInfo::mutualPosition(curStackPos, destHex);
 
 	if(LOCPLINT->cb->battleGetCreature(number).isDoubleWide() &&
 		((creDir[number] && mutPos == 5) || (creDir[number] && mutPos == 0) || (creDir[number] && mutPos == 4))) //for special cases
 	{
-		switch(CBattleHex::mutualPosition(curStackPos, destHex)) //reverse unit if necessary
+		switch(BattleInfo::mutualPosition(curStackPos, destHex)) //reverse unit if necessary
 		{
 		case 0:
 			if(creDir[number] == true)
@@ -538,7 +539,7 @@ void CBattleInterface::stackMoved(int number, int destHex, bool startMoving, boo
 		creAnims[number]->setType(0);
 		for(int i=0; i<steps; ++i)
 		{
-			switch(CBattleHex::mutualPosition(curStackPos, destHex))
+			switch(BattleInfo::mutualPosition(curStackPos, destHex))
 			{
 			case 0:
 				creAnims[number]->pos.x -= hexWbase/(2*steps);
@@ -575,7 +576,7 @@ void CBattleInterface::stackMoved(int number, int destHex, bool startMoving, boo
 	}
 	else //normal move instructions
 	{
-		switch(CBattleHex::mutualPosition(curStackPos, destHex)) //reverse unit if necessary
+		switch(BattleInfo::mutualPosition(curStackPos, destHex)) //reverse unit if necessary
 		{
 		case 0:
 			if(creDir[number] == true)
@@ -606,7 +607,7 @@ void CBattleInterface::stackMoved(int number, int destHex, bool startMoving, boo
 		creAnims[number]->setType(0);
 		for(int i=0; i<steps; ++i)
 		{
-			switch(CBattleHex::mutualPosition(curStackPos, destHex))
+			switch(BattleInfo::mutualPosition(curStackPos, destHex))
 			{
 			case 0:
 				creAnims[number]->pos.x -= hexWbase/(2*steps);
@@ -645,9 +646,9 @@ void CBattleInterface::stackMoved(int number, int destHex, bool startMoving, boo
 			CSDL_Ext::update();
 			SDL_framerateDelay(LOCPLINT->mainFPSmng);
 		}
+		creAnims[number]->setType(2); //resetting to default
 	}
 
-	creAnims[number]->setType(2); //resetting to default
 	CStack curs = *LOCPLINT->cb->battleGetStackByID(number);
 	if(endMoving) //resetting to default
 	{
@@ -712,7 +713,7 @@ void CBattleInterface::stackAttacking(int ID, int dest)
 	CStack aStack = *LOCPLINT->cb->battleGetStackByID(ID); //attacking stack
 	if(aStack.creature->isDoubleWide())
 	{
-		switch(CBattleHex::mutualPosition(aStack.position, dest)) //attack direction
+		switch(BattleInfo::mutualPosition(aStack.position, dest)) //attack direction
 		{
 			case 0:
 				//reverseCreature(ID, aStack.position, true);
@@ -733,7 +734,7 @@ void CBattleInterface::stackAttacking(int ID, int dest)
 	}
 	else //else for if(aStack.creature->isDoubleWide())
 	{
-		switch(CBattleHex::mutualPosition(aStack.position, dest)) //attack direction
+		switch(BattleInfo::mutualPosition(aStack.position, dest)) //attack direction
 		{
 			case 0:
 				reverseCreature(ID, aStack.position, true);
@@ -760,7 +761,7 @@ void CBattleInterface::stackAttacking(int ID, int dest)
 	attackingInfo->reversing = false;
 	attackingInfo->shooting = false;
 
-	switch(CBattleHex::mutualPosition(aStack.position, dest)) //attack direction
+	switch(BattleInfo::mutualPosition(aStack.position, dest)) //attack direction
 	{
 		case 0:
 			attackingInfo->maxframe = creAnims[ID]->framesInGroup(10);
@@ -796,6 +797,7 @@ void CBattleInterface::giveCommand(ui8 action, ui16 tile, ui32 stack)
 	ba->stackNumber = stack;
 	givenCommand->setn(ba);
 	myTurn = false;
+	activeStack = -1;
 }
 
 void CBattleInterface::hexLclicked(int whichOne)
@@ -807,9 +809,10 @@ void CBattleInterface::hexLclicked(int whichOne)
 
 		int atCre = LOCPLINT->cb->battleGetStack(whichOne); //creature at destination tile; -1 if there is no one
 		//LOCPLINT->cb->battleGetCreature();
-		if(atCre==-1) //normal move action
+		if(atCre==-1) //no creature at that tile
 		{
-			giveCommand(2,whichOne,activeStack);
+			if(std::find(shadedHexes.begin(),shadedHexes.end(),whichOne)!=shadedHexes.end())// and it's in our range
+				giveCommand(2,whichOne,activeStack);
 		}
 		else if(LOCPLINT->cb->battleGetStackByID(atCre)->owner != attackingHeroInstance->tempOwner
 			&& LOCPLINT->cb->battleCanShoot(activeStack, whichOne)) //shooting
@@ -919,7 +922,7 @@ void CBattleInterface::attackingShowHelper()
 			{
 				if(aStack.creature->isDoubleWide())
 				{
-					switch(CBattleHex::mutualPosition(aStack.position, attackingInfo->dest)) //attack direction
+					switch(BattleInfo::mutualPosition(aStack.position, attackingInfo->dest)) //attack direction
 					{
 						case 0:
 							creAnims[attackingInfo->ID]->setType(10);
@@ -943,7 +946,7 @@ void CBattleInterface::attackingShowHelper()
 				}
 				else //else for if(aStack.creature->isDoubleWide())
 				{
-					switch(CBattleHex::mutualPosition(aStack.position, attackingInfo->dest)) //attack direction
+					switch(BattleInfo::mutualPosition(aStack.position, attackingInfo->dest)) //attack direction
 					{
 						case 0:
 							creAnims[attackingInfo->ID]->setType(10);
@@ -973,7 +976,7 @@ void CBattleInterface::attackingShowHelper()
 			CStack aStack = *LOCPLINT->cb->battleGetStackByID(attackingInfo->ID); //attacking stack
 			if(aStack.creature->isDoubleWide())
 			{
-				switch(CBattleHex::mutualPosition(aStack.position, attackingInfo->dest)) //attack direction
+				switch(BattleInfo::mutualPosition(aStack.position, attackingInfo->dest)) //attack direction
 				{
 					case 0:
 						//reverseCreature(ID, aStack.position, true);
@@ -994,7 +997,7 @@ void CBattleInterface::attackingShowHelper()
 			}
 			else //else for if(aStack.creature->isDoubleWide())
 			{
-				switch(CBattleHex::mutualPosition(aStack.position, attackingInfo->dest)) //attack direction
+				switch(BattleInfo::mutualPosition(aStack.position, attackingInfo->dest)) //attack direction
 				{
 					case 0:
 						reverseCreature(attackingInfo->ID, aStack.position, true);
@@ -1186,24 +1189,6 @@ std::pair<int, int> CBattleHex::getXYUnitAnim(int hexNum, bool attacker, CCreatu
 	//returning
 	return ret;
 }
-
-signed char CBattleHex::mutualPosition(int hex1, int hex2)
-{
-	if(hex2 == hex1 - ( (hex1/17)%2 ? 18 : 17 )) //top left
-		return 0;
-	if(hex2 == hex1 - ( (hex1/17)%2 ? 17 : 16 )) //top right
-		return 1;
-	if(hex2 == hex1 - 1 && hex1%17 != 0) //left
-		return 5;
-	if(hex2 == hex1 + 1 && hex1%17 != 16) //right
-		return 2;
-	if(hex2 == hex1 + ( (hex1/17)%2 ? 16 : 17 )) //bottom left
-		return 4;
-	if(hex2 == hex1 + ( (hex1/17)%2 ? 17 : 18 )) //bottom right
-		return 3;
-	return -1;
-}
-
 void CBattleHex::activate()
 {
 	Hoverable::activate();

+ 0 - 1
CBattleInterface.h

@@ -37,7 +37,6 @@ public:
 	bool hovered, strictHovered;
 	CBattleInterface * myInterface; //interface that owns me
 	static std::pair<int, int> getXYUnitAnim(int hexNum, bool attacker, CCreature * creature); //returns (x, y) of left top corner of animation
-	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)
 	//for user interactions
 	void hover (bool on);
 	void activate();

+ 40 - 43
CGameState.cpp

@@ -112,12 +112,12 @@ CStack * BattleInfo::getStackT(int tileID)
 	}
 	return NULL;
 }
-void BattleInfo::getAccessibilityMap(bool *accessibility)
+void BattleInfo::getAccessibilityMap(bool *accessibility, int stackToOmmit)
 {
 	memset(accessibility,1,187); //initialize array with trues
 	for(int g=0; g<stacks.size(); ++g)
 	{
-		if(!stacks[g]->alive) //we don't want to lock enemy's positions and this units' position
+		if(!stacks[g]->alive || stacks[g]->ID==stackToOmmit) //we don't want to lock position of this stack
 			continue;
 
 		accessibility[stacks[g]->position] = false;
@@ -131,10 +131,10 @@ void BattleInfo::getAccessibilityMap(bool *accessibility)
 	}
 	//TODO: obstacles
 }
-void BattleInfo::getAccessibilityMapForTwoHex(bool *accessibility, bool atackerSide) //send pointer to at least 187 allocated bytes
+void BattleInfo::getAccessibilityMapForTwoHex(bool *accessibility, bool atackerSide, int stackToOmmit) //send pointer to at least 187 allocated bytes
 {	
 	bool mac[187];
-	getAccessibilityMap(mac);
+	getAccessibilityMap(mac,stackToOmmit);
 	memcpy(accessibility,mac,187);
 
 	for(int b=0; b<187; ++b)
@@ -165,45 +165,13 @@ void BattleInfo::makeBFS(int start, bool*accessibility, int *predecessor, int *d
 	while(!hexq.empty()) //bfs loop
 	{
 		int curHex = hexq.front();
+		std::vector<int> neighbours = neighbouringTiles(curHex);
 		hexq.pop();
-		curNext = curHex - ( (curHex/17)%2 ? 18 : 17 );
-		if((curNext > 0) && (accessibility[curNext]) && (dists[curHex] + 1 < dists[curNext]) && (curNext)%17!=0 && (curNext)%17!=16) //top left
-		{
-			hexq.push(curNext);
-			dists[curNext] = dists[curHex] + 1;
-			predecessor[curNext] = curHex;
-		}
-		curNext = curHex - ( (curHex/17)%2 ? 17 : 16 );
-		if((curNext > 0) && (accessibility[curNext])  && (dists[curHex] + 1 < dists[curNext]) && (curNext)%17!=0 && (curNext)%17!=16) //top right
-		{
-			hexq.push(curNext);
-			dists[curNext] = dists[curHex] + 1;
-			predecessor[curNext] = curHex;
-		}
-		curNext = curHex - 1;
-		if((curNext > 0) && (accessibility[curNext])  && (dists[curHex] + 1 < dists[curNext]) && (curNext)%17!=0 && (curNext)%17!=16) //left
-		{
-			hexq.push(curNext);
-			dists[curNext] = dists[curHex] + 1;
-			predecessor[curNext] = curHex;
-		}
-		curNext = curHex + 1;
-		if((curNext < 187) && (accessibility[curNext])  && (dists[curHex] + 1 < dists[curNext]) && (curNext)%17!=0 && (curNext)%17!=16) //right
-		{
-			hexq.push(curNext);
-			dists[curNext] = dists[curHex] + 1;
-			predecessor[curNext] = curHex;
-		}
-		curNext = curHex + ( (curHex/17)%2 ? 16 : 17 );
-		if((curNext < 187) && (accessibility[curNext])  && (dists[curHex] + 1 < dists[curNext]) && (curNext)%17!=0 && (curNext)%17!=16) //bottom left
-		{
-			hexq.push(curNext);
-			dists[curNext] = dists[curHex] + 1;
-			predecessor[curNext] = curHex;
-		}
-		curNext = curHex + ( (curHex/17)%2 ? 17 : 18 );
-		if((curNext < 187) && (accessibility[curNext])  && (dists[curHex] + 1 < dists[curNext]) && (curNext)%17!=0 && (curNext)%17!=16) //bottom right
+		for(int nr=0; nr<neighbours.size(); nr++)
 		{
+			curNext = neighbours[nr];
+			if(!accessibility[curNext] || (dists[curHex]+1)>=dists[curNext])
+				continue;
 			hexq.push(curNext);
 			dists[curNext] = dists[curHex] + 1;
 			predecessor[curNext] = curHex;
@@ -217,9 +185,9 @@ std::vector<int> BattleInfo::getAccessibility(int stackID)
 	bool ac[187];
 	CStack *s = getStack(stackID);
 	if(s->creature->isDoubleWide())
-		getAccessibilityMapForTwoHex(ac,s->attackerOwned);
+		getAccessibilityMapForTwoHex(ac,s->attackerOwned,stackID);
 	else
-		getAccessibilityMap(ac);
+		getAccessibilityMap(ac,stackID);
 
 	int pr[187], dist[187];
 	makeBFS(s->position,ac,pr,dist);
@@ -230,6 +198,35 @@ std::vector<int> BattleInfo::getAccessibility(int stackID)
 
 	return ret;
 }
+signed char BattleInfo::mutualPosition(int hex1, int hex2)
+{
+	if(hex2 == hex1 - ( (hex1/17)%2 ? 18 : 17 )) //top left
+		return 0;
+	if(hex2 == hex1 - ( (hex1/17)%2 ? 17 : 16 )) //top right
+		return 1;
+	if(hex2 == hex1 - 1 && hex1%17 != 0) //left
+		return 5;
+	if(hex2 == hex1 + 1 && hex1%17 != 16) //right
+		return 2;
+	if(hex2 == hex1 + ( (hex1/17)%2 ? 16 : 17 )) //bottom left
+		return 4;
+	if(hex2 == hex1 + ( (hex1/17)%2 ? 17 : 18 )) //bottom right
+		return 3;
+	return -1;
+}
+std::vector<int> BattleInfo::neighbouringTiles(int hex)
+{
+#define CHECK_AND_PUSH(tile) {int hlp = (tile); if(hlp>=0 && hlp<187 && (hlp%17!=16) && hlp%17) ret.push_back(hlp);}
+	std::vector<int> ret;
+	CHECK_AND_PUSH(hex - ( (hex/17)%2 ? 18 : 17 ));
+	CHECK_AND_PUSH(hex - ( (hex/17)%2 ? 17 : 16 ));
+	CHECK_AND_PUSH(hex - 1);
+	CHECK_AND_PUSH(hex + 1);
+	CHECK_AND_PUSH(hex + ( (hex/17)%2 ? 16 : 17 ));
+	CHECK_AND_PUSH(hex + ( (hex/17)%2 ? 17 : 18 ));
+#undef CHECK_AND_PUSH
+	return ret;
+}
 std::vector<int> BattleInfo::getPath(int start, int dest, bool*accessibility)
 {							
 	int predecessor[187]; //for getting the Path

+ 5 - 2
CGameState.h

@@ -65,11 +65,14 @@ struct DLL_EXPORT BattleInfo
 	}
 	CStack * getStack(int stackID);
 	CStack * getStackT(int tileID);
-	void getAccessibilityMap(bool *accessibility); //send pointer to at least 187 allocated bytes
-	void getAccessibilityMapForTwoHex(bool *accessibility, bool atackerSide); //send pointer to at least 187 allocated bytes
+	void getAccessibilityMap(bool *accessibility, int stackToOmmit=-1); //send pointer to at least 187 allocated bytes
+	void getAccessibilityMapForTwoHex(bool *accessibility, bool atackerSide, int stackToOmmit=-1); //send pointer to at least 187 allocated bytes
 	void makeBFS(int start, bool*accessibility, int *predecessor, int *dists); //*accessibility must be prepared bool[187] array; last two pointers must point to the at least 187-elements int arrays - there is written result
 	std::vector<int> getPath(int start, int dest, bool*accessibility);
 	std::vector<int> getAccessibility(int stackID); //returns vector of accessible tiles (taking into account the creature range)
+
+	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);
 };
 
 class DLL_EXPORT CStack

+ 1 - 1
CPlayerInterface.cpp

@@ -1016,7 +1016,7 @@ void CPlayerInterface::yourTurn()
 			events.pop();
 		}
 		eventsM.unlock();
-		if (!castleInt) //stuff for advMapInt
+		if (curint == adventureInt) //stuff for advMapInt
 		{
 			++LOCPLINT->adventureInt->animValHitCount; //for animations
 			if(LOCPLINT->adventureInt->animValHitCount == 8)

+ 6 - 5
server/CGameHandler.cpp

@@ -592,12 +592,12 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
 							bool accessibility[187];
 							if(curStack->creature->isDoubleWide())
 							{
-								gs->curB->getAccessibilityMapForTwoHex(accessibility,curStack->attackerOwned);
-								accessibility[curStack->attackerOwned ? curStack->position+1 : curStack->position-1]=true;//OUR second tile is for US accessible
+								gs->curB->getAccessibilityMapForTwoHex(accessibility,curStack->attackerOwned,curStack->ID);
+								//accessibility[curStack->attackerOwned ? curStack->position+1 : curStack->position-1]=true;//OUR second tile is for US accessible
 							}
 							else 
-								gs->curB->getAccessibilityMap(accessibility);
-							accessibility[curStack->position] = true; //OUR tile is for US accessible
+								gs->curB->getAccessibilityMap(accessibility,curStack->ID);
+							//accessibility[curStack->position] = true; //OUR tile is for US accessible
 
 							//if(!stackAtEnd && !accessibility[dest])
 							//	return false;
@@ -900,7 +900,8 @@ void CGameHandler::run()
 				p= boost::posix_time::seconds(1);
 				boost::xtime time={0,0};
 				time.sec = static_cast<boost::xtime::xtime_sec_t>(p.total_seconds());
-				cTurn.timed_wait(lock,time);
+				cTurn.wait(lock);
+				//cTurn.timed_wait(lock,time);
 			}
 		}
 	}