- 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;
std::vector<Vec2i> cachedPath = unit->getFaction()->findCachedPath(finalPos, unit);
if(cachedPath.size() > 0) {
path->clear();
//route cache miss
ts = aStar(unit, finalPos, false);
for(int i=0; i < cachedPath.size() && i < pathFindRefresh; ++i) {
path->add(cachedPath[i]);
if(ts == tsBlocked) {
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

View File

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

View File

@ -84,7 +84,7 @@ private:
bool thisFaction;
std::map<Vec2i, std::vector<FactionPathSuccessCache> > successfulPathFinderTargetList;
std::vector<std::pair<const ResourceType *, Vec2i> > cacheResourceTypeTargetList;
std::vector<Vec2i> cacheResourceTargetList;
public:
Faction();
@ -156,8 +156,7 @@ public:
std::vector<Vec2i> findCachedPath(const Vec2i &target, Unit *unit);
void addCachedPath(const Vec2i &target, Unit *unit);
//std::map<const ResourceType *, Vec2i > cacheResourceTypeTargetList;
void addResourceTypeTargetToCache(const ResourceType *type, const Vec2i &pos);
void addResourceTargetToCache(const Vec2i &pos);
Vec2i getClosestResourceTypeTargetFromCache(Unit *unit, const ResourceType *type);
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) {
if(isInside(pos.x + i, pos.y + j)) {
Resource *r= getSurfaceCell(toSurfCoords(Vec2i(pos.x + i, pos.y + j)))->getResource();
if(r != NULL){
if(r != NULL) {
if(r->getType() == rt) {
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) {
// Look for another unit that is currently harvesting the same resource
// type right now
for(int i = 0; i < unit->getFaction()->getUnitCount(); ++i) {
Unit *peerUnit = unit->getFaction()->getUnit(i);
if( peerUnit != NULL && peerUnit->getId() != unit->getId() &&
peerUnit->getType()->getSize() <= unit->getType()->getSize()) {
if( peerUnit->getCurrSkill()->getClass() == scHarvest &&
if( peerUnit->getCurrSkill() != NULL &&
peerUnit->getCurrSkill()->getClass() == scHarvest &&
peerUnit->getLoadType() == rt &&
peerUnit->getCurrCommand() != NULL) {
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();
}
if(unit->getPos().dist(peerUnit->getCurrCommand()->getPos()) <= 5) {
resourcePos = peerUnit->getCurrCommand()->getPos();
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);
if(result.x >= 0) {
resourcePos = result;
if(unit->getPos().dist(resourcePos) <= 5) {
return true;
}
}
}
return false;
}

View File

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