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 years ago
parent
commit
4673a6d0e1
6 changed files with 70 additions and 85 deletions
  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);
 			}
 		}
 	}