浏览代码

[Refactoring] use virtual method for object specific actions when new map object is created
* --TODO
* fixes CID 1366291, CID 1366297

AlexVinS 8 年之前
父节点
当前提交
70a092f58c

+ 5 - 0
lib/mapObjects/CGHeroInstance.cpp

@@ -1559,6 +1559,11 @@ std::string CGHeroInstance::getHeroTypeName() const
 	return "";
 }
 
+void CGHeroInstance::afterAddToMap(CMap * map)
+{
+	map->heroesOnMap.push_back(this);
+}
+
 void CGHeroInstance::setHeroTypeName(const std::string & identifier)
 {
 	if(ID == Obj::HERO || ID == Obj::PRISON)

+ 2 - 0
lib/mapObjects/CGHeroInstance.h

@@ -256,6 +256,8 @@ public:
 	void initObj(CRandomGenerator & rand) override;
 	void onHeroVisit(const CGHeroInstance * h) const override;
 	std::string getObjectName() const override;
+
+	void afterAddToMap(CMap * map) override;
 protected:
 	void setPropertyDer(ui8 what, ui32 val) override;//synchr
 	///common part of hero instance and hero definition

+ 6 - 1
lib/mapObjects/CGTownInstance.cpp

@@ -18,7 +18,7 @@
 #include "../CModHandler.h"
 #include "../IGameCallback.h"
 #include "../CGameState.h"
-#include "../mapping/CMapDefines.h"
+#include "../mapping/CMap.h"
 #include "../CPlayerState.h"
 #include "../serializer/JsonSerializeFormat.h"
 
@@ -1335,6 +1335,11 @@ void CGTownInstance::battleFinished(const CGHeroInstance *hero, const BattleResu
 	}
 }
 
+void CGTownInstance::afterAddToMap(CMap * map)
+{
+	map->towns.push_back(this);
+}
+
 void CGTownInstance::serializeJsonOptions(JsonSerializeFormat & handler)
 {
 	CGObjectInstance::serializeJsonOwner(handler);

+ 2 - 0
lib/mapObjects/CGTownInstance.h

@@ -277,6 +277,8 @@ public:
 	void initObj(CRandomGenerator & rand) override;
 	void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
 	std::string getObjectName() const override;
+
+	void afterAddToMap(CMap * map) override;
 protected:
 	void setPropertyDer(ui8 what, ui32 val) override;
 	void serializeJsonOptions(JsonSerializeFormat & handler) override;

+ 6 - 1
lib/mapObjects/CObjectHandler.cpp

@@ -345,9 +345,14 @@ void CGObjectInstance::serializeJson(JsonSerializeFormat & handler)
 	}
 }
 
-void CGObjectInstance::serializeJsonOptions(JsonSerializeFormat & handler)
+void CGObjectInstance::afterAddToMap(CMap * map)
 {
+	//nothing here
+}
 
+void CGObjectInstance::serializeJsonOptions(JsonSerializeFormat & handler)
+{
+	//nothing here
 }
 
 void CGObjectInstance::serializeJsonOwner(JsonSerializeFormat & handler)

+ 2 - 1
lib/mapObjects/CObjectHandler.h

@@ -23,6 +23,7 @@ struct MetaString;
 struct BattleResult;
 class JsonSerializeFormat;
 class CRandomGenerator;
+class CMap;
 
 // This one teleport-specific, but has to be available everywhere in callbacks and netpacks
 // For now it's will be there till teleports code refactored and moved into own file
@@ -172,7 +173,7 @@ public:
 	/// method for synchronous update. Note: For new properties classes should override setPropertyDer instead
 	void setProperty(ui8 what, ui32 val) override final;
 
-	//friend class CGameHandler;
+	virtual void afterAddToMap(CMap * map);
 
 	///Entry point of binary (de-)serialization
 	template <typename Handler> void serialize(Handler &h, const int version)

+ 16 - 0
lib/mapObjects/CQuest.cpp

@@ -25,6 +25,7 @@
 #include "../GameConstants.h"
 #include "../StringConstants.h"
 #include "../spells/CSpellHandler.h"
+#include "../mapping/CMap.h"
 
 
 std::map <PlayerColor, std::set <ui8> > CGKeys::playerKeyMap;
@@ -599,6 +600,11 @@ void IQuestObject::getVisitText (MetaString &text, std::vector<Component> &compo
 	quest->getVisitText (text,components, isCustom, FirstVisit, h);
 }
 
+void IQuestObject::afterAddToMapCommon(CMap * map)
+{
+	map->addNewQuestInstance(quest);
+}
+
 void CGSeerHut::getCompletionText(MetaString &text, std::vector<Component> &components, bool isCustom, const CGHeroInstance * h) const
 {
 	quest->getCompletionText (text, components, isCustom, h);
@@ -849,6 +855,11 @@ void CGSeerHut::blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer)
 	finishQuest(hero, answer);
 }
 
