|
|
Модератор форума: Dimitro |
Форум TrinityCore Патчи / Моды / Фиксы для Trinity Dynamic Teleporter |
Dynamic Teleporter |
Решил выложить патч на динамического телепортера.
Чем отличается он от остальных? Все манипуляции с телепортером осуществляются в игре, с помощью команд. Доступно 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
|
| |||
| |||