Skip to content

Instantly share code, notes, and snippets.

@walkline
Created May 7, 2012 19:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save walkline/2629831 to your computer and use it in GitHub Desktop.
Save walkline/2629831 to your computer and use it in GitHub Desktop.
Dynamic teleporter
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();
+}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment