1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00

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

This commit is contained in:
Michał W. Urbańczyk 2008-08-06 17:49:47 +00:00
parent 1462e50995
commit 4673a6d0e1
6 changed files with 70 additions and 85 deletions

View File

@ -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();

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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);
}
}
}