mirror of
https://github.com/vcmi/vcmi.git
synced 2025-06-23 00:28:08 +02:00
Crashes realted to illegal access to enemy hero data should be fixed, including #1178.
This commit is contained in:
@ -1204,10 +1204,12 @@ void CBattleInterface::bSurrenderf()
|
|||||||
int cost = curInt->cb->battleGetSurrenderCost();
|
int cost = curInt->cb->battleGetSurrenderCost();
|
||||||
if(cost >= 0)
|
if(cost >= 0)
|
||||||
{
|
{
|
||||||
const CGHeroInstance *opponent = curInt->cb->battleGetFightingHero(1);
|
std::string enemyHeroName = curInt->cb->battleGetEnemyHero().name;
|
||||||
std::string enemyHeroName = opponent ? opponent->name : "#ENEMY#"; //TODO: should surrendering without enemy hero be enabled?
|
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."
|
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];
|
std::string text = CGI->generaltexth->allTexts[195];
|
||||||
if(sc->castedByHero)
|
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", CGI->spellh->spells[sc->id]->name); //spell name
|
||||||
boost::algorithm::replace_first(text, "%s", curInt->cb->battleGetStackByID(*sc->affectedCres.begin(), false)->getCreature()->namePl ); //target
|
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];
|
std::string text = CGI->generaltexth->allTexts[196];
|
||||||
if(sc->castedByHero)
|
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())
|
else if(sc->attackerType < CGI->creh->creatures.size())
|
||||||
{
|
{
|
||||||
@ -2911,7 +2913,7 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
|
|||||||
case FREE_LOCATION:
|
case FREE_LOCATION:
|
||||||
{
|
{
|
||||||
ui8 side = curInt->cb->battleGetMySide();
|
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(!creatureCasting); //we assume hero casts this spell
|
||||||
assert(hero);
|
assert(hero);
|
||||||
|
|
||||||
|
@ -645,7 +645,7 @@ void CSpellWindow::SpellArea::clickLeft(tribool down, bool previousState)
|
|||||||
if(vstd::contains(s->state, EBattleStackState::SUMMONED))
|
if(vstd::contains(s->state, EBattleStackState::SUMMONED))
|
||||||
{
|
{
|
||||||
elemental = s->getCreature()->namePl;
|
elemental = s->getCreature()->namePl;
|
||||||
summoner = owner->myInt->cb->battleGetFightingHero(!s->attackerOwned)->name;
|
summoner = owner->myInt->cb->battleGetHeroInfo(!s->attackerOwned).name;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -296,6 +296,15 @@ const CGHeroInstance * CBattleInfoEssentials::battleGetFightingHero(ui8 side) co
|
|||||||
return getBattle()->heroes[side];
|
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
|
int CBattleInfoEssentials::battleCastSpells(ui8 side) const
|
||||||
{
|
{
|
||||||
RETURN_IF_NOT_BATTLE(-1);
|
RETURN_IF_NOT_BATTLE(-1);
|
||||||
@ -2296,10 +2305,7 @@ const CGHeroInstance * CPlayerBattleCallback::battleGetMyHero() const
|
|||||||
|
|
||||||
InfoAboutHero CPlayerBattleCallback::battleGetEnemyHero() const
|
InfoAboutHero CPlayerBattleCallback::battleGetEnemyHero() const
|
||||||
{
|
{
|
||||||
InfoAboutHero ret;
|
return battleGetHeroInfo(!battleGetMySide());
|
||||||
assert(0);
|
|
||||||
///TODO implement and replace usages of battleGetFightingHero obtaining enemy hero
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BattleAttackInfo::BattleAttackInfo(const CStack *Attacker, const CStack *Defender, bool Shooting)
|
BattleAttackInfo::BattleAttackInfo(const CStack *Attacker, const CStack *Defender, bool Shooting)
|
||||||
|
@ -181,7 +181,8 @@ public:
|
|||||||
ui8 battleGetSiegeLevel() const; //returns 0 when there is no siege, 1 if fort, 2 is citadel, 3 is castle
|
ui8 battleGetSiegeLevel() const; //returns 0 when there is no siege, 1 if fort, 2 is citadel, 3 is castle
|
||||||
bool battleHasHero(ui8 side) const;
|
bool battleHasHero(ui8 side) const;
|
||||||
int battleCastSpells(ui8 side) const; //how many spells has given side casted
|
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
|
//helpers
|
||||||
TStacks battleAliveStacks() const;
|
TStacks battleAliveStacks() const;
|
||||||
|
@ -2764,6 +2764,9 @@ InfoAboutHero::InfoAboutHero(const InfoAboutHero & iah):
|
|||||||
}
|
}
|
||||||
|
|
||||||
InfoAboutHero::InfoAboutHero(const CGHeroInstance *h, bool detailed)
|
InfoAboutHero::InfoAboutHero(const CGHeroInstance *h, bool detailed)
|
||||||
|
: details(nullptr),
|
||||||
|
hclass(nullptr),
|
||||||
|
portrait(-1)
|
||||||
{
|
{
|
||||||
initFromHero(h, detailed);
|
initFromHero(h, detailed);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user