1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

- Quest log minimap now has clickable icons

- Border guard & border gate inherit Quest interface
- Lots of tweaks
This commit is contained in:
DjWarmonger 2012-07-08 16:36:20 +00:00
parent 32d1a08470
commit b28da1a5d3
12 changed files with 189 additions and 29 deletions

View File

@ -376,21 +376,24 @@ const SDL_Color & CMinimapInstance::getTileColor(const int3 & pos)
else else
return parent->colors.find(tile->tertype)->second.first; return parent->colors.find(tile->tertype)->second.first;
} }
void CMinimapInstance::tileToPixels (const int3 &tile, int &x, int &y, int toX, int toY)
void CMinimapInstance::blitTileWithColor(const SDL_Color &color, const int3 &tile, SDL_Surface *to, int toX, int toY)
{ {
//method is mostly copy-pasted from drawScaled()
int3 mapSizes = LOCPLINT->cb->getMapSize(); int3 mapSizes = LOCPLINT->cb->getMapSize();
double stepX = double(pos.w) / mapSizes.x; double stepX = double(pos.w) / mapSizes.x;
double stepY = double(pos.h) / mapSizes.y; double stepY = double(pos.h) / mapSizes.y;
x = toX + stepX * tile.x;
y = toY + stepY * tile.y;
}
void CMinimapInstance::blitTileWithColor(const SDL_Color &color, const int3 &tile, SDL_Surface *to, int toX, int toY)
{
//coordinates of rectangle on minimap representing this tile //coordinates of rectangle on minimap representing this tile
// begin - first to blit, end - first NOT to blit // begin - first to blit, end - first NOT to blit
int xBegin = toX + stepX * tile.x; int xBegin, yBegin, xEnd, yEnd;
int yBegin = toY + stepY * tile.y; tileToPixels (tile, xBegin, yBegin, toX, toY);
int xEnd = toX + stepX * (tile.x + 1); tileToPixels (int3 (tile.x + 1, tile.y + 1, tile.z), xEnd, yEnd, toX, toY);
int yEnd = toY + stepY * (tile.y + 1);
for (int y=yBegin; y<yEnd; y++) for (int y=yBegin; y<yEnd; y++)
{ {
@ -516,7 +519,7 @@ CMinimap::CMinimap(const Rect &position):
pos.h = position.h; pos.h = position.h;
} }
void CMinimap::moveAdvMapSelection() int3 CMinimap::translateMousePosition()
{ {
// 0 = top-left corner, 1 = bottom-right corner // 0 = top-left corner, 1 = bottom-right corner
double dx = double(GH.current->motion.x - pos.x) / pos.w; double dx = double(GH.current->motion.x - pos.x) / pos.w;
@ -524,8 +527,13 @@ void CMinimap::moveAdvMapSelection()
int3 mapSizes = LOCPLINT->cb->getMapSize(); int3 mapSizes = LOCPLINT->cb->getMapSize();
int3 newLocation (mapSizes.x * dx, mapSizes.y * dy, level); int3 tile (mapSizes.x * dx, mapSizes.y * dy, level);
return tile;
}
void CMinimap::moveAdvMapSelection()
{
int3 newLocation = translateMousePosition();
adventureInt->centerOn(newLocation); adventureInt->centerOn(newLocation);
redraw(); redraw();

View File

@ -195,6 +195,7 @@ public:
~CMinimapInstance(); ~CMinimapInstance();
void showAll(SDL_Surface *to); void showAll(SDL_Surface *to);
void tileToPixels (const int3 &tile, int &x, int &y,int toX = 0, int toY = 0);
void refreshTile(const int3 &pos); void refreshTile(const int3 &pos);
}; };
@ -202,6 +203,8 @@ public:
/// Minimap which is displayed at the right upper corner of adventure map /// Minimap which is displayed at the right upper corner of adventure map
class CMinimap : public CIntObject class CMinimap : public CIntObject
{ {
protected:
CPicture *aiShield; //the graphic displayed during AI turn CPicture *aiShield; //the graphic displayed during AI turn
CMinimapInstance * minimap; CMinimapInstance * minimap;
int level; int level;
@ -214,8 +217,6 @@ class CMinimap : public CIntObject
void hover (bool on); void hover (bool on);
void mouseMoved (const SDL_MouseMotionEvent & sEvent); void mouseMoved (const SDL_MouseMotionEvent & sEvent);
protected:
void moveAdvMapSelection(); void moveAdvMapSelection();
public: public:
@ -225,6 +226,7 @@ public:
CMinimap(const Rect & position); CMinimap(const Rect & position);
//should be called to invalidate whole map - different player or level //should be called to invalidate whole map - different player or level
int3 translateMousePosition();
void update(); void update();
void setLevel(int level); void setLevel(int level);
void setAIRadar(bool on); void setAIRadar(bool on);

View File

@ -46,15 +46,78 @@ void CQuestLabel::showAll(SDL_Surface * to)
CBoundedLabel::showAll (to); CBoundedLabel::showAll (to);
} }
void CQuestMinimap::clickLeft(tribool down, bool previousState) CQuestIcon::CQuestIcon (const std::string &bmpname, int x, int y) :
CPicture (bmpname, x, y)
{
addUsedEvents(LCLICK);
}
void CQuestIcon::clickLeft(tribool down, bool previousState)
{ {
if (down) if (down)
callback();
}
void CQuestIcon::showAll(SDL_Surface * to)
{
if(bg)
{ {
moveAdvMapSelection(); if(srcRect)
update(); {
SDL_Rect srcRectCpy = *srcRect;
SDL_Rect dstRect = srcRectCpy;
dstRect.x = pos.x;
dstRect.y = pos.y;
CSDL_Ext::blitSurface(bg, &srcRectCpy, to, &dstRect);
}
else //TODO: allow blitting with offset correction (center of picture on the center of pos)
{
SDL_Rect dstRect = pos;
dstRect.x -= pos.w + 2;
dstRect.y -= pos.h + 2;
blitAt(bg, dstRect, to);
}
} }
} }
CQuestMinimap::CQuestMinimap (const Rect & position) :
CMinimap (position),
currentQuest (NULL)
{
}
void CQuestMinimap::addQuestMarks (const QuestInfo * q)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
icons.clear();
int3 tile;
if (q->obj)
{
tile = q->obj->pos;
}
else
{
tile = q->tile;
}
CQuestIcon * pic = new CQuestIcon ("", 0, 0);
CDefHandler * def = CDefHandler::giveDef("VwSymbol.def");
CSDL_Ext::alphaTransform(def->ourImages[3].bitmap);
pic->bg = def->ourImages[3].bitmap;
pic->pos.w = 8;
pic->pos.h = 8;
int x, y;
minimap->tileToPixels (tile, x, y);
pic->moveTo (Point (minimap->pos.x, minimap->pos.y), true);
pic->pos.x += x - pic->pos.w / 2 - 1;
pic->pos.y += y - pic->pos.h / 2 - 1;
pic->callback = boost::bind (&CQuestMinimap::iconClicked, this);
icons.push_back(pic);
}
void CQuestMinimap::update() void CQuestMinimap::update()
{ {
CMinimap::update(); CMinimap::update();
@ -62,6 +125,20 @@ void CQuestMinimap::update()
addQuestMarks (currentQuest); addQuestMarks (currentQuest);
} }
void CQuestMinimap::iconClicked()
{
if (currentQuest->obj)
adventureInt->centerOn (currentQuest->obj->pos);
moveAdvMapSelection();
}
void CQuestMinimap::showAll(SDL_Surface * to)
{
CMinimap::showAll(to);
BOOST_FOREACH (auto pic, icons)
pic->showAll(to);
}
CQuestLog::CQuestLog (const std::vector<QuestInfo> & Quests) : CQuestLog::CQuestLog (const std::vector<QuestInfo> & Quests) :
CWindowObject(PLAYER_COLORED, "QuestLog.pcx"), CWindowObject(PLAYER_COLORED, "QuestLog.pcx"),
quests (Quests), slider (NULL), quests (Quests), slider (NULL),
@ -116,6 +193,7 @@ void CQuestLog::showAll(SDL_Surface * to)
} }
description->show(to); description->show(to);
minimap->update(); minimap->update();
minimap->show(to);
} }
void CQuestLog::recreateQuestList (int newpos) void CQuestLog::recreateQuestList (int newpos)
@ -139,10 +217,7 @@ void CQuestLog::selectQuest (int which)
questIndex = which; questIndex = which;
currentQuest = &quests[which]; currentQuest = &quests[which];
minimap->currentQuest = currentQuest; minimap->currentQuest = currentQuest;
if (currentQuest->obj)
{
adventureInt->centerOn (currentQuest->obj->pos);
}
MetaString text; MetaString text;
std::vector<Component> components; //TODO: display them std::vector<Component> components; //TODO: display them
currentQuest->quest->getVisitText (text, components , currentQuest->quest->isCustomFirst, true); currentQuest->quest->getVisitText (text, components , currentQuest->quest->isCustomFirst, true);