+void CGSeerHut::afterAddToMap(CMap* map)
+{
+	IQuestObject::afterAddToMapCommon(map);
+}
+
 void CGSeerHut::serializeJsonOptions(JsonSerializeFormat & handler)
 {
 	static const std::map<ERewardType, std::string> REWARD_MAP =
@@ -1128,6 +1139,11 @@ void CGBorderGuard::blockingDialogAnswered(const CGHeroInstance *hero, ui32 answ
 		cb->removeObject(this);
 }
 
+void CGBorderGuard::afterAddToMap(CMap * map)
+{
+	IQuestObject::afterAddToMapCommon(map);
+}
+
 void CGBorderGate::onHeroVisit(const CGHeroInstance * h) const //TODO: passability
 {
 	if (!wasMyColorVisited (h->getOwner()) )

+ 6 - 0
lib/mapObjects/CQuest.h

@@ -98,6 +98,8 @@ public:
 	{
 		h & quest;
 	}
+protected:
+	void afterAddToMapCommon(CMap * map);
 };
 
 class DLL_LINKAGE CGSeerHut : public CArmedInstance, public IQuestObject //army is used when giving reward
@@ -126,6 +128,8 @@ public:
 	void finishQuest (const CGHeroInstance * h, ui32 accept) const; //common for both objects
 	virtual void completeQuest (const CGHeroInstance * h) const;
 
+	void afterAddToMap(CMap * map) override;
+
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 		h & static_cast<CArmedInstance&>(*this) & static_cast<IQuestObject&>(*this);
@@ -199,6 +203,8 @@ public:
 	void getRolloverText (MetaString &text, bool onHover) const;
 	bool checkQuest (const CGHeroInstance * h) const override;
 
+	void afterAddToMap(CMap * map) override;
+
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 		h & static_cast<IQuestObject&>(*this);

+ 6 - 0
lib/mapObjects/MiscObjects.cpp

@@ -1405,6 +1405,12 @@ void CGArtifact::blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer)
 		cb->startBattleI(hero, this);
 }
 
+void CGArtifact::afterAddToMap(CMap * map)
+{
+	if(ID == Obj::SPELL_SCROLL && storedArtifact && storedArtifact->id.getNum() < 0)
+        map->addNewArtifactInstance(storedArtifact);
+}
+
 void CGArtifact::serializeJsonOptions(JsonSerializeFormat& handler)
 {
 	handler.serializeString("guardMessage", message);

+ 2 - 0
lib/mapObjects/MiscObjects.h

@@ -189,6 +189,8 @@ public:
 	void pick( const CGHeroInstance * h ) const;
 	void initObj(CRandomGenerator & rand) override;
 
+	void afterAddToMap(CMap * map) override;
+
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 		h & static_cast<CArmedInstance&>(*this);

+ 7 - 31
lib/mapping/CMap.cpp

@@ -418,7 +418,6 @@ bool CMap::checkForVisitableDir(const int3 & src, const TerrainTile *pom, const
 
 int3 CMap::guardingCreaturePosition (int3 pos) const
 {
-
 	const int3 originalPos = pos;
 	// Give monster at position priority.
 	if (!isInTheMap(pos))
@@ -591,6 +590,12 @@ void CMap::eraseArtifactInstance(CArtifactInstance * art)
 	artInstances[art->id.getNum()].dellNull();
 }
 
+void CMap::addNewQuestInstance(CQuest* quest)
+{
+	quest->qid = quests.size();
+	quests.push_back(quest);
+}
+
 void CMap::addNewObject(CGObjectInstance * obj)
 {
 	if(obj->id != ObjectInstanceID(objects.size()))
@@ -607,36 +612,7 @@ void CMap::addNewObject(CGObjectInstance * obj)
 	instanceNames[obj->instanceName] = obj;
 	addBlockVisTiles(obj);
 
-	//todo: make this virtual method of CGObjectInstance
-	switch (obj->ID)
-	{
-	case Obj::TOWN:
-		towns.push_back(static_cast<CGTownInstance *>(obj));
-		break;
-	case Obj::HERO:
-		heroesOnMap.push_back(static_cast<CGHeroInstance*>(obj));
-		break;
-	case Obj::SEER_HUT:
-	case Obj::QUEST_GUARD:
-	case Obj::BORDERGUARD:
-	case Obj::BORDER_GATE:
-		{
-			auto q = dynamic_cast<IQuestObject *>(obj);
-			q->quest->qid = quests.size();
-			quests.push_back(q->quest);
-		}
-		break;
-	case Obj::SPELL_SCROLL:
-		{
-			CGArtifact * art = dynamic_cast<CGArtifact *>(obj);
-
-			if(art->storedArtifact && art->storedArtifact->id.getNum() < 0)
-				addNewArtifactInstance(art->storedArtifact);
-		}
-		break;
-	default:
-		break;
-	}
+	obj->afterAddToMap(this);
 }
 
 void CMap::initTerrain()

+ 3 - 0
lib/mapping/CMap.h

@@ -334,6 +334,9 @@ public:
 	void addNewArtifactInstance(CArtifactInstance * art);
 	void eraseArtifactInstance(CArtifactInstance * art);
 
+	void addNewQuestInstance(CQuest * quest);
+
+	///Use only this method when creating new map object instances
 	void addNewObject(CGObjectInstance * obj);
 
 	/// Gets object of specified type on requested position