Sfoglia il codice sorgente

Extract spell layers processing into separate method

Dydzio 1 anno fa
parent
commit
5dac8e2bbf

+ 57 - 51
server/battles/BattleActionProcessor.cpp

@@ -1123,58 +1123,8 @@ void BattleActionProcessor::attackCasting(const CBattleInfoCallback & battle, bo
 {
 	if(attacker->hasBonusOfType(attackMode))
 	{
-		std::set<SpellID> spellsToCast;
-
-		const int unlayeredItemsInternalLayer = -1;
 		TConstBonusListPtr spells = attacker->getBonuses(Selector::type()(attackMode));
-
-		std::map<int, std::vector<std::shared_ptr<Bonus>>> spellsWithBackupLayers;
-
-		for(int i = 0; i < spells->size(); i++)
-		{
-			std::shared_ptr<Bonus> bonus = spells->operator[](i);
-			int layer = bonus->additionalInfo[2];
-			vstd::amax(layer, -1);
-			spellsWithBackupLayers[layer].push_back(bonus);
-		}
-
-		auto addSpellsFromLayer = [&](int layer) -> void
-		{
-			assert(spellsWithBackupLayers.find(layer) != spellsWithBackupLayers.end());
-
-			for(const auto & spell : spellsWithBackupLayers[layer])
-			{
-				if (spell->subtype.as<SpellID>() != SpellID())
-					spellsToCast.insert(spell->subtype.as<SpellID>());
-				else
-					logGlobal->error("Invalid spell to cast during attack!");
-			}
-		};
-
-		if(spellsWithBackupLayers.find(unlayeredItemsInternalLayer) != spellsWithBackupLayers.end())
-		{
-			addSpellsFromLayer(unlayeredItemsInternalLayer);
-			spellsWithBackupLayers.erase(unlayeredItemsInternalLayer);
-		}
-
-		for(auto item : spellsWithBackupLayers)
-		{
-			if(item.first < spellsWithBackupLayers.rbegin()->first)
-			{
-				bool areCurrentLayerSpellsApplied = std::all_of(item.second.begin(), item.second.end(),
-					[&](const std::shared_ptr<Bonus> spell)
-					{
-						std::vector<SpellID> activeSpells = defender->activeSpells();
-						return vstd::find(activeSpells, spell->subtype.as<SpellID>()) != activeSpells.end();
-					});
-
-				if(areCurrentLayerSpellsApplied)
-					continue;
-			}
-
-			addSpellsFromLayer(item.first);
-			break;
-		}
+		std::set<SpellID> spellsToCast = getSpellsForAttackCasting(spells, defender);
 
 		for(SpellID spellID : spellsToCast)
 		{
@@ -1234,6 +1184,62 @@ void BattleActionProcessor::attackCasting(const CBattleInfoCallback & battle, bo
 	}
 }
 
+std::set<SpellID> BattleActionProcessor::getSpellsForAttackCasting(TConstBonusListPtr spells, const CStack *defender)
+{
+	std::set<SpellID> spellsToCast;
+	constexpr int unlayeredItemsInternalLayer = -1;
+
+	std::map<int, std::vector<std::shared_ptr<Bonus>>> spellsWithBackupLayers;
+
+	for(int i = 0; i < spells->size(); i++)
+	{
+		std::shared_ptr<Bonus> bonus = spells->operator[](i);
+		int layer = bonus->additionalInfo[2];
+		vstd::amax(layer, -1);
+		spellsWithBackupLayers[layer].push_back(bonus);
+	}
+
+	auto addSpellsFromLayer = [&](int layer) -> void
+	{
+		assert(spellsWithBackupLayers.find(layer) != spellsWithBackupLayers.end());
+
+		for(const auto & spell : spellsWithBackupLayers[layer])
+		{
+			if (spell->subtype.as<SpellID>() != SpellID())
+				spellsToCast.insert(spell->subtype.as<SpellID>());
+			else
+				logGlobal->error("Invalid spell to cast during attack!");
+		}
+	};
+
+	if(spellsWithBackupLayers.find(unlayeredItemsInternalLayer) != spellsWithBackupLayers.end())
+	{
+		addSpellsFromLayer(unlayeredItemsInternalLayer);
+		spellsWithBackupLayers.erase(unlayeredItemsInternalLayer);
+	}
+
+	for(auto item : spellsWithBackupLayers)
+	{
+		if(item.first < spellsWithBackupLayers.rbegin()->first)
+		{
+			bool areCurrentLayerSpellsApplied = std::all_of(item.second.begin(), item.second.end(),
+				[&](const std::shared_ptr<Bonus> spell)
+				{
+					std::vector<SpellID> activeSpells = defender->activeSpells();
+					return vstd::find(activeSpells, spell->subtype.as<SpellID>()) != activeSpells.end();
+				});
+
+			if(areCurrentLayerSpellsApplied)
+				continue;
+		}
+
+		addSpellsFromLayer(item.first);
+		break;
+	}
+
+	return spellsToCast;
+}
+
 void BattleActionProcessor::handleAttackBeforeCasting(const CBattleInfoCallback & battle, bool ranged, const CStack * attacker, const CStack * defender)
 {
 	attackCasting(battle, ranged, BonusType::SPELL_BEFORE_ATTACK, attacker, defender); //no death stare / acid breath needed?

+ 3 - 0
server/battles/BattleActionProcessor.h

@@ -8,6 +8,7 @@
  *
  */
 #pragma once
+#include "bonuses/BonusList.h"
 
 VCMI_LIB_NAMESPACE_BEGIN
 
@@ -45,6 +46,8 @@ class BattleActionProcessor : boost::noncopyable
 	void handleAttackBeforeCasting(const CBattleInfoCallback & battle, bool ranged, const CStack * attacker, const CStack * defender);
 	void handleAfterAttackCasting(const CBattleInfoCallback & battle, bool ranged, const CStack * attacker, const CStack * defender);
 	void attackCasting(const CBattleInfoCallback & battle, bool ranged, BonusType attackMode, const battle::Unit * attacker, const CStack * defender);
+	
+	std::set<SpellID> getSpellsForAttackCasting(TConstBonusListPtr spells, const CStack *defender);
 
 	// damage, drain life & fire shield; returns amount of drained life
 	int64_t applyBattleEffects(const CBattleInfoCallback & battle, BattleAttack & bat, std::shared_ptr<battle::CUnitState> attackerState, FireShieldInfo & fireShield, const CStack * def, int distance, bool secondary);