2011-01-20 15:56:30 +00:00
|
|
|
// ==============================================================
|
|
|
|
// This file is part of Glest (www.glest.org)
|
|
|
|
//
|
2011-12-14 07:40:48 +00:00
|
|
|
// Copyright (C) 2001-2008 Martiño Figueroa
|
2011-01-20 15:56:30 +00:00
|
|
|
//
|
|
|
|
// You can redistribute this code and/or modify it under
|
|
|
|
// the terms of the GNU General Public License as published
|
|
|
|
// by the Free Software Foundation; either version 2 of the
|
|
|
|
// License, or (at your option) any later version
|
|
|
|
// ==============================================================
|
|
|
|
|
|
|
|
#ifndef _GLEST_GAME_PATHFINDER_H_
|
|
|
|
#define _GLEST_GAME_PATHFINDER_H_
|
|
|
|
|
|
|
|
#include "vec.h"
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
#include <map>
|
|
|
|
#include "game_constants.h"
|
|
|
|
#include "skill_type.h"
|
|
|
|
#include "leak_dumper.h"
|
|
|
|
|
|
|
|
using std::vector;
|
|
|
|
using Shared::Graphics::Vec2i;
|
|
|
|
|
|
|
|
namespace Glest { namespace Game {
|
|
|
|
|
|
|
|
class Map;
|
|
|
|
class Unit;
|
|
|
|
|
2011-09-26 23:55:18 +00:00
|
|
|
// The order of directions is:
|
|
|
|
// N, NE, E, SE, S, SW, W, NW
|
|
|
|
typedef unsigned char direction;
|
|
|
|
#define NO_DIRECTION 8
|
|
|
|
typedef unsigned char directionset;
|
|
|
|
|
2011-01-20 15:56:30 +00:00
|
|
|
// =====================================================
|
|
|
|
// class PathFinder
|
|
|
|
//
|
|
|
|
/// Finds paths for units using a modification of the A* algorithm
|
|
|
|
// =====================================================
|
|
|
|
|
|
|
|
class PathFinder {
|
|
|
|
public:
|
|
|
|
class Node {
|
|
|
|
public:
|
2011-02-16 19:44:12 +00:00
|
|
|
Node() {
|
|
|
|
clear();
|
|
|
|
}
|
|
|
|
void clear() {
|
|
|
|
pos.x = 0;
|
|
|
|
pos.y = 0;
|
2011-01-20 15:56:30 +00:00
|
|
|
next=NULL;
|
|
|
|
prev=NULL;
|
|
|
|
heuristic=0.0;
|
|
|
|
exploredCell=false;
|
|
|
|
}
|
|
|
|
Vec2i pos;
|
|
|
|
Node *next;
|
|
|
|
Node *prev;
|
|
|
|
float heuristic;
|
|
|
|
bool exploredCell;
|
|
|
|
};
|
|
|
|
typedef vector<Node*> Nodes;
|
|
|
|
|
2011-03-18 03:53:06 +00:00
|
|
|
class FactionState {
|
|
|
|
public:
|
|
|
|
FactionState() {
|
|
|
|
openPosList.clear();
|
|
|
|
openNodesList.clear();
|
|
|
|
closedNodesList.clear();
|
|
|
|
nodePool.clear();
|
|
|
|
nodePoolCount = 0;
|
|
|
|
useMaxNodeCount = 0;
|
|
|
|
precachedTravelState.clear();
|
|
|
|
precachedPath.clear();
|
2011-10-05 21:46:41 +00:00
|
|
|
//mapFromToNodeList.clear();
|
|
|
|
//lastFromToNodeListFrame = -100;
|
2011-03-18 03:53:06 +00:00
|
|
|
}
|
|
|
|
std::map<Vec2i, bool> openPosList;
|
|
|
|
std::map<float, Nodes> openNodesList;
|
|
|
|
std::map<float, Nodes> closedNodesList;
|
|
|
|
std::vector<Node> nodePool;
|
|
|
|
int nodePoolCount;
|
|
|
|
RandomGen random;
|
|
|
|
int useMaxNodeCount;
|
|
|
|
|
|
|
|
std::map<int,TravelState> precachedTravelState;
|
|
|
|
std::map<int,std::vector<Vec2i> > precachedPath;
|
2011-10-05 21:46:41 +00:00
|
|
|
|
|
|
|
//int lastFromToNodeListFrame;
|
|
|
|
//std::map<int, std::map<Vec2i,std::map<Vec2i, bool> > > mapFromToNodeList;
|
2011-03-18 03:53:06 +00:00
|
|
|
};
|
|
|
|
typedef vector<FactionState> FactionStateList;
|
|
|
|
|
2011-01-20 15:56:30 +00:00
|
|
|
public:
|
|
|
|
static const int maxFreeSearchRadius;
|
|
|
|
static const int pathFindRefresh;
|
2011-01-28 07:17:32 +00:00
|
|
|
static const int pathFindBailoutRadius;
|
2011-04-26 21:51:18 +00:00
|
|
|
static const int pathFindExtendRefreshForNodeCount;
|
2011-06-24 19:40:47 +00:00
|
|
|
static const int pathFindExtendRefreshNodeCountMin;
|
|
|
|
static const int pathFindExtendRefreshNodeCountMax;
|
2011-01-20 15:56:30 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
|
2011-03-18 03:53:06 +00:00
|
|
|
static int pathFindNodesMax;
|
2011-04-14 02:51:13 +00:00
|
|
|
static int pathFindNodesAbsoluteMax;
|
2011-03-18 03:53:06 +00:00
|
|
|
|
|
|
|
FactionStateList factions;
|
2011-01-20 15:56:30 +00:00
|
|
|
const Map *map;
|
|
|
|
|
|
|
|
public:
|
|
|
|
PathFinder();
|
|
|
|
PathFinder(const Map *map);
|
|
|
|
~PathFinder();
|
|
|
|
void init(const Map *map);
|
2011-03-18 03:53:06 +00:00
|
|
|
TravelState findPath(Unit *unit, const Vec2i &finalPos, bool *wasStuck=NULL,int frameIndex=-1);
|
|
|
|
void clearUnitPrecache(Unit *unit);
|
2011-03-29 10:01:01 +00:00
|
|
|
void removeUnitPrecache(Unit *unit);
|
2011-01-20 15:56:30 +00:00
|
|
|
|
2012-03-10 03:27:25 +00:00
|
|
|
int findNodeIndex(Node *node, Nodes &nodeList);
|
|
|
|
int findNodeIndex(Node *node, std::vector<Node> &nodeList);
|
|
|
|
|
|
|
|
void saveGame(XmlNode *rootNode);
|
|
|
|
|
2011-01-20 15:56:30 +00:00
|
|
|
private:
|
2011-04-14 02:51:13 +00:00
|
|
|
TravelState aStar(Unit *unit, const Vec2i &finalPos, bool inBailout, int frameIndex, int maxNodeCount=-1);
|
|
|
|
Node *newNode(FactionState &faction,int maxNodeCount);
|
2011-01-20 15:56:30 +00:00
|
|
|
Vec2i computeNearestFreePos(const Unit *unit, const Vec2i &targetPos);
|
|
|
|
float heuristic(const Vec2i &pos, const Vec2i &finalPos);
|
2011-03-18 03:53:06 +00:00
|
|
|
bool openPos(const Vec2i &sucPos,FactionState &faction);
|
2011-01-20 15:56:30 +00:00
|
|
|
|
2011-03-18 03:53:06 +00:00
|
|
|
Node * minHeuristicFastLookup(FactionState &faction);
|
2011-02-04 06:34:32 +00:00
|
|
|
|
2011-04-14 02:51:13 +00:00
|
|
|
bool processNode(Unit *unit, Node *node,const Vec2i finalPos, int i, int j, bool &nodeLimitReached, int maxNodeCount);
|
2011-02-04 06:34:32 +00:00
|
|
|
void processNearestFreePos(const Vec2i &finalPos, int i, int j, int size, Field field, int teamIndex,Vec2i unitPos, Vec2i &nearestPos, float &nearestDist);
|
2011-06-24 19:40:47 +00:00
|
|
|
int getPathFindExtendRefreshNodeCount(int factionIndex);
|
2011-09-26 23:55:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
bool contained(Vec2i c);
|
2011-12-02 16:07:59 +00:00
|
|
|
direction directionOfMove(Vec2i to, Vec2i from) const;
|
2011-12-02 17:46:02 +00:00
|
|
|
direction directionWeCameFrom(Vec2i node, Vec2i nodeFrom) const;
|
2011-09-26 23:55:18 +00:00
|
|
|
bool isEnterable(Vec2i coord);
|
|
|
|
Vec2i adjustInDirection(Vec2i c, int dir);
|
2011-12-02 16:07:59 +00:00
|
|
|
bool directionIsDiagonal(direction dir) const;
|
2011-09-26 23:55:18 +00:00
|
|
|
directionset forcedNeighbours(Vec2i coord,direction dir);
|
2011-12-02 16:07:59 +00:00
|
|
|
bool implies(bool a, bool b) const;
|
|
|
|
directionset addDirectionToSet(directionset dirs, direction dir) const;
|
2011-12-02 17:46:02 +00:00
|
|
|
directionset naturalNeighbours(direction dir) const;
|
2011-12-02 16:07:59 +00:00
|
|
|
direction nextDirectionInSet(directionset *dirs) const;
|
2011-09-26 23:55:18 +00:00
|
|
|
Vec2i jump(Vec2i dest, direction dir, Vec2i start,std::vector<Vec2i> &path,int pathLength);
|
|
|
|
bool addToOpenSet(Unit *unit, Node *node,const Vec2i finalPos, Vec2i sucPos, bool &nodeLimitReached,int maxNodeCount,Node **newNodeAdded,bool bypassChecks);
|
2011-01-20 15:56:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}}//end namespace
|
|
|
|
|
|
|
|
#endif
|