- more tweaking for units harvesting, this hopefully cleans up segfaults and makes things more stable.

This commit is contained in:
Mark Vejvoda 2010-10-20 20:40:29 +00:00
parent 6104dedc76
commit bc7ba297fd
5 changed files with 77 additions and 53 deletions

View File

@ -128,18 +128,21 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
} }
TravelState ts = tsImpossible; TravelState ts = tsImpossible;
std::vector<Vec2i> cachedPath = unit->getFaction()->findCachedPath(finalPos, unit); //route cache miss
if(cachedPath.size() > 0) { ts = aStar(unit, finalPos, false);
path->clear();
for(int i=0; i < cachedPath.size() && i < pathFindRefresh; ++i) { if(ts == tsBlocked) {
path->add(cachedPath[i]); std::vector<Vec2i> cachedPath = unit->getFaction()->findCachedPath(finalPos, unit);
if(cachedPath.size() > 0) {
path->clear();
for(int i=0; i < cachedPath.size() && i < pathFindRefresh; ++i) {
path->add(cachedPath[i]);
}
ts = tsMoving;
unit->addCurrentTargetPathTakenCell(Vec2i(-1),Vec2i(-1));
} }
ts = tsMoving;
}
else {
//route cache miss
ts = aStar(unit, finalPos, false);
} }
//post actions //post actions

View File

