فهرست منبع

1. Fixed #843
2. Refactoring for battle console hoover texts
3. Clone should work only for creatures of certain tier. However, ALL creature immunities stopped working in the meantime. Looking for an earlier bug.

DjWarmonger 13 سال پیش
والد
کامیت
444b59d478

+ 78 - 74
client/BattleInterface/CBattleInterface.cpp

@@ -912,6 +912,8 @@ void CBattleInterface::keyPressed(const SDL_KeyboardEvent & key)
 }
 }
 void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
 void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
 {
 {
+	std::string consoleMsg;
+
 	if(activeStack && !spellDestSelectMode)
 	if(activeStack && !spellDestSelectMode)
 	{
 	{
         int lastMouseHoveredStack = mouseHoveredStack;
         int lastMouseHoveredStack = mouseHoveredStack;
@@ -977,7 +979,7 @@ void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
 									CCS->curh->changeGraphic(3, 0);
 									CCS->curh->changeGraphic(3, 0);
 									stackCastsSpell = true;
 									stackCastsSpell = true;
 									std::string buf = CGI->generaltexth->allTexts[301]; //Cast spell on %s
 									std::string buf = CGI->generaltexth->allTexts[301]; //Cast spell on %s
-									boost::replace_first (buf, "%s", shere->getName());
+									boost::replace_first (buf, "%s", shere->getName().c_str());
 									console->alterTxt = buf;
 									console->alterTxt = buf;
 									console->whoSetAlter = 0;
 									console->whoSetAlter = 0;
 								}
 								}
@@ -1002,9 +1004,9 @@ void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
 									CCS->curh->changeGraphic(1,5);
 									CCS->curh->changeGraphic(1,5);
 								}
 								}
 								//setting console text
 								//setting console text
-								char buf[500];
-								sprintf(buf, CGI->generaltexth->allTexts[297].c_str(), shere->count == 1 ? shere->getCreature()->nameSing.c_str() : shere->getCreature()->namePl.c_str());
-								console->alterTxt = buf;
+								consoleMsg += CGI->generaltexth->allTexts[297];
+								boost::replace_first (consoleMsg, "%s", shere->getName());
+								console->alterText (consoleMsg);
 								console->whoSetAlter = 0;
 								console->whoSetAlter = 0;
 								const time_t curTime = time(NULL);
 								const time_t curTime = time(NULL);
 								if (shere->ID != lastMouseHoveredStack &&
 								if (shere->ID != lastMouseHoveredStack &&
@@ -1037,16 +1039,17 @@ void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
 							{
 							{
 								CCS->curh->changeGraphic(1,3);
 								CCS->curh->changeGraphic(1,3);
 							}
 							}
-							//setting console text
-							char buf[500];
 							//calculating estimated dmg
 							//calculating estimated dmg
 							std::pair<ui32, ui32> estimatedDmg = curInt->cb->battleEstimateDamage(sactive, shere);
 							std::pair<ui32, ui32> estimatedDmg = curInt->cb->battleEstimateDamage(sactive, shere);
-							std::ostringstream estDmg;
-							estDmg << estimatedDmg.first << " - " << estimatedDmg.second;
+							std::string estDmg;
+							estDmg += boost::lexical_cast<std::string>(estimatedDmg.first) += " - ";
+							estDmg += boost::lexical_cast<std::string>(estimatedDmg.second);
 							//printing
 							//printing
-							sprintf(buf, CGI->generaltexth->allTexts[296].c_str(), shere->count == 1 ? shere->getCreature()->nameSing.c_str() : shere->getCreature()->namePl.c_str(),
-								sactive->shots, estDmg.str().c_str());
-							console->alterTxt = buf;
+							consoleMsg += CGI->generaltexth->allTexts[296];
+							boost::replace_first (consoleMsg, "%s", shere->getName());
+							boost::replace_first (consoleMsg, "%d", boost::lexical_cast<std::string>(sactive->shots));
+							boost::replace_first (consoleMsg, "%s", estDmg);
+							console->alterText (consoleMsg);
 							console->whoSetAlter = 0;
 							console->whoSetAlter = 0;
 						}
 						}
 						else if (isTileAttackable(myNumber)) //available enemy (melee attackable)
 						else if (isTileAttackable(myNumber)) //available enemy (melee attackable)
