mirror of
https://github.com/vcmi/vcmi.git
synced 2025-07-15 01:24:45 +02:00
Rearragned Seer Huts & Quests. More work on Quest Log descriptions.
This commit is contained in:
@ -21,6 +21,16 @@
|
|||||||
#include "UIFramework/CGuiHandler.h"
|
#include "UIFramework/CGuiHandler.h"
|
||||||
#include "UIFramework/CIntObjectClasses.h"
|
#include "UIFramework/CIntObjectClasses.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CQuestLog.cpp, part of VCMI engine
|
||||||
|
*
|
||||||
|
* Authors: listed in file AUTHORS in main folder
|
||||||
|
*
|
||||||
|
* License: GNU General Public License v2.0 or later
|
||||||
|
* Full text of license available in license.txt file, in main folder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
struct QuestInfo;
|
struct QuestInfo;
|
||||||
class CAdvmapInterface;
|
class CAdvmapInterface;
|
||||||
|
|
||||||
@ -30,6 +40,12 @@ void CQuestLabel::clickLeft(tribool down, bool previousState)
|
|||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CQuestLabel::showAll(SDL_Surface * to)
|
||||||
|
{
|
||||||
|
if (active)
|
||||||
|
CBoundedLabel::showAll (to);
|
||||||
|
}
|
||||||
|
|
||||||
void CQuestMinimap::clickLeft(tribool down, bool previousState)
|
void CQuestMinimap::clickLeft(tribool down, bool previousState)
|
||||||
{
|
{
|
||||||
if (down)
|
if (down)
|
||||||
@ -58,11 +74,11 @@ CQuestLog::CQuestLog (const std::vector<QuestInfo> & Quests) :
|
|||||||
void CQuestLog::init()
|
void CQuestLog::init()
|
||||||
{
|
{
|
||||||
minimap = new CQuestMinimap (Rect (47, 33, 144, 144));
|
minimap = new CQuestMinimap (Rect (47, 33, 144, 144));
|
||||||
description = new CTextBox ("", Rect(240, 33, 355, 355), 1, FONT_SMALL, TOPLEFT, Colors::Cornsilk);
|
description = new CTextBox ("", Rect(245, 33, 350, 355), 1, FONT_MEDIUM, TOPLEFT, Colors::Cornsilk);
|
||||||
ok = new CAdventureMapButton("",CGI->generaltexth->zelp[445].second, boost::bind(&CQuestLog::close,this), 547, 401, "IOKAY.DEF", SDLK_RETURN);
|
ok = new CAdventureMapButton("",CGI->generaltexth->zelp[445].second, boost::bind(&CQuestLog::close,this), 547, 401, "IOKAY.DEF", SDLK_RETURN);
|
||||||
|
|
||||||
if (quests.size() > QUEST_COUNT)
|
if (quests.size() > QUEST_COUNT)
|
||||||
slider = new CSlider(203, 199, 230, boost::bind (&CQuestLog::sliderMoved, this, _1), quests.size(), quests.size(), false, 0);
|
slider = new CSlider(203, 199, 230, boost::bind (&CQuestLog::sliderMoved, this, _1), QUEST_COUNT, quests.size(), false, 0);
|
||||||
|
|
||||||
auto map = LOCPLINT->cb->getVisibilityMap(); //TODO: another function to get all tiles?
|
auto map = LOCPLINT->cb->getVisibilityMap(); //TODO: another function to get all tiles?
|
||||||
|
|
||||||
@ -73,26 +89,31 @@ void CQuestLog::init()
|
|||||||
|
|
||||||
for (int i = 0; i < quests.size(); ++i)
|
for (int i = 0; i < quests.size(); ++i)
|
||||||
{
|
{
|
||||||
CQuestLabel * label = new CQuestLabel (28, 199 + i * 24, FONT_SMALL, TOPLEFT, Colors::Cornsilk, quests[i].quest.firstVisitText);
|
MetaString text;
|
||||||
|
quests[i].quest.getRolloverText (text, false);
|
||||||
|
if (quests[i].obj)
|
||||||
|
text.addReplacement (quests[i].obj->getHoverText()); //get name of the object
|
||||||
|
CQuestLabel * label = new CQuestLabel (28, 199 + i * 24, FONT_SMALL, TOPLEFT, Colors::Cornsilk, text.toString());
|
||||||
label->callback = boost::bind(&CQuestLog::selectQuest, this, i);
|
label->callback = boost::bind(&CQuestLog::selectQuest, this, i);
|
||||||
|
label->setBounds (172, 30);
|
||||||
labels.push_back(label);
|
labels.push_back(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
recreateQuestList (0); //truncate invisible and too wide labels
|
recreateQuestList (0);
|
||||||
showAll (screen2);
|
showAll (screen2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CQuestLog::showAll(SDL_Surface * to)
|
void CQuestLog::showAll(SDL_Surface * to)
|
||||||
{
|
{
|
||||||
CIntObject::showAll (to);
|
CIntObject::showAll (to);
|
||||||
recreateQuestList (0);
|
|
||||||
BOOST_FOREACH (auto label, labels)
|
BOOST_FOREACH (auto label, labels)
|
||||||
{
|
{
|
||||||
if (label->active)
|
label->show(to); //shows only if active
|
||||||
label->show(to);
|
|
||||||
}
|
}
|
||||||
if (labels.size())
|
if (labels.size() && labels[questIndex]->active)
|
||||||
|
{
|
||||||
CSDL_Ext::drawBorder(to, Rect::around(labels[questIndex]->pos), int3(Colors::MetallicGold.r, Colors::MetallicGold.g, Colors::MetallicGold.b));
|
CSDL_Ext::drawBorder(to, Rect::around(labels[questIndex]->pos), int3(Colors::MetallicGold.r, Colors::MetallicGold.g, Colors::MetallicGold.b));
|
||||||
|
}
|
||||||
description->show(to);
|
description->show(to);
|
||||||
minimap->update();
|
minimap->update();
|
||||||
}
|
}
|
||||||
@ -101,9 +122,9 @@ void CQuestLog::recreateQuestList (int newpos)
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < labels.size(); ++i)
|
for (int i = 0; i < labels.size(); ++i)
|
||||||
{
|
{
|
||||||
|
labels[i]->pos = Rect (pos.x + 28, pos.y + 207 + (i-newpos) * 25, 173, 23);
|
||||||
if (i >= newpos && i < newpos + QUEST_COUNT)
|
if (i >= newpos && i < newpos + QUEST_COUNT)
|
||||||
{
|
{
|
||||||
labels[i]->pos = Rect (pos.x + 28, pos.y + 207 + (i-newpos) * 24, 172, 30); //TODO: limit label width?
|
|
||||||
labels[i]->activate();
|
labels[i]->activate();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -120,10 +141,12 @@ void CQuestLog::selectQuest (int which)
|
|||||||
minimap->currentQuest = currentQuest;
|
minimap->currentQuest = currentQuest;
|
||||||
if (currentQuest->obj)
|
if (currentQuest->obj)
|
||||||
{
|
{
|
||||||
//minimap->setLevel (currentQuest->obj->pos.z);
|
|
||||||
adventureInt->centerOn (currentQuest->obj->pos);
|
adventureInt->centerOn (currentQuest->obj->pos);
|
||||||
}
|
}
|
||||||
description->text = currentQuest->quest.firstVisitText; //TODO: use special log entry text
|
MetaString text;
|
||||||
|
std::vector<Component> components; //TODO: display them
|
||||||
|
currentQuest->quest.getVisitText (text, components , currentQuest->quest.isCustomFirst, true);
|
||||||
|
description->setTxt (text.toString()); //TODO: use special log entry text
|
||||||
redraw();
|
redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include "../lib/CGameState.h"
|
#include "../lib/CGameState.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CCreatureWindow.h, part of VCMI engine
|
* CQuestLog.h, part of VCMI engine
|
||||||
*
|
*
|
||||||
* Authors: listed in file AUTHORS in main folder
|
* Authors: listed in file AUTHORS in main folder
|
||||||
*
|
*
|
||||||
@ -33,14 +33,15 @@ extern CAdvMapInt *adventureInt;
|
|||||||
|
|
||||||
const int QUEST_COUNT = 9;
|
const int QUEST_COUNT = 9;
|
||||||
|
|
||||||
class CQuestLabel : public LRClickableAreaWText, public CLabel
|
class CQuestLabel : public LRClickableAreaWText, public CBoundedLabel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
boost::function<void()> callback;
|
boost::function<void()> callback;
|
||||||
|
|
||||||
CQuestLabel (int x=0, int y=0, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = Colors::Cornsilk, const std::string &Text = "")
|
CQuestLabel (int x=0, int y=0, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = Colors::Cornsilk, const std::string &Text = "")
|
||||||
: CLabel (x, y, FONT_SMALL, TOPLEFT, Colors::Cornsilk, Text){};
|
: CBoundedLabel (x, y, FONT_SMALL, TOPLEFT, Colors::Cornsilk, Text){};
|
||||||
void clickLeft(tribool down, bool previousState);
|
void clickLeft(tribool down, bool previousState);
|
||||||
|
void showAll(SDL_Surface * to);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CQuestMinimap : public CMinimap
|
class CQuestMinimap : public CMinimap
|
||||||
|
@ -1234,6 +1234,71 @@ void CLabel::setTxt(const std::string &Txt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CBoundedLabel::setBounds(int limitW, int limitH)
|
||||||
|
{
|
||||||
|
pos.h = limitH;
|
||||||
|
pos.w = limitW;
|
||||||
|
recalculateLines(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CBoundedLabel::setTxt(const std::string &Txt)
|
||||||
|
{
|
||||||
|
recalculateLines(Txt);
|
||||||
|
CLabel::setTxt(Txt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CBoundedLabel::showAll(SDL_Surface * to)
|
||||||
|
{
|
||||||
|
CIntObject::showAll(to);
|
||||||
|
|
||||||
|
const Font &f = *graphics->fonts[font];
|
||||||
|
int lineHeight = f.height;
|
||||||
|
int lineCapacity = pos.h / lineHeight;
|
||||||
|
|
||||||
|
int dy = f.height; //line height
|
||||||
|
int base_y = pos.y;
|
||||||
|
if(alignment == CENTER)
|
||||||
|
base_y += std::max((pos.h - maxH)/2,0);
|
||||||
|
|
||||||
|
for (int i = 0; i < lineCapacity; i++)
|
||||||
|
{
|
||||||
|
const std::string &line = lines[i];
|
||||||
|
if(!line.size()) continue;
|
||||||
|
|
||||||
|
int x = pos.x;
|
||||||
|
if(alignment == CENTER)
|
||||||
|
{
|
||||||
|
x += (pos.w - f.getWidth(line.c_str())) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(line[0] == '{' && line[line.size()-1] == '}')
|
||||||
|
CSDL_Ext::printAt(line, x, base_y + i*dy, font, Colors::Jasmine, to);
|
||||||
|
else
|
||||||
|
CSDL_Ext::printAt(line, x, base_y + i*dy, font, color, to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CBoundedLabel::recalculateLines(const std::string &Txt)
|
||||||
|
{
|
||||||
|
lines.clear();
|
||||||
|
|
||||||
|
const Font &f = *graphics->fonts[font];
|
||||||
|
int lineHeight = f.height;
|
||||||
|
int lineCapacity = pos.h / lineHeight;
|
||||||
|
|
||||||
|
lines = CMessage::breakText(Txt, pos.w, font);
|
||||||
|
if(lines.size() > lineCapacity) //we need to add a slider
|
||||||
|
{
|
||||||
|
lines = CMessage::breakText(Txt, pos.w - 32 - 10, font);
|
||||||
|
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
maxH = lineHeight * lines.size();
|
||||||
|
maxW = 0;
|
||||||
|
BOOST_FOREACH(const std::string &line, lines)
|
||||||
|
vstd::amax(maxW, f.getWidth(line.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
CLabelGroup::CLabelGroup(EFonts Font, EAlignment Align, const SDL_Color &Color):
|
CLabelGroup::CLabelGroup(EFonts Font, EAlignment Align, const SDL_Color &Color):
|
||||||
font(Font), align(Align), color(Color)
|
font(Font), align(Align), color(Color)
|
||||||
{};
|
{};
|
||||||
@ -1245,7 +1310,7 @@ void CLabelGroup::add(int x, int y, const std::string &text)
|
|||||||
};
|
};
|
||||||
|
|
||||||
CTextBox::CTextBox(std::string Text, const Rect &rect, int SliderStyle, EFonts Font /*= FONT_SMALL*/, EAlignment Align /*= TOPLEFT*/, const SDL_Color &Color /*= Colors::Cornsilk*/)
|
CTextBox::CTextBox(std::string Text, const Rect &rect, int SliderStyle, EFonts Font /*= FONT_SMALL*/, EAlignment Align /*= TOPLEFT*/, const SDL_Color &Color /*= Colors::Cornsilk*/)
|
||||||
:CLabel(rect.x, rect.y, Font, Align, Color, Text), sliderStyle(SliderStyle), slider(NULL)
|
:CBoundedLabel(rect.x, rect.y, Font, Align, Color, Text), sliderStyle(SliderStyle), slider(NULL)
|
||||||
{
|
{
|
||||||
type |= REDRAW_PARENT;
|
type |= REDRAW_PARENT;
|
||||||
autoRedraw = false;
|
autoRedraw = false;
|
||||||
@ -1256,6 +1321,19 @@ CTextBox::CTextBox(std::string Text, const Rect &rect, int SliderStyle, EFonts F
|
|||||||
setTxt(Text);
|
setTxt(Text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CTextBox::recalculateLines(const std::string &Txt)
|
||||||
|
{
|
||||||
|
CBoundedLabel::recalculateLines (Txt);
|
||||||
|
|
||||||
|
const Font &f = *graphics->fonts[font];
|
||||||
|
int lineHeight = f.height;
|
||||||
|
int lineCapacity = pos.h / lineHeight;
|
||||||
|
|
||||||
|
vstd::clear_pointer(slider);
|
||||||
|
if (lines.size() > lineCapacity) //we need to add a slider
|
||||||
|
slider = new CSlider(pos.w - 32, 0, pos.h, boost::bind(&CTextBox::sliderMoved, this, _1), lineCapacity, lines.size(), 0, false, sliderStyle);
|
||||||
|
}
|
||||||
|
|
||||||
void CTextBox::showAll(SDL_Surface * to)
|
void CTextBox::showAll(SDL_Surface * to)
|
||||||
{
|
{
|
||||||
CIntObject::showAll(to);
|
CIntObject::showAll(to);
|
||||||
@ -1290,12 +1368,6 @@ void CTextBox::showAll(SDL_Surface * to)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTextBox::setTxt(const std::string &Txt)
|
|
||||||
{
|
|
||||||
recalculateLines(Txt);
|
|
||||||
CLabel::setTxt(Txt);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CTextBox::sliderMoved(int to)
|
void CTextBox::sliderMoved(int to)
|
||||||
{
|
{
|
||||||
if(!slider)
|
if(!slider)
|
||||||
@ -1304,36 +1376,6 @@ void CTextBox::sliderMoved(int to)
|
|||||||
redraw();
|
redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTextBox::setBounds(int limitW, int limitH)
|
|
||||||
{
|
|
||||||
pos.h = limitH;
|
|
||||||
pos.w = limitW;
|
|
||||||
recalculateLines(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CTextBox::recalculateLines(const std::string &Txt)
|
|
||||||
{
|
|
||||||
vstd::clear_pointer(slider);
|
|
||||||
lines.clear();
|
|
||||||
|
|
||||||
const Font &f = *graphics->fonts[font];
|
|
||||||
int lineHeight = f.height;
|
|
||||||
int lineCapacity = pos.h / lineHeight;
|
|
||||||
|
|
||||||
lines = CMessage::breakText(Txt, pos.w, font);
|
|
||||||
if(lines.size() > lineCapacity) //we need to add a slider
|
|
||||||
{
|
|
||||||
lines = CMessage::breakText(Txt, pos.w - 32 - 10, font);
|
|
||||||
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
|
||||||
slider = new CSlider(pos.w - 32, 0, pos.h, boost::bind(&CTextBox::sliderMoved, this, _1), lineCapacity, lines.size(), 0, false, sliderStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
maxH = lineHeight * lines.size();
|
|
||||||
maxW = 0;
|
|
||||||
BOOST_FOREACH(const std::string &line, lines)
|
|
||||||
vstd::amax(maxW, f.getWidth(line.c_str()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CGStatusBar::print(const std::string & Text)
|
void CGStatusBar::print(const std::string & Text)
|
||||||
{
|
{
|
||||||
setTxt(Text);
|
setTxt(Text);
|
||||||
|
@ -339,6 +339,23 @@ public:
|
|||||||
CLabel(int x=0, int y=0, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = Colors::Cornsilk, const std::string &Text = "");
|
CLabel(int x=0, int y=0, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = Colors::Cornsilk, const std::string &Text = "");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CBoundedLabel : public CLabel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
int maxW; //longest line of text in px
|
||||||
|
int maxH; //total height needed to print all lines
|
||||||
|
|
||||||
|
std::vector<std::string> lines;
|
||||||
|
|
||||||
|
CBoundedLabel(int x=0, int y=0, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = Colors::Cornsilk, const std::string &Text = "")
|
||||||
|
: CLabel (x, y, Font, Align, Color, Text){};
|
||||||
|
void setTxt(const std::string &Txt);
|
||||||
|
void setBounds(int limitW, int limitH);
|
||||||
|
void recalculateLines(const std::string &Txt);
|
||||||
|
void showAll(SDL_Surface * to);
|
||||||
|
};
|
||||||
|
|
||||||
//Small helper class to manage group of similar labels
|
//Small helper class to manage group of similar labels
|
||||||
class CLabelGroup : public CIntObject
|
class CLabelGroup : public CIntObject
|
||||||
{
|
{
|
||||||
@ -352,24 +369,18 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// a multi-line label that tries to fit text with given available width and height; if not possible, it creates a slider for scrolling text
|
/// a multi-line label that tries to fit text with given available width and height; if not possible, it creates a slider for scrolling text
|
||||||
class CTextBox
|
class CTextBox : public CBoundedLabel
|
||||||
: public CLabel
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int maxW; //longest line of text in px
|
|
||||||
int maxH; //total height needed to print all lines
|
|
||||||
|
|
||||||
int sliderStyle;
|
int sliderStyle;
|
||||||
|
|
||||||
std::vector<std::string> lines;
|
|
||||||
std::vector<CAnimImage* > effects;
|
std::vector<CAnimImage* > effects;
|
||||||
CSlider *slider;
|
CSlider *slider;
|
||||||
|
|
||||||
//CTextBox( std::string Text, const Point &Pos, int w, int h, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = Colors::Cornsilk);
|
//CTextBox( std::string Text, const Point &Pos, int w, int h, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = Colors::Cornsilk);
|
||||||
CTextBox(std::string Text, const Rect &rect, int SliderStyle, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = Colors::Cornsilk);
|
CTextBox(std::string Text, const Rect &rect, int SliderStyle, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = Colors::Cornsilk);
|
||||||
void showAll(SDL_Surface * to); //shows statusbar (with current text)
|
void showAll(SDL_Surface * to); //shows statusbar (with current text)
|
||||||
void setTxt(const std::string &Txt);
|
|
||||||
void setBounds(int limitW, int limitH);
|
|
||||||
void recalculateLines(const std::string &Txt);
|
void recalculateLines(const std::string &Txt);
|
||||||
|
|
||||||
void sliderMoved(int to);
|
void sliderMoved(int to);
|
||||||
|
@ -4121,55 +4121,119 @@ bool CQuest::checkQuest (const CGHeroInstance * h) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void CGSeerHut::initObj()
|
void CQuest::getVisitText (MetaString &iwText, std::vector<Component> &components, bool isCustom, bool firstVisit, const CGHeroInstance * h) const
|
||||||
{
|
{
|
||||||
seerName = VLC->generaltexth->seerNames[ran()%VLC->generaltexth->seerNames.size()];
|
std::string text;
|
||||||
textOption = ran()%3;
|
bool failRequirements = (h ? !checkQuest(h) : true);
|
||||||
progress = 0;
|
|
||||||
if (missionType)
|
|
||||||
{
|
|
||||||
if (!isCustomFirst)
|
|
||||||
firstVisitText = VLC->generaltexth->quests[missionType-1][0][textOption];
|
|
||||||
if (!isCustomNext)
|
|
||||||
nextVisitText = VLC->generaltexth->quests[missionType-1][1][textOption];
|
|
||||||
if (!isCustomComplete)
|
|
||||||
completedText = VLC->generaltexth->quests[missionType-1][2][textOption];
|
|
||||||
|
|
||||||
if(missionType == MISSION_KILL_CREATURE)
|
if (firstVisit)
|
||||||
{
|
{
|
||||||
stackToKill = getCreatureToKill(false)->getStack(0);
|
isCustom = isCustomFirst;
|
||||||
stackDirection = checkDirection();
|
iwText << firstVisitText;
|
||||||
}
|
}
|
||||||
else if(missionType == MISSION_KILL_HERO)
|
else if (failRequirements)
|
||||||
{
|
{
|
||||||
heroName = getHeroToKill(false)->name;
|
isCustom = isCustomNext;
|
||||||
heroPortrait = getHeroToKill(false)->portrait;
|
iwText << nextVisitText;
|
||||||
}
|
}
|
||||||
}
|
switch (missionType)
|
||||||
else
|
|
||||||
firstVisitText = VLC->generaltexth->seerEmpty[textOption];
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string & CGSeerHut::getHoverText() const
|
|
||||||
{
|
{
|
||||||
switch (ID)
|
case MISSION_LEVEL:
|
||||||
{
|
components.push_back(Component (Component::EXPERIENCE, 1, m13489val, 0));
|
||||||
case 83:
|
if (!isCustom)
|
||||||
hoverName = VLC->generaltexth->allTexts[347];
|
iwText.addReplacement(m13489val);
|
||||||
boost::algorithm::replace_first(hoverName,"%s", seerName);
|
|
||||||
break;
|
break;
|
||||||
case 215:
|
case MISSION_PRIMARY_STAT:
|
||||||
hoverName = VLC->generaltexth->names[ID];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
tlog5 << "unrecognized quest object\n";
|
|
||||||
}
|
|
||||||
if (progress & missionType) //rollover when the quest is active
|
|
||||||
{
|
{
|
||||||
MetaString ms;
|
MetaString loot;
|
||||||
ms << "\n\n" << VLC->generaltexth->quests[missionType-1][3][textOption];
|
for (int i = 0; i < 4; ++i)
|
||||||
std::string str;
|
{
|
||||||
|
if (m2stats[i])
|
||||||
|
{
|
||||||
|
components.push_back(Component (Component::PRIM_SKILL, i, m2stats[i], 0));
|
||||||
|
loot << "%d %s";
|
||||||
|
loot.addReplacement(m2stats[i]);
|
||||||
|
loot.addReplacement(VLC->generaltexth->primarySkillNames[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isCustom)
|
||||||
|
iwText.addReplacement(loot.buildList());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MISSION_KILL_HERO:
|
||||||
|
components.push_back(Component(Component::HERO, heroPortrait, 0, 0));
|
||||||
|
if (!isCustom)
|
||||||
|
addReplacements(iwText, text);
|
||||||
|
break;
|
||||||
|
case MISSION_HERO:
|
||||||
|
components.push_back(Component (Component::HERO, m13489val, 0, 0));
|
||||||
|
if (!isCustom)
|
||||||
|
iwText.addReplacement(VLC->heroh->heroes[m13489val]->name);
|
||||||
|
break;
|
||||||
|
case MISSION_KILL_CREATURE:
|
||||||
|
{
|
||||||
|
components.push_back(Component(stackToKill));
|
||||||
|
if (!isCustom)
|
||||||
|
addReplacements(iwText, text);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MISSION_ART:
|
||||||
|
{
|
||||||
|
MetaString loot;
|
||||||
|
for (std::vector<ui16>::const_iterator it = m5arts.begin(); it != m5arts.end(); ++it)
|
||||||
|
{
|
||||||
|
components.push_back(Component (Component::ARTIFACT, *it, 0, 0));
|
||||||
|
loot << "%s";
|
||||||
|
loot.addReplacement(MetaString::ART_NAMES, *it);
|
||||||
|
}
|
||||||
|
if (!isCustom)
|
||||||
|
iwText.addReplacement(loot.buildList());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MISSION_ARMY:
|
||||||
|
{
|
||||||
|
MetaString loot;
|
||||||
|
for (std::vector<CStackBasicDescriptor>::const_iterator it = m6creatures.begin(); it != m6creatures.end(); ++it)
|
||||||
|
{
|
||||||
|
components.push_back(Component(*it));
|
||||||
|
loot << "%s";
|
||||||
|
loot.addReplacement(*it);
|
||||||
|
}
|
||||||
|
if (!isCustom)
|
||||||
|
iwText.addReplacement(loot.buildList());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MISSION_RESOURCES:
|
||||||
|
{
|
||||||
|
MetaString loot;
|
||||||
|
for (int i = 0; i < 7; ++i)
|
||||||
|
{
|
||||||
|
if (m7resources[i])
|
||||||
|
{
|
||||||
|
components.push_back(Component (Component::RESOURCE, i, m7resources[i], 0));
|
||||||
|
loot << "%d %s";
|
||||||
|
loot.addReplacement(m7resources[i]);
|
||||||
|
loot.addReplacement(MetaString::RES_NAMES, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isCustom)
|
||||||
|
iwText.addReplacement(loot.buildList());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MISSION_PLAYER:
|
||||||
|
components.push_back(Component (Component::FLAG, m13489val, 0, 0));
|
||||||
|
if (!isCustom)
|
||||||
|
iwText.addReplacement(VLC->generaltexth->colors[m13489val]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void CQuest::getRolloverText (MetaString &ms, bool onHover) const
|
||||||
|
{
|
||||||
|
if (onHover)
|
||||||
|
ms << "\n\n";
|
||||||
|
|
||||||
|
ms << VLC->generaltexth->quests[missionType-1][onHover ? 3 : 4][textOption];
|
||||||
|
|
||||||
switch (missionType)
|
switch (missionType)
|
||||||
{
|
{
|
||||||
case MISSION_LEVEL:
|
case MISSION_LEVEL:
|
||||||
@ -4242,12 +4306,188 @@ const std::string & CGSeerHut::getHoverText() const
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ms.toString(str);
|
}
|
||||||
hoverName += str;
|
|
||||||
|
void CQuest::getCompletionText (MetaString &iwText, std::vector<Component> &components, bool isCustom, const CGHeroInstance * h) const
|
||||||
|
{
|
||||||
|
iwText << completedText;
|
||||||
|
switch (missionType)
|
||||||
|
{
|
||||||
|
case CQuest::MISSION_LEVEL:
|
||||||
|
if (!isCustomComplete)
|
||||||
|
iwText.addReplacement(m13489val);
|
||||||
|
break;
|
||||||
|
case CQuest::MISSION_PRIMARY_STAT:
|
||||||
|
if (vstd::contains (completedText,'%')) //there's one case when there's nothing to replace
|
||||||
|
{
|
||||||
|
MetaString loot;
|
||||||
|
for (int i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
|
if (m2stats[i])
|
||||||
|
{
|
||||||
|
loot << "%d %s";
|
||||||
|
loot.addReplacement(m2stats[i]);
|
||||||
|
loot.addReplacement(VLC->generaltexth->primarySkillNames[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isCustomComplete)
|
||||||
|
iwText.addReplacement(loot.buildList());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CQuest::MISSION_ART:
|
||||||
|
{
|
||||||
|
MetaString loot;
|
||||||
|
for (std::vector<ui16>::const_iterator it = m5arts.begin(); it != m5arts.end(); ++it)
|
||||||
|
{
|
||||||
|
loot << "%s";
|
||||||
|
loot.addReplacement(MetaString::ART_NAMES, *it);
|
||||||
|
}
|
||||||
|
if (!isCustomComplete)
|
||||||
|
iwText.addReplacement(loot.buildList());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CQuest::MISSION_ARMY:
|
||||||
|
{
|
||||||
|
MetaString loot;
|
||||||
|
for (std::vector<CStackBasicDescriptor>::const_iterator it = m6creatures.begin(); it != m6creatures.end(); ++it)
|
||||||
|
{
|
||||||
|
loot << "%s";
|
||||||
|
loot.addReplacement(*it);
|
||||||
|
}
|
||||||
|
if (!isCustomComplete)
|
||||||
|
iwText.addReplacement(loot.buildList());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CQuest::MISSION_RESOURCES:
|
||||||
|
{
|
||||||
|
MetaString loot;
|
||||||
|
for (int i = 0; i < 7; ++i)
|
||||||
|
{
|
||||||
|
if (m7resources[i])
|
||||||
|
{
|
||||||
|
loot << "%d %s";
|
||||||
|
loot.addReplacement(m7resources[i]);
|
||||||
|
loot.addReplacement(MetaString::RES_NAMES, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isCustomComplete)
|
||||||
|
iwText.addReplacement(loot.buildList());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MISSION_KILL_HERO:
|
||||||
|
case MISSION_KILL_CREATURE:
|
||||||
|
if (!isCustomComplete)
|
||||||
|
addReplacements(iwText, completedText);
|
||||||
|
break;
|
||||||
|
case MISSION_HERO:
|
||||||
|
if (!isCustomComplete)
|
||||||
|
iwText.addReplacement(VLC->heroh->heroes[m13489val]->name);
|
||||||
|
break;
|
||||||
|
case MISSION_PLAYER:
|
||||||
|
if (!isCustomComplete)
|
||||||
|
iwText.addReplacement(VLC->generaltexth->colors[m13489val]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGSeerHut::initObj()
|
||||||
|
{
|
||||||
|
seerName = VLC->generaltexth->seerNames[ran()%VLC->generaltexth->seerNames.size()];
|
||||||
|
textOption = ran()%3;
|
||||||
|
progress = 0;
|
||||||
|
if (missionType)
|
||||||
|
{
|
||||||
|
if (!isCustomFirst)
|
||||||
|
firstVisitText = VLC->generaltexth->quests[missionType-1][0][textOption];
|
||||||
|
if (!isCustomNext)
|
||||||
|
nextVisitText = VLC->generaltexth->quests[missionType-1][1][textOption];
|
||||||
|
if (!isCustomComplete)
|
||||||
|
completedText = VLC->generaltexth->quests[missionType-1][2][textOption];
|
||||||
|
|
||||||
|
if(missionType == MISSION_KILL_CREATURE)
|
||||||
|
{
|
||||||
|
stackToKill = getCreatureToKill(false)->getStack(0);
|
||||||
|
stackDirection = checkDirection();
|
||||||
|
}
|
||||||
|
else if(missionType == MISSION_KILL_HERO)
|
||||||
|
{
|
||||||
|
heroName = getHeroToKill(false)->name;
|
||||||
|
heroPortrait = getHeroToKill(false)->portrait;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
firstVisitText = VLC->generaltexth->seerEmpty[textOption];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string & CGSeerHut::getHoverText() const
|
||||||
|
{
|
||||||
|
switch (ID)
|
||||||
|
{
|
||||||
|
case 83:
|
||||||
|
hoverName = VLC->generaltexth->allTexts[347];
|
||||||
|
boost::algorithm::replace_first(hoverName,"%s", seerName);
|
||||||
|
break;
|
||||||
|
case 215:
|
||||||
|
hoverName = VLC->generaltexth->names[ID];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
tlog5 << "unrecognized quest object\n";
|
||||||
|
}
|
||||||
|
if (progress & missionType) //rollover when the quest is active
|
||||||
|
{
|
||||||
|
MetaString ms;
|
||||||
|
getRolloverText (ms, true);
|
||||||
|
hoverName += ms.toString();
|
||||||
}
|
}
|
||||||
return hoverName;
|
return hoverName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CQuest::addReplacements(MetaString &out, const std::string &base) const
|
||||||
|
{
|
||||||
|
switch(missionType)
|
||||||
|
{
|
||||||
|
case MISSION_KILL_CREATURE:
|
||||||
|
out.addReplacement(stackToKill);
|
||||||
|
if (std::count(base.begin(), base.end(), '%') == 2) //say where is placed monster
|
||||||
|
{
|
||||||
|
out.addReplacement(VLC->generaltexth->arraytxt[147+stackDirection]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MISSION_KILL_HERO:
|
||||||
|
out.addReplacement(heroName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGSeerHut::getCompletionText(MetaString &text, std::vector<Component> &components, bool isCustom, const CGHeroInstance * h) const
|
||||||
|
{
|
||||||
|
CQuest::getCompletionText (text, components, isCustom, h);
|
||||||
|
switch (rewardType)
|
||||||
|
{
|
||||||
|
case 1: components.push_back(Component (Component::EXPERIENCE, 0, rVal*(100+h->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0, 0));
|
||||||
|
break;
|
||||||
|
case 2: components.push_back(Component (Component::PRIM_SKILL, 5, rVal, 0));
|
||||||
|
break;
|
||||||
|
case 3: components.push_back(Component (Component::MORALE, 0, rVal, 0));
|
||||||
|
break;
|
||||||
|
case 4: components.push_back(Component (Component::LUCK, 0, rVal, 0));
|
||||||
|
break;
|
||||||
|
case 5: components.push_back(Component (Component::RESOURCE, rID, rVal, 0));
|
||||||
|
break;
|
||||||
|
case 6: components.push_back(Component (Component::PRIM_SKILL, rID, rVal, 0));
|
||||||
|
break;
|
||||||
|
case 7: components.push_back(Component (Component::SEC_SKILL, rID, rVal, 0));
|
||||||
|
break;
|
||||||
|
case 8: components.push_back(Component (Component::ARTIFACT, rID, 0, 0));
|
||||||
|
break;
|
||||||
|
case 9: components.push_back(Component (Component::SPELL, rID, 0, 0));
|
||||||
|
break;
|
||||||
|
case 10: components.push_back(Component (Component::CREATURE, rID, rVal, 0));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CGSeerHut::setPropertyDer (ui8 what, ui32 val)
|
void CGSeerHut::setPropertyDer (ui8 what, ui32 val)
|
||||||
{
|
{
|
||||||
switch (what)
|
switch (what)
|
||||||
@ -4278,11 +4518,10 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const
|
|||||||
bool firstVisit = !progress;
|
bool firstVisit = !progress;
|
||||||
bool failRequirements = !checkQuest(h);
|
bool failRequirements = !checkQuest(h);
|
||||||
bool isCustom=false;
|
bool isCustom=false;
|
||||||
std::string text;
|
|
||||||
if (firstVisit)
|
if (firstVisit)
|
||||||
{
|
{
|
||||||
isCustom = isCustomFirst;
|
isCustom = isCustomFirst;
|
||||||
text = firstVisitText;
|
|
||||||
cb->setObjProperty (id, 10, 1);
|
cb->setObjProperty (id, 10, 1);
|
||||||
|
|
||||||
AddQuest aq;
|
AddQuest aq;
|
||||||
@ -4293,102 +4532,12 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const
|
|||||||
else if (failRequirements)
|
else if (failRequirements)
|
||||||
{
|
{
|
||||||
isCustom = isCustomNext;
|
isCustom = isCustomNext;
|
||||||
text = nextVisitText;
|
|
||||||
}
|
}
|
||||||
iw.text << text;
|
|
||||||
|
|
||||||
if (firstVisit || failRequirements)
|
if (firstVisit || failRequirements)
|
||||||
{
|
{
|
||||||
switch (missionType)
|
getVisitText (iw.text, iw.components, isCustom, firstVisit, h);
|
||||||
{
|
|
||||||
case MISSION_LEVEL:
|
|
||||||
iw.components.push_back(Component (Component::EXPERIENCE, 1, m13489val, 0));
|
|
||||||
if (!isCustom)
|
|
||||||
iw.text.addReplacement(m13489val);
|
|
||||||
break;
|
|
||||||
case MISSION_PRIMARY_STAT:
|
|
||||||
{
|
|
||||||
MetaString loot;
|
|
||||||
for (int i = 0; i < 4; ++i)
|
|
||||||
{
|
|
||||||
if (m2stats[i])
|
|
||||||
{
|
|
||||||
iw.components.push_back(Component (Component::PRIM_SKILL, i, m2stats[i], 0));
|
|
||||||
loot << "%d %s";
|
|
||||||
loot.addReplacement(m2stats[i]);
|
|
||||||
loot.addReplacement(VLC->generaltexth->primarySkillNames[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!isCustom)
|
|
||||||
iw.text.addReplacement(loot.buildList());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MISSION_KILL_HERO:
|
|
||||||
iw.components.push_back(Component(Component::HERO, heroPortrait, 0, 0));
|
|
||||||
if (!isCustom)
|
|
||||||
addReplacements(iw.text, text);
|
|
||||||
break;
|
|
||||||
case MISSION_HERO:
|
|
||||||
iw.components.push_back(Component (Component::HERO, m13489val, 0, 0));
|
|
||||||
if (!isCustom)
|
|
||||||
iw.text.addReplacement(VLC->heroh->heroes[m13489val]->name);
|
|
||||||
break;
|
|
||||||
case MISSION_KILL_CREATURE:
|
|
||||||
{
|
|
||||||
iw.components.push_back(Component(stackToKill));
|
|
||||||
if (!isCustom)
|
|
||||||
addReplacements(iw.text, text);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MISSION_ART:
|
|
||||||
{
|
|
||||||
MetaString loot;
|
|
||||||
for (std::vector<ui16>::const_iterator it = m5arts.begin(); it != m5arts.end(); ++it)
|
|
||||||
{
|
|
||||||
iw.components.push_back(Component (Component::ARTIFACT, *it, 0, 0));
|
|
||||||
loot << "%s";
|
|
||||||
loot.addReplacement(MetaString::ART_NAMES, *it);
|
|
||||||
}
|
|
||||||
if (!isCustom)
|
|
||||||
iw.text.addReplacement(loot.buildList());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MISSION_ARMY:
|
|
||||||
{
|
|
||||||
MetaString loot;
|
|
||||||
for (std::vector<CStackBasicDescriptor>::const_iterator it = m6creatures.begin(); it != m6creatures.end(); ++it)
|
|
||||||
{
|
|
||||||
iw.components.push_back(Component(*it));
|
|
||||||
loot << "%s";
|
|
||||||
loot.addReplacement(*it);
|
|
||||||
}
|
|
||||||
if (!isCustom)
|
|
||||||
iw.text.addReplacement(loot.buildList());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MISSION_RESOURCES:
|
|
||||||
{
|
|
||||||
MetaString loot;
|
|
||||||
for (int i = 0; i < 7; ++i)
|
|
||||||
{
|
|
||||||
if (m7resources[i])
|
|
||||||
{
|
|
||||||
iw.components.push_back(Component (Component::RESOURCE, i, m7resources[i], 0));
|
|
||||||
loot << "%d %s";
|
|
||||||
loot.addReplacement(m7resources[i]);
|
|
||||||
loot.addReplacement(MetaString::RES_NAMES, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!isCustom)
|
|
||||||
iw.text.addReplacement(loot.buildList());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MISSION_PLAYER:
|
|
||||||
iw.components.push_back(Component (Component::FLAG, m13489val, 0, 0));
|
|
||||||
if (!isCustom)
|
|
||||||
iw.text.addReplacement(VLC->generaltexth->colors[m13489val]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
cb->showInfoDialog(&iw);
|
cb->showInfoDialog(&iw);
|
||||||
}
|
}
|
||||||
if (!failRequirements) // propose completion, also on first visit
|
if (!failRequirements) // propose completion, also on first visit
|
||||||
@ -4396,108 +4545,8 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const
|
|||||||
BlockingDialog bd (true, false);
|
BlockingDialog bd (true, false);
|
||||||
bd.player = h->getOwner();
|
bd.player = h->getOwner();
|
||||||
bd.soundID = soundBase::QUEST;
|
bd.soundID = soundBase::QUEST;
|
||||||
bd.text << completedText;
|
|
||||||
switch (missionType)
|
|
||||||
{
|
|
||||||
case CQuest::MISSION_LEVEL:
|
|
||||||
if (!isCustomComplete)
|
|
||||||
bd.text.addReplacement(m13489val);
|
|
||||||
break;
|
|
||||||
case CQuest::MISSION_PRIMARY_STAT:
|
|
||||||
if (vstd::contains (completedText,'%')) //there's one case when there's nothing to replace
|
|
||||||
{
|
|
||||||
MetaString loot;
|
|
||||||
for (int i = 0; i < 4; ++i)
|
|
||||||
{
|
|
||||||
if (m2stats[i])
|
|
||||||
{
|
|
||||||
loot << "%d %s";
|
|
||||||
loot.addReplacement(m2stats[i]);
|
|
||||||
loot.addReplacement(VLC->generaltexth->primarySkillNames[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!isCustomComplete)
|
|
||||||
bd.text.addReplacement(loot.buildList());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CQuest::MISSION_ART:
|
|
||||||
{
|
|
||||||
MetaString loot;
|
|
||||||
for (std::vector<ui16>::const_iterator it = m5arts.begin(); it != m5arts.end(); ++it)
|
|
||||||
{
|
|
||||||
loot << "%s";
|
|
||||||
loot.addReplacement(MetaString::ART_NAMES, *it);
|
|
||||||
}
|
|
||||||
if (!isCustomComplete)
|
|
||||||
bd.text.addReplacement(loot.buildList());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CQuest::MISSION_ARMY:
|
|
||||||
{
|
|
||||||
MetaString loot;
|
|
||||||
for (std::vector<CStackBasicDescriptor>::const_iterator it = m6creatures.begin(); it != m6creatures.end(); ++it)
|
|
||||||
{
|
|
||||||
loot << "%s";
|
|
||||||
loot.addReplacement(*it);
|
|
||||||
}
|
|
||||||
if (!isCustomComplete)
|
|
||||||
bd.text.addReplacement(loot.buildList());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CQuest::MISSION_RESOURCES:
|
|
||||||
{
|
|
||||||
MetaString loot;
|
|
||||||
for (int i = 0; i < 7; ++i)
|
|
||||||
{
|
|
||||||
if (m7resources[i])
|
|
||||||
{
|
|
||||||
loot << "%d %s";
|
|
||||||
loot.addReplacement(m7resources[i]);
|
|
||||||
loot.addReplacement(MetaString::RES_NAMES, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!isCustomComplete)
|
|
||||||
bd.text.addReplacement(loot.buildList());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MISSION_KILL_HERO:
|
|
||||||
case MISSION_KILL_CREATURE:
|
|
||||||
if (!isCustomComplete)
|
|
||||||
addReplacements(bd.text, completedText);
|
|
||||||
break;
|
|
||||||
case MISSION_HERO:
|
|
||||||
if (!isCustomComplete)
|
|
||||||
bd.text.addReplacement(VLC->heroh->heroes[m13489val]->name);
|
|
||||||
break;
|
|
||||||
case MISSION_PLAYER:
|
|
||||||
if (!isCustomComplete)
|
|
||||||
bd.text.addReplacement(VLC->generaltexth->colors[m13489val]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (rewardType)
|
getCompletionText (bd.text, bd.components, isCustom, h);
|
||||||
{
|
|
||||||
case 1: bd.components.push_back(Component (Component::EXPERIENCE, 0, rVal*(100+h->getSecSkillLevel(CGHeroInstance::LEARNING)*5)/100.0, 0));
|
|
||||||
break;
|
|
||||||
case 2: bd.components.push_back(Component (Component::PRIM_SKILL, 5, rVal, 0));
|
|
||||||
break;
|
|
||||||
case 3: bd.components.push_back(Component (Component::MORALE, 0, rVal, 0));
|
|
||||||
break;
|
|
||||||
case 4: bd.components.push_back(Component (Component::LUCK, 0, rVal, 0));
|
|
||||||
break;
|
|
||||||
case 5: bd.components.push_back(Component (Component::RESOURCE, rID, rVal, 0));
|
|
||||||
break;
|
|
||||||
case 6: bd.components.push_back(Component (Component::PRIM_SKILL, rID, rVal, 0));
|
|
||||||
break;
|
|
||||||
case 7: bd.components.push_back(Component (Component::SEC_SKILL, rID, rVal, 0));
|
|
||||||
break;
|
|
||||||
case 8: bd.components.push_back(Component (Component::ARTIFACT, rID, 0, 0));
|
|
||||||
break;
|
|
||||||
case 9: bd.components.push_back(Component (Component::SPELL, rID, 0, 0));
|
|
||||||
break;
|
|
||||||
case 10: bd.components.push_back(Component (Component::CREATURE, rID, rVal, 0));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
cb->showBlockingDialog (&bd, boost::bind (&CGSeerHut::finishQuest, this, h, _1));
|
cb->showBlockingDialog (&bd, boost::bind (&CGSeerHut::finishQuest, this, h, _1));
|
||||||
return;
|
return;
|
||||||
@ -4644,23 +4693,6 @@ const CGCreature * CGSeerHut::getCreatureToKill(bool allowNull) const
|
|||||||
return static_cast<const CGCreature*>(o);
|
return static_cast<const CGCreature*>(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGSeerHut::addReplacements(MetaString &out, const std::string &base) const
|
|
||||||
{
|
|
||||||
switch(missionType)
|
|
||||||
{
|
|
||||||
case MISSION_KILL_CREATURE:
|
|
||||||
out.addReplacement(stackToKill);
|
|
||||||
if (std::count(base.begin(), base.end(), '%') == 2) //say where is placed monster
|
|
||||||
{
|
|
||||||
out.addReplacement(VLC->generaltexth->arraytxt[147+stackDirection]);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MISSION_KILL_HERO:
|
|
||||||
out.addReplacement(heroName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CGQuestGuard::initObj()
|
void CGQuestGuard::initObj()
|
||||||
{
|
{
|
||||||
blockVisit = true;
|
blockVisit = true;
|
||||||
|
@ -58,7 +58,7 @@ class DLL_LINKAGE CQuest
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum Emission {MISSION_NONE = 0, MISSION_LEVEL = 1, MISSION_PRIMARY_STAT = 2, MISSION_KILL_HERO = 3, MISSION_KILL_CREATURE = 4,
|
enum Emission {MISSION_NONE = 0, MISSION_LEVEL = 1, MISSION_PRIMARY_STAT = 2, MISSION_KILL_HERO = 3, MISSION_KILL_CREATURE = 4,
|
||||||
MISSION_ART = 5, MISSION_ARMY = 6, MISSION_RESOURCES = 7, MISSION_HERO = 8, MISSION_PLAYER = 9};
|
MISSION_ART = 5, MISSION_ARMY = 6, MISSION_RESOURCES = 7, MISSION_HERO = 8, MISSION_PLAYER = 9};//MISSION_KEYMASTER = 10}; //TODO?
|
||||||
|
|
||||||
ui8 missionType, progress;
|
ui8 missionType, 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
|
||||||
@ -69,15 +69,27 @@ public:
|
|||||||
std::vector<CStackBasicDescriptor> m6creatures; //pair[cre id, cre count], CreatureSet info irrelevant
|
std::vector<CStackBasicDescriptor> m6creatures; //pair[cre id, cre count], CreatureSet info irrelevant
|
||||||
std::vector<ui32> m7resources;
|
std::vector<ui32> m7resources;
|
||||||
|
|
||||||
|
//following field are used only for kill creature/hero missions, the original objects became inaccessible after their removal, so we need to store info needed for messages / hover text
|
||||||
|
ui8 textOption;
|
||||||
|
CStackBasicDescriptor stackToKill;
|
||||||
|
ui8 stackDirection;
|
||||||
|
std::string heroName; //backup of hero name
|
||||||
|
si32 heroPortrait;
|
||||||
|
|
||||||
std::string firstVisitText, nextVisitText, completedText;
|
std::string firstVisitText, nextVisitText, completedText;
|
||||||
bool isCustomFirst, isCustomNext, isCustomComplete;
|
bool isCustomFirst, isCustomNext, isCustomComplete;
|
||||||
|
|
||||||
bool checkQuest (const CGHeroInstance * h) const; //determines whether the quest is complete or not
|
bool checkQuest (const CGHeroInstance * h) const; //determines whether the quest is complete or not
|
||||||
|
virtual void getVisitText (MetaString &text, std::vector<Component> &components, bool isCustom, bool FirstVisit, const CGHeroInstance * h = NULL) const;
|
||||||
|
virtual void getCompletionText (MetaString &text, std::vector<Component> &components, bool isCustom, const CGHeroInstance * h = NULL) const;
|
||||||
|
virtual void getRolloverText (MetaString &text, bool onHover) const; //hover or quest log entry
|
||||||
virtual void completeQuest (const CGHeroInstance * h) const {};
|
virtual void completeQuest (const CGHeroInstance * h) const {};
|
||||||
|
virtual void addReplacements(MetaString &out, const std::string &base) const;
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & missionType & progress & lastDay & m13489val & m2stats & m5arts & m6creatures & m7resources
|
h & missionType & progress & lastDay & m13489val & m2stats & m5arts & m6creatures & m7resources
|
||||||
|
& textOption & stackToKill & stackDirection & heroName & heroPortrait
|
||||||
& firstVisitText & nextVisitText & completedText & isCustomFirst & isCustomNext & isCustomComplete;
|
& firstVisitText & nextVisitText & completedText & isCustomFirst & isCustomNext & isCustomComplete;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -754,36 +766,25 @@ 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
|
||||||
si32 rID; //reward ID
|
si32 rID; //reward ID
|
||||||
si32 rVal; //reward value
|
si32 rVal; //reward value
|
||||||
ui8 textOption; //store randomized mission write-ups rather than entire string (?)
|
|
||||||
std::string seerName;
|
std::string seerName;
|
||||||
|
|
||||||
//following field are used only for kill creature/hero missions, the original objects became inaccessible after their removal, so we need to store info needed for messages / hover text
|
|
||||||
//TODO? organize
|
|
||||||
CStackBasicDescriptor stackToKill;
|
|
||||||
ui8 stackDirection;
|
|
||||||
std::string heroName; //backup of hero name
|
|
||||||
si32 heroPortrait;
|
|
||||||
|
|
||||||
|
|
||||||
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
|
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;
|
||||||
|
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;
|
||||||
|
|
||||||
const CGHeroInstance *getHeroToKill(bool allowNull = false) const;
|
const CGHeroInstance *getHeroToKill(bool allowNull = false) const;
|
||||||
const CGCreature *getCreatureToKill(bool allowNull = false) const;
|
const CGCreature *getCreatureToKill(bool allowNull = false) const;
|
||||||
|
|
||||||
void addReplacements(MetaString &out, const std::string &base) const;
|
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & static_cast<CGObjectInstance&>(*this) & static_cast<CQuest&>(*this);
|
h & static_cast<CGObjectInstance&>(*this) & static_cast<CQuest&>(*this);
|
||||||
h & rewardType & rID & rVal & textOption & seerName;
|
h & rewardType & rID & rVal & textOption & seerName;
|
||||||
h & stackToKill & stackDirection & heroName & heroPortrait;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user