mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
Added AStar pathfinding.
It can be removed easily by undefing USE_ASTAR_PATHS. See AStar thread in mod discussion forum for changes. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@1331 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -10,6 +10,176 @@
|
||||
#define _PATHAI_H
|
||||
#include "isometric utils.h"
|
||||
|
||||
|
||||
#define USE_ASTAR_PATHS
|
||||
|
||||
#ifdef USE_ASTAR_PATHS
|
||||
|
||||
namespace ASTAR {
|
||||
#include "BinaryHeap.hpp"
|
||||
#include <vector>
|
||||
|
||||
enum eAStar
|
||||
{
|
||||
AStar_Init,
|
||||
AStar_Open,
|
||||
AStar_Closed
|
||||
};
|
||||
|
||||
class AStar_Data
|
||||
{
|
||||
public:
|
||||
AStar_Data()
|
||||
{
|
||||
cost = f = APCost = direction = prevCost = 0;
|
||||
extraGCoverCost = -1;//-1 means we have not stopped at this node
|
||||
wasBackwards = false;
|
||||
status = AStar_Init;
|
||||
parent = GridNode(-1,-1);
|
||||
};
|
||||
//no H
|
||||
int cost;//G
|
||||
int f;//F
|
||||
int APCost;//the APs spent to get here
|
||||
int extraGCoverCost;//an extra cost that makes stopping in midpath at a node with little cover worse
|
||||
GridNode parent;
|
||||
eAStar status;
|
||||
int prevCost;
|
||||
bool wasBackwards;
|
||||
int direction;
|
||||
};
|
||||
|
||||
typedef HEAP<int, GridNode> AStarHeap;
|
||||
|
||||
class AStarPathfinder
|
||||
{
|
||||
public:
|
||||
AStarPathfinder ();
|
||||
static AStarPathfinder& GetInstance();
|
||||
int GetPath (SOLDIERTYPE *s ,
|
||||
INT16 dest,
|
||||
INT8 ubLevel,
|
||||
INT16 usMovementMode,
|
||||
INT8 bCopy,
|
||||
UINT8 fFlags );
|
||||
|
||||
private:
|
||||
static AStarPathfinder* pThis;
|
||||
std::vector<GridNode> ClosedList;
|
||||
CBinaryHeap<int, GridNode> OpenHeap;
|
||||
|
||||
int direction;//current direction
|
||||
int startDir;
|
||||
int endDir;
|
||||
int lastDir;
|
||||
bool startingLoop;
|
||||
|
||||
SOLDIERTYPE* pSoldier;
|
||||
INT8 onRooftop;//aka ubLevel, not sure if this bool is logically reversed yet
|
||||
bool fNonFenceJumper;
|
||||
bool fNonSwimmer;
|
||||
bool fPathingForPlayer;
|
||||
bool fPathAroundPeople;
|
||||
bool fGoingThroughDoor;
|
||||
int bOKToAddStructID;
|
||||
int bLoopState;
|
||||
bool bWaterToWater;
|
||||
bool fVisitSpotsOnlyOnce;
|
||||
bool fCheckedBehind;
|
||||
bool fTurnBased;
|
||||
bool fCloseGoodEnough;
|
||||
bool fContinuousTurnNeeded;
|
||||
bool fConsiderPersonAtDestAsObstacle;
|
||||
bool fCopyReachable;
|
||||
bool fCopyPathCosts;
|
||||
|
||||
int maxAPBudget;//the gubNPCAPBudget
|
||||
int mercsMaxAPs;//the merc only has so many points to move with
|
||||
int movementMode;
|
||||
int sClosePathLimit;
|
||||
|
||||
int PATHAI_VISIBLE_DEBUG_Counter;
|
||||
|
||||
//vehicle defined in cpp
|
||||
//#ifdef VEHICLE
|
||||
BOOLEAN fMultiTile;
|
||||
STRUCTURE_FILE_REF * pStructureFileRef;
|
||||
//#endif
|
||||
|
||||
// member variables to prevent passing them around
|
||||
GridNode StartNode;
|
||||
GridNode DestNode;
|
||||
GridNode CurrentNode;
|
||||
GridNode ParentNode;
|
||||
INT16 ParentNodeIndex;
|
||||
INT16 CurrentNodeIndex;
|
||||
|
||||
AStar_Data AStarData[WORLD_COLS][WORLD_ROWS];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AStarHeap AStar ();
|
||||
|
||||
void ExecuteAStarLogic();
|
||||
|
||||
void ResetAStarList ();
|
||||
|
||||
int TerrainCostToAStarG(int const terrainCost);
|
||||
int CalcG (int* pPrevCost);
|
||||
int CalcAP (int const terrainCost);
|
||||
int CalcH ();
|
||||
int CalcGCover (int const NodeIndex,
|
||||
int const APCost);
|
||||
int CalcStartingAP ();
|
||||
|
||||
//including THREATTYPE was a pain, so pass by value
|
||||
int CalcCoverValue (INT16 sMyGridNo, INT32 iMyThreat, INT32 iMyAPsLeft,
|
||||
INT32 myThreatsiOrigRange, INT16 myThreatssGridNo, SOLDIERTYPE* myThreatspOpponent,
|
||||
INT32 myThreatsiValue, INT32 myThreatsiAPs, INT32 myThreatsiCertainty);
|
||||
|
||||
eAStar GetAStarStatus (const GridNode node) const {return AStarData[node.x][node.y].status;};
|
||||
GridNode GetAStarParent (const GridNode node) const {return AStarData[node.x][node.y].parent;};
|
||||
int GetAStarG (const GridNode node) const {return AStarData[node.x][node.y].cost;};
|
||||
int GetExtraGCover (const GridNode node) const {return AStarData[node.x][node.y].extraGCoverCost;};
|
||||
int GetAStarF (const GridNode node) const {return AStarData[node.x][node.y].f;};
|
||||
int GetActionPoints (const GridNode node) const {return AStarData[node.x][node.y].APCost;};
|
||||
bool GetLoopState (const GridNode node) const {return AStarData[node.x][node.y].wasBackwards;};
|
||||
int GetPrevCost (const GridNode node) const {return AStarData[node.x][node.y].prevCost;};
|
||||
int GetDirection (const GridNode node) const {return AStarData[node.x][node.y].direction;};
|
||||
|
||||
void SetAStarStatus (const GridNode node, const eAStar status) {AStarData[node.x][node.y].status = status;};
|
||||
void SetAStarParent (const GridNode node, const GridNode parent) {AStarData[node.x][node.y].parent = parent;};
|
||||
void SetAStarG (const GridNode node, const int cost) {AStarData[node.x][node.y].cost = cost;};
|
||||
void SetExtraGCover (const GridNode node, const int extraGCoverCost) {AStarData[node.x][node.y].extraGCoverCost = extraGCoverCost;};
|
||||
void SetAStarF (const GridNode node, const int f) {AStarData[node.x][node.y].f = f;};
|
||||
void SetActionPoints (const GridNode node, const int APCost) {AStarData[node.x][node.y].APCost = APCost;};
|
||||
void SetLoopState (const GridNode node, const int loopState);
|
||||
void SetPrevCost (const GridNode node, const int prevCost) {AStarData[node.x][node.y].prevCost = prevCost;};
|
||||
void SetDirection (const GridNode node, const int direction) {AStarData[node.x][node.y].direction = direction;};
|
||||
|
||||
INT16 PythSpacesAway (GridNode const node1,
|
||||
GridNode const node2);
|
||||
INT16 SpacesAway (GridNode const node1,
|
||||
GridNode const node2);
|
||||
//bool IsDiagonal (GridNode const node1,
|
||||
// GridNode const node2) {return (abs(node1.x - node2.x) && abs(node1.y - node2.y));};
|
||||
bool IsDiagonal (int const direction) {return (direction & 1);};
|
||||
void InitVehicle ();
|
||||
int VehicleObstacleCheck();
|
||||
bool CanTraverse ();
|
||||
bool IsSomeoneInTheWay();
|
||||
void IncrementLoop ();
|
||||
void InitLoop ();
|
||||
bool ContinueLoop ();
|
||||
};
|
||||
|
||||
};//end namespace ASTAR
|
||||
|
||||
#endif//end #ifdef USE_ASTAR_PATHS
|
||||
|
||||
|
||||
BOOLEAN InitPathAI( void );
|
||||
void ShutDownPathAI( void );
|
||||
INT16 PlotPath( SOLDIERTYPE *pSold, INT16 sDestGridno, INT8 bCopyRoute, INT8 bPlot, INT8 bStayOn, UINT16 usMovementMode, INT8 bStealth, INT8 bReverse , INT16 sAPBudget);
|
||||
|
||||
+1505
File diff suppressed because it is too large
Load Diff
+24
-1
@@ -19,7 +19,30 @@
|
||||
|
||||
#define WORLD_BASE_HEIGHT 0
|
||||
#define WORLD_CLIFF_HEIGHT 80
|
||||
|
||||
|
||||
|
||||
//ADB I'm tired of seeing a 5 digit number when looking at something's gridno.
|
||||
//I need to see an x and y. I created this class for the AStar,
|
||||
//but moved it here as you can convert a regular INT16 gridno to a GridNode then print it out for debugging.
|
||||
//Don't switch between the 2 types too often, IntToGridNode is especially slow
|
||||
class GridNode
|
||||
{
|
||||
public:
|
||||
GridNode () {x = -1; y = -1;};
|
||||
GridNode (INT16 const loc) {this->x = loc % WORLD_COLS; this->y = loc / WORLD_COLS;};
|
||||
GridNode (int x, int y) {GridNode::x = x; GridNode::y = y;};
|
||||
GridNode operator + (const GridNode& point) const {return GridNode(this->x + point.x, this->y + point.y);};
|
||||
bool operator == (const GridNode& point) const {return this->x == point.x && this->y == point.y;};
|
||||
bool operator != (const GridNode& point) const {return !(*this == point);};
|
||||
INT16 GridNodeToInt() {return (this->x + this->y * WORLD_COLS);};
|
||||
void IntToGridNode(INT16 const loc) {this->x = loc % WORLD_COLS; this->y = loc / WORLD_COLS;};
|
||||
bool isInWorld() {return (this->x < WORLD_COLS && this->x >= 0 &&
|
||||
this->y < WORLD_ROWS && this->y >= 0);};
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
|
||||
//A macro that actually memcpy's over data and increments the pointer automatically
|
||||
//based on the size. Works like a FileRead except with a buffer instead of a file pointer.
|
||||
//Used by LoadWorld() and child functions.
|
||||
|
||||
Reference in New Issue
Block a user