@@ -1054,21 +1057,21 @@ void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
 							//handle direction of cursor and attackable tile
 							//handle direction of cursor and attackable tile
 							setBattleCursor(myNumber);
 							setBattleCursor(myNumber);
 
 
-							//setting console info
-							char buf[500];
 							//calculating estimated dmg
 							//calculating estimated dmg
 							std::pair<ui32, ui32> estimatedDmg = curInt->cb->battleEstimateDamage(sactive, shere);
 							std::pair<ui32, ui32> estimatedDmg = curInt->cb->battleEstimateDamage(sactive, shere);
-							std::ostringstream estDmg;
-							estDmg << estimatedDmg.first << " - " << estimatedDmg.second;
+							std::string estDmg;
+							estDmg += boost::lexical_cast<std::string>(estimatedDmg.first) += " - ";
+							estDmg += boost::lexical_cast<std::string>(estimatedDmg.second);
 							//printing
 							//printing
-							sprintf(buf, CGI->generaltexth->allTexts[36].c_str(),
-								shere->count == 1 ? shere->getCreature()->nameSing.c_str() : shere->getCreature()->namePl.c_str(), estDmg.str().c_str());
-							console->alterTxt = buf;
+							consoleMsg += CGI->generaltexth->allTexts[36];
+							boost::replace_first (consoleMsg, "%s", shere->getName());
+							boost::replace_first (consoleMsg, "%s", estDmg);
+							console->alterText (consoleMsg);
 							console->whoSetAlter = 0;
 							console->whoSetAlter = 0;
 						}
 						}
 						else //unavailable enemy
 						else //unavailable enemy
 						{
 						{
-							CCS->curh->changeGraphic(1,0);
+							CCS->curh->changeGraphic (1,0);
 							console->alterTxt = "";
 							console->alterTxt = "";
 							console->whoSetAlter = 0;
 							console->whoSetAlter = 0;
 						}
 						}
@@ -1091,29 +1094,27 @@ void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
 			else //available tile
 			else //available tile
 			{
 			{
 				//setting console text and cursor
 				//setting console text and cursor
-				if(activeStack) //there can be a moment when stack is dead ut next is not yet activated
+				if (activeStack) //there can be a moment when stack is dead ut next is not yet activated
 				{
 				{
-					char buf[500];
 					if(activeStack->hasBonusOfType(Bonus::FLYING))
 					if(activeStack->hasBonusOfType(Bonus::FLYING))
 					{
 					{
 						CCS->curh->changeGraphic(1,2);
 						CCS->curh->changeGraphic(1,2);
-						sprintf(buf, CGI->generaltexth->allTexts[295].c_str(),
-							activeStack->count == 1 ? activeStack->getCreature()->nameSing.c_str() : activeStack->getCreature()->namePl.c_str());
+						consoleMsg += CGI->generaltexth->allTexts[295]; //Fly %s here
 					}
 					}
 					else
 					else
 					{
 					{
 						CCS->curh->changeGraphic(1,1);
 						CCS->curh->changeGraphic(1,1);
-						sprintf(buf, CGI->generaltexth->allTexts[294].c_str(),
-							activeStack->count == 1 ? activeStack->getCreature()->nameSing.c_str() : activeStack->getCreature()->namePl.c_str());
+						consoleMsg += CGI->generaltexth->allTexts[294]; //Move %s here
+						
 					}
 					}
-
-					console->alterTxt = buf;
+					boost::replace_first (consoleMsg, "%s", activeStack->getName());
+					console->alterText(consoleMsg);
 					console->whoSetAlter = 0;
 					console->whoSetAlter = 0;
 				}
 				}
 			}
 			}
 		}
 		}
 	}
 	}