View File

@ -44,22 +44,36 @@ public:
void showAll(SDL_Surface * to); void showAll(SDL_Surface * to);
}; };
class CQuestIcon : public CPicture
{
public:
boost::function<void()> callback; //TODO: merge with other similiar classes?
CQuestIcon (const std::string &bmpname, int x=0, int y=0);
void clickLeft(tribool down, bool previousState);
void showAll(SDL_Surface * to);
};
class CQuestMinimap : public CMinimap class CQuestMinimap : public CMinimap
{ {
void clickLeft(tribool down, bool previousState); std::vector <CQuestIcon *> icons;
void clickLeft(tribool down, bool previousState){}; //minimap ignores clicking on its surface
void iconClicked();
void mouseMoved (const SDL_MouseMotionEvent & sEvent){}; void mouseMoved (const SDL_MouseMotionEvent & sEvent){};
public: public:
const QuestInfo * currentQuest; const QuestInfo * currentQuest;
CQuestMinimap (const Rect & position) : CMinimap (position){}; CQuestMinimap (const Rect & position);
//should be called to invalidate whole map - different player or level //should be called to invalidate whole map - different player or level
void update(); void update();
void setLevel(int level); void setLevel(int level);
void addQuestMarks (const QuestInfo * q){}; void addQuestMarks (const QuestInfo * q);
//void showAll(SDL_Surface * to){}; void showAll(SDL_Surface * to);
}; };
class CQuestLog : public CWindowObject class CQuestLog : public CWindowObject

