mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Merge pull request #530 from dydzio0614/objRemovalFix
Extend objectRemoved callback to check parent goals and resource manager
This commit is contained in:
commit
efc53e8f8b
@ -88,6 +88,11 @@ bool AIhelper::hasTasksLeft() const
|
|||||||
return resourceManager->hasTasksLeft();
|
return resourceManager->hasTasksLeft();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AIhelper::removeOutdatedObjectives(std::function<bool(const Goals::TSubgoal&)> predicate)
|
||||||
|
{
|
||||||
|
return resourceManager->removeOutdatedObjectives(predicate);
|
||||||
|
}
|
||||||
|
|
||||||
bool AIhelper::canAfford(const TResources & cost) const
|
bool AIhelper::canAfford(const TResources & cost) const
|
||||||
{
|
{
|
||||||
return resourceManager->canAfford(cost);
|
return resourceManager->canAfford(cost);
|
||||||
|
@ -47,6 +47,7 @@ public:
|
|||||||
Goals::TSubgoal whatToDo() const override;
|
Goals::TSubgoal whatToDo() const override;
|
||||||
bool containsObjective(Goals::TSubgoal goal) const;
|
bool containsObjective(Goals::TSubgoal goal) const;
|
||||||
bool hasTasksLeft() const override;
|
bool hasTasksLeft() const override;
|
||||||
|
bool removeOutdatedObjectives(std::function<bool(const Goals::TSubgoal &)> predicate) override;
|
||||||
|
|
||||||
bool getBuildingOptions(const CGTownInstance * t) override;
|
bool getBuildingOptions(const CGTownInstance * t) override;
|
||||||
BuildingID getMaxPossibleGoldBuilding(const CGTownInstance * t);
|
BuildingID getMaxPossibleGoldBuilding(const CGTownInstance * t);
|
||||||
|
@ -232,22 +232,12 @@ bool ResourceManager::notifyGoalCompleted(Goals::TSubgoal goal)
|
|||||||
if (goal->invalid())
|
if (goal->invalid())
|
||||||
logAi->warn("Attempt to complete Invalid goal");
|
logAi->warn("Attempt to complete Invalid goal");
|
||||||
|
|
||||||
bool removedGoal = false;
|
std::function<bool(const Goals::TSubgoal &)> equivalentGoalsCheck = [goal](const Goals::TSubgoal & x) -> bool
|
||||||
while (true)
|
{
|
||||||
{ //unfortunatelly we can't use remove_if on heap
|
return x == goal || x->fulfillsMe(goal);
|
||||||
auto it = boost::find_if(queue, [goal](const ResourceObjective & ro) -> bool
|
};
|
||||||
{
|
|
||||||
return ro.goal == goal || ro.goal->fulfillsMe (goal);
|
bool removedGoal = removeOutdatedObjectives(equivalentGoalsCheck);
|
||||||
});
|
|
||||||
if(it != queue.end()) //removed at least one
|
|
||||||
{
|
|
||||||
logAi->debug("Removing goal %s from ResourceManager.", it->goal->name());
|
|
||||||
queue.erase(queue.s_handle_from_iterator(it));
|
|
||||||
removedGoal = true;
|
|
||||||
}
|
|
||||||
else //found nothing more to remove
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
dumpToLog();
|
dumpToLog();
|
||||||
|
|
||||||
@ -315,6 +305,27 @@ bool ResourceManager::hasTasksLeft() const
|
|||||||
return !queue.empty();
|
return !queue.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ResourceManager::removeOutdatedObjectives(std::function<bool(const Goals::TSubgoal &)> predicate)
|
||||||
|
{
|
||||||
|
bool removedAnything = false;
|
||||||
|
while(true)
|
||||||
|
{ //unfortunately we can't use remove_if on heap
|
||||||
|
auto it = boost::find_if(queue, [&](const ResourceObjective & ro) -> bool
|
||||||
|
{
|
||||||
|
predicate(ro.goal);
|
||||||
|
});
|
||||||
|
if(it != queue.end()) //removed at least one
|
||||||
|
{
|
||||||
|
logAi->debug("Removing goal %s from ResourceManager.", it->goal->name());
|
||||||
|
queue.erase(queue.s_handle_from_iterator(it));
|
||||||
|
removedAnything = true;
|
||||||
|
}
|
||||||
|
else //found nothing more to remove
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return removedAnything;
|
||||||
|
}
|
||||||
|
|
||||||
TResources ResourceManager::reservedResources() const
|
TResources ResourceManager::reservedResources() const
|
||||||
{
|
{
|
||||||
TResources res;
|
TResources res;
|
||||||
|
@ -52,7 +52,7 @@ public:
|
|||||||
virtual Goals::TSubgoal whatToDo(TResources &res, Goals::TSubgoal goal) = 0;
|
virtual Goals::TSubgoal whatToDo(TResources &res, Goals::TSubgoal goal) = 0;
|
||||||
virtual bool containsObjective(Goals::TSubgoal goal) const = 0;
|
virtual bool containsObjective(Goals::TSubgoal goal) const = 0;
|
||||||
virtual bool hasTasksLeft() const = 0;
|
virtual bool hasTasksLeft() const = 0;
|
||||||
private:
|
virtual bool removeOutdatedObjectives(std::function<bool(const Goals::TSubgoal &)> predicate) = 0; //remove ResourceObjectives from queue if ResourceObjective->goal meets specific criteria
|
||||||
virtual bool notifyGoalCompleted(Goals::TSubgoal goal) = 0;
|
virtual bool notifyGoalCompleted(Goals::TSubgoal goal) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -82,6 +82,7 @@ public:
|
|||||||
Goals::TSubgoal whatToDo(TResources & res, Goals::TSubgoal goal); //can we afford this goal or need to CollectRes?
|
Goals::TSubgoal whatToDo(TResources & res, Goals::TSubgoal goal); //can we afford this goal or need to CollectRes?
|
||||||
bool containsObjective(Goals::TSubgoal goal) const;
|
bool containsObjective(Goals::TSubgoal goal) const;
|
||||||
bool hasTasksLeft() const override;
|
bool hasTasksLeft() const override;
|
||||||
|
bool removeOutdatedObjectives(std::function<bool(const Goals::TSubgoal &)> predicate) override;
|
||||||
|
|
||||||
protected: //not-const actions only for AI
|
protected: //not-const actions only for AI
|
||||||
virtual void reserveResoures(const TResources & res, Goals::TSubgoal goal = Goals::TSubgoal());
|
virtual void reserveResoures(const TResources & res, Goals::TSubgoal goal = Goals::TSubgoal());
|
||||||
|
@ -418,37 +418,36 @@ void VCAI::objectRemoved(const CGObjectInstance * obj)
|
|||||||
for(auto h : cb->getHeroesInfo())
|
for(auto h : cb->getHeroesInfo())
|
||||||
unreserveObject(h, obj);
|
unreserveObject(h, obj);
|
||||||
|
|
||||||
|
std::function<bool(const Goals::TSubgoal &)> checkRemovalValidity = [&](const Goals::TSubgoal & x) -> bool
|
||||||
vstd::erase_if(lockedHeroes, [&](const std::pair<HeroPtr, Goals::TSubgoal> & x) -> bool
|
|
||||||
{
|
|
||||||
if((x.second->goalType == Goals::VISIT_OBJ) && (x.second->objid == obj->id.getNum()))
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
vstd::erase_if(ultimateGoalsFromBasic, [&](const std::pair<Goals::TSubgoal, Goals::TGoalVec> & x) -> bool
|
|
||||||
{
|
|
||||||
if((x.first->goalType == Goals::VISIT_OBJ) && (x.first->objid == obj->id.getNum()))
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
auto goalErasePredicate = [&](const Goals::TSubgoal & x) ->bool
|
|
||||||
{
|
{
|
||||||
if((x->goalType == Goals::VISIT_OBJ) && (x->objid == obj->id.getNum()))
|
if((x->goalType == Goals::VISIT_OBJ) && (x->objid == obj->id.getNum()))
|
||||||
return true;
|
return true;
|
||||||
|
else if(x->parent && checkRemovalValidity(x->parent)) //repeat this lambda check recursively on parent goal
|
||||||
|
return true;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
vstd::erase_if(basicGoals, goalErasePredicate);
|
//clear VCAI / main loop caches
|
||||||
vstd::erase_if(goalsToAdd, goalErasePredicate);
|
vstd::erase_if(lockedHeroes, [&](const std::pair<HeroPtr, Goals::TSubgoal> & x) -> bool
|
||||||
vstd::erase_if(goalsToRemove, goalErasePredicate);
|
{
|
||||||
|
return checkRemovalValidity(x.second);
|
||||||
|
});
|
||||||
|
|
||||||
|
vstd::erase_if(ultimateGoalsFromBasic, [&](const std::pair<Goals::TSubgoal, Goals::TGoalVec> & x) -> bool
|
||||||
|
{
|
||||||
|
return checkRemovalValidity(x.first);
|
||||||
|
});
|
||||||
|
|
||||||
|
vstd::erase_if(basicGoals, checkRemovalValidity);
|
||||||
|
vstd::erase_if(goalsToAdd, checkRemovalValidity);
|
||||||
|
vstd::erase_if(goalsToRemove, checkRemovalValidity);
|
||||||
|
|
||||||
for(auto goal : ultimateGoalsFromBasic)
|
for(auto goal : ultimateGoalsFromBasic)
|
||||||
vstd::erase_if(goal.second, goalErasePredicate);
|
vstd::erase_if(goal.second, checkRemovalValidity);
|
||||||
|
|
||||||
|
//clear resource manager goal cache
|
||||||
|
ah->removeOutdatedObjectives(checkRemovalValidity);
|
||||||
|
|
||||||
//TODO: Find better way to handle hero boat removal
|
//TODO: Find better way to handle hero boat removal
|
||||||
if(auto hero = dynamic_cast<const CGHeroInstance *>(obj))
|
if(auto hero = dynamic_cast<const CGHeroInstance *>(obj))
|
||||||
|
Loading…
Reference in New Issue
Block a user