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:
parent
90c31d5cd5
commit
fceeb05e16
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user