mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-24 08:32:34 +02:00
Nullkiller: fix/refactor temporary bonus nodes, fix gather army quest completion
This commit is contained in:
parent
ae67ef027a
commit
d47564955e
@ -407,7 +407,6 @@ bool shouldVisit(const Nullkiller * ai, const CGHeroInstance * h, const CGObject
|
||||
case Obj::BORDERGUARD: //open borderguard if possible
|
||||
return (dynamic_cast<const CGKeys *>(obj))->wasMyColorVisited(ai->playerID);
|
||||
case Obj::SEER_HUT:
|
||||
case Obj::QUEST_GUARD:
|
||||
{
|
||||
for(auto q : ai->cb->getMyQuests())
|
||||
{
|
||||
|
@ -85,8 +85,8 @@ class TemporaryArmy : public CArmedInstance
|
||||
public:
|
||||
void armyChanged() override {}
|
||||
TemporaryArmy()
|
||||
:CArmedInstance(true)
|
||||
{
|
||||
CBonusSystemNode::isHypotheticNode = true;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -162,17 +162,14 @@ TGoalVec CompleteQuest::missionHero() const
|
||||
|
||||
TGoalVec CompleteQuest::missionArmy() const
|
||||
{
|
||||
TGoalVec solutions = tryCompleteQuest();
|
||||
auto paths = ai->nullkiller->pathfinder->getPathInfo(q.obj->visitablePos());
|
||||
|
||||
if(!solutions.empty())
|
||||
return solutions;
|
||||
/*
|
||||
for(auto creature : q.quest->m6creatures)
|
||||
vstd::erase_if(paths, [&](const AIPath & path) -> bool
|
||||
{
|
||||
solutions.push_back(sptr(GatherTroops(creature.type->idNumber, creature.count)));
|
||||
}*/
|
||||
return !CQuest::checkMissionArmy(q.quest, path.heroArmy);
|
||||
});
|
||||
|
||||
return solutions;
|
||||
return CaptureObjectsBehavior::getVisitGoals(paths, q.obj);
|
||||
}
|
||||
|
||||
TGoalVec CompleteQuest::missionIncreasePrimaryStat() const
|
||||
|
@ -29,9 +29,8 @@ public:
|
||||
virtual bool needsLastStack() const override;
|
||||
std::shared_ptr<SpecialAction> getActorAction() const;
|
||||
|
||||
HeroExchangeArmy() : CArmedInstance(), armyCost(), requireBuyArmy(false)
|
||||
HeroExchangeArmy() : CArmedInstance(true), armyCost(), requireBuyArmy(false)
|
||||
{
|
||||
CBonusSystemNode::isHypotheticNode = true;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -536,21 +536,19 @@ CStackInstance::CStackInstance()
|
||||
}
|
||||
|
||||
CStackInstance::CStackInstance(CreatureID id, TQuantity Count, bool isHypothetic)
|
||||
: armyObj(_armyObj)
|
||||
: CBonusSystemNode(isHypothetic), armyObj(_armyObj)
|
||||
{
|
||||
init();
|
||||
setType(id);
|
||||
count = Count;
|
||||
CBonusSystemNode::isHypotheticNode = isHypothetic;
|
||||
}
|
||||
|
||||
CStackInstance::CStackInstance(const CCreature *cre, TQuantity Count, bool isHypothetic)
|
||||
: armyObj(_armyObj)
|
||||
: CBonusSystemNode(isHypothetic), armyObj(_armyObj)
|
||||
{
|
||||
init();
|
||||
setType(cre);
|
||||
count = Count;
|
||||
CBonusSystemNode::isHypotheticNode = isHypothetic;
|
||||
}
|
||||
|
||||
void CStackInstance::init()
|
||||
|
@ -989,12 +989,17 @@ std::shared_ptr<Bonus> CBonusSystemNode::update(const std::shared_ptr<Bonus> & b
|
||||
}
|
||||
|
||||
CBonusSystemNode::CBonusSystemNode()
|
||||
:CBonusSystemNode(false)
|
||||
{
|
||||
}
|
||||
|
||||
CBonusSystemNode::CBonusSystemNode(bool isHypotetic)
|
||||
: bonuses(true),
|
||||
exportedBonuses(true),
|
||||
nodeType(UNKNOWN),
|
||||
cachedLast(0),
|
||||
sync(),
|
||||
isHypotheticNode(false)
|
||||
isHypotheticNode(isHypotetic)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1015,17 +1020,20 @@ CBonusSystemNode::CBonusSystemNode(CBonusSystemNode && other):
|
||||
description(other.description),
|
||||
cachedLast(0),
|
||||
sync(),
|
||||
isHypotheticNode(false)
|
||||
isHypotheticNode(other.isHypotheticNode)
|
||||
{
|
||||
std::swap(parents, other.parents);
|
||||
std::swap(children, other.children);
|
||||
|
||||
//fixing bonus tree without recalculation
|
||||
|
||||
for(CBonusSystemNode * n : parents)
|
||||
if(!isHypothetic())
|
||||
{
|
||||
n->children -= &other;
|
||||
n->children.push_back(this);
|
||||
for(CBonusSystemNode * n : parents)
|
||||
{
|
||||
n->children -= &other;
|
||||
n->children.push_back(this);
|
||||
}
|
||||
}
|
||||
|
||||
for(CBonusSystemNode * n : children)
|
||||
|
@ -751,6 +751,7 @@ private:
|
||||
|
||||
ENodeTypes nodeType;
|
||||
std::string description;
|
||||
bool isHypotheticNode;
|
||||
|
||||
static const bool cachingEnabled;
|
||||
mutable BonusList cachedBonuses;
|
||||
@ -768,11 +769,9 @@ private:
|
||||
TConstBonusListPtr getAllBonusesWithoutCaching(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = nullptr) const;
|
||||
std::shared_ptr<Bonus> update(const std::shared_ptr<Bonus> & b) const;
|
||||
|
||||
protected:
|
||||
bool isHypotheticNode;
|
||||
|
||||
public:
|
||||
explicit CBonusSystemNode();
|
||||
explicit CBonusSystemNode(bool isHypotetic);
|
||||
explicit CBonusSystemNode(ENodeTypes NodeType);
|
||||
CBonusSystemNode(CBonusSystemNode && other);
|
||||
virtual ~CBonusSystemNode();
|
||||
|
@ -40,7 +40,12 @@ void CArmedInstance::randomizeArmy(int type)
|
||||
CSelector CArmedInstance::nonEvilAlignmentMixSelector = Selector::type()(Bonus::NONEVIL_ALIGNMENT_MIX);
|
||||
|
||||
CArmedInstance::CArmedInstance()
|
||||
:nonEvilAlignmentMix(this, nonEvilAlignmentMixSelector)
|
||||
:CArmedInstance(false)
|
||||
{
|
||||
}
|
||||
|
||||
CArmedInstance::CArmedInstance(bool isHypotetic)
|
||||
:CBonusSystemNode(isHypotetic), nonEvilAlignmentMix(this, nonEvilAlignmentMixSelector)
|
||||
{
|
||||
battle = nullptr;
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ public:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
CArmedInstance();
|
||||
CArmedInstance(bool isHypotetic);
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
|
@ -60,6 +60,33 @@ static std::string & visitedTxt(const bool visited)
|
||||
return VLC->generaltexth->allTexts[id];
|
||||
}
|
||||
|
||||
bool CQuest::checkMissionArmy(const CQuest * q, const CCreatureSet * army)
|
||||
{
|
||||
std::vector<CStackBasicDescriptor>::const_iterator cre;
|
||||
TSlots::const_iterator it;
|
||||
ui32 count;
|
||||
ui32 slotsCount = 0;
|
||||
bool hasExtraCreatures = false;
|
||||
for(cre = q->m6creatures.begin(); cre != q->m6creatures.end(); ++cre)
|
||||
{
|
||||
for(count = 0, it = army->Slots().begin(); it != army->Slots().end(); ++it)
|
||||
{
|
||||
if(it->second->type == cre->type)
|
||||
{
|
||||
count += it->second->count;
|
||||
slotsCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if((TQuantity)count < cre->count) //not enough creatures of this kind
|
||||
return false;
|
||||
|
||||
hasExtraCreatures |= (TQuantity)count > cre->count;
|
||||
}
|
||||
|
||||
return hasExtraCreatures || slotsCount < army->Slots().size();
|
||||
}
|
||||
|
||||
bool CQuest::checkQuest(const CGHeroInstance * h) const
|
||||
{
|
||||
switch (missionType)
|
||||
@ -91,29 +118,7 @@ bool CQuest::checkQuest(const CGHeroInstance * h) const
|
||||
}
|
||||
return true;
|
||||
case MISSION_ARMY:
|
||||
{
|
||||
std::vector<CStackBasicDescriptor>::const_iterator cre;
|
||||
TSlots::const_iterator it;
|
||||
ui32 count;
|
||||
ui32 slotsCount = 0;
|
||||
bool hasExtraCreatures = false;
|
||||
for(cre = m6creatures.begin(); cre != m6creatures.end(); ++cre)
|
||||
{
|
||||
for(count = 0, it = h->Slots().begin(); it != h->Slots().end(); ++it)
|
||||
{
|
||||
if(it->second->type == cre->type)
|
||||
{
|
||||
count += it->second->count;
|
||||
slotsCount++;
|
||||
}
|
||||
}
|
||||
if((TQuantity)count < cre->count) //not enough creatures of this kind
|
||||
return false;
|
||||
|
||||
hasExtraCreatures |= (TQuantity)count > cre->count;
|
||||
}
|
||||
return hasExtraCreatures || slotsCount < h->Slots().size();
|
||||
}
|
||||
return checkMissionArmy(this, h);
|
||||
case MISSION_RESOURCES:
|
||||
for(Res::ERes i = Res::WOOD; i <= Res::GOLD; vstd::advance(i, +1)) //including Mithril ?
|
||||
{ //Quest has no direct access to callback
|
||||
|
@ -52,6 +52,7 @@ public:
|
||||
CQuest();
|
||||
virtual ~CQuest(){};
|
||||
|
||||
static bool checkMissionArmy(const CQuest * q, const CCreatureSet * army);
|
||||
virtual bool checkQuest (const CGHeroInstance * h) const; //determines whether the quest is complete or not
|
||||
virtual void getVisitText (MetaString &text, std::vector<Component> &components, bool isCustom, bool FirstVisit, const CGHeroInstance * h = nullptr) const;
|
||||
virtual void getCompletionText (MetaString &text, std::vector<Component> &components, bool isCustom, const CGHeroInstance * h = nullptr) const;
|
||||
|
Loading…
Reference in New Issue
Block a user