-	else if(spellDestSelectMode)
+	else if (spellDestSelectMode)
 	{
 	{
 		int myNumber = -1; //number of hovered tile
 		int myNumber = -1; //number of hovered tile
 		for(int g=0; g<GameConstants::BFIELD_SIZE; ++g)
 		for(int g=0; g<GameConstants::BFIELD_SIZE; ++g)
@@ -1134,65 +1135,68 @@ void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
 		else
 		else
 		{
 		{
 			//get dead stack if we cast resurrection or animate dead
 			//get dead stack if we cast resurrection or animate dead
-			const CStack * stackUnder = curInt->cb->battleGetStackByPos(myNumber, spellToCast->additionalInfo != 38 && spellToCast->additionalInfo != 39);
+			const CStack * stackUnder = curInt->cb->battleGetStackByPos(myNumber, vstd::contains(CGI->spellh->risingSpells, spellToCast->additionalInfo));
 
 
 			if(stackUnder && spellToCast->additionalInfo == 39 && !stackUnder->hasBonusOfType(Bonus::UNDEAD)) //animate dead can be cast only on undead creatures
 			if(stackUnder && spellToCast->additionalInfo == 39 && !stackUnder->hasBonusOfType(Bonus::UNDEAD)) //animate dead can be cast only on undead creatures
 				stackUnder = NULL;
 				stackUnder = NULL;
 
 
-			bool whichCase; //for cases 1, 2 and 3
-			switch(spellSelMode)
+			bool potentialTargetStack; //for cases 1, 2 and 3
+			switch (spellSelMode)
 			{
 			{
-			case 1:
-				whichCase = stackUnder != NULL && curInt->playerID == stackUnder->owner;
-				break;
-			case 2:
-				whichCase = stackUnder != NULL && curInt->playerID != stackUnder->owner;
-				break;
-			case 3:
-				whichCase = stackUnder != NULL;
-				break;
+					case SpellSelectionType::FRIENDLY_CREATURE:
+						potentialTargetStack = stackUnder != NULL && curInt->playerID == stackUnder->owner;
+						break;
+					case SpellSelectionType::HOSTILE_CREATURE:
+						potentialTargetStack = stackUnder != NULL && curInt->playerID != stackUnder->owner;
+						break;
+					case SpellSelectionType::ANY_CREATURE:
+						potentialTargetStack = stackUnder != NULL;
+						break;
 			}
 			}
 
 
 			switch(spellSelMode)
 			switch(spellSelMode)
 			{
 			{
-			case 0:
-				CCS->curh->changeGraphic(3, 0);
-				//setting console text
-				char buf[500];
-				sprintf(buf, CGI->generaltexth->allTexts[26].c_str(), CGI->spellh->spells[spellToCast->additionalInfo]->name.c_str());
-				console->alterTxt = buf;
-				console->whoSetAlter = 0;
-				break;
-			case 1: case 2: case 3:
-				if( whichCase )
-				{
+			case SpellSelectionType::ANY_LOCATION:
 					CCS->curh->changeGraphic(3, 0);
 					CCS->curh->changeGraphic(3, 0);
 					//setting console text
 					//setting console text
-					char buf[500];
-					std::string creName = stackUnder->count > 1 ? stackUnder->getCreature()->namePl : stackUnder->getCreature()->nameSing;
-						sprintf(buf, CGI->generaltexth->allTexts[27].c_str(), CGI->spellh->spells[spellToCast->additionalInfo]->name.c_str(), creName.c_str());
-					console->alterTxt = buf;
+					consoleMsg += CGI->generaltexth->allTexts[26] += CGI->spellh->spells[spellToCast->additionalInfo]->name;
+					console->alterText (consoleMsg);
 					console->whoSetAlter = 0;
 					console->whoSetAlter = 0;
 					break;
 					break;
-				}
-				else
-				{
-					CCS->curh->changeGraphic(1, 0);
-					//setting console text
-					console->alterTxt = CGI->generaltexth->allTexts[23];
-					console->whoSetAlter = 0;
-				}
-				break;
-			case 4: //TODO: implement this case
-				if( blockedByObstacle(myNumber) )
-				{
-					CCS->curh->changeGraphic(3, 0);
-				}
-				else
-				{
-					CCS->curh->changeGraphic(1, 0);
-				}
-				break;
+				case SpellSelectionType::FRIENDLY_CREATURE:
+				case SpellSelectionType::HOSTILE_CREATURE:
+				case SpellSelectionType::ANY_CREATURE:
+					if( potentialTargetStack )
+					{
+						if (curInt->cb->battleCanCastThisSpell (CGI->spellh->spells[spellToCast->additionalInfo], BattleHex(myNumber)))
+							CCS->curh->changeGraphic(3, 0);
+						else
+							CCS->curh->changeGraphic(1, 0);
+						//setting console text
+						consoleMsg += CGI->generaltexth->allTexts[27] += CGI->spellh->spells[spellToCast->additionalInfo]->name;
+						consoleMsg += stackUnder->getName();
+						console->alterText (consoleMsg);
+						console->whoSetAlter = 0;
+						break;
+					}
+					else
+					{
+						CCS->curh->changeGraphic(1, 0);
+						//setting console text
+						console->alterTxt = CGI->generaltexth->allTexts[23];
+						console->whoSetAlter = 0;
+					}
+					break;
+				case SpellSelectionType::OBSTACLE: //TODO: implement this case
+					if ( blockedByObstacle(myNumber) )
+					{
+						CCS->curh->changeGraphic(3, 0);
+					}
+					else
+					{
+						CCS->curh->changeGraphic(1, 0);
+					}
+					break;
 			}
 			}
 		}
 		}
 	}
 	}

