From 18535db0efb28f6c5aa995352eab3c1cea41c494 Mon Sep 17 00:00:00 2001
From: ArseniyShestakov <ArseniyShestakov@users.noreply.github.com>
Date: Sun, 8 Mar 2015 16:37:33 +0300
Subject: [PATCH] Add TeleportDialog and CTeleportDialogQuery

TeleportDialog is based off BlockingDialog and it's needed for server to ask client what teleport hero should be teleported to.
It's also contain list of possible exits, identifier of currently used channel and also impassable option.
If impassable set to true then client will remember that current teleport channel is lack of exit point.
---
 client/NetPacksClient.cpp         |  5 +++++
 lib/NetPacks.h                    | 22 ++++++++++++++++++++++
 lib/registerTypes/RegisterTypes.h |  1 +
 server/CQuery.cpp                 | 12 ++++++++++++
 server/CQuery.h                   | 10 ++++++++++
 5 files changed, 50 insertions(+)

diff --git a/client/NetPacksClient.cpp b/client/NetPacksClient.cpp
index 1dee3e8d4..f6a8adc02 100644
--- a/client/NetPacksClient.cpp
+++ b/client/NetPacksClient.cpp
@@ -595,6 +595,11 @@ void ExchangeDialog::applyCl(CClient *cl)
 	INTERFACE_CALL_IF_PRESENT(heroes[0]->tempOwner, heroExchangeStarted, heroes[0]->id, heroes[1]->id, queryID);
 }
 
+void TeleportDialog::applyCl( CClient *cl )
+{
+	CALL_ONLY_THAT_INTERFACE(hero->tempOwner,showTeleportDialog,channel,exits,impassable,queryID);
+}
+
 void BattleStart::applyFirstCl( CClient *cl )
 {
 	//Cannot use the usual macro because curB is not set yet
diff --git a/lib/NetPacks.h b/lib/NetPacks.h
index f798a502d..0a6dca03e 100644
--- a/lib/NetPacks.h
+++ b/lib/NetPacks.h
@@ -1206,6 +1206,28 @@ struct ExchangeDialog : public Query//2005
 	}
 };
 
+struct TeleportDialog : public Query//2006
+{
+	TeleportDialog() {type = 2006;}
+	TeleportDialog(const CGHeroInstance *Hero, TeleportChannelID Channel)
+		: hero(Hero), channel(Channel), impassable(false)
+	{
+		type = 2006;
+	}
+
+	void applyCl(CClient *cl);
+
+	const CGHeroInstance *hero;
+	TeleportChannelID channel;
+	std::vector<ObjectInstanceID> exits;
+	bool impassable;
+
+	template <typename Handler> void serialize(Handler &h, const int version)
+	{
+		h & queryID & hero & channel & exits & impassable;
+	}
+};
+
 struct BattleInfo;
 struct BattleStart : public CPackForClient//3000
 {
diff --git a/lib/registerTypes/RegisterTypes.h b/lib/registerTypes/RegisterTypes.h
index 69761172f..252c4b5e2 100644
--- a/lib/registerTypes/RegisterTypes.h
+++ b/lib/registerTypes/RegisterTypes.h
@@ -286,6 +286,7 @@ void registerTypesClientPacks2(Serializer &s)
 	s.template registerType<Query, BlockingDialog>();
 	s.template registerType<Query, GarrisonDialog>();
 	s.template registerType<Query, ExchangeDialog>();
+	s.template registerType<Query, TeleportDialog>();
 
 	s.template registerType<CPackForClient, CGarrisonOperationPack>();
 	s.template registerType<CGarrisonOperationPack, ChangeStackCount>();
diff --git a/server/CQuery.cpp b/server/CQuery.cpp
index 45bffae79..19ca42a7e 100644
--- a/server/CQuery.cpp
+++ b/server/CQuery.cpp
@@ -313,6 +313,18 @@ CBlockingDialogQuery::CBlockingDialogQuery(const BlockingDialog &bd)
 	addPlayer(bd.player);
 }
 
+void CTeleportDialogQuery::notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const
+{
+	auto obj = dynamic_cast<const CGTeleport *>(objectVisit.visitedObject);
+	obj->teleportDialogAnswered(objectVisit.visitingHero, *answer, td.exits);
+}
+
+CTeleportDialogQuery::CTeleportDialogQuery(const TeleportDialog &td)
+{
+	this->td = td;
+	addPlayer(td.hero->tempOwner);
+}
+
 CHeroLevelUpDialogQuery::CHeroLevelUpDialogQuery(const HeroLevelUp &Hlu)
 {
 	hlu = Hlu;
diff --git a/server/CQuery.h b/server/CQuery.h
index 355882e93..b4e725102 100644
--- a/server/CQuery.h
+++ b/server/CQuery.h
@@ -130,6 +130,16 @@ public:
 	virtual void notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const override;
 };
 
+class CTeleportDialogQuery : public CDialogQuery
+{
+public:
+	TeleportDialog td; //copy of pack... debug purposes
+
+	CTeleportDialogQuery(const TeleportDialog &td);
+
+	virtual void notifyObjectAboutRemoval(const CObjectVisitQuery &objectVisit) const override;
+};
+
 class CHeroLevelUpDialogQuery : public CDialogQuery
 {
 public: