Quellcode durchsuchen

Quest Log is partially functional. TODO: update quest after completion.

DjWarmonger vor 13 Jahren
Ursprung
Commit
49d2ba1982
6 geänderte Dateien mit 141 neuen und 15 gelöschten Zeilen
  1. 4 2
      client/AdventureMapClasses.h
  2. 98 2
      client/CQuestLog.cpp
  3. 30 7
      client/CQuestLog.h
  4. 5 3
      lib/CGameState.h
  5. 1 1
      lib/CObjectHandler.cpp
  6. 3 0
      lib/RegisterTypes.h

+ 4 - 2
client/AdventureMapClasses.h

@@ -209,13 +209,15 @@ class CMinimap : public CIntObject
 	//to initialize colors
 	std::map<int, std::pair<SDL_Color, SDL_Color> > loadColors(std::string from);
 
-	void moveAdvMapSelection();
-
 	void clickLeft(tribool down, bool previousState);
 	void clickRight(tribool down, bool previousState);
 	void hover (bool on);
 	void mouseMoved (const SDL_MouseMotionEvent & sEvent);
 
+protected:
+
+	void moveAdvMapSelection();
+
 public:
 	// terrainID -> (normal color, blocked color)
 	const std::map<int, std::pair<SDL_Color, SDL_Color> > colors;

+ 98 - 2
client/CQuestLog.cpp

@@ -16,15 +16,40 @@
 #include "../lib/CGameState.h"
 #include "../lib/CArtHandler.h"
 #include "../lib/NetPacks.h"
+#include "../lib/CObjectHandler.h"
 
 #include "UIFramework/CGuiHandler.h"
 #include "UIFramework/CIntObjectClasses.h"
 
 struct QuestInfo;
+class CAdvmapInterface;
+
+void CQuestLabel::clickLeft(tribool down, bool previousState)
+{
+	if (down)
+		callback();
+}
+
+void CQuestMinimap::clickLeft(tribool down, bool previousState)
+{
+	if (down)
+	{
+		moveAdvMapSelection();
+		update();
+	}
+}
+
+void CQuestMinimap::update()
+{
+	CMinimap::update();
+	if (currentQuest)
+		addQuestMarks (currentQuest);
+}
 
 CQuestLog::CQuestLog (const std::vector<QuestInfo> & Quests) :
 	CWindowObject(PLAYER_COLORED, "QuestLog.pcx"),
-	quests (Quests), slider (NULL)
+	quests (Quests), slider (NULL),
+	questIndex(0), currentQuest(NULL)
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 	init();
@@ -33,6 +58,77 @@ CQuestLog::CQuestLog (const std::vector<QuestInfo> & Quests) :
 void CQuestLog::init()
 {
 	minimap = new CQuestMinimap (Rect (47, 33, 144, 144));
-	description = new CTextBox ("", Rect(244, 36, 355, 350), 1);
+	description = new CTextBox ("", Rect(240, 33, 355, 355), 1, FONT_SMALL, TOPLEFT, Colors::Cornsilk);
 	ok = new CAdventureMapButton("",CGI->generaltexth->zelp[445].second, boost::bind(&CQuestLog::close,this), 547, 401, "IOKAY.DEF", SDLK_RETURN);
+
+	if (quests.size() > QUEST_COUNT)
+		slider = new CSlider(203, 199, 230, boost::bind (&CQuestLog::sliderMoved, this, _1), quests.size(), quests.size(), false, 0);
+
+	auto map = LOCPLINT->cb->getVisibilityMap(); //TODO: another function to get all tiles?
+
+	for (int g = 0; g < map.size(); ++g)
+		for (int h = 0; h < map[g].size(); ++h)
+			for (int y = 0; y < map[g][h].size(); ++y)
+				minimap->showTile (int3 (g, h, y));
+
+	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);
+		label->callback = boost::bind(&CQuestLog::selectQuest, this, i);
+		labels.push_back(label);
+	}
+
+	recreateQuestList (0); //truncate invisible and too wide labels
+	showAll (screen2);
+}
+
+void CQuestLog::showAll(SDL_Surface * to)
+{
+	CIntObject::showAll (to);
+	recreateQuestList (0);
+	BOOST_FOREACH (auto label, labels)
+	{
+		if (label->active)
+			label->show(to);
+	}
+	if (labels.size())
+		CSDL_Ext::drawBorder(to, Rect::around(labels[questIndex]->pos), int3(Colors::MetallicGold.r, Colors::MetallicGold.g, Colors::MetallicGold.b));
+	description->show(to);
+	minimap->update();
+}
+
+void CQuestLog::recreateQuestList (int newpos)
+{
+	for (int i = 0; i < labels.size(); ++i)
+	{
+		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();
+		}
+		else
+		{
+			labels[i]->deactivate();
+		}
+	}
+}
+
+void CQuestLog::selectQuest (int which)
+{
+	questIndex = which;
+	currentQuest = &quests[which];
+	minimap->currentQuest = currentQuest;
+	if (currentQuest->obj)
+	{
+		//minimap->setLevel (currentQuest->obj->pos.z);
+		adventureInt->centerOn (currentQuest->obj->pos);
+	}
+	description->text = currentQuest->quest.firstVisitText; //TODO: use special log entry text
+	redraw();
+}
+
+void CQuestLog::sliderMoved (int newpos)
+{
+	recreateQuestList (newpos); //move components
+	redraw();
 }

