mirror of
https://github.com/glest/glest-source.git
synced 2025-02-24 11:42:31 +01:00
- improved performance for when the AI decides which resource is closest.
This commit is contained in:
parent
ca9cbc6e75
commit
9d9fa0deeb
@ -141,6 +141,9 @@ Ai::~Ai() {
|
||||
}
|
||||
|
||||
void Ai::update() {
|
||||
Chrono chrono;
|
||||
chrono.start();
|
||||
|
||||
//process ai rules
|
||||
for(int ruleIdx = 0; ruleIdx < aiRules.size(); ++ruleIdx) {
|
||||
AiRule *rule = aiRules[ruleIdx];
|
||||
@ -148,12 +151,23 @@ void Ai::update() {
|
||||
throw runtime_error("rule == NULL");
|
||||
}
|
||||
if((aiInterface->getTimer() % (rule->getTestInterval() * GameConstants::updateFps / 1000)) == 0){
|
||||
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] ruleIdx = %d, aiRules.size() = %d, took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,ruleIdx,aiRules.size(),chrono.getMillis());
|
||||
|
||||
if(rule->test()) {
|
||||
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] ruleIdx = %d, aiRules.size() = %d, took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,ruleIdx,aiRules.size(),chrono.getMillis());
|
||||
|
||||
aiInterface->printLog(3, intToStr(1000 * aiInterface->getTimer() / GameConstants::updateFps) + ": Executing rule: " + rule->getName() + '\n');
|
||||
|
||||
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] ruleIdx = %d, aiRules.size() = %d, took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,ruleIdx,aiRules.size(),chrono.getMillis());
|
||||
|
||||
rule->execute();
|
||||
|
||||
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] ruleIdx = %d, aiRules.size() = %d, took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,ruleIdx,aiRules.size(),chrono.getMillis());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||
}
|
||||
|
||||
|
||||
|
@ -371,6 +371,42 @@ const TechTree *AiInterface::getTechTree(){
|
||||
return world->getTechTree();
|
||||
}
|
||||
|
||||
//returns if there is a resource next to a unit, in "resourcePos" is stored the relative position of the resource
|
||||
bool AiInterface::isResourceNear(const Vec2i &pos, const ResourceType *rt, Vec2i &resourcePos, Faction *faction, bool fallbackToPeersHarvestingSameResource) const {
|
||||
const Map *map= world->getMap();
|
||||
int size = 1;
|
||||
for(int i = -1; i <= size; ++i) {
|
||||
for(int j = -1; j <= size; ++j) {
|
||||
if(map->isInside(pos.x + i, pos.y + j)) {
|
||||
Resource *r= map->getSurfaceCell(map->toSurfCoords(Vec2i(pos.x + i, pos.y + j)))->getResource();
|
||||
if(r != NULL) {
|
||||
if(r->getType() == rt) {
|
||||
resourcePos= pos + Vec2i(i,j);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(fallbackToPeersHarvestingSameResource == true && faction != NULL) {
|
||||
// Look for another unit that is currently harvesting the same resource
|
||||
// type right now
|
||||
|
||||
// Check the faction cache for a known position where we can harvest
|
||||
// this resource type
|
||||
Vec2i result = faction->getClosestResourceTypeTargetFromCache(pos, rt);
|
||||
if(result.x >= 0) {
|
||||
resourcePos = result;
|
||||
if(pos.dist(resourcePos) <= size) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AiInterface::getNearestSightedResource(const ResourceType *rt, const Vec2i &pos,
|
||||
Vec2i &resultPos, bool usableResourceTypeOnly) {
|
||||
float tmpDist=0;
|
||||
@ -381,7 +417,8 @@ bool AiInterface::getNearestSightedResource(const ResourceType *rt, const Vec2i
|
||||
bool canUseResourceType = (usableResourceTypeOnly == false);
|
||||
if(usableResourceTypeOnly == true) {
|
||||
// can any unit harvest this resource yet?
|
||||
for(int i = 0; i < getMyUnitCount(); ++i) {
|
||||
int unitCount = getMyUnitCount();
|
||||
for(int i = 0; i < unitCount; ++i) {
|
||||
const Unit *unit = getMyUnit(i);
|
||||
const HarvestCommandType *hct= unit->getType()->getFirstHarvestCommand(rt,unit->getFaction());
|
||||
if(hct != NULL) {
|
||||
@ -392,23 +429,28 @@ bool AiInterface::getNearestSightedResource(const ResourceType *rt, const Vec2i
|
||||
}
|
||||
|
||||
if(canUseResourceType == true) {
|
||||
const Map *map= world->getMap();
|
||||
Faction *faction = world->getFaction(factionIndex);
|
||||
if(isResourceNear(pos, rt, resultPos, faction, true) == true) {
|
||||
anyResource= true;
|
||||
}
|
||||
else {
|
||||
const Map *map= world->getMap();
|
||||
for(int i = 0; i < map->getW(); ++i) {
|
||||
for(int j = 0; j < map->getH(); ++j) {
|
||||
Vec2i surfPos= Map::toSurfCoords(Vec2i(i, j));
|
||||
|
||||
for(int i=0; i<map->getW(); ++i){
|
||||
for(int j=0; j<map->getH(); ++j){
|
||||
Vec2i surfPos= Map::toSurfCoords(Vec2i(i, j));
|
||||
|
||||
//if explored cell
|
||||
if(map->getSurfaceCell(surfPos)->isExplored(teamIndex)){
|
||||
Resource *r= map->getSurfaceCell(surfPos)->getResource();
|
||||
//if explored cell
|
||||
if(map->getSurfaceCell(surfPos)->isExplored(teamIndex)) {
|
||||
Resource *r= map->getSurfaceCell(surfPos)->getResource();
|
||||
|
||||
//if resource cell
|
||||
if(r != NULL && r->getType() == rt) {
|
||||
tmpDist= pos.dist(Vec2i(i, j));
|
||||
if(tmpDist < nearestDist) {
|
||||
anyResource= true;
|
||||
nearestDist= tmpDist;
|
||||
resultPos= Vec2i(i, j);
|
||||
//if resource cell
|
||||
if(r != NULL && r->getType() == rt) {
|
||||
tmpDist= pos.dist(Vec2i(i, j));
|
||||
if(tmpDist < nearestDist) {
|
||||
anyResource= true;
|
||||
nearestDist= tmpDist;
|
||||
resultPos= Vec2i(i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -80,6 +80,7 @@ public:
|
||||
const Unit *getOnSightUnit(int unitIndex);
|
||||
const FactionType *getMyFactionType();
|
||||
const TechTree *getTechTree();
|
||||
bool isResourceNear(const Vec2i &pos, const ResourceType *rt, Vec2i &resourcePos, Faction *faction, bool fallbackToPeersHarvestingSameResource) const;
|
||||
bool getNearestSightedResource(const ResourceType *rt, const Vec2i &pos, Vec2i &resultPos, bool usableResourceTypeOnly);
|
||||
bool isAlly(const Unit *unit) const;
|
||||
bool isAlly(int factionIndex) const;
|
||||
|
@ -1092,24 +1092,24 @@ AiRuleExpand::AiRuleExpand(Ai *ai):
|
||||
bool AiRuleExpand::test() {
|
||||
AiInterface *aiInterface = ai->getAiInterface();
|
||||
|
||||
for(int i= 0; i<aiInterface->getTechTree()->getResourceTypeCount(); ++i){
|
||||
int unitCount = aiInterface->getMyUnitCount();
|
||||
for(int i = 0; i < aiInterface->getTechTree()->getResourceTypeCount(); ++i) {
|
||||
const ResourceType *rt = aiInterface->getTechTree()->getResourceType(i);
|
||||
if(rt->getClass() == rcTech){
|
||||
if(rt->getClass() == rcTech) {
|
||||
// If any resource sighted
|
||||
if(aiInterface->getNearestSightedResource(rt, aiInterface->getHomeLocation(), expandPos, true)) {
|
||||
int minDistance= INT_MAX;
|
||||
storeType= NULL;
|
||||
|
||||
//If there is no close store
|
||||
for(int j=0; j < aiInterface->getMyUnitCount(); ++j) {
|
||||
for(int j=0; j < unitCount; ++j) {
|
||||
const Unit *u= aiInterface->getMyUnit(j);
|
||||
const UnitType *ut= aiInterface->getMyUnit(j)->getType();
|
||||
const UnitType *ut= u->getType();
|
||||
|
||||
// If this building is a store
|
||||
if(ut->getStore(rt) > 0) {
|
||||
storeType = ut;
|
||||
int distance= static_cast<int> (u->getPos().dist(expandPos));
|
||||
|
||||
if(distance < minDistance) {
|
||||
minDistance = distance;
|
||||
}
|
||||
|
@ -697,6 +697,8 @@ void Game::update() {
|
||||
scriptManager.getPlayerModifiers(i)->getAiEnabled() == true) {
|
||||
|
||||
aiInterfaces[i]->update();
|
||||
|
||||
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] i = %d, world.getFactionCount() = %d, took msecs: %lld [AI updates]\n",__FILE__,__FUNCTION__,__LINE__,i,world.getFactionCount(),chrono.getMillis());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -806,6 +806,77 @@ Vec2i Faction::getClosestResourceTypeTargetFromCache(Unit *unit, const ResourceT
|
||||
return result;
|
||||
}
|
||||
|
||||
Vec2i Faction::getClosestResourceTypeTargetFromCache(const Vec2i &pos, const ResourceType *type) {
|
||||
Vec2i result(-1);
|
||||
if(Config::getInstance().getBool("DisableCaching","false") == false) {
|
||||
if(cacheResourceTargetList.size() > 0) {
|
||||
std::vector<Vec2i> deleteList;
|
||||
|
||||
const int harvestDistance = 5;
|
||||
const Map *map = world->getMap();
|
||||
|
||||
bool foundCloseResource = false;
|
||||
// First look immediately around the given position
|
||||
for(int j = -harvestDistance; j <= harvestDistance && foundCloseResource == false; ++j) {
|
||||
for(int k = -harvestDistance; k <= harvestDistance && foundCloseResource == false; ++k) {
|
||||
Vec2i newPos = pos + Vec2i(j,k);
|
||||
if(map->isInside(newPos) == true && isResourceTargetInCache(newPos) == false) {
|
||||
const SurfaceCell *sc = map->getSurfaceCell(map->toSurfCoords(newPos));
|
||||
if( sc != NULL && sc->getResource() != NULL) {
|
||||
const Resource *resource = sc->getResource();
|
||||
if(resource->getType() != NULL && resource->getType() == type) {
|
||||
if(result.x < 0 || pos.dist(newPos) < pos.dist(result)) {
|
||||
result = newPos;
|
||||
foundCloseResource = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
deleteList.push_back(newPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(foundCloseResource == false) {
|
||||
// Now check the whole cache
|
||||
for(std::map<Vec2i,int>::iterator iter = cacheResourceTargetList.begin();
|
||||
iter != cacheResourceTargetList.end() && foundCloseResource == false;
|
||||
++iter) {
|
||||
const Vec2i &cache = iter->first;
|
||||
if(map->isInside(cache) == true) {
|
||||
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 || pos.dist(cache) < pos.dist(result)) {
|
||||
result = cache;
|
||||
// Close enough to our position, no more looking
|
||||
if(pos.dist(result) <= (harvestDistance * 2)) {
|
||||
foundCloseResource = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
deleteList.push_back(cache);
|
||||
}
|
||||
}
|
||||
else {
|
||||
deleteList.push_back(cache);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(deleteList.size() > 0) {
|
||||
cleanupResourceTypeTargetCache(&deleteList);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void Faction::cleanupResourceTypeTargetCache(std::vector<Vec2i> *deleteListPtr) {
|
||||
if(Config::getInstance().getBool("DisableCaching","false") == false) {
|
||||
if(cacheResourceTargetList.size() > 0) {
|
||||
|
@ -167,6 +167,7 @@ public:
|
||||
void removeResourceTargetFromCache(const Vec2i &pos);
|
||||
void addCloseResourceTargetToCache(const Vec2i &pos);
|
||||
Vec2i getClosestResourceTypeTargetFromCache(Unit *unit, const ResourceType *type);
|
||||
Vec2i getClosestResourceTypeTargetFromCache(const Vec2i &pos, const ResourceType *type);
|
||||
void cleanupResourceTypeTargetCache(std::vector<Vec2i> *deleteListPtr);
|
||||
|
||||
void deletePixels();
|
||||
|
@ -429,6 +429,8 @@ void UnitUpdater::updateBuild(Unit *unit) {
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||
|
||||
switch (tsValue) {
|
||||
case tsMoving:
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] tsMoving\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
@ -456,6 +458,8 @@ void UnitUpdater::updateBuild(Unit *unit) {
|
||||
throw runtime_error("detected unsupported pathfinder type!");
|
||||
}
|
||||
|
||||
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||
|
||||
if (canOccupyCell == true) {
|
||||
const UnitType *builtUnitType= command->getUnitType();
|
||||
CardinalDir facing = command->getFacing();
|
||||
@ -474,6 +478,8 @@ void UnitUpdater::updateBuild(Unit *unit) {
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||
|
||||
Vec2i buildPos = command->getPos();
|
||||
Unit *builtUnit= new Unit(world->getNextUnitId(unit->getFaction()), newpath, buildPos, builtUnitType, unit->getFaction(), world->getMap(), facing);
|
||||
|
||||
@ -501,6 +507,8 @@ void UnitUpdater::updateBuild(Unit *unit) {
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||
|
||||
switch(this->game->getGameSettings()->getPathFinderType()) {
|
||||
case pfBasic:
|
||||
break;
|
||||
@ -533,6 +541,7 @@ void UnitUpdater::updateBuild(Unit *unit) {
|
||||
}
|
||||
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] got BuildingNoPlace\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -545,10 +554,14 @@ void UnitUpdater::updateBuild(Unit *unit) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||
}
|
||||
else {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] tsArrived unit = %s\n",__FILE__,__FUNCTION__,__LINE__,unit->toString().c_str());
|
||||
|
||||
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||
|
||||
//if building
|
||||
Unit *builtUnit = map->getCell(unit->getTargetPos())->getUnit(fLand);
|
||||
if(builtUnit == NULL) {
|
||||
@ -574,6 +587,8 @@ void UnitUpdater::updateBuild(Unit *unit) {
|
||||
else if(builtUnit == NULL || builtUnit->repair()) {
|
||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||
|
||||
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||
|
||||
//building finished
|
||||
unit->finishCommand();
|
||||
unit->setCurrSkill(scStop);
|
||||
@ -586,6 +601,8 @@ void UnitUpdater::updateBuild(Unit *unit) {
|
||||
unit->getCurrVector(),
|
||||
gameCamera->getPos());
|
||||
}
|
||||
|
||||
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -244,6 +244,9 @@ void World::loadScenario(const string &path, Checksum *checksum){
|
||||
// ==================== misc ====================
|
||||
|
||||
void World::updateAllFactionUnits() {
|
||||
Chrono chrono;
|
||||
chrono.start();
|
||||
|
||||
scriptManager->onTimerTriggerEvent();
|
||||
//units
|
||||
int factionCount = getFactionCount();
|
||||
@ -254,6 +257,9 @@ void World::updateAllFactionUnits() {
|
||||
}
|
||||
|
||||
int unitCount = faction->getUnitCount();
|
||||
|
||||
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] i = %d, unitCount = %d, took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,i,unitCount,chrono.getMillis());
|
||||
|
||||
for(int j = 0; j < unitCount; ++j) {
|
||||
Unit *unit = faction->getUnit(j);
|
||||
if(unit == NULL) {
|
||||
@ -263,6 +269,8 @@ void World::updateAllFactionUnits() {
|
||||
unitUpdater.updateUnit(unit);
|
||||
}
|
||||
}
|
||||
|
||||
if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());
|
||||
}
|
||||
|
||||
void World::underTakeDeadFactionUnits() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user