1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-04-23 12:08:45 +02:00

* a bit of pathfinder interface redesign

* a few fixes for sieges
* better wall parts' positions by Ivan
This commit is contained in:
mateuszb 2009-08-28 09:03:58 +00:00
parent 90c31d5cd5
commit fceeb05e16
6 changed files with 279 additions and 104 deletions

View File

@ -606,7 +606,7 @@ const CGTownInstance *CCallback::battleGetDefendedTown()
if(!gs->curB || gs->curB->tid == -1) if(!gs->curB || gs->curB->tid == -1)
return NULL; return NULL;
return gs->map->towns[gs->curB->tid]; return static_cast<const CGTownInstance *>(gs->map->objects[gs->curB->tid]);
} }
ui8 CCallback::battleGetWallState(int partOfWall) ui8 CCallback::battleGetWallState(int partOfWall)

View File

@ -3234,7 +3234,17 @@ std::string CBattleInterface::SiegeHelper::getSiegeName(ui16 what, ui16 additInf
case 0: //background case 0: //background
return "SG" + townTypeInfixes[town->town->typeID] + "BACK.BMP"; return "SG" + townTypeInfixes[town->town->typeID] + "BACK.BMP";
case 1: //background wall case 1: //background wall
{
switch(town->town->typeID)
{
case 5: case 4: case 1: case 6:
return "SG" + townTypeInfixes[town->town->typeID] + "TPW1.BMP"; return "SG" + townTypeInfixes[town->town->typeID] + "TPW1.BMP";
case 0: case 2: case 3: case 7: case 8:
return "SG" + townTypeInfixes[town->town->typeID] + "TPWL.BMP";
default:
return "";
}
}
case 2: //keep case 2: //keep
return "SG" + townTypeInfixes[town->town->typeID] + "MAN" + addit + ".BMP"; return "SG" + townTypeInfixes[town->town->typeID] + "MAN" + addit + ".BMP";
case 3: //bottom tower case 3: //bottom tower

View File

@ -1,100 +1,100 @@
//this file is a description of positions of wall parts' positions, following lines contain positions of: bottom tower, bottom wall, wall below gate, wall over gate, upper wall, upper tower, gate, gate arch, bottom static wall and upper static wall (x, y) //this file is a description of positions of wall parts' positions, following lines contain positions of: bottom tower, bottom wall, wall below gate, wall over gate, upper wall, upper tower, gate, gate arch, bottom static wall and upper static wall (x, y)
//castle //Castle
602 494 601 500
557 469 528 350
474 300 468 291
491 188 469 127
544 57 523 32
567 16 568 35
391 260 399 274
471 164 476 238
518 305 511 347
500 54 488 79
//rampart //Rampart
602 494 593 511
557 469 548 451
474 300 468 309
491 188 468 186
544 57 529 57
567 16 565 31
391 260 403 271
471 164 459 220
518 305 509 364
500 54 491 103
//tower //Tower
602 494 591 516
557 469 547 452
474 300 474 298
491 188 487 190
544 57 546 66
567 16 579 36
391 260 400 253
471 164 470 187
518 305 516 365
500 54 513 79
//inferno //Inferno
602 494 594 514
557 469 560 451
474 300 484 316
491 188 479 151
544 57 531 71
567 16 568 27
391 260 408 254
471 164 476 221
518 305 521 376
500 54 501 92
//necropolis //Necropolis
602 494 591 512
557 469 535 445
474 300 477 323
491 188 486 164
544 57 542 66
567 16 560 26
391 260 401 262
471 164 473 240
518 305 508 372
500 54 503 97
//dungeon //Dungeon
602 494 599 495
557 469 558 448
474 300 470 296
491 188 476 180
544 57 522 56
567 16 564 15
391 260 395 260
471 164 470 164
518 305 521 305
500 54 493 53
//stronghold //Stronghold
602 494 585 508
557 469 552 440
474 300 482 304
491 188 475 189
544 57 533 69
567 16 567 30
391 260 407 266
471 164 477 235
518 305 510 380
500 54 498 107
//fortress //Fortress
602 494 599 505
557 469 545 441
474 300 486 306
491 188 497 184
544 57 525 80
567 16 547 27
391 260 392 253
471 164 482 236
518 305 521 382
500 54 507 130
//conflux //Conflux
602 494 607 505
557 469 508 346
474 300 467 299
491 188 470 147
544 57 520 41
567 16 575 28
391 260 408 254
471 164 485 232
518 305 508 346
500 54 489 97

View File

@ -457,7 +457,7 @@ unsigned int CGHeroInstance::getTileCost(const TerrainTile &dest, const TerrainT
} }
else else
{ {
ret = std::max(type->heroClass->terrCosts[dest.tertype],type->heroClass->terrCosts[from.tertype]); //take cost of worse of two tiles ret = type->heroClass->terrCosts[from.tertype];
ret = std::max(ret - 25*unsigned(getSecSkillLevel(0)), 100u); //reduce 25% of terrain penalty for each pathfinding level ret = std::max(ret - 25*unsigned(getSecSkillLevel(0)), 100u); //reduce 25% of terrain penalty for each pathfinding level
} }
return ret; return ret;

