Prechádzať zdrojové kódy

Support all spell target types (except NO_TARGET) for creature casting.

AlexVinS 9 rokov pred
rodič
commit
b7509f588f

+ 31 - 27
client/battle/CBattleInterface.cpp

@@ -1366,25 +1366,11 @@ void CBattleInterface::battleStacksEffectsSet(const SetStackEffect & sse)
 	}
 }
 
-void CBattleInterface::castThisSpell(SpellID spellID)
+CBattleInterface::PossibleActions CBattleInterface::getCasterAction(const CSpell * spell, const ISpellCaster * caster) const
 {
-	auto  ba = new BattleAction;
-	ba->actionType = Battle::HERO_SPELL;
-	ba->additionalInfo = spellID; //spell number
-	ba->destinationTile = -1;
-	ba->stackNumber = (attackingHeroInstance->tempOwner == curInt->playerID) ? -1 : -2;
-	ba->side = defendingHeroInstance ? (curInt->playerID == defendingHeroInstance->tempOwner) : false;
-	spellToCast = ba;
-	spellDestSelectMode = true;
-	creatureCasting = false;
-
-	//choosing possible tragets
-	const CGHeroInstance * castingHero = (attackingHeroInstance->tempOwner == curInt->playerID) ? attackingHeroInstance : defendingHeroInstance;
-	assert(castingHero); // code below assumes non-null hero
-	sp = spellID.toSpell();
 	PossibleActions spellSelMode = ANY_LOCATION;
 
-	const CSpell::TargetInfo ti(sp, castingHero->getSpellSchoolLevel(sp));
+	const CSpell::TargetInfo ti(spell, caster->getSpellSchoolLevel(spell));
 
 	if(ti.massive || ti.type == CSpell::NO_TARGET)
 		spellSelMode = NO_LOCATION;
@@ -1401,6 +1387,27 @@ void CBattleInterface::castThisSpell(SpellID spellID)
 		spellSelMode = OBSTACLE;
 	}
 
+	return spellSelMode;
+}
+
+void CBattleInterface::castThisSpell(SpellID spellID)
+{
+	auto  ba = new BattleAction;
+	ba->actionType = Battle::HERO_SPELL;
+	ba->additionalInfo = spellID; //spell number
+	ba->destinationTile = -1;
+	ba->stackNumber = (attackingHeroInstance->tempOwner == curInt->playerID) ? -1 : -2;
+	ba->side = defendingHeroInstance ? (curInt->playerID == defendingHeroInstance->tempOwner) : false;
+	spellToCast = ba;
+	spellDestSelectMode = true;
+	creatureCasting = false;
+
+	//choosing possible tragets
+	const CGHeroInstance * castingHero = (attackingHeroInstance->tempOwner == curInt->playerID) ? attackingHeroInstance : defendingHeroInstance;
+	assert(castingHero); // code below assumes non-null hero
+	sp = spellID.toSpell();
+	PossibleActions spellSelMode = getCasterAction(sp, castingHero);
+
 	if (spellSelMode == NO_LOCATION) //user does not have to select location
 	{
 		spellToCast->destinationTile = -1;
@@ -1631,17 +1638,14 @@ void CBattleInterface::getPossibleActionsForStack(const CStack * stack)
 				BonusList spellBonuses = *stack->getBonuses (Selector::type(Bonus::SPELLCASTER));
 				for (Bonus * spellBonus : spellBonuses)
 				{
-					spell = CGI->spellh->objects[spellBonus->subtype];
-					switch (spell->id)
-					{
-						case SpellID::REMOVE_OBSTACLE:
-							possibleActions.push_back (OBSTACLE);
-							break;
-						default:
-							possibleActions.push_back (AIMED_SPELL_CREATURE);
-							break;
-					}
+					spell = SpellID(spellBonus->subtype).toSpell();
 
+					PossibleActions act = getCasterAction(spell, stack);
+
+					if(act == NO_LOCATION)
+						logGlobal->error("NO_LOCATION action target is not yet supported for creatures");
+					else
+						possibleActions.push_back(act);
 				}
 				std::sort(possibleActions.begin(), possibleActions.end());
 				auto it = std::unique (possibleActions.begin(), possibleActions.end());
@@ -2432,7 +2436,7 @@ bool CBattleInterface::isCastingPossibleHere (const CStack * sactive, const CSta
 
 	if (sp)
 	{
-		const ISpellCaster * caster = creatureCasting ? dynamic_cast<const ISpellCaster *>(sactive) : dynamic_cast<const ISpellCaster *>(curInt->cb->battleGetMyHero());
+		const ISpellCaster * caster = creatureCasting ? static_cast<const ISpellCaster *>(sactive) : static_cast<const ISpellCaster *>(curInt->cb->battleGetMyHero());
 		if(caster == nullptr)
 		{
 			isCastingPossible = false;//just in case

+ 1 - 0
client/battle/CBattleInterface.h

@@ -259,6 +259,7 @@ private:
 	void redrawBackgroundWithHexes(const CStack * activeStack);
 	/** End of battle screen blitting methods */
 
+	PossibleActions getCasterAction(const CSpell * spell, const ISpellCaster * caster) const;
 public:
 	std::list<std::pair<CBattleAnimation *, bool> > pendingAnims; //currently displayed animations <anim, initialized>
 	void addNewAnim(CBattleAnimation * anim); //adds new anim to pendingAnims