mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Nullkiller: fix/refactor temporary bonus nodes, fix gather army quest completion
This commit is contained in:
		
				
					committed by
					
						 Andrii Danylchenko
						Andrii Danylchenko
					
				
			
			
				
	
			
			
			
						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; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user