• Страница 1 из 1
  • 1
Модератор форума: Dimitro  
Dynamic Teleporter
walkline
Скаут
Решил выложить патч на динамического телепортера.
Чем отличается он от остальных?
Все манипуляции с телепортером осуществляются в игре, с помощью команд.
Доступно 4 команды:
- tp addpoint;
- tp addmenu;
- tp list;
- tp remove;
Подробное описание команд и их синтаксис можете посмотреть в sql файле.

С помощью данных команд, можно построить многоуровневые меню телепортаций, не замарачиваясь на координатах.

Патч в ядро:

Code
diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp
index 6322151..e7890cb 100755
@@ -63,6 +63,10 @@ void AddSC_wp_commandscript();
  void AddSC_gps_commandscript();
   
  #ifdef SCRIPTS
+//custom
+void AddSC_npc_teleporter();
+void AddSC_tp_commandscript();
+
  //world
  void AddSC_areatrigger_scripts();
  void AddSC_emerald_dragons();
@@ -1234,5 +1238,7 @@ void AddCustomScripts()
  #ifdef SCRIPTS
      /* This is where custom scripts should be added. */
   
+    AddSC_npc_teleporter();
+    AddSC_tp_commandscript();
  #endif
  }
diff --git a/src/server/scripts/Custom/CMakeLists.txt b/src/server/scripts/Custom/CMakeLists.txt
index 1570ca1..5daea6c 100644
@@ -10,6 +10,7 @@
   
  set(scripts_STAT_SRCS
    ${scripts_STAT_SRCS}
+  Custom/npc_teleporter.cpp
  )
   
  message("  -> Prepared: Custom")