View File

@ -1593,7 +1593,7 @@ int CGameState::getMovementCost(const CGHeroInstance *h, int3 src, int3 dest, in
if(src.x != dest.x && src.y != dest.y) //it's diagonal move if(src.x != dest.x && src.y != dest.y) //it's diagonal move
{ {
int old = ret; int old = ret;
ret *= 1.414; ret *= 1.414213;
//diagonal move costs too much but normal move is possible - allow diagonal move for remaining move points //diagonal move costs too much but normal move is possible - allow diagonal move for remaining move points
if(ret > remainingMovePoints && remainingMovePoints > old) if(ret > remainingMovePoints && remainingMovePoints > old)
{ {
@ -1831,6 +1831,147 @@ bool CGameState::getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath
return true; return true;
} }
//void CGameState::calculatePaths(const CGHeroInstance *hero, CPathsInfo &out, const int3 &src)
//{
// if(!map->isInTheMap(src)/* || !map->isInTheMap(dest)*/) //check input
// //todo: distater
// return;
//
// int3 hpos = hero->getPosition(false);
// tribool blockLandSea; //true - blocks sea, false - blocks land, indeterminate - allows all
//
// if (!hero->canWalkOnSea())
// blockLandSea = (map->getTile(hpos).tertype != TerrainTile::water); //block land if hero is on water and vice versa
// else
// blockLandSea = boost::logic::indeterminate;
//
// const std::vector<std::vector<std::vector<ui8> > > &FoW = getPlayer(hero->tempOwner)->fogOfWarMap;
//
// //graph initialization
// CGPathNode ***graph = out.nodes;
// for(size_t i=0; i < out.sizes.x; ++i)
// {
// for(size_t j=0; j < out.sizes.y; ++j)
// {
// for(size_t k=0; k < out.sizes.z; ++k)
// {
// const TerrainTile *tinfo = &map->terrain[i][j][k];
// CGPathNode &node = graph[i][j][k];
//
// node.accessible = (tinfo->blocked ? CGPathNode::BLOCKED : CGPathNode::ACCESSIBLE);
// node.visited = false;
// node.turns = 0xff;
// node.moveRemains = 0;
// node.coord.x = i;
// node.coord.y = j;
// node.coord.z = k;
// node.land = tinfo->tertype == TerrainTile::water;
//
// if ((tinfo->tertype == TerrainTile::rock) //it's rock
// || ((blockLandSea) && () //it's sea and we cannot walk on sea
// || ((!blockLandSea) && (tinfo->tertype != TerrainTile::water)) //it's land and we cannot walk on land
// || !FoW[i][j][k] //tile is covered by the FoW
// )
// {
// node.accessible = CGPathNode::BLOCKED;
// }
// else if(tinfo->visitable)
// {
// for(size_t ii = 0; ii < tinfo->visitableObjects.size(); ii++)
// {
// if(tinfo->visitableObjects[ii]->blockVisit)
// {
// node.accessible = CGPathNode::BLOCKVIS;
// break;
// }
// else
// node.accessible = CGPathNode::VISITABLE;
// }
// }
//
// if(blockLandSea && tinfo->tertype == TerrainTile::water) //hero can walk only on land and tile lays on the water
// {
// size_t i = 0;
// for(; i < tinfo->visitableObjects.size(); i++)
// if(tinfo->visitableObjects[i]->ID == 8 || tinfo->visitableObjects[i]->ID == HEROI_TYPE) //it's a Boat
// break;
//
// if(i < tinfo->visitableObjects.size())
// node.accessible = CGPathNode::BLOCKVIS; //dest is accessible only if there is boat/hero
// }
// else if(!blockLandSea && tinfo->tertype != TerrainTile::water) //hero is moving by water
// {
// if((tinfo->siodmyTajemniczyBajt & 64) && !tinfo->blocked)
// node.accessible = CGPathNode::ACCESSIBLE; //tile is accessible if it's coastal and not blocked
// }
// }
// }
// }
// //graph initialized
//
//
// //initial tile - set cost on 0 and add to the queue
// graph[src.x][src.y][src.z].turns = 0;
// graph[src.x][src.y][src.z].moveRemains = hero->movement;
// std::queue<CGPathNode*> mq;
// mq.push(&graph[src.x][src.y][src.z]);
//
// ui32 curDist = 0xffffffff; //total cost of path - init with max possible val
//
// std::vector<int3> neighbours;
// neighbours.reserve(8);
//
// while(!mq.empty())
// {
// CGPathNode *cp = graph[mq.front()->coord.x][mq.front()->coord.y];
// mq.pop();
//
// //add accessible neighbouring nodes to the queue
// getNeighbours(cp->coord, neighbours, boost::logic::indeterminate);
// for(unsigned int i=0; i < neighbours.size(); i++)
// {
// const int3 &n = neighbours[i]; //current neighbour
// CGPathNode & dp = graph[n.x][n.y][n.z];
// if(!cp->moveRemains)
// {
// cp->turns++;
// cp->moveRemains = hero->maxMovePoints(
// }
//
//
// if(dp.accessible != CGPathNode::BLOCKVIS)
// {
// int cost = getMovementCost(hero,cp->coord,dp.coord,hero->movement - cp->dist);
// if((dp.turns==0xff || (dp.dist > cp->dist + cost)) && dp.accesible && checkForVisitableDir(cp->coord, dp.coord) && checkForVisitableDir(dp.coord, cp->coord))
// {
// dp.moveRemains = cp.moveRemains - cost;
// dp.theNodeBefore = &cp;
// if(dp.accessible == CGPathNode::ACCESSIBLE)
// {
// mq.push(dp);
// }
// }
// }
// }
// }
//
// CPathNode *curNode = &graph[dest.x][dest.y];
// if(!curNode->theNodeBefore) //destination is not accessible
// return false;
//
//
// //fill ret with found path
// ret.nodes.clear();
// while(curNode->coord != graph[src.x][src.y].coord)
// {
// ret.nodes.push_back(*curNode);
// curNode = curNode->theNodeBefore;
// }
// ret.nodes.push_back(graph[src.x][src.y]);
//
// return true;
//}
bool CGameState::isVisible(int3 pos, int player) bool CGameState::isVisible(int3 pos, int player)
{ {
if(player == 255) //neutral player if(player == 255) //neutral player

View File

@ -241,6 +241,19 @@ struct CPathNode
bool visited; bool visited;
}; };
struct CGPathNode
{
enum {ACCESSIBLE=1, VISITABLE, BLOCKVIS, BLOCKED}; //BLOCKVIS - visitable from neighbourign tile but not passable
ui8 land;
ui8 accessible; //the enum above
ui8 turns;
ui32 moveRemains;
CPathNode * theNodeBefore;
int3 coord; //coordiantes
CGPathNode();
};
struct DLL_EXPORT CPath struct DLL_EXPORT CPath
{ {
std::vector<CPathNode> nodes; //just get node by node std::vector<CPathNode> nodes; //just get node by node
@ -250,6 +263,16 @@ struct DLL_EXPORT CPath
void convert(ui8 mode); //mode=0 -> from 'manifest' to 'object' void convert(ui8 mode); //mode=0 -> from 'manifest' to 'object'
}; };
struct CPathsInfo
{
int3 sizes;
CGPathNode ***nodes; //[w][h][level]
void getPath(const int3 &src, const int3 &dst, CPath &out);
CPathsInfo(const int3 &sizes);
~CPathsInfo();
};
class DLL_EXPORT CGameState class DLL_EXPORT CGameState
{ {
public: public:
@ -299,6 +322,7 @@ public:
int canBuildStructure(const CGTownInstance *t, int ID);// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements int canBuildStructure(const CGTownInstance *t, int ID);// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
bool checkForVisitableDir(const int3 & src, const int3 & dst) const; //check if dst tile is visitable from dst tile bool checkForVisitableDir(const int3 & src, const int3 & dst) const; //check if dst tile is visitable from dst tile
bool getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath &ret); //calculates path between src and dest; returns pointer to newly allocated CPath or NULL if path does not exists bool getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath &ret); //calculates path between src and dest; returns pointer to newly allocated CPath or NULL if path does not exists
void calculatePaths(const CGHeroInstance *hero, CPathsInfo &out, const int3 &src = int3(-1,-1,-1)); //calculates path between src and dest; returns pointer to newly allocated CPath or NULL if path does not exists
bool isVisible(int3 pos, int player); bool isVisible(int3 pos, int player);
bool isVisible(const CGObjectInstance *obj, int player); bool isVisible(const CGObjectInstance *obj, int player);