From 32d1a08470271a0573fa3a96ce456211fae13802 Mon Sep 17 00:00:00 2001
From: DjWarmonger <warmonger@vp.pl>
Date: Sun, 8 Jul 2012 08:42:03 +0000
Subject: [PATCH] Pointer serialization for CQuest.

---
 client/CQuestLog.cpp   | 4 ++--
 lib/CGameState.h       | 4 ++--
 lib/CObjectHandler.cpp | 2 +-
 lib/CObjectHandler.h   | 4 +++-
 lib/Connection.cpp     | 1 +
 lib/map.cpp            | 8 ++++++++
 lib/map.h              | 2 ++
 7 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/client/CQuestLog.cpp b/client/CQuestLog.cpp
index 1b041f446..387e89f0e 100644
--- a/client/CQuestLog.cpp
+++ b/client/CQuestLog.cpp
@@ -90,7 +90,7 @@ void CQuestLog::init()
 	for (int i = 0; i < quests.size(); ++i)
 	{
 		MetaString text;
-		quests[i].quest.getRolloverText (text, false);
+		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());
@@ -145,7 +145,7 @@ void CQuestLog::selectQuest (int which)
 	}
 	MetaString text;
 	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);
 	description->setTxt (text.toString()); //TODO: use special log entry text
 	redraw();
 }
diff --git a/lib/CGameState.h b/lib/CGameState.h
index d21fda6cd..f08bdd6be 100644
--- a/lib/CGameState.h
+++ b/lib/CGameState.h
@@ -445,12 +445,12 @@ public:
  
 struct DLL_LINKAGE QuestInfo //universal interface for human and AI
 {
-	CQuest quest;
+	const CQuest * quest;
 	const CGObjectInstance * obj; //related object, most likely Seer Hut
 	int3 tile;
 
 	QuestInfo(){};
-	QuestInfo (const CQuest &Quest, const CGObjectInstance * Obj, int3 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?
diff --git a/lib/CObjectHandler.cpp b/lib/CObjectHandler.cpp
index 2631897bf..1f22cef67 100644
--- a/lib/CObjectHandler.cpp
+++ b/lib/CObjectHandler.cpp
@@ -4525,7 +4525,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?
 		}
diff --git a/lib/CObjectHandler.h b/lib/CObjectHandler.h
index f10e4e742..565e5c409 100644
--- a/lib/CObjectHandler.h
+++ b/lib/CObjectHandler.h
@@ -60,6 +60,8 @@ 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?
 
+	si32 qid; //unique quets id for serialization / identification
+
 	ui8 missionType, progress;
 	si32 lastDay; //after this day (first day is 0) mission cannot be completed; if -1 - no limit
 
@@ -88,7 +90,7 @@ public:
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
-		h & missionType & progress & lastDay & m13489val & m2stats & m5arts & m6creatures & m7resources
+		h & qid & missionType & progress & lastDay & m13489val & m2stats & m5arts & m6creatures & m7resources
 			& textOption & stackToKill & stackDirection & heroName & heroPortrait
 			& firstVisitText & nextVisitText & completedText & isCustomFirst & isCustomNext & isCustomComplete;
 	}
diff --git a/lib/Connection.cpp b/lib/Connection.cpp
index 009fcb104..1ab6e64d7 100644
--- a/lib/Connection.cpp
+++ b/lib/Connection.cpp
@@ -432,5 +432,6 @@ void CSerializer::addStdVecItems(CGameState *gs, LibClasses *lib)
 	registerVectoredType(&lib->creh->creatures, &CCreature::idNumber);
 	registerVectoredType(&lib->arth->artifacts, &CArtifact::id);
 	registerVectoredType(&gs->map->artInstances, &CArtifactInstance::id);
+	registerVectoredType(&gs->map->quests, &CQuest::qid);
 	smartVectorMembersSerialization = true;
 }
diff --git a/lib/map.cpp b/lib/map.cpp
index 932a60644..edf3505dd 100644
--- a/lib/map.cpp
+++ b/lib/map.cpp
@@ -559,6 +559,7 @@ CGHeroInstance * Mapa::getHero(int ID, int mode)
 int Mapa::loadSeerHut( const ui8 * bufor, int i, CGObjectInstance *& nobj )
 {
 	CGSeerHut *hut = new CGSeerHut();
+	addQuest (hut);
 	nobj = hut;
 
 	if(version>RoE)
@@ -1945,6 +1946,7 @@ bool Mapa::isInTheMap(const int3 &pos) const
 
 void Mapa::loadQuest(CQuest * guard, const ui8 * bufor, int & i)
 {
+	addQuest (guard);
 	guard->missionType = bufor[i]; ++i;
 	//int len1, len2, len3;
 	switch(guard->missionType)
@@ -2068,6 +2070,12 @@ void Mapa::addNewArtifactInstance( CArtifactInstance *art )
 	artInstances.push_back(art);
 }
 
+void Mapa::addQuest (CQuest *quest)
+{
+	quest->qid = quests.size();
+	quests.push_back(quest);
+}
+
 bool Mapa::loadArtifactToSlot(CGHeroInstance *h, int slot, const ui8 * bufor, int &i)
 {
 	const int artmask = version == RoE ? 0xff : 0xffff;
diff --git a/lib/map.h b/lib/map.h
index f9e0fc72c..9b05b8c82 100644
--- a/lib/map.h
+++ b/lib/map.h
@@ -306,6 +306,7 @@ struct DLL_LINKAGE Mapa : public CMapHeader
 	std::vector< ConstTransitivePtr<CGHeroInstance> > heroes;
 	std::vector< ConstTransitivePtr<CGTownInstance> > towns;
 	std::vector< ConstTransitivePtr<CArtifactInstance> > artInstances; //stores all artifacts
+	std::vector< ConstTransitivePtr<CQuest> > quests;
 	//std::vector< ConstTransitivePtr<CCommanderInstance> > commanders;
 	//bmap<ui16, ConstTransitivePtr<CGCreature> > monsters;
 	//bmap<ui16, ConstTransitivePtr<CGHeroInstance> > heroesToBeat;
@@ -330,6 +331,7 @@ struct DLL_LINKAGE Mapa : public CMapHeader
 
 	CArtifactInstance *createArt(int aid, int spellID = -1);
 	void addNewArtifactInstance(CArtifactInstance *art);
+	void addQuest (CQuest *quest);
 	void eraseArtifactInstance(CArtifactInstance *art);