mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Nullkiller: allow buy army through pathfinder
This commit is contained in:
parent
673d908c40
commit
3822d788e8
@ -202,7 +202,11 @@ ui64 ArmyManager::howManyReinforcementsCanBuy(const CCreatureSet * h, const CGDw
|
||||
|
||||
std::vector<creInfo> ArmyManager::getArmyAvailableToBuy(const CCreatureSet * hero, const CGDwelling * dwelling) const
|
||||
{
|
||||
auto availableRes = cb->getResourceAmount();
|
||||
return getArmyAvailableToBuy(hero, dwelling, cb->getResourceAmount());
|
||||
}
|
||||
|
||||
std::vector<creInfo> ArmyManager::getArmyAvailableToBuy(const CCreatureSet * hero, const CGDwelling * dwelling, TResources availableRes) const
|
||||
{
|
||||
std::vector<creInfo> creaturesInDwellings;
|
||||
int freeHeroSlots = GameConstants::ARMY_SIZE - hero->stacksCount();
|
||||
|
||||
|
@ -48,13 +48,14 @@ public:
|
||||
virtual std::vector<SlotInfo> getBestArmy(const IBonusBearer * armyCarrier, const CCreatureSet * target, const CCreatureSet * source) const = 0;
|
||||
virtual std::vector<SlotInfo>::iterator getWeakestCreature(std::vector<SlotInfo> & army) const = 0;
|
||||
virtual std::vector<SlotInfo> getSortedSlots(const CCreatureSet * target, const CCreatureSet * source) const = 0;
|
||||
virtual std::vector<creInfo> getArmyAvailableToBuy(const CCreatureSet * hero, const CGDwelling * dwelling) const = 0;
|
||||
virtual std::vector<creInfo> getArmyAvailableToBuy(const CCreatureSet * hero, const CGDwelling * dwelling, TResources availableRes) const = 0;
|
||||
virtual uint64_t evaluateStackPower(const CCreature * creature, int count) const = 0;
|
||||
virtual SlotInfo getTotalCreaturesAvailable(CreatureID creatureID) const = 0;
|
||||
virtual ArmyUpgradeInfo calculateCreateresUpgrade(
|
||||
const CCreatureSet * army,
|
||||
const CGObjectInstance * upgrader,
|
||||
const TResources & availableResources) const = 0;
|
||||
virtual std::vector<creInfo> getArmyAvailableToBuy(const CCreatureSet * hero, const CGDwelling * dwelling) const = 0;
|
||||
};
|
||||
|
||||
struct StackUpgradeInfo;
|
||||
@ -75,6 +76,7 @@ public:
|
||||
std::vector<SlotInfo> getBestArmy(const IBonusBearer * armyCarrier, const CCreatureSet * target, const CCreatureSet * source) const override;
|
||||
std::vector<SlotInfo>::iterator getWeakestCreature(std::vector<SlotInfo> & army) const override;
|
||||
std::vector<SlotInfo> getSortedSlots(const CCreatureSet * target, const CCreatureSet * source) const override;
|
||||
std::vector<creInfo> getArmyAvailableToBuy(const CCreatureSet * hero, const CGDwelling * dwelling, TResources availableRes) const override;
|
||||
std::vector<creInfo> getArmyAvailableToBuy(const CCreatureSet * hero, const CGDwelling * dwelling) const override;
|
||||
uint64_t evaluateStackPower(const CCreature * creature, int count) const override;
|
||||
SlotInfo getTotalCreaturesAvailable(CreatureID creatureID) const override;
|
||||
|
@ -7,6 +7,8 @@ set(VCAI_SRCS
|
||||
Pathfinding/Actors.cpp
|
||||
Pathfinding/Actions/SpecialAction.cpp
|
||||
Pathfinding/Actions/BattleAction.cpp
|
||||
Pathfinding/Actions/QuestAction.cpp
|
||||
Pathfinding/Actions/BuyArmyAction.cpp
|
||||
Pathfinding/Actions/BoatActions.cpp
|
||||
Pathfinding/Actions/TownPortalAction.cpp
|
||||
Pathfinding/Rules/AILayerTransitionRule.cpp
|
||||
@ -62,6 +64,8 @@ set(VCAI_HEADERS
|
||||
Pathfinding/Actors.h
|
||||
Pathfinding/Actions/SpecialAction.h
|
||||
Pathfinding/Actions/BattleAction.h
|
||||
Pathfinding/Actions/QuestAction.h
|
||||
Pathfinding/Actions/BuyArmyAction.h
|
||||
Pathfinding/Actions/BoatActions.h
|
||||
Pathfinding/Actions/TownPortalAction.h
|
||||
Pathfinding/Rules/AILayerTransitionRule.h
|
||||
|
@ -613,6 +613,12 @@ void AINodeStorage::addHeroChain(const std::vector<ExchangeCandidate> & result)
|
||||
exchangeNode->theNodeBefore = carrier;
|
||||
}
|
||||
|
||||
if(exchangeNode->actor->actorAction)
|
||||
{
|
||||
exchangeNode->theNodeBefore = carrier;
|
||||
exchangeNode->specialAction = exchangeNode->actor->actorAction;
|
||||
}
|
||||
|
||||
exchangeNode->chainOther = other;
|
||||
exchangeNode->armyLoss = chainInfo.armyLoss;
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
#pragma once
|
||||
|
||||
#define PATHFINDER_TRACE_LEVEL 0
|
||||
#define AI_TRACE_LEVEL 0
|
||||
#define AI_TRACE_LEVEL 2
|
||||
#define SCOUT_TURN_DISTANCE_LIMIT 3
|
||||
|
||||
#include "../../../lib/CPathfinder.h"
|
||||
|
@ -28,30 +28,4 @@ namespace AIPathfinding
|
||||
{
|
||||
return "Battle at " + targetTile.toString();
|
||||
}
|
||||
|
||||
bool QuestAction::canAct(const AIPathNode * node) const
|
||||
{
|
||||
if(questInfo.obj->ID == Obj::BORDER_GATE || questInfo.obj->ID == Obj::BORDERGUARD)
|
||||
{
|
||||
return dynamic_cast<const IQuestObject *>(questInfo.obj)->checkQuest(node->actor->hero);
|
||||
}
|
||||
|
||||
return questInfo.quest->progress == CQuest::NOT_ACTIVE
|
||||
|| questInfo.quest->checkQuest(node->actor->hero);
|
||||
}
|
||||
|
||||
Goals::TSubgoal QuestAction::decompose(const CGHeroInstance * hero) const
|
||||
{
|
||||
return Goals::sptr(Goals::CompleteQuest(questInfo));
|
||||
}
|
||||
|
||||
void QuestAction::execute(const CGHeroInstance * hero) const
|
||||
{
|
||||
ai->moveHeroToTile(questInfo.obj->visitablePos(), hero);
|
||||
}
|
||||
|
||||
std::string QuestAction::toString() const
|
||||
{
|
||||
return "Complete Quest";
|
||||
}
|
||||
}
|
@ -30,24 +30,4 @@ namespace AIPathfinding
|
||||
|
||||
virtual std::string toString() const override;
|
||||
};
|
||||
|
||||
class QuestAction : public SpecialAction
|
||||
{
|
||||
private:
|
||||
QuestInfo questInfo;
|
||||
|
||||
public:
|
||||
QuestAction(QuestInfo questInfo)
|
||||
:questInfo(questInfo)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool canAct(const AIPathNode * node) const override;
|
||||
|
||||
virtual Goals::TSubgoal decompose(const CGHeroInstance * hero) const override;
|
||||
|
||||
virtual void execute(const CGHeroInstance * hero) const override;
|
||||
|
||||
virtual std::string toString() const override;
|
||||
};
|
||||
}
|
31
AI/Nullkiller/Pathfinding/Actions/BuyArmyAction.cpp
Normal file
31
AI/Nullkiller/Pathfinding/Actions/BuyArmyAction.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* BattleAction.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 "BuyArmyAction.h"
|
||||
#include "../../VCAI.h"
|
||||
#include "../../Goals/CompleteQuest.h"
|
||||
#include "../../../../lib/mapping/CMap.h" //for victory conditions
|
||||
|
||||
extern boost::thread_specific_ptr<CCallback> cb;
|
||||
extern boost::thread_specific_ptr<VCAI> ai;
|
||||
|
||||
namespace AIPathfinding
|
||||
{
|
||||
void BuyArmyAction::execute(const CGHeroInstance * hero) const
|
||||
{
|
||||
ai->recruitCreatures(hero->visitedTown, hero);
|
||||
}
|
||||
|
||||
std::string BuyArmyAction::toString() const
|
||||
{
|
||||
return "Buy Army";
|
||||
}
|
||||
}
|
31
AI/Nullkiller/Pathfinding/Actions/BuyArmyAction.h
Normal file
31
AI/Nullkiller/Pathfinding/Actions/BuyArmyAction.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* BuyArmyAction.h, 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
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SpecialAction.h"
|
||||
#include "../../../../lib/CGameState.h"
|
||||
|
||||
namespace AIPathfinding
|
||||
{
|
||||
class BuyArmyAction : public SpecialAction
|
||||
{
|
||||
private:
|
||||
|
||||
public:
|
||||
bool canAct(const AIPathNode * source) const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void execute(const CGHeroInstance * hero) const override;
|
||||
std::string toString() const override;
|
||||
};
|
||||
}
|
47
AI/Nullkiller/Pathfinding/Actions/QuestAction.cpp
Normal file
47
AI/Nullkiller/Pathfinding/Actions/QuestAction.cpp
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* QuestAction.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 "QuestAction.h"
|
||||
#include "../../VCAI.h"
|
||||
#include "../../Goals/CompleteQuest.h"
|
||||
#include "../../../../lib/mapping/CMap.h" //for victory conditions
|
||||
|
||||
extern boost::thread_specific_ptr<CCallback> cb;
|
||||
extern boost::thread_specific_ptr<VCAI> ai;
|
||||
|
||||
namespace AIPathfinding
|
||||
{
|
||||
bool QuestAction::canAct(const AIPathNode * node) const
|
||||
{
|
||||
if(questInfo.obj->ID == Obj::BORDER_GATE || questInfo.obj->ID == Obj::BORDERGUARD)
|
||||
{
|
||||
return dynamic_cast<const IQuestObject *>(questInfo.obj)->checkQuest(node->actor->hero);
|
||||
}
|
||||
|
||||
return questInfo.quest->progress == CQuest::NOT_ACTIVE
|
||||
|| questInfo.quest->checkQuest(node->actor->hero);
|
||||
}
|
||||
|
||||
Goals::TSubgoal QuestAction::decompose(const CGHeroInstance * hero) const
|
||||
{
|
||||
return Goals::sptr(Goals::CompleteQuest(questInfo));
|
||||
}
|
||||
|
||||
void QuestAction::execute(const CGHeroInstance * hero) const
|
||||
{
|
||||
ai->moveHeroToTile(questInfo.obj->visitablePos(), hero);
|
||||
}
|
||||
|
||||
std::string QuestAction::toString() const
|
||||
{
|
||||
return "Complete Quest";
|
||||
}
|
||||
}
|
37
AI/Nullkiller/Pathfinding/Actions/QuestAction.h
Normal file
37
AI/Nullkiller/Pathfinding/Actions/QuestAction.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* QuestAction.h, 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
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SpecialAction.h"
|
||||
#include "../../../../lib/CGameState.h"
|
||||
|
||||
namespace AIPathfinding
|
||||
{
|
||||
class QuestAction : public SpecialAction
|
||||
{
|
||||
private:
|
||||
QuestInfo questInfo;
|
||||
|
||||
public:
|
||||
QuestAction(QuestInfo questInfo)
|
||||
:questInfo(questInfo)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool canAct(const AIPathNode * node) const override;
|
||||
|
||||
virtual Goals::TSubgoal decompose(const CGHeroInstance * hero) const override;
|
||||
|
||||
virtual void execute(const CGHeroInstance * hero) const override;
|
||||
|
||||
virtual std::string toString() const override;
|
||||
};
|
||||
}
|
@ -14,6 +14,7 @@
|
||||
#include "../../../CCallback.h"
|
||||
#include "../../../lib/mapping/CMap.h"
|
||||
#include "../../../lib/mapObjects/MapObjects.h"
|
||||
#include "Actions/BuyArmyAction.h"
|
||||
|
||||
CCreatureSet emptyArmy;
|
||||
|
||||
@ -22,9 +23,21 @@ bool HeroExchangeArmy::needsLastStack() const
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<SpecialAction> HeroExchangeArmy::getActorAction() const
|
||||
{
|
||||
std::shared_ptr<SpecialAction> result;
|
||||
|
||||
if(requireBuyArmy)
|
||||
{
|
||||
result.reset(new AIPathfinding::BuyArmyAction());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ChainActor::ChainActor(const CGHeroInstance * hero, HeroRole heroRole, uint64_t chainMask)
|
||||
:hero(hero), heroRole(heroRole), isMovable(true), chainMask(chainMask), creatureSet(hero),
|
||||
baseActor(this), carrierParent(nullptr), otherParent(nullptr), actorExchangeCount(1), armyCost()
|
||||
baseActor(this), carrierParent(nullptr), otherParent(nullptr), actorExchangeCount(1), armyCost(), actorAction()
|
||||
{
|
||||
initialPosition = hero->visitablePos();
|
||||
layer = hero->boat ? EPathfindingLayer::SAIL : EPathfindingLayer::LAND;
|
||||
@ -37,7 +50,7 @@ ChainActor::ChainActor(const CGHeroInstance * hero, HeroRole heroRole, uint64_t
|
||||
ChainActor::ChainActor(const ChainActor * carrier, const ChainActor * other, const CCreatureSet * heroArmy)
|
||||
:hero(carrier->hero), heroRole(carrier->heroRole), isMovable(true), creatureSet(heroArmy), chainMask(carrier->chainMask | other->chainMask),
|
||||
baseActor(this), carrierParent(carrier), otherParent(other), heroFightingStrength(carrier->heroFightingStrength),
|
||||
actorExchangeCount(carrier->actorExchangeCount + other->actorExchangeCount), armyCost(carrier->armyCost + other->armyCost)
|
||||
actorExchangeCount(carrier->actorExchangeCount + other->actorExchangeCount), armyCost(carrier->armyCost + other->armyCost), actorAction()
|
||||
{
|
||||
armyValue = heroArmy->getArmyStrength();
|
||||
}
|
||||
@ -45,7 +58,7 @@ ChainActor::ChainActor(const ChainActor * carrier, const ChainActor * other, con
|
||||
ChainActor::ChainActor(const CGObjectInstance * obj, const CCreatureSet * creatureSet, uint64_t chainMask, int initialTurn)
|
||||
:hero(nullptr), heroRole(HeroRole::MAIN), isMovable(false), creatureSet(creatureSet), chainMask(chainMask),
|
||||
baseActor(this), carrierParent(nullptr), otherParent(nullptr), initialTurn(initialTurn), initialMovement(0),
|
||||
heroFightingStrength(0), actorExchangeCount(1), armyCost()
|
||||
heroFightingStrength(0), actorExchangeCount(1), armyCost(), actorAction()
|
||||
{
|
||||
initialPosition = obj->visitablePos();
|
||||
layer = EPathfindingLayer::LAND;
|
||||
@ -82,11 +95,13 @@ HeroActor::HeroActor(const CGHeroInstance * hero, HeroRole heroRole, uint64_t ch
|
||||
HeroActor::HeroActor(
|
||||
const ChainActor * carrier,
|
||||
const ChainActor * other,
|
||||
const CCreatureSet * army,
|
||||
const HeroExchangeArmy * army,
|
||||
const Nullkiller * ai)
|
||||
:ChainActor(carrier, other, army)
|
||||
{
|
||||
exchangeMap = new HeroExchangeMap(this, ai);
|
||||
armyCost += army->armyCost;
|
||||
actorAction = army->getActorAction();
|
||||
setupSpecialActors();
|
||||
}
|
||||
|
||||
@ -104,6 +119,7 @@ void ChainActor::setBaseActor(HeroActor * base)
|
||||
isMovable = base->isMovable;
|
||||
heroFightingStrength = base->heroFightingStrength;
|
||||
armyCost = base->armyCost;
|
||||
actorAction = base->actorAction;
|
||||
}
|
||||
|
||||
void HeroActor::setupSpecialActors()
|
||||
@ -191,6 +207,12 @@ bool HeroExchangeMap::canExchange(const ChainActor * other)
|
||||
|
||||
if(other->creatureSet->Slots().size())
|
||||
reinforcment += ai->armyManager->howManyReinforcementsCanGet(actor->hero, actor->creatureSet, other->creatureSet);
|
||||
|
||||
auto obj = other->getActorObject();
|
||||
if(obj && obj->ID == Obj::TOWN)
|
||||
{
|
||||
reinforcment += ai->armyManager->howManyReinforcementsCanBuy(actor->creatureSet, ai->cb->getTown(obj->id));
|
||||
}
|
||||
|
||||
#if PATHFINDER_TRACE_LEVEL >= 2
|
||||
logAi->trace(
|
||||
@ -242,14 +264,16 @@ HeroActor * HeroExchangeMap::exchange(const ChainActor * other)
|
||||
else
|
||||
{
|
||||
TResources availableResources = ai->cb->getResourceAmount() - actor->armyCost - other->armyCost;
|
||||
CCreatureSet * upgradedInitialArmy = tryUpgrade(actor->creatureSet, other->getActorObject(), availableResources);
|
||||
CCreatureSet * newArmy;
|
||||
HeroExchangeArmy * upgradedInitialArmy = tryUpgrade(actor->creatureSet, other->getActorObject(), availableResources);
|
||||
HeroExchangeArmy * newArmy;
|
||||
|
||||
if(other->creatureSet->Slots().size())
|
||||
{
|
||||
if(upgradedInitialArmy)
|
||||
{
|
||||
newArmy = pickBestCreatures(upgradedInitialArmy, other->creatureSet);
|
||||
newArmy->armyCost = upgradedInitialArmy->armyCost;
|
||||
|
||||
delete upgradedInitialArmy;
|
||||
}
|
||||
else
|
||||
@ -263,34 +287,66 @@ HeroActor * HeroExchangeMap::exchange(const ChainActor * other)
|
||||
}
|
||||
|
||||
result = new HeroActor(actor, other, newArmy, ai);
|
||||
result->armyCost += newArmy->armyCost;
|
||||
exchangeMap[other] = result;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
CCreatureSet * HeroExchangeMap::tryUpgrade(const CCreatureSet * army, const CGObjectInstance * upgrader, TResources resources) const
|
||||
HeroExchangeArmy * HeroExchangeMap::tryUpgrade(
|
||||
const CCreatureSet * army,
|
||||
const CGObjectInstance * upgrader,
|
||||
TResources resources) const
|
||||
{
|
||||
HeroExchangeArmy * target = new HeroExchangeArmy();
|
||||
auto upgradeInfo = ai->armyManager->calculateCreateresUpgrade(army, upgrader, resources);
|
||||
|
||||
if(!upgradeInfo.upgradeValue)
|
||||
return nullptr;
|
||||
|
||||
CCreatureSet * target = new HeroExchangeArmy();
|
||||
|
||||
for(auto & slotInfo : upgradeInfo.resultingArmy)
|
||||
if(upgradeInfo.upgradeValue)
|
||||
{
|
||||
auto targetSlot = target->getFreeSlot();
|
||||
for(auto & slotInfo : upgradeInfo.resultingArmy)
|
||||
{
|
||||
auto targetSlot = target->getFreeSlot();
|
||||
|
||||
target->addToSlot(targetSlot, slotInfo.creature->idNumber, TQuantity(slotInfo.count));
|
||||
target->addToSlot(targetSlot, slotInfo.creature->idNumber, TQuantity(slotInfo.count));
|
||||
}
|
||||
|
||||
resources -= upgradeInfo.upgradeCost;
|
||||
target->armyCost += upgradeInfo.upgradeCost;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(auto slot : army->Slots())
|
||||
{
|
||||
auto targetSlot = target->getSlotFor(slot.second->getCreatureID());
|
||||
|
||||
target->addToSlot(targetSlot, slot.second->getCreatureID(), slot.second->count);
|
||||
}
|
||||
}
|
||||
|
||||
if(upgrader->ID == Obj::TOWN)
|
||||
{
|
||||
auto buyArmy = ai->armyManager->getArmyAvailableToBuy(target, ai->cb->getTown(upgrader->id), resources);
|
||||
|
||||
for(auto creatureToBuy : buyArmy)
|
||||
{
|
||||
auto targetSlot = target->getSlotFor(creatureToBuy.cre);
|
||||
|
||||
target->addToSlot(targetSlot, creatureToBuy.creID, creatureToBuy.count);
|
||||
target->armyCost += creatureToBuy.cre->cost * creatureToBuy.count;
|
||||
target->requireBuyArmy = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(target->getArmyStrength() <= army->getArmyStrength())
|
||||
return nullptr;
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
CCreatureSet * HeroExchangeMap::pickBestCreatures(const CCreatureSet * army1, const CCreatureSet * army2) const
|
||||
HeroExchangeArmy * HeroExchangeMap::pickBestCreatures(const CCreatureSet * army1, const CCreatureSet * army2) const
|
||||
{
|
||||
CCreatureSet * target = new HeroExchangeArmy();
|
||||
HeroExchangeArmy * target = new HeroExchangeArmy();
|
||||
auto bestArmy = ai->armyManager->getBestArmy(actor->hero, army1, army2);
|
||||
|
||||
for(auto & slotInfo : bestArmy)
|
||||
|
@ -21,7 +21,14 @@ class Nullkiller;
|
||||
class HeroExchangeArmy : public CCreatureSet
|
||||
{
|
||||
public:
|
||||
TResources armyCost;
|
||||
bool requireBuyArmy;
|
||||
virtual bool needsLastStack() const override;
|
||||
std::shared_ptr<SpecialAction> getActorAction() const;
|
||||
|
||||
HeroExchangeArmy() : CCreatureSet(), armyCost(), requireBuyArmy(false)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class ChainActor
|
||||
@ -37,6 +44,7 @@ public:
|
||||
bool allowUseResources;
|
||||
bool allowBattle;
|
||||
bool allowSpellCast;
|
||||
std::shared_ptr<SpecialAction> actorAction;
|
||||
const CGHeroInstance * hero;
|
||||
HeroRole heroRole;
|
||||
const CCreatureSet * creatureSet;
|
||||
@ -87,8 +95,8 @@ public:
|
||||
bool canExchange(const ChainActor * other);
|
||||
|
||||
private:
|
||||
CCreatureSet * pickBestCreatures(const CCreatureSet * army1, const CCreatureSet * army2) const;
|
||||
CCreatureSet * tryUpgrade(const CCreatureSet * army, const CGObjectInstance * upgrader, TResources resources) const;
|
||||
HeroExchangeArmy * pickBestCreatures(const CCreatureSet * army1, const CCreatureSet * army2) const;
|
||||
HeroExchangeArmy * tryUpgrade(const CCreatureSet * army, const CGObjectInstance * upgrader, TResources resources) const;
|
||||
};
|
||||
|
||||
class HeroActor : public ChainActor
|
||||
@ -107,7 +115,7 @@ public:
|
||||
// chain flags, can be combined meaning hero exchange and so on
|
||||
|
||||
HeroActor(const CGHeroInstance * hero, HeroRole heroRole, uint64_t chainMask, const Nullkiller * ai);
|
||||
HeroActor(const ChainActor * carrier, const ChainActor * other, const CCreatureSet * army, const Nullkiller * ai);
|
||||
HeroActor(const ChainActor * carrier, const ChainActor * other, const HeroExchangeArmy * army, const Nullkiller * ai);
|
||||
|
||||
virtual bool canExchange(const ChainActor * other) const override;
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "StdInc.h"
|
||||
#include "AIMovementAfterDestinationRule.h"
|
||||
#include "../Actions/BattleAction.h"
|
||||
#include "../Actions/QuestAction.h"
|
||||
#include "../../Goals/Invalid.h"
|
||||
#include "AIPreviousNodeRule.h"
|
||||
|
||||
|
@ -526,6 +526,7 @@ void VCAI::heroGotLevel(const CGHeroInstance * hero, PrimarySkill::PrimarySkill
|
||||
{
|
||||
if(hPtr.validAndSet())
|
||||
{
|
||||
nullkiller->heroManager->update();
|
||||
answerQuery(queryID, nullkiller->heroManager->selectBestSkill(hPtr, skills));
|
||||
}
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user