+ 7 - 0
client/BattleInterface/CBattleInterfaceClasses.cpp

@@ -72,6 +72,13 @@ bool CBattleConsole::addText(const std::string & text)
 	return true;
 	return true;
 }
 }
 
 
+void CBattleConsole::alterText(const std::string &text)
+{
+	char buf[500];
+	sprintf(buf, text.c_str());
+	alterTxt = buf;
+}
+
 void CBattleConsole::eraseText(ui32 pos)
 void CBattleConsole::eraseText(ui32 pos)
 {
 {
 	if(pos < texts.size())
 	if(pos < texts.size())

+ 1 - 0
client/BattleInterface/CBattleInterfaceClasses.h

@@ -38,6 +38,7 @@ public:
 	~CBattleConsole(); //d-tor
 	~CBattleConsole(); //d-tor
 	void show(SDL_Surface * to = 0);
 	void show(SDL_Surface * to = 0);
 	bool addText(const std::string &text); //adds text at the last position; returns false if failed (e.g. text longer than 70 characters)
 	bool addText(const std::string &text); //adds text at the last position; returns false if failed (e.g. text longer than 70 characters)
+	void alterText(const std::string &text); //place string at alterTxt
 	void eraseText(ui32 pos); //erases added text at position pos
 	void eraseText(ui32 pos); //erases added text at position pos
 	void changeTextAt(const std::string &text, ui32 pos); //if we have more than pos texts, pos-th is changed to given one
 	void changeTextAt(const std::string &text, ui32 pos); //if we have more than pos texts, pos-th is changed to given one
 	void scrollUp(ui32 by = 1); //scrolls console up by 'by' positions
 	void scrollUp(ui32 by = 1); //scrolls console up by 'by' positions

+ 3 - 1
client/CCreatureWindow.cpp

@@ -130,7 +130,9 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *
 	const CStack *battleStack = dynamic_cast<const CStack*>(stackNode); //only during battle
 	const CStack *battleStack = dynamic_cast<const CStack*>(stackNode); //only during battle
 	heroOwner = HeroOwner;
 	heroOwner = HeroOwner;
 
 
-	if (Stack->count)
+	if (battleStack)
+		count = boost::lexical_cast<std::string>(battleStack->count);
+	else if (Stack->count)
 		count = boost::lexical_cast<std::string>(Stack->count);
 		count = boost::lexical_cast<std::string>(Stack->count);
 
 
 	//Basic graphics - need to calculate size
 	//Basic graphics - need to calculate size

+ 7 - 0
lib/BattleState.cpp

@@ -2121,6 +2121,13 @@ ESpellCastProblem::ESpellCastProblem BattleInfo::battleIsImmune(const CGHeroInst
 			case Spells::CLONE:
 			case Spells::CLONE:
 				if (subject->hasBonusOfType(Bonus::SIEGE_WEAPON))
 				if (subject->hasBonusOfType(Bonus::SIEGE_WEAPON))
 					return ESpellCastProblem::STACK_IMMUNE_TO_SPELL; //war machines are mmune to some spells than involve movement
 					return ESpellCastProblem::STACK_IMMUNE_TO_SPELL; //war machines are mmune to some spells than involve movement
+				if (spell->id == Spells::CLONE)
+				{
+					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
+						return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
+				}
 				break;
 				break;
 			case Spells::FORGETFULNESS:
 			case Spells::FORGETFULNESS:
 				if (!subject->hasBonusOfType(Bonus::SHOOTER))
 				if (!subject->hasBonusOfType(Bonus::SHOOTER))