mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-06 09:09:40 +02:00
Split pathfinder into multiple smaller files
This commit is contained in:
222
lib/pathfinder/CGPathNode.h
Normal file
222
lib/pathfinder/CGPathNode.h
Normal file
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* CGPathNode.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../GameConstants.h"
|
||||
#include "../int3.h"
|
||||
|
||||
#include <boost/heap/fibonacci_heap.hpp>
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class CGHeroInstance;
|
||||
class CGObjectInstance;
|
||||
class CGameState;
|
||||
class CPathfinderHelper;
|
||||
struct TerrainTile;
|
||||
|
||||
template<typename N>
|
||||
struct DLL_LINKAGE NodeComparer
|
||||
{
|
||||
STRONG_INLINE
|
||||
bool operator()(const N * lhs, const N * rhs) const
|
||||
{
|
||||
return lhs->getCost() > rhs->getCost();
|
||||
}
|
||||
};
|
||||
|
||||
struct DLL_LINKAGE CGPathNode
|
||||
{
|
||||
using ELayer = EPathfindingLayer;
|
||||
|
||||
enum ENodeAction : ui8
|
||||
{
|
||||
UNKNOWN = 0,
|
||||
EMBARK = 1,
|
||||
DISEMBARK,
|
||||
NORMAL,
|
||||
BATTLE,
|
||||
VISIT,
|
||||
BLOCKING_VISIT,
|
||||
TELEPORT_NORMAL,
|
||||
TELEPORT_BLOCKING_VISIT,
|
||||
TELEPORT_BATTLE
|
||||
};
|
||||
|
||||
enum EAccessibility : ui8
|
||||
{
|
||||
NOT_SET = 0,
|
||||
ACCESSIBLE = 1, //tile can be entered and passed
|
||||
VISITABLE, //tile can be entered as the last tile in path
|
||||
BLOCKVIS, //visitable from neighboring tile but not passable
|
||||
FLYABLE, //can only be accessed in air layer
|
||||
BLOCKED //tile can be neither entered nor visited
|
||||
};
|
||||
|
||||
CGPathNode * theNodeBefore;
|
||||
int3 coord; //coordinates
|
||||
ELayer layer;
|
||||
ui32 moveRemains; //remaining movement points after hero reaches the tile
|
||||
ui8 turns; //how many turns we have to wait before reaching the tile - 0 means current turn
|
||||
|
||||
EAccessibility accessible;
|
||||
ENodeAction action;
|
||||
bool locked;
|
||||
bool inPQ;
|
||||
|
||||
CGPathNode()
|
||||
: coord(-1),
|
||||
layer(ELayer::WRONG),
|
||||
pqHandle(nullptr)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
STRONG_INLINE
|
||||
void reset()
|
||||
{
|
||||
locked = false;
|
||||
accessible = NOT_SET;
|
||||
moveRemains = 0;
|
||||
cost = std::numeric_limits<float>::max();
|
||||
turns = 255;
|
||||
theNodeBefore = nullptr;
|
||||
action = UNKNOWN;
|
||||
inPQ = false;
|
||||
pq = nullptr;
|
||||
}
|
||||
|
||||
STRONG_INLINE
|
||||
float getCost() const
|
||||
{
|
||||
return cost;
|
||||
}
|
||||
|
||||
STRONG_INLINE
|
||||
void setCost(float value)
|
||||
{
|
||||
if(value == cost)
|
||||
return;
|
||||
|
||||
bool getUpNode = value < cost;
|
||||
cost = value;
|
||||
// If the node is in the heap, update the heap.
|
||||
if(inPQ && pq != nullptr)
|
||||
{
|
||||
if(getUpNode)
|
||||
{
|
||||
pq->increase(this->pqHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
pq->decrease(this->pqHandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STRONG_INLINE
|
||||
void update(const int3 & Coord, const ELayer Layer, const EAccessibility Accessible)
|
||||
{
|
||||
if(layer == ELayer::WRONG)
|
||||
{
|
||||
coord = Coord;
|
||||
layer = Layer;
|
||||
}
|
||||
else
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
accessible = Accessible;
|
||||
}
|
||||
|
||||
STRONG_INLINE
|
||||
bool reachable() const
|
||||
{
|
||||
return turns < 255;
|
||||
}
|
||||
|
||||
using TFibHeap = boost::heap::fibonacci_heap<CGPathNode *, boost::heap::compare<NodeComparer<CGPathNode>>>;
|
||||
|
||||
TFibHeap::handle_type pqHandle;
|
||||
TFibHeap* pq;
|
||||
|
||||
private:
|
||||
float cost; //total cost of the path to this tile measured in turns with fractions
|
||||
};
|
||||
|
||||
struct DLL_LINKAGE CGPath
|
||||
{
|
||||
std::vector<CGPathNode> nodes; //just get node by node
|
||||
|
||||
int3 startPos() const; // start point
|
||||
int3 endPos() const; //destination point
|
||||
};
|
||||
|
||||
struct DLL_LINKAGE CPathsInfo
|
||||
{
|
||||
using ELayer = EPathfindingLayer;
|
||||
|
||||
const CGHeroInstance * hero;
|
||||
int3 hpos;
|
||||
int3 sizes;
|
||||
boost::multi_array<CGPathNode, 4> nodes; //[layer][level][w][h]
|
||||
|
||||
CPathsInfo(const int3 & Sizes, const CGHeroInstance * hero_);
|
||||
~CPathsInfo();
|
||||
const CGPathNode * getPathInfo(const int3 & tile) const;
|
||||
bool getPath(CGPath & out, const int3 & dst) const;
|
||||
const CGPathNode * getNode(const int3 & coord) const;
|
||||
|
||||
STRONG_INLINE
|
||||
CGPathNode * getNode(const int3 & coord, const ELayer layer)
|
||||
{
|
||||
return &nodes[layer][coord.z][coord.x][coord.y];
|
||||
}
|
||||
};
|
||||
|
||||
struct DLL_LINKAGE PathNodeInfo
|
||||
{
|
||||
CGPathNode * node;
|
||||
const CGObjectInstance * nodeObject;
|
||||
const CGHeroInstance * nodeHero;
|
||||
const TerrainTile * tile;
|
||||
int3 coord;
|
||||
bool guarded;
|
||||
PlayerRelations::PlayerRelations objectRelations;
|
||||
PlayerRelations::PlayerRelations heroRelations;
|
||||
bool isInitialPosition;
|
||||
|
||||
PathNodeInfo();
|
||||
|
||||
virtual void setNode(CGameState * gs, CGPathNode * n);
|
||||
|
||||
void updateInfo(CPathfinderHelper * hlp, CGameState * gs);
|
||||
|
||||
bool isNodeObjectVisitable() const;
|
||||
};
|
||||
|
||||
struct DLL_LINKAGE CDestinationNodeInfo : public PathNodeInfo
|
||||
{
|
||||
CGPathNode::ENodeAction action;
|
||||
int turn;
|
||||
int movementLeft;
|
||||
float cost; //same as CGPathNode::cost
|
||||
bool blocked;
|
||||
bool isGuardianTile;
|
||||
|
||||
CDestinationNodeInfo();
|
||||
|
||||
virtual void setNode(CGameState * gs, CGPathNode * n) override;
|
||||
|
||||
virtual bool isBetterWay() const;
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
Reference in New Issue
Block a user