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:
parent
32d1a08470
commit
b28da1a5d3
@ -376,21 +376,24 @@ const SDL_Color & CMinimapInstance::getTileColor(const int3 & pos)
|
||||
else
|
||||
return parent->colors.find(tile->tertype)->second.first;
|
||||
}
|
||||
|
||||
void CMinimapInstance::blitTileWithColor(const SDL_Color &color, const int3 &tile, SDL_Surface *to, int toX, int toY)
|
||||
void CMinimapInstance::tileToPixels (const int3 &tile, int &x, int &y, int toX, int toY)
|
||||
{
|
||||
//method is mostly copy-pasted from drawScaled()
|
||||
int3 mapSizes = LOCPLINT->cb->getMapSize();
|
||||
|
||||
double stepX = double(pos.w) / mapSizes.x;
|
||||
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
|
||||
// begin - first to blit, end - first NOT to blit
|
||||
int xBegin = toX + stepX * tile.x;
|
||||
int yBegin = toY + stepY * tile.y;
|
||||
int xEnd = toX + stepX * (tile.x + 1);
|
||||
int yEnd = toY + stepY * (tile.y + 1);
|
||||
int xBegin, yBegin, xEnd, yEnd;
|
||||
tileToPixels (tile, xBegin, yBegin, toX, toY);
|
||||
tileToPixels (int3 (tile.x + 1, tile.y + 1, tile.z), xEnd, yEnd, toX, toY);
|
||||
|
||||
for (int y=yBegin; y<yEnd; y++)
|
||||
{
|
||||
@ -516,7 +519,7 @@ CMinimap::CMinimap(const Rect &position):
|
||||
pos.h = position.h;
|
||||
}
|
||||
|
||||
void CMinimap::moveAdvMapSelection()
|
||||
int3 CMinimap::translateMousePosition()
|
||||
{
|
||||
// 0 = top-left corner, 1 = bottom-right corner
|
||||
double dx = double(GH.current->motion.x - pos.x) / pos.w;
|
||||
@ -524,8 +527,13 @@ void CMinimap::moveAdvMapSelection()
|
||||
|
||||
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);
|
||||
|
||||
redraw();
|
||||
|
@ -195,6 +195,7 @@ public:
|
||||
~CMinimapInstance();
|
||||
|
||||
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);
|
||||
};
|
||||
@ -202,6 +203,8 @@ public:
|
||||
/// Minimap which is displayed at the right upper corner of adventure map
|
||||
class CMinimap : public CIntObject
|
||||
{
|
||||
protected:
|
||||
|
||||
CPicture *aiShield; //the graphic displayed during AI turn
|
||||
CMinimapInstance * minimap;
|
||||
int level;
|
||||
@ -214,8 +217,6 @@ class CMinimap : public CIntObject
|
||||
void hover (bool on);
|
||||
void mouseMoved (const SDL_MouseMotionEvent & sEvent);
|
||||
|
||||
protected:
|
||||
|
||||
void moveAdvMapSelection();
|
||||
|
||||
public:
|
||||
@ -225,6 +226,7 @@ public:
|
||||
CMinimap(const Rect & position);
|
||||
|
||||
//should be called to invalidate whole map - different player or level
|
||||
int3 translateMousePosition();
|
||||
void update();
|
||||
void setLevel(int level);
|
||||
void setAIRadar(bool on);
|
||||
|
@ -46,13 +46,76 @@ void CQuestLabel::showAll(SDL_Surface * 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)
|
||||
callback();
|
||||
}
|
||||
|
||||
void CQuestIcon::showAll(SDL_Surface * to)
|
||||
{
|
||||
if(bg)
|
||||
{
|
||||
moveAdvMapSelection();
|
||||
update();
|
||||
if(srcRect)
|
||||
{
|
||||
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()
|
||||
@ -62,6 +125,20 @@ void CQuestMinimap::update()
|
||||
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) :
|
||||
CWindowObject(PLAYER_COLORED, "QuestLog.pcx"),
|
||||
quests (Quests), slider (NULL),
|
||||
@ -116,6 +193,7 @@ void CQuestLog::showAll(SDL_Surface * to)
|
||||
}
|
||||
description->show(to);
|
||||
minimap->update();
|
||||
minimap->show(to);
|
||||
}
|
||||
|
||||
void CQuestLog::recreateQuestList (int newpos)
|
||||
@ -139,10 +217,7 @@ void CQuestLog::selectQuest (int which)
|
||||
questIndex = which;
|
||||
currentQuest = &quests[which];
|
||||
minimap->currentQuest = currentQuest;
|
||||
if (currentQuest->obj)
|
||||
{
|
||||
adventureInt->centerOn (currentQuest->obj->pos);
|
||||
}
|
||||
|
||||
MetaString text;
|
||||
std::vector<Component> components; //TODO: display them
|
||||
currentQuest->quest->getVisitText (text, components , currentQuest->quest->isCustomFirst, true);
|
||||
|
@ -44,22 +44,36 @@ public:
|
||||
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
|
||||
{
|
||||
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){};
|
||||
|
||||
public:
|
||||
|
||||
const QuestInfo * currentQuest;
|
||||
|
||||
CQuestMinimap (const Rect & position) : CMinimap (position){};
|
||||
CQuestMinimap (const Rect & position);
|
||||
//should be called to invalidate whole map - different player or level
|
||||
void update();
|
||||
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
|
||||
|
@ -453,6 +453,11 @@ struct DLL_LINKAGE QuestInfo //universal interface for human and AI
|
||||
QuestInfo (const CQuest * Quest, const CGObjectInstance * Obj, int3 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?
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
|
@ -502,6 +502,15 @@ void CGeneralTextHandler::load()
|
||||
for (i = 0; i < 48; ++i)
|
||||
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
|
||||
buf = bitmaph->getTextFile ("CAMPTEXT.TXT");
|
||||
it = 0;
|
||||
|
@ -66,6 +66,7 @@ public:
|
||||
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
|
||||
std::vector<std::string> seerNames;
|
||||
std::vector<std::string> tentColors;
|
||||
std::vector<std::string> threat; //power rating for neutral stacks
|
||||
|
||||
//sec skills
|
||||
|
@ -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
|
||||
{
|
||||
switch (ID)
|
||||
@ -6244,9 +6251,16 @@ bool CGKeys::wasMyColorVisited (int player) const
|
||||
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
|
||||
{
|
||||
hoverName = VLC->generaltexth->names[ID];
|
||||
hoverName = getName();
|
||||
if (wasMyColorVisited (cb->getCurrentPlayer()) )//TODO: use local player, not current
|
||||
hoverName += "\n" + VLC->generaltexth->allTexts[352];
|
||||
else
|
||||
@ -6276,12 +6290,13 @@ void CGKeymasterTent::onHeroVisit( const CGHeroInstance * h ) const
|
||||
|
||||
void CGBorderGuard::initObj()
|
||||
{
|
||||
ui32 m13489val = subID; //store color as quest info
|
||||
blockVisit = true;
|
||||
}
|
||||
|
||||
const std::string & CGBorderGuard::getHoverText() const
|
||||
{
|
||||
hoverName = VLC->generaltexth->names[ID];
|
||||
hoverName = getName();
|
||||
if (wasMyColorVisited (cb->getCurrentPlayer()) )//TODO: use local player, not current
|
||||
hoverName += "\n" + VLC->generaltexth->allTexts[352];
|
||||
else
|
||||
@ -6289,6 +6304,17 @@ const std::string & CGBorderGuard::getHoverText() const
|
||||
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
|
||||
{
|
||||
if (wasMyColorVisited (h->getOwner()) )
|
||||
@ -6307,7 +6333,11 @@ void CGBorderGuard::onHeroVisit( const CGHeroInstance * h ) const
|
||||
iw.text << std::pair<ui8,ui32>(11,18);
|
||||
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.text << std::pair<ui8,ui32>(11,18);
|
||||
cb->showInfoDialog(&iw);
|
||||
|
||||
AddQuest aq;
|
||||
aq.quest = QuestInfo (this, this, pos);
|
||||
aq.player = h->tempOwner;
|
||||
cb->sendAndApply (&aq);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ class DLL_LINKAGE CQuest
|
||||
{
|
||||
public:
|
||||
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
|
||||
|
||||
@ -776,6 +776,7 @@ public:
|
||||
int checkDirection() const; //calculates the region of map where monster is placed
|
||||
void newTurn() 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 finishQuest (const CGHeroInstance * h, ui32 accept) const; //common for both objects
|
||||
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
|
||||
|
||||
void setPropertyDer (ui8 what, ui32 val);
|
||||
const std::string getName() const; //depending on color
|
||||
bool wasMyColorVisited (int player) const;
|
||||
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:
|
||||
void initObj();
|
||||
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 openGate(const CGHeroInstance *h, ui32 accept) const;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CQuest&>(*this);
|
||||
h & static_cast<CGObjectInstance&>(*this);
|
||||
h & blockVisit;
|
||||
}
|
||||
|
@ -186,6 +186,7 @@ namespace Obj
|
||||
enum
|
||||
{
|
||||
BOAT = 8,
|
||||
KEYMASTER = 10,
|
||||
CREATURE_BANK = 16,
|
||||
CREATURE_GENERATOR1 = 17,
|
||||
CURSED_GROUND1 = 21,
|
||||
|
@ -108,8 +108,11 @@ DLL_LINKAGE void SetCommanderProperty::applyGs(CGameState *gs)
|
||||
DLL_LINKAGE void AddQuest::applyGs(CGameState *gs)
|
||||
{
|
||||
assert (vstd::contains(gs->players, player));
|
||||
//TODO: check for duplicates?
|
||||
gs->players[player].quests.push_back (quest);
|
||||
auto vec = &gs->players[player].quests;
|
||||
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 )
|
||||
|
@ -1804,11 +1804,13 @@ void Mapa::readObjects( const ui8 * bufor, int &i)
|
||||
case 9: //Border Guard
|
||||
{
|
||||
nobj = new CGBorderGuard();
|
||||
addQuest (dynamic_cast<CQuest *>(nobj));
|
||||
break;
|
||||
}
|
||||
case 212: //Border Gate
|
||||
{
|
||||
nobj = new CGBorderGate();
|
||||
addQuest (dynamic_cast<CQuest *>(nobj));
|
||||
break;
|
||||
}
|
||||
case 27: case 37: //Eye and Hut of Magi
|
||||
|
Loading…
Reference in New Issue
Block a user