Browse Source

Crashes realted to illegal access to enemy hero data should be fixed, including #1178.

Michał W. Urbańczyk 12 years ago
parent
commit
a96f03e947

+ 8 - 6
client/BattleInterface/CBattleInterface.cpp

@@ -1204,10 +1204,12 @@ void CBattleInterface::bSurrenderf()
 	int cost = curInt->cb->battleGetSurrenderCost();
 	if(cost >= 0)
 	{
-		const CGHeroInstance *opponent = curInt->cb->battleGetFightingHero(1);
-		std::string enemyHeroName = opponent ? opponent->name : "#ENEMY#"; //TODO: should surrendering without enemy hero be enabled?
+		std::string enemyHeroName = curInt->cb->battleGetEnemyHero().name;
+		if(enemyHeroName.empty())
+			enemyHeroName = "#ENEMY#"; //TODO: should surrendering without enemy hero be enabled?
+
 		std::string surrenderMessage = boost::str(boost::format(CGI->generaltexth->allTexts[32]) % enemyHeroName % cost); //%s states: "I will accept your surrender and grant you and your troops safe passage for the price of %d gold."
-		curInt->showYesNoDialog(surrenderMessage, boost::bind(&CBattleInterface::reallySurrender,this), 0, false);
+		curInt->showYesNoDialog(surrenderMessage, [this]{ reallySurrender(); }, 0, false);
 	}
 }
 
@@ -1714,7 +1716,7 @@ void CBattleInterface::spellCast( const BattleSpellCast * sc )
 		std::string text = CGI->generaltexth->allTexts[195];
 		if(sc->castedByHero)
 		{
-			boost::algorithm::replace_first(text, "%s", curInt->cb->battleGetFightingHero(sc->side)->name);
+			boost::algorithm::replace_first(text, "%s", curInt->cb->battleGetHeroInfo(sc->side).name);
 			boost::algorithm::replace_first(text, "%s", CGI->spellh->spells[sc->id]->name); //spell name
 			boost::algorithm::replace_first(text, "%s", curInt->cb->battleGetStackByID(*sc->affectedCres.begin(), false)->getCreature()->namePl ); //target
 		}
@@ -1829,7 +1831,7 @@ void CBattleInterface::spellCast( const BattleSpellCast * sc )
 		std::string text = CGI->generaltexth->allTexts[196];
 		if(sc->castedByHero)
 		{
-			boost::algorithm::replace_first(text, "%s", curInt->cb->battleGetFightingHero(sc->side)->name);
+			boost::algorithm::replace_first(text, "%s", curInt->cb->battleGetHeroInfo(sc->side).name);
 		}
 		else if(sc->attackerType < CGI->creh->creatures.size())
 		{
@@ -2911,7 +2913,7 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
 			case FREE_LOCATION:
 				{
 					ui8 side = curInt->cb->battleGetMySide();
-					auto hero = curInt->cb->battleGetFightingHero(side);
+					auto hero = curInt->cb->battleGetMyHero();
 					assert(!creatureCasting); //we assume hero casts this spell
 					assert(hero);
 

+ 1 - 1
client/CSpellWindow.cpp

@@ -645,7 +645,7 @@ void CSpellWindow::SpellArea::clickLeft(tribool down, bool previousState)
 						if(vstd::contains(s->state, EBattleStackState::SUMMONED))
 						{
 							elemental = s->getCreature()->namePl;
-							summoner = owner->myInt->cb->battleGetFightingHero(!s->attackerOwned)->name;
+							summoner = owner->myInt->cb->battleGetHeroInfo(!s->attackerOwned).name;
 							break;
 						}
 					}

+ 10 - 4
lib/CBattleCallback.cpp

@@ -296,6 +296,15 @@ const CGHeroInstance * CBattleInfoEssentials::battleGetFightingHero(ui8 side) co
 	return getBattle()->heroes[side];
 }
 
+InfoAboutHero CBattleInfoEssentials::battleGetHeroInfo( ui8 side ) const
+{
+	auto hero = getBattle()->heroes[side];
+	if(!hero)
+		tlog3 << __FUNCTION__ << ": side " << (int)side << " does not have hero!\n";
+
+	return InfoAboutHero(hero, battleDoWeKnowAbout(side));
+}
+
 int CBattleInfoEssentials::battleCastSpells(ui8 side) const
 {
 	RETURN_IF_NOT_BATTLE(-1);
@@ -2296,10 +2305,7 @@ const CGHeroInstance * CPlayerBattleCallback::battleGetMyHero() const
 
 InfoAboutHero CPlayerBattleCallback::battleGetEnemyHero() const
 {
-	InfoAboutHero ret;
-	assert(0);
-	///TODO implement and replace usages of battleGetFightingHero obtaining enemy hero
-	return ret;
+	return battleGetHeroInfo(!battleGetMySide());
 }
 
 BattleAttackInfo::BattleAttackInfo(const CStack *Attacker, const CStack *Defender, bool Shooting)

+ 2 - 1
lib/CBattleCallback.h

@@ -181,7 +181,8 @@ public:
 	ui8 battleGetSiegeLevel() const; //returns 0 when there is no siege, 1 if fort, 2 is citadel, 3 is castle
 	bool battleHasHero(ui8 side) const;
 	int battleCastSpells(ui8 side) const; //how many spells has given side casted
-	const CGHeroInstance * battleGetFightingHero(ui8 side) const;
+	const CGHeroInstance * battleGetFightingHero(ui8 side) const; //depracated for players callback, easy to get wrong
+	InfoAboutHero battleGetHeroInfo(ui8 side) const;
 
 	//helpers
 	TStacks battleAliveStacks() const;

+ 3 - 0
lib/CGameState.cpp

@@ -2764,6 +2764,9 @@ InfoAboutHero::InfoAboutHero(const InfoAboutHero & iah):
 }
 
 InfoAboutHero::InfoAboutHero(const CGHeroInstance *h, bool detailed)
+	: details(nullptr),
+	hclass(nullptr),
+	portrait(-1)
 {
 	initFromHero(h, detailed);
 }