mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Now hero movement should be working.
- fixed/added #22, #24, #25, #8, #11, partially #19 - minor improvements
This commit is contained in:
parent
49565e6b45
commit
e02f752211
@ -178,12 +178,13 @@ void CHeroList::select(int which)
|
||||
{
|
||||
selected = which;
|
||||
if (which>=items.size())
|
||||
which=items.size();
|
||||
draw();
|
||||
return;
|
||||
LOCPLINT->adventureInt->centerOn(items[which].first->pos);
|
||||
LOCPLINT->adventureInt->selection.type = HEROI_TYPE;
|
||||
LOCPLINT->adventureInt->selection.selected = items[which].first;
|
||||
LOCPLINT->adventureInt->terrain.currentPath = items[which].second;
|
||||
draw();
|
||||
LOCPLINT->adventureInt->townList.draw();
|
||||
}
|
||||
void CHeroList::clickLeft(tribool down)
|
||||
{
|
||||
@ -308,7 +309,7 @@ void CHeroList::draw()
|
||||
blitAtWR(mana->ourImages[pom].bitmap,posmanx,posmany+i*32); //mana
|
||||
SDL_Surface * temp = LOCPLINT->cb->getHeroInfo(LOCPLINT->playerID,iT,0)->type->portraitSmall;
|
||||
blitAtWR(temp,posporx,pospory+i*32);
|
||||
if (selected == iT)
|
||||
if ((selected == iT) && (LOCPLINT->adventureInt->selection.type == HEROI_TYPE))
|
||||
{
|
||||
blitAtWR(selection,posporx,pospory+i*32);
|
||||
}
|
||||
@ -332,10 +333,16 @@ CTownList::CTownList()
|
||||
|
||||
arrupp.x=747;
|
||||
arrupp.y=196;
|
||||
arrupp.w=arrup->ourImages[0].bitmap->w;
|
||||
arrupp.h=arrup->ourImages[0].bitmap->h;
|
||||
arrdop.x=747;
|
||||
arrdop.y=372;
|
||||
arrdop.w=arrdo->ourImages[0].bitmap->w;
|
||||
arrdop.h=arrdo->ourImages[0].bitmap->h;
|
||||
posporx = 747;
|
||||
pospory = 211;
|
||||
pospory = 212;
|
||||
|
||||
pressed = indeterminate;
|
||||
|
||||
from = 0;
|
||||
|
||||
@ -350,12 +357,77 @@ void CTownList::genList()
|
||||
}
|
||||
void CTownList::select(int which)
|
||||
{
|
||||
selected = which;
|
||||
if (which>=items.size())
|
||||
return;
|
||||
LOCPLINT->adventureInt->centerOn(items[which]->pos);
|
||||
LOCPLINT->adventureInt->selection.type = TOWNI_TYPE;
|
||||
LOCPLINT->adventureInt->selection.selected = items[which];
|
||||
LOCPLINT->adventureInt->terrain.currentPath = NULL;
|
||||
draw();
|
||||
LOCPLINT->adventureInt->heroList.draw();
|
||||
}
|
||||
void CTownList::mouseMoved (SDL_MouseMotionEvent & sEvent)
|
||||
{
|
||||
}
|
||||
void CTownList::clickLeft(tribool down)
|
||||
{
|
||||
if (down)
|
||||
{
|
||||
/***************************ARROWS*****************************************/
|
||||
if(isItIn(&arrupp,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y) && from>0)
|
||||
{
|
||||
blitAtWR(arrup->ourImages[1].bitmap,arrupp.x,arrupp.y);
|
||||
pressed = true;
|
||||
return;
|
||||
}
|
||||
else if(isItIn(&arrdop,LOCPLINT->current->motion.x,LOCPLINT->current->motion.y) && (items.size()-from>5))
|
||||
{
|
||||
blitAtWR(arrdo->ourImages[1].bitmap,arrdop.x,arrdop.y);
|
||||
pressed = false;
|
||||
return;
|
||||
}
|
||||
/***************************HEROES*****************************************/
|
||||
int hx = LOCPLINT->current->motion.x, hy = LOCPLINT->current->motion.y;
|
||||
hx-=pos.x;
|
||||
hy-=pos.y; hy-=arrup->ourImages[0].bitmap->h;
|
||||
float ny = (float)hy/(float)32;
|
||||
if (ny>5 || ny<0)
|
||||
return;
|
||||
select(ny+from);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (indeterminate(pressed))
|
||||
return;
|
||||
if (pressed) //up
|
||||
{
|
||||
blitAtWR(arrup->ourImages[0].bitmap,arrupp.x,arrupp.y);
|
||||
pressed = indeterminate;
|
||||
if (!down)
|
||||
{
|
||||
from--;
|
||||
if (from<0)
|
||||
from=0;
|
||||
draw();
|
||||
}
|
||||
}
|
||||
else if (!pressed) //down
|
||||
{
|
||||
blitAtWR(arrdo->ourImages[0].bitmap,arrdop.x,arrdop.y);
|
||||
pressed = indeterminate;
|
||||
if (!down)
|
||||
{
|
||||
from++;
|
||||
if (from<items.size()-5)
|
||||
from=items.size()-5;
|
||||
draw();
|
||||
}
|
||||
}
|
||||
else
|
||||
throw 0;
|
||||
|
||||
}
|
||||
}
|
||||
void CTownList::clickRight(tribool down)
|
||||
{
|
||||
@ -379,7 +451,7 @@ void CTownList::draw()
|
||||
|
||||
blitAtWR(CGI->townh->getPic(items[i]->type),posporx,pospory+i*32);
|
||||
|
||||
if (selected == iT)
|
||||
if ((selected == iT) && (LOCPLINT->adventureInt->selection.type == TOWNI_TYPE))
|
||||
{
|
||||
blitAtWR(CGI->townh->getPic(-2),posporx,pospory+i*32);
|
||||
}
|
||||
@ -598,8 +670,8 @@ void CTerrainRect::clickLeft(tribool down)
|
||||
{
|
||||
if ( (currentPath->endPos()) == mp)
|
||||
{ //move
|
||||
LOCPLINT->cb->moveHero(0,currentPath->endPos(),0, 1);//todo - move selected hero
|
||||
return;
|
||||
CPath sended(*currentPath); //temporary path - engine will operate on it
|
||||
LOCPLINT->cb->moveHero( ((const CHeroInstance*)LOCPLINT->adventureInt->selection.selected)->type->ID,&sended,1,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -608,7 +680,7 @@ void CTerrainRect::clickLeft(tribool down)
|
||||
}
|
||||
}
|
||||
const CHeroInstance * currentHero = LOCPLINT->adventureInt->heroList.items[LOCPLINT->adventureInt->heroList.selected].first;
|
||||
int3 bufpos = currentHero->pos;
|
||||
int3 bufpos = currentHero->getPosition(false);
|
||||
//bufpos.x-=1;
|
||||
currentPath = LOCPLINT->adventureInt->heroList.items[LOCPLINT->adventureInt->heroList.selected].second = CGI->pathf->getPath(bufpos,mp,currentHero,1);
|
||||
}
|
||||
|
@ -40,36 +40,67 @@ void CCallback::newTurn()
|
||||
}
|
||||
}
|
||||
}
|
||||
bool CCallback::moveHero(int ID, int3 destPoint, int idtype, unsigned char posType)
|
||||
bool CCallback::moveHero(int ID, CPath * path, int idtype, int pathType)
|
||||
{
|
||||
if(ID<0 || ID>CGI->heroh->heroInstances.size())
|
||||
return false;
|
||||
if(destPoint.x<0 || destPoint.x>CGI->ac->map.width)
|
||||
return false;
|
||||
if(destPoint.y<0 || destPoint.y>CGI->ac->map.height)
|
||||
return false;
|
||||
if(destPoint.z<0 || destPoint.z>CGI->mh->ttiles[0][0].size()-1)
|
||||
return false;
|
||||
if(posType==1)
|
||||
CHeroInstance * hero = NULL;
|
||||
|
||||
if (idtype==0)
|
||||
{
|
||||
destPoint.x+=1;
|
||||
if (player==-1)
|
||||
hero=gs->players[player+1].heroes[ID];
|
||||
else
|
||||
hero=gs->players[player].heroes[ID];
|
||||
}
|
||||
CPath * ourPath = CGI->pathf->getPath(CGI->heroh->heroInstances[ID]->pos, destPoint, CGI->heroh->heroInstances[ID]);
|
||||
else if (idtype==1 && player>=0) //szukamy lokalnie
|
||||
{
|
||||
for (int i=0; i<gs->players[player].heroes.size();i++)
|
||||
{
|
||||
if (gs->players[player].heroes[i]->type->ID == ID)
|
||||
hero = gs->players[player].heroes[i];
|
||||
}
|
||||
}
|
||||
else //idtype==1; player<0
|
||||
{
|
||||
|
||||
for(std::map<int, PlayerState>::iterator j=CGI->state->players.begin(); j!=CGI->state->players.end(); ++j)
|
||||
{
|
||||
for (int i=0; i<(*j).second.heroes.size();i++)
|
||||
{
|
||||
if ((*j).second.heroes[i]->type->ID == ID)
|
||||
{
|
||||
hero = (*j).second.heroes[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hero)
|
||||
return false; //can't find hero
|
||||
if(!verifyPath(path,!hero->canWalkOnSea()))//TODO: not check sea, if hero has flying or walking on water
|
||||
return false; //invalid path
|
||||
|
||||
//check path format
|
||||
if (pathType==0)
|
||||
CPathfinder::convertPath(path,pathType);
|
||||
if (pathType>1)
|
||||
throw std::exception("Unknown path format");
|
||||
|
||||
CPath * ourPath = path;
|
||||
if(!ourPath)
|
||||
return false;
|
||||
for(int i=ourPath->nodes.size()-1; i>0; i--)
|
||||
{
|
||||
int3 stpos, endpos;
|
||||
stpos = int3(ourPath->nodes[i].coord.x, ourPath->nodes[i].coord.y, CGI->heroh->heroInstances[ID]->pos.z);
|
||||
endpos = int3(ourPath->nodes[i-1].coord.x, ourPath->nodes[i-1].coord.y, CGI->heroh->heroInstances[ID]->pos.z);
|
||||
stpos = int3(ourPath->nodes[i].coord.x, ourPath->nodes[i].coord.y, hero->pos.z);
|
||||
endpos = int3(ourPath->nodes[i-1].coord.x, ourPath->nodes[i-1].coord.y, hero->pos.z);
|
||||
HeroMoveDetails curd;
|
||||
curd.src = stpos;
|
||||
curd.dst = endpos;
|
||||
curd.heroID = ID;
|
||||
curd.owner = CGI->heroh->heroInstances[ID]->owner;
|
||||
curd.ho = hero->ourObject;
|
||||
curd.owner = hero->owner;
|
||||
if(player!=-1)
|
||||
{
|
||||
gs->players[player].heroes[ID]->pos = endpos;
|
||||
hero->pos = endpos;
|
||||
}
|
||||
//if(CGI->heroh->heroInstances[ID]->movement>=CGI->mh->getCost(stpos, endpos, CGI->heroh->heroInstances[ID]))
|
||||
{ //performing move
|
||||
@ -86,6 +117,7 @@ bool CCallback::moveHero(int ID, int3 destPoint, int idtype, unsigned char posTy
|
||||
}
|
||||
//else
|
||||
//return true; //move ended - no more movement points
|
||||
hero->pos = curd.dst;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -162,6 +194,36 @@ int CCallback::getDate(int mode)
|
||||
return ((gs->day-1)/28)+1;
|
||||
}
|
||||
}
|
||||
bool CCallback::verifyPath(CPath * path, bool blockSea)
|
||||
{
|
||||
for (int i=0;i<path->nodes.size();i++)
|
||||
{
|
||||
if ( CGI->mh->ttiles[path->nodes[i].coord.x][path->nodes[i].coord.y][path->nodes[i].coord.z].blocked
|
||||
&& (! (CGI->mh->ttiles[path->nodes[i].coord.x][path->nodes[i].coord.y][path->nodes[i].coord.z].visitable)))
|
||||
return false; //path is wrong - one of the tiles is blocked
|
||||
|
||||
if (blockSea)
|
||||
{
|
||||
if (i==0)
|
||||
continue;
|
||||
|
||||
if (
|
||||
((CGI->mh->ttiles[path->nodes[i].coord.x][path->nodes[i].coord.y][path->nodes[i].coord.z].terType==EterrainType::water)
|
||||
&&
|
||||
(CGI->mh->ttiles[path->nodes[i-1].coord.x][path->nodes[i-1].coord.y][path->nodes[i-1].coord.z].terType!=EterrainType::water))
|
||||
||
|
||||
((CGI->mh->ttiles[path->nodes[i].coord.x][path->nodes[i].coord.y][path->nodes[i].coord.z].terType!=EterrainType::water)
|
||||
&&
|
||||
(CGI->mh->ttiles[path->nodes[i-1].coord.x][path->nodes[i-1].coord.y][path->nodes[i-1].coord.z].terType==EterrainType::water))
|
||||
|
||||
)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector < std::string > CCallback::getObjDescriptions(int3 pos)
|
||||
{
|
||||
|
@ -3,10 +3,12 @@
|
||||
class CGameState;
|
||||
class CHeroInstance;
|
||||
class CTownInstance;
|
||||
class CPath;
|
||||
class CObjectInstance;
|
||||
struct HeroMoveDetails
|
||||
{
|
||||
int3 src, dst; //source and destination points
|
||||
int heroID; //position in vector
|
||||
CObjectInstance * ho; //object instance of this hero
|
||||
int owner;
|
||||
};
|
||||
class CCallback
|
||||
@ -22,7 +24,8 @@ protected:
|
||||
int player;
|
||||
|
||||
public:
|
||||
bool moveHero(int ID, int3 destPoint, int idtype=0, unsigned char posType=0);//idtype: 0-position in vector; 1-ID of hero
|
||||
bool moveHero(int ID, CPath * path, int idtype, int pathType=0);//idtype: 0 - position in vector of heroes (of that player); 1 - ID of hero
|
||||
//pathType: 0 - nodes are manifestation pos, 1 - nodes are object pos
|
||||
std::vector < std::string > getObjDescriptions(int3 pos); //returns descriptions of objects at pos in order from the lowest to the highest
|
||||
|
||||
int howManyTowns();
|
||||
@ -32,6 +35,7 @@ public:
|
||||
const CHeroInstance * getHeroInfo(int player, int val, bool mode); //mode = 0 -> val = serial; mode = 1 -> val = ID
|
||||
int getResourceAmount(int type);
|
||||
int getDate(int mode=0); //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month
|
||||
bool verifyPath(CPath * path, bool blockSea);
|
||||
|
||||
friend int _tmain(int argc, _TCHAR* argv[]);
|
||||
};
|
||||
|
@ -41,12 +41,17 @@ int internalFunc(void * callback)
|
||||
break;
|
||||
case 'H': //position of hero
|
||||
readed>>heronum;
|
||||
std::cout<<"Position of hero "<<heronum<<": "<<CGI->heroh->heroInstances[heronum]->pos<<std::endl;
|
||||
break;
|
||||
case 'M': //move hero
|
||||
readed>>heronum>>dest;
|
||||
cb->moveHero(heronum, dest);
|
||||
std::cout<<"Position of hero "<<heronum<<": "<<CGI->heroh->heroInstances[heronum]->getPosition(false)<<std::endl;
|
||||
break;
|
||||
case 'M': //move heroa
|
||||
{
|
||||
readed>>heronum>>dest;
|
||||
const CHeroInstance * hero = cb->getHeroInfo(0,heronum,0);
|
||||
CPath * path = CGI->pathf->getPath(hero->getPosition(false),dest,hero);
|
||||
cb->moveHero(heronum, path, 0, 0);
|
||||
delete path;
|
||||
break;
|
||||
}
|
||||
case 'D': //pos description
|
||||
readed>>src;
|
||||
CGI->mh->getObjDescriptions(src);
|
||||
|
@ -208,8 +208,8 @@ inline void delObjRect(const int & x, const int & y, const int & z, const int &
|
||||
void CPlayerInterface::heroMoved(const HeroMoveDetails & details)
|
||||
{
|
||||
//initializing objects and performing first step of move
|
||||
CObjectInstance * ho = CGI->heroh->heroInstances[details.heroID]->ourObject; //object representing this hero
|
||||
int3 hp = CGI->heroh->heroInstances[details.heroID]->pos;
|
||||
CObjectInstance * ho = details.ho; //object representing this hero
|
||||
int3 hp = details.src;
|
||||
if(details.dst.x+1 == details.src.x && details.dst.y+1 == details.src.y) //tl
|
||||
{
|
||||
ho->moveDir = 1;
|
||||
@ -736,8 +736,7 @@ void CPlayerInterface::heroMoved(const HeroMoveDetails & details)
|
||||
delObjRect(hp.x, hp.y-1, hp.z, ho->id);
|
||||
delObjRect(hp.x, hp.y, hp.z, ho->id);
|
||||
}
|
||||
CGI->heroh->heroInstances[details.heroID]->pos = details.dst; //actualizing hero position
|
||||
CGI->heroh->heroInstances[details.heroID]->ourObject->pos = details.dst; //copy of hero's position
|
||||
ho->pos = details.dst; //copy of hero's position
|
||||
ho->moveDir = 0; //move ended
|
||||
//move finished
|
||||
}
|
||||
|
@ -15,11 +15,30 @@ int3 CPath::endPos()
|
||||
|
||||
CPath * CPathfinder::getPath(int3 src, int3 dest, const CHeroInstance * hero, unsigned char type) //TODO: test it (seems to be finished, but relies on unwritten functions :()
|
||||
{
|
||||
if(src.z!=dest.z) //first check
|
||||
return NULL;
|
||||
if(type==1) //calibrating
|
||||
//check input
|
||||
if ((src.x < 0)||(src.y < 0)||(src.z < 0)||(dest.x < 0)||(dest.y < 0)||(dest.z < 0))
|
||||
{
|
||||
src.x-=1;
|
||||
return NULL;
|
||||
}
|
||||
if ((src.x >= CGI->mh->sizes.x)||(src.y >= CGI->mh->sizes.y)||(src.z >= CGI->mh->sizes.z)
|
||||
||(dest.x >= CGI->mh->sizes.x)||(dest.y >= CGI->mh->sizes.y)||(dest.z >= CGI->mh->sizes.z))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int3 hpos = hero->getPosition(false);
|
||||
|
||||
tribool blockLandSea; //true - blocks sea, false - blocks land, indeterminate - allows all
|
||||
if (!hero->canWalkOnSea())
|
||||
{
|
||||
if (CGI->mh->ttiles[hpos.x][hpos.y][hpos.z].terType==EterrainType::water)
|
||||
blockLandSea=false;
|
||||
else
|
||||
blockLandSea=true;
|
||||
}
|
||||
else
|
||||
{
|
||||
blockLandSea = indeterminate;
|
||||
}
|
||||
|
||||
//graph initialization
|
||||
@ -39,6 +58,10 @@ CPath * CPathfinder::getPath(int3 src, int3 dest, const CHeroInstance * hero, un
|
||||
graph[i][j]->coord.x = i;
|
||||
graph[i][j]->coord.y = j;
|
||||
graph[i][j]->coord.z = dest.z;
|
||||
if ((blockLandSea) && (CGI->mh->ttiles[i][j][src.z].terType==EterrainType::water))
|
||||
graph[i][j]->accesible = false;
|
||||
else if ((!blockLandSea) && (CGI->mh->ttiles[i][j][src.z].terType!=EterrainType::water))
|
||||
graph[i][j]->accesible = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,3 +188,14 @@ CPath * CPathfinder::getPath(int3 src, int3 dest, const CHeroInstance * hero, un
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CPathfinder::convertPath(CPath * path, unsigned int mode) //mode=0 -> from 'manifest' to 'object'
|
||||
{
|
||||
if (mode==0)
|
||||
{
|
||||
for (int i=0;i<path->nodes.size();i++)
|
||||
{
|
||||
path->nodes[i].coord = CHeroInstance::convertPosition(path->nodes[i].coord,true);
|
||||
}
|
||||
}
|
||||
}
|
@ -31,6 +31,8 @@ private:
|
||||
public:
|
||||
CPath * getPath(int3 src, int3 dest, const CHeroInstance * hero, unsigned char type=0); //calculates path between src and dest; returns pointer to CPath or NULL if path does not exists; type - type of calculation: 0 - positions are normal positions of hero; 1 - given places are tiles blocked by hero
|
||||
CPath * getPath(const int3 & src, const int3 & dest, const CHeroInstance * hero, int (*getDist)(int3 & a, int3 & b), unsigned char type=0); //calculates path between src and dest; returns pointer to CPath or NULL if path does not exists; uses getDist to calculate distance; type - type of calculation: 0 - positions are normal positions of hero; 1 - given places are tiles blocked by hero
|
||||
|
||||
static void convertPath(CPath * path, unsigned int mode); //mode=0 -> from 'manifest' to 'object'
|
||||
};
|
||||
|
||||
#endif //CPATHFINDER_H
|
@ -439,6 +439,37 @@ unsigned int CHeroInstance::getLowestCreatureSpeed()
|
||||
return sl;
|
||||
}
|
||||
|
||||
int3 CHeroInstance::convertPosition(int3 src, bool toh3m) //toh3m=true: manifest->h3m; toh3m=false: h3m->manifest
|
||||
{
|
||||
if (toh3m)
|
||||
{
|
||||
src.x+=1;
|
||||
return src;
|
||||
}
|
||||
else
|
||||
{
|
||||
src.x-=1;
|
||||
return src;
|
||||
}
|
||||
}
|
||||
int3 CHeroInstance::getPosition(bool h3m) const
|
||||
{
|
||||
if (h3m)
|
||||
return pos;
|
||||
else return convertPosition(pos,false);
|
||||
}
|
||||
void CHeroInstance::setPosition(int3 Pos, bool h3m)
|
||||
{
|
||||
if (h3m)
|
||||
pos = Pos;
|
||||
else
|
||||
pos = convertPosition(Pos,true);
|
||||
}
|
||||
bool CHeroInstance::canWalkOnSea() const
|
||||
{
|
||||
//TODO: write it - it should check if hero is flying, or something similiar
|
||||
return false;
|
||||
}
|
||||
void CHeroHandler::initTerrainCosts()
|
||||
{
|
||||
std::ifstream inp;
|
||||
@ -458,4 +489,4 @@ void CHeroHandler::initTerrainCosts()
|
||||
}
|
||||
}
|
||||
inp.close();
|
||||
}
|
||||
}
|
@ -57,7 +57,7 @@ public:
|
||||
std::string name; //may be custom
|
||||
std::string biography; //may be custom
|
||||
int portrait; //may be custom
|
||||
int3 pos; //position on adventure map
|
||||
int3 pos; //position of object (hero pic is on the left)
|
||||
CCreatureSet army; //army
|
||||
int mana; // remaining spell points
|
||||
std::vector<int> primSkills; //0-attack, 1-defence, 2-spell power, 3-knowledge
|
||||
@ -69,6 +69,11 @@ public:
|
||||
unsigned int getLowestCreatureSpeed();
|
||||
unsigned int getAdditiveMoveBonus();
|
||||
unsigned float getMultiplicativeMoveBonus();
|
||||
static int3 convertPosition(int3 src, bool toh3m); //toh3m=true: manifest->h3m; toh3m=false: h3m->manifest
|
||||
int3 getPosition(bool h3m) const; //h3m=true - returns position of hero object; h3m=false - returns position of hero 'manifestation'
|
||||
void setPosition(int3 Pos, bool h3m); //as above, but sets position
|
||||
|
||||
bool canWalkOnSea() const;
|
||||
|
||||
//TODO: artifacts, known spells, commander, blessings, curses, morale/luck special modifiers
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user