- some in progress pathfinder work
This commit is contained in:
parent
85f98e8f55
commit
3ff0796bec
|
@ -220,17 +220,23 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
|
|||
|
||||
int unitFactionIndex = unit->getFactionIndex();
|
||||
|
||||
bool minorDebugPathfinderPerformance = false;
|
||||
Chrono chrono;
|
||||
//if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
|
||||
if(minorDebugPathfinderPerformance) chrono.start();
|
||||
|
||||
uint32 searched_node_count = 0;
|
||||
minorDebugPathfinder = false;
|
||||
bool enableFastPathfinder = Config::getInstance().getBool("EnableFastPathFinder","false");
|
||||
if(enableFastPathfinder == true) {
|
||||
if(minorDebugPathfinder) printf("Fast Pathfind Unit [%d - %s] from = %s to = %s frameIndex = %d\n",unit->getId(),unit->getType()->getName().c_str(),unit->getPos().getString().c_str(),finalPos.getString().c_str(),frameIndex);
|
||||
|
||||
ts = aStarFast(unit, finalPos, false, frameIndex, maxNodeCount);
|
||||
ts = aStarFast(unit, finalPos, false, frameIndex, maxNodeCount,&searched_node_count);
|
||||
}
|
||||
else {
|
||||
if(minorDebugPathfinder) printf("Legacy Pathfind Unit [%d - %s] from = %s to = %s frameIndex = %d\n",unit->getId(),unit->getType()->getName().c_str(),unit->getPos().getString().c_str(),finalPos.getString().c_str(),frameIndex);
|
||||
|
||||
ts = aStar(unit, finalPos, false, frameIndex, maxNodeCount);
|
||||
ts = aStar(unit, finalPos, false, frameIndex, maxNodeCount,&searched_node_count);
|
||||
}
|
||||
|
||||
//post actions
|
||||
|
@ -309,10 +315,10 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
|
|||
int maxBailoutNodeCount = (PathFinder::pathFindBailoutRadius * 2);
|
||||
|
||||
if(enableFastPathfinder == true) {
|
||||
ts= aStarFast(unit, newFinalPos, true, frameIndex, maxBailoutNodeCount);
|
||||
ts= aStarFast(unit, newFinalPos, true, frameIndex, maxBailoutNodeCount,&searched_node_count);
|
||||
}
|
||||
else {
|
||||
ts= aStar(unit, newFinalPos, true, frameIndex, maxBailoutNodeCount);
|
||||
ts= aStar(unit, newFinalPos, true, frameIndex, maxBailoutNodeCount,&searched_node_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -336,10 +342,10 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
|
|||
int maxBailoutNodeCount = (PathFinder::pathFindBailoutRadius * 2);
|
||||
|
||||
if(enableFastPathfinder == true) {
|
||||
ts= aStarFast(unit, newFinalPos, true, frameIndex, maxBailoutNodeCount);
|
||||
ts= aStarFast(unit, newFinalPos, true, frameIndex, maxBailoutNodeCount,&searched_node_count);
|
||||
}
|
||||
else {
|
||||
ts= aStar(unit, newFinalPos, true, frameIndex, maxBailoutNodeCount);
|
||||
ts= aStar(unit, newFinalPos, true, frameIndex, maxBailoutNodeCount,&searched_node_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -387,6 +393,8 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
|
|||
if(frameIndex < 0) {
|
||||
unit->setCurrSkill(scStop);
|
||||
}
|
||||
|
||||
if(minorDebugPathfinderPerformance && chrono.getMillis() >= 1) printf("Unit [%d - %s] astar #2 took [%lld] msecs, ts = %d searched_node_count = %d.\n",unit->getId(),unit->getType()->getName().c_str(),(long long int)chrono.getMillis(),ts,searched_node_count);
|
||||
return tsBlocked;
|
||||
}
|
||||
}
|
||||
|
@ -405,6 +413,8 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
|
|||
}
|
||||
|
||||
if(minorDebugPathfinder) printf("Pathfind Unit [%d - %s] INT BAILOUT ATTEMPT BLOCKED frameIndex = %d\n",unit->getId(),unit->getType()->getName().c_str(),frameIndex);
|
||||
|
||||
if(minorDebugPathfinderPerformance && chrono.getMillis() >= 1) printf("Unit [%d - %s] astar #3 took [%lld] msecs, ts = %d searched_node_count = %d.\n",unit->getId(),unit->getType()->getName().c_str(),(long long int)chrono.getMillis(),ts,searched_node_count);
|
||||
return tsBlocked;
|
||||
}
|
||||
}
|
||||
|
@ -414,12 +424,16 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() >= 1) printf("In [%s::%s Line: %d] fastastar took [%lld] msecs, ts = %d nodeSearchCount = %d.\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis(),ts,nodeSearchCount);
|
||||
if(minorDebugPathfinderPerformance && chrono.getMillis() >= 1) printf("Unit [%d - %s] astar took [%lld] msecs, ts = %d searched_node_count = %d.\n",unit->getId(),unit->getType()->getName().c_str(),(long long int)chrono.getMillis(),ts,searched_node_count);
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
// ==================== PRIVATE ====================
|
||||
|
||||
TravelState PathFinder::aStarFast(Unit *unit, Vec2i finalPos, bool inBailout, int frameIndex, int maxNodeCount) {
|
||||
TravelState PathFinder::aStarFast(Unit *unit, Vec2i finalPos, bool inBailout, int frameIndex, int maxNodeCount,uint32 *searched_node_count) {
|
||||
TravelState ts = tsImpossible;
|
||||
|
||||
Chrono chrono;
|
||||
|
@ -448,9 +462,6 @@ TravelState PathFinder::aStarFast(Unit *unit, Vec2i finalPos, bool inBailout, in
|
|||
clearUnitPrecache(unit);
|
||||
}
|
||||
|
||||
/////////////////////////////////////
|
||||
|
||||
|
||||
// check the pre-cache to see if we can re-use a cached path
|
||||
if(frameIndex < 0) {
|
||||
if(factions[unitFactionIndex].precachedTravelState.find(unit->getId()) != factions[unitFactionIndex].precachedTravelState.end()) {
|
||||
|
@ -677,7 +688,6 @@ TravelState PathFinder::aStarFast(Unit *unit, Vec2i finalPos, bool inBailout, in
|
|||
//b) loop
|
||||
bool pathFound = true;
|
||||
bool nodeLimitReached = false;
|
||||
Node *node = NULL;
|
||||
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled == true && chrono.getMillis() > 4) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||
|
||||
|
@ -738,20 +748,15 @@ TravelState PathFinder::aStarFast(Unit *unit, Vec2i finalPos, bool inBailout, in
|
|||
}
|
||||
//
|
||||
|
||||
// START
|
||||
// Do the a-star base pathfind work if required
|
||||
|
||||
///////////////////////////////////////
|
||||
|
||||
|
||||
//finalPos= computeNearestFreePos(unit, finalPos);
|
||||
|
||||
FastAINodeCache nodeCache(unit);
|
||||
// Start of New Fast AStar
|
||||
FastAINode *fromNode = map->getCellNode(unit->getPos());
|
||||
FastAINode *toNode = map->getCellNode(finalPos);
|
||||
//FastAstar *fa = createFastAstar();
|
||||
FastAstar *fa = factions[unitFactionIndex].fa;
|
||||
astarStartSearch(fa,fromNode,toNode, unit);
|
||||
astarStartSearch(fa,fromNode,toNode, &nodeCache);
|
||||
|
||||
pathFound = false;
|
||||
unsigned int nodeSearchCount=0;
|
||||
|
@ -766,6 +771,9 @@ TravelState PathFinder::aStarFast(Unit *unit, Vec2i finalPos, bool inBailout, in
|
|||
|
||||
solution = getSolution(fa,count);
|
||||
}
|
||||
if(searched_node_count != NULL) {
|
||||
*searched_node_count = nodeSearchCount;
|
||||
}
|
||||
|
||||
if(count <= 1 || getLastSearchState(fa) != SEARCH_STATE_SUCCEEDED) {
|
||||
if(minorDebugPathfinder) printf("Fast Pathfind Unit [%d - %s] NOT FOUND PATH frameIndex = %d nodeSearchCount = %d\n",unit->getId(),unit->getType()->getName().c_str(),frameIndex,nodeSearchCount);
|
||||
|
@ -1265,7 +1273,7 @@ void PathFinder::astarJPS(std::map<Vec2i,Vec2i> cameFrom, Node *& node,
|
|||
|
||||
//route a unit using A* algorithm
|
||||
TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout,
|
||||
int frameIndex, int maxNodeCount) {
|
||||
int frameIndex, int maxNodeCount, uint32 *searched_node_count) {
|
||||
|
||||
Chrono chrono;
|
||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start();
|
||||
|
@ -1622,6 +1630,10 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
|
|||
pathFound, node, finalPos, tryJPSPathfinder,
|
||||
closedNodes, cameFrom, canAddNode, unit, maxNodeCount,frameIndex);
|
||||
|
||||
if(searched_node_count != NULL) {
|
||||
*searched_node_count = whileLoopCount;
|
||||
}
|
||||
|
||||
// Now see if the unit is eligble for pathfind max nodes boost?
|
||||
if(nodeLimitReached == true) {
|
||||
unit->incrementPathfindFailedConsecutiveFrameCount();
|
||||
|
|
|
@ -170,8 +170,8 @@ public:
|
|||
void loadGame(const XmlNode *rootNode);
|
||||
|
||||
private:
|
||||
TravelState aStarFast(Unit *unit, Vec2i finalPos, bool inBailout, int frameIndex, int maxNodeCount=-1);
|
||||
TravelState aStar(Unit *unit, const Vec2i &finalPos, bool inBailout, int frameIndex, int maxNodeCount=-1);
|
||||
TravelState aStarFast(Unit *unit, Vec2i finalPos, bool inBailout, int frameIndex, int maxNodeCount=-1,uint32 *searched_node_count=NULL);
|
||||
TravelState aStar(Unit *unit, const Vec2i &finalPos, bool inBailout, int frameIndex, int maxNodeCount=-1,uint32 *searched_node_count=NULL);
|
||||
//Node *newNode(FactionState &faction,int maxNodeCount);
|
||||
inline static Node *newNode(FactionState &faction, int maxNodeCount) {
|
||||
if( faction.nodePoolCount < faction.nodePool.size() &&
|
||||
|
|
|
@ -151,10 +151,33 @@ private:
|
|||
TechTree *techTree;
|
||||
const XmlNode *loadWorldNode;
|
||||
|
||||
std::map<int,std::map<Field, std::map<Vec2i,bool> > > mapSharedPathFinderCache;
|
||||
|
||||
public:
|
||||
Faction();
|
||||
~Faction();
|
||||
|
||||
inline const bool * aproxCanMoveSoonCached(int size, Field field, const Vec2i &pos1, const Vec2i &pos2) const {
|
||||
const bool *result = NULL;
|
||||
// std::map<int,std::map<Field, std::map<Vec2i,bool> > >::const_iterator iterFind1 = mapSharedPathFinderCache.find(size);
|
||||
// if(iterFind1 != mapSharedPathFinderCache.end()) {
|
||||
// std::map<Field, std::map<Vec2i,bool> >::const_iterator iterFind2 = iterFind1->second.find(field);
|
||||
// if(iterFind2 != iterFind1->second.end()) {
|
||||
// std::map<Vec2i,bool>::const_iterator iterFind3 = iterFind2->second.find(pos2);
|
||||
// if(iterFind3 != iterFind2->second.end()) {
|
||||
// result = &iterFind3->second;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
return result;
|
||||
}
|
||||
inline void addAproxCanMoveSoonCached(int size, Field field, const Vec2i &pos1, const Vec2i &pos2,bool result) {
|
||||
//mapSharedPathFinderCache[size][field][pos2]=result;
|
||||
}
|
||||
inline void clearAproxCanMoveSoonCached() {
|
||||
//mapSharedPathFinderCache.clear();
|
||||
}
|
||||
|
||||
inline void addLivingUnits(int id) { livingUnits.insert(id); }
|
||||
inline void addLivingUnitsp(Unit *unit) { livingUnitsp.insert(unit); }
|
||||
|
||||
|
|
|
@ -857,10 +857,6 @@ bool Unit::isBuilt() const{
|
|||
return (isBeingBuilt() == false);
|
||||
}
|
||||
|
||||
bool Unit::isPutrefacting() const{
|
||||
return deadCount!=0;
|
||||
}
|
||||
|
||||
bool Unit::isAlly(const Unit *unit) const {
|
||||
if(unit == NULL) {
|
||||
char szBuf[4096]="";
|
||||
|
|
|
@ -530,7 +530,9 @@ public:
|
|||
bool isBeingBuilt() const;
|
||||
bool isBuilt() const;
|
||||
bool isAnimProgressBound() const;
|
||||
bool isPutrefacting() const;
|
||||
bool isPutrefacting() const {
|
||||
return deadCount!=0;
|
||||
}
|
||||
bool isAlly(const Unit *unit) const;
|
||||
bool isDamaged() const;
|
||||
bool isInteresting(InterestingUnitType iut) const;
|
||||
|
|
|
@ -307,13 +307,30 @@ FastAINode * FastAINode::getNodeForEdgeIndex(int index,void *userData) const {
|
|||
resultNode = map->getCellNode(pos.x-1,pos.y-1,false);
|
||||
break;
|
||||
}
|
||||
if(resultNode != NULL) {
|
||||
Unit *unit = (Unit *)userData;
|
||||
if(resultNode->getPos() != unit->getCurrentPathFinderDesiredFinalPos()) {
|
||||
if(map->aproxCanMoveSoon(unit, pos, resultNode->getPos()) == false) {
|
||||
bool checkCellObjects = true;
|
||||
if(checkCellObjects == true && resultNode != NULL) {
|
||||
FastAINodeCache *nodeCache = (FastAINodeCache *)userData;
|
||||
std::map<Vec2i,std::map<Vec2i,bool> >::const_iterator iterFind = nodeCache->cachedCanMoveSoonList.find(pos);
|
||||
if(iterFind != nodeCache->cachedCanMoveSoonList.end() &&
|
||||
iterFind->second.find(resultNode->getPos()) != iterFind->second.end()) {
|
||||
const std::map<Vec2i,bool> &mapCache2 = iterFind->second;
|
||||
std::map<Vec2i,bool>::const_iterator iterFind2 = mapCache2.find(resultNode->getPos());
|
||||
|
||||
if(iterFind2->second == false) {
|
||||
resultNode = NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const Vec2i &nodePos = resultNode->getPos();
|
||||
|
||||
if(resultNode->getPos() != nodeCache->unit->getCurrentPathFinderDesiredFinalPos()) {
|
||||
if(map->aproxCanMoveSoon(nodeCache->unit, pos, resultNode->getPos()) == false) {
|
||||
resultNode = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
nodeCache->cachedCanMoveSoonList[pos][nodePos] = (resultNode != NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return resultNode;
|
||||
|
@ -323,7 +340,38 @@ float FastAINode::getDistance(const AI_Node *node,void *userData) {
|
|||
return pos.dist(dynamic_cast<const FastAINode *>(node)->pos);
|
||||
}
|
||||
float FastAINode::getCost(void *userData) {
|
||||
return 1.0f;
|
||||
float result = 1.0f;
|
||||
// bool checkCellObjects = true;
|
||||
// if(checkCellObjects == true) {
|
||||
// FastAINode *resultNode = map->getCellNode(pos,false);
|
||||
// if(resultNode != NULL) {
|
||||
// FastAINodeCache *nodeCache = (FastAINodeCache *)userData;
|
||||
// std::map<Vec2i,std::map<Vec2i,bool> >::const_iterator iterFind = nodeCache->cachedCanMoveSoonList.find(pos);
|
||||
// if(iterFind != nodeCache->cachedCanMoveSoonList.end() &&
|
||||
// iterFind->second.find(resultNode->getPos()) != iterFind->second.end()) {
|
||||
// const std::map<Vec2i,bool> &mapCache2 = iterFind->second;
|
||||
// std::map<Vec2i,bool>::const_iterator iterFind2 = mapCache2.find(resultNode->getPos());
|
||||
//
|
||||
// if(iterFind2->second == false) {
|
||||
// resultNode = NULL;
|
||||
// result = 9999999;
|
||||
// }
|
||||
// }
|
||||
// else {
|
||||
// const Vec2i &nodePos = resultNode->getPos();
|
||||
//
|
||||
// if(resultNode->getPos() != nodeCache->unit->getCurrentPathFinderDesiredFinalPos()) {
|
||||
// if(map->aproxCanMoveSoon(nodeCache->unit, pos, resultNode->getPos()) == false) {
|
||||
// resultNode = NULL;
|
||||
// result = 9999999;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// nodeCache->cachedCanMoveSoonList[pos][nodePos] = (resultNode != NULL);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned int FastAINode::getEdgeCount(void *userData) const {
|
||||
|
@ -1127,104 +1175,6 @@ bool Map::aproxCanMove(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2, s
|
|||
return true;
|
||||
}
|
||||
|
||||
//checks if a unit can move from between 2 cells using only visible cells (for pathfinding)
|
||||
bool Map::aproxCanMoveSoon(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2) const {
|
||||
if(isInside(pos1) == false || isInsideSurface(toSurfCoords(pos1)) == false ||
|
||||
isInside(pos2) == false || isInsideSurface(toSurfCoords(pos2)) == false) {
|
||||
|
||||
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
int size= unit->getType()->getSize();
|
||||
int teamIndex= unit->getTeam();
|
||||
Field field= unit->getCurrField();
|
||||
|
||||
//single cell units
|
||||
if(size == 1) {
|
||||
if(isAproxFreeCellOrMightBeFreeSoon(unit->getPos(),pos2, field, teamIndex) == false) {
|
||||
|
||||
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
|
||||
return false;
|
||||
}
|
||||
if(pos1.x != pos2.x && pos1.y != pos2.y) {
|
||||
if(isAproxFreeCellOrMightBeFreeSoon(unit->getPos(),Vec2i(pos1.x, pos2.y), field, teamIndex) == false) {
|
||||
|
||||
//Unit *cellUnit = getCell(Vec2i(pos1.x, pos2.y))->getUnit(field);
|
||||
//Object * obj = getSurfaceCell(toSurfCoords(Vec2i(pos1.x, pos2.y)))->getObject();
|
||||
|
||||
//printf("[%s] Line: %d returning false cell [%s] free [%d] cell unitid = %d object class = %d\n",__FUNCTION__,__LINE__,Vec2i(pos1.x, pos2.y).getString().c_str(),this->isFreeCell(Vec2i(pos1.x, pos2.y),field),(cellUnit != NULL ? cellUnit->getId() : -1),(obj != NULL ? obj->getType()->getClass() : -1));
|
||||
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
|
||||
return false;
|
||||
}
|
||||
if(isAproxFreeCellOrMightBeFreeSoon(unit->getPos(),Vec2i(pos2.x, pos1.y), field, teamIndex) == false) {
|
||||
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool isBadHarvestPos = false;
|
||||
if(unit != NULL) {
|
||||
Command *command= unit->getCurrCommand();
|
||||
if(command != NULL) {
|
||||
const HarvestCommandType *hct = dynamic_cast<const HarvestCommandType*>(command->getCommandType());
|
||||
if(hct != NULL && unit->isBadHarvestPos(pos2) == true) {
|
||||
isBadHarvestPos = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(unit == NULL || isBadHarvestPos == true) {
|
||||
|
||||
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
//multi cell units
|
||||
else {
|
||||
for(int i = pos2.x; i < pos2.x + size; ++i) {
|
||||
for(int j = pos2.y; j < pos2.y + size; ++j) {
|
||||
|
||||
Vec2i cellPos = Vec2i(i,j);
|
||||
if(isInside(cellPos) && isInsideSurface(toSurfCoords(cellPos))) {
|
||||
if(getCell(cellPos)->getUnit(unit->getCurrField()) != unit) {
|
||||
if(isAproxFreeCellOrMightBeFreeSoon(unit->getPos(),cellPos, field, teamIndex) == false) {
|
||||
|
||||
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool isBadHarvestPos = false;
|
||||
if(unit != NULL) {
|
||||
Command *command= unit->getCurrCommand();
|
||||
if(command != NULL) {
|
||||
const HarvestCommandType *hct = dynamic_cast<const HarvestCommandType*>(command->getCommandType());
|
||||
if(hct != NULL && unit->isBadHarvestPos(pos2) == true) {
|
||||
isBadHarvestPos = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(unit == NULL || isBadHarvestPos == true) {
|
||||
|
||||
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Vec2i Map::computeRefPos(const Selection *selection) const {
|
||||
Vec2i total= Vec2i(0);
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <cassert>
|
||||
#include "unit_type.h"
|
||||
#include "fast_path_finder.h"
|
||||
#include "command.h"
|
||||
#include "leak_dumper.h"
|
||||
|
||||
|
||||
|
@ -193,6 +194,15 @@ public:
|
|||
/// Represents the game map (and loads it from a gbm file)
|
||||
// =====================================================
|
||||
|
||||
class FastAINodeCache {
|
||||
public:
|
||||
FastAINodeCache(Unit *unit) {
|
||||
this->unit = unit;
|
||||
}
|
||||
Unit *unit;
|
||||
std::map<Vec2i,std::map<Vec2i,bool> > cachedCanMoveSoonList;
|
||||
};
|
||||
|
||||
class FastAINode : public AI_Node {
|
||||
protected:
|
||||
Vec2i pos;
|
||||
|
@ -432,7 +442,118 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
bool aproxCanMoveSoon(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2) const;
|
||||
//checks if a unit can move from between 2 cells using only visible cells (for pathfinding)
|
||||
inline bool aproxCanMoveSoon(const Unit *unit, const Vec2i &pos1, const Vec2i &pos2) const {
|
||||
if(isInside(pos1) == false || isInsideSurface(toSurfCoords(pos1)) == false ||
|
||||
isInside(pos2) == false || isInsideSurface(toSurfCoords(pos2)) == false) {
|
||||
|
||||
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
int size= unit->getType()->getSize();
|
||||
int teamIndex= unit->getTeam();
|
||||
Field field= unit->getCurrField();
|
||||
|
||||
const bool *cachedResult = unit->getFaction()->aproxCanMoveSoonCached(size,field,pos1,pos2);
|
||||
if(cachedResult != NULL) {
|
||||
return *cachedResult;
|
||||
}
|
||||
|
||||
//single cell units
|
||||
if(size == 1) {
|
||||
if(isAproxFreeCellOrMightBeFreeSoon(unit->getPos(),pos2, field, teamIndex) == false) {
|
||||
|
||||
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
|
||||
unit->getFaction()->addAproxCanMoveSoonCached(size,field, pos1, pos2, false);
|
||||
return false;
|
||||
}
|
||||
if(pos1.x != pos2.x && pos1.y != pos2.y) {
|
||||
if(isAproxFreeCellOrMightBeFreeSoon(unit->getPos(),Vec2i(pos1.x, pos2.y), field, teamIndex) == false) {
|
||||
|
||||
//Unit *cellUnit = getCell(Vec2i(pos1.x, pos2.y))->getUnit(field);
|
||||
//Object * obj = getSurfaceCell(toSurfCoords(Vec2i(pos1.x, pos2.y)))->getObject();
|
||||
|
||||
//printf("[%s] Line: %d returning false cell [%s] free [%d] cell unitid = %d object class = %d\n",__FUNCTION__,__LINE__,Vec2i(pos1.x, pos2.y).getString().c_str(),this->isFreeCell(Vec2i(pos1.x, pos2.y),field),(cellUnit != NULL ? cellUnit->getId() : -1),(obj != NULL ? obj->getType()->getClass() : -1));
|
||||
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
|
||||
unit->getFaction()->addAproxCanMoveSoonCached(size,field, pos1, pos2, false);
|
||||
return false;
|
||||
}
|
||||
if(isAproxFreeCellOrMightBeFreeSoon(unit->getPos(),Vec2i(pos2.x, pos1.y), field, teamIndex) == false) {
|
||||
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
|
||||
unit->getFaction()->addAproxCanMoveSoonCached(size,field, pos1, pos2, false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool isBadHarvestPos = false;
|
||||
if(unit != NULL) {
|
||||
Command *command= unit->getCurrCommand();
|
||||
if(command != NULL) {
|
||||
const HarvestCommandType *hct = dynamic_cast<const HarvestCommandType*>(command->getCommandType());
|
||||
if(hct != NULL && unit->isBadHarvestPos(pos2) == true) {
|
||||
isBadHarvestPos = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(unit == NULL || isBadHarvestPos == true) {
|
||||
|
||||
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
|
||||
unit->getFaction()->addAproxCanMoveSoonCached(size,field, pos1, pos2, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
unit->getFaction()->addAproxCanMoveSoonCached(size,field, pos1, pos2, true);
|
||||
return true;
|
||||
}
|
||||
//multi cell units
|
||||
else {
|
||||
for(int i = pos2.x; i < pos2.x + size; ++i) {
|
||||
for(int j = pos2.y; j < pos2.y + size; ++j) {
|
||||
|
||||
Vec2i cellPos = Vec2i(i,j);
|
||||
if(isInside(cellPos) && isInsideSurface(toSurfCoords(cellPos))) {
|
||||
if(getCell(cellPos)->getUnit(unit->getCurrField()) != unit) {
|
||||
if(isAproxFreeCellOrMightBeFreeSoon(unit->getPos(),cellPos, field, teamIndex) == false) {
|
||||
|
||||
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
|
||||
unit->getFaction()->addAproxCanMoveSoonCached(size,field, pos1, pos2, false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
|
||||
unit->getFaction()->addAproxCanMoveSoonCached(size,field, pos1, pos2, false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool isBadHarvestPos = false;
|
||||
if(unit != NULL) {
|
||||
Command *command= unit->getCurrCommand();
|
||||
if(command != NULL) {
|
||||
const HarvestCommandType *hct = dynamic_cast<const HarvestCommandType*>(command->getCommandType());
|
||||
if(hct != NULL && unit->isBadHarvestPos(pos2) == true) {
|
||||
isBadHarvestPos = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(unit == NULL || isBadHarvestPos == true) {
|
||||
|
||||
//printf("[%s] Line: %d returning false\n",__FUNCTION__,__LINE__);
|
||||
unit->getFaction()->addAproxCanMoveSoonCached(size,field, pos1, pos2, false);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
unit->getFaction()->addAproxCanMoveSoonCached(size,field, pos1, pos2, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
string getMapFile() const { return mapFile; }
|
||||
|
||||
|
|
|
@ -399,6 +399,7 @@ void World::updateAllFactionUnits() {
|
|||
throw megaglest_runtime_error("faction == NULL");
|
||||
}
|
||||
faction->clearUnitsPathfinding();
|
||||
faction->clearAproxCanMoveSoonCached();
|
||||
}
|
||||
|
||||
// Signal the faction threads to do any pre-processing
|
||||
|
|
|
@ -172,7 +172,7 @@ public:
|
|||
return x*v.x+y*v.y;
|
||||
}
|
||||
|
||||
float dist(const Vec2<T> &v) const{
|
||||
inline float dist(const Vec2<T> &v) const{
|
||||
return Vec2<T>(v-*this).length();
|
||||
}
|
||||
|
||||
|
@ -392,7 +392,7 @@ public:
|
|||
return x*v.x + y*v.y + z*v.z;
|
||||
}
|
||||
|
||||
float dist(const Vec3<T> &v) const{
|
||||
inline float dist(const Vec3<T> &v) const{
|
||||
return Vec3<T>(v-*this).length();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue