mirror of
https://github.com/vcmi/vcmi.git
synced 2025-06-17 00:07:41 +02:00
Quests will now be handled as object member instead of inheritance. Enabled quest objects for AI.
This commit is contained in:
@ -3462,7 +3462,7 @@ bool shouldVisit(HeroPtr h, const CGObjectInstance * obj)
|
|||||||
case Obj::SEER_HUT:
|
case Obj::SEER_HUT:
|
||||||
case Obj::QUEST_GUARD:
|
case Obj::QUEST_GUARD:
|
||||||
{
|
{
|
||||||
return false; //fixme: avoid crash
|
//return false; //fixme: avoid crash
|
||||||
BOOST_FOREACH (auto q, ai->myCb->getMyQuests())
|
BOOST_FOREACH (auto q, ai->myCb->getMyQuests())
|
||||||
{
|
{
|
||||||
if (q.obj == obj)
|
if (q.obj == obj)
|
||||||
|
@ -1281,7 +1281,8 @@ void CBoundedLabel::showAll(SDL_Surface * to)
|
|||||||
for (int i = 0; i < lineCapacity; i++)
|
for (int i = 0; i < lineCapacity; i++)
|
||||||
{
|
{
|
||||||
const std::string &line = lines[i];
|
const std::string &line = lines[i];
|
||||||
if(!line.size()) continue;
|
if ( !(lines.size() && line.size())) //empty message or empty line
|
||||||
|
continue;
|
||||||
|
|
||||||
int x = pos.x;
|
int x = pos.x;
|
||||||
if(alignment == CENTER)
|
if(alignment == CENTER)
|
||||||
|
@ -4404,41 +4404,41 @@ void CQuest::getCompletionText (MetaString &iwText, std::vector<Component> &comp
|
|||||||
}
|
}
|
||||||
void CGSeerHut::setObjToKill()
|
void CGSeerHut::setObjToKill()
|
||||||
{
|
{
|
||||||
if (missionType == MISSION_KILL_CREATURE)
|
if (quest.missionType == CQuest::MISSION_KILL_CREATURE)
|
||||||
{
|
{
|
||||||
stackToKill = getCreatureToKill(false)->getStack(0); //FIXME: stacks tend to dissapear (desync?) on server :?
|
quest.stackToKill = getCreatureToKill(false)->getStack(0); //FIXME: stacks tend to dissapear (desync?) on server :?
|
||||||
stackToKill.count = 0; //no count in info window
|
quest.stackToKill.count = 0; //no count in info window
|
||||||
stackDirection = checkDirection();
|
quest.stackDirection = checkDirection();
|
||||||
}
|
}
|
||||||
else if (missionType == MISSION_KILL_HERO)
|
else if (quest.missionType == CQuest::MISSION_KILL_HERO)
|
||||||
{
|
{
|
||||||
heroName = getHeroToKill(false)->name;
|
quest.heroName = getHeroToKill(false)->name;
|
||||||
heroPortrait = getHeroToKill(false)->portrait;
|
quest.heroPortrait = getHeroToKill(false)->portrait;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGSeerHut::initObj()
|
void CGSeerHut::initObj()
|
||||||
{
|
{
|
||||||
seerName = VLC->generaltexth->seerNames[ran()%VLC->generaltexth->seerNames.size()];
|
seerName = VLC->generaltexth->seerNames[ran()%VLC->generaltexth->seerNames.size()];
|
||||||
textOption = ran()%3;
|
quest.textOption = ran()%3;
|
||||||
progress = 0;
|
quest.progress = 0;
|
||||||
if (missionType)
|
if (quest.missionType)
|
||||||
{
|
{
|
||||||
if (!isCustomFirst)
|
if (!quest.isCustomFirst)
|
||||||
firstVisitText = VLC->generaltexth->quests[missionType-1][0][textOption];
|
quest.firstVisitText = VLC->generaltexth->quests[quest.missionType-1][0][quest.textOption];
|
||||||
if (!isCustomNext)
|
if (!quest.isCustomNext)
|
||||||
nextVisitText = VLC->generaltexth->quests[missionType-1][1][textOption];
|
quest.nextVisitText = VLC->generaltexth->quests[quest.missionType-1][1][quest.textOption];
|
||||||
if (!isCustomComplete)
|
if (!quest.isCustomComplete)
|
||||||
completedText = VLC->generaltexth->quests[missionType-1][2][textOption];
|
quest.completedText = VLC->generaltexth->quests[quest.missionType-1][2][quest.textOption];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
firstVisitText = VLC->generaltexth->seerEmpty[textOption];
|
quest.firstVisitText = VLC->generaltexth->seerEmpty[quest.textOption];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGSeerHut::getRolloverText (MetaString &text, bool onHover) const
|
void CGSeerHut::getRolloverText (MetaString &text, bool onHover) const
|
||||||
{
|
{
|
||||||
CQuest::getRolloverText (text, onHover);//TODO: simplify?
|
quest.getRolloverText (text, onHover);//TODO: simplify?
|
||||||
if (!onHover)
|
if (!onHover)
|
||||||
text.addReplacement(seerName);
|
text.addReplacement(seerName);
|
||||||
}
|
}
|
||||||
@ -4448,7 +4448,7 @@ const std::string & CGSeerHut::getHoverText() const
|
|||||||
switch (ID)
|
switch (ID)
|
||||||
{
|
{
|
||||||
case 83:
|
case 83:
|
||||||
if (progress)
|
if (quest.progress)
|
||||||
{
|
{
|
||||||
hoverName = VLC->generaltexth->allTexts[347];
|
hoverName = VLC->generaltexth->allTexts[347];
|
||||||
boost::algorithm::replace_first(hoverName,"%s", seerName);
|
boost::algorithm::replace_first(hoverName,"%s", seerName);
|
||||||
@ -4462,7 +4462,7 @@ const std::string & CGSeerHut::getHoverText() const
|
|||||||
default:
|
default:
|
||||||
tlog5 << "unrecognized quest object\n";
|
tlog5 << "unrecognized quest object\n";
|
||||||
}
|
}
|
||||||
if (progress & missionType) //rollover when the quest is active
|
if (quest.progress & quest.missionType) //rollover when the quest is active
|
||||||
{
|
{
|
||||||
MetaString ms;
|
MetaString ms;
|
||||||
getRolloverText (ms, true);
|
getRolloverText (ms, true);
|
||||||
@ -4488,9 +4488,19 @@ void CQuest::addReplacements(MetaString &out, const std::string &base) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IQuestObject::checkQuest(const CGHeroInstance* h) const
|
||||||
|
{
|
||||||
|
return quest.checkQuest(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IQuestObject::getVisitText (MetaString &text, std::vector<Component> &components, bool isCustom, bool FirstVisit, const CGHeroInstance * h) const
|
||||||
|
{
|
||||||
|
quest.getVisitText (text,components, isCustom, FirstVisit, h);
|
||||||
|
}
|
||||||
|
|
||||||
void CGSeerHut::getCompletionText(MetaString &text, std::vector<Component> &components, bool isCustom, const CGHeroInstance * h) const
|
void CGSeerHut::getCompletionText(MetaString &text, std::vector<Component> &components, bool isCustom, const CGHeroInstance * h) const
|
||||||
{
|
{
|
||||||
CQuest::getCompletionText (text, components, isCustom, h);
|
quest.getCompletionText (text, components, isCustom, h);
|
||||||
switch (rewardType)
|
switch (rewardType)
|
||||||
{
|
{
|
||||||
case 1: components.push_back(Component (Component::EXPERIENCE, 0, rVal*(100+h->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0, 0));
|
case 1: components.push_back(Component (Component::EXPERIENCE, 0, rVal*(100+h->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0, 0));
|
||||||
@ -4521,16 +4531,16 @@ void CGSeerHut::setPropertyDer (ui8 what, ui32 val)
|
|||||||
switch (what)
|
switch (what)
|
||||||
{
|
{
|
||||||
case 10:
|
case 10:
|
||||||
progress = val;
|
quest.progress = val;
|
||||||
break;
|
break;
|
||||||
case 11:
|
case 11:
|
||||||
missionType = CQuest::MISSION_NONE;
|
quest.missionType = CQuest::MISSION_NONE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void CGSeerHut::newTurn() const
|
void CGSeerHut::newTurn() const
|
||||||
{
|
{
|
||||||
if (lastDay >= 0 && lastDay < cb->getDate(0)) //time is up
|
if (quest.lastDay >= 0 && quest.lastDay < cb->getDate(0)) //time is up
|
||||||
{
|
{
|
||||||
cb->setObjProperty (id, 11, 0);
|
cb->setObjProperty (id, 11, 0);
|
||||||
cb->setObjProperty (id, 10, 0);
|
cb->setObjProperty (id, 10, 0);
|
||||||
@ -4541,25 +4551,25 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const
|
|||||||
{
|
{
|
||||||
InfoWindow iw;
|
InfoWindow iw;
|
||||||
iw.player = h->getOwner();
|
iw.player = h->getOwner();
|
||||||
if (missionType)
|
if (quest.missionType)
|
||||||
{
|
{
|
||||||
bool firstVisit = !progress;
|
bool firstVisit = !quest.progress;
|
||||||
bool failRequirements = !checkQuest(h);
|
bool failRequirements = !checkQuest(h);
|
||||||
bool isCustom=false;
|
bool isCustom=false;
|
||||||
|
|
||||||
if (firstVisit)
|
if (firstVisit)
|
||||||
{
|
{
|
||||||
isCustom = isCustomFirst;
|
isCustom = quest.isCustomFirst;
|
||||||
cb->setObjProperty (id, 10, IN_PROGRESS);
|
cb->setObjProperty (id, 10, CQuest::IN_PROGRESS);
|
||||||
|
|
||||||
AddQuest aq;
|
AddQuest aq;
|
||||||
aq.quest = QuestInfo (this, this, visitablePos());
|
aq.quest = QuestInfo (&quest, this, visitablePos());
|
||||||
aq.player = h->tempOwner;
|
aq.player = h->tempOwner;
|
||||||
cb->sendAndApply (&aq); //TODO: merge with setObjProperty?
|
cb->sendAndApply (&aq); //TODO: merge with setObjProperty?
|
||||||
}
|
}
|
||||||
else if (failRequirements)
|
else if (failRequirements)
|
||||||
{
|
{
|
||||||
isCustom = isCustomNext;
|
isCustom = quest.isCustomNext;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstVisit || failRequirements)
|
if (firstVisit || failRequirements)
|
||||||
@ -4582,7 +4592,7 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
iw.text << VLC->generaltexth->seerEmpty[textOption];
|
iw.text << VLC->generaltexth->seerEmpty[quest.textOption];
|
||||||
if (ID == 83)
|
if (ID == 83)
|
||||||
iw.text.addReplacement(seerName);
|
iw.text.addReplacement(seerName);
|
||||||
cb->showInfoDialog(&iw);
|
cb->showInfoDialog(&iw);
|
||||||
@ -4623,27 +4633,27 @@ void CGSeerHut::finishQuest(const CGHeroInstance * h, ui32 accept) const
|
|||||||
{
|
{
|
||||||
if (accept)
|
if (accept)
|
||||||
{
|
{
|
||||||
switch (missionType)
|
switch (quest.missionType)
|
||||||
{
|
{
|
||||||
case CQuest::MISSION_ART:
|
case CQuest::MISSION_ART:
|
||||||
for (std::vector<ui16>::const_iterator it = m5arts.begin(); it != m5arts.end(); ++it)
|
for (std::vector<ui16>::const_iterator it = quest.m5arts.begin(); it != quest.m5arts.end(); ++it)
|
||||||
{
|
{
|
||||||
cb->removeArtifact(ArtifactLocation(h, h->getArtPos(*it, false)));
|
cb->removeArtifact(ArtifactLocation(h, h->getArtPos(*it, false)));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CQuest::MISSION_ARMY:
|
case CQuest::MISSION_ARMY:
|
||||||
cb->takeCreatures(h->id, m6creatures);
|
cb->takeCreatures(h->id, quest.m6creatures);
|
||||||
break;
|
break;
|
||||||
case CQuest::MISSION_RESOURCES:
|
case CQuest::MISSION_RESOURCES:
|
||||||
for (int i = 0; i < 7; ++i)
|
for (int i = 0; i < 7; ++i)
|
||||||
{
|
{
|
||||||
cb->giveResource(h->getOwner(), i, -m7resources[i]);
|
cb->giveResource(h->getOwner(), i, -quest.m7resources[i]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cb->setObjProperty (id, 10, COMPLETE); //mission complete - for AI
|
cb->setObjProperty (id, 10, CQuest::COMPLETE); //mission complete - for AI
|
||||||
cb->setObjProperty (id, 11, 0); //no more mission available - redundant?
|
cb->setObjProperty (id, 11, 0); //no more mission available - redundant?
|
||||||
completeQuest(h); //make sure to remove QuestQuard at the very end
|
completeQuest(h); //make sure to remove QuestQuard at the very end
|
||||||
}
|
}
|
||||||
@ -4706,7 +4716,7 @@ void CGSeerHut::completeQuest (const CGHeroInstance * h) const //reward
|
|||||||
|
|
||||||
const CGHeroInstance * CGSeerHut::getHeroToKill(bool allowNull) const
|
const CGHeroInstance * CGSeerHut::getHeroToKill(bool allowNull) const
|
||||||
{
|
{
|
||||||
const CGObjectInstance *o = cb->getObjByQuestIdentifier(m13489val);
|
const CGObjectInstance *o = cb->getObjByQuestIdentifier(quest.m13489val);
|
||||||
if(allowNull && !o)
|
if(allowNull && !o)
|
||||||
return NULL;
|
return NULL;
|
||||||
assert(o && o->ID == GameConstants::HEROI_TYPE);
|
assert(o && o->ID == GameConstants::HEROI_TYPE);
|
||||||
@ -4715,7 +4725,7 @@ const CGHeroInstance * CGSeerHut::getHeroToKill(bool allowNull) const
|
|||||||
|
|
||||||
const CGCreature * CGSeerHut::getCreatureToKill(bool allowNull) const
|
const CGCreature * CGSeerHut::getCreatureToKill(bool allowNull) const
|
||||||
{
|
{
|
||||||
const CGObjectInstance *o = cb->getObjByQuestIdentifier(m13489val);
|
const CGObjectInstance *o = cb->getObjByQuestIdentifier(quest.m13489val);
|
||||||
if(allowNull && !o)
|
if(allowNull && !o)
|
||||||
return NULL;
|
return NULL;
|
||||||
assert(o && o->ID == 54);
|
assert(o && o->ID == 54);
|
||||||
@ -4725,19 +4735,19 @@ const CGCreature * CGSeerHut::getCreatureToKill(bool allowNull) const
|
|||||||
void CGQuestGuard::initObj()
|
void CGQuestGuard::initObj()
|
||||||
{
|
{
|
||||||
blockVisit = true;
|
blockVisit = true;
|
||||||
progress = 0;
|
quest.progress = 0;
|
||||||
textOption = ran()%3 + 3; //3-5
|
quest.textOption = ran()%3 + 3; //3-5
|
||||||
if (missionType)
|
if (quest.missionType)
|
||||||
{
|
{
|
||||||
if (!isCustomFirst)
|
if (!quest.isCustomFirst)
|
||||||
firstVisitText = VLC->generaltexth->quests[missionType-1][0][textOption];
|
quest.firstVisitText = VLC->generaltexth->quests[quest.missionType-1][0][quest.textOption];
|
||||||
if (!isCustomNext)
|
if (!quest.isCustomNext)
|
||||||
nextVisitText = VLC->generaltexth->quests[missionType-1][1][textOption];
|
quest.nextVisitText = VLC->generaltexth->quests[quest.missionType-1][1][quest.textOption];
|
||||||
if (!isCustomComplete)
|
if (!quest.isCustomComplete)
|
||||||
completedText = VLC->generaltexth->quests[missionType-1][2][textOption];
|
quest.completedText = VLC->generaltexth->quests[quest.missionType-1][2][quest.textOption];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
firstVisitText = VLC->generaltexth->seerEmpty[textOption];
|
quest.firstVisitText = VLC->generaltexth->seerEmpty[quest.textOption];
|
||||||
}
|
}
|
||||||
void CGQuestGuard::completeQuest(const CGHeroInstance *h) const
|
void CGQuestGuard::completeQuest(const CGHeroInstance *h) const
|
||||||
{
|
{
|
||||||
@ -6361,7 +6371,7 @@ void CGBorderGuard::onHeroVisit( const CGHeroInstance * h ) const
|
|||||||
cb->showInfoDialog (&iw);
|
cb->showInfoDialog (&iw);
|
||||||
|
|
||||||
AddQuest aq;
|
AddQuest aq;
|
||||||
aq.quest = QuestInfo (this, this, visitablePos());
|
aq.quest = QuestInfo (&quest, this, visitablePos());
|
||||||
aq.player = h->tempOwner;
|
aq.player = h->tempOwner;
|
||||||
cb->sendAndApply (&aq);
|
cb->sendAndApply (&aq);
|
||||||
//TODO: add this quest only once OR check for multiple instances later
|
//TODO: add this quest only once OR check for multiple instances later
|
||||||
@ -6384,7 +6394,7 @@ void CGBorderGate::onHeroVisit( const CGHeroInstance * h ) const //TODO: passabi
|
|||||||
cb->showInfoDialog(&iw);
|
cb->showInfoDialog(&iw);
|
||||||
|
|
||||||
AddQuest aq;
|
AddQuest aq;
|
||||||
aq.quest = QuestInfo (this, this, visitablePos());
|
aq.quest = QuestInfo (&quest, this, visitablePos());
|
||||||
aq.player = h->tempOwner;
|
aq.player = h->tempOwner;
|
||||||
cb->sendAndApply (&aq);
|
cb->sendAndApply (&aq);
|
||||||
}
|
}
|
||||||
|
@ -759,7 +759,21 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE CGSeerHut : public CArmedInstance, public CQuest //army is used when giving reward
|
class DLL_LINKAGE IQuestObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CQuest quest;
|
||||||
|
|
||||||
|
virtual void getVisitText (MetaString &text, std::vector<Component> &components, bool isCustom, bool FirstVisit, const CGHeroInstance * h = NULL) const;
|
||||||
|
virtual bool checkQuest (const CGHeroInstance * h) const;
|
||||||
|
|
||||||
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
|
{
|
||||||
|
h & quest;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class DLL_LINKAGE CGSeerHut : public CArmedInstance, public IQuestObject //army is used when giving reward
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ui8 rewardType; //type of reward: 0 - no reward; 1 - experience; 2 - mana points; 3 - morale bonus; 4 - luck bonus; 5 - resources; 6 - main ability bonus (attak, defence etd.); 7 - secondary ability gain; 8 - artifact; 9 - spell; 10 - creature
|
ui8 rewardType; //type of reward: 0 - no reward; 1 - experience; 2 - mana points; 3 - morale bonus; 4 - luck bonus; 5 - resources; 6 - main ability bonus (attak, defence etd.); 7 - secondary ability gain; 8 - artifact; 9 - spell; 10 - creature
|
||||||
@ -770,21 +784,21 @@ public:
|
|||||||
void initObj();
|
void initObj();
|
||||||
const std::string & getHoverText() const;
|
const std::string & getHoverText() const;
|
||||||
void setPropertyDer (ui8 what, ui32 val);
|
void setPropertyDer (ui8 what, ui32 val);
|
||||||
int checkDirection() const; //calculates the region of map where monster is placed
|
|
||||||
void newTurn() const;
|
void newTurn() const;
|
||||||
void onHeroVisit (const CGHeroInstance * h) const;
|
void onHeroVisit (const CGHeroInstance * h) const;
|
||||||
|
|
||||||
|
int checkDirection() const; //calculates the region of map where monster is placed
|
||||||
|
void setObjToKill(); //remember creatures / heroes to kill after they are initialized
|
||||||
|
const CGHeroInstance *getHeroToKill(bool allowNull = false) const;
|
||||||
|
const CGCreature *getCreatureToKill(bool allowNull = false) const;
|
||||||
void getRolloverText (MetaString &text, bool onHover) const;
|
void getRolloverText (MetaString &text, bool onHover) const;
|
||||||
void getCompletionText(MetaString &text, std::vector<Component> &components, bool isCustom, const CGHeroInstance * h = NULL) const;
|
void getCompletionText(MetaString &text, std::vector<Component> &components, bool isCustom, const CGHeroInstance * h = NULL) const;
|
||||||
void finishQuest (const CGHeroInstance * h, ui32 accept) const; //common for both objects
|
void finishQuest (const CGHeroInstance * h, ui32 accept) const; //common for both objects
|
||||||
void completeQuest (const CGHeroInstance * h) const;
|
void completeQuest (const CGHeroInstance * h) const;
|
||||||
|
|
||||||
void setObjToKill(); //remember creatures / heroes to kill after they are initialized
|
|
||||||
const CGHeroInstance *getHeroToKill(bool allowNull = false) const;
|
|
||||||
const CGCreature *getCreatureToKill(bool allowNull = false) const;
|
|
||||||
|
|
||||||
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) & static_cast<CQuest&>(*this);
|
h & static_cast<CArmedInstance&>(*this) & static_cast<IQuestObject&>(*this);
|
||||||
h & rewardType & rID & rVal & seerName;
|
h & rewardType & rID & rVal & seerName;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1067,7 +1081,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE CGBorderGuard : public CGKeys, public CQuest
|
class DLL_LINKAGE CGBorderGuard : public CGKeys, public IQuestObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void initObj();
|
void initObj();
|
||||||
@ -1080,7 +1094,7 @@ public:
|
|||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & static_cast<CQuest&>(*this);
|
h & static_cast<IQuestObject&>(*this);
|
||||||
h & static_cast<CGObjectInstance&>(*this);
|
h & static_cast<CGObjectInstance&>(*this);
|
||||||
h & blockVisit;
|
h & blockVisit;
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ void registerTypes1(Serializer &s)
|
|||||||
s.template registerType<CGCreature>();
|
s.template registerType<CGCreature>();
|
||||||
s.template registerType<CGSignBottle>();
|
s.template registerType<CGSignBottle>();
|
||||||
s.template registerType<CQuest>();
|
s.template registerType<CQuest>();
|
||||||
|
s.template registerType<IQuestObject>();
|
||||||
s.template registerType<CGSeerHut>();
|
s.template registerType<CGSeerHut>();
|
||||||
s.template registerType<CGQuestGuard>();
|
s.template registerType<CGQuestGuard>();
|
||||||
s.template registerType<CGWitchHut>();
|
s.template registerType<CGWitchHut>();
|
||||||
|
68
lib/map.cpp
68
lib/map.cpp
@ -567,18 +567,18 @@ int Mapa::loadSeerHut( const ui8 * bufor, int i, CGObjectInstance *& nobj )
|
|||||||
int artID = bufor[i]; ++i;
|
int artID = bufor[i]; ++i;
|
||||||
if (artID != 255) //not none quest
|
if (artID != 255) //not none quest
|
||||||
{
|
{
|
||||||
hut->m5arts.push_back (artID);
|
hut->quest.m5arts.push_back (artID);
|
||||||
hut->missionType = CQuest::MISSION_ART;
|
hut->quest.missionType = CQuest::MISSION_ART;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hut->missionType = CQuest::MISSION_NONE; //no mission
|
hut->quest.missionType = CQuest::MISSION_NONE; //no mission
|
||||||
}
|
}
|
||||||
hut->lastDay = -1; //no timeout
|
hut->quest.lastDay = -1; //no timeout
|
||||||
hut->isCustomFirst = hut->isCustomNext = hut->isCustomComplete = false;
|
hut->quest.isCustomFirst = hut->quest.isCustomNext = hut->quest.isCustomComplete = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hut->missionType)
|
if (hut->quest.missionType)
|
||||||
{
|
{
|
||||||
ui8 rewardType = bufor[i]; ++i;
|
ui8 rewardType = bufor[i]; ++i;
|
||||||
hut->rewardType = rewardType;
|
hut->rewardType = rewardType;
|
||||||
@ -1461,7 +1461,7 @@ void Mapa::readObjects( const ui8 * bufor, int &i)
|
|||||||
case 83: //seer's hut
|
case 83: //seer's hut
|
||||||
{
|
{
|
||||||
i = loadSeerHut(bufor, i, nobj);
|
i = loadSeerHut(bufor, i, nobj);
|
||||||
addQuest (dynamic_cast<CQuest *>(nobj));
|
addQuest (dynamic_cast<IQuestObject *>(nobj));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 113: //witch hut
|
case 113: //witch hut
|
||||||
@ -1722,7 +1722,7 @@ void Mapa::readObjects( const ui8 * bufor, int &i)
|
|||||||
CGQuestGuard *guard = new CGQuestGuard();
|
CGQuestGuard *guard = new CGQuestGuard();
|
||||||
nobj = guard;
|
nobj = guard;
|
||||||
loadQuest(guard, bufor, i);
|
loadQuest(guard, bufor, i);
|
||||||
addQuest (dynamic_cast <CQuest *>(guard));
|
addQuest (dynamic_cast <IQuestObject *>(guard));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 28: //faerie ring
|
case 28: //faerie ring
|
||||||
@ -1803,13 +1803,13 @@ void Mapa::readObjects( const ui8 * bufor, int &i)
|
|||||||
case 9: //Border Guard
|
case 9: //Border Guard
|
||||||
{
|
{
|
||||||
nobj = new CGBorderGuard();
|
nobj = new CGBorderGuard();
|
||||||
addQuest (dynamic_cast<CQuest *>(nobj));
|
addQuest (dynamic_cast<IQuestObject *>(nobj));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 212: //Border Gate
|
case 212: //Border Gate
|
||||||
{
|
{
|
||||||
nobj = new CGBorderGate();
|
nobj = new CGBorderGate();
|
||||||
addQuest (dynamic_cast<CQuest *>(nobj));
|
addQuest (dynamic_cast<IQuestObject *>(nobj));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 27: case 37: //Eye and Hut of Magi
|
case 27: case 37: //Eye and Hut of Magi
|
||||||
@ -1945,20 +1945,20 @@ bool Mapa::isInTheMap(const int3 &pos) const
|
|||||||
else return true;
|
else return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mapa::loadQuest(CQuest * guard, const ui8 * bufor, int & i)
|
void Mapa::loadQuest(IQuestObject * guard, const ui8 * bufor, int & i)
|
||||||
{
|
{
|
||||||
guard->missionType = bufor[i]; ++i;
|
guard->quest.missionType = bufor[i]; ++i;
|
||||||
//int len1, len2, len3;
|
//int len1, len2, len3;
|
||||||
switch(guard->missionType)
|
switch(guard->quest.missionType)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
return;
|
return;
|
||||||
case 2:
|
case 2:
|
||||||
{
|
{
|
||||||
guard->m2stats.resize(4);
|
guard->quest.m2stats.resize(4);
|
||||||
for(int x=0; x<4; x++)
|
for(int x=0; x<4; x++)
|
||||||
{
|
{
|
||||||
guard->m2stats[x] = bufor[i++];
|
guard->quest.m2stats[x] = bufor[i++];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1966,7 +1966,7 @@ void Mapa::loadQuest(CQuest * guard, const ui8 * bufor, int & i)
|
|||||||
case 3:
|
case 3:
|
||||||
case 4:
|
case 4:
|
||||||
{
|
{
|
||||||
guard->m13489val = read_le_u32(bufor + i); i+=4;
|
guard->quest.m13489val = read_le_u32(bufor + i); i+=4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 5:
|
case 5:
|
||||||
@ -1975,7 +1975,7 @@ void Mapa::loadQuest(CQuest * guard, const ui8 * bufor, int & i)
|
|||||||
for(int yy=0; yy<artNumber; ++yy)
|
for(int yy=0; yy<artNumber; ++yy)
|
||||||
{
|
{
|
||||||
int artid = read_le_u16(bufor + i); i+=2;
|
int artid = read_le_u16(bufor + i); i+=2;
|
||||||
guard->m5arts.push_back(artid);
|
guard->quest.m5arts.push_back(artid);
|
||||||
allowedArtifact[artid] = false; //these are unavailable for random generation
|
allowedArtifact[artid] = false; //these are unavailable for random generation
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1983,20 +1983,20 @@ void Mapa::loadQuest(CQuest * guard, const ui8 * bufor, int & i)
|
|||||||
case 6:
|
case 6:
|
||||||
{
|
{
|
||||||
int typeNumber = bufor[i]; ++i;
|
int typeNumber = bufor[i]; ++i;
|
||||||
guard->m6creatures.resize(typeNumber);
|
guard->quest.m6creatures.resize(typeNumber);
|
||||||
for(int hh=0; hh<typeNumber; ++hh)
|
for(int hh=0; hh<typeNumber; ++hh)
|
||||||
{
|
{
|
||||||
guard->m6creatures[hh].type = VLC->creh->creatures[read_le_u16(bufor + i)]; i+=2;
|
guard->quest.m6creatures[hh].type = VLC->creh->creatures[read_le_u16(bufor + i)]; i+=2;
|
||||||
guard->m6creatures[hh].count = read_le_u16(bufor + i); i+=2;
|
guard->quest.m6creatures[hh].count = read_le_u16(bufor + i); i+=2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 7:
|
case 7:
|
||||||
{
|
{
|
||||||
guard->m7resources.resize(7);
|
guard->quest.m7resources.resize(7);
|
||||||
for(int x=0; x<7; x++)
|
for(int x=0; x<7; x++)
|
||||||
{
|
{
|
||||||
guard->m7resources[x] = read_le_u32(bufor + i);
|
guard->quest.m7resources[x] = read_le_u32(bufor + i);
|
||||||
i+=4;
|
i+=4;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2004,7 +2004,7 @@ void Mapa::loadQuest(CQuest * guard, const ui8 * bufor, int & i)
|
|||||||
case 8:
|
case 8:
|
||||||
case 9:
|
case 9:
|
||||||
{
|
{
|
||||||
guard->m13489val = bufor[i]; ++i;
|
guard->quest.m13489val = bufor[i]; ++i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2013,18 +2013,18 @@ void Mapa::loadQuest(CQuest * guard, const ui8 * bufor, int & i)
|
|||||||
int limit = read_le_u32(bufor + i); i+=4;
|
int limit = read_le_u32(bufor + i); i+=4;
|
||||||
if(limit == ((int)0xffffffff))
|
if(limit == ((int)0xffffffff))
|
||||||
{
|
{
|
||||||
guard->lastDay = -1;
|
guard->quest.lastDay = -1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
guard->lastDay = limit;
|
guard->quest.lastDay = limit;
|
||||||
}
|
}
|
||||||
guard->firstVisitText = readString(bufor,i);
|
guard->quest.firstVisitText = readString(bufor,i);
|
||||||
guard->nextVisitText = readString(bufor,i);
|
guard->quest.nextVisitText = readString(bufor,i);
|
||||||
guard->completedText = readString(bufor,i);
|
guard->quest.completedText = readString(bufor,i);
|
||||||
guard->isCustomFirst = guard->firstVisitText.size() > 0;
|
guard->quest.isCustomFirst = guard->quest.firstVisitText.size() > 0;
|
||||||
guard->isCustomNext = guard->nextVisitText.size() > 0;
|
guard->quest.isCustomNext = guard->quest.nextVisitText.size() > 0;
|
||||||
guard->isCustomComplete = guard->completedText.size() > 0;
|
guard->quest.isCustomComplete = guard->quest.completedText.size() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
TerrainTile & Mapa::getTile( const int3 & tile )
|
TerrainTile & Mapa::getTile( const int3 & tile )
|
||||||
@ -2070,10 +2070,10 @@ void Mapa::addNewArtifactInstance( CArtifactInstance *art )
|
|||||||
artInstances.push_back(art);
|
artInstances.push_back(art);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mapa::addQuest (CQuest *quest)
|
void Mapa::addQuest (IQuestObject *obj)
|
||||||
{
|
{
|
||||||
quest->qid = quests.size();
|
obj->quest.qid = quests.size();
|
||||||
quests.push_back(quest);
|
quests.push_back(&obj->quest);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mapa::loadArtifactToSlot(CGHeroInstance *h, int slot, const ui8 * bufor, int &i)
|
bool Mapa::loadArtifactToSlot(CGHeroInstance *h, int slot, const ui8 * bufor, int &i)
|
||||||
|
20
lib/map.h
20
lib/map.h
@ -30,6 +30,7 @@ class CGCreature;
|
|||||||
class CQuest;
|
class CQuest;
|
||||||
class CGTownInstance;
|
class CGTownInstance;
|
||||||
class IModableArt;
|
class IModableArt;
|
||||||
|
class IQuestObject;
|
||||||
|
|
||||||
/// Struct which describes a single terrain tile
|
/// Struct which describes a single terrain tile
|
||||||
struct DLL_LINKAGE TerrainTile
|
struct DLL_LINKAGE TerrainTile
|
||||||
@ -306,7 +307,7 @@ struct DLL_LINKAGE Mapa : public CMapHeader
|
|||||||
std::vector< ConstTransitivePtr<CGHeroInstance> > heroes;
|
std::vector< ConstTransitivePtr<CGHeroInstance> > heroes;
|
||||||
std::vector< ConstTransitivePtr<CGTownInstance> > towns;
|
std::vector< ConstTransitivePtr<CGTownInstance> > towns;
|
||||||
std::vector< ConstTransitivePtr<CArtifactInstance> > artInstances; //stores all artifacts
|
std::vector< ConstTransitivePtr<CArtifactInstance> > artInstances; //stores all artifacts
|
||||||
std::vector< ConstTransitivePtr<CQuest> > quests;
|
std::vector< ConstTransitivePtr<CQuest> > quests; //FIXME: allow to serialize quests not related to objects
|
||||||
//std::vector< ConstTransitivePtr<CCommanderInstance> > commanders;
|
//std::vector< ConstTransitivePtr<CCommanderInstance> > commanders;
|
||||||
//bmap<ui16, ConstTransitivePtr<CGCreature> > monsters;
|
//bmap<ui16, ConstTransitivePtr<CGCreature> > monsters;
|
||||||
//bmap<ui16, ConstTransitivePtr<CGHeroInstance> > heroesToBeat;
|
//bmap<ui16, ConstTransitivePtr<CGHeroInstance> > heroesToBeat;
|
||||||
@ -317,7 +318,7 @@ struct DLL_LINKAGE Mapa : public CMapHeader
|
|||||||
|
|
||||||
void readEvents( const ui8 * bufor, int &i);
|
void readEvents( const ui8 * bufor, int &i);
|
||||||
void readObjects( const ui8 * bufor, int &i);
|
void readObjects( const ui8 * bufor, int &i);
|
||||||
void loadQuest( CQuest * guard, const ui8 * bufor, int & i);
|
void loadQuest( IQuestObject * guard, const ui8 * bufor, int & i);
|
||||||
void readDefInfo( const ui8 * bufor, int &i);
|
void readDefInfo( const ui8 * bufor, int &i);
|
||||||
void readTerrain( const ui8 * bufor, int &i);
|
void readTerrain( const ui8 * bufor, int &i);
|
||||||
void readPredefinedHeroes( const ui8 * bufor, int &i);
|
void readPredefinedHeroes( const ui8 * bufor, int &i);
|
||||||
@ -331,7 +332,7 @@ struct DLL_LINKAGE Mapa : public CMapHeader
|
|||||||
|
|
||||||
CArtifactInstance *createArt(int aid, int spellID = -1);
|
CArtifactInstance *createArt(int aid, int spellID = -1);
|
||||||
void addNewArtifactInstance(CArtifactInstance *art);
|
void addNewArtifactInstance(CArtifactInstance *art);
|
||||||
void addQuest (CQuest *quest);
|
void addQuest (IQuestObject *quest);
|
||||||
void eraseArtifactInstance(CArtifactInstance *art);
|
void eraseArtifactInstance(CArtifactInstance *art);
|
||||||
|
|
||||||
|
|
||||||
@ -447,11 +448,16 @@ struct DLL_LINKAGE Mapa : public CMapHeader
|
|||||||
for(ui32 i=0; i<objects.size(); i++)
|
for(ui32 i=0; i<objects.size(); i++)
|
||||||
{
|
{
|
||||||
if(!objects[i]) continue;
|
if(!objects[i]) continue;
|
||||||
if(objects[i]->ID == GameConstants::HEROI_TYPE)
|
|
||||||
heroes.push_back(static_cast<CGHeroInstance*>(+objects[i]));
|
|
||||||
else if(objects[i]->ID == GameConstants::TOWNI_TYPE)
|
|
||||||
towns.push_back(static_cast<CGTownInstance*>(+objects[i]));
|
|
||||||
|
|
||||||
|
switch (objects[i]->ID)
|
||||||
|
{
|
||||||
|
case GameConstants::HEROI_TYPE:
|
||||||
|
heroes.push_back (static_cast<CGHeroInstance*>(+objects[i]));
|
||||||
|
break;
|
||||||
|
case GameConstants::TOWNI_TYPE:
|
||||||
|
towns.push_back (static_cast<CGTownInstance*>(+objects[i]));
|
||||||
|
break;
|
||||||
|
}
|
||||||
addBlockVisTiles(objects[i]); //recreate blockvis map
|
addBlockVisTiles(objects[i]); //recreate blockvis map
|
||||||
}
|
}
|
||||||
for(ui32 i=0; i<heroes.size(); i++) //if hero is visiting/garrisoned in town set appropriate pointers
|
for(ui32 i=0; i<heroes.size(); i++) //if hero is visiting/garrisoned in town set appropriate pointers
|
||||||
|
Reference in New Issue
Block a user