mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Fixed #1271.
This commit is contained in:
parent
b01637840a
commit
9f5d1ba623
@ -140,6 +140,11 @@ void IObjectInterface::garrisonDialogClosed(const CGHeroInstance *hero) const
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IObjectInterface::heroLevelUpDone(const CGHeroInstance *hero) const
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void CPlayersVisited::setPropertyDer( ui8 what, ui32 val )
|
void CPlayersVisited::setPropertyDer( ui8 what, ui32 val )
|
||||||
{
|
{
|
||||||
if(what == 10)
|
if(what == 10)
|
||||||
@ -5307,6 +5312,7 @@ const std::string & CGMagicWell::getHoverText() const
|
|||||||
void CGPandoraBox::initObj()
|
void CGPandoraBox::initObj()
|
||||||
{
|
{
|
||||||
blockVisit = (ID==Obj::PANDORAS_BOX); //block only if it's really pandora's box (events also derive from that class)
|
blockVisit = (ID==Obj::PANDORAS_BOX); //block only if it's really pandora's box (events also derive from that class)
|
||||||
|
hasGuardians = stacks.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGPandoraBox::onHeroVisit(const CGHeroInstance * h) const
|
void CGPandoraBox::onHeroVisit(const CGHeroInstance * h) const
|
||||||
@ -5318,11 +5324,12 @@ void CGPandoraBox::onHeroVisit(const CGHeroInstance * h) const
|
|||||||
cb->showBlockingDialog (&bd);
|
cb->showBlockingDialog (&bd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGPandoraBox::giveContents( const CGHeroInstance *h, bool afterBattle ) const
|
void CGPandoraBox::giveContentsUpToExp(const CGHeroInstance *h) const
|
||||||
{
|
{
|
||||||
|
cb->removeAfterVisit(this);
|
||||||
|
|
||||||
InfoWindow iw;
|
InfoWindow iw;
|
||||||
iw.player = h->getOwner();
|
iw.player = h->getOwner();
|
||||||
std::string msg = message; //in case box is removed in the meantime
|
|
||||||
|
|
||||||
bool changesPrimSkill = false;
|
bool changesPrimSkill = false;
|
||||||
for (int i = 0; i < primskills.size(); i++)
|
for (int i = 0; i < primskills.size(); i++)
|
||||||
@ -5352,14 +5359,6 @@ void CGPandoraBox::giveContents( const CGHeroInstance *h, bool afterBattle ) con
|
|||||||
|
|
||||||
cb->showInfoDialog(&iw);
|
cb->showInfoDialog(&iw);
|
||||||
|
|
||||||
//give exp
|
|
||||||
if(expVal)
|
|
||||||
cb->changePrimSkill(h, PrimarySkill::EXPERIENCE, expVal, false);
|
|
||||||
//give prim skills
|
|
||||||
for(int i=0; i<primskills.size(); i++)
|
|
||||||
if(primskills[i])
|
|
||||||
cb->changePrimSkill(h,static_cast<PrimarySkill::PrimarySkill>(i),primskills[i],false);
|
|
||||||
|
|
||||||
//give sec skills
|
//give sec skills
|
||||||
for(int i=0; i<abilities.size(); i++)
|
for(int i=0; i<abilities.size(); i++)
|
||||||
{
|
{
|
||||||
@ -5371,8 +5370,31 @@ void CGPandoraBox::giveContents( const CGHeroInstance *h, bool afterBattle ) con
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//give prim skills
|
||||||
|
for(int i=0; i<primskills.size(); i++)
|
||||||
|
if(primskills[i])
|
||||||
|
cb->changePrimSkill(h,static_cast<PrimarySkill::PrimarySkill>(i),primskills[i],false);
|
||||||
|
|
||||||
|
assert(!cb->isVisitCoveredByAnotherQuery(this, h));
|
||||||
|
|
||||||
|
//give exp
|
||||||
|
if(expVal)
|
||||||
|
cb->changePrimSkill(h, PrimarySkill::EXPERIENCE, expVal, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!cb->isVisitCoveredByAnotherQuery(this, h))
|
||||||
|
giveContentsAfterExp(h);
|
||||||
|
//Otherwise continuation occurs via post-level-up callback.
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGPandoraBox::giveContentsAfterExp(const CGHeroInstance *h) const
|
||||||
|
{
|
||||||
|
bool hadGuardians = hasGuardians; //copy, because flag will be emptied after issuing first post-battle message
|
||||||
|
|
||||||
|
std::string msg = message; //in case box is removed in the meantime
|
||||||
|
InfoWindow iw;
|
||||||
|
iw.player = h->getOwner();
|
||||||
|
|
||||||
if(spells.size())
|
if(spells.size())
|
||||||
{
|
{
|
||||||
std::set<SpellID> spellsToGive;
|
std::set<SpellID> spellsToGive;
|
||||||
@ -5404,7 +5426,7 @@ void CGPandoraBox::giveContents( const CGHeroInstance *h, bool afterBattle ) con
|
|||||||
|
|
||||||
if(manaDiff)
|
if(manaDiff)
|
||||||
{
|
{
|
||||||
getText(iw,afterBattle,manaDiff,176,177,h);
|
getText(iw,hadGuardians,manaDiff,176,177,h);
|
||||||
iw.components.push_back(Component(Component::PRIM_SKILL,5,manaDiff,0));
|
iw.components.push_back(Component(Component::PRIM_SKILL,5,manaDiff,0));
|
||||||
cb->showInfoDialog(&iw);
|
cb->showInfoDialog(&iw);
|
||||||
cb->setManaPoints(h->id, h->mana + manaDiff);
|
cb->setManaPoints(h->id, h->mana + manaDiff);
|
||||||
@ -5412,7 +5434,7 @@ void CGPandoraBox::giveContents( const CGHeroInstance *h, bool afterBattle ) con
|
|||||||
|
|
||||||
if(moraleDiff)
|
if(moraleDiff)
|
||||||
{
|
{
|
||||||
getText(iw,afterBattle,moraleDiff,178,179,h);
|
getText(iw,hadGuardians,moraleDiff,178,179,h);
|
||||||
iw.components.push_back(Component(Component::MORALE,0,moraleDiff,0));
|
iw.components.push_back(Component(Component::MORALE,0,moraleDiff,0));
|
||||||
cb->showInfoDialog(&iw);
|
cb->showInfoDialog(&iw);
|
||||||
GiveBonus gb;
|
GiveBonus gb;
|
||||||
@ -5423,7 +5445,7 @@ void CGPandoraBox::giveContents( const CGHeroInstance *h, bool afterBattle ) con
|
|||||||
|
|
||||||
if(luckDiff)
|
if(luckDiff)
|
||||||
{
|
{
|
||||||
getText(iw,afterBattle,luckDiff,180,181,h);
|
getText(iw,hadGuardians,luckDiff,180,181,h);
|
||||||
iw.components.push_back(Component(Component::LUCK,0,luckDiff,0));
|
iw.components.push_back(Component(Component::LUCK,0,luckDiff,0));
|
||||||
cb->showInfoDialog(&iw);
|
cb->showInfoDialog(&iw);
|
||||||
GiveBonus gb;
|
GiveBonus gb;
|
||||||
@ -5441,7 +5463,7 @@ void CGPandoraBox::giveContents( const CGHeroInstance *h, bool afterBattle ) con
|
|||||||
}
|
}
|
||||||
if(iw.components.size())
|
if(iw.components.size())
|
||||||
{
|
{
|
||||||
getText(iw,afterBattle,182,h);
|
getText(iw,hadGuardians,182,h);
|
||||||
cb->showInfoDialog(&iw);
|
cb->showInfoDialog(&iw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5454,12 +5476,12 @@ void CGPandoraBox::giveContents( const CGHeroInstance *h, bool afterBattle ) con
|
|||||||
}
|
}
|
||||||
if(iw.components.size())
|
if(iw.components.size())
|
||||||
{
|
{
|
||||||
getText(iw,afterBattle,183,h);
|
getText(iw,hadGuardians,183,h);
|
||||||
cb->showInfoDialog(&iw);
|
cb->showInfoDialog(&iw);
|
||||||
}
|
}
|
||||||
|
|
||||||
iw.components.clear();
|
iw.components.clear();
|
||||||
// getText(iw,afterBattle,183,h);
|
// getText(iw,afterBattle,183,h);
|
||||||
iw.text.addTxt(MetaString::ADVOB_TXT, 183); //% has found treasure
|
iw.text.addTxt(MetaString::ADVOB_TXT, 183); //% has found treasure
|
||||||
iw.text.addReplacement(h->name);
|
iw.text.addReplacement(h->name);
|
||||||
for(int i=0; i<artifacts.size(); i++)
|
for(int i=0; i<artifacts.size(); i++)
|
||||||
@ -5509,13 +5531,11 @@ void CGPandoraBox::giveContents( const CGHeroInstance *h, bool afterBattle ) con
|
|||||||
cb->showInfoDialog(&iw);
|
cb->showInfoDialog(&iw);
|
||||||
cb->giveCreatures(this, h, creatures, true);
|
cb->giveCreatures(this, h, creatures, true);
|
||||||
}
|
}
|
||||||
if(!afterBattle && msg.size())
|
if(!hasGuardians && msg.size())
|
||||||
{
|
{
|
||||||
iw.text << msg;
|
iw.text << msg;
|
||||||
cb->showInfoDialog(&iw);
|
cb->showInfoDialog(&iw);
|
||||||
}
|
}
|
||||||
if (!creatures.Slots().size())
|
|
||||||
cb->removeObject(this); //only when we don't need to display garrison window
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGPandoraBox::getText( InfoWindow &iw, bool &afterBattle, int text, const CGHeroInstance * h ) const
|
void CGPandoraBox::getText( InfoWindow &iw, bool &afterBattle, int text, const CGHeroInstance * h ) const
|
||||||
@ -5553,7 +5573,7 @@ void CGPandoraBox::battleFinished(const CGHeroInstance *hero, const BattleResult
|
|||||||
if(result.winner)
|
if(result.winner)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
giveContents(hero, true);
|
giveContentsUpToExp(hero);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGPandoraBox::blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const
|
void CGPandoraBox::blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const
|
||||||
@ -5576,11 +5596,16 @@ void CGPandoraBox::blockingDialogAnswered(const CGHeroInstance *hero, ui32 answe
|
|||||||
}
|
}
|
||||||
else //if it gives something without battle
|
else //if it gives something without battle
|
||||||
{
|
{
|
||||||
giveContents(hero, false);
|
giveContentsUpToExp(hero);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGPandoraBox::heroLevelUpDone(const CGHeroInstance *hero) const
|
||||||
|
{
|
||||||
|
giveContentsAfterExp(hero);
|
||||||
|
}
|
||||||
|
|
||||||
void CGEvent::onHeroVisit( const CGHeroInstance * h ) const
|
void CGEvent::onHeroVisit( const CGHeroInstance * h ) const
|
||||||
{
|
{
|
||||||
if(!(availableFor & (1 << h->tempOwner.getNum())))
|
if(!(availableFor & (1 << h->tempOwner.getNum())))
|
||||||
@ -5609,7 +5634,7 @@ void CGEvent::activated( const CGHeroInstance * h ) const
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
giveContents(h,false);
|
giveContentsUpToExp(h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,6 +119,7 @@ public:
|
|||||||
virtual void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const;
|
virtual void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const;
|
||||||
virtual void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const;
|
virtual void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const;
|
||||||
virtual void garrisonDialogClosed(const CGHeroInstance *hero) const;
|
virtual void garrisonDialogClosed(const CGHeroInstance *hero) const;
|
||||||
|
virtual void heroLevelUpDone(const CGHeroInstance *hero) const;
|
||||||
|
|
||||||
//unified interface, AI helpers
|
//unified interface, AI helpers
|
||||||
virtual bool wasVisited (PlayerColor player) const;
|
virtual bool wasVisited (PlayerColor player) const;
|
||||||
@ -679,6 +680,7 @@ class DLL_LINKAGE CGPandoraBox : public CArmedInstance
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::string message;
|
std::string message;
|
||||||
|
bool hasGuardians; //helper - after battle even though we have no stacks, allows us to know that there was battle
|
||||||
|
|
||||||
//gained things:
|
//gained things:
|
||||||
ui32 gainedExp;
|
ui32 gainedExp;
|
||||||
@ -697,15 +699,17 @@ public:
|
|||||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||||
void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const OVERRIDE;
|
void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const OVERRIDE;
|
||||||
void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const OVERRIDE;
|
void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const OVERRIDE;
|
||||||
|
void heroLevelUpDone(const CGHeroInstance *hero) const OVERRIDE;
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & static_cast<CArmedInstance&>(*this);
|
h & static_cast<CArmedInstance&>(*this);
|
||||||
h & message & gainedExp & manaDiff & moraleDiff & luckDiff & resources & primskills
|
h & message & hasGuardians & gainedExp & manaDiff & moraleDiff & luckDiff & resources & primskills
|
||||||
& abilities & abilityLevels & artifacts & spells & creatures;
|
& abilities & abilityLevels & artifacts & spells & creatures;
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
void giveContents(const CGHeroInstance *h, bool afterBattle) const;
|
void giveContentsUpToExp(const CGHeroInstance *h) const;
|
||||||
|
void giveContentsAfterExp(const CGHeroInstance *h) const;
|
||||||
private:
|
private:
|
||||||
void getText( InfoWindow &iw, bool &afterBattle, int val, int negative, int positive, const CGHeroInstance * h ) const;
|
void getText( InfoWindow &iw, bool &afterBattle, int val, int negative, int positive, const CGHeroInstance * h ) const;
|
||||||
void getText( InfoWindow &iw, bool &afterBattle, int text, const CGHeroInstance * h ) const;
|
void getText( InfoWindow &iw, bool &afterBattle, int text, const CGHeroInstance * h ) const;
|
||||||
|
@ -1012,3 +1012,10 @@ const CGCreature * IGameCallback::putNewMonster(CreatureID creID, int count, int
|
|||||||
setObjProperty(m->id, ObjProperty::MONSTER_POWER, (si64)1000*count);
|
setObjProperty(m->id, ObjProperty::MONSTER_POWER, (si64)1000*count);
|
||||||
return dynamic_cast<const CGCreature*>(m);
|
return dynamic_cast<const CGCreature*>(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IGameCallback::isVisitCoveredByAnotherQuery(const CGObjectInstance *obj, const CGHeroInstance *hero)
|
||||||
|
{
|
||||||
|
//only server knows
|
||||||
|
assert(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@ -274,6 +274,9 @@ public:
|
|||||||
const CGObjectInstance *putNewObject(Obj ID, int subID, int3 pos);
|
const CGObjectInstance *putNewObject(Obj ID, int subID, int3 pos);
|
||||||
const CGCreature *putNewMonster(CreatureID creID, int count, int3 pos);
|
const CGCreature *putNewMonster(CreatureID creID, int count, int3 pos);
|
||||||
|
|
||||||
|
//get info
|
||||||
|
virtual bool isVisitCoveredByAnotherQuery(const CGObjectInstance *obj, const CGHeroInstance *hero);
|
||||||
|
|
||||||
friend struct CPack;
|
friend struct CPack;
|
||||||
friend struct CPackForClient;
|
friend struct CPackForClient;
|
||||||
friend struct CPackForServer;
|
friend struct CPackForServer;
|
||||||
|
@ -6154,6 +6154,15 @@ void CGameHandler::removeAfterVisit(const CGObjectInstance *object)
|
|||||||
assert("This function needs to be called during the object visit!");
|
assert("This function needs to be called during the object visit!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CGameHandler::isVisitCoveredByAnotherQuery(const CGObjectInstance *obj, const CGHeroInstance *hero)
|
||||||
|
{
|
||||||
|
if(auto topQuery = queries.topQuery(hero->getOwner()))
|
||||||
|
if(auto visit = std::dynamic_pointer_cast<const CObjectVisitQuery>(topQuery))
|
||||||
|
return !(visit->visitedObject == obj && visit->visitingHero == hero);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance *army, BattleInfo *bat)
|
CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance *army, BattleInfo *bat)
|
||||||
{
|
{
|
||||||
heroWithDeadCommander = ObjectInstanceID();
|
heroWithDeadCommander = ObjectInstanceID();
|
||||||
|
@ -178,6 +178,10 @@ public:
|
|||||||
void giveHero(ObjectInstanceID id, PlayerColor player) OVERRIDE;
|
void giveHero(ObjectInstanceID id, PlayerColor player) OVERRIDE;
|
||||||
void changeObjPos(ObjectInstanceID objid, int3 newPos, ui8 flags) OVERRIDE;
|
void changeObjPos(ObjectInstanceID objid, int3 newPos, ui8 flags) OVERRIDE;
|
||||||
void heroExchange(ObjectInstanceID hero1, ObjectInstanceID hero2) OVERRIDE;
|
void heroExchange(ObjectInstanceID hero1, ObjectInstanceID hero2) OVERRIDE;
|
||||||
|
|
||||||
|
|
||||||
|
bool isVisitCoveredByAnotherQuery(const CGObjectInstance *obj, const CGHeroInstance *hero) OVERRIDE;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
void useScholarSkill(ObjectInstanceID hero1, ObjectInstanceID hero2);
|
void useScholarSkill(ObjectInstanceID hero1, ObjectInstanceID hero2);
|
||||||
void setPortalDwelling(const CGTownInstance * town, bool forced, bool clear);
|
void setPortalDwelling(const CGTownInstance * town, bool forced, bool clear);
|
||||||
|
@ -295,6 +295,11 @@ void CHeroLevelUpDialogQuery::onRemoval(CGameHandler *gh, PlayerColor color)
|
|||||||
gh->levelUpHero(hlu.hero, hlu.skills[*answer]);
|
gh->levelUpHero(hlu.hero, hlu.skills[*answer]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CHeroLevelUpDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
||||||
|
{
|
||||||
|
objectVisit.visitedObject->heroLevelUpDone(objectVisit.visitingHero);
|
||||||
|
}
|
||||||
|
|
||||||
CCommanderLevelUpDialogQuery::CCommanderLevelUpDialogQuery(const CommanderLevelUp &Clu)
|
CCommanderLevelUpDialogQuery::CCommanderLevelUpDialogQuery(const CommanderLevelUp &Clu)
|
||||||
{
|
{
|
||||||
clu = Clu;
|
clu = Clu;
|
||||||
@ -308,6 +313,11 @@ void CCommanderLevelUpDialogQuery::onRemoval(CGameHandler *gh, PlayerColor color
|
|||||||
gh->levelUpCommander(clu.hero->commander, clu.skills[*answer]);
|
gh->levelUpCommander(clu.hero->commander, clu.skills[*answer]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CCommanderLevelUpDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
|
||||||
|
{
|
||||||
|
objectVisit.visitedObject->heroLevelUpDone(objectVisit.visitingHero);
|
||||||
|
}
|
||||||
|
|
||||||
bool CDialogQuery::endsByPlayerAnswer() const
|
bool CDialogQuery::endsByPlayerAnswer() const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
@ -135,6 +135,7 @@ public:
|
|||||||
CHeroLevelUpDialogQuery(const HeroLevelUp &Hlu);
|
CHeroLevelUpDialogQuery(const HeroLevelUp &Hlu);
|
||||||
|
|
||||||
virtual void onRemoval(CGameHandler *gh, PlayerColor color) OVERRIDE;
|
virtual void onRemoval(CGameHandler *gh, PlayerColor color) OVERRIDE;
|
||||||
|
virtual void notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const OVERRIDE;
|
||||||
|
|
||||||
HeroLevelUp hlu;
|
HeroLevelUp hlu;
|
||||||
};
|
};
|
||||||
@ -146,6 +147,7 @@ public:
|
|||||||
CCommanderLevelUpDialogQuery(const CommanderLevelUp &Clu);
|
CCommanderLevelUpDialogQuery(const CommanderLevelUp &Clu);
|
||||||
|
|
||||||
virtual void onRemoval(CGameHandler *gh, PlayerColor color) OVERRIDE;
|
virtual void onRemoval(CGameHandler *gh, PlayerColor color) OVERRIDE;
|
||||||
|
virtual void notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const OVERRIDE;
|
||||||
|
|
||||||
CommanderLevelUp clu;
|
CommanderLevelUp clu;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user