@ -584,19 +584,19 @@ void Faction::resetResourceAmount(const ResourceType *rt){
assert(false); assert(false);
} }
void Faction::addResourceTypeTargetToCache(const ResourceType *type, const Vec2i &pos) { void Faction::addResourceTargetToCache(const Vec2i &pos) {
bool duplicateEntry = false; bool duplicateEntry = false;
if(cacheResourceTypeTargetList.size() > 0) { if(cacheResourceTargetList.size() > 0) {
for(int i = 0; i < cacheResourceTypeTargetList.size(); ++i) { for(int i = 0; i < cacheResourceTargetList.size(); ++i) {
std::pair<const ResourceType *, Vec2i> &cache = cacheResourceTypeTargetList[i]; const Vec2i &cache = cacheResourceTargetList[i];
if(cache.first == type && cache.second == pos) { if(cache == pos) {
duplicateEntry = true; duplicateEntry = true;
break; break;
} }
} }
} }
if(duplicateEntry == false) { if(duplicateEntry == false) {
cacheResourceTypeTargetList.push_back(make_pair<const ResourceType *, Vec2i>(type,pos)); cacheResourceTargetList.push_back(pos);
} }
cleanupResourceTypeTargetCache(); cleanupResourceTypeTargetCache();
@ -604,14 +604,18 @@ void Faction::addResourceTypeTargetToCache(const ResourceType *type, const Vec2i
Vec2i Faction::getClosestResourceTypeTargetFromCache(Unit *unit, const ResourceType *type) { Vec2i Faction::getClosestResourceTypeTargetFromCache(Unit *unit, const ResourceType *type) {
Vec2i result(-1); Vec2i result(-1);
if(cacheResourceTypeTargetList.size() > 0) { if(cacheResourceTargetList.size() > 0) {
for(int i = 0; i < cacheResourceTypeTargetList.size(); ++i) { const Map *map = world->getMap();
std::pair<const ResourceType *, Vec2i> &cache = cacheResourceTypeTargetList[i]; for(int i = 0; i < cacheResourceTargetList.size(); ++i) {
const Vec2i &cache = cacheResourceTargetList[i];
Resource *resource = world->getMap()->getSurfaceCell(world->getMap()->toSurfCoords(cache.second))->getResource(); const SurfaceCell *sc = map->getSurfaceCell(map->toSurfCoords(cache));
if(resource != NULL && cache.first == type) { if( sc != NULL && sc->getResource() != NULL) {
if(result.x < 0 || unit->getPos().dist(cache.second) < unit->getPos().dist(result)) { const Resource *resource = sc->getResource();
result = cache.second; if(resource->getType() != NULL && resource->getType() == type) {
if(result.x < 0 || unit->getPos().dist(cache) < unit->getPos().dist(result)) {
result = cache;
}
} }
} }
} }
@ -623,13 +627,18 @@ Vec2i Faction::getClosestResourceTypeTargetFromCache(Unit *unit, const ResourceT
} }
void Faction::cleanupResourceTypeTargetCache() { void Faction::cleanupResourceTypeTargetCache() {
if(cacheResourceTypeTargetList.size() > 0) { if(cacheResourceTargetList.size() > 0) {
for(int i = cacheResourceTypeTargetList.size() - 1; i >= 0; --i) { for(int i = cacheResourceTargetList.size() - 1; i >= 0; --i) {
std::pair<const ResourceType *, Vec2i> &cache = cacheResourceTypeTargetList[i]; const Vec2i &cache = cacheResourceTargetList[i];
Resource *resource = world->getMap()->getSurfaceCell(world->getMap()->toSurfCoords(cache.second))->getResource(); if(world->getMap()->getSurfaceCell(world->getMap()->toSurfCoords(cache)) != NULL) {
if(resource == NULL) { Resource *resource = world->getMap()->getSurfaceCell(world->getMap()->toSurfCoords(cache))->getResource();
cacheResourceTypeTargetList.erase(cacheResourceTypeTargetList.begin() + i); if(resource == NULL) {
cacheResourceTargetList.erase(cacheResourceTargetList.begin() + i);
}
}
else {
cacheResourceTargetList.erase(cacheResourceTargetList.begin() + i);
} }
} }
} }

View File

@ -84,7 +84,7 @@ private:
bool thisFaction; bool thisFaction;
std::map<Vec2i, std::vector<FactionPathSuccessCache> > successfulPathFinderTargetList; std::map<Vec2i, std::vector<FactionPathSuccessCache> > successfulPathFinderTargetList;
std::vector<std::pair<const ResourceType *, Vec2i> > cacheResourceTypeTargetList; std::vector<Vec2i> cacheResourceTargetList;
public: public:
Faction(); Faction();
@ -156,8 +156,7 @@ public:
std::vector<Vec2i> findCachedPath(const Vec2i &target, Unit *unit); std::vector<Vec2i> findCachedPath(const Vec2i &target, Unit *unit);
void addCachedPath(const Vec2i &target, Unit *unit); void addCachedPath(const Vec2i &target, Unit *unit);
//std::map<const ResourceType *, Vec2i > cacheResourceTypeTargetList; void addResourceTargetToCache(const Vec2i &pos);
void addResourceTypeTargetToCache(const ResourceType *type, const Vec2i &pos);
Vec2i getClosestResourceTypeTargetFromCache(Unit *unit, const ResourceType *type); Vec2i getClosestResourceTypeTargetFromCache(Unit *unit, const ResourceType *type);
void cleanupResourceTypeTargetCache(); void cleanupResourceTypeTargetCache();

View File

@ -256,7 +256,7 @@ bool Map::isResourceNear(const Vec2i &pos, const ResourceType *rt, Vec2i &resour
for(int j = -1; j <= size; ++j) { for(int j = -1; j <= size; ++j) {
if(isInside(pos.x + i, pos.y + j)) { if(isInside(pos.x + i, pos.y + j)) {
Resource *r= getSurfaceCell(toSurfCoords(Vec2i(pos.x + i, pos.y + j)))->getResource(); Resource *r= getSurfaceCell(toSurfCoords(Vec2i(pos.x + i, pos.y + j)))->getResource();
if(r != NULL){ if(r != NULL) {
if(r->getType() == rt) { if(r->getType() == rt) {
resourcePos= pos + Vec2i(i,j); resourcePos= pos + Vec2i(i,j);
@ -270,20 +270,23 @@ bool Map::isResourceNear(const Vec2i &pos, const ResourceType *rt, Vec2i &resour
} }
if(fallbackToPeersHarvestingSameResource == true && unit != NULL) { if(fallbackToPeersHarvestingSameResource == true && unit != NULL) {
// Look for another unit that is currently harvesting the same resource
// type right now
for(int i = 0; i < unit->getFaction()->getUnitCount(); ++i) { for(int i = 0; i < unit->getFaction()->getUnitCount(); ++i) {
Unit *peerUnit = unit->getFaction()->getUnit(i); Unit *peerUnit = unit->getFaction()->getUnit(i);
if( peerUnit != NULL && peerUnit->getId() != unit->getId() && if( peerUnit != NULL && peerUnit->getId() != unit->getId() &&
peerUnit->getType()->getSize() <= unit->getType()->getSize()) { peerUnit->getType()->getSize() <= unit->getType()->getSize()) {
if( peerUnit->getCurrSkill()->getClass() == scHarvest && if( peerUnit->getCurrSkill() != NULL &&
peerUnit->getCurrSkill()->getClass() == scHarvest &&
peerUnit->getLoadType() == rt && peerUnit->getLoadType() == rt &&
peerUnit->getCurrCommand() != NULL) { peerUnit->getCurrCommand() != NULL) {
if(unit->getPos().dist(peerUnit->getCurrCommand()->getPos()) <= 40) { if(unit->getPos().dist(peerUnit->getCurrCommand()->getPos()) <= 40) {
if(i == 0 || (unit->getPos().dist(peerUnit->getCurrCommand()->getPos()) < unit->getPos().dist(resourcePos))) { if( i == 0 ||
(unit->getPos().dist(peerUnit->getCurrCommand()->getPos()) < unit->getPos().dist(resourcePos))) {
resourcePos = peerUnit->getCurrCommand()->getPos(); resourcePos = peerUnit->getCurrCommand()->getPos();
} }
if(unit->getPos().dist(peerUnit->getCurrCommand()->getPos()) <= 5) { if(unit->getPos().dist(peerUnit->getCurrCommand()->getPos()) <= 5) {
resourcePos = peerUnit->getCurrCommand()->getPos();
return true; return true;
} }
} }
@ -291,15 +294,18 @@ bool Map::isResourceNear(const Vec2i &pos, const ResourceType *rt, Vec2i &resour
} }
} }
// Check the faction cache for a known position where we can harvest
// this resource type
Vec2i result = unit->getFaction()->getClosestResourceTypeTargetFromCache(unit, rt); Vec2i result = unit->getFaction()->getClosestResourceTypeTargetFromCache(unit, rt);
if(result.x >= 0) { if(result.x >= 0) {
resourcePos = result; resourcePos = result;
if(unit->getPos().dist(resourcePos) <= 5) { if(unit->getPos().dist(resourcePos) <= 5) {
return true; return true;
} }
} }
} }
return false; return false;
} }

View File

@ -578,7 +578,7 @@ void UnitUpdater::updateHarvest(Unit *unit) {
Command *command= unit->getCurrCommand(); Command *command= unit->getCurrCommand();
const HarvestCommandType *hct= static_cast<const HarvestCommandType*>(command->getCommandType()); const HarvestCommandType *hct= static_cast<const HarvestCommandType*>(command->getCommandType());
Vec2i targetPos; Vec2i targetPos(-1);
TravelState tsValue = tsImpossible; TravelState tsValue = tsImpossible;
UnitPathInterface *path= unit->getPath(); UnitPathInterface *path= unit->getPath();
@ -587,17 +587,21 @@ void UnitUpdater::updateHarvest(Unit *unit) {
//if not working //if not working
if(unit->getLoadCount() == 0) { if(unit->getLoadCount() == 0) {
//if not loaded go for resources //if not loaded go for resources
Resource *r= map->getSurfaceCell(Map::toSurfCoords(command->getPos()))->getResource(); Resource *r = map->getSurfaceCell(Map::toSurfCoords(command->getPos()))->getResource();
if(r != NULL && hct->canHarvest(r->getType())) { if(r != NULL && hct->canHarvest(r->getType())) {
//if can harvest dest. pos //if can harvest dest. pos
bool canHarvestDestPos = false; bool canHarvestDestPos = false;
targetPos.x = -1;
targetPos.y = -1;
switch(this->game->getGameSettings()->getPathFinderType()) { switch(this->game->getGameSettings()->getPathFinderType()) {
case pfBasic: case pfBasic:
canHarvestDestPos = (unit->getPos().dist(command->getPos()) < harvestDistance && {
map->isResourceNear(unit->getPos(), r->getType(), targetPos,unit->getType()->getSize(),unit)); bool isNearResource = map->isResourceNear(unit->getPos(), r->getType(), targetPos,unit->getType()->getSize(),unit);
if(isNearResource == true) {
if((unit->getPos().dist(command->getPos()) < harvestDistance || unit->getPos().dist(targetPos) < harvestDistance) && isNearResource == true) {
canHarvestDestPos = true;
}
}
}
break; break;
case pfRoutePlanner: case pfRoutePlanner:
canHarvestDestPos = map->isResourceNear(unit->getPos(), unit->getType()->getSize(), r->getType(), targetPos); canHarvestDestPos = map->isResourceNear(unit->getPos(), unit->getType()->getSize(), r->getType(), targetPos);
@ -616,11 +620,11 @@ void UnitUpdater::updateHarvest(Unit *unit) {
unit->setTargetPos(targetPos); unit->setTargetPos(targetPos);
command->setPos(targetPos); command->setPos(targetPos);
unit->setLoadCount(0); unit->setLoadCount(0);
unit->getFaction()->addResourceTypeTargetToCache(r->getType(), targetPos); unit->getFaction()->addResourceTargetToCache(targetPos);
switch(this->game->getGameSettings()->getPathFinderType()) { switch(this->game->getGameSettings()->getPathFinderType()) {
case pfBasic: case pfBasic:
unit->setLoadType(map->getSurfaceCell(Map::toSurfCoords(unit->getTargetPos()))->getResource()->getType()); unit->setLoadType(r->getType());
break; break;
case pfRoutePlanner: case pfRoutePlanner:
unit->setLoadType(r->getType()); unit->setLoadType(r->getType());
@ -653,11 +657,17 @@ void UnitUpdater::updateHarvest(Unit *unit) {
throw runtime_error("detected unsupported pathfinder type!"); throw runtime_error("detected unsupported pathfinder type!");
} }
if(wasStuck == true) { if(wasStuck == true && unit->isAlive() == true) {
switch(this->game->getGameSettings()->getPathFinderType()) { switch(this->game->getGameSettings()->getPathFinderType()) {
case pfBasic: case pfBasic:
canHarvestDestPos = (unit->getPos().dist(command->getPos()) < harvestDistance && {
map->isResourceNear(unit->getPos(), r->getType(), targetPos,unit->getType()->getSize(),unit, true)); bool isNearResource = map->isResourceNear(unit->getPos(), r->getType(), targetPos,unit->getType()->getSize(),unit);
if(isNearResource == true) {
if((unit->getPos().dist(command->getPos()) < harvestDistance || unit->getPos().dist(targetPos) < harvestDistance) && isNearResource == true) {
canHarvestDestPos = true;
}
}
}
break; break;
case pfRoutePlanner: case pfRoutePlanner:
canHarvestDestPos = map->isResourceNear(unit->getPos(), unit->getType()->getSize(), r->getType(), targetPos); canHarvestDestPos = map->isResourceNear(unit->getPos(), unit->getType()->getSize(), r->getType(), targetPos);
@ -676,14 +686,11 @@ void UnitUpdater::updateHarvest(Unit *unit) {
unit->setTargetPos(targetPos); unit->setTargetPos(targetPos);
command->setPos(targetPos); command->setPos(targetPos);
unit->setLoadCount(0); unit->setLoadCount(0);
unit->getFaction()->addResourceTypeTargetToCache(r->getType(), targetPos); unit->getFaction()->addResourceTargetToCache(targetPos);
switch(this->game->getGameSettings()->getPathFinderType()) { switch(this->game->getGameSettings()->getPathFinderType()) {
case pfBasic: case pfBasic:
{ unit->setLoadType(r->getType());
const ResourceType *loadType = map->getSurfaceCell(Map::toSurfCoords(unit->getTargetPos()))->getResource()->getType();
unit->setLoadType(loadType);
}
break; break;
case pfRoutePlanner: case pfRoutePlanner:
unit->setLoadType(r->getType()); unit->setLoadType(r->getType());