- attempt to see if threaded pathfinding will work and if it improves performance
This commit is contained in:
parent
e65f588045
commit
07f56669b7
|
@ -45,12 +45,19 @@ const int PathFinder::pathFindBailoutRadius = 20;
|
||||||
|
|
||||||
|
|
||||||
PathFinder::PathFinder() {
|
PathFinder::PathFinder() {
|
||||||
nodePool.clear();
|
for(int i = 0; i < GameConstants::maxPlayers; ++i) {
|
||||||
|
factions.push_back(FactionState());
|
||||||
|
}
|
||||||
|
//nodePool.clear();
|
||||||
map=NULL;
|
map=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PathFinder::PathFinder(const Map *map) {
|
PathFinder::PathFinder(const Map *map) {
|
||||||
nodePool.clear();
|
for(int i = 0; i < GameConstants::maxPlayers; ++i) {
|
||||||
|
factions.push_back(FactionState());
|
||||||
|
}
|
||||||
|
|
||||||
|
//nodePool.clear();
|
||||||
|
|
||||||
map=NULL;
|
map=NULL;
|
||||||
init(map);
|
init(map);
|
||||||
|
@ -58,22 +65,35 @@ PathFinder::PathFinder(const Map *map) {
|
||||||
|
|
||||||
void PathFinder::init(const Map *map) {
|
void PathFinder::init(const Map *map) {
|
||||||
PathFinder::pathFindNodesMax = Config::getInstance().getInt("MaxPathfinderNodeCount",intToStr(PathFinder::pathFindNodesMax).c_str());
|
PathFinder::pathFindNodesMax = Config::getInstance().getInt("MaxPathfinderNodeCount",intToStr(PathFinder::pathFindNodesMax).c_str());
|
||||||
nodePool.resize(pathFindNodesMax);
|
|
||||||
useMaxNodeCount = PathFinder::pathFindNodesMax;
|
for(int i = 0; i < GameConstants::maxPlayers; ++i) {
|
||||||
|
factions[i].nodePool.resize(pathFindNodesMax);
|
||||||
|
factions[i].useMaxNodeCount = PathFinder::pathFindNodesMax;
|
||||||
|
}
|
||||||
this->map= map;
|
this->map= map;
|
||||||
}
|
}
|
||||||
|
|
||||||
PathFinder::~PathFinder(){
|
PathFinder::~PathFinder() {
|
||||||
nodePool.clear();
|
for(int i = 0; i < GameConstants::maxPlayers; ++i) {
|
||||||
|
factions[i].nodePool.clear();
|
||||||
|
}
|
||||||
map=NULL;
|
map=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStuck) {
|
void PathFinder::clearUnitPrecache(Unit *unit) {
|
||||||
|
factions[unit->getFactionIndex()].precachedTravelState[unit->getId()] = tsImpossible;
|
||||||
|
factions[unit->getFactionIndex()].precachedPath[unit->getId()].clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStuck, int frameIndex) {
|
||||||
//printf("PathFinder::findPath...\n");
|
//printf("PathFinder::findPath...\n");
|
||||||
|
|
||||||
if(map == NULL) {
|
if(map == NULL) {
|
||||||
throw runtime_error("map == NULL");
|
throw runtime_error("map == NULL");
|
||||||
}
|
}
|
||||||
|
if(frameIndex >= 0) {
|
||||||
|
clearUnitPrecache(unit);
|
||||||
|
}
|
||||||
|
|
||||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
|
||||||
char szBuf[4096]="";
|
char szBuf[4096]="";
|
||||||
|
@ -83,11 +103,11 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
|
||||||
}
|
}
|
||||||
|
|
||||||
//route cache
|
//route cache
|
||||||
UnitPathInterface *path= unit->getPath();
|
|
||||||
if(finalPos == unit->getPos()) {
|
if(finalPos == unit->getPos()) {
|
||||||
//if arrived
|
if(frameIndex < 0) {
|
||||||
unit->setCurrSkill(scStop);
|
//if arrived
|
||||||
|
unit->setCurrSkill(scStop);
|
||||||
|
}
|
||||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled == true) {
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugPathFinder).enabled == true) {
|
||||||
string commandDesc = "none";
|
string commandDesc = "none";
|
||||||
Command *command= unit->getCurrCommand();
|
Command *command= unit->getCurrCommand();
|
||||||
|
@ -102,36 +122,39 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
|
||||||
//unit->getFaction()->addCachedPath(finalPos,unit);
|
//unit->getFaction()->addCachedPath(finalPos,unit);
|
||||||
return tsArrived;
|
return tsArrived;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
if(path->isEmpty() == false) {
|
|
||||||
if(dynamic_cast<UnitPathBasic *>(path) != NULL) {
|
|
||||||
//route cache
|
|
||||||
UnitPathBasic *basicPath = dynamic_cast<UnitPathBasic *>(path);
|
|
||||||
Vec2i pos= basicPath->pop();
|
|
||||||
|
|
||||||
//if(map->canMove(unit, unit->getPos(), pos, &lookupCacheCanMove)) {
|
UnitPathInterface *path= unit->getPath();
|
||||||
if(map->canMove(unit, unit->getPos(), pos)) {
|
if(path->isEmpty() == false) {
|
||||||
|
if(dynamic_cast<UnitPathBasic *>(path) != NULL) {
|
||||||
|
//route cache
|
||||||
|
UnitPathBasic *basicPath = dynamic_cast<UnitPathBasic *>(path);
|
||||||
|
Vec2i pos= basicPath->pop(frameIndex < 0);
|
||||||
|
|
||||||
|
if(map->canMove(unit, unit->getPos(), pos)) {
|
||||||
|
if(frameIndex < 0) {
|
||||||
unit->setTargetPos(pos);
|
unit->setTargetPos(pos);
|
||||||
unit->addCurrentTargetPathTakenCell(finalPos,pos);
|
unit->addCurrentTargetPathTakenCell(finalPos,pos);
|
||||||
return tsMoving;
|
|
||||||
}
|
}
|
||||||
}
|
return tsMoving;
|
||||||
else if(dynamic_cast<UnitPath *>(path) != NULL) {
|
|
||||||
UnitPath *advPath = dynamic_cast<UnitPath *>(path);
|
|
||||||
//route cache
|
|
||||||
Vec2i pos= advPath->peek();
|
|
||||||
//if(map->canMove(unit, unit->getPos(), pos, &lookupCacheCanMove)) {
|
|
||||||
if(map->canMove(unit, unit->getPos(), pos)) {
|
|
||||||
advPath->pop();
|
|
||||||
unit->setTargetPos(pos);
|
|
||||||
return tsMoving;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw runtime_error("unsupported or missing path finder detected!");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(dynamic_cast<UnitPath *>(path) != NULL) {
|
||||||
|
UnitPath *advPath = dynamic_cast<UnitPath *>(path);
|
||||||
|
//route cache
|
||||||
|
Vec2i pos= advPath->peek();
|
||||||
|
if(map->canMove(unit, unit->getPos(), pos)) {
|
||||||
|
if(frameIndex < 0) {
|
||||||
|
advPath->pop();
|
||||||
|
unit->setTargetPos(pos);
|
||||||
|
}
|
||||||
|
return tsMoving;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw runtime_error("unsupported or missing path finder detected!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TravelState ts = tsImpossible;
|
TravelState ts = tsImpossible;
|
||||||
//std::vector<Vec2i> cachedPath = unit->getFaction()->findCachedPath(finalPos, unit);
|
//std::vector<Vec2i> cachedPath = unit->getFaction()->findCachedPath(finalPos, unit);
|
||||||
|
@ -144,10 +167,10 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
|
||||||
//}
|
//}
|
||||||
//else {
|
//else {
|
||||||
//route cache miss
|
//route cache miss
|
||||||
ts = aStar(unit, finalPos, false);
|
ts = aStar(unit, finalPos, false, frameIndex);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
if(ts == tsBlocked) {
|
//if(ts == tsBlocked) {
|
||||||
//std::vector<Vec2i> cachedPath = unit->getFaction()->findCachedPath(finalPos, unit);
|
//std::vector<Vec2i> cachedPath = unit->getFaction()->findCachedPath(finalPos, unit);
|
||||||
//if(cachedPath.size() > 0) {
|
//if(cachedPath.size() > 0) {
|
||||||
// path->clear();
|
// path->clear();
|
||||||
|
@ -158,16 +181,16 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
|
||||||
// ts = tsMoving;
|
// ts = tsMoving;
|
||||||
// unit->addCurrentTargetPathTakenCell(Vec2i(-1),Vec2i(-1));
|
// unit->addCurrentTargetPathTakenCell(Vec2i(-1),Vec2i(-1));
|
||||||
//}
|
//}
|
||||||
}
|
//}
|
||||||
|
|
||||||
//post actions
|
//post actions
|
||||||
switch(ts) {
|
switch(ts) {
|
||||||
case tsBlocked:
|
case tsBlocked:
|
||||||
case tsArrived:
|
case tsArrived:
|
||||||
|
|
||||||
if(ts == tsArrived) {
|
//if(ts == tsArrived) {
|
||||||
//unit->getFaction()->addCachedPath(finalPos,unit);
|
//unit->getFaction()->addCachedPath(finalPos,unit);
|
||||||
}
|
//}
|
||||||
|
|
||||||
// The unit is stuck (not only blocked but unable to go anywhere for a while)
|
// The unit is stuck (not only blocked but unable to go anywhere for a while)
|
||||||
// We will try to bail out of the immediate area
|
// We will try to bail out of the immediate area
|
||||||
|
@ -224,7 +247,7 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
|
||||||
|
|
||||||
if(useBailoutRadius == true) {
|
if(useBailoutRadius == true) {
|
||||||
//int tryRadius = random.randRange(-PathFinder::pathFindBailoutRadius, PathFinder::pathFindBailoutRadius);
|
//int tryRadius = random.randRange(-PathFinder::pathFindBailoutRadius, PathFinder::pathFindBailoutRadius);
|
||||||
int tryRadius = random.randRange(0,1);
|
int tryRadius = factions[unit->getFactionIndex()].random.randRange(0,1);
|
||||||
|
|
||||||
//printf("#4 BAILOUT test unitid [%d] useBailoutRadius [%d] tryRadius [%d]\n",unit->getId(),useBailoutRadius,tryRadius);
|
//printf("#4 BAILOUT test unitid [%d] useBailoutRadius [%d] tryRadius [%d]\n",unit->getId(),useBailoutRadius,tryRadius);
|
||||||
|
|
||||||
|
@ -243,7 +266,7 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
|
||||||
}
|
}
|
||||||
|
|
||||||
if(canUnitMove) {
|
if(canUnitMove) {
|
||||||
ts= aStar(unit, newFinalPos, true);
|
ts= aStar(unit, newFinalPos, true, frameIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -262,7 +285,7 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
|
||||||
}
|
}
|
||||||
|
|
||||||
if(canUnitMove) {
|
if(canUnitMove) {
|
||||||
ts= aStar(unit, newFinalPos, true);
|
ts= aStar(unit, newFinalPos, true, frameIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -271,35 +294,50 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
|
||||||
unit->setInBailOutAttempt(false);
|
unit->setInBailOutAttempt(false);
|
||||||
}
|
}
|
||||||
if(ts == tsArrived || ts == tsBlocked) {
|
if(ts == tsArrived || ts == tsBlocked) {
|
||||||
unit->setCurrSkill(scStop);
|
if(frameIndex < 0) {
|
||||||
|
unit->setCurrSkill(scStop);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case tsMoving:
|
case tsMoving:
|
||||||
{
|
{
|
||||||
if(dynamic_cast<UnitPathBasic *>(path) != NULL) {
|
if(dynamic_cast<UnitPathBasic *>(path) != NULL) {
|
||||||
UnitPathBasic *basicPath = dynamic_cast<UnitPathBasic *>(path);
|
UnitPathBasic *basicPath = dynamic_cast<UnitPathBasic *>(path);
|
||||||
Vec2i pos= basicPath->pop();
|
Vec2i pos;
|
||||||
|
if(frameIndex < 0) {
|
||||||
|
pos = basicPath->pop(frameIndex < 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pos = factions[unit->getFactionIndex()].precachedPath[unit->getId()][0];
|
||||||
|
}
|
||||||
|
|
||||||
//if(map->canMove(unit, unit->getPos(), pos, &lookupCacheCanMove)) {
|
//if(map->canMove(unit, unit->getPos(), pos, &lookupCacheCanMove)) {
|
||||||
if(map->canMove(unit, unit->getPos(), pos)) {
|
if(map->canMove(unit, unit->getPos(), pos)) {
|
||||||
unit->setTargetPos(pos);
|
if(frameIndex < 0) {
|
||||||
unit->addCurrentTargetPathTakenCell(finalPos,pos);
|
unit->setTargetPos(pos);
|
||||||
|
unit->addCurrentTargetPathTakenCell(finalPos,pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
unit->setCurrSkill(scStop);
|
if(frameIndex < 0) {
|
||||||
|
unit->setCurrSkill(scStop);
|
||||||
|
}
|
||||||
return tsBlocked;
|
return tsBlocked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(dynamic_cast<UnitPath *>(path) != NULL) {
|
else if(dynamic_cast<UnitPath *>(path) != NULL) {
|
||||||
UnitPath *advPath = dynamic_cast<UnitPath *>(path);
|
UnitPath *advPath = dynamic_cast<UnitPath *>(path);
|
||||||
Vec2i pos= advPath->peek();
|
Vec2i pos= advPath->peek();
|
||||||
//if(map->canMove(unit, unit->getPos(), pos, &lookupCacheCanMove)) {
|
|
||||||
if(map->canMove(unit, unit->getPos(), pos)) {
|
if(map->canMove(unit, unit->getPos(), pos)) {
|
||||||
advPath->pop();
|
if(frameIndex < 0) {
|
||||||
unit->setTargetPos(pos);
|
advPath->pop();
|
||||||
|
unit->setTargetPos(pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
unit->setCurrSkill(scStop);
|
if(frameIndex < 0) {
|
||||||
|
unit->setCurrSkill(scStop);
|
||||||
|
}
|
||||||
return tsBlocked;
|
return tsBlocked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -319,20 +357,20 @@ bool PathFinder::processNode(Unit *unit, Node *node,const Vec2i finalPos, int i,
|
||||||
bool result = false;
|
bool result = false;
|
||||||
Vec2i sucPos= node->pos + Vec2i(i, j);
|
Vec2i sucPos= node->pos + Vec2i(i, j);
|
||||||
bool canUnitMoveToCell = map->aproxCanMove(unit, node->pos, sucPos);
|
bool canUnitMoveToCell = map->aproxCanMove(unit, node->pos, sucPos);
|
||||||
if(openPos(sucPos) == false && canUnitMoveToCell == true) {
|
if(openPos(sucPos, factions[unit->getFactionIndex()]) == false && canUnitMoveToCell == true) {
|
||||||
//if node is not open and canMove then generate another node
|
//if node is not open and canMove then generate another node
|
||||||
Node *sucNode= newNode();
|
Node *sucNode= newNode(factions[unit->getFactionIndex()]);
|
||||||
if(sucNode != NULL) {
|
if(sucNode != NULL) {
|
||||||
sucNode->pos= sucPos;
|
sucNode->pos= sucPos;
|
||||||
sucNode->heuristic= heuristic(sucNode->pos, finalPos);
|
sucNode->heuristic= heuristic(sucNode->pos, finalPos);
|
||||||
sucNode->prev= node;
|
sucNode->prev= node;
|
||||||
sucNode->next= NULL;
|
sucNode->next= NULL;
|
||||||
sucNode->exploredCell= map->getSurfaceCell(Map::toSurfCoords(sucPos))->isExplored(unit->getTeam());
|
sucNode->exploredCell= map->getSurfaceCell(Map::toSurfCoords(sucPos))->isExplored(unit->getTeam());
|
||||||
if(openNodesList.find(sucNode->heuristic) == openNodesList.end()) {
|
if(factions[unit->getFactionIndex()].openNodesList.find(sucNode->heuristic) == factions[unit->getFactionIndex()].openNodesList.end()) {
|
||||||
openNodesList[sucNode->heuristic].clear();
|
factions[unit->getFactionIndex()].openNodesList[sucNode->heuristic].clear();
|
||||||
}
|
}
|
||||||
openNodesList[sucNode->heuristic].push_back(sucNode);
|
factions[unit->getFactionIndex()].openNodesList[sucNode->heuristic].push_back(sucNode);
|
||||||
openPosList[sucNode->pos] = true;
|
factions[unit->getFactionIndex()].openPosList[sucNode->pos] = true;
|
||||||
|
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
|
@ -344,7 +382,8 @@ bool PathFinder::processNode(Unit *unit, Node *node,const Vec2i finalPos, int i,
|
||||||
}
|
}
|
||||||
|
|
||||||
//route a unit using A* algorithm
|
//route a unit using A* algorithm
|
||||||
TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout) {
|
TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout,
|
||||||
|
int frameIndex) {
|
||||||
//printf("PathFinder::aStar...\n");
|
//printf("PathFinder::aStar...\n");
|
||||||
|
|
||||||
Chrono chrono;
|
Chrono chrono;
|
||||||
|
@ -354,18 +393,78 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
|
||||||
throw runtime_error("map == NULL");
|
throw runtime_error("map == NULL");
|
||||||
}
|
}
|
||||||
|
|
||||||
nodePoolCount= 0;
|
UnitPathInterface *path= unit->getPath();
|
||||||
openNodesList.clear();
|
|
||||||
openPosList.clear();
|
factions[unit->getFactionIndex()].nodePoolCount= 0;
|
||||||
closedNodesList.clear();
|
factions[unit->getFactionIndex()].openNodesList.clear();
|
||||||
|
factions[unit->getFactionIndex()].openPosList.clear();
|
||||||
|
factions[unit->getFactionIndex()].closedNodesList.clear();
|
||||||
|
|
||||||
TravelState ts = tsImpossible;
|
TravelState ts = tsImpossible;
|
||||||
|
|
||||||
|
if(frameIndex < 0) {
|
||||||
|
if(factions[unit->getFactionIndex()].precachedTravelState.find(unit->getId()) != factions[unit->getFactionIndex()].precachedTravelState.end()) {
|
||||||
|
if(factions[unit->getFactionIndex()].precachedTravelState[unit->getId()] == tsMoving) {
|
||||||
|
bool canMoveToCells = true;
|
||||||
|
|
||||||
|
Vec2i lastPos = unit->getPos();
|
||||||
|
for(int i=0; i < factions[unit->getFactionIndex()].precachedPath[unit->getId()].size(); i++) {
|
||||||
|
Vec2i nodePos = factions[unit->getFactionIndex()].precachedPath[unit->getId()][i];
|
||||||
|
if(map->isInside(nodePos) == false || map->isInsideSurface(map->toSurfCoords(nodePos)) == false) {
|
||||||
|
throw runtime_error("Pathfinder invalid node path position = " + nodePos.getString() + " i = " + intToStr(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i < pathFindRefresh) {
|
||||||
|
if(map->aproxCanMove(unit, lastPos, nodePos) == false) {
|
||||||
|
canMoveToCells = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lastPos = nodePos;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(canMoveToCells == true) {
|
||||||
|
path->clear();
|
||||||
|
UnitPathBasic *basicPathFinder = dynamic_cast<UnitPathBasic *>(path);
|
||||||
|
|
||||||
|
for(int i=0; i < factions[unit->getFactionIndex()].precachedPath[unit->getId()].size(); i++) {
|
||||||
|
Vec2i nodePos = factions[unit->getFactionIndex()].precachedPath[unit->getId()][i];
|
||||||
|
if(map->isInside(nodePos) == false || map->isInsideSurface(map->toSurfCoords(nodePos)) == false) {
|
||||||
|
throw runtime_error("Pathfinder invalid node path position = " + nodePos.getString() + " i = " + intToStr(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(i < pathFindRefresh) {
|
||||||
|
path->add(nodePos);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return factions[unit->getFactionIndex()].precachedTravelState[unit->getId()];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
clearUnitPrecache(unit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(factions[unit->getFactionIndex()].precachedTravelState[unit->getId()] == tsBlocked) {
|
||||||
|
path->incBlockCount();
|
||||||
|
return factions[unit->getFactionIndex()].precachedTravelState[unit->getId()];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
clearUnitPrecache(unit);
|
||||||
|
}
|
||||||
|
|
||||||
const Vec2i unitPos = unit->getPos();
|
const Vec2i unitPos = unit->getPos();
|
||||||
const Vec2i finalPos= computeNearestFreePos(unit, targetPos);
|
const Vec2i finalPos= computeNearestFreePos(unit, targetPos);
|
||||||
|
|
||||||
float dist= unitPos.dist(finalPos);
|
float dist= unitPos.dist(finalPos);
|
||||||
|
|
||||||
useMaxNodeCount = PathFinder::pathFindNodesMax;
|
factions[unit->getFactionIndex()].useMaxNodeCount = PathFinder::pathFindNodesMax;
|
||||||
// if(dist <= 10) {
|
// if(dist <= 10) {
|
||||||
// useMaxNodeCount = (int)dist * 20;
|
// useMaxNodeCount = (int)dist * 20;
|
||||||
// if(useMaxNodeCount <= 0) {
|
// if(useMaxNodeCount <= 0) {
|
||||||
|
@ -375,7 +474,6 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
|
||||||
|
|
||||||
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());
|
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());
|
||||||
|
|
||||||
UnitPathInterface *path= unit->getPath();
|
|
||||||
// Check the previous path find cache for the unit to see if its good to
|
// Check the previous path find cache for the unit to see if its good to
|
||||||
// use
|
// use
|
||||||
const bool showConsoleDebugInfo = Config::getInstance().getBool("EnablePathfinderDistanceOutput","false");
|
const bool showConsoleDebugInfo = Config::getInstance().getBool("EnablePathfinderDistanceOutput","false");
|
||||||
|
@ -422,7 +520,7 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
|
||||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
|
||||||
char szBuf[4096]="";
|
char szBuf[4096]="";
|
||||||
sprintf(szBuf,"[Setting new path for unit] openNodesList.size() [%lu] openPosList.size() [%lu] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d]",
|
sprintf(szBuf,"[Setting new path for unit] openNodesList.size() [%lu] openPosList.size() [%lu] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d]",
|
||||||
openNodesList.size(),openPosList.size(),finalPos.getString().c_str(),targetPos.getString().c_str(),inBailout,ts);
|
factions[unit->getFactionIndex()].openNodesList.size(),factions[unit->getFactionIndex()].openPosList.size(),finalPos.getString().c_str(),targetPos.getString().c_str(),inBailout,ts);
|
||||||
unit->logSynchData(__FILE__,__LINE__,szBuf);
|
unit->logSynchData(__FILE__,__LINE__,szBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,7 +568,7 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
|
||||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
|
||||||
char szBuf[4096]="";
|
char szBuf[4096]="";
|
||||||
sprintf(szBuf,"[Setting new path for unit] openNodesList.size() [%lu] openPosList.size() [%lu] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d]",
|
sprintf(szBuf,"[Setting new path for unit] openNodesList.size() [%lu] openPosList.size() [%lu] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d]",
|
||||||
openNodesList.size(),openPosList.size(),finalPos.getString().c_str(),targetPos.getString().c_str(),inBailout,ts);
|
factions[unit->getFactionIndex()].openNodesList.size(),factions[unit->getFactionIndex()].openPosList.size(),finalPos.getString().c_str(),targetPos.getString().c_str(),inBailout,ts);
|
||||||
unit->logSynchData(__FILE__,__LINE__,szBuf);
|
unit->logSynchData(__FILE__,__LINE__,szBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -506,7 +604,7 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
|
||||||
//path find algorithm
|
//path find algorithm
|
||||||
|
|
||||||
//a) push starting pos into openNodes
|
//a) push starting pos into openNodes
|
||||||
Node *firstNode= newNode();
|
Node *firstNode= newNode(factions[unit->getFactionIndex()]);
|
||||||
assert(firstNode != NULL);
|
assert(firstNode != NULL);
|
||||||
if(firstNode == NULL) {
|
if(firstNode == NULL) {
|
||||||
throw runtime_error("firstNode == NULL");
|
throw runtime_error("firstNode == NULL");
|
||||||
|
@ -517,11 +615,11 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
|
||||||
firstNode->pos= unitPos;
|
firstNode->pos= unitPos;
|
||||||
firstNode->heuristic= heuristic(unitPos, finalPos);
|
firstNode->heuristic= heuristic(unitPos, finalPos);
|
||||||
firstNode->exploredCell= true;
|
firstNode->exploredCell= true;
|
||||||
if(openNodesList.find(firstNode->heuristic) == openNodesList.end()) {
|
if(factions[unit->getFactionIndex()].openNodesList.find(firstNode->heuristic) == factions[unit->getFactionIndex()].openNodesList.end()) {
|
||||||
openNodesList[firstNode->heuristic].clear();
|
factions[unit->getFactionIndex()].openNodesList[firstNode->heuristic].clear();
|
||||||
}
|
}
|
||||||
openNodesList[firstNode->heuristic].push_back(firstNode);
|
factions[unit->getFactionIndex()].openNodesList[firstNode->heuristic].push_back(firstNode);
|
||||||
openPosList[firstNode->pos] = true;
|
factions[unit->getFactionIndex()].openPosList[firstNode->pos] = true;
|
||||||
|
|
||||||
//b) loop
|
//b) loop
|
||||||
bool pathFound = true;
|
bool pathFound = true;
|
||||||
|
@ -592,14 +690,14 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
|
||||||
whileLoopCount++;
|
whileLoopCount++;
|
||||||
|
|
||||||
//b1) is open nodes is empty => failed to find the path
|
//b1) is open nodes is empty => failed to find the path
|
||||||
if(openNodesList.empty() == true) {
|
if(factions[unit->getFactionIndex()].openNodesList.empty() == true) {
|
||||||
pathFound= false;
|
pathFound= false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//b2) get the minimum heuristic node
|
//b2) get the minimum heuristic node
|
||||||
//Nodes::iterator it = minHeuristic();
|
//Nodes::iterator it = minHeuristic();
|
||||||
node = minHeuristicFastLookup();
|
node = minHeuristicFastLookup(factions[unit->getFactionIndex()]);
|
||||||
|
|
||||||
//b3) if minHeuristic is the finalNode, or the path is no more explored => path was found
|
//b3) if minHeuristic is the finalNode, or the path is no more explored => path was found
|
||||||
if(node->pos == finalPos || node->exploredCell == false) {
|
if(node->pos == finalPos || node->exploredCell == false) {
|
||||||
|
@ -609,16 +707,16 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
|
||||||
|
|
||||||
//b4) move this node from closedNodes to openNodes
|
//b4) move this node from closedNodes to openNodes
|
||||||
//add all succesors that are not in closedNodes or openNodes to openNodes
|
//add all succesors that are not in closedNodes or openNodes to openNodes
|
||||||
if(closedNodesList.find(node->heuristic) == closedNodesList.end()) {
|
if(factions[unit->getFactionIndex()].closedNodesList.find(node->heuristic) == factions[unit->getFactionIndex()].closedNodesList.end()) {
|
||||||
closedNodesList[node->heuristic].clear();
|
factions[unit->getFactionIndex()].closedNodesList[node->heuristic].clear();
|
||||||
}
|
}
|
||||||
closedNodesList[node->heuristic].push_back(node);
|
factions[unit->getFactionIndex()].closedNodesList[node->heuristic].push_back(node);
|
||||||
openPosList[node->pos] = true;
|
factions[unit->getFactionIndex()].openPosList[node->pos] = true;
|
||||||
|
|
||||||
int failureCount = 0;
|
int failureCount = 0;
|
||||||
int cellCount = 0;
|
int cellCount = 0;
|
||||||
|
|
||||||
int tryDirection = random.randRange(0,3);
|
int tryDirection = factions[unit->getFactionIndex()].random.randRange(0,3);
|
||||||
if(tryDirection == 3) {
|
if(tryDirection == 3) {
|
||||||
for(int i = 1; i >= -1 && nodeLimitReached == false; --i) {
|
for(int i = 1; i >= -1 && nodeLimitReached == false; --i) {
|
||||||
for(int j = -1; j <= 1 && nodeLimitReached == false; ++j) {
|
for(int j = -1; j <= 1 && nodeLimitReached == false; ++j) {
|
||||||
|
@ -673,19 +771,19 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
|
||||||
}
|
}
|
||||||
} //while
|
} //while
|
||||||
|
|
||||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled == true && chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld nodeLimitReached = %d whileLoopCount = %d nodePoolCount = %d\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),nodeLimitReached,whileLoopCount,nodePoolCount);
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled == true && chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld nodeLimitReached = %d whileLoopCount = %d nodePoolCount = %d\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis(),nodeLimitReached,whileLoopCount,factions[unit->getFactionIndex()].nodePoolCount);
|
||||||
if(showConsoleDebugInfo && chrono.getMillis() > 2) {
|
if(showConsoleDebugInfo && chrono.getMillis() > 2) {
|
||||||
printf("Distance for unit [%d - %s] from [%s] to [%s] is %.2f took msecs: %lld nodeLimitReached = %d whileLoopCount = %d nodePoolCount = %d\n",unit->getId(),unit->getFullName().c_str(), unitPos.getString().c_str(), finalPos.getString().c_str(), dist,(long long int)chrono.getMillis(),nodeLimitReached,whileLoopCount,nodePoolCount);
|
printf("Distance for unit [%d - %s] from [%s] to [%s] is %.2f took msecs: %lld nodeLimitReached = %d whileLoopCount = %d nodePoolCount = %d\n",unit->getId(),unit->getFullName().c_str(), unitPos.getString().c_str(), finalPos.getString().c_str(), dist,(long long int)chrono.getMillis(),nodeLimitReached,whileLoopCount,factions[unit->getFactionIndex()].nodePoolCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
Node *lastNode= node;
|
Node *lastNode= node;
|
||||||
|
|
||||||
//if consumed all nodes find best node (to avoid strange behaviour)
|
//if consumed all nodes find best node (to avoid strange behaviour)
|
||||||
if(nodeLimitReached == true) {
|
if(nodeLimitReached == true) {
|
||||||
if(closedNodesList.size() > 0) {
|
if(factions[unit->getFactionIndex()].closedNodesList.size() > 0) {
|
||||||
float bestHeuristic = closedNodesList.begin()->first;
|
float bestHeuristic = factions[unit->getFactionIndex()].closedNodesList.begin()->first;
|
||||||
if(bestHeuristic < lastNode->heuristic) {
|
if(bestHeuristic < lastNode->heuristic) {
|
||||||
lastNode= closedNodesList.begin()->second[0];
|
lastNode= factions[unit->getFactionIndex()].closedNodesList.begin()->second[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -712,12 +810,14 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
|
||||||
}
|
}
|
||||||
|
|
||||||
ts= tsBlocked;
|
ts= tsBlocked;
|
||||||
path->incBlockCount();
|
if(frameIndex < 0) {
|
||||||
|
path->incBlockCount();
|
||||||
|
}
|
||||||
|
|
||||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
|
||||||
char szBuf[4096]="";
|
char szBuf[4096]="";
|
||||||
sprintf(szBuf,"[path for unit BLOCKED] openNodesList.size() [%lu] openPosList.size() [%lu] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d]",
|
sprintf(szBuf,"[path for unit BLOCKED] openNodesList.size() [%lu] openPosList.size() [%lu] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d]",
|
||||||
openNodesList.size(),openPosList.size(),finalPos.getString().c_str(),targetPos.getString().c_str(),inBailout,ts);
|
factions[unit->getFactionIndex()].openNodesList.size(),factions[unit->getFactionIndex()].openPosList.size(),finalPos.getString().c_str(),targetPos.getString().c_str(),inBailout,ts);
|
||||||
unit->logSynchData(__FILE__,__LINE__,szBuf);
|
unit->logSynchData(__FILE__,__LINE__,szBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -737,7 +837,10 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
|
||||||
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());
|
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());
|
||||||
|
|
||||||
//store path
|
//store path
|
||||||
path->clear();
|
if(frameIndex < 0) {
|
||||||
|
path->clear();
|
||||||
|
}
|
||||||
|
|
||||||
UnitPathBasic *basicPathFinder = dynamic_cast<UnitPathBasic *>(path);
|
UnitPathBasic *basicPathFinder = dynamic_cast<UnitPathBasic *>(path);
|
||||||
|
|
||||||
currNode= firstNode;
|
currNode= firstNode;
|
||||||
|
@ -747,15 +850,20 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
|
||||||
throw runtime_error("Pathfinder invalid node path position = " + nodePos.getString() + " i = " + intToStr(i));
|
throw runtime_error("Pathfinder invalid node path position = " + nodePos.getString() + " i = " + intToStr(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(i < pathFindRefresh) {
|
if(frameIndex >= 0) {
|
||||||
path->add(nodePos);
|
factions[unit->getFactionIndex()].precachedPath[unit->getId()].push_back(nodePos);
|
||||||
}
|
|
||||||
else if(tryLastPathCache == false) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if(i < pathFindRefresh) {
|
||||||
|
path->add(nodePos);
|
||||||
|
}
|
||||||
|
else if(tryLastPathCache == false) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if(tryLastPathCache == true && basicPathFinder) {
|
if(tryLastPathCache == true && basicPathFinder) {
|
||||||
basicPathFinder->addToLastPathCache(nodePos);
|
basicPathFinder->addToLastPathCache(nodePos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -764,7 +872,7 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
|
||||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) {
|
||||||
char szBuf[4096]="";
|
char szBuf[4096]="";
|
||||||
sprintf(szBuf,"[Setting new path for unit] openNodesList.size() [%lu] openPosList.size() [%lu] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d]",
|
sprintf(szBuf,"[Setting new path for unit] openNodesList.size() [%lu] openPosList.size() [%lu] finalPos [%s] targetPos [%s] inBailout [%d] ts [%d]",
|
||||||
openNodesList.size(),openPosList.size(),finalPos.getString().c_str(),targetPos.getString().c_str(),inBailout,ts);
|
factions[unit->getFactionIndex()].openNodesList.size(),factions[unit->getFactionIndex()].openPosList.size(),finalPos.getString().c_str(),targetPos.getString().c_str(),inBailout,ts);
|
||||||
unit->logSynchData(__FILE__,__LINE__,szBuf);
|
unit->logSynchData(__FILE__,__LINE__,szBuf);
|
||||||
|
|
||||||
string pathToTake = "";
|
string pathToTake = "";
|
||||||
|
@ -794,20 +902,27 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
|
||||||
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());
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
openNodesList.clear();
|
factions[unit->getFactionIndex()].openNodesList.clear();
|
||||||
openPosList.clear();
|
factions[unit->getFactionIndex()].openPosList.clear();
|
||||||
closedNodesList.clear();
|
factions[unit->getFactionIndex()].closedNodesList.clear();
|
||||||
|
|
||||||
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled == true && chrono.getMillis() > 4) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled == true && chrono.getMillis() > 4) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||||
|
|
||||||
|
if(frameIndex >= 0) {
|
||||||
|
factions[unit->getFactionIndex()].precachedTravelState[unit->getId()] = ts;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(SystemFlags::VERBOSE_MODE_ENABLED && chrono.getMillis() >= 5) printf("In [%s::%s Line: %d] astar took [%lld] msecs, ts = %d.\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis(),ts);
|
||||||
|
}
|
||||||
return ts;
|
return ts;
|
||||||
}
|
}
|
||||||
|
|
||||||
PathFinder::Node *PathFinder::newNode() {
|
PathFinder::Node *PathFinder::newNode(FactionState &faction) {
|
||||||
if(nodePoolCount < nodePool.size() && nodePoolCount < useMaxNodeCount) {
|
if( faction.nodePoolCount < faction.nodePool.size() &&
|
||||||
Node *node= &nodePool[nodePoolCount];
|
faction.nodePoolCount < faction.useMaxNodeCount) {
|
||||||
|
Node *node= &(faction.nodePool[faction.nodePoolCount]);
|
||||||
node->clear();
|
node->clear();
|
||||||
nodePoolCount++;
|
faction.nodePoolCount++;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -864,22 +979,22 @@ float PathFinder::heuristic(const Vec2i &pos, const Vec2i &finalPos) {
|
||||||
return pos.dist(finalPos);
|
return pos.dist(finalPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
PathFinder::Node * PathFinder::minHeuristicFastLookup() {
|
PathFinder::Node * PathFinder::minHeuristicFastLookup(FactionState &faction) {
|
||||||
assert(openNodesList.empty() == false);
|
assert(faction.openNodesList.empty() == false);
|
||||||
if(openNodesList.empty() == true) {
|
if(faction.openNodesList.empty() == true) {
|
||||||
throw runtime_error("openNodesList.empty() == true");
|
throw runtime_error("openNodesList.empty() == true");
|
||||||
}
|
}
|
||||||
|
|
||||||
Node *result = openNodesList.begin()->second[0];
|
Node *result = faction.openNodesList.begin()->second[0];
|
||||||
openNodesList.begin()->second.erase(openNodesList.begin()->second.begin());
|
faction.openNodesList.begin()->second.erase(faction.openNodesList.begin()->second.begin());
|
||||||
if(openNodesList.begin()->second.size() == 0) {
|
if(faction.openNodesList.begin()->second.size() == 0) {
|
||||||
openNodesList.erase(openNodesList.begin());
|
faction.openNodesList.erase(faction.openNodesList.begin());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PathFinder::openPos(const Vec2i &sucPos) {
|
bool PathFinder::openPos(const Vec2i &sucPos, FactionState &faction) {
|
||||||
if(openPosList.find(sucPos) == openPosList.end()) {
|
if(faction.openPosList.find(sucPos) == faction.openPosList.end()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -57,38 +57,59 @@ public:
|
||||||
};
|
};
|
||||||
typedef vector<Node*> Nodes;
|
typedef vector<Node*> Nodes;
|
||||||
|
|
||||||
|
class FactionState {
|
||||||
|
public:
|
||||||
|
FactionState() {
|
||||||
|
openPosList.clear();
|
||||||
|
openNodesList.clear();
|
||||||
|
closedNodesList.clear();
|
||||||
|
nodePool.clear();
|
||||||
|
nodePoolCount = 0;
|
||||||
|
useMaxNodeCount = 0;
|
||||||
|
precachedTravelState.clear();
|
||||||
|
precachedPath.clear();
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
typedef vector<FactionState> FactionStateList;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const int maxFreeSearchRadius;
|
static const int maxFreeSearchRadius;
|
||||||
static int pathFindNodesMax;
|
|
||||||
static const int pathFindRefresh;
|
static const int pathFindRefresh;
|
||||||
static const int pathFindBailoutRadius;
|
static const int pathFindBailoutRadius;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<Vec2i, bool> openPosList;
|
|
||||||
std::map<float, Nodes> openNodesList;
|
|
||||||
std::map<float, Nodes> closedNodesList;
|
|
||||||
|
|
||||||
std::vector<Node> nodePool;
|
static int pathFindNodesMax;
|
||||||
int nodePoolCount;
|
|
||||||
|
FactionStateList factions;
|
||||||
const Map *map;
|
const Map *map;
|
||||||
RandomGen random;
|
|
||||||
int useMaxNodeCount;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PathFinder();
|
PathFinder();
|
||||||
PathFinder(const Map *map);
|
PathFinder(const Map *map);
|
||||||
~PathFinder();
|
~PathFinder();
|
||||||
void init(const Map *map);
|
void init(const Map *map);
|
||||||
TravelState findPath(Unit *unit, const Vec2i &finalPos, bool *wasStuck=NULL);
|
TravelState findPath(Unit *unit, const Vec2i &finalPos, bool *wasStuck=NULL,int frameIndex=-1);
|
||||||
|
void clearUnitPrecache(Unit *unit);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TravelState aStar(Unit *unit, const Vec2i &finalPos, bool inBailout);
|
TravelState aStar(Unit *unit, const Vec2i &finalPos, bool inBailout, int frameIndex);
|
||||||
Node *newNode();
|
Node *newNode(FactionState &faction);
|
||||||
Vec2i computeNearestFreePos(const Unit *unit, const Vec2i &targetPos);
|
Vec2i computeNearestFreePos(const Unit *unit, const Vec2i &targetPos);
|
||||||
float heuristic(const Vec2i &pos, const Vec2i &finalPos);
|
float heuristic(const Vec2i &pos, const Vec2i &finalPos);
|
||||||
bool openPos(const Vec2i &sucPos);
|
bool openPos(const Vec2i &sucPos,FactionState &faction);
|
||||||
|
|
||||||
Node * minHeuristicFastLookup();
|
Node * minHeuristicFastLookup(FactionState &faction);
|
||||||
|
|
||||||
bool processNode(Unit *unit, Node *node,const Vec2i finalPos, int i, int j, bool &nodeLimitReached);
|
bool processNode(Unit *unit, Node *node,const Vec2i finalPos, int i, int j, bool &nodeLimitReached);
|
||||||
void processNearestFreePos(const Vec2i &finalPos, int i, int j, int size, Field field, int teamIndex,Vec2i unitPos, Vec2i &nearestPos, float &nearestDist);
|
void processNearestFreePos(const Vec2i &finalPos, int i, int j, int size, Field field, int teamIndex,Vec2i unitPos, Vec2i &nearestPos, float &nearestDist);
|
||||||
|
|
|
@ -26,7 +26,164 @@
|
||||||
|
|
||||||
using namespace Shared::Util;
|
using namespace Shared::Util;
|
||||||
|
|
||||||
namespace Glest{ namespace Game{
|
namespace Glest { namespace Game {
|
||||||
|
|
||||||
|
// =====================================================
|
||||||
|
// class FactionThread
|
||||||
|
// =====================================================
|
||||||
|
|
||||||
|
FactionThread::FactionThread(Faction *faction) : BaseThread() {
|
||||||
|
this->faction = faction;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FactionThread::setQuitStatus(bool value) {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d value = %d\n",__FILE__,__FUNCTION__,__LINE__,value);
|
||||||
|
|
||||||
|
BaseThread::setQuitStatus(value);
|
||||||
|
if(value == true) {
|
||||||
|
signalPathfinder(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FactionThread::signalPathfinder(int frameIndex) {
|
||||||
|
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] event = %p\n",__FILE__,__FUNCTION__,__LINE__,event);
|
||||||
|
|
||||||
|
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] frameIndex = %d this = %p\n",__FILE__,__FUNCTION__,__LINE__,frameIndex, this);
|
||||||
|
|
||||||
|
if(frameIndex >= 0) {
|
||||||
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
||||||
|
MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId);
|
||||||
|
this->frameIndex.first = frameIndex;
|
||||||
|
this->frameIndex.second = false;
|
||||||
|
safeMutex.ReleaseLock();
|
||||||
|
}
|
||||||
|
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
semTaskSignalled.signal();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FactionThread::setTaskCompleted(int frameIndex) {
|
||||||
|
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] frameIndex = %d this = %p\n",__FILE__,__FUNCTION__,__LINE__,frameIndex, this);
|
||||||
|
|
||||||
|
if(frameIndex >= 0) {
|
||||||
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
||||||
|
MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId);
|
||||||
|
if(this->frameIndex.first == frameIndex) {
|
||||||
|
this->frameIndex.second = true;
|
||||||
|
}
|
||||||
|
safeMutex.ReleaseLock();
|
||||||
|
}
|
||||||
|
|
||||||
|
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FactionThread::canShutdown(bool deleteSelfIfShutdownDelayed) {
|
||||||
|
bool ret = (getExecutingTask() == false);
|
||||||
|
if(ret == false && deleteSelfIfShutdownDelayed == true) {
|
||||||
|
setDeleteSelfOnExecutionDone(deleteSelfIfShutdownDelayed);
|
||||||
|
signalQuit();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FactionThread::isSignalPathfinderCompleted(int frameIndex) {
|
||||||
|
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] slotIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex);
|
||||||
|
if(getRunningStatus() == false) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
||||||
|
MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId);
|
||||||
|
//bool result = (event != NULL ? event->eventCompleted : true);
|
||||||
|
bool result = (this->frameIndex.first == frameIndex && this->frameIndex.second == true);
|
||||||
|
|
||||||
|
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] worker thread this = %p, this->frameIndex.first = %d, this->frameIndex.second = %d\n",__FILE__,__FUNCTION__,__LINE__,this,this->frameIndex.first,this->frameIndex.second);
|
||||||
|
|
||||||
|
safeMutex.ReleaseLock();
|
||||||
|
//if(result == false) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] slotIndex = %d, result = %d\n",__FILE__,__FUNCTION__,__LINE__,slotIndex,result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FactionThread::execute() {
|
||||||
|
RunningStatusSafeWrapper runningStatus(this);
|
||||||
|
try {
|
||||||
|
//setRunningStatus(true);
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] ****************** STARTING worker thread this = %p\n",__FILE__,__FUNCTION__,__LINE__,this);
|
||||||
|
|
||||||
|
unsigned int idx = 0;
|
||||||
|
for(;this->faction != NULL;) {
|
||||||
|
if(getQuitStatus() == true) {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
semTaskSignalled.waitTillSignalled();
|
||||||
|
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
if(getQuitStatus() == true) {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
||||||
|
MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId);
|
||||||
|
bool executeTask = (frameIndex.first >= 0);
|
||||||
|
|
||||||
|
//if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] frameIndex = %d this = %p executeTask = %d\n",__FILE__,__FUNCTION__,__LINE__,frameIndex.first, this, executeTask);
|
||||||
|
|
||||||
|
safeMutex.ReleaseLock();
|
||||||
|
|
||||||
|
if(executeTask == true) {
|
||||||
|
ExecutingTaskSafeWrapper safeExecutingTaskMutex(this);
|
||||||
|
//this->slotInterface->slotUpdateTask(&eventCopy);
|
||||||
|
|
||||||
|
World *world = faction->getWorld();
|
||||||
|
int unitCount = faction->getUnitCount();
|
||||||
|
for(int j = 0; j < unitCount; ++j) {
|
||||||
|
Unit *unit = faction->getUnit(j);
|
||||||
|
if(unit == NULL) {
|
||||||
|
throw runtime_error("unit == NULL");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool update = unit->needToUpdate();
|
||||||
|
if(update == true) {
|
||||||
|
world->getUnitUpdater()->updateUnitCommand(unit,frameIndex.first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setTaskCompleted(frameIndex.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
if(getQuitStatus() == true) {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] ****************** ENDING worker thread this = %p\n",__FILE__,__FUNCTION__,__LINE__,this);
|
||||||
|
}
|
||||||
|
catch(const exception &ex) {
|
||||||
|
//setRunningStatus(false);
|
||||||
|
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] Error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
throw runtime_error(ex.what());
|
||||||
|
}
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
//setRunningStatus(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// =====================================================
|
// =====================================================
|
||||||
// class Faction
|
// class Faction
|
||||||
|
@ -37,6 +194,7 @@ Faction::Faction() {
|
||||||
//lastResourceTargettListPurge = 0;
|
//lastResourceTargettListPurge = 0;
|
||||||
cachingDisabled=false;
|
cachingDisabled=false;
|
||||||
factionDisconnectHandled=false;
|
factionDisconnectHandled=false;
|
||||||
|
workerThread = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Faction::~Faction() {
|
Faction::~Faction() {
|
||||||
|
@ -50,11 +208,33 @@ Faction::~Faction() {
|
||||||
//texture->end();
|
//texture->end();
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
if(workerThread != NULL) {
|
||||||
|
workerThread->signalQuit();
|
||||||
|
if(workerThread->shutdownAndWait() == true) {
|
||||||
|
delete workerThread;
|
||||||
|
}
|
||||||
|
workerThread = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
//delete texture;
|
//delete texture;
|
||||||
texture = NULL;
|
texture = NULL;
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Faction::signalWorkerThread(int frameIndex) {
|
||||||
|
if(workerThread != NULL) {
|
||||||
|
workerThread->signalPathfinder(frameIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Faction::isWorkerThreadSignalCompleted(int frameIndex) {
|
||||||
|
if(workerThread != NULL) {
|
||||||
|
return workerThread->isSignalPathfinderCompleted(frameIndex);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Faction::init(
|
void Faction::init(
|
||||||
FactionType *factionType, ControlType control, TechTree *techTree, Game *game,
|
FactionType *factionType, ControlType control, TechTree *techTree, Game *game,
|
||||||
int factionIndex, int teamIndex, int startLocationIndex, bool thisFaction, bool giveResources)
|
int factionIndex, int teamIndex, int startLocationIndex, bool thisFaction, bool giveResources)
|
||||||
|
@ -84,11 +264,33 @@ void Faction::init(
|
||||||
string data_path = getGameReadWritePath(GameConstants::path_data_CacheLookupKey);
|
string data_path = getGameReadWritePath(GameConstants::path_data_CacheLookupKey);
|
||||||
texture->load(data_path + "data/core/faction_textures/faction"+intToStr(startLocationIndex)+".tga");
|
texture->load(data_path + "data/core/faction_textures/faction"+intToStr(startLocationIndex)+".tga");
|
||||||
|
|
||||||
|
if(Config::getInstance().getBool("EnableFactionWorkerThreads","true") == true) {
|
||||||
|
if(workerThread != NULL) {
|
||||||
|
workerThread->signalQuit();
|
||||||
|
if(workerThread->shutdownAndWait() == true) {
|
||||||
|
delete workerThread;
|
||||||
|
}
|
||||||
|
workerThread = NULL;
|
||||||
|
}
|
||||||
|
this->workerThread = new FactionThread(this);
|
||||||
|
this->workerThread->setUniqueID(__FILE__);
|
||||||
|
this->workerThread->start();
|
||||||
|
}
|
||||||
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Faction::end(){
|
void Faction::end() {
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
if(workerThread != NULL) {
|
||||||
|
workerThread->signalQuit();
|
||||||
|
if(workerThread->shutdownAndWait() == true) {
|
||||||
|
delete workerThread;
|
||||||
|
}
|
||||||
|
workerThread = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
deleteValues(units.begin(), units.end());
|
deleteValues(units.begin(), units.end());
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,12 +20,14 @@
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include "game_constants.h"
|
#include "game_constants.h"
|
||||||
#include "command_type.h"
|
#include "command_type.h"
|
||||||
|
#include "base_thread.h"
|
||||||
#include "leak_dumper.h"
|
#include "leak_dumper.h"
|
||||||
|
|
||||||
using std::map;
|
using std::map;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
|
|
||||||
using Shared::Graphics::Texture2D;
|
using Shared::Graphics::Texture2D;
|
||||||
|
using namespace Shared::PlatformCommon;
|
||||||
|
|
||||||
namespace Glest{ namespace Game{
|
namespace Glest{ namespace Game{
|
||||||
|
|
||||||
|
@ -39,6 +41,7 @@ class UnitType;
|
||||||
class Game;
|
class Game;
|
||||||
class ScriptManager;
|
class ScriptManager;
|
||||||
class World;
|
class World;
|
||||||
|
class Faction;
|
||||||
|
|
||||||
// =====================================================
|
// =====================================================
|
||||||
// class Faction
|
// class Faction
|
||||||
|
@ -54,6 +57,25 @@ public:
|
||||||
vector<std::pair<vector<Vec2i>, int> > pathQueue;
|
vector<std::pair<vector<Vec2i>, int> > pathQueue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FactionThread : public BaseThread {
|
||||||
|
protected:
|
||||||
|
|
||||||
|
Faction *faction;
|
||||||
|
Semaphore semTaskSignalled;
|
||||||
|
Mutex triggerIdMutex;
|
||||||
|
std::pair<int,bool> frameIndex;
|
||||||
|
|
||||||
|
virtual void setQuitStatus(bool value);
|
||||||
|
virtual void setTaskCompleted(int frameIndex);
|
||||||
|
virtual bool canShutdown(bool deleteSelfIfShutdownDelayed=false);
|
||||||
|
|
||||||
|
public:
|
||||||
|
FactionThread(Faction *faction);
|
||||||
|
virtual void execute();
|
||||||
|
void signalPathfinder(int frameIndex);
|
||||||
|
bool isSignalPathfinderCompleted(int frameIndex);
|
||||||
|
};
|
||||||
|
|
||||||
class Faction {
|
class Faction {
|
||||||
private:
|
private:
|
||||||
typedef vector<Resource> Resources;
|
typedef vector<Resource> Resources;
|
||||||
|
@ -98,6 +120,8 @@ private:
|
||||||
// update of the faction
|
// update of the faction
|
||||||
//std::map<int,std::map<Field, std::map<Vec2i,std::map<Vec2i, > > > localCacheForUnitCellMovement;
|
//std::map<int,std::map<Field, std::map<Vec2i,std::map<Vec2i, > > > localCacheForUnitCellMovement;
|
||||||
|
|
||||||
|
FactionThread *workerThread;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Faction();
|
Faction();
|
||||||
~Faction();
|
~Faction();
|
||||||
|
@ -186,7 +210,11 @@ public:
|
||||||
|
|
||||||
void deletePixels();
|
void deletePixels();
|
||||||
|
|
||||||
|
World * getWorld() { return world; }
|
||||||
int getFrameCount();
|
int getFrameCount();
|
||||||
|
void signalWorkerThread(int frameIndex);
|
||||||
|
bool isWorkerThreadSignalCompleted(int frameIndex);
|
||||||
|
|
||||||
std::string toString() const;
|
std::string toString() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -101,12 +101,14 @@ void UnitPathBasic::addToLastPathCache(const Vec2i &path) {
|
||||||
lastPathCacheQueue.push_back(path);
|
lastPathCacheQueue.push_back(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec2i UnitPathBasic::pop() {
|
Vec2i UnitPathBasic::pop(bool removeFrontPos) {
|
||||||
if(pathQueue.size() <= 0) {
|
if(pathQueue.size() <= 0) {
|
||||||
throw runtime_error("pathQueue.size() = " + intToStr(pathQueue.size()));
|
throw runtime_error("pathQueue.size() = " + intToStr(pathQueue.size()));
|
||||||
}
|
}
|
||||||
Vec2i p= pathQueue.front();
|
Vec2i p= pathQueue.front();
|
||||||
pathQueue.erase(pathQueue.begin());
|
if(removeFrontPos == true) {
|
||||||
|
pathQueue.erase(pathQueue.begin());
|
||||||
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
std::string UnitPathBasic::toString() const {
|
std::string UnitPathBasic::toString() const {
|
||||||
|
@ -1105,6 +1107,60 @@ const CommandType *Unit::computeCommandType(const Vec2i &pos, const Unit *target
|
||||||
return commandType;
|
return commandType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Unit::needToUpdate() {
|
||||||
|
assert(progress <= 1.f);
|
||||||
|
|
||||||
|
if(currSkill == NULL) {
|
||||||
|
char szBuf[4096]="";
|
||||||
|
sprintf(szBuf,"In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->toString().c_str());
|
||||||
|
throw runtime_error(szBuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
//speed
|
||||||
|
int speed = currSkill->getTotalSpeed(&totalUpgrade);
|
||||||
|
|
||||||
|
//speed modifier
|
||||||
|
float diagonalFactor= 1.f;
|
||||||
|
float heightFactor= 1.f;
|
||||||
|
if(currSkill->getClass() == scMove) {
|
||||||
|
//if moving in diagonal move slower
|
||||||
|
Vec2i dest= pos-lastPos;
|
||||||
|
if(abs(dest.x) + abs(dest.y) == 2) {
|
||||||
|
diagonalFactor= 0.71f;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if movig to an higher cell move slower else move faster
|
||||||
|
float heightDiff= map->getCell(pos)->getHeight() - map->getCell(targetPos)->getHeight();
|
||||||
|
heightFactor= clamp(1.f + heightDiff / 5.f, 0.2f, 5.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
//update progresses
|
||||||
|
float newProgress = progress;
|
||||||
|
const Game *game = Renderer::getInstance().getGame();
|
||||||
|
newProgress += (speed * diagonalFactor * heightFactor) / (speedDivider * game->getWorld()->getUpdateFps(this->getFactionIndex()));
|
||||||
|
|
||||||
|
//checks
|
||||||
|
bool return_value = false;
|
||||||
|
//checks
|
||||||
|
if(newProgress >= 1.f) {
|
||||||
|
if(currSkill->getClass() != scDie) {
|
||||||
|
newProgress= 0.f;
|
||||||
|
return_value = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
newProgress= 1.f;
|
||||||
|
int newDeadCount = deadCount;
|
||||||
|
newDeadCount++;
|
||||||
|
if(newDeadCount >= maxDeadCount) {
|
||||||
|
return_value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
bool Unit::update() {
|
bool Unit::update() {
|
||||||
assert(progress<=1.f);
|
assert(progress<=1.f);
|
||||||
|
|
||||||
|
|
|
@ -147,7 +147,7 @@ public:
|
||||||
virtual void incBlockCount();
|
virtual void incBlockCount();
|
||||||
virtual void add(const Vec2i &path);
|
virtual void add(const Vec2i &path);
|
||||||
void addToLastPathCache(const Vec2i &path);
|
void addToLastPathCache(const Vec2i &path);
|
||||||
Vec2i pop();
|
Vec2i pop(bool removeFrontPos=true);
|
||||||
virtual int getBlockCount() const { return blockCount; }
|
virtual int getBlockCount() const { return blockCount; }
|
||||||
virtual int getQueueCount() const { return pathQueue.size(); }
|
virtual int getQueueCount() const { return pathQueue.size(); }
|
||||||
|
|
||||||
|
@ -494,6 +494,7 @@ public:
|
||||||
|
|
||||||
void logSynchData(string file,int line,string source="");
|
void logSynchData(string file,int line,string source="");
|
||||||
std::string toString() const;
|
std::string toString() const;
|
||||||
|
bool needToUpdate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float computeHeight(const Vec2i &pos) const;
|
float computeHeight(const Vec2i &pos) const;
|
||||||
|
|
|
@ -88,8 +88,8 @@ StopCommandType::StopCommandType(){
|
||||||
clicks= cOne;
|
clicks= cOne;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StopCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
|
void StopCommandType::update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const {
|
||||||
unitUpdater->updateStop(unit);
|
unitUpdater->updateStop(unit, frameIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
string StopCommandType::getDesc(const TotalUpgrade *totalUpgrade) const{
|
string StopCommandType::getDesc(const TotalUpgrade *totalUpgrade) const{
|
||||||
|
@ -131,8 +131,8 @@ MoveCommandType::MoveCommandType(){
|
||||||
clicks= cTwo;
|
clicks= cTwo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MoveCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
|
void MoveCommandType::update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const {
|
||||||
unitUpdater->updateMove(unit);
|
unitUpdater->updateMove(unit, frameIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MoveCommandType::load(int id, const XmlNode *n, const string &dir,
|
void MoveCommandType::load(int id, const XmlNode *n, const string &dir,
|
||||||
|
@ -180,8 +180,8 @@ AttackCommandType::AttackCommandType(){
|
||||||
clicks= cTwo;
|
clicks= cTwo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttackCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
|
void AttackCommandType::update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const {
|
||||||
unitUpdater->updateAttack(unit);
|
unitUpdater->updateAttack(unit, frameIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttackCommandType::load(int id, const XmlNode *n, const string &dir,
|
void AttackCommandType::load(int id, const XmlNode *n, const string &dir,
|
||||||
|
@ -272,8 +272,8 @@ AttackStoppedCommandType::AttackStoppedCommandType(){
|
||||||
clicks= cOne;
|
clicks= cOne;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttackStoppedCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
|
void AttackStoppedCommandType::update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const {
|
||||||
unitUpdater->updateAttackStopped(unit);
|
unitUpdater->updateAttackStopped(unit, frameIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AttackStoppedCommandType::load(int id, const XmlNode *n, const string &dir,
|
void AttackStoppedCommandType::load(int id, const XmlNode *n, const string &dir,
|
||||||
|
@ -359,8 +359,8 @@ BuildCommandType::~BuildCommandType() {
|
||||||
deleteValues(startSounds.getSounds().begin(), startSounds.getSounds().end());
|
deleteValues(startSounds.getSounds().begin(), startSounds.getSounds().end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
|
void BuildCommandType::update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const {
|
||||||
unitUpdater->updateBuild(unit);
|
unitUpdater->updateBuild(unit, frameIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildCommandType::load(int id, const XmlNode *n, const string &dir,
|
void BuildCommandType::load(int id, const XmlNode *n, const string &dir,
|
||||||
|
@ -457,8 +457,8 @@ HarvestCommandType::HarvestCommandType(){
|
||||||
clicks= cTwo;
|
clicks= cTwo;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HarvestCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
|
void HarvestCommandType::update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const {
|
||||||
unitUpdater->updateHarvest(unit);
|
unitUpdater->updateHarvest(unit, frameIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HarvestCommandType::load(int id, const XmlNode *n, const string &dir,
|
void HarvestCommandType::load(int id, const XmlNode *n, const string &dir,
|
||||||
|
@ -538,8 +538,8 @@ RepairCommandType::RepairCommandType(){
|
||||||
RepairCommandType::~RepairCommandType(){
|
RepairCommandType::~RepairCommandType(){
|
||||||
}
|
}
|
||||||
|
|
||||||
void RepairCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
|
void RepairCommandType::update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const {
|
||||||
unitUpdater->updateRepair(unit);
|
unitUpdater->updateRepair(unit, frameIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RepairCommandType::load(int id, const XmlNode *n, const string &dir,
|
void RepairCommandType::load(int id, const XmlNode *n, const string &dir,
|
||||||
|
@ -615,8 +615,8 @@ ProduceCommandType::ProduceCommandType(){
|
||||||
clicks= cOne;
|
clicks= cOne;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProduceCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
|
void ProduceCommandType::update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const {
|
||||||
unitUpdater->updateProduce(unit);
|
unitUpdater->updateProduce(unit, frameIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProduceCommandType::load(int id, const XmlNode *n, const string &dir,
|
void ProduceCommandType::load(int id, const XmlNode *n, const string &dir,
|
||||||
|
@ -680,8 +680,8 @@ UpgradeCommandType::UpgradeCommandType(){
|
||||||
clicks= cOne;
|
clicks= cOne;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpgradeCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
|
void UpgradeCommandType::update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const {
|
||||||
unitUpdater->updateUpgrade(unit);
|
unitUpdater->updateUpgrade(unit, frameIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpgradeCommandType::load(int id, const XmlNode *n, const string &dir,
|
void UpgradeCommandType::load(int id, const XmlNode *n, const string &dir,
|
||||||
|
@ -737,8 +737,8 @@ MorphCommandType::MorphCommandType(){
|
||||||
clicks= cOne;
|
clicks= cOne;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MorphCommandType::update(UnitUpdater *unitUpdater, Unit *unit) const{
|
void MorphCommandType::update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const {
|
||||||
unitUpdater->updateMorph(unit);
|
unitUpdater->updateMorph(unit, frameIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MorphCommandType::load(int id, const XmlNode *n, const string &dir,
|
void MorphCommandType::load(int id, const XmlNode *n, const string &dir,
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#include "sound_container.h"
|
#include "sound_container.h"
|
||||||
#include "leak_dumper.h"
|
#include "leak_dumper.h"
|
||||||
|
|
||||||
namespace Glest{ namespace Game{
|
namespace Glest { namespace Game {
|
||||||
|
|
||||||
using Shared::Util::MultiFactory;
|
using Shared::Util::MultiFactory;
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ class UnitType;
|
||||||
class TechTree;
|
class TechTree;
|
||||||
class FactionType;
|
class FactionType;
|
||||||
|
|
||||||
enum CommandClass{
|
enum CommandClass {
|
||||||
ccStop,
|
ccStop,
|
||||||
ccMove,
|
ccMove,
|
||||||
ccAttack,
|
ccAttack,
|
||||||
|
@ -47,7 +47,7 @@ enum CommandClass{
|
||||||
ccNull
|
ccNull
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Clicks{
|
enum Clicks {
|
||||||
cOne,
|
cOne,
|
||||||
cTwo
|
cTwo
|
||||||
};
|
};
|
||||||
|
@ -80,7 +80,7 @@ public:
|
||||||
clicks = cOne;
|
clicks = cOne;
|
||||||
id = -1;
|
id = -1;
|
||||||
}
|
}
|
||||||
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const= 0;
|
virtual void update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const= 0;
|
||||||
virtual void load(int id, const XmlNode *n, const string &dir,
|
virtual void load(int id, const XmlNode *n, const string &dir,
|
||||||
const TechTree *tt, const FactionType *ft, const UnitType &ut,
|
const TechTree *tt, const FactionType *ft, const UnitType &ut,
|
||||||
std::map<string,int> &loadedFileList);
|
std::map<string,int> &loadedFileList);
|
||||||
|
@ -109,13 +109,13 @@ public:
|
||||||
// class StopCommandType
|
// class StopCommandType
|
||||||
// ===============================
|
// ===============================
|
||||||
|
|
||||||
class StopCommandType: public CommandType{
|
class StopCommandType: public CommandType {
|
||||||
private:
|
private:
|
||||||
const StopSkillType* stopSkillType;
|
const StopSkillType* stopSkillType;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StopCommandType();
|
StopCommandType();
|
||||||
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
|
virtual void update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const;
|
||||||
virtual void load(int id, const XmlNode *n, const string &dir, const TechTree *tt,
|
virtual void load(int id, const XmlNode *n, const string &dir, const TechTree *tt,
|
||||||
const FactionType *ft, const UnitType &ut, std::map<string,int> &loadedFileList);
|
const FactionType *ft, const UnitType &ut, std::map<string,int> &loadedFileList);
|
||||||
virtual string getDesc(const TotalUpgrade *totalUpgrade) const;
|
virtual string getDesc(const TotalUpgrade *totalUpgrade) const;
|
||||||
|
@ -131,13 +131,13 @@ public:
|
||||||
// class MoveCommandType
|
// class MoveCommandType
|
||||||
// ===============================
|
// ===============================
|
||||||
|
|
||||||
class MoveCommandType: public CommandType{
|
class MoveCommandType: public CommandType {
|
||||||
private:
|
private:
|
||||||
const MoveSkillType *moveSkillType;
|
const MoveSkillType *moveSkillType;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MoveCommandType();
|
MoveCommandType();
|
||||||
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
|
virtual void update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const;
|
||||||
virtual void load(int id, const XmlNode *n, const string &dir,
|
virtual void load(int id, const XmlNode *n, const string &dir,
|
||||||
const TechTree *tt, const FactionType *ft, const UnitType &ut,
|
const TechTree *tt, const FactionType *ft, const UnitType &ut,
|
||||||
std::map<string,int> &loadedFileList);
|
std::map<string,int> &loadedFileList);
|
||||||
|
@ -153,14 +153,14 @@ public:
|
||||||
// class AttackCommandType
|
// class AttackCommandType
|
||||||
// ===============================
|
// ===============================
|
||||||
|
|
||||||
class AttackCommandType: public CommandType{
|
class AttackCommandType: public CommandType {
|
||||||
private:
|
private:
|
||||||
const MoveSkillType* moveSkillType;
|
const MoveSkillType* moveSkillType;
|
||||||
const AttackSkillType* attackSkillType;
|
const AttackSkillType* attackSkillType;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AttackCommandType();
|
AttackCommandType();
|
||||||
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
|
virtual void update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const;
|
||||||
virtual void load(int id, const XmlNode *n, const string &dir,
|
virtual void load(int id, const XmlNode *n, const string &dir,
|
||||||
const TechTree *tt, const FactionType *ft, const UnitType &ut,
|
const TechTree *tt, const FactionType *ft, const UnitType &ut,
|
||||||
std::map<string,int> &loadedFileList);
|
std::map<string,int> &loadedFileList);
|
||||||
|
@ -177,14 +177,14 @@ public:
|
||||||
// class AttackStoppedCommandType
|
// class AttackStoppedCommandType
|
||||||
// =======================================
|
// =======================================
|
||||||
|
|
||||||
class AttackStoppedCommandType: public CommandType{
|
class AttackStoppedCommandType: public CommandType {
|
||||||
private:
|
private:
|
||||||
const StopSkillType* stopSkillType;
|
const StopSkillType* stopSkillType;
|
||||||
const AttackSkillType* attackSkillType;
|
const AttackSkillType* attackSkillType;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AttackStoppedCommandType();
|
AttackStoppedCommandType();
|
||||||
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
|
virtual void update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const;
|
||||||
virtual void load(int id, const XmlNode *n, const string &dir,
|
virtual void load(int id, const XmlNode *n, const string &dir,
|
||||||
const TechTree *tt, const FactionType *ft, const UnitType &ut,
|
const TechTree *tt, const FactionType *ft, const UnitType &ut,
|
||||||
std::map<string,int> &loadedFileList);
|
std::map<string,int> &loadedFileList);
|
||||||
|
@ -201,7 +201,7 @@ public:
|
||||||
// class BuildCommandType
|
// class BuildCommandType
|
||||||
// ===============================
|
// ===============================
|
||||||
|
|
||||||
class BuildCommandType: public CommandType{
|
class BuildCommandType: public CommandType {
|
||||||
private:
|
private:
|
||||||
const MoveSkillType* moveSkillType;
|
const MoveSkillType* moveSkillType;
|
||||||
const BuildSkillType* buildSkillType;
|
const BuildSkillType* buildSkillType;
|
||||||
|
@ -212,7 +212,7 @@ private:
|
||||||
public:
|
public:
|
||||||
BuildCommandType();
|
BuildCommandType();
|
||||||
~BuildCommandType();
|
~BuildCommandType();
|
||||||
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
|
virtual void update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const;
|
||||||
virtual void load(int id, const XmlNode *n, const string &dir,
|
virtual void load(int id, const XmlNode *n, const string &dir,
|
||||||
const TechTree *tt, const FactionType *ft, const UnitType &ut,
|
const TechTree *tt, const FactionType *ft, const UnitType &ut,
|
||||||
std::map<string,int> &loadedFileList);
|
std::map<string,int> &loadedFileList);
|
||||||
|
@ -233,7 +233,7 @@ public:
|
||||||
// class HarvestCommandType
|
// class HarvestCommandType
|
||||||
// ===============================
|
// ===============================
|
||||||
|
|
||||||
class HarvestCommandType: public CommandType{
|
class HarvestCommandType: public CommandType {
|
||||||
private:
|
private:
|
||||||
const MoveSkillType *moveSkillType;
|
const MoveSkillType *moveSkillType;
|
||||||
const MoveSkillType *moveLoadedSkillType;
|
const MoveSkillType *moveLoadedSkillType;
|
||||||
|
@ -245,7 +245,7 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HarvestCommandType();
|
HarvestCommandType();
|
||||||
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
|
virtual void update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const;
|
||||||
virtual void load(int id, const XmlNode *n, const string &dir,
|
virtual void load(int id, const XmlNode *n, const string &dir,
|
||||||
const TechTree *tt, const FactionType *ft, const UnitType &ut,
|
const TechTree *tt, const FactionType *ft, const UnitType &ut,
|
||||||
std::map<string,int> &loadedFileList);
|
std::map<string,int> &loadedFileList);
|
||||||
|
@ -270,7 +270,7 @@ public:
|
||||||
// class RepairCommandType
|
// class RepairCommandType
|
||||||
// ===============================
|
// ===============================
|
||||||
|
|
||||||
class RepairCommandType: public CommandType{
|
class RepairCommandType: public CommandType {
|
||||||
private:
|
private:
|
||||||
const MoveSkillType* moveSkillType;
|
const MoveSkillType* moveSkillType;
|
||||||
const RepairSkillType* repairSkillType;
|
const RepairSkillType* repairSkillType;
|
||||||
|
@ -279,7 +279,7 @@ private:
|
||||||
public:
|
public:
|
||||||
RepairCommandType();
|
RepairCommandType();
|
||||||
~RepairCommandType();
|
~RepairCommandType();
|
||||||
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
|
virtual void update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const;
|
||||||
virtual void load(int id, const XmlNode *n, const string &dir,
|
virtual void load(int id, const XmlNode *n, const string &dir,
|
||||||
const TechTree *tt, const FactionType *ft, const UnitType &ut,
|
const TechTree *tt, const FactionType *ft, const UnitType &ut,
|
||||||
std::map<string,int> &loadedFileList);
|
std::map<string,int> &loadedFileList);
|
||||||
|
@ -301,14 +301,14 @@ public:
|
||||||
// class ProduceCommandType
|
// class ProduceCommandType
|
||||||
// ===============================
|
// ===============================
|
||||||
|
|
||||||
class ProduceCommandType: public CommandType{
|
class ProduceCommandType: public CommandType {
|
||||||
private:
|
private:
|
||||||
const ProduceSkillType* produceSkillType;
|
const ProduceSkillType* produceSkillType;
|
||||||
const UnitType *producedUnit;
|
const UnitType *producedUnit;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ProduceCommandType();
|
ProduceCommandType();
|
||||||
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
|
virtual void update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const;
|
||||||
virtual void load(int id, const XmlNode *n, const string &dir,
|
virtual void load(int id, const XmlNode *n, const string &dir,
|
||||||
const TechTree *tt, const FactionType *ft, const UnitType &ut,
|
const TechTree *tt, const FactionType *ft, const UnitType &ut,
|
||||||
std::map<string,int> &loadedFileList);
|
std::map<string,int> &loadedFileList);
|
||||||
|
@ -328,14 +328,14 @@ public:
|
||||||
// class UpgradeCommandType
|
// class UpgradeCommandType
|
||||||
// ===============================
|
// ===============================
|
||||||
|
|
||||||
class UpgradeCommandType: public CommandType{
|
class UpgradeCommandType: public CommandType {
|
||||||
private:
|
private:
|
||||||
const UpgradeSkillType* upgradeSkillType;
|
const UpgradeSkillType* upgradeSkillType;
|
||||||
const UpgradeType* producedUpgrade;
|
const UpgradeType* producedUpgrade;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UpgradeCommandType();
|
UpgradeCommandType();
|
||||||
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
|
virtual void update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const;
|
||||||
virtual void load(int id, const XmlNode *n, const string &dir,
|
virtual void load(int id, const XmlNode *n, const string &dir,
|
||||||
const TechTree *tt, const FactionType *ft, const UnitType &ut,
|
const TechTree *tt, const FactionType *ft, const UnitType &ut,
|
||||||
std::map<string,int> &loadedFileList);
|
std::map<string,int> &loadedFileList);
|
||||||
|
@ -354,7 +354,7 @@ public:
|
||||||
// class MorphCommandType
|
// class MorphCommandType
|
||||||
// ===============================
|
// ===============================
|
||||||
|
|
||||||
class MorphCommandType: public CommandType{
|
class MorphCommandType: public CommandType {
|
||||||
private:
|
private:
|
||||||
const MorphSkillType* morphSkillType;
|
const MorphSkillType* morphSkillType;
|
||||||
const UnitType* morphUnit;
|
const UnitType* morphUnit;
|
||||||
|
@ -362,7 +362,7 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MorphCommandType();
|
MorphCommandType();
|
||||||
virtual void update(UnitUpdater *unitUpdater, Unit *unit) const;
|
virtual void update(UnitUpdater *unitUpdater, Unit *unit, int frameIndex) const;
|
||||||
virtual void load(int id, const XmlNode *n, const string &dir,
|
virtual void load(int id, const XmlNode *n, const string &dir,
|
||||||
const TechTree *tt, const FactionType *ft, const UnitType &ut,
|
const TechTree *tt, const FactionType *ft, const UnitType &ut,
|
||||||
std::map<string,int> &loadedFileList);
|
std::map<string,int> &loadedFileList);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -100,17 +100,17 @@ public:
|
||||||
void updateUnit(Unit *unit);
|
void updateUnit(Unit *unit);
|
||||||
|
|
||||||
//update commands
|
//update commands
|
||||||
void updateUnitCommand(Unit *unit);
|
void updateUnitCommand(Unit *unit, int frameIndex);
|
||||||
void updateStop(Unit *unit);
|
void updateStop(Unit *unit, int frameIndex);
|
||||||
void updateMove(Unit *unit);
|
void updateMove(Unit *unit, int frameIndex);
|
||||||
void updateAttack(Unit *unit);
|
void updateAttack(Unit *unit, int frameIndex);
|
||||||
void updateAttackStopped(Unit *unit);
|
void updateAttackStopped(Unit *unit, int frameIndex);
|
||||||
void updateBuild(Unit *unit);
|
void updateBuild(Unit *unit, int frameIndex);
|
||||||
void updateHarvest(Unit *unit);
|
void updateHarvest(Unit *unit, int frameIndex);
|
||||||
void updateRepair(Unit *unit);
|
void updateRepair(Unit *unit, int frameIndex);
|
||||||
void updateProduce(Unit *unit);
|
void updateProduce(Unit *unit, int frameIndex);
|
||||||
void updateUpgrade(Unit *unit);
|
void updateUpgrade(Unit *unit, int frameIndex);
|
||||||
void updateMorph(Unit *unit);
|
void updateMorph(Unit *unit, int frameIndex);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//attack
|
//attack
|
||||||
|
@ -133,6 +133,7 @@ private:
|
||||||
const CommandType *commandType,
|
const CommandType *commandType,
|
||||||
int originalValue,int newValue);
|
int originalValue,int newValue);
|
||||||
|
|
||||||
|
void clearUnitPrecache(Unit *unit);
|
||||||
};
|
};
|
||||||
|
|
||||||
// =====================================================
|
// =====================================================
|
||||||
|
|
|
@ -271,8 +271,44 @@ Checksum World::loadScenario(const string &path, Checksum *checksum) {
|
||||||
|
|
||||||
void World::updateAllFactionUnits() {
|
void World::updateAllFactionUnits() {
|
||||||
scriptManager->onTimerTriggerEvent();
|
scriptManager->onTimerTriggerEvent();
|
||||||
//units
|
|
||||||
|
// Signal the faction threads to do any pre-processing
|
||||||
int factionCount = getFactionCount();
|
int factionCount = getFactionCount();
|
||||||
|
for(int i = 0; i < factionCount; ++i) {
|
||||||
|
Faction *faction = getFaction(i);
|
||||||
|
if(faction == NULL) {
|
||||||
|
throw runtime_error("faction == NULL");
|
||||||
|
}
|
||||||
|
faction->signalWorkerThread(frameCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool workThreadsFinished = false;
|
||||||
|
Chrono chrono;
|
||||||
|
chrono.start();
|
||||||
|
|
||||||
|
for(;chrono.getMillis() < 10000;) {
|
||||||
|
workThreadsFinished = true;
|
||||||
|
for(int i = 0; i < factionCount; ++i) {
|
||||||
|
Faction *faction = getFaction(i);
|
||||||
|
if(faction == NULL) {
|
||||||
|
throw runtime_error("faction == NULL");
|
||||||
|
}
|
||||||
|
if(faction->isWorkerThreadSignalCompleted(frameCount) == false) {
|
||||||
|
workThreadsFinished = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(workThreadsFinished == false) {
|
||||||
|
sleep(0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(SystemFlags::VERBOSE_MODE_ENABLED && chrono.getMillis() >= 10) printf("In [%s::%s Line: %d] *** Faction thread preprocessing took [%lld] msecs for %d factions for frameCount = %d.\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis(),factionCount,frameCount);
|
||||||
|
|
||||||
|
//units
|
||||||
for(int i = 0; i < factionCount; ++i) {
|
for(int i = 0; i < factionCount; ++i) {
|
||||||
Faction *faction = getFaction(i);
|
Faction *faction = getFaction(i);
|
||||||
if(faction == NULL) {
|
if(faction == NULL) {
|
||||||
|
@ -290,6 +326,8 @@ void World::updateAllFactionUnits() {
|
||||||
unitUpdater.updateUnit(unit);
|
unitUpdater.updateUnit(unit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(SystemFlags::VERBOSE_MODE_ENABLED && chrono.getMillis() >= 20) printf("In [%s::%s Line: %d] *** Faction MAIN thread processing took [%lld] msecs for %d factions for frameCount = %d.\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis(),factionCount,frameCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::underTakeDeadFactionUnits() {
|
void World::underTakeDeadFactionUnits() {
|
||||||
|
|
|
@ -231,6 +231,8 @@ public:
|
||||||
void exploreCells(const Vec2i &newPos, int sightRange, int teamIndex);
|
void exploreCells(const Vec2i &newPos, int sightRange, int teamIndex);
|
||||||
bool showWorldForPlayer(int factionIndex) const;
|
bool showWorldForPlayer(int factionIndex) const;
|
||||||
|
|
||||||
|
UnitUpdater * getUnitUpdater() { return &unitUpdater; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void initCells(bool fogOfWar);
|
void initCells(bool fogOfWar);
|
||||||
|
|
Loading…
Reference in New Issue