关灯
开启左侧

WOTLK335最新的带数据库的魔兽服务端的传送NPC的代码

  [复制链接]
admin实名认证 发表于 2016-4-19 23:05:51 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
 
From 31fbd1716a927b1d8eca58f8b9027087e5dba6ea Mon Sep 17 00:00:00 2001From: LordPsyan <uppp@juno.com>
Date: Mon, 21 Feb 2011 18:55:53 -0500
Subject: [PATCH] 11261-TeleNPC2

---
README.NPCTELEPORT                                |   14 +
sql/CMakeLists.txt                                |    1 +
sql/extras/setup_npc_teleport.sql                 |  119 +++++++
src/server/game/AI/ScriptedAI/sc_npc_teleport.cpp |  373 +++++++++++++++++++++
src/server/game/AI/ScriptedAI/sc_npc_teleport.h   |  151 +++++++++
src/server/game/Scripting/ScriptLoader.cpp        |    6 +-
src/server/game/Scripting/ScriptMgr.cpp           |    3 +
src/server/scripts/CMakeLists.txt                 |    3 +
src/server/scripts/Custom/npc_teleport.cpp        |  221 ++++++++++++
9 files changed, 890 insertions(+), 1 deletions(-)
create mode 100644 README.NPCTELEPORT
create mode 100644 sql/extras/setup_npc_teleport.sql
create mode 100644 src/server/game/AI/ScriptedAI/sc_npc_teleport.cpp
create mode 100644 src/server/game/AI/ScriptedAI/sc_npc_teleport.h
create mode 100644 src/server/scripts/Custom/npc_teleport.cpp

diff --git a/README.NPCTELEPORT b/README.NPCTELEPORT
new file mode 100644
index 0000000..015c9c2
--- /dev/null
+++ b/README.NPCTELEPORT
@@ -0,0 +1,14 @@
+NPC Teleport for Trinity
+
+Original author : Wilibald09
+
+Allows you to add a custom NPC for teleporting, using .npc add 100000.
+The default NPC is entry 100000.
+
+All settings are located in the DB, so you can customize and add destinations,
+set level restrictions and also charge the player for teleporting.
+
+Installation:
+
+Run the query setup_npc_teleport.sql located in the trinity sql directory on
+your world DB. This will setup the DB and you can customize from there.
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index e1b0921..4562748 100644
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -15,6 +15,7 @@ if( WITH_SQL )
       scripts
       base
       create
+          All
     DESTINATION
       shared/trinity/sql
   )