View File

@ -453,6 +453,11 @@ struct DLL_LINKAGE QuestInfo //universal interface for human and AI
QuestInfo (const CQuest * Quest, const CGObjectInstance * Obj, int3 Tile) : QuestInfo (const CQuest * Quest, const CGObjectInstance * Obj, int3 Tile) :
quest (Quest), obj (Obj), tile (Tile){}; quest (Quest), obj (Obj), tile (Tile){};
bool operator== (const QuestInfo qi) const
{
return (quest == qi.quest && obj == qi.obj);
}
//std::vector<std::string> > texts //allow additional info for quest log? //std::vector<std::string> > texts //allow additional info for quest log?
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)

View File

@ -502,6 +502,15 @@ void CGeneralTextHandler::load()
for (i = 0; i < 48; ++i) for (i = 0; i < 48; ++i)
loadToIt(seerNames[i], buf, it, 3); loadToIt(seerNames[i], buf, it, 3);
buf = bitmaph->getTextFile("TENTCOLR.TXT");
itr=0;
while(itr<buf.length()-1)
{
std::string tmp;
loadToIt(tmp, buf, itr, 3);
tentColors.push_back(tmp);
}
//campaigns //campaigns
buf = bitmaph->getTextFile ("CAMPTEXT.TXT"); buf = bitmaph->getTextFile ("CAMPTEXT.TXT");
it = 0; it = 0;

View File

@ -66,6 +66,7 @@ public:
std::vector <std::vector <std::vector <std::string> > > quests; //[quest][type][index] std::vector <std::vector <std::vector <std::string> > > quests; //[quest][type][index]
//type: quest, progress, complete, rollover, log OR time limit //index: 0-2 seer hut, 3-5 border guard //type: quest, progress, complete, rollover, log OR time limit //index: 0-2 seer hut, 3-5 border guard
std::vector<std::string> seerNames; std::vector<std::string> seerNames;
std::vector<std::string> tentColors;
std::vector<std::string> threat; //power rating for neutral stacks std::vector<std::string> threat; //power rating for neutral stacks
//sec skills //sec skills

View File

@ -4420,6 +4420,13 @@ void CGSeerHut::initObj()
} }
void CGSeerHut::getRolloverText (MetaString &text, bool onHover) const
{
CQuest::getRolloverText (text, onHover);//TODO: simplify?
if (!onHover)
text.addReplacement(seerName);
}
const std::string & CGSeerHut::getHoverText() const const std::string & CGSeerHut::getHoverText() const
{ {
switch (ID) switch (ID)
@ -6244,9 +6251,16 @@ bool CGKeys::wasMyColorVisited (int player) const
return false; return false;
} }
const std::string CGKeys::getName() const
{
std::string name;
name = VLC->generaltexth->tentColors[subID] + " " + VLC->generaltexth->names[ID];
return name;
}
const std::string & CGKeymasterTent::getHoverText() const const std::string & CGKeymasterTent::getHoverText() const
{ {
hoverName = VLC->generaltexth->names[ID]; hoverName = getName();
if (wasMyColorVisited (cb->getCurrentPlayer()) )//TODO: use local player, not current if (wasMyColorVisited (cb->getCurrentPlayer()) )//TODO: use local player, not current
hoverName += "\n" + VLC->generaltexth->allTexts[352]; hoverName += "\n" + VLC->generaltexth->allTexts[352];
else else
@ -6276,12 +6290,13 @@ void CGKeymasterTent::onHeroVisit( const CGHeroInstance * h ) const
void CGBorderGuard::initObj() void CGBorderGuard::initObj()
{ {
ui32 m13489val = subID; //store color as quest info
blockVisit = true; blockVisit = true;
} }
const std::string & CGBorderGuard::getHoverText() const const std::string & CGBorderGuard::getHoverText() const
{ {
hoverName = VLC->generaltexth->names[ID]; hoverName = getName();
if (wasMyColorVisited (cb->getCurrentPlayer()) )//TODO: use local player, not current if (wasMyColorVisited (cb->getCurrentPlayer()) )//TODO: use local player, not current
hoverName += "\n" + VLC->generaltexth->allTexts[352]; hoverName += "\n" + VLC->generaltexth->allTexts[352];
else else
@ -6289,6 +6304,17 @@ const std::string & CGBorderGuard::getHoverText() const
return hoverName; return hoverName;
} }
void CGBorderGuard::getVisitText (MetaString &text, std::vector<Component> &components, bool isCustom, bool FirstVisit, const CGHeroInstance * h) const
{
text << std::pair<ui8,ui32>(11,18);
}
void CGBorderGuard::getRolloverText (MetaString &text, bool onHover) const
{
if (!onHover)
text << VLC->generaltexth->tentColors[subID] << " " << VLC->generaltexth->names[Obj::KEYMASTER];
}
void CGBorderGuard::onHeroVisit( const CGHeroInstance * h ) const void CGBorderGuard::onHeroVisit( const CGHeroInstance * h ) const
{ {
if (wasMyColorVisited (h->getOwner()) ) if (wasMyColorVisited (h->getOwner()) )
@ -6307,7 +6333,11 @@ void CGBorderGuard::onHeroVisit( const CGHeroInstance * h ) const
iw.text << std::pair<ui8,ui32>(11,18); iw.text << std::pair<ui8,ui32>(11,18);
cb->showInfoDialog (&iw); cb->showInfoDialog (&iw);
//TODO: implement QuestInfo AddQuest aq;
aq.quest = QuestInfo (this, this, pos);
aq.player = h->tempOwner;
cb->sendAndApply (&aq);
//TODO: add this quest only once OR check for multiple instances later
} }
} }
@ -6325,6 +6355,11 @@ void CGBorderGate::onHeroVisit( const CGHeroInstance * h ) const //TODO: passabi
iw.player = h->getOwner(); iw.player = h->getOwner();
iw.text << std::pair<ui8,ui32>(11,18); iw.text << std::pair<ui8,ui32>(11,18);
cb->showInfoDialog(&iw); cb->showInfoDialog(&iw);
AddQuest aq;
aq.quest = QuestInfo (this, this, pos);
aq.player = h->tempOwner;
cb->sendAndApply (&aq);
} }
} }

