Browse Source

Really fixed #918.

Michał W. Urbańczyk 13 years ago
parent
commit
b874295b3a
4 changed files with 29 additions and 13 deletions
  1. 4 2
      client/BattleInterface/CBattleInterface.cpp
  2. 7 4
      client/CMT.cpp
  3. 17 7
      lib/BattleState.cpp
  4. 1 0
      lib/BattleState.h

+ 4 - 2
client/BattleInterface/CBattleInterface.cpp

@@ -2669,10 +2669,12 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
 			else
 				isCastingPossible = (curInt->cb->battleCanCastThisSpell(sp, myNumber) == ESpellCastProblem::OK);
 		}
-		else if(shere && shere->alive())
+		else
 		{
 			//needed for genie, otherwise covered by battleCan*CastThisSpell
-			if(spellSelMode == HOSTILE_CREATURE && shere->owner == sactive->owner
+			if(!shere
+				|| !shere->alive()
+				|| spellSelMode == HOSTILE_CREATURE && shere->owner == sactive->owner
 				|| spellSelMode == FRIENDLY_CREATURE && shere->owner != sactive->owner)
 			{
 				isCastingPossible = false;

+ 7 - 4
client/CMT.cpp

@@ -697,6 +697,7 @@ static void listenForEvents()
 		}
 		else if(ev->type == SDL_USEREVENT)
 		{
+			enum {CHANGE_SCREEN_RESOLUTION, RETURN_TO_MAIN_MENU, END_GAME_AND_DIE};
 			switch(ev->user.code)
 			{
 			case 1:
@@ -720,10 +721,12 @@ static void listenForEvents()
 				GH.curInt = CGP;
 				GH.defActionsDef = 63;
 				break;
-
-			case 3:
-				client->endGame(false);
-				break;
+			default:
+				tlog1 << "Error: unknown user event. Code " << ev->user.code << std::endl;
+				assert(0);
+// 			case 3:
+// 				client->endGame(false);
+// 				break;
 			}
 
 			delete ev;

+ 17 - 7
lib/BattleState.cpp

@@ -1960,24 +1960,26 @@ ESpellCastProblem::ESpellCastProblem BattleInfo::battleCanCastThisSpellHere( int
 
 
 	//get dead stack if we cast resurrection or animate dead
-	const CStack * stackUnder = getStackT(dest, false);
+	const CStack *deadStack = getStackIf([dest](const CStack *s) { return !s->alive() && s->position == dest; });
+	const CStack *aliveStack = getStackIf([dest](const CStack *s) { return s->alive() && s->position == dest; });
+
 
 	if(spell->isRisingSpell())
 	{
-		if(!stackUnder || stackUnder->alive())
+		if(!deadStack || aliveStack)
 			return ESpellCastProblem::NO_APPROPRIATE_TARGET;
-		if(spell->id == Spells::ANIMATE_DEAD  &&  !stackUnder->hasBonusOfType(Bonus::UNDEAD)) 
+		if(spell->id == Spells::ANIMATE_DEAD  &&  !deadStack->hasBonusOfType(Bonus::UNDEAD)) 
 			return ESpellCastProblem::NO_APPROPRIATE_TARGET;
-		if(stackUnder->owner != player) //you can resurrect only your own stacks
+		if(deadStack->owner != player) //you can resurrect only your own stacks
 			return ESpellCastProblem::NO_APPROPRIATE_TARGET;
 	}
 	else if(spell->getTargetType() == CSpell::CREATURE  ||  spell->getTargetType() == CSpell::CREATURE_EXPERT_MASSIVE)
 	{
-		if(!stackUnder || !stackUnder->alive())
+		if(!aliveStack)
 			return ESpellCastProblem::NO_APPROPRIATE_TARGET;
-		if(spell->isNegative() && stackUnder->owner == player)
+		if(spell->isNegative() && aliveStack->owner == player)
 			return ESpellCastProblem::NO_APPROPRIATE_TARGET;
-		if(spell->isPositive() && stackUnder->owner != player)
+		if(spell->isPositive() && aliveStack->owner != player)
 			return ESpellCastProblem::NO_APPROPRIATE_TARGET;
 	}
 
@@ -2379,6 +2381,14 @@ bool BattleInfo::isObstacleOnTile(BattleHex tile) const
 	return vstd::contains(coveredHexes, tile);
 }
 
+const CStack * BattleInfo::getStackIf(boost::function<bool(const CStack*)> pred) const
+{
+	auto stackItr = range::find_if(stacks, pred);
+	return stackItr == stacks.end() 
+		? NULL
+		: *stackItr;
+}
+
 CStack::CStack(const CStackInstance *Base, int O, int I, bool AO, int S)
 	: base(Base), ID(I), owner(O), slot(S), attackerOwned(AO),   
 	counterAttacks(1)

+ 1 - 0
lib/BattleState.h

@@ -83,6 +83,7 @@ struct DLL_LINKAGE BattleInfo : public CBonusSystemNode
 	//void getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const;
 	//////////////////////////////////////////////////////////////////////////
 
+	const CStack *getStackIf(boost::function<bool(const CStack*)> pred) const;
 	const CStack * getNextStack() const; //which stack will have turn after current one
 	void getStackQueue(std::vector<const CStack *> &out, int howMany, int turn = 0, int lastMoved = -1) const; //returns stack in order of their movement action
 	CStack * getStack(int stackID, bool onlyAlive = true);