diff --git a/src/server/scripts/Custom/npc_teleporter.cpp b/src/server/scripts/Custom/npc_teleporter.cpp
new file mode 100644
@@ -0,0 +1,317 @@
+#include "ScriptPCH.h"
+
+enum ActionType {
+    ACTION_TYPE_SUBMENU,
+    ACTION_TYPE_POINT
+};
+
+class npc_teleporter : public CreatureScript
+{
+public:
+    npc_teleporter() : CreatureScript("npc_teleporter") { }
+
+    bool OnGossipHello(Player *player, Creature *creature)
+    {
+        if (!player || !creature)
+            return false;
+
+        return ActionSubmenu(player, creature, 0);
+    }
+
+    bool OnGossipSelect(Player *player, Creature *creature, uint32 sender, uint32 action )
+    {
+        if (player->isInCombat())
+        {
+            player->CLOSE_GOSSIP_MENU();
+            creature->MonsterTextEmote("You are in combat!", 0, true);
+            return false;
+        }
+
+        QueryResult result = WorldDatabase.PQuery("SELECT type FROM teleporter_actions WHERE action = %u", action);
+        if (result && result->GetRowCount() > 0)
+        {
+            Field *fields = result->Fetch();
+            uint8 aType = fields[0].GetUInt8();
+            switch (aType)
+            {
+            case ACTION_TYPE_SUBMENU:
+                ActionSubmenu(player, creature, action);
+                break;
+            case ACTION_TYPE_POINT:
+                ActionTeleport(player, action);
+                break;
+            default:
+                sLog->outString("Unknown action type in `teleporter_actions`.");
+            }
+        }
+
+        return true;
+    }
+
+    bool ActionTeleport(Player *player, uint32 action)
+    {
+        player->PlayerTalkClass->ClearMenus();
+        QueryResult result = WorldDatabase.PQuery("SELECT map, x, y, z, o FROM teleporter_points WHERE action = %u", action);
+        if (result && result->GetRowCount() > 0)
+        {
+            Field *fields = result->Fetch();
+
+            uint8 map   = fields[0].GetUInt8();
+            float tmpX  = fields[1].GetFloat();
+            float tmpY  = fields[2].GetFloat();
+            float tmpZ  = fields[3].GetFloat();
+            float tmpO  = fields[4].GetFloat();
+
+            return player->TeleportTo(map, tmpX, tmpY, tmpZ, tmpO);
+        }
+
+        return false;
+    }
+
+    bool ActionSubmenu(Player *player, Creature *creature, uint32 action)
+    {
+        player->PlayerTalkClass->ClearMenus();
+        if (!player->isInCombat())
+        {
+            //                    0    1      2       3
+            QueryResult result = WorldDatabase.PQuery("SELECT text, icon, action, faction FROM teleporter_menu WHERE showAction = %u ORDER BY id", action);
+            if (result && result->GetRowCount() > 0)
+            {
+                do
+                {
+                    Field *fields = result->Fetch();
+
+                    std::string text = fields[0].GetString();
+                    uint8 icon       = fields[1].GetUInt8();
+                    uint32 action    = fields[2].GetUInt32();
+                    uint8 faction    = fields[3].GetUInt8();
+
+                    if ((faction == 1 && player->GetTeam() == HORDE) ||
+                        (faction == 2 && player->GetTeam() == ALLIANCE))
+                        continue;
+
+                    player->ADD_GOSSIP_ITEM(icon, text, GOSSIP_SENDER_MAIN, action);
+                }
+                while (result->NextRow());
+            }
+        }
+
+        player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID());
+
+        return true;
+    }
+};
+
+void AddSC_npc_teleporter()
+{
+    new npc_teleporter;
+}
+
+
+class tp_commandscript : public CommandScript
+{
+public:
+    tp_commandscript() : CommandScript("tp_commandscript") { }
+
+    ChatCommand* GetCommands() const
+    {
+        static ChatCommand tpCommandTable[] =
+        {
+            { "addpoint",       SEC_MODERATOR,      false, &HandleTpAddPointCommand,          "", NULL },
+            { "addmenu",        SEC_MODERATOR,      false, &HandleTpAddMenuCommand,           "", NULL },
+            { "remove",         SEC_MODERATOR,      false, &HandleTpRemoveCommand,            "", NULL },
+            { "list",           SEC_MODERATOR,      false, &HandleTpListCommand,              "", NULL },
+            { NULL,             0,                  false, NULL,                    "", NULL }
+        };
+        static ChatCommand commandTable[] =
+        {
+            { "tp",             SEC_MODERATOR,      false, NULL,                     "", tpCommandTable },
+            { NULL,             0,                  false, NULL,                    "", NULL }
+        };
+        return commandTable;
+    }
+
+    // args = "Name" submenu icon faction
+    static bool HandleTpAddPointCommand(ChatHandler* handler, char const* args)
+    {
+        if (!*args)
+            return false;
+
+        std::string sArgs = args;
+
+        //search name arg
+        std::string name;
+        int32 firstS = sArgs.find("\"");
+        int32 secondS = sArgs.find("\"", firstS + 1);
+        if (!secondS || firstS == secondS || secondS - firstS == sArgs.size())
+            return false;
+        name = sArgs.substr(firstS + 1, secondS - 1);
+        sArgs.replace(0, secondS + 1, "");
+
+        //search submenu arg
+        uint32 endPos = sArgs.find(" ", 1);
+        if (!endPos)
+            return false;
+        std::string sSM = sArgs.substr(1, endPos);
+        uint32 submenu = atoi(sSM.c_str());
+        sArgs.replace(0, endPos, "");
+
+        //search icon
+        endPos = sArgs.find(" ", 1);
+        if (!endPos)
+            return false;
+        std::string sIco = sArgs.substr(1, endPos);
+        uint32 icon = atoi(sIco.c_str());
+        sArgs.replace(0, endPos, "");
+
+        //search faction
+        std::string sFaction = sArgs.substr(1);
+        uint32 faction = atoi(sFaction.c_str());
+
+        sLog->outString("%s; %u, %u, %u", name.c_str(), submenu, icon, faction);
+
+        uint32 action;
+        QueryResult result = WorldDatabase.PQuery("SELECT MAX(action) FROM teleporter_menu");
+        if (result)
+        {
+            Field* fields = result->Fetch();
+            action = fields[0].GetUInt32() + 1;
+        }
+        else
+            action = 1;
+
+        WorldDatabase.PQuery("INSERT INTO teleporter_menu (action, showAction, text, icon, faction) VALUES (%u, %u, '%s', %u, %u)", action, submenu, name.c_str(), icon, faction);
+        WorldDatabase.PQuery("INSERT INTO teleporter_actions (action, type) VALUES (%u, %u)", action, ACTION_TYPE_POINT);
+
+        Player *player = handler->GetSession()->GetPlayer();
+        float x = player->GetPositionX();
+        float y = player->GetPositionY();
+        float z = player->GetPositionZ();
+        float o = player->GetOrientation();
+        uint32 map = player->GetMapId();
+        WorldDatabase.PQuery("INSERT INTO teleporter_points (action, map, x, y, z, o) VALUES (%u, %u, %f, %f, %f, %f)", action, map, x, y, z, o);
+        return true;
+    }
+
+    static bool HandleTpAddMenuCommand(ChatHandler* handler, char const* args)
+    {
+        if (!*args)
+            return false;
+
+        std::string sArgs = args;
+
+        //search name arg
+        std::string name;
+        int32 firstS = sArgs.find("\"");
+        int32 secondS = sArgs.find("\"", firstS + 1);
+        if (!secondS || firstS == secondS || secondS - firstS == sArgs.size())
+            return false;
+        name = sArgs.substr(firstS + 1, secondS - 1);
+        sArgs.replace(0, secondS + 1, "");
+
+        //search submenu arg
+        uint32 endPos = sArgs.find(" ", 1);
+        if (!endPos)
+            return false;
+        std::string sSM = sArgs.substr(1, endPos);
+        uint32 submenu = atoi(sSM.c_str());
+        sArgs.replace(0, endPos, "");
+
+        //search icon
+        endPos = sArgs.find(" ", 1);
+        if (!endPos)
+            return false;
+        std::string sIco = sArgs.substr(1, endPos);
+        uint32 icon = atoi(sIco.c_str());
+        sArgs.replace(0, endPos, "");
+
+        //search faction
+        std::string sFaction = sArgs.substr(1);
+        uint32 faction = atoi(sFaction.c_str());
+
+        sLog->outString("%s; %u, %u, %u", name.c_str(), submenu, icon, faction);
+
+        uint32 action;
+        QueryResult result = WorldDatabase.PQuery("SELECT MAX(action) FROM teleporter_menu");
+        if (result)
+        {
+            Field* fields = result->Fetch();
+            action = fields[0].GetUInt32() + 1;
+        }
+        else
+            action = 1;
+
+        WorldDatabase.PQuery("INSERT INTO teleporter_menu (action, showAction, text, icon, faction) VALUES (%u, %u, '%s', %u, %u)", action, submenu, name.c_str(), icon, faction);
+        WorldDatabase.PQuery("INSERT INTO teleporter_actions (action, type) VALUES (%u, %u)", action, ACTION_TYPE_SUBMENU);
+
+        return true;
+    }
+
+
+    static void PrintSubMenus(ChatHandler* handler, uint32 action, std::string space)
+    {
+        QueryResult result = WorldDatabase.PQuery("SELECT action, text, faction FROM teleporter_menu WHERE showAction = %u ORDER BY id", action);
+        if (result && result->GetRowCount() > 0)
+        {
+            do
+            {
+                Field *fields = result->Fetch();
+
+                uint32 _action    = fields[0].GetUInt32();
+                std::string text = fields[1].GetString();
+                uint8 faction    = fields[2].GetUInt8();
+
+                handler->PSendSysMessage("%s %u - \"%s\" - %u", space.c_str(), _action, text.c_str(), faction);
+                PrintSubMenus(handler, _action, space + "    ");
+            }
+            while (result->NextRow());
+        }
+
+    }
+
+    static bool HandleTpListCommand(ChatHandler* handler, char const* args)
+    {
+        handler->PSendSysMessage("*----------------------------");
+        handler->PSendSysMessage("ID  - \"Name\" - Faction");
+        PrintSubMenus(handler, 0, "");
+        handler->PSendSysMessage("----------------------------*");
+
+        return true;
+    }
+
+    static void RemoveAction(uint32 action)
+    {
+        if (!action)
+            return;
+
+        QueryResult result = WorldDatabase.PQuery("SELECT action FROM teleporter_menu WHERE showAction = %u ORDER BY id", action);
+        if (result && result->GetRowCount() > 0)
+        {
+            do
+            {
+                Field *fields  = result->Fetch();
+                uint32 _action = fields[0].GetUInt32();
+                RemoveAction(_action);
+            }
+            while (result->NextRow());
+        }
+        WorldDatabase.PQuery("DELETE FROM teleporter_menu WHERE action = %u", action);
+        WorldDatabase.PQuery("DELETE FROM teleporter_points WHERE action = %u", action);
+        WorldDatabase.PQuery("DELETE FROM teleporter_actions WHERE action = %u", action);
+    }
+
+    static bool HandleTpRemoveCommand(ChatHandler* handler, char const* args)
+    {
+        if (!*args)
+            return false;
+
+        uint32 action = atoi(args);
+        RemoveAction(action);
+        return true;
+    }
+};
+
+void AddSC_tp_commandscript()
+{
+    new tp_commandscript();
+}

