mirror of
https://github.com/vcmi/vcmi.git
synced 2026-05-22 09:55:17 +02:00
Fuzzy rework, added more defence and gather army routines
This commit is contained in:
@@ -71,7 +71,7 @@ void BuyArmy::accept(AIGateway * ai)
|
||||
throw cannotFulfillGoalException("No creatures to buy.");
|
||||
}
|
||||
|
||||
if(town->visitingHero)
|
||||
if(town->visitingHero && !town->garrisonHero)
|
||||
{
|
||||
ai->moveHeroToTile(town->visitablePos(), town->visitingHero.get());
|
||||
}
|
||||
|
||||
@@ -31,9 +31,17 @@ std::string Composition::toString() const
|
||||
{
|
||||
std::string result = "Composition";
|
||||
|
||||
for(auto goal : subtasks)
|
||||
for(auto step : subtasks)
|
||||
{
|
||||
result += " " + goal->toString();
|
||||
result += "[";
|
||||
for(auto goal : step)
|
||||
{
|
||||
if(goal->isElementar())
|
||||
result += goal->toString() + " => ";
|
||||
else
|
||||
result += goal->toString() + ", ";
|
||||
}
|
||||
result += "] ";
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -41,17 +49,34 @@ std::string Composition::toString() const
|
||||
|
||||
void Composition::accept(AIGateway * ai)
|
||||
{
|
||||
taskptr(*subtasks.back())->accept(ai);
|
||||
for(auto task : subtasks.back())
|
||||
{
|
||||
if(task->isElementar())
|
||||
{
|
||||
taskptr(*task)->accept(ai);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TGoalVec Composition::decompose() const
|
||||
{
|
||||
return subtasks;
|
||||
TGoalVec result;
|
||||
|
||||
for(const TGoalVec & step : subtasks)
|
||||
vstd::concatenate(result, step);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Composition & Composition::addNext(const AbstractGoal & goal)
|
||||
Composition & Composition::addNextSequence(const TGoalVec & taskSequence)
|
||||
{
|
||||
return addNext(sptr(goal));
|
||||
subtasks.push_back(taskSequence);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Composition & Composition::addNext(TSubgoal goal)
|
||||
@@ -64,20 +89,35 @@ Composition & Composition::addNext(TSubgoal goal)
|
||||
}
|
||||
else
|
||||
{
|
||||
subtasks.push_back(goal);
|
||||
subtasks.push_back({goal});
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Composition & Composition::addNext(const AbstractGoal & goal)
|
||||
{
|
||||
return addNext(sptr(goal));
|
||||
}
|
||||
|
||||
bool Composition::isElementar() const
|
||||
{
|
||||
return subtasks.back()->isElementar();
|
||||
return subtasks.back().front()->isElementar();
|
||||
}
|
||||
|
||||
int Composition::getHeroExchangeCount() const
|
||||
{
|
||||
return isElementar() ? taskptr(*subtasks.back())->getHeroExchangeCount() : 0;
|
||||
auto result = 0;
|
||||
|
||||
for(auto task : subtasks.back())
|
||||
{
|
||||
if(task->isElementar())
|
||||
{
|
||||
result += taskptr(*task)->getHeroExchangeCount();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Goals
|
||||
class DLL_EXPORT Composition : public ElementarGoal<Composition>
|
||||
{
|
||||
private:
|
||||
TGoalVec subtasks;
|
||||
std::vector<TGoalVec> subtasks; // things we want to do now
|
||||
|
||||
public:
|
||||
Composition()
|
||||
@@ -26,16 +26,12 @@ namespace Goals
|
||||
{
|
||||
}
|
||||
|
||||
Composition(TGoalVec subtasks)
|
||||
: ElementarGoal(Goals::COMPOSITION), subtasks(subtasks)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool operator==(const Composition & other) const override;
|
||||
virtual std::string toString() const override;
|
||||
void accept(AIGateway * ai) override;
|
||||
Composition & addNext(const AbstractGoal & goal);
|
||||
Composition & addNext(TSubgoal goal);
|
||||
Composition & addNextSequence(const TGoalVec & taskSequence);
|
||||
virtual TGoalVec decompose() const override;
|
||||
virtual bool isElementar() const override;
|
||||
virtual int getHeroExchangeCount() const override;
|
||||
|
||||
@@ -52,6 +52,20 @@ void ExecuteHeroChain::accept(AIGateway * ai)
|
||||
ai->nullkiller->setActive(chainPath.targetHero, tile);
|
||||
ai->nullkiller->setTargetObject(objid);
|
||||
|
||||
auto targetObject = ai->myCb->getObj(static_cast<ObjectInstanceID>(objid), false);
|
||||
|
||||
if(chainPath.turn() == 0 && targetObject && targetObject->ID == Obj::TOWN)
|
||||
{
|
||||
auto relations = ai->myCb->getPlayerRelations(ai->playerID, targetObject->getOwner());
|
||||
|
||||
if(relations == PlayerRelations::ENEMIES)
|
||||
{
|
||||
ai->nullkiller->armyFormation->rearrangeArmyForSiege(
|
||||
dynamic_cast<const CGTownInstance *>(targetObject),
|
||||
chainPath.targetHero);
|
||||
}
|
||||
}
|
||||
|
||||
std::set<int> blockedIndexes;
|
||||
|
||||
for(int i = chainPath.nodes.size() - 1; i >= 0; i--)
|
||||
|
||||
@@ -24,7 +24,10 @@ using namespace Goals;
|
||||
|
||||
std::string RecruitHero::toString() const
|
||||
{
|
||||
return "Recruit hero at " + town->getNameTranslated();
|
||||
if(heroToBuy)
|
||||
return "Recruit " + heroToBuy->getNameTranslated() + " at " + town->getNameTranslated();
|
||||
else
|
||||
return "Recruit hero at " + town->getNameTranslated();
|
||||
}
|
||||
|
||||
void RecruitHero::accept(AIGateway * ai)
|
||||
@@ -45,20 +48,20 @@ void RecruitHero::accept(AIGateway * ai)
|
||||
throw cannotFulfillGoalException("No available heroes in tavern in " + t->nodeName());
|
||||
}
|
||||
|
||||
auto heroToHire = heroes[0];
|
||||
auto heroToHire = heroToBuy;
|
||||
|
||||
for(auto hero : heroes)
|
||||
if(!heroToHire)
|
||||
{
|
||||
if(objid == hero->id.getNum())
|
||||
for(auto hero : heroes)
|
||||
{
|
||||
heroToHire = hero;
|
||||
break;
|
||||
if(!heroToHire || hero->getTotalStrength() > heroToHire->getTotalStrength())
|
||||
heroToHire = hero;
|
||||
}
|
||||
|
||||
if(hero->getTotalStrength() > heroToHire->getTotalStrength())
|
||||
heroToHire = hero;
|
||||
}
|
||||
|
||||
if(!heroToHire)
|
||||
throw cannotFulfillGoalException("No hero to hire!");
|
||||
|
||||
if(t->visitingHero)
|
||||
{
|
||||
cb->swapGarrisonHero(t);
|
||||
|
||||
@@ -22,18 +22,20 @@ namespace Goals
|
||||
{
|
||||
class DLL_EXPORT RecruitHero : public ElementarGoal<RecruitHero>
|
||||
{
|
||||
private:
|
||||
const CGHeroInstance * heroToBuy;
|
||||
|
||||
public:
|
||||
RecruitHero(const CGTownInstance * townWithTavern, const CGHeroInstance * heroToBuy)
|
||||
: RecruitHero(townWithTavern)
|
||||
: ElementarGoal(Goals::RECRUIT_HERO), heroToBuy(heroToBuy)
|
||||
{
|
||||
objid = heroToBuy->id.getNum();
|
||||
town = townWithTavern;
|
||||
priority = 1;
|
||||
}
|
||||
|
||||
RecruitHero(const CGTownInstance * townWithTavern)
|
||||
: ElementarGoal(Goals::RECRUIT_HERO)
|
||||
: RecruitHero(townWithTavern, nullptr)
|
||||
{
|
||||
priority = 1;
|
||||
town = townWithTavern;
|
||||
}
|
||||
|
||||
virtual bool operator==(const RecruitHero & other) const override
|
||||
|
||||
Reference in New Issue
Block a user