mirror of
https://github.com/vcmi/vcmi.git
synced 2025-06-17 00:07:41 +02:00
Refactor quests progress
This commit is contained in:
@ -25,7 +25,7 @@ namespace AIPathfinding
|
|||||||
return dynamic_cast<const IQuestObject *>(questInfo.obj)->checkQuest(node->actor->hero);
|
return dynamic_cast<const IQuestObject *>(questInfo.obj)->checkQuest(node->actor->hero);
|
||||||
}
|
}
|
||||||
|
|
||||||
return questInfo.quest->progress == CQuest::NOT_ACTIVE
|
return questInfo.quest->activeForPlayers.count(node->actor->hero->getOwner())
|
||||||
|| questInfo.quest->checkQuest(node->actor->hero);
|
|| questInfo.quest->checkQuest(node->actor->hero);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ TGoalVec CompleteQuest::getAllPossibleSubgoals()
|
|||||||
{
|
{
|
||||||
TGoalVec solutions;
|
TGoalVec solutions;
|
||||||
|
|
||||||
if(q.quest->progress != CQuest::COMPLETE)
|
if(!q.quest->isCompleted)
|
||||||
{
|
{
|
||||||
logAi->debug("Trying to realize quest: %s", questToString());
|
logAi->debug("Trying to realize quest: %s", questToString());
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ void CQuestLog::recreateLabelList()
|
|||||||
if (quests[i].quest->questName == CQuest::missionName(0))
|
if (quests[i].quest->questName == CQuest::missionName(0))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (quests[i].quest->progress == CQuest::COMPLETE)
|
if (quests[i].quest->isCompleted)
|
||||||
{
|
{
|
||||||
completeMissing = false;
|
completeMissing = false;
|
||||||
if (hideComplete)
|
if (hideComplete)
|
||||||
@ -180,7 +180,7 @@ void CQuestLog::recreateLabelList()
|
|||||||
labels.push_back(label);
|
labels.push_back(label);
|
||||||
|
|
||||||
// Select latest active quest
|
// Select latest active quest
|
||||||
if (quests[i].quest->progress != CQuest::COMPLETE)
|
if(!quests[i].quest->isCompleted)
|
||||||
selectQuest(i, currentLabel);
|
selectQuest(i, currentLabel);
|
||||||
|
|
||||||
currentLabel = static_cast<int>(labels.size());
|
currentLabel = static_cast<int>(labels.size());
|
||||||
|
@ -38,7 +38,7 @@ std::map <PlayerColor, std::set <ui8> > CGKeys::playerKeyMap;
|
|||||||
//TODO: Remove constructor
|
//TODO: Remove constructor
|
||||||
CQuest::CQuest():
|
CQuest::CQuest():
|
||||||
qid(-1),
|
qid(-1),
|
||||||
progress(NOT_ACTIVE),
|
isCompleted(false),
|
||||||
lastDay(-1),
|
lastDay(-1),
|
||||||
killTarget(ObjectInstanceID::NONE),
|
killTarget(ObjectInstanceID::NONE),
|
||||||
textOption(0),
|
textOption(0),
|
||||||
@ -451,13 +451,11 @@ void CGSeerHut::initObj(CRandomGenerator & rand)
|
|||||||
|
|
||||||
CRewardableObject::initObj(rand);
|
CRewardableObject::initObj(rand);
|
||||||
|
|
||||||
quest->progress = CQuest::NOT_ACTIVE;
|
|
||||||
|
|
||||||
setObjToKill();
|
setObjToKill();
|
||||||
quest->defineQuestName();
|
quest->defineQuestName();
|
||||||
|
|
||||||
if(quest->mission == Rewardable::Limiter{} && quest->killTarget == ObjectInstanceID::NONE)
|
if(quest->mission == Rewardable::Limiter{} && quest->killTarget == ObjectInstanceID::NONE)
|
||||||
quest->progress = CQuest::COMPLETE;
|
quest->isCompleted = true;
|
||||||
|
|
||||||
if(quest->questName == quest->missionName(0))
|
if(quest->questName == quest->missionName(0))
|
||||||
{
|
{
|
||||||
@ -484,13 +482,15 @@ void CGSeerHut::getRolloverText(MetaString &text, bool onHover) const
|
|||||||
std::string CGSeerHut::getHoverText(PlayerColor player) const
|
std::string CGSeerHut::getHoverText(PlayerColor player) const
|
||||||
{
|
{
|
||||||
std::string hoverName = getObjectName();
|
std::string hoverName = getObjectName();
|
||||||
if(ID == Obj::SEER_HUT && quest->progress != CQuest::NOT_ACTIVE)
|
if(ID == Obj::SEER_HUT && quest->activeForPlayers.count(player))
|
||||||
{
|
{
|
||||||
hoverName = VLC->generaltexth->allTexts[347];
|
hoverName = VLC->generaltexth->allTexts[347];
|
||||||
boost::algorithm::replace_first(hoverName, "%s", seerName);
|
boost::algorithm::replace_first(hoverName, "%s", seerName);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(quest->progress/* & quest->missionType*/) //rollover when the quest is active
|
if(quest->activeForPlayers.count(player)
|
||||||
|
&& (quest->mission != Rewardable::Limiter{}
|
||||||
|
|| quest->killTarget != ObjectInstanceID::NONE)) //rollover when the quest is active
|
||||||
{
|
{
|
||||||
MetaString ms;
|
MetaString ms;
|
||||||
getRolloverText (ms, true);
|
getRolloverText (ms, true);
|
||||||
@ -503,10 +503,18 @@ void CGSeerHut::setPropertyDer (ui8 what, ui32 val)
|
|||||||
{
|
{
|
||||||
switch(what)
|
switch(what)
|
||||||
{
|
{
|
||||||
case CGSeerHut::OBJPROP_VISITED:
|
case CGSeerHut::SEERHUT_VISITED:
|
||||||
quest->progress = static_cast<CQuest::EProgress>(val);
|
{
|
||||||
|
quest->activeForPlayers.emplace(val);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case CGSeerHut::SEERHUT_COMPLETE:
|
||||||
|
{
|
||||||
|
quest->isCompleted = val;
|
||||||
|
quest->activeForPlayers.clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGSeerHut::newTurn(CRandomGenerator & rand) const
|
void CGSeerHut::newTurn(CRandomGenerator & rand) const
|
||||||
@ -514,7 +522,7 @@ void CGSeerHut::newTurn(CRandomGenerator & rand) const
|
|||||||
CRewardableObject::newTurn(rand);
|
CRewardableObject::newTurn(rand);
|
||||||
if(quest->lastDay >= 0 && quest->lastDay <= cb->getDate() - 1) //time is up
|
if(quest->lastDay >= 0 && quest->lastDay <= cb->getDate() - 1) //time is up
|
||||||
{
|
{
|
||||||
cb->setObjProperty (id, CGSeerHut::OBJPROP_VISITED, CQuest::COMPLETE);
|
cb->setObjProperty (id, CGSeerHut::SEERHUT_COMPLETE, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -522,14 +530,14 @@ void CGSeerHut::onHeroVisit(const CGHeroInstance * h) const
|
|||||||
{
|
{
|
||||||
InfoWindow iw;
|
InfoWindow iw;
|
||||||
iw.player = h->getOwner();
|
iw.player = h->getOwner();
|
||||||
if(quest->progress < CQuest::COMPLETE)
|
if(!quest->isCompleted)
|
||||||
{
|
{
|
||||||
bool firstVisit = !quest->progress;
|
bool firstVisit = !quest->activeForPlayers.count(h->getOwner());
|
||||||
bool failRequirements = !checkQuest(h);
|
bool failRequirements = !checkQuest(h);
|
||||||
|
|
||||||
if(firstVisit)
|
if(firstVisit)
|
||||||
{
|
{
|
||||||
cb->setObjProperty(id, CGSeerHut::OBJPROP_VISITED, CQuest::IN_PROGRESS);
|
cb->setObjProperty(id, CGSeerHut::SEERHUT_VISITED, h->getOwner());
|
||||||
|
|
||||||
AddQuest aq;
|
AddQuest aq;
|
||||||
aq.quest = QuestInfo (quest, this, visitablePos());
|
aq.quest = QuestInfo (quest, this, visitablePos());
|
||||||
@ -612,10 +620,7 @@ void CGSeerHut::blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer)
|
|||||||
if(answer)
|
if(answer)
|
||||||
{
|
{
|
||||||
quest->completeQuest(cb, hero);
|
quest->completeQuest(cb, hero);
|
||||||
if(quest && quest->repeatedQuest)
|
cb->setObjProperty(id, CGSeerHut::SEERHUT_COMPLETE, !quest->repeatedQuest); //mission complete
|
||||||
cb->setObjProperty(id, CGSeerHut::OBJPROP_VISITED, CQuest::NOT_ACTIVE);
|
|
||||||
else
|
|
||||||
cb->setObjProperty(id, CGSeerHut::OBJPROP_VISITED, CQuest::COMPLETE); //mission complete
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,12 +21,6 @@ class DLL_LINKAGE CQuest final
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum EProgress {
|
|
||||||
NOT_ACTIVE,
|
|
||||||
IN_PROGRESS,
|
|
||||||
COMPLETE
|
|
||||||
};
|
|
||||||
|
|
||||||
static const std::string & missionName(int index);
|
static const std::string & missionName(int index);
|
||||||
static const std::string & missionState(int index);
|
static const std::string & missionState(int index);
|
||||||
|
|
||||||
@ -34,11 +28,12 @@ public:
|
|||||||
|
|
||||||
si32 qid; //unique quest id for serialization / identification
|
si32 qid; //unique quest id for serialization / identification
|
||||||
|
|
||||||
EProgress progress;
|
|
||||||
si32 lastDay; //after this day (first day is 0) mission cannot be completed; if -1 - no limit
|
si32 lastDay; //after this day (first day is 0) mission cannot be completed; if -1 - no limit
|
||||||
ObjectInstanceID killTarget;
|
ObjectInstanceID killTarget;
|
||||||
Rewardable::Limiter mission;
|
Rewardable::Limiter mission;
|
||||||
bool repeatedQuest;
|
bool repeatedQuest;
|
||||||
|
bool isCompleted;
|
||||||
|
std::set<PlayerColor> activeForPlayers;
|
||||||
|
|
||||||
// following fields are used only for kill creature/hero missions, the original
|
// following fields are used only for kill creature/hero missions, the original
|
||||||
// objects became inaccessible after their removal, so we need to store info
|
// objects became inaccessible after their removal, so we need to store info
|
||||||
@ -75,7 +70,8 @@ public:
|
|||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & qid;
|
h & qid;
|
||||||
h & progress;
|
h & isCompleted;
|
||||||
|
h & activeForPlayers;
|
||||||
h & lastDay;
|
h & lastDay;
|
||||||
h & textOption;
|
h & textOption;
|
||||||
h & stackToKill;
|
h & stackToKill;
|
||||||
@ -143,7 +139,8 @@ public:
|
|||||||
h & seerName;
|
h & seerName;
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
static constexpr int OBJPROP_VISITED = 10;
|
static constexpr int SEERHUT_VISITED = 10;
|
||||||
|
static constexpr int SEERHUT_COMPLETE = 11;
|
||||||
|
|
||||||
void setPropertyDer(ui8 what, ui32 val) override;
|
void setPropertyDer(ui8 what, ui32 val) override;
|
||||||
|
|
||||||
|
@ -57,6 +57,11 @@ bool operator==(const Rewardable::Limiter & l, const Rewardable::Limiter & r)
|
|||||||
&& l.anyOf == r.anyOf;
|
&& l.anyOf == r.anyOf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool operator!=(const Rewardable::Limiter & l, const Rewardable::Limiter & r)
|
||||||
|
{
|
||||||
|
return !(l == r);
|
||||||
|
}
|
||||||
|
|
||||||
bool Rewardable::Limiter::heroAllowed(const CGHeroInstance * hero) const
|
bool Rewardable::Limiter::heroAllowed(const CGHeroInstance * hero) const
|
||||||
{
|
{
|
||||||
if(dayOfWeek != 0)
|
if(dayOfWeek != 0)
|
||||||
|
@ -113,5 +113,6 @@ struct DLL_LINKAGE Limiter final
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool DLL_LINKAGE operator== (const Rewardable::Limiter & l, const Rewardable::Limiter & r);
|
bool DLL_LINKAGE operator== (const Rewardable::Limiter & l, const Rewardable::Limiter & r);
|
||||||
|
bool DLL_LINKAGE operator!= (const Rewardable::Limiter & l, const Rewardable::Limiter & r);
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_END
|
VCMI_LIB_NAMESPACE_END
|
||||||
|
Reference in New Issue
Block a user