diff --git a/sql/extras/setup_npc_teleport.sql b/sql/extras/setup_npc_teleport.sql
new file mode 100644
index 0000000..03b9e93
--- /dev/null
+++ b/sql/extras/setup_npc_teleport.sql
@@ -0,0 +1,119 @@
+DROP TABLE IF EXISTS `custom_npc_tele_category`;
+CREATE TABLE `custom_npc_tele_category` (
+  `id` int(6) unsigned NOT NULL default '0',
+  `name` varchar(255) NOT NULL default '',
+  `flag` tinyint(3) unsigned NOT NULL default '0',
+  `data0` bigint(20) unsigned NOT NULL default '0',
+  `data1` int(6) unsigned NOT NULL default '0',
+  PRIMARY KEY  (`id`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+DROP TABLE IF EXISTS `custom_npc_tele_destination`;
+CREATE TABLE `custom_npc_tele_destination` (
+  `id` int(6) unsigned NOT NULL auto_increment,
+  `name` char(100) NOT NULL default '',
+  `pos_X` float NOT NULL default '0',
+  `pos_Y` float NOT NULL default '0',
+  `pos_Z` float NOT NULL default '0',
+  `map` smallint(5) unsigned NOT NULL default '0',
+  `orientation` float NOT NULL default '0',
+  `level` tinyint(3) unsigned NOT NULL default '0',
+  `cost` int(10) unsigned NOT NULL default '0',
+  PRIMARY KEY  (`id`)
+) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
+
+DROP TABLE IF EXISTS `custom_npc_tele_association`;
+CREATE TABLE `custom_npc_tele_association` (
+  `cat_id` int(6) unsigned NOT NULL default '0',
+  `dest_id` int(6) unsigned NOT NULL default '0',
+  PRIMARY KEY  (`cat_id`, `dest_id`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+TRUNCATE `custom_npc_tele_category`;
+INSERT INTO `custom_npc_tele_category`
+   (`id`, `name`, `flag`, `data0`, `data1`)
+VALUES
+   (1, 'Cities', 0, 1, 0),
+   (2, 'Cities', 0, 2, 0),
+   (3, 'Battlegrounds', 0, 1, 0),
+   (4, 'Battlegrounds', 0, 2, 0),
+   (5, 'Arenas', 0, 0, 0),
+   (6, '[Instances Lvl 1-60]', 0, 0, 0),
+   (7, '[Instances Lvl 60+]', 5, 60, 0),
+   (8, '[Instances Lvl 70+]', 5, 70, 0),
+   (9, 'Destinations MJ', 3, 0, 0);
+
+TRUNCATE `custom_npc_tele_destination`;
+INSERT INTO `custom_npc_tele_destination`
+   (`id`, `name`, `pos_X`, `pos_Y`, `pos_Z`, `map`, `orientation`, `level`, `cost`)
+VALUES
+   (1, 'Alterac Valley', 883.187, -489.375, 96.7618, 30, 3.06932, 0, 0),
+   (2, 'Alterac Valley', -818.155, -623.043, 54.0884, 30, 2.1, 0, 0),
+   (3, 'Arathi Basin', 686.053, 683.165, -12.9149, 529, 0.18, 0, 0),
+   (4, 'Arathi Basin', 1308.68, 1306.03, -9.0107, 529, 3.91285, 0, 0),
+   (5, 'Black Temple', -3610.72, 324.988, 37.4, 530, 3.28298, 0, 0),
+   (6, 'Blackfathom Deeps', 4254.58, 664.74, -29.04, 1, 1.97, 0, 0),
+   (7, 'Blackrock Depths', -7301.03, -913.19, 165.37, 0, 0.08, 0, 0),
+   (8, 'Blackrock Spire', -7535.43, -1212.04, 285.45, 0, 5.29, 0, 0),
+   (9, 'Blackwing Lair', -7665.55, -1102.49, 400.679, 469, 0, 0, 0),
+   (10, 'Caverns of Time', -8173.66, -4746.36, 33.8423, 1, 4.93989, 0, 0),
+   (11, 'Circle of Blood', 2839.44, 5930.17, 11.1002, 530, 3.16284, 0, 0),
+   (12, 'Coilfang Reservoir', 517.288, 6976.28, 32.0072, 530, 0, 0, 0),
+   (13, 'Darnassus', 9947.52, 2482.73, 1316.21, 1, 0, 0, 0),
+   (14, 'Dire Maul', -3982.47, 1127.79, 161.02, 1, 0.05, 0, 0),
+   (15, 'Exodar', -4073.03, -12020.4, -1.47, 530, 0, 0, 0),
+   (16, 'Eye of the Storm', 2487.72, 1609.12, 1224.64, 566, 3.35671, 0, 0),
+   (17, 'Eye of the Storm', 1843.73, 1529.77, 1224.43, 566, 0.297579, 0, 0),
+   (18, 'Goldshire', -9464, 62, 56, 0, 0, 0, 0),
+   (19, 'Gruul\'s Lair', 3539.01, 5082.36, 1.69107, 530, 0, 0, 0),
+   (20, 'Gurubashi', -13261.3, 168.294, 35.0792, 0, 1.00688, 0, 0),
+   (21, 'Hellfire Citadel', -305.816, 3056.4, -2.47318, 530, 2.01, 0, 0),
+   (22, 'Ironforge', -4924.07, -951.95, 501.55, 0, 5.4, 0, 0),
+   (23, 'Isle Of Quel\'Danas', 12947.4, -6893.31, 5.68398, 530, 3.09154, 0, 0),
+   (24, 'Karazhan', -11118.8, -2010.84, 47.0807, 0, 0, 0, 0),
+   (25, 'Maraudon', -1433.33, 2955.34, 96.21, 1, 4.82, 0, 0),
+   (26, 'Molten Core', 1121.45, -454.317, -101.33, 230, 3.5, 0, 0),
+   (27, 'Naxxramas', 3125.18, -3748.02, 136.049, 0, 0, 0, 0),
+   (28, 'Onyxia\'s Lair', -4707.44, -3726.82, 54.6723, 1, 3.8, 0, 0),
+   (29, 'Orgrimmar', 1552.5, -4420.66, 8.94802, 1, 0, 0, 0),
+   (30, 'Razor Hill', 315.721, -4743.4, 10.4867, 1, 0, 0, 0),
+   (31, 'Razorfen Downs', -4645.08, -2470.85, 85.53, 1, 4.39, 0, 0),
+   (32, 'Razorfen Kraul', -4484.04, -1739.4, 86.47, 1, 1.23, 0, 0),
+   (33, 'Ring of Trials', -1999.94, 6581.71, 11.32, 530, 2.3, 0, 0),
+   (34, 'Ruins of Ahn\'Qiraj', -8409.03, 1498.83, 27.3615, 1, 2.49757, 0, 0),
+   (35, 'Scholomance', 1219.01, -2604.66, 85.61, 0, 0.5, 0, 0),
+   (36, 'Shadowfang Keep', -254.47, 1524.68, 76.89, 0, 1.56, 0, 0),
+   (37, 'Shattrath City', -1850.21, 5435.82, -10.9614, 530, 3.40391, 0, 0),
+   (38, 'Silvermoon', 9338.74, -7277.27, 13.7895, 530, 0, 0, 0),
+   (39, 'Stormwind', -8960.14, 516.266, 96.3568, 0, 0, 0, 0),
+   (40, 'Stratholme', 3263.54, -3379.46, 143.59, 0, 0, 0, 0),
+   (41, 'Tempest Keep', 3089.58, 1399.05, 187.653, 530, 4.79407, 0, 0),
+   (42, 'Temple of Ahn\'Qiraj', -8245.84, 1983.74, 129.072, 1, 0.936195, 0, 0),
+   (43, 'The Deadmines', -11212, 1658.58, 25.67, 0, 1.45, 0, 0),
+   (44, 'The Maul', -3761.49, 1133.43, 132.083, 1, 4.57259, 0, 0),
+   (45, 'The Scarlet Monastery', 2843.89, -693.74, 139.32, 0, 5.11, 0, 0),
+   (46, 'The Sunken Temple', -10346.9, -3851.9, -43.41, 0, 6.09, 0, 0),
+   (47, 'The Wailing Caverns', -722.53, -2226.3, 16.94, 1, 2.71, 0, 0),
+   (48, 'Thunder Bluff', -1290, 147.034, 129.682, 1, 4.919, 0, 0),
+   (49, 'Uldaman', -6119.7, -2957.3, 204.11, 0, 0.03, 0, 0),
+   (50, 'Undercity', 1819.71, 238.79, 60.5321, 0, 0, 0, 0),
+   (51, 'Warsong Gulch', 930.851, 1431.57, 345.537, 489, 0.015704, 0, 0),
+   (52, 'Warsong Gulch', 1525.95, 1481.66, 352.001, 489, 3.20756, 0, 0),
+   (53, 'Zul\'Aman', 6846.95, -7954.5, 170.028, 530, 4.61501, 0, 0),
+   (54, 'Zul\'Farrak', -6839.39, -2911.03, 8.87, 1, 0.41, 0, 0),
+   (55, 'Zul\'Gurub', -11916.7, -1212.82, 92.2868, 0, 4.6095, 0, 0),
+   (56, 'Ile des MJ', 16254, 16276.9, 14.5082, 1, 1.70269, 0, 0);
+
+TRUNCATE `custom_npc_tele_association`;
+INSERT INTO `custom_npc_tele_association`
+  (`cat_id`, `dest_id`)
+VALUES
+  (1, 13), (1, 15), (1, 18), (1, 22), (1, 23), (1, 37), (1, 39), (2, 23), (2, 29), (2, 30), (2, 37), (2, 38), (2, 48), (2, 50), (3, 1), (3, 4), (3, 16), (3, 52), (4, 2), (4, 3), (4, 17), (4, 51), (5, 11), (5, 20), (5, 33), (5, 44), (6, 6), (6, 7), (6, 8), (6, 14), (6, 25), (6, 31), (6, 32), (6, 35), (6, 36), (6, 40), (6, 43), (6, 45), (6, 46), (6, 47), (6, 49), (6, 54), (7, 9), (7, 26), (7, 27), (7, 28), (7, 34), (7, 42), (7, 55), (8, 5), (8, 10), (8, 12), (8, 19), (8, 21), (8, 24), (8, 41), (8, 53), (9, 56);
+
+-- `npc_text`
+REPLACE INTO `npc_text` (`ID`, `text0_0`) VALUES
+   (100000, 'Choose your Category.'),
+   (100001, 'Choose your Destination.');
+
+-- `creature_template`
+INSERT INTO `creature_template` VALUES (100000, 0, 0, 0, 0, 0, 26502, 0, 0, 0, 'Abisal Vortex', '', '', 0, 83, 83, 0, 35, 35, 1, 1, 1.14286, 2, 1, 509, 683, 0, 805, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 371, 535, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 'npc_teleport', 1);
diff --git a/src/server/game/AI/ScriptedAI/sc_npc_teleport.cpp b/src/server/game/AI/ScriptedAI/sc_npc_teleport.cpp
new file mode 100644
index 0000000..68565db
--- /dev/null
+++ b/src/server/game/AI/ScriptedAI/sc_npc_teleport.cpp
@@ -0,0 +1,373 @@
+/**
+ *
+ * @File : sc_npc_teleport.cpp
+ *
+ * @Authors : Wilibald09
+ *
+ * @Date : 28/08/2008
+ *
+ * @Version : 1.2
+ *
+ **/
+
+
+#include "ScriptPCH.h"
+#include "sc_npc_teleport.h"
+
+#define TELE    nsNpcTel::CatDest
+#define PAGE    nsNpcTel::Page
+#define PAGEI   PAGE::Instance
+
+
+nsNpcTel::VCatDest nsNpcTel::TabCatDest;
+
+
+uint32 PAGE::operator [] (Player * const player) const
+{
+    for (VInst_t i(0); i < m_TabInstance.size(); ++i)
+    {
+        if (m_TabInstance.GetPlayer() == player)
+            return m_TabInstance.GetPageId();
+    }
+    return 0;
+}
+
+PAGE::Instance & PAGE::operator () (Player * const player)
+{
+    for (VInst_t i(0); i < m_TabInstance.size(); ++i)
+    {
+        if (m_TabInstance.GetPlayer() == player)
+            return m_TabInstance;
+    }
+    m_TabInstance.push_back(Instance(player));
+    return m_TabInstance.back();
+}
+
+PAGE::Instance & PAGEI::operator = (const uint32 &id)
+{
+    m_PageId = id;
+    return *this;
+}
+
+PAGE::Instance & PAGEI::operator ++ (void)
+{
+    ++m_PageId;
+    return *this;
+}
+
+PAGE::Instance PAGEI::operator ++ (int32)
+{
+    Instance tmp (*this);
+    ++m_PageId;
+    return tmp;
+}
+
+PAGE::Instance & PAGEI::operator -- (void)
+{
+    --m_PageId;
+    return *this;
+}
+
+PAGE::Instance PAGEI::operator -- (int32)
+{
+    Instance tmp (*this);
+    --m_PageId;
+    return tmp;
+}
+
+TELE::CatDest(const uint32 &id, const std::string &name,
+              const Flag &flag, const uint64 &data0, const uint32 &data1)
+    : m_id(id), m_name(name), m_flag(flag), m_data0(data0), m_data1(data1)
+{
+    m_TabDest.clear();
+}
+
+std::string TELE::GetName(const bool IsGM /* = false */) const
+{
+    if (!IsGM || m_flag != FLAG_TEAM)
+        return m_name;
+
+    switch (m_data0)
+    {
+      case TEAM_HORDE:      return std::string(m_name + " (H)");
+      case TEAM_ALLIANCE:   return std::string(m_name + " (A)");
+    }
+    return m_name;
+}
+
+bool TELE::IsAllowedToTeleport(Player * const player) const
+{
+    if (player->isGameMaster())
+    {
+        if (m_flag == FLAG_GMLEVEL)
+            return player->GetSession()->GetSecurity() >= m_data0;
+        return true;
+    }
+
+    switch (m_flag)
+    {
+      case FLAG_TEAM:
+        switch (m_data0)
+        {
+          case TEAM_HORDE:      return player->GetTeam() == HORDE;
+          case TEAM_ALLIANCE:   return player->GetTeam() == ALLIANCE;
+          case TEAM_ALL:        return true;
+        }
+
+      case FLAG_GUILD:
+        return player->GetGuildId() == m_data0;
+
+      case FLAG_GMLEVEL:
+        return player->GetSession()->GetSecurity() >= m_data0;
+
+      case FLAG_ISGM:
+        return player->isGameMaster();
+
+      case FLAG_ACCOUNT:
+        return player->GetSession()->GetAccountId() == m_data0;
+
+      case FLAG_LEVEL:
+        return player->getLevel() >= m_data0;
+
+      case FLAG_ITEM:
+        return player->HasItemCount(m_data0, m_data1, true);
+
+      case FLAG_QUEST:
+        if (m_data1 < MAX_QUEST_STATUS)
+            return player->GetQuestStatus(m_data0) == m_data1;
+        return player->GetQuestRewardStatus(m_data0);
+
+      case FLAG_GENDER:
+        return player->getGender() == m_data0;
+
+      case FLAG_RACE:
+        return player->getRace() == m_data0;
+
+      case FLAG_CLASS:
+        return player->getClass() == m_data0;
+
+      case FLAG_REPUTATION:
+        return player->GetReputationRank(m_data0) >= m_data1;
+
+      case FLAG_PLAYER:
+        return player->GetGUID() == m_data0;
+    }
+
+    sLog->outError("Invalid flag (category: %u). Important problem...", GetCatID());
+    return false;
+}
+
+uint32 TELE::CountOfCategoryAllowedBy(Player * const player)
+{
+    uint32 count (0);
+    for (VCatDest_t i(0); i < TabCatDest.size(); ++i)
+    {
+        if (TabCatDest.IsAllowedToTeleport(player))
+            ++count;
+    }
+    return count;
+}
+
+bool nsNpcTel::IsValidData(const uint32 &cat,   const Flag &flag,
+                           const uint64 &data0, const uint32 &data1)
+{
+    switch(flag)
+    {
+      case FLAG_TEAM:
+        if (data1)
+            sLog->outError("Invalid data1 (category: %u).", cat);
+        if (data0 < MAX_FLAG_TEAM)
+            return true;
+        sLog->outError("Invalid data0 (Team) (category: %u).", cat);
+        return false;
+
+      case FLAG_GUILD:
+        if (data1)
+            sLog->outError("Invalid data1 (category: %u).", cat);
+        if (data0)
+            return true;
+        sLog->outError("Invalid data0 (GuildID) (category: %u).", cat);
+        return false;
+
+      case FLAG_GMLEVEL:
+        if (data1)
+            sLog->outError("Invalid data1 (category: %u).", cat);
+        if (0 < data0 && data0 < 256)
+            return true;
+        sLog->outError("Invalid data0 (GmLevel) (category: %u).", cat);
+        return false;
+
+      case FLAG_ISGM:
+        if (data0)
+            sLog->outError("Invalid data0 (category: %u).", cat);
+        if (data1)
+            sLog->outError("Invalid data1 (category: %u).", cat);
+        return true;
+
+      case FLAG_ACCOUNT:
+        if (data1)
+            sLog->outError("Invalid data1 (category: %u).", cat);
+        if (data0)
+            return true;
+        sLog->outError("Invalid data0 (AccountID) (category: %u).", cat);
+        return false;
+
+      case FLAG_LEVEL:
+        if (data1)
+            sLog->outError("Invalid data1 (category: %u).", cat);
+        if (0 < data0 && data0 < 256)
+            return true;
+        sLog->outError("Invalid data0 (Level) (category: %u).", cat);
+        return false;
+
+      case FLAG_ITEM:
+        if (!data0)
+        {
+            sLog->outError("Invalid data0 (ItemID) (category: %u).", cat);
+            return false;
+        }
+        if (data1)
+            return true;
+        sLog->outError("Invalid data1 (Item Count) (category: %u).", cat);
+        return false;
+
+      case FLAG_QUEST:
+        if (!data0)
+        {
+            sLog->outError("Invalid data0 (QuestID) (category: %u).", cat);
+            return false;
+        }
+        if (data1 < MAX_QUEST_STATUS + 1)
+            return true;
+        sLog->outError("Invalid data1 (Quest Status) (category: %u).", cat);
+        return false;
+
+      case FLAG_GENDER:
+        if (data1)
+            sLog->outError("Invalid data1 (category: %u).", cat);
+        if (data0 < GENDER_NONE)
+            return true;
+        sLog->outError("Invalid data0 (Gender) (category: %u).", cat);
+        return false;
+
+      case FLAG_RACE:
+        if (data1)
+            sLog->outError("Invalid data1 (category: %u).", cat);
+        if (0 < data0 && data0 < MAX_RACES)
+            return true;
+        sLog->outError("Invalid data0 (Race) (category: %u).", cat);
+        return false;
+
+      case FLAG_CLASS:
+        if (data1)
+            sLog->outError("Invalid data1 (category: %u).", cat);
+        if (0 < data0 && data0 < MAX_CLASSES)
+            return true;
+        sLog->outError("Invalid data0 (Class) (category: %u).", cat);
+        return false;
+
+      case FLAG_REPUTATION:
+        if (!data0)
+        {
+            sLog->outError("Invalid data0 (Faction/Reputation) (category: %u).", cat);
+            return false;
+        }
+        if (data1 <= REP_EXALTED)
+            return true;
+        sLog->outError("Invalid data1 (Faction/Reputation) (category: %u).", cat);
+        return false;
+
+      case FLAG_PLAYER:
+        if (data1)
+            sLog->outError("Invalid data1 (category: %u).", cat);
+        if (data0)
+            return true;
+        sLog->outError("Invalid data0 (PlayerGuid) (category: %u).", cat);
+        return false;
+    }
+
+    sLog->outError("Invalid flag (category: %u).", cat);
+    return false;
+}
+
+void LoadNpcTele(void)
+{
+    const char *Table[] =
+    {
+        "custom_npc_tele_category",
+        "custom_npc_tele_destination",
+        "custom_npc_tele_association",
+    };
+
+
+    QueryResult result = WorldDatabase.PQuery(
+        "SELECT `flag`, `data0`, `data1`, `cat_id`, C.`name` `namecat`, D.`name` `namedest`, "
+        //      0        1        2        3                  4                   5
+               "`pos_X`, `pos_Y`, `pos_Z`, `orientation`, `map`, `level`, `cost` "
+        //      6        7        8        9              10     11       12
+        "FROM `%s` C, `%s` D, `%s` A "
+        "WHERE C.`id` = `cat_id` AND D.`id` = `dest_id` "
+        "ORDER BY `namecat`, `cat_id`, `namedest`", Table[0], Table[1], Table[2]);
+
+    nsNpcTel::TabCatDest.clear();
+
+    if (result)
+    {
+            sLog->outString( "TSCR: Loading %s, %s and %s...", Table[0], Table[1], Table[2]);
+
+        uint32 catid = 0;
+        uint32 nbDest = 0;
+        bool IsValidCat = true;
+        bool FirstTime = true;
+
+        do
+        {
+            Field *fields = result->Fetch();
+
+            if (!IsValidCat && catid == fields[3].GetUInt32() && !FirstTime)
+                continue;
+
+            IsValidCat = true;
+            FirstTime = false;
+
+            if (!nsNpcTel::IsValidData(fields[3].GetUInt32(), (nsNpcTel::Flag)fields[0].GetUInt8(),
+                                       fields[1].GetUInt64(), fields[2].GetUInt32()))
+            {
+                IsValidCat = false;
+                catid = fields[3].GetUInt32();
+                continue;
+            }
+
+            if (catid != fields[3].GetUInt32())
+            {
+                catid = fields[3].GetUInt32();
+                nsNpcTel::CatDest categorie (catid, fields[4].GetString(), (nsNpcTel::Flag)fields[0].GetUInt8(),
+                                             fields[1].GetUInt64(), fields[2].GetUInt32());
+                nsNpcTel::TabCatDest.push_back(categorie);
+            }
+
+            nsNpcTel::Dest item =
+            {
+                fields[5].GetString(),   // Name
+                fields[6].GetFloat(),       // X
+                fields[7].GetFloat(),       // Y
+                fields[8].GetFloat(),       // Z
+                fields[9].GetFloat(),       // Orientation
+                fields[10].GetUInt16(),     // Map
+                fields[11].GetUInt8(),      // Level
+                fields[12].GetUInt32(),     // Cost
+            };
+
+            nsNpcTel::TabCatDest.back().AddDest(item);
+            ++nbDest;
+        } while (result->NextRow());
+
+        sLog->outString("");
+        sLog->outString("TSCR: >> Loaded %u npc_teleport.", nbDest);
+    } else sLog->outString("TSCR: WARNING >> Loaded 0 npc_teleport.");
+}
+
+
+#undef TELE
+#undef PAGE
+#undef PAGEI
diff --git a/src/server/game/AI/ScriptedAI/sc_npc_teleport.h b/src/server/game/AI/ScriptedAI/sc_npc_teleport.h
new file mode 100644
index 0000000..4830245
--- /dev/null
+++ b/src/server/game/AI/ScriptedAI/sc_npc_teleport.h
@@ -0,0 +1,151 @@
+/**
+ *
+ * @File : sc_npc_teleport.h
+ *
+ * @Authors : Wilibald09
+ *
+ * @Date : 19/08/2008
+ *
+ * @Version : 1.2
+ *
+ **/
+
+
+#ifndef SC_NPC_TELEPORT_H
+#define SC_NPC_TELEPORT_H
+
+#include <vector>
+
+
+namespace nsNpcTel
+{
+    // Different types of permissions
+    enum Flag
+    {
+        FLAG_TEAM       = 0,
+        FLAG_GUILD      = 1,
+        FLAG_GMLEVEL    = 2,
+        FLAG_ISGM       = 3,
+        FLAG_ACCOUNT    = 4,
+        FLAG_LEVEL      = 5,
+        FLAG_ITEM       = 6,
+        FLAG_QUEST      = 7,
+        FLAG_GENDER     = 8,
+        FLAG_RACE       = 9,
+        FLAG_CLASS      = 10,
+        FLAG_REPUTATION = 11,
+        FLAG_PLAYER     = 12,
+        MAX_FLAG,
+    };
+
+    // Different parameters of FLAG_TEAM
+    enum
+    {
+        TEAM_ALL        = 0,
+        TEAM_ALLIANCE   = 1,
+        TEAM_HORDE      = 2,
+        MAX_FLAG_TEAM,
+    };
+
+    // Structure representing the destinations
+    struct Dest
+    {
+        std::string m_name;
+        float       m_X, m_Y, m_Z, m_orient;
+        uint16      m_map;
+        uint8       m_level;
+        uint32      m_cost;
+    };
+
+    // Class representing the categories of destinations
+    class CatDest
+    {
+      public:
+
+        typedef std::vector<Dest> VDest;
+        typedef VDest::size_type  VDest_t;
+
+        CatDest(const uint32 &id, const std::string &name,
+                const Flag &flag, const uint64 &data0, const uint32 &data1);
+
+        void   AddDest  (const Dest &item)       { m_TabDest.push_back(item); }
+        Dest   GetDest  (const uint32 &id) const { return m_TabDest[id]; }
+        uint32 GetCatID (void)             const { return m_id; }
+        uint32 size     (void)             const { return m_TabDest.size(); }
+
+        std::string GetName(const bool IsGM = false)    const;
+        bool IsAllowedToTeleport(Player * const player) const;
+
+        static uint32 CountOfCategoryAllowedBy(Player * const player);
+
+      private:
+
+        uint32      m_id;
+        std::string m_name;
+        Flag        m_flag;
+        uint64      m_data0;
+        uint32      m_data1;
+        VDest       m_TabDest;
+    };
+
+    // Class page for current player
+    class Page
+    {
+      protected:
+
+        // Class instance for current player
+        class Instance
+        {
+          public:
+
+            Instance(Player * const player, const uint32 &PageId = 0)
+                : m_player(player), m_PageId(PageId) {}
+
+            Instance & operator =  (const uint32 &id);
+            Instance & operator ++ (void);
+            Instance   operator ++ (int32);
+            Instance & operator -- (void);
+            Instance   operator -- (int32);
+
+            uint32   GetPageId(void) const { return m_PageId; }
+            Player * GetPlayer(void) const { return m_player; }
+
+          private:
+
+            Player *m_player;
+            uint32  m_PageId;
+        };
+
+
+      public:
+
+        typedef std::vector<Instance> VInst;
+        typedef VInst::size_type      VInst_t;
+
+        Page(void) { m_TabInstance.clear(); }
+
+        Instance &   operator () (Player * const player);
+        uint32 operator [] (Player * const player) const;
+
+
+      private:
+
+        VInst m_TabInstance;
+    };
+
+    typedef std::vector <CatDest> VCatDest;
+    typedef VCatDest::size_type   VCatDest_t;
+
+    // Verification of data integrity
+    bool IsValidData(const uint32 &cat,   const Flag &flag,
+                     const uint64 &data0, const uint32 &data1);
+
+    extern VCatDest TabCatDest;
+}
+
+// Loading contents of database
+void LoadNpcTele(void);
+
+extern WorldDatabaseWorkerPool WorldDatabase;
+
+#endif
diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp
index cb1b2c8..abd9706 100755
--- a/src/server/game/Scripting/ScriptLoader.cpp
+++ b/src/server/game/Scripting/ScriptLoader.cpp
@@ -25,6 +25,9 @@ void AddSC_example_gossip_codebox();
void AddSC_example_misc();
void AddSC_example_commandscript();

+//TeleNPC2
+void AddSC_npc_teleport();
+
// spells
void AddSC_deathknight_spell_scripts();
void AddSC_druid_spell_scripts();
@@ -1210,6 +1213,7 @@ void AddCustomScripts()
{
#ifdef SCRIPTS
     /* This is where custom scripts should be added. */
-
+    //TeleNPC2
+    AddSC_npc_teleport();
#endif
}
diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp
index 4219a17..36c38a7 100755
--- a/src/server/game/Scripting/ScriptMgr.cpp
+++ b/src/server/game/Scripting/ScriptMgr.cpp
@@ -25,6 +25,7 @@
#include "ScriptLoader.h"
#include "ScriptSystem.h"
#include "Transport.h"
+#include "sc_npc_teleport.h"

// Utility macros to refer to the script registry.
#define SCR_REG_MAP(T) ScriptRegistry<T>::ScriptMap
@@ -180,6 +181,8 @@ void ScriptMgr::Initialize()
     uint32 oldMSTime = getMSTime();

     LoadDatabase();
+        // Load TeleNPC2 - maybe not the best place to load it ...
+        LoadNpcTele();

     sLog->outString("Loading C++ scripts");

diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt
index 9fd63fd..047dff1 100644
--- a/src/server/scripts/CMakeLists.txt
+++ b/src/server/scripts/CMakeLists.txt
@@ -31,6 +31,9 @@ include(Examples/CMakeLists.txt)

set(scripts_STAT_SRCS
   ${scripts_STAT_SRCS}
+  Custom/npc_teleport.cpp
+  ../game/AI/ScriptedAI/sc_npc_teleport.cpp
+  ../game/AI/ScriptedAI/sc_npc_teleport.h
   ../game/AI/ScriptedAI/ScriptedEscortAI.cpp
   ../game/AI/ScriptedAI/ScriptedCreature.cpp
   ../game/AI/ScriptedAI/ScriptedFollowerAI.cpp
diff --git a/src/server/scripts/Custom/npc_teleport.cpp b/src/server/scripts/Custom/npc_teleport.cpp
new file mode 100644
index 0000000..1e51336
--- /dev/null
+++ b/src/server/scripts/Custom/npc_teleport.cpp
@@ -0,0 +1,221 @@
+/**
+ *
+ * @File : npc_teleport.cpp
+ *
+ * @Authors : Wilibald09
+ *
+ * @Date : 19/08/2008
+ *
+ * @Version : 1.2
+ *
+ **/
+
+
+
+#include "ScriptPCH.h"
+#include "sc_npc_teleport.h"
+#include <sstream>
+
+#define GOSSIP_SHOW_DEST        1000
+#define GOSSIP_TELEPORT         1001
+#define GOSSIP_NEXT_PAGEC       1002
+#define GOSSIP_PREV_PAGEC       1003
+#define GOSSIP_NEXT_PAGED       1004
+#define GOSSIP_PREV_PAGED       1005
+#define GOSSIP_MAIN_MENU        1006
+
+#define SPELL_ID_PASSIVE_RESURRECTION_SICKNESS  15007
+#define SPELL_VISUAL_TELEPORT   35517
+
+#define NB_ITEM_PAGE            10
+#define MSG_CAT                 100000
+#define MSG_DEST                100001
+
+#define NEXT_PAGE               "-> [Next Page]"
+#define PREV_PAGE               "<- [Previous Page]"
+#define MAIN_MENU               "<= [Main Menu]"
+
+
+using namespace nsNpcTel;
+
+
+namespace
+{
+    Page PageC, PageD;
+    Page Cat;
+
+    // Conversion function int->string
+    std::string ConvertStr(const int64 &val)
+    {
+        std::ostringstream ostr;
+        ostr << val;
+        return ostr.str();
+    }
+
+    // Conversion function intMoney->stringMoney
+    std::string ConvertMoney(const uint32 &Money)
+    {
+        std::string Str(ConvertStr(Money));
+        uint32 SizeStr = Str.length();
+
+        if (SizeStr > 4)
+            Str = Str.insert(Str.length()-4, "po");
+        if (SizeStr > 2)
+            Str = Str.insert(Str.length()-2, "pa");
+        Str += "pc";
+
+        return Str;
+    }
+
+    // Teleport Player
+    void Teleport(Player * const player, const uint16 &map,
+                  const float &X, const float &Y, const float &Z, const float &orient)
+    {
+        player->CastSpell(player, SPELL_VISUAL_TELEPORT, true);
+        player->TeleportTo(map, X, Y, Z, orient);
+    }
+
+    // Display categories
+    void AffichCat(Player * const player, Creature * const creature)
+    {
+        if (PageC[player] > 0)
+            player->ADD_GOSSIP_ITEM(7, PREV_PAGE, GOSSIP_PREV_PAGEC, 0);
+
+        VCatDest_t i (PageC[player] * NB_ITEM_PAGE);
+        for ( ; i < TabCatDest.size() && i < (NB_ITEM_PAGE * (PageC[player] + 1)); ++i)
+        {
+            if (TabCatDest.IsAllowedToTeleport(player))
+                player->ADD_GOSSIP_ITEM(7, TabCatDest.GetName(player->isGameMaster()).c_str(), GOSSIP_SHOW_DEST, i);
+        }
+
+        if (i < TabCatDest.size())
+            player->ADD_GOSSIP_ITEM(7, NEXT_PAGE, GOSSIP_NEXT_PAGEC, 0);
+
+        player->SEND_GOSSIP_MENU(MSG_CAT, creature->GetGUID());
+    }
+
+    // Display destination categories
+    void AffichDest(Player * const player, Creature * const creature)
+    {
+        if (PageD[player] > 0)
+            player->ADD_GOSSIP_ITEM(7, PREV_PAGE, GOSSIP_PREV_PAGED, 0);
+
+        CatDest::VDest_t i (PageD[player] * NB_ITEM_PAGE);
+        for ( ; i < TabCatDest[Cat[player]].size() && i < (NB_ITEM_PAGE * (PageD[player] + 1)); ++i)
+        {
+            player->ADD_GOSSIP_ITEM(5, TabCatDest[Cat[player]].GetDest(i).m_name.c_str(), GOSSIP_TELEPORT, i);
+        }
+
+        if (i < TabCatDest[Cat[player]].size())
+            player->ADD_GOSSIP_ITEM(7, NEXT_PAGE, GOSSIP_NEXT_PAGED, 0);
+
+        if (CatDest::CountOfCategoryAllowedBy(player) > 1)
+            player->ADD_GOSSIP_ITEM(7, MAIN_MENU, GOSSIP_MAIN_MENU, 0);
+
+        player->SEND_GOSSIP_MENU(MSG_DEST, creature->GetGUID());
+    }
+
+    // Verification before teleportation
+    void ActionTeleport(Player * const player, Creature * const creature, const uint32 &id)
+    {
+        Dest dest (TabCatDest[Cat[player]].GetDest(id));
+
+        if (player->getLevel() < dest.m_level && !player->isGameMaster())
+        {
+            std::string msg ("You do not have the required level. This destination requires level " + ConvertStr(dest.m_level) + ".");
+            creature->MonsterWhisper(msg.c_str(), player->GetGUID());
+            return;
+        }
+
+        if (player->GetMoney() < dest.m_cost && !player->isGameMaster())
+        {
+            std::string msg ("You do not have enough money. The price for teleportation is " + ConvertMoney(dest.m_cost) + ".");
+            creature->MonsterWhisper(msg.c_str(), player->GetGUID());
+            return;
+        }
+
+        if (!player->isGameMaster() && dest.m_cost)
+            player->ModifyMoney(-1 * dest.m_cost);
+
+        Teleport(player, dest.m_map, dest.m_X, dest.m_Y, dest.m_Z, dest.m_orient);
+    }
+}
+
+class npc_teleport : public CreatureScript
+{
+public:
+    npc_teleport() : CreatureScript("npc_teleport") {}
+
+bool OnGossipHello(Player *player, Creature *creature)
+{
+    PageC(player) = PageD(player) = Cat(player) = 0;
+
+    if(player->isInCombat())
+    {
+        player->CLOSE_GOSSIP_MENU();
+        creature->MonsterWhisper("You are in combat. Come back later", player->GetGUID());
+        return true;
+    }
+    AffichCat(player, creature);
+    return true;
+}
+
+bool OnGossipSelect(Player *player, Creature *creature, uint32 sender, uint32 param)
+{
+    player->PlayerTalkClass->ClearMenus();
+    switch(sender)
+    {
+      // Display destinations
+      case GOSSIP_SHOW_DEST:
+        Cat(player) = param;
+        AffichDest(player, creature);
+        break;
+
+      // Previous categories page
+      case GOSSIP_PREV_PAGEC:
+        --PageC(player);
+        AffichCat(player, creature);
+        break;
+
+      // Next page categories
+      case GOSSIP_NEXT_PAGEC:
+        ++PageC(player);
+        AffichCat(player, creature);
+        break;
+
+      // Previous destinations page
+      case GOSSIP_PREV_PAGED:
+        --PageD(player);
+        AffichDest(player, creature);
+        break;
+
+      // Next destination page
+      case GOSSIP_NEXT_PAGED:
+        ++PageD(player);
+        AffichDest(player, creature);
+        break;
+
+      // Display main menu
+      case GOSSIP_MAIN_MENU:
+        OnGossipHello(player, creature);
+        break;
+
+      // Teleportation
+      case GOSSIP_TELEPORT:
+        player->CLOSE_GOSSIP_MENU();
+        if(player->HasAura(SPELL_ID_PASSIVE_RESURRECTION_SICKNESS,0)) {
+            creature->CastSpell(player,38588,false); // Healing effect
+            player->RemoveAurasDueToSpell(SPELL_ID_PASSIVE_RESURRECTION_SICKNESS);
+        }
+
+        ActionTeleport(player, creature, param);
+        break;
+    }
+    return true;
+}
+};
+
+void AddSC_npc_teleport()
+{
+    new npc_teleport;
+}
--
1.7.2.3


 
VIP介绍
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 最佳新人

    注册账号后积极发帖的会员
  • 活跃会员

    经常参与各类话题的讨论,发帖内容较有主见
  • 热心会员

    经常帮助其他会员答疑
  • 推广达人

    积极宣传本站,为本站带来更多注册会员
  • 宣传达人

    积极宣传本站,为本站带来更多的用户访问量
  • 灌水之王

    经常在论坛发帖,且发帖量较大
  • 突出贡献

    长期对论坛的繁荣而不断努力,或多次提出建设性意见
  • 优秀版主

    活跃且尽责职守的版主
  • 荣誉管理

    曾经为论坛做出突出贡献目前已离职的版主
  • 论坛元老

    为论坛做出突出贡献的会员

0关注

5粉丝

3421帖子

排行榜
作者专栏

QQ交流群&&微信订阅号

QQ交流群

微信订阅号

吾爱尚玩资源基地永久域名:

Www.523Play.Com

在线管理员QQ:1589479632

邮箱:Email@523play.com

QQ交流群:558936238

Copyright   ©2015-2116  吾爱尚玩资源基地|523play.comPowered by©523Pplay.Com技术支持:吾爱尚玩资源基地