浏览代码

Fixes for r2543.

DjWarmonger 13 年之前
父节点
当前提交
5e14d17ed3
共有 5 个文件被更改,包括 39 次插入27 次删除
  1. 20 23
      client/BattleInterface/CBattleInterface.cpp
  2. 4 2
      lib/BattleState.cpp
  3. 1 1
      lib/CObjectHandler.cpp
  4. 12 0
      lib/IGameCallback.cpp
  5. 2 1
      lib/IGameCallback.h

+ 20 - 23
client/BattleInterface/CBattleInterface.cpp

@@ -954,7 +954,7 @@ void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
 							if (shere != sactive) //can't cast on itself
 							{
 								const CSpell * spell =  CGI->spellh->spells[creatureSpellToCast];
-								if (curInt->cb->battleCanCastThisSpell(spell, BattleHex(myNumber)) == ESpellCastProblem::OK)
+								if (curInt->cb->battleCanCreatureCastThisSpell(spell, BattleHex(myNumber)) == ESpellCastProblem::OK)
 								{
 									if ((!spell->isNegative() && ourStack) || (!spell->isPositive() && !ourStack))
 									{
@@ -1159,7 +1159,8 @@ void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
 			case SpellSelectionType::ANY_LOCATION:
 					CCS->curh->changeGraphic(3, 0);
 					//setting console text
-					consoleMsg += CGI->generaltexth->allTexts[26] += CGI->spellh->spells[spellToCast->additionalInfo]->name;
+					consoleMsg += CGI->generaltexth->allTexts[26];
+					boost::replace_first (consoleMsg, "%s", CGI->spellh->spells[spellToCast->additionalInfo]->name);
 					console->alterText (consoleMsg);
 					console->whoSetAlter = 0;
 					break;
@@ -1169,12 +1170,13 @@ void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
 					if( potentialTargetStack )
 					{
 						if (curInt->cb->battleCanCastThisSpell (CGI->spellh->spells[spellToCast->additionalInfo], BattleHex(myNumber)))
-							CCS->curh->changeGraphic(3, 0);
-						else
 							CCS->curh->changeGraphic(1, 0);
+						else
+							CCS->curh->changeGraphic(3, 0);
 						//setting console text
-						consoleMsg += CGI->generaltexth->allTexts[27] += CGI->spellh->spells[spellToCast->additionalInfo]->name;
-						consoleMsg += stackUnder->getName();
+						consoleMsg += CGI->generaltexth->allTexts[27];
+						boost::replace_first (consoleMsg, "%s", CGI->spellh->spells[spellToCast->additionalInfo]->name);
+						boost::replace_first (consoleMsg, "%s", stackUnder->getName());
 						console->alterText (consoleMsg);
 						console->whoSetAlter = 0;
 						break;
@@ -1759,15 +1761,9 @@ void CBattleInterface::hexLclicked(int whichOne)
 			switch(spellSelMode)
 			{
 			case FRIENDLY_CREATURE:
-				if(!curInt->cb->battleGetStackByPos(whichOne, onlyAlive) || curInt->playerID != dest->owner )
-					allowCasting = false;
-				break;
 			case HOSTILE_CREATURE:
-				if(!curInt->cb->battleGetStackByPos(whichOne, onlyAlive) || curInt->playerID == dest->owner )
-					allowCasting = false;
-				break;
 			case ANY_CREATURE:
-				if(!curInt->cb->battleGetStackByPos(whichOne, onlyAlive))
+				if (curInt->cb->battleCanCastThisSpell (CGI->spellh->spells[spellToCast->additionalInfo], BattleHex(whichOne)) != ESpellCastProblem::OK)
 					allowCasting = false;
 				break;
 			case OBSTACLE:
@@ -1801,21 +1797,22 @@ void CBattleInterface::hexLclicked(int whichOne)
 				//try to cast stack spell first
 				if (stackCanCastSpell && spellSelMode > STACK_SPELL_CANCELLED) //player did not decide to cancel this spell
 				{
-					if ((int)creatureSpellToCast > -1) //use randomized spell (Faerie Dragon), or only avaliable spell (Archangel)
+					if (dest != actSt) //can't cast on itself
 					{
-						const CSpell * spell =  CGI->spellh->spells[creatureSpellToCast];
-						if (curInt->cb->battleCanCastThisSpell(spell, BattleHex(whichOne)) == ESpellCastProblem::OK)
+						if ((int)creatureSpellToCast > -1) //use randomized spell (Faerie Dragon), or only avaliable spell (Archangel)
 						{
-							if ((!spell->isNegative() && ourStack) || (!spell->isPositive() && !ourStack))
+							const CSpell * spell =  CGI->spellh->spells[creatureSpellToCast];
+
+							if (curInt->cb->battleCanCastThisSpell(spell, BattleHex(whichOne)) == ESpellCastProblem::OK)
 							{
-								giveCommand(BattleAction::MONSTER_SPELL, whichOne, actSt->ID, creatureSpellToCast);
-								spellCast = true;
+								if ((!spell->isNegative() && ourStack) || (!spell->isPositive() && !ourStack))
+								{
+									giveCommand(BattleAction::MONSTER_SPELL, whichOne, actSt->ID, creatureSpellToCast);
+									spellCast = true;
+								}
 							}
 						}
-					}
-					else if (ourStack) //must have only random positive spell (genie)
-					{
-						if (dest != actSt) //can't cast on itself
+						else if (ourStack) //must have only random positive spell (genie)
 						{
 							int spellID = curInt->cb->battleGetRandomStackSpell(dest, CBattleInfoCallback::RANDOM_GENIE);
 							if (spellID > -1) //can cast any spell on target stack

+ 4 - 2
lib/BattleState.cpp

@@ -2120,9 +2120,11 @@ ESpellCastProblem::ESpellCastProblem BattleInfo::battleIsImmune(const CGHeroInst
 			case Spells::TELEPORT:
 			case Spells::CLONE:
 				if (subject->hasBonusOfType(Bonus::SIEGE_WEAPON))
-					return ESpellCastProblem::STACK_IMMUNE_TO_SPELL; //war machines are mmune to some spells than involve movement
-				if (spell->id == Spells::CLONE)
+					return ESpellCastProblem::STACK_IMMUNE_TO_SPELL; //war machines are immune to some spells than involve movement
+				if (spell->id == Spells::CLONE && caster) //TODO: how about stacks casting Clone?
 				{
+					if (vstd::contains(subject->state, EBattleStackState::CLONED))
+						return ESpellCastProblem::STACK_IMMUNE_TO_SPELL; //can't clone already cloned creature
 					int maxLevel = (std::max(caster->getSpellSchoolLevel(spell), (ui8)1) + 4);
 					int creLevel = subject->getCreature()->level;
 					if (maxLevel < creLevel) //tier 1-5 for basic, 1-6 for advanced, 1-7 for expert

+ 1 - 1
lib/CObjectHandler.cpp

@@ -3012,7 +3012,7 @@ void CGCreature::newTurn() const
 		cb->setObjProperty(id, ObjProperty::MONSTER_POWER, power); //increase temppower
 	}
 	if (GameConstants::STACK_EXP)
-		cb->setObjProperty(id, ObjProperty::MONSTER_EXP, 10000); //for testing purpose
+		cb->setObjProperty(id, ObjProperty::MONSTER_EXP, 500); //for testing purpose
 }
 void CGCreature::setPropertyDer(ui8 what, ui32 val)
 {

+ 12 - 0
lib/IGameCallback.cpp

@@ -116,6 +116,18 @@ ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCastThisSpell
 		return ESpellCastProblem::NO_HERO_TO_CAST_SPELL;
 	}
 
+	return gs->curB->battleCanCastThisSpellHere(player, spell, ECastingMode::HERO_CASTING, destination);
+}
+
+ESpellCastProblem::ESpellCastProblem CBattleInfoCallback::battleCanCreatureCastThisSpell(const CSpell * spell, BattleHex destination)
+{
+	if(!gs->curB)
+	{
+
+		tlog1 << "battleCanCastThisSpell called when there is no battle!\n";
+		return ESpellCastProblem::NO_HERO_TO_CAST_SPELL;
+	}
+
 	return gs->curB->battleCanCastThisSpellHere(player, spell, ECastingMode::CREATURE_ACTIVE_CASTING, destination);
 }
 

+ 2 - 1
lib/IGameCallback.h

@@ -108,7 +108,8 @@ public:
 	bool battleCanShoot(const CStack * stack, BattleHex dest); //returns true if unit with id ID can shoot to dest
 	bool battleCanCastSpell(); //returns true, if caller can cast a spell
 	ESpellCastProblem::ESpellCastProblem battleCanCastThisSpell(const CSpell * spell); //determines if given spell can be casted (and returns problem description)
-	ESpellCastProblem::ESpellCastProblem battleCanCastThisSpell(const CSpell * spell, BattleHex destination); //determines if creature can cast a spell here
+	ESpellCastProblem::ESpellCastProblem battleCanCastThisSpell(const CSpell * spell, BattleHex destination); //if hero can cast spell here
+	ESpellCastProblem::ESpellCastProblem battleCanCreatureCastThisSpell(const CSpell * spell, BattleHex destination); //determines if creature can cast a spell here
 	ui32 battleGetRandomStackSpell(const CStack * stack, ERandomSpell mode);
 	bool battleCanFlee(); //returns true if caller can flee from the battle
 	int battleGetSurrenderCost(); //returns cost of surrendering battle, -1 if surrendering is not possible