| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- /*
- * ExecuteHeroChain.cpp, part of VCMI engine
- *
- * Authors: listed in file AUTHORS in main folder
- *
- * License: GNU General Public License v2.0 or later
- * Full text of license available in license.txt file, in main folder
- *
- */
- #include "StdInc.h"
- #include "ExecuteHeroChain.h"
- #include "VisitTile.h"
- #include "../VCAI.h"
- #include "../FuzzyHelper.h"
- #include "../AIhelper.h"
- #include "../../../lib/mapping/CMap.h" //for victory conditions
- #include "../../../lib/CPathfinder.h"
- #include "../Engine/Nullkiller.h"
- extern boost::thread_specific_ptr<CCallback> cb;
- extern boost::thread_specific_ptr<VCAI> ai;
- extern FuzzyHelper * fh;
- using namespace Goals;
- ExecuteHeroChain::ExecuteHeroChain(const AIPath & path, const CGObjectInstance * obj)
- :CGoal(Goals::EXECUTE_HERO_CHAIN), chainPath(path)
- {
- evaluationContext.danger = path.getTotalDanger(hero);
- evaluationContext.movementCost = path.movementCost();
- evaluationContext.armyLoss = path.armyLoss;
- evaluationContext.heroStrength = path.getHeroStrength();
- hero = path.targetHero;
- tile = path.targetTile();
- if(obj)
- {
- objid = obj->id.getNum();
- targetName = obj->getObjectName() + tile.toString();
- }
- else
- {
- targetName = "tile" + tile.toString();
- }
- }
- bool ExecuteHeroChain::operator==(const ExecuteHeroChain & other) const
- {
- return false;
- }
- TSubgoal ExecuteHeroChain::whatToDoToAchieve()
- {
- return iAmElementar();
- }
- void ExecuteHeroChain::accept(VCAI * ai)
- {
- logAi->debug("Executing hero chain towards %s. Path %s", targetName, chainPath.toString());
- std::set<int> blockedIndexes;
- for(int i = chainPath.nodes.size() - 1; i >= 0; i--)
- {
- auto & node = chainPath.nodes[i];
- HeroPtr hero = node.targetHero;
- if(vstd::contains(blockedIndexes, i))
- {
- blockedIndexes.insert(node.parentIndex);
- ai->nullkiller->lockHero(hero.get());
- continue;
- }
- logAi->debug("Executing chain node %d. Moving hero %s to %s", i, hero.name, node.coord.toString());
- try
- {
- if(hero->movement)
- {
- ai->nullkiller->setActive(hero.get());
- if(node.specialAction)
- {
- if(node.specialAction->canAct(hero.get()))
- {
- auto specialGoal = node.specialAction->whatToDo(hero);
- specialGoal->accept(ai);
- }
- else
- {
- //TODO: decompose
- }
- }
- Goals::VisitTile(node.coord).sethero(hero).accept(ai);
- }
- // no exception means we were not able to rich the tile
- ai->nullkiller->lockHero(hero.get());
- blockedIndexes.insert(node.parentIndex);
- }
- catch(goalFulfilledException)
- {
- if(!hero)
- {
- logAi->debug("Hero %s was killed while attempting to rich %s", hero.name, node.coord.toString());
- return;
- }
- }
- }
- }
- std::string ExecuteHeroChain::name() const
- {
- return "ExecuteHeroChain " + targetName;
- }
- std::string ExecuteHeroChain::completeMessage() const
- {
- return "Hero chain completed";
- }
|