1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00

Make stables message appear if hero has cavaliers but visited stables before

This commit is contained in:
Vadim Markovtsev 2016-02-01 09:41:15 +03:00
parent c30a6f2ff3
commit 88bc21952b
2 changed files with 57 additions and 27 deletions

View File

@ -23,13 +23,13 @@
bool CRewardLimiter::heroAllowed(const CGHeroInstance * hero) const bool CRewardLimiter::heroAllowed(const CGHeroInstance * hero) const
{ {
if (dayOfWeek != 0) if(dayOfWeek != 0)
{ {
if (IObjectInterface::cb->getDate(Date::DAY_OF_WEEK) != dayOfWeek) if (IObjectInterface::cb->getDate(Date::DAY_OF_WEEK) != dayOfWeek)
return false; return false;
} }
for (auto & reqStack : creatures) for(auto & reqStack : creatures)
{ {
size_t count = 0; size_t count = 0;
for (auto slot : hero->Slots()) for (auto slot : hero->Slots())
@ -42,25 +42,25 @@ bool CRewardLimiter::heroAllowed(const CGHeroInstance * hero) const
return false; return false;
} }
if (!IObjectInterface::cb->getPlayer(hero->tempOwner)->resources.canAfford(resources)) if(!IObjectInterface::cb->getPlayer(hero->tempOwner)->resources.canAfford(resources))
return false; return false;
if (minLevel > hero->level) if(minLevel > hero->level)
return false; return false;
for (size_t i=0; i<primary.size(); i++) for(size_t i=0; i<primary.size(); i++)
{ {
if (primary[i] > hero->getPrimSkillLevel(PrimarySkill::PrimarySkill(i))) if (primary[i] > hero->getPrimSkillLevel(PrimarySkill::PrimarySkill(i)))
return false; return false;
} }
for (auto & skill : secondary) for(auto & skill : secondary)
{ {
if (skill.second > hero->getSecSkillLevel(skill.first)) if (skill.second > hero->getSecSkillLevel(skill.first))
return false; return false;
} }
for (auto & art : artifacts) for(auto & art : artifacts)
{ {
if (!hero->hasArt(art)) if (!hero->hasArt(art))
return false; return false;
@ -73,11 +73,11 @@ std::vector<ui32> CRewardableObject::getAvailableRewards(const CGHeroInstance *
{ {
std::vector<ui32> ret; std::vector<ui32> ret;
for (size_t i=0; i<info.size(); i++) for(size_t i=0; i<info.size(); i++)
{ {
const CVisitInfo & visit = info[i]; const CVisitInfo & visit = info[i];
if ((visit.limiter.numOfGrants == 0 || visit.numOfGrants < visit.limiter.numOfGrants) // reward has unlimited uses or some are still available if((visit.limiter.numOfGrants == 0 || visit.numOfGrants < visit.limiter.numOfGrants) // reward has unlimited uses or some are still available
&& visit.limiter.heroAllowed(hero)) && visit.limiter.heroAllowed(hero))
{ {
logGlobal->debugStream() << "Reward " << i << " is allowed"; logGlobal->debugStream() << "Reward " << i << " is allowed";
@ -122,7 +122,7 @@ void CRewardableObject::onHeroVisit(const CGHeroInstance *h) const
cb->showBlockingDialog(&sd); cb->showBlockingDialog(&sd);
}; };
if (!wasVisited(h)) if(!wasVisited(h))
{ {
auto rewards = getAvailableRewards(h); auto rewards = getAvailableRewards(h);
logGlobal->debugStream() << "Visiting object with " << rewards.size() << " possible rewards"; logGlobal->debugStream() << "Visiting object with " << rewards.size() << " possible rewards";
@ -186,10 +186,10 @@ void CRewardableObject::heroLevelUpDone(const CGHeroInstance *hero) const
void CRewardableObject::blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const void CRewardableObject::blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const
{ {
if (answer == 0) if(answer == 0)
return; // player refused return; // player refused
if (answer > 0 && answer-1 < info.size()) if(answer > 0 && answer-1 < info.size())
{ {
auto list = getAvailableRewards(hero); auto list = getAvailableRewards(hero);
grantReward(list[answer - 1], hero); grantReward(list[answer - 1], hero);
@ -224,7 +224,7 @@ void CRewardableObject::grantRewardBeforeLevelup(const CVisitInfo & info, const
cb->giveResources(hero->tempOwner, info.reward.resources); cb->giveResources(hero->tempOwner, info.reward.resources);
for (auto & entry : info.reward.secondary) for(auto & entry : info.reward.secondary)
{ {
int current = hero->getSecSkillLevel(entry.first); int current = hero->getSecSkillLevel(entry.first);
if( (current != 0 && current < entry.second) || if( (current != 0 && current < entry.second) ||
@ -241,11 +241,11 @@ void CRewardableObject::grantRewardBeforeLevelup(const CVisitInfo & info, const
si64 expToGive = 0; si64 expToGive = 0;
expToGive += VLC->heroh->reqExp(hero->level+info.reward.gainedLevels) - VLC->heroh->reqExp(hero->level); expToGive += VLC->heroh->reqExp(hero->level+info.reward.gainedLevels) - VLC->heroh->reqExp(hero->level);
expToGive += hero->calculateXp(info.reward.gainedExp); expToGive += hero->calculateXp(info.reward.gainedExp);
if (expToGive) if(expToGive)
cb->changePrimSkill(hero, PrimarySkill::EXPERIENCE, expToGive); cb->changePrimSkill(hero, PrimarySkill::EXPERIENCE, expToGive);
// hero is not blocked by levelup dialog - grant remainer immediately // hero is not blocked by levelup dialog - grant remainer immediately
if (!cb->isVisitCoveredByAnotherQuery(this, hero)) if(!cb->isVisitCoveredByAnotherQuery(this, hero))
{ {
grantRewardAfterLevelup(info, hero); grantRewardAfterLevelup(info, hero);
} }
@ -253,7 +253,7 @@ void CRewardableObject::grantRewardBeforeLevelup(const CVisitInfo & info, const
void CRewardableObject::grantRewardAfterLevelup(const CVisitInfo & info, const CGHeroInstance * hero) const void CRewardableObject::grantRewardAfterLevelup(const CVisitInfo & info, const CGHeroInstance * hero) const
{ {
if (info.reward.manaDiff || info.reward.manaPercentage >= 0) if(info.reward.manaDiff || info.reward.manaPercentage >= 0)
{ {
si32 mana = hero->mana; si32 mana = hero->mana;
if (info.reward.manaPercentage >= 0) if (info.reward.manaPercentage >= 0)
@ -275,7 +275,7 @@ void CRewardableObject::grantRewardAfterLevelup(const CVisitInfo & info, const C
cb->setMovePoints(&smp); cb->setMovePoints(&smp);
} }
for (const Bonus & bonus : info.reward.bonuses) for(const Bonus & bonus : info.reward.bonuses)
{ {
assert(bonus.source == Bonus::OBJECT); assert(bonus.source == Bonus::OBJECT);
assert(bonus.sid == ID); assert(bonus.sid == ID);
@ -286,16 +286,16 @@ void CRewardableObject::grantRewardAfterLevelup(const CVisitInfo & info, const C
cb->giveHeroBonus(&gb); cb->giveHeroBonus(&gb);
} }
for (ArtifactID art : info.reward.artifacts) for(ArtifactID art : info.reward.artifacts)
cb->giveHeroNewArtifact(hero, VLC->arth->artifacts[art],ArtifactPosition::FIRST_AVAILABLE); cb->giveHeroNewArtifact(hero, VLC->arth->artifacts[art],ArtifactPosition::FIRST_AVAILABLE);
if (!info.reward.spells.empty()) if(!info.reward.spells.empty())
{ {
std::set<SpellID> spellsToGive(info.reward.spells.begin(), info.reward.spells.end()); std::set<SpellID> spellsToGive(info.reward.spells.begin(), info.reward.spells.end());
cb->changeSpells(hero, true, spellsToGive); cb->changeSpells(hero, true, spellsToGive);
} }
if (!info.reward.creatures.empty()) if(!info.reward.creatures.empty())
{ {
CCreatureSet creatures; CCreatureSet creatures;
for (auto & crea : info.reward.creatures) for (auto & crea : info.reward.creatures)
@ -306,11 +306,11 @@ void CRewardableObject::grantRewardAfterLevelup(const CVisitInfo & info, const C
onRewardGiven(hero); onRewardGiven(hero);
if (info.reward.removeObject) if(info.reward.removeObject)
cb->removeObject(this); cb->removeObject(this);
} }
bool CRewardableObject::wasVisited (PlayerColor player) const bool CRewardableObject::wasVisited(PlayerColor player) const
{ {
switch (visitMode) switch (visitMode)
{ {
@ -332,7 +332,7 @@ bool CRewardableObject::wasVisited (PlayerColor player) const
} }
} }
bool CRewardableObject::wasVisited (const CGHeroInstance * h) const bool CRewardableObject::wasVisited(const CGHeroInstance * h) const
{ {
switch (visitMode) switch (visitMode)
{ {
@ -783,6 +783,32 @@ void CGBonusingObject::onHeroVisit(const CGHeroInstance *h) const
} }
} }
bool CGBonusingObject::wasVisited(const CGHeroInstance * h) const
{
if(ID == Obj::STABLES)
{
for(auto& slot : h->Slots())
{
if(slot.second->type->idNumber == CreatureID::CAVALIER)
{
// always display the reward message if the hero got cavaliers
return false;
}
}
}
return CRewardableObject::wasVisited(h);
}
void CGBonusingObject::grantReward(ui32 rewardID, const CGHeroInstance * hero) const
{
if(ID == Obj::STABLES && CRewardableObject::wasVisited(hero))
{
// reward message has been displayed - do not give the actual bonus
return;
}
CRewardableObject::grantReward(rewardID, hero);
}
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
CGOnceVisitable::CGOnceVisitable() CGOnceVisitable::CGOnceVisitable()

View File

@ -159,8 +159,6 @@ public:
/// Inherits from CArmedInstance for proper trasfer of armies /// Inherits from CArmedInstance for proper trasfer of armies
class DLL_LINKAGE CRewardableObject : public CArmedInstance class DLL_LINKAGE CRewardableObject : public CArmedInstance
{ {
void grantReward(ui32 rewardID, const CGHeroInstance * hero) const;
/// function that must be called if hero got level-up during grantReward call /// function that must be called if hero got level-up during grantReward call
void grantRewardAfterLevelup(const CVisitInfo & reward, const CGHeroInstance * hero) const; void grantRewardAfterLevelup(const CVisitInfo & reward, const CGHeroInstance * hero) const;
@ -188,6 +186,8 @@ protected:
/// filters list of visit info and returns rewards that can be granted to current hero /// filters list of visit info and returns rewards that can be granted to current hero
virtual std::vector<ui32> getAvailableRewards(const CGHeroInstance * hero) const; virtual std::vector<ui32> getAvailableRewards(const CGHeroInstance * hero) const;
virtual void grantReward(ui32 rewardID, const CGHeroInstance * hero) const;
virtual CVisitInfo getVisitInfo(int index, const CGHeroInstance *h) const; virtual CVisitInfo getVisitInfo(int index, const CGHeroInstance *h) const;
/// Rewards that can be granted by an object /// Rewards that can be granted by an object
@ -219,8 +219,8 @@ public:
std::string getHoverText(const CGHeroInstance * hero) const override; std::string getHoverText(const CGHeroInstance * hero) const override;
/// Visitability checks. Note that hero check includes check for hero owner (returns true if object was visited by player) /// Visitability checks. Note that hero check includes check for hero owner (returns true if object was visited by player)
bool wasVisited (PlayerColor player) const override; bool wasVisited(PlayerColor player) const override;
bool wasVisited (const CGHeroInstance * h) const override; bool wasVisited(const CGHeroInstance * h) const override;
/// gives reward to player or ask for choice in case of multiple rewards /// gives reward to player or ask for choice in case of multiple rewards
void onHeroVisit(const CGHeroInstance *h) const override; void onHeroVisit(const CGHeroInstance *h) const override;
@ -269,6 +269,8 @@ class DLL_LINKAGE CGBonusingObject : public CRewardableObject //objects giving b
protected: protected:
CVisitInfo getVisitInfo(int index, const CGHeroInstance *h) const override; CVisitInfo getVisitInfo(int index, const CGHeroInstance *h) const override;
void grantReward(ui32 rewardID, const CGHeroInstance * hero) const override;
public: public:
void initObj() override; void initObj() override;
@ -276,6 +278,8 @@ public:
void onHeroVisit(const CGHeroInstance *h) const override; void onHeroVisit(const CGHeroInstance *h) const override;
bool wasVisited(const CGHeroInstance * h) 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<CRewardableObject&>(*this); h & static_cast<CRewardableObject&>(*this);