+ 30 - 7
client/CQuestLog.h

@@ -1,5 +1,6 @@
 #include "UIFramework/CIntObject.h"
 #include "AdventureMapClasses.h"
+#include "CAdvmapInterface.h"
 #include "GUIClasses.h"
 
 #include "../lib/CGameState.h"
@@ -28,25 +29,45 @@ class CSlider;
 class CLabel;
 struct QuestInfo;
 
+extern CAdvMapInt *adventureInt;
+
+const int QUEST_COUNT = 9;
+
+class CQuestLabel : public LRClickableAreaWText, public CLabel
+{
+public:
+	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 =  "")
+		: CLabel (x, y, FONT_SMALL, TOPLEFT, Colors::Cornsilk, Text){};
+	void clickLeft(tribool down, bool previousState);
+};
+
 class CQuestMinimap : public CMinimap
 {
-	void clickLeft(tribool down, bool previousState){};
+	void clickLeft(tribool down, bool previousState);
 	void mouseMoved (const SDL_MouseMotionEvent & sEvent){};
 
 public:
 
+	const QuestInfo * currentQuest;
+
 	CQuestMinimap (const Rect & position) : CMinimap (position){};
 	//should be called to invalidate whole map - different player or level
-	void update(){};
-	void setLevel(int level){};
-	void addQuestMarks (QuestInfo q){};
+	void update();
+	void setLevel(int level);
+	void addQuestMarks (const QuestInfo * q){};
 
-	void showAll(SDL_Surface * to){};
+	//void showAll(SDL_Surface * to){};
 };
 
 class CQuestLog : public CWindowObject
 {
+	int questIndex;
+	const QuestInfo * currentQuest;
+
 	const std::vector<QuestInfo> quests;
+	std::vector<CQuestLabel *> labels;
 	CTextBox * description;
 	CQuestMinimap * minimap;
 	CSlider * slider; //scrolls quests
@@ -59,8 +80,10 @@ public:
 	~CQuestLog(){};
 
 	void init ();
-	void selectQuest (int which){};
+	void selectQuest (int which);
 	void updateMinimap (int which){};
 	void printDescription (int which){};
-	void sliderMoved(int newpos){};
+	void sliderMoved (int newpos);
+	void recreateQuestList (int pos);
+	void showAll (SDL_Surface * to);
 };

+ 5 - 3
lib/CGameState.h

@@ -14,6 +14,7 @@
 #include "IGameCallback.h"
 #include "ResourceSet.h"
 #include "int3.h"
+#include "CObjectHandler.h"
 
 
 /*
@@ -60,6 +61,7 @@ class IModableArt;
 class CGGarrison;
 class CGameInfo;
 struct QuestInfo;
+class CQuest;
 
 namespace boost
 {
@@ -443,13 +445,13 @@ public:
  
 struct DLL_LINKAGE QuestInfo //universal interface for human and AI
 {
-	const CQuest * quest;
+	CQuest quest;
 	const CGObjectInstance * obj; //related object, most likely Seer Hut
 	int3 tile;
 
 	QuestInfo(){};
-	QuestInfo (const CQuest * Quest, const CGObjectInstance * Obj, int3 Tile) :
-		quest (Quest), obj (Obj), tile (Tile){}
+	QuestInfo (const CQuest &Quest, const CGObjectInstance * Obj, int3 Tile) :
+		quest (Quest), obj (Obj), tile (Tile){};
 
 	//std::vector<std::string> > texts //allow additional info for quest log?
 

+ 1 - 1
lib/CObjectHandler.cpp

@@ -4286,7 +4286,7 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const
 			cb->setObjProperty (id, 10, 1);
 
 			AddQuest aq;
-			aq.quest = QuestInfo (this, this, pos);
+			aq.quest = QuestInfo (*this, this, pos);
 			aq.player = h->tempOwner;
 			cb->sendAndApply (&aq); //TODO: merge with setObjProperty?
 		}

+ 3 - 0
lib/RegisterTypes.h

@@ -36,6 +36,7 @@ void registerTypes1(Serializer &s)
 	s.template registerType<CGPickable>();
 	s.template registerType<CGCreature>();
 	s.template registerType<CGSignBottle>();
+	s.template registerType<CQuest>();
 	s.template registerType<CGSeerHut>();
 	s.template registerType<CGQuestGuard>();
 	s.template registerType<CGWitchHut>();
@@ -93,6 +94,7 @@ void registerTypes1(Serializer &s)
 	s.template registerType<CArmedInstance>();
 	s.template registerType<CStack>();
 	s.template registerType<BattleInfo>();
+	s.template registerType<QuestInfo>();
 	s.template registerType<CArtifactInstance>();
 	s.template registerType<CCombinedArtifactInstance>();
 
@@ -173,6 +175,7 @@ void registerTypes2(Serializer &s)
 	s.template registerType<OpenWindow>();
 	s.template registerType<NewObject>();
 	s.template registerType<NewArtifact>();
+	s.template registerType<AddQuest>();
 	s.template registerType<ChangeStackCount>();
 	s.template registerType<SetStackType>();
 	s.template registerType<EraseStack>();