View File

@ -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_KEYMASTER = 10}; //TODO? MISSION_ART = 5, MISSION_ARMY = 6, MISSION_RESOURCES = 7, MISSION_HERO = 8, MISSION_PLAYER = 9, MISSION_KEYMASTER = 10};
si32 qid; //unique quets id for serialization / identification si32 qid; //unique quets id for serialization / identification
@ -776,6 +776,7 @@ public:
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 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;
@ -1047,6 +1048,7 @@ public:
//SubID 0 - lightblue, 1 - green, 2 - red, 3 - darkblue, 4 - brown, 5 - purple, 6 - white, 7 - black //SubID 0 - lightblue, 1 - green, 2 - red, 3 - darkblue, 4 - brown, 5 - purple, 6 - white, 7 - black
void setPropertyDer (ui8 what, ui32 val); void setPropertyDer (ui8 what, ui32 val);
const std::string getName() const; //depending on color
bool wasMyColorVisited (int player) const; bool wasMyColorVisited (int player) const;
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
@ -1067,16 +1069,19 @@ public:
} }
}; };
class DLL_LINKAGE CGBorderGuard : public CGKeys class DLL_LINKAGE CGBorderGuard : public CGKeys, public CQuest
{ {
public: public:
void initObj(); void initObj();
const std::string & getHoverText() const; const std::string & getHoverText() const;
void getVisitText (MetaString &text, std::vector<Component> &components, bool isCustom, bool FirstVisit, const CGHeroInstance * h = NULL) const;
void getRolloverText (MetaString &text, bool onHover) const;
void onHeroVisit(const CGHeroInstance * h) const; void onHeroVisit(const CGHeroInstance * h) const;
void openGate(const CGHeroInstance *h, ui32 accept) const; void openGate(const CGHeroInstance *h, ui32 accept) const;
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<CGObjectInstance&>(*this); h & static_cast<CGObjectInstance&>(*this);
h & blockVisit; h & blockVisit;
} }

View File

@ -186,6 +186,7 @@ namespace Obj
enum enum
{ {
BOAT = 8, BOAT = 8,
KEYMASTER = 10,
CREATURE_BANK = 16, CREATURE_BANK = 16,
CREATURE_GENERATOR1 = 17, CREATURE_GENERATOR1 = 17,
CURSED_GROUND1 = 21, CURSED_GROUND1 = 21,

View File

@ -108,8 +108,11 @@ DLL_LINKAGE void SetCommanderProperty::applyGs(CGameState *gs)
DLL_LINKAGE void AddQuest::applyGs(CGameState *gs) DLL_LINKAGE void AddQuest::applyGs(CGameState *gs)
{ {
assert (vstd::contains(gs->players, player)); assert (vstd::contains(gs->players, player));
//TODO: check for duplicates? auto vec = &gs->players[player].quests;
gs->players[player].quests.push_back (quest); if (!vstd::contains(*vec, quest))
vec->push_back (quest);
else
tlog2 << "Warning! Attempt to add duplicated quest\n";
} }
DLL_LINKAGE void HeroVisitCastle::applyGs( CGameState *gs ) DLL_LINKAGE void HeroVisitCastle::applyGs( CGameState *gs )

View File

@ -1804,11 +1804,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));
break; break;
} }
case 212: //Border Gate case 212: //Border Gate
{ {
nobj = new CGBorderGate(); nobj = new CGBorderGate();
addQuest (dynamic_cast<CQuest *>(nobj));
break; break;
} }
case 27: case 37: //Eye and Hut of Magi case 27: case 37: //Eye and Hut of Magi