Патч в базу:
Code
DROP TABLE IF EXISTS `teleporter_menu`;
CREATE TABLE `teleporter_menu` (
         `id` int(10) unsigned AUTO_INCREMENT,
         `action` int(10) unsigned DEFAULT '0',
         `showAction` int(10) unsigned DEFAULT '0',
         `text` varchar(100) NOT NULL,
         `icon` int(3) unsigned DEFAULT '0',
         `faction` int(3) unsigned DEFAULT '0',
         PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

DROP TABLE IF EXISTS `teleporter_actions`;
CREATE TABLE `teleporter_actions` (
         `action` int(10) unsigned NOT NULL,
         `type` int(3) unsigned DEFAULT '0',
         PRIMARY KEY (`action`)
);

DROP TABLE IF EXISTS `teleporter_points`;
CREATE TABLE `teleporter_points` (
         `action` int(10) unsigned NOT NULL,
         `map` int(1) unsigned DEFAULT '0',
         `x` float(10) NOT NULL,
         `y` float(10) NOT NULL,  
         `z` float(10) NOT NULL,
         `o` float(10) NOT NULL,
         PRIMARY KEY (`action`)
);

DELETE FROM creature_template WHERE entry = '190000';

INSERT INTO creature_template (entry, modelid1, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, Health_mod, Mana_mod, Armor_mod, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, dmg_multiplier, unit_class, unit_flags, type, type_flags, InhabitType, RegenHealth, flags_extra, ScriptName) VALUES
('190000', '21769', "Yarrrr!", "SoS Teleporter", 'Directions', '50000', 71, 71, 1.56, 1.56, 1.56, 35, 35, 3, 1, 1.14286, 1.25, 1, 1, 1, 2, 7, 138936390, 3, 1, 2, 'npc_teleporter');

DELETE FROM `command` WHERE `name` = 'tp';       
INSERT INTO `command` (`name`, `security`, `help`) VALUES ('tp', 0, 'Syntax: .tp $subcommand.\nUse .help tp.');
DELETE FROM `command` WHERE `name` = 'tp addpoint';      
INSERT INTO `command` (`name`, `security`, `help`) VALUES ('tp addpoint', 2, 'Syntax: .tp addpoint "#name" #submenu #icon #faction\nFor #submenu check tp list id.\n#icon see GossipOptionIcon declaration.\n#Faction - 0 -all, 1 - alliance, 2 -horde.');
DELETE FROM `command` WHERE `name` = 'tp addmenu';       
INSERT INTO `command` (`name`, `security`, `help`) VALUES ('tp addmenu', 2, 'Syntax: .tp addmenu "#name" #submenu #icon #faction\nFor #submenu check tp list id.\n#icon see GossipOptionIcon declaration.\n#Faction - 0 -all, 1 - alliance, 2 -horde.');
DELETE FROM `command` WHERE `name` = 'tp list';  
INSERT INTO `command` (`name`, `security`, `help`) VALUES ('tp list', 1, 'Syntax: .tp list\nList of menus in teleporter...');
DELETE FROM `command` WHERE `name` = 'tp remove';        
INSERT INTO `command` (`name`, `security`, `help`) VALUES ('tp remove', 2, 'Syntax: .tp remove #id\nLook #id in .tp list.');
Сообщение # 1 написано 07.05.2012 в 23:28
Djumhоrdе
Скаут
Насколько я понял, игрок сам может создавать поинты?
Сообщение # 2 написано 08.05.2012 в 10:20
walkline
Скаут
Quote (OmgTIsFree)
Насколько я понял, игрок сам может создавать поинты?


Если сделать доступными эти команды игроку, тогда да, игрок сможет сам добавлять/удалять. Но не рекомендую этого делать.
Сообщение # 3 написано 08.05.2012 в 11:07
  • Страница 1 из 1
  